@agentshouse/mdruntime 0.1.0-c56daf494ecb4 → 0.1.0-c59a5a6bd2f31

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 (290) hide show
  1. package/README.md +19 -16
  2. package/dist/acceptance.d.ts +26 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +384 -0
  5. package/dist/adapter.d.ts +152 -57
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/attached-model.d.ts +7 -10
  8. package/dist/attached-model.d.ts.map +1 -1
  9. package/dist/attached-model.js +40 -41
  10. package/dist/binary.d.ts +0 -5
  11. package/dist/binary.d.ts.map +1 -1
  12. package/dist/binary.js +1 -1
  13. package/dist/bootstrap.d.ts +31 -11
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +323 -93
  16. package/dist/chain.d.ts +12 -0
  17. package/dist/chain.d.ts.map +1 -0
  18. package/dist/chain.js +64 -0
  19. package/dist/change-set.d.ts +9 -14
  20. package/dist/change-set.d.ts.map +1 -1
  21. package/dist/change-set.js +11 -63
  22. package/dist/change.d.ts +32 -1
  23. package/dist/change.d.ts.map +1 -1
  24. package/dist/change.js +10 -1
  25. package/dist/chat-types.d.ts +3 -0
  26. package/dist/chat-types.d.ts.map +1 -0
  27. package/dist/chat-types.js +2 -0
  28. package/dist/client.d.ts +38 -16
  29. package/dist/client.d.ts.map +1 -1
  30. package/dist/client.js +101 -12
  31. package/dist/collection.d.ts +11 -7
  32. package/dist/collection.d.ts.map +1 -1
  33. package/dist/collection.js +38 -79
  34. package/dist/compile.d.ts +16 -0
  35. package/dist/compile.d.ts.map +1 -0
  36. package/dist/compile.js +717 -0
  37. package/dist/connection.d.ts +44 -39
  38. package/dist/connection.d.ts.map +1 -1
  39. package/dist/connection.js +2307 -1712
  40. package/dist/context.d.ts +2 -0
  41. package/dist/context.d.ts.map +1 -0
  42. package/dist/{chat/context.js → context.js} +1 -4
  43. package/dist/conversation-row.d.ts +33 -0
  44. package/dist/conversation-row.d.ts.map +1 -0
  45. package/dist/conversation-row.js +47 -0
  46. package/dist/conversation.d.ts +50 -20
  47. package/dist/conversation.d.ts.map +1 -1
  48. package/dist/conversation.js +897 -303
  49. package/dist/digest.d.ts +7 -0
  50. package/dist/digest.d.ts.map +1 -0
  51. package/dist/digest.js +113 -0
  52. package/dist/durability.d.ts +10 -1
  53. package/dist/durability.d.ts.map +1 -1
  54. package/dist/durability.js +5 -0
  55. package/dist/entry.d.ts +7 -4
  56. package/dist/entry.d.ts.map +1 -1
  57. package/dist/entry.js +33 -28
  58. package/dist/figures.d.ts +48 -0
  59. package/dist/figures.d.ts.map +1 -0
  60. package/dist/figures.js +197 -0
  61. package/dist/file.d.ts +2 -19
  62. package/dist/file.d.ts.map +1 -1
  63. package/dist/file.js +7 -122
  64. package/dist/host.d.ts +11 -2
  65. package/dist/host.d.ts.map +1 -1
  66. package/dist/host.js +127 -17
  67. package/dist/index.d.ts +27 -11
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +10 -0
  70. package/dist/install.d.ts +86 -0
  71. package/dist/install.d.ts.map +1 -0
  72. package/dist/install.js +537 -0
  73. package/dist/job.d.ts +33 -0
  74. package/dist/job.d.ts.map +1 -0
  75. package/dist/job.js +54 -0
  76. package/dist/live.d.ts +23 -0
  77. package/dist/live.d.ts.map +1 -0
  78. package/dist/live.js +165 -0
  79. package/dist/log.d.ts +1 -0
  80. package/dist/log.d.ts.map +1 -1
  81. package/dist/media.d.ts +8 -0
  82. package/dist/media.d.ts.map +1 -0
  83. package/dist/media.js +218 -0
  84. package/dist/memory.d.ts +19 -5
  85. package/dist/memory.d.ts.map +1 -1
  86. package/dist/memory.js +253 -94
  87. package/dist/messages.d.ts +52 -0
  88. package/dist/messages.d.ts.map +1 -0
  89. package/dist/messages.js +168 -0
  90. package/dist/model.d.ts +11 -11
  91. package/dist/model.d.ts.map +1 -1
  92. package/dist/model.js +7 -10
  93. package/dist/name.d.ts +4 -0
  94. package/dist/name.d.ts.map +1 -0
  95. package/dist/name.js +122 -0
  96. package/dist/observation.d.ts +22 -4
  97. package/dist/observation.d.ts.map +1 -1
  98. package/dist/observation.js +120 -14
  99. package/dist/opened.d.ts +22 -0
  100. package/dist/opened.d.ts.map +1 -0
  101. package/dist/opened.js +107 -0
  102. package/dist/outcome.d.ts +50 -7
  103. package/dist/outcome.d.ts.map +1 -1
  104. package/dist/outcome.js +43 -0
  105. package/dist/overlay.d.ts +4 -4
  106. package/dist/overlay.d.ts.map +1 -1
  107. package/dist/overlay.js +111 -182
  108. package/dist/{chat/parts.d.ts → parts.d.ts} +11 -9
  109. package/dist/parts.d.ts.map +1 -0
  110. package/dist/{chat/parts.js → parts.js} +45 -46
  111. package/dist/paths.d.ts +1 -0
  112. package/dist/paths.d.ts.map +1 -1
  113. package/dist/paths.js +4 -0
  114. package/dist/query.d.ts +50 -183
  115. package/dist/query.d.ts.map +1 -1
  116. package/dist/query.js +3 -464
  117. package/dist/{chat/questions.d.ts → questions.d.ts} +3 -2
  118. package/dist/questions.d.ts.map +1 -0
  119. package/dist/{chat/questions.js → questions.js} +8 -1
  120. package/dist/reach.d.ts +19 -7
  121. package/dist/reach.d.ts.map +1 -1
  122. package/dist/reach.js +289 -89
  123. package/dist/react.d.ts +11 -6
  124. package/dist/react.d.ts.map +1 -1
  125. package/dist/react.js +7 -17
  126. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  127. package/dist/read.d.ts.map +1 -0
  128. package/dist/{chat/read.js → read.js} +4 -0
  129. package/dist/readiness.d.ts +50 -0
  130. package/dist/readiness.d.ts.map +1 -0
  131. package/dist/readiness.js +27 -0
  132. package/dist/reads.d.ts +35 -0
  133. package/dist/reads.d.ts.map +1 -0
  134. package/dist/reads.js +128 -0
  135. package/dist/recovery.d.ts +26 -0
  136. package/dist/recovery.d.ts.map +1 -0
  137. package/dist/recovery.js +232 -0
  138. package/dist/refresh.d.ts +17 -14
  139. package/dist/refresh.d.ts.map +1 -1
  140. package/dist/refresh.js +143 -51
  141. package/dist/replica.d.ts +55 -33
  142. package/dist/replica.d.ts.map +1 -1
  143. package/dist/replica.js +332 -154
  144. package/dist/room-draft.d.ts +37 -6
  145. package/dist/room-draft.d.ts.map +1 -1
  146. package/dist/room-draft.js +161 -74
  147. package/dist/room-drafts.d.ts +29 -0
  148. package/dist/room-drafts.d.ts.map +1 -0
  149. package/dist/room-drafts.js +216 -0
  150. package/dist/rows.d.ts +30 -37
  151. package/dist/rows.d.ts.map +1 -1
  152. package/dist/rows.js +59 -126
  153. package/dist/save.d.ts +53 -9
  154. package/dist/save.d.ts.map +1 -1
  155. package/dist/save.js +542 -172
  156. package/dist/saves.d.ts +96 -0
  157. package/dist/saves.d.ts.map +1 -0
  158. package/dist/saves.js +999 -0
  159. package/dist/search.d.ts +15 -55
  160. package/dist/search.d.ts.map +1 -1
  161. package/dist/search.js +10 -121
  162. package/dist/seed.d.ts +30 -0
  163. package/dist/seed.d.ts.map +1 -0
  164. package/dist/seed.js +141 -0
  165. package/dist/shared.d.ts +15 -0
  166. package/dist/shared.d.ts.map +1 -0
  167. package/dist/shared.js +421 -0
  168. package/dist/socket/admission.d.ts +7 -0
  169. package/dist/socket/admission.d.ts.map +1 -0
  170. package/dist/socket/admission.js +39 -0
  171. package/dist/socket/answers.d.ts +6 -0
  172. package/dist/socket/answers.d.ts.map +1 -0
  173. package/dist/socket/answers.js +20 -0
  174. package/dist/socket/reads.d.ts +10 -0
  175. package/dist/socket/reads.d.ts.map +1 -0
  176. package/dist/socket/reads.js +31 -0
  177. package/dist/socket.d.ts +43 -0
  178. package/dist/socket.d.ts.map +1 -0
  179. package/dist/socket.js +96 -0
  180. package/dist/source.d.ts +61 -0
  181. package/dist/source.d.ts.map +1 -0
  182. package/dist/source.js +81 -0
  183. package/dist/status.d.ts +5 -2
  184. package/dist/status.d.ts.map +1 -1
  185. package/dist/status.js +3 -7
  186. package/dist/store/fences.d.ts +16 -0
  187. package/dist/store/fences.d.ts.map +1 -0
  188. package/dist/store/fences.js +26 -0
  189. package/dist/store/installs.d.ts +30 -0
  190. package/dist/store/installs.d.ts.map +1 -0
  191. package/dist/store/installs.js +34 -0
  192. package/dist/store/records.d.ts +212 -0
  193. package/dist/store/records.d.ts.map +1 -0
  194. package/dist/store/records.js +408 -0
  195. package/dist/store/room-held.d.ts +8 -0
  196. package/dist/store/room-held.d.ts.map +1 -0
  197. package/dist/store/room-held.js +17 -0
  198. package/dist/store/watchers.d.ts +15 -0
  199. package/dist/store/watchers.d.ts.map +1 -0
  200. package/dist/store/watchers.js +36 -0
  201. package/dist/store/writes.d.ts +24 -0
  202. package/dist/store/writes.d.ts.map +1 -0
  203. package/dist/store/writes.js +125 -0
  204. package/dist/store.d.ts +77 -120
  205. package/dist/store.d.ts.map +1 -1
  206. package/dist/store.js +112 -529
  207. package/dist/stored.d.ts +156 -0
  208. package/dist/stored.d.ts.map +1 -0
  209. package/dist/stored.js +637 -0
  210. package/dist/tables.d.ts +407 -0
  211. package/dist/tables.d.ts.map +1 -0
  212. package/dist/tables.js +724 -0
  213. package/dist/tallies.d.ts +18 -0
  214. package/dist/tallies.d.ts.map +1 -0
  215. package/dist/tallies.js +129 -0
  216. package/dist/transfer.d.ts +0 -5
  217. package/dist/transfer.d.ts.map +1 -1
  218. package/dist/turn.d.ts +9 -0
  219. package/dist/turn.d.ts.map +1 -0
  220. package/dist/turn.js +75 -0
  221. package/dist/validation.d.ts +29 -0
  222. package/dist/validation.d.ts.map +1 -0
  223. package/dist/validation.js +104 -0
  224. package/dist/windows.d.ts +11 -0
  225. package/dist/windows.d.ts.map +1 -0
  226. package/dist/windows.js +16 -0
  227. package/dist/wire.d.ts +179 -32
  228. package/dist/wire.d.ts.map +1 -1
  229. package/dist/wire.js +61 -31
  230. package/package.json +18 -19
  231. package/AGENTS.md +0 -302
  232. package/dist/chat/acts.d.ts +0 -34
  233. package/dist/chat/acts.d.ts.map +0 -1
  234. package/dist/chat/acts.js +0 -36
  235. package/dist/chat/context.d.ts +0 -3
  236. package/dist/chat/context.d.ts.map +0 -1
  237. package/dist/chat/input.d.ts +0 -9
  238. package/dist/chat/input.d.ts.map +0 -1
  239. package/dist/chat/input.js +0 -99
  240. package/dist/chat/kit.d.ts +0 -60
  241. package/dist/chat/kit.d.ts.map +0 -1
  242. package/dist/chat/kit.js +0 -123
  243. package/dist/chat/lasting.d.ts +0 -6
  244. package/dist/chat/lasting.d.ts.map +0 -1
  245. package/dist/chat/lasting.js +0 -19
  246. package/dist/chat/list.d.ts +0 -26
  247. package/dist/chat/list.d.ts.map +0 -1
  248. package/dist/chat/list.js +0 -62
  249. package/dist/chat/markdown.d.ts +0 -20
  250. package/dist/chat/markdown.d.ts.map +0 -1
  251. package/dist/chat/markdown.js +0 -188
  252. package/dist/chat/message.d.ts +0 -6
  253. package/dist/chat/message.d.ts.map +0 -1
  254. package/dist/chat/message.js +0 -192
  255. package/dist/chat/messages.d.ts +0 -21
  256. package/dist/chat/messages.d.ts.map +0 -1
  257. package/dist/chat/messages.js +0 -151
  258. package/dist/chat/name.d.ts +0 -6
  259. package/dist/chat/name.d.ts.map +0 -1
  260. package/dist/chat/name.js +0 -37
  261. package/dist/chat/opened.d.ts +0 -11
  262. package/dist/chat/opened.d.ts.map +0 -1
  263. package/dist/chat/opened.js +0 -17
  264. package/dist/chat/overlay.d.ts +0 -31
  265. package/dist/chat/overlay.d.ts.map +0 -1
  266. package/dist/chat/overlay.js +0 -97
  267. package/dist/chat/parts.d.ts.map +0 -1
  268. package/dist/chat/process.d.ts +0 -20
  269. package/dist/chat/process.d.ts.map +0 -1
  270. package/dist/chat/process.js +0 -32
  271. package/dist/chat/provider.d.ts +0 -63
  272. package/dist/chat/provider.d.ts.map +0 -1
  273. package/dist/chat/provider.js +0 -645
  274. package/dist/chat/question.d.ts +0 -9
  275. package/dist/chat/question.d.ts.map +0 -1
  276. package/dist/chat/question.js +0 -80
  277. package/dist/chat/questions.d.ts.map +0 -1
  278. package/dist/chat/read.d.ts.map +0 -1
  279. package/dist/chat/ready.d.ts +0 -33
  280. package/dist/chat/ready.d.ts.map +0 -1
  281. package/dist/chat/ready.js +0 -91
  282. package/dist/chat/style.d.ts +0 -4
  283. package/dist/chat/style.d.ts.map +0 -1
  284. package/dist/chat/style.js +0 -302
  285. package/dist/chat.d.ts +0 -14
  286. package/dist/chat.d.ts.map +0 -1
  287. package/dist/chat.js +0 -8
  288. package/dist/read-side.d.ts +0 -18
  289. package/dist/read-side.d.ts.map +0 -1
  290. package/dist/read-side.js +0 -440
package/dist/read-side.js DELETED
@@ -1,440 +0,0 @@
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
- }