syncorejs 0.2.1 → 0.2.3

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