@juxtapose/core 0.4.0 → 0.6.0
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/agent/handoff.d.ts +8 -1
- package/dist/agent/handoff.js +75 -7
- package/dist/agent/handoff.js.map +1 -1
- package/dist/analysis/affected.d.ts +37 -0
- package/dist/analysis/affected.js +97 -22
- package/dist/analysis/affected.js.map +1 -1
- package/dist/analysis/cause.d.ts +32 -0
- package/dist/analysis/cause.js +187 -0
- package/dist/analysis/cause.js.map +1 -0
- package/dist/baseline/approve.d.ts +24 -0
- package/dist/baseline/approve.js +54 -0
- package/dist/baseline/approve.js.map +1 -0
- package/dist/baseline/git-store.d.ts +4 -0
- package/dist/baseline/git-store.js +22 -0
- package/dist/baseline/git-store.js.map +1 -1
- package/dist/browser/acquire.d.ts +15 -0
- package/dist/browser/acquire.js +26 -0
- package/dist/browser/acquire.js.map +1 -0
- package/dist/browser/browser.d.ts +53 -0
- package/dist/browser/browser.js +122 -0
- package/dist/browser/browser.js.map +1 -0
- package/dist/browser/cdp.d.ts +81 -0
- package/dist/browser/cdp.js +230 -0
- package/dist/browser/cdp.js.map +1 -0
- package/dist/browser/daemon/client.d.ts +145 -0
- package/dist/browser/daemon/client.js +764 -0
- package/dist/browser/daemon/client.js.map +1 -0
- package/dist/browser/daemon/state.d.ts +99 -0
- package/dist/browser/daemon/state.js +297 -0
- package/dist/browser/daemon/state.js.map +1 -0
- package/dist/browser/daemon/supervisor-main.d.ts +1 -0
- package/dist/browser/daemon/supervisor-main.js +54 -0
- package/dist/browser/daemon/supervisor-main.js.map +1 -0
- package/dist/browser/daemon/supervisor.d.ts +37 -0
- package/dist/browser/daemon/supervisor.js +777 -0
- package/dist/browser/daemon/supervisor.js.map +1 -0
- package/dist/{capture/launch.d.ts → browser/flags.d.ts} +19 -1
- package/dist/browser/flags.js +146 -0
- package/dist/browser/flags.js.map +1 -0
- package/dist/browser/index.d.ts +14 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/install.d.ts +33 -0
- package/dist/browser/install.js +167 -0
- package/dist/browser/install.js.map +1 -0
- package/dist/browser/launch.d.ts +37 -0
- package/dist/browser/launch.js +254 -0
- package/dist/browser/launch.js.map +1 -0
- package/dist/browser/page.d.ts +125 -0
- package/dist/browser/page.js +564 -0
- package/dist/browser/page.js.map +1 -0
- package/dist/browser/pins.d.ts +12 -0
- package/dist/browser/pins.js +57 -0
- package/dist/browser/pins.js.map +1 -0
- package/dist/browser/private-dir.d.ts +7 -0
- package/dist/browser/private-dir.js +24 -0
- package/dist/browser/private-dir.js.map +1 -0
- package/dist/browser/resolve.d.ts +31 -0
- package/dist/browser/resolve.js +126 -0
- package/dist/browser/resolve.js.map +1 -0
- package/dist/browser/selectors.d.ts +10 -0
- package/dist/browser/selectors.js +60 -0
- package/dist/browser/selectors.js.map +1 -0
- package/dist/browser/transport.d.ts +51 -0
- package/dist/browser/transport.js +124 -0
- package/dist/browser/transport.js.map +1 -0
- package/dist/browser/types.d.ts +4 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/browser/zip.d.ts +27 -0
- package/dist/browser/zip.js +241 -0
- package/dist/browser/zip.js.map +1 -0
- package/dist/capture/capture.d.ts +7 -1
- package/dist/capture/capture.js +25 -8
- package/dist/capture/capture.js.map +1 -1
- package/dist/capture/env.d.ts +1 -1
- package/dist/capture/pool.d.ts +1 -1
- package/dist/capture/pool.js +41 -8
- package/dist/capture/pool.js.map +1 -1
- package/dist/capture/settle.d.ts +1 -1
- package/dist/capture/settle.js +2 -0
- package/dist/capture/settle.js.map +1 -1
- package/dist/capture/snap.d.ts +43 -0
- package/dist/capture/snap.js +103 -0
- package/dist/capture/snap.js.map +1 -0
- package/dist/capture/structure.d.ts +77 -0
- package/dist/capture/structure.js +498 -0
- package/dist/capture/structure.js.map +1 -0
- package/dist/diff/compare.d.ts +19 -0
- package/dist/diff/compare.js +19 -0
- package/dist/diff/compare.js.map +1 -0
- package/dist/diff/crops.d.ts +26 -0
- package/dist/diff/crops.js +92 -0
- package/dist/diff/crops.js.map +1 -0
- package/dist/diff/structural/classify.d.ts +29 -0
- package/dist/diff/structural/classify.js +113 -0
- package/dist/diff/structural/classify.js.map +1 -0
- package/dist/diff/structural/coverage.d.ts +11 -0
- package/dist/diff/structural/coverage.js +37 -0
- package/dist/diff/structural/coverage.js.map +1 -0
- package/dist/diff/structural/deltas.d.ts +29 -0
- package/dist/diff/structural/deltas.js +218 -0
- package/dist/diff/structural/deltas.js.map +1 -0
- package/dist/diff/structural/disambiguate.d.ts +3 -0
- package/dist/diff/structural/disambiguate.js +89 -0
- package/dist/diff/structural/disambiguate.js.map +1 -0
- package/dist/diff/structural/label.d.ts +15 -0
- package/dist/diff/structural/label.js +64 -0
- package/dist/diff/structural/label.js.map +1 -0
- package/dist/diff/structural/match.d.ts +13 -0
- package/dist/diff/structural/match.js +135 -0
- package/dist/diff/structural/match.js.map +1 -0
- package/dist/diff/structural/shift.d.ts +2 -0
- package/dist/diff/structural/shift.js +144 -0
- package/dist/diff/structural/shift.js.map +1 -0
- package/dist/diff/structural/summary.d.ts +31 -0
- package/dist/diff/structural/summary.js +420 -0
- package/dist/diff/structural/summary.js.map +1 -0
- package/dist/diff/structural.d.ts +40 -0
- package/dist/diff/structural.js +219 -0
- package/dist/diff/structural.js.map +1 -0
- package/dist/index.d.ts +28 -4
- package/dist/index.js +32 -3
- package/dist/index.js.map +1 -1
- package/dist/platform.d.ts +1 -1
- package/dist/platforms/urls.d.ts +3 -0
- package/dist/platforms/urls.js +89 -0
- package/dist/platforms/urls.js.map +1 -0
- package/dist/report/comment.js +9 -3
- package/dist/report/comment.js.map +1 -1
- package/dist/report/format.d.ts +18 -0
- package/dist/report/format.js +20 -0
- package/dist/report/format.js.map +1 -1
- package/dist/report/html.js +2 -2
- package/dist/report/html.js.map +1 -1
- package/dist/run/groups.d.ts +2 -0
- package/dist/run/groups.js +45 -0
- package/dist/run/groups.js.map +1 -0
- package/dist/run/run.d.ts +6 -2
- package/dist/run/run.js +74 -6
- package/dist/run/run.js.map +1 -1
- package/dist/shell-quote.d.ts +2 -0
- package/dist/shell-quote.js +10 -0
- package/dist/shell-quote.js.map +1 -0
- package/dist/types.d.ts +201 -5
- package/dist/types.js +0 -2
- package/dist/types.js.map +1 -1
- package/dist/url-platform.d.ts +2 -2
- package/dist/url-platform.js +2 -2
- package/dist/url-platform.js.map +1 -1
- package/package.json +6 -10
- package/dist/capture/launch.js +0 -56
- package/dist/capture/launch.js.map +0 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Transport } from './transport.js';
|
|
2
|
+
export interface RawMessage {
|
|
3
|
+
id?: number;
|
|
4
|
+
method?: string;
|
|
5
|
+
params?: unknown;
|
|
6
|
+
result?: unknown;
|
|
7
|
+
error?: {
|
|
8
|
+
code: number;
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const SEND_TIMEOUT_MS = 30000;
|
|
14
|
+
export declare class CdpError extends Error {
|
|
15
|
+
readonly code: number;
|
|
16
|
+
constructor(code: number, method: string, message: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class TargetClosedError extends Error {
|
|
19
|
+
constructor(reason?: string, method?: string);
|
|
20
|
+
}
|
|
21
|
+
export declare class SendTimeoutError extends Error {
|
|
22
|
+
constructor(method: string, timeout: number);
|
|
23
|
+
}
|
|
24
|
+
type Handler = (params: unknown, sessionId?: string) => void;
|
|
25
|
+
export declare class CdpConnection {
|
|
26
|
+
private readonly transport;
|
|
27
|
+
private lastId;
|
|
28
|
+
private readonly pending;
|
|
29
|
+
/** key = `${sessionId ?? ''}\n${method}` */
|
|
30
|
+
private readonly handlers;
|
|
31
|
+
private readonly closeWaiters;
|
|
32
|
+
private _closed;
|
|
33
|
+
private closeReason;
|
|
34
|
+
onClose: ((reason?: string) => void) | null;
|
|
35
|
+
/** Every parsed frame, before routing. The PR 2 supervisor proxies from here. */
|
|
36
|
+
onRaw: ((m: RawMessage) => void) | null;
|
|
37
|
+
/**
|
|
38
|
+
* A throwing event handler or onRaw must not escape into the stream's data
|
|
39
|
+
* event (an uncaught exception would kill the daemon) nor skip the rest of
|
|
40
|
+
* the chunk. Default: one line on stderr.
|
|
41
|
+
*/
|
|
42
|
+
onError: (error: unknown, where: 'handler' | 'onRaw') => void;
|
|
43
|
+
constructor(transport: Transport);
|
|
44
|
+
get closed(): boolean;
|
|
45
|
+
get pendingCount(): number;
|
|
46
|
+
/** Number of distinct (session, method) handler keys; empty sets are pruned. */
|
|
47
|
+
get handlerKeyCount(): number;
|
|
48
|
+
/** Total registered handlers, summed over every key; a leak test's yardstick. */
|
|
49
|
+
get handlerCount(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Call `listener` once when the connection closes (at once if it already
|
|
52
|
+
* has); returns the unsubscribe. Pages use it to fail in-flight work fast
|
|
53
|
+
* instead of waiting out each send's timeout.
|
|
54
|
+
*/
|
|
55
|
+
onClosed(listener: (e: Error) => void): () => void;
|
|
56
|
+
allocateId(): number;
|
|
57
|
+
/**
|
|
58
|
+
* Throws TargetClosedError once the connection is closed, so a proxying
|
|
59
|
+
* caller (the PR 2 supervisor) learns its client message was not delivered
|
|
60
|
+
* instead of waiting for a reply that cannot come.
|
|
61
|
+
*/
|
|
62
|
+
sendRaw(message: RawMessage & {
|
|
63
|
+
id: number;
|
|
64
|
+
method: string;
|
|
65
|
+
}): void;
|
|
66
|
+
send<T = unknown>(method: string, params?: object, sessionId?: string, opts?: {
|
|
67
|
+
timeout?: number;
|
|
68
|
+
}): Promise<T>;
|
|
69
|
+
on(method: string, handler: Handler, sessionId?: string): () => void;
|
|
70
|
+
/**
|
|
71
|
+
* Without a sessionId this listens on the browser session only, where
|
|
72
|
+
* session-scoped events never arrive; pass the page's sessionId for page
|
|
73
|
+
* events.
|
|
74
|
+
*/
|
|
75
|
+
once<P = unknown>(method: string, sessionId?: string, predicate?: (p: P) => boolean): Promise<P>;
|
|
76
|
+
close(): void;
|
|
77
|
+
private dispatch;
|
|
78
|
+
private runHandlers;
|
|
79
|
+
private handleClose;
|
|
80
|
+
}
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// packages/core/src/browser/cdp.ts
|
|
2
|
+
//
|
|
3
|
+
// The whole protocol client: ids out, replies back, events routed by
|
|
4
|
+
// sessionId. Playwright's CRConnection does the same in ~300 lines plus
|
|
5
|
+
// the parts we never use.
|
|
6
|
+
//
|
|
7
|
+
// Every send has a Node-side timeout. Chrome answers Runtime.evaluate only
|
|
8
|
+
// when the script returns, so a story with a synchronous infinite loop would
|
|
9
|
+
// otherwise hang the worker and the run.
|
|
10
|
+
export const SEND_TIMEOUT_MS = 30_000;
|
|
11
|
+
export class CdpError extends Error {
|
|
12
|
+
code;
|
|
13
|
+
constructor(code, method, message) {
|
|
14
|
+
super(`${method}: ${message}`);
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.name = 'CdpError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class TargetClosedError extends Error {
|
|
20
|
+
constructor(reason = 'browser closed', method) {
|
|
21
|
+
super(`jux: browser connection closed (${reason})${method ? ` while waiting for ${method}` : ''}`);
|
|
22
|
+
this.name = 'TargetClosedError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class SendTimeoutError extends Error {
|
|
26
|
+
constructor(method, timeout) {
|
|
27
|
+
super(`jux: ${method} got no reply from the browser within ${timeout} ms`);
|
|
28
|
+
this.name = 'SendTimeoutError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class CdpConnection {
|
|
32
|
+
transport;
|
|
33
|
+
lastId = 0;
|
|
34
|
+
pending = new Map();
|
|
35
|
+
/** key = `${sessionId ?? ''}\n${method}` */
|
|
36
|
+
handlers = new Map();
|
|
37
|
+
closeWaiters = new Set();
|
|
38
|
+
_closed = false;
|
|
39
|
+
closeReason;
|
|
40
|
+
onClose = null;
|
|
41
|
+
/** Every parsed frame, before routing. The PR 2 supervisor proxies from here. */
|
|
42
|
+
onRaw = null;
|
|
43
|
+
/**
|
|
44
|
+
* A throwing event handler or onRaw must not escape into the stream's data
|
|
45
|
+
* event (an uncaught exception would kill the daemon) nor skip the rest of
|
|
46
|
+
* the chunk. Default: one line on stderr.
|
|
47
|
+
*/
|
|
48
|
+
onError = (error, where) => {
|
|
49
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
50
|
+
process.stderr.write(`jux: ${where} threw: ${msg}\n`);
|
|
51
|
+
};
|
|
52
|
+
constructor(transport) {
|
|
53
|
+
this.transport = transport;
|
|
54
|
+
transport.onMessage = (m) => this.dispatch(m);
|
|
55
|
+
transport.onClose = (reason) => this.handleClose(reason);
|
|
56
|
+
}
|
|
57
|
+
get closed() {
|
|
58
|
+
return this._closed;
|
|
59
|
+
}
|
|
60
|
+
get pendingCount() {
|
|
61
|
+
return this.pending.size;
|
|
62
|
+
}
|
|
63
|
+
/** Number of distinct (session, method) handler keys; empty sets are pruned. */
|
|
64
|
+
get handlerKeyCount() {
|
|
65
|
+
return this.handlers.size;
|
|
66
|
+
}
|
|
67
|
+
/** Total registered handlers, summed over every key; a leak test's yardstick. */
|
|
68
|
+
get handlerCount() {
|
|
69
|
+
let n = 0;
|
|
70
|
+
for (const set of this.handlers.values())
|
|
71
|
+
n += set.size;
|
|
72
|
+
return n;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Call `listener` once when the connection closes (at once if it already
|
|
76
|
+
* has); returns the unsubscribe. Pages use it to fail in-flight work fast
|
|
77
|
+
* instead of waiting out each send's timeout.
|
|
78
|
+
*/
|
|
79
|
+
onClosed(listener) {
|
|
80
|
+
if (this._closed) {
|
|
81
|
+
listener(new TargetClosedError(this.closeReason));
|
|
82
|
+
return () => { };
|
|
83
|
+
}
|
|
84
|
+
this.closeWaiters.add(listener);
|
|
85
|
+
return () => this.closeWaiters.delete(listener);
|
|
86
|
+
}
|
|
87
|
+
allocateId() {
|
|
88
|
+
return ++this.lastId;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Throws TargetClosedError once the connection is closed, so a proxying
|
|
92
|
+
* caller (the PR 2 supervisor) learns its client message was not delivered
|
|
93
|
+
* instead of waiting for a reply that cannot come.
|
|
94
|
+
*/
|
|
95
|
+
sendRaw(message) {
|
|
96
|
+
if (this._closed)
|
|
97
|
+
throw new TargetClosedError(this.closeReason, message.method);
|
|
98
|
+
this.transport.send(JSON.stringify(message));
|
|
99
|
+
}
|
|
100
|
+
send(method, params = {}, sessionId, opts = {}) {
|
|
101
|
+
if (this._closed)
|
|
102
|
+
return Promise.reject(new TargetClosedError(this.closeReason, method));
|
|
103
|
+
const id = this.allocateId();
|
|
104
|
+
const timeout = opts.timeout ?? SEND_TIMEOUT_MS;
|
|
105
|
+
return new Promise((resolve, reject) => {
|
|
106
|
+
const timer = setTimeout(() => {
|
|
107
|
+
this.pending.delete(id);
|
|
108
|
+
reject(new SendTimeoutError(method, timeout));
|
|
109
|
+
}, timeout);
|
|
110
|
+
timer.unref();
|
|
111
|
+
this.pending.set(id, {
|
|
112
|
+
method,
|
|
113
|
+
resolve: resolve,
|
|
114
|
+
reject,
|
|
115
|
+
timer,
|
|
116
|
+
});
|
|
117
|
+
try {
|
|
118
|
+
this.sendRaw(sessionId ? { id, method, params, sessionId } : { id, method, params });
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
this.pending.delete(id);
|
|
123
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
on(method, handler, sessionId) {
|
|
128
|
+
const key = `${sessionId ?? ''}\n${method}`;
|
|
129
|
+
let set = this.handlers.get(key);
|
|
130
|
+
if (!set)
|
|
131
|
+
this.handlers.set(key, (set = new Set()));
|
|
132
|
+
set.add(handler);
|
|
133
|
+
return () => {
|
|
134
|
+
set.delete(handler);
|
|
135
|
+
if (set.size === 0 && this.handlers.get(key) === set)
|
|
136
|
+
this.handlers.delete(key);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Without a sessionId this listens on the browser session only, where
|
|
141
|
+
* session-scoped events never arrive; pass the page's sessionId for page
|
|
142
|
+
* events.
|
|
143
|
+
*/
|
|
144
|
+
once(method, sessionId, predicate = () => true) {
|
|
145
|
+
if (this._closed)
|
|
146
|
+
return Promise.reject(new TargetClosedError(this.closeReason, method));
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
const onClosed = (e) => {
|
|
149
|
+
off();
|
|
150
|
+
reject(e);
|
|
151
|
+
};
|
|
152
|
+
const off = this.on(method, (params) => {
|
|
153
|
+
if (!predicate(params))
|
|
154
|
+
return;
|
|
155
|
+
off();
|
|
156
|
+
this.closeWaiters.delete(onClosed);
|
|
157
|
+
resolve(params);
|
|
158
|
+
}, sessionId);
|
|
159
|
+
this.closeWaiters.add(onClosed);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
close() {
|
|
163
|
+
this.transport.close();
|
|
164
|
+
}
|
|
165
|
+
dispatch(raw) {
|
|
166
|
+
let m;
|
|
167
|
+
try {
|
|
168
|
+
m = JSON.parse(raw);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return; // Chrome never sends non-JSON frames; nothing to do but ignore.
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
this.onRaw?.(m);
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
this.onError(e, 'onRaw');
|
|
178
|
+
}
|
|
179
|
+
if (m.id !== undefined) {
|
|
180
|
+
const p = this.pending.get(m.id);
|
|
181
|
+
if (!p)
|
|
182
|
+
return; // a raw (proxied) id, or a reply after its timeout
|
|
183
|
+
this.pending.delete(m.id);
|
|
184
|
+
clearTimeout(p.timer);
|
|
185
|
+
if (m.error)
|
|
186
|
+
p.reject(new CdpError(m.error.code, p.method, m.error.message));
|
|
187
|
+
else
|
|
188
|
+
p.resolve(m.result);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (m.method) {
|
|
192
|
+
const set = this.handlers.get(`${m.sessionId ?? ''}\n${m.method}`);
|
|
193
|
+
if (set)
|
|
194
|
+
this.runHandlers(set, m);
|
|
195
|
+
// Session-less listeners see every event (the browser session's Target.* events).
|
|
196
|
+
if (m.sessionId) {
|
|
197
|
+
const all = this.handlers.get(`\n${m.method}`);
|
|
198
|
+
if (all)
|
|
199
|
+
this.runHandlers(all, m);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
runHandlers(set, m) {
|
|
204
|
+
for (const h of [...set]) {
|
|
205
|
+
try {
|
|
206
|
+
h(m.params, m.sessionId);
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
this.onError(e, 'handler');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
handleClose(reason) {
|
|
214
|
+
if (this._closed)
|
|
215
|
+
return;
|
|
216
|
+
this._closed = true;
|
|
217
|
+
this.closeReason = reason;
|
|
218
|
+
for (const p of this.pending.values()) {
|
|
219
|
+
clearTimeout(p.timer);
|
|
220
|
+
p.reject(new TargetClosedError(reason, p.method));
|
|
221
|
+
}
|
|
222
|
+
this.pending.clear();
|
|
223
|
+
const err = new TargetClosedError(reason);
|
|
224
|
+
for (const w of [...this.closeWaiters])
|
|
225
|
+
w(err);
|
|
226
|
+
this.closeWaiters.clear();
|
|
227
|
+
this.onClose?.(reason);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=cdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../src/browser/cdp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
2
|
+
import { Browser } from '../browser.js';
|
|
3
|
+
import { type DaemonPaths, type DaemonState } from './state.js';
|
|
4
|
+
export interface SpawnArgs {
|
|
5
|
+
executablePath: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
stateDir: string;
|
|
8
|
+
key: string;
|
|
9
|
+
idleMinutes: number;
|
|
10
|
+
}
|
|
11
|
+
export interface WarmOptions {
|
|
12
|
+
executablePath: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
stateDir: string;
|
|
15
|
+
/** The caller's environment: the key is computed from it and the daemon runs with it. */
|
|
16
|
+
env?: NodeJS.ProcessEnv;
|
|
17
|
+
idleMinutes?: number;
|
|
18
|
+
/** Test seam: start a daemon for these args with this env. Default: a detached supervisor-main. */
|
|
19
|
+
spawnDaemon?: (args: SpawnArgs, env: NodeJS.ProcessEnv) => ChildProcess | void;
|
|
20
|
+
connectTimeoutMs?: number;
|
|
21
|
+
/** Test seam: see CommandReader. */
|
|
22
|
+
readCommand?: CommandReader;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The command line of a pid, '' when no such process exists, null when this
|
|
26
|
+
* machine gives no way to read it (no /proc and no ps).
|
|
27
|
+
*/
|
|
28
|
+
export type CommandReader = (pid: number) => Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* `CI` is the convention; these are the systems that do not set it (GitHub
|
|
31
|
+
* Actions does, but `CI` can be unset in a step's env; Jenkins sets BUILD_ID).
|
|
32
|
+
*/
|
|
33
|
+
export declare const CI_ENV_VARS: readonly ["CI", "GITHUB_ACTIONS", "JENKINS_URL", "BUILD_ID", "TEAMCITY_VERSION", "BUILDKITE", "GITLAB_CI", "TF_BUILD", "CODEBUILD_BUILD_ID"];
|
|
34
|
+
/** Off with `--no-daemon`, JUX_NO_DAEMON (any truthy value), or any CI marker. */
|
|
35
|
+
export declare function daemonEnabled(env: NodeJS.ProcessEnv, flagNoDaemon?: boolean): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* JUX_BROWSER_IDLE_MINUTES within [1, 35000], else the default (undefined).
|
|
38
|
+
* The upper bound is setTimeout's: 100000 minutes overflowed to a 1 ms idle
|
|
39
|
+
* timer and the daemon quit as soon as its last client left. Infinity used to
|
|
40
|
+
* pass too, became null in the spawn JSON, and every supervisor exited 1.
|
|
41
|
+
*/
|
|
42
|
+
export declare function daemonIdleMinutes(env: NodeJS.ProcessEnv): number | undefined;
|
|
43
|
+
type StatusOptions = Pick<WarmOptions, 'executablePath' | 'stateDir' | 'args' | 'env' | 'readCommand'>;
|
|
44
|
+
/**
|
|
45
|
+
* A hash of `entry` and every file it reaches through relative imports. The
|
|
46
|
+
* supervisor that serves a client is whichever build spawned it; after a
|
|
47
|
+
* rebuild or an upgrade the supervisor's flags, allowlist or protocol can
|
|
48
|
+
* differ from this client's, and reusing it would render with the old code.
|
|
49
|
+
* A missing file hashes as missing (vitest runs the .ts sources, where the
|
|
50
|
+
* .js entry does not exist).
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildIdentity(entry: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* `<@juxtapose/core version>+<build hash of the supervisor entry>`. Cached
|
|
55
|
+
* per process, but rechecked by stat on every call (about ten files): a
|
|
56
|
+
* Storybook addon or review server that stays up across a `pnpm build` kept
|
|
57
|
+
* the old key while spawning the new supervisor-main from disk, so it never
|
|
58
|
+
* shared a daemon with the CLI and ran a mixed build (PR #102 re-review N5).
|
|
59
|
+
*/
|
|
60
|
+
export declare function juxIdentity(entry?: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* The daemon key for these options. It covers everything a fresh launch
|
|
63
|
+
* would render with: the binary (path, size, mtime), the pin, the full Chrome
|
|
64
|
+
* command line jux would launch, the render env and this jux build. Keys that
|
|
65
|
+
* differ name different sockets, so a daemon from an older jux or other
|
|
66
|
+
* flags is never reused; it idles out.
|
|
67
|
+
*/
|
|
68
|
+
export declare function daemonKeyFor(opts: Pick<WarmOptions, 'executablePath' | 'args' | 'env'>, jux?: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Start a detached supervisor-main with the caller's env: the key was computed
|
|
71
|
+
* from that env, so Chrome must render with it (TZ, LANG, fonts), not with
|
|
72
|
+
* whatever env this process happens to have. Detached in its own process
|
|
73
|
+
* group with stdio ignored: it outlives this jux, and a Ctrl-C to this
|
|
74
|
+
* terminal must not reach it.
|
|
75
|
+
*
|
|
76
|
+
* NODE_OPTIONS is not a render input and is dropped: VS Code's debug
|
|
77
|
+
* terminal (`--require …/bootloader.js`), `--inspect` or `--cpu-prof` would
|
|
78
|
+
* otherwise attach to a process that lives for hours, and `--cpu-prof` would
|
|
79
|
+
* write a profile into the project when it finally exits. The cwd is the
|
|
80
|
+
* state dir for the same reason: not the project that happened to start it.
|
|
81
|
+
*/
|
|
82
|
+
export declare function spawnSupervisor(args: SpawnArgs, env: NodeJS.ProcessEnv, entry?: string): ChildProcess;
|
|
83
|
+
export declare const defaultReadCommand: CommandReader;
|
|
84
|
+
/**
|
|
85
|
+
* Remove the files of the daemon `s` describes, and nothing newer. The state
|
|
86
|
+
* goes only if it still names the same pid and start time: between our read
|
|
87
|
+
* and this call another client may have spawned a replacement that wrote its
|
|
88
|
+
* own (the review traced `jux browser stop` deleting a new daemon's files
|
|
89
|
+
* while the old one's Chrome took 5 s to close, orphaning the new one). The
|
|
90
|
+
* socket goes only if it is the path that state named and nothing listens on
|
|
91
|
+
* it, compared by inode so a socket bound meanwhile is left alone.
|
|
92
|
+
*/
|
|
93
|
+
export declare function clearStaleState(paths: DaemonPaths, s: DaemonState): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* The warm daemon's browser, or a private one if the daemon cannot be had.
|
|
96
|
+
* Never rejects because of the daemon; a private launch failure rejects as in
|
|
97
|
+
* PR 1.
|
|
98
|
+
*/
|
|
99
|
+
export declare function connectWarmBrowser(opts: WarmOptions): Promise<{
|
|
100
|
+
browser: Browser;
|
|
101
|
+
warm: boolean;
|
|
102
|
+
}>;
|
|
103
|
+
/**
|
|
104
|
+
* Start (or find) the daemon without a private fallback: `jux browser start`
|
|
105
|
+
* must not launch and close a whole Chrome just to report that the daemon
|
|
106
|
+
* could not start.
|
|
107
|
+
*/
|
|
108
|
+
export declare function startDaemon(opts: WarmOptions): Promise<{
|
|
109
|
+
state: DaemonState;
|
|
110
|
+
} | {
|
|
111
|
+
error: string;
|
|
112
|
+
}>;
|
|
113
|
+
/** The running daemon for this fingerprint, or null. A dead daemon's files are cleared. */
|
|
114
|
+
export declare function daemonStatus(given: StatusOptions): Promise<DaemonState | null>;
|
|
115
|
+
type ListOptions = Pick<WarmOptions, 'stateDir' | 'readCommand'>;
|
|
116
|
+
/** Every live daemon in `stateDir`, whichever key; dead ones' files are cleared on the way. */
|
|
117
|
+
export declare function listDaemons(opts: ListOptions): Promise<DaemonState[]>;
|
|
118
|
+
/**
|
|
119
|
+
* What stopping one daemon did: `none` (nothing running, or the state named a
|
|
120
|
+
* pid that is not ours and nothing listened on its socket), `stopped` (its
|
|
121
|
+
* pid is gone), `unverified` (a live pid we could not confirm as ours:
|
|
122
|
+
* nothing is signalled or removed), or `running` (ours, signalled, and still
|
|
123
|
+
* alive after 2 s).
|
|
124
|
+
*/
|
|
125
|
+
export type StopResult = {
|
|
126
|
+
outcome: 'none' | 'stopped';
|
|
127
|
+
} | {
|
|
128
|
+
outcome: 'unverified' | 'running';
|
|
129
|
+
pid: number;
|
|
130
|
+
reason: string;
|
|
131
|
+
};
|
|
132
|
+
/** Stop the daemon for this fingerprint only. */
|
|
133
|
+
export declare function stopDaemon(given: StatusOptions): Promise<StopResult>;
|
|
134
|
+
/** One daemon `stopAllDaemons` found, and what stopping it did. */
|
|
135
|
+
export type DaemonStop = {
|
|
136
|
+
key: string;
|
|
137
|
+
pid: number;
|
|
138
|
+
} & StopResult;
|
|
139
|
+
/**
|
|
140
|
+
* Stop every daemon in `stateDir`, whichever key it runs under, each through
|
|
141
|
+
* the same verification as `stopDaemon`. Entries whose outcome is `none`
|
|
142
|
+
* (stale files, reused pids) are cleared and left out.
|
|
143
|
+
*/
|
|
144
|
+
export declare function stopAllDaemons(opts: ListOptions): Promise<DaemonStop[]>;
|
|
145
|
+
export {};
|