@procedures/peer 0.9.2 → 0.11.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.
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The request tracking of the procedures host (decisions D3 and D4, CLI-7).
3
+ *
4
+ * Each call of a face goes through `life.request` of the service. Thus the service admits the
5
+ * call, counts it, drains it and cuts it, as it does for each request of a process.
6
+ *
7
+ * - The route of a call is the name of its face and the key of its procedure: `http git.status`.
8
+ * One route pattern for each face (`http *`) matches each call, also of a procedure that the
9
+ * registry gets later.
10
+ * - A function of the pattern gives the operation of each call, thus its idempotency (D3): a
11
+ * repeatable procedure, a call with an idempotency key, or a call that runs one time.
12
+ * - Each call is a stream (D4). A unary call is a stream of one. A stream call stays in flight
13
+ * until its last item, and a cut after the first item ends the stream in-band, with an error.
14
+ */
15
+ import type { Lifecycle, Operation, OperationOf } from "@mark1russell7/service";
16
+ import { type ProcedureRegistry, type ProcedureServer, type RequestHandler } from "@procedures/client";
17
+ /**
18
+ * The operation of a call, which gives its idempotency (D3):
19
+ * - `repeatable`: the effects of the procedure permit a second run (no writes, or idempotent writes).
20
+ * - `keyed`: the call has an idempotency key, and the server keeps its result for the window.
21
+ * - `once`: each other call. A cut of it before its first item answers 500, because it can have had its effect.
22
+ */
23
+ export type CallOperation = "repeatable" | "keyed" | "once";
24
+ /** The detail of a call for the function of a route pattern: its face, its procedure and its operation. */
25
+ export interface CallDetail {
26
+ readonly face: string;
27
+ /** The key of the procedure, for example `git.status`. */
28
+ readonly key: string;
29
+ readonly operation: CallOperation;
30
+ }
31
+ /**
32
+ * This function gives the operations that a call of a face can be, by name. With a window, a call
33
+ * with an idempotency key is a keyed operation for that window (the time that the server keeps a result).
34
+ */
35
+ export declare function callOperations(keyedWindowMs: number | undefined): Readonly<Record<string, Operation>>;
36
+ /** This function is the operation function of each pattern of the host: it reads the operation from the detail of the call. */
37
+ export declare const operationOfCall: OperationOf;
38
+ /** A handler of one face: the server of the host, with each call through the request tracking of the service. */
39
+ export interface FaceHandler extends RequestHandler {
40
+ /** This method gives the registry of the server. The MCP face lists its tools from it. */
41
+ getRegistry(): ProcedureRegistry;
42
+ }
43
+ /** The options of `faceHandler()`. */
44
+ export interface FaceHandlerOptions {
45
+ readonly server: ProcedureServer;
46
+ /** The controller of the calls in the declaration of the service. */
47
+ readonly controller: string;
48
+ /** The name of the face: the first part of the route of each call. */
49
+ readonly face: string;
50
+ /** This function gives the lifecycle of the service, or null. Without a lifecycle, each call goes to the server directly. */
51
+ readonly life: () => Lifecycle | null;
52
+ /** True: a call with an idempotency key is a keyed operation. The server then keeps the results of the keys. */
53
+ readonly keyed: boolean;
54
+ }
55
+ /**
56
+ * This function gives the handler of one face. While the host runs under a service, each call
57
+ * goes through `life.request`. Without a service, each call goes to the server directly.
58
+ */
59
+ export declare function faceHandler(options: FaceHandlerOptions): FaceHandler;
60
+ //# sourceMappingURL=tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../../src/host/tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAA0C,MAAM,wBAAwB,CAAC;AACxH,OAAO,EAQL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,oBAAoB,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D,2GAA2G;AAC3G,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAMrG;AAED,+HAA+H;AAC/H,eAAO,MAAM,eAAe,EAAE,WAAgH,CAAC;AAE/I,iHAAiH;AACjH,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,0FAA0F;IAC1F,WAAW,IAAI,iBAAiB,CAAC;CAClC;AAED,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6HAA6H;IAC7H,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IACtC,gHAAgH;IAChH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AA2HD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAUpE"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * The request tracking of the procedures host (decisions D3 and D4, CLI-7).
3
+ *
4
+ * Each call of a face goes through `life.request` of the service. Thus the service admits the
5
+ * call, counts it, drains it and cuts it, as it does for each request of a process.
6
+ *
7
+ * - The route of a call is the name of its face and the key of its procedure: `http git.status`.
8
+ * One route pattern for each face (`http *`) matches each call, also of a procedure that the
9
+ * registry gets later.
10
+ * - A function of the pattern gives the operation of each call, thus its idempotency (D3): a
11
+ * repeatable procedure, a call with an idempotency key, or a call that runs one time.
12
+ * - Each call is a stream (D4). A unary call is a stream of one. A stream call stays in flight
13
+ * until its last item, and a cut after the first item ends the stream in-band, with an error.
14
+ */
15
+ import { IDEMPOTENCY_KEY_METADATA, effectsOf, idempotencyKeyOf, isRepeatable, methodToPath, ms, pathToKey, } from "@procedures/client";
16
+ /**
17
+ * This function gives the operations that a call of a face can be, by name. With a window, a call
18
+ * with an idempotency key is a keyed operation for that window (the time that the server keeps a result).
19
+ */
20
+ export function callOperations(keyedWindowMs) {
21
+ return {
22
+ repeatable: { idempotent: true },
23
+ once: { idempotent: false },
24
+ ...(keyedWindowMs !== undefined ? { keyed: { idempotent: { key: IDEMPOTENCY_KEY_METADATA, window: ms(keyedWindowMs) } } } : {}),
25
+ };
26
+ }
27
+ /** This function is the operation function of each pattern of the host: it reads the operation from the detail of the call. */
28
+ export const operationOfCall = (request) => request.detail?.operation ?? "once";
29
+ /** The response of an error, in wire v1. */
30
+ function failure(id, code, message, retryable) {
31
+ return { id, status: { type: "error", code, message, retryable }, metadata: {} };
32
+ }
33
+ /** The text of an error. */
34
+ function messageOf(error) {
35
+ return error instanceof Error ? error.message : String(error);
36
+ }
37
+ /**
38
+ * The response of an end before the first item. A refusal and a retryable cut are `UNAVAILABLE`
39
+ * (503, with `Retry-After` from the transport). Another cut and a failure are `INTERNAL_ERROR` (500).
40
+ */
41
+ function endResponse(id, end) {
42
+ switch (end.kind) {
43
+ case "refused":
44
+ return failure(id, "UNAVAILABLE", `The host does not take the call now: ${end.cause}`, true);
45
+ case "cut":
46
+ return end.status === 503
47
+ ? failure(id, "UNAVAILABLE", `The host stopped the call: ${end.cause}`, true)
48
+ : failure(id, "INTERNAL_ERROR", `The host stopped the call, and the call can have had its effect: ${end.cause}`, false);
49
+ case "failed":
50
+ return failure(id, "INTERNAL_ERROR", messageOf(end.error), false);
51
+ case "done":
52
+ return failure(id, "INTERNAL_ERROR", "The call ended without a response", false);
53
+ }
54
+ }
55
+ /**
56
+ * The error of an end after the first item: the stream ends in-band, with an error line. The count
57
+ * of the items of the stream goes in the message. The head of the response is not an item.
58
+ */
59
+ function inBandEnd(end) {
60
+ const delivered = Math.max(0, end.delivered - 1);
61
+ return Object.assign(new Error(`The host stopped the stream after ${delivered} items: ${end.cause}`), {
62
+ code: end.retryable ? "UNAVAILABLE" : "INTERNAL_ERROR",
63
+ retryable: end.retryable,
64
+ delivered,
65
+ });
66
+ }
67
+ /** The items of a stream call after its head. The reader that stops early stops the call. */
68
+ async function* streamRest(events) {
69
+ let ended = false;
70
+ try {
71
+ for (;;) {
72
+ const next = await events.next();
73
+ if (next.done) {
74
+ ended = true;
75
+ return;
76
+ }
77
+ const event = next.value;
78
+ if (event.kind === "item") {
79
+ if ("value" in event.value)
80
+ yield event.value.value;
81
+ continue;
82
+ }
83
+ ended = true;
84
+ if (event.kind === "done")
85
+ return;
86
+ if (event.kind === "failed")
87
+ throw event.error;
88
+ throw inBandEnd(event);
89
+ }
90
+ }
91
+ finally {
92
+ if (!ended)
93
+ await events.return?.(undefined);
94
+ }
95
+ }
96
+ /** This function does one call through `life.request`, and gives the response of the face. */
97
+ async function trackedCall(life, options, request) {
98
+ const { server } = options;
99
+ const key = pathToKey(methodToPath(request.method));
100
+ const procedure = server.procedureOf(request.method);
101
+ const operation = procedure !== undefined && isRepeatable(effectsOf(procedure))
102
+ ? "repeatable"
103
+ : options.keyed && idempotencyKeyOf(request.metadata) !== undefined
104
+ ? "keyed"
105
+ : "once";
106
+ const detail = { face: options.face, key, operation };
107
+ const outer = request.signal;
108
+ // The work of the request: the head of the response, then each item of a stream
109
+ const work = async function* (signal) {
110
+ request.signal = outer ? AbortSignal.any([outer, signal]) : signal;
111
+ const response = await server.handle(request);
112
+ const items = response.stream;
113
+ if (items === undefined) {
114
+ yield { head: response, streams: false };
115
+ return;
116
+ }
117
+ const { stream: _items, ...head } = response;
118
+ yield { head, streams: true };
119
+ for await (const value of items)
120
+ yield { value };
121
+ };
122
+ let events;
123
+ try {
124
+ events = life.request(options.controller, `${options.face} ${key}`, (signal) => work(signal), { detail })[Symbol.asyncIterator]();
125
+ }
126
+ catch (error) {
127
+ return failure(request.id, "INTERNAL_ERROR", `The service of the host has no route for this call: ${messageOf(error)}`, false);
128
+ }
129
+ const first = await events.next();
130
+ if (first.done)
131
+ return failure(request.id, "INTERNAL_ERROR", "The call ended without a response", false);
132
+ const event = first.value;
133
+ if (event.kind !== "item")
134
+ return endResponse(request.id, event);
135
+ const part = event.value;
136
+ if (!("head" in part)) {
137
+ await events.return?.(undefined);
138
+ return failure(request.id, "INTERNAL_ERROR", "The call gave an item before its response", false);
139
+ }
140
+ if (!part.streams) {
141
+ // The end of a unary call: the call leaves the count of the service
142
+ await events.next();
143
+ return part.head;
144
+ }
145
+ return { ...part.head, stream: streamRest(events) };
146
+ }
147
+ /**
148
+ * This function gives the handler of one face. While the host runs under a service, each call
149
+ * goes through `life.request`. Without a service, each call goes to the server directly.
150
+ */
151
+ export function faceHandler(options) {
152
+ const { server } = options;
153
+ return {
154
+ ambientCredentials: server.ambientCredentials,
155
+ getRegistry: () => server.getRegistry(),
156
+ handle: (request) => {
157
+ const life = options.life();
158
+ return life ? trackedCall(life, options, request) : server.handle(request);
159
+ },
160
+ };
161
+ }
162
+ //# sourceMappingURL=tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.js","sourceRoot":"","sources":["../../src/host/tracking.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,7 +5,9 @@
5
5
  * Exposes procedures and generates manifests.
6
6
  */
7
7
  export type { TransportType, TransportConfig, HttpTransportConfig, WebSocketTransportConfig, LocalTransportConfig, ServerCreateInput, ServerCreateOutput, ServerConnectInput, ServerConnectOutput, ServerDisconnectInput, ServerDisconnectOutput, ManifestGenerateInput, ManifestGenerateOutput, ProcedureInfo, PeerConnection, ProcedureAnnounceMessage, ProcedureUpdateMessage, } from "./types.js";
8
- export { createPeer, type Peer, type PeerOptions, type PeerEndpoint } from "./peer/index.js";
8
+ export { createProcedureHost, httpFace, wsFace, LOCAL_LISTENER_KNOBS, callOperations, faceHandler, operationOfCall, } from "./host/index.js";
9
+ export type { ProcedureHost, ProcedureHostOptions, ProcedureHostFaces, HostListener, HostCollection, HostServerOptions, HostPart, HostDependency, HostCheck, HostPattern, HostController, HostEndpoint, HostInfo, HostKnobs, HostFace, HostFaceContext, HostFaceEndpoint, HostFaceFactory, HostFaceUpgrade, CallDetail, CallOperation, FaceHandler, FaceHandlerOptions, } from "./host/index.js";
10
+ export { createPeer, peerHostOptions, PEER_PROFILE, type Peer, type PeerOptions, type PeerEndpoint } from "./peer/index.js";
9
11
  export { exposeRule } from "./expose.js";
10
12
  export { serverCreateProcedure, getPeer, getActivePeerIds, serverConnectProcedure, serverDisconnectProcedure, manifestGenerateProcedure, } from "./procedures/index.js";
11
13
  export { generateTypeScript, generateJson, generateJsonString, type ProcedureManifest, } from "./manifest/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,MAAM,EACN,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC5H,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -4,8 +4,10 @@
4
4
  * Transport-agnostic peer for bidirectional RPC.
5
5
  * Exposes procedures and generates manifests.
6
6
  */
7
- // Peer
8
- export { createPeer } from "./peer/index.js";
7
+ // The procedures host (CLI-7): the parts of a service, and its faces
8
+ export { createProcedureHost, httpFace, wsFace, LOCAL_LISTENER_KNOBS, callOperations, faceHandler, operationOfCall, } from "./host/index.js";
9
+ // Peer: a procedures host with a service of its own, for a process that has no service
10
+ export { createPeer, peerHostOptions, PEER_PROFILE } from "./peer/index.js";
9
11
  export { exposeRule } from "./expose.js";
10
12
  // Procedures
11
13
  export { serverCreateProcedure, getPeer, getActivePeerIds, serverConnectProcedure, serverDisconnectProcedure, manifestGenerateProcedure, } from "./procedures/index.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,OAAO;AACP,OAAO,EAAE,UAAU,EAAkD,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,aAAa;AACb,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,GAEnB,MAAM,qBAAqB,CAAC;AAE7B,aAAa;AACb,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAE/B,YAAY;AACZ,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAE9B,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,qEAAqE;AACrE,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,MAAM,EACN,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,iBAAiB,CAAC;AA2BzB,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAkD,MAAM,iBAAiB,CAAC;AAC5H,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,aAAa;AACb,OAAO,EACL,qBAAqB,EACrB,OAAO,EACP,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,GAEnB,MAAM,qBAAqB,CAAC;AAE7B,aAAa;AACb,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAE/B,YAAY;AACZ,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAE9B,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
@@ -5,7 +5,8 @@
5
5
  * the build of `mark` and its peer id. Before, five copies of this logic had drifted, and a
6
6
  * server counted as alive when its PID existed: Windows reuses PIDs, so a stale lockfile broke
7
7
  * every `mark` command and `server stop` killed an unrelated process (deep dive CLI-4). Now a
8
- * server is alive only when its health endpoint answers with the peer id of its lockfile.
8
+ * server is alive only when its procedure `host.info` answers the token of its lockfile with the
9
+ * peer id of its lockfile.
9
10
  */
10
11
  export interface LockfileData {
11
12
  pid: number;
@@ -32,10 +33,12 @@ export declare function readLockfileForPort(port: number): LockfileData | null;
32
33
  export declare function readAllLockfiles(): LockfileData[];
33
34
  export declare function removeLockfileForPort(port: number): void;
34
35
  /**
35
- * The state of a lockfile's server:
36
- * - "alive": the health endpoint answers with the lockfile's peer id;
36
+ * The state of a lockfile's server, from the procedure `host.info` with the token of the lockfile
37
+ * (CLI-7, CLI-9). Before, the server answered a `/health` route without the token, and that route said
38
+ * "ok" also while the server stopped.
39
+ * - "alive": `host.info` answers with the lockfile's peer id;
37
40
  * - "dead": nothing answers (the lockfile is stale);
38
- * - "other": something else answers on the port (another server, or a lockfile without a peer id).
41
+ * - "other": something else answers on the port (another server, a refused token, or a lockfile without a peer id).
39
42
  */
40
43
  export declare function checkServer(lockfile: LockfileData, timeoutMs?: number): Promise<"alive" | "dead" | "other">;
41
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,6GAA6G;IAC7G,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAMD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAGtD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAiBjD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAYxD;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAa/G;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAUjI"}
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,6GAA6G;IAC7G,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAMD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAGtD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAiBjD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAYxD;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAkB/G;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAUjI"}
package/dist/lockfile.js CHANGED
@@ -5,7 +5,8 @@
5
5
  * the build of `mark` and its peer id. Before, five copies of this logic had drifted, and a
6
6
  * server counted as alive when its PID existed: Windows reuses PIDs, so a stale lockfile broke
7
7
  * every `mark` command and `server stop` killed an unrelated process (deep dive CLI-4). Now a
8
- * server is alive only when its health endpoint answers with the peer id of its lockfile.
8
+ * server is alive only when its procedure `host.info` answers the token of its lockfile with the
9
+ * peer id of its lockfile.
9
10
  */
10
11
  import * as fs from "node:fs";
11
12
  import * as os from "node:os";
@@ -74,22 +75,29 @@ export function removeLockfileForPort(port) {
74
75
  }
75
76
  }
76
77
  /**
77
- * The state of a lockfile's server:
78
- * - "alive": the health endpoint answers with the lockfile's peer id;
78
+ * The state of a lockfile's server, from the procedure `host.info` with the token of the lockfile
79
+ * (CLI-7, CLI-9). Before, the server answered a `/health` route without the token, and that route said
80
+ * "ok" also while the server stopped.
81
+ * - "alive": `host.info` answers with the lockfile's peer id;
79
82
  * - "dead": nothing answers (the lockfile is stale);
80
- * - "other": something else answers on the port (another server, or a lockfile without a peer id).
83
+ * - "other": something else answers on the port (another server, a refused token, or a lockfile without a peer id).
81
84
  */
82
85
  export async function checkServer(lockfile, timeoutMs = 1000) {
83
86
  let response;
84
87
  try {
85
- response = await fetch(`${lockfile.endpoint}/health`, { signal: AbortSignal.timeout(timeoutMs) });
88
+ response = await fetch(`${lockfile.endpoint}/host/info`, {
89
+ method: "POST",
90
+ headers: { "content-type": "application/json", ...(lockfile.token !== undefined ? { authorization: `Bearer ${lockfile.token}` } : {}) },
91
+ body: "{}",
92
+ signal: AbortSignal.timeout(timeoutMs),
93
+ });
86
94
  }
87
95
  catch {
88
96
  return "dead";
89
97
  }
90
98
  try {
91
- const health = (await response.json());
92
- return lockfile.peerId !== undefined && health.peerId === lockfile.peerId ? "alive" : "other";
99
+ const info = (await response.json());
100
+ return response.ok && lockfile.peerId !== undefined && info.peerId === lockfile.peerId ? "alive" : "other";
93
101
  }
94
102
  catch {
95
103
  return "other";
@@ -1 +1 @@
1
- {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,23 @@
1
1
  /**
2
2
  * Peer Module
3
3
  *
4
- * Transport-agnostic peer implementation for bidirectional RPC.
4
+ * A peer is a procedures host with a service of its own (CLI-7), for a process that has no service
5
+ * of its own: a test, or a host that a procedure starts (`server.create`). `createPeer()` builds it
6
+ * with `createProcedureHost()`: each HTTP or WebSocket transport of the options is a face on a
7
+ * listener of the host, and the listener is an `httpTransport` of `@mark1russell7/service/http`.
8
+ *
9
+ * - `start()` declares the parts in a service and starts `run()` of `@mark1russell7/service`, on
10
+ * a process port that installs no signal handler and never ends the process.
11
+ * - `stop()` asks the lifecycle for its shutdown, and waits for the end of its stages.
12
+ *
13
+ * A process that has a service of its own declares the parts of `createProcedureHost()` with
14
+ * `host.declare(svc)`, in place of a peer (decision D2). The peer has no listener, URL strategy,
15
+ * `/health` route or token check of its own.
5
16
  */
6
- import { ProcedureServer, type ProcedureRegistry, Client, type HostPolicy } from "@procedures/client";
7
- import type { ProcedurePath, StopOptions } from "@procedures/client";
17
+ import { type Profile } from "@mark1russell7/service";
18
+ import { type Client, type HostPolicy, type ProcedurePath, type ProcedureRegistry, type ProcedureServer, type StopOptions } from "@procedures/client";
8
19
  import type { TransportConfig, TransportType } from "../types.js";
20
+ import { type ProcedureHost, type ProcedureHostOptions } from "../host/index.js";
9
21
  export interface PeerOptions {
10
22
  /** Unique peer ID */
11
23
  id: string;
@@ -24,10 +36,13 @@ export interface PeerOptions {
24
36
  metrics?: boolean | undefined;
25
37
  /**
26
38
  * The policy of the host (`hostPolicy()` of the core, roadmap 2.3): the expose rule, the call
27
- * rule, the interceptors (a time limit), the token of each network transport that has none of
28
- * its own, and the browser checks. `expose` above, when given, wins over the policy's.
39
+ * rule, the interceptors (a time limit), the token and the browser checks. `expose` above, when
40
+ * given, wins over the policy's. A peer has one token: the token of its transports, or else the
41
+ * token of the policy.
29
42
  */
30
43
  policy?: HostPolicy | undefined;
44
+ /** The profile of the service of the peer. The default is `PEER_PROFILE`. */
45
+ profile?: Profile | undefined;
31
46
  }
32
47
  export interface PeerEndpoint {
33
48
  type: TransportType;
@@ -36,15 +51,21 @@ export interface PeerEndpoint {
36
51
  export interface Peer {
37
52
  /** Peer ID */
38
53
  id: string;
39
- /** Start all transports */
54
+ /** This method starts the parts of the host. A peer starts one time. */
40
55
  start(): Promise<void>;
41
- /** Stop all transports */
42
- /** Stop the peer. With `grace`, the calls in flight have that time to end (roadmap R14). */
56
+ /**
57
+ * This method asks the lifecycle of the peer for its shutdown, and waits for the end of its stages.
58
+ *
59
+ * @param options - Deprecated: the grace has no effect. The drain of the profile of the peer gives
60
+ * the calls in flight their time (CLI-7).
61
+ */
43
62
  stop(options?: StopOptions): Promise<void>;
44
63
  /** Get active endpoints */
45
64
  getEndpoints(): PeerEndpoint[];
46
65
  /** Get underlying server */
47
66
  getServer(): ProcedureServer;
67
+ /** The procedures host of the peer: its parts, its faces and its info (CLI-7). */
68
+ getHost(): ProcedureHost;
48
69
  /** The ids of the WebSocket connections of the clients (roadmap R24). */
49
70
  connections(): string[];
50
71
  /**
@@ -54,7 +75,20 @@ export interface Peer {
54
75
  clientFor(connectionId: string): Client;
55
76
  }
56
77
  /**
57
- * Create a new peer instance
78
+ * This function gives the options of a procedures host for the options of a peer: each HTTP or
79
+ * WebSocket transport is a face on a listener with `LOCAL_LISTENER_KNOBS`, and the peer has one
80
+ * token. `createPeer()` uses it, and so does `runProcedureHost()` of `@procedures/server` (CLI-8).
81
+ */
82
+ export declare function peerHostOptions(options: PeerOptions, name?: string): ProcedureHostOptions;
83
+ /**
84
+ * The profile of the service of a peer, as data: the caps of `daemon`, and the cooperative abort at
85
+ * the start of the drain. Thus `stop()` aborts the calls in flight at once, as `stop()` without a
86
+ * grace did before (CLI-7). A repeat signal has no effect, and the port of a peer has no signal.
87
+ */
88
+ export declare const PEER_PROFILE: Profile;
89
+ /**
90
+ * Create a new peer instance: a procedures host with a service of its own, for a process that has
91
+ * no service of its own. A process with a service uses `createProcedureHost()` and `host.declare(svc)`.
58
92
  */
59
93
  export declare function createPeer(options: PeerOptions): Promise<Peer>;
60
94
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/peer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EAGf,KAAK,iBAAiB,EAQtB,MAAM,EAEN,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAuB,eAAe,EAAE,aAAa,EAA4B,MAAM,aAAa,CAAC;AA0BjH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,2GAA2G;IAC3G,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAQD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,0BAA0B;IAC1B,4FAA4F;IAC5F,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,2BAA2B;IAC3B,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,4BAA4B;IAC5B,SAAS,IAAI,eAAe,CAAC;IAC7B,yEAAyE;IACzE,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AA4RD;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/peer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAoD,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAuB,eAAe,EAAE,aAAa,EAA4B,MAAM,aAAa,CAAC;AACjH,OAAO,EAAwG,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAOvL,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,2GAA2G;IAC3G,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;OAKG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,2BAA2B;IAC3B,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,4BAA4B;IAC5B,SAAS,IAAI,eAAe,CAAC;IAC7B,kFAAkF;IAClF,OAAO,IAAI,aAAa,CAAC;IACzB,yEAAyE;IACzE,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AAuED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,GAAE,MAAe,GAAG,oBAAoB,CAgBjG;AAKD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,OAA0G,CAAC;AAuEtI;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE"}