@milaboratories/pl-model-common 1.25.1 → 1.25.3

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 (288) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/author_marker.d.ts +9 -6
  3. package/dist/base32_encode.cjs +40 -46
  4. package/dist/base32_encode.cjs.map +1 -1
  5. package/dist/base32_encode.js +40 -45
  6. package/dist/base32_encode.js.map +1 -1
  7. package/dist/base64.cjs +5 -4
  8. package/dist/base64.cjs.map +1 -1
  9. package/dist/base64.d.ts +10 -6
  10. package/dist/base64.js +5 -3
  11. package/dist/base64.js.map +1 -1
  12. package/dist/block_state.d.ts +21 -23
  13. package/dist/bmodel/block_config.cjs +9 -10
  14. package/dist/bmodel/block_config.cjs.map +1 -1
  15. package/dist/bmodel/block_config.d.ts +53 -72
  16. package/dist/bmodel/block_config.js +9 -9
  17. package/dist/bmodel/block_config.js.map +1 -1
  18. package/dist/bmodel/code.cjs +7 -6
  19. package/dist/bmodel/code.cjs.map +1 -1
  20. package/dist/bmodel/code.d.ts +17 -13
  21. package/dist/bmodel/code.js +6 -4
  22. package/dist/bmodel/code.js.map +1 -1
  23. package/dist/bmodel/container.d.ts +46 -44
  24. package/dist/bmodel/index.cjs +3 -0
  25. package/dist/bmodel/index.d.ts +5 -6
  26. package/dist/bmodel/index.js +3 -0
  27. package/dist/bmodel/normalization.cjs +90 -106
  28. package/dist/bmodel/normalization.cjs.map +1 -1
  29. package/dist/bmodel/normalization.d.ts +7 -3
  30. package/dist/bmodel/normalization.js +90 -105
  31. package/dist/bmodel/normalization.js.map +1 -1
  32. package/dist/bmodel/types.d.ts +4 -1
  33. package/dist/branding.d.ts +5 -5
  34. package/dist/common_types.d.ts +19 -15
  35. package/dist/driver_kit.d.ts +25 -17
  36. package/dist/drivers/ChunkedStreamReader.cjs +168 -203
  37. package/dist/drivers/ChunkedStreamReader.cjs.map +1 -1
  38. package/dist/drivers/ChunkedStreamReader.d.ts +104 -100
  39. package/dist/drivers/ChunkedStreamReader.js +168 -202
  40. package/dist/drivers/ChunkedStreamReader.js.map +1 -1
  41. package/dist/drivers/blob.cjs +15 -17
  42. package/dist/drivers/blob.cjs.map +1 -1
  43. package/dist/drivers/blob.d.ts +35 -35
  44. package/dist/drivers/blob.js +14 -15
  45. package/dist/drivers/blob.js.map +1 -1
  46. package/dist/drivers/index.cjs +18 -0
  47. package/dist/drivers/index.d.ts +29 -9
  48. package/dist/drivers/index.js +18 -0
  49. package/dist/drivers/interfaces.d.ts +17 -14
  50. package/dist/drivers/log.cjs +4 -3
  51. package/dist/drivers/log.cjs.map +1 -1
  52. package/dist/drivers/log.d.ts +52 -49
  53. package/dist/drivers/log.js +4 -2
  54. package/dist/drivers/log.js.map +1 -1
  55. package/dist/drivers/ls.cjs +16 -19
  56. package/dist/drivers/ls.cjs.map +1 -1
  57. package/dist/drivers/ls.d.ts +73 -76
  58. package/dist/drivers/ls.js +16 -17
  59. package/dist/drivers/ls.js.map +1 -1
  60. package/dist/drivers/pframe/column_filter.d.ts +19 -15
  61. package/dist/drivers/pframe/data_info.cjs +201 -252
  62. package/dist/drivers/pframe/data_info.cjs.map +1 -1
  63. package/dist/drivers/pframe/data_info.d.ts +84 -109
  64. package/dist/drivers/pframe/data_info.js +201 -250
  65. package/dist/drivers/pframe/data_info.js.map +1 -1
  66. package/dist/drivers/pframe/data_types.cjs +38 -63
  67. package/dist/drivers/pframe/data_types.cjs.map +1 -1
  68. package/dist/drivers/pframe/data_types.d.ts +91 -93
  69. package/dist/drivers/pframe/data_types.js +38 -61
  70. package/dist/drivers/pframe/data_types.js.map +1 -1
  71. package/dist/drivers/pframe/driver.cjs +7 -0
  72. package/dist/drivers/pframe/driver.cjs.map +1 -0
  73. package/dist/drivers/pframe/driver.d.ts +50 -45
  74. package/dist/drivers/pframe/driver.js +6 -0
  75. package/dist/drivers/pframe/driver.js.map +1 -0
  76. package/dist/drivers/pframe/filter_spec.d.ts +127 -123
  77. package/dist/drivers/pframe/find_columns.d.ts +21 -17
  78. package/dist/drivers/pframe/index.cjs +15 -0
  79. package/dist/drivers/pframe/index.d.ts +23 -16
  80. package/dist/drivers/pframe/index.js +15 -0
  81. package/dist/drivers/pframe/linker_columns.cjs +184 -238
  82. package/dist/drivers/pframe/linker_columns.cjs.map +1 -1
  83. package/dist/drivers/pframe/linker_columns.d.ts +45 -38
  84. package/dist/drivers/pframe/linker_columns.js +184 -236
  85. package/dist/drivers/pframe/linker_columns.js.map +1 -1
  86. package/dist/drivers/pframe/pframe.d.ts +26 -21
  87. package/dist/drivers/pframe/query/index.cjs +1 -0
  88. package/dist/drivers/pframe/query/index.d.ts +3 -4
  89. package/dist/drivers/pframe/query/index.js +1 -0
  90. package/dist/drivers/pframe/query/query_common.d.ts +205 -247
  91. package/dist/drivers/pframe/query/query_data.d.ts +25 -23
  92. package/dist/drivers/pframe/query/query_spec.d.ts +30 -29
  93. package/dist/drivers/pframe/query/utils.cjs +164 -183
  94. package/dist/drivers/pframe/query/utils.cjs.map +1 -1
  95. package/dist/drivers/pframe/query/utils.d.ts +13 -12
  96. package/dist/drivers/pframe/query/utils.js +164 -181
  97. package/dist/drivers/pframe/query/utils.js.map +1 -1
  98. package/dist/drivers/pframe/spec/anchored.cjs +178 -216
  99. package/dist/drivers/pframe/spec/anchored.cjs.map +1 -1
  100. package/dist/drivers/pframe/spec/anchored.d.ts +53 -49
  101. package/dist/drivers/pframe/spec/anchored.js +176 -214
  102. package/dist/drivers/pframe/spec/anchored.js.map +1 -1
  103. package/dist/drivers/pframe/spec/filtered_column.cjs +8 -7
  104. package/dist/drivers/pframe/spec/filtered_column.cjs.map +1 -1
  105. package/dist/drivers/pframe/spec/filtered_column.d.ts +20 -17
  106. package/dist/drivers/pframe/spec/filtered_column.js +8 -6
  107. package/dist/drivers/pframe/spec/filtered_column.js.map +1 -1
  108. package/dist/drivers/pframe/spec/ids.cjs +16 -14
  109. package/dist/drivers/pframe/spec/ids.cjs.map +1 -1
  110. package/dist/drivers/pframe/spec/ids.d.ts +13 -8
  111. package/dist/drivers/pframe/spec/ids.js +14 -12
  112. package/dist/drivers/pframe/spec/ids.js.map +1 -1
  113. package/dist/drivers/pframe/spec/index.cjs +6 -0
  114. package/dist/drivers/pframe/spec/index.d.ts +6 -7
  115. package/dist/drivers/pframe/spec/index.js +6 -0
  116. package/dist/drivers/pframe/spec/native_id.cjs +16 -16
  117. package/dist/drivers/pframe/spec/native_id.cjs.map +1 -1
  118. package/dist/drivers/pframe/spec/native_id.d.ts +9 -4
  119. package/dist/drivers/pframe/spec/native_id.js +13 -13
  120. package/dist/drivers/pframe/spec/native_id.js.map +1 -1
  121. package/dist/drivers/pframe/spec/selectors.cjs +72 -112
  122. package/dist/drivers/pframe/spec/selectors.cjs.map +1 -1
  123. package/dist/drivers/pframe/spec/selectors.d.ts +99 -94
  124. package/dist/drivers/pframe/spec/selectors.js +72 -110
  125. package/dist/drivers/pframe/spec/selectors.js.map +1 -1
  126. package/dist/drivers/pframe/spec/spec.cjs +282 -324
  127. package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
  128. package/dist/drivers/pframe/spec/spec.d.ts +263 -272
  129. package/dist/drivers/pframe/spec/spec.js +281 -322
  130. package/dist/drivers/pframe/spec/spec.js.map +1 -1
  131. package/dist/drivers/pframe/table.d.ts +28 -24
  132. package/dist/drivers/pframe/table_calculate.cjs +117 -147
  133. package/dist/drivers/pframe/table_calculate.cjs.map +1 -1
  134. package/dist/drivers/pframe/table_calculate.d.ts +219 -220
  135. package/dist/drivers/pframe/table_calculate.js +117 -145
  136. package/dist/drivers/pframe/table_calculate.js.map +1 -1
  137. package/dist/drivers/pframe/table_common.cjs +13 -14
  138. package/dist/drivers/pframe/table_common.cjs.map +1 -1
  139. package/dist/drivers/pframe/table_common.d.ts +24 -19
  140. package/dist/drivers/pframe/table_common.js +13 -13
  141. package/dist/drivers/pframe/table_common.js.map +1 -1
  142. package/dist/drivers/pframe/unique_values.d.ts +23 -18
  143. package/dist/drivers/upload.d.ts +21 -18
  144. package/dist/drivers/urls.cjs +5 -6
  145. package/dist/drivers/urls.cjs.map +1 -1
  146. package/dist/drivers/urls.d.ts +12 -9
  147. package/dist/drivers/urls.js +5 -5
  148. package/dist/drivers/urls.js.map +1 -1
  149. package/dist/errors.cjs +65 -86
  150. package/dist/errors.cjs.map +1 -1
  151. package/dist/errors.d.ts +36 -33
  152. package/dist/errors.js +65 -85
  153. package/dist/errors.js.map +1 -1
  154. package/dist/flags/block_flags.cjs +7 -6
  155. package/dist/flags/block_flags.cjs.map +1 -1
  156. package/dist/flags/block_flags.d.ts +12 -8
  157. package/dist/flags/block_flags.js +7 -5
  158. package/dist/flags/block_flags.js.map +1 -1
  159. package/dist/flags/flag_utils.cjs +69 -108
  160. package/dist/flags/flag_utils.cjs.map +1 -1
  161. package/dist/flags/flag_utils.d.ts +40 -42
  162. package/dist/flags/flag_utils.js +70 -107
  163. package/dist/flags/flag_utils.js.map +1 -1
  164. package/dist/flags/type_utils.d.ts +12 -11
  165. package/dist/httpAuth.cjs +16 -20
  166. package/dist/httpAuth.cjs.map +1 -1
  167. package/dist/httpAuth.d.ts +10 -7
  168. package/dist/httpAuth.js +16 -19
  169. package/dist/httpAuth.js.map +1 -1
  170. package/dist/index.cjs +176 -179
  171. package/dist/index.d.ts +58 -20
  172. package/dist/index.js +37 -34
  173. package/dist/json.cjs +10 -8
  174. package/dist/json.cjs.map +1 -1
  175. package/dist/json.d.ts +18 -18
  176. package/dist/json.js +8 -6
  177. package/dist/json.js.map +1 -1
  178. package/dist/navigation.cjs +3 -2
  179. package/dist/navigation.cjs.map +1 -1
  180. package/dist/navigation.d.ts +18 -21
  181. package/dist/navigation.js +3 -1
  182. package/dist/navigation.js.map +1 -1
  183. package/dist/plid.cjs +16 -20
  184. package/dist/plid.cjs.map +1 -1
  185. package/dist/plid.d.ts +11 -7
  186. package/dist/plid.js +15 -18
  187. package/dist/plid.js.map +1 -1
  188. package/dist/pool/entry.d.ts +11 -11
  189. package/dist/pool/index.d.ts +3 -4
  190. package/dist/pool/query.cjs +21 -43
  191. package/dist/pool/query.cjs.map +1 -1
  192. package/dist/pool/query.d.ts +25 -20
  193. package/dist/pool/query.js +20 -40
  194. package/dist/pool/query.js.map +1 -1
  195. package/dist/pool/spec.cjs +40 -47
  196. package/dist/pool/spec.cjs.map +1 -1
  197. package/dist/pool/spec.d.ts +33 -31
  198. package/dist/pool/spec.js +40 -45
  199. package/dist/pool/spec.js.map +1 -1
  200. package/dist/ref.cjs +51 -71
  201. package/dist/ref.cjs.map +1 -1
  202. package/dist/ref.d.ts +36 -33
  203. package/dist/ref.js +50 -69
  204. package/dist/ref.js.map +1 -1
  205. package/dist/utag.d.ts +18 -14
  206. package/dist/util.cjs +8 -7
  207. package/dist/util.cjs.map +1 -1
  208. package/dist/util.d.ts +5 -2
  209. package/dist/util.js +8 -6
  210. package/dist/util.js.map +1 -1
  211. package/dist/value_or_error.cjs +7 -3
  212. package/dist/value_or_error.cjs.map +1 -1
  213. package/dist/value_or_error.d.ts +9 -6
  214. package/dist/value_or_error.js +7 -2
  215. package/dist/value_or_error.js.map +1 -1
  216. package/package.json +6 -6
  217. package/src/flags/block_flags.ts +2 -1
  218. package/src/flags/flag_utils.ts +0 -22
  219. package/dist/author_marker.d.ts.map +0 -1
  220. package/dist/base32_encode.d.ts +0 -8
  221. package/dist/base32_encode.d.ts.map +0 -1
  222. package/dist/base64.d.ts.map +0 -1
  223. package/dist/block_state.d.ts.map +0 -1
  224. package/dist/bmodel/block_config.d.ts.map +0 -1
  225. package/dist/bmodel/code.d.ts.map +0 -1
  226. package/dist/bmodel/container.d.ts.map +0 -1
  227. package/dist/bmodel/index.d.ts.map +0 -1
  228. package/dist/bmodel/normalization.d.ts.map +0 -1
  229. package/dist/bmodel/types.d.ts.map +0 -1
  230. package/dist/branding.d.ts.map +0 -1
  231. package/dist/common_types.d.ts.map +0 -1
  232. package/dist/driver_kit.d.ts.map +0 -1
  233. package/dist/drivers/ChunkedStreamReader.d.ts.map +0 -1
  234. package/dist/drivers/blob.d.ts.map +0 -1
  235. package/dist/drivers/index.d.ts.map +0 -1
  236. package/dist/drivers/interfaces.d.ts.map +0 -1
  237. package/dist/drivers/log.d.ts.map +0 -1
  238. package/dist/drivers/ls.d.ts.map +0 -1
  239. package/dist/drivers/pframe/column_filter.d.ts.map +0 -1
  240. package/dist/drivers/pframe/data_info.d.ts.map +0 -1
  241. package/dist/drivers/pframe/data_types.d.ts.map +0 -1
  242. package/dist/drivers/pframe/driver.d.ts.map +0 -1
  243. package/dist/drivers/pframe/filter_spec.d.ts.map +0 -1
  244. package/dist/drivers/pframe/find_columns.d.ts.map +0 -1
  245. package/dist/drivers/pframe/index.d.ts.map +0 -1
  246. package/dist/drivers/pframe/linker_columns.d.ts.map +0 -1
  247. package/dist/drivers/pframe/pframe.d.ts.map +0 -1
  248. package/dist/drivers/pframe/query/index.d.ts.map +0 -1
  249. package/dist/drivers/pframe/query/query_common.d.ts.map +0 -1
  250. package/dist/drivers/pframe/query/query_data.d.ts.map +0 -1
  251. package/dist/drivers/pframe/query/query_spec.d.ts.map +0 -1
  252. package/dist/drivers/pframe/query/utils.d.ts.map +0 -1
  253. package/dist/drivers/pframe/spec/anchored.d.ts.map +0 -1
  254. package/dist/drivers/pframe/spec/filtered_column.d.ts.map +0 -1
  255. package/dist/drivers/pframe/spec/ids.d.ts.map +0 -1
  256. package/dist/drivers/pframe/spec/index.d.ts.map +0 -1
  257. package/dist/drivers/pframe/spec/native_id.d.ts.map +0 -1
  258. package/dist/drivers/pframe/spec/selectors.d.ts.map +0 -1
  259. package/dist/drivers/pframe/spec/spec.d.ts.map +0 -1
  260. package/dist/drivers/pframe/table.d.ts.map +0 -1
  261. package/dist/drivers/pframe/table_calculate.d.ts.map +0 -1
  262. package/dist/drivers/pframe/table_common.d.ts.map +0 -1
  263. package/dist/drivers/pframe/type_util.d.ts +0 -5
  264. package/dist/drivers/pframe/type_util.d.ts.map +0 -1
  265. package/dist/drivers/pframe/unique_values.d.ts.map +0 -1
  266. package/dist/drivers/upload.d.ts.map +0 -1
  267. package/dist/drivers/urls.d.ts.map +0 -1
  268. package/dist/errors.d.ts.map +0 -1
  269. package/dist/flags/block_flags.d.ts.map +0 -1
  270. package/dist/flags/flag_utils.d.ts.map +0 -1
  271. package/dist/flags/index.d.ts +0 -4
  272. package/dist/flags/index.d.ts.map +0 -1
  273. package/dist/flags/type_utils.d.ts.map +0 -1
  274. package/dist/httpAuth.d.ts.map +0 -1
  275. package/dist/index.cjs.map +0 -1
  276. package/dist/index.d.ts.map +0 -1
  277. package/dist/index.js.map +0 -1
  278. package/dist/json.d.ts.map +0 -1
  279. package/dist/navigation.d.ts.map +0 -1
  280. package/dist/plid.d.ts.map +0 -1
  281. package/dist/pool/entry.d.ts.map +0 -1
  282. package/dist/pool/index.d.ts.map +0 -1
  283. package/dist/pool/query.d.ts.map +0 -1
  284. package/dist/pool/spec.d.ts.map +0 -1
  285. package/dist/ref.d.ts.map +0 -1
  286. package/dist/utag.d.ts.map +0 -1
  287. package/dist/util.d.ts.map +0 -1
  288. package/dist/value_or_error.d.ts.map +0 -1
@@ -1,5 +1,7 @@
1
- import type { SpecQueryBooleanExpression, SpecQueryExpression, SpecQuery, SpecQueryJoinEntry } from "./query_spec";
2
- export declare function isBooleanExpression(expr: SpecQueryExpression): expr is SpecQueryBooleanExpression;
1
+ import { SpecQuery, SpecQueryBooleanExpression, SpecQueryExpression, SpecQueryJoinEntry } from "./query_spec.js";
2
+
3
+ //#region src/drivers/pframe/query/utils.d.ts
4
+ declare function isBooleanExpression(expr: SpecQueryExpression): expr is SpecQueryBooleanExpression;
3
5
  /**
4
6
  * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.
5
7
  *
@@ -10,17 +12,16 @@ export declare function isBooleanExpression(expr: SpecQueryExpression): expr is
10
12
  * 4. Assemble node with transformed children
11
13
  * 5. Apply `node` to the assembled node
12
14
  */
13
- export declare function traverseQuerySpec<C1, C2>(query: SpecQuery<C1>, visitor: {
14
- /** Transform column references in leaf nodes (column, sparseToDenseColumn). */
15
- column: (c: C1) => C2;
16
- /** Visit a node after its children have been traversed. */
17
- node?: (node: SpecQuery<C2>) => SpecQuery<C2>;
18
- /** Visit a join entry after its inner query has been traversed. */
19
- joinEntry?: (entry: SpecQueryJoinEntry<C2>) => SpecQueryJoinEntry<C2>;
15
+ declare function traverseQuerySpec<C1, C2>(query: SpecQuery<C1>, visitor: {
16
+ /** Transform column references in leaf nodes (column, sparseToDenseColumn). */column: (c: C1) => C2; /** Visit a node after its children have been traversed. */
17
+ node?: (node: SpecQuery<C2>) => SpecQuery<C2>; /** Visit a join entry after its inner query has been traversed. */
18
+ joinEntry?: (entry: SpecQueryJoinEntry<C2>) => SpecQueryJoinEntry<C2>;
20
19
  }): SpecQuery<C2>;
21
20
  /** Recursively maps all column references in a SpecQuery tree. */
22
- export declare function mapSpecQueryColumns<C1, C2>(query: SpecQuery<C1>, cb: (c: C1) => C2): SpecQuery<C2>;
21
+ declare function mapSpecQueryColumns<C1, C2>(query: SpecQuery<C1>, cb: (c: C1) => C2): SpecQuery<C2>;
23
22
  /** Collects all column references from a SpecQuery tree. */
24
- export declare function collectSpecQueryColumns<C>(query: SpecQuery<C>): C[];
25
- export declare function sortSpecQuery(query: SpecQuery): SpecQuery;
23
+ declare function collectSpecQueryColumns<C>(query: SpecQuery<C>): C[];
24
+ declare function sortSpecQuery(query: SpecQuery): SpecQuery;
25
+ //#endregion
26
+ export { collectSpecQueryColumns, isBooleanExpression, mapSpecQueryColumns, sortSpecQuery, traverseQuerySpec };
26
27
  //# sourceMappingURL=utils.d.ts.map
@@ -1,203 +1,186 @@
1
- import { canonicalizeJson } from '../../../json.js';
2
- import { assertNever } from '../../../util.js';
1
+ import { assertNever } from "../../../util.js";
2
+ import { canonicalizeJson } from "../../../json.js";
3
3
 
4
+ //#region src/drivers/pframe/query/utils.ts
4
5
  const booleanTypesSet = new Set([
5
- "numericComparison",
6
- "stringEquals",
7
- "stringContains",
8
- "stringContainsFuzzy",
9
- "stringRegex",
10
- "isNull",
11
- "not",
12
- "and",
13
- "or",
14
- "isIn",
6
+ "numericComparison",
7
+ "stringEquals",
8
+ "stringContains",
9
+ "stringContainsFuzzy",
10
+ "stringRegex",
11
+ "isNull",
12
+ "not",
13
+ "and",
14
+ "or",
15
+ "isIn"
15
16
  ]);
16
17
  function isBooleanExpression(expr) {
17
- return booleanTypesSet.has(
18
- // @ts-expect-error -- TypeScript doesn't understand the discriminated union here, but we do at runtime
19
- expr.type);
18
+ return booleanTypesSet.has(expr.type);
20
19
  }
21
20
  /**
22
- * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.
23
- *
24
- * Traversal order:
25
- * 1. Recurse into child queries
26
- * 2. Apply `column` to transform column references in leaf nodes
27
- * 3. Apply `joinEntry` to each join entry (with inner query already traversed)
28
- * 4. Assemble node with transformed children
29
- * 5. Apply `node` to the assembled node
30
- */
21
+ * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.
22
+ *
23
+ * Traversal order:
24
+ * 1. Recurse into child queries
25
+ * 2. Apply `column` to transform column references in leaf nodes
26
+ * 3. Apply `joinEntry` to each join entry (with inner query already traversed)
27
+ * 4. Assemble node with transformed children
28
+ * 5. Apply `node` to the assembled node
29
+ */
31
30
  function traverseQuerySpec(query, visitor) {
32
- const traverseEntry = (entry) => {
33
- const traversed = {
34
- ...entry,
35
- entry: traverseQuerySpec(entry.entry, visitor),
36
- };
37
- return visitor.joinEntry ? visitor.joinEntry(traversed) : traversed;
38
- };
39
- let result;
40
- switch (query.type) {
41
- case "column":
42
- result = { type: "column", column: visitor.column(query.column) };
43
- break;
44
- case "sparseToDenseColumn":
45
- result = { ...query, column: visitor.column(query.column) };
46
- break;
47
- case "inlineColumn":
48
- result = query;
49
- break;
50
- case "innerJoin":
51
- case "fullJoin":
52
- result = { ...query, entries: query.entries.map(traverseEntry) };
53
- break;
54
- case "outerJoin":
55
- result = {
56
- ...query,
57
- primary: traverseEntry(query.primary),
58
- secondary: query.secondary.map(traverseEntry),
59
- };
60
- break;
61
- case "filter":
62
- case "sort":
63
- case "sliceAxes":
64
- result = { ...query, input: traverseQuerySpec(query.input, visitor) };
65
- break;
66
- default:
67
- assertNever(query);
68
- }
69
- return visitor.node ? visitor.node(result) : result;
31
+ const traverseEntry = (entry) => {
32
+ const traversed = {
33
+ ...entry,
34
+ entry: traverseQuerySpec(entry.entry, visitor)
35
+ };
36
+ return visitor.joinEntry ? visitor.joinEntry(traversed) : traversed;
37
+ };
38
+ let result;
39
+ switch (query.type) {
40
+ case "column":
41
+ result = {
42
+ type: "column",
43
+ column: visitor.column(query.column)
44
+ };
45
+ break;
46
+ case "sparseToDenseColumn":
47
+ result = {
48
+ ...query,
49
+ column: visitor.column(query.column)
50
+ };
51
+ break;
52
+ case "inlineColumn":
53
+ result = query;
54
+ break;
55
+ case "innerJoin":
56
+ case "fullJoin":
57
+ result = {
58
+ ...query,
59
+ entries: query.entries.map(traverseEntry)
60
+ };
61
+ break;
62
+ case "outerJoin":
63
+ result = {
64
+ ...query,
65
+ primary: traverseEntry(query.primary),
66
+ secondary: query.secondary.map(traverseEntry)
67
+ };
68
+ break;
69
+ case "filter":
70
+ case "sort":
71
+ case "sliceAxes":
72
+ result = {
73
+ ...query,
74
+ input: traverseQuerySpec(query.input, visitor)
75
+ };
76
+ break;
77
+ default: assertNever(query);
78
+ }
79
+ return visitor.node ? visitor.node(result) : result;
70
80
  }
71
81
  /** Recursively maps all column references in a SpecQuery tree. */
72
82
  function mapSpecQueryColumns(query, cb) {
73
- return traverseQuerySpec(query, { column: cb });
83
+ return traverseQuerySpec(query, { column: cb });
74
84
  }
75
85
  /** Collects all column references from a SpecQuery tree. */
76
86
  function collectSpecQueryColumns(query) {
77
- const result = [];
78
- traverseQuerySpec(query, {
79
- column: (c) => {
80
- result.push(c);
81
- return c;
82
- },
83
- });
84
- return result;
87
+ const result = [];
88
+ traverseQuerySpec(query, { column: (c) => {
89
+ result.push(c);
90
+ return c;
91
+ } });
92
+ return result;
85
93
  }
86
94
  function sortSpecQuery(query) {
87
- return traverseQuerySpec(query, {
88
- column: (c) => c,
89
- node: (node) => {
90
- switch (node.type) {
91
- case "sparseToDenseColumn":
92
- return { ...node, axesIndices: node.axesIndices.toSorted((a, b) => a - b) };
93
- case "innerJoin":
94
- case "fullJoin": {
95
- const sorted = [...node.entries].sort(cmpQueryJoinEntrySpec);
96
- return { ...node, entries: sorted };
97
- }
98
- case "outerJoin": {
99
- const sorted = [...node.secondary].sort(cmpQueryJoinEntrySpec);
100
- return { ...node, secondary: sorted };
101
- }
102
- case "sliceAxes":
103
- return {
104
- ...node,
105
- axisFilters: node.axisFilters.toSorted((a, b) => {
106
- const ak = canonicalizeJson(a.axisSelector);
107
- const bk = canonicalizeJson(b.axisSelector);
108
- return ak < bk ? -1 : ak === bk ? 0 : 1;
109
- }),
110
- };
111
- default:
112
- return node;
113
- }
114
- },
115
- joinEntry: (entry) => ({
116
- ...entry,
117
- qualifications: entry.qualifications.toSorted((a, b) => {
118
- const ak = canonicalizeJson(a.axis);
119
- const bk = canonicalizeJson(b.axis);
120
- return ak < bk ? -1 : ak === bk ? 0 : 1;
121
- }),
122
- }),
123
- });
95
+ return traverseQuerySpec(query, {
96
+ column: (c) => c,
97
+ node: (node) => {
98
+ switch (node.type) {
99
+ case "sparseToDenseColumn": return {
100
+ ...node,
101
+ axesIndices: node.axesIndices.toSorted((a, b) => a - b)
102
+ };
103
+ case "innerJoin":
104
+ case "fullJoin": {
105
+ const sorted = [...node.entries].sort(cmpQueryJoinEntrySpec);
106
+ return {
107
+ ...node,
108
+ entries: sorted
109
+ };
110
+ }
111
+ case "outerJoin": {
112
+ const sorted = [...node.secondary].sort(cmpQueryJoinEntrySpec);
113
+ return {
114
+ ...node,
115
+ secondary: sorted
116
+ };
117
+ }
118
+ case "sliceAxes": return {
119
+ ...node,
120
+ axisFilters: node.axisFilters.toSorted((a, b) => {
121
+ const ak = canonicalizeJson(a.axisSelector);
122
+ const bk = canonicalizeJson(b.axisSelector);
123
+ return ak < bk ? -1 : ak === bk ? 0 : 1;
124
+ })
125
+ };
126
+ default: return node;
127
+ }
128
+ },
129
+ joinEntry: (entry) => ({
130
+ ...entry,
131
+ qualifications: entry.qualifications.toSorted((a, b) => {
132
+ const ak = canonicalizeJson(a.axis);
133
+ const bk = canonicalizeJson(b.axis);
134
+ return ak < bk ? -1 : ak === bk ? 0 : 1;
135
+ })
136
+ })
137
+ });
124
138
  }
125
139
  function cmpQuerySpec(lhs, rhs) {
126
- if (lhs.type !== rhs.type) {
127
- return lhs.type < rhs.type ? -1 : 1;
128
- }
129
- switch (lhs.type) {
130
- case "column":
131
- return lhs.column < rhs.column
132
- ? -1
133
- : lhs.column === rhs.column
134
- ? 0
135
- : 1;
136
- case "inlineColumn":
137
- return lhs.spec.id < rhs.spec.id
138
- ? -1
139
- : lhs.spec.id === rhs.spec.id
140
- ? 0
141
- : 1;
142
- case "sparseToDenseColumn":
143
- return lhs.column < rhs.column
144
- ? -1
145
- : lhs.column === rhs.column
146
- ? 0
147
- : 1;
148
- case "innerJoin":
149
- case "fullJoin": {
150
- const rhsJoin = rhs;
151
- if (lhs.entries.length !== rhsJoin.entries.length) {
152
- return lhs.entries.length - rhsJoin.entries.length;
153
- }
154
- for (let i = 0; i < lhs.entries.length; i++) {
155
- const cmp = cmpQueryJoinEntrySpec(lhs.entries[i], rhsJoin.entries[i]);
156
- if (cmp !== 0)
157
- return cmp;
158
- }
159
- return 0;
160
- }
161
- case "outerJoin": {
162
- const rhsOuter = rhs;
163
- const cmp = cmpQueryJoinEntrySpec(lhs.primary, rhsOuter.primary);
164
- if (cmp !== 0)
165
- return cmp;
166
- if (lhs.secondary.length !== rhsOuter.secondary.length) {
167
- return lhs.secondary.length - rhsOuter.secondary.length;
168
- }
169
- for (let i = 0; i < lhs.secondary.length; i++) {
170
- const cmp = cmpQueryJoinEntrySpec(lhs.secondary[i], rhsOuter.secondary[i]);
171
- if (cmp !== 0)
172
- return cmp;
173
- }
174
- return 0;
175
- }
176
- case "sliceAxes":
177
- return cmpQuerySpec(lhs.input, rhs.input);
178
- case "sort":
179
- return cmpQuerySpec(lhs.input, rhs.input);
180
- case "filter":
181
- return cmpQuerySpec(lhs.input, rhs.input);
182
- default:
183
- assertNever(lhs);
184
- }
140
+ if (lhs.type !== rhs.type) return lhs.type < rhs.type ? -1 : 1;
141
+ switch (lhs.type) {
142
+ case "column": return lhs.column < rhs.column ? -1 : lhs.column === rhs.column ? 0 : 1;
143
+ case "inlineColumn": return lhs.spec.id < rhs.spec.id ? -1 : lhs.spec.id === rhs.spec.id ? 0 : 1;
144
+ case "sparseToDenseColumn": return lhs.column < rhs.column ? -1 : lhs.column === rhs.column ? 0 : 1;
145
+ case "innerJoin":
146
+ case "fullJoin": {
147
+ const rhsJoin = rhs;
148
+ if (lhs.entries.length !== rhsJoin.entries.length) return lhs.entries.length - rhsJoin.entries.length;
149
+ for (let i = 0; i < lhs.entries.length; i++) {
150
+ const cmp = cmpQueryJoinEntrySpec(lhs.entries[i], rhsJoin.entries[i]);
151
+ if (cmp !== 0) return cmp;
152
+ }
153
+ return 0;
154
+ }
155
+ case "outerJoin": {
156
+ const rhsOuter = rhs;
157
+ const cmp = cmpQueryJoinEntrySpec(lhs.primary, rhsOuter.primary);
158
+ if (cmp !== 0) return cmp;
159
+ if (lhs.secondary.length !== rhsOuter.secondary.length) return lhs.secondary.length - rhsOuter.secondary.length;
160
+ for (let i = 0; i < lhs.secondary.length; i++) {
161
+ const cmp = cmpQueryJoinEntrySpec(lhs.secondary[i], rhsOuter.secondary[i]);
162
+ if (cmp !== 0) return cmp;
163
+ }
164
+ return 0;
165
+ }
166
+ case "sliceAxes": return cmpQuerySpec(lhs.input, rhs.input);
167
+ case "sort": return cmpQuerySpec(lhs.input, rhs.input);
168
+ case "filter": return cmpQuerySpec(lhs.input, rhs.input);
169
+ default: assertNever(lhs);
170
+ }
185
171
  }
186
172
  function cmpQueryJoinEntrySpec(lhs, rhs) {
187
- const cmp = cmpQuerySpec(lhs.entry, rhs.entry);
188
- if (cmp !== 0)
189
- return cmp;
190
- if (lhs.qualifications.length !== rhs.qualifications.length) {
191
- return lhs.qualifications.length - rhs.qualifications.length;
192
- }
193
- for (let i = 0; i < lhs.qualifications.length; i++) {
194
- const lhsQ = canonicalizeJson(lhs.qualifications[i]);
195
- const rhsQ = canonicalizeJson(rhs.qualifications[i]);
196
- if (lhsQ !== rhsQ)
197
- return lhsQ < rhsQ ? -1 : 1;
198
- }
199
- return 0;
173
+ const cmp = cmpQuerySpec(lhs.entry, rhs.entry);
174
+ if (cmp !== 0) return cmp;
175
+ if (lhs.qualifications.length !== rhs.qualifications.length) return lhs.qualifications.length - rhs.qualifications.length;
176
+ for (let i = 0; i < lhs.qualifications.length; i++) {
177
+ const lhsQ = canonicalizeJson(lhs.qualifications[i]);
178
+ const rhsQ = canonicalizeJson(rhs.qualifications[i]);
179
+ if (lhsQ !== rhsQ) return lhsQ < rhsQ ? -1 : 1;
180
+ }
181
+ return 0;
200
182
  }
201
183
 
184
+ //#endregion
202
185
  export { collectSpecQueryColumns, isBooleanExpression, mapSpecQueryColumns, sortSpecQuery, traverseQuerySpec };
203
- //# sourceMappingURL=utils.js.map
186
+ //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/drivers/pframe/query/utils.ts"],"sourcesContent":["import { canonicalizeJson } from \"../../../json\";\nimport { assertNever } from \"../../../util\";\nimport type {\n SpecQueryBooleanExpression,\n SpecQueryExpression,\n SpecQuery,\n SpecQueryJoinEntry,\n} from \"./query_spec\";\n\nconst booleanTypesSet = new Set<SpecQueryBooleanExpression[\"type\"]>([\n \"numericComparison\",\n \"stringEquals\",\n \"stringContains\",\n \"stringContainsFuzzy\",\n \"stringRegex\",\n \"isNull\",\n \"not\",\n \"and\",\n \"or\",\n \"isIn\",\n]);\n\nexport function isBooleanExpression(expr: SpecQueryExpression): expr is SpecQueryBooleanExpression {\n return booleanTypesSet.has(\n // @ts-expect-error -- TypeScript doesn't understand the discriminated union here, but we do at runtime\n expr.type,\n );\n}\n\n/**\n * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.\n *\n * Traversal order:\n * 1. Recurse into child queries\n * 2. Apply `column` to transform column references in leaf nodes\n * 3. Apply `joinEntry` to each join entry (with inner query already traversed)\n * 4. Assemble node with transformed children\n * 5. Apply `node` to the assembled node\n */\nexport function traverseQuerySpec<C1, C2>(\n query: SpecQuery<C1>,\n visitor: {\n /** Transform column references in leaf nodes (column, sparseToDenseColumn). */\n column: (c: C1) => C2;\n /** Visit a node after its children have been traversed. */\n node?: (node: SpecQuery<C2>) => SpecQuery<C2>;\n /** Visit a join entry after its inner query has been traversed. */\n joinEntry?: (entry: SpecQueryJoinEntry<C2>) => SpecQueryJoinEntry<C2>;\n },\n): SpecQuery<C2> {\n const traverseEntry = (entry: SpecQueryJoinEntry<C1>): SpecQueryJoinEntry<C2> => {\n const traversed: SpecQueryJoinEntry<C2> = {\n ...entry,\n entry: traverseQuerySpec(entry.entry, visitor),\n };\n return visitor.joinEntry ? visitor.joinEntry(traversed) : traversed;\n };\n\n let result: SpecQuery<C2>;\n switch (query.type) {\n case \"column\":\n result = { type: \"column\", column: visitor.column(query.column) };\n break;\n case \"sparseToDenseColumn\":\n result = { ...query, column: visitor.column(query.column) };\n break;\n case \"inlineColumn\":\n result = query;\n break;\n case \"innerJoin\":\n case \"fullJoin\":\n result = { ...query, entries: query.entries.map(traverseEntry) };\n break;\n case \"outerJoin\":\n result = {\n ...query,\n primary: traverseEntry(query.primary),\n secondary: query.secondary.map(traverseEntry),\n };\n break;\n case \"filter\":\n case \"sort\":\n case \"sliceAxes\":\n result = { ...query, input: traverseQuerySpec(query.input, visitor) };\n break;\n default:\n assertNever(query);\n }\n\n return visitor.node ? visitor.node(result) : result;\n}\n\n/** Recursively maps all column references in a SpecQuery tree. */\nexport function mapSpecQueryColumns<C1, C2>(\n query: SpecQuery<C1>,\n cb: (c: C1) => C2,\n): SpecQuery<C2> {\n return traverseQuerySpec(query, { column: cb });\n}\n\n/** Collects all column references from a SpecQuery tree. */\nexport function collectSpecQueryColumns<C>(query: SpecQuery<C>): C[] {\n const result: C[] = [];\n traverseQuerySpec(query, {\n column: (c: C) => {\n result.push(c);\n return c;\n },\n });\n return result;\n}\n\nexport function sortSpecQuery(query: SpecQuery): SpecQuery {\n return traverseQuerySpec(query, {\n column: (c) => c,\n node: (node) => {\n switch (node.type) {\n case \"sparseToDenseColumn\":\n return { ...node, axesIndices: node.axesIndices.toSorted((a, b) => a - b) };\n case \"innerJoin\":\n case \"fullJoin\": {\n const sorted = [...node.entries].sort(cmpQueryJoinEntrySpec);\n return { ...node, entries: sorted };\n }\n case \"outerJoin\": {\n const sorted = [...node.secondary].sort(cmpQueryJoinEntrySpec);\n return { ...node, secondary: sorted };\n }\n case \"sliceAxes\":\n return {\n ...node,\n axisFilters: node.axisFilters.toSorted((a, b) => {\n const ak = canonicalizeJson(a.axisSelector);\n const bk = canonicalizeJson(b.axisSelector);\n return ak < bk ? -1 : ak === bk ? 0 : 1;\n }),\n };\n default:\n return node;\n }\n },\n joinEntry: (entry) => ({\n ...entry,\n qualifications: entry.qualifications.toSorted((a, b) => {\n const ak = canonicalizeJson(a.axis);\n const bk = canonicalizeJson(b.axis);\n return ak < bk ? -1 : ak === bk ? 0 : 1;\n }),\n }),\n });\n}\n\nfunction cmpQuerySpec(lhs: SpecQuery, rhs: SpecQuery): number {\n if (lhs.type !== rhs.type) {\n return lhs.type < rhs.type ? -1 : 1;\n }\n switch (lhs.type) {\n case \"column\":\n return lhs.column < (rhs as typeof lhs).column\n ? -1\n : lhs.column === (rhs as typeof lhs).column\n ? 0\n : 1;\n case \"inlineColumn\":\n return lhs.spec.id < (rhs as typeof lhs).spec.id\n ? -1\n : lhs.spec.id === (rhs as typeof lhs).spec.id\n ? 0\n : 1;\n case \"sparseToDenseColumn\":\n return lhs.column < (rhs as typeof lhs).column\n ? -1\n : lhs.column === (rhs as typeof lhs).column\n ? 0\n : 1;\n case \"innerJoin\":\n case \"fullJoin\": {\n const rhsJoin = rhs as typeof lhs;\n if (lhs.entries.length !== rhsJoin.entries.length) {\n return lhs.entries.length - rhsJoin.entries.length;\n }\n for (let i = 0; i < lhs.entries.length; i++) {\n const cmp = cmpQueryJoinEntrySpec(lhs.entries[i], rhsJoin.entries[i]);\n if (cmp !== 0) return cmp;\n }\n return 0;\n }\n case \"outerJoin\": {\n const rhsOuter = rhs as typeof lhs;\n const cmp = cmpQueryJoinEntrySpec(lhs.primary, rhsOuter.primary);\n if (cmp !== 0) return cmp;\n if (lhs.secondary.length !== rhsOuter.secondary.length) {\n return lhs.secondary.length - rhsOuter.secondary.length;\n }\n for (let i = 0; i < lhs.secondary.length; i++) {\n const cmp = cmpQueryJoinEntrySpec(lhs.secondary[i], rhsOuter.secondary[i]);\n if (cmp !== 0) return cmp;\n }\n return 0;\n }\n case \"sliceAxes\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n case \"sort\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n case \"filter\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n default:\n assertNever(lhs);\n }\n}\n\nfunction cmpQueryJoinEntrySpec(lhs: SpecQueryJoinEntry, rhs: SpecQueryJoinEntry): number {\n const cmp = cmpQuerySpec(lhs.entry, rhs.entry);\n if (cmp !== 0) return cmp;\n if (lhs.qualifications.length !== rhs.qualifications.length) {\n return lhs.qualifications.length - rhs.qualifications.length;\n }\n for (let i = 0; i < lhs.qualifications.length; i++) {\n const lhsQ = canonicalizeJson(lhs.qualifications[i]);\n const rhsQ = canonicalizeJson(rhs.qualifications[i]);\n if (lhsQ !== rhsQ) return lhsQ < rhsQ ? -1 : 1;\n }\n return 0;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/drivers/pframe/query/utils.ts"],"sourcesContent":["import { canonicalizeJson } from \"../../../json\";\nimport { assertNever } from \"../../../util\";\nimport type {\n SpecQueryBooleanExpression,\n SpecQueryExpression,\n SpecQuery,\n SpecQueryJoinEntry,\n} from \"./query_spec\";\n\nconst booleanTypesSet = new Set<SpecQueryBooleanExpression[\"type\"]>([\n \"numericComparison\",\n \"stringEquals\",\n \"stringContains\",\n \"stringContainsFuzzy\",\n \"stringRegex\",\n \"isNull\",\n \"not\",\n \"and\",\n \"or\",\n \"isIn\",\n]);\n\nexport function isBooleanExpression(expr: SpecQueryExpression): expr is SpecQueryBooleanExpression {\n return booleanTypesSet.has(\n // @ts-expect-error -- TypeScript doesn't understand the discriminated union here, but we do at runtime\n expr.type,\n );\n}\n\n/**\n * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.\n *\n * Traversal order:\n * 1. Recurse into child queries\n * 2. Apply `column` to transform column references in leaf nodes\n * 3. Apply `joinEntry` to each join entry (with inner query already traversed)\n * 4. Assemble node with transformed children\n * 5. Apply `node` to the assembled node\n */\nexport function traverseQuerySpec<C1, C2>(\n query: SpecQuery<C1>,\n visitor: {\n /** Transform column references in leaf nodes (column, sparseToDenseColumn). */\n column: (c: C1) => C2;\n /** Visit a node after its children have been traversed. */\n node?: (node: SpecQuery<C2>) => SpecQuery<C2>;\n /** Visit a join entry after its inner query has been traversed. */\n joinEntry?: (entry: SpecQueryJoinEntry<C2>) => SpecQueryJoinEntry<C2>;\n },\n): SpecQuery<C2> {\n const traverseEntry = (entry: SpecQueryJoinEntry<C1>): SpecQueryJoinEntry<C2> => {\n const traversed: SpecQueryJoinEntry<C2> = {\n ...entry,\n entry: traverseQuerySpec(entry.entry, visitor),\n };\n return visitor.joinEntry ? visitor.joinEntry(traversed) : traversed;\n };\n\n let result: SpecQuery<C2>;\n switch (query.type) {\n case \"column\":\n result = { type: \"column\", column: visitor.column(query.column) };\n break;\n case \"sparseToDenseColumn\":\n result = { ...query, column: visitor.column(query.column) };\n break;\n case \"inlineColumn\":\n result = query;\n break;\n case \"innerJoin\":\n case \"fullJoin\":\n result = { ...query, entries: query.entries.map(traverseEntry) };\n break;\n case \"outerJoin\":\n result = {\n ...query,\n primary: traverseEntry(query.primary),\n secondary: query.secondary.map(traverseEntry),\n };\n break;\n case \"filter\":\n case \"sort\":\n case \"sliceAxes\":\n result = { ...query, input: traverseQuerySpec(query.input, visitor) };\n break;\n default:\n assertNever(query);\n }\n\n return visitor.node ? visitor.node(result) : result;\n}\n\n/** Recursively maps all column references in a SpecQuery tree. */\nexport function mapSpecQueryColumns<C1, C2>(\n query: SpecQuery<C1>,\n cb: (c: C1) => C2,\n): SpecQuery<C2> {\n return traverseQuerySpec(query, { column: cb });\n}\n\n/** Collects all column references from a SpecQuery tree. */\nexport function collectSpecQueryColumns<C>(query: SpecQuery<C>): C[] {\n const result: C[] = [];\n traverseQuerySpec(query, {\n column: (c: C) => {\n result.push(c);\n return c;\n },\n });\n return result;\n}\n\nexport function sortSpecQuery(query: SpecQuery): SpecQuery {\n return traverseQuerySpec(query, {\n column: (c) => c,\n node: (node) => {\n switch (node.type) {\n case \"sparseToDenseColumn\":\n return { ...node, axesIndices: node.axesIndices.toSorted((a, b) => a - b) };\n case \"innerJoin\":\n case \"fullJoin\": {\n const sorted = [...node.entries].sort(cmpQueryJoinEntrySpec);\n return { ...node, entries: sorted };\n }\n case \"outerJoin\": {\n const sorted = [...node.secondary].sort(cmpQueryJoinEntrySpec);\n return { ...node, secondary: sorted };\n }\n case \"sliceAxes\":\n return {\n ...node,\n axisFilters: node.axisFilters.toSorted((a, b) => {\n const ak = canonicalizeJson(a.axisSelector);\n const bk = canonicalizeJson(b.axisSelector);\n return ak < bk ? -1 : ak === bk ? 0 : 1;\n }),\n };\n default:\n return node;\n }\n },\n joinEntry: (entry) => ({\n ...entry,\n qualifications: entry.qualifications.toSorted((a, b) => {\n const ak = canonicalizeJson(a.axis);\n const bk = canonicalizeJson(b.axis);\n return ak < bk ? -1 : ak === bk ? 0 : 1;\n }),\n }),\n });\n}\n\nfunction cmpQuerySpec(lhs: SpecQuery, rhs: SpecQuery): number {\n if (lhs.type !== rhs.type) {\n return lhs.type < rhs.type ? -1 : 1;\n }\n switch (lhs.type) {\n case \"column\":\n return lhs.column < (rhs as typeof lhs).column\n ? -1\n : lhs.column === (rhs as typeof lhs).column\n ? 0\n : 1;\n case \"inlineColumn\":\n return lhs.spec.id < (rhs as typeof lhs).spec.id\n ? -1\n : lhs.spec.id === (rhs as typeof lhs).spec.id\n ? 0\n : 1;\n case \"sparseToDenseColumn\":\n return lhs.column < (rhs as typeof lhs).column\n ? -1\n : lhs.column === (rhs as typeof lhs).column\n ? 0\n : 1;\n case \"innerJoin\":\n case \"fullJoin\": {\n const rhsJoin = rhs as typeof lhs;\n if (lhs.entries.length !== rhsJoin.entries.length) {\n return lhs.entries.length - rhsJoin.entries.length;\n }\n for (let i = 0; i < lhs.entries.length; i++) {\n const cmp = cmpQueryJoinEntrySpec(lhs.entries[i], rhsJoin.entries[i]);\n if (cmp !== 0) return cmp;\n }\n return 0;\n }\n case \"outerJoin\": {\n const rhsOuter = rhs as typeof lhs;\n const cmp = cmpQueryJoinEntrySpec(lhs.primary, rhsOuter.primary);\n if (cmp !== 0) return cmp;\n if (lhs.secondary.length !== rhsOuter.secondary.length) {\n return lhs.secondary.length - rhsOuter.secondary.length;\n }\n for (let i = 0; i < lhs.secondary.length; i++) {\n const cmp = cmpQueryJoinEntrySpec(lhs.secondary[i], rhsOuter.secondary[i]);\n if (cmp !== 0) return cmp;\n }\n return 0;\n }\n case \"sliceAxes\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n case \"sort\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n case \"filter\":\n return cmpQuerySpec(lhs.input, (rhs as typeof lhs).input);\n default:\n assertNever(lhs);\n }\n}\n\nfunction cmpQueryJoinEntrySpec(lhs: SpecQueryJoinEntry, rhs: SpecQueryJoinEntry): number {\n const cmp = cmpQuerySpec(lhs.entry, rhs.entry);\n if (cmp !== 0) return cmp;\n if (lhs.qualifications.length !== rhs.qualifications.length) {\n return lhs.qualifications.length - rhs.qualifications.length;\n }\n for (let i = 0; i < lhs.qualifications.length; i++) {\n const lhsQ = canonicalizeJson(lhs.qualifications[i]);\n const rhsQ = canonicalizeJson(rhs.qualifications[i]);\n if (lhsQ !== rhsQ) return lhsQ < rhsQ ? -1 : 1;\n }\n return 0;\n}\n"],"mappings":"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"}