@fnndsc/calypso 0.3.6 → 0.4.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/dist/daemon/berth.d.ts +148 -0
- package/dist/daemon/berth.js +288 -0
- package/dist/daemon/berth.js.map +1 -0
- package/dist/daemon/launch.js +26 -4
- package/dist/daemon/launch.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The advertised location of one running daemon, keyed by CUBE identity.
|
|
3
|
+
*
|
|
4
|
+
* @property identity - The normalised `<user>@<url>` this daemon hosts; stored
|
|
5
|
+
* so a resolve can verify an exact match rather than trust the filename hash
|
|
6
|
+
* alone.
|
|
7
|
+
* @property url - The daemon's WebSocket address (e.g. `ws://127.0.0.1:54321`).
|
|
8
|
+
* @property token - The attach token gating the daemon's handshake.
|
|
9
|
+
*/
|
|
10
|
+
export interface Berth {
|
|
11
|
+
identity: string;
|
|
12
|
+
url: string;
|
|
13
|
+
token: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Normalises a `<user>@<url>` identity lexically — no DNS, no network.
|
|
17
|
+
*
|
|
18
|
+
* The URL scheme and host are lowercased; the trailing slash CUBE requires is
|
|
19
|
+
* preserved; the port and the user's case are kept exactly. Host aliases (a
|
|
20
|
+
* short hostname versus its FQDN) are deliberately *not* merged: that is DNS
|
|
21
|
+
* resolution, not string rewriting, and a key that depends on DNS breaks under
|
|
22
|
+
* load balancers and split-horizon resolution. The rule is "same string, same
|
|
23
|
+
* daemon" — operators adopt one canonical URL per CUBE by convention.
|
|
24
|
+
*
|
|
25
|
+
* @param user - The CUBE username, used with exact case.
|
|
26
|
+
* @param cubeUrl - The CUBE API URL as the user typed it (scheme included).
|
|
27
|
+
* @returns The normalised identity string used as the berth key input.
|
|
28
|
+
*/
|
|
29
|
+
export declare function identity_normalise(user: string, cubeUrl: string): string;
|
|
30
|
+
/** The reserved identity for a daemon started with no restored CUBE session. */
|
|
31
|
+
export declare const DISCONNECTED_IDENTITY: string;
|
|
32
|
+
/**
|
|
33
|
+
* Derives the berth identity for a session, falling back to the reserved
|
|
34
|
+
* disconnected identity when there is no restored user/URL. Both the daemon
|
|
35
|
+
* (writing its berth) and a surface (guarding against a duplicate, or attaching)
|
|
36
|
+
* key on this so they always agree.
|
|
37
|
+
*
|
|
38
|
+
* @param user - The connected CUBE username, or null/undefined when disconnected.
|
|
39
|
+
* @param cubeUrl - The connected CUBE URL, or null/undefined when disconnected.
|
|
40
|
+
* @returns The normalised identity, or {@link DISCONNECTED_IDENTITY}.
|
|
41
|
+
*/
|
|
42
|
+
export declare function identity_forSession(user: string | null | undefined, cubeUrl: string | null | undefined): string;
|
|
43
|
+
/**
|
|
44
|
+
* Computes the short, filesystem-safe key for a normalised identity.
|
|
45
|
+
*
|
|
46
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
47
|
+
* @returns The first 16 hex characters of the identity's SHA-256 digest.
|
|
48
|
+
*/
|
|
49
|
+
export declare function berthKey_compute(identity: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* The directory berths live in: `$XDG_RUNTIME_DIR/calypso` when the runtime
|
|
52
|
+
* directory is set (Linux, per-user `0700`, cleared on logout), else the system
|
|
53
|
+
* temp directory (macOS `TMPDIR` is already per-user-private; Linux `/tmp`).
|
|
54
|
+
*
|
|
55
|
+
* @returns The absolute berth directory path (not guaranteed to exist yet).
|
|
56
|
+
*/
|
|
57
|
+
export declare function berthDir_path(): string;
|
|
58
|
+
/**
|
|
59
|
+
* The absolute path of one identity's berth file.
|
|
60
|
+
*
|
|
61
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
62
|
+
* @returns The berth file path (may not exist).
|
|
63
|
+
*/
|
|
64
|
+
export declare function berth_path(identity: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Writes a berth to its identity-keyed file, readable only by the current user.
|
|
67
|
+
*
|
|
68
|
+
* @param berth - The berth to advertise; its `identity` must be normalised.
|
|
69
|
+
*/
|
|
70
|
+
export declare function berth_write(berth: Berth): void;
|
|
71
|
+
/**
|
|
72
|
+
* Reads one identity's berth from disk, verifying the stored identity matches
|
|
73
|
+
* exactly (so a hash collision can never mis-route).
|
|
74
|
+
*
|
|
75
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
76
|
+
* @returns The berth, or null when none is advertised or it is malformed.
|
|
77
|
+
*/
|
|
78
|
+
export declare function berth_read(identity: string): Berth | null;
|
|
79
|
+
/**
|
|
80
|
+
* Reads every advertised berth in the berth directory.
|
|
81
|
+
*
|
|
82
|
+
* @returns All well-formed berths; an empty array when the directory is absent
|
|
83
|
+
* or holds none.
|
|
84
|
+
*/
|
|
85
|
+
export declare function berthAll_read(): Berth[];
|
|
86
|
+
/**
|
|
87
|
+
* Removes an identity's berth file if present (used to reap a berth whose
|
|
88
|
+
* daemon a liveness probe found dead).
|
|
89
|
+
*
|
|
90
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
91
|
+
*/
|
|
92
|
+
export declare function berth_remove(identity: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Reports whether something is listening at a berth's WebSocket address, by a
|
|
95
|
+
* plain TCP connect — no WebSocket handshake, so this stays within the daemon
|
|
96
|
+
* package (which has no client). It is the liveness check `daemon_launch` uses
|
|
97
|
+
* to refuse starting a rival for an identity that is already hosted; a surface's
|
|
98
|
+
* resolver uses a stronger handshake probe for attach.
|
|
99
|
+
*
|
|
100
|
+
* @param url - A `ws://host:port` berth URL.
|
|
101
|
+
* @param timeoutMs - How long to wait for the TCP connect (default 500 ms).
|
|
102
|
+
* @returns True when the port accepts a connection.
|
|
103
|
+
*/
|
|
104
|
+
export declare function berthUrl_isAlive(url: string, timeoutMs?: number): Promise<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* A probe that reports whether a berth's daemon is actually reachable. The
|
|
107
|
+
* surface supplies one backed by its attach client; the local resolver uses it
|
|
108
|
+
* to reap dead berths on read.
|
|
109
|
+
*/
|
|
110
|
+
export type BerthLivenessProbe = (berth: Berth) => Promise<boolean>;
|
|
111
|
+
/**
|
|
112
|
+
* The berth lookup seam. Tier 1 ships {@link LocalBerthResolver} over the local
|
|
113
|
+
* files; a future tier-2 `PorterBerthResolver` will implement the same contract
|
|
114
|
+
* over the network. Every surface depends only on this interface.
|
|
115
|
+
*/
|
|
116
|
+
export interface BerthResolver {
|
|
117
|
+
/**
|
|
118
|
+
* Resolves one identity to a live berth.
|
|
119
|
+
*
|
|
120
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
121
|
+
* @returns The live berth, or null when none is advertised or it is dead.
|
|
122
|
+
*/
|
|
123
|
+
resolve(identity: string): Promise<Berth | null>;
|
|
124
|
+
/**
|
|
125
|
+
* Lists every live berth (for a bare `--remote` with several daemons).
|
|
126
|
+
*
|
|
127
|
+
* @returns The live berths, dead ones reaped.
|
|
128
|
+
*/
|
|
129
|
+
list(): Promise<Berth[]>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The tier-1 resolver: reads identity-keyed berth files and, when given a
|
|
133
|
+
* liveness probe, reaps any berth whose daemon has gone (passive cleanup — the
|
|
134
|
+
* next read of a stale berth removes it). Without a probe it returns berths as
|
|
135
|
+
* recorded, trusting the caller's own attach to surface a dead one.
|
|
136
|
+
*/
|
|
137
|
+
export declare class LocalBerthResolver implements BerthResolver {
|
|
138
|
+
private readonly liveness_probe?;
|
|
139
|
+
/**
|
|
140
|
+
* @param liveness_probe - Optional reachability probe; when present, dead
|
|
141
|
+
* berths are reaped and never returned.
|
|
142
|
+
*/
|
|
143
|
+
constructor(liveness_probe?: BerthLivenessProbe | undefined);
|
|
144
|
+
/** @inheritdoc */
|
|
145
|
+
resolve(identity: string): Promise<Berth | null>;
|
|
146
|
+
/** @inheritdoc */
|
|
147
|
+
list(): Promise<Berth[]>;
|
|
148
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Identity-keyed daemon berths.
|
|
3
|
+
*
|
|
4
|
+
* A *berth* is the advertised location of one running CALYPSO daemon, keyed by
|
|
5
|
+
* the CUBE identity it hosts. It supersedes the single per-OS-user discovery
|
|
6
|
+
* file: several daemons — one per `<user>@<url>` identity — can now advertise on
|
|
7
|
+
* one machine, each in its own file, and a surface resolves the one it wants by
|
|
8
|
+
* identity.
|
|
9
|
+
*
|
|
10
|
+
* The berth records the daemon's WebSocket address and attach token. Files live
|
|
11
|
+
* in the user's runtime directory (`$XDG_RUNTIME_DIR`, else the system temp dir)
|
|
12
|
+
* under an owned `calypso/` subdirectory, `0700` on the directory and `0600` on
|
|
13
|
+
* each file — the same same-user perimeter the single-file discovery used, now
|
|
14
|
+
* multiplied by identity. See docs/session-supervisor.adoc for the design.
|
|
15
|
+
*
|
|
16
|
+
* All berth lookup goes through the {@link BerthResolver} seam so a future
|
|
17
|
+
* network `PorterBerthResolver` can replace the local one without any surface
|
|
18
|
+
* change. Liveness (is the daemon still there?) is supplied to the local
|
|
19
|
+
* resolver as an injected probe, keeping this server-side package free of a
|
|
20
|
+
* WebSocket client: the surface injects a probe backed by its own attach client.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
|
|
25
|
+
import { join } from 'path';
|
|
26
|
+
import { tmpdir } from 'os';
|
|
27
|
+
import { createHash } from 'node:crypto';
|
|
28
|
+
import { connect as net_connect } from 'node:net';
|
|
29
|
+
/** The prefix of every berth filename, so a directory scan finds only berths. */
|
|
30
|
+
const BERTH_FILE_PREFIX = 'berth-';
|
|
31
|
+
/** The owned subdirectory berths live under, inside the runtime directory. */
|
|
32
|
+
const BERTH_SUBDIR = 'calypso';
|
|
33
|
+
/**
|
|
34
|
+
* Normalises a `<user>@<url>` identity lexically — no DNS, no network.
|
|
35
|
+
*
|
|
36
|
+
* The URL scheme and host are lowercased; the trailing slash CUBE requires is
|
|
37
|
+
* preserved; the port and the user's case are kept exactly. Host aliases (a
|
|
38
|
+
* short hostname versus its FQDN) are deliberately *not* merged: that is DNS
|
|
39
|
+
* resolution, not string rewriting, and a key that depends on DNS breaks under
|
|
40
|
+
* load balancers and split-horizon resolution. The rule is "same string, same
|
|
41
|
+
* daemon" — operators adopt one canonical URL per CUBE by convention.
|
|
42
|
+
*
|
|
43
|
+
* @param user - The CUBE username, used with exact case.
|
|
44
|
+
* @param cubeUrl - The CUBE API URL as the user typed it (scheme included).
|
|
45
|
+
* @returns The normalised identity string used as the berth key input.
|
|
46
|
+
*/
|
|
47
|
+
export function identity_normalise(user, cubeUrl) {
|
|
48
|
+
const schemeSplit = cubeUrl.indexOf('://');
|
|
49
|
+
let normalisedUrl;
|
|
50
|
+
if (schemeSplit === -1) {
|
|
51
|
+
normalisedUrl = cubeUrl;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const scheme = cubeUrl.slice(0, schemeSplit).toLowerCase();
|
|
55
|
+
const rest = cubeUrl.slice(schemeSplit + 3);
|
|
56
|
+
// Lowercase only the authority (host[:port]); leave the path exactly as
|
|
57
|
+
// written, including the trailing slash CUBE requires.
|
|
58
|
+
const pathStart = rest.indexOf('/');
|
|
59
|
+
const authority = pathStart === -1 ? rest : rest.slice(0, pathStart);
|
|
60
|
+
const path = pathStart === -1 ? '' : rest.slice(pathStart);
|
|
61
|
+
normalisedUrl = `${scheme}://${authority.toLowerCase()}${path}`;
|
|
62
|
+
}
|
|
63
|
+
return `${user}@${normalisedUrl}`;
|
|
64
|
+
}
|
|
65
|
+
/** The reserved identity for a daemon started with no restored CUBE session. */
|
|
66
|
+
export const DISCONNECTED_IDENTITY = 'disconnected@no-cube';
|
|
67
|
+
/**
|
|
68
|
+
* Derives the berth identity for a session, falling back to the reserved
|
|
69
|
+
* disconnected identity when there is no restored user/URL. Both the daemon
|
|
70
|
+
* (writing its berth) and a surface (guarding against a duplicate, or attaching)
|
|
71
|
+
* key on this so they always agree.
|
|
72
|
+
*
|
|
73
|
+
* @param user - The connected CUBE username, or null/undefined when disconnected.
|
|
74
|
+
* @param cubeUrl - The connected CUBE URL, or null/undefined when disconnected.
|
|
75
|
+
* @returns The normalised identity, or {@link DISCONNECTED_IDENTITY}.
|
|
76
|
+
*/
|
|
77
|
+
export function identity_forSession(user, cubeUrl) {
|
|
78
|
+
return user && cubeUrl ? identity_normalise(user, cubeUrl) : DISCONNECTED_IDENTITY;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Computes the short, filesystem-safe key for a normalised identity.
|
|
82
|
+
*
|
|
83
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
84
|
+
* @returns The first 16 hex characters of the identity's SHA-256 digest.
|
|
85
|
+
*/
|
|
86
|
+
export function berthKey_compute(identity) {
|
|
87
|
+
return createHash('sha256').update(identity).digest('hex').slice(0, 16);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The directory berths live in: `$XDG_RUNTIME_DIR/calypso` when the runtime
|
|
91
|
+
* directory is set (Linux, per-user `0700`, cleared on logout), else the system
|
|
92
|
+
* temp directory (macOS `TMPDIR` is already per-user-private; Linux `/tmp`).
|
|
93
|
+
*
|
|
94
|
+
* @returns The absolute berth directory path (not guaranteed to exist yet).
|
|
95
|
+
*/
|
|
96
|
+
export function berthDir_path() {
|
|
97
|
+
const runtimeDir = process.env.XDG_RUNTIME_DIR || tmpdir();
|
|
98
|
+
return join(runtimeDir, BERTH_SUBDIR);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Ensures the berth directory exists, owner-only (`0700`).
|
|
102
|
+
*/
|
|
103
|
+
function berthDir_ensure() {
|
|
104
|
+
mkdirSync(berthDir_path(), { recursive: true, mode: 0o700 });
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The absolute path of one identity's berth file.
|
|
108
|
+
*
|
|
109
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
110
|
+
* @returns The berth file path (may not exist).
|
|
111
|
+
*/
|
|
112
|
+
export function berth_path(identity) {
|
|
113
|
+
return join(berthDir_path(), `${BERTH_FILE_PREFIX}${berthKey_compute(identity)}.json`);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Writes a berth to its identity-keyed file, readable only by the current user.
|
|
117
|
+
*
|
|
118
|
+
* @param berth - The berth to advertise; its `identity` must be normalised.
|
|
119
|
+
*/
|
|
120
|
+
export function berth_write(berth) {
|
|
121
|
+
berthDir_ensure();
|
|
122
|
+
writeFileSync(berth_path(berth.identity), JSON.stringify(berth), { mode: 0o600 });
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validates that an unknown parsed value is a well-formed {@link Berth}.
|
|
126
|
+
*
|
|
127
|
+
* @param parsed - The value read from a berth file.
|
|
128
|
+
* @returns The value as a Berth, or null when it is malformed.
|
|
129
|
+
*/
|
|
130
|
+
function berth_validate(parsed) {
|
|
131
|
+
if (typeof parsed === 'object' && parsed !== null &&
|
|
132
|
+
typeof parsed.identity === 'string' &&
|
|
133
|
+
typeof parsed.url === 'string' &&
|
|
134
|
+
typeof parsed.token === 'string') {
|
|
135
|
+
return parsed;
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Reads one identity's berth from disk, verifying the stored identity matches
|
|
141
|
+
* exactly (so a hash collision can never mis-route).
|
|
142
|
+
*
|
|
143
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
144
|
+
* @returns The berth, or null when none is advertised or it is malformed.
|
|
145
|
+
*/
|
|
146
|
+
export function berth_read(identity) {
|
|
147
|
+
const path = berth_path(identity);
|
|
148
|
+
if (!existsSync(path)) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const berth = berth_validate(JSON.parse(readFileSync(path, 'utf-8')));
|
|
153
|
+
return berth && berth.identity === identity ? berth : null;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Reads every advertised berth in the berth directory.
|
|
161
|
+
*
|
|
162
|
+
* @returns All well-formed berths; an empty array when the directory is absent
|
|
163
|
+
* or holds none.
|
|
164
|
+
*/
|
|
165
|
+
export function berthAll_read() {
|
|
166
|
+
const dir = berthDir_path();
|
|
167
|
+
if (!existsSync(dir)) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const berths = [];
|
|
171
|
+
for (const name of readdirSync(dir)) {
|
|
172
|
+
if (!name.startsWith(BERTH_FILE_PREFIX) || !name.endsWith('.json')) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const berth = berth_validate(JSON.parse(readFileSync(join(dir, name), 'utf-8')));
|
|
177
|
+
if (berth) {
|
|
178
|
+
berths.push(berth);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// A malformed or vanished file is simply skipped.
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return berths;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Removes an identity's berth file if present (used to reap a berth whose
|
|
189
|
+
* daemon a liveness probe found dead).
|
|
190
|
+
*
|
|
191
|
+
* @param identity - A normalised identity from {@link identity_normalise}.
|
|
192
|
+
*/
|
|
193
|
+
export function berth_remove(identity) {
|
|
194
|
+
const path = berth_path(identity);
|
|
195
|
+
if (existsSync(path)) {
|
|
196
|
+
try {
|
|
197
|
+
unlinkSync(path);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Already gone: the reap is a best-effort convenience.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Reports whether something is listening at a berth's WebSocket address, by a
|
|
206
|
+
* plain TCP connect — no WebSocket handshake, so this stays within the daemon
|
|
207
|
+
* package (which has no client). It is the liveness check `daemon_launch` uses
|
|
208
|
+
* to refuse starting a rival for an identity that is already hosted; a surface's
|
|
209
|
+
* resolver uses a stronger handshake probe for attach.
|
|
210
|
+
*
|
|
211
|
+
* @param url - A `ws://host:port` berth URL.
|
|
212
|
+
* @param timeoutMs - How long to wait for the TCP connect (default 500 ms).
|
|
213
|
+
* @returns True when the port accepts a connection.
|
|
214
|
+
*/
|
|
215
|
+
export function berthUrl_isAlive(url, timeoutMs = 500) {
|
|
216
|
+
return new Promise((resolve) => {
|
|
217
|
+
let host;
|
|
218
|
+
let port;
|
|
219
|
+
try {
|
|
220
|
+
const parsed = new URL(url);
|
|
221
|
+
host = parsed.hostname;
|
|
222
|
+
port = Number(parsed.port);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
resolve(false);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (!port) {
|
|
229
|
+
resolve(false);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const socket = net_connect({ host, port });
|
|
233
|
+
const settle = (alive) => {
|
|
234
|
+
socket.destroy();
|
|
235
|
+
resolve(alive);
|
|
236
|
+
};
|
|
237
|
+
socket.setTimeout(timeoutMs);
|
|
238
|
+
socket.once('connect', () => settle(true));
|
|
239
|
+
socket.once('timeout', () => settle(false));
|
|
240
|
+
socket.once('error', () => settle(false));
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The tier-1 resolver: reads identity-keyed berth files and, when given a
|
|
245
|
+
* liveness probe, reaps any berth whose daemon has gone (passive cleanup — the
|
|
246
|
+
* next read of a stale berth removes it). Without a probe it returns berths as
|
|
247
|
+
* recorded, trusting the caller's own attach to surface a dead one.
|
|
248
|
+
*/
|
|
249
|
+
export class LocalBerthResolver {
|
|
250
|
+
liveness_probe;
|
|
251
|
+
/**
|
|
252
|
+
* @param liveness_probe - Optional reachability probe; when present, dead
|
|
253
|
+
* berths are reaped and never returned.
|
|
254
|
+
*/
|
|
255
|
+
constructor(liveness_probe) {
|
|
256
|
+
this.liveness_probe = liveness_probe;
|
|
257
|
+
}
|
|
258
|
+
/** @inheritdoc */
|
|
259
|
+
async resolve(identity) {
|
|
260
|
+
const berth = berth_read(identity);
|
|
261
|
+
if (!berth) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
if (this.liveness_probe && !(await this.liveness_probe(berth))) {
|
|
265
|
+
berth_remove(berth.identity);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
return berth;
|
|
269
|
+
}
|
|
270
|
+
/** @inheritdoc */
|
|
271
|
+
async list() {
|
|
272
|
+
const berths = berthAll_read();
|
|
273
|
+
if (!this.liveness_probe) {
|
|
274
|
+
return berths;
|
|
275
|
+
}
|
|
276
|
+
const live = [];
|
|
277
|
+
for (const berth of berths) {
|
|
278
|
+
if (await this.liveness_probe(berth)) {
|
|
279
|
+
live.push(berth);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
berth_remove(berth.identity);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return live;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=berth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"berth.js","sourceRoot":"","sources":["../../src/daemon/berth.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/launch.js
CHANGED
|
@@ -17,7 +17,8 @@ import { token_generate } from './token.js';
|
|
|
17
17
|
import { sink_set } from '@fnndsc/brasa';
|
|
18
18
|
import { surface_set } from '@fnndsc/brasa';
|
|
19
19
|
import { sessionPromptContext_build } from '@fnndsc/brasa';
|
|
20
|
-
import {
|
|
20
|
+
import { chrisContext } from '@fnndsc/cumin';
|
|
21
|
+
import { identity_forSession, berth_write, berth_read, berth_path, berthUrl_isAlive, DISCONNECTED_IDENTITY } from './berth.js';
|
|
21
22
|
/** The daemon sink forwards live command output to the executing surface. */
|
|
22
23
|
class DaemonSink {
|
|
23
24
|
daemon;
|
|
@@ -49,6 +50,24 @@ export async function daemon_launch(engine) {
|
|
|
49
50
|
if (chalk.level < 1) {
|
|
50
51
|
chalk.level = 3;
|
|
51
52
|
}
|
|
53
|
+
// Key the berth by the CUBE identity this daemon hosts, so several daemons —
|
|
54
|
+
// one per identity — can advertise on one machine. A daemon with no restored
|
|
55
|
+
// session (disconnected standalone start) falls back to a sentinel identity,
|
|
56
|
+
// matching the disconnected prompt context, so it stays discoverable.
|
|
57
|
+
const cubeUrl = await chrisContext.ChRISURL_get();
|
|
58
|
+
const cubeUser = await chrisContext.ChRISuser_get();
|
|
59
|
+
const identity = identity_forSession(cubeUser, cubeUrl);
|
|
60
|
+
// Guard against a split-brain second daemon for this identity: if one is
|
|
61
|
+
// already live, point the operator at it and refuse rather than host a rival
|
|
62
|
+
// and orphan the running one's berth. This covers both launch paths (chell
|
|
63
|
+
// --daemon and the standalone calypso binary), since both land here.
|
|
64
|
+
const existing = berth_read(identity);
|
|
65
|
+
if (existing && (await berthUrl_isAlive(existing.url))) {
|
|
66
|
+
const attachHint = identity === DISCONNECTED_IDENTITY ? '' : ` ${identity}`;
|
|
67
|
+
console.error(chalk.red(`[!] A CALYPSO daemon for ${identity} is already running at ${existing.url}`));
|
|
68
|
+
console.error(chalk.gray(` attach with: chell --remote${attachHint}`));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
52
71
|
const token = token_generate();
|
|
53
72
|
const daemon = new CalypsoDaemon({
|
|
54
73
|
engine,
|
|
@@ -73,10 +92,13 @@ export async function daemon_launch(engine) {
|
|
|
73
92
|
surface_set(surface);
|
|
74
93
|
const port = await daemon.start();
|
|
75
94
|
const url = `ws://127.0.0.1:${port}`;
|
|
76
|
-
|
|
95
|
+
const berth = { identity, url, token };
|
|
96
|
+
berth_write(berth);
|
|
97
|
+
const attachHint = identity === DISCONNECTED_IDENTITY ? '' : ` ${identity}`;
|
|
77
98
|
console.log(chalk.green(`[+] CALYPSO daemon listening on ${url}`));
|
|
99
|
+
console.log(chalk.gray(` identity: ${identity}`));
|
|
78
100
|
console.log(chalk.gray(` token: ${token}`));
|
|
79
|
-
console.log(chalk.gray(`
|
|
80
|
-
console.log(chalk.gray(
|
|
101
|
+
console.log(chalk.gray(` berth: ${berth_path(identity)}`));
|
|
102
|
+
console.log(chalk.gray(` attach a surface with: chell --remote${attachHint}`));
|
|
81
103
|
}
|
|
82
104
|
//# sourceMappingURL=launch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../src/daemon/launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAmB,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAiF,MAAM,eAAe,CAAC;AAC3H,OAAO,EAAE,0BAA0B,EAA6B,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../src/daemon/launch.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,3 +19,4 @@ export { token_generate, token_writeFile, token_matches } from './daemon/token.j
|
|
|
19
19
|
export { CalypsoDaemon, type DaemonOptions, type EditOutcome } from './daemon/server.js';
|
|
20
20
|
export { daemon_launch } from './daemon/launch.js';
|
|
21
21
|
export { discovery_read, discovery_write, discovery_path, type Discovery } from './daemon/discovery.js';
|
|
22
|
+
export { identity_normalise, identity_forSession, DISCONNECTED_IDENTITY, berthKey_compute, berthDir_path, berth_path, berth_write, berth_read, berthAll_read, berth_remove, berthUrl_isAlive, LocalBerthResolver, type Berth, type BerthResolver, type BerthLivenessProbe, } from './daemon/berth.js';
|
package/dist/index.js
CHANGED
|
@@ -18,4 +18,5 @@ export { token_generate, token_writeFile, token_matches } from './daemon/token.j
|
|
|
18
18
|
export { CalypsoDaemon } from './daemon/server.js';
|
|
19
19
|
export { daemon_launch } from './daemon/launch.js';
|
|
20
20
|
export { discovery_read, discovery_write, discovery_path } from './daemon/discovery.js';
|
|
21
|
+
export { identity_normalise, identity_forSession, DISCONNECTED_IDENTITY, berthKey_compute, berthDir_path, berth_path, berth_write, berth_read, berthAll_read, berth_remove, berthUrl_isAlive, LocalBerthResolver, } from './daemon/berth.js';
|
|
21
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GAEtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,YAAY,GAEb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAwC,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAkB,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GAEtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,YAAY,GAEb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAwC,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAkB,MAAM,uBAAuB,CAAC;AACxG,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,GAInB,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fnndsc/calypso",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The CALYPSO wire contract: typed protocol schemas and boundary validation for the ChRIS session daemon",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"typescript": "^5.0.0"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@fnndsc/brasa": "^0.
|
|
54
|
+
"@fnndsc/brasa": "^0.8.0",
|
|
55
55
|
"@fnndsc/cumin": "^3.7.0",
|
|
56
56
|
"chalk": "^4.1.2",
|
|
57
57
|
"ws": "^8.18.0",
|