@rocicorp/zero 0.16.2025022601 → 0.17.2025022800

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 (183) hide show
  1. package/out/{chunk-7E4L5D3N.js → chunk-5BT5TJFM.js} +517 -3962
  2. package/out/chunk-5BT5TJFM.js.map +7 -0
  3. package/out/chunk-P3NUVEQJ.js +3578 -0
  4. package/out/chunk-P3NUVEQJ.js.map +7 -0
  5. package/out/pg.js +593 -0
  6. package/out/pg.js.map +7 -0
  7. package/out/react.js +1 -4
  8. package/out/react.js.map +2 -2
  9. package/out/shared/src/types.js +2 -0
  10. package/out/shared/src/types.js.map +1 -0
  11. package/out/solid.js +3 -2
  12. package/out/solid.js.map +1 -1
  13. package/out/z2s/src/compiler.d.ts +26 -0
  14. package/out/z2s/src/compiler.d.ts.map +1 -0
  15. package/out/z2s/src/compiler.js +155 -0
  16. package/out/z2s/src/compiler.js.map +1 -0
  17. package/out/z2s/src/sql.d.ts +12 -0
  18. package/out/z2s/src/sql.d.ts.map +1 -0
  19. package/out/z2s/src/sql.js +18 -0
  20. package/out/z2s/src/sql.js.map +1 -0
  21. package/out/zero/src/pg.d.ts +2 -0
  22. package/out/zero/src/pg.d.ts.map +1 -0
  23. package/out/zero/src/pg.js +3 -0
  24. package/out/zero/src/pg.js.map +1 -0
  25. package/out/zero-cache/src/auth/load-permissions.d.ts +2 -2
  26. package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
  27. package/out/zero-cache/src/auth/load-permissions.js +6 -7
  28. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  29. package/out/zero-cache/src/auth/read-authorizer.d.ts.map +1 -1
  30. package/out/zero-cache/src/auth/read-authorizer.js +1 -1
  31. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  32. package/out/zero-cache/src/auth/write-authorizer.d.ts +1 -1
  33. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  34. package/out/zero-cache/src/auth/write-authorizer.js +4 -2
  35. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  36. package/out/zero-cache/src/config/zero-config.d.ts +1 -1
  37. package/out/zero-cache/src/config/zero-config.js +4 -4
  38. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  39. package/out/zero-cache/src/scripts/deploy-permissions.js +5 -4
  40. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  41. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  42. package/out/zero-cache/src/server/change-streamer.js +3 -2
  43. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  44. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  45. package/out/zero-cache/src/server/main.js +2 -1
  46. package/out/zero-cache/src/server/main.js.map +1 -1
  47. package/out/zero-cache/src/server/multi/config.d.ts +1 -1
  48. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  49. package/out/zero-cache/src/server/syncer.js +4 -3
  50. package/out/zero-cache/src/server/syncer.js.map +1 -1
  51. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +2 -2
  52. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  53. package/out/zero-cache/src/services/change-source/custom/change-source.js +10 -10
  54. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  55. package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts +1 -1
  56. package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts.map +1 -1
  57. package/out/zero-cache/src/services/change-source/custom/sync-schema.js +2 -2
  58. package/out/zero-cache/src/services/change-source/custom/sync-schema.js.map +1 -1
  59. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +1 -1
  60. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  61. package/out/zero-cache/src/services/change-source/pg/change-source.js +14 -12
  62. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  63. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +2 -2
  64. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  65. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +13 -9
  66. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  67. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +1 -1
  68. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  69. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +11 -9
  70. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  71. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +2 -2
  72. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  73. package/out/zero-cache/src/services/change-source/pg/schema/init.js +10 -10
  74. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  75. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +1 -3
  76. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  77. package/out/zero-cache/src/services/change-source/pg/schema/published.js +1 -3
  78. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  79. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +10 -12
  80. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  81. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +55 -51
  82. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  83. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +1 -0
  84. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
  85. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -0
  86. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  87. package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts +1 -1
  88. package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts.map +1 -1
  89. package/out/zero-cache/src/services/change-source/pg/sync-schema.js +2 -2
  90. package/out/zero-cache/src/services/change-source/pg/sync-schema.js.map +1 -1
  91. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  92. package/out/zero-cache/src/services/change-streamer/storer.js +1 -3
  93. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  94. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +2 -2
  95. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  96. package/out/zero-cache/src/services/mutagen/mutagen.js +18 -14
  97. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  98. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +1 -1
  99. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  100. package/out/zero-cache/src/services/view-syncer/client-handler.js +5 -6
  101. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  102. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +1 -1
  103. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/view-syncer/cvr-store.js +3 -3
  105. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  106. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +1 -1
  107. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  108. package/out/zero-cache/src/services/view-syncer/cvr.js +4 -3
  109. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  110. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +3 -3
  111. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  112. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +12 -4
  113. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  114. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts +1 -1
  115. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  116. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +2 -2
  117. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  118. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +3 -3
  119. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
  120. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +39 -39
  121. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  122. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts +1 -1
  123. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
  124. package/out/zero-cache/src/services/view-syncer/schema/init.js +5 -5
  125. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  126. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +4 -3
  127. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  128. package/out/zero-cache/src/services/view-syncer/snapshotter.js +25 -23
  129. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  130. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -1
  131. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  132. package/out/zero-cache/src/services/view-syncer/view-syncer.js +12 -8
  133. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  134. package/out/zero-client/src/client/custom.d.ts +1 -1
  135. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  136. package/out/zero-client/src/client/zero.d.ts +1 -1
  137. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  138. package/out/zero-client/src/mod.d.ts +1 -0
  139. package/out/zero-client/src/mod.d.ts.map +1 -1
  140. package/out/zero-pg/src/custom.d.ts +42 -0
  141. package/out/zero-pg/src/custom.d.ts.map +1 -0
  142. package/out/zero-pg/src/custom.js +99 -0
  143. package/out/zero-pg/src/custom.js.map +1 -0
  144. package/out/zero-pg/src/db.d.ts +27 -0
  145. package/out/zero-pg/src/db.d.ts.map +1 -0
  146. package/out/zero-pg/src/db.js +2 -0
  147. package/out/zero-pg/src/db.js.map +1 -0
  148. package/out/zero-pg/src/logging.d.ts +3 -0
  149. package/out/zero-pg/src/logging.d.ts.map +1 -0
  150. package/out/zero-pg/src/logging.js +5 -0
  151. package/out/zero-pg/src/logging.js.map +1 -0
  152. package/out/zero-pg/src/mod.d.ts +5 -0
  153. package/out/zero-pg/src/mod.d.ts.map +1 -0
  154. package/out/zero-pg/src/mod.js +2 -0
  155. package/out/zero-pg/src/mod.js.map +1 -0
  156. package/out/zero-pg/src/query.d.ts +22 -0
  157. package/out/zero-pg/src/query.d.ts.map +1 -0
  158. package/out/zero-pg/src/query.js +54 -0
  159. package/out/zero-pg/src/query.js.map +1 -0
  160. package/out/zero-pg/src/web.d.ts +16 -0
  161. package/out/zero-pg/src/web.d.ts.map +1 -0
  162. package/out/zero-pg/src/web.js +115 -0
  163. package/out/zero-pg/src/web.js.map +1 -0
  164. package/out/zero-react/src/use-zero.d.ts +5 -4
  165. package/out/zero-react/src/use-zero.d.ts.map +1 -1
  166. package/out/zero.js +2 -1
  167. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  168. package/out/zql/src/ivm/exists.js +43 -23
  169. package/out/zql/src/ivm/exists.js.map +1 -1
  170. package/out/zql/src/mutate/custom.js +10 -0
  171. package/out/zql/src/mutate/custom.js.map +1 -0
  172. package/out/zql/src/query/query-impl.d.ts +2 -2
  173. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  174. package/out/zql/src/query/query-impl.js +1 -1
  175. package/out/zql/src/query/query-impl.js.map +1 -1
  176. package/out/zql/src/query/query.d.ts +1 -1
  177. package/out/zql/src/query/query.d.ts.map +1 -1
  178. package/out/zql/src/query/static-query.d.ts +1 -1
  179. package/out/zql/src/query/static-query.d.ts.map +1 -1
  180. package/out/zql/src/query/static-query.js +3 -3
  181. package/out/zql/src/query/static-query.js.map +1 -1
  182. package/package.json +5 -1
  183. package/out/chunk-7E4L5D3N.js.map +0 -7
@@ -0,0 +1,3578 @@
1
+ import {
2
+ hasOwn
3
+ } from "./chunk-HARIWJ2J.js";
4
+ import {
5
+ applyChange,
6
+ assert,
7
+ assertObject,
8
+ assertString,
9
+ compareValues,
10
+ drainStreams,
11
+ must,
12
+ normalizeUndefined,
13
+ throwInvalidType,
14
+ unreachable,
15
+ valuesEqual
16
+ } from "./chunk-Q6D7EOS6.js";
17
+ import {
18
+ __export,
19
+ __reExport
20
+ } from "./chunk-424PT5DM.js";
21
+
22
+ // ../shared/src/valita.ts
23
+ var valita_exports = {};
24
+ __export(valita_exports, {
25
+ assert: () => assert2,
26
+ deepPartial: () => deepPartial,
27
+ instanceOfAbstractType: () => instanceOfAbstractType,
28
+ is: () => is,
29
+ parse: () => parse,
30
+ readonly: () => readonly,
31
+ readonlyArray: () => readonlyArray,
32
+ readonlyObject: () => readonlyObject,
33
+ readonlyRecord: () => readonlyRecord,
34
+ test: () => test,
35
+ testOptional: () => testOptional
36
+ });
37
+ __reExport(valita_exports, valita_star);
38
+ import * as v from "@badrap/valita";
39
+ import * as valita_star from "@badrap/valita";
40
+ function toDisplay(value) {
41
+ switch (typeof value) {
42
+ case "string":
43
+ case "number":
44
+ case "boolean":
45
+ return JSON.stringify(value);
46
+ case "undefined":
47
+ return "undefined";
48
+ case "bigint":
49
+ return value.toString() + "n";
50
+ default:
51
+ if (value === null) {
52
+ return "null";
53
+ }
54
+ if (Array.isArray(value)) {
55
+ return "array";
56
+ }
57
+ return typeof value;
58
+ }
59
+ }
60
+ function toDisplayAtPath(v2, path2) {
61
+ if (!path2?.length) {
62
+ return toDisplay(v2);
63
+ }
64
+ let cur = v2;
65
+ for (const p of path2) {
66
+ cur = cur[p];
67
+ }
68
+ return toDisplay(cur);
69
+ }
70
+ function displayList(word, expected, toDisplay2 = (x) => String(x)) {
71
+ if (expected.length === 1) {
72
+ return toDisplay2(expected[0]);
73
+ }
74
+ const suffix = `${toDisplay2(
75
+ expected[expected.length - 2]
76
+ )} ${word} ${toDisplay2(expected[expected.length - 1])}`;
77
+ if (expected.length === 2) {
78
+ return suffix;
79
+ }
80
+ return `${expected.slice(0, -2).map(toDisplay2).join(", ")}, ${suffix}`;
81
+ }
82
+ function getMessage(err2, v2, schema, mode) {
83
+ const firstIssue = err2.issues[0];
84
+ const { path: path2 } = firstIssue;
85
+ const atPath = path2?.length ? ` at ${path2.join(".")}` : "";
86
+ switch (firstIssue.code) {
87
+ case "invalid_type":
88
+ return `Expected ${displayList(
89
+ "or",
90
+ firstIssue.expected
91
+ )}${atPath}. Got ${toDisplayAtPath(v2, path2)}`;
92
+ case "missing_value": {
93
+ const atPath2 = path2 && path2.length > 1 ? ` at ${path2.slice(0, -1).join(".")}` : "";
94
+ if (firstIssue.path?.length) {
95
+ return `Missing property ${firstIssue.path.at(-1)}${atPath2}`;
96
+ }
97
+ return `TODO Unknown missing property${atPath2}`;
98
+ }
99
+ case "invalid_literal":
100
+ return `Expected literal value ${displayList(
101
+ "or",
102
+ firstIssue.expected,
103
+ toDisplay
104
+ )}${atPath} Got ${toDisplayAtPath(v2, path2)}`;
105
+ case "invalid_length": {
106
+ return `Expected array with length ${firstIssue.minLength === firstIssue.maxLength ? firstIssue.minLength : `between ${firstIssue.minLength} and ${firstIssue.maxLength}`}${atPath}. Got array with length ${v2.length}`;
107
+ }
108
+ case "unrecognized_keys":
109
+ if (firstIssue.keys.length === 1) {
110
+ return `Unexpected property ${firstIssue.keys[0]}${atPath}`;
111
+ }
112
+ return `Unexpected properties ${displayList(
113
+ "and",
114
+ firstIssue.keys
115
+ )}${atPath}`;
116
+ case "invalid_union":
117
+ return schema.name === "union" ? getDeepestUnionParseError(v2, schema, mode ?? "strict") : `Invalid union value${atPath}`;
118
+ case "custom_error": {
119
+ const { error } = firstIssue;
120
+ const message = !error ? "unknown" : typeof error === "string" ? error : error.message ?? "unknown";
121
+ return `${message}${atPath}. Got ${toDisplayAtPath(v2, path2)}`;
122
+ }
123
+ }
124
+ }
125
+ function getDeepestUnionParseError(value, schema, mode) {
126
+ const failures = [];
127
+ for (const type of schema.options) {
128
+ const r = type.try(value, { mode });
129
+ if (!r.ok) {
130
+ failures.push({ type, err: r });
131
+ }
132
+ }
133
+ if (failures.length) {
134
+ failures.sort(pathCmp);
135
+ if (failures.length === 1 || pathCmp(failures[0], failures[1]) < 0) {
136
+ return getMessage(failures[0].err, value, failures[0].type, mode);
137
+ }
138
+ }
139
+ try {
140
+ const str = JSON.stringify(value);
141
+ return `Invalid union value: ${str}`;
142
+ } catch (e) {
143
+ return `Invalid union value`;
144
+ }
145
+ }
146
+ function pathCmp(a, b) {
147
+ const aPath = a.err.issues[0].path;
148
+ const bPath = b.err.issues[0].path;
149
+ if (aPath.length !== bPath.length) {
150
+ return bPath.length - aPath.length;
151
+ }
152
+ for (let i = 0; i < aPath.length; i++) {
153
+ if (bPath[i] > aPath[i]) {
154
+ return -1;
155
+ }
156
+ if (bPath[i] < aPath[i]) {
157
+ return 1;
158
+ }
159
+ }
160
+ return 0;
161
+ }
162
+ function parse(value, schema, mode) {
163
+ const res = test(value, schema, mode);
164
+ if (!res.ok) {
165
+ throw new TypeError(res.error);
166
+ }
167
+ return res.value;
168
+ }
169
+ function is(value, schema, mode) {
170
+ return test(value, schema, mode).ok;
171
+ }
172
+ function assert2(value, schema, mode) {
173
+ parse(value, schema, mode);
174
+ }
175
+ function test(value, schema, mode) {
176
+ const res = schema.try(value, mode ? { mode } : void 0);
177
+ if (!res.ok) {
178
+ return {
179
+ ok: false,
180
+ error: getMessage(res, value, schema, mode)
181
+ };
182
+ }
183
+ return res;
184
+ }
185
+ function testOptional(value, schema, mode) {
186
+ let flags = 1;
187
+ if (mode === "passthrough") {
188
+ flags = 0;
189
+ } else if (mode === "strip") {
190
+ flags = 2;
191
+ }
192
+ const res = schema.func(value, flags);
193
+ if (res === void 0) {
194
+ return { ok: true, value };
195
+ } else if (res.ok) {
196
+ return res;
197
+ }
198
+ const err2 = new v.ValitaError(res);
199
+ return { ok: false, error: getMessage(err2, value, schema, mode) };
200
+ }
201
+ function readonly(t) {
202
+ return t;
203
+ }
204
+ function readonlyObject(t) {
205
+ return v.object(t);
206
+ }
207
+ function readonlyArray(t) {
208
+ return v.array(t);
209
+ }
210
+ function readonlyRecord(t) {
211
+ return v.record(t);
212
+ }
213
+ var AbstractType = Object.getPrototypeOf(
214
+ Object.getPrototypeOf(v.string().optional())
215
+ ).constructor;
216
+ function instanceOfAbstractType(obj) {
217
+ return obj instanceof AbstractType;
218
+ }
219
+ function deepPartial(s) {
220
+ const shape = {};
221
+ for (const [key, type] of Object.entries(s.shape)) {
222
+ if (type.name === "object") {
223
+ shape[key] = deepPartial(type).optional();
224
+ } else {
225
+ shape[key] = type.optional();
226
+ }
227
+ }
228
+ return v.object(shape);
229
+ }
230
+
231
+ // ../zero-protocol/src/ast.ts
232
+ import { compareUTF8 } from "compare-utf8";
233
+
234
+ // ../shared/src/arrays.ts
235
+ function defined(arr) {
236
+ let i = arr.findIndex((x) => x === void 0);
237
+ if (i < 0) {
238
+ return arr;
239
+ }
240
+ const defined2 = arr.slice(0, i);
241
+ for (i++; i < arr.length; i++) {
242
+ const x = arr[i];
243
+ if (x !== void 0) {
244
+ defined2.push(x);
245
+ }
246
+ }
247
+ return defined2;
248
+ }
249
+ function areEqual(arr1, arr2) {
250
+ return arr1.length === arr2.length && arr1.every((e, i) => e === arr2[i]);
251
+ }
252
+
253
+ // ../shared/src/json-schema.ts
254
+ import * as valita from "@badrap/valita";
255
+
256
+ // ../shared/src/config.ts
257
+ var isProd = process.env.NODE_ENV === "production";
258
+
259
+ // ../shared/src/json.ts
260
+ function deepEqual(a, b) {
261
+ if (a === b) {
262
+ return true;
263
+ }
264
+ if (typeof a !== typeof b) {
265
+ return false;
266
+ }
267
+ switch (typeof a) {
268
+ case "boolean":
269
+ case "number":
270
+ case "string":
271
+ return false;
272
+ }
273
+ a = a;
274
+ if (Array.isArray(a)) {
275
+ if (!Array.isArray(b)) {
276
+ return false;
277
+ }
278
+ if (a.length !== b.length) {
279
+ return false;
280
+ }
281
+ for (let i = 0; i < a.length; i++) {
282
+ if (!deepEqual(a[i], b[i])) {
283
+ return false;
284
+ }
285
+ }
286
+ return true;
287
+ }
288
+ if (a === null || b === null) {
289
+ return false;
290
+ }
291
+ if (Array.isArray(b)) {
292
+ return false;
293
+ }
294
+ a = a;
295
+ b = b;
296
+ let aSize = 0;
297
+ for (const key in a) {
298
+ if (hasOwn(a, key)) {
299
+ if (!deepEqual(a[key], b[key])) {
300
+ return false;
301
+ }
302
+ aSize++;
303
+ }
304
+ }
305
+ let bSize = 0;
306
+ for (const key in b) {
307
+ if (hasOwn(b, key)) {
308
+ bSize++;
309
+ }
310
+ }
311
+ return aSize === bSize;
312
+ }
313
+ function assertJSONValue(v2) {
314
+ if (isProd) {
315
+ return;
316
+ }
317
+ switch (typeof v2) {
318
+ case "boolean":
319
+ case "number":
320
+ case "string":
321
+ return;
322
+ case "object":
323
+ if (v2 === null) {
324
+ return;
325
+ }
326
+ if (Array.isArray(v2)) {
327
+ return assertJSONArray(v2);
328
+ }
329
+ return assertObjectIsJSONObject(v2);
330
+ }
331
+ throwInvalidType(v2, "JSON value");
332
+ }
333
+ function assertJSONObject(v2) {
334
+ assertObject(v2);
335
+ assertObjectIsJSONObject(v2);
336
+ }
337
+ function assertObjectIsJSONObject(v2) {
338
+ for (const k in v2) {
339
+ if (hasOwn(v2, k)) {
340
+ const value = v2[k];
341
+ if (value !== void 0) {
342
+ assertJSONValue(value);
343
+ }
344
+ }
345
+ }
346
+ }
347
+ function assertJSONArray(v2) {
348
+ for (const item of v2) {
349
+ assertJSONValue(item);
350
+ }
351
+ }
352
+ function isJSONValue(v2, path2) {
353
+ switch (typeof v2) {
354
+ case "boolean":
355
+ case "number":
356
+ case "string":
357
+ return true;
358
+ case "object":
359
+ if (v2 === null) {
360
+ return true;
361
+ }
362
+ if (Array.isArray(v2)) {
363
+ return isJSONArray(v2, path2);
364
+ }
365
+ return objectIsJSONObject(v2, path2);
366
+ }
367
+ return false;
368
+ }
369
+ function isJSONObject(v2, path2) {
370
+ if (typeof v2 !== "object" || v2 === null) {
371
+ return false;
372
+ }
373
+ return objectIsJSONObject(v2, path2);
374
+ }
375
+ function objectIsJSONObject(v2, path2) {
376
+ for (const k in v2) {
377
+ if (hasOwn(v2, k)) {
378
+ path2.push(k);
379
+ const value = v2[k];
380
+ if (value !== void 0 && !isJSONValue(value, path2)) {
381
+ return false;
382
+ }
383
+ path2.pop();
384
+ }
385
+ }
386
+ return true;
387
+ }
388
+ function isJSONArray(v2, path2) {
389
+ for (let i = 0; i < v2.length; i++) {
390
+ path2.push(i);
391
+ if (!isJSONValue(v2[i], path2)) {
392
+ return false;
393
+ }
394
+ path2.pop();
395
+ }
396
+ return true;
397
+ }
398
+
399
+ // ../shared/src/json-schema.ts
400
+ var path = [];
401
+ var jsonSchema = valita_exports.unknown().chain((v2) => {
402
+ if (isProd) {
403
+ return valita.ok(v2);
404
+ }
405
+ const rv = isJSONValue(v2, path) ? valita.ok(v2) : valita.err({
406
+ message: `Not a JSON value`,
407
+ path: path.slice()
408
+ });
409
+ path.length = 0;
410
+ return rv;
411
+ });
412
+ var jsonObjectSchema = valita_exports.unknown().chain((v2) => {
413
+ if (isProd) {
414
+ return valita.ok(v2);
415
+ }
416
+ const rv = isJSONObject(v2, path) ? valita.ok(v2) : valita.err({
417
+ message: `Not a JSON object`,
418
+ path: path.slice()
419
+ });
420
+ path.length = 0;
421
+ return rv;
422
+ });
423
+
424
+ // ../zero-protocol/src/data.ts
425
+ var valueSchema = valita_exports.union(jsonSchema, valita_exports.undefined());
426
+ var rowSchema = readonlyRecord(valueSchema);
427
+
428
+ // ../zero-protocol/src/ast.ts
429
+ var selectorSchema = valita_exports.string();
430
+ var toStaticParam = Symbol();
431
+ var orderingElementSchema = readonly(
432
+ valita_exports.tuple([selectorSchema, valita_exports.union(valita_exports.literal("asc"), valita_exports.literal("desc"))])
433
+ );
434
+ var orderingSchema = readonlyArray(orderingElementSchema);
435
+ var primitiveSchema = valita_exports.union(
436
+ valita_exports.string(),
437
+ valita_exports.number(),
438
+ valita_exports.boolean(),
439
+ valita_exports.null()
440
+ );
441
+ var equalityOpsSchema = valita_exports.union(
442
+ valita_exports.literal("="),
443
+ valita_exports.literal("!="),
444
+ valita_exports.literal("IS"),
445
+ valita_exports.literal("IS NOT")
446
+ );
447
+ var orderOpsSchema = valita_exports.union(
448
+ valita_exports.literal("<"),
449
+ valita_exports.literal(">"),
450
+ valita_exports.literal("<="),
451
+ valita_exports.literal(">=")
452
+ );
453
+ var likeOpsSchema = valita_exports.union(
454
+ valita_exports.literal("LIKE"),
455
+ valita_exports.literal("NOT LIKE"),
456
+ valita_exports.literal("ILIKE"),
457
+ valita_exports.literal("NOT ILIKE")
458
+ );
459
+ var inOpsSchema = valita_exports.union(valita_exports.literal("IN"), valita_exports.literal("NOT IN"));
460
+ var simpleOperatorSchema = valita_exports.union(
461
+ equalityOpsSchema,
462
+ orderOpsSchema,
463
+ likeOpsSchema,
464
+ inOpsSchema
465
+ );
466
+ var literalReferenceSchema = readonlyObject({
467
+ type: valita_exports.literal("literal"),
468
+ value: valita_exports.union(
469
+ valita_exports.string(),
470
+ valita_exports.number(),
471
+ valita_exports.boolean(),
472
+ valita_exports.null(),
473
+ readonlyArray(valita_exports.union(valita_exports.string(), valita_exports.number(), valita_exports.boolean()))
474
+ )
475
+ });
476
+ var columnReferenceSchema = readonlyObject({
477
+ type: valita_exports.literal("column"),
478
+ name: valita_exports.string()
479
+ });
480
+ var parameterReferenceSchema = readonlyObject({
481
+ type: valita_exports.literal("static"),
482
+ // The "namespace" of the injected parameter.
483
+ // Write authorization will send the value of a row
484
+ // prior to the mutation being run (preMutationRow).
485
+ // Read and write authorization will both send the
486
+ // current authentication data (authData).
487
+ anchor: valita_exports.union(valita_exports.literal("authData"), valita_exports.literal("preMutationRow")),
488
+ field: valita_exports.union(valita_exports.string(), valita_exports.array(valita_exports.string()))
489
+ });
490
+ var conditionValueSchema = valita_exports.union(
491
+ literalReferenceSchema,
492
+ columnReferenceSchema,
493
+ parameterReferenceSchema
494
+ );
495
+ var simpleConditionSchema = readonlyObject({
496
+ type: valita_exports.literal("simple"),
497
+ op: simpleOperatorSchema,
498
+ left: conditionValueSchema,
499
+ right: valita_exports.union(parameterReferenceSchema, literalReferenceSchema)
500
+ });
501
+ var correlatedSubqueryConditionOperatorSchema = valita_exports.union(valita_exports.literal("EXISTS"), valita_exports.literal("NOT EXISTS"));
502
+ var correlatedSubqueryConditionSchema = readonlyObject({
503
+ type: valita_exports.literal("correlatedSubquery"),
504
+ related: valita_exports.lazy(() => correlatedSubquerySchema),
505
+ op: correlatedSubqueryConditionOperatorSchema
506
+ });
507
+ var conditionSchema = valita_exports.union(
508
+ simpleConditionSchema,
509
+ valita_exports.lazy(() => conjunctionSchema),
510
+ valita_exports.lazy(() => disjunctionSchema),
511
+ correlatedSubqueryConditionSchema
512
+ );
513
+ var conjunctionSchema = readonlyObject({
514
+ type: valita_exports.literal("and"),
515
+ conditions: readonlyArray(conditionSchema)
516
+ });
517
+ var disjunctionSchema = readonlyObject({
518
+ type: valita_exports.literal("or"),
519
+ conditions: readonlyArray(conditionSchema)
520
+ });
521
+ function mustCompoundKey(field) {
522
+ assert(Array.isArray(field) && field.length >= 1);
523
+ return field;
524
+ }
525
+ var compoundKeySchema = readonly(
526
+ valita_exports.tuple([valita_exports.string()]).concat(valita_exports.array(valita_exports.string()))
527
+ );
528
+ var correlationSchema = readonlyObject({
529
+ parentField: compoundKeySchema,
530
+ childField: compoundKeySchema
531
+ });
532
+ var correlatedSubquerySchemaOmitSubquery = readonlyObject({
533
+ correlation: correlationSchema,
534
+ hidden: valita_exports.boolean().optional(),
535
+ system: valita_exports.union(valita_exports.literal("permissions"), valita_exports.literal("client")).optional()
536
+ });
537
+ var correlatedSubquerySchema = correlatedSubquerySchemaOmitSubquery.extend({
538
+ subquery: valita_exports.lazy(() => astSchema)
539
+ });
540
+ var astSchema = readonlyObject({
541
+ schema: valita_exports.string().optional(),
542
+ table: valita_exports.string(),
543
+ alias: valita_exports.string().optional(),
544
+ where: conditionSchema.optional(),
545
+ related: readonlyArray(correlatedSubquerySchema).optional(),
546
+ limit: valita_exports.number().optional(),
547
+ orderBy: orderingSchema.optional(),
548
+ start: valita_exports.object({
549
+ row: rowSchema,
550
+ exclusive: valita_exports.boolean()
551
+ }).optional()
552
+ });
553
+ function transformAST(ast, transform) {
554
+ const { tableName, columnName } = transform;
555
+ const colName = (c) => columnName(ast.table, c);
556
+ const key = (table, k) => {
557
+ const serverKey = k.map((col) => columnName(table, col));
558
+ return mustCompoundKey(serverKey);
559
+ };
560
+ const where = ast.where ? transform.where(ast.where) : void 0;
561
+ const transformed = {
562
+ schema: ast.schema,
563
+ table: tableName(ast.table),
564
+ alias: ast.alias,
565
+ where: where ? transformWhere(where, ast.table, transform) : void 0,
566
+ related: ast.related ? transform.related(
567
+ ast.related.map(
568
+ (r) => ({
569
+ correlation: {
570
+ parentField: key(ast.table, r.correlation.parentField),
571
+ childField: key(r.subquery.table, r.correlation.childField)
572
+ },
573
+ hidden: r.hidden,
574
+ subquery: transformAST(r.subquery, transform),
575
+ system: r.system
576
+ })
577
+ )
578
+ ) : void 0,
579
+ start: ast.start ? {
580
+ ...ast.start,
581
+ row: Object.fromEntries(
582
+ Object.entries(ast.start.row).map(([col, val]) => [
583
+ colName(col),
584
+ val
585
+ ])
586
+ )
587
+ } : void 0,
588
+ limit: ast.limit,
589
+ orderBy: ast.orderBy?.map(([col, dir]) => [colName(col), dir])
590
+ };
591
+ return transformed;
592
+ }
593
+ function transformWhere(where, table, transform) {
594
+ const { columnName } = transform;
595
+ const condValue = (c) => c.type !== "column" ? c : { ...c, name: columnName(table, c.name) };
596
+ const key = (table2, k) => {
597
+ const serverKey = k.map((col) => columnName(table2, col));
598
+ return mustCompoundKey(serverKey);
599
+ };
600
+ if (where.type === "simple") {
601
+ return { ...where, left: condValue(where.left) };
602
+ } else if (where.type === "correlatedSubquery") {
603
+ const { correlation, subquery } = where.related;
604
+ return {
605
+ ...where,
606
+ related: {
607
+ ...where.related,
608
+ correlation: {
609
+ parentField: key(table, correlation.parentField),
610
+ childField: key(subquery.table, correlation.childField)
611
+ },
612
+ subquery: transformAST(subquery, transform)
613
+ }
614
+ };
615
+ }
616
+ return {
617
+ type: where.type,
618
+ conditions: transform.conditions(
619
+ where.conditions.map((c) => transformWhere(c, table, transform))
620
+ )
621
+ };
622
+ }
623
+ var normalizeCache = /* @__PURE__ */ new WeakMap();
624
+ var NORMALIZE_TRANSFORM = {
625
+ tableName: (t) => t,
626
+ columnName: (_, c) => c,
627
+ related: sortedRelated,
628
+ where: flattened,
629
+ conditions: (c) => c.sort(cmpCondition)
630
+ };
631
+ function normalizeAST(ast) {
632
+ let normalized = normalizeCache.get(ast);
633
+ if (!normalized) {
634
+ normalized = transformAST(ast, NORMALIZE_TRANSFORM);
635
+ normalizeCache.set(ast, normalized);
636
+ }
637
+ return normalized;
638
+ }
639
+ function mapAST(ast, mapper) {
640
+ return transformAST(ast, {
641
+ tableName: (table) => mapper.tableName(table),
642
+ columnName: (table, col) => mapper.columnName(table, col),
643
+ related: (r) => r,
644
+ where: (w) => w,
645
+ conditions: (c) => c
646
+ });
647
+ }
648
+ function mapCondition(cond, table, mapper) {
649
+ return transformWhere(cond, table, {
650
+ tableName: (table2) => mapper.tableName(table2),
651
+ columnName: (table2, col) => mapper.columnName(table2, col),
652
+ related: (r) => r,
653
+ where: (w) => w,
654
+ conditions: (c) => c
655
+ });
656
+ }
657
+ function sortedRelated(related) {
658
+ return related.sort(cmpRelated);
659
+ }
660
+ function cmpCondition(a, b) {
661
+ if (a.type === "simple") {
662
+ if (b.type !== "simple") {
663
+ return -1;
664
+ }
665
+ return compareValuePosition(a.left, b.left) || compareUTF8MaybeNull(a.op, b.op) || compareValuePosition(a.right, b.right);
666
+ }
667
+ if (b.type === "simple") {
668
+ return 1;
669
+ }
670
+ if (a.type === "correlatedSubquery") {
671
+ if (b.type !== "correlatedSubquery") {
672
+ return -1;
673
+ }
674
+ return cmpRelated(a.related, b.related) || compareUTF8MaybeNull(a.op, b.op);
675
+ }
676
+ if (b.type === "correlatedSubquery") {
677
+ return -1;
678
+ }
679
+ const val = compareUTF8MaybeNull(a.type, b.type);
680
+ if (val !== 0) {
681
+ return val;
682
+ }
683
+ for (let l = 0, r = 0; l < a.conditions.length && r < b.conditions.length; l++, r++) {
684
+ const val2 = cmpCondition(a.conditions[l], b.conditions[r]);
685
+ if (val2 !== 0) {
686
+ return val2;
687
+ }
688
+ }
689
+ return a.conditions.length - b.conditions.length;
690
+ }
691
+ function compareValuePosition(a, b) {
692
+ if (a.type !== b.type) {
693
+ return compareUTF8(a.type, b.type);
694
+ }
695
+ switch (a.type) {
696
+ case "literal":
697
+ assert(b.type === "literal");
698
+ return compareUTF8(String(a.value), String(b.value));
699
+ case "column":
700
+ assert(b.type === "column");
701
+ return compareUTF8(a.name, b.name);
702
+ case "static":
703
+ throw new Error(
704
+ "Static parameters should be resolved before normalization"
705
+ );
706
+ }
707
+ }
708
+ function cmpRelated(a, b) {
709
+ return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));
710
+ }
711
+ function flattened(cond) {
712
+ if (cond.type === "simple" || cond.type === "correlatedSubquery") {
713
+ return cond;
714
+ }
715
+ const conditions = defined(
716
+ cond.conditions.flatMap(
717
+ (c) => c.type === cond.type ? c.conditions.map((c2) => flattened(c2)) : flattened(c)
718
+ )
719
+ );
720
+ switch (conditions.length) {
721
+ case 0:
722
+ return void 0;
723
+ case 1:
724
+ return conditions[0];
725
+ default:
726
+ return {
727
+ type: cond.type,
728
+ conditions
729
+ };
730
+ }
731
+ }
732
+ function compareUTF8MaybeNull(a, b) {
733
+ if (a !== null && b !== null) {
734
+ return compareUTF8(a, b);
735
+ }
736
+ if (b !== null) {
737
+ return -1;
738
+ }
739
+ if (a !== null) {
740
+ return 1;
741
+ }
742
+ return 0;
743
+ }
744
+
745
+ // ../zero-schema/src/table-schema.ts
746
+ function isOneHop(r) {
747
+ return r.length === 1;
748
+ }
749
+ function isTwoHop(r) {
750
+ return r.length === 2;
751
+ }
752
+
753
+ // ../zql/src/query/query-impl.ts
754
+ import { resolver } from "@rocicorp/resolver";
755
+
756
+ // ../shared/src/hash.ts
757
+ import { xxHash32 } from "js-xxhash";
758
+ var h64 = (s) => hash(s, 2);
759
+ var h128 = (s) => hash(s, 4);
760
+ function hash(str, words) {
761
+ let hash2 = 0n;
762
+ for (let i = 0; i < words; i++) {
763
+ hash2 = (hash2 << 32n) + BigInt(xxHash32(str, i));
764
+ }
765
+ return hash2;
766
+ }
767
+
768
+ // ../zero-protocol/src/ast-hash.ts
769
+ var hashCache = /* @__PURE__ */ new WeakMap();
770
+ function hashOfAST(ast) {
771
+ const normalized = normalizeAST(ast);
772
+ const cached = hashCache.get(normalized);
773
+ if (cached) {
774
+ return cached;
775
+ }
776
+ const hash2 = h64(JSON.stringify(normalized)).toString(36);
777
+ hashCache.set(normalized, hash2);
778
+ return hash2;
779
+ }
780
+
781
+ // ../zql/src/ivm/operator.ts
782
+ var throwOutput = {
783
+ push(_change) {
784
+ throw new Error("Output not set");
785
+ }
786
+ };
787
+
788
+ // ../zql/src/ivm/stream.ts
789
+ function* take(stream, limit) {
790
+ if (limit < 1) {
791
+ return;
792
+ }
793
+ let count = 0;
794
+ for (const v2 of stream) {
795
+ yield v2;
796
+ if (++count === limit) {
797
+ break;
798
+ }
799
+ }
800
+ }
801
+ function first(stream) {
802
+ const it = stream[Symbol.iterator]();
803
+ const { value } = it.next();
804
+ it.return?.();
805
+ return value;
806
+ }
807
+
808
+ // ../zql/src/ivm/exists.ts
809
+ var Exists = class {
810
+ #input;
811
+ #relationshipName;
812
+ #storage;
813
+ #not;
814
+ #parentJoinKey;
815
+ #skipCache;
816
+ #output = throwOutput;
817
+ constructor(input, storage, relationshipName, parentJoinKey, type) {
818
+ this.#input = input;
819
+ this.#relationshipName = relationshipName;
820
+ this.#input.setOutput(this);
821
+ this.#storage = storage;
822
+ assert(this.#input.getSchema().relationships[relationshipName]);
823
+ this.#not = type === "NOT EXISTS";
824
+ this.#parentJoinKey = parentJoinKey;
825
+ this.#skipCache = areEqual(
826
+ parentJoinKey,
827
+ this.#input.getSchema().primaryKey
828
+ );
829
+ }
830
+ setOutput(output) {
831
+ this.#output = output;
832
+ }
833
+ destroy() {
834
+ this.#input.destroy();
835
+ }
836
+ getSchema() {
837
+ return this.#input.getSchema();
838
+ }
839
+ *fetch(req) {
840
+ for (const node of this.#input.fetch(req)) {
841
+ if (this.#filter(node)) {
842
+ yield node;
843
+ }
844
+ }
845
+ }
846
+ *cleanup(req) {
847
+ for (const node of this.#input.cleanup(req)) {
848
+ if (this.#filter(node)) {
849
+ yield node;
850
+ } else {
851
+ drainStreams(node);
852
+ }
853
+ this.#delSize(node);
854
+ }
855
+ }
856
+ push(change) {
857
+ switch (change.type) {
858
+ // add, remove and edit cannot change the size of the
859
+ // this.#relationshipName relationship, so simply #pushWithFilter
860
+ case "add":
861
+ case "edit": {
862
+ this.#pushWithFilter(change);
863
+ return;
864
+ }
865
+ case "remove": {
866
+ const size = this.#getSize(change.node);
867
+ if (size === void 0) {
868
+ return;
869
+ }
870
+ this.#pushWithFilter(change, size);
871
+ this.#delSize(change.node);
872
+ return;
873
+ }
874
+ case "child":
875
+ if (change.child.relationshipName !== this.#relationshipName || change.child.change.type === "edit" || change.child.change.type === "child") {
876
+ this.#pushWithFilter(change);
877
+ return;
878
+ }
879
+ switch (change.child.change.type) {
880
+ case "add": {
881
+ let size = this.#getSize(change.node);
882
+ if (size !== void 0) {
883
+ size++;
884
+ this.#setCachedSize(change.node, size);
885
+ this.#setSize(change.node, size);
886
+ } else {
887
+ size = this.#fetchSize(change.node);
888
+ }
889
+ if (size === 1) {
890
+ if (this.#not) {
891
+ this.#output.push({
892
+ type: "remove",
893
+ node: {
894
+ row: change.node.row,
895
+ relationships: {
896
+ ...change.node.relationships,
897
+ [this.#relationshipName]: () => []
898
+ }
899
+ }
900
+ });
901
+ } else {
902
+ this.#output.push({
903
+ type: "add",
904
+ node: change.node
905
+ });
906
+ }
907
+ } else {
908
+ this.#pushWithFilter(change, size);
909
+ }
910
+ return;
911
+ }
912
+ case "remove": {
913
+ let size = this.#getSize(change.node);
914
+ if (size !== void 0) {
915
+ if (size === 0) {
916
+ return;
917
+ }
918
+ size--;
919
+ this.#setCachedSize(change.node, size);
920
+ this.#setSize(change.node, size);
921
+ } else {
922
+ size = this.#fetchSize(change.node);
923
+ }
924
+ if (size === 0) {
925
+ if (this.#not) {
926
+ this.#output.push({
927
+ type: "add",
928
+ node: change.node
929
+ });
930
+ } else {
931
+ this.#output.push({
932
+ type: "remove",
933
+ node: {
934
+ row: change.node.row,
935
+ relationships: {
936
+ ...change.node.relationships,
937
+ [this.#relationshipName]: () => [
938
+ change.child.change.node
939
+ ]
940
+ }
941
+ }
942
+ });
943
+ }
944
+ } else {
945
+ this.#pushWithFilter(change, size);
946
+ }
947
+ return;
948
+ }
949
+ }
950
+ return;
951
+ default:
952
+ unreachable(change);
953
+ }
954
+ }
955
+ /**
956
+ * Returns whether or not the node's this.#relationshipName
957
+ * relationship passes the exist/not exists filter condition.
958
+ * If the optional `size` is passed it is used.
959
+ * Otherwise, if there is a stored size for the row it is used.
960
+ * Otherwise the size is computed by streaming the node's
961
+ * relationship with this.#relationshipName (this computed size is also
962
+ * stored).
963
+ */
964
+ #filter(node, size) {
965
+ const exists = (size ?? this.#getOrFetchSize(node)) > 0;
966
+ return this.#not ? !exists : exists;
967
+ }
968
+ /**
969
+ * Pushes a change if this.#filter is true for its row.
970
+ */
971
+ #pushWithFilter(change, size) {
972
+ if (this.#filter(change.node, size)) {
973
+ this.#output.push(change);
974
+ }
975
+ }
976
+ #getSize(node) {
977
+ return this.#storage.get(this.#makeSizeStorageKey(node));
978
+ }
979
+ #setSize(node, size) {
980
+ this.#storage.set(this.#makeSizeStorageKey(node), size);
981
+ }
982
+ #setCachedSize(node, size) {
983
+ if (this.#skipCache) {
984
+ return;
985
+ }
986
+ this.#storage.set(this.#makeCacheStorageKey(node), size);
987
+ }
988
+ #getCachedSize(node) {
989
+ if (this.#skipCache) {
990
+ return void 0;
991
+ }
992
+ return this.#storage.get(this.#makeCacheStorageKey(node));
993
+ }
994
+ #delSize(node) {
995
+ this.#storage.del(this.#makeSizeStorageKey(node));
996
+ if (!this.#skipCache) {
997
+ const cacheKey = this.#makeCacheStorageKey(node);
998
+ if (first(this.#storage.scan({ prefix: `${cacheKey}/` })) === void 0) {
999
+ this.#storage.del(cacheKey);
1000
+ }
1001
+ }
1002
+ }
1003
+ #getOrFetchSize(node) {
1004
+ const size = this.#getSize(node);
1005
+ if (size !== void 0) {
1006
+ return size;
1007
+ }
1008
+ return this.#fetchSize(node);
1009
+ }
1010
+ #fetchSize(node) {
1011
+ const cachedSize = this.#getCachedSize(node);
1012
+ if (cachedSize !== void 0) {
1013
+ this.#setSize(node, cachedSize);
1014
+ return cachedSize;
1015
+ }
1016
+ const relationship = node.relationships[this.#relationshipName];
1017
+ assert(relationship);
1018
+ let size = 0;
1019
+ for (const _relatedNode of relationship()) {
1020
+ size++;
1021
+ }
1022
+ this.#setCachedSize(node, size);
1023
+ this.#setSize(node, size);
1024
+ return size;
1025
+ }
1026
+ #makeCacheStorageKey(node) {
1027
+ return `row/${JSON.stringify(
1028
+ this.#getKeyValues(node, this.#parentJoinKey)
1029
+ )}`;
1030
+ }
1031
+ #makeSizeStorageKey(node) {
1032
+ return `row/${this.#skipCache ? "" : JSON.stringify(this.#getKeyValues(node, this.#parentJoinKey))}/${JSON.stringify(
1033
+ this.#getKeyValues(node, this.#input.getSchema().primaryKey)
1034
+ )}`;
1035
+ }
1036
+ #getKeyValues(node, def) {
1037
+ const values = [];
1038
+ for (const key of def) {
1039
+ values.push(normalizeUndefined(node.row[key]));
1040
+ }
1041
+ return values;
1042
+ }
1043
+ };
1044
+
1045
+ // ../shared/src/iterables.ts
1046
+ function* joinIterables(...iters) {
1047
+ for (const iter of iters) {
1048
+ yield* iter;
1049
+ }
1050
+ }
1051
+ function* filterIter(iter, p) {
1052
+ let index = 0;
1053
+ for (const t of iter) {
1054
+ if (p(t, index++)) {
1055
+ yield t;
1056
+ }
1057
+ }
1058
+ }
1059
+ function* mapIter(iter, f) {
1060
+ let index = 0;
1061
+ for (const t of iter) {
1062
+ yield f(t, index++);
1063
+ }
1064
+ }
1065
+ function first2(stream) {
1066
+ const it = stream[Symbol.iterator]();
1067
+ const { value } = it.next();
1068
+ it.return?.();
1069
+ return value;
1070
+ }
1071
+ var IterWrapper = class _IterWrapper {
1072
+ iter;
1073
+ constructor(iter) {
1074
+ this.iter = iter;
1075
+ }
1076
+ [Symbol.iterator]() {
1077
+ return this.iter[Symbol.iterator]();
1078
+ }
1079
+ map(f) {
1080
+ return new _IterWrapper(mapIter(this.iter, f));
1081
+ }
1082
+ filter(p) {
1083
+ return new _IterWrapper(filterIter(this.iter, p));
1084
+ }
1085
+ };
1086
+ function wrapIterable(iter) {
1087
+ return new IterWrapper(iter);
1088
+ }
1089
+ function* mergeIterables(iterables, comparator, distinct = false) {
1090
+ const iterators = iterables.map((i) => i[Symbol.iterator]());
1091
+ try {
1092
+ const current = iterators.map((i) => i.next());
1093
+ let lastYielded;
1094
+ while (current.some((c) => !c.done)) {
1095
+ const min = current.reduce(
1096
+ (acc, c, i) => {
1097
+ if (c.done) {
1098
+ return acc;
1099
+ }
1100
+ if (acc === void 0 || comparator(c.value, acc[0]) < 0) {
1101
+ return [c.value, i];
1102
+ }
1103
+ return acc;
1104
+ },
1105
+ void 0
1106
+ );
1107
+ assert(min !== void 0, "min is undefined");
1108
+ current[min[1]] = iterators[min[1]].next();
1109
+ if (lastYielded !== void 0 && distinct && comparator(lastYielded, min[0]) === 0) {
1110
+ continue;
1111
+ }
1112
+ lastYielded = min[0];
1113
+ yield min[0];
1114
+ }
1115
+ } finally {
1116
+ for (const it of iterators) {
1117
+ it.return?.();
1118
+ }
1119
+ }
1120
+ }
1121
+
1122
+ // ../zql/src/ivm/fan-in.ts
1123
+ var FanIn = class {
1124
+ #inputs;
1125
+ #fanOut;
1126
+ #schema;
1127
+ #output = throwOutput;
1128
+ constructor(fanOut, inputs) {
1129
+ this.#inputs = inputs;
1130
+ this.#schema = fanOut.getSchema();
1131
+ this.#fanOut = fanOut;
1132
+ for (const input of inputs) {
1133
+ input.setOutput(this);
1134
+ assert(this.#schema === input.getSchema(), `Schema mismatch in fan-in`);
1135
+ }
1136
+ }
1137
+ setOutput(output) {
1138
+ this.#output = output;
1139
+ }
1140
+ destroy() {
1141
+ for (const input of this.#inputs) {
1142
+ input.destroy();
1143
+ }
1144
+ }
1145
+ getSchema() {
1146
+ return this.#schema;
1147
+ }
1148
+ fetch(req) {
1149
+ return this.#fetchOrCleanup((input) => input.fetch(req));
1150
+ }
1151
+ cleanup(req) {
1152
+ return this.#fetchOrCleanup((input) => input.cleanup(req));
1153
+ }
1154
+ *#fetchOrCleanup(streamProvider) {
1155
+ const iterables = this.#inputs.map((input) => streamProvider(input));
1156
+ yield* mergeIterables(
1157
+ iterables,
1158
+ (l, r) => must(this.#schema).compareRows(l.row, r.row),
1159
+ true
1160
+ );
1161
+ }
1162
+ push(change) {
1163
+ this.#fanOut.onFanInReceivedPush();
1164
+ this.#output.push(change);
1165
+ }
1166
+ };
1167
+
1168
+ // ../zql/src/ivm/fan-out.ts
1169
+ var FanOut = class {
1170
+ #input;
1171
+ #outputs = [];
1172
+ // FanOut is paired with a FanIn.
1173
+ // Once FanIn has received a push from FanOut along
1174
+ // any branch, FanOut no longer needs to push that value
1175
+ // across the rest of its outputs..
1176
+ #fanInReceivedPush = false;
1177
+ #destroyCount = 0;
1178
+ constructor(input) {
1179
+ this.#input = input;
1180
+ input.setOutput(this);
1181
+ }
1182
+ setOutput(output) {
1183
+ this.#outputs.push(output);
1184
+ }
1185
+ destroy() {
1186
+ if (this.#destroyCount < this.#outputs.length) {
1187
+ if (this.#destroyCount === 0) {
1188
+ this.#input.destroy();
1189
+ }
1190
+ ++this.#destroyCount;
1191
+ } else {
1192
+ throw new Error("FanOut already destroyed once for each output");
1193
+ }
1194
+ }
1195
+ getSchema() {
1196
+ return this.#input.getSchema();
1197
+ }
1198
+ fetch(req) {
1199
+ return this.#input.fetch(req);
1200
+ }
1201
+ cleanup(req) {
1202
+ return this.#input.cleanup(req);
1203
+ }
1204
+ onFanInReceivedPush() {
1205
+ this.#fanInReceivedPush = true;
1206
+ }
1207
+ push(change) {
1208
+ this.#fanInReceivedPush = false;
1209
+ for (const out of this.#outputs) {
1210
+ out.push(change);
1211
+ if (this.#fanInReceivedPush) {
1212
+ return;
1213
+ }
1214
+ }
1215
+ }
1216
+ };
1217
+
1218
+ // ../zql/src/ivm/maybe-split-and-push-edit-change.ts
1219
+ function maybeSplitAndPushEditChange(change, predicate, output) {
1220
+ const oldWasPresent = predicate(change.oldNode.row);
1221
+ const newIsPresent = predicate(change.node.row);
1222
+ if (oldWasPresent && newIsPresent) {
1223
+ output.push(change);
1224
+ } else if (oldWasPresent && !newIsPresent) {
1225
+ output.push({
1226
+ type: "remove",
1227
+ node: change.oldNode
1228
+ });
1229
+ } else if (!oldWasPresent && newIsPresent) {
1230
+ output.push({
1231
+ type: "add",
1232
+ node: change.node
1233
+ });
1234
+ }
1235
+ }
1236
+
1237
+ // ../zql/src/ivm/filter-push.ts
1238
+ function filterPush(change, output, predicate) {
1239
+ if (!predicate) {
1240
+ output.push(change);
1241
+ return;
1242
+ }
1243
+ switch (change.type) {
1244
+ case "add":
1245
+ case "remove":
1246
+ if (predicate(change.node.row)) {
1247
+ output.push(change);
1248
+ }
1249
+ break;
1250
+ case "child":
1251
+ if (predicate(change.node.row)) {
1252
+ output.push(change);
1253
+ }
1254
+ break;
1255
+ case "edit":
1256
+ maybeSplitAndPushEditChange(change, predicate, output);
1257
+ break;
1258
+ default:
1259
+ unreachable(change);
1260
+ }
1261
+ }
1262
+
1263
+ // ../zql/src/ivm/filter.ts
1264
+ var Filter = class {
1265
+ #input;
1266
+ #predicate;
1267
+ #output = throwOutput;
1268
+ constructor(input, predicate) {
1269
+ this.#input = input;
1270
+ this.#predicate = predicate;
1271
+ input.setOutput(this);
1272
+ }
1273
+ setOutput(output) {
1274
+ this.#output = output;
1275
+ }
1276
+ destroy() {
1277
+ this.#input.destroy();
1278
+ }
1279
+ getSchema() {
1280
+ return this.#input.getSchema();
1281
+ }
1282
+ *fetch(req) {
1283
+ for (const node of this.#input.fetch(req)) {
1284
+ if (this.#predicate(node.row)) {
1285
+ yield node;
1286
+ }
1287
+ }
1288
+ }
1289
+ *cleanup(req) {
1290
+ for (const node of this.#input.cleanup(req)) {
1291
+ if (this.#predicate(node.row)) {
1292
+ yield node;
1293
+ } else {
1294
+ drainStreams(node);
1295
+ }
1296
+ }
1297
+ }
1298
+ push(change) {
1299
+ filterPush(change, this.#output, this.#predicate);
1300
+ }
1301
+ };
1302
+
1303
+ // ../zql/src/ivm/join.ts
1304
+ var Join = class {
1305
+ #parent;
1306
+ #child;
1307
+ #storage;
1308
+ #parentKey;
1309
+ #childKey;
1310
+ #relationshipName;
1311
+ #schema;
1312
+ #output = throwOutput;
1313
+ constructor({
1314
+ parent,
1315
+ child,
1316
+ storage,
1317
+ parentKey,
1318
+ childKey,
1319
+ relationshipName,
1320
+ hidden,
1321
+ system
1322
+ }) {
1323
+ assert(parent !== child, "Parent and child must be different operators");
1324
+ assert(
1325
+ parentKey.length === childKey.length,
1326
+ "The parentKey and childKey keys must have same length"
1327
+ );
1328
+ this.#parent = parent;
1329
+ this.#child = child;
1330
+ this.#storage = storage;
1331
+ this.#parentKey = parentKey;
1332
+ this.#childKey = childKey;
1333
+ this.#relationshipName = relationshipName;
1334
+ const parentSchema = parent.getSchema();
1335
+ const childSchema = child.getSchema();
1336
+ this.#schema = {
1337
+ ...parentSchema,
1338
+ relationships: {
1339
+ ...parentSchema.relationships,
1340
+ [relationshipName]: {
1341
+ ...childSchema,
1342
+ isHidden: hidden,
1343
+ system
1344
+ }
1345
+ }
1346
+ };
1347
+ parent.setOutput({
1348
+ push: (change) => this.#pushParent(change)
1349
+ });
1350
+ child.setOutput({
1351
+ push: (change) => this.#pushChild(change)
1352
+ });
1353
+ }
1354
+ destroy() {
1355
+ this.#parent.destroy();
1356
+ this.#child.destroy();
1357
+ }
1358
+ setOutput(output) {
1359
+ this.#output = output;
1360
+ }
1361
+ getSchema() {
1362
+ return this.#schema;
1363
+ }
1364
+ *fetch(req) {
1365
+ for (const parentNode of this.#parent.fetch(req)) {
1366
+ yield this.#processParentNode(
1367
+ parentNode.row,
1368
+ parentNode.relationships,
1369
+ "fetch"
1370
+ );
1371
+ }
1372
+ }
1373
+ *cleanup(req) {
1374
+ for (const parentNode of this.#parent.cleanup(req)) {
1375
+ yield this.#processParentNode(
1376
+ parentNode.row,
1377
+ parentNode.relationships,
1378
+ "cleanup"
1379
+ );
1380
+ }
1381
+ }
1382
+ #pushParent(change) {
1383
+ switch (change.type) {
1384
+ case "add":
1385
+ this.#output.push({
1386
+ type: "add",
1387
+ node: this.#processParentNode(
1388
+ change.node.row,
1389
+ change.node.relationships,
1390
+ "fetch"
1391
+ )
1392
+ });
1393
+ break;
1394
+ case "remove":
1395
+ this.#output.push({
1396
+ type: "remove",
1397
+ node: this.#processParentNode(
1398
+ change.node.row,
1399
+ change.node.relationships,
1400
+ "cleanup"
1401
+ )
1402
+ });
1403
+ break;
1404
+ case "child":
1405
+ this.#output.push({
1406
+ type: "child",
1407
+ node: this.#processParentNode(
1408
+ change.node.row,
1409
+ change.node.relationships,
1410
+ "fetch"
1411
+ ),
1412
+ child: change.child
1413
+ });
1414
+ break;
1415
+ case "edit": {
1416
+ if (rowEqualsForCompoundKey(
1417
+ change.oldNode.row,
1418
+ change.node.row,
1419
+ this.#parentKey
1420
+ )) {
1421
+ this.#output.push({
1422
+ type: "edit",
1423
+ oldNode: this.#processParentNode(
1424
+ change.oldNode.row,
1425
+ change.oldNode.relationships,
1426
+ "cleanup"
1427
+ ),
1428
+ node: this.#processParentNode(
1429
+ change.node.row,
1430
+ change.node.relationships,
1431
+ "fetch"
1432
+ )
1433
+ });
1434
+ } else {
1435
+ this.#pushParent({
1436
+ type: "remove",
1437
+ node: change.oldNode
1438
+ });
1439
+ this.#pushParent({
1440
+ type: "add",
1441
+ node: change.node
1442
+ });
1443
+ }
1444
+ break;
1445
+ }
1446
+ default:
1447
+ unreachable(change);
1448
+ }
1449
+ }
1450
+ #pushChild(change) {
1451
+ const pushChildChange = (childRow, change2) => {
1452
+ const parentNodes = this.#parent.fetch({
1453
+ constraint: Object.fromEntries(
1454
+ this.#parentKey.map((key, i) => [key, childRow[this.#childKey[i]]])
1455
+ )
1456
+ });
1457
+ for (const parentNode of parentNodes) {
1458
+ const childChange = {
1459
+ type: "child",
1460
+ node: this.#processParentNode(
1461
+ parentNode.row,
1462
+ parentNode.relationships,
1463
+ "fetch"
1464
+ ),
1465
+ child: {
1466
+ relationshipName: this.#relationshipName,
1467
+ change: change2
1468
+ }
1469
+ };
1470
+ this.#output.push(childChange);
1471
+ }
1472
+ };
1473
+ switch (change.type) {
1474
+ case "add":
1475
+ case "remove":
1476
+ pushChildChange(change.node.row, change);
1477
+ break;
1478
+ case "child":
1479
+ pushChildChange(change.node.row, change);
1480
+ break;
1481
+ case "edit": {
1482
+ const childRow = change.node.row;
1483
+ const oldChildRow = change.oldNode.row;
1484
+ if (rowEqualsForCompoundKey(oldChildRow, childRow, this.#childKey)) {
1485
+ pushChildChange(childRow, change);
1486
+ } else {
1487
+ pushChildChange(oldChildRow, {
1488
+ type: "remove",
1489
+ node: change.oldNode
1490
+ });
1491
+ pushChildChange(childRow, {
1492
+ type: "add",
1493
+ node: change.node
1494
+ });
1495
+ }
1496
+ break;
1497
+ }
1498
+ default:
1499
+ unreachable(change);
1500
+ }
1501
+ }
1502
+ #processParentNode(parentNodeRow, parentNodeRelations, mode) {
1503
+ let method = mode;
1504
+ let storageUpdated = false;
1505
+ const childStream = () => {
1506
+ if (!storageUpdated) {
1507
+ if (mode === "cleanup") {
1508
+ this.#storage.del(
1509
+ makeStorageKey(
1510
+ this.#parentKey,
1511
+ this.#parent.getSchema().primaryKey,
1512
+ parentNodeRow
1513
+ )
1514
+ );
1515
+ const empty = [
1516
+ ...take(
1517
+ this.#storage.scan({
1518
+ prefix: makeStorageKeyPrefix(parentNodeRow, this.#parentKey)
1519
+ }),
1520
+ 1
1521
+ )
1522
+ ].length === 0;
1523
+ method = empty ? "cleanup" : "fetch";
1524
+ }
1525
+ storageUpdated = true;
1526
+ if (mode === "fetch") {
1527
+ this.#storage.set(
1528
+ makeStorageKey(
1529
+ this.#parentKey,
1530
+ this.#parent.getSchema().primaryKey,
1531
+ parentNodeRow
1532
+ ),
1533
+ true
1534
+ );
1535
+ }
1536
+ }
1537
+ return this.#child[method]({
1538
+ constraint: Object.fromEntries(
1539
+ this.#childKey.map((key, i) => [
1540
+ key,
1541
+ parentNodeRow[this.#parentKey[i]]
1542
+ ])
1543
+ )
1544
+ });
1545
+ };
1546
+ return {
1547
+ row: parentNodeRow,
1548
+ relationships: {
1549
+ ...parentNodeRelations,
1550
+ [this.#relationshipName]: childStream
1551
+ }
1552
+ };
1553
+ }
1554
+ };
1555
+ function makeStorageKeyForValues(values) {
1556
+ const json = JSON.stringify(["pKeySet", ...values]);
1557
+ return json.substring(1, json.length - 1) + ",";
1558
+ }
1559
+ function makeStorageKeyPrefix(row, key) {
1560
+ return makeStorageKeyForValues(key.map((k) => row[k]));
1561
+ }
1562
+ function makeStorageKey(key, primaryKey, row) {
1563
+ const values = key.map((k) => row[k]);
1564
+ for (const key2 of primaryKey) {
1565
+ values.push(row[key2]);
1566
+ }
1567
+ return makeStorageKeyForValues(values);
1568
+ }
1569
+ function rowEqualsForCompoundKey(a, b, key) {
1570
+ for (let i = 0; i < key.length; i++) {
1571
+ if (!valuesEqual(a[key[i]], b[key[i]])) {
1572
+ return false;
1573
+ }
1574
+ }
1575
+ return true;
1576
+ }
1577
+
1578
+ // ../zql/src/ivm/skip.ts
1579
+ var Skip = class {
1580
+ #input;
1581
+ #bound;
1582
+ #comparator;
1583
+ #output = throwOutput;
1584
+ constructor(input, bound) {
1585
+ this.#input = input;
1586
+ this.#bound = bound;
1587
+ this.#comparator = input.getSchema().compareRows;
1588
+ input.setOutput(this);
1589
+ }
1590
+ getSchema() {
1591
+ return this.#input.getSchema();
1592
+ }
1593
+ fetch(req) {
1594
+ return this.#fetchOrCleanup("fetch", req);
1595
+ }
1596
+ cleanup(req) {
1597
+ return this.#fetchOrCleanup("fetch", req);
1598
+ }
1599
+ *#fetchOrCleanup(method, req) {
1600
+ const start = this.#getStart(req);
1601
+ if (start === "empty") {
1602
+ return;
1603
+ }
1604
+ const nodes = this.#input[method]({ ...req, start });
1605
+ if (!req.reverse) {
1606
+ yield* nodes;
1607
+ return;
1608
+ }
1609
+ for (const node of nodes) {
1610
+ if (!this.#shouldBePresent(node.row)) {
1611
+ return;
1612
+ }
1613
+ yield node;
1614
+ }
1615
+ }
1616
+ setOutput(output) {
1617
+ this.#output = output;
1618
+ }
1619
+ destroy() {
1620
+ this.#input.destroy();
1621
+ }
1622
+ #shouldBePresent(row) {
1623
+ const cmp2 = this.#comparator(this.#bound.row, row);
1624
+ return cmp2 < 0 || cmp2 === 0 && !this.#bound.exclusive;
1625
+ }
1626
+ push(change) {
1627
+ const shouldBePresent = (row) => this.#shouldBePresent(row);
1628
+ if (change.type === "edit") {
1629
+ maybeSplitAndPushEditChange(change, shouldBePresent, this.#output);
1630
+ return;
1631
+ }
1632
+ change;
1633
+ if (shouldBePresent(change.node.row)) {
1634
+ this.#output.push(change);
1635
+ }
1636
+ }
1637
+ #getStart(req) {
1638
+ const boundStart = {
1639
+ row: this.#bound.row,
1640
+ basis: this.#bound.exclusive ? "after" : "at"
1641
+ };
1642
+ if (!req.start) {
1643
+ if (req.reverse) {
1644
+ return void 0;
1645
+ }
1646
+ return boundStart;
1647
+ }
1648
+ const cmp2 = this.#comparator(this.#bound.row, req.start.row);
1649
+ if (!req.reverse) {
1650
+ if (cmp2 > 0) {
1651
+ return boundStart;
1652
+ }
1653
+ if (cmp2 === 0) {
1654
+ if (this.#bound.exclusive || req.start.basis === "after") {
1655
+ return {
1656
+ row: this.#bound.row,
1657
+ basis: "after"
1658
+ };
1659
+ }
1660
+ return boundStart;
1661
+ }
1662
+ return req.start;
1663
+ }
1664
+ req.reverse;
1665
+ if (cmp2 > 0) {
1666
+ return "empty";
1667
+ }
1668
+ if (cmp2 === 0) {
1669
+ if (!this.#bound.exclusive && req.start.basis === "at") {
1670
+ return boundStart;
1671
+ }
1672
+ return "empty";
1673
+ }
1674
+ return req.start;
1675
+ }
1676
+ };
1677
+
1678
+ // ../zql/src/ivm/take.ts
1679
+ var MAX_BOUND_KEY = "maxBound";
1680
+ var Take = class {
1681
+ #input;
1682
+ #storage;
1683
+ #limit;
1684
+ #partitionKey;
1685
+ #partitionKeyComparator;
1686
+ #output = throwOutput;
1687
+ constructor(input, storage, limit, partitionKey) {
1688
+ assert(limit >= 0);
1689
+ assertOrderingIncludesPK(
1690
+ input.getSchema().sort,
1691
+ input.getSchema().primaryKey
1692
+ );
1693
+ input.setOutput(this);
1694
+ this.#input = input;
1695
+ this.#storage = storage;
1696
+ this.#limit = limit;
1697
+ this.#partitionKey = partitionKey;
1698
+ this.#partitionKeyComparator = partitionKey && makePartitionKeyComparator(partitionKey);
1699
+ }
1700
+ setOutput(output) {
1701
+ this.#output = output;
1702
+ }
1703
+ getSchema() {
1704
+ return this.#input.getSchema();
1705
+ }
1706
+ *fetch(req) {
1707
+ if (!this.#partitionKey || req.constraint && constraintMatchesPartitionKey(req.constraint, this.#partitionKey)) {
1708
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
1709
+ const takeState = this.#storage.get(takeStateKey);
1710
+ if (!takeState) {
1711
+ yield* this.#initialFetch(req);
1712
+ return;
1713
+ }
1714
+ if (takeState.bound === void 0) {
1715
+ return;
1716
+ }
1717
+ for (const inputNode of this.#input.fetch(req)) {
1718
+ if (this.getSchema().compareRows(takeState.bound, inputNode.row) < 0) {
1719
+ return;
1720
+ }
1721
+ yield inputNode;
1722
+ }
1723
+ return;
1724
+ }
1725
+ const maxBound = this.#storage.get(MAX_BOUND_KEY);
1726
+ if (maxBound === void 0) {
1727
+ return;
1728
+ }
1729
+ for (const inputNode of this.#input.fetch(req)) {
1730
+ if (this.getSchema().compareRows(inputNode.row, maxBound) > 0) {
1731
+ return;
1732
+ }
1733
+ const takeStateKey = getTakeStateKey(this.#partitionKey, inputNode.row);
1734
+ const takeState = this.#storage.get(takeStateKey);
1735
+ if (takeState?.bound !== void 0 && this.getSchema().compareRows(takeState.bound, inputNode.row) >= 0) {
1736
+ yield inputNode;
1737
+ }
1738
+ }
1739
+ }
1740
+ *#initialFetch(req) {
1741
+ assert(req.start === void 0);
1742
+ assert(!req.reverse);
1743
+ assert(constraintMatchesPartitionKey(req.constraint, this.#partitionKey));
1744
+ if (this.#limit === 0) {
1745
+ return;
1746
+ }
1747
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
1748
+ assert(this.#storage.get(takeStateKey) === void 0);
1749
+ let size = 0;
1750
+ let bound;
1751
+ let downstreamEarlyReturn = true;
1752
+ let exceptionThrown = false;
1753
+ try {
1754
+ for (const inputNode of this.#input.fetch(req)) {
1755
+ yield inputNode;
1756
+ bound = inputNode.row;
1757
+ size++;
1758
+ if (size === this.#limit) {
1759
+ break;
1760
+ }
1761
+ }
1762
+ downstreamEarlyReturn = false;
1763
+ } catch (e) {
1764
+ exceptionThrown = true;
1765
+ throw e;
1766
+ } finally {
1767
+ if (!exceptionThrown) {
1768
+ this.#setTakeState(
1769
+ takeStateKey,
1770
+ size,
1771
+ bound,
1772
+ this.#storage.get(MAX_BOUND_KEY)
1773
+ );
1774
+ assert(
1775
+ !downstreamEarlyReturn,
1776
+ "Unexpected early return prevented full hydration"
1777
+ );
1778
+ }
1779
+ }
1780
+ }
1781
+ *cleanup(req) {
1782
+ assert(req.start === void 0);
1783
+ assert(constraintMatchesPartitionKey(req.constraint, this.#partitionKey));
1784
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
1785
+ this.#storage.del(takeStateKey);
1786
+ let size = 0;
1787
+ for (const inputNode of this.#input.cleanup(req)) {
1788
+ if (size === this.#limit) {
1789
+ return;
1790
+ }
1791
+ size++;
1792
+ yield inputNode;
1793
+ }
1794
+ }
1795
+ #getStateAndConstraint(row) {
1796
+ const takeStateKey = getTakeStateKey(this.#partitionKey, row);
1797
+ const takeState = this.#storage.get(takeStateKey);
1798
+ let maxBound;
1799
+ let constraint;
1800
+ if (takeState) {
1801
+ maxBound = this.#storage.get(MAX_BOUND_KEY);
1802
+ constraint = this.#partitionKey && Object.fromEntries(
1803
+ this.#partitionKey.map((key) => [key, row[key]])
1804
+ );
1805
+ }
1806
+ return { takeState, takeStateKey, maxBound, constraint };
1807
+ }
1808
+ push(change) {
1809
+ if (change.type === "edit") {
1810
+ this.#pushEditChange(change);
1811
+ return;
1812
+ }
1813
+ const { takeState, takeStateKey, maxBound, constraint } = this.#getStateAndConstraint(change.node.row);
1814
+ if (!takeState) {
1815
+ return;
1816
+ }
1817
+ const { compareRows } = this.getSchema();
1818
+ if (change.type === "add") {
1819
+ if (takeState.size < this.#limit) {
1820
+ this.#setTakeState(
1821
+ takeStateKey,
1822
+ takeState.size + 1,
1823
+ takeState.bound === void 0 || compareRows(takeState.bound, change.node.row) < 0 ? change.node.row : takeState.bound,
1824
+ maxBound
1825
+ );
1826
+ this.#output.push(change);
1827
+ return;
1828
+ }
1829
+ if (takeState.bound === void 0 || compareRows(change.node.row, takeState.bound) >= 0) {
1830
+ return;
1831
+ }
1832
+ let beforeBoundNode;
1833
+ let boundNode;
1834
+ if (this.#limit === 1) {
1835
+ boundNode = must(
1836
+ first(
1837
+ this.#input.fetch({
1838
+ start: {
1839
+ row: takeState.bound,
1840
+ basis: "at"
1841
+ },
1842
+ constraint
1843
+ })
1844
+ )
1845
+ );
1846
+ } else {
1847
+ [boundNode, beforeBoundNode] = take(
1848
+ this.#input.fetch({
1849
+ start: {
1850
+ row: takeState.bound,
1851
+ basis: "at"
1852
+ },
1853
+ constraint,
1854
+ reverse: true
1855
+ }),
1856
+ 2
1857
+ );
1858
+ }
1859
+ const removeChange = {
1860
+ type: "remove",
1861
+ node: boundNode
1862
+ };
1863
+ this.#setTakeState(
1864
+ takeStateKey,
1865
+ takeState.size,
1866
+ beforeBoundNode === void 0 || compareRows(change.node.row, beforeBoundNode.row) > 0 ? change.node.row : beforeBoundNode.row,
1867
+ maxBound
1868
+ );
1869
+ this.#output.push(removeChange);
1870
+ this.#output.push(change);
1871
+ } else if (change.type === "remove") {
1872
+ if (takeState.bound === void 0) {
1873
+ return;
1874
+ }
1875
+ const compToBound = compareRows(change.node.row, takeState.bound);
1876
+ if (compToBound > 0) {
1877
+ return;
1878
+ }
1879
+ const [beforeBoundNode] = take(
1880
+ this.#input.fetch({
1881
+ start: {
1882
+ row: takeState.bound,
1883
+ basis: "after"
1884
+ },
1885
+ constraint,
1886
+ reverse: true
1887
+ }),
1888
+ 1
1889
+ );
1890
+ let newBound;
1891
+ if (beforeBoundNode) {
1892
+ const push = compareRows(beforeBoundNode.row, takeState.bound) > 0;
1893
+ newBound = {
1894
+ node: beforeBoundNode,
1895
+ push
1896
+ };
1897
+ }
1898
+ if (!newBound?.push) {
1899
+ for (const node of this.#input.fetch({
1900
+ start: {
1901
+ row: takeState.bound,
1902
+ basis: "at"
1903
+ },
1904
+ constraint
1905
+ })) {
1906
+ const push = compareRows(node.row, takeState.bound) > 0;
1907
+ newBound = {
1908
+ node,
1909
+ push
1910
+ };
1911
+ if (push) {
1912
+ break;
1913
+ }
1914
+ }
1915
+ }
1916
+ if (newBound?.push) {
1917
+ this.#setTakeState(
1918
+ takeStateKey,
1919
+ takeState.size,
1920
+ newBound.node.row,
1921
+ maxBound
1922
+ );
1923
+ this.#output.push(change);
1924
+ this.#output.push({
1925
+ type: "add",
1926
+ node: newBound.node
1927
+ });
1928
+ return;
1929
+ }
1930
+ this.#setTakeState(
1931
+ takeStateKey,
1932
+ takeState.size - 1,
1933
+ newBound?.node.row,
1934
+ maxBound
1935
+ );
1936
+ this.#output.push(change);
1937
+ } else if (change.type === "child") {
1938
+ if (takeState.bound && compareRows(change.node.row, takeState.bound) <= 0) {
1939
+ this.#output.push(change);
1940
+ }
1941
+ }
1942
+ }
1943
+ #pushEditChange(change) {
1944
+ if (this.#partitionKeyComparator && this.#partitionKeyComparator(change.oldNode.row, change.node.row) !== 0) {
1945
+ this.push({
1946
+ type: "remove",
1947
+ node: change.oldNode
1948
+ });
1949
+ this.push({
1950
+ type: "add",
1951
+ node: change.node
1952
+ });
1953
+ return;
1954
+ }
1955
+ const { takeState, takeStateKey, maxBound, constraint } = this.#getStateAndConstraint(change.oldNode.row);
1956
+ if (!takeState) {
1957
+ return;
1958
+ }
1959
+ assert(takeState.bound, "Bound should be set");
1960
+ const { compareRows } = this.getSchema();
1961
+ const oldCmp = compareRows(change.oldNode.row, takeState.bound);
1962
+ const newCmp = compareRows(change.node.row, takeState.bound);
1963
+ const replaceBoundAndForwardChange = () => {
1964
+ this.#setTakeState(
1965
+ takeStateKey,
1966
+ takeState.size,
1967
+ change.node.row,
1968
+ maxBound
1969
+ );
1970
+ this.#output.push(change);
1971
+ };
1972
+ if (oldCmp === 0) {
1973
+ if (newCmp === 0) {
1974
+ this.#output.push(change);
1975
+ return;
1976
+ }
1977
+ if (newCmp < 0) {
1978
+ if (this.#limit === 1) {
1979
+ replaceBoundAndForwardChange();
1980
+ return;
1981
+ }
1982
+ const beforeBoundNode = must(
1983
+ first(
1984
+ this.#input.fetch({
1985
+ start: {
1986
+ row: takeState.bound,
1987
+ basis: "after"
1988
+ },
1989
+ constraint,
1990
+ reverse: true
1991
+ })
1992
+ )
1993
+ );
1994
+ this.#setTakeState(
1995
+ takeStateKey,
1996
+ takeState.size,
1997
+ beforeBoundNode.row,
1998
+ maxBound
1999
+ );
2000
+ this.#output.push(change);
2001
+ return;
2002
+ }
2003
+ assert(newCmp > 0);
2004
+ const newBoundNode = must(
2005
+ first(
2006
+ this.#input.fetch({
2007
+ start: {
2008
+ row: takeState.bound,
2009
+ basis: "at"
2010
+ },
2011
+ constraint
2012
+ })
2013
+ )
2014
+ );
2015
+ if (compareRows(newBoundNode.row, change.node.row) === 0) {
2016
+ replaceBoundAndForwardChange();
2017
+ return;
2018
+ }
2019
+ this.#setTakeState(
2020
+ takeStateKey,
2021
+ takeState.size,
2022
+ newBoundNode.row,
2023
+ maxBound
2024
+ );
2025
+ this.#output.push({
2026
+ type: "remove",
2027
+ node: change.oldNode
2028
+ });
2029
+ this.#output.push({
2030
+ type: "add",
2031
+ node: newBoundNode
2032
+ });
2033
+ return;
2034
+ }
2035
+ if (oldCmp > 0) {
2036
+ assert(newCmp !== 0, "Invalid state. Row has duplicate primary key");
2037
+ if (newCmp > 0) {
2038
+ return;
2039
+ }
2040
+ assert(newCmp < 0);
2041
+ const [oldBoundNode, newBoundNode] = take(
2042
+ this.#input.fetch({
2043
+ start: {
2044
+ row: takeState.bound,
2045
+ basis: "at"
2046
+ },
2047
+ constraint,
2048
+ reverse: true
2049
+ }),
2050
+ 2
2051
+ );
2052
+ this.#setTakeState(
2053
+ takeStateKey,
2054
+ takeState.size,
2055
+ newBoundNode.row,
2056
+ maxBound
2057
+ );
2058
+ this.#output.push({
2059
+ type: "remove",
2060
+ node: oldBoundNode
2061
+ });
2062
+ this.#output.push({
2063
+ type: "add",
2064
+ node: change.node
2065
+ });
2066
+ return;
2067
+ }
2068
+ if (oldCmp < 0) {
2069
+ assert(newCmp !== 0, "Invalid state. Row has duplicate primary key");
2070
+ if (newCmp < 0) {
2071
+ this.#output.push(change);
2072
+ return;
2073
+ }
2074
+ assert(newCmp > 0);
2075
+ const afterBoundNode = must(
2076
+ first(
2077
+ this.#input.fetch({
2078
+ start: {
2079
+ row: takeState.bound,
2080
+ basis: "after"
2081
+ },
2082
+ constraint
2083
+ })
2084
+ )
2085
+ );
2086
+ if (compareRows(afterBoundNode.row, change.node.row) === 0) {
2087
+ replaceBoundAndForwardChange();
2088
+ return;
2089
+ }
2090
+ this.#setTakeState(
2091
+ takeStateKey,
2092
+ takeState.size,
2093
+ afterBoundNode.row,
2094
+ maxBound
2095
+ );
2096
+ this.#output.push({
2097
+ type: "remove",
2098
+ node: change.oldNode
2099
+ });
2100
+ this.#output.push({
2101
+ type: "add",
2102
+ node: afterBoundNode
2103
+ });
2104
+ return;
2105
+ }
2106
+ unreachable();
2107
+ }
2108
+ #setTakeState(takeStateKey, size, bound, maxBound) {
2109
+ this.#storage.set(takeStateKey, {
2110
+ size,
2111
+ bound
2112
+ });
2113
+ if (bound !== void 0 && (maxBound === void 0 || this.getSchema().compareRows(bound, maxBound) > 0)) {
2114
+ this.#storage.set(MAX_BOUND_KEY, bound);
2115
+ }
2116
+ }
2117
+ destroy() {
2118
+ this.#input.destroy();
2119
+ }
2120
+ };
2121
+ function getTakeStateKey(partitionKey, rowOrConstraint) {
2122
+ const partitionValues = [];
2123
+ if (partitionKey && rowOrConstraint) {
2124
+ for (const key of partitionKey) {
2125
+ partitionValues.push(rowOrConstraint[key]);
2126
+ }
2127
+ }
2128
+ return JSON.stringify(["take", ...partitionValues]);
2129
+ }
2130
+ function constraintMatchesPartitionKey(constraint, partitionKey) {
2131
+ if (constraint === void 0 || partitionKey === void 0) {
2132
+ return constraint === partitionKey;
2133
+ }
2134
+ if (partitionKey.length !== Object.keys(constraint).length) {
2135
+ return false;
2136
+ }
2137
+ for (const key of partitionKey) {
2138
+ if (!hasOwn(constraint, key)) {
2139
+ return false;
2140
+ }
2141
+ }
2142
+ return true;
2143
+ }
2144
+ function makePartitionKeyComparator(partitionKey) {
2145
+ return (a, b) => {
2146
+ for (const key of partitionKey) {
2147
+ const cmp2 = compareValues(a[key], b[key]);
2148
+ if (cmp2 !== 0) {
2149
+ return cmp2;
2150
+ }
2151
+ }
2152
+ return 0;
2153
+ };
2154
+ }
2155
+
2156
+ // ../zql/src/builder/like.ts
2157
+ function getLikePredicate(pattern, flags) {
2158
+ const op = getLikeOp(String(pattern), flags);
2159
+ return (lhs) => {
2160
+ assertString(lhs);
2161
+ return op(String(lhs));
2162
+ };
2163
+ }
2164
+ function getLikeOp(pattern, flags) {
2165
+ if (!/_|%|\\/.test(pattern)) {
2166
+ if (flags === "i") {
2167
+ const rhsLower = pattern.toLowerCase();
2168
+ return (lhs) => lhs.toLowerCase() === rhsLower;
2169
+ }
2170
+ return (lhs) => lhs === pattern;
2171
+ }
2172
+ const re = patternToRegExp(pattern, flags);
2173
+ return (lhs) => re.test(lhs);
2174
+ }
2175
+ var specialCharsRe = /[$()*+.?[\]\\^{|}]/;
2176
+ function patternToRegExp(source, flags = "") {
2177
+ let pattern = "^";
2178
+ for (let i = 0; i < source.length; i++) {
2179
+ let c = source[i];
2180
+ switch (c) {
2181
+ case "%":
2182
+ pattern += ".*";
2183
+ break;
2184
+ case "_":
2185
+ pattern += ".";
2186
+ break;
2187
+ // @ts-expect-error fallthrough
2188
+ case "\\":
2189
+ if (i === source.length - 1) {
2190
+ throw new Error("LIKE pattern must not end with escape character");
2191
+ }
2192
+ i++;
2193
+ c = source[i];
2194
+ // fall through
2195
+ default:
2196
+ if (specialCharsRe.test(c)) {
2197
+ pattern += "\\";
2198
+ }
2199
+ pattern += c;
2200
+ break;
2201
+ }
2202
+ }
2203
+ return new RegExp(pattern + "$", flags + "m");
2204
+ }
2205
+
2206
+ // ../zql/src/builder/filter.ts
2207
+ function createPredicate(condition) {
2208
+ if (condition.type !== "simple") {
2209
+ const predicates = condition.conditions.map((c) => createPredicate(c));
2210
+ return condition.type === "and" ? (row) => {
2211
+ for (const predicate of predicates) {
2212
+ if (!predicate(row)) {
2213
+ return false;
2214
+ }
2215
+ }
2216
+ return true;
2217
+ } : (row) => {
2218
+ for (const predicate of predicates) {
2219
+ if (predicate(row)) {
2220
+ return true;
2221
+ }
2222
+ }
2223
+ return false;
2224
+ };
2225
+ }
2226
+ const { left } = condition;
2227
+ const { right } = condition;
2228
+ assert(
2229
+ right.type !== "static",
2230
+ "static values should be resolved before creating predicates"
2231
+ );
2232
+ assert(
2233
+ left.type !== "static",
2234
+ "static values should be resolved before creating predicates"
2235
+ );
2236
+ switch (condition.op) {
2237
+ case "IS":
2238
+ case "IS NOT": {
2239
+ const impl2 = createIsPredicate(right.value, condition.op);
2240
+ if (left.type === "literal") {
2241
+ const result = impl2(left.value);
2242
+ return () => result;
2243
+ }
2244
+ return (row) => impl2(row[left.name]);
2245
+ }
2246
+ }
2247
+ if (right.value === null || right.value === void 0) {
2248
+ return (_row) => false;
2249
+ }
2250
+ const impl = createPredicateImpl(right.value, condition.op);
2251
+ if (left.type === "literal") {
2252
+ if (left.value === null || left.value === void 0) {
2253
+ return (_row) => false;
2254
+ }
2255
+ const result = impl(left.value);
2256
+ return () => result;
2257
+ }
2258
+ return (row) => {
2259
+ const lhs = row[left.name];
2260
+ if (lhs === null || lhs === void 0) {
2261
+ return false;
2262
+ }
2263
+ return impl(lhs);
2264
+ };
2265
+ }
2266
+ function createIsPredicate(rhs, operator) {
2267
+ switch (operator) {
2268
+ case "IS":
2269
+ return (lhs) => lhs === rhs;
2270
+ case "IS NOT":
2271
+ return (lhs) => lhs !== rhs;
2272
+ }
2273
+ }
2274
+ function createPredicateImpl(rhs, operator) {
2275
+ switch (operator) {
2276
+ case "=":
2277
+ return (lhs) => lhs === rhs;
2278
+ case "!=":
2279
+ return (lhs) => lhs !== rhs;
2280
+ case "<":
2281
+ return (lhs) => lhs < rhs;
2282
+ case "<=":
2283
+ return (lhs) => lhs <= rhs;
2284
+ case ">":
2285
+ return (lhs) => lhs > rhs;
2286
+ case ">=":
2287
+ return (lhs) => lhs >= rhs;
2288
+ case "LIKE":
2289
+ return getLikePredicate(rhs, "");
2290
+ case "NOT LIKE":
2291
+ return not(getLikePredicate(rhs, ""));
2292
+ case "ILIKE":
2293
+ return getLikePredicate(rhs, "i");
2294
+ case "NOT ILIKE":
2295
+ return not(getLikePredicate(rhs, "i"));
2296
+ case "IN": {
2297
+ assert(Array.isArray(rhs));
2298
+ const set = new Set(rhs);
2299
+ return (lhs) => set.has(lhs);
2300
+ }
2301
+ case "NOT IN": {
2302
+ assert(Array.isArray(rhs));
2303
+ const set = new Set(rhs);
2304
+ return (lhs) => !set.has(lhs);
2305
+ }
2306
+ default:
2307
+ operator;
2308
+ throw new Error(`Unexpected operator: ${operator}`);
2309
+ }
2310
+ }
2311
+ function not(f) {
2312
+ return (lhs) => !f(lhs);
2313
+ }
2314
+ function transformFilters(filters) {
2315
+ if (!filters) {
2316
+ return { filters: void 0, conditionsRemoved: false };
2317
+ }
2318
+ switch (filters.type) {
2319
+ case "simple":
2320
+ return { filters, conditionsRemoved: false };
2321
+ case "correlatedSubquery":
2322
+ return { filters: void 0, conditionsRemoved: true };
2323
+ case "and": {
2324
+ const transformedConditions = [];
2325
+ for (const cond of filters.conditions) {
2326
+ assert(cond.type === "simple" || cond.type === "correlatedSubquery");
2327
+ if (cond.type === "simple") {
2328
+ transformedConditions.push(cond);
2329
+ }
2330
+ }
2331
+ const conditionsRemoved = transformedConditions.length !== filters.conditions.length;
2332
+ if (transformedConditions.length === 0) {
2333
+ return { filters: void 0, conditionsRemoved };
2334
+ }
2335
+ if (transformedConditions.length === 1) {
2336
+ return {
2337
+ filters: transformedConditions[0],
2338
+ conditionsRemoved
2339
+ };
2340
+ }
2341
+ return {
2342
+ filters: {
2343
+ type: "and",
2344
+ conditions: transformedConditions
2345
+ },
2346
+ conditionsRemoved
2347
+ };
2348
+ }
2349
+ case "or": {
2350
+ const transformedConditions = [];
2351
+ let conditionsRemoved = false;
2352
+ for (const cond of filters.conditions) {
2353
+ assert(cond.type !== "or");
2354
+ const transformed = transformFilters(cond);
2355
+ if (transformed.filters === void 0) {
2356
+ return { filters: void 0, conditionsRemoved: true };
2357
+ }
2358
+ conditionsRemoved = conditionsRemoved || transformed.conditionsRemoved;
2359
+ transformedConditions.push(transformed.filters);
2360
+ }
2361
+ return {
2362
+ filters: { type: "or", conditions: transformedConditions },
2363
+ conditionsRemoved
2364
+ };
2365
+ }
2366
+ default:
2367
+ unreachable(filters);
2368
+ }
2369
+ }
2370
+
2371
+ // ../zql/src/builder/builder.ts
2372
+ function buildPipeline(ast, delegate) {
2373
+ return buildPipelineInternal(ast, delegate);
2374
+ }
2375
+ function buildPipelineInternal(ast, delegate, partitionKey) {
2376
+ const source = delegate.getSource(ast.table);
2377
+ if (!source) {
2378
+ throw new Error(`Source not found: ${ast.table}`);
2379
+ }
2380
+ const conn = source.connect(must(ast.orderBy), ast.where);
2381
+ let end = conn;
2382
+ const { fullyAppliedFilters } = conn;
2383
+ ast = uniquifyCorrelatedSubqueryConditionAliases(ast);
2384
+ if (ast.start) {
2385
+ end = new Skip(end, ast.start);
2386
+ }
2387
+ for (const csq of gatherCorrelatedSubqueryQueriesFromCondition(ast.where)) {
2388
+ end = applyCorrelatedSubQuery(csq, delegate, end);
2389
+ }
2390
+ if (ast.where && !fullyAppliedFilters) {
2391
+ end = applyWhere(end, ast.where, delegate);
2392
+ }
2393
+ if (ast.limit) {
2394
+ end = new Take(end, delegate.createStorage(), ast.limit, partitionKey);
2395
+ }
2396
+ if (ast.related) {
2397
+ for (const csq of ast.related) {
2398
+ end = applyCorrelatedSubQuery(csq, delegate, end);
2399
+ }
2400
+ }
2401
+ return end;
2402
+ }
2403
+ function applyWhere(input, condition, delegate) {
2404
+ switch (condition.type) {
2405
+ case "and":
2406
+ return applyAnd(input, condition, delegate);
2407
+ case "or":
2408
+ return applyOr(input, condition, delegate);
2409
+ case "correlatedSubquery":
2410
+ return applyCorrelatedSubqueryCondition(input, condition, delegate);
2411
+ case "simple":
2412
+ return applySimpleCondition(input, condition);
2413
+ }
2414
+ }
2415
+ function applyAnd(input, condition, delegate) {
2416
+ for (const subCondition of condition.conditions) {
2417
+ input = applyWhere(input, subCondition, delegate);
2418
+ }
2419
+ return input;
2420
+ }
2421
+ function applyOr(input, condition, delegate) {
2422
+ const [subqueryConditions, otherConditions] = groupSubqueryConditions(condition);
2423
+ if (subqueryConditions.length === 0) {
2424
+ return new Filter(
2425
+ input,
2426
+ createPredicate({
2427
+ type: "or",
2428
+ conditions: otherConditions
2429
+ })
2430
+ );
2431
+ }
2432
+ const fanOut = new FanOut(input);
2433
+ const branches = subqueryConditions.map(
2434
+ (subCondition) => applyWhere(fanOut, subCondition, delegate)
2435
+ );
2436
+ if (otherConditions.length > 0) {
2437
+ branches.push(
2438
+ new Filter(
2439
+ fanOut,
2440
+ createPredicate({
2441
+ type: "or",
2442
+ conditions: otherConditions
2443
+ })
2444
+ )
2445
+ );
2446
+ }
2447
+ return new FanIn(fanOut, branches);
2448
+ }
2449
+ function groupSubqueryConditions(condition) {
2450
+ const partitioned = [[], []];
2451
+ for (const subCondition of condition.conditions) {
2452
+ if (isNotAndDoesNotContainSubquery(subCondition)) {
2453
+ partitioned[1].push(subCondition);
2454
+ } else {
2455
+ partitioned[0].push(subCondition);
2456
+ }
2457
+ }
2458
+ return partitioned;
2459
+ }
2460
+ function isNotAndDoesNotContainSubquery(condition) {
2461
+ if (condition.type === "correlatedSubquery") {
2462
+ return false;
2463
+ }
2464
+ if (condition.type === "and") {
2465
+ return condition.conditions.every(isNotAndDoesNotContainSubquery);
2466
+ }
2467
+ assert(condition.type !== "or", "where conditions are expected to be in DNF");
2468
+ return true;
2469
+ }
2470
+ function applySimpleCondition(input, condition) {
2471
+ return new Filter(input, createPredicate(condition));
2472
+ }
2473
+ function applyCorrelatedSubQuery(sq, delegate, end) {
2474
+ assert(sq.subquery.alias, "Subquery must have an alias");
2475
+ const child = buildPipelineInternal(
2476
+ sq.subquery,
2477
+ delegate,
2478
+ sq.correlation.childField
2479
+ );
2480
+ end = new Join({
2481
+ parent: end,
2482
+ child,
2483
+ storage: delegate.createStorage(),
2484
+ parentKey: sq.correlation.parentField,
2485
+ childKey: sq.correlation.childField,
2486
+ relationshipName: sq.subquery.alias,
2487
+ hidden: sq.hidden ?? false,
2488
+ system: sq.system ?? "client"
2489
+ });
2490
+ return end;
2491
+ }
2492
+ function applyCorrelatedSubqueryCondition(input, condition, delegate) {
2493
+ assert(condition.op === "EXISTS" || condition.op === "NOT EXISTS");
2494
+ return new Exists(
2495
+ input,
2496
+ delegate.createStorage(),
2497
+ must(condition.related.subquery.alias),
2498
+ condition.related.correlation.parentField,
2499
+ condition.op
2500
+ );
2501
+ }
2502
+ function gatherCorrelatedSubqueryQueriesFromCondition(condition) {
2503
+ const csqs = [];
2504
+ const gather = (condition2) => {
2505
+ if (condition2.type === "correlatedSubquery") {
2506
+ assert(condition2.op === "EXISTS" || condition2.op === "NOT EXISTS");
2507
+ csqs.push({
2508
+ ...condition2.related,
2509
+ subquery: {
2510
+ ...condition2.related.subquery,
2511
+ limit: condition2.related.system === "permissions" ? PERMISSIONS_EXISTS_LIMIT : EXISTS_LIMIT
2512
+ }
2513
+ });
2514
+ return;
2515
+ }
2516
+ if (condition2.type === "and" || condition2.type === "or") {
2517
+ for (const c of condition2.conditions) {
2518
+ gather(c);
2519
+ }
2520
+ return;
2521
+ }
2522
+ };
2523
+ if (condition) {
2524
+ gather(condition);
2525
+ }
2526
+ return csqs;
2527
+ }
2528
+ var EXISTS_LIMIT = 3;
2529
+ var PERMISSIONS_EXISTS_LIMIT = 1;
2530
+ function assertOrderingIncludesPK(ordering, pk) {
2531
+ const orderingFields = ordering.map(([field]) => field);
2532
+ const missingFields = pk.filter((pkField) => !orderingFields.includes(pkField));
2533
+ if (missingFields.length > 0) {
2534
+ throw new Error(
2535
+ `Ordering must include all primary key fields. Missing: ${missingFields.join(
2536
+ ", "
2537
+ )}. ZQL automatically appends primary key fields to the ordering if they are missing
2538
+ so a common cause of this error is a casing mismatch between Postgres and ZQL.
2539
+ E.g., "userid" vs "userID".
2540
+ You may want to add double-quotes around your Postgres column names to prevent Postgres from lower-casing them:
2541
+ https://www.postgresql.org/docs/current/sql-syntax-lexical.htm`
2542
+ );
2543
+ }
2544
+ }
2545
+ function uniquifyCorrelatedSubqueryConditionAliases(ast) {
2546
+ if (!ast.where) {
2547
+ return ast;
2548
+ }
2549
+ const { where } = ast;
2550
+ if (where.type !== "and" && where.type !== "or") {
2551
+ return ast;
2552
+ }
2553
+ let count = 0;
2554
+ const uniquifyCorrelatedSubquery = (csqc) => ({
2555
+ ...csqc,
2556
+ related: {
2557
+ ...csqc.related,
2558
+ subquery: {
2559
+ ...csqc.related.subquery,
2560
+ alias: (csqc.related.subquery.alias ?? "") + "_" + count++
2561
+ }
2562
+ }
2563
+ });
2564
+ const uniquifyAnd = (and2) => {
2565
+ const conds2 = [];
2566
+ for (const cond of and2.conditions) {
2567
+ if (cond.type === "correlatedSubquery") {
2568
+ conds2.push(uniquifyCorrelatedSubquery(cond));
2569
+ } else {
2570
+ conds2.push(cond);
2571
+ }
2572
+ }
2573
+ return {
2574
+ ...and2,
2575
+ conditions: conds2
2576
+ };
2577
+ };
2578
+ if (where.type === "and") {
2579
+ return {
2580
+ ...ast,
2581
+ where: uniquifyAnd(where)
2582
+ };
2583
+ }
2584
+ const conds = [];
2585
+ for (const cond of where.conditions) {
2586
+ if (cond.type === "simple") {
2587
+ conds.push(cond);
2588
+ } else if (cond.type === "correlatedSubquery") {
2589
+ conds.push(uniquifyCorrelatedSubquery(cond));
2590
+ } else if (cond.type === "and") {
2591
+ conds.push(uniquifyAnd(cond));
2592
+ }
2593
+ }
2594
+ return {
2595
+ ...ast,
2596
+ where: {
2597
+ ...where,
2598
+ conditions: conds
2599
+ }
2600
+ };
2601
+ }
2602
+
2603
+ // ../zql/src/ivm/array-view.ts
2604
+ var ArrayView = class {
2605
+ #input;
2606
+ #listeners = /* @__PURE__ */ new Set();
2607
+ #schema;
2608
+ #format;
2609
+ // Synthetic "root" entry that has a single "" relationship, so that we can
2610
+ // treat all changes, including the root change, generically.
2611
+ #root;
2612
+ onDestroy;
2613
+ #dirty = false;
2614
+ #complete = false;
2615
+ constructor(input, format = { singular: false, relationships: {} }, queryComplete = true) {
2616
+ this.#input = input;
2617
+ this.#schema = input.getSchema();
2618
+ this.#format = format;
2619
+ this.#root = { "": format.singular ? void 0 : [] };
2620
+ input.setOutput(this);
2621
+ if (queryComplete === true) {
2622
+ this.#complete = true;
2623
+ } else {
2624
+ void queryComplete.then(() => {
2625
+ this.#complete = true;
2626
+ this.#fireListeners();
2627
+ });
2628
+ }
2629
+ this.#hydrate();
2630
+ }
2631
+ get data() {
2632
+ return this.#root[""];
2633
+ }
2634
+ addListener(listener) {
2635
+ assert(!this.#listeners.has(listener), "Listener already registered");
2636
+ this.#listeners.add(listener);
2637
+ this.#fireListener(listener);
2638
+ return () => {
2639
+ this.#listeners.delete(listener);
2640
+ };
2641
+ }
2642
+ #fireListeners() {
2643
+ for (const listener of this.#listeners) {
2644
+ this.#fireListener(listener);
2645
+ }
2646
+ }
2647
+ #fireListener(listener) {
2648
+ listener(
2649
+ this.data,
2650
+ this.#complete ? "complete" : "unknown"
2651
+ );
2652
+ }
2653
+ destroy() {
2654
+ this.onDestroy?.();
2655
+ }
2656
+ #hydrate() {
2657
+ this.#dirty = true;
2658
+ for (const node of this.#input.fetch({})) {
2659
+ applyChange(
2660
+ this.#root,
2661
+ { type: "add", node },
2662
+ this.#schema,
2663
+ "",
2664
+ this.#format
2665
+ );
2666
+ }
2667
+ this.flush();
2668
+ }
2669
+ push(change) {
2670
+ this.#dirty = true;
2671
+ applyChange(this.#root, change, this.#schema, "", this.#format);
2672
+ }
2673
+ flush() {
2674
+ if (!this.#dirty) {
2675
+ return;
2676
+ }
2677
+ this.#dirty = false;
2678
+ this.#fireListeners();
2679
+ }
2680
+ };
2681
+
2682
+ // ../zql/src/query/expression.ts
2683
+ var ExpressionBuilder = class {
2684
+ #exists;
2685
+ constructor(exists) {
2686
+ this.#exists = exists;
2687
+ this.exists = this.exists.bind(this);
2688
+ }
2689
+ get eb() {
2690
+ return this;
2691
+ }
2692
+ cmp(field, opOrValue, value) {
2693
+ return cmp(field, opOrValue, value);
2694
+ }
2695
+ cmpLit(left, op, right) {
2696
+ return {
2697
+ type: "simple",
2698
+ left: isParameterReference(left) ? left[toStaticParam]() : { type: "literal", value: left },
2699
+ right: isParameterReference(right) ? right[toStaticParam]() : { type: "literal", value: right },
2700
+ op
2701
+ };
2702
+ }
2703
+ and = and;
2704
+ or = or;
2705
+ not = not2;
2706
+ exists(relationship, cb) {
2707
+ return this.#exists(relationship, cb);
2708
+ }
2709
+ };
2710
+ function and(...conditions) {
2711
+ const expressions = filterTrue(filterUndefined(conditions));
2712
+ if (expressions.length === 1) {
2713
+ return expressions[0];
2714
+ }
2715
+ if (expressions.some(isAlwaysFalse)) {
2716
+ return FALSE;
2717
+ }
2718
+ return { type: "and", conditions: expressions };
2719
+ }
2720
+ function or(...conditions) {
2721
+ const expressions = filterFalse(filterUndefined(conditions));
2722
+ if (expressions.length === 1) {
2723
+ return expressions[0];
2724
+ }
2725
+ if (expressions.some(isAlwaysTrue)) {
2726
+ return TRUE;
2727
+ }
2728
+ return { type: "or", conditions: expressions };
2729
+ }
2730
+ function not2(expression) {
2731
+ switch (expression.type) {
2732
+ case "and":
2733
+ return {
2734
+ type: "or",
2735
+ conditions: expression.conditions.map(not2)
2736
+ };
2737
+ case "or":
2738
+ return {
2739
+ type: "and",
2740
+ conditions: expression.conditions.map(not2)
2741
+ };
2742
+ case "correlatedSubquery":
2743
+ return {
2744
+ type: "correlatedSubquery",
2745
+ related: expression.related,
2746
+ op: negateOperator(expression.op)
2747
+ };
2748
+ case "simple":
2749
+ return {
2750
+ type: "simple",
2751
+ op: negateOperator(expression.op),
2752
+ left: expression.left,
2753
+ right: expression.right
2754
+ };
2755
+ }
2756
+ }
2757
+ function cmp(field, opOrValue, value) {
2758
+ let op;
2759
+ if (value === void 0) {
2760
+ value = opOrValue;
2761
+ op = "=";
2762
+ } else {
2763
+ op = opOrValue;
2764
+ }
2765
+ return {
2766
+ type: "simple",
2767
+ left: { type: "column", name: field },
2768
+ right: isParameterReference(value) ? value[toStaticParam]() : { type: "literal", value },
2769
+ op
2770
+ };
2771
+ }
2772
+ function isParameterReference(value) {
2773
+ return value !== null && typeof value === "object" && value[toStaticParam];
2774
+ }
2775
+ var TRUE = {
2776
+ type: "and",
2777
+ conditions: []
2778
+ };
2779
+ var FALSE = {
2780
+ type: "or",
2781
+ conditions: []
2782
+ };
2783
+ function isAlwaysTrue(condition) {
2784
+ return condition.type === "and" && condition.conditions.length === 0;
2785
+ }
2786
+ function isAlwaysFalse(condition) {
2787
+ return condition.type === "or" && condition.conditions.length === 0;
2788
+ }
2789
+ function flatten(type, conditions) {
2790
+ const flattened2 = [];
2791
+ for (const c of conditions) {
2792
+ if (c.type === type) {
2793
+ flattened2.push(...c.conditions);
2794
+ } else {
2795
+ flattened2.push(c);
2796
+ }
2797
+ }
2798
+ return flattened2;
2799
+ }
2800
+ var negateSimpleOperatorMap = {
2801
+ ["="]: "!=",
2802
+ ["!="]: "=",
2803
+ ["<"]: ">=",
2804
+ [">"]: "<=",
2805
+ [">="]: "<",
2806
+ ["<="]: ">",
2807
+ ["IN"]: "NOT IN",
2808
+ ["NOT IN"]: "IN",
2809
+ ["LIKE"]: "NOT LIKE",
2810
+ ["NOT LIKE"]: "LIKE",
2811
+ ["ILIKE"]: "NOT ILIKE",
2812
+ ["NOT ILIKE"]: "ILIKE",
2813
+ ["IS"]: "IS NOT",
2814
+ ["IS NOT"]: "IS"
2815
+ };
2816
+ var negateOperatorMap = {
2817
+ ...negateSimpleOperatorMap,
2818
+ ["EXISTS"]: "NOT EXISTS",
2819
+ ["NOT EXISTS"]: "EXISTS"
2820
+ };
2821
+ function negateOperator(op) {
2822
+ return must(negateOperatorMap[op]);
2823
+ }
2824
+ function filterUndefined(array5) {
2825
+ return array5.filter((e) => e !== void 0);
2826
+ }
2827
+ function filterTrue(conditions) {
2828
+ return conditions.filter((c) => !isAlwaysTrue(c));
2829
+ }
2830
+ function filterFalse(conditions) {
2831
+ return conditions.filter((c) => !isAlwaysFalse(c));
2832
+ }
2833
+
2834
+ // ../zql/src/query/dnf.ts
2835
+ function dnf(condition) {
2836
+ return unwrap(dnfInner(condition));
2837
+ }
2838
+ function dnfInner(condition) {
2839
+ switch (condition.type) {
2840
+ case "simple":
2841
+ case "correlatedSubquery":
2842
+ return { type: "or", conditions: [condition] };
2843
+ case "and":
2844
+ return distributeAnd(condition.conditions.map(dnfInner));
2845
+ case "or":
2846
+ return {
2847
+ type: "or",
2848
+ conditions: flatten(
2849
+ "or",
2850
+ condition.conditions.map(dnfInner).flatMap((c) => c.conditions)
2851
+ )
2852
+ };
2853
+ default:
2854
+ unreachable(condition);
2855
+ }
2856
+ }
2857
+ function distributeAnd(conditions) {
2858
+ if (conditions.length === 0) {
2859
+ return { type: "or", conditions: [TRUE] };
2860
+ }
2861
+ return conditions.reduce((acc, orCondition) => {
2862
+ const newConditions = [];
2863
+ for (const accCondition of acc.conditions) {
2864
+ for (const orSubCondition of orCondition.conditions) {
2865
+ newConditions.push({
2866
+ type: "and",
2867
+ conditions: [accCondition, orSubCondition]
2868
+ });
2869
+ }
2870
+ }
2871
+ return {
2872
+ type: "or",
2873
+ conditions: flatten("or", newConditions)
2874
+ };
2875
+ });
2876
+ }
2877
+ function unwrap(c) {
2878
+ if (c.type === "simple" || c.type === "correlatedSubquery") {
2879
+ return c;
2880
+ }
2881
+ if (c.conditions.length === 1) {
2882
+ return unwrap(c.conditions[0]);
2883
+ }
2884
+ return { type: c.type, conditions: flatten(c.type, c.conditions.map(unwrap)) };
2885
+ }
2886
+
2887
+ // ../zql/src/query/query-impl.ts
2888
+ var astForTestingSymbol = Symbol();
2889
+ function newQuery(delegate, schema, table) {
2890
+ return new QueryImpl(delegate, schema, table);
2891
+ }
2892
+ function newQueryWithDetails(delegate, schema, tableName, ast, ttl, format) {
2893
+ return new QueryImpl(delegate, schema, tableName, ast, ttl, format);
2894
+ }
2895
+ function staticParam(anchorClass, field) {
2896
+ return {
2897
+ type: "static",
2898
+ anchor: anchorClass,
2899
+ // for backwards compatibility
2900
+ field: field.length === 1 ? field[0] : field
2901
+ };
2902
+ }
2903
+ var SUBQ_PREFIX = "zsubq_";
2904
+ var AbstractQuery = class {
2905
+ #schema;
2906
+ #tableName;
2907
+ #ast;
2908
+ #ttl;
2909
+ #format;
2910
+ #hash = "";
2911
+ constructor(schema, tableName, ast = { table: tableName }, ttl, format) {
2912
+ this.#schema = schema;
2913
+ this.#tableName = tableName;
2914
+ this.#ast = ast;
2915
+ this.#ttl = ttl;
2916
+ this.#format = format ?? { singular: false, relationships: {} };
2917
+ }
2918
+ get format() {
2919
+ return this.#format;
2920
+ }
2921
+ // Not part of Query or QueryInternal interface
2922
+ get [astForTestingSymbol]() {
2923
+ return this.#ast;
2924
+ }
2925
+ hash() {
2926
+ if (!this.#hash) {
2927
+ const ast = this._completeAst();
2928
+ const hash2 = hashOfAST(ast);
2929
+ this.#hash = hash2;
2930
+ }
2931
+ return this.#hash;
2932
+ }
2933
+ one() {
2934
+ return this._newQuery(
2935
+ this.#schema,
2936
+ this.#tableName,
2937
+ {
2938
+ ...this.#ast,
2939
+ limit: 1
2940
+ },
2941
+ this.#ttl,
2942
+ {
2943
+ ...this.#format,
2944
+ singular: true
2945
+ }
2946
+ );
2947
+ }
2948
+ whereExists(relationship, cb) {
2949
+ return this.where(({ exists }) => exists(relationship, cb));
2950
+ }
2951
+ related(relationship, cb) {
2952
+ if (relationship.startsWith(SUBQ_PREFIX)) {
2953
+ throw new Error(
2954
+ `Relationship names may not start with "${SUBQ_PREFIX}". That is a reserved prefix.`
2955
+ );
2956
+ }
2957
+ cb = cb ?? ((q) => q);
2958
+ const related = this.#schema.relationships[this.#tableName][relationship];
2959
+ assert(related, "Invalid relationship");
2960
+ if (isOneHop(related)) {
2961
+ const { destSchema, destField, sourceField, cardinality } = related[0];
2962
+ const sq = cb(
2963
+ this._newQuery(
2964
+ this.#schema,
2965
+ destSchema,
2966
+ {
2967
+ table: destSchema,
2968
+ alias: relationship
2969
+ },
2970
+ this.#ttl,
2971
+ {
2972
+ relationships: {},
2973
+ singular: cardinality === "one"
2974
+ }
2975
+ )
2976
+ );
2977
+ assert(
2978
+ isCompoundKey(sourceField),
2979
+ "The source of a relationship must specify at last 1 field"
2980
+ );
2981
+ assert(
2982
+ isCompoundKey(destField),
2983
+ "The destination of a relationship must specify at last 1 field"
2984
+ );
2985
+ assert(
2986
+ sourceField.length === destField.length,
2987
+ "The source and destination of a relationship must have the same number of fields"
2988
+ );
2989
+ return this._newQuery(
2990
+ this.#schema,
2991
+ this.#tableName,
2992
+ {
2993
+ ...this.#ast,
2994
+ related: [
2995
+ ...this.#ast.related ?? [],
2996
+ {
2997
+ system: this._system,
2998
+ correlation: {
2999
+ parentField: sourceField,
3000
+ childField: destField
3001
+ },
3002
+ subquery: addPrimaryKeysToAst(
3003
+ this.#schema.tables[destSchema],
3004
+ sq.#ast
3005
+ )
3006
+ }
3007
+ ]
3008
+ },
3009
+ this.#ttl,
3010
+ {
3011
+ ...this.#format,
3012
+ relationships: {
3013
+ ...this.#format.relationships,
3014
+ [relationship]: sq.#format
3015
+ }
3016
+ }
3017
+ );
3018
+ }
3019
+ if (isTwoHop(related)) {
3020
+ assert(related.length === 2, "Invalid relationship");
3021
+ const [firstRelation, secondRelation] = related;
3022
+ const { destSchema } = secondRelation;
3023
+ const junctionSchema = firstRelation.destSchema;
3024
+ const sq = cb(
3025
+ this._newQuery(
3026
+ this.#schema,
3027
+ destSchema,
3028
+ {
3029
+ table: destSchema,
3030
+ alias: relationship
3031
+ },
3032
+ this.#ttl,
3033
+ {
3034
+ relationships: {},
3035
+ singular: secondRelation.cardinality === "one"
3036
+ }
3037
+ )
3038
+ );
3039
+ assert(isCompoundKey(firstRelation.sourceField), "Invalid relationship");
3040
+ assert(isCompoundKey(firstRelation.destField), "Invalid relationship");
3041
+ assert(isCompoundKey(secondRelation.sourceField), "Invalid relationship");
3042
+ assert(isCompoundKey(secondRelation.destField), "Invalid relationship");
3043
+ return this._newQuery(
3044
+ this.#schema,
3045
+ this.#tableName,
3046
+ {
3047
+ ...this.#ast,
3048
+ related: [
3049
+ ...this.#ast.related ?? [],
3050
+ {
3051
+ system: this._system,
3052
+ correlation: {
3053
+ parentField: firstRelation.sourceField,
3054
+ childField: firstRelation.destField
3055
+ },
3056
+ hidden: true,
3057
+ subquery: {
3058
+ table: junctionSchema,
3059
+ alias: relationship,
3060
+ orderBy: addPrimaryKeys(
3061
+ this.#schema.tables[junctionSchema],
3062
+ void 0
3063
+ ),
3064
+ related: [
3065
+ {
3066
+ system: this._system,
3067
+ correlation: {
3068
+ parentField: secondRelation.sourceField,
3069
+ childField: secondRelation.destField
3070
+ },
3071
+ subquery: addPrimaryKeysToAst(
3072
+ this.#schema.tables[destSchema],
3073
+ sq.#ast
3074
+ )
3075
+ }
3076
+ ]
3077
+ }
3078
+ }
3079
+ ]
3080
+ },
3081
+ this.#ttl,
3082
+ {
3083
+ ...this.#format,
3084
+ relationships: {
3085
+ ...this.#format.relationships,
3086
+ [relationship]: sq.#format
3087
+ }
3088
+ }
3089
+ );
3090
+ }
3091
+ throw new Error(`Invalid relationship ${relationship}`);
3092
+ }
3093
+ where(fieldOrExpressionFactory, opOrValue, value) {
3094
+ let cond;
3095
+ if (typeof fieldOrExpressionFactory === "function") {
3096
+ cond = fieldOrExpressionFactory(
3097
+ new ExpressionBuilder(this._exists)
3098
+ );
3099
+ } else {
3100
+ assert(opOrValue !== void 0, "Invalid condition");
3101
+ cond = cmp(fieldOrExpressionFactory, opOrValue, value);
3102
+ }
3103
+ const existingWhere = this.#ast.where;
3104
+ if (existingWhere) {
3105
+ cond = and(existingWhere, cond);
3106
+ }
3107
+ return this._newQuery(
3108
+ this.#schema,
3109
+ this.#tableName,
3110
+ {
3111
+ ...this.#ast,
3112
+ where: dnf(cond)
3113
+ },
3114
+ this.#ttl,
3115
+ this.#format
3116
+ );
3117
+ }
3118
+ start(row, opts) {
3119
+ return this._newQuery(
3120
+ this.#schema,
3121
+ this.#tableName,
3122
+ {
3123
+ ...this.#ast,
3124
+ start: {
3125
+ row,
3126
+ exclusive: !opts?.inclusive
3127
+ }
3128
+ },
3129
+ this.#ttl,
3130
+ this.#format
3131
+ );
3132
+ }
3133
+ limit(limit) {
3134
+ if (limit < 0) {
3135
+ throw new Error("Limit must be non-negative");
3136
+ }
3137
+ if ((limit | 0) !== limit) {
3138
+ throw new Error("Limit must be an integer");
3139
+ }
3140
+ return this._newQuery(
3141
+ this.#schema,
3142
+ this.#tableName,
3143
+ {
3144
+ ...this.#ast,
3145
+ limit
3146
+ },
3147
+ this.#ttl,
3148
+ this.#format
3149
+ );
3150
+ }
3151
+ orderBy(field, direction) {
3152
+ return this._newQuery(
3153
+ this.#schema,
3154
+ this.#tableName,
3155
+ {
3156
+ ...this.#ast,
3157
+ orderBy: [...this.#ast.orderBy ?? [], [field, direction]]
3158
+ },
3159
+ this.#ttl,
3160
+ this.#format
3161
+ );
3162
+ }
3163
+ _exists = (relationship, cb = (q) => q) => {
3164
+ const related = this.#schema.relationships[this.#tableName][relationship];
3165
+ assert(related, "Invalid relationship");
3166
+ if (isOneHop(related)) {
3167
+ const { destSchema, sourceField, destField } = related[0];
3168
+ assert(isCompoundKey(sourceField), "Invalid relationship");
3169
+ assert(isCompoundKey(destField), "Invalid relationship");
3170
+ const sq = cb(
3171
+ this._newQuery(
3172
+ this.#schema,
3173
+ destSchema,
3174
+ {
3175
+ table: destSchema,
3176
+ alias: `${SUBQ_PREFIX}${relationship}`
3177
+ },
3178
+ this.#ttl,
3179
+ void 0
3180
+ )
3181
+ );
3182
+ return {
3183
+ type: "correlatedSubquery",
3184
+ related: {
3185
+ system: this._system,
3186
+ correlation: {
3187
+ parentField: sourceField,
3188
+ childField: destField
3189
+ },
3190
+ subquery: addPrimaryKeysToAst(
3191
+ this.#schema.tables[destSchema],
3192
+ sq.#ast
3193
+ )
3194
+ },
3195
+ op: "EXISTS"
3196
+ };
3197
+ }
3198
+ if (isTwoHop(related)) {
3199
+ assert(related.length === 2, "Invalid relationship");
3200
+ const [firstRelation, secondRelation] = related;
3201
+ assert(isCompoundKey(firstRelation.sourceField), "Invalid relationship");
3202
+ assert(isCompoundKey(firstRelation.destField), "Invalid relationship");
3203
+ assert(isCompoundKey(secondRelation.sourceField), "Invalid relationship");
3204
+ assert(isCompoundKey(secondRelation.destField), "Invalid relationship");
3205
+ const { destSchema } = secondRelation;
3206
+ const junctionSchema = firstRelation.destSchema;
3207
+ const queryToDest = cb(
3208
+ this._newQuery(
3209
+ this.#schema,
3210
+ destSchema,
3211
+ {
3212
+ table: destSchema,
3213
+ alias: `${SUBQ_PREFIX}${relationship}`
3214
+ },
3215
+ this.#ttl,
3216
+ void 0
3217
+ )
3218
+ );
3219
+ return {
3220
+ type: "correlatedSubquery",
3221
+ related: {
3222
+ system: this._system,
3223
+ correlation: {
3224
+ parentField: firstRelation.sourceField,
3225
+ childField: firstRelation.destField
3226
+ },
3227
+ subquery: {
3228
+ table: junctionSchema,
3229
+ alias: `${SUBQ_PREFIX}${relationship}`,
3230
+ orderBy: addPrimaryKeys(
3231
+ this.#schema.tables[junctionSchema],
3232
+ void 0
3233
+ ),
3234
+ where: {
3235
+ type: "correlatedSubquery",
3236
+ related: {
3237
+ system: this._system,
3238
+ correlation: {
3239
+ parentField: secondRelation.sourceField,
3240
+ childField: secondRelation.destField
3241
+ },
3242
+ subquery: addPrimaryKeysToAst(
3243
+ this.#schema.tables[destSchema],
3244
+ queryToDest.#ast
3245
+ )
3246
+ },
3247
+ op: "EXISTS"
3248
+ }
3249
+ }
3250
+ },
3251
+ op: "EXISTS"
3252
+ };
3253
+ }
3254
+ throw new Error(`Invalid relationship ${relationship}`);
3255
+ };
3256
+ #completedAST;
3257
+ _completeAst() {
3258
+ if (!this.#completedAST) {
3259
+ const finalOrderBy = addPrimaryKeys(
3260
+ this.#schema.tables[this.#tableName],
3261
+ this.#ast.orderBy
3262
+ );
3263
+ if (this.#ast.start) {
3264
+ const { row } = this.#ast.start;
3265
+ const narrowedRow = {};
3266
+ for (const [field] of finalOrderBy) {
3267
+ narrowedRow[field] = row[field];
3268
+ }
3269
+ this.#completedAST = {
3270
+ ...this.#ast,
3271
+ start: {
3272
+ ...this.#ast.start,
3273
+ row: narrowedRow
3274
+ },
3275
+ orderBy: finalOrderBy
3276
+ };
3277
+ } else {
3278
+ this.#completedAST = {
3279
+ ...this.#ast,
3280
+ orderBy: addPrimaryKeys(
3281
+ this.#schema.tables[this.#tableName],
3282
+ this.#ast.orderBy
3283
+ )
3284
+ };
3285
+ }
3286
+ }
3287
+ return this.#completedAST;
3288
+ }
3289
+ };
3290
+ var completedAstSymbol = Symbol();
3291
+ var QueryImpl = class extends AbstractQuery {
3292
+ #delegate;
3293
+ constructor(delegate, schema, tableName, ast, ttl, format) {
3294
+ super(schema, tableName, ast, ttl, format);
3295
+ this.#delegate = delegate;
3296
+ }
3297
+ _system = "client";
3298
+ get [completedAstSymbol]() {
3299
+ return this._completeAst();
3300
+ }
3301
+ _newQuery(schema, tableName, ast, ttl, format) {
3302
+ return newQueryWithDetails(
3303
+ this.#delegate,
3304
+ schema,
3305
+ tableName,
3306
+ ast,
3307
+ ttl,
3308
+ format
3309
+ );
3310
+ }
3311
+ materialize(factory) {
3312
+ const ast = this._completeAst();
3313
+ const queryCompleteResolver = resolver();
3314
+ let queryGot = false;
3315
+ const ttl = void 0;
3316
+ const removeServerQuery = this.#delegate.addServerQuery(ast, ttl, (got) => {
3317
+ if (got) {
3318
+ queryGot = true;
3319
+ queryCompleteResolver.resolve(true);
3320
+ }
3321
+ });
3322
+ const input = buildPipeline(ast, this.#delegate);
3323
+ let removeCommitObserver;
3324
+ const onDestroy = () => {
3325
+ input.destroy();
3326
+ removeCommitObserver?.();
3327
+ removeServerQuery();
3328
+ };
3329
+ const view = this.#delegate.batchViewUpdates(
3330
+ () => (factory ?? arrayViewFactory)(
3331
+ this,
3332
+ input,
3333
+ this.format,
3334
+ onDestroy,
3335
+ (cb) => {
3336
+ removeCommitObserver = this.#delegate.onTransactionCommit(cb);
3337
+ },
3338
+ queryGot || queryCompleteResolver.promise
3339
+ )
3340
+ );
3341
+ return view;
3342
+ }
3343
+ run() {
3344
+ const v2 = this.materialize();
3345
+ const ret = v2.data;
3346
+ v2.destroy();
3347
+ return Promise.resolve(ret);
3348
+ }
3349
+ preload() {
3350
+ const { resolve, promise: complete } = resolver();
3351
+ const ast = this._completeAst();
3352
+ const ttl = void 0;
3353
+ const unsub = this.#delegate.addServerQuery(ast, ttl, (got) => {
3354
+ if (got) {
3355
+ resolve();
3356
+ }
3357
+ });
3358
+ return {
3359
+ cleanup: unsub,
3360
+ complete
3361
+ };
3362
+ }
3363
+ };
3364
+ function addPrimaryKeys(schema, orderBy) {
3365
+ orderBy = orderBy ?? [];
3366
+ const { primaryKey } = schema;
3367
+ const primaryKeysToAdd = new Set(primaryKey);
3368
+ for (const [field] of orderBy) {
3369
+ primaryKeysToAdd.delete(field);
3370
+ }
3371
+ if (primaryKeysToAdd.size === 0) {
3372
+ return orderBy;
3373
+ }
3374
+ return [
3375
+ ...orderBy,
3376
+ ...[...primaryKeysToAdd].map((key) => [key, "asc"])
3377
+ ];
3378
+ }
3379
+ function addPrimaryKeysToAst(schema, ast) {
3380
+ return {
3381
+ ...ast,
3382
+ orderBy: addPrimaryKeys(schema, ast.orderBy)
3383
+ };
3384
+ }
3385
+ function arrayViewFactory(_query, input, format, onDestroy, onTransactionCommit, queryComplete) {
3386
+ const v2 = new ArrayView(input, format, queryComplete);
3387
+ v2.onDestroy = onDestroy;
3388
+ onTransactionCommit(() => {
3389
+ v2.flush();
3390
+ });
3391
+ return v2;
3392
+ }
3393
+ function isCompoundKey(field) {
3394
+ return Array.isArray(field) && field.length >= 1;
3395
+ }
3396
+
3397
+ // ../zero-protocol/src/mutation-type-enum.ts
3398
+ var CRUD = "crud";
3399
+ var Custom = "custom";
3400
+
3401
+ // ../zero-protocol/src/primary-key.ts
3402
+ var primaryKeySchema = readonly(
3403
+ valita_exports.tuple([valita_exports.string()]).concat(valita_exports.array(valita_exports.string()))
3404
+ );
3405
+ var primaryKeyValueSchema = valita_exports.union(
3406
+ valita_exports.string(),
3407
+ valita_exports.number(),
3408
+ valita_exports.boolean()
3409
+ );
3410
+ var primaryKeyValueRecordSchema = readonlyRecord(
3411
+ primaryKeyValueSchema
3412
+ );
3413
+
3414
+ // ../zero-protocol/src/push.ts
3415
+ var CRUD_MUTATION_NAME = "_zero_crud";
3416
+ var insertOpSchema = valita_exports.object({
3417
+ op: valita_exports.literal("insert"),
3418
+ tableName: valita_exports.string(),
3419
+ primaryKey: primaryKeySchema,
3420
+ value: rowSchema
3421
+ });
3422
+ var upsertOpSchema = valita_exports.object({
3423
+ op: valita_exports.literal("upsert"),
3424
+ tableName: valita_exports.string(),
3425
+ primaryKey: primaryKeySchema,
3426
+ value: rowSchema
3427
+ });
3428
+ var updateOpSchema = valita_exports.object({
3429
+ op: valita_exports.literal("update"),
3430
+ tableName: valita_exports.string(),
3431
+ primaryKey: primaryKeySchema,
3432
+ // Partial value with at least the primary key fields
3433
+ value: rowSchema
3434
+ });
3435
+ var deleteOpSchema = valita_exports.object({
3436
+ op: valita_exports.literal("delete"),
3437
+ tableName: valita_exports.string(),
3438
+ primaryKey: primaryKeySchema,
3439
+ // Partial value representing the primary key
3440
+ value: primaryKeyValueRecordSchema
3441
+ });
3442
+ var crudOpSchema = valita_exports.union(
3443
+ insertOpSchema,
3444
+ upsertOpSchema,
3445
+ updateOpSchema,
3446
+ deleteOpSchema
3447
+ );
3448
+ var crudArgSchema = valita_exports.object({
3449
+ ops: valita_exports.array(crudOpSchema)
3450
+ });
3451
+ var crudArgsSchema = valita_exports.tuple([crudArgSchema]);
3452
+ var crudMutationSchema = valita_exports.object({
3453
+ type: valita_exports.literal(CRUD),
3454
+ id: valita_exports.number(),
3455
+ clientID: valita_exports.string(),
3456
+ name: valita_exports.literal(CRUD_MUTATION_NAME),
3457
+ args: crudArgsSchema,
3458
+ timestamp: valita_exports.number()
3459
+ });
3460
+ var customMutationSchema = valita_exports.object({
3461
+ type: valita_exports.literal(Custom),
3462
+ id: valita_exports.number(),
3463
+ clientID: valita_exports.string(),
3464
+ name: valita_exports.string(),
3465
+ args: valita_exports.array(jsonSchema),
3466
+ timestamp: valita_exports.number()
3467
+ });
3468
+ var mutationSchema = valita_exports.union(crudMutationSchema, customMutationSchema);
3469
+ var pushBodySchema = valita_exports.object({
3470
+ clientGroupID: valita_exports.string(),
3471
+ mutations: valita_exports.array(mutationSchema),
3472
+ pushVersion: valita_exports.number(),
3473
+ schemaVersion: valita_exports.number(),
3474
+ timestamp: valita_exports.number(),
3475
+ requestID: valita_exports.string()
3476
+ });
3477
+ var pushMessageSchema = valita_exports.tuple([valita_exports.literal("push"), pushBodySchema]);
3478
+ var mutationIDSchema = valita_exports.object({
3479
+ id: valita_exports.number(),
3480
+ clientID: valita_exports.string()
3481
+ });
3482
+ var appErrorSchema = valita_exports.object({
3483
+ error: valita_exports.literal("app"),
3484
+ details: valita_exports.string()
3485
+ });
3486
+ var zeroErrorSchema = valita_exports.object({
3487
+ error: valita_exports.literal("ooo-mutation")
3488
+ });
3489
+ var mutationOkSchema = valita_exports.object({});
3490
+ var mutationErrorSchema = valita_exports.union(appErrorSchema, zeroErrorSchema);
3491
+ var mutationResultSchema = valita_exports.union(mutationOkSchema, mutationErrorSchema);
3492
+ var mutationResponseSchema = valita_exports.object({
3493
+ id: mutationIDSchema,
3494
+ result: mutationResultSchema
3495
+ });
3496
+ var pushOkSchema = valita_exports.object({
3497
+ mutations: valita_exports.array(mutationResponseSchema)
3498
+ });
3499
+ var unsupportedPushVersionSchema = valita_exports.object({
3500
+ error: valita_exports.literal("unsupported-push-version")
3501
+ });
3502
+ var unsupportedSchemaVersionSchema = valita_exports.object({
3503
+ error: valita_exports.literal("unsupported-schema-version")
3504
+ });
3505
+ var pushErrorSchema = valita_exports.union(
3506
+ unsupportedPushVersionSchema,
3507
+ unsupportedSchemaVersionSchema
3508
+ );
3509
+ var pushResponseSchema = valita_exports.union(pushOkSchema, pushErrorSchema);
3510
+ function mapCRUD(arg, map) {
3511
+ return {
3512
+ ops: arg.ops.map(
3513
+ ({ op, tableName, primaryKey, value }) => ({
3514
+ op,
3515
+ tableName: map.tableName(tableName),
3516
+ primaryKey: map.columns(tableName, primaryKey),
3517
+ value: map.row(tableName, value)
3518
+ // The cast is necessary because ts objects to the `value` field
3519
+ // for "delete" ops being different.
3520
+ })
3521
+ )
3522
+ };
3523
+ }
3524
+
3525
+ // ../zql/src/mutate/custom.ts
3526
+ function customMutatorKey(namespace, name) {
3527
+ assert(!namespace.includes("|"), "mutator namespaces must not include a |");
3528
+ assert(!name.includes("|"), "mutator names must not include a |");
3529
+ return `${namespace}|${name}`;
3530
+ }
3531
+ function splitMutatorKey(key) {
3532
+ return key.split("|");
3533
+ }
3534
+
3535
+ export {
3536
+ isProd,
3537
+ deepEqual,
3538
+ assertJSONValue,
3539
+ assertJSONObject,
3540
+ parse,
3541
+ assert2 as assert,
3542
+ test,
3543
+ readonlyObject,
3544
+ readonlyArray,
3545
+ readonlyRecord,
3546
+ valita_exports,
3547
+ joinIterables,
3548
+ first2 as first,
3549
+ wrapIterable,
3550
+ jsonSchema,
3551
+ jsonObjectSchema,
3552
+ rowSchema,
3553
+ toStaticParam,
3554
+ astSchema,
3555
+ normalizeAST,
3556
+ mapAST,
3557
+ mapCondition,
3558
+ h128,
3559
+ hashOfAST,
3560
+ filterPush,
3561
+ createPredicate,
3562
+ transformFilters,
3563
+ assertOrderingIncludesPK,
3564
+ ExpressionBuilder,
3565
+ newQuery,
3566
+ staticParam,
3567
+ AbstractQuery,
3568
+ primaryKeyValueSchema,
3569
+ primaryKeyValueRecordSchema,
3570
+ CRUD,
3571
+ Custom,
3572
+ CRUD_MUTATION_NAME,
3573
+ pushBodySchema,
3574
+ mapCRUD,
3575
+ customMutatorKey,
3576
+ splitMutatorKey
3577
+ };
3578
+ //# sourceMappingURL=chunk-P3NUVEQJ.js.map