@agentshouse/mdruntime 0.1.0-alpha.4 → 0.1.0-alpha.40

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 (125) hide show
  1. package/AGENTS.md +191 -0
  2. package/README.md +44 -0
  3. package/dist/adapter.d.ts +174 -18
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +2 -1
  6. package/dist/adapter.js.map +1 -1
  7. package/dist/bootstrap.d.ts +7 -7
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +14 -9
  10. package/dist/bootstrap.js.map +1 -1
  11. package/dist/change-set.d.ts +33 -0
  12. package/dist/change-set.d.ts.map +1 -0
  13. package/dist/change-set.js +89 -0
  14. package/dist/change-set.js.map +1 -0
  15. package/dist/change.d.ts +10 -0
  16. package/dist/change.d.ts.map +1 -1
  17. package/dist/change.js.map +1 -1
  18. package/dist/client.d.ts +74 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +232 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/collection.d.ts +25 -12
  23. package/dist/collection.d.ts.map +1 -1
  24. package/dist/collection.js +113 -31
  25. package/dist/collection.js.map +1 -1
  26. package/dist/connection.d.ts +84 -27
  27. package/dist/connection.d.ts.map +1 -1
  28. package/dist/connection.js +1685 -336
  29. package/dist/connection.js.map +1 -1
  30. package/dist/conversation.d.ts +79 -0
  31. package/dist/conversation.d.ts.map +1 -0
  32. package/dist/conversation.js +593 -0
  33. package/dist/conversation.js.map +1 -0
  34. package/dist/durability.d.ts +9 -0
  35. package/dist/durability.d.ts.map +1 -0
  36. package/dist/durability.js +11 -0
  37. package/dist/durability.js.map +1 -0
  38. package/dist/file.d.ts +20 -0
  39. package/dist/file.d.ts.map +1 -0
  40. package/dist/file.js +149 -0
  41. package/dist/file.js.map +1 -0
  42. package/dist/host.d.ts +14 -0
  43. package/dist/host.d.ts.map +1 -0
  44. package/dist/host.js +211 -0
  45. package/dist/host.js.map +1 -0
  46. package/dist/identity.d.ts +3 -0
  47. package/dist/identity.d.ts.map +1 -0
  48. package/dist/identity.js +23 -0
  49. package/dist/identity.js.map +1 -0
  50. package/dist/index.d.ts +15 -7
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +1 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/memory.d.ts +17 -2
  55. package/dist/memory.d.ts.map +1 -1
  56. package/dist/memory.js +201 -15
  57. package/dist/memory.js.map +1 -1
  58. package/dist/model.d.ts +55 -0
  59. package/dist/model.d.ts.map +1 -0
  60. package/dist/model.js +36 -0
  61. package/dist/model.js.map +1 -0
  62. package/dist/observation.d.ts +25 -0
  63. package/dist/observation.d.ts.map +1 -0
  64. package/dist/observation.js +92 -0
  65. package/dist/observation.js.map +1 -0
  66. package/dist/outcome.d.ts +22 -18
  67. package/dist/outcome.d.ts.map +1 -1
  68. package/dist/outcome.js +1 -11
  69. package/dist/outcome.js.map +1 -1
  70. package/dist/overlay.d.ts +2 -0
  71. package/dist/overlay.d.ts.map +1 -1
  72. package/dist/overlay.js +107 -1
  73. package/dist/overlay.js.map +1 -1
  74. package/dist/paths.d.ts +0 -1
  75. package/dist/paths.d.ts.map +1 -1
  76. package/dist/paths.js +0 -4
  77. package/dist/paths.js.map +1 -1
  78. package/dist/query.d.ts +209 -0
  79. package/dist/query.d.ts.map +1 -0
  80. package/dist/query.js +467 -0
  81. package/dist/query.js.map +1 -0
  82. package/dist/read-side.d.ts +14 -0
  83. package/dist/read-side.d.ts.map +1 -0
  84. package/dist/read-side.js +451 -0
  85. package/dist/read-side.js.map +1 -0
  86. package/dist/refresh.d.ts +3 -3
  87. package/dist/refresh.d.ts.map +1 -1
  88. package/dist/refresh.js +10 -7
  89. package/dist/refresh.js.map +1 -1
  90. package/dist/replica.d.ts +23 -4
  91. package/dist/replica.d.ts.map +1 -1
  92. package/dist/replica.js +224 -13
  93. package/dist/replica.js.map +1 -1
  94. package/dist/room-draft.d.ts +124 -0
  95. package/dist/room-draft.d.ts.map +1 -0
  96. package/dist/room-draft.js +406 -0
  97. package/dist/room-draft.js.map +1 -0
  98. package/dist/rows.d.ts +39 -0
  99. package/dist/rows.d.ts.map +1 -0
  100. package/dist/rows.js +100 -0
  101. package/dist/rows.js.map +1 -0
  102. package/dist/save.d.ts +11 -2
  103. package/dist/save.d.ts.map +1 -1
  104. package/dist/save.js +116 -128
  105. package/dist/save.js.map +1 -1
  106. package/dist/search.d.ts +61 -0
  107. package/dist/search.d.ts.map +1 -0
  108. package/dist/search.js +155 -0
  109. package/dist/search.js.map +1 -0
  110. package/dist/status.d.ts +9 -2
  111. package/dist/status.d.ts.map +1 -1
  112. package/dist/status.js +5 -4
  113. package/dist/status.js.map +1 -1
  114. package/dist/store.d.ts +89 -18
  115. package/dist/store.d.ts.map +1 -1
  116. package/dist/store.js +445 -57
  117. package/dist/store.js.map +1 -1
  118. package/dist/transfer.d.ts +5 -0
  119. package/dist/transfer.d.ts.map +1 -1
  120. package/dist/transfer.js.map +1 -1
  121. package/dist/wire.d.ts +64 -0
  122. package/dist/wire.d.ts.map +1 -0
  123. package/dist/wire.js +144 -0
  124. package/dist/wire.js.map +1 -0
  125. package/package.json +15 -13
@@ -0,0 +1,451 @@
1
+ import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, gt, gte, inArray, isNull, isUndefined, lt, lte, not, or, toArray } from '@tanstack/db';
2
+ import { rowsOf } from './observation.js';
3
+ import { documentKey } from './rows.js';
4
+ function every(expressions) {
5
+ const [first, second, ...rest] = expressions;
6
+ return second === undefined ? first : and(first, second, ...rest);
7
+ }
8
+ function some(expressions) {
9
+ const [first, second, ...rest] = expressions;
10
+ return second === undefined ? first : or(first, second, ...rest);
11
+ }
12
+ function equal(field, value) {
13
+ return or(eq(field, value), inArray(value, field));
14
+ }
15
+ function tested(test, field, size, written) {
16
+ if (test.op === 'eq') return test.value === null ? isNull(field) : equal(field, test.value);
17
+ if (test.op === 'ne') {
18
+ return test.value === null ? not(isNull(field)) : or(isUndefined(field), isNull(field), not(equal(field, test.value)));
19
+ }
20
+ if (test.op === 'in' || test.op === 'nin') {
21
+ const matches = test.values.length === 0 ? inArray(field, []) : some(test.values.map((value)=>value === null ? isNull(field) : equal(field, value)));
22
+ if (test.op === 'in') return matches;
23
+ return some([
24
+ isUndefined(field),
25
+ ...test.values.includes(null) ? [] : [
26
+ isNull(field)
27
+ ],
28
+ not(matches)
29
+ ]);
30
+ }
31
+ if (test.op === 'range') {
32
+ const compare = {
33
+ gt,
34
+ gte,
35
+ lt,
36
+ lte
37
+ };
38
+ return every(test.bounds.map(([operator, bound])=>compare[operator](field, bound)));
39
+ }
40
+ if (test.op === 'all') {
41
+ return every([
42
+ not(isUndefined(size)),
43
+ ...test.values.map((value)=>inArray(value, field))
44
+ ]);
45
+ }
46
+ if (test.op === 'size') return eq(size, test.size);
47
+ return test.exists ? not(isUndefined(written)) : isUndefined(written);
48
+ }
49
+ function conditioned(condition, row) {
50
+ if ('every' in condition) return every(condition.every.map((item)=>conditioned(item, row)));
51
+ if ('some' in condition) return some(condition.some.map((item)=>conditioned(item, row)));
52
+ return tested(condition.test, row.values[condition.field], row.sizes[condition.field], row.fields[condition.field]);
53
+ }
54
+ function scoped(scope, row, rooms) {
55
+ return every([
56
+ eq(row.kind, 'document'),
57
+ ...rooms === null ? [] : [
58
+ inArray(row.room, [
59
+ ...rooms
60
+ ])
61
+ ],
62
+ ...scope.types === null ? [] : [
63
+ inArray(row.type, [
64
+ ...scope.types
65
+ ])
66
+ ],
67
+ ...scope.pathPrefix === null ? [] : [
68
+ inArray(scope.pathPrefix, row.directories)
69
+ ],
70
+ ...scope.where === null ? [] : [
71
+ conditioned(scope.where, row)
72
+ ]
73
+ ]);
74
+ }
75
+ function keyed(key, row) {
76
+ return key.of === 'field' ? row.values[key.field] : row[key.of];
77
+ }
78
+ function live(query) {
79
+ return createLiveQueryCollection({
80
+ query: query,
81
+ startSync: true
82
+ });
83
+ }
84
+ function related(q, rows, scope, field, kept) {
85
+ const matched = kept === 'source' ? 'target' : 'source';
86
+ const from = q.from({
87
+ r: rows
88
+ });
89
+ return from.where(({ r })=>every([
90
+ eq(r.kind, 'reference'),
91
+ ...field === null ? [] : [
92
+ eq(r.field, field)
93
+ ]
94
+ ])).innerJoin({
95
+ m: rows
96
+ }, ({ r, m })=>eq(r[matched], m.key)).where(({ m })=>scoped(scope, m, null)).groupBy(({ r })=>r[kept]).select(({ r })=>({
97
+ key: r[kept]
98
+ }));
99
+ }
100
+ function filtered(q, rows, plan) {
101
+ const from = q.from({
102
+ d: rows
103
+ });
104
+ let query = from.where(({ d })=>scoped(plan.root, d, plan.rooms));
105
+ if (plan.hop !== null) {
106
+ const hop = related(q, rows, plan.hop, plan.hop.field, 'source');
107
+ query = query.innerJoin({
108
+ h: hop
109
+ }, ({ d, h })=>eq(d.key, h.key));
110
+ }
111
+ if (plan.backlinks !== null) {
112
+ const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target');
113
+ query = query.innerJoin({
114
+ k: backlinks
115
+ }, ({ d, k })=>eq(d.key, k.key));
116
+ }
117
+ return query;
118
+ }
119
+ function named(prefix, names, source) {
120
+ return Object.fromEntries(names.map((name, index)=>[
121
+ `${prefix}${index}`,
122
+ source[name]
123
+ ]));
124
+ }
125
+ function documents(q, rows, plan, shape) {
126
+ let query = filtered(q, rows, plan);
127
+ if (shape.sections !== null || shape.preamble || shape.markdown) {
128
+ query = query.leftJoin({
129
+ b: rows
130
+ }, ({ d, b })=>eq(d.body, b.key));
131
+ }
132
+ for (const { key, options } of shape.orderBy){
133
+ query = query.orderBy(({ d })=>keyed(key, d), options);
134
+ }
135
+ if (shape.orderBy.length === 0 && plan.limit !== null) {
136
+ query = query.orderBy(({ d })=>d.key, {
137
+ stringSort: 'lexical'
138
+ });
139
+ }
140
+ if (plan.limit !== null) query = query.limit(plan.limit);
141
+ return query.select(({ d, b })=>({
142
+ room: d.room,
143
+ path: d.path,
144
+ type: d.type,
145
+ ...shape.fields === 'all' ? {
146
+ fields: d.fields
147
+ } : {},
148
+ ...Array.isArray(shape.fields) ? named('field', shape.fields, d.fields) : {},
149
+ ...shape.sections === 'all' ? {
150
+ sections: b.sections
151
+ } : {},
152
+ ...Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {},
153
+ ...shape.preamble ? {
154
+ preamble: b.preamble
155
+ } : {},
156
+ ...shape.markdown ? {
157
+ markdown: b.markdown
158
+ } : {},
159
+ ...shape.backlinks ? {
160
+ backlinks: toArray(backlinked(q, rows, d))
161
+ } : {}
162
+ }));
163
+ }
164
+ function backlinked(q, rows, document) {
165
+ const from = q.from({
166
+ r: rows
167
+ });
168
+ return from.where(({ r })=>eq(r.target, document.key)).orderBy(({ r })=>r.path, {
169
+ stringSort: 'lexical'
170
+ }).orderBy(({ r })=>r.field, {
171
+ stringSort: 'lexical'
172
+ }).select(({ r })=>({
173
+ path: r.path,
174
+ type: r.type,
175
+ field: r.field
176
+ }));
177
+ }
178
+ function groups(q, stage, shape, limit) {
179
+ const keys = shape.groupBy.map((_, index)=>`key${index}`);
180
+ const from = q.from({
181
+ m: stage
182
+ });
183
+ let query = from.groupBy(({ m })=>keys.map((key)=>m[key]));
184
+ for (const { by, direction } of shape.orderBy){
185
+ query = query.orderBy(({ m })=>by === 'count' ? count(m.key) : m[keys[by]], direction);
186
+ }
187
+ if (limit !== null && shape.orderBy.length > 0) query = query.limit(limit);
188
+ return query.select(({ m })=>({
189
+ ...Object.fromEntries(keys.map((key)=>[
190
+ key,
191
+ m[key]
192
+ ])),
193
+ count: count(m.key)
194
+ }));
195
+ }
196
+ function built(rows, plan) {
197
+ const shape = plan.shape;
198
+ if (shape.kind === 'documents') {
199
+ const collection = live((q)=>documents(q, rows, plan, shape));
200
+ return {
201
+ live: collection,
202
+ dispose: ()=>void collection.cleanup()
203
+ };
204
+ }
205
+ const stage = live((q)=>filtered(q, rows, plan).select(({ d })=>({
206
+ key: d.key,
207
+ ...Object.fromEntries(shape.groupBy.map((key, index)=>[
208
+ `key${index}`,
209
+ keyed(key, d)
210
+ ]))
211
+ })));
212
+ const collection = live((q)=>groups(q, stage, shape, plan.limit));
213
+ return {
214
+ live: collection,
215
+ dispose: ()=>{
216
+ void collection.cleanup();
217
+ void stage.cleanup();
218
+ }
219
+ };
220
+ }
221
+ function present(entries) {
222
+ return Object.fromEntries(entries.filter(([, value])=>value !== undefined));
223
+ }
224
+ function part(row, prefix, names, whole) {
225
+ if (names === 'all') return whole;
226
+ return present(names.map((name, index)=>[
227
+ name,
228
+ row[`${prefix}${index}`]
229
+ ]));
230
+ }
231
+ function documentOf(row, shape) {
232
+ if (row.type === null) return {
233
+ room: row.room,
234
+ path: row.path
235
+ };
236
+ return {
237
+ room: row.room,
238
+ path: row.path,
239
+ type: row.type,
240
+ ...shape.fields === null ? {} : {
241
+ fields: part(row, 'field', shape.fields, row.fields)
242
+ },
243
+ ...shape.sections === null ? {} : {
244
+ sections: part(row, 'section', shape.sections, row.sections)
245
+ },
246
+ ...shape.preamble ? {
247
+ preamble: row.preamble
248
+ } : {},
249
+ ...shape.markdown ? {
250
+ markdown: row.markdown
251
+ } : {},
252
+ ...shape.backlinks ? {
253
+ backlinks: row.backlinks.map(({ path, type, field })=>({
254
+ path,
255
+ type,
256
+ field
257
+ }))
258
+ } : {}
259
+ };
260
+ }
261
+ function keyedOf(plan, entries) {
262
+ const shape = plan.shape;
263
+ if (shape.kind === 'documents') {
264
+ return {
265
+ result: structuredClone({
266
+ documents: entries.map(([, row])=>documentOf(row, shape))
267
+ }),
268
+ keys: entries.map(([key])=>key)
269
+ };
270
+ }
271
+ const bounded = shape.orderBy.length === 0 && plan.limit !== null ? entries.slice(0, plan.limit) : entries;
272
+ return {
273
+ result: structuredClone({
274
+ groups: bounded.map(([, row])=>({
275
+ key: shape.groupBy.map((_, index)=>row[`key${index}`]),
276
+ count: row.count
277
+ }))
278
+ }),
279
+ keys: bounded.map(([key])=>key)
280
+ };
281
+ }
282
+ function reconciled(previous, next) {
283
+ const before = rowsOf(previous.result);
284
+ const held = new Map(previous.keys.map((key, index)=>[
285
+ key,
286
+ before[index]
287
+ ]));
288
+ const changed = [];
289
+ const rows = rowsOf(next.result).map((row, index)=>{
290
+ const key = next.keys[index];
291
+ const kept = held.get(key);
292
+ if (kept !== undefined && deepEquals(kept, row)) return kept;
293
+ changed.push([
294
+ key,
295
+ row
296
+ ]);
297
+ return row;
298
+ });
299
+ const present = new Set(next.keys);
300
+ const survivors = previous.keys.filter((key)=>present.has(key));
301
+ const removed = previous.keys.filter((key)=>!present.has(key));
302
+ const moved = survivors.length !== next.keys.length || survivors.some((key, index)=>key !== next.keys[index]);
303
+ if (changed.length === 0 && removed.length === 0 && !moved) return null;
304
+ return {
305
+ keyed: {
306
+ result: 'groups' in next.result ? {
307
+ groups: rows
308
+ } : {
309
+ documents: rows
310
+ },
311
+ keys: next.keys
312
+ },
313
+ change: {
314
+ changed,
315
+ removed,
316
+ order: moved ? next.keys : null
317
+ }
318
+ };
319
+ }
320
+ export function createReadSide() {
321
+ configureIndexDevMode({
322
+ enabled: false
323
+ });
324
+ let sync;
325
+ const rows = createCollection({
326
+ getKey: (row)=>row.key,
327
+ gcTime: 0,
328
+ startSync: true,
329
+ autoIndex: 'eager',
330
+ defaultIndexType: BasicIndex,
331
+ sync: {
332
+ rowUpdateMode: 'full',
333
+ sync: (params)=>{
334
+ sync = params;
335
+ params.markReady();
336
+ }
337
+ }
338
+ });
339
+ const shared = new Map();
340
+ function searched(row) {
341
+ const body = rows.get(row.body);
342
+ return {
343
+ room: row.room,
344
+ path: row.path,
345
+ type: row.type,
346
+ fields: row.fields,
347
+ preamble: body.preamble,
348
+ sections: body.sections
349
+ };
350
+ }
351
+ function publish(entry) {
352
+ const next = reconciled(entry.result, keyedOf(entry.plan, [
353
+ ...entry.built.live.entries()
354
+ ]));
355
+ if (next === null) return;
356
+ entry.result = next.keyed;
357
+ for (const listener of entry.listeners)listener(next.change);
358
+ }
359
+ return {
360
+ apply (set) {
361
+ const next = new Map();
362
+ for (const change of set.documents){
363
+ for (const row of change.before)next.set(row.key, null);
364
+ for (const row of change.after)next.set(row.key, row);
365
+ }
366
+ if (next.size === 0) return;
367
+ sync.begin();
368
+ for (const [key, row] of next){
369
+ if (row === null) {
370
+ if (rows.has(key)) sync.write({
371
+ type: 'delete',
372
+ key
373
+ });
374
+ continue;
375
+ }
376
+ sync.write({
377
+ type: rows.has(key) ? 'update' : 'insert',
378
+ value: row
379
+ });
380
+ }
381
+ sync.commit();
382
+ },
383
+ async query (plan) {
384
+ const { live: collection, dispose } = built(rows, plan);
385
+ try {
386
+ await collection.toArrayWhenReady();
387
+ return keyedOf(plan, [
388
+ ...collection.entries()
389
+ ]).result;
390
+ } finally{
391
+ dispose();
392
+ }
393
+ },
394
+ watch (plan, identity, deliver) {
395
+ let entry = shared.get(identity);
396
+ if (entry === undefined) {
397
+ const created = {
398
+ plan,
399
+ built: built(rows, plan),
400
+ result: undefined,
401
+ listeners: new Set(),
402
+ subscription: null
403
+ };
404
+ created.built.live.on('status:change', ({ status })=>{
405
+ if (status === 'cleaned-up' && created.listeners.size === 0) shared.delete(identity);
406
+ });
407
+ shared.set(identity, created);
408
+ entry = created;
409
+ }
410
+ const observed = entry;
411
+ observed.listeners.add(deliver);
412
+ observed.built.live.onFirstReady(()=>{
413
+ if (!observed.listeners.has(deliver)) return;
414
+ if (observed.subscription === null) {
415
+ observed.result = keyedOf(observed.plan, [
416
+ ...observed.built.live.entries()
417
+ ]);
418
+ observed.subscription = observed.built.live.subscribeChanges(()=>{
419
+ publish(observed);
420
+ }, {
421
+ includeInitialState: false
422
+ });
423
+ }
424
+ deliver(observed.result);
425
+ });
426
+ return ()=>{
427
+ if (!observed.listeners.delete(deliver) || observed.listeners.size > 0) return;
428
+ observed.subscription?.unsubscribe();
429
+ observed.subscription = null;
430
+ };
431
+ },
432
+ documents () {
433
+ return rows.toArray.filter((row)=>row.kind === 'document' && row.type !== null).map(searched);
434
+ },
435
+ document (room, path) {
436
+ const row = rows.get(documentKey(room, path));
437
+ return row === undefined || row.type === null ? null : searched(row);
438
+ },
439
+ close () {
440
+ for (const entry of shared.values()){
441
+ entry.listeners.clear();
442
+ entry.subscription?.unsubscribe();
443
+ entry.built.dispose();
444
+ }
445
+ shared.clear();
446
+ void rows.cleanup();
447
+ }
448
+ };
449
+ }
450
+
451
+ //# sourceMappingURL=read-side.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/read-side.ts"],"sourcesContent":["import {\n and,\n BasicIndex,\n configureIndexDevMode,\n count,\n createCollection,\n createLiveQueryCollection,\n deepEquals,\n eq,\n gt,\n gte,\n inArray,\n isNull,\n isUndefined,\n lt,\n lte,\n not,\n or,\n toArray,\n type Collection,\n type Context,\n type InitialQueryBuilder,\n type QueryBuilder,\n type Ref,\n type SyncConfig,\n} from '@tanstack/db';\nimport type { ChangeSet } from './change-set.js';\nimport { rowsOf, type KeyedResult, type QueryChange, type RowKey } from './observation.js';\nimport type {\n Condition,\n Direction,\n DocumentShape,\n GroupShape,\n KeyPlan,\n OrderOptions,\n Plan,\n QueryDocument,\n QueryGroup,\n QueryResult,\n Scope,\n Test,\n Value,\n} from './query.js';\nimport { documentKey, type Row } from './rows.js';\nimport type { SearchedDocument } from './search.js';\n\ntype Stored = {\n key: string;\n kind: string;\n room: string;\n path: string;\n type: string | null;\n body: string;\n source: string;\n target: string;\n field: string;\n fields: Readonly<Record<string, unknown>>;\n values: Readonly<Record<string, unknown>>;\n sizes: Readonly<Record<string, number>>;\n directories: readonly string[];\n preamble: string;\n sections: Readonly<Record<string, string>>;\n markdown: string;\n} & Readonly<Record<string, unknown>>;\n\ntype Reference = Ref<Stored>;\n\ntype Field = Reference['values'][string];\n\ntype Size = Reference['sizes'][string];\n\ntype Refs = Readonly<Record<string, Reference>>;\n\ntype Expression = ReturnType<typeof eq>;\n\ntype Builder = {\n where(callback: (refs: Refs) => Expression): Builder;\n innerJoin(source: Readonly<Record<string, unknown>>, on: (refs: Refs) => Expression): Builder;\n groupBy(callback: (refs: Refs) => unknown): Builder;\n orderBy(callback: (refs: Refs) => unknown, options: Direction | OrderOptions): Builder;\n limit(count: number): Builder;\n select(callback: (refs: Refs) => object): object;\n};\n\ntype Live = Collection<Stored, string | number>;\n\ntype Built = { live: Live; dispose(): void };\n\ntype Shared = {\n plan: Plan;\n built: Built;\n result: KeyedResult | undefined;\n listeners: Set<(message: KeyedResult | QueryChange) => void>;\n subscription: { unsubscribe(): void } | null;\n};\n\nexport type ReadSide = {\n apply(set: ChangeSet): void;\n query(plan: Plan): Promise<QueryResult>;\n watch(\n plan: Plan,\n identity: string,\n deliver: (message: KeyedResult | QueryChange) => void,\n ): () => void;\n documents(): readonly SearchedDocument[];\n document(room: string, path: string): SearchedDocument | null;\n close(): void;\n};\n\nfunction every(expressions: readonly Expression[]): Expression {\n const [first, second, ...rest] = expressions;\n return second === undefined ? first : and(first, second, ...rest);\n}\n\nfunction some(expressions: readonly Expression[]): Expression {\n const [first, second, ...rest] = expressions;\n return second === undefined ? first : or(first, second, ...rest);\n}\n\nfunction equal(field: Field, value: Exclude<Value, null>): Expression {\n return or(eq(field, value), inArray(value, field));\n}\n\nfunction tested(test: Test, field: Field, size: Size, written: Field): Expression {\n if (test.op === 'eq') return test.value === null ? isNull(field) : equal(field, test.value);\n if (test.op === 'ne') {\n return test.value === null\n ? not(isNull(field))\n : or(isUndefined(field), isNull(field), not(equal(field, test.value)));\n }\n if (test.op === 'in' || test.op === 'nin') {\n const matches =\n test.values.length === 0\n ? inArray(field, [])\n : some(test.values.map((value) => (value === null ? isNull(field) : equal(field, value))));\n if (test.op === 'in') return matches;\n return some([\n isUndefined(field),\n ...(test.values.includes(null) ? [] : [isNull(field)]),\n not(matches),\n ]);\n }\n if (test.op === 'range') {\n const compare = { gt, gte, lt, lte };\n return every(test.bounds.map(([operator, bound]) => compare[operator](field, bound)));\n }\n if (test.op === 'all') {\n return every([not(isUndefined(size)), ...test.values.map((value) => inArray(value, field))]);\n }\n if (test.op === 'size') return eq(size, test.size);\n return test.exists ? not(isUndefined(written)) : isUndefined(written);\n}\n\nfunction conditioned(condition: Condition, row: Reference): Expression {\n if ('every' in condition) return every(condition.every.map((item) => conditioned(item, row)));\n if ('some' in condition) return some(condition.some.map((item) => conditioned(item, row)));\n return tested(\n condition.test,\n row.values[condition.field],\n row.sizes[condition.field],\n row.fields[condition.field],\n );\n}\n\nfunction scoped(scope: Scope, row: Reference, rooms: readonly string[] | null): Expression {\n return every([\n eq(row.kind, 'document'),\n ...(rooms === null ? [] : [inArray(row.room, [...rooms])]),\n ...(scope.types === null ? [] : [inArray(row.type as Reference['room'], [...scope.types])]),\n ...(scope.pathPrefix === null ? [] : [inArray(scope.pathPrefix, row.directories)]),\n ...(scope.where === null ? [] : [conditioned(scope.where, row)]),\n ]);\n}\n\nfunction keyed(key: KeyPlan, row: Reference): Field | Reference['room'] | null {\n return key.of === 'field' ? row.values[key.field] : row[key.of];\n}\n\nfunction live(query: (q: InitialQueryBuilder) => object): Live {\n return createLiveQueryCollection({\n query: query as (q: InitialQueryBuilder) => QueryBuilder<Context>,\n startSync: true,\n }) as unknown as Live;\n}\n\nfunction related(\n q: InitialQueryBuilder,\n rows: Collection<Stored, string>,\n scope: Scope,\n field: string | null,\n kept: 'source' | 'target',\n): object {\n const matched = kept === 'source' ? 'target' : 'source';\n const from: Builder = q.from({ r: rows });\n return from\n .where(({ r }) =>\n every([eq(r.kind, 'reference'), ...(field === null ? [] : [eq(r.field, field)])]),\n )\n .innerJoin({ m: rows }, ({ r, m }) => eq(r[matched], m.key))\n .where(({ m }) => scoped(scope, m, null))\n .groupBy(({ r }) => r[kept])\n .select(({ r }) => ({ key: r[kept] }));\n}\n\nfunction filtered(q: InitialQueryBuilder, rows: Collection<Stored, string>, plan: Plan): Builder {\n const from: Builder = q.from({ d: rows });\n let query = from.where(({ d }) => scoped(plan.root, d, plan.rooms));\n if (plan.hop !== null) {\n const hop = related(q, rows, plan.hop, plan.hop.field, 'source');\n query = query.innerJoin({ h: hop }, ({ d, h }) => eq(d.key, h.key));\n }\n if (plan.backlinks !== null) {\n const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target');\n query = query.innerJoin({ k: backlinks }, ({ d, k }) => eq(d.key, k.key));\n }\n return query;\n}\n\nfunction named<T>(prefix: string, names: readonly string[], source: Readonly<Record<string, T>>) {\n return Object.fromEntries(names.map((name, index) => [`${prefix}${index}`, source[name]]));\n}\n\nfunction documents(\n q: InitialQueryBuilder,\n rows: Collection<Stored, string>,\n plan: Plan,\n shape: DocumentShape,\n): object {\n let query = filtered(q, rows, plan);\n if (shape.sections !== null || shape.preamble || shape.markdown) {\n query = (\n query as Builder & {\n leftJoin(\n source: Readonly<Record<string, unknown>>,\n on: (refs: Refs) => Expression,\n ): Builder;\n }\n ).leftJoin({ b: rows }, ({ d, b }) => eq(d.body, b.key));\n }\n for (const { key, options } of shape.orderBy) {\n query = query.orderBy(({ d }) => keyed(key, d), options);\n }\n if (shape.orderBy.length === 0 && plan.limit !== null) {\n query = query.orderBy(({ d }) => d.key, { stringSort: 'lexical' });\n }\n if (plan.limit !== null) query = query.limit(plan.limit);\n return query.select(({ d, b }) => ({\n room: d.room,\n path: d.path,\n type: d.type,\n ...(shape.fields === 'all' ? { fields: d.fields } : {}),\n ...(Array.isArray(shape.fields) ? named('field', shape.fields, d.fields) : {}),\n ...(shape.sections === 'all' ? { sections: b.sections } : {}),\n ...(Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {}),\n ...(shape.preamble ? { preamble: b.preamble } : {}),\n ...(shape.markdown ? { markdown: b.markdown } : {}),\n ...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d)) } : {}),\n }));\n}\n\nfunction backlinked(q: InitialQueryBuilder, rows: Collection<Stored, string>, document: Reference) {\n const from: Builder = q.from({ r: rows });\n return from\n .where(({ r }) => eq(r.target, document.key))\n .orderBy(({ r }) => r.path, { stringSort: 'lexical' })\n .orderBy(({ r }) => r.field, { stringSort: 'lexical' })\n .select(({ r }) => ({ path: r.path, type: r.type, field: r.field })) as QueryBuilder<Context>;\n}\n\nfunction groups(q: InitialQueryBuilder, stage: Live, shape: GroupShape, limit: number | null) {\n const keys = shape.groupBy.map((_, index) => `key${index}`);\n const from: Builder = q.from({ m: stage });\n let query = from.groupBy(({ m }) => keys.map((key) => m[key]));\n for (const { by, direction } of shape.orderBy) {\n query = query.orderBy(({ m }) => (by === 'count' ? count(m.key) : m[keys[by]]), direction);\n }\n if (limit !== null && shape.orderBy.length > 0) query = query.limit(limit);\n return query.select(({ m }) => ({\n ...Object.fromEntries(keys.map((key) => [key, m[key]])),\n count: count(m.key),\n }));\n}\n\nfunction built(rows: Collection<Stored, string>, plan: Plan): Built {\n const shape = plan.shape;\n if (shape.kind === 'documents') {\n const collection = live((q) => documents(q, rows, plan, shape));\n return { live: collection, dispose: () => void collection.cleanup() };\n }\n const stage = live((q) =>\n filtered(q, rows, plan).select(({ d }) => ({\n key: d.key,\n ...Object.fromEntries(shape.groupBy.map((key, index) => [`key${index}`, keyed(key, d)])),\n })),\n );\n const collection = live((q) => groups(q, stage, shape, plan.limit));\n return {\n live: collection,\n dispose: () => {\n void collection.cleanup();\n void stage.cleanup();\n },\n };\n}\n\nfunction present(entries: readonly (readonly [string, unknown])[]) {\n return Object.fromEntries(entries.filter(([, value]) => value !== undefined));\n}\n\nfunction part(\n row: Readonly<Record<string, unknown>>,\n prefix: string,\n names: 'all' | readonly string[],\n whole: unknown,\n) {\n if (names === 'all') return whole;\n return present(names.map((name, index) => [name, row[`${prefix}${index}`]] as const));\n}\n\nfunction documentOf(row: Readonly<Record<string, unknown>>, shape: DocumentShape): QueryDocument {\n if (row.type === null) return { room: row.room as string, path: row.path as string };\n return {\n room: row.room as string,\n path: row.path as string,\n type: row.type as string,\n ...(shape.fields === null\n ? {}\n : { fields: part(row, 'field', shape.fields, row.fields) as QueryDocument['fields'] }),\n ...(shape.sections === null\n ? {}\n : {\n sections: part(row, 'section', shape.sections, row.sections) as QueryDocument['sections'],\n }),\n ...(shape.preamble ? { preamble: row.preamble as string } : {}),\n ...(shape.markdown ? { markdown: row.markdown as string } : {}),\n ...(shape.backlinks\n ? {\n backlinks: (row.backlinks as readonly Readonly<Record<string, string>>[]).map(\n ({ path, type, field }) => ({ path, type, field }),\n ),\n }\n : {}),\n };\n}\n\nfunction keyedOf(\n plan: Plan,\n entries: readonly (readonly [RowKey, Readonly<Record<string, unknown>>])[],\n): KeyedResult {\n const shape = plan.shape;\n if (shape.kind === 'documents') {\n return {\n result: structuredClone({ documents: entries.map(([, row]) => documentOf(row, shape)) }),\n keys: entries.map(([key]) => key),\n };\n }\n const bounded =\n shape.orderBy.length === 0 && plan.limit !== null ? entries.slice(0, plan.limit) : entries;\n return {\n result: structuredClone({\n groups: bounded.map(([, row]) => ({\n key: shape.groupBy.map((_, index) => row[`key${index}`]),\n count: row.count as number,\n })),\n }),\n keys: bounded.map(([key]) => key),\n };\n}\n\nfunction reconciled(\n previous: KeyedResult,\n next: KeyedResult,\n): { keyed: KeyedResult; change: QueryChange } | null {\n const before = rowsOf(previous.result);\n const held = new Map(previous.keys.map((key, index) => [key, before[index]]));\n const changed: (readonly [RowKey, QueryDocument | QueryGroup])[] = [];\n const rows = rowsOf(next.result).map((row, index) => {\n const key = next.keys[index];\n const kept = held.get(key);\n if (kept !== undefined && deepEquals(kept, row)) return kept;\n changed.push([key, row]);\n return row;\n });\n const present = new Set(next.keys);\n const survivors = previous.keys.filter((key) => present.has(key));\n const removed = previous.keys.filter((key) => !present.has(key));\n const moved =\n survivors.length !== next.keys.length ||\n survivors.some((key, index) => key !== next.keys[index]);\n if (changed.length === 0 && removed.length === 0 && !moved) return null;\n return {\n keyed: {\n result:\n 'groups' in next.result\n ? { groups: rows as readonly QueryGroup[] }\n : { documents: rows as readonly QueryDocument[] },\n keys: next.keys,\n },\n change: { changed, removed, order: moved ? next.keys : null },\n };\n}\n\nexport function createReadSide(): ReadSide {\n configureIndexDevMode({ enabled: false });\n let sync!: Parameters<SyncConfig<Stored, string>['sync']>[0];\n const rows = createCollection<Stored, string>({\n getKey: (row) => row.key,\n gcTime: 0,\n startSync: true,\n autoIndex: 'eager',\n defaultIndexType: BasicIndex,\n sync: {\n rowUpdateMode: 'full',\n sync: (params) => {\n sync = params;\n params.markReady();\n },\n },\n });\n const shared = new Map<string, Shared>();\n\n function searched(row: Stored): SearchedDocument {\n const body = rows.get(row.body) as Stored;\n return {\n room: row.room,\n path: row.path,\n type: row.type as string,\n fields: row.fields,\n preamble: body.preamble,\n sections: body.sections,\n };\n }\n\n function publish(entry: Shared) {\n const next = reconciled(\n entry.result as KeyedResult,\n keyedOf(entry.plan, [...entry.built.live.entries()]),\n );\n if (next === null) return;\n entry.result = next.keyed;\n for (const listener of entry.listeners) listener(next.change);\n }\n\n return {\n apply(set) {\n const next = new Map<string, Row | null>();\n for (const change of set.documents) {\n for (const row of change.before) next.set(row.key, null);\n for (const row of change.after) next.set(row.key, row);\n }\n if (next.size === 0) return;\n sync.begin();\n for (const [key, row] of next) {\n if (row === null) {\n if (rows.has(key)) sync.write({ type: 'delete', key });\n continue;\n }\n sync.write({ type: rows.has(key) ? 'update' : 'insert', value: row as Stored });\n }\n sync.commit();\n },\n async query(plan) {\n const { live: collection, dispose } = built(rows, plan);\n try {\n await collection.toArrayWhenReady();\n return keyedOf(plan, [...collection.entries()]).result;\n } finally {\n dispose();\n }\n },\n watch(plan, identity, deliver) {\n let entry = shared.get(identity);\n if (entry === undefined) {\n const created: Shared = {\n plan,\n built: built(rows, plan),\n result: undefined,\n listeners: new Set(),\n subscription: null,\n };\n created.built.live.on('status:change', ({ status }) => {\n if (status === 'cleaned-up' && created.listeners.size === 0) shared.delete(identity);\n });\n shared.set(identity, created);\n entry = created;\n }\n const observed = entry;\n observed.listeners.add(deliver);\n observed.built.live.onFirstReady(() => {\n if (!observed.listeners.has(deliver)) return;\n if (observed.subscription === null) {\n observed.result = keyedOf(observed.plan, [...observed.built.live.entries()]);\n observed.subscription = observed.built.live.subscribeChanges(\n () => {\n publish(observed);\n },\n { includeInitialState: false },\n );\n }\n deliver(observed.result as KeyedResult);\n });\n return () => {\n if (!observed.listeners.delete(deliver) || observed.listeners.size > 0) return;\n observed.subscription?.unsubscribe();\n observed.subscription = null;\n };\n },\n documents() {\n return rows.toArray\n .filter((row) => row.kind === 'document' && row.type !== null)\n .map(searched);\n },\n document(room, path) {\n const row = rows.get(documentKey(room, path));\n return row === undefined || row.type === null ? null : searched(row);\n },\n close() {\n for (const entry of shared.values()) {\n entry.listeners.clear();\n entry.subscription?.unsubscribe();\n entry.built.dispose();\n }\n shared.clear();\n void rows.cleanup();\n },\n };\n}\n"],"names":["and","BasicIndex","configureIndexDevMode","count","createCollection","createLiveQueryCollection","deepEquals","eq","gt","gte","inArray","isNull","isUndefined","lt","lte","not","or","toArray","rowsOf","documentKey","every","expressions","first","second","rest","undefined","some","equal","field","value","tested","test","size","written","op","matches","values","length","map","includes","compare","bounds","operator","bound","exists","conditioned","condition","row","item","sizes","fields","scoped","scope","rooms","kind","room","types","type","pathPrefix","directories","where","keyed","key","of","live","query","startSync","related","q","rows","kept","matched","from","r","innerJoin","m","groupBy","select","filtered","plan","d","root","hop","h","backlinks","k","named","prefix","names","source","Object","fromEntries","name","index","documents","shape","sections","preamble","markdown","leftJoin","b","body","options","orderBy","limit","stringSort","path","Array","isArray","backlinked","document","target","groups","stage","keys","_","by","direction","built","collection","dispose","cleanup","present","entries","filter","part","whole","documentOf","keyedOf","result","structuredClone","bounded","slice","reconciled","previous","next","before","held","Map","changed","get","push","Set","survivors","has","removed","moved","change","order","createReadSide","enabled","sync","getKey","gcTime","autoIndex","defaultIndexType","rowUpdateMode","params","markReady","shared","searched","publish","entry","listener","listeners","apply","set","after","begin","write","commit","toArrayWhenReady","watch","identity","deliver","created","subscription","on","status","delete","observed","add","onFirstReady","subscribeChanges","includeInitialState","unsubscribe","close","clear"],"mappings":"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"}
package/dist/refresh.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Adapter, AdapterFailure, Authorization } from './adapter.js';
2
2
  import { type ConfirmedLayer } from './replica.js';
3
- import { type Unconfirmed } from './transfer.js';
3
+ import { type Refused, type Unconfirmed } from './transfer.js';
4
4
  export type RefreshOutcome = {
5
5
  kind: 'still-current';
6
6
  } | {
@@ -8,6 +8,6 @@ export type RefreshOutcome = {
8
8
  confirmed: ConfirmedLayer;
9
9
  } | {
10
10
  kind: 'beyond-horizon';
11
- } | Unconfirmed | AdapterFailure;
12
- export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer): Promise<RefreshOutcome>;
11
+ } | Unconfirmed | Refused | AdapterFailure;
12
+ export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer, continuing: () => boolean): Promise<RefreshOutcome>;
13
13
  //# sourceMappingURL=refresh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,cAAc,CAAC,CA0CzB"}
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,cAAc,CAAC,CAuDzB"}
package/dist/refresh.js CHANGED
@@ -1,10 +1,11 @@
1
- import { readConfirmed } from './replica.js';
1
+ import { readStaged } from './replica.js';
2
2
  import { unconfirmed } from './transfer.js';
3
- export async function refreshRoom(adapter, authorization, confirmed) {
3
+ export async function refreshRoom(adapter, authorization, confirmed, continuing) {
4
4
  const locator = confirmed.record.locator;
5
5
  const fromRoomVersion = confirmed.record.roomVersion;
6
6
  const first = await adapter.refresh(authorization, {
7
7
  locator,
8
+ selection: confirmed.record.replica.selection,
8
9
  fromRoomVersion
9
10
  });
10
11
  if (first.kind !== 'net-advancement') return first;
@@ -34,8 +35,10 @@ export async function refreshRoom(adapter, authorization, confirmed) {
34
35
  stage(first);
35
36
  let pageToken = first.pageToken;
36
37
  while(pageToken !== undefined){
38
+ if (!continuing()) return unconfirmed;
37
39
  const page = await adapter.refresh(authorization, {
38
40
  locator,
41
+ selection: confirmed.record.replica.selection,
39
42
  fromRoomVersion,
40
43
  pageToken
41
44
  });
@@ -45,7 +48,7 @@ export async function refreshRoom(adapter, authorization, confirmed) {
45
48
  stage(page);
46
49
  pageToken = page.pageToken;
47
50
  }
48
- const advanced = readConfirmed({
51
+ const staged = readStaged({
49
52
  ...confirmed.record,
50
53
  roomVersion,
51
54
  documents,
@@ -53,11 +56,11 @@ export async function refreshRoom(adapter, authorization, confirmed) {
53
56
  ...binaryTargets
54
57
  ].sort(),
55
58
  revisions
56
- });
57
- return advanced === null ? unconfirmed : {
59
+ }, confirmed);
60
+ return staged.kind === 'staged' ? {
58
61
  kind: 'advanced',
59
- confirmed: advanced
60
- };
62
+ confirmed: staged.confirmed
63
+ } : staged;
61
64
  }
62
65
 
63
66
  //# sourceMappingURL=refresh.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/refresh.ts"],"sourcesContent":["import type { Adapter, AdapterFailure, Authorization, RefreshPage } from './adapter.js';\nimport { readConfirmed, type ConfirmedLayer } from './replica.js';\nimport { unconfirmed, type Unconfirmed } from './transfer.js';\n\nexport type RefreshOutcome =\n | { kind: 'still-current' }\n | { kind: 'advanced'; confirmed: ConfirmedLayer }\n | { kind: 'beyond-horizon' }\n | Unconfirmed\n | AdapterFailure;\n\nexport async function refreshRoom(\n adapter: Adapter,\n authorization: Authorization,\n confirmed: ConfirmedLayer,\n): Promise<RefreshOutcome> {\n const locator = confirmed.record.locator;\n const fromRoomVersion = confirmed.record.roomVersion;\n const first = await adapter.refresh(authorization, { locator, fromRoomVersion });\n if (first.kind !== 'net-advancement') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...confirmed.record.documents };\n const revisions: Record<string, string> = { ...confirmed.record.revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n const stage = (page: RefreshPage) => {\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const path of Object.keys(page.documents)) binaryTargets.delete(path);\n for (const target of page.binaryTargets) {\n delete documents[target];\n delete revisions[target];\n binaryTargets.add(target);\n }\n for (const path of page.removals) {\n delete documents[path];\n delete revisions[path];\n binaryTargets.delete(path);\n }\n };\n stage(first);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n const page = await adapter.refresh(authorization, { locator, fromRoomVersion, pageToken });\n if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;\n if (page.kind !== 'net-advancement') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n stage(page);\n pageToken = page.pageToken;\n }\n const advanced = readConfirmed({\n ...confirmed.record,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n });\n return advanced === null ? unconfirmed : { kind: 'advanced', confirmed: advanced };\n}\n"],"names":["readConfirmed","unconfirmed","refreshRoom","adapter","authorization","confirmed","locator","record","fromRoomVersion","roomVersion","first","refresh","kind","documents","revisions","binaryTargets","Set","stage","page","Object","assign","path","keys","delete","target","add","removals","pageToken","undefined","advanced","sort"],"mappings":"AACA,SAASA,aAAa,QAA6B,eAAe;AAClE,SAASC,WAAW,QAA0B,gBAAgB;AAS9D,OAAO,eAAeC,YACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,SAAyB;IAEzB,MAAMC,UAAUD,UAAUE,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBH,UAAUE,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMP,QAAQQ,OAAO,CAACP,eAAe;QAAEE;QAASE;IAAgB;IAC9E,IAAIE,MAAME,IAAI,KAAK,mBAAmB,OAAOF;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMI,YAAoC;QAAE,GAAGR,UAAUE,MAAM,CAACM,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGT,UAAUE,MAAM,CAACO,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAIX,UAAUE,MAAM,CAACQ,aAAa;IAC5D,MAAME,QAAQ,CAACC;QACbC,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvCM,OAAOC,MAAM,CAACN,WAAWI,KAAKJ,SAAS;QACvC,KAAK,MAAMO,QAAQF,OAAOG,IAAI,CAACJ,KAAKL,SAAS,EAAGE,cAAcQ,MAAM,CAACF;QACrE,KAAK,MAAMG,UAAUN,KAAKH,aAAa,CAAE;YACvC,OAAOF,SAAS,CAACW,OAAO;YACxB,OAAOV,SAAS,CAACU,OAAO;YACxBT,cAAcU,GAAG,CAACD;QACpB;QACA,KAAK,MAAMH,QAAQH,KAAKQ,QAAQ,CAAE;YAChC,OAAOb,SAAS,CAACQ,KAAK;YACtB,OAAOP,SAAS,CAACO,KAAK;YACtBN,cAAcQ,MAAM,CAACF;QACvB;IACF;IACAJ,MAAMP;IACN,IAAIiB,YAAYjB,MAAMiB,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,MAAMV,OAAO,MAAMf,QAAQQ,OAAO,CAACP,eAAe;YAAEE;YAASE;YAAiBmB;QAAU;QACxF,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOX;QAC5E,IAAIiB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKT,WAAW,KAAKA,aAAa,OAAOR;QAC7CgB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,WAAW7B,cAAc;QAC7B,GAAGK,UAAUE,MAAM;QACnBE;QACAI;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF;IACA,OAAOe,aAAa,OAAO5B,cAAc;QAAEW,MAAM;QAAYP,WAAWwB;IAAS;AACnF"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/refresh.ts"],"sourcesContent":["import type { Adapter, AdapterFailure, Authorization, RefreshPage } from './adapter.js';\nimport { readStaged, type ConfirmedLayer } from './replica.js';\nimport { unconfirmed, type Refused, type Unconfirmed } from './transfer.js';\n\nexport type RefreshOutcome =\n | { kind: 'still-current' }\n | { kind: 'advanced'; confirmed: ConfirmedLayer }\n | { kind: 'beyond-horizon' }\n | Unconfirmed\n | Refused\n | AdapterFailure;\n\nexport async function refreshRoom(\n adapter: Adapter,\n authorization: Authorization,\n confirmed: ConfirmedLayer,\n continuing: () => boolean,\n): Promise<RefreshOutcome> {\n const locator = confirmed.record.locator;\n const fromRoomVersion = confirmed.record.roomVersion;\n const first = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n });\n if (first.kind !== 'net-advancement') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...confirmed.record.documents };\n const revisions: Record<string, string> = { ...confirmed.record.revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n const stage = (page: RefreshPage) => {\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const path of Object.keys(page.documents)) binaryTargets.delete(path);\n for (const target of page.binaryTargets) {\n delete documents[target];\n delete revisions[target];\n binaryTargets.add(target);\n }\n for (const path of page.removals) {\n delete documents[path];\n delete revisions[path];\n binaryTargets.delete(path);\n }\n };\n stage(first);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n if (!continuing()) return unconfirmed;\n const page = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n pageToken,\n });\n if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;\n if (page.kind !== 'net-advancement') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n stage(page);\n pageToken = page.pageToken;\n }\n const staged = readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n },\n confirmed,\n );\n return staged.kind === 'staged' ? { kind: 'advanced', confirmed: staged.confirmed } : staged;\n}\n"],"names":["readStaged","unconfirmed","refreshRoom","adapter","authorization","confirmed","continuing","locator","record","fromRoomVersion","roomVersion","first","refresh","selection","replica","kind","documents","revisions","binaryTargets","Set","stage","page","Object","assign","path","keys","delete","target","add","removals","pageToken","undefined","staged","sort"],"mappings":"AACA,SAASA,UAAU,QAA6B,eAAe;AAC/D,SAASC,WAAW,QAAwC,gBAAgB;AAU5E,OAAO,eAAeC,YACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,SAAyB,EACzBC,UAAyB;IAEzB,MAAMC,UAAUF,UAAUG,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBJ,UAAUG,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMR,QAAQS,OAAO,CAACR,eAAe;QACjDG;QACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;QAC7CJ;IACF;IACA,IAAIE,MAAMI,IAAI,KAAK,mBAAmB,OAAOJ;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMM,YAAoC;QAAE,GAAGX,UAAUG,MAAM,CAACQ,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGZ,UAAUG,MAAM,CAACS,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAId,UAAUG,MAAM,CAACU,aAAa;IAC5D,MAAME,QAAQ,CAACC;QACbC,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvCM,OAAOC,MAAM,CAACN,WAAWI,KAAKJ,SAAS;QACvC,KAAK,MAAMO,QAAQF,OAAOG,IAAI,CAACJ,KAAKL,SAAS,EAAGE,cAAcQ,MAAM,CAACF;QACrE,KAAK,MAAMG,UAAUN,KAAKH,aAAa,CAAE;YACvC,OAAOF,SAAS,CAACW,OAAO;YACxB,OAAOV,SAAS,CAACU,OAAO;YACxBT,cAAcU,GAAG,CAACD;QACpB;QACA,KAAK,MAAMH,QAAQH,KAAKQ,QAAQ,CAAE;YAChC,OAAOb,SAAS,CAACQ,KAAK;YACtB,OAAOP,SAAS,CAACO,KAAK;YACtBN,cAAcQ,MAAM,CAACF;QACvB;IACF;IACAJ,MAAMT;IACN,IAAImB,YAAYnB,MAAMmB,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,IAAI,CAACzB,cAAc,OAAOL;QAC1B,MAAMoB,OAAO,MAAMlB,QAAQS,OAAO,CAACR,eAAe;YAChDG;YACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;YAC7CJ;YACAqB;QACF;QACA,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOd;QAC5E,IAAIoB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKX,WAAW,KAAKA,aAAa,OAAOT;QAC7CmB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,SAAShC,WACb;QACE,GAAGK,UAAUG,MAAM;QACnBE;QACAM;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF,GACAZ;IAEF,OAAO2B,OAAOjB,IAAI,KAAK,WAAW;QAAEA,MAAM;QAAYV,WAAW2B,OAAO3B,SAAS;IAAC,IAAI2B;AACxF"}