@agentshouse/mdruntime 0.1.0-cc7bd7a53214e → 0.1.0-ccd098ff75bbf

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 (183) hide show
  1. package/README.md +24 -11
  2. package/dist/adapter.d.ts +172 -49
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +1 -9
  5. package/dist/attached-model.d.ts +15 -0
  6. package/dist/attached-model.d.ts.map +1 -0
  7. package/dist/attached-model.js +64 -0
  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 +39 -7
  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/client.d.ts +37 -15
  27. package/dist/client.d.ts.map +1 -1
  28. package/dist/client.js +110 -27
  29. package/dist/collection.d.ts +9 -13
  30. package/dist/collection.d.ts.map +1 -1
  31. package/dist/collection.js +46 -56
  32. package/dist/compile.d.ts +16 -0
  33. package/dist/compile.d.ts.map +1 -0
  34. package/dist/compile.js +740 -0
  35. package/dist/connection.d.ts +62 -25
  36. package/dist/connection.d.ts.map +1 -1
  37. package/dist/connection.js +3831 -958
  38. package/dist/conversation.d.ts +56 -16
  39. package/dist/conversation.d.ts.map +1 -1
  40. package/dist/conversation.js +739 -242
  41. package/dist/digest.d.ts +7 -0
  42. package/dist/digest.d.ts.map +1 -0
  43. package/dist/digest.js +113 -0
  44. package/dist/durability.d.ts +5 -1
  45. package/dist/durability.d.ts.map +1 -1
  46. package/dist/durability.js +5 -0
  47. package/dist/entry.d.ts +19 -0
  48. package/dist/entry.d.ts.map +1 -0
  49. package/dist/entry.js +151 -0
  50. package/dist/expectation.d.ts +21 -0
  51. package/dist/expectation.d.ts.map +1 -0
  52. package/dist/expectation.js +70 -0
  53. package/dist/failure.d.ts +13 -0
  54. package/dist/failure.d.ts.map +1 -0
  55. package/dist/failure.js +19 -0
  56. package/dist/fence.d.ts +6 -0
  57. package/dist/fence.d.ts.map +1 -0
  58. package/dist/fence.js +10 -0
  59. package/dist/file.d.ts +2 -10
  60. package/dist/file.d.ts.map +1 -1
  61. package/dist/file.js +3 -120
  62. package/dist/fulltext.d.ts +27 -0
  63. package/dist/fulltext.d.ts.map +1 -0
  64. package/dist/fulltext.js +368 -0
  65. package/dist/host.d.ts +15 -2
  66. package/dist/host.d.ts.map +1 -1
  67. package/dist/host.js +134 -31
  68. package/dist/identity.d.ts +4 -0
  69. package/dist/identity.d.ts.map +1 -1
  70. package/dist/identity.js +16 -1
  71. package/dist/index.d.ts +20 -9
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +8 -0
  74. package/dist/live.d.ts +22 -0
  75. package/dist/live.d.ts.map +1 -0
  76. package/dist/live.js +123 -0
  77. package/dist/memory.d.ts +22 -8
  78. package/dist/memory.d.ts.map +1 -1
  79. package/dist/memory.js +167 -47
  80. package/dist/messages.d.ts +28 -0
  81. package/dist/messages.d.ts.map +1 -0
  82. package/dist/messages.js +90 -0
  83. package/dist/model.d.ts +17 -14
  84. package/dist/model.d.ts.map +1 -1
  85. package/dist/model.js +16 -4
  86. package/dist/name.d.ts +4 -0
  87. package/dist/name.d.ts.map +1 -0
  88. package/dist/name.js +122 -0
  89. package/dist/observation.d.ts +19 -2
  90. package/dist/observation.d.ts.map +1 -1
  91. package/dist/observation.js +113 -12
  92. package/dist/open.d.ts +2 -0
  93. package/dist/open.d.ts.map +1 -0
  94. package/dist/open.js +1 -0
  95. package/dist/opened.d.ts +22 -0
  96. package/dist/opened.d.ts.map +1 -0
  97. package/dist/opened.js +107 -0
  98. package/dist/outcome.d.ts +62 -3
  99. package/dist/outcome.d.ts.map +1 -1
  100. package/dist/outcome.js +67 -1
  101. package/dist/overlay.d.ts +15 -5
  102. package/dist/overlay.d.ts.map +1 -1
  103. package/dist/overlay.js +136 -180
  104. package/dist/paths.d.ts +0 -1
  105. package/dist/paths.d.ts.map +1 -1
  106. package/dist/paths.js +0 -16
  107. package/dist/query.d.ts +65 -5
  108. package/dist/query.d.ts.map +1 -1
  109. package/dist/query.js +122 -40
  110. package/dist/reach.d.ts +11 -4
  111. package/dist/reach.d.ts.map +1 -1
  112. package/dist/reach.js +211 -75
  113. package/dist/react.d.ts +43 -0
  114. package/dist/react.d.ts.map +1 -0
  115. package/dist/react.js +54 -0
  116. package/dist/readiness.d.ts +64 -0
  117. package/dist/readiness.d.ts.map +1 -0
  118. package/dist/readiness.js +33 -0
  119. package/dist/reads.d.ts +11 -0
  120. package/dist/reads.d.ts.map +1 -0
  121. package/dist/reads.js +100 -0
  122. package/dist/recovery.d.ts +25 -0
  123. package/dist/recovery.d.ts.map +1 -0
  124. package/dist/recovery.js +198 -0
  125. package/dist/refresh.d.ts +19 -7
  126. package/dist/refresh.d.ts.map +1 -1
  127. package/dist/refresh.js +125 -53
  128. package/dist/replica.d.ts +59 -33
  129. package/dist/replica.d.ts.map +1 -1
  130. package/dist/replica.js +321 -156
  131. package/dist/room-draft.d.ts +41 -9
  132. package/dist/room-draft.d.ts.map +1 -1
  133. package/dist/room-draft.js +186 -37
  134. package/dist/rows.d.ts +37 -34
  135. package/dist/rows.d.ts.map +1 -1
  136. package/dist/rows.js +187 -82
  137. package/dist/save.d.ts +72 -6
  138. package/dist/save.d.ts.map +1 -1
  139. package/dist/save.js +889 -178
  140. package/dist/search.d.ts +41 -29
  141. package/dist/search.d.ts.map +1 -1
  142. package/dist/search.js +37 -105
  143. package/dist/seed.d.ts +16 -0
  144. package/dist/seed.d.ts.map +1 -0
  145. package/dist/seed.js +75 -0
  146. package/dist/shared.d.ts +16 -0
  147. package/dist/shared.d.ts.map +1 -0
  148. package/dist/shared.js +431 -0
  149. package/dist/status.d.ts +6 -2
  150. package/dist/status.d.ts.map +1 -1
  151. package/dist/status.js +0 -8
  152. package/dist/store.d.ts +123 -58
  153. package/dist/store.d.ts.map +1 -1
  154. package/dist/store.js +359 -344
  155. package/dist/stored.d.ts +145 -0
  156. package/dist/stored.d.ts.map +1 -0
  157. package/dist/stored.js +557 -0
  158. package/dist/tables.d.ts +354 -0
  159. package/dist/tables.d.ts.map +1 -0
  160. package/dist/tables.js +624 -0
  161. package/dist/turn.d.ts +9 -0
  162. package/dist/turn.d.ts.map +1 -0
  163. package/dist/turn.js +75 -0
  164. package/dist/validation.d.ts +30 -0
  165. package/dist/validation.d.ts.map +1 -0
  166. package/dist/validation.js +162 -0
  167. package/dist/windows.d.ts +22 -0
  168. package/dist/windows.d.ts.map +1 -0
  169. package/dist/windows.js +89 -0
  170. package/dist/wire.d.ts +170 -45
  171. package/dist/wire.d.ts.map +1 -1
  172. package/dist/wire.js +69 -46
  173. package/dist/words.d.ts +19 -0
  174. package/dist/words.d.ts.map +1 -0
  175. package/dist/words.js +150 -0
  176. package/package.json +33 -10
  177. package/AGENTS.md +0 -215
  178. package/dist/attachment.d.ts +0 -3
  179. package/dist/attachment.d.ts.map +0 -1
  180. package/dist/attachment.js +0 -8
  181. package/dist/read-side.d.ts +0 -18
  182. package/dist/read-side.d.ts.map +0 -1
  183. package/dist/read-side.js +0 -377
package/dist/memory.js CHANGED
@@ -1,9 +1,7 @@
1
- import { ROOM_CONTRACT_VERSION, } from './adapter.js';
2
- import { MD_MODEL } from './collection.js';
3
1
  import { sameChange } from './overlay.js';
4
2
  const FIXTURE_RETENTION = {
5
3
  history: { kind: 'duration', seconds: 1 },
6
- outcome: 1,
4
+ outcome: 604_800,
7
5
  refreshHorizon: 1,
8
6
  };
9
7
  function declaredRetention(value) {
@@ -15,6 +13,14 @@ function declaredRetention(value) {
15
13
  }
16
14
  throw new Error('history retention duration must be a finite positive number of seconds');
17
15
  }
16
+ const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
17
+ function modelsOf(room) {
18
+ return { collection: room.model ?? MODEL_ABSENT };
19
+ }
20
+ function changedModels(room, from) {
21
+ const now = modelsOf(room);
22
+ return JSON.stringify(now) === JSON.stringify(modelsOf(from)) ? undefined : now;
23
+ }
18
24
  function named(source, paths) {
19
25
  const taken = {};
20
26
  for (const path of paths) {
@@ -31,8 +37,6 @@ async function resolveScript(answer, fallback, request) {
31
37
  }
32
38
  export function createMemoryAdapter(options = {}) {
33
39
  let rooms = options.rooms === undefined ? [] : [...options.rooms];
34
- const mdModel = options.mdModel ?? MD_MODEL;
35
- const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];
36
40
  const capabilities = options.capabilities ?? [];
37
41
  const providerLimits = options.providerLimits ?? [];
38
42
  const retention = declaredRetention(options.retention);
@@ -46,8 +50,10 @@ export function createMemoryAdapter(options = {}) {
46
50
  const scripted = new Map();
47
51
  const unsealed = new Map();
48
52
  const sealed = new Set();
53
+ const sentTurns = new Map();
49
54
  const historyPageSize = options.historyPageSize;
50
- let selected = [];
55
+ let held = [];
56
+ let expiring = [];
51
57
  let replicated = [];
52
58
  let issued = 0;
53
59
  function scriptConversations(entries) {
@@ -89,37 +95,54 @@ export function createMemoryAdapter(options = {}) {
89
95
  return {
90
96
  name: room.name,
91
97
  locator: room.locator,
98
+ handle: room.handle,
92
99
  roomVersion: room.roomVersion,
93
100
  operations: room.operations,
94
101
  replica: room.replica,
95
- attachedModel: room.attachedModel,
96
102
  ...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
97
103
  providerOwnedPaths: room.providerOwnedPaths,
98
104
  };
99
105
  }
100
- function page(room, from) {
106
+ function page(room, after) {
101
107
  const paths = Object.keys(room.documents ?? {}).sort();
108
+ const opening = after === undefined;
109
+ const from = opening ? 0 : paths.filter((path) => path <= after).length;
102
110
  const size = pageSize ?? paths.length;
103
111
  const taken = paths.slice(from, from + size);
104
112
  const next = from + taken.length;
105
- const targets = from === 0 ? (room.binaryTargets ?? []) : [];
113
+ const targets = opening ? Object.keys(room.binaryFiles ?? {}) : [];
106
114
  return {
107
115
  kind: 'bootstrap',
108
116
  roomVersion: room.roomVersion,
117
+ ...(opening ? { models: modelsOf(room) } : {}),
109
118
  documents: named(room.documents ?? {}, taken),
110
- revisions: named(room.revisions ?? {}, taken),
119
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
120
+ ...(room.fileIds === undefined
121
+ ? {}
122
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
111
123
  changes: named(room.changes ?? {}, [...taken, ...targets]),
112
- binaryTargets: targets,
113
- ...(from === 0 && room.attachments !== undefined ? { attachments: room.attachments } : {}),
114
- ...(next < paths.length ? { pageToken: String(next) } : {}),
124
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
125
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
126
+ ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
127
+ };
128
+ }
129
+ function foldersMoved(room, from) {
130
+ const now = new Set(room.folders ?? []);
131
+ const before = new Set(from.folders ?? []);
132
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
133
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
134
+ return {
135
+ ...(folders.length === 0 ? {} : { folders }),
136
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
115
137
  };
116
138
  }
117
139
  function advancement(room, from, at) {
118
140
  const current = room.documents ?? {};
119
141
  const previous = from.documents ?? {};
120
- const currentTargets = new Set(room.binaryTargets ?? []);
121
- const previousTargets = new Set(from.binaryTargets ?? []);
142
+ const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
143
+ const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
122
144
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
145
+ room.fileIds?.[path] !== from.fileIds?.[path] ||
123
146
  !sameChange(room.changes?.[path], from.changes?.[path]);
124
147
  const changed = Object.keys(current)
125
148
  .filter((path) => current[path] !== previous[path] || headMoved(path))
@@ -134,22 +157,25 @@ export function createMemoryAdapter(options = {}) {
134
157
  const targets = opening
135
158
  ? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
136
159
  : [];
137
- const attachments = room.attachments ?? [];
138
- const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
160
+ const models = opening ? changedModels(room, from) : undefined;
139
161
  return {
140
162
  kind: 'net-advancement',
141
163
  roomVersion: room.roomVersion,
164
+ ...(models === undefined ? {} : { models }),
142
165
  documents: named(current, taken),
143
- revisions: named(room.revisions ?? {}, taken),
166
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
167
+ ...(room.fileIds === undefined
168
+ ? {}
169
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
144
170
  changes: named(room.changes ?? {}, [...taken, ...targets]),
145
- binaryTargets: targets,
171
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
172
+ ...(opening ? foldersMoved(room, from) : {}),
146
173
  removals: opening
147
174
  ? [
148
175
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
149
176
  ...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
150
177
  ].sort()
151
178
  : [],
152
- ...(declared ? { attachments } : {}),
153
179
  ...(pageToken === undefined ? {} : { pageToken }),
154
180
  };
155
181
  }
@@ -170,7 +196,7 @@ export function createMemoryAdapter(options = {}) {
170
196
  function historiesOf(input) {
171
197
  const asked = input?.conversations;
172
198
  if (!Array.isArray(asked))
173
- return { kind: 'rejected', code: 'invalid_request', fields: {} };
199
+ return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
174
200
  const histories = [];
175
201
  for (const entry of asked) {
176
202
  const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
@@ -198,21 +224,32 @@ export function createMemoryAdapter(options = {}) {
198
224
  const named = typeof input.conversation === 'string' ? input.conversation : '';
199
225
  const conversation = scripted.get(named);
200
226
  if (conversation === undefined) {
201
- return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
227
+ return {
228
+ kind: 'rejected',
229
+ code: 'unknown-conversation',
230
+ fields: { conversation: named },
231
+ retryable: false,
232
+ };
202
233
  }
203
234
  const outcome = conversation.outcomes?.[name];
204
235
  if (outcome !== undefined)
205
236
  return outcome;
206
237
  if (name === 'conversation.send') {
238
+ const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
239
+ const answered = operation === null ? undefined : sentTurns.get(operation);
240
+ if (answered !== undefined)
241
+ return { kind: 'action', result: { turn: answered } };
207
242
  issued += 1;
208
243
  const turn = `turn-${issued}`;
209
244
  unsealed.set(turn, named);
245
+ if (operation !== null)
246
+ sentTurns.set(operation, turn);
210
247
  return { kind: 'action', result: { turn } };
211
248
  }
212
249
  if (name === 'conversation.cancel') {
213
250
  const turn = typeof input.turn === 'string' ? input.turn : '';
214
251
  if (sealed.has(turn) || !unsealed.has(turn)) {
215
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
252
+ return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
216
253
  }
217
254
  unsealed.delete(turn);
218
255
  return { kind: 'action', result: { turn, cancelled: true } };
@@ -221,18 +258,24 @@ export function createMemoryAdapter(options = {}) {
221
258
  scripted.delete(named);
222
259
  return { kind: 'action', result: { conversation: named } };
223
260
  }
261
+ function announceList() {
262
+ const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined ? [] : [{ conversation, ...listed }]);
263
+ for (const listener of listeners)
264
+ listener({ kind: 'list', entries });
265
+ }
224
266
  function discovery() {
225
267
  return {
226
268
  kind: 'discovery',
227
- supportedVersions,
228
- mdModel,
229
269
  rooms: rooms.map(declared),
230
270
  capabilities,
231
271
  providerLimits,
232
272
  retention,
273
+ ...(options.member === undefined ? {} : { member: options.member }),
233
274
  };
234
275
  }
235
276
  return {
277
+ ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
278
+ ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
236
279
  setRooms(next) {
237
280
  rooms = [...next];
238
281
  retain(rooms);
@@ -240,9 +283,28 @@ export function createMemoryAdapter(options = {}) {
240
283
  setConversations(next) {
241
284
  scriptConversations(next);
242
285
  },
243
- notifyRoomVersion(notification) {
286
+ open() {
287
+ announceList();
288
+ for (const observer of observers)
289
+ observer({ kind: 'opened' });
290
+ },
291
+ close({ revoked = false, lost = !revoked } = {}) {
244
292
  for (const observer of observers)
245
- observer(notification);
293
+ observer({ kind: 'closed', revoked, lost });
294
+ },
295
+ expire(locators) {
296
+ expiring = [...locators];
297
+ },
298
+ notifyRoomVersion({ locator, roomVersion }) {
299
+ for (const observer of observers)
300
+ observer({ kind: 'room-version', locator, roomVersion });
301
+ },
302
+ notifyAuthorityChanged(scope) {
303
+ for (const observer of observers) {
304
+ observer(scope === undefined
305
+ ? { kind: 'authority-changed' }
306
+ : { kind: 'authority-changed', scope });
307
+ }
246
308
  },
247
309
  notifyConversation(event) {
248
310
  if (event.kind === 'accepted-message') {
@@ -256,8 +318,8 @@ export function createMemoryAdapter(options = {}) {
256
318
  for (const observer of modeObservers)
257
319
  observer(mode);
258
320
  },
259
- selectedRooms() {
260
- return selected;
321
+ heldRooms() {
322
+ return held;
261
323
  },
262
324
  replicatedConversations() {
263
325
  return replicated;
@@ -281,12 +343,47 @@ export function createMemoryAdapter(options = {}) {
281
343
  };
282
344
  },
283
345
  },
284
- roomVersions: {
285
- select(locators) {
286
- selected = [...locators];
346
+ roomStream: {
347
+ hold(asked) {
348
+ held = asked.map((room) => room.locator);
349
+ const expired = expiring.filter((locator) => held.includes(locator));
350
+ expiring = [];
351
+ const moved = asked.flatMap((room) => {
352
+ const current = rooms.find((entry) => entry.locator === room.locator);
353
+ return current === undefined ||
354
+ expired.includes(room.locator) ||
355
+ current.roomVersion === room.roomVersion
356
+ ? []
357
+ : [{ locator: room.locator, roomVersion: current.roomVersion }];
358
+ });
359
+ queueMicrotask(() => {
360
+ for (const observer of observers) {
361
+ for (const room of moved)
362
+ observer({ kind: 'room-version', ...room });
363
+ observer({ kind: 'opening', expired });
364
+ }
365
+ });
366
+ },
367
+ reopen() {
368
+ queueMicrotask(() => {
369
+ for (const observer of observers) {
370
+ observer({ kind: 'closed', revoked: false, lost: false });
371
+ }
372
+ });
287
373
  },
374
+ published() { },
288
375
  observe(notify) {
289
376
  observers.add(notify);
377
+ queueMicrotask(() => {
378
+ if (!observers.has(notify))
379
+ return;
380
+ if (options.unopened === true) {
381
+ notify({ kind: 'closed', revoked: false, lost: true });
382
+ return;
383
+ }
384
+ announceList();
385
+ notify({ kind: 'opened' });
386
+ });
290
387
  return () => {
291
388
  observers.delete(notify);
292
389
  };
@@ -298,13 +395,6 @@ export function createMemoryAdapter(options = {}) {
298
395
  else
299
396
  scripts[operation] = answer;
300
397
  },
301
- async model(_authorization, request) {
302
- return resolveScript(scripts.model, () => {
303
- const room = rooms.find((entry) => entry.locator === request.locator);
304
- const answer = request.attached === 'collection' ? room?.model : room?.selectionModel;
305
- return answer ?? { kind: 'model-unavailable', reason: 'not-readable' };
306
- }, request);
307
- },
308
398
  async authorize() {
309
399
  return resolveScript(scripts.authorize, () => ({}), undefined);
310
400
  },
@@ -317,13 +407,21 @@ export function createMemoryAdapter(options = {}) {
317
407
  });
318
408
  },
319
409
  reached,
410
+ follows(locator, roomVersion, next) {
411
+ const scripted = scripts.follows;
412
+ if (typeof scripted === 'boolean')
413
+ return scripted;
414
+ if (scripted !== undefined)
415
+ return scripted(locator, roomVersion, next);
416
+ return true;
417
+ },
320
418
  async bootstrap(_authorization, request) {
321
419
  return resolveScript(scripts.bootstrap, () => {
322
420
  const room = rooms.find((entry) => entry.locator === request.locator);
323
421
  if (room === undefined) {
324
422
  return { kind: 'room-not-readable', locator: request.locator };
325
423
  }
326
- return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));
424
+ return page(room, request.pageToken);
327
425
  }, request).then((answer) => note(request.locator, answer));
328
426
  },
329
427
  async refresh(_authorization, request) {
@@ -341,10 +439,6 @@ export function createMemoryAdapter(options = {}) {
341
439
  }
342
440
  return advancement(continuation.room, continuation.from, continuation.at);
343
441
  }
344
- if (request.minPosition !== undefined &&
345
- !reached(room.locator, room.roomVersion, request.minPosition)) {
346
- return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
347
- }
348
442
  if (request.fromRoomVersion === room.roomVersion) {
349
443
  return { kind: 'still-current' };
350
444
  }
@@ -360,8 +454,20 @@ export function createMemoryAdapter(options = {}) {
360
454
  if (room === undefined) {
361
455
  return { kind: 'room-not-readable', locator: request.locator };
362
456
  }
363
- return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
364
- }, request).then((answer) => note(request.locator, answer));
457
+ return {
458
+ kind: 'rejected',
459
+ code: 'unscripted-mutation',
460
+ fields: {},
461
+ retryable: false,
462
+ affected: {},
463
+ };
464
+ }, request).then((answer) => {
465
+ const destination = request.changeBatch.between?.destination.room;
466
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
467
+ note(destination, answer.destination);
468
+ }
469
+ return note(request.locator, answer);
470
+ });
365
471
  },
366
472
  async history(_authorization, request) {
367
473
  return resolveScript(scripts.history, () => {
@@ -375,11 +481,25 @@ export function createMemoryAdapter(options = {}) {
375
481
  };
376
482
  }, request);
377
483
  },
484
+ async binary(_authorization, request) {
485
+ return resolveScript(scripts.binary, () => {
486
+ const room = rooms.find((entry) => entry.locator === request.locator);
487
+ if (room === undefined)
488
+ return { kind: 'room-not-readable', locator: request.locator };
489
+ const blob = room.blobs?.[request.path];
490
+ return blob === undefined
491
+ ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
492
+ : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
493
+ }, request);
494
+ },
495
+ async link(_authorization, request) {
496
+ return resolveScript(scripts.link, () => ({ kind: 'rejected', code: 'unscripted-link', fields: {}, retryable: false }), request);
497
+ },
378
498
  async action(_authorization, request) {
379
499
  return resolveScript(scripts.action, () => {
380
500
  if (request.name.startsWith('conversation.'))
381
501
  return conversationAction(request);
382
- return { kind: 'rejected', code: 'unscripted-action', fields: {} };
502
+ return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
383
503
  }, request).then((answer) => {
384
504
  if (answer.kind === 'action' && answer.at !== undefined)
385
505
  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,31 +1,27 @@
1
- import type { Definition, FieldSpec, SectionSpec, VerifiedModel } from '@agentshouse/mdmodel';
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;
5
6
  };
6
7
  export type ModelSnapshot = ModelIdentity & {
7
8
  schema: string | null;
9
+ revision: string | null;
8
10
  };
9
- export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'version-changed' | 'invalid';
11
+ export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired' | 'invalid'>;
10
12
  export type ModelResult = {
11
13
  kind: 'model';
12
14
  snapshot: ModelSnapshot;
13
15
  } | {
14
16
  kind: 'model-unavailable';
15
17
  reason: ModelUnavailableReason;
16
- } | {
17
- kind: 'transport-uncertainty';
18
- } | {
19
- kind: 'revoked-authorization';
20
- };
21
- export type MdType = {
22
- name: string;
23
- fields: Readonly<Record<string, FieldSpec>>;
24
- sections: Readonly<Record<string, SectionSpec>>;
25
18
  };
19
+ export type MdType = Definition;
26
20
  export type ModelState = {
27
21
  status: 'unavailable';
28
22
  reason: ModelUnavailableReason;
23
+ schema?: string | null;
24
+ revision?: string | null;
29
25
  } | {
30
26
  status: 'current' | 'cached';
31
27
  snapshot: ModelSnapshot;
@@ -33,23 +29,30 @@ export type ModelState = {
33
29
  types: VerifiedModel['types'];
34
30
  };
35
31
  export type TypesResult = {
36
- status: 'unavailable';
32
+ status: Open<'unavailable'>;
37
33
  reason: ModelUnavailableReason;
34
+ types: null;
35
+ schema?: string | null;
36
+ revision?: string | null;
38
37
  } | {
39
- status: 'current' | 'cached';
38
+ status: Open<'current' | 'cached'>;
40
39
  identity: string;
41
40
  version: string;
42
41
  verifiedWith: ModelIdentity;
43
42
  types: readonly MdType[];
43
+ schema: string | null;
44
+ revision: string | null;
44
45
  };
45
46
  export type ValidationReceipt = {
46
47
  identity: string;
47
48
  version: string;
48
- source: 'current' | 'cached';
49
+ source: Open<'current' | 'cached'>;
49
50
  };
50
51
  export declare const NO_MODEL: ModelState;
51
52
  export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
52
53
  export declare function modelTypes(state: ModelState): TypesResult;
53
54
  export declare function cached(state: ModelState): ModelState;
54
55
  export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
56
+ export declare function sameTyping(left: ModelState, right: ModelState): boolean;
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,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9F,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,CAAA;CAAE,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,SAAS,CAAC;AACd,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,GAC7D;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;CACjD,CAAC;AACF,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;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;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;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;CAC1B,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,CAczD;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E"}
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,CAczD;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,15 +6,15 @@ 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,
13
13
  version: state.snapshot.version,
14
14
  verifiedWith: { ...state.verifiedWith },
15
- types: structuredClone(Object.values(state.types)
16
- .sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
17
- .map(({ name, fields, sections }) => ({ name, fields, sections }))),
15
+ schema: state.snapshot.schema,
16
+ revision: state.snapshot.revision,
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
20
  export function cached(state) {
@@ -23,3 +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
+ }
35
+ export function referenceField(facts) {
36
+ return facts?.reference !== undefined || facts?.items?.reference !== undefined;
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"}