@dcupl/common 1.11.11 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/esm/attribute-dependency-graph.d.ts +119 -0
  2. package/dist/esm/cache.controller.d.ts +56 -1
  3. package/dist/esm/changeDetection.d.ts +1 -1
  4. package/dist/esm/date-utils.d.ts +50 -0
  5. package/dist/esm/deep-query.service.d.ts +133 -0
  6. package/dist/esm/dependency-graph.d.ts +102 -3
  7. package/dist/esm/index.d.ts +4 -0
  8. package/dist/esm/index.js +3096 -19
  9. package/dist/esm/index.js.map +1 -1
  10. package/dist/esm/indices.controller.d.ts +92 -0
  11. package/dist/esm/logger/index.d.ts +2 -0
  12. package/dist/esm/logger/logger.d.ts +101 -0
  13. package/dist/esm/pivot.d.ts +2 -1
  14. package/dist/esm/query-builder.d.ts +435 -2
  15. package/dist/esm/queryData.d.ts +9 -4
  16. package/dist/esm/types/dcupl.types.d.ts +80 -0
  17. package/dist/esm/types/internal.types.d.ts +1 -1
  18. package/dist/esm/types/list.types.d.ts +10 -0
  19. package/dist/esm/types/model.types.d.ts +49 -12
  20. package/dist/esm/types/query.types.d.ts +500 -2
  21. package/dist/node/index.cjs +5 -0
  22. package/dist/node/index.cjs.map +1 -0
  23. package/package.json +7 -8
  24. package/dist/browser/common.umd.js +0 -2
  25. package/dist/browser/common.umd.js.map +0 -1
  26. package/dist/esm/analytics.controller.js +0 -105
  27. package/dist/esm/analytics.controller.js.map +0 -1
  28. package/dist/esm/cache.controller.js +0 -40
  29. package/dist/esm/cache.controller.js.map +0 -1
  30. package/dist/esm/changeDetection.js +0 -179
  31. package/dist/esm/changeDetection.js.map +0 -1
  32. package/dist/esm/computeSuggestions.js +0 -38
  33. package/dist/esm/computeSuggestions.js.map +0 -1
  34. package/dist/esm/dependency-graph.js +0 -136
  35. package/dist/esm/dependency-graph.js.map +0 -1
  36. package/dist/esm/getAggregation.js +0 -170
  37. package/dist/esm/getAggregation.js.map +0 -1
  38. package/dist/esm/getFacets.js +0 -67
  39. package/dist/esm/getFacets.js.map +0 -1
  40. package/dist/esm/helper.js +0 -102
  41. package/dist/esm/helper.js.map +0 -1
  42. package/dist/esm/indices.controller.js +0 -97
  43. package/dist/esm/indices.controller.js.map +0 -1
  44. package/dist/esm/object-hash.js +0 -33
  45. package/dist/esm/object-hash.js.map +0 -1
  46. package/dist/esm/performance.js +0 -33
  47. package/dist/esm/performance.js.map +0 -1
  48. package/dist/esm/pivot.js +0 -132
  49. package/dist/esm/pivot.js.map +0 -1
  50. package/dist/esm/property-parser.js +0 -57
  51. package/dist/esm/property-parser.js.map +0 -1
  52. package/dist/esm/query-builder.js +0 -233
  53. package/dist/esm/query-builder.js.map +0 -1
  54. package/dist/esm/query.helper.js +0 -172
  55. package/dist/esm/query.helper.js.map +0 -1
  56. package/dist/esm/queryData.js +0 -360
  57. package/dist/esm/queryData.js.map +0 -1
  58. package/dist/esm/script.controller.js +0 -54
  59. package/dist/esm/script.controller.js.map +0 -1
  60. package/dist/esm/template-parser.js +0 -22
  61. package/dist/esm/template-parser.js.map +0 -1
  62. package/dist/esm/types/aggregation.types.js +0 -2
  63. package/dist/esm/types/aggregation.types.js.map +0 -1
  64. package/dist/esm/types/app-loader.types.js +0 -2
  65. package/dist/esm/types/app-loader.types.js.map +0 -1
  66. package/dist/esm/types/data.types.js +0 -2
  67. package/dist/esm/types/data.types.js.map +0 -1
  68. package/dist/esm/types/dcupl.types.js +0 -2
  69. package/dist/esm/types/dcupl.types.js.map +0 -1
  70. package/dist/esm/types/facets.types.js +0 -2
  71. package/dist/esm/types/facets.types.js.map +0 -1
  72. package/dist/esm/types/filter.types.js +0 -2
  73. package/dist/esm/types/filter.types.js.map +0 -1
  74. package/dist/esm/types/group-by.types.js +0 -2
  75. package/dist/esm/types/group-by.types.js.map +0 -1
  76. package/dist/esm/types/index.js +0 -17
  77. package/dist/esm/types/index.js.map +0 -1
  78. package/dist/esm/types/internal.types.js +0 -2
  79. package/dist/esm/types/internal.types.js.map +0 -1
  80. package/dist/esm/types/list.types.js +0 -2
  81. package/dist/esm/types/list.types.js.map +0 -1
  82. package/dist/esm/types/model.types.js +0 -16
  83. package/dist/esm/types/model.types.js.map +0 -1
  84. package/dist/esm/types/projection.types.js +0 -2
  85. package/dist/esm/types/projection.types.js.map +0 -1
  86. package/dist/esm/types/quality.types.js +0 -2
  87. package/dist/esm/types/quality.types.js.map +0 -1
  88. package/dist/esm/types/query.types.js +0 -12
  89. package/dist/esm/types/query.types.js.map +0 -1
  90. package/dist/esm/types/section.types.js +0 -2
  91. package/dist/esm/types/section.types.js.map +0 -1
  92. package/dist/esm/types/suggestion.types.js +0 -2
  93. package/dist/esm/types/suggestion.types.js.map +0 -1
  94. package/dist/esm/types/testing.types.js +0 -2
  95. package/dist/esm/types/testing.types.js.map +0 -1
  96. package/dist/node/index.cjs.js +0 -1
  97. package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/esm/index.js CHANGED
@@ -1,19 +1,3096 @@
1
- export * from './analytics.controller';
2
- export * from './cache.controller';
3
- export * from './changeDetection';
4
- export * from './computeSuggestions';
5
- export * from './dependency-graph';
6
- export * from './getAggregation';
7
- export * from './getFacets';
8
- export * from './helper';
9
- export * from './indices.controller';
10
- export * from './performance';
11
- export * from './pivot';
12
- export * from './property-parser';
13
- export * from './query-builder';
14
- export * from './query.helper';
15
- export * from './queryData';
16
- export * from './script.controller';
17
- export * from './template-parser';
18
- export * from './types';
19
- //# sourceMappingURL=index.js.map
1
+ import { cloneDeep as y, get as v, every as B, findIndex as C, size as W, isEqual as E, differenceBy as q, startsWith as L, endsWith as H, isEqualWith as b, isMatch as U, find as V } from "lodash-es";
2
+ function I(o) {
3
+ const e = K(o);
4
+ return J(e);
5
+ }
6
+ function K(o) {
7
+ if (typeof o != "object" || o === null)
8
+ return String(o);
9
+ if (Array.isArray(o))
10
+ return "[" + o.map(K).join(",") + "]";
11
+ const e = Object.keys(o).sort();
12
+ let t = "{";
13
+ for (let r = 0; r < e.length; r++) {
14
+ const s = e[r];
15
+ t += s + ":" + K(o[s]), r < e.length - 1 && (t += ",");
16
+ }
17
+ return t += "}", t;
18
+ }
19
+ function J(o) {
20
+ let e = 0;
21
+ for (let t = 0; t < o.length; t++) {
22
+ const r = o.charCodeAt(t);
23
+ e = (e << 5) - e + r, e |= 0;
24
+ }
25
+ return e.toString(16);
26
+ }
27
+ const x = {
28
+ now: () => typeof performance < "u" && performance.now ? performance.now() : (/* @__PURE__ */ new Date()).getTime(),
29
+ mark: (o) => {
30
+ typeof performance < "u" && performance.mark && performance.mark(o);
31
+ },
32
+ measure: (o, e, t) => {
33
+ typeof performance < "u" && performance.measure && performance.measure(o, e, t);
34
+ },
35
+ getEntriesByName(o) {
36
+ if (typeof performance < "u" && performance.getEntriesByName)
37
+ return performance.getEntriesByName(o);
38
+ },
39
+ getEntriesByType(o) {
40
+ if (typeof performance < "u" && performance.getEntriesByType)
41
+ return performance.getEntriesByType(o);
42
+ }
43
+ };
44
+ class De {
45
+ data;
46
+ enabled = !1;
47
+ constructor() {
48
+ }
49
+ init(e) {
50
+ this.data = /* @__PURE__ */ new Map(), this.enabled = e;
51
+ }
52
+ set(e) {
53
+ if (!this.enabled) return e.value;
54
+ const t = this.getKey(e.value.name, e.context);
55
+ return this.data.set(t, e.value), this.data.get(t);
56
+ }
57
+ mark(e) {
58
+ if (!this.enabled) return;
59
+ const t = this.getKey(e.name, e.context), r = {
60
+ name: e.name,
61
+ type: "mark",
62
+ value: x.now(),
63
+ createdAt: Date.now()
64
+ };
65
+ return this.data.set(t, r), r;
66
+ }
67
+ measure(e) {
68
+ if (!this.enabled) return;
69
+ const t = this.getKey(e.name, e.context), r = this.data.get(this.getKey(e.start, e.context)), s = this.data.get(this.getKey(e.end, e.context));
70
+ if (!r || !s)
71
+ return;
72
+ const i = s.value - r.value, n = Math.round(i * 100) / 100, a = this.data.get(t);
73
+ if (a && e.sum) {
74
+ const c = a.value + n, f = {
75
+ ...a,
76
+ value: c
77
+ };
78
+ return this.data.set(t, f), f;
79
+ }
80
+ const u = {
81
+ name: e.name,
82
+ type: "measure",
83
+ value: n,
84
+ createdAt: Date.now()
85
+ };
86
+ return e.detail && (u.detail = e.detail), this.data.set(t, u), u;
87
+ }
88
+ update(e) {
89
+ if (!this.enabled) return e.value;
90
+ const t = this.getKey(e.value.name, e.context), r = this.data.get(t);
91
+ if (r) {
92
+ const s = { ...r, ...e.value };
93
+ this.data.set(t, s);
94
+ } else
95
+ this.data.set(t, e.value);
96
+ return this.data.get(t);
97
+ }
98
+ getResourceInfosFromPerformanceAPI() {
99
+ return typeof performance > "u" ? [] : x.getEntriesByType("resource");
100
+ }
101
+ get(e) {
102
+ const t = this.getKey(e.name, e.context);
103
+ return this.data.get(t);
104
+ }
105
+ getByType(e) {
106
+ return Array.from(this.data.values()).filter((t) => t.type === e);
107
+ }
108
+ getByName(e) {
109
+ return Array.from(this.data.values()).filter((t) => t.name === e);
110
+ }
111
+ clear() {
112
+ this.data.clear();
113
+ }
114
+ getKey(e, t) {
115
+ if (!t)
116
+ return e;
117
+ const r = I(t);
118
+ return e + "_" + r;
119
+ }
120
+ }
121
+ let Z = class T {
122
+ nodes;
123
+ edges;
124
+ nodeKinds = /* @__PURE__ */ new Map();
125
+ nodeMeta = /* @__PURE__ */ new Map();
126
+ edgePolicy;
127
+ constructor() {
128
+ this.nodes = /* @__PURE__ */ new Set(), this.edges = /* @__PURE__ */ new Map();
129
+ }
130
+ addNode(e, t) {
131
+ this.nodes.has(e) || (this.nodes.add(e), this.edges.set(e, /* @__PURE__ */ new Set())), t?.kind !== void 0 && this.nodeKinds.set(e, t.kind), t?.meta !== void 0 && this.nodeMeta.set(e, t.meta);
132
+ }
133
+ addDependency(e, t) {
134
+ if (!this.nodes.has(e) || !this.nodes.has(t))
135
+ throw new Error("Both nodes must exist before adding a dependency.");
136
+ if (this.edgePolicy && !this.edgePolicy(
137
+ { name: e, kind: this.nodeKinds.get(e) },
138
+ { name: t, kind: this.nodeKinds.get(t) }
139
+ ))
140
+ throw new Error(`Edge policy rejected dependency from "${e}" to "${t}".`);
141
+ this.edges.get(e).add(t);
142
+ }
143
+ /** Configure an optional policy to validate edges before they are added */
144
+ setEdgePolicy(e) {
145
+ this.edgePolicy = e;
146
+ }
147
+ /** Assign or change a node's kind */
148
+ setNodeKind(e, t) {
149
+ if (!this.nodes.has(e)) throw new Error("Node does not exist.");
150
+ t === void 0 ? this.nodeKinds.delete(e) : this.nodeKinds.set(e, t);
151
+ }
152
+ /** Get a node's kind */
153
+ getNodeKind(e) {
154
+ return this.nodeKinds.get(e);
155
+ }
156
+ /** Set arbitrary metadata for a node */
157
+ setNodeMeta(e, t) {
158
+ if (!this.nodes.has(e)) throw new Error("Node does not exist.");
159
+ this.nodeMeta.set(e, t);
160
+ }
161
+ /** Get metadata for a node */
162
+ getNodeMeta(e) {
163
+ return this.nodeMeta.get(e);
164
+ }
165
+ removeNode(e) {
166
+ if (!this.nodes.has(e))
167
+ throw new Error("Node does not exist.");
168
+ this.nodes.delete(e), this.edges.delete(e);
169
+ for (let t of this.edges.values())
170
+ t.delete(e);
171
+ }
172
+ removeDependency(e, t) {
173
+ if (!this.edges.has(e))
174
+ throw new Error("From node does not exist.");
175
+ this.edges.get(e).delete(t);
176
+ }
177
+ hasNode(e) {
178
+ return this.nodes.has(e);
179
+ }
180
+ hasDependency(e, t) {
181
+ return this.edges.has(e) ? this.edges.get(e).has(t) : !1;
182
+ }
183
+ getDependencies(e) {
184
+ if (!this.edges.has(e))
185
+ throw new Error("Node does not exist.");
186
+ return Array.from(this.edges.get(e));
187
+ }
188
+ getDependents(e) {
189
+ const t = [];
190
+ for (let [r, s] of this.edges)
191
+ s.has(e) && t.push(r);
192
+ return t;
193
+ }
194
+ isCyclic() {
195
+ const e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), r = (s) => {
196
+ if (e.has(s))
197
+ return !1;
198
+ if (t.has(s))
199
+ return !0;
200
+ t.add(s);
201
+ const i = this.edges.get(s);
202
+ if (i) {
203
+ for (let n of i)
204
+ if (r(n))
205
+ return !0;
206
+ }
207
+ return t.delete(s), e.add(s), !1;
208
+ };
209
+ for (let s of this.nodes)
210
+ if (r(s))
211
+ return !0;
212
+ return !1;
213
+ }
214
+ /**
215
+ * Validates that the graph has no cycles.
216
+ * Returns an object with hasCycle boolean and the cycle path if found.
217
+ * @returns {hasCycle: boolean, path?: string[]} - hasCycle is true if a cycle exists, path contains the cycle nodes
218
+ */
219
+ validateNoCycles() {
220
+ const e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), r = [], s = (i) => {
221
+ if (e.has(i))
222
+ return null;
223
+ if (t.has(i)) {
224
+ const a = r.indexOf(i);
225
+ return r.slice(a).concat([i]);
226
+ }
227
+ t.add(i), r.push(i);
228
+ const n = this.edges.get(i);
229
+ if (n)
230
+ for (let a of n) {
231
+ const u = s(a);
232
+ if (u)
233
+ return u;
234
+ }
235
+ return r.pop(), t.delete(i), e.add(i), null;
236
+ };
237
+ for (let i of this.nodes) {
238
+ const n = s(i);
239
+ if (n)
240
+ return { hasCycle: !0, path: n };
241
+ }
242
+ return { hasCycle: !1 };
243
+ }
244
+ order(e) {
245
+ const t = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), s = [], i = e?.allowCycles ?? !1, n = (a) => {
246
+ if (t.has(a))
247
+ return;
248
+ if (r.has(a)) {
249
+ if (i)
250
+ return;
251
+ throw new Error("Graph has a cycle.");
252
+ }
253
+ r.add(a);
254
+ const u = this.edges.get(a);
255
+ if (u)
256
+ for (let c of u)
257
+ n(c);
258
+ r.delete(a), t.add(a), s.push(a);
259
+ };
260
+ for (let a of this.nodes)
261
+ t.has(a) || n(a);
262
+ return s;
263
+ }
264
+ clear() {
265
+ this.nodes.clear(), this.edges.clear();
266
+ }
267
+ getNodes() {
268
+ return Array.from(this.nodes);
269
+ }
270
+ getAllEdges() {
271
+ const e = [];
272
+ for (let [t, r] of this.edges)
273
+ for (let s of r)
274
+ e.push([t, s]);
275
+ return e;
276
+ }
277
+ /**
278
+ * Returns all nodes that have no dependants (i.e., no other node depends on them).
279
+ * In graph terms, nodes with zero incoming edges.
280
+ */
281
+ getNodesWithNoDependants() {
282
+ if (this.nodes.size === 0)
283
+ return [];
284
+ const e = /* @__PURE__ */ new Set();
285
+ for (const r of this.edges.values())
286
+ for (const s of r)
287
+ e.add(s);
288
+ const t = [];
289
+ for (const r of this.nodes)
290
+ e.has(r) || t.push(r);
291
+ return t;
292
+ }
293
+ /** Return nodes filtered by kind */
294
+ getNodesByKind(e) {
295
+ const t = [];
296
+ for (const r of this.nodes)
297
+ this.nodeKinds.get(r) === e && t.push(r);
298
+ return t;
299
+ }
300
+ /** Roots by kind (zero incoming) */
301
+ getRootsByKind(e) {
302
+ const t = new Set(this.getNodesWithNoDependants()), r = Array.from(t);
303
+ return e ? r.filter((s) => this.nodeKinds.get(s) === e) : r;
304
+ }
305
+ /** Leaves by kind (zero outgoing) */
306
+ getLeavesByKind(e) {
307
+ const t = [];
308
+ for (const r of this.nodes) {
309
+ const s = this.edges.get(r);
310
+ (!s || s.size === 0) && (!e || this.nodeKinds.get(r) === e) && t.push(r);
311
+ }
312
+ return t;
313
+ }
314
+ /** Filter dependencies of a node by kind */
315
+ getDependenciesOfKind(e, t) {
316
+ return this.getDependencies(e).filter((s) => this.nodeKinds.get(s) === t);
317
+ }
318
+ /** Filter dependents of a node by kind */
319
+ getDependentsOfKind(e, t) {
320
+ return this.getDependents(e).filter((s) => this.nodeKinds.get(s) === t);
321
+ }
322
+ /**
323
+ * Create execution batches (topological levels). Throws if the graph has a cycle.
324
+ * If filterKinds is provided, batches contain only nodes of these kinds, but readiness
325
+ * is evaluated against the complete graph.
326
+ */
327
+ plan(e) {
328
+ const t = /* @__PURE__ */ new Map();
329
+ for (const n of this.nodes) t.set(n, 0);
330
+ for (const n of this.edges.values())
331
+ for (const a of n) t.set(a, (t.get(a) || 0) + 1);
332
+ const r = [];
333
+ let s = Array.from(this.nodes).filter((n) => (t.get(n) || 0) === 0);
334
+ const i = /* @__PURE__ */ new Set();
335
+ for (; s.length > 0; ) {
336
+ const n = s.slice();
337
+ r.push(n), s = [];
338
+ for (const a of n) {
339
+ if (i.has(a)) continue;
340
+ i.add(a);
341
+ const u = this.edges.get(a);
342
+ if (u)
343
+ for (const c of u)
344
+ t.set(c, (t.get(c) || 0) - 1), (t.get(c) || 0) === 0 && s.push(c);
345
+ }
346
+ }
347
+ if (i.size !== this.nodes.size)
348
+ throw new Error("Graph has a cycle.");
349
+ if (e?.filterKinds && e.filterKinds.length > 0) {
350
+ const n = new Set(e.filterKinds);
351
+ return {
352
+ batches: r.map((a) => a.filter((u) => n.has(this.nodeKinds.get(u))))
353
+ };
354
+ }
355
+ return { batches: r };
356
+ }
357
+ /**
358
+ * Impact analysis: return nodes impacted by a set of changed nodes.
359
+ * direction:
360
+ * - 'downstream': nodes that depend (directly/indirectly) on changed
361
+ * - 'upstream': nodes that changed depends on
362
+ * - 'both': union of upstream and downstream
363
+ */
364
+ getImpactedNodes(e, t = "downstream", r) {
365
+ const s = new Set(e), i = (c) => !r || r.length === 0 || r.includes(this.nodeKinds.get(c) ?? void 0), n = () => {
366
+ const c = /* @__PURE__ */ new Set(), f = Array.from(s);
367
+ for (; f.length; ) {
368
+ const d = f.shift();
369
+ for (const [l, h] of this.edges)
370
+ h.has(d) && !c.has(l) && (c.add(l), f.push(l));
371
+ }
372
+ return c;
373
+ }, a = () => {
374
+ const c = /* @__PURE__ */ new Set(), f = Array.from(s);
375
+ for (; f.length; ) {
376
+ const d = f.shift(), l = this.edges.get(d);
377
+ if (l)
378
+ for (const h of l)
379
+ c.has(h) || (c.add(h), f.push(h));
380
+ }
381
+ return c;
382
+ };
383
+ let u;
384
+ return t === "both" ? u = /* @__PURE__ */ new Set([...n(), ...a()]) : t === "upstream" ? u = a() : u = n(), Array.from(u).filter(i);
385
+ }
386
+ toJSON() {
387
+ const e = Array.from(this.nodes).map((r) => ({
388
+ name: r,
389
+ kind: this.nodeKinds.get(r),
390
+ meta: this.nodeMeta.get(r)
391
+ })), t = this.getAllEdges().map(([r, s]) => ({ from: r, to: s }));
392
+ return { nodes: e, edges: t };
393
+ }
394
+ static fromJSON(e) {
395
+ const t = new T();
396
+ for (const r of e.nodes)
397
+ t.addNode(r.name, { kind: r.kind, meta: r.meta });
398
+ for (const r of e.edges)
399
+ t.addDependency(r.from, r.to);
400
+ return t;
401
+ }
402
+ diff(e) {
403
+ const t = new Set(this.getNodes()), r = new Set(e.getNodes()), s = Array.from(r).filter((d) => !t.has(d)), i = Array.from(t).filter((d) => !r.has(d)), n = new Set(this.getAllEdges().map((d) => d.join("→"))), a = new Set(e.getAllEdges().map((d) => d.join("→"))), u = Array.from(a).filter((d) => !n.has(d)).map((d) => d.split("→")), c = Array.from(n).filter((d) => !a.has(d)).map((d) => d.split("→")), f = [];
404
+ for (const d of /* @__PURE__ */ new Set([...t, ...r])) {
405
+ const l = this.nodeKinds.get(d), h = e.nodeKinds.get(d);
406
+ l !== h && f.push({ name: d, from: l, to: h });
407
+ }
408
+ return { addedNodes: s, removedNodes: i, addedEdges: u, removedEdges: c, kindChanges: f };
409
+ }
410
+ };
411
+ class Ke {
412
+ graph;
413
+ nodeIndex;
414
+ constructor() {
415
+ this.graph = new Z(), this.nodeIndex = /* @__PURE__ */ new Map();
416
+ }
417
+ /**
418
+ * Creates a unique ID for an attribute node
419
+ */
420
+ getNodeId(e, t) {
421
+ return `${e}.${t}`;
422
+ }
423
+ /**
424
+ * Parses a node ID back into components
425
+ */
426
+ parseNodeId(e) {
427
+ const t = e.split(".");
428
+ return {
429
+ modelKey: t[0],
430
+ attributeKey: t.slice(1).join(".")
431
+ // Handle attribute keys with dots
432
+ };
433
+ }
434
+ /**
435
+ * Adds an attribute node to the graph
436
+ */
437
+ addAttribute(e) {
438
+ const t = this.getNodeId(e.modelKey, e.attributeKey);
439
+ this.nodeIndex.has(t) || (this.graph.addNode(t, { meta: e }), this.nodeIndex.set(t, e));
440
+ }
441
+ /**
442
+ * Adds a dependency between two attributes
443
+ * @param from - The dependent attribute (e.g., ModelA.derivedPrice)
444
+ * @param to - The source attribute it depends on (e.g., ModelB.baseCost)
445
+ */
446
+ addAttributeDependency(e, t) {
447
+ this.addAttribute(e), this.addAttribute(t);
448
+ const r = this.getNodeId(e.modelKey, e.attributeKey), s = this.getNodeId(t.modelKey, t.attributeKey);
449
+ this.graph.hasDependency(r, s) || this.graph.addDependency(r, s);
450
+ }
451
+ /**
452
+ * Gets all attributes impacted by changes to the given attributes
453
+ * @param changed - Array of changed attribute nodes
454
+ * @returns Array of all impacted attribute nodes (including the changed ones)
455
+ */
456
+ getImpactedAttributes(e) {
457
+ const t = e.map((a) => this.getNodeId(a.modelKey, a.attributeKey)), s = this.graph.getImpactedNodes(t, "downstream").map((a) => this.nodeIndex.get(a)).filter((a) => a !== void 0), i = [...e, ...s], n = /* @__PURE__ */ new Set();
458
+ return i.filter((a) => {
459
+ const u = this.getNodeId(a.modelKey, a.attributeKey);
460
+ return n.has(u) ? !1 : (n.add(u), !0);
461
+ });
462
+ }
463
+ /**
464
+ * Generates a processing plan for the given attributes
465
+ * Groups attributes by model and processing step for efficient batch processing
466
+ *
467
+ * @param attributes - Array of attributes to process
468
+ * @returns Map<modelKey, Map<processingStep, Set<attributeKeys>>>
469
+ */
470
+ getProcessingOrder(e) {
471
+ const t = /* @__PURE__ */ new Map(), r = [...e].sort((s, i) => s.processingStep - i.processingStep);
472
+ for (const s of r) {
473
+ const { modelKey: i, attributeKey: n, processingStep: a } = s;
474
+ t.has(i) || t.set(i, /* @__PURE__ */ new Map());
475
+ const u = t.get(i);
476
+ u.has(a) || u.set(a, /* @__PURE__ */ new Set()), u.get(a).add(n);
477
+ }
478
+ return t;
479
+ }
480
+ /**
481
+ * Gets all attributes for a specific model
482
+ */
483
+ getAttributesForModel(e) {
484
+ const t = [];
485
+ for (const r of this.nodeIndex.values())
486
+ r.modelKey === e && t.push(r);
487
+ return t;
488
+ }
489
+ /**
490
+ * Gets dependencies for a specific attribute
491
+ */
492
+ getDependencies(e) {
493
+ const t = this.getNodeId(e.modelKey, e.attributeKey);
494
+ return this.graph.hasNode(t) ? this.graph.getDependencies(t).map((s) => this.nodeIndex.get(s)).filter((s) => s !== void 0) : [];
495
+ }
496
+ /**
497
+ * Gets dependents for a specific attribute (attributes that depend on this one)
498
+ */
499
+ getDependents(e) {
500
+ const t = this.getNodeId(e.modelKey, e.attributeKey);
501
+ return this.graph.hasNode(t) ? this.graph.getDependents(t).map((s) => this.nodeIndex.get(s)).filter((s) => s !== void 0) : [];
502
+ }
503
+ /**
504
+ * Checks if an attribute has any dependencies
505
+ */
506
+ hasDependencies(e) {
507
+ const t = this.getNodeId(e.modelKey, e.attributeKey);
508
+ return this.graph.hasNode(t) ? this.graph.getDependencies(t).length > 0 : !1;
509
+ }
510
+ /**
511
+ * Checks if a node exists in the graph
512
+ */
513
+ hasNode(e) {
514
+ return this.nodeIndex.has(e);
515
+ }
516
+ /**
517
+ * Gets all attribute nodes in the graph
518
+ */
519
+ getAllAttributes() {
520
+ return Array.from(this.nodeIndex.values());
521
+ }
522
+ /**
523
+ * Gets the maximum dependency depth in the graph
524
+ * Useful for determining if full update might be more efficient
525
+ */
526
+ getMaxDepth() {
527
+ let e = 0;
528
+ const t = (r, s = /* @__PURE__ */ new Set()) => {
529
+ if (s.has(r)) return 0;
530
+ s.add(r);
531
+ const i = this.graph.getDependencies(r);
532
+ if (i.length === 0) return 1;
533
+ let n = 0;
534
+ for (const a of i) {
535
+ const u = t(a, new Set(s));
536
+ n = Math.max(n, u);
537
+ }
538
+ return n + 1;
539
+ };
540
+ for (const r of this.graph.getNodes()) {
541
+ const s = t(r);
542
+ e = Math.max(e, s);
543
+ }
544
+ return e;
545
+ }
546
+ /**
547
+ * Validates that all expected attributes are present in the graph.
548
+ * This helps catch silent failures during graph building where attributes
549
+ * with expressions or derivations might not be properly added.
550
+ *
551
+ * @param expectedAttributes - Map of modelKey to array of attribute keys that should exist
552
+ * @returns Object with validation result and any missing attributes
553
+ */
554
+ validateCompleteness(e) {
555
+ const t = [];
556
+ for (const [r, s] of e)
557
+ for (const i of s) {
558
+ const n = this.getNodeId(r, i);
559
+ this.hasNode(n) || t.push({ modelKey: r, attributeKey: i });
560
+ }
561
+ return {
562
+ isComplete: t.length === 0,
563
+ missing: t
564
+ };
565
+ }
566
+ /**
567
+ * Clears the entire graph
568
+ */
569
+ clear() {
570
+ this.graph.clear(), this.nodeIndex.clear();
571
+ }
572
+ /**
573
+ * Gets statistics about the graph
574
+ */
575
+ getStats() {
576
+ const e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
577
+ for (const r of this.nodeIndex.values())
578
+ e.set(r.modelKey, (e.get(r.modelKey) || 0) + 1), t.set(r.processingStep, (t.get(r.processingStep) || 0) + 1);
579
+ return {
580
+ totalAttributes: this.nodeIndex.size,
581
+ totalDependencies: this.graph.getAllEdges().length,
582
+ maxDepth: this.getMaxDepth(),
583
+ attributesByModel: e,
584
+ attributesByStep: t
585
+ };
586
+ }
587
+ /**
588
+ * Exports the graph to JSON for debugging
589
+ */
590
+ toJSON() {
591
+ return {
592
+ nodes: Array.from(this.nodeIndex.values()),
593
+ edges: this.graph.getAllEdges().map(([e, t]) => {
594
+ const r = this.parseNodeId(e), s = this.parseNodeId(t);
595
+ return {
596
+ from: r,
597
+ to: s
598
+ };
599
+ })
600
+ };
601
+ }
602
+ }
603
+ const O = {
604
+ silent: 0,
605
+ error: 1,
606
+ warn: 2,
607
+ info: 3,
608
+ debug: 4
609
+ };
610
+ class p {
611
+ config;
612
+ static globalConfig = {};
613
+ constructor(e = {}) {
614
+ this.config = {
615
+ level: e.level ?? p.globalConfig.level ?? this.getDefaultLevel(),
616
+ format: e.format ?? p.globalConfig.format ?? this.getDefaultFormat(),
617
+ prefix: e.prefix,
618
+ onLog: e.onLog ?? p.globalConfig.onLog,
619
+ onTrackError: e.onTrackError ?? p.globalConfig.onTrackError
620
+ };
621
+ }
622
+ /**
623
+ * Set global logger configuration (affects all logger instances)
624
+ */
625
+ static setGlobalConfig(e) {
626
+ p.globalConfig = { ...p.globalConfig, ...e };
627
+ }
628
+ /**
629
+ * Get the global logger configuration
630
+ */
631
+ static getGlobalConfig() {
632
+ return { ...p.globalConfig };
633
+ }
634
+ /**
635
+ * Configure module-specific log levels
636
+ * @example
637
+ * logger.setModuleLevel('ModelParser', 'debug');
638
+ * logger.setModuleLevel('Catalog', 'warn');
639
+ */
640
+ static setModuleLevel(e, t) {
641
+ p.globalConfig.onLog || (p.globalConfig.onLog = void 0), p._moduleOverrides || (p._moduleOverrides = /* @__PURE__ */ new Map()), p._moduleOverrides.set(e, t);
642
+ }
643
+ /**
644
+ * Get module-specific log level
645
+ */
646
+ static getModuleLevel(e) {
647
+ if (!(!e || !p._moduleOverrides))
648
+ return p._moduleOverrides.get(e);
649
+ }
650
+ getDefaultLevel() {
651
+ return "info";
652
+ }
653
+ getDefaultFormat() {
654
+ return "pretty";
655
+ }
656
+ getEffectiveLevel() {
657
+ if (this.config.prefix) {
658
+ const e = p.getModuleLevel(this.config.prefix);
659
+ if (e)
660
+ return e;
661
+ }
662
+ return this.config.level;
663
+ }
664
+ shouldLog(e) {
665
+ const t = this.getEffectiveLevel();
666
+ return O[e] <= O[t];
667
+ }
668
+ formatMessage(e) {
669
+ if (this.config.format === "json") {
670
+ const n = {
671
+ timestamp: new Date(e.timestamp).toISOString(),
672
+ level: e.level,
673
+ message: e.message
674
+ };
675
+ return e.prefix && (n.module = e.prefix), e.context && (n.context = e.context), e.error && (n.error = {
676
+ name: e.error.name,
677
+ message: e.error.message,
678
+ stack: e.error.stack
679
+ }), JSON.stringify(n);
680
+ }
681
+ const t = new Date(e.timestamp).toISOString().substring(11, 23), r = e.prefix ? `[${e.prefix}]` : "", s = this.getLevelIcon(e.level), i = e.context ? ` ${JSON.stringify(e.context)}` : "";
682
+ return `${t} ${s} ${r} ${e.message}${i}`.trim();
683
+ }
684
+ getLevelIcon(e) {
685
+ switch (e) {
686
+ case "error":
687
+ return "✖";
688
+ case "warn":
689
+ return "⚠";
690
+ case "info":
691
+ return "ℹ";
692
+ case "debug":
693
+ return "⚙";
694
+ default:
695
+ return " ";
696
+ }
697
+ }
698
+ log(e, t, r, s) {
699
+ if (!this.shouldLog(e))
700
+ return;
701
+ const i = {
702
+ level: e,
703
+ message: t,
704
+ timestamp: Date.now(),
705
+ prefix: this.config.prefix,
706
+ context: r,
707
+ error: s
708
+ };
709
+ if (this.config.onLog) {
710
+ this.config.onLog(i);
711
+ return;
712
+ }
713
+ const n = this.formatMessage(i);
714
+ if (typeof console < "u")
715
+ switch (e) {
716
+ case "error":
717
+ s ? console.error(n, s) : console.error(n);
718
+ break;
719
+ case "warn":
720
+ console.warn(n);
721
+ break;
722
+ case "debug":
723
+ console.debug ? console.debug(n) : console.log(n);
724
+ break;
725
+ default:
726
+ console.log(n);
727
+ }
728
+ }
729
+ /**
730
+ * Log an error message
731
+ */
732
+ error(e, t, r) {
733
+ const s = t instanceof Error ? t : void 0, i = t instanceof Error ? r : t;
734
+ this.log("error", e, i, s);
735
+ }
736
+ /**
737
+ * Log and track an error (integrates with QualityController)
738
+ * @param message Error message
739
+ * @param error Error object
740
+ * @param options Additional context and error classification
741
+ */
742
+ trackError(e, t, r) {
743
+ if (this.error(e, t, r?.context), this.config.onTrackError) {
744
+ const s = {
745
+ level: "error",
746
+ message: e,
747
+ timestamp: Date.now(),
748
+ prefix: this.config.prefix,
749
+ context: r?.context,
750
+ error: t,
751
+ errorType: r?.errorType,
752
+ errorGroup: r?.errorGroup
753
+ };
754
+ this.config.onTrackError(s);
755
+ }
756
+ }
757
+ /**
758
+ * Log a warning message
759
+ */
760
+ warn(e, t) {
761
+ this.log("warn", e, t);
762
+ }
763
+ /**
764
+ * Log an info message
765
+ */
766
+ info(e, t) {
767
+ this.log("info", e, t);
768
+ }
769
+ /**
770
+ * Log a debug message
771
+ */
772
+ debug(e, t) {
773
+ this.log("debug", e, t);
774
+ }
775
+ /**
776
+ * Create a child logger with additional context or configuration
777
+ * Child loggers inherit parent config but can override specific settings
778
+ *
779
+ * @example
780
+ * const modelLogger = logger.child({ prefix: 'ModelParser' });
781
+ * modelLogger.info('Processing data'); // [ModelParser] Processing data
782
+ *
783
+ * @example
784
+ * const debugLogger = logger.child({ prefix: 'Catalog', level: 'debug' });
785
+ */
786
+ child(e) {
787
+ const t = {
788
+ ...this.config,
789
+ ...e,
790
+ // Handle prefix concatenation for nested children
791
+ prefix: e.prefix ? this.config.prefix ? `${this.config.prefix}:${e.prefix}` : e.prefix : this.config.prefix
792
+ };
793
+ return new p(t);
794
+ }
795
+ /**
796
+ * Update this logger's configuration
797
+ */
798
+ configure(e) {
799
+ Object.assign(this.config, e);
800
+ }
801
+ }
802
+ const Y = new p();
803
+ class Se {
804
+ constructor(e) {
805
+ this.enabled = e, this.cache = /* @__PURE__ */ new Map(), this.cacheDependencies = /* @__PURE__ */ new Map();
806
+ }
807
+ cache;
808
+ // Track which models and attributes each cache entry depends on
809
+ cacheDependencies;
810
+ // Track cache hits and misses for statistics
811
+ hitCount = 0;
812
+ missCount = 0;
813
+ log = Y.child({ prefix: "CacheController" });
814
+ get(e, t) {
815
+ if (!this.enabled) return;
816
+ const r = this.getCacheName(e, t);
817
+ return this.cache.has(r) ? this.hitCount++ : this.missCount++, this.cache.get(r);
818
+ }
819
+ set(e, t, r, s) {
820
+ if (!this.enabled) return;
821
+ const i = this.getCacheName(e, t);
822
+ this.cache.set(i, r), s ? this.cacheDependencies.set(i, s) : this.log.debug(
823
+ `Cache entry '${e}' stored without dependencies. This prevents granular invalidation and may cause stale data.`
824
+ );
825
+ }
826
+ has(e, t) {
827
+ return this.cache.has(this.getCacheName(e, t));
828
+ }
829
+ clear() {
830
+ this.cache.clear(), this.cacheDependencies.clear(), this.hitCount = 0, this.missCount = 0;
831
+ }
832
+ /**
833
+ * Invalidates cache entries that depend on the specified models and attributes
834
+ * @param changedModels - Map of modelKey → Set of changed attributeKeys
835
+ */
836
+ invalidateByDependencies(e) {
837
+ if (!this.enabled) return;
838
+ const t = [];
839
+ for (const [r, s] of this.cacheDependencies) {
840
+ let i = !1;
841
+ for (const [n, a] of e) {
842
+ if (s.models.has(n))
843
+ if (s.modelAttributes.has(n)) {
844
+ const u = s.modelAttributes.get(n);
845
+ for (const c of a)
846
+ if (u.has(c)) {
847
+ i = !0;
848
+ break;
849
+ }
850
+ } else
851
+ i = !0;
852
+ if (i) break;
853
+ }
854
+ i && t.push(r);
855
+ }
856
+ for (const r of t)
857
+ this.cache.delete(r), this.cacheDependencies.delete(r);
858
+ }
859
+ /**
860
+ * Invalidates all cache entries for specific models
861
+ * @param modelKeys - Array of model keys to invalidate
862
+ */
863
+ invalidateByModels(e) {
864
+ if (!this.enabled) return;
865
+ const t = new Set(e), r = [];
866
+ for (const [s, i] of this.cacheDependencies)
867
+ for (const n of t)
868
+ if (i.models.has(n)) {
869
+ r.push(s);
870
+ break;
871
+ }
872
+ for (const s of r)
873
+ this.cache.delete(s), this.cacheDependencies.delete(s);
874
+ }
875
+ /**
876
+ * Invalidates cache entries by key prefix (e.g., 'query', 'facets')
877
+ * @param keyPrefix - The key prefix to match
878
+ */
879
+ invalidateByKeyPrefix(e) {
880
+ if (!this.enabled) return;
881
+ const t = [];
882
+ for (const r of this.cache.keys())
883
+ r.startsWith(e + "_") && t.push(r);
884
+ for (const r of t)
885
+ this.cache.delete(r), this.cacheDependencies.delete(r);
886
+ }
887
+ /**
888
+ * Invalidates all cache entries for a specific model
889
+ * @param modelKey - The model key to invalidate
890
+ */
891
+ invalidateForModel(e) {
892
+ this.invalidateByModels([e]);
893
+ }
894
+ /**
895
+ * Invalidates cache entries that depend on a specific attribute of a model
896
+ * @param modelKey - The model key
897
+ * @param attributeKey - The attribute key to invalidate
898
+ */
899
+ invalidateForAttribute(e, t) {
900
+ if (!this.enabled) return;
901
+ const r = /* @__PURE__ */ new Map();
902
+ r.set(e, /* @__PURE__ */ new Set([t])), this.invalidateByDependencies(r);
903
+ }
904
+ /**
905
+ * Invalidates cache entries matching a custom predicate
906
+ * @param predicate - Function that returns true for cache keys to invalidate
907
+ */
908
+ invalidateMatching(e) {
909
+ if (!this.enabled) return;
910
+ const t = [];
911
+ for (const r of this.cache.keys())
912
+ e(r) && t.push(r);
913
+ for (const r of t)
914
+ this.cache.delete(r), this.cacheDependencies.delete(r);
915
+ }
916
+ generateContext(e) {
917
+ try {
918
+ return y(e);
919
+ } catch (t) {
920
+ return this.log.error("Error in cache generateContext", t), e;
921
+ }
922
+ }
923
+ getCacheName(e, t) {
924
+ const r = I(t);
925
+ return e + "_" + r;
926
+ }
927
+ /**
928
+ * Gets cache statistics including hit rate
929
+ */
930
+ getStats() {
931
+ const e = this.hitCount + this.missCount, t = e > 0 ? this.hitCount / e : 0;
932
+ return {
933
+ size: this.cache.size,
934
+ hitRate: t,
935
+ totalEntries: this.cache.size,
936
+ entriesWithDependencies: this.cacheDependencies.size,
937
+ hits: this.hitCount,
938
+ misses: this.missCount
939
+ };
940
+ }
941
+ }
942
+ const Ie = (o, e = "") => `${o}#${e}`, Qe = (o) => `${o.gt}_${o.gte}_${o.lt}_${o.lte}_${o.eq}_${o.ne}`, Me = (o) => `${o.gt}_${o.gte}_${o.lt}_${o.lte}_${o.eq}_${o.ne}`, Ne = (o, e) => {
943
+ const t = typeof e == "function" ? e : (r) => r[e];
944
+ return [
945
+ ...o.reduce((r, s) => {
946
+ const i = s == null ? s : t(s);
947
+ return r.has(i) || r.set(i, s), r;
948
+ }, /* @__PURE__ */ new Map()).values()
949
+ ];
950
+ }, ke = (o, e) => o.reduce(function(t, r) {
951
+ const s = typeof e == "function" ? e(r) : r[e];
952
+ return Object.prototype.hasOwnProperty.call(t, s) || (t[s] = []), t[s].push(r), t;
953
+ }, {});
954
+ function X(o = 10) {
955
+ let e = "";
956
+ const t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
957
+ for (let r = 0; r < o; r++) e += t.charAt(Math.floor(Math.random() * t.length));
958
+ return e;
959
+ }
960
+ const Ce = (o) => o.replace(/\/+$/, ""), ee = (o) => typeof o != "string" ? "" : o.replace(/[[\]{}()*+?.,\\^$|#]/g, "\\$&"), Ee = (o) => typeof o != "string" ? "" : o.replace(/\\([[\]{}()*+?.,\\^$|#])/g, "$1"), qe = (o, e) => {
961
+ try {
962
+ return te(o, e) >= 0;
963
+ } catch {
964
+ return !1;
965
+ }
966
+ }, te = (o, e) => {
967
+ if (!$(o) || !$(e))
968
+ throw new Error(`Invalid version format: v1="${o}", v2="${e}". Expected format: "x.y.z"`);
969
+ const t = o.split(".").map(Number), r = e.split(".").map(Number);
970
+ for (let s = 0; s < 3; s++) {
971
+ const i = t[s] || 0, n = r[s] || 0;
972
+ if (i > n) return 1;
973
+ if (i < n) return -1;
974
+ }
975
+ return 0;
976
+ }, $ = (o) => /^\d+(\.\d+){0,2}$/.test(o);
977
+ class Oe {
978
+ key;
979
+ parentCd;
980
+ dcuplInitOptions;
981
+ analyticsController;
982
+ off;
983
+ updateListener = /* @__PURE__ */ new Set();
984
+ // only the "root" counter will be increased and used in the events
985
+ counter = 0;
986
+ constructor() {
987
+ }
988
+ _init(e) {
989
+ this.key = e.cdRefKey, this.analyticsController = e.analyticsController, this.parentCd = e.parentCd, this.dcuplInitOptions = e.dcuplInitOptions, this.parentCd && (this.off = this.parentCd.on((t) => {
990
+ t.action === "update" && t.originCdRefKey === this.parentCd?.key && (t.connectMessage = !1, this.trigger(t));
991
+ }));
992
+ }
993
+ getCounter() {
994
+ return this.parentCd ? this.parentCd.getCounter() : this.counter;
995
+ }
996
+ increaseCounter() {
997
+ this.parentCd ? this.parentCd.increaseCounter() : this.counter++;
998
+ }
999
+ destroy() {
1000
+ this.off && this.off();
1001
+ }
1002
+ trigger(e) {
1003
+ e.originCdRefKey || (e.originCdRefKey = this.key), e.key || (this.increaseCounter(), e.key = this.getCounter()), e.end || (e.end = x.now(), e.duration = e.start - e.end), this.updateListener.forEach((t) => {
1004
+ t(e);
1005
+ });
1006
+ }
1007
+ on(e) {
1008
+ return this.updateListener.add(e), () => {
1009
+ this.updateListener.delete(e);
1010
+ };
1011
+ }
1012
+ }
1013
+ const j = (o, e) => e ? typeof structuredClone < "u" ? structuredClone(o) : y(o) : o, F = (o, e, t, r, s, i) => {
1014
+ try {
1015
+ const n = !!e.dcuplInitOptions.performance?.clone?.enabled && !!t.cloneResult, a = j(i, n);
1016
+ if (t.scope === "list" && (t.listKey = o.cdRef?.key || o.key, t.modelKey = o.model?.key || o.modelKey), t.type === "list_created" && t.args[0].listKey.startsWith("__global_list__") || t.listKey?.startsWith("__global_list__"))
1017
+ return a;
1018
+ const u = x.now(), c = u - r, f = Math.round(c * 1e3) / 1e3;
1019
+ t.duration = f, t.start = r, t.end = u;
1020
+ const d = {
1021
+ duration: t.duration
1022
+ };
1023
+ return t.modelKey && (d.model = t.modelKey), t.connectMessageResult && (t.result = a), t.args && (d.args = t.args), e?.trigger(t), e.analyticsController.mark({
1024
+ name: `${t.type}:end`,
1025
+ context: s
1026
+ }), e.analyticsController.measure({
1027
+ name: t.type,
1028
+ start: `${t.type}:start`,
1029
+ end: `${t.type}:end`,
1030
+ context: s,
1031
+ detail: d
1032
+ }), a;
1033
+ } catch {
1034
+ return i;
1035
+ }
1036
+ }, $e = (o) => (t, r, s) => {
1037
+ const i = s.value;
1038
+ return s.value = function(...n) {
1039
+ const a = x.now(), u = this.cdRef, c = j(o, !0);
1040
+ c.key || (u.increaseCounter(), c.key = u.getCounter());
1041
+ const f = X();
1042
+ u.analyticsController.mark({
1043
+ name: `${c.type}:start`,
1044
+ context: f
1045
+ });
1046
+ const d = this.model?.key;
1047
+ !c.originCdRefKey && u.key && (c.originCdRefKey = u.key), d && (c.modelKey = d);
1048
+ const l = i.apply(this, n);
1049
+ return c.method = r, c.args = n, l && typeof l == "object" && "then" in l ? l.then((h) => F(this, u, c, a, f, h)) : F(this, u, c, a, f, l);
1050
+ }, s;
1051
+ };
1052
+ function Fe(o, e, t, r) {
1053
+ t.max || (t.max = 20);
1054
+ const s = [], i = t.transform ? r.transformValue(t.value, t.transform) : t.value;
1055
+ for (const [n, a] of e.entries()) {
1056
+ const u = Array.from(a).some((f) => o.has(f)), c = t.transform ? r.transformValue(n, t.transform) : n;
1057
+ if (!(t.excludeUndefineds && typeof n > "u") && !(t.excludeNulls && n === null)) {
1058
+ if (u && (i === "" || i === "//")) {
1059
+ const f = {
1060
+ value: n,
1061
+ keys: t.calculateResultKeys ? Array.from(a) : []
1062
+ };
1063
+ s.push(f);
1064
+ } else if (u && typeof i == "string" && i.startsWith("/") && i.endsWith("/")) {
1065
+ if (r.queryFind(c, i, "some")) {
1066
+ const f = {
1067
+ value: n,
1068
+ keys: t.calculateResultKeys ? Array.from(a) : []
1069
+ };
1070
+ s.push(f);
1071
+ }
1072
+ } else if (u && typeof i == "string") {
1073
+ const f = String(c ?? ""), d = i;
1074
+ if (f.toLowerCase().startsWith(d.toLowerCase())) {
1075
+ const l = {
1076
+ value: n,
1077
+ keys: t.calculateResultKeys ? Array.from(a) : []
1078
+ };
1079
+ s.push(l);
1080
+ }
1081
+ } else if (u && r.queryFind(c, i, "some")) {
1082
+ const f = {
1083
+ value: n,
1084
+ keys: t.calculateResultKeys ? Array.from(a) : []
1085
+ };
1086
+ s.push(f);
1087
+ }
1088
+ if (s.length === t.max)
1089
+ break;
1090
+ }
1091
+ }
1092
+ return s;
1093
+ }
1094
+ function re(o) {
1095
+ return o instanceof Date;
1096
+ }
1097
+ function se(o) {
1098
+ return o instanceof Date && !isNaN(o.getTime());
1099
+ }
1100
+ const ne = {
1101
+ yyyy: { type: "year", pattern: "yyyy", regex: "(\\d{4})" },
1102
+ yy: { type: "year", pattern: "yy", regex: "(\\d{2})" },
1103
+ MM: { type: "month", pattern: "MM", regex: "(\\d{2})" },
1104
+ M: { type: "month", pattern: "M", regex: "(\\d{1,2})" },
1105
+ dd: { type: "day", pattern: "dd", regex: "(\\d{2})" },
1106
+ d: { type: "day", pattern: "d", regex: "(\\d{1,2})" },
1107
+ HH: { type: "hour", pattern: "HH", regex: "(\\d{2})" },
1108
+ H: { type: "hour", pattern: "H", regex: "(\\d{1,2})" },
1109
+ mm: { type: "minute", pattern: "mm", regex: "(\\d{2})" },
1110
+ m: { type: "minute", pattern: "m", regex: "(\\d{1,2})" },
1111
+ ss: { type: "second", pattern: "ss", regex: "(\\d{2})" },
1112
+ s: { type: "second", pattern: "s", regex: "(\\d{1,2})" },
1113
+ SSS: { type: "millisecond", pattern: "SSS", regex: "(\\d{3})" }
1114
+ };
1115
+ function ie(o) {
1116
+ let e = "^";
1117
+ const t = [];
1118
+ let r = o;
1119
+ const s = Object.entries(ne).sort((i, n) => n[0].length - i[0].length);
1120
+ for (; r.length > 0; ) {
1121
+ let i = !1;
1122
+ for (const [n, a] of s)
1123
+ if (r.startsWith(n)) {
1124
+ e += a.regex, t.push({ type: a.type, pattern: n }), r = r.slice(n.length), i = !0;
1125
+ break;
1126
+ }
1127
+ if (!i) {
1128
+ const n = r[0];
1129
+ if (!n)
1130
+ break;
1131
+ e += n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), r = r.slice(1);
1132
+ }
1133
+ }
1134
+ return e += "$", { regex: new RegExp(e), tokenOrder: t };
1135
+ }
1136
+ function oe(o, e) {
1137
+ const t = {
1138
+ year: 1970,
1139
+ month: 1,
1140
+ day: 1,
1141
+ hour: 0,
1142
+ minute: 0,
1143
+ second: 0,
1144
+ millisecond: 0
1145
+ };
1146
+ for (let r = 0; r < e.length; r++) {
1147
+ const s = o[r + 1];
1148
+ if (!s)
1149
+ continue;
1150
+ const i = parseInt(s, 10), n = e[r];
1151
+ n && (n.type === "year" && n.pattern === "yy" ? t.year = 2e3 + i : t[n.type] = i);
1152
+ }
1153
+ return t;
1154
+ }
1155
+ function ae(o) {
1156
+ if (o.month < 1 || o.month > 12)
1157
+ return /* @__PURE__ */ new Date(NaN);
1158
+ if (o.day < 1 || o.day > 31)
1159
+ return /* @__PURE__ */ new Date(NaN);
1160
+ if (o.hour < 0 || o.hour > 23)
1161
+ return /* @__PURE__ */ new Date(NaN);
1162
+ if (o.minute < 0 || o.minute > 59)
1163
+ return /* @__PURE__ */ new Date(NaN);
1164
+ if (o.second < 0 || o.second > 59)
1165
+ return /* @__PURE__ */ new Date(NaN);
1166
+ if (o.millisecond < 0 || o.millisecond > 999)
1167
+ return /* @__PURE__ */ new Date(NaN);
1168
+ const e = new Date(
1169
+ o.year,
1170
+ o.month - 1,
1171
+ o.day,
1172
+ o.hour,
1173
+ o.minute,
1174
+ o.second,
1175
+ o.millisecond
1176
+ );
1177
+ return se(e) ? e.getFullYear() !== o.year || e.getMonth() !== o.month - 1 || e.getDate() !== o.day ? /* @__PURE__ */ new Date(NaN) : e : /* @__PURE__ */ new Date(NaN);
1178
+ }
1179
+ function Ge(o, e, t) {
1180
+ if (o = o.trim(), e === "t") {
1181
+ const a = Number(o);
1182
+ return isNaN(a) ? /* @__PURE__ */ new Date(NaN) : new Date(a * 1e3);
1183
+ }
1184
+ if (e === "T") {
1185
+ const a = Number(o);
1186
+ return isNaN(a) ? /* @__PURE__ */ new Date(NaN) : new Date(a);
1187
+ }
1188
+ const { regex: r, tokenOrder: s } = ie(e), i = o.match(r);
1189
+ if (!i)
1190
+ return /* @__PURE__ */ new Date(NaN);
1191
+ const n = oe(i, s);
1192
+ return ae(n);
1193
+ }
1194
+ class ue {
1195
+ cache;
1196
+ maxSize;
1197
+ accessOrder;
1198
+ constructor(e) {
1199
+ this.cache = /* @__PURE__ */ new Map(), this.maxSize = e, this.accessOrder = [];
1200
+ }
1201
+ get(e) {
1202
+ const t = this.cache.get(e);
1203
+ return t !== void 0 && this.updateAccessOrder(e), t;
1204
+ }
1205
+ set(e, t) {
1206
+ if (this.cache.has(e))
1207
+ this.cache.set(e, t), this.updateAccessOrder(e);
1208
+ else {
1209
+ if (this.cache.size >= this.maxSize) {
1210
+ const r = this.accessOrder.shift();
1211
+ r !== void 0 && this.cache.delete(r);
1212
+ }
1213
+ this.cache.set(e, t), this.accessOrder.push(e);
1214
+ }
1215
+ }
1216
+ has(e) {
1217
+ return this.cache.has(e);
1218
+ }
1219
+ clear() {
1220
+ this.cache.clear(), this.accessOrder = [];
1221
+ }
1222
+ get size() {
1223
+ return this.cache.size;
1224
+ }
1225
+ updateAccessOrder(e) {
1226
+ const t = this.accessOrder.indexOf(e);
1227
+ t > -1 && this.accessOrder.splice(t, 1), this.accessOrder.push(e);
1228
+ }
1229
+ // For testing/debugging
1230
+ getStats() {
1231
+ return {
1232
+ size: this.cache.size,
1233
+ maxSize: this.maxSize
1234
+ };
1235
+ }
1236
+ }
1237
+ class ce {
1238
+ graph;
1239
+ constructor() {
1240
+ this.graph = /* @__PURE__ */ new Map();
1241
+ }
1242
+ addDependency(e, t) {
1243
+ this.graph.has(e) || this.graph.set(e, /* @__PURE__ */ new Set()), this.graph.get(e).add(t);
1244
+ }
1245
+ hasCycle(e) {
1246
+ if (e.length === 0) return !1;
1247
+ const t = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), s = (i) => {
1248
+ t.add(i), r.add(i);
1249
+ const n = this.graph.get(i);
1250
+ if (n) {
1251
+ for (const a of n)
1252
+ if (t.has(a)) {
1253
+ if (r.has(a))
1254
+ return !0;
1255
+ } else if (s(a))
1256
+ return !0;
1257
+ }
1258
+ return r.delete(i), !1;
1259
+ };
1260
+ for (let i = 0; i < e.length - 1; i++) {
1261
+ const n = e[i], a = e[i + 1];
1262
+ n && a && this.addDependency(n, a);
1263
+ }
1264
+ for (const i of e)
1265
+ if (!t.has(i) && s(i))
1266
+ return !0;
1267
+ return !1;
1268
+ }
1269
+ clear() {
1270
+ this.graph.clear();
1271
+ }
1272
+ }
1273
+ class fe {
1274
+ parseCache;
1275
+ circularRefDetector;
1276
+ cacheHits = 0;
1277
+ cacheMisses = 0;
1278
+ constructor(e = 1e3) {
1279
+ this.parseCache = new ue(e), this.circularRefDetector = new ce();
1280
+ }
1281
+ /**
1282
+ * Parse an attribute string into its components
1283
+ *
1284
+ * Supports:
1285
+ * - Dot notation: `customer.name`
1286
+ * - Bracket notation: `items[0].price`, `items[*].price`
1287
+ * - Multi-level: `order.customer.address.city`
1288
+ *
1289
+ * @param attribute - The attribute path to parse
1290
+ * @returns QueryAttributeEntry with isDeepQuery, reference, referenceAttribute
1291
+ *
1292
+ * @example
1293
+ * ```typescript
1294
+ * const service = new DeepQueryService();
1295
+ * const entry = service.parse('customer.name');
1296
+ * // Returns: { attribute: 'customer.name', isDeepQuery: true, reference: 'customer', referenceAttribute: 'name' }
1297
+ * ```
1298
+ */
1299
+ parse(e) {
1300
+ if (this.parseCache.has(e))
1301
+ return this.cacheHits++, this.parseCache.get(e);
1302
+ this.cacheMisses++;
1303
+ let t, r;
1304
+ const s = e.includes("."), i = e.includes("["), n = s || i;
1305
+ if (n)
1306
+ if (r = e.split(/[.[]/)[0], i) {
1307
+ const u = e.indexOf("]");
1308
+ if (u > -1) {
1309
+ const c = e.indexOf(".", u + 1);
1310
+ c > -1 ? t = e.substring(c + 1) : t = void 0;
1311
+ } else s && (t = e.substring(e.indexOf(".") + 1));
1312
+ } else s && (t = e.substring(e.indexOf(".") + 1));
1313
+ const a = {
1314
+ attribute: e,
1315
+ isDeepQuery: n
1316
+ };
1317
+ return r && (a.reference = r), typeof t < "u" && t !== "" && (a.referenceAttribute = t), this.parseCache.set(e, a), a;
1318
+ }
1319
+ /**
1320
+ * Detect circular references in a path
1321
+ *
1322
+ * Checks for:
1323
+ * - Direct circular: A→B→A
1324
+ * - Indirect circular: A→B→C→A
1325
+ * - Self-referential: A→A
1326
+ *
1327
+ * @param path - Array of model/reference keys in the dependency chain
1328
+ * @returns true if circular reference detected
1329
+ *
1330
+ * @example
1331
+ * ```typescript
1332
+ * const service = new DeepQueryService();
1333
+ * const hasCircular = service.detectCircular(['Order', 'Customer', 'Order']);
1334
+ * // Returns: true
1335
+ * ```
1336
+ */
1337
+ detectCircular(e) {
1338
+ return e.length === 0 ? !1 : new Set(e).size !== e.length ? !0 : this.circularRefDetector.hasCycle(e);
1339
+ }
1340
+ /**
1341
+ * Validate attribute path syntax
1342
+ *
1343
+ * Checks for:
1344
+ * - Empty strings
1345
+ * - Malformed bracket notation
1346
+ * - Invalid characters
1347
+ * - Excessive nesting depth
1348
+ *
1349
+ * @param attribute - The attribute path to validate
1350
+ * @param maxDepth - Maximum allowed nesting depth (default: 10)
1351
+ * @returns ValidationResult with errors if invalid
1352
+ *
1353
+ * @example
1354
+ * ```typescript
1355
+ * const service = new DeepQueryService();
1356
+ * const result = service.validatePath('customer.name');
1357
+ * // Returns: { valid: true }
1358
+ *
1359
+ * const badResult = service.validatePath('customer.[invalid]');
1360
+ * // Returns: { valid: false, errors: ['Invalid bracket notation: customer.[invalid]'] }
1361
+ * ```
1362
+ */
1363
+ validatePath(e, t = 10) {
1364
+ const r = [];
1365
+ if (!e || e.trim().length === 0)
1366
+ return r.push("Attribute path cannot be empty"), { valid: !1, errors: r };
1367
+ (e.startsWith(".") || e.endsWith(".")) && r.push(`Invalid path: Leading or trailing dots are not allowed: ${e}`), e.includes("..") && r.push(`Invalid path: Consecutive dots are not allowed: ${e}`);
1368
+ const s = (e.match(/\[/g) || []).length, i = (e.match(/]/g) || []).length;
1369
+ s !== i && r.push(`Invalid bracket notation: Mismatched brackets in ${e}`), e.includes("[]") && r.push(`Invalid bracket notation: Empty brackets not allowed: ${e}`);
1370
+ const n = /\[([^\]]+)\]/g;
1371
+ let a;
1372
+ for (; (a = n.exec(e)) !== null; ) {
1373
+ const f = a[1];
1374
+ f && f !== "*" && !/^\d+$/.test(f) && r.push(`Invalid bracket content: Must be a number or '*', got '${f}' in ${e}`);
1375
+ }
1376
+ const u = (e.match(/\./g) || []).length + 1;
1377
+ u > t && r.push(`Path too deep: Maximum depth is ${t}, got ${u} in ${e}`);
1378
+ const c = e.match(/[^a-zA-Z0-9._[\]*-]/g);
1379
+ return c && r.push(`Invalid characters in path: ${c.join(", ")} in ${e}`), {
1380
+ valid: r.length === 0,
1381
+ errors: r.length > 0 ? r : void 0
1382
+ };
1383
+ }
1384
+ /**
1385
+ * Clear the parse cache
1386
+ * Should be called when models are updated or removed
1387
+ */
1388
+ clearCache() {
1389
+ this.parseCache.clear(), this.cacheHits = 0, this.cacheMisses = 0;
1390
+ }
1391
+ /**
1392
+ * Clear the circular reference detector
1393
+ */
1394
+ clearCircularDetector() {
1395
+ this.circularRefDetector.clear();
1396
+ }
1397
+ /**
1398
+ * Get cache statistics for monitoring and debugging
1399
+ *
1400
+ * @returns Object containing cache size, hit rate, and other metrics
1401
+ */
1402
+ getCacheStats() {
1403
+ const e = this.parseCache.getStats(), t = this.cacheHits + this.cacheMisses, r = t > 0 ? this.cacheHits / t : 0;
1404
+ return {
1405
+ ...e,
1406
+ hits: this.cacheHits,
1407
+ misses: this.cacheMisses,
1408
+ hitRate: r
1409
+ };
1410
+ }
1411
+ /**
1412
+ * Extract path segments from an attribute string
1413
+ * Useful for analyzing deep query structure
1414
+ *
1415
+ * @param attribute - The attribute path
1416
+ * @returns Array of path segments
1417
+ *
1418
+ * @example
1419
+ * ```typescript
1420
+ * const service = new DeepQueryService();
1421
+ * const segments = service.getPathSegments('order.customer.name');
1422
+ * // Returns: ['order', 'customer', 'name']
1423
+ * ```
1424
+ */
1425
+ getPathSegments(e) {
1426
+ return e.replace(/\[[^\]]+\]/g, "").split(".").filter((r) => r.length > 0);
1427
+ }
1428
+ /**
1429
+ * Get the depth of a deep query path
1430
+ *
1431
+ * @param attribute - The attribute path
1432
+ * @returns Depth of the path (1 for shallow, 2+ for deep)
1433
+ */
1434
+ getPathDepth(e) {
1435
+ return this.getPathSegments(e).length;
1436
+ }
1437
+ }
1438
+ const g = new fe();
1439
+ function D(o) {
1440
+ let e = 0;
1441
+ for (let t of o) {
1442
+ const r = t.toString().split(".")[1];
1443
+ r && (e = Math.max(e, r.length));
1444
+ }
1445
+ return Math.pow(10, e);
1446
+ }
1447
+ function G(o, e, t) {
1448
+ return (o * t + e * t) / t;
1449
+ }
1450
+ function de(o, e, t) {
1451
+ return o * t / (e * t);
1452
+ }
1453
+ const Q = (o, e, t, r) => {
1454
+ if (!r)
1455
+ throw new Error("Attribute not found");
1456
+ const s = {
1457
+ attribute: r,
1458
+ types: o.types
1459
+ };
1460
+ let i;
1461
+ (s.types.includes("sum") || s.types.includes("avg") || s.types.includes("count")) && (i = pe(r, e));
1462
+ let n;
1463
+ return (s.types.includes("min") || s.types.includes("max")) && (n = le(r, e)), o.types.forEach((a) => {
1464
+ a === "sum" ? s.sum = i?.sum : a === "avg" ? s.avg = i?.average : a === "count" ? s.count = i?.count : a === "min" ? s.min = n && n[0] : a === "max" ? s.max = n && n[1] : a === "distinct" ? s.distinct = ge(o, e, t) : a === "group" && (s.group = he(o, e));
1465
+ }), s;
1466
+ }, le = (o, e) => {
1467
+ let t, r;
1468
+ const i = g.parse(o).isDeepQuery;
1469
+ for (const n of e.values())
1470
+ if (n) {
1471
+ const a = i ? v(n, o) : n[o];
1472
+ (t === void 0 || a < t) && (t = a), (r === void 0 || a > r) && (r = a);
1473
+ }
1474
+ if (!(t === void 0 || r === void 0))
1475
+ return [t, r];
1476
+ }, he = (o, e) => {
1477
+ const t = [];
1478
+ o.groupOptions?.groups?.forEach((n) => {
1479
+ t.push({
1480
+ option: n,
1481
+ count: 0,
1482
+ keys: []
1483
+ });
1484
+ });
1485
+ const r = {
1486
+ option: { value: ["$dcupl_not_found"] },
1487
+ count: 0,
1488
+ keys: []
1489
+ }, i = g.parse(o.attribute).isDeepQuery;
1490
+ for (const n of e.values()) {
1491
+ const a = i ? v(n, o.attribute) : n[o.attribute];
1492
+ for (const u of t)
1493
+ typeof u.option.value < "u" && u.option.value.includes(a) || typeof u.option.from < "u" && u.option.from < a && typeof u.option.to < "u" && u.option.to > a ? (u.count++, u.keys.push(n.key)) : o?.groupOptions?.calculateNotFound && (r.count++, r.keys.push(n.key));
1494
+ }
1495
+ return o?.groupOptions?.calculateNotFound && t.push(r), t;
1496
+ }, pe = (o, e) => {
1497
+ let t = 0, r = 0;
1498
+ const i = g.parse(o).isDeepQuery;
1499
+ for (const u of e.values()) {
1500
+ if (!u) continue;
1501
+ const c = i ? v(u, o) : u[o];
1502
+ if (Array.isArray(c))
1503
+ for (const f of c)
1504
+ typeof f == "number" && (t = G(t, f, D([t, f])), r++);
1505
+ else typeof c == "number" && (t = G(t, c, D([t, c])), r++);
1506
+ }
1507
+ return r === 0 || r === 0 ? void 0 : {
1508
+ average: de(t, r, D([t, r])),
1509
+ count: e.size,
1510
+ sum: t
1511
+ };
1512
+ }, ge = (o, e, t) => {
1513
+ const r = [];
1514
+ for (const [s, i] of t)
1515
+ if (!(o.excludeUndefineds && typeof s > "u") && Array.from(i).find((n) => e.has(n))) {
1516
+ const n = {
1517
+ value: s,
1518
+ count: i.size
1519
+ };
1520
+ if (o.distinctOptions?.skipKeys || (n.keys = Array.from(i)), r.push(n), o.distinctOptions?.limit && r.length >= o.distinctOptions.limit)
1521
+ break;
1522
+ }
1523
+ return r;
1524
+ };
1525
+ class w extends Error {
1526
+ query;
1527
+ constructor(e, t) {
1528
+ const r = `Query Error: ${e} in ${JSON.stringify(t, null, 2)}`;
1529
+ super(r), this.query = t, this.name = "DcuplQueryError";
1530
+ }
1531
+ }
1532
+ class P {
1533
+ _defaultQueryOptions = {
1534
+ modelKey: "",
1535
+ groupKey: "root",
1536
+ groupType: "and",
1537
+ queries: []
1538
+ };
1539
+ _initOptions;
1540
+ currentQuery = y(this._defaultQueryOptions);
1541
+ deepQueryService;
1542
+ constructor(e) {
1543
+ this.deepQueryService = e || g;
1544
+ }
1545
+ /**
1546
+ * Initialize the query builder.
1547
+ * Accepts either minimal options with just modelKey, or a complete query object.
1548
+ *
1549
+ * @param options - Minimal { modelKey } or full DcuplGlobalQueryOptions
1550
+ *
1551
+ * @example
1552
+ * // Minimal initialization
1553
+ * builder.init({ modelKey: 'Product' });
1554
+ *
1555
+ * @example
1556
+ * // Full query initialization
1557
+ * builder.init({
1558
+ * modelKey: 'Product',
1559
+ * groupType: 'and',
1560
+ * queries: [
1561
+ * { operator: 'eq', attribute: 'status', value: 'active' },
1562
+ * { operator: 'gte', attribute: 'price', value: 100 }
1563
+ * ],
1564
+ * count: 10,
1565
+ * sort: { price: 'asc' }
1566
+ * });
1567
+ */
1568
+ init(e) {
1569
+ this._initOptions = y(e), this.currentQuery = y(this._defaultQueryOptions), this.currentQuery.modelKey = e.modelKey, "queries" in e && Array.isArray(e.queries) && (e.groupType && (this.currentQuery.groupType = e.groupType), e.queries && (this.currentQuery.queries = y(e.queries)), e.count !== void 0 && (this.currentQuery.count = e.count), e.start !== void 0 && (this.currentQuery.start = e.start), e.sort && (this.currentQuery.sort = e.sort), e.projection && (this.currentQuery.projection = e.projection));
1570
+ }
1571
+ reset() {
1572
+ return this.init(this._initOptions), this.getQuery();
1573
+ }
1574
+ isQuery(e) {
1575
+ return "attribute" in e;
1576
+ }
1577
+ isQueryGroup(e) {
1578
+ return "groupKey" in e;
1579
+ }
1580
+ isRootQueryGroup(e) {
1581
+ return this.isQueryGroup(e) && e.groupKey === "root";
1582
+ }
1583
+ getQueryGroup(e) {
1584
+ return this.currentQuery.queries.find((t) => this.isQueryGroup(t) && t.groupKey === e);
1585
+ }
1586
+ getQuery() {
1587
+ return y(this.currentQuery);
1588
+ }
1589
+ hasQueryGroup(e) {
1590
+ return this.currentQuery.queries.some((t) => this.isQueryGroup(t) && t.groupKey === e);
1591
+ }
1592
+ has(e) {
1593
+ if (e.groupKey && e.queryKey) {
1594
+ const t = this.getQueryGroup(e.groupKey);
1595
+ if (t)
1596
+ return t.queries.some((r) => this.isQuery(r) && r.queryKey === e.queryKey);
1597
+ } else if (e.groupKey)
1598
+ return this.hasQueryGroup(e.groupKey);
1599
+ return !1;
1600
+ }
1601
+ validate(e) {
1602
+ const t = e.queries.map((s) => this.validateQuery(s));
1603
+ return { valid: B(t, (s) => s.valid), errors: t.map((s) => s.errors).flat() };
1604
+ }
1605
+ applyOptions(e, t = "update") {
1606
+ return t === "set" ? (this.currentQuery.count = e.count, this.currentQuery.start = e.start, this.currentQuery.sort = e.sort, this.currentQuery.projection = e.projection) : (typeof e?.sort < "u" && (this.currentQuery.sort = e.sort), typeof e?.count < "u" && (this.currentQuery.count = e.count), typeof e?.start < "u" && (this.currentQuery.start = e?.start), typeof e?.projection < "u" && (this.currentQuery.projection = e?.projection)), this.getQuery();
1607
+ }
1608
+ /**
1609
+ * Apply query conditions, groups, or complete queries.
1610
+ * This method has implicit behavior based on input type.
1611
+ *
1612
+ * @deprecated Use explicit methods instead for clearer intent:
1613
+ * - {@link addCondition} - Add single condition
1614
+ * - {@link addConditions} - Add multiple conditions
1615
+ * - {@link addGroup} - Add query group
1616
+ * - {@link setCondition} - Replace condition
1617
+ * - {@link setConditions} - Replace conditions
1618
+ * - {@link setGroup} - Replace query group
1619
+ * - {@link mergeQuery} - Merge complete query
1620
+ * - {@link replaceQuery} - Replace complete query
1621
+ *
1622
+ * @param queryToApply - Query, condition, or array to apply
1623
+ * @param options - Mode: 'add' (default) or 'set' (replace)
1624
+ * @param relevantQuery - Target query (defaults to current)
1625
+ * @returns Updated query
1626
+ */
1627
+ applyQuery(e, t, r) {
1628
+ if (r || (r = this.currentQuery), Array.isArray(e))
1629
+ for (const s of e)
1630
+ this.applyQuery(s, t, r);
1631
+ else if (this.isRootQueryGroup(e))
1632
+ e.groupType && (r.groupType = e.groupType), t?.mode === "set" ? r.queries = e.queries : r.queries = [...r.queries, ...e.queries], this.applyOptions(e, "set");
1633
+ else if (this.isQuery(e)) {
1634
+ const s = r.queries.findIndex(
1635
+ (i) => this.isQueryGroup(i) && i.groupKey === e.attribute
1636
+ );
1637
+ if (s > -1) {
1638
+ const i = r.queries[s];
1639
+ t?.mode === "set" ? i.queries = [e] : i.queries.push(e);
1640
+ } else
1641
+ r.queries.push({
1642
+ groupKey: e.attribute,
1643
+ groupType: "or",
1644
+ queries: [e]
1645
+ });
1646
+ } else if (this.isQueryGroup(e)) {
1647
+ const s = r.queries.findIndex(
1648
+ (i) => this.isQueryGroup(i) && i.groupKey === e.groupKey
1649
+ );
1650
+ if (s > -1) {
1651
+ const i = r.queries[s];
1652
+ e.groupType && (i.groupType = e.groupType), t?.mode === "set" ? r.queries[s] = e : i.queries = [...i.queries, ...e.queries];
1653
+ } else
1654
+ r.queries.push({
1655
+ groupKey: e.groupKey,
1656
+ groupType: e.groupType || "or",
1657
+ queries: e.queries
1658
+ // options: queryToApply.options,
1659
+ });
1660
+ }
1661
+ return r;
1662
+ }
1663
+ /**
1664
+ * Remove all query conditions.
1665
+ *
1666
+ * @deprecated Use {@link clearConditions} for clearer intent.
1667
+ * @returns Query with no conditions
1668
+ */
1669
+ removeAllQueries() {
1670
+ return this.currentQuery.queries = [], this.getQuery();
1671
+ }
1672
+ /**
1673
+ * Remove a specific query or query group.
1674
+ *
1675
+ * @param queryToRemove - Query or group to remove (partial match)
1676
+ * @param relevantQuery - Target query (defaults to current)
1677
+ * @returns Updated query
1678
+ */
1679
+ removeQuery(e, t) {
1680
+ if (t || (t = this.currentQuery), this.isQuery(e)) {
1681
+ const r = t.queries.findIndex(
1682
+ (s) => this.isQueryGroup(s) && s.groupKey === e.attribute
1683
+ );
1684
+ if (r > -1) {
1685
+ const s = t.queries[r], i = C(s.queries, e);
1686
+ i > -1 && s.queries.splice(i, 1), s.queries.length === 0 && t.queries.splice(r, 1);
1687
+ }
1688
+ } else if (this.isQueryGroup(e)) {
1689
+ const r = t.queries.findIndex(
1690
+ (s) => this.isQueryGroup(s) && s.groupKey === e.groupKey
1691
+ );
1692
+ if (r > -1)
1693
+ if (!e.queries)
1694
+ t.queries.splice(r, 1);
1695
+ else {
1696
+ const s = t.queries[r];
1697
+ for (const i of e.queries) {
1698
+ const n = C(s.queries, i);
1699
+ n > -1 && s.queries.splice(n, 1);
1700
+ }
1701
+ s.queries.length === 0 && t.queries.splice(r, 1);
1702
+ }
1703
+ }
1704
+ return t;
1705
+ }
1706
+ validateQuery(e) {
1707
+ const t = [];
1708
+ if (this.isQuery(e))
1709
+ return e.attribute || t.push(new w("Missing attribute", e)), e.operator || t.push(new w("Missing operator", e)), typeof e.value > "u" && t.push(new w("Missing value", e)), e.operator === "find" && Array.isArray(e.value) && t.push(new w("find operator cannot have array value", e)), t.length > 0 ? { valid: !1, errors: t } : { valid: !0 };
1710
+ if (this.isQueryGroup(e)) {
1711
+ const i = e.queries.map((n) => this.validateQuery(n)).filter((n) => !n.valid).map((n) => n.errors).flat();
1712
+ return i.length > 0 ? { valid: !1, errors: i } : { valid: !0 };
1713
+ }
1714
+ return t.push(new w("Invalid query definition", e)), { valid: !1, errors: t };
1715
+ }
1716
+ /**
1717
+ * Get all attribute names used in the query.
1718
+ *
1719
+ * @deprecated Use {@link getAttributeNames} for clearer naming.
1720
+ * @param query - Optional query to analyze
1721
+ * @returns Array of attribute names
1722
+ */
1723
+ getQueryAttributes(e) {
1724
+ const t = [], r = /* @__PURE__ */ new Set(), s = (i) => {
1725
+ for (const n of i)
1726
+ this.isQuery(n) ? n.attribute && !r.has(n.attribute) && (t.push(n.attribute), r.add(n.attribute)) : this.isQueryGroup(n) && s(n.queries);
1727
+ };
1728
+ return s(e?.queries || this.currentQuery.queries), t;
1729
+ }
1730
+ /**
1731
+ * Extract detailed attribute information from query.
1732
+ *
1733
+ * @deprecated Use {@link getAttributeDetails} for clearer naming.
1734
+ * @param query - Query to analyze
1735
+ * @returns Array of QueryAttributeEntry objects
1736
+ */
1737
+ extractQueryAttributes(e) {
1738
+ const t = [], r = /* @__PURE__ */ new Set(), s = (i) => {
1739
+ for (const n of i)
1740
+ if (this.isQuery(n)) {
1741
+ if (n.attribute && !r.has(n.attribute)) {
1742
+ const a = this.getQueryAttributeForString(n.attribute);
1743
+ t.push(a), r.add(n.attribute);
1744
+ }
1745
+ } else this.isQueryGroup(n) && s(n.queries);
1746
+ };
1747
+ return s(e?.queries || this.currentQuery.queries), t;
1748
+ }
1749
+ /**
1750
+ * Parse an attribute string into its components using the DeepQueryService
1751
+ * This method now delegates to the centralized DeepQueryService for consistent
1752
+ * parsing, caching, and validation across the codebase.
1753
+ *
1754
+ * @param attribute - The attribute path to parse (e.g., 'customer.name', 'items[0].price')
1755
+ * @returns QueryAttributeEntry with isDeepQuery, reference, referenceAttribute
1756
+ */
1757
+ getQueryAttributeForString(e) {
1758
+ return this.deepQueryService.parse(e);
1759
+ }
1760
+ /**
1761
+ * Get the DeepQueryService instance used by this query builder
1762
+ * Useful for accessing cache statistics and other service methods
1763
+ *
1764
+ * @returns The DeepQueryService instance
1765
+ */
1766
+ getDeepQueryService() {
1767
+ return this.deepQueryService;
1768
+ }
1769
+ getProjectionForAttributes(e) {
1770
+ const t = {};
1771
+ return e.forEach((r) => {
1772
+ t[r] = !0;
1773
+ }), t;
1774
+ }
1775
+ getProjectionForAttributeEntries(e) {
1776
+ const t = {
1777
+ $: !0
1778
+ };
1779
+ return e.forEach((r) => {
1780
+ if (r.isDeepQuery) {
1781
+ if (r.reference)
1782
+ if (r.referenceAttribute && r.referenceAttribute.length > 0) {
1783
+ t[r.reference] || (t[r.reference] = { $: !0 });
1784
+ const s = this.deepQueryService.parse(r.referenceAttribute);
1785
+ if (s.isDeepQuery && r.reference) {
1786
+ const i = this.getProjectionForAttributeEntries([s]);
1787
+ Object.keys(i).forEach((n) => {
1788
+ n !== "$" && r.reference && (t[r.reference][n] = i[n]);
1789
+ });
1790
+ } else r.reference && (t[r.reference][r.referenceAttribute] = !0);
1791
+ } else
1792
+ t[r.reference] = !0;
1793
+ } else
1794
+ t[r.attribute] = !0;
1795
+ }), t;
1796
+ }
1797
+ // ============================================================================
1798
+ // Semantic Method Aliases - Clearer naming for improved developer experience
1799
+ // ============================================================================
1800
+ /**
1801
+ * Get all attribute names used in the query.
1802
+ * Returns a simple array of unique attribute names.
1803
+ *
1804
+ * Clearer alternative to {@link getQueryAttributes}.
1805
+ *
1806
+ * @param query - Optional query to analyze. If not provided, uses current query.
1807
+ * @returns Array of attribute names used in the query
1808
+ *
1809
+ * @example
1810
+ * ```typescript
1811
+ * builder.addCondition({ operator: 'eq', attribute: 'status', value: 'active' });
1812
+ * builder.addCondition({ operator: 'gte', attribute: 'price', value: 100 });
1813
+ * const attrs = builder.getAttributeNames(); // ['status', 'price']
1814
+ * ```
1815
+ */
1816
+ getAttributeNames(e) {
1817
+ return this.getQueryAttributes(e);
1818
+ }
1819
+ /**
1820
+ * Get detailed information about attributes used in the query.
1821
+ * Returns entries with deep query information (reference, referenceAttribute).
1822
+ *
1823
+ * Clearer alternative to {@link extractQueryAttributes}.
1824
+ *
1825
+ * @param query - Query to analyze. Defaults to current query if not provided.
1826
+ * @returns Array of QueryAttributeEntry objects with details about each attribute
1827
+ *
1828
+ * @example
1829
+ * ```typescript
1830
+ * builder.addCondition({ operator: 'eq', attribute: 'customer.name', value: 'John' });
1831
+ * const details = builder.getAttributeDetails();
1832
+ * // [{ attribute: 'customer.name', isDeepQuery: true, reference: 'customer', referenceAttribute: 'name' }]
1833
+ * ```
1834
+ */
1835
+ getAttributeDetails(e) {
1836
+ return this.extractQueryAttributes(e || this.currentQuery);
1837
+ }
1838
+ /**
1839
+ * Get attribute names from the current query state.
1840
+ * Convenience method that operates on the current query.
1841
+ *
1842
+ * @returns Array of attribute names in current query
1843
+ *
1844
+ * @example
1845
+ * ```typescript
1846
+ * const attrs = builder.getCurrentAttributeNames();
1847
+ * ```
1848
+ */
1849
+ getCurrentAttributeNames() {
1850
+ return this.getAttributeNames(this.currentQuery);
1851
+ }
1852
+ /**
1853
+ * Get detailed attribute information from the current query state.
1854
+ * Convenience method that operates on the current query.
1855
+ *
1856
+ * @returns Array of QueryAttributeEntry objects from current query
1857
+ *
1858
+ * @example
1859
+ * ```typescript
1860
+ * const details = builder.getCurrentAttributeDetails();
1861
+ * ```
1862
+ */
1863
+ getCurrentAttributeDetails() {
1864
+ return this.getAttributeDetails(this.currentQuery);
1865
+ }
1866
+ // ============================================================================
1867
+ // Explicit Query Application Methods - Intention-revealing alternatives to applyQuery
1868
+ // ============================================================================
1869
+ /**
1870
+ * Add query condition(s) to the current query.
1871
+ * Accepts single condition or array of conditions.
1872
+ * Each condition is added to its respective attribute group.
1873
+ *
1874
+ * Clearer alternative to `applyQuery(condition, { mode: 'add' })`.
1875
+ *
1876
+ * @param condition - Single query condition or array of conditions to add
1877
+ * @returns Updated query
1878
+ *
1879
+ * @example
1880
+ * ```typescript
1881
+ * // Add single condition
1882
+ * builder.addCondition({ operator: 'eq', attribute: 'status', value: 'active' });
1883
+ *
1884
+ * // Add multiple conditions
1885
+ * builder.addCondition([
1886
+ * { operator: 'eq', attribute: 'status', value: 'active' },
1887
+ * { operator: 'gte', attribute: 'price', value: 100 }
1888
+ * ]);
1889
+ * ```
1890
+ */
1891
+ addCondition(e) {
1892
+ return this.applyQuery(e, { mode: "add" });
1893
+ }
1894
+ /**
1895
+ * Add a query group to the current query.
1896
+ * If a group with the same groupKey exists, extends it; otherwise creates new group.
1897
+ *
1898
+ * @param group - Query group to add
1899
+ * @returns Updated query
1900
+ *
1901
+ * @example
1902
+ * ```typescript
1903
+ * builder.addGroup({
1904
+ * groupKey: 'priceRange',
1905
+ * groupType: 'and',
1906
+ * queries: [
1907
+ * { operator: 'gte', attribute: 'price', value: 50 },
1908
+ * { operator: 'lte', attribute: 'price', value: 100 }
1909
+ * ]
1910
+ * });
1911
+ * ```
1912
+ */
1913
+ addGroup(e) {
1914
+ return this.applyQuery(e, { mode: "add" });
1915
+ }
1916
+ /**
1917
+ * Replace query with new condition(s).
1918
+ * Accepts single condition or array of conditions.
1919
+ * Each condition replaces all existing conditions for its attribute.
1920
+ *
1921
+ * Clearer alternative to `applyQuery(condition, { mode: 'set' })`.
1922
+ *
1923
+ * @param condition - Single query condition or array of conditions to set
1924
+ * @returns Updated query
1925
+ *
1926
+ * @example
1927
+ * ```typescript
1928
+ * // Replace with single condition
1929
+ * builder.setCondition({ operator: 'eq', attribute: 'status', value: 'active' });
1930
+ *
1931
+ * // Replace with multiple conditions
1932
+ * builder.setCondition([
1933
+ * { operator: 'eq', attribute: 'status', value: 'active' },
1934
+ * { operator: 'gte', attribute: 'price', value: 100 }
1935
+ * ]);
1936
+ * ```
1937
+ */
1938
+ setCondition(e) {
1939
+ return this.applyQuery(e, { mode: "set" });
1940
+ }
1941
+ /**
1942
+ * Replace a query group with new definition.
1943
+ * If group exists, replaces it; otherwise creates new group.
1944
+ *
1945
+ * @param group - Query group to set
1946
+ * @returns Updated query
1947
+ *
1948
+ * @example
1949
+ * ```typescript
1950
+ * builder.setGroup({
1951
+ * groupKey: 'priceRange',
1952
+ * groupType: 'and',
1953
+ * queries: [
1954
+ * { operator: 'gte', attribute: 'price', value: 100 },
1955
+ * { operator: 'lte', attribute: 'price', value: 200 }
1956
+ * ]
1957
+ * });
1958
+ * ```
1959
+ */
1960
+ setGroup(e) {
1961
+ return this.applyQuery(e, { mode: "set" });
1962
+ }
1963
+ /**
1964
+ * Merge a complete query into the current query.
1965
+ * Adds all conditions and groups from the provided query.
1966
+ *
1967
+ * @param query - Complete query to merge
1968
+ * @returns Updated query
1969
+ *
1970
+ * @example
1971
+ * ```typescript
1972
+ * builder.mergeQuery({
1973
+ * modelKey: 'Product',
1974
+ * groupType: 'and',
1975
+ * queries: [
1976
+ * { operator: 'eq', attribute: 'status', value: 'active' },
1977
+ * { operator: 'gte', attribute: 'price', value: 100 }
1978
+ * ]
1979
+ * });
1980
+ * ```
1981
+ */
1982
+ mergeQuery(e) {
1983
+ if (e.queries && Array.isArray(e.queries))
1984
+ for (const t of e.queries)
1985
+ this.applyQuery(t, { mode: "add" });
1986
+ return this.currentQuery;
1987
+ }
1988
+ /**
1989
+ * Replace the entire current query with a new query.
1990
+ * Completely replaces all conditions, groups, and options.
1991
+ *
1992
+ * @param query - Complete query to replace with
1993
+ * @returns Updated query
1994
+ *
1995
+ * @example
1996
+ * ```typescript
1997
+ * builder.replaceQuery({
1998
+ * modelKey: 'Product',
1999
+ * groupType: 'or',
2000
+ * queries: [
2001
+ * { operator: 'eq', attribute: 'featured', value: true },
2002
+ * { operator: 'gte', attribute: 'rating', value: 4.5 }
2003
+ * ]
2004
+ * });
2005
+ * ```
2006
+ */
2007
+ replaceQuery(e) {
2008
+ return this.currentQuery.queries = [], e.groupType && (this.currentQuery.groupType = e.groupType), e.queries && Array.isArray(e.queries) && (this.currentQuery.queries = e.queries), this.currentQuery;
2009
+ }
2010
+ // ============================================================================
2011
+ // State Management Clarity Methods
2012
+ // ============================================================================
2013
+ /**
2014
+ * Clear all query conditions and reset to initial state.
2015
+ * Alias for {@link reset} with clearer intent.
2016
+ *
2017
+ * @returns Empty query
2018
+ *
2019
+ * @example
2020
+ * ```typescript
2021
+ * builder.addCondition({ operator: 'eq', attribute: 'status', value: 'active' });
2022
+ * builder.clear(); // Removes all conditions
2023
+ * ```
2024
+ */
2025
+ clear() {
2026
+ return this.reset();
2027
+ }
2028
+ /**
2029
+ * Remove all query conditions but keep query structure.
2030
+ * Alias for {@link removeAllQueries} with clearer intent.
2031
+ *
2032
+ * @returns Query with no conditions
2033
+ *
2034
+ * @example
2035
+ * ```typescript
2036
+ * builder.clearConditions(); // Remove all conditions but keep modelKey, etc.
2037
+ * ```
2038
+ */
2039
+ clearConditions() {
2040
+ return this.removeAllQueries();
2041
+ }
2042
+ /**
2043
+ * Get an immutable copy of the current query state.
2044
+ * Alias for {@link getQuery} with clearer intent.
2045
+ *
2046
+ * @returns Deep clone of current query
2047
+ *
2048
+ * @example
2049
+ * ```typescript
2050
+ * const snapshot = builder.getCurrentQuery();
2051
+ * ```
2052
+ */
2053
+ getCurrentQuery() {
2054
+ return this.getQuery();
2055
+ }
2056
+ /**
2057
+ * Check if the query has any conditions.
2058
+ *
2059
+ * @returns true if query has no conditions, false otherwise
2060
+ *
2061
+ * @example
2062
+ * ```typescript
2063
+ * if (builder.isEmpty()) {
2064
+ * console.log('No filters applied');
2065
+ * }
2066
+ * ```
2067
+ */
2068
+ isEmpty() {
2069
+ return this.currentQuery.queries.length === 0;
2070
+ }
2071
+ /**
2072
+ * Check if a specific condition exists in the query.
2073
+ *
2074
+ * @param condition - Condition to check for (partial match)
2075
+ * @returns true if condition exists
2076
+ *
2077
+ * @example
2078
+ * ```typescript
2079
+ * const hasStatus = builder.hasCondition({ attribute: 'status', value: 'active' });
2080
+ * ```
2081
+ */
2082
+ hasCondition(e) {
2083
+ const t = (r) => {
2084
+ for (const s of r)
2085
+ if (this.isQuery(s)) {
2086
+ let i = !0;
2087
+ for (const n in e)
2088
+ if (s[n] !== e[n]) {
2089
+ i = !1;
2090
+ break;
2091
+ }
2092
+ if (i) return !0;
2093
+ } else if (this.isQueryGroup(s) && t(s.queries))
2094
+ return !0;
2095
+ return !1;
2096
+ };
2097
+ return t(this.currentQuery.queries);
2098
+ }
2099
+ /**
2100
+ * Check if a query group with the given key exists.
2101
+ * Alias for {@link hasQueryGroup} with consistent naming.
2102
+ *
2103
+ * @param groupKey - Group key to check
2104
+ * @returns true if group exists
2105
+ *
2106
+ * @example
2107
+ * ```typescript
2108
+ * if (builder.hasGroup('priceRange')) {
2109
+ * console.log('Price range filter is active');
2110
+ * }
2111
+ * ```
2112
+ */
2113
+ hasGroup(e) {
2114
+ return this.hasQueryGroup(e);
2115
+ }
2116
+ // ============================================================================
2117
+ // Query Inspection Methods
2118
+ // ============================================================================
2119
+ /**
2120
+ * Get all unique attribute names used in the query.
2121
+ * Convenience alias for {@link getAttributeNames}.
2122
+ *
2123
+ * @returns Array of attribute names
2124
+ *
2125
+ * @example
2126
+ * ```typescript
2127
+ * const attrs = builder.getUsedAttributes(); // ['status', 'price', 'customer.name']
2128
+ * ```
2129
+ */
2130
+ getUsedAttributes() {
2131
+ return this.getAttributeNames();
2132
+ }
2133
+ /**
2134
+ * Get only deep query attributes (e.g., 'customer.name', 'items[0].price').
2135
+ * Filters out simple attributes and returns only those with references.
2136
+ *
2137
+ * @returns Array of deep query attribute details
2138
+ *
2139
+ * @example
2140
+ * ```typescript
2141
+ * const deepAttrs = builder.getDeepQueryAttributes();
2142
+ * // [{ attribute: 'customer.name', isDeepQuery: true, reference: 'customer', referenceAttribute: 'name' }]
2143
+ * ```
2144
+ */
2145
+ getDeepQueryAttributes() {
2146
+ return this.getAttributeDetails().filter((t) => t.isDeepQuery);
2147
+ }
2148
+ /**
2149
+ * Get all query groups in the current query.
2150
+ *
2151
+ * @returns Array of query groups
2152
+ *
2153
+ * @example
2154
+ * ```typescript
2155
+ * const groups = builder.getGroups();
2156
+ * // [{ groupKey: 'priceRange', groupType: 'and', queries: [...] }]
2157
+ * ```
2158
+ */
2159
+ getGroups() {
2160
+ return this.currentQuery.queries.filter((e) => this.isQueryGroup(e));
2161
+ }
2162
+ /**
2163
+ * Get top-level conditions (queries not inside groups).
2164
+ *
2165
+ * @returns Array of top-level query conditions
2166
+ *
2167
+ * @example
2168
+ * ```typescript
2169
+ * const topLevel = builder.getTopLevelConditions();
2170
+ * ```
2171
+ */
2172
+ getTopLevelConditions() {
2173
+ return this.currentQuery.queries.filter((e) => this.isQuery(e));
2174
+ }
2175
+ /**
2176
+ * Get a specific query group by its key.
2177
+ * Alias for {@link getQueryGroup} with consistent naming.
2178
+ *
2179
+ * @param groupKey - Key of the group to retrieve
2180
+ * @returns Query group or undefined if not found
2181
+ *
2182
+ * @example
2183
+ * ```typescript
2184
+ * const group = builder.getGroup('priceRange');
2185
+ * if (group) {
2186
+ * console.log('Price range:', group.queries);
2187
+ * }
2188
+ * ```
2189
+ */
2190
+ getGroup(e) {
2191
+ return this.getQueryGroup(e);
2192
+ }
2193
+ /**
2194
+ * Count total number of conditions in the query (including nested).
2195
+ *
2196
+ * @returns Total count of query conditions
2197
+ *
2198
+ * @example
2199
+ * ```typescript
2200
+ * const count = builder.getConditionCount(); // 5
2201
+ * ```
2202
+ */
2203
+ getConditionCount() {
2204
+ const e = (t) => {
2205
+ let r = 0;
2206
+ for (const s of t)
2207
+ this.isQuery(s) ? r++ : this.isQueryGroup(s) && (r += e(s.queries));
2208
+ return r;
2209
+ };
2210
+ return e(this.currentQuery.queries);
2211
+ }
2212
+ }
2213
+ const S = new P();
2214
+ function Be(o, e, t, r, s, i, n) {
2215
+ const a = [], u = S.removeQuery({ groupKey: s }, y(r)), c = n.queryData(o, u, !1, i), f = e ? [...e.keys()] : [], d = new Set(f), l = i.get(s);
2216
+ if (!t.excludeUnresolved)
2217
+ for (const h of l.keys())
2218
+ d.add(h);
2219
+ t.excludeUndefineds ? d.delete(void 0) : d.add(void 0);
2220
+ for (const h of d.values()) {
2221
+ const A = /* @__PURE__ */ new Map(), _ = l.get(h) || /* @__PURE__ */ new Set();
2222
+ for (const N of _) {
2223
+ const k = c.get(N);
2224
+ if (k && (A.set(N, k), !t?.calculateFacets))
2225
+ break;
2226
+ }
2227
+ const M = {
2228
+ key: String(h),
2229
+ value: h,
2230
+ selected: ye(s, h, r),
2231
+ enabled: A.size > 0,
2232
+ size: A.size,
2233
+ entry: e.get(h),
2234
+ resultKeys: Array.from(A.keys())
2235
+ };
2236
+ if (!(t?.excludeZeros && M.size === 0)) {
2237
+ if (t?.count && a.length === t?.count)
2238
+ return a;
2239
+ a.push(M);
2240
+ }
2241
+ }
2242
+ return a;
2243
+ }
2244
+ const ye = (o, e, t) => {
2245
+ const r = t.queries.findIndex((s) => S.isQueryGroup(s) && s.groupKey === o);
2246
+ return r > -1 ? !!t.queries[r].queries.find((i) => {
2247
+ if (S.isQuery(i)) {
2248
+ const n = i.value?.key || i.value;
2249
+ return i.attribute === o && n === e;
2250
+ }
2251
+ return !1;
2252
+ }) : !1;
2253
+ };
2254
+ class me {
2255
+ indexMap = /* @__PURE__ */ new Map();
2256
+ // Possible performance gain*
2257
+ dataMap = /* @__PURE__ */ new Map();
2258
+ indexMetadata = /* @__PURE__ */ new Map();
2259
+ constructor() {
2260
+ }
2261
+ reset(e) {
2262
+ e ? (this.indexMap.delete(e), this.dataMap.delete(e), this.indexMetadata.delete(e)) : (this.indexMap.clear(), this.dataMap.clear(), this.indexMetadata.clear());
2263
+ }
2264
+ fillDataMap(e, t) {
2265
+ let r = this.dataMap.get(e);
2266
+ r || (r = /* @__PURE__ */ new Map(), this.dataMap.set(e, r));
2267
+ for (const s of t) {
2268
+ let i;
2269
+ if (typeof s == "object" && s && s.key)
2270
+ i = s.key;
2271
+ else if (Array.isArray(s)) {
2272
+ for (const a of s)
2273
+ this.fillDataMap(e, [a]);
2274
+ return;
2275
+ } else s instanceof Date ? i = s.toISOString() : i = s;
2276
+ let n = r.get(i);
2277
+ n || (n = { key: i }, this.dataMap.get(e)?.set(i, n));
2278
+ }
2279
+ }
2280
+ fillInverseIndex(e, t, r) {
2281
+ if (!e || !t || !r || !Array.isArray(r))
2282
+ return;
2283
+ const s = this.indexMap.get(e) || /* @__PURE__ */ new Map();
2284
+ for (const i of r) {
2285
+ let n;
2286
+ if (typeof i == "object" && i && i.key)
2287
+ n = i.key;
2288
+ else if (Array.isArray(i)) {
2289
+ for (const u of i)
2290
+ this.fillInverseIndex(e, t, [u]);
2291
+ return;
2292
+ } else i instanceof Date ? n = i.toISOString() : n = i;
2293
+ let a = s.get(n);
2294
+ a || (a = /* @__PURE__ */ new Set(), s.set(n, a)), a.add(t);
2295
+ }
2296
+ this.indexMap.set(e, s);
2297
+ }
2298
+ getIndex(e, t) {
2299
+ const r = this.getIndexName(e, t);
2300
+ return this.indexMap.get(r);
2301
+ }
2302
+ getData(e, t) {
2303
+ const r = this.getIndexName(e, t);
2304
+ return this.dataMap.get(r);
2305
+ }
2306
+ getOrCreateIndex(e, t, r) {
2307
+ const s = this.getIndexName(e, r);
2308
+ let i = this.getIndex(s);
2309
+ const n = this.indexMetadata.get(s);
2310
+ if (n)
2311
+ n.lastAccessedAt = Date.now();
2312
+ else if (!i) {
2313
+ const u = g.parse(e).isDeepQuery ?? !1;
2314
+ this.indexMetadata.set(s, {
2315
+ createdAt: Date.now(),
2316
+ lastAccessedAt: Date.now(),
2317
+ context: r,
2318
+ type: u ? "deep" : "shallow"
2319
+ });
2320
+ }
2321
+ if (!i) {
2322
+ this.reset(s), this.indexMap.set(s, /* @__PURE__ */ new Map());
2323
+ const u = g.parse(e).isDeepQuery;
2324
+ for (const c of t.values()) {
2325
+ const f = u ? v(c, e) : c[e];
2326
+ this.fillInverseIndex(s, c.key, [f]), this.fillDataMap(s, [f]);
2327
+ }
2328
+ i = this.getIndex(s) || /* @__PURE__ */ new Map();
2329
+ }
2330
+ return i;
2331
+ }
2332
+ getIndexName(e, t) {
2333
+ return t ? e + "_" + I(t) : e;
2334
+ }
2335
+ // ========== PARTIAL UPDATE METHODS ==========
2336
+ /**
2337
+ * Removes a specific item from an inverse index
2338
+ * @param attributeKey - The attribute key
2339
+ * @param itemKey - The item key to remove
2340
+ * @param oldValues - The old attribute values to remove from the index
2341
+ */
2342
+ removeFromInverseIndex(e, t, r) {
2343
+ const s = this.indexMap.get(e);
2344
+ if (s)
2345
+ for (const i of r) {
2346
+ let n;
2347
+ if (typeof i == "object" && i && i.key)
2348
+ n = i.key;
2349
+ else if (Array.isArray(i)) {
2350
+ for (const u of i)
2351
+ this.removeFromInverseIndex(e, t, [u]);
2352
+ return;
2353
+ } else i instanceof Date ? n = i.toISOString() : n = i;
2354
+ const a = s.get(n);
2355
+ a && (a.delete(t), a.size === 0 && s.delete(n));
2356
+ }
2357
+ }
2358
+ /**
2359
+ * Updates inverse index for a specific item by removing old values and adding new ones
2360
+ * @param attributeKey - The attribute key
2361
+ * @param itemKey - The item key being updated
2362
+ * @param oldValues - The old attribute values to remove
2363
+ * @param newValues - The new attribute values to add
2364
+ */
2365
+ updateInverseIndex(e, t, r, s) {
2366
+ this.removeFromInverseIndex(e, t, r), this.fillInverseIndex(e, t, s);
2367
+ }
2368
+ /**
2369
+ * Removes a specific item from the data map
2370
+ * @param attributeKey - The attribute key
2371
+ * @param values - The values to remove
2372
+ */
2373
+ removeFromDataMap(e, t) {
2374
+ const r = this.dataMap.get(e);
2375
+ if (r)
2376
+ for (const s of t) {
2377
+ let i;
2378
+ if (typeof s == "object" && s && s.key)
2379
+ i = s.key;
2380
+ else if (Array.isArray(s)) {
2381
+ for (const n of s)
2382
+ this.removeFromDataMap(e, [n]);
2383
+ return;
2384
+ } else s instanceof Date ? i = s.toISOString() : i = s;
2385
+ r.delete(i);
2386
+ }
2387
+ }
2388
+ /**
2389
+ * Updates data map for a specific item by removing old values and adding new ones
2390
+ * @param attributeKey - The attribute key
2391
+ * @param oldValues - The old values to remove
2392
+ * @param newValues - The new values to add
2393
+ */
2394
+ updateDataMap(e, t, r) {
2395
+ this.removeFromDataMap(e, t), this.fillDataMap(e, r);
2396
+ }
2397
+ /**
2398
+ * Completely removes an item from all indices
2399
+ * Used when an item is deleted
2400
+ * @param itemKey - The item key to remove
2401
+ */
2402
+ removeItemFromAllIndices(e) {
2403
+ for (const t of this.indexMap.values())
2404
+ for (const [r, s] of t)
2405
+ s.delete(e) && s.size === 0 && t.delete(r);
2406
+ for (const t of this.dataMap.values())
2407
+ t.has(e) && t.delete(e);
2408
+ }
2409
+ /**
2410
+ * Resets indices for specific attributes only
2411
+ * Useful for partial updates when only certain attributes changed
2412
+ * @param attributeKeys - Array of attribute keys to reset
2413
+ */
2414
+ resetAttributes(e) {
2415
+ for (const t of e)
2416
+ this.reset(t);
2417
+ }
2418
+ /**
2419
+ * Checks if an index key represents a deep query (contains dots in the attribute path)
2420
+ * Uses deep query service for accurate detection
2421
+ * @param indexKey - The index key to check
2422
+ * @returns true if the index is for a deep query attribute
2423
+ */
2424
+ isDeepQueryIndex(e) {
2425
+ const t = e.includes("_") ? e.split("_")[0] : e;
2426
+ try {
2427
+ return g.parse(t).isDeepQuery ?? !1;
2428
+ } catch {
2429
+ return !1;
2430
+ }
2431
+ }
2432
+ /**
2433
+ * Gets all deep query index keys currently in the index map
2434
+ * @returns Array of index keys that represent deep queries
2435
+ */
2436
+ getDeepIndexKeys() {
2437
+ const e = [];
2438
+ for (const t of this.indexMap.keys())
2439
+ this.isDeepQueryIndex(t) && e.push(t);
2440
+ return e;
2441
+ }
2442
+ /**
2443
+ * Resets all deep query indices (e.g., "customer.country", "order.customer.address.city")
2444
+ * This is critical for data updates as deep query indices need to be rebuilt
2445
+ * when underlying data changes.
2446
+ *
2447
+ * Shallow indices (direct attributes) are preserved as they're updated incrementally.
2448
+ */
2449
+ resetAllDeepIndices() {
2450
+ const e = this.getDeepIndexKeys();
2451
+ for (const t of e)
2452
+ this.indexMap.delete(t), this.dataMap.delete(t);
2453
+ }
2454
+ /**
2455
+ * Gets count of indices by type for monitoring and debugging
2456
+ * @returns Object with counts of shallow and deep indices
2457
+ */
2458
+ getIndexCount() {
2459
+ let e = 0, t = 0;
2460
+ for (const r of this.indexMap.keys())
2461
+ this.isDeepQueryIndex(r) ? t++ : e++;
2462
+ return {
2463
+ shallow: e,
2464
+ deep: t,
2465
+ total: e + t
2466
+ };
2467
+ }
2468
+ /**
2469
+ * Removes stale indices that haven't been accessed recently
2470
+ * This helps prevent memory buildup from indices with varying contexts
2471
+ * @param maxAge - Maximum age in milliseconds (default: 5 minutes)
2472
+ * @returns Number of indices cleaned up
2473
+ */
2474
+ cleanupStaleIndices(e = 300 * 1e3) {
2475
+ const t = Date.now();
2476
+ let r = 0;
2477
+ for (const [s, i] of this.indexMetadata)
2478
+ t - i.lastAccessedAt > e && (this.reset(s), r++);
2479
+ return r;
2480
+ }
2481
+ /**
2482
+ * Gets comprehensive statistics about indices for monitoring
2483
+ * @returns IndexStats object with counts and age information
2484
+ */
2485
+ getStats() {
2486
+ const e = this.getIndexCount(), t = Date.now();
2487
+ let r = 0, s = 0;
2488
+ for (const n of this.indexMetadata.values()) {
2489
+ const a = t - n.createdAt;
2490
+ r += a, a > s && (s = a);
2491
+ }
2492
+ const i = this.indexMetadata.size > 0 ? r / this.indexMetadata.size : 0;
2493
+ return {
2494
+ shallow: e.shallow,
2495
+ deep: e.deep,
2496
+ total: e.total,
2497
+ oldestAge: s,
2498
+ avgAge: i
2499
+ };
2500
+ }
2501
+ }
2502
+ const m = "__";
2503
+ function R(o, e, t = { key: "root" }, r = "root", s = new me(), i) {
2504
+ const n = i || o;
2505
+ for (const a of e.columns)
2506
+ a.attribute && (g.parse(a.attribute), s.getOrCreateIndex(a.attribute, n));
2507
+ for (const a of e.rows)
2508
+ a.attribute && (g.parse(a.attribute), s.getOrCreateIndex(a.attribute, n));
2509
+ for (const a of e.values)
2510
+ a.attribute && (g.parse(a.attribute), s.getOrCreateIndex(a.attribute, n));
2511
+ if (e.rows && e.rows.length > 0) {
2512
+ t.rows = t.rows || [];
2513
+ const a = ve(o, e.rows[0], e, s, r, i);
2514
+ t.rows.push(a);
2515
+ }
2516
+ if (e.columns && e.columns.length > 0) {
2517
+ t.columns = t.columns || [];
2518
+ const a = z(o, e.columns[0], e, s, r, i);
2519
+ t.columns.push(a);
2520
+ }
2521
+ if (t.key === "root")
2522
+ for (const a of e.values) {
2523
+ if (t.values = t.values || [], r === "root" && e.options?.calculateTotals === !1)
2524
+ continue;
2525
+ const u = Q(a, o, s.getIndex(a.attribute), a.attribute);
2526
+ t.values.push(u);
2527
+ }
2528
+ return t;
2529
+ }
2530
+ function ve(o, e, t, r, s = "", i) {
2531
+ const n = { key: e.attribute }, a = r.getIndex(e.attribute);
2532
+ if (!a)
2533
+ return n;
2534
+ for (const [u, c] of a.entries()) {
2535
+ const f = {
2536
+ key: u,
2537
+ value: u
2538
+ }, d = /* @__PURE__ */ new Map();
2539
+ for (const l of c)
2540
+ o.has(l) && d.set(l, o.get(l));
2541
+ if (d.size) {
2542
+ for (const l of t.values) {
2543
+ if (f.values = f.values || [], s === "root" && e?.calculateTotals === !1)
2544
+ continue;
2545
+ const h = Q(l, d, r.getIndex(l.attribute), l.attribute);
2546
+ f.values.push(h);
2547
+ }
2548
+ if (n.rows = n.rows || [], n.rows.push(f), t.rows.length > 1) {
2549
+ const l = { ...t, rows: t.rows.slice(1) };
2550
+ R(
2551
+ d,
2552
+ l,
2553
+ f,
2554
+ s + m + e.attribute + m + u,
2555
+ r,
2556
+ i
2557
+ );
2558
+ } else if (t.columns)
2559
+ for (const l of t.columns) {
2560
+ f.columns = f.columns || [];
2561
+ const h = z(
2562
+ d,
2563
+ l,
2564
+ t,
2565
+ r,
2566
+ s + m + e.attribute + m + u,
2567
+ i
2568
+ );
2569
+ f.columns.push(h);
2570
+ }
2571
+ }
2572
+ }
2573
+ return n;
2574
+ }
2575
+ function z(o, e, t, r, s = "", i) {
2576
+ const n = { key: e.attribute }, a = r.getIndex(e.attribute);
2577
+ if (!a)
2578
+ return n;
2579
+ for (const [u, c] of a.entries()) {
2580
+ const f = {
2581
+ key: u,
2582
+ value: u
2583
+ }, d = /* @__PURE__ */ new Map();
2584
+ for (const l of c)
2585
+ o.has(l) && d.set(l, o.get(l));
2586
+ if (d.size) {
2587
+ for (const l of t.values) {
2588
+ if (f.values = f.values || [], s === "root" && e?.calculateTotals === !1)
2589
+ continue;
2590
+ const h = Q(l, d, r.getIndex(l.attribute), l.attribute);
2591
+ f.values.push(h);
2592
+ }
2593
+ if (n.columns = n.columns || [], n.columns.push(f), t.columns.length > 1) {
2594
+ const l = { ...t, columns: t.columns.slice(1) };
2595
+ R(
2596
+ d,
2597
+ l,
2598
+ f,
2599
+ s + m + e.attribute + m + u,
2600
+ r,
2601
+ i
2602
+ );
2603
+ }
2604
+ }
2605
+ }
2606
+ return n;
2607
+ }
2608
+ const Te = (o, e) => {
2609
+ const t = [];
2610
+ for (const r of o) {
2611
+ for (const [s, i] of Object.entries(r)) {
2612
+ const n = t.find((u) => u.key === s), a = Ae(i);
2613
+ if (n)
2614
+ n.type !== a && (n.type = "any");
2615
+ else {
2616
+ const u = {
2617
+ key: s,
2618
+ type: a
2619
+ };
2620
+ t.push(u);
2621
+ }
2622
+ }
2623
+ if (!e)
2624
+ break;
2625
+ }
2626
+ return t;
2627
+ }, we = (o) => Number(o) === o && o % 1 === 0, xe = (o) => Number(o) === o && o % 1 !== 0, Ae = (o) => {
2628
+ switch (typeof o) {
2629
+ case "string":
2630
+ return "string";
2631
+ case "number":
2632
+ return we(o) ? "int" : xe(o) ? "float" : "any";
2633
+ case "boolean":
2634
+ return "boolean";
2635
+ case "object":
2636
+ return re(o) ? "date" : "json";
2637
+ default:
2638
+ return "any";
2639
+ }
2640
+ }, je = (o, e) => {
2641
+ const t = ee(o.text || ""), r = e?.attributeKey || o.filterKey;
2642
+ let s;
2643
+ const i = e?.comparisonType || "containsIgnoreCase";
2644
+ return i === "containsIgnoreCase" ? s = {
2645
+ groupKey: o.filterKey,
2646
+ queries: [
2647
+ {
2648
+ queryKey: o.text,
2649
+ attribute: r,
2650
+ value: `/${t}/`,
2651
+ operator: "find",
2652
+ options: {
2653
+ transform: ["lowercase"]
2654
+ }
2655
+ }
2656
+ ]
2657
+ } : i === "containsIgnoreCaseAndWhitespace" ? s = {
2658
+ groupKey: o.filterKey,
2659
+ queries: [
2660
+ {
2661
+ queryKey: o.text,
2662
+ attribute: r,
2663
+ value: `/${t}/`,
2664
+ operator: "find",
2665
+ options: {
2666
+ transform: ["removeWhitespace", "lowercase"]
2667
+ }
2668
+ }
2669
+ ]
2670
+ } : i === "contains" ? s = {
2671
+ groupKey: o.filterKey,
2672
+ queries: [
2673
+ {
2674
+ queryKey: o.text,
2675
+ attribute: r,
2676
+ value: `/${t}/`,
2677
+ operator: "find"
2678
+ }
2679
+ ]
2680
+ } : i === "equal" ? s = {
2681
+ groupKey: o.filterKey,
2682
+ queries: [
2683
+ {
2684
+ queryKey: o.text,
2685
+ attribute: r,
2686
+ value: o.text,
2687
+ operator: "eq"
2688
+ }
2689
+ ]
2690
+ } : i === "equalIgnoreCase" && (s = {
2691
+ groupKey: o.filterKey,
2692
+ queries: [
2693
+ {
2694
+ queryKey: o.text,
2695
+ attribute: r,
2696
+ value: o.text,
2697
+ operator: "eq",
2698
+ options: {
2699
+ transform: ["lowercase"]
2700
+ }
2701
+ }
2702
+ ]
2703
+ }), s;
2704
+ }, Pe = (o, e) => {
2705
+ const t = e?.attributeKey || o.filterKey;
2706
+ return {
2707
+ groupKey: o.filterKey,
2708
+ queries: [
2709
+ {
2710
+ queryKey: o.value,
2711
+ attribute: t,
2712
+ value: o.value,
2713
+ operator: "eq"
2714
+ }
2715
+ ]
2716
+ };
2717
+ }, Re = (o, e) => {
2718
+ const t = e?.attributeKey || o.filterKey, r = {
2719
+ groupKey: o.filterKey,
2720
+ queries: []
2721
+ };
2722
+ return typeof o.eq < "u" && (r.groupType = "or", Array.isArray(o.eq) ? o.eq.forEach((s) => {
2723
+ r.queries.push({ attribute: t, value: s, operator: "eq" });
2724
+ }) : r.queries.push({ attribute: t, value: o.eq, operator: "eq" })), typeof o.ne < "u" && (r.groupType = "and", Array.isArray(o.ne) ? o.ne.forEach((s) => {
2725
+ r.queries.push({ attribute: t, value: s, operator: "eq", options: { invert: !0 } });
2726
+ }) : r.queries.push({
2727
+ attribute: t,
2728
+ value: o.ne,
2729
+ operator: "eq",
2730
+ options: { invert: !0 }
2731
+ })), typeof o.gt < "u" && (r.groupType = "and", r.queries.push({ attribute: t, value: o.gt, operator: "gt" })), typeof o.lt < "u" && (r.groupType = "and", r.queries.push({ attribute: t, value: o.lt, operator: "lt" })), typeof o.gte < "u" && (r.groupType = "and", r.queries.push({ attribute: t, value: o.gte, operator: "gte" })), typeof o.lte < "u" && (r.groupType = "and", r.queries.push({ attribute: t, value: o.lte, operator: "lte" })), r;
2732
+ }, ze = (o, e) => {
2733
+ const t = e?.attributeKey || o.filterKey, r = {
2734
+ groupKey: o.filterKey,
2735
+ queries: []
2736
+ };
2737
+ return o.itemKeys.forEach((s) => {
2738
+ r.queries.push({
2739
+ queryKey: s,
2740
+ attribute: t,
2741
+ value: { key: s },
2742
+ operator: "eq"
2743
+ });
2744
+ }), r;
2745
+ }, _e = (o) => !(typeof o.modelKey != "string" || !Array.isArray(o.queries));
2746
+ class We {
2747
+ constructor(e, t, r) {
2748
+ this.scriptController = e, this.globalItemService = t, this.modelParser = r;
2749
+ }
2750
+ registeredCustomOperator = /* @__PURE__ */ new Map();
2751
+ queryBuilder = new P();
2752
+ registerCustomOperator(e, t) {
2753
+ this.registeredCustomOperator.set(e, t);
2754
+ }
2755
+ transformValue(e, t) {
2756
+ if (Array.isArray(e))
2757
+ return e.map((r) => this.transformValue(r, t));
2758
+ if (typeof e != "string")
2759
+ return e;
2760
+ for (const r of t)
2761
+ r === "lowercase" ? e = e.toLowerCase() : r === "trim" ? e = e.trim() : r === "removeWhitespace" && (e = e.replace(/\s/g, ""));
2762
+ return e;
2763
+ }
2764
+ evaluateQuery(e, t) {
2765
+ let r, s = e.value;
2766
+ const i = e.options?.arrayValueHandling || "some";
2767
+ if (Array.isArray(e.options?.transform) && e.options.transform.length > 0 && (s = this.transformValue(s, e.options.transform)), e.attribute.includes(".") || e.attribute.includes("[") ? r = v(t, e.attribute) : r = t[e.attribute], Array.isArray(e.options?.transform) && e.options.transform.length > 0 && (r = this.transformValue(r, e.options.transform)), (typeof r > "u" || r === null) && !["typeof", "isTruthy", "eq"].includes(e.operator))
2768
+ return !1;
2769
+ switch (e.operator) {
2770
+ case "eq":
2771
+ return e.options?.invert ? !E(r, s) : E(r, s);
2772
+ case "find":
2773
+ return e.options?.invert ? !this.queryFind(r, s, i) : this.queryFind(r, s, i);
2774
+ case "lt":
2775
+ return Array.isArray(r) ? i === "some" ? r.some((n) => n < s) : r.every((n) => n < s) : r < s;
2776
+ case "gt":
2777
+ return Array.isArray(r) ? i === "some" ? r.some((n) => n > s) : r.every((n) => n > s) : r > s;
2778
+ case "lte":
2779
+ return Array.isArray(r) ? i === "some" ? r.some((n) => n <= s) : r.every((n) => n <= s) : r <= s;
2780
+ case "gte":
2781
+ return Array.isArray(r) ? i === "some" ? r.some((n) => n >= s) : r.every((n) => n >= s) : r >= s;
2782
+ case "typeof":
2783
+ return e.options?.invert ? typeof r !== s : Array.isArray(r) ? i === "some" ? r.some((n) => typeof n === s) : r.every((n) => typeof n === s) : typeof r === s;
2784
+ case "isTruthy":
2785
+ return s === !0 ? Array.isArray(r) ? i === "some" ? r.some((n) => typeof !!n) : r.every((n) => typeof !!n) : !!r : !r;
2786
+ case "size":
2787
+ return typeof r == "string" ? r.length === s : W(r) === s;
2788
+ default:
2789
+ if (this.scriptController.hasScript(e.operator))
2790
+ return this.scriptController.executeScript(e.operator, "operator", { query: e, item: t });
2791
+ if (this.registeredCustomOperator.has(e.operator)) {
2792
+ const n = this.registeredCustomOperator.get(e.operator);
2793
+ if (typeof n == "function")
2794
+ return n(e, t);
2795
+ }
2796
+ }
2797
+ return !1;
2798
+ }
2799
+ evaluateEqOperator(e, t, r, s) {
2800
+ const i = /* @__PURE__ */ new Map(), n = s.get(t.attribute);
2801
+ if (n) {
2802
+ let a;
2803
+ if (typeof t.value == "string" ? a = t.value : t.value?.key && Object.keys(t.value).length === 1 && (a = t.value.key), typeof a < "u") {
2804
+ const u = n.get(a);
2805
+ if (u)
2806
+ if (u.forEach((c) => {
2807
+ r.has(c) && i.set(c, r.get(c));
2808
+ }), t.options?.invert) {
2809
+ const c = q(Array.from(r.values()), Array.from(i.values()), "key"), f = /* @__PURE__ */ new Map();
2810
+ return c.forEach((d) => {
2811
+ f.set(d.key, d);
2812
+ }), f;
2813
+ } else
2814
+ return i;
2815
+ }
2816
+ }
2817
+ for (let [a, u] of r) {
2818
+ const c = this.queryBuilder.extractQueryAttributes({ queries: [t] });
2819
+ if (c.some((f) => f.isDeepQuery)) {
2820
+ const f = this.queryBuilder.getProjectionForAttributeEntries(
2821
+ c.filter((d) => d.isDeepQuery)
2822
+ );
2823
+ u = this.globalItemService.getProjectedData(
2824
+ f,
2825
+ this.modelParser.models.get(e.modelKey),
2826
+ u
2827
+ );
2828
+ }
2829
+ this.evaluateQuery(t, u) && i.set(a, u);
2830
+ }
2831
+ return i;
2832
+ }
2833
+ equalRegexFn(e, t) {
2834
+ if (typeof t == "string" && L(t, "/") && H(t, "/"))
2835
+ try {
2836
+ return new RegExp(t.slice(1, -1)).test(e);
2837
+ } catch {
2838
+ return !1;
2839
+ }
2840
+ else return Array.isArray(e) ? !!e.find((r) => b(r, t, this.equalRegexFn)) : typeof t == "object" ? U(e, t) : e === t;
2841
+ }
2842
+ queryFind(e, t, r) {
2843
+ return Array.isArray(e) ? typeof t == "string" || typeof t == "number" || typeof t == "boolean" ? r === "some" ? e.some((s) => b(s, t, this.equalRegexFn)) : e.every((s) => b(s, t, this.equalRegexFn)) : !!V(e, t) : b(e, t, this.equalRegexFn);
2844
+ }
2845
+ validateQuery(e) {
2846
+ if (this.queryBuilder.isQuery(e)) {
2847
+ if (!e.attribute || !e.operator)
2848
+ throw new Error("invalid query - missing attribute or operator");
2849
+ if (e.operator === "find" && Array.isArray(e.value))
2850
+ throw new Error("invalid query - find operator cannot have array value");
2851
+ return !0;
2852
+ } else {
2853
+ if (this.queryBuilder.isQueryGroup(e))
2854
+ return B(e.queries, (t) => this.validateQuery(t));
2855
+ throw new Error("invalid query - missing query or attribute");
2856
+ }
2857
+ }
2858
+ getEvaluatedQueryDataset(e, t, r, s) {
2859
+ const i = /* @__PURE__ */ new Map();
2860
+ if (t.attribute.includes("[*]"))
2861
+ for (let n of r.values()) {
2862
+ const a = this.queryBuilder.extractQueryAttributes({ queries: [t] });
2863
+ if (a.some((c) => c.isDeepQuery)) {
2864
+ const c = this.queryBuilder.getProjectionForAttributeEntries(
2865
+ a.filter((f) => f.isDeepQuery)
2866
+ );
2867
+ n = this.globalItemService.getProjectedData(
2868
+ c,
2869
+ this.modelParser.models.get(e.modelKey),
2870
+ n
2871
+ );
2872
+ }
2873
+ const u = this.handleArrayStarQuery(t, n);
2874
+ for (const c of u.queries)
2875
+ this.evaluateQuery(c, n) && i.set(n.key, n);
2876
+ }
2877
+ else {
2878
+ if (t.operator === "eq")
2879
+ return this.evaluateEqOperator(e, t, r, s);
2880
+ for (let [n, a] of r) {
2881
+ const u = this.queryBuilder.extractQueryAttributes({ queries: [t] });
2882
+ if (u.some((c) => c.isDeepQuery)) {
2883
+ const c = this.queryBuilder.getProjectionForAttributeEntries(
2884
+ u.filter((f) => f.isDeepQuery)
2885
+ );
2886
+ a = this.globalItemService.getProjectedData(
2887
+ c,
2888
+ this.modelParser.models.get(e.modelKey),
2889
+ a
2890
+ );
2891
+ }
2892
+ this.evaluateQuery(t, a) && i.set(n, a);
2893
+ }
2894
+ }
2895
+ return i;
2896
+ }
2897
+ handleArrayStarQuery(e, t) {
2898
+ const r = e.attribute.indexOf("[*]"), s = {
2899
+ groupKey: e.queryKey || e.attribute + "[*]",
2900
+ groupType: "or",
2901
+ queries: []
2902
+ };
2903
+ if (r !== -1) {
2904
+ const i = e.attribute.substring(0, r), n = t[i];
2905
+ if (Array.isArray(n))
2906
+ for (let a = 0; a < n.length; a++) {
2907
+ const u = e.attribute.replace("[*]", `[${a}]`);
2908
+ s.queries.push({
2909
+ attribute: u,
2910
+ operator: e.operator,
2911
+ value: e.value
2912
+ });
2913
+ }
2914
+ }
2915
+ return s;
2916
+ }
2917
+ evaluateQueryGroup(e, t, r, s, i) {
2918
+ let n = /* @__PURE__ */ new Map(), a = r;
2919
+ if (!t.queries || t.queries?.length === 0)
2920
+ return a;
2921
+ for (const u of t.queries) {
2922
+ let c = /* @__PURE__ */ new Map();
2923
+ if (this.queryBuilder.isQuery(u) ? c = this.getEvaluatedQueryDataset(e, u, a, i) : c = this.evaluateQueryGroup(e, u, a, s, i), n.size === 0 && (n = c), t.groupType === "or")
2924
+ c.forEach((f) => {
2925
+ n.set(f.key, f);
2926
+ });
2927
+ else {
2928
+ const f = q(Array.from(n.values()), Array.from(c.values()), "key");
2929
+ for (const d of f)
2930
+ n.delete(d.key);
2931
+ }
2932
+ t.groupType === "and" ? a = n : a = r;
2933
+ }
2934
+ return n;
2935
+ }
2936
+ queryData(e, t, r, s) {
2937
+ const i = new Map(e);
2938
+ return t.queries.length === 0 ? e : (t.groupKey || (t.groupKey = "root"), t.groupType || (t.groupType = "and"), t.queries || (t.queries = []), this.validateQuery(t), this.evaluateQueryGroup(t, t, i, r, s));
2939
+ }
2940
+ // public getRelevantQueryData(data: any, options: DcuplGlobalQueryOptions<any>, model: DcuplModel<ListItem>) {
2941
+ // // detect if any of the query attributes are a deep query.
2942
+ // // a deep query is a query that references another models property.
2943
+ // // if so we need to make a getItems call with the projected data.
2944
+ // const attributes = this.queryBuilder.getQueryAttributes(options);
2945
+ // const deepQueries = attributes.filter((attr) => {
2946
+ // return attr.includes('.') || attr.includes('[');
2947
+ // });
2948
+ // if (deepQueries.length > 0) {
2949
+ // const projection: Projection<any> = {
2950
+ // $: true,
2951
+ // };
2952
+ // for (const deepQuery of deepQueries) {
2953
+ // // split the deep query into modelKey and attribute
2954
+ // // e.g. modelA.someAttribute or modelB[0].someAttribute or modelB[*].someAttribute
2955
+ // // the result should the modelKey: modelA and attribute: someAttribute
2956
+ // // const [modelKey, attribute] = deepQuery.split(new RegExp(/\.|\[|\]/)).filter(Boolean);
2957
+ // const parts = deepQuery.split(new RegExp(/\.|\[|\]/)).filter(Boolean);
2958
+ // const modelKey = parts[0];
2959
+ // if (modelKey) {
2960
+ // (projection as any)[modelKey] = {
2961
+ // $: true,
2962
+ // };
2963
+ // }
2964
+ // }
2965
+ // const relevantData = this.globalItemService.getItemsAsMap(data, model, {
2966
+ // projection,
2967
+ // } as DcuplItemsOptions<ListItem>);
2968
+ // return relevantData;
2969
+ // } else {
2970
+ // return data;
2971
+ // }
2972
+ // }
2973
+ }
2974
+ class Le {
2975
+ scripts = /* @__PURE__ */ new Map();
2976
+ scriptFunctions = /* @__PURE__ */ new Map();
2977
+ constructor() {
2978
+ }
2979
+ keys() {
2980
+ return Array.from(this.scripts.keys());
2981
+ }
2982
+ setScript(e, t) {
2983
+ this.scripts.set(e, t);
2984
+ }
2985
+ removeScript(e) {
2986
+ this.scripts.delete(e);
2987
+ }
2988
+ getScript(e) {
2989
+ return this.scripts.get(e);
2990
+ }
2991
+ hasScript(e) {
2992
+ return this.scripts.has(e);
2993
+ }
2994
+ getScriptAsFn(e, t) {
2995
+ if (this.scriptFunctions.has(e))
2996
+ return this.scriptFunctions.get(e);
2997
+ const r = this.getScript(e);
2998
+ if (!r)
2999
+ throw new Error(`Script ${e} not found`);
3000
+ const s = this.getWrapperScript(r), i = new Function("script_type", ...t, s);
3001
+ return this.scriptFunctions.set(e, i), i;
3002
+ }
3003
+ getWrapperScript(e) {
3004
+ return `
3005
+ "use strict";
3006
+ ${e}
3007
+ `;
3008
+ }
3009
+ executeScript(e, t, r) {
3010
+ if (!this.getScript(e))
3011
+ throw new Error(`Script ${e} not found`);
3012
+ r.context || (r.context = r.options || {});
3013
+ const i = Object.keys(r), n = Object.values(r);
3014
+ return this.getScriptAsFn(e, i)(t, ...n);
3015
+ }
3016
+ }
3017
+ const He = (o, e) => o ? (e || (e = {}), o.replace(/\$\{(.*?)\}/g, (t, r) => v(e, r.trim(), ""))) : "", Ue = (o) => {
3018
+ const e = /* @__PURE__ */ new Set();
3019
+ return o.replace(/\$\{(.*?)\}/g, (r, s) => (e.add(s.trim()), "")), { variables: Array.from(e).map((r) => ({ name: r })) };
3020
+ }, Ve = [
3021
+ "any",
3022
+ "Array<date>",
3023
+ "Array<float>",
3024
+ "Array<int>",
3025
+ "Array<string>",
3026
+ "boolean",
3027
+ "date",
3028
+ "float",
3029
+ "int",
3030
+ "json",
3031
+ "string"
3032
+ ], Je = ["int", "float", "Array<int>", "Array<float>"], Ze = ["date", "Array<date>"], Ye = [
3033
+ "eq",
3034
+ "find",
3035
+ "gt",
3036
+ "gte",
3037
+ "lt",
3038
+ "lte",
3039
+ "typeof",
3040
+ "isTruthy",
3041
+ "size"
3042
+ ];
3043
+ export {
3044
+ De as AnalyticsController,
3045
+ Ke as AttributeDependencyGraph,
3046
+ Se as CacheController,
3047
+ Oe as ChangeDetector,
3048
+ Ze as DatePropertyTypes,
3049
+ P as DcuplQueryBuilder,
3050
+ Ye as DcuplQueryOperatorsAsArray,
3051
+ fe as DeepQueryService,
3052
+ Z as DependencyGraph,
3053
+ me as IndicesController,
3054
+ p as Logger,
3055
+ Je as NumberPropertyTypes,
3056
+ Ve as PropertyTypesAsArray,
3057
+ We as QueryManager,
3058
+ Le as ScriptController,
3059
+ j as clone,
3060
+ te as compareVersions,
3061
+ Fe as computeSuggestions,
3062
+ g as deepQueryService,
3063
+ ee as escapeRegExp,
3064
+ He as evaluateTemplate,
3065
+ Pe as generateBooleanQuery,
3066
+ X as generateKey,
3067
+ Re as generateNumberAndDateQuery,
3068
+ ze as generateReferenceQuery,
3069
+ je as generateTextQuery,
3070
+ Q as getAggregation,
3071
+ Me as getDateConstraintUid,
3072
+ Ae as getDcuplPropertyTypeForNativeType,
3073
+ ge as getDistinct,
3074
+ Be as getFacets,
3075
+ Ie as getFilterEntryId,
3076
+ Qe as getNumberConstraintUid,
3077
+ Te as getPropertiesForData,
3078
+ ke as groupBy,
3079
+ qe as hasMinimumVersion,
3080
+ re as isDateInstance,
3081
+ xe as isFloat,
3082
+ we as isInt,
3083
+ se as isValidDate,
3084
+ _e as isValidQueryStatement,
3085
+ $ as isValidVersion,
3086
+ Y as logger,
3087
+ Ge as parseDate,
3088
+ Ue as parseTemplate,
3089
+ x as perf,
3090
+ R as pivot,
3091
+ Ce as removeTrailingSlash,
3092
+ $e as trigger,
3093
+ Ee as unescapeRegExp,
3094
+ Ne as uniqBy
3095
+ };
3096
+ //# sourceMappingURL=index.js.map