@procedures/peer 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/README.md +46 -7
- package/dist/.tsbuildinfo +1 -1
- package/dist/host/faces.d.ts +78 -0
- package/dist/host/faces.d.ts.map +1 -0
- package/dist/host/faces.js +77 -0
- package/dist/host/faces.js.map +1 -0
- package/dist/host/index.d.ts +186 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +257 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/tracking.d.ts +60 -0
- package/dist/host/tracking.d.ts.map +1 -0
- package/dist/host/tracking.js +162 -0
- package/dist/host/tracking.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/lockfile.d.ts +21 -4
- package/dist/lockfile.d.ts.map +1 -1
- package/dist/lockfile.js +31 -7
- package/dist/lockfile.js.map +1 -1
- package/dist/peer/index.d.ts +43 -9
- package/dist/peer/index.d.ts.map +1 -1
- package/dist/peer/index.js +156 -241
- package/dist/peer/index.js.map +1 -1
- package/package.json +6 -9
- package/src/host/faces.ts +130 -0
- package/src/host/index.ts +434 -0
- package/src/host/tracking.ts +217 -0
- package/src/index.ts +38 -2
- package/src/lockfile.ts +39 -7
- package/src/peer/index.ts +172 -292
package/src/index.ts
CHANGED
|
@@ -26,8 +26,44 @@ export type {
|
|
|
26
26
|
ProcedureUpdateMessage,
|
|
27
27
|
} from "./types.js";
|
|
28
28
|
|
|
29
|
-
//
|
|
30
|
-
export {
|
|
29
|
+
// The procedures host (CLI-7): the parts of a service, and its faces
|
|
30
|
+
export {
|
|
31
|
+
createProcedureHost,
|
|
32
|
+
httpFace,
|
|
33
|
+
wsFace,
|
|
34
|
+
LOCAL_LISTENER_KNOBS,
|
|
35
|
+
callOperations,
|
|
36
|
+
faceHandler,
|
|
37
|
+
operationOfCall,
|
|
38
|
+
} from "./host/index.js";
|
|
39
|
+
export type {
|
|
40
|
+
ProcedureHost,
|
|
41
|
+
ProcedureHostOptions,
|
|
42
|
+
ProcedureHostFaces,
|
|
43
|
+
HostListener,
|
|
44
|
+
HostCollection,
|
|
45
|
+
HostServerOptions,
|
|
46
|
+
HostPart,
|
|
47
|
+
HostDependency,
|
|
48
|
+
HostCheck,
|
|
49
|
+
HostPattern,
|
|
50
|
+
HostController,
|
|
51
|
+
HostEndpoint,
|
|
52
|
+
HostInfo,
|
|
53
|
+
HostKnobs,
|
|
54
|
+
HostFace,
|
|
55
|
+
HostFaceContext,
|
|
56
|
+
HostFaceEndpoint,
|
|
57
|
+
HostFaceFactory,
|
|
58
|
+
HostFaceUpgrade,
|
|
59
|
+
CallDetail,
|
|
60
|
+
CallOperation,
|
|
61
|
+
FaceHandler,
|
|
62
|
+
FaceHandlerOptions,
|
|
63
|
+
} from "./host/index.js";
|
|
64
|
+
|
|
65
|
+
// Peer: a procedures host with a service of its own, for a process that has no service
|
|
66
|
+
export { createPeer, peerHostOptions, PEER_PROFILE, type Peer, type PeerOptions, type PeerEndpoint } from "./peer/index.js";
|
|
31
67
|
export { exposeRule } from "./expose.js";
|
|
32
68
|
|
|
33
69
|
// Procedures
|
package/src/lockfile.ts
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
|
|
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
|
|
|
11
12
|
import * as fs from "node:fs";
|
|
@@ -53,6 +54,30 @@ export function writeLockfile(data: LockfileData): void {
|
|
|
53
54
|
fs.writeFileSync(lockfilePath(data.port), JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
/** A lockfile as a dependency of a service: the shape of `DependencyHandle` of `@mark1russell7/service`. */
|
|
58
|
+
export interface LockfileHandle {
|
|
59
|
+
/** This method writes the lockfile. */
|
|
60
|
+
connect(): void;
|
|
61
|
+
/** This method removes the lockfile, when it is still the lockfile of this host. */
|
|
62
|
+
close(): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* This function gives the lockfile of a host as a dependency of its service (CLI-8). The lifecycle
|
|
67
|
+
* connects the dependencies before the listeners start, and it closes them after the listeners
|
|
68
|
+
* close. Thus the stages of `run()` own the lockfile, and the entry has no signal handler for it.
|
|
69
|
+
* The close leaves a lockfile of another peer on the same port.
|
|
70
|
+
*/
|
|
71
|
+
export function lockfileHandle(data: LockfileData): LockfileHandle {
|
|
72
|
+
return {
|
|
73
|
+
connect: () => writeLockfile(data),
|
|
74
|
+
close: () => {
|
|
75
|
+
const current = readLockfileForPort(data.port);
|
|
76
|
+
if (current === null || current.peerId === data.peerId) removeLockfileForPort(data.port);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
56
81
|
export function readLockfileForPort(port: number): LockfileData | null {
|
|
57
82
|
try {
|
|
58
83
|
return JSON.parse(fs.readFileSync(lockfilePath(port), "utf-8")) as LockfileData;
|
|
@@ -95,21 +120,28 @@ export function removeLockfileForPort(port: number): void {
|
|
|
95
120
|
}
|
|
96
121
|
|
|
97
122
|
/**
|
|
98
|
-
* The state of a lockfile's server
|
|
99
|
-
* -
|
|
123
|
+
* The state of a lockfile's server, from the procedure `host.info` with the token of the lockfile
|
|
124
|
+
* (CLI-7, CLI-9). Before, the server answered a `/health` route without the token, and that route said
|
|
125
|
+
* "ok" also while the server stopped.
|
|
126
|
+
* - "alive": `host.info` answers with the lockfile's peer id;
|
|
100
127
|
* - "dead": nothing answers (the lockfile is stale);
|
|
101
|
-
* - "other": something else answers on the port (another server, or a lockfile without a peer id).
|
|
128
|
+
* - "other": something else answers on the port (another server, a refused token, or a lockfile without a peer id).
|
|
102
129
|
*/
|
|
103
130
|
export async function checkServer(lockfile: LockfileData, timeoutMs = 1000): Promise<"alive" | "dead" | "other"> {
|
|
104
131
|
let response: Response;
|
|
105
132
|
try {
|
|
106
|
-
response = await fetch(`${lockfile.endpoint}/
|
|
133
|
+
response = await fetch(`${lockfile.endpoint}/host/info`, {
|
|
134
|
+
method: "POST",
|
|
135
|
+
headers: { "content-type": "application/json", ...(lockfile.token !== undefined ? { authorization: `Bearer ${lockfile.token}` } : {}) },
|
|
136
|
+
body: "{}",
|
|
137
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
138
|
+
});
|
|
107
139
|
} catch {
|
|
108
140
|
return "dead";
|
|
109
141
|
}
|
|
110
142
|
try {
|
|
111
|
-
const
|
|
112
|
-
return lockfile.peerId !== undefined &&
|
|
143
|
+
const info = (await response.json()) as { peerId?: unknown };
|
|
144
|
+
return response.ok && lockfile.peerId !== undefined && info.peerId === lockfile.peerId ? "alive" : "other";
|
|
113
145
|
} catch {
|
|
114
146
|
return "other";
|
|
115
147
|
}
|