@agentshouse/mdruntime 0.1.0-cf96c797c5fa8 → 0.1.0-cfac557170cf3

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 (235) hide show
  1. package/README.md +18 -15
  2. package/dist/adapter.d.ts +114 -33
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/attempt.d.ts.map +1 -1
  8. package/dist/attempt.js +14 -1
  9. package/dist/binary.d.ts +0 -5
  10. package/dist/binary.d.ts.map +1 -1
  11. package/dist/binary.js +1 -1
  12. package/dist/bootstrap.d.ts +28 -9
  13. package/dist/bootstrap.d.ts.map +1 -1
  14. package/dist/bootstrap.js +178 -80
  15. package/dist/chain.d.ts +11 -0
  16. package/dist/chain.d.ts.map +1 -0
  17. package/dist/chain.js +64 -0
  18. package/dist/change-set.d.ts +9 -14
  19. package/dist/change-set.d.ts.map +1 -1
  20. package/dist/change-set.js +11 -63
  21. package/dist/change.d.ts +31 -1
  22. package/dist/change.d.ts.map +1 -1
  23. package/dist/change.js +10 -1
  24. package/dist/client.d.ts +24 -12
  25. package/dist/client.d.ts.map +1 -1
  26. package/dist/client.js +98 -11
  27. package/dist/collection.d.ts +12 -6
  28. package/dist/collection.d.ts.map +1 -1
  29. package/dist/collection.js +51 -76
  30. package/dist/compile.d.ts +16 -0
  31. package/dist/compile.d.ts.map +1 -0
  32. package/dist/compile.js +773 -0
  33. package/dist/connection.d.ts +46 -16
  34. package/dist/connection.d.ts.map +1 -1
  35. package/dist/connection.js +3740 -837
  36. package/dist/conversation.d.ts +33 -12
  37. package/dist/conversation.d.ts.map +1 -1
  38. package/dist/conversation.js +662 -202
  39. package/dist/digest.d.ts +7 -0
  40. package/dist/digest.d.ts.map +1 -0
  41. package/dist/digest.js +113 -0
  42. package/dist/durability.d.ts +5 -1
  43. package/dist/durability.d.ts.map +1 -1
  44. package/dist/durability.js +5 -0
  45. package/dist/entry.d.ts +20 -0
  46. package/dist/entry.d.ts.map +1 -0
  47. package/dist/entry.js +151 -0
  48. package/dist/fence.d.ts +6 -0
  49. package/dist/fence.d.ts.map +1 -0
  50. package/dist/fence.js +10 -0
  51. package/dist/file.d.ts +2 -19
  52. package/dist/file.d.ts.map +1 -1
  53. package/dist/file.js +7 -122
  54. package/dist/fulltext.d.ts +27 -0
  55. package/dist/fulltext.d.ts.map +1 -0
  56. package/dist/fulltext.js +370 -0
  57. package/dist/host.d.ts +15 -3
  58. package/dist/host.d.ts.map +1 -1
  59. package/dist/host.js +134 -17
  60. package/dist/identity.d.ts +1 -0
  61. package/dist/identity.d.ts.map +1 -1
  62. package/dist/identity.js +3 -0
  63. package/dist/index.d.ts +15 -9
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +6 -0
  66. package/dist/live.d.ts +22 -0
  67. package/dist/live.d.ts.map +1 -0
  68. package/dist/live.js +124 -0
  69. package/dist/media.d.ts +8 -0
  70. package/dist/media.d.ts.map +1 -0
  71. package/dist/media.js +218 -0
  72. package/dist/memory.d.ts +11 -4
  73. package/dist/memory.d.ts.map +1 -1
  74. package/dist/memory.js +98 -28
  75. package/dist/messages.d.ts +28 -0
  76. package/dist/messages.d.ts.map +1 -0
  77. package/dist/messages.js +90 -0
  78. package/dist/model.d.ts +10 -2
  79. package/dist/model.d.ts.map +1 -1
  80. package/dist/model.js +17 -2
  81. package/dist/name.d.ts +4 -0
  82. package/dist/name.d.ts.map +1 -0
  83. package/dist/name.js +122 -0
  84. package/dist/observation.d.ts +20 -2
  85. package/dist/observation.d.ts.map +1 -1
  86. package/dist/observation.js +113 -12
  87. package/dist/opened.d.ts +22 -0
  88. package/dist/opened.d.ts.map +1 -0
  89. package/dist/opened.js +107 -0
  90. package/dist/outcome.d.ts +49 -4
  91. package/dist/outcome.d.ts.map +1 -1
  92. package/dist/outcome.js +40 -0
  93. package/dist/overlay.d.ts +3 -4
  94. package/dist/overlay.d.ts.map +1 -1
  95. package/dist/overlay.js +100 -182
  96. package/dist/paths.d.ts +1 -0
  97. package/dist/paths.d.ts.map +1 -1
  98. package/dist/paths.js +4 -0
  99. package/dist/query.d.ts +66 -4
  100. package/dist/query.d.ts.map +1 -1
  101. package/dist/query.js +48 -7
  102. package/dist/reach.d.ts +18 -6
  103. package/dist/reach.d.ts.map +1 -1
  104. package/dist/reach.js +225 -71
  105. package/dist/react.d.ts +8 -6
  106. package/dist/react.d.ts.map +1 -1
  107. package/dist/react.js +7 -17
  108. package/dist/readiness.d.ts +63 -0
  109. package/dist/readiness.d.ts.map +1 -0
  110. package/dist/readiness.js +33 -0
  111. package/dist/reads.d.ts +11 -0
  112. package/dist/reads.d.ts.map +1 -0
  113. package/dist/reads.js +91 -0
  114. package/dist/recovery.d.ts +26 -0
  115. package/dist/recovery.d.ts.map +1 -0
  116. package/dist/recovery.js +224 -0
  117. package/dist/refresh.d.ts +16 -15
  118. package/dist/refresh.d.ts.map +1 -1
  119. package/dist/refresh.js +113 -49
  120. package/dist/replica.d.ts +56 -33
  121. package/dist/replica.d.ts.map +1 -1
  122. package/dist/replica.js +298 -151
  123. package/dist/room-draft.d.ts +34 -4
  124. package/dist/room-draft.d.ts.map +1 -1
  125. package/dist/room-draft.js +105 -31
  126. package/dist/rows.d.ts +37 -37
  127. package/dist/rows.d.ts.map +1 -1
  128. package/dist/rows.js +173 -104
  129. package/dist/save.d.ts +52 -9
  130. package/dist/save.d.ts.map +1 -1
  131. package/dist/save.js +539 -171
  132. package/dist/search.d.ts +39 -28
  133. package/dist/search.d.ts.map +1 -1
  134. package/dist/search.js +37 -105
  135. package/dist/seed.d.ts +16 -0
  136. package/dist/seed.d.ts.map +1 -0
  137. package/dist/seed.js +75 -0
  138. package/dist/shared.d.ts +16 -0
  139. package/dist/shared.d.ts.map +1 -0
  140. package/dist/shared.js +431 -0
  141. package/dist/status.d.ts +9 -0
  142. package/dist/status.d.ts.map +1 -1
  143. package/dist/status.js +3 -1
  144. package/dist/store.d.ts +114 -75
  145. package/dist/store.d.ts.map +1 -1
  146. package/dist/store.js +342 -442
  147. package/dist/stored.d.ts +135 -0
  148. package/dist/stored.d.ts.map +1 -0
  149. package/dist/stored.js +569 -0
  150. package/dist/tables.d.ts +352 -0
  151. package/dist/tables.d.ts.map +1 -0
  152. package/dist/tables.js +621 -0
  153. package/dist/turn.d.ts +9 -0
  154. package/dist/turn.d.ts.map +1 -0
  155. package/dist/turn.js +75 -0
  156. package/dist/validation.d.ts +30 -0
  157. package/dist/validation.d.ts.map +1 -0
  158. package/dist/validation.js +162 -0
  159. package/dist/windows.d.ts +22 -0
  160. package/dist/windows.d.ts.map +1 -0
  161. package/dist/windows.js +89 -0
  162. package/dist/wire.d.ts +168 -32
  163. package/dist/wire.d.ts.map +1 -1
  164. package/dist/wire.js +56 -31
  165. package/dist/words.d.ts +19 -0
  166. package/dist/words.d.ts.map +1 -0
  167. package/dist/words.js +156 -0
  168. package/package.json +27 -24
  169. package/AGENTS.md +0 -318
  170. package/dist/chat/acts.d.ts +0 -34
  171. package/dist/chat/acts.d.ts.map +0 -1
  172. package/dist/chat/acts.js +0 -36
  173. package/dist/chat/context.d.ts +0 -3
  174. package/dist/chat/context.d.ts.map +0 -1
  175. package/dist/chat/context.js +0 -10
  176. package/dist/chat/input.d.ts +0 -9
  177. package/dist/chat/input.d.ts.map +0 -1
  178. package/dist/chat/input.js +0 -99
  179. package/dist/chat/kit.d.ts +0 -60
  180. package/dist/chat/kit.d.ts.map +0 -1
  181. package/dist/chat/kit.js +0 -123
  182. package/dist/chat/lasting.d.ts +0 -6
  183. package/dist/chat/lasting.d.ts.map +0 -1
  184. package/dist/chat/lasting.js +0 -19
  185. package/dist/chat/list.d.ts +0 -20
  186. package/dist/chat/list.d.ts.map +0 -1
  187. package/dist/chat/list.js +0 -59
  188. package/dist/chat/markdown.d.ts +0 -19
  189. package/dist/chat/markdown.d.ts.map +0 -1
  190. package/dist/chat/markdown.js +0 -187
  191. package/dist/chat/message.d.ts +0 -6
  192. package/dist/chat/message.d.ts.map +0 -1
  193. package/dist/chat/message.js +0 -192
  194. package/dist/chat/messages.d.ts +0 -21
  195. package/dist/chat/messages.d.ts.map +0 -1
  196. package/dist/chat/messages.js +0 -151
  197. package/dist/chat/name.d.ts +0 -6
  198. package/dist/chat/name.d.ts.map +0 -1
  199. package/dist/chat/name.js +0 -37
  200. package/dist/chat/opened.d.ts +0 -11
  201. package/dist/chat/opened.d.ts.map +0 -1
  202. package/dist/chat/opened.js +0 -17
  203. package/dist/chat/overlay.d.ts +0 -31
  204. package/dist/chat/overlay.d.ts.map +0 -1
  205. package/dist/chat/overlay.js +0 -97
  206. package/dist/chat/parts.d.ts +0 -57
  207. package/dist/chat/parts.d.ts.map +0 -1
  208. package/dist/chat/parts.js +0 -119
  209. package/dist/chat/process.d.ts +0 -20
  210. package/dist/chat/process.d.ts.map +0 -1
  211. package/dist/chat/process.js +0 -32
  212. package/dist/chat/provider.d.ts +0 -63
  213. package/dist/chat/provider.d.ts.map +0 -1
  214. package/dist/chat/provider.js +0 -645
  215. package/dist/chat/question.d.ts +0 -9
  216. package/dist/chat/question.d.ts.map +0 -1
  217. package/dist/chat/question.js +0 -80
  218. package/dist/chat/questions.d.ts +0 -31
  219. package/dist/chat/questions.d.ts.map +0 -1
  220. package/dist/chat/questions.js +0 -111
  221. package/dist/chat/read.d.ts +0 -5
  222. package/dist/chat/read.d.ts.map +0 -1
  223. package/dist/chat/read.js +0 -13
  224. package/dist/chat/ready.d.ts +0 -33
  225. package/dist/chat/ready.d.ts.map +0 -1
  226. package/dist/chat/ready.js +0 -91
  227. package/dist/chat/style.d.ts +0 -4
  228. package/dist/chat/style.d.ts.map +0 -1
  229. package/dist/chat/style.js +0 -302
  230. package/dist/chat.d.ts +0 -14
  231. package/dist/chat.d.ts.map +0 -1
  232. package/dist/chat.js +0 -8
  233. package/dist/read-side.d.ts +0 -18
  234. package/dist/read-side.d.ts.map +0 -1
  235. package/dist/read-side.js +0 -440
package/dist/memory.js CHANGED
@@ -1,7 +1,11 @@
1
1
  import { sameChange } from './overlay.js';
2
+ const ATTACHMENTS = 'attachments';
3
+ function lastName(path) {
4
+ return path.slice(path.lastIndexOf('/') + 1);
5
+ }
2
6
  const FIXTURE_RETENTION = {
3
7
  history: { kind: 'duration', seconds: 1 },
4
- outcome: 1,
8
+ outcome: 604_800,
5
9
  refreshHorizon: 1,
6
10
  };
7
11
  function declaredRetention(value) {
@@ -15,12 +19,7 @@ function declaredRetention(value) {
15
19
  }
16
20
  const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
17
21
  function modelsOf(room) {
18
- return {
19
- collection: room.model ?? MODEL_ABSENT,
20
- ...(room.typedSelection === undefined
21
- ? {}
22
- : { selection: room.selectionModel ?? MODEL_ABSENT }),
23
- };
22
+ return { collection: room.model ?? MODEL_ABSENT };
24
23
  }
25
24
  function changedModels(room, from) {
26
25
  const now = modelsOf(room);
@@ -55,7 +54,10 @@ export function createMemoryAdapter(options = {}) {
55
54
  const scripted = new Map();
56
55
  const unsealed = new Map();
57
56
  const sealed = new Set();
57
+ const sentTurns = new Map();
58
58
  const historyPageSize = options.historyPageSize;
59
+ const attached = new Map();
60
+ const linked = new WeakMap();
59
61
  let held = [];
60
62
  let expiring = [];
61
63
  let replicated = [];
@@ -86,6 +88,19 @@ export function createMemoryAdapter(options = {}) {
86
88
  const wanted = ordinals.get(`${locator}\u0000${target}`);
87
89
  return held !== undefined && wanted !== undefined && held >= wanted;
88
90
  }
91
+ function heldBlob(room, path) {
92
+ return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
93
+ }
94
+ function freePath(room, name) {
95
+ const dot = name.lastIndexOf('.');
96
+ const stem = dot > 0 ? name.slice(0, dot) : name;
97
+ const extension = dot > 0 ? name.slice(dot) : '';
98
+ for (let count = 1;; count += 1) {
99
+ const path = `${ATTACHMENTS}/${count === 1 ? stem : `${stem}-${count}`}${extension}`;
100
+ if (heldBlob(room, path) === undefined && room.documents?.[path] === undefined)
101
+ return path;
102
+ }
103
+ }
89
104
  function retain(entries) {
90
105
  for (const room of entries) {
91
106
  note(room.locator, room);
@@ -121,17 +136,32 @@ export function createMemoryAdapter(options = {}) {
121
136
  ...(opening ? { models: modelsOf(room) } : {}),
122
137
  documents: named(room.documents ?? {}, taken),
123
138
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
139
+ ...(room.fileIds === undefined
140
+ ? {}
141
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
124
142
  changes: named(room.changes ?? {}, [...taken, ...targets]),
125
143
  binaryFiles: named(room.binaryFiles ?? {}, targets),
144
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
126
145
  ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
127
146
  };
128
147
  }
148
+ function foldersMoved(room, from) {
149
+ const now = new Set(room.folders ?? []);
150
+ const before = new Set(from.folders ?? []);
151
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
152
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
153
+ return {
154
+ ...(folders.length === 0 ? {} : { folders }),
155
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
156
+ };
157
+ }
129
158
  function advancement(room, from, at) {
130
159
  const current = room.documents ?? {};
131
160
  const previous = from.documents ?? {};
132
161
  const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
133
162
  const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
134
163
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
164
+ room.fileIds?.[path] !== from.fileIds?.[path] ||
135
165
  !sameChange(room.changes?.[path], from.changes?.[path]);
136
166
  const changed = Object.keys(current)
137
167
  .filter((path) => current[path] !== previous[path] || headMoved(path))
@@ -153,8 +183,12 @@ export function createMemoryAdapter(options = {}) {
153
183
  ...(models === undefined ? {} : { models }),
154
184
  documents: named(current, taken),
155
185
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
186
+ ...(room.fileIds === undefined
187
+ ? {}
188
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
156
189
  changes: named(room.changes ?? {}, [...taken, ...targets]),
157
190
  binaryFiles: named(room.binaryFiles ?? {}, targets),
191
+ ...(opening ? foldersMoved(room, from) : {}),
158
192
  removals: opening
159
193
  ? [
160
194
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
@@ -220,9 +254,15 @@ export function createMemoryAdapter(options = {}) {
220
254
  if (outcome !== undefined)
221
255
  return outcome;
222
256
  if (name === 'conversation.send') {
257
+ const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
258
+ const answered = operation === null ? undefined : sentTurns.get(operation);
259
+ if (answered !== undefined)
260
+ return { kind: 'action', result: { turn: answered } };
223
261
  issued += 1;
224
262
  const turn = `turn-${issued}`;
225
263
  unsealed.set(turn, named);
264
+ if (operation !== null)
265
+ sentTurns.set(operation, turn);
226
266
  return { kind: 'action', result: { turn } };
227
267
  }
228
268
  if (name === 'conversation.cancel') {
@@ -238,7 +278,9 @@ export function createMemoryAdapter(options = {}) {
238
278
  return { kind: 'action', result: { conversation: named } };
239
279
  }
240
280
  function announceList() {
241
- const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined ? [] : [{ conversation, ...listed }]);
281
+ const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
282
+ ? []
283
+ : [{ conversation, ...listed, newest: messages.at(-1)?.position ?? null }]);
242
284
  for (const listener of listeners)
243
285
  listener({ kind: 'list', entries });
244
286
  }
@@ -253,6 +295,8 @@ export function createMemoryAdapter(options = {}) {
253
295
  };
254
296
  }
255
297
  return {
298
+ ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
299
+ ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
256
300
  setRooms(next) {
257
301
  rooms = [...next];
258
302
  retain(rooms);
@@ -265,9 +309,9 @@ export function createMemoryAdapter(options = {}) {
265
309
  for (const observer of observers)
266
310
  observer({ kind: 'opened' });
267
311
  },
268
- close(revoked = false) {
312
+ close({ revoked = false, lost = !revoked } = {}) {
269
313
  for (const observer of observers)
270
- observer({ kind: 'closed', revoked });
314
+ observer({ kind: 'closed', revoked, lost });
271
315
  },
272
316
  expire(locators) {
273
317
  expiring = [...locators];
@@ -276,6 +320,13 @@ export function createMemoryAdapter(options = {}) {
276
320
  for (const observer of observers)
277
321
  observer({ kind: 'room-version', locator, roomVersion });
278
322
  },
323
+ notifyAuthorityChanged(scope) {
324
+ for (const observer of observers) {
325
+ observer(scope === undefined
326
+ ? { kind: 'authority-changed' }
327
+ : { kind: 'authority-changed', scope });
328
+ }
329
+ },
279
330
  notifyConversation(event) {
280
331
  if (event.kind === 'accepted-message') {
281
332
  sealed.add(event.message.turn);
@@ -336,17 +387,19 @@ export function createMemoryAdapter(options = {}) {
336
387
  },
337
388
  reopen() {
338
389
  queueMicrotask(() => {
339
- for (const observer of observers)
340
- observer({ kind: 'closed', revoked: false });
390
+ for (const observer of observers) {
391
+ observer({ kind: 'closed', revoked: false, lost: false });
392
+ }
341
393
  });
342
394
  },
395
+ published() { },
343
396
  observe(notify) {
344
397
  observers.add(notify);
345
398
  queueMicrotask(() => {
346
399
  if (!observers.has(notify))
347
400
  return;
348
401
  if (options.unopened === true) {
349
- notify({ kind: 'closed', revoked: false });
402
+ notify({ kind: 'closed', revoked: false, lost: true });
350
403
  return;
351
404
  }
352
405
  announceList();
@@ -429,7 +482,13 @@ export function createMemoryAdapter(options = {}) {
429
482
  retryable: false,
430
483
  affected: {},
431
484
  };
432
- }, request).then((answer) => note(request.locator, answer));
485
+ }, request).then((answer) => {
486
+ const destination = request.changeBatch.between?.destination.room;
487
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
488
+ note(destination, answer.destination);
489
+ }
490
+ return note(request.locator, answer);
491
+ });
433
492
  },
434
493
  async history(_authorization, request) {
435
494
  return resolveScript(scripts.history, () => {
@@ -445,27 +504,38 @@ export function createMemoryAdapter(options = {}) {
445
504
  },
446
505
  async binary(_authorization, request) {
447
506
  return resolveScript(scripts.binary, () => {
448
- if (request.kind === 'reference') {
449
- return { kind: 'rejected', code: 'unscripted-binary', fields: {}, retryable: false };
450
- }
451
507
  const room = rooms.find((entry) => entry.locator === request.locator);
452
508
  if (room === undefined)
453
509
  return { kind: 'room-not-readable', locator: request.locator };
454
- const blob = room.blobs?.[request.path];
510
+ const blob = heldBlob(room, request.path);
455
511
  return blob === undefined
456
512
  ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
457
- : { kind: 'binary', blob };
513
+ : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
514
+ }, request);
515
+ },
516
+ async link(_authorization, request) {
517
+ return resolveScript(scripts.link, () => {
518
+ const room = rooms.find((entry) => entry.locator === request.locator);
519
+ if (room === undefined)
520
+ return { kind: 'room-not-readable', locator: request.locator };
521
+ const blob = heldBlob(room, request.path);
522
+ if (blob === undefined) {
523
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
524
+ }
525
+ const url = linked.get(blob) ?? URL.createObjectURL(blob);
526
+ linked.set(blob, url);
527
+ return { kind: 'link', url, name: lastName(request.path), mediaType: blob.type };
458
528
  }, request);
459
529
  },
460
- referrerScope(referrer) {
461
- if (typeof referrer !== 'object' || referrer === null)
462
- return null;
463
- const { room, path, message } = referrer;
464
- if (typeof message === 'string')
465
- return { kind: 'conversations' };
466
- if (typeof room !== 'string')
467
- return null;
468
- return { kind: 'room', locator: room, ...(typeof path === 'string' ? { path } : {}) };
530
+ async attach(_authorization, request) {
531
+ return resolveScript(scripts.attach, () => {
532
+ const room = rooms.find((entry) => entry.locator === request.locator);
533
+ if (room === undefined)
534
+ return { kind: 'room-not-readable', locator: request.locator };
535
+ const path = freePath(room, request.name);
536
+ attached.set(`${room.locator}\u0000${path}`, request.blob);
537
+ return { kind: 'attached', path, revision: `attached-${attached.size}` };
538
+ }, request);
469
539
  },
470
540
  async action(_authorization, request) {
471
541
  return resolveScript(scripts.action, () => {
@@ -0,0 +1,28 @@
1
+ import type { AcceptedMessage } from './adapter.js';
2
+ import type { Connection } from './tables.js';
3
+ export declare const MESSAGE_TABLES: readonly string[];
4
+ export type HeldConversation = {
5
+ readonly conversation: string;
6
+ readonly read: string | null | undefined;
7
+ readonly partial: boolean;
8
+ };
9
+ export type MessageWindow = {
10
+ readonly messages: AcceptedMessage[];
11
+ readonly more: boolean;
12
+ };
13
+ export type ConversationWrite = {
14
+ readonly conversation: string;
15
+ readonly messages: readonly AcceptedMessage[];
16
+ readonly read?: {
17
+ readonly at: string | null;
18
+ readonly partial: boolean;
19
+ };
20
+ };
21
+ export declare function heldConversations(connection: Connection): HeldConversation[];
22
+ export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
23
+ export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null): MessageWindow;
24
+ export declare function messageCount(connection: Connection, conversation: string): number;
25
+ export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
26
+ export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
27
+ export declare function forgottenMessages(connection: Connection): void;
28
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAM3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3E,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAmB5E;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CAoCN;AAYD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GACvC,aAAa,CAUf;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAW9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}
@@ -0,0 +1,90 @@
1
+ import { indexMessage, unindexMessages } from './fulltext.js';
2
+ export const MESSAGE_TABLES = [
3
+ 'CREATE TABLE conversation_reads (conversation TEXT PRIMARY KEY, read TEXT, partial INTEGER NOT NULL) WITHOUT ROWID',
4
+ 'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
5
+ 'CREATE UNIQUE INDEX conversation_messages_identity ON conversation_messages (conversation, identity)',
6
+ 'CREATE INDEX conversation_messages_position ON conversation_messages (conversation, position, identity)',
7
+ 'CREATE INDEX conversation_messages_turn ON conversation_messages (conversation, turn)',
8
+ ];
9
+ function text(value) {
10
+ return typeof value === 'string' ? value : String(value);
11
+ }
12
+ export function heldConversations(connection) {
13
+ const held = new Map();
14
+ for (const row of connection.rows('SELECT conversation, read, partial FROM conversation_reads')) {
15
+ held.set(text(row.conversation), {
16
+ conversation: text(row.conversation),
17
+ read: row.read === null ? null : text(row.read),
18
+ partial: Number(row.partial) === 1,
19
+ });
20
+ }
21
+ for (const row of connection.rows('SELECT DISTINCT conversation FROM conversation_messages WHERE conversation NOT IN (SELECT conversation FROM conversation_reads)')) {
22
+ held.set(text(row.conversation), {
23
+ conversation: text(row.conversation),
24
+ read: undefined,
25
+ partial: true,
26
+ });
27
+ }
28
+ return [...held.values()];
29
+ }
30
+ export function keptMessages(connection, { conversation, messages, read }) {
31
+ for (const message of messages) {
32
+ const [held] = connection.rows('SELECT id FROM conversation_messages WHERE conversation = ? AND identity = ?', [conversation, message.identity]);
33
+ const record = [
34
+ message.turn,
35
+ message.position,
36
+ JSON.stringify(message.message ?? null),
37
+ message.text,
38
+ ];
39
+ let id;
40
+ if (held === undefined) {
41
+ connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, message, text) VALUES (?, ?, ?, ?, ?, ?)', [conversation, message.identity, ...record]);
42
+ id = Number(connection.rows('SELECT last_insert_rowid() AS id')[0].id);
43
+ }
44
+ else {
45
+ id = Number(held.id);
46
+ unindexMessages(connection, [id]);
47
+ connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, id]);
48
+ }
49
+ indexMessage(connection, id, message.text);
50
+ }
51
+ if (read !== undefined) {
52
+ connection.run('INSERT OR REPLACE INTO conversation_reads (conversation, read, partial) VALUES (?, ?, ?)', [conversation, read.at, read.partial ? 1 : 0]);
53
+ }
54
+ return null;
55
+ }
56
+ function accepted(row) {
57
+ return {
58
+ identity: text(row.identity),
59
+ turn: text(row.turn),
60
+ position: text(row.position),
61
+ text: text(row.text),
62
+ message: JSON.parse(text(row.message)),
63
+ };
64
+ }
65
+ export function messageWindow(connection, conversation, limit, before) {
66
+ const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
67
+ ? [conversation, limit + 1]
68
+ : [conversation, before[0], before[0], before[1], limit + 1]);
69
+ return { messages: rows.slice(0, limit).map(accepted).reverse(), more: rows.length > limit };
70
+ }
71
+ export function messageCount(connection, conversation) {
72
+ const [counted] = connection.rows('SELECT count(*) AS held FROM conversation_messages WHERE conversation = ?', [conversation]);
73
+ return Number(counted?.held ?? 0);
74
+ }
75
+ export function turnArrived(connection, conversation, turn) {
76
+ return (connection.rows('SELECT 1 FROM conversation_messages WHERE conversation = ? AND turn = ? LIMIT 1', [conversation, turn]).length > 0);
77
+ }
78
+ export function droppedMessages(connection, conversations) {
79
+ for (const conversation of conversations) {
80
+ unindexMessages(connection, connection
81
+ .rows('SELECT id FROM conversation_messages WHERE conversation = ?', [conversation])
82
+ .map((row) => Number(row.id)));
83
+ connection.run('DELETE FROM conversation_messages WHERE conversation = ?', [conversation]);
84
+ connection.run('DELETE FROM conversation_reads WHERE conversation = ?', [conversation]);
85
+ }
86
+ }
87
+ export function forgottenMessages(connection) {
88
+ connection.run('DELETE FROM conversation_messages');
89
+ connection.run('DELETE FROM conversation_reads');
90
+ }
package/dist/model.d.ts CHANGED
@@ -28,13 +28,19 @@ export type ModelState = {
28
28
  verifiedWith: ModelIdentity;
29
29
  types: VerifiedModel['types'];
30
30
  };
31
- export type TypesResult = {
31
+ export type StoredModel = Extract<ModelState, {
32
32
  status: 'unavailable';
33
+ }> | Omit<Extract<ModelState, {
34
+ status: 'current' | 'cached';
35
+ }>, 'types'>;
36
+ export type TypesResult = {
37
+ status: Open<'unavailable'>;
33
38
  reason: ModelUnavailableReason;
39
+ types: null;
34
40
  schema?: string | null;
35
41
  revision?: string | null;
36
42
  } | {
37
- status: 'current' | 'cached';
43
+ status: Open<'current' | 'cached'>;
38
44
  identity: string;
39
45
  version: string;
40
46
  verifiedWith: ModelIdentity;
@@ -50,7 +56,9 @@ export type ValidationReceipt = {
50
56
  export declare const NO_MODEL: ModelState;
51
57
  export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
52
58
  export declare function modelTypes(state: ModelState): TypesResult;
59
+ export declare function storedModel(state: ModelState): StoredModel;
53
60
  export declare function cached(state: ModelState): ModelState;
54
61
  export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
62
+ export declare function sameTyping(left: ModelState, right: ModelState): boolean;
55
63
  export declare function referenceField(facts: ValueFacts | undefined): boolean;
56
64
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC,CAAC;AACnG,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAgBzD;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAErE"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/model.js CHANGED
@@ -6,7 +6,7 @@ export function definitionOf(state, type) {
6
6
  }
7
7
  export function modelTypes(state) {
8
8
  return state.status === 'unavailable'
9
- ? { ...state }
9
+ ? { ...state, types: null }
10
10
  : {
11
11
  status: state.status,
12
12
  identity: state.snapshot.identity,
@@ -14,15 +14,30 @@ export function modelTypes(state) {
14
14
  verifiedWith: { ...state.verifiedWith },
15
15
  schema: state.snapshot.schema,
16
16
  revision: state.snapshot.revision,
17
- types: structuredClone(Object.values(state.types).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0)),
17
+ types: Object.values(state.types).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0),
18
18
  };
19
19
  }
20
+ export function storedModel(state) {
21
+ if (state.status === 'unavailable')
22
+ return state;
23
+ const { types: _types, ...stored } = state;
24
+ return stored;
25
+ }
20
26
  export function cached(state) {
21
27
  return state.status === 'unavailable' ? state : { ...state, status: 'cached' };
22
28
  }
23
29
  export function sameModel(left, right) {
24
30
  return left.identity === right.identity && left.version === right.version;
25
31
  }
32
+ export function sameTyping(left, right) {
33
+ if (left === right)
34
+ return true;
35
+ if (left.status === 'unavailable' || right.status === 'unavailable') {
36
+ return left.status === right.status;
37
+ }
38
+ return (left.snapshot.schema === right.snapshot.schema &&
39
+ sameModel(left.verifiedWith, right.verifiedWith));
40
+ }
26
41
  export function referenceField(facts) {
27
42
  return facts?.reference !== undefined || facts?.items?.reference !== undefined;
28
43
  }
package/dist/name.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare function transliterated(text: string): string;
2
+ export declare function nameFrom(title: string): string;
3
+ export declare function cutName(name: string, most: number): string;
4
+ //# sourceMappingURL=name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"name.d.ts","sourceRoot":"","sources":["../src/name.ts"],"names":[],"mappings":"AAgHA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D"}
package/dist/name.js ADDED
@@ -0,0 +1,122 @@
1
+ const LETTERS = {
2
+ а: 'a',
3
+ б: 'b',
4
+ в: 'v',
5
+ г: 'g',
6
+ ґ: 'g',
7
+ д: 'd',
8
+ ђ: 'dj',
9
+ ѓ: 'gj',
10
+ е: 'e',
11
+ ё: 'yo',
12
+ є: 'ye',
13
+ ж: 'zh',
14
+ з: 'z',
15
+ ѕ: 'dz',
16
+ и: 'i',
17
+ і: 'i',
18
+ ї: 'yi',
19
+ й: 'y',
20
+ ј: 'j',
21
+ к: 'k',
22
+ ќ: 'kj',
23
+ л: 'l',
24
+ љ: 'lj',
25
+ м: 'm',
26
+ н: 'n',
27
+ њ: 'nj',
28
+ о: 'o',
29
+ п: 'p',
30
+ р: 'r',
31
+ с: 's',
32
+ т: 't',
33
+ ћ: 'c',
34
+ у: 'u',
35
+ ў: 'u',
36
+ ф: 'f',
37
+ х: 'kh',
38
+ ц: 'ts',
39
+ ч: 'ch',
40
+ џ: 'dz',
41
+ ш: 'sh',
42
+ щ: 'shch',
43
+ ъ: '',
44
+ ы: 'y',
45
+ ь: '',
46
+ э: 'e',
47
+ ю: 'yu',
48
+ я: 'ya',
49
+ α: 'a',
50
+ β: 'v',
51
+ γ: 'g',
52
+ δ: 'd',
53
+ ε: 'e',
54
+ ζ: 'z',
55
+ η: 'i',
56
+ θ: 'th',
57
+ ι: 'i',
58
+ κ: 'k',
59
+ λ: 'l',
60
+ μ: 'm',
61
+ ν: 'n',
62
+ ξ: 'x',
63
+ ο: 'o',
64
+ π: 'p',
65
+ ρ: 'r',
66
+ σ: 's',
67
+ ς: 's',
68
+ τ: 't',
69
+ υ: 'y',
70
+ φ: 'f',
71
+ χ: 'ch',
72
+ ψ: 'ps',
73
+ ω: 'o',
74
+ ß: 'ss',
75
+ æ: 'ae',
76
+ œ: 'oe',
77
+ ø: 'o',
78
+ đ: 'd',
79
+ ð: 'd',
80
+ þ: 'th',
81
+ ł: 'l',
82
+ ı: 'i',
83
+ };
84
+ const MARKS = /\p{M}/gu;
85
+ const ADMITTED = /^[a-z0-9]$/;
86
+ const WORDLIKE = /^[\p{L}\p{N}]$/u;
87
+ function lowerLetterOf(character) {
88
+ const known = LETTERS[character];
89
+ if (known !== undefined)
90
+ return known;
91
+ const bare = character.normalize('NFKD').replace(MARKS, '');
92
+ const mapped = LETTERS[bare];
93
+ if (mapped !== undefined)
94
+ return mapped;
95
+ return [...bare].every((one) => ADMITTED.test(one)) ? bare : null;
96
+ }
97
+ function codePoint(character) {
98
+ return WORDLIKE.test(character) ? `-u${character.codePointAt(0)?.toString(16) ?? ''}-` : '-';
99
+ }
100
+ function latin(text, unknown) {
101
+ return [...text]
102
+ .map((character) => {
103
+ if ((character.codePointAt(0) ?? 0) < 0x80)
104
+ return character;
105
+ const lower = character.toLowerCase();
106
+ const letter = lowerLetterOf(lower) ?? unknown(lower);
107
+ return lower === character ? letter : `${letter.charAt(0).toUpperCase()}${letter.slice(1)}`;
108
+ })
109
+ .join('');
110
+ }
111
+ export function transliterated(text) {
112
+ return latin(text, () => '-');
113
+ }
114
+ export function nameFrom(title) {
115
+ return latin(title, codePoint)
116
+ .toLowerCase()
117
+ .replace(/[^a-z0-9]+/g, '-')
118
+ .replace(/^-+|-+$/g, '');
119
+ }
120
+ export function cutName(name, most) {
121
+ return name.slice(0, most).replace(/-+$/, '');
122
+ }
@@ -1,4 +1,4 @@
1
- import type { QueryDocument, QueryGroup, QueryResult } from './query.js';
1
+ import type { QueryCoverage, QueryDocument, QueryGroup, QueryResult } from './query.js';
2
2
  export type Observation<T> = {
3
3
  current(): T;
4
4
  subscribe(listener: (value: T) => void): () => void;
@@ -13,15 +13,33 @@ export type QueryChange = {
13
13
  changed: readonly (readonly [RowKey, QueryDocument | QueryGroup])[];
14
14
  removed: readonly RowKey[];
15
15
  order: readonly RowKey[] | null;
16
+ coverage?: QueryCoverage;
17
+ next?: string | null;
18
+ total?: number;
16
19
  };
20
+ export type QueryMessage = KeyedResult | QueryChange;
17
21
  export type Observed = {
18
22
  observation: Observation<unknown>;
19
23
  receive(message: unknown): void;
20
24
  end(): void;
21
25
  };
22
26
  export declare function rowsOf(result: QueryResult): readonly (QueryDocument | QueryGroup)[];
23
- export declare function applied(keyed: KeyedResult, change: QueryChange): KeyedResult;
27
+ export declare function whole(message: QueryMessage): message is KeyedResult;
28
+ export declare function applied(keyed: KeyedResult, message: QueryMessage): KeyedResult;
24
29
  export declare function observed(first: unknown, stop: () => void, keyed: boolean): Observed;
25
30
  export declare function opened(watch: (deliver: (message: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
26
31
  export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
32
+ export type Digest = {
33
+ readonly pending: string;
34
+ } | {
35
+ readonly keys: readonly RowKey[];
36
+ readonly rows: ReadonlyMap<RowKey, number>;
37
+ readonly coverage: string;
38
+ readonly next: string | undefined;
39
+ readonly total: number | undefined;
40
+ };
41
+ export declare function hashed(text: string): number;
42
+ export declare function digestOf({ result, keys }: KeyedResult): Digest;
43
+ export declare function digestApplied(digest: Digest, message: QueryMessage): Digest;
44
+ export declare function changeOf(previous: Digest, next: KeyedResult): QueryMessage | null;
27
45
  //# sourceMappingURL=observation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,IAAI,CAAC,CAAC;IACb,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,GAAG,IAAI,IAAI,CAAC;CACb,CAAC;AAEF,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,aAAa,GAAG,UAAU,CAAC,EAAE,CAEnF;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,CAc5E;AAiBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAkCnF;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,EAC1D,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAiB/B;AAED,wBAAgB,SAAS,CAAC,KAAK,SAAS,MAAM,EAC5C,KAAK,EAAE,CACL,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAChC,MAAM,IAAI,WAEA,KAAK,YAAY,OAAO,EAAE,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAQ1E"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}