@mark1russell7/service 0.4.0 → 0.5.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.
@@ -1,5 +1,136 @@
1
1
  import { n as Clock } from "./clock-D-38uH_z.js";
2
2
  import { Extent, Quantity } from "@mark1russell7/quantity";
3
+ //#region src/operation.d.ts
4
+ /**
5
+ * This type tells if an operation can go again after a failure. It is a property of the
6
+ * operation, not of the dependency. One Redis client sends a GET, which is safe to send again. It
7
+ * also sends an INCR, which counts two times when it goes again after a timeout. Each operation
8
+ * declares its idempotency:
9
+ * - `true`: a second issue has the same effect. Examples are an HTTP GET or PUT, a SELECT, a
10
+ * Redis GET or SET, and a write that the server removes when it is a copy.
11
+ * - `false`: the client does not send it again after it can have reached the server.
12
+ * - keyed: the server keeps a key for a window, as with an `Idempotency-Key` header, and it
13
+ * ignores a copy in that window. A copy after the window is a second operation. Thus the
14
+ * window is a timer, and it must be longer than all retries of the operation.
15
+ */
16
+ type Idempotency = boolean | {
17
+ readonly key: string;
18
+ readonly window: Extent;
19
+ };
20
+ /** An operation is an endpoint that the service calls or serves, a command, or a query. */
21
+ interface Operation {
22
+ readonly idempotent: Idempotency;
23
+ }
24
+ /**
25
+ * This function tells if an operation can go again `since` its first issue. An idempotent
26
+ * operation can always go again, and other operations cannot. A keyed operation can go again
27
+ * while the server keeps its key.
28
+ */
29
+ declare const mayReissue: (operation: Operation, since: Quantity) => boolean;
30
+ //#endregion
31
+ //#region src/process.d.ts
32
+ /** An exit signal is a signal that asks the process to stop: each one starts the shutdown. */
33
+ type ExitSignal = "SIGINT" | "SIGTERM" | "SIGQUIT";
34
+ /** These are the signals that the runtime handles. */
35
+ declare const EXIT_SIGNALS: readonly ExitSignal[];
36
+ /**
37
+ * A process trigger is an event of the process, other than a signal, that starts the shutdown. A
38
+ * declaration opts in to each one (`svc.trigger`):
39
+ * - `stdin-close`: the standard input ends or closes, as when the parent of a stdio child goes away.
40
+ * The process must read its input, as a stdio transport does, or Node does not see the end.
41
+ * - `ipc-close`: the IPC channel to the parent process closes.
42
+ */
43
+ type ProcessTrigger = "stdin-close" | "ipc-close";
44
+ /** These are the process triggers that a declaration can opt in to. */
45
+ declare const PROCESS_TRIGGERS: readonly ProcessTrigger[];
46
+ /** An exit trigger is an event that starts the shutdown: an exit signal, or a declared process trigger. */
47
+ type ExitTrigger = ExitSignal | ProcessTrigger;
48
+ /** This function tells if a number is an exit code of a process: a whole number from 0 to 255. */
49
+ declare const isExitCode: (code: number) => boolean;
50
+ /** This function tells if a trigger is an exit signal. A repeat signal obeys `onRepeatSignal`. */
51
+ declare const isExitSignal: (trigger: string) => trigger is ExitSignal;
52
+ /**
53
+ * A process port is the part of the process that the runtime uses: its exit triggers, its output
54
+ * and its exit. The runtime owns the handlers, because Node as PID 1 without a handler ignores
55
+ * SIGTERM. Only the runtime ends the process, and library code does not. A test gives a fake port,
56
+ * sends triggers, and reads the exit code.
57
+ */
58
+ interface ProcessPort {
59
+ /**
60
+ * This method adds a handler for a trigger, and gives the function that removes it. The runtime
61
+ * asks for a process trigger only when the declaration opts in to it.
62
+ */
63
+ on(trigger: ExitTrigger, handler: () => void): () => void;
64
+ /**
65
+ * This method writes each buffered line of the output, and its promise ends when the output is
66
+ * written. The stage `flush the output` uses it, in the cap of that stage.
67
+ */
68
+ flush?(): Promise<void> | void;
69
+ /** This method ends the process with a code: the code of the exit request, 1 after an error, or 0. */
70
+ exit(code: number): void;
71
+ }
72
+ /** A host stream is the part of a stream of Node that the port uses. */
73
+ interface HostStream {
74
+ readonly writable?: boolean;
75
+ readonly destroyed?: boolean;
76
+ readonly readableEnded?: boolean;
77
+ write(chunk: string, done: (error?: unknown) => void): boolean;
78
+ on(event: string, handler: () => void): unknown;
79
+ off(event: string, handler: () => void): unknown;
80
+ }
81
+ /** A process host is the part of the process of Node that the port uses. */
82
+ interface ProcessHost {
83
+ on(signal: string, handler: () => void): unknown;
84
+ off(signal: string, handler: () => void): unknown;
85
+ exit(code: number): unknown;
86
+ readonly stdin?: HostStream | undefined;
87
+ readonly stdout?: HostStream | undefined;
88
+ readonly stderr?: HostStream | undefined;
89
+ }
90
+ /**
91
+ * This function makes a process port on a host. `find` gives the host at each use, or undefined
92
+ * when the platform has no process. Then the use throws.
93
+ */
94
+ declare const processPortOf: (find: () => ProcessHost | undefined) => ProcessPort;
95
+ /** This port is the process of Node. */
96
+ declare const nodeProcess: ProcessPort;
97
+ //#endregion
98
+ //#region src/routes.d.ts
99
+ /**
100
+ * A route pattern matches the routes of a controller that its exact routes do not name. A
101
+ * registry that changes while the service operates, for example a registry of procedures, thus
102
+ * needs no list of routes before the start. The syntax of a pattern:
103
+ * - `*` matches each text, also an empty text and a text with `/`. The pattern `*` alone matches
104
+ * each route.
105
+ * - `:name` matches a text of one character or more without `/`, and gives it in `params.name`.
106
+ * - Each other character matches itself.
107
+ *
108
+ * The declaration names the operations that a request of the pattern can be. Each operation
109
+ * declares its idempotency, as a route does. A function picks the operation of each request.
110
+ */
111
+ interface RoutePattern {
112
+ readonly pattern: string;
113
+ /** These are the operations that a request of the pattern can be, by name. */
114
+ readonly operations: Readonly<Record<string, Operation>>;
115
+ }
116
+ /** A route request is what the function of a pattern gets for one request. */
117
+ interface RouteRequest {
118
+ readonly controller: string;
119
+ readonly route: string;
120
+ /** These are the texts of the `:name` parts of the pattern, by name. */
121
+ readonly params: Readonly<Record<string, string>>;
122
+ /** These are the texts of the `*` parts of the pattern, in their sequence. */
123
+ readonly wildcards: readonly string[];
124
+ /** This value is the detail that the transport gives with the request, or undefined. */
125
+ readonly detail: unknown;
126
+ }
127
+ /**
128
+ * An operation choice gives the name of the operation of one request: one of the operations that
129
+ * the pattern declares. Thus the function decides the idempotency of each request, and the
130
+ * declaration keeps each window of a keyed operation as data.
131
+ */
132
+ type OperationOf = (request: RouteRequest) => string;
133
+ //#endregion
3
134
  //#region src/timing.d.ts
4
135
  /**
5
136
  * All policies have the same timing shape. A timing is a count of polls (a debounce) or a
@@ -64,34 +195,6 @@ declare const asDebounce: (timing: Timing, poll: Poll) => Timing;
64
195
  */
65
196
  declare const heartbeatDetection: (interval: Extent, timeout: Quantity, misses: number) => Extent;
66
197
  //#endregion
67
- //#region src/operation.d.ts
68
- /**
69
- * This type tells if an operation can go again after a failure. It is a property of the
70
- * operation, not of the dependency. One Redis client sends a GET, which is safe to send again. It
71
- * also sends an INCR, which counts two times when it goes again after a timeout. Each operation
72
- * declares its idempotency:
73
- * - `true`: a second issue has the same effect. Examples are an HTTP GET or PUT, a SELECT, a
74
- * Redis GET or SET, and a write that the server removes when it is a copy.
75
- * - `false`: the client does not send it again after it can have reached the server.
76
- * - keyed: the server keeps a key for a window, as with an `Idempotency-Key` header, and it
77
- * ignores a copy in that window. A copy after the window is a second operation. Thus the
78
- * window is a timer, and it must be longer than all retries of the operation.
79
- */
80
- type Idempotency = boolean | {
81
- readonly key: string;
82
- readonly window: Extent;
83
- };
84
- /** An operation is an endpoint that the service calls or serves, a command, or a query. */
85
- interface Operation {
86
- readonly idempotent: Idempotency;
87
- }
88
- /**
89
- * This function tells if an operation can go again `since` its first issue. An idempotent
90
- * operation can always go again, and other operations cannot. A keyed operation can go again
91
- * while the server keeps its key.
92
- */
93
- declare const mayReissue: (operation: Operation, since: Quantity) => boolean;
94
- //#endregion
95
198
  //#region src/description.d.ts
96
199
  /**
97
200
  * This is the format of a service as data: what `describe()` exports, and nothing starts. The
@@ -152,6 +255,12 @@ interface Controller {
152
255
  readonly name: string;
153
256
  readonly requires: readonly string[];
154
257
  readonly routes: Readonly<Record<string, Operation>>;
258
+ /**
259
+ * These patterns match the routes that `routes` does not name, in their sequence: the first
260
+ * pattern that matches a route gives its operations. Without a declaration, the controller has
261
+ * no patterns.
262
+ */
263
+ readonly patterns?: readonly RoutePattern[] | undefined;
155
264
  }
156
265
  /** A coupling is a declared edge between two policies. The algebra checks its margin. */
157
266
  interface Coupling {
@@ -164,6 +273,20 @@ interface Phase {
164
273
  readonly name: string;
165
274
  readonly cap: Quantity;
166
275
  }
276
+ /**
277
+ * A repeat signal policy tells what an exit signal does while the shutdown runs:
278
+ * - `ignore`: the signal has no effect, and the shutdown continues.
279
+ * - `exit`: the process exits with the code 1 at once, as a second Ctrl-C does in a terminal.
280
+ */
281
+ type RepeatSignal = "ignore" | "exit";
282
+ /**
283
+ * A cooperative floor is the earliest time of the cooperative abort in the drain:
284
+ * - `half`: half the cap of the drain. The work in flight gets half the drain at the least.
285
+ * - `none`: no floor. A window of the whole cap or more aborts the work at the start of the drain.
286
+ */
287
+ type CooperativeFloor = "half" | "none";
288
+ /** These exit codes replace the code 0 of a clean shutdown, by the trigger of the shutdown. */
289
+ type ExitCodes = Readonly<Partial<Record<ExitTrigger, number>>>;
167
290
  /** A service description is the whole graph of a service, as data. */
168
291
  interface ServiceDescription {
169
292
  readonly format: typeof FORMAT;
@@ -185,6 +308,14 @@ interface ServiceDescription {
185
308
  readonly phases: readonly Phase[];
186
309
  /** This window is how long before the end of the drain the cooperative abort occurs, or no bound. */
187
310
  readonly cooperativeWindow: Extent;
311
+ /** This floor is the earliest time of the cooperative abort. Without a declaration, the floor is `half`. */
312
+ readonly cooperativeFloor?: CooperativeFloor | undefined;
313
+ /** This policy tells what a signal does while the shutdown runs. Each declaration gives it, because the runtime has no defaults. */
314
+ readonly onRepeatSignal: RepeatSignal;
315
+ /** These triggers start the shutdown, in addition to the exit signals. Each one is opt-in. */
316
+ readonly triggers?: readonly ProcessTrigger[] | undefined;
317
+ /** These codes replace the exit code 0 by the trigger. Without a code, a clean shutdown exits 0. */
318
+ readonly exitCodes?: ExitCodes | undefined;
188
319
  };
189
320
  }
190
321
  //#endregion
@@ -330,57 +461,70 @@ interface Health {
330
461
  stop(): void;
331
462
  }
332
463
  //#endregion
333
- //#region src/process.d.ts
334
- /** An exit signal is a signal that asks the process to stop: each one starts the shutdown. */
335
- type ExitSignal = "SIGINT" | "SIGTERM" | "SIGQUIT";
336
- /** These are the signals that the runtime handles. */
337
- declare const EXIT_SIGNALS: readonly ExitSignal[];
338
- /**
339
- * A process port is the part of the process that the runtime uses: its exit signals and its exit.
340
- * The runtime owns the handlers, because Node as PID 1 without a handler ignores SIGTERM. Only the
341
- * runtime ends the process, and library code does not. A test gives a fake port, sends signals,
342
- * and reads the exit code.
343
- */
344
- interface ProcessPort {
345
- /** This method adds a handler for a signal, and gives the function that removes it. */
346
- on(signal: ExitSignal, handler: () => void): () => void;
347
- /** This method ends the process with a code: 0 after a clean shutdown, and 1 after an error. */
348
- exit(code: number): void;
349
- }
350
- /** This port is the process of Node. */
351
- declare const nodeProcess: ProcessPort;
352
- //#endregion
353
464
  //#region src/requests.d.ts
354
465
  /**
355
- * A request outcome is what a request of a controller came to, for any HTTP framework or none:
356
- * - `done`: the work gave a value.
357
- * - `failed`: the work failed for a cause of its own. The adapter answers it as it answers any
358
- * error of the route.
466
+ * A request end is the one final result of the stream of a request. Its count `delivered` is the
467
+ * number of items that the stream gave before it. An end after the first item is in-band. The
468
+ * transport sent its answer, thus it writes the end as the last line of the stream, not as a status.
469
+ * - `done`: the work gave each of its items.
470
+ * - `failed`: the work failed for a cause of its own. Before the first item, the adapter answers it
471
+ * as it answers any error of the route.
359
472
  * - `refused`: the service did not admit the request. A refused request did not start, thus its
360
473
  * caller can send it again: 503, retryable.
361
- * - `cut`: the shutdown stopped the request. A route whose callers can send it again answers 503,
362
- * retryable. Each other route answers 500, not retryable, because the work can have had its
363
- * effect.
474
+ * - `cut`: the shutdown stopped the request. Before the first item, a route whose callers can send
475
+ * it again answers 503, retryable, and each other route answers 500. After the first item, the
476
+ * status is null, and the end is in-band.
364
477
  */
365
- type RequestOutcome<T> = {
478
+ type RequestEnd = {
366
479
  readonly kind: "done";
367
- readonly value: T;
480
+ readonly delivered: number;
368
481
  } | {
369
482
  readonly kind: "failed";
370
483
  readonly error: unknown;
484
+ readonly delivered: number;
371
485
  } | {
372
486
  readonly kind: "refused";
373
487
  readonly status: 503;
374
488
  readonly retryable: true;
375
489
  readonly cause: string;
490
+ readonly delivered: 0;
376
491
  } | {
377
492
  readonly kind: "cut";
378
- readonly status: 503 | 500;
493
+ readonly status: 503 | 500 | null;
379
494
  readonly retryable: boolean;
380
495
  readonly cause: string;
496
+ readonly delivered: number;
381
497
  };
498
+ /** A request event is one event of the stream of a request: an item, or the one end, which comes last. */
499
+ type RequestEvent<T> = {
500
+ readonly kind: "item";
501
+ readonly value: T;
502
+ } | RequestEnd;
503
+ /**
504
+ * A request stream is what a request comes to: its items, then one end. A unary work gives a stream
505
+ * of one item. The stream gives an item only when its reader asks for the next event. Thus a slow
506
+ * reader slows the work, and the request stays in flight until the work ends. When the reader
507
+ * stops before the end, the work gets its abort and the `return()` of its iterator.
508
+ */
509
+ interface RequestStream<T> extends AsyncIterable<RequestEvent<T>> {
510
+ /** This method reads the whole stream, and gives its items and its end. */
511
+ collect(): Promise<{
512
+ readonly items: readonly T[];
513
+ readonly end: RequestEnd;
514
+ }>;
515
+ }
516
+ /**
517
+ * A request work is what a request function gives: one value, or a stream of values. A work that
518
+ * gives an async iterable is a stream, also through a promise. Each other value is a stream of one.
519
+ */
520
+ type RequestWork<T> = T | PromiseLike<T> | AsyncIterable<T> | PromiseLike<AsyncIterable<T>>;
382
521
  /** A request function does the work of one request. It receives a signal that the shutdown aborts. */
383
- type RequestFn<T> = (signal: AbortSignal) => Promise<T> | T;
522
+ type RequestFn<T> = (signal: AbortSignal) => RequestWork<T>;
523
+ /** These options go with one request. */
524
+ interface RequestOptions {
525
+ /** This value goes to the function of a route pattern, for example the metadata of a procedure. */
526
+ readonly detail?: unknown;
527
+ }
384
528
  //#endregion
385
529
  //#region src/lifecycle.d.ts
386
530
  /**
@@ -389,7 +533,13 @@ type RequestFn<T> = (signal: AbortSignal) => Promise<T> | T;
389
533
  * and it closes. A second close has no effect.
390
534
  */
391
535
  interface TransportImpl {
392
- start(signal: AbortSignal): Promise<void> | void;
536
+ /**
537
+ * This method starts the transport. The lifecycle is the object that `run()` gives at the end of
538
+ * the startup. Its request tracking operates from the start: a request before the startup ends
539
+ * gets a retryable refusal, and `keepAlive()` is false. Do not wait for `life.started` here,
540
+ * because the startup waits for this method.
541
+ */
542
+ start(signal: AbortSignal, life: Lifecycle): Promise<void> | void;
393
543
  stopIntake(): Promise<void> | void;
394
544
  /**
395
545
  * This method lets the work in flight end until `deadline` (milliseconds on the monotonic
@@ -434,22 +584,32 @@ type PhaseWork = (context: PhaseContext) => Promise<void> | void;
434
584
  * - `close transports`: each transport closes.
435
585
  * - `stop the poller`: each check and watchdog stops. Then the signal of the service aborts.
436
586
  * - `tear down dependencies`: each dependency closes, in the reverse sequence of its connection.
437
- * - `close the health server`: the probes stop last.
587
+ * - `close the health server`: the probes stop.
588
+ * - `flush the output`: the work of the owners of this phase ends, and then the process port
589
+ * writes the buffered output. Without this phase, the process exits without a wait.
438
590
  */
439
- declare const STAGES: readonly ["fail readiness", "stop intake", "drain", "close transports", "stop the poller", "tear down dependencies", "close the health server"];
591
+ declare const STAGES: readonly ["fail readiness", "stop intake", "drain", "close transports", "stop the poller", "tear down dependencies", "close the health server", "flush the output"];
440
592
  type Stage = (typeof STAGES)[number];
441
593
  /** This function gives the place of a stage in the sequence, or -1 for a phase of another name. */
442
594
  declare const stageRank: (name: string) => number;
443
595
  /**
444
596
  * This function gives the time of the cooperative abort, in milliseconds after the drain starts. It
445
- * is the cap less the cooperative window, and not less than half the cap. A window without a bound
446
- * gives half the cap.
597
+ * is the cap less the cooperative window. With the floor `half`, it is not less than half the cap,
598
+ * and a window without a bound gives half the cap. With the floor `none`, it is not less than 0.
447
599
  */
448
- declare const cooperativeAbortAt: (cap: number, window: Extent) => number;
600
+ declare const cooperativeAbortAt: (cap: number, window: Extent, floor?: CooperativeFloor) => number;
449
601
  /** These options run the lifecycle. Without them, it uses the real clock and the process of Node. */
450
602
  interface RunOptions extends StartOptions {
451
603
  readonly process?: ProcessPort | undefined;
452
604
  }
605
+ /** These options go with a request for the shutdown. */
606
+ interface ShutdownOptions {
607
+ /**
608
+ * This code is the exit code that the work of the process gives, a whole number from 0 to 255. The
609
+ * first exit request with a code sets it. A code of 0 lets an error make the exit code 1.
610
+ */
611
+ readonly code?: number | undefined;
612
+ }
453
613
  /** A lifecycle state tells where the service is in its life. */
454
614
  type LifecycleState = "starting" | "running" | "draining" | "exited";
455
615
  /** The lifecycle of a running service. */
@@ -458,7 +618,7 @@ interface Lifecycle {
458
618
  readonly state: LifecycleState;
459
619
  /** This code is the exit code, or null before the exit. */
460
620
  readonly exitCode: number | null;
461
- /** These texts are the errors that make the exit code 1. */
621
+ /** These texts are the errors of the lifecycle. An error makes the exit code 1, unless an exit request gives another code. */
462
622
  readonly errors: readonly string[];
463
623
  /** This promise ends when the startup ends: the service runs, or its startup failed. */
464
624
  readonly started: Promise<void>;
@@ -466,13 +626,18 @@ interface Lifecycle {
466
626
  readonly done: Promise<number>;
467
627
  /** This signal aborts after the poller stops: the background work of the service stops with it. */
468
628
  readonly signal: AbortSignal;
469
- /** This method asks for the shutdown, as an exit signal does. A second request has no effect. */
470
- shutdown(cause?: string): Promise<number>;
471
629
  /**
472
- * This method does one request of a controller, on a route that the controller declares. The
473
- * service refuses it while it cannot take new work, and the shutdown can cut it.
630
+ * This method asks for the shutdown, as an exit signal does. A second request does not start a
631
+ * second shutdown. It can give the exit code, when no request gave one before.
474
632
  */
475
- request<T>(controller: string, route: string, work: RequestFn<T>): Promise<RequestOutcome<T>>;
633
+ shutdown(cause?: string, options?: ShutdownOptions): Promise<number>;
634
+ /**
635
+ * This method does one request of a controller, on a route or a route pattern that the controller
636
+ * declares. It gives the stream of the request: each item of the work, then one end. The service
637
+ * refuses the request while it cannot take new work, and the shutdown can cut it. An undeclared
638
+ * route throws, because it has no idempotency.
639
+ */
640
+ request<T>(controller: string, route: string, work: RequestFn<T>, options?: RequestOptions): RequestStream<T>;
476
641
  inFlight(controller?: string): number;
477
642
  /**
478
643
  * This method tells if a response can keep its connection open. It is false while the service is
@@ -481,113 +646,5 @@ interface Lifecycle {
481
646
  keepAlive(): boolean;
482
647
  }
483
648
  //#endregion
484
- //#region src/watchdog.d.ts
485
- /**
486
- * A watchdog spec declares a watchdog of the event loop. The service declares it as a check whose
487
- * function the watchdog gives: the process's own wedge, which a liveness window reads.
488
- */
489
- interface WatchdogSpec {
490
- readonly name: string;
491
- /** This time is the interval of the tick of the watchdog. */
492
- readonly tick: Quantity;
493
- /** This time is the most that a tick can be late before the loop counts as blocked. */
494
- readonly threshold: Quantity;
495
- /** This gate is the policy that the check controls, or null for a check that only reports. */
496
- readonly gates: Gate | null;
497
- readonly poll: Poll;
498
- }
499
- /**
500
- * A watchdog measures how late its own tick comes. A blocked event loop delays each timer, thus a
501
- * tick that comes later than the threshold shows the block. Its states are `watching`, `blocked`
502
- * and `stopped`.
503
- */
504
- interface Watchdog {
505
- /** This function is the check: it fails when a tick since the last poll came late, or the loop is still blocked. */
506
- readonly check: () => Outcome;
507
- /** This time is the most that a tick was late, in milliseconds, since the start. */
508
- readonly worst: number;
509
- readonly blocked: boolean;
510
- stop(): void;
511
- }
512
- /** This function starts a watchdog on a clock. */
513
- declare const watchdog: (clock: Clock, spec: WatchdogSpec, trace?: Trace) => Watchdog;
514
- //#endregion
515
- //#region src/builder.d.ts
516
- /**
517
- * A service is composed with plain method uses before it starts. The builder is imperative, and
518
- * it holds static knowledge. The service does not use an `init` function that gives registrations.
519
- *
520
- * const svc = service("app");
521
- * svc.dependency("weather", {
522
- * system: null,
523
- * knobs: { request_timeout },
524
- * operations: { "GET /v1/forecast": { idempotent: true } },
525
- * });
526
- * svc.controller("forecast").requires("weather").route("GET /api/forecast", { idempotent: true });
527
- * svc.check({ name: "weather.round-trip", dependency: "weather", … }, roundTrip);
528
- * svc.describe(); // the whole graph as data, with nothing started
529
- * const health = await svc.start();
530
- *
531
- * The graph has one source, thus its parts cannot disagree. A dependency or a check can join
532
- * after the start. It starts tripped, and the export is partial. The runtime has no defaults of
533
- * its own. Thus `describe()` refuses a service that does not declare a policy, its startup budget
534
- * or its shutdown, and it tells which.
535
- *
536
- * `start()` starts only the health runtime. `run()` starts the whole lifecycle: the startup in its
537
- * sequence, the exit signals, the capped phases of the shutdown, and the exit of the process.
538
- */
539
- interface ControllerBuilder {
540
- /** This method declares the dependencies that its routes need. The controller is ready only while they are ready. */
541
- requires(...dependencies: string[]): ControllerBuilder;
542
- /** This method declares a route that the controller serves, and if its callers can send it again. */
543
- route(route: string, operation: Operation): ControllerBuilder;
544
- }
545
- /** A service builder composes a service, gives it as data, and starts it. */
546
- interface ServiceBuilder {
547
- readonly name: string;
548
- /** This method declares a dependency, and the handle that connects to it and closes it, if it has one. */
549
- dependency(name: string, spec: Omit<Dependency, "name">, handle?: DependencyHandle): ServiceBuilder;
550
- /** This method declares a server, and its implementation. `run()` needs the implementation. */
551
- server(name: string, knobs: Readonly<Record<string, Extent>>, impl?: TransportImpl): ServiceBuilder;
552
- consumer(name: string, knobs: Readonly<Record<string, Extent>>, impl?: TransportImpl): ServiceBuilder;
553
- worker(name: string, knobs: Readonly<Record<string, Extent>>, impl?: TransportImpl): ServiceBuilder;
554
- /** This method gives the server of the probes. It starts first and closes last. */
555
- healthServer(server: HealthServer): ServiceBuilder;
556
- /** This method adds work to a declared phase of the shutdown: the owner of the work registers it. */
557
- onPhase(phase: string, work: PhaseWork): ServiceBuilder;
558
- /** This method declares a watchdog of the event loop, as a check on the state of the process. */
559
- watchdog(spec: WatchdogSpec): ServiceBuilder;
560
- controller(name: string): ControllerBuilder;
561
- /** This method declares a check, and the function that measures its step. `start()` needs the function. */
562
- check(check: Check, run?: CheckFn): ServiceBuilder;
563
- readiness(timing: Timing): ServiceBuilder;
564
- liveness(timing: Timing): ServiceBuilder;
565
- startup(budget: Quantity): ServiceBuilder;
566
- couple(coupling: Coupling): ServiceBuilder;
567
- phase(name: string, cap: Quantity): ServiceBuilder;
568
- cooperativeWindow(window: Extent): ServiceBuilder;
569
- /** This method gives the service as data, and it starts nothing. */
570
- describe(): ServiceDescription;
571
- /**
572
- * This method closes the composition, starts the health runtime, and gives it after one warm-up
573
- * sweep of each check. A part that joins after it starts tripped, and it makes the export
574
- * partial. A second use gives the same runtime.
575
- */
576
- start(options?: StartOptions): Promise<Health>;
577
- /**
578
- * This method starts the whole lifecycle and gives it when its startup ends: the service operates,
579
- * or its startup failed and it shuts down. It refuses a declaration that it cannot start: a transport
580
- * without its implementation, or a stage with work and no declared phase.
581
- */
582
- run(options?: RunOptions): Promise<Lifecycle>;
583
- /**
584
- * This value is the health runtime from the time that `start()` begins, or null before. Thus the
585
- * probes can answer during the warm-up sweep: the startup probe fails until the sweep ends.
586
- */
587
- readonly health: Health | null;
588
- }
589
- /** This function starts the composition of a service. */
590
- declare const service: (name: string) => ServiceBuilder;
591
- //#endregion
592
- export { Timing as $, StartOptions as A, Dependency as B, ProcessPort as C, HealthVerdict as D, Health as E, MachineName as F, Step as G, Gate as H, Recorder as I, Operation as J, Transport as K, Check as L, Outcome as M, Result as N, ProbeAnswer as O, LifecycleEvent as P, Span as Q, Controller as R, ExitSignal as S, CheckVerdict as T, Phase as U, FORMAT as V, ServiceDescription as W, FailsBy as X, mayReissue as Y, Poll as Z, cooperativeAbortAt as _, WatchdogSpec as a, RequestOutcome as b, HealthServer as c, PhaseContext as d, asDebounce as et, PhaseWork as f, TransportImpl as g, Stage as h, Watchdog as i, recoverSpan as it, CheckFn as j, ProbeKind as k, Lifecycle as l, STAGES as m, ServiceBuilder as n, failSpan as nt, watchdog as o, RunOptions as p, Idempotency as q, service as r, heartbeatDetection as rt, DependencyHandle as s, ControllerBuilder as t, asWindow as tt, LifecycleState as u, stageRank as v, nodeProcess as w, EXIT_SIGNALS as x, RequestFn as y, Coupling as z };
593
- //# sourceMappingURL=builder-DnfUDW9u.d.ts.map
649
+ export { heartbeatDetection as $, LifecycleEvent as A, Gate as B, ProbeAnswer as C, Outcome as D, CheckFn as E, CooperativeFloor as F, Transport as G, RepeatSignal as H, Coupling as I, Span as J, FailsBy as K, Dependency as L, Recorder as M, Check as N, Result as O, Controller as P, failSpan as Q, ExitCodes as R, HealthVerdict as S, StartOptions as T, ServiceDescription as U, Phase as V, Step as W, asDebounce as X, Timing as Y, asWindow as Z, RequestOptions as _, Operation as _t, PhaseContext as a, ExitSignal as at, CheckVerdict as b, STAGES as c, PROCESS_TRIGGERS as ct, TransportImpl as d, ProcessTrigger as dt, recoverSpan as et, cooperativeAbortAt as f, isExitCode as ft, RequestFn as g, Idempotency as gt, RequestEvent as h, processPortOf as ht, LifecycleState as i, EXIT_SIGNALS as it, MachineName as j, Trace as k, ShutdownOptions as l, ProcessHost as lt, RequestEnd as m, nodeProcess as mt, HealthServer as n, RoutePattern as nt, PhaseWork as o, ExitTrigger as ot, stageRank as p, isExitSignal as pt, Poll as q, Lifecycle as r, RouteRequest as rt, RunOptions as s, HostStream as st, DependencyHandle as t, OperationOf as tt, Stage as u, ProcessPort as ut, RequestStream as v, mayReissue as vt, ProbeKind as w, Health as x, RequestWork as y, FORMAT as z };
650
+ //# sourceMappingURL=lifecycle-DIj4YGmO.d.ts.map
package/build/redis.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { t as Backoff } from "./backoff-B-jGWVDm.js";
2
2
  import { n as Clock } from "./clock-D-38uH_z.js";
3
- import { B as Dependency, G as Step, H as Gate, I as Recorder, J as Operation, L as Check, W as ServiceDescription, Z as Poll, j as CheckFn, n as ServiceBuilder, rt as heartbeatDetection, s as DependencyHandle } from "./builder-DnfUDW9u.js";
3
+ import { $ as heartbeatDetection, B as Gate, E as CheckFn, L as Dependency, M as Recorder, N as Check, U as ServiceDescription, W as Step, _t as Operation, q as Poll, t as DependencyHandle } from "./lifecycle-DIj4YGmO.js";
4
+ import { n as ServiceBuilder } from "./builder-B_q-JeW8.js";
4
5
  import { Extent, Quantity } from "@mark1russell7/quantity";
5
6
  import { Machine } from "@mark1russell7/algebra";
6
7
  //#region src/redis/connection.d.ts