@agentshouse/mdruntime 0.1.0-alpha.23 → 0.1.0-alpha.25

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 (83) hide show
  1. package/AGENTS.md +70 -18
  2. package/dist/change-set.d.ts +4 -11
  3. package/dist/change-set.d.ts.map +1 -1
  4. package/dist/change-set.js +8 -16
  5. package/dist/change-set.js.map +1 -1
  6. package/dist/change.d.ts +4 -0
  7. package/dist/change.d.ts.map +1 -1
  8. package/dist/change.js.map +1 -1
  9. package/dist/client.d.ts +16 -15
  10. package/dist/client.d.ts.map +1 -1
  11. package/dist/client.js +17 -22
  12. package/dist/client.js.map +1 -1
  13. package/dist/collection.d.ts +0 -2
  14. package/dist/collection.d.ts.map +1 -1
  15. package/dist/collection.js +0 -5
  16. package/dist/collection.js.map +1 -1
  17. package/dist/connection.d.ts +21 -23
  18. package/dist/connection.d.ts.map +1 -1
  19. package/dist/connection.js +435 -352
  20. package/dist/connection.js.map +1 -1
  21. package/dist/conversation.d.ts +4 -4
  22. package/dist/conversation.d.ts.map +1 -1
  23. package/dist/conversation.js +12 -6
  24. package/dist/conversation.js.map +1 -1
  25. package/dist/durability.js +1 -1
  26. package/dist/durability.js.map +1 -1
  27. package/dist/host.d.ts.map +1 -1
  28. package/dist/host.js +12 -14
  29. package/dist/host.js.map +1 -1
  30. package/dist/identity.d.ts +1 -0
  31. package/dist/identity.d.ts.map +1 -1
  32. package/dist/identity.js +7 -0
  33. package/dist/identity.js.map +1 -1
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/outcome.d.ts +17 -20
  38. package/dist/outcome.d.ts.map +1 -1
  39. package/dist/outcome.js +1 -21
  40. package/dist/outcome.js.map +1 -1
  41. package/dist/overlay.d.ts.map +1 -1
  42. package/dist/overlay.js +1 -1
  43. package/dist/overlay.js.map +1 -1
  44. package/dist/paths.d.ts +1 -0
  45. package/dist/paths.d.ts.map +1 -1
  46. package/dist/paths.js +8 -0
  47. package/dist/paths.js.map +1 -1
  48. package/dist/query.d.ts +199 -10
  49. package/dist/query.d.ts.map +1 -1
  50. package/dist/query.js +450 -14
  51. package/dist/query.js.map +1 -1
  52. package/dist/read-side.d.ts +10 -0
  53. package/dist/read-side.d.ts.map +1 -0
  54. package/dist/read-side.js +374 -0
  55. package/dist/read-side.js.map +1 -0
  56. package/dist/replica.d.ts +1 -0
  57. package/dist/replica.d.ts.map +1 -1
  58. package/dist/replica.js +54 -0
  59. package/dist/replica.js.map +1 -1
  60. package/dist/room-draft.d.ts +124 -0
  61. package/dist/room-draft.d.ts.map +1 -0
  62. package/dist/room-draft.js +403 -0
  63. package/dist/room-draft.js.map +1 -0
  64. package/dist/rows.d.ts +39 -0
  65. package/dist/rows.d.ts.map +1 -0
  66. package/dist/rows.js +85 -0
  67. package/dist/rows.js.map +1 -0
  68. package/dist/save.d.ts +4 -1
  69. package/dist/save.d.ts.map +1 -1
  70. package/dist/save.js +34 -100
  71. package/dist/save.js.map +1 -1
  72. package/dist/status.d.ts +4 -6
  73. package/dist/status.d.ts.map +1 -1
  74. package/dist/status.js.map +1 -1
  75. package/dist/store.d.ts +18 -12
  76. package/dist/store.d.ts.map +1 -1
  77. package/dist/store.js +43 -34
  78. package/dist/store.js.map +1 -1
  79. package/dist/wire.d.ts +3 -3
  80. package/dist/wire.d.ts.map +1 -1
  81. package/dist/wire.js +6 -7
  82. package/dist/wire.js.map +1 -1
  83. package/package.json +2 -2
@@ -0,0 +1,374 @@
1
+ import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, gt, gte, inArray, isNull, isUndefined, lt, lte, not, or, toArray } from '@tanstack/db';
2
+ function every(expressions) {
3
+ const [first, second, ...rest] = expressions;
4
+ return second === undefined ? first : and(first, second, ...rest);
5
+ }
6
+ function some(expressions) {
7
+ const [first, second, ...rest] = expressions;
8
+ return second === undefined ? first : or(first, second, ...rest);
9
+ }
10
+ function equal(field, value) {
11
+ return or(eq(field, value), inArray(value, field));
12
+ }
13
+ function tested(test, field, size, written) {
14
+ if (test.op === 'eq') return test.value === null ? isNull(field) : equal(field, test.value);
15
+ if (test.op === 'ne') {
16
+ return test.value === null ? not(isNull(field)) : or(isUndefined(field), isNull(field), not(equal(field, test.value)));
17
+ }
18
+ if (test.op === 'in' || test.op === 'nin') {
19
+ const matches = test.values.length === 0 ? inArray(field, []) : some(test.values.map((value)=>value === null ? isNull(field) : equal(field, value)));
20
+ if (test.op === 'in') return matches;
21
+ return some([
22
+ isUndefined(field),
23
+ ...test.values.includes(null) ? [] : [
24
+ isNull(field)
25
+ ],
26
+ not(matches)
27
+ ]);
28
+ }
29
+ if (test.op === 'range') {
30
+ const compare = {
31
+ gt,
32
+ gte,
33
+ lt,
34
+ lte
35
+ };
36
+ return every(test.bounds.map(([operator, bound])=>compare[operator](field, bound)));
37
+ }
38
+ if (test.op === 'all') {
39
+ return every([
40
+ not(isUndefined(size)),
41
+ ...test.values.map((value)=>inArray(value, field))
42
+ ]);
43
+ }
44
+ if (test.op === 'size') return eq(size, test.size);
45
+ return test.exists ? not(isUndefined(written)) : isUndefined(written);
46
+ }
47
+ function conditioned(condition, row) {
48
+ if ('every' in condition) return every(condition.every.map((item)=>conditioned(item, row)));
49
+ if ('some' in condition) return some(condition.some.map((item)=>conditioned(item, row)));
50
+ return tested(condition.test, row.values[condition.field], row.sizes[condition.field], row.fields[condition.field]);
51
+ }
52
+ function scoped(scope, row, rooms) {
53
+ return every([
54
+ eq(row.kind, 'document'),
55
+ ...rooms === null ? [] : [
56
+ inArray(row.room, [
57
+ ...rooms
58
+ ])
59
+ ],
60
+ ...scope.types === null ? [] : [
61
+ inArray(row.type, [
62
+ ...scope.types
63
+ ])
64
+ ],
65
+ ...scope.pathPrefix === null ? [] : [
66
+ inArray(scope.pathPrefix, row.directories)
67
+ ],
68
+ ...scope.where === null ? [] : [
69
+ conditioned(scope.where, row)
70
+ ]
71
+ ]);
72
+ }
73
+ function keyed(key, row) {
74
+ return key.of === 'field' ? row.values[key.field] : row[key.of];
75
+ }
76
+ function live(query) {
77
+ return createLiveQueryCollection({
78
+ query: query,
79
+ startSync: true
80
+ });
81
+ }
82
+ function related(q, rows, scope, field, kept) {
83
+ const matched = kept === 'source' ? 'target' : 'source';
84
+ const from = q.from({
85
+ r: rows
86
+ });
87
+ return from.where(({ r })=>every([
88
+ eq(r.kind, 'reference'),
89
+ ...field === null ? [] : [
90
+ eq(r.field, field)
91
+ ]
92
+ ])).innerJoin({
93
+ m: rows
94
+ }, ({ r, m })=>eq(r[matched], m.key)).where(({ m })=>scoped(scope, m, null)).groupBy(({ r })=>r[kept]).select(({ r })=>({
95
+ key: r[kept]
96
+ }));
97
+ }
98
+ function filtered(q, rows, plan) {
99
+ const from = q.from({
100
+ d: rows
101
+ });
102
+ let query = from.where(({ d })=>scoped(plan.root, d, plan.rooms));
103
+ if (plan.hop !== null) {
104
+ const hop = related(q, rows, plan.hop, plan.hop.field, 'source');
105
+ query = query.innerJoin({
106
+ h: hop
107
+ }, ({ d, h })=>eq(d.key, h.key));
108
+ }
109
+ if (plan.backlinks !== null) {
110
+ const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target');
111
+ query = query.innerJoin({
112
+ k: backlinks
113
+ }, ({ d, k })=>eq(d.key, k.key));
114
+ }
115
+ return query;
116
+ }
117
+ function named(prefix, names, source) {
118
+ return Object.fromEntries(names.map((name, index)=>[
119
+ `${prefix}${index}`,
120
+ source[name]
121
+ ]));
122
+ }
123
+ function documents(q, rows, plan, shape) {
124
+ let query = filtered(q, rows, plan);
125
+ if (shape.sections !== null || shape.preamble || shape.markdown) {
126
+ query = query.innerJoin({
127
+ b: rows
128
+ }, ({ d, b })=>eq(d.body, b.key));
129
+ }
130
+ for (const { key, options } of shape.orderBy){
131
+ query = query.orderBy(({ d })=>keyed(key, d), options);
132
+ }
133
+ if (shape.orderBy.length === 0 && plan.limit !== null) {
134
+ query = query.orderBy(({ d })=>d.key, {
135
+ stringSort: 'lexical'
136
+ });
137
+ }
138
+ if (plan.limit !== null) query = query.limit(plan.limit);
139
+ return query.select(({ d, b })=>({
140
+ room: d.room,
141
+ path: d.path,
142
+ type: d.type,
143
+ ...shape.fields === 'all' ? {
144
+ fields: d.fields
145
+ } : {},
146
+ ...Array.isArray(shape.fields) ? named('field', shape.fields, d.fields) : {},
147
+ ...shape.sections === 'all' ? {
148
+ sections: b.sections
149
+ } : {},
150
+ ...Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {},
151
+ ...shape.preamble ? {
152
+ preamble: b.preamble
153
+ } : {},
154
+ ...shape.markdown ? {
155
+ markdown: b.markdown
156
+ } : {},
157
+ ...shape.backlinks ? {
158
+ backlinks: toArray(backlinked(q, rows, d))
159
+ } : {}
160
+ }));
161
+ }
162
+ function backlinked(q, rows, document) {
163
+ const from = q.from({
164
+ r: rows
165
+ });
166
+ return from.where(({ r })=>eq(r.target, document.key)).orderBy(({ r })=>r.path, {
167
+ stringSort: 'lexical'
168
+ }).orderBy(({ r })=>r.field, {
169
+ stringSort: 'lexical'
170
+ }).select(({ r })=>({
171
+ path: r.path,
172
+ type: r.type,
173
+ field: r.field
174
+ }));
175
+ }
176
+ function groups(q, stage, shape, limit) {
177
+ const keys = shape.groupBy.map((_, index)=>`key${index}`);
178
+ const from = q.from({
179
+ m: stage
180
+ });
181
+ let query = from.groupBy(({ m })=>keys.map((key)=>m[key]));
182
+ for (const { by, direction } of shape.orderBy){
183
+ query = query.orderBy(({ m })=>by === 'count' ? count(m.key) : m[keys[by]], direction);
184
+ }
185
+ if (limit !== null && shape.orderBy.length > 0) query = query.limit(limit);
186
+ return query.select(({ m })=>({
187
+ ...Object.fromEntries(keys.map((key)=>[
188
+ key,
189
+ m[key]
190
+ ])),
191
+ count: count(m.key)
192
+ }));
193
+ }
194
+ function built(rows, plan) {
195
+ const shape = plan.shape;
196
+ if (shape.kind === 'documents') {
197
+ const collection = live((q)=>documents(q, rows, plan, shape));
198
+ return {
199
+ live: collection,
200
+ dispose: ()=>void collection.cleanup()
201
+ };
202
+ }
203
+ const stage = live((q)=>filtered(q, rows, plan).select(({ d })=>({
204
+ key: d.key,
205
+ ...Object.fromEntries(shape.groupBy.map((key, index)=>[
206
+ `key${index}`,
207
+ keyed(key, d)
208
+ ]))
209
+ })));
210
+ const collection = live((q)=>groups(q, stage, shape, plan.limit));
211
+ return {
212
+ live: collection,
213
+ dispose: ()=>{
214
+ void collection.cleanup();
215
+ void stage.cleanup();
216
+ }
217
+ };
218
+ }
219
+ function present(entries) {
220
+ return Object.fromEntries(entries.filter(([, value])=>value !== undefined));
221
+ }
222
+ function part(row, prefix, names, whole) {
223
+ if (names === 'all') return whole;
224
+ return present(names.map((name, index)=>[
225
+ name,
226
+ row[`${prefix}${index}`]
227
+ ]));
228
+ }
229
+ function documentOf(row, shape) {
230
+ return {
231
+ room: row.room,
232
+ path: row.path,
233
+ type: row.type,
234
+ ...shape.fields === null ? {} : {
235
+ fields: part(row, 'field', shape.fields, row.fields)
236
+ },
237
+ ...shape.sections === null ? {} : {
238
+ sections: part(row, 'section', shape.sections, row.sections)
239
+ },
240
+ ...shape.preamble ? {
241
+ preamble: row.preamble
242
+ } : {},
243
+ ...shape.markdown ? {
244
+ markdown: row.markdown
245
+ } : {},
246
+ ...shape.backlinks ? {
247
+ backlinks: row.backlinks.map(({ path, type, field })=>({
248
+ path,
249
+ type,
250
+ field
251
+ }))
252
+ } : {}
253
+ };
254
+ }
255
+ function resultOf(plan, rows) {
256
+ const shape = plan.shape;
257
+ if (shape.kind === 'documents') {
258
+ return structuredClone({
259
+ documents: rows.map((row)=>documentOf(row, shape))
260
+ });
261
+ }
262
+ const bounded = shape.orderBy.length === 0 && plan.limit !== null ? rows.slice(0, plan.limit) : rows;
263
+ return structuredClone({
264
+ groups: bounded.map((row)=>({
265
+ key: shape.groupBy.map((_, index)=>row[`key${index}`]),
266
+ count: row.count
267
+ }))
268
+ });
269
+ }
270
+ export function createReadSide() {
271
+ configureIndexDevMode({
272
+ enabled: false
273
+ });
274
+ let sync;
275
+ const rows = createCollection({
276
+ getKey: (row)=>row.key,
277
+ gcTime: 0,
278
+ startSync: true,
279
+ autoIndex: 'eager',
280
+ defaultIndexType: BasicIndex,
281
+ sync: {
282
+ rowUpdateMode: 'full',
283
+ sync: (params)=>{
284
+ sync = params;
285
+ params.markReady();
286
+ }
287
+ }
288
+ });
289
+ const shared = new Map();
290
+ function publish(entry) {
291
+ const next = resultOf(entry.plan, entry.built.live.toArray);
292
+ if (deepEquals(entry.result, next)) return;
293
+ entry.result = next;
294
+ for (const listener of entry.listeners)listener(next);
295
+ }
296
+ return {
297
+ apply (set) {
298
+ const next = new Map();
299
+ for (const change of set.documents){
300
+ for (const row of change.before)next.set(row.key, null);
301
+ for (const row of change.after)next.set(row.key, row);
302
+ }
303
+ if (next.size === 0) return;
304
+ sync.begin();
305
+ for (const [key, row] of next){
306
+ if (row === null) {
307
+ if (rows.has(key)) sync.write({
308
+ type: 'delete',
309
+ key
310
+ });
311
+ continue;
312
+ }
313
+ sync.write({
314
+ type: rows.has(key) ? 'update' : 'insert',
315
+ value: row
316
+ });
317
+ }
318
+ sync.commit();
319
+ },
320
+ async query (plan) {
321
+ const { live: collection, dispose } = built(rows, plan);
322
+ try {
323
+ return resultOf(plan, await collection.toArrayWhenReady());
324
+ } finally{
325
+ dispose();
326
+ }
327
+ },
328
+ observe (plan, identity, listener) {
329
+ let entry = shared.get(identity);
330
+ if (entry === undefined) {
331
+ const created = {
332
+ plan,
333
+ built: built(rows, plan),
334
+ result: undefined,
335
+ listeners: new Set(),
336
+ subscription: null
337
+ };
338
+ created.built.live.on('status:change', ({ status })=>{
339
+ if (status === 'cleaned-up' && created.listeners.size === 0) shared.delete(identity);
340
+ });
341
+ shared.set(identity, created);
342
+ entry = created;
343
+ }
344
+ const observed = entry;
345
+ observed.listeners.add(listener);
346
+ observed.built.live.onFirstReady(()=>{
347
+ if (!observed.listeners.has(listener)) return;
348
+ if (observed.subscription === null) {
349
+ observed.result = resultOf(observed.plan, observed.built.live.toArray);
350
+ observed.subscription = observed.built.live.subscribeChanges(()=>{
351
+ publish(observed);
352
+ });
353
+ }
354
+ listener(observed.result);
355
+ });
356
+ return ()=>{
357
+ if (!observed.listeners.delete(listener) || observed.listeners.size > 0) return;
358
+ observed.subscription?.unsubscribe();
359
+ observed.subscription = null;
360
+ };
361
+ },
362
+ close () {
363
+ for (const entry of shared.values()){
364
+ entry.listeners.clear();
365
+ entry.subscription?.unsubscribe();
366
+ entry.built.dispose();
367
+ }
368
+ shared.clear();
369
+ void rows.cleanup();
370
+ }
371
+ };
372
+ }
373
+
374
+ //# 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 type {\n Condition,\n Direction,\n DocumentShape,\n GroupShape,\n KeyPlan,\n OrderOptions,\n Plan,\n QueryDocument,\n QueryResult,\n Scope,\n Test,\n Value,\n} from './query.js';\nimport type { Row } from './rows.js';\n\ntype Stored = {\n key: string;\n kind: string;\n room: string;\n path: string;\n type: string;\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: QueryResult | undefined;\n listeners: Set<(result: QueryResult) => void>;\n subscription: { unsubscribe(): void } | null;\n};\n\nexport type ReadSide = {\n apply(set: ChangeSet): void;\n query(plan: Plan): Promise<QueryResult>;\n observe(plan: Plan, identity: string, listener: (result: QueryResult) => void): () => void;\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, [...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'] {\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 = query.innerJoin({ 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 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 resultOf(plan: Plan, rows: readonly Readonly<Record<string, unknown>>[]): QueryResult {\n const shape = plan.shape;\n if (shape.kind === 'documents') {\n return structuredClone({ documents: rows.map((row) => documentOf(row, shape)) });\n }\n const bounded =\n shape.orderBy.length === 0 && plan.limit !== null ? rows.slice(0, plan.limit) : rows;\n return structuredClone({\n groups: bounded.map((row) => ({\n key: shape.groupBy.map((_, index) => row[`key${index}`]),\n count: row.count as number,\n })),\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 publish(entry: Shared) {\n const next = resultOf(entry.plan, entry.built.live.toArray);\n if (deepEquals(entry.result, next)) return;\n entry.result = next;\n for (const listener of entry.listeners) listener(next);\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 return resultOf(plan, await collection.toArrayWhenReady());\n } finally {\n dispose();\n }\n },\n observe(plan, identity, listener) {\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(listener);\n observed.built.live.onFirstReady(() => {\n if (!observed.listeners.has(listener)) return;\n if (observed.subscription === null) {\n observed.result = resultOf(observed.plan, observed.built.live.toArray);\n observed.subscription = observed.built.live.subscribeChanges(() => {\n publish(observed);\n });\n }\n listener(observed.result as QueryResult);\n });\n return () => {\n if (!observed.listeners.delete(listener) || observed.listeners.size > 0) return;\n observed.subscription?.unsubscribe();\n observed.subscription = null;\n };\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","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","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","resultOf","structuredClone","bounded","slice","createReadSide","enabled","sync","getKey","gcTime","autoIndex","defaultIndexType","rowUpdateMode","params","markReady","shared","Map","publish","entry","next","result","listener","listeners","apply","set","change","before","after","begin","has","write","commit","toArrayWhenReady","observe","identity","get","created","Set","subscription","on","status","delete","observed","add","onFirstReady","subscribeChanges","unsubscribe","close","clear"],"mappings":"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"}
package/dist/replica.d.ts CHANGED
@@ -28,5 +28,6 @@ export declare function readConfirmed(record: ReplicaRecord, previous?: Confirme
28
28
  export declare function readStaged(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer | null;
29
29
  export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], roomVersion: string): ConfirmedLayer | null;
30
30
  export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting, previous?: Replica): Replica;
31
+ export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, rewriting: Rewriting): readonly ChangeBatch[];
31
32
  export {};
32
33
  //# sourceMappingURL=replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA0C,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAShE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CASvB;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CAgBvB;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,cAAc,GAAG,IAAI,CAmBvB;AAuDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA2CT"}
1
+ {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC7E,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA0C,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAShE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CASvB;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CAgBvB;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,cAAc,GAAG,IAAI,CAmBvB;AAuDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA2CT;AAyCD,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,EAC7C,SAAS,EAAE,SAAS,GACnB,SAAS,WAAW,EAAE,CAoBxB"}
package/dist/replica.js CHANGED
@@ -1,7 +1,9 @@
1
+ import { parse } from '@agentshouse/mdmodel';
1
2
  import { immutable } from './change.js';
2
3
  import { parseCollection, readCollection, validateCollection } from './collection.js';
3
4
  import { overlay, overlayChanged, sameLayerText } from './overlay.js';
4
5
  import { providerRewritten } from './save.js';
6
+ import { equalValue } from './room-draft.js';
5
7
  export function compositionOf(record) {
6
8
  return {
7
9
  collectionRoot: record.collectionRoot,
@@ -130,5 +132,57 @@ export function replicaOf(confirmed, queue, rewriting, previous) {
130
132
  }
131
133
  };
132
134
  }
135
+ function present(layer, path) {
136
+ return layer.documents[path] !== undefined || layer.binaryTargets.includes(path);
137
+ }
138
+ function holds(layer, preconditions) {
139
+ const parsed = new Map();
140
+ const documentAt = (path)=>{
141
+ if (!parsed.has(path)) {
142
+ const text = layer.documents[path];
143
+ const opened = text === undefined ? null : parse(text, path);
144
+ parsed.set(path, opened?.ok === true ? opened.document : null);
145
+ }
146
+ return parsed.get(path) ?? null;
147
+ };
148
+ return preconditions.every((precondition)=>{
149
+ const path = precondition.path;
150
+ if (precondition.kind === 'absent') return !present(layer, path);
151
+ if (precondition.kind === 'present') return present(layer, path);
152
+ if (precondition.kind === 'revision') {
153
+ return present(layer, path) && layer.revisions[path] === precondition.revision;
154
+ }
155
+ const document = documentAt(path);
156
+ if (document === null) return false;
157
+ if (precondition.kind === 'field') {
158
+ const value = Object.hasOwn(document.fields, precondition.name) ? document.fields[precondition.name] : undefined;
159
+ return equalValue(value, precondition.value);
160
+ }
161
+ if (precondition.kind === 'section') {
162
+ return Object.hasOwn(document.sections, precondition.name) && document.sections[precondition.name] === precondition.value;
163
+ }
164
+ return document.preamble === precondition.value;
165
+ });
166
+ }
167
+ export function withdrawals(confirmed, queue, withdrawable, rewriting) {
168
+ if (!queue.some(withdrawable)) return [];
169
+ const composition = compositionOf(confirmed.record);
170
+ let layer = confirmed.record;
171
+ const withdrawn = [];
172
+ for (const batch of queue){
173
+ if (withdrawable(batch) && !holds(layer, batch.preconditions)) {
174
+ withdrawn.push(batch);
175
+ continue;
176
+ }
177
+ const effective = rewriting === 'provider' && batch.changes.some((change)=>change.kind === 'move') ? providerRewritten(batch, {
178
+ ...layer,
179
+ collection: parseCollection(layer.documents, composition)
180
+ }) : batch;
181
+ layer = overlay(layer, [
182
+ effective
183
+ ]);
184
+ }
185
+ return withdrawn;
186
+ }
133
187
 
134
188
  //# sourceMappingURL=replica.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import { immutable, type ChangeBatch } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, overlayChanged, sameLayerText, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n replay: readonly ReplayStep[];\n};\n\ntype ReplayStep = {\n id: string;\n before: Layer;\n after: Layer;\n effective: ChangeBatch;\n collection?: Collection;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n const collection = readCollection(\n record.documents,\n compositionOf(record),\n previous === undefined\n ? undefined\n : { text: previous.record.documents, collection: previous.collection },\n );\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n if (\n (record.model.status === 'current' || record.selectionModel.status === 'current') &&\n (previous === undefined ||\n !sameLayerText(record, previous.record) ||\n record.model !== previous.record.model ||\n record.selectionModel !== previous.record.selectionModel)\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record, previous);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n confirmed,\n );\n}\n\nfunction predicted(\n confirmed: ConfirmedLayer,\n batches: readonly ChangeBatch[],\n previous?: Replica,\n): { layer: Layer; replay: readonly ReplayStep[] } {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const replay: ReplayStep[] = [];\n const prior = new Map(previous?.replay.map((step) => [step.id, step]) ?? []);\n for (const batch of batches) {\n const before = layer;\n const old = prior.get(batch.id);\n const hasMove = batch.changes.some((change) => change.kind === 'move');\n const reuseRewrite =\n old?.collection !== undefined &&\n sameLayerText(before, old.before) &&\n old.collection.composition.collectionRoot === composition.collectionRoot &&\n old.collection.composition.model === composition.model &&\n old.collection.composition.selection?.model === composition.selection?.model &&\n JSON.stringify(old.collection.composition.selection?.roots) ===\n JSON.stringify(composition.selection?.roots);\n const collection = hasMove\n ? reuseRewrite\n ? old.collection\n : parseCollection(\n before.documents,\n composition,\n old?.collection === undefined\n ? { text: confirmed.record.documents, collection: confirmed.collection }\n : { text: old.before.documents, collection: old.collection },\n )\n : undefined;\n const effective =\n collection === undefined\n ? batch\n : reuseRewrite\n ? old.effective\n : providerRewritten(batch, { ...before, collection });\n layer =\n old === undefined\n ? overlay(before, [effective])\n : overlayChanged(before, [effective], old.before, [old.effective], old.after);\n replay.push({\n id: batch.id,\n before,\n after: layer,\n effective,\n ...(collection === undefined ? {} : { collection }),\n });\n }\n return { layer, replay };\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n previous?: Replica,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n replay: [],\n };\n }\n const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;\n const layer =\n rewriting === 'provider'\n ? predictedState!.layer\n : previous === undefined\n ? overlay(confirmed.record, batches)\n : overlayChanged(\n confirmed.record,\n batches,\n previous.confirmed.record,\n previous.queue,\n previous.visible,\n );\n return {\n confirmed,\n queue: batches,\n replay: predictedState?.replay ?? [],\n visible: {\n ...layer,\n collection: parseCollection(\n layer.documents,\n compositionOf(confirmed.record),\n previous === undefined\n ? undefined\n : { text: previous.visible.documents, collection: previous.visible.collection },\n ),\n },\n };\n}\n"],"names":["immutable","parseCollection","readCollection","validateCollection","overlay","overlayChanged","sameLayerText","providerRewritten","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","previous","collection","documents","undefined","text","readStaged","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","replay","prior","Map","map","step","id","batch","before","old","get","hasMove","changes","some","change","kind","reuseRewrite","JSON","stringify","effective","after","push","replicaOf","queue","rewriting","Object","freeze","length","visible","predictedState"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import { parse, type Document } from '@agentshouse/mdmodel';\nimport { immutable, type ChangeBatch, type Precondition } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, overlayChanged, sameLayerText, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport { equalValue } from './room-draft.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n replay: readonly ReplayStep[];\n};\n\ntype ReplayStep = {\n id: string;\n before: Layer;\n after: Layer;\n effective: ChangeBatch;\n collection?: Collection;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n const collection = readCollection(\n record.documents,\n compositionOf(record),\n previous === undefined\n ? undefined\n : { text: previous.record.documents, collection: previous.collection },\n );\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n if (\n (record.model.status === 'current' || record.selectionModel.status === 'current') &&\n (previous === undefined ||\n !sameLayerText(record, previous.record) ||\n record.model !== previous.record.model ||\n record.selectionModel !== previous.record.selectionModel)\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record, previous);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n confirmed,\n );\n}\n\nfunction predicted(\n confirmed: ConfirmedLayer,\n batches: readonly ChangeBatch[],\n previous?: Replica,\n): { layer: Layer; replay: readonly ReplayStep[] } {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const replay: ReplayStep[] = [];\n const prior = new Map(previous?.replay.map((step) => [step.id, step]) ?? []);\n for (const batch of batches) {\n const before = layer;\n const old = prior.get(batch.id);\n const hasMove = batch.changes.some((change) => change.kind === 'move');\n const reuseRewrite =\n old?.collection !== undefined &&\n sameLayerText(before, old.before) &&\n old.collection.composition.collectionRoot === composition.collectionRoot &&\n old.collection.composition.model === composition.model &&\n old.collection.composition.selection?.model === composition.selection?.model &&\n JSON.stringify(old.collection.composition.selection?.roots) ===\n JSON.stringify(composition.selection?.roots);\n const collection = hasMove\n ? reuseRewrite\n ? old.collection\n : parseCollection(\n before.documents,\n composition,\n old?.collection === undefined\n ? { text: confirmed.record.documents, collection: confirmed.collection }\n : { text: old.before.documents, collection: old.collection },\n )\n : undefined;\n const effective =\n collection === undefined\n ? batch\n : reuseRewrite\n ? old.effective\n : providerRewritten(batch, { ...before, collection });\n layer =\n old === undefined\n ? overlay(before, [effective])\n : overlayChanged(before, [effective], old.before, [old.effective], old.after);\n replay.push({\n id: batch.id,\n before,\n after: layer,\n effective,\n ...(collection === undefined ? {} : { collection }),\n });\n }\n return { layer, replay };\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n previous?: Replica,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n replay: [],\n };\n }\n const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;\n const layer =\n rewriting === 'provider'\n ? predictedState!.layer\n : previous === undefined\n ? overlay(confirmed.record, batches)\n : overlayChanged(\n confirmed.record,\n batches,\n previous.confirmed.record,\n previous.queue,\n previous.visible,\n );\n return {\n confirmed,\n queue: batches,\n replay: predictedState?.replay ?? [],\n visible: {\n ...layer,\n collection: parseCollection(\n layer.documents,\n compositionOf(confirmed.record),\n previous === undefined\n ? undefined\n : { text: previous.visible.documents, collection: previous.visible.collection },\n ),\n },\n };\n}\n\nfunction present(layer: Layer, path: string): boolean {\n return layer.documents[path] !== undefined || layer.binaryTargets.includes(path);\n}\n\nfunction holds(layer: Layer, preconditions: readonly Precondition[]): boolean {\n const parsed = new Map<string, Document | null>();\n const documentAt = (path: string) => {\n if (!parsed.has(path)) {\n const text = layer.documents[path];\n const opened = text === undefined ? null : parse(text, path);\n parsed.set(path, opened?.ok === true ? opened.document : null);\n }\n return parsed.get(path) ?? null;\n };\n return preconditions.every((precondition) => {\n const path = precondition.path;\n if (precondition.kind === 'absent') return !present(layer, path);\n if (precondition.kind === 'present') return present(layer, path);\n if (precondition.kind === 'revision') {\n return present(layer, path) && layer.revisions[path] === precondition.revision;\n }\n const document = documentAt(path);\n if (document === null) return false;\n if (precondition.kind === 'field') {\n const value = Object.hasOwn(document.fields, precondition.name)\n ? document.fields[precondition.name]\n : undefined;\n return equalValue(value, precondition.value);\n }\n if (precondition.kind === 'section') {\n return (\n Object.hasOwn(document.sections, precondition.name) &&\n document.sections[precondition.name] === precondition.value\n );\n }\n return document.preamble === precondition.value;\n });\n}\n\nexport function withdrawals(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n withdrawable: (batch: ChangeBatch) => boolean,\n rewriting: Rewriting,\n): readonly ChangeBatch[] {\n if (!queue.some(withdrawable)) return [];\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const withdrawn: ChangeBatch[] = [];\n for (const batch of queue) {\n if (withdrawable(batch) && !holds(layer, batch.preconditions)) {\n withdrawn.push(batch);\n continue;\n }\n const effective =\n rewriting === 'provider' && batch.changes.some((change) => change.kind === 'move')\n ? providerRewritten(batch, {\n ...layer,\n collection: parseCollection(layer.documents, composition),\n })\n : batch;\n layer = overlay(layer, [effective]);\n }\n return withdrawn;\n}\n"],"names":["parse","immutable","parseCollection","readCollection","validateCollection","overlay","overlayChanged","sameLayerText","providerRewritten","equalValue","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","previous","collection","documents","undefined","text","readStaged","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","replay","prior","Map","map","step","id","batch","before","old","get","hasMove","changes","some","change","kind","reuseRewrite","JSON","stringify","effective","after","push","replicaOf","queue","rewriting","Object","freeze","length","visible","predictedState","present","includes","holds","preconditions","parsed","documentAt","has","opened","set","ok","document","every","precondition","revision","value","hasOwn","fields","name","sections","preamble","withdrawals","withdrawable","withdrawn"],"mappings":"AAAA,SAASA,KAAK,QAAuB,uBAAuB;AAC5D,SAASC,SAAS,QAA6C,cAAc;AAC7E,SACEC,eAAe,EACfC,cAAc,EACdC,kBAAkB,QAGb,kBAAkB;AACzB,SAASC,OAAO,EAAEC,cAAc,EAAEC,aAAa,QAAoB,eAAe;AAClF,SAASC,iBAAiB,QAAwB,YAAY;AAC9D,SAASC,UAAU,QAAQ,kBAAkB;AA2B7C,OAAO,SAASC,cAAcC,MAAqB;IACjD,OAAO;QACLC,gBAAgBD,OAAOC,cAAc;QACrCC,OAAOF,OAAOE,KAAK;QACnBC,WACEH,OAAOI,cAAc,KAAK,OACtB,OACA;YAAEC,OAAOL,OAAOI,cAAc,CAACC,KAAK;YAAEH,OAAOF,OAAOM,cAAc;QAAC;IAC3E;AACF;AAEA,OAAO,SAASC,cACdP,MAAqB,EACrBQ,QAAyB;IAEzB,MAAMC,aAAajB,eACjBQ,OAAOU,SAAS,EAChBX,cAAcC,SACdQ,aAAaG,YACTA,YACA;QAAEC,MAAMJ,SAASR,MAAM,CAACU,SAAS;QAAED,YAAYD,SAASC,UAAU;IAAC;IAEzE,OAAOA,eAAe,OAAO,OAAO;QAAET;QAAQS;IAAW;AAC3D;AAEA,OAAO,SAASI,WACdb,MAAqB,EACrBQ,QAAyB;IAEzB,IACE,AAACR,CAAAA,OAAOE,KAAK,CAACY,MAAM,KAAK,aAAad,OAAOM,cAAc,CAACQ,MAAM,KAAK,SAAQ,KAC9EN,CAAAA,aAAaG,aACZ,CAACf,cAAcI,QAAQQ,SAASR,MAAM,KACtCA,OAAOE,KAAK,KAAKM,SAASR,MAAM,CAACE,KAAK,IACtCF,OAAOM,cAAc,KAAKE,SAASR,MAAM,CAACM,cAAc,AAAD,GACzD;QACA,MAAMS,UAAUtB,mBACdO,OAAOU,SAAS,EAChBV,OAAOgB,aAAa,EACpBjB,cAAcC;QAEhB,IAAIe,QAAQA,OAAO,KAAK,YAAYA,QAAQE,IAAI,KAAK,qBAAqB,OAAO;IACnF;IACA,OAAOV,cAAcP,QAAQQ;AAC/B;AAEA,OAAO,SAASU,cACdC,SAAyB,EACzBT,SAA2C,EAC3CU,SAA2C,EAC3CC,QAA2B,EAC3BC,WAAmB;IAEnB,MAAMC,gBAAgB;QAAE,GAAGJ,UAAUnB,MAAM,CAACU,SAAS;QAAE,GAAGA,SAAS;IAAC;IACpE,MAAMc,gBAAgB;QAAE,GAAGL,UAAUnB,MAAM,CAACoB,SAAS;QAAE,GAAGA,SAAS;IAAC;IACpE,MAAMJ,gBAAgB,IAAIS,IAAIN,UAAUnB,MAAM,CAACgB,aAAa;IAC5D,KAAK,MAAMU,QAAQL,SAAU;QAC3B,OAAOE,aAAa,CAACG,KAAK;QAC1B,OAAOF,aAAa,CAACE,KAAK;QAC1BV,cAAcW,MAAM,CAACD;IACvB;IACA,OAAOb,WACL;QACE,GAAGM,UAAUnB,MAAM;QACnBsB;QACAZ,WAAWa;QACXH,WAAWI;QACXR,eAAe;eAAIA;SAAc,CAACY,IAAI;IACxC,GACAT;AAEJ;AAEA,SAASU,UACPV,SAAyB,EACzBW,OAA+B,EAC/BtB,QAAkB;IAElB,MAAMuB,cAAchC,cAAcoB,UAAUnB,MAAM;IAClD,IAAIgC,QAAeb,UAAUnB,MAAM;IACnC,MAAMiC,SAAuB,EAAE;IAC/B,MAAMC,QAAQ,IAAIC,IAAI3B,UAAUyB,OAAOG,IAAI,CAACC,OAAS;YAACA,KAAKC,EAAE;YAAED;SAAK,KAAK,EAAE;IAC3E,KAAK,MAAME,SAAST,QAAS;QAC3B,MAAMU,SAASR;QACf,MAAMS,MAAMP,MAAMQ,GAAG,CAACH,MAAMD,EAAE;QAC9B,MAAMK,UAAUJ,MAAMK,OAAO,CAACC,IAAI,CAAC,CAACC,SAAWA,OAAOC,IAAI,KAAK;QAC/D,MAAMC,eACJP,KAAKhC,eAAeE,aACpBf,cAAc4C,QAAQC,IAAID,MAAM,KAChCC,IAAIhC,UAAU,CAACsB,WAAW,CAAC9B,cAAc,KAAK8B,YAAY9B,cAAc,IACxEwC,IAAIhC,UAAU,CAACsB,WAAW,CAAC7B,KAAK,KAAK6B,YAAY7B,KAAK,IACtDuC,IAAIhC,UAAU,CAACsB,WAAW,CAAC5B,SAAS,EAAED,UAAU6B,YAAY5B,SAAS,EAAED,SACvE+C,KAAKC,SAAS,CAACT,IAAIhC,UAAU,CAACsB,WAAW,CAAC5B,SAAS,EAAEE,WACnD4C,KAAKC,SAAS,CAACnB,YAAY5B,SAAS,EAAEE;QAC1C,MAAMI,aAAakC,UACfK,eACEP,IAAIhC,UAAU,GACdlB,gBACEiD,OAAO9B,SAAS,EAChBqB,aACAU,KAAKhC,eAAeE,YAChB;YAAEC,MAAMO,UAAUnB,MAAM,CAACU,SAAS;YAAED,YAAYU,UAAUV,UAAU;QAAC,IACrE;YAAEG,MAAM6B,IAAID,MAAM,CAAC9B,SAAS;YAAED,YAAYgC,IAAIhC,UAAU;QAAC,KAEjEE;QACJ,MAAMwC,YACJ1C,eAAeE,YACX4B,QACAS,eACEP,IAAIU,SAAS,GACbtD,kBAAkB0C,OAAO;YAAE,GAAGC,MAAM;YAAE/B;QAAW;QACzDuB,QACES,QAAQ9B,YACJjB,QAAQ8C,QAAQ;YAACW;SAAU,IAC3BxD,eAAe6C,QAAQ;YAACW;SAAU,EAAEV,IAAID,MAAM,EAAE;YAACC,IAAIU,SAAS;SAAC,EAAEV,IAAIW,KAAK;QAChFnB,OAAOoB,IAAI,CAAC;YACVf,IAAIC,MAAMD,EAAE;YACZE;YACAY,OAAOpB;YACPmB;YACA,GAAI1C,eAAeE,YAAY,CAAC,IAAI;gBAAEF;YAAW,CAAC;QACpD;IACF;IACA,OAAO;QAAEuB;QAAOC;IAAO;AACzB;AAEA,OAAO,SAASqB,UACdnC,SAAyB,EACzBoC,KAA6B,EAC7BC,SAAoB,EACpBhD,QAAkB;IAElB,MAAMsB,UAAU2B,OAAOC,MAAM,CAACH,MAAMnB,GAAG,CAAC9C;IACxC,IAAIwC,QAAQ6B,MAAM,KAAK,GAAG;QACxB,OAAO;YACLxC;YACAoC,OAAOzB;YACP8B,SAAS;gBACPlD,WAAWS,UAAUnB,MAAM,CAACU,SAAS;gBACrCM,eAAeG,UAAUnB,MAAM,CAACgB,aAAa;gBAC7CI,WAAWD,UAAUnB,MAAM,CAACoB,SAAS;gBACrCX,YAAYU,UAAUV,UAAU;YAClC;YACAwB,QAAQ,EAAE;QACZ;IACF;IACA,MAAM4B,iBAAiBL,cAAc,aAAa3B,UAAUV,WAAWW,SAAStB,YAAY;IAC5F,MAAMwB,QACJwB,cAAc,aACVK,eAAgB7B,KAAK,GACrBxB,aAAaG,YACXjB,QAAQyB,UAAUnB,MAAM,EAAE8B,WAC1BnC,eACEwB,UAAUnB,MAAM,EAChB8B,SACAtB,SAASW,SAAS,CAACnB,MAAM,EACzBQ,SAAS+C,KAAK,EACd/C,SAASoD,OAAO;IAE1B,OAAO;QACLzC;QACAoC,OAAOzB;QACPG,QAAQ4B,gBAAgB5B,UAAU,EAAE;QACpC2B,SAAS;YACP,GAAG5B,KAAK;YACRvB,YAAYlB,gBACVyC,MAAMtB,SAAS,EACfX,cAAcoB,UAAUnB,MAAM,GAC9BQ,aAAaG,YACTA,YACA;gBAAEC,MAAMJ,SAASoD,OAAO,CAAClD,SAAS;gBAAED,YAAYD,SAASoD,OAAO,CAACnD,UAAU;YAAC;QAEpF;IACF;AACF;AAEA,SAASqD,QAAQ9B,KAAY,EAAEN,IAAY;IACzC,OAAOM,MAAMtB,SAAS,CAACgB,KAAK,KAAKf,aAAaqB,MAAMhB,aAAa,CAAC+C,QAAQ,CAACrC;AAC7E;AAEA,SAASsC,MAAMhC,KAAY,EAAEiC,aAAsC;IACjE,MAAMC,SAAS,IAAI/B;IACnB,MAAMgC,aAAa,CAACzC;QAClB,IAAI,CAACwC,OAAOE,GAAG,CAAC1C,OAAO;YACrB,MAAMd,OAAOoB,MAAMtB,SAAS,CAACgB,KAAK;YAClC,MAAM2C,SAASzD,SAASD,YAAY,OAAOtB,MAAMuB,MAAMc;YACvDwC,OAAOI,GAAG,CAAC5C,MAAM2C,QAAQE,OAAO,OAAOF,OAAOG,QAAQ,GAAG;QAC3D;QACA,OAAON,OAAOxB,GAAG,CAAChB,SAAS;IAC7B;IACA,OAAOuC,cAAcQ,KAAK,CAAC,CAACC;QAC1B,MAAMhD,OAAOgD,aAAahD,IAAI;QAC9B,IAAIgD,aAAa3B,IAAI,KAAK,UAAU,OAAO,CAACe,QAAQ9B,OAAON;QAC3D,IAAIgD,aAAa3B,IAAI,KAAK,WAAW,OAAOe,QAAQ9B,OAAON;QAC3D,IAAIgD,aAAa3B,IAAI,KAAK,YAAY;YACpC,OAAOe,QAAQ9B,OAAON,SAASM,MAAMZ,SAAS,CAACM,KAAK,KAAKgD,aAAaC,QAAQ;QAChF;QACA,MAAMH,WAAWL,WAAWzC;QAC5B,IAAI8C,aAAa,MAAM,OAAO;QAC9B,IAAIE,aAAa3B,IAAI,KAAK,SAAS;YACjC,MAAM6B,QAAQnB,OAAOoB,MAAM,CAACL,SAASM,MAAM,EAAEJ,aAAaK,IAAI,IAC1DP,SAASM,MAAM,CAACJ,aAAaK,IAAI,CAAC,GAClCpE;YACJ,OAAOb,WAAW8E,OAAOF,aAAaE,KAAK;QAC7C;QACA,IAAIF,aAAa3B,IAAI,KAAK,WAAW;YACnC,OACEU,OAAOoB,MAAM,CAACL,SAASQ,QAAQ,EAAEN,aAAaK,IAAI,KAClDP,SAASQ,QAAQ,CAACN,aAAaK,IAAI,CAAC,KAAKL,aAAaE,KAAK;QAE/D;QACA,OAAOJ,SAASS,QAAQ,KAAKP,aAAaE,KAAK;IACjD;AACF;AAEA,OAAO,SAASM,YACd/D,SAAyB,EACzBoC,KAA6B,EAC7B4B,YAA6C,EAC7C3B,SAAoB;IAEpB,IAAI,CAACD,MAAMV,IAAI,CAACsC,eAAe,OAAO,EAAE;IACxC,MAAMpD,cAAchC,cAAcoB,UAAUnB,MAAM;IAClD,IAAIgC,QAAeb,UAAUnB,MAAM;IACnC,MAAMoF,YAA2B,EAAE;IACnC,KAAK,MAAM7C,SAASgB,MAAO;QACzB,IAAI4B,aAAa5C,UAAU,CAACyB,MAAMhC,OAAOO,MAAM0B,aAAa,GAAG;YAC7DmB,UAAU/B,IAAI,CAACd;YACf;QACF;QACA,MAAMY,YACJK,cAAc,cAAcjB,MAAMK,OAAO,CAACC,IAAI,CAAC,CAACC,SAAWA,OAAOC,IAAI,KAAK,UACvElD,kBAAkB0C,OAAO;YACvB,GAAGP,KAAK;YACRvB,YAAYlB,gBAAgByC,MAAMtB,SAAS,EAAEqB;QAC/C,KACAQ;QACNP,QAAQtC,QAAQsC,OAAO;YAACmB;SAAU;IACpC;IACA,OAAOiC;AACT"}