@agentshouse/mdruntime 0.1.0-cde2b99d2fcbc → 0.1.0-ce131cb435f8b

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 (146) hide show
  1. package/AGENTS.md +271 -290
  2. package/README.md +8 -8
  3. package/dist/adapter.d.ts +52 -10
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/attempt.d.ts.map +1 -1
  6. package/dist/attempt.js +14 -1
  7. package/dist/bootstrap.d.ts +3 -2
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +33 -7
  10. package/dist/change-set.d.ts +2 -0
  11. package/dist/change-set.d.ts.map +1 -1
  12. package/dist/change-set.js +36 -10
  13. package/dist/chat/acts.d.ts +3 -4
  14. package/dist/chat/acts.d.ts.map +1 -1
  15. package/dist/chat/acts.js +10 -10
  16. package/dist/chat/earlier.d.ts +10 -0
  17. package/dist/chat/earlier.d.ts.map +1 -0
  18. package/dist/chat/earlier.js +54 -0
  19. package/dist/chat/kit.d.ts +2 -1
  20. package/dist/chat/kit.d.ts.map +1 -1
  21. package/dist/chat/kit.js +3 -3
  22. package/dist/chat/list.d.ts +8 -1
  23. package/dist/chat/list.d.ts.map +1 -1
  24. package/dist/chat/list.js +48 -8
  25. package/dist/chat/markdown.d.ts +2 -1
  26. package/dist/chat/markdown.d.ts.map +1 -1
  27. package/dist/chat/markdown.js +7 -6
  28. package/dist/chat/message.d.ts.map +1 -1
  29. package/dist/chat/message.js +2 -2
  30. package/dist/chat/messages.d.ts +1 -0
  31. package/dist/chat/messages.d.ts.map +1 -1
  32. package/dist/chat/messages.js +4 -0
  33. package/dist/chat/provider.d.ts +1 -1
  34. package/dist/chat/provider.d.ts.map +1 -1
  35. package/dist/chat/provider.js +62 -79
  36. package/dist/chat/question.d.ts +1 -1
  37. package/dist/chat/question.d.ts.map +1 -1
  38. package/dist/chat/question.js +7 -18
  39. package/dist/chat/ready.d.ts +1 -0
  40. package/dist/chat/ready.d.ts.map +1 -1
  41. package/dist/chat/ready.js +4 -4
  42. package/dist/chat/style.js +5 -5
  43. package/dist/client.d.ts +17 -9
  44. package/dist/client.d.ts.map +1 -1
  45. package/dist/client.js +19 -6
  46. package/dist/collection.d.ts +20 -5
  47. package/dist/collection.d.ts.map +1 -1
  48. package/dist/collection.js +309 -33
  49. package/dist/connection.d.ts +31 -9
  50. package/dist/connection.d.ts.map +1 -1
  51. package/dist/connection.js +1620 -397
  52. package/dist/conversation.d.ts +20 -7
  53. package/dist/conversation.d.ts.map +1 -1
  54. package/dist/conversation.js +474 -163
  55. package/dist/durability.d.ts +7 -1
  56. package/dist/durability.d.ts.map +1 -1
  57. package/dist/entry.d.ts +17 -0
  58. package/dist/entry.d.ts.map +1 -0
  59. package/dist/entry.js +157 -0
  60. package/dist/fence.d.ts +6 -0
  61. package/dist/fence.d.ts.map +1 -0
  62. package/dist/fence.js +10 -0
  63. package/dist/host.d.ts +15 -3
  64. package/dist/host.d.ts.map +1 -1
  65. package/dist/host.js +94 -12
  66. package/dist/identity.d.ts +2 -0
  67. package/dist/identity.d.ts.map +1 -1
  68. package/dist/identity.js +6 -0
  69. package/dist/index.d.ts +10 -7
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -0
  72. package/dist/memory.d.ts +8 -2
  73. package/dist/memory.d.ts.map +1 -1
  74. package/dist/memory.js +33 -6
  75. package/dist/model.d.ts +4 -2
  76. package/dist/model.d.ts.map +1 -1
  77. package/dist/model.js +10 -1
  78. package/dist/observation.d.ts +7 -2
  79. package/dist/observation.d.ts.map +1 -1
  80. package/dist/observation.js +29 -12
  81. package/dist/outcome.d.ts +12 -2
  82. package/dist/outcome.d.ts.map +1 -1
  83. package/dist/outcome.js +4 -0
  84. package/dist/overlay.d.ts +3 -0
  85. package/dist/overlay.d.ts.map +1 -1
  86. package/dist/overlay.js +62 -55
  87. package/dist/query.d.ts +56 -4
  88. package/dist/query.d.ts.map +1 -1
  89. package/dist/query.js +36 -7
  90. package/dist/reach.d.ts +6 -3
  91. package/dist/reach.d.ts.map +1 -1
  92. package/dist/reach.js +30 -5
  93. package/dist/react.d.ts +8 -6
  94. package/dist/react.d.ts.map +1 -1
  95. package/dist/react.js +7 -17
  96. package/dist/read-side.d.ts +16 -7
  97. package/dist/read-side.d.ts.map +1 -1
  98. package/dist/read-side.js +484 -100
  99. package/dist/readiness.d.ts +53 -0
  100. package/dist/readiness.d.ts.map +1 -0
  101. package/dist/readiness.js +33 -0
  102. package/dist/reads.d.ts +11 -0
  103. package/dist/reads.d.ts.map +1 -0
  104. package/dist/reads.js +98 -0
  105. package/dist/recovery.d.ts +25 -0
  106. package/dist/recovery.d.ts.map +1 -0
  107. package/dist/recovery.js +197 -0
  108. package/dist/refresh.d.ts +4 -4
  109. package/dist/refresh.d.ts.map +1 -1
  110. package/dist/refresh.js +18 -11
  111. package/dist/replica.d.ts +10 -5
  112. package/dist/replica.d.ts.map +1 -1
  113. package/dist/replica.js +96 -44
  114. package/dist/room-draft.d.ts +13 -1
  115. package/dist/room-draft.d.ts.map +1 -1
  116. package/dist/room-draft.js +2 -2
  117. package/dist/rows.d.ts +6 -13
  118. package/dist/rows.d.ts.map +1 -1
  119. package/dist/rows.js +10 -13
  120. package/dist/save.d.ts +9 -3
  121. package/dist/save.d.ts.map +1 -1
  122. package/dist/save.js +68 -22
  123. package/dist/search.d.ts +49 -6
  124. package/dist/search.d.ts.map +1 -1
  125. package/dist/search.js +192 -47
  126. package/dist/seed.d.ts +16 -0
  127. package/dist/seed.d.ts.map +1 -0
  128. package/dist/seed.js +75 -0
  129. package/dist/shared.d.ts +14 -0
  130. package/dist/shared.d.ts.map +1 -0
  131. package/dist/shared.js +394 -0
  132. package/dist/status.d.ts +4 -0
  133. package/dist/status.d.ts.map +1 -1
  134. package/dist/store.d.ts +64 -16
  135. package/dist/store.d.ts.map +1 -1
  136. package/dist/store.js +447 -178
  137. package/dist/turn.d.ts +9 -0
  138. package/dist/turn.d.ts.map +1 -0
  139. package/dist/turn.js +64 -0
  140. package/dist/windows.d.ts +26 -0
  141. package/dist/windows.d.ts.map +1 -0
  142. package/dist/windows.js +93 -0
  143. package/dist/wire.d.ts +152 -32
  144. package/dist/wire.d.ts.map +1 -1
  145. package/dist/wire.js +52 -31
  146. package/package.json +12 -8
package/dist/save.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { definitionOf } from './model.js';
2
2
  import { apply, ATTACHMENT, links, parse, pointerSegments, references, relative, relativize, retarget, serialize, target, } from '@agentshouse/mdmodel';
3
3
  import { immutable, queuedFile, departure, } from './change.js';
4
- import { collectionOf, documentsOf, governing, validateCollection, } from './collection.js';
4
+ import { available, changedCleanly, collectionOf, documentsOf, governing, referring, validateCollection, } from './collection.js';
5
5
  import { changeBatchIdentity } from './identity.js';
6
6
  import { overlay } from './overlay.js';
7
7
  import { covered, normalize } from './paths.js';
8
+ import { differences } from './shared.js';
9
+ import { ROW_WEIGHT, stepped } from './turn.js';
8
10
  function refuse(code, file, location) {
9
11
  return {
10
12
  kind: 'refused',
@@ -177,7 +179,7 @@ export function providerRewritten(batch, visible) {
177
179
  ...anticipated(batch.changes, batch.preconditions, rewritten.changes, visible),
178
180
  };
179
181
  }
180
- function incoming(collection, removed) {
182
+ function* incoming(collection, removed, candidates) {
181
183
  const found = new Map();
182
184
  const note = (target, file) => {
183
185
  if (!removed.has(target))
@@ -186,7 +188,14 @@ function incoming(collection, removed) {
186
188
  referrers.add(file);
187
189
  found.set(target, referrers);
188
190
  };
189
- for (const [path, document] of documentsOf(collection)) {
191
+ const read = function* (paths) {
192
+ for (const path of [...new Set(paths)].sort()) {
193
+ const document = collection.document(path);
194
+ if (document !== undefined)
195
+ yield [path, document];
196
+ }
197
+ };
198
+ for (const [path, document] of candidates === null ? documentsOf(collection) : read(candidates)) {
190
199
  const definition = definitionOf(governing(collection.composition, path), document.type);
191
200
  for (const { value, to } of definition === undefined ? [] : references(document, definition)) {
192
201
  if (to.includes(ATTACHMENT))
@@ -195,6 +204,7 @@ function incoming(collection, removed) {
195
204
  if (named !== null)
196
205
  note(named, path);
197
206
  }
207
+ yield ROW_WEIGHT + collection.text[path].length;
198
208
  }
199
209
  const [first] = [...found.keys()].sort();
200
210
  if (first === undefined)
@@ -217,10 +227,13 @@ function affected(change) {
217
227
  return change.kind === 'move' ? [change.path, change.to] : [change.path];
218
228
  }
219
229
  function guard(changes, input) {
220
- const existing = new Set([
221
- ...Object.keys(input.visible.documents),
222
- ...Object.keys(input.visible.binaries),
223
- ]);
230
+ const overridden = new Map();
231
+ const existing = {
232
+ has: (path) => overridden.get(path) ??
233
+ (Object.hasOwn(input.visible.documents, path) || Object.hasOwn(input.visible.binaries, path)),
234
+ add: (path) => void overridden.set(path, true),
235
+ delete: (path) => void overridden.set(path, false),
236
+ };
224
237
  for (const [index, change] of changes.entries()) {
225
238
  for (const path of affected(change)) {
226
239
  const normalized = normalize(path);
@@ -275,7 +288,7 @@ function guard(changes, input) {
275
288
  continue;
276
289
  }
277
290
  if (change.kind === 'replace') {
278
- if (!input.local && input.visible.revisions[change.path] === undefined) {
291
+ if (unrevised(input, change.path)) {
279
292
  return refuse('unknown-revision', change.path);
280
293
  }
281
294
  continue;
@@ -289,6 +302,22 @@ function guard(changes, input) {
289
302
  function unrevised(input, path) {
290
303
  return (!input.local && input.queued?.has(path) !== true && input.visible.revisions[path] === undefined);
291
304
  }
305
+ export function queuedDocuments(queue) {
306
+ const paths = new Set();
307
+ for (const batch of queue) {
308
+ for (const change of batch.changes) {
309
+ if (change.kind === 'binary')
310
+ continue;
311
+ if (change.kind === 'remove')
312
+ paths.delete(change.path);
313
+ else if (change.kind !== 'move')
314
+ paths.add(change.path);
315
+ else if (paths.delete(change.path))
316
+ paths.add(change.to);
317
+ }
318
+ }
319
+ return paths;
320
+ }
292
321
  function identity(precondition) {
293
322
  const part = precondition.kind === 'field' || precondition.kind === 'section' ? precondition.name : '';
294
323
  return `${precondition.kind} ${precondition.path} ${part}`;
@@ -364,8 +393,8 @@ function preconditionsOf(changes, visible, bases) {
364
393
  function depth(path) {
365
394
  return path.split('/').length;
366
395
  }
367
- function exceeded(limits, changes, resulting) {
368
- const written = changes.map((change) => (change.kind === 'move' ? change.to : change.path));
396
+ function exceeded(limits, changes, effective, resulting) {
397
+ const written = effective.map((change) => (change.kind === 'move' ? change.to : change.path));
369
398
  const created = changes
370
399
  .filter((change) => change.kind === 'create' || change.kind === 'move' || change.kind === 'binary')
371
400
  .map((change) => (change.kind === 'move' ? change.to : change.path));
@@ -381,7 +410,7 @@ function exceeded(limits, changes, resulting) {
381
410
  return refuse('provider-limit', undefined, limit.name);
382
411
  }
383
412
  if (limit.name === 'document-size') {
384
- const large = written.find((path) => (resulting.documents[path] ?? '').length > value);
413
+ const large = written.find((path) => new TextEncoder().encode(resulting.documents[path] ?? '').byteLength > value);
385
414
  if (large !== undefined)
386
415
  return refuse('provider-limit', large, limit.name);
387
416
  }
@@ -449,12 +478,15 @@ function relativeChanges(input) {
449
478
  return { ...change, fields, sections };
450
479
  });
451
480
  }
452
- function unmodeledType(collection, composition) {
481
+ function* unmodeledType(collection, composition) {
482
+ if (available(composition))
483
+ return false;
453
484
  for (const [path, document] of documentsOf(collection)) {
454
485
  if (document.type !== undefined &&
455
486
  document.type !== 'any' &&
456
487
  governing(composition, path).status === 'unavailable')
457
488
  return true;
489
+ yield ROW_WEIGHT + collection.text[path].length;
458
490
  }
459
491
  return false;
460
492
  }
@@ -718,13 +750,15 @@ export function joined(queue, owner, extra) {
718
750
  return { kind: 'joined', batch, queue: queue.map((item) => (item === owner ? batch : item)) };
719
751
  }
720
752
  export function limitedIn(queue, batch, limits, state) {
721
- const limited = exceeded(limits, batch.changes, state(queue.slice(0, queue.indexOf(batch) + 1)));
753
+ const at = queue.indexOf(batch);
754
+ const limited = exceeded(limits, batch.changes, providerRewritten(batch, state(queue.slice(0, at))).changes, state(queue.slice(0, at + 1)));
722
755
  return limited?.kind === 'refused' ? limited.refusal : null;
723
756
  }
724
- export function buildBatch(input) {
757
+ function* batching(input) {
725
758
  const changes = relativeChanges(input);
726
759
  const structural = changes.find((change) => change.kind === 'move' || change.kind === 'remove');
727
- if (structural !== undefined && unmodeledType(input.visible.collection, input.composition))
760
+ if (structural !== undefined &&
761
+ (yield* unmodeledType(input.visible.collection, input.composition)))
728
762
  return refuse('model-unavailable', structural.path);
729
763
  if (changes.length === 0)
730
764
  return refuse('no-change');
@@ -739,9 +773,13 @@ export function buildBatch(input) {
739
773
  const resulting = overlay(input.visible, [
740
774
  { id: '', baseRoomVersion: input.baseRoomVersion, ...predicted },
741
775
  ]);
776
+ const clean = input.clean !== undefined && available(input.composition) ? input.clean : null;
742
777
  const removed = new Set(changes.filter((change) => change.kind === 'remove').map((change) => change.path));
743
778
  if (removed.size > 0) {
744
- const referenced = incoming(collectionOf(resulting.documents, input.composition), removed);
779
+ const referrers = clean === null ? null : referring(clean, input.composition, removed);
780
+ const referenced = yield* incoming(collectionOf(resulting.documents, input.composition), removed, clean === null || referrers === null
781
+ ? null
782
+ : [...referrers, ...(yield* differences(clean.text, resulting.documents))]);
745
783
  if (referenced !== null)
746
784
  return referenced;
747
785
  }
@@ -751,15 +789,20 @@ export function buildBatch(input) {
751
789
  const parsed = parse(content);
752
790
  return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';
753
791
  };
754
- const typedPaths = [...new Set(predicted.changes.flatMap(affected))].filter((path) => typed(input.visible.documents[path]) || typed(resulting.documents[path]));
792
+ const touched = [...new Set(predicted.changes.flatMap(affected))];
793
+ const typedPaths = touched.filter((path) => typed(input.visible.documents[path]) || typed(resulting.documents[path]));
755
794
  const needsModel = typedPaths.length > 0;
756
795
  const withoutModel = typedPaths.find((path) => governing(input.composition, path).status === 'unavailable');
757
796
  if (withoutModel !== undefined)
758
797
  return refuse('model-unavailable', withoutModel);
759
- const validationText = needsModel
760
- ? resulting.documents
761
- : Object.fromEntries(Object.entries(resulting.documents).filter(([path]) => predicted.changes.some((change) => affected(change).includes(path))));
762
- const verdict = validateCollection(validationText, Object.keys(resulting.binaries), input.composition);
798
+ const verdict = clean !== null &&
799
+ (yield* changedCleanly({ text: resulting.documents, binaries: resulting.binaries }, clean, input.composition))
800
+ ? { verdict: 'accept' }
801
+ : yield* validateCollection(needsModel
802
+ ? resulting.documents
803
+ : Object.fromEntries(touched.flatMap((path) => resulting.documents[path] === undefined
804
+ ? []
805
+ : [[path, resulting.documents[path]]])), Object.keys(resulting.binaries), input.composition);
763
806
  if (verdict.verdict === 'refuse') {
764
807
  return {
765
808
  kind: 'refused',
@@ -772,7 +815,7 @@ export function buildBatch(input) {
772
815
  },
773
816
  };
774
817
  }
775
- const limited = exceeded(input.providerLimits, changes, resulting);
818
+ const limited = exceeded(input.providerLimits, changes, predicted.changes, resulting);
776
819
  if (limited !== null)
777
820
  return limited;
778
821
  const validated = typedPaths
@@ -798,3 +841,6 @@ export function buildBatch(input) {
798
841
  }),
799
842
  };
800
843
  }
844
+ export function buildBatch(input) {
845
+ return stepped(batching(input));
846
+ }
package/dist/search.d.ts CHANGED
@@ -1,12 +1,16 @@
1
+ import type { ProviderRefusal } from './adapter.js';
1
2
  import type { ChangeSet } from './change-set.js';
2
- import { type Filter } from './query.js';
3
+ import { type CoveredRoom, type Filter, type PendingRoom } from './query.js';
3
4
  import type { Open } from './open.js';
4
5
  export type DocumentPart = Open<'fields' | 'sections' | 'preamble' | 'path'>;
5
6
  export type SearchRequest = {
6
7
  text: string;
7
8
  documents?: Filter;
9
+ collection?: true;
8
10
  conversations?: readonly string[];
9
11
  limit?: number;
12
+ after?: string;
13
+ total?: true;
10
14
  };
11
15
  export type DocumentHit = {
12
16
  room: string;
@@ -21,10 +25,38 @@ export type MessageHit = {
21
25
  score: number;
22
26
  matches: Readonly<Record<string, readonly Open<'text'>[]>>;
23
27
  };
24
- export type SearchResult = {
28
+ export type SearchCoverage = {
29
+ rooms: readonly CoveredRoom[];
30
+ conversations: readonly string[];
31
+ index: string;
32
+ overlay: readonly string[];
33
+ };
34
+ export type PendingConversation = {
35
+ conversation: string;
36
+ awaits: Open<'index'>;
37
+ };
38
+ export type SearchHits = {
25
39
  documents: readonly DocumentHit[];
26
40
  messages: readonly MessageHit[];
27
41
  };
42
+ export type SearchWindow = SearchHits & {
43
+ next?: string;
44
+ total?: {
45
+ documents: number;
46
+ messages: number;
47
+ };
48
+ };
49
+ export type SearchPending = SearchHits & {
50
+ pending: readonly (PendingRoom | PendingConversation)[];
51
+ coverage: SearchCoverage;
52
+ };
53
+ export type SearchUndeclared = ProviderRefusal & {
54
+ kind: 'undeclared';
55
+ };
56
+ export type SearchResult = (SearchWindow & {
57
+ coverage: SearchCoverage;
58
+ }) | SearchPending | SearchUndeclared;
59
+ export declare function undeclaredSearch(): SearchUndeclared;
28
60
  export type SearchedDocument = {
29
61
  room: string;
30
62
  path: string;
@@ -39,24 +71,35 @@ export type SearchedMessage = {
39
71
  text: string;
40
72
  };
41
73
  export type SearchSource = {
42
- documents(): readonly SearchedDocument[];
74
+ room(room: string): readonly string[];
43
75
  document(room: string, path: string): SearchedDocument | null;
44
- messages(): readonly SearchedMessage[];
45
- message(conversation: string, identity: string): SearchedMessage | null;
46
76
  };
77
+ type HitCursor = readonly [number, string, string] | readonly [] | null;
47
78
  export type SearchPlan = {
48
79
  text: string;
49
80
  documents: unknown;
81
+ collection: boolean;
50
82
  conversations: readonly string[] | null;
51
83
  limit: number | null;
84
+ after: readonly [HitCursor, HitCursor] | null;
85
+ total: boolean;
52
86
  };
53
87
  export type SearchIndex = {
88
+ generation(): string;
89
+ rooms(): ReadonlySet<string>;
90
+ conversations(): ReadonlySet<string>;
91
+ indexRoom(room: string): Promise<void>;
92
+ indexMessages(conversation: string, messages: readonly SearchedMessage[], whole: boolean): void;
93
+ forget(rooms: readonly string[]): void;
54
94
  changed(set: ChangeSet): void;
95
+ changes(): number;
96
+ caughtUp(): Promise<void>;
55
97
  search(plan: SearchPlan, documents: readonly {
56
98
  room: string;
57
99
  path: string;
58
- }[] | null): SearchResult;
100
+ }[] | null, conversations: readonly string[], rooms: ReadonlySet<string> | null, selections: ReadonlyMap<string, readonly string[]> | null): SearchWindow;
59
101
  };
60
102
  export declare function searchPlanOf(input: unknown): SearchPlan;
61
103
  export declare function createSearchIndex(source: SearchSource): SearchIndex;
104
+ export {};
62
105
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
package/dist/search.js CHANGED
@@ -1,5 +1,17 @@
1
1
  import MiniSearch from 'minisearch';
2
- import { invalid, known, limitOf, plain } from './query.js';
2
+ import { indexGeneration } from './identity.js';
3
+ import { flag, invalid, known, limitOf, plain, } from './query.js';
4
+ import { beneath } from './paths.js';
5
+ import { inUnits, ROW_WEIGHT } from './turn.js';
6
+ import { decodedCursor } from './windows.js';
7
+ export function undeclaredSearch() {
8
+ return {
9
+ kind: 'undeclared',
10
+ code: 'search-undeclared',
11
+ fields: { name: 'local_search' },
12
+ retryable: false,
13
+ };
14
+ }
3
15
  const FIELDS = ['fields', 'sections', 'preamble', 'path', 'text'];
4
16
  function documentId(room, path) {
5
17
  return JSON.stringify(['document', room, path]);
@@ -16,10 +28,36 @@ function scalars(value) {
16
28
  return Object.values(value).flatMap(scalars);
17
29
  return [String(value)];
18
30
  }
31
+ function hitCursor(input) {
32
+ if (input === null)
33
+ return null;
34
+ if (!Array.isArray(input))
35
+ return undefined;
36
+ if (input.length === 0)
37
+ return [];
38
+ const [score, first, second] = input;
39
+ return input.length === 3 &&
40
+ typeof score === 'number' &&
41
+ typeof first === 'string' &&
42
+ typeof second === 'string'
43
+ ? [score, first, second]
44
+ : undefined;
45
+ }
46
+ function searchAfter(input) {
47
+ if (input === undefined)
48
+ return null;
49
+ const decoded = typeof input === 'string' ? decodedCursor(input) : null;
50
+ const documents = decoded?.length === 2 ? hitCursor(decoded[0]) : undefined;
51
+ const messages = decoded?.length === 2 ? hitCursor(decoded[1]) : undefined;
52
+ if (documents === undefined || messages === undefined) {
53
+ invalid('after', 'expects the next an earlier search returned');
54
+ }
55
+ return [documents, messages];
56
+ }
19
57
  export function searchPlanOf(input) {
20
58
  if (!plain(input))
21
59
  invalid('search', 'expects a search object');
22
- known(input, ['text', 'documents', 'conversations', 'limit'], '');
60
+ known(input, ['text', 'documents', 'collection', 'conversations', 'limit', 'after', 'total'], '');
23
61
  if (typeof input.text !== 'string')
24
62
  invalid('text', 'expects text');
25
63
  const conversations = input.conversations;
@@ -30,20 +68,49 @@ export function searchPlanOf(input) {
30
68
  return {
31
69
  text: input.text,
32
70
  documents: input.documents,
71
+ collection: flag(input.collection, 'collection'),
33
72
  conversations: conversations ?? null,
34
73
  limit: limitOf(input.limit),
74
+ after: searchAfter(input.after),
75
+ total: flag(input.total, 'total'),
35
76
  };
36
77
  }
78
+ function pair(left, right) {
79
+ if (left[0] !== right[0])
80
+ return left[0] < right[0] ? -1 : 1;
81
+ if (left[1] !== right[1])
82
+ return left[1] < right[1] ? -1 : 1;
83
+ return 0;
84
+ }
85
+ function hitWindow(found, cursor, limit, tie) {
86
+ if (cursor === null)
87
+ return { kept: [], cursor: null };
88
+ const start = cursor.length === 0
89
+ ? 0
90
+ : found.findIndex((hit) => hit.score < cursor[0] ||
91
+ (hit.score === cursor[0] && pair(tie(hit), [cursor[1], cursor[2]]) > 0));
92
+ const following = start === -1 ? [] : found.slice(start);
93
+ if (limit === null || following.length <= limit)
94
+ return { kept: following, cursor: null };
95
+ const kept = following.slice(0, limit);
96
+ const last = kept[kept.length - 1];
97
+ return { kept, cursor: last === undefined ? cursor : [last.score, ...tie(last)] };
98
+ }
37
99
  export function createSearchIndex(source) {
38
- let index = null;
100
+ const generation = indexGeneration();
101
+ const index = new MiniSearch({ fields: FIELDS });
39
102
  const documents = new Map();
40
103
  const messages = new Map();
104
+ const rooms = new Set();
105
+ const filling = new Set();
106
+ const conversations = new Set();
107
+ const acquiring = new Set();
41
108
  const changedDocuments = new Map();
42
- const changedMessages = new Map();
43
- function addDocument(built, document) {
109
+ let changes = 0;
110
+ function addDocument(document) {
44
111
  const id = documentId(document.room, document.path);
45
- documents.set(id, { room: document.room, path: document.path, type: document.type });
46
- built.add({
112
+ discard(id, documents);
113
+ index.add({
47
114
  id,
48
115
  fields: scalars(document.fields).join('\n'),
49
116
  sections: Object.entries(document.sections)
@@ -52,73 +119,151 @@ export function createSearchIndex(source) {
52
119
  preamble: document.preamble,
53
120
  path: document.path,
54
121
  });
122
+ documents.set(id, { room: document.room, path: document.path, type: document.type });
55
123
  }
56
- function addMessage(built, message) {
124
+ function addMessage(message) {
57
125
  const id = messageId(message.conversation, message.identity);
126
+ discard(id, messages);
127
+ index.add({ id, text: message.text });
58
128
  messages.set(id, { conversation: message.conversation, identity: message.identity });
59
- built.add({ id, text: message.text });
60
129
  }
61
- function current() {
62
- if (index === null) {
63
- const built = new MiniSearch({ fields: FIELDS });
64
- for (const document of source.documents())
65
- addDocument(built, document);
66
- for (const message of source.messages())
67
- addMessage(built, message);
68
- index = built;
69
- return built;
130
+ function discard(id, entries) {
131
+ if (entries.delete(id))
132
+ index.discard(id);
133
+ }
134
+ function* pending() {
135
+ for (;;) {
136
+ const next = changedDocuments.entries().next();
137
+ if (next.done === true)
138
+ return;
139
+ changedDocuments.delete(next.value[0]);
140
+ yield next.value;
70
141
  }
71
- const built = index;
72
- for (const [id, { room, path }] of changedDocuments) {
73
- if (documents.delete(id))
74
- built.discard(id);
142
+ }
143
+ let catching = null;
144
+ function caughtUp() {
145
+ if (catching !== null)
146
+ return catching;
147
+ const running = inUnits(pending(), ([id, { room, path }]) => {
148
+ discard(id, documents);
75
149
  const document = source.document(room, path);
76
- if (document !== null)
77
- addDocument(built, document);
78
- }
79
- changedDocuments.clear();
80
- for (const [id, { conversation, identity }] of changedMessages) {
81
- if (messages.delete(id))
82
- built.discard(id);
83
- const message = source.message(conversation, identity);
84
- if (message !== null)
85
- addMessage(built, message);
86
- }
87
- changedMessages.clear();
88
- return built;
150
+ if (document === null)
151
+ return ROW_WEIGHT;
152
+ addDocument(document);
153
+ return Object.values(document.sections).reduce((total, text) => total + text.length, ROW_WEIGHT + document.preamble.length);
154
+ });
155
+ if (!(running instanceof Promise))
156
+ return Promise.resolve();
157
+ catching = running.finally(() => {
158
+ catching = null;
159
+ });
160
+ return catching;
89
161
  }
90
- function ranked(built, text, entries, keep, limit) {
91
- const found = built.search(text, {
162
+ function ranked(text, entries, keep, tie) {
163
+ const found = index.search(text, {
92
164
  filter: ({ id }) => {
93
165
  const entry = entries.get(id);
94
166
  return entry !== undefined && keep(entry, id);
95
167
  },
96
168
  });
97
- return (limit === null ? found : found.slice(0, limit)).map(({ id, score, match }) => ({
169
+ found.sort((left, right) => right.score - left.score ||
170
+ pair(tie(entries.get(left.id)), tie(entries.get(right.id))));
171
+ return found.map(({ id, score, match }) => ({
98
172
  ...entries.get(id),
99
173
  score,
100
174
  match,
101
175
  }));
102
176
  }
103
177
  return {
104
- changed(set) {
105
- if (index === null)
178
+ generation: () => generation,
179
+ rooms: () => rooms,
180
+ conversations: () => conversations,
181
+ async indexRoom(room) {
182
+ if (rooms.has(room) || filling.has(room))
183
+ return;
184
+ filling.add(room);
185
+ try {
186
+ await inUnits(source.room(room), (path) => {
187
+ const document = filling.has(room) ? source.document(room, path) : null;
188
+ if (document === null)
189
+ return ROW_WEIGHT;
190
+ addDocument(document);
191
+ return Object.values(document.sections).reduce((total, text) => total + text.length, ROW_WEIGHT + document.preamble.length);
192
+ });
193
+ if (filling.has(room))
194
+ rooms.add(room);
195
+ }
196
+ finally {
197
+ filling.delete(room);
198
+ }
199
+ },
200
+ indexMessages(conversation, arriving, whole) {
201
+ for (const message of arriving)
202
+ addMessage(message);
203
+ if (!whole) {
204
+ acquiring.add(conversation);
106
205
  return;
206
+ }
207
+ acquiring.delete(conversation);
208
+ conversations.add(conversation);
209
+ },
210
+ forget(leaving) {
211
+ const gone = new Set(leaving);
212
+ for (const [id, entry] of documents)
213
+ if (gone.has(entry.room))
214
+ discard(id, documents);
215
+ for (const room of leaving) {
216
+ rooms.delete(room);
217
+ filling.delete(room);
218
+ }
219
+ },
220
+ changed(set) {
221
+ changes += 1;
107
222
  for (const { locator, path } of set.documents) {
108
- changedDocuments.set(documentId(locator, path), { room: locator, path });
223
+ if (rooms.has(locator) || filling.has(locator)) {
224
+ changedDocuments.set(documentId(locator, path), { room: locator, path });
225
+ }
109
226
  }
110
- for (const { conversation, identity } of set.messages) {
111
- changedMessages.set(messageId(conversation, identity), { conversation, identity });
227
+ for (const { conversation, identity, text } of set.messages) {
228
+ if (!conversations.has(conversation) && !acquiring.has(conversation))
229
+ continue;
230
+ const id = messageId(conversation, identity);
231
+ if (text === null)
232
+ discard(id, messages);
233
+ else
234
+ addMessage({ conversation, identity, text });
112
235
  }
113
236
  },
114
- search({ text, conversations, limit }, selected) {
115
- const built = current();
237
+ changes: () => changes,
238
+ caughtUp,
239
+ search({ text, limit, after, total }, selected, named, within, selections) {
116
240
  const chosen = selected === null
117
241
  ? null
118
242
  : new Set(selected.map(({ room, path }) => documentId(room, path)));
243
+ const asked = new Set(named);
244
+ const documentTie = ({ room, path }) => [room, path];
245
+ const messageTie = ({ conversation, identity }) => [conversation, identity];
246
+ const foundDocuments = ranked(text, documents, ({ room, path }, id) => (chosen === null || chosen.has(id)) &&
247
+ (within === null || within.has(room)) &&
248
+ !(selections?.get(room) ?? []).some((root) => beneath(root, path)), documentTie);
249
+ const foundMessages = ranked(text, messages, ({ conversation }) => asked.has(conversation), messageTie);
250
+ const [documentsAfter, messagesAfter] = after ?? [[], []];
251
+ const documentWindow = hitWindow(foundDocuments, documentsAfter, limit, documentTie);
252
+ const messageWindow = hitWindow(foundMessages, messagesAfter, limit, messageTie);
253
+ const more = documentWindow.cursor !== null || messageWindow.cursor !== null;
119
254
  return {
120
- documents: ranked(built, text, documents, (_entry, id) => chosen === null || chosen.has(id), limit).map(({ match, ...hit }) => ({ ...hit, matches: match })),
121
- messages: ranked(built, text, messages, ({ conversation }) => conversations === null || conversations.includes(conversation), limit).map(({ match, ...hit }) => ({ ...hit, matches: match })),
255
+ documents: documentWindow.kept.map(({ match, ...hit }) => ({
256
+ ...hit,
257
+ matches: match,
258
+ })),
259
+ messages: messageWindow.kept.map(({ match, ...hit }) => ({
260
+ ...hit,
261
+ matches: match,
262
+ })),
263
+ ...(more ? { next: JSON.stringify([documentWindow.cursor, messageWindow.cursor]) } : {}),
264
+ ...(total
265
+ ? { total: { documents: foundDocuments.length, messages: foundMessages.length } }
266
+ : {}),
122
267
  };
123
268
  },
124
269
  };
package/dist/seed.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { KeyedResult } from './observation.js';
2
+ import type { QueryRows } from './query.js';
3
+ export type EntrySeed = {
4
+ readonly at: Readonly<Record<string, string>>;
5
+ readonly queries: readonly {
6
+ readonly query: unknown;
7
+ readonly rows: QueryRows;
8
+ }[];
9
+ };
10
+ export type Seeded = {
11
+ readonly rows: QueryRows;
12
+ readonly at: Readonly<Record<string, string>>;
13
+ };
14
+ export declare function entrySeedOf(value: unknown): EntrySeed | null;
15
+ export declare function seededResult(seed: Seeded): KeyedResult;
16
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAA4C,SAAS,EAAE,MAAM,YAAY,CAAC;AAGtF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,EAAE,CAAC;CACpF,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAC;AAwCjG,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAe5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAoBtD"}