@onlyne/lib 3.1.0 → 3.2.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/README.md +4 -3
- package/dist/awaited.d.ts +43 -0
- package/dist/awaited.d.ts.map +1 -0
- package/dist/awaited.js +82 -0
- package/dist/awaited.js.map +1 -0
- package/dist/client.d.ts +140 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1772 -0
- package/dist/client.js.map +1 -0
- package/dist/core.d.ts +36 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +122 -0
- package/dist/core.js.map +1 -0
- package/dist/delivery.d.ts +120 -0
- package/dist/delivery.d.ts.map +1 -0
- package/dist/delivery.js +117 -0
- package/dist/delivery.js.map +1 -0
- package/dist/discovery.d.ts +35 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +306 -0
- package/dist/discovery.js.map +1 -0
- package/dist/domains.d.ts +29 -0
- package/dist/domains.d.ts.map +1 -0
- package/dist/domains.js +267 -0
- package/dist/domains.js.map +1 -0
- package/dist/history.d.ts +13 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +143 -0
- package/dist/history.js.map +1 -0
- package/dist/http.d.ts +20 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +88 -0
- package/dist/http.js.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +97 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +679 -0
- package/dist/keys.js.map +1 -0
- package/dist/memory.d.ts +9 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +35 -0
- package/dist/memory.js.map +1 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +480 -0
- package/dist/messages.js.map +1 -0
- package/dist/node.d.ts +26 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +59 -0
- package/dist/node.js.map +1 -0
- package/dist/resolve.d.ts +18 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +37 -0
- package/dist/resolve.js.map +1 -0
- package/dist/resources.d.ts +25 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +782 -0
- package/dist/resources.js.map +1 -0
- package/dist/routes/domains.d.ts +4 -0
- package/dist/routes/domains.d.ts.map +1 -0
- package/dist/routes/domains.js +42 -0
- package/dist/routes/domains.js.map +1 -0
- package/dist/routes/grants.d.ts +8 -0
- package/dist/routes/grants.d.ts.map +1 -0
- package/dist/routes/grants.js +32 -0
- package/dist/routes/grants.js.map +1 -0
- package/dist/routes/public.d.ts +4 -0
- package/dist/routes/public.d.ts.map +1 -0
- package/dist/routes/public.js +62 -0
- package/dist/routes/public.js.map +1 -0
- package/dist/routes/resources.d.ts +8 -0
- package/dist/routes/resources.d.ts.map +1 -0
- package/dist/routes/resources.js +87 -0
- package/dist/routes/resources.js.map +1 -0
- package/dist/routes/shared.d.ts +77 -0
- package/dist/routes/shared.d.ts.map +1 -0
- package/dist/routes/shared.js +349 -0
- package/dist/routes/shared.js.map +1 -0
- package/dist/routes/threads.d.ts +8 -0
- package/dist/routes/threads.d.ts.map +1 -0
- package/dist/routes/threads.js +113 -0
- package/dist/routes/threads.js.map +1 -0
- package/dist/routes/trust.d.ts +4 -0
- package/dist/routes/trust.d.ts.map +1 -0
- package/dist/routes/trust.js +36 -0
- package/dist/routes/trust.js.map +1 -0
- package/dist/stream.d.ts +20 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +141 -0
- package/dist/stream.js.map +1 -0
- package/dist/threads.d.ts +79 -0
- package/dist/threads.d.ts.map +1 -0
- package/dist/threads.js +480 -0
- package/dist/threads.js.map +1 -0
- package/dist/transport.d.ts +45 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +175 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +809 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +16 -8
- package/src/client.ts +0 -1745
- package/src/core.ts +0 -114
- package/src/discovery.ts +0 -275
- package/src/domains.ts +0 -213
- package/src/history.ts +0 -139
- package/src/http.ts +0 -852
- package/src/keys.ts +0 -642
- package/src/memory.ts +0 -34
- package/src/messages.ts +0 -409
- package/src/node.ts +0 -63
- package/src/resolve.ts +0 -39
- package/src/resources.ts +0 -745
- package/src/threads.ts +0 -409
- package/src/transport.ts +0 -211
- package/src/types.ts +0 -428
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Context } from './core.ts';
|
|
2
|
+
import type { DiscoveryCandidate, DiscoveryRecord, DomainId, NodeId, Page, PageOptions, Target } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The local discovery catalog. It holds one record per (node, address), so two addresses for the
|
|
5
|
+
* same node stay two observations until a direct answer shows they are the same instance.
|
|
6
|
+
*
|
|
7
|
+
* Nothing here trusts a third party: a record enters the catalog as a candidate clue, and only a
|
|
8
|
+
* direct `GET /description` makes it usable for routing.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DiscoveryService {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(ctx: Context, fetcher?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>);
|
|
13
|
+
/** Whether this process has directly verified this identity at least once. */
|
|
14
|
+
known(node_id: NodeId): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Reads `base_url`'s service description and records what it declares. A failed observation
|
|
17
|
+
* keeps the last verified identity of the address and stores the failure beside it.
|
|
18
|
+
*/
|
|
19
|
+
observe(base_url: string, source: string, expectedNode?: NodeId, signal?: AbortSignal): Promise<DiscoveryRecord>;
|
|
20
|
+
/** The public candidate exchange: verified, fresh and reachable from somewhere other than this host. */
|
|
21
|
+
list(options?: PageOptions): Promise<Page<DiscoveryCandidate>>;
|
|
22
|
+
/** Every observation this node holds, expired and failed ones included. */
|
|
23
|
+
listRecords(): Promise<DiscoveryRecord[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Rechecks every recorded address for one identity. Two live instances of one NodeId are a
|
|
26
|
+
* conflict; the same instance at several addresses is one target. An address that no longer
|
|
27
|
+
* answers is skipped, so a restarted node's new address is usable immediately.
|
|
28
|
+
*/
|
|
29
|
+
resolve(node_id: NodeId): Promise<Target>;
|
|
30
|
+
/** Verified, fresh candidates that declare exactly this region. */
|
|
31
|
+
candidates(domain_id: DomainId): Promise<NodeId[]>;
|
|
32
|
+
/** Reobserves every recorded address. One unreachable candidate commits its own failure and no other. */
|
|
33
|
+
refresh(signal?: AbortSignal): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,KAAK,EACV,kBAAkB,EAAE,eAAe,EAAE,QAAQ,EAAW,MAAM,EAAE,IAAI,EAAE,WAAW,EAAsB,MAAM,EAC9G,MAAM,YAAY,CAAC;AAyFpB;;;;;;GAMG;AACH,qBAAa,gBAAgB;;gBAMf,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAS;IAKnH,8EAA8E;IAC9E,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI/B;;;OAGG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAiCtH,wGAAwG;IAClG,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAUxE,2EAA2E;IACrE,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAK/C;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB/C,mEAAmE;IAC7D,UAAU,CAAC,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAcxD,yGAAyG;IACnG,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CA+DnD"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { OnlyneError, fail, key, page } from "./core.js";
|
|
2
|
+
import { membershipRecord, validateDomainId } from "./domains.js";
|
|
3
|
+
/** How long candidate evidence stays current. An expired record is history, not a live address. */
|
|
4
|
+
const FRESH_MS = 120_000;
|
|
5
|
+
const PREFIX = 'discovery';
|
|
6
|
+
function iso(at) { return new Date(at).toISOString(); }
|
|
7
|
+
function order(a, b) { return a < b ? -1 : a > b ? 1 : 0; }
|
|
8
|
+
function position(candidate) {
|
|
9
|
+
return `${candidate.node_id}\u0000${candidate.instance_id}\u0000${candidate.base_url}`;
|
|
10
|
+
}
|
|
11
|
+
function hostOf(url) { return url.hostname.replace(/^\[|\]$/g, '').toLowerCase(); }
|
|
12
|
+
/** Loopback may be spoken to over plain HTTP; every other peer must use HTTPS. */
|
|
13
|
+
function loopback(url) {
|
|
14
|
+
const host = hostOf(url);
|
|
15
|
+
return host === 'localhost' || host === '::1' || /^127\./.test(host);
|
|
16
|
+
}
|
|
17
|
+
/** True for an address another host could use. Loopback, wildcard and unscoped link-local stay home. */
|
|
18
|
+
function exchangeable(value, allowLoopback = false) {
|
|
19
|
+
let url;
|
|
20
|
+
try {
|
|
21
|
+
url = new URL(value);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
27
|
+
return false;
|
|
28
|
+
const host = hostOf(url);
|
|
29
|
+
if ((!allowLoopback && loopback(url)) || host === '0.0.0.0' || host === '::')
|
|
30
|
+
return false;
|
|
31
|
+
if (/^169\.254\./.test(host))
|
|
32
|
+
return false;
|
|
33
|
+
return !(/^fe80:/.test(host) && !host.includes('%'));
|
|
34
|
+
}
|
|
35
|
+
function address(value) {
|
|
36
|
+
let url;
|
|
37
|
+
try {
|
|
38
|
+
url = new URL(value);
|
|
39
|
+
}
|
|
40
|
+
catch { /* reported below */ }
|
|
41
|
+
if (url === undefined)
|
|
42
|
+
fail('invalid_request', 'A discovery address must be an absolute URL.');
|
|
43
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
44
|
+
fail('invalid_request', 'A discovery address must be HTTP or HTTPS.');
|
|
45
|
+
if (url.search !== '' || url.hash !== '')
|
|
46
|
+
fail('invalid_request', 'A discovery address carries no query or fragment.');
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
function field(value, name) {
|
|
50
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
51
|
+
fail('unavailable', `The candidate published no ${name}.`);
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
function isFailureRecord(value) {
|
|
55
|
+
if (value === null || typeof value !== 'object' || !('code' in value) || !('message' in value))
|
|
56
|
+
return false;
|
|
57
|
+
return typeof value.code === 'string' && typeof value.message === 'string';
|
|
58
|
+
}
|
|
59
|
+
function names(value, what) {
|
|
60
|
+
if (!Array.isArray(value) || !value.every(entry => typeof entry === 'string'))
|
|
61
|
+
fail('unavailable', `The candidate published unreadable ${what}.`);
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A service description is the candidate's own declaration. It must speak onlyne/3, name an
|
|
66
|
+
* instance, and publish a membership that agrees with the identity it claims.
|
|
67
|
+
*/
|
|
68
|
+
function published(value) {
|
|
69
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
70
|
+
fail('unavailable', 'The candidate returned no service description.');
|
|
71
|
+
if (!('protocol' in value) || !('node_id' in value) || !('instance_id' in value) || !('base_url' in value)
|
|
72
|
+
|| !('features' in value) || !('authentication' in value) || !('membership' in value) || !('domain' in value)) {
|
|
73
|
+
fail('unavailable', 'The candidate returned an incomplete service description.');
|
|
74
|
+
}
|
|
75
|
+
if (value.protocol !== 'onlyne/3')
|
|
76
|
+
fail('unavailable', 'The candidate does not speak onlyne/3.');
|
|
77
|
+
const node_id = field(value.node_id, 'node identity');
|
|
78
|
+
const instance_id = field(value.instance_id, 'instance identity');
|
|
79
|
+
const base_url = field(value.base_url, 'base address');
|
|
80
|
+
let parsed;
|
|
81
|
+
try {
|
|
82
|
+
parsed = new URL(base_url);
|
|
83
|
+
}
|
|
84
|
+
catch { /* reported below */ }
|
|
85
|
+
if (parsed === undefined)
|
|
86
|
+
fail('unavailable', 'The candidate published an unreadable base address.');
|
|
87
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
|
|
88
|
+
fail('unavailable', 'The candidate published a base address this protocol cannot use.');
|
|
89
|
+
const features = names(value.features, 'features');
|
|
90
|
+
const authentication = names(value.authentication, 'authentication schemes');
|
|
91
|
+
const membership = membershipRecord(value.membership);
|
|
92
|
+
if (membership === undefined)
|
|
93
|
+
fail('unavailable', 'The candidate published an unreadable membership.');
|
|
94
|
+
if (membership !== null && membership.node_id !== node_id)
|
|
95
|
+
fail('unavailable', 'The candidate published a membership for another node.');
|
|
96
|
+
const domain = value.domain;
|
|
97
|
+
if (domain !== null && typeof domain !== 'string')
|
|
98
|
+
fail('unavailable', 'The candidate published an unreadable region.');
|
|
99
|
+
if (domain !== null && (membership === null || membership.domain_id !== domain))
|
|
100
|
+
fail('unavailable', 'The candidate published a region its membership does not match.');
|
|
101
|
+
return {
|
|
102
|
+
protocol: 'onlyne/3', node_id, instance_id, base_url,
|
|
103
|
+
features, authentication, domain, membership,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The local discovery catalog. It holds one record per (node, address), so two addresses for the
|
|
108
|
+
* same node stay two observations until a direct answer shows they are the same instance.
|
|
109
|
+
*
|
|
110
|
+
* Nothing here trusts a third party: a record enters the catalog as a candidate clue, and only a
|
|
111
|
+
* direct `GET /description` makes it usable for routing.
|
|
112
|
+
*/
|
|
113
|
+
export class DiscoveryService {
|
|
114
|
+
/** Directly verified identities in this process; lets admission policies answer without nested storage work. */
|
|
115
|
+
#known = new Set();
|
|
116
|
+
#ctx;
|
|
117
|
+
#fetcher;
|
|
118
|
+
constructor(ctx, fetcher = fetch) {
|
|
119
|
+
this.#ctx = ctx;
|
|
120
|
+
this.#fetcher = fetcher;
|
|
121
|
+
}
|
|
122
|
+
/** Whether this process has directly verified this identity at least once. */
|
|
123
|
+
known(node_id) { return this.#known.has(node_id); }
|
|
124
|
+
get #allowLoopback() { return Boolean(this.#ctx.options.plugins.allow_loopback); }
|
|
125
|
+
/**
|
|
126
|
+
* Reads `base_url`'s service description and records what it declares. A failed observation
|
|
127
|
+
* keeps the last verified identity of the address and stores the failure beside it.
|
|
128
|
+
*/
|
|
129
|
+
async observe(base_url, source, expectedNode, signal) {
|
|
130
|
+
if (source.length === 0)
|
|
131
|
+
fail('invalid_request', 'A discovery record needs a source.');
|
|
132
|
+
const url = address(base_url);
|
|
133
|
+
if (url.protocol === 'http:' && !loopback(url))
|
|
134
|
+
fail('unavailable', 'Plain HTTP is limited to loopback; cross-host candidates must use HTTPS.');
|
|
135
|
+
const at = this.#ctx.now();
|
|
136
|
+
let description;
|
|
137
|
+
try {
|
|
138
|
+
description = published(await this.#read(url, signal));
|
|
139
|
+
if (expectedNode !== undefined && description.node_id !== expectedNode) {
|
|
140
|
+
fail('unavailable', 'The candidate description names another node.');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (signal?.aborted)
|
|
145
|
+
throw signal.reason;
|
|
146
|
+
await this.#failed(base_url, source, at, error instanceof OnlyneError ? error.error : { code: 'internal', message: 'The candidate observation failed.', retryable: false });
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
const record = {
|
|
150
|
+
node_id: description.node_id,
|
|
151
|
+
instance_id: description.instance_id,
|
|
152
|
+
base_url,
|
|
153
|
+
last_seen: iso(at),
|
|
154
|
+
source,
|
|
155
|
+
received_at: iso(at),
|
|
156
|
+
expires_at: iso(at + FRESH_MS),
|
|
157
|
+
verified_at: iso(at),
|
|
158
|
+
membership: description.membership,
|
|
159
|
+
};
|
|
160
|
+
await this.#ctx.storage.transaction(async (tx) => { await tx.put(key(PREFIX, record.node_id, base_url), record); });
|
|
161
|
+
this.#known.add(record.node_id);
|
|
162
|
+
return record;
|
|
163
|
+
}
|
|
164
|
+
/** The public candidate exchange: verified, fresh and reachable from somewhere other than this host. */
|
|
165
|
+
async list(options = {}) {
|
|
166
|
+
const at = this.#ctx.now();
|
|
167
|
+
const candidates = (await this.listRecords())
|
|
168
|
+
.filter(record => record.verified_at !== undefined && record.instance_id !== ''
|
|
169
|
+
&& exchangeable(record.base_url, this.#allowLoopback) && Date.parse(record.expires_at) > at)
|
|
170
|
+
.map(record => ({ node_id: record.node_id, instance_id: record.instance_id, base_url: record.base_url, last_seen: record.last_seen }))
|
|
171
|
+
.sort((a, b) => order(position(a), position(b)));
|
|
172
|
+
return page(candidates, options, { kind: 'discovery', node: this.#ctx.node }, position);
|
|
173
|
+
}
|
|
174
|
+
/** Every observation this node holds, expired and failed ones included. */
|
|
175
|
+
async listRecords() {
|
|
176
|
+
const rows = await this.#ctx.storage.transaction(tx => tx.scan(`${PREFIX}/`));
|
|
177
|
+
return rows.map(row => row.value).sort((a, b) => order(position(a), position(b)));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Rechecks every recorded address for one identity. Two live instances of one NodeId are a
|
|
181
|
+
* conflict; the same instance at several addresses is one target. An address that no longer
|
|
182
|
+
* answers is skipped, so a restarted node's new address is usable immediately.
|
|
183
|
+
*/
|
|
184
|
+
async resolve(node_id) {
|
|
185
|
+
const records = (await this.listRecords()).filter(record => record.node_id === node_id);
|
|
186
|
+
if (records.length === 0)
|
|
187
|
+
fail('not_found', 'No discovery record names this node.');
|
|
188
|
+
const answers = await Promise.all(records.map(async (record) => {
|
|
189
|
+
try {
|
|
190
|
+
return await this.observe(record.base_url, record.source, node_id);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
}));
|
|
196
|
+
const live = new Map();
|
|
197
|
+
for (const record of answers) {
|
|
198
|
+
if (record === undefined)
|
|
199
|
+
continue;
|
|
200
|
+
const addresses = live.get(record.instance_id) ?? [];
|
|
201
|
+
addresses.push(record.base_url);
|
|
202
|
+
live.set(record.instance_id, addresses);
|
|
203
|
+
}
|
|
204
|
+
if (live.size > 1)
|
|
205
|
+
fail('conflict', 'More than one live instance answers for this node.');
|
|
206
|
+
const entries = [...live.entries()];
|
|
207
|
+
if (entries.length === 0)
|
|
208
|
+
fail('unavailable', 'No recorded address for this node answered.');
|
|
209
|
+
const addresses = entries[0][1].sort(order);
|
|
210
|
+
return { node_id, base_url: addresses[0] };
|
|
211
|
+
}
|
|
212
|
+
/** Verified, fresh candidates that declare exactly this region. */
|
|
213
|
+
async candidates(domain_id) {
|
|
214
|
+
validateDomainId(domain_id);
|
|
215
|
+
const at = this.#ctx.now();
|
|
216
|
+
const nodes = new Set();
|
|
217
|
+
for (const record of await this.listRecords()) {
|
|
218
|
+
if (record.verified_at === undefined || record.instance_id === '')
|
|
219
|
+
continue;
|
|
220
|
+
if (Date.parse(record.expires_at) <= at || !exchangeable(record.base_url, this.#allowLoopback))
|
|
221
|
+
continue;
|
|
222
|
+
const membership = record.membership;
|
|
223
|
+
if (membership === null || membership === undefined || membership.state !== 'active' || membership.domain_id !== domain_id)
|
|
224
|
+
continue;
|
|
225
|
+
nodes.add(record.node_id);
|
|
226
|
+
}
|
|
227
|
+
return [...nodes].sort(order);
|
|
228
|
+
}
|
|
229
|
+
/** Reobserves every recorded address. One unreachable candidate commits its own failure and no other. */
|
|
230
|
+
async refresh(signal) {
|
|
231
|
+
const records = await this.listRecords();
|
|
232
|
+
await Promise.all(records.map(record => this.observe(record.base_url, record.source, record.node_id, signal).then(() => undefined, () => undefined)));
|
|
233
|
+
if (signal?.aborted)
|
|
234
|
+
throw signal.reason;
|
|
235
|
+
}
|
|
236
|
+
async #read(url, signal) {
|
|
237
|
+
const target = new URL('./description', url.href.endsWith('/') ? url.href : `${url.href}/`);
|
|
238
|
+
const controller = new AbortController();
|
|
239
|
+
const relay = () => controller.abort(signal?.reason);
|
|
240
|
+
if (signal?.aborted)
|
|
241
|
+
controller.abort(signal.reason);
|
|
242
|
+
else
|
|
243
|
+
signal?.addEventListener('abort', relay, { once: true });
|
|
244
|
+
const gate = Promise.withResolvers();
|
|
245
|
+
controller.signal.addEventListener('abort', () => gate.reject(controller.signal.reason), { once: true });
|
|
246
|
+
const timeout = setTimeout(() => controller.abort(new OnlyneError('unavailable', 'The candidate description lookup timed out.')), this.#ctx.options.wait_ms ?? 30_000);
|
|
247
|
+
let response;
|
|
248
|
+
try {
|
|
249
|
+
response = await Promise.race([
|
|
250
|
+
this.#fetcher(target, { method: 'GET', headers: { accept: 'application/json' }, signal: controller.signal }),
|
|
251
|
+
gate.promise,
|
|
252
|
+
]);
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
if (signal?.aborted)
|
|
256
|
+
throw signal.reason;
|
|
257
|
+
throw error instanceof OnlyneError ? error : new OnlyneError('unavailable', 'The candidate could not be reached.');
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
clearTimeout(timeout);
|
|
261
|
+
signal?.removeEventListener('abort', relay);
|
|
262
|
+
}
|
|
263
|
+
let text;
|
|
264
|
+
try {
|
|
265
|
+
text = await response.text();
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
throw new OnlyneError('unavailable', 'The candidate response could not be read.');
|
|
269
|
+
}
|
|
270
|
+
let parsed;
|
|
271
|
+
try {
|
|
272
|
+
parsed = text === '' ? undefined : JSON.parse(text);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
parsed = undefined;
|
|
276
|
+
}
|
|
277
|
+
if (!response.ok) {
|
|
278
|
+
const record = parsed !== null && typeof parsed === 'object' && 'error' in parsed ? parsed.error : parsed;
|
|
279
|
+
if (isFailureRecord(record))
|
|
280
|
+
throw new OnlyneError(record.code, record.message, record.details);
|
|
281
|
+
throw new OnlyneError('unavailable', `The candidate answered HTTP ${response.status} without a service description.`);
|
|
282
|
+
}
|
|
283
|
+
if (parsed === undefined)
|
|
284
|
+
throw new OnlyneError('unavailable', 'The candidate returned no service description.');
|
|
285
|
+
return parsed;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* A failure is recorded beside addresses this node already observed; a clue that never
|
|
289
|
+
* verified leaves no record. A record whose freshness window has already lapsed is
|
|
290
|
+
* deleted instead: a row nobody can reach and nobody would trust as fresh is a
|
|
291
|
+
* candidate that has to be rediscovered, not a permanent entry.
|
|
292
|
+
*/
|
|
293
|
+
async #failed(base_url, source, at, error) {
|
|
294
|
+
await this.#ctx.storage.transaction(async (tx) => {
|
|
295
|
+
const rows = (await tx.scan(`${PREFIX}/`)).filter(row => row.value.base_url === base_url);
|
|
296
|
+
for (const row of rows) {
|
|
297
|
+
if (row.value.verified_at !== undefined) {
|
|
298
|
+
await tx.put(row.key, { ...row.value, source, received_at: iso(at), error });
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
await tx.delete(row.key);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Context } from './core.ts';
|
|
2
|
+
import type { Auth, DomainDiscovery, DomainMembership, DomainMutation, Mutation, PageOptions } from './types.ts';
|
|
3
|
+
export declare function validateDomainId(value: unknown): string;
|
|
4
|
+
/**
|
|
5
|
+
* Shape check for a membership as published on the wire. `null` is a valid declaration of no
|
|
6
|
+
* membership; `undefined` means the value is not a membership at all.
|
|
7
|
+
*/
|
|
8
|
+
export declare function membershipRecord(value: unknown): DomainMembership | null | undefined;
|
|
9
|
+
export declare class DomainService {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(ctx: Context, fetcher?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>);
|
|
12
|
+
/**
|
|
13
|
+
* The node's one declared membership, kept in memory for the public description probe. Once
|
|
14
|
+
* it is known, this answers without entering the transaction queue; the first read hydrates
|
|
15
|
+
* it under a tight bound, and an unhydratable read fails instead of inventing a membership.
|
|
16
|
+
*/
|
|
17
|
+
declared(auth: Auth): Promise<DomainMembership | null>;
|
|
18
|
+
private authenticate;
|
|
19
|
+
private self;
|
|
20
|
+
create(auth: Auth, mutation: Mutation): Promise<DomainMembership>;
|
|
21
|
+
join(auth: Auth, id: string, mutation: DomainMutation): Promise<DomainMembership>;
|
|
22
|
+
leave(auth: Auth, id: string, mutation: DomainMutation): Promise<DomainMembership>;
|
|
23
|
+
private change;
|
|
24
|
+
list(auth: Auth, options?: PageOptions): Promise<import("./types.ts").Page<DomainMembership>>;
|
|
25
|
+
describe(auth: Auth, id: string): Promise<DomainMembership>;
|
|
26
|
+
discover(auth: Auth, id: string, signal?: AbortSignal): Promise<DomainDiscovery>;
|
|
27
|
+
private query;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=domains.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../src/domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAErF,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAe,MAAM,YAAY,CAAC;AAK9H,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKvD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAUpF;AAgCD,qBAAa,aAAa;;gBAKZ,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAS;IAKnH;;;;OAIG;IACG,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuB5D,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,IAAI;IAKN,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiBjE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIjF,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAI1E,MAAM;IA0Bd,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,WAAgB;IAU1C,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAM3D,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;YAgCxE,KAAK;CA0CpB"}
|