@agentshouse/mdruntime 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (59) hide show
  1. package/dist/adapter.d.ts +17 -12
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/adapter.js.map +1 -1
  4. package/dist/bootstrap.d.ts +9 -0
  5. package/dist/bootstrap.d.ts.map +1 -0
  6. package/dist/bootstrap.js +47 -0
  7. package/dist/bootstrap.js.map +1 -0
  8. package/dist/change.d.ts +64 -0
  9. package/dist/change.d.ts.map +1 -0
  10. package/dist/change.js +12 -0
  11. package/dist/change.js.map +1 -0
  12. package/dist/collection.d.ts +18 -0
  13. package/dist/collection.d.ts.map +1 -0
  14. package/dist/collection.js +52 -0
  15. package/dist/collection.js.map +1 -0
  16. package/dist/connection.d.ts +30 -5
  17. package/dist/connection.d.ts.map +1 -1
  18. package/dist/connection.js +345 -40
  19. package/dist/connection.js.map +1 -1
  20. package/dist/index.d.ts +7 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/memory.d.ts +8 -2
  24. package/dist/memory.d.ts.map +1 -1
  25. package/dist/memory.js +105 -24
  26. package/dist/memory.js.map +1 -1
  27. package/dist/overlay.d.ts +8 -0
  28. package/dist/overlay.d.ts.map +1 -0
  29. package/dist/overlay.js +139 -0
  30. package/dist/overlay.js.map +1 -0
  31. package/dist/paths.d.ts +6 -0
  32. package/dist/paths.d.ts.map +1 -0
  33. package/dist/paths.js +47 -0
  34. package/dist/paths.js.map +1 -0
  35. package/dist/refresh.d.ts +13 -0
  36. package/dist/refresh.d.ts.map +1 -0
  37. package/dist/refresh.js +63 -0
  38. package/dist/refresh.js.map +1 -0
  39. package/dist/replica.d.ts +19 -0
  40. package/dist/replica.d.ts.map +1 -0
  41. package/dist/replica.js +36 -0
  42. package/dist/replica.js.map +1 -0
  43. package/dist/save.d.ts +26 -0
  44. package/dist/save.d.ts.map +1 -0
  45. package/dist/save.js +496 -0
  46. package/dist/save.js.map +1 -0
  47. package/dist/status.d.ts +15 -0
  48. package/dist/status.d.ts.map +1 -0
  49. package/dist/status.js +29 -0
  50. package/dist/status.js.map +1 -0
  51. package/dist/store.d.ts +37 -0
  52. package/dist/store.d.ts.map +1 -0
  53. package/dist/store.js +116 -0
  54. package/dist/store.js.map +1 -0
  55. package/dist/transfer.d.ts +5 -0
  56. package/dist/transfer.d.ts.map +1 -0
  57. package/dist/transfer.js +5 -0
  58. package/dist/transfer.js.map +1 -0
  59. package/package.json +5 -1
@@ -1,43 +1,98 @@
1
+ import { query as evaluate } from '@agentshouse/query';
1
2
  import { ROOM_CONTRACT_VERSION, VERSION_1_CAPABILITIES } from './adapter.js';
3
+ import { bootstrapRoom } from './bootstrap.js';
4
+ import { MD_MODEL, PRESENTED } from './collection.js';
5
+ import { refreshRoom } from './refresh.js';
6
+ import { buildBatch } from './save.js';
7
+ import { readConfirmed, replicaOf } from './replica.js';
8
+ import { settled, same, saving, STARTING, transferring } from './status.js';
9
+ import { openReplicaStore } from './store.js';
10
+ import { unconfirmed } from './transfer.js';
2
11
  const DEFAULT_DISCOVERY_INTERVAL_MS = 60_000;
3
12
  const knownCapabilities = new Set(VERSION_1_CAPABILITIES);
4
- function asAppRoom(room) {
5
- return {
6
- name: room.name,
7
- locator: room.locator,
8
- writeGrants: room.writeGrants,
9
- providerOwnedPaths: room.providerOwnedPaths,
10
- synchronizationAvailable: true
11
- };
12
- }
13
- function heldRoom(room) {
14
- return {
15
- name: room.name,
16
- locator: room.locator,
17
- writeGrants: room.writeGrants,
18
- providerOwnedPaths: room.providerOwnedPaths,
19
- synchronizationAvailable: false
20
- };
21
- }
22
13
  export function createMdRuntime(options) {
23
14
  const period = options.discoveryIntervalMs ?? DEFAULT_DISCOVERY_INTERVAL_MS;
24
15
  let authorization = options.authorization;
25
- let rooms = (options.rooms ?? []).map(heldRoom);
16
+ let opening;
17
+ let store;
18
+ const replicas = new Map();
19
+ const drafts = new Map();
20
+ let limits = [];
21
+ const rooms = new Map();
22
+ const unreadable = new Set();
26
23
  let refusal = null;
24
+ let status = STARTING;
27
25
  let discoveryPaused = false;
28
26
  let timer;
29
27
  let closed = false;
30
28
  let chain = Promise.resolve();
29
+ let mutations = Promise.resolve();
31
30
  let inflight = false;
32
31
  let queued = false;
33
32
  const roomListeners = new Set();
34
33
  const refusalListeners = new Set();
34
+ const statusListeners = new Set();
35
+ const querySubscriptions = new Set();
36
+ const queueSubscriptions = new Set();
37
+ function at(locator, path) {
38
+ return `${locator} ${path}`;
39
+ }
40
+ function pending() {
41
+ return [
42
+ ...replicas.values()
43
+ ].some((replica)=>replica.queue.length > 0);
44
+ }
45
+ function listed() {
46
+ return [
47
+ ...rooms.values()
48
+ ];
49
+ }
50
+ function queryRooms() {
51
+ return [
52
+ ...replicas.values()
53
+ ].map((replica)=>({
54
+ room: replica.confirmed.record.locator,
55
+ roomVersion: replica.confirmed.record.roomVersion,
56
+ documents: replica.visible.collection.documents
57
+ }));
58
+ }
35
59
  function emitRooms() {
36
- for (const listener of roomListeners)listener(rooms);
60
+ const value = listed();
61
+ for (const listener of roomListeners)listener(value);
37
62
  }
38
63
  function emitRefusal() {
39
64
  for (const listener of refusalListeners)listener(refusal);
40
65
  }
66
+ function moveTo(next) {
67
+ if (closed || same(status, next)) return;
68
+ status = next;
69
+ for (const listener of statusListeners)listener(status);
70
+ }
71
+ function visible(request) {
72
+ return evaluate(queryRooms(), {
73
+ ...request,
74
+ selector: {
75
+ $and: [
76
+ PRESENTED,
77
+ request.selector ?? {}
78
+ ]
79
+ }
80
+ });
81
+ }
82
+ function emitVisible() {
83
+ for (const subscription of querySubscriptions){
84
+ subscription.notify(visible(subscription.query));
85
+ }
86
+ }
87
+ function queueOf(locator) {
88
+ return replicas.get(locator)?.queue ?? [];
89
+ }
90
+ function emitQueue(locator) {
91
+ const batches = queueOf(locator);
92
+ for (const subscription of queueSubscriptions){
93
+ if (subscription.locator === locator) subscription.notify(batches);
94
+ }
95
+ }
41
96
  function stopTimer() {
42
97
  if (timer === undefined) return;
43
98
  clearInterval(timer);
@@ -58,21 +113,183 @@ export function createMdRuntime(options) {
58
113
  };
59
114
  emitRefusal();
60
115
  }
116
+ function list(room, synchronizationAvailable) {
117
+ rooms.set(room.locator, {
118
+ name: room.name,
119
+ locator: room.locator,
120
+ writeGrants: room.writeGrants,
121
+ providerOwnedPaths: room.providerOwnedPaths,
122
+ roomVersion: replicas.get(room.locator)?.confirmed.record.roomVersion ?? null,
123
+ synchronizationAvailable
124
+ });
125
+ }
61
126
  function applyDiscovery(discovered) {
62
- const next = discovered.map(asAppRoom);
63
- const listed = new Set(discovered.map((room)=>room.locator));
64
- for (const room of rooms){
65
- if (listed.has(room.locator)) continue;
66
- next.push(heldRoom(room));
127
+ const listedLocators = new Set(discovered.map((room)=>room.locator));
128
+ for (const room of discovered){
129
+ list(room, !unreadable.has(room.locator));
130
+ }
131
+ for (const [locator, room] of rooms){
132
+ if (listedLocators.has(locator)) continue;
133
+ rooms.set(locator, {
134
+ ...room,
135
+ synchronizationAvailable: false
136
+ });
67
137
  }
68
- rooms = next;
69
138
  emitRooms();
139
+ return listedLocators;
140
+ }
141
+ async function open() {
142
+ const opened = await openReplicaStore();
143
+ const [records, queues, kept, lastCompleted, declared] = await Promise.all([
144
+ opened.all(),
145
+ opened.queues(),
146
+ opened.drafts(),
147
+ opened.lastCompleted(),
148
+ opened.providerLimits()
149
+ ]);
150
+ store = opened;
151
+ limits = declared;
152
+ for (const draft of kept)drafts.set(at(draft.locator, draft.path), draft.content);
153
+ const queued = new Map(queues.map((queue)=>[
154
+ queue.locator,
155
+ queue.batches
156
+ ]));
157
+ for (const record of records){
158
+ const confirmed = readConfirmed(record);
159
+ if (confirmed === null) continue;
160
+ replicas.set(record.locator, replicaOf(confirmed, queued.get(record.locator) ?? []));
161
+ list(record, false);
162
+ }
163
+ moveTo({
164
+ ...status,
165
+ lastCompleted
166
+ });
167
+ if (replicas.size > 0) {
168
+ emitRooms();
169
+ emitVisible();
170
+ }
171
+ return opened;
172
+ }
173
+ function openLocal() {
174
+ opening ??= open().catch((error)=>{
175
+ opening = undefined;
176
+ throw error;
177
+ });
178
+ return opening;
179
+ }
180
+ function exclusive(work) {
181
+ const next = mutations.then(work, work);
182
+ mutations = next.then(()=>undefined, ()=>undefined);
183
+ return next;
184
+ }
185
+ function publish(local, room, confirmed) {
186
+ return exclusive(async ()=>{
187
+ await local.publish(confirmed.record);
188
+ unreadable.delete(room.locator);
189
+ replicas.set(room.locator, replicaOf(confirmed, replicas.get(room.locator)?.queue ?? []));
190
+ list(room, true);
191
+ emitRooms();
192
+ emitVisible();
193
+ });
194
+ }
195
+ async function write(locator, changes) {
196
+ const replica = replicas.get(locator);
197
+ const room = rooms.get(locator);
198
+ if (replica === undefined || room === undefined) {
199
+ throw new Error(`No Local Replica for ${locator}`);
200
+ }
201
+ const built = buildBatch({
202
+ baseRoomVersion: replica.confirmed.record.roomVersion,
203
+ writeGrants: room.writeGrants,
204
+ providerOwnedPaths: room.providerOwnedPaths,
205
+ providerLimits: limits,
206
+ visible: replica.visible,
207
+ changes
208
+ });
209
+ if (built.kind === 'refused') return {
210
+ outcome: 'refused',
211
+ ...built.refusal
212
+ };
213
+ const local = await openLocal();
214
+ const batches = [
215
+ ...replica.queue,
216
+ built.batch
217
+ ];
218
+ const consumed = [
219
+ ...new Set(changes.map((change)=>change.path))
220
+ ];
221
+ await local.append({
222
+ locator,
223
+ batches
224
+ }, consumed);
225
+ for (const path of consumed)drafts.delete(at(locator, path));
226
+ replicas.set(locator, replicaOf(replica.confirmed, batches));
227
+ emitQueue(locator);
228
+ emitVisible();
229
+ moveTo(saving(status));
230
+ return {
231
+ outcome: 'saved',
232
+ id: built.batch.id
233
+ };
234
+ }
235
+ async function advance(room, local, authorized) {
236
+ const held = replicas.get(room.locator);
237
+ if (held !== undefined) {
238
+ const refreshed = await refreshRoom(options.adapter, authorized, held.confirmed);
239
+ if (refreshed.kind === 'still-current') {
240
+ if (unreadable.delete(room.locator)) {
241
+ list(room, true);
242
+ emitRooms();
243
+ }
244
+ return null;
245
+ }
246
+ if (refreshed.kind === 'advanced') {
247
+ if (closed) return unconfirmed;
248
+ await publish(local, room, refreshed.confirmed);
249
+ return null;
250
+ }
251
+ if (refreshed.kind !== 'beyond-horizon') return refreshed;
252
+ }
253
+ const bootstrapped = await bootstrapRoom(options.adapter, authorized, room);
254
+ if (bootstrapped.kind !== 'staged') return bootstrapped;
255
+ if (closed) return unconfirmed;
256
+ await publish(local, room, bootstrapped.confirmed);
257
+ return null;
258
+ }
259
+ async function synchronize(discovered, local, progress) {
260
+ for (const room of discovered){
261
+ if (closed || authorization === undefined) {
262
+ progress.complete = false;
263
+ return;
264
+ }
265
+ const withheld = await advance(room, local, authorization);
266
+ if (withheld === null) continue;
267
+ progress.complete = false;
268
+ if (withheld.kind === 'transport-uncertainty') {
269
+ progress.reachable = false;
270
+ continue;
271
+ }
272
+ if (withheld.kind === 'room-not-readable') {
273
+ unreadable.add(room.locator);
274
+ list(room, false);
275
+ emitRooms();
276
+ continue;
277
+ }
278
+ if (withheld.kind === 'revoked-authorization') {
279
+ refuse('revoked-authorization');
280
+ return;
281
+ }
282
+ }
70
283
  }
71
- async function cycle() {
284
+ async function cycle(local, progress) {
72
285
  if (closed || authorization === undefined) return;
286
+ moveTo(transferring(status));
73
287
  const result = await options.adapter.discover(authorization);
74
288
  if (closed) return;
75
- if (result.kind === 'transport-uncertainty') return;
289
+ if (result.kind === 'transport-uncertainty') {
290
+ progress.reachable = false;
291
+ return;
292
+ }
76
293
  if (result.kind === 'revoked-authorization') {
77
294
  refuse('revoked-authorization');
78
295
  return;
@@ -81,7 +298,7 @@ export function createMdRuntime(options) {
81
298
  refuse('no-matching-version');
82
299
  return;
83
300
  }
84
- if (result.mdModel.identity !== options.mdModel.identity || result.mdModel.version !== options.mdModel.version) {
301
+ if (result.mdModel.identity !== MD_MODEL.identity || result.mdModel.version !== MD_MODEL.version) {
85
302
  refuse('md-model-version-mismatch');
86
303
  return;
87
304
  }
@@ -96,7 +313,15 @@ export function createMdRuntime(options) {
96
313
  refusal = null;
97
314
  emitRefusal();
98
315
  }
99
- applyDiscovery(result.rooms);
316
+ if (JSON.stringify(result.providerLimits) !== JSON.stringify(limits)) {
317
+ limits = result.providerLimits;
318
+ await local.declare(limits);
319
+ }
320
+ const listedLocators = applyDiscovery(result.rooms);
321
+ progress.complete = [
322
+ ...replicas.keys()
323
+ ].every((locator)=>listedLocators.has(locator));
324
+ await synchronize(result.rooms, local, progress);
100
325
  }
101
326
  async function ensureAuthorization() {
102
327
  if (authorization !== undefined) return;
@@ -104,14 +329,28 @@ export function createMdRuntime(options) {
104
329
  }
105
330
  async function connect() {
106
331
  if (closed || discoveryPaused) return;
332
+ startTimer();
333
+ const progress = {
334
+ complete: false,
335
+ reachable: true
336
+ };
337
+ let completedAt = new Date().toISOString();
107
338
  try {
339
+ const local = await openLocal();
340
+ if (closed) return;
108
341
  await ensureAuthorization();
109
342
  if (closed) return;
110
- await cycle();
343
+ await cycle(local, progress);
344
+ if (closed) return;
345
+ if (progress.complete) {
346
+ completedAt = new Date().toISOString();
347
+ await local.complete(completedAt);
348
+ }
111
349
  } catch {
350
+ progress.complete = false;
112
351
  return;
113
352
  } finally{
114
- if (!closed && !discoveryPaused) startTimer();
353
+ moveTo(settled(status, progress, completedAt, pending()));
115
354
  }
116
355
  }
117
356
  async function run() {
@@ -137,8 +376,12 @@ export function createMdRuntime(options) {
137
376
  function close() {
138
377
  closed = true;
139
378
  stopTimer();
379
+ store?.close();
140
380
  roomListeners.clear();
141
381
  refusalListeners.clear();
382
+ statusListeners.clear();
383
+ querySubscriptions.clear();
384
+ queueSubscriptions.clear();
142
385
  }
143
386
  options.signal?.addEventListener('abort', close, {
144
387
  once: true
@@ -147,22 +390,84 @@ export function createMdRuntime(options) {
147
390
  void enqueue();
148
391
  return {
149
392
  rooms () {
150
- return rooms;
393
+ return listed();
394
+ },
395
+ query (request = {}) {
396
+ return visible(request);
151
397
  },
152
- observe (topic, listener) {
398
+ types (locator) {
399
+ return replicas.get(locator)?.visible.collection.types ?? [];
400
+ },
401
+ syncStatus () {
402
+ return status;
403
+ },
404
+ draft: {
405
+ read (locator, path) {
406
+ return drafts.get(at(locator, path)) ?? null;
407
+ },
408
+ async replace (locator, path, content) {
409
+ const local = await openLocal();
410
+ await local.keep({
411
+ locator,
412
+ path,
413
+ content
414
+ });
415
+ drafts.set(at(locator, path), content);
416
+ },
417
+ async discard (locator, path) {
418
+ const local = await openLocal();
419
+ await local.discard(locator, path);
420
+ drafts.delete(at(locator, path));
421
+ }
422
+ },
423
+ save (locator, changes) {
424
+ return exclusive(()=>write(locator, changes));
425
+ },
426
+ observe (topic, second, third) {
153
427
  if (topic === 'rooms') {
154
- const notify = listener;
428
+ const notify = second;
155
429
  roomListeners.add(notify);
156
- notify(rooms);
430
+ notify(listed());
157
431
  return ()=>{
158
432
  roomListeners.delete(notify);
159
433
  };
160
434
  }
161
- const notify = listener;
162
- refusalListeners.add(notify);
163
- notify(refusal);
435
+ if (topic === 'connection-refusal') {
436
+ const notify = second;
437
+ refusalListeners.add(notify);
438
+ notify(refusal);
439
+ return ()=>{
440
+ refusalListeners.delete(notify);
441
+ };
442
+ }
443
+ if (topic === 'sync-status') {
444
+ const notify = second;
445
+ statusListeners.add(notify);
446
+ notify(status);
447
+ return ()=>{
448
+ statusListeners.delete(notify);
449
+ };
450
+ }
451
+ if (topic === 'queue') {
452
+ const queue = {
453
+ locator: second,
454
+ notify: third
455
+ };
456
+ queueSubscriptions.add(queue);
457
+ queue.notify(queueOf(queue.locator));
458
+ return ()=>{
459
+ queueSubscriptions.delete(queue);
460
+ };
461
+ }
462
+ const subscription = {
463
+ query: second,
464
+ notify: third
465
+ };
466
+ const first = visible(subscription.query);
467
+ querySubscriptions.add(subscription);
468
+ subscription.notify(first);
164
469
  return ()=>{
165
- refusalListeners.delete(notify);
470
+ querySubscriptions.delete(subscription);
166
471
  };
167
472
  },
168
473
  async reauthorize () {
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/connection.ts"],"sourcesContent":["import {\n ROOM_CONTRACT_VERSION,\n VERSION_1_CAPABILITIES,\n type Adapter,\n type Authorization,\n type DiscoveredRoom,\n type MdModelIdentity,\n} from './adapter.js';\n\nconst DEFAULT_DISCOVERY_INTERVAL_MS = 60_000;\n\nconst knownCapabilities = new Set<string>(VERSION_1_CAPABILITIES);\n\nexport type AppRoom = {\n name: string;\n locator: string;\n writeGrants: readonly string[];\n providerOwnedPaths: readonly string[];\n synchronizationAvailable: boolean;\n};\n\nexport type ConnectionRefusalReason =\n | 'no-matching-version'\n | 'missing-required-guarantee'\n | 'md-model-version-mismatch'\n | 'revoked-authorization';\n\nexport type ConnectionRefusal = {\n reason: ConnectionRefusalReason;\n reauthorizationOffered: boolean;\n};\n\nexport type MdRuntimeOptions = {\n adapter: Adapter;\n requiredGuarantees: readonly string[];\n mdModel: MdModelIdentity;\n authorization?: Authorization;\n rooms?: readonly AppRoom[];\n discoveryIntervalMs?: number;\n signal?: AbortSignal;\n};\n\nexport type MdRuntime = {\n rooms(): readonly AppRoom[];\n observe(topic: 'rooms', listener: (rooms: readonly AppRoom[]) => void): () => void;\n observe(\n topic: 'connection-refusal',\n listener: (refusal: ConnectionRefusal | null) => void,\n ): () => void;\n reauthorize(): Promise<void>;\n};\n\nfunction asAppRoom(room: DiscoveredRoom): AppRoom {\n return {\n name: room.name,\n locator: room.locator,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n synchronizationAvailable: true,\n };\n}\n\nfunction heldRoom(room: AppRoom): AppRoom {\n return {\n name: room.name,\n locator: room.locator,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n synchronizationAvailable: false,\n };\n}\n\nexport function createMdRuntime(options: MdRuntimeOptions): MdRuntime {\n const period = options.discoveryIntervalMs ?? DEFAULT_DISCOVERY_INTERVAL_MS;\n let authorization: Authorization | undefined = options.authorization;\n let rooms: AppRoom[] = (options.rooms ?? []).map(heldRoom);\n let refusal: ConnectionRefusal | null = null;\n let discoveryPaused = false;\n let timer: ReturnType<typeof setInterval> | undefined;\n let closed = false;\n let chain: Promise<void> = Promise.resolve();\n let inflight = false;\n let queued = false;\n const roomListeners = new Set<(rooms: readonly AppRoom[]) => void>();\n const refusalListeners = new Set<(refusal: ConnectionRefusal | null) => void>();\n\n function emitRooms() {\n for (const listener of roomListeners) listener(rooms);\n }\n\n function emitRefusal() {\n for (const listener of refusalListeners) listener(refusal);\n }\n\n function stopTimer() {\n if (timer === undefined) return;\n clearInterval(timer);\n timer = undefined;\n }\n\n function startTimer() {\n if (timer !== undefined) return;\n timer = setInterval(() => {\n void enqueue();\n }, period);\n }\n\n function refuse(reason: ConnectionRefusalReason) {\n stopTimer();\n discoveryPaused = true;\n refusal = {\n reason,\n reauthorizationOffered: reason === 'revoked-authorization',\n };\n emitRefusal();\n }\n\n function applyDiscovery(discovered: readonly DiscoveredRoom[]) {\n const next = discovered.map(asAppRoom);\n const listed = new Set(discovered.map((room) => room.locator));\n for (const room of rooms) {\n if (listed.has(room.locator)) continue;\n next.push(heldRoom(room));\n }\n rooms = next;\n emitRooms();\n }\n\n async function cycle() {\n if (closed || authorization === undefined) return;\n const result = await options.adapter.discover(authorization);\n if (closed) return;\n if (result.kind === 'transport-uncertainty') return;\n if (result.kind === 'revoked-authorization') {\n refuse('revoked-authorization');\n return;\n }\n if (!result.supportedVersions.includes(ROOM_CONTRACT_VERSION)) {\n refuse('no-matching-version');\n return;\n }\n if (\n result.mdModel.identity !== options.mdModel.identity ||\n result.mdModel.version !== options.mdModel.version\n ) {\n refuse('md-model-version-mismatch');\n return;\n }\n const declared = new Set(result.capabilities.map((capability) => capability.name));\n for (const required of options.requiredGuarantees) {\n if (!knownCapabilities.has(required) || !declared.has(required)) {\n refuse('missing-required-guarantee');\n return;\n }\n }\n if (refusal !== null) {\n refusal = null;\n emitRefusal();\n }\n applyDiscovery(result.rooms);\n }\n\n async function ensureAuthorization() {\n if (authorization !== undefined) return;\n authorization = await options.adapter.authorize();\n }\n\n async function connect() {\n if (closed || discoveryPaused) return;\n try {\n await ensureAuthorization();\n if (closed) return;\n await cycle();\n } catch {\n return;\n } finally {\n if (!closed && !discoveryPaused) startTimer();\n }\n }\n\n async function run() {\n try {\n await connect();\n } finally {\n inflight = false;\n if (queued && !closed) {\n queued = false;\n void enqueue();\n }\n }\n }\n\n function enqueue() {\n if (inflight) {\n queued = true;\n return chain;\n }\n inflight = true;\n chain = chain.then(run, run);\n return chain;\n }\n\n function close() {\n closed = true;\n stopTimer();\n roomListeners.clear();\n refusalListeners.clear();\n }\n\n options.signal?.addEventListener('abort', close, { once: true });\n if (options.signal?.aborted) close();\n\n void enqueue();\n\n return {\n rooms() {\n return rooms;\n },\n observe(topic: 'rooms' | 'connection-refusal', listener: (value: never) => void) {\n if (topic === 'rooms') {\n const notify = listener as (value: readonly AppRoom[]) => void;\n roomListeners.add(notify);\n notify(rooms);\n return () => {\n roomListeners.delete(notify);\n };\n }\n const notify = listener as (value: ConnectionRefusal | null) => void;\n refusalListeners.add(notify);\n notify(refusal);\n return () => {\n refusalListeners.delete(notify);\n };\n },\n async reauthorize() {\n if (refusal === null || !refusal.reauthorizationOffered) return;\n authorization = undefined;\n discoveryPaused = false;\n await enqueue();\n },\n };\n}\n"],"names":["ROOM_CONTRACT_VERSION","VERSION_1_CAPABILITIES","DEFAULT_DISCOVERY_INTERVAL_MS","knownCapabilities","Set","asAppRoom","room","name","locator","writeGrants","providerOwnedPaths","synchronizationAvailable","heldRoom","createMdRuntime","options","period","discoveryIntervalMs","authorization","rooms","map","refusal","discoveryPaused","timer","closed","chain","Promise","resolve","inflight","queued","roomListeners","refusalListeners","emitRooms","listener","emitRefusal","stopTimer","undefined","clearInterval","startTimer","setInterval","enqueue","refuse","reason","reauthorizationOffered","applyDiscovery","discovered","next","listed","has","push","cycle","result","adapter","discover","kind","supportedVersions","includes","mdModel","identity","version","declared","capabilities","capability","required","requiredGuarantees","ensureAuthorization","authorize","connect","run","then","close","clear","signal","addEventListener","once","aborted","observe","topic","notify","add","delete","reauthorize"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/connection.ts"],"sourcesContent":["import {\n query as evaluate,\n type QueryOptions,\n type QueryResult,\n type QueryRoom,\n} from '@agentshouse/query';\nimport {\n ROOM_CONTRACT_VERSION,\n VERSION_1_CAPABILITIES,\n type Adapter,\n type AdapterFailure,\n type Authorization,\n type DiscoveredRoom,\n type ProviderLimit,\n} from './adapter.js';\nimport { bootstrapRoom } from './bootstrap.js';\nimport type { Change, ChangeBatch } from './change.js';\nimport { MD_MODEL, PRESENTED, type MdType } from './collection.js';\nimport { refreshRoom } from './refresh.js';\nimport { buildBatch, type SaveRefusal } from './save.js';\nimport { readConfirmed, replicaOf, type ConfirmedLayer, type Replica } from './replica.js';\nimport {\n settled,\n same,\n saving,\n STARTING,\n transferring,\n type CycleProgress,\n type SyncStatus,\n} from './status.js';\nimport { openReplicaStore, type ReplicaStore } from './store.js';\nimport { unconfirmed, type Unconfirmed } from './transfer.js';\n\nconst DEFAULT_DISCOVERY_INTERVAL_MS = 60_000;\n\nconst knownCapabilities = new Set<string>(VERSION_1_CAPABILITIES);\n\nexport type AppRoom = {\n name: string;\n locator: string;\n writeGrants: readonly string[];\n providerOwnedPaths: readonly string[];\n roomVersion: string | null;\n synchronizationAvailable: boolean;\n};\n\nexport type ConnectionRefusalReason =\n | 'no-matching-version'\n | 'missing-required-guarantee'\n | 'md-model-version-mismatch'\n | 'revoked-authorization';\n\nexport type ConnectionRefusal = {\n reason: ConnectionRefusalReason;\n reauthorizationOffered: boolean;\n};\n\nexport type MdRuntimeOptions = {\n adapter: Adapter;\n requiredGuarantees: readonly string[];\n authorization?: Authorization;\n discoveryIntervalMs?: number;\n signal?: AbortSignal;\n};\n\nexport type SaveResult = { outcome: 'saved'; id: string } | ({ outcome: 'refused' } & SaveRefusal);\n\nexport type DraftSurface = {\n read(locator: string, path: string): unknown;\n replace(locator: string, path: string, content: unknown): Promise<void>;\n discard(locator: string, path: string): Promise<void>;\n};\n\nexport type MdRuntime = {\n rooms(): readonly AppRoom[];\n query(options?: QueryOptions): QueryResult;\n types(locator: string): readonly MdType[];\n syncStatus(): SyncStatus;\n draft: DraftSurface;\n save(locator: string, changes: readonly Change[]): Promise<SaveResult>;\n observe: {\n (topic: 'rooms', listener: (rooms: readonly AppRoom[]) => void): () => void;\n (\n topic: 'connection-refusal',\n listener: (refusal: ConnectionRefusal | null) => void,\n ): () => void;\n (topic: 'sync-status', listener: (status: SyncStatus) => void): () => void;\n (topic: 'query', query: QueryOptions, listener: (result: QueryResult) => void): () => void;\n (\n topic: 'queue',\n locator: string,\n listener: (batches: readonly ChangeBatch[]) => void,\n ): () => void;\n };\n reauthorize(): Promise<void>;\n};\n\ntype QuerySubscription = {\n query: QueryOptions;\n notify: (result: QueryResult) => void;\n};\n\ntype QueueSubscription = {\n locator: string;\n notify: (batches: readonly ChangeBatch[]) => void;\n};\n\ntype Withheld = AdapterFailure | Unconfirmed;\n\nexport function createMdRuntime(options: MdRuntimeOptions): MdRuntime {\n const period = options.discoveryIntervalMs ?? DEFAULT_DISCOVERY_INTERVAL_MS;\n let authorization: Authorization | undefined = options.authorization;\n let opening: Promise<ReplicaStore> | undefined;\n let store: ReplicaStore | undefined;\n const replicas = new Map<string, Replica>();\n const drafts = new Map<string, unknown>();\n let limits: readonly ProviderLimit[] = [];\n const rooms = new Map<string, AppRoom>();\n const unreadable = new Set<string>();\n let refusal: ConnectionRefusal | null = null;\n let status: SyncStatus = STARTING;\n let discoveryPaused = false;\n let timer: ReturnType<typeof setInterval> | undefined;\n let closed = false;\n let chain: Promise<void> = Promise.resolve();\n let mutations: Promise<unknown> = Promise.resolve();\n let inflight = false;\n let queued = false;\n const roomListeners = new Set<(rooms: readonly AppRoom[]) => void>();\n const refusalListeners = new Set<(refusal: ConnectionRefusal | null) => void>();\n const statusListeners = new Set<(status: SyncStatus) => void>();\n const querySubscriptions = new Set<QuerySubscription>();\n const queueSubscriptions = new Set<QueueSubscription>();\n\n function at(locator: string, path: string) {\n return `${locator} ${path}`;\n }\n\n function pending() {\n return [...replicas.values()].some((replica) => replica.queue.length > 0);\n }\n\n function listed(): readonly AppRoom[] {\n return [...rooms.values()];\n }\n\n function queryRooms(): readonly QueryRoom[] {\n return [...replicas.values()].map((replica) => ({\n room: replica.confirmed.record.locator,\n roomVersion: replica.confirmed.record.roomVersion,\n documents: replica.visible.collection.documents,\n }));\n }\n\n function emitRooms() {\n const value = listed();\n for (const listener of roomListeners) listener(value);\n }\n\n function emitRefusal() {\n for (const listener of refusalListeners) listener(refusal);\n }\n\n function moveTo(next: SyncStatus) {\n if (closed || same(status, next)) return;\n status = next;\n for (const listener of statusListeners) listener(status);\n }\n\n function visible(request: QueryOptions): QueryResult {\n return evaluate(queryRooms(), {\n ...request,\n selector: { $and: [PRESENTED, request.selector ?? {}] },\n });\n }\n\n function emitVisible() {\n for (const subscription of querySubscriptions) {\n subscription.notify(visible(subscription.query));\n }\n }\n\n function queueOf(locator: string): readonly ChangeBatch[] {\n return replicas.get(locator)?.queue ?? [];\n }\n\n function emitQueue(locator: string) {\n const batches = queueOf(locator);\n for (const subscription of queueSubscriptions) {\n if (subscription.locator === locator) subscription.notify(batches);\n }\n }\n\n function stopTimer() {\n if (timer === undefined) return;\n clearInterval(timer);\n timer = undefined;\n }\n\n function startTimer() {\n if (timer !== undefined) return;\n timer = setInterval(() => {\n void enqueue();\n }, period);\n }\n\n function refuse(reason: ConnectionRefusalReason) {\n stopTimer();\n discoveryPaused = true;\n refusal = {\n reason,\n reauthorizationOffered: reason === 'revoked-authorization',\n };\n emitRefusal();\n }\n\n function list(room: DiscoveredRoom, synchronizationAvailable: boolean) {\n rooms.set(room.locator, {\n name: room.name,\n locator: room.locator,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n roomVersion: replicas.get(room.locator)?.confirmed.record.roomVersion ?? null,\n synchronizationAvailable,\n });\n }\n\n function applyDiscovery(discovered: readonly DiscoveredRoom[]): ReadonlySet<string> {\n const listedLocators = new Set(discovered.map((room) => room.locator));\n for (const room of discovered) {\n list(room, !unreadable.has(room.locator));\n }\n for (const [locator, room] of rooms) {\n if (listedLocators.has(locator)) continue;\n rooms.set(locator, { ...room, synchronizationAvailable: false });\n }\n emitRooms();\n return listedLocators;\n }\n\n async function open(): Promise<ReplicaStore> {\n const opened = await openReplicaStore();\n const [records, queues, kept, lastCompleted, declared] = await Promise.all([\n opened.all(),\n opened.queues(),\n opened.drafts(),\n opened.lastCompleted(),\n opened.providerLimits(),\n ]);\n store = opened;\n limits = declared;\n for (const draft of kept) drafts.set(at(draft.locator, draft.path), draft.content);\n const queued = new Map(queues.map((queue) => [queue.locator, queue.batches]));\n for (const record of records) {\n const confirmed = readConfirmed(record);\n if (confirmed === null) continue;\n replicas.set(record.locator, replicaOf(confirmed, queued.get(record.locator) ?? []));\n list(record, false);\n }\n moveTo({ ...status, lastCompleted });\n if (replicas.size > 0) {\n emitRooms();\n emitVisible();\n }\n return opened;\n }\n\n function openLocal(): Promise<ReplicaStore> {\n opening ??= open().catch((error: unknown) => {\n opening = undefined;\n throw error;\n });\n return opening;\n }\n\n function exclusive<T>(work: () => Promise<T>): Promise<T> {\n const next = mutations.then(work, work);\n mutations = next.then(\n () => undefined,\n () => undefined,\n );\n return next;\n }\n\n function publish(local: ReplicaStore, room: DiscoveredRoom, confirmed: ConfirmedLayer) {\n return exclusive(async () => {\n await local.publish(confirmed.record);\n unreadable.delete(room.locator);\n replicas.set(room.locator, replicaOf(confirmed, replicas.get(room.locator)?.queue ?? []));\n list(room, true);\n emitRooms();\n emitVisible();\n });\n }\n\n async function write(locator: string, changes: readonly Change[]): Promise<SaveResult> {\n const replica = replicas.get(locator);\n const room = rooms.get(locator);\n if (replica === undefined || room === undefined) {\n throw new Error(`No Local Replica for ${locator}`);\n }\n const built = buildBatch({\n baseRoomVersion: replica.confirmed.record.roomVersion,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n providerLimits: limits,\n visible: replica.visible,\n changes,\n });\n if (built.kind === 'refused') return { outcome: 'refused', ...built.refusal };\n const local = await openLocal();\n const batches = [...replica.queue, built.batch];\n const consumed = [...new Set(changes.map((change) => change.path))];\n await local.append({ locator, batches }, consumed);\n for (const path of consumed) drafts.delete(at(locator, path));\n replicas.set(locator, replicaOf(replica.confirmed, batches));\n emitQueue(locator);\n emitVisible();\n moveTo(saving(status));\n return { outcome: 'saved', id: built.batch.id };\n }\n\n async function advance(\n room: DiscoveredRoom,\n local: ReplicaStore,\n authorized: Authorization,\n ): Promise<Withheld | null> {\n const held = replicas.get(room.locator);\n if (held !== undefined) {\n const refreshed = await refreshRoom(options.adapter, authorized, held.confirmed);\n if (refreshed.kind === 'still-current') {\n if (unreadable.delete(room.locator)) {\n list(room, true);\n emitRooms();\n }\n return null;\n }\n if (refreshed.kind === 'advanced') {\n if (closed) return unconfirmed;\n await publish(local, room, refreshed.confirmed);\n return null;\n }\n if (refreshed.kind !== 'beyond-horizon') return refreshed;\n }\n const bootstrapped = await bootstrapRoom(options.adapter, authorized, room);\n if (bootstrapped.kind !== 'staged') return bootstrapped;\n if (closed) return unconfirmed;\n await publish(local, room, bootstrapped.confirmed);\n return null;\n }\n\n async function synchronize(\n discovered: readonly DiscoveredRoom[],\n local: ReplicaStore,\n progress: CycleProgress,\n ) {\n for (const room of discovered) {\n if (closed || authorization === undefined) {\n progress.complete = false;\n return;\n }\n const withheld = await advance(room, local, authorization);\n if (withheld === null) continue;\n progress.complete = false;\n if (withheld.kind === 'transport-uncertainty') {\n progress.reachable = false;\n continue;\n }\n if (withheld.kind === 'room-not-readable') {\n unreadable.add(room.locator);\n list(room, false);\n emitRooms();\n continue;\n }\n if (withheld.kind === 'revoked-authorization') {\n refuse('revoked-authorization');\n return;\n }\n }\n }\n\n async function cycle(local: ReplicaStore, progress: CycleProgress) {\n if (closed || authorization === undefined) return;\n moveTo(transferring(status));\n const result = await options.adapter.discover(authorization);\n if (closed) return;\n if (result.kind === 'transport-uncertainty') {\n progress.reachable = false;\n return;\n }\n if (result.kind === 'revoked-authorization') {\n refuse('revoked-authorization');\n return;\n }\n if (!result.supportedVersions.includes(ROOM_CONTRACT_VERSION)) {\n refuse('no-matching-version');\n return;\n }\n if (\n result.mdModel.identity !== MD_MODEL.identity ||\n result.mdModel.version !== MD_MODEL.version\n ) {\n refuse('md-model-version-mismatch');\n return;\n }\n const declared = new Set(result.capabilities.map((capability) => capability.name));\n for (const required of options.requiredGuarantees) {\n if (!knownCapabilities.has(required) || !declared.has(required)) {\n refuse('missing-required-guarantee');\n return;\n }\n }\n if (refusal !== null) {\n refusal = null;\n emitRefusal();\n }\n if (JSON.stringify(result.providerLimits) !== JSON.stringify(limits)) {\n limits = result.providerLimits;\n await local.declare(limits);\n }\n const listedLocators = applyDiscovery(result.rooms);\n progress.complete = [...replicas.keys()].every((locator) => listedLocators.has(locator));\n await synchronize(result.rooms, local, progress);\n }\n\n async function ensureAuthorization() {\n if (authorization !== undefined) return;\n authorization = await options.adapter.authorize();\n }\n\n async function connect() {\n if (closed || discoveryPaused) return;\n startTimer();\n const progress: CycleProgress = { complete: false, reachable: true };\n let completedAt = new Date().toISOString();\n try {\n const local = await openLocal();\n if (closed) return;\n await ensureAuthorization();\n if (closed) return;\n await cycle(local, progress);\n if (closed) return;\n if (progress.complete) {\n completedAt = new Date().toISOString();\n await local.complete(completedAt);\n }\n } catch {\n progress.complete = false;\n return;\n } finally {\n moveTo(settled(status, progress, completedAt, pending()));\n }\n }\n\n async function run() {\n try {\n await connect();\n } finally {\n inflight = false;\n if (queued && !closed) {\n queued = false;\n void enqueue();\n }\n }\n }\n\n function enqueue() {\n if (inflight) {\n queued = true;\n return chain;\n }\n inflight = true;\n chain = chain.then(run, run);\n return chain;\n }\n\n function close() {\n closed = true;\n stopTimer();\n store?.close();\n roomListeners.clear();\n refusalListeners.clear();\n statusListeners.clear();\n querySubscriptions.clear();\n queueSubscriptions.clear();\n }\n\n options.signal?.addEventListener('abort', close, { once: true });\n if (options.signal?.aborted) close();\n\n void enqueue();\n\n return {\n rooms() {\n return listed();\n },\n query(request: QueryOptions = {}) {\n return visible(request);\n },\n types(locator: string) {\n return replicas.get(locator)?.visible.collection.types ?? [];\n },\n syncStatus() {\n return status;\n },\n draft: {\n read(locator: string, path: string) {\n return drafts.get(at(locator, path)) ?? null;\n },\n async replace(locator: string, path: string, content: unknown) {\n const local = await openLocal();\n await local.keep({ locator, path, content });\n drafts.set(at(locator, path), content);\n },\n async discard(locator: string, path: string) {\n const local = await openLocal();\n await local.discard(locator, path);\n drafts.delete(at(locator, path));\n },\n },\n save(locator: string, changes: readonly Change[]): Promise<SaveResult> {\n return exclusive(() => write(locator, changes));\n },\n observe(\n topic: 'rooms' | 'connection-refusal' | 'sync-status' | 'query' | 'queue',\n second: QueryOptions | string | ((value: never) => void),\n third?: (value: never) => void,\n ) {\n if (topic === 'rooms') {\n const notify = second as (value: readonly AppRoom[]) => void;\n roomListeners.add(notify);\n notify(listed());\n return () => {\n roomListeners.delete(notify);\n };\n }\n if (topic === 'connection-refusal') {\n const notify = second as (value: ConnectionRefusal | null) => void;\n refusalListeners.add(notify);\n notify(refusal);\n return () => {\n refusalListeners.delete(notify);\n };\n }\n if (topic === 'sync-status') {\n const notify = second as (value: SyncStatus) => void;\n statusListeners.add(notify);\n notify(status);\n return () => {\n statusListeners.delete(notify);\n };\n }\n if (topic === 'queue') {\n const queue: QueueSubscription = {\n locator: second as string,\n notify: third as (batches: readonly ChangeBatch[]) => void,\n };\n queueSubscriptions.add(queue);\n queue.notify(queueOf(queue.locator));\n return () => {\n queueSubscriptions.delete(queue);\n };\n }\n const subscription: QuerySubscription = {\n query: second as QueryOptions,\n notify: third as (result: QueryResult) => void,\n };\n const first = visible(subscription.query);\n querySubscriptions.add(subscription);\n subscription.notify(first);\n return () => {\n querySubscriptions.delete(subscription);\n };\n },\n async reauthorize() {\n if (refusal === null || !refusal.reauthorizationOffered) return;\n authorization = undefined;\n discoveryPaused = false;\n await enqueue();\n },\n };\n}\n"],"names":["query","evaluate","ROOM_CONTRACT_VERSION","VERSION_1_CAPABILITIES","bootstrapRoom","MD_MODEL","PRESENTED","refreshRoom","buildBatch","readConfirmed","replicaOf","settled","same","saving","STARTING","transferring","openReplicaStore","unconfirmed","DEFAULT_DISCOVERY_INTERVAL_MS","knownCapabilities","Set","createMdRuntime","options","period","discoveryIntervalMs","authorization","opening","store","replicas","Map","drafts","limits","rooms","unreadable","refusal","status","discoveryPaused","timer","closed","chain","Promise","resolve","mutations","inflight","queued","roomListeners","refusalListeners","statusListeners","querySubscriptions","queueSubscriptions","at","locator","path","pending","values","some","replica","queue","length","listed","queryRooms","map","room","confirmed","record","roomVersion","documents","visible","collection","emitRooms","value","listener","emitRefusal","moveTo","next","request","selector","$and","emitVisible","subscription","notify","queueOf","get","emitQueue","batches","stopTimer","undefined","clearInterval","startTimer","setInterval","enqueue","refuse","reason","reauthorizationOffered","list","synchronizationAvailable","set","name","writeGrants","providerOwnedPaths","applyDiscovery","discovered","listedLocators","has","open","opened","records","queues","kept","lastCompleted","declared","all","providerLimits","draft","content","size","openLocal","catch","error","exclusive","work","then","publish","local","delete","write","changes","Error","built","baseRoomVersion","kind","outcome","batch","consumed","change","append","id","advance","authorized","held","refreshed","adapter","bootstrapped","synchronize","progress","complete","withheld","reachable","add","cycle","result","discover","supportedVersions","includes","mdModel","identity","version","capabilities","capability","required","requiredGuarantees","JSON","stringify","declare","keys","every","ensureAuthorization","authorize","connect","completedAt","Date","toISOString","run","close","clear","signal","addEventListener","once","aborted","types","syncStatus","read","replace","keep","discard","save","observe","topic","second","third","first","reauthorize"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,9 @@
1
- export type { ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapRequest, BootstrapResult, Capability, DiscoverResult, DiscoveredRoom, Discovery, HistoryRequest, HistoryResult, MdModelIdentity, MutationRequest, MutationResult, PageToken, ProviderLimit, RefreshRequest, RefreshResult, Retention, RevokedAuthorization, RoomNotReadable, TransportUncertainty, } from './adapter.js';
2
- export type { AppRoom, ConnectionRefusal, ConnectionRefusalReason, MdRuntime, MdRuntimeOptions, } from './connection.js';
1
+ export type { ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, DiscoverResult, DiscoveredRoom, Discovery, HistoryRequest, HistoryResult, MdModelIdentity, MutationRequest, MutationResult, PageToken, ProviderLimit, RefreshPage, RefreshRequest, RefreshResult, Retention, RevokedAuthorization, RoomNotReadable, TransportUncertainty, } from './adapter.js';
2
+ export type { Change, ChangeBatch, Precondition } from './change.js';
3
+ export type { MdType } from './collection.js';
4
+ export type { AppRoom, ConnectionRefusal, ConnectionRefusalReason, DraftSurface, MdRuntime, MdRuntimeOptions, SaveResult, } from './connection.js';
5
+ export type { SaveRefusal } from './save.js';
3
6
  export { createMdRuntime } from './connection.js';
7
+ export type { SyncStatus } from './status.js';
8
+ export type { Backlink, QueryDocument, QueryGroup, QueryOptions, QueryResult, Selector, } from '@agentshouse/query';
4
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,cAAc,EACd,cAAc,EACd,SAAS,EACT,cAAc,EACd,aAAa,EACb,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,uBAAuB,EACvB,SAAS,EACT,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,cAAc,EACd,cAAc,EACd,SAAS,EACT,cAAc,EACd,aAAa,EACb,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,oBAAoB,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/index.ts"],"sourcesContent":["export type {\n ActionDeclaration,\n ActionRequest,\n ActionResult,\n Adapter,\n AdapterFailure,\n Authorization,\n BootstrapRequest,\n BootstrapResult,\n Capability,\n DiscoverResult,\n DiscoveredRoom,\n Discovery,\n HistoryRequest,\n HistoryResult,\n MdModelIdentity,\n MutationRequest,\n MutationResult,\n PageToken,\n ProviderLimit,\n RefreshRequest,\n RefreshResult,\n Retention,\n RevokedAuthorization,\n RoomNotReadable,\n TransportUncertainty,\n} from './adapter.js';\nexport type {\n AppRoom,\n ConnectionRefusal,\n ConnectionRefusalReason,\n MdRuntime,\n MdRuntimeOptions,\n} from './connection.js';\nexport { createMdRuntime } from './connection.js';\n"],"names":["createMdRuntime"],"mappings":"AAkCA,SAASA,eAAe,QAAQ,kBAAkB"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/index.ts"],"sourcesContent":["export type {\n ActionDeclaration,\n ActionRequest,\n ActionResult,\n Adapter,\n AdapterFailure,\n Authorization,\n BootstrapPage,\n BootstrapRequest,\n BootstrapResult,\n Capability,\n DiscoverResult,\n DiscoveredRoom,\n Discovery,\n HistoryRequest,\n HistoryResult,\n MdModelIdentity,\n MutationRequest,\n MutationResult,\n PageToken,\n ProviderLimit,\n RefreshPage,\n RefreshRequest,\n RefreshResult,\n Retention,\n RevokedAuthorization,\n RoomNotReadable,\n TransportUncertainty,\n} from './adapter.js';\nexport type { Change, ChangeBatch, Precondition } from './change.js';\nexport type { MdType } from './collection.js';\nexport type {\n AppRoom,\n ConnectionRefusal,\n ConnectionRefusalReason,\n DraftSurface,\n MdRuntime,\n MdRuntimeOptions,\n SaveResult,\n} from './connection.js';\nexport type { SaveRefusal } from './save.js';\nexport { createMdRuntime } from './connection.js';\nexport type { SyncStatus } from './status.js';\nexport type {\n Backlink,\n QueryDocument,\n QueryGroup,\n QueryOptions,\n QueryResult,\n Selector,\n} from '@agentshouse/query';\n"],"names":["createMdRuntime"],"mappings":"AAyCA,SAASA,eAAe,QAAQ,kBAAkB"}
package/dist/memory.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  import { type Adapter, type Capability, type DiscoveredRoom, type MdModelIdentity, type ProviderLimit, type Retention } from './adapter.js';
2
+ export type MemoryRoom = DiscoveredRoom & {
3
+ documents?: Readonly<Record<string, string>>;
4
+ revisions?: Readonly<Record<string, string>>;
5
+ binaryTargets?: readonly string[];
6
+ };
2
7
  export type MemoryAdapterOptions = {
3
- rooms?: readonly DiscoveredRoom[];
8
+ rooms?: readonly MemoryRoom[];
9
+ pageSize?: number;
4
10
  mdModel?: MdModelIdentity;
5
11
  supportedVersions?: readonly number[];
6
12
  capabilities?: readonly Capability[];
@@ -9,7 +15,7 @@ export type MemoryAdapterOptions = {
9
15
  origins?: readonly string[];
10
16
  };
11
17
  export type MemoryAdapter = Adapter & {
12
- setRooms(rooms: readonly DiscoveredRoom[]): void;
18
+ setRooms(rooms: readonly MemoryRoom[]): void;
13
19
  script(operation: keyof Adapter, answer: unknown): void;
14
20
  };
15
21
  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,EAIL,KAAK,OAAO,EAIZ,KAAK,UAAU,EAEf,KAAK,cAAc,EAGnB,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,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,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAAC;IACjD,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACzD,CAAC;AASF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA2GrF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EAIZ,KAAK,UAAU,EAEf,KAAK,cAAc,EAGnB,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,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,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,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,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACzD,CAAC;AA+BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA0MrF"}