@ixo/topic-protocol 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +14 -2
  2. package/dist/schemas/topic-capsule.schema.json +2 -1
  3. package/dist/schemas/topic-file-attachment.schema.json +23 -0
  4. package/dist/schemas/topic-index-entry.schema.json +34 -1
  5. package/dist/schemas/topic-index.schema.json +39 -0
  6. package/dist/schemas/topic-operation.schema.json +1 -1
  7. package/dist/schemas/topic-root.schema.json +13 -1
  8. package/dist/schemas/topic-state.schema.json +10 -1
  9. package/dist/src/contracts/schemas.d.ts +212 -1
  10. package/dist/src/contracts/schemas.js +4 -0
  11. package/dist/src/contracts/schemas.js.map +1 -1
  12. package/dist/src/errors.d.ts +1 -1
  13. package/dist/src/errors.js.map +1 -1
  14. package/dist/src/index.d.ts +5 -1
  15. package/dist/src/index.js +5 -1
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/indexing/rank.d.ts +2 -0
  18. package/dist/src/indexing/rank.js +31 -0
  19. package/dist/src/indexing/rank.js.map +1 -0
  20. package/dist/src/indexing/reconcile.d.ts +3 -0
  21. package/dist/src/indexing/reconcile.js +58 -0
  22. package/dist/src/indexing/reconcile.js.map +1 -0
  23. package/dist/src/indexing/search.d.ts +2 -0
  24. package/dist/src/indexing/search.js +37 -0
  25. package/dist/src/indexing/search.js.map +1 -0
  26. package/dist/src/indexing/types.d.ts +75 -0
  27. package/dist/src/indexing/types.js +22 -0
  28. package/dist/src/indexing/types.js.map +1 -0
  29. package/dist/src/matrix/content.d.ts +1 -1
  30. package/dist/src/matrix/content.js +8 -0
  31. package/dist/src/matrix/content.js.map +1 -1
  32. package/dist/src/projector/payload.d.ts +7 -1
  33. package/dist/src/projector/payload.js +86 -2
  34. package/dist/src/projector/payload.js.map +1 -1
  35. package/dist/src/projector/state.js +41 -0
  36. package/dist/src/projector/state.js.map +1 -1
  37. package/dist/src/projector/types.d.ts +32 -1
  38. package/dist/src/projector/types.js +18 -0
  39. package/dist/src/projector/types.js.map +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@ identity of a discussion.
9
9
 
10
10
  ## Status
11
11
 
12
- **Version:** 0.2.0
12
+ **Version:** 0.4.0
13
13
 
14
14
  **Maturity:** Draft implementation candidate
15
15
  **Execution source of truth:** [Linear Topic Protocol project](https://linear.app/ixo-world/project/topic-protocol-4ea58bc7910d)
@@ -39,7 +39,8 @@ key-value adapter at its integration boundary.
39
39
 
40
40
  The package includes:
41
41
 
42
- - strict Draft 2020-12 validation for all 15 contracts;
42
+ - strict Draft 2020-12 validation for all 17 contracts;
43
+ - deterministic Topic-index reconciliation, structured search, and personal ranking;
43
44
  - deterministic Topic projection from a root and authorised operations;
44
45
  - singular accepted Overview projection with deterministic conflict handling;
45
46
  - relation-free Matrix root and canonical native `m.thread` event builders;
@@ -49,6 +50,12 @@ The package includes:
49
50
  - explicit conflict, duplicate-delivery, unauthorised, and unreachable handling;
50
51
  - immutable caller inputs and typed protocol errors.
51
52
 
53
+ Topics retain a singular conversational `kind` while linking any number of
54
+ typed subject contexts. They also project pinned VFS file references without
55
+ copying bytes into Matrix or granting VFS access. A CID, content hash, and
56
+ snapshot metadata are visible to Topic members; the VFS grant remains the
57
+ authority for the file bytes.
58
+
52
59
  Install it in a client:
53
60
 
54
61
  ```bash
@@ -88,6 +95,11 @@ never binds a Topic to a temporary local-echo ID. Pending storage contains only
88
95
  the room ID, Topic ID, root event ID, and creation timestamp; clients must back
89
96
  it with durable local storage to make restart recovery effective.
90
97
 
98
+ Topic index snapshots are plaintext only while in trusted process memory. A
99
+ client persistence adapter must encrypt them at rest. Portal uses Matrix Secret
100
+ Storage, while follow, mute, pin, and mark-unread flags remain room account data
101
+ rather than shared Topic state.
102
+
91
103
  Install development dependencies and run the complete quality gate:
92
104
 
93
105
  ```bash
@@ -3,13 +3,14 @@
3
3
  "$id": "https://topic-protocol.ixo.world/schemas/topic-capsule.schema.json",
4
4
  "title": "Topic Capsule",
5
5
  "type": "object",
6
- "required": ["topicId", "anchor", "stateRevision", "participants", "acceptedMemory", "capabilities", "runtimePolicy"],
6
+ "required": ["topicId", "anchor", "stateRevision", "participants", "attachments", "acceptedMemory", "capabilities", "runtimePolicy"],
7
7
  "properties": {
8
8
  "topicId": { "type": "string", "pattern": "^ixo:topic:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" },
9
9
  "anchor": { "type": "object", "required": ["roomId", "rootEventId"], "properties": { "roomId": { "type": "string" }, "rootEventId": { "type": "string", "pattern": "^\\$" } } },
10
10
  "stateRevision": { "type": "string", "minLength": 1 },
11
11
  "participants": { "type": "array", "items": { "type": "object" } },
12
12
  "linkedContext": { "type": "array", "items": { "type": "object" } },
13
+ "attachments": { "type": "array", "items": { "$ref": "https://topic-protocol.ixo.world/schemas/topic-file-attachment.schema.json" } },
13
14
  "acceptedMemory": { "type": "array", "items": { "type": "object" } },
14
15
  "relevantEvents": { "type": "array", "items": { "type": "object" } },
15
16
  "capabilities": { "type": "array", "items": { "type": "object" } },
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://topic-protocol.ixo.world/schemas/topic-file-attachment.schema.json",
4
+ "title": "Pinned Topic VFS file reference",
5
+ "type": "object",
6
+ "required": ["provider", "resource", "fileId", "version", "cid", "contentHash", "path", "name", "mimeType", "size"],
7
+ "properties": {
8
+ "provider": { "const": "ixo.vfs" },
9
+ "resource": { "type": "string", "pattern": "^ixo:filesystem/.+" },
10
+ "fileId": { "type": "string", "minLength": 1 },
11
+ "version": { "type": "integer", "minimum": 1 },
12
+ "cid": { "type": "string", "minLength": 1 },
13
+ "contentHash": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
14
+ "path": { "type": "string", "pattern": "^/(?!.*(?:^|/)\\.\\.(?:/|$)).+" },
15
+ "name": { "type": "string", "minLength": 1 },
16
+ "mimeType": { "type": "string", "minLength": 1 },
17
+ "size": { "type": "integer", "minimum": 0 },
18
+ "attachedBy": { "type": "string", "minLength": 1 },
19
+ "attachedAt": { "type": "string", "format": "date-time" },
20
+ "operationId": { "type": "string", "minLength": 1 }
21
+ },
22
+ "additionalProperties": false
23
+ }
@@ -8,10 +8,43 @@
8
8
  "topicId": { "type": "string", "pattern": "^ixo:topic:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" },
9
9
  "roomId": { "type": "string", "minLength": 1 },
10
10
  "rootEventId": { "type": "string", "pattern": "^\\$" },
11
+ "title": { "type": "string", "minLength": 1, "maxLength": 280 },
12
+ "currentState": { "type": "string", "minLength": 1, "maxLength": 280 },
11
13
  "status": { "type": "string" },
14
+ "kind": { "type": "string", "enum": ["discussion", "question", "decision", "proposal", "task", "incident", "flow"] },
15
+ "domain": {
16
+ "type": "object",
17
+ "required": ["id"],
18
+ "properties": {
19
+ "id": { "type": "string", "minLength": 1 },
20
+ "name": { "type": "string", "minLength": 1 }
21
+ },
22
+ "additionalProperties": false
23
+ },
24
+ "context": {
25
+ "type": "array",
26
+ "items": {
27
+ "type": "object",
28
+ "required": ["type", "id"],
29
+ "properties": {
30
+ "type": { "type": "string", "minLength": 1 },
31
+ "id": { "type": "string", "minLength": 1 }
32
+ },
33
+ "additionalProperties": false
34
+ }
35
+ },
36
+ "sourceKinds": {
37
+ "type": "array",
38
+ "uniqueItems": true,
39
+ "items": { "type": "string", "enum": ["message", "flow", "decision", "artifact", "notification", "other"] }
40
+ },
12
41
  "latestActivityAt": { "type": "string", "format": "date-time" },
42
+ "latestEventId": { "type": "string", "pattern": "^\\$" },
43
+ "participated": { "type": "boolean" },
44
+ "unread": { "type": "string", "enum": ["unread", "read", "unknown"] },
13
45
  "notificationMode": { "type": "string", "enum": ["follow", "default", "mute"] },
14
- "completeness": { "type": "string", "enum": ["complete", "partial-history", "metadata-pending", "decryption-pending"] }
46
+ "completeness": { "type": "string", "enum": ["complete", "partial-history", "metadata-pending", "decryption-pending"] },
47
+ "indexedAt": { "type": "string", "format": "date-time" }
15
48
  },
16
49
  "additionalProperties": true
17
50
  }
@@ -0,0 +1,39 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://topic-protocol.ixo.world/schemas/topic-index.schema.json",
4
+ "title": "Encrypted Topic index plaintext snapshot",
5
+ "type": "object",
6
+ "required": ["version", "updatedAt", "entries", "tombstones"],
7
+ "properties": {
8
+ "version": { "const": 1 },
9
+ "updatedAt": { "type": "string", "format": "date-time" },
10
+ "entries": {
11
+ "type": "array",
12
+ "items": {
13
+ "allOf": [
14
+ { "$ref": "https://topic-protocol.ixo.world/schemas/topic-index-entry.schema.json" },
15
+ {
16
+ "type": "object",
17
+ "required": ["participated", "unread", "indexedAt"],
18
+ "properties": {
19
+ "status": { "type": "string", "enum": ["draft", "active", "waiting", "blocked", "resolved", "archived", "redirected"] }
20
+ }
21
+ }
22
+ ]
23
+ }
24
+ },
25
+ "tombstones": {
26
+ "type": "array",
27
+ "items": {
28
+ "type": "object",
29
+ "required": ["roomId", "removedAt"],
30
+ "properties": {
31
+ "roomId": { "type": "string", "minLength": 1 },
32
+ "removedAt": { "type": "string", "format": "date-time" }
33
+ },
34
+ "additionalProperties": false
35
+ }
36
+ }
37
+ },
38
+ "additionalProperties": false
39
+ }
@@ -8,7 +8,7 @@
8
8
  "version": { "const": 1 },
9
9
  "operationId": { "type": "string", "minLength": 1 },
10
10
  "topicId": { "type": "string", "pattern": "^ixo:topic:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" },
11
- "type": { "type": "string", "enum": ["rename", "change-status", "update-overview", "link-context", "unlink-context", "record-decision", "redirect", "branch", "merge", "resolve-conflict"] },
11
+ "type": { "type": "string", "enum": ["rename", "change-status", "update-overview", "link-context", "unlink-context", "attach-files", "detach-files", "record-decision", "redirect", "branch", "merge", "resolve-conflict"] },
12
12
  "previousRevision": { "type": "string", "minLength": 1 },
13
13
  "actor": { "type": "string", "minLength": 1 },
14
14
  "createdAt": { "type": "string", "format": "date-time" },
@@ -12,7 +12,19 @@
12
12
  "status": { "type": "string", "enum": ["draft", "active", "waiting", "blocked", "resolved", "archived", "redirected"] },
13
13
  "createdBy": { "type": "string", "minLength": 1 },
14
14
  "createdAt": { "type": "string", "format": "date-time" },
15
- "context": { "type": "array", "items": { "type": "object", "required": ["type", "id"], "properties": { "type": { "type": "string" }, "id": { "type": "string" } } } },
15
+ "context": {
16
+ "type": "array",
17
+ "uniqueItems": true,
18
+ "items": {
19
+ "type": "object",
20
+ "required": ["type", "id"],
21
+ "properties": {
22
+ "type": { "type": "string", "minLength": 1 },
23
+ "id": { "type": "string", "minLength": 1 }
24
+ },
25
+ "additionalProperties": false
26
+ }
27
+ },
16
28
  "overview": {
17
29
  "type": "object",
18
30
  "required": ["summary"],
@@ -3,7 +3,7 @@
3
3
  "$id": "https://topic-protocol.ixo.world/schemas/topic-state.schema.json",
4
4
  "title": "Projected Topic state",
5
5
  "type": "object",
6
- "required": ["topicId", "revision", "status", "basedOnEvents", "conflicts"],
6
+ "required": ["topicId", "revision", "status", "attachments", "basedOnEvents", "conflicts"],
7
7
  "properties": {
8
8
  "topicId": { "type": "string", "pattern": "^ixo:topic:[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" },
9
9
  "revision": { "type": "string", "minLength": 1 },
@@ -24,6 +24,15 @@
24
24
  "acceptedFacts": { "type": "array", "items": { "type": "object" } },
25
25
  "decisions": { "type": "array", "items": { "type": "object" } },
26
26
  "unresolvedQuestions": { "type": "array", "items": { "type": "object" } },
27
+ "attachments": {
28
+ "type": "array",
29
+ "items": {
30
+ "allOf": [
31
+ { "$ref": "https://topic-protocol.ixo.world/schemas/topic-file-attachment.schema.json" },
32
+ { "type": "object", "required": ["attachedBy", "attachedAt", "operationId"] }
33
+ ]
34
+ }
35
+ },
27
36
  "basedOnEvents": { "type": "array", "items": { "type": "string", "pattern": "^\\$" } },
28
37
  "conflicts": { "type": "array", "items": { "type": "string" } }
29
38
  },
@@ -197,6 +197,12 @@ export declare const SCHEMA_REGISTRY: Readonly<{
197
197
  type: string;
198
198
  };
199
199
  };
200
+ attachments: {
201
+ type: string;
202
+ items: {
203
+ $ref: string;
204
+ };
205
+ };
200
206
  acceptedMemory: {
201
207
  type: string;
202
208
  items: {
@@ -221,6 +227,67 @@ export declare const SCHEMA_REGISTRY: Readonly<{
221
227
  };
222
228
  additionalProperties: boolean;
223
229
  };
230
+ "topic-file-attachment": {
231
+ $schema: string;
232
+ $id: string;
233
+ title: string;
234
+ type: string;
235
+ required: string[];
236
+ properties: {
237
+ provider: {
238
+ const: string;
239
+ };
240
+ resource: {
241
+ type: string;
242
+ pattern: string;
243
+ };
244
+ fileId: {
245
+ type: string;
246
+ minLength: number;
247
+ };
248
+ version: {
249
+ type: string;
250
+ minimum: number;
251
+ };
252
+ cid: {
253
+ type: string;
254
+ minLength: number;
255
+ };
256
+ contentHash: {
257
+ type: string;
258
+ pattern: string;
259
+ };
260
+ path: {
261
+ type: string;
262
+ pattern: string;
263
+ };
264
+ name: {
265
+ type: string;
266
+ minLength: number;
267
+ };
268
+ mimeType: {
269
+ type: string;
270
+ minLength: number;
271
+ };
272
+ size: {
273
+ type: string;
274
+ minimum: number;
275
+ };
276
+ attachedBy: {
277
+ type: string;
278
+ minLength: number;
279
+ };
280
+ attachedAt: {
281
+ type: string;
282
+ format: string;
283
+ };
284
+ operationId: {
285
+ type: string;
286
+ minLength: number;
287
+ };
288
+ };
289
+ additionalProperties: boolean;
290
+ };
224
291
  "topic-index-entry": {
225
292
  $schema: string;
226
293
  $id: string;
@@ -240,13 +307,79 @@ export declare const SCHEMA_REGISTRY: Readonly<{
240
307
  type: string;
241
308
  pattern: string;
242
309
  };
310
+ title: {
311
+ type: string;
312
+ minLength: number;
313
+ maxLength: number;
314
+ };
315
+ currentState: {
316
+ type: string;
317
+ minLength: number;
318
+ maxLength: number;
319
+ };
243
320
  status: {
244
321
  type: string;
245
322
  };
323
+ kind: {
324
+ type: string;
325
+ enum: string[];
326
+ };
327
+ domain: {
328
+ type: string;
329
+ required: string[];
330
+ properties: {
331
+ id: {
332
+ type: string;
333
+ minLength: number;
334
+ };
335
+ name: {
336
+ type: string;
337
+ minLength: number;
338
+ };
339
+ };
340
+ additionalProperties: boolean;
341
+ };
342
+ context: {
343
+ type: string;
344
+ items: {
345
+ type: string;
346
+ required: string[];
347
+ properties: {
348
+ type: {
349
+ type: string;
350
+ minLength: number;
351
+ };
352
+ id: {
353
+ type: string;
354
+ minLength: number;
355
+ };
356
+ };
357
+ additionalProperties: boolean;
358
+ };
359
+ };
360
+ sourceKinds: {
361
+ type: string;
362
+ uniqueItems: boolean;
363
+ items: {
364
+ type: string;
365
+ enum: string[];
366
+ };
367
+ };
246
368
  latestActivityAt: {
247
369
  type: string;
248
370
  format: string;
249
371
  };
372
+ latestEventId: {
373
+ type: string;
374
+ pattern: string;
375
+ };
376
+ participated: {
377
+ type: string;
378
+ };
379
+ unread: {
380
+ type: string;
381
+ enum: string[];
382
+ };
250
383
  notificationMode: {
251
384
  type: string;
252
385
  enum: string[];
@@ -255,6 +388,66 @@ export declare const SCHEMA_REGISTRY: Readonly<{
255
388
  type: string;
256
389
  enum: string[];
257
390
  };
391
+ indexedAt: {
392
+ type: string;
393
+ format: string;
394
+ };
395
+ };
396
+ additionalProperties: boolean;
397
+ };
398
+ "topic-index": {
399
+ $schema: string;
400
+ $id: string;
401
+ title: string;
402
+ type: string;
403
+ required: string[];
404
+ properties: {
405
+ version: {
406
+ const: number;
407
+ };
408
+ updatedAt: {
409
+ type: string;
410
+ format: string;
411
+ };
412
+ entries: {
413
+ type: string;
414
+ items: {
415
+ allOf: ({
416
+ $ref: string;
417
+ type?: never;
418
+ required?: never;
419
+ properties?: never;
420
+ } | {
421
+ type: string;
422
+ required: string[];
423
+ properties: {
424
+ status: {
425
+ type: string;
426
+ enum: string[];
427
+ };
428
+ };
429
+ $ref?: never;
430
+ })[];
431
+ };
432
+ };
433
+ tombstones: {
434
+ type: string;
435
+ items: {
436
+ type: string;
437
+ required: string[];
438
+ properties: {
439
+ roomId: {
440
+ type: string;
441
+ minLength: number;
442
+ };
443
+ removedAt: {
444
+ type: string;
445
+ format: string;
446
+ };
447
+ };
448
+ additionalProperties: boolean;
449
+ };
450
+ };
258
451
  };
259
452
  additionalProperties: boolean;
260
453
  };
@@ -529,17 +722,21 @@ export declare const SCHEMA_REGISTRY: Readonly<{
529
722
  };
530
723
  context: {
531
724
  type: string;
725
+ uniqueItems: boolean;
532
726
  items: {
533
727
  type: string;
534
728
  required: string[];
535
729
  properties: {
536
730
  type: {
537
731
  type: string;
732
+ minLength: number;
538
733
  };
539
734
  id: {
540
735
  type: string;
736
+ minLength: number;
541
737
  };
542
738
  };
739
+ additionalProperties: boolean;
543
740
  };
544
741
  };
545
742
  overview: {
@@ -644,6 +841,20 @@ export declare const SCHEMA_REGISTRY: Readonly<{
644
841
  type: string;
645
842
  };
646
843
  };
844
+ attachments: {
845
+ type: string;
846
+ items: {
847
+ allOf: ({
848
+ $ref: string;
849
+ type?: never;
850
+ required?: never;
851
+ } | {
852
+ type: string;
853
+ required: string[];
854
+ $ref?: never;
855
+ })[];
856
+ };
857
+ };
647
858
  basedOnEvents: {
648
859
  type: string;
649
860
  items: {
@@ -782,4 +993,4 @@ export declare const SCHEMA_REGISTRY: Readonly<{
782
993
  };
783
994
  }>;
784
995
  export type ContractName = keyof typeof SCHEMA_REGISTRY;
785
- export declare const CONTRACT_NAMES: readonly ("action-receipt" | "agent-run" | "external-session-binding" | "room-policy" | "topic-capsule" | "topic-index-entry" | "topic-message" | "topic-operation" | "topic-preferences" | "topic-record" | "topic-record-message" | "topic-relation" | "topic-root" | "topic-state" | "topic-source-message")[];
996
+ export declare const CONTRACT_NAMES: readonly ("action-receipt" | "agent-run" | "external-session-binding" | "room-policy" | "topic-capsule" | "topic-file-attachment" | "topic-index-entry" | "topic-index" | "topic-message" | "topic-operation" | "topic-preferences" | "topic-record" | "topic-record-message" | "topic-relation" | "topic-root" | "topic-state" | "topic-source-message")[];
@@ -3,7 +3,9 @@ import agentRun from "../../schemas/agent-run.schema.json" with { type: "json" }
3
3
  import externalSessionBinding from "../../schemas/external-session-binding.schema.json" with { type: "json" };
4
4
  import roomPolicy from "../../schemas/room-policy.schema.json" with { type: "json" };
5
5
  import topicCapsule from "../../schemas/topic-capsule.schema.json" with { type: "json" };
6
+ import topicFileAttachment from "../../schemas/topic-file-attachment.schema.json" with { type: "json" };
6
7
  import topicIndexEntry from "../../schemas/topic-index-entry.schema.json" with { type: "json" };
8
+ import topicIndex from "../../schemas/topic-index.schema.json" with { type: "json" };
7
9
  import topicMessage from "../../schemas/topic-message.schema.json" with { type: "json" };
8
10
  import topicOperation from "../../schemas/topic-operation.schema.json" with { type: "json" };
9
11
  import topicPreferences from "../../schemas/topic-preferences.schema.json" with { type: "json" };
@@ -19,7 +21,9 @@ export const SCHEMA_REGISTRY = Object.freeze({
19
21
  "external-session-binding": externalSessionBinding,
20
22
  "room-policy": roomPolicy,
21
23
  "topic-capsule": topicCapsule,
24
+ "topic-file-attachment": topicFileAttachment,
22
25
  "topic-index-entry": topicIndexEntry,
26
+ "topic-index": topicIndex,
23
27
  "topic-message": topicMessage,
24
28
  "topic-operation": topicOperation,
25
29
  "topic-preferences": topicPreferences,
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/contracts/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,QAAQ,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,sBAAsB,MAAM,oDAAoD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9G,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,eAAe,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,cAAc,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjG,OAAO,WAAW,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACvF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtG,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,SAAS,MAAM,sCAAsC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACnF,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtG,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,gBAAgB,EAAE,aAAa;IAC/B,WAAW,EAAE,QAAQ;IACrB,0BAA0B,EAAE,sBAAsB;IAClD,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,mBAAmB,EAAE,eAAe;IACpC,eAAe,EAAE,YAAY;IAC7B,iBAAiB,EAAE,cAAc;IACjC,mBAAmB,EAAE,gBAAgB;IACrC,cAAc,EAAE,WAAW;IAC3B,sBAAsB,EAAE,kBAAkB;IAC1C,gBAAgB,EAAE,aAAa;IAC/B,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;IACzB,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CACzC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAoB,CACtD,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/contracts/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,QAAQ,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,sBAAsB,MAAM,oDAAoD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9G,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,mBAAmB,MAAM,iDAAiD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxG,OAAO,eAAe,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,cAAc,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjG,OAAO,WAAW,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACvF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtG,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,SAAS,MAAM,sCAAsC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACnF,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtG,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,gBAAgB,EAAE,aAAa;IAC/B,WAAW,EAAE,QAAQ;IACrB,0BAA0B,EAAE,sBAAsB;IAClD,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,uBAAuB,EAAE,mBAAmB;IAC5C,mBAAmB,EAAE,eAAe;IACpC,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,iBAAiB,EAAE,cAAc;IACjC,mBAAmB,EAAE,gBAAgB;IACrC,cAAc,EAAE,WAAW;IAC3B,sBAAsB,EAAE,kBAAkB;IAC1C,gBAAgB,EAAE,aAAa;IAC/B,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;IACzB,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CACzC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAoB,CACtD,CAAC"}
@@ -1,4 +1,4 @@
1
- export type TopicProtocolErrorCode = "ANCHOR_CONFLICT" | "ANCHOR_CYCLE" | "AUTHORIZATION_FAILED" | "CONTRACT_VALIDATION_FAILED" | "DUPLICATE_OPERATION" | "FIRST_MESSAGE_FAILED" | "INVALID_ANCHOR" | "INVALID_MATRIX_EVENT" | "INVALID_OPERATION_PAYLOAD" | "INVALID_SERVER_EVENT_ID" | "NON_CANONICAL_CONFLICT_SELECTION" | "PENDING_ROOT_UNRESOLVED" | "ROOT_CREATION_FAILED" | "ROOT_DISCOVERY_FAILED" | "STORAGE_FAILED" | "TOPIC_ROOT_NOT_FOUND" | "TOPIC_MISMATCH" | "UNKNOWN_CONFLICT" | "UNKNOWN_CONTRACT";
1
+ export type TopicProtocolErrorCode = "ANCHOR_CONFLICT" | "ANCHOR_CYCLE" | "AUTHORIZATION_FAILED" | "CONTRACT_VALIDATION_FAILED" | "DUPLICATE_OPERATION" | "FIRST_MESSAGE_FAILED" | "INVALID_ANCHOR" | "INVALID_CONTEXT_TYPE" | "INVALID_MATRIX_EVENT" | "INVALID_OPERATION_PAYLOAD" | "INVALID_SERVER_EVENT_ID" | "NON_CANONICAL_CONFLICT_SELECTION" | "PENDING_ROOT_UNRESOLVED" | "ROOT_CREATION_FAILED" | "ROOT_DISCOVERY_FAILED" | "STORAGE_FAILED" | "TOPIC_ROOT_NOT_FOUND" | "TOPIC_MISMATCH" | "UNKNOWN_CONFLICT" | "UNKNOWN_CONTRACT";
2
2
  export declare class TopicProtocolError extends Error {
3
3
  readonly code: TopicProtocolErrorCode;
4
4
  readonly details: Readonly<Record<string, unknown>>;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAqBA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,CAAyB;IAC7B,OAAO,CAAoC;IAEpD,YACE,IAA4B,EAC5B,OAAe,EACf,UAA6C,EAAE,EAC/C,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAsBA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,CAAyB;IAC7B,OAAO,CAAoC;IAEpD,YACE,IAA4B,EAC5B,OAAe,EACf,UAA6C,EAAE,EAC/C,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
@@ -9,5 +9,9 @@ export { isTopicInfrastructureEvent, parseTopicRootEvent, projectMatrixTopic, }
9
9
  export { JsonPendingTopicStore, MemoryPendingTopicStore, type TopicKeyValueStore, } from "./matrix/pending.js";
10
10
  export { TopicRuntime, type TopicRuntimeOptions } from "./matrix/runtime.js";
11
11
  export { MATRIX_ROOM_MESSAGE, TOPIC_ANCHOR_KEY, TOPIC_METADATA_KEY, TOPIC_OPERATION_EVENT_TYPE, type CanonicalTopicAnchor, type MatrixEventContent, type MatrixSendRequest, type MatrixTopicProjection, type MatrixTopicProjectionInput, type ParsedTopicRoot, type PendingTopicCreation, type PendingTopicStore, type RejectedTopicEvent, type RejectedTopicEventReason, type TopicAnchorConflict, type TopicCreationInput, type TopicCreationResult, type TopicFirstMessageFactory, type TopicMatrixEvent, type TopicMatrixTransport, type TopicRootContentOptions, } from "./matrix/types.js";
12
- export { TOPIC_KINDS, TOPIC_STATUSES, type IgnoredOperation, type IgnoredOperationReason, type MatrixAnchor, type ProjectedTopicRelation, type ProjectionInput, type TopicContext, type TopicDecision, type TopicKind, type TopicNextStep, type TopicOperation, type TopicOperationType, type TopicProjection, type ProjectedTopicOverview, type TopicOverview, type TopicProjectionConflict, type TopicRelationType, type TopicRoot, type TopicStatus, } from "./projector/types.js";
12
+ export { TOPIC_KINDS, TOPIC_CONTEXT_TYPES, TOPIC_STATUSES, TOPIC_VFS_FILE_PROVIDER, type IgnoredOperation, type IgnoredOperationReason, type MatrixAnchor, type ProjectedTopicRelation, type ProjectionInput, type TopicContext, type TopicContextType, type TopicFileAttachmentIdentity, type TopicDecision, type TopicKind, type TopicNextStep, type TopicOperation, type TopicOperationType, type TopicProjection, type ProjectedTopicAttachment, type ProjectedTopicOverview, type TopicOverview, type TopicProjectionConflict, type TopicRelationType, type TopicRoot, type TopicStatus, type TopicVfsFileReference, isCanonicalTopicContextType, } from "./projector/types.js";
13
13
  export { TOPIC_RECORD_KINDS, type TopicRecord, type TopicRecordKind, } from "./records/types.js";
14
+ export { emptyTopicIndexSnapshot, reconcileTopicIndex } from "./indexing/reconcile.js";
15
+ export { searchTopicIndex } from "./indexing/search.js";
16
+ export { rankTopicIndex } from "./indexing/rank.js";
17
+ export { TOPIC_INDEX_COMPLETENESS, TOPIC_INDEX_RANK_REASONS, TOPIC_INDEX_STORAGE_STATES, TOPIC_INDEX_UNREAD_STATES, TOPIC_NOTIFICATION_MODES, type RankedTopicIndexEntry, type TopicAttentionSignalMap, type TopicAttentionSignals, type TopicIndexCompleteness, type TopicIndexDomain, type TopicIndexEntry, type TopicIndexObservation, type TopicIndexRankReason, type TopicIndexReconciliation, type TopicIndexSearchFilters, type TopicIndexSnapshot, type TopicIndexStorageState, type TopicIndexTombstone, type TopicIndexUnreadState, type TopicNotificationMode, type TopicPreference, type TopicPreferenceMap, } from "./indexing/types.js";
package/dist/src/index.js CHANGED
@@ -9,6 +9,10 @@ export { isTopicInfrastructureEvent, parseTopicRootEvent, projectMatrixTopic, }
9
9
  export { JsonPendingTopicStore, MemoryPendingTopicStore, } from "./matrix/pending.js";
10
10
  export { TopicRuntime } from "./matrix/runtime.js";
11
11
  export { MATRIX_ROOM_MESSAGE, TOPIC_ANCHOR_KEY, TOPIC_METADATA_KEY, TOPIC_OPERATION_EVENT_TYPE, } from "./matrix/types.js";
12
- export { TOPIC_KINDS, TOPIC_STATUSES, } from "./projector/types.js";
12
+ export { TOPIC_KINDS, TOPIC_CONTEXT_TYPES, TOPIC_STATUSES, TOPIC_VFS_FILE_PROVIDER, isCanonicalTopicContextType, } from "./projector/types.js";
13
13
  export { TOPIC_RECORD_KINDS, } from "./records/types.js";
14
+ export { emptyTopicIndexSnapshot, reconcileTopicIndex } from "./indexing/reconcile.js";
15
+ export { searchTopicIndex } from "./indexing/search.js";
16
+ export { rankTopicIndex } from "./indexing/rank.js";
17
+ export { TOPIC_INDEX_COMPLETENESS, TOPIC_INDEX_RANK_REASONS, TOPIC_INDEX_STORAGE_STATES, TOPIC_INDEX_UNREAD_STATES, TOPIC_NOTIFICATION_MODES, } from "./indexing/types.js";
14
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,GAS/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAA4B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,GAkB3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,cAAc,GAmBf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,GAS/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAA4B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,GAkB3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EAuBvB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,GAkBzB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { RankedTopicIndexEntry, TopicAttentionSignalMap, TopicIndexEntry, TopicPreferenceMap } from "./types.js";
2
+ export declare function rankTopicIndex(entries: readonly TopicIndexEntry[], preferences?: TopicPreferenceMap, signals?: TopicAttentionSignalMap): RankedTopicIndexEntry[];
@@ -0,0 +1,31 @@
1
+ import { compareText } from "../shared/compare.js";
2
+ const REASON_RANK = {
3
+ pinned: 0,
4
+ "direct-attention": 1,
5
+ "followed-unread": 2,
6
+ participated: 3,
7
+ recent: 4,
8
+ };
9
+ function reasonFor(entry, preferences, signals) {
10
+ const preference = preferences[entry.topicId];
11
+ if (preference?.pinned)
12
+ return "pinned";
13
+ if (signals[entry.topicId]?.directAttention)
14
+ return "direct-attention";
15
+ if (preference?.notificationMode === "follow" && entry.unread === "unread")
16
+ return "followed-unread";
17
+ if (entry.participated)
18
+ return "participated";
19
+ return "recent";
20
+ }
21
+ function compareRanked(left, right) {
22
+ return REASON_RANK[left.reason] - REASON_RANK[right.reason]
23
+ || compareText(right.entry.latestActivityAt, left.entry.latestActivityAt)
24
+ || compareText(left.entry.topicId, right.entry.topicId);
25
+ }
26
+ export function rankTopicIndex(entries, preferences = {}, signals = {}) {
27
+ return entries
28
+ .map((entry) => ({ entry, reason: reasonFor(entry, preferences, signals) }))
29
+ .sort(compareRanked);
30
+ }
31
+ //# sourceMappingURL=rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.js","sourceRoot":"","sources":["../../../src/indexing/rank.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AASnD,MAAM,WAAW,GAAyC;IACxD,MAAM,EAAE,CAAC;IACT,kBAAkB,EAAE,CAAC;IACrB,iBAAiB,EAAE,CAAC;IACpB,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,SAAS,SAAS,CAAC,KAAsB,EAAE,WAA+B,EAAE,OAAgC;IAC1G,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,UAAU,EAAE,MAAM;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,eAAe;QAAE,OAAO,kBAAkB,CAAC;IACvE,IAAI,UAAU,EAAE,gBAAgB,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,iBAAiB,CAAC;IACrG,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,cAAc,CAAC;IAC9C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAA2B,EAAE,KAA4B;IAC9E,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;WACtD,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;WACtE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAmC,EACnC,cAAkC,EAAE,EACpC,UAAmC,EAAE;IAErC,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;SAC3E,IAAI,CAAC,aAAa,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TopicIndexReconciliation, TopicIndexSnapshot } from "./types.js";
2
+ export declare function emptyTopicIndexSnapshot(updatedAt: string): TopicIndexSnapshot;
3
+ export declare function reconcileTopicIndex(snapshot: TopicIndexSnapshot, input: TopicIndexReconciliation): TopicIndexSnapshot;