@agentshouse/mdruntime 0.1.0-alpha.24 → 0.1.0-alpha.25

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 (46) hide show
  1. package/AGENTS.md +36 -0
  2. package/dist/change-set.d.ts +4 -11
  3. package/dist/change-set.d.ts.map +1 -1
  4. package/dist/change-set.js +8 -16
  5. package/dist/change-set.js.map +1 -1
  6. package/dist/client.d.ts +7 -3
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +2 -2
  9. package/dist/client.js.map +1 -1
  10. package/dist/collection.d.ts +0 -2
  11. package/dist/collection.d.ts.map +1 -1
  12. package/dist/collection.js +0 -5
  13. package/dist/collection.js.map +1 -1
  14. package/dist/connection.d.ts +7 -5
  15. package/dist/connection.d.ts.map +1 -1
  16. package/dist/connection.js +52 -68
  17. package/dist/connection.js.map +1 -1
  18. package/dist/conversation.d.ts +4 -4
  19. package/dist/conversation.d.ts.map +1 -1
  20. package/dist/conversation.js +12 -6
  21. package/dist/conversation.js.map +1 -1
  22. package/dist/host.d.ts.map +1 -1
  23. package/dist/host.js.map +1 -1
  24. package/dist/index.d.ts +1 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/paths.d.ts +1 -0
  28. package/dist/paths.d.ts.map +1 -1
  29. package/dist/paths.js +8 -0
  30. package/dist/paths.js.map +1 -1
  31. package/dist/query.d.ts +199 -10
  32. package/dist/query.d.ts.map +1 -1
  33. package/dist/query.js +450 -14
  34. package/dist/query.js.map +1 -1
  35. package/dist/read-side.d.ts +10 -0
  36. package/dist/read-side.d.ts.map +1 -0
  37. package/dist/read-side.js +374 -0
  38. package/dist/read-side.js.map +1 -0
  39. package/dist/rows.d.ts +39 -0
  40. package/dist/rows.d.ts.map +1 -0
  41. package/dist/rows.js +85 -0
  42. package/dist/rows.js.map +1 -0
  43. package/dist/wire.d.ts +1 -1
  44. package/dist/wire.js +1 -1
  45. package/dist/wire.js.map +1 -1
  46. package/package.json +2 -2
@@ -1,11 +1,12 @@
1
- import { rawQuery } from './query.js';
2
1
  import { verify } from '@agentshouse/mdmodel';
3
2
  import { cached, modelTypes, NO_MODEL, sameModel } from './model.js';
3
+ import { identityOf, planOf } from './query.js';
4
+ import { createReadSide } from './read-side.js';
4
5
  import { ROOM_CONTRACT_VERSION, VERSION_1_CAPABILITIES } from './adapter.js';
5
6
  import { bootstrapRoom } from './bootstrap.js';
6
7
  import { changeSet, mergeChangeSets } from './change-set.js';
7
8
  import { createConversationStore } from './conversation.js';
8
- import { MD_MODEL, PRESENTED, validRoot } from './collection.js';
9
+ import { MD_MODEL, validRoot } from './collection.js';
9
10
  import { createLog } from './log.js';
10
11
  import { refreshRoom } from './refresh.js';
11
12
  import { buildBatch } from './save.js';
@@ -58,6 +59,7 @@ export function createMdRuntime(options) {
58
59
  const invalidModels = new Set();
59
60
  const modelEpoch = new Map();
60
61
  const discovered = new Map();
62
+ let roomsListed = false;
61
63
  const scopedRefusals = new Map();
62
64
  function modelKey(locator, attached) {
63
65
  return `${attached} ${locator}`;
@@ -97,15 +99,20 @@ export function createMdRuntime(options) {
97
99
  const refusalListeners = new Set();
98
100
  const storageLossListeners = new Set();
99
101
  const statusListeners = new Set();
100
- const querySubscriptions = new Set();
101
102
  const queueSubscriptions = new Set();
102
103
  const roomDraftListeners = new Set();
103
104
  const presentationListeners = new Set();
105
+ const readSide = createReadSide();
104
106
  let withdrawConversations;
105
107
  let currencyQueued = false;
106
108
  const conversations = createConversationStore({
107
109
  cards: declaredCards,
108
- documents: ()=>visible({}).documents,
110
+ documents: (locator)=>readSide.query(planOf({
111
+ rooms: [
112
+ locator
113
+ ],
114
+ select: 'all'
115
+ }, roomFacts())),
109
116
  call: (name, input)=>invokeAction(name, input),
110
117
  durably,
111
118
  stream: ()=>options.adapter.conversations,
@@ -223,16 +230,26 @@ export function createMdRuntime(options) {
223
230
  })
224
231
  })));
225
232
  }
226
- function queryRooms() {
227
- return [
228
- ...replicas.values()
229
- ].map((replica)=>({
230
- room: replica.confirmed.record.locator,
231
- roomVersion: replica.confirmed.record.roomVersion,
232
- documents: replica.visible.collection.documents,
233
- model: modelTypes(modelOf(replica.confirmed.record.locator)),
234
- typedSelection: replica.confirmed.record.typedSelection === null ? null : modelTypes(modelOf(replica.confirmed.record.locator, 'typed-selection'))
235
- }));
233
+ function roomFacts() {
234
+ const held = [
235
+ ...rooms.values()
236
+ ].map((room)=>{
237
+ const attached = [
238
+ modelOf(room.locator),
239
+ ...room.typedSelection === null ? [] : [
240
+ modelOf(room.locator, 'typed-selection')
241
+ ]
242
+ ];
243
+ return {
244
+ locator: room.locator,
245
+ available: attached.every((model)=>model.status !== 'unavailable'),
246
+ types: attached.flatMap((model)=>model.status === 'unavailable' ? [] : Object.values(model.types))
247
+ };
248
+ });
249
+ return {
250
+ listed: roomsListed,
251
+ rooms: held
252
+ };
236
253
  }
237
254
  function emitRooms() {
238
255
  const value = listed();
@@ -259,26 +276,6 @@ export function createMdRuntime(options) {
259
276
  shown = next;
260
277
  for (const listener of statusListeners)listener(shown);
261
278
  }
262
- function visible(request) {
263
- if (options.queryBinding === null) {
264
- if (Object.keys(request).length > 0) throw new Error('query-binding-unavailable');
265
- return rawQuery(queryRooms());
266
- }
267
- return options.queryBinding(queryRooms(), {
268
- ...request,
269
- selector: {
270
- $and: [
271
- PRESENTED,
272
- request.selector ?? {}
273
- ]
274
- }
275
- });
276
- }
277
- function emitVisible() {
278
- for (const subscription of querySubscriptions){
279
- subscription.notify(visible(subscription.query));
280
- }
281
- }
282
279
  function submissionOf(batch) {
283
280
  return pendings.get(batch.id)?.submission ?? {
284
281
  state: 'waiting'
@@ -299,8 +296,8 @@ export function createMdRuntime(options) {
299
296
  }
300
297
  }
301
298
  function publishChangeSet(set) {
299
+ readSide.apply(set);
302
300
  if (set.rooms.length > 0) emitRooms();
303
- if (set.documents.length > 0 || set.query) emitVisible();
304
301
  for (const locator of set.queues)emitQueue(locator);
305
302
  if (set.drafts.length > 0 || set.documents.some((change)=>roomDrafts.get(change.locator)?.has(change.path) === true)) {
306
303
  publishRoomDrafts(false);
@@ -377,8 +374,7 @@ export function createMdRuntime(options) {
377
374
  }
378
375
  });
379
376
  changed.push(changeSet(locator, before, replicas.get(locator) ?? null, {
380
- room: true,
381
- query: true
377
+ room: true
382
378
  }));
383
379
  }
384
380
  publishChangeSet(mergeChangeSets(changed));
@@ -429,6 +425,7 @@ export function createMdRuntime(options) {
429
425
  }
430
426
  list(room, room.replica.admission === 'admitted' && !unreadable.has(room.locator));
431
427
  }
428
+ roomsListed = true;
432
429
  emitRooms();
433
430
  }
434
431
  function unlistedHeld(listed) {
@@ -452,7 +449,6 @@ export function createMdRuntime(options) {
452
449
  const removed = unlisted.map((locator)=>changeSet(locator, replicas.get(locator) ?? null, null, {
453
450
  room: true,
454
451
  queue: true,
455
- query: true,
456
452
  drafts: [
457
453
  ...roomDrafts.get(locator)?.keys() ?? []
458
454
  ]
@@ -569,15 +565,19 @@ export function createMdRuntime(options) {
569
565
  locators: new Set([
570
566
  ...queuedBatches.keys(),
571
567
  ...replicas.keys()
572
- ])
568
+ ]),
569
+ read: mergeChangeSets([
570
+ ...new Set([
571
+ ...previousReplicas.keys(),
572
+ ...replicas.keys()
573
+ ])
574
+ ].map((locator)=>changeSet(locator, previousReplicas.get(locator) ?? null, replicas.get(locator) ?? null)))
573
575
  };
574
576
  }
575
577
  async function readState(opened) {
576
- const { lastCompleted, locators } = await hydrate(opened);
577
- if (replicas.size > 0) {
578
- emitRooms();
579
- emitVisible();
580
- }
578
+ const { lastCompleted, locators, read } = await hydrate(opened);
579
+ readSide.apply(read);
580
+ if (replicas.size > 0) emitRooms();
581
581
  for (const locator of locators)emitQueue(locator);
582
582
  publishRoomDrafts(false);
583
583
  return lastCompleted;
@@ -689,7 +689,6 @@ export function createMdRuntime(options) {
689
689
  replicas.set(locator, replicaOf(confirmed, kept, rewriting(), before));
690
690
  return changeSet(locator, before ?? null, replicas.get(locator) ?? null, {
691
691
  room: settling.room,
692
- query: settling.query,
693
692
  queue: kept.length !== (before?.queue.length ?? 0),
694
693
  drafts: [
695
694
  ...written.keys()
@@ -707,14 +706,12 @@ export function createMdRuntime(options) {
707
706
  if (retained === null) {
708
707
  list(room, true);
709
708
  publishChangeSet(changeSet(room.locator, prior ?? null, prior ?? null, {
710
- room: true,
711
- query: true
709
+ room: true
712
710
  }));
713
711
  return;
714
712
  }
715
713
  const set = await settle(local, room.locator, prior, retained, prior?.queue ?? [], {
716
- room: true,
717
- query: true
714
+ room: true
718
715
  });
719
716
  unreadable.delete(room.locator);
720
717
  list(room, true);
@@ -1082,8 +1079,7 @@ export function createMdRuntime(options) {
1082
1079
  id: submitted.id,
1083
1080
  outcome: acceptedOutcome
1084
1081
  },
1085
- room: true,
1086
- query: true
1082
+ room: true
1087
1083
  });
1088
1084
  unreadable.delete(room.locator);
1089
1085
  list(room, true);
@@ -1261,7 +1257,6 @@ export function createMdRuntime(options) {
1261
1257
  const previous = modelOf(room.locator, attached);
1262
1258
  const heldBefore = replicas.get(room.locator)?.confirmed.record;
1263
1259
  if (JSON.stringify(previous) === JSON.stringify(next) && (heldBefore === undefined || JSON.stringify(heldBefore.operations) === JSON.stringify(room.operations) && JSON.stringify(heldBefore.replica) === JSON.stringify(room.replica) && JSON.stringify(heldBefore.attachedModel) === JSON.stringify(room.attachedModel) && JSON.stringify(heldBefore.typedSelection) === JSON.stringify(room.typedSelection ?? null))) return;
1264
- const queryChanged = previous.status === 'unavailable' || next.status === 'unavailable' ? previous.status !== next.status : JSON.stringify(previous.types) !== JSON.stringify(next.types);
1265
1260
  if (next.status === 'unavailable') {
1266
1261
  invalidModels.add(key);
1267
1262
  liveModels.delete(key);
@@ -1300,8 +1295,7 @@ export function createMdRuntime(options) {
1300
1295
  list(room, room.replica.admission === 'admitted' && !unreadable.has(room.locator));
1301
1296
  if (held === undefined) emitRooms();
1302
1297
  else publishChangeSet(changeSet(room.locator, held, replicas.get(room.locator) ?? null, {
1303
- room: true,
1304
- query: queryChanged
1298
+ room: true
1305
1299
  }));
1306
1300
  });
1307
1301
  }
@@ -1751,7 +1745,7 @@ export function createMdRuntime(options) {
1751
1745
  refusalListeners.clear();
1752
1746
  storageLossListeners.clear();
1753
1747
  statusListeners.clear();
1754
- querySubscriptions.clear();
1748
+ readSide.close();
1755
1749
  queueSubscriptions.clear();
1756
1750
  roomDraftListeners.clear();
1757
1751
  presentationListeners.clear();
@@ -1774,9 +1768,7 @@ export function createMdRuntime(options) {
1774
1768
  slots () {
1775
1769
  return slotted();
1776
1770
  },
1777
- query (request = {}) {
1778
- return visible(request);
1779
- },
1771
+ query: (input)=>readSide.query(planOf(input, roomFacts())),
1780
1772
  types (locator) {
1781
1773
  return {
1782
1774
  collection: modelTypes(modelOf(locator)),
@@ -1989,16 +1981,8 @@ export function createMdRuntime(options) {
1989
1981
  queueSubscriptions.delete(queue);
1990
1982
  };
1991
1983
  }
1992
- const subscription = {
1993
- query: second,
1994
- notify: third
1995
- };
1996
- const first = visible(subscription.query);
1997
- querySubscriptions.add(subscription);
1998
- subscription.notify(first);
1999
- return ()=>{
2000
- querySubscriptions.delete(subscription);
2001
- };
1984
+ const plan = planOf(second, roomFacts());
1985
+ return readSide.observe(plan, identityOf(plan), third);
2002
1986
  },
2003
1987
  async reauthorize () {
2004
1988
  if (refusal === null || !refusal.reauthorizationOffered) return;