syncorejs 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +2 -1
  2. package/dist/_vendor/cli/app.d.mts.map +1 -1
  3. package/dist/_vendor/cli/app.mjs +323 -42
  4. package/dist/_vendor/cli/app.mjs.map +1 -1
  5. package/dist/_vendor/cli/context.mjs +27 -9
  6. package/dist/_vendor/cli/context.mjs.map +1 -1
  7. package/dist/_vendor/cli/doctor.mjs +513 -46
  8. package/dist/_vendor/cli/doctor.mjs.map +1 -1
  9. package/dist/_vendor/cli/messages.mjs +5 -4
  10. package/dist/_vendor/cli/messages.mjs.map +1 -1
  11. package/dist/_vendor/cli/project.mjs +110 -12
  12. package/dist/_vendor/cli/project.mjs.map +1 -1
  13. package/dist/_vendor/cli/render.mjs +57 -9
  14. package/dist/_vendor/cli/render.mjs.map +1 -1
  15. package/dist/_vendor/cli/targets.mjs +4 -3
  16. package/dist/_vendor/cli/targets.mjs.map +1 -1
  17. package/dist/_vendor/core/cli.d.mts +13 -3
  18. package/dist/_vendor/core/cli.d.mts.map +1 -1
  19. package/dist/_vendor/core/cli.mjs +242 -91
  20. package/dist/_vendor/core/cli.mjs.map +1 -1
  21. package/dist/_vendor/core/devtools-auth.mjs +60 -0
  22. package/dist/_vendor/core/devtools-auth.mjs.map +1 -0
  23. package/dist/_vendor/core/index.d.mts +5 -3
  24. package/dist/_vendor/core/index.mjs +22 -2
  25. package/dist/_vendor/core/index.mjs.map +1 -1
  26. package/dist/_vendor/core/runtime/components.d.mts +111 -0
  27. package/dist/_vendor/core/runtime/components.d.mts.map +1 -0
  28. package/dist/_vendor/core/runtime/components.mjs +186 -0
  29. package/dist/_vendor/core/runtime/components.mjs.map +1 -0
  30. package/dist/_vendor/core/runtime/devtools.d.mts +4 -4
  31. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  32. package/dist/_vendor/core/runtime/devtools.mjs +52 -41
  33. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  34. package/dist/_vendor/core/runtime/functions.d.mts +10 -10
  35. package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
  36. package/dist/_vendor/core/runtime/functions.mjs +2 -2
  37. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  38. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +77 -0
  39. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -0
  40. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +617 -0
  41. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -0
  42. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +186 -0
  43. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -0
  44. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +220 -0
  45. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -0
  46. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +203 -0
  47. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -0
  48. package/dist/_vendor/core/runtime/internal/engines/shared.mjs +177 -0
  49. package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -0
  50. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +144 -0
  51. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -0
  52. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +220 -0
  53. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -0
  54. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs +32 -0
  55. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -0
  56. package/dist/_vendor/core/runtime/internal/systemMeta.mjs +61 -0
  57. package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -0
  58. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +37 -0
  59. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -0
  60. package/dist/_vendor/core/runtime/runtime.d.mts +159 -205
  61. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  62. package/dist/_vendor/core/runtime/runtime.mjs +16 -1371
  63. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  64. package/dist/_vendor/core/transport.d.mts +111 -0
  65. package/dist/_vendor/core/transport.d.mts.map +1 -0
  66. package/dist/_vendor/core/transport.mjs +419 -0
  67. package/dist/_vendor/core/transport.mjs.map +1 -0
  68. package/dist/_vendor/devtools-protocol/index.d.ts +39 -1
  69. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  70. package/dist/_vendor/devtools-protocol/index.js +25 -9
  71. package/dist/_vendor/devtools-protocol/index.js.map +1 -1
  72. package/dist/_vendor/next/index.d.ts +1 -1
  73. package/dist/_vendor/next/index.d.ts.map +1 -1
  74. package/dist/_vendor/next/index.js +31 -13
  75. package/dist/_vendor/next/index.js.map +1 -1
  76. package/dist/_vendor/platform-expo/index.d.ts +12 -12
  77. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  78. package/dist/_vendor/platform-expo/index.js +4 -2
  79. package/dist/_vendor/platform-expo/index.js.map +1 -1
  80. package/dist/_vendor/platform-expo/react.d.ts.map +1 -1
  81. package/dist/_vendor/platform-expo/react.js +11 -10
  82. package/dist/_vendor/platform-expo/react.js.map +1 -1
  83. package/dist/_vendor/platform-node/index.d.mts +23 -19
  84. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  85. package/dist/_vendor/platform-node/index.mjs +13 -5
  86. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  87. package/dist/_vendor/platform-node/ipc-react.d.mts.map +1 -1
  88. package/dist/_vendor/platform-node/ipc-react.mjs +15 -2
  89. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  90. package/dist/_vendor/platform-node/ipc.d.mts +11 -35
  91. package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
  92. package/dist/_vendor/platform-node/ipc.mjs +3 -273
  93. package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
  94. package/dist/_vendor/platform-web/external-change.d.ts +2 -1
  95. package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
  96. package/dist/_vendor/platform-web/external-change.js +2 -1
  97. package/dist/_vendor/platform-web/external-change.js.map +1 -1
  98. package/dist/_vendor/platform-web/index.d.ts +21 -21
  99. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  100. package/dist/_vendor/platform-web/index.js +44 -7
  101. package/dist/_vendor/platform-web/index.js.map +1 -1
  102. package/dist/_vendor/platform-web/react.d.ts.map +1 -1
  103. package/dist/_vendor/platform-web/react.js +29 -13
  104. package/dist/_vendor/platform-web/react.js.map +1 -1
  105. package/dist/_vendor/platform-web/worker.d.ts +11 -35
  106. package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
  107. package/dist/_vendor/platform-web/worker.js +3 -267
  108. package/dist/_vendor/platform-web/worker.js.map +1 -1
  109. package/dist/_vendor/react/index.d.ts +36 -20
  110. package/dist/_vendor/react/index.d.ts.map +1 -1
  111. package/dist/_vendor/react/index.js +279 -57
  112. package/dist/_vendor/react/index.js.map +1 -1
  113. package/dist/_vendor/schema/definition.d.ts +48 -63
  114. package/dist/_vendor/schema/definition.d.ts.map +1 -1
  115. package/dist/_vendor/schema/definition.js +22 -39
  116. package/dist/_vendor/schema/definition.js.map +1 -1
  117. package/dist/_vendor/schema/index.d.ts +4 -4
  118. package/dist/_vendor/schema/index.js +2 -2
  119. package/dist/_vendor/schema/planner.d.ts +19 -2
  120. package/dist/_vendor/schema/planner.d.ts.map +1 -1
  121. package/dist/_vendor/schema/planner.js +79 -3
  122. package/dist/_vendor/schema/planner.js.map +1 -1
  123. package/dist/_vendor/schema/validators.d.ts +141 -121
  124. package/dist/_vendor/schema/validators.d.ts.map +1 -1
  125. package/dist/_vendor/schema/validators.js +300 -42
  126. package/dist/_vendor/schema/validators.js.map +1 -1
  127. package/dist/_vendor/svelte/index.d.ts +47 -19
  128. package/dist/_vendor/svelte/index.d.ts.map +1 -1
  129. package/dist/_vendor/svelte/index.js +250 -20
  130. package/dist/_vendor/svelte/index.js.map +1 -1
  131. package/dist/components.d.ts +2 -0
  132. package/dist/components.js +2 -0
  133. package/dist/index.d.ts +3 -2
  134. package/dist/index.js +2 -1
  135. package/package.json +8 -3
@@ -0,0 +1,617 @@
1
+ import { toCanonicalComponentFunctionName } from "../../components.mjs";
2
+ import { generateId } from "../../id.mjs";
3
+ import { fieldExpression, normalizeOptionalArgs, omitSystemFields, quoteIdentifier, resolveSearchIndexTableName, splitSchedulerArgs, stableStringify } from "./shared.mjs";
4
+ import { createEmptyExecutionResult } from "../transactionCoordinator.mjs";
5
+ //#region src/runtime/internal/engines/executionEngine.ts
6
+ const DEFAULT_MISFIRE_POLICY = { type: "catch_up" };
7
+ var RuntimeFilterBuilder = class {
8
+ eq(field, value) {
9
+ return {
10
+ type: "condition",
11
+ condition: {
12
+ field,
13
+ operator: "=",
14
+ value
15
+ }
16
+ };
17
+ }
18
+ gt(field, value) {
19
+ return {
20
+ type: "condition",
21
+ condition: {
22
+ field,
23
+ operator: ">",
24
+ value
25
+ }
26
+ };
27
+ }
28
+ gte(field, value) {
29
+ return {
30
+ type: "condition",
31
+ condition: {
32
+ field,
33
+ operator: ">=",
34
+ value
35
+ }
36
+ };
37
+ }
38
+ lt(field, value) {
39
+ return {
40
+ type: "condition",
41
+ condition: {
42
+ field,
43
+ operator: "<",
44
+ value
45
+ }
46
+ };
47
+ }
48
+ lte(field, value) {
49
+ return {
50
+ type: "condition",
51
+ condition: {
52
+ field,
53
+ operator: "<=",
54
+ value
55
+ }
56
+ };
57
+ }
58
+ and(...expressions) {
59
+ return {
60
+ type: "and",
61
+ expressions
62
+ };
63
+ }
64
+ or(...expressions) {
65
+ return {
66
+ type: "or",
67
+ expressions
68
+ };
69
+ }
70
+ };
71
+ var RuntimeIndexRangeBuilder = class {
72
+ conditions = [];
73
+ eq(field, value) {
74
+ this.conditions.push({
75
+ field,
76
+ operator: "=",
77
+ value
78
+ });
79
+ return this;
80
+ }
81
+ gt(field, value) {
82
+ this.conditions.push({
83
+ field,
84
+ operator: ">",
85
+ value
86
+ });
87
+ return this;
88
+ }
89
+ gte(field, value) {
90
+ this.conditions.push({
91
+ field,
92
+ operator: ">=",
93
+ value
94
+ });
95
+ return this;
96
+ }
97
+ lt(field, value) {
98
+ this.conditions.push({
99
+ field,
100
+ operator: "<",
101
+ value
102
+ });
103
+ return this;
104
+ }
105
+ lte(field, value) {
106
+ this.conditions.push({
107
+ field,
108
+ operator: "<=",
109
+ value
110
+ });
111
+ return this;
112
+ }
113
+ build() {
114
+ return [...this.conditions];
115
+ }
116
+ };
117
+ var RuntimeSearchIndexBuilder = class {
118
+ searchField;
119
+ searchText;
120
+ filters = [];
121
+ search(field, value) {
122
+ this.searchField = field;
123
+ this.searchText = value;
124
+ return this;
125
+ }
126
+ eq(field, value) {
127
+ this.filters.push({
128
+ field,
129
+ operator: "=",
130
+ value
131
+ });
132
+ return this;
133
+ }
134
+ build() {
135
+ if (!this.searchField || !this.searchText) throw new Error("Search queries require a search field and search text.");
136
+ return {
137
+ searchField: this.searchField,
138
+ searchText: this.searchText,
139
+ filters: [...this.filters]
140
+ };
141
+ }
142
+ };
143
+ var RuntimeQueryBuilder = class {
144
+ orderDirection = "asc";
145
+ source = { type: "table" };
146
+ filterExpression;
147
+ constructor(executeQuery, tableName, dependencyCollector) {
148
+ this.executeQuery = executeQuery;
149
+ this.tableName = tableName;
150
+ this.dependencyCollector = dependencyCollector;
151
+ }
152
+ withIndex(indexName, builder) {
153
+ this.source = {
154
+ type: "index",
155
+ name: indexName,
156
+ range: builder?.(new RuntimeIndexRangeBuilder()).build() ?? []
157
+ };
158
+ return this;
159
+ }
160
+ withSearchIndex(indexName, builder) {
161
+ this.source = {
162
+ type: "search",
163
+ name: indexName,
164
+ query: builder(new RuntimeSearchIndexBuilder()).build()
165
+ };
166
+ return this;
167
+ }
168
+ order(order) {
169
+ this.orderDirection = order;
170
+ return this;
171
+ }
172
+ filter(builder) {
173
+ this.filterExpression = builder(new RuntimeFilterBuilder());
174
+ return this;
175
+ }
176
+ async collect() {
177
+ return this.execute();
178
+ }
179
+ async take(count) {
180
+ return this.execute({ limit: count });
181
+ }
182
+ async first() {
183
+ return (await this.execute({ limit: 1 }))[0] ?? null;
184
+ }
185
+ async unique() {
186
+ const results = await this.execute({ limit: 2 });
187
+ if (results.length > 1) throw new Error("Expected a unique result but found multiple rows.");
188
+ return results[0] ?? null;
189
+ }
190
+ async paginate(options) {
191
+ const offset = options.cursor ? Number.parseInt(options.cursor, 10) : 0;
192
+ const page = await this.execute({
193
+ limit: options.numItems,
194
+ offset
195
+ });
196
+ const nextCursor = page.length < options.numItems ? null : String(offset + page.length);
197
+ return {
198
+ page,
199
+ cursor: nextCursor,
200
+ isDone: nextCursor === null
201
+ };
202
+ }
203
+ async execute(options) {
204
+ this.dependencyCollector?.add(`table:${this.tableName}`);
205
+ const queryOptions = {
206
+ tableName: this.tableName,
207
+ source: this.source,
208
+ filterExpression: this.filterExpression,
209
+ orderDirection: this.orderDirection
210
+ };
211
+ if (this.dependencyCollector) queryOptions.dependencyCollector = this.dependencyCollector;
212
+ if (options?.limit !== void 0) queryOptions.limit = options.limit;
213
+ if (options?.offset !== void 0) queryOptions.offset = options.offset;
214
+ return this.executeQuery(queryOptions);
215
+ }
216
+ };
217
+ var ExecutionEngine = class {
218
+ constructor(deps) {
219
+ this.deps = deps;
220
+ }
221
+ createClient() {
222
+ return {
223
+ query: (reference, ...args) => this.runQuery(reference, normalizeOptionalArgs(args)),
224
+ mutation: (reference, ...args) => this.runMutation(reference, normalizeOptionalArgs(args)),
225
+ action: (reference, ...args) => this.runAction(reference, normalizeOptionalArgs(args)),
226
+ watchQuery: (reference, ...args) => this.watchQuery(reference, normalizeOptionalArgs(args)),
227
+ watchRuntimeStatus: () => this.deps.runtimeStatus.watch()
228
+ };
229
+ }
230
+ watchQuery(reference, args = {}) {
231
+ return this.deps.reactivity.watchQuery(reference, args);
232
+ }
233
+ async runQuery(reference, args = {}, meta = {}) {
234
+ const definition = this.resolveFunction(reference, "query");
235
+ const dependencyCollector = /* @__PURE__ */ new Set();
236
+ const startedAt = Date.now();
237
+ const result = await this.invokeFunction(definition, args, {
238
+ mutationDepth: 0,
239
+ changedTables: /* @__PURE__ */ new Set(),
240
+ storageChanges: [],
241
+ dependencyCollector,
242
+ componentMetadata: definition.__syncoreComponent
243
+ });
244
+ this.deps.devtools.emit({
245
+ type: "query.executed",
246
+ runtimeId: this.deps.runtimeId,
247
+ queryId: reference.name,
248
+ functionName: reference.name,
249
+ ...definition.__syncoreComponent ? {
250
+ componentPath: definition.__syncoreComponent.componentPath,
251
+ componentName: definition.__syncoreComponent.componentName
252
+ } : {},
253
+ dependencies: [...dependencyCollector],
254
+ durationMs: Date.now() - startedAt,
255
+ timestamp: Date.now(),
256
+ ...meta.origin ? { origin: meta.origin } : {}
257
+ });
258
+ return result;
259
+ }
260
+ async runMutation(reference, args = {}, meta = {}) {
261
+ const definition = this.resolveFunction(reference, "mutation");
262
+ const mutationId = generateId();
263
+ const startedAt = Date.now();
264
+ const execution = await this.deps.transactionCoordinator.runInTransaction(async (transactionState) => this.invokeFunction(definition, args, {
265
+ mutationDepth: 1,
266
+ changedTables: transactionState.changedTables,
267
+ storageChanges: transactionState.storageChanges,
268
+ componentMetadata: definition.__syncoreComponent
269
+ }));
270
+ await this.finalizeStatefulExecution(mutationId, execution, Date.now() - startedAt);
271
+ this.deps.devtools.emit({
272
+ type: "mutation.committed",
273
+ runtimeId: this.deps.runtimeId,
274
+ mutationId,
275
+ functionName: reference.name,
276
+ ...definition.__syncoreComponent ? {
277
+ componentPath: definition.__syncoreComponent.componentPath,
278
+ componentName: definition.__syncoreComponent.componentName
279
+ } : {},
280
+ changedTables: [...execution.changedTables],
281
+ durationMs: Date.now() - startedAt,
282
+ timestamp: Date.now(),
283
+ ...meta.origin ? { origin: meta.origin } : {}
284
+ });
285
+ return execution.result;
286
+ }
287
+ async runAction(reference, args = {}, meta = {}) {
288
+ const definition = this.resolveFunction(reference, "action");
289
+ const actionId = generateId();
290
+ const startedAt = Date.now();
291
+ const state = this.deps.transactionCoordinator.createState();
292
+ try {
293
+ const result = await this.invokeFunction(definition, args, {
294
+ mutationDepth: 0,
295
+ changedTables: state.changedTables,
296
+ storageChanges: state.storageChanges,
297
+ componentMetadata: definition.__syncoreComponent
298
+ });
299
+ await this.finalizeStatefulExecution(actionId, createEmptyExecutionResult(result, state), Date.now() - startedAt);
300
+ this.deps.devtools.emit({
301
+ type: "action.completed",
302
+ runtimeId: this.deps.runtimeId,
303
+ actionId,
304
+ functionName: reference.name,
305
+ ...definition.__syncoreComponent ? {
306
+ componentPath: definition.__syncoreComponent.componentPath,
307
+ componentName: definition.__syncoreComponent.componentName
308
+ } : {},
309
+ durationMs: Date.now() - startedAt,
310
+ timestamp: Date.now(),
311
+ ...meta.origin ? { origin: meta.origin } : {}
312
+ });
313
+ return result;
314
+ } catch (error) {
315
+ this.deps.devtools.emit({
316
+ type: "action.completed",
317
+ runtimeId: this.deps.runtimeId,
318
+ actionId,
319
+ functionName: reference.name,
320
+ ...definition.__syncoreComponent ? {
321
+ componentPath: definition.__syncoreComponent.componentPath,
322
+ componentName: definition.__syncoreComponent.componentName
323
+ } : {},
324
+ durationMs: Date.now() - startedAt,
325
+ timestamp: Date.now(),
326
+ ...meta.origin ? { origin: meta.origin } : {},
327
+ error: error instanceof Error ? error.message : String(error)
328
+ });
329
+ throw error;
330
+ }
331
+ }
332
+ async runDevtoolsMutation(callback, meta = {}) {
333
+ const mutationId = generateId();
334
+ const startedAt = Date.now();
335
+ const execution = await this.deps.transactionCoordinator.runInTransaction(async (transactionState) => callback({ db: this.createDatabaseWriter({
336
+ mutationDepth: 1,
337
+ changedTables: transactionState.changedTables,
338
+ storageChanges: transactionState.storageChanges
339
+ }) }));
340
+ await this.finalizeStatefulExecution(mutationId, execution, Date.now() - startedAt);
341
+ this.deps.devtools.emit({
342
+ type: "mutation.committed",
343
+ runtimeId: this.deps.runtimeId,
344
+ mutationId,
345
+ functionName: "__devtools__/mutation",
346
+ changedTables: [...execution.changedTables],
347
+ durationMs: Date.now() - startedAt,
348
+ timestamp: Date.now(),
349
+ ...meta.origin ? { origin: meta.origin } : {}
350
+ });
351
+ return execution.result;
352
+ }
353
+ async finalizeStatefulExecution(executionId, execution, durationMs) {
354
+ const changedScopes = collectChangedScopes(execution.changedTables, execution.storageChanges);
355
+ if (changedScopes.size > 0) await this.deps.reactivity.refreshQueriesForScopes(changedScopes, `Execution ${executionId} touched ${[...changedScopes].join(", ")}`);
356
+ if (execution.changedTables.size > 0) await this.deps.reactivity.publishExternalChange({
357
+ scope: "database",
358
+ reason: "commit",
359
+ changedScopes: [...changedScopes].filter((scope) => scope.startsWith("table:")),
360
+ changedTables: [...execution.changedTables]
361
+ });
362
+ await this.deps.reactivity.publishStorageChanges(execution.storageChanges);
363
+ }
364
+ async collectQueryDependencies(functionName, args) {
365
+ const definition = this.resolveFunction({
366
+ kind: "query",
367
+ name: functionName
368
+ }, "query");
369
+ const dependencyCollector = /* @__PURE__ */ new Set();
370
+ await this.invokeFunction(definition, args, {
371
+ mutationDepth: 0,
372
+ changedTables: /* @__PURE__ */ new Set(),
373
+ storageChanges: [],
374
+ dependencyCollector,
375
+ componentMetadata: definition.__syncoreComponent
376
+ });
377
+ return dependencyCollector;
378
+ }
379
+ async executeQueryBuilder(options) {
380
+ const table = this.deps.schema.getTableDefinition(options.tableName);
381
+ const params = [];
382
+ const whereClauses = [];
383
+ const orderClauses = [];
384
+ let joinClause = "";
385
+ const source = options.source;
386
+ if (source.type === "index") {
387
+ const index = table.indexes.find((candidate) => candidate.name === source.name);
388
+ if (!index) throw new Error(`Unknown index "${source.name}" on table "${options.tableName}".`);
389
+ for (const condition of source.range) whereClauses.push(this.renderCondition("t", condition, params));
390
+ const primaryField = index.fields[0];
391
+ if (primaryField) orderClauses.push(`${fieldExpression("t", primaryField)} ${options.orderDirection.toUpperCase()}`);
392
+ }
393
+ if (source.type === "search") {
394
+ const searchIndex = table.searchIndexes.find((candidate) => candidate.name === source.name);
395
+ if (!searchIndex) throw new Error(`Unknown search index "${source.name}" on table "${options.tableName}".`);
396
+ if (searchIndex.searchField !== source.query.searchField) throw new Error(`Search index "${searchIndex.name}" expects field "${searchIndex.searchField}".`);
397
+ if (this.deps.schema.isSearchIndexDisabled(options.tableName, searchIndex.name)) {
398
+ whereClauses.push(`${fieldExpression("t", searchIndex.searchField)} LIKE ?`);
399
+ params.push(`%${source.query.searchText}%`);
400
+ } else {
401
+ joinClause = `JOIN ${quoteIdentifier(resolveSearchIndexTableName(options.tableName, searchIndex.name))} s ON s._id = t._id`;
402
+ whereClauses.push(`s.search_value MATCH ?`);
403
+ params.push(source.query.searchText);
404
+ }
405
+ for (const condition of source.query.filters) whereClauses.push(this.renderCondition("t", condition, params));
406
+ }
407
+ if (options.filterExpression) whereClauses.push(this.renderExpression("t", options.filterExpression, params));
408
+ if (orderClauses.length === 0) orderClauses.push(`t._creationTime ${options.orderDirection.toUpperCase()}`);
409
+ orderClauses.push(`t._id ${options.orderDirection.toUpperCase()}`);
410
+ const sql = [
411
+ `SELECT t._id, t._creationTime, t._json FROM ${quoteIdentifier(options.tableName)} t`,
412
+ joinClause,
413
+ whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "",
414
+ `ORDER BY ${orderClauses.join(", ")}`,
415
+ options.limit !== void 0 ? `LIMIT ${options.limit}` : "",
416
+ options.offset !== void 0 ? `OFFSET ${options.offset}` : ""
417
+ ].filter(Boolean).join(" ");
418
+ return (await this.deps.driver.all(sql, params)).map((row) => this.deps.schema.deserializeDocument(options.tableName, row));
419
+ }
420
+ async invokeFunction(definition, rawArgs, state) {
421
+ const args = definition.argsValidator.parse(rawArgs);
422
+ const ctx = this.createContext(definition.kind, {
423
+ ...state,
424
+ componentMetadata: definition.__syncoreComponent ?? state.componentMetadata
425
+ });
426
+ const result = await definition.handler(ctx, args);
427
+ if (definition.returnsValidator) return definition.returnsValidator.parse(result);
428
+ return result;
429
+ }
430
+ createContext(kind, state) {
431
+ const db = kind === "mutation" ? this.createDatabaseWriter(state) : this.createDatabaseReader(state);
432
+ const storage = this.deps.storage.createStorageApi(state);
433
+ const scheduler = this.createSchedulerApi(state.componentMetadata);
434
+ const callerMetadata = state.componentMetadata;
435
+ return {
436
+ db,
437
+ storage,
438
+ capabilities: this.deps.capabilities,
439
+ capabilityDescriptors: this.deps.capabilityDescriptors,
440
+ ...callerMetadata ? { component: {
441
+ path: callerMetadata.componentPath,
442
+ name: callerMetadata.componentName,
443
+ version: callerMetadata.version,
444
+ capabilities: callerMetadata.grantedCapabilities
445
+ } } : {},
446
+ scheduler,
447
+ runQuery: (reference, ...args) => this.runQuery(this.resolveReferenceForCaller(reference, "query", callerMetadata), normalizeOptionalArgs(args)),
448
+ runMutation: (reference, ...args) => {
449
+ const resolvedReference = this.resolveReferenceForCaller(reference, "mutation", callerMetadata);
450
+ const normalizedArgs = normalizeOptionalArgs(args);
451
+ if (kind === "mutation") return this.deps.driver.withSavepoint(`sp_${generateId().replace(/-/g, "_")}`, () => this.invokeFunction(this.resolveFunction(resolvedReference, "mutation", callerMetadata), normalizedArgs, {
452
+ mutationDepth: state.mutationDepth + 1,
453
+ changedTables: state.changedTables,
454
+ storageChanges: state.storageChanges,
455
+ componentMetadata: callerMetadata
456
+ }));
457
+ return this.runMutation(resolvedReference, normalizedArgs);
458
+ },
459
+ runAction: (reference, ...args) => this.runAction(this.resolveReferenceForCaller(reference, "action", callerMetadata), normalizeOptionalArgs(args))
460
+ };
461
+ }
462
+ createDatabaseReader(state) {
463
+ return {
464
+ get: async (tableName, id) => {
465
+ const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
466
+ state.dependencyCollector?.add(`table:${scopedTableName}`);
467
+ state.dependencyCollector?.add(`row:${scopedTableName}:${id}`);
468
+ const row = await this.deps.driver.get(`SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
469
+ return row ? this.deps.schema.deserializeDocument(scopedTableName, row) : null;
470
+ },
471
+ query: (tableName) => new RuntimeQueryBuilder((options) => this.executeQueryBuilder({
472
+ ...options,
473
+ tableName: this.resolveTableName(tableName, state.componentMetadata)
474
+ }), this.resolveTableName(tableName, state.componentMetadata), state.dependencyCollector),
475
+ raw: (sql, params) => this.deps.driver.all(sql, params)
476
+ };
477
+ }
478
+ createDatabaseWriter(state) {
479
+ const reader = this.createDatabaseReader(state);
480
+ return {
481
+ ...reader,
482
+ insert: async (tableName, value) => {
483
+ const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
484
+ const validated = this.deps.schema.validateDocument(scopedTableName, value);
485
+ const id = generateId();
486
+ const creationTime = Date.now();
487
+ const json = stableStringify(validated);
488
+ await this.deps.driver.run(`INSERT INTO ${quoteIdentifier(scopedTableName)} (_id, _creationTime, _json) VALUES (?, ?, ?)`, [
489
+ id,
490
+ creationTime,
491
+ json
492
+ ]);
493
+ await this.deps.schema.syncSearchIndexes(scopedTableName, {
494
+ _id: id,
495
+ _creationTime: creationTime,
496
+ _json: json
497
+ });
498
+ state.changedTables.add(scopedTableName);
499
+ return id;
500
+ },
501
+ patch: async (tableName, id, value) => {
502
+ const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
503
+ const current = await reader.get(tableName, id);
504
+ if (!current) throw new Error(`Document "${id}" does not exist in "${scopedTableName}".`);
505
+ const merged = {
506
+ ...omitSystemFields(current),
507
+ ...value
508
+ };
509
+ for (const key of Object.keys(merged)) if (merged[key] === void 0) delete merged[key];
510
+ const validated = this.deps.schema.validateDocument(scopedTableName, merged);
511
+ await this.deps.driver.run(`UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`, [stableStringify(validated), id]);
512
+ const row = await this.deps.driver.get(`SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
513
+ if (row) await this.deps.schema.syncSearchIndexes(scopedTableName, row);
514
+ state.changedTables.add(scopedTableName);
515
+ },
516
+ replace: async (tableName, id, value) => {
517
+ const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
518
+ const validated = this.deps.schema.validateDocument(scopedTableName, value);
519
+ await this.deps.driver.run(`UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`, [stableStringify(validated), id]);
520
+ const row = await this.deps.driver.get(`SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
521
+ if (!row) throw new Error(`Document "${id}" does not exist in "${scopedTableName}".`);
522
+ await this.deps.schema.syncSearchIndexes(scopedTableName, row);
523
+ state.changedTables.add(scopedTableName);
524
+ },
525
+ delete: async (tableName, id) => {
526
+ const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
527
+ await this.deps.driver.run(`DELETE FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
528
+ await this.deps.schema.removeSearchIndexes(scopedTableName, id);
529
+ state.changedTables.add(scopedTableName);
530
+ }
531
+ };
532
+ }
533
+ createSchedulerApi(componentMetadata) {
534
+ return {
535
+ runAfter: async (delayMs, reference, ...args) => {
536
+ if (componentMetadata && !componentMetadata.grantedCapabilities.includes("scheduler")) throw new Error(`Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`);
537
+ const schedulerArgs = splitSchedulerArgs(args);
538
+ const functionArgs = schedulerArgs[0];
539
+ const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;
540
+ const resolvedReference = this.resolveReferenceForCaller(reference, reference.kind, componentMetadata);
541
+ return this.deps.scheduler.scheduleJob(Date.now() + delayMs, resolvedReference, functionArgs, misfirePolicy, componentMetadata ? `component:${componentMetadata.componentPath}:` : void 0);
542
+ },
543
+ runAt: async (timestamp, reference, ...args) => {
544
+ if (componentMetadata && !componentMetadata.grantedCapabilities.includes("scheduler")) throw new Error(`Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`);
545
+ const schedulerArgs = splitSchedulerArgs(args);
546
+ const functionArgs = schedulerArgs[0];
547
+ const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;
548
+ const value = timestamp instanceof Date ? timestamp.getTime() : timestamp;
549
+ const resolvedReference = this.resolveReferenceForCaller(reference, reference.kind, componentMetadata);
550
+ return this.deps.scheduler.scheduleJob(value, resolvedReference, functionArgs, misfirePolicy, componentMetadata ? `component:${componentMetadata.componentPath}:` : void 0);
551
+ },
552
+ cancel: async (id) => {
553
+ await this.deps.scheduler.cancelScheduledJob(id);
554
+ }
555
+ };
556
+ }
557
+ resolveFunction(reference, expectedKind, callerMetadata) {
558
+ const resolvedReference = this.resolveReferenceForCaller(reference, expectedKind, callerMetadata);
559
+ const definition = this.deps.functions[resolvedReference.name];
560
+ if (!definition) throw new Error(`Unknown function "${resolvedReference.name}".`);
561
+ if (definition.kind !== expectedKind) throw new Error(`Function "${resolvedReference.name}" is a ${definition.kind}, expected ${expectedKind}.`);
562
+ const metadata = definition.__syncoreComponent;
563
+ if (metadata?.visibility === "internal") {
564
+ if (!callerMetadata) throw new Error(`Function "${resolvedReference.name}" is internal to component "${metadata.componentPath}".`);
565
+ if (callerMetadata.componentPath !== metadata.componentPath) throw new Error(`Function "${resolvedReference.name}" is internal to component "${metadata.componentPath}" and cannot be called from "${callerMetadata.componentPath}".`);
566
+ }
567
+ return definition;
568
+ }
569
+ renderExpression(tableAlias, expression, params) {
570
+ if (expression.type === "condition") return this.renderCondition(tableAlias, expression.condition, params);
571
+ const separator = expression.type === "and" ? " AND " : " OR ";
572
+ return `(${expression.expressions.map((child) => this.renderExpression(tableAlias, child, params)).join(separator)})`;
573
+ }
574
+ renderCondition(tableAlias, condition, params) {
575
+ params.push(condition.value);
576
+ return `${fieldExpression(tableAlias, condition.field)} ${condition.operator} ?`;
577
+ }
578
+ resolveReferenceForCaller(reference, expectedKind, callerMetadata) {
579
+ if (!callerMetadata) return reference;
580
+ if (reference.name.startsWith("components/")) return reference;
581
+ const bindingMatch = /^binding:([^/]+)\/(.+)$/.exec(reference.name);
582
+ if (bindingMatch) {
583
+ const bindingName = bindingMatch[1];
584
+ const localName = bindingMatch[2];
585
+ const targetComponentPath = callerMetadata.bindings[bindingName];
586
+ if (!targetComponentPath) throw new Error(`Component ${JSON.stringify(callerMetadata.componentPath)} does not define binding ${JSON.stringify(bindingName)}.`);
587
+ return {
588
+ kind: expectedKind,
589
+ name: toCanonicalComponentFunctionName(targetComponentPath, "public", localName)
590
+ };
591
+ }
592
+ const internalName = toCanonicalComponentFunctionName(callerMetadata.componentPath, "internal", reference.name);
593
+ if (this.deps.functions[internalName]) return {
594
+ kind: expectedKind,
595
+ name: internalName
596
+ };
597
+ const publicName = toCanonicalComponentFunctionName(callerMetadata.componentPath, "public", reference.name);
598
+ if (this.deps.functions[publicName]) return {
599
+ kind: expectedKind,
600
+ name: publicName
601
+ };
602
+ return reference;
603
+ }
604
+ resolveTableName(tableName, componentMetadata) {
605
+ if (!componentMetadata) return tableName;
606
+ const scopedTableName = componentMetadata.localTables[tableName];
607
+ if (!scopedTableName) throw new Error(`Table ${JSON.stringify(tableName)} is not available inside component ${JSON.stringify(componentMetadata.componentPath)}.`);
608
+ return scopedTableName;
609
+ }
610
+ };
611
+ function collectChangedScopes(changedTables, storageChanges) {
612
+ return new Set([...[...changedTables].map((tableName) => `table:${tableName}`), ...storageChanges.map((change) => `storage:${change.storageId}`)]);
613
+ }
614
+ //#endregion
615
+ export { ExecutionEngine };
616
+
617
+ //# sourceMappingURL=executionEngine.mjs.map