@agentshouse/mdruntime 0.1.0-cf28918c2bf91 → 0.1.0-cf6d5f0a5c9c8

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 (79) hide show
  1. package/AGENTS.md +68 -22
  2. package/README.md +10 -10
  3. package/dist/adapter.d.ts +58 -25
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -9
  6. package/dist/attached-model.d.ts +11 -0
  7. package/dist/attached-model.d.ts.map +1 -0
  8. package/dist/attached-model.js +47 -0
  9. package/dist/bootstrap.d.ts +20 -6
  10. package/dist/bootstrap.d.ts.map +1 -1
  11. package/dist/bootstrap.js +89 -35
  12. package/dist/change-set.d.ts.map +1 -1
  13. package/dist/change-set.js +13 -7
  14. package/dist/client.d.ts +6 -3
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +38 -10
  17. package/dist/collection.d.ts +6 -11
  18. package/dist/collection.d.ts.map +1 -1
  19. package/dist/collection.js +56 -19
  20. package/dist/connection.d.ts +13 -13
  21. package/dist/connection.d.ts.map +1 -1
  22. package/dist/connection.js +643 -542
  23. package/dist/conversation.d.ts +18 -6
  24. package/dist/conversation.d.ts.map +1 -1
  25. package/dist/conversation.js +179 -78
  26. package/dist/host.d.ts +8 -1
  27. package/dist/host.d.ts.map +1 -1
  28. package/dist/host.js +35 -31
  29. package/dist/identity.d.ts +1 -0
  30. package/dist/identity.d.ts.map +1 -1
  31. package/dist/identity.js +7 -1
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/memory.d.ts +12 -5
  35. package/dist/memory.d.ts.map +1 -1
  36. package/dist/memory.js +92 -31
  37. package/dist/model.d.ts +11 -11
  38. package/dist/model.d.ts.map +1 -1
  39. package/dist/model.js +6 -3
  40. package/dist/observation.d.ts +2 -0
  41. package/dist/observation.d.ts.map +1 -1
  42. package/dist/observation.js +24 -14
  43. package/dist/paths.d.ts +0 -1
  44. package/dist/paths.d.ts.map +1 -1
  45. package/dist/paths.js +0 -16
  46. package/dist/query.d.ts +8 -3
  47. package/dist/query.d.ts.map +1 -1
  48. package/dist/query.js +75 -36
  49. package/dist/reach.d.ts +40 -0
  50. package/dist/reach.d.ts.map +1 -0
  51. package/dist/reach.js +270 -0
  52. package/dist/react.d.ts +39 -0
  53. package/dist/react.d.ts.map +1 -0
  54. package/dist/react.js +63 -0
  55. package/dist/read-side.d.ts +4 -0
  56. package/dist/read-side.d.ts.map +1 -1
  57. package/dist/read-side.js +116 -54
  58. package/dist/refresh.d.ts +12 -1
  59. package/dist/refresh.d.ts.map +1 -1
  60. package/dist/refresh.js +35 -22
  61. package/dist/replica.d.ts +6 -6
  62. package/dist/replica.d.ts.map +1 -1
  63. package/dist/replica.js +41 -36
  64. package/dist/room-draft.d.ts +3 -0
  65. package/dist/room-draft.d.ts.map +1 -1
  66. package/dist/room-draft.js +7 -5
  67. package/dist/rows.d.ts +4 -1
  68. package/dist/rows.d.ts.map +1 -1
  69. package/dist/rows.js +82 -39
  70. package/dist/save.d.ts +1 -2
  71. package/dist/save.d.ts.map +1 -1
  72. package/dist/save.js +106 -58
  73. package/dist/store.d.ts +25 -2
  74. package/dist/store.d.ts.map +1 -1
  75. package/dist/store.js +206 -90
  76. package/dist/wire.d.ts +52 -16
  77. package/dist/wire.d.ts.map +1 -1
  78. package/dist/wire.js +51 -59
  79. package/package.json +14 -2
@@ -1 +1 @@
1
- {"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAOV,IAAI,EAGJ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAqDpD,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,KAAK,IAAI,GACpD,MAAM,IAAI,CAAC;IACd,SAAS,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAySF,wBAAgB,cAAc,IAAI,QAAQ,CA4HzC"}
1
+ {"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAOV,IAAI,EAIJ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAuDpD,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,KAAK,IAAI,GACpD,MAAM,IAAI,CAAC;IACd,SAAS,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AA+UF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,WAAW,GAChB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CA4BpD;AAED,wBAAgB,cAAc,IAAI,QAAQ,CA4HzC"}
package/dist/read-side.js CHANGED
@@ -1,62 +1,71 @@
1
- import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, gt, gte, inArray, isNull, isUndefined, lt, lte, not, or, toArray, } from '@tanstack/db';
1
+ import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, inArray, or, toArray, } from '@tanstack/db';
2
+ import { ARRAY_INDEX, pointerSegments } from '@agentshouse/mdmodel';
2
3
  import { rowsOf } from './observation.js';
3
4
  import { documentKey } from './rows.js';
4
5
  function every(expressions) {
5
6
  const [first, second, ...rest] = expressions;
6
7
  return second === undefined ? first : and(first, second, ...rest);
7
8
  }
8
- function some(expressions) {
9
- const [first, second, ...rest] = expressions;
10
- return second === undefined ? first : or(first, second, ...rest);
9
+ function same(held, value) {
10
+ return Array.isArray(held) ? held.includes(value) : held === value;
11
11
  }
12
- function equal(field, value) {
13
- return or(eq(field, value), inArray(value, field));
12
+ function ordered(held, [operator, bound]) {
13
+ if (typeof held !== typeof bound || held === null || typeof held === 'object')
14
+ return false;
15
+ const left = held;
16
+ const right = bound;
17
+ if (operator === 'gt')
18
+ return left > right;
19
+ if (operator === 'gte')
20
+ return left >= right;
21
+ if (operator === 'lt')
22
+ return left < right;
23
+ return left <= right;
14
24
  }
15
- function tested(test, field, size, written) {
25
+ function satisfied(test, held) {
16
26
  if (test.op === 'eq')
17
- return test.value === null ? isNull(field) : equal(field, test.value);
18
- if (test.op === 'ne') {
19
- return test.value === null
20
- ? not(isNull(field))
21
- : or(isUndefined(field), isNull(field), not(equal(field, test.value)));
22
- }
23
- if (test.op === 'in' || test.op === 'nin') {
24
- const matches = test.values.length === 0
25
- ? inArray(field, [])
26
- : some(test.values.map((value) => (value === null ? isNull(field) : equal(field, value))));
27
- if (test.op === 'in')
28
- return matches;
29
- return some([
30
- isUndefined(field),
31
- ...(test.values.includes(null) ? [] : [isNull(field)]),
32
- not(matches),
33
- ]);
34
- }
35
- if (test.op === 'range') {
36
- const compare = { gt, gte, lt, lte };
37
- return every(test.bounds.map(([operator, bound]) => compare[operator](field, bound)));
38
- }
39
- if (test.op === 'all') {
40
- return every([not(isUndefined(size)), ...test.values.map((value) => inArray(value, field))]);
41
- }
42
- if (test.op === 'size')
43
- return eq(size, test.size);
44
- return test.exists ? not(isUndefined(written)) : isUndefined(written);
27
+ return same(held, test.value);
28
+ if (test.op === 'ne')
29
+ return !same(held, test.value);
30
+ if (test.op === 'in')
31
+ return test.values.some((value) => same(held, value));
32
+ if (test.op === 'nin')
33
+ return !test.values.some((value) => same(held, value));
34
+ if (test.op === 'range')
35
+ return test.bounds.every((bound) => ordered(held, bound));
36
+ if (test.op === 'all')
37
+ return Array.isArray(held) && test.values.every((value) => same(held, value));
38
+ return Array.isArray(held) && held.length === test.size;
39
+ }
40
+ function tested(test, reached) {
41
+ if (test.op === 'exists')
42
+ return test.exists === (reached !== undefined);
43
+ if (reached === undefined)
44
+ return test.op === 'ne' || test.op === 'nin';
45
+ return reached.some((held) => satisfied(test, held));
45
46
  }
46
47
  function conditioned(condition, row) {
47
48
  if ('every' in condition)
48
- return every(condition.every.map((item) => conditioned(item, row)));
49
+ return condition.every.every((item) => conditioned(item, row));
49
50
  if ('some' in condition)
50
- return some(condition.some.map((item) => conditioned(item, row)));
51
- return tested(condition.test, row.values[condition.field], row.sizes[condition.field], row.fields[condition.field]);
51
+ return condition.some.some((item) => conditioned(item, row));
52
+ return tested(condition.test, row.reached[condition.field]);
53
+ }
54
+ function narrowed(query, where, alias) {
55
+ return where === null ? query : query.fn.where((row) => conditioned(where, row[alias]));
56
+ }
57
+ function reached(reach, room, document) {
58
+ return reach === null
59
+ ? []
60
+ : [or(inArray(room, [...reach.rooms]), inArray(document, [...reach.documents]))];
52
61
  }
53
- function scoped(scope, row, rooms) {
62
+ function scoped(scope, row, rooms, reach) {
54
63
  return every([
55
64
  eq(row.kind, 'document'),
56
65
  ...(rooms === null ? [] : [inArray(row.room, [...rooms])]),
66
+ ...reached(reach, row.room, row.key),
57
67
  ...(scope.types === null ? [] : [inArray(row.type, [...scope.types])]),
58
68
  ...(scope.pathPrefix === null ? [] : [inArray(scope.pathPrefix, row.directories)]),
59
- ...(scope.where === null ? [] : [conditioned(scope.where, row)]),
60
69
  ]);
61
70
  }
62
71
  function keyed(key, row) {
@@ -68,25 +77,26 @@ function live(query) {
68
77
  startSync: true,
69
78
  });
70
79
  }
71
- function related(q, rows, scope, field, kept) {
80
+ function related(q, rows, scope, field, kept, reach) {
72
81
  const matched = kept === 'source' ? 'target' : 'source';
73
82
  const from = q.from({ r: rows });
74
- return from
75
- .where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [eq(r.field, field)])]))
83
+ const joined = from
84
+ .where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [inArray(field, r.forms)])]))
76
85
  .innerJoin({ m: rows }, ({ r, m }) => eq(r[matched], m.key))
77
- .where(({ m }) => scoped(scope, m, null))
86
+ .where(({ m }) => scoped(scope, m, null, reach));
87
+ return narrowed(joined, scope.where, 'm')
78
88
  .groupBy(({ r }) => r[kept])
79
89
  .select(({ r }) => ({ key: r[kept] }));
80
90
  }
81
91
  function filtered(q, rows, plan) {
82
92
  const from = q.from({ d: rows });
83
- let query = from.where(({ d }) => scoped(plan.root, d, plan.rooms));
93
+ let query = narrowed(from.where(({ d }) => scoped(plan.root, d, plan.rooms, plan.reach)), plan.root.where, 'd');
84
94
  if (plan.hop !== null) {
85
- const hop = related(q, rows, plan.hop, plan.hop.field, 'source');
95
+ const hop = related(q, rows, plan.hop, plan.hop.field, 'source', plan.reach);
86
96
  query = query.innerJoin({ h: hop }, ({ d, h }) => eq(d.key, h.key));
87
97
  }
88
98
  if (plan.backlinks !== null) {
89
- const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target');
99
+ const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target', plan.reach);
90
100
  query = query.innerJoin({ k: backlinks }, ({ d, k }) => eq(d.key, k.key));
91
101
  }
92
102
  return query;
@@ -111,20 +121,19 @@ function documents(q, rows, plan, shape) {
111
121
  room: d.room,
112
122
  path: d.path,
113
123
  type: d.type,
114
- ...(shape.fields === 'all' ? { fields: d.fields } : {}),
115
- ...(Array.isArray(shape.fields) ? named('field', shape.fields, d.fields) : {}),
124
+ ...(shape.fields === null ? {} : { fields: d.fields }),
116
125
  ...(shape.sections === 'all' ? { sections: b.sections } : {}),
117
126
  ...(Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {}),
118
127
  ...(shape.preamble ? { preamble: b.preamble } : {}),
119
128
  ...(shape.markdown ? { markdown: b.markdown } : {}),
120
- ...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d)) } : {}),
129
+ ...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d, plan.reach)) } : {}),
121
130
  ...(shape.change ? { change: d.change } : {}),
122
131
  }));
123
132
  }
124
- function backlinked(q, rows, document) {
133
+ function backlinked(q, rows, document, reach) {
125
134
  const from = q.from({ r: rows });
126
135
  return from
127
- .where(({ r }) => eq(r.target, document.key))
136
+ .where(({ r }) => every([eq(r.target, document.key), ...reached(reach, r.room, r.source)]))
128
137
  .orderBy(({ r }) => r.path, { stringSort: 'lexical' })
129
138
  .orderBy(({ r }) => r.field, { stringSort: 'lexical' })
130
139
  .select(({ r }) => ({ path: r.path, type: r.type, field: r.field }));
@@ -170,6 +179,55 @@ function part(row, prefix, names, whole) {
170
179
  return whole;
171
180
  return present(names.map((name, index) => [name, row[`${prefix}${index}`]]));
172
181
  }
182
+ function masked(pointers) {
183
+ const root = { whole: false, members: new Map() };
184
+ for (const pointer of pointers) {
185
+ let mask = root;
186
+ for (const token of pointerSegments(pointer)) {
187
+ const next = mask.members.get(token) ?? { whole: false, members: new Map() };
188
+ mask.members.set(token, next);
189
+ mask = next;
190
+ }
191
+ mask.whole = true;
192
+ }
193
+ return root;
194
+ }
195
+ function merged(left, right) {
196
+ if (left === undefined)
197
+ return right;
198
+ const members = new Map(left.members);
199
+ for (const [token, mask] of right.members)
200
+ members.set(token, merged(members.get(token), mask));
201
+ return { whole: left.whole || right.whole, members };
202
+ }
203
+ function cut(value, mask) {
204
+ if (mask.whole)
205
+ return value;
206
+ if (Array.isArray(value)) {
207
+ const each = {
208
+ whole: false,
209
+ members: new Map([...mask.members].filter(([token]) => !ARRAY_INDEX.test(token))),
210
+ };
211
+ const kept = [];
212
+ value.forEach((item, index) => {
213
+ const part = cut(item, merged(mask.members.get(String(index)), each));
214
+ if (part !== undefined)
215
+ kept[index] = part;
216
+ });
217
+ return kept.length === 0 ? undefined : kept;
218
+ }
219
+ if (typeof value !== 'object' || value === null)
220
+ return undefined;
221
+ const kept = Object.entries(value).flatMap(([key, held]) => {
222
+ const member = mask.members.get(key);
223
+ const part = member === undefined ? undefined : cut(held, member);
224
+ return part === undefined ? [] : [[key, part]];
225
+ });
226
+ return kept.length === 0 ? undefined : Object.fromEntries(kept);
227
+ }
228
+ function selected(fields, pointers) {
229
+ return (cut(fields, masked(pointers)) ?? {});
230
+ }
173
231
  function documentOf(row, shape) {
174
232
  if (row.type === null)
175
233
  return { room: row.room, path: row.path };
@@ -179,7 +237,11 @@ function documentOf(row, shape) {
179
237
  type: row.type,
180
238
  ...(shape.fields === null
181
239
  ? {}
182
- : { fields: part(row, 'field', shape.fields, row.fields) }),
240
+ : {
241
+ fields: shape.fields === 'all'
242
+ ? row.fields
243
+ : selected(row.fields, shape.fields),
244
+ }),
183
245
  ...(shape.sections === null
184
246
  ? {}
185
247
  : {
@@ -214,7 +276,7 @@ function keyedOf(plan, entries) {
214
276
  keys: bounded.map(([key]) => key),
215
277
  };
216
278
  }
217
- function reconciled(previous, next) {
279
+ export function reconciled(previous, next) {
218
280
  const before = rowsOf(previous.result);
219
281
  const held = new Map(previous.keys.map((key, index) => [key, before[index]]));
220
282
  const changed = [];
package/dist/refresh.d.ts CHANGED
@@ -1,6 +1,16 @@
1
1
  import type { Adapter, AdapterFailure, Authorization, RetryableRefusal } from './adapter.js';
2
+ import type { Remodel } from './bootstrap.js';
2
3
  import { type ConfirmedLayer } from './replica.js';
4
+ import type { ReplicaRecord } from './store.js';
3
5
  import { type Refused, type Unconfirmed } from './transfer.js';
6
+ export type Advancement = {
7
+ kind: 'still-current';
8
+ } | {
9
+ kind: 'advanced';
10
+ record: ReplicaRecord;
11
+ } | {
12
+ kind: 'beyond-horizon';
13
+ } | RetryableRefusal | Unconfirmed | AdapterFailure;
4
14
  export type RefreshOutcome = {
5
15
  kind: 'still-current';
6
16
  } | {
@@ -9,5 +19,6 @@ export type RefreshOutcome = {
9
19
  } | {
10
20
  kind: 'beyond-horizon';
11
21
  } | RetryableRefusal | Unconfirmed | Refused | AdapterFailure;
12
- export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer, continuing: () => boolean, minPosition: string | undefined): Promise<RefreshOutcome>;
22
+ export declare function advancement(adapter: Adapter, authorization: Authorization, held: ReplicaRecord, remodel: Remodel, continuing: () => boolean): Promise<Advancement>;
23
+ export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer, remodel: Remodel, continuing: () => boolean): Promise<RefreshOutcome>;
13
24
  //# sourceMappingURL=refresh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EAGb,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AAEtB,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,gBAAgB,GAChB,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,UAAU,EAAE,MAAM,OAAO,EACzB,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,cAAc,CAAC,CA0EzB"}
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EAGb,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/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,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,WAAW,CAAC,CA4EtB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,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,23 +1,26 @@
1
1
  import { declaredAttachments } from './attachment.js';
2
2
  import { readStaged } from './replica.js';
3
3
  import { unconfirmed } from './transfer.js';
4
- export async function refreshRoom(adapter, authorization, confirmed, continuing, minPosition) {
5
- const locator = confirmed.record.locator;
6
- const fromRoomVersion = confirmed.record.roomVersion;
4
+ export async function advancement(adapter, authorization, held, remodel, continuing) {
5
+ const locator = held.locator;
6
+ const fromRoomVersion = held.roomVersion;
7
7
  const first = await adapter.refresh(authorization, {
8
8
  locator,
9
- selection: confirmed.record.replica.selection,
9
+ selection: held.replica.selection,
10
10
  fromRoomVersion,
11
- ...(minPosition === undefined ? {} : { minPosition }),
12
11
  });
13
12
  if (first.kind !== 'net-advancement')
14
13
  return first;
15
14
  const roomVersion = first.roomVersion;
16
- const documents = { ...confirmed.record.documents };
17
- const revisions = { ...confirmed.record.revisions };
18
- const changes = { ...confirmed.record.changes };
19
- const written = { ...confirmed.record.written };
20
- const binaryTargets = new Set(confirmed.record.binaryTargets);
15
+ const models = remodel(first.models, {
16
+ collection: held.model,
17
+ selection: held.selectionModel,
18
+ });
19
+ const documents = { ...held.documents };
20
+ const revisions = { ...held.revisions };
21
+ const changes = { ...held.changes };
22
+ const written = { ...held.written };
23
+ const binaryTargets = new Set(held.binaryTargets);
21
24
  const attachments = [];
22
25
  const stage = (page) => {
23
26
  if (page.attachments !== undefined)
@@ -52,9 +55,8 @@ export async function refreshRoom(adapter, authorization, confirmed, continuing,
52
55
  return unconfirmed;
53
56
  const page = await adapter.refresh(authorization, {
54
57
  locator,
55
- selection: confirmed.record.replica.selection,
58
+ selection: held.replica.selection,
56
59
  fromRoomVersion,
57
- ...(minPosition === undefined ? {} : { minPosition }),
58
60
  pageToken,
59
61
  });
60
62
  if (page.kind === 'still-current' || page.kind === 'beyond-horizon')
@@ -66,15 +68,26 @@ export async function refreshRoom(adapter, authorization, confirmed, continuing,
66
68
  stage(page);
67
69
  pageToken = page.pageToken;
68
70
  }
69
- const staged = readStaged({
70
- ...confirmed.record,
71
- roomVersion,
72
- documents,
73
- binaryTargets: [...binaryTargets].sort(),
74
- revisions,
75
- changes,
76
- written,
77
- attachments: attachments.length === 0 ? confirmed.record.attachments : declaredAttachments(attachments),
78
- }, confirmed);
71
+ return {
72
+ kind: 'advanced',
73
+ record: {
74
+ ...held,
75
+ model: models.collection,
76
+ selectionModel: models.selection,
77
+ roomVersion,
78
+ documents,
79
+ binaryTargets: [...binaryTargets].sort(),
80
+ revisions,
81
+ changes,
82
+ written,
83
+ attachments: attachments.length === 0 ? held.attachments : declaredAttachments(attachments),
84
+ },
85
+ };
86
+ }
87
+ export async function refreshRoom(adapter, authorization, confirmed, remodel, continuing) {
88
+ const advanced = await advancement(adapter, authorization, confirmed.record, remodel, continuing);
89
+ if (advanced.kind !== 'advanced')
90
+ return advanced;
91
+ const staged = readStaged(advanced.record, confirmed);
79
92
  return staged.kind === 'staged' ? { kind: 'advanced', confirmed: staged.confirmed } : staged;
80
93
  }
package/dist/replica.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type ChangeBatch } from './change.js';
2
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
+ import type { HeadChange, RoomAttachment } from './adapter.js';
5
5
  import type { ReplicaRecord } from './store.js';
6
6
  import type { Refused } from './transfer.js';
7
7
  export type ConfirmedLayer = {
@@ -29,15 +29,15 @@ type ReplayStep = {
29
29
  collection?: Collection;
30
30
  };
31
31
  export declare function compositionOf(record: ReplicaRecord): Composition;
32
- export declare function readConfirmed(record: ReplicaRecord, previous?: ConfirmedLayer): Staged;
32
+ export declare function confirmedOf(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer;
33
33
  export declare function sameMembership(record: ReplicaRecord, other: ReplicaRecord): boolean;
34
34
  export declare function readStaged(record: ReplicaRecord, previous?: ConfirmedLayer): Staged;
35
35
  export declare function readReclassified(record: ReplicaRecord, previous: ConfirmedLayer): Staged | {
36
36
  kind: 'deferred';
37
37
  };
38
- export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], roomVersion: string): Staged;
39
- export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting, previous?: Replica): Replica;
40
- export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer): boolean;
41
- export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, rewriting: Rewriting): readonly ChangeBatch[];
38
+ export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, changes: Readonly<Record<string, HeadChange>>, removals: readonly string[], attachments: readonly RoomAttachment[] | undefined, roomVersion: string, writtenAt: string): Staged;
39
+ export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Replica;
40
+ export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer, current?: Readonly<Record<string, string>>): boolean;
41
+ export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean): readonly ChangeBatch[];
42
42
  export {};
43
43
  //# sourceMappingURL=replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC1F,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;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,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,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAAG,OAAO,CAAC;AAE7E,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,CAQhE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAWtF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAKnF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAkBnF;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,cAAc,GACvB,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAM/B;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,MAAM,CA+BR;AAsDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA4CT;AAkFD,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAa7E;AAED,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"}
1
+ {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"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"}
package/dist/replica.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { parse } from '@agentshouse/mdmodel';
2
2
  import { immutable } from './change.js';
3
- import { parseCollection, readCollection, validateCollection, } from './collection.js';
3
+ import { collectionOf, unreadable, validateCollection, } from './collection.js';
4
4
  import { overlay, overlayChanged, sameLayerText } from './overlay.js';
5
5
  import { providerRewritten } from './save.js';
6
6
  import { equalValue } from './room-draft.js';
7
+ import { declaredAttachments } from './attachment.js';
7
8
  export function compositionOf(record) {
8
9
  return {
9
10
  model: record.model,
@@ -12,52 +13,62 @@ export function compositionOf(record) {
12
13
  : { roots: record.typedSelection.roots, model: record.selectionModel },
13
14
  };
14
15
  }
15
- export function readConfirmed(record, previous) {
16
- const read = readCollection(record.documents, compositionOf(record), previous === undefined
17
- ? undefined
18
- : { text: previous.record.documents, collection: previous.collection });
19
- return read.kind === 'read'
20
- ? { kind: 'staged', confirmed: { record, collection: read.collection } }
21
- : read;
16
+ export function confirmedOf(record, previous) {
17
+ return {
18
+ record,
19
+ collection: collectionOf(record.documents, compositionOf(record), previous?.collection),
20
+ };
22
21
  }
23
22
  export function sameMembership(record, other) {
24
23
  return (JSON.stringify(record.typedSelection?.roots ?? null) ===
25
24
  JSON.stringify(other.typedSelection?.roots ?? null));
26
25
  }
27
26
  export function readStaged(record, previous) {
28
- if ((record.model.status === 'current' || record.selectionModel.status === 'current') &&
29
- (previous === undefined ||
30
- !sameLayerText(record, previous.record) ||
31
- record.model !== previous.record.model ||
32
- record.selectionModel !== previous.record.selectionModel)) {
27
+ const textChanged = previous === undefined || !sameLayerText(record, previous.record);
28
+ const modeled = record.model.status !== 'unavailable' || record.selectionModel.status !== 'unavailable';
29
+ if (modeled &&
30
+ (textChanged ||
31
+ record.model !== previous?.record.model ||
32
+ record.selectionModel !== previous?.record.selectionModel)) {
33
33
  const verdict = validateCollection(record.documents, record.binaryTargets, compositionOf(record));
34
34
  if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') {
35
35
  return { kind: 'refused', refusal: verdict };
36
36
  }
37
+ if (verdict.verdict === 'refuse') {
38
+ const refused = unreadable(record.documents, previous?.record.documents);
39
+ if (refused !== null)
40
+ return refused;
41
+ }
42
+ }
43
+ else if (textChanged) {
44
+ const refused = unreadable(record.documents, previous?.record.documents);
45
+ if (refused !== null)
46
+ return refused;
37
47
  }
38
- return readConfirmed(record, previous);
48
+ return { kind: 'staged', confirmed: confirmedOf(record, previous) };
39
49
  }
40
50
  export function readReclassified(record, previous) {
41
51
  const verdict = validateCollection(record.documents, record.binaryTargets, compositionOf(record));
42
52
  if (verdict.verdict !== 'refuse')
43
- return readConfirmed(record, previous);
53
+ return { kind: 'staged', confirmed: confirmedOf(record, previous) };
44
54
  return verdict.rule === 'model-unavailable'
45
55
  ? { kind: 'deferred' }
46
56
  : { kind: 'refused', refusal: verdict };
47
57
  }
48
- export function applyReturned(confirmed, documents, revisions, removals, roomVersion) {
58
+ export function applyReturned(confirmed, documents, revisions, changes, removals, attachments, roomVersion, writtenAt) {
49
59
  const nextDocuments = { ...confirmed.record.documents, ...documents };
50
60
  const nextRevisions = { ...confirmed.record.revisions, ...revisions };
51
61
  const nextChanges = { ...confirmed.record.changes };
52
62
  const nextWritten = {
53
63
  ...confirmed.record.written,
54
- ...Object.fromEntries(Object.keys(documents).map((path) => [path, roomVersion])),
64
+ ...Object.fromEntries(Object.keys(documents).map((path) => [path, writtenAt])),
55
65
  };
56
66
  const binaryTargets = new Set(confirmed.record.binaryTargets);
57
67
  for (const [path, revision] of Object.entries(revisions)) {
58
68
  if (confirmed.record.revisions[path] !== revision)
59
69
  delete nextChanges[path];
60
70
  }
71
+ Object.assign(nextChanges, changes);
61
72
  for (const path of removals) {
62
73
  delete nextDocuments[path];
63
74
  delete nextRevisions[path];
@@ -73,6 +84,9 @@ export function applyReturned(confirmed, documents, revisions, removals, roomVer
73
84
  changes: nextChanges,
74
85
  written: nextWritten,
75
86
  binaryTargets: [...binaryTargets].sort(),
87
+ attachments: attachments === undefined
88
+ ? confirmed.record.attachments
89
+ : declaredAttachments([attachments]),
76
90
  }, confirmed);
77
91
  }
78
92
  function predicted(confirmed, batches, previous) {
@@ -93,9 +107,7 @@ function predicted(confirmed, batches, previous) {
93
107
  const collection = hasMove
94
108
  ? reuseRewrite
95
109
  ? old.collection
96
- : parseCollection(before.documents, composition, old?.collection === undefined
97
- ? { text: confirmed.record.documents, collection: confirmed.collection }
98
- : { text: old.before.documents, collection: old.collection })
110
+ : collectionOf(before.documents, composition, old?.collection ?? confirmed.collection)
99
111
  : undefined;
100
112
  const effective = collection === undefined
101
113
  ? batch
@@ -116,7 +128,7 @@ function predicted(confirmed, batches, previous) {
116
128
  }
117
129
  return { layer, replay };
118
130
  }
119
- export function replicaOf(confirmed, queue, rewriting, previous) {
131
+ export function replicaOf(confirmed, queue, previous) {
120
132
  const batches = Object.freeze(queue.map(immutable));
121
133
  if (batches.length === 0) {
122
134
  return {
@@ -132,21 +144,14 @@ export function replicaOf(confirmed, queue, rewriting, previous) {
132
144
  replay: [],
133
145
  };
134
146
  }
135
- const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;
136
- const layer = rewriting === 'provider'
137
- ? predictedState.layer
138
- : previous === undefined
139
- ? overlay(confirmed.record, batches)
140
- : overlayChanged(confirmed.record, batches, previous.confirmed.record, previous.queue, previous.visible);
147
+ const { layer, replay } = predicted(confirmed, batches, previous);
141
148
  return {
142
149
  confirmed,
143
150
  queue: batches,
144
- replay: predictedState?.replay ?? [],
151
+ replay,
145
152
  visible: {
146
153
  ...layer,
147
- collection: parseCollection(layer.documents, compositionOf(confirmed.record), previous === undefined
148
- ? undefined
149
- : { text: previous.visible.documents, collection: previous.visible.collection }),
154
+ collection: collectionOf(layer.documents, compositionOf(confirmed.record), previous?.visible.collection ?? confirmed.collection),
150
155
  },
151
156
  };
152
157
  }
@@ -230,8 +235,8 @@ function after(changes, index, path) {
230
235
  }
231
236
  return at;
232
237
  }
233
- export function landed(batch, confirmed) {
234
- const layer = confirmed.record;
238
+ export function landed(batch, confirmed, current = {}) {
239
+ const layer = { ...confirmed.record, documents: { ...confirmed.record.documents, ...current } };
235
240
  return batch.changes.every((change, index) => {
236
241
  if (change.kind === 'replace' || (change.kind === 'create' && 'content' in change)) {
237
242
  const at = after(batch.changes, index, change.path);
@@ -245,7 +250,7 @@ export function landed(batch, confirmed) {
245
250
  });
246
251
  });
247
252
  }
248
- export function withdrawals(confirmed, queue, withdrawable, rewriting) {
253
+ export function withdrawals(confirmed, queue, withdrawable) {
249
254
  if (!queue.some(withdrawable))
250
255
  return [];
251
256
  const composition = compositionOf(confirmed.record);
@@ -256,10 +261,10 @@ export function withdrawals(confirmed, queue, withdrawable, rewriting) {
256
261
  withdrawn.push(batch);
257
262
  continue;
258
263
  }
259
- const effective = rewriting === 'provider' && batch.changes.some((change) => change.kind === 'move')
264
+ const effective = batch.changes.some((change) => change.kind === 'move')
260
265
  ? providerRewritten(batch, {
261
266
  ...layer,
262
- collection: parseCollection(layer.documents, composition),
267
+ collection: collectionOf(layer.documents, composition),
263
268
  })
264
269
  : batch;
265
270
  layer = overlay(layer, [effective]);
@@ -116,6 +116,9 @@ export declare function equalValue(left: unknown, right: unknown): boolean;
116
116
  export declare function underneath(parts: HeldParts, path: string, visible: VisibleLayer | undefined): ChangedUnderneath;
117
117
  export declare function changedParts(path: string, report: ChangedUnderneath): readonly ChangedPart[];
118
118
  export declare function returnedInto(existing: HeldParts | undefined, returned: HeldParts): HeldParts;
119
+ export declare function moveTarget(move: {
120
+ readonly to: string;
121
+ }): string;
119
122
  export declare function changesOf(path: string, parts: HeldParts): {
120
123
  changes: readonly Change[];
121
124
  bases: readonly Precondition[];
@@ -1 +1 @@
1
- {"version":3,"file":"room-draft.d.ts","sourceRoot":"","sources":["../src/room-draft.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room-draft.d.ts","sourceRoot":"","sources":["../src/room-draft.ts"],"names":[],"mappings":"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"}