@agentshouse/mdruntime 0.1.0-c8c4b020a3ec7 → 0.1.0-ca7c26c6bc27e

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 (52) hide show
  1. package/AGENTS.md +13 -6
  2. package/dist/adapter.d.ts +56 -37
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +11 -0
  5. package/dist/attached-model.d.ts.map +1 -0
  6. package/dist/attached-model.js +34 -0
  7. package/dist/bootstrap.d.ts +5 -3
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +2 -2
  10. package/dist/connection.d.ts +3 -6
  11. package/dist/connection.d.ts.map +1 -1
  12. package/dist/connection.js +478 -468
  13. package/dist/conversation.d.ts +6 -6
  14. package/dist/conversation.d.ts.map +1 -1
  15. package/dist/conversation.js +93 -37
  16. package/dist/host.d.ts +7 -1
  17. package/dist/host.d.ts.map +1 -1
  18. package/dist/host.js +32 -21
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/memory.d.ts +10 -3
  22. package/dist/memory.d.ts.map +1 -1
  23. package/dist/memory.js +66 -20
  24. package/dist/model.d.ts +1 -5
  25. package/dist/model.d.ts.map +1 -1
  26. package/dist/observation.d.ts +2 -0
  27. package/dist/observation.d.ts.map +1 -1
  28. package/dist/observation.js +24 -14
  29. package/dist/query.d.ts +7 -2
  30. package/dist/query.d.ts.map +1 -1
  31. package/dist/query.js +4 -3
  32. package/dist/reach.d.ts +40 -0
  33. package/dist/reach.d.ts.map +1 -0
  34. package/dist/reach.js +277 -0
  35. package/dist/read-side.d.ts +4 -0
  36. package/dist/read-side.d.ts.map +1 -1
  37. package/dist/read-side.js +16 -10
  38. package/dist/refresh.d.ts +2 -1
  39. package/dist/refresh.d.ts.map +1 -1
  40. package/dist/refresh.js +7 -3
  41. package/dist/replica.d.ts +2 -1
  42. package/dist/replica.d.ts.map +1 -1
  43. package/dist/replica.js +7 -3
  44. package/dist/room-draft.d.ts +3 -0
  45. package/dist/room-draft.d.ts.map +1 -1
  46. package/dist/room-draft.js +6 -4
  47. package/dist/store.d.ts +0 -1
  48. package/dist/store.d.ts.map +1 -1
  49. package/dist/wire.d.ts +50 -4
  50. package/dist/wire.d.ts.map +1 -1
  51. package/dist/wire.js +50 -45
  52. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import type { ConversationAction, ConversationCards, ConversationEvent, ConversationMessage, ConversationStream, PlanStep, ProcessCommand, SessionOption, WorkingNote } from './adapter.js';
1
+ import type { ConversationAction, ConversationCards, ConversationEvent, ConversationMessage, ConversationStream, ProcessCommand, SessionOption, TurnContext } from './adapter.js';
2
2
  import { type ChangeSet } from './change-set.js';
3
3
  import { type ChatDraftFile } from './file.js';
4
4
  import type { CallResult } from './outcome.js';
@@ -11,9 +11,10 @@ export type ConversationEntry = {
11
11
  card: Required<QueryDocument>;
12
12
  agent: Required<QueryDocument> | null;
13
13
  };
14
- export type GrowingText = {
14
+ export type RunningTurn = {
15
15
  turn: string;
16
- text: string;
16
+ parts: readonly unknown[];
17
+ context: TurnContext | null;
17
18
  };
18
19
  export type ChatDraft = {
19
20
  text: string;
@@ -25,9 +26,7 @@ export type ConversationOptions = {
25
26
  export type ConversationView = {
26
27
  conversation: string;
27
28
  messages: readonly ConversationMessage[];
28
- growingText: GrowingText | null;
29
- workingNote: WorkingNote | null;
30
- plan: readonly PlanStep[] | null;
29
+ turn: RunningTurn | null;
31
30
  questions: readonly unknown[];
32
31
  process: {
33
32
  running: boolean;
@@ -75,5 +74,6 @@ export type ConversationStore = {
75
74
  message(conversation: string, identity: string): SearchedMessage | null;
76
75
  close(): void;
77
76
  };
77
+ export declare function unheldView(conversation: string): ConversationView;
78
78
  export declare function createConversationStore(deps: ConversationDependencies): ConversationStore;
79
79
  //# sourceMappingURL=conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,64 @@
1
1
  import { conversationChangeSet } from './change-set.js';
2
2
  import { declaredFile } from './file.js';
3
3
  const QUIET = {
4
- growingText: null,
5
- plan: null,
6
- workingNote: null,
4
+ turn: null,
7
5
  questions: [],
8
6
  process: null,
9
7
  commands: [],
10
8
  options: [],
11
9
  };
10
+ export function unheldView(conversation) {
11
+ return {
12
+ conversation,
13
+ messages: [],
14
+ turn: null,
15
+ questions: [],
16
+ process: null,
17
+ commands: [],
18
+ options: [],
19
+ chatDraft: null,
20
+ };
21
+ }
22
+ function startedTurn(turn, operation) {
23
+ if (operation.op === 'context') {
24
+ return { turn, parts: [], context: { used: operation.used, window: operation.window } };
25
+ }
26
+ return operation.op === 'start' && operation.index === 0
27
+ ? { turn, parts: [structuredClone(operation.part)], context: null }
28
+ : null;
29
+ }
30
+ function changedFields(part, operation) {
31
+ if (operation.op === 'append') {
32
+ return { text: `${String(part.text ?? '')}${operation.text}` };
33
+ }
34
+ if (operation.op === 'status') {
35
+ return { status: operation.status, result: structuredClone(operation.result) };
36
+ }
37
+ if (operation.op === 'count')
38
+ return { count: operation.count };
39
+ return { entries: structuredClone(operation.entries) };
40
+ }
41
+ function appliedTurn(held, operation) {
42
+ if (operation.op === 'context') {
43
+ return { ...held, context: { used: operation.used, window: operation.window } };
44
+ }
45
+ if (operation.op === 'start') {
46
+ if (operation.index !== 0 && operation.index !== held.parts.length)
47
+ return null;
48
+ return {
49
+ ...held,
50
+ parts: [...held.parts.slice(0, operation.index), structuredClone(operation.part)],
51
+ };
52
+ }
53
+ const part = held.parts[operation.index];
54
+ if (typeof part !== 'object' || part === null)
55
+ return null;
56
+ const changed = { ...part, ...changedFields(part, operation) };
57
+ return {
58
+ ...held,
59
+ parts: held.parts.map((kept, at) => (at === operation.index ? changed : kept)),
60
+ };
61
+ }
12
62
  function ordered(left, right) {
13
63
  if (left.position !== right.position)
14
64
  return left.position < right.position ? -1 : 1;
@@ -111,22 +161,23 @@ export function createConversationStore(deps) {
111
161
  function liveOf(conversation) {
112
162
  return lives.get(conversation) ?? QUIET;
113
163
  }
114
- function viewOf(conversation, limit) {
164
+ function shownMessages(conversation, limit) {
115
165
  const held = messages.get(conversation) ?? [];
116
166
  const shown = limit === undefined ? held : held.slice(Math.max(0, held.length - limit));
167
+ return shown.map(({ identity, turn, text, message }) => ({
168
+ identity,
169
+ turn,
170
+ text,
171
+ message: structuredClone(message),
172
+ }));
173
+ }
174
+ function viewOf(conversation, limit, shown = shownMessages(conversation, limit)) {
117
175
  const draft = drafts.get(conversation);
118
176
  const facts = liveOf(conversation);
119
177
  return {
120
178
  conversation,
121
- messages: shown.map(({ identity, turn, text, message }) => ({
122
- identity,
123
- turn,
124
- text,
125
- message: structuredClone(message),
126
- })),
127
- growingText: facts.growingText === null ? null : { ...facts.growingText },
128
- workingNote: facts.workingNote === null ? null : { ...facts.workingNote },
129
- plan: structuredClone(facts.plan?.plan ?? null),
179
+ messages: shown,
180
+ turn: structuredClone(facts.turn),
130
181
  questions: structuredClone(facts.questions),
131
182
  process: facts.process === null ? null : { ...facts.process },
132
183
  commands: structuredClone(facts.commands),
@@ -136,33 +187,38 @@ export function createConversationStore(deps) {
136
187
  : { text: draft.text, files: [...draft.files] },
137
188
  };
138
189
  }
139
- function emit(conversation) {
190
+ function emit(conversation, messagesChanged = true) {
140
191
  if (deps.closed())
141
192
  return;
142
193
  for (const view of views.values()) {
143
194
  if (view.conversation !== conversation)
144
195
  continue;
196
+ if (messagesChanged)
197
+ view.messages = null;
145
198
  const ready = [...view.watchers].filter((watcher) => watcher.ready);
146
199
  if (ready.length === 0)
147
200
  continue;
148
- const value = viewOf(conversation, view.limit);
201
+ view.messages ??= shownMessages(conversation, view.limit);
202
+ const value = viewOf(conversation, view.limit, view.messages);
149
203
  for (const watcher of ready)
150
204
  watcher.notify(value);
151
205
  }
152
206
  }
153
207
  function live(conversation, change) {
154
208
  lives.set(conversation, { ...liveOf(conversation), ...change });
155
- emit(conversation);
209
+ emit(conversation, false);
210
+ }
211
+ function relayed(conversation, turn, operation) {
212
+ const held = liveOf(conversation).turn;
213
+ const next = held?.turn === turn ? appliedTurn(held, operation) : startedTurn(turn, operation);
214
+ if (next !== null)
215
+ live(conversation, { turn: next });
156
216
  }
157
217
  function sealTurns(conversation, turns) {
158
218
  const held = lives.get(conversation);
159
- if (held === undefined)
160
- return false;
161
- const growingText = held.growingText !== null && turns.has(held.growingText.turn) ? null : held.growingText;
162
- const plan = held.plan !== null && turns.has(held.plan.turn) ? null : held.plan;
163
- if (growingText === held.growingText && plan === held.plan)
219
+ if (held?.turn == null || !turns.has(held.turn.turn))
164
220
  return false;
165
- lives.set(conversation, { ...held, growingText, plan });
221
+ lives.set(conversation, { ...held, turn: null });
166
222
  return true;
167
223
  }
168
224
  function handReplicated() {
@@ -424,6 +480,8 @@ export function createConversationStore(deps) {
424
480
  hydrate(held, stored) {
425
481
  messages.clear();
426
482
  reads.clear();
483
+ for (const view of views.values())
484
+ view.messages = null;
427
485
  for (const entry of held) {
428
486
  messages.set(entry.conversation, [...entry.messages].sort(ordered));
429
487
  if (entry.read !== undefined)
@@ -467,7 +525,12 @@ export function createConversationStore(deps) {
467
525
  watch(conversation, options, deliver) {
468
526
  const limit = limitOf(options);
469
527
  const key = JSON.stringify([conversation, limit ?? null]);
470
- const view = views.get(key) ?? { conversation, limit, watchers: new Set() };
528
+ const view = views.get(key) ?? {
529
+ conversation,
530
+ limit,
531
+ watchers: new Set(),
532
+ messages: null,
533
+ };
471
534
  views.set(key, view);
472
535
  const watcher = { notify: deliver, ready: false };
473
536
  view.watchers.add(watcher);
@@ -498,22 +561,15 @@ export function createConversationStore(deps) {
498
561
  if (event.kind === 'gap') {
499
562
  if (replicated.has(conversation))
500
563
  gap(conversation);
501
- if (lives.delete(conversation))
502
- emit(conversation);
503
- return;
504
- }
505
- if (event.kind === 'growing-text') {
506
- live(conversation, { growingText: { turn: event.turn, text: event.text } });
507
- return;
508
- }
509
- if (event.kind === 'plan') {
510
- live(conversation, { plan: { turn: event.turn, plan: structuredClone(event.plan) } });
564
+ const held = lives.get(conversation);
565
+ if (held === undefined)
566
+ return;
567
+ lives.set(conversation, { ...QUIET, turn: held.turn });
568
+ emit(conversation, false);
511
569
  return;
512
570
  }
513
- if (event.kind === 'working-note') {
514
- live(conversation, {
515
- workingNote: event.note === null ? null : { noteId: event.note.noteId, text: event.note.text },
516
- });
571
+ if (event.kind === 'turn') {
572
+ relayed(conversation, event.turn, event.operation);
517
573
  return;
518
574
  }
519
575
  if (event.kind === 'questions') {
package/dist/host.d.ts CHANGED
@@ -1,13 +1,19 @@
1
1
  import { type MdRuntimeOptions } from './connection.js';
2
+ import type { PortReach } from './reach.js';
2
3
  import { type RuntimePort } from './wire.js';
3
4
  export type MdRuntimeHostOptions = MdRuntimeOptions & {
4
5
  deploymentFacts?: unknown;
5
6
  };
7
+ export type AttachedPort = {
8
+ detach(): void;
9
+ narrow(reach: PortReach): void;
10
+ };
6
11
  export type MdRuntimeHost = {
7
- attach(port: RuntimePort, app: string, release?: string): () => void;
12
+ attach(port: RuntimePort, app: string, release?: string, reach?: PortReach): AttachedPort;
8
13
  endAuthorization(): Promise<void>;
9
14
  stop(): Promise<void>;
10
15
  };
11
16
  export declare function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost;
17
+ export type { PortReach, ReachedDocument } from './reach.js';
12
18
  export type { RuntimePort } from './wire.js';
13
19
  //# 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,EAEtB,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EAML,KAAK,WAAW,EAIjB,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACrE,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,CAwG3E;AAED,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,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"}
package/dist/host.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { composeRuntime, } from './connection.js';
2
2
  import { removeRuntimeStore } from './store.js';
3
- import { AUTHORIZATION_ENDED, carried, envelope, PROTOCOL_MISMATCH, request, } from './wire.js';
3
+ import { AUTHORIZATION_ENDED, carried, envelope, PROTOCOL_MISMATCH, request, WIRE_REACH, } from './wire.js';
4
+ const NARROWED = new Set(['within', 'whole']);
4
5
  function answered(md, app, writtenBy, member, input) {
5
6
  switch (member) {
6
7
  case 'rooms':
@@ -71,18 +72,19 @@ export function serveMdRuntime(options) {
71
72
  if (options.signal?.aborted === true)
72
73
  close();
73
74
  const runtime = composeRuntime({ ...options, signal: closing.signal });
74
- const { md, watch } = runtime;
75
+ const { md } = runtime;
75
76
  const attachments = new Map();
76
77
  let authorized = true;
77
78
  const watchFacts = (deliver) => {
78
79
  deliver(structuredClone(deploymentFacts));
79
80
  return () => { };
80
81
  };
81
- function attach(port, app, release) {
82
+ function attach(port, app, release, reach) {
82
83
  if (!authorized)
83
84
  throw new Error(AUTHORIZATION_ENDED);
84
85
  const writtenBy = release === undefined ? undefined : { app, release };
85
- const subscriptions = new Map();
86
+ const view = runtime.within(reach ?? null);
87
+ const observations = new Map();
86
88
  let serving = true;
87
89
  const send = (message) => {
88
90
  port.postMessage(envelope(message));
@@ -91,37 +93,40 @@ export function serveMdRuntime(options) {
91
93
  if (!serving)
92
94
  return;
93
95
  serving = false;
94
- for (const end of subscriptions.values())
96
+ for (const end of observations.values())
95
97
  end();
96
- subscriptions.clear();
98
+ observations.clear();
97
99
  attachments.delete(detach);
98
100
  };
101
+ const observe = (id, topic, input) => {
102
+ let resolved = false;
103
+ const deliver = (value) => {
104
+ if (!serving)
105
+ return;
106
+ send(resolved ? { kind: 'event', id, value } : { kind: 'result', id, value });
107
+ resolved = true;
108
+ };
109
+ observations.set(id, topic === 'deployment-facts'
110
+ ? watchFacts(deliver)
111
+ : (NARROWED.has(WIRE_REACH.topics[topic]) ? view : runtime).watch(topic, topic === 'presentation' ? [app] : input, deliver));
112
+ };
99
113
  const serve = async (message) => {
100
114
  if (message.kind === 'hello')
101
115
  return;
102
116
  if (message.kind === 'stop') {
103
- subscriptions.get(message.id)?.();
104
- subscriptions.delete(message.id);
117
+ observations.get(message.id)?.();
118
+ observations.delete(message.id);
105
119
  return;
106
120
  }
107
121
  try {
108
122
  if (message.kind !== 'observe' || message.topic !== 'room-drafts')
109
123
  await md.loaded();
110
124
  if (message.kind === 'observe') {
111
- const { id, topic } = message;
112
- let resolved = false;
113
- const deliver = (value) => {
114
- if (!serving)
115
- return;
116
- send(resolved ? { kind: 'event', id, value } : { kind: 'result', id, value });
117
- resolved = true;
118
- };
119
- subscriptions.set(id, topic === 'deployment-facts'
120
- ? watchFacts(deliver)
121
- : watch(topic, topic === 'presentation' ? [app] : message.input, deliver));
125
+ if (serving)
126
+ observe(message.id, message.topic, message.input);
122
127
  return;
123
128
  }
124
- const value = await answered(md, app, writtenBy, message.member, message.input);
129
+ const value = await answered(NARROWED.has(WIRE_REACH.members[message.member]) ? view.md : md, app, writtenBy, message.member, message.input);
125
130
  if (serving)
126
131
  send({ kind: 'result', id: message.id, value });
127
132
  }
@@ -154,7 +159,13 @@ export function serveMdRuntime(options) {
154
159
  port.addEventListener('close', detach);
155
160
  port.start();
156
161
  attachments.set(detach, send);
157
- return detach;
162
+ return {
163
+ detach,
164
+ narrow(next) {
165
+ if (serving)
166
+ view.narrow(next);
167
+ },
168
+ };
158
169
  }
159
170
  return {
160
171
  attach,
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, MdModelIdentity, ModelRequest, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomAttachment, RoomNotReadable, RoomVersionAt, RoomVersionNotification, SelectedRooms, ServiceMode, ServiceModeSignal, TransportUncertainty, TypedSelection, WorkingNote, } from './adapter.js';
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';
2
2
  export type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';
3
- export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationSurface, ConversationView, GrowingText, } from './conversation.js';
3
+ export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, 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,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,WAAW,GACZ,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,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"}
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 RoomVersionNotification, type ServiceMode } from './adapter.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';
3
3
  export type MemoryRoom = DiscoveredRoom & {
4
4
  model?: ModelResult;
5
5
  selectionModel?: ModelResult;
@@ -24,15 +24,22 @@ export type MemoryAdapterOptions = {
24
24
  capabilities?: readonly Capability[];
25
25
  providerLimits?: readonly ProviderLimit[];
26
26
  retention?: Retention;
27
+ unopened?: boolean;
27
28
  };
28
29
  export type MemoryAdapter = Adapter & {
29
30
  setRooms(rooms: readonly MemoryRoom[]): void;
30
31
  setConversations(conversations: readonly MemoryConversation[]): void;
31
32
  script(operation: keyof Adapter, answer: unknown): void;
32
- notifyRoomVersion(notification: RoomVersionNotification): void;
33
+ open(): void;
34
+ close(revoked?: boolean): void;
35
+ expire(locators: readonly string[]): void;
36
+ notifyRoomVersion(notification: {
37
+ locator: string;
38
+ roomVersion: string;
39
+ }): void;
33
40
  notifyConversation(event: ConversationEvent): void;
34
41
  notifyServiceMode(mode: ServiceMode): void;
35
- selectedRooms(): readonly string[];
42
+ heldRooms(): readonly string[];
36
43
  replicatedConversations(): readonly string[];
37
44
  };
38
45
  export declare function createMemoryAdapter(options?: MemoryAdapterOptions): MemoryAdapter;
@@ -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,EACnB,KAAK,uBAAuB,EAC5B,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;CACvB,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,iBAAiB,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/D,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,aAAa,IAAI,SAAS,MAAM,EAAE,CAAC;IACnC,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAiZrF"}
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"}
package/dist/memory.js CHANGED
@@ -15,6 +15,19 @@ function declaredRetention(value) {
15
15
  }
16
16
  throw new Error('history retention duration must be a finite positive number of seconds');
17
17
  }
18
+ const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
19
+ function modelsOf(room) {
20
+ return {
21
+ collection: room.model ?? MODEL_ABSENT,
22
+ ...(room.typedSelection === undefined
23
+ ? {}
24
+ : { selection: room.selectionModel ?? MODEL_ABSENT }),
25
+ };
26
+ }
27
+ function changedModels(room, from) {
28
+ const now = modelsOf(room);
29
+ return JSON.stringify(now) === JSON.stringify(modelsOf(from)) ? undefined : now;
30
+ }
18
31
  function named(source, paths) {
19
32
  const taken = {};
20
33
  for (const path of paths) {
@@ -47,7 +60,8 @@ export function createMemoryAdapter(options = {}) {
47
60
  const unsealed = new Map();
48
61
  const sealed = new Set();
49
62
  const historyPageSize = options.historyPageSize;
50
- let selected = [];
63
+ let held = [];
64
+ let expiring = [];
51
65
  let replicated = [];
52
66
  let issued = 0;
53
67
  function scriptConversations(entries) {
@@ -92,7 +106,6 @@ export function createMemoryAdapter(options = {}) {
92
106
  roomVersion: room.roomVersion,
93
107
  operations: room.operations,
94
108
  replica: room.replica,
95
- attachedModel: room.attachedModel,
96
109
  ...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
97
110
  providerOwnedPaths: room.providerOwnedPaths,
98
111
  };
@@ -106,6 +119,7 @@ export function createMemoryAdapter(options = {}) {
106
119
  return {
107
120
  kind: 'bootstrap',
108
121
  roomVersion: room.roomVersion,
122
+ ...(from === 0 ? { models: modelsOf(room) } : {}),
109
123
  documents: named(room.documents ?? {}, taken),
110
124
  revisions: named(room.revisions ?? {}, taken),
111
125
  changes: named(room.changes ?? {}, [...taken, ...targets]),
@@ -136,9 +150,11 @@ export function createMemoryAdapter(options = {}) {
136
150
  : [];
137
151
  const attachments = room.attachments ?? [];
138
152
  const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
153
+ const models = opening ? changedModels(room, from) : undefined;
139
154
  return {
140
155
  kind: 'net-advancement',
141
156
  roomVersion: room.roomVersion,
157
+ ...(models === undefined ? {} : { models }),
142
158
  documents: named(current, taken),
143
159
  revisions: named(room.revisions ?? {}, taken),
144
160
  changes: named(room.changes ?? {}, [...taken, ...targets]),
@@ -240,9 +256,20 @@ export function createMemoryAdapter(options = {}) {
240
256
  setConversations(next) {
241
257
  scriptConversations(next);
242
258
  },
243
- notifyRoomVersion(notification) {
259
+ open() {
260
+ for (const observer of observers)
261
+ observer({ kind: 'opened' });
262
+ },
263
+ close(revoked = false) {
264
+ for (const observer of observers)
265
+ observer({ kind: 'closed', revoked });
266
+ },
267
+ expire(locators) {
268
+ expiring = [...locators];
269
+ },
270
+ notifyRoomVersion({ locator, roomVersion }) {
244
271
  for (const observer of observers)
245
- observer(notification);
272
+ observer({ kind: 'room-version', locator, roomVersion });
246
273
  },
247
274
  notifyConversation(event) {
248
275
  if (event.kind === 'accepted-message') {
@@ -256,8 +283,8 @@ export function createMemoryAdapter(options = {}) {
256
283
  for (const observer of modeObservers)
257
284
  observer(mode);
258
285
  },
259
- selectedRooms() {
260
- return selected;
286
+ heldRooms() {
287
+ return held;
261
288
  },
262
289
  replicatedConversations() {
263
290
  return replicated;
@@ -281,12 +308,34 @@ export function createMemoryAdapter(options = {}) {
281
308
  };
282
309
  },
283
310
  },
284
- roomVersions: {
285
- select(locators) {
286
- selected = [...locators];
311
+ roomStream: {
312
+ hold(asked) {
313
+ held = asked.map((room) => room.locator);
314
+ const expired = expiring.filter((locator) => held.includes(locator));
315
+ expiring = [];
316
+ const moved = asked.flatMap((room) => {
317
+ const current = rooms.find((entry) => entry.locator === room.locator);
318
+ return current === undefined ||
319
+ expired.includes(room.locator) ||
320
+ current.roomVersion === room.roomVersion
321
+ ? []
322
+ : [{ locator: room.locator, roomVersion: current.roomVersion }];
323
+ });
324
+ queueMicrotask(() => {
325
+ for (const observer of observers) {
326
+ for (const room of moved)
327
+ observer({ kind: 'room-version', ...room });
328
+ observer({ kind: 'opening', expired });
329
+ }
330
+ });
287
331
  },
288
332
  observe(notify) {
289
333
  observers.add(notify);
334
+ queueMicrotask(() => {
335
+ if (!observers.has(notify))
336
+ return;
337
+ notify(options.unopened === true ? { kind: 'closed', revoked: false } : { kind: 'opened' });
338
+ });
290
339
  return () => {
291
340
  observers.delete(notify);
292
341
  };
@@ -298,13 +347,6 @@ export function createMemoryAdapter(options = {}) {
298
347
  else
299
348
  scripts[operation] = answer;
300
349
  },
301
- async model(_authorization, request) {
302
- return resolveScript(scripts.model, () => {
303
- const room = rooms.find((entry) => entry.locator === request.locator);
304
- const answer = request.attached === 'collection' ? room?.model : room?.selectionModel;
305
- return answer ?? { kind: 'model-unavailable', reason: 'not-readable' };
306
- }, request);
307
- },
308
350
  async authorize() {
309
351
  return resolveScript(scripts.authorize, () => ({}), undefined);
310
352
  },
@@ -317,6 +359,14 @@ export function createMemoryAdapter(options = {}) {
317
359
  });
318
360
  },
319
361
  reached,
362
+ follows(locator, roomVersion, next) {
363
+ const scripted = scripts.follows;
364
+ if (typeof scripted === 'boolean')
365
+ return scripted;
366
+ if (scripted !== undefined)
367
+ return scripted(locator, roomVersion, next);
368
+ return true;
369
+ },
320
370
  async bootstrap(_authorization, request) {
321
371
  return resolveScript(scripts.bootstrap, () => {
322
372
  const room = rooms.find((entry) => entry.locator === request.locator);
@@ -341,10 +391,6 @@ export function createMemoryAdapter(options = {}) {
341
391
  }
342
392
  return advancement(continuation.room, continuation.from, continuation.at);
343
393
  }
344
- if (request.minPosition !== undefined &&
345
- !reached(room.locator, room.roomVersion, request.minPosition)) {
346
- return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
347
- }
348
394
  if (request.fromRoomVersion === room.roomVersion) {
349
395
  return { kind: 'still-current' };
350
396
  }
package/dist/model.d.ts CHANGED
@@ -6,17 +6,13 @@ export type ModelIdentity = {
6
6
  export type ModelSnapshot = ModelIdentity & {
7
7
  schema: string | null;
8
8
  };
9
- export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'version-changed' | 'invalid';
9
+ export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'invalid';
10
10
  export type ModelResult = {
11
11
  kind: 'model';
12
12
  snapshot: ModelSnapshot;
13
13
  } | {
14
14
  kind: 'model-unavailable';
15
15
  reason: ModelUnavailableReason;
16
- } | {
17
- kind: 'transport-uncertainty';
18
- } | {
19
- kind: 'revoked-authorization';
20
16
  };
21
17
  export type MdType = {
22
18
  name: string;