@spine-event-engine/storage 2.0.0-snapshot.2

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 (133) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +160 -0
  3. package/REFERENCE.md +120 -0
  4. package/dist/entity/entity-history-record-spec.d.ts +26 -0
  5. package/dist/entity/entity-history-record-spec.d.ts.map +1 -0
  6. package/dist/entity/entity-history-record-spec.js +77 -0
  7. package/dist/entity/entity-history-record-spec.js.map +1 -0
  8. package/dist/entity/entity-history-storage.d.ts +111 -0
  9. package/dist/entity/entity-history-storage.d.ts.map +1 -0
  10. package/dist/entity/entity-history-storage.js +40 -0
  11. package/dist/entity/entity-history-storage.js.map +1 -0
  12. package/dist/entity/entity-record.d.ts +31 -0
  13. package/dist/entity/entity-record.d.ts.map +1 -0
  14. package/dist/entity/entity-record.js +15 -0
  15. package/dist/entity/entity-record.js.map +1 -0
  16. package/dist/entity/history-conformance.d.ts +55 -0
  17. package/dist/entity/history-conformance.d.ts.map +1 -0
  18. package/dist/entity/history-conformance.js +165 -0
  19. package/dist/entity/history-conformance.js.map +1 -0
  20. package/dist/event/event-store.d.ts +141 -0
  21. package/dist/event/event-store.d.ts.map +1 -0
  22. package/dist/event/event-store.js +407 -0
  23. package/dist/event/event-store.js.map +1 -0
  24. package/dist/index.d.ts +23 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +30 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/internal/delivery-cleanup.d.ts +99 -0
  29. package/dist/internal/delivery-cleanup.d.ts.map +1 -0
  30. package/dist/internal/delivery-cleanup.js +38 -0
  31. package/dist/internal/delivery-cleanup.js.map +1 -0
  32. package/dist/internal/entity-commit.d.ts +108 -0
  33. package/dist/internal/entity-commit.d.ts.map +1 -0
  34. package/dist/internal/entity-commit.js +32 -0
  35. package/dist/internal/entity-commit.js.map +1 -0
  36. package/dist/internal/entity-history.d.ts +12 -0
  37. package/dist/internal/entity-history.d.ts.map +1 -0
  38. package/dist/internal/entity-history.js +17 -0
  39. package/dist/internal/entity-history.js.map +1 -0
  40. package/dist/internal/event-store.d.ts +8 -0
  41. package/dist/internal/event-store.d.ts.map +1 -0
  42. package/dist/internal/event-store.js +21 -0
  43. package/dist/internal/event-store.js.map +1 -0
  44. package/dist/internal/query-values.d.ts +5 -0
  45. package/dist/internal/query-values.d.ts.map +1 -0
  46. package/dist/internal/query-values.js +18 -0
  47. package/dist/internal/query-values.js.map +1 -0
  48. package/dist/internal/tenancy.d.ts +89 -0
  49. package/dist/internal/tenancy.d.ts.map +1 -0
  50. package/dist/internal/tenancy.js +97 -0
  51. package/dist/internal/tenancy.js.map +1 -0
  52. package/dist/memory/canonical-utf8.d.ts +21 -0
  53. package/dist/memory/canonical-utf8.d.ts.map +1 -0
  54. package/dist/memory/canonical-utf8.js +65 -0
  55. package/dist/memory/canonical-utf8.js.map +1 -0
  56. package/dist/memory/in-memory-entity-commit.d.ts +35 -0
  57. package/dist/memory/in-memory-entity-commit.d.ts.map +1 -0
  58. package/dist/memory/in-memory-entity-commit.js +183 -0
  59. package/dist/memory/in-memory-entity-commit.js.map +1 -0
  60. package/dist/memory/in-memory-entity-history.d.ts +379 -0
  61. package/dist/memory/in-memory-entity-history.d.ts.map +1 -0
  62. package/dist/memory/in-memory-entity-history.js +756 -0
  63. package/dist/memory/in-memory-entity-history.js.map +1 -0
  64. package/dist/memory/in-memory-record-storage.d.ts +78 -0
  65. package/dist/memory/in-memory-record-storage.d.ts.map +1 -0
  66. package/dist/memory/in-memory-record-storage.js +127 -0
  67. package/dist/memory/in-memory-record-storage.js.map +1 -0
  68. package/dist/memory/in-memory-storage-backend.d.ts +38 -0
  69. package/dist/memory/in-memory-storage-backend.d.ts.map +1 -0
  70. package/dist/memory/in-memory-storage-backend.js +108 -0
  71. package/dist/memory/in-memory-storage-backend.js.map +1 -0
  72. package/dist/memory/in-memory-storage-factory.d.ts +58 -0
  73. package/dist/memory/in-memory-storage-factory.d.ts.map +1 -0
  74. package/dist/memory/in-memory-storage-factory.js +148 -0
  75. package/dist/memory/in-memory-storage-factory.js.map +1 -0
  76. package/dist/memory/memory-delivery-cleanup.d.ts +32 -0
  77. package/dist/memory/memory-delivery-cleanup.d.ts.map +1 -0
  78. package/dist/memory/memory-delivery-cleanup.js +61 -0
  79. package/dist/memory/memory-delivery-cleanup.js.map +1 -0
  80. package/dist/memory/tenant-records.d.ts +66 -0
  81. package/dist/memory/tenant-records.d.ts.map +1 -0
  82. package/dist/memory/tenant-records.js +573 -0
  83. package/dist/memory/tenant-records.js.map +1 -0
  84. package/dist/query/query-execution.d.ts +50 -0
  85. package/dist/query/query-execution.d.ts.map +1 -0
  86. package/dist/query/query-execution.js +222 -0
  87. package/dist/query/query-execution.js.map +1 -0
  88. package/dist/query/query-policy.d.ts +115 -0
  89. package/dist/query/query-policy.d.ts.map +1 -0
  90. package/dist/query/query-policy.js +294 -0
  91. package/dist/query/query-policy.js.map +1 -0
  92. package/dist/record/column-mapping.d.ts +41 -0
  93. package/dist/record/column-mapping.d.ts.map +1 -0
  94. package/dist/record/column-mapping.js +36 -0
  95. package/dist/record/column-mapping.js.map +1 -0
  96. package/dist/record/column-type.d.ts +75 -0
  97. package/dist/record/column-type.d.ts.map +1 -0
  98. package/dist/record/column-type.js +69 -0
  99. package/dist/record/column-type.js.map +1 -0
  100. package/dist/record/record-column.d.ts +23 -0
  101. package/dist/record/record-column.d.ts.map +1 -0
  102. package/dist/record/record-column.js +41 -0
  103. package/dist/record/record-column.js.map +1 -0
  104. package/dist/record/record-mask.d.ts +11 -0
  105. package/dist/record/record-mask.d.ts.map +1 -0
  106. package/dist/record/record-mask.js +82 -0
  107. package/dist/record/record-mask.js.map +1 -0
  108. package/dist/record/record-query.d.ts +102 -0
  109. package/dist/record/record-query.d.ts.map +1 -0
  110. package/dist/record/record-query.js +44 -0
  111. package/dist/record/record-query.js.map +1 -0
  112. package/dist/record/record-spec.d.ts +101 -0
  113. package/dist/record/record-spec.d.ts.map +1 -0
  114. package/dist/record/record-spec.js +159 -0
  115. package/dist/record/record-spec.js.map +1 -0
  116. package/dist/record/record-storage.d.ts +202 -0
  117. package/dist/record/record-storage.d.ts.map +1 -0
  118. package/dist/record/record-storage.js +234 -0
  119. package/dist/record/record-storage.js.map +1 -0
  120. package/dist/record/storage-group.d.ts +17 -0
  121. package/dist/record/storage-group.d.ts.map +1 -0
  122. package/dist/record/storage-group.js +37 -0
  123. package/dist/record/storage-group.js.map +1 -0
  124. package/dist/storage/storage-factory.d.ts +44 -0
  125. package/dist/storage/storage-factory.d.ts.map +1 -0
  126. package/dist/storage/storage-factory.js +54 -0
  127. package/dist/storage/storage-factory.js.map +1 -0
  128. package/dist/storage/storage.d.ts +62 -0
  129. package/dist/storage/storage.d.ts.map +1 -0
  130. package/dist/storage/storage.js +15 -0
  131. package/dist/storage/storage.js.map +1 -0
  132. package/dist/tsconfig.tsbuildinfo +1 -0
  133. package/package.json +56 -0
@@ -0,0 +1,222 @@
1
+ /*
2
+ * Copyright 2026, CodeMatters. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
+ * in compliance with the License. You may obtain a copy of the License at
6
+ *
7
+ * https://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
10
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ * or implied. See the License for the specific language governing permissions and limitations under
12
+ * the License.
13
+ */
14
+ /**
15
+ * Finite default number of provider candidates a normalized plan may materialize.
16
+ */
17
+ export const defaultQueryCandidateLimit = 10_000;
18
+ /**
19
+ * Raised before evaluating a plan that exceeded its finite candidate budget.
20
+ */
21
+ export class QueryCandidateLimitError extends Error {
22
+ candidateLimit;
23
+ // prettier-ignore
24
+ /**
25
+ * Creates a candidate-limit error.
26
+ *
27
+ * @param candidateLimit Specifies the exceeded candidate budget.
28
+ */
29
+ constructor(candidateLimit) {
30
+ super(`Storage query exceeded the candidate limit of ${String(candidateLimit)}.`);
31
+ this.candidateLimit = candidateLimit;
32
+ this.name = "QueryCandidateLimitError";
33
+ }
34
+ }
35
+ /**
36
+ * Shared complete in-process semantics for one validated normalized query plan.
37
+ */
38
+ export const StorageQueryEvaluator = Object.freeze({
39
+ evaluate(entries, plan) {
40
+ const predicate = plan.predicate;
41
+ const matching = predicate === undefined
42
+ ? [...entries]
43
+ : entries.filter((entry) => QueryPredicateMatcher.matches(entry, predicate));
44
+ const ordered = matching.sort((left, right) => QueryOrdering.compareEntries(left, right, plan));
45
+ return plan.limit === undefined ? ordered : ordered.slice(0, plan.limit);
46
+ },
47
+ });
48
+ /**
49
+ * Shared deterministic value semantics for provider-side query adapters.
50
+ *
51
+ * @internal
52
+ */
53
+ export const StorageQueryValues = Object.freeze({
54
+ equal(left, right) {
55
+ return QueryPredicateMatcher.equalValues(left, right);
56
+ },
57
+ compare(left, right) {
58
+ return QueryOrdering.compareStable(left, right);
59
+ },
60
+ });
61
+ /**
62
+ * Matches normalized predicates against materialized storage rows.
63
+ */
64
+ const QueryPredicateMatcher = {
65
+ // prettier-ignore
66
+ /**
67
+ * Matches a row against one normalized predicate.
68
+ */
69
+ matches(entry, predicate) {
70
+ switch (predicate.kind) {
71
+ case "ids":
72
+ return predicate.ids.some((id) => QueryPredicateMatcher.equalValues(id, entry.id));
73
+ case "comparison":
74
+ return QueryPredicateMatcher.comparePredicate(entry.columns.get(predicate.column), predicate.operator, predicate.value);
75
+ case "all":
76
+ return predicate.predicates.every((child) => QueryPredicateMatcher.matches(entry, child));
77
+ case "either":
78
+ return predicate.predicates.some((child) => QueryPredicateMatcher.matches(entry, child));
79
+ }
80
+ },
81
+ /**
82
+ * Evaluates one normalized comparison predicate.
83
+ */
84
+ comparePredicate(actual, operator, expected) {
85
+ if (operator === "equal")
86
+ return QueryPredicateMatcher.equalValues(actual, expected);
87
+ if (QueryOrdering.isMissing(actual) || QueryOrdering.isMissing(expected))
88
+ return false;
89
+ const result = QueryOrdering.compareOrdered(actual, expected);
90
+ if (operator === "greaterThan")
91
+ return result > 0;
92
+ if (operator === "lessThan")
93
+ return result < 0;
94
+ if (operator === "greaterOrEqual")
95
+ return result >= 0;
96
+ return result <= 0;
97
+ },
98
+ /**
99
+ * Compares values using normalized query equality semantics.
100
+ */
101
+ equalValues(left, right) {
102
+ if (QueryOrdering.isMissing(left) || QueryOrdering.isMissing(right)) {
103
+ return QueryOrdering.isMissing(left) && QueryOrdering.isMissing(right);
104
+ }
105
+ return QueryOrdering.stableKey(left) === QueryOrdering.stableKey(right);
106
+ },
107
+ };
108
+ /**
109
+ * Orders normalized query values and materialized rows deterministically.
110
+ */
111
+ const QueryOrdering = {
112
+ // prettier-ignore
113
+ /**
114
+ * Compares two rows by requested ordering and stable ID tie-breaker.
115
+ */
116
+ compareEntries(left, right, plan) {
117
+ for (const order of plan.order ?? []) {
118
+ const comparison = QueryOrdering.compareWithMissing(left.columns.get(order.column), right.columns.get(order.column));
119
+ if (comparison !== 0)
120
+ return order.direction === "desc" ? comparison * -1 : comparison;
121
+ }
122
+ return QueryOrdering.compareStable(left.id, right.id);
123
+ },
124
+ /**
125
+ * Compares values while placing missing values before present values.
126
+ */
127
+ compareWithMissing(left, right) {
128
+ if (QueryOrdering.isMissing(left) || QueryOrdering.isMissing(right)) {
129
+ if (QueryOrdering.isMissing(left) && QueryOrdering.isMissing(right))
130
+ return 0;
131
+ return QueryOrdering.isMissing(left) ? -1 : 1;
132
+ }
133
+ return QueryOrdering.compareOrdered(left, right);
134
+ },
135
+ /**
136
+ * Compares values supported by normalized query ordering.
137
+ */
138
+ compareOrdered(left, right) {
139
+ if (typeof left === "number" && typeof right === "number")
140
+ return QueryOrdering.compareNumber(left, right);
141
+ if (typeof left === "bigint" && typeof right === "bigint") {
142
+ return left < right ? -1 : left > right ? 1 : 0;
143
+ }
144
+ if (typeof left === "string" && typeof right === "string")
145
+ return QueryOrdering.compareText(left, right);
146
+ if (QueryOrdering.isOrderedMessage(left) &&
147
+ QueryOrdering.isOrderedMessage(right) &&
148
+ left.$typeName === right.$typeName) {
149
+ if (left.$typeName === "google.protobuf.Timestamp") {
150
+ return QueryOrdering.comparePair(left.seconds, left.nanos, right.seconds, right.nanos);
151
+ }
152
+ return QueryOrdering.comparePair(left.number, left.timestamp, right.number, right.timestamp);
153
+ }
154
+ throw new TypeError("Normalized query ordering value has an unsupported type.");
155
+ },
156
+ /**
157
+ * Compares ordered-message major and minor components.
158
+ */
159
+ comparePair(leftMajor, leftMinor, rightMajor, rightMinor) {
160
+ const major = QueryOrdering.compareStable(leftMajor, rightMajor);
161
+ return major === 0 ? QueryOrdering.compareStable(leftMinor, rightMinor) : major;
162
+ },
163
+ /**
164
+ * Compares values with a deterministic fallback for distinct shapes.
165
+ */
166
+ compareStable(left, right) {
167
+ if (QueryOrdering.isMissing(left) || QueryOrdering.isMissing(right))
168
+ return QueryOrdering.compareWithMissing(left, right);
169
+ if (typeof left === typeof right && ["number", "bigint", "string"].includes(typeof left)) {
170
+ return QueryOrdering.compareOrdered(left, right);
171
+ }
172
+ return QueryOrdering.compareText(QueryOrdering.stableKey(left), QueryOrdering.stableKey(right));
173
+ },
174
+ /**
175
+ * Creates a deterministic value representation for equality and tie-breaking.
176
+ */
177
+ stableKey(value) {
178
+ if (value instanceof Uint8Array)
179
+ return `bytes:${[...value].join(".")}`;
180
+ if (typeof value === "bigint")
181
+ return `bigint:${value.toString()}`;
182
+ if (typeof value !== "object" || value === null)
183
+ return `${typeof value}:${String(value)}`;
184
+ if (Array.isArray(value))
185
+ return `array:[${value.map((item) => QueryOrdering.stableKey(item)).join(",")}]`;
186
+ return `object:{${Object.keys(value)
187
+ .sort()
188
+ .map((key) => `${JSON.stringify(key)}:${QueryOrdering.stableKey(Reflect.get(value, key))}`)
189
+ .join(",")}}`;
190
+ },
191
+ /**
192
+ * Identifies ordered Protobuf timestamp and version values.
193
+ */
194
+ isOrderedMessage(value) {
195
+ return (typeof value === "object" &&
196
+ value !== null &&
197
+ (Reflect.get(value, "$typeName") === "google.protobuf.Timestamp" ||
198
+ Reflect.get(value, "$typeName") === "spine.core.Version"));
199
+ },
200
+ /**
201
+ * Compares finite numeric values.
202
+ */
203
+ compareNumber(left, right) {
204
+ if (!Number.isFinite(left) || !Number.isFinite(right)) {
205
+ throw new TypeError("Normalized query ordering numbers must be finite.");
206
+ }
207
+ return left < right ? -1 : left > right ? 1 : 0;
208
+ },
209
+ /**
210
+ * Compares text values in code-unit order.
211
+ */
212
+ compareText(left, right) {
213
+ return left < right ? -1 : left > right ? 1 : 0;
214
+ },
215
+ /**
216
+ * Identifies absent normalized query values.
217
+ */
218
+ isMissing(value) {
219
+ return value === undefined || value === null;
220
+ },
221
+ };
222
+ //# sourceMappingURL=query-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-execution.js","sourceRoot":"","sources":["../../src/query/query-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAwBjD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAQ5B;IAPrB,kBAAkB;IAElB;;;;OAIG;IACH,YAAqB,cAAsB;QACzC,KAAK,CAAC,iDAAiD,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAD/D,mBAAc,GAAd,cAAc,CAAQ;QAEzC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAK7B,MAAM,CAAC,MAAM,CAAC;IACjB,QAAQ,CACN,OAAoD,EACpD,IAA6B;QAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,MAAM,QAAQ,GACZ,SAAS,KAAK,SAAS;YACrB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACd,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QACjF,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAChG,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC;CACF,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAG1B,MAAM,CAAC,MAAM,CAAC;IACjB,KAAK,CAAC,IAAa,EAAE,KAAc;QACjC,OAAO,qBAAqB,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,IAAa,EAAE,KAAc;QACnC,OAAO,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;CACF,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,qBAAqB,GAAG;IAC5B,kBAAkB;IAElB;;OAEG;IACH,OAAO,CACL,KAAuC,EACvC,SAAuC;QAEvC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,KAAK;gBACR,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YACrF,KAAK,YAAY;gBACf,OAAO,qBAAqB,CAAC,gBAAgB,CAC3C,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EACnC,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,KAAK,CAChB,CAAC;YACJ,KAAK,KAAK;gBACR,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YAC5F,KAAK,QAAQ;gBACX,OAAO,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB,CACd,MAAe,EACf,QAAsC,EACtC,QAAiB;QAEjB,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,qBAAqB,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACrF,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACvF,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9D,IAAI,QAAQ,KAAK,aAAa;YAAE,OAAO,MAAM,GAAG,CAAC,CAAC;QAClD,IAAI,QAAQ,KAAK,UAAU;YAAE,OAAO,MAAM,GAAG,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,gBAAgB;YAAE,OAAO,MAAM,IAAI,CAAC,CAAC;QACtD,OAAO,MAAM,IAAI,CAAC,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,IAAa,EAAE,KAAc;QACvC,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACpE,OAAO,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,aAAa,GAAG;IACpB,kBAAkB;IAElB;;OAEG;IACH,cAAc,CACZ,IAAsC,EACtC,KAAuC,EACvC,IAA6B;QAE7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,aAAa,CAAC,kBAAkB,CACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAC9B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAChC,CAAC;YACF,IAAI,UAAU,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QACzF,CAAC;QACD,OAAO,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,IAAa,EAAE,KAAc;QAC9C,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACpE,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,CAAC;YAC9E,OAAO,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,IAAa,EAAE,KAAc;QAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;YACvD,OAAO,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC1D,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;YACvD,OAAO,aAAa,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,IACE,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACpC,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC;YACrC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,EAClC,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBACnD,OAAO,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACzF,CAAC;YACD,OAAO,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,0DAA0D,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACH,WAAW,CACT,SAAkB,EAClB,SAAkB,EAClB,UAAmB,EACnB,UAAmB;QAEnB,MAAM,KAAK,GAAG,aAAa,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACjE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClF,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAa,EAAE,KAAc;QACzC,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC;YACjE,OAAO,aAAa,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,OAAO,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;YACzF,OAAO,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,aAAa,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAClG,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAc;QACtB,IAAI,KAAK,YAAY,UAAU;YAAE,OAAO,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,UAAU,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;QACnE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,GAAG,OAAO,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACtB,OAAO,UAAU,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACnF,OAAO,WAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACjC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;aAC1F,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAc;QAO7B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,2BAA2B;gBAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,oBAAoB,CAAC,CAC5D,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAY,EAAE,KAAa;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,IAAY,EAAE,KAAa;QACrC,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAc;QACtB,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;IAC/C,CAAC;CACF,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Normalized comparison operators understood by storage providers.
3
+ */
4
+ export type NormalizedComparisonOperator = "equal" | "greaterThan" | "lessThan" | "greaterOrEqual" | "lessOrEqual";
5
+ /**
6
+ * Provider-independent normalized query predicate.
7
+ */
8
+ export type NormalizedQueryPredicate<Id> = Readonly<{
9
+ /**
10
+ * Identifies the predicate as an explicit ID set.
11
+ */
12
+ kind: "ids";
13
+ /**
14
+ * Lists the IDs selected by the predicate.
15
+ */
16
+ ids: readonly Id[];
17
+ }> | Readonly<{
18
+ /**
19
+ * Identifies the predicate as a column comparison.
20
+ */
21
+ kind: "comparison";
22
+ /**
23
+ * Names the compared record column.
24
+ */
25
+ column: string;
26
+ /**
27
+ * Selects the comparison operator.
28
+ */
29
+ operator: NormalizedComparisonOperator;
30
+ /**
31
+ * Provides the value compared against the column.
32
+ */
33
+ value: unknown;
34
+ }> | Readonly<{
35
+ /**
36
+ * Identifies the predicate as an all-or-either composition.
37
+ */
38
+ kind: "all" | "either";
39
+ /**
40
+ * Lists the component predicates.
41
+ */
42
+ predicates: readonly NormalizedQueryPredicate<Id>[];
43
+ }>;
44
+ /**
45
+ * Provider-independent normalized query ordering.
46
+ */
47
+ export interface NormalizedQueryOrder {
48
+ /**
49
+ * Names the column used for ordering.
50
+ */
51
+ readonly column: string;
52
+ /**
53
+ * Selects ascending or descending order.
54
+ */
55
+ readonly direction: "asc" | "desc";
56
+ }
57
+ /**
58
+ * Provider-independent normalized field mask.
59
+ */
60
+ export interface NormalizedQueryMask {
61
+ /**
62
+ * Lists the record paths retained by the mask.
63
+ */
64
+ readonly paths: readonly string[];
65
+ }
66
+ /**
67
+ * Canonical query plan accepted at the storage-provider boundary.
68
+ */
69
+ export interface NormalizedQueryPlan<Id> {
70
+ /**
71
+ * Defines the optional predicate.
72
+ */
73
+ readonly predicate?: NormalizedQueryPredicate<Id>;
74
+ /**
75
+ * Defines the optional ordering.
76
+ */
77
+ readonly order?: readonly NormalizedQueryOrder[];
78
+ /**
79
+ * Defines the optional field mask.
80
+ */
81
+ readonly mask?: NormalizedQueryMask;
82
+ /**
83
+ * Limits matching rows after ordering.
84
+ */
85
+ readonly limit?: number;
86
+ /**
87
+ * Maximum provider rows materialized before semantic evaluation. Values must
88
+ * be positive safe integers; the default and inclusive maximum are 10,000.
89
+ */
90
+ readonly candidateLimit?: number;
91
+ }
92
+ /**
93
+ * Optional normalized query features a storage provider can execute.
94
+ */
95
+ export type StorageQueryFeature = "either" | "nested" | "order" | "mask" | "limit";
96
+ /**
97
+ * Explicit query capabilities advertised by a storage provider.
98
+ */
99
+ export interface StorageQueryCapabilities {
100
+ /**
101
+ * Lists supported comparison operators.
102
+ */
103
+ readonly comparisons: readonly NormalizedComparisonOperator[];
104
+ /**
105
+ * Lists supported normalized query features.
106
+ */
107
+ readonly features: readonly StorageQueryFeature[];
108
+ }
109
+ /**
110
+ * Shared fail-fast validation for normalized plans before provider execution.
111
+ */
112
+ export declare const StorageQueryPolicy: Readonly<{
113
+ validate<Id>(plan: NormalizedQueryPlan<Id>, capabilities: StorageQueryCapabilities): void;
114
+ }>;
115
+ //# sourceMappingURL=query-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-policy.d.ts","sourceRoot":"","sources":["../../src/query/query-policy.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,MAAM,4BAA4B,GACtC,OAAO,GAAG,aAAa,GAAG,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,wBAAwB,CAAC,EAAE,IACnC,QAAQ,CAAC;IAGP;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC;IAEZ;;OAEG;IACH,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC;CACpB,CAAC,GACF,QAAQ,CAAC;IAGP;;OAEG;IACH,IAAI,EAAE,YAAY,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,4BAA4B,CAAC;IAEvC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IAGP;;OAEG;IACH,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;IAEvB;;OAEG;IACH,UAAU,EAAE,SAAS,wBAAwB,CAAC,EAAE,CAAC,EAAE,CAAC;CACrD,CAAC,CAAC;AAEP;;GAEG;AACH,MAAM,WAAW,oBAAoB;IAGnC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAGlC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,EAAE;IAGrC;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,wBAAwB,CAAC,EAAE,CAAC,CAAC;IAElD;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAEjD;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAEpC;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IAGvC;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,4BAA4B,EAAE,CAAC;IAE9D;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACnD;AAcD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC;IACxC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC3F,CAwBC,CAAC"}
@@ -0,0 +1,294 @@
1
+ /*
2
+ * Copyright 2026, CodeMatters. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
+ * in compliance with the License. You may obtain a copy of the License at
6
+ *
7
+ * https://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
10
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ * or implied. See the License for the specific language governing permissions and limitations under
12
+ * the License.
13
+ */
14
+ const maximumPredicateDepth = 64;
15
+ const maximumPredicateNodes = 10_000;
16
+ const knownComparisons = new Set([
17
+ "equal",
18
+ "greaterThan",
19
+ "lessThan",
20
+ "greaterOrEqual",
21
+ "lessOrEqual",
22
+ ]);
23
+ const knownFeatures = new Set(["either", "nested", "order", "mask", "limit"]);
24
+ const knownPlanProperties = new Set(["predicate", "order", "mask", "limit", "candidateLimit"]);
25
+ /**
26
+ * Shared fail-fast validation for normalized plans before provider execution.
27
+ */
28
+ export const StorageQueryPolicy = Object.freeze({
29
+ validate(plan, capabilities) {
30
+ const normalizedPlan = QueryPlanValidator.requireRecord(plan, "query plan must be an object.");
31
+ const normalizedCapabilities = QueryPlanValidator.requireRecord(capabilities, "query capabilities must be an object.");
32
+ QueryPlanValidator.validatePlanProperties(normalizedPlan);
33
+ const comparisons = QueryCapabilities.validateComparisons(normalizedCapabilities.comparisons);
34
+ const features = QueryCapabilities.validateFeatures(normalizedCapabilities.features);
35
+ const requirements = {
36
+ comparisons: new Set(),
37
+ features: new Set(),
38
+ };
39
+ if (normalizedPlan.predicate !== undefined) {
40
+ QueryPlanValidator.validatePredicate(normalizedPlan.predicate, requirements);
41
+ }
42
+ QueryPlanValidator.validateOrder(normalizedPlan.order, requirements);
43
+ QueryPlanValidator.validateMask(normalizedPlan.mask, requirements);
44
+ QueryPlanValidator.validateLimit(normalizedPlan.limit, normalizedPlan.order, requirements);
45
+ QueryPlanValidator.validateCandidateLimit(normalizedPlan.candidateLimit);
46
+ QueryCapabilities.admit(requirements, comparisons, features);
47
+ },
48
+ });
49
+ /**
50
+ * Validates normalized plan values and accumulates their required capabilities.
51
+ */
52
+ const QueryPlanValidator = {
53
+ // prettier-ignore
54
+ /**
55
+ * Rejects unsupported or misspelled normalized-plan properties.
56
+ */
57
+ validatePlanProperties(plan) {
58
+ if (Object.hasOwn(plan, "offset")) {
59
+ throw new TypeError("normalized query plans do not support offset.");
60
+ }
61
+ for (const property of Object.keys(plan)) {
62
+ if (!knownPlanProperties.has(property)) {
63
+ throw new TypeError("query plan property must be recognized.");
64
+ }
65
+ }
66
+ },
67
+ /**
68
+ * Validates the maximum materialized candidate count.
69
+ */
70
+ validateCandidateLimit(value) {
71
+ if (value === undefined)
72
+ return;
73
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
74
+ throw new TypeError("query candidate limit must be a positive safe integer.");
75
+ }
76
+ if (value > 10_000)
77
+ throw new TypeError("query candidate limit must not exceed 10,000.");
78
+ },
79
+ /**
80
+ * Validates a normalized predicate tree and records its required capabilities.
81
+ */
82
+ validatePredicate(root, requirements) {
83
+ const pending = [
84
+ { predicate: root, depth: 0 },
85
+ ];
86
+ const seen = new WeakSet();
87
+ let visited = 0;
88
+ while (pending.length > 0) {
89
+ const current = pending.pop();
90
+ if (current === undefined)
91
+ break;
92
+ visited += 1;
93
+ if (visited > maximumPredicateNodes) {
94
+ throw new TypeError(`query predicate exceeds maximum node count ${String(maximumPredicateNodes)}.`);
95
+ }
96
+ if (current.depth > maximumPredicateDepth) {
97
+ throw new TypeError(`query predicate exceeds maximum depth ${String(maximumPredicateDepth)}.`);
98
+ }
99
+ const predicate = QueryPlanValidator.requireRecord(current.predicate, "query predicate must be an object.");
100
+ if (seen.has(predicate))
101
+ throw new TypeError("query predicate must not contain cycles.");
102
+ seen.add(predicate);
103
+ if (predicate.kind === "ids") {
104
+ if (!Array.isArray(predicate.ids))
105
+ throw new TypeError("ID predicate IDs must be an array.");
106
+ if (predicate.ids.length === 0)
107
+ throw new TypeError("ID predicate must not be empty.");
108
+ for (let index = 0; index < predicate.ids.length; index += 1) {
109
+ if (!Object.hasOwn(predicate.ids, index) || predicate.ids[index] === undefined) {
110
+ throw new TypeError("ID predicate entries must be defined.");
111
+ }
112
+ }
113
+ continue;
114
+ }
115
+ if (predicate.kind === "comparison") {
116
+ if (typeof predicate.column !== "string") {
117
+ throw new TypeError("comparison column must be a string.");
118
+ }
119
+ if (predicate.column.trim().length === 0) {
120
+ throw new TypeError("comparison column must not be blank.");
121
+ }
122
+ if (typeof predicate.operator !== "string" ||
123
+ !knownComparisons.has(predicate.operator)) {
124
+ throw new TypeError("comparison operator must be recognized.");
125
+ }
126
+ if (predicate.value === undefined)
127
+ throw new TypeError("comparison value must be defined.");
128
+ requirements.comparisons.add(predicate.operator);
129
+ continue;
130
+ }
131
+ if (predicate.kind !== "all" && predicate.kind !== "either") {
132
+ throw new TypeError("query predicate kind must be recognized.");
133
+ }
134
+ if (!Array.isArray(predicate.predicates)) {
135
+ throw new TypeError(`${predicate.kind.toUpperCase()} predicate predicates must be an array.`);
136
+ }
137
+ if (predicate.predicates.length === 0) {
138
+ throw new TypeError(`${predicate.kind.toUpperCase()} predicate must not be empty.`);
139
+ }
140
+ if (predicate.kind === "either")
141
+ requirements.features.add("either");
142
+ if (current.depth > 0)
143
+ requirements.features.add("nested");
144
+ if (visited + pending.length + predicate.predicates.length > maximumPredicateNodes) {
145
+ throw new TypeError(`query predicate exceeds maximum node count ${String(maximumPredicateNodes)}.`);
146
+ }
147
+ for (let index = predicate.predicates.length - 1; index >= 0; index -= 1) {
148
+ if (!Object.hasOwn(predicate.predicates, index)) {
149
+ throw new TypeError("query predicate entries must be defined.");
150
+ }
151
+ pending.push({ predicate: predicate.predicates[index], depth: current.depth + 1 });
152
+ }
153
+ }
154
+ },
155
+ /**
156
+ * Validates normalized ordering and records the ordering capability.
157
+ */
158
+ validateOrder(value, requirements) {
159
+ if (value === undefined)
160
+ return;
161
+ if (!Array.isArray(value))
162
+ throw new TypeError("query order must be an array.");
163
+ if (value.length === 0)
164
+ throw new TypeError("query order must not be empty.");
165
+ for (const candidate of value) {
166
+ const order = QueryPlanValidator.requireRecord(candidate, "query order entry must be an object.");
167
+ if (typeof order.column !== "string")
168
+ throw new TypeError("query order column must be a string.");
169
+ if (order.column.trim().length === 0)
170
+ throw new TypeError("query order column must not be blank.");
171
+ if (order.direction !== "asc" && order.direction !== "desc") {
172
+ throw new TypeError("query order direction must be asc or desc.");
173
+ }
174
+ }
175
+ requirements.features.add("order");
176
+ },
177
+ /**
178
+ * Validates a normalized field mask and records the mask capability.
179
+ */
180
+ validateMask(value, requirements) {
181
+ if (value === undefined)
182
+ return;
183
+ const mask = QueryPlanValidator.requireRecord(value, "field mask must be an object.");
184
+ if (!Array.isArray(mask.paths))
185
+ throw new TypeError("field-mask paths must be an array.");
186
+ if (mask.paths.length === 0)
187
+ throw new TypeError("field mask must not be empty.");
188
+ const paths = mask.paths;
189
+ for (let index = 0; index < paths.length; index += 1) {
190
+ const path = paths[index];
191
+ if (!Object.hasOwn(paths, index) || typeof path !== "string") {
192
+ throw new TypeError("field-mask paths must be strings.");
193
+ }
194
+ if (path.trim().length === 0)
195
+ throw new TypeError("field-mask paths must not be blank.");
196
+ }
197
+ requirements.features.add("mask");
198
+ },
199
+ /**
200
+ * Validates a result limit and records the limit capability.
201
+ */
202
+ validateLimit(value, order, requirements) {
203
+ if (value === undefined)
204
+ return;
205
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
206
+ throw new TypeError("query limit must be a positive integer.");
207
+ }
208
+ if (!Array.isArray(order) || order.length === 0) {
209
+ throw new TypeError("query limit requires ordering.");
210
+ }
211
+ requirements.features.add("limit");
212
+ },
213
+ /**
214
+ * Requires a non-array object value and returns its properties.
215
+ */
216
+ requireRecord(value, message) {
217
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
218
+ throw new TypeError(message);
219
+ }
220
+ return value;
221
+ },
222
+ };
223
+ /**
224
+ * Validates advertised capabilities and admits normalized query requirements.
225
+ */
226
+ const QueryCapabilities = {
227
+ // prettier-ignore
228
+ /**
229
+ * Validates advertised comparison operators.
230
+ */
231
+ validateComparisons(value) {
232
+ if (!Array.isArray(value))
233
+ throw new TypeError("comparison capabilities must be an array.");
234
+ const validated = [];
235
+ for (const comparison of value) {
236
+ if (typeof comparison !== "string" || !knownComparisons.has(comparison)) {
237
+ throw new TypeError("comparison capability must be recognized.");
238
+ }
239
+ validated.push(comparison);
240
+ }
241
+ return new Set(validated);
242
+ },
243
+ /**
244
+ * Validates advertised normalized query features.
245
+ */
246
+ validateFeatures(value) {
247
+ if (!Array.isArray(value))
248
+ throw new TypeError("query features must be an array.");
249
+ const validated = [];
250
+ for (const feature of value) {
251
+ if (typeof feature !== "string" || !knownFeatures.has(feature)) {
252
+ throw new TypeError("query feature must be recognized.");
253
+ }
254
+ validated.push(feature);
255
+ }
256
+ return new Set(validated);
257
+ },
258
+ /**
259
+ * Rejects requirements that an advertised provider capability set does not satisfy.
260
+ */
261
+ admit(requirements, comparisons, features) {
262
+ for (const feature of requirements.features) {
263
+ QueryCapabilities.requireFeature(features, feature, QueryCapabilities.featureDescription(feature));
264
+ }
265
+ for (const comparison of requirements.comparisons) {
266
+ if (!comparisons.has(comparison)) {
267
+ throw new TypeError(`Storage provider does not support comparison operator "${comparison}".`);
268
+ }
269
+ }
270
+ },
271
+ /**
272
+ * Describes a capability in a provider-rejection message.
273
+ */
274
+ featureDescription(feature) {
275
+ if (feature === "either")
276
+ return "EITHER predicates";
277
+ if (feature === "nested")
278
+ return "nested predicates";
279
+ if (feature === "order")
280
+ return "ordering";
281
+ if (feature === "mask")
282
+ return "field masks";
283
+ return "limits";
284
+ },
285
+ /**
286
+ * Rejects a missing required feature with its provider-facing description.
287
+ */
288
+ requireFeature(features, feature, description) {
289
+ if (!features.has(feature)) {
290
+ throw new TypeError(`Storage provider does not support ${description}.`);
291
+ }
292
+ },
293
+ };
294
+ //# sourceMappingURL=query-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-policy.js","sourceRoot":"","sources":["../../src/query/query-policy.ts"],"names":[],"mappings":"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"}