@agentshouse/mdruntime 0.1.0-cde2b99d2fcbc → 0.1.0-ce131cb435f8b

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 (146) hide show
  1. package/AGENTS.md +271 -290
  2. package/README.md +8 -8
  3. package/dist/adapter.d.ts +52 -10
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/attempt.d.ts.map +1 -1
  6. package/dist/attempt.js +14 -1
  7. package/dist/bootstrap.d.ts +3 -2
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +33 -7
  10. package/dist/change-set.d.ts +2 -0
  11. package/dist/change-set.d.ts.map +1 -1
  12. package/dist/change-set.js +36 -10
  13. package/dist/chat/acts.d.ts +3 -4
  14. package/dist/chat/acts.d.ts.map +1 -1
  15. package/dist/chat/acts.js +10 -10
  16. package/dist/chat/earlier.d.ts +10 -0
  17. package/dist/chat/earlier.d.ts.map +1 -0
  18. package/dist/chat/earlier.js +54 -0
  19. package/dist/chat/kit.d.ts +2 -1
  20. package/dist/chat/kit.d.ts.map +1 -1
  21. package/dist/chat/kit.js +3 -3
  22. package/dist/chat/list.d.ts +8 -1
  23. package/dist/chat/list.d.ts.map +1 -1
  24. package/dist/chat/list.js +48 -8
  25. package/dist/chat/markdown.d.ts +2 -1
  26. package/dist/chat/markdown.d.ts.map +1 -1
  27. package/dist/chat/markdown.js +7 -6
  28. package/dist/chat/message.d.ts.map +1 -1
  29. package/dist/chat/message.js +2 -2
  30. package/dist/chat/messages.d.ts +1 -0
  31. package/dist/chat/messages.d.ts.map +1 -1
  32. package/dist/chat/messages.js +4 -0
  33. package/dist/chat/provider.d.ts +1 -1
  34. package/dist/chat/provider.d.ts.map +1 -1
  35. package/dist/chat/provider.js +62 -79
  36. package/dist/chat/question.d.ts +1 -1
  37. package/dist/chat/question.d.ts.map +1 -1
  38. package/dist/chat/question.js +7 -18
  39. package/dist/chat/ready.d.ts +1 -0
  40. package/dist/chat/ready.d.ts.map +1 -1
  41. package/dist/chat/ready.js +4 -4
  42. package/dist/chat/style.js +5 -5
  43. package/dist/client.d.ts +17 -9
  44. package/dist/client.d.ts.map +1 -1
  45. package/dist/client.js +19 -6
  46. package/dist/collection.d.ts +20 -5
  47. package/dist/collection.d.ts.map +1 -1
  48. package/dist/collection.js +309 -33
  49. package/dist/connection.d.ts +31 -9
  50. package/dist/connection.d.ts.map +1 -1
  51. package/dist/connection.js +1620 -397
  52. package/dist/conversation.d.ts +20 -7
  53. package/dist/conversation.d.ts.map +1 -1
  54. package/dist/conversation.js +474 -163
  55. package/dist/durability.d.ts +7 -1
  56. package/dist/durability.d.ts.map +1 -1
  57. package/dist/entry.d.ts +17 -0
  58. package/dist/entry.d.ts.map +1 -0
  59. package/dist/entry.js +157 -0
  60. package/dist/fence.d.ts +6 -0
  61. package/dist/fence.d.ts.map +1 -0
  62. package/dist/fence.js +10 -0
  63. package/dist/host.d.ts +15 -3
  64. package/dist/host.d.ts.map +1 -1
  65. package/dist/host.js +94 -12
  66. package/dist/identity.d.ts +2 -0
  67. package/dist/identity.d.ts.map +1 -1
  68. package/dist/identity.js +6 -0
  69. package/dist/index.d.ts +10 -7
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -0
  72. package/dist/memory.d.ts +8 -2
  73. package/dist/memory.d.ts.map +1 -1
  74. package/dist/memory.js +33 -6
  75. package/dist/model.d.ts +4 -2
  76. package/dist/model.d.ts.map +1 -1
  77. package/dist/model.js +10 -1
  78. package/dist/observation.d.ts +7 -2
  79. package/dist/observation.d.ts.map +1 -1
  80. package/dist/observation.js +29 -12
  81. package/dist/outcome.d.ts +12 -2
  82. package/dist/outcome.d.ts.map +1 -1
  83. package/dist/outcome.js +4 -0
  84. package/dist/overlay.d.ts +3 -0
  85. package/dist/overlay.d.ts.map +1 -1
  86. package/dist/overlay.js +62 -55
  87. package/dist/query.d.ts +56 -4
  88. package/dist/query.d.ts.map +1 -1
  89. package/dist/query.js +36 -7
  90. package/dist/reach.d.ts +6 -3
  91. package/dist/reach.d.ts.map +1 -1
  92. package/dist/reach.js +30 -5
  93. package/dist/react.d.ts +8 -6
  94. package/dist/react.d.ts.map +1 -1
  95. package/dist/react.js +7 -17
  96. package/dist/read-side.d.ts +16 -7
  97. package/dist/read-side.d.ts.map +1 -1
  98. package/dist/read-side.js +484 -100
  99. package/dist/readiness.d.ts +53 -0
  100. package/dist/readiness.d.ts.map +1 -0
  101. package/dist/readiness.js +33 -0
  102. package/dist/reads.d.ts +11 -0
  103. package/dist/reads.d.ts.map +1 -0
  104. package/dist/reads.js +98 -0
  105. package/dist/recovery.d.ts +25 -0
  106. package/dist/recovery.d.ts.map +1 -0
  107. package/dist/recovery.js +197 -0
  108. package/dist/refresh.d.ts +4 -4
  109. package/dist/refresh.d.ts.map +1 -1
  110. package/dist/refresh.js +18 -11
  111. package/dist/replica.d.ts +10 -5
  112. package/dist/replica.d.ts.map +1 -1
  113. package/dist/replica.js +96 -44
  114. package/dist/room-draft.d.ts +13 -1
  115. package/dist/room-draft.d.ts.map +1 -1
  116. package/dist/room-draft.js +2 -2
  117. package/dist/rows.d.ts +6 -13
  118. package/dist/rows.d.ts.map +1 -1
  119. package/dist/rows.js +10 -13
  120. package/dist/save.d.ts +9 -3
  121. package/dist/save.d.ts.map +1 -1
  122. package/dist/save.js +68 -22
  123. package/dist/search.d.ts +49 -6
  124. package/dist/search.d.ts.map +1 -1
  125. package/dist/search.js +192 -47
  126. package/dist/seed.d.ts +16 -0
  127. package/dist/seed.d.ts.map +1 -0
  128. package/dist/seed.js +75 -0
  129. package/dist/shared.d.ts +14 -0
  130. package/dist/shared.d.ts.map +1 -0
  131. package/dist/shared.js +394 -0
  132. package/dist/status.d.ts +4 -0
  133. package/dist/status.d.ts.map +1 -1
  134. package/dist/store.d.ts +64 -16
  135. package/dist/store.d.ts.map +1 -1
  136. package/dist/store.js +447 -178
  137. package/dist/turn.d.ts +9 -0
  138. package/dist/turn.d.ts.map +1 -0
  139. package/dist/turn.js +64 -0
  140. package/dist/windows.d.ts +26 -0
  141. package/dist/windows.d.ts.map +1 -0
  142. package/dist/windows.js +93 -0
  143. package/dist/wire.d.ts +152 -32
  144. package/dist/wire.d.ts.map +1 -1
  145. package/dist/wire.js +52 -31
  146. package/package.json +12 -8
package/dist/seed.js ADDED
@@ -0,0 +1,75 @@
1
+ import { documentKey } from './rows.js';
2
+ function plain(value) {
3
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
4
+ }
5
+ function windowOf(value) {
6
+ const { next, total } = value;
7
+ if (next !== undefined && typeof next !== 'string')
8
+ return null;
9
+ if (total !== undefined && !Number.isSafeInteger(total))
10
+ return null;
11
+ return {
12
+ ...(next === undefined ? {} : { next }),
13
+ ...(total === undefined ? {} : { total: total }),
14
+ };
15
+ }
16
+ function rowsOf(value) {
17
+ if (!plain(value))
18
+ return null;
19
+ const window = windowOf(value);
20
+ if (window === null)
21
+ return null;
22
+ if (Array.isArray(value.groups)) {
23
+ const groups = value.groups;
24
+ return groups.every((group) => plain(group) && Array.isArray(group.key) && typeof group.count === 'number')
25
+ ? { groups: groups, ...window }
26
+ : null;
27
+ }
28
+ if (!Array.isArray(value.documents))
29
+ return null;
30
+ const documents = value.documents;
31
+ return documents.every((document) => plain(document) && typeof document.room === 'string' && typeof document.path === 'string')
32
+ ? { documents: documents, ...window }
33
+ : null;
34
+ }
35
+ export function entrySeedOf(value) {
36
+ if (!plain(value) || !plain(value.at) || !Array.isArray(value.queries))
37
+ return null;
38
+ const at = {};
39
+ for (const [room, version] of Object.entries(value.at)) {
40
+ if (typeof version !== 'string')
41
+ return null;
42
+ at[room] = version;
43
+ }
44
+ const queries = [];
45
+ for (const entry of value.queries) {
46
+ if (!plain(entry) || !plain(entry.query))
47
+ return null;
48
+ const rows = rowsOf(entry.rows);
49
+ if (rows === null)
50
+ return null;
51
+ queries.push({ query: entry.query, rows });
52
+ }
53
+ return { at, queries };
54
+ }
55
+ export function seededResult(seed) {
56
+ const coverage = {
57
+ rooms: Object.entries(seed.at).map(([room, generation]) => ({
58
+ room,
59
+ generation,
60
+ current: false,
61
+ })),
62
+ indexes: [],
63
+ overlay: [],
64
+ };
65
+ if ('groups' in seed.rows) {
66
+ return {
67
+ result: { ...seed.rows, coverage },
68
+ keys: seed.rows.groups.map((_group, index) => index),
69
+ };
70
+ }
71
+ return {
72
+ result: { ...seed.rows, coverage },
73
+ keys: seed.rows.documents.map((document) => documentKey(document.room, document.path)),
74
+ };
75
+ }
@@ -0,0 +1,14 @@
1
+ export type Paths<V> = Readonly<Record<string, V>>;
2
+ type Weigh<V> = (key: string, value: V) => number;
3
+ export declare function sharing<V>(map: Paths<V>): Generator<number, Paths<V>, void>;
4
+ export declare function shared<V>(map: Paths<V>): Paths<V>;
5
+ export declare function patched<V>(base: Paths<V>, set: Iterable<readonly [string, V]>, removed?: Iterable<string>): Paths<V>;
6
+ export declare function patching<V>(base: Paths<V>, set: Iterable<readonly [string, V]>, removed?: Iterable<string>): Generator<number, Paths<V>, void>;
7
+ export declare function tally<V>(map: Paths<V>, weigh: Weigh<V>): number;
8
+ export declare function sizeOf<V>(map: Paths<V>): number;
9
+ export declare function differences<V>(left: Paths<V>, right: Paths<V>, same?: (left: V, right: V) => boolean): Generator<number, ReadonlySet<string>, void>;
10
+ export declare function differing<V>(left: Paths<V>, right: Paths<V>, same?: (left: V, right: V) => boolean): ReadonlySet<string>;
11
+ export declare function drafted<V>(base: Paths<V>): Record<string, V>;
12
+ export declare function settled<V>(draft: Record<string, V>): Paths<V>;
13
+ export {};
14
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAkBnD,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC;AA8LlD,wBAAiB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAE5E;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAEjD;AAED,wBAAgB,OAAO,CAAC,CAAC,EACvB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAM,GAC7B,KAAK,CAAC,CAAC,CAAC,CAEV;AAED,wBAAiB,QAAQ,CAAC,CAAC,EACzB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAM,GAC7B,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAgCnC;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAY/D;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAE/C;AA8CD,wBAAiB,WAAW,CAAC,CAAC,EAC5B,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,IAAI,GAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAmB,GAC/C,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAkB9C;AAED,wBAAgB,SAAS,CAAC,CAAC,EACzB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,IAAI,GAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAmB,GAC/C,WAAW,CAAC,MAAM,CAAC,CAErB;AAMD,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAiD5D;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAS7D"}
package/dist/shared.js ADDED
@@ -0,0 +1,394 @@
1
+ import { finished, ROW_WEIGHT } from './turn.js';
2
+ const BITS = 5;
3
+ const MASK = (1 << BITS) - 1;
4
+ const roots = new WeakMap();
5
+ const tallies = new WeakMap();
6
+ function hashOf(key) {
7
+ let hash = 0x811c9dc5;
8
+ for (let index = 0; index < key.length; index += 1) {
9
+ hash ^= key.charCodeAt(index);
10
+ hash = Math.imul(hash, 0x01000193);
11
+ }
12
+ return hash >>> 0;
13
+ }
14
+ function isLeaf(node) {
15
+ return 'key' in node;
16
+ }
17
+ function isCollision(node) {
18
+ return 'leaves' in node;
19
+ }
20
+ function fragment(hash, shift) {
21
+ return (hash >>> shift) & MASK;
22
+ }
23
+ function count(bits) {
24
+ let left = bits - ((bits >>> 1) & 0x55555555);
25
+ left = (left & 0x33333333) + ((left >>> 2) & 0x33333333);
26
+ return (((left + (left >>> 4)) & 0x0f0f0f0f) * 0x01010101) >>> 24;
27
+ }
28
+ function slot(bitmap, bit) {
29
+ return count(bitmap & (bit - 1));
30
+ }
31
+ function lookup(root, key) {
32
+ const hash = hashOf(key);
33
+ let node = root.node;
34
+ let shift = 0;
35
+ while (node !== undefined) {
36
+ if (isLeaf(node))
37
+ return node.key === key ? node : undefined;
38
+ if (isCollision(node))
39
+ return node.leaves.find((leaf) => leaf.key === key);
40
+ const bit = 1 << fragment(hash, shift);
41
+ if ((node.bitmap & bit) === 0)
42
+ return undefined;
43
+ node = node.children[slot(node.bitmap, bit)];
44
+ shift += BITS;
45
+ }
46
+ return undefined;
47
+ }
48
+ function branchOf(node, shift) {
49
+ return { bitmap: 1 << fragment(node.hash, shift), children: [node] };
50
+ }
51
+ function joined(left, right, shift) {
52
+ if (left.hash === right.hash) {
53
+ const leaves = isCollision(left) ? left.leaves : [left];
54
+ return { hash: right.hash, leaves: [...leaves, right] };
55
+ }
56
+ return put(branchOf(left, shift), right, shift);
57
+ }
58
+ function put(node, leaf, shift) {
59
+ if (node === undefined)
60
+ return leaf;
61
+ if (isLeaf(node)) {
62
+ if (node.key !== leaf.key)
63
+ return joined(node, leaf, shift);
64
+ return node.value === leaf.value ? node : leaf;
65
+ }
66
+ if (isCollision(node)) {
67
+ if (node.hash !== leaf.hash)
68
+ return joined(node, leaf, shift);
69
+ const at = node.leaves.findIndex((held) => held.key === leaf.key);
70
+ if (at === -1)
71
+ return { hash: node.hash, leaves: [...node.leaves, leaf] };
72
+ if (node.leaves[at].value === leaf.value)
73
+ return node;
74
+ return {
75
+ hash: node.hash,
76
+ leaves: node.leaves.map((held, index) => (index === at ? leaf : held)),
77
+ };
78
+ }
79
+ const bit = 1 << fragment(leaf.hash, shift);
80
+ const at = slot(node.bitmap, bit);
81
+ if ((node.bitmap & bit) === 0) {
82
+ return {
83
+ bitmap: node.bitmap | bit,
84
+ children: [...node.children.slice(0, at), leaf, ...node.children.slice(at)],
85
+ };
86
+ }
87
+ const child = node.children[at];
88
+ const next = put(child, leaf, shift + BITS);
89
+ if (next === child)
90
+ return node;
91
+ return {
92
+ bitmap: node.bitmap,
93
+ children: node.children.map((held, index) => (index === at ? next : held)),
94
+ };
95
+ }
96
+ function lone(node) {
97
+ if (node.children.length !== 1)
98
+ return null;
99
+ const [only] = node.children;
100
+ return isLeaf(only) || isCollision(only) ? only : null;
101
+ }
102
+ function taken(node, hash, key, shift) {
103
+ if (isLeaf(node))
104
+ return node.key === key ? undefined : node;
105
+ if (isCollision(node)) {
106
+ const leaves = node.leaves.filter((leaf) => leaf.key !== key);
107
+ if (leaves.length === node.leaves.length)
108
+ return node;
109
+ return leaves.length === 1 ? leaves[0] : { hash: node.hash, leaves };
110
+ }
111
+ const bit = 1 << fragment(hash, shift);
112
+ if ((node.bitmap & bit) === 0)
113
+ return node;
114
+ const at = slot(node.bitmap, bit);
115
+ const child = node.children[at];
116
+ const next = taken(child, hash, key, shift + BITS);
117
+ if (next === child)
118
+ return node;
119
+ if (next === undefined) {
120
+ if (node.children.length === 1)
121
+ return undefined;
122
+ const rest = {
123
+ bitmap: node.bitmap & ~bit,
124
+ children: node.children.filter((_, index) => index !== at),
125
+ };
126
+ return lone(rest) ?? rest;
127
+ }
128
+ const replaced = {
129
+ bitmap: node.bitmap,
130
+ children: node.children.map((held, index) => (index === at ? next : held)),
131
+ };
132
+ return lone(replaced) ?? replaced;
133
+ }
134
+ function* leavesOf(node) {
135
+ if (node === undefined)
136
+ return;
137
+ if (isLeaf(node)) {
138
+ yield node;
139
+ return;
140
+ }
141
+ if (isCollision(node)) {
142
+ yield* node.leaves;
143
+ return;
144
+ }
145
+ for (const child of node.children)
146
+ yield* leavesOf(child);
147
+ }
148
+ function facade(root) {
149
+ let keys;
150
+ const target = {};
151
+ const map = new Proxy(target, {
152
+ get(held, property, receiver) {
153
+ if (typeof property === 'string') {
154
+ const leaf = lookup(root, property);
155
+ if (leaf !== undefined)
156
+ return leaf.value;
157
+ }
158
+ return Reflect.get(held, property, receiver);
159
+ },
160
+ has(held, property) {
161
+ return ((typeof property === 'string' && lookup(root, property) !== undefined) ||
162
+ Reflect.has(held, property));
163
+ },
164
+ ownKeys() {
165
+ keys ??= [...leavesOf(root.node)].map((leaf) => leaf.key);
166
+ return keys;
167
+ },
168
+ getOwnPropertyDescriptor(_held, property) {
169
+ if (typeof property !== 'string')
170
+ return undefined;
171
+ const leaf = lookup(root, property);
172
+ if (leaf === undefined)
173
+ return undefined;
174
+ return { value: leaf.value, writable: false, enumerable: true, configurable: true };
175
+ },
176
+ set: () => false,
177
+ defineProperty: () => false,
178
+ deleteProperty: () => false,
179
+ });
180
+ roots.set(map, root);
181
+ return map;
182
+ }
183
+ function* rooted(map) {
184
+ const held = roots.get(map);
185
+ if (held !== undefined)
186
+ return held;
187
+ let node;
188
+ let size = 0;
189
+ for (const [key, value] of Object.entries(map)) {
190
+ node = put(node, { key, hash: hashOf(key), value }, 0);
191
+ size += 1;
192
+ yield ROW_WEIGHT;
193
+ }
194
+ return { node, size };
195
+ }
196
+ export function* sharing(map) {
197
+ return roots.has(map) ? map : facade(yield* rooted(map));
198
+ }
199
+ export function shared(map) {
200
+ return finished(sharing(map));
201
+ }
202
+ export function patched(base, set, removed = []) {
203
+ return finished(patching(base, set, removed));
204
+ }
205
+ export function* patching(base, set, removed = []) {
206
+ const root = yield* rooted(base);
207
+ const weighed = [...(tallies.get(base) ?? [])];
208
+ let node = root.node;
209
+ let size = root.size;
210
+ const shift = (key, before, after) => {
211
+ for (const entry of weighed) {
212
+ entry[1] +=
213
+ (after === undefined ? 0 : entry[0](key, after)) -
214
+ (before === undefined ? 0 : entry[0](key, before.value));
215
+ }
216
+ };
217
+ for (const key of removed) {
218
+ if (node === undefined)
219
+ break;
220
+ const before = lookup({ node, size }, key);
221
+ if (before === undefined)
222
+ continue;
223
+ node = taken(node, before.hash, key, 0);
224
+ size -= 1;
225
+ shift(key, before, undefined);
226
+ yield ROW_WEIGHT;
227
+ }
228
+ for (const [key, value] of set) {
229
+ const before = lookup({ node, size }, key);
230
+ node = put(node, { key, hash: hashOf(key), value }, 0);
231
+ if (before === undefined)
232
+ size += 1;
233
+ shift(key, before, value);
234
+ yield ROW_WEIGHT;
235
+ }
236
+ if (node === root.node && roots.has(base))
237
+ return base;
238
+ const map = facade({ node, size });
239
+ if (weighed.length > 0)
240
+ tallies.set(map, new Map(weighed));
241
+ return map;
242
+ }
243
+ export function tally(map, weigh) {
244
+ const held = tallies.get(map);
245
+ const known = held?.get(weigh);
246
+ if (known !== undefined)
247
+ return known;
248
+ let total = 0;
249
+ for (const [key, value] of Object.entries(map))
250
+ total += weigh(key, value);
251
+ if (roots.has(map)) {
252
+ const kept = held ?? new Map();
253
+ kept.set(weigh, total);
254
+ tallies.set(map, kept);
255
+ }
256
+ return total;
257
+ }
258
+ export function sizeOf(map) {
259
+ return roots.get(map)?.size ?? Object.keys(map).length;
260
+ }
261
+ function* compared(left, right, same, into) {
262
+ const pending = [[left, right]];
263
+ for (let pair = pending.pop(); pair !== undefined; pair = pending.pop()) {
264
+ const [one, other] = pair;
265
+ if (one === other)
266
+ continue;
267
+ if (one !== undefined &&
268
+ other !== undefined &&
269
+ !isLeaf(one) &&
270
+ !isCollision(one) &&
271
+ !isLeaf(other) &&
272
+ !isCollision(other)) {
273
+ const children = [];
274
+ for (let remaining = one.bitmap | other.bitmap; remaining !== 0; remaining &= remaining - 1) {
275
+ const bit = remaining & -remaining;
276
+ children.push([
277
+ (one.bitmap & bit) === 0 ? undefined : one.children[slot(one.bitmap, bit)],
278
+ (other.bitmap & bit) === 0 ? undefined : other.children[slot(other.bitmap, bit)],
279
+ ]);
280
+ }
281
+ pending.push(...children.reverse());
282
+ continue;
283
+ }
284
+ const before = new Map();
285
+ for (const leaf of leavesOf(one)) {
286
+ before.set(leaf.key, leaf.value);
287
+ yield ROW_WEIGHT;
288
+ }
289
+ for (const leaf of leavesOf(other)) {
290
+ const held = before.get(leaf.key);
291
+ before.delete(leaf.key);
292
+ if (held === undefined || !same(held, leaf.value))
293
+ into.add(leaf.key);
294
+ yield ROW_WEIGHT;
295
+ }
296
+ for (const key of before.keys())
297
+ into.add(key);
298
+ }
299
+ }
300
+ export function* differences(left, right, same = Object.is) {
301
+ const into = new Set();
302
+ if (left === right)
303
+ return into;
304
+ const leftRoot = roots.get(left);
305
+ const rightRoot = roots.get(right);
306
+ if (leftRoot !== undefined && rightRoot !== undefined) {
307
+ yield* compared(leftRoot.node, rightRoot.node, same, into);
308
+ return into;
309
+ }
310
+ for (const key of Object.keys(left)) {
311
+ if (!Object.hasOwn(right, key) || !same(left[key], right[key]))
312
+ into.add(key);
313
+ yield ROW_WEIGHT;
314
+ }
315
+ for (const key of Object.keys(right)) {
316
+ if (!Object.hasOwn(left, key))
317
+ into.add(key);
318
+ yield ROW_WEIGHT;
319
+ }
320
+ return into;
321
+ }
322
+ export function differing(left, right, same = Object.is) {
323
+ return finished(differences(left, right, same));
324
+ }
325
+ const drafts = new WeakMap();
326
+ const GONE = Symbol('gone');
327
+ export function drafted(base) {
328
+ const written = new Map();
329
+ const read = (key) => {
330
+ const held = written.get(key);
331
+ if (held === GONE)
332
+ return undefined;
333
+ return held ?? (Object.hasOwn(base, key) ? base[key] : undefined);
334
+ };
335
+ const draft = new Proxy({}, {
336
+ get(held, property, receiver) {
337
+ if (typeof property === 'string') {
338
+ const value = read(property);
339
+ if (value !== undefined)
340
+ return value;
341
+ }
342
+ return Reflect.get(held, property, receiver);
343
+ },
344
+ has(held, property) {
345
+ return ((typeof property === 'string' && read(property) !== undefined) ||
346
+ Reflect.has(held, property));
347
+ },
348
+ ownKeys() {
349
+ const keys = new Set(Object.keys(base));
350
+ for (const [key, value] of written) {
351
+ if (value === GONE)
352
+ keys.delete(key);
353
+ else
354
+ keys.add(key);
355
+ }
356
+ return [...keys];
357
+ },
358
+ getOwnPropertyDescriptor(_held, property) {
359
+ if (typeof property !== 'string')
360
+ return undefined;
361
+ const value = read(property);
362
+ if (value === undefined)
363
+ return undefined;
364
+ return { value, writable: true, enumerable: true, configurable: true };
365
+ },
366
+ set(_held, property, value) {
367
+ if (typeof property !== 'string')
368
+ return false;
369
+ written.set(property, value);
370
+ return true;
371
+ },
372
+ deleteProperty(_held, property) {
373
+ if (typeof property !== 'string')
374
+ return false;
375
+ written.set(property, GONE);
376
+ return true;
377
+ },
378
+ defineProperty: () => false,
379
+ });
380
+ drafts.set(draft, { base, written });
381
+ return draft;
382
+ }
383
+ export function settled(draft) {
384
+ const held = drafts.get(draft);
385
+ const set = [];
386
+ const removed = [];
387
+ for (const [key, value] of held.written) {
388
+ if (value === GONE)
389
+ removed.push(key);
390
+ else
391
+ set.push([key, value]);
392
+ }
393
+ return patched(held.base, set, removed);
394
+ }
package/dist/status.d.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import type { Open } from './open.js';
2
+ import type { ProviderRefusal } from './adapter.js';
2
3
  import type { ReturnReason } from './room-draft.js';
3
4
  export type AttentionEntry = {
4
5
  room: string;
5
6
  path: string;
6
7
  returned: ReturnReason;
8
+ } | {
9
+ room: string;
10
+ refusal: ProviderRefusal;
7
11
  };
8
12
  export type SyncStatus = {
9
13
  state: Open<'pending' | 'syncing' | 'synced'>;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC;IAC9C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,UAMtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE3D;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAErD;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAQhE"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC;IAC9C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,UAMtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE3D;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAErD;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAQhE"}
package/dist/store.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import type { ModelState } from './model.js';
2
2
  import type { Capability, HeadChange, Member, OperationScopes, ProviderLimit, ReplicaAdmission, TypedSelection } from './adapter.js';
3
- import type { AcceptedMessage } from './adapter.js';
3
+ import type { AcceptedMessage, KeptReceipt } from './adapter.js';
4
4
  import type { ChangeBatch } from './change.js';
5
5
  import { type HeldBinary } from './overlay.js';
6
6
  import type { ChatDraftFile } from './file.js';
7
7
  import type { Submission } from './outcome.js';
8
8
  import type { RoomDraftRecord, SavedDraft } from './room-draft.js';
9
- export declare const STORE_SCHEMA = 22;
9
+ export declare const STORE_SCHEMA = 25;
10
+ export declare const AUTHORED_SCHEMA = 3;
10
11
  export type ReplicaRecord = {
11
12
  locator: string;
12
13
  name: string;
@@ -22,10 +23,11 @@ export type ReplicaRecord = {
22
23
  documents: Readonly<Record<string, string>>;
23
24
  binaries: Readonly<Record<string, HeldBinary>>;
24
25
  revisions: Readonly<Record<string, string>>;
26
+ fileIds: Readonly<Record<string, string>>;
25
27
  changes: Readonly<Record<string, HeadChange>>;
26
28
  written: Readonly<Record<string, string>>;
27
29
  };
28
- export type StagedLayer = Pick<ReplicaRecord, 'documents' | 'binaries' | 'revisions' | 'changes' | 'written'>;
30
+ export type StagedLayer = Pick<ReplicaRecord, 'documents' | 'binaries' | 'revisions' | 'fileIds' | 'changes' | 'written'>;
29
31
  export type TransferRecord = {
30
32
  locator: string;
31
33
  transfer: string;
@@ -45,6 +47,9 @@ export type PendingState = {
45
47
  readonly upload?: unknown;
46
48
  readonly accepted?: string;
47
49
  };
50
+ export type TargetRecord = {
51
+ established: boolean;
52
+ };
48
53
  export type QueueRecord = {
49
54
  locator: string;
50
55
  pending: readonly {
@@ -59,38 +64,57 @@ export type PresentationRecord = {
59
64
  export type HeldConversation = {
60
65
  conversation: string;
61
66
  read: string | null | undefined;
62
- messages: readonly AcceptedMessage[];
67
+ partial: boolean;
68
+ };
69
+ export type MessageWindow = {
70
+ messages: AcceptedMessage[];
71
+ more: boolean;
63
72
  };
64
73
  export type ConversationWrite = {
65
74
  conversation: string;
66
75
  messages: readonly AcceptedMessage[];
67
- read?: string | null;
68
- sealed?: boolean;
76
+ read?: {
77
+ at: string | null;
78
+ partial: boolean;
79
+ };
80
+ };
81
+ export type ChatSubmission = {
82
+ readonly operation: string;
83
+ readonly text: string;
84
+ readonly files: readonly ChatDraftFile[];
85
+ readonly turn: string | null;
69
86
  };
70
87
  export type ChatDraftRecord = {
71
88
  conversation: string;
72
89
  text: string;
73
90
  files: readonly ChatDraftFile[];
74
- turn: string | null;
75
91
  revision: string;
92
+ submitted?: readonly ChatSubmission[];
93
+ moves?: readonly string[];
94
+ };
95
+ export type CallRecord = {
96
+ readonly operation: string;
97
+ readonly name: string;
98
+ readonly input: unknown;
76
99
  };
77
100
  export type RecordWrite = {
78
101
  next: ReplicaRecord;
79
102
  previous: ReplicaRecord | null;
80
103
  stored?: StagedLayer;
104
+ };
105
+ export type AuthoredWrite = {
106
+ locator: string;
81
107
  queue: readonly ChangeBatch[];
82
- previousQueue?: readonly ChangeBatch[];
108
+ founded?: readonly ChangeBatch[];
83
109
  saved?: ReadonlyMap<string, readonly SavedDraft[]>;
84
110
  roomDrafts?: readonly RoomDraftRecord[];
85
111
  consumedRoomDrafts?: readonly string[];
86
112
  };
87
113
  export type RuntimeStore = {
88
114
  all(): Promise<readonly ReplicaRecord[]>;
115
+ keepAuthored(input: AuthoredWrite): Promise<void>;
89
116
  write(input: RecordWrite): Promise<void>;
90
- revokeModels(records: readonly {
91
- record: ReplicaRecord;
92
- queue: readonly ChangeBatch[];
93
- }[]): Promise<void>;
117
+ revokeModels(records: readonly ReplicaRecord[]): Promise<void>;
94
118
  lastCompleted(): Promise<string | null>;
95
119
  complete(at: string): Promise<void>;
96
120
  providerLimits(): Promise<readonly ProviderLimit[]>;
@@ -98,6 +122,8 @@ export type RuntimeStore = {
98
122
  declare(limits: readonly ProviderLimit[], capabilities: readonly Capability[]): Promise<void>;
99
123
  member(): Promise<Member | null>;
100
124
  keepMember(member: Member | null): Promise<void>;
125
+ targets(): Promise<Readonly<Record<string, TargetRecord>>>;
126
+ keepTargets(targets: Readonly<Record<string, TargetRecord>>): Promise<void>;
101
127
  queues(): Promise<readonly QueueRecord[]>;
102
128
  submit(locator: string, id: string, submission: Submission, lost: boolean): Promise<void>;
103
129
  accept(locator: string, id: string, roomVersion: string): Promise<void>;
@@ -107,21 +133,43 @@ export type RuntimeStore = {
107
133
  present(record: PresentationRecord): Promise<void>;
108
134
  conversations(): Promise<readonly HeldConversation[]>;
109
135
  keepMessages(write: ConversationWrite): Promise<void>;
136
+ messageWindow(conversation: string, limit: number, before: readonly [string, string] | null): Promise<MessageWindow>;
137
+ messageCount(conversation: string): Promise<number>;
138
+ messagesAfter(conversation: string, identity: string | null): Promise<AcceptedMessage[]>;
139
+ messageIdentities(conversation: string): Promise<readonly string[]>;
140
+ turnArrived(conversation: string, turn: string): Promise<boolean>;
110
141
  dropConversations(conversations: readonly string[]): Promise<void>;
111
142
  chatDrafts(): Promise<readonly ChatDraftRecord[]>;
112
- keepChatDraft(record: ChatDraftRecord): Promise<void>;
143
+ keepChatDrafts(records: readonly ChatDraftRecord[]): Promise<void>;
113
144
  dropChatDraft(conversation: string): Promise<void>;
145
+ calls(): Promise<readonly CallRecord[]>;
146
+ keepCall(record: CallRecord): Promise<void>;
147
+ dropCall(operation: string): Promise<void>;
114
148
  keepRoomDraft(record: RoomDraftRecord): Promise<void>;
115
149
  discardRoomDraft(locator: string, path: string): Promise<void>;
116
- dropRooms(locators: readonly string[]): Promise<void>;
150
+ fences(): Promise<readonly string[]>;
151
+ erase(locators: readonly string[]): Promise<void>;
152
+ discard(locator: string): Promise<void>;
117
153
  transfers(): Promise<readonly TransferRecord[]>;
118
154
  staged(record: TransferRecord): Promise<StagedLayer>;
119
155
  stage(record: TransferRecord, page: StagedLayer): Promise<void>;
120
156
  abandon(locator: string): Promise<void>;
157
+ receivedHeads(): Promise<readonly KeptReceipt[]>;
158
+ receivedParts(key: string, count: number): Promise<readonly unknown[]>;
159
+ keepReceived(key: string, head: unknown, part?: {
160
+ index: number;
161
+ value: unknown;
162
+ }): Promise<void>;
163
+ dropReceived(keys: readonly string[]): Promise<void>;
121
164
  generation(): Promise<string | null>;
122
165
  rememberGeneration(value: string): Promise<void>;
123
166
  close(): void;
124
167
  };
125
- export declare function removeRuntimeStore(): Promise<void>;
126
- export declare function openRuntimeStore(): Promise<RuntimeStore>;
168
+ export declare function authoredHolder(): Promise<string | null>;
169
+ export declare function authoredBy(holder: string): Promise<boolean>;
170
+ export declare function authoredBinding(): Promise<string | null>;
171
+ export declare function bindAuthored(binding: string): Promise<void>;
172
+ export declare function removeRuntimeStore(holder?: string): Promise<boolean>;
173
+ export declare function openDatabase(name: string, version: number, upgrade: (opening: IDBOpenDBRequest, oldVersion: number) => void): Promise<IDBDatabase>;
174
+ export declare function openRuntimeStore(fenced: (locator: string) => boolean): Promise<RuntimeStore>;
127
175
  //# sourceMappingURL=store.d.ts.map