@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.
- package/dist/columns/accessor_traversal.cjs +119 -0
- package/dist/columns/accessor_traversal.cjs.map +1 -0
- package/dist/columns/accessor_traversal.d.ts +52 -0
- package/dist/columns/accessor_traversal.d.ts.map +1 -0
- package/dist/columns/accessor_traversal.js +114 -0
- package/dist/columns/accessor_traversal.js.map +1 -0
- package/dist/columns/column_registry.cjs +40 -0
- package/dist/columns/column_registry.cjs.map +1 -0
- package/dist/columns/column_registry.d.ts +31 -0
- package/dist/columns/column_registry.d.ts.map +1 -0
- package/dist/columns/column_registry.js +40 -0
- package/dist/columns/column_registry.js.map +1 -0
- package/dist/columns/column_selector.cjs +49 -0
- package/dist/columns/column_selector.cjs.map +1 -0
- package/dist/columns/column_selector.d.ts +33 -0
- package/dist/columns/column_selector.d.ts.map +1 -0
- package/dist/columns/column_selector.js +47 -0
- package/dist/columns/column_selector.js.map +1 -0
- package/dist/columns/dedup.cjs +47 -0
- package/dist/columns/dedup.cjs.map +1 -0
- package/dist/columns/dedup.d.ts +27 -0
- package/dist/columns/dedup.d.ts.map +1 -0
- package/dist/columns/dedup.js +47 -0
- package/dist/columns/dedup.js.map +1 -0
- package/dist/columns/index.cjs +18 -0
- package/dist/columns/index.d.ts +8 -0
- package/dist/columns/index.js +6 -0
- package/dist/columns/providers.cjs +62 -0
- package/dist/columns/providers.cjs.map +1 -0
- package/dist/columns/providers.d.ts +39 -0
- package/dist/columns/providers.d.ts.map +1 -0
- package/dist/columns/providers.js +61 -0
- package/dist/columns/providers.js.map +1 -0
- package/dist/columns/types.d.ts +108 -0
- package/dist/columns/types.d.ts.map +1 -0
- package/dist/driver_kit.d.ts +1 -2
- package/dist/driver_kit.d.ts.map +1 -1
- package/dist/drivers/columns/columns_collection_driver.d.ts +124 -0
- package/dist/drivers/columns/columns_collection_driver.d.ts.map +1 -0
- package/dist/drivers/columns/discover_columns_options.cjs +28 -0
- package/dist/drivers/columns/discover_columns_options.cjs.map +1 -0
- package/dist/drivers/columns/discover_columns_options.d.ts +64 -0
- package/dist/drivers/columns/discover_columns_options.d.ts.map +1 -0
- package/dist/drivers/columns/discover_columns_options.js +28 -0
- package/dist/drivers/columns/discover_columns_options.js.map +1 -0
- package/dist/drivers/columns/index.d.ts +3 -0
- package/dist/drivers/index.cjs +32 -7
- package/dist/drivers/index.d.ts +12 -9
- package/dist/drivers/index.js +6 -4
- package/dist/drivers/pframe/driver.d.ts +1 -2
- package/dist/drivers/pframe/driver.d.ts.map +1 -1
- package/dist/drivers/pframe/index.cjs +30 -7
- package/dist/drivers/pframe/index.d.ts +9 -8
- package/dist/drivers/pframe/index.js +5 -4
- package/dist/drivers/pframe/query/index.d.ts +2 -2
- package/dist/drivers/pframe/query/query_common.d.ts +24 -1
- package/dist/drivers/pframe/query/query_common.d.ts.map +1 -1
- package/dist/drivers/pframe/query/query_spec.d.ts +25 -24
- package/dist/drivers/pframe/query/query_spec.d.ts.map +1 -1
- package/dist/drivers/pframe/query/utils.cjs +18 -8
- package/dist/drivers/pframe/query/utils.cjs.map +1 -1
- package/dist/drivers/pframe/query/utils.d.ts +5 -1
- package/dist/drivers/pframe/query/utils.d.ts.map +1 -1
- package/dist/drivers/pframe/query/utils.js +18 -8
- package/dist/drivers/pframe/query/utils.js.map +1 -1
- package/dist/drivers/pframe/spec/anchored.d.ts +2 -2
- package/dist/drivers/pframe/spec/discovered_column.cjs +31 -15
- package/dist/drivers/pframe/spec/discovered_column.cjs.map +1 -1
- package/dist/drivers/pframe/spec/discovered_column.d.ts +23 -13
- package/dist/drivers/pframe/spec/discovered_column.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/discovered_column.js +26 -12
- package/dist/drivers/pframe/spec/discovered_column.js.map +1 -1
- package/dist/drivers/pframe/spec/filtered_column.cjs +46 -0
- package/dist/drivers/pframe/spec/filtered_column.cjs.map +1 -1
- package/dist/drivers/pframe/spec/filtered_column.d.ts +39 -1
- package/dist/drivers/pframe/spec/filtered_column.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/filtered_column.js +41 -1
- package/dist/drivers/pframe/spec/filtered_column.js.map +1 -1
- package/dist/drivers/pframe/spec/ids.cjs +62 -10
- package/dist/drivers/pframe/spec/ids.cjs.map +1 -1
- package/dist/drivers/pframe/spec/ids.d.ts +48 -15
- package/dist/drivers/pframe/spec/ids.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/ids.js +60 -9
- package/dist/drivers/pframe/spec/ids.js.map +1 -1
- package/dist/drivers/pframe/spec/index.cjs +30 -7
- package/dist/drivers/pframe/spec/index.d.ts +6 -5
- package/dist/drivers/pframe/spec/index.js +5 -4
- package/dist/drivers/pframe/spec/native_id.cjs +1 -0
- package/dist/drivers/pframe/spec/native_id.cjs.map +1 -1
- package/dist/drivers/pframe/spec/native_id.js +1 -0
- package/dist/drivers/pframe/spec/native_id.js.map +1 -1
- package/dist/drivers/pframe/spec/overridden.cjs +212 -0
- package/dist/drivers/pframe/spec/overridden.cjs.map +1 -0
- package/dist/drivers/pframe/spec/overridden.d.ts +67 -0
- package/dist/drivers/pframe/spec/overridden.d.ts.map +1 -0
- package/dist/drivers/pframe/spec/overridden.js +202 -0
- package/dist/drivers/pframe/spec/overridden.js.map +1 -0
- package/dist/drivers/pframe/spec/selectors.cjs +1 -0
- package/dist/drivers/pframe/spec/selectors.cjs.map +1 -1
- package/dist/drivers/pframe/spec/selectors.d.ts +3 -0
- package/dist/drivers/pframe/spec/selectors.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/selectors.js +1 -0
- package/dist/drivers/pframe/spec/selectors.js.map +1 -1
- package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
- package/dist/drivers/pframe/spec/spec.d.ts +2 -3
- package/dist/drivers/pframe/spec/spec.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/spec.js.map +1 -1
- package/dist/drivers/pframe/spec_driver.d.ts +2 -2
- package/dist/drivers/pframe/spec_driver.d.ts.map +1 -1
- package/dist/drivers/pframe/table_calculate.cjs +2 -2
- package/dist/drivers/pframe/table_calculate.cjs.map +1 -1
- package/dist/drivers/pframe/table_calculate.d.ts +6 -2
- package/dist/drivers/pframe/table_calculate.d.ts.map +1 -1
- package/dist/drivers/pframe/table_calculate.js +2 -2
- package/dist/drivers/pframe/table_calculate.js.map +1 -1
- package/dist/drivers/pframe/table_common.cjs.map +1 -1
- package/dist/drivers/pframe/table_common.d.ts +11 -4
- package/dist/drivers/pframe/table_common.d.ts.map +1 -1
- package/dist/drivers/pframe/table_common.js.map +1 -1
- package/dist/index.cjs +63 -10
- package/dist/index.d.ts +20 -11
- package/dist/index.js +15 -6
- package/dist/pool/index.cjs +18 -0
- package/dist/pool/index.d.ts +2 -2
- package/dist/pool/index.js +3 -0
- package/dist/pool/spec.cjs +59 -11
- package/dist/pool/spec.cjs.map +1 -1
- package/dist/pool/spec.d.ts +24 -9
- package/dist/pool/spec.d.ts.map +1 -1
- package/dist/pool/spec.js +50 -10
- package/dist/pool/spec.js.map +1 -1
- package/dist/services/index.d.ts +2 -2
- package/dist/services/service_declarations.cjs +22 -0
- package/dist/services/service_declarations.cjs.map +1 -1
- package/dist/services/service_declarations.d.ts +5 -3
- package/dist/services/service_declarations.d.ts.map +1 -1
- package/dist/services/service_declarations.js +22 -0
- package/dist/services/service_declarations.js.map +1 -1
- package/dist/services/service_registry.cjs.map +1 -1
- package/dist/services/service_registry.d.ts +3 -3
- package/dist/services/service_registry.d.ts.map +1 -1
- package/dist/services/service_registry.js.map +1 -1
- package/dist/services/service_types.cjs.map +1 -1
- package/dist/services/service_types.d.ts +25 -9
- package/dist/services/service_types.d.ts.map +1 -1
- package/dist/services/service_types.js.map +1 -1
- package/package.json +2 -1
- package/src/columns/accessor_traversal.ts +139 -0
- package/src/columns/column_registry.ts +41 -0
- package/src/columns/column_selector.ts +100 -0
- package/src/columns/dedup.ts +49 -0
- package/src/columns/index.ts +6 -0
- package/src/columns/providers.ts +74 -0
- package/src/columns/types.ts +116 -0
- package/src/drivers/columns/columns_collection_driver.ts +146 -0
- package/src/drivers/columns/discover_columns_options.ts +91 -0
- package/src/drivers/columns/index.ts +2 -0
- package/src/drivers/index.ts +1 -0
- package/src/drivers/pframe/index.ts +0 -1
- package/src/drivers/pframe/query/query_common.ts +24 -0
- package/src/drivers/pframe/query/query_spec.ts +38 -25
- package/src/drivers/pframe/query/utils.test.ts +6 -6
- package/src/drivers/pframe/query/utils.ts +27 -7
- package/src/drivers/pframe/spec/discovered_column.ts +43 -28
- package/src/drivers/pframe/spec/filtered_column.ts +66 -0
- package/src/drivers/pframe/spec/ids.ts +142 -17
- package/src/drivers/pframe/spec/index.ts +1 -0
- package/src/drivers/pframe/spec/overridden.ts +285 -0
- package/src/drivers/pframe/spec/selectors.ts +3 -0
- package/src/drivers/pframe/spec/spec.ts +7 -3
- package/src/drivers/pframe/spec_driver.ts +3 -3
- package/src/drivers/pframe/table_calculate.ts +13 -3
- package/src/drivers/pframe/table_common.ts +10 -3
- package/src/index.ts +1 -0
- package/src/pool/spec.ts +69 -23
- package/src/services/service_declarations.ts +31 -0
- package/src/services/service_registry.ts +8 -4
- package/src/services/service_types.ts +35 -9
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { canonicalizeJson } from "../../../json.js";
|
|
2
|
+
import { parseColumnIdSafely } from "./ids.js";
|
|
3
|
+
import { throwError } from "@milaboratories/helpers";
|
|
4
|
+
import { isNil, isString } from "es-toolkit";
|
|
5
|
+
//#region src/drivers/pframe/spec/overridden.ts
|
|
6
|
+
function isColumnOverriddenKey(obj) {
|
|
7
|
+
return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
|
|
8
|
+
}
|
|
9
|
+
function distillColumnOverriddenKey(props) {
|
|
10
|
+
return {
|
|
11
|
+
__isOverridden: true,
|
|
12
|
+
source: props.source,
|
|
13
|
+
specOverrides: props.specOverrides
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function createColumnOverriddenId(props) {
|
|
17
|
+
return stringifyColumnOverriddenId(createColumnOverriddenKey(props));
|
|
18
|
+
}
|
|
19
|
+
function createColumnOverriddenKey(props) {
|
|
20
|
+
const { source, specOverrides } = props;
|
|
21
|
+
const unwrapped = unwrapOverrides(source);
|
|
22
|
+
return {
|
|
23
|
+
__isOverridden: true,
|
|
24
|
+
source: unwrapped ? unwrapped.source : source,
|
|
25
|
+
specOverrides: unwrapped ? mergeSpecOverrides(unwrapped.specOverrides, specOverrides) : specOverrides
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function parseColumnOverriddenId(id) {
|
|
29
|
+
try {
|
|
30
|
+
const parsed = JSON.parse(id);
|
|
31
|
+
return isColumnOverriddenKey(parsed) ? parsed : throwError("Parsed object is not a valid OverriddenPColumn");
|
|
32
|
+
} catch {
|
|
33
|
+
throw new Error("Invalid ColumnOverriddenId: not a valid JSON or does not conform to OverriddenPColumn structure");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function stringifyColumnOverriddenId(id) {
|
|
37
|
+
return canonicalizeJson(distillColumnOverriddenKey(id));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Peel one override-wrap layer.
|
|
41
|
+
*
|
|
42
|
+
* Invariant: `{source, specOverrides}` can only appear at the top level —
|
|
43
|
+
* the inner `source` is never itself an override-wrap. Anything else throws.
|
|
44
|
+
*/
|
|
45
|
+
function unwrapOverrides(id) {
|
|
46
|
+
const parsed = parseColumnIdSafely(id);
|
|
47
|
+
if (parsed === void 0 || !isColumnOverriddenKey(parsed)) return void 0;
|
|
48
|
+
const inner = parseColumnIdSafely(parsed.source);
|
|
49
|
+
if (inner !== void 0 && isColumnOverriddenKey(inner)) throw new Error("nested override-wrap detected — invariant broken");
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Diff two specs into a {@link SpecOverrides} patch that, when applied on top
|
|
54
|
+
* of `base`, reconstructs `next`.
|
|
55
|
+
*
|
|
56
|
+
* - For top-level `annotations` / `domain` / `contextDomain`: include keys
|
|
57
|
+
* whose value in `next` differs from `base` (or is missing in `base`).
|
|
58
|
+
* Keys present in `base` but missing in `next` are not emitted — overrides
|
|
59
|
+
* merge, they cannot delete.
|
|
60
|
+
* - For `axesSpec`: matched by **positional index**. Each `next[i]` is diffed
|
|
61
|
+
* against `base[i]`; only changed fields are emitted as a patch under key
|
|
62
|
+
* `i`. Indices past `base.length` carry the full new axis (append).
|
|
63
|
+
*/
|
|
64
|
+
function deriveSpecDelta(base, next) {
|
|
65
|
+
const annotations = recordDelta(base.annotations, next.annotations);
|
|
66
|
+
const domain = recordDelta(base.domain, next.domain);
|
|
67
|
+
const contextDomain = recordDelta(base.contextDomain, next.contextDomain);
|
|
68
|
+
const axesSpec = deriveAxesDelta(base.axesSpec, next.axesSpec);
|
|
69
|
+
return {
|
|
70
|
+
...axesSpec && { axesSpec },
|
|
71
|
+
...annotations && { annotations },
|
|
72
|
+
...domain && { domain },
|
|
73
|
+
...contextDomain && { contextDomain }
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function isEmptySpecDelta(delta) {
|
|
77
|
+
return (!delta.annotations || Object.keys(delta.annotations).length === 0) && (!delta.domain || Object.keys(delta.domain).length === 0) && (!delta.contextDomain || Object.keys(delta.contextDomain).length === 0) && (!delta.axesSpec || Object.keys(delta.axesSpec).length === 0);
|
|
78
|
+
}
|
|
79
|
+
function deriveAxesDelta(base, next) {
|
|
80
|
+
const out = {};
|
|
81
|
+
let any = false;
|
|
82
|
+
for (let i = 0; i < next.length; i++) {
|
|
83
|
+
const a = next[i];
|
|
84
|
+
const b = base[i];
|
|
85
|
+
if (b === void 0) {
|
|
86
|
+
out[i] = a;
|
|
87
|
+
any = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const nameChanged = a.name !== b.name;
|
|
91
|
+
const typeChanged = a.type !== b.type;
|
|
92
|
+
const annotations = recordDelta(b.annotations, a.annotations);
|
|
93
|
+
const domain = recordDelta(b.domain, a.domain);
|
|
94
|
+
const contextDomain = recordDelta(b.contextDomain, a.contextDomain);
|
|
95
|
+
if (!nameChanged && !typeChanged && !annotations && !domain && !contextDomain) continue;
|
|
96
|
+
out[i] = {
|
|
97
|
+
...nameChanged && { name: a.name },
|
|
98
|
+
...typeChanged && { type: a.type },
|
|
99
|
+
...annotations && { annotations },
|
|
100
|
+
...domain && { domain },
|
|
101
|
+
...contextDomain && { contextDomain }
|
|
102
|
+
};
|
|
103
|
+
any = true;
|
|
104
|
+
}
|
|
105
|
+
return any ? out : void 0;
|
|
106
|
+
}
|
|
107
|
+
function recordDelta(base, next) {
|
|
108
|
+
if (!next) return void 0;
|
|
109
|
+
let any = false;
|
|
110
|
+
const diff = {};
|
|
111
|
+
for (const [k, v] of Object.entries(next)) if (!base || base[k] !== v) {
|
|
112
|
+
diff[k] = v;
|
|
113
|
+
any = true;
|
|
114
|
+
}
|
|
115
|
+
return any ? diff : void 0;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Apply `specOverrides` from a rich id (`SUniversalPColumnId`) on top of a
|
|
119
|
+
* resolved {@link PColumnSpec}. Returns `base` unchanged when the id carries
|
|
120
|
+
* no overrides.
|
|
121
|
+
*/
|
|
122
|
+
function applySpecOverrides(base, idOrOverride) {
|
|
123
|
+
if (isNil(idOrOverride)) return base;
|
|
124
|
+
const overrides = isString(idOrOverride) ? unwrapOverrides(idOrOverride)?.specOverrides : idOrOverride;
|
|
125
|
+
if (isNil(overrides)) return base;
|
|
126
|
+
const result = { ...base };
|
|
127
|
+
if (overrides.annotations) result.annotations = mergeRecord(base.annotations, overrides.annotations);
|
|
128
|
+
if (overrides.domain) result.domain = mergeRecord(base.domain, overrides.domain);
|
|
129
|
+
if (overrides.contextDomain) result.contextDomain = mergeRecord(base.contextDomain, overrides.contextDomain);
|
|
130
|
+
if (overrides.axesSpec) result.axesSpec = applyAxesPatches(base.axesSpec, overrides.axesSpec);
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Compose two override patches: applying `mergeSpecOverrides(prior, next)` on
|
|
135
|
+
* top of a base spec produces the same result as applying `prior` then `next`.
|
|
136
|
+
*/
|
|
137
|
+
function mergeSpecOverrides(prior, next) {
|
|
138
|
+
const result = {};
|
|
139
|
+
const axesSpec = mergeAxesPatches(prior.axesSpec, next.axesSpec);
|
|
140
|
+
if (axesSpec !== void 0) result.axesSpec = axesSpec;
|
|
141
|
+
const annotations = mergeRecord(prior.annotations, next.annotations);
|
|
142
|
+
if (annotations !== void 0) result.annotations = annotations;
|
|
143
|
+
const domain = mergeRecord(prior.domain, next.domain);
|
|
144
|
+
if (domain !== void 0) result.domain = domain;
|
|
145
|
+
const contextDomain = mergeRecord(prior.contextDomain, next.contextDomain);
|
|
146
|
+
if (contextDomain !== void 0) result.contextDomain = contextDomain;
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Apply positional `patches` onto `base.axesSpec`. Patches deep-merge
|
|
151
|
+
* `annotations` / `domain` / `contextDomain` and shallow-override `name` /
|
|
152
|
+
* `type` at their slot. Indices `>= base.length` append new axes; intermediate
|
|
153
|
+
* gaps (if any) are filled with the patch itself, so callers should not leave
|
|
154
|
+
* holes between base.length and the highest patched index.
|
|
155
|
+
*/
|
|
156
|
+
function applyAxesPatches(base, patches) {
|
|
157
|
+
const result = base.slice();
|
|
158
|
+
for (const [k, p] of Object.entries(patches)) {
|
|
159
|
+
const i = Number(k);
|
|
160
|
+
const existing = result[i];
|
|
161
|
+
result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Compose two positional patch maps: `mergeAxesPatches(prior, next)` applied to
|
|
167
|
+
* a base spec must equal applying `prior` then `next`. Patches sharing an
|
|
168
|
+
* index deep-merge field-by-field.
|
|
169
|
+
*/
|
|
170
|
+
function mergeAxesPatches(prior, next) {
|
|
171
|
+
if (!prior || Object.keys(prior).length === 0) return next;
|
|
172
|
+
if (!next || Object.keys(next).length === 0) return prior;
|
|
173
|
+
const result = { ...prior };
|
|
174
|
+
for (const [k, p] of Object.entries(next)) {
|
|
175
|
+
const i = Number(k);
|
|
176
|
+
const existing = result[i];
|
|
177
|
+
result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
function mergeAxisPatch(axis, patch) {
|
|
182
|
+
const result = {
|
|
183
|
+
...axis,
|
|
184
|
+
...patch
|
|
185
|
+
};
|
|
186
|
+
if (patch.annotations) result.annotations = mergeRecord(axis.annotations, patch.annotations);
|
|
187
|
+
if (patch.domain) result.domain = mergeRecord(axis.domain, patch.domain);
|
|
188
|
+
if (patch.contextDomain) result.contextDomain = mergeRecord(axis.contextDomain, patch.contextDomain);
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
function mergeRecord(a, b) {
|
|
192
|
+
if (!b) return a;
|
|
193
|
+
if (!a) return b;
|
|
194
|
+
return {
|
|
195
|
+
...a,
|
|
196
|
+
...b
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
export { applySpecOverrides, createColumnOverriddenId, createColumnOverriddenKey, deriveSpecDelta, distillColumnOverriddenKey, isColumnOverriddenKey, isEmptySpecDelta, mergeSpecOverrides, parseColumnOverriddenId, stringifyColumnOverriddenId, unwrapOverrides };
|
|
201
|
+
|
|
202
|
+
//# sourceMappingURL=overridden.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overridden.js","names":[],"sources":["../../../../src/drivers/pframe/spec/overridden.ts"],"sourcesContent":["import { type Branded, throwError, type Mutable, Nil } from \"@milaboratories/helpers\";\nimport { type CanonicalizedJson, canonicalizeJson } from \"../../../json\";\nimport { AxisPatches, type ColumnUniversalId, parseColumnIdSafely } from \"./ids\";\nimport type { AxisSpec, PColumnSpec } from \"./spec\";\nimport { isNil, isString } from \"es-toolkit\";\n\nexport type SpecOverrides = Pick<PColumnSpec, \"domain\" | \"contextDomain\" | \"annotations\"> & {\n axesSpec?: AxisPatches;\n};\n\n/**\n * `source` can reference a leaf or a Filtered/Discovered id, but never another\n * Overridden id — there is no `Overridden<Overridden<...>>`. Repeated overrides\n * merge at the outer wrapper via {@link mergeSpecOverrides}.\n */\nexport interface ColumnOverriddenKey {\n __isOverridden: true;\n source: Exclude<ColumnUniversalId, ColumnOverriddenId>;\n specOverrides: SpecOverrides;\n}\n\nexport type ColumnOverriddenId = Branded<\n CanonicalizedJson<ColumnOverriddenKey>,\n \"ColumnOverriddenId\"\n>;\n\nexport function isColumnOverriddenKey(obj: unknown): obj is ColumnOverriddenKey {\n return typeof obj === \"object\" && obj !== null && \"__isOverridden\" in obj;\n}\n\nexport function distillColumnOverriddenKey(props: ColumnOverriddenKey): ColumnOverriddenKey {\n return {\n __isOverridden: true,\n source: props.source,\n specOverrides: props.specOverrides,\n };\n}\n\nexport function createColumnOverriddenId(props: {\n source: ColumnUniversalId;\n specOverrides: SpecOverrides;\n}): ColumnOverriddenId {\n return stringifyColumnOverriddenId(createColumnOverriddenKey(props));\n}\n\nexport function createColumnOverriddenKey(props: {\n source: ColumnUniversalId;\n specOverrides: SpecOverrides;\n}): ColumnOverriddenKey {\n const { source, specOverrides } = props;\n const unwrapped = unwrapOverrides(source);\n const baseSource = unwrapped\n ? unwrapped.source\n : (source as Exclude<ColumnUniversalId, ColumnOverriddenId>);\n const mergedOverrides = unwrapped\n ? mergeSpecOverrides(unwrapped.specOverrides, specOverrides)\n : specOverrides;\n\n return {\n __isOverridden: true,\n source: baseSource,\n specOverrides: mergedOverrides,\n };\n}\n\nexport function parseColumnOverriddenId(id: ColumnUniversalId): ColumnOverriddenKey {\n try {\n const parsed = JSON.parse(id);\n return isColumnOverriddenKey(parsed)\n ? parsed\n : throwError(\"Parsed object is not a valid OverriddenPColumn\");\n } catch {\n throw new Error(\n \"Invalid ColumnOverriddenId: not a valid JSON or does not conform to OverriddenPColumn structure\",\n );\n }\n}\n\nexport function stringifyColumnOverriddenId(id: ColumnOverriddenKey): ColumnOverriddenId {\n return canonicalizeJson<ColumnOverriddenKey>(\n distillColumnOverriddenKey(id),\n ) as ColumnOverriddenId;\n}\n\n/**\n * Peel one override-wrap layer.\n *\n * Invariant: `{source, specOverrides}` can only appear at the top level —\n * the inner `source` is never itself an override-wrap. Anything else throws.\n */\nexport function unwrapOverrides(id: ColumnUniversalId): ColumnOverriddenKey | undefined {\n const parsed = parseColumnIdSafely(id);\n if (parsed === undefined || !isColumnOverriddenKey(parsed)) return undefined;\n const inner = parseColumnIdSafely(parsed.source);\n if (inner !== undefined && isColumnOverriddenKey(inner)) {\n throw new Error(\"nested override-wrap detected — invariant broken\");\n }\n return parsed;\n}\n\n/**\n * Diff two specs into a {@link SpecOverrides} patch that, when applied on top\n * of `base`, reconstructs `next`.\n *\n * - For top-level `annotations` / `domain` / `contextDomain`: include keys\n * whose value in `next` differs from `base` (or is missing in `base`).\n * Keys present in `base` but missing in `next` are not emitted — overrides\n * merge, they cannot delete.\n * - For `axesSpec`: matched by **positional index**. Each `next[i]` is diffed\n * against `base[i]`; only changed fields are emitted as a patch under key\n * `i`. Indices past `base.length` carry the full new axis (append).\n */\nexport function deriveSpecDelta(base: PColumnSpec, next: PColumnSpec): SpecOverrides {\n const annotations = recordDelta(base.annotations, next.annotations);\n const domain = recordDelta(base.domain, next.domain);\n const contextDomain = recordDelta(base.contextDomain, next.contextDomain);\n const axesSpec = deriveAxesDelta(base.axesSpec, next.axesSpec);\n return {\n ...(axesSpec && { axesSpec }),\n ...(annotations && { annotations }),\n ...(domain && { domain }),\n ...(contextDomain && { contextDomain }),\n };\n}\n\nexport function isEmptySpecDelta(delta: SpecOverrides): boolean {\n return (\n (!delta.annotations || Object.keys(delta.annotations).length === 0) &&\n (!delta.domain || Object.keys(delta.domain).length === 0) &&\n (!delta.contextDomain || Object.keys(delta.contextDomain).length === 0) &&\n (!delta.axesSpec || Object.keys(delta.axesSpec).length === 0)\n );\n}\n\nfunction deriveAxesDelta(\n base: readonly AxisSpec[],\n next: readonly AxisSpec[],\n): AxisPatches | undefined {\n const out: AxisPatches = {};\n let any = false;\n for (let i = 0; i < next.length; i++) {\n const a = next[i];\n const b = base[i];\n if (b === undefined) {\n out[i] = a;\n any = true;\n continue;\n }\n const nameChanged = a.name !== b.name;\n const typeChanged = a.type !== b.type;\n const annotations = recordDelta(b.annotations, a.annotations);\n const domain = recordDelta(b.domain, a.domain);\n const contextDomain = recordDelta(b.contextDomain, a.contextDomain);\n if (!nameChanged && !typeChanged && !annotations && !domain && !contextDomain) continue;\n out[i] = {\n ...(nameChanged && { name: a.name }),\n ...(typeChanged && { type: a.type }),\n ...(annotations && { annotations }),\n ...(domain && { domain }),\n ...(contextDomain && { contextDomain }),\n };\n any = true;\n }\n return any ? out : undefined;\n}\n\nfunction recordDelta(\n base: Record<string, string> | undefined,\n next: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!next) return undefined;\n let any = false;\n const diff: Record<string, string> = {};\n for (const [k, v] of Object.entries(next)) {\n if (!base || base[k] !== v) {\n diff[k] = v;\n any = true;\n }\n }\n return any ? diff : undefined;\n}\n\n/**\n * Apply `specOverrides` from a rich id (`SUniversalPColumnId`) on top of a\n * resolved {@link PColumnSpec}. Returns `base` unchanged when the id carries\n * no overrides.\n */\nexport function applySpecOverrides(\n base: PColumnSpec,\n idOrOverride: Nil | SpecOverrides | ColumnUniversalId,\n): PColumnSpec {\n if (isNil(idOrOverride)) {\n return base;\n }\n\n const overrides = isString(idOrOverride)\n ? unwrapOverrides(idOrOverride)?.specOverrides\n : idOrOverride;\n\n if (isNil(overrides)) {\n return base;\n }\n\n const result = { ...base };\n if (overrides.annotations)\n result.annotations = mergeRecord(base.annotations, overrides.annotations);\n if (overrides.domain) result.domain = mergeRecord(base.domain, overrides.domain);\n if (overrides.contextDomain)\n result.contextDomain = mergeRecord(base.contextDomain, overrides.contextDomain);\n if (overrides.axesSpec) result.axesSpec = applyAxesPatches(base.axesSpec, overrides.axesSpec);\n return result;\n}\n\n/**\n * Compose two override patches: applying `mergeSpecOverrides(prior, next)` on\n * top of a base spec produces the same result as applying `prior` then `next`.\n */\nexport function mergeSpecOverrides(prior: SpecOverrides, next: SpecOverrides): SpecOverrides {\n const result: Mutable<SpecOverrides> = {};\n const axesSpec = mergeAxesPatches(prior.axesSpec, next.axesSpec);\n if (axesSpec !== undefined) result.axesSpec = axesSpec;\n const annotations = mergeRecord(prior.annotations, next.annotations);\n if (annotations !== undefined) result.annotations = annotations;\n const domain = mergeRecord(prior.domain, next.domain);\n if (domain !== undefined) result.domain = domain;\n const contextDomain = mergeRecord(prior.contextDomain, next.contextDomain);\n if (contextDomain !== undefined) result.contextDomain = contextDomain;\n return result;\n}\n\n/**\n * Apply positional `patches` onto `base.axesSpec`. Patches deep-merge\n * `annotations` / `domain` / `contextDomain` and shallow-override `name` /\n * `type` at their slot. Indices `>= base.length` append new axes; intermediate\n * gaps (if any) are filled with the patch itself, so callers should not leave\n * holes between base.length and the highest patched index.\n */\nfunction applyAxesPatches(base: readonly AxisSpec[], patches: AxisPatches): AxisSpec[] {\n const result: AxisSpec[] = base.slice();\n for (const [k, p] of Object.entries(patches)) {\n const i = Number(k);\n const existing = result[i];\n result[i] = (existing === undefined ? p : mergeAxisPatch(existing, p)) as AxisSpec;\n }\n return result;\n}\n\n/**\n * Compose two positional patch maps: `mergeAxesPatches(prior, next)` applied to\n * a base spec must equal applying `prior` then `next`. Patches sharing an\n * index deep-merge field-by-field.\n */\nfunction mergeAxesPatches(\n prior: AxisPatches | undefined,\n next: AxisPatches | undefined,\n): AxisPatches | undefined {\n if (!prior || Object.keys(prior).length === 0) return next;\n if (!next || Object.keys(next).length === 0) return prior;\n const result: AxisPatches = { ...prior };\n for (const [k, p] of Object.entries(next)) {\n const i = Number(k);\n const existing = result[i];\n result[i] = existing === undefined ? p : mergeAxisPatch(existing, p);\n }\n return result;\n}\n\nfunction mergeAxisPatch<A extends Partial<AxisSpec>>(axis: A, patch: Partial<AxisSpec>): A {\n const result: Mutable<A> = { ...axis, ...patch };\n if (patch.annotations) result.annotations = mergeRecord(axis.annotations, patch.annotations);\n if (patch.domain) result.domain = mergeRecord(axis.domain, patch.domain);\n if (patch.contextDomain) {\n result.contextDomain = mergeRecord(axis.contextDomain, patch.contextDomain);\n }\n return result;\n}\n\nfunction mergeRecord(\n a: Record<string, string> | undefined,\n b: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!b) return a;\n if (!a) return b;\n return { ...a, ...b };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.cjs","names":["getAxisId","isPColumnSpec"],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"sourcesContent":["import { isPColumnSpec, type PObjectSpec } from \"../../../pool\";\nimport type {\n MatcherMap,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../spec_driver\";\nimport type { AxisId, AxisValueType, Domain, PColumnSpec, ValueType } from \"./spec\";\nimport { getAxisId } from \"./spec\";\n\n/**\n * Defines a pattern for matching axes within the PFrame data model.\n *\n * AxisSelector provides a flexible way to identify axes based on their\n * properties. All fields are optional, allowing for partial matching.\n * When multiple properties are specified, all must match for an axis\n * to be selected (logical AND).\n *\n * This interface is used in various selection and matching operations\n * throughout the PFrame system, such as column queries and axis lookups.\n *\n * @deprecated This selector is part of the legacy column matching API.\n * The new Columns API (see sdk/model/src/columns/) now handles column and axis\n * selection via {@link AxisSelector} and {@link ColumnSelector}, providing\n * stricter matching semantics (StringMatcher-based) and a unified approach\n * to working with columns, including domain and annotation matching.\n */\nexport interface LegacyAxisSelector {\n /**\n * Optional value type to match against.\n * When specified, only axes with this exact type will match.\n * Can be a single type or an array of types to match against any of them.\n * Valid types include: 'Int', 'Long', 'Float', 'Double', 'String', 'Bytes'.\n */\n type?: ValueType | ValueType[];\n\n /**\n * Optional name to match against.\n * When specified, only axes with this exact name will match.\n */\n name?: string;\n\n /**\n * Optional domain key-value pairs to match against.\n * Domains provide additional context to uniquely identify an axis beyond its name and type.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n * An axis with additional domain entries not present in this selector will still match.\n */\n domain?: Record<string, string>;\n\n /**\n * Optional context domain key-value pairs to match against.\n * Context domains are matched by kinship rules (subset/superset/overlap) rather than exact equality.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n */\n contextDomain?: Record<string, string>;\n}\n\n/** Single axis selector */\nexport interface SingleAxisSelector {\n /** Axis name (required) */\n name: string;\n /** Axis type (optional) */\n type?: AxisValueType;\n /** Domain requirements (optional) */\n domain?: Domain;\n /** Parent axes requirements (optional) */\n parentAxes?: SingleAxisSelector[];\n}\n\n/** Qualification applied to a single axis to make it compatible during integration. */\nexport interface AxisQualification {\n /** Axis selector identifying which axis is qualified. */\n readonly axis: SingleAxisSelector;\n /** Additional context domain entries applied to the axis. */\n readonly contextDomain: Record<string, string>;\n}\n\n/**\n * Reference to an axis by its numerical index within the anchor column's axes array\n * Format: [anchorId, axisIndex]\n */\nexport type AnchorAxisRefByIdx = { anchor: string; idx: number };\n\n/**\n * Reference to an axis by its name within the anchor column\n * Format: [anchorId, axisName]\n */\nexport type AnchorAxisRefByName = { anchor: string; name: string };\n\n/**\n * Reference to an axis using an AxisId matcher within the anchor\n * Format: [anchorId, axisMatcher]\n */\nexport type AnchorAxisRefByMatcher = { anchor: string; id: AxisId };\n\n/**\n * Basic anchor axis reference that can be either by index or a direct AxisId\n */\nexport type AnchorAxisIdOrRefBasic = AnchorAxisRefByIdx | AxisId;\n\n/** Union of all possible ways to reference an axis in an anchored context */\nexport type AnchorAxisRef = AnchorAxisRefByIdx | AnchorAxisRefByName | AnchorAxisRefByMatcher;\n\n/** Reference to a domain value through an anchor */\nexport type AnchorDomainRef = { anchor: string };\n\n/**\n * Domain value that can be either a direct string value or a reference to a domain through an anchor\n * Used to establish domain context that can be resolved relative to other anchored columns\n */\nexport type ADomain = string | AnchorDomainRef;\n/**\n * Axis identifier that can be either a direct AxisId or a reference to an axis through an anchor\n * Allows referring to axes in a way that can be resolved in different contexts\n */\nexport type AAxisSelector = LegacyAxisSelector | AnchorAxisRef;\n\n/**\n * Match resolution strategy for PColumns\n * Specifies how to handle when multiple columns match the criteria\n * (default is \"expectSingle\")\n */\nexport type AnchoredColumnMatchStrategy = \"expectSingle\" | \"expectMultiple\" | \"takeFirst\";\n\n/**\n * Matcher for PColumns in an anchored context\n * Supports partial matching on axes, allowing for flexible column discovery\n */\nexport interface AnchoredPColumnSelector {\n /** Optional name of the column to match; can't be used together with namePattern */\n name?: string;\n /** Optional regexp pattern for column name matching; can't be used together with name */\n namePattern?: string;\n /** Optional value type to match. If an array is provided, matches if the column's type is any of the specified types */\n type?: ValueType | ValueType[];\n /** If specified, the domain values must be anchored to this anchor */\n domainAnchor?: string;\n /** Optional domain values to match, can include anchored references, if domainAnchor is specified,\n * interpreted as additional domains to domain from the anchor */\n domain?: Record<string, ADomain>;\n /** If specified, the context domain values must be anchored to this anchor */\n contextDomainAnchor?: string;\n /** Optional context domain values to match, can include anchored references, if contextDomainAnchor is specified,\n * interpreted as additional context domains to context domain from the anchor */\n contextDomain?: Record<string, ADomain>;\n /** Optional axes to match, can include anchored references */\n axes?: AAxisSelector[];\n /** When true, allows matching if only a subset of axes match */\n partialAxesMatch?: boolean;\n /** Optional annotations to match with exact values */\n annotations?: Record<string, string>;\n /** Optional annotation patterns to match with regex patterns */\n annotationPatterns?: Record<string, string>;\n /** Match resolution strategy, default is \"expectSingle\" */\n matchStrategy?: AnchoredColumnMatchStrategy;\n}\n\n/**\n * Matcher for PColumns in a non-anchored context\n */\nexport interface PColumnSelector extends AnchoredPColumnSelector {\n domainAnchor?: never;\n domain?: Record<string, string>;\n contextDomainAnchor?: never;\n contextDomain?: Record<string, string>;\n axes?: LegacyAxisSelector[];\n}\n\n/**\n * Strict identifier for PColumns in an anchored context\n * Unlike APColumnMatcher, this requires exact matches on domain and axes\n */\nexport interface AnchoredPColumnId extends AnchoredPColumnSelector {\n /** Name is required for exact column identification */\n name: string;\n /** No namePattern in ID */\n namePattern?: never;\n /** Type is not used in exact column identification */\n type?: never;\n /** Full axes specification using only basic references */\n axes: AnchorAxisIdOrRefBasic[];\n /** Partial axes matching is not allowed for exact identification */\n partialAxesMatch?: never;\n /** Annotations are not used in exact column identification */\n annotations?: never;\n /** Annotation patterns are not used in exact column identification */\n annotationPatterns?: never;\n /** \"Id\" implies single match strategy */\n matchStrategy?: never;\n}\n\n/**\n * Checks if a given value is an anchored column identifier\n * @param id - The value to check\n * @returns True if the value is an anchored column identifier, false otherwise\n */\nexport function isAnchoredPColumnId(id: unknown): id is AnchoredPColumnId {\n // basic check, can be extended if needed\n return typeof id === \"object\" && id !== null && \"name\" in id && \"axes\" in id;\n}\n\n/**\n * Determines if an axis ID matches an axis selector.\n *\n * @param selector - The selector with criteria to match against\n * @param axis - The AxisId to check against the selector\n * @returns true if the AxisId matches all specified criteria in the selector, false otherwise\n */\nexport function matchAxis(selector: LegacyAxisSelector, axis: AxisId): boolean {\n // Match name if specified\n if (selector.name !== undefined && selector.name !== axis.name) return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(axis.type)) return false;\n } else if (selector.type !== axis.type) {\n return false;\n }\n }\n\n // Match domain if specified - using existing logic from matchAxisId\n if (selector.domain !== undefined) {\n const axisDomain = axis.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (axisDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const axisContextDomain = axis.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (axisContextDomain[key] !== value) return false;\n }\n\n return true;\n}\n\n/**\n * Determines if a given PColumnSpec matches a selector.\n *\n * @param pcolumn - The PColumnSpec to check against the selector\n * @param selector - The selector criteria to match against\n * @returns true if the PColumnSpec matches all criteria in the selector, false otherwise\n */\nexport function matchPColumn(pcolumn: PColumnSpec, selector: PColumnSelector): boolean {\n // Match name if specified\n if (selector.name !== undefined && pcolumn.name !== selector.name) return false;\n\n // Match name pattern if specified\n if (selector.namePattern !== undefined && !new RegExp(selector.namePattern).test(pcolumn.name))\n return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(pcolumn.valueType)) return false;\n } else if (selector.type !== pcolumn.valueType) {\n return false;\n }\n }\n\n // Match domain if specified\n if (selector.domain !== undefined) {\n const columnDomain = pcolumn.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (columnDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const columnContextDomain = pcolumn.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (columnContextDomain[key] !== value) return false;\n }\n\n // Match axes if specified\n if (selector.axes !== undefined) {\n const pcolumnAxes = pcolumn.axesSpec.map(getAxisId);\n\n if (selector.partialAxesMatch) {\n // For partial matching, all selector axes must match at least one column axis\n for (const selectorAxis of selector.axes)\n if (!pcolumnAxes.some((columnAxis) => matchAxis(selectorAxis, columnAxis))) return false;\n } else {\n // For exact matching, column must have the same number of axes and all must match\n if (pcolumnAxes.length !== selector.axes.length) return false;\n\n // Each selector axis must match a corresponding column axis\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchAxis(selector.axes[i], pcolumnAxes[i])) return false;\n }\n }\n\n // Match annotations if specified\n if (selector.annotations !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, value] of Object.entries(selector.annotations))\n if (columnAnnotations[key] !== value) return false;\n }\n\n // Match annotation patterns if specified\n if (selector.annotationPatterns !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, pattern] of Object.entries(selector.annotationPatterns)) {\n const value = columnAnnotations[key];\n if (value === undefined || !new RegExp(pattern).test(value)) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Convert a predicate or array of selectors to a single predicate function\n * @param predicateOrSelectors - Either a function that takes a PColumnSpec and returns a boolean,\n * or an array of PColumnSelectors, or a single PColumnSelector\n * @returns A function that takes a PColumnSpec and returns a boolean\n */\nexport function legacyColumnSelectorsToPredicate(\n predicateOrSelectors: PColumnSelector | PColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n if (Array.isArray(predicateOrSelectors))\n return (spec) =>\n predicateOrSelectors.some((selector) => isPColumnSpec(spec) && matchPColumn(spec, selector));\n else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);\n}\n\nfunction matchString(matcher: StringMatcher, value: string): boolean {\n return matcher.type === \"exact\" ? value === matcher.value : new RegExp(matcher.value).test(value);\n}\n\nfunction matchMatcherMap(map: MatcherMap, target: Record<string, string> | undefined): boolean {\n const t = target ?? {};\n for (const [key, matchers] of Object.entries(map)) {\n const v = t[key];\n if (v === undefined) return false;\n if (!matchers.some((m) => matchString(m, v))) return false;\n }\n return true;\n}\n\nfunction matchMultiAxis(selector: MultiAxisSelector, axis: AxisId): boolean {\n if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, axis.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, axis.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, axis.contextDomain)\n )\n return false;\n return true;\n}\n\n/** Match a {@link PColumnSpec} against a {@link MultiColumnSelector}. */\nexport function matchMultiColumnSelector(\n spec: PColumnSpec,\n selector: MultiColumnSelector,\n): boolean {\n if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, spec.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, spec.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, spec.contextDomain)\n )\n return false;\n if (\n selector.annotations !== undefined &&\n !matchMatcherMap(selector.annotations, spec.annotations)\n )\n return false;\n if (selector.axes !== undefined) {\n const columnAxes = spec.axesSpec.map(getAxisId);\n if (selector.partialAxesMatch ?? true) {\n for (const axisSelector of selector.axes)\n if (!columnAxes.some((axis) => matchMultiAxis(axisSelector, axis))) return false;\n } else {\n if (columnAxes.length !== selector.axes.length) return false;\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchMultiAxis(selector.axes[i], columnAxes[i])) return false;\n }\n }\n return true;\n}\n\n/**\n * Convert a {@link MultiColumnSelector} (or array; selectors OR-ed) to a predicate.\n * Non-PColumn specs always return false.\n */\nexport function multiColumnSelectorsToPredicate(\n selectors: MultiColumnSelector | MultiColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n const arr = Array.isArray(selectors) ? selectors : [selectors];\n return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selectors.cjs","names":["getAxisId","isPColumnSpec"],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"sourcesContent":["import { isPColumnSpec, type PObjectSpec } from \"../../../pool\";\nimport type {\n MatcherMap,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../spec_driver\";\nimport type { AxisId, AxisValueType, Domain, PColumnSpec, ValueType } from \"./spec\";\nimport { getAxisId } from \"./spec\";\n\n/**\n * Defines a pattern for matching axes within the PFrame data model.\n *\n * AxisSelector provides a flexible way to identify axes based on their\n * properties. All fields are optional, allowing for partial matching.\n * When multiple properties are specified, all must match for an axis\n * to be selected (logical AND).\n *\n * This interface is used in various selection and matching operations\n * throughout the PFrame system, such as column queries and axis lookups.\n *\n * @deprecated This selector is part of the legacy column matching API.\n * The new Columns API (see sdk/model/src/columns/) now handles column and axis\n * selection via {@link AxisSelector} and {@link ColumnSelector}, providing\n * stricter matching semantics (StringMatcher-based) and a unified approach\n * to working with columns, including domain and annotation matching.\n */\nexport interface LegacyAxisSelector {\n /**\n * Optional value type to match against.\n * When specified, only axes with this exact type will match.\n * Can be a single type or an array of types to match against any of them.\n * Valid types include: 'Int', 'Long', 'Float', 'Double', 'String', 'Bytes'.\n */\n type?: ValueType | ValueType[];\n\n /**\n * Optional name to match against.\n * When specified, only axes with this exact name will match.\n */\n name?: string;\n\n /**\n * Optional domain key-value pairs to match against.\n * Domains provide additional context to uniquely identify an axis beyond its name and type.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n * An axis with additional domain entries not present in this selector will still match.\n */\n domain?: Record<string, string>;\n\n /**\n * Optional context domain key-value pairs to match against.\n * Context domains are matched by kinship rules (subset/superset/overlap) rather than exact equality.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n */\n contextDomain?: Record<string, string>;\n}\n\n/** Single axis selector */\nexport interface SingleAxisSelector {\n /** Axis name (required) */\n name: string;\n /** Axis type (optional) */\n type?: AxisValueType;\n /** Domain requirements (optional) */\n domain?: Domain;\n /** Context-domain requirements (optional) */\n contextDomain?: Domain;\n /** Parent axes requirements (optional) */\n parentAxes?: SingleAxisSelector[];\n}\n\n/** Qualification applied to a single axis to make it compatible during integration. */\nexport interface AxisQualification {\n /** Axis selector identifying which axis is qualified. */\n readonly axis: SingleAxisSelector;\n /** Additional context domain entries applied to the axis. */\n readonly contextDomain: Record<string, string>;\n}\n\n/**\n * Reference to an axis by its numerical index within the anchor column's axes array\n * Format: [anchorId, axisIndex]\n */\nexport type AnchorAxisRefByIdx = { anchor: string; idx: number };\n\n/**\n * Reference to an axis by its name within the anchor column\n * Format: [anchorId, axisName]\n */\nexport type AnchorAxisRefByName = { anchor: string; name: string };\n\n/**\n * Reference to an axis using an AxisId matcher within the anchor\n * Format: [anchorId, axisMatcher]\n */\nexport type AnchorAxisRefByMatcher = { anchor: string; id: AxisId };\n\n/**\n * Basic anchor axis reference that can be either by index or a direct AxisId\n */\nexport type AnchorAxisIdOrRefBasic = AnchorAxisRefByIdx | AxisId;\n\n/** Union of all possible ways to reference an axis in an anchored context */\nexport type AnchorAxisRef = AnchorAxisRefByIdx | AnchorAxisRefByName | AnchorAxisRefByMatcher;\n\n/** Reference to a domain value through an anchor */\nexport type AnchorDomainRef = { anchor: string };\n\n/**\n * Domain value that can be either a direct string value or a reference to a domain through an anchor\n * Used to establish domain context that can be resolved relative to other anchored columns\n */\nexport type ADomain = string | AnchorDomainRef;\n/**\n * Axis identifier that can be either a direct AxisId or a reference to an axis through an anchor\n * Allows referring to axes in a way that can be resolved in different contexts\n */\nexport type AAxisSelector = LegacyAxisSelector | AnchorAxisRef;\n\n/**\n * Match resolution strategy for PColumns\n * Specifies how to handle when multiple columns match the criteria\n * (default is \"expectSingle\")\n */\nexport type AnchoredColumnMatchStrategy = \"expectSingle\" | \"expectMultiple\" | \"takeFirst\";\n\n/**\n * Matcher for PColumns in an anchored context\n * Supports partial matching on axes, allowing for flexible column discovery\n */\nexport interface AnchoredPColumnSelector {\n /** Optional name of the column to match; can't be used together with namePattern */\n name?: string;\n /** Optional regexp pattern for column name matching; can't be used together with name */\n namePattern?: string;\n /** Optional value type to match. If an array is provided, matches if the column's type is any of the specified types */\n type?: ValueType | ValueType[];\n /** If specified, the domain values must be anchored to this anchor */\n domainAnchor?: string;\n /** Optional domain values to match, can include anchored references, if domainAnchor is specified,\n * interpreted as additional domains to domain from the anchor */\n domain?: Record<string, ADomain>;\n /** If specified, the context domain values must be anchored to this anchor */\n contextDomainAnchor?: string;\n /** Optional context domain values to match, can include anchored references, if contextDomainAnchor is specified,\n * interpreted as additional context domains to context domain from the anchor */\n contextDomain?: Record<string, ADomain>;\n /** Optional axes to match, can include anchored references */\n axes?: AAxisSelector[];\n /** When true, allows matching if only a subset of axes match */\n partialAxesMatch?: boolean;\n /** Optional annotations to match with exact values */\n annotations?: Record<string, string>;\n /** Optional annotation patterns to match with regex patterns */\n annotationPatterns?: Record<string, string>;\n /** Match resolution strategy, default is \"expectSingle\" */\n matchStrategy?: AnchoredColumnMatchStrategy;\n}\n\n/**\n * Matcher for PColumns in a non-anchored context\n */\nexport interface PColumnSelector extends AnchoredPColumnSelector {\n domainAnchor?: never;\n domain?: Record<string, string>;\n contextDomainAnchor?: never;\n contextDomain?: Record<string, string>;\n axes?: LegacyAxisSelector[];\n}\n\n/**\n * Strict identifier for PColumns in an anchored context\n * Unlike APColumnMatcher, this requires exact matches on domain and axes\n * @deprecated This is part of the legacy column matching API. The new Columns API (see sdk/model/src/columns/) now handles column and axis\n */\nexport interface AnchoredPColumnId extends AnchoredPColumnSelector {\n /** Name is required for exact column identification */\n name: string;\n /** No namePattern in ID */\n namePattern?: never;\n /** Type is not used in exact column identification */\n type?: never;\n /** Full axes specification using only basic references */\n axes: AnchorAxisIdOrRefBasic[];\n /** Partial axes matching is not allowed for exact identification */\n partialAxesMatch?: never;\n /** Annotations are not used in exact column identification */\n annotations?: never;\n /** Annotation patterns are not used in exact column identification */\n annotationPatterns?: never;\n /** \"Id\" implies single match strategy */\n matchStrategy?: never;\n}\n\n/**\n * Checks if a given value is an anchored column identifier\n * @param id - The value to check\n * @returns True if the value is an anchored column identifier, false otherwise\n */\nexport function isAnchoredPColumnId(id: unknown): id is AnchoredPColumnId {\n // basic check, can be extended if needed\n return typeof id === \"object\" && id !== null && \"name\" in id && \"axes\" in id;\n}\n\n/**\n * Determines if an axis ID matches an axis selector.\n *\n * @param selector - The selector with criteria to match against\n * @param axis - The AxisId to check against the selector\n * @returns true if the AxisId matches all specified criteria in the selector, false otherwise\n */\nexport function matchAxis(selector: LegacyAxisSelector, axis: AxisId): boolean {\n // Match name if specified\n if (selector.name !== undefined && selector.name !== axis.name) return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(axis.type)) return false;\n } else if (selector.type !== axis.type) {\n return false;\n }\n }\n\n // Match domain if specified - using existing logic from matchAxisId\n if (selector.domain !== undefined) {\n const axisDomain = axis.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (axisDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const axisContextDomain = axis.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (axisContextDomain[key] !== value) return false;\n }\n\n return true;\n}\n\n/**\n * Determines if a given PColumnSpec matches a selector.\n *\n * @param pcolumn - The PColumnSpec to check against the selector\n * @param selector - The selector criteria to match against\n * @returns true if the PColumnSpec matches all criteria in the selector, false otherwise\n */\nexport function matchPColumn(pcolumn: PColumnSpec, selector: PColumnSelector): boolean {\n // Match name if specified\n if (selector.name !== undefined && pcolumn.name !== selector.name) return false;\n\n // Match name pattern if specified\n if (selector.namePattern !== undefined && !new RegExp(selector.namePattern).test(pcolumn.name))\n return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(pcolumn.valueType)) return false;\n } else if (selector.type !== pcolumn.valueType) {\n return false;\n }\n }\n\n // Match domain if specified\n if (selector.domain !== undefined) {\n const columnDomain = pcolumn.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (columnDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const columnContextDomain = pcolumn.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (columnContextDomain[key] !== value) return false;\n }\n\n // Match axes if specified\n if (selector.axes !== undefined) {\n const pcolumnAxes = pcolumn.axesSpec.map(getAxisId);\n\n if (selector.partialAxesMatch) {\n // For partial matching, all selector axes must match at least one column axis\n for (const selectorAxis of selector.axes)\n if (!pcolumnAxes.some((columnAxis) => matchAxis(selectorAxis, columnAxis))) return false;\n } else {\n // For exact matching, column must have the same number of axes and all must match\n if (pcolumnAxes.length !== selector.axes.length) return false;\n\n // Each selector axis must match a corresponding column axis\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchAxis(selector.axes[i], pcolumnAxes[i])) return false;\n }\n }\n\n // Match annotations if specified\n if (selector.annotations !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, value] of Object.entries(selector.annotations))\n if (columnAnnotations[key] !== value) return false;\n }\n\n // Match annotation patterns if specified\n if (selector.annotationPatterns !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, pattern] of Object.entries(selector.annotationPatterns)) {\n const value = columnAnnotations[key];\n if (value === undefined || !new RegExp(pattern).test(value)) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Convert a predicate or array of selectors to a single predicate function\n * @param predicateOrSelectors - Either a function that takes a PColumnSpec and returns a boolean,\n * or an array of PColumnSelectors, or a single PColumnSelector\n * @returns A function that takes a PColumnSpec and returns a boolean\n */\nexport function legacyColumnSelectorsToPredicate(\n predicateOrSelectors: PColumnSelector | PColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n if (Array.isArray(predicateOrSelectors))\n return (spec) =>\n predicateOrSelectors.some((selector) => isPColumnSpec(spec) && matchPColumn(spec, selector));\n else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);\n}\n\nfunction matchString(matcher: StringMatcher, value: string): boolean {\n return matcher.type === \"exact\" ? value === matcher.value : new RegExp(matcher.value).test(value);\n}\n\nfunction matchMatcherMap(map: MatcherMap, target: Record<string, string> | undefined): boolean {\n const t = target ?? {};\n for (const [key, matchers] of Object.entries(map)) {\n const v = t[key];\n if (v === undefined) return false;\n if (!matchers.some((m) => matchString(m, v))) return false;\n }\n return true;\n}\n\nfunction matchMultiAxis(selector: MultiAxisSelector, axis: AxisId): boolean {\n if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, axis.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, axis.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, axis.contextDomain)\n )\n return false;\n return true;\n}\n\n/** Match a {@link PColumnSpec} against a {@link MultiColumnSelector}. */\nexport function matchMultiColumnSelector(\n spec: PColumnSpec,\n selector: MultiColumnSelector,\n): boolean {\n if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, spec.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, spec.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, spec.contextDomain)\n )\n return false;\n if (\n selector.annotations !== undefined &&\n !matchMatcherMap(selector.annotations, spec.annotations)\n )\n return false;\n if (selector.axes !== undefined) {\n const columnAxes = spec.axesSpec.map(getAxisId);\n if (selector.partialAxesMatch ?? true) {\n for (const axisSelector of selector.axes)\n if (!columnAxes.some((axis) => matchMultiAxis(axisSelector, axis))) return false;\n } else {\n if (columnAxes.length !== selector.axes.length) return false;\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchMultiAxis(selector.axes[i], columnAxes[i])) return false;\n }\n }\n return true;\n}\n\n/**\n * Convert a {@link MultiColumnSelector} (or array; selectors OR-ed) to a predicate.\n * Non-PColumn specs always return false.\n */\nexport function multiColumnSelectorsToPredicate(\n selectors: MultiColumnSelector | MultiColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n const arr = Array.isArray(selectors) ? selectors : [selectors];\n return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));\n}\n"],"mappings":"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"}
|
|
@@ -54,6 +54,8 @@ interface SingleAxisSelector {
|
|
|
54
54
|
type?: AxisValueType;
|
|
55
55
|
/** Domain requirements (optional) */
|
|
56
56
|
domain?: Domain;
|
|
57
|
+
/** Context-domain requirements (optional) */
|
|
58
|
+
contextDomain?: Domain;
|
|
57
59
|
/** Parent axes requirements (optional) */
|
|
58
60
|
parentAxes?: SingleAxisSelector[];
|
|
59
61
|
}
|
|
@@ -159,6 +161,7 @@ interface PColumnSelector extends AnchoredPColumnSelector {
|
|
|
159
161
|
/**
|
|
160
162
|
* Strict identifier for PColumns in an anchored context
|
|
161
163
|
* Unlike APColumnMatcher, this requires exact matches on domain and axes
|
|
164
|
+
* @deprecated This is part of the legacy column matching API. The new Columns API (see sdk/model/src/columns/) now handles column and axis
|
|
162
165
|
*/
|
|
163
166
|
interface AnchoredPColumnId extends AnchoredPColumnSelector {
|
|
164
167
|
/** Name is required for exact column identification */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"mappings":";;;;;;;AA2BA;;;;;;;;;;;;;;UAAiB,kBAAA;EA4Bf;;;AAAsB;AAIxB;;EAzBE,IAAA,GAAO,SAAA,GAAY,SAAA;EA6BZ;;;;EAvBP,IAAA;
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"mappings":";;;;;;;AA2BA;;;;;;;;;;;;;;UAAiB,kBAAA;EA4Bf;;;AAAsB;AAIxB;;EAzBE,IAAA,GAAO,SAAA,GAAY,SAAA;EA6BZ;;;;EAvBP,IAAA;EA6B+B;;;;;;EArB/B,MAAA,GAAS,MAAA;EAmBO;;;;AAEe;EAd/B,aAAA,GAAgB,MAAA;AAAA;;UAID,kBAAA;EAgBN;EAdT,IAAA;EAgBS;EAdT,IAAA,GAAO,aAAA;EAcuB;EAZ9B,MAAA,GAAS,MAAA;EAmBC;EAjBV,aAAA,GAAgB,MAAA;;EAEhB,UAAA,GAAa,kBAAA;AAAA;AAqBf;AAAA,UAjBiB,iBAAA;;WAEN,IAAA,EAAM,kBAAA;EAeuC;EAAA,SAb7C,aAAA,EAAe,MAAM;AAAA;;;;;KAOpB,kBAAA;EAAuB,MAAA;EAAgB,GAAG;AAAA;;;;AAiBU;KAXpD,mBAAA;EAAwB,MAAA;EAAgB,IAAI;AAAA;;;;;KAM5C,sBAAA;EAA2B,MAAA;EAAgB,EAAA,EAAI,MAAM;AAAA;AAQ4B;AAG7F;;AAH6F,KAHjF,sBAAA,GAAyB,kBAAA,GAAqB,MAAM;;KAGpD,aAAA,GAAgB,kBAAA,GAAqB,mBAAA,GAAsB,sBAAA;AASvE;AAAA,KANY,eAAA;EAAoB,MAAM;AAAA;AAMQ;AAK9C;;;AAL8C,KAAlC,OAAA,YAAmB,eAAe;AAKgB;AAO9D;;;AAP8D,KAAlD,aAAA,GAAgB,kBAAA,GAAqB,aAAa;AAOvB;AAMvC;;;;AANuC,KAA3B,2BAAA;;;;;UAMK,uBAAA;EAsBD;EApBd,IAAA;EAwBgB;EAtBhB,WAAA;EAsB2C;EApB3C,IAAA,GAAO,SAAA,GAAY,SAAA;EAFnB;EAIA,YAAA;EAFO;;EAKP,MAAA,GAAS,MAAA,SAAe,OAAA;EAAxB;EAEA,mBAAA;EAFwB;;EAKxB,aAAA,GAAgB,MAAA,SAAe,OAAA;EAAf;EAEhB,IAAA,GAAO,aAAA;EAAP;EAEA,gBAAA;EAAA;EAEA,WAAA,GAAc,MAAA;EAAA;EAEd,kBAAA,GAAqB,MAAA;EAAA;EAErB,aAAA,GAAgB,2BAAA;AAAA;;AAA2B;AAM7C;UAAiB,eAAA,SAAwB,uBAAA;EACvC,YAAA;EACA,MAAA,GAAS,MAAA;EACT,mBAAA;EACA,aAAA,GAAgB,MAAA;EAChB,IAAA,GAAO,kBAAA;AAAA;;;;;;UAQQ,iBAAA,SAA0B,uBAAuB;EAThE;EAWA,IAAA;EAVA;EAYA,WAAA;EAZyB;EAczB,IAAA;EANe;EAQf,IAAA,EAAM,sBAAA;;EAEN,gBAAA;EAVyC;EAYzC,WAAA;EARA;EAUA,kBAAA;EANA;EAQA,aAAA;AAAA;;;;;AAAa;iBAQC,mBAAA,CAAoB,EAAA,YAAc,EAAA,IAAM,iBAAiB;;;;;;;;iBAYzD,SAAA,CAAU,QAAA,EAAU,kBAAA,EAAoB,IAAA,EAAM,MAAM;AAApE;;;;;;;AAAA,iBAqCgB,YAAA,CAAa,OAAA,EAAS,WAAA,EAAa,QAAA,EAAU,eAAe;;AArCR;AAqCpE;;;;iBA0EgB,gCAAA,CACd,oBAAA,EAAsB,eAAA,GAAkB,eAAA,MACtC,IAAA,EAAM,WAAA;;iBAmCM,wBAAA,CACd,IAAA,EAAM,WAAA,EACN,QAAA,EAAU,mBAAmB;;;AAjH6C;AA0E5E;iBAyEgB,+BAAA,CACd,SAAA,EAAW,mBAAA,GAAsB,mBAAA,MAC/B,IAAA,EAAM,WAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.js","names":[],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"sourcesContent":["import { isPColumnSpec, type PObjectSpec } from \"../../../pool\";\nimport type {\n MatcherMap,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../spec_driver\";\nimport type { AxisId, AxisValueType, Domain, PColumnSpec, ValueType } from \"./spec\";\nimport { getAxisId } from \"./spec\";\n\n/**\n * Defines a pattern for matching axes within the PFrame data model.\n *\n * AxisSelector provides a flexible way to identify axes based on their\n * properties. All fields are optional, allowing for partial matching.\n * When multiple properties are specified, all must match for an axis\n * to be selected (logical AND).\n *\n * This interface is used in various selection and matching operations\n * throughout the PFrame system, such as column queries and axis lookups.\n *\n * @deprecated This selector is part of the legacy column matching API.\n * The new Columns API (see sdk/model/src/columns/) now handles column and axis\n * selection via {@link AxisSelector} and {@link ColumnSelector}, providing\n * stricter matching semantics (StringMatcher-based) and a unified approach\n * to working with columns, including domain and annotation matching.\n */\nexport interface LegacyAxisSelector {\n /**\n * Optional value type to match against.\n * When specified, only axes with this exact type will match.\n * Can be a single type or an array of types to match against any of them.\n * Valid types include: 'Int', 'Long', 'Float', 'Double', 'String', 'Bytes'.\n */\n type?: ValueType | ValueType[];\n\n /**\n * Optional name to match against.\n * When specified, only axes with this exact name will match.\n */\n name?: string;\n\n /**\n * Optional domain key-value pairs to match against.\n * Domains provide additional context to uniquely identify an axis beyond its name and type.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n * An axis with additional domain entries not present in this selector will still match.\n */\n domain?: Record<string, string>;\n\n /**\n * Optional context domain key-value pairs to match against.\n * Context domains are matched by kinship rules (subset/superset/overlap) rather than exact equality.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n */\n contextDomain?: Record<string, string>;\n}\n\n/** Single axis selector */\nexport interface SingleAxisSelector {\n /** Axis name (required) */\n name: string;\n /** Axis type (optional) */\n type?: AxisValueType;\n /** Domain requirements (optional) */\n domain?: Domain;\n /** Parent axes requirements (optional) */\n parentAxes?: SingleAxisSelector[];\n}\n\n/** Qualification applied to a single axis to make it compatible during integration. */\nexport interface AxisQualification {\n /** Axis selector identifying which axis is qualified. */\n readonly axis: SingleAxisSelector;\n /** Additional context domain entries applied to the axis. */\n readonly contextDomain: Record<string, string>;\n}\n\n/**\n * Reference to an axis by its numerical index within the anchor column's axes array\n * Format: [anchorId, axisIndex]\n */\nexport type AnchorAxisRefByIdx = { anchor: string; idx: number };\n\n/**\n * Reference to an axis by its name within the anchor column\n * Format: [anchorId, axisName]\n */\nexport type AnchorAxisRefByName = { anchor: string; name: string };\n\n/**\n * Reference to an axis using an AxisId matcher within the anchor\n * Format: [anchorId, axisMatcher]\n */\nexport type AnchorAxisRefByMatcher = { anchor: string; id: AxisId };\n\n/**\n * Basic anchor axis reference that can be either by index or a direct AxisId\n */\nexport type AnchorAxisIdOrRefBasic = AnchorAxisRefByIdx | AxisId;\n\n/** Union of all possible ways to reference an axis in an anchored context */\nexport type AnchorAxisRef = AnchorAxisRefByIdx | AnchorAxisRefByName | AnchorAxisRefByMatcher;\n\n/** Reference to a domain value through an anchor */\nexport type AnchorDomainRef = { anchor: string };\n\n/**\n * Domain value that can be either a direct string value or a reference to a domain through an anchor\n * Used to establish domain context that can be resolved relative to other anchored columns\n */\nexport type ADomain = string | AnchorDomainRef;\n/**\n * Axis identifier that can be either a direct AxisId or a reference to an axis through an anchor\n * Allows referring to axes in a way that can be resolved in different contexts\n */\nexport type AAxisSelector = LegacyAxisSelector | AnchorAxisRef;\n\n/**\n * Match resolution strategy for PColumns\n * Specifies how to handle when multiple columns match the criteria\n * (default is \"expectSingle\")\n */\nexport type AnchoredColumnMatchStrategy = \"expectSingle\" | \"expectMultiple\" | \"takeFirst\";\n\n/**\n * Matcher for PColumns in an anchored context\n * Supports partial matching on axes, allowing for flexible column discovery\n */\nexport interface AnchoredPColumnSelector {\n /** Optional name of the column to match; can't be used together with namePattern */\n name?: string;\n /** Optional regexp pattern for column name matching; can't be used together with name */\n namePattern?: string;\n /** Optional value type to match. If an array is provided, matches if the column's type is any of the specified types */\n type?: ValueType | ValueType[];\n /** If specified, the domain values must be anchored to this anchor */\n domainAnchor?: string;\n /** Optional domain values to match, can include anchored references, if domainAnchor is specified,\n * interpreted as additional domains to domain from the anchor */\n domain?: Record<string, ADomain>;\n /** If specified, the context domain values must be anchored to this anchor */\n contextDomainAnchor?: string;\n /** Optional context domain values to match, can include anchored references, if contextDomainAnchor is specified,\n * interpreted as additional context domains to context domain from the anchor */\n contextDomain?: Record<string, ADomain>;\n /** Optional axes to match, can include anchored references */\n axes?: AAxisSelector[];\n /** When true, allows matching if only a subset of axes match */\n partialAxesMatch?: boolean;\n /** Optional annotations to match with exact values */\n annotations?: Record<string, string>;\n /** Optional annotation patterns to match with regex patterns */\n annotationPatterns?: Record<string, string>;\n /** Match resolution strategy, default is \"expectSingle\" */\n matchStrategy?: AnchoredColumnMatchStrategy;\n}\n\n/**\n * Matcher for PColumns in a non-anchored context\n */\nexport interface PColumnSelector extends AnchoredPColumnSelector {\n domainAnchor?: never;\n domain?: Record<string, string>;\n contextDomainAnchor?: never;\n contextDomain?: Record<string, string>;\n axes?: LegacyAxisSelector[];\n}\n\n/**\n * Strict identifier for PColumns in an anchored context\n * Unlike APColumnMatcher, this requires exact matches on domain and axes\n */\nexport interface AnchoredPColumnId extends AnchoredPColumnSelector {\n /** Name is required for exact column identification */\n name: string;\n /** No namePattern in ID */\n namePattern?: never;\n /** Type is not used in exact column identification */\n type?: never;\n /** Full axes specification using only basic references */\n axes: AnchorAxisIdOrRefBasic[];\n /** Partial axes matching is not allowed for exact identification */\n partialAxesMatch?: never;\n /** Annotations are not used in exact column identification */\n annotations?: never;\n /** Annotation patterns are not used in exact column identification */\n annotationPatterns?: never;\n /** \"Id\" implies single match strategy */\n matchStrategy?: never;\n}\n\n/**\n * Checks if a given value is an anchored column identifier\n * @param id - The value to check\n * @returns True if the value is an anchored column identifier, false otherwise\n */\nexport function isAnchoredPColumnId(id: unknown): id is AnchoredPColumnId {\n // basic check, can be extended if needed\n return typeof id === \"object\" && id !== null && \"name\" in id && \"axes\" in id;\n}\n\n/**\n * Determines if an axis ID matches an axis selector.\n *\n * @param selector - The selector with criteria to match against\n * @param axis - The AxisId to check against the selector\n * @returns true if the AxisId matches all specified criteria in the selector, false otherwise\n */\nexport function matchAxis(selector: LegacyAxisSelector, axis: AxisId): boolean {\n // Match name if specified\n if (selector.name !== undefined && selector.name !== axis.name) return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(axis.type)) return false;\n } else if (selector.type !== axis.type) {\n return false;\n }\n }\n\n // Match domain if specified - using existing logic from matchAxisId\n if (selector.domain !== undefined) {\n const axisDomain = axis.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (axisDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const axisContextDomain = axis.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (axisContextDomain[key] !== value) return false;\n }\n\n return true;\n}\n\n/**\n * Determines if a given PColumnSpec matches a selector.\n *\n * @param pcolumn - The PColumnSpec to check against the selector\n * @param selector - The selector criteria to match against\n * @returns true if the PColumnSpec matches all criteria in the selector, false otherwise\n */\nexport function matchPColumn(pcolumn: PColumnSpec, selector: PColumnSelector): boolean {\n // Match name if specified\n if (selector.name !== undefined && pcolumn.name !== selector.name) return false;\n\n // Match name pattern if specified\n if (selector.namePattern !== undefined && !new RegExp(selector.namePattern).test(pcolumn.name))\n return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(pcolumn.valueType)) return false;\n } else if (selector.type !== pcolumn.valueType) {\n return false;\n }\n }\n\n // Match domain if specified\n if (selector.domain !== undefined) {\n const columnDomain = pcolumn.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (columnDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const columnContextDomain = pcolumn.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (columnContextDomain[key] !== value) return false;\n }\n\n // Match axes if specified\n if (selector.axes !== undefined) {\n const pcolumnAxes = pcolumn.axesSpec.map(getAxisId);\n\n if (selector.partialAxesMatch) {\n // For partial matching, all selector axes must match at least one column axis\n for (const selectorAxis of selector.axes)\n if (!pcolumnAxes.some((columnAxis) => matchAxis(selectorAxis, columnAxis))) return false;\n } else {\n // For exact matching, column must have the same number of axes and all must match\n if (pcolumnAxes.length !== selector.axes.length) return false;\n\n // Each selector axis must match a corresponding column axis\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchAxis(selector.axes[i], pcolumnAxes[i])) return false;\n }\n }\n\n // Match annotations if specified\n if (selector.annotations !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, value] of Object.entries(selector.annotations))\n if (columnAnnotations[key] !== value) return false;\n }\n\n // Match annotation patterns if specified\n if (selector.annotationPatterns !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, pattern] of Object.entries(selector.annotationPatterns)) {\n const value = columnAnnotations[key];\n if (value === undefined || !new RegExp(pattern).test(value)) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Convert a predicate or array of selectors to a single predicate function\n * @param predicateOrSelectors - Either a function that takes a PColumnSpec and returns a boolean,\n * or an array of PColumnSelectors, or a single PColumnSelector\n * @returns A function that takes a PColumnSpec and returns a boolean\n */\nexport function legacyColumnSelectorsToPredicate(\n predicateOrSelectors: PColumnSelector | PColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n if (Array.isArray(predicateOrSelectors))\n return (spec) =>\n predicateOrSelectors.some((selector) => isPColumnSpec(spec) && matchPColumn(spec, selector));\n else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);\n}\n\nfunction matchString(matcher: StringMatcher, value: string): boolean {\n return matcher.type === \"exact\" ? value === matcher.value : new RegExp(matcher.value).test(value);\n}\n\nfunction matchMatcherMap(map: MatcherMap, target: Record<string, string> | undefined): boolean {\n const t = target ?? {};\n for (const [key, matchers] of Object.entries(map)) {\n const v = t[key];\n if (v === undefined) return false;\n if (!matchers.some((m) => matchString(m, v))) return false;\n }\n return true;\n}\n\nfunction matchMultiAxis(selector: MultiAxisSelector, axis: AxisId): boolean {\n if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, axis.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, axis.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, axis.contextDomain)\n )\n return false;\n return true;\n}\n\n/** Match a {@link PColumnSpec} against a {@link MultiColumnSelector}. */\nexport function matchMultiColumnSelector(\n spec: PColumnSpec,\n selector: MultiColumnSelector,\n): boolean {\n if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, spec.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, spec.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, spec.contextDomain)\n )\n return false;\n if (\n selector.annotations !== undefined &&\n !matchMatcherMap(selector.annotations, spec.annotations)\n )\n return false;\n if (selector.axes !== undefined) {\n const columnAxes = spec.axesSpec.map(getAxisId);\n if (selector.partialAxesMatch ?? true) {\n for (const axisSelector of selector.axes)\n if (!columnAxes.some((axis) => matchMultiAxis(axisSelector, axis))) return false;\n } else {\n if (columnAxes.length !== selector.axes.length) return false;\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchMultiAxis(selector.axes[i], columnAxes[i])) return false;\n }\n }\n return true;\n}\n\n/**\n * Convert a {@link MultiColumnSelector} (or array; selectors OR-ed) to a predicate.\n * Non-PColumn specs always return false.\n */\nexport function multiColumnSelectorsToPredicate(\n selectors: MultiColumnSelector | MultiColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n const arr = Array.isArray(selectors) ? selectors : [selectors];\n return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selectors.js","names":[],"sources":["../../../../src/drivers/pframe/spec/selectors.ts"],"sourcesContent":["import { isPColumnSpec, type PObjectSpec } from \"../../../pool\";\nimport type {\n MatcherMap,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"../spec_driver\";\nimport type { AxisId, AxisValueType, Domain, PColumnSpec, ValueType } from \"./spec\";\nimport { getAxisId } from \"./spec\";\n\n/**\n * Defines a pattern for matching axes within the PFrame data model.\n *\n * AxisSelector provides a flexible way to identify axes based on their\n * properties. All fields are optional, allowing for partial matching.\n * When multiple properties are specified, all must match for an axis\n * to be selected (logical AND).\n *\n * This interface is used in various selection and matching operations\n * throughout the PFrame system, such as column queries and axis lookups.\n *\n * @deprecated This selector is part of the legacy column matching API.\n * The new Columns API (see sdk/model/src/columns/) now handles column and axis\n * selection via {@link AxisSelector} and {@link ColumnSelector}, providing\n * stricter matching semantics (StringMatcher-based) and a unified approach\n * to working with columns, including domain and annotation matching.\n */\nexport interface LegacyAxisSelector {\n /**\n * Optional value type to match against.\n * When specified, only axes with this exact type will match.\n * Can be a single type or an array of types to match against any of them.\n * Valid types include: 'Int', 'Long', 'Float', 'Double', 'String', 'Bytes'.\n */\n type?: ValueType | ValueType[];\n\n /**\n * Optional name to match against.\n * When specified, only axes with this exact name will match.\n */\n name?: string;\n\n /**\n * Optional domain key-value pairs to match against.\n * Domains provide additional context to uniquely identify an axis beyond its name and type.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n * An axis with additional domain entries not present in this selector will still match.\n */\n domain?: Record<string, string>;\n\n /**\n * Optional context domain key-value pairs to match against.\n * Context domains are matched by kinship rules (subset/superset/overlap) rather than exact equality.\n * When specified, an axis will match only if it contains all the key-value pairs defined here.\n */\n contextDomain?: Record<string, string>;\n}\n\n/** Single axis selector */\nexport interface SingleAxisSelector {\n /** Axis name (required) */\n name: string;\n /** Axis type (optional) */\n type?: AxisValueType;\n /** Domain requirements (optional) */\n domain?: Domain;\n /** Context-domain requirements (optional) */\n contextDomain?: Domain;\n /** Parent axes requirements (optional) */\n parentAxes?: SingleAxisSelector[];\n}\n\n/** Qualification applied to a single axis to make it compatible during integration. */\nexport interface AxisQualification {\n /** Axis selector identifying which axis is qualified. */\n readonly axis: SingleAxisSelector;\n /** Additional context domain entries applied to the axis. */\n readonly contextDomain: Record<string, string>;\n}\n\n/**\n * Reference to an axis by its numerical index within the anchor column's axes array\n * Format: [anchorId, axisIndex]\n */\nexport type AnchorAxisRefByIdx = { anchor: string; idx: number };\n\n/**\n * Reference to an axis by its name within the anchor column\n * Format: [anchorId, axisName]\n */\nexport type AnchorAxisRefByName = { anchor: string; name: string };\n\n/**\n * Reference to an axis using an AxisId matcher within the anchor\n * Format: [anchorId, axisMatcher]\n */\nexport type AnchorAxisRefByMatcher = { anchor: string; id: AxisId };\n\n/**\n * Basic anchor axis reference that can be either by index or a direct AxisId\n */\nexport type AnchorAxisIdOrRefBasic = AnchorAxisRefByIdx | AxisId;\n\n/** Union of all possible ways to reference an axis in an anchored context */\nexport type AnchorAxisRef = AnchorAxisRefByIdx | AnchorAxisRefByName | AnchorAxisRefByMatcher;\n\n/** Reference to a domain value through an anchor */\nexport type AnchorDomainRef = { anchor: string };\n\n/**\n * Domain value that can be either a direct string value or a reference to a domain through an anchor\n * Used to establish domain context that can be resolved relative to other anchored columns\n */\nexport type ADomain = string | AnchorDomainRef;\n/**\n * Axis identifier that can be either a direct AxisId or a reference to an axis through an anchor\n * Allows referring to axes in a way that can be resolved in different contexts\n */\nexport type AAxisSelector = LegacyAxisSelector | AnchorAxisRef;\n\n/**\n * Match resolution strategy for PColumns\n * Specifies how to handle when multiple columns match the criteria\n * (default is \"expectSingle\")\n */\nexport type AnchoredColumnMatchStrategy = \"expectSingle\" | \"expectMultiple\" | \"takeFirst\";\n\n/**\n * Matcher for PColumns in an anchored context\n * Supports partial matching on axes, allowing for flexible column discovery\n */\nexport interface AnchoredPColumnSelector {\n /** Optional name of the column to match; can't be used together with namePattern */\n name?: string;\n /** Optional regexp pattern for column name matching; can't be used together with name */\n namePattern?: string;\n /** Optional value type to match. If an array is provided, matches if the column's type is any of the specified types */\n type?: ValueType | ValueType[];\n /** If specified, the domain values must be anchored to this anchor */\n domainAnchor?: string;\n /** Optional domain values to match, can include anchored references, if domainAnchor is specified,\n * interpreted as additional domains to domain from the anchor */\n domain?: Record<string, ADomain>;\n /** If specified, the context domain values must be anchored to this anchor */\n contextDomainAnchor?: string;\n /** Optional context domain values to match, can include anchored references, if contextDomainAnchor is specified,\n * interpreted as additional context domains to context domain from the anchor */\n contextDomain?: Record<string, ADomain>;\n /** Optional axes to match, can include anchored references */\n axes?: AAxisSelector[];\n /** When true, allows matching if only a subset of axes match */\n partialAxesMatch?: boolean;\n /** Optional annotations to match with exact values */\n annotations?: Record<string, string>;\n /** Optional annotation patterns to match with regex patterns */\n annotationPatterns?: Record<string, string>;\n /** Match resolution strategy, default is \"expectSingle\" */\n matchStrategy?: AnchoredColumnMatchStrategy;\n}\n\n/**\n * Matcher for PColumns in a non-anchored context\n */\nexport interface PColumnSelector extends AnchoredPColumnSelector {\n domainAnchor?: never;\n domain?: Record<string, string>;\n contextDomainAnchor?: never;\n contextDomain?: Record<string, string>;\n axes?: LegacyAxisSelector[];\n}\n\n/**\n * Strict identifier for PColumns in an anchored context\n * Unlike APColumnMatcher, this requires exact matches on domain and axes\n * @deprecated This is part of the legacy column matching API. The new Columns API (see sdk/model/src/columns/) now handles column and axis\n */\nexport interface AnchoredPColumnId extends AnchoredPColumnSelector {\n /** Name is required for exact column identification */\n name: string;\n /** No namePattern in ID */\n namePattern?: never;\n /** Type is not used in exact column identification */\n type?: never;\n /** Full axes specification using only basic references */\n axes: AnchorAxisIdOrRefBasic[];\n /** Partial axes matching is not allowed for exact identification */\n partialAxesMatch?: never;\n /** Annotations are not used in exact column identification */\n annotations?: never;\n /** Annotation patterns are not used in exact column identification */\n annotationPatterns?: never;\n /** \"Id\" implies single match strategy */\n matchStrategy?: never;\n}\n\n/**\n * Checks if a given value is an anchored column identifier\n * @param id - The value to check\n * @returns True if the value is an anchored column identifier, false otherwise\n */\nexport function isAnchoredPColumnId(id: unknown): id is AnchoredPColumnId {\n // basic check, can be extended if needed\n return typeof id === \"object\" && id !== null && \"name\" in id && \"axes\" in id;\n}\n\n/**\n * Determines if an axis ID matches an axis selector.\n *\n * @param selector - The selector with criteria to match against\n * @param axis - The AxisId to check against the selector\n * @returns true if the AxisId matches all specified criteria in the selector, false otherwise\n */\nexport function matchAxis(selector: LegacyAxisSelector, axis: AxisId): boolean {\n // Match name if specified\n if (selector.name !== undefined && selector.name !== axis.name) return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(axis.type)) return false;\n } else if (selector.type !== axis.type) {\n return false;\n }\n }\n\n // Match domain if specified - using existing logic from matchAxisId\n if (selector.domain !== undefined) {\n const axisDomain = axis.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (axisDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const axisContextDomain = axis.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (axisContextDomain[key] !== value) return false;\n }\n\n return true;\n}\n\n/**\n * Determines if a given PColumnSpec matches a selector.\n *\n * @param pcolumn - The PColumnSpec to check against the selector\n * @param selector - The selector criteria to match against\n * @returns true if the PColumnSpec matches all criteria in the selector, false otherwise\n */\nexport function matchPColumn(pcolumn: PColumnSpec, selector: PColumnSelector): boolean {\n // Match name if specified\n if (selector.name !== undefined && pcolumn.name !== selector.name) return false;\n\n // Match name pattern if specified\n if (selector.namePattern !== undefined && !new RegExp(selector.namePattern).test(pcolumn.name))\n return false;\n\n // Match type if specified\n if (selector.type !== undefined) {\n if (Array.isArray(selector.type)) {\n if (!selector.type.includes(pcolumn.valueType)) return false;\n } else if (selector.type !== pcolumn.valueType) {\n return false;\n }\n }\n\n // Match domain if specified\n if (selector.domain !== undefined) {\n const columnDomain = pcolumn.domain || {};\n for (const [key, value] of Object.entries(selector.domain))\n if (columnDomain[key] !== value) return false;\n }\n\n // Match contextDomain if specified\n if (selector.contextDomain !== undefined) {\n const columnContextDomain = pcolumn.contextDomain || {};\n for (const [key, value] of Object.entries(selector.contextDomain))\n if (columnContextDomain[key] !== value) return false;\n }\n\n // Match axes if specified\n if (selector.axes !== undefined) {\n const pcolumnAxes = pcolumn.axesSpec.map(getAxisId);\n\n if (selector.partialAxesMatch) {\n // For partial matching, all selector axes must match at least one column axis\n for (const selectorAxis of selector.axes)\n if (!pcolumnAxes.some((columnAxis) => matchAxis(selectorAxis, columnAxis))) return false;\n } else {\n // For exact matching, column must have the same number of axes and all must match\n if (pcolumnAxes.length !== selector.axes.length) return false;\n\n // Each selector axis must match a corresponding column axis\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchAxis(selector.axes[i], pcolumnAxes[i])) return false;\n }\n }\n\n // Match annotations if specified\n if (selector.annotations !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, value] of Object.entries(selector.annotations))\n if (columnAnnotations[key] !== value) return false;\n }\n\n // Match annotation patterns if specified\n if (selector.annotationPatterns !== undefined) {\n const columnAnnotations = pcolumn.annotations || {};\n for (const [key, pattern] of Object.entries(selector.annotationPatterns)) {\n const value = columnAnnotations[key];\n if (value === undefined || !new RegExp(pattern).test(value)) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Convert a predicate or array of selectors to a single predicate function\n * @param predicateOrSelectors - Either a function that takes a PColumnSpec and returns a boolean,\n * or an array of PColumnSelectors, or a single PColumnSelector\n * @returns A function that takes a PColumnSpec and returns a boolean\n */\nexport function legacyColumnSelectorsToPredicate(\n predicateOrSelectors: PColumnSelector | PColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n if (Array.isArray(predicateOrSelectors))\n return (spec) =>\n predicateOrSelectors.some((selector) => isPColumnSpec(spec) && matchPColumn(spec, selector));\n else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);\n}\n\nfunction matchString(matcher: StringMatcher, value: string): boolean {\n return matcher.type === \"exact\" ? value === matcher.value : new RegExp(matcher.value).test(value);\n}\n\nfunction matchMatcherMap(map: MatcherMap, target: Record<string, string> | undefined): boolean {\n const t = target ?? {};\n for (const [key, matchers] of Object.entries(map)) {\n const v = t[key];\n if (v === undefined) return false;\n if (!matchers.some((m) => matchString(m, v))) return false;\n }\n return true;\n}\n\nfunction matchMultiAxis(selector: MultiAxisSelector, axis: AxisId): boolean {\n if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, axis.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, axis.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, axis.contextDomain)\n )\n return false;\n return true;\n}\n\n/** Match a {@link PColumnSpec} against a {@link MultiColumnSelector}. */\nexport function matchMultiColumnSelector(\n spec: PColumnSpec,\n selector: MultiColumnSelector,\n): boolean {\n if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;\n if (selector.name !== undefined && !selector.name.some((m) => matchString(m, spec.name)))\n return false;\n if (selector.domain !== undefined && !matchMatcherMap(selector.domain, spec.domain)) return false;\n if (\n selector.contextDomain !== undefined &&\n !matchMatcherMap(selector.contextDomain, spec.contextDomain)\n )\n return false;\n if (\n selector.annotations !== undefined &&\n !matchMatcherMap(selector.annotations, spec.annotations)\n )\n return false;\n if (selector.axes !== undefined) {\n const columnAxes = spec.axesSpec.map(getAxisId);\n if (selector.partialAxesMatch ?? true) {\n for (const axisSelector of selector.axes)\n if (!columnAxes.some((axis) => matchMultiAxis(axisSelector, axis))) return false;\n } else {\n if (columnAxes.length !== selector.axes.length) return false;\n for (let i = 0; i < selector.axes.length; i++)\n if (!matchMultiAxis(selector.axes[i], columnAxes[i])) return false;\n }\n }\n return true;\n}\n\n/**\n * Convert a {@link MultiColumnSelector} (or array; selectors OR-ed) to a predicate.\n * Non-PColumn specs always return false.\n */\nexport function multiColumnSelectorsToPredicate(\n selectors: MultiColumnSelector | MultiColumnSelector[],\n): (spec: PObjectSpec) => boolean {\n const arr = Array.isArray(selectors) ? selectors : [selectors];\n return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));\n}\n"],"mappings":"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"}
|