@agentshouse/mdruntime 0.1.0-ce131cb435f8b → 0.1.0-ce9f29a01a271

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 (66) hide show
  1. package/dist/adapter.d.ts +12 -0
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/change-set.d.ts +5 -2
  4. package/dist/change-set.d.ts.map +1 -1
  5. package/dist/change-set.js +6 -1
  6. package/dist/chat/list.d.ts +2 -1
  7. package/dist/chat/list.d.ts.map +1 -1
  8. package/dist/chat/list.js +2 -2
  9. package/dist/chat/markdown.d.ts +1 -0
  10. package/dist/chat/markdown.d.ts.map +1 -1
  11. package/dist/chat/markdown.js +78 -20
  12. package/dist/chat/message.d.ts.map +1 -1
  13. package/dist/chat/message.js +9 -2
  14. package/dist/chat/messages.d.ts.map +1 -1
  15. package/dist/chat/messages.js +36 -16
  16. package/dist/chat/overlay.d.ts +1 -0
  17. package/dist/chat/overlay.d.ts.map +1 -1
  18. package/dist/chat/overlay.js +10 -0
  19. package/dist/chat/pieces.d.ts +62 -0
  20. package/dist/chat/pieces.d.ts.map +1 -0
  21. package/dist/chat/pieces.js +1110 -0
  22. package/dist/chat/provider.d.ts +1 -0
  23. package/dist/chat/provider.d.ts.map +1 -1
  24. package/dist/chat/provider.js +12 -3
  25. package/dist/chat/ready.d.ts +1 -1
  26. package/dist/chat/ready.d.ts.map +1 -1
  27. package/dist/chat/ready.js +1 -1
  28. package/dist/chat/steady.d.ts +3 -0
  29. package/dist/chat/steady.d.ts.map +1 -0
  30. package/dist/chat/steady.js +26 -0
  31. package/dist/chat.d.ts +2 -2
  32. package/dist/chat.d.ts.map +1 -1
  33. package/dist/chat.js +2 -2
  34. package/dist/connection.d.ts.map +1 -1
  35. package/dist/connection.js +45 -30
  36. package/dist/conversation.d.ts +5 -0
  37. package/dist/conversation.d.ts.map +1 -1
  38. package/dist/conversation.js +35 -1
  39. package/dist/host.d.ts +1 -1
  40. package/dist/host.d.ts.map +1 -1
  41. package/dist/host.js +1 -1
  42. package/dist/overlay.d.ts +3 -4
  43. package/dist/overlay.d.ts.map +1 -1
  44. package/dist/overlay.js +178 -141
  45. package/dist/read-side.d.ts.map +1 -1
  46. package/dist/read-side.js +4 -2
  47. package/dist/refresh.d.ts.map +1 -1
  48. package/dist/refresh.js +34 -15
  49. package/dist/replica.d.ts +2 -1
  50. package/dist/replica.d.ts.map +1 -1
  51. package/dist/replica.js +18 -15
  52. package/dist/room-draft.d.ts.map +1 -1
  53. package/dist/room-draft.js +8 -9
  54. package/dist/save.d.ts +1 -1
  55. package/dist/save.d.ts.map +1 -1
  56. package/dist/save.js +154 -92
  57. package/dist/shared.d.ts +1 -0
  58. package/dist/shared.d.ts.map +1 -1
  59. package/dist/shared.js +5 -1
  60. package/dist/store.d.ts +2 -0
  61. package/dist/store.d.ts.map +1 -1
  62. package/dist/store.js +387 -339
  63. package/dist/turn.d.ts +1 -1
  64. package/dist/turn.d.ts.map +1 -1
  65. package/dist/turn.js +4 -4
  66. package/package.json +2 -2
package/dist/overlay.js CHANGED
@@ -1,6 +1,6 @@
1
- import { apply, parse, serialize } from '@agentshouse/mdmodel';
2
- import { differences, differing, drafted, patched, settled } from './shared.js';
3
- import { finished } from './turn.js';
1
+ import { apply, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
2
+ import { differences, drafted, patching, settling } from './shared.js';
3
+ import { ROW_WEIGHT } from './turn.js';
4
4
  export function acceptedBinaries(files) {
5
5
  return Object.fromEntries(Object.entries(files).map(([path, file]) => [path, { state: 'accepted', ...file }]));
6
6
  }
@@ -24,10 +24,13 @@ export function sameChange(left, right) {
24
24
  left.author?.name === right.author?.name);
25
25
  }
26
26
  const EMPTY_FRONTMATTER = '---\n---\n';
27
+ function isPart(change) {
28
+ return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
29
+ }
27
30
  function at(path, name) {
28
31
  return `${path} ${name}`;
29
32
  }
30
- function priorsOf(preconditions) {
33
+ function* priorsOf(preconditions) {
31
34
  const fields = new Map();
32
35
  const sections = new Map();
33
36
  const preambles = new Map();
@@ -41,6 +44,7 @@ function priorsOf(preconditions) {
41
44
  if (precondition.kind === 'preamble') {
42
45
  preambles.set(precondition.path, precondition.value);
43
46
  }
47
+ yield ROW_WEIGHT;
44
48
  }
45
49
  return {
46
50
  field: (path, name) => fields.get(at(path, name)),
@@ -56,51 +60,50 @@ function compose(fields, sections) {
56
60
  const opened = parse(skeleton);
57
61
  if (!opened.ok)
58
62
  return skeleton;
59
- let document = opened.document;
60
- for (const [name, value] of Object.entries(fields)) {
61
- const next = apply(document, { kind: 'field', name, value, prior: undefined });
62
- if (next.outcome === 'applied')
63
- document = next.document;
64
- }
65
- return serialize(document);
63
+ const next = apply(opened.document, Object.entries(fields).flatMap(([name, value]) => frontmatterValue(value) ? [{ kind: 'field', name, value, prior: undefined }] : []));
64
+ return serialize(next.outcome === 'applied' ? next.document : opened.document);
66
65
  }
67
- function edited(document, change, priors) {
68
- if (change.kind === 'field') {
69
- return apply(document, {
66
+ function edited(change, priors) {
67
+ if (change.kind === 'field')
68
+ return {
70
69
  kind: 'field',
71
70
  name: change.name,
72
71
  value: change.value,
73
72
  prior: priors.field(change.path, change.name),
74
- });
75
- }
76
- if (change.kind === 'preamble') {
77
- return apply(document, {
78
- kind: 'preamble',
79
- value: change.value,
80
- prior: priors.preamble(change.path),
81
- });
82
- }
83
- if (change.kind !== 'section')
84
- return null;
85
- return apply(document, {
73
+ };
74
+ if (change.kind === 'preamble')
75
+ return { kind: 'preamble', value: change.value, prior: priors.preamble(change.path) };
76
+ return {
86
77
  kind: 'section',
87
78
  name: change.name,
88
79
  value: change.value,
89
80
  prior: priors.section(change.path, change.name),
90
- });
81
+ };
91
82
  }
92
- function edit(staged, change, priors) {
93
- const text = staged.documents[change.path];
83
+ function edit(staged, changes, priors) {
84
+ const path = changes[0].path;
85
+ delete staged.revisions[path];
86
+ const text = staged.documents[path];
94
87
  if (text === undefined)
95
- return false;
96
- const parsed = parse(text, change.path);
88
+ return changes.length;
89
+ const parsed = parse(text, path);
97
90
  if (!parsed.ok)
98
- return false;
99
- const next = edited(parsed.document, change, priors);
100
- if (next?.outcome !== 'applied')
101
- return false;
102
- staged.documents[change.path] = serialize(next.document);
103
- return true;
91
+ return changes.length;
92
+ const wanted = changes.map((change) => edited(change, priors));
93
+ const first = apply(parsed.document, wanted);
94
+ if (first.outcome === 'refuse')
95
+ return changes.length;
96
+ if (first.outcome === 'applied') {
97
+ staged.documents[path] = serialize(first.document);
98
+ return 0;
99
+ }
100
+ const stale = new Set(first.stale);
101
+ const kept = wanted.filter((_, at) => !stale.has(at));
102
+ const rest = apply(parsed.document, kept);
103
+ if (rest.outcome !== 'applied')
104
+ return changes.length;
105
+ staged.documents[path] = serialize(rest.document);
106
+ return first.stale.length;
104
107
  }
105
108
  function relocate(staged, from, to) {
106
109
  const text = staged.documents[from];
@@ -141,11 +144,7 @@ function erase(staged, path) {
141
144
  delete staged.changes[path];
142
145
  delete staged.binaries[path];
143
146
  }
144
- function stage(staged, change, priors) {
145
- if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
146
- delete staged.revisions[change.path];
147
- return edit(staged, change, priors);
148
- }
147
+ function stage(staged, change) {
149
148
  if (change.kind === 'create') {
150
149
  staged.documents[change.path] =
151
150
  'content' in change ? change.content : compose(change.fields, change.sections);
@@ -180,7 +179,7 @@ function stage(staged, change, priors) {
180
179
  erase(staged, change.path);
181
180
  return true;
182
181
  }
183
- export function overlay(base, queue, unapplied) {
182
+ export function* overlaying(base, queue, unapplied) {
184
183
  const staged = {
185
184
  documents: drafted(base.documents),
186
185
  binaries: drafted(base.binaries),
@@ -189,140 +188,178 @@ export function overlay(base, queue, unapplied) {
189
188
  changes: drafted(base.changes),
190
189
  };
191
190
  for (const batch of queue) {
192
- const priors = priorsOf(batch.preconditions);
193
- for (const change of batch.changes) {
194
- if (!stage(staged, change, priors))
191
+ const priors = yield* priorsOf(batch.preconditions);
192
+ for (let index = 0; index < batch.changes.length; index += 1) {
193
+ const change = batch.changes[index];
194
+ if (!isPart(change)) {
195
+ if (!stage(staged, change))
196
+ unapplied?.();
197
+ yield ROW_WEIGHT;
198
+ continue;
199
+ }
200
+ const run = [change];
201
+ while (index + 1 < batch.changes.length) {
202
+ const next = batch.changes[index + 1];
203
+ if (!isPart(next) || next.path !== change.path)
204
+ break;
205
+ run.push(next);
206
+ index += 1;
207
+ }
208
+ const text = staged.documents[change.path] ?? '';
209
+ for (let left = edit(staged, run, priors); left > 0; left -= 1)
195
210
  unapplied?.();
211
+ yield ROW_WEIGHT + text.length;
196
212
  }
197
213
  }
198
214
  return {
199
- documents: settled(staged.documents),
200
- binaries: settled(staged.binaries),
201
- revisions: settled(staged.revisions),
202
- fileIds: settled(staged.fileIds),
203
- changes: settled(staged.changes),
215
+ documents: yield* settling(staged.documents),
216
+ binaries: yield* settling(staged.binaries),
217
+ revisions: yield* settling(staged.revisions),
218
+ fileIds: yield* settling(staged.fileIds),
219
+ changes: yield* settling(staged.changes),
204
220
  };
205
221
  }
206
- function pathsOf(batch) {
207
- return batch.changes.flatMap((change) => change.kind === 'move' ? [change.path, change.to] : [change.path]);
208
- }
209
- export function sameLayerText(left, right) {
210
- return finished(sameText(left, right));
222
+ function* pathsOf(batch) {
223
+ const paths = new Set();
224
+ for (const change of batch.changes) {
225
+ paths.add(change.path);
226
+ if (change.kind === 'move')
227
+ paths.add(change.to);
228
+ yield ROW_WEIGHT;
229
+ }
230
+ return paths;
211
231
  }
212
232
  export function* sameText(left, right) {
213
233
  return ((yield* differences(left.documents, right.documents)).size === 0 &&
214
234
  (yield* differences(left.binaries, right.binaries, sameBinary)).size === 0);
215
235
  }
216
- export function changedPaths(left, right) {
236
+ export function* changedPaths(left, right) {
217
237
  return new Set([
218
- ...differing(left.documents, right.documents),
219
- ...differing(left.revisions, right.revisions),
220
- ...differing(left.fileIds, right.fileIds),
221
- ...differing(left.changes, right.changes, sameChange),
222
- ...differing(left.binaries, right.binaries, sameBinary),
238
+ ...(yield* differences(left.documents, right.documents)),
239
+ ...(yield* differences(left.revisions, right.revisions)),
240
+ ...(yield* differences(left.fileIds, right.fileIds)),
241
+ ...(yield* differences(left.changes, right.changes, sameChange)),
242
+ ...(yield* differences(left.binaries, right.binaries, sameBinary)),
223
243
  ]);
224
244
  }
225
- function replayHeads(base, queue) {
245
+ function* sameItems(left, right) {
246
+ if (left.length !== right.length)
247
+ return false;
248
+ for (let index = 0; index < left.length; index += 1) {
249
+ const item = JSON.stringify(left[index]);
250
+ if (item !== JSON.stringify(right[index]))
251
+ return false;
252
+ yield ROW_WEIGHT + item.length;
253
+ }
254
+ return true;
255
+ }
256
+ function* sameBatch(left, right) {
257
+ if (left === right)
258
+ return true;
259
+ const { changes, preconditions, ...rest } = left;
260
+ const { changes: others, preconditions: priors, ...held } = right;
261
+ return (JSON.stringify(rest) === JSON.stringify(held) &&
262
+ (yield* sameItems(changes, others)) &&
263
+ (yield* sameItems(preconditions, priors)));
264
+ }
265
+ function* replayHeads(base, batch) {
226
266
  const heads = {
227
267
  revisions: drafted(base.revisions),
228
268
  fileIds: drafted(base.fileIds),
229
269
  changes: drafted(base.changes),
230
270
  };
231
- for (const batch of queue) {
232
- for (const change of batch.changes) {
233
- if (change.kind === 'remove') {
234
- delete heads.revisions[change.path];
235
- delete heads.fileIds[change.path];
236
- delete heads.changes[change.path];
237
- }
238
- else if (change.kind === 'create') {
239
- delete heads.fileIds[change.path];
240
- delete heads.changes[change.path];
241
- }
242
- else if (change.kind === 'replace' ||
243
- change.kind === 'field' ||
244
- change.kind === 'section' ||
245
- change.kind === 'preamble') {
246
- delete heads.revisions[change.path];
247
- }
248
- else if (change.kind === 'binary') {
249
- delete heads.revisions[change.path];
250
- delete heads.changes[change.path];
251
- }
252
- else if (change.kind === 'move') {
253
- moveHead(heads, change.path, change.to);
254
- }
271
+ for (const change of batch.changes) {
272
+ if (change.kind === 'remove') {
273
+ delete heads.revisions[change.path];
274
+ delete heads.fileIds[change.path];
275
+ delete heads.changes[change.path];
276
+ }
277
+ else if (change.kind === 'create') {
278
+ delete heads.fileIds[change.path];
279
+ delete heads.changes[change.path];
255
280
  }
281
+ else if (change.kind === 'replace' ||
282
+ change.kind === 'field' ||
283
+ change.kind === 'section' ||
284
+ change.kind === 'preamble') {
285
+ delete heads.revisions[change.path];
286
+ }
287
+ else if (change.kind === 'binary') {
288
+ delete heads.revisions[change.path];
289
+ delete heads.changes[change.path];
290
+ }
291
+ else if (change.kind === 'move') {
292
+ moveHead(heads, change.path, change.to);
293
+ }
294
+ yield ROW_WEIGHT;
256
295
  }
257
296
  return {
258
- revisions: settled(heads.revisions),
259
- fileIds: settled(heads.fileIds),
260
- changes: settled(heads.changes),
297
+ revisions: yield* settling(heads.revisions),
298
+ fileIds: yield* settling(heads.fileIds),
299
+ changes: yield* settling(heads.changes),
261
300
  };
262
301
  }
263
- export function overlayChanged(base, queue, previousBase, previousQueue, previousVisible) {
264
- const before = previousQueue.map((batch) => JSON.stringify(batch));
265
- const after = queue.map((batch) => JSON.stringify(batch));
266
- if (before.length === after.length &&
267
- before.every((id, index) => id === after[index]) &&
268
- sameLayerText(base, previousBase)) {
302
+ function* repatched(held, paths, value) {
303
+ const set = [];
304
+ const removed = [];
305
+ for (const path of paths) {
306
+ const found = value(path);
307
+ if (found === undefined)
308
+ removed.push(path);
309
+ else
310
+ set.push([path, found]);
311
+ yield ROW_WEIGHT;
312
+ }
313
+ return yield* patching(held, set, removed);
314
+ }
315
+ export function* overlayChanged(base, batch, previousBase, previousBatch, previousVisible) {
316
+ const same = yield* sameBatch(batch, previousBatch);
317
+ if (same && (yield* sameText(base, previousBase))) {
269
318
  return {
270
319
  documents: previousVisible.documents,
271
320
  binaries: previousVisible.binaries,
272
- ...replayHeads(base, queue),
321
+ ...(yield* replayHeads(base, batch)),
273
322
  };
274
323
  }
275
- const affected = new Set(changedPaths(base, previousBase));
276
- const oldIds = new Set(before);
277
- const newIds = new Set(after);
278
- for (const batch of previousQueue) {
279
- if (!newIds.has(JSON.stringify(batch)))
280
- for (const path of pathsOf(batch))
281
- affected.add(path);
282
- }
283
- for (const batch of queue) {
284
- if (!oldIds.has(JSON.stringify(batch)))
285
- for (const path of pathsOf(batch))
286
- affected.add(path);
287
- }
288
- let expanded = true;
289
- while (expanded) {
290
- expanded = false;
291
- for (const batch of queue) {
292
- const touched = pathsOf(batch);
293
- if (!touched.some((path) => affected.has(path)))
294
- continue;
295
- for (const path of touched) {
296
- if (affected.has(path))
297
- continue;
298
- affected.add(path);
299
- expanded = true;
300
- }
301
- }
324
+ const affected = new Set(yield* changedPaths(base, previousBase));
325
+ const touched = yield* pathsOf(batch);
326
+ let replayed = !same;
327
+ if (replayed)
328
+ for (const path of yield* pathsOf(previousBatch))
329
+ affected.add(path);
330
+ for (const path of touched) {
331
+ if (affected.has(path))
332
+ replayed = true;
333
+ yield ROW_WEIGHT;
302
334
  }
303
- const documents = {};
304
- const revisions = {};
305
- const fileIds = {};
306
- const changes = {};
307
- const binaries = {};
308
- for (const path of affected) {
335
+ const restricted = {
336
+ documents: {},
337
+ revisions: {},
338
+ fileIds: {},
339
+ changes: {},
340
+ binaries: {},
341
+ };
342
+ for (const path of replayed ? touched : []) {
343
+ affected.add(path);
309
344
  if (base.documents[path] !== undefined)
310
- documents[path] = base.documents[path];
345
+ restricted.documents[path] = base.documents[path];
311
346
  if (base.revisions[path] !== undefined)
312
- revisions[path] = base.revisions[path];
347
+ restricted.revisions[path] = base.revisions[path];
313
348
  if (base.fileIds[path] !== undefined)
314
- fileIds[path] = base.fileIds[path];
349
+ restricted.fileIds[path] = base.fileIds[path];
315
350
  if (base.changes[path] !== undefined)
316
- changes[path] = base.changes[path];
351
+ restricted.changes[path] = base.changes[path];
317
352
  if (base.binaries[path] !== undefined)
318
- binaries[path] = base.binaries[path];
353
+ restricted.binaries[path] = base.binaries[path];
354
+ yield ROW_WEIGHT;
319
355
  }
320
- const staged = overlay({ documents, revisions, fileIds, changes, binaries }, queue.filter((batch) => pathsOf(batch).some((path) => affected.has(path))));
356
+ const staged = replayed ? yield* overlaying(restricted, [batch]) : base;
357
+ const from = (path) => (touched.has(path) ? staged : base);
321
358
  return {
322
- documents: patched(previousVisible.documents, Object.entries(staged.documents), affected),
323
- revisions: patched(previousVisible.revisions, Object.entries(staged.revisions), affected),
324
- fileIds: patched(previousVisible.fileIds, Object.entries(staged.fileIds), affected),
325
- changes: patched(previousVisible.changes, Object.entries(staged.changes), affected),
326
- binaries: patched(previousVisible.binaries, Object.entries(staged.binaries), affected),
359
+ documents: yield* repatched(previousVisible.documents, affected, (path) => from(path).documents[path]),
360
+ revisions: yield* repatched(previousVisible.revisions, affected, (path) => from(path).revisions[path]),
361
+ fileIds: yield* repatched(previousVisible.fileIds, affected, (path) => from(path).fileIds[path]),
362
+ changes: yield* repatched(previousVisible.changes, affected, (path) => from(path).changes[path]),
363
+ binaries: yield* repatched(previousVisible.binaries, affected, (path) => from(path).binaries[path]),
327
364
  };
328
365
  }
@@ -1 +1 @@
1
- {"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAOV,aAAa,EACb,IAAI,EAEJ,aAAa,EAGb,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA8B,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkDpD,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAAG,aAAa,CAAC;AAwBhE,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,IAAI,IAAI,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,EAAE,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,KAAK,EAClB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GACvC,MAAM,IAAI,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAucF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,WAAW,GAChB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,CA+CtD;AA4BD,wBAAgB,cAAc,IAAI,QAAQ,CA8WzC"}
1
+ {"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAOV,aAAa,EACb,IAAI,EAEJ,aAAa,EAGb,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA8B,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkDpD,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAAG,aAAa,CAAC;AAwBhE,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,IAAI,IAAI,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,EAAE,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,KAAK,EAClB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GACvC,MAAM,IAAI,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAycF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,WAAW,GAChB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,CA+CtD;AA4BD,wBAAgB,cAAc,IAAI,QAAQ,CA+WzC"}
package/dist/read-side.js CHANGED
@@ -317,6 +317,7 @@ function documentOf(key, row, shape, bodies) {
317
317
  function weight(row) {
318
318
  return ROW_WEIGHT + (typeof row?.text === 'string' ? row.text.length : 0);
319
319
  }
320
+ const HELD_PER_WEIGHT = 16;
320
321
  function groupValues(shape, [key, row]) {
321
322
  return [...shape.orderBy.map(({ by }) => (by === 'count' ? row.count : row[`key${by}`])), key];
322
323
  }
@@ -617,14 +618,15 @@ export function createReadSide() {
617
618
  return inUnits(set.documents, (change) => {
618
619
  if (closed)
619
620
  return 0;
621
+ const shifted = rows.size / HELD_PER_WEIGHT;
620
622
  let spent = 0;
621
623
  for (const row of change.before) {
622
624
  unit.set(row.key, null);
623
- spent += ROW_WEIGHT;
625
+ spent += ROW_WEIGHT + shifted;
624
626
  }
625
627
  for (const row of change.after) {
626
628
  unit.set(row.key, row);
627
- spent += weight(row);
629
+ spent += weight(row) + shifted;
628
630
  }
629
631
  return spent;
630
632
  }, () => {
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAe,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjG,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,gBAAgB,GAChB,WAAW,GACX,cAAc,CAAC;AAEnB,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,gBAAgB,GAChB,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,KAAK,EACd,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,WAAW,CAAC,CA8EtB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,KAAK,EACd,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,cAAc,CAAC,CAKzB"}
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAe,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjG,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,gBAAgB,GAChB,WAAW,GACX,cAAc,CAAC;AAEnB,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,gBAAgB,GAChB,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,KAAK,EACd,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,WAAW,CAAC,CAgGtB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,KAAK,EACd,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,cAAc,CAAC,CAKzB"}
package/dist/refresh.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { acceptedBinaries } from './overlay.js';
2
2
  import { readStaged } from './replica.js';
3
- import { drafted, settled } from './shared.js';
3
+ import { drafted, settling } from './shared.js';
4
+ import { ROW_WEIGHT, stepped } from './turn.js';
4
5
  import { unconfirmed } from './transfer.js';
5
6
  export async function advancement(adapter, authorization, held, remodel, continuing) {
6
7
  const locator = held.locator;
@@ -23,24 +24,41 @@ export async function advancement(adapter, authorization, held, remodel, continu
23
24
  const changes = drafted(held.changes);
24
25
  const written = drafted(held.written);
25
26
  const binaries = drafted(held.binaries);
26
- const stage = (page) => {
27
+ const stage = function* (page) {
27
28
  for (const path of Object.keys(page.documents)) {
28
29
  delete binaries[path];
29
30
  delete fileIds[path];
30
31
  delete changes[path];
31
32
  written[path] = roomVersion;
33
+ yield ROW_WEIGHT;
32
34
  }
33
35
  for (const path of Object.keys(page.binaryFiles)) {
34
36
  delete documents[path];
35
37
  delete fileIds[path];
36
38
  delete changes[path];
37
39
  delete written[path];
40
+ yield ROW_WEIGHT;
41
+ }
42
+ for (const [path, content] of Object.entries(page.documents)) {
43
+ documents[path] = content;
44
+ yield ROW_WEIGHT + content.length;
45
+ }
46
+ for (const [path, binary] of Object.entries(acceptedBinaries(page.binaryFiles))) {
47
+ binaries[path] = binary;
48
+ yield ROW_WEIGHT;
49
+ }
50
+ for (const [path, revision] of Object.entries(page.revisions)) {
51
+ revisions[path] = revision;
52
+ yield ROW_WEIGHT;
53
+ }
54
+ for (const [path, fileId] of Object.entries(page.fileIds ?? {})) {
55
+ fileIds[path] = fileId;
56
+ yield ROW_WEIGHT;
57
+ }
58
+ for (const [path, change] of Object.entries(page.changes)) {
59
+ changes[path] = change;
60
+ yield ROW_WEIGHT;
38
61
  }
39
- Object.assign(documents, page.documents);
40
- Object.assign(binaries, acceptedBinaries(page.binaryFiles));
41
- Object.assign(revisions, page.revisions);
42
- Object.assign(fileIds, page.fileIds);
43
- Object.assign(changes, page.changes);
44
62
  for (const path of page.removals) {
45
63
  delete documents[path];
46
64
  delete revisions[path];
@@ -48,9 +66,10 @@ export async function advancement(adapter, authorization, held, remodel, continu
48
66
  delete changes[path];
49
67
  delete written[path];
50
68
  delete binaries[path];
69
+ yield ROW_WEIGHT;
51
70
  }
52
71
  };
53
- stage(first);
72
+ await stepped(stage(first));
54
73
  let pageToken = first.pageToken;
55
74
  while (pageToken !== undefined) {
56
75
  if (!continuing())
@@ -67,7 +86,7 @@ export async function advancement(adapter, authorization, held, remodel, continu
67
86
  return page;
68
87
  if (page.roomVersion !== roomVersion)
69
88
  return unconfirmed;
70
- stage(page);
89
+ await stepped(stage(page));
71
90
  pageToken = page.pageToken;
72
91
  }
73
92
  return {
@@ -77,12 +96,12 @@ export async function advancement(adapter, authorization, held, remodel, continu
77
96
  model: models.collection,
78
97
  selectionModel: models.selection,
79
98
  roomVersion,
80
- documents: settled(documents),
81
- binaries: settled(binaries),
82
- revisions: settled(revisions),
83
- fileIds: settled(fileIds),
84
- changes: settled(changes),
85
- written: settled(written),
99
+ documents: await stepped(settling(documents)),
100
+ binaries: await stepped(settling(binaries)),
101
+ revisions: await stepped(settling(revisions)),
102
+ fileIds: await stepped(settling(fileIds)),
103
+ changes: await stepped(settling(changes)),
104
+ written: await stepped(settling(written)),
86
105
  },
87
106
  };
88
107
  }
package/dist/replica.d.ts CHANGED
@@ -40,12 +40,13 @@ type Accepted = Extract<MutationResult, {
40
40
  kind: 'accepted';
41
41
  }>;
42
42
  export declare function applyReturned(confirmed: ConfirmedLayer, submitted: ChangeBatch, accepted: Accepted, roomVersion: string, writtenAt: string): Later<Staged>;
43
+ export declare function replicating(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Generator<number, Replica, void>;
43
44
  export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Replica;
44
45
  export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer, current?: Readonly<Record<string, string>>): boolean;
45
46
  export type Standing = {
46
47
  readonly withdrawn: readonly ChangeBatch[];
47
48
  readonly kept: readonly ChangeBatch[];
48
49
  };
49
- export declare function standing(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, local: boolean): Standing;
50
+ export declare function standing(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, local: boolean): Generator<number, Standing, void>;
50
51
  export {};
51
52
  //# sourceMappingURL=replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"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"}