@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/README.md
CHANGED
|
@@ -6,10 +6,11 @@ The protocol is specified by the draft RFCs in [`docs/rfcs`](../../docs/rfcs). T
|
|
|
6
6
|
|
|
7
7
|
## Run
|
|
8
8
|
|
|
9
|
-
The package
|
|
9
|
+
The package compiles TypeScript source to standard ESM JavaScript and `.d.ts` declarations under `./dist/`, so Node.js (including inside `node_modules` and Electron ASAR), Bun, and TypeScript consumers load it directly without runtime type-stripping flags.
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
bun install
|
|
13
|
+
bun run build
|
|
13
14
|
bun run check
|
|
14
15
|
bun run test
|
|
15
16
|
```
|
|
@@ -34,9 +35,9 @@ export function serveOnlyne(options: NodeOptions, port: number) {
|
|
|
34
35
|
}
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
`options.base_url` includes `/onlyne/v3
|
|
38
|
+
`options.base_url` includes `/onlyne/v3` (and may be mounted under a URL path prefix such as `/nodes/<id>/onlyne/v3` when sharing a single HTTP listener across local identities). `FetchTransport` permits HTTP on loopback and requires HTTPS for remote hosts. The resolver supplies the remote identity, URL, and authentication headers. The authentication plugin maps each inbound request to its verified actor.
|
|
38
39
|
|
|
39
|
-
The model calls `node.client.msg({ delivery_kind, msg, meta })`. The `decide` plugin returns a typed send, read, thread, resource, or domain action. An unavailable decision returns `decision_unavailable`. Hosts can also call the typed `threads`, `messages`, `resources`, `domains`, and `client.send` interfaces directly.
|
|
40
|
+
The model calls `node.client.msg({ delivery_kind, msg, meta })`. Work-unit correlation travels as first-class `meta.work` (`{ unit, parent?, attempt? }`) on `Message['meta']` and `Action(kind: 'send')`, covered by the message identity digest. The `decide` plugin returns a typed send, read, thread, resource, or domain action. An unavailable decision returns `decision_unavailable`. Hosts can also call the typed `threads`, `messages`, `resources`, `domains`, and `client.send` interfaces directly.
|
|
40
41
|
|
|
41
42
|
A plan whose `response` is `await` keeps `client.send` on the reply. The outcome reports `wait` as `answered`, `timed_out`, or `cancelled`, and an answered one carries `reply` with `reply_body`. The awaited tool result and the automatic attention fragment share one consumption record per `(context, ThreadRef, seq)`. A body already confirmed in that context comes back as `reply_body: 'withheld'` with the arrival facts and the original MessageRef only; a body this result rendered closes the record, so the fragment does not present it again. `runtime.confirmToolResult` reports the tool result the host observed in that context. A record no path confirmed stays open and is replayed.
|
|
42
43
|
|
|
@@ -60,6 +61,8 @@ A resource has one binding — the handler and the highest event it has confirme
|
|
|
60
61
|
|
|
61
62
|
`client.readResources(query)` reads local resources or requests their owner's authenticated endpoint. The `ResourceReadQuery` operations are `list`, `describe`, `log`, `event`, `operations`, and `status`. The `decide` plugin can return `{ kind: 'read', scope: 'resources', query }` to use the same reader through `msg`. Reads create no operation record and do not call a resource driver.
|
|
62
63
|
|
|
64
|
+
A queued entry that projects a resource event (`meta.data.resource_ref`, authenticated by that resource's owner) is checked against the binding before it is injected. If the binding names another handler, the row is settled with `settlement.via === 'handover'`; if this node may no longer read the resource, the row is settled as `undeliverable` with `reason: 'resource-unavailable'`. A transient failure leaves the row owed and is traced as `inbound.resource-check.failed`. Settlement closes the local delivery obligation. It records why delivery ended, and it does not assert that the model read the entry, so no consumption record and no todo are written.
|
|
65
|
+
|
|
63
66
|
`list` accepts concrete `owners`, `page_size`, and `cursor`. Omitted `owners` selects the local node. The result contains `owners: [{ owner, page } | { owner, error }]`, so an unavailable owner remains visible beside successful pages. A cursor selects exactly one owner. The host chooses which owners to include. Other queries name `resource: { owner, id }`. `log` accepts an exclusive `since` event id, `page_size`, and `cursor`. `event` names `event_id`; `status` names `operation_id` and returns the existing operation record. The original actor can read that record after losing resource-read access. `operations` returns only the current actor's records.
|
|
64
67
|
|
|
65
68
|
An operation result is `committed`, `pending`, `aborted`, or `unknown`. `aborted` means the endpoint refused or locally stopped the call and confirmed that no external effect happened; a failure whose side effect cannot be ruled out is `unknown`, keeps the original error in `details`, and stays owed to `node.resources.recover()`, which asks the driver for the outcome by `operation_id`. A caller that stops waiting gets `unknown` while the external call keeps running, and a later driver outcome settles that record. A retried operation is asked for its outcome, never executed a second time.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Entry, Message } from './types.ts';
|
|
2
|
+
/** One in-flight await on a message this node sent: it lives only while its `send` runs. */
|
|
3
|
+
export interface Waiter {
|
|
4
|
+
original: Message;
|
|
5
|
+
expected_author: string;
|
|
6
|
+
/** The sender-local context this await consumes its reply in; absent for a generic caller. */
|
|
7
|
+
local_context?: string;
|
|
8
|
+
outcome: Promise<Entry>;
|
|
9
|
+
settle(entry: Entry): void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Live awaits and the tool-result holds they place, one registry per client. A reply already
|
|
13
|
+
* returned as a tool result holds its body in this registry until the host confirms
|
|
14
|
+
* consumption, so no automatic fragment presents the same body in that context again.
|
|
15
|
+
*/
|
|
16
|
+
export declare class AwaitedReplies {
|
|
17
|
+
#private;
|
|
18
|
+
/** Registered before the network call, so a reply that lands first still finds its waiter. */
|
|
19
|
+
register(record: {
|
|
20
|
+
request: {
|
|
21
|
+
message: Message;
|
|
22
|
+
};
|
|
23
|
+
expected_author: string;
|
|
24
|
+
local_context?: string;
|
|
25
|
+
}): Waiter;
|
|
26
|
+
/** An await ends when its caller leaves; a channel replaced by a newer caller stays chained. */
|
|
27
|
+
release(waiter: Waiter): void;
|
|
28
|
+
/** Releases every live await whose original this entry answers; reports how many. */
|
|
29
|
+
settle(entry: Entry): number;
|
|
30
|
+
/**
|
|
31
|
+
* Whether this entry answers an `await` that owns its body here, optionally only one whose
|
|
32
|
+
* sender-local context is `context`: a waiter still running, or a reply already returned as
|
|
33
|
+
* a tool result and not yet confirmed consumed.
|
|
34
|
+
*/
|
|
35
|
+
waiting(entry: Entry, context?: string): boolean;
|
|
36
|
+
/** Holds one entry's body in one context until its consumption is confirmed. */
|
|
37
|
+
hold(entry: Entry, context: string): void;
|
|
38
|
+
/** Drops one context's hold after its path confirmed the entry's consumption. */
|
|
39
|
+
releaseContext(entry: Entry, context: string): void;
|
|
40
|
+
/** Drops every hold on one entry, for the paths that settle it without a confirmation context. */
|
|
41
|
+
forget(entry: Entry): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=awaited.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"awaited.d.ts","sourceRoot":"","sources":["../src/awaited.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEjD,4FAA4F;AAC5F,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CAC5B;AAED;;;;GAIG;AACH,qBAAa,cAAc;;IAIzB,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAmB5G,gGAAgG;IAChG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7B,qFAAqF;IACrF,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAW5B;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAUhD,gFAAgF;IAChF,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAMzC,iFAAiF;IACjF,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQnD,kGAAkG;IAClG,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAG3B"}
|
package/dist/awaited.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { entryKey, isReply, replyKey } from "./delivery.js";
|
|
2
|
+
/**
|
|
3
|
+
* Live awaits and the tool-result holds they place, one registry per client. A reply already
|
|
4
|
+
* returned as a tool result holds its body in this registry until the host confirms
|
|
5
|
+
* consumption, so no automatic fragment presents the same body in that context again.
|
|
6
|
+
*/
|
|
7
|
+
export class AwaitedReplies {
|
|
8
|
+
#waiters = new Map();
|
|
9
|
+
#held = new Map();
|
|
10
|
+
/** Registered before the network call, so a reply that lands first still finds its waiter. */
|
|
11
|
+
register(record) {
|
|
12
|
+
const original = record.request.message;
|
|
13
|
+
const pending = Promise.withResolvers();
|
|
14
|
+
const slot = replyKey(original);
|
|
15
|
+
const previous = this.#waiters.get(slot);
|
|
16
|
+
const waiter = {
|
|
17
|
+
original,
|
|
18
|
+
expected_author: record.expected_author,
|
|
19
|
+
...(record.local_context === undefined ? {} : { local_context: record.local_context }),
|
|
20
|
+
outcome: pending.promise,
|
|
21
|
+
settle(entry) {
|
|
22
|
+
previous?.settle(entry);
|
|
23
|
+
pending.resolve(entry);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
this.#waiters.set(slot, waiter);
|
|
27
|
+
return waiter;
|
|
28
|
+
}
|
|
29
|
+
/** An await ends when its caller leaves; a channel replaced by a newer caller stays chained. */
|
|
30
|
+
release(waiter) {
|
|
31
|
+
if (this.#waiters.get(replyKey(waiter.original)) === waiter)
|
|
32
|
+
this.#waiters.delete(replyKey(waiter.original));
|
|
33
|
+
}
|
|
34
|
+
/** Releases every live await whose original this entry answers; reports how many. */
|
|
35
|
+
settle(entry) {
|
|
36
|
+
let settled = 0;
|
|
37
|
+
for (const waiter of this.#waiters.values()) {
|
|
38
|
+
if (waiter.expected_author === entry.authenticated_author && isReply(waiter.original, entry)) {
|
|
39
|
+
waiter.settle(entry);
|
|
40
|
+
settled++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return settled;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether this entry answers an `await` that owns its body here, optionally only one whose
|
|
47
|
+
* sender-local context is `context`: a waiter still running, or a reply already returned as
|
|
48
|
+
* a tool result and not yet confirmed consumed.
|
|
49
|
+
*/
|
|
50
|
+
waiting(entry, context) {
|
|
51
|
+
for (const waiter of this.#waiters.values()) {
|
|
52
|
+
if (waiter.expected_author !== entry.authenticated_author || !isReply(waiter.original, entry))
|
|
53
|
+
continue;
|
|
54
|
+
if (context !== undefined && waiter.local_context !== context)
|
|
55
|
+
continue;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const held = this.#held.get(entryKey(entry.thread_ref, entry.seq));
|
|
59
|
+
return held !== undefined && (context === undefined || held.has(context));
|
|
60
|
+
}
|
|
61
|
+
/** Holds one entry's body in one context until its consumption is confirmed. */
|
|
62
|
+
hold(entry, context) {
|
|
63
|
+
const identity = entryKey(entry.thread_ref, entry.seq);
|
|
64
|
+
const held = this.#held.get(identity) ?? new Set();
|
|
65
|
+
this.#held.set(identity, held.add(context));
|
|
66
|
+
}
|
|
67
|
+
/** Drops one context's hold after its path confirmed the entry's consumption. */
|
|
68
|
+
releaseContext(entry, context) {
|
|
69
|
+
const identity = entryKey(entry.thread_ref, entry.seq);
|
|
70
|
+
const held = this.#held.get(identity);
|
|
71
|
+
if (held === undefined)
|
|
72
|
+
return;
|
|
73
|
+
held.delete(context);
|
|
74
|
+
if (held.size === 0)
|
|
75
|
+
this.#held.delete(identity);
|
|
76
|
+
}
|
|
77
|
+
/** Drops every hold on one entry, for the paths that settle it without a confirmation context. */
|
|
78
|
+
forget(entry) {
|
|
79
|
+
this.#held.delete(entryKey(entry.thread_ref, entry.seq));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=awaited.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"awaited.js","sourceRoot":"","sources":["../src/awaited.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { Context } from "./core.ts";
|
|
2
|
+
import type { DeliveryPlan, Entry, LocalAttention, JoinedThread, Message, MessageQuery, MsgInput, Page, PageOptions, ThreadDescription, ThreadRef, Transport, PreparedSend, ResourceReadQuery, ResourceReadResult } from "./types.ts";
|
|
3
|
+
import type { MessageService } from "./messages.ts";
|
|
4
|
+
import type { ResourceService } from "./resources.ts";
|
|
5
|
+
import type { ThreadService } from "./threads.ts";
|
|
6
|
+
import type { DomainService } from "./domains.ts";
|
|
7
|
+
import type { TrustService } from "./keys.ts";
|
|
8
|
+
import type { ConsumptionRecord, MsgOptions, SendOptions, SendOutcome } from "./delivery.ts";
|
|
9
|
+
export type { MsgOptions, SendOptions, SendOutcome } from "./delivery.ts";
|
|
10
|
+
export declare class OnlyneClient {
|
|
11
|
+
#private;
|
|
12
|
+
/** The maintenance cadence the loop uses while durable work is pending or the host just woke it. */
|
|
13
|
+
static readonly ACTIVE_INTERVAL_MS = 2000;
|
|
14
|
+
/** The floor the loop drops to once the durable ledger holds no pending work. */
|
|
15
|
+
static readonly IDLE_INTERVAL_MS = 30000;
|
|
16
|
+
constructor(ctx: Context, transport: Transport, messages: MessageService, threads: ThreadService, resources: ResourceService, domains: DomainService, trust?: TrustService);
|
|
17
|
+
/**
|
|
18
|
+
* RFC 0017 §6: the library-owned maintenance loop. One pass runs `maintain`,
|
|
19
|
+
* `recover`, then re-arms: pending durable work keeps the active cadence, an idle
|
|
20
|
+
* ledger drops to the idle floor. Every clock read goes through the injected
|
|
21
|
+
* `MaintenanceClock`. A pass is never re-entered; a wake during a pass schedules
|
|
22
|
+
* the next tick at the active cadence. `notify` carries every pending-work change.
|
|
23
|
+
*/
|
|
24
|
+
runMaintenance(): void;
|
|
25
|
+
stopMaintenance(): void;
|
|
26
|
+
/** @internal Flips the loop to its active cadence: new evidence arrived while it idled. */
|
|
27
|
+
wakeLoop(): void;
|
|
28
|
+
/** @internal Schedules an immediate maintenance pass when new inbound or grant work lands locally. */
|
|
29
|
+
wakeImmediate(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Delivers one message under a caller-supplied plan. The plan is never re-derived
|
|
32
|
+
* here: RFC 0005 §2 forbids the library from choosing a delivery mode itself.
|
|
33
|
+
*/
|
|
34
|
+
send(to: string, message: Message, plan: DeliveryPlan, options?: SendOptions): Promise<SendOutcome>;
|
|
35
|
+
/**
|
|
36
|
+
* Re-drives outbound records still open inside their window (RFC 0003 §3). `unknown`
|
|
37
|
+
* is terminal in meaning but the window still owns another attempt, so the window
|
|
38
|
+
* decides when to stop, not the last recorded state. A record whose window closed is
|
|
39
|
+
* settled as `unknown`, never left looking pending. Each record's own attempt series
|
|
40
|
+
* bounds the re-drive: a scheduled next attempt is respected instead of retried every
|
|
41
|
+
* pass, and a series that reached its limit stays a dead letter until an explicit
|
|
42
|
+
* re-send starts a new one. A caller invoking this directly is asking for a retry now,
|
|
43
|
+
* so it ignores the schedule; the maintenance loop's own pass respects it.
|
|
44
|
+
*/
|
|
45
|
+
recover(signal?: AbortSignal): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Records one inbound attention item, then acts. The durable entry and the local
|
|
48
|
+
* reply record commit before the ack (RFC 0003 §2); only then may a waiter be
|
|
49
|
+
* released, and only by an entry whose author the owner authenticated and whose
|
|
50
|
+
* author is the one expected. Invalid evidence is still acked but resolves nothing.
|
|
51
|
+
*
|
|
52
|
+
* The entry is trusted as-is: this is the runtime binding's own receive path, where
|
|
53
|
+
* the owner's authenticated response is the evidence, not a caller argument. No
|
|
54
|
+
* HTTP route accepts an `Entry` from a peer, so no peer can supply one.
|
|
55
|
+
*/
|
|
56
|
+
receive(entry: Entry, obligation_id: string, context?: string): Promise<LocalAttention>;
|
|
57
|
+
/**
|
|
58
|
+
* Reconciles unacked attention for every owner this node knows (RFC 0003 §2): the
|
|
59
|
+
* `owner + thread_ref` pairs recorded when a grant notice was accepted, plus the
|
|
60
|
+
* threads this node hosts, which need no grant. The owner's authenticated attention
|
|
61
|
+
* list is the evidence; the ack goes out only after the entry is durable locally.
|
|
62
|
+
* An owner this node cannot reach is reported as a trace record, never thrown: one dead
|
|
63
|
+
* owner must not starve the rest, and a silent skip is the failure nobody can diagnose.
|
|
64
|
+
* Each (owner, thread) carries its own attempt series: a call from the maintenance pass
|
|
65
|
+
* respects the scheduled next attempt, and an exhausted series stays a dead letter so an
|
|
66
|
+
* unreachable owner costs one probe per window instead of one storm per pass. A caller
|
|
67
|
+
* invoking this directly is asking for a retry now, so it ignores the schedule — and still
|
|
68
|
+
* counts the attempt, so a caller that retries in a loop reaches the same dead letter.
|
|
69
|
+
*/
|
|
70
|
+
reconcile(signal?: AbortSignal): Promise<Page<LocalAttention>>;
|
|
71
|
+
/**
|
|
72
|
+
* Delivers outstanding owner grant notices, replays owed todos and entries whose durable
|
|
73
|
+
* record never reached the model, re-asks trusted owners for the memberships they hold for
|
|
74
|
+
* this node, re-drives owed trust statements, then reconciles. Replay follows each thread's
|
|
75
|
+
* own order: `owner`, `id`, then `seq` as a number. One record that fails never starves the
|
|
76
|
+
* rest, and the failures are thrown after the pass with their records still owed for the
|
|
77
|
+
* next one. Caller-scheduled, and the only entry a host without a maintenance clock needs
|
|
78
|
+
* besides `recover`.
|
|
79
|
+
*/
|
|
80
|
+
maintain(signal?: AbortSignal): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Whether any durable record still needs a local pass: an unacked grant notice, an
|
|
83
|
+
* owed todo, an uninjected inbox row, or an outbound still owed an attempt. A scheduler
|
|
84
|
+
* consults this before running `maintain`, so an idle node costs no rounds; anything
|
|
85
|
+
* that flips this on (an admission, an ack, a failed delivery) also wakes the host.
|
|
86
|
+
* A dead-lettered send is terminal, and a scheduled retry counts only once it is due, so
|
|
87
|
+
* neither holds the active cadence for a peer that is simply away.
|
|
88
|
+
*/
|
|
89
|
+
hasPendingWork(): Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* The one call a model makes. SystemOne turns the intent into a typed action, the
|
|
92
|
+
* decision is persisted with its input, then exactly that action runs. With no
|
|
93
|
+
* usable decision the request fails: the library never picks a plan itself.
|
|
94
|
+
*/
|
|
95
|
+
msg(input: MsgInput, options?: MsgOptions): Promise<unknown>;
|
|
96
|
+
prepare(input: MsgInput): Promise<PreparedSend>;
|
|
97
|
+
readResources(query: ResourceReadQuery, options?: MsgOptions): Promise<ResourceReadResult>;
|
|
98
|
+
/**
|
|
99
|
+
* `confirmConsumption(entry, context?, via = 'fragment'): Promise<void>`
|
|
100
|
+
*
|
|
101
|
+
* The host's confirmation that this entry's body was consumed by the path it names
|
|
102
|
+
* (RFC 0008 §5). One commit writes the shared consumption slot, marks every matching inbox
|
|
103
|
+
* record delivered, and records the todo this consumption owes; the host's todo hook runs
|
|
104
|
+
* outside that commit, and the todo is filed where the model saw the body. `context` names
|
|
105
|
+
* that place; with none, the context the entry landed in decides, then this node. A failing
|
|
106
|
+
* hook leaves the todo owed, so `maintain` replays it, and replaying is safe because the
|
|
107
|
+
* host commits the todo it creates. This also releases the hold an awaited tool result
|
|
108
|
+
* placed on the entry for that context.
|
|
109
|
+
*/
|
|
110
|
+
confirmConsumption(entry: Entry, context?: string, via?: ConsumptionRecord['via']): Promise<void>;
|
|
111
|
+
/** `confirmToolResult(entry, context?): Promise<void>`: the same settlement for an awaited tool result. */
|
|
112
|
+
confirmToolResult(entry: Entry, context?: string): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* `isWaitingReply(entry, context?): boolean`
|
|
115
|
+
*
|
|
116
|
+
* Whether this entry answers an `await` that owns its body here, optionally only one whose
|
|
117
|
+
* sender-local context is `context`: a waiter still running, or a reply already returned as
|
|
118
|
+
* a tool result and not yet confirmed consumed. A host defers the automatic fragment on
|
|
119
|
+
* `true`, because the tool result either holds or already presented the same body. A
|
|
120
|
+
* cancelled wait returns no reply, so it holds nothing.
|
|
121
|
+
*/
|
|
122
|
+
isWaitingReply(entry: Entry, context?: string): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* The threads this node was invited into. The rows come from the records it already holds;
|
|
125
|
+
* each row is then asked of its owner through the same describe read the thread view uses,
|
|
126
|
+
* which is where the title, the state and the member table live. An owner that cannot be
|
|
127
|
+
* reached leaves the row in place with the failure attached: an unreachable peer is a
|
|
128
|
+
* reported outage, never a reason to hide a thread this node belongs to.
|
|
129
|
+
*/
|
|
130
|
+
joinedThreads(options?: PageOptions, signal?: AbortSignal): Promise<Page<JoinedThread>>;
|
|
131
|
+
/** One thread's record and members: local when this node hosts it, from the owner otherwise. */
|
|
132
|
+
describeThread(ref: ThreadRef, signal?: AbortSignal): Promise<ThreadDescription>;
|
|
133
|
+
/**
|
|
134
|
+
* One page of a thread's entries, read locally when this node hosts the thread and from the
|
|
135
|
+
* owner otherwise. A member of a joined thread has no local copy of the entries, so the
|
|
136
|
+
* owner's message route is the only source that can answer for them.
|
|
137
|
+
*/
|
|
138
|
+
threadEntries(ref: ThreadRef, query?: MessageQuery, signal?: AbortSignal): Promise<Page<Entry>>;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|