/** * A factory wrapper around a webpack compiler plugin to create a serializer * object that caches a various data hard-source turns into json data without * circular references. * * The wrapper uses a plugin hook on the webpack Compiler called * `'hard-source-cache-factory'`. It is a waterfall plugin, the returned value * of one plugin handle is passed to the next as the first argument. This * plugin is expected to return a factory function that takes one argument. The * argument passed to the factory function is the info about what kind of cache * serializer hard-source wants. * * The info object contains three fields, `name`, `type`, and `cacheDirPath`. * * One example of info might be * * ```js * { * name: 'asset', * type: 'file', * cacheDirPath: '/absolute/path/to/my-project/path/configured/in/hard-source' * } * ``` * * - `name` is the general name of the cache in hard-source. * - `type` is the type of data contained. The `file` type means it'll be file * data like large buffers and strings. The `data` type means its generally * smaller info and serializable with JSON.stringify. * - `cacheDirPath` is the root of the hard-source disk cache. A serializer * should add some further element to the path for where it will store its * info. * * So an example plugin handle should take the `factory` argument and return * its own wrapping factory function. That function will take the `info` data * and if it wants to returns a serializer. Otherwise its best to call the * factory passed into the plugin handle. * * ```js * compiler.plugin('hard-source-cache-factory', function(factory) { * return function(info) { * if (info.type === 'data') { * return new MySerializer({ * cacheDirPath: join(info.cacheDirPath, info.name) * }); * } * return factory(info); * }; * }); * ``` * * @module hard-source-webpack-plugin/cache-serializer-factory * @author Michael "Z" Goddard */ /** * @constructor Serializer * @memberof module:hard-source-webpack-plugin/cache-serializer-factory */ /** * @method read * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~Serializer# * @returns {Promise} promise that resolves the disk cache's contents * @resolves {Object} a map of keys to current values stored on disk that has * previously been cached */ /** * @method write * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~Serializer# * @param {Array.Object} ops difference of values to be stored in the disk cache * @param {string} ops.key * @param ops.value * @returns {Promise} promise that resolves when writing completes */ const FileSerializerPlugin = require('./SerializerFilePlugin'); const Append2SerializerPlugin = require('./SerializerAppend2Plugin'); const pluginCompat = require('./util/plugin-compat'); /** * @constructor CacheSerializerFactory * @memberof module:hard-source-webpack-plugin/cache-serializer-factory */ class CacheSerializerFactory { constructor(compiler) { this.compiler = compiler; pluginCompat.register(compiler, 'hardSourceCacheFactory', 'syncWaterfall', [ 'factory', ]); pluginCompat.tap( compiler, 'hardSourceCacheFactory', 'default factory', factory => info => { // It's best to have plugins to hard-source listed in the config after it // but to make hard-source easier to use we can call the factory of a // plugin passed into this default factory. if (factory) { serializer = factory(info); if (serializer) { return serializer; } } // Otherwise lets return the default serializers. switch (info.type) { case 'data': return CacheSerializerFactory.dataSerializer.createSerializer(info); break; case 'file': return CacheSerializerFactory.fileSerializer.createSerializer(info); break; default: throw new Error( `Unknown hard-source cache serializer type: ${info.type}`, ); break; } }, ); } /** * @method create * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~CacheSerializerFactory# * @param {Object} info * @param {String} info.name * @param {String} info.type * @param {String} info.cacheDirPath * @returns {Serializer} */ create(info) { const factory = pluginCompat.call(this.compiler, 'hardSourceCacheFactory', [ null, ]); const serializer = factory(info); return serializer; } } /** * The default data serializer factory. */ CacheSerializerFactory.dataSerializer = Append2SerializerPlugin; /** * The default file serializer factory. */ CacheSerializerFactory.fileSerializer = FileSerializerPlugin; module.exports = CacheSerializerFactory;