@agentshouse/mdruntime 0.1.0-c1cc928d1d256 → 0.1.0-c1ffd2bc60355

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 (257) hide show
  1. package/AGENTS.md +296 -232
  2. package/README.md +21 -10
  3. package/dist/adapter.d.ts +123 -32
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/attached-model.d.ts +4 -1
  6. package/dist/attached-model.d.ts.map +1 -1
  7. package/dist/attached-model.js +13 -3
  8. package/dist/attempt.d.ts +16 -0
  9. package/dist/attempt.d.ts.map +1 -0
  10. package/dist/attempt.js +70 -0
  11. package/dist/binary.d.ts +18 -0
  12. package/dist/binary.d.ts.map +1 -0
  13. package/dist/binary.js +8 -0
  14. package/dist/bootstrap.d.ts +36 -5
  15. package/dist/bootstrap.d.ts.map +1 -1
  16. package/dist/bootstrap.js +187 -45
  17. package/dist/chain.d.ts +11 -0
  18. package/dist/chain.d.ts.map +1 -0
  19. package/dist/chain.js +64 -0
  20. package/dist/change-set.d.ts +9 -14
  21. package/dist/change-set.d.ts.map +1 -1
  22. package/dist/change-set.js +11 -56
  23. package/dist/change.d.ts +45 -0
  24. package/dist/change.d.ts.map +1 -1
  25. package/dist/change.js +34 -0
  26. package/dist/chat/acts.d.ts +33 -0
  27. package/dist/chat/acts.d.ts.map +1 -0
  28. package/dist/chat/acts.js +36 -0
  29. package/dist/chat/context.d.ts +3 -0
  30. package/dist/chat/context.d.ts.map +1 -0
  31. package/dist/chat/context.js +10 -0
  32. package/dist/chat/earlier.d.ts +10 -0
  33. package/dist/chat/earlier.d.ts.map +1 -0
  34. package/dist/chat/earlier.js +54 -0
  35. package/dist/chat/house.d.ts +25 -0
  36. package/dist/chat/house.d.ts.map +1 -0
  37. package/dist/chat/house.js +38 -0
  38. package/dist/chat/input.d.ts +11 -0
  39. package/dist/chat/input.d.ts.map +1 -0
  40. package/dist/chat/input.js +92 -0
  41. package/dist/chat/kit.d.ts +61 -0
  42. package/dist/chat/kit.d.ts.map +1 -0
  43. package/dist/chat/kit.js +123 -0
  44. package/dist/chat/lasting.d.ts +6 -0
  45. package/dist/chat/lasting.d.ts.map +1 -0
  46. package/dist/chat/lasting.js +19 -0
  47. package/dist/chat/list.d.ts +28 -0
  48. package/dist/chat/list.d.ts.map +1 -0
  49. package/dist/chat/list.js +103 -0
  50. package/dist/chat/markdown.d.ts +20 -0
  51. package/dist/chat/markdown.d.ts.map +1 -0
  52. package/dist/chat/markdown.js +229 -0
  53. package/dist/chat/message.d.ts +7 -0
  54. package/dist/chat/message.d.ts.map +1 -0
  55. package/dist/chat/message.js +254 -0
  56. package/dist/chat/messages.d.ts +35 -0
  57. package/dist/chat/messages.d.ts.map +1 -0
  58. package/dist/chat/messages.js +210 -0
  59. package/dist/chat/name.d.ts +7 -0
  60. package/dist/chat/name.d.ts.map +1 -0
  61. package/dist/chat/name.js +37 -0
  62. package/dist/chat/opened.d.ts +12 -0
  63. package/dist/chat/opened.d.ts.map +1 -0
  64. package/dist/chat/opened.js +19 -0
  65. package/dist/chat/overlay.d.ts +32 -0
  66. package/dist/chat/overlay.d.ts.map +1 -0
  67. package/dist/chat/overlay.js +103 -0
  68. package/dist/chat/parts.d.ts +58 -0
  69. package/dist/chat/parts.d.ts.map +1 -0
  70. package/dist/chat/parts.js +120 -0
  71. package/dist/chat/pieces.d.ts +62 -0
  72. package/dist/chat/pieces.d.ts.map +1 -0
  73. package/dist/chat/pieces.js +1110 -0
  74. package/dist/chat/process.d.ts +20 -0
  75. package/dist/chat/process.d.ts.map +1 -0
  76. package/dist/chat/process.js +32 -0
  77. package/dist/chat/provider.d.ts +70 -0
  78. package/dist/chat/provider.d.ts.map +1 -0
  79. package/dist/chat/provider.js +635 -0
  80. package/dist/chat/question.d.ts +9 -0
  81. package/dist/chat/question.d.ts.map +1 -0
  82. package/dist/chat/question.js +69 -0
  83. package/dist/chat/questions.d.ts +31 -0
  84. package/dist/chat/questions.d.ts.map +1 -0
  85. package/dist/chat/questions.js +111 -0
  86. package/dist/chat/read.d.ts +5 -0
  87. package/dist/chat/read.d.ts.map +1 -0
  88. package/dist/chat/read.js +13 -0
  89. package/dist/chat/ready.d.ts +37 -0
  90. package/dist/chat/ready.d.ts.map +1 -0
  91. package/dist/chat/ready.js +93 -0
  92. package/dist/chat/room-file.d.ts +8 -0
  93. package/dist/chat/room-file.d.ts.map +1 -0
  94. package/dist/chat/room-file.js +72 -0
  95. package/dist/chat/steady.d.ts +3 -0
  96. package/dist/chat/steady.d.ts.map +1 -0
  97. package/dist/chat/steady.js +26 -0
  98. package/dist/chat/style.d.ts +4 -0
  99. package/dist/chat/style.d.ts.map +1 -0
  100. package/dist/chat/style.js +307 -0
  101. package/dist/chat.d.ts +15 -0
  102. package/dist/chat.d.ts.map +1 -0
  103. package/dist/chat.js +8 -0
  104. package/dist/client.d.ts +33 -14
  105. package/dist/client.d.ts.map +1 -1
  106. package/dist/client.js +74 -19
  107. package/dist/collection.d.ts +9 -13
  108. package/dist/collection.d.ts.map +1 -1
  109. package/dist/collection.js +47 -56
  110. package/dist/compile.d.ts +16 -0
  111. package/dist/compile.d.ts.map +1 -0
  112. package/dist/compile.js +721 -0
  113. package/dist/connection.d.ts +57 -19
  114. package/dist/connection.d.ts.map +1 -1
  115. package/dist/connection.js +3561 -663
  116. package/dist/conversation.d.ts +41 -12
  117. package/dist/conversation.d.ts.map +1 -1
  118. package/dist/conversation.js +585 -180
  119. package/dist/digest.d.ts +7 -0
  120. package/dist/digest.d.ts.map +1 -0
  121. package/dist/digest.js +113 -0
  122. package/dist/durability.d.ts +5 -1
  123. package/dist/durability.d.ts.map +1 -1
  124. package/dist/durability.js +5 -0
  125. package/dist/entry.d.ts +19 -0
  126. package/dist/entry.d.ts.map +1 -0
  127. package/dist/entry.js +151 -0
  128. package/dist/expectation.d.ts +21 -0
  129. package/dist/expectation.d.ts.map +1 -0
  130. package/dist/expectation.js +70 -0
  131. package/dist/failure.d.ts +13 -0
  132. package/dist/failure.d.ts.map +1 -0
  133. package/dist/failure.js +19 -0
  134. package/dist/fence.d.ts +6 -0
  135. package/dist/fence.d.ts.map +1 -0
  136. package/dist/fence.js +10 -0
  137. package/dist/file.d.ts +2 -10
  138. package/dist/file.d.ts.map +1 -1
  139. package/dist/file.js +3 -120
  140. package/dist/fulltext.d.ts +27 -0
  141. package/dist/fulltext.d.ts.map +1 -0
  142. package/dist/fulltext.js +368 -0
  143. package/dist/host.d.ts +15 -3
  144. package/dist/host.d.ts.map +1 -1
  145. package/dist/host.js +132 -22
  146. package/dist/identity.d.ts +4 -0
  147. package/dist/identity.d.ts.map +1 -1
  148. package/dist/identity.js +16 -1
  149. package/dist/index.d.ts +20 -9
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +8 -0
  152. package/dist/live.d.ts +22 -0
  153. package/dist/live.d.ts.map +1 -0
  154. package/dist/live.js +123 -0
  155. package/dist/memory.d.ts +11 -4
  156. package/dist/memory.d.ts.map +1 -1
  157. package/dist/memory.js +92 -27
  158. package/dist/messages.d.ts +28 -0
  159. package/dist/messages.d.ts.map +1 -0
  160. package/dist/messages.js +90 -0
  161. package/dist/model.d.ts +7 -4
  162. package/dist/model.d.ts.map +1 -1
  163. package/dist/model.js +10 -1
  164. package/dist/name.d.ts +4 -0
  165. package/dist/name.d.ts.map +1 -0
  166. package/dist/name.js +122 -0
  167. package/dist/observation.d.ts +19 -2
  168. package/dist/observation.d.ts.map +1 -1
  169. package/dist/observation.js +113 -12
  170. package/dist/open.d.ts +2 -0
  171. package/dist/open.d.ts.map +1 -0
  172. package/dist/open.js +1 -0
  173. package/dist/opened.d.ts +22 -0
  174. package/dist/opened.d.ts.map +1 -0
  175. package/dist/opened.js +107 -0
  176. package/dist/outcome.d.ts +62 -3
  177. package/dist/outcome.d.ts.map +1 -1
  178. package/dist/outcome.js +67 -1
  179. package/dist/overlay.d.ts +15 -5
  180. package/dist/overlay.d.ts.map +1 -1
  181. package/dist/overlay.js +136 -180
  182. package/dist/query.d.ts +64 -4
  183. package/dist/query.d.ts.map +1 -1
  184. package/dist/query.js +51 -7
  185. package/dist/reach.d.ts +11 -4
  186. package/dist/reach.d.ts.map +1 -1
  187. package/dist/reach.js +203 -59
  188. package/dist/react.d.ts +12 -8
  189. package/dist/react.d.ts.map +1 -1
  190. package/dist/react.js +8 -17
  191. package/dist/readiness.d.ts +64 -0
  192. package/dist/readiness.d.ts.map +1 -0
  193. package/dist/readiness.js +33 -0
  194. package/dist/reads.d.ts +11 -0
  195. package/dist/reads.d.ts.map +1 -0
  196. package/dist/reads.js +100 -0
  197. package/dist/recovery.d.ts +25 -0
  198. package/dist/recovery.d.ts.map +1 -0
  199. package/dist/recovery.js +198 -0
  200. package/dist/refresh.d.ts +19 -8
  201. package/dist/refresh.d.ts.map +1 -1
  202. package/dist/refresh.js +127 -55
  203. package/dist/replica.d.ts +60 -33
  204. package/dist/replica.d.ts.map +1 -1
  205. package/dist/replica.js +318 -152
  206. package/dist/room-draft.d.ts +41 -9
  207. package/dist/room-draft.d.ts.map +1 -1
  208. package/dist/room-draft.js +186 -37
  209. package/dist/rows.d.ts +30 -35
  210. package/dist/rows.d.ts.map +1 -1
  211. package/dist/rows.js +116 -67
  212. package/dist/save.d.ts +71 -4
  213. package/dist/save.d.ts.map +1 -1
  214. package/dist/save.js +815 -146
  215. package/dist/search.d.ts +41 -29
  216. package/dist/search.d.ts.map +1 -1
  217. package/dist/search.js +37 -105
  218. package/dist/seed.d.ts +16 -0
  219. package/dist/seed.d.ts.map +1 -0
  220. package/dist/seed.js +75 -0
  221. package/dist/shared.d.ts +16 -0
  222. package/dist/shared.d.ts.map +1 -0
  223. package/dist/shared.js +431 -0
  224. package/dist/status.d.ts +6 -2
  225. package/dist/status.d.ts.map +1 -1
  226. package/dist/status.js +0 -8
  227. package/dist/store.d.ts +124 -61
  228. package/dist/store.d.ts.map +1 -1
  229. package/dist/store.js +358 -354
  230. package/dist/stored.d.ts +145 -0
  231. package/dist/stored.d.ts.map +1 -0
  232. package/dist/stored.js +567 -0
  233. package/dist/tables.d.ts +354 -0
  234. package/dist/tables.d.ts.map +1 -0
  235. package/dist/tables.js +624 -0
  236. package/dist/turn.d.ts +9 -0
  237. package/dist/turn.d.ts.map +1 -0
  238. package/dist/turn.js +75 -0
  239. package/dist/validation.d.ts +30 -0
  240. package/dist/validation.d.ts.map +1 -0
  241. package/dist/validation.js +162 -0
  242. package/dist/windows.d.ts +22 -0
  243. package/dist/windows.d.ts.map +1 -0
  244. package/dist/windows.js +89 -0
  245. package/dist/wire.d.ts +168 -33
  246. package/dist/wire.d.ts.map +1 -1
  247. package/dist/wire.js +67 -31
  248. package/dist/words.d.ts +19 -0
  249. package/dist/words.d.ts.map +1 -0
  250. package/dist/words.js +150 -0
  251. package/package.json +34 -16
  252. package/dist/attachment.d.ts +0 -3
  253. package/dist/attachment.d.ts.map +0 -1
  254. package/dist/attachment.js +0 -8
  255. package/dist/read-side.d.ts +0 -18
  256. package/dist/read-side.d.ts.map +0 -1
  257. package/dist/read-side.js +0 -433
package/dist/memory.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { sameChange } from './overlay.js';
2
2
  const FIXTURE_RETENTION = {
3
3
  history: { kind: 'duration', seconds: 1 },
4
- outcome: 1,
4
+ outcome: 604_800,
5
5
  refreshHorizon: 1,
6
6
  };
7
7
  function declaredRetention(value) {
@@ -55,6 +55,7 @@ export function createMemoryAdapter(options = {}) {
55
55
  const scripted = new Map();
56
56
  const unsealed = new Map();
57
57
  const sealed = new Set();
58
+ const sentTurns = new Map();
58
59
  const historyPageSize = options.historyPageSize;
59
60
  let held = [];
60
61
  let expiring = [];
@@ -107,30 +108,46 @@ export function createMemoryAdapter(options = {}) {
107
108
  providerOwnedPaths: room.providerOwnedPaths,
108
109
  };
109
110
  }
110
- function page(room, from) {
111
+ function page(room, after) {
111
112
  const paths = Object.keys(room.documents ?? {}).sort();
113
+ const opening = after === undefined;
114
+ const from = opening ? 0 : paths.filter((path) => path <= after).length;
112
115
  const size = pageSize ?? paths.length;
113
116
  const taken = paths.slice(from, from + size);
114
117
  const next = from + taken.length;
115
- const targets = from === 0 ? (room.binaryTargets ?? []) : [];
118
+ const targets = opening ? Object.keys(room.binaryFiles ?? {}) : [];
116
119
  return {
117
120
  kind: 'bootstrap',
118
121
  roomVersion: room.roomVersion,
119
- ...(from === 0 ? { models: modelsOf(room) } : {}),
122
+ ...(opening ? { models: modelsOf(room) } : {}),
120
123
  documents: named(room.documents ?? {}, taken),
121
- revisions: named(room.revisions ?? {}, taken),
124
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
125
+ ...(room.fileIds === undefined
126
+ ? {}
127
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
122
128
  changes: named(room.changes ?? {}, [...taken, ...targets]),
123
- binaryTargets: targets,
124
- ...(from === 0 && room.attachments !== undefined ? { attachments: room.attachments } : {}),
125
- ...(next < paths.length ? { pageToken: String(next) } : {}),
129
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
130
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
131
+ ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
132
+ };
133
+ }
134
+ function foldersMoved(room, from) {
135
+ const now = new Set(room.folders ?? []);
136
+ const before = new Set(from.folders ?? []);
137
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
138
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
139
+ return {
140
+ ...(folders.length === 0 ? {} : { folders }),
141
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
126
142
  };
127
143
  }
128
144
  function advancement(room, from, at) {
129
145
  const current = room.documents ?? {};
130
146
  const previous = from.documents ?? {};
131
- const currentTargets = new Set(room.binaryTargets ?? []);
132
- const previousTargets = new Set(from.binaryTargets ?? []);
147
+ const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
148
+ const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
133
149
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
150
+ room.fileIds?.[path] !== from.fileIds?.[path] ||
134
151
  !sameChange(room.changes?.[path], from.changes?.[path]);
135
152
  const changed = Object.keys(current)
136
153
  .filter((path) => current[path] !== previous[path] || headMoved(path))
@@ -145,24 +162,25 @@ export function createMemoryAdapter(options = {}) {
145
162
  const targets = opening
146
163
  ? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
147
164
  : [];
148
- const attachments = room.attachments ?? [];
149
- const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
150
165
  const models = opening ? changedModels(room, from) : undefined;
151
166
  return {
152
167
  kind: 'net-advancement',
153
168
  roomVersion: room.roomVersion,
154
169
  ...(models === undefined ? {} : { models }),
155
170
  documents: named(current, taken),
156
- revisions: named(room.revisions ?? {}, taken),
171
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
172
+ ...(room.fileIds === undefined
173
+ ? {}
174
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
157
175
  changes: named(room.changes ?? {}, [...taken, ...targets]),
158
- binaryTargets: targets,
176
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
177
+ ...(opening ? foldersMoved(room, from) : {}),
159
178
  removals: opening
160
179
  ? [
161
180
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
162
181
  ...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
163
182
  ].sort()
164
183
  : [],
165
- ...(declared ? { attachments } : {}),
166
184
  ...(pageToken === undefined ? {} : { pageToken }),
167
185
  };
168
186
  }
@@ -183,7 +201,7 @@ export function createMemoryAdapter(options = {}) {
183
201
  function historiesOf(input) {
184
202
  const asked = input?.conversations;
185
203
  if (!Array.isArray(asked))
186
- return { kind: 'rejected', code: 'invalid_request', fields: {} };
204
+ return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
187
205
  const histories = [];
188
206
  for (const entry of asked) {
189
207
  const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
@@ -211,21 +229,32 @@ export function createMemoryAdapter(options = {}) {
211
229
  const named = typeof input.conversation === 'string' ? input.conversation : '';
212
230
  const conversation = scripted.get(named);
213
231
  if (conversation === undefined) {
214
- return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
232
+ return {
233
+ kind: 'rejected',
234
+ code: 'unknown-conversation',
235
+ fields: { conversation: named },
236
+ retryable: false,
237
+ };
215
238
  }
216
239
  const outcome = conversation.outcomes?.[name];
217
240
  if (outcome !== undefined)
218
241
  return outcome;
219
242
  if (name === 'conversation.send') {
243
+ const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
244
+ const answered = operation === null ? undefined : sentTurns.get(operation);
245
+ if (answered !== undefined)
246
+ return { kind: 'action', result: { turn: answered } };
220
247
  issued += 1;
221
248
  const turn = `turn-${issued}`;
222
249
  unsealed.set(turn, named);
250
+ if (operation !== null)
251
+ sentTurns.set(operation, turn);
223
252
  return { kind: 'action', result: { turn } };
224
253
  }
225
254
  if (name === 'conversation.cancel') {
226
255
  const turn = typeof input.turn === 'string' ? input.turn : '';
227
256
  if (sealed.has(turn) || !unsealed.has(turn)) {
228
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
257
+ return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
229
258
  }
230
259
  unsealed.delete(turn);
231
260
  return { kind: 'action', result: { turn, cancelled: true } };
@@ -250,6 +279,7 @@ export function createMemoryAdapter(options = {}) {
250
279
  };
251
280
  }
252
281
  return {
282
+ ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
253
283
  setRooms(next) {
254
284
  rooms = [...next];
255
285
  retain(rooms);
@@ -262,9 +292,9 @@ export function createMemoryAdapter(options = {}) {
262
292
  for (const observer of observers)
263
293
  observer({ kind: 'opened' });
264
294
  },
265
- close(revoked = false) {
295
+ close({ revoked = false, lost = !revoked } = {}) {
266
296
  for (const observer of observers)
267
- observer({ kind: 'closed', revoked });
297
+ observer({ kind: 'closed', revoked, lost });
268
298
  },
269
299
  expire(locators) {
270
300
  expiring = [...locators];
@@ -273,6 +303,13 @@ export function createMemoryAdapter(options = {}) {
273
303
  for (const observer of observers)
274
304
  observer({ kind: 'room-version', locator, roomVersion });
275
305
  },
306
+ notifyAuthorityChanged(scope) {
307
+ for (const observer of observers) {
308
+ observer(scope === undefined
309
+ ? { kind: 'authority-changed' }
310
+ : { kind: 'authority-changed', scope });
311
+ }
312
+ },
276
313
  notifyConversation(event) {
277
314
  if (event.kind === 'accepted-message') {
278
315
  sealed.add(event.message.turn);
@@ -333,17 +370,19 @@ export function createMemoryAdapter(options = {}) {
333
370
  },
334
371
  reopen() {
335
372
  queueMicrotask(() => {
336
- for (const observer of observers)
337
- observer({ kind: 'closed', revoked: false });
373
+ for (const observer of observers) {
374
+ observer({ kind: 'closed', revoked: false, lost: false });
375
+ }
338
376
  });
339
377
  },
378
+ published() { },
340
379
  observe(notify) {
341
380
  observers.add(notify);
342
381
  queueMicrotask(() => {
343
382
  if (!observers.has(notify))
344
383
  return;
345
384
  if (options.unopened === true) {
346
- notify({ kind: 'closed', revoked: false });
385
+ notify({ kind: 'closed', revoked: false, lost: true });
347
386
  return;
348
387
  }
349
388
  announceList();
@@ -386,7 +425,7 @@ export function createMemoryAdapter(options = {}) {
386
425
  if (room === undefined) {
387
426
  return { kind: 'room-not-readable', locator: request.locator };
388
427
  }
389
- return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));
428
+ return page(room, request.pageToken);
390
429
  }, request).then((answer) => note(request.locator, answer));
391
430
  },
392
431
  async refresh(_authorization, request) {
@@ -419,8 +458,20 @@ export function createMemoryAdapter(options = {}) {
419
458
  if (room === undefined) {
420
459
  return { kind: 'room-not-readable', locator: request.locator };
421
460
  }
422
- return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
423
- }, request).then((answer) => note(request.locator, answer));
461
+ return {
462
+ kind: 'rejected',
463
+ code: 'unscripted-mutation',
464
+ fields: {},
465
+ retryable: false,
466
+ affected: {},
467
+ };
468
+ }, request).then((answer) => {
469
+ const destination = request.changeBatch.between?.destination.room;
470
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
471
+ note(destination, answer.destination);
472
+ }
473
+ return note(request.locator, answer);
474
+ });
424
475
  },
425
476
  async history(_authorization, request) {
426
477
  return resolveScript(scripts.history, () => {
@@ -434,11 +485,25 @@ export function createMemoryAdapter(options = {}) {
434
485
  };
435
486
  }, request);
436
487
  },
488
+ async binary(_authorization, request) {
489
+ return resolveScript(scripts.binary, () => {
490
+ const room = rooms.find((entry) => entry.locator === request.locator);
491
+ if (room === undefined)
492
+ return { kind: 'room-not-readable', locator: request.locator };
493
+ const blob = room.blobs?.[request.path];
494
+ return blob === undefined
495
+ ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
496
+ : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
497
+ }, request);
498
+ },
499
+ async link(_authorization, request) {
500
+ return resolveScript(scripts.link, () => ({ kind: 'rejected', code: 'unscripted-link', fields: {}, retryable: false }), request);
501
+ },
437
502
  async action(_authorization, request) {
438
503
  return resolveScript(scripts.action, () => {
439
504
  if (request.name.startsWith('conversation.'))
440
505
  return conversationAction(request);
441
- return { kind: 'rejected', code: 'unscripted-action', fields: {} };
506
+ return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
442
507
  }, request).then((answer) => {
443
508
  if (answer.kind === 'action' && answer.at !== undefined)
444
509
  note(answer.at.locator, answer.at);
@@ -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
@@ -1,4 +1,5 @@
1
1
  import type { Definition, ValueFacts, VerifiedModel } from '@agentshouse/mdmodel';
2
+ import type { Open } from './open.js';
2
3
  export type ModelIdentity = {
3
4
  identity: string;
4
5
  version: string;
@@ -7,7 +8,7 @@ export type ModelSnapshot = ModelIdentity & {
7
8
  schema: string | null;
8
9
  revision: string | null;
9
10
  };
10
- export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'invalid';
11
+ export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired' | 'invalid'>;
11
12
  export type ModelResult = {
12
13
  kind: 'model';
13
14
  snapshot: ModelSnapshot;
@@ -28,12 +29,13 @@ export type ModelState = {
28
29
  types: VerifiedModel['types'];
29
30
  };
30
31
  export type TypesResult = {
31
- status: 'unavailable';
32
+ status: Open<'unavailable'>;
32
33
  reason: ModelUnavailableReason;
34
+ types: null;
33
35
  schema?: string | null;
34
36
  revision?: string | null;
35
37
  } | {
36
- status: 'current' | 'cached';
38
+ status: Open<'current' | 'cached'>;
37
39
  identity: string;
38
40
  version: string;
39
41
  verifiedWith: ModelIdentity;
@@ -44,12 +46,13 @@ export type TypesResult = {
44
46
  export type ValidationReceipt = {
45
47
  identity: string;
46
48
  version: string;
47
- source: 'current' | 'cached';
49
+ source: Open<'current' | 'cached'>;
48
50
  };
49
51
  export declare const NO_MODEL: ModelState;
50
52
  export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
51
53
  export declare function modelTypes(state: ModelState): TypesResult;
52
54
  export declare function cached(state: ModelState): ModelState;
53
55
  export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
56
+ export declare function sameTyping(left: ModelState, right: ModelState): boolean;
54
57
  export declare function referenceField(facts: ValueFacts | undefined): boolean;
55
58
  //# 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;AAElF,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,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AAC7F,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;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC;AACpG,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":"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,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,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,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CASvE;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAErE"}
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,
@@ -23,6 +23,15 @@ export function cached(state) {
23
23
  export function sameModel(left, right) {
24
24
  return left.identity === right.identity && left.version === right.version;
25
25
  }
26
+ export function sameTyping(left, right) {
27
+ if (left === right)
28
+ return true;
29
+ if (left.status === 'unavailable' || right.status === 'unavailable') {
30
+ return left.status === right.status;
31
+ }
32
+ return (left.snapshot.schema === right.snapshot.schema &&
33
+ sameModel(left.verifiedWith, right.verifiedWith));
34
+ }
26
35
  export function referenceField(facts) {
27
36
  return facts?.reference !== undefined || facts?.items?.reference !== undefined;
28
37
  }
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,32 @@ 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 digestOf({ result, keys }: KeyedResult): Digest;
42
+ export declare function digestApplied(digest: Digest, message: QueryMessage): Digest;
43
+ export declare function changeOf(previous: Digest, next: KeyedResult): QueryMessage | null;
27
44
  //# 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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"}