@c9up/ream 0.2.26 → 0.2.28
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/README.md +1 -0
- package/dist/HttpKernel.d.ts +5 -1
- package/dist/HttpKernel.d.ts.map +1 -1
- package/dist/HttpKernel.js +6 -6
- package/dist/HttpKernel.js.map +1 -1
- package/dist/Ignitor.d.ts +3 -1
- package/dist/Ignitor.d.ts.map +1 -1
- package/dist/Ignitor.js +94 -14
- package/dist/Ignitor.js.map +1 -1
- package/dist/console/prompts.d.ts.map +1 -1
- package/dist/console/prompts.js +34 -46
- package/dist/console/prompts.js.map +1 -1
- package/dist/console/selection.d.ts +54 -0
- package/dist/console/selection.d.ts.map +1 -0
- package/dist/console/selection.js +235 -0
- package/dist/console/selection.js.map +1 -0
- package/dist/dev/fullReload.d.ts +35 -10
- package/dist/dev/fullReload.d.ts.map +1 -1
- package/dist/dev/fullReload.js +55 -14
- package/dist/dev/fullReload.js.map +1 -1
- package/dist/dev/hotWatcher.d.ts +19 -3
- package/dist/dev/hotWatcher.d.ts.map +1 -1
- package/dist/dev/hotWatcher.js +168 -18
- package/dist/dev/hotWatcher.js.map +1 -1
- package/dist/dev/readyBanner.d.ts +45 -0
- package/dist/dev/readyBanner.d.ts.map +1 -0
- package/dist/dev/readyBanner.js +72 -0
- package/dist/dev/readyBanner.js.map +1 -0
- package/dist/dev/shortcuts.d.ts +41 -0
- package/dist/dev/shortcuts.d.ts.map +1 -0
- package/dist/dev/shortcuts.js +142 -0
- package/dist/dev/shortcuts.js.map +1 -0
- package/dist/errors/prettyPrintError.d.ts.map +1 -1
- package/dist/errors/prettyPrintError.js +5 -8
- package/dist/errors/prettyPrintError.js.map +1 -1
- package/dist/errors/renderError.d.ts +46 -0
- package/dist/errors/renderError.d.ts.map +1 -0
- package/dist/errors/renderError.js +197 -0
- package/dist/errors/renderError.js.map +1 -0
- package/dist/hot.js +12 -2
- package/dist/hot.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/native/generated.d.ts +34 -0
- package/dist/native/generated.d.ts.map +1 -1
- package/dist/profiler/MemoryProfileStore.d.ts +23 -0
- package/dist/profiler/MemoryProfileStore.d.ts.map +1 -0
- package/dist/profiler/MemoryProfileStore.js +70 -0
- package/dist/profiler/MemoryProfileStore.js.map +1 -0
- package/dist/profiler/Profiler.d.ts +56 -0
- package/dist/profiler/Profiler.d.ts.map +1 -0
- package/dist/profiler/Profiler.js +162 -0
- package/dist/profiler/Profiler.js.map +1 -0
- package/dist/profiler/collectors.d.ts +105 -0
- package/dist/profiler/collectors.d.ts.map +1 -0
- package/dist/profiler/collectors.js +164 -0
- package/dist/profiler/collectors.js.map +1 -0
- package/dist/profiler/endpoint.d.ts +27 -0
- package/dist/profiler/endpoint.d.ts.map +1 -0
- package/dist/profiler/endpoint.js +79 -0
- package/dist/profiler/endpoint.js.map +1 -0
- package/dist/profiler/index.d.ts +26 -0
- package/dist/profiler/index.d.ts.map +1 -0
- package/dist/profiler/index.js +41 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/middleware.d.ts +17 -0
- package/dist/profiler/middleware.d.ts.map +1 -0
- package/dist/profiler/middleware.js +79 -0
- package/dist/profiler/middleware.js.map +1 -0
- package/dist/profiler/render.d.ts +23 -0
- package/dist/profiler/render.d.ts.map +1 -0
- package/dist/profiler/render.js +141 -0
- package/dist/profiler/render.js.map +1 -0
- package/dist/profiler/toolbar.d.ts +34 -0
- package/dist/profiler/toolbar.d.ts.map +1 -0
- package/dist/profiler/toolbar.js +104 -0
- package/dist/profiler/toolbar.js.map +1 -0
- package/dist/profiler/types.d.ts +70 -0
- package/dist/profiler/types.d.ts.map +1 -0
- package/dist/profiler/types.js +11 -0
- package/dist/profiler/types.js.map +1 -0
- package/dist/router/Router.d.ts +11 -0
- package/dist/router/Router.d.ts.map +1 -1
- package/dist/router/Router.js +16 -0
- package/dist/router/Router.js.map +1 -1
- package/dist/server/Server.d.ts +37 -0
- package/dist/server/Server.d.ts.map +1 -1
- package/dist/server/Server.js +30 -0
- package/dist/server/Server.js.map +1 -1
- package/dist/session/Session.d.ts +33 -0
- package/dist/session/Session.d.ts.map +1 -1
- package/dist/session/Session.js +31 -2
- package/dist/session/Session.js.map +1 -1
- package/dist/session/SessionMiddleware.d.ts.map +1 -1
- package/dist/session/SessionMiddleware.js +24 -4
- package/dist/session/SessionMiddleware.js.map +1 -1
- package/dist/session/drivers/CookieDriver.d.ts +12 -3
- package/dist/session/drivers/CookieDriver.d.ts.map +1 -1
- package/dist/session/drivers/CookieDriver.js +20 -6
- package/dist/session/drivers/CookieDriver.js.map +1 -1
- package/dist/session/drivers/DatabaseDriver.d.ts +2 -0
- package/dist/session/drivers/DatabaseDriver.d.ts.map +1 -1
- package/dist/session/drivers/DatabaseDriver.js +6 -0
- package/dist/session/drivers/DatabaseDriver.js.map +1 -1
- package/dist/session/drivers/FileDriver.d.ts +8 -0
- package/dist/session/drivers/FileDriver.d.ts.map +1 -1
- package/dist/session/drivers/FileDriver.js +85 -11
- package/dist/session/drivers/FileDriver.js.map +1 -1
- package/dist/session/drivers/MemoryDriver.d.ts +2 -0
- package/dist/session/drivers/MemoryDriver.d.ts.map +1 -1
- package/dist/session/drivers/MemoryDriver.js +9 -0
- package/dist/session/drivers/MemoryDriver.js.map +1 -1
- package/dist/session/drivers/RedisDriver.d.ts +2 -0
- package/dist/session/drivers/RedisDriver.d.ts.map +1 -1
- package/dist/session/drivers/RedisDriver.js +6 -0
- package/dist/session/drivers/RedisDriver.js.map +1 -1
- package/dist/session/errors.d.ts +10 -0
- package/dist/session/errors.d.ts.map +1 -1
- package/dist/session/errors.js +12 -0
- package/dist/session/errors.js.map +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 +1 -1
- 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/HttpKernel.ts +12 -8
- package/src/Ignitor.ts +109 -15
- package/src/console/prompts.ts +45 -64
- package/src/console/selection.ts +274 -0
- package/src/dev/fullReload.ts +57 -15
- package/src/dev/hotWatcher.ts +165 -21
- package/src/dev/readyBanner.ts +84 -0
- package/src/dev/shortcuts.ts +158 -0
- package/src/errors/prettyPrintError.ts +5 -5
- package/src/errors/renderError.ts +230 -0
- package/src/hot.ts +12 -2
- package/src/index.ts +11 -1
- package/src/native/generated.ts +38 -0
- package/src/profiler/MemoryProfileStore.ts +75 -0
- package/src/profiler/Profiler.ts +182 -0
- package/src/profiler/collectors.ts +230 -0
- package/src/profiler/endpoint.ts +98 -0
- package/src/profiler/index.ts +56 -0
- package/src/profiler/middleware.ts +83 -0
- package/src/profiler/render.ts +173 -0
- package/src/profiler/toolbar.ts +106 -0
- package/src/profiler/types.ts +75 -0
- package/src/router/Router.ts +16 -0
- package/src/server/Server.ts +49 -0
- package/src/session/Session.ts +56 -2
- package/src/session/SessionMiddleware.ts +23 -4
- package/src/session/drivers/CookieDriver.ts +21 -6
- package/src/session/drivers/DatabaseDriver.ts +10 -0
- package/src/session/drivers/FileDriver.ts +91 -11
- package/src/session/drivers/MemoryDriver.ts +9 -0
- package/src/session/drivers/RedisDriver.ts +7 -0
- package/src/session/errors.ts +17 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullReload.js","sourceRoot":"","sources":["../../src/dev/fullReload.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fullReload.js","sourceRoot":"","sources":["../../src/dev/fullReload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKrE;;;;;;GAMG;AACH,SAAS,MAAM;IACb,OAAO,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,CAAA;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,OAAO;QAAE,OAAM;IACzD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAM;IACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAAoC;IAClF,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAA;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,OAAqB,EACrB,UAAoC;IAEpC,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAA;AAC1D,CAAC"}
|
package/dist/dev/hotWatcher.d.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Watching the project for the changes a hot reload reacts to.
|
|
3
3
|
*
|
|
4
|
-
* `fs.watch`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* ONE `fs.watch` PER DIRECTORY, walked ourselves — not `recursive: true`, and
|
|
5
|
+
* never a watch on a file. That is not a preference, it is the bug this module
|
|
6
|
+
* was reported for: most editors save by writing a temporary file and renaming
|
|
7
|
+
* it over the original (JetBrains IDEs, several formatters, anything using
|
|
8
|
+
* write-and-replace for crash safety). The rename gives the path a NEW inode,
|
|
9
|
+
* and a watcher holding the old one is watching something that no longer has a
|
|
10
|
+
* name. Measured on Node 25, Linux:
|
|
11
|
+
*
|
|
12
|
+
* fs.watch(dir, { recursive: true }) first rename fires, then silence
|
|
13
|
+
* fs.watch(file) first rename fires, then silence
|
|
14
|
+
* fs.watch(dir) every rename fires
|
|
15
|
+
*
|
|
16
|
+
* So the first save hot-swapped and every one after it was ignored without a
|
|
17
|
+
* word — no reload, no restart, nothing in the log. A directory keeps its inode
|
|
18
|
+
* when a file inside it is replaced, which is why watching directories is the
|
|
19
|
+
* form that survives. A file to watch is watched through its parent instead,
|
|
20
|
+
* filtered by name.
|
|
7
21
|
*
|
|
8
22
|
* Two behaviours are worth stating because they are not obvious from the API:
|
|
9
23
|
*
|
|
@@ -26,6 +40,8 @@ export interface WatcherOptions {
|
|
|
26
40
|
files: readonly string[];
|
|
27
41
|
/** Called once per settled change, with an absolute path. */
|
|
28
42
|
onChange: (file: string) => void;
|
|
43
|
+
/** Told when a directory could not be watched for a reason worth knowing. */
|
|
44
|
+
onWarning?: (message: string) => void;
|
|
29
45
|
}
|
|
30
46
|
export interface Watcher {
|
|
31
47
|
close: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hotWatcher.d.ts","sourceRoot":"","sources":["../../src/dev/hotWatcher.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hotWatcher.d.ts","sourceRoot":"","sources":["../../src/dev/hotWatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA6BH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,0FAA0F;IAC1F,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAuI7D"}
|
package/dist/dev/hotWatcher.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Watching the project for the changes a hot reload reacts to.
|
|
3
3
|
*
|
|
4
|
-
* `fs.watch`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* ONE `fs.watch` PER DIRECTORY, walked ourselves — not `recursive: true`, and
|
|
5
|
+
* never a watch on a file. That is not a preference, it is the bug this module
|
|
6
|
+
* was reported for: most editors save by writing a temporary file and renaming
|
|
7
|
+
* it over the original (JetBrains IDEs, several formatters, anything using
|
|
8
|
+
* write-and-replace for crash safety). The rename gives the path a NEW inode,
|
|
9
|
+
* and a watcher holding the old one is watching something that no longer has a
|
|
10
|
+
* name. Measured on Node 25, Linux:
|
|
11
|
+
*
|
|
12
|
+
* fs.watch(dir, { recursive: true }) first rename fires, then silence
|
|
13
|
+
* fs.watch(file) first rename fires, then silence
|
|
14
|
+
* fs.watch(dir) every rename fires
|
|
15
|
+
*
|
|
16
|
+
* So the first save hot-swapped and every one after it was ignored without a
|
|
17
|
+
* word — no reload, no restart, nothing in the log. A directory keeps its inode
|
|
18
|
+
* when a file inside it is replaced, which is why watching directories is the
|
|
19
|
+
* form that survives. A file to watch is watched through its parent instead,
|
|
20
|
+
* filtered by name.
|
|
7
21
|
*
|
|
8
22
|
* Two behaviours are worth stating because they are not obvious from the API:
|
|
9
23
|
*
|
|
@@ -17,13 +31,33 @@
|
|
|
17
31
|
* syntax error has nothing left to notice the fix. The outer one covers exactly
|
|
18
32
|
* that window, and hands back over by restarting the process.
|
|
19
33
|
*/
|
|
20
|
-
import { watch } from 'node:fs';
|
|
21
|
-
import { join, resolve } from 'node:path';
|
|
34
|
+
import { readdirSync, realpathSync, statSync, watch } from 'node:fs';
|
|
35
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
22
36
|
/** How long to wait for a save to finish arriving before acting on it. */
|
|
23
37
|
const SETTLE_MS = 40;
|
|
38
|
+
/** Never walked: none of it is application source, and some of it is enormous. */
|
|
39
|
+
const SKIP_DIRECTORIES = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.wolf']);
|
|
40
|
+
/**
|
|
41
|
+
* The half-written files an atomic save leaves behind for a few milliseconds.
|
|
42
|
+
*
|
|
43
|
+
* Reported, they would be a change to `Controller.ts.tmp8f3` — a file the graph
|
|
44
|
+
* has never heard of, on its way to being renamed into the one that matters.
|
|
45
|
+
*/
|
|
46
|
+
function isEditorArtefact(name) {
|
|
47
|
+
return (name.endsWith('~') ||
|
|
48
|
+
name.endsWith('.swp') ||
|
|
49
|
+
name.endsWith('.swx') ||
|
|
50
|
+
name.startsWith('.#') ||
|
|
51
|
+
name.startsWith('.goutputstream') ||
|
|
52
|
+
/\.tmp[\w-]*$/.test(name) ||
|
|
53
|
+
/^\.?[\w.-]+\.(?:tmp|temp|crswap|part|partial)$/i.test(name));
|
|
54
|
+
}
|
|
24
55
|
export function watchProject(options) {
|
|
25
|
-
const watchers =
|
|
56
|
+
const watchers = new Map();
|
|
26
57
|
const pending = new Map();
|
|
58
|
+
/** Real paths already walked, so a symlink loop cannot spin forever. */
|
|
59
|
+
const visited = new Set();
|
|
60
|
+
let closed = false;
|
|
27
61
|
const report = (file) => {
|
|
28
62
|
const existing = pending.get(file);
|
|
29
63
|
if (existing !== undefined)
|
|
@@ -36,37 +70,153 @@ export function watchProject(options) {
|
|
|
36
70
|
timer.unref?.();
|
|
37
71
|
pending.set(file, timer);
|
|
38
72
|
};
|
|
39
|
-
|
|
40
|
-
|
|
73
|
+
const warn = (message) => options.onWarning?.(message);
|
|
74
|
+
/**
|
|
75
|
+
* Watch one directory, then everything under it.
|
|
76
|
+
*
|
|
77
|
+
* Called again for a directory that appears later: a `mkdir app/billing`
|
|
78
|
+
* during a session must be watched, and the parent's event is what says so.
|
|
79
|
+
*
|
|
80
|
+
* `announce` closes the gap between that mkdir and the watch being in place.
|
|
81
|
+
* `mkdir -p app/billing && cp Controller.ts app/billing/` writes the file
|
|
82
|
+
* before the watcher on the new directory exists, so what is already inside a
|
|
83
|
+
* directory discovered mid-session is reported as a change. At startup it is
|
|
84
|
+
* false, or booting would report every file in the project.
|
|
85
|
+
*/
|
|
86
|
+
const watchDirectory = (absolute, announce = false) => {
|
|
87
|
+
if (closed || watchers.has(absolute))
|
|
88
|
+
return;
|
|
89
|
+
let real;
|
|
90
|
+
try {
|
|
91
|
+
real = realpathSync(absolute);
|
|
92
|
+
if (!statSync(real).isDirectory())
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
// Absent is ordinary — the list is the framework's conventional layout,
|
|
97
|
+
// not a requirement, and a directory can be removed mid-session. Any
|
|
98
|
+
// other reason (no permission, too many open files) is worth saying, or
|
|
99
|
+
// the project silently stops hot-reloading.
|
|
100
|
+
if (!isMissing(error))
|
|
101
|
+
warn(`cannot watch ${absolute}: ${describe(error)}`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (visited.has(real))
|
|
105
|
+
return;
|
|
106
|
+
visited.add(real);
|
|
41
107
|
try {
|
|
42
|
-
|
|
108
|
+
const watcher = watch(absolute, (_event, name) => {
|
|
43
109
|
if (typeof name !== 'string' || name === '')
|
|
44
110
|
return;
|
|
45
|
-
|
|
46
|
-
|
|
111
|
+
const child = join(absolute, name);
|
|
112
|
+
// A new directory has to be picked up, or nothing in it is ever seen.
|
|
113
|
+
// Cheap: only for names that are directories right now.
|
|
114
|
+
if (!SKIP_DIRECTORIES.has(name) && isDirectory(child))
|
|
115
|
+
watchDirectory(child, true);
|
|
116
|
+
if (isEditorArtefact(name))
|
|
117
|
+
return;
|
|
118
|
+
report(child);
|
|
119
|
+
});
|
|
120
|
+
watcher.on('error', (error) => {
|
|
121
|
+
// A watcher whose directory was removed is done; anything else is a
|
|
122
|
+
// surprise the developer should hear about rather than lose.
|
|
123
|
+
watchers.delete(absolute);
|
|
124
|
+
if (!isMissing(error))
|
|
125
|
+
warn(`watch on ${absolute} failed: ${describe(error)}`);
|
|
126
|
+
});
|
|
127
|
+
watchers.set(absolute, watcher);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (!isMissing(error))
|
|
131
|
+
warn(`cannot watch ${absolute}: ${describe(error)}`);
|
|
132
|
+
return;
|
|
47
133
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
134
|
+
let entries = [];
|
|
135
|
+
try {
|
|
136
|
+
entries = readdirSync(absolute);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (!isMissing(error))
|
|
140
|
+
warn(`cannot read ${absolute}: ${describe(error)}`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
for (const entry of entries) {
|
|
144
|
+
if (SKIP_DIRECTORIES.has(entry))
|
|
145
|
+
continue;
|
|
146
|
+
const child = join(absolute, entry);
|
|
147
|
+
if (isDirectory(child)) {
|
|
148
|
+
watchDirectory(child, announce);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (announce && !isEditorArtefact(entry))
|
|
152
|
+
report(child);
|
|
51
153
|
}
|
|
154
|
+
};
|
|
155
|
+
for (const directory of options.directories) {
|
|
156
|
+
watchDirectory(resolve(options.root, directory));
|
|
52
157
|
}
|
|
158
|
+
// A file is watched through its parent directory, for the reason at the top
|
|
159
|
+
// of this module: `fs.watch` on the file itself holds an inode, and an atomic
|
|
160
|
+
// save replaces it. `.env` is saved by the same editors as everything else.
|
|
161
|
+
const watchedFiles = new Map();
|
|
53
162
|
for (const file of options.files) {
|
|
54
163
|
const absolute = resolve(options.root, file);
|
|
164
|
+
const parent = dirname(absolute);
|
|
165
|
+
const names = watchedFiles.get(parent) ?? new Set();
|
|
166
|
+
names.add(basename(absolute));
|
|
167
|
+
watchedFiles.set(parent, names);
|
|
168
|
+
}
|
|
169
|
+
for (const [parent, names] of watchedFiles) {
|
|
170
|
+
// The parent may already be covered as a watched directory — `.env` sits at
|
|
171
|
+
// the root, which is not in the list, but a caller is free to pass both.
|
|
172
|
+
if (watchers.has(parent))
|
|
173
|
+
continue;
|
|
55
174
|
try {
|
|
56
|
-
|
|
175
|
+
const watcher = watch(parent, (_event, name) => {
|
|
176
|
+
if (typeof name !== 'string' || !names.has(name))
|
|
177
|
+
return;
|
|
178
|
+
report(join(parent, name));
|
|
179
|
+
});
|
|
180
|
+
watcher.on('error', (error) => {
|
|
181
|
+
watchers.delete(parent);
|
|
182
|
+
if (!isMissing(error))
|
|
183
|
+
warn(`watch on ${parent} failed: ${describe(error)}`);
|
|
184
|
+
});
|
|
185
|
+
watchers.set(parent, watcher);
|
|
57
186
|
}
|
|
58
|
-
catch {
|
|
59
|
-
|
|
187
|
+
catch (error) {
|
|
188
|
+
if (!isMissing(error))
|
|
189
|
+
warn(`cannot watch ${parent}: ${describe(error)}`);
|
|
60
190
|
}
|
|
61
191
|
}
|
|
62
192
|
return {
|
|
63
193
|
close: () => {
|
|
194
|
+
closed = true;
|
|
64
195
|
for (const timer of pending.values())
|
|
65
196
|
clearTimeout(timer);
|
|
66
197
|
pending.clear();
|
|
67
|
-
for (const watcher of watchers)
|
|
198
|
+
for (const watcher of watchers.values())
|
|
68
199
|
watcher.close();
|
|
200
|
+
watchers.clear();
|
|
69
201
|
},
|
|
70
202
|
};
|
|
71
203
|
}
|
|
204
|
+
function isDirectory(path) {
|
|
205
|
+
try {
|
|
206
|
+
return statSync(path).isDirectory();
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** ENOENT and friends: the path is simply not there, which is not a failure. */
|
|
213
|
+
function isMissing(error) {
|
|
214
|
+
const code = error.code;
|
|
215
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
216
|
+
}
|
|
217
|
+
function describe(error) {
|
|
218
|
+
if (error instanceof Error)
|
|
219
|
+
return error.message;
|
|
220
|
+
return String(error);
|
|
221
|
+
}
|
|
72
222
|
//# sourceMappingURL=hotWatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hotWatcher.js","sourceRoot":"","sources":["../../src/dev/hotWatcher.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hotWatcher.js","sourceRoot":"","sources":["../../src/dev/hotWatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the dev server says once it is listening.
|
|
3
|
+
*
|
|
4
|
+
* Upstream prints a sticker the moment the child reports ready: the address,
|
|
5
|
+
* the mode, how long the boot took. Read off `@adonisjs/assembler`'s build:
|
|
6
|
+
*
|
|
7
|
+
* this.ui.sticker()
|
|
8
|
+
* .add(`Server address: ${colors.cyan(serverUrl)}`)
|
|
9
|
+
* .add(`Mode: ${colors.cyan(this.mode)}`)
|
|
10
|
+
* .add(`Ready in: ${colors.cyan(prettyHrtime(message.duration))}`)
|
|
11
|
+
*
|
|
12
|
+
* Ours says the same, `Press h to show help` included — the shortcuts are in
|
|
13
|
+
* `./shortcuts.ts`, so the line is an offer this process keeps.
|
|
14
|
+
*
|
|
15
|
+
* Printed from the application rather than from the `ream dev` parent, which
|
|
16
|
+
* is where upstream prints it. The parent is a Rust process here and the port
|
|
17
|
+
* is not its to know: a dev server that found 3000 taken binds 3001, and only
|
|
18
|
+
* the process that bound it can say so. Upstream solves the same problem by
|
|
19
|
+
* having the child send the port over IPC — the address it prints is the
|
|
20
|
+
* child's either way.
|
|
21
|
+
*/
|
|
22
|
+
/** Whether `ream dev` is what started this process. */
|
|
23
|
+
export declare function inDevServer(): boolean;
|
|
24
|
+
export interface ReadyBanner {
|
|
25
|
+
/** The host the server bound, as the Ignitor resolved it. */
|
|
26
|
+
host: string;
|
|
27
|
+
port: number;
|
|
28
|
+
/** `HMR` when the loader is swapping modules, `watch` when it only restarts. */
|
|
29
|
+
mode: string;
|
|
30
|
+
/** Milliseconds from process start to listening. */
|
|
31
|
+
bootMs?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The address to show for a bound host and port.
|
|
35
|
+
*
|
|
36
|
+
* `localhost` rather than `0.0.0.0`: bound to every interface is not a link
|
|
37
|
+
* that opens, and printing it sends you looking in the wrong place. Shared
|
|
38
|
+
* with the `o` shortcut so the browser goes where the sticker said.
|
|
39
|
+
*/
|
|
40
|
+
export declare function devServerUrl(host: string, port: number): string;
|
|
41
|
+
/** The lines of the sticker, so a test can read them without a terminal. */
|
|
42
|
+
export declare function readyBannerLines(banner: ReadyBanner): string[];
|
|
43
|
+
/** Print it, the way upstream prints its sticker. */
|
|
44
|
+
export declare function printReadyBanner(banner: ReadyBanner): void;
|
|
45
|
+
//# sourceMappingURL=readyBanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readyBanner.d.ts","sourceRoot":"","sources":["../../src/dev/readyBanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,uDAAuD;AACvD,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAY9D;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAK1D"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the dev server says once it is listening.
|
|
3
|
+
*
|
|
4
|
+
* Upstream prints a sticker the moment the child reports ready: the address,
|
|
5
|
+
* the mode, how long the boot took. Read off `@adonisjs/assembler`'s build:
|
|
6
|
+
*
|
|
7
|
+
* this.ui.sticker()
|
|
8
|
+
* .add(`Server address: ${colors.cyan(serverUrl)}`)
|
|
9
|
+
* .add(`Mode: ${colors.cyan(this.mode)}`)
|
|
10
|
+
* .add(`Ready in: ${colors.cyan(prettyHrtime(message.duration))}`)
|
|
11
|
+
*
|
|
12
|
+
* Ours says the same, `Press h to show help` included — the shortcuts are in
|
|
13
|
+
* `./shortcuts.ts`, so the line is an offer this process keeps.
|
|
14
|
+
*
|
|
15
|
+
* Printed from the application rather than from the `ream dev` parent, which
|
|
16
|
+
* is where upstream prints it. The parent is a Rust process here and the port
|
|
17
|
+
* is not its to know: a dev server that found 3000 taken binds 3001, and only
|
|
18
|
+
* the process that bound it can say so. Upstream solves the same problem by
|
|
19
|
+
* having the child send the port over IPC — the address it prints is the
|
|
20
|
+
* child's either way.
|
|
21
|
+
*/
|
|
22
|
+
import { lumen } from '@c9up/lumen';
|
|
23
|
+
/** Whether `ream dev` is what started this process. */
|
|
24
|
+
export function inDevServer() {
|
|
25
|
+
return process.env.REAM_DEV === 'true';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The address to show for a bound host and port.
|
|
29
|
+
*
|
|
30
|
+
* `localhost` rather than `0.0.0.0`: bound to every interface is not a link
|
|
31
|
+
* that opens, and printing it sends you looking in the wrong place. Shared
|
|
32
|
+
* with the `o` shortcut so the browser goes where the sticker said.
|
|
33
|
+
*/
|
|
34
|
+
export function devServerUrl(host, port) {
|
|
35
|
+
const shown = host === '0.0.0.0' || host === '::' ? 'localhost' : host;
|
|
36
|
+
return `http://${shown}:${port}`;
|
|
37
|
+
}
|
|
38
|
+
/** The lines of the sticker, so a test can read them without a terminal. */
|
|
39
|
+
export function readyBannerLines(banner) {
|
|
40
|
+
const ui = lumen();
|
|
41
|
+
const lines = [
|
|
42
|
+
`Server address: ${ui.colors.cyan(devServerUrl(banner.host, banner.port))}`,
|
|
43
|
+
`Mode: ${ui.colors.cyan(banner.mode)}`,
|
|
44
|
+
];
|
|
45
|
+
if (banner.bootMs !== undefined) {
|
|
46
|
+
lines.push(`Ready in: ${ui.colors.cyan(formatBootTime(banner.bootMs))}`);
|
|
47
|
+
}
|
|
48
|
+
// Only where there is a keyboard: piped into a file, the offer is a lie.
|
|
49
|
+
if (process.stdin.isTTY)
|
|
50
|
+
lines.push(`Press ${ui.colors.dim('h')} to show help`);
|
|
51
|
+
return lines;
|
|
52
|
+
}
|
|
53
|
+
/** Print it, the way upstream prints its sticker. */
|
|
54
|
+
export function printReadyBanner(banner) {
|
|
55
|
+
const ui = lumen();
|
|
56
|
+
const sticker = ui.sticker();
|
|
57
|
+
for (const line of readyBannerLines(banner))
|
|
58
|
+
sticker.add(line);
|
|
59
|
+
sticker.render();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* `412 ms`, `1.2 s` — upstream runs the duration through `pretty-hrtime`.
|
|
63
|
+
*
|
|
64
|
+
* Not that dependency: this prints one number once per boot, and the package
|
|
65
|
+
* is 60 lines of unit selection for a case we have exactly one of.
|
|
66
|
+
*/
|
|
67
|
+
function formatBootTime(ms) {
|
|
68
|
+
if (ms < 1000)
|
|
69
|
+
return `${Math.round(ms)} ms`;
|
|
70
|
+
return `${(ms / 1000).toFixed(1)} s`;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=readyBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readyBanner.js","sourceRoot":"","sources":["../../src/dev/readyBanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEnC,uDAAuD;AACvD,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAA;AACxC,CAAC;AAYD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY;IACrD,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAA;IACtE,OAAO,UAAU,KAAK,IAAI,IAAI,EAAE,CAAA;AAClC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAClB,MAAM,KAAK,GAAG;QACZ,mBAAmB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;QAC3E,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;KACvC,CAAA;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;IAC1E,CAAC;IACD,yEAAyE;IACzE,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC/E,OAAO,KAAK,CAAA;AACd,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAClB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IAC5B,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC9D,OAAO,CAAC,MAAM,EAAE,CAAA;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAA;IAC5C,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys the dev server answers to.
|
|
3
|
+
*
|
|
4
|
+
* Upstream's set, read off `@adonisjs/assembler`'s build: `r` restarts, `c`
|
|
5
|
+
* clears, `o` opens the browser, `h` shows the list, and Ctrl-C or Ctrl-D
|
|
6
|
+
* quits. Same keys, same order, same words.
|
|
7
|
+
*
|
|
8
|
+
* Owned by the application rather than by the `ream dev` parent, which is
|
|
9
|
+
* where upstream owns it — the same split as the ready sticker, and for the
|
|
10
|
+
* same reason: `o` needs the address, and a port found by scanning past a
|
|
11
|
+
* taken 3000 is known only to the process that bound it. Everything else
|
|
12
|
+
* follows from there, because this process already has what each key needs:
|
|
13
|
+
* exiting on the restart code is what makes the parent start it again, and
|
|
14
|
+
* the graceful shutdown is already wired to a signal.
|
|
15
|
+
*
|
|
16
|
+
* NO dependency for opening a browser. Upstream imports `open`; this spawns
|
|
17
|
+
* the platform's opener, which is the one thing that package does on the three
|
|
18
|
+
* platforms a dev server runs on.
|
|
19
|
+
*/
|
|
20
|
+
/** The exit code the `ream dev` parent restarts on. */
|
|
21
|
+
export declare const RESTART_EXIT_CODE = 75;
|
|
22
|
+
export interface ShortcutsOptions {
|
|
23
|
+
/** Where the server is listening, for `o`. */
|
|
24
|
+
url?: string;
|
|
25
|
+
/** Leave the process the way a restart leaves it. Defaults to exiting. */
|
|
26
|
+
onRestart?: () => void;
|
|
27
|
+
/** End the session. Defaults to exiting through the normal shutdown. */
|
|
28
|
+
onQuit?: () => void;
|
|
29
|
+
}
|
|
30
|
+
/** The lines `h` prints, so a test can read them without a terminal. */
|
|
31
|
+
export declare function helpLines(): string[];
|
|
32
|
+
/** What to do with one keypress. Exported so the mapping is testable. */
|
|
33
|
+
export declare function handleKey(key: string, options?: ShortcutsOptions): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Listen for keys. Answers a function that stops listening.
|
|
36
|
+
*
|
|
37
|
+
* A no-op when stdin is not a terminal — `ream dev` piped into a file has no
|
|
38
|
+
* keyboard, and raw mode on a pipe throws.
|
|
39
|
+
*/
|
|
40
|
+
export declare function installShortcuts(options?: ShortcutsOptions): () => void;
|
|
41
|
+
//# sourceMappingURL=shortcuts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcuts.d.ts","sourceRoot":"","sources":["../../src/dev/shortcuts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAQnC,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wEAAwE;AACxE,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAiDD,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAY9E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,IAAI,CAiB3E"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys the dev server answers to.
|
|
3
|
+
*
|
|
4
|
+
* Upstream's set, read off `@adonisjs/assembler`'s build: `r` restarts, `c`
|
|
5
|
+
* clears, `o` opens the browser, `h` shows the list, and Ctrl-C or Ctrl-D
|
|
6
|
+
* quits. Same keys, same order, same words.
|
|
7
|
+
*
|
|
8
|
+
* Owned by the application rather than by the `ream dev` parent, which is
|
|
9
|
+
* where upstream owns it — the same split as the ready sticker, and for the
|
|
10
|
+
* same reason: `o` needs the address, and a port found by scanning past a
|
|
11
|
+
* taken 3000 is known only to the process that bound it. Everything else
|
|
12
|
+
* follows from there, because this process already has what each key needs:
|
|
13
|
+
* exiting on the restart code is what makes the parent start it again, and
|
|
14
|
+
* the graceful shutdown is already wired to a signal.
|
|
15
|
+
*
|
|
16
|
+
* NO dependency for opening a browser. Upstream imports `open`; this spawns
|
|
17
|
+
* the platform's opener, which is the one thing that package does on the three
|
|
18
|
+
* platforms a dev server runs on.
|
|
19
|
+
*/
|
|
20
|
+
import { spawn } from 'node:child_process';
|
|
21
|
+
import { lumen } from '@c9up/lumen';
|
|
22
|
+
import { clearScreen } from './fullReload.js';
|
|
23
|
+
/** The exit code the `ream dev` parent restarts on. */
|
|
24
|
+
export const RESTART_EXIT_CODE = 75;
|
|
25
|
+
/** The lines `h` prints, so a test can read them without a terminal. */
|
|
26
|
+
export function helpLines() {
|
|
27
|
+
return ['Available shortcuts:', ...shortcutsFor({}).map((s) => `· ${s.key}: ${s.description}`)];
|
|
28
|
+
}
|
|
29
|
+
function shortcutsFor(options) {
|
|
30
|
+
const ui = lumen();
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
key: 'r',
|
|
34
|
+
description: 'restart server',
|
|
35
|
+
handler: () => {
|
|
36
|
+
ui.logger.log('');
|
|
37
|
+
ui.logger.info('Manual restart triggered...');
|
|
38
|
+
// Exiting on the restart code IS the restart: the parent loops on it,
|
|
39
|
+
// which is the same path a change outside the boundaries takes.
|
|
40
|
+
if (options.onRestart)
|
|
41
|
+
options.onRestart();
|
|
42
|
+
else
|
|
43
|
+
process.exit(RESTART_EXIT_CODE);
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
key: 'c',
|
|
48
|
+
description: 'clear console',
|
|
49
|
+
handler: () => {
|
|
50
|
+
clearScreen();
|
|
51
|
+
ui.logger.info('Console cleared');
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
key: 'o',
|
|
56
|
+
description: 'open in browser',
|
|
57
|
+
handler: () => {
|
|
58
|
+
if (options.url === undefined) {
|
|
59
|
+
ui.logger.warning('No server address to open');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
ui.logger.log('');
|
|
63
|
+
ui.logger.info(`Opening ${options.url}...`);
|
|
64
|
+
openBrowser(options.url);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: 'h',
|
|
69
|
+
description: 'show this help',
|
|
70
|
+
handler: () => {
|
|
71
|
+
ui.logger.log('');
|
|
72
|
+
for (const line of helpLines())
|
|
73
|
+
ui.logger.log(line);
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
/** What to do with one keypress. Exported so the mapping is testable. */
|
|
79
|
+
export function handleKey(key, options = {}) {
|
|
80
|
+
// \u0003 is Ctrl-C and \u0004 is Ctrl-D. Raw mode means no signal is raised
|
|
81
|
+
// for either, so the process would sit there unkillable without this.
|
|
82
|
+
if (key === '\u0003' || key === '\u0004') {
|
|
83
|
+
if (options.onQuit)
|
|
84
|
+
options.onQuit();
|
|
85
|
+
else
|
|
86
|
+
process.kill(process.pid, 'SIGINT');
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
const shortcut = shortcutsFor(options).find((entry) => entry.key === key);
|
|
90
|
+
if (shortcut === undefined)
|
|
91
|
+
return false;
|
|
92
|
+
shortcut.handler();
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Listen for keys. Answers a function that stops listening.
|
|
97
|
+
*
|
|
98
|
+
* A no-op when stdin is not a terminal — `ream dev` piped into a file has no
|
|
99
|
+
* keyboard, and raw mode on a pipe throws.
|
|
100
|
+
*/
|
|
101
|
+
export function installShortcuts(options = {}) {
|
|
102
|
+
if (!process.stdin.isTTY)
|
|
103
|
+
return () => { };
|
|
104
|
+
const onData = (data) => {
|
|
105
|
+
handleKey(data.toString(), options);
|
|
106
|
+
};
|
|
107
|
+
process.stdin.setRawMode(true);
|
|
108
|
+
process.stdin.on('data', onData);
|
|
109
|
+
// Nothing should stay alive for a keyboard: a server that finished its work
|
|
110
|
+
// must be able to exit with a listener still attached.
|
|
111
|
+
process.stdin.unref();
|
|
112
|
+
return () => {
|
|
113
|
+
process.stdin.setRawMode(false);
|
|
114
|
+
process.stdin.removeListener('data', onData);
|
|
115
|
+
process.stdin.pause();
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Hand the URL to whatever opens links here.
|
|
120
|
+
*
|
|
121
|
+
* Detached and ignored: an opener that writes to stderr, or outlives the dev
|
|
122
|
+
* server, must not take the terminal or the exit with it.
|
|
123
|
+
*/
|
|
124
|
+
function openBrowser(url) {
|
|
125
|
+
const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
126
|
+
try {
|
|
127
|
+
const child = spawn(command, [url], {
|
|
128
|
+
detached: true,
|
|
129
|
+
stdio: 'ignore',
|
|
130
|
+
shell: process.platform === 'win32',
|
|
131
|
+
});
|
|
132
|
+
child.unref();
|
|
133
|
+
child.on('error', () => {
|
|
134
|
+
// No opener on this machine — a headless container, say. The address was
|
|
135
|
+
// printed a moment ago; losing the click is not worth a crash.
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Same.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=shortcuts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../../src/dev/shortcuts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prettyPrintError.d.ts","sourceRoot":"","sources":["../../src/errors/prettyPrintError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"prettyPrintError.d.ts","sourceRoot":"","sources":["../../src/errors/prettyPrintError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAQrD"}
|
|
@@ -6,17 +6,14 @@
|
|
|
6
6
|
* that would make the two import each other.
|
|
7
7
|
*/
|
|
8
8
|
import { ReamError } from './ReamError.js';
|
|
9
|
+
import { renderError } from './renderError.js';
|
|
9
10
|
export function prettyPrintError(error) {
|
|
11
|
+
// A framework error already says what it is, what it was doing and what to
|
|
12
|
+
// try — printing a source excerpt under it would bury that.
|
|
10
13
|
if (error instanceof ReamError) {
|
|
11
14
|
console.error(error.toDevString());
|
|
15
|
+
return;
|
|
12
16
|
}
|
|
13
|
-
|
|
14
|
-
console.error(`\n ${error.message}\n`);
|
|
15
|
-
if (error.stack)
|
|
16
|
-
console.error(error.stack);
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
console.error(error);
|
|
20
|
-
}
|
|
17
|
+
console.error(renderError(error));
|
|
21
18
|
}
|
|
22
19
|
//# sourceMappingURL=prettyPrintError.js.map
|