@milaboratories/pl-model-common 1.46.4 → 1.47.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 (178) hide show
  1. package/dist/columns/accessor_traversal.cjs +119 -0
  2. package/dist/columns/accessor_traversal.cjs.map +1 -0
  3. package/dist/columns/accessor_traversal.d.ts +52 -0
  4. package/dist/columns/accessor_traversal.d.ts.map +1 -0
  5. package/dist/columns/accessor_traversal.js +114 -0
  6. package/dist/columns/accessor_traversal.js.map +1 -0
  7. package/dist/columns/column_registry.cjs +40 -0
  8. package/dist/columns/column_registry.cjs.map +1 -0
  9. package/dist/columns/column_registry.d.ts +31 -0
  10. package/dist/columns/column_registry.d.ts.map +1 -0
  11. package/dist/columns/column_registry.js +40 -0
  12. package/dist/columns/column_registry.js.map +1 -0
  13. package/dist/columns/column_selector.cjs +49 -0
  14. package/dist/columns/column_selector.cjs.map +1 -0
  15. package/dist/columns/column_selector.d.ts +33 -0
  16. package/dist/columns/column_selector.d.ts.map +1 -0
  17. package/dist/columns/column_selector.js +47 -0
  18. package/dist/columns/column_selector.js.map +1 -0
  19. package/dist/columns/dedup.cjs +47 -0
  20. package/dist/columns/dedup.cjs.map +1 -0
  21. package/dist/columns/dedup.d.ts +27 -0
  22. package/dist/columns/dedup.d.ts.map +1 -0
  23. package/dist/columns/dedup.js +47 -0
  24. package/dist/columns/dedup.js.map +1 -0
  25. package/dist/columns/index.cjs +18 -0
  26. package/dist/columns/index.d.ts +8 -0
  27. package/dist/columns/index.js +6 -0
  28. package/dist/columns/providers.cjs +62 -0
  29. package/dist/columns/providers.cjs.map +1 -0
  30. package/dist/columns/providers.d.ts +39 -0
  31. package/dist/columns/providers.d.ts.map +1 -0
  32. package/dist/columns/providers.js +61 -0
  33. package/dist/columns/providers.js.map +1 -0
  34. package/dist/columns/types.d.ts +108 -0
  35. package/dist/columns/types.d.ts.map +1 -0
  36. package/dist/driver_kit.d.ts +1 -2
  37. package/dist/driver_kit.d.ts.map +1 -1
  38. package/dist/drivers/columns/columns_collection_driver.d.ts +124 -0
  39. package/dist/drivers/columns/columns_collection_driver.d.ts.map +1 -0
  40. package/dist/drivers/columns/discover_columns_options.cjs +28 -0
  41. package/dist/drivers/columns/discover_columns_options.cjs.map +1 -0
  42. package/dist/drivers/columns/discover_columns_options.d.ts +64 -0
  43. package/dist/drivers/columns/discover_columns_options.d.ts.map +1 -0
  44. package/dist/drivers/columns/discover_columns_options.js +28 -0
  45. package/dist/drivers/columns/discover_columns_options.js.map +1 -0
  46. package/dist/drivers/columns/index.d.ts +3 -0
  47. package/dist/drivers/index.cjs +32 -7
  48. package/dist/drivers/index.d.ts +12 -9
  49. package/dist/drivers/index.js +6 -4
  50. package/dist/drivers/pframe/driver.d.ts +1 -2
  51. package/dist/drivers/pframe/driver.d.ts.map +1 -1
  52. package/dist/drivers/pframe/index.cjs +30 -7
  53. package/dist/drivers/pframe/index.d.ts +9 -8
  54. package/dist/drivers/pframe/index.js +5 -4
  55. package/dist/drivers/pframe/query/index.d.ts +2 -2
  56. package/dist/drivers/pframe/query/query_common.d.ts +24 -1
  57. package/dist/drivers/pframe/query/query_common.d.ts.map +1 -1
  58. package/dist/drivers/pframe/query/query_spec.d.ts +25 -24
  59. package/dist/drivers/pframe/query/query_spec.d.ts.map +1 -1
  60. package/dist/drivers/pframe/query/utils.cjs +18 -8
  61. package/dist/drivers/pframe/query/utils.cjs.map +1 -1
  62. package/dist/drivers/pframe/query/utils.d.ts +5 -1
  63. package/dist/drivers/pframe/query/utils.d.ts.map +1 -1
  64. package/dist/drivers/pframe/query/utils.js +18 -8
  65. package/dist/drivers/pframe/query/utils.js.map +1 -1
  66. package/dist/drivers/pframe/spec/anchored.d.ts +2 -2
  67. package/dist/drivers/pframe/spec/discovered_column.cjs +31 -15
  68. package/dist/drivers/pframe/spec/discovered_column.cjs.map +1 -1
  69. package/dist/drivers/pframe/spec/discovered_column.d.ts +23 -13
  70. package/dist/drivers/pframe/spec/discovered_column.d.ts.map +1 -1
  71. package/dist/drivers/pframe/spec/discovered_column.js +26 -12
  72. package/dist/drivers/pframe/spec/discovered_column.js.map +1 -1
  73. package/dist/drivers/pframe/spec/filtered_column.cjs +46 -0
  74. package/dist/drivers/pframe/spec/filtered_column.cjs.map +1 -1
  75. package/dist/drivers/pframe/spec/filtered_column.d.ts +39 -1
  76. package/dist/drivers/pframe/spec/filtered_column.d.ts.map +1 -1
  77. package/dist/drivers/pframe/spec/filtered_column.js +41 -1
  78. package/dist/drivers/pframe/spec/filtered_column.js.map +1 -1
  79. package/dist/drivers/pframe/spec/ids.cjs +62 -10
  80. package/dist/drivers/pframe/spec/ids.cjs.map +1 -1
  81. package/dist/drivers/pframe/spec/ids.d.ts +48 -15
  82. package/dist/drivers/pframe/spec/ids.d.ts.map +1 -1
  83. package/dist/drivers/pframe/spec/ids.js +60 -9
  84. package/dist/drivers/pframe/spec/ids.js.map +1 -1
  85. package/dist/drivers/pframe/spec/index.cjs +30 -7
  86. package/dist/drivers/pframe/spec/index.d.ts +6 -5
  87. package/dist/drivers/pframe/spec/index.js +5 -4
  88. package/dist/drivers/pframe/spec/native_id.cjs +1 -0
  89. package/dist/drivers/pframe/spec/native_id.cjs.map +1 -1
  90. package/dist/drivers/pframe/spec/native_id.js +1 -0
  91. package/dist/drivers/pframe/spec/native_id.js.map +1 -1
  92. package/dist/drivers/pframe/spec/overridden.cjs +212 -0
  93. package/dist/drivers/pframe/spec/overridden.cjs.map +1 -0
  94. package/dist/drivers/pframe/spec/overridden.d.ts +67 -0
  95. package/dist/drivers/pframe/spec/overridden.d.ts.map +1 -0
  96. package/dist/drivers/pframe/spec/overridden.js +202 -0
  97. package/dist/drivers/pframe/spec/overridden.js.map +1 -0
  98. package/dist/drivers/pframe/spec/selectors.cjs +1 -0
  99. package/dist/drivers/pframe/spec/selectors.cjs.map +1 -1
  100. package/dist/drivers/pframe/spec/selectors.d.ts +3 -0
  101. package/dist/drivers/pframe/spec/selectors.d.ts.map +1 -1
  102. package/dist/drivers/pframe/spec/selectors.js +1 -0
  103. package/dist/drivers/pframe/spec/selectors.js.map +1 -1
  104. package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
  105. package/dist/drivers/pframe/spec/spec.d.ts +2 -3
  106. package/dist/drivers/pframe/spec/spec.d.ts.map +1 -1
  107. package/dist/drivers/pframe/spec/spec.js.map +1 -1
  108. package/dist/drivers/pframe/spec_driver.d.ts +2 -2
  109. package/dist/drivers/pframe/spec_driver.d.ts.map +1 -1
  110. package/dist/drivers/pframe/table_calculate.cjs +2 -2
  111. package/dist/drivers/pframe/table_calculate.cjs.map +1 -1
  112. package/dist/drivers/pframe/table_calculate.d.ts +6 -2
  113. package/dist/drivers/pframe/table_calculate.d.ts.map +1 -1
  114. package/dist/drivers/pframe/table_calculate.js +2 -2
  115. package/dist/drivers/pframe/table_calculate.js.map +1 -1
  116. package/dist/drivers/pframe/table_common.cjs.map +1 -1
  117. package/dist/drivers/pframe/table_common.d.ts +11 -4
  118. package/dist/drivers/pframe/table_common.d.ts.map +1 -1
  119. package/dist/drivers/pframe/table_common.js.map +1 -1
  120. package/dist/index.cjs +63 -10
  121. package/dist/index.d.ts +20 -11
  122. package/dist/index.js +15 -6
  123. package/dist/pool/index.cjs +18 -0
  124. package/dist/pool/index.d.ts +2 -2
  125. package/dist/pool/index.js +3 -0
  126. package/dist/pool/spec.cjs +59 -11
  127. package/dist/pool/spec.cjs.map +1 -1
  128. package/dist/pool/spec.d.ts +24 -9
  129. package/dist/pool/spec.d.ts.map +1 -1
  130. package/dist/pool/spec.js +50 -10
  131. package/dist/pool/spec.js.map +1 -1
  132. package/dist/services/index.d.ts +2 -2
  133. package/dist/services/service_declarations.cjs +22 -0
  134. package/dist/services/service_declarations.cjs.map +1 -1
  135. package/dist/services/service_declarations.d.ts +5 -3
  136. package/dist/services/service_declarations.d.ts.map +1 -1
  137. package/dist/services/service_declarations.js +22 -0
  138. package/dist/services/service_declarations.js.map +1 -1
  139. package/dist/services/service_registry.cjs.map +1 -1
  140. package/dist/services/service_registry.d.ts +3 -3
  141. package/dist/services/service_registry.d.ts.map +1 -1
  142. package/dist/services/service_registry.js.map +1 -1
  143. package/dist/services/service_types.cjs.map +1 -1
  144. package/dist/services/service_types.d.ts +25 -9
  145. package/dist/services/service_types.d.ts.map +1 -1
  146. package/dist/services/service_types.js.map +1 -1
  147. package/package.json +2 -1
  148. package/src/columns/accessor_traversal.ts +139 -0
  149. package/src/columns/column_registry.ts +41 -0
  150. package/src/columns/column_selector.ts +100 -0
  151. package/src/columns/dedup.ts +49 -0
  152. package/src/columns/index.ts +6 -0
  153. package/src/columns/providers.ts +74 -0
  154. package/src/columns/types.ts +116 -0
  155. package/src/drivers/columns/columns_collection_driver.ts +146 -0
  156. package/src/drivers/columns/discover_columns_options.ts +91 -0
  157. package/src/drivers/columns/index.ts +2 -0
  158. package/src/drivers/index.ts +1 -0
  159. package/src/drivers/pframe/index.ts +0 -1
  160. package/src/drivers/pframe/query/query_common.ts +24 -0
  161. package/src/drivers/pframe/query/query_spec.ts +38 -25
  162. package/src/drivers/pframe/query/utils.test.ts +6 -6
  163. package/src/drivers/pframe/query/utils.ts +27 -7
  164. package/src/drivers/pframe/spec/discovered_column.ts +43 -28
  165. package/src/drivers/pframe/spec/filtered_column.ts +66 -0
  166. package/src/drivers/pframe/spec/ids.ts +142 -17
  167. package/src/drivers/pframe/spec/index.ts +1 -0
  168. package/src/drivers/pframe/spec/overridden.ts +285 -0
  169. package/src/drivers/pframe/spec/selectors.ts +3 -0
  170. package/src/drivers/pframe/spec/spec.ts +7 -3
  171. package/src/drivers/pframe/spec_driver.ts +3 -3
  172. package/src/drivers/pframe/table_calculate.ts +13 -3
  173. package/src/drivers/pframe/table_common.ts +10 -3
  174. package/src/index.ts +1 -0
  175. package/src/pool/spec.ts +69 -23
  176. package/src/services/service_declarations.ts +31 -0
  177. package/src/services/service_registry.ts +8 -4
  178. package/src/services/service_types.ts +35 -9
@@ -0,0 +1,119 @@
1
+ const require_spec = require("../pool/spec.cjs");
2
+ require("../pool/index.cjs");
3
+ const require_resource_types = require("../resource_types.cjs");
4
+ //#region src/columns/accessor_traversal.ts
5
+ /** Resource types that hold column collections — DFS stops here and collects. */
6
+ const COLLECT_TYPES = [require_resource_types.ResourceTypeName.PFrame];
7
+ /** Resource types DFS descends through when looking for PFrames. */
8
+ const DESCEND_TYPES = [require_resource_types.ResourceTypeName.StdMap, require_resource_types.ResourceTypeName.StdMapSlash];
9
+ /**
10
+ * Enumerate column names backing a PFrame accessor — derived from
11
+ * `<name>.spec` field names, without resolving the spec resources.
12
+ */
13
+ function listColumnNames(accessor, prefix = "") {
14
+ if (accessor.resourceType.name !== require_resource_types.ResourceTypeName.PFrame) return [];
15
+ const out = [];
16
+ for (const field of accessor.listInputFields()) {
17
+ if (!field.endsWith(".spec")) continue;
18
+ const raw = field.slice(0, -5);
19
+ if (!raw.startsWith(prefix)) continue;
20
+ out.push(raw.slice(prefix.length));
21
+ }
22
+ return out;
23
+ }
24
+ /**
25
+ * DFS over the input-field subtree of `root`. Collects nodes whose resource
26
+ * type ∈ `collectTypes`. Descends only through `descendTypes`
27
+ * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
28
+ *
29
+ * Threads the field-name path from `rootPath` to each hit, so callers can
30
+ * build canonical {@link createLocalPObjectId}s without relying on the
31
+ * accessor itself to remember its path.
32
+ *
33
+ * Includes `root` itself in the walk.
34
+ */
35
+ function findDescendantsByType(opts) {
36
+ const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
37
+ const collectSet = new Set(collectTypes);
38
+ const descendSet = new Set(descendTypes);
39
+ const result = [];
40
+ const stack = [{
41
+ node: root,
42
+ path: rootPath
43
+ }];
44
+ while (stack.length > 0) {
45
+ const { node, path } = stack.pop();
46
+ const typeName = node.resourceType.name;
47
+ if (collectSet.has(typeName)) {
48
+ result.push({
49
+ node,
50
+ path
51
+ });
52
+ continue;
53
+ }
54
+ if (!descendSet.has(typeName)) continue;
55
+ const fields = node.listInputFields();
56
+ for (let i = fields.length - 1; i >= 0; i--) {
57
+ const child = node.traverse({
58
+ field: fields[i],
59
+ assertFieldType: "Input",
60
+ ignoreError: true
61
+ });
62
+ if (child !== void 0) stack.push({
63
+ node: child,
64
+ path: [...path, fields[i]]
65
+ });
66
+ }
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Walk an accessor root and return one {@link LeafEntry} per discovered column.
72
+ * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
73
+ * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
74
+ */
75
+ function indexAccessorRoot(root, rootPath) {
76
+ const result = [];
77
+ for (const { node, path } of findDescendantsByType({
78
+ root,
79
+ rootPath,
80
+ collectTypes: COLLECT_TYPES,
81
+ descendTypes: DESCEND_TYPES
82
+ })) for (const name of listColumnNames(node)) result.push({
83
+ accessor: node,
84
+ name,
85
+ id: require_spec.createLocalPObjectId([...path], name)
86
+ });
87
+ return result;
88
+ }
89
+ /**
90
+ * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
91
+ * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
92
+ * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
93
+ */
94
+ function indexPoolBlock(block) {
95
+ const accessors = [];
96
+ if (block.prodCtx) accessors.push(block.prodCtx);
97
+ if (block.stagingCtx) accessors.push(block.stagingCtx);
98
+ const result = [];
99
+ const seen = /* @__PURE__ */ new Set();
100
+ for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
101
+ if (seen.has(name)) continue;
102
+ seen.add(name);
103
+ result.push({
104
+ accessor,
105
+ name,
106
+ id: require_spec.createGlobalPObjectId(block.blockId, name)
107
+ });
108
+ }
109
+ return result;
110
+ }
111
+ //#endregion
112
+ exports.COLLECT_TYPES = COLLECT_TYPES;
113
+ exports.DESCEND_TYPES = DESCEND_TYPES;
114
+ exports.findDescendantsByType = findDescendantsByType;
115
+ exports.indexAccessorRoot = indexAccessorRoot;
116
+ exports.indexPoolBlock = indexPoolBlock;
117
+ exports.listColumnNames = listColumnNames;
118
+
119
+ //# sourceMappingURL=accessor_traversal.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessor_traversal.cjs","names":["ResourceTypeName","createLocalPObjectId","createGlobalPObjectId"],"sources":["../../src/columns/accessor_traversal.ts"],"sourcesContent":["import { createGlobalPObjectId, createLocalPObjectId } from \"../pool\";\nimport { ResourceTypeName } from \"../resource_types\";\nimport type { AccessorLike, LeafEntry, UpstreamBlockCtx } from \"./types\";\n\n/** Resource types that hold column collections — DFS stops here and collects. */\nexport const COLLECT_TYPES: ReadonlyArray<string> = [ResourceTypeName.PFrame];\n\n/** Resource types DFS descends through when looking for PFrames. */\nexport const DESCEND_TYPES: ReadonlyArray<string> = [\n ResourceTypeName.StdMap,\n ResourceTypeName.StdMapSlash,\n];\n\n/**\n * Enumerate column names backing a PFrame accessor — derived from\n * `<name>.spec` field names, without resolving the spec resources.\n */\nexport function listColumnNames<A extends AccessorLike<A>>(\n accessor: A,\n prefix: string = \"\",\n): string[] {\n if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];\n const out: string[] = [];\n for (const field of accessor.listInputFields()) {\n if (!field.endsWith(\".spec\")) continue;\n const raw = field.slice(0, -\".spec\".length);\n if (!raw.startsWith(prefix)) continue;\n out.push(raw.slice(prefix.length));\n }\n return out;\n}\n\n/**\n * One DFS hit — the accessor whose resource-type matched `collectTypes`, and\n * the field-name path from the DFS root used to reach it.\n */\ntype DescendantHit<A extends AccessorLike<A>> = {\n readonly node: A;\n readonly path: ReadonlyArray<string>;\n};\n\n/**\n * DFS over the input-field subtree of `root`. Collects nodes whose resource\n * type ∈ `collectTypes`. Descends only through `descendTypes`\n * (default: StdMap / StdMapSlash). Collected nodes are not descended into.\n *\n * Threads the field-name path from `rootPath` to each hit, so callers can\n * build canonical {@link createLocalPObjectId}s without relying on the\n * accessor itself to remember its path.\n *\n * Includes `root` itself in the walk.\n */\nexport function findDescendantsByType<A extends AccessorLike<A>>(opts: {\n root: A;\n rootPath: ReadonlyArray<string>;\n collectTypes: ReadonlyArray<string>;\n descendTypes?: ReadonlyArray<string>;\n}): DescendantHit<A>[] {\n const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;\n const collectSet = new Set(collectTypes);\n const descendSet = new Set(descendTypes);\n const result: DescendantHit<A>[] = [];\n\n const stack: DescendantHit<A>[] = [{ node: root, path: rootPath }];\n while (stack.length > 0) {\n const { node, path } = stack.pop()!;\n const typeName = node.resourceType.name;\n if (collectSet.has(typeName)) {\n result.push({ node, path });\n continue;\n }\n if (!descendSet.has(typeName)) continue;\n const fields = node.listInputFields();\n for (let i = fields.length - 1; i >= 0; i--) {\n const child = node.traverse({\n field: fields[i],\n assertFieldType: \"Input\",\n ignoreError: true,\n });\n if (child !== undefined) stack.push({ node: child, path: [...path, fields[i]] });\n }\n }\n return result;\n}\n\n/**\n * Walk an accessor root and return one {@link LeafEntry} per discovered column.\n * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The\n * `resolvePath` is derived from `rootPath` extended by the DFS traversal.\n */\nexport function indexAccessorRoot<A extends AccessorLike<A>>(\n root: A,\n rootPath: ReadonlyArray<string>,\n): LeafEntry<A>[] {\n const result: LeafEntry<A>[] = [];\n for (const { node, path } of findDescendantsByType({\n root,\n rootPath,\n collectTypes: COLLECT_TYPES,\n descendTypes: DESCEND_TYPES,\n })) {\n for (const name of listColumnNames(node)) {\n result.push({\n accessor: node,\n name,\n id: createLocalPObjectId([...path], name),\n });\n }\n }\n return result;\n}\n\n/**\n * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one\n * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).\n * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.\n */\nexport function indexPoolBlock<A extends AccessorLike<A>>(\n block: UpstreamBlockCtx<A>,\n): LeafEntry<A>[] {\n const accessors: A[] = [];\n if (block.prodCtx) accessors.push(block.prodCtx);\n if (block.stagingCtx) accessors.push(block.stagingCtx);\n\n const result: LeafEntry<A>[] = [];\n const seen = new Set<string>();\n for (const accessor of accessors) {\n for (const name of listColumnNames(accessor)) {\n if (seen.has(name)) continue;\n seen.add(name);\n result.push({\n accessor,\n name,\n id: createGlobalPObjectId(block.blockId, name),\n });\n }\n }\n return result;\n}\n"],"mappings":";;;;;AAKA,MAAa,gBAAuC,CAACA,uBAAAA,iBAAiB,MAAM;;AAG5E,MAAa,gBAAuC,CAClDA,uBAAAA,iBAAiB,QACjBA,uBAAAA,iBAAiB,WACnB;;;;;AAMA,SAAgB,gBACd,UACA,SAAiB,IACP;CACV,IAAI,SAAS,aAAa,SAASA,uBAAAA,iBAAiB,QAAQ,OAAO,CAAC;CACpE,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,SAAS,SAAS,gBAAgB,GAAG;EAC9C,IAAI,CAAC,MAAM,SAAS,OAAO,GAAG;EAC9B,MAAM,MAAM,MAAM,MAAM,GAAG,EAAe;EAC1C,IAAI,CAAC,IAAI,WAAW,MAAM,GAAG;EAC7B,IAAI,KAAK,IAAI,MAAM,OAAO,MAAM,CAAC;CACnC;CACA,OAAO;AACT;;;;;;;;;;;;AAsBA,SAAgB,sBAAiD,MAK1C;CACrB,MAAM,EAAE,MAAM,UAAU,cAAc,eAAe,kBAAkB;CACvE,MAAM,aAAa,IAAI,IAAI,YAAY;CACvC,MAAM,aAAa,IAAI,IAAI,YAAY;CACvC,MAAM,SAA6B,CAAC;CAEpC,MAAM,QAA4B,CAAC;EAAE,MAAM;EAAM,MAAM;CAAS,CAAC;CACjE,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,EAAE,MAAM,SAAS,MAAM,IAAI;EACjC,MAAM,WAAW,KAAK,aAAa;EACnC,IAAI,WAAW,IAAI,QAAQ,GAAG;GAC5B,OAAO,KAAK;IAAE;IAAM;GAAK,CAAC;GAC1B;EACF;EACA,IAAI,CAAC,WAAW,IAAI,QAAQ,GAAG;EAC/B,MAAM,SAAS,KAAK,gBAAgB;EACpC,KAAK,IAAI,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;GAC3C,MAAM,QAAQ,KAAK,SAAS;IAC1B,OAAO,OAAO;IACd,iBAAiB;IACjB,aAAa;GACf,CAAC;GACD,IAAI,UAAU,KAAA,GAAW,MAAM,KAAK;IAAE,MAAM;IAAO,MAAM,CAAC,GAAG,MAAM,OAAO,EAAE;GAAE,CAAC;EACjF;CACF;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,kBACd,MACA,UACgB;CAChB,MAAM,SAAyB,CAAC;CAChC,KAAK,MAAM,EAAE,MAAM,UAAU,sBAAsB;EACjD;EACA;EACA,cAAc;EACd,cAAc;CAChB,CAAC,GACC,KAAK,MAAM,QAAQ,gBAAgB,IAAI,GACrC,OAAO,KAAK;EACV,UAAU;EACV;EACA,IAAIC,aAAAA,qBAAqB,CAAC,GAAG,IAAI,GAAG,IAAI;CAC1C,CAAC;CAGL,OAAO;AACT;;;;;;AAOA,SAAgB,eACd,OACgB;CAChB,MAAM,YAAiB,CAAC;CACxB,IAAI,MAAM,SAAS,UAAU,KAAK,MAAM,OAAO;CAC/C,IAAI,MAAM,YAAY,UAAU,KAAK,MAAM,UAAU;CAErD,MAAM,SAAyB,CAAC;CAChC,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,YAAY,WACrB,KAAK,MAAM,QAAQ,gBAAgB,QAAQ,GAAG;EAC5C,IAAI,KAAK,IAAI,IAAI,GAAG;EACpB,KAAK,IAAI,IAAI;EACb,OAAO,KAAK;GACV;GACA;GACA,IAAIC,aAAAA,sBAAsB,MAAM,SAAS,IAAI;EAC/C,CAAC;CACH;CAEF,OAAO;AACT"}
@@ -0,0 +1,52 @@
1
+ import { AccessorLike, LeafEntry, UpstreamBlockCtx } from "./types.js";
2
+
3
+ //#region src/columns/accessor_traversal.d.ts
4
+ /** Resource types that hold column collections — DFS stops here and collects. */
5
+ declare const COLLECT_TYPES: ReadonlyArray<string>;
6
+ /** Resource types DFS descends through when looking for PFrames. */
7
+ declare const DESCEND_TYPES: ReadonlyArray<string>;
8
+ /**
9
+ * Enumerate column names backing a PFrame accessor — derived from
10
+ * `<name>.spec` field names, without resolving the spec resources.
11
+ */
12
+ declare function listColumnNames<A extends AccessorLike<A>>(accessor: A, prefix?: string): string[];
13
+ /**
14
+ * One DFS hit — the accessor whose resource-type matched `collectTypes`, and
15
+ * the field-name path from the DFS root used to reach it.
16
+ */
17
+ type DescendantHit<A extends AccessorLike<A>> = {
18
+ readonly node: A;
19
+ readonly path: ReadonlyArray<string>;
20
+ };
21
+ /**
22
+ * DFS over the input-field subtree of `root`. Collects nodes whose resource
23
+ * type ∈ `collectTypes`. Descends only through `descendTypes`
24
+ * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
25
+ *
26
+ * Threads the field-name path from `rootPath` to each hit, so callers can
27
+ * build canonical {@link createLocalPObjectId}s without relying on the
28
+ * accessor itself to remember its path.
29
+ *
30
+ * Includes `root` itself in the walk.
31
+ */
32
+ declare function findDescendantsByType<A extends AccessorLike<A>>(opts: {
33
+ root: A;
34
+ rootPath: ReadonlyArray<string>;
35
+ collectTypes: ReadonlyArray<string>;
36
+ descendTypes?: ReadonlyArray<string>;
37
+ }): DescendantHit<A>[];
38
+ /**
39
+ * Walk an accessor root and return one {@link LeafEntry} per discovered column.
40
+ * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
41
+ * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
42
+ */
43
+ declare function indexAccessorRoot<A extends AccessorLike<A>>(root: A, rootPath: ReadonlyArray<string>): LeafEntry<A>[];
44
+ /**
45
+ * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
46
+ * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
47
+ * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
48
+ */
49
+ declare function indexPoolBlock<A extends AccessorLike<A>>(block: UpstreamBlockCtx<A>): LeafEntry<A>[];
50
+ //#endregion
51
+ export { COLLECT_TYPES, DESCEND_TYPES, findDescendantsByType, indexAccessorRoot, indexPoolBlock, listColumnNames };
52
+ //# sourceMappingURL=accessor_traversal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessor_traversal.d.ts","names":[],"sources":["../../src/columns/accessor_traversal.ts"],"mappings":";;;;cAKa,aAAA,EAAe,aAAa;AAAzC;AAAA,cAGa,aAAA,EAAe,aAAa;;;AAHA;AAGzC;iBASgB,eAAA,WAA0B,YAAA,CAAa,CAAA,GACrD,QAAA,EAAU,CAAA,EACV,MAAA;;;AAXuC;AASzC;KAmBK,aAAA,WAAwB,YAAA,CAAa,CAAA;EAAA,SAC/B,IAAA,EAAM,CAAA;EAAA,SACN,IAAA,EAAM,aAAA;AAAA;;;;;;;;;;;AAnBI;iBAiCL,qBAAA,WAAgC,YAAA,CAAa,CAAA,GAAI,IAAA;EAC/D,IAAA,EAAM,CAAA;EACN,QAAA,EAAU,aAAA;EACV,YAAA,EAAc,aAAA;EACd,YAAA,GAAe,aAAA;AAAA,IACb,aAAA,CAAc,CAAA;;;;;;iBAiCF,iBAAA,WAA4B,YAAA,CAAa,CAAA,GACvD,IAAA,EAAM,CAAA,EACN,QAAA,EAAU,aAAA,WACT,SAAA,CAAU,CAAA;;;;;;iBAwBG,cAAA,WAAyB,YAAA,CAAa,CAAA,GACpD,KAAA,EAAO,gBAAA,CAAiB,CAAA,IACvB,SAAA,CAAU,CAAA"}
@@ -0,0 +1,114 @@
1
+ import { createGlobalPObjectId, createLocalPObjectId } from "../pool/spec.js";
2
+ import "../pool/index.js";
3
+ import { ResourceTypeName } from "../resource_types.js";
4
+ //#region src/columns/accessor_traversal.ts
5
+ /** Resource types that hold column collections — DFS stops here and collects. */
6
+ const COLLECT_TYPES = [ResourceTypeName.PFrame];
7
+ /** Resource types DFS descends through when looking for PFrames. */
8
+ const DESCEND_TYPES = [ResourceTypeName.StdMap, ResourceTypeName.StdMapSlash];
9
+ /**
10
+ * Enumerate column names backing a PFrame accessor — derived from
11
+ * `<name>.spec` field names, without resolving the spec resources.
12
+ */
13
+ function listColumnNames(accessor, prefix = "") {
14
+ if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];
15
+ const out = [];
16
+ for (const field of accessor.listInputFields()) {
17
+ if (!field.endsWith(".spec")) continue;
18
+ const raw = field.slice(0, -5);
19
+ if (!raw.startsWith(prefix)) continue;
20
+ out.push(raw.slice(prefix.length));
21
+ }
22
+ return out;
23
+ }
24
+ /**
25
+ * DFS over the input-field subtree of `root`. Collects nodes whose resource
26
+ * type ∈ `collectTypes`. Descends only through `descendTypes`
27
+ * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
28
+ *
29
+ * Threads the field-name path from `rootPath` to each hit, so callers can
30
+ * build canonical {@link createLocalPObjectId}s without relying on the
31
+ * accessor itself to remember its path.
32
+ *
33
+ * Includes `root` itself in the walk.
34
+ */
35
+ function findDescendantsByType(opts) {
36
+ const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
37
+ const collectSet = new Set(collectTypes);
38
+ const descendSet = new Set(descendTypes);
39
+ const result = [];
40
+ const stack = [{
41
+ node: root,
42
+ path: rootPath
43
+ }];
44
+ while (stack.length > 0) {
45
+ const { node, path } = stack.pop();
46
+ const typeName = node.resourceType.name;
47
+ if (collectSet.has(typeName)) {
48
+ result.push({
49
+ node,
50
+ path
51
+ });
52
+ continue;
53
+ }
54
+ if (!descendSet.has(typeName)) continue;
55
+ const fields = node.listInputFields();
56
+ for (let i = fields.length - 1; i >= 0; i--) {
57
+ const child = node.traverse({
58
+ field: fields[i],
59
+ assertFieldType: "Input",
60
+ ignoreError: true
61
+ });
62
+ if (child !== void 0) stack.push({
63
+ node: child,
64
+ path: [...path, fields[i]]
65
+ });
66
+ }
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Walk an accessor root and return one {@link LeafEntry} per discovered column.
72
+ * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
73
+ * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
74
+ */
75
+ function indexAccessorRoot(root, rootPath) {
76
+ const result = [];
77
+ for (const { node, path } of findDescendantsByType({
78
+ root,
79
+ rootPath,
80
+ collectTypes: COLLECT_TYPES,
81
+ descendTypes: DESCEND_TYPES
82
+ })) for (const name of listColumnNames(node)) result.push({
83
+ accessor: node,
84
+ name,
85
+ id: createLocalPObjectId([...path], name)
86
+ });
87
+ return result;
88
+ }
89
+ /**
90
+ * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
91
+ * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
92
+ * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
93
+ */
94
+ function indexPoolBlock(block) {
95
+ const accessors = [];
96
+ if (block.prodCtx) accessors.push(block.prodCtx);
97
+ if (block.stagingCtx) accessors.push(block.stagingCtx);
98
+ const result = [];
99
+ const seen = /* @__PURE__ */ new Set();
100
+ for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
101
+ if (seen.has(name)) continue;
102
+ seen.add(name);
103
+ result.push({
104
+ accessor,
105
+ name,
106
+ id: createGlobalPObjectId(block.blockId, name)
107
+ });
108
+ }
109
+ return result;
110
+ }
111
+ //#endregion
112
+ export { COLLECT_TYPES, DESCEND_TYPES, findDescendantsByType, indexAccessorRoot, indexPoolBlock, listColumnNames };
113
+
114
+ //# sourceMappingURL=accessor_traversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessor_traversal.js","names":[],"sources":["../../src/columns/accessor_traversal.ts"],"sourcesContent":["import { createGlobalPObjectId, createLocalPObjectId } from \"../pool\";\nimport { ResourceTypeName } from \"../resource_types\";\nimport type { AccessorLike, LeafEntry, UpstreamBlockCtx } from \"./types\";\n\n/** Resource types that hold column collections — DFS stops here and collects. */\nexport const COLLECT_TYPES: ReadonlyArray<string> = [ResourceTypeName.PFrame];\n\n/** Resource types DFS descends through when looking for PFrames. */\nexport const DESCEND_TYPES: ReadonlyArray<string> = [\n ResourceTypeName.StdMap,\n ResourceTypeName.StdMapSlash,\n];\n\n/**\n * Enumerate column names backing a PFrame accessor — derived from\n * `<name>.spec` field names, without resolving the spec resources.\n */\nexport function listColumnNames<A extends AccessorLike<A>>(\n accessor: A,\n prefix: string = \"\",\n): string[] {\n if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];\n const out: string[] = [];\n for (const field of accessor.listInputFields()) {\n if (!field.endsWith(\".spec\")) continue;\n const raw = field.slice(0, -\".spec\".length);\n if (!raw.startsWith(prefix)) continue;\n out.push(raw.slice(prefix.length));\n }\n return out;\n}\n\n/**\n * One DFS hit — the accessor whose resource-type matched `collectTypes`, and\n * the field-name path from the DFS root used to reach it.\n */\ntype DescendantHit<A extends AccessorLike<A>> = {\n readonly node: A;\n readonly path: ReadonlyArray<string>;\n};\n\n/**\n * DFS over the input-field subtree of `root`. Collects nodes whose resource\n * type ∈ `collectTypes`. Descends only through `descendTypes`\n * (default: StdMap / StdMapSlash). Collected nodes are not descended into.\n *\n * Threads the field-name path from `rootPath` to each hit, so callers can\n * build canonical {@link createLocalPObjectId}s without relying on the\n * accessor itself to remember its path.\n *\n * Includes `root` itself in the walk.\n */\nexport function findDescendantsByType<A extends AccessorLike<A>>(opts: {\n root: A;\n rootPath: ReadonlyArray<string>;\n collectTypes: ReadonlyArray<string>;\n descendTypes?: ReadonlyArray<string>;\n}): DescendantHit<A>[] {\n const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;\n const collectSet = new Set(collectTypes);\n const descendSet = new Set(descendTypes);\n const result: DescendantHit<A>[] = [];\n\n const stack: DescendantHit<A>[] = [{ node: root, path: rootPath }];\n while (stack.length > 0) {\n const { node, path } = stack.pop()!;\n const typeName = node.resourceType.name;\n if (collectSet.has(typeName)) {\n result.push({ node, path });\n continue;\n }\n if (!descendSet.has(typeName)) continue;\n const fields = node.listInputFields();\n for (let i = fields.length - 1; i >= 0; i--) {\n const child = node.traverse({\n field: fields[i],\n assertFieldType: \"Input\",\n ignoreError: true,\n });\n if (child !== undefined) stack.push({ node: child, path: [...path, fields[i]] });\n }\n }\n return result;\n}\n\n/**\n * Walk an accessor root and return one {@link LeafEntry} per discovered column.\n * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The\n * `resolvePath` is derived from `rootPath` extended by the DFS traversal.\n */\nexport function indexAccessorRoot<A extends AccessorLike<A>>(\n root: A,\n rootPath: ReadonlyArray<string>,\n): LeafEntry<A>[] {\n const result: LeafEntry<A>[] = [];\n for (const { node, path } of findDescendantsByType({\n root,\n rootPath,\n collectTypes: COLLECT_TYPES,\n descendTypes: DESCEND_TYPES,\n })) {\n for (const name of listColumnNames(node)) {\n result.push({\n accessor: node,\n name,\n id: createLocalPObjectId([...path], name),\n });\n }\n }\n return result;\n}\n\n/**\n * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one\n * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).\n * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.\n */\nexport function indexPoolBlock<A extends AccessorLike<A>>(\n block: UpstreamBlockCtx<A>,\n): LeafEntry<A>[] {\n const accessors: A[] = [];\n if (block.prodCtx) accessors.push(block.prodCtx);\n if (block.stagingCtx) accessors.push(block.stagingCtx);\n\n const result: LeafEntry<A>[] = [];\n const seen = new Set<string>();\n for (const accessor of accessors) {\n for (const name of listColumnNames(accessor)) {\n if (seen.has(name)) continue;\n seen.add(name);\n result.push({\n accessor,\n name,\n id: createGlobalPObjectId(block.blockId, name),\n });\n }\n }\n return result;\n}\n"],"mappings":";;;;;AAKA,MAAa,gBAAuC,CAAC,iBAAiB,MAAM;;AAG5E,MAAa,gBAAuC,CAClD,iBAAiB,QACjB,iBAAiB,WACnB;;;;;AAMA,SAAgB,gBACd,UACA,SAAiB,IACP;CACV,IAAI,SAAS,aAAa,SAAS,iBAAiB,QAAQ,OAAO,CAAC;CACpE,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,SAAS,SAAS,gBAAgB,GAAG;EAC9C,IAAI,CAAC,MAAM,SAAS,OAAO,GAAG;EAC9B,MAAM,MAAM,MAAM,MAAM,GAAG,EAAe;EAC1C,IAAI,CAAC,IAAI,WAAW,MAAM,GAAG;EAC7B,IAAI,KAAK,IAAI,MAAM,OAAO,MAAM,CAAC;CACnC;CACA,OAAO;AACT;;;;;;;;;;;;AAsBA,SAAgB,sBAAiD,MAK1C;CACrB,MAAM,EAAE,MAAM,UAAU,cAAc,eAAe,kBAAkB;CACvE,MAAM,aAAa,IAAI,IAAI,YAAY;CACvC,MAAM,aAAa,IAAI,IAAI,YAAY;CACvC,MAAM,SAA6B,CAAC;CAEpC,MAAM,QAA4B,CAAC;EAAE,MAAM;EAAM,MAAM;CAAS,CAAC;CACjE,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,EAAE,MAAM,SAAS,MAAM,IAAI;EACjC,MAAM,WAAW,KAAK,aAAa;EACnC,IAAI,WAAW,IAAI,QAAQ,GAAG;GAC5B,OAAO,KAAK;IAAE;IAAM;GAAK,CAAC;GAC1B;EACF;EACA,IAAI,CAAC,WAAW,IAAI,QAAQ,GAAG;EAC/B,MAAM,SAAS,KAAK,gBAAgB;EACpC,KAAK,IAAI,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;GAC3C,MAAM,QAAQ,KAAK,SAAS;IAC1B,OAAO,OAAO;IACd,iBAAiB;IACjB,aAAa;GACf,CAAC;GACD,IAAI,UAAU,KAAA,GAAW,MAAM,KAAK;IAAE,MAAM;IAAO,MAAM,CAAC,GAAG,MAAM,OAAO,EAAE;GAAE,CAAC;EACjF;CACF;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,kBACd,MACA,UACgB;CAChB,MAAM,SAAyB,CAAC;CAChC,KAAK,MAAM,EAAE,MAAM,UAAU,sBAAsB;EACjD;EACA;EACA,cAAc;EACd,cAAc;CAChB,CAAC,GACC,KAAK,MAAM,QAAQ,gBAAgB,IAAI,GACrC,OAAO,KAAK;EACV,UAAU;EACV;EACA,IAAI,qBAAqB,CAAC,GAAG,IAAI,GAAG,IAAI;CAC1C,CAAC;CAGL,OAAO;AACT;;;;;;AAOA,SAAgB,eACd,OACgB;CAChB,MAAM,YAAiB,CAAC;CACxB,IAAI,MAAM,SAAS,UAAU,KAAK,MAAM,OAAO;CAC/C,IAAI,MAAM,YAAY,UAAU,KAAK,MAAM,UAAU;CAErD,MAAM,SAAyB,CAAC;CAChC,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,YAAY,WACrB,KAAK,MAAM,QAAQ,gBAAgB,QAAQ,GAAG;EAC5C,IAAI,KAAK,IAAI,IAAI,GAAG;EACpB,KAAK,IAAI,IAAI;EACb,OAAO,KAAK;GACV;GACA;GACA,IAAI,sBAAsB,MAAM,SAAS,IAAI;EAC/C,CAAC;CACH;CAEF,OAAO;AACT"}
@@ -0,0 +1,40 @@
1
+ //#region src/columns/column_registry.ts
2
+ /**
3
+ * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
4
+ * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
5
+ * the same class backs both sandbox (`TreeNodeAccessor`) and host
6
+ * (`PlTreeNodeAccessor`) usage.
7
+ *
8
+ * Stateless beyond the provider list — every lookup goes through each
9
+ * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
10
+ * directly at the call site that has the providers; there is no ambient
11
+ * singleton.
12
+ */
13
+ var ColumnRegistry = class {
14
+ providers;
15
+ constructor(providers) {
16
+ this.providers = providers;
17
+ }
18
+ /**
19
+ * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
20
+ * `undefined` if the column is not reachable from any provider — caller
21
+ * decides whether that's `absent` or `resolving` via {@link isFinal}.
22
+ */
23
+ resolve(id) {
24
+ return this.lookupById(id);
25
+ }
26
+ /** Whether every indexed source has finished enumerating its columns. */
27
+ isFinal() {
28
+ return this.providers.every((p) => p.isFinal());
29
+ }
30
+ lookupById(id) {
31
+ for (const p of this.providers) {
32
+ const hit = p.getPObjectEntries().get(id);
33
+ if (hit !== void 0) return hit;
34
+ }
35
+ }
36
+ };
37
+ //#endregion
38
+ exports.ColumnRegistry = ColumnRegistry;
39
+
40
+ //# sourceMappingURL=column_registry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_registry.cjs","names":[],"sources":["../../src/columns/column_registry.ts"],"sourcesContent":["import type { PObjectId } from \"../pool\";\nimport type { AccessorLike, ColumnEntriesProvider, LeafEntry } from \"./types\";\n\n/**\n * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:\n * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so\n * the same class backs both sandbox (`TreeNodeAccessor`) and host\n * (`PlTreeNodeAccessor`) usage.\n *\n * Stateless beyond the provider list — every lookup goes through each\n * provider's `getPObjectEntries()` (cached inside the provider). Instantiate\n * directly at the call site that has the providers; there is no ambient\n * singleton.\n */\nexport class ColumnRegistry<A extends AccessorLike<A>> {\n constructor(private readonly providers: ReadonlyArray<ColumnEntriesProvider<A>>) {}\n\n /**\n * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns\n * `undefined` if the column is not reachable from any provider — caller\n * decides whether that's `absent` or `resolving` via {@link isFinal}.\n */\n resolve(id: PObjectId): LeafEntry<A> | undefined {\n return this.lookupById(id);\n }\n\n /** Whether every indexed source has finished enumerating its columns. */\n isFinal(): boolean {\n return this.providers.every((p) => p.isFinal());\n }\n\n private lookupById(id: PObjectId): LeafEntry<A> | undefined {\n // First-wins across providers — caller controls precedence via the\n // construction order of `providers`.\n for (const p of this.providers) {\n const hit = p.getPObjectEntries().get(id);\n if (hit !== undefined) return hit;\n }\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAcA,IAAa,iBAAb,MAAuD;CACxB;CAA7B,YAAY,WAAqE;EAApD,KAAA,YAAA;CAAqD;;;;;;CAOlF,QAAQ,IAAyC;EAC/C,OAAO,KAAK,WAAW,EAAE;CAC3B;;CAGA,UAAmB;EACjB,OAAO,KAAK,UAAU,OAAO,MAAM,EAAE,QAAQ,CAAC;CAChD;CAEA,WAAmB,IAAyC;EAG1D,KAAK,MAAM,KAAK,KAAK,WAAW;GAC9B,MAAM,MAAM,EAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE;GACxC,IAAI,QAAQ,KAAA,GAAW,OAAO;EAChC;CAEF;AACF"}
@@ -0,0 +1,31 @@
1
+ import { PObjectId } from "../pool/spec.js";
2
+ import { AccessorLike, ColumnEntriesProvider, LeafEntry } from "./types.js";
3
+
4
+ //#region src/columns/column_registry.d.ts
5
+ /**
6
+ * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
7
+ * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
8
+ * the same class backs both sandbox (`TreeNodeAccessor`) and host
9
+ * (`PlTreeNodeAccessor`) usage.
10
+ *
11
+ * Stateless beyond the provider list — every lookup goes through each
12
+ * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
13
+ * directly at the call site that has the providers; there is no ambient
14
+ * singleton.
15
+ */
16
+ declare class ColumnRegistry<A extends AccessorLike<A>> {
17
+ private readonly providers;
18
+ constructor(providers: ReadonlyArray<ColumnEntriesProvider<A>>);
19
+ /**
20
+ * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
21
+ * `undefined` if the column is not reachable from any provider — caller
22
+ * decides whether that's `absent` or `resolving` via {@link isFinal}.
23
+ */
24
+ resolve(id: PObjectId): LeafEntry<A> | undefined;
25
+ /** Whether every indexed source has finished enumerating its columns. */
26
+ isFinal(): boolean;
27
+ private lookupById;
28
+ }
29
+ //#endregion
30
+ export { ColumnRegistry };
31
+ //# sourceMappingURL=column_registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_registry.d.ts","names":[],"sources":["../../src/columns/column_registry.ts"],"mappings":";;;;;;;AAcA;;;;;;;;cAAa,cAAA,WAAyB,YAAA,CAAa,CAAA;EAAA,iBACpB,SAAA;cAAA,SAAA,EAAW,aAAA,CAAc,qBAAA,CAAsB,CAAA;EAO3C;;;;;EAAjC,OAAA,CAAQ,EAAA,EAAI,SAAA,GAAY,SAAA,CAAU,CAAA;;EAKlC,OAAA;EAAA,QAIQ,UAAA;AAAA"}
@@ -0,0 +1,40 @@
1
+ //#region src/columns/column_registry.ts
2
+ /**
3
+ * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
4
+ * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
5
+ * the same class backs both sandbox (`TreeNodeAccessor`) and host
6
+ * (`PlTreeNodeAccessor`) usage.
7
+ *
8
+ * Stateless beyond the provider list — every lookup goes through each
9
+ * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
10
+ * directly at the call site that has the providers; there is no ambient
11
+ * singleton.
12
+ */
13
+ var ColumnRegistry = class {
14
+ providers;
15
+ constructor(providers) {
16
+ this.providers = providers;
17
+ }
18
+ /**
19
+ * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
20
+ * `undefined` if the column is not reachable from any provider — caller
21
+ * decides whether that's `absent` or `resolving` via {@link isFinal}.
22
+ */
23
+ resolve(id) {
24
+ return this.lookupById(id);
25
+ }
26
+ /** Whether every indexed source has finished enumerating its columns. */
27
+ isFinal() {
28
+ return this.providers.every((p) => p.isFinal());
29
+ }
30
+ lookupById(id) {
31
+ for (const p of this.providers) {
32
+ const hit = p.getPObjectEntries().get(id);
33
+ if (hit !== void 0) return hit;
34
+ }
35
+ }
36
+ };
37
+ //#endregion
38
+ export { ColumnRegistry };
39
+
40
+ //# sourceMappingURL=column_registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_registry.js","names":[],"sources":["../../src/columns/column_registry.ts"],"sourcesContent":["import type { PObjectId } from \"../pool\";\nimport type { AccessorLike, ColumnEntriesProvider, LeafEntry } from \"./types\";\n\n/**\n * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:\n * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so\n * the same class backs both sandbox (`TreeNodeAccessor`) and host\n * (`PlTreeNodeAccessor`) usage.\n *\n * Stateless beyond the provider list — every lookup goes through each\n * provider's `getPObjectEntries()` (cached inside the provider). Instantiate\n * directly at the call site that has the providers; there is no ambient\n * singleton.\n */\nexport class ColumnRegistry<A extends AccessorLike<A>> {\n constructor(private readonly providers: ReadonlyArray<ColumnEntriesProvider<A>>) {}\n\n /**\n * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns\n * `undefined` if the column is not reachable from any provider — caller\n * decides whether that's `absent` or `resolving` via {@link isFinal}.\n */\n resolve(id: PObjectId): LeafEntry<A> | undefined {\n return this.lookupById(id);\n }\n\n /** Whether every indexed source has finished enumerating its columns. */\n isFinal(): boolean {\n return this.providers.every((p) => p.isFinal());\n }\n\n private lookupById(id: PObjectId): LeafEntry<A> | undefined {\n // First-wins across providers — caller controls precedence via the\n // construction order of `providers`.\n for (const p of this.providers) {\n const hit = p.getPObjectEntries().get(id);\n if (hit !== undefined) return hit;\n }\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAcA,IAAa,iBAAb,MAAuD;CACxB;CAA7B,YAAY,WAAqE;EAApD,KAAA,YAAA;CAAqD;;;;;;CAOlF,QAAQ,IAAyC;EAC/C,OAAO,KAAK,WAAW,EAAE;CAC3B;;CAGA,UAAmB;EACjB,OAAO,KAAK,UAAU,OAAO,MAAM,EAAE,QAAQ,CAAC;CAChD;CAEA,WAAmB,IAAyC;EAG1D,KAAK,MAAM,KAAK,KAAK,WAAW;GAC9B,MAAM,MAAM,EAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE;GACxC,IAAI,QAAQ,KAAA,GAAW,OAAO;EAChC;CAEF;AACF"}
@@ -0,0 +1,49 @@
1
+ //#region src/columns/column_selector.ts
2
+ function normalizeStringMatchers(input) {
3
+ if (typeof input === "string") return [{
4
+ type: "regex",
5
+ value: input
6
+ }];
7
+ if (!Array.isArray(input)) return [input];
8
+ return input.map((v) => typeof v === "string" ? {
9
+ type: "regex",
10
+ value: v
11
+ } : v);
12
+ }
13
+ function normalizeRecord(input) {
14
+ const result = {};
15
+ for (const [key, value] of Object.entries(input)) result[key] = normalizeStringMatchers(value);
16
+ return result;
17
+ }
18
+ function normalizeTypes(input) {
19
+ return Array.isArray(input) ? input : [input];
20
+ }
21
+ function convertRelaxedAxisSelectorToMultiAxisSelector(input) {
22
+ const result = {};
23
+ if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
24
+ if (input.type !== void 0) result.type = normalizeTypes(input.type);
25
+ if (input.domain !== void 0) result.domain = normalizeRecord(input.domain);
26
+ if (input.contextDomain !== void 0) result.contextDomain = normalizeRecord(input.contextDomain);
27
+ if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
28
+ return result;
29
+ }
30
+ function convertRelaxedColumnSelectorToMultiColumnSelector(input) {
31
+ const result = {};
32
+ if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
33
+ if (input.type !== void 0) result.type = normalizeTypes(input.type);
34
+ if (input.domain !== void 0) result.domain = normalizeRecord(input.domain);
35
+ if (input.contextDomain !== void 0) result.contextDomain = normalizeRecord(input.contextDomain);
36
+ if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
37
+ if (input.axes !== void 0) result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);
38
+ if (input.partialAxesMatch !== void 0) result.partialAxesMatch = input.partialAxesMatch;
39
+ return result;
40
+ }
41
+ function convertColumnSelectorToMultiColumnSelector(input) {
42
+ return (Array.isArray(input) ? input : [input]).map(convertRelaxedColumnSelectorToMultiColumnSelector);
43
+ }
44
+ //#endregion
45
+ exports.convertColumnSelectorToMultiColumnSelector = convertColumnSelectorToMultiColumnSelector;
46
+ exports.convertRelaxedAxisSelectorToMultiAxisSelector = convertRelaxedAxisSelectorToMultiAxisSelector;
47
+ exports.convertRelaxedColumnSelectorToMultiColumnSelector = convertRelaxedColumnSelectorToMultiColumnSelector;
48
+
49
+ //# sourceMappingURL=column_selector.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_selector.cjs","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../drivers/pframe\";\n\nexport type { StringMatcher } from \"../drivers/pframe\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;CAC9E,IAAI,OAAO,UAAU,UAAU,OAAO,CAAC;EAAE,MAAM;EAAS,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACxC,OAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;CAAE,IAA6B,CAClF;AACF;AAEA,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,CAAC;CACjD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,OAAO,OAAO,wBAAwB,KAAK;CAE7C,OAAO;AACT;AAEA,SAAS,eAAkB,OAAqB;CAC9C,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAIA,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,CAAC;CAC5C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,OAAO;AACT;AAEA,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,CAAC;CAC9C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,MAAM,KAAK,IAAI,6CAA6C;CAC5E,IAAI,MAAM,qBAAqB,KAAA,GAAW,OAAO,mBAAmB,MAAM;CAC1E,OAAO;AACT;AAEA,SAAgB,2CACd,OACuB;CAEvB,QADY,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CACtC,IAAI,iDAAiD;AAClE"}
@@ -0,0 +1,33 @@
1
+ import { AxisValueType, ColumnValueType } from "../drivers/pframe/spec/spec.js";
2
+ import { MultiAxisSelector, MultiColumnSelector, StringMatcher } from "../drivers/pframe/spec_driver.js";
3
+ //#region src/columns/column_selector.d.ts
4
+ /** Relaxed string matcher input: plain string, single matcher, or array of mixed. */
5
+ type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];
6
+ /** Relaxed record matcher: values can be plain strings or relaxed matchers. */
7
+ type RelaxedRecord = Record<string, RelaxedStringMatchers>;
8
+ /** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */
9
+ interface RelaxedAxisSelector {
10
+ name?: RelaxedStringMatchers;
11
+ type?: AxisValueType | AxisValueType[];
12
+ domain?: RelaxedRecord;
13
+ contextDomain?: RelaxedRecord;
14
+ annotations?: RelaxedRecord;
15
+ }
16
+ /** Relaxed column selector — convenient hand-written form. */
17
+ interface RelaxedColumnSelector {
18
+ name?: RelaxedStringMatchers;
19
+ type?: ColumnValueType | ColumnValueType[];
20
+ domain?: RelaxedRecord;
21
+ contextDomain?: RelaxedRecord;
22
+ annotations?: RelaxedRecord;
23
+ axes?: RelaxedAxisSelector[];
24
+ partialAxesMatch?: boolean;
25
+ }
26
+ /** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */
27
+ type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];
28
+ declare function convertRelaxedAxisSelectorToMultiAxisSelector(input: RelaxedAxisSelector): MultiAxisSelector;
29
+ declare function convertRelaxedColumnSelectorToMultiColumnSelector(input: RelaxedColumnSelector): MultiColumnSelector;
30
+ declare function convertColumnSelectorToMultiColumnSelector(input: ColumnSelector): MultiColumnSelector[];
31
+ //#endregion
32
+ export { ColumnSelector, RelaxedAxisSelector, RelaxedColumnSelector, RelaxedRecord, RelaxedStringMatchers, convertColumnSelectorToMultiColumnSelector, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector };
33
+ //# sourceMappingURL=column_selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_selector.d.ts","names":[],"sources":["../../src/columns/column_selector.ts"],"mappings":";;;;KAaY,qBAAA,YAAiC,aAAA,aAA0B,aAAa;;KAGxE,aAAA,GAAgB,MAAM,SAAS,qBAAA;;UAG1B,mBAAA;EACf,IAAA,GAAO,qBAAA;EACP,IAAA,GAAO,aAAA,GAAgB,aAAA;EACvB,MAAA,GAAS,aAAA;EACT,aAAA,GAAgB,aAAA;EAChB,WAAA,GAAc,aAAA;AAAA;AARgD;AAAA,UAY/C,qBAAA;EACf,IAAA,GAAO,qBAAA;EACP,IAAA,GAAO,eAAA,GAAkB,eAAA;EACzB,MAAA,GAAS,aAAA;EACT,aAAA,GAAgB,aAAA;EAChB,WAAA,GAAc,aAAA;EACd,IAAA,GAAO,mBAAA;EACP,gBAAA;AAAA;;KAIU,cAAA,GAAiB,qBAAA,GAAwB,qBAAqB;AAAA,iBA0B1D,6CAAA,CACd,KAAA,EAAO,mBAAA,GACN,iBAAiB;AAAA,iBAWJ,iDAAA,CACd,KAAA,EAAO,qBAAA,GACN,mBAAmB;AAAA,iBAcN,0CAAA,CACd,KAAA,EAAO,cAAA,GACN,mBAAmB"}
@@ -0,0 +1,47 @@
1
+ //#region src/columns/column_selector.ts
2
+ function normalizeStringMatchers(input) {
3
+ if (typeof input === "string") return [{
4
+ type: "regex",
5
+ value: input
6
+ }];
7
+ if (!Array.isArray(input)) return [input];
8
+ return input.map((v) => typeof v === "string" ? {
9
+ type: "regex",
10
+ value: v
11
+ } : v);
12
+ }
13
+ function normalizeRecord(input) {
14
+ const result = {};
15
+ for (const [key, value] of Object.entries(input)) result[key] = normalizeStringMatchers(value);
16
+ return result;
17
+ }
18
+ function normalizeTypes(input) {
19
+ return Array.isArray(input) ? input : [input];
20
+ }
21
+ function convertRelaxedAxisSelectorToMultiAxisSelector(input) {
22
+ const result = {};
23
+ if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
24
+ if (input.type !== void 0) result.type = normalizeTypes(input.type);
25
+ if (input.domain !== void 0) result.domain = normalizeRecord(input.domain);
26
+ if (input.contextDomain !== void 0) result.contextDomain = normalizeRecord(input.contextDomain);
27
+ if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
28
+ return result;
29
+ }
30
+ function convertRelaxedColumnSelectorToMultiColumnSelector(input) {
31
+ const result = {};
32
+ if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
33
+ if (input.type !== void 0) result.type = normalizeTypes(input.type);
34
+ if (input.domain !== void 0) result.domain = normalizeRecord(input.domain);
35
+ if (input.contextDomain !== void 0) result.contextDomain = normalizeRecord(input.contextDomain);
36
+ if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
37
+ if (input.axes !== void 0) result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);
38
+ if (input.partialAxesMatch !== void 0) result.partialAxesMatch = input.partialAxesMatch;
39
+ return result;
40
+ }
41
+ function convertColumnSelectorToMultiColumnSelector(input) {
42
+ return (Array.isArray(input) ? input : [input]).map(convertRelaxedColumnSelectorToMultiColumnSelector);
43
+ }
44
+ //#endregion
45
+ export { convertColumnSelectorToMultiColumnSelector, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector };
46
+
47
+ //# sourceMappingURL=column_selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column_selector.js","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../drivers/pframe\";\n\nexport type { StringMatcher } from \"../drivers/pframe\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;CAC9E,IAAI,OAAO,UAAU,UAAU,OAAO,CAAC;EAAE,MAAM;EAAS,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACxC,OAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;CAAE,IAA6B,CAClF;AACF;AAEA,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,CAAC;CACjD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,OAAO,OAAO,wBAAwB,KAAK;CAE7C,OAAO;AACT;AAEA,SAAS,eAAkB,OAAqB;CAC9C,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAIA,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,CAAC;CAC5C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,OAAO;AACT;AAEA,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,CAAC;CAC9C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,MAAM,KAAK,IAAI,6CAA6C;CAC5E,IAAI,MAAM,qBAAqB,KAAA,GAAW,OAAO,mBAAmB,MAAM;CAC1E,OAAO;AACT;AAEA,SAAgB,2CACd,OACuB;CAEvB,QADY,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CACtC,IAAI,iDAAiD;AAClE"}