@agentshouse/mdruntime 0.1.0-c1ff51b87bc3d → 0.1.0-c20970f71a6a9

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 (111) hide show
  1. package/README.md +1 -1
  2. package/dist/adapter.d.ts +68 -48
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/bootstrap.d.ts +4 -7
  5. package/dist/bootstrap.d.ts.map +1 -1
  6. package/dist/bootstrap.js +19 -14
  7. package/dist/client.d.ts +4 -4
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +0 -1
  10. package/dist/collection.d.ts +0 -3
  11. package/dist/collection.d.ts.map +1 -1
  12. package/dist/collection.js +1 -17
  13. package/dist/compile.d.ts +1 -1
  14. package/dist/compile.d.ts.map +1 -1
  15. package/dist/compile.js +69 -45
  16. package/dist/connection.d.ts +3 -5
  17. package/dist/connection.d.ts.map +1 -1
  18. package/dist/connection.js +867 -851
  19. package/dist/conversation.d.ts +14 -14
  20. package/dist/conversation.d.ts.map +1 -1
  21. package/dist/conversation.js +153 -145
  22. package/dist/durability.d.ts +0 -1
  23. package/dist/durability.d.ts.map +1 -1
  24. package/dist/entry.d.ts.map +1 -1
  25. package/dist/entry.js +1 -0
  26. package/dist/host.d.ts +3 -6
  27. package/dist/host.d.ts.map +1 -1
  28. package/dist/host.js +8 -17
  29. package/dist/index.d.ts +5 -4
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/live.d.ts.map +1 -1
  33. package/dist/live.js +1 -2
  34. package/dist/media.d.ts +1 -1
  35. package/dist/media.d.ts.map +1 -1
  36. package/dist/media.js +19 -9
  37. package/dist/memory.d.ts +9 -5
  38. package/dist/memory.d.ts.map +1 -1
  39. package/dist/memory.js +134 -82
  40. package/dist/messages.d.ts +2 -2
  41. package/dist/messages.d.ts.map +1 -1
  42. package/dist/messages.js +15 -16
  43. package/dist/model.d.ts +0 -1
  44. package/dist/model.d.ts.map +1 -1
  45. package/dist/model.js +0 -9
  46. package/dist/outcome.d.ts +0 -3
  47. package/dist/outcome.d.ts.map +1 -1
  48. package/dist/phrase.d.ts +3 -0
  49. package/dist/phrase.d.ts.map +1 -0
  50. package/dist/phrase.js +8 -0
  51. package/dist/query.d.ts +5 -1
  52. package/dist/query.d.ts.map +1 -1
  53. package/dist/query.js +20 -1
  54. package/dist/reach.d.ts +3 -3
  55. package/dist/reach.d.ts.map +1 -1
  56. package/dist/reach.js +19 -29
  57. package/dist/react.d.ts +1 -0
  58. package/dist/react.d.ts.map +1 -1
  59. package/dist/readiness.d.ts +2 -15
  60. package/dist/readiness.d.ts.map +1 -1
  61. package/dist/readiness.js +4 -10
  62. package/dist/recovery.d.ts +1 -0
  63. package/dist/recovery.d.ts.map +1 -1
  64. package/dist/recovery.js +26 -0
  65. package/dist/refresh.d.ts +7 -5
  66. package/dist/refresh.d.ts.map +1 -1
  67. package/dist/refresh.js +46 -6
  68. package/dist/replica.d.ts +0 -1
  69. package/dist/replica.d.ts.map +1 -1
  70. package/dist/replica.js +3 -4
  71. package/dist/room-draft.d.ts +1 -1
  72. package/dist/room-draft.d.ts.map +1 -1
  73. package/dist/room-draft.js +61 -48
  74. package/dist/rows.d.ts +3 -2
  75. package/dist/rows.d.ts.map +1 -1
  76. package/dist/rows.js +34 -29
  77. package/dist/search.d.ts +12 -63
  78. package/dist/search.d.ts.map +1 -1
  79. package/dist/search.js +9 -52
  80. package/dist/shared.d.ts +0 -1
  81. package/dist/shared.d.ts.map +1 -1
  82. package/dist/shared.js +0 -10
  83. package/dist/status.d.ts +0 -4
  84. package/dist/status.d.ts.map +1 -1
  85. package/dist/store.d.ts +15 -19
  86. package/dist/store.d.ts.map +1 -1
  87. package/dist/store.js +40 -39
  88. package/dist/stored.d.ts +33 -6
  89. package/dist/stored.d.ts.map +1 -1
  90. package/dist/stored.js +97 -122
  91. package/dist/tables.d.ts +34 -33
  92. package/dist/tables.d.ts.map +1 -1
  93. package/dist/tables.js +18 -54
  94. package/dist/transfer.d.ts +0 -5
  95. package/dist/transfer.d.ts.map +1 -1
  96. package/dist/validation.d.ts +3 -4
  97. package/dist/validation.d.ts.map +1 -1
  98. package/dist/validation.js +35 -96
  99. package/dist/wire.d.ts +1 -4
  100. package/dist/wire.d.ts.map +1 -1
  101. package/dist/wire.js +1 -1
  102. package/package.json +2 -2
  103. package/dist/fulltext.d.ts +0 -27
  104. package/dist/fulltext.d.ts.map +0 -1
  105. package/dist/fulltext.js +0 -368
  106. package/dist/reads.d.ts +0 -11
  107. package/dist/reads.d.ts.map +0 -1
  108. package/dist/reads.js +0 -91
  109. package/dist/words.d.ts +0 -19
  110. package/dist/words.d.ts.map +0 -1
  111. package/dist/words.js +0 -156
@@ -3,6 +3,7 @@ import { runtimeError } from './failure.js';
3
3
  import { refusedForSpace } from './durability.js';
4
4
  import { changeBatchIdentity, chatDraftRevision } from './identity.js';
5
5
  import { OFFLINE } from './outcome.js';
6
+ import { untilAnswered } from './recovery.js';
6
7
  import { capped, cursorOf, decodedCursor, FROM_START, messageOrder, precedes } from './windows.js';
7
8
  const QUIET = {
8
9
  turn: null,
@@ -11,6 +12,7 @@ const QUIET = {
11
12
  commands: [],
12
13
  options: [],
13
14
  starting: null,
15
+ subagents: [],
14
16
  link: null,
15
17
  deliveryUnknown: [],
16
18
  };
@@ -20,6 +22,7 @@ const FACTS = [
20
22
  'commands',
21
23
  'options',
22
24
  'starting',
25
+ 'subagents',
23
26
  'link',
24
27
  'deliveryUnknown',
25
28
  ];
@@ -33,6 +36,7 @@ export function unheldView(conversation) {
33
36
  commands: [],
34
37
  options: [],
35
38
  starting: null,
39
+ subagents: [],
36
40
  link: null,
37
41
  deliveryUnknown: [],
38
42
  chatDraft: null,
@@ -209,6 +213,14 @@ function askedOf(options) {
209
213
  }
210
214
  return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
211
215
  }
216
+ function phraseOf(text) {
217
+ if (text === undefined)
218
+ return null;
219
+ if (typeof text !== 'string' || text === '') {
220
+ throw runtimeError('invalid-text', 'a conversation is found by a phrase');
221
+ }
222
+ return text;
223
+ }
212
224
  const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
213
225
  const DURABLE_WRITE = {
214
226
  kind: 'rejected',
@@ -255,6 +267,8 @@ export function createConversationStore(deps) {
255
267
  const unsent = new Map();
256
268
  const views = new Map();
257
269
  const listing = new Map();
270
+ let relisting = null;
271
+ let listCursor = null;
258
272
  const creations = new Set();
259
273
  const listWatchers = new Set();
260
274
  const unlisted = new Set();
@@ -263,11 +277,9 @@ export function createConversationStore(deps) {
263
277
  let listKept = false;
264
278
  const agentWatchers = new Set();
265
279
  const unnamed = new Set();
266
- let agentsKnown = false;
267
- let agentNames = new Map();
268
- let retiredAgents = new Set();
269
- let agentsRead = null;
270
- let agentsFrom;
280
+ let agentsShown = null;
281
+ let listedAgents = null;
282
+ let agentsReading = false;
271
283
  let replicated = new Set();
272
284
  let handedReplicated;
273
285
  function liveOf(conversation) {
@@ -291,6 +303,7 @@ export function createConversationStore(deps) {
291
303
  commands: structuredClone(facts.commands),
292
304
  options: structuredClone(facts.options),
293
305
  starting: facts.starting,
306
+ subagents: structuredClone(facts.subagents),
294
307
  link: facts.link === null ? null : { ...facts.link },
295
308
  deliveryUnknown: [...facts.deliveryUnknown],
296
309
  chatDraft: draft === undefined || unwritten(draft)
@@ -346,7 +359,7 @@ export function createConversationStore(deps) {
346
359
  function entries() {
347
360
  return [...listing.values()].map((entry) => ({
348
361
  conversation: entry.conversation,
349
- agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
362
+ agent: { identity: entry.agent, name: entry.agentName },
350
363
  name: entry.name,
351
364
  created: entry.created,
352
365
  finished: entry.finished,
@@ -365,9 +378,19 @@ export function createConversationStore(deps) {
365
378
  if (deps.closed())
366
379
  return;
367
380
  const entries = [...listing.values()];
368
- void deps.durably((local) => local.fact('conversationList', entries)).catch(() => { });
381
+ const cursor = listCursor;
382
+ void deps
383
+ .durably(async (local) => {
384
+ await local.fact('conversationList', entries);
385
+ await local.fact('conversationCursor', cursor);
386
+ })
387
+ .catch(() => { });
369
388
  });
370
389
  }
390
+ function listed(entry) {
391
+ listing.set(entry.conversation, { ...entry });
392
+ creations.delete(entry.conversation);
393
+ }
371
394
  function emitList() {
372
395
  if (deps.closed())
373
396
  return;
@@ -376,18 +399,15 @@ export function createConversationStore(deps) {
376
399
  for (const watcher of listWatchers)
377
400
  watcher(value);
378
401
  }
402
+ emitAgents();
379
403
  learned();
380
404
  }
381
- function unlearnable() {
382
- return !deps.online() || (deps.listed() && deps.agents() === undefined);
383
- }
384
405
  function learned() {
385
406
  if (deps.closed())
386
407
  return;
387
- const named = agentsKnown || unlearnable();
388
- if (unlisted.size > 0 &&
389
- named &&
390
- (listKnown || listHeld || deps.stream() === undefined || unlearnable())) {
408
+ if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
409
+ return;
410
+ if (unlisted.size > 0) {
391
411
  const value = entries();
392
412
  for (const watcher of [...unlisted]) {
393
413
  unlisted.delete(watcher);
@@ -395,7 +415,7 @@ export function createConversationStore(deps) {
395
415
  watcher(value);
396
416
  }
397
417
  }
398
- if (unnamed.size > 0 && named) {
418
+ if (unnamed.size > 0) {
399
419
  const value = agents();
400
420
  for (const watcher of [...unnamed]) {
401
421
  unnamed.delete(watcher);
@@ -405,17 +425,44 @@ export function createConversationStore(deps) {
405
425
  }
406
426
  }
407
427
  function agents() {
408
- return [...agentNames]
409
- .filter(([identity]) => !retiredAgents.has(identity))
410
- .map(([identity, name]) => ({ identity, name }))
428
+ const named = new Map();
429
+ for (const agent of listedAgents ?? [])
430
+ named.set(agent.agent, agent);
431
+ for (const entry of listing.values()) {
432
+ named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
433
+ }
434
+ return [...named]
435
+ .filter(([, agent]) => !agent.retired)
436
+ .map(([identity, agent]) => ({ identity, name: agent.name }))
411
437
  .sort((left, right) => left.name === right.name
412
438
  ? left.identity.localeCompare(right.identity)
413
439
  : left.name.localeCompare(right.name));
414
440
  }
441
+ function readAgents() {
442
+ const stream = deps.stream();
443
+ if (stream?.agents === undefined || !deps.online() || agentsReading)
444
+ return;
445
+ agentsReading = true;
446
+ void stream
447
+ .agents()
448
+ .then((read) => {
449
+ if (read === null)
450
+ return;
451
+ listedAgents = read;
452
+ emitAgents();
453
+ }, () => { })
454
+ .finally(() => {
455
+ agentsReading = false;
456
+ });
457
+ }
415
458
  function emitAgents() {
416
459
  if (deps.closed() || agentWatchers.size === 0)
417
460
  return;
418
461
  const value = agents();
462
+ const shown = JSON.stringify(value);
463
+ if (shown === agentsShown)
464
+ return;
465
+ agentsShown = shown;
419
466
  for (const watcher of agentWatchers)
420
467
  watcher(value);
421
468
  }
@@ -431,60 +478,11 @@ export function createConversationStore(deps) {
431
478
  if (stateOf(conversation) !== before || next?.turn?.started !== began)
432
479
  emitList();
433
480
  }
434
- async function readAgents() {
435
- const declaration = deps.agents();
436
- agentsFrom = JSON.stringify(declaration);
437
- if (declaration === undefined)
438
- return;
439
- const names = new Map();
440
- const retired = new Set();
441
- let covered = null;
442
- for (let after;;) {
443
- const read = await deps.documents(declaration, after);
444
- if ('pending' in read)
445
- return;
446
- const coverage = JSON.stringify(read.coverage);
447
- if (covered !== null && coverage !== covered)
448
- return readAgents();
449
- covered = coverage;
450
- for (const document of read.documents) {
451
- const identity = document.fields?.[declaration.identity];
452
- const name = document.fields?.[declaration.name];
453
- if (typeof identity !== 'string' || typeof name !== 'string')
454
- continue;
455
- names.set(identity, name);
456
- const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
457
- if (ended !== undefined && ended !== null)
458
- retired.add(identity);
459
- }
460
- if (read.next === undefined)
461
- break;
462
- after = read.next;
463
- }
464
- agentsKnown = true;
465
- const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
466
- if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents])) {
467
- learned();
468
- return;
469
- }
470
- agentNames = names;
471
- retiredAgents = retired;
472
- emitAgents();
473
- if (named)
474
- emitList();
475
- learned();
476
- const ended = [...drafts.keys()].filter(retiredChat);
477
- if (ended.length > 0)
478
- await remove(ended);
479
- }
480
481
  function retiredChat(conversation) {
481
- return (conversation.startsWith(NEW_CHAT) && retiredAgents.has(conversation.slice(NEW_CHAT.length)));
482
- }
483
- function agentsReady() {
484
- agentsRead ??= readAgents().catch(() => {
485
- agentsRead = null;
486
- });
487
- return agentsRead;
482
+ if (!conversation.startsWith(NEW_CHAT))
483
+ return false;
484
+ const agent = conversation.slice(NEW_CHAT.length);
485
+ return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
488
486
  }
489
487
  function live(conversation, change) {
490
488
  const owed = unsent.get(conversation);
@@ -507,6 +505,7 @@ export function createConversationStore(deps) {
507
505
  commands: facts.has('commands') ? QUIET.commands : held.commands,
508
506
  options: facts.has('options') ? QUIET.options : held.options,
509
507
  starting: facts.has('starting') ? QUIET.starting : held.starting,
508
+ subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
510
509
  link: facts.has('link') ? QUIET.link : held.link,
511
510
  deliveryUnknown: facts.has('deliveryUnknown')
512
511
  ? QUIET.deliveryUnknown
@@ -560,6 +559,20 @@ export function createConversationStore(deps) {
560
559
  deps.publish(conversationChangeSet(changed));
561
560
  });
562
561
  }
562
+ function missed(conversation) {
563
+ const read = reads.get(conversation);
564
+ const newest = listing.get(conversation)?.newest;
565
+ return (read === undefined ||
566
+ newest === undefined ||
567
+ partials.has(conversation) ||
568
+ (newest !== null && (read === null || newest > read)));
569
+ }
570
+ function noted(conversation, message) {
571
+ const entry = listing.get(conversation);
572
+ if (entry === undefined || (entry.newest !== null && entry.newest >= message.position))
573
+ return;
574
+ listing.set(conversation, { ...entry, newest: message.position });
575
+ }
563
576
  function gap(conversation) {
564
577
  gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
565
578
  behind.add(conversation);
@@ -594,7 +607,7 @@ export function createConversationStore(deps) {
594
607
  }));
595
608
  while (waiting.length > 0) {
596
609
  const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
597
- const result = await deps.call('conversation.history', {
610
+ const result = await deps.history({
598
611
  conversations: asking.map(({ conversation, after }) => ({
599
612
  conversation,
600
613
  ...(after === undefined ? {} : { after }),
@@ -697,6 +710,10 @@ export function createConversationStore(deps) {
697
710
  live(conversation, { starting: event.step });
698
711
  return;
699
712
  }
713
+ if (event.kind === 'subagents') {
714
+ live(conversation, { subagents: structuredClone(event.subagents) });
715
+ return;
716
+ }
700
717
  if (event.kind === 'link') {
701
718
  live(conversation, { link: { connected: event.connected } });
702
719
  return;
@@ -708,6 +725,7 @@ export function createConversationStore(deps) {
708
725
  const arriving = acceptedMessage(event.message);
709
726
  if (arriving === null)
710
727
  return;
728
+ noted(conversation, arriving);
711
729
  if (replicated.has(conversation)) {
712
730
  if (deps.full()) {
713
731
  gap(conversation);
@@ -804,9 +822,9 @@ export function createConversationStore(deps) {
804
822
  const dispatch = { answered: false };
805
823
  sending.set(submission.operation, dispatch);
806
824
  try {
807
- const result = await invoke('conversation.send', conversation, {
808
- text: submission.text,
825
+ const result = await invoke('conversations/send', conversation, {
809
826
  operation_id: submission.operation,
827
+ text: submission.text,
810
828
  });
811
829
  dispatch.answered = result.kind !== 'transport-uncertainty';
812
830
  if (result.kind === 'revoked-authorization')
@@ -815,7 +833,7 @@ export function createConversationStore(deps) {
815
833
  deps.unanswered();
816
834
  return result;
817
835
  }
818
- const turn = answered(result, 'turn');
836
+ const turn = answered(result, 'message_id');
819
837
  await withDraft(conversation, async (current, local) => {
820
838
  const held = current?.submitted?.find((one) => one.operation === submission.operation);
821
839
  if (current === undefined || held === undefined || held.turn !== null)
@@ -835,12 +853,11 @@ export function createConversationStore(deps) {
835
853
  sending.delete(submission.operation);
836
854
  }
837
855
  }
838
- function invoke(name, conversation, extra = {}) {
839
- return deps.call(name, { conversation, ...extra });
856
+ function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
857
+ return deps.call(name, { conversation_id: conversation, ...extra });
840
858
  }
841
859
  const surface = {
842
- async list() {
843
- await agentsReady();
860
+ list() {
844
861
  return new Promise((settle) => {
845
862
  const answer = (listed) => {
846
863
  unlisted.delete(answer);
@@ -852,16 +869,18 @@ export function createConversationStore(deps) {
852
869
  });
853
870
  },
854
871
  async read(conversation, options = {}) {
855
- const asked = askedOf(options);
872
+ const { text, ...windowed } = options;
873
+ const asked = askedOf(windowed);
874
+ const phrase = phraseOf(text);
856
875
  return deps.durably(async (local) => {
857
- const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
858
- const total = asked.total ? await local.messageCount(conversation) : null;
876
+ const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
877
+ const total = asked.total ? await local.messageCount(conversation, phrase) : null;
859
878
  return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
860
879
  });
861
880
  },
862
881
  async create(input) {
863
- const result = await deps.call('conversation.create', input);
864
- const conversation = answered(result, 'conversation');
882
+ const result = await deps.call('conversations/create', input);
883
+ const conversation = answered(result, 'conversation_id');
865
884
  if (conversation === null)
866
885
  return result;
867
886
  if (!listing.has(conversation))
@@ -896,28 +915,19 @@ export function createConversationStore(deps) {
896
915
  return OFFLINE;
897
916
  },
898
917
  answer(conversation, answer) {
899
- return invoke('conversation.answer', conversation, { answer });
918
+ return invoke('conversations/interaction/answer', conversation, {
919
+ operation_id: changeBatchIdentity(),
920
+ ...answer,
921
+ });
900
922
  },
901
923
  interrupt(conversation) {
902
- return invoke('conversation.interrupt', conversation);
924
+ return invoke('conversations/interrupt', conversation);
903
925
  },
904
926
  kill(conversation) {
905
- return invoke('conversation.kill', conversation);
906
- },
907
- async cancel(conversation, turn) {
908
- const result = await invoke('conversation.cancel', conversation, { turn });
909
- if (result.kind !== 'action')
910
- return result;
911
- await withDraft(conversation, (current) => {
912
- const held = current?.submitted?.find((one) => one.turn === turn);
913
- if (current === undefined || held === undefined)
914
- return undefined;
915
- return returned(current, held, current.submitted.filter((one) => one !== held));
916
- });
917
- return result;
927
+ return invoke('conversations/kill', conversation);
918
928
  },
919
929
  delete(conversation) {
920
- return invoke('conversation.delete', conversation);
930
+ return invoke('conversations/delete', conversation);
921
931
  },
922
932
  };
923
933
  const chatDraft = {
@@ -946,12 +956,14 @@ export function createConversationStore(deps) {
946
956
  return {
947
957
  surface,
948
958
  chatDraft,
949
- hydrate(held, kept, list) {
959
+ hydrate(held, kept, list, cursor) {
950
960
  if (list !== null && !listKnown) {
951
961
  listing.clear();
952
962
  for (const entry of list)
953
963
  listing.set(entry.conversation, { ...entry });
954
964
  listHeld = true;
965
+ listCursor = cursor;
966
+ deps.stream()?.hold(cursor);
955
967
  }
956
968
  stored.clear();
957
969
  reads.clear();
@@ -979,7 +991,7 @@ export function createConversationStore(deps) {
979
991
  !creations.has(conversation) &&
980
992
  (!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
981
993
  for (const conversation of named) {
982
- if (!replicated.has(conversation))
994
+ if (!replicated.has(conversation) && missed(conversation))
983
995
  behind.add(conversation);
984
996
  }
985
997
  replicated = named;
@@ -1041,11 +1053,8 @@ export function createConversationStore(deps) {
1041
1053
  known() {
1042
1054
  return listKnown;
1043
1055
  },
1044
- reconnected() {
1045
- for (const conversation of replicated)
1046
- gap(conversation);
1047
- },
1048
1056
  reopened() {
1057
+ relisting = null;
1049
1058
  for (const [operation, dispatch] of sending)
1050
1059
  if (!dispatch.answered)
1051
1060
  sending.delete(operation);
@@ -1067,15 +1076,15 @@ export function createConversationStore(deps) {
1067
1076
  views.set(key, view);
1068
1077
  const watcher = { notify: deliver, ready: false };
1069
1078
  view.watchers.add(watcher);
1070
- void deps
1071
- .durably(async (local) => {
1079
+ const reading = new AbortController();
1080
+ void untilAnswered(() => deps.durably(async (local) => {
1072
1081
  if (view.window !== null)
1073
1082
  return;
1074
1083
  const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
1075
1084
  view.window = messages;
1076
1085
  view.more = more;
1077
1086
  view.total = asked.total ? await local.messageCount(conversation) : null;
1078
- })
1087
+ }), reading.signal)
1079
1088
  .then(() => {
1080
1089
  if (deps.closed() || !view.watchers.has(watcher))
1081
1090
  return;
@@ -1085,6 +1094,7 @@ export function createConversationStore(deps) {
1085
1094
  })
1086
1095
  .catch(() => { });
1087
1096
  return () => {
1097
+ reading.abort();
1088
1098
  if (!view.watchers.delete(watcher))
1089
1099
  return;
1090
1100
  if (view.watchers.size === 0)
@@ -1092,82 +1102,80 @@ export function createConversationStore(deps) {
1092
1102
  };
1093
1103
  },
1094
1104
  watchList(deliver) {
1095
- let ended = false;
1096
- void agentsReady().then(() => {
1097
- if (ended)
1098
- return;
1099
- unlisted.add(deliver);
1100
- learned();
1101
- });
1105
+ unlisted.add(deliver);
1106
+ learned();
1102
1107
  return () => {
1103
- ended = true;
1104
1108
  unlisted.delete(deliver);
1105
1109
  listWatchers.delete(deliver);
1106
1110
  };
1107
1111
  },
1108
1112
  watchAgents(deliver) {
1109
1113
  unnamed.add(deliver);
1110
- void agentsReady().then(learned);
1114
+ learned();
1115
+ readAgents();
1111
1116
  return () => {
1112
1117
  unnamed.delete(deliver);
1113
1118
  agentWatchers.delete(deliver);
1114
1119
  };
1115
1120
  },
1116
1121
  learned,
1117
- declared() {
1118
- if (JSON.stringify(deps.agents()) === agentsFrom)
1119
- return;
1120
- agentsRead = readAgents().catch(() => {
1121
- agentsRead = null;
1122
- });
1123
- },
1124
1122
  changed(set) {
1125
1123
  for (const conversation of set.conversations)
1126
1124
  emit(conversation);
1127
- const declaration = deps.agents();
1128
- if (declaration !== undefined &&
1129
- set.documents.some((change) => change.locator === declaration.locator)) {
1130
- agentsRead = readAgents().catch(() => {
1131
- agentsRead = null;
1132
- });
1133
- }
1134
1125
  },
1135
1126
  receive(event) {
1136
1127
  if (deps.closed())
1137
1128
  return false;
1138
1129
  if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
1139
1130
  if (event.kind === 'list') {
1140
- listing.clear();
1131
+ if (event.whole)
1132
+ relisting ??= new Map();
1141
1133
  for (const entry of event.entries) {
1142
- listing.set(entry.conversation, { ...entry });
1143
- creations.delete(entry.conversation);
1134
+ if (relisting === null)
1135
+ listed(entry);
1136
+ else
1137
+ relisting.set(entry.conversation, { ...entry });
1144
1138
  }
1139
+ if (event.more)
1140
+ return false;
1141
+ if (relisting !== null) {
1142
+ listing.clear();
1143
+ for (const entry of relisting.values())
1144
+ listed(entry);
1145
+ relisting = null;
1146
+ }
1147
+ listCursor = event.cursor;
1148
+ deps.stream()?.hold(event.cursor);
1145
1149
  listKnown = true;
1150
+ for (const conversation of replicated) {
1151
+ if (!listing.has(conversation))
1152
+ continue;
1153
+ if (!missed(conversation))
1154
+ behind.delete(conversation);
1155
+ else if (!behind.has(conversation))
1156
+ gap(conversation);
1157
+ }
1146
1158
  openingEnded();
1147
1159
  }
1148
1160
  else if (event.kind === 'listed') {
1149
- listing.set(event.entry.conversation, { ...event.entry });
1150
- creations.delete(event.entry.conversation);
1161
+ listed(event.entry);
1162
+ relisting?.set(event.entry.conversation, { ...event.entry });
1151
1163
  }
1152
1164
  else {
1153
1165
  listing.delete(event.conversation);
1166
+ relisting?.delete(event.conversation);
1154
1167
  }
1155
1168
  keepList();
1156
1169
  emitList();
1157
- return (event.kind !== 'list' &&
1170
+ return ((event.kind !== 'list' &&
1158
1171
  listKnown &&
1159
1172
  (listing.size !== replicated.size ||
1160
- [...listing.keys()].some((conversation) => !replicated.has(conversation))));
1173
+ [...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
1174
+ (listKnown && [...drafts.keys()].some(retiredChat)));
1161
1175
  }
1162
1176
  heard(event);
1163
1177
  return false;
1164
1178
  },
1165
- searchable() {
1166
- return [...(listKnown ? listing.keys() : stored)].sort();
1167
- },
1168
- acquired(conversation) {
1169
- return reads.has(conversation) && !partials.has(conversation);
1170
- },
1171
1179
  close() {
1172
1180
  views.clear();
1173
1181
  lives.clear();
@@ -2,7 +2,6 @@ import type { Persistence } from './readiness.js';
2
2
  export type RuntimeShell = {
3
3
  persistence: Persistence;
4
4
  generation: string | null;
5
- onScreen: boolean;
6
5
  keepGeneration(value: string): void | Promise<void>;
7
6
  dropGeneration(): void | Promise<void>;
8
7
  cleanUp?(): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAkCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAmDZ"}
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAkCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAoDZ"}
package/dist/entry.js CHANGED
@@ -129,6 +129,7 @@ export function entryScope(rooms, roomTypes, connection) {
129
129
  .map((path) => ({
130
130
  path,
131
131
  content: room.documents[path],
132
+ outline: null,
132
133
  binary: null,
133
134
  revision: room.revisions?.[path] ?? null,
134
135
  fileId: null,
package/dist/host.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type MdRuntimeOptions } from './connection.js';
2
2
  import type { PortReach } from './reach.js';
3
- import type { CodeAvailability, Persistence, Readiness, SearchObligation, Space } from './readiness.js';
3
+ import type { CodeAvailability, Persistence, Readiness, Space } from './readiness.js';
4
4
  import type { EntrySeed } from './seed.js';
5
5
  import { type RuntimePort } from './wire.js';
6
6
  export type MdRuntimeHostOptions = MdRuntimeOptions & {
@@ -12,21 +12,18 @@ export type AttachedPort = {
12
12
  readiness(deliver: (readiness: Readiness) => void): () => void;
13
13
  answered(queries: readonly unknown[], done: () => void): void;
14
14
  code(code: CodeAvailability, space: Space | null): void;
15
- search(search: SearchObligation): void;
16
15
  };
17
16
  export type MdRuntimeHost = {
18
- attach(port: RuntimePort, app: string, release?: string, reach?: PortReach, code?: CodeAvailability, search?: SearchObligation): AttachedPort;
17
+ attach(port: RuntimePort, app: string, release?: string, reach?: PortReach, code?: CodeAvailability): AttachedPort;
19
18
  seed(entry: EntrySeed): void;
20
19
  persisted(answer: Persistence): void;
21
- shown(onScreen: boolean): void;
22
20
  endAuthorization(holder?: string): Promise<void>;
23
- lose(locators: readonly string[]): Promise<void>;
24
21
  stop(): Promise<void>;
25
22
  };
26
23
  export declare function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost;
27
24
  export { entrySeedOf, type EntrySeed } from './seed.js';
28
25
  export type { PortReach, ReachedDocument } from './reach.js';
29
- export type { CodeAvailability, Persistence, SearchObligation, Space } from './readiness.js';
26
+ export type { CodeAvailability, Persistence, Space } from './readiness.js';
30
27
  export { createRecovery, retryDelay, type Attempt, type Attempted, type AttemptOptions, type Recovery, type RecoveryOptions, } from './recovery.js';
31
28
  export type { RuntimePort } from './wire.js';
32
29
  //# sourceMappingURL=host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EAItB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,KAAK,EACN,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAGL,KAAK,WAAW,EAOjB,MAAM,WAAW,CAAC;AAInB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IACxD,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CACJ,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE,gBAAgB,EACvB,MAAM,CAAC,EAAE,gBAAgB,GACxB,YAAY,CAAC;IAChB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAsIF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAuL3E;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EACL,cAAc,EACd,UAAU,EACV,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EAItB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAGL,KAAK,WAAW,EAOjB,MAAM,WAAW,CAAC;AAInB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CACJ,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE,gBAAgB,GACtB,YAAY,CAAC;IAChB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAoIF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA8K3E;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,UAAU,EACV,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}