@agentshouse/mdruntime 0.1.0-cb122f2ba154d → 0.1.0-cb1f56e16291b

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 (121) 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 +61 -43
  16. package/dist/connection.d.ts +3 -5
  17. package/dist/connection.d.ts.map +1 -1
  18. package/dist/connection.js +900 -861
  19. package/dist/context.d.ts +2 -0
  20. package/dist/context.d.ts.map +1 -0
  21. package/dist/context.js +7 -0
  22. package/dist/conversation.d.ts +15 -13
  23. package/dist/conversation.d.ts.map +1 -1
  24. package/dist/conversation.js +136 -144
  25. package/dist/durability.d.ts +0 -1
  26. package/dist/durability.d.ts.map +1 -1
  27. package/dist/entry.d.ts.map +1 -1
  28. package/dist/entry.js +1 -0
  29. package/dist/host.d.ts +3 -6
  30. package/dist/host.d.ts.map +1 -1
  31. package/dist/host.js +17 -19
  32. package/dist/index.d.ts +8 -5
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -1
  35. package/dist/job.d.ts +14 -0
  36. package/dist/job.d.ts.map +1 -0
  37. package/dist/job.js +28 -0
  38. package/dist/live.d.ts +2 -1
  39. package/dist/live.d.ts.map +1 -1
  40. package/dist/live.js +10 -7
  41. package/dist/media.d.ts +1 -1
  42. package/dist/media.d.ts.map +1 -1
  43. package/dist/media.js +19 -9
  44. package/dist/memory.d.ts +8 -4
  45. package/dist/memory.d.ts.map +1 -1
  46. package/dist/memory.js +131 -81
  47. package/dist/messages.d.ts +2 -2
  48. package/dist/messages.d.ts.map +1 -1
  49. package/dist/messages.js +15 -16
  50. package/dist/model.d.ts +0 -1
  51. package/dist/model.d.ts.map +1 -1
  52. package/dist/model.js +0 -9
  53. package/dist/observation.d.ts +2 -2
  54. package/dist/observation.d.ts.map +1 -1
  55. package/dist/observation.js +7 -2
  56. package/dist/outcome.d.ts +0 -3
  57. package/dist/outcome.d.ts.map +1 -1
  58. package/dist/phrase.d.ts +3 -0
  59. package/dist/phrase.d.ts.map +1 -0
  60. package/dist/phrase.js +8 -0
  61. package/dist/query.d.ts +5 -1
  62. package/dist/query.d.ts.map +1 -1
  63. package/dist/query.js +20 -1
  64. package/dist/reach.d.ts +6 -5
  65. package/dist/reach.d.ts.map +1 -1
  66. package/dist/reach.js +30 -37
  67. package/dist/react.d.ts +1 -0
  68. package/dist/react.d.ts.map +1 -1
  69. package/dist/readiness.d.ts +2 -15
  70. package/dist/readiness.d.ts.map +1 -1
  71. package/dist/readiness.js +4 -10
  72. package/dist/recovery.d.ts +1 -0
  73. package/dist/recovery.d.ts.map +1 -1
  74. package/dist/recovery.js +26 -0
  75. package/dist/refresh.d.ts +7 -5
  76. package/dist/refresh.d.ts.map +1 -1
  77. package/dist/refresh.js +46 -6
  78. package/dist/replica.d.ts +0 -1
  79. package/dist/replica.d.ts.map +1 -1
  80. package/dist/replica.js +3 -4
  81. package/dist/room-draft.d.ts +2 -1
  82. package/dist/room-draft.d.ts.map +1 -1
  83. package/dist/room-draft.js +65 -52
  84. package/dist/rows.d.ts +3 -2
  85. package/dist/rows.d.ts.map +1 -1
  86. package/dist/rows.js +34 -29
  87. package/dist/search.d.ts +12 -63
  88. package/dist/search.d.ts.map +1 -1
  89. package/dist/search.js +9 -52
  90. package/dist/shared.d.ts +0 -1
  91. package/dist/shared.d.ts.map +1 -1
  92. package/dist/shared.js +0 -10
  93. package/dist/status.d.ts +0 -4
  94. package/dist/status.d.ts.map +1 -1
  95. package/dist/store.d.ts +15 -19
  96. package/dist/store.d.ts.map +1 -1
  97. package/dist/store.js +40 -39
  98. package/dist/stored.d.ts +33 -6
  99. package/dist/stored.d.ts.map +1 -1
  100. package/dist/stored.js +92 -111
  101. package/dist/tables.d.ts +34 -33
  102. package/dist/tables.d.ts.map +1 -1
  103. package/dist/tables.js +18 -54
  104. package/dist/transfer.d.ts +0 -5
  105. package/dist/transfer.d.ts.map +1 -1
  106. package/dist/validation.d.ts +3 -4
  107. package/dist/validation.d.ts.map +1 -1
  108. package/dist/validation.js +35 -96
  109. package/dist/wire.d.ts +1 -4
  110. package/dist/wire.d.ts.map +1 -1
  111. package/dist/wire.js +1 -1
  112. package/package.json +2 -2
  113. package/dist/fulltext.d.ts +0 -27
  114. package/dist/fulltext.d.ts.map +0 -1
  115. package/dist/fulltext.js +0 -370
  116. package/dist/reads.d.ts +0 -11
  117. package/dist/reads.d.ts.map +0 -1
  118. package/dist/reads.js +0 -91
  119. package/dist/words.d.ts +0 -19
  120. package/dist/words.d.ts.map +0 -1
  121. 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
  ];
@@ -30,9 +33,11 @@ export function unheldView(conversation) {
30
33
  turn: null,
31
34
  questions: [],
32
35
  process: null,
36
+ processEnded: null,
33
37
  commands: [],
34
38
  options: [],
35
39
  starting: null,
40
+ subagents: [],
36
41
  link: null,
37
42
  deliveryUnknown: [],
38
43
  chatDraft: null,
@@ -47,10 +52,8 @@ export function newChat(agent) {
47
52
  function creationOf(input) {
48
53
  if (typeof input !== 'object' || input === null)
49
54
  return null;
50
- const { agent_id: agent, operation_id: operation, replaces, } = input;
51
- return typeof agent === 'string' && typeof operation === 'string' && replaces === undefined
52
- ? { agent, operation }
53
- : null;
55
+ const { agent_id: agent, operation_id: operation } = input;
56
+ return typeof agent === 'string' && typeof operation === 'string' ? { agent, operation } : null;
54
57
  }
55
58
  function startedTurn(turn, operation) {
56
59
  if (operation.op === 'begin')
@@ -209,6 +212,14 @@ function askedOf(options) {
209
212
  }
210
213
  return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
211
214
  }
215
+ function phraseOf(text) {
216
+ if (text === undefined)
217
+ return null;
218
+ if (typeof text !== 'string' || text === '') {
219
+ throw runtimeError('invalid-text', 'a conversation is found by a phrase');
220
+ }
221
+ return text;
222
+ }
212
223
  const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
213
224
  const DURABLE_WRITE = {
214
225
  kind: 'rejected',
@@ -255,6 +266,8 @@ export function createConversationStore(deps) {
255
266
  const unsent = new Map();
256
267
  const views = new Map();
257
268
  const listing = new Map();
269
+ let relisting = null;
270
+ let listCursor = null;
258
271
  const creations = new Set();
259
272
  const listWatchers = new Set();
260
273
  const unlisted = new Set();
@@ -263,11 +276,9 @@ export function createConversationStore(deps) {
263
276
  let listKept = false;
264
277
  const agentWatchers = new Set();
265
278
  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;
279
+ let agentsShown = null;
280
+ let listedAgents = null;
281
+ let agentsReading = false;
271
282
  let replicated = new Set();
272
283
  let handedReplicated;
273
284
  function liveOf(conversation) {
@@ -288,9 +299,11 @@ export function createConversationStore(deps) {
288
299
  turn: structuredClone(facts.turn),
289
300
  questions: structuredClone(facts.questions),
290
301
  process: facts.process === null ? null : { ...facts.process },
302
+ processEnded: listing.get(conversation)?.processEnded ?? null,
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,22 @@ 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
+ const ended = listing.get(entry.conversation)?.processEnded ?? null;
392
+ listing.set(entry.conversation, { ...entry });
393
+ creations.delete(entry.conversation);
394
+ if (entry.processEnded !== ended)
395
+ emit(entry.conversation);
396
+ }
371
397
  function emitList() {
372
398
  if (deps.closed())
373
399
  return;
@@ -376,18 +402,15 @@ export function createConversationStore(deps) {
376
402
  for (const watcher of listWatchers)
377
403
  watcher(value);
378
404
  }
405
+ emitAgents();
379
406
  learned();
380
407
  }
381
- function unlearnable() {
382
- return !deps.online() || (deps.listed() && deps.agents() === undefined);
383
- }
384
408
  function learned() {
385
409
  if (deps.closed())
386
410
  return;
387
- const named = agentsKnown || unlearnable();
388
- if (unlisted.size > 0 &&
389
- named &&
390
- (listKnown || listHeld || deps.stream() === undefined || unlearnable())) {
411
+ if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
412
+ return;
413
+ if (unlisted.size > 0) {
391
414
  const value = entries();
392
415
  for (const watcher of [...unlisted]) {
393
416
  unlisted.delete(watcher);
@@ -395,7 +418,7 @@ export function createConversationStore(deps) {
395
418
  watcher(value);
396
419
  }
397
420
  }
398
- if (unnamed.size > 0 && named) {
421
+ if (unnamed.size > 0) {
399
422
  const value = agents();
400
423
  for (const watcher of [...unnamed]) {
401
424
  unnamed.delete(watcher);
@@ -405,17 +428,44 @@ export function createConversationStore(deps) {
405
428
  }
406
429
  }
407
430
  function agents() {
408
- return [...agentNames]
409
- .filter(([identity]) => !retiredAgents.has(identity))
410
- .map(([identity, name]) => ({ identity, name }))
431
+ const named = new Map();
432
+ for (const agent of listedAgents ?? [])
433
+ named.set(agent.agent, agent);
434
+ for (const entry of listing.values()) {
435
+ named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
436
+ }
437
+ return [...named]
438
+ .filter(([, agent]) => !agent.retired)
439
+ .map(([identity, agent]) => ({ identity, name: agent.name }))
411
440
  .sort((left, right) => left.name === right.name
412
441
  ? left.identity.localeCompare(right.identity)
413
442
  : left.name.localeCompare(right.name));
414
443
  }
444
+ function readAgents() {
445
+ const stream = deps.stream();
446
+ if (stream?.agents === undefined || !deps.online() || agentsReading)
447
+ return;
448
+ agentsReading = true;
449
+ void stream
450
+ .agents()
451
+ .then((read) => {
452
+ if (read === null)
453
+ return;
454
+ listedAgents = read;
455
+ emitAgents();
456
+ }, () => { })
457
+ .finally(() => {
458
+ agentsReading = false;
459
+ });
460
+ }
415
461
  function emitAgents() {
416
462
  if (deps.closed() || agentWatchers.size === 0)
417
463
  return;
418
464
  const value = agents();
465
+ const shown = JSON.stringify(value);
466
+ if (shown === agentsShown)
467
+ return;
468
+ agentsShown = shown;
419
469
  for (const watcher of agentWatchers)
420
470
  watcher(value);
421
471
  }
@@ -431,60 +481,11 @@ export function createConversationStore(deps) {
431
481
  if (stateOf(conversation) !== before || next?.turn?.started !== began)
432
482
  emitList();
433
483
  }
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
484
  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;
485
+ if (!conversation.startsWith(NEW_CHAT))
486
+ return false;
487
+ const agent = conversation.slice(NEW_CHAT.length);
488
+ return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
488
489
  }
489
490
  function live(conversation, change) {
490
491
  const owed = unsent.get(conversation);
@@ -507,6 +508,7 @@ export function createConversationStore(deps) {
507
508
  commands: facts.has('commands') ? QUIET.commands : held.commands,
508
509
  options: facts.has('options') ? QUIET.options : held.options,
509
510
  starting: facts.has('starting') ? QUIET.starting : held.starting,
511
+ subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
510
512
  link: facts.has('link') ? QUIET.link : held.link,
511
513
  deliveryUnknown: facts.has('deliveryUnknown')
512
514
  ? QUIET.deliveryUnknown
@@ -608,7 +610,7 @@ export function createConversationStore(deps) {
608
610
  }));
609
611
  while (waiting.length > 0) {
610
612
  const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
611
- const result = await deps.call('conversation.history', {
613
+ const result = await deps.history({
612
614
  conversations: asking.map(({ conversation, after }) => ({
613
615
  conversation,
614
616
  ...(after === undefined ? {} : { after }),
@@ -711,6 +713,10 @@ export function createConversationStore(deps) {
711
713
  live(conversation, { starting: event.step });
712
714
  return;
713
715
  }
716
+ if (event.kind === 'subagents') {
717
+ live(conversation, { subagents: structuredClone(event.subagents) });
718
+ return;
719
+ }
714
720
  if (event.kind === 'link') {
715
721
  live(conversation, { link: { connected: event.connected } });
716
722
  return;
@@ -819,9 +825,9 @@ export function createConversationStore(deps) {
819
825
  const dispatch = { answered: false };
820
826
  sending.set(submission.operation, dispatch);
821
827
  try {
822
- const result = await invoke('conversation.send', conversation, {
823
- text: submission.text,
828
+ const result = await invoke('conversations/send', conversation, {
824
829
  operation_id: submission.operation,
830
+ text: submission.text,
825
831
  });
826
832
  dispatch.answered = result.kind !== 'transport-uncertainty';
827
833
  if (result.kind === 'revoked-authorization')
@@ -830,7 +836,7 @@ export function createConversationStore(deps) {
830
836
  deps.unanswered();
831
837
  return result;
832
838
  }
833
- const turn = answered(result, 'turn');
839
+ const turn = answered(result, 'message_id');
834
840
  await withDraft(conversation, async (current, local) => {
835
841
  const held = current?.submitted?.find((one) => one.operation === submission.operation);
836
842
  if (current === undefined || held === undefined || held.turn !== null)
@@ -850,12 +856,11 @@ export function createConversationStore(deps) {
850
856
  sending.delete(submission.operation);
851
857
  }
852
858
  }
853
- function invoke(name, conversation, extra = {}) {
854
- return deps.call(name, { conversation, ...extra });
859
+ function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
860
+ return deps.call(name, { conversation_id: conversation, ...extra });
855
861
  }
856
862
  const surface = {
857
- async list() {
858
- await agentsReady();
863
+ list() {
859
864
  return new Promise((settle) => {
860
865
  const answer = (listed) => {
861
866
  unlisted.delete(answer);
@@ -867,16 +872,18 @@ export function createConversationStore(deps) {
867
872
  });
868
873
  },
869
874
  async read(conversation, options = {}) {
870
- const asked = askedOf(options);
875
+ const { text, ...windowed } = options;
876
+ const asked = askedOf(windowed);
877
+ const phrase = phraseOf(text);
871
878
  return deps.durably(async (local) => {
872
- const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
873
- const total = asked.total ? await local.messageCount(conversation) : null;
879
+ const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
880
+ const total = asked.total ? await local.messageCount(conversation, phrase) : null;
874
881
  return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
875
882
  });
876
883
  },
877
884
  async create(input) {
878
- const result = await deps.call('conversation.create', input);
879
- const conversation = answered(result, 'conversation');
885
+ const result = await deps.call('conversations/create', input);
886
+ const conversation = answered(result, 'conversation_id');
880
887
  if (conversation === null)
881
888
  return result;
882
889
  if (!listing.has(conversation))
@@ -911,28 +918,19 @@ export function createConversationStore(deps) {
911
918
  return OFFLINE;
912
919
  },
913
920
  answer(conversation, answer) {
914
- return invoke('conversation.answer', conversation, { answer });
921
+ return invoke('conversations/interaction/answer', conversation, {
922
+ operation_id: changeBatchIdentity(),
923
+ ...answer,
924
+ });
915
925
  },
916
926
  interrupt(conversation) {
917
- return invoke('conversation.interrupt', conversation);
927
+ return invoke('conversations/interrupt', conversation);
918
928
  },
919
929
  kill(conversation) {
920
- return invoke('conversation.kill', conversation);
921
- },
922
- async cancel(conversation, turn) {
923
- const result = await invoke('conversation.cancel', conversation, { turn });
924
- if (result.kind !== 'action')
925
- return result;
926
- await withDraft(conversation, (current) => {
927
- const held = current?.submitted?.find((one) => one.turn === turn);
928
- if (current === undefined || held === undefined)
929
- return undefined;
930
- return returned(current, held, current.submitted.filter((one) => one !== held));
931
- });
932
- return result;
930
+ return invoke('conversations/kill', conversation);
933
931
  },
934
932
  delete(conversation) {
935
- return invoke('conversation.delete', conversation);
933
+ return invoke('conversations/delete', conversation);
936
934
  },
937
935
  };
938
936
  const chatDraft = {
@@ -961,12 +959,14 @@ export function createConversationStore(deps) {
961
959
  return {
962
960
  surface,
963
961
  chatDraft,
964
- hydrate(held, kept, list) {
962
+ hydrate(held, kept, list, cursor) {
965
963
  if (list !== null && !listKnown) {
966
964
  listing.clear();
967
965
  for (const entry of list)
968
966
  listing.set(entry.conversation, { ...entry });
969
967
  listHeld = true;
968
+ listCursor = cursor;
969
+ deps.stream()?.hold(cursor);
970
970
  }
971
971
  stored.clear();
972
972
  reads.clear();
@@ -1057,6 +1057,7 @@ export function createConversationStore(deps) {
1057
1057
  return listKnown;
1058
1058
  },
1059
1059
  reopened() {
1060
+ relisting = null;
1060
1061
  for (const [operation, dispatch] of sending)
1061
1062
  if (!dispatch.answered)
1062
1063
  sending.delete(operation);
@@ -1078,15 +1079,15 @@ export function createConversationStore(deps) {
1078
1079
  views.set(key, view);
1079
1080
  const watcher = { notify: deliver, ready: false };
1080
1081
  view.watchers.add(watcher);
1081
- void deps
1082
- .durably(async (local) => {
1082
+ const reading = new AbortController();
1083
+ void untilAnswered(() => deps.durably(async (local) => {
1083
1084
  if (view.window !== null)
1084
1085
  return;
1085
1086
  const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
1086
1087
  view.window = messages;
1087
1088
  view.more = more;
1088
1089
  view.total = asked.total ? await local.messageCount(conversation) : null;
1089
- })
1090
+ }), reading.signal)
1090
1091
  .then(() => {
1091
1092
  if (deps.closed() || !view.watchers.has(watcher))
1092
1093
  return;
@@ -1096,6 +1097,7 @@ export function createConversationStore(deps) {
1096
1097
  })
1097
1098
  .catch(() => { });
1098
1099
  return () => {
1100
+ reading.abort();
1099
1101
  if (!view.watchers.delete(watcher))
1100
1102
  return;
1101
1103
  if (view.watchers.size === 0)
@@ -1103,56 +1105,50 @@ export function createConversationStore(deps) {
1103
1105
  };
1104
1106
  },
1105
1107
  watchList(deliver) {
1106
- let ended = false;
1107
- void agentsReady().then(() => {
1108
- if (ended)
1109
- return;
1110
- unlisted.add(deliver);
1111
- learned();
1112
- });
1108
+ unlisted.add(deliver);
1109
+ learned();
1113
1110
  return () => {
1114
- ended = true;
1115
1111
  unlisted.delete(deliver);
1116
1112
  listWatchers.delete(deliver);
1117
1113
  };
1118
1114
  },
1119
1115
  watchAgents(deliver) {
1120
1116
  unnamed.add(deliver);
1121
- void agentsReady().then(learned);
1117
+ learned();
1118
+ readAgents();
1122
1119
  return () => {
1123
1120
  unnamed.delete(deliver);
1124
1121
  agentWatchers.delete(deliver);
1125
1122
  };
1126
1123
  },
1127
1124
  learned,
1128
- declared() {
1129
- if (JSON.stringify(deps.agents()) === agentsFrom)
1130
- return;
1131
- agentsRead = readAgents().catch(() => {
1132
- agentsRead = null;
1133
- });
1134
- },
1135
1125
  changed(set) {
1136
1126
  for (const conversation of set.conversations)
1137
1127
  emit(conversation);
1138
- const declaration = deps.agents();
1139
- if (declaration !== undefined &&
1140
- set.documents.some((change) => change.locator === declaration.locator)) {
1141
- agentsRead = readAgents().catch(() => {
1142
- agentsRead = null;
1143
- });
1144
- }
1145
1128
  },
1146
1129
  receive(event) {
1147
1130
  if (deps.closed())
1148
1131
  return false;
1149
1132
  if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
1150
1133
  if (event.kind === 'list') {
1151
- listing.clear();
1134
+ if (event.whole)
1135
+ relisting ??= new Map();
1152
1136
  for (const entry of event.entries) {
1153
- listing.set(entry.conversation, { ...entry });
1154
- creations.delete(entry.conversation);
1137
+ if (relisting === null)
1138
+ listed(entry);
1139
+ else
1140
+ relisting.set(entry.conversation, { ...entry });
1155
1141
  }
1142
+ if (event.more)
1143
+ return false;
1144
+ if (relisting !== null) {
1145
+ listing.clear();
1146
+ for (const entry of relisting.values())
1147
+ listed(entry);
1148
+ relisting = null;
1149
+ }
1150
+ listCursor = event.cursor;
1151
+ deps.stream()?.hold(event.cursor);
1156
1152
  listKnown = true;
1157
1153
  for (const conversation of replicated) {
1158
1154
  if (!listing.has(conversation))
@@ -1165,28 +1161,24 @@ export function createConversationStore(deps) {
1165
1161
  openingEnded();
1166
1162
  }
1167
1163
  else if (event.kind === 'listed') {
1168
- listing.set(event.entry.conversation, { ...event.entry });
1169
- creations.delete(event.entry.conversation);
1164
+ listed(event.entry);
1165
+ relisting?.set(event.entry.conversation, { ...event.entry });
1170
1166
  }
1171
1167
  else {
1172
1168
  listing.delete(event.conversation);
1169
+ relisting?.delete(event.conversation);
1173
1170
  }
1174
1171
  keepList();
1175
1172
  emitList();
1176
- return (event.kind !== 'list' &&
1173
+ return ((event.kind !== 'list' &&
1177
1174
  listKnown &&
1178
1175
  (listing.size !== replicated.size ||
1179
- [...listing.keys()].some((conversation) => !replicated.has(conversation))));
1176
+ [...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
1177
+ (listKnown && [...drafts.keys()].some(retiredChat)));
1180
1178
  }
1181
1179
  heard(event);
1182
1180
  return false;
1183
1181
  },
1184
- searchable() {
1185
- return [...(listKnown ? listing.keys() : stored)].sort();
1186
- },
1187
- acquired(conversation) {
1188
- return reads.has(conversation) && !partials.has(conversation);
1189
- },
1190
1182
  close() {
1191
1183
  views.clear();
1192
1184
  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,CA0L3E;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"}