@datakable/core 0.0.0-stage → 1.0.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 (551) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +473 -2
  3. package/dist/catalog/codes.cjs +102 -0
  4. package/dist/catalog/codes.cjs.map +1 -0
  5. package/dist/catalog/codes.js +76 -0
  6. package/dist/catalog/codes.js.map +1 -0
  7. package/dist/catalog/index.cjs +49 -0
  8. package/dist/catalog/index.cjs.map +1 -0
  9. package/dist/catalog/index.js +26 -0
  10. package/dist/catalog/index.js.map +1 -0
  11. package/dist/catalog/options.cjs +39 -0
  12. package/dist/catalog/options.cjs.map +1 -0
  13. package/dist/catalog/options.js +13 -0
  14. package/dist/catalog/options.js.map +1 -0
  15. package/dist/catalog/slots.cjs +103 -0
  16. package/dist/catalog/slots.cjs.map +1 -0
  17. package/dist/catalog/slots.js +72 -0
  18. package/dist/catalog/slots.js.map +1 -0
  19. package/dist/catalog/suggest.cjs +43 -0
  20. package/dist/catalog/suggest.cjs.map +1 -0
  21. package/dist/catalog/suggest.js +18 -0
  22. package/dist/catalog/suggest.js.map +1 -0
  23. package/dist/catalog/table-options.cjs +103 -0
  24. package/dist/catalog/table-options.cjs.map +1 -0
  25. package/dist/catalog/table-options.js +78 -0
  26. package/dist/catalog/table-options.js.map +1 -0
  27. package/dist/catalog/validator.cjs +238 -0
  28. package/dist/catalog/validator.cjs.map +1 -0
  29. package/dist/catalog/validator.js +214 -0
  30. package/dist/catalog/validator.js.map +1 -0
  31. package/dist/codes-BKdS9EiO.d.cts +1109 -0
  32. package/dist/codes-BKdS9EiO.d.ts +1109 -0
  33. package/dist/column/column-def.cjs +19 -0
  34. package/dist/column/column-def.cjs.map +1 -0
  35. package/dist/column/column-def.js +1 -0
  36. package/dist/column/column-def.js.map +1 -0
  37. package/dist/column/format.cjs +65 -0
  38. package/dist/column/format.cjs.map +1 -0
  39. package/dist/column/format.js +40 -0
  40. package/dist/column/format.js.map +1 -0
  41. package/dist/column/get-value.cjs +49 -0
  42. package/dist/column/get-value.cjs.map +1 -0
  43. package/dist/column/get-value.js +23 -0
  44. package/dist/column/get-value.js.map +1 -0
  45. package/dist/column/index.cjs +36 -0
  46. package/dist/column/index.cjs.map +1 -0
  47. package/dist/column/index.js +9 -0
  48. package/dist/column/index.js.map +1 -0
  49. package/dist/column/path.cjs +19 -0
  50. package/dist/column/path.cjs.map +1 -0
  51. package/dist/column/path.js +1 -0
  52. package/dist/column/path.js.map +1 -0
  53. package/dist/column-filters.d.cts +88 -0
  54. package/dist/column-filters.d.ts +88 -0
  55. package/dist/diagnostics/build.cjs +185 -0
  56. package/dist/diagnostics/build.cjs.map +1 -0
  57. package/dist/diagnostics/build.js +161 -0
  58. package/dist/diagnostics/build.js.map +1 -0
  59. package/dist/diagnostics/catalog.cjs +76 -0
  60. package/dist/diagnostics/catalog.cjs.map +1 -0
  61. package/dist/diagnostics/catalog.js +45 -0
  62. package/dist/diagnostics/catalog.js.map +1 -0
  63. package/dist/diagnostics/codes.cjs +126 -0
  64. package/dist/diagnostics/codes.cjs.map +1 -0
  65. package/dist/diagnostics/codes.js +100 -0
  66. package/dist/diagnostics/codes.js.map +1 -0
  67. package/dist/diagnostics/console.cjs +78 -0
  68. package/dist/diagnostics/console.cjs.map +1 -0
  69. package/dist/diagnostics/console.js +52 -0
  70. package/dist/diagnostics/console.js.map +1 -0
  71. package/dist/diagnostics/env.cjs +31 -0
  72. package/dist/diagnostics/env.cjs.map +1 -0
  73. package/dist/diagnostics/env.js +6 -0
  74. package/dist/diagnostics/env.js.map +1 -0
  75. package/dist/diagnostics/explain-detail.cjs +84 -0
  76. package/dist/diagnostics/explain-detail.cjs.map +1 -0
  77. package/dist/diagnostics/explain-detail.js +59 -0
  78. package/dist/diagnostics/explain-detail.js.map +1 -0
  79. package/dist/diagnostics/explain-text.cjs +125 -0
  80. package/dist/diagnostics/explain-text.cjs.map +1 -0
  81. package/dist/diagnostics/explain-text.js +99 -0
  82. package/dist/diagnostics/explain-text.js.map +1 -0
  83. package/dist/diagnostics/explain.cjs +188 -0
  84. package/dist/diagnostics/explain.cjs.map +1 -0
  85. package/dist/diagnostics/explain.js +159 -0
  86. package/dist/diagnostics/explain.js.map +1 -0
  87. package/dist/diagnostics/hub.cjs +158 -0
  88. package/dist/diagnostics/hub.cjs.map +1 -0
  89. package/dist/diagnostics/hub.js +137 -0
  90. package/dist/diagnostics/hub.js.map +1 -0
  91. package/dist/diagnostics/index.cjs +86 -0
  92. package/dist/diagnostics/index.cjs.map +1 -0
  93. package/dist/diagnostics/index.js +62 -0
  94. package/dist/diagnostics/index.js.map +1 -0
  95. package/dist/diagnostics/redact.cjs +195 -0
  96. package/dist/diagnostics/redact.cjs.map +1 -0
  97. package/dist/diagnostics/redact.js +160 -0
  98. package/dist/diagnostics/redact.js.map +1 -0
  99. package/dist/diagnostics/ring-buffer.cjs +58 -0
  100. package/dist/diagnostics/ring-buffer.cjs.map +1 -0
  101. package/dist/diagnostics/ring-buffer.js +33 -0
  102. package/dist/diagnostics/ring-buffer.js.map +1 -0
  103. package/dist/diagnostics/safe-json.cjs +99 -0
  104. package/dist/diagnostics/safe-json.cjs.map +1 -0
  105. package/dist/diagnostics/safe-json.js +74 -0
  106. package/dist/diagnostics/safe-json.js.map +1 -0
  107. package/dist/diagnostics/trace-store.cjs +37 -0
  108. package/dist/diagnostics/trace-store.cjs.map +1 -0
  109. package/dist/diagnostics/trace-store.js +11 -0
  110. package/dist/diagnostics/trace-store.js.map +1 -0
  111. package/dist/diagnostics/tracer.cjs +104 -0
  112. package/dist/diagnostics/tracer.cjs.map +1 -0
  113. package/dist/diagnostics/tracer.js +78 -0
  114. package/dist/diagnostics/tracer.js.map +1 -0
  115. package/dist/diagnostics/types.cjs +19 -0
  116. package/dist/diagnostics/types.cjs.map +1 -0
  117. package/dist/diagnostics/types.js +1 -0
  118. package/dist/diagnostics/types.js.map +1 -0
  119. package/dist/explain-DcUZfFh5.d.ts +1028 -0
  120. package/dist/explain-aagaYHcy.d.cts +1028 -0
  121. package/dist/feature/codes.cjs +91 -0
  122. package/dist/feature/codes.cjs.map +1 -0
  123. package/dist/feature/codes.js +65 -0
  124. package/dist/feature/codes.js.map +1 -0
  125. package/dist/feature/define.cjs +47 -0
  126. package/dist/feature/define.cjs.map +1 -0
  127. package/dist/feature/define.js +22 -0
  128. package/dist/feature/define.js.map +1 -0
  129. package/dist/feature/index.cjs +39 -0
  130. package/dist/feature/index.cjs.map +1 -0
  131. package/dist/feature/index.js +11 -0
  132. package/dist/feature/index.js.map +1 -0
  133. package/dist/feature/install.cjs +139 -0
  134. package/dist/feature/install.cjs.map +1 -0
  135. package/dist/feature/install.js +113 -0
  136. package/dist/feature/install.js.map +1 -0
  137. package/dist/feature/order.cjs +57 -0
  138. package/dist/feature/order.cjs.map +1 -0
  139. package/dist/feature/order.js +31 -0
  140. package/dist/feature/order.js.map +1 -0
  141. package/dist/feature/runtime.cjs +43 -0
  142. package/dist/feature/runtime.cjs.map +1 -0
  143. package/dist/feature/runtime.js +17 -0
  144. package/dist/feature/runtime.js.map +1 -0
  145. package/dist/feature/types.cjs +19 -0
  146. package/dist/feature/types.cjs.map +1 -0
  147. package/dist/feature/types.js +1 -0
  148. package/dist/feature/types.js.map +1 -0
  149. package/dist/features/column-filters/codes.cjs +115 -0
  150. package/dist/features/column-filters/codes.cjs.map +1 -0
  151. package/dist/features/column-filters/codes.js +88 -0
  152. package/dist/features/column-filters/codes.js.map +1 -0
  153. package/dist/features/column-filters/column-filters.cjs +207 -0
  154. package/dist/features/column-filters/column-filters.cjs.map +1 -0
  155. package/dist/features/column-filters/column-filters.js +188 -0
  156. package/dist/features/column-filters/column-filters.js.map +1 -0
  157. package/dist/features/column-filters/index.cjs +34 -0
  158. package/dist/features/column-filters/index.cjs.map +1 -0
  159. package/dist/features/column-filters/index.js +8 -0
  160. package/dist/features/column-filters/index.js.map +1 -0
  161. package/dist/features/column-filters/match.cjs +195 -0
  162. package/dist/features/column-filters/match.cjs.map +1 -0
  163. package/dist/features/column-filters/match.js +166 -0
  164. package/dist/features/column-filters/match.js.map +1 -0
  165. package/dist/features/column-filters/types.cjs +19 -0
  166. package/dist/features/column-filters/types.cjs.map +1 -0
  167. package/dist/features/column-filters/types.js +1 -0
  168. package/dist/features/column-filters/types.js.map +1 -0
  169. package/dist/features/pagination/codes.cjs +75 -0
  170. package/dist/features/pagination/codes.cjs.map +1 -0
  171. package/dist/features/pagination/codes.js +49 -0
  172. package/dist/features/pagination/codes.js.map +1 -0
  173. package/dist/features/pagination/index.cjs +34 -0
  174. package/dist/features/pagination/index.cjs.map +1 -0
  175. package/dist/features/pagination/index.js +10 -0
  176. package/dist/features/pagination/index.js.map +1 -0
  177. package/dist/features/pagination/pagination.cjs +207 -0
  178. package/dist/features/pagination/pagination.cjs.map +1 -0
  179. package/dist/features/pagination/pagination.js +182 -0
  180. package/dist/features/pagination/pagination.js.map +1 -0
  181. package/dist/features/search/codes.cjs +53 -0
  182. package/dist/features/search/codes.cjs.map +1 -0
  183. package/dist/features/search/codes.js +27 -0
  184. package/dist/features/search/codes.js.map +1 -0
  185. package/dist/features/search/index.cjs +40 -0
  186. package/dist/features/search/index.cjs.map +1 -0
  187. package/dist/features/search/index.js +14 -0
  188. package/dist/features/search/index.js.map +1 -0
  189. package/dist/features/search/search-async-entry.cjs +37 -0
  190. package/dist/features/search/search-async-entry.cjs.map +1 -0
  191. package/dist/features/search/search-async-entry.js +12 -0
  192. package/dist/features/search/search-async-entry.js.map +1 -0
  193. package/dist/features/search/search-engine.cjs +267 -0
  194. package/dist/features/search/search-engine.cjs.map +1 -0
  195. package/dist/features/search/search-engine.js +245 -0
  196. package/dist/features/search/search-engine.js.map +1 -0
  197. package/dist/features/search/search-fn-brand.cjs +37 -0
  198. package/dist/features/search/search-fn-brand.cjs.map +1 -0
  199. package/dist/features/search/search-fn-brand.js +10 -0
  200. package/dist/features/search/search-fn-brand.js.map +1 -0
  201. package/dist/features/search/search-index.cjs +190 -0
  202. package/dist/features/search/search-index.cjs.map +1 -0
  203. package/dist/features/search/search-index.js +163 -0
  204. package/dist/features/search/search-index.js.map +1 -0
  205. package/dist/features/search/search.cjs +334 -0
  206. package/dist/features/search/search.cjs.map +1 -0
  207. package/dist/features/search/search.js +313 -0
  208. package/dist/features/search/search.js.map +1 -0
  209. package/dist/features/search/with-search-fn.cjs +43 -0
  210. package/dist/features/search/with-search-fn.cjs.map +1 -0
  211. package/dist/features/search/with-search-fn.js +18 -0
  212. package/dist/features/search/with-search-fn.js.map +1 -0
  213. package/dist/features/sorting/codes.cjs +73 -0
  214. package/dist/features/sorting/codes.cjs.map +1 -0
  215. package/dist/features/sorting/codes.js +46 -0
  216. package/dist/features/sorting/codes.js.map +1 -0
  217. package/dist/features/sorting/compare.cjs +129 -0
  218. package/dist/features/sorting/compare.cjs.map +1 -0
  219. package/dist/features/sorting/compare.js +100 -0
  220. package/dist/features/sorting/compare.js.map +1 -0
  221. package/dist/features/sorting/index.cjs +41 -0
  222. package/dist/features/sorting/index.cjs.map +1 -0
  223. package/dist/features/sorting/index.js +14 -0
  224. package/dist/features/sorting/index.js.map +1 -0
  225. package/dist/features/sorting/ranks.cjs +112 -0
  226. package/dist/features/sorting/ranks.cjs.map +1 -0
  227. package/dist/features/sorting/ranks.js +87 -0
  228. package/dist/features/sorting/ranks.js.map +1 -0
  229. package/dist/features/sorting/sorting.cjs +446 -0
  230. package/dist/features/sorting/sorting.cjs.map +1 -0
  231. package/dist/features/sorting/sorting.js +433 -0
  232. package/dist/features/sorting/sorting.js.map +1 -0
  233. package/dist/features/sorting/strategy.cjs +123 -0
  234. package/dist/features/sorting/strategy.cjs.map +1 -0
  235. package/dist/features/sorting/strategy.js +93 -0
  236. package/dist/features/sorting/strategy.js.map +1 -0
  237. package/dist/features/validity/codes.cjs +53 -0
  238. package/dist/features/validity/codes.cjs.map +1 -0
  239. package/dist/features/validity/codes.js +27 -0
  240. package/dist/features/validity/codes.js.map +1 -0
  241. package/dist/features/validity/index.cjs +34 -0
  242. package/dist/features/validity/index.cjs.map +1 -0
  243. package/dist/features/validity/index.js +10 -0
  244. package/dist/features/validity/index.js.map +1 -0
  245. package/dist/features/validity/validity.cjs +86 -0
  246. package/dist/features/validity/validity.cjs.map +1 -0
  247. package/dist/features/validity/validity.js +61 -0
  248. package/dist/features/validity/validity.js.map +1 -0
  249. package/dist/index.cjs +92 -0
  250. package/dist/index.cjs.map +1 -0
  251. package/dist/index.d.cts +396 -0
  252. package/dist/index.d.ts +396 -0
  253. package/dist/index.js +45 -0
  254. package/dist/index.js.map +1 -0
  255. package/dist/ingest/cell-issues.cjs +76 -0
  256. package/dist/ingest/cell-issues.cjs.map +1 -0
  257. package/dist/ingest/cell-issues.js +49 -0
  258. package/dist/ingest/cell-issues.js.map +1 -0
  259. package/dist/ingest/data-check-codes.cjs +91 -0
  260. package/dist/ingest/data-check-codes.cjs.map +1 -0
  261. package/dist/ingest/data-check-codes.js +65 -0
  262. package/dist/ingest/data-check-codes.js.map +1 -0
  263. package/dist/ingest/data-checks.cjs +155 -0
  264. package/dist/ingest/data-checks.cjs.map +1 -0
  265. package/dist/ingest/data-checks.js +130 -0
  266. package/dist/ingest/data-checks.js.map +1 -0
  267. package/dist/ingest/derive-columns.cjs +82 -0
  268. package/dist/ingest/derive-columns.cjs.map +1 -0
  269. package/dist/ingest/derive-columns.js +54 -0
  270. package/dist/ingest/derive-columns.js.map +1 -0
  271. package/dist/ingest/row-key-codes.cjs +101 -0
  272. package/dist/ingest/row-key-codes.cjs.map +1 -0
  273. package/dist/ingest/row-key-codes.js +75 -0
  274. package/dist/ingest/row-key-codes.js.map +1 -0
  275. package/dist/ingest/row-key.cjs +161 -0
  276. package/dist/ingest/row-key.cjs.map +1 -0
  277. package/dist/ingest/row-key.js +136 -0
  278. package/dist/ingest/row-key.js.map +1 -0
  279. package/dist/ingest/schema-brand.cjs +31 -0
  280. package/dist/ingest/schema-brand.cjs.map +1 -0
  281. package/dist/ingest/schema-brand.js +6 -0
  282. package/dist/ingest/schema-brand.js.map +1 -0
  283. package/dist/ingest/schema-codes.cjs +101 -0
  284. package/dist/ingest/schema-codes.cjs.map +1 -0
  285. package/dist/ingest/schema-codes.js +75 -0
  286. package/dist/ingest/schema-codes.js.map +1 -0
  287. package/dist/ingest/schema-entry.cjs +42 -0
  288. package/dist/ingest/schema-entry.cjs.map +1 -0
  289. package/dist/ingest/schema-entry.js +16 -0
  290. package/dist/ingest/schema-entry.js.map +1 -0
  291. package/dist/ingest/schema.cjs +213 -0
  292. package/dist/ingest/schema.cjs.map +1 -0
  293. package/dist/ingest/schema.js +186 -0
  294. package/dist/ingest/schema.js.map +1 -0
  295. package/dist/ingest/standard-schema.cjs +19 -0
  296. package/dist/ingest/standard-schema.cjs.map +1 -0
  297. package/dist/ingest/standard-schema.js +1 -0
  298. package/dist/ingest/standard-schema.js.map +1 -0
  299. package/dist/ingest/test-schemas.cjs +73 -0
  300. package/dist/ingest/test-schemas.cjs.map +1 -0
  301. package/dist/ingest/test-schemas.js +46 -0
  302. package/dist/ingest/test-schemas.js.map +1 -0
  303. package/dist/ingest/unique-fields.cjs +87 -0
  304. package/dist/ingest/unique-fields.cjs.map +1 -0
  305. package/dist/ingest/unique-fields.js +62 -0
  306. package/dist/ingest/unique-fields.js.map +1 -0
  307. package/dist/ingest/with-schema.cjs +45 -0
  308. package/dist/ingest/with-schema.cjs.map +1 -0
  309. package/dist/ingest/with-schema.js +20 -0
  310. package/dist/ingest/with-schema.js.map +1 -0
  311. package/dist/intercept/boundary.cjs +116 -0
  312. package/dist/intercept/boundary.cjs.map +1 -0
  313. package/dist/intercept/boundary.js +91 -0
  314. package/dist/intercept/boundary.js.map +1 -0
  315. package/dist/intercept/cell-batch.cjs +99 -0
  316. package/dist/intercept/cell-batch.cjs.map +1 -0
  317. package/dist/intercept/cell-batch.js +72 -0
  318. package/dist/intercept/cell-batch.js.map +1 -0
  319. package/dist/intercept/classify.cjs +72 -0
  320. package/dist/intercept/classify.cjs.map +1 -0
  321. package/dist/intercept/classify.js +43 -0
  322. package/dist/intercept/classify.js.map +1 -0
  323. package/dist/intercept/codes.cjs +75 -0
  324. package/dist/intercept/codes.cjs.map +1 -0
  325. package/dist/intercept/codes.js +49 -0
  326. package/dist/intercept/codes.js.map +1 -0
  327. package/dist/intercept/context.cjs +81 -0
  328. package/dist/intercept/context.cjs.map +1 -0
  329. package/dist/intercept/context.js +55 -0
  330. package/dist/intercept/context.js.map +1 -0
  331. package/dist/intercept/define.cjs +33 -0
  332. package/dist/intercept/define.cjs.map +1 -0
  333. package/dist/intercept/define.js +8 -0
  334. package/dist/intercept/define.js.map +1 -0
  335. package/dist/intercept/fallbacks.cjs +91 -0
  336. package/dist/intercept/fallbacks.cjs.map +1 -0
  337. package/dist/intercept/fallbacks.js +63 -0
  338. package/dist/intercept/fallbacks.js.map +1 -0
  339. package/dist/intercept/index.cjs +73 -0
  340. package/dist/intercept/index.cjs.map +1 -0
  341. package/dist/intercept/index.js +40 -0
  342. package/dist/intercept/index.js.map +1 -0
  343. package/dist/intercept/operations.cjs +69 -0
  344. package/dist/intercept/operations.cjs.map +1 -0
  345. package/dist/intercept/operations.js +42 -0
  346. package/dist/intercept/operations.js.map +1 -0
  347. package/dist/intercept/runtime.cjs +168 -0
  348. package/dist/intercept/runtime.cjs.map +1 -0
  349. package/dist/intercept/runtime.js +143 -0
  350. package/dist/intercept/runtime.js.map +1 -0
  351. package/dist/messages/index.cjs +74 -0
  352. package/dist/messages/index.cjs.map +1 -0
  353. package/dist/messages/index.js +49 -0
  354. package/dist/messages/index.js.map +1 -0
  355. package/dist/messages.d.cts +4 -0
  356. package/dist/messages.d.ts +4 -0
  357. package/dist/mode-DFV8ryXo.d.cts +5 -0
  358. package/dist/mode-DFV8ryXo.d.ts +5 -0
  359. package/dist/pagination.d.cts +49 -0
  360. package/dist/pagination.d.ts +49 -0
  361. package/dist/pipeline/codes.cjs +58 -0
  362. package/dist/pipeline/codes.cjs.map +1 -0
  363. package/dist/pipeline/codes.js +32 -0
  364. package/dist/pipeline/codes.js.map +1 -0
  365. package/dist/pipeline/column-cache.cjs +237 -0
  366. package/dist/pipeline/column-cache.cjs.map +1 -0
  367. package/dist/pipeline/column-cache.js +212 -0
  368. package/dist/pipeline/column-cache.js.map +1 -0
  369. package/dist/pipeline/columns.cjs +60 -0
  370. package/dist/pipeline/columns.cjs.map +1 -0
  371. package/dist/pipeline/columns.js +35 -0
  372. package/dist/pipeline/columns.js.map +1 -0
  373. package/dist/pipeline/dev-checks.cjs +85 -0
  374. package/dist/pipeline/dev-checks.cjs.map +1 -0
  375. package/dist/pipeline/dev-checks.js +58 -0
  376. package/dist/pipeline/dev-checks.js.map +1 -0
  377. package/dist/pipeline/env-codes.cjs +65 -0
  378. package/dist/pipeline/env-codes.cjs.map +1 -0
  379. package/dist/pipeline/env-codes.js +39 -0
  380. package/dist/pipeline/env-codes.js.map +1 -0
  381. package/dist/pipeline/index.cjs +43 -0
  382. package/dist/pipeline/index.cjs.map +1 -0
  383. package/dist/pipeline/index.js +16 -0
  384. package/dist/pipeline/index.js.map +1 -0
  385. package/dist/pipeline/indices.cjs +40 -0
  386. package/dist/pipeline/indices.cjs.map +1 -0
  387. package/dist/pipeline/indices.js +15 -0
  388. package/dist/pipeline/indices.js.map +1 -0
  389. package/dist/pipeline/perf-codes.cjs +42 -0
  390. package/dist/pipeline/perf-codes.cjs.map +1 -0
  391. package/dist/pipeline/perf-codes.js +17 -0
  392. package/dist/pipeline/perf-codes.js.map +1 -0
  393. package/dist/pipeline/row.cjs +105 -0
  394. package/dist/pipeline/row.cjs.map +1 -0
  395. package/dist/pipeline/row.js +77 -0
  396. package/dist/pipeline/row.js.map +1 -0
  397. package/dist/pipeline/runner.cjs +335 -0
  398. package/dist/pipeline/runner.cjs.map +1 -0
  399. package/dist/pipeline/runner.js +310 -0
  400. package/dist/pipeline/runner.js.map +1 -0
  401. package/dist/pipeline/slice.cjs +142 -0
  402. package/dist/pipeline/slice.cjs.map +1 -0
  403. package/dist/pipeline/slice.js +114 -0
  404. package/dist/pipeline/slice.js.map +1 -0
  405. package/dist/pipeline/status-rule.cjs +33 -0
  406. package/dist/pipeline/status-rule.cjs.map +1 -0
  407. package/dist/pipeline/status-rule.js +8 -0
  408. package/dist/pipeline/status-rule.js.map +1 -0
  409. package/dist/pipeline/types.cjs +19 -0
  410. package/dist/pipeline/types.cjs.map +1 -0
  411. package/dist/pipeline/types.js +1 -0
  412. package/dist/pipeline/types.js.map +1 -0
  413. package/dist/preset/index.cjs +39 -0
  414. package/dist/preset/index.cjs.map +1 -0
  415. package/dist/preset/index.js +13 -0
  416. package/dist/preset/index.js.map +1 -0
  417. package/dist/schema.d.cts +12 -0
  418. package/dist/schema.d.ts +12 -0
  419. package/dist/search-async-entry-BmQYT120.d.ts +94 -0
  420. package/dist/search-async-entry-C3mXxLP8.d.cts +94 -0
  421. package/dist/search-async.d.cts +3 -0
  422. package/dist/search-async.d.ts +3 -0
  423. package/dist/search.d.cts +84 -0
  424. package/dist/search.d.ts +84 -0
  425. package/dist/server.d.cts +49 -0
  426. package/dist/server.d.ts +49 -0
  427. package/dist/sorting.d.cts +76 -0
  428. package/dist/sorting.d.ts +76 -0
  429. package/dist/source/async-control.cjs +117 -0
  430. package/dist/source/async-control.cjs.map +1 -0
  431. package/dist/source/async-control.js +90 -0
  432. package/dist/source/async-control.js.map +1 -0
  433. package/dist/source/codes.cjs +53 -0
  434. package/dist/source/codes.cjs.map +1 -0
  435. package/dist/source/codes.js +27 -0
  436. package/dist/source/codes.js.map +1 -0
  437. package/dist/source/fetch-codes.cjs +126 -0
  438. package/dist/source/fetch-codes.cjs.map +1 -0
  439. package/dist/source/fetch-codes.js +100 -0
  440. package/dist/source/fetch-codes.js.map +1 -0
  441. package/dist/source/fetcher.cjs +130 -0
  442. package/dist/source/fetcher.cjs.map +1 -0
  443. package/dist/source/fetcher.js +98 -0
  444. package/dist/source/fetcher.js.map +1 -0
  445. package/dist/source/index.cjs +50 -0
  446. package/dist/source/index.cjs.map +1 -0
  447. package/dist/source/index.js +22 -0
  448. package/dist/source/index.js.map +1 -0
  449. package/dist/source/mode.cjs +37 -0
  450. package/dist/source/mode.cjs.map +1 -0
  451. package/dist/source/mode.js +11 -0
  452. package/dist/source/mode.js.map +1 -0
  453. package/dist/source/requests.cjs +105 -0
  454. package/dist/source/requests.cjs.map +1 -0
  455. package/dist/source/requests.js +79 -0
  456. package/dist/source/requests.js.map +1 -0
  457. package/dist/source/server-brand.cjs +31 -0
  458. package/dist/source/server-brand.cjs.map +1 -0
  459. package/dist/source/server-brand.js +6 -0
  460. package/dist/source/server-brand.js.map +1 -0
  461. package/dist/source/server-entry.cjs +47 -0
  462. package/dist/source/server-entry.cjs.map +1 -0
  463. package/dist/source/server-entry.js +20 -0
  464. package/dist/source/server-entry.js.map +1 -0
  465. package/dist/source/server.cjs +118 -0
  466. package/dist/source/server.cjs.map +1 -0
  467. package/dist/source/server.js +101 -0
  468. package/dist/source/server.js.map +1 -0
  469. package/dist/source/with-fetcher.cjs +43 -0
  470. package/dist/source/with-fetcher.cjs.map +1 -0
  471. package/dist/source/with-fetcher.js +18 -0
  472. package/dist/source/with-fetcher.js.map +1 -0
  473. package/dist/table/codes.cjs +102 -0
  474. package/dist/table/codes.cjs.map +1 -0
  475. package/dist/table/codes.js +76 -0
  476. package/dist/table/codes.js.map +1 -0
  477. package/dist/table/create-table.cjs +696 -0
  478. package/dist/table/create-table.cjs.map +1 -0
  479. package/dist/table/create-table.js +676 -0
  480. package/dist/table/create-table.js.map +1 -0
  481. package/dist/table/data-mutation.cjs +133 -0
  482. package/dist/table/data-mutation.cjs.map +1 -0
  483. package/dist/table/data-mutation.js +105 -0
  484. package/dist/table/data-mutation.js.map +1 -0
  485. package/dist/table/index.cjs +51 -0
  486. package/dist/table/index.cjs.map +1 -0
  487. package/dist/table/index.js +21 -0
  488. package/dist/table/index.js.map +1 -0
  489. package/dist/table/internals.cjs +49 -0
  490. package/dist/table/internals.cjs.map +1 -0
  491. package/dist/table/internals.js +21 -0
  492. package/dist/table/internals.js.map +1 -0
  493. package/dist/table/read-once.cjs +51 -0
  494. package/dist/table/read-once.cjs.map +1 -0
  495. package/dist/table/read-once.js +25 -0
  496. package/dist/table/read-once.js.map +1 -0
  497. package/dist/table/ssr-codes.cjs +73 -0
  498. package/dist/table/ssr-codes.cjs.map +1 -0
  499. package/dist/table/ssr-codes.js +47 -0
  500. package/dist/table/ssr-codes.js.map +1 -0
  501. package/dist/table/ssr.cjs +57 -0
  502. package/dist/table/ssr.cjs.map +1 -0
  503. package/dist/table/ssr.js +31 -0
  504. package/dist/table/ssr.js.map +1 -0
  505. package/dist/table/state-feedback.cjs +99 -0
  506. package/dist/table/state-feedback.cjs.map +1 -0
  507. package/dist/table/state-feedback.js +72 -0
  508. package/dist/table/state-feedback.js.map +1 -0
  509. package/dist/table/types.cjs +31 -0
  510. package/dist/table/types.cjs.map +1 -0
  511. package/dist/table/types.js +6 -0
  512. package/dist/table/types.js.map +1 -0
  513. package/dist/types.cjs +19 -0
  514. package/dist/types.cjs.map +1 -0
  515. package/dist/types.js +1 -0
  516. package/dist/types.js.map +1 -0
  517. package/dist/validity.d.cts +22 -0
  518. package/dist/validity.d.ts +22 -0
  519. package/dist/version.cjs +36 -0
  520. package/dist/version.cjs.map +1 -0
  521. package/dist/version.js +9 -0
  522. package/dist/version.js.map +1 -0
  523. package/dist/versioning/capability.cjs +49 -0
  524. package/dist/versioning/capability.cjs.map +1 -0
  525. package/dist/versioning/capability.js +23 -0
  526. package/dist/versioning/capability.js.map +1 -0
  527. package/dist/versioning/codes.cjs +138 -0
  528. package/dist/versioning/codes.cjs.map +1 -0
  529. package/dist/versioning/codes.js +111 -0
  530. package/dist/versioning/codes.js.map +1 -0
  531. package/dist/versioning/deprecation.cjs +56 -0
  532. package/dist/versioning/deprecation.cjs.map +1 -0
  533. package/dist/versioning/deprecation.js +30 -0
  534. package/dist/versioning/deprecation.js.map +1 -0
  535. package/dist/versioning/global.cjs +36 -0
  536. package/dist/versioning/global.cjs.map +1 -0
  537. package/dist/versioning/global.js +11 -0
  538. package/dist/versioning/global.js.map +1 -0
  539. package/dist/versioning/index.cjs +44 -0
  540. package/dist/versioning/index.cjs.map +1 -0
  541. package/dist/versioning/index.js +14 -0
  542. package/dist/versioning/index.js.map +1 -0
  543. package/dist/versioning/registry.cjs +105 -0
  544. package/dist/versioning/registry.cjs.map +1 -0
  545. package/dist/versioning/registry.js +76 -0
  546. package/dist/versioning/registry.js.map +1 -0
  547. package/dist/versioning/semver.cjs +108 -0
  548. package/dist/versioning/semver.cjs.map +1 -0
  549. package/dist/versioning/semver.js +81 -0
  550. package/dist/versioning/semver.js.map +1 -0
  551. package/package.json +149 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Supakit Kitjanabumrungsak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,474 @@
1
- # Temporary Holding Version
1
+ # @datakable/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The headless, framework-agnostic core of DataKable: a table store, a row pipeline built from
4
+ features (column filters, validity, search, sorting, pagination), data modes, schema validation,
5
+ diagnostics and `explain()`. No React. For React, use [`datakable`](https://github.com/Ink01101011/datakable/tree/main/packages/datakable) or
6
+ [`@datakable/react`](https://github.com/Ink01101011/datakable/tree/main/packages/react).
7
+
8
+ > Version 1.0: the public API is stable and follows semantic versioning from here. Guides,
9
+ > examples and troubleshooting: the [documentation](https://github.com/Ink01101011/datakable/blob/main/docs/README.md).
10
+
11
+ ```bash
12
+ npm install @datakable/core
13
+ ```
14
+
15
+ **Bundler requirement:** core reads `process.env.NODE_ENV` directly so bundlers can fold it to a
16
+ constant and remove development-only checks, tracing and message text from production builds.
17
+ Vite, webpack, Next.js, Rollup (`@rollup/plugin-replace`) and esbuild
18
+ (`--define:process.env.NODE_ENV='"production"'`) all replace it. Without a replacement, unbundled
19
+ browser code throws `ReferenceError: process is not defined`, as React and Redux do. Node needs
20
+ nothing.
21
+
22
+ ## Contents
23
+
24
+ - [Zero-config](#zero-config)
25
+ - [Features](#features)
26
+ - [Columns](#columns)
27
+ - [Schema validation](#schema-validation)
28
+ - [Server mode](#server-mode)
29
+ - [Status model](#status-model)
30
+ - [Diagnostics](#diagnostics)
31
+ - [explain() and explainRow()](#explain-and-explainrow)
32
+ - [Table API](#table-api)
33
+
34
+ ## Zero-config
35
+
36
+ `datakable`'s `createTable({ data })` installs the default preset, derives the columns from the
37
+ data (the union of keys over the first 50 rows) and infers the row type:
38
+
39
+ ```ts
40
+ import { createTable } from 'datakable'
41
+
42
+ type User = { id: number; name: string; age: number; city: string }
43
+
44
+ const users: User[] = [
45
+ { id: 1, name: 'Mali', age: 31, city: 'Bangkok' },
46
+ { id: 2, name: 'Anan', age: 25, city: 'Chiang Mai' },
47
+ { id: 3, name: 'Ploy', age: 40, city: 'Bangkok' },
48
+ ]
49
+
50
+ // No React needed: the same table, headless. `User` is inferred from `data`.
51
+ const table = createTable({ data: users, rowKey: 'id' })
52
+
53
+ table.toggleSort('age') // asc → desc → none; Shift+click style: toggleSort('age', { multi: true })
54
+ table.setColumnFilter('city', { type: 'equals', value: 'Bangkok' })
55
+ await table.setSearch('mal') // resolves { status: 'applied' | 'superseded' | 'error' }, never rejects
56
+ table.setPageSize(20)
57
+
58
+ const { rows, filteredCount, totalCount, status } = table.getRowModel()
59
+ console.log(
60
+ rows.map((r) => r.original.name),
61
+ filteredCount,
62
+ totalCount,
63
+ status,
64
+ )
65
+
66
+ const unsubscribe = table.subscribe((state) => console.log(state.sorting.by))
67
+ unsubscribe()
68
+ table.destroy()
69
+ ```
70
+
71
+ ## Features
72
+
73
+ `@datakable/core`'s own `createTable` installs **no** features, so a bare import stays small. Each
74
+ feature has its own entry point, and the table's type contains only the state and methods of the
75
+ features you installed:
76
+
77
+ ```ts
78
+ import { createTable } from '@datakable/core'
79
+ import { pagination } from '@datakable/core/pagination'
80
+ import { sorting } from '@datakable/core/sorting'
81
+
82
+ type User = { id: number; name: string; age: number }
83
+ declare const users: User[]
84
+
85
+ // Only what you install is bundled, in the state, and on the table's type.
86
+ const table = createTable({
87
+ data: users,
88
+ features: [sorting(), pagination({ pageSize: 25 })],
89
+ })
90
+
91
+ table.toggleSort('age')
92
+ table.nextPage()
93
+ // @ts-expect-error search() is not installed, so setSearch does not exist
94
+ void table.setSearch
95
+ // @ts-expect-error 'nope' is not a path of User
96
+ table.toggleSort('nope')
97
+ ```
98
+
99
+ | Entry | Feature | State slice | API |
100
+ | --- | --- | --- | --- |
101
+ | `@datakable/core/column-filters` | `columnFilters({ mode })` | `columnFilters`: one filter per column | `setColumnFilter(id, filter)`, `resetColumnFilters()` |
102
+ | `@datakable/core/validity` | `validity()` | `validity`: `'all' \| 'valid' \| 'invalid'` | `setValidity(value)` |
103
+ | `@datakable/core/search` | `search({ threshold, fuzzyMaxDistance, caseSensitive, typing, mode, searchFn })` | `search`: `{ input, query, status, error? }` | `setSearch(q)`, `flushSearch()`, `cancelSearch()`, `clearSearch()` |
104
+ | `@datakable/core/sorting` | `sorting({ locale, algorithm, debug, mode })` | `sorting`: `{ by: { id, desc }[] }` | `toggleSort(id, { multi })`, `setSorting(by)`, `clearSorting()`, `getSortDirection(id)` |
105
+ | `@datakable/core/pagination` | `pagination({ pageSize, autoResetPageIndex, mode })` | `pagination`: `{ pageIndex, pageSize }` | `setPageIndex`, `setPageSize`, `nextPage`, `prevPage`, `getPageCount`, `canNextPage`, `canPrevPage` |
106
+
107
+ The features are also exported from `@datakable/core` itself. The pipeline always runs
108
+ `filter (columnFilters, validity) → search → sort → paginate`, whatever order you list them in.
109
+
110
+ - **Column filters:** `equals`, `contains` (case-insensitive, NFC-normalised), `in`, `range`
111
+ (number / bigint / Date, inclusive) and `custom` (`fn(value, filterValue, row)`). Filters AND
112
+ together; an array cell matches when any element matches.
113
+ - **Search:** fuzzy matching over the formatted cell values. When a column declares
114
+ `search: weight`, only columns with a weight are searched; otherwise every column is, at weight 1. `input` follows the keyboard,
115
+ `query` is the applied value; `typing` sets `immediate` / `debounce` / `throttle`, `wait`,
116
+ `minLength` and `commitOn: 'enter'`. `setSearch` / `flushSearch` return a promise of
117
+ `{ status: 'applied' | 'superseded' | 'error' }` and never reject. A `searchFn` replaces the
118
+ built-in matching (sync or async; the previous results stay while it runs). Wrap it with
119
+ `withSearchFn()` from `@datakable/core/search-async`, so client search does not bundle the
120
+ async engine: `search({ searchFn: withSearchFn(async ({ query, signal }) => …) })`.
121
+ - **Sorting:** asc → desc → none; nulls, `NaN` and invalid dates always last; strings with
122
+ `Intl.Collator` (numeric). `algorithm: 'auto'` (default) picks a stable algorithm per sort.
123
+ - **Pagination:** `setPageSize` keeps the first visible row on screen; the page index resets when
124
+ search, filters or sort change (`autoResetPageIndex`) and is clamped when rows shrink.
125
+
126
+ To install the whole preset with core, pass it:
127
+
128
+ ```ts
129
+ import { createTable, defaultFeatures } from '@datakable/core'
130
+
131
+ type User = { id: number; name: string }
132
+ declare const users: User[]
133
+
134
+ // `@datakable/core`'s createTable installs nothing by default. Opt into the preset explicitly:
135
+ // [columnFilters(), validity(), search(), sorting(), pagination()]
136
+ const table = createTable({ data: users, features: defaultFeatures })
137
+ table.toggleSort('name')
138
+ ```
139
+
140
+ `defaultFeatures` is one set of instances; `createDefaultFeatures()` returns fresh ones (so tables
141
+ do not share a feature's caches). Custom features use the same contract as the built-ins:
142
+ `defineFeature({ name, stage, options, initialState, createApi, rowModel, interceptors })`.
143
+
144
+ ## Columns
145
+
146
+ `columns` is optional. Each column is typed against the row type: `key` is a dot-path of the row
147
+ (depth 4), and the column's value type drives `filter`, `cell`, `format` and `sortFn`.
148
+
149
+ ```ts
150
+ import { createTable } from '@datakable/core'
151
+ import { columnFilters } from '@datakable/core/column-filters'
152
+ import { sorting } from '@datakable/core/sorting'
153
+
154
+ type User = {
155
+ id: number
156
+ name: string
157
+ email: string
158
+ age: number
159
+ joined: Date
160
+ address: { city: string; zip: string }
161
+ manager: { name: string } | null
162
+ }
163
+ declare const users: User[]
164
+
165
+ const table = createTable({
166
+ data: users,
167
+ rowKey: 'id',
168
+ features: [columnFilters(), sorting()],
169
+ columns: [
170
+ { key: 'name', header: 'Name', search: 1 }, // search weight
171
+ { key: 'age', filter: { type: 'range' } },
172
+ { key: 'joined', sortAlgorithm: 'native' },
173
+ { key: 'address.city', search: 0.5 }, // dot-paths, typed against User
174
+ { key: 'manager.name' }, // nullable parents are fine
175
+ { key: 'address', format: (a) => `${a.city} ${a.zip}` }, // objects need format or cell
176
+ { key: 'email', sensitive: true }, // never written to diagnostics
177
+ { id: 'label', accessor: (u) => `${u.name} (${u.age})` }, // derived column
178
+ ],
179
+ })
180
+
181
+ table.setColumnFilter('age', { type: 'range', value: { min: 18, max: 65 } })
182
+ // @ts-expect-error 'range' needs a number / bigint / Date column
183
+ table.setColumnFilter('name', { type: 'range', value: { min: 1 } })
184
+ ```
185
+
186
+ Other column fields: `cell` (custom render; `R` is `ReactNode` in React), `sortable`, `sortFn`,
187
+ `sortBy`, `invalidCell`. Values without a renderer go through the default formatter (`null` →
188
+ `''`, dates `toLocaleString()`, arrays of primitives joined). [Reading type errors](https://github.com/Ink01101011/datakable/blob/main/docs/how-to-fix/reading-type-errors.md)
189
+ explains the compile errors these rules produce.
190
+
191
+ ## Schema validation
192
+
193
+ Pass any [Standard Schema](https://standardschema.dev) (zod, valibot, arktype, …) wrapped with
194
+ `withSchema()` from `@datakable/core/schema`, and the row type is its output. Validation is an
195
+ opt-in import, so a table without a schema does not bundle it:
196
+
197
+ ```ts
198
+ import { createTable, type StandardSchemaV1 } from '@datakable/core'
199
+ import { withSchema } from '@datakable/core/schema'
200
+ import { validity } from '@datakable/core/validity'
201
+
202
+ type User = { id: number; name: string }
203
+ // Any Standard Schema v1: zod, valibot, arktype, … e.g. z.object({ id: z.number(), … })
204
+ declare const UserSchema: StandardSchemaV1<unknown, User>
205
+ declare const json: unknown[] // e.g. await res.json()
206
+
207
+ const table = createTable({
208
+ data: json, // raw input: every row is validated
209
+ schema: withSchema(UserSchema), // opt-in validation; the row type is the schema's output
210
+ invalidRows: 'flag', // 'drop' (default) | 'flag' | 'throw'
211
+ rowKey: 'id',
212
+ features: [validity()], // filters 'all' | 'valid' | 'invalid'
213
+ })
214
+
215
+ for (const row of table.getRowModel().rows) {
216
+ if (row.valid) {
217
+ console.log(row.original.name) // narrowed: original is a User
218
+ } else {
219
+ console.warn(row.issues, row.getCellIssues('name')) // original is unknown
220
+ }
221
+ }
222
+ table.setValidity('invalid') // only the flagged rows
223
+ console.log(table.getInvalidRows()) // [{ index, raw, issues }] in every mode
224
+ ```
225
+
226
+ `invalidRows: 'drop'` (default) removes invalid rows, `'flag'` keeps them as rows with
227
+ `valid: false`, and `'throw'` throws `DatakableSchemaError`. Every mode reports
228
+ `DK_SCHEMA_INVALID_ROW` and lists the rows in `getInvalidRows()`. An async schema sets
229
+ `status: 'validating'` while it runs.
230
+
231
+ ## Server mode
232
+
233
+ Every pipeline feature takes `mode: 'client' | 'server'`. Server steps must form a prefix of the
234
+ pipeline (server filter + search, then client sort + paginate is fine; server paginate before
235
+ client search is not) — a violation throws `DatakableConfigError` (`DK_MODE_ORDER`) at creation
236
+ (a development check).
237
+
238
+ With a `fetcher`, the table loads its own data. The server source is an opt-in import: wrap the
239
+ fetcher with `withFetcher()` from `@datakable/core/server`, so a table without one does not bundle
240
+ it:
241
+
242
+ ```ts
243
+ import { createTable, type FetchResult } from '@datakable/core'
244
+ import { pagination } from '@datakable/core/pagination'
245
+ import { search } from '@datakable/core/search'
246
+ import { withFetcher } from '@datakable/core/server'
247
+ import { sorting } from '@datakable/core/sorting'
248
+
249
+ type User = { id: number; name: string }
250
+
251
+ const table = createTable({
252
+ rowKey: 'id',
253
+ // Server steps must come first in the pipeline (filter → search → sort → paginate);
254
+ // client steps may follow them. Search typing defaults to a 300 ms debounce in server mode.
255
+ features: [
256
+ search({ mode: 'server' }),
257
+ sorting({ mode: 'server' }),
258
+ pagination({ mode: 'server', pageSize: 20 }),
259
+ ],
260
+ // Receives only the server-mode state. Latest request wins; superseded ones are aborted.
261
+ fetcher: withFetcher(async ({ query, sort, pageIndex, pageSize, signal }) => {
262
+ const params = new URLSearchParams({
263
+ q: query ?? '',
264
+ sort: (sort ?? []).map((s) => `${s.desc ? '-' : ''}${s.id}`).join(','),
265
+ page: String(pageIndex),
266
+ size: String(pageSize),
267
+ })
268
+ const res = await fetch(`/api/users?${params}`, { signal })
269
+ if (!res.ok) throw new Error(`HTTP ${res.status}`)
270
+ return (await res.json()) as FetchResult<User> // { rows, rowCount }
271
+ }),
272
+ timeout: 10_000, // default 30 s → DK_ASYNC_TIMEOUT
273
+ })
274
+
275
+ // A failed request keeps the previous rows, sets status 'error' and reports DK_FETCH_FAILED.
276
+ // Retry with the current params; like setSearch, it never rejects.
277
+ const { status } = await table.refetch() // 'applied' | 'superseded' | 'error'
278
+ console.log(status)
279
+ ```
280
+
281
+ - The fetcher receives only the state of the server-mode features (`query`, `filters`, `sort`,
282
+ `pageIndex`, `pageSize`) and a `signal`. It runs at creation and whenever that state changes.
283
+ - Requests go through one async control: latest wins, superseded requests are aborted, `timeout`
284
+ applies, and the result is validated (`DK_FETCH_BAD_RESPONSE` for a missing `rows`, or
285
+ `rowCount < rows.length`). Returned rows go through `schema` and the data checks.
286
+ - A failure (`DK_FETCH_FAILED`, `DK_ASYNC_TIMEOUT`) keeps the previous rows and sets
287
+ `status: 'error'`. `refetch()` retries with the current params; it never rejects.
288
+ - A `fetcher` without any server-mode feature throws `DK_FETCHER_WITHOUT_SERVER_MODE`.
289
+
290
+ Without a fetcher, core only holds the server-mode state and you pass each page in:
291
+
292
+ ```ts
293
+ import { createTable } from '@datakable/core'
294
+ import { pagination } from '@datakable/core/pagination'
295
+
296
+ type User = { id: number; name: string }
297
+ declare const page: User[] // the rows of the current page, fetched by the app
298
+ declare const total: number
299
+
300
+ // Server mode without a fetcher: core only holds the state; the app fetches.
301
+ const table = createTable({
302
+ data: page,
303
+ rowCount: total, // without it: DK_ROW_COUNT_MISSING
304
+ features: [pagination({ mode: 'server' })],
305
+ })
306
+
307
+ table.subscribe((state) => {
308
+ // fetch page state.pagination.pageIndex, then:
309
+ // table.setOptions({ data: nextPage, rowCount: nextTotal })
310
+ console.log(state.pagination)
311
+ })
312
+ ```
313
+
314
+ ## Status model
315
+
316
+ `getRowModel()` returns `{ rows, filteredCount, totalCount, status, isInitialLoad }`. `rows` holds
317
+ the visible page only; `filteredCount` counts the rows after filter and search; `totalCount` the
318
+ rows after ingest.
319
+
320
+ | `status` | Meaning |
321
+ | --- | --- |
322
+ | `'idle'` | the row model is current |
323
+ | `'validating'` | an async schema is running |
324
+ | `'pending'` | a search debounce is waiting, time-sliced work (search index, string sort over large data) is running, or async work waits for the client after SSR (`createDeferred`) |
325
+ | `'searching'` | an async `searchFn` request is in flight |
326
+ | `'fetching'` | a `fetcher` request is in flight (initial load, or a page / sort / filter / query change in server mode) |
327
+ | `'error'` | a diagnostic affected the row model; the last good row model is shown |
328
+
329
+ When activities overlap, the most specific one wins: `error` > `fetching` > `searching` >
330
+ `validating` > `pending` > `idle`. So a `refetch()` after a failed fetch keeps `status: 'error'`
331
+ until a request applies; await the promise `refetch()` returns to follow the retry. A cell-level
332
+ problem handled inside a step (a throwing `format`, `DK_FILTER_TYPE_MISMATCH`) is reported as a
333
+ diagnostic and leaves the status as it was.
334
+
335
+ `isInitialLoad` is `true` until the table has had rows to show for the first time (data given at
336
+ creation, or the first fetcher / `searchFn` result applied). It never goes back to `true`, and an
337
+ empty result counts as loaded. If the first request fails, `status` is `'error'` while
338
+ `isInitialLoad` stays `true`.
339
+
340
+ **Status is never silent:** every change of `status` or `isInitialLoad` produces a new row model
341
+ and notifies subscribers, so a UI bound to `getRowModel()` always shows what the table is doing.
342
+
343
+ ```ts
344
+ import type { RowModel } from '@datakable/core'
345
+
346
+ // What to show for a row model (§6.6). A change of `status` or `isInitialLoad` always produces a
347
+ // new row model and notifies subscribers: status is never silent.
348
+ export function view<T>(model: RowModel<T>) {
349
+ const { status, isInitialLoad, rows } = model
350
+ // Before the first rows, 'pending' is a load waiting to start (e.g. deferred to the client, §7.2).
351
+ const busy = status !== 'idle' && status !== 'error'
352
+ if (isInitialLoad && busy) return 'loading' // nothing to show yet
353
+ if (isInitialLoad && status === 'error') return 'error' // the first request failed
354
+ if (rows.length === 0 && status === 'idle') return 'empty' // loaded, zero rows
355
+ // Otherwise show the rows: during 'pending' / 'searching' / 'fetching' / 'validating' they are
356
+ // the previous results (add a refresh indicator); on 'error' they are the last good rows.
357
+ return status === 'idle' ? 'rows' : `rows+${status}`
358
+ }
359
+ ```
360
+
361
+ ## Diagnostics
362
+
363
+ Every problem the table detects is a `Diagnostic`: a stable `code` (`DK_*`, public API, never
364
+ reused), `level`, `problem`, `where` (column, feature, option or row), `impact` (what the table did
365
+ instead), `fix` (computed from your data, best first), `docs`, redacted `details`, a `context`
366
+ (table name, trigger, pipeline run, phase) and a `fingerprint` for grouping. Data and runtime
367
+ problems never throw: the table falls back to the last good state. Configuration mistakes (for
368
+ example `DK_MODE_ORDER`, an invalid option) throw `DatakableConfigError` at creation.
369
+
370
+ ```ts
371
+ import { createTable, type Diagnostic } from '@datakable/core'
372
+
373
+ type User = { id: number; name: string; ssn: string }
374
+ declare const users: User[]
375
+ declare const Sentry: { captureMessage(message: string, context: object): void }
376
+
377
+ const table = createTable({
378
+ name: 'UsersTable', // shown in every diagnostic
379
+ data: users,
380
+ rowKey: 'id',
381
+ columns: [{ key: 'name' }, { key: 'ssn', sensitive: true }],
382
+ diagnostics: { redact: 'safe' }, // 'safe' (prod default) | 'keys' (dev default) | 'full' | fn
383
+ onDiagnostic: (d: Diagnostic) => {
384
+ // code, level, where, problem, impact, fix[], docs, context, fingerprint
385
+ if (d.level === 'error') Sentry.captureMessage(d.code, d.toJSON())
386
+ },
387
+ strict: false, // true: error-level diagnostics throw DatakableError
388
+ })
389
+
390
+ for (const d of table.getDiagnostics()) console.log(d.code, d.where, d.fix)
391
+ ```
392
+
393
+ - **Sinks:** `onDiagnostic` receives every diagnostic. The default console sink prints one
394
+ collapsed group per diagnostic in development and only `error` level, on one line, in
395
+ production. `getDiagnostics()` keeps the last 100. Repeats of the same code and location are
396
+ aggregated (`context.occurrences`) and the console is rate-limited.
397
+ - **Redaction** (`diagnostics.redact`): `'safe'` logs paths, indices, counts, value types and
398
+ hashed row keys (production default); `'keys'` adds raw row keys (development default); `'full'`
399
+ adds row values. A custom `redact(path, value)` can rewrite any field. Columns with
400
+ `sensitive: true` are never logged at any level, and fetcher errors are logged by name only (the
401
+ original goes to `onDiagnostic` as `context.cause`).
402
+ - **Production text:** production builds keep `code`, `where`, `context` and a docs URL and drop
403
+ the `problem` / `impact` / `fix` text. To keep it:
404
+
405
+ ```ts
406
+ // Production builds keep code, where, context and a docs URL; the text is stripped. Import once
407
+ // in the app entry to keep the full problem / impact / fix text in production:
408
+ import '@datakable/core/messages'
409
+ ```
410
+
411
+ ## explain() and explainRow()
412
+
413
+ Both work in the browser console, in tests and on the server, and go through the same redaction as
414
+ diagnostics:
415
+
416
+ ```ts
417
+ import { createTable, defaultFeatures } from '@datakable/core'
418
+
419
+ type Product = { sku: string; name: string; price: number }
420
+ declare const products: Product[]
421
+
422
+ const table = createTable({ data: products, rowKey: 'sku', features: defaultFeatures })
423
+ table.setColumnFilter('price', { type: 'range', value: { min: 100 } })
424
+ await table.setSearch('chair')
425
+
426
+ // Where did my rows go? Rows per step, the page, timings (traced in development).
427
+ console.log(String(table.explain()))
428
+
429
+ // Why is this row not shown? Replays one row through every step.
430
+ const why = table.explainRow('SKU-042')
431
+ console.log(why.visible, why.removedBy, String(why))
432
+ ```
433
+
434
+ ```text
435
+ run 2 1.1 ms · trigger api:setSearch · 300 rows → columnFilters 200 cached → validity 200 cached → search 28 1.1 ms → sorting 28 0.0 ms → page 1/3 (10) · status idle · 0 open diagnostics
436
+
437
+ row SKU-042 · data index 42 · run 2
438
+ – schema no schema
439
+ ✗ columnFilters price range object → number fails ← removed here
440
+ · validity not reached
441
+ · search not reached
442
+ · sorting not reached
443
+ · pagination not reached
444
+ fix setColumnFilter('price', undefined) or resetColumnFilters()
445
+ ```
446
+
447
+ `explain()` returns the last pipeline run (rows per step, schema drops, the page, open diagnostics,
448
+ timings when traced); `explainRow(key)` replays one row through the schema and every step and
449
+ names the step that removed it. Both are plain objects; `String(…)` gives the report above.
450
+
451
+ ## Table API
452
+
453
+ | Method | |
454
+ | --- | --- |
455
+ | `getState()` / `setState(updater)` / `subscribe(listener)` | immutable snapshots; one throwing listener never stops the others |
456
+ | `getRowModel()` | rows, counts, `status`, `isInitialLoad` |
457
+ | `setOptions(partial)` / `getOptions()` | update `data`, `columns`, `state`, `fetcher`, `rowCount`, … |
458
+ | `getData()` / `getInvalidRows()` | ingested data; rows that failed `schema` |
459
+ | `getDiagnostics()` | the last 100 diagnostics |
460
+ | `explain()` / `explainRow(key)` | why the rows are what they are |
461
+ | `refetch()` | re-run the fetcher; never rejects |
462
+ | `destroy()` | release listeners; later calls are no-ops (`DK_TABLE_DESTROYED`) |
463
+
464
+ Options: `data`, `columns`, `rowKey` (a path or `(row) => string | number`; duplicates and missing
465
+ keys are reported and get fallback keys), `features`, `schema` (`withSchema`, from
466
+ `@datakable/core/schema`), `invalidRows`, `initialState`, controlled `state` + `onStateChange`,
467
+ `interceptors`, `fetcher` (`withFetcher`, from `@datakable/core/server`), `rowCount`, `timeout`,
468
+ `name`, `onDiagnostic`, `strict`, `diagnostics`. In development, unknown options are reported with a
469
+ did-you-mean and invalid values throw `DatakableConfigError` naming the accepted values; production
470
+ builds skip these checks (like the data checks and version checks) to stay small.
471
+
472
+ ## License
473
+
474
+ MIT
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/catalog/codes.ts
21
+ var codes_exports = {};
22
+ __export(codes_exports, {
23
+ optionDiagnostics: () => optionDiagnostics,
24
+ optionMessages: () => optionMessages
25
+ });
26
+ module.exports = __toCommonJS(codes_exports);
27
+ var import_catalog = require("../diagnostics/catalog.cjs");
28
+ var where = (d) => d.feature === void 0 ? { kind: "option", path: d.path } : { kind: "feature", name: d.feature };
29
+ var label = (d) => d.feature === void 0 ? `options.${d.path}` : `${d.feature}({ ${d.path} })`;
30
+ var leaf = (path) => path.slice(path.lastIndexOf(".") + 1);
31
+ var optionMessages = {
32
+ DK_UNKNOWN_OPTION: {
33
+ problem: (d) => d.feature === void 0 ? `unknown option "${d.path}"` : `feature "${d.feature}" got an unknown option "${d.path}"`,
34
+ impact: () => "the option is ignored",
35
+ fix: (d) => {
36
+ const out = [];
37
+ const s = d.suggestions[0];
38
+ if (s !== void 0) out.push(`did you mean "${s}"? rename "${leaf(d.path)}" to "${s}"`);
39
+ if (d.owner !== void 0) {
40
+ out.push(
41
+ `"${d.path}" is an option of feature "${d.owner}": pass it to the feature, ${d.owner}({ ${d.path}: ... })`
42
+ );
43
+ }
44
+ out.push(
45
+ `remove "${leaf(d.path)}"; accepted ${d.feature === void 0 ? "" : `${d.feature} `}options here: ${d.known.join(", ") || "(none)"}`
46
+ );
47
+ return out;
48
+ }
49
+ },
50
+ DK_INVALID_OPTION: {
51
+ problem: (d) => `${label(d)} must be ${d.expected}, got ${d.received}`,
52
+ impact: (d) => d.phase === "init" ? "the table was not created" : "setOptions() was rejected; the previous options are kept",
53
+ fix: (d) => {
54
+ const out = [];
55
+ if (d.hint !== void 0) out.push(d.hint);
56
+ const s = d.suggestions[0];
57
+ if (s !== void 0) out.push(`use '${s}' (the closest accepted value) for ${label(d)}`);
58
+ out.push(`pass ${d.expected} as ${label(d)}, or leave it out for the default`);
59
+ return out;
60
+ }
61
+ },
62
+ DK_OPTION_NO_EFFECT: {
63
+ problem: (d) => d.once ? `setOptions({ ${d.path} }) has no effect: ${d.reason}` : `${label(d)} has no effect: ${d.reason}`,
64
+ impact: (d) => d.once ? "the new value was ignored; the table keeps the value it was created with" : "the option is ignored in this configuration",
65
+ fix: (d) => d.once ? [
66
+ `pass ${d.path} to createTable() instead; to change it, create a new table (in React, change the component key)`
67
+ ] : [`remove ${label(d)}, or change the configuration so that it applies (${d.reason})`]
68
+ }
69
+ };
70
+ var optionDiagnostics = [
71
+ (0, import_catalog.defineDiagnostic)(
72
+ {
73
+ code: "DK_UNKNOWN_OPTION",
74
+ level: "warn",
75
+ where
76
+ },
77
+ process.env.NODE_ENV !== "production" && optionMessages.DK_UNKNOWN_OPTION
78
+ ),
79
+ (0, import_catalog.defineDiagnostic)(
80
+ {
81
+ code: "DK_INVALID_OPTION",
82
+ level: "error",
83
+ config: true,
84
+ where
85
+ },
86
+ process.env.NODE_ENV !== "production" && optionMessages.DK_INVALID_OPTION
87
+ ),
88
+ (0, import_catalog.defineDiagnostic)(
89
+ {
90
+ code: "DK_OPTION_NO_EFFECT",
91
+ level: "warn",
92
+ where
93
+ },
94
+ process.env.NODE_ENV !== "production" && optionMessages.DK_OPTION_NO_EFFECT
95
+ )
96
+ ];
97
+ // Annotate the CommonJS export names for ESM import in node:
98
+ 0 && (module.exports = {
99
+ optionDiagnostics,
100
+ optionMessages
101
+ });
102
+ //# sourceMappingURL=codes.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/catalog/codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../diagnostics/catalog'\nimport type { Location } from '../diagnostics/types'\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_UNKNOWN_OPTION: {\n /** Option path as written (`colums`, `diagnostics.redcat`); option keys, never values. */\n path: string\n /** Set when the option was given to a feature factory. */\n feature?: string\n /** Close accepted names, best first (did-you-mean). */\n suggestions: string[]\n /** The accepted options at that level. */\n known: string[]\n /** An installed feature that has this option (it was passed to the table instead). */\n owner?: string\n }\n DK_INVALID_OPTION: {\n path: string\n feature?: string\n /** The accepted values in words. */\n expected: string\n /** What was given: a type, or a short constant (`\"ful\"`, `NaN`). */\n received: string\n /** Close accepted values (enums), best first. */\n suggestions: string[]\n /** A fix specific to this mistake, shown first. */\n hint?: string\n /** Where it was given: `createTable` (the table was not created) or `setOptions` (rejected). */\n phase: 'init' | 'setOptions'\n }\n DK_OPTION_NO_EFFECT: {\n path: string\n feature?: string\n /** Why the option is ignored. */\n reason: string\n /** `true` for a read-once option changed with `setOptions`. */\n once: boolean\n }\n }\n}\n\nconst where = (d: { path: string; feature?: string }): Location =>\n d.feature === undefined ? { kind: 'option', path: d.path } : { kind: 'feature', name: d.feature }\n\n/** `options.timeout` / `paging({ pageSize })`. */\nconst label = (d: { path: string; feature?: string }) =>\n d.feature === undefined ? `options.${d.path}` : `${d.feature}({ ${d.path} })`\n\nconst leaf = (path: string) => path.slice(path.lastIndexOf('.') + 1)\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const optionMessages: DiagnosticMessages<\n 'DK_UNKNOWN_OPTION' | 'DK_INVALID_OPTION' | 'DK_OPTION_NO_EFFECT'\n> = {\n DK_UNKNOWN_OPTION: {\n problem: (d) =>\n d.feature === undefined\n ? `unknown option \"${d.path}\"`\n : `feature \"${d.feature}\" got an unknown option \"${d.path}\"`,\n impact: () => 'the option is ignored',\n fix: (d) => {\n const out: string[] = []\n const s = d.suggestions[0]\n if (s !== undefined) out.push(`did you mean \"${s}\"? rename \"${leaf(d.path)}\" to \"${s}\"`)\n if (d.owner !== undefined) {\n out.push(\n `\"${d.path}\" is an option of feature \"${d.owner}\": pass it to the feature, ` +\n `${d.owner}({ ${d.path}: ... })`,\n )\n }\n out.push(\n `remove \"${leaf(d.path)}\"; accepted ${d.feature === undefined ? '' : `${d.feature} `}` +\n `options here: ${d.known.join(', ') || '(none)'}`,\n )\n return out\n },\n },\n DK_INVALID_OPTION: {\n problem: (d) => `${label(d)} must be ${d.expected}, got ${d.received}`,\n impact: (d) =>\n d.phase === 'init'\n ? 'the table was not created'\n : 'setOptions() was rejected; the previous options are kept',\n fix: (d) => {\n const out: string[] = []\n if (d.hint !== undefined) out.push(d.hint)\n const s = d.suggestions[0]\n if (s !== undefined) out.push(`use '${s}' (the closest accepted value) for ${label(d)}`)\n out.push(`pass ${d.expected} as ${label(d)}, or leave it out for the default`)\n return out\n },\n },\n DK_OPTION_NO_EFFECT: {\n problem: (d) =>\n d.once\n ? `setOptions({ ${d.path} }) has no effect: ${d.reason}`\n : `${label(d)} has no effect: ${d.reason}`,\n impact: (d) =>\n d.once\n ? 'the new value was ignored; the table keeps the value it was created with'\n : 'the option is ignored in this configuration',\n fix: (d) =>\n d.once\n ? [\n `pass ${d.path} to createTable() instead; to change it, create a new table ` +\n '(in React, change the component key)',\n ]\n : [`remove ${label(d)}, or change the configuration so that it applies (${d.reason})`],\n },\n}\n\n/** Codes owned by the options catalog (§3.5, §8.3). */\nexport const optionDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_UNKNOWN_OPTION',\n level: 'warn',\n where,\n },\n (process.env.NODE_ENV !== \"production\") && optionMessages.DK_UNKNOWN_OPTION,\n ),\n defineDiagnostic(\n {\n code: 'DK_INVALID_OPTION',\n level: 'error',\n config: true,\n where,\n },\n (process.env.NODE_ENV !== \"production\") && optionMessages.DK_INVALID_OPTION,\n ),\n defineDiagnostic(\n {\n code: 'DK_OPTION_NO_EFFECT',\n level: 'warn',\n where,\n },\n (process.env.NODE_ENV !== \"production\") && optionMessages.DK_OPTION_NO_EFFECT,\n ),\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA0D;AA0C1D,IAAM,QAAQ,CAAC,MACb,EAAE,YAAY,SAAY,EAAE,MAAM,UAAU,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAGlG,IAAM,QAAQ,CAAC,MACb,EAAE,YAAY,SAAY,WAAW,EAAE,IAAI,KAAK,GAAG,EAAE,OAAO,MAAM,EAAE,IAAI;AAE1E,IAAM,OAAO,CAAC,SAAiB,KAAK,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;AAG5D,IAAM,iBAET;AAAA,EACF,mBAAmB;AAAA,IACjB,SAAS,CAAC,MACR,EAAE,YAAY,SACV,mBAAmB,EAAE,IAAI,MACzB,YAAY,EAAE,OAAO,4BAA4B,EAAE,IAAI;AAAA,IAC7D,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AACV,YAAM,MAAgB,CAAC;AACvB,YAAM,IAAI,EAAE,YAAY,CAAC;AACzB,UAAI,MAAM,OAAW,KAAI,KAAK,iBAAiB,CAAC,cAAc,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;AACvF,UAAI,EAAE,UAAU,QAAW;AACzB,YAAI;AAAA,UACF,IAAI,EAAE,IAAI,8BAA8B,EAAE,KAAK,8BAC1C,EAAE,KAAK,MAAM,EAAE,IAAI;AAAA,QAC1B;AAAA,MACF;AACA,UAAI;AAAA,QACF,WAAW,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,SAAY,KAAK,GAAG,EAAE,OAAO,GAAG,iBACjE,EAAE,MAAM,KAAK,IAAI,KAAK,QAAQ;AAAA,MACnD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,EAAE,QAAQ,SAAS,EAAE,QAAQ;AAAA,IACpE,QAAQ,CAAC,MACP,EAAE,UAAU,SACR,8BACA;AAAA,IACN,KAAK,CAAC,MAAM;AACV,YAAM,MAAgB,CAAC;AACvB,UAAI,EAAE,SAAS,OAAW,KAAI,KAAK,EAAE,IAAI;AACzC,YAAM,IAAI,EAAE,YAAY,CAAC;AACzB,UAAI,MAAM,OAAW,KAAI,KAAK,QAAQ,CAAC,sCAAsC,MAAM,CAAC,CAAC,EAAE;AACvF,UAAI,KAAK,QAAQ,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC,mCAAmC;AAC7E,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,qBAAqB;AAAA,IACnB,SAAS,CAAC,MACR,EAAE,OACE,gBAAgB,EAAE,IAAI,sBAAsB,EAAE,MAAM,KACpD,GAAG,MAAM,CAAC,CAAC,mBAAmB,EAAE,MAAM;AAAA,IAC5C,QAAQ,CAAC,MACP,EAAE,OACE,6EACA;AAAA,IACN,KAAK,CAAC,MACJ,EAAE,OACE;AAAA,MACE,QAAQ,EAAE,IAAI;AAAA,IAEhB,IACA,CAAC,UAAU,MAAM,CAAC,CAAC,qDAAqD,EAAE,MAAM,GAAG;AAAA,EAC3F;AACF;AAGO,IAAM,oBAAoB;AAAA,MAC/B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,IACF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,eAAe;AAAA,EAC5D;AAAA,MACA;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,eAAe;AAAA,EAC5D;AAAA,MACA;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,IACF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,eAAe;AAAA,EAC5D;AACF;","names":[]}