@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.
- package/dist/adapter.d.ts +17 -12
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/bootstrap.d.ts +9 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +47 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/change.d.ts +64 -0
- package/dist/change.d.ts.map +1 -0
- package/dist/change.js +12 -0
- package/dist/change.js.map +1 -0
- package/dist/collection.d.ts +18 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +52 -0
- package/dist/collection.js.map +1 -0
- package/dist/connection.d.ts +30 -5
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +345 -40
- package/dist/connection.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +8 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +105 -24
- package/dist/memory.js.map +1 -1
- package/dist/overlay.d.ts +8 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +139 -0
- package/dist/overlay.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +47 -0
- package/dist/paths.js.map +1 -0
- package/dist/refresh.d.ts +13 -0
- package/dist/refresh.d.ts.map +1 -0
- package/dist/refresh.js +63 -0
- package/dist/refresh.js.map +1 -0
- package/dist/replica.d.ts +19 -0
- package/dist/replica.d.ts.map +1 -0
- package/dist/replica.js +36 -0
- package/dist/replica.js.map +1 -0
- package/dist/save.d.ts +26 -0
- package/dist/save.d.ts.map +1 -0
- package/dist/save.js +496 -0
- package/dist/save.js.map +1 -0
- package/dist/status.d.ts +15 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +29 -0
- package/dist/status.js.map +1 -0
- package/dist/store.d.ts +37 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +116 -0
- package/dist/store.js.map +1 -0
- package/dist/transfer.d.ts +5 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +5 -0
- package/dist/transfer.js.map +1 -0
- package/package.json +5 -1
package/dist/connection.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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')
|
|
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 !==
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
393
|
+
return listed();
|
|
394
|
+
},
|
|
395
|
+
query (request = {}) {
|
|
396
|
+
return visible(request);
|
|
151
397
|
},
|
|
152
|
-
|
|
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 =
|
|
428
|
+
const notify = second;
|
|
155
429
|
roomListeners.add(notify);
|
|
156
|
-
notify(
|
|
430
|
+
notify(listed());
|
|
157
431
|
return ()=>{
|
|
158
432
|
roomListeners.delete(notify);
|
|
159
433
|
};
|
|
160
434
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
470
|
+
querySubscriptions.delete(subscription);
|
|
166
471
|
};
|
|
167
472
|
},
|
|
168
473
|
async reauthorize () {
|
package/dist/connection.js.map
CHANGED
|
@@ -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 {
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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":"
|
|
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
|
|
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
|
|
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;
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|