@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.
Files changed (121) hide show
  1. package/README.md +6 -3
  2. package/dist/awaited.d.ts +43 -0
  3. package/dist/awaited.d.ts.map +1 -0
  4. package/dist/awaited.js +82 -0
  5. package/dist/awaited.js.map +1 -0
  6. package/dist/client.d.ts +140 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +1772 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/core.d.ts +36 -0
  11. package/dist/core.d.ts.map +1 -0
  12. package/dist/core.js +122 -0
  13. package/dist/core.js.map +1 -0
  14. package/dist/delivery.d.ts +120 -0
  15. package/dist/delivery.d.ts.map +1 -0
  16. package/dist/delivery.js +117 -0
  17. package/dist/delivery.js.map +1 -0
  18. package/dist/discovery.d.ts +35 -0
  19. package/dist/discovery.d.ts.map +1 -0
  20. package/dist/discovery.js +306 -0
  21. package/dist/discovery.js.map +1 -0
  22. package/dist/domains.d.ts +29 -0
  23. package/dist/domains.d.ts.map +1 -0
  24. package/dist/domains.js +267 -0
  25. package/dist/domains.js.map +1 -0
  26. package/dist/history.d.ts +13 -0
  27. package/dist/history.d.ts.map +1 -0
  28. package/dist/history.js +143 -0
  29. package/dist/history.js.map +1 -0
  30. package/dist/http.d.ts +20 -0
  31. package/dist/http.d.ts.map +1 -0
  32. package/dist/http.js +88 -0
  33. package/dist/http.js.map +1 -0
  34. package/dist/index.d.ts +20 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +15 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/keys.d.ts +97 -0
  39. package/dist/keys.d.ts.map +1 -0
  40. package/dist/keys.js +679 -0
  41. package/dist/keys.js.map +1 -0
  42. package/dist/memory.d.ts +9 -0
  43. package/dist/memory.d.ts.map +1 -0
  44. package/dist/memory.js +35 -0
  45. package/dist/memory.js.map +1 -0
  46. package/dist/messages.d.ts +64 -0
  47. package/dist/messages.d.ts.map +1 -0
  48. package/dist/messages.js +480 -0
  49. package/dist/messages.js.map +1 -0
  50. package/dist/node.d.ts +26 -0
  51. package/dist/node.d.ts.map +1 -0
  52. package/dist/node.js +59 -0
  53. package/dist/node.js.map +1 -0
  54. package/dist/resolve.d.ts +18 -0
  55. package/dist/resolve.d.ts.map +1 -0
  56. package/dist/resolve.js +37 -0
  57. package/dist/resolve.js.map +1 -0
  58. package/dist/resources.d.ts +25 -0
  59. package/dist/resources.d.ts.map +1 -0
  60. package/dist/resources.js +782 -0
  61. package/dist/resources.js.map +1 -0
  62. package/dist/routes/domains.d.ts +4 -0
  63. package/dist/routes/domains.d.ts.map +1 -0
  64. package/dist/routes/domains.js +42 -0
  65. package/dist/routes/domains.js.map +1 -0
  66. package/dist/routes/grants.d.ts +8 -0
  67. package/dist/routes/grants.d.ts.map +1 -0
  68. package/dist/routes/grants.js +32 -0
  69. package/dist/routes/grants.js.map +1 -0
  70. package/dist/routes/public.d.ts +4 -0
  71. package/dist/routes/public.d.ts.map +1 -0
  72. package/dist/routes/public.js +62 -0
  73. package/dist/routes/public.js.map +1 -0
  74. package/dist/routes/resources.d.ts +8 -0
  75. package/dist/routes/resources.d.ts.map +1 -0
  76. package/dist/routes/resources.js +87 -0
  77. package/dist/routes/resources.js.map +1 -0
  78. package/dist/routes/shared.d.ts +77 -0
  79. package/dist/routes/shared.d.ts.map +1 -0
  80. package/dist/routes/shared.js +349 -0
  81. package/dist/routes/shared.js.map +1 -0
  82. package/dist/routes/threads.d.ts +8 -0
  83. package/dist/routes/threads.d.ts.map +1 -0
  84. package/dist/routes/threads.js +113 -0
  85. package/dist/routes/threads.js.map +1 -0
  86. package/dist/routes/trust.d.ts +4 -0
  87. package/dist/routes/trust.d.ts.map +1 -0
  88. package/dist/routes/trust.js +36 -0
  89. package/dist/routes/trust.js.map +1 -0
  90. package/dist/stream.d.ts +20 -0
  91. package/dist/stream.d.ts.map +1 -0
  92. package/dist/stream.js +141 -0
  93. package/dist/stream.js.map +1 -0
  94. package/dist/threads.d.ts +79 -0
  95. package/dist/threads.d.ts.map +1 -0
  96. package/dist/threads.js +480 -0
  97. package/dist/threads.js.map +1 -0
  98. package/dist/transport.d.ts +45 -0
  99. package/dist/transport.d.ts.map +1 -0
  100. package/dist/transport.js +175 -0
  101. package/dist/transport.js.map +1 -0
  102. package/dist/types.d.ts +809 -0
  103. package/dist/types.d.ts.map +1 -0
  104. package/dist/types.js +9 -0
  105. package/dist/types.js.map +1 -0
  106. package/package.json +16 -8
  107. package/src/client.ts +0 -1549
  108. package/src/core.ts +0 -114
  109. package/src/discovery.ts +0 -267
  110. package/src/domains.ts +0 -210
  111. package/src/history.ts +0 -129
  112. package/src/http.ts +0 -841
  113. package/src/index.ts +0 -18
  114. package/src/keys.ts +0 -632
  115. package/src/memory.ts +0 -34
  116. package/src/messages.ts +0 -398
  117. package/src/node.ts +0 -56
  118. package/src/resources.ts +0 -745
  119. package/src/threads.ts +0 -350
  120. package/src/transport.ts +0 -204
  121. package/src/types.ts +0 -383
@@ -0,0 +1,809 @@
1
+ export type Json = null | boolean | number | string | Json[] | {
2
+ [key: string]: Json;
3
+ };
4
+ export type NodeId = string;
5
+ export type DomainId = string;
6
+ export interface DomainMembership {
7
+ domain_id: DomainId;
8
+ node_id: NodeId;
9
+ state: 'active' | 'left';
10
+ revision: string;
11
+ }
12
+ export interface DomainMutation extends Mutation {
13
+ expected_revision?: string;
14
+ }
15
+ export interface DomainDiscovery {
16
+ domain_id: DomainId;
17
+ members: DomainMembership[];
18
+ unavailable: NodeId[];
19
+ }
20
+ export interface DiscoveryCandidate {
21
+ node_id: NodeId;
22
+ instance_id: string;
23
+ base_url: string;
24
+ last_seen: string;
25
+ }
26
+ export interface DiscoveryRecord extends DiscoveryCandidate {
27
+ source: string;
28
+ received_at: string;
29
+ expires_at: string;
30
+ verified_at?: string;
31
+ membership?: DomainMembership | null;
32
+ error?: Failure;
33
+ }
34
+ export interface ServiceDescription {
35
+ protocol: 'onlyne/3';
36
+ node_id: NodeId;
37
+ instance_id: string;
38
+ base_url: string;
39
+ features: string[];
40
+ authentication: string[];
41
+ domain: DomainId | null;
42
+ membership: DomainMembership | null;
43
+ }
44
+ export interface ThreadRef {
45
+ owner: NodeId;
46
+ id: string;
47
+ }
48
+ export interface MessageRef {
49
+ sender: NodeId;
50
+ id: string;
51
+ }
52
+ export interface ResourceRef {
53
+ owner: NodeId;
54
+ id: string;
55
+ }
56
+ export type ErrorCode = 'invalid_request' | 'unauthenticated' | 'forbidden' | 'not_a_member' | 'not_found' | 'id_conflict' | 'revision_conflict' | 'request_in_progress' | 'conflict' | 'thread_closed' | 'context_lost' | 'retry_window_expired' | 'cursor_expired' | 'payload_too_large' | 'unsupported_media_type' | 'unsupported_delivery' | 'ambiguous_target' | 'ambiguous_resource' | 'capacity_exceeded' | 'internal' | 'unavailable' | 'decision_unavailable';
57
+ export interface Failure {
58
+ code: ErrorCode;
59
+ message: string;
60
+ retryable: boolean;
61
+ details?: Json;
62
+ }
63
+ export interface Auth {
64
+ actor: NodeId;
65
+ sender?: NodeId;
66
+ reply_authority?: NodeId;
67
+ }
68
+ export interface Transaction {
69
+ get<T>(key: string): Promise<T | undefined>;
70
+ put<T>(key: string, value: T): Promise<void>;
71
+ delete(key: string): Promise<void>;
72
+ scan<T>(prefix: string): Promise<Array<{
73
+ key: string;
74
+ value: T;
75
+ }>>;
76
+ }
77
+ export interface Storage {
78
+ readonly guarantee: 'durable' | 'binding-defined';
79
+ /** Serializable, atomic commit. Rejecting the callback rolls back every write. */
80
+ transaction<T>(work: (tx: Transaction) => Promise<T>): Promise<T>;
81
+ }
82
+ export interface Page<T> {
83
+ items: T[];
84
+ next_cursor: string | null;
85
+ }
86
+ export interface Mutation {
87
+ idempotency_key: string;
88
+ retry_until: string;
89
+ }
90
+ export interface DeliveryPlan {
91
+ response: 'none' | 'async' | 'await';
92
+ execution: 'existing' | 'new';
93
+ context?: string;
94
+ }
95
+ /**
96
+ * RFC 0003 §1: the unit of work a message belongs to. `unit` is the identity a receiver
97
+ * dedupes on, so a re-delivery of the same unit is recognised across threads, sessions and
98
+ * restarts; `parent` names the enclosing unit; `attempt` counts retries of one unit.
99
+ */
100
+ export interface WorkRef {
101
+ unit: string;
102
+ parent?: string | null;
103
+ attempt?: number;
104
+ }
105
+ export interface Message {
106
+ id: string;
107
+ sender: NodeId;
108
+ delivery_kind: string;
109
+ msg: string;
110
+ meta?: {
111
+ work?: WorkRef;
112
+ thread?: ThreadRef;
113
+ in_reply_to?: MessageRef;
114
+ relation?: 'reply' | 'followup';
115
+ mentions?: string[];
116
+ parts?: Json[];
117
+ data?: {
118
+ [key: string]: Json;
119
+ };
120
+ };
121
+ }
122
+ export interface SendRequest extends Mutation {
123
+ message: Message;
124
+ target_endpoint: NodeId;
125
+ plan: DeliveryPlan;
126
+ }
127
+ export interface Receipt {
128
+ message_ref: MessageRef;
129
+ receipt_id: string;
130
+ guarantee: Storage['guarantee'];
131
+ thread_ref: ThreadRef;
132
+ seq: string;
133
+ plan: DeliveryPlan;
134
+ thread_created?: boolean;
135
+ previous_seq?: string;
136
+ /**
137
+ * The message this one answers, in the identity the owner stored: the sender's
138
+ * `{thread,seq}` spelling is resolved before delivery, so this is the pair every
139
+ * later read agrees on. Absent when the message answers nothing.
140
+ */
141
+ in_reply_to?: MessageRef;
142
+ }
143
+ export interface Entry {
144
+ thread_ref: ThreadRef;
145
+ seq: string;
146
+ message: Message;
147
+ authenticated_author: NodeId;
148
+ reply_authority: NodeId;
149
+ at: string;
150
+ }
151
+ export interface ReadScope {
152
+ peers?: NodeId[];
153
+ since_seq?: string;
154
+ related_to?: MessageRef;
155
+ }
156
+ export interface Member {
157
+ peer: NodeId;
158
+ state: 'requested' | 'active' | 'revoked' | 'denied';
159
+ access: Array<'read' | 'post'>;
160
+ read_scope: ReadScope;
161
+ revision: string;
162
+ }
163
+ export interface Thread {
164
+ thread_ref: ThreadRef;
165
+ title: string;
166
+ state: 'open' | 'closed';
167
+ next_seq: string;
168
+ event_seq: string;
169
+ created_at: string;
170
+ closed_at: string | null;
171
+ messages_until?: string;
172
+ }
173
+ /**
174
+ * A thread this node was invited into and does not own. Every field here comes from a record
175
+ * this node already holds; the owner's title, state and member table are filled in only by a
176
+ * caller that could ask the owner, and a row that could not ask keeps the failure instead of
177
+ * inventing them.
178
+ */
179
+ export interface JoinedThread {
180
+ thread_ref: ThreadRef;
181
+ /** The highest sequence this node holds a local record for; `0` when it holds none. */
182
+ last_seq: string;
183
+ /** Distinct messages this node holds for the thread. */
184
+ message_count: number;
185
+ /** A participant never owns the member table, so this view is read-only by construction. */
186
+ read_only: true;
187
+ title?: string;
188
+ state?: Thread['state'];
189
+ members?: Member[];
190
+ /** The owner could not be asked; the row stays listed with what the local records prove. */
191
+ unavailable?: Failure;
192
+ }
193
+ /** One thread record with its member table: what the describe read answers, here or at the owner. */
194
+ export interface ThreadDescription {
195
+ thread: Thread;
196
+ members: Member[];
197
+ }
198
+ export interface Attention {
199
+ obligation_id: string;
200
+ recipient: NodeId;
201
+ thread_ref: ThreadRef;
202
+ seq: string;
203
+ message_ref: MessageRef;
204
+ authenticated_author: NodeId;
205
+ acked: boolean;
206
+ disposition?: 'expired';
207
+ plan?: DeliveryPlan;
208
+ entry?: Entry;
209
+ }
210
+ export interface Grant {
211
+ id: string;
212
+ recipient: NodeId;
213
+ thread_ref: ThreadRef;
214
+ revision: string;
215
+ acked: boolean;
216
+ /**
217
+ * Set on a re-issued notice: the ref the recipient learned under the previous owner. The
218
+ * recipient stores the new known row and drops the one this names, so a renamed owner does
219
+ * not leave a second row pointing at an endpoint that no longer exists.
220
+ */
221
+ previous_thread_ref?: ThreadRef;
222
+ }
223
+ export interface Event {
224
+ id: string;
225
+ type: 'message' | 'membership' | 'thread_closed' | 'resource_event' | 'operation';
226
+ thread_ref?: ThreadRef;
227
+ resource_ref?: ResourceRef;
228
+ message_ref?: MessageRef;
229
+ data: Json;
230
+ }
231
+ export interface PageOptions {
232
+ cursor?: string;
233
+ page_size?: number;
234
+ }
235
+ export interface MessageQuery extends PageOptions {
236
+ attention?: 'inbox' | 'thread';
237
+ since_seq?: string;
238
+ peer?: NodeId;
239
+ related_to?: MessageRef;
240
+ }
241
+ export interface ReplyPermit {
242
+ message_ref: MessageRef;
243
+ grantee: NodeId;
244
+ landing: ThreadRef;
245
+ expires_at: string;
246
+ remaining: number;
247
+ revoked: boolean;
248
+ followup: boolean;
249
+ }
250
+ /**
251
+ * RFC 0006 §3: the resource's runtime state. `binding` is the one pointer events route
252
+ * through; `log_readers` is a separate authorization for the append-only log, and a
253
+ * handover never touches it (§6).
254
+ */
255
+ export interface Resource {
256
+ resource_ref: ResourceRef;
257
+ kind: string;
258
+ operations: string[];
259
+ binding: {
260
+ handler: NodeId;
261
+ cursor: string;
262
+ };
263
+ log_readers: NodeId[];
264
+ revision: string;
265
+ event_seq: string;
266
+ retention_ms: number;
267
+ data?: Json;
268
+ }
269
+ /** RFC 0006 §5: an event belongs to the resource, never to a recipient list. */
270
+ export interface ResourceEvent {
271
+ resource_ref: ResourceRef;
272
+ event_id: string;
273
+ source_id: string;
274
+ data: Json;
275
+ at: string;
276
+ expires_at: string;
277
+ expired: boolean;
278
+ }
279
+ /** RFC 0006 §6: the log query. `since` is exclusive, the same side of the cursor an ack names. */
280
+ export interface LogQuery extends PageOptions {
281
+ since?: string;
282
+ }
283
+ /** What an ack answers: the handler's confirmed position, not the event it named. */
284
+ export interface AckReceipt {
285
+ resource_ref: ResourceRef;
286
+ cursor: string;
287
+ }
288
+ /** RFC 0006 §4.3: the probe an endpoint sends to the node it wants to become handler. */
289
+ export interface HandoverProbe {
290
+ operation_id: string;
291
+ resource: ResourceRef;
292
+ kind: string;
293
+ operations: string[];
294
+ metadata?: Json;
295
+ initiator: NodeId;
296
+ cursor: string;
297
+ deadline: string;
298
+ }
299
+ export type ProbeAnswer = {
300
+ answer: 'accept';
301
+ cursor: string;
302
+ } | {
303
+ answer: 'reject';
304
+ reason: string;
305
+ };
306
+ export interface OperationRequest extends Mutation {
307
+ operation_id: string;
308
+ operation: string;
309
+ expected_revision?: string;
310
+ data?: Json;
311
+ }
312
+ export interface OperationResult {
313
+ operation_id: string;
314
+ state: 'committed' | 'pending' | 'aborted' | 'unknown';
315
+ data?: Json;
316
+ error?: Failure;
317
+ }
318
+ export interface OperationRecord {
319
+ actor: NodeId;
320
+ request: OperationRequest;
321
+ digest: string;
322
+ result: OperationResult;
323
+ resource_ref: ResourceRef;
324
+ accepted_at: string;
325
+ authorized_revision: string;
326
+ }
327
+ export interface Outbound {
328
+ /**
329
+ * `unreachable` is the terminal dead letter of a bounded retry series: the peer never
330
+ * answered inside the window, so a later pass stops re-driving it until an explicit
331
+ * re-send starts a new series.
332
+ */
333
+ request: SendRequest;
334
+ expected_author: NodeId;
335
+ state: 'pending' | 'accepted' | 'refused' | 'unknown' | 'unreachable';
336
+ receipt?: Receipt;
337
+ error?: Failure;
338
+ created_at?: string;
339
+ /** The peer this send addresses when it differs from the endpoint that stores the entry. */
340
+ addressee?: NodeId;
341
+ /** The caller's own spelling of the addressee, when it differs from the resolved node id. */
342
+ requested?: string;
343
+ /** Failed attempts in the current retry series, and when the next one is due. */
344
+ attempt?: number;
345
+ next_attempt?: string;
346
+ }
347
+ export interface HistoryMessage {
348
+ message_ref: MessageRef;
349
+ message: Message;
350
+ direction: 'in' | 'out';
351
+ thread_ref?: ThreadRef;
352
+ seq?: string;
353
+ at: string | null;
354
+ delivery: Outbound['state'] | 'received';
355
+ consumption?: 'pending' | 'consumed';
356
+ settlement?: AttentionSettlement;
357
+ guarantee?: Storage['guarantee'];
358
+ error?: Failure;
359
+ }
360
+ export interface Conversation {
361
+ id: MessageRef;
362
+ title: string;
363
+ thread_refs: ThreadRef[];
364
+ messages: HistoryMessage[];
365
+ last_at: string | null;
366
+ }
367
+ export interface HistoryQuery extends PageOptions {
368
+ thread?: ThreadRef;
369
+ message?: MessageRef;
370
+ }
371
+ export type AttentionSettlement = {
372
+ via: 'handover';
373
+ resource_ref: ResourceRef;
374
+ handler: NodeId;
375
+ revision: string;
376
+ at: string;
377
+ } | {
378
+ via: 'undeliverable';
379
+ resource_ref: ResourceRef;
380
+ reason: 'resource-unavailable';
381
+ at: string;
382
+ };
383
+ /**
384
+ * `injected` closes the local delivery obligation after observed consumption or an explicit
385
+ * settlement. A settlement records why delivery ended without claiming model consumption.
386
+ */
387
+ export interface LocalAttention {
388
+ attention: Attention;
389
+ context?: string;
390
+ injected: boolean;
391
+ settlement?: AttentionSettlement;
392
+ resource_check_failures?: number;
393
+ }
394
+ export interface Target {
395
+ node_id: NodeId;
396
+ base_url: string;
397
+ headers?: Record<string, string>;
398
+ }
399
+ export interface Transport {
400
+ request<T>(target: NodeId, method: string, path: string, body?: unknown, signal?: AbortSignal): Promise<T>;
401
+ }
402
+ export interface MsgInput {
403
+ delivery_kind: string;
404
+ msg: string;
405
+ meta?: Record<string, Json>;
406
+ }
407
+ export interface PreparedSend {
408
+ to: NodeId;
409
+ message: Message;
410
+ plan: DeliveryPlan;
411
+ }
412
+ export type ResourceReadQuery = ({
413
+ op: 'list';
414
+ owners?: NodeId[];
415
+ } & PageOptions) | {
416
+ op: 'describe';
417
+ resource: ResourceRef;
418
+ } | ({
419
+ op: 'log';
420
+ resource: ResourceRef;
421
+ } & LogQuery) | {
422
+ op: 'event';
423
+ resource: ResourceRef;
424
+ event_id: string;
425
+ } | ({
426
+ op: 'operations';
427
+ resource: ResourceRef;
428
+ } & PageOptions) | {
429
+ op: 'status';
430
+ resource: ResourceRef;
431
+ operation_id: string;
432
+ };
433
+ export interface ResourceInventory {
434
+ owners: Array<{
435
+ owner: NodeId;
436
+ page: Page<Resource>;
437
+ } | {
438
+ owner: NodeId;
439
+ error: Failure;
440
+ }>;
441
+ }
442
+ export type ResourceReadResult = ResourceInventory | Resource | Page<ResourceEvent> | ResourceEvent | Page<OperationRecord> | OperationRecord;
443
+ export type Action = {
444
+ kind: 'domain';
445
+ op: 'create' | 'join' | 'leave' | 'list' | 'describe' | 'discover';
446
+ domain_id?: DomainId;
447
+ expected_revision?: string;
448
+ } | {
449
+ kind: 'send';
450
+ to: NodeId;
451
+ work?: WorkRef;
452
+ thread?: ThreadRef;
453
+ context?: string;
454
+ in_reply_to?: MessageRef;
455
+ relation?: 'reply' | 'followup';
456
+ mentions?: NodeId[];
457
+ response: DeliveryPlan['response'];
458
+ execution: DeliveryPlan['execution'];
459
+ } | {
460
+ kind: 'read';
461
+ scope: 'directory' | 'neighbors' | 'threads' | 'inbox' | 'messages' | 'message' | 'evidence';
462
+ thread?: ThreadRef;
463
+ message?: MessageRef;
464
+ seq?: string;
465
+ cursor?: string;
466
+ page_size?: number;
467
+ attention?: 'inbox' | 'thread';
468
+ } | {
469
+ kind: 'read';
470
+ scope: 'resources';
471
+ query: ResourceReadQuery;
472
+ } | {
473
+ kind: 'thread';
474
+ op: 'create' | 'close' | 'list' | 'describe' | 'member_add' | 'member_remove';
475
+ thread?: ThreadRef;
476
+ to?: NodeId;
477
+ title?: string;
478
+ } | {
479
+ kind: 'resource';
480
+ resource: ResourceRef;
481
+ operation: string;
482
+ data?: Json;
483
+ expected_revision?: string;
484
+ };
485
+ /**
486
+ * One lifecycle transition of the local node, emitted for offline diagnosis. Every field is an
487
+ * identifier, a state name or a count: message bodies and credentials never appear here.
488
+ */
489
+ export type TraceEvent = {
490
+ event: 'inbound.received';
491
+ obligation: string;
492
+ thread: ThreadRef;
493
+ seq: string;
494
+ sender: NodeId;
495
+ relation?: 'reply' | 'followup';
496
+ valid: boolean;
497
+ context?: string;
498
+ injected: boolean;
499
+ } | {
500
+ event: 'inbound.duplicate';
501
+ sender: NodeId;
502
+ message: string;
503
+ } | {
504
+ event: 'inbound.acked';
505
+ obligation: string;
506
+ thread: ThreadRef;
507
+ seq: string;
508
+ } | {
509
+ event: 'inbound.inject';
510
+ thread: ThreadRef;
511
+ seq: string;
512
+ context: string;
513
+ outcome: InjectOutcome;
514
+ reason?: string;
515
+ } | {
516
+ event: 'inbound.settled';
517
+ thread: ThreadRef;
518
+ seq: string;
519
+ settlement: AttentionSettlement;
520
+ } | {
521
+ event: 'inbound.resource-check.failed';
522
+ thread: ThreadRef;
523
+ seq: string;
524
+ resource_ref: ResourceRef;
525
+ code: ErrorCode;
526
+ attempts: number;
527
+ } | {
528
+ event: 'consumption.confirmed';
529
+ thread: ThreadRef;
530
+ seq: string;
531
+ context: string;
532
+ via: 'fragment' | 'tool_result';
533
+ } | {
534
+ event: 'outbound.admitted';
535
+ sender: NodeId;
536
+ message: string;
537
+ target: string;
538
+ state: string;
539
+ guarantee?: string;
540
+ code?: string;
541
+ resolved?: NodeId;
542
+ } | {
543
+ event: 'outbound.redriven';
544
+ sender: NodeId;
545
+ message: string;
546
+ target: string;
547
+ } | {
548
+ event: 'outbound.expired';
549
+ sender: NodeId;
550
+ message: string;
551
+ code: string;
552
+ } | {
553
+ event: 'await.settled';
554
+ thread: ThreadRef;
555
+ seq: string;
556
+ waiters: number;
557
+ }
558
+ /**
559
+ * A known owner this node could not reconcile, written at most once per (owner, thread, code)
560
+ * per window. `attempts` is how many failed passes that one line accounts for, the suppressed
561
+ * duplicates included; the local rows a failed pull never reached are still owed, not dropped.
562
+ */
563
+ | {
564
+ event: 'reconcile.failed';
565
+ owner: NodeId;
566
+ thread: string;
567
+ code: ErrorCode;
568
+ message: string;
569
+ attempts: number;
570
+ }
571
+ /**
572
+ * A known thread whose retry series is exhausted: the owner stayed unreachable through every
573
+ * attempt, so reconciliation stops asking until the owner answers on another path.
574
+ */
575
+ | {
576
+ event: 'reconcile.unreachable';
577
+ owner: NodeId;
578
+ thread: string;
579
+ code: ErrorCode;
580
+ attempts: number;
581
+ }
582
+ /** A grant the owner still holds for this node was missing here and has been re-recorded. */
583
+ | {
584
+ event: 'grant.restored';
585
+ owner: NodeId;
586
+ thread: ThreadRef;
587
+ grant: string;
588
+ }
589
+ /**
590
+ * Asking a trusted owner for the memberships it holds for this node failed. Deduplicated per
591
+ * (owner, code) per window, like every other repeated failure line.
592
+ */
593
+ | {
594
+ event: 'grant.resync.failed';
595
+ owner: NodeId;
596
+ code: ErrorCode;
597
+ message: string;
598
+ attempts: number;
599
+ }
600
+ /** A delivery series exhausted its attempts; the record is a dead letter, not a pending send. */
601
+ | {
602
+ event: 'outbound.unreachable';
603
+ sender: NodeId;
604
+ message: string;
605
+ target: string;
606
+ attempts: number;
607
+ code: ErrorCode;
608
+ };
609
+ /** What the host did with one inbound entry, reported back with the injection result. */
610
+ export type InjectOutcome = 'delivered' | 'queued' | 'waiting' | 'skipped' | 'consumed';
611
+ export interface Runtime {
612
+ supports(plan: DeliveryPlan, message?: Message): Promise<boolean>;
613
+ /** Submission returns consumed:false; an observed request boundary may confirm it later. */
614
+ inject(entry: Entry, context?: string, plan?: DeliveryPlan): Promise<{
615
+ context: string;
616
+ consumed: boolean;
617
+ outcome?: InjectOutcome;
618
+ }>;
619
+ todo?(entry: Entry, context: string): Promise<void>;
620
+ /**
621
+ * RFC 0017 §5: the one notification channel. The node calls it for every committed
622
+ * trust transition, every inbound entry, and after each maintenance pass that changed
623
+ * the pending-work answer. A host that renders from these events never polls storage
624
+ * on its own; a host that misses one still converges on the next maintenance pass.
625
+ */
626
+ notify(event: NotifyEvent): void;
627
+ /**
628
+ * Optional structured trace. The node calls it on every lifecycle transition; the host maps
629
+ * it onto its own log, so a delivery can be followed from admission to consumption offline.
630
+ */
631
+ trace?(event: TraceEvent): void;
632
+ /**
633
+ * Called by the host once it observes that the model consumed an `await` tool result
634
+ * (RFC 0008 §5). The library records that as the shared consumption for the entry's
635
+ * `(context, ThreadRef, seq)`, so the automatic fragment does not present it again.
636
+ */
637
+ confirmToolResult?(entry: Entry, context: string): Promise<void>;
638
+ }
639
+ export interface ResourceDriver {
640
+ validate(resource: Resource, operation: string, data: Json | undefined): Promise<void>;
641
+ execute(resource: Resource, request: OperationRequest, signal?: AbortSignal): Promise<Omit<OperationResult, 'operation_id'>>;
642
+ query?(resource: Resource, operation_id: string): Promise<Omit<OperationResult, 'operation_id'>>;
643
+ /**
644
+ * RFC 0006 §2: retention has just given these events a terminal disposition. A driver that
645
+ * keeps state per event source drops what it still holds for them here; the log rows
646
+ * themselves stay readable with `expired: true`, so this never deletes history.
647
+ */
648
+ retire?(events: ResourceEvent[]): Promise<void>;
649
+ }
650
+ /** RFC 0017 key material the host hands the library: the signing key and the public key it proves. */
651
+ export interface KeyMaterial {
652
+ readonly private_key: Uint8Array;
653
+ readonly public_key: Uint8Array;
654
+ }
655
+ /** Load-or-create the node identity key; storage is the host's choice (RFC 0017 §2). */
656
+ export type KeyHook = (() => Promise<KeyMaterial>) & {
657
+ replace?(material: KeyMaterial): Promise<void>;
658
+ };
659
+ export interface KeyIdentity {
660
+ node_id: NodeId;
661
+ public_key: string;
662
+ fingerprint: string;
663
+ }
664
+ export interface TrustSeed {
665
+ node_id: NodeId;
666
+ fingerprint: string;
667
+ }
668
+ export interface TrustStatement {
669
+ node_id: NodeId;
670
+ target: NodeId;
671
+ public_key: string;
672
+ target_fingerprint: string;
673
+ base_url: string;
674
+ approved: boolean;
675
+ nonce: string;
676
+ timestamp: number;
677
+ signature: string;
678
+ previous_signature?: string;
679
+ /**
680
+ * Set on a reply: the nonce of the request this statement answers. A sender settles its
681
+ * delivery obligation only on a reply that echoes the nonce it sent (RFC 0017 §3.5).
682
+ */
683
+ reply_nonce?: string;
684
+ }
685
+ /**
686
+ * The observable stage of one trust relation, derived only from the approval halves
687
+ * (RFC 0017 §3). A host renders and decides from this value; it never re-derives
688
+ * the stage from the raw halves.
689
+ */
690
+ export type TrustPhase = 'invited' | 'requested' | 'exchanged' | 'revoked';
691
+ /** RFC 0017 §5: what changed when the node calls `runtime.notify`. */
692
+ export type NotifyEvent = {
693
+ event: 'work-pending';
694
+ pending: boolean;
695
+ } | {
696
+ event: 'trust';
697
+ cause: 'local-request' | 'local-accept' | 'local-revoke' | 'peer-statement' | 'rotation';
698
+ phase: TrustPhase;
699
+ entry: TrustEntry;
700
+ previous?: TrustEntry;
701
+ } | {
702
+ event: 'inbound';
703
+ thread: ThreadRef;
704
+ seq: string;
705
+ sender: NodeId;
706
+ };
707
+ /** RFC 0017 §3: one exchange, as one object. `begin` hands this to the host. */
708
+ export interface KeyExchange {
709
+ /** The peer the host named; the statement proves this identity, never a guess from discovery. */
710
+ readonly node_id: NodeId;
711
+ /** The fingerprint the peer's live key lookup proved at `begin` time. */
712
+ readonly fingerprint: string;
713
+ readonly public_key: string;
714
+ readonly base_url: string;
715
+ /**
716
+ * Commits local approval and sends the signed introduction. `fingerprint` must repeat
717
+ * the value shown to the user: a changed key between display and commit fails here.
718
+ */
719
+ confirm(fingerprint: string): Promise<TrustEntry>;
720
+ }
721
+ /** One trust-table row: a peer's verified public key and the exchange state. */
722
+ export interface TrustEntry {
723
+ readonly node_id: NodeId;
724
+ readonly public_key: string;
725
+ readonly fingerprint: string;
726
+ readonly state: 'pending' | 'trusted' | 'revoked';
727
+ readonly first_seen: string;
728
+ readonly last_checked: string;
729
+ readonly local_approved: boolean;
730
+ readonly remote_approved: boolean;
731
+ readonly base_url: string;
732
+ readonly history?: string[];
733
+ }
734
+ /** The stage derived from the approval halves; the single source hosts read (RFC 0017 §3). */
735
+ export declare function trustPhase(entry: Pick<TrustEntry, 'local_approved' | 'remote_approved' | 'state'>): TrustPhase;
736
+ /**
737
+ * What an admission policy may read. The policy runs inside the admission transaction, so it
738
+ * MUST read through this view and MUST NOT open a storage transaction of its own: the outer
739
+ * transaction still holds the store, and a nested one waits on it forever.
740
+ */
741
+ export interface AdmissionContext {
742
+ /** The peer's exchange stage, or undefined when the two nodes never exchanged keys. */
743
+ trust(node: NodeId): Promise<TrustPhase | undefined>;
744
+ }
745
+ export interface Plugins {
746
+ storage: Storage;
747
+ authenticate(request: Request): Promise<Auth | null>;
748
+ keys?: KeyHook;
749
+ trust_seeds?: TrustSeed[];
750
+ resolve(node: NodeId): Promise<Target>;
751
+ decide(input: MsgInput): Promise<Action>;
752
+ runtime?: Runtime;
753
+ /** When true, candidate exchange allows loopback addresses (useful in local dev & testing). */
754
+ allow_loopback?: boolean;
755
+ /** Supplied when the host wants the library to own the maintenance loop (RFC 0017 §6). */
756
+ maintenanceClock?: MaintenanceClock;
757
+ resources?: ResourceDriver;
758
+ /** The host may adopt a dynamic resource after HTTP authentication and request parsing. */
759
+ prepareResourceOperation?(auth: Auth, ref: ResourceRef, request: OperationRequest): Promise<void>;
760
+ transport?: Transport;
761
+ mayAdmit?(actor: NodeId, thread: ThreadRef, context: AdmissionContext): Promise<boolean>;
762
+ /** Owner policy permitting a first-contact thread and membership for this actor. */
763
+ inboundThread?(actor: NodeId, context: AdmissionContext): Promise<boolean>;
764
+ /**
765
+ * Target-side handover policy (RFC 0006 §4.3): whether this node takes over the resource
766
+ * a probe names. The probe's `metadata` is what it judges from; `sender` is the endpoint
767
+ * whose signature the probe carried. A node without this hook accepts every well-formed
768
+ * probe from an authenticated peer.
769
+ */
770
+ handoverProbe?(probe: HandoverProbe, sender: NodeId): Promise<ProbeAnswer>;
771
+ directory?(): Promise<Json>;
772
+ executionContexts?(): Promise<Json>;
773
+ domainCandidates?(domain_id: DomainId): Promise<NodeId[]>;
774
+ /** Resolves a thread-local mention alias to the member node it names. */
775
+ mention?(alias: string, thread: ThreadRef): Promise<NodeId>;
776
+ /** Observed nodes with trust state; the same rows onlyne://neighbors renders. */
777
+ neighbors?(): Promise<unknown>;
778
+ }
779
+ export interface NodeOptions {
780
+ node_id: NodeId;
781
+ base_url: string;
782
+ plugins: Plugins;
783
+ instance_id?: string;
784
+ authentication?: string[];
785
+ request_bytes?: number;
786
+ retry_max_ms?: number;
787
+ wait_ms?: number;
788
+ /**
789
+ * The trusted tick source, required at construction (RFC 0017 §6). Every protocol
790
+ * clock read — transcript windows, nonce expiry, retry gates — goes through `now`,
791
+ * and every nonce through `id`. A host that cannot supply an unguessable `id` must
792
+ * refuse to run a keyed node instead of falling back to a default.
793
+ */
794
+ now: () => number;
795
+ id: () => string;
796
+ }
797
+ /**
798
+ * RFC 0017 §6: the timer primitives the library's maintenance loop needs. Supplying
799
+ * them opts into `client.runMaintenance`, the loop the library owns: cadence, wake
800
+ * handling and the pending-work re-arm all live there, so a host cannot poll at a
801
+ * rate the protocol does not sanction. `setTimer` is one-shot: it calls `run` once and
802
+ * the loop re-arms, so a host that repeats the callback breaks the cadence contract.
803
+ * Every clock read goes through `NodeOptions.now`; the clock carries no second time source.
804
+ */
805
+ export interface MaintenanceClock {
806
+ setTimer(ms: number, run: () => void): unknown;
807
+ clearTimer(handle: unknown): void;
808
+ }
809
+ //# sourceMappingURL=types.d.ts.map