@agentshouse/mdruntime 0.1.0-c94cfdbdb6f68 → 0.1.0-c95dc33df5c05

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 (364) hide show
  1. package/README.md +19 -16
  2. package/dist/acceptance.d.ts +6 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +389 -0
  5. package/dist/actions.d.ts +20 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +250 -0
  8. package/dist/adapter.d.ts +140 -85
  9. package/dist/adapter.d.ts.map +1 -1
  10. package/dist/attached-model.d.ts +7 -10
  11. package/dist/attached-model.d.ts.map +1 -1
  12. package/dist/attached-model.js +40 -41
  13. package/dist/binary.d.ts +0 -5
  14. package/dist/binary.d.ts.map +1 -1
  15. package/dist/binary.js +1 -1
  16. package/dist/bootstrap.d.ts +30 -11
  17. package/dist/bootstrap.d.ts.map +1 -1
  18. package/dist/bootstrap.js +319 -111
  19. package/dist/cell.d.ts +6 -0
  20. package/dist/cell.d.ts.map +1 -0
  21. package/dist/cell.js +9 -0
  22. package/dist/chain.d.ts +12 -0
  23. package/dist/chain.d.ts.map +1 -0
  24. package/dist/chain.js +64 -0
  25. package/dist/change-set.d.ts +9 -16
  26. package/dist/change-set.d.ts.map +1 -1
  27. package/dist/change-set.js +11 -89
  28. package/dist/change.d.ts +32 -1
  29. package/dist/change.d.ts.map +1 -1
  30. package/dist/change.js +10 -1
  31. package/dist/chat-types.d.ts +5 -0
  32. package/dist/chat-types.d.ts.map +1 -0
  33. package/dist/chat-types.js +13 -0
  34. package/dist/client.d.ts +30 -11
  35. package/dist/client.d.ts.map +1 -1
  36. package/dist/client.js +83 -7
  37. package/dist/collection.d.ts +11 -21
  38. package/dist/collection.d.ts.map +1 -1
  39. package/dist/collection.js +39 -321
  40. package/dist/compile.d.ts +16 -0
  41. package/dist/compile.d.ts.map +1 -0
  42. package/dist/compile.js +717 -0
  43. package/dist/connection.d.ts +7 -137
  44. package/dist/connection.d.ts.map +1 -1
  45. package/dist/connection.js +98 -3600
  46. package/dist/context.d.ts +2 -0
  47. package/dist/context.d.ts.map +1 -0
  48. package/dist/{chat/context.js → context.js} +1 -4
  49. package/dist/conversation-row.d.ts +33 -0
  50. package/dist/conversation-row.d.ts.map +1 -0
  51. package/dist/conversation-row.js +53 -0
  52. package/dist/conversation.d.ts +37 -18
  53. package/dist/conversation.d.ts.map +1 -1
  54. package/dist/conversation.js +573 -287
  55. package/dist/digest.d.ts +7 -0
  56. package/dist/digest.d.ts.map +1 -0
  57. package/dist/digest.js +113 -0
  58. package/dist/discovery.d.ts +10 -0
  59. package/dist/discovery.d.ts.map +1 -0
  60. package/dist/discovery.js +175 -0
  61. package/dist/durability.d.ts +16 -4
  62. package/dist/durability.d.ts.map +1 -1
  63. package/dist/durability.js +5 -0
  64. package/dist/entry.d.ts +5 -2
  65. package/dist/entry.d.ts.map +1 -1
  66. package/dist/entry.js +33 -29
  67. package/dist/figures.d.ts +48 -0
  68. package/dist/figures.d.ts.map +1 -0
  69. package/dist/figures.js +197 -0
  70. package/dist/file.d.ts +2 -19
  71. package/dist/file.d.ts.map +1 -1
  72. package/dist/file.js +7 -122
  73. package/dist/holdings.d.ts +29 -0
  74. package/dist/holdings.d.ts.map +1 -0
  75. package/dist/holdings.js +95 -0
  76. package/dist/host.d.ts +4 -7
  77. package/dist/host.d.ts.map +1 -1
  78. package/dist/host.js +67 -39
  79. package/dist/identity.d.ts +0 -2
  80. package/dist/identity.d.ts.map +1 -1
  81. package/dist/identity.js +0 -6
  82. package/dist/index.d.ts +31 -13
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +10 -2
  85. package/dist/install.d.ts +56 -0
  86. package/dist/install.d.ts.map +1 -0
  87. package/dist/install.js +560 -0
  88. package/dist/job.d.ts +33 -0
  89. package/dist/job.d.ts.map +1 -0
  90. package/dist/job.js +54 -0
  91. package/dist/lifecycle.d.ts +7 -0
  92. package/dist/lifecycle.d.ts.map +1 -0
  93. package/dist/lifecycle.js +267 -0
  94. package/dist/listing.d.ts +53 -0
  95. package/dist/listing.d.ts.map +1 -0
  96. package/dist/listing.js +175 -0
  97. package/dist/live.d.ts +23 -0
  98. package/dist/live.d.ts.map +1 -0
  99. package/dist/live.js +165 -0
  100. package/dist/locks.d.ts +9 -0
  101. package/dist/locks.d.ts.map +1 -0
  102. package/dist/locks.js +61 -0
  103. package/dist/log.d.ts +1 -0
  104. package/dist/log.d.ts.map +1 -1
  105. package/dist/lost.d.ts +5 -0
  106. package/dist/lost.d.ts.map +1 -0
  107. package/dist/lost.js +61 -0
  108. package/dist/media.d.ts +8 -0
  109. package/dist/media.d.ts.map +1 -0
  110. package/dist/media.js +218 -0
  111. package/dist/memory.d.ts +14 -6
  112. package/dist/memory.d.ts.map +1 -1
  113. package/dist/memory.js +237 -105
  114. package/dist/messages.d.ts +52 -0
  115. package/dist/messages.d.ts.map +1 -0
  116. package/dist/messages.js +168 -0
  117. package/dist/model.d.ts +8 -10
  118. package/dist/model.d.ts.map +1 -1
  119. package/dist/model.js +6 -18
  120. package/dist/models.d.ts +14 -0
  121. package/dist/models.d.ts.map +1 -0
  122. package/dist/models.js +193 -0
  123. package/dist/name.d.ts +4 -0
  124. package/dist/name.d.ts.map +1 -0
  125. package/dist/name.js +122 -0
  126. package/dist/observation.d.ts +15 -2
  127. package/dist/observation.d.ts.map +1 -1
  128. package/dist/observation.js +91 -2
  129. package/dist/opened.d.ts +22 -0
  130. package/dist/opened.d.ts.map +1 -0
  131. package/dist/opened.js +107 -0
  132. package/dist/opening.d.ts +4 -0
  133. package/dist/opening.d.ts.map +1 -0
  134. package/dist/opening.js +56 -0
  135. package/dist/outcome.d.ts +44 -9
  136. package/dist/outcome.d.ts.map +1 -1
  137. package/dist/outcome.js +41 -2
  138. package/dist/overlay.d.ts +3 -5
  139. package/dist/overlay.d.ts.map +1 -1
  140. package/dist/overlay.js +98 -172
  141. package/dist/{chat/parts.d.ts → parts.d.ts} +11 -9
  142. package/dist/parts.d.ts.map +1 -0
  143. package/dist/{chat/parts.js → parts.js} +45 -46
  144. package/dist/paths.d.ts +1 -0
  145. package/dist/paths.d.ts.map +1 -1
  146. package/dist/paths.js +4 -0
  147. package/dist/preparation.d.ts +20 -0
  148. package/dist/preparation.d.ts.map +1 -0
  149. package/dist/preparation.js +226 -0
  150. package/dist/queries.d.ts +16 -0
  151. package/dist/queries.d.ts.map +1 -0
  152. package/dist/queries.js +272 -0
  153. package/dist/query.d.ts +21 -206
  154. package/dist/query.d.ts.map +1 -1
  155. package/dist/query.js +3 -493
  156. package/dist/{chat/questions.d.ts → questions.d.ts} +5 -2
  157. package/dist/questions.d.ts.map +1 -0
  158. package/dist/{chat/questions.js → questions.js} +12 -1
  159. package/dist/reach.d.ts +20 -9
  160. package/dist/reach.d.ts.map +1 -1
  161. package/dist/reach.js +278 -103
  162. package/dist/react.d.ts +10 -2
  163. package/dist/react.d.ts.map +1 -1
  164. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  165. package/dist/read.d.ts.map +1 -0
  166. package/dist/{chat/read.js → read.js} +4 -0
  167. package/dist/readiness.d.ts +14 -17
  168. package/dist/readiness.d.ts.map +1 -1
  169. package/dist/readiness.js +2 -8
  170. package/dist/reads.d.ts +35 -10
  171. package/dist/reads.d.ts.map +1 -1
  172. package/dist/reads.js +136 -84
  173. package/dist/recovery.d.ts +3 -2
  174. package/dist/recovery.d.ts.map +1 -1
  175. package/dist/recovery.js +43 -8
  176. package/dist/refresh.d.ts +18 -15
  177. package/dist/refresh.d.ts.map +1 -1
  178. package/dist/refresh.js +143 -58
  179. package/dist/refusal.d.ts +5 -0
  180. package/dist/refusal.d.ts.map +1 -0
  181. package/dist/refusal.js +56 -0
  182. package/dist/replica.d.ts +54 -36
  183. package/dist/replica.d.ts.map +1 -1
  184. package/dist/replica.js +313 -188
  185. package/dist/room-draft.d.ts +25 -6
  186. package/dist/room-draft.d.ts.map +1 -1
  187. package/dist/room-draft.js +158 -71
  188. package/dist/room-drafts.d.ts +24 -0
  189. package/dist/room-drafts.d.ts.map +1 -0
  190. package/dist/room-drafts.js +216 -0
  191. package/dist/rows.d.ts +31 -31
  192. package/dist/rows.d.ts.map +1 -1
  193. package/dist/rows.js +59 -123
  194. package/dist/runtime.d.ts +42 -0
  195. package/dist/runtime.d.ts.map +1 -0
  196. package/dist/runtime.js +1 -0
  197. package/dist/save.d.ts +52 -14
  198. package/dist/save.d.ts.map +1 -1
  199. package/dist/save.js +518 -185
  200. package/dist/saves.d.ts +70 -0
  201. package/dist/saves.d.ts.map +1 -0
  202. package/dist/saves.js +1004 -0
  203. package/dist/search.d.ts +12 -95
  204. package/dist/search.d.ts.map +1 -1
  205. package/dist/search.js +10 -266
  206. package/dist/seed.d.ts +11 -2
  207. package/dist/seed.d.ts.map +1 -1
  208. package/dist/seed.js +71 -0
  209. package/dist/shared.d.ts +7 -3
  210. package/dist/shared.d.ts.map +1 -1
  211. package/dist/shared.js +119 -66
  212. package/dist/shown.d.ts +31 -0
  213. package/dist/shown.d.ts.map +1 -0
  214. package/dist/shown.js +294 -0
  215. package/dist/socket/admission.d.ts +7 -0
  216. package/dist/socket/admission.d.ts.map +1 -0
  217. package/dist/socket/admission.js +39 -0
  218. package/dist/socket/answers.d.ts +6 -0
  219. package/dist/socket/answers.d.ts.map +1 -0
  220. package/dist/socket/answers.js +20 -0
  221. package/dist/socket/lanes.d.ts +20 -0
  222. package/dist/socket/lanes.d.ts.map +1 -0
  223. package/dist/socket/lanes.js +77 -0
  224. package/dist/socket/reads.d.ts +10 -0
  225. package/dist/socket/reads.d.ts.map +1 -0
  226. package/dist/socket/reads.js +31 -0
  227. package/dist/socket/rooms.d.ts +43 -0
  228. package/dist/socket/rooms.d.ts.map +1 -0
  229. package/dist/socket/rooms.js +90 -0
  230. package/dist/socket/session.d.ts +39 -0
  231. package/dist/socket/session.d.ts.map +1 -0
  232. package/dist/socket/session.js +23 -0
  233. package/dist/socket.d.ts +70 -0
  234. package/dist/socket.d.ts.map +1 -0
  235. package/dist/socket.js +175 -0
  236. package/dist/source.d.ts +61 -0
  237. package/dist/source.d.ts.map +1 -0
  238. package/dist/source.js +81 -0
  239. package/dist/status.d.ts +4 -5
  240. package/dist/status.d.ts.map +1 -1
  241. package/dist/status.js +3 -7
  242. package/dist/store/fences.d.ts +16 -0
  243. package/dist/store/fences.d.ts.map +1 -0
  244. package/dist/store/fences.js +26 -0
  245. package/dist/store/installs.d.ts +30 -0
  246. package/dist/store/installs.d.ts.map +1 -0
  247. package/dist/store/installs.js +34 -0
  248. package/dist/store/readiness.d.ts +10 -0
  249. package/dist/store/readiness.d.ts.map +1 -0
  250. package/dist/store/readiness.js +52 -0
  251. package/dist/store/records.d.ts +212 -0
  252. package/dist/store/records.d.ts.map +1 -0
  253. package/dist/store/records.js +408 -0
  254. package/dist/store/room-held.d.ts +8 -0
  255. package/dist/store/room-held.d.ts.map +1 -0
  256. package/dist/store/room-held.js +17 -0
  257. package/dist/store/space.d.ts +11 -0
  258. package/dist/store/space.d.ts.map +1 -0
  259. package/dist/store/space.js +43 -0
  260. package/dist/store/watchers.d.ts +17 -0
  261. package/dist/store/watchers.d.ts.map +1 -0
  262. package/dist/store/watchers.js +57 -0
  263. package/dist/store/writes.d.ts +24 -0
  264. package/dist/store/writes.d.ts.map +1 -0
  265. package/dist/store/writes.js +125 -0
  266. package/dist/store.d.ts +106 -164
  267. package/dist/store.d.ts.map +1 -1
  268. package/dist/store.js +136 -752
  269. package/dist/stored.d.ts +156 -0
  270. package/dist/stored.d.ts.map +1 -0
  271. package/dist/stored.js +637 -0
  272. package/dist/surface.d.ts +88 -0
  273. package/dist/surface.d.ts.map +1 -0
  274. package/dist/surface.js +222 -0
  275. package/dist/sync.d.ts +20 -0
  276. package/dist/sync.d.ts.map +1 -0
  277. package/dist/sync.js +531 -0
  278. package/dist/tables.d.ts +415 -0
  279. package/dist/tables.d.ts.map +1 -0
  280. package/dist/tables.js +740 -0
  281. package/dist/tallies.d.ts +18 -0
  282. package/dist/tallies.d.ts.map +1 -0
  283. package/dist/tallies.js +129 -0
  284. package/dist/transfer.d.ts +0 -5
  285. package/dist/transfer.d.ts.map +1 -1
  286. package/dist/turn.d.ts +4 -2
  287. package/dist/turn.d.ts.map +1 -1
  288. package/dist/turn.js +46 -22
  289. package/dist/validation.d.ts +29 -0
  290. package/dist/validation.d.ts.map +1 -0
  291. package/dist/validation.js +104 -0
  292. package/dist/windows.d.ts +1 -16
  293. package/dist/windows.d.ts.map +1 -1
  294. package/dist/windows.js +2 -79
  295. package/dist/wire.d.ts +34 -6
  296. package/dist/wire.d.ts.map +1 -1
  297. package/dist/wire.js +12 -2
  298. package/package.json +18 -19
  299. package/AGENTS.md +0 -299
  300. package/dist/chat/acts.d.ts +0 -33
  301. package/dist/chat/acts.d.ts.map +0 -1
  302. package/dist/chat/acts.js +0 -36
  303. package/dist/chat/context.d.ts +0 -3
  304. package/dist/chat/context.d.ts.map +0 -1
  305. package/dist/chat/earlier.d.ts +0 -10
  306. package/dist/chat/earlier.d.ts.map +0 -1
  307. package/dist/chat/earlier.js +0 -54
  308. package/dist/chat/input.d.ts +0 -9
  309. package/dist/chat/input.d.ts.map +0 -1
  310. package/dist/chat/input.js +0 -99
  311. package/dist/chat/kit.d.ts +0 -61
  312. package/dist/chat/kit.d.ts.map +0 -1
  313. package/dist/chat/kit.js +0 -123
  314. package/dist/chat/lasting.d.ts +0 -6
  315. package/dist/chat/lasting.d.ts.map +0 -1
  316. package/dist/chat/lasting.js +0 -19
  317. package/dist/chat/list.d.ts +0 -27
  318. package/dist/chat/list.d.ts.map +0 -1
  319. package/dist/chat/list.js +0 -99
  320. package/dist/chat/markdown.d.ts +0 -20
  321. package/dist/chat/markdown.d.ts.map +0 -1
  322. package/dist/chat/markdown.js +0 -188
  323. package/dist/chat/message.d.ts +0 -6
  324. package/dist/chat/message.d.ts.map +0 -1
  325. package/dist/chat/message.js +0 -192
  326. package/dist/chat/messages.d.ts +0 -22
  327. package/dist/chat/messages.d.ts.map +0 -1
  328. package/dist/chat/messages.js +0 -155
  329. package/dist/chat/name.d.ts +0 -6
  330. package/dist/chat/name.d.ts.map +0 -1
  331. package/dist/chat/name.js +0 -37
  332. package/dist/chat/opened.d.ts +0 -11
  333. package/dist/chat/opened.d.ts.map +0 -1
  334. package/dist/chat/opened.js +0 -17
  335. package/dist/chat/overlay.d.ts +0 -31
  336. package/dist/chat/overlay.d.ts.map +0 -1
  337. package/dist/chat/overlay.js +0 -97
  338. package/dist/chat/parts.d.ts.map +0 -1
  339. package/dist/chat/process.d.ts +0 -20
  340. package/dist/chat/process.d.ts.map +0 -1
  341. package/dist/chat/process.js +0 -32
  342. package/dist/chat/provider.d.ts +0 -63
  343. package/dist/chat/provider.d.ts.map +0 -1
  344. package/dist/chat/provider.js +0 -628
  345. package/dist/chat/question.d.ts +0 -9
  346. package/dist/chat/question.d.ts.map +0 -1
  347. package/dist/chat/question.js +0 -69
  348. package/dist/chat/questions.d.ts.map +0 -1
  349. package/dist/chat/read.d.ts.map +0 -1
  350. package/dist/chat/ready.d.ts +0 -34
  351. package/dist/chat/ready.d.ts.map +0 -1
  352. package/dist/chat/ready.js +0 -91
  353. package/dist/chat/style.d.ts +0 -4
  354. package/dist/chat/style.d.ts.map +0 -1
  355. package/dist/chat/style.js +0 -302
  356. package/dist/chat.d.ts +0 -14
  357. package/dist/chat.d.ts.map +0 -1
  358. package/dist/chat.js +0 -8
  359. package/dist/fence.d.ts +0 -6
  360. package/dist/fence.d.ts.map +0 -1
  361. package/dist/fence.js +0 -10
  362. package/dist/read-side.d.ts +0 -27
  363. package/dist/read-side.d.ts.map +0 -1
  364. package/dist/read-side.js +0 -824
package/dist/read-side.js DELETED
@@ -1,824 +0,0 @@
1
- import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, inArray, or, toArray, } from '@tanstack/db';
2
- import { ARRAY_INDEX, parse, pointerSegments } from '@agentshouse/mdmodel';
3
- import { documentKey } from './rows.js';
4
- import { after, inUnits, ROW_WEIGHT } from './turn.js';
5
- import { beyond, cursorOf, MAXIMUM_WINDOW, windowed } from './windows.js';
6
- function every(expressions) {
7
- const [first, second, ...rest] = expressions;
8
- return second === undefined ? first : and(first, second, ...rest);
9
- }
10
- function same(held, value) {
11
- return Array.isArray(held) ? held.includes(value) : held === value;
12
- }
13
- function ordered(held, [operator, bound]) {
14
- if (typeof held !== typeof bound || held === null || typeof held === 'object')
15
- return false;
16
- const left = held;
17
- const right = bound;
18
- if (operator === 'gt')
19
- return left > right;
20
- if (operator === 'gte')
21
- return left >= right;
22
- if (operator === 'lt')
23
- return left < right;
24
- return left <= right;
25
- }
26
- function satisfied(test, held) {
27
- if (test.op === 'eq')
28
- return same(held, test.value);
29
- if (test.op === 'ne')
30
- return !same(held, test.value);
31
- if (test.op === 'in')
32
- return test.values.some((value) => same(held, value));
33
- if (test.op === 'nin')
34
- return !test.values.some((value) => same(held, value));
35
- if (test.op === 'range')
36
- return test.bounds.every((bound) => ordered(held, bound));
37
- if (test.op === 'all')
38
- return Array.isArray(held) && test.values.every((value) => same(held, value));
39
- return Array.isArray(held) && held.length === test.size;
40
- }
41
- function tested(test, reached) {
42
- if (test.op === 'exists')
43
- return test.exists === (reached !== undefined);
44
- if (reached === undefined)
45
- return test.op === 'ne' || test.op === 'nin';
46
- return reached.some((held) => satisfied(test, held));
47
- }
48
- function conditioned(condition, row) {
49
- if ('every' in condition)
50
- return condition.every.every((item) => conditioned(item, row));
51
- if ('some' in condition)
52
- return condition.some.some((item) => conditioned(item, row));
53
- return tested(condition.test, row.reached[condition.field]);
54
- }
55
- function narrowed(query, where, alias) {
56
- return where === null ? query : query.fn.where((row) => conditioned(where, row[alias]));
57
- }
58
- function reached(reach, room, document) {
59
- return reach === null
60
- ? []
61
- : [or(inArray(room, [...reach.rooms]), inArray(document, [...reach.documents]))];
62
- }
63
- function scoped(scope, row, rooms, reach, paths = null, folder = null) {
64
- return every([
65
- eq(row.kind, 'document'),
66
- ...(rooms === null ? [] : [inArray(row.room, [...rooms])]),
67
- ...(paths === null ? [] : [inArray(row.path, [...paths])]),
68
- ...(folder === null ? [] : [eq(row.folder, folder)]),
69
- ...reached(reach, row.room, row.key),
70
- ...(scope.types === null ? [] : [inArray(row.type, [...scope.types])]),
71
- ...(scope.pathPrefix === null ? [] : [inArray(scope.pathPrefix, row.directories)]),
72
- ]);
73
- }
74
- function keyed(key, row) {
75
- return key.of === 'field' ? row.values[key.field] : row[key.of];
76
- }
77
- function live(query) {
78
- return createLiveQueryCollection({
79
- query: query,
80
- startSync: true,
81
- });
82
- }
83
- function related(q, rows, scope, field, kept, reach) {
84
- const matched = kept === 'source' ? 'target' : 'source';
85
- const from = q.from({ r: rows });
86
- const joined = from
87
- .where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [inArray(field, r.forms)])]))
88
- .innerJoin({ m: rows }, ({ r, m }) => eq(r[matched], m.key))
89
- .where(({ m }) => scoped(scope, m, null, reach));
90
- return narrowed(joined, scope.where, 'm')
91
- .groupBy(({ r }) => r[kept])
92
- .select(({ r }) => ({ key: r[kept] }));
93
- }
94
- function filtered(q, rows, plan) {
95
- const from = q.from({ d: rows });
96
- let query = narrowed(from.where(({ d }) => scoped(plan.root, d, plan.rooms, plan.reach, plan.paths, plan.folder)), plan.root.where, 'd');
97
- if (plan.hop !== null) {
98
- const hop = related(q, rows, plan.hop, plan.hop.field, 'source', plan.reach);
99
- query = query.innerJoin({ h: hop }, ({ d, h }) => eq(d.key, h.key));
100
- }
101
- if (plan.backlinks !== null) {
102
- const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target', plan.reach);
103
- query = query.innerJoin({ k: backlinks }, ({ d, k }) => eq(d.key, k.key));
104
- }
105
- return query;
106
- }
107
- function bodied(shape) {
108
- return shape.sections !== null || shape.preamble || shape.markdown;
109
- }
110
- function orderingOf(options) {
111
- const collated = options.stringSort === 'locale';
112
- return {
113
- direction: options.direction,
114
- nulls: options.nulls ?? 'first',
115
- stringSort: options.stringSort ?? 'locale',
116
- locale: collated ? options.locale : undefined,
117
- localeOptions: collated
118
- ? options.localeOptions
119
- : undefined,
120
- };
121
- }
122
- function storedValue(key, row) {
123
- return key.of === 'field' ? row.values[key.field] : row[key.of];
124
- }
125
- function documentOrder(shape) {
126
- return shape.orderBy.map(({ options }) => orderingOf(options));
127
- }
128
- function documentCursor(shape, row) {
129
- return cursorOf([
130
- ...shape.orderBy.map((_, index) => row[`order${index}`]),
131
- documentKey(row.room, row.path),
132
- ]);
133
- }
134
- function documents(q, rows, plan, shape) {
135
- let query = filtered(q, rows, plan);
136
- const cursor = plan.after?.values ?? null;
137
- if (cursor !== null) {
138
- const orderings = documentOrder(shape);
139
- query = query.fn.where(({ d }) => beyond([...shape.orderBy.map(({ key }) => storedValue(key, d)), d.key], cursor, orderings));
140
- }
141
- for (const { key, options } of shape.orderBy) {
142
- query = query.orderBy(({ d }) => keyed(key, d), options);
143
- }
144
- if (shape.orderBy.length > 0 || plan.limit !== null || plan.after !== null) {
145
- query = query.orderBy(({ d }) => d.key, { stringSort: 'lexical' });
146
- }
147
- if (plan.limit !== null)
148
- query = query.limit(plan.limit + 1);
149
- return query.select(({ d }) => ({
150
- room: d.room,
151
- path: d.path,
152
- type: d.type,
153
- binary: d.binary,
154
- ...Object.fromEntries(shape.orderBy.map(({ key }, index) => [`order${index}`, keyed(key, d)])),
155
- ...(shape.fields === null ? {} : { fields: d.fields }),
156
- ...(bodied(shape) ? { text: d.text } : {}),
157
- ...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d, plan.reach)) } : {}),
158
- ...(shape.change ? { change: d.change } : {}),
159
- ...(shape.fileId ? { fileId: d.fileId } : {}),
160
- }));
161
- }
162
- function backlinked(q, rows, document, reach) {
163
- const from = q.from({ r: rows });
164
- return from
165
- .where(({ r }) => every([eq(r.target, document.key), ...reached(reach, r.room, r.source)]))
166
- .orderBy(({ r }) => r.path, { stringSort: 'lexical' })
167
- .orderBy(({ r }) => r.field, { stringSort: 'lexical' })
168
- .select(({ r }) => ({ path: r.path, type: r.type, field: r.field }));
169
- }
170
- function groups(q, stage, shape) {
171
- const keys = shape.groupBy.map((_, index) => `key${index}`);
172
- const from = q.from({ m: stage });
173
- let query = from.groupBy(({ m }) => keys.map((key) => m[key]));
174
- for (const { by, direction } of shape.orderBy) {
175
- query = query.orderBy(({ m }) => (by === 'count' ? count(m.key) : m[keys[by]]), direction);
176
- }
177
- return query.select(({ m }) => ({
178
- ...Object.fromEntries(keys.map((key) => [key, m[key]])),
179
- count: count(m.key),
180
- }));
181
- }
182
- function built(rows, plan) {
183
- const shape = plan.shape;
184
- if (shape.kind === 'documents') {
185
- const collection = live((q) => documents(q, rows, plan, shape));
186
- const count = plan.total
187
- ? live((q) => filtered(q, rows, plan).select(({ d }) => ({ key: d.key })))
188
- : null;
189
- return {
190
- live: collection,
191
- count,
192
- dispose: () => {
193
- void collection.cleanup();
194
- if (count !== null)
195
- void count.cleanup();
196
- },
197
- };
198
- }
199
- const stage = live((q) => filtered(q, rows, plan).select(({ d }) => ({
200
- key: d.key,
201
- ...Object.fromEntries(shape.groupBy.map((key, index) => [`key${index}`, keyed(key, d)])),
202
- })));
203
- const collection = live((q) => groups(q, stage, shape));
204
- return {
205
- live: collection,
206
- count: null,
207
- dispose: () => {
208
- void collection.cleanup();
209
- void stage.cleanup();
210
- },
211
- };
212
- }
213
- function sectionsOf(sections, names) {
214
- if (names === 'all')
215
- return sections;
216
- return Object.fromEntries(names.flatMap((name) => (Object.hasOwn(sections, name) ? [[name, sections[name]]] : [])));
217
- }
218
- function bodyOf(row, key, bodies) {
219
- const text = row.text;
220
- if (text === null)
221
- return null;
222
- const held = bodies?.get(key);
223
- if (held !== undefined && held.text === text)
224
- return held.document;
225
- const read = parse(text, row.path);
226
- const document = read.ok ? read.document : null;
227
- bodies?.set(key, { text, document });
228
- return document;
229
- }
230
- function masked(pointers) {
231
- const root = { whole: false, members: new Map() };
232
- for (const pointer of pointers) {
233
- let mask = root;
234
- for (const token of pointerSegments(pointer)) {
235
- const next = mask.members.get(token) ?? { whole: false, members: new Map() };
236
- mask.members.set(token, next);
237
- mask = next;
238
- }
239
- mask.whole = true;
240
- }
241
- return root;
242
- }
243
- function merged(left, right) {
244
- if (left === undefined)
245
- return right;
246
- const members = new Map(left.members);
247
- for (const [token, mask] of right.members)
248
- members.set(token, merged(members.get(token), mask));
249
- return { whole: left.whole || right.whole, members };
250
- }
251
- function cut(value, mask) {
252
- if (mask.whole)
253
- return value;
254
- if (Array.isArray(value)) {
255
- const each = {
256
- whole: false,
257
- members: new Map([...mask.members].filter(([token]) => !ARRAY_INDEX.test(token))),
258
- };
259
- const kept = [];
260
- value.forEach((item, index) => {
261
- const part = cut(item, merged(mask.members.get(String(index)), each));
262
- if (part !== undefined)
263
- kept[index] = part;
264
- });
265
- return kept.length === 0 ? undefined : kept;
266
- }
267
- if (typeof value !== 'object' || value === null)
268
- return undefined;
269
- const kept = Object.entries(value).flatMap(([key, held]) => {
270
- const member = mask.members.get(key);
271
- const part = member === undefined ? undefined : cut(held, member);
272
- return part === undefined ? [] : [[key, part]];
273
- });
274
- return kept.length === 0 ? undefined : Object.fromEntries(kept);
275
- }
276
- function selected(fields, pointers) {
277
- return (cut(fields, masked(pointers)) ?? {});
278
- }
279
- function documentOf(key, row, shape, bodies) {
280
- if (row.type === null) {
281
- const binary = row.binary;
282
- return {
283
- room: row.room,
284
- path: row.path,
285
- ...(binary === null ? {} : { binaryFile: binary }),
286
- ...(shape.fileId ? { fileId: row.fileId } : {}),
287
- };
288
- }
289
- const body = bodied(shape) ? bodyOf(row, key, bodies) : null;
290
- return {
291
- room: row.room,
292
- path: row.path,
293
- type: row.type,
294
- ...(shape.fields === null
295
- ? {}
296
- : {
297
- fields: shape.fields === 'all'
298
- ? row.fields
299
- : selected(row.fields, shape.fields),
300
- }),
301
- ...(shape.sections === null || body === null
302
- ? {}
303
- : { sections: sectionsOf(body.sections, shape.sections) }),
304
- ...(shape.preamble && body !== null ? { preamble: body.preamble } : {}),
305
- ...(shape.markdown && body !== null ? { markdown: body.content } : {}),
306
- ...(shape.backlinks
307
- ? {
308
- backlinks: row.backlinks
309
- .slice(0, MAXIMUM_WINDOW)
310
- .map(({ path, type, field }) => ({ path, type, field })),
311
- }
312
- : {}),
313
- ...(shape.change ? { change: row.change } : {}),
314
- ...(shape.fileId ? { fileId: row.fileId } : {}),
315
- };
316
- }
317
- function weight(row) {
318
- return ROW_WEIGHT + (typeof row?.text === 'string' ? row.text.length : 0);
319
- }
320
- function groupValues(shape, [key, row]) {
321
- return [...shape.orderBy.map(({ by }) => (by === 'count' ? row.count : row[`key${by}`])), key];
322
- }
323
- function groupOrder(shape) {
324
- return shape.orderBy.map(({ direction }) => ({
325
- direction,
326
- nulls: 'first',
327
- stringSort: 'locale',
328
- locale: undefined,
329
- localeOptions: undefined,
330
- }));
331
- }
332
- function windowOf(plan, entries, total) {
333
- const shape = plan.shape;
334
- if (shape.kind === 'documents') {
335
- return {
336
- ...windowed(entries, plan.limit, plan.after?.text, ([, row]) => documentCursor(shape, row)),
337
- total,
338
- };
339
- }
340
- const cursor = plan.after?.values ?? null;
341
- const orderings = groupOrder(shape);
342
- const following = cursor === null
343
- ? entries
344
- : entries.filter((entry) => beyond(groupValues(shape, entry), cursor, orderings));
345
- return {
346
- ...windowed(following, plan.limit, plan.after?.text, (entry) => cursorOf(groupValues(shape, entry))),
347
- total: plan.total ? entries.length : undefined,
348
- };
349
- }
350
- function framed(rows, { next, total }) {
351
- return {
352
- ...rows,
353
- ...(next === undefined ? {} : { next }),
354
- ...(total === undefined ? {} : { total }),
355
- };
356
- }
357
- function rowsOfPlan(plan, entries, total, bodies, each = (row) => row) {
358
- const shape = plan.shape;
359
- const { kept, ...window } = windowOf(plan, entries, total);
360
- const keys = kept.map(([key]) => key);
361
- if (shape.kind === 'documents') {
362
- const documents = [];
363
- return after(inUnits(kept, ([key, row]) => {
364
- documents.push(each(documentOf(key, row, shape, bodies)));
365
- return weight(row);
366
- }), () => ({ rows: framed({ documents }, window), keys, ...window }));
367
- }
368
- const groups = [];
369
- return after(inUnits(kept, ([, row]) => {
370
- groups.push(each({
371
- key: shape.groupBy.map((_, index) => row[`key${index}`]),
372
- count: row.count,
373
- }));
374
- return ROW_WEIGHT;
375
- }), () => ({ rows: framed({ groups }, window), keys, ...window }));
376
- }
377
- export function reconciled(previous, next) {
378
- const before = previous.result;
379
- const after = next.result;
380
- if ('pending' in before || 'pending' in after) {
381
- if (deepEquals(before, after))
382
- return null;
383
- return { keyed: next, message: next };
384
- }
385
- const earlier = 'groups' in before ? before.groups : before.documents;
386
- const held = new Map(previous.keys.map((key, index) => [key, earlier[index]]));
387
- const changed = [];
388
- const rows = ('groups' in after ? after.groups : after.documents).map((row, index) => {
389
- const key = next.keys[index];
390
- const kept = held.get(key);
391
- if (kept !== undefined && deepEquals(kept, row))
392
- return kept;
393
- changed.push([key, row]);
394
- return row;
395
- });
396
- const present = new Set(next.keys);
397
- const removed = previous.keys.filter((key) => !present.has(key));
398
- const moved = reordered(previous.keys, next.keys, present);
399
- const covered = !deepEquals(before.coverage, after.coverage);
400
- const framing = reframed(before, after);
401
- if (changed.length === 0 && removed.length === 0 && !moved && !covered && framing === null) {
402
- return null;
403
- }
404
- const window = { next: after.next, total: after.total };
405
- return {
406
- keyed: {
407
- result: 'groups' in after
408
- ? framed({ groups: rows, coverage: after.coverage }, window)
409
- : framed({ documents: rows, coverage: after.coverage }, window),
410
- keys: next.keys,
411
- },
412
- message: {
413
- changed,
414
- removed,
415
- order: moved ? next.keys : null,
416
- ...(covered ? { coverage: after.coverage } : {}),
417
- ...framing,
418
- },
419
- };
420
- }
421
- function reframed(before, after) {
422
- const next = before.next === after.next ? {} : { next: after.next ?? null };
423
- const total = before.total === after.total || after.total === undefined ? {} : { total: after.total };
424
- return Object.keys(next).length === 0 && Object.keys(total).length === 0
425
- ? null
426
- : { ...next, ...total };
427
- }
428
- function reordered(previous, next, present) {
429
- let at = 0;
430
- for (const key of previous) {
431
- if (!present.has(key))
432
- continue;
433
- if (next[at] !== key)
434
- return true;
435
- at += 1;
436
- }
437
- return at !== next.length;
438
- }
439
- export function createReadSide() {
440
- configureIndexDevMode({ enabled: false });
441
- let sync;
442
- const rows = createCollection({
443
- getKey: (row) => row.key,
444
- gcTime: 0,
445
- startSync: true,
446
- autoIndex: 'eager',
447
- defaultIndexType: BasicIndex,
448
- sync: {
449
- rowUpdateMode: 'full',
450
- sync: (params) => {
451
- sync = params;
452
- params.markReady();
453
- },
454
- },
455
- });
456
- const shared = new Map();
457
- let writing = false;
458
- let publishing = null;
459
- let closed = false;
460
- function searched(row) {
461
- const read = row.text === null ? null : parse(row.text, row.path);
462
- if (read === null || !read.ok)
463
- return null;
464
- return {
465
- room: row.room,
466
- path: row.path,
467
- type: row.type,
468
- fields: row.fields,
469
- preamble: read.document.preamble,
470
- sections: read.document.sections,
471
- };
472
- }
473
- function kept(entry, key, row) {
474
- const held = entry.rows.get(key);
475
- if (held !== undefined && deepEquals(held, row))
476
- return;
477
- entry.rows.set(key, row);
478
- }
479
- function counted(entry) {
480
- return entry.built.count === null ? undefined : entry.built.count.size;
481
- }
482
- function rebuilt(entry) {
483
- return after(rowsOfPlan(entry.plan, [...entry.built.live.entries()], counted(entry), entry.bodies), ({ rows: found, keys, next, total }) => {
484
- const present = new Set(keys);
485
- for (const key of [...entry.rows.keys()])
486
- if (!present.has(key))
487
- entry.rows.delete(key);
488
- for (const key of [...entry.bodies.keys()]) {
489
- if (!present.has(key))
490
- entry.bodies.delete(key);
491
- }
492
- keys.forEach((key, index) => kept(entry, key, rowAt(found, index)));
493
- return { keys, next, total };
494
- });
495
- }
496
- function refreshed(entry, dirty) {
497
- const shape = entry.plan.shape;
498
- const { kept: inWindow, next, total, } = windowOf(entry.plan, [...entry.built.live.entries()], counted(entry));
499
- const keys = inWindow.map(([key]) => key);
500
- const present = new Set(keys);
501
- for (const key of [...entry.rows.keys()]) {
502
- if (present.has(key))
503
- continue;
504
- entry.rows.delete(key);
505
- entry.bodies.delete(key);
506
- }
507
- const values = inWindow.filter(([key]) => dirty.has(key) || !entry.rows.has(key));
508
- const done = inUnits(values, ([key, value]) => {
509
- kept(entry, key, documentOf(key, value, shape, entry.bodies));
510
- return weight(value);
511
- });
512
- return after(done, () => ({ keys, next, total }));
513
- }
514
- function current(entry, found, coverage) {
515
- const rows = found.keys.map((key) => entry.rows.get(key));
516
- return {
517
- result: entry.plan.shape.kind === 'groups'
518
- ? framed({ groups: rows, coverage }, found)
519
- : framed({ documents: rows, coverage }, found),
520
- keys: found.keys,
521
- };
522
- }
523
- function delivered(entry, next) {
524
- const previous = entry.result;
525
- entry.result = next;
526
- const message = previous === undefined ? null : changedFrom(previous, next);
527
- if (message !== null)
528
- for (const listener of entry.ready)
529
- listener(message);
530
- for (const listener of entry.fresh) {
531
- entry.ready.add(listener);
532
- listener(next);
533
- }
534
- entry.fresh.clear();
535
- }
536
- function run(entry) {
537
- while (entry.listeners.size > 0 &&
538
- (entry.whole || entry.dirty.size > 0 || entry.stale || entry.fresh.size > 0)) {
539
- entry.stale = false;
540
- const cover = entry.cover();
541
- if ('pending' in cover) {
542
- entry.whole = true;
543
- entry.dirty.clear();
544
- entry.rows.clear();
545
- entry.bodies.clear();
546
- delivered(entry, { result: cover, keys: [] });
547
- break;
548
- }
549
- const whole = entry.whole ||
550
- entry.plan.shape.kind === 'groups' ||
551
- entry.result === undefined ||
552
- 'pending' in entry.result.result;
553
- const dirty = entry.dirty;
554
- entry.dirty = new Set();
555
- entry.whole = false;
556
- const found = whole ? rebuilt(entry) : refreshed(entry, dirty);
557
- if (found instanceof Promise) {
558
- void found
559
- .then((window) => {
560
- if (entry.listeners.size > 0)
561
- delivered(entry, current(entry, window, cover.coverage));
562
- entry.running = false;
563
- wake(entry);
564
- })
565
- .catch(() => {
566
- entry.running = false;
567
- });
568
- return;
569
- }
570
- delivered(entry, current(entry, found, cover.coverage));
571
- }
572
- entry.running = false;
573
- }
574
- function wake(entry) {
575
- if (entry.subscription === null || entry.running || writing || publishing !== null)
576
- return;
577
- entry.running = true;
578
- try {
579
- run(entry);
580
- }
581
- catch (error) {
582
- entry.running = false;
583
- throw error;
584
- }
585
- }
586
- function recover() {
587
- for (const entry of shared.values()) {
588
- if (entry.result === undefined || entry.subscription === null)
589
- continue;
590
- const cover = entry.cover();
591
- const before = entry.result.result;
592
- const held = 'pending' in cover
593
- ? deepEquals(before, cover)
594
- : 'coverage' in before && deepEquals(before.coverage, cover.coverage);
595
- if (held)
596
- continue;
597
- entry.stale = true;
598
- wake(entry);
599
- }
600
- }
601
- function committed(next) {
602
- if (closed || next.size === 0)
603
- return;
604
- sync.begin();
605
- for (const [key, row] of next) {
606
- if (row === null) {
607
- if (rows.has(key))
608
- sync.write({ type: 'delete', key });
609
- continue;
610
- }
611
- sync.write({ type: rows.has(key) ? 'update' : 'insert', value: row });
612
- }
613
- sync.commit();
614
- }
615
- function published(set) {
616
- let unit = new Map();
617
- return inUnits(set.documents, (change) => {
618
- if (closed)
619
- return 0;
620
- let spent = 0;
621
- for (const row of change.before) {
622
- unit.set(row.key, null);
623
- spent += ROW_WEIGHT;
624
- }
625
- for (const row of change.after) {
626
- unit.set(row.key, row);
627
- spent += weight(row);
628
- }
629
- return spent;
630
- }, () => {
631
- committed(unit);
632
- unit = new Map();
633
- });
634
- }
635
- function released() {
636
- recover();
637
- for (const entry of shared.values())
638
- wake(entry);
639
- }
640
- function publishedLater(applied) {
641
- const fence = applied.then(() => { }, () => { });
642
- publishing = fence;
643
- void fence.then(() => {
644
- if (publishing !== fence)
645
- return;
646
- publishing = null;
647
- released();
648
- });
649
- return applied;
650
- }
651
- async function settled() {
652
- while (publishing !== null)
653
- await publishing;
654
- }
655
- return {
656
- apply(set, next = () => { }) {
657
- const pending = publishing;
658
- if (pending !== null) {
659
- return publishedLater(pending.then(() => after(published(set), next)));
660
- }
661
- writing = true;
662
- let applied;
663
- try {
664
- applied = published(set);
665
- }
666
- finally {
667
- writing = false;
668
- }
669
- if (applied instanceof Promise)
670
- return publishedLater(applied.then(next));
671
- released();
672
- next();
673
- },
674
- recover,
675
- settled,
676
- async query(plan, at) {
677
- const { live: collection, count, dispose } = built(rows, plan);
678
- try {
679
- await collection.toArrayWhenReady();
680
- if (count !== null)
681
- await count.toArrayWhenReady();
682
- await settled();
683
- const entries = [...collection.entries()];
684
- const held = at();
685
- const found = await rowsOfPlan(plan, entries, count?.size, null, structuredClone);
686
- return { rows: found.rows, at: held };
687
- }
688
- finally {
689
- dispose();
690
- }
691
- },
692
- watch(plan, identity, cover, deliverTo) {
693
- let entry = shared.get(identity);
694
- if (entry === undefined) {
695
- const created = {
696
- plan,
697
- built: built(rows, plan),
698
- cover,
699
- result: undefined,
700
- rows: new Map(),
701
- bodies: new Map(),
702
- listeners: new Set(),
703
- fresh: new Set(),
704
- ready: new Set(),
705
- subscription: null,
706
- counting: null,
707
- whole: true,
708
- dirty: new Set(),
709
- stale: false,
710
- running: false,
711
- };
712
- created.built.live.on('status:change', ({ status }) => {
713
- if (status !== 'cleaned-up' || created.listeners.size > 0)
714
- return;
715
- if (shared.get(identity) === created)
716
- shared.delete(identity);
717
- });
718
- shared.set(identity, created);
719
- entry = created;
720
- }
721
- const observed = entry;
722
- observed.listeners.add(deliverTo);
723
- const ready = (then) => observed.built.live.onFirstReady(() => observed.built.count === null ? then() : observed.built.count.onFirstReady(then));
724
- const settled = () => {
725
- if (observed.built.count === null)
726
- wake(observed);
727
- else
728
- queueMicrotask(() => wake(observed));
729
- };
730
- ready(() => {
731
- if (!observed.listeners.has(deliverTo))
732
- return;
733
- observed.fresh.add(deliverTo);
734
- if (observed.subscription === null) {
735
- observed.whole = true;
736
- observed.subscription = observed.built.live.subscribeChanges((changes) => {
737
- if (observed.plan.shape.kind === 'groups')
738
- observed.whole = true;
739
- else
740
- for (const { key } of changes)
741
- observed.dirty.add(key);
742
- settled();
743
- }, { includeInitialState: false });
744
- observed.counting =
745
- observed.built.count?.subscribeChanges(() => {
746
- observed.stale = true;
747
- settled();
748
- }, { includeInitialState: false }) ?? null;
749
- }
750
- wake(observed);
751
- });
752
- return () => {
753
- observed.fresh.delete(deliverTo);
754
- observed.ready.delete(deliverTo);
755
- if (!observed.listeners.delete(deliverTo) || observed.listeners.size > 0)
756
- return;
757
- observed.subscription?.unsubscribe();
758
- observed.subscription = null;
759
- observed.counting?.unsubscribe();
760
- observed.counting = null;
761
- observed.result = undefined;
762
- observed.rows.clear();
763
- observed.bodies.clear();
764
- observed.dirty.clear();
765
- observed.whole = true;
766
- if (shared.get(identity) === observed)
767
- shared.delete(identity);
768
- observed.built.dispose();
769
- };
770
- },
771
- room(room) {
772
- return rows.toArray.flatMap((row) => row.kind !== 'document' || row.type === null || row.room !== room ? [] : [row.path]);
773
- },
774
- document(room, path) {
775
- const row = rows.get(documentKey(room, path));
776
- return row === undefined || row.type === null ? null : searched(row);
777
- },
778
- close() {
779
- closed = true;
780
- for (const entry of shared.values()) {
781
- entry.listeners.clear();
782
- entry.fresh.clear();
783
- entry.ready.clear();
784
- entry.subscription?.unsubscribe();
785
- entry.counting?.unsubscribe();
786
- entry.built.dispose();
787
- }
788
- shared.clear();
789
- void rows.cleanup();
790
- },
791
- };
792
- }
793
- function changedFrom(previous, next) {
794
- const before = previous.result;
795
- const after = next.result;
796
- if ('pending' in before || 'pending' in after)
797
- return deepEquals(before, after) ? null : next;
798
- const earlier = 'groups' in before ? before.groups : before.documents;
799
- const held = new Map(previous.keys.map((key, index) => [key, earlier[index]]));
800
- const later = 'groups' in after ? after.groups : after.documents;
801
- const changed = [];
802
- next.keys.forEach((key, index) => {
803
- if (held.get(key) !== later[index])
804
- changed.push([key, later[index]]);
805
- });
806
- const present = new Set(next.keys);
807
- const removed = previous.keys.filter((key) => !present.has(key));
808
- const moved = reordered(previous.keys, next.keys, present);
809
- const covered = !deepEquals(before.coverage, after.coverage);
810
- const framing = reframed(before, after);
811
- if (changed.length === 0 && removed.length === 0 && !moved && !covered && framing === null) {
812
- return null;
813
- }
814
- return {
815
- changed,
816
- removed,
817
- order: moved ? next.keys : null,
818
- ...(covered ? { coverage: after.coverage } : {}),
819
- ...framing,
820
- };
821
- }
822
- function rowAt(rows, index) {
823
- return 'groups' in rows ? rows.groups[index] : rows.documents[index];
824
- }