@datakable/core 1.0.0 → 1.1.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 (290) hide show
  1. package/README.md +4 -2
  2. package/dist/catalog/codes.cjs +12 -8
  3. package/dist/catalog/codes.cjs.map +1 -1
  4. package/dist/catalog/codes.js +12 -8
  5. package/dist/catalog/codes.js.map +1 -1
  6. package/dist/catalog/slots.cjs +10 -6
  7. package/dist/catalog/slots.cjs.map +1 -1
  8. package/dist/catalog/slots.js +10 -6
  9. package/dist/catalog/slots.js.map +1 -1
  10. package/dist/{codes-BKdS9EiO.d.cts → codes-B9bCK73-.d.cts} +46 -8
  11. package/dist/{codes-BKdS9EiO.d.ts → codes-B9bCK73-.d.ts} +46 -8
  12. package/dist/column/column-def.cjs.map +1 -1
  13. package/dist/column/get-value.cjs +6 -1
  14. package/dist/column/get-value.cjs.map +1 -1
  15. package/dist/column/get-value.js +6 -1
  16. package/dist/column/get-value.js.map +1 -1
  17. package/dist/column-filters.d.cts +2 -2
  18. package/dist/column-filters.d.ts +2 -2
  19. package/dist/diagnostics/build.cjs +10 -4
  20. package/dist/diagnostics/build.cjs.map +1 -1
  21. package/dist/diagnostics/build.js +8 -3
  22. package/dist/diagnostics/build.js.map +1 -1
  23. package/dist/diagnostics/catalog.cjs +11 -5
  24. package/dist/diagnostics/catalog.cjs.map +1 -1
  25. package/dist/diagnostics/catalog.js +10 -5
  26. package/dist/diagnostics/catalog.js.map +1 -1
  27. package/dist/diagnostics/codes.cjs +12 -8
  28. package/dist/diagnostics/codes.cjs.map +1 -1
  29. package/dist/diagnostics/codes.js +12 -8
  30. package/dist/diagnostics/codes.js.map +1 -1
  31. package/dist/diagnostics/console.cjs +13 -6
  32. package/dist/diagnostics/console.cjs.map +1 -1
  33. package/dist/diagnostics/console.js +13 -6
  34. package/dist/diagnostics/console.js.map +1 -1
  35. package/dist/diagnostics/env.cjs +1 -0
  36. package/dist/diagnostics/env.cjs.map +1 -1
  37. package/dist/diagnostics/env.js +1 -0
  38. package/dist/diagnostics/env.js.map +1 -1
  39. package/dist/diagnostics/explain-text.cjs +2 -1
  40. package/dist/diagnostics/explain-text.cjs.map +1 -1
  41. package/dist/diagnostics/explain-text.js +2 -1
  42. package/dist/diagnostics/explain-text.js.map +1 -1
  43. package/dist/diagnostics/explain.cjs +3 -2
  44. package/dist/diagnostics/explain.cjs.map +1 -1
  45. package/dist/diagnostics/explain.js +3 -2
  46. package/dist/diagnostics/explain.js.map +1 -1
  47. package/dist/diagnostics/hub.cjs +6 -5
  48. package/dist/diagnostics/hub.cjs.map +1 -1
  49. package/dist/diagnostics/hub.js +7 -6
  50. package/dist/diagnostics/hub.js.map +1 -1
  51. package/dist/diagnostics/process-guard.cjs +26 -0
  52. package/dist/diagnostics/process-guard.cjs.map +1 -0
  53. package/dist/diagnostics/process-guard.js +9 -0
  54. package/dist/diagnostics/process-guard.js.map +1 -0
  55. package/dist/diagnostics/prose.cjs +120 -0
  56. package/dist/diagnostics/prose.cjs.map +1 -0
  57. package/dist/diagnostics/prose.js +93 -0
  58. package/dist/diagnostics/prose.js.map +1 -0
  59. package/dist/diagnostics/redact.cjs +7 -4
  60. package/dist/diagnostics/redact.cjs.map +1 -1
  61. package/dist/diagnostics/redact.js +6 -4
  62. package/dist/diagnostics/redact.js.map +1 -1
  63. package/dist/diagnostics/trace-store.cjs +6 -0
  64. package/dist/diagnostics/trace-store.cjs.map +1 -1
  65. package/dist/diagnostics/trace-store.js +4 -0
  66. package/dist/diagnostics/trace-store.js.map +1 -1
  67. package/dist/diagnostics/tracer.cjs +74 -13
  68. package/dist/diagnostics/tracer.cjs.map +1 -1
  69. package/dist/diagnostics/tracer.js +75 -14
  70. package/dist/diagnostics/tracer.js.map +1 -1
  71. package/dist/diagnostics/types.cjs.map +1 -1
  72. package/dist/{explain-aagaYHcy.d.cts → explain-Q8Cg0cZy.d.cts} +13 -4
  73. package/dist/{explain-DcUZfFh5.d.ts → explain-i0OATi_W.d.ts} +13 -4
  74. package/dist/feature/codes.cjs +1 -0
  75. package/dist/feature/codes.cjs.map +1 -1
  76. package/dist/feature/codes.js +1 -0
  77. package/dist/feature/codes.js.map +1 -1
  78. package/dist/feature/define.cjs +3 -1
  79. package/dist/feature/define.cjs.map +1 -1
  80. package/dist/feature/define.js +3 -1
  81. package/dist/feature/define.js.map +1 -1
  82. package/dist/feature/install.cjs +4 -3
  83. package/dist/feature/install.cjs.map +1 -1
  84. package/dist/feature/install.js +4 -3
  85. package/dist/feature/install.js.map +1 -1
  86. package/dist/feature/runtime.cjs.map +1 -1
  87. package/dist/feature/runtime.js.map +1 -1
  88. package/dist/features/column-filters/codes.cjs +1 -0
  89. package/dist/features/column-filters/codes.cjs.map +1 -1
  90. package/dist/features/column-filters/codes.js +1 -0
  91. package/dist/features/column-filters/codes.js.map +1 -1
  92. package/dist/features/column-filters/column-filters.cjs +4 -2
  93. package/dist/features/column-filters/column-filters.cjs.map +1 -1
  94. package/dist/features/column-filters/column-filters.js +4 -2
  95. package/dist/features/column-filters/column-filters.js.map +1 -1
  96. package/dist/features/column-filters/match.cjs +5 -5
  97. package/dist/features/column-filters/match.cjs.map +1 -1
  98. package/dist/features/column-filters/match.js +5 -5
  99. package/dist/features/column-filters/match.js.map +1 -1
  100. package/dist/features/pagination/codes.cjs +6 -3
  101. package/dist/features/pagination/codes.cjs.map +1 -1
  102. package/dist/features/pagination/codes.js +6 -3
  103. package/dist/features/pagination/codes.js.map +1 -1
  104. package/dist/features/pagination/pagination.cjs +19 -14
  105. package/dist/features/pagination/pagination.cjs.map +1 -1
  106. package/dist/features/pagination/pagination.js +19 -14
  107. package/dist/features/pagination/pagination.js.map +1 -1
  108. package/dist/features/search/codes.cjs +1 -0
  109. package/dist/features/search/codes.cjs.map +1 -1
  110. package/dist/features/search/codes.js +1 -0
  111. package/dist/features/search/codes.js.map +1 -1
  112. package/dist/features/search/search-index.cjs +105 -48
  113. package/dist/features/search/search-index.cjs.map +1 -1
  114. package/dist/features/search/search-index.js +106 -49
  115. package/dist/features/search/search-index.js.map +1 -1
  116. package/dist/features/search/search.cjs +82 -24
  117. package/dist/features/search/search.cjs.map +1 -1
  118. package/dist/features/search/search.js +82 -24
  119. package/dist/features/search/search.js.map +1 -1
  120. package/dist/features/search/skipped-codes.cjs +45 -0
  121. package/dist/features/search/skipped-codes.cjs.map +1 -0
  122. package/dist/features/search/skipped-codes.js +20 -0
  123. package/dist/features/search/skipped-codes.js.map +1 -0
  124. package/dist/features/sorting/codes.cjs +1 -0
  125. package/dist/features/sorting/codes.cjs.map +1 -1
  126. package/dist/features/sorting/codes.js +1 -0
  127. package/dist/features/sorting/codes.js.map +1 -1
  128. package/dist/features/sorting/sorting.cjs +19 -23
  129. package/dist/features/sorting/sorting.cjs.map +1 -1
  130. package/dist/features/sorting/sorting.js +19 -23
  131. package/dist/features/sorting/sorting.js.map +1 -1
  132. package/dist/features/sorting/strategy.cjs +4 -4
  133. package/dist/features/sorting/strategy.cjs.map +1 -1
  134. package/dist/features/sorting/strategy.js +4 -4
  135. package/dist/features/sorting/strategy.js.map +1 -1
  136. package/dist/features/validity/codes.cjs +1 -0
  137. package/dist/features/validity/codes.cjs.map +1 -1
  138. package/dist/features/validity/codes.js +1 -0
  139. package/dist/features/validity/codes.js.map +1 -1
  140. package/dist/features/validity/validity.cjs +3 -3
  141. package/dist/features/validity/validity.cjs.map +1 -1
  142. package/dist/features/validity/validity.js +3 -3
  143. package/dist/features/validity/validity.js.map +1 -1
  144. package/dist/index.d.cts +16 -11
  145. package/dist/index.d.ts +16 -11
  146. package/dist/ingest/data-check-codes.cjs +4 -2
  147. package/dist/ingest/data-check-codes.cjs.map +1 -1
  148. package/dist/ingest/data-check-codes.js +4 -2
  149. package/dist/ingest/data-check-codes.js.map +1 -1
  150. package/dist/ingest/data-checks.cjs +1 -1
  151. package/dist/ingest/data-checks.cjs.map +1 -1
  152. package/dist/ingest/data-checks.js +1 -1
  153. package/dist/ingest/data-checks.js.map +1 -1
  154. package/dist/ingest/row-key-codes.cjs +1 -0
  155. package/dist/ingest/row-key-codes.cjs.map +1 -1
  156. package/dist/ingest/row-key-codes.js +1 -0
  157. package/dist/ingest/row-key-codes.js.map +1 -1
  158. package/dist/ingest/row-key.cjs +23 -20
  159. package/dist/ingest/row-key.cjs.map +1 -1
  160. package/dist/ingest/row-key.js +23 -20
  161. package/dist/ingest/row-key.js.map +1 -1
  162. package/dist/ingest/schema-codes.cjs +1 -0
  163. package/dist/ingest/schema-codes.cjs.map +1 -1
  164. package/dist/ingest/schema-codes.js +1 -0
  165. package/dist/ingest/schema-codes.js.map +1 -1
  166. package/dist/ingest/unique-fields.cjs +2 -2
  167. package/dist/ingest/unique-fields.cjs.map +1 -1
  168. package/dist/ingest/unique-fields.js +2 -2
  169. package/dist/ingest/unique-fields.js.map +1 -1
  170. package/dist/intercept/boundary.cjs +4 -2
  171. package/dist/intercept/boundary.cjs.map +1 -1
  172. package/dist/intercept/boundary.js +4 -2
  173. package/dist/intercept/boundary.js.map +1 -1
  174. package/dist/intercept/cell-batch.cjs +7 -4
  175. package/dist/intercept/cell-batch.cjs.map +1 -1
  176. package/dist/intercept/cell-batch.js +7 -4
  177. package/dist/intercept/cell-batch.js.map +1 -1
  178. package/dist/intercept/codes.cjs +1 -0
  179. package/dist/intercept/codes.cjs.map +1 -1
  180. package/dist/intercept/codes.js +1 -0
  181. package/dist/intercept/codes.js.map +1 -1
  182. package/dist/intercept/fallbacks.cjs +12 -20
  183. package/dist/intercept/fallbacks.cjs.map +1 -1
  184. package/dist/intercept/fallbacks.js +12 -20
  185. package/dist/intercept/fallbacks.js.map +1 -1
  186. package/dist/intercept/runtime.cjs +7 -9
  187. package/dist/intercept/runtime.cjs.map +1 -1
  188. package/dist/intercept/runtime.js +7 -9
  189. package/dist/intercept/runtime.js.map +1 -1
  190. package/dist/messages/index.cjs +4 -1
  191. package/dist/messages/index.cjs.map +1 -1
  192. package/dist/messages/index.js +4 -1
  193. package/dist/messages/index.js.map +1 -1
  194. package/dist/pagination.d.cts +2 -2
  195. package/dist/pagination.d.ts +2 -2
  196. package/dist/pipeline/codes.cjs +1 -0
  197. package/dist/pipeline/codes.cjs.map +1 -1
  198. package/dist/pipeline/codes.js +1 -0
  199. package/dist/pipeline/codes.js.map +1 -1
  200. package/dist/pipeline/column-cache.cjs +94 -76
  201. package/dist/pipeline/column-cache.cjs.map +1 -1
  202. package/dist/pipeline/column-cache.js +92 -75
  203. package/dist/pipeline/column-cache.js.map +1 -1
  204. package/dist/pipeline/dev-checks.cjs +1 -0
  205. package/dist/pipeline/dev-checks.cjs.map +1 -1
  206. package/dist/pipeline/dev-checks.js +1 -0
  207. package/dist/pipeline/dev-checks.js.map +1 -1
  208. package/dist/pipeline/env-codes.cjs +3 -2
  209. package/dist/pipeline/env-codes.cjs.map +1 -1
  210. package/dist/pipeline/env-codes.js +3 -2
  211. package/dist/pipeline/env-codes.js.map +1 -1
  212. package/dist/pipeline/perf-codes.cjs +1 -0
  213. package/dist/pipeline/perf-codes.cjs.map +1 -1
  214. package/dist/pipeline/perf-codes.js +1 -0
  215. package/dist/pipeline/perf-codes.js.map +1 -1
  216. package/dist/pipeline/row.cjs +8 -7
  217. package/dist/pipeline/row.cjs.map +1 -1
  218. package/dist/pipeline/row.js +8 -7
  219. package/dist/pipeline/row.js.map +1 -1
  220. package/dist/pipeline/runner.cjs +17 -9
  221. package/dist/pipeline/runner.cjs.map +1 -1
  222. package/dist/pipeline/runner.js +17 -9
  223. package/dist/pipeline/runner.js.map +1 -1
  224. package/dist/pipeline/slice.cjs +3 -1
  225. package/dist/pipeline/slice.cjs.map +1 -1
  226. package/dist/pipeline/slice.js +3 -1
  227. package/dist/pipeline/slice.js.map +1 -1
  228. package/dist/schema.d.cts +2 -2
  229. package/dist/schema.d.ts +2 -2
  230. package/dist/{search-async-entry-C3mXxLP8.d.cts → search-async-entry-CuLYPfY_.d.cts} +2 -2
  231. package/dist/{search-async-entry-BmQYT120.d.ts → search-async-entry-Cx7xpuVZ.d.ts} +2 -2
  232. package/dist/search-async.d.cts +3 -3
  233. package/dist/search-async.d.ts +3 -3
  234. package/dist/search.d.cts +8 -6
  235. package/dist/search.d.ts +8 -6
  236. package/dist/server.d.cts +3 -3
  237. package/dist/server.d.ts +3 -3
  238. package/dist/sorting.d.cts +6 -3
  239. package/dist/sorting.d.ts +6 -3
  240. package/dist/source/codes.cjs +1 -0
  241. package/dist/source/codes.cjs.map +1 -1
  242. package/dist/source/codes.js +1 -0
  243. package/dist/source/codes.js.map +1 -1
  244. package/dist/source/fetch-codes.cjs +1 -0
  245. package/dist/source/fetch-codes.cjs.map +1 -1
  246. package/dist/source/fetch-codes.js +1 -0
  247. package/dist/source/fetch-codes.js.map +1 -1
  248. package/dist/table/codes.cjs +1 -0
  249. package/dist/table/codes.cjs.map +1 -1
  250. package/dist/table/codes.js +1 -0
  251. package/dist/table/codes.js.map +1 -1
  252. package/dist/table/create-table.cjs +39 -9
  253. package/dist/table/create-table.cjs.map +1 -1
  254. package/dist/table/create-table.js +39 -9
  255. package/dist/table/create-table.js.map +1 -1
  256. package/dist/table/data-mutation.cjs +1 -0
  257. package/dist/table/data-mutation.cjs.map +1 -1
  258. package/dist/table/data-mutation.js +1 -0
  259. package/dist/table/data-mutation.js.map +1 -1
  260. package/dist/table/internals.cjs.map +1 -1
  261. package/dist/table/internals.js.map +1 -1
  262. package/dist/table/ssr-codes.cjs +1 -0
  263. package/dist/table/ssr-codes.cjs.map +1 -1
  264. package/dist/table/ssr-codes.js +1 -0
  265. package/dist/table/ssr-codes.js.map +1 -1
  266. package/dist/table/ssr.cjs +4 -1
  267. package/dist/table/ssr.cjs.map +1 -1
  268. package/dist/table/ssr.js +4 -1
  269. package/dist/table/ssr.js.map +1 -1
  270. package/dist/table/state-feedback.cjs +19 -0
  271. package/dist/table/state-feedback.cjs.map +1 -1
  272. package/dist/table/state-feedback.js +19 -0
  273. package/dist/table/state-feedback.js.map +1 -1
  274. package/dist/table/types.cjs.map +1 -1
  275. package/dist/table/types.js.map +1 -1
  276. package/dist/validity.d.cts +2 -2
  277. package/dist/validity.d.ts +2 -2
  278. package/dist/version.cjs +1 -1
  279. package/dist/version.cjs.map +1 -1
  280. package/dist/version.js +1 -1
  281. package/dist/version.js.map +1 -1
  282. package/dist/versioning/codes.cjs +18 -0
  283. package/dist/versioning/codes.cjs.map +1 -1
  284. package/dist/versioning/codes.js +18 -0
  285. package/dist/versioning/codes.js.map +1 -1
  286. package/dist/versioning/registry.cjs +4 -2
  287. package/dist/versioning/registry.cjs.map +1 -1
  288. package/dist/versioning/registry.js +4 -2
  289. package/dist/versioning/registry.js.map +1 -1
  290. package/package.json +39 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/features/search/skipped-codes.ts"],"sourcesContent":["import { defineDiagnostic } from '../../diagnostics/catalog'\nimport '../../diagnostics/process-guard'\n\n// Its own module, not `./codes`: `search()` imports it, and `./codes` registers DK_SEARCH_FAILED,\n// which only the `searchFn` engine (`search-engine.ts`) emits and keeps.\n\n/**\n * `DK_SEARCH_COLUMN_SKIPPED` (#27) is a development hint: with no column declaring a `search`\n * weight, a column of dates, arrays or other objects is not searched. Its definition is behind\n * `(process.env.NODE_ENV !== \"production\")`, so a production bundle has none of it.\n */\nexport const skippedColumnDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_SEARCH_COLUMN_SKIPPED',\n level: 'info',\n where: (d) => ({ kind: 'column', index: d.index, id: d.column }),\n problem: (d) =>\n `column \"${d.column}\" holds dates, arrays or other objects, and no column declares a ` +\n 'search weight: such a column is not searched (only strings, numbers and booleans are)',\n impact: () => 'search does not match the values of this column',\n fix: (d) => [\n `give it a search weight to search it: columns: [{ key: '${d.column}', search: 1 }, …], ` +\n 'and give one to every other column to search (once a column declares a weight, ' +\n 'only weighted columns are searched)',\n `to choose the text it matches, add format: (value) => string to columns[${d.index}] ` +\n '(by default dates match their toLocaleString(), arrays their items joined by \", \")',\n ],\n }),\n ]\n : []\n"],"mappings":";AAAA,SAAS,wBAAwB;AACjC,OAAO;AAUA,IAAM,2BAA4B,QAAQ,IAAI,aAAa,eAC9D;AAAA,EACE,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,UAAU,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO;AAAA,IAC9D,SAAS,CAAC,MACR,WAAW,EAAE,MAAM;AAAA,IAErB,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,2DAA2D,EAAE,MAAM;AAAA,MAGnE,2EAA2E,EAAE,KAAK;AAAA,IAEpF;AAAA,EACF,CAAC;AACH,IACA,CAAC;","names":[]}
@@ -26,6 +26,7 @@ __export(codes_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(codes_exports);
28
28
  var import_catalog = require("../../diagnostics/catalog.cjs");
29
+ var import_process_guard = require("../../diagnostics/process-guard.cjs");
29
30
  var REASON = {
30
31
  nan: "returned NaN",
31
32
  "not-number": "returned a non-number",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/features/sorting/codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../../diagnostics/catalog'\n\ndeclare module '../../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_SORT_STRATEGY: {\n /** The algorithm that sorted: `tim`, `radix`, `counting`, `native` or `custom`. */\n algorithm: string\n /** Why it was chosen (auto rule, override, or fallback). */\n reason: string\n /** Rows sorted. */\n n: number\n /** Time taken, in milliseconds (scan + sort). */\n ms: number\n /** The sort entries, e.g. `['age:desc']`. */\n by: readonly string[]\n /** The primary sort column (`where`), when it is in `options.columns`. */\n column?: { index: number; id: string }\n }\n DK_SORT_COMPARATOR_INVALID: {\n /** Column id. */\n column: string\n /** Position in `options.columns`. */\n index: number\n /** `nan`: returned NaN; `not-number`: returned a non-number; `inconsistent`: f(a, b) and f(b, a) disagree. */\n reason: 'nan' | 'not-number' | 'inconsistent'\n /** The type of the bad return (`not-number`), never the value. */\n received?: string\n }\n }\n}\n\nconst REASON = {\n nan: 'returned NaN',\n 'not-number': 'returned a non-number',\n inconsistent: 'is inconsistent: sortFn(a, b) and sortFn(b, a) do not have opposite signs',\n} as const\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const sortingMessages: DiagnosticMessages<'DK_SORT_STRATEGY'> = {\n DK_SORT_STRATEGY: {\n problem: (d) =>\n `sorted ${d.n} rows by ${d.by.join(', ')} with ${d.algorithm} in ${d.ms.toFixed(2)} ms ` +\n `(${d.reason})`,\n impact: () => 'none; reported because sorting({ debug: true }) is set',\n fix: () => [\n \"to force an algorithm: sorting({ algorithm: 'tim' | 'radix' | 'counting' | \" +\n \"'native' }) or a column's sortAlgorithm\",\n 'remove debug: true from sorting() to stop these reports',\n ],\n },\n}\n\n/**\n * Codes owned by the `sorting` feature (§6.4, §8.3). `DK_SORT_COMPARATOR_INVALID` is a dev check\n * (sampled): its definition is behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has none of it.\n */\nexport const sortingDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_SORT_STRATEGY',\n level: 'info',\n where: (d) =>\n d.column ? { kind: 'column', ...d.column } : { kind: 'feature', name: 'sorting' },\n },\n (process.env.NODE_ENV !== \"production\") && sortingMessages.DK_SORT_STRATEGY,\n ),\n]\n\nexport const comparatorDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_SORT_COMPARATOR_INVALID',\n level: 'warn',\n where: (d) => ({ kind: 'option', path: `columns[${d.index}].sortFn` }),\n problem: (d) =>\n `columns[${d.index}].sortFn (column \"${d.column}\") ${REASON[d.reason]}` +\n (d.received === undefined ? '' : ` (${d.received})`),\n impact: () => 'the column was sorted with the default comparator instead',\n fix: (d) => [\n d.reason === 'inconsistent'\n ? 'return a negative number when a < b, positive when a > b and 0 when equal, so that ' +\n 'sortFn(a, b) === -sortFn(b, a), e.g. (a, b) => a.rank - b.rank'\n : 'return a finite number from sortFn: negative (a first), positive (b first) or 0, ' +\n 'e.g. (a, b) => a.rank - b.rank',\n `or sort by a primitive key instead: columns[${d.index}].sortBy: (row) => row.<field>`,\n ],\n }),\n ]\n : []\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA0D;AA+B1D,IAAM,SAAS;AAAA,EACb,KAAK;AAAA,EACL,cAAc;AAAA,EACd,cAAc;AAChB;AAGO,IAAM,kBAA0D;AAAA,EACrE,kBAAkB;AAAA,IAChB,SAAS,CAAC,MACR,UAAU,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,QAC9E,EAAE,MAAM;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,MACT;AAAA,MAEA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,qBAAqB;AAAA,MAChC;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,MACN,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACpF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,gBAAgB;AAAA,EAC7D;AACF;AAEO,IAAM,wBAAyB,QAAQ,IAAI,aAAa,eAC3D;AAAA,MACE,iCAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,UAAU,MAAM,WAAW,EAAE,KAAK,WAAW;AAAA,IACpE,SAAS,CAAC,MACR,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,CAAC,MACpE,EAAE,aAAa,SAAY,KAAK,KAAK,EAAE,QAAQ;AAAA,IAClD,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,WAAW,iBACT,sJAEA;AAAA,MAEJ,+CAA+C,EAAE,KAAK;AAAA,IACxD;AAAA,EACF,CAAC;AACH,IACA,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/features/sorting/codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../../diagnostics/catalog'\nimport '../../diagnostics/process-guard'\n\ndeclare module '../../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_SORT_STRATEGY: {\n /** The algorithm that sorted: `tim`, `radix`, `counting`, `native` or `custom`. */\n algorithm: string\n /** Why it was chosen (auto rule, override, or fallback). */\n reason: string\n /** Rows sorted. */\n n: number\n /** Time taken, in milliseconds (scan + sort). */\n ms: number\n /** The sort entries, e.g. `['age:desc']`. */\n by: readonly string[]\n /** The primary sort column (`where`), when it is in `options.columns`. */\n column?: { index: number; id: string }\n }\n DK_SORT_COMPARATOR_INVALID: {\n /** Column id. */\n column: string\n /** Position in `options.columns`. */\n index: number\n /** `nan`: returned NaN; `not-number`: returned a non-number; `inconsistent`: f(a, b) and f(b, a) disagree. */\n reason: 'nan' | 'not-number' | 'inconsistent'\n /** The type of the bad return (`not-number`), never the value. */\n received?: string\n }\n }\n}\n\nconst REASON = {\n nan: 'returned NaN',\n 'not-number': 'returned a non-number',\n inconsistent: 'is inconsistent: sortFn(a, b) and sortFn(b, a) do not have opposite signs',\n} as const\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const sortingMessages: DiagnosticMessages<'DK_SORT_STRATEGY'> = {\n DK_SORT_STRATEGY: {\n problem: (d) =>\n `sorted ${d.n} rows by ${d.by.join(', ')} with ${d.algorithm} in ${d.ms.toFixed(2)} ms ` +\n `(${d.reason})`,\n impact: () => 'none; reported because sorting({ debug: true }) is set',\n fix: () => [\n \"to force an algorithm: sorting({ algorithm: 'tim' | 'radix' | 'counting' | \" +\n \"'native' }) or a column's sortAlgorithm\",\n 'remove debug: true from sorting() to stop these reports',\n ],\n },\n}\n\n/**\n * Codes owned by the `sorting` feature (§6.4, §8.3). `DK_SORT_COMPARATOR_INVALID` is a dev check\n * (sampled): its definition is behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has none of it.\n */\nexport const sortingDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_SORT_STRATEGY',\n level: 'info',\n where: (d) =>\n d.column ? { kind: 'column', ...d.column } : { kind: 'feature', name: 'sorting' },\n },\n (process.env.NODE_ENV !== \"production\") && sortingMessages.DK_SORT_STRATEGY,\n ),\n]\n\nexport const comparatorDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_SORT_COMPARATOR_INVALID',\n level: 'warn',\n where: (d) => ({ kind: 'option', path: `columns[${d.index}].sortFn` }),\n problem: (d) =>\n `columns[${d.index}].sortFn (column \"${d.column}\") ${REASON[d.reason]}` +\n (d.received === undefined ? '' : ` (${d.received})`),\n impact: () => 'the column was sorted with the default comparator instead',\n fix: (d) => [\n d.reason === 'inconsistent'\n ? 'return a negative number when a < b, positive when a > b and 0 when equal, so that ' +\n 'sortFn(a, b) === -sortFn(b, a), e.g. (a, b) => a.rank - b.rank'\n : 'return a finite number from sortFn: negative (a first), positive (b first) or 0, ' +\n 'e.g. (a, b) => a.rank - b.rank',\n `or sort by a primitive key instead: columns[${d.index}].sortBy: (row) => row.<field>`,\n ],\n }),\n ]\n : []\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA0D;AAC1D,2BAAO;AA+BP,IAAM,SAAS;AAAA,EACb,KAAK;AAAA,EACL,cAAc;AAAA,EACd,cAAc;AAChB;AAGO,IAAM,kBAA0D;AAAA,EACrE,kBAAkB;AAAA,IAChB,SAAS,CAAC,MACR,UAAU,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,QAC9E,EAAE,MAAM;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,MACT;AAAA,MAEA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,qBAAqB;AAAA,MAChC;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,MACN,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACpF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,gBAAgB;AAAA,EAC7D;AACF;AAEO,IAAM,wBAAyB,QAAQ,IAAI,aAAa,eAC3D;AAAA,MACE,iCAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,UAAU,MAAM,WAAW,EAAE,KAAK,WAAW;AAAA,IACpE,SAAS,CAAC,MACR,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,CAAC,MACpE,EAAE,aAAa,SAAY,KAAK,KAAK,EAAE,QAAQ;AAAA,IAClD,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,WAAW,iBACT,sJAEA;AAAA,MAEJ,+CAA+C,EAAE,KAAK;AAAA,IACxD;AAAA,EACF,CAAC;AACH,IACA,CAAC;","names":[]}
@@ -1,5 +1,6 @@
1
1
  // src/features/sorting/codes.ts
2
2
  import { defineDiagnostic } from "../../diagnostics/catalog.js";
3
+ import "../../diagnostics/process-guard.js";
3
4
  var REASON = {
4
5
  nan: "returned NaN",
5
6
  "not-number": "returned a non-number",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/features/sorting/codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../../diagnostics/catalog'\n\ndeclare module '../../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_SORT_STRATEGY: {\n /** The algorithm that sorted: `tim`, `radix`, `counting`, `native` or `custom`. */\n algorithm: string\n /** Why it was chosen (auto rule, override, or fallback). */\n reason: string\n /** Rows sorted. */\n n: number\n /** Time taken, in milliseconds (scan + sort). */\n ms: number\n /** The sort entries, e.g. `['age:desc']`. */\n by: readonly string[]\n /** The primary sort column (`where`), when it is in `options.columns`. */\n column?: { index: number; id: string }\n }\n DK_SORT_COMPARATOR_INVALID: {\n /** Column id. */\n column: string\n /** Position in `options.columns`. */\n index: number\n /** `nan`: returned NaN; `not-number`: returned a non-number; `inconsistent`: f(a, b) and f(b, a) disagree. */\n reason: 'nan' | 'not-number' | 'inconsistent'\n /** The type of the bad return (`not-number`), never the value. */\n received?: string\n }\n }\n}\n\nconst REASON = {\n nan: 'returned NaN',\n 'not-number': 'returned a non-number',\n inconsistent: 'is inconsistent: sortFn(a, b) and sortFn(b, a) do not have opposite signs',\n} as const\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const sortingMessages: DiagnosticMessages<'DK_SORT_STRATEGY'> = {\n DK_SORT_STRATEGY: {\n problem: (d) =>\n `sorted ${d.n} rows by ${d.by.join(', ')} with ${d.algorithm} in ${d.ms.toFixed(2)} ms ` +\n `(${d.reason})`,\n impact: () => 'none; reported because sorting({ debug: true }) is set',\n fix: () => [\n \"to force an algorithm: sorting({ algorithm: 'tim' | 'radix' | 'counting' | \" +\n \"'native' }) or a column's sortAlgorithm\",\n 'remove debug: true from sorting() to stop these reports',\n ],\n },\n}\n\n/**\n * Codes owned by the `sorting` feature (§6.4, §8.3). `DK_SORT_COMPARATOR_INVALID` is a dev check\n * (sampled): its definition is behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has none of it.\n */\nexport const sortingDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_SORT_STRATEGY',\n level: 'info',\n where: (d) =>\n d.column ? { kind: 'column', ...d.column } : { kind: 'feature', name: 'sorting' },\n },\n (process.env.NODE_ENV !== \"production\") && sortingMessages.DK_SORT_STRATEGY,\n ),\n]\n\nexport const comparatorDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_SORT_COMPARATOR_INVALID',\n level: 'warn',\n where: (d) => ({ kind: 'option', path: `columns[${d.index}].sortFn` }),\n problem: (d) =>\n `columns[${d.index}].sortFn (column \"${d.column}\") ${REASON[d.reason]}` +\n (d.received === undefined ? '' : ` (${d.received})`),\n impact: () => 'the column was sorted with the default comparator instead',\n fix: (d) => [\n d.reason === 'inconsistent'\n ? 'return a negative number when a < b, positive when a > b and 0 when equal, so that ' +\n 'sortFn(a, b) === -sortFn(b, a), e.g. (a, b) => a.rank - b.rank'\n : 'return a finite number from sortFn: negative (a first), positive (b first) or 0, ' +\n 'e.g. (a, b) => a.rank - b.rank',\n `or sort by a primitive key instead: columns[${d.index}].sortBy: (row) => row.<field>`,\n ],\n }),\n ]\n : []\n"],"mappings":";AAAA,SAAkC,wBAAwB;AA+B1D,IAAM,SAAS;AAAA,EACb,KAAK;AAAA,EACL,cAAc;AAAA,EACd,cAAc;AAChB;AAGO,IAAM,kBAA0D;AAAA,EACrE,kBAAkB;AAAA,IAChB,SAAS,CAAC,MACR,UAAU,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,QAC9E,EAAE,MAAM;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,MACT;AAAA,MAEA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,qBAAqB;AAAA,EAChC;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,MACN,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACpF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,gBAAgB;AAAA,EAC7D;AACF;AAEO,IAAM,wBAAyB,QAAQ,IAAI,aAAa,eAC3D;AAAA,EACE,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,UAAU,MAAM,WAAW,EAAE,KAAK,WAAW;AAAA,IACpE,SAAS,CAAC,MACR,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,CAAC,MACpE,EAAE,aAAa,SAAY,KAAK,KAAK,EAAE,QAAQ;AAAA,IAClD,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,WAAW,iBACT,sJAEA;AAAA,MAEJ,+CAA+C,EAAE,KAAK;AAAA,IACxD;AAAA,EACF,CAAC;AACH,IACA,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/features/sorting/codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../../diagnostics/catalog'\nimport '../../diagnostics/process-guard'\n\ndeclare module '../../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_SORT_STRATEGY: {\n /** The algorithm that sorted: `tim`, `radix`, `counting`, `native` or `custom`. */\n algorithm: string\n /** Why it was chosen (auto rule, override, or fallback). */\n reason: string\n /** Rows sorted. */\n n: number\n /** Time taken, in milliseconds (scan + sort). */\n ms: number\n /** The sort entries, e.g. `['age:desc']`. */\n by: readonly string[]\n /** The primary sort column (`where`), when it is in `options.columns`. */\n column?: { index: number; id: string }\n }\n DK_SORT_COMPARATOR_INVALID: {\n /** Column id. */\n column: string\n /** Position in `options.columns`. */\n index: number\n /** `nan`: returned NaN; `not-number`: returned a non-number; `inconsistent`: f(a, b) and f(b, a) disagree. */\n reason: 'nan' | 'not-number' | 'inconsistent'\n /** The type of the bad return (`not-number`), never the value. */\n received?: string\n }\n }\n}\n\nconst REASON = {\n nan: 'returned NaN',\n 'not-number': 'returned a non-number',\n inconsistent: 'is inconsistent: sortFn(a, b) and sortFn(b, a) do not have opposite signs',\n} as const\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const sortingMessages: DiagnosticMessages<'DK_SORT_STRATEGY'> = {\n DK_SORT_STRATEGY: {\n problem: (d) =>\n `sorted ${d.n} rows by ${d.by.join(', ')} with ${d.algorithm} in ${d.ms.toFixed(2)} ms ` +\n `(${d.reason})`,\n impact: () => 'none; reported because sorting({ debug: true }) is set',\n fix: () => [\n \"to force an algorithm: sorting({ algorithm: 'tim' | 'radix' | 'counting' | \" +\n \"'native' }) or a column's sortAlgorithm\",\n 'remove debug: true from sorting() to stop these reports',\n ],\n },\n}\n\n/**\n * Codes owned by the `sorting` feature (§6.4, §8.3). `DK_SORT_COMPARATOR_INVALID` is a dev check\n * (sampled): its definition is behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has none of it.\n */\nexport const sortingDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_SORT_STRATEGY',\n level: 'info',\n where: (d) =>\n d.column ? { kind: 'column', ...d.column } : { kind: 'feature', name: 'sorting' },\n },\n (process.env.NODE_ENV !== \"production\") && sortingMessages.DK_SORT_STRATEGY,\n ),\n]\n\nexport const comparatorDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_SORT_COMPARATOR_INVALID',\n level: 'warn',\n where: (d) => ({ kind: 'option', path: `columns[${d.index}].sortFn` }),\n problem: (d) =>\n `columns[${d.index}].sortFn (column \"${d.column}\") ${REASON[d.reason]}` +\n (d.received === undefined ? '' : ` (${d.received})`),\n impact: () => 'the column was sorted with the default comparator instead',\n fix: (d) => [\n d.reason === 'inconsistent'\n ? 'return a negative number when a < b, positive when a > b and 0 when equal, so that ' +\n 'sortFn(a, b) === -sortFn(b, a), e.g. (a, b) => a.rank - b.rank'\n : 'return a finite number from sortFn: negative (a first), positive (b first) or 0, ' +\n 'e.g. (a, b) => a.rank - b.rank',\n `or sort by a primitive key instead: columns[${d.index}].sortBy: (row) => row.<field>`,\n ],\n }),\n ]\n : []\n"],"mappings":";AAAA,SAAkC,wBAAwB;AAC1D,OAAO;AA+BP,IAAM,SAAS;AAAA,EACb,KAAK;AAAA,EACL,cAAc;AAAA,EACd,cAAc;AAChB;AAGO,IAAM,kBAA0D;AAAA,EACrE,kBAAkB;AAAA,IAChB,SAAS,CAAC,MACR,UAAU,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,QAC9E,EAAE,MAAM;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,MACT;AAAA,MAEA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,qBAAqB;AAAA,EAChC;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,MACN,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACpF;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,gBAAgB;AAAA,EAC7D;AACF;AAEO,IAAM,wBAAyB,QAAQ,IAAI,aAAa,eAC3D;AAAA,EACE,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,UAAU,MAAM,WAAW,EAAE,KAAK,WAAW;AAAA,IACpE,SAAS,CAAC,MACR,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,CAAC,MACpE,EAAE,aAAa,SAAY,KAAK,KAAK,EAAE,QAAQ;AAAA,IAClD,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,WAAW,iBACT,sJAEA;AAAA,MAEJ,+CAA+C,EAAE,KAAK;AAAA,IACxD;AAAA,EACF,CAAC;AACH,IACA,CAAC;","names":[]}
@@ -28,6 +28,7 @@ var import_options = require("../../catalog/options.cjs");
28
28
  var import_slots = require("../../catalog/slots.cjs");
29
29
  var import_get_value = require("../../column/get-value.cjs");
30
30
  var import_catalog = require("../../diagnostics/catalog.cjs");
31
+ var import_process_guard = require("../../diagnostics/process-guard.cjs");
31
32
  var import_define = require("../../feature/define.cjs");
32
33
  var import_cell_batch = require("../../intercept/cell-batch.cjs");
33
34
  var import_classify = require("../../intercept/classify.cjs");
@@ -49,6 +50,7 @@ var import_strategy = require("./strategy.cjs");
49
50
  import_codes.optionDiagnostics,
50
51
  import_env_codes.envDiagnostics
51
52
  );
53
+ var setSort = (ctx, by) => ctx.setState((s) => JSON.stringify(s.by) === JSON.stringify(by) ? s : { by: by.slice() });
52
54
  var validLocale = (v) => {
53
55
  try {
54
56
  Intl.getCanonicalLocales(v);
@@ -114,11 +116,11 @@ var sorting = (opts = {}) => {
114
116
  let collator;
115
117
  const getCollator = (emit) => {
116
118
  if (collator) return collator;
117
- const locale = opts.locale;
119
+ const locale = opts.locale ?? "en";
118
120
  let supported = true;
119
121
  try {
120
122
  collator = new Intl.Collator(locale, { numeric: true });
121
- supported = locale === void 0 || Intl.Collator.supportedLocalesOf(locale).length > 0;
123
+ supported = Intl.Collator.supportedLocalesOf(locale).length > 0;
122
124
  } catch {
123
125
  collator = new Intl.Collator(void 0, { numeric: true });
124
126
  supported = false;
@@ -127,8 +129,8 @@ var sorting = (opts = {}) => {
127
129
  emit("DK_ENV_FALLBACK", {
128
130
  api: "Intl.Collator",
129
131
  feature: "sorting",
130
- requested: [].concat(locale ?? []).join(", "),
131
- fallback: `the runtime's collation for "${collator.resolvedOptions().locale}"`
132
+ requested: [].concat(locale).join(", "),
133
+ fallback: `collation|${collator.resolvedOptions().locale}`
132
134
  });
133
135
  }
134
136
  return collator;
@@ -216,8 +218,8 @@ var sorting = (opts = {}) => {
216
218
  else out.splice(i, 1);
217
219
  return { by: out };
218
220
  }),
219
- setSorting: (by) => ctx.setState({ by: by.slice() }),
220
- clearSorting: () => ctx.setState({ by: [] }),
221
+ setSorting: (by) => setSort(ctx, by),
222
+ clearSorting: () => setSort(ctx, []),
221
223
  getSortDirection: (id) => {
222
224
  const e = ctx.getState().by.find((x) => x.id === id);
223
225
  return e ? e.desc ? "desc" : "asc" : false;
@@ -258,9 +260,7 @@ var sorting = (opts = {}) => {
258
260
  fromColumn ? { path: `columns[${primary.col?.index}].sortAlgorithm`, reason: reason2, once: false } : { path: "algorithm", feature: "sorting", reason: reason2, once: false }
259
261
  );
260
262
  if (typeof requested !== "function" && !ALGORITHMS.includes(requested)) {
261
- noEffect(
262
- `${JSON.stringify(requested)} is not a sort algorithm (accepted: ${ALGORITHMS.join(", ")}, or a function); auto was used`
263
- );
263
+ noEffect(`not-algorithm|${JSON.stringify(requested)}`);
264
264
  requested = "auto";
265
265
  }
266
266
  if (requested !== "native" && exsorted === void 0) {
@@ -324,7 +324,7 @@ var sorting = (opts = {}) => {
324
324
  } catch (error) {
325
325
  if (error instanceof SortFnFailed) throw error;
326
326
  reportCustom(true, error);
327
- return native("the custom algorithm threw");
327
+ return native("custom-threw");
328
328
  }
329
329
  if (res instanceof Uint32Array && res.length === indices.length) {
330
330
  algorithm = "custom";
@@ -332,7 +332,7 @@ var sorting = (opts = {}) => {
332
332
  return res;
333
333
  }
334
334
  reportCustom(false, res);
335
- return native("the custom algorithm returned a bad value");
335
+ return native("custom-bad");
336
336
  }
337
337
  if (exsorted === false) return native("exsorted unavailable");
338
338
  const by2 = fromColumn ? "column sortAlgorithm" : "sorting({ algorithm })";
@@ -343,17 +343,13 @@ var sorting = (opts = {}) => {
343
343
  try {
344
344
  const out = (0, import_strategy.sortIntKeys)(keys, want);
345
345
  algorithm = want;
346
- reason = `${by2}, safe-integer keys`;
346
+ reason = `int-keys|${by2}`;
347
347
  return out;
348
348
  } catch {
349
- noEffect(
350
- `exsorted ${want}Sort could not sort these keys` + (want === "counting" ? " (key range above 1,000,000)" : "") + "; auto was used"
351
- );
349
+ noEffect(`exsorted-${want === "counting" ? "range" : "failed"}|${want}`);
352
350
  }
353
351
  } else if ((0, import_strategy.needsIntKeys)(want)) {
354
- noEffect(
355
- `${want} sorts a single column of safe integer keys (numbers or Dates, no sortFn); auto was used`
356
- );
352
+ noEffect(`needs-int-keys|${want}`);
357
353
  } else {
358
354
  algorithm = want;
359
355
  reason = by2;
@@ -362,22 +358,22 @@ var sorting = (opts = {}) => {
362
358
  } else if (want === "native") return native(by2);
363
359
  if (!keys) {
364
360
  return native(
365
- single ? "keys are not all safe integers" : entries.length > 1 ? "multi-column" : "custom sortFn"
361
+ single ? "not-safe-int" : entries.length > 1 ? "multi-column" : "custom sortFn"
366
362
  );
367
363
  }
368
364
  const choice = (0, import_strategy.chooseAuto)(keys);
369
365
  algorithm = choice.algorithm;
370
- reason = `auto: ${ranked ? "collation ranks of a string column, " : ""}${choice.reason}`;
366
+ reason = `auto-${ranked ? "ranked-" : ""}${choice.reason}`;
371
367
  return (0, import_strategy.sortIntKeys)(keys, choice.algorithm);
372
368
  };
373
369
  const native = (why) => {
374
370
  algorithm = "native";
375
- reason = ranked ? `${why}, strings as collation ranks` : why;
371
+ reason = ranked ? `ranks|${why}` : why;
376
372
  return (0, import_strategy.sortWithComparator)(indices, build(), "native");
377
373
  };
378
374
  const reportCustom = (threw, value) => {
379
375
  const slot = fromColumn ? `columns[${primary.col?.index}].sortAlgorithm` : "sorting.algorithm";
380
- const fallback = "the rows were sorted with the native algorithm";
376
+ const fallback = "sorted-native";
381
377
  if (!threw) {
382
378
  if (process.env.NODE_ENV !== "production") {
383
379
  ctx.emit("DK_CALLBACK_BAD_RETURN", {
@@ -429,7 +425,7 @@ var sorting = (opts = {}) => {
429
425
  slot: `columns[${col.index}].sortFn`,
430
426
  column: col.id,
431
427
  count: 1,
432
- fallback: "the column was sorted with the default comparator",
428
+ fallback: "sorted-default",
433
429
  ...name === void 0 ? {} : { errorName: name }
434
430
  },
435
431
  { cause: e.error }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/features/sorting/sorting.ts"],"sourcesContent":["import { optionDiagnostics } from '../../catalog/codes'\nimport { defineOptions } from '../../catalog/options'\nimport { describeReturn } from '../../catalog/slots'\nimport type { SortAlgorithm } from '../../column/column-def'\nimport { compilePath, getValue } from '../../column/get-value'\nimport type { Path } from '../../column/path'\nimport { keepDiagnostics } from '../../diagnostics/catalog'\nimport type { Emit } from '../../diagnostics/types'\nimport { defineFeature } from '../../feature/define'\nimport type { FeatureTypes, RowModelContext } from '../../feature/types'\nimport { CellFailures } from '../../intercept/cell-batch'\nimport { errorName } from '../../intercept/classify'\nimport { boundaryDiagnostics } from '../../intercept/codes'\nimport { type ResolvedColumn, resolveColumns } from '../../pipeline/columns'\nimport { envDiagnostics } from '../../pipeline/env-codes'\nimport { allRows } from '../../pipeline/indices'\nimport { sliced } from '../../pipeline/slice'\nimport type { ColumnValues } from '../../pipeline/types'\nimport { type DataMode, modeOption } from '../../source/mode'\nimport { detectCapability, hasCapability } from '../../versioning/capability'\nimport { comparatorDiagnostics, sortingDiagnostics } from './codes'\nimport {\n defaultIndexComparator,\n type IndexComparator,\n RANK,\n sortFnIndexComparator,\n typeRank,\n} from './compare'\nimport { collationRanks } from './ranks'\nimport {\n chooseAuto,\n hasExsorted,\n intKeys,\n needsIntKeys,\n sortIntKeys,\n sortWithComparator,\n} from './strategy'\n\nkeepDiagnostics(\n sortingDiagnostics,\n comparatorDiagnostics,\n boundaryDiagnostics,\n optionDiagnostics,\n envDiagnostics,\n)\n\n/** One sort key: a column id (a path of the row type) and its direction. */\nexport type SortEntry<T> = { id: Path<T>; desc: boolean }\n\n/** The `sorting` slice (§6.4): multi-column, earlier entries first. Empty = unsorted. */\nexport type SortingState<T> = { by: readonly SortEntry<T>[] }\n\nexport type SortDirection = 'asc' | 'desc'\n\nexport type SortingApi<T> = {\n /**\n * Cycles `id` asc → desc → none. Without `multi` the result is a single-column sort; with `multi`\n * (Shift+click) `id` is appended, cycled in place or removed and the other entries are kept.\n */\n toggleSort(id: Path<T>, options?: { multi?: boolean }): void\n /** Replaces the whole sort. */\n setSorting(by: readonly SortEntry<T>[]): void\n /** Removes every sort entry (input order). */\n clearSorting(): void\n /** `id`'s direction in the current sort, or `false` (for `aria-sort`). */\n getSortDirection(id: Path<T>): SortDirection | false\n}\n\nexport interface SortingTypes extends FeatureTypes {\n state: SortingState<this['T']>\n api: SortingApi<this['T']>\n}\n\n/**\n * How rows are sorted (§6.4): `'auto'` (default) picks per sort from one O(n) scan — exsorted\n * tim / counting / radix for a single column of safe-integer keys (numbers, `Date`s), native\n * `Array.prototype.sort` otherwise. A built-in name forces that algorithm (radix / counting only\n * apply to safe-integer keys); a function sorts the row indices itself.\n */\nexport type SortAlgorithmOption = SortAlgorithm\n\nexport interface SortingOptions {\n /** Locale(s) of the string collator (`Intl.Collator(locale, { numeric: true })`); default: the runtime's. */\n locale?: string | readonly string[]\n /** The sort algorithm (default `'auto'`); a column's `sortAlgorithm` takes precedence. */\n algorithm?: SortAlgorithmOption\n /** Reports the algorithm chosen for each sort, why, n and the time taken (`DK_SORT_STRATEGY`). */\n debug?: boolean\n /**\n * `'server'`: the server sorts (its state goes to `options.fetcher`, or the app fetches); core\n * skips this step (§7.1). Default `'client'`.\n */\n mode?: DataMode\n}\n\nconst validLocale = (v: unknown) => {\n try {\n Intl.getCanonicalLocales(v as string | string[])\n return true\n } catch {\n return false\n }\n}\n\nconst ALGORITHMS = ['auto', 'tim', 'radix', 'counting', 'native'] as const\n\nconst sortingOptions = {\n locale: {\n type: ['string', 'array'],\n check: validLocale,\n expected: 'a BCP 47 locale tag or a list of them, e.g. \"th\" or [\"th\", \"en\"]',\n },\n algorithm: {\n type: ['string', 'function'],\n oneOf: ALGORITHMS,\n // A literal (not built from ALGORITHMS): a module-level call would keep the schema in production.\n expected:\n \"one of 'auto', 'tim', 'radix', 'counting', 'native', or (indices, compare) => indices\",\n },\n debug: { type: 'boolean' },\n mode: modeOption,\n} as const\n\ntype CustomAlgorithm = Extract<SortAlgorithm, (...args: never[]) => unknown>\n\nconst now = () => (typeof performance === 'undefined' ? Date.now() : performance.now())\n\n/**\n * From this many rows, `auto` sorts a string column by precomputed collation ranks (§9.1): one\n * time-sliced job per column values, then integer-key sorts (a few ms at 100k rows) instead of a\n * collator call per comparison (~100–200 ms at 100k, one long task).\n */\nconst RANKS_MIN = 10_000\n\nconst missing = (v: unknown) => typeRank(v) === RANK.missing\n\n/**\n * Dev check of a column's `sortFn` (§8.3 `DK_SORT_COMPARATOR_INVALID`), sampled: up to 8 present\n * values spread over the input, every pair both ways. A throw gives no verdict (the sort reports\n * it as `DK_CALLBACK_FAILED`).\n */\nfunction checkSortFn(\n fn: SortFn,\n values: ColumnValues,\n indices: Uint32Array,\n): { reason: 'nan' | 'not-number' | 'inconsistent'; received?: string } | undefined {\n const sample: unknown[] = []\n const step = Math.max(1, Math.floor(indices.length / 8))\n for (let i = 0; i < indices.length && sample.length < 8; i += step) {\n const v = values[indices[i] as number]\n if (!missing(v)) sample.push(v)\n }\n try {\n for (let i = 0; i < sample.length; i++) {\n for (let j = i; j < sample.length; j++) {\n const x = fn(sample[i], sample[j])\n const y = fn(sample[j], sample[i])\n for (const r of [x, y]) {\n if (typeof r !== 'number') return { reason: 'not-number', received: describeReturn(r) }\n if (Number.isNaN(r)) return { reason: 'nan' }\n }\n if (Math.sign(x) !== -Math.sign(y)) return { reason: 'inconsistent' }\n }\n }\n } catch {\n return undefined\n }\n return undefined\n}\n\ntype SortFn = (a: unknown, b: unknown) => number\ntype SortBy = (row: unknown) => unknown\n\nconst fnField = (def: object, field: 'sortFn' | 'sortBy') => {\n const f = (def as Record<string, unknown>)[field]\n return typeof f === 'function' ? f : undefined\n}\n\n/** Aborts a native sort when a column's `sortFn` throws (the entry then falls back). */\nclass SortFnFailed {\n constructor(\n readonly entry: number,\n readonly error: unknown,\n ) {}\n}\n\n/**\n * Sorting (§6.4): `toggleSort` (asc → desc → none, `multi`), stable sort of the row indices with\n * the default comparator — missing values (`null`, `undefined`, `NaN`, invalid `Date`) last in both\n * directions, mixed types by type rank, strings with one `Intl.Collator(locale, { numeric: true })`\n * — or a column's `sortFn` / `sortBy`. Never touches the data: a copy of the index array is sorted.\n *\n * `algorithm: 'auto'` (default) picks per sort from one O(n) scan (§6.4): exsorted tim / counting /\n * radix for a single column of safe-integer keys (numbers, `Date`s), native `Array.prototype.sort`\n * (stable) for strings, floats, multi-column and `sortFn`. Every choice gives the same stable order.\n * `sorting({ algorithm })` or a column's `sortAlgorithm` overrides it; `debug: true` reports each\n * choice (`DK_SORT_STRATEGY`).\n */\nexport const sorting = (opts: SortingOptions = {}) => {\n let collator: Intl.Collator | undefined\n /** The collator; `DK_ENV_FALLBACK` when the runtime supports none of the requested locales. */\n const getCollator = (emit: Emit) => {\n if (collator) return collator\n const locale = opts.locale as string | string[] | undefined\n let supported = true\n try {\n collator = new Intl.Collator(locale, { numeric: true })\n supported = locale === undefined || Intl.Collator.supportedLocalesOf(locale).length > 0\n } catch {\n collator = new Intl.Collator(undefined, { numeric: true })\n supported = false\n }\n if (!supported) {\n emit('DK_ENV_FALLBACK', {\n api: 'Intl.Collator',\n feature: 'sorting',\n requested: ([] as string[]).concat(locale ?? []).join(', '),\n fallback: `the runtime's collation for \"${collator.resolvedOptions().locale}\"`,\n })\n }\n return collator\n }\n\n /** Values array → the key of its collation-ranks job (`ctx.slice`); released with the values. */\n const rankKeys = new WeakMap<object, object>()\n function ranksFor(ctx: RowModelContext, values: readonly unknown[]) {\n let key = rankKeys.get(values)\n if (!key) {\n key = {}\n rankKeys.set(values, key)\n }\n const c = getCollator(ctx.emit)\n return sliced(ctx, key, () => collationRanks(values, c))\n }\n /** The last sorted output and its input: the stand-in while ranks are computed (§9.1). */\n let shown: { input: Uint32Array; output: Uint32Array } | undefined\n\n // Values that the column cache does not hold, per data reference (released with it).\n const sortByCache = new WeakMap<readonly unknown[], WeakMap<object, unknown[]>>()\n const pathCache = new WeakMap<readonly unknown[], Map<string, unknown[]>>()\n /** exsorted feature detection (§8.5), once per feature instance, on the first sort needing it. */\n let exsorted: boolean | undefined\n\n /** `sortBy` failures (§3.4): numbers only; text is built only when a cell failed. */\n const sortByFailures = new CellFailures()\n\n /**\n * `sortBy` is a cell slot: one `column:batch` per column per data reference, an inline\n * `try/catch` per row. A failed row (or a batch an interceptor skipped) keys as `undefined`,\n * which sorts last.\n */\n function sortByValues(ctx: RowModelContext, col: ResolvedColumn, sortBy: SortBy): unknown[] {\n const data = ctx.data\n let byDef = sortByCache.get(data)\n if (!byDef) {\n byDef = new WeakMap()\n sortByCache.set(data, byDef)\n }\n let out = byDef.get(col.def)\n if (out) return out\n const values: unknown[] = new Array(data.length).fill(undefined)\n const rows = allRows(data)\n sortByFailures.reset()\n ctx.batch(col.id, 'sortBy', rows, () => {\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i] as number\n try {\n values[r] = sortBy(data[r])\n } catch (e) {\n sortByFailures.add(r, e)\n }\n }\n sortByFailures.report(ctx.emit, col.index, col.id, 'sortBy')\n })\n sortByFailures.reset()\n out = values\n byDef.set(col.def, out)\n return out\n }\n\n function pathValues(ctx: RowModelContext, id: string): unknown[] {\n const data = ctx.data\n let byId = pathCache.get(data)\n if (!byId) {\n byId = new Map()\n pathCache.set(data, byId)\n }\n let out = byId.get(id)\n if (out) return out\n const path = compilePath(id)\n out = new Array(data.length)\n for (let r = 0; r < data.length; r++) out[r] = getValue(data[r], path)\n byId.set(id, out)\n return out\n }\n\n return defineFeature<'sorting', SortingTypes>({\n name: 'sorting',\n stage: 'sort',\n mode: opts.mode ?? 'client',\n options: defineOptions(\n // The option validator runs in development only (§9.3): production drops the schema.\n (process.env.NODE_ENV !== \"production\") ? sortingOptions : ({} as typeof sortingOptions),\n opts,\n ),\n initialState: () => ({ by: [] }),\n // After destroy(): still a declared value (`aria-sort` reads it during teardown renders).\n destroyedResult: { getSortDirection: () => false },\n createApi: (ctx) => ({\n toggleSort: (id, options) =>\n ctx.setState((s) => {\n const by = s.by\n const i = by.findIndex((e) => e.id === id)\n const cur = by[i]\n const next = !cur ? { id, desc: false } : cur.desc ? undefined : { id, desc: true }\n if (!options?.multi) return { by: next ? [next] : [] }\n if (!cur) return { by: [...by, next as SortEntry<unknown>] }\n const out = by.slice()\n if (next) out[i] = next\n else out.splice(i, 1)\n return { by: out }\n }),\n setSorting: (by) => ctx.setState({ by: by.slice() }),\n clearSorting: () => ctx.setState({ by: [] }),\n getSortDirection: (id) => {\n const e = ctx.getState().by.find((x) => x.id === id)\n return e ? (e.desc ? 'desc' : 'asc') : false\n },\n }),\n rowModel: (indices, state, ctx) => {\n const by = state?.by\n if (!by || by.length === 0 || indices.length < 2) {\n shown = undefined\n return indices\n }\n const t0 = opts.debug ? now() : 0\n const cols = resolveColumns(ctx.columns)\n const entries = by.map((e) => {\n const id = String(e.id)\n const col = cols.byId.get(id)\n const sortBy = col && (fnField(col.def, 'sortBy') as SortBy | undefined)\n const values: ColumnValues = sortBy\n ? sortByValues(ctx, col, sortBy)\n : (ctx.getColumnValues(id) ?? pathValues(ctx, id))\n const sortFn =\n col && !sortBy ? (fnField(col.def, 'sortFn') as SortFn | undefined) : undefined\n return { col, desc: e.desc === true, values, sortFn, ranked: false }\n })\n\n // Dev (§8.3): a sampled sortFn check; an invalid one falls back to the default comparator.\n if ((process.env.NODE_ENV !== \"production\")) {\n for (const e of entries) {\n if (!e.sortFn) continue\n const bad = checkSortFn(e.sortFn, e.values, indices)\n if (!bad) continue\n e.sortFn = undefined\n const col = e.col as ResolvedColumn\n ctx.emit('DK_SORT_COMPARATOR_INVALID', { column: col.id, index: col.index, ...bad })\n }\n }\n\n // The requested algorithm: the primary column's `sortAlgorithm`, else the table's.\n const primary = entries[0] as (typeof entries)[number]\n const colAlgorithm =\n primary.col && (primary.col.def as { sortAlgorithm?: unknown }).sortAlgorithm\n const fromColumn = colAlgorithm !== undefined\n let requested = (fromColumn ? colAlgorithm : (opts.algorithm ?? 'auto')) as SortAlgorithm\n const noEffect = (reason: string) =>\n ctx.emit(\n 'DK_OPTION_NO_EFFECT',\n fromColumn\n ? { path: `columns[${primary.col?.index}].sortAlgorithm`, reason, once: false }\n : { path: 'algorithm', feature: 'sorting', reason, once: false },\n )\n if (\n typeof requested !== 'function' &&\n !(ALGORITHMS as readonly unknown[]).includes(requested)\n ) {\n noEffect(\n `${JSON.stringify(requested)} is not a sort algorithm (accepted: ${ALGORITHMS.join(', ')}, ` +\n 'or a function); auto was used',\n )\n requested = 'auto'\n }\n if (requested !== 'native' && exsorted === undefined) {\n // DK_DEP_INCOMPATIBLE is a development check (§8.5); the fallback is not.\n exsorted = (process.env.NODE_ENV !== \"production\")\n ? detectCapability(\n hasExsorted,\n {\n feature: 'sorting',\n dependency: 'exsorted',\n capability: 'timSort / radixSort / countingSort',\n supported: '^1.2.3',\n fallback: 'Array.prototype.sort (native, stable)',\n },\n ctx.emit,\n )\n : hasCapability(hasExsorted)\n }\n\n // auto at large n (§9.1): string columns sort by collation ranks, computed by a sliced job.\n if (requested === 'auto' && indices.length >= RANKS_MIN) {\n let computing = false\n for (const e of entries) {\n if (e.sortFn || e.values instanceof Float64Array) continue\n const ranks = ranksFor(ctx, e.values)\n if (ranks === undefined) computing = true\n else if (ranks) {\n e.values = ranks\n e.ranked = true\n }\n }\n // Meanwhile: the previous order of these rows (or the input order); 'pending'.\n if (computing) return shown && shown.input === indices ? shown.output : indices\n }\n const ranked = entries.some((e) => e.ranked)\n\n const build = (): IndexComparator => {\n const cmps = entries.map((e, k) => {\n const fn = e.sortFn\n if (!fn) return defaultIndexComparator(e.values, e.desc, getCollator(ctx.emit))\n const guarded: SortFn = (a, b) => {\n try {\n return fn(a, b)\n } catch (error) {\n throw new SortFnFailed(k, error)\n }\n }\n return sortFnIndexComparator(e.values, e.desc, guarded)\n })\n if (cmps.length === 1) return cmps[0] as IndexComparator\n return (a, b) => {\n for (let k = 0; k < cmps.length; k++) {\n const c = (cmps[k] as IndexComparator)(a, b)\n if (c !== 0) return c\n }\n return 0\n }\n }\n\n let algorithm: string = 'native'\n let reason = ''\n /** One attempt; a throwing sortFn propagates as SortFnFailed (the loop below retries). */\n const sortOnce = (): Uint32Array => {\n const want = requested\n if (typeof want === 'function') {\n const custom = want as CustomAlgorithm\n let res: unknown\n try {\n res = custom(indices.slice(), build())\n } catch (error) {\n if (error instanceof SortFnFailed) throw error\n reportCustom(true, error)\n return native('the custom algorithm threw')\n }\n if (res instanceof Uint32Array && res.length === indices.length) {\n algorithm = 'custom'\n reason = fromColumn ? 'column sortAlgorithm' : 'sorting({ algorithm })'\n return res\n }\n reportCustom(false, res)\n return native('the custom algorithm returned a bad value')\n }\n if (exsorted === false) return native('exsorted unavailable')\n const by = fromColumn ? 'column sortAlgorithm' : 'sorting({ algorithm })'\n // Integer keys: a single column with the default comparator (§6.4).\n const single = entries.length === 1 && !primary.sortFn\n const keys =\n single && want !== 'native' ? intKeys(primary.values, indices, primary.desc) : undefined\n if (want !== 'auto' && want !== 'native') {\n if (keys) {\n try {\n const out = sortIntKeys(keys, want)\n algorithm = want\n reason = `${by}, safe-integer keys`\n return out\n } catch {\n noEffect(\n `exsorted ${want}Sort could not sort these keys` +\n (want === 'counting' ? ' (key range above 1,000,000)' : '') +\n '; auto was used',\n )\n }\n } else if (needsIntKeys(want)) {\n noEffect(\n `${want} sorts a single column of safe integer keys (numbers or Dates, no sortFn); ` +\n 'auto was used',\n )\n } else {\n algorithm = want\n reason = by\n return sortWithComparator(indices, build(), want as 'tim')\n }\n } else if (want === 'native') return native(by)\n if (!keys) {\n return native(\n single\n ? 'keys are not all safe integers'\n : entries.length > 1\n ? 'multi-column'\n : 'custom sortFn',\n )\n }\n const choice = chooseAuto(keys)\n algorithm = choice.algorithm\n reason = `auto: ${ranked ? 'collation ranks of a string column, ' : ''}${choice.reason}`\n return sortIntKeys(keys, choice.algorithm)\n }\n const native = (why: string) => {\n algorithm = 'native'\n reason = ranked ? `${why}, strings as collation ranks` : why\n return sortWithComparator(indices, build(), 'native')\n }\n /** A custom algorithm threw (`threw`, `value` = the error) or returned a bad `value`. */\n const reportCustom = (threw: boolean, value: unknown) => {\n const slot = fromColumn\n ? `columns[${primary.col?.index}].sortAlgorithm`\n : 'sorting.algorithm'\n const fallback = 'the rows were sorted with the native algorithm'\n if (!threw) {\n // The slot contract check is dev only (§3.4 slotContract); the fallback applies always.\n if ((process.env.NODE_ENV !== \"production\")) {\n ctx.emit('DK_CALLBACK_BAD_RETURN', {\n slot,\n expected: `a Uint32Array of ${indices.length} row indices`,\n received: describeReturn(value),\n count: 1,\n fallback,\n })\n }\n return\n }\n const name = errorName(value)\n ctx.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot,\n count: 1,\n fallback,\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: value },\n )\n }\n\n // At most one retry per entry: each failing sortFn falls back to the default comparator.\n for (;;) {\n try {\n const out = sortOnce()\n if (opts.debug) {\n ctx.emit('DK_SORT_STRATEGY', {\n algorithm,\n reason,\n n: indices.length,\n ms: now() - t0,\n by: by.map((e) => `${String(e.id)}:${e.desc ? 'desc' : 'asc'}`),\n ...(primary.col ? { column: { index: primary.col.index, id: primary.col.id } } : {}),\n })\n }\n shown = { input: indices, output: out }\n return out\n } catch (e) {\n if (!(e instanceof SortFnFailed)) throw e\n const entry = entries[e.entry] as (typeof entries)[number]\n entry.sortFn = undefined\n const col = entry.col as ResolvedColumn\n const name = errorName(e.error)\n ctx.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].sortFn`,\n column: col.id,\n count: 1,\n fallback: 'the column was sorted with the default comparator',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e.error },\n )\n }\n }\n },\n })\n}\n"],"mappings":"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","names":["import_codes","reason","by"]}
1
+ {"version":3,"sources":["../../../src/features/sorting/sorting.ts"],"sourcesContent":["import { optionDiagnostics } from '../../catalog/codes'\nimport { defineOptions } from '../../catalog/options'\nimport { describeReturn } from '../../catalog/slots'\nimport type { SortAlgorithm } from '../../column/column-def'\nimport { compilePath, getValue } from '../../column/get-value'\nimport type { Path } from '../../column/path'\nimport { keepDiagnostics } from '../../diagnostics/catalog'\nimport '../../diagnostics/process-guard'\nimport type { Emit } from '../../diagnostics/types'\nimport { defineFeature } from '../../feature/define'\nimport type { FeatureTypes, RowModelContext } from '../../feature/types'\nimport { CellFailures } from '../../intercept/cell-batch'\nimport { errorName } from '../../intercept/classify'\nimport { boundaryDiagnostics } from '../../intercept/codes'\nimport { type ResolvedColumn, resolveColumns } from '../../pipeline/columns'\nimport { envDiagnostics } from '../../pipeline/env-codes'\nimport { allRows } from '../../pipeline/indices'\nimport { sliced } from '../../pipeline/slice'\nimport type { ColumnValues } from '../../pipeline/types'\nimport { type DataMode, modeOption } from '../../source/mode'\nimport { detectCapability, hasCapability } from '../../versioning/capability'\nimport { comparatorDiagnostics, sortingDiagnostics } from './codes'\nimport {\n defaultIndexComparator,\n type IndexComparator,\n RANK,\n sortFnIndexComparator,\n typeRank,\n} from './compare'\nimport { collationRanks } from './ranks'\nimport {\n chooseAuto,\n hasExsorted,\n intKeys,\n needsIntKeys,\n sortIntKeys,\n sortWithComparator,\n} from './strategy'\n\nkeepDiagnostics(\n sortingDiagnostics,\n comparatorDiagnostics,\n boundaryDiagnostics,\n optionDiagnostics,\n envDiagnostics,\n)\n\n/** One sort key: a column id (a path of the row type) and its direction. */\nexport type SortEntry<T> = { id: Path<T>; desc: boolean }\n\n/** The `sorting` slice (§6.4): multi-column, earlier entries first. Empty = unsorted. */\nexport type SortingState<T> = { by: readonly SortEntry<T>[] }\n\nexport type SortDirection = 'asc' | 'desc'\n\n/** Replaces the sort; an equal one keeps the slice (same reference, no notification, #21). */\nconst setSort = (\n ctx: { setState(u: (s: SortingState<unknown>) => SortingState<unknown>): void },\n by: readonly SortEntry<unknown>[],\n) => ctx.setState((s) => (JSON.stringify(s.by) === JSON.stringify(by) ? s : { by: by.slice() }))\n\nexport type SortingApi<T> = {\n /**\n * Cycles `id` asc → desc → none. Without `multi` the result is a single-column sort; with `multi`\n * (Shift+click) `id` is appended, cycled in place or removed and the other entries are kept.\n */\n toggleSort(id: Path<T>, options?: { multi?: boolean }): void\n /** Replaces the whole sort. */\n setSorting(by: readonly SortEntry<T>[]): void\n /** Removes every sort entry (input order). */\n clearSorting(): void\n /** `id`'s direction in the current sort, or `false` (for `aria-sort`). */\n getSortDirection(id: Path<T>): SortDirection | false\n}\n\nexport interface SortingTypes extends FeatureTypes {\n state: SortingState<this['T']>\n api: SortingApi<this['T']>\n}\n\n/**\n * How rows are sorted (§6.4): `'auto'` (default) picks per sort from one O(n) scan — exsorted\n * tim / counting / radix for a single column of safe-integer keys (numbers, `Date`s), native\n * `Array.prototype.sort` otherwise. A built-in name forces that algorithm (radix / counting only\n * apply to safe-integer keys); a function sorts the row indices itself.\n */\nexport type SortAlgorithmOption = SortAlgorithm\n\nexport interface SortingOptions {\n /**\n * Locale(s) of the string collator (`Intl.Collator(locale, { numeric: true })`). Default `'en'`,\n * not the runtime's: the server and the browser must sort alike (SSR hydration, #12).\n */\n locale?: string | readonly string[]\n /** The sort algorithm (default `'auto'`); a column's `sortAlgorithm` takes precedence. */\n algorithm?: SortAlgorithmOption\n /** Reports the algorithm chosen for each sort, why, n and the time taken (`DK_SORT_STRATEGY`). */\n debug?: boolean\n /**\n * `'server'`: the server sorts (its state goes to `options.fetcher`, or the app fetches); core\n * skips this step (§7.1). Default `'client'`.\n */\n mode?: DataMode\n}\n\nconst validLocale = (v: unknown) => {\n try {\n Intl.getCanonicalLocales(v as string | string[])\n return true\n } catch {\n return false\n }\n}\n\nconst ALGORITHMS = ['auto', 'tim', 'radix', 'counting', 'native'] as const\n\nconst sortingOptions = {\n locale: {\n type: ['string', 'array'],\n check: validLocale,\n expected: 'a BCP 47 locale tag or a list of them, e.g. \"th\" or [\"th\", \"en\"]',\n },\n algorithm: {\n type: ['string', 'function'],\n oneOf: ALGORITHMS,\n // A literal (not built from ALGORITHMS): a module-level call would keep the schema in production.\n expected:\n \"one of 'auto', 'tim', 'radix', 'counting', 'native', or (indices, compare) => indices\",\n },\n debug: { type: 'boolean' },\n mode: modeOption,\n} as const\n\ntype CustomAlgorithm = Extract<SortAlgorithm, (...args: never[]) => unknown>\n\nconst now = () => (typeof performance === 'undefined' ? Date.now() : performance.now())\n\n/**\n * From this many rows, `auto` sorts a string column by precomputed collation ranks (§9.1): one\n * time-sliced job per column values, then integer-key sorts (a few ms at 100k rows) instead of a\n * collator call per comparison (~100–200 ms at 100k, one long task).\n */\nconst RANKS_MIN = 10_000\n\nconst missing = (v: unknown) => typeRank(v) === RANK.missing\n\n/**\n * Dev check of a column's `sortFn` (§8.3 `DK_SORT_COMPARATOR_INVALID`), sampled: up to 8 present\n * values spread over the input, every pair both ways. A throw gives no verdict (the sort reports\n * it as `DK_CALLBACK_FAILED`).\n */\nfunction checkSortFn(\n fn: SortFn,\n values: ColumnValues,\n indices: Uint32Array,\n): { reason: 'nan' | 'not-number' | 'inconsistent'; received?: string } | undefined {\n const sample: unknown[] = []\n const step = Math.max(1, Math.floor(indices.length / 8))\n for (let i = 0; i < indices.length && sample.length < 8; i += step) {\n const v = values[indices[i] as number]\n if (!missing(v)) sample.push(v)\n }\n try {\n for (let i = 0; i < sample.length; i++) {\n for (let j = i; j < sample.length; j++) {\n const x = fn(sample[i], sample[j])\n const y = fn(sample[j], sample[i])\n for (const r of [x, y]) {\n if (typeof r !== 'number') return { reason: 'not-number', received: describeReturn(r) }\n if (Number.isNaN(r)) return { reason: 'nan' }\n }\n if (Math.sign(x) !== -Math.sign(y)) return { reason: 'inconsistent' }\n }\n }\n } catch {\n return undefined\n }\n return undefined\n}\n\ntype SortFn = (a: unknown, b: unknown) => number\ntype SortBy = (row: unknown) => unknown\n\nconst fnField = (def: object, field: 'sortFn' | 'sortBy') => {\n const f = (def as Record<string, unknown>)[field]\n return typeof f === 'function' ? f : undefined\n}\n\n/** Aborts a native sort when a column's `sortFn` throws (the entry then falls back). */\nclass SortFnFailed {\n constructor(\n readonly entry: number,\n readonly error: unknown,\n ) {}\n}\n\n/**\n * Sorting (§6.4): `toggleSort` (asc → desc → none, `multi`), stable sort of the row indices with\n * the default comparator — missing values (`null`, `undefined`, `NaN`, invalid `Date`) last in both\n * directions, mixed types by type rank, strings with one `Intl.Collator(locale, { numeric: true })`\n * — or a column's `sortFn` / `sortBy`. Never touches the data: a copy of the index array is sorted.\n *\n * `algorithm: 'auto'` (default) picks per sort from one O(n) scan (§6.4): exsorted tim / counting /\n * radix for a single column of safe-integer keys (numbers, `Date`s), native `Array.prototype.sort`\n * (stable) for strings, floats, multi-column and `sortFn`. Every choice gives the same stable order.\n * `sorting({ algorithm })` or a column's `sortAlgorithm` overrides it; `debug: true` reports each\n * choice (`DK_SORT_STRATEGY`).\n */\nexport const sorting = (opts: SortingOptions = {}) => {\n let collator: Intl.Collator | undefined\n /** The collator; `DK_ENV_FALLBACK` when the runtime supports none of the requested locales. */\n const getCollator = (emit: Emit) => {\n if (collator) return collator\n const locale = (opts.locale ?? 'en') as string | string[]\n let supported = true\n try {\n collator = new Intl.Collator(locale, { numeric: true })\n supported = Intl.Collator.supportedLocalesOf(locale).length > 0\n } catch {\n collator = new Intl.Collator(undefined, { numeric: true })\n supported = false\n }\n if (!supported) {\n emit('DK_ENV_FALLBACK', {\n api: 'Intl.Collator',\n feature: 'sorting',\n requested: ([] as string[]).concat(locale).join(', '),\n fallback: `collation|${collator.resolvedOptions().locale}`,\n })\n }\n return collator\n }\n\n /** Values array → the key of its collation-ranks job (`ctx.slice`); released with the values. */\n const rankKeys = new WeakMap<object, object>()\n function ranksFor(ctx: RowModelContext, values: readonly unknown[]) {\n let key = rankKeys.get(values)\n if (!key) {\n key = {}\n rankKeys.set(values, key)\n }\n const c = getCollator(ctx.emit)\n return sliced(ctx, key, () => collationRanks(values, c))\n }\n /** The last sorted output and its input: the stand-in while ranks are computed (§9.1). */\n let shown: { input: Uint32Array; output: Uint32Array } | undefined\n\n // Values that the column cache does not hold, per data reference (released with it).\n const sortByCache = new WeakMap<readonly unknown[], WeakMap<object, unknown[]>>()\n const pathCache = new WeakMap<readonly unknown[], Map<string, unknown[]>>()\n /** exsorted feature detection (§8.5), once per feature instance, on the first sort needing it. */\n let exsorted: boolean | undefined\n\n /** `sortBy` failures (§3.4): numbers only; text is built only when a cell failed. */\n const sortByFailures = new CellFailures()\n\n /**\n * `sortBy` is a cell slot: one `column:batch` per column per data reference, an inline\n * `try/catch` per row. A failed row (or a batch an interceptor skipped) keys as `undefined`,\n * which sorts last.\n */\n function sortByValues(ctx: RowModelContext, col: ResolvedColumn, sortBy: SortBy): unknown[] {\n const data = ctx.data\n let byDef = sortByCache.get(data)\n if (!byDef) {\n byDef = new WeakMap()\n sortByCache.set(data, byDef)\n }\n let out = byDef.get(col.def)\n if (out) return out\n const values: unknown[] = new Array(data.length).fill(undefined)\n const rows = allRows(data)\n sortByFailures.reset()\n ctx.batch(col.id, 'sortBy', rows, () => {\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i] as number\n try {\n values[r] = sortBy(data[r])\n } catch (e) {\n sortByFailures.add(r, e)\n }\n }\n sortByFailures.report(ctx.emit, col.index, col.id, 'sortBy')\n })\n sortByFailures.reset()\n out = values\n byDef.set(col.def, out)\n return out\n }\n\n function pathValues(ctx: RowModelContext, id: string): unknown[] {\n const data = ctx.data\n let byId = pathCache.get(data)\n if (!byId) {\n byId = new Map()\n pathCache.set(data, byId)\n }\n let out = byId.get(id)\n if (out) return out\n const path = compilePath(id)\n out = new Array(data.length)\n for (let r = 0; r < data.length; r++) out[r] = getValue(data[r], path)\n byId.set(id, out)\n return out\n }\n\n return defineFeature<'sorting', SortingTypes>({\n name: 'sorting',\n stage: 'sort',\n mode: opts.mode ?? 'client',\n options: defineOptions(\n // The option validator runs in development only (§9.3): production drops the schema.\n (process.env.NODE_ENV !== \"production\") ? sortingOptions : ({} as typeof sortingOptions),\n opts,\n ),\n initialState: () => ({ by: [] }),\n // After destroy(): still a declared value (`aria-sort` reads it during teardown renders).\n destroyedResult: { getSortDirection: () => false },\n createApi: (ctx) => ({\n toggleSort: (id, options) =>\n ctx.setState((s) => {\n const by = s.by\n const i = by.findIndex((e) => e.id === id)\n const cur = by[i]\n const next = !cur ? { id, desc: false } : cur.desc ? undefined : { id, desc: true }\n if (!options?.multi) return { by: next ? [next] : [] }\n if (!cur) return { by: [...by, next as SortEntry<unknown>] }\n const out = by.slice()\n if (next) out[i] = next\n else out.splice(i, 1)\n return { by: out }\n }),\n setSorting: (by) => setSort(ctx, by),\n clearSorting: () => setSort(ctx, []),\n getSortDirection: (id) => {\n const e = ctx.getState().by.find((x) => x.id === id)\n return e ? (e.desc ? 'desc' : 'asc') : false\n },\n }),\n rowModel: (indices, state, ctx) => {\n const by = state?.by\n if (!by || by.length === 0 || indices.length < 2) {\n shown = undefined\n return indices\n }\n const t0 = opts.debug ? now() : 0\n const cols = resolveColumns(ctx.columns)\n const entries = by.map((e) => {\n const id = String(e.id)\n const col = cols.byId.get(id)\n const sortBy = col && (fnField(col.def, 'sortBy') as SortBy | undefined)\n const values: ColumnValues = sortBy\n ? sortByValues(ctx, col, sortBy)\n : (ctx.getColumnValues(id) ?? pathValues(ctx, id))\n const sortFn =\n col && !sortBy ? (fnField(col.def, 'sortFn') as SortFn | undefined) : undefined\n return { col, desc: e.desc === true, values, sortFn, ranked: false }\n })\n\n // Dev (§8.3): a sampled sortFn check; an invalid one falls back to the default comparator.\n if ((process.env.NODE_ENV !== \"production\")) {\n for (const e of entries) {\n if (!e.sortFn) continue\n const bad = checkSortFn(e.sortFn, e.values, indices)\n if (!bad) continue\n e.sortFn = undefined\n const col = e.col as ResolvedColumn\n ctx.emit('DK_SORT_COMPARATOR_INVALID', { column: col.id, index: col.index, ...bad })\n }\n }\n\n // The requested algorithm: the primary column's `sortAlgorithm`, else the table's.\n const primary = entries[0] as (typeof entries)[number]\n const colAlgorithm =\n primary.col && (primary.col.def as { sortAlgorithm?: unknown }).sortAlgorithm\n const fromColumn = colAlgorithm !== undefined\n let requested = (fromColumn ? colAlgorithm : (opts.algorithm ?? 'auto')) as SortAlgorithm\n const noEffect = (reason: string) =>\n ctx.emit(\n 'DK_OPTION_NO_EFFECT',\n fromColumn\n ? { path: `columns[${primary.col?.index}].sortAlgorithm`, reason, once: false }\n : { path: 'algorithm', feature: 'sorting', reason, once: false },\n )\n if (\n typeof requested !== 'function' &&\n !(ALGORITHMS as readonly unknown[]).includes(requested)\n ) {\n noEffect(`not-algorithm|${JSON.stringify(requested)}`)\n requested = 'auto'\n }\n if (requested !== 'native' && exsorted === undefined) {\n // DK_DEP_INCOMPATIBLE is a development check (§8.5); the fallback is not.\n exsorted = (process.env.NODE_ENV !== \"production\")\n ? detectCapability(\n hasExsorted,\n {\n feature: 'sorting',\n dependency: 'exsorted',\n capability: 'timSort / radixSort / countingSort',\n supported: '^1.2.3',\n fallback: 'Array.prototype.sort (native, stable)',\n },\n ctx.emit,\n )\n : hasCapability(hasExsorted)\n }\n\n // auto at large n (§9.1): string columns sort by collation ranks, computed by a sliced job.\n if (requested === 'auto' && indices.length >= RANKS_MIN) {\n let computing = false\n for (const e of entries) {\n if (e.sortFn || e.values instanceof Float64Array) continue\n const ranks = ranksFor(ctx, e.values)\n if (ranks === undefined) computing = true\n else if (ranks) {\n e.values = ranks\n e.ranked = true\n }\n }\n // Meanwhile: the previous order of these rows (or the input order); 'pending'.\n if (computing) return shown && shown.input === indices ? shown.output : indices\n }\n const ranked = entries.some((e) => e.ranked)\n\n const build = (): IndexComparator => {\n const cmps = entries.map((e, k) => {\n const fn = e.sortFn\n if (!fn) return defaultIndexComparator(e.values, e.desc, getCollator(ctx.emit))\n const guarded: SortFn = (a, b) => {\n try {\n return fn(a, b)\n } catch (error) {\n throw new SortFnFailed(k, error)\n }\n }\n return sortFnIndexComparator(e.values, e.desc, guarded)\n })\n if (cmps.length === 1) return cmps[0] as IndexComparator\n return (a, b) => {\n for (let k = 0; k < cmps.length; k++) {\n const c = (cmps[k] as IndexComparator)(a, b)\n if (c !== 0) return c\n }\n return 0\n }\n }\n\n let algorithm: string = 'native'\n let reason = ''\n /** One attempt; a throwing sortFn propagates as SortFnFailed (the loop below retries). */\n const sortOnce = (): Uint32Array => {\n const want = requested\n if (typeof want === 'function') {\n const custom = want as CustomAlgorithm\n let res: unknown\n try {\n res = custom(indices.slice(), build())\n } catch (error) {\n if (error instanceof SortFnFailed) throw error\n reportCustom(true, error)\n return native('custom-threw')\n }\n if (res instanceof Uint32Array && res.length === indices.length) {\n algorithm = 'custom'\n reason = fromColumn ? 'column sortAlgorithm' : 'sorting({ algorithm })'\n return res\n }\n reportCustom(false, res)\n return native('custom-bad')\n }\n if (exsorted === false) return native('exsorted unavailable')\n const by = fromColumn ? 'column sortAlgorithm' : 'sorting({ algorithm })'\n // Integer keys: a single column with the default comparator (§6.4).\n const single = entries.length === 1 && !primary.sortFn\n const keys =\n single && want !== 'native' ? intKeys(primary.values, indices, primary.desc) : undefined\n if (want !== 'auto' && want !== 'native') {\n if (keys) {\n try {\n const out = sortIntKeys(keys, want)\n algorithm = want\n reason = `int-keys|${by}`\n return out\n } catch {\n noEffect(`exsorted-${want === 'counting' ? 'range' : 'failed'}|${want}`)\n }\n } else if (needsIntKeys(want)) {\n noEffect(`needs-int-keys|${want}`)\n } else {\n algorithm = want\n reason = by\n return sortWithComparator(indices, build(), want as 'tim')\n }\n } else if (want === 'native') return native(by)\n if (!keys) {\n return native(\n single ? 'not-safe-int' : entries.length > 1 ? 'multi-column' : 'custom sortFn',\n )\n }\n const choice = chooseAuto(keys)\n algorithm = choice.algorithm\n reason = `auto-${ranked ? 'ranked-' : ''}${choice.reason}`\n return sortIntKeys(keys, choice.algorithm)\n }\n const native = (why: string) => {\n algorithm = 'native'\n reason = ranked ? `ranks|${why}` : why\n return sortWithComparator(indices, build(), 'native')\n }\n /** A custom algorithm threw (`threw`, `value` = the error) or returned a bad `value`. */\n const reportCustom = (threw: boolean, value: unknown) => {\n const slot = fromColumn\n ? `columns[${primary.col?.index}].sortAlgorithm`\n : 'sorting.algorithm'\n const fallback = 'sorted-native'\n if (!threw) {\n // The slot contract check is dev only (§3.4 slotContract); the fallback applies always.\n if ((process.env.NODE_ENV !== \"production\")) {\n ctx.emit('DK_CALLBACK_BAD_RETURN', {\n slot,\n expected: `a Uint32Array of ${indices.length} row indices`,\n received: describeReturn(value),\n count: 1,\n fallback,\n })\n }\n return\n }\n const name = errorName(value)\n ctx.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot,\n count: 1,\n fallback,\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: value },\n )\n }\n\n // At most one retry per entry: each failing sortFn falls back to the default comparator.\n for (;;) {\n try {\n const out = sortOnce()\n if (opts.debug) {\n ctx.emit('DK_SORT_STRATEGY', {\n algorithm,\n reason,\n n: indices.length,\n ms: now() - t0,\n by: by.map((e) => `${String(e.id)}:${e.desc ? 'desc' : 'asc'}`),\n ...(primary.col ? { column: { index: primary.col.index, id: primary.col.id } } : {}),\n })\n }\n shown = { input: indices, output: out }\n return out\n } catch (e) {\n if (!(e instanceof SortFnFailed)) throw e\n const entry = entries[e.entry] as (typeof entries)[number]\n entry.sortFn = undefined\n const col = entry.col as ResolvedColumn\n const name = errorName(e.error)\n ctx.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].sortFn`,\n column: col.id,\n count: 1,\n fallback: 'sorted-default',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e.error },\n )\n }\n }\n },\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,qBAA8B;AAC9B,mBAA+B;AAE/B,uBAAsC;AAEtC,qBAAgC;AAChC,2BAAO;AAEP,oBAA8B;AAE9B,wBAA6B;AAC7B,sBAA0B;AAC1B,IAAAA,gBAAoC;AACpC,qBAAoD;AACpD,uBAA+B;AAC/B,qBAAwB;AACxB,mBAAuB;AAEvB,kBAA0C;AAC1C,wBAAgD;AAChD,IAAAA,gBAA0D;AAC1D,qBAMO;AACP,mBAA+B;AAC/B,sBAOO;AAAA,IAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWA,IAAM,UAAU,CACd,KACA,OACG,IAAI,SAAS,CAAC,MAAO,KAAK,UAAU,EAAE,EAAE,MAAM,KAAK,UAAU,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAAE;AA8C/F,IAAM,cAAc,CAAC,MAAe;AAClC,MAAI;AACF,SAAK,oBAAoB,CAAsB;AAC/C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,aAAa,CAAC,QAAQ,OAAO,SAAS,YAAY,QAAQ;AAEhE,IAAM,iBAAiB;AAAA,EACrB,QAAQ;AAAA,IACN,MAAM,CAAC,UAAU,OAAO;AAAA,IACxB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,MAAM,CAAC,UAAU,UAAU;AAAA,IAC3B,OAAO;AAAA;AAAA,IAEP,UACE;AAAA,EACJ;AAAA,EACA,OAAO,EAAE,MAAM,UAAU;AAAA,EACzB,MAAM;AACR;AAIA,IAAM,MAAM,MAAO,OAAO,gBAAgB,cAAc,KAAK,IAAI,IAAI,YAAY,IAAI;AAOrF,IAAM,YAAY;AAElB,IAAM,UAAU,CAAC,UAAe,yBAAS,CAAC,MAAM,oBAAK;AAOrD,SAAS,YACP,IACA,QACA,SACkF;AAClF,QAAM,SAAoB,CAAC;AAC3B,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC;AACvD,WAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,OAAO,SAAS,GAAG,KAAK,MAAM;AAClE,UAAM,IAAI,OAAO,QAAQ,CAAC,CAAW;AACrC,QAAI,CAAC,QAAQ,CAAC,EAAG,QAAO,KAAK,CAAC;AAAA,EAChC;AACA,MAAI;AACF,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,IAAI,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACjC,cAAM,IAAI,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACjC,mBAAW,KAAK,CAAC,GAAG,CAAC,GAAG;AACtB,cAAI,OAAO,MAAM,SAAU,QAAO,EAAE,QAAQ,cAAc,cAAU,6BAAe,CAAC,EAAE;AACtF,cAAI,OAAO,MAAM,CAAC,EAAG,QAAO,EAAE,QAAQ,MAAM;AAAA,QAC9C;AACA,YAAI,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,EAAG,QAAO,EAAE,QAAQ,eAAe;AAAA,MACtE;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,IAAM,UAAU,CAAC,KAAa,UAA+B;AAC3D,QAAM,IAAK,IAAgC,KAAK;AAChD,SAAO,OAAO,MAAM,aAAa,IAAI;AACvC;AAGA,IAAM,eAAN,MAAmB;AAAA,EACjB,YACW,OACA,OACT;AAFS;AACA;AAAA,EACR;AACL;AAcO,IAAM,UAAU,CAAC,OAAuB,CAAC,MAAM;AACpD,MAAI;AAEJ,QAAM,cAAc,CAAC,SAAe;AAClC,QAAI,SAAU,QAAO;AACrB,UAAM,SAAU,KAAK,UAAU;AAC/B,QAAI,YAAY;AAChB,QAAI;AACF,iBAAW,IAAI,KAAK,SAAS,QAAQ,EAAE,SAAS,KAAK,CAAC;AACtD,kBAAY,KAAK,SAAS,mBAAmB,MAAM,EAAE,SAAS;AAAA,IAChE,QAAQ;AACN,iBAAW,IAAI,KAAK,SAAS,QAAW,EAAE,SAAS,KAAK,CAAC;AACzD,kBAAY;AAAA,IACd;AACA,QAAI,CAAC,WAAW;AACd,WAAK,mBAAmB;AAAA,QACtB,KAAK;AAAA,QACL,SAAS;AAAA,QACT,WAAY,CAAC,EAAe,OAAO,MAAM,EAAE,KAAK,IAAI;AAAA,QACpD,UAAU,aAAa,SAAS,gBAAgB,EAAE,MAAM;AAAA,MAC1D,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,oBAAI,QAAwB;AAC7C,WAAS,SAAS,KAAsB,QAA4B;AAClE,QAAI,MAAM,SAAS,IAAI,MAAM;AAC7B,QAAI,CAAC,KAAK;AACR,YAAM,CAAC;AACP,eAAS,IAAI,QAAQ,GAAG;AAAA,IAC1B;AACA,UAAM,IAAI,YAAY,IAAI,IAAI;AAC9B,eAAO,qBAAO,KAAK,KAAK,UAAM,6BAAe,QAAQ,CAAC,CAAC;AAAA,EACzD;AAEA,MAAI;AAGJ,QAAM,cAAc,oBAAI,QAAwD;AAChF,QAAM,YAAY,oBAAI,QAAoD;AAE1E,MAAI;AAGJ,QAAM,iBAAiB,IAAI,+BAAa;AAOxC,WAAS,aAAa,KAAsB,KAAqB,QAA2B;AAC1F,UAAM,OAAO,IAAI;AACjB,QAAI,QAAQ,YAAY,IAAI,IAAI;AAChC,QAAI,CAAC,OAAO;AACV,cAAQ,oBAAI,QAAQ;AACpB,kBAAY,IAAI,MAAM,KAAK;AAAA,IAC7B;AACA,QAAI,MAAM,MAAM,IAAI,IAAI,GAAG;AAC3B,QAAI,IAAK,QAAO;AAChB,UAAM,SAAoB,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,MAAS;AAC/D,UAAM,WAAO,wBAAQ,IAAI;AACzB,mBAAe,MAAM;AACrB,QAAI,MAAM,IAAI,IAAI,UAAU,MAAM,MAAM;AACtC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,IAAI,KAAK,CAAC;AAChB,YAAI;AACF,iBAAO,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC;AAAA,QAC5B,SAAS,GAAG;AACV,yBAAe,IAAI,GAAG,CAAC;AAAA,QACzB;AAAA,MACF;AACA,qBAAe,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI,IAAI,QAAQ;AAAA,IAC7D,CAAC;AACD,mBAAe,MAAM;AACrB,UAAM;AACN,UAAM,IAAI,IAAI,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,KAAsB,IAAuB;AAC/D,UAAM,OAAO,IAAI;AACjB,QAAI,OAAO,UAAU,IAAI,IAAI;AAC7B,QAAI,CAAC,MAAM;AACT,aAAO,oBAAI,IAAI;AACf,gBAAU,IAAI,MAAM,IAAI;AAAA,IAC1B;AACA,QAAI,MAAM,KAAK,IAAI,EAAE;AACrB,QAAI,IAAK,QAAO;AAChB,UAAM,WAAO,8BAAY,EAAE;AAC3B,UAAM,IAAI,MAAM,KAAK,MAAM;AAC3B,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,KAAI,CAAC,QAAI,2BAAS,KAAK,CAAC,GAAG,IAAI;AACrE,SAAK,IAAI,IAAI,GAAG;AAChB,WAAO;AAAA,EACT;AAEA,aAAO,6BAAuC;AAAA,IAC5C,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM,KAAK,QAAQ;AAAA,IACnB,aAAS;AAAA;AAAA,MAEN,QAAQ,IAAI,aAAa,eAAgB,iBAAkB,CAAC;AAAA,MAC7D;AAAA,IACF;AAAA,IACA,cAAc,OAAO,EAAE,IAAI,CAAC,EAAE;AAAA;AAAA,IAE9B,iBAAiB,EAAE,kBAAkB,MAAM,MAAM;AAAA,IACjD,WAAW,CAAC,SAAS;AAAA,MACnB,YAAY,CAAC,IAAI,YACf,IAAI,SAAS,CAAC,MAAM;AAClB,cAAM,KAAK,EAAE;AACb,cAAM,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACzC,cAAM,MAAM,GAAG,CAAC;AAChB,cAAM,OAAO,CAAC,MAAM,EAAE,IAAI,MAAM,MAAM,IAAI,IAAI,OAAO,SAAY,EAAE,IAAI,MAAM,KAAK;AAClF,YAAI,CAAC,SAAS,MAAO,QAAO,EAAE,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE;AACrD,YAAI,CAAC,IAAK,QAAO,EAAE,IAAI,CAAC,GAAG,IAAI,IAA0B,EAAE;AAC3D,cAAM,MAAM,GAAG,MAAM;AACrB,YAAI,KAAM,KAAI,CAAC,IAAI;AAAA,YACd,KAAI,OAAO,GAAG,CAAC;AACpB,eAAO,EAAE,IAAI,IAAI;AAAA,MACnB,CAAC;AAAA,MACH,YAAY,CAAC,OAAO,QAAQ,KAAK,EAAE;AAAA,MACnC,cAAc,MAAM,QAAQ,KAAK,CAAC,CAAC;AAAA,MACnC,kBAAkB,CAAC,OAAO;AACxB,cAAM,IAAI,IAAI,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACnD,eAAO,IAAK,EAAE,OAAO,SAAS,QAAS;AAAA,MACzC;AAAA,IACF;AAAA,IACA,UAAU,CAAC,SAAS,OAAO,QAAQ;AACjC,YAAM,KAAK,OAAO;AAClB,UAAI,CAAC,MAAM,GAAG,WAAW,KAAK,QAAQ,SAAS,GAAG;AAChD,gBAAQ;AACR,eAAO;AAAA,MACT;AACA,YAAM,KAAK,KAAK,QAAQ,IAAI,IAAI;AAChC,YAAM,WAAO,+BAAe,IAAI,OAAO;AACvC,YAAM,UAAU,GAAG,IAAI,CAAC,MAAM;AAC5B,cAAM,KAAK,OAAO,EAAE,EAAE;AACtB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,cAAM,SAAS,OAAQ,QAAQ,IAAI,KAAK,QAAQ;AAChD,cAAM,SAAuB,SACzB,aAAa,KAAK,KAAK,MAAM,IAC5B,IAAI,gBAAgB,EAAE,KAAK,WAAW,KAAK,EAAE;AAClD,cAAM,SACJ,OAAO,CAAC,SAAU,QAAQ,IAAI,KAAK,QAAQ,IAA2B;AACxE,eAAO,EAAE,KAAK,MAAM,EAAE,SAAS,MAAM,QAAQ,QAAQ,QAAQ,MAAM;AAAA,MACrE,CAAC;AAGD,UAAK,QAAQ,IAAI,aAAa,cAAe;AAC3C,mBAAW,KAAK,SAAS;AACvB,cAAI,CAAC,EAAE,OAAQ;AACf,gBAAM,MAAM,YAAY,EAAE,QAAQ,EAAE,QAAQ,OAAO;AACnD,cAAI,CAAC,IAAK;AACV,YAAE,SAAS;AACX,gBAAM,MAAM,EAAE;AACd,cAAI,KAAK,8BAA8B,EAAE,QAAQ,IAAI,IAAI,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC;AAAA,QACrF;AAAA,MACF;AAGA,YAAM,UAAU,QAAQ,CAAC;AACzB,YAAM,eACJ,QAAQ,OAAQ,QAAQ,IAAI,IAAoC;AAClE,YAAM,aAAa,iBAAiB;AACpC,UAAI,YAAa,aAAa,eAAgB,KAAK,aAAa;AAChE,YAAM,WAAW,CAACC,YAChB,IAAI;AAAA,QACF;AAAA,QACA,aACI,EAAE,MAAM,WAAW,QAAQ,KAAK,KAAK,mBAAmB,QAAAA,SAAQ,MAAM,MAAM,IAC5E,EAAE,MAAM,aAAa,SAAS,WAAW,QAAAA,SAAQ,MAAM,MAAM;AAAA,MACnE;AACF,UACE,OAAO,cAAc,cACrB,CAAE,WAAkC,SAAS,SAAS,GACtD;AACA,iBAAS,iBAAiB,KAAK,UAAU,SAAS,CAAC,EAAE;AACrD,oBAAY;AAAA,MACd;AACA,UAAI,cAAc,YAAY,aAAa,QAAW;AAEpD,mBAAY,QAAQ,IAAI,aAAa,mBACjC;AAAA,UACE;AAAA,UACA;AAAA,YACE,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,WAAW;AAAA,YACX,UAAU;AAAA,UACZ;AAAA,UACA,IAAI;AAAA,QACN,QACA,iCAAc,2BAAW;AAAA,MAC/B;AAGA,UAAI,cAAc,UAAU,QAAQ,UAAU,WAAW;AACvD,YAAI,YAAY;AAChB,mBAAW,KAAK,SAAS;AACvB,cAAI,EAAE,UAAU,EAAE,kBAAkB,aAAc;AAClD,gBAAM,QAAQ,SAAS,KAAK,EAAE,MAAM;AACpC,cAAI,UAAU,OAAW,aAAY;AAAA,mBAC5B,OAAO;AACd,cAAE,SAAS;AACX,cAAE,SAAS;AAAA,UACb;AAAA,QACF;AAEA,YAAI,UAAW,QAAO,SAAS,MAAM,UAAU,UAAU,MAAM,SAAS;AAAA,MAC1E;AACA,YAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,MAAM;AAE3C,YAAM,QAAQ,MAAuB;AACnC,cAAM,OAAO,QAAQ,IAAI,CAAC,GAAG,MAAM;AACjC,gBAAM,KAAK,EAAE;AACb,cAAI,CAAC,GAAI,YAAO,uCAAuB,EAAE,QAAQ,EAAE,MAAM,YAAY,IAAI,IAAI,CAAC;AAC9E,gBAAM,UAAkB,CAAC,GAAG,MAAM;AAChC,gBAAI;AACF,qBAAO,GAAG,GAAG,CAAC;AAAA,YAChB,SAAS,OAAO;AACd,oBAAM,IAAI,aAAa,GAAG,KAAK;AAAA,YACjC;AAAA,UACF;AACA,qBAAO,sCAAsB,EAAE,QAAQ,EAAE,MAAM,OAAO;AAAA,QACxD,CAAC;AACD,YAAI,KAAK,WAAW,EAAG,QAAO,KAAK,CAAC;AACpC,eAAO,CAAC,GAAG,MAAM;AACf,mBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,kBAAM,IAAK,KAAK,CAAC,EAAsB,GAAG,CAAC;AAC3C,gBAAI,MAAM,EAAG,QAAO;AAAA,UACtB;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,UAAI,YAAoB;AACxB,UAAI,SAAS;AAEb,YAAM,WAAW,MAAmB;AAClC,cAAM,OAAO;AACb,YAAI,OAAO,SAAS,YAAY;AAC9B,gBAAM,SAAS;AACf,cAAI;AACJ,cAAI;AACF,kBAAM,OAAO,QAAQ,MAAM,GAAG,MAAM,CAAC;AAAA,UACvC,SAAS,OAAO;AACd,gBAAI,iBAAiB,aAAc,OAAM;AACzC,yBAAa,MAAM,KAAK;AACxB,mBAAO,OAAO,cAAc;AAAA,UAC9B;AACA,cAAI,eAAe,eAAe,IAAI,WAAW,QAAQ,QAAQ;AAC/D,wBAAY;AACZ,qBAAS,aAAa,yBAAyB;AAC/C,mBAAO;AAAA,UACT;AACA,uBAAa,OAAO,GAAG;AACvB,iBAAO,OAAO,YAAY;AAAA,QAC5B;AACA,YAAI,aAAa,MAAO,QAAO,OAAO,sBAAsB;AAC5D,cAAMC,MAAK,aAAa,yBAAyB;AAEjD,cAAM,SAAS,QAAQ,WAAW,KAAK,CAAC,QAAQ;AAChD,cAAM,OACJ,UAAU,SAAS,eAAW,yBAAQ,QAAQ,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACjF,YAAI,SAAS,UAAU,SAAS,UAAU;AACxC,cAAI,MAAM;AACR,gBAAI;AACF,oBAAM,UAAM,6BAAY,MAAM,IAAI;AAClC,0BAAY;AACZ,uBAAS,YAAYA,GAAE;AACvB,qBAAO;AAAA,YACT,QAAQ;AACN,uBAAS,YAAY,SAAS,aAAa,UAAU,QAAQ,IAAI,IAAI,EAAE;AAAA,YACzE;AAAA,UACF,eAAW,8BAAa,IAAI,GAAG;AAC7B,qBAAS,kBAAkB,IAAI,EAAE;AAAA,UACnC,OAAO;AACL,wBAAY;AACZ,qBAASA;AACT,uBAAO,oCAAmB,SAAS,MAAM,GAAG,IAAa;AAAA,UAC3D;AAAA,QACF,WAAW,SAAS,SAAU,QAAO,OAAOA,GAAE;AAC9C,YAAI,CAAC,MAAM;AACT,iBAAO;AAAA,YACL,SAAS,iBAAiB,QAAQ,SAAS,IAAI,iBAAiB;AAAA,UAClE;AAAA,QACF;AACA,cAAM,aAAS,4BAAW,IAAI;AAC9B,oBAAY,OAAO;AACnB,iBAAS,QAAQ,SAAS,YAAY,EAAE,GAAG,OAAO,MAAM;AACxD,mBAAO,6BAAY,MAAM,OAAO,SAAS;AAAA,MAC3C;AACA,YAAM,SAAS,CAAC,QAAgB;AAC9B,oBAAY;AACZ,iBAAS,SAAS,SAAS,GAAG,KAAK;AACnC,mBAAO,oCAAmB,SAAS,MAAM,GAAG,QAAQ;AAAA,MACtD;AAEA,YAAM,eAAe,CAAC,OAAgB,UAAmB;AACvD,cAAM,OAAO,aACT,WAAW,QAAQ,KAAK,KAAK,oBAC7B;AACJ,cAAM,WAAW;AACjB,YAAI,CAAC,OAAO;AAEV,cAAK,QAAQ,IAAI,aAAa,cAAe;AAC3C,gBAAI,KAAK,0BAA0B;AAAA,cACjC;AAAA,cACA,UAAU,oBAAoB,QAAQ,MAAM;AAAA,cAC5C,cAAU,6BAAe,KAAK;AAAA,cAC9B,OAAO;AAAA,cACP;AAAA,YACF,CAAC;AAAA,UACH;AACA;AAAA,QACF;AACA,cAAM,WAAO,2BAAU,KAAK;AAC5B,YAAI;AAAA,UACF;AAAA,UACA;AAAA,YACE;AAAA,YACA,OAAO;AAAA,YACP;AAAA,YACA,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK;AAAA,UAClD;AAAA,UACA,EAAE,OAAO,MAAM;AAAA,QACjB;AAAA,MACF;AAGA,iBAAS;AACP,YAAI;AACF,gBAAM,MAAM,SAAS;AACrB,cAAI,KAAK,OAAO;AACd,gBAAI,KAAK,oBAAoB;AAAA,cAC3B;AAAA,cACA;AAAA,cACA,GAAG,QAAQ;AAAA,cACX,IAAI,IAAI,IAAI;AAAA,cACZ,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,SAAS,KAAK,EAAE;AAAA,cAC9D,GAAI,QAAQ,MAAM,EAAE,QAAQ,EAAE,OAAO,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,GAAG,EAAE,IAAI,CAAC;AAAA,YACpF,CAAC;AAAA,UACH;AACA,kBAAQ,EAAE,OAAO,SAAS,QAAQ,IAAI;AACtC,iBAAO;AAAA,QACT,SAAS,GAAG;AACV,cAAI,EAAE,aAAa,cAAe,OAAM;AACxC,gBAAM,QAAQ,QAAQ,EAAE,KAAK;AAC7B,gBAAM,SAAS;AACf,gBAAM,MAAM,MAAM;AAClB,gBAAM,WAAO,2BAAU,EAAE,KAAK;AAC9B,cAAI;AAAA,YACF;AAAA,YACA;AAAA,cACE,MAAM,WAAW,IAAI,KAAK;AAAA,cAC1B,QAAQ,IAAI;AAAA,cACZ,OAAO;AAAA,cACP,UAAU;AAAA,cACV,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK;AAAA,YAClD;AAAA,YACA,EAAE,OAAO,EAAE,MAAM;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":["import_codes","reason","by"]}
@@ -4,6 +4,7 @@ import { defineOptions } from "../../catalog/options.js";
4
4
  import { describeReturn } from "../../catalog/slots.js";
5
5
  import { compilePath, getValue } from "../../column/get-value.js";
6
6
  import { keepDiagnostics } from "../../diagnostics/catalog.js";
7
+ import "../../diagnostics/process-guard.js";
7
8
  import { defineFeature } from "../../feature/define.js";
8
9
  import { CellFailures } from "../../intercept/cell-batch.js";
9
10
  import { errorName } from "../../intercept/classify.js";
@@ -37,6 +38,7 @@ keepDiagnostics(
37
38
  optionDiagnostics,
38
39
  envDiagnostics
39
40
  );
41
+ var setSort = (ctx, by) => ctx.setState((s) => JSON.stringify(s.by) === JSON.stringify(by) ? s : { by: by.slice() });
40
42
  var validLocale = (v) => {
41
43
  try {
42
44
  Intl.getCanonicalLocales(v);
@@ -102,11 +104,11 @@ var sorting = (opts = {}) => {
102
104
  let collator;
103
105
  const getCollator = (emit) => {
104
106
  if (collator) return collator;
105
- const locale = opts.locale;
107
+ const locale = opts.locale ?? "en";
106
108
  let supported = true;
107
109
  try {
108
110
  collator = new Intl.Collator(locale, { numeric: true });
109
- supported = locale === void 0 || Intl.Collator.supportedLocalesOf(locale).length > 0;
111
+ supported = Intl.Collator.supportedLocalesOf(locale).length > 0;
110
112
  } catch {
111
113
  collator = new Intl.Collator(void 0, { numeric: true });
112
114
  supported = false;
@@ -115,8 +117,8 @@ var sorting = (opts = {}) => {
115
117
  emit("DK_ENV_FALLBACK", {
116
118
  api: "Intl.Collator",
117
119
  feature: "sorting",
118
- requested: [].concat(locale ?? []).join(", "),
119
- fallback: `the runtime's collation for "${collator.resolvedOptions().locale}"`
120
+ requested: [].concat(locale).join(", "),
121
+ fallback: `collation|${collator.resolvedOptions().locale}`
120
122
  });
121
123
  }
122
124
  return collator;
@@ -204,8 +206,8 @@ var sorting = (opts = {}) => {
204
206
  else out.splice(i, 1);
205
207
  return { by: out };
206
208
  }),
207
- setSorting: (by) => ctx.setState({ by: by.slice() }),
208
- clearSorting: () => ctx.setState({ by: [] }),
209
+ setSorting: (by) => setSort(ctx, by),
210
+ clearSorting: () => setSort(ctx, []),
209
211
  getSortDirection: (id) => {
210
212
  const e = ctx.getState().by.find((x) => x.id === id);
211
213
  return e ? e.desc ? "desc" : "asc" : false;
@@ -246,9 +248,7 @@ var sorting = (opts = {}) => {
246
248
  fromColumn ? { path: `columns[${primary.col?.index}].sortAlgorithm`, reason: reason2, once: false } : { path: "algorithm", feature: "sorting", reason: reason2, once: false }
247
249
  );
248
250
  if (typeof requested !== "function" && !ALGORITHMS.includes(requested)) {
249
- noEffect(
250
- `${JSON.stringify(requested)} is not a sort algorithm (accepted: ${ALGORITHMS.join(", ")}, or a function); auto was used`
251
- );
251
+ noEffect(`not-algorithm|${JSON.stringify(requested)}`);
252
252
  requested = "auto";
253
253
  }
254
254
  if (requested !== "native" && exsorted === void 0) {
@@ -312,7 +312,7 @@ var sorting = (opts = {}) => {
312
312
  } catch (error) {
313
313
  if (error instanceof SortFnFailed) throw error;
314
314
  reportCustom(true, error);
315
- return native("the custom algorithm threw");
315
+ return native("custom-threw");
316
316
  }
317
317
  if (res instanceof Uint32Array && res.length === indices.length) {
318
318
  algorithm = "custom";
@@ -320,7 +320,7 @@ var sorting = (opts = {}) => {
320
320
  return res;
321
321
  }
322
322
  reportCustom(false, res);
323
- return native("the custom algorithm returned a bad value");
323
+ return native("custom-bad");
324
324
  }
325
325
  if (exsorted === false) return native("exsorted unavailable");
326
326
  const by2 = fromColumn ? "column sortAlgorithm" : "sorting({ algorithm })";
@@ -331,17 +331,13 @@ var sorting = (opts = {}) => {
331
331
  try {
332
332
  const out = sortIntKeys(keys, want);
333
333
  algorithm = want;
334
- reason = `${by2}, safe-integer keys`;
334
+ reason = `int-keys|${by2}`;
335
335
  return out;
336
336
  } catch {
337
- noEffect(
338
- `exsorted ${want}Sort could not sort these keys` + (want === "counting" ? " (key range above 1,000,000)" : "") + "; auto was used"
339
- );
337
+ noEffect(`exsorted-${want === "counting" ? "range" : "failed"}|${want}`);
340
338
  }
341
339
  } else if (needsIntKeys(want)) {
342
- noEffect(
343
- `${want} sorts a single column of safe integer keys (numbers or Dates, no sortFn); auto was used`
344
- );
340
+ noEffect(`needs-int-keys|${want}`);
345
341
  } else {
346
342
  algorithm = want;
347
343
  reason = by2;
@@ -350,22 +346,22 @@ var sorting = (opts = {}) => {
350
346
  } else if (want === "native") return native(by2);
351
347
  if (!keys) {
352
348
  return native(
353
- single ? "keys are not all safe integers" : entries.length > 1 ? "multi-column" : "custom sortFn"
349
+ single ? "not-safe-int" : entries.length > 1 ? "multi-column" : "custom sortFn"
354
350
  );
355
351
  }
356
352
  const choice = chooseAuto(keys);
357
353
  algorithm = choice.algorithm;
358
- reason = `auto: ${ranked ? "collation ranks of a string column, " : ""}${choice.reason}`;
354
+ reason = `auto-${ranked ? "ranked-" : ""}${choice.reason}`;
359
355
  return sortIntKeys(keys, choice.algorithm);
360
356
  };
361
357
  const native = (why) => {
362
358
  algorithm = "native";
363
- reason = ranked ? `${why}, strings as collation ranks` : why;
359
+ reason = ranked ? `ranks|${why}` : why;
364
360
  return sortWithComparator(indices, build(), "native");
365
361
  };
366
362
  const reportCustom = (threw, value) => {
367
363
  const slot = fromColumn ? `columns[${primary.col?.index}].sortAlgorithm` : "sorting.algorithm";
368
- const fallback = "the rows were sorted with the native algorithm";
364
+ const fallback = "sorted-native";
369
365
  if (!threw) {
370
366
  if (process.env.NODE_ENV !== "production") {
371
367
  ctx.emit("DK_CALLBACK_BAD_RETURN", {
@@ -417,7 +413,7 @@ var sorting = (opts = {}) => {
417
413
  slot: `columns[${col.index}].sortFn`,
418
414
  column: col.id,
419
415
  count: 1,
420
- fallback: "the column was sorted with the default comparator",
416
+ fallback: "sorted-default",
421
417
  ...name === void 0 ? {} : { errorName: name }
422
418
  },
423
419
  { cause: e.error }