starskiff 0.6.1 → 0.7.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/README.md +14 -9
- package/dist/Instance.d.ts +25 -8
- package/dist/Instance.d.ts.map +1 -1
- package/dist/Instance.js +208 -132
- package/dist/Instance.js.map +1 -1
- package/dist/command.d.ts +29 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +100 -0
- package/dist/command.js.map +1 -0
- package/dist/cosmos.d.ts +27 -9
- package/dist/cosmos.d.ts.map +1 -1
- package/dist/cosmos.js +133 -107
- package/dist/cosmos.js.map +1 -1
- package/dist/docker.d.ts +8 -8
- package/dist/docker.d.ts.map +1 -1
- package/dist/docker.js +26 -13
- package/dist/docker.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instances/evmd.d.ts +11 -20
- package/dist/instances/evmd.d.ts.map +1 -1
- package/dist/instances/evmd.js +6 -4
- package/dist/instances/evmd.js.map +1 -1
- package/dist/instances/gaiad.d.ts +5 -17
- package/dist/instances/gaiad.d.ts.map +1 -1
- package/dist/instances/gaiad.js.map +1 -1
- package/dist/instances/hermes.d.ts +3 -9
- package/dist/instances/hermes.d.ts.map +1 -1
- package/dist/instances/hermes.js +10 -1
- package/dist/instances/hermes.js.map +1 -1
- package/dist/instances/mantra.d.ts +9 -20
- package/dist/instances/mantra.d.ts.map +1 -1
- package/dist/instances/mantra.js +5 -6
- package/dist/instances/mantra.js.map +1 -1
- package/dist/instances/marood.d.ts +8 -21
- package/dist/instances/marood.d.ts.map +1 -1
- package/dist/instances/marood.js +7 -7
- package/dist/instances/marood.js.map +1 -1
- package/dist/instances/simd.d.ts +5 -17
- package/dist/instances/simd.d.ts.map +1 -1
- package/dist/instances/simd.js.map +1 -1
- package/dist/instances/wasmd.d.ts +5 -17
- package/dist/instances/wasmd.d.ts.map +1 -1
- package/dist/instances/wasmd.js.map +1 -1
- package/dist/instances/xplad.d.ts +6 -17
- package/dist/instances/xplad.d.ts.map +1 -1
- package/dist/instances/xplad.js +1 -1
- package/dist/instances/xplad.js.map +1 -1
- package/dist/instances/xrplevm.d.ts +12 -20
- package/dist/instances/xrplevm.d.ts.map +1 -1
- package/dist/instances/xrplevm.js +14 -10
- package/dist/instances/xrplevm.js.map +1 -1
- package/dist/ports.d.ts.map +1 -1
- package/dist/ports.js +8 -2
- package/dist/ports.js.map +1 -1
- package/dist/process.d.ts +2 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +3 -2
- package/dist/process.js.map +1 -1
- package/dist/runtime.d.ts +20 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +11 -0
- package/dist/runtime.js.map +1 -0
- package/dist/source.d.ts +25 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +2 -0
- package/dist/source.js.map +1 -0
- package/package.json +5 -2
- package/src/Instance.ts +244 -133
- package/src/command.ts +144 -0
- package/src/cosmos.ts +178 -128
- package/src/docker.ts +33 -16
- package/src/index.ts +2 -1
- package/src/instances/evmd.ts +8 -11
- package/src/instances/gaiad.ts +2 -8
- package/src/instances/hermes.ts +10 -1
- package/src/instances/mantra.ts +8 -13
- package/src/instances/marood.ts +12 -18
- package/src/instances/simd.ts +2 -8
- package/src/instances/wasmd.ts +2 -8
- package/src/instances/xplad.ts +3 -8
- package/src/instances/xrplevm.ts +20 -16
- package/src/ports.ts +8 -5
- package/src/process.ts +5 -2
- package/src/runtime.ts +30 -0
- package/src/source.ts +26 -0
- package/dist/execution.d.ts +0 -21
- package/dist/execution.d.ts.map +0 -1
- package/dist/execution.js +0 -13
- package/dist/execution.js.map +0 -1
- package/src/execution.ts +0 -32
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ Inspired by [prool](https://github.com/wevm/prool) (test instances for Ethereum)
|
|
|
32
32
|
| `Instance.marood()` | **required** — `image` or `binary` (private) | Cosmos SDK + **EVM** + maroo modules | maroo chain (viem `marooTestnet`) |
|
|
33
33
|
| `Instance.hermes()` | binary `hermes` | — (IBC relayer) | Relaying between two instances |
|
|
34
34
|
|
|
35
|
-
Every instance is **image-first**: where a usable, version-pinned image exists it's the default (Docker required); pass `binary` to run a local executable, or `image` to bind your own. Where none exists (`marood` — private node source)
|
|
35
|
+
Every instance is **image-first**: where a usable, version-pinned image exists it's the default (Docker required); pass `binary` to run a local executable, or `image` to bind your own. The two overrides are mutually exclusive in TypeScript and at runtime. Where none exists (`marood` — private node source) exactly one source is **required** by its TypeScript signature, with runtime validation retained for JavaScript callers. `hermes` is a relayer run as a host binary, not a chain node. See the docs [container runtime guide](./../docs/src/pages/docs/guides/docker.mdx).
|
|
36
36
|
|
|
37
37
|
> `evmd`'s default image is built from cosmos/evm source by the `publish-images` workflow and pinned by multi-arch manifest **digest** — the default always resolves to the exact published artifact.
|
|
38
38
|
|
|
@@ -42,6 +42,8 @@ Every instance is **image-first**: where a usable, version-pinned image exists i
|
|
|
42
42
|
pnpm add -D starskiff
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
starskiff is ESM-only and supports Node.js 22 or newer.
|
|
46
|
+
|
|
45
47
|
### Prerequisites
|
|
46
48
|
|
|
47
49
|
Image-backed instances (`simd`, `wasmd`, `gaiad`, `xplad`, `xrplevm`, `mantra`, `evmd`) need only a running **Docker** — the image is pulled on first use. The `hermes` relayer needs its binary on `PATH` (official releases at [informalsystems/hermes](https://github.com/informalsystems/hermes/releases)); `marood` (no default image) needs an injected source — an `image`, or a binary on `PATH`.
|
|
@@ -275,12 +277,20 @@ const instance = Instance.wasmd({ chainId: 'test-1' }, { timeout: 30_000 });
|
|
|
275
277
|
|
|
276
278
|
| Method | Description |
|
|
277
279
|
| --------------------- | ---------------------------------------------------------------------- |
|
|
278
|
-
| `start()` | Start the instance
|
|
280
|
+
| `start()` | Start the instance; resolves when it is ready. |
|
|
279
281
|
| `stop()` | Stop the instance and cleanup temp directory. |
|
|
280
282
|
| `restart()` | Stop then start. |
|
|
281
283
|
| `on(event, handler)` | Listen to events (`message`, `stdout`, `stderr`, `listening`, `exit`). |
|
|
282
284
|
| `off(event, handler)` | Remove event listener. |
|
|
283
285
|
|
|
286
|
+
Instances also implement `Symbol.asyncDispose`, so `await using` scopes stop
|
|
287
|
+
them automatically:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
await using instance = Instance.wasmd();
|
|
291
|
+
await instance.start();
|
|
292
|
+
```
|
|
293
|
+
|
|
284
294
|
### Instance properties
|
|
285
295
|
|
|
286
296
|
| Property | Type | Description |
|
|
@@ -328,14 +338,9 @@ Recommended: fund multiple accounts in genesis, assign each test its own account
|
|
|
328
338
|
| State reset | Helm redeploy (minutes) | kill + restart (~3s) |
|
|
329
339
|
| Best for | Production simulation | Dev/test |
|
|
330
340
|
|
|
331
|
-
##
|
|
332
|
-
|
|
333
|
-
- [ ] `starskiff.config.ts` — config-based chain + relayer declaration
|
|
334
|
-
- [ ] `starskiff/vitest` — vitest plugin (automatic setup/teardown via `vitestPlugin(config)`)
|
|
335
|
-
- [ ] `starskiff/playwright` — playwright plugin (`playwrightPlugin(config)`)
|
|
336
|
-
- [ ] `starskiff/setup-binaries` GitHub Action for CI binary setup
|
|
341
|
+
## Roadmap
|
|
337
342
|
|
|
338
|
-
|
|
343
|
+
See the [roadmap to v1.0](https://github.com/2wheeh/starskiff/blob/main/ROADMAP.md) for planned API, runtime, artifact, and integration work.
|
|
339
344
|
|
|
340
345
|
## License
|
|
341
346
|
|
package/dist/Instance.d.ts
CHANGED
|
@@ -27,8 +27,8 @@ export type Instance = {
|
|
|
27
27
|
/** Get all buffered messages. */
|
|
28
28
|
get(): string[];
|
|
29
29
|
};
|
|
30
|
-
/** Start the instance.
|
|
31
|
-
start(): Promise<
|
|
30
|
+
/** Start the instance. */
|
|
31
|
+
start(): Promise<void>;
|
|
32
32
|
/** Stop the instance and clean up resources. */
|
|
33
33
|
stop(): Promise<void>;
|
|
34
34
|
/** Stop then start the instance. */
|
|
@@ -37,6 +37,8 @@ export type Instance = {
|
|
|
37
37
|
on: Emitter<EventTypes>['on'];
|
|
38
38
|
/** Unsubscribe from instance events. */
|
|
39
39
|
off: Emitter<EventTypes>['off'];
|
|
40
|
+
/** Stop the instance when leaving an `await using` scope. */
|
|
41
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
40
42
|
};
|
|
41
43
|
export type InstanceOptions = {
|
|
42
44
|
/** Number of messages to store in-memory. @default 20 */
|
|
@@ -49,29 +51,43 @@ export type InstanceStartOptions = {
|
|
|
49
51
|
};
|
|
50
52
|
export type InstanceStartContext = {
|
|
51
53
|
emitter: Emitter<EventTypes>;
|
|
54
|
+
/** Aborted when the managed start operation times out. */
|
|
55
|
+
signal: AbortSignal;
|
|
56
|
+
/** Record the active startup phase for actionable failure diagnostics. */
|
|
57
|
+
setStartDiagnostics(diagnostics: InstanceStartDiagnostics): void;
|
|
52
58
|
setEndpoint?(endpoint: {
|
|
53
59
|
host?: string;
|
|
54
60
|
port?: number;
|
|
55
61
|
}): void;
|
|
56
62
|
status: InstanceStatus;
|
|
57
63
|
};
|
|
64
|
+
export type InstanceStartDiagnostics = {
|
|
65
|
+
/** Human-readable startup phase, such as `init` or `readiness`. */
|
|
66
|
+
phase: string;
|
|
67
|
+
/** Logical command, excluding runtime wrappers and injected environment. */
|
|
68
|
+
command?: string;
|
|
69
|
+
};
|
|
58
70
|
export type InstanceStopContext = {
|
|
59
71
|
emitter: Emitter<EventTypes>;
|
|
60
72
|
status: InstanceStatus;
|
|
61
73
|
};
|
|
62
|
-
|
|
74
|
+
/** Values supplied by an instance definition before lifecycle management is applied. */
|
|
75
|
+
export type InstanceDefinition = {
|
|
63
76
|
name: string;
|
|
64
77
|
host: string;
|
|
65
78
|
port: number;
|
|
66
79
|
start(options: InstanceStartOptions, context: InstanceStartContext): Promise<void>;
|
|
67
80
|
stop(context: InstanceStopContext): Promise<void>;
|
|
68
81
|
};
|
|
82
|
+
/** Callable returned by {@link define}. */
|
|
83
|
+
export type InstanceFactory<P, R extends InstanceDefinition = InstanceDefinition> = (...args: undefined extends P ? [parameters?: P, options?: InstanceOptions] : [parameters: P, options?: InstanceOptions]) => Omit<R, keyof Instance> & Instance;
|
|
69
84
|
/**
|
|
70
85
|
* Creates an instance definition.
|
|
71
86
|
*
|
|
72
|
-
* Takes a
|
|
73
|
-
* and start/stop implementations.
|
|
74
|
-
*
|
|
87
|
+
* Takes a definition function that returns the instance's name, host, port,
|
|
88
|
+
* and start/stop implementations. The returned callable always treats its
|
|
89
|
+
* first argument as definition parameters and its second as lifecycle
|
|
90
|
+
* options. For a parameterless definition, pass `undefined` before options.
|
|
75
91
|
*
|
|
76
92
|
* @example
|
|
77
93
|
* ```ts
|
|
@@ -79,14 +95,15 @@ type DefineFnResult = {
|
|
|
79
95
|
* name: 'simd',
|
|
80
96
|
* host: 'localhost',
|
|
81
97
|
* port: 26657,
|
|
98
|
+
* chainId: params?.chainId ?? 'test-1',
|
|
82
99
|
* async start(opts, ctx) { ... },
|
|
83
100
|
* async stop(ctx) { ... },
|
|
84
101
|
* }))
|
|
85
102
|
*
|
|
86
|
-
* const instance = simd({ chainId: 'test-1' })
|
|
103
|
+
* const instance = simd({ chainId: 'test-1' }, { timeout: 30_000 })
|
|
87
104
|
* instance.chainId // string — extra field preserved
|
|
88
105
|
* await instance.start()
|
|
89
106
|
* ```
|
|
90
107
|
*/
|
|
91
|
-
export declare function define<P = undefined, R extends
|
|
108
|
+
export declare function define<P = undefined, R extends InstanceDefinition = InstanceDefinition>(fn: (parameters: P) => R): InstanceFactory<P, R>;
|
|
92
109
|
//# sourceMappingURL=Instance.d.ts.map
|
package/dist/Instance.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Instance.d.ts","sourceRoot":"","sources":["../src/Instance.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,KAAK,OAAO,EAAgB,MAAM,MAAM,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,YAAY,CAAA;AAEhB,oEAAoE;AACpE,MAAM,MAAM,QAAQ,GAAG;IACrB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,gCAAgC;IAChC,MAAM,EAAE,cAAc,CAAA;IACtB,8CAA8C;IAC9C,QAAQ,EAAE;QACR,mCAAmC;QACnC,KAAK,IAAI,IAAI,CAAA;QACb,iCAAiC;QACjC,GAAG,IAAI,MAAM,EAAE,CAAA;KAChB,CAAA;IACD,
|
|
1
|
+
{"version":3,"file":"Instance.d.ts","sourceRoot":"","sources":["../src/Instance.ts"],"names":[],"mappings":"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"}
|
package/dist/Instance.js
CHANGED
|
@@ -8,12 +8,36 @@ export { xrplevm } from './instances/xrplevm.js';
|
|
|
8
8
|
export { evmd } from './instances/evmd.js';
|
|
9
9
|
export { marood } from './instances/marood.js';
|
|
10
10
|
export { hermes } from './instances/hermes.js';
|
|
11
|
+
const DIAGNOSTIC_OUTPUT_LIMIT = 64 * 1024;
|
|
12
|
+
const DIAGNOSTIC_LINE_LIMIT = 50;
|
|
13
|
+
function outputTail(output) {
|
|
14
|
+
const normalized = output.slice(-DIAGNOSTIC_OUTPUT_LIMIT).trimEnd();
|
|
15
|
+
if (!normalized)
|
|
16
|
+
return undefined;
|
|
17
|
+
return normalized.split(/\r?\n/).slice(-DIAGNOSTIC_LINE_LIMIT).join('\n');
|
|
18
|
+
}
|
|
19
|
+
function startError(name, cause, diagnostics, output, timedOut) {
|
|
20
|
+
const phase = diagnostics ? ` during ${diagnostics.phase}` : '';
|
|
21
|
+
const lines = [
|
|
22
|
+
`Instance "${name}" failed to start${timedOut ? ' in time' : ''}${phase}.`,
|
|
23
|
+
];
|
|
24
|
+
if (diagnostics?.command)
|
|
25
|
+
lines.push(`command: ${diagnostics.command}`);
|
|
26
|
+
const detail = outputTail(cause instanceof Error ? cause.message : String(cause));
|
|
27
|
+
if (!timedOut && detail)
|
|
28
|
+
lines.push(`details:\n${detail}`);
|
|
29
|
+
const tail = outputTail(output);
|
|
30
|
+
if (tail)
|
|
31
|
+
lines.push(`last ${DIAGNOSTIC_LINE_LIMIT} lines:\n${tail}`);
|
|
32
|
+
return new Error(lines.join('\n'), { cause });
|
|
33
|
+
}
|
|
11
34
|
/**
|
|
12
35
|
* Creates an instance definition.
|
|
13
36
|
*
|
|
14
|
-
* Takes a
|
|
15
|
-
* and start/stop implementations.
|
|
16
|
-
*
|
|
37
|
+
* Takes a definition function that returns the instance's name, host, port,
|
|
38
|
+
* and start/stop implementations. The returned callable always treats its
|
|
39
|
+
* first argument as definition parameters and its second as lifecycle
|
|
40
|
+
* options. For a parameterless definition, pass `undefined` before options.
|
|
17
41
|
*
|
|
18
42
|
* @example
|
|
19
43
|
* ```ts
|
|
@@ -21,43 +45,69 @@ export { hermes } from './instances/hermes.js';
|
|
|
21
45
|
* name: 'simd',
|
|
22
46
|
* host: 'localhost',
|
|
23
47
|
* port: 26657,
|
|
48
|
+
* chainId: params?.chainId ?? 'test-1',
|
|
24
49
|
* async start(opts, ctx) { ... },
|
|
25
50
|
* async stop(ctx) { ... },
|
|
26
51
|
* }))
|
|
27
52
|
*
|
|
28
|
-
* const instance = simd({ chainId: 'test-1' })
|
|
53
|
+
* const instance = simd({ chainId: 'test-1' }, { timeout: 30_000 })
|
|
29
54
|
* instance.chainId // string — extra field preserved
|
|
30
55
|
* await instance.start()
|
|
31
56
|
* ```
|
|
32
57
|
*/
|
|
33
58
|
export function define(fn) {
|
|
34
|
-
return (
|
|
35
|
-
const isInstanceOptions = (v) => v != null && typeof v === 'object' && ('messageBuffer' in v || 'timeout' in v);
|
|
36
|
-
// When P = undefined: (options?) → first arg is options
|
|
37
|
-
// When P is defined: (params, options?) → first arg is params, second is options
|
|
38
|
-
const parameters = (options_ !== undefined || !isInstanceOptions(parametersOrOptions)
|
|
39
|
-
? parametersOrOptions
|
|
40
|
-
: undefined);
|
|
41
|
-
const options = options_ ?? (isInstanceOptions(parametersOrOptions) ? parametersOrOptions : {});
|
|
59
|
+
return ((parameters, options = {}) => {
|
|
42
60
|
const raw = fn(parameters);
|
|
43
61
|
const { name, start, stop } = raw;
|
|
44
62
|
let host = raw.host;
|
|
45
63
|
let port = raw.port;
|
|
46
64
|
const { messageBuffer = 20, timeout = 60_000 } = options;
|
|
47
|
-
let
|
|
48
|
-
let
|
|
49
|
-
let
|
|
65
|
+
let startOperation;
|
|
66
|
+
let stopOperation;
|
|
67
|
+
let stopCleanupOperation;
|
|
68
|
+
let restartOperation;
|
|
50
69
|
const emitter = mitt();
|
|
51
70
|
let messages = [];
|
|
71
|
+
let diagnosticOutput = '';
|
|
72
|
+
let startDiagnostics;
|
|
52
73
|
let status = 'idle';
|
|
53
74
|
let restarting = false;
|
|
54
75
|
const onMessage = (message) => {
|
|
55
76
|
messages.push(message);
|
|
56
77
|
if (messages.length > messageBuffer)
|
|
57
78
|
messages.shift();
|
|
79
|
+
diagnosticOutput += message;
|
|
80
|
+
if (diagnosticOutput.length > DIAGNOSTIC_OUTPUT_LIMIT) {
|
|
81
|
+
diagnosticOutput = diagnosticOutput.slice(-DIAGNOSTIC_OUTPUT_LIMIT);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const onListening = () => {
|
|
85
|
+
if (status === 'starting')
|
|
86
|
+
status = 'started';
|
|
87
|
+
};
|
|
88
|
+
const onExit = () => {
|
|
89
|
+
// A managed stop owns the transition to `stopped` after all cleanup is
|
|
90
|
+
// complete. Exit events only represent an unexpected running-process
|
|
91
|
+
// exit; changing state while `stopping` would reopen start too early.
|
|
92
|
+
if (status === 'started')
|
|
93
|
+
status = 'stopped';
|
|
94
|
+
};
|
|
95
|
+
const subscribe = () => {
|
|
96
|
+
emitter.on('message', onMessage);
|
|
97
|
+
emitter.on('listening', onListening);
|
|
98
|
+
emitter.on('exit', onExit);
|
|
99
|
+
};
|
|
100
|
+
const unsubscribe = () => {
|
|
101
|
+
emitter.off('message', onMessage);
|
|
102
|
+
emitter.off('listening', onListening);
|
|
103
|
+
emitter.off('exit', onExit);
|
|
104
|
+
};
|
|
105
|
+
const clearRuntimeState = () => {
|
|
106
|
+
self.messages.clear();
|
|
107
|
+
diagnosticOutput = '';
|
|
108
|
+
startDiagnostics = undefined;
|
|
109
|
+
unsubscribe();
|
|
58
110
|
};
|
|
59
|
-
const onListening = () => { status = 'started'; };
|
|
60
|
-
const onExit = () => { status = 'stopped'; };
|
|
61
111
|
const self = {
|
|
62
112
|
get host() { return host; },
|
|
63
113
|
name,
|
|
@@ -72,138 +122,164 @@ export function define(fn) {
|
|
|
72
122
|
get() { return [...messages]; },
|
|
73
123
|
},
|
|
74
124
|
async start() {
|
|
75
|
-
if (status === 'starting')
|
|
76
|
-
return
|
|
125
|
+
if (status === 'starting' && startOperation)
|
|
126
|
+
return startOperation;
|
|
77
127
|
if (status !== 'idle' && status !== 'stopped')
|
|
78
128
|
throw new Error(`Instance "${name}" is not in an idle or stopped state. Status: ${status}`);
|
|
79
|
-
let startTimer;
|
|
80
|
-
// Guards the in-flight start(...) call's .then/.catch below: once the
|
|
81
|
-
// timeout fires, status/resolvers have already been reset (and a
|
|
82
|
-
// retry may be in flight), so a late settle must not touch them.
|
|
83
|
-
let timedOut = false;
|
|
84
|
-
if (typeof timeout === 'number') {
|
|
85
|
-
startTimer = setTimeout(() => {
|
|
86
|
-
timedOut = true;
|
|
87
|
-
status = 'idle';
|
|
88
|
-
self.messages.clear();
|
|
89
|
-
emitter.off('message', onMessage);
|
|
90
|
-
emitter.off('listening', onListening);
|
|
91
|
-
emitter.off('exit', onExit);
|
|
92
|
-
startResolver.reject(new Error(`Instance "${name}" failed to start in time.`));
|
|
93
|
-
startResolver = Promise.withResolvers();
|
|
94
|
-
// Best-effort: the child may still be running post-timeout, so
|
|
95
|
-
// ask the underlying stop to tear it down. Never let this throw —
|
|
96
|
-
// the instance must remain retryable regardless of the outcome.
|
|
97
|
-
try {
|
|
98
|
-
void stop({ emitter, status: self.status }).catch(() => { });
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// ignore
|
|
102
|
-
}
|
|
103
|
-
}, timeout);
|
|
104
|
-
}
|
|
105
|
-
emitter.on('message', onMessage);
|
|
106
|
-
emitter.on('listening', onListening);
|
|
107
|
-
emitter.on('exit', onExit);
|
|
108
129
|
status = 'starting';
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
130
|
+
diagnosticOutput = '';
|
|
131
|
+
startDiagnostics = undefined;
|
|
132
|
+
subscribe();
|
|
133
|
+
const controller = new AbortController();
|
|
134
|
+
startOperation = (async () => {
|
|
135
|
+
let startTimer;
|
|
136
|
+
let timedOut = false;
|
|
137
|
+
const startTimeout = new Promise((_, reject) => {
|
|
138
|
+
startTimer = setTimeout(() => {
|
|
139
|
+
timedOut = true;
|
|
140
|
+
const timeoutCause = new Error(`Instance "${name}" exceeded its ${timeout}ms start timeout.`);
|
|
141
|
+
const error = startError(name, timeoutCause, startDiagnostics, diagnosticOutput, true);
|
|
142
|
+
controller.abort(error);
|
|
143
|
+
reject(error);
|
|
144
|
+
}, timeout);
|
|
145
|
+
});
|
|
146
|
+
const rawStart = Promise.resolve().then(() => start({ port }, {
|
|
147
|
+
emitter,
|
|
148
|
+
signal: controller.signal,
|
|
149
|
+
setStartDiagnostics(diagnostics) {
|
|
150
|
+
startDiagnostics = { ...diagnostics };
|
|
151
|
+
},
|
|
152
|
+
setEndpoint(endpoint) {
|
|
153
|
+
if (endpoint.host !== undefined)
|
|
154
|
+
host = endpoint.host;
|
|
155
|
+
if (endpoint.port !== undefined)
|
|
156
|
+
port = endpoint.port;
|
|
157
|
+
},
|
|
158
|
+
status: self.status,
|
|
159
|
+
}));
|
|
160
|
+
try {
|
|
161
|
+
await Promise.race([rawStart, startTimeout]);
|
|
162
|
+
status = 'started';
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (!timedOut) {
|
|
166
|
+
status = 'idle';
|
|
167
|
+
const enriched = startDiagnostics
|
|
168
|
+
? startError(name, error, startDiagnostics, diagnosticOutput, false)
|
|
169
|
+
: error;
|
|
170
|
+
clearRuntimeState();
|
|
171
|
+
throw enriched;
|
|
172
|
+
}
|
|
173
|
+
// A timed-out start is not retryable until its teardown finishes.
|
|
174
|
+
// Keeping the instance in `stopping` prevents an old child from
|
|
175
|
+
// racing with a new start and overwriting shared runtime state.
|
|
176
|
+
status = 'stopping';
|
|
177
|
+
stopCleanupOperation = Promise.resolve()
|
|
178
|
+
.then(() => stop({ emitter, status: self.status }))
|
|
179
|
+
.then(() => {
|
|
180
|
+
status = 'idle';
|
|
181
|
+
clearRuntimeState();
|
|
182
|
+
}, () => {
|
|
183
|
+
// Startup never completed, so keep new starts blocked. A
|
|
184
|
+
// later stop() can retry teardown from this state.
|
|
185
|
+
status = 'stopping';
|
|
186
|
+
})
|
|
187
|
+
.finally(() => {
|
|
188
|
+
startOperation = undefined;
|
|
189
|
+
stopCleanupOperation = undefined;
|
|
190
|
+
});
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
if (startTimer)
|
|
195
|
+
clearTimeout(startTimer);
|
|
196
|
+
if (!timedOut)
|
|
197
|
+
startOperation = undefined;
|
|
198
|
+
}
|
|
199
|
+
})();
|
|
200
|
+
return startOperation;
|
|
142
201
|
},
|
|
143
202
|
async stop() {
|
|
144
|
-
if (status === 'stopping')
|
|
145
|
-
return
|
|
203
|
+
if (status === 'stopping' && stopOperation)
|
|
204
|
+
return stopOperation;
|
|
205
|
+
if (status === 'stopping' && stopCleanupOperation) {
|
|
206
|
+
await stopCleanupOperation;
|
|
207
|
+
const settledStatus = status;
|
|
208
|
+
if (settledStatus === 'idle' || settledStatus === 'stopped')
|
|
209
|
+
return;
|
|
210
|
+
return self.stop();
|
|
211
|
+
}
|
|
146
212
|
if (status === 'starting')
|
|
147
213
|
throw new Error(`Instance "${name}" is starting.`);
|
|
148
|
-
let stopTimer;
|
|
149
|
-
if (typeof timeout === 'number') {
|
|
150
|
-
stopTimer = setTimeout(() => {
|
|
151
|
-
stopResolver.reject(new Error(`Instance "${name}" failed to stop in time.`));
|
|
152
|
-
}, timeout);
|
|
153
|
-
}
|
|
154
214
|
status = 'stopping';
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
215
|
+
stopOperation = (async () => {
|
|
216
|
+
let stopTimer;
|
|
217
|
+
let timedOut = false;
|
|
218
|
+
const stopTimeout = new Promise((_, reject) => {
|
|
219
|
+
stopTimer = setTimeout(() => {
|
|
220
|
+
timedOut = true;
|
|
221
|
+
reject(new Error(`Instance "${name}" failed to stop in time.`));
|
|
222
|
+
}, timeout);
|
|
223
|
+
});
|
|
224
|
+
const rawStop = Promise.resolve().then(() => stop({ emitter, status: self.status }));
|
|
225
|
+
try {
|
|
226
|
+
await Promise.race([rawStop, stopTimeout]);
|
|
227
|
+
status = 'stopped';
|
|
228
|
+
clearRuntimeState();
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
if (!timedOut) {
|
|
232
|
+
status = 'started';
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Keep `stopping` until the original teardown settles. A stop
|
|
236
|
+
// timeout must not make a still-running instance restartable.
|
|
237
|
+
stopCleanupOperation = rawStop
|
|
238
|
+
.then(() => {
|
|
239
|
+
status = 'stopped';
|
|
240
|
+
clearRuntimeState();
|
|
241
|
+
})
|
|
242
|
+
.catch(() => {
|
|
243
|
+
status = 'started';
|
|
244
|
+
})
|
|
245
|
+
.finally(() => {
|
|
246
|
+
stopCleanupOperation = undefined;
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
if (stopTimer)
|
|
253
|
+
clearTimeout(stopTimer);
|
|
254
|
+
stopOperation = undefined;
|
|
255
|
+
}
|
|
256
|
+
})();
|
|
257
|
+
return stopOperation;
|
|
178
258
|
},
|
|
179
259
|
async restart() {
|
|
180
|
-
if (restarting)
|
|
181
|
-
return
|
|
260
|
+
if (restarting && restartOperation)
|
|
261
|
+
return restartOperation;
|
|
182
262
|
restarting = true;
|
|
183
|
-
self.stop()
|
|
263
|
+
restartOperation = self.stop()
|
|
184
264
|
.then(() => self.start())
|
|
185
|
-
.then(() => {
|
|
186
|
-
|
|
187
|
-
restartResolver.resolve();
|
|
188
|
-
restartResolver = Promise.withResolvers();
|
|
189
|
-
})
|
|
190
|
-
.catch((error) => {
|
|
265
|
+
.then(() => { })
|
|
266
|
+
.finally(() => {
|
|
191
267
|
restarting = false;
|
|
192
|
-
|
|
193
|
-
restartResolver = Promise.withResolvers();
|
|
268
|
+
restartOperation = undefined;
|
|
194
269
|
});
|
|
195
|
-
return
|
|
270
|
+
return restartOperation;
|
|
196
271
|
},
|
|
197
272
|
on: emitter.on.bind(emitter),
|
|
198
273
|
off: emitter.off.bind(emitter),
|
|
274
|
+
[Symbol.asyncDispose]() {
|
|
275
|
+
return self.stop();
|
|
276
|
+
},
|
|
199
277
|
};
|
|
200
|
-
const knownKeys = new Set(
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return Object.assign(self, extra);
|
|
207
|
-
};
|
|
278
|
+
const knownKeys = new Set(Reflect.ownKeys(self));
|
|
279
|
+
const extraDescriptors = Object.fromEntries(Reflect.ownKeys(raw)
|
|
280
|
+
.filter((key) => !knownKeys.has(key))
|
|
281
|
+
.map((key) => [key, Object.getOwnPropertyDescriptor(raw, key)]));
|
|
282
|
+
return Object.defineProperties(self, extraDescriptors);
|
|
283
|
+
});
|
|
208
284
|
}
|
|
209
285
|
//# sourceMappingURL=Instance.js.map
|
package/dist/Instance.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Instance.js","sourceRoot":"","sources":["../src/Instance.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAA8B,MAAM,MAAM,CAAA;AAGvD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"Instance.js","sourceRoot":"","sources":["../src/Instance.ts"],"names":[],"mappings":"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"}
|