@discoveryjs/cli
Advanced tools
Comparing version
@@ -0,1 +1,8 @@ | ||
## 2.0.0-beta.9 (04-03-2021) | ||
- Added `inspector` and `router` options in model's `view` config | ||
- Changed `prepare` modules handling. Now a `prepare` module should export a function instead of calling `discovery.setPrepare()` method and no more `discovery` (a reference to `App` or `Widget` instance) injected into module's scope. | ||
- Added support for a common `prepare` function. When `modelBaseConfig.prepare` is set it invokes for every model, right before model's `prepare` if any. | ||
- Added config change detection on server's asset bundling, it eliminates the need to restart the server on config change to get assets according changes | ||
## 2.0.0-beta.8 (01-03-2021) | ||
@@ -2,0 +9,0 @@ |
@@ -0,4 +1,65 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const makeBundle = require('../shared/bundle'); | ||
const configUtils = require('../shared/config'); | ||
const { logMsg, logError } = require('../shared/utils'); | ||
const refreshConfigMap = new WeakMap(); | ||
function alwaysFreshConfig(config, options) { | ||
if (!refreshConfigMap.has(config)) { | ||
refreshConfigMap.set(config, { | ||
requireCacheDigest: Object.create(null), | ||
lastRequireCacheCheck: 0, | ||
config | ||
}); | ||
} | ||
const cfg = refreshConfigMap.get(config); | ||
const newDigest = Object.create(null); | ||
let changed = false; | ||
// don't check if last check was less than 1 second ago | ||
if (Date.now() - cfg.lastRequireCacheCheck < 1000) { | ||
return cfg.config; | ||
} | ||
// avoid update on first check | ||
if (cfg.lastRequireCacheCheck === 0) { | ||
cfg.requireCacheDigest = newDigest; | ||
} | ||
// check modules in cache is changed | ||
for (const ref of [...new Set([...Object.keys(require.cache), ...Object.keys(cfg.requireCacheDigest)])]) { | ||
const { mtime } = fs.statSync(ref); | ||
newDigest[ref] = Number(mtime); | ||
if (cfg.requireCacheDigest[ref] !== Number(mtime)) { | ||
changed = true; | ||
} | ||
} | ||
cfg.lastRequireCacheCheck = Date.now(); | ||
if (changed) { | ||
// drop require cache | ||
for (const ref of Object.keys(require.cache)) { | ||
delete require.cache[ref]; | ||
} | ||
logMsg('Сonfig change detected, reload config...'); | ||
// load fresh config and update configuration | ||
try { | ||
cfg.config = configUtils.loadConfigWithFallback(options).config; | ||
cfg.requireCacheDigest = newDigest; | ||
} catch (e) { | ||
logError('Config load failed', e); | ||
throw e; | ||
} | ||
} | ||
// fresh config or the same if nothing changed | ||
return cfg.config; | ||
} | ||
async function responseBundleAsset(res, next, type, content) { | ||
@@ -22,3 +83,3 @@ try { | ||
if (!currentBundle || !/\.map$/.test(type)) { | ||
currentBundle = makeBundle(config, options, { | ||
currentBundle = makeBundle(alwaysFreshConfig(config, options), options, { | ||
outdir: '/', | ||
@@ -25,0 +86,0 @@ // FIXME: Disable incremental build for now, since it's as twice as slower |
@@ -11,16 +11,3 @@ const path = require('path'); | ||
module.exports = fn => Object.assign(options => { | ||
const configFile = configUtils.resolveConfigFilename(options.configFile); | ||
const config = configFile | ||
? configUtils.loadConfig(configFile, { | ||
model: options.model, | ||
cachedir: options.cachedir, | ||
cache: options.cache, | ||
cachePersistent: options.cachePersistent | ||
}) | ||
: { | ||
...configUtils.normalizeConfig({}), | ||
name: 'Discovery', | ||
mode: 'modelfree', | ||
models: [] | ||
}; | ||
const { configFile, config } = configUtils.loadConfigWithFallback(options); | ||
@@ -27,0 +14,0 @@ return fn(options, config, preprocessConfigFile(configFile)); |
@@ -32,3 +32,6 @@ const fs = require('fs'); | ||
files.set(`${modelConfig.slug}/setup.js`, () => gen['/gen/setup.js'](modelConfig, options, config, cacheDispatcher)); | ||
files.set(`${modelConfig.slug}/prepare.js`, () => modelConfig.prepare); | ||
files.set(`${modelConfig.slug}/prepare.js`, () => [ | ||
['commonPrepare', modelConfig.commonPrepare], | ||
['modelPrepare', modelConfig.prepare] | ||
].filter(([, path]) => path)); | ||
files.set(`${modelConfig.slug}/extensions.js`, () => selectAssets(modelConfig) | ||
@@ -121,5 +124,21 @@ .filter(fn => /\.[tj]sx?/.test(path.extname(fn))) | ||
resolveDir: '/', | ||
contents: 'export default [\n' + (contents | ||
? ' require(' + JSON.stringify(contents + ':discovery') + ')' | ||
: '') + '\n]' | ||
contents: contents | ||
.map(([name, path]) => | ||
`import ${name} from ${JSON.stringify(path)};\n` | ||
).join('') + | ||
[ | ||
'export default function(host) {', | ||
` const prepares = [${contents.map(([name]) => name).join(', ')}].filter(p => {`, | ||
' if (typeof p === "function") return true;', | ||
' console.warn("[discovery-cli] \\"prepare\\" module should return a function, but got " + typeof p);', | ||
' });', | ||
' if (prepares.length) {', | ||
' host.setPrepare((data, ...args) => {', | ||
' for (const prepare of prepares) {', | ||
' data = prepare(data, ...args) || data;', | ||
' }', | ||
' });', | ||
' }', | ||
'}' | ||
].join('\n') | ||
}; | ||
@@ -126,0 +145,0 @@ |
@@ -66,2 +66,4 @@ const fs = require('fs'); | ||
libs, | ||
inspector, | ||
router, | ||
assets | ||
@@ -73,2 +75,8 @@ } = viewConfig || {}; | ||
// inspector (enabled by default) | ||
inspector = inspector === undefined || Boolean(inspector); | ||
// default router (enabled by default) | ||
router = router === undefined || Boolean(router); | ||
// assets | ||
@@ -85,2 +93,4 @@ assets = (Array.isArray(assets) ? assets : []) | ||
...stripKeys(viewConfig || {}, ['basedir']), | ||
inspector, | ||
router, | ||
assets, | ||
@@ -244,3 +254,3 @@ warnings | ||
...normalizeModelConfig({ | ||
...modelBaseConfig, | ||
...stripKeys(modelBaseConfig, 'prepare'), | ||
...resolvedConfig | ||
@@ -250,2 +260,6 @@ }, modelBasedir) | ||
if (modelBaseConfig.prepare) { | ||
modelConfig.commonPrepare = modelBaseConfig.prepare; | ||
} | ||
modelConfig.darkmode = 'darkmode' in modelConfig | ||
@@ -324,2 +338,23 @@ ? modelConfig.darkmode | ||
function loadConfigWithFallback({ configFile, model, cachedir, cache, cachePersistent }) { | ||
const resolvedConfigFile = resolveConfigFilename(configFile); | ||
const config = resolvedConfigFile | ||
? loadConfig(resolvedConfigFile, { | ||
model, | ||
cachedir, | ||
cache, | ||
cachePersistent | ||
}) | ||
: { | ||
...normalizeConfig({}), | ||
name: 'Discovery', | ||
mode: 'modelfree' | ||
}; | ||
return { | ||
configFile: resolvedConfigFile, | ||
config | ||
}; | ||
} | ||
module.exports = { | ||
@@ -330,3 +365,4 @@ resolveConfigFilename, | ||
normalizeConfig, | ||
loadConfig | ||
loadConfig, | ||
loadConfigWithFallback | ||
}; |
@@ -55,3 +55,4 @@ const path = require('path'); | ||
download, | ||
darkmode | ||
darkmode, | ||
view | ||
} = modelConfig; | ||
@@ -62,2 +63,6 @@ const { | ||
} = cacheDispatcher.getModelCacheInfo(slug); | ||
const { | ||
inspector, | ||
router | ||
} = view || {}; | ||
@@ -71,2 +76,4 @@ return { | ||
darkmode, | ||
inspector, | ||
router, | ||
meta: meta || null | ||
@@ -73,0 +80,0 @@ }; |
@@ -15,2 +15,4 @@ /* eslint-env browser */ | ||
download: model.download, | ||
inspector: model.inspector, | ||
router: model.router, | ||
cache: model.cache, | ||
@@ -17,0 +19,0 @@ cacheReset: model.cacheReset, |
{ | ||
"name": "@discoveryjs/cli", | ||
"version": "2.0.0-beta.8", | ||
"version": "2.0.0-beta.9", | ||
"description": "CLI tools to serve & build projects based on Discovery.js", | ||
@@ -39,3 +39,3 @@ "author": "Roman Dvornov <rdvornov@gmail.com> (https://github.com/lahmatiy)", | ||
"cronstrue": "^1.109.0", | ||
"esbuild": "^0.8.54", | ||
"esbuild": "^0.8.55", | ||
"express": "^4.17.1", | ||
@@ -42,0 +42,0 @@ "mime": "^2.4.4", |
136835
3.37%2650
3.76%27
3.85%Updated