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

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 (128) hide show
  1. package/AGENTS.md +178 -0
  2. package/dist/adapter.d.ts +150 -18
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +2 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/bootstrap.d.ts +7 -7
  7. package/dist/bootstrap.d.ts.map +1 -1
  8. package/dist/bootstrap.js +13 -9
  9. package/dist/bootstrap.js.map +1 -1
  10. package/dist/change-set.d.ts +33 -0
  11. package/dist/change-set.d.ts.map +1 -0
  12. package/dist/change-set.js +89 -0
  13. package/dist/change-set.js.map +1 -0
  14. package/dist/change.d.ts +10 -0
  15. package/dist/change.d.ts.map +1 -1
  16. package/dist/change.js.map +1 -1
  17. package/dist/client.d.ts +72 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +231 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/collection.d.ts +22 -12
  22. package/dist/collection.d.ts.map +1 -1
  23. package/dist/collection.js +88 -30
  24. package/dist/collection.js.map +1 -1
  25. package/dist/connection.d.ts +90 -20
  26. package/dist/connection.d.ts.map +1 -1
  27. package/dist/connection.js +1776 -194
  28. package/dist/connection.js.map +1 -1
  29. package/dist/conversation.d.ts +72 -0
  30. package/dist/conversation.d.ts.map +1 -0
  31. package/dist/conversation.js +529 -0
  32. package/dist/conversation.js.map +1 -0
  33. package/dist/durability.d.ts +9 -0
  34. package/dist/durability.d.ts.map +1 -0
  35. package/dist/durability.js +11 -0
  36. package/dist/durability.js.map +1 -0
  37. package/dist/file.d.ts +20 -0
  38. package/dist/file.d.ts.map +1 -0
  39. package/dist/file.js +149 -0
  40. package/dist/file.js.map +1 -0
  41. package/dist/host.d.ts +13 -0
  42. package/dist/host.d.ts.map +1 -0
  43. package/dist/host.js +205 -0
  44. package/dist/host.js.map +1 -0
  45. package/dist/identity.d.ts +3 -0
  46. package/dist/identity.d.ts.map +1 -0
  47. package/dist/identity.js +23 -0
  48. package/dist/identity.js.map +1 -0
  49. package/dist/index.d.ts +15 -6
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +1 -0
  52. package/dist/index.js.map +1 -1
  53. package/dist/log.d.ts +5 -0
  54. package/dist/log.d.ts.map +1 -0
  55. package/dist/log.js +15 -0
  56. package/dist/log.js.map +1 -0
  57. package/dist/memory.d.ts +17 -2
  58. package/dist/memory.d.ts.map +1 -1
  59. package/dist/memory.js +201 -15
  60. package/dist/memory.js.map +1 -1
  61. package/dist/model.d.ts +56 -0
  62. package/dist/model.d.ts.map +1 -0
  63. package/dist/model.js +37 -0
  64. package/dist/model.js.map +1 -0
  65. package/dist/observation.d.ts +25 -0
  66. package/dist/observation.d.ts.map +1 -0
  67. package/dist/observation.js +92 -0
  68. package/dist/observation.js.map +1 -0
  69. package/dist/outcome.d.ts +34 -0
  70. package/dist/outcome.d.ts.map +1 -0
  71. package/dist/outcome.js +3 -0
  72. package/dist/outcome.js.map +1 -0
  73. package/dist/overlay.d.ts +2 -0
  74. package/dist/overlay.d.ts.map +1 -1
  75. package/dist/overlay.js +107 -1
  76. package/dist/overlay.js.map +1 -1
  77. package/dist/paths.d.ts +0 -1
  78. package/dist/paths.d.ts.map +1 -1
  79. package/dist/paths.js +0 -4
  80. package/dist/paths.js.map +1 -1
  81. package/dist/query.d.ts +209 -0
  82. package/dist/query.d.ts.map +1 -0
  83. package/dist/query.js +467 -0
  84. package/dist/query.js.map +1 -0
  85. package/dist/read-side.d.ts +14 -0
  86. package/dist/read-side.d.ts.map +1 -0
  87. package/dist/read-side.js +451 -0
  88. package/dist/read-side.js.map +1 -0
  89. package/dist/refresh.d.ts +2 -2
  90. package/dist/refresh.d.ts.map +1 -1
  91. package/dist/refresh.js +8 -6
  92. package/dist/refresh.js.map +1 -1
  93. package/dist/replica.d.ts +22 -3
  94. package/dist/replica.d.ts.map +1 -1
  95. package/dist/replica.js +170 -8
  96. package/dist/replica.js.map +1 -1
  97. package/dist/room-draft.d.ts +124 -0
  98. package/dist/room-draft.d.ts.map +1 -0
  99. package/dist/room-draft.js +406 -0
  100. package/dist/room-draft.js.map +1 -0
  101. package/dist/rows.d.ts +39 -0
  102. package/dist/rows.d.ts.map +1 -0
  103. package/dist/rows.js +100 -0
  104. package/dist/rows.js.map +1 -0
  105. package/dist/save.d.ts +11 -2
  106. package/dist/save.d.ts.map +1 -1
  107. package/dist/save.js +104 -128
  108. package/dist/save.js.map +1 -1
  109. package/dist/search.d.ts +61 -0
  110. package/dist/search.d.ts.map +1 -0
  111. package/dist/search.js +155 -0
  112. package/dist/search.js.map +1 -0
  113. package/dist/status.d.ts +9 -1
  114. package/dist/status.d.ts.map +1 -1
  115. package/dist/status.js +7 -4
  116. package/dist/status.js.map +1 -1
  117. package/dist/store.d.ts +87 -15
  118. package/dist/store.d.ts.map +1 -1
  119. package/dist/store.js +436 -54
  120. package/dist/store.js.map +1 -1
  121. package/dist/transfer.d.ts +5 -0
  122. package/dist/transfer.d.ts.map +1 -1
  123. package/dist/transfer.js.map +1 -1
  124. package/dist/wire.d.ts +64 -0
  125. package/dist/wire.d.ts.map +1 -0
  126. package/dist/wire.js +142 -0
  127. package/dist/wire.js.map +1 -0
  128. package/package.json +14 -4
@@ -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;
11
+ } | Unconfirmed | Refused | AdapterFailure;
12
12
  export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer): 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,GACxB,OAAO,CAAC,cAAc,CAAC,CAsDzB"}
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
3
  export async function refreshRoom(adapter, authorization, confirmed) {
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;
@@ -36,6 +37,7 @@ export async function refreshRoom(adapter, authorization, confirmed) {
36
37
  while(pageToken !== undefined){
37
38
  const page = await adapter.refresh(authorization, {
38
39
  locator,
40
+ selection: confirmed.record.replica.selection,
39
41
  fromRoomVersion,
40
42
  pageToken
41
43
  });
@@ -45,7 +47,7 @@ export async function refreshRoom(adapter, authorization, confirmed) {
45
47
  stage(page);
46
48
  pageToken = page.pageToken;
47
49
  }
48
- const advanced = readConfirmed({
50
+ const staged = readStaged({
49
51
  ...confirmed.record,
50
52
  roomVersion,
51
53
  documents,
@@ -53,11 +55,11 @@ export async function refreshRoom(adapter, authorization, confirmed) {
53
55
  ...binaryTargets
54
56
  ].sort(),
55
57
  revisions
56
- });
57
- return advanced === null ? unconfirmed : {
58
+ }, confirmed);
59
+ return staged.kind === 'staged' ? {
58
60
  kind: 'advanced',
59
- confirmed: advanced
60
- };
61
+ confirmed: staged.confirmed
62
+ } : staged;
61
63
  }
62
64
 
63
65
  //# 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): 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 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","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;IAEzB,MAAMC,UAAUD,UAAUE,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBH,UAAUE,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMP,QAAQQ,OAAO,CAACP,eAAe;QACjDE;QACAM,WAAWP,UAAUE,MAAM,CAACM,OAAO,CAACD,SAAS;QAC7CJ;IACF;IACA,IAAIE,MAAMI,IAAI,KAAK,mBAAmB,OAAOJ;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMM,YAAoC;QAAE,GAAGV,UAAUE,MAAM,CAACQ,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGX,UAAUE,MAAM,CAACS,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAIb,UAAUE,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,MAAMV,OAAO,MAAMjB,QAAQQ,OAAO,CAACP,eAAe;YAChDE;YACAM,WAAWP,UAAUE,MAAM,CAACM,OAAO,CAACD,SAAS;YAC7CJ;YACAqB;QACF;QACA,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOb;QAC5E,IAAImB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKX,WAAW,KAAKA,aAAa,OAAOR;QAC7CkB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,SAAS/B,WACb;QACE,GAAGK,UAAUE,MAAM;QACnBE;QACAM;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF,GACAX;IAEF,OAAO0B,OAAOjB,IAAI,KAAK,WAAW;QAAEA,MAAM;QAAYT,WAAW0B,OAAO1B,SAAS;IAAC,IAAI0B;AACxF"}
package/dist/replica.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { type ChangeBatch } from './change.js';
2
- import { type Collection } from './collection.js';
2
+ import { type Collection, type Composition } from './collection.js';
3
3
  import { type Layer } from './overlay.js';
4
+ import { type Rewriting } from './save.js';
4
5
  import type { ReplicaRecord } from './store.js';
6
+ import { type Refused, type Unconfirmed } from './transfer.js';
5
7
  export type ConfirmedLayer = {
6
8
  record: ReplicaRecord;
7
9
  collection: Collection;
@@ -9,11 +11,28 @@ export type ConfirmedLayer = {
9
11
  export type VisibleLayer = Layer & {
10
12
  collection: Collection;
11
13
  };
14
+ export type Staged = {
15
+ kind: 'staged';
16
+ confirmed: ConfirmedLayer;
17
+ } | Refused | Unconfirmed;
12
18
  export type Replica = {
13
19
  confirmed: ConfirmedLayer;
14
20
  queue: readonly ChangeBatch[];
15
21
  visible: VisibleLayer;
22
+ replay: readonly ReplayStep[];
23
+ };
24
+ type ReplayStep = {
25
+ id: string;
26
+ before: Layer;
27
+ after: Layer;
28
+ effective: ChangeBatch;
29
+ collection?: Collection;
16
30
  };
17
- export declare function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null;
18
- export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[]): Replica;
31
+ export declare function compositionOf(record: ReplicaRecord): Composition;
32
+ export declare function readConfirmed(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer | null;
33
+ export declare function readStaged(record: ReplicaRecord, previous?: ConfirmedLayer): Staged;
34
+ export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], roomVersion: string): Staged;
35
+ export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting, previous?: Replica): Replica;
36
+ export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, rewriting: Rewriting): readonly ChangeBatch[];
37
+ export {};
19
38
  //# sourceMappingURL=replica.d.ts.map