@agentshouse/mdruntime 0.1.0-alpha.9 → 0.1.0-c0105dbd22806

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 (214) hide show
  1. package/AGENTS.md +299 -0
  2. package/README.md +54 -0
  3. package/dist/adapter.d.ts +246 -40
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -10
  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/attempt.d.ts +16 -0
  10. package/dist/attempt.d.ts.map +1 -0
  11. package/dist/attempt.js +70 -0
  12. package/dist/binary.d.ts +23 -0
  13. package/dist/binary.d.ts.map +1 -0
  14. package/dist/binary.js +8 -0
  15. package/dist/bootstrap.d.ts +17 -7
  16. package/dist/bootstrap.d.ts.map +1 -1
  17. package/dist/bootstrap.js +97 -41
  18. package/dist/change-set.d.ts +33 -0
  19. package/dist/change-set.d.ts.map +1 -0
  20. package/dist/change-set.js +90 -0
  21. package/dist/change.d.ts +24 -0
  22. package/dist/change.d.ts.map +1 -1
  23. package/dist/change.js +31 -5
  24. package/dist/chat/acts.d.ts +34 -0
  25. package/dist/chat/acts.d.ts.map +1 -0
  26. package/dist/chat/acts.js +36 -0
  27. package/dist/chat/context.d.ts +3 -0
  28. package/dist/chat/context.d.ts.map +1 -0
  29. package/dist/chat/context.js +10 -0
  30. package/dist/chat/input.d.ts +9 -0
  31. package/dist/chat/input.d.ts.map +1 -0
  32. package/dist/chat/input.js +99 -0
  33. package/dist/chat/kit.d.ts +60 -0
  34. package/dist/chat/kit.d.ts.map +1 -0
  35. package/dist/chat/kit.js +123 -0
  36. package/dist/chat/lasting.d.ts +6 -0
  37. package/dist/chat/lasting.d.ts.map +1 -0
  38. package/dist/chat/lasting.js +19 -0
  39. package/dist/chat/list.d.ts +26 -0
  40. package/dist/chat/list.d.ts.map +1 -0
  41. package/dist/chat/list.js +62 -0
  42. package/dist/chat/markdown.d.ts +20 -0
  43. package/dist/chat/markdown.d.ts.map +1 -0
  44. package/dist/chat/markdown.js +188 -0
  45. package/dist/chat/message.d.ts +6 -0
  46. package/dist/chat/message.d.ts.map +1 -0
  47. package/dist/chat/message.js +192 -0
  48. package/dist/chat/messages.d.ts +21 -0
  49. package/dist/chat/messages.d.ts.map +1 -0
  50. package/dist/chat/messages.js +151 -0
  51. package/dist/chat/name.d.ts +6 -0
  52. package/dist/chat/name.d.ts.map +1 -0
  53. package/dist/chat/name.js +37 -0
  54. package/dist/chat/opened.d.ts +11 -0
  55. package/dist/chat/opened.d.ts.map +1 -0
  56. package/dist/chat/opened.js +17 -0
  57. package/dist/chat/overlay.d.ts +31 -0
  58. package/dist/chat/overlay.d.ts.map +1 -0
  59. package/dist/chat/overlay.js +97 -0
  60. package/dist/chat/parts.d.ts +57 -0
  61. package/dist/chat/parts.d.ts.map +1 -0
  62. package/dist/chat/parts.js +119 -0
  63. package/dist/chat/process.d.ts +20 -0
  64. package/dist/chat/process.d.ts.map +1 -0
  65. package/dist/chat/process.js +32 -0
  66. package/dist/chat/provider.d.ts +63 -0
  67. package/dist/chat/provider.d.ts.map +1 -0
  68. package/dist/chat/provider.js +645 -0
  69. package/dist/chat/question.d.ts +9 -0
  70. package/dist/chat/question.d.ts.map +1 -0
  71. package/dist/chat/question.js +80 -0
  72. package/dist/chat/questions.d.ts +31 -0
  73. package/dist/chat/questions.d.ts.map +1 -0
  74. package/dist/chat/questions.js +111 -0
  75. package/dist/chat/read.d.ts +5 -0
  76. package/dist/chat/read.d.ts.map +1 -0
  77. package/dist/chat/read.js +13 -0
  78. package/dist/chat/ready.d.ts +33 -0
  79. package/dist/chat/ready.d.ts.map +1 -0
  80. package/dist/chat/ready.js +91 -0
  81. package/dist/chat/style.d.ts +4 -0
  82. package/dist/chat/style.d.ts.map +1 -0
  83. package/dist/chat/style.js +302 -0
  84. package/dist/chat.d.ts +14 -0
  85. package/dist/chat.d.ts.map +1 -0
  86. package/dist/chat.js +8 -0
  87. package/dist/client.d.ts +49 -33
  88. package/dist/client.d.ts.map +1 -1
  89. package/dist/client.js +164 -183
  90. package/dist/collection.d.ts +9 -17
  91. package/dist/collection.d.ts.map +1 -1
  92. package/dist/collection.js +83 -89
  93. package/dist/connection.d.ts +66 -48
  94. package/dist/connection.d.ts.map +1 -1
  95. package/dist/connection.js +1964 -1173
  96. package/dist/conversation.d.ts +65 -24
  97. package/dist/conversation.d.ts.map +1 -1
  98. package/dist/conversation.js +675 -334
  99. package/dist/durability.js +6 -6
  100. package/dist/entry.d.ts +17 -0
  101. package/dist/entry.d.ts.map +1 -0
  102. package/dist/entry.js +156 -0
  103. package/dist/expectation.d.ts +21 -0
  104. package/dist/expectation.d.ts.map +1 -0
  105. package/dist/expectation.js +70 -0
  106. package/dist/failure.d.ts +13 -0
  107. package/dist/failure.d.ts.map +1 -0
  108. package/dist/failure.js +19 -0
  109. package/dist/fence.d.ts +6 -0
  110. package/dist/fence.d.ts.map +1 -0
  111. package/dist/fence.js +10 -0
  112. package/dist/file.d.ts +2 -2
  113. package/dist/file.d.ts.map +1 -1
  114. package/dist/file.js +48 -71
  115. package/dist/host.d.ts +15 -3
  116. package/dist/host.d.ts.map +1 -1
  117. package/dist/host.js +109 -127
  118. package/dist/identity.d.ts +4 -0
  119. package/dist/identity.d.ts.map +1 -1
  120. package/dist/identity.js +22 -9
  121. package/dist/index.d.ts +17 -11
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +4 -3
  124. package/dist/log.js +5 -6
  125. package/dist/memory.d.ts +19 -8
  126. package/dist/memory.d.ts.map +1 -1
  127. package/dist/memory.js +304 -216
  128. package/dist/model.d.ts +16 -30
  129. package/dist/model.d.ts.map +1 -1
  130. package/dist/model.js +21 -21
  131. package/dist/observation.d.ts +27 -0
  132. package/dist/observation.d.ts.map +1 -0
  133. package/dist/observation.js +95 -0
  134. package/dist/open.d.ts +2 -0
  135. package/dist/open.d.ts.map +1 -0
  136. package/dist/open.js +1 -0
  137. package/dist/outcome.d.ts +37 -31
  138. package/dist/outcome.d.ts.map +1 -1
  139. package/dist/outcome.js +36 -18
  140. package/dist/overlay.d.ts +22 -4
  141. package/dist/overlay.d.ts.map +1 -1
  142. package/dist/overlay.js +236 -54
  143. package/dist/paths.d.ts +0 -2
  144. package/dist/paths.d.ts.map +1 -1
  145. package/dist/paths.js +6 -29
  146. package/dist/query.d.ts +219 -10
  147. package/dist/query.d.ts.map +1 -1
  148. package/dist/query.js +462 -15
  149. package/dist/reach.d.ts +42 -0
  150. package/dist/reach.d.ts.map +1 -0
  151. package/dist/reach.js +294 -0
  152. package/dist/react.d.ts +41 -0
  153. package/dist/react.d.ts.map +1 -0
  154. package/dist/react.js +64 -0
  155. package/dist/read-side.d.ts +18 -0
  156. package/dist/read-side.d.ts.map +1 -0
  157. package/dist/read-side.js +440 -0
  158. package/dist/refresh.d.ts +15 -5
  159. package/dist/refresh.d.ts.map +1 -1
  160. package/dist/refresh.js +64 -41
  161. package/dist/replica.d.ts +28 -5
  162. package/dist/replica.d.ts.map +1 -1
  163. package/dist/replica.js +249 -40
  164. package/dist/room-draft.d.ts +144 -0
  165. package/dist/room-draft.d.ts.map +1 -0
  166. package/dist/room-draft.js +438 -0
  167. package/dist/rows.d.ts +46 -0
  168. package/dist/rows.d.ts.map +1 -0
  169. package/dist/rows.js +145 -0
  170. package/dist/save.d.ts +33 -5
  171. package/dist/save.d.ts.map +1 -1
  172. package/dist/save.js +630 -366
  173. package/dist/search.d.ts +62 -0
  174. package/dist/search.d.ts.map +1 -0
  175. package/dist/search.js +125 -0
  176. package/dist/status.d.ts +6 -8
  177. package/dist/status.d.ts.map +1 -1
  178. package/dist/status.js +8 -20
  179. package/dist/store.d.ts +89 -34
  180. package/dist/store.d.ts.map +1 -1
  181. package/dist/store.js +513 -132
  182. package/dist/transfer.d.ts +5 -0
  183. package/dist/transfer.d.ts.map +1 -1
  184. package/dist/transfer.js +1 -5
  185. package/dist/wire.d.ts +59 -19
  186. package/dist/wire.d.ts.map +1 -1
  187. package/dist/wire.js +88 -105
  188. package/package.json +34 -16
  189. package/dist/adapter.js.map +0 -1
  190. package/dist/bootstrap.js.map +0 -1
  191. package/dist/change.js.map +0 -1
  192. package/dist/client.js.map +0 -1
  193. package/dist/collection.js.map +0 -1
  194. package/dist/connection.js.map +0 -1
  195. package/dist/conversation.js.map +0 -1
  196. package/dist/durability.js.map +0 -1
  197. package/dist/file.js.map +0 -1
  198. package/dist/host.js.map +0 -1
  199. package/dist/identity.js.map +0 -1
  200. package/dist/index.js.map +0 -1
  201. package/dist/log.js.map +0 -1
  202. package/dist/memory.js.map +0 -1
  203. package/dist/model.js.map +0 -1
  204. package/dist/outcome.js.map +0 -1
  205. package/dist/overlay.js.map +0 -1
  206. package/dist/paths.js.map +0 -1
  207. package/dist/query.js.map +0 -1
  208. package/dist/refresh.js.map +0 -1
  209. package/dist/replica.js.map +0 -1
  210. package/dist/save.js.map +0 -1
  211. package/dist/status.js.map +0 -1
  212. package/dist/store.js.map +0 -1
  213. package/dist/transfer.js.map +0 -1
  214. package/dist/wire.js.map +0 -1
@@ -0,0 +1,440 @@
1
+ import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, inArray, or, toArray, } from '@tanstack/db';
2
+ import { ARRAY_INDEX, pointerSegments } from '@agentshouse/mdmodel';
3
+ import { rowsOf } from './observation.js';
4
+ import { documentKey } from './rows.js';
5
+ function every(expressions) {
6
+ const [first, second, ...rest] = expressions;
7
+ return second === undefined ? first : and(first, second, ...rest);
8
+ }
9
+ function same(held, value) {
10
+ return Array.isArray(held) ? held.includes(value) : held === value;
11
+ }
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;
24
+ }
25
+ function satisfied(test, held) {
26
+ if (test.op === 'eq')
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));
46
+ }
47
+ function conditioned(condition, row) {
48
+ if ('every' in condition)
49
+ return condition.every.every((item) => conditioned(item, row));
50
+ if ('some' in condition)
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]))];
61
+ }
62
+ function scoped(scope, row, rooms, reach) {
63
+ return every([
64
+ eq(row.kind, 'document'),
65
+ ...(rooms === null ? [] : [inArray(row.room, [...rooms])]),
66
+ ...reached(reach, row.room, row.key),
67
+ ...(scope.types === null ? [] : [inArray(row.type, [...scope.types])]),
68
+ ...(scope.pathPrefix === null ? [] : [inArray(scope.pathPrefix, row.directories)]),
69
+ ]);
70
+ }
71
+ function keyed(key, row) {
72
+ return key.of === 'field' ? row.values[key.field] : row[key.of];
73
+ }
74
+ function live(query) {
75
+ return createLiveQueryCollection({
76
+ query: query,
77
+ startSync: true,
78
+ });
79
+ }
80
+ function related(q, rows, scope, field, kept, reach) {
81
+ const matched = kept === 'source' ? 'target' : 'source';
82
+ const from = q.from({ r: rows });
83
+ const joined = from
84
+ .where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [inArray(field, r.forms)])]))
85
+ .innerJoin({ m: rows }, ({ r, m }) => eq(r[matched], m.key))
86
+ .where(({ m }) => scoped(scope, m, null, reach));
87
+ return narrowed(joined, scope.where, 'm')
88
+ .groupBy(({ r }) => r[kept])
89
+ .select(({ r }) => ({ key: r[kept] }));
90
+ }
91
+ function filtered(q, rows, plan) {
92
+ const from = q.from({ d: rows });
93
+ let query = narrowed(from.where(({ d }) => scoped(plan.root, d, plan.rooms, plan.reach)), plan.root.where, 'd');
94
+ if (plan.hop !== null) {
95
+ const hop = related(q, rows, plan.hop, plan.hop.field, 'source', plan.reach);
96
+ query = query.innerJoin({ h: hop }, ({ d, h }) => eq(d.key, h.key));
97
+ }
98
+ if (plan.backlinks !== null) {
99
+ const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target', plan.reach);
100
+ query = query.innerJoin({ k: backlinks }, ({ d, k }) => eq(d.key, k.key));
101
+ }
102
+ return query;
103
+ }
104
+ function named(prefix, names, source) {
105
+ return Object.fromEntries(names.map((name, index) => [`${prefix}${index}`, source[name]]));
106
+ }
107
+ function documents(q, rows, plan, shape) {
108
+ let query = filtered(q, rows, plan);
109
+ if (shape.sections !== null || shape.preamble || shape.markdown) {
110
+ query = query.leftJoin({ b: rows }, ({ d, b }) => eq(d.body, b.key));
111
+ }
112
+ for (const { key, options } of shape.orderBy) {
113
+ query = query.orderBy(({ d }) => keyed(key, d), options);
114
+ }
115
+ if (shape.orderBy.length === 0 && plan.limit !== null) {
116
+ query = query.orderBy(({ d }) => d.key, { stringSort: 'lexical' });
117
+ }
118
+ if (plan.limit !== null)
119
+ query = query.limit(plan.limit);
120
+ return query.select(({ d, b }) => ({
121
+ room: d.room,
122
+ path: d.path,
123
+ type: d.type,
124
+ binary: d.binary,
125
+ ...(shape.fields === null ? {} : { fields: d.fields }),
126
+ ...(shape.sections === 'all' ? { sections: b.sections } : {}),
127
+ ...(Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {}),
128
+ ...(shape.preamble ? { preamble: b.preamble } : {}),
129
+ ...(shape.markdown ? { markdown: b.markdown } : {}),
130
+ ...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d, plan.reach)) } : {}),
131
+ ...(shape.change ? { change: d.change } : {}),
132
+ }));
133
+ }
134
+ function backlinked(q, rows, document, reach) {
135
+ const from = q.from({ r: rows });
136
+ return from
137
+ .where(({ r }) => every([eq(r.target, document.key), ...reached(reach, r.room, r.source)]))
138
+ .orderBy(({ r }) => r.path, { stringSort: 'lexical' })
139
+ .orderBy(({ r }) => r.field, { stringSort: 'lexical' })
140
+ .select(({ r }) => ({ path: r.path, type: r.type, field: r.field }));
141
+ }
142
+ function groups(q, stage, shape, limit) {
143
+ const keys = shape.groupBy.map((_, index) => `key${index}`);
144
+ const from = q.from({ m: stage });
145
+ let query = from.groupBy(({ m }) => keys.map((key) => m[key]));
146
+ for (const { by, direction } of shape.orderBy) {
147
+ query = query.orderBy(({ m }) => (by === 'count' ? count(m.key) : m[keys[by]]), direction);
148
+ }
149
+ if (limit !== null && shape.orderBy.length > 0)
150
+ query = query.limit(limit);
151
+ return query.select(({ m }) => ({
152
+ ...Object.fromEntries(keys.map((key) => [key, m[key]])),
153
+ count: count(m.key),
154
+ }));
155
+ }
156
+ function built(rows, plan) {
157
+ const shape = plan.shape;
158
+ if (shape.kind === 'documents') {
159
+ const collection = live((q) => documents(q, rows, plan, shape));
160
+ return { live: collection, dispose: () => void collection.cleanup() };
161
+ }
162
+ const stage = live((q) => filtered(q, rows, plan).select(({ d }) => ({
163
+ key: d.key,
164
+ ...Object.fromEntries(shape.groupBy.map((key, index) => [`key${index}`, keyed(key, d)])),
165
+ })));
166
+ const collection = live((q) => groups(q, stage, shape, plan.limit));
167
+ return {
168
+ live: collection,
169
+ dispose: () => {
170
+ void collection.cleanup();
171
+ void stage.cleanup();
172
+ },
173
+ };
174
+ }
175
+ function present(entries) {
176
+ return Object.fromEntries(entries.filter(([, value]) => value !== undefined));
177
+ }
178
+ function part(row, prefix, names, whole) {
179
+ if (names === 'all')
180
+ return whole;
181
+ return present(names.map((name, index) => [name, row[`${prefix}${index}`]]));
182
+ }
183
+ function masked(pointers) {
184
+ const root = { whole: false, members: new Map() };
185
+ for (const pointer of pointers) {
186
+ let mask = root;
187
+ for (const token of pointerSegments(pointer)) {
188
+ const next = mask.members.get(token) ?? { whole: false, members: new Map() };
189
+ mask.members.set(token, next);
190
+ mask = next;
191
+ }
192
+ mask.whole = true;
193
+ }
194
+ return root;
195
+ }
196
+ function merged(left, right) {
197
+ if (left === undefined)
198
+ return right;
199
+ const members = new Map(left.members);
200
+ for (const [token, mask] of right.members)
201
+ members.set(token, merged(members.get(token), mask));
202
+ return { whole: left.whole || right.whole, members };
203
+ }
204
+ function cut(value, mask) {
205
+ if (mask.whole)
206
+ return value;
207
+ if (Array.isArray(value)) {
208
+ const each = {
209
+ whole: false,
210
+ members: new Map([...mask.members].filter(([token]) => !ARRAY_INDEX.test(token))),
211
+ };
212
+ const kept = [];
213
+ value.forEach((item, index) => {
214
+ const part = cut(item, merged(mask.members.get(String(index)), each));
215
+ if (part !== undefined)
216
+ kept[index] = part;
217
+ });
218
+ return kept.length === 0 ? undefined : kept;
219
+ }
220
+ if (typeof value !== 'object' || value === null)
221
+ return undefined;
222
+ const kept = Object.entries(value).flatMap(([key, held]) => {
223
+ const member = mask.members.get(key);
224
+ const part = member === undefined ? undefined : cut(held, member);
225
+ return part === undefined ? [] : [[key, part]];
226
+ });
227
+ return kept.length === 0 ? undefined : Object.fromEntries(kept);
228
+ }
229
+ function selected(fields, pointers) {
230
+ return (cut(fields, masked(pointers)) ?? {});
231
+ }
232
+ function documentOf(row, shape) {
233
+ if (row.type === null) {
234
+ const binary = row.binary;
235
+ return {
236
+ room: row.room,
237
+ path: row.path,
238
+ ...(binary === null ? {} : { binaryFile: binary }),
239
+ };
240
+ }
241
+ return {
242
+ room: row.room,
243
+ path: row.path,
244
+ type: row.type,
245
+ ...(shape.fields === null
246
+ ? {}
247
+ : {
248
+ fields: shape.fields === 'all'
249
+ ? row.fields
250
+ : selected(row.fields, shape.fields),
251
+ }),
252
+ ...(shape.sections === null
253
+ ? {}
254
+ : {
255
+ sections: part(row, 'section', shape.sections, row.sections),
256
+ }),
257
+ ...(shape.preamble ? { preamble: row.preamble } : {}),
258
+ ...(shape.markdown ? { markdown: row.markdown } : {}),
259
+ ...(shape.backlinks
260
+ ? {
261
+ backlinks: row.backlinks.map(({ path, type, field }) => ({ path, type, field })),
262
+ }
263
+ : {}),
264
+ ...(shape.change ? { change: row.change } : {}),
265
+ };
266
+ }
267
+ function keyedOf(plan, entries) {
268
+ const shape = plan.shape;
269
+ if (shape.kind === 'documents') {
270
+ return {
271
+ result: structuredClone({ documents: entries.map(([, row]) => documentOf(row, shape)) }),
272
+ keys: entries.map(([key]) => key),
273
+ };
274
+ }
275
+ const bounded = shape.orderBy.length === 0 && plan.limit !== null ? entries.slice(0, plan.limit) : entries;
276
+ return {
277
+ result: structuredClone({
278
+ groups: bounded.map(([, row]) => ({
279
+ key: shape.groupBy.map((_, index) => row[`key${index}`]),
280
+ count: row.count,
281
+ })),
282
+ }),
283
+ keys: bounded.map(([key]) => key),
284
+ };
285
+ }
286
+ export function reconciled(previous, next) {
287
+ const before = rowsOf(previous.result);
288
+ const held = new Map(previous.keys.map((key, index) => [key, before[index]]));
289
+ const changed = [];
290
+ const rows = rowsOf(next.result).map((row, index) => {
291
+ const key = next.keys[index];
292
+ const kept = held.get(key);
293
+ if (kept !== undefined && deepEquals(kept, row))
294
+ return kept;
295
+ changed.push([key, row]);
296
+ return row;
297
+ });
298
+ const present = new Set(next.keys);
299
+ const survivors = previous.keys.filter((key) => present.has(key));
300
+ const removed = previous.keys.filter((key) => !present.has(key));
301
+ const moved = survivors.length !== next.keys.length ||
302
+ survivors.some((key, index) => key !== next.keys[index]);
303
+ if (changed.length === 0 && removed.length === 0 && !moved)
304
+ return null;
305
+ return {
306
+ keyed: {
307
+ result: 'groups' in next.result
308
+ ? { groups: rows }
309
+ : { documents: rows },
310
+ keys: next.keys,
311
+ },
312
+ change: { changed, removed, order: moved ? next.keys : null },
313
+ };
314
+ }
315
+ export function createReadSide() {
316
+ configureIndexDevMode({ enabled: false });
317
+ let sync;
318
+ const rows = createCollection({
319
+ getKey: (row) => row.key,
320
+ gcTime: 0,
321
+ startSync: true,
322
+ autoIndex: 'eager',
323
+ defaultIndexType: BasicIndex,
324
+ sync: {
325
+ rowUpdateMode: 'full',
326
+ sync: (params) => {
327
+ sync = params;
328
+ params.markReady();
329
+ },
330
+ },
331
+ });
332
+ const shared = new Map();
333
+ function searched(row) {
334
+ const body = rows.get(row.body);
335
+ return {
336
+ room: row.room,
337
+ path: row.path,
338
+ type: row.type,
339
+ fields: row.fields,
340
+ preamble: body.preamble,
341
+ sections: body.sections,
342
+ };
343
+ }
344
+ function publish(entry) {
345
+ const next = reconciled(entry.result, keyedOf(entry.plan, [...entry.built.live.entries()]));
346
+ if (next === null)
347
+ return;
348
+ entry.result = next.keyed;
349
+ for (const listener of entry.listeners)
350
+ listener(next.change);
351
+ }
352
+ return {
353
+ apply(set) {
354
+ const next = new Map();
355
+ for (const change of set.documents) {
356
+ for (const row of change.before)
357
+ next.set(row.key, null);
358
+ for (const row of change.after)
359
+ next.set(row.key, row);
360
+ }
361
+ if (next.size === 0)
362
+ return;
363
+ sync.begin();
364
+ for (const [key, row] of next) {
365
+ if (row === null) {
366
+ if (rows.has(key))
367
+ sync.write({ type: 'delete', key });
368
+ continue;
369
+ }
370
+ sync.write({ type: rows.has(key) ? 'update' : 'insert', value: row });
371
+ }
372
+ sync.commit();
373
+ },
374
+ async query(plan) {
375
+ const { live: collection, dispose } = built(rows, plan);
376
+ try {
377
+ await collection.toArrayWhenReady();
378
+ return keyedOf(plan, [...collection.entries()]).result;
379
+ }
380
+ finally {
381
+ dispose();
382
+ }
383
+ },
384
+ watch(plan, identity, deliver) {
385
+ let entry = shared.get(identity);
386
+ if (entry === undefined) {
387
+ const created = {
388
+ plan,
389
+ built: built(rows, plan),
390
+ result: undefined,
391
+ listeners: new Set(),
392
+ subscription: null,
393
+ };
394
+ created.built.live.on('status:change', ({ status }) => {
395
+ if (status === 'cleaned-up' && created.listeners.size === 0)
396
+ shared.delete(identity);
397
+ });
398
+ shared.set(identity, created);
399
+ entry = created;
400
+ }
401
+ const observed = entry;
402
+ observed.listeners.add(deliver);
403
+ observed.built.live.onFirstReady(() => {
404
+ if (!observed.listeners.has(deliver))
405
+ return;
406
+ if (observed.subscription === null) {
407
+ observed.result = keyedOf(observed.plan, [...observed.built.live.entries()]);
408
+ observed.subscription = observed.built.live.subscribeChanges(() => {
409
+ publish(observed);
410
+ }, { includeInitialState: false });
411
+ }
412
+ deliver(observed.result);
413
+ });
414
+ return () => {
415
+ if (!observed.listeners.delete(deliver) || observed.listeners.size > 0)
416
+ return;
417
+ observed.subscription?.unsubscribe();
418
+ observed.subscription = null;
419
+ };
420
+ },
421
+ documents() {
422
+ return rows.toArray
423
+ .filter((row) => row.kind === 'document' && row.type !== null)
424
+ .map(searched);
425
+ },
426
+ document(room, path) {
427
+ const row = rows.get(documentKey(room, path));
428
+ return row === undefined || row.type === null ? null : searched(row);
429
+ },
430
+ close() {
431
+ for (const entry of shared.values()) {
432
+ entry.listeners.clear();
433
+ entry.subscription?.unsubscribe();
434
+ entry.built.dispose();
435
+ }
436
+ shared.clear();
437
+ void rows.cleanup();
438
+ },
439
+ };
440
+ }
package/dist/refresh.d.ts CHANGED
@@ -1,7 +1,16 @@
1
- import type { AttachedModelBinding } from './model.js';
2
- import type { Adapter, AdapterFailure, Authorization } from './adapter.js';
1
+ import type { Adapter, AdapterFailure, Authorization, RetryableRefusal } from './adapter.js';
2
+ import type { Remodel } from './bootstrap.js';
3
3
  import { type ConfirmedLayer } from './replica.js';
4
- import { type Unconfirmed } from './transfer.js';
4
+ import type { ReplicaRecord } from './store.js';
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;
5
14
  export type RefreshOutcome = {
6
15
  kind: 'still-current';
7
16
  } | {
@@ -9,6 +18,7 @@ export type RefreshOutcome = {
9
18
  confirmed: ConfirmedLayer;
10
19
  } | {
11
20
  kind: 'beyond-horizon';
12
- } | Unconfirmed | AdapterFailure;
13
- export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer, binding: AttachedModelBinding | null): Promise<RefreshOutcome>;
21
+ } | RetryableRefusal | Unconfirmed | Refused | AdapterFailure;
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>;
14
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,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,OAAO,CAAC,cAAc,CAAC,CAsDzB"}
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,EACjB,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,CAwEtB;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,65 +1,88 @@
1
+ import { acceptedBinaries } from './overlay.js';
1
2
  import { readStaged } from './replica.js';
2
3
  import { unconfirmed } from './transfer.js';
3
- export async function refreshRoom(adapter, authorization, confirmed, binding) {
4
- const locator = confirmed.record.locator;
5
- 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;
6
7
  const first = await adapter.refresh(authorization, {
7
8
  locator,
8
- selection: confirmed.record.replica.selection,
9
- fromRoomVersion
9
+ selection: held.replica.selection,
10
+ fromRoomVersion,
10
11
  });
11
- if (first.kind !== 'net-advancement') return first;
12
+ if (first.kind !== 'net-advancement')
13
+ return first;
12
14
  const roomVersion = first.roomVersion;
13
- const documents = {
14
- ...confirmed.record.documents
15
- };
16
- const revisions = {
17
- ...confirmed.record.revisions
18
- };
19
- const binaryTargets = new Set(confirmed.record.binaryTargets);
20
- const stage = (page)=>{
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 binaries = { ...held.binaries };
24
+ const stage = (page) => {
25
+ for (const path of Object.keys(page.documents)) {
26
+ delete binaries[path];
27
+ delete changes[path];
28
+ written[path] = roomVersion;
29
+ }
30
+ for (const path of Object.keys(page.binaryFiles)) {
31
+ delete documents[path];
32
+ delete changes[path];
33
+ delete written[path];
34
+ }
21
35
  Object.assign(documents, page.documents);
36
+ Object.assign(binaries, acceptedBinaries(page.binaryFiles));
22
37
  Object.assign(revisions, page.revisions);
23
- for (const path of Object.keys(page.documents))binaryTargets.delete(path);
24
- for (const target of page.binaryTargets){
25
- delete documents[target];
26
- delete revisions[target];
27
- binaryTargets.add(target);
28
- }
29
- for (const path of page.removals){
38
+ Object.assign(changes, page.changes);
39
+ for (const path of page.removals) {
30
40
  delete documents[path];
31
41
  delete revisions[path];
32
- binaryTargets.delete(path);
42
+ delete changes[path];
43
+ delete written[path];
44
+ delete binaries[path];
33
45
  }
34
46
  };
35
47
  stage(first);
36
48
  let pageToken = first.pageToken;
37
- while(pageToken !== undefined){
49
+ while (pageToken !== undefined) {
50
+ if (!continuing())
51
+ return unconfirmed;
38
52
  const page = await adapter.refresh(authorization, {
39
53
  locator,
40
- selection: confirmed.record.replica.selection,
54
+ selection: held.replica.selection,
41
55
  fromRoomVersion,
42
- pageToken
56
+ pageToken,
43
57
  });
44
- if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;
45
- if (page.kind !== 'net-advancement') return page;
46
- if (page.roomVersion !== roomVersion) return unconfirmed;
58
+ if (page.kind === 'still-current' || page.kind === 'beyond-horizon')
59
+ return unconfirmed;
60
+ if (page.kind !== 'net-advancement')
61
+ return page;
62
+ if (page.roomVersion !== roomVersion)
63
+ return unconfirmed;
47
64
  stage(page);
48
65
  pageToken = page.pageToken;
49
66
  }
50
- const advanced = readStaged({
51
- ...confirmed.record,
52
- roomVersion,
53
- documents,
54
- binaryTargets: [
55
- ...binaryTargets
56
- ].sort(),
57
- revisions
58
- }, binding);
59
- return advanced === null ? unconfirmed : {
67
+ return {
60
68
  kind: 'advanced',
61
- confirmed: advanced
69
+ record: {
70
+ ...held,
71
+ model: models.collection,
72
+ selectionModel: models.selection,
73
+ roomVersion,
74
+ documents,
75
+ binaries,
76
+ revisions,
77
+ changes,
78
+ written,
79
+ },
62
80
  };
63
81
  }
64
-
65
- //# sourceMappingURL=refresh.js.map
82
+ export async function refreshRoom(adapter, authorization, confirmed, remodel, continuing) {
83
+ const advanced = await advancement(adapter, authorization, confirmed.record, remodel, continuing);
84
+ if (advanced.kind !== 'advanced')
85
+ return advanced;
86
+ const staged = readStaged(advanced.record, confirmed);
87
+ return staged.kind === 'staged' ? { kind: 'advanced', confirmed: staged.confirmed } : staged;
88
+ }
package/dist/replica.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type { AttachedModelBinding } from './model.js';
2
1
  import { type ChangeBatch } from './change.js';
3
2
  import { type Collection, type Composition } from './collection.js';
4
3
  import { type Layer } from './overlay.js';
4
+ import type { MutationResult } from './adapter.js';
5
5
  import type { ReplicaRecord } from './store.js';
6
+ import type { Refused } from './transfer.js';
6
7
  export type ConfirmedLayer = {
7
8
  record: ReplicaRecord;
8
9
  collection: Collection;
@@ -10,14 +11,36 @@ export type ConfirmedLayer = {
10
11
  export type VisibleLayer = Layer & {
11
12
  collection: Collection;
12
13
  };
14
+ export type Staged = {
15
+ kind: 'staged';
16
+ confirmed: ConfirmedLayer;
17
+ } | Refused;
13
18
  export type Replica = {
14
19
  confirmed: ConfirmedLayer;
15
20
  queue: readonly ChangeBatch[];
16
21
  visible: VisibleLayer;
22
+ replay: readonly ReplayStep[];
23
+ };
24
+ type ReplayStep = {
25
+ id: string;
26
+ before: Layer;
27
+ after: Layer;
28
+ effective: ChangeBatch;
29
+ collection?: Collection;
17
30
  };
18
31
  export declare function compositionOf(record: ReplicaRecord): Composition;
19
- export declare function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null;
20
- export declare function readStaged(record: ReplicaRecord, binding: AttachedModelBinding | null): ConfirmedLayer | null;
21
- export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], roomVersion: string, binding: AttachedModelBinding | null): ConfirmedLayer | null;
22
- export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[]): Replica;
32
+ export declare function confirmedOf(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer;
33
+ export declare function sameMembership(record: ReplicaRecord, other: ReplicaRecord): boolean;
34
+ export declare function readStaged(record: ReplicaRecord, previous?: ConfirmedLayer): Staged;
35
+ export declare function readReclassified(record: ReplicaRecord, previous: ConfirmedLayer): Staged | {
36
+ kind: 'deferred';
37
+ };
38
+ type Accepted = Extract<MutationResult, {
39
+ kind: 'accepted';
40
+ }>;
41
+ export declare function applyReturned(confirmed: ConfirmedLayer, submitted: ChangeBatch, accepted: Accepted, roomVersion: string, writtenAt: string): Staged;
42
+ export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Replica;
43
+ export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer, current?: Readonly<Record<string, string>>): boolean;
44
+ export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, local: boolean): readonly ChangeBatch[];
45
+ export {};
23
46
  //# sourceMappingURL=replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAShE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,IAAI,CAG1E;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,cAAc,GAAG,IAAI,CAcvB;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,EACnB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,cAAc,GAAG,IAAI,CAmBvB;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAuB3F"}
1
+ {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AACnG,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAML,KAAK,KAAK,EACX,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,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,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,CAK5F;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,CA2BnF;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,cAAc,GACvB,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAW/B;AAoBD,KAAK,QAAQ,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE9D,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CA+BR;AAgDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA8BT;AA0ED,wBAAgB,MAAM,CACpB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,cAAc,EACzB,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC7C,OAAO,CAiBT;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,EAC7C,KAAK,EAAE,OAAO,GACb,SAAS,WAAW,EAAE,CA2BxB"}