Removed GopherJS, basic frontend completed, need backend changes for

torrent storage
This commit is contained in:
2017-11-30 18:12:11 -05:00
parent 67fdef16b1
commit e98ad2cc88
69321 changed files with 5498914 additions and 337 deletions

View File

@@ -0,0 +1,93 @@
'use strict';
var toposort = require('toposort');
var _ = require('lodash');
/*
Sorts dependencies between chunks by their "parents" attribute.
This function sorts chunks based on their dependencies with each other.
The parent relation between chunks as generated by Webpack for each chunk
is used to define a directed (and hopefully acyclic) graph, which is then
topologically sorted in order to retrieve the correct order in which
chunks need to be embedded into HTML. A directed edge in this graph is
describing a "is parent of" relationship from a chunk to another (distinct)
chunk. Thus topological sorting orders chunks from bottom-layer chunks to
highest level chunks that use the lower-level chunks.
@param {Array} chunks an array of chunks as generated by the html-webpack-plugin.
It is assumed that each entry contains at least the properties "id"
(containing the chunk id) and "parents" (array containing the ids of the
parent chunks).
@return {Array} A topologically sorted version of the input chunks
*/
module.exports.dependency = function (chunks) {
if (!chunks) {
return chunks;
}
// We build a map (chunk-id -> chunk) for faster access during graph building.
var nodeMap = {};
chunks.forEach(function (chunk) {
nodeMap[chunk.id] = chunk;
});
// Next, we add an edge for each parent relationship into the graph
var edges = [];
chunks.forEach(function (chunk) {
if (chunk.parents) {
// Add an edge for each parent (parent -> child)
chunk.parents.forEach(function (parentId) {
// webpack2 chunk.parents are chunks instead of string id(s)
var parentChunk = _.isObject(parentId) ? parentId : nodeMap[parentId];
// If the parent chunk does not exist (e.g. because of an excluded chunk)
// we ignore that parent
if (parentChunk) {
edges.push([parentChunk, chunk]);
}
});
}
});
// We now perform a topological sorting on the input chunks and built edges
return toposort.array(chunks, edges);
};
/**
* Sorts the chunks based on the chunk id.
*
* @param {Array} chunks the list of chunks to sort
* @return {Array} The sorted list of chunks
*/
module.exports.id = function (chunks) {
return chunks.sort(function orderEntryLast (a, b) {
if (a.entry !== b.entry) {
return b.entry ? 1 : -1;
} else {
return b.id - a.id;
}
});
};
/**
* Performs identity mapping (no-sort).
* @param {Array} chunks the chunks to sort
* @return {Array} The sorted chunks
*/
module.exports.none = function (chunks) {
return chunks;
};
/**
* Defines the default sorter.
*/
module.exports.auto = module.exports.id;
// In webpack 2 the ids have been flipped.
// Therefore the id sort doesn't work the same way as it did for webpack 1
// Luckily the dependency sort is working as expected
if (Number(require('webpack/package.json').version.split('.')[0]) > 1) {
module.exports.auto = module.exports.dependency;
}

View File

@@ -0,0 +1,112 @@
/*
* This file uses webpack to compile a template with a child compiler.
*
* [TEMPLATE] -> [JAVASCRIPT]
*
*/
'use strict';
var Promise = require('bluebird');
var _ = require('lodash');
var path = require('path');
var NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
/**
* Compiles the template into a nodejs factory, adds its to the compilation.assets
* and returns a promise of the result asset object.
*
* @param template relative path to the template file
* @param context path context
* @param outputFilename the file name
* @param compilation The webpack compilation object
*
* Returns an object:
* {
* hash: {String} - Base64 hash of the file
* content: {String} - Javascript executable code of the template
* }
*
*/
module.exports.compileTemplate = function compileTemplate (template, context, outputFilename, compilation) {
// The entry file is just an empty helper as the dynamic template
// require is added in "loader.js"
var outputOptions = {
filename: outputFilename,
publicPath: compilation.outputOptions.publicPath
};
// Store the result of the parent compilation before we start the child compilation
var assetsBeforeCompilation = _.assign({}, compilation.assets[outputOptions.filename]);
// Create an additional child compiler which takes the template
// and turns it into an Node.JS html factory.
// This allows us to use loaders during the compilation
var compilerName = getCompilerName(context, outputFilename);
var childCompiler = compilation.createChildCompiler(compilerName, outputOptions);
childCompiler.context = context;
childCompiler.apply(
new NodeTemplatePlugin(outputOptions),
new NodeTargetPlugin(),
new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var'),
new SingleEntryPlugin(this.context, template),
new LoaderTargetPlugin('node')
);
// Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"
// Hot module replacement requires that every child compiler has its own
// cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179
childCompiler.plugin('compilation', function (compilation) {
if (compilation.cache) {
if (!compilation.cache[compilerName]) {
compilation.cache[compilerName] = {};
}
compilation.cache = compilation.cache[compilerName];
}
});
// Compile and return a promise
return new Promise(function (resolve, reject) {
childCompiler.runAsChild(function (err, entries, childCompilation) {
// Resolve / reject the promise
if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
var errorDetails = childCompilation.errors.map(function (error) {
return error.message + (error.error ? ':\n' + error.error : '');
}).join('\n');
reject(new Error('Child compilation failed:\n' + errorDetails));
} else if (err) {
reject(err);
} else {
// Replace [hash] placeholders in filename
var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
hash: childCompilation.hash,
chunk: entries[0]
});
// Restore the parent compilation to the state like it
// was before the child compilation
compilation.assets[outputName] = assetsBeforeCompilation[outputName];
if (assetsBeforeCompilation[outputName] === undefined) {
// If it wasn't there - delete it
delete compilation.assets[outputName];
}
resolve({
// Hash of the template entry point
hash: entries[0].hash,
// Output name
outputName: outputName,
// Compiled code
content: childCompilation.assets[outputName].source()
});
}
});
});
};
/**
* Returns the child compiler name e.g. 'html-webpack-plugin for "index.html"'
*/
function getCompilerName (context, filename) {
var absolutePath = path.resolve(context, filename);
var relativePath = path.relative(context, absolutePath);
return 'html-webpack-plugin for "' + (absolutePath.length < relativePath.length ? absolutePath : relativePath) + '"';
}

View File

@@ -0,0 +1,23 @@
'use strict';
var PrettyError = require('pretty-error');
var prettyError = new PrettyError();
prettyError.withoutColors();
prettyError.skipPackage(['html-plugin-evaluation']);
prettyError.skipNodeFiles();
prettyError.skip(function (traceLine) {
return traceLine.path === 'html-plugin-evaluation';
});
module.exports = function (err, context) {
return {
toHtml: function () {
return 'Html Webpack Plugin:\n<pre>\n' + this.toString() + '</pre>';
},
toJsonHtml: function () {
return JSON.stringify(this.toHtml());
},
toString: function () {
return prettyError.render(err).replace(/webpack:\/\/\/\./g, context);
}
};
};

View File

@@ -0,0 +1,51 @@
/* This loader renders the template with underscore if no other loader was found */
'use strict';
var _ = require('lodash');
var loaderUtils = require('loader-utils');
module.exports = function (source) {
if (this.cacheable) {
this.cacheable();
}
var allLoadersButThisOne = this.loaders.filter(function (loader) {
// Loader API changed from `loader.module` to `loader.normal` in Webpack 2.
return (loader.module || loader.normal) !== module.exports;
});
// This loader shouldn't kick in if there is any other loader
if (allLoadersButThisOne.length > 0) {
return source;
}
// Skip .js files
if (/\.js$/.test(this.resourcePath)) {
return source;
}
// The following part renders the tempalte with lodash as aminimalistic loader
//
// Get templating options
var options = loaderUtils.parseQuery(this.query);
// Webpack 2 does not allow with() statements, which lodash templates use to unwrap
// the parameters passed to the compiled template inside the scope. We therefore
// need to unwrap them ourselves here. This is essentially what lodash does internally
// To tell lodash it should not use with we set a variable
var template = _.template(source, _.defaults(options, { variable: 'data' }));
// All templateVariables which should be available
// @see HtmlWebpackPlugin.prototype.executeTemplate
var templateVariables = [
'compilation',
'webpack',
'webpackConfig',
'htmlWebpackPlugin'
];
return 'var _ = require(' + loaderUtils.stringifyRequest(this, require.resolve('lodash')) + ');' +
'module.exports = function (templateParams) {' +
// Declare the template variables in the outer scope of the
// lodash template to unwrap them
templateVariables.map(function (variableName) {
return 'var ' + variableName + ' = templateParams.' + variableName;
}).join(';') + ';' +
// Execute the lodash template
'return (' + template.source + ')();' +
'}';
};