@c9up/ream 0.2.23 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Codemods.d.ts +1 -0
- package/dist/Codemods.d.ts.map +1 -1
- package/dist/Codemods.js +44 -0
- package/dist/Codemods.js.map +1 -1
- package/dist/Ignitor.d.ts +50 -0
- package/dist/Ignitor.d.ts.map +1 -1
- package/dist/Ignitor.js +15 -15
- package/dist/Ignitor.js.map +1 -1
- package/dist/dev/fullReload.d.ts +23 -0
- package/dist/dev/fullReload.d.ts.map +1 -0
- package/dist/dev/fullReload.js +26 -0
- package/dist/dev/fullReload.js.map +1 -0
- package/dist/dev/hmr.d.ts +52 -4
- package/dist/dev/hmr.d.ts.map +1 -1
- package/dist/dev/hmr.js +75 -9
- package/dist/dev/hmr.js.map +1 -1
- package/dist/dev/hotGlob.d.ts +35 -0
- package/dist/dev/hotGlob.d.ts.map +1 -0
- package/dist/dev/hotGlob.js +92 -0
- package/dist/dev/hotGlob.js.map +1 -0
- package/dist/dev/hotGraph.d.ts +58 -0
- package/dist/dev/hotGraph.d.ts.map +1 -0
- package/dist/dev/hotGraph.js +91 -0
- package/dist/dev/hotGraph.js.map +1 -0
- package/dist/dev/hotWatcher.d.ts +34 -0
- package/dist/dev/hotWatcher.d.ts.map +1 -0
- package/dist/dev/hotWatcher.js +72 -0
- package/dist/dev/hotWatcher.js.map +1 -0
- package/dist/env/loadEnvFiles.d.ts +13 -0
- package/dist/env/loadEnvFiles.d.ts.map +1 -1
- package/dist/env/loadEnvFiles.js +65 -13
- package/dist/env/loadEnvFiles.js.map +1 -1
- package/dist/hot.d.ts +13 -16
- package/dist/hot.d.ts.map +1 -1
- package/dist/hot.js +161 -84
- package/dist/hot.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/events.darwin-arm64.node +0 -0
- package/events.darwin-x64.node +0 -0
- package/events.linux-arm64-gnu.node +0 -0
- package/events.linux-x64-gnu.node +0 -0
- package/events.win32-x64-msvc.node +0 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +4 -7
- package/scheduler.darwin-arm64.node +0 -0
- package/scheduler.darwin-x64.node +0 -0
- package/scheduler.linux-arm64-gnu.node +0 -0
- package/scheduler.linux-x64-gnu.node +0 -0
- package/scheduler.win32-x64-msvc.node +0 -0
- package/src/Codemods.ts +53 -0
- package/src/Ignitor.ts +68 -14
- package/src/dev/fullReload.ts +34 -0
- package/src/dev/hmr.ts +102 -9
- package/src/dev/hotGlob.ts +91 -0
- package/src/dev/hotGraph.ts +109 -0
- package/src/dev/hotWatcher.ts +89 -0
- package/src/env/loadEnvFiles.ts +69 -14
- package/src/hot.ts +169 -102
- package/src/index.ts +1 -1
package/dist/env/loadEnvFiles.js
CHANGED
|
@@ -1,8 +1,56 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
3
|
import { parseEnv } from 'node:util';
|
|
4
4
|
import { interpolate } from './interpolate.js';
|
|
5
5
|
import { normalizeNodeEnv } from './nodeEnv.js';
|
|
6
|
+
/**
|
|
7
|
+
* The `.env*` files that will be read, most-specific first.
|
|
8
|
+
*
|
|
9
|
+
* Exported because `@c9up/ream/hot` has to WATCH exactly this list: nothing
|
|
10
|
+
* imports an env file, so hot-hook's dependency tree never sees one and an
|
|
11
|
+
* edit to `.env` changed nothing at all. A second copy of the list in the
|
|
12
|
+
* loader entry would drift from this one the first time the naming changes.
|
|
13
|
+
*
|
|
14
|
+
* @param options.skipEnvLocal Skip `.env.local` — see {@link loadEnvFiles}.
|
|
15
|
+
*/
|
|
16
|
+
export function envFileNames(options = {}) {
|
|
17
|
+
// Normalised, so `NODE_ENV=prod` loads `.env.production` — the file the
|
|
18
|
+
// deployment actually wrote — instead of looking for `.env.prod`.
|
|
19
|
+
const raw = normalizeNodeEnv(process.env.NODE_ENV);
|
|
20
|
+
const nodeEnv = raw === 'unknown' ? undefined : raw;
|
|
21
|
+
return [
|
|
22
|
+
nodeEnv ? `.env.${nodeEnv}.local` : null,
|
|
23
|
+
options.skipEnvLocal ? null : '.env.local',
|
|
24
|
+
nodeEnv ? `.env.${nodeEnv}` : null,
|
|
25
|
+
'.env',
|
|
26
|
+
].filter((name) => name !== null);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Where the `.env*` files are read from.
|
|
30
|
+
*
|
|
31
|
+
* Normally beside the application, which is what `appRoot` names. A BUILT
|
|
32
|
+
* application moves: `start/env.js` sits in `dist/`, so `new URL('../',
|
|
33
|
+
* import.meta.url)` resolves there and the files at the project root become
|
|
34
|
+
* invisible — `ream start` died on a `.env` it was standing next to.
|
|
35
|
+
*
|
|
36
|
+
* `ENV_PATH` is AdonisJS's own variable for this, named and shaped the same
|
|
37
|
+
* way: a DIRECTORY to read the files from, as in
|
|
38
|
+
* `ENV_PATH=/etc/secrets node server.js`. An application moving over keeps
|
|
39
|
+
* whatever it already sets.
|
|
40
|
+
*
|
|
41
|
+
* It is also why the ordering rule stays here rather than in the CLI: node's
|
|
42
|
+
* `--env-file` applies files last-wins while this loader applies them
|
|
43
|
+
* most-specific-first, and a second copy of that would be one to keep in step
|
|
44
|
+
* forever.
|
|
45
|
+
*/
|
|
46
|
+
function envDirectory(appRoot) {
|
|
47
|
+
const override = process.env.ENV_PATH;
|
|
48
|
+
if (override === undefined || override.trim() === '')
|
|
49
|
+
return appRoot;
|
|
50
|
+
// A directory URL, so `new URL('.env', directory)` lands inside it rather
|
|
51
|
+
// than beside it.
|
|
52
|
+
return pathToFileURL(override.endsWith('/') ? override : `${override}/`);
|
|
53
|
+
}
|
|
6
54
|
/**
|
|
7
55
|
* Load `.env` files into `process.env` — the shared primitive behind both the
|
|
8
56
|
* Ignitor (HTTP/console boot) and `Env.create()` (config/test flow), mirroring
|
|
@@ -17,24 +65,17 @@ import { normalizeNodeEnv } from './nodeEnv.js';
|
|
|
17
65
|
* developer's local overrides don't leak into tests).
|
|
18
66
|
*/
|
|
19
67
|
export function loadEnvFiles(appRoot, options = {}) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const nodeEnv = raw === 'unknown' ? undefined : raw;
|
|
24
|
-
const files = [
|
|
25
|
-
nodeEnv ? `.env.${nodeEnv}.local` : null,
|
|
26
|
-
options.skipEnvLocal ? null : '.env.local',
|
|
27
|
-
nodeEnv ? `.env.${nodeEnv}` : null,
|
|
28
|
-
'.env',
|
|
29
|
-
].filter((name) => name !== null);
|
|
30
|
-
for (const name of files) {
|
|
68
|
+
const directory = envDirectory(appRoot);
|
|
69
|
+
let found = false;
|
|
70
|
+
for (const name of envFileNames(options)) {
|
|
31
71
|
let contents;
|
|
32
72
|
try {
|
|
33
|
-
contents = readFileSync(fileURLToPath(new URL(name,
|
|
73
|
+
contents = readFileSync(fileURLToPath(new URL(name, directory)), 'utf8');
|
|
34
74
|
}
|
|
35
75
|
catch {
|
|
36
76
|
continue; // file absent — nothing to load
|
|
37
77
|
}
|
|
78
|
+
found = true;
|
|
38
79
|
const parsed = parseEnv(contents);
|
|
39
80
|
for (const [key, value] of Object.entries(parsed)) {
|
|
40
81
|
if (typeof value !== 'string' || process.env[key] !== undefined)
|
|
@@ -50,5 +91,16 @@ export function loadEnvFiles(appRoot, options = {}) {
|
|
|
50
91
|
});
|
|
51
92
|
}
|
|
52
93
|
}
|
|
94
|
+
// Upstream raises when `ENV_PATH` names a place with no env file in it, and
|
|
95
|
+
// for the reason silence would be wrong: the variable is somebody saying
|
|
96
|
+
// where the file IS. A typo in the path would otherwise start a server on
|
|
97
|
+
// whatever defaults happened to be around, which is how a deployment reads
|
|
98
|
+
// its staging config in production and nobody finds out until later.
|
|
99
|
+
//
|
|
100
|
+
// Without `ENV_PATH` a missing file stays silent: an application may have
|
|
101
|
+
// none at all, and every value may come from the environment.
|
|
102
|
+
if (!found && process.env.ENV_PATH !== undefined && process.env.ENV_PATH.trim() !== '') {
|
|
103
|
+
throw new Error(`ENV_PATH points at ${process.env.ENV_PATH}, which holds none of ${envFileNames(options).join(', ')}`);
|
|
104
|
+
}
|
|
53
105
|
}
|
|
54
106
|
//# sourceMappingURL=loadEnvFiles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadEnvFiles.js","sourceRoot":"","sources":["../../src/env/loadEnvFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"loadEnvFiles.js","sourceRoot":"","sources":["../../src/env/loadEnvFiles.ts"],"names":[],"mappings":"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"}
|
package/dist/hot.d.ts
CHANGED
|
@@ -5,25 +5,22 @@
|
|
|
5
5
|
*
|
|
6
6
|
* node --import @swc-node/register/esm-register --import @c9up/ream/hot bin/server.ts
|
|
7
7
|
*
|
|
8
|
-
* It
|
|
9
|
-
*
|
|
10
|
-
* boundary changes it invalidates just that module instead of the process. The
|
|
11
|
-
* `hotHook` key in the application's `package.json` configures it, exactly as
|
|
12
|
-
* upstream reads it.
|
|
8
|
+
* It replaces a module that changed instead of the process that was serving it,
|
|
9
|
+
* so the container, the pools and the connections survive a save.
|
|
13
10
|
*
|
|
14
|
-
* NAMED DEVIATION —
|
|
11
|
+
* NAMED DEVIATION — this is ream's own, where AdonisJS uses `hot-hook`.
|
|
15
12
|
*
|
|
16
|
-
* Upstream
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
13
|
+
* Upstream ships that package in its starter kit, which means every application
|
|
14
|
+
* installs it, and one created before the convention existed silently loses hot
|
|
15
|
+
* reloading. The parts that once justified a library are now in Node:
|
|
16
|
+
* `module.registerHooks` gives the import graph, `fs.watch` gives the changes.
|
|
17
|
+
* What is left is the decision of what to invalidate, which is this file and
|
|
18
|
+
* its three neighbours — and no entry in anyone's `package.json`.
|
|
22
19
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* The graph comes from the resolver rather than from reading files: a resolve
|
|
21
|
+
* hook is handed the importer and the imported, which is exactly an edge, and
|
|
22
|
+
* it sees a dynamic import at the moment it happens rather than guessing at it
|
|
23
|
+
* from the source.
|
|
27
24
|
*/
|
|
28
25
|
export {};
|
|
29
26
|
//# sourceMappingURL=hot.d.ts.map
|
package/dist/hot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hot.d.ts","sourceRoot":"","sources":["../src/hot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hot.d.ts","sourceRoot":"","sources":["../src/hot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
|
package/dist/hot.js
CHANGED
|
@@ -5,108 +5,185 @@
|
|
|
5
5
|
*
|
|
6
6
|
* node --import @swc-node/register/esm-register --import @c9up/ream/hot bin/server.ts
|
|
7
7
|
*
|
|
8
|
-
* It
|
|
9
|
-
*
|
|
10
|
-
* boundary changes it invalidates just that module instead of the process. The
|
|
11
|
-
* `hotHook` key in the application's `package.json` configures it, exactly as
|
|
12
|
-
* upstream reads it.
|
|
8
|
+
* It replaces a module that changed instead of the process that was serving it,
|
|
9
|
+
* so the container, the pools and the connections survive a save.
|
|
13
10
|
*
|
|
14
|
-
* NAMED DEVIATION —
|
|
11
|
+
* NAMED DEVIATION — this is ream's own, where AdonisJS uses `hot-hook`.
|
|
15
12
|
*
|
|
16
|
-
* Upstream
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
13
|
+
* Upstream ships that package in its starter kit, which means every application
|
|
14
|
+
* installs it, and one created before the convention existed silently loses hot
|
|
15
|
+
* reloading. The parts that once justified a library are now in Node:
|
|
16
|
+
* `module.registerHooks` gives the import graph, `fs.watch` gives the changes.
|
|
17
|
+
* What is left is the decision of what to invalidate, which is this file and
|
|
18
|
+
* its three neighbours — and no entry in anyone's `package.json`.
|
|
22
19
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* The graph comes from the resolver rather than from reading files: a resolve
|
|
21
|
+
* hook is handed the importer and the imported, which is exactly an edge, and
|
|
22
|
+
* it sees a dynamic import at the moment it happens rather than guessing at it
|
|
23
|
+
* from the source.
|
|
27
24
|
*/
|
|
25
|
+
import { existsSync, writeSync } from 'node:fs';
|
|
26
|
+
import { readFile } from 'node:fs/promises';
|
|
27
|
+
import { registerHooks } from 'node:module';
|
|
28
|
+
import { dirname, relative, resolve as resolvePath } from 'node:path';
|
|
29
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
30
|
+
import { fullReloadNotice } from './dev/fullReload.js';
|
|
28
31
|
import { hotReloadHappened } from './dev/hmr.js';
|
|
29
32
|
import { readHotHookConfig } from './dev/hotConfig.js';
|
|
33
|
+
import { globMatcher } from './dev/hotGlob.js';
|
|
34
|
+
import { HotGraph } from './dev/hotGraph.js';
|
|
35
|
+
import { watchProject } from './dev/hotWatcher.js';
|
|
36
|
+
import { envFileNames } from './env/loadEnvFiles.js';
|
|
30
37
|
/** Exit code meaning "restart me" — see `EXIT_RESTART` in the CLI's dev module. */
|
|
31
38
|
const FULL_RELOAD_EXIT_CODE = 75;
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
39
|
+
/** The query parameter that makes the loader fetch a module again. */
|
|
40
|
+
const VERSION_PARAM = 'ream_hot';
|
|
41
|
+
/** Directories a project keeps its own code in — the CLI watches the same list. */
|
|
42
|
+
const WATCH_DIRS = ['app', 'bin', 'config', 'start', 'database', 'providers', 'commands'];
|
|
43
|
+
const packageJsonPath = resolvePath(process.cwd(), 'package.json');
|
|
44
|
+
const root = dirname(packageJsonPath);
|
|
35
45
|
let config = {};
|
|
36
46
|
try {
|
|
37
47
|
config = readHotHookConfig(JSON.parse(await readFile(packageJsonPath, 'utf8')));
|
|
38
48
|
}
|
|
39
49
|
catch {
|
|
40
|
-
// No package.json, or unreadable:
|
|
41
|
-
//
|
|
50
|
+
// No package.json, or unreadable: a project with no boundaries declared gets
|
|
51
|
+
// a working server that restarts on change, which is the old behaviour.
|
|
42
52
|
}
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
const { boundaries = [], restart = [] } = config;
|
|
54
|
+
// Env files are not modules: nothing imports one, so the graph never sees them
|
|
55
|
+
// and an edit to `.env` did nothing at all — the values are read once, at boot.
|
|
56
|
+
// They always restart.
|
|
57
|
+
const restartFiles = new Set(envFileNames()
|
|
58
|
+
.map((name) => resolvePath(root, name))
|
|
59
|
+
.filter((file) => existsSync(file)));
|
|
60
|
+
/**
|
|
61
|
+
* `metaFiles` entries that asked for a restart.
|
|
62
|
+
*
|
|
63
|
+
* Non-module files the application owns — translations, view templates — live
|
|
64
|
+
* in `reamrc.ts` because the BUILD has to copy them. A change to one is
|
|
65
|
+
* invisible to the import graph, so the only way it can do anything in
|
|
66
|
+
* development is by being named here.
|
|
67
|
+
*
|
|
68
|
+
* `reloadServer: false` is the interesting default, and the one upstream picks
|
|
69
|
+
* for translations: the entry exists so the file ships, and an edit does NOT
|
|
70
|
+
* restart. NAMED DEVIATION — upstream still logs such a change, because its
|
|
71
|
+
* watcher covers the whole project anyway. This one watches a fixed list of
|
|
72
|
+
* directories on purpose (`resources/` belongs to the asset watcher, and a
|
|
73
|
+
* stylesheet edit must not restart the server), so a `false` entry is simply
|
|
74
|
+
* not watched. The observable behaviour is the same: nothing happens.
|
|
75
|
+
*/
|
|
76
|
+
async function readReloadPatterns() {
|
|
77
|
+
try {
|
|
78
|
+
const rc = (await import(pathToFileURL(resolvePath(root, 'reamrc.ts')).href));
|
|
79
|
+
return (rc.default?.metaFiles ?? [])
|
|
80
|
+
.filter((entry) => entry.reloadServer === true && typeof entry.pattern === 'string')
|
|
81
|
+
.map((entry) => String(entry.pattern));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// No rc file, or one that does not load. The server itself reports a broken
|
|
85
|
+
// rc far more clearly than the loader could, and a dev server that refuses
|
|
86
|
+
// to start because of a watch list helps nobody.
|
|
87
|
+
return [];
|
|
64
88
|
}
|
|
65
|
-
hot = candidate;
|
|
66
89
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
const reloadPatterns = await readReloadPatterns();
|
|
91
|
+
/**
|
|
92
|
+
* The directory a pattern lives under — everything before its first wildcard.
|
|
93
|
+
*
|
|
94
|
+
* `resources/lang/**\/*.json` is watched as `resources/lang`. Watching the
|
|
95
|
+
* project root instead would pull in `node_modules` and the build output.
|
|
96
|
+
*/
|
|
97
|
+
function watchRootOf(pattern) {
|
|
98
|
+
const segments = pattern.replace(/^\.\//, '').split('/');
|
|
99
|
+
const fixed = [];
|
|
100
|
+
for (const segment of segments) {
|
|
101
|
+
if (/[*?{[]/.test(segment))
|
|
102
|
+
break;
|
|
103
|
+
fixed.push(segment);
|
|
104
|
+
}
|
|
105
|
+
// A pattern that is a bare glob has no directory to narrow to.
|
|
106
|
+
return fixed.slice(0, -1).join('/') || fixed.join('/');
|
|
79
107
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
108
|
+
const relativeToRoot = (file) => relative(root, file).replace(/\\/g, '/');
|
|
109
|
+
const matchesBoundary = globMatcher(boundaries);
|
|
110
|
+
const matchesRestartGlob = globMatcher([...restart, ...reloadPatterns]);
|
|
111
|
+
const graph = new HotGraph({
|
|
112
|
+
isBoundary: (file) => matchesBoundary(relativeToRoot(file)),
|
|
113
|
+
isRestart: (file) => restartFiles.has(file) || matchesRestartGlob(relativeToRoot(file)),
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* Track every edge the resolver reports, and hand back a versioned URL for a
|
|
117
|
+
* module that has been invalidated.
|
|
118
|
+
*
|
|
119
|
+
* The version travels in the URL because that is the only handle V8 offers: a
|
|
120
|
+
* module is keyed by its URL, so a different one is a different module. The
|
|
121
|
+
* parameter is stripped off the importer before delegating, or a relative
|
|
122
|
+
* specifier would be resolved against a URL that does not name a directory.
|
|
123
|
+
*/
|
|
124
|
+
registerHooks({
|
|
125
|
+
resolve(specifier, context, nextResolve) {
|
|
126
|
+
let parentURL = context.parentURL;
|
|
127
|
+
let parentPath;
|
|
128
|
+
if (typeof parentURL === 'string' && parentURL.startsWith('file:')) {
|
|
129
|
+
const url = new URL(parentURL);
|
|
130
|
+
if (url.searchParams.has(VERSION_PARAM)) {
|
|
131
|
+
url.searchParams.delete(VERSION_PARAM);
|
|
132
|
+
parentURL = url.href;
|
|
133
|
+
}
|
|
134
|
+
parentPath = fileURLToPath(url);
|
|
135
|
+
}
|
|
136
|
+
const result = nextResolve(specifier, { ...context, parentURL });
|
|
137
|
+
if (!result.url.startsWith('file:'))
|
|
138
|
+
return result;
|
|
139
|
+
const resolved = new URL(result.url);
|
|
140
|
+
resolved.searchParams.delete(VERSION_PARAM);
|
|
141
|
+
const file = fileURLToPath(resolved);
|
|
142
|
+
graph.link(file, parentPath);
|
|
143
|
+
const version = graph.version(file);
|
|
144
|
+
if (version === 0)
|
|
145
|
+
return result;
|
|
146
|
+
resolved.searchParams.set(VERSION_PARAM, String(version));
|
|
147
|
+
return { ...result, url: resolved.href };
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
/** Print a line that must survive the exit on the very next statement. */
|
|
151
|
+
function sayNow(line) {
|
|
152
|
+
// Synchronously: a piped stdout — what `ream dev` hands this process when it
|
|
153
|
+
// runs an asset watcher alongside — is asynchronous, and the line would be
|
|
154
|
+
// dropped on the way out.
|
|
155
|
+
try {
|
|
156
|
+
writeSync(1, `${line}\n`);
|
|
96
157
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (typeof previousSend === 'function') {
|
|
100
|
-
return Reflect.apply(previousSend, process, [message, ...rest]) === true;
|
|
158
|
+
catch {
|
|
159
|
+
// The parent can close the pipe first on Ctrl-C. Losing the line is fine.
|
|
101
160
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
161
|
+
}
|
|
162
|
+
watchProject({
|
|
163
|
+
root,
|
|
164
|
+
directories: [
|
|
165
|
+
...WATCH_DIRS,
|
|
166
|
+
// Whatever a `reloadServer: true` entry named, and nothing else: the
|
|
167
|
+
// directories above are the ones the graph can reason about.
|
|
168
|
+
...reloadPatterns.map(watchRootOf).filter((dir) => dir !== ''),
|
|
169
|
+
],
|
|
170
|
+
files: [...restartFiles].map((file) => relative(root, file)),
|
|
171
|
+
onChange: (file) => {
|
|
172
|
+
const decision = graph.decide(file);
|
|
173
|
+
if (decision.kind === 'ignore')
|
|
174
|
+
return;
|
|
175
|
+
if (decision.kind === 'reload') {
|
|
176
|
+
sayNow(fullReloadNotice(decision.file, decision.reason, relativeToRoot));
|
|
177
|
+
// Exiting on a known code is how the Rust parent learns it must restart —
|
|
178
|
+
// see `EXIT_RESTART` in the CLI's dev module.
|
|
179
|
+
process.exit(FULL_RELOAD_EXIT_CODE);
|
|
180
|
+
}
|
|
181
|
+
// The router caches a promoted controller per route, and the kernel drops
|
|
182
|
+
// that cache when this counter moves. Without it the swap happens and the
|
|
183
|
+
// process keeps serving the class it promoted: a stable PID and stale
|
|
184
|
+
// output, which is exactly how it was first reported.
|
|
185
|
+
hotReloadHappened();
|
|
186
|
+
sayNow(`[ream] hot swap — ${relativeToRoot(file)}`);
|
|
187
|
+
},
|
|
111
188
|
});
|
|
112
189
|
//# sourceMappingURL=hot.js.map
|
package/dist/hot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hot.js","sourceRoot":"","sources":["../src/hot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hot.js","sourceRoot":"","sources":["../src/hot.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -121,5 +121,5 @@ export { BaseEvent, Emitter, type EmitterResolver, type ListenerClass, } from '.
|
|
|
121
121
|
export { type BufferedEvent, type BufferedEventName, type EventFinder, EventsBuffer, } from './events/EventsBuffer.js';
|
|
122
122
|
export type { ErrorReporter, LockBackend, LockBackendFactory, LockRedisClient, LockRedisResolver, RunTaskOutcome, ScheduleEvent, ScheduleEventSink, ScheduleInvocation, ScheduleMetadata, ScheduleProviderOptions, SchedulerConfig, SchedulerOptions, ScheduleTaskCompletedEvent, ScheduleTaskFailedEvent, ScheduleTaskSkippedEvent, ScheduleTaskStartedEvent, TaskInfo, TaskStats, } from './scheduler/index.js';
|
|
123
123
|
export { defineSchedulerConfig, getScheduleMetadata, locks, MemoryLockBackend, RedisLockBackend, SCHEDULE_METADATA_KEY, Schedule, ScheduleProvider, Scheduler, StatsTracker, } from './scheduler/index.js';
|
|
124
|
-
export declare const VERSION = "0.2.
|
|
124
|
+
export declare const VERSION = "0.2.25";
|
|
125
125
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -92,5 +92,5 @@ export { defineConfig as defineEventsConfig } from './events/config.js';
|
|
|
92
92
|
export { BaseEvent, Emitter, } from './events/Emitter.js';
|
|
93
93
|
export { EventsBuffer, } from './events/EventsBuffer.js';
|
|
94
94
|
export { defineSchedulerConfig, getScheduleMetadata, locks, MemoryLockBackend, RedisLockBackend, SCHEDULE_METADATA_KEY, Schedule, ScheduleProvider, Scheduler, StatsTracker, } from './scheduler/index.js';
|
|
95
|
-
export const VERSION = '0.2.
|
|
95
|
+
export const VERSION = '0.2.25';
|
|
96
96
|
//# sourceMappingURL=index.js.map
|
package/events.darwin-arm64.node
CHANGED
|
Binary file
|
package/events.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.darwin-arm64.node
CHANGED
|
Binary file
|
package/index.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
package/index.linux-x64-gnu.node
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c9up/ream",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"description": "Ream — Rust-powered Node.js application framework",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -233,8 +233,7 @@
|
|
|
233
233
|
},
|
|
234
234
|
"peerDependencies": {
|
|
235
235
|
"@c9up/comet": "^0.1.0",
|
|
236
|
-
"@c9up/quasar": "^0.1.0 || ^0.2.0"
|
|
237
|
-
"hot-hook": "^1.0.0"
|
|
236
|
+
"@c9up/quasar": "^0.1.0 || ^0.2.0"
|
|
238
237
|
},
|
|
239
238
|
"peerDependenciesMeta": {
|
|
240
239
|
"@c9up/comet": {
|
|
@@ -242,9 +241,6 @@
|
|
|
242
241
|
},
|
|
243
242
|
"@c9up/quasar": {
|
|
244
243
|
"optional": true
|
|
245
|
-
},
|
|
246
|
-
"hot-hook": {
|
|
247
|
-
"optional": true
|
|
248
244
|
}
|
|
249
245
|
},
|
|
250
246
|
"devDependencies": {
|
|
@@ -257,8 +253,9 @@
|
|
|
257
253
|
"typescript": "^6.0.3",
|
|
258
254
|
"vitest": "4.1.11"
|
|
259
255
|
},
|
|
256
|
+
"//engines": "Node 24, not 22, because AsyncLocalStorage sits on the request hot path — the container resolves through it, HttpContext is it, and the emitter reads it on every event. Node 24 backs it with AsyncContextFrame by default, and measured on that exact pattern (one context per request, six async boundaries, several reads) it costs 0.61 us per request instead of 1.55 us: 2.5x, on every request, for free. Before 24 the same mechanism existed only behind an experimental flag, and a framework cannot base its performance on a flag the application has to remember to pass. This is NOT 'track the current LTS' — security fixes still land in 22 until 2027, npm 11 is irrelevant under pnpm, and node:sqlite is not what atlas uses.",
|
|
260
257
|
"engines": {
|
|
261
|
-
"node": ">=
|
|
258
|
+
"node": ">=24.0.0"
|
|
262
259
|
},
|
|
263
260
|
"publishConfig": {
|
|
264
261
|
"access": "public"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|