This repository has been archived by the owner on Jun 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow opting out of using worker for asset bundling
Add a flag `bundleInProcess` that does asset bundling in-process instead of using a worker. This is helpful when you don't want to clean up after the server is no longer used, particularly when testing a Podlet or Layout server with a local instance of the asset server. Note: `bundler#endWorkers` is made async.
- Loading branch information
Showing
13 changed files
with
286 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
const bundleJS = require('@asset-pipe/js-reader'); | ||
const bundleCSS = require('@asset-pipe/css-reader'); | ||
|
||
module.exports.bundleJS = bundleJS; | ||
module.exports.bundleCSS = bundleCSS; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,133 @@ | ||
'use strict'; | ||
|
||
const bundleJS = require('@asset-pipe/js-reader'); | ||
const bundleCSS = require('@asset-pipe/css-reader'); | ||
const assert = require('assert'); | ||
const Boom = require('boom'); | ||
const { promisify } = require('util'); | ||
const body = promisify(require('body/json')); | ||
const schemas = require('./schemas'); | ||
const parseJson = require('parse-json'); | ||
const { hasher } = require('@asset-pipe/common'); | ||
const { default: Worker } = require('jest-worker'); | ||
|
||
module.exports.bundleJS = bundleJS; | ||
module.exports.bundleCSS = bundleCSS; | ||
module.exports = class Bundler { | ||
constructor({ bundleInProcess = false } = {}) { | ||
this.bundleInProcess = bundleInProcess; | ||
|
||
if (bundleInProcess) { | ||
this.bundler = require('./bundler-utils'); | ||
} else { | ||
this.bundler = new Worker(require.resolve('./bundler-utils'), { | ||
numWorkers: 2, | ||
}); | ||
} | ||
} | ||
|
||
async fetchFeeds(sink, ids) { | ||
try { | ||
return await Promise.all( | ||
ids.map(async fileName => ({ | ||
fileName, | ||
contents: await sink.get(fileName), | ||
})) | ||
); | ||
} catch (err) { | ||
throw Boom.boomify(err, { | ||
message: 'Unable to fetch 1 or more feeds.', | ||
}); | ||
} | ||
} | ||
|
||
parseFeedContent(feeds) { | ||
const result = []; | ||
for (const { fileName, contents } of feeds) { | ||
try { | ||
result.push(parseJson(contents)); | ||
} catch (err) { | ||
throw Boom.boomify(err, { | ||
message: `Unable to parse 1 or more feeds as JSON. File ${fileName} was unparseable.`, | ||
}); | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
async bundleFeeds(feeds, type, options) { | ||
if (type === 'css') { | ||
try { | ||
return await this.bundler.bundleCSS(feeds); | ||
} catch (err) { | ||
throw Boom.boomify(err, { | ||
message: 'Unable to bundle feeds as CSS.', | ||
}); | ||
} | ||
} else { | ||
try { | ||
return await this.bundler.bundleJS(feeds, options); | ||
} catch (err) { | ||
throw Boom.boomify(err, { | ||
message: 'Unable to bundle feeds as JS.', | ||
}); | ||
} | ||
} | ||
} | ||
|
||
async upload(sink, fileName, content) { | ||
try { | ||
return await sink.set(fileName, content); | ||
} catch (err) { | ||
throw Boom.boomify(err, { | ||
message: `Unable to upload file with name "${fileName}".`, | ||
}); | ||
} | ||
} | ||
|
||
async bundleAndUpload({ sink, type, feedIds, uri, ...options }) { | ||
assert( | ||
Array.isArray(feedIds) && feedIds.length > 0, | ||
`Expected at least 1 feed id, but got ${feedIds}` | ||
); | ||
|
||
const fetchedFeeds = await this.fetchFeeds(sink, feedIds, 3); | ||
const parsedFeeds = this.parseFeedContent(fetchedFeeds); | ||
const content = await this.bundleFeeds(parsedFeeds, type, options); | ||
const fileName = `${hasher(content)}.${type}`; | ||
await this.upload(sink, fileName, content, 3); | ||
|
||
return { | ||
file: fileName, | ||
uri: uri + fileName, | ||
}; | ||
} | ||
|
||
async parseBody(req, res) { | ||
try { | ||
return await body(req, res, {}); | ||
} catch (e) { | ||
throw Boom.boomify(e, { | ||
statusCode: 400, | ||
message: | ||
'Unparsable feed data given in POST-body. Invalid or empty JSON payload.', | ||
}); | ||
} | ||
} | ||
|
||
validateFeeds(feeds) { | ||
const result = schemas.ids.validate(feeds); | ||
if (result.error) { | ||
throw Boom.boomify(result.error, { | ||
statusCode: 400, | ||
message: 'Invalid feed data given in POST-body.', | ||
}); | ||
} | ||
return result.value; | ||
} | ||
|
||
async endWorkers() { | ||
if (this.bundleInProcess) { | ||
return false; | ||
} | ||
|
||
await this.bundler.end(); | ||
return true; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.