@onlyne/lib 3.0.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 +6 -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/dist/index.d.ts +20 -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 -1549
- package/src/core.ts +0 -114
- package/src/discovery.ts +0 -267
- package/src/domains.ts +0 -210
- package/src/history.ts +0 -129
- package/src/http.ts +0 -841
- package/src/index.ts +0 -18
- package/src/keys.ts +0 -632
- package/src/memory.ts +0 -34
- package/src/messages.ts +0 -398
- package/src/node.ts +0 -56
- package/src/resources.ts +0 -745
- package/src/threads.ts +0 -350
- package/src/transport.ts +0 -204
- package/src/types.ts +0 -383
package/dist/stream.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { OnlyneError, canonical, fail, same } from "./core.js";
|
|
2
|
+
const STREAM_TICK_MS = 15_000;
|
|
3
|
+
const STREAM_MAX_PAGES = 1_000;
|
|
4
|
+
/** A resume cursor this binding issues: a decimal event position bound to one stream scope. */
|
|
5
|
+
function eventCursor(value) {
|
|
6
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
7
|
+
return undefined;
|
|
8
|
+
if (!('after' in value) || !('scope' in value))
|
|
9
|
+
return undefined;
|
|
10
|
+
const { after, scope } = value;
|
|
11
|
+
if (typeof after !== 'string' || !/^(0|[1-9][0-9]*)$/.test(after))
|
|
12
|
+
return undefined;
|
|
13
|
+
return { scope, after };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Polls the event page on a timer and writes SSE frames. Every frame carries its own `id:`: a
|
|
17
|
+
* cursor bound to this node, actor, ThreadRef and query scope, positioned after the event the
|
|
18
|
+
* frame delivered. A frame that reused one page cursor would replay the whole page on resume.
|
|
19
|
+
* The resume value is validated against that same scope before the response exists, the first
|
|
20
|
+
* page is fetched up front so a lost credential or expired cursor answers with an HTTP error
|
|
21
|
+
* instead of a 200 stream, and every later page re-checks the credential.
|
|
22
|
+
*/
|
|
23
|
+
export async function eventStream({ ctx, messages, keys, trust }, request, auth, ref) {
|
|
24
|
+
const encoder = new TextEncoder();
|
|
25
|
+
const scope = { ref, actor: auth.actor, kind: 'events' };
|
|
26
|
+
const resume = request.headers.get('last-event-id');
|
|
27
|
+
let cursor;
|
|
28
|
+
if (resume !== null && resume.length > 0) {
|
|
29
|
+
let decoded;
|
|
30
|
+
try {
|
|
31
|
+
decoded = JSON.parse(decodeURIComponent(resume));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
fail('invalid_request', 'Last-Event-ID is not a cursor this binding issues.');
|
|
35
|
+
}
|
|
36
|
+
const parsed = eventCursor(decoded);
|
|
37
|
+
if (parsed === undefined || !same(parsed.scope, scope)) {
|
|
38
|
+
fail('invalid_request', 'Last-Event-ID belongs to another node, actor or thread.');
|
|
39
|
+
}
|
|
40
|
+
cursor = resume;
|
|
41
|
+
}
|
|
42
|
+
let tick;
|
|
43
|
+
let running = false;
|
|
44
|
+
let done = false;
|
|
45
|
+
let detach = () => { };
|
|
46
|
+
const write = (controller, text) => {
|
|
47
|
+
if (done)
|
|
48
|
+
return;
|
|
49
|
+
try {
|
|
50
|
+
controller.enqueue(encoder.encode(text));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// The consumer closed the stream; release the tick and the abort listener with it.
|
|
54
|
+
done = true;
|
|
55
|
+
clearInterval(tick);
|
|
56
|
+
detach();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const stop = (controller) => {
|
|
60
|
+
if (done)
|
|
61
|
+
return;
|
|
62
|
+
done = true;
|
|
63
|
+
clearInterval(tick);
|
|
64
|
+
detach();
|
|
65
|
+
try {
|
|
66
|
+
controller.close();
|
|
67
|
+
}
|
|
68
|
+
catch { /* the consumer already closed it */ }
|
|
69
|
+
};
|
|
70
|
+
const emit = (controller, event) => {
|
|
71
|
+
cursor = encodeURIComponent(canonical({ scope, after: event.id }));
|
|
72
|
+
write(controller, `id: ${cursor}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
|
|
73
|
+
};
|
|
74
|
+
const drain = async (controller) => {
|
|
75
|
+
for (let pages = 0; pages < STREAM_MAX_PAGES && !done; pages++) {
|
|
76
|
+
const page = await messages.events(auth, ref, cursor === undefined ? {} : { cursor });
|
|
77
|
+
if (page.items.length === 0) {
|
|
78
|
+
write(controller, ': idle\n\n');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
for (const event of page.items)
|
|
82
|
+
emit(controller, event);
|
|
83
|
+
if (page.next_cursor === null)
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const poll = async (controller) => {
|
|
88
|
+
if (running || done)
|
|
89
|
+
return;
|
|
90
|
+
running = true;
|
|
91
|
+
try {
|
|
92
|
+
const current = keys?.enabled === true
|
|
93
|
+
? ((await trust?.entry(auth.actor))?.state === 'trusted' ? { actor: auth.actor } : null)
|
|
94
|
+
: await ctx.options.plugins.authenticate(request);
|
|
95
|
+
if (current === null || current.actor !== auth.actor) {
|
|
96
|
+
write(controller, `event: error\ndata: ${JSON.stringify({ error: new OnlyneError('forbidden', 'The credential is no longer valid for this stream.').error })}\n\n`);
|
|
97
|
+
stop(controller);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
await drain(controller);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
const onlyne = error instanceof OnlyneError ? error : new OnlyneError('internal', 'The event stream failed.');
|
|
104
|
+
write(controller, `event: error\ndata: ${JSON.stringify({ error: onlyne.error })}\n\n`);
|
|
105
|
+
stop(controller);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
running = false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
// The first page settles authorization and cursor validity while a status code can still say so.
|
|
112
|
+
const first = await messages.events(auth, ref, cursor === undefined ? {} : { cursor });
|
|
113
|
+
const body = new ReadableStream({
|
|
114
|
+
start(controller) {
|
|
115
|
+
for (const event of first.items)
|
|
116
|
+
emit(controller, event);
|
|
117
|
+
if (first.items.length === 0)
|
|
118
|
+
write(controller, ': idle\n\n');
|
|
119
|
+
if (request.signal.aborted) {
|
|
120
|
+
stop(controller);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const onAbort = () => stop(controller);
|
|
124
|
+
detach = () => request.signal.removeEventListener('abort', onAbort);
|
|
125
|
+
request.signal.addEventListener('abort', onAbort, { once: true });
|
|
126
|
+
tick = setInterval(() => { void poll(controller); }, STREAM_TICK_MS);
|
|
127
|
+
if (first.next_cursor !== null)
|
|
128
|
+
void poll(controller);
|
|
129
|
+
},
|
|
130
|
+
cancel() {
|
|
131
|
+
done = true;
|
|
132
|
+
clearInterval(tick);
|
|
133
|
+
detach();
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
return new Response(body, {
|
|
137
|
+
status: 200,
|
|
138
|
+
headers: { 'content-type': 'text/event-stream', 'cache-control': 'no-store', connection: 'keep-alive' },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Context } from './core.ts';
|
|
2
|
+
import type { Auth, Entry, Grant, JoinedThread, Member, Mutation, Page, PageOptions, ReplyPermit, Thread, ThreadDescription, ThreadRef, Transaction } from './types.ts';
|
|
3
|
+
/** One reserved default-thread id per owner: omitted targets land here, and the id is never reused. */
|
|
4
|
+
export declare const DEFAULT_THREAD = "thr-default";
|
|
5
|
+
/** Reads a thread record under the caller's authority over its owner. */
|
|
6
|
+
export declare function getThread(tx: Transaction, ctx: Context, ref: ThreadRef): Promise<Thread>;
|
|
7
|
+
/**
|
|
8
|
+
* Read authority for a thread: the owner reads everything; any other actor reads
|
|
9
|
+
* only as an active member holding read whose current read_scope admits the entry.
|
|
10
|
+
* The scope is evaluated at read time, never stored on the entry.
|
|
11
|
+
*/
|
|
12
|
+
export declare function canRead(tx: Transaction, actor: string, ref: ThreadRef, entry?: Entry): Promise<boolean>;
|
|
13
|
+
export declare class ThreadService {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(ctx: Context);
|
|
16
|
+
/** @internal Called by OnlyneNode so grant notices wake the maintenance loop immediately. */
|
|
17
|
+
bindLoop(waker: {
|
|
18
|
+
wakeImmediate(): void;
|
|
19
|
+
}): void;
|
|
20
|
+
create(auth: Auth, mutation: Mutation & {
|
|
21
|
+
title: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
default?: boolean;
|
|
24
|
+
}): Promise<Thread>;
|
|
25
|
+
close(auth: Auth, ref: ThreadRef, mutation: Mutation): Promise<Thread>;
|
|
26
|
+
list(auth: Auth, options?: PageOptions): Promise<Page<Thread>>;
|
|
27
|
+
/**
|
|
28
|
+
* Participant view: the threads this node was invited into and does not own, derived only
|
|
29
|
+
* from the records it already holds — the known-owner rows and grant notices `acceptGrant`
|
|
30
|
+
* wrote, the attention and inbox rows that name a thread, and the receipts of messages it
|
|
31
|
+
* sent there. The title, the state and the member table belong to the owner, so they are
|
|
32
|
+
* absent here; a caller that can reach the owner fills them in. This listing never invents
|
|
33
|
+
* a member it could not read.
|
|
34
|
+
*/
|
|
35
|
+
joined(auth: Auth, options?: PageOptions): Promise<Page<JoinedThread>>;
|
|
36
|
+
describe(auth: Auth, ref: ThreadRef): Promise<ThreadDescription>;
|
|
37
|
+
member(auth: Auth, ref: ThreadRef, peer: string, patch: Partial<Member>, mutation: Mutation): Promise<Member>;
|
|
38
|
+
members(auth: Auth, ref: ThreadRef, options?: PageOptions): Promise<Page<Member>>;
|
|
39
|
+
defaultThread(auth: Auth): Promise<ThreadRef>;
|
|
40
|
+
/**
|
|
41
|
+
* Owner-side notice outbox: every grant notice this node issued that has no ack yet.
|
|
42
|
+
* Only the owner calling as ctx.node may read this list; each item carries recipient
|
|
43
|
+
* so the client knows where to POST the full notice.
|
|
44
|
+
*/
|
|
45
|
+
notices(auth: Auth, options?: PageOptions): Promise<Page<Grant>>;
|
|
46
|
+
/**
|
|
47
|
+
* Recipient view: the grants this node accepted from owners, until it confirms each one.
|
|
48
|
+
* A missed push is fetched over HTTP and processed with acceptGrant; this list is what
|
|
49
|
+
* the confirmation pass walks to close the owner's notice.
|
|
50
|
+
*/
|
|
51
|
+
grants(auth: Auth, options?: PageOptions): Promise<Page<Grant>>;
|
|
52
|
+
/**
|
|
53
|
+
* Owner-side evidence for a recipient repairing its own lost grant and known rows: every
|
|
54
|
+
* membership of this node that is still active for the caller, with its notice. An acked
|
|
55
|
+
* notice is included, because the caller's rebuilding store cannot distinguish it from a
|
|
56
|
+
* notice that was never sent; a revoked membership and a superseded revision are not,
|
|
57
|
+
* because their notice id is the member revision they replaced.
|
|
58
|
+
*/
|
|
59
|
+
issued(auth: Auth, options?: PageOptions): Promise<Page<Grant>>;
|
|
60
|
+
/** Recipient side: records that the owner confirmed this grant, so it is not confirmed twice. */
|
|
61
|
+
ackGrantLocally(auth: Auth, ref: ThreadRef, id: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Recipient side of grant acceptance: an owner pushes us a notice we received during
|
|
64
|
+
* a prior join. We store both the notice and the known-owner record keyed owner+threadid.
|
|
65
|
+
* Caller is the owner the notice names, notice is addressed to our node, thread stays on owner.
|
|
66
|
+
*
|
|
67
|
+
* A notice that names `previous_thread_ref` is a re-issue after its owner changed identity:
|
|
68
|
+
* the ref it names is the one this node learned before, so that known row is dropped. Two
|
|
69
|
+
* rows for one thread would make every reconciliation pass pull the dead owner.
|
|
70
|
+
*/
|
|
71
|
+
acceptGrant(auth: Auth, grant: Grant): Promise<Grant>;
|
|
72
|
+
/**
|
|
73
|
+
* Acknowledge a notice on the owner node: owner receives our confirmation, updates
|
|
74
|
+
* the owner-issued notice to acked:true, stops retries. Caller must be recipient of the notice.
|
|
75
|
+
*/
|
|
76
|
+
ackGrant(auth: Auth, id: string, mutation: Mutation): Promise<Grant>;
|
|
77
|
+
permits(auth: Auth, permit: ReplyPermit, mutation: Mutation): Promise<ReplyPermit>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=threads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
|