@agentshouse/mdruntime 0.1.0-ca7c26c6bc27e → 0.1.0-ca9a5a0b81b98

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.
@@ -20,11 +20,18 @@ export function unheldView(conversation) {
20
20
  };
21
21
  }
22
22
  function startedTurn(turn, operation) {
23
+ if (operation.op === 'begin')
24
+ return { turn, started: operation.at, parts: [], context: null };
23
25
  if (operation.op === 'context') {
24
- return { turn, parts: [], context: { used: operation.used, window: operation.window } };
26
+ return {
27
+ turn,
28
+ started: null,
29
+ parts: [],
30
+ context: { used: operation.used, window: operation.window },
31
+ };
25
32
  }
26
33
  return operation.op === 'start' && operation.index === 0
27
- ? { turn, parts: [structuredClone(operation.part)], context: null }
34
+ ? { turn, started: null, parts: [structuredClone(operation.part)], context: null }
28
35
  : null;
29
36
  }
30
37
  function changedFields(part, operation) {
@@ -39,6 +46,8 @@ function changedFields(part, operation) {
39
46
  return { entries: structuredClone(operation.entries) };
40
47
  }
41
48
  function appliedTurn(held, operation) {
49
+ if (operation.op === 'begin')
50
+ return { ...held, started: operation.at };
42
51
  if (operation.op === 'context') {
43
52
  return { ...held, context: { used: operation.used, window: operation.window } };
44
53
  }
@@ -156,6 +165,11 @@ export function createConversationStore(deps) {
156
165
  const gaps = new Map();
157
166
  const lives = new Map();
158
167
  const views = new Map();
168
+ const listing = new Map();
169
+ const listWatchers = new Set();
170
+ let listKnown = false;
171
+ let agentNames = new Map();
172
+ let agentsRead = null;
159
173
  let replicated = new Set();
160
174
  let handedReplicated;
161
175
  function liveOf(conversation) {
@@ -204,8 +218,70 @@ export function createConversationStore(deps) {
204
218
  watcher.notify(value);
205
219
  }
206
220
  }
221
+ function stateOf(conversation) {
222
+ const facts = liveOf(conversation);
223
+ if (facts.questions.length > 0)
224
+ return 'asking';
225
+ return facts.turn === null ? 'idle' : 'working';
226
+ }
227
+ function entries() {
228
+ return [...listing.values()].map((entry) => ({
229
+ conversation: entry.conversation,
230
+ agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
231
+ name: entry.name,
232
+ created: entry.created,
233
+ finished: entry.finished,
234
+ outcome: entry.outcome,
235
+ state: stateOf(entry.conversation),
236
+ started: lives.get(entry.conversation)?.turn?.started ?? null,
237
+ }));
238
+ }
239
+ function emitList() {
240
+ if (deps.closed() || listWatchers.size === 0)
241
+ return;
242
+ const value = entries();
243
+ for (const watcher of listWatchers)
244
+ watcher(value);
245
+ }
246
+ function setLive(conversation, next) {
247
+ const before = stateOf(conversation);
248
+ const began = lives.get(conversation)?.turn?.started;
249
+ if (next === null)
250
+ lives.delete(conversation);
251
+ else
252
+ lives.set(conversation, next);
253
+ if (!listing.has(conversation))
254
+ return;
255
+ if (stateOf(conversation) !== before || next?.turn?.started !== began)
256
+ emitList();
257
+ }
258
+ async function readAgents() {
259
+ const declaration = deps.agents();
260
+ if (declaration === undefined)
261
+ return;
262
+ const { documents } = await deps.documents(declaration.locator);
263
+ const names = new Map();
264
+ for (const document of documents) {
265
+ if (document.type !== declaration.type)
266
+ continue;
267
+ const identity = document.fields?.[declaration.identity];
268
+ const name = document.fields?.[declaration.name];
269
+ if (typeof identity === 'string' && typeof name === 'string')
270
+ names.set(identity, name);
271
+ }
272
+ if (JSON.stringify([...names]) === JSON.stringify([...agentNames]))
273
+ return;
274
+ agentNames = names;
275
+ emitList();
276
+ }
277
+ function agentsReady() {
278
+ agentsRead ??= readAgents().catch(() => {
279
+ agentsRead = null;
280
+ });
281
+ return agentsRead;
282
+ }
207
283
  function live(conversation, change) {
208
- lives.set(conversation, { ...liveOf(conversation), ...change });
284
+ setLive(conversation, { ...liveOf(conversation), ...change });
209
285
  emit(conversation, false);
210
286
  }
211
287
  function relayed(conversation, turn, operation) {
@@ -218,7 +294,7 @@ export function createConversationStore(deps) {
218
294
  const held = lives.get(conversation);
219
295
  if (held?.turn == null || !turns.has(held.turn.turn))
220
296
  return false;
221
- lives.set(conversation, { ...held, turn: null });
297
+ setLive(conversation, { ...held, turn: null });
222
298
  return true;
223
299
  }
224
300
  function handReplicated() {
@@ -232,27 +308,6 @@ export function createConversationStore(deps) {
232
308
  handedReplicated = named;
233
309
  stream.replicate(held);
234
310
  }
235
- async function documented() {
236
- const declaration = deps.cards();
237
- if (declaration === undefined)
238
- return [];
239
- const { documents } = await deps.documents(declaration.locator);
240
- return documents.filter((document) => typeof document.type === 'string');
241
- }
242
- function carded(documents) {
243
- const declaration = deps.cards();
244
- if (declaration === undefined)
245
- return [];
246
- const cards = [];
247
- for (const card of documents) {
248
- if (card.type !== declaration.type)
249
- continue;
250
- const identity = card.fields[declaration.identity];
251
- if (typeof identity === 'string')
252
- cards.push({ conversation: identity, card });
253
- }
254
- return cards;
255
- }
256
311
  async function remove(leaving) {
257
312
  await deps.durably(async (local) => {
258
313
  await local.dropConversations(leaving);
@@ -269,7 +324,7 @@ export function createConversationStore(deps) {
269
324
  reads.delete(conversation);
270
325
  drafts.delete(conversation);
271
326
  behind.delete(conversation);
272
- lives.delete(conversation);
327
+ setLive(conversation, null);
273
328
  }
274
329
  if (changed.length > 0)
275
330
  deps.publish(conversationChangeSet(removed, changed));
@@ -365,6 +420,48 @@ export function createConversationStore(deps) {
365
420
  }
366
421
  });
367
422
  }
423
+ function heard(event) {
424
+ const { conversation } = event;
425
+ if (event.kind === 'gap') {
426
+ if (replicated.has(conversation))
427
+ gap(conversation);
428
+ const held = lives.get(conversation);
429
+ if (held === undefined)
430
+ return;
431
+ setLive(conversation, { ...QUIET, turn: held.turn });
432
+ emit(conversation, false);
433
+ return;
434
+ }
435
+ if (event.kind === 'turn') {
436
+ relayed(conversation, event.turn, event.operation);
437
+ return;
438
+ }
439
+ if (event.kind === 'questions') {
440
+ live(conversation, { questions: structuredClone(event.questions) });
441
+ return;
442
+ }
443
+ if (event.kind === 'process') {
444
+ live(conversation, { process: { running: event.running } });
445
+ return;
446
+ }
447
+ if (event.kind === 'commands') {
448
+ live(conversation, { commands: structuredClone(event.commands) });
449
+ return;
450
+ }
451
+ if (event.kind === 'options') {
452
+ live(conversation, { options: structuredClone(event.options) });
453
+ return;
454
+ }
455
+ const arriving = acceptedMessage(event.message);
456
+ if (arriving === null)
457
+ return;
458
+ if (replicated.has(conversation)) {
459
+ void keep(conversation, arriving).catch(() => { });
460
+ return;
461
+ }
462
+ if (sealTurns(conversation, new Set([arriving.turn])))
463
+ emit(conversation);
464
+ }
368
465
  function withDraft(conversation, next) {
369
466
  return deps.durably(async (local) => {
370
467
  const following = next(drafts.get(conversation));
@@ -386,17 +483,8 @@ export function createConversationStore(deps) {
386
483
  }
387
484
  const surface = {
388
485
  async list() {
389
- const declaration = deps.cards();
390
- if (declaration === undefined)
391
- return [];
392
- const documents = await documented();
393
- const entries = carded(documents).map(({ conversation, card }) => ({
394
- conversation,
395
- card,
396
- agent: documents.find((document) => document.backlinks.some((backlink) => backlink.path === card.path && backlink.field === declaration.agent)) ?? null,
397
- }));
398
- entries.sort((left, right) => (left.conversation < right.conversation ? -1 : 1));
399
- return entries;
486
+ await agentsReady();
487
+ return entries();
400
488
  },
401
489
  async read(conversation, options = {}) {
402
490
  const limit = limitOf(options);
@@ -492,7 +580,9 @@ export function createConversationStore(deps) {
492
580
  drafts.set(record.conversation, record);
493
581
  },
494
582
  async reconcile() {
495
- const named = new Set(carded(await documented()).map((entry) => entry.conversation));
583
+ if (!listKnown)
584
+ return;
585
+ const named = new Set(listing.keys());
496
586
  const leaving = [
497
587
  ...new Set([...replicated, ...messages.keys(), ...reads.keys(), ...drafts.keys()]),
498
588
  ].filter((conversation) => !named.has(conversation));
@@ -550,53 +640,51 @@ export function createConversationStore(deps) {
550
640
  views.delete(key);
551
641
  };
552
642
  },
643
+ watchList(deliver) {
644
+ listWatchers.add(deliver);
645
+ void agentsReady().then(() => {
646
+ if (!deps.closed() && listWatchers.has(deliver))
647
+ deliver(entries());
648
+ });
649
+ return () => {
650
+ listWatchers.delete(deliver);
651
+ };
652
+ },
553
653
  changed(set) {
554
654
  for (const conversation of set.conversations)
555
655
  emit(conversation);
656
+ const declaration = deps.agents();
657
+ if (declaration !== undefined &&
658
+ set.documents.some((change) => change.locator === declaration.locator)) {
659
+ agentsRead = readAgents().catch(() => {
660
+ agentsRead = null;
661
+ });
662
+ }
556
663
  },
557
664
  receive(event) {
558
665
  if (deps.closed())
559
- return;
560
- const { conversation } = event;
561
- if (event.kind === 'gap') {
562
- if (replicated.has(conversation))
563
- gap(conversation);
564
- const held = lives.get(conversation);
565
- if (held === undefined)
566
- return;
567
- lives.set(conversation, { ...QUIET, turn: held.turn });
568
- emit(conversation, false);
569
- return;
570
- }
571
- if (event.kind === 'turn') {
572
- relayed(conversation, event.turn, event.operation);
573
- return;
574
- }
575
- if (event.kind === 'questions') {
576
- live(conversation, { questions: structuredClone(event.questions) });
577
- return;
578
- }
579
- if (event.kind === 'process') {
580
- live(conversation, { process: { running: event.running } });
581
- return;
582
- }
583
- if (event.kind === 'commands') {
584
- live(conversation, { commands: structuredClone(event.commands) });
585
- return;
586
- }
587
- if (event.kind === 'options') {
588
- live(conversation, { options: structuredClone(event.options) });
589
- return;
590
- }
591
- const arriving = acceptedMessage(event.message);
592
- if (arriving === null)
593
- return;
594
- if (replicated.has(conversation)) {
595
- void keep(conversation, arriving).catch(() => { });
596
- return;
666
+ return false;
667
+ if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
668
+ if (event.kind === 'list') {
669
+ listing.clear();
670
+ for (const entry of event.entries)
671
+ listing.set(entry.conversation, { ...entry });
672
+ listKnown = true;
673
+ }
674
+ else if (event.kind === 'listed') {
675
+ listing.set(event.entry.conversation, { ...event.entry });
676
+ }
677
+ else {
678
+ listing.delete(event.conversation);
679
+ }
680
+ emitList();
681
+ return (event.kind !== 'list' &&
682
+ listKnown &&
683
+ (listing.size !== replicated.size ||
684
+ [...listing.keys()].some((conversation) => !replicated.has(conversation))));
597
685
  }
598
- if (sealTurns(conversation, new Set([arriving.turn])))
599
- emit(conversation);
686
+ heard(event);
687
+ return false;
600
688
  },
601
689
  messages() {
602
690
  return [...messages].flatMap(([conversation, held]) => held.map(({ identity, text }) => ({ conversation, identity, text })));
@@ -608,6 +696,7 @@ export function createConversationStore(deps) {
608
696
  close() {
609
697
  views.clear();
610
698
  lives.clear();
699
+ listWatchers.clear();
611
700
  },
612
701
  };
613
702
  }
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAML,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;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IAC1F,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AA0EF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA+H3E;AAED,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,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,EAEtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,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;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IAC1F,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AA0EF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwH3E;AAED,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
package/dist/host.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { composeRuntime, } from './connection.js';
2
2
  import { removeRuntimeStore } from './store.js';
3
- import { AUTHORIZATION_ENDED, carried, envelope, PROTOCOL_MISMATCH, request, WIRE_REACH, } from './wire.js';
3
+ import { AUTHORIZATION_ENDED, request, WIRE_REACH, } from './wire.js';
4
4
  const NARROWED = new Set(['within', 'whole']);
5
5
  function answered(md, app, writtenBy, member, input) {
6
6
  switch (member) {
@@ -87,7 +87,7 @@ export function serveMdRuntime(options) {
87
87
  const observations = new Map();
88
88
  let serving = true;
89
89
  const send = (message) => {
90
- port.postMessage(envelope(message));
90
+ port.postMessage(message);
91
91
  };
92
92
  const detach = () => {
93
93
  if (!serving)
@@ -143,15 +143,7 @@ export function serveMdRuntime(options) {
143
143
  port.addEventListener('message', (event) => {
144
144
  if (!serving)
145
145
  return;
146
- const wire = carried(event.data);
147
- if (wire === null)
148
- return;
149
- if (!wire.matching) {
150
- send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });
151
- detach();
152
- return;
153
- }
154
- const message = request(wire.message);
146
+ const message = request(event.data);
155
147
  if (message === null)
156
148
  return;
157
149
  void serve(message);
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export type { AcceptedMessage, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationCards, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, HeldRoom, MdModelIdentity, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomAttachment, RoomModels, RoomNotReadable, RoomStream, RoomStreamEvent, RoomVersionAt, ServiceMode, ServiceModeSignal, TransportUncertainty, TurnContext, TurnOperation, TypedSelection, } from './adapter.js';
1
+ export type { AcceptedMessage, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationAgents, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, HeldRoom, ListedConversation, MdModelIdentity, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomAttachment, RoomModels, RoomNotReadable, RoomStream, RoomStreamEvent, RoomVersionAt, ServiceMode, ServiceModeSignal, TransportUncertainty, TurnContext, TurnOperation, TypedSelection, } from './adapter.js';
2
2
  export type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';
3
- export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationSurface, ConversationView, RunningTurn, } from './conversation.js';
3
+ export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationState, ConversationSurface, ConversationView, RunningTurn, } from './conversation.js';
4
4
  export type { ChatDraftFile, FileDeclaration } from './file.js';
5
5
  export type { AppRoom, AppTypedSelection, ConnectionRefusal, ConnectionRefusalReason, HistoryQuery, MdRuntime, MdRuntimeOptions, PresentationSurface, RoomDraftSurface, RoomTypes, SavedRoomDraft, SaveResult, } from './connection.js';
6
6
  export type { Observation } from './observation.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,MAAM,EACN,UAAU,EACV,WAAW,EACX,GAAG,EACH,UAAU,EACV,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,EACP,MAAM,EACN,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,MAAM,EACN,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,MAAM,EACN,UAAU,EACV,WAAW,EACX,GAAG,EACH,UAAU,EACV,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,EACP,MAAM,EACN,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,MAAM,EACN,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/memory.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ModelResult } from './model.js';
2
- import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type MdModelIdentity, type ProviderLimit, type Retention, type RoomAttachment, type ServiceMode } from './adapter.js';
2
+ import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type ListedConversation, type ProviderLimit, type Retention, type RoomAttachment, type ServiceMode } from './adapter.js';
3
3
  export type MemoryRoom = DiscoveredRoom & {
4
4
  model?: ModelResult;
5
5
  selectionModel?: ModelResult;
@@ -11,6 +11,7 @@ export type MemoryRoom = DiscoveredRoom & {
11
11
  };
12
12
  export type MemoryConversation = {
13
13
  conversation: string;
14
+ listed?: Omit<ListedConversation, 'conversation'>;
14
15
  messages?: readonly AcceptedMessage[];
15
16
  outcomes?: Partial<Record<ConversationAction, ActionResult>>;
16
17
  };
@@ -19,8 +20,6 @@ export type MemoryAdapterOptions = {
19
20
  conversations?: readonly MemoryConversation[];
20
21
  historyPageSize?: number;
21
22
  pageSize?: number;
22
- mdModel?: MdModelIdentity;
23
- supportedVersions?: readonly number[];
24
23
  capabilities?: readonly Capability[];
25
24
  providerLimits?: readonly ProviderLimit[];
26
25
  retention?: Retention;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAmBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,SAAS,IAAI,SAAS,MAAM,EAAE,CAAC;IAC/B,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+CF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA2arF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,kBAAkB,EAGvB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAkBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,SAAS,IAAI,SAAS,MAAM,EAAE,CAAC;IAC/B,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+CF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAkbrF"}
package/dist/memory.js CHANGED
@@ -1,5 +1,3 @@
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 },
@@ -44,8 +42,6 @@ async function resolveScript(answer, fallback, request) {
44
42
  }
45
43
  export function createMemoryAdapter(options = {}) {
46
44
  let rooms = options.rooms === undefined ? [] : [...options.rooms];
47
- const mdModel = options.mdModel ?? MD_MODEL;
48
- const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];
49
45
  const capabilities = options.capabilities ?? [];
50
46
  const providerLimits = options.providerLimits ?? [];
51
47
  const retention = declaredRetention(options.retention);
@@ -237,11 +233,14 @@ export function createMemoryAdapter(options = {}) {
237
233
  scripted.delete(named);
238
234
  return { kind: 'action', result: { conversation: named } };
239
235
  }
236
+ function announceList() {
237
+ const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined ? [] : [{ conversation, ...listed }]);
238
+ for (const listener of listeners)
239
+ listener({ kind: 'list', entries });
240
+ }
240
241
  function discovery() {
241
242
  return {
242
243
  kind: 'discovery',
243
- supportedVersions,
244
- mdModel,
245
244
  rooms: rooms.map(declared),
246
245
  capabilities,
247
246
  providerLimits,
@@ -257,6 +256,7 @@ export function createMemoryAdapter(options = {}) {
257
256
  scriptConversations(next);
258
257
  },
259
258
  open() {
259
+ announceList();
260
260
  for (const observer of observers)
261
261
  observer({ kind: 'opened' });
262
262
  },
@@ -334,7 +334,12 @@ export function createMemoryAdapter(options = {}) {
334
334
  queueMicrotask(() => {
335
335
  if (!observers.has(notify))
336
336
  return;
337
- notify(options.unopened === true ? { kind: 'closed', revoked: false } : { kind: 'opened' });
337
+ if (options.unopened === true) {
338
+ notify({ kind: 'closed', revoked: false });
339
+ return;
340
+ }
341
+ announceList();
342
+ notify({ kind: 'opened' });
338
343
  });
339
344
  return () => {
340
345
  observers.delete(notify);
@@ -1 +1 @@
1
- {"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,SAAS,EAAa,YAAY,EAAc,MAAM,iBAAiB,CAAC;AAM/F,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAEjD,MAAM,MAAM,KAAK,GAAG,CAClB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,OAAO,EAAE,OAAO,KACb,MAAM,IAAI,CAAC;AAEhB,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IACpC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;IACpD,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACvE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACxE,CAAC;AA2BF,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMpE;AAMD,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,IAAI,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;CAAE,GAC/F;IAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAU/D;AAcD,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CASnE;AA2FD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,YAAY,CAyJlF"}
1
+ {"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,SAAS,EAAa,YAAY,EAAc,MAAM,iBAAiB,CAAC;AAM/F,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAEjD,MAAM,MAAM,KAAK,GAAG,CAClB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,OAAO,EAAE,OAAO,KACb,MAAM,IAAI,CAAC;AAEhB,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IACpC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;IACpD,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACvE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACxE,CAAC;AA2BF,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMpE;AAMD,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,IAAI,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;CAAE,GAC/F;IAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAU/D;AAcD,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CASnE;AA2FD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,YAAY,CAgKlF"}
package/dist/reach.js CHANGED
@@ -201,6 +201,14 @@ export function narrowed(runtime, given) {
201
201
  return () => { };
202
202
  });
203
203
  }
204
+ if (topic === 'conversations') {
205
+ return following(() => {
206
+ if (conversing(reach))
207
+ return watch(topic, input, deliver);
208
+ deliver([]);
209
+ return () => { };
210
+ });
211
+ }
204
212
  return watch(topic, input, deliver);
205
213
  };
206
214
  const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
@@ -0,0 +1,31 @@
1
+ import type { MdRuntimeClient } from './client.js';
2
+ import type { AppRoom, ConnectionRefusal, SaveResult } from './connection.js';
3
+ import type { ServiceMode } from './adapter.js';
4
+ import type { ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
5
+ import type { QueueEntry } from './outcome.js';
6
+ import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult } from './query.js';
7
+ import type { RoomDraft, RoomDraftParts } from './room-draft.js';
8
+ import type { SyncStatus } from './status.js';
9
+ type Client = MdRuntimeClient | null;
10
+ export declare function useObserve(client: Client, topic: 'deployment-facts'): unknown;
11
+ export declare function useObserve(client: Client, topic: 'rooms'): readonly AppRoom[] | undefined;
12
+ export declare function useObserve(client: Client, topic: 'connection-refusal'): ConnectionRefusal | null | undefined;
13
+ export declare function useObserve(client: Client, topic: 'storage-loss'): string | null | undefined;
14
+ export declare function useObserve(client: Client, topic: 'sync-status'): SyncStatus | undefined;
15
+ export declare function useObserve(client: Client, topic: 'service-mode'): ServiceMode | undefined;
16
+ export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): DocumentResult | undefined;
17
+ export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): GroupResult | undefined;
18
+ export declare function useObserve(client: Client, topic: 'queue', locator: string): readonly QueueEntry[] | undefined;
19
+ export declare function useObserve(client: Client, topic: 'room-drafts'): readonly RoomDraft[] | undefined;
20
+ export declare function useObserve(client: Client, topic: 'presentation'): unknown;
21
+ export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): ConversationView | undefined;
22
+ export declare function useObserve(client: Client, topic: 'conversations'): readonly ConversationEntry[] | undefined;
23
+ export type Saving = {
24
+ readonly busy: boolean;
25
+ readonly outcome: SaveResult | null;
26
+ readonly failure: Error | null;
27
+ save(room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
28
+ };
29
+ export declare function useSave(client: MdRuntimeClient): Saving;
30
+ export {};
31
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
package/dist/react.js ADDED
@@ -0,0 +1,62 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ export function useObserve(client, topic, ...input) {
3
+ const key = JSON.stringify([topic, ...input]);
4
+ const [held, setHeld] = useState(null);
5
+ const opened = useRef(input);
6
+ opened.current = input;
7
+ useEffect(() => {
8
+ if (client === null)
9
+ return;
10
+ let live = true;
11
+ let observation = null;
12
+ const observe = client.observe;
13
+ void observe(topic, ...opened.current).then((open) => {
14
+ if (!live) {
15
+ open.close();
16
+ return;
17
+ }
18
+ observation = open;
19
+ const take = (value) => {
20
+ if (live)
21
+ setHeld({ client, key, value });
22
+ };
23
+ take(open.current());
24
+ open.subscribe(take);
25
+ });
26
+ return () => {
27
+ live = false;
28
+ observation?.close();
29
+ };
30
+ }, [client, key]);
31
+ return held !== null && held.client === client && held.key === key ? held.value : undefined;
32
+ }
33
+ const IDLE = { busy: false, outcome: null, failure: null };
34
+ async function written(client, room, roomDrafts) {
35
+ const kept = [];
36
+ for (const [path, parts] of roomDrafts) {
37
+ const prior = await client.roomDraft.read(room, path);
38
+ const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
39
+ if (write.outcome !== 'written' || write.roomDraft === null) {
40
+ throw new Error(`the Room Draft at ${path} was not written`);
41
+ }
42
+ kept.push({ path, revision: write.roomDraft.revision });
43
+ }
44
+ return client.save(room, kept);
45
+ }
46
+ export function useSave(client) {
47
+ const [state, setState] = useState(IDLE);
48
+ const save = useCallback(async (room, roomDrafts) => {
49
+ setState({ busy: true, outcome: null, failure: null });
50
+ try {
51
+ const outcome = await written(client, room, roomDrafts);
52
+ setState({ busy: false, outcome, failure: null });
53
+ return outcome;
54
+ }
55
+ catch (error) {
56
+ const failure = error instanceof Error ? error : new Error(String(error));
57
+ setState({ busy: false, outcome: null, failure });
58
+ throw failure;
59
+ }
60
+ }, [client]);
61
+ return { ...state, save };
62
+ }
package/dist/replica.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { type ChangeBatch } from './change.js';
2
2
  import { type Collection, type Composition } from './collection.js';
3
3
  import { type Layer } from './overlay.js';
4
- import { type Rewriting } from './save.js';
5
4
  import type { RoomAttachment } from './adapter.js';
6
5
  import type { ReplicaRecord } from './store.js';
7
6
  import type { Refused } from './transfer.js';
@@ -37,8 +36,8 @@ export declare function readReclassified(record: ReplicaRecord, previous: Confir
37
36
  kind: 'deferred';
38
37
  };
39
38
  export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], attachments: readonly RoomAttachment[] | undefined, roomVersion: string, writtenAt: string): Staged;
40
- export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting, previous?: Replica): Replica;
39
+ export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Replica;
41
40
  export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer): boolean;
42
- export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, rewriting: Rewriting): readonly ChangeBatch[];
41
+ export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean): readonly ChangeBatch[];
43
42
  export {};
44
43
  //# sourceMappingURL=replica.d.ts.map