@brass-build/client 0.4.1 → 0.5.0

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 (323) hide show
  1. package/AGENTS.md +124 -45
  2. package/CHANGELOG.md +80 -4
  3. package/README.md +666 -179
  4. package/dist/api-fetch.d.ts +8 -0
  5. package/dist/api-fetch.d.ts.map +1 -1
  6. package/dist/api-fetch.js +35 -8
  7. package/dist/api-fetch.js.map +1 -1
  8. package/dist/batched-get.d.ts +11 -0
  9. package/dist/batched-get.d.ts.map +1 -0
  10. package/dist/batched-get.js +92 -0
  11. package/dist/batched-get.js.map +1 -0
  12. package/dist/call-service.d.ts +4 -0
  13. package/dist/call-service.d.ts.map +1 -1
  14. package/dist/call-service.js +66 -3
  15. package/dist/call-service.js.map +1 -1
  16. package/dist/client.d.ts +48 -2
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +918 -115
  19. package/dist/client.js.map +1 -1
  20. package/dist/document-checkpoints.d.ts +25 -2
  21. package/dist/document-checkpoints.d.ts.map +1 -1
  22. package/dist/document-checkpoints.js +258 -61
  23. package/dist/document-checkpoints.js.map +1 -1
  24. package/dist/document-commands.d.ts.map +1 -1
  25. package/dist/document-commands.js +5 -3
  26. package/dist/document-commands.js.map +1 -1
  27. package/dist/document-contents.d.ts +10 -0
  28. package/dist/document-contents.d.ts.map +1 -1
  29. package/dist/document-contents.js +23 -1
  30. package/dist/document-contents.js.map +1 -1
  31. package/dist/document-set-subscription.d.ts +56 -0
  32. package/dist/document-set-subscription.d.ts.map +1 -0
  33. package/dist/document-set-subscription.js +240 -0
  34. package/dist/document-set-subscription.js.map +1 -0
  35. package/dist/document-signals.d.ts +6 -0
  36. package/dist/document-signals.d.ts.map +1 -1
  37. package/dist/document-signals.js +31 -1
  38. package/dist/document-signals.js.map +1 -1
  39. package/dist/document-streams.d.ts +36 -2
  40. package/dist/document-streams.d.ts.map +1 -1
  41. package/dist/document-streams.js +69 -18
  42. package/dist/document-streams.js.map +1 -1
  43. package/dist/document-thumbnail-capture.d.ts +12 -2
  44. package/dist/document-thumbnail-capture.d.ts.map +1 -1
  45. package/dist/document-thumbnail-capture.js +103 -27
  46. package/dist/document-thumbnail-capture.js.map +1 -1
  47. package/dist/documents-namespace.d.ts +92 -10
  48. package/dist/documents-namespace.d.ts.map +1 -1
  49. package/dist/documents-namespace.js +285 -39
  50. package/dist/documents-namespace.js.map +1 -1
  51. package/dist/documents.d.ts +173 -8
  52. package/dist/documents.d.ts.map +1 -1
  53. package/dist/documents.js +1778 -310
  54. package/dist/documents.js.map +1 -1
  55. package/dist/errors.d.ts +3 -3
  56. package/dist/errors.d.ts.map +1 -1
  57. package/dist/errors.js.map +1 -1
  58. package/dist/fetch-retry.d.ts +1 -0
  59. package/dist/fetch-retry.d.ts.map +1 -1
  60. package/dist/fetch-retry.js +2 -0
  61. package/dist/fetch-retry.js.map +1 -1
  62. package/dist/file-choice.d.ts +2 -0
  63. package/dist/file-choice.d.ts.map +1 -0
  64. package/dist/file-choice.js +27 -0
  65. package/dist/file-choice.js.map +1 -0
  66. package/dist/guest-link.d.ts +18 -1
  67. package/dist/guest-link.d.ts.map +1 -1
  68. package/dist/guest-link.js +329 -1
  69. package/dist/guest-link.js.map +1 -1
  70. package/dist/handle-types.d.ts +67 -5
  71. package/dist/handle-types.d.ts.map +1 -1
  72. package/dist/handles.d.ts +15 -19
  73. package/dist/handles.d.ts.map +1 -1
  74. package/dist/handles.js +231 -76
  75. package/dist/handles.js.map +1 -1
  76. package/dist/hosted-ui.d.ts +61 -0
  77. package/dist/hosted-ui.d.ts.map +1 -1
  78. package/dist/hosted-ui.js +94 -42
  79. package/dist/hosted-ui.js.map +1 -1
  80. package/dist/import-contract.d.ts +74 -0
  81. package/dist/import-contract.d.ts.map +1 -0
  82. package/dist/import-contract.js +163 -0
  83. package/dist/import-contract.js.map +1 -0
  84. package/dist/import-guest.d.ts +9 -0
  85. package/dist/import-guest.d.ts.map +1 -0
  86. package/dist/import-guest.js +155 -0
  87. package/dist/import-guest.js.map +1 -0
  88. package/dist/import-report.d.ts +17 -0
  89. package/dist/import-report.d.ts.map +1 -0
  90. package/dist/import-report.js +7 -0
  91. package/dist/import-report.js.map +1 -0
  92. package/dist/importer-wait.d.ts +2 -0
  93. package/dist/importer-wait.d.ts.map +1 -0
  94. package/dist/importer-wait.js +5 -0
  95. package/dist/importer-wait.js.map +1 -0
  96. package/dist/importer.d.ts +18 -4
  97. package/dist/importer.d.ts.map +1 -1
  98. package/dist/importer.js +322 -105
  99. package/dist/importer.js.map +1 -1
  100. package/dist/in-development.d.ts +2 -0
  101. package/dist/in-development.d.ts.map +1 -0
  102. package/dist/in-development.js +10 -0
  103. package/dist/in-development.js.map +1 -0
  104. package/dist/index.d.ts +16 -8
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +24 -8
  107. package/dist/index.js.map +1 -1
  108. package/dist/init-keys.d.ts +1 -1
  109. package/dist/init-keys.d.ts.map +1 -1
  110. package/dist/init-keys.js +6 -1
  111. package/dist/init-keys.js.map +1 -1
  112. package/dist/input-documents.d.ts +67 -0
  113. package/dist/input-documents.d.ts.map +1 -0
  114. package/dist/input-documents.js +693 -0
  115. package/dist/input-documents.js.map +1 -0
  116. package/dist/inputs-status.d.ts +80 -0
  117. package/dist/inputs-status.d.ts.map +1 -0
  118. package/dist/inputs-status.js +460 -0
  119. package/dist/inputs-status.js.map +1 -0
  120. package/dist/inputs.d.ts +2 -0
  121. package/dist/inputs.d.ts.map +1 -0
  122. package/dist/inputs.js +793 -0
  123. package/dist/inputs.js.map +1 -0
  124. package/dist/internal.d.ts +6 -1
  125. package/dist/internal.d.ts.map +1 -1
  126. package/dist/internal.js +4 -1
  127. package/dist/internal.js.map +1 -1
  128. package/dist/join-content.d.ts +33 -0
  129. package/dist/join-content.d.ts.map +1 -0
  130. package/dist/join-content.js +114 -0
  131. package/dist/join-content.js.map +1 -0
  132. package/dist/join-stamp.d.ts +3 -0
  133. package/dist/join-stamp.d.ts.map +1 -0
  134. package/dist/join-stamp.js +12 -0
  135. package/dist/join-stamp.js.map +1 -0
  136. package/dist/manifest-drift.d.ts +9 -0
  137. package/dist/manifest-drift.d.ts.map +1 -0
  138. package/dist/manifest-drift.js +46 -0
  139. package/dist/manifest-drift.js.map +1 -0
  140. package/dist/open-document.d.ts +109 -2
  141. package/dist/open-document.d.ts.map +1 -1
  142. package/dist/open-document.js +1822 -811
  143. package/dist/open-document.js.map +1 -1
  144. package/dist/page-restore.d.ts +12 -0
  145. package/dist/page-restore.d.ts.map +1 -0
  146. package/dist/page-restore.js +23 -0
  147. package/dist/page-restore.js.map +1 -0
  148. package/dist/placement.d.ts +13 -0
  149. package/dist/placement.d.ts.map +1 -0
  150. package/dist/placement.js +34 -0
  151. package/dist/placement.js.map +1 -0
  152. package/dist/presence.d.ts +1 -0
  153. package/dist/presence.d.ts.map +1 -1
  154. package/dist/presence.js +16 -4
  155. package/dist/presence.js.map +1 -1
  156. package/dist/read-only-document.d.ts +87 -0
  157. package/dist/read-only-document.d.ts.map +1 -0
  158. package/dist/read-only-document.js +4 -0
  159. package/dist/read-only-document.js.map +1 -0
  160. package/dist/record-paging.d.ts +63 -6
  161. package/dist/record-paging.d.ts.map +1 -1
  162. package/dist/record-paging.js +122 -29
  163. package/dist/record-paging.js.map +1 -1
  164. package/dist/references.d.ts +40 -0
  165. package/dist/references.d.ts.map +1 -0
  166. package/dist/references.js +135 -0
  167. package/dist/references.js.map +1 -0
  168. package/dist/request-lane.d.ts +5 -0
  169. package/dist/request-lane.d.ts.map +1 -0
  170. package/dist/request-lane.js +48 -0
  171. package/dist/request-lane.js.map +1 -0
  172. package/dist/sealed-arrow.d.ts +170 -0
  173. package/dist/sealed-arrow.d.ts.map +1 -0
  174. package/dist/sealed-arrow.js +769 -0
  175. package/dist/sealed-arrow.js.map +1 -0
  176. package/dist/sealed-cache.d.ts +21 -0
  177. package/dist/sealed-cache.d.ts.map +1 -0
  178. package/dist/sealed-cache.js +247 -0
  179. package/dist/sealed-cache.js.map +1 -0
  180. package/dist/sealed-encode.d.ts +87 -0
  181. package/dist/sealed-encode.d.ts.map +1 -0
  182. package/dist/sealed-encode.js +876 -0
  183. package/dist/sealed-encode.js.map +1 -0
  184. package/dist/sealed-handles.d.ts +45 -0
  185. package/dist/sealed-handles.d.ts.map +1 -0
  186. package/dist/sealed-handles.js +408 -0
  187. package/dist/sealed-handles.js.map +1 -0
  188. package/dist/sealed-store.d.ts +242 -0
  189. package/dist/sealed-store.d.ts.map +1 -0
  190. package/dist/sealed-store.js +1155 -0
  191. package/dist/sealed-store.js.map +1 -0
  192. package/dist/serializer.d.ts +6 -15
  193. package/dist/serializer.d.ts.map +1 -1
  194. package/dist/session-toolbar.d.ts +20 -5
  195. package/dist/session-toolbar.d.ts.map +1 -1
  196. package/dist/session-toolbar.js +419 -67
  197. package/dist/session-toolbar.js.map +1 -1
  198. package/dist/session.d.ts +38 -1
  199. package/dist/session.d.ts.map +1 -1
  200. package/dist/session.js +562 -79
  201. package/dist/session.js.map +1 -1
  202. package/dist/sha256.d.ts +3 -0
  203. package/dist/sha256.d.ts.map +1 -0
  204. package/dist/sha256.js +74 -0
  205. package/dist/sha256.js.map +1 -0
  206. package/dist/stable-handles.d.ts +19 -0
  207. package/dist/stable-handles.d.ts.map +1 -0
  208. package/dist/stable-handles.js +193 -0
  209. package/dist/stable-handles.js.map +1 -0
  210. package/dist/staged-seal.d.ts +2 -0
  211. package/dist/staged-seal.d.ts.map +1 -0
  212. package/dist/staged-seal.js +76 -0
  213. package/dist/staged-seal.js.map +1 -0
  214. package/dist/subscriber-delivery.d.ts +8 -0
  215. package/dist/subscriber-delivery.d.ts.map +1 -0
  216. package/dist/subscriber-delivery.js +31 -0
  217. package/dist/subscriber-delivery.js.map +1 -0
  218. package/dist/tail-op-import.d.ts +10 -0
  219. package/dist/tail-op-import.d.ts.map +1 -0
  220. package/dist/tail-op-import.js +33 -0
  221. package/dist/tail-op-import.js.map +1 -0
  222. package/dist/topic-lifecycle.d.ts +6 -0
  223. package/dist/topic-lifecycle.d.ts.map +1 -1
  224. package/dist/topic-lifecycle.js +32 -2
  225. package/dist/topic-lifecycle.js.map +1 -1
  226. package/dist/trial-replace-dialog.d.ts +10 -0
  227. package/dist/trial-replace-dialog.d.ts.map +1 -0
  228. package/dist/trial-replace-dialog.js +153 -0
  229. package/dist/trial-replace-dialog.js.map +1 -0
  230. package/dist/types.d.ts +8 -1
  231. package/dist/types.d.ts.map +1 -1
  232. package/dist/undo.d.ts +60 -5
  233. package/dist/undo.d.ts.map +1 -1
  234. package/dist/undo.js +344 -75
  235. package/dist/undo.js.map +1 -1
  236. package/dist/version-bar.d.ts +1 -0
  237. package/dist/version-bar.d.ts.map +1 -1
  238. package/dist/version-bar.js +2 -1
  239. package/dist/version-bar.js.map +1 -1
  240. package/dist/version.d.ts +2 -2
  241. package/dist/version.js +1 -1
  242. package/dist/ws-client.d.ts +21 -0
  243. package/dist/ws-client.d.ts.map +1 -1
  244. package/dist/ws-client.js +192 -8
  245. package/dist/ws-client.js.map +1 -1
  246. package/dist/ws-frame-limit.d.ts +1 -0
  247. package/dist/ws-frame-limit.d.ts.map +1 -1
  248. package/dist/ws-frame-limit.js.map +1 -1
  249. package/docs/app-manifest.md +121 -17
  250. package/docs/custom-chrome.md +24 -16
  251. package/docs/hosted-ui-advanced.md +38 -6
  252. package/docs/imported-documents.md +104 -51
  253. package/docs/presence.md +16 -4
  254. package/docs/schemas.md +8 -5
  255. package/docs/services.md +6 -6
  256. package/docs/streams.md +139 -150
  257. package/docs/text-fields.md +26 -19
  258. package/package.json +5 -2
  259. package/src/api-fetch.ts +53 -3
  260. package/src/auth-flow.ts +1 -1
  261. package/src/batched-get.ts +117 -0
  262. package/src/call-service.ts +78 -3
  263. package/src/client.ts +1022 -112
  264. package/src/document-checkpoints.ts +307 -65
  265. package/src/document-commands.ts +5 -5
  266. package/src/document-contents.ts +27 -1
  267. package/src/document-set-subscription.ts +274 -0
  268. package/src/document-signals.ts +47 -5
  269. package/src/document-streams.ts +85 -16
  270. package/src/document-thumbnail-capture.ts +118 -32
  271. package/src/documents-namespace.ts +539 -84
  272. package/src/documents.ts +2017 -348
  273. package/src/errors.ts +17 -6
  274. package/src/fetch-retry.ts +5 -0
  275. package/src/file-choice.ts +26 -0
  276. package/src/guest-link.ts +362 -1
  277. package/src/handle-types.ts +73 -47
  278. package/src/handles.ts +253 -83
  279. package/src/hosted-ui.ts +211 -50
  280. package/src/import-contract.ts +227 -0
  281. package/src/import-guest.ts +193 -0
  282. package/src/import-report.ts +24 -0
  283. package/src/importer-wait.ts +4 -0
  284. package/src/importer.ts +386 -131
  285. package/src/in-development.ts +10 -0
  286. package/src/index.ts +76 -16
  287. package/src/init-keys.ts +6 -1
  288. package/src/input-documents.ts +819 -0
  289. package/src/inputs-status.ts +598 -0
  290. package/src/inputs.ts +1090 -0
  291. package/src/internal.ts +7 -0
  292. package/src/join-content.ts +135 -0
  293. package/src/join-stamp.ts +12 -0
  294. package/src/manifest-drift.ts +54 -0
  295. package/src/open-document.ts +2346 -930
  296. package/src/page-restore.ts +38 -0
  297. package/src/placement.ts +54 -0
  298. package/src/presence.ts +21 -5
  299. package/src/read-only-document.ts +133 -0
  300. package/src/record-paging.ts +147 -25
  301. package/src/references.ts +207 -0
  302. package/src/request-lane.ts +59 -0
  303. package/src/sealed-arrow.ts +843 -0
  304. package/src/sealed-cache.ts +267 -0
  305. package/src/sealed-encode.ts +1015 -0
  306. package/src/sealed-handles.ts +486 -0
  307. package/src/sealed-store.ts +1330 -0
  308. package/src/serializer.ts +8 -20
  309. package/src/session-toolbar.ts +463 -72
  310. package/src/session.ts +740 -99
  311. package/src/sha256.ts +65 -0
  312. package/src/stable-handles.ts +235 -0
  313. package/src/staged-seal.ts +90 -0
  314. package/src/subscriber-delivery.ts +37 -0
  315. package/src/tail-op-import.ts +30 -0
  316. package/src/topic-lifecycle.ts +38 -2
  317. package/src/trial-replace-dialog.ts +163 -0
  318. package/src/types.ts +6 -6
  319. package/src/undo.ts +386 -73
  320. package/src/version-bar.ts +5 -1
  321. package/src/version.ts +1 -1
  322. package/src/ws-client.ts +208 -16
  323. package/src/ws-frame-limit.ts +1 -0
@@ -0,0 +1,769 @@
1
+ // Frame 4's reader: a stream's maps as typed Arrow tables, inferred from the
2
+ // values alone by the platform's encoder, compressed with the rest of the
3
+ // stream as one ZSTD frame.
4
+ //
5
+ // A value sits in a slot, and a slot holds one or more variants. A variant is
6
+ // a JSON kind, and for an object its ordered key list plus a slot per field,
7
+ // so values that differ in kind or key set sit side by side rather than in one
8
+ // widened column. A slot of several variants carries a `t` column naming each
9
+ // row's variant.
10
+ //
11
+ // null no column
12
+ // bool uint8, or a constant in the schema
13
+ // num int32 where every value is one, else float64; or a constant
14
+ // str dictionary utf8, or a constant, or (`derive`) a code into
15
+ // rules that rebuild the text from a sibling number field
16
+ // tuple a struct of position slots (one array length)
17
+ // list a list of one item slot
18
+ // obj a struct of field slots
19
+ // json JSON text, where no other variant can carry the value
20
+ //
21
+ // A map is one or more tables. Each holds its rows' keys, their positions in
22
+ // the map as gaps from the row before, and the root slot, so the reader puts
23
+ // every entry back at its position and the map's order is its own.
24
+ //
25
+ // What a read returns is what `JSON.parse` of the value's JSON text returns:
26
+ // the same keys in the same order. Objects are built by cloning a per-variant
27
+ // template; no generated code runs, which a page whose CSP withholds
28
+ // `unsafe-eval` requires.
29
+ //
30
+ // Nothing here is exported from the package. Arrow is loaded only when a
31
+ // frame-4 stream is opened (`loadSealedCodec` in `sealed-store.ts`).
32
+ import { DictionaryBatch } from 'apache-arrow/fb/dictionary-batch';
33
+ import { Footer } from 'apache-arrow/fb/footer';
34
+ import { Message } from 'apache-arrow/fb/message';
35
+ import { MessageHeader } from 'apache-arrow/fb/message-header';
36
+ import { RecordBatch } from 'apache-arrow/fb/record-batch';
37
+ import { ByteBuffer } from 'flatbuffers';
38
+ /** The derived-string code for a row whose text no rule rebuilds. */
39
+ export const HELD = 255;
40
+ /** The table metadata's key in an IPC file's schema metadata. */
41
+ export const TABLE_META_KEY = 'brass:table';
42
+ /** Whether a variant stores a column. */
43
+ export function variantStored(v) {
44
+ switch (v.k) {
45
+ case 'null':
46
+ return false;
47
+ case 'bool':
48
+ case 'num':
49
+ case 'str':
50
+ return v.c === undefined;
51
+ }
52
+ return true;
53
+ }
54
+ // --- parts ---------------------------------------------------------------
55
+ // Each row decodes on its own, so a decoder that strips a leading BOM would
56
+ // take U+FEFF off the start of every value that begins with one.
57
+ const utf8Decoder = new TextDecoder('utf-8', { ignoreBOM: true });
58
+ /** Named parts behind a JSON table of names and lengths. */
59
+ export function unpackParts(bytes) {
60
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
61
+ const headLength = view.getUint32(0, true);
62
+ const table = JSON.parse(utf8Decoder.decode(bytes.subarray(4, 4 + headLength)));
63
+ let at = 4 + headLength;
64
+ return table.map(([name, length]) => {
65
+ const part = bytes.subarray(at, at + length);
66
+ at += length;
67
+ if (part.byteLength !== length)
68
+ throw new RangeError(`part ${name} is truncated`);
69
+ return [name, part];
70
+ });
71
+ }
72
+ // --- checking ------------------------------------------------------------
73
+ const ARROW_MAGIC = [0x41, 0x52, 0x52, 0x4f, 0x57, 0x31];
74
+ /** Throws unless `count` items of `stride` bytes fit in the buffer. */
75
+ function fits(count, stride, bb) {
76
+ if (!(count >= 0 && count * stride <= bb.capacity())) {
77
+ throw new RangeError('an IPC vector runs past its bytes');
78
+ }
79
+ }
80
+ function checkField(f, bb, depth, budget) {
81
+ if (depth > 64 || (budget.left -= 1) < 0)
82
+ throw new RangeError('an IPC schema nests too deep');
83
+ fits(f.childrenLength(), 4, bb);
84
+ fits(f.customMetadataLength(), 4, bb);
85
+ for (let i = 0; i < f.childrenLength(); i += 1) {
86
+ const child = f.children(i);
87
+ if (child === null)
88
+ throw new RangeError('an IPC field is missing');
89
+ checkField(child, bb, depth + 1, budget);
90
+ }
91
+ }
92
+ function checkSchema(s, bb) {
93
+ fits(s.fieldsLength(), 4, bb);
94
+ fits(s.customMetadataLength(), 4, bb);
95
+ fits(s.featuresLength(), 8, bb);
96
+ const budget = { left: bb.capacity() >> 2 };
97
+ for (let i = 0; i < s.fieldsLength(); i += 1) {
98
+ const field = s.fields(i);
99
+ if (field === null)
100
+ throw new RangeError('an IPC field is missing');
101
+ checkField(field, bb, 0, budget);
102
+ }
103
+ }
104
+ function checkBatch(rb, bb) {
105
+ fits(rb.nodesLength(), 16, bb);
106
+ fits(rb.buffersLength(), 16, bb);
107
+ fits(rb.variadicBufferCountsLength(), 8, bb);
108
+ }
109
+ /**
110
+ * Throws unless an Arrow IPC file's footer and every message it points at
111
+ * stay inside the file. Arrow reads a file by its own offsets and vector
112
+ * lengths, so a footer block naming a message of the wrong kind makes its
113
+ * reader loop, and a declared length makes it allocate that much; both are
114
+ * held to the bytes here before Arrow reads anything.
115
+ */
116
+ export function checkIpcFile(bytes) {
117
+ const n = bytes.byteLength;
118
+ if (n < 22)
119
+ throw new RangeError('an IPC file is truncated');
120
+ for (let i = 0; i < ARROW_MAGIC.length; i += 1) {
121
+ if (bytes[i] !== ARROW_MAGIC[i] || bytes[n - 6 + i] !== ARROW_MAGIC[i]) {
122
+ throw new RangeError('an IPC file lacks its magic');
123
+ }
124
+ }
125
+ const view = new DataView(bytes.buffer, bytes.byteOffset, n);
126
+ const footerLength = view.getInt32(n - 10, true);
127
+ if (!(footerLength > 0 && footerLength <= n - 18)) {
128
+ throw new RangeError('an IPC footer runs past its file');
129
+ }
130
+ const bodyEnd = n - 10 - footerLength;
131
+ const fbb = new ByteBuffer(bytes.subarray(bodyEnd, n - 10));
132
+ const footer = Footer.getRootAsFooter(fbb);
133
+ const schema = footer.schema();
134
+ if (schema === null)
135
+ throw new RangeError('an IPC file has no schema');
136
+ checkSchema(schema, fbb);
137
+ fits(footer.recordBatchesLength(), 24, fbb);
138
+ fits(footer.dictionariesLength(), 24, fbb);
139
+ fits(footer.customMetadataLength(), 4, fbb);
140
+ const blocks = [
141
+ [MessageHeader.DictionaryBatch, footer.dictionariesLength(), (i) => footer.dictionaries(i)],
142
+ [MessageHeader.RecordBatch, footer.recordBatchesLength(), (i) => footer.recordBatches(i)],
143
+ ];
144
+ for (const [want, count, blockAt] of blocks) {
145
+ for (let i = 0; i < count; i += 1) {
146
+ const block = blockAt(i);
147
+ if (block === null)
148
+ throw new RangeError('an IPC block is missing');
149
+ const offset = Number(block.offset());
150
+ const metaLength = block.metaDataLength();
151
+ const bodyLength = Number(block.bodyLength());
152
+ if (!(offset >= 8 && metaLength > 8 && bodyLength >= 0 && offset + metaLength + bodyLength <= bodyEnd)) {
153
+ throw new RangeError('an IPC block runs past its file');
154
+ }
155
+ if (view.getInt32(offset, true) !== -1)
156
+ throw new RangeError('an IPC block names no message');
157
+ const length = view.getInt32(offset + 4, true);
158
+ if (!(length > 0 && length <= metaLength - 8)) {
159
+ throw new RangeError('an IPC message runs past its block');
160
+ }
161
+ const mbb = new ByteBuffer(bytes.subarray(offset + 8, offset + 8 + length));
162
+ const message = Message.getRootAsMessage(mbb);
163
+ if (message.headerType() !== want)
164
+ throw new RangeError('an IPC block names the wrong message');
165
+ if (!(Number(message.bodyLength()) <= bodyLength)) {
166
+ throw new RangeError('an IPC message body runs past its block');
167
+ }
168
+ fits(message.customMetadataLength(), 4, mbb);
169
+ const rb = want === MessageHeader.RecordBatch
170
+ ? message.header(new RecordBatch())
171
+ : message.header(new DictionaryBatch())?.data() ?? null;
172
+ if (rb === null)
173
+ throw new RangeError('an IPC message has no batch');
174
+ checkBatch(rb, mbb);
175
+ }
176
+ }
177
+ }
178
+ // Arrow's type ids for the column types a sealed table is written with.
179
+ const TYPE_INT = 2;
180
+ const TYPE_FLOAT = 3;
181
+ const TYPE_UTF8 = 5;
182
+ const TYPE_LIST = 12;
183
+ const TYPE_STRUCT = 13;
184
+ const TYPE_DICTIONARY = -1;
185
+ /**
186
+ * Throws unless a stored table's buffers carry every row it declares. A
187
+ * column's length is the uploader's claim, and the reader allocates and loops
188
+ * on it, so each claim is held to the bytes behind it: a fixed-width column
189
+ * has a value per row, offsets rise and stay inside the bytes or child they
190
+ * index (so no two rows share a range, and decoding every row reads each
191
+ * byte once), a struct's fields are each as long as it, and a dictionary is
192
+ * no longer than the column that indexes it. A table's own struct carries
193
+ * the key, gap and value columns.
194
+ */
195
+ export function checkTableData(data) {
196
+ if (data.type.typeId !== TYPE_STRUCT || data.children.length !== 3) {
197
+ throw new RangeError('a table is not a key, gap and value struct');
198
+ }
199
+ checkData(data);
200
+ }
201
+ function checkData(d) {
202
+ const n = d.length;
203
+ if (d.offset !== 0 || !(n >= 0))
204
+ throw new RangeError('a column starts past its buffer');
205
+ switch (d.type.typeId) {
206
+ case TYPE_INT:
207
+ case TYPE_FLOAT:
208
+ if (d.values.length < n)
209
+ throw new RangeError('a column is shorter than its rows');
210
+ return;
211
+ case TYPE_UTF8:
212
+ checkOffsets(d.valueOffsets, n, d.values.length);
213
+ return;
214
+ case TYPE_LIST: {
215
+ const child = d.children[0];
216
+ if (child === undefined)
217
+ throw new RangeError('a list has no items');
218
+ checkOffsets(d.valueOffsets, n, child.length);
219
+ checkData(child);
220
+ return;
221
+ }
222
+ case TYPE_STRUCT:
223
+ for (const child of d.children) {
224
+ if (child.length < n)
225
+ throw new RangeError('a field is shorter than its struct');
226
+ checkData(child);
227
+ }
228
+ return;
229
+ case TYPE_DICTIONARY: {
230
+ const dictionary = d.dictionary;
231
+ if (d.values.length < n || dictionary === undefined || dictionary.length > n) {
232
+ throw new RangeError('a dictionary column does not cover its rows');
233
+ }
234
+ checkIndices(d.values, n, dictionary.length);
235
+ for (const chunk of dictionary.data) {
236
+ if (chunk.type.typeId !== TYPE_UTF8)
237
+ throw new RangeError('a dictionary is not text');
238
+ checkData(chunk);
239
+ }
240
+ return;
241
+ }
242
+ }
243
+ throw new RangeError(`a column has type ${d.type.typeId}, which no sealed table is written with`);
244
+ }
245
+ /** Throws unless each of the first `n` values indexes into `extent`. */
246
+ function checkIndices(values, n, extent) {
247
+ for (let row = 0; row < n; row += 1) {
248
+ const i = values[row];
249
+ if (!(i >= 0 && i < extent))
250
+ throw new RangeError('an index runs past what it indexes');
251
+ }
252
+ }
253
+ function checkOffsets(offsets, n, extent) {
254
+ if (offsets.length < n + 1)
255
+ throw new RangeError('a column is shorter than its rows');
256
+ let last = offsets[0];
257
+ if (last < 0)
258
+ throw new RangeError('an offset is negative');
259
+ for (let row = 1; row <= n; row += 1) {
260
+ const next = offsets[row];
261
+ if (next < last)
262
+ throw new RangeError('offsets fall');
263
+ last = next;
264
+ }
265
+ if (last > extent)
266
+ throw new RangeError('an offset runs past its bytes');
267
+ }
268
+ /** What one decode shares across its tables: each object key list's
269
+ * construction site, and each dictionary decoded once. A `lazy` context
270
+ * decodes a dictionary's entries as reads reach them, which suits a keyed
271
+ * read; a walk reads every entry, and decoding them up front is faster. */
272
+ export class ReadContext {
273
+ lazy;
274
+ shapes = new Map();
275
+ dictionaries = new WeakMap();
276
+ lazyDictionaries = new WeakMap();
277
+ constructor(lazy = false) {
278
+ this.lazy = lazy;
279
+ }
280
+ strings(dictionary) {
281
+ let strings = this.dictionaries.get(dictionary);
282
+ if (strings === undefined) {
283
+ strings = [];
284
+ for (const chunk of dictionary.data) {
285
+ const at = utf8At(chunk);
286
+ for (let row = 0; row < chunk.length; row += 1)
287
+ strings.push(at(row));
288
+ }
289
+ this.dictionaries.set(dictionary, strings);
290
+ }
291
+ return strings;
292
+ }
293
+ lazyStrings(dictionary) {
294
+ let strings = this.lazyDictionaries.get(dictionary);
295
+ if (strings === undefined) {
296
+ strings = new LazyDictionary(dictionary.data);
297
+ this.lazyDictionaries.set(dictionary, strings);
298
+ }
299
+ return strings;
300
+ }
301
+ /** A flag per dictionary entry equal to `s`, or null where none is. */
302
+ matches(dictionary, s) {
303
+ return this.lazy ? this.lazyStrings(dictionary).matches(s) : dictionaryMatches(this.strings(dictionary), s);
304
+ }
305
+ shapeId(keys) {
306
+ const sig = keys.join('\u0000');
307
+ let id = this.shapes.get(sig);
308
+ if (id === undefined) {
309
+ id = this.shapes.size;
310
+ this.shapes.set(sig, id);
311
+ }
312
+ return id;
313
+ }
314
+ }
315
+ /** A dictionary whose entries are decoded on first read and kept. */
316
+ export class LazyDictionary {
317
+ chunks;
318
+ length;
319
+ decoded;
320
+ /** Each chunk's first entry. */
321
+ starts = [];
322
+ constructor(chunks) {
323
+ this.chunks = chunks;
324
+ let length = 0;
325
+ for (const chunk of chunks) {
326
+ this.starts.push(length);
327
+ length += chunk.length;
328
+ }
329
+ this.length = length;
330
+ this.decoded = Array.from({ length });
331
+ }
332
+ at(i) {
333
+ let s = this.decoded[i];
334
+ if (s === undefined) {
335
+ let c = this.chunks.length - 1;
336
+ while (c > 0 && this.starts[c] > i)
337
+ c -= 1;
338
+ const chunk = this.chunks[c];
339
+ const row = i - this.starts[c];
340
+ const offsets = chunk.valueOffsets;
341
+ s = utf8Decoder.decode(chunk.values.subarray(offsets[row], offsets[row + 1]));
342
+ this.decoded[i] = s;
343
+ }
344
+ return s;
345
+ }
346
+ /** A flag per entry equal to `s`, found by comparing bytes, or null where
347
+ * none is. */
348
+ matches(s) {
349
+ // An entry reads with replacement characters where its bytes are not
350
+ // UTF-8, so a wanted string carrying one is compared as text.
351
+ if (s.includes('\uFFFD'))
352
+ return dictionaryMatches(Array.from({ length: this.length }, (_, i) => this.at(i)), s);
353
+ // Every entry decodes well formed, so a string that is not equals none.
354
+ if (!wellFormed(s))
355
+ return null;
356
+ const want = utf8Encoder.encode(s);
357
+ const length = want.length;
358
+ let flags = null;
359
+ this.chunks.forEach((chunk, c) => {
360
+ const bytes = chunk.values;
361
+ const offsets = chunk.valueOffsets;
362
+ for (let row = 0; row < chunk.length; row += 1) {
363
+ const start = offsets[row];
364
+ if (offsets[row + 1] - start !== length)
365
+ continue;
366
+ let i = 0;
367
+ while (i < length && bytes[start + i] === want[i])
368
+ i += 1;
369
+ if (i === length)
370
+ (flags ??= new Uint8Array(this.length))[this.starts[c] + row] = 1;
371
+ }
372
+ });
373
+ return flags;
374
+ }
375
+ }
376
+ function utf8At(d) {
377
+ const bytes = d.values;
378
+ const offsets = d.valueOffsets;
379
+ return (row) => utf8Decoder.decode(bytes.subarray(offsets[row], offsets[row + 1]));
380
+ }
381
+ // Keys are compared by their bytes on a keyed read, so a key whose bytes are
382
+ // not UTF-8 is refused rather than read with replacement characters.
383
+ const keyDecoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
384
+ /**
385
+ * A table's keys as text, row by row. Each key reads only in the form the
386
+ * encoder writes it (a non-negative integer id, a separator that falls after
387
+ * the first half, UTF-8 text, JSON text as `JSON.stringify` writes it), so a
388
+ * walk and a keyed read (`rowsWithKey`) agree on every key; any other form
389
+ * throws.
390
+ */
391
+ export function keyReader(meta, d, cx) {
392
+ const key = meta.key;
393
+ if ('prefix' in key) {
394
+ const prefix = key.prefix;
395
+ const ids = d.values;
396
+ if (typeof prefix !== 'string')
397
+ throw new RangeError('a key prefix is not text');
398
+ for (let row = 0; row < d.length; row += 1) {
399
+ const id = ids[row];
400
+ if (!(Number.isInteger(id) && id >= 0))
401
+ throw new RangeError('a key id is not a whole number');
402
+ }
403
+ return (row) => prefix + String(ids[row]);
404
+ }
405
+ if ('split' in key) {
406
+ const [a, b] = d.children;
407
+ if (cx.lazy)
408
+ return lazySplitKeyReader(key.split, a, b, cx);
409
+ const as = cx.strings(a.dictionary);
410
+ const bs = cx.strings(b.dictionary);
411
+ const ai = a.values;
412
+ const bi = b.values;
413
+ const sep = key.split;
414
+ if (typeof sep !== 'string' || sep === '' || as.some((s) => (s + sep).indexOf(sep) !== s.length)) {
415
+ throw new RangeError('a key separator does not split its keys');
416
+ }
417
+ return (row) => as[ai[row]] + sep + bs[bi[row]];
418
+ }
419
+ const bytes = d.values;
420
+ const offsets = d.valueOffsets;
421
+ const at = (row) => keyDecoder.decode(bytes.subarray(offsets[row], offsets[row + 1]));
422
+ if ('json' in key) {
423
+ return (row) => {
424
+ const text = at(row);
425
+ const k = JSON.parse(text);
426
+ if (typeof k !== 'string' || JSON.stringify(k) !== text)
427
+ throw new RangeError('a JSON key is not as written');
428
+ return k;
429
+ };
430
+ }
431
+ return at;
432
+ }
433
+ /** Split keys read through lazy dictionaries. Each first half is checked
434
+ * against the separator when a read first reaches it. */
435
+ function lazySplitKeyReader(sep, a, b, cx) {
436
+ if (typeof sep !== 'string' || sep === '')
437
+ throw new RangeError('a key separator does not split its keys');
438
+ const as = cx.lazyStrings(a.dictionary);
439
+ const bs = cx.lazyStrings(b.dictionary);
440
+ const ai = a.values;
441
+ const bi = b.values;
442
+ const checked = new Uint8Array(as.length);
443
+ return (row) => {
444
+ const i = ai[row];
445
+ const first = as.at(i);
446
+ if (checked[i] === 0) {
447
+ if ((first + sep).indexOf(sep) !== first.length)
448
+ throw new RangeError('a key separator does not split its keys');
449
+ checked[i] = 1;
450
+ }
451
+ return first + sep + bs.at(bi[row]);
452
+ };
453
+ }
454
+ const utf8Encoder = new TextEncoder();
455
+ /** Whether a string is well-formed UTF-16, which UTF-8 can carry. */
456
+ const wellFormed = (s) => s.isWellFormed();
457
+ /**
458
+ * The rows of a table whose key reads as `key`, found from the key column
459
+ * alone: an id compared as a number, a dictionary half by its index, text by
460
+ * its bytes. Nothing is decoded for a row that does not match.
461
+ */
462
+ export function rowsWithKey(meta, d, key, cx) {
463
+ const rows = [];
464
+ const n = d.length;
465
+ const k = meta.key;
466
+ if ('prefix' in k) {
467
+ if (!key.startsWith(k.prefix))
468
+ return rows;
469
+ const digits = key.slice(k.prefix.length);
470
+ const id = Number(digits);
471
+ if (digits === '' || String(id) !== digits)
472
+ return rows;
473
+ const ids = d.values;
474
+ for (let row = 0; row < n; row += 1)
475
+ if (ids[row] === id)
476
+ rows.push(row);
477
+ return rows;
478
+ }
479
+ if ('split' in k) {
480
+ const at = key.indexOf(k.split);
481
+ if (at < 0)
482
+ return rows;
483
+ const [a, b] = d.children;
484
+ const inA = cx.matches(a.dictionary, key.slice(0, at));
485
+ const inB = cx.matches(b.dictionary, key.slice(at + k.split.length));
486
+ if (inA === null || inB === null)
487
+ return rows;
488
+ const ai = a.values;
489
+ const bi = b.values;
490
+ for (let row = 0; row < n; row += 1)
491
+ if (inA[ai[row]] === 1 && inB[bi[row]] === 1)
492
+ rows.push(row);
493
+ return rows;
494
+ }
495
+ // Text keys are written well formed, and JSON keys as `JSON.stringify` writes them.
496
+ if ('text' in k && !wellFormed(key))
497
+ return rows;
498
+ const want = utf8Encoder.encode('json' in k ? JSON.stringify(key) : key);
499
+ const bytes = d.values;
500
+ const offsets = d.valueOffsets;
501
+ const length = want.length;
502
+ for (let row = 0; row < n; row += 1) {
503
+ const start = offsets[row];
504
+ if (offsets[row + 1] - start !== length)
505
+ continue;
506
+ let i = 0;
507
+ while (i < length && bytes[start + i] === want[i])
508
+ i += 1;
509
+ if (i === length)
510
+ rows.push(row);
511
+ }
512
+ return rows;
513
+ }
514
+ /** A flag per dictionary entry equal to `s`, or null where none is. */
515
+ function dictionaryMatches(strings, s) {
516
+ let flags = null;
517
+ for (let i = 0; i < strings.length; i += 1) {
518
+ if (strings[i] === s)
519
+ (flags ??= new Uint8Array(strings.length))[i] = 1;
520
+ }
521
+ return flags;
522
+ }
523
+ export function readSlot(slot, d, cx) {
524
+ if (d.offset !== 0)
525
+ throw new RangeError('a slot column starts past its buffer');
526
+ let c = 0;
527
+ const tags = slot.v.length > 1 ? d.children[c++].values : null;
528
+ const readers = slot.v.map((v) => readVariant(v, variantStored(v) ? d.children[c++] : null, cx));
529
+ if (tags === null)
530
+ return readers[0];
531
+ checkIndices(tags, d.length, readers.length);
532
+ return (row) => readers[tags[row]](row);
533
+ }
534
+ function readVariant(v, d, cx) {
535
+ switch (v.k) {
536
+ case 'null':
537
+ return () => null;
538
+ case 'bool': {
539
+ if (v.c !== undefined) {
540
+ const c = v.c;
541
+ return () => c;
542
+ }
543
+ const values = d.values;
544
+ return (row) => values[row] === 1;
545
+ }
546
+ case 'num': {
547
+ if (v.c !== undefined) {
548
+ const c = v.c;
549
+ return () => c;
550
+ }
551
+ const values = d.values;
552
+ return (row) => values[row];
553
+ }
554
+ case 'str': {
555
+ if (v.c !== undefined) {
556
+ const c = v.c;
557
+ return () => c;
558
+ }
559
+ if (v.derive)
560
+ throw new TypeError('a derived string is read through its object');
561
+ const idx = d.values;
562
+ if (cx.lazy) {
563
+ const lazy = cx.lazyStrings(d.dictionary);
564
+ return (row) => lazy.at(idx[row]);
565
+ }
566
+ const strings = cx.strings(d.dictionary);
567
+ return (row) => strings[idx[row]];
568
+ }
569
+ case 'json': {
570
+ const at = utf8At(d);
571
+ return (row) => JSON.parse(at(row));
572
+ }
573
+ case 'tuple':
574
+ return tupleReader(v.items.map((s, p) => readSlot(s, d.children[p], cx)));
575
+ case 'list': {
576
+ const offsets = d.valueOffsets;
577
+ const item = readSlot(v.item, d.children[0], cx);
578
+ return (row) => {
579
+ const out = [];
580
+ for (let j = offsets[row]; j < offsets[row + 1]; j += 1)
581
+ out.push(item(j));
582
+ return out;
583
+ };
584
+ }
585
+ case 'obj': {
586
+ // The encoder writes an object whose keys assign onto `{}` in order as
587
+ // JSON text instead, so a field named `__proto__` is not a table's.
588
+ if (v.keys.includes('__proto__') || v.keys.length !== v.fields.length) {
589
+ throw new RangeError('an object variant names a key no table carries');
590
+ }
591
+ // Fields every row agrees on ride in the template the object is cloned
592
+ // from; the rest are read per row.
593
+ const template = {};
594
+ const varying = [];
595
+ const readers = [];
596
+ v.fields.forEach((s, f) => {
597
+ const key = v.keys[f];
598
+ const only = s.v.length === 1 ? s.v[0] : null;
599
+ if (only?.k === 'null')
600
+ template[key] = null;
601
+ else if ((only?.k === 'num' || only?.k === 'str' || only?.k === 'bool') &&
602
+ only.c !== undefined) {
603
+ template[key] = only.c;
604
+ }
605
+ else {
606
+ template[key] = null;
607
+ varying.push(key);
608
+ const derive = only?.k === 'str' ? only.derive : undefined;
609
+ readers.push(derive === undefined
610
+ ? readSlot(s, d.children[f], cx)
611
+ : derivedReader(derive, d.children[f].children[0], d.children[derive.from].children[0].values));
612
+ }
613
+ });
614
+ return objectReader(cx.shapeId(v.keys), template, varying, readers);
615
+ }
616
+ }
617
+ }
618
+ function derivedReader(derive, d, numbers) {
619
+ const codes = d.children[0].values;
620
+ for (let row = 0; row < d.length; row += 1) {
621
+ const code = codes[row];
622
+ if (code !== HELD && !(code >= 0 && code < derive.rules.length)) {
623
+ throw new RangeError('a derived string names no rule');
624
+ }
625
+ }
626
+ const held = utf8At(d.children[1]);
627
+ const upper = derive.rules.map((r) => r[0] === 1);
628
+ const suffix = derive.rules.map((r) => r[1]);
629
+ return (row) => {
630
+ const code = codes[row];
631
+ if (code === HELD)
632
+ return held(row);
633
+ const s = String(numbers[row]);
634
+ return (upper[code] ? s.toUpperCase() : s) + suffix[code];
635
+ };
636
+ }
637
+ // An array literal allocates at its length, where pushing grows the array.
638
+ const TUPLES = [
639
+ () => () => [],
640
+ ([r0]) => (row) => [r0(row)],
641
+ ([r0, r1]) => (row) => [r0(row), r1(row)],
642
+ ([r0, r1, r2]) => (row) => [r0(row), r1(row), r2(row)],
643
+ ([r0, r1, r2, r3]) => (row) => [r0(row), r1(row), r2(row), r3(row)],
644
+ ([r0, r1, r2, r3, r4]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row)],
645
+ ([r0, r1, r2, r3, r4, r5]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row)],
646
+ ([r0, r1, r2, r3, r4, r5, r6]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row)],
647
+ ([r0, r1, r2, r3, r4, r5, r6, r7]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row), r7(row)],
648
+ ([r0, r1, r2, r3, r4, r5, r6, r7, r8]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row), r7(row), r8(row)],
649
+ ([r0, r1, r2, r3, r4, r5, r6, r7, r8, r9]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row), r7(row), r8(row), r9(row)],
650
+ ([r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row), r7(row), r8(row), r9(row), r10(row)],
651
+ ([r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11]) => (row) => [r0(row), r1(row), r2(row), r3(row), r4(row), r5(row), r6(row), r7(row), r8(row), r9(row), r10(row), r11(row)],
652
+ ];
653
+ function tupleReader(rs) {
654
+ const literal = TUPLES[rs.length];
655
+ if (literal !== undefined)
656
+ return literal(rs);
657
+ const n = rs.length;
658
+ return (row) => {
659
+ const out = [];
660
+ for (let p = 0; p < n; p += 1)
661
+ out.push(rs[p](row));
662
+ return out;
663
+ };
664
+ }
665
+ // One construction site per object shape. V8 keeps type feedback per source
666
+ // site, and a site that clones one template and stores one set of keys stays
667
+ // monomorphic, where one shared site sees every shape in the stream and runs
668
+ // at about half the speed. Each array holds distinct copies of one site, by
669
+ // the number of fields a row reads; shape `id` takes copy `id`, and a shape
670
+ // past the copies takes the shared loop.
671
+ const SITES0 = [
672
+ (t) => () => ({ ...t }),
673
+ (t) => () => ({ ...t }),
674
+ (t) => () => ({ ...t }),
675
+ (t) => () => ({ ...t }),
676
+ (t) => () => ({ ...t }),
677
+ (t) => () => ({ ...t }),
678
+ (t) => () => ({ ...t }),
679
+ (t) => () => ({ ...t }),
680
+ (t) => () => ({ ...t }),
681
+ (t) => () => ({ ...t }),
682
+ (t) => () => ({ ...t }),
683
+ (t) => () => ({ ...t }),
684
+ (t) => () => ({ ...t }),
685
+ (t) => () => ({ ...t }),
686
+ (t) => () => ({ ...t }),
687
+ (t) => () => ({ ...t }),
688
+ ];
689
+ const SITES1 = [
690
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
691
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
692
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
693
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
694
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
695
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
696
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
697
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
698
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
699
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
700
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
701
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
702
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
703
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
704
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
705
+ (t, [k0], [r0]) => (row) => { const o = { ...t }; o[k0] = r0(row); return o; },
706
+ ];
707
+ const SITES2 = [
708
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
709
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
710
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
711
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
712
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
713
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
714
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
715
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
716
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
717
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
718
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
719
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
720
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
721
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
722
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
723
+ (t, [k0, k1], [r0, r1]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); return o; },
724
+ ];
725
+ const SITES3 = [
726
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
727
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
728
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
729
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
730
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
731
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
732
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
733
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
734
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
735
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
736
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
737
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
738
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
739
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
740
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
741
+ (t, [k0, k1, k2], [r0, r1, r2]) => (row) => { const o = { ...t }; o[k0] = r0(row); o[k1] = r1(row); o[k2] = r2(row); return o; },
742
+ ];
743
+ const SITES = [SITES0, SITES1, SITES2, SITES3];
744
+ function objectReader(id, template, varying, rs) {
745
+ const site = SITES[varying.length]?.[id];
746
+ if (site !== undefined)
747
+ return site(template, varying, rs);
748
+ const n = varying.length;
749
+ return (row) => {
750
+ const o = { ...template };
751
+ for (let f = 0; f < n; f += 1)
752
+ o[varying[f]] = rs[f](row);
753
+ return o;
754
+ };
755
+ }
756
+ /** A stored table's rows prepared for reading. Positions are absolute, and a
757
+ * table's gap column runs from zero. */
758
+ export function readyTable(meta, data, cx) {
759
+ const [keyCol, gapCol, rootCol] = data.children;
760
+ const positions = new Int32Array(data.length);
761
+ const gaps = gapCol.values;
762
+ let at = 0;
763
+ for (let row = 0; row < data.length; row += 1) {
764
+ at += gaps[row];
765
+ positions[row] = at;
766
+ }
767
+ return { positions, key: keyReader(meta, keyCol, cx), value: readSlot(meta.slot, rootCol, cx) };
768
+ }
769
+ //# sourceMappingURL=sealed-arrow.js.map