@andrew_l/app 0.3.8 → 0.4.1
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 +2 -1
- package/bin/vrun +0 -1
- package/dist/_chunks/cli.mjs +2 -0
- package/dist/index.d.mts +315 -320
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2026 -2348
- package/dist/index.mjs.map +1 -1
- package/dist/vrun.d.mts +1 -2
- package/dist/vrun.mjs +9 -10
- package/dist/vrun.mjs.map +1 -1
- package/package.json +10 -9
- package/dist/index.cjs +0 -2678
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -651
- package/dist/index.d.ts +0 -651
- package/dist/vrun.cjs +0 -13
- package/dist/vrun.cjs.map +0 -1
- package/dist/vrun.d.cts +0 -2
- package/dist/vrun.d.ts +0 -2
package/dist/index.d.ts
DELETED
|
@@ -1,651 +0,0 @@
|
|
|
1
|
-
import { IfAny, Data, Logger, AnyFunction, Awaitable, SimpleEventEmitter, ExecResult, LogLevel, Scheduler, AsyncIterableQueue, ResourcePool, CancellablePromise } from '@andrew_l/toolkit';
|
|
2
|
-
import * as cp from 'node:child_process';
|
|
3
|
-
import { EventEmitter } from 'node:events';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Declaration for a single typed app prop.
|
|
7
|
-
* @group Types
|
|
8
|
-
*/
|
|
9
|
-
interface PropOptions<T = any> {
|
|
10
|
-
type: PropType<T> | null;
|
|
11
|
-
description?: string;
|
|
12
|
-
alias?: string;
|
|
13
|
-
required?: boolean;
|
|
14
|
-
env?: string | string[];
|
|
15
|
-
default?: () => InferPropType<T>;
|
|
16
|
-
parser?: (value: string) => InferPropType<T>;
|
|
17
|
-
enum?: string[];
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* @group Types
|
|
21
|
-
*/
|
|
22
|
-
type PropType<T> = PropConstructor<T> | PropConstructor<T>[];
|
|
23
|
-
/**
|
|
24
|
-
* Map of prop declarations keyed by name — passed as `props` in `defineApp`.
|
|
25
|
-
* @group Types
|
|
26
|
-
*/
|
|
27
|
-
type ObjectPropsOptions<P = Data> = {
|
|
28
|
-
[K in keyof P]: PropOptions<P[K]>;
|
|
29
|
-
};
|
|
30
|
-
type PropConstructor<T = any> = {
|
|
31
|
-
new (...args: any[]): T & {};
|
|
32
|
-
} | {
|
|
33
|
-
(): T;
|
|
34
|
-
} | PropMethod<T>;
|
|
35
|
-
type PropMethod<T, TConstructor = any> = [T] extends [
|
|
36
|
-
((...args: any) => any) | undefined
|
|
37
|
-
] ? {
|
|
38
|
-
new (): TConstructor;
|
|
39
|
-
(): T;
|
|
40
|
-
readonly prototype: TConstructor;
|
|
41
|
-
} : never;
|
|
42
|
-
type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>;
|
|
43
|
-
type RequiredKeys<T> = {
|
|
44
|
-
[K in keyof T]: T[K] extends {
|
|
45
|
-
required: true;
|
|
46
|
-
} ? K : never;
|
|
47
|
-
}[keyof T];
|
|
48
|
-
type InferPropType<T> = [T] extends [null] ? any : [T] extends [{
|
|
49
|
-
type: null;
|
|
50
|
-
}] ? any : [T] extends [ObjectConstructor | {
|
|
51
|
-
type: ObjectConstructor;
|
|
52
|
-
}] ? Record<string, any> : [T] extends [BooleanConstructor | {
|
|
53
|
-
type: BooleanConstructor;
|
|
54
|
-
}] ? boolean : [T] extends [DateConstructor | {
|
|
55
|
-
type: DateConstructor;
|
|
56
|
-
}] ? Date : [T] extends [DateConstructor | {
|
|
57
|
-
type: DateConstructor;
|
|
58
|
-
}] ? Date : [T] extends [StringConstructor | {
|
|
59
|
-
type: StringConstructor;
|
|
60
|
-
}] ? string : [T] extends [(infer U)[] | {
|
|
61
|
-
type: (infer U)[];
|
|
62
|
-
}] ? U extends DateConstructor ? Date | InferPropType<U> : InferPropType<U> : [T] extends [PropOptions<infer V>] ? unknown extends V ? IfAny<V, V, V> : V : T;
|
|
63
|
-
/**
|
|
64
|
-
* Resolve the concrete prop value types from an `ObjectPropsOptions` declaration.
|
|
65
|
-
* @group Types
|
|
66
|
-
*/
|
|
67
|
-
type ExtractPropTypes<O> = {
|
|
68
|
-
[K in keyof Pick<O, RequiredKeys<O>>]: InferPropType<O[K]>;
|
|
69
|
-
} & {
|
|
70
|
-
[K in keyof Pick<O, OptionalKeys<O>>]?: InferPropType<O[K]>;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
declare namespace AppDefinition {
|
|
74
|
-
type EntryContext<T extends Data = Data> = T & {
|
|
75
|
-
log: Logger;
|
|
76
|
-
};
|
|
77
|
-
type SetupContext<T extends Data = Data> = T & {
|
|
78
|
-
log: Logger;
|
|
79
|
-
};
|
|
80
|
-
type RuntimeContext<T extends Data = Data> = T & {
|
|
81
|
-
log: Logger;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Shape of an application — name, typed props, lifecycle hooks, and optional methods.
|
|
86
|
-
* @group Types
|
|
87
|
-
*/
|
|
88
|
-
interface AppDefinition<P extends ObjectPropsOptions = {}, S extends Record<string, any> = {}, M extends Record<string, AnyFunction> = {}, RuntimeContext extends AppDefinition.RuntimeContext = AppDefinition.RuntimeContext<S & M>, EntryContext extends AppDefinition.EntryContext = AppDefinition.EntryContext<S & M>, SetupContext extends AppDefinition.SetupContext = AppDefinition.SetupContext<M>> {
|
|
89
|
-
/**
|
|
90
|
-
* Name of your awesome application
|
|
91
|
-
*/
|
|
92
|
-
name: string;
|
|
93
|
-
/**
|
|
94
|
-
* Describe what your application does
|
|
95
|
-
*/
|
|
96
|
-
description?: string;
|
|
97
|
-
/**
|
|
98
|
-
* Props options to be parsed from cli arguments of env variables
|
|
99
|
-
*/
|
|
100
|
-
props?: P;
|
|
101
|
-
/**
|
|
102
|
-
* Path to the file where this definition exports default
|
|
103
|
-
* Usually you should not use this option, because it tracks automatically
|
|
104
|
-
*/
|
|
105
|
-
filePath?: string | null;
|
|
106
|
-
/**
|
|
107
|
-
* Logger instance or constructor function
|
|
108
|
-
*/
|
|
109
|
-
logger?: false | Logger | ((definition: AppDefinition) => Logger);
|
|
110
|
-
/**
|
|
111
|
-
* Setup function to initialize application. Will be called once
|
|
112
|
-
*/
|
|
113
|
-
setup?(this: SetupContext, props: ExtractPropTypes<P>): Awaitable<S>;
|
|
114
|
-
/**
|
|
115
|
-
* Custom methods which will be available under `this` context
|
|
116
|
-
*/
|
|
117
|
-
methods?: M & ThisType<RuntimeContext>;
|
|
118
|
-
/**
|
|
119
|
-
* Entry function that will be called each time when application starts
|
|
120
|
-
*/
|
|
121
|
-
entry?(this: EntryContext, props: ExtractPropTypes<P>): Awaitable<any>;
|
|
122
|
-
/**
|
|
123
|
-
* Stop function that will be called each time when application stops
|
|
124
|
-
*/
|
|
125
|
-
stop?(this: RuntimeContext, props: ExtractPropTypes<P>): Awaitable<void>;
|
|
126
|
-
/**
|
|
127
|
-
* Shutdown function that will be called before application/process graceful shutdown
|
|
128
|
-
*/
|
|
129
|
-
shutdown?(this: RuntimeContext, props: ExtractPropTypes<P>): Awaitable<void>;
|
|
130
|
-
}
|
|
131
|
-
declare const APP_INSTANCE_STATE: {
|
|
132
|
-
readonly INIT: "init";
|
|
133
|
-
readonly IN_SETUP: "in-setup";
|
|
134
|
-
readonly SETUP: "setup";
|
|
135
|
-
readonly IN_STOP: "in-stop";
|
|
136
|
-
readonly IN_RUN: "in-run";
|
|
137
|
-
readonly RUN: "run";
|
|
138
|
-
readonly STOP: "stop";
|
|
139
|
-
readonly IN_SHUTDOWN: "in-shutdown";
|
|
140
|
-
readonly SHUTDOWN: "shutdown";
|
|
141
|
-
readonly ERROR: "error";
|
|
142
|
-
};
|
|
143
|
-
declare namespace AppInstance {
|
|
144
|
-
type EventMap = {
|
|
145
|
-
state: [newState: State, oldState: State];
|
|
146
|
-
error: [err: Error];
|
|
147
|
-
} & {
|
|
148
|
-
[K in State as `state:${K}`]: [];
|
|
149
|
-
};
|
|
150
|
-
type State = (typeof APP_INSTANCE_STATE)[keyof typeof APP_INSTANCE_STATE];
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Runtime state of a created app instance.
|
|
154
|
-
* @group Types
|
|
155
|
-
*/
|
|
156
|
-
interface AppInstance<P extends ObjectPropsOptions = {}, S extends Record<string, any> = {}, M extends Record<string, AnyFunction> = {}> {
|
|
157
|
-
definition: AppDefinition<P, S, M>;
|
|
158
|
-
props: ExtractPropTypes<P> | null;
|
|
159
|
-
setupState: AppDefinition.SetupContext<Data>;
|
|
160
|
-
eventBus: SimpleEventEmitter<AppInstance.EventMap>;
|
|
161
|
-
/** @internal */
|
|
162
|
-
mutexName: string | null;
|
|
163
|
-
/** @internal */
|
|
164
|
-
mutexQueue: Promise<void>;
|
|
165
|
-
readonly state: AppInstance.State;
|
|
166
|
-
logger: Logger;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Define an application with typed props and lifecycle hooks.
|
|
170
|
-
*
|
|
171
|
-
* When executed directly (`node app.ts`), the CLI is launched automatically.
|
|
172
|
-
* @group Main
|
|
173
|
-
* @example
|
|
174
|
-
* ```ts
|
|
175
|
-
* import { defineApp } from '@andrew_l/app';
|
|
176
|
-
*
|
|
177
|
-
* export default defineApp({
|
|
178
|
-
* name: 'server',
|
|
179
|
-
* props: {
|
|
180
|
-
* port: { type: Number, default: () => 3000 },
|
|
181
|
-
* },
|
|
182
|
-
* setup() {
|
|
183
|
-
* return { server: createServer() };
|
|
184
|
-
* },
|
|
185
|
-
* async entry(props) {
|
|
186
|
-
* await this.server.listen(props.port);
|
|
187
|
-
* },
|
|
188
|
-
* async stop() {
|
|
189
|
-
* await this.server.close();
|
|
190
|
-
* },
|
|
191
|
-
* });
|
|
192
|
-
* ```
|
|
193
|
-
*/
|
|
194
|
-
declare function defineApp<P extends ObjectPropsOptions, S extends Record<string, any>, M extends Record<string, AnyFunction>>(definition: AppDefinition<P, S, M>): AppDefinition<P, S, M>;
|
|
195
|
-
/**
|
|
196
|
-
* Create a new runtime instance from an app definition.
|
|
197
|
-
* @group App Lifecycle
|
|
198
|
-
* @example
|
|
199
|
-
* ```ts
|
|
200
|
-
* const instance = createAppInstance(myApp);
|
|
201
|
-
* await setupApp(instance, { port: 3000 });
|
|
202
|
-
* await runApp(instance);
|
|
203
|
-
* ```
|
|
204
|
-
*/
|
|
205
|
-
declare function createAppInstance<P extends ObjectPropsOptions, S extends Record<string, any>, M extends Record<string, AnyFunction>>(definition: AppDefinition<P, S, M>): AppInstance<P, S, M>;
|
|
206
|
-
/**
|
|
207
|
-
* Returns true if the value was created by `defineApp`.
|
|
208
|
-
* @group Utils
|
|
209
|
-
*/
|
|
210
|
-
declare function isAppDefinition(value: unknown): value is AppDefinition;
|
|
211
|
-
/**
|
|
212
|
-
* Run setup and entry in one call. Shuts down automatically if entry fails.
|
|
213
|
-
* @group App Lifecycle
|
|
214
|
-
* @example
|
|
215
|
-
* ```ts
|
|
216
|
-
* const result = await startApp(myApp, { port: 3000 });
|
|
217
|
-
* if (isSuccess(result)) {
|
|
218
|
-
* await appWaitShutdown(result.app);
|
|
219
|
-
* }
|
|
220
|
-
* ```
|
|
221
|
-
*/
|
|
222
|
-
declare function startApp<P extends ObjectPropsOptions, S extends Record<string, any>>(app: AppDefinition<P, S> | AppInstance<P, S>, props: ExtractPropTypes<P>): Promise<ExecResult<{
|
|
223
|
-
app: AppInstance<P, S>;
|
|
224
|
-
}>>;
|
|
225
|
-
/**
|
|
226
|
-
* Run the setup phase of an app instance.
|
|
227
|
-
* @group App Lifecycle
|
|
228
|
-
* @example
|
|
229
|
-
* ```ts
|
|
230
|
-
* const result = await setupApp(instance, { port: 3000 });
|
|
231
|
-
* if (isSuccess(result)) {
|
|
232
|
-
* await runApp(instance);
|
|
233
|
-
* }
|
|
234
|
-
* ```
|
|
235
|
-
*/
|
|
236
|
-
declare function setupApp(instance: AppInstance, props: Data): Promise<ExecResult>;
|
|
237
|
-
/**
|
|
238
|
-
* Run the entry phase of an app instance.
|
|
239
|
-
* @group App Lifecycle
|
|
240
|
-
* @example
|
|
241
|
-
* ```ts
|
|
242
|
-
* await setupApp(instance, props);
|
|
243
|
-
* await runApp(instance);
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
|
-
declare function runApp$1(instance: AppInstance): Promise<ExecResult>;
|
|
247
|
-
/**
|
|
248
|
-
* Stop a running app instance and call its `stop` hook.
|
|
249
|
-
* @group App Lifecycle
|
|
250
|
-
* @example
|
|
251
|
-
* ```ts
|
|
252
|
-
* process.on('SIGTERM', async () => {
|
|
253
|
-
* await stopApp(instance);
|
|
254
|
-
* await shutdownApp(instance);
|
|
255
|
-
* });
|
|
256
|
-
* ```
|
|
257
|
-
*/
|
|
258
|
-
declare function stopApp(instance: AppInstance): Promise<ExecResult>;
|
|
259
|
-
/**
|
|
260
|
-
* Shut down an app instance, call its `shutdown` hook, and reset all state.
|
|
261
|
-
* @group App Lifecycle
|
|
262
|
-
* @example
|
|
263
|
-
* ```ts
|
|
264
|
-
* await stopApp(instance);
|
|
265
|
-
* await shutdownApp(instance);
|
|
266
|
-
* // instance can be set up and started again after this
|
|
267
|
-
* ```
|
|
268
|
-
*/
|
|
269
|
-
declare function shutdownApp(instance: AppInstance): Promise<ExecResult>;
|
|
270
|
-
/**
|
|
271
|
-
* Returns a promise that resolves when the app emits its shutdown event.
|
|
272
|
-
* Resolves immediately if the app is not running.
|
|
273
|
-
* @group App Lifecycle
|
|
274
|
-
* @example
|
|
275
|
-
* ```ts
|
|
276
|
-
* await startApp(myApp, props);
|
|
277
|
-
* await appWaitShutdown(instance); // blocks until shutdown
|
|
278
|
-
* ```
|
|
279
|
-
*/
|
|
280
|
-
declare function appWaitShutdown(instance: AppInstance): Promise<void>;
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Combine multiple app definitions into a single orchestrated app.
|
|
284
|
-
* Props from each definition are namespaced by their app name.
|
|
285
|
-
* @group Utils
|
|
286
|
-
*/
|
|
287
|
-
declare function createAppHub(definitions: AppDefinition[]): AppDefinition;
|
|
288
|
-
declare function getPrefixedProps(definition: AppDefinition, props: Data): Data;
|
|
289
|
-
declare function prefixifyProps(definitions: AppDefinition[]): ObjectPropsOptions;
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Wrap an app definition to run across N child processes. Adds a
|
|
293
|
-
* `threads` prop and manages the full lifecycle of each child.
|
|
294
|
-
* @group Types
|
|
295
|
-
*/
|
|
296
|
-
declare function createAppThread(definition: AppDefinition): AppDefinition;
|
|
297
|
-
interface CreateAppThreadInstanceParams {
|
|
298
|
-
definition: AppDefinition;
|
|
299
|
-
parentPort: ParentPortLike;
|
|
300
|
-
threadId: number;
|
|
301
|
-
onShutdown?: () => void;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* A minimal port abstraction implemented by both IPC `MessagePort`
|
|
305
|
-
* and the `process`-based shim spawned by {@link initThread}.
|
|
306
|
-
* @group Types
|
|
307
|
-
*/
|
|
308
|
-
interface ParentPortLike {
|
|
309
|
-
on(event: 'message', cb: (msg: unknown) => void): unknown;
|
|
310
|
-
postMessage(msg: unknown, cb?: () => void): unknown;
|
|
311
|
-
close?(): unknown;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Create app instance with IPC fully managed lifecycle
|
|
315
|
-
* @group Threads
|
|
316
|
-
*/
|
|
317
|
-
declare function createAppThreadInstance({ definition, parentPort, threadId, onShutdown, }: CreateAppThreadInstanceParams): AppInstance;
|
|
318
|
-
|
|
319
|
-
interface RunAppOptions {
|
|
320
|
-
scriptFile?: string;
|
|
321
|
-
cliName?: string;
|
|
322
|
-
cliDescription?: string;
|
|
323
|
-
argv?: string[];
|
|
324
|
-
}
|
|
325
|
-
declare function runApp({ scriptFile, cliName, cliDescription, argv, }: RunAppOptions): Promise<void>;
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Programmatic access to the `vrun` CLI internals.
|
|
329
|
-
* @group Utils
|
|
330
|
-
*/
|
|
331
|
-
declare const cli: Readonly<{
|
|
332
|
-
readonly runApp: typeof runApp;
|
|
333
|
-
}>;
|
|
334
|
-
|
|
335
|
-
type LogEventFields = Record<string, any>;
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* @group Types
|
|
339
|
-
*/
|
|
340
|
-
declare namespace ManagedThread {
|
|
341
|
-
type State = AppInstance.State | 'ready';
|
|
342
|
-
interface LogEntry {
|
|
343
|
-
ts: number;
|
|
344
|
-
level: LogLevel;
|
|
345
|
-
text: string;
|
|
346
|
-
}
|
|
347
|
-
type EventMap = {
|
|
348
|
-
ready: [];
|
|
349
|
-
state: [newState: State, oldState: State];
|
|
350
|
-
log: [entry: LogEntry];
|
|
351
|
-
pid: [pid: number];
|
|
352
|
-
exit: [code: number | null, signal: NodeJS.Signals | null];
|
|
353
|
-
message: [message: ManagedThread.ThreadMessage];
|
|
354
|
-
error: [err: Error];
|
|
355
|
-
} & {
|
|
356
|
-
[K in ManagedThread.ThreadMessage as `msg:${K['type']}`]: [msg: K];
|
|
357
|
-
};
|
|
358
|
-
type ThreadMessage = ThreadMessage.AppState | ThreadMessage.Ping | ThreadMessage.Pong | ThreadMessage.Ready | ThreadMessage.Shutdown | ThreadMessage.ShutdownDone | ThreadMessage.Start | ThreadMessage.StartDone | ThreadMessage.Setup | ThreadMessage.SetupDone | ThreadMessage.Stop | ThreadMessage.StopDone;
|
|
359
|
-
type ThreadMessageMap = {
|
|
360
|
-
[K in ManagedThread.ThreadMessage as K['type']]: K;
|
|
361
|
-
};
|
|
362
|
-
type ThreadMessageDone<T extends string> = `${T}_done` extends keyof ThreadMessageMap ? `${T}_done` : never;
|
|
363
|
-
namespace ThreadMessage {
|
|
364
|
-
interface Base<T extends string> {
|
|
365
|
-
type: T;
|
|
366
|
-
vrun_app_thread_message: true;
|
|
367
|
-
}
|
|
368
|
-
type AppState = Base<'app-state'> & {
|
|
369
|
-
state: AppInstance.State;
|
|
370
|
-
};
|
|
371
|
-
type Start = Base<'start'>;
|
|
372
|
-
type StartDone = Base<'start_done'> & {
|
|
373
|
-
result: ExecResult;
|
|
374
|
-
};
|
|
375
|
-
type Setup = Base<'setup'> & {
|
|
376
|
-
props: Data;
|
|
377
|
-
};
|
|
378
|
-
type SetupDone = Base<'setup_done'> & {
|
|
379
|
-
result: ExecResult;
|
|
380
|
-
};
|
|
381
|
-
type Stop = Base<'stop'>;
|
|
382
|
-
type StopDone = Base<'stop_done'> & {
|
|
383
|
-
result: ExecResult;
|
|
384
|
-
};
|
|
385
|
-
type Shutdown = Base<'shutdown'>;
|
|
386
|
-
type ShutdownDone = Base<'shutdown_done'> & {
|
|
387
|
-
result: ExecResult;
|
|
388
|
-
};
|
|
389
|
-
type Ping = Base<'ping'>;
|
|
390
|
-
type Pong = Base<'pong'>;
|
|
391
|
-
type Ready = Base<'ready'> & {
|
|
392
|
-
pid: number;
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* A child process managed by the parent.
|
|
398
|
-
* @group Types
|
|
399
|
-
*/
|
|
400
|
-
interface ManagedThread {
|
|
401
|
-
child: cp.ChildProcess;
|
|
402
|
-
threadId: number;
|
|
403
|
-
pid: number;
|
|
404
|
-
state: ManagedThread.State;
|
|
405
|
-
restartCount: number;
|
|
406
|
-
scriptFile: string;
|
|
407
|
-
threadProps: Record<string, unknown>;
|
|
408
|
-
eventBus: EventEmitter<ManagedThread.EventMap>;
|
|
409
|
-
scheduler: Scheduler;
|
|
410
|
-
writeLog(level: LogLevel, event: string, fields?: LogEventFields): void;
|
|
411
|
-
/** @internal */ heartbeatTimer?: NodeJS.Timeout;
|
|
412
|
-
/** @internal */ lastPong: number;
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Wait for thread ready signal
|
|
416
|
-
* @group Threads
|
|
417
|
-
*/
|
|
418
|
-
declare function waitForThreadReady(w: ManagedThread): Promise<void>;
|
|
419
|
-
/**
|
|
420
|
-
* Spawn a child process for `scriptFile` and return its {@link ManagedThread}
|
|
421
|
-
* immediately — synchronously, before the child signals readiness.
|
|
422
|
-
* @group Threads
|
|
423
|
-
*/
|
|
424
|
-
declare function initThread(threadId: number, scriptFile: string, threadProps: Record<string, unknown>): ManagedThread;
|
|
425
|
-
/**
|
|
426
|
-
* Send the setup message; resolves when child replies setup_done.
|
|
427
|
-
* @group Threads
|
|
428
|
-
*/
|
|
429
|
-
declare function setupThreadApp(w: ManagedThread): Promise<void>;
|
|
430
|
-
/**
|
|
431
|
-
* Send the start message; on reply, switch to running and arm heartbeat.
|
|
432
|
-
* @group Threads
|
|
433
|
-
*/
|
|
434
|
-
declare function startThreadApp(w: ManagedThread): Promise<void>;
|
|
435
|
-
/**
|
|
436
|
-
* Send the stop message; child keeps running, app inside is stopped.
|
|
437
|
-
* @group Threads
|
|
438
|
-
*/
|
|
439
|
-
declare function stopThreadApp(w: ManagedThread): Promise<void>;
|
|
440
|
-
/**
|
|
441
|
-
* Send shutdown and wait for the OS process to exit (SIGKILL fallback).
|
|
442
|
-
* @group Threads
|
|
443
|
-
*/
|
|
444
|
-
declare function shutdownThreadApp(w: ManagedThread): Promise<void>;
|
|
445
|
-
/**
|
|
446
|
-
* Terminate the child and spawn a fresh one with the same script + props.
|
|
447
|
-
* @group Threads
|
|
448
|
-
*/
|
|
449
|
-
declare function restartThreadApp(w: ManagedThread): Promise<void>;
|
|
450
|
-
declare function isThreadMessage(value: unknown): value is ManagedThread.ThreadMessage;
|
|
451
|
-
declare function createThreadMessage<T extends keyof ManagedThread.ThreadMessageMap>(type: T, msg: Omit<ManagedThread.ThreadMessageMap[T], 'type' | 'vrun_app_thread_message'>): ManagedThread.ThreadMessageMap[T];
|
|
452
|
-
declare function isThreadExit(w: ManagedThread): boolean;
|
|
453
|
-
|
|
454
|
-
type WorkerSuccessData = {
|
|
455
|
-
[x: string]: unknown;
|
|
456
|
-
};
|
|
457
|
-
type WorkerSkipData = {
|
|
458
|
-
error?: boolean;
|
|
459
|
-
[x: string]: unknown;
|
|
460
|
-
};
|
|
461
|
-
type WorkerResult = ExecResult<WorkerSuccessData, WorkerSkipData>;
|
|
462
|
-
/**
|
|
463
|
-
* @group Types
|
|
464
|
-
*/
|
|
465
|
-
declare namespace WorkerStrategy {
|
|
466
|
-
/**
|
|
467
|
-
* Base context bag emitted by strategies per task. Strategies extend this with typed fields.
|
|
468
|
-
* @group Types
|
|
469
|
-
*/
|
|
470
|
-
interface Context {
|
|
471
|
-
[key: string]: unknown;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Pluggable trigger source. Drives when tasks are enqueued.
|
|
476
|
-
* @group Types
|
|
477
|
-
*/
|
|
478
|
-
interface WorkerStrategy<C extends WorkerStrategy.Context = WorkerStrategy.Context> {
|
|
479
|
-
doSetup(opts: {
|
|
480
|
-
worker: WorkerInstance;
|
|
481
|
-
}): Awaitable<void>;
|
|
482
|
-
startSignal(): void;
|
|
483
|
-
stopSignal(done: () => void): void;
|
|
484
|
-
doShutdown(): Awaitable<void>;
|
|
485
|
-
createTask(...args: any[]): C;
|
|
486
|
-
executeSignal?(ctx: WorkerDefinition.EntryContext<WorkerStrategy<C>>): Awaitable<ExecResult>;
|
|
487
|
-
completeSignal?(ctx: WorkerDefinition.EntryContext<WorkerStrategy<C>>, result: WorkerResult | WorkerResult[]): Awaitable<void>;
|
|
488
|
-
overloadedSignal?(): void;
|
|
489
|
-
availableSignal?(): void;
|
|
490
|
-
handleEntryError?(err: Error): WorkerResult;
|
|
491
|
-
}
|
|
492
|
-
declare namespace WorkerDefinition {
|
|
493
|
-
/**
|
|
494
|
-
* Entry function that will be called each time when worker handle a job
|
|
495
|
-
*/
|
|
496
|
-
type EntryFn<Context extends Data, Props extends Data> = (this: Context, props: Props) => Awaitable<WorkerResult | WorkerResult[] | void>;
|
|
497
|
-
type SetupFn<Context extends Data, Props extends Data, Result> = (this: Context, props: Props) => Awaitable<Result>;
|
|
498
|
-
type EntryContext<T extends WorkerStrategy = WorkerStrategy> = AppDefinition.EntryContext<{
|
|
499
|
-
worker: WorkerInstance<T>;
|
|
500
|
-
} & TaskContext<T>>;
|
|
501
|
-
type SetupContext<T extends Data = Data> = AppDefinition.SetupContext<T & {
|
|
502
|
-
worker: WorkerInstance;
|
|
503
|
-
}>;
|
|
504
|
-
type RuntimeContext<T extends Data = Data> = AppDefinition.RuntimeContext<T & {
|
|
505
|
-
worker: WorkerInstance;
|
|
506
|
-
}>;
|
|
507
|
-
type TaskContext<T extends WorkerStrategy> = T extends WorkerStrategy<infer X> ? X : never;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Worker definition — extends AppDefinition with strategy, per-task entry, and concurrency config.
|
|
511
|
-
* @group Types
|
|
512
|
-
*/
|
|
513
|
-
interface WorkerDefinition<P extends ObjectPropsOptions = {}, S extends Record<string, any> = {}, M extends Record<string, AnyFunction> = {}, C extends WorkerStrategy = WorkerStrategy, RuntimeContext extends WorkerDefinition.RuntimeContext = WorkerDefinition.RuntimeContext<S & M>, EntryContext extends WorkerDefinition.EntryContext = WorkerDefinition.EntryContext<C> & S & M, SetupContext extends WorkerDefinition.SetupContext = WorkerDefinition.SetupContext<M>> extends AppDefinition<P, S, M, RuntimeContext, EntryContext, SetupContext> {
|
|
514
|
-
/**
|
|
515
|
-
* Entry function that will be called each time when worker handle a job
|
|
516
|
-
*/
|
|
517
|
-
entry?(this: EntryContext, props: ExtractPropTypes<P>): Awaitable<WorkerResult | WorkerResult[] | void>;
|
|
518
|
-
/**
|
|
519
|
-
* Setup function will be called once while worker setup.
|
|
520
|
-
*/
|
|
521
|
-
setup?(this: SetupContext, props: ExtractPropTypes<P>): Awaitable<S>;
|
|
522
|
-
executeStrategy: C;
|
|
523
|
-
/**
|
|
524
|
-
* Maximum limit of queued tasks
|
|
525
|
-
* @default 50
|
|
526
|
-
*/
|
|
527
|
-
taskLimit?: number;
|
|
528
|
-
/**
|
|
529
|
-
* Amount of task to be executed in parallel
|
|
530
|
-
* @default 2
|
|
531
|
-
*/
|
|
532
|
-
taskParallel?: number;
|
|
533
|
-
/**
|
|
534
|
-
* Disable worker
|
|
535
|
-
* @default false
|
|
536
|
-
*/
|
|
537
|
-
disabled?: boolean;
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Runtime state of a worker instance. Extends AppInstance with task queue and pool.
|
|
541
|
-
* Managed with the standard startApp / stopApp / shutdownApp lifecycle.
|
|
542
|
-
* @group Types
|
|
543
|
-
*/
|
|
544
|
-
interface WorkerInstance<C extends WorkerStrategy = WorkerStrategy> {
|
|
545
|
-
definition: WorkerDefinition<{}, {}, {}, C>;
|
|
546
|
-
queue: AsyncIterableQueue<WorkerDefinition.TaskContext<C>>;
|
|
547
|
-
pool: ResourcePool<symbol>;
|
|
548
|
-
runTask: CancellablePromise<void> | null;
|
|
549
|
-
overloadedSignaled: boolean;
|
|
550
|
-
log: Logger;
|
|
551
|
-
readonly queueMaxSize: number;
|
|
552
|
-
readonly taskParallel: number;
|
|
553
|
-
/**
|
|
554
|
-
* Tasks queue size
|
|
555
|
-
*/
|
|
556
|
-
readonly queueSize: number;
|
|
557
|
-
/**
|
|
558
|
-
* Check if the worker is overloaded (e.g., queue length is high)
|
|
559
|
-
*/
|
|
560
|
-
readonly isOverloaded: boolean;
|
|
561
|
-
/**
|
|
562
|
-
* Returns true when worker do nothing
|
|
563
|
-
*/
|
|
564
|
-
readonly isIdle: boolean;
|
|
565
|
-
/**
|
|
566
|
-
* Add task into execution queue
|
|
567
|
-
*/
|
|
568
|
-
addTask(ctx: WorkerDefinition.TaskContext<C>): void;
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Create a runtime WorkerInstance from a WorkerDefinition.
|
|
572
|
-
* Use with startApp / stopApp / shutdownApp.
|
|
573
|
-
* @group Worker
|
|
574
|
-
*/
|
|
575
|
-
declare function createWorkerInstance<C extends WorkerStrategy>(definition: WorkerDefinition<{}, {}, {}, C>, logger: Logger): WorkerInstance<C>;
|
|
576
|
-
/**
|
|
577
|
-
* Enqueue a task context on the worker. Fires backpressure signals at 80% capacity.
|
|
578
|
-
* @group Worker
|
|
579
|
-
*/
|
|
580
|
-
declare function addWorkerTask<C extends WorkerStrategy>(instance: WorkerInstance<C>, ctx: WorkerDefinition.TaskContext<C>): void;
|
|
581
|
-
/**
|
|
582
|
-
* Define a background worker with a pluggable execution strategy.
|
|
583
|
-
* Returns a WorkerDefinition that can be run with createWorkerInstance + startApp.
|
|
584
|
-
*
|
|
585
|
-
* @example
|
|
586
|
-
* ```ts
|
|
587
|
-
* import { defineWorker, IntervalStrategy } from '@andrew_l/app';
|
|
588
|
-
*
|
|
589
|
-
* export default defineWorker({
|
|
590
|
-
* name: 'clock',
|
|
591
|
-
* executeStrategy: new IntervalStrategy({
|
|
592
|
-
* intervalSeconds: 1,
|
|
593
|
-
* }),
|
|
594
|
-
* entry() {
|
|
595
|
-
* this.log.info('tick=%d', this.timerSequence);
|
|
596
|
-
* },
|
|
597
|
-
* async shutdown() {
|
|
598
|
-
* await delay(1000);
|
|
599
|
-
* },
|
|
600
|
-
* });
|
|
601
|
-
* ```
|
|
602
|
-
*
|
|
603
|
-
* @group Main
|
|
604
|
-
*/
|
|
605
|
-
declare function defineWorker<P extends ObjectPropsOptions, S extends Record<string, any>, M extends Record<string, AnyFunction>, C extends WorkerStrategy = WorkerStrategy>(definition: WorkerDefinition<P, S, M, C>): WorkerDefinition<P, S, M, C>;
|
|
606
|
-
/**
|
|
607
|
-
* Returns true if the value was created by defineWorker.
|
|
608
|
-
* @group Utils
|
|
609
|
-
*/
|
|
610
|
-
declare function isWorkerDefinition(value: unknown): value is WorkerDefinition;
|
|
611
|
-
/**
|
|
612
|
-
* Returns true if the value is a WorkerInstance.
|
|
613
|
-
* @group Utils
|
|
614
|
-
*/
|
|
615
|
-
declare function isWorkerInstance(value: unknown): value is WorkerInstance;
|
|
616
|
-
|
|
617
|
-
declare namespace IntervalStrategy {
|
|
618
|
-
/**
|
|
619
|
-
* Options for the built-in IntervalStrategy.
|
|
620
|
-
*/
|
|
621
|
-
interface Options {
|
|
622
|
-
intervalSeconds: number;
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Context emitted by IntervalStrategy on each tick.
|
|
626
|
-
*/
|
|
627
|
-
interface Context extends WorkerStrategy.Context {
|
|
628
|
-
timerSequence: number;
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Triggers a worker task on a fixed interval.
|
|
633
|
-
* Skips the tick with a warning if the worker is not idle.
|
|
634
|
-
* @group Worker Strategies
|
|
635
|
-
*/
|
|
636
|
-
declare class IntervalStrategy implements WorkerStrategy<IntervalStrategy.Context> {
|
|
637
|
-
private readonly options;
|
|
638
|
-
private timerSequence;
|
|
639
|
-
private timer;
|
|
640
|
-
private worker;
|
|
641
|
-
constructor(options: IntervalStrategy.Options);
|
|
642
|
-
doSetup({ worker }: {
|
|
643
|
-
worker: WorkerInstance;
|
|
644
|
-
}): void;
|
|
645
|
-
startSignal(): void;
|
|
646
|
-
stopSignal(done: () => void): void;
|
|
647
|
-
doShutdown(): void;
|
|
648
|
-
createTask(): IntervalStrategy.Context;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
export { APP_INSTANCE_STATE, AppDefinition, AppInstance, type CreateAppThreadInstanceParams, type ExtractPropTypes, IntervalStrategy, ManagedThread, type ObjectPropsOptions, type ParentPortLike, type PropOptions, WorkerDefinition, type WorkerInstance, type WorkerResult, type WorkerSkipData, WorkerStrategy, type WorkerSuccessData, addWorkerTask, appWaitShutdown, cli, createAppHub, createAppInstance, createAppThread, createAppThreadInstance, createThreadMessage, createWorkerInstance, defineApp, defineWorker, getPrefixedProps, initThread, isAppDefinition, isThreadExit, isThreadMessage, isWorkerDefinition, isWorkerInstance, prefixifyProps, restartThreadApp, runApp$1 as runApp, setupApp, setupThreadApp, shutdownApp, shutdownThreadApp, startApp, startThreadApp, stopApp, stopThreadApp, waitForThreadReady };
|
package/dist/vrun.cjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const toolkit = require('@andrew_l/toolkit');
|
|
4
|
-
|
|
5
|
-
const timer = setTimeout(toolkit.noop, 1 << 30);
|
|
6
|
-
import('./index.cjs').then(
|
|
7
|
-
(r) => r.cli.runApp({
|
|
8
|
-
cliName: "vrun",
|
|
9
|
-
cliDescription: "Launch any application.",
|
|
10
|
-
argv: process.argv.slice(2)
|
|
11
|
-
})
|
|
12
|
-
).finally(() => clearInterval(timer));
|
|
13
|
-
//# sourceMappingURL=vrun.cjs.map
|
package/dist/vrun.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vrun.cjs","sources":["../src/vrun.ts"],"sourcesContent":["import { noop } from '@andrew_l/toolkit';\n\nconst timer = setTimeout(noop, 1 << 30);\n\nimport('./index.js')\n .then(r =>\n r.cli.runApp({\n cliName: 'vrun',\n cliDescription: 'Launch any application.',\n argv: process.argv.slice(2),\n }),\n )\n .finally(() => clearInterval(timer));\n"],"names":["noop"],"mappings":";;;;AAEA,MAAM,KAAA,GAAQ,UAAA,CAAWA,YAAA,EAAM,CAAA,IAAK,EAAE,CAAA;AAEtC,OAAO,aAAY,CAAA,CAChB,IAAA;AAAA,EAAK,CAAA,CAAA,KACJ,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO;AAAA,IACX,OAAA,EAAS,MAAA;AAAA,IACT,cAAA,EAAgB,yBAAA;AAAA,IAChB,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC;AAAA,GAC3B;AACH,CAAA,CACC,OAAA,CAAQ,MAAM,aAAA,CAAc,KAAK,CAAC,CAAA;;"}
|
package/dist/vrun.d.cts
DELETED
package/dist/vrun.d.ts
DELETED