Skip to content

Commit

Permalink
Reduce complexity
Browse files Browse the repository at this point in the history
Rewrote internals in order to reduce future, breaking rollup API changes

Fixes #4
Fixes #6
  • Loading branch information
AgronKabashi authored Jan 13, 2019
1 parent c35f229 commit f8bc042
Show file tree
Hide file tree
Showing 14 changed files with 723 additions and 841 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Version 3.1.0
*2019-01-14*
* Rewrote internals in order remove overhead and better conform to future rollup API changes.
* Increased performance and reduced plugin size.

## Version 3.0.0
*2019-01-01*
* Compatibility with rollup v1.0. Contains several under the hood changes such as removal of deprecated options and new API hooks.
Expand Down
104 changes: 16 additions & 88 deletions build/rollup-plugin-conditional.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,6 @@
'use strict';

const ensureArray = input => Array.isArray(input) ? input : [input]; // TODO: Issue #4 - Reduce complexity

const byMethod = names => plugin => ensureArray(names).some(name => plugin.hasOwnProperty(name)); // TODO: Issue #4 - Reduce complexity

const codeTransformSequencer = (plugin, hookNames) =>
(previousResult = "") => {
const input = typeof previousResult === "object" ? previousResult.code : previousResult;
const hookName = ensureArray(hookNames).find(hookName => plugin.hasOwnProperty(hookName)); // TODO: Issue #4 - Reduce complexity
return plugin[hookName](input) || previousResult;
};

const stringConcatSequencer = (plugin, hookName, separator = "\n") =>
async (previousResult = "") => {
const result = await Promise.resolve(plugin[hookName]());
return result ? `${previousResult}${previousResult && separator}${result}` : previousResult;
};

const doubleLineStringConcatSequencer = (...args) => stringConcatSequencer(...args, "\n\n");

/**
* Execute the plugins in sequence, passing the output of the current to the next plugin in the queue
* @param {Array<{}>} plugins Collection of rollup plugins
* @param {string|Array<string>} hookName Name(s) of plugin API method(s) to filter by and execute
* @param {Function} callback Callback method for handling the result of each plugin.hookName call
* @returns {Function} A reduced function that returns the final result of all the plugins' results
*/
const promisifiedSequence = (plugins, hookName, callback) =>
(...args) => {
const hookNames = ensureArray(hookName); // TODO: Issue #4 - Reduce complexity
const [firstPlugin, ...restPlugins] = plugins.filter(byMethod(hookNames));

if (!restPlugins.length && !firstPlugin) {
return null;
}

const startingValue = Promise.resolve(callback(firstPlugin, hookNames)(...args));

return restPlugins.reduce((result, plugin) =>
result.then(callback(plugin, hookNames)), startingValue);
};
const byHook = hookName => plugin => plugin.hasOwnProperty(hookName);

/**
* Run the specified plugins in sequence, passing the output to the next plugin in the queue
Expand All @@ -49,45 +10,15 @@ const promisifiedSequence = (plugins, hookName, callback) =>
*/
const sequence = (plugins, hookName) =>
(...args) => {
const [firstPlugin, ...restPlugins] = plugins.filter(byMethod(hookName));
const [firstPlugin, ...restPlugins] = plugins.filter(byHook(hookName));

if (!restPlugins.length && !firstPlugin) {
return null;
}

const startingValue = firstPlugin[hookName](...args);

return restPlugins.reduce((result, plugin) => plugin[hookName](result), startingValue);
};

/**
* Find and return the result of the first plugin with specified hookName that returns a truthy value
* @param {Array<{}>} plugins Collection of rollup plugins
* @param {string} hookName Plugin hook to execute
* @returns {Function} Reduced function that returns the truthy result of the last plugin in the colleciton
*/
const firstAvailable = (plugins, hookName) =>
(...args) => plugins
.filter(byMethod(hookName))
.reduce((output, plugin) => output || plugin[hookName](...args), null);

/**
* Execute all hooks for the plugins with the specified hookName
* @param {Array<{}>} plugins Collection of rollup plugins
* @param {string} hookName Plugin hook to execute
* @returns {Function} Reduced function that returns the truthy result of the last plugin in the colleciton
*/
const all = (plugins, hookName) =>
(...args) => {
const hookNames = ensureArray(hookName); // TODO: Issue #4 - Reduce complexity
return Promise.all([
plugins
.filter(byMethod(hookNames))
.map(plugin => {
const hookName = hookNames.find(hookName => plugin.hasOwnProperty(hookName));
return Promise.resolve(plugin[hookName](...args));
})
]);
return restPlugins.reduce((result, plugin) => plugin[hookName](result) || result, startingValue);
};

function conditional (condition, plugins) {
Expand All @@ -100,24 +31,21 @@ function conditional (condition, plugins) {
return;
}

const conditionalUniqueId = `${Date.now()}${Math.random()}`;

return {
name: "rollup-plugin-conditional",
banner: promisifiedSequence(plugins, "banner", stringConcatSequencer),
buildEnd: all(plugins, "buildEnd"),
buildStart: all(plugins, "buildStart"),
footer: promisifiedSequence(plugins, "footer", stringConcatSequencer),
generateBundle: all(plugins, ["generateBundle", "ongenerate", "onwrite"]),
intro: promisifiedSequence(plugins, "intro", doubleLineStringConcatSequencer),
load: firstAvailable(plugins, "load"),
options: sequence(plugins, "options"),
outro: promisifiedSequence(plugins, "outro", doubleLineStringConcatSequencer),
renderChunk: promisifiedSequence(plugins, ["renderChunk", "transformChunk", "transformBundle"], codeTransformSequencer), // TODO: Issue #4 - Reduce complexity
renderError: all(plugins, "renderError"),
renderStart: all(plugins, "renderStart"),
resolveId: firstAvailable(plugins, "resolveId"),
resolveDynamicImport: firstAvailable(plugins, "resolveDynamicImport"),
transform: promisifiedSequence(plugins, "transform", codeTransformSequencer),
watchChange: sequence(plugins, "watchChange")
conditionalUniqueId,
options: inputOptions => {
const conditionalPluginIndex = inputOptions.plugins.findIndex(plugin => plugin.conditionalUniqueId === conditionalUniqueId);
if (conditionalPluginIndex >= 0) {
// Inject the supplied plugins into conditional's position
inputOptions.plugins.splice(conditionalPluginIndex, 1, ...plugins);
}

// The options hook needs to be called manually for the supplied plugins
return sequence(plugins, "options")(inputOptions);
}
};
}

Expand Down
Loading

0 comments on commit f8bc042

Please sign in to comment.