syncorejs 0.2.2 → 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 (140) hide show
  1. package/dist/_vendor/cli/app.d.mts.map +1 -1
  2. package/dist/_vendor/cli/app.mjs +8 -5
  3. package/dist/_vendor/cli/app.mjs.map +1 -1
  4. package/dist/_vendor/cli/context.mjs.map +1 -1
  5. package/dist/_vendor/cli/dev-session.mjs.map +1 -1
  6. package/dist/_vendor/cli/doctor.mjs.map +1 -1
  7. package/dist/_vendor/cli/errors.mjs.map +1 -1
  8. package/dist/_vendor/cli/help.mjs.map +1 -1
  9. package/dist/_vendor/cli/index.mjs +9 -2
  10. package/dist/_vendor/cli/index.mjs.map +1 -1
  11. package/dist/_vendor/cli/messages.mjs.map +1 -1
  12. package/dist/_vendor/cli/preflight.mjs.map +1 -1
  13. package/dist/_vendor/cli/project.mjs +20 -20
  14. package/dist/_vendor/cli/project.mjs.map +1 -1
  15. package/dist/_vendor/cli/render.mjs.map +1 -1
  16. package/dist/_vendor/cli/targets.mjs.map +1 -1
  17. package/dist/_vendor/core/cli.d.mts +8 -2
  18. package/dist/_vendor/core/cli.d.mts.map +1 -1
  19. package/dist/_vendor/core/cli.mjs +238 -64
  20. package/dist/_vendor/core/cli.mjs.map +1 -1
  21. package/dist/_vendor/core/devtools-auth.mjs.map +1 -1
  22. package/dist/_vendor/core/runtime/components.d.mts.map +1 -1
  23. package/dist/_vendor/core/runtime/components.mjs.map +1 -1
  24. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  25. package/dist/_vendor/core/runtime/devtools.mjs +130 -23
  26. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  27. package/dist/_vendor/core/runtime/functions.d.mts +388 -6
  28. package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
  29. package/dist/_vendor/core/runtime/functions.mjs +72 -1
  30. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  31. package/dist/_vendor/core/runtime/id.d.mts.map +1 -1
  32. package/dist/_vendor/core/runtime/id.mjs.map +1 -1
  33. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +11 -5
  34. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -1
  35. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +123 -20
  36. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -1
  37. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +56 -8
  38. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -1
  39. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +49 -14
  40. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -1
  41. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +4 -7
  42. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -1
  43. package/dist/_vendor/core/runtime/internal/engines/shared.mjs +76 -1
  44. package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
  45. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +1 -0
  46. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
  47. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +4 -3
  48. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -1
  49. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -1
  50. package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -1
  51. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +4 -0
  52. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -1
  53. package/dist/_vendor/core/runtime/runtime.d.mts +1040 -9
  54. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  55. package/dist/_vendor/core/runtime/runtime.mjs +63 -0
  56. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  57. package/dist/_vendor/core/transport.d.mts +2 -0
  58. package/dist/_vendor/core/transport.d.mts.map +1 -1
  59. package/dist/_vendor/core/transport.mjs +33 -24
  60. package/dist/_vendor/core/transport.mjs.map +1 -1
  61. package/dist/_vendor/devtools-protocol/index.d.ts +149 -4
  62. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  63. package/dist/_vendor/devtools-protocol/index.js.map +1 -1
  64. package/dist/_vendor/next/config.d.ts +3 -4
  65. package/dist/_vendor/next/config.d.ts.map +1 -1
  66. package/dist/_vendor/next/config.js +37 -19
  67. package/dist/_vendor/next/config.js.map +1 -1
  68. package/dist/_vendor/next/index.d.ts +109 -29
  69. package/dist/_vendor/next/index.d.ts.map +1 -1
  70. package/dist/_vendor/next/index.js +77 -17
  71. package/dist/_vendor/next/index.js.map +1 -1
  72. package/dist/_vendor/platform-expo/index.d.ts +146 -27
  73. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  74. package/dist/_vendor/platform-expo/index.js +76 -10
  75. package/dist/_vendor/platform-expo/index.js.map +1 -1
  76. package/dist/_vendor/platform-expo/react.js.map +1 -1
  77. package/dist/_vendor/platform-expo/web-sqljs-wasm.js +16 -0
  78. package/dist/_vendor/platform-expo/web-sqljs-wasm.js.map +1 -0
  79. package/dist/_vendor/platform-node/index.d.mts +173 -9
  80. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  81. package/dist/_vendor/platform-node/index.mjs +225 -94
  82. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  83. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  84. package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
  85. package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
  86. package/dist/_vendor/platform-web/external-change.d.ts +41 -0
  87. package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
  88. package/dist/_vendor/platform-web/external-change.js +30 -0
  89. package/dist/_vendor/platform-web/external-change.js.map +1 -1
  90. package/dist/_vendor/platform-web/index.d.ts +307 -35
  91. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  92. package/dist/_vendor/platform-web/index.js +189 -23
  93. package/dist/_vendor/platform-web/index.js.map +1 -1
  94. package/dist/_vendor/platform-web/indexeddb.d.ts +12 -0
  95. package/dist/_vendor/platform-web/indexeddb.d.ts.map +1 -1
  96. package/dist/_vendor/platform-web/indexeddb.js +10 -0
  97. package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
  98. package/dist/_vendor/platform-web/opfs.d.ts +13 -0
  99. package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
  100. package/dist/_vendor/platform-web/opfs.js +12 -0
  101. package/dist/_vendor/platform-web/opfs.js.map +1 -1
  102. package/dist/_vendor/platform-web/persistence.d.ts +54 -0
  103. package/dist/_vendor/platform-web/persistence.d.ts.map +1 -1
  104. package/dist/_vendor/platform-web/persistence.js +15 -0
  105. package/dist/_vendor/platform-web/persistence.js.map +1 -1
  106. package/dist/_vendor/platform-web/react.d.ts +1 -2
  107. package/dist/_vendor/platform-web/react.d.ts.map +1 -1
  108. package/dist/_vendor/platform-web/react.js +2 -4
  109. package/dist/_vendor/platform-web/react.js.map +1 -1
  110. package/dist/_vendor/platform-web/sqljs.js +10 -1
  111. package/dist/_vendor/platform-web/sqljs.js.map +1 -1
  112. package/dist/_vendor/platform-web/web-sqljs-wasm.js +8 -0
  113. package/dist/_vendor/platform-web/web-sqljs-wasm.js.map +1 -0
  114. package/dist/_vendor/platform-web/worker.d.ts +60 -9
  115. package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
  116. package/dist/_vendor/platform-web/worker.js +37 -4
  117. package/dist/_vendor/platform-web/worker.js.map +1 -1
  118. package/dist/_vendor/react/index.d.ts +196 -13
  119. package/dist/_vendor/react/index.d.ts.map +1 -1
  120. package/dist/_vendor/react/index.js +208 -17
  121. package/dist/_vendor/react/index.js.map +1 -1
  122. package/dist/_vendor/schema/definition.d.ts +129 -0
  123. package/dist/_vendor/schema/definition.d.ts.map +1 -1
  124. package/dist/_vendor/schema/definition.js +99 -0
  125. package/dist/_vendor/schema/definition.js.map +1 -1
  126. package/dist/_vendor/schema/planner.d.ts.map +1 -1
  127. package/dist/_vendor/schema/planner.js.map +1 -1
  128. package/dist/_vendor/schema/validators.d.ts +180 -4
  129. package/dist/_vendor/schema/validators.d.ts.map +1 -1
  130. package/dist/_vendor/schema/validators.js +35 -1
  131. package/dist/_vendor/schema/validators.js.map +1 -1
  132. package/dist/_vendor/svelte/index.d.ts +205 -7
  133. package/dist/_vendor/svelte/index.d.ts.map +1 -1
  134. package/dist/_vendor/svelte/index.js +199 -6
  135. package/dist/_vendor/svelte/index.js.map +1 -1
  136. package/dist/browser.d.ts.map +1 -1
  137. package/dist/cli.js +3 -1
  138. package/dist/cli.js.map +1 -1
  139. package/dist/index.d.ts +1 -1
  140. package/package.json +24 -21
@@ -1 +1 @@
1
- {"version":3,"file":"executionEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/executionEngine.ts"],"sourcesContent":["import type {\n FunctionArgsFromDefinition,\n FunctionKindFromDefinition,\n FunctionReference,\n FunctionResultFromDefinition,\n MisfirePolicy,\n SyncoreFunctionKind\n} from \"../../functions.js\";\nimport {\n toCanonicalComponentFunctionName,\n type SyncoreComponentFunctionMetadata\n} from \"../../components.js\";\nimport type {\n ActionCtx,\n CapabilityDescriptor,\n DevtoolsLiveQueryScope,\n DocumentForTable,\n ExecutionResult,\n FilterBuilder,\n ImpactScope,\n IndexRangeBuilder,\n InsertValueForTable,\n JsonObject,\n MutationCtx,\n PatchValueForTable,\n PaginationOptions,\n PaginationResult,\n QueryBuilder,\n QueryCtx,\n QueryExpression,\n RegisteredSyncoreFunction,\n SchedulerApi,\n SearchIndexBuilder,\n SearchQuery,\n SyncoreCapabilities,\n SyncoreClient,\n SyncoreDataModel,\n SyncoreDatabaseReader,\n SyncoreDatabaseWriter,\n SyncoreFunctionRegistry,\n SyncoreSqlDriver,\n SyncoreWatch,\n TableNames\n} from \"../../runtime.js\";\nimport type {\n AnyTableDefinition as SchemaAnyTableDefinition,\n TableIndexFields,\n TableIndexNames,\n TableSearchIndexConfig,\n TableSearchIndexNames\n} from \"@syncore/schema\";\nimport { DevtoolsEngine } from \"./devtoolsEngine.js\";\nimport { SchemaEngine } from \"./schemaEngine.js\";\nimport { StorageEngine } from \"./storageEngine.js\";\nimport { SchedulerEngine } from \"./schedulerEngine.js\";\nimport { ReactivityEngine } from \"./reactivityEngine.js\";\nimport {\n fieldExpression,\n normalizeOptionalArgs,\n omitSystemFields,\n quoteIdentifier,\n resolveSearchIndexTableName,\n splitSchedulerArgs,\n stableStringify,\n type DatabaseRow,\n type DependencyKey,\n type DevtoolsEventMeta,\n type ExecuteQueryBuilderOptions,\n type QuerySource,\n type RuntimeExecutionState\n} from \"./shared.js\";\nimport { generateId } from \"../../id.js\";\nimport type { Validator } from \"@syncore/schema\";\nimport {\n TransactionCoordinator,\n createEmptyExecutionResult\n} from \"../transactionCoordinator.js\";\nimport type { RuntimeStatusController } from \"../runtimeStatus.js\";\n\nconst DEFAULT_MISFIRE_POLICY: MisfirePolicy = { type: \"catch_up\" };\n\ntype OptionalArgsTuple<TArgs> =\n Record<never, never> extends TArgs ? [args?: TArgs] : [args: TArgs];\n\ntype ExecutionEngineDeps<TSchema extends SyncoreDataModel> = {\n runtimeId: string;\n functions: SyncoreFunctionRegistry;\n driver: SyncoreSqlDriver;\n capabilities: Readonly<SyncoreCapabilities>;\n capabilityDescriptors: ReadonlyArray<CapabilityDescriptor>;\n schema: SchemaEngine<TSchema>;\n storage: StorageEngine;\n scheduler: SchedulerEngine;\n reactivity: ReactivityEngine;\n devtools: DevtoolsEngine;\n transactionCoordinator: TransactionCoordinator;\n runtimeStatus: RuntimeStatusController;\n};\n\nclass RuntimeFilterBuilder implements FilterBuilder {\n eq(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"=\", value } };\n }\n\n gt(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \">\", value } };\n }\n\n gte(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \">=\", value } };\n }\n\n lt(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"<\", value } };\n }\n\n lte(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"<=\", value } };\n }\n\n and(...expressions: QueryExpression[]): QueryExpression {\n return { type: \"and\", expressions };\n }\n\n or(...expressions: QueryExpression[]): QueryExpression {\n return { type: \"or\", expressions };\n }\n}\n\nclass RuntimeIndexRangeBuilder<\n TFieldName extends string = string\n> implements IndexRangeBuilder<TFieldName> {\n private readonly conditions: Array<{\n field: string;\n operator: \"=\" | \">\" | \">=\" | \"<\" | \"<=\";\n value: unknown;\n }> = [];\n\n eq(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"=\", value });\n return this;\n }\n\n gt(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \">\", value });\n return this;\n }\n\n gte(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \">=\", value });\n return this;\n }\n\n lt(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"<\", value });\n return this;\n }\n\n lte(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"<=\", value });\n return this;\n }\n\n build() {\n return [...this.conditions];\n }\n}\n\nclass RuntimeSearchIndexBuilder<\n TSearchField extends string = string,\n TFilterField extends string = string\n> implements SearchIndexBuilder<TSearchField, TFilterField> {\n private searchField: string | undefined;\n private searchText: string | undefined;\n private readonly filters: Array<{\n field: string;\n operator: \"=\";\n value: unknown;\n }> = [];\n\n search(\n field: TSearchField,\n value: string\n ): SearchIndexBuilder<TSearchField, TFilterField> {\n this.searchField = field;\n this.searchText = value;\n return this;\n }\n\n eq(\n field: TFilterField,\n value: unknown\n ): SearchIndexBuilder<TSearchField, TFilterField> {\n this.filters.push({ field, operator: \"=\", value });\n return this;\n }\n\n build(): SearchQuery {\n if (!this.searchField || !this.searchText) {\n throw new Error(\"Search queries require a search field and search text.\");\n }\n return {\n searchField: this.searchField,\n searchText: this.searchText,\n filters: [...this.filters]\n };\n }\n}\n\nclass RuntimeQueryBuilder<\n TTable extends SchemaAnyTableDefinition,\n TDocument\n> implements QueryBuilder<TTable, TDocument> {\n private orderDirection: \"asc\" | \"desc\" = \"asc\";\n private source: QuerySource = { type: \"table\" };\n private filterExpression: QueryExpression | undefined;\n\n constructor(\n private readonly executeQuery: (\n options: ExecuteQueryBuilderOptions\n ) => Promise<TDocument[]>,\n private readonly tableName: string,\n private readonly dependencyCollector?: Set<DependencyKey>\n ) {}\n\n withIndex<TIndexName extends TableIndexNames<TTable>>(\n indexName: TIndexName,\n builder?: (\n range: IndexRangeBuilder<TableIndexFields<TTable, TIndexName>[number]>\n ) => IndexRangeBuilder<TableIndexFields<TTable, TIndexName>[number]>\n ): this {\n const indexRange = builder?.(new RuntimeIndexRangeBuilder()).build() ?? [];\n this.source = { type: \"index\", name: indexName, range: indexRange };\n return this;\n }\n\n withSearchIndex<TIndexName extends TableSearchIndexNames<TTable>>(\n indexName: TIndexName,\n builder: (\n search: SearchIndexBuilder<\n TableSearchIndexConfig<TTable, TIndexName>[\"searchField\"],\n TableSearchIndexConfig<TTable, TIndexName>[\"filterFields\"]\n >\n ) => SearchIndexBuilder<\n TableSearchIndexConfig<TTable, TIndexName>[\"searchField\"],\n TableSearchIndexConfig<TTable, TIndexName>[\"filterFields\"]\n >\n ): this {\n this.source = {\n type: \"search\",\n name: indexName,\n query: builder(new RuntimeSearchIndexBuilder()).build()\n };\n return this;\n }\n\n order(order: \"asc\" | \"desc\"): this {\n this.orderDirection = order;\n return this;\n }\n\n filter(builder: (filter: FilterBuilder) => QueryExpression): this {\n this.filterExpression = builder(new RuntimeFilterBuilder());\n return this;\n }\n\n async collect(): Promise<TDocument[]> {\n return this.execute();\n }\n\n async take(count: number): Promise<TDocument[]> {\n return this.execute({ limit: count });\n }\n\n async first(): Promise<TDocument | null> {\n const results = await this.execute({ limit: 1 });\n return results[0] ?? null;\n }\n\n async unique(): Promise<TDocument | null> {\n const results = await this.execute({ limit: 2 });\n if (results.length > 1) {\n throw new Error(\"Expected a unique result but found multiple rows.\");\n }\n return results[0] ?? null;\n }\n\n async paginate(\n options: PaginationOptions\n ): Promise<PaginationResult<TDocument>> {\n const offset = options.cursor ? Number.parseInt(options.cursor, 10) : 0;\n const page = await this.execute({ limit: options.numItems, offset });\n const nextCursor =\n page.length < options.numItems ? null : String(offset + page.length);\n return {\n page,\n cursor: nextCursor,\n isDone: nextCursor === null\n };\n }\n\n private async execute(options?: {\n limit?: number;\n offset?: number;\n }): Promise<TDocument[]> {\n this.dependencyCollector?.add(`table:${this.tableName}`);\n const queryOptions: ExecuteQueryBuilderOptions = {\n tableName: this.tableName,\n source: this.source,\n filterExpression: this.filterExpression,\n orderDirection: this.orderDirection\n };\n if (this.dependencyCollector) {\n queryOptions.dependencyCollector = this.dependencyCollector;\n }\n if (options?.limit !== undefined) {\n queryOptions.limit = options.limit;\n }\n if (options?.offset !== undefined) {\n queryOptions.offset = options.offset;\n }\n return this.executeQuery(queryOptions);\n }\n}\n\nexport class ExecutionEngine<\n TSchema extends SyncoreDataModel\n> {\n constructor(private readonly deps: ExecutionEngineDeps<TSchema>) {}\n\n createClient(): SyncoreClient {\n return {\n query: (reference, ...args) =>\n this.runQuery(reference, normalizeOptionalArgs(args) as JsonObject),\n mutation: (reference, ...args) =>\n this.runMutation(reference, normalizeOptionalArgs(args) as JsonObject),\n action: (reference, ...args) =>\n this.runAction(reference, normalizeOptionalArgs(args) as JsonObject),\n watchQuery: (reference, ...args) =>\n this.watchQuery(reference, normalizeOptionalArgs(args) as JsonObject),\n watchRuntimeStatus: () => this.deps.runtimeStatus.watch()\n };\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {}\n ): SyncoreWatch<TResult> {\n return this.deps.reactivity.watchQuery(reference, args);\n }\n\n async runQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"query\");\n const dependencyCollector = new Set<DependencyKey>();\n const startedAt = Date.now();\n const result = await this.invokeFunction<TResult>(definition, args, {\n mutationDepth: 0,\n changedTables: new Set<string>(),\n storageChanges: [],\n dependencyCollector,\n componentMetadata: definition.__syncoreComponent\n });\n\n this.deps.devtools.emit({\n type: \"query.executed\",\n runtimeId: this.deps.runtimeId,\n queryId: reference.name,\n functionName: reference.name,\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n dependencies: [...dependencyCollector],\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n\n return result;\n }\n\n async runMutation<TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"mutation\");\n const mutationId = generateId();\n const startedAt = Date.now();\n const execution = await this.deps.transactionCoordinator.runInTransaction(\n async (transactionState) =>\n this.invokeFunction<TResult>(definition, args, {\n mutationDepth: 1,\n changedTables: transactionState.changedTables,\n storageChanges: transactionState.storageChanges,\n componentMetadata: definition.__syncoreComponent\n })\n );\n\n await this.finalizeStatefulExecution(\n mutationId,\n execution,\n Date.now() - startedAt\n );\n\n this.deps.devtools.emit({\n type: \"mutation.committed\",\n runtimeId: this.deps.runtimeId,\n mutationId,\n functionName: reference.name,\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n changedTables: [...execution.changedTables],\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n\n return execution.result;\n }\n\n async runAction<TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"action\");\n const actionId = generateId();\n const startedAt = Date.now();\n const state = this.deps.transactionCoordinator.createState();\n\n try {\n const result = await this.invokeFunction<TResult>(definition, args, {\n mutationDepth: 0,\n changedTables: state.changedTables,\n storageChanges: state.storageChanges,\n componentMetadata: definition.__syncoreComponent\n });\n await this.finalizeStatefulExecution(\n actionId,\n createEmptyExecutionResult(result, state),\n Date.now() - startedAt\n );\n this.deps.devtools.emit({\n type: \"action.completed\",\n runtimeId: this.deps.runtimeId,\n actionId,\n functionName: reference.name,\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n return result;\n } catch (error) {\n this.deps.devtools.emit({\n type: \"action.completed\",\n runtimeId: this.deps.runtimeId,\n actionId,\n functionName: reference.name,\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {}),\n error: error instanceof Error ? error.message : String(error)\n });\n throw error;\n }\n }\n\n async runDevtoolsMutation<TResult>(\n callback: (ctx: { db: SyncoreDatabaseWriter<TSchema> }) => Promise<TResult>,\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const mutationId = generateId();\n const startedAt = Date.now();\n const execution = await this.deps.transactionCoordinator.runInTransaction(\n async (transactionState) =>\n callback({\n db: this.createDatabaseWriter({\n mutationDepth: 1,\n changedTables: transactionState.changedTables,\n storageChanges: transactionState.storageChanges\n })\n })\n );\n\n await this.finalizeStatefulExecution(\n mutationId,\n execution,\n Date.now() - startedAt\n );\n\n this.deps.devtools.emit({\n type: \"mutation.committed\",\n runtimeId: this.deps.runtimeId,\n mutationId,\n functionName: \"__devtools__/mutation\",\n changedTables: [...execution.changedTables],\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n return execution.result;\n }\n\n private async finalizeStatefulExecution<TResult>(\n executionId: string,\n execution: ExecutionResult<TResult>,\n durationMs: number\n ): Promise<void> {\n const changedScopes = collectChangedScopes(\n execution.changedTables,\n execution.storageChanges\n );\n if (changedScopes.size > 0) {\n await this.deps.reactivity.refreshQueriesForScopes(\n changedScopes,\n `Execution ${executionId} touched ${[...changedScopes].join(\", \")}`\n );\n }\n if (execution.changedTables.size > 0) {\n await this.deps.reactivity.publishExternalChange({\n scope: \"database\",\n reason: \"commit\",\n changedScopes: [...changedScopes].filter((scope) =>\n scope.startsWith(\"table:\")\n ),\n changedTables: [...execution.changedTables]\n });\n }\n await this.deps.reactivity.publishStorageChanges(execution.storageChanges);\n }\n\n async collectQueryDependencies(\n functionName: string,\n args: JsonObject\n ): Promise<Set<DependencyKey>> {\n const definition = this.resolveFunction(\n { kind: \"query\", name: functionName },\n \"query\"\n );\n const dependencyCollector = new Set<DependencyKey>();\n await this.invokeFunction(definition, args, {\n mutationDepth: 0,\n changedTables: new Set<string>(),\n storageChanges: [],\n dependencyCollector,\n componentMetadata: definition.__syncoreComponent\n });\n return dependencyCollector;\n }\n\n private async executeQueryBuilder<TDocument>(\n options: ExecuteQueryBuilderOptions\n ): Promise<TDocument[]> {\n const table = this.deps.schema.getTableDefinition(options.tableName);\n const params: unknown[] = [];\n const whereClauses: string[] = [];\n const orderClauses: string[] = [];\n let joinClause = \"\";\n const source = options.source;\n\n if (source.type === \"index\") {\n const index = table.indexes.find(\n (candidate) => candidate.name === source.name\n );\n if (!index) {\n throw new Error(\n `Unknown index \"${source.name}\" on table \"${options.tableName}\".`\n );\n }\n for (const condition of source.range) {\n whereClauses.push(this.renderCondition(\"t\", condition, params));\n }\n const primaryField = index.fields[0];\n if (primaryField) {\n orderClauses.push(\n `${fieldExpression(\"t\", primaryField)} ${options.orderDirection.toUpperCase()}`\n );\n }\n }\n\n if (source.type === \"search\") {\n const searchIndex = table.searchIndexes.find(\n (candidate) => candidate.name === source.name\n );\n if (!searchIndex) {\n throw new Error(\n `Unknown search index \"${source.name}\" on table \"${options.tableName}\".`\n );\n }\n if (searchIndex.searchField !== source.query.searchField) {\n throw new Error(\n `Search index \"${searchIndex.name}\" expects field \"${searchIndex.searchField}\".`\n );\n }\n if (this.deps.schema.isSearchIndexDisabled(options.tableName, searchIndex.name)) {\n whereClauses.push(\n `${fieldExpression(\"t\", searchIndex.searchField)} LIKE ?`\n );\n params.push(`%${source.query.searchText}%`);\n } else {\n const searchTableName = resolveSearchIndexTableName(\n options.tableName,\n searchIndex.name\n );\n joinClause = `JOIN ${quoteIdentifier(searchTableName)} s ON s._id = t._id`;\n whereClauses.push(`s.search_value MATCH ?`);\n params.push(source.query.searchText);\n }\n for (const condition of source.query.filters) {\n whereClauses.push(this.renderCondition(\"t\", condition, params));\n }\n }\n\n if (options.filterExpression) {\n whereClauses.push(\n this.renderExpression(\"t\", options.filterExpression, params)\n );\n }\n\n if (orderClauses.length === 0) {\n orderClauses.push(\n `t._creationTime ${options.orderDirection.toUpperCase()}`\n );\n }\n orderClauses.push(`t._id ${options.orderDirection.toUpperCase()}`);\n\n const sql = [\n `SELECT t._id, t._creationTime, t._json FROM ${quoteIdentifier(options.tableName)} t`,\n joinClause,\n whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\",\n `ORDER BY ${orderClauses.join(\", \")}`,\n options.limit !== undefined ? `LIMIT ${options.limit}` : \"\",\n options.offset !== undefined ? `OFFSET ${options.offset}` : \"\"\n ]\n .filter(Boolean)\n .join(\" \");\n\n const rows = await this.deps.driver.all<DatabaseRow>(sql, params);\n return rows.map((row) =>\n this.deps.schema.deserializeDocument<TDocument>(options.tableName, row)\n );\n }\n\n private async invokeFunction<TResult>(\n definition: RegisteredSyncoreFunction,\n rawArgs: JsonObject,\n state: RuntimeExecutionState\n ): Promise<TResult> {\n const args = definition.argsValidator.parse(rawArgs) as JsonObject;\n const ctx = this.createContext(definition.kind, {\n ...state,\n componentMetadata:\n definition.__syncoreComponent ?? state.componentMetadata\n });\n const result = (await definition.handler(ctx, args)) as TResult;\n if (definition.returnsValidator) {\n return definition.returnsValidator.parse(result) as TResult;\n }\n return result;\n }\n\n private createContext(\n kind: SyncoreFunctionKind,\n state: RuntimeExecutionState\n ): QueryCtx<TSchema> | MutationCtx<TSchema> | ActionCtx<TSchema> {\n const db =\n kind === \"mutation\"\n ? this.createDatabaseWriter(state)\n : this.createDatabaseReader(state);\n const storage = this.deps.storage.createStorageApi(state);\n const scheduler = this.createSchedulerApi(state.componentMetadata);\n const callerMetadata = state.componentMetadata;\n\n return {\n db,\n storage,\n capabilities: this.deps.capabilities,\n capabilityDescriptors: this.deps.capabilityDescriptors,\n ...(callerMetadata\n ? {\n component: {\n path: callerMetadata.componentPath,\n name: callerMetadata.componentName,\n version: callerMetadata.version,\n capabilities: callerMetadata.grantedCapabilities\n }\n }\n : {}),\n scheduler,\n runQuery: <TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) =>\n this.runQuery(\n this.resolveReferenceForCaller(reference, \"query\", callerMetadata),\n normalizeOptionalArgs(args) as JsonObject\n ),\n runMutation: <TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) => {\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n \"mutation\",\n callerMetadata\n );\n const normalizedArgs = normalizeOptionalArgs(args);\n if (kind === \"mutation\") {\n return this.deps.driver.withSavepoint(\n `sp_${generateId().replace(/-/g, \"_\")}`,\n () =>\n this.invokeFunction<TResult>(\n this.resolveFunction(\n resolvedReference,\n \"mutation\",\n callerMetadata\n ),\n normalizedArgs as JsonObject,\n {\n mutationDepth: state.mutationDepth + 1,\n changedTables: state.changedTables,\n storageChanges: state.storageChanges,\n componentMetadata: callerMetadata\n }\n )\n );\n }\n return this.runMutation(resolvedReference, normalizedArgs as JsonObject);\n },\n runAction: <TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) =>\n this.runAction(\n this.resolveReferenceForCaller(reference, \"action\", callerMetadata),\n normalizeOptionalArgs(args) as JsonObject\n )\n } as QueryCtx<TSchema> | MutationCtx<TSchema> | ActionCtx<TSchema>;\n }\n\n private createDatabaseReader(\n state: RuntimeExecutionState\n ): SyncoreDatabaseReader<TSchema> {\n return {\n get: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n state.dependencyCollector?.add(`table:${scopedTableName}`);\n state.dependencyCollector?.add(`row:${scopedTableName}:${id}`);\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n return row\n ? this.deps.schema.deserializeDocument<\n DocumentForTable<TSchema, TTableName>\n >(scopedTableName, row)\n : null;\n },\n query: <TTableName extends TableNames<TSchema>>(tableName: TTableName) =>\n new RuntimeQueryBuilder<\n TSchema[\"tables\"][TTableName],\n DocumentForTable<TSchema, TTableName>\n >(\n (options) =>\n this.executeQueryBuilder<DocumentForTable<TSchema, TTableName>>(\n {\n ...options,\n tableName: this.resolveTableName(\n tableName,\n state.componentMetadata\n )\n }\n ),\n this.resolveTableName(tableName, state.componentMetadata),\n state.dependencyCollector\n ),\n raw: <TValue>(sql: string, params?: unknown[]) =>\n this.deps.driver.all<TValue>(sql, params)\n };\n }\n\n private createDatabaseWriter(\n state: RuntimeExecutionState\n ): SyncoreDatabaseWriter<TSchema> {\n const reader = this.createDatabaseReader(state);\n\n return {\n ...reader,\n insert: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n value: InsertValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n value as JsonObject\n );\n const id = generateId();\n const creationTime = Date.now();\n const json = stableStringify(validated);\n await this.deps.driver.run(\n `INSERT INTO ${quoteIdentifier(scopedTableName)} (_id, _creationTime, _json) VALUES (?, ?, ?)`,\n [id, creationTime, json]\n );\n await this.deps.schema.syncSearchIndexes(scopedTableName, {\n _id: id,\n _creationTime: creationTime,\n _json: json\n });\n state.changedTables.add(scopedTableName);\n return id;\n },\n patch: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string,\n value: PatchValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const current = await reader.get(tableName, id);\n if (!current) {\n throw new Error(`Document \"${id}\" does not exist in \"${scopedTableName}\".`);\n }\n const merged: JsonObject = { ...omitSystemFields(current), ...value };\n for (const key of Object.keys(merged)) {\n if (merged[key] === undefined) {\n delete merged[key];\n }\n }\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n merged\n );\n await this.deps.driver.run(\n `UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`,\n [stableStringify(validated), id]\n );\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n if (row) {\n await this.deps.schema.syncSearchIndexes(scopedTableName, row);\n }\n state.changedTables.add(scopedTableName);\n },\n replace: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string,\n value: InsertValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n value as JsonObject\n );\n await this.deps.driver.run(\n `UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`,\n [stableStringify(validated), id]\n );\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n if (!row) {\n throw new Error(`Document \"${id}\" does not exist in \"${scopedTableName}\".`);\n }\n await this.deps.schema.syncSearchIndexes(scopedTableName, row);\n state.changedTables.add(scopedTableName);\n },\n delete: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n await this.deps.driver.run(\n `DELETE FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n await this.deps.schema.removeSearchIndexes(scopedTableName, id);\n state.changedTables.add(scopedTableName);\n }\n };\n }\n\n private createSchedulerApi(\n componentMetadata?: SyncoreComponentFunctionMetadata\n ): SchedulerApi {\n return {\n runAfter: async (delayMs, reference, ...args) => {\n if (\n componentMetadata &&\n !componentMetadata.grantedCapabilities.includes(\"scheduler\")\n ) {\n throw new Error(\n `Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`\n );\n }\n const schedulerArgs = splitSchedulerArgs(args);\n const functionArgs = schedulerArgs[0];\n const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n reference.kind,\n componentMetadata\n );\n return this.deps.scheduler.scheduleJob(\n Date.now() + delayMs,\n resolvedReference,\n functionArgs,\n misfirePolicy,\n componentMetadata\n ? `component:${componentMetadata.componentPath}:`\n : undefined\n );\n },\n runAt: async (timestamp, reference, ...args) => {\n if (\n componentMetadata &&\n !componentMetadata.grantedCapabilities.includes(\"scheduler\")\n ) {\n throw new Error(\n `Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`\n );\n }\n const schedulerArgs = splitSchedulerArgs(args);\n const functionArgs = schedulerArgs[0];\n const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;\n const value =\n timestamp instanceof Date ? timestamp.getTime() : timestamp;\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n reference.kind,\n componentMetadata\n );\n return this.deps.scheduler.scheduleJob(\n value,\n resolvedReference,\n functionArgs,\n misfirePolicy,\n componentMetadata\n ? `component:${componentMetadata.componentPath}:`\n : undefined\n );\n },\n cancel: async (id) => {\n await this.deps.scheduler.cancelScheduledJob(id);\n }\n };\n }\n\n private resolveFunction<TKind extends SyncoreFunctionKind>(\n reference: FunctionReference<TKind, unknown, unknown>,\n expectedKind: TKind,\n callerMetadata?: SyncoreComponentFunctionMetadata\n ): RegisteredSyncoreFunction & {\n kind: TKind;\n } {\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n expectedKind,\n callerMetadata\n );\n const definition = this.deps.functions[resolvedReference.name];\n if (!definition) {\n throw new Error(`Unknown function \"${resolvedReference.name}\".`);\n }\n if (definition.kind !== expectedKind) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is a ${definition.kind}, expected ${expectedKind}.`\n );\n }\n const metadata = definition.__syncoreComponent;\n if (metadata?.visibility === \"internal\") {\n if (!callerMetadata) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is internal to component \"${metadata.componentPath}\".`\n );\n }\n if (callerMetadata.componentPath !== metadata.componentPath) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is internal to component \"${metadata.componentPath}\" and cannot be called from \"${callerMetadata.componentPath}\".`\n );\n }\n }\n return definition as RegisteredSyncoreFunction & {\n kind: TKind;\n };\n }\n\n private renderExpression(\n tableAlias: string,\n expression: QueryExpression,\n params: unknown[]\n ): string {\n if (expression.type === \"condition\") {\n return this.renderCondition(tableAlias, expression.condition, params);\n }\n const separator = expression.type === \"and\" ? \" AND \" : \" OR \";\n return `(${expression.expressions\n .map((child) => this.renderExpression(tableAlias, child, params))\n .join(separator)})`;\n }\n\n private renderCondition(\n tableAlias: string,\n condition: {\n field: string;\n operator: \"=\" | \">\" | \">=\" | \"<\" | \"<=\";\n value: unknown;\n },\n params: unknown[]\n ): string {\n params.push(condition.value);\n return `${fieldExpression(tableAlias, condition.field)} ${condition.operator} ?`;\n }\n\n private resolveReferenceForCaller<TKind extends SyncoreFunctionKind>(\n reference: FunctionReference<TKind, unknown, unknown>,\n expectedKind: TKind,\n callerMetadata?: SyncoreComponentFunctionMetadata\n ): FunctionReference<TKind, unknown, unknown> {\n if (!callerMetadata) {\n return reference;\n }\n\n if (reference.name.startsWith(\"components/\")) {\n return reference;\n }\n\n const bindingMatch = /^binding:([^/]+)\\/(.+)$/.exec(reference.name);\n if (bindingMatch) {\n const bindingName = bindingMatch[1]!;\n const localName = bindingMatch[2]!;\n const targetComponentPath = callerMetadata.bindings[bindingName];\n if (!targetComponentPath) {\n throw new Error(\n `Component ${JSON.stringify(callerMetadata.componentPath)} does not define binding ${JSON.stringify(bindingName)}.`\n );\n }\n const canonicalName = toCanonicalComponentFunctionName(\n targetComponentPath,\n \"public\",\n localName\n );\n return {\n kind: expectedKind,\n name: canonicalName\n };\n }\n\n const internalName = toCanonicalComponentFunctionName(\n callerMetadata.componentPath,\n \"internal\",\n reference.name\n );\n if (this.deps.functions[internalName]) {\n return {\n kind: expectedKind,\n name: internalName\n };\n }\n\n const publicName = toCanonicalComponentFunctionName(\n callerMetadata.componentPath,\n \"public\",\n reference.name\n );\n if (this.deps.functions[publicName]) {\n return {\n kind: expectedKind,\n name: publicName\n };\n }\n\n return reference;\n }\n\n private resolveTableName<TTableName extends string>(\n tableName: TTableName,\n componentMetadata?: SyncoreComponentFunctionMetadata\n ): TTableName {\n if (!componentMetadata) {\n return tableName;\n }\n\n const scopedTableName = componentMetadata.localTables[tableName];\n if (!scopedTableName) {\n throw new Error(\n `Table ${JSON.stringify(tableName)} is not available inside component ${JSON.stringify(componentMetadata.componentPath)}.`\n );\n }\n\n return scopedTableName as TTableName;\n }\n}\n\nfunction collectChangedScopes(\n changedTables: Set<string>,\n storageChanges: Array<{\n storageId: string;\n reason: \"storage-put\" | \"storage-delete\";\n }>\n): Set<ImpactScope> {\n return new Set<ImpactScope>([\n ...[...changedTables].map((tableName) => `table:${tableName}` as ImpactScope),\n ...storageChanges.map(\n (change) => `storage:${change.storageId}` as ImpactScope\n )\n ]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"executionEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/executionEngine.ts"],"sourcesContent":["import type {\n FunctionArgsFromDefinition,\n FunctionKindFromDefinition,\n FunctionReference,\n FunctionResultFromDefinition,\n MisfirePolicy,\n SyncoreFunctionKind\n} from \"../../functions.js\";\nimport {\n toCanonicalComponentFunctionName,\n type SyncoreComponentFunctionMetadata\n} from \"../../components.js\";\nimport type {\n ActionCtx,\n CapabilityDescriptor,\n DevtoolsLiveQueryScope,\n DocumentForTable,\n ExecutionResult,\n FilterBuilder,\n ImpactScope,\n IndexRangeBuilder,\n InsertValueForTable,\n JsonObject,\n MutationCtx,\n PatchValueForTable,\n PaginationOptions,\n PaginationResult,\n QueryBuilder,\n QueryCtx,\n QueryExpression,\n RegisteredSyncoreFunction,\n SchedulerApi,\n SearchIndexBuilder,\n SearchQuery,\n SyncoreCapabilities,\n SyncoreClient,\n SyncoreDataModel,\n SyncoreDatabaseReader,\n SyncoreDatabaseWriter,\n SyncoreFunctionRegistry,\n SyncoreSqlDriver,\n SyncoreWatch,\n TableNames\n} from \"../../runtime.js\";\nimport type {\n AnyTableDefinition as SchemaAnyTableDefinition,\n TableIndexFields,\n TableIndexNames,\n TableSearchIndexConfig,\n TableSearchIndexNames\n} from \"@syncore/schema\";\nimport { DevtoolsEngine } from \"./devtoolsEngine.js\";\nimport { SchemaEngine } from \"./schemaEngine.js\";\nimport { StorageEngine } from \"./storageEngine.js\";\nimport { SchedulerEngine } from \"./schedulerEngine.js\";\nimport { ReactivityEngine } from \"./reactivityEngine.js\";\nimport {\n createDevtoolsPreview,\n fieldExpression,\n normalizeOptionalArgs,\n omitSystemFields,\n quoteIdentifier,\n resolveSearchIndexTableName,\n splitSchedulerArgs,\n stableStringify,\n type DatabaseRow,\n type DependencyKey,\n type DevtoolsEventMeta,\n type ExecuteQueryBuilderOptions,\n type QuerySource,\n type RuntimeExecutionState\n} from \"./shared.js\";\nimport { generateId } from \"../../id.js\";\nimport type { Validator } from \"@syncore/schema\";\nimport {\n TransactionCoordinator,\n createEmptyExecutionResult\n} from \"../transactionCoordinator.js\";\nimport type { RuntimeStatusController } from \"../runtimeStatus.js\";\n\nconst DEFAULT_MISFIRE_POLICY: MisfirePolicy = { type: \"catch_up\" };\n\ntype OptionalArgsTuple<TArgs> =\n Record<never, never> extends TArgs ? [args?: TArgs] : [args: TArgs];\n\ntype ExecutionEngineDeps<TSchema extends SyncoreDataModel> = {\n runtimeId: string;\n functions: SyncoreFunctionRegistry;\n driver: SyncoreSqlDriver;\n capabilities: Readonly<SyncoreCapabilities>;\n capabilityDescriptors: ReadonlyArray<CapabilityDescriptor>;\n schema: SchemaEngine<TSchema>;\n storage: StorageEngine;\n scheduler: SchedulerEngine;\n reactivity: ReactivityEngine;\n devtools: DevtoolsEngine;\n transactionCoordinator: TransactionCoordinator;\n runtimeStatus: RuntimeStatusController;\n};\n\nclass RuntimeFilterBuilder implements FilterBuilder {\n eq(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"=\", value } };\n }\n\n gt(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \">\", value } };\n }\n\n gte(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \">=\", value } };\n }\n\n lt(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"<\", value } };\n }\n\n lte(field: string, value: unknown): QueryExpression {\n return { type: \"condition\", condition: { field, operator: \"<=\", value } };\n }\n\n and(...expressions: QueryExpression[]): QueryExpression {\n return { type: \"and\", expressions };\n }\n\n or(...expressions: QueryExpression[]): QueryExpression {\n return { type: \"or\", expressions };\n }\n}\n\nclass RuntimeIndexRangeBuilder<\n TFieldName extends string = string\n> implements IndexRangeBuilder<TFieldName> {\n private readonly conditions: Array<{\n field: string;\n operator: \"=\" | \">\" | \">=\" | \"<\" | \"<=\";\n value: unknown;\n }> = [];\n\n eq(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"=\", value });\n return this;\n }\n\n gt(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \">\", value });\n return this;\n }\n\n gte(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \">=\", value });\n return this;\n }\n\n lt(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"<\", value });\n return this;\n }\n\n lte(field: TFieldName, value: unknown): IndexRangeBuilder<TFieldName> {\n this.conditions.push({ field, operator: \"<=\", value });\n return this;\n }\n\n build() {\n return [...this.conditions];\n }\n}\n\nclass RuntimeSearchIndexBuilder<\n TSearchField extends string = string,\n TFilterField extends string = string\n> implements SearchIndexBuilder<TSearchField, TFilterField> {\n private searchField: string | undefined;\n private searchText: string | undefined;\n private readonly filters: Array<{\n field: string;\n operator: \"=\";\n value: unknown;\n }> = [];\n\n search(\n field: TSearchField,\n value: string\n ): SearchIndexBuilder<TSearchField, TFilterField> {\n this.searchField = field;\n this.searchText = value;\n return this;\n }\n\n eq(\n field: TFilterField,\n value: unknown\n ): SearchIndexBuilder<TSearchField, TFilterField> {\n this.filters.push({ field, operator: \"=\", value });\n return this;\n }\n\n build(): SearchQuery {\n if (!this.searchField || !this.searchText) {\n throw new Error(\"Search queries require a search field and search text.\");\n }\n return {\n searchField: this.searchField,\n searchText: this.searchText,\n filters: [...this.filters]\n };\n }\n}\n\nclass RuntimeQueryBuilder<\n TTable extends SchemaAnyTableDefinition,\n TDocument\n> implements QueryBuilder<TTable, TDocument> {\n private orderDirection: \"asc\" | \"desc\" = \"asc\";\n private source: QuerySource = { type: \"table\" };\n private filterExpression: QueryExpression | undefined;\n\n constructor(\n private readonly executeQuery: (\n options: ExecuteQueryBuilderOptions\n ) => Promise<TDocument[]>,\n private readonly tableName: string,\n private readonly dependencyCollector?: Set<DependencyKey>\n ) {}\n\n withIndex<TIndexName extends TableIndexNames<TTable>>(\n indexName: TIndexName,\n builder?: (\n range: IndexRangeBuilder<TableIndexFields<TTable, TIndexName>[number]>\n ) => IndexRangeBuilder<TableIndexFields<TTable, TIndexName>[number]>\n ): this {\n const indexRange = builder?.(new RuntimeIndexRangeBuilder()).build() ?? [];\n this.source = { type: \"index\", name: indexName, range: indexRange };\n return this;\n }\n\n withSearchIndex<TIndexName extends TableSearchIndexNames<TTable>>(\n indexName: TIndexName,\n builder: (\n search: SearchIndexBuilder<\n TableSearchIndexConfig<TTable, TIndexName>[\"searchField\"],\n TableSearchIndexConfig<TTable, TIndexName>[\"filterFields\"]\n >\n ) => SearchIndexBuilder<\n TableSearchIndexConfig<TTable, TIndexName>[\"searchField\"],\n TableSearchIndexConfig<TTable, TIndexName>[\"filterFields\"]\n >\n ): this {\n this.source = {\n type: \"search\",\n name: indexName,\n query: builder(new RuntimeSearchIndexBuilder()).build()\n };\n return this;\n }\n\n order(order: \"asc\" | \"desc\"): this {\n this.orderDirection = order;\n return this;\n }\n\n filter(builder: (filter: FilterBuilder) => QueryExpression): this {\n this.filterExpression = builder(new RuntimeFilterBuilder());\n return this;\n }\n\n async collect(): Promise<TDocument[]> {\n return this.execute();\n }\n\n async take(count: number): Promise<TDocument[]> {\n return this.execute({ limit: count });\n }\n\n async first(): Promise<TDocument | null> {\n const results = await this.execute({ limit: 1 });\n return results[0] ?? null;\n }\n\n async unique(): Promise<TDocument | null> {\n const results = await this.execute({ limit: 2 });\n if (results.length > 1) {\n throw new Error(\"Expected a unique result but found multiple rows.\");\n }\n return results[0] ?? null;\n }\n\n async paginate(\n options: PaginationOptions\n ): Promise<PaginationResult<TDocument>> {\n const offset = options.cursor ? Number.parseInt(options.cursor, 10) : 0;\n const page = await this.execute({ limit: options.numItems, offset });\n const nextCursor =\n page.length < options.numItems ? null : String(offset + page.length);\n return {\n page,\n cursor: nextCursor,\n isDone: nextCursor === null\n };\n }\n\n private async execute(options?: {\n limit?: number;\n offset?: number;\n }): Promise<TDocument[]> {\n this.dependencyCollector?.add(`table:${this.tableName}`);\n const queryOptions: ExecuteQueryBuilderOptions = {\n tableName: this.tableName,\n source: this.source,\n filterExpression: this.filterExpression,\n orderDirection: this.orderDirection\n };\n if (this.dependencyCollector) {\n queryOptions.dependencyCollector = this.dependencyCollector;\n }\n if (options?.limit !== undefined) {\n queryOptions.limit = options.limit;\n }\n if (options?.offset !== undefined) {\n queryOptions.offset = options.offset;\n }\n return this.executeQuery(queryOptions);\n }\n}\n\nexport class ExecutionEngine<\n TSchema extends SyncoreDataModel\n> {\n constructor(private readonly deps: ExecutionEngineDeps<TSchema>) {}\n\n createClient(): SyncoreClient {\n return {\n query: (reference, ...args) =>\n this.runQuery(reference, normalizeOptionalArgs(args) as JsonObject),\n mutation: (reference, ...args) =>\n this.runMutation(reference, normalizeOptionalArgs(args) as JsonObject),\n action: (reference, ...args) =>\n this.runAction(reference, normalizeOptionalArgs(args) as JsonObject),\n watchQuery: (reference, ...args) =>\n this.watchQuery(reference, normalizeOptionalArgs(args) as JsonObject),\n watchRuntimeStatus: () => this.deps.runtimeStatus.watch()\n };\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {}\n ): SyncoreWatch<TResult> {\n return this.deps.reactivity.watchQuery(reference, args);\n }\n\n async runQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"query\");\n const dependencyCollector = new Set<DependencyKey>();\n const executionId = meta.executionId ?? generateId();\n const startedAt = Date.now();\n const result = await this.invokeFunction<TResult>(definition, args, {\n executionId,\n mutationDepth: 0,\n changedTables: new Set<string>(),\n documentChanges: [],\n storageChanges: [],\n dependencyCollector,\n componentMetadata: definition.__syncoreComponent\n });\n const completedAt = Date.now();\n\n this.deps.devtools.emit({\n type: \"query.executed\",\n runtimeId: this.deps.runtimeId,\n queryId: reference.name,\n functionName: reference.name,\n executionId,\n ...(meta.parentExecutionId\n ? { parentExecutionId: meta.parentExecutionId }\n : {}),\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n dependencies: [...dependencyCollector],\n argsPreview: createDevtoolsPreview(args),\n resultPreview: createDevtoolsPreview(result),\n readScopes: [...dependencyCollector],\n durationMs: completedAt - startedAt,\n timestamp: completedAt,\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n\n return result;\n }\n\n async runMutation<TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"mutation\");\n const mutationId = generateId();\n const executionId = meta.executionId ?? mutationId;\n const startedAt = Date.now();\n const execution = await this.deps.transactionCoordinator.runInTransaction(\n async (transactionState) =>\n this.invokeFunction<TResult>(definition, args, {\n executionId,\n mutationDepth: 1,\n changedTables: transactionState.changedTables,\n documentChanges: transactionState.documentChanges,\n storageChanges: transactionState.storageChanges,\n componentMetadata: definition.__syncoreComponent\n })\n );\n const completedAt = Date.now();\n\n const impact = this.collectStatefulExecutionImpact(execution);\n\n this.deps.devtools.emit({\n type: \"mutation.committed\",\n runtimeId: this.deps.runtimeId,\n mutationId,\n functionName: reference.name,\n executionId,\n ...(meta.parentExecutionId\n ? { parentExecutionId: meta.parentExecutionId }\n : {}),\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n changedTables: [...execution.changedTables],\n argsPreview: createDevtoolsPreview(args),\n resultPreview: createDevtoolsPreview(execution.result),\n writeScopes: [...impact.changedScopes],\n changedScopes: [...impact.changedScopes],\n changedDocumentsPreview: execution.documentChanges,\n invalidatedQueryIds: impact.invalidatedQueryIds,\n durationMs: completedAt - startedAt,\n timestamp: completedAt,\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n await this.publishStatefulExecutionEffects(\n executionId,\n execution,\n impact.changedScopes\n );\n\n return execution.result;\n }\n\n async runAction<TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n args: JsonObject = {},\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const definition = this.resolveFunction(reference, \"action\");\n const actionId = generateId();\n const executionId = meta.executionId ?? actionId;\n const startedAt = Date.now();\n const state = this.deps.transactionCoordinator.createState();\n\n try {\n const result = await this.invokeFunction<TResult>(definition, args, {\n executionId,\n mutationDepth: 0,\n changedTables: state.changedTables,\n documentChanges: state.documentChanges,\n storageChanges: state.storageChanges,\n componentMetadata: definition.__syncoreComponent\n });\n const completedAt = Date.now();\n const execution = createEmptyExecutionResult(result, state);\n const impact = this.collectStatefulExecutionImpact(execution);\n this.deps.devtools.emit({\n type: \"action.completed\",\n runtimeId: this.deps.runtimeId,\n actionId,\n functionName: reference.name,\n executionId,\n ...(meta.parentExecutionId\n ? { parentExecutionId: meta.parentExecutionId }\n : {}),\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n argsPreview: createDevtoolsPreview(args),\n resultPreview: createDevtoolsPreview(result),\n writeScopes: [...impact.changedScopes],\n changedScopes: [...impact.changedScopes],\n changedDocumentsPreview: state.documentChanges,\n invalidatedQueryIds: impact.invalidatedQueryIds,\n durationMs: completedAt - startedAt,\n timestamp: completedAt,\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n await this.publishStatefulExecutionEffects(\n executionId,\n execution,\n impact.changedScopes\n );\n return result;\n } catch (error) {\n const completedAt = Date.now();\n this.deps.devtools.emit({\n type: \"action.completed\",\n runtimeId: this.deps.runtimeId,\n actionId,\n functionName: reference.name,\n executionId,\n ...(meta.parentExecutionId\n ? { parentExecutionId: meta.parentExecutionId }\n : {}),\n ...(definition.__syncoreComponent\n ? {\n componentPath: definition.__syncoreComponent.componentPath,\n componentName: definition.__syncoreComponent.componentName\n }\n : {}),\n argsPreview: createDevtoolsPreview(args),\n durationMs: completedAt - startedAt,\n timestamp: completedAt,\n ...(meta.origin ? { origin: meta.origin } : {}),\n error: error instanceof Error ? error.message : String(error)\n });\n throw error;\n }\n }\n\n async runDevtoolsMutation<TResult>(\n callback: (ctx: { db: SyncoreDatabaseWriter<TSchema> }) => Promise<TResult>,\n meta: DevtoolsEventMeta = {}\n ): Promise<TResult> {\n const mutationId = generateId();\n const executionId = meta.executionId ?? mutationId;\n const startedAt = Date.now();\n const execution = await this.deps.transactionCoordinator.runInTransaction(\n async (transactionState) =>\n callback({\n db: this.createDatabaseWriter({\n executionId,\n mutationDepth: 1,\n changedTables: transactionState.changedTables,\n documentChanges: transactionState.documentChanges,\n storageChanges: transactionState.storageChanges\n })\n })\n );\n const completedAt = Date.now();\n\n const impact = this.collectStatefulExecutionImpact(execution);\n\n this.deps.devtools.emit({\n type: \"mutation.committed\",\n runtimeId: this.deps.runtimeId,\n mutationId,\n functionName: \"__devtools__/mutation\",\n executionId,\n ...(meta.parentExecutionId\n ? { parentExecutionId: meta.parentExecutionId }\n : {}),\n changedTables: [...execution.changedTables],\n argsPreview: createDevtoolsPreview({ source: \"dashboard\" }),\n resultPreview: createDevtoolsPreview(execution.result),\n writeScopes: [...impact.changedScopes],\n changedScopes: [...impact.changedScopes],\n changedDocumentsPreview: execution.documentChanges,\n invalidatedQueryIds: impact.invalidatedQueryIds,\n durationMs: completedAt - startedAt,\n timestamp: completedAt,\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n await this.publishStatefulExecutionEffects(\n executionId,\n execution,\n impact.changedScopes\n );\n return execution.result;\n }\n\n private collectStatefulExecutionImpact<TResult>(\n execution: ExecutionResult<TResult>\n ): { changedScopes: Set<ImpactScope>; invalidatedQueryIds: string[] } {\n const changedScopes = collectChangedScopes(\n execution.changedTables,\n execution.storageChanges\n );\n const invalidatedQueryIds =\n changedScopes.size > 0\n ? this.deps.reactivity.getInvalidatedQueryIdsForScopes(changedScopes)\n : [];\n return { changedScopes, invalidatedQueryIds };\n }\n\n private async publishStatefulExecutionEffects<TResult>(\n executionId: string,\n execution: ExecutionResult<TResult>,\n changedScopes: Set<ImpactScope>\n ): Promise<void> {\n if (changedScopes.size > 0) {\n await this.deps.reactivity.refreshQueriesForScopes(\n changedScopes,\n `Execution ${executionId} touched ${[...changedScopes].join(\", \")}`,\n { executionId }\n );\n }\n if (execution.changedTables.size > 0) {\n await this.deps.reactivity.publishExternalChange({\n scope: \"database\",\n reason: \"commit\",\n changedScopes: [...changedScopes].filter((scope) =>\n scope.startsWith(\"table:\")\n ),\n changedTables: [...execution.changedTables]\n });\n }\n await this.deps.reactivity.publishStorageChanges(execution.storageChanges);\n }\n\n async collectQueryDependencies(\n functionName: string,\n args: JsonObject\n ): Promise<Set<DependencyKey>> {\n const definition = this.resolveFunction(\n { kind: \"query\", name: functionName },\n \"query\"\n );\n const dependencyCollector = new Set<DependencyKey>();\n await this.invokeFunction(definition, args, {\n executionId: generateId(),\n mutationDepth: 0,\n changedTables: new Set<string>(),\n documentChanges: [],\n storageChanges: [],\n dependencyCollector,\n componentMetadata: definition.__syncoreComponent\n });\n return dependencyCollector;\n }\n\n private async executeQueryBuilder<TDocument>(\n options: ExecuteQueryBuilderOptions\n ): Promise<TDocument[]> {\n const table = this.deps.schema.getTableDefinition(options.tableName);\n const params: unknown[] = [];\n const whereClauses: string[] = [];\n const orderClauses: string[] = [];\n let joinClause = \"\";\n const source = options.source;\n\n if (source.type === \"index\") {\n const index = table.indexes.find(\n (candidate) => candidate.name === source.name\n );\n if (!index) {\n throw new Error(\n `Unknown index \"${source.name}\" on table \"${options.tableName}\".`\n );\n }\n for (const condition of source.range) {\n whereClauses.push(this.renderCondition(\"t\", condition, params));\n }\n const primaryField = index.fields[0];\n if (primaryField) {\n orderClauses.push(\n `${fieldExpression(\"t\", primaryField)} ${options.orderDirection.toUpperCase()}`\n );\n }\n }\n\n if (source.type === \"search\") {\n const searchIndex = table.searchIndexes.find(\n (candidate) => candidate.name === source.name\n );\n if (!searchIndex) {\n throw new Error(\n `Unknown search index \"${source.name}\" on table \"${options.tableName}\".`\n );\n }\n if (searchIndex.searchField !== source.query.searchField) {\n throw new Error(\n `Search index \"${searchIndex.name}\" expects field \"${searchIndex.searchField}\".`\n );\n }\n if (this.deps.schema.isSearchIndexDisabled(options.tableName, searchIndex.name)) {\n whereClauses.push(\n `${fieldExpression(\"t\", searchIndex.searchField)} LIKE ?`\n );\n params.push(`%${source.query.searchText}%`);\n } else {\n const searchTableName = resolveSearchIndexTableName(\n options.tableName,\n searchIndex.name\n );\n joinClause = `JOIN ${quoteIdentifier(searchTableName)} s ON s._id = t._id`;\n whereClauses.push(`s.search_value MATCH ?`);\n params.push(source.query.searchText);\n }\n for (const condition of source.query.filters) {\n whereClauses.push(this.renderCondition(\"t\", condition, params));\n }\n }\n\n if (options.filterExpression) {\n whereClauses.push(\n this.renderExpression(\"t\", options.filterExpression, params)\n );\n }\n\n if (orderClauses.length === 0) {\n orderClauses.push(\n `t._creationTime ${options.orderDirection.toUpperCase()}`\n );\n }\n orderClauses.push(`t._id ${options.orderDirection.toUpperCase()}`);\n\n const sql = [\n `SELECT t._id, t._creationTime, t._json FROM ${quoteIdentifier(options.tableName)} t`,\n joinClause,\n whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\",\n `ORDER BY ${orderClauses.join(\", \")}`,\n options.limit !== undefined ? `LIMIT ${options.limit}` : \"\",\n options.offset !== undefined ? `OFFSET ${options.offset}` : \"\"\n ]\n .filter(Boolean)\n .join(\" \");\n\n const rows = await this.deps.driver.all<DatabaseRow>(sql, params);\n return rows.map((row) =>\n this.deps.schema.deserializeDocument<TDocument>(options.tableName, row)\n );\n }\n\n private async invokeFunction<TResult>(\n definition: RegisteredSyncoreFunction,\n rawArgs: JsonObject,\n state: RuntimeExecutionState\n ): Promise<TResult> {\n const args = definition.argsValidator.parse(rawArgs) as JsonObject;\n const ctx = this.createContext(definition.kind, {\n ...state,\n componentMetadata:\n definition.__syncoreComponent ?? state.componentMetadata\n });\n const result = (await definition.handler(ctx, args)) as TResult;\n if (definition.returnsValidator) {\n return definition.returnsValidator.parse(result) as TResult;\n }\n return result;\n }\n\n private createContext(\n kind: SyncoreFunctionKind,\n state: RuntimeExecutionState\n ): QueryCtx<TSchema> | MutationCtx<TSchema> | ActionCtx<TSchema> {\n const db =\n kind === \"mutation\"\n ? this.createDatabaseWriter(state)\n : this.createDatabaseReader(state);\n const storage = this.deps.storage.createStorageApi(state);\n const scheduler = this.createSchedulerApi(state.componentMetadata);\n const callerMetadata = state.componentMetadata;\n\n return {\n db,\n storage,\n capabilities: this.deps.capabilities,\n capabilityDescriptors: this.deps.capabilityDescriptors,\n ...(callerMetadata\n ? {\n component: {\n path: callerMetadata.componentPath,\n name: callerMetadata.componentName,\n version: callerMetadata.version,\n capabilities: callerMetadata.grantedCapabilities\n }\n }\n : {}),\n scheduler,\n runQuery: <TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) =>\n this.runQuery(\n this.resolveReferenceForCaller(reference, \"query\", callerMetadata),\n normalizeOptionalArgs(args) as JsonObject,\n state.executionId ? { parentExecutionId: state.executionId } : {}\n ),\n runMutation: <TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) => {\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n \"mutation\",\n callerMetadata\n );\n const normalizedArgs = normalizeOptionalArgs(args);\n if (kind === \"mutation\") {\n return this.deps.driver.withSavepoint(\n `sp_${generateId().replace(/-/g, \"_\")}`,\n () =>\n this.invokeFunction<TResult>(\n this.resolveFunction(\n resolvedReference,\n \"mutation\",\n callerMetadata\n ),\n normalizedArgs as JsonObject,\n {\n ...(state.executionId ? { executionId: state.executionId } : {}),\n mutationDepth: state.mutationDepth + 1,\n changedTables: state.changedTables,\n documentChanges: state.documentChanges,\n storageChanges: state.storageChanges,\n componentMetadata: callerMetadata\n }\n )\n );\n }\n return this.runMutation(\n resolvedReference,\n normalizedArgs as JsonObject,\n state.executionId ? { parentExecutionId: state.executionId } : {}\n );\n },\n runAction: <TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ) =>\n this.runAction(\n this.resolveReferenceForCaller(reference, \"action\", callerMetadata),\n normalizeOptionalArgs(args) as JsonObject,\n state.executionId ? { parentExecutionId: state.executionId } : {}\n )\n } as QueryCtx<TSchema> | MutationCtx<TSchema> | ActionCtx<TSchema>;\n }\n\n private createDatabaseReader(\n state: RuntimeExecutionState\n ): SyncoreDatabaseReader<TSchema> {\n return {\n get: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n state.dependencyCollector?.add(`table:${scopedTableName}`);\n state.dependencyCollector?.add(`row:${scopedTableName}:${id}`);\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n return row\n ? this.deps.schema.deserializeDocument<\n DocumentForTable<TSchema, TTableName>\n >(scopedTableName, row)\n : null;\n },\n query: <TTableName extends TableNames<TSchema>>(tableName: TTableName) =>\n new RuntimeQueryBuilder<\n TSchema[\"tables\"][TTableName],\n DocumentForTable<TSchema, TTableName>\n >(\n (options) =>\n this.executeQueryBuilder<DocumentForTable<TSchema, TTableName>>(\n {\n ...options,\n tableName: this.resolveTableName(\n tableName,\n state.componentMetadata\n )\n }\n ),\n this.resolveTableName(tableName, state.componentMetadata),\n state.dependencyCollector\n ),\n raw: <TValue>(sql: string, params?: unknown[]) =>\n this.deps.driver.all<TValue>(sql, params)\n };\n }\n\n private createDatabaseWriter(\n state: RuntimeExecutionState\n ): SyncoreDatabaseWriter<TSchema> {\n const reader = this.createDatabaseReader(state);\n\n return {\n ...reader,\n insert: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n value: InsertValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n value as JsonObject\n );\n const id = generateId();\n const creationTime = Date.now();\n const json = stableStringify(validated);\n await this.deps.driver.run(\n `INSERT INTO ${quoteIdentifier(scopedTableName)} (_id, _creationTime, _json) VALUES (?, ?, ?)`,\n [id, creationTime, json]\n );\n await this.deps.schema.syncSearchIndexes(scopedTableName, {\n _id: id,\n _creationTime: creationTime,\n _json: json\n });\n state.changedTables.add(scopedTableName);\n state.documentChanges.push({\n table: scopedTableName,\n id,\n operation: \"insert\",\n fields: Object.keys(validated),\n afterPreview: createDevtoolsPreview({\n _id: id,\n _creationTime: creationTime,\n ...validated\n })\n });\n return id;\n },\n patch: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string,\n value: PatchValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const current = await reader.get(tableName, id);\n if (!current) {\n throw new Error(`Document \"${id}\" does not exist in \"${scopedTableName}\".`);\n }\n const merged: JsonObject = { ...omitSystemFields(current), ...value };\n for (const key of Object.keys(merged)) {\n if (merged[key] === undefined) {\n delete merged[key];\n }\n }\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n merged\n );\n await this.deps.driver.run(\n `UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`,\n [stableStringify(validated), id]\n );\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n if (row) {\n await this.deps.schema.syncSearchIndexes(scopedTableName, row);\n }\n state.changedTables.add(scopedTableName);\n state.documentChanges.push({\n table: scopedTableName,\n id,\n operation: \"patch\",\n fields: Object.keys(value as Record<string, unknown>),\n beforePreview: createDevtoolsPreview(current),\n afterPreview: createDevtoolsPreview(\n row\n ? this.deps.schema.deserializeDocument(scopedTableName, row)\n : validated\n )\n });\n },\n replace: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string,\n value: InsertValueForTable<TSchema, TTableName>\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const validated = this.deps.schema.validateDocument(\n scopedTableName,\n value as JsonObject\n );\n const current = await reader.get(tableName, id);\n await this.deps.driver.run(\n `UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`,\n [stableStringify(validated), id]\n );\n const row = await this.deps.driver.get<DatabaseRow>(\n `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n if (!row) {\n throw new Error(`Document \"${id}\" does not exist in \"${scopedTableName}\".`);\n }\n await this.deps.schema.syncSearchIndexes(scopedTableName, row);\n state.changedTables.add(scopedTableName);\n state.documentChanges.push({\n table: scopedTableName,\n id,\n operation: \"replace\",\n fields: Object.keys(validated),\n ...(current ? { beforePreview: createDevtoolsPreview(current) } : {}),\n afterPreview: createDevtoolsPreview(\n this.deps.schema.deserializeDocument(scopedTableName, row)\n )\n });\n },\n delete: async <TTableName extends TableNames<TSchema>>(\n tableName: TTableName,\n id: string\n ) => {\n const scopedTableName = this.resolveTableName(\n tableName,\n state.componentMetadata\n );\n const current = await reader.get(tableName, id);\n await this.deps.driver.run(\n `DELETE FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`,\n [id]\n );\n await this.deps.schema.removeSearchIndexes(scopedTableName, id);\n state.changedTables.add(scopedTableName);\n state.documentChanges.push({\n table: scopedTableName,\n id,\n operation: \"delete\",\n ...(current ? { beforePreview: createDevtoolsPreview(current) } : {})\n });\n }\n };\n }\n\n private createSchedulerApi(\n componentMetadata?: SyncoreComponentFunctionMetadata\n ): SchedulerApi {\n return {\n runAfter: async (delayMs, reference, ...args) => {\n if (\n componentMetadata &&\n !componentMetadata.grantedCapabilities.includes(\"scheduler\")\n ) {\n throw new Error(\n `Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`\n );\n }\n const schedulerArgs = splitSchedulerArgs(args);\n const functionArgs = schedulerArgs[0];\n const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n reference.kind,\n componentMetadata\n );\n return this.deps.scheduler.scheduleJob(\n Date.now() + delayMs,\n resolvedReference,\n functionArgs,\n misfirePolicy,\n componentMetadata\n ? `component:${componentMetadata.componentPath}:`\n : undefined\n );\n },\n runAt: async (timestamp, reference, ...args) => {\n if (\n componentMetadata &&\n !componentMetadata.grantedCapabilities.includes(\"scheduler\")\n ) {\n throw new Error(\n `Component ${JSON.stringify(componentMetadata.componentPath)} does not have scheduler capability.`\n );\n }\n const schedulerArgs = splitSchedulerArgs(args);\n const functionArgs = schedulerArgs[0];\n const misfirePolicy = schedulerArgs[1] ?? DEFAULT_MISFIRE_POLICY;\n const value =\n timestamp instanceof Date ? timestamp.getTime() : timestamp;\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n reference.kind,\n componentMetadata\n );\n return this.deps.scheduler.scheduleJob(\n value,\n resolvedReference,\n functionArgs,\n misfirePolicy,\n componentMetadata\n ? `component:${componentMetadata.componentPath}:`\n : undefined\n );\n },\n cancel: async (id) => {\n await this.deps.scheduler.cancelScheduledJob(id);\n }\n };\n }\n\n private resolveFunction<TKind extends SyncoreFunctionKind>(\n reference: FunctionReference<TKind, unknown, unknown>,\n expectedKind: TKind,\n callerMetadata?: SyncoreComponentFunctionMetadata\n ): RegisteredSyncoreFunction & {\n kind: TKind;\n } {\n const resolvedReference = this.resolveReferenceForCaller(\n reference,\n expectedKind,\n callerMetadata\n );\n const definition = this.deps.functions[resolvedReference.name];\n if (!definition) {\n throw new Error(`Unknown function \"${resolvedReference.name}\".`);\n }\n if (definition.kind !== expectedKind) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is a ${definition.kind}, expected ${expectedKind}.`\n );\n }\n const metadata = definition.__syncoreComponent;\n if (metadata?.visibility === \"internal\") {\n if (!callerMetadata) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is internal to component \"${metadata.componentPath}\".`\n );\n }\n if (callerMetadata.componentPath !== metadata.componentPath) {\n throw new Error(\n `Function \"${resolvedReference.name}\" is internal to component \"${metadata.componentPath}\" and cannot be called from \"${callerMetadata.componentPath}\".`\n );\n }\n }\n return definition as RegisteredSyncoreFunction & {\n kind: TKind;\n };\n }\n\n private renderExpression(\n tableAlias: string,\n expression: QueryExpression,\n params: unknown[]\n ): string {\n if (expression.type === \"condition\") {\n return this.renderCondition(tableAlias, expression.condition, params);\n }\n const separator = expression.type === \"and\" ? \" AND \" : \" OR \";\n return `(${expression.expressions\n .map((child) => this.renderExpression(tableAlias, child, params))\n .join(separator)})`;\n }\n\n private renderCondition(\n tableAlias: string,\n condition: {\n field: string;\n operator: \"=\" | \">\" | \">=\" | \"<\" | \"<=\";\n value: unknown;\n },\n params: unknown[]\n ): string {\n params.push(condition.value);\n return `${fieldExpression(tableAlias, condition.field)} ${condition.operator} ?`;\n }\n\n private resolveReferenceForCaller<TKind extends SyncoreFunctionKind>(\n reference: FunctionReference<TKind, unknown, unknown>,\n expectedKind: TKind,\n callerMetadata?: SyncoreComponentFunctionMetadata\n ): FunctionReference<TKind, unknown, unknown> {\n if (!callerMetadata) {\n return reference;\n }\n\n if (reference.name.startsWith(\"components/\")) {\n return reference;\n }\n\n const bindingMatch = /^binding:([^/]+)\\/(.+)$/.exec(reference.name);\n if (bindingMatch) {\n const bindingName = bindingMatch[1]!;\n const localName = bindingMatch[2]!;\n const targetComponentPath = callerMetadata.bindings[bindingName];\n if (!targetComponentPath) {\n throw new Error(\n `Component ${JSON.stringify(callerMetadata.componentPath)} does not define binding ${JSON.stringify(bindingName)}.`\n );\n }\n const canonicalName = toCanonicalComponentFunctionName(\n targetComponentPath,\n \"public\",\n localName\n );\n return {\n kind: expectedKind,\n name: canonicalName\n };\n }\n\n const internalName = toCanonicalComponentFunctionName(\n callerMetadata.componentPath,\n \"internal\",\n reference.name\n );\n if (this.deps.functions[internalName]) {\n return {\n kind: expectedKind,\n name: internalName\n };\n }\n\n const publicName = toCanonicalComponentFunctionName(\n callerMetadata.componentPath,\n \"public\",\n reference.name\n );\n if (this.deps.functions[publicName]) {\n return {\n kind: expectedKind,\n name: publicName\n };\n }\n\n return reference;\n }\n\n private resolveTableName<TTableName extends string>(\n tableName: TTableName,\n componentMetadata?: SyncoreComponentFunctionMetadata\n ): TTableName {\n if (!componentMetadata) {\n return tableName;\n }\n\n const scopedTableName = componentMetadata.localTables[tableName];\n if (!scopedTableName) {\n throw new Error(\n `Table ${JSON.stringify(tableName)} is not available inside component ${JSON.stringify(componentMetadata.componentPath)}.`\n );\n }\n\n return scopedTableName as TTableName;\n }\n}\n\nfunction collectChangedScopes(\n changedTables: Set<string>,\n storageChanges: Array<{\n storageId: string;\n reason: \"storage-put\" | \"storage-delete\";\n }>\n): Set<ImpactScope> {\n return new Set<ImpactScope>([\n ...[...changedTables].map((tableName) => `table:${tableName}` as ImpactScope),\n ...storageChanges.map(\n (change) => `storage:${change.storageId}` as ImpactScope\n )\n ]);\n}\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import { generateId } from "../../id.mjs";
1
2
  import { parseCanonicalComponentFunctionName } from "./shared.mjs";
2
3
  //#region src/runtime/internal/engines/reactivityEngine.ts
3
4
  var ReactivityEngine = class {
5
+ deps;
4
6
  activeQueries = /* @__PURE__ */ new Map();
5
7
  detachExternalChangeListener;
6
8
  pendingExternalChangePromise;
@@ -23,6 +25,8 @@ var ReactivityEngine = class {
23
25
  return {
24
26
  id: query.id,
25
27
  functionName: query.functionName,
28
+ args: query.args,
29
+ consumers: query.consumers,
26
30
  ...componentFunction ? {
27
31
  owner: "component",
28
32
  componentPath: componentFunction.componentPath
@@ -48,6 +52,7 @@ var ReactivityEngine = class {
48
52
  lastRunAt: 0
49
53
  };
50
54
  this.activeQueries.set(key, record);
55
+ this.notifyActiveQueriesChanged();
51
56
  this.rerunActiveQuery(record);
52
57
  }
53
58
  const activeRecord = record;
@@ -72,7 +77,10 @@ var ReactivityEngine = class {
72
77
  for (const callback of ownedListeners) activeRecord.listeners.delete(callback);
73
78
  ownedListeners.clear();
74
79
  activeRecord.consumers = Math.max(0, activeRecord.consumers - 1);
75
- if (activeRecord.consumers === 0) this.activeQueries.delete(key);
80
+ if (activeRecord.consumers === 0) {
81
+ this.activeQueries.delete(key);
82
+ this.notifyActiveQueriesChanged();
83
+ }
76
84
  }
77
85
  };
78
86
  }
@@ -80,21 +88,34 @@ var ReactivityEngine = class {
80
88
  const impactedScopes = new Set([...changedTables].map((tableName) => `table:${tableName}`));
81
89
  await this.refreshQueriesForScopes(impactedScopes, `Mutation ${mutationId} changed ${[...changedTables].join(", ")}`);
82
90
  }
83
- async refreshQueriesForScopes(scopes, reason) {
91
+ async refreshQueriesForScopes(scopes, reason, cause) {
84
92
  const scopeSet = new Set(scopes);
85
- if (scopeSet.size === 0) return;
86
- for (const query of this.activeQueries.values()) {
87
- if (![...scopeSet].some((scope) => query.dependencyKeys.has(scope))) continue;
93
+ if (scopeSet.size === 0) return [];
94
+ const invalidatedQueryIds = [];
95
+ for (const { query, matchedScopes } of this.getInvalidatedQueriesForScopes(scopeSet)) {
96
+ const rerunExecutionId = generateReactivityExecutionId();
88
97
  this.deps.devtools.emit({
89
98
  type: "query.invalidated",
90
99
  runtimeId: this.deps.runtimeId,
91
100
  queryId: query.id,
92
101
  ...parseCanonicalComponentFunctionName(query.functionName) ? { componentPath: parseCanonicalComponentFunctionName(query.functionName).componentPath } : {},
93
102
  reason,
103
+ ...cause?.executionId ? { causedByExecutionId: cause.executionId } : {},
104
+ changedScopes: [...scopeSet],
105
+ matchedScopes,
106
+ rerunExecutionId,
94
107
  timestamp: Date.now()
95
108
  });
96
- await this.rerunActiveQuery(query);
109
+ invalidatedQueryIds.push(query.id);
110
+ await this.rerunActiveQuery(query, {
111
+ executionId: rerunExecutionId,
112
+ ...cause?.executionId ? { parentExecutionId: cause.executionId } : {}
113
+ });
97
114
  }
115
+ return invalidatedQueryIds;
116
+ }
117
+ getInvalidatedQueryIdsForScopes(scopes) {
118
+ return this.getInvalidatedQueriesForScopes(new Set(scopes)).map(({ query }) => query.id);
98
119
  }
99
120
  async publishExternalChange(event) {
100
121
  const changedScopes = resolveChangedScopes(event);
@@ -117,20 +138,31 @@ var ReactivityEngine = class {
117
138
  async publishDatabaseReconcile() {
118
139
  throw new Error("Syncore database reconcile without precise impact scopes is unsupported.");
119
140
  }
120
- async rerunActiveQuery(record) {
141
+ async rerunActiveQuery(record, meta) {
121
142
  record.dependencyKeys.clear();
122
143
  try {
123
144
  record.lastResult = await this.deps.runQuery({
124
145
  kind: "query",
125
146
  name: record.functionName
126
- }, record.args);
147
+ }, record.args, meta);
127
148
  record.lastError = void 0;
128
149
  record.lastRunAt = Date.now();
129
150
  record.dependencyKeys = await this.deps.collectQueryDependencies(record.functionName, record.args);
130
151
  } catch (error) {
131
152
  record.lastError = error;
153
+ record.lastRunAt = Date.now();
132
154
  }
133
155
  for (const listener of record.listeners) listener();
156
+ this.notifyActiveQueriesChanged();
157
+ }
158
+ notifyActiveQueriesChanged() {
159
+ this.deps.devtools.notifyScopes(["runtime.summary", "runtime.activeQueries"]);
160
+ }
161
+ getInvalidatedQueriesForScopes(scopeSet) {
162
+ return [...this.activeQueries.values()].map((query) => ({
163
+ query,
164
+ matchedScopes: [...scopeSet].filter((scope) => query.dependencyKeys.has(scope))
165
+ })).filter(({ matchedScopes }) => matchedScopes.length > 0);
134
166
  }
135
167
  async handleExternalChangeEvent(event) {
136
168
  if (event.sourceId === this.deps.externalChangeSourceId) return;
@@ -149,6 +181,7 @@ var ReactivityEngine = class {
149
181
  return this.pendingExternalChangePromise;
150
182
  }
151
183
  this.pendingExternalChangePromise = (async () => {
184
+ this.deps.devtools.notifyScopes(toDevtoolsScopes(changedScopes));
152
185
  await this.refreshQueriesForScopes(changedScopes, `External change touched ${[...changedScopes].join(", ")}`);
153
186
  })();
154
187
  try {
@@ -164,6 +197,9 @@ var ReactivityEngine = class {
164
197
  return `${name}:${stableStringify(args)}`;
165
198
  }
166
199
  };
200
+ function generateReactivityExecutionId() {
201
+ return generateId();
202
+ }
167
203
  function resolveChangedScopes(event) {
168
204
  if (Array.isArray(event.changedScopes) && event.changedScopes.length > 0) return new Set(event.changedScopes);
169
205
  const scopes = /* @__PURE__ */ new Set();
@@ -172,6 +208,18 @@ function resolveChangedScopes(event) {
172
208
  if (scopes.size === 0 && event.scope !== void 0) throw new Error(`Syncore external change scope "${event.scope}" did not provide precise impact scopes.`);
173
209
  return scopes;
174
210
  }
211
+ function toDevtoolsScopes(scopes) {
212
+ const resolved = /* @__PURE__ */ new Set();
213
+ for (const scope of scopes) {
214
+ if (scope.startsWith("row:")) {
215
+ const [, tableName] = scope.split(":");
216
+ if (tableName) resolved.add(`table:${tableName}`);
217
+ continue;
218
+ }
219
+ if (scope === "runtime.summary" || scope === "runtime.activeQueries" || scope === "schema.tables" || scope === "scheduler.jobs" || scope.startsWith("table:") || scope.startsWith("storage:")) resolved.add(scope);
220
+ }
221
+ return resolved.size > 0 ? [...resolved] : ["all"];
222
+ }
175
223
  function stableStringify(value) {
176
224
  return JSON.stringify(sortValue(value));
177
225
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reactivityEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/reactivityEngine.ts"],"sourcesContent":["import type {\n SyncoreActiveQueryInfo,\n SyncoreDevtoolsEvent\n} from \"@syncore/devtools-protocol\";\nimport type { FunctionReference } from \"../../functions.js\";\nimport type {\n ImpactScope,\n JsonObject,\n SyncoreExternalChangeApplier,\n SyncoreExternalChangeEvent,\n SyncoreExternalChangeSignal,\n SyncoreWatch\n} from \"../../runtime.js\";\nimport { DevtoolsEngine } from \"./devtoolsEngine.js\";\nimport type {\n ActiveQueryRecord,\n DependencyKey\n} from \"./shared.js\";\nimport { parseCanonicalComponentFunctionName } from \"./shared.js\";\n\ntype ReactivityEngineDeps = {\n runtimeId: string;\n externalChangeSourceId: string;\n externalChangeSignal?: SyncoreExternalChangeSignal;\n externalChangeApplier?: SyncoreExternalChangeApplier;\n devtools: DevtoolsEngine;\n runQuery: <TResult>(\n reference: FunctionReference<\"query\", unknown, TResult>,\n args: JsonObject\n ) => Promise<TResult>;\n collectQueryDependencies: (\n functionName: string,\n args: JsonObject\n ) => Promise<Set<DependencyKey>>;\n};\n\nexport class ReactivityEngine {\n private readonly activeQueries = new Map<string, ActiveQueryRecord>();\n private detachExternalChangeListener: (() => void) | undefined;\n private pendingExternalChangePromise: Promise<void> | undefined;\n private queuedExternalChange:\n | {\n changedScopes: Set<ImpactScope>;\n }\n | undefined;\n\n constructor(private readonly deps: ReactivityEngineDeps) {}\n\n start(): void {\n this.detachExternalChangeListener =\n this.deps.externalChangeSignal?.subscribe((event) => {\n void this.handleExternalChangeEvent(event);\n });\n }\n\n stop(): void {\n this.detachExternalChangeListener?.();\n this.detachExternalChangeListener = undefined;\n }\n\n getActiveQueryInfos(): SyncoreActiveQueryInfo[] {\n return [...this.activeQueries.values()].map((query) => {\n const componentFunction = parseCanonicalComponentFunctionName(\n query.functionName\n );\n return {\n id: query.id,\n functionName: query.functionName,\n ...(componentFunction\n ? {\n owner: \"component\" as const,\n componentPath: componentFunction.componentPath\n }\n : {\n owner: \"root\" as const\n }),\n dependencyKeys: [...query.dependencyKeys],\n lastRunAt: query.lastRunAt\n };\n });\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {}\n ): SyncoreWatch<TResult> {\n const key = this.createActiveQueryKey(reference.name, args);\n let record = this.activeQueries.get(key);\n\n if (!record) {\n record = {\n id: key,\n functionName: reference.name,\n args,\n listeners: new Set<() => void>(),\n consumers: 0,\n dependencyKeys: new Set<DependencyKey>(),\n lastResult: undefined,\n lastError: undefined,\n lastRunAt: 0\n };\n this.activeQueries.set(key, record);\n void this.rerunActiveQuery(record);\n }\n\n const activeRecord = record;\n activeRecord.consumers += 1;\n let disposed = false;\n const ownedListeners = new Set<() => void>();\n\n return {\n onUpdate: (callback) => {\n activeRecord.listeners.add(callback);\n ownedListeners.add(callback);\n queueMicrotask(callback);\n return () => {\n activeRecord.listeners.delete(callback);\n ownedListeners.delete(callback);\n };\n },\n localQueryResult: () => activeRecord.lastResult as TResult | undefined,\n localQueryError: () => activeRecord.lastError,\n dispose: () => {\n if (disposed) {\n return;\n }\n disposed = true;\n for (const callback of ownedListeners) {\n activeRecord.listeners.delete(callback);\n }\n ownedListeners.clear();\n activeRecord.consumers = Math.max(0, activeRecord.consumers - 1);\n if (activeRecord.consumers === 0) {\n this.activeQueries.delete(key);\n }\n }\n };\n }\n\n async refreshInvalidatedQueries(\n changedTables: Set<string>,\n mutationId: string\n ): Promise<void> {\n const impactedScopes = new Set(\n [...changedTables].map((tableName) => `table:${tableName}` as ImpactScope)\n );\n await this.refreshQueriesForScopes(\n impactedScopes,\n `Mutation ${mutationId} changed ${[...changedTables].join(\", \")}`\n );\n }\n\n async refreshQueriesForScopes(\n scopes: Iterable<ImpactScope>,\n reason: string\n ): Promise<void> {\n const scopeSet = new Set(scopes);\n if (scopeSet.size === 0) {\n return;\n }\n for (const query of this.activeQueries.values()) {\n const needsRefresh = [...scopeSet].some((scope) =>\n query.dependencyKeys.has(scope)\n );\n if (!needsRefresh) {\n continue;\n }\n this.deps.devtools.emit({\n type: \"query.invalidated\",\n runtimeId: this.deps.runtimeId,\n queryId: query.id,\n ...(parseCanonicalComponentFunctionName(query.functionName)\n ? {\n componentPath: parseCanonicalComponentFunctionName(query.functionName)!\n .componentPath\n }\n : {}),\n reason,\n timestamp: Date.now()\n });\n await this.rerunActiveQuery(query);\n }\n }\n\n async publishExternalChange(\n event: Omit<SyncoreExternalChangeEvent, \"sourceId\" | \"timestamp\">\n ): Promise<void> {\n const changedScopes = resolveChangedScopes(event);\n if (changedScopes.size === 0) {\n throw new Error(\n `Syncore cannot publish external change \"${event.reason}\" without precise impact scopes.`\n );\n }\n await this.deps.externalChangeSignal?.publish({\n ...event,\n changedScopes: [...changedScopes],\n sourceId: this.deps.externalChangeSourceId,\n timestamp: Date.now()\n });\n }\n\n async publishStorageChanges(\n storageChanges: Array<{\n storageId: string;\n reason: \"storage-put\" | \"storage-delete\";\n }>\n ): Promise<void> {\n for (const change of storageChanges) {\n await this.publishExternalChange({\n scope: \"storage\",\n reason: change.reason,\n changedScopes: [`storage:${change.storageId}`],\n storageIds: [change.storageId]\n });\n }\n }\n\n async publishDatabaseReconcile(): Promise<void> {\n throw new Error(\n \"Syncore database reconcile without precise impact scopes is unsupported.\"\n );\n }\n\n private async rerunActiveQuery(record: ActiveQueryRecord): Promise<void> {\n record.dependencyKeys.clear();\n try {\n const result = await this.deps.runQuery(\n { kind: \"query\", name: record.functionName },\n record.args\n );\n record.lastResult = result;\n record.lastError = undefined;\n record.lastRunAt = Date.now();\n record.dependencyKeys = await this.deps.collectQueryDependencies(\n record.functionName,\n record.args\n );\n } catch (error) {\n record.lastError = error as Error;\n }\n for (const listener of record.listeners) {\n listener();\n }\n }\n\n private async handleExternalChangeEvent(\n event: SyncoreExternalChangeEvent\n ): Promise<void> {\n if (event.sourceId === this.deps.externalChangeSourceId) {\n return;\n }\n const result = this.deps.externalChangeApplier\n ? await this.deps.externalChangeApplier.applyExternalChange(event)\n : {\n databaseChanged: event.scope === \"database\" || event.scope === \"all\",\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes: [...resolveChangedScopes(event)]\n };\n await this.processExternalChangeResult(result);\n }\n\n private async processExternalChangeResult(result: {\n changedScopes: ImpactScope[];\n }): Promise<void> {\n const changedScopes = new Set(result.changedScopes);\n if (changedScopes.size === 0) {\n return;\n }\n if (this.pendingExternalChangePromise) {\n this.queuedExternalChange = {\n changedScopes: new Set([\n ...(this.queuedExternalChange?.changedScopes ?? []),\n ...changedScopes\n ])\n };\n return this.pendingExternalChangePromise;\n }\n\n this.pendingExternalChangePromise = (async () => {\n await this.refreshQueriesForScopes(\n changedScopes,\n `External change touched ${[...changedScopes].join(\", \")}`\n );\n })();\n\n try {\n await this.pendingExternalChangePromise;\n } finally {\n this.pendingExternalChangePromise = undefined;\n const queued = this.queuedExternalChange;\n this.queuedExternalChange = undefined;\n if (queued) {\n await this.processExternalChangeResult({\n changedScopes: [...queued.changedScopes]\n });\n }\n }\n }\n\n private createActiveQueryKey(name: string, args: JsonObject): string {\n return `${name}:${stableStringify(args)}`;\n }\n}\n\nfunction resolveChangedScopes(\n event: Pick<\n SyncoreExternalChangeEvent,\n \"scope\" | \"changedScopes\" | \"changedTables\" | \"storageIds\"\n >\n): Set<ImpactScope> {\n if (Array.isArray(event.changedScopes) && event.changedScopes.length > 0) {\n return new Set(event.changedScopes);\n }\n\n const scopes = new Set<ImpactScope>();\n for (const tableName of event.changedTables ?? []) {\n scopes.add(`table:${tableName}`);\n }\n for (const storageId of event.storageIds ?? []) {\n scopes.add(`storage:${storageId}`);\n }\n\n if (scopes.size === 0 && event.scope !== undefined) {\n throw new Error(\n `Syncore external change scope \"${event.scope}\" did not provide precise impact scopes.`\n );\n }\n\n return scopes;\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortValue(value));\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, sortValue(nested)])\n );\n }\n return value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"reactivityEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/reactivityEngine.ts"],"sourcesContent":["import type {\n SyncoreActiveQueryInfo,\n SyncoreDevtoolsEvent\n} from \"@syncore/devtools-protocol\";\nimport type { FunctionReference } from \"../../functions.js\";\nimport type {\n DevtoolsLiveQueryScope,\n ImpactScope,\n JsonObject,\n SyncoreExternalChangeApplier,\n SyncoreExternalChangeEvent,\n SyncoreExternalChangeSignal,\n SyncoreWatch\n} from \"../../runtime.js\";\nimport { DevtoolsEngine } from \"./devtoolsEngine.js\";\nimport { generateId } from \"../../id.js\";\nimport type {\n ActiveQueryRecord,\n DependencyKey\n} from \"./shared.js\";\nimport { parseCanonicalComponentFunctionName } from \"./shared.js\";\n\ntype ReactivityEngineDeps = {\n runtimeId: string;\n externalChangeSourceId: string;\n externalChangeSignal?: SyncoreExternalChangeSignal;\n externalChangeApplier?: SyncoreExternalChangeApplier;\n devtools: DevtoolsEngine;\n runQuery: <TResult>(\n reference: FunctionReference<\"query\", unknown, TResult>,\n args: JsonObject,\n meta?: { executionId?: string; parentExecutionId?: string }\n ) => Promise<TResult>;\n collectQueryDependencies: (\n functionName: string,\n args: JsonObject\n ) => Promise<Set<DependencyKey>>;\n};\n\nexport class ReactivityEngine {\n private readonly activeQueries = new Map<string, ActiveQueryRecord>();\n private detachExternalChangeListener: (() => void) | undefined;\n private pendingExternalChangePromise: Promise<void> | undefined;\n private queuedExternalChange:\n | {\n changedScopes: Set<ImpactScope>;\n }\n | undefined;\n\n constructor(private readonly deps: ReactivityEngineDeps) {}\n\n start(): void {\n this.detachExternalChangeListener =\n this.deps.externalChangeSignal?.subscribe((event) => {\n void this.handleExternalChangeEvent(event);\n });\n }\n\n stop(): void {\n this.detachExternalChangeListener?.();\n this.detachExternalChangeListener = undefined;\n }\n\n getActiveQueryInfos(): SyncoreActiveQueryInfo[] {\n return [...this.activeQueries.values()].map((query) => {\n const componentFunction = parseCanonicalComponentFunctionName(\n query.functionName\n );\n return {\n id: query.id,\n functionName: query.functionName,\n args: query.args,\n consumers: query.consumers,\n ...(componentFunction\n ? {\n owner: \"component\" as const,\n componentPath: componentFunction.componentPath\n }\n : {\n owner: \"root\" as const\n }),\n dependencyKeys: [...query.dependencyKeys],\n lastRunAt: query.lastRunAt\n };\n });\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject = {}\n ): SyncoreWatch<TResult> {\n const key = this.createActiveQueryKey(reference.name, args);\n let record = this.activeQueries.get(key);\n\n if (!record) {\n record = {\n id: key,\n functionName: reference.name,\n args,\n listeners: new Set<() => void>(),\n consumers: 0,\n dependencyKeys: new Set<DependencyKey>(),\n lastResult: undefined,\n lastError: undefined,\n lastRunAt: 0\n };\n this.activeQueries.set(key, record);\n this.notifyActiveQueriesChanged();\n void this.rerunActiveQuery(record);\n }\n\n const activeRecord = record;\n activeRecord.consumers += 1;\n let disposed = false;\n const ownedListeners = new Set<() => void>();\n\n return {\n onUpdate: (callback) => {\n activeRecord.listeners.add(callback);\n ownedListeners.add(callback);\n queueMicrotask(callback);\n return () => {\n activeRecord.listeners.delete(callback);\n ownedListeners.delete(callback);\n };\n },\n localQueryResult: () => activeRecord.lastResult as TResult | undefined,\n localQueryError: () => activeRecord.lastError,\n dispose: () => {\n if (disposed) {\n return;\n }\n disposed = true;\n for (const callback of ownedListeners) {\n activeRecord.listeners.delete(callback);\n }\n ownedListeners.clear();\n activeRecord.consumers = Math.max(0, activeRecord.consumers - 1);\n if (activeRecord.consumers === 0) {\n this.activeQueries.delete(key);\n this.notifyActiveQueriesChanged();\n }\n }\n };\n }\n\n async refreshInvalidatedQueries(\n changedTables: Set<string>,\n mutationId: string\n ): Promise<void> {\n const impactedScopes = new Set(\n [...changedTables].map((tableName) => `table:${tableName}` as ImpactScope)\n );\n await this.refreshQueriesForScopes(\n impactedScopes,\n `Mutation ${mutationId} changed ${[...changedTables].join(\", \")}`\n );\n }\n\n async refreshQueriesForScopes(\n scopes: Iterable<ImpactScope>,\n reason: string,\n cause?: { executionId?: string }\n ): Promise<string[]> {\n const scopeSet = new Set(scopes);\n if (scopeSet.size === 0) {\n return [];\n }\n const invalidatedQueryIds: string[] = [];\n for (const { query, matchedScopes } of this.getInvalidatedQueriesForScopes(\n scopeSet\n )) {\n const rerunExecutionId = generateReactivityExecutionId();\n this.deps.devtools.emit({\n type: \"query.invalidated\",\n runtimeId: this.deps.runtimeId,\n queryId: query.id,\n ...(parseCanonicalComponentFunctionName(query.functionName)\n ? {\n componentPath: parseCanonicalComponentFunctionName(query.functionName)!\n .componentPath\n }\n : {}),\n reason,\n ...(cause?.executionId ? { causedByExecutionId: cause.executionId } : {}),\n changedScopes: [...scopeSet],\n matchedScopes,\n rerunExecutionId,\n timestamp: Date.now()\n });\n invalidatedQueryIds.push(query.id);\n await this.rerunActiveQuery(query, {\n executionId: rerunExecutionId,\n ...(cause?.executionId ? { parentExecutionId: cause.executionId } : {})\n });\n }\n return invalidatedQueryIds;\n }\n\n getInvalidatedQueryIdsForScopes(scopes: Iterable<ImpactScope>): string[] {\n return this.getInvalidatedQueriesForScopes(new Set(scopes)).map(\n ({ query }) => query.id\n );\n }\n\n async publishExternalChange(\n event: Omit<SyncoreExternalChangeEvent, \"sourceId\" | \"timestamp\">\n ): Promise<void> {\n const changedScopes = resolveChangedScopes(event);\n if (changedScopes.size === 0) {\n throw new Error(\n `Syncore cannot publish external change \"${event.reason}\" without precise impact scopes.`\n );\n }\n await this.deps.externalChangeSignal?.publish({\n ...event,\n changedScopes: [...changedScopes],\n sourceId: this.deps.externalChangeSourceId,\n timestamp: Date.now()\n });\n }\n\n async publishStorageChanges(\n storageChanges: Array<{\n storageId: string;\n reason: \"storage-put\" | \"storage-delete\";\n }>\n ): Promise<void> {\n for (const change of storageChanges) {\n await this.publishExternalChange({\n scope: \"storage\",\n reason: change.reason,\n changedScopes: [`storage:${change.storageId}`],\n storageIds: [change.storageId]\n });\n }\n }\n\n async publishDatabaseReconcile(): Promise<void> {\n throw new Error(\n \"Syncore database reconcile without precise impact scopes is unsupported.\"\n );\n }\n\n private async rerunActiveQuery(\n record: ActiveQueryRecord,\n meta?: { executionId?: string; parentExecutionId?: string }\n ): Promise<void> {\n record.dependencyKeys.clear();\n try {\n const result = await this.deps.runQuery(\n { kind: \"query\", name: record.functionName },\n record.args,\n meta\n );\n record.lastResult = result;\n record.lastError = undefined;\n record.lastRunAt = Date.now();\n record.dependencyKeys = await this.deps.collectQueryDependencies(\n record.functionName,\n record.args\n );\n } catch (error) {\n record.lastError = error as Error;\n record.lastRunAt = Date.now();\n }\n for (const listener of record.listeners) {\n listener();\n }\n this.notifyActiveQueriesChanged();\n }\n\n private notifyActiveQueriesChanged(): void {\n this.deps.devtools.notifyScopes([\"runtime.summary\", \"runtime.activeQueries\"]);\n }\n\n private getInvalidatedQueriesForScopes(scopeSet: Set<ImpactScope>): Array<{\n query: ActiveQueryRecord;\n matchedScopes: ImpactScope[];\n }> {\n return [...this.activeQueries.values()]\n .map((query) => ({\n query,\n matchedScopes: [...scopeSet].filter((scope) =>\n query.dependencyKeys.has(scope)\n )\n }))\n .filter(({ matchedScopes }) => matchedScopes.length > 0);\n }\n\n private async handleExternalChangeEvent(\n event: SyncoreExternalChangeEvent\n ): Promise<void> {\n if (event.sourceId === this.deps.externalChangeSourceId) {\n return;\n }\n const result = this.deps.externalChangeApplier\n ? await this.deps.externalChangeApplier.applyExternalChange(event)\n : {\n databaseChanged: event.scope === \"database\" || event.scope === \"all\",\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes: [...resolveChangedScopes(event)]\n };\n await this.processExternalChangeResult(result);\n }\n\n private async processExternalChangeResult(result: {\n changedScopes: ImpactScope[];\n }): Promise<void> {\n const changedScopes = new Set(result.changedScopes);\n if (changedScopes.size === 0) {\n return;\n }\n if (this.pendingExternalChangePromise) {\n this.queuedExternalChange = {\n changedScopes: new Set([\n ...(this.queuedExternalChange?.changedScopes ?? []),\n ...changedScopes\n ])\n };\n return this.pendingExternalChangePromise;\n }\n\n this.pendingExternalChangePromise = (async () => {\n this.deps.devtools.notifyScopes(toDevtoolsScopes(changedScopes));\n await this.refreshQueriesForScopes(\n changedScopes,\n `External change touched ${[...changedScopes].join(\", \")}`\n );\n })();\n\n try {\n await this.pendingExternalChangePromise;\n } finally {\n this.pendingExternalChangePromise = undefined;\n const queued = this.queuedExternalChange;\n this.queuedExternalChange = undefined;\n if (queued) {\n await this.processExternalChangeResult({\n changedScopes: [...queued.changedScopes]\n });\n }\n }\n }\n\n private createActiveQueryKey(name: string, args: JsonObject): string {\n return `${name}:${stableStringify(args)}`;\n }\n}\n\nfunction generateReactivityExecutionId(): string {\n return generateId();\n}\n\nfunction resolveChangedScopes(\n event: Pick<\n SyncoreExternalChangeEvent,\n \"scope\" | \"changedScopes\" | \"changedTables\" | \"storageIds\"\n >\n): Set<ImpactScope> {\n if (Array.isArray(event.changedScopes) && event.changedScopes.length > 0) {\n return new Set(event.changedScopes);\n }\n\n const scopes = new Set<ImpactScope>();\n for (const tableName of event.changedTables ?? []) {\n scopes.add(`table:${tableName}`);\n }\n for (const storageId of event.storageIds ?? []) {\n scopes.add(`storage:${storageId}`);\n }\n\n if (scopes.size === 0 && event.scope !== undefined) {\n throw new Error(\n `Syncore external change scope \"${event.scope}\" did not provide precise impact scopes.`\n );\n }\n\n return scopes;\n}\n\nfunction toDevtoolsScopes(\n scopes: Iterable<ImpactScope>\n): DevtoolsLiveQueryScope[] {\n const resolved = new Set<DevtoolsLiveQueryScope>();\n for (const scope of scopes) {\n if (scope.startsWith(\"row:\")) {\n const [, tableName] = scope.split(\":\");\n if (tableName) {\n resolved.add(`table:${tableName}`);\n }\n continue;\n }\n if (\n scope === \"runtime.summary\" ||\n scope === \"runtime.activeQueries\" ||\n scope === \"schema.tables\" ||\n scope === \"scheduler.jobs\" ||\n scope.startsWith(\"table:\") ||\n scope.startsWith(\"storage:\")\n ) {\n resolved.add(scope as DevtoolsLiveQueryScope);\n }\n }\n return resolved.size > 0 ? [...resolved] : [\"all\"];\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortValue(value));\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, sortValue(nested)])\n );\n }\n return value;\n}\n"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { generateId } from "../../id.mjs";
2
- import { computeNextRun, parseMisfirePolicy, shouldRunMissedJob, stableStringify } from "./shared.mjs";
2
+ import { computeNextRun, createDevtoolsPreview, parseMisfirePolicy, shouldRunMissedJob, stableStringify } from "./shared.mjs";
3
3
  //#region src/runtime/internal/engines/schedulerEngine.ts
4
4
  var SchedulerEngine = class {
5
+ deps;
5
6
  timer;
6
7
  constructor(deps) {
7
8
  this.deps = deps;
@@ -66,20 +67,24 @@ var SchedulerEngine = class {
66
67
  return false;
67
68
  }
68
69
  async updateScheduledJob(options) {
69
- const existing = await this.deps.driver.get(`SELECT status, recurring_name FROM "_scheduled_functions" WHERE id = ?`, [options.id]);
70
- if (!existing || existing.status !== "scheduled" || !existing.recurring_name) return false;
70
+ const existing = await this.deps.driver.get(`SELECT status, run_at, recurring_name, schedule_json, misfire_policy, window_ms
71
+ FROM "_scheduled_functions" WHERE id = ?`, [options.id]);
72
+ if (!existing || existing.status !== "scheduled") return false;
73
+ const existingSchedule = existing.schedule_json ? JSON.parse(existing.schedule_json) : void 0;
74
+ const schedule = options.schedule ?? existingSchedule;
75
+ const misfirePolicy = options.misfirePolicy ?? parseMisfirePolicy(existing.misfire_policy ?? "catch_up", existing.window_ms);
71
76
  const now = Date.now();
72
- const runAt = options.runAt ?? computeNextRun(options.schedule, now);
77
+ const runAt = options.runAt ?? (schedule ? computeNextRun(schedule, now) : existing.run_at);
73
78
  if (((await this.deps.driver.run(`UPDATE "_scheduled_functions"
74
79
  SET args_json = ?, run_at = ?, updated_at = ?, schedule_json = ?, timezone = ?, misfire_policy = ?, window_ms = ?
75
- WHERE id = ? AND status = 'scheduled' AND recurring_name IS NOT NULL`, [
80
+ WHERE id = ? AND status = 'scheduled'`, [
76
81
  stableStringify(options.args),
77
82
  runAt,
78
83
  now,
79
- stableStringify(options.schedule),
80
- "timezone" in options.schedule ? options.schedule.timezone ?? null : null,
81
- options.misfirePolicy.type,
82
- options.misfirePolicy.type === "windowed" ? options.misfirePolicy.windowMs : null,
84
+ schedule ? stableStringify(schedule) : null,
85
+ schedule && "timezone" in schedule ? schedule.timezone ?? null : null,
86
+ misfirePolicy.type,
87
+ misfirePolicy.type === "windowed" ? misfirePolicy.windowMs : null,
83
88
  options.id
84
89
  ])).changes ?? 0) > 0) {
85
90
  this.notifySchedulerJobsChanged();
@@ -118,6 +123,7 @@ var SchedulerEngine = class {
118
123
  const now = Date.now();
119
124
  const dueJobs = await this.deps.driver.all(`SELECT * FROM "_scheduled_functions" WHERE status = 'scheduled' AND run_at <= ? ORDER BY run_at ASC`, [now]);
120
125
  const executedJobIds = [];
126
+ const jobExecutions = [];
121
127
  for (const job of dueJobs) {
122
128
  const misfirePolicy = parseMisfirePolicy(job.misfire_policy, job.window_ms);
123
129
  if (!shouldRunMissedJob(job.run_at, now, misfirePolicy)) {
@@ -125,17 +131,44 @@ var SchedulerEngine = class {
125
131
  continue;
126
132
  }
127
133
  try {
128
- if (job.function_kind === "mutation") await this.deps.runMutation({
134
+ const args = JSON.parse(job.args_json);
135
+ const executionId = generateId();
136
+ const startedAt = Date.now();
137
+ let result;
138
+ if (job.function_kind === "mutation") result = await this.deps.runMutation({
129
139
  kind: "mutation",
130
140
  name: job.function_name
131
- }, JSON.parse(job.args_json));
132
- else await this.deps.runAction({
141
+ }, args, {
142
+ executionId,
143
+ schedulerJobId: job.id,
144
+ schedulerRun: true
145
+ });
146
+ else result = await this.deps.runAction({
133
147
  kind: "action",
134
148
  name: job.function_name
135
- }, JSON.parse(job.args_json));
149
+ }, args, {
150
+ executionId,
151
+ schedulerJobId: job.id,
152
+ schedulerRun: true
153
+ });
136
154
  executedJobIds.push(job.id);
155
+ jobExecutions.push({
156
+ jobId: job.id,
157
+ executionId,
158
+ functionName: job.function_name,
159
+ functionType: job.function_kind === "mutation" ? "mutation" : "action",
160
+ argsPreview: createDevtoolsPreview(args),
161
+ resultPreview: createDevtoolsPreview(result),
162
+ durationMs: Date.now() - startedAt
163
+ });
137
164
  await this.advanceOrFinalizeJob(job, "completed", now);
138
165
  } catch (error) {
166
+ jobExecutions.push({
167
+ jobId: job.id,
168
+ functionName: job.function_name,
169
+ functionType: job.function_kind === "mutation" ? "mutation" : "action",
170
+ error: error instanceof Error ? error.message : String(error)
171
+ });
139
172
  await this.deps.driver.run(`UPDATE "_scheduled_functions" SET status = 'failed', updated_at = ? WHERE id = ?`, [Date.now(), job.id]);
140
173
  this.notifySchedulerJobsChanged();
141
174
  this.deps.devtools.emit({
@@ -147,11 +180,13 @@ var SchedulerEngine = class {
147
180
  });
148
181
  }
149
182
  }
150
- if (executedJobIds.length > 0) {
183
+ if (jobExecutions.length > 0) {
151
184
  this.deps.devtools.emit({
152
185
  type: "scheduler.tick",
153
186
  runtimeId: this.deps.runtimeId,
187
+ executionId: generateId(),
154
188
  executedJobIds,
189
+ jobExecutions,
155
190
  timestamp: Date.now()
156
191
  });
157
192
  this.notifySchedulerJobsChanged();