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":"functions.mjs","names":[],"sources":["../../src/runtime/functions.ts"],"sourcesContent":["import {\n ensureObjectValidator,\n isValidator,\n type Infer,\n type Validator,\n type ValidatorMap\n} from \"@syncore/schema\";\n\nexport type SyncoreFunctionKind = \"query\" | \"mutation\" | \"action\";\nexport type EmptyArgs = Record<never, never>;\n\n/**\n * A typed reference to a Syncore function.\n *\n * Most app code gets these references from the generated `api` object.\n */\nexport interface FunctionReference<\n TKind extends SyncoreFunctionKind = SyncoreFunctionKind,\n TArgs = EmptyArgs,\n TResult = unknown\n> {\n kind: TKind;\n name: string;\n readonly __args?: TArgs;\n readonly __result?: TResult;\n}\n\nexport interface SyncoreFunctionDefinition<\n TKind extends SyncoreFunctionKind,\n TContext,\n TArgs,\n TResult\n> {\n kind: TKind;\n argsValidator: Validator<TArgs, TArgs, string>;\n returnsValidator?: Validator<TResult, TResult, string>;\n handler: (ctx: TContext, args: TArgs) => Promise<TResult> | TResult;\n}\n\nexport type FunctionArgs<TReference> =\n TReference extends FunctionReference<\n SyncoreFunctionKind,\n infer TArgs,\n unknown\n >\n ? TArgs\n : never;\n\nexport type FunctionResult<TReference> =\n TReference extends FunctionReference<\n SyncoreFunctionKind,\n unknown,\n infer TResult\n >\n ? TResult\n : never;\n\nexport type FunctionKindFromDefinition<TDefinition> = TDefinition extends {\n kind: infer TKind;\n}\n ? Extract<TKind, SyncoreFunctionKind>\n : never;\n\nexport type FunctionArgsFromDefinition<TDefinition> = TDefinition extends {\n argsValidator: Validator<infer TArgs, unknown, string>;\n}\n ? TArgs\n : never;\n\nexport type FunctionResultFromDefinition<TDefinition> = TDefinition extends {\n returnsValidator?: Validator<infer TResult, unknown, string>;\n}\n ? TResult\n : never;\n\nexport type FunctionReferenceFor<TDefinition> =\n FunctionKindFromDefinition<TDefinition> extends never\n ? never\n : FunctionReference<\n FunctionKindFromDefinition<TDefinition>,\n FunctionArgsFromDefinition<TDefinition>,\n FunctionResultFromDefinition<TDefinition>\n >;\n\nexport interface FunctionConfig<TContext, TArgs, TResult> {\n args: Validator<TArgs, TArgs, string> | ValidatorMap;\n returns?: Validator<TResult, TResult, string>;\n handler: (ctx: TContext, args: TArgs) => Promise<TResult> | TResult;\n}\n\nexport type InferArgs<\n TArgs extends Validator<unknown, unknown, string> | ValidatorMap\n> = TArgs extends Validator<unknown, unknown, string>\n ? Infer<TArgs>\n : TArgs extends ValidatorMap\n ? {\n [TKey in keyof TArgs]: Infer<TArgs[TKey]>;\n }\n : never;\n\nfunction createFunctionDefinition<\n TKind extends SyncoreFunctionKind,\n TContext,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap,\n TResult\n>(\n kind: TKind,\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<TKind, TContext, InferArgs<TArgsShape>, TResult> {\n const argsValidator = isValidator(config.args)\n ? (config.args as Validator<\n InferArgs<TArgsShape>,\n InferArgs<TArgsShape>,\n string\n >)\n : (ensureObjectValidator(config.args as ValidatorMap) as unknown as Validator<\n InferArgs<TArgsShape>,\n InferArgs<TArgsShape>,\n string\n >);\n\n return {\n kind,\n argsValidator,\n ...(config.returns ? { returnsValidator: config.returns } : {}),\n handler: config.handler\n };\n}\n\n/**\n * Define a Syncore query.\n *\n * Queries can read local Syncore state and are available to clients.\n */\nexport function query<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"query\", TContext, Infer<TValidator>, TResult>;\nexport function query<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\"query\", TContext, InferArgs<TArgsShape>, TResult>;\nexport function query<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"query\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"query\", config);\n}\n\n/**\n * Define a Syncore mutation.\n *\n * Mutations can modify local Syncore state and are available to clients.\n */\nexport function mutation<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"mutation\", TContext, Infer<TValidator>, TResult>;\nexport function mutation<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"mutation\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n>;\nexport function mutation<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"mutation\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"mutation\", config);\n}\n\n/**\n * Define a Syncore action.\n *\n * Actions can run arbitrary JavaScript and may call other Syncore functions.\n */\nexport function action<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"action\", TContext, Infer<TValidator>, TResult>;\nexport function action<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"action\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n>;\nexport function action<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"action\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"action\", config);\n}\n\nexport interface RecurringIntervalSchedule {\n type: \"interval\";\n seconds?: number;\n minutes?: number;\n hours?: number;\n}\n\nexport interface RecurringDailySchedule {\n type: \"daily\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport interface RecurringWeeklySchedule {\n type: \"weekly\";\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport type RecurringSchedule =\n | RecurringIntervalSchedule\n | RecurringDailySchedule\n | RecurringWeeklySchedule;\n\nexport type MisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n\nexport interface RecurringJobDefinition {\n name: string;\n schedule: RecurringSchedule;\n function: FunctionReference<\"mutation\" | \"action\">;\n args: Record<string, unknown>;\n misfirePolicy: MisfirePolicy;\n}\n\nexport class CronJobs {\n readonly jobs: RecurringJobDefinition[] = [];\n\n interval(\n name: string,\n schedule: Omit<RecurringIntervalSchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"interval\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n\n daily(\n name: string,\n schedule: Omit<RecurringDailySchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"daily\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n\n weekly(\n name: string,\n schedule: Omit<RecurringWeeklySchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"weekly\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n}\n\n/**\n * Create a recurring job registry for Syncore scheduler definitions.\n */\nexport function cronJobs(): CronJobs {\n return new CronJobs();\n}\n"],"mappings":";;AAoGA,SAAS,yBAMP,MACA,QAG4E;AAa5E,QAAO;EACL;EACA,eAdoB,YAAY,OAAO,KAAK,GACzC,OAAO,OAKP,sBAAsB,OAAO,KAAqB;EASrD,GAAI,OAAO,UAAU,EAAE,kBAAkB,OAAO,SAAS,GAAG,EAAE;EAC9D,SAAS,OAAO;EACjB;;AA8BH,SAAgB,MAMd,QAQA;AACA,QAAO,yBAAyB,SAAS,OAAO;;AAmClD,SAAgB,SAMd,QAQA;AACA,QAAO,yBAAyB,YAAY,OAAO;;AAmCrD,SAAgB,OAMd,QAQA;AACA,QAAO,yBAAyB,UAAU,OAAO;;AAmDnD,IAAa,WAAb,MAAsB;CACpB,OAA0C,EAAE;CAE5C,SACE,MACA,UACA,mBACA,OAAgC,EAAE,EAClC,gBAA+B,EAAE,MAAM,YAAY,EAC7C;AACN,OAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAY,GAAG;IAAU;GAC3C,UAAU;GACV;GACA;GACD,CAAC;AACF,SAAO;;CAGT,MACE,MACA,UACA,mBACA,OAAgC,EAAE,EAClC,gBAA+B,EAAE,MAAM,YAAY,EAC7C;AACN,OAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAS,GAAG;IAAU;GACxC,UAAU;GACV;GACA;GACD,CAAC;AACF,SAAO;;CAGT,OACE,MACA,UACA,mBACA,OAAgC,EAAE,EAClC,gBAA+B,EAAE,MAAM,YAAY,EAC7C;AACN,OAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAU,GAAG;IAAU;GACzC,UAAU;GACV;GACA;GACD,CAAC;AACF,SAAO;;;;;;AAOX,SAAgB,WAAqB;AACnC,QAAO,IAAI,UAAU"}
1
+ {"version":3,"file":"functions.mjs","names":[],"sources":["../../src/runtime/functions.ts"],"sourcesContent":["import {\n ensureObjectValidator,\n isValidator,\n type Infer,\n type Validator,\n type ValidatorMap\n} from \"@syncore/schema\";\n\n/**\n * Discriminates the three function kinds Syncore supports.\n *\n * - `\"query\"` — read-only handler that observes local state. Syncore re-runs it\n * automatically whenever any table it read changes, keeping connected clients\n * up to date without manual cache invalidation.\n * - `\"mutation\"` — transactional write handler. Runs inside a single SQLite\n * transaction and automatically invalidates every query that read the tables it\n * modified.\n * - `\"action\"` — arbitrary async handler that may call external services, invoke\n * other Syncore functions, or schedule deferred work. Actions do not run inside\n * a transaction and cannot directly write to the database — they must delegate\n * writes to mutations.\n */\nexport type SyncoreFunctionKind = \"query\" | \"mutation\" | \"action\";\n\n/**\n * Convenience type representing a function that accepts no arguments.\n *\n * Used as the default `TArgs` for {@link FunctionReference} so that calling\n * `client.query(api.tasks.list)` without a second argument is type-safe.\n */\nexport type EmptyArgs = Record<never, never>;\n\n/**\n * A typed, serialisable handle to a registered Syncore function.\n *\n * `FunctionReference` objects are how you address Syncore functions across the\n * entire API surface: hooks, client calls, scheduler helpers, and `ctx.runQuery`\n * / `ctx.runMutation` inside other functions all accept them. They carry the\n * function's kind and its fully-inferred arg / result types at the type level,\n * but at runtime they hold only the function's string name, making them safe to\n * pass across IPC channels.\n *\n * In almost every case you get references from the auto-generated `api` object\n * rather than constructing them manually:\n *\n * ```ts\n * import { api } from \"../syncore/_generated/api\";\n *\n * // In a React component:\n * const tasks = useQuery(api.tasks.list);\n *\n * // Inside a mutation that calls another function:\n * const id = await ctx.runMutation(api.tasks.create, { title: \"Buy milk\" });\n *\n * // Scheduling deferred work:\n * await ctx.scheduler.runAfter(60_000, api.notifications.send, { userId });\n * ```\n *\n * When you need to type a parameter that accepts a function reference, derive\n * the correct type with {@link FunctionReferenceFor}.\n */\nexport interface FunctionReference<\n TKind extends SyncoreFunctionKind = SyncoreFunctionKind,\n TArgs = EmptyArgs,\n TResult = unknown\n> {\n kind: TKind;\n name: string;\n readonly __args?: TArgs;\n readonly __result?: TResult;\n}\n\n/**\n * The full definition of a Syncore function as produced by {@link query},\n * {@link mutation}, or {@link action}.\n *\n * This is the value you export from files inside `syncore/functions/`. Syncore\n * stores it in the function registry and uses the validators at runtime to parse\n * incoming arguments and optionally validate return values.\n *\n * You rarely reference this type directly in application code — use\n * {@link FunctionReferenceFor} when you need a type-level handle, or the\n * generated `api` object for runtime usage.\n */\nexport interface SyncoreFunctionDefinition<\n TKind extends SyncoreFunctionKind,\n TContext,\n TArgs,\n TResult\n> {\n kind: TKind;\n argsValidator: Validator<TArgs, TArgs, string>;\n returnsValidator?: Validator<TResult, TResult, string>;\n handler: (ctx: TContext, args: TArgs) => Promise<TResult> | TResult;\n}\n\n/**\n * Extracts the argument type from a {@link FunctionReference}.\n *\n * Useful when writing generic helpers that accept a function reference and need\n * to type the corresponding arguments:\n *\n * ```ts\n * async function run<TRef extends FunctionReference<\"mutation\">>(\n * ref: TRef,\n * args: FunctionArgs<TRef>\n * ) { ... }\n * ```\n */\nexport type FunctionArgs<TReference> =\n TReference extends FunctionReference<\n SyncoreFunctionKind,\n infer TArgs,\n unknown\n >\n ? TArgs\n : never;\n\n/**\n * Extracts the result type from a {@link FunctionReference}.\n *\n * ```ts\n * type TaskList = FunctionResult<typeof api.tasks.list>; // Task[]\n * ```\n */\nexport type FunctionResult<TReference> =\n TReference extends FunctionReference<\n SyncoreFunctionKind,\n unknown,\n infer TResult\n >\n ? TResult\n : never;\n\n/**\n * Extracts the {@link SyncoreFunctionKind} from a function definition object.\n *\n * Used internally by {@link FunctionReferenceFor} and the code generator.\n */\nexport type FunctionKindFromDefinition<TDefinition> = TDefinition extends {\n kind: infer TKind;\n}\n ? Extract<TKind, SyncoreFunctionKind>\n : never;\n\n/**\n * Extracts the validated argument type from a function definition object.\n *\n * Used internally by {@link FunctionReferenceFor} and the code generator.\n */\nexport type FunctionArgsFromDefinition<TDefinition> = TDefinition extends {\n argsValidator: Validator<infer TArgs, unknown, string>;\n}\n ? TArgs\n : never;\n\n/**\n * Extracts the return type from a function definition object.\n *\n * Used internally by {@link FunctionReferenceFor} and the code generator.\n */\nexport type FunctionResultFromDefinition<TDefinition> = TDefinition extends {\n returnsValidator?: Validator<infer TResult, unknown, string>;\n}\n ? TResult\n : never;\n\n/**\n * Derives a fully-typed {@link FunctionReference} from a function definition.\n *\n * Use this when you need a typed reference to a function you have imported\n * directly — for example when writing test helpers or custom wrappers:\n *\n * ```ts\n * import type { create } from \"../syncore/functions/tasks\";\n *\n * type CreateRef = FunctionReferenceFor<typeof create>;\n * // FunctionReference<\"mutation\", { title: string }, string>\n * ```\n *\n * The generated `api` object already exposes `FunctionReferenceFor`-derived\n * values for every exported function, so you rarely need this in application\n * code.\n */\nexport type FunctionReferenceFor<TDefinition> =\n FunctionKindFromDefinition<TDefinition> extends never\n ? never\n : FunctionReference<\n FunctionKindFromDefinition<TDefinition>,\n FunctionArgsFromDefinition<TDefinition>,\n FunctionResultFromDefinition<TDefinition>\n >;\n\n/**\n * Configuration object accepted by {@link query}, {@link mutation}, and\n * {@link action}.\n *\n * @template TContext - The execution context injected by the runtime\n * (`QueryCtx`, `MutationCtx`, or `ActionCtx`).\n * @template TArgs - The validated argument shape after parsing.\n * @template TResult - The return type of the handler.\n */\nexport interface FunctionConfig<TContext, TArgs, TResult> {\n /**\n * Schema that validates and types the arguments this function accepts.\n *\n * You can pass either a single `Validator` or a plain object (\"validator map\")\n * whose keys map to individual field validators — both forms are equivalent:\n *\n * ```ts\n * // Validator map (most common)\n * args: { title: s.string(), done: s.boolean() }\n *\n * // Single object validator (same result)\n * args: s.object({ title: s.string(), done: s.boolean() })\n * ```\n */\n args: Validator<TArgs, TArgs, string> | ValidatorMap;\n\n /**\n * Optional schema that validates the value returned by the handler.\n *\n * When provided, Syncore validates the return value before sending it to\n * clients. Omitting `returns` disables return-value validation but does not\n * affect the TypeScript return type inferred from the handler.\n */\n returns?: Validator<TResult, TResult, string>;\n\n /**\n * The function body. Receives a typed context object and the validated\n * arguments and must return (or resolve to) the function's result.\n */\n handler: (ctx: TContext, args: TArgs) => Promise<TResult> | TResult;\n}\n\nexport type InferArgs<\n TArgs extends Validator<unknown, unknown, string> | ValidatorMap\n> = TArgs extends Validator<unknown, unknown, string>\n ? Infer<TArgs>\n : TArgs extends ValidatorMap\n ? {\n [TKey in keyof TArgs]: Infer<TArgs[TKey]>;\n }\n : never;\n\nfunction createFunctionDefinition<\n TKind extends SyncoreFunctionKind,\n TContext,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap,\n TResult\n>(\n kind: TKind,\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<TKind, TContext, InferArgs<TArgsShape>, TResult> {\n const argsValidator = isValidator(config.args)\n ? (config.args as Validator<\n InferArgs<TArgsShape>,\n InferArgs<TArgsShape>,\n string\n >)\n : (ensureObjectValidator(config.args as ValidatorMap) as unknown as Validator<\n InferArgs<TArgsShape>,\n InferArgs<TArgsShape>,\n string\n >);\n\n return {\n kind,\n argsValidator,\n ...(config.returns ? { returnsValidator: config.returns } : {}),\n handler: config.handler\n };\n}\n\n/**\n * Define a Syncore query.\n *\n * Queries are the read layer of Syncore. They run inside a read-only database\n * transaction, may call other queries via `ctx.runQuery`, and are\n * **automatically reactive**: whenever a table that a query read changes,\n * every active subscription to that query is invalidated and re-executed.\n *\n * Export one query per named export in a file under `syncore/functions/`.\n * After running `npx syncorejs codegen` a typed reference will be available\n * on the generated `api` object.\n *\n * ```ts\n * // syncore/functions/tasks.ts\n * import { query } from \"syncorejs\";\n * import { s } from \"syncorejs\";\n * import type { QueryCtx } from \"../_generated/server\";\n *\n * export const list = query({\n * args: { projectId: s.optional(s.id(\"projects\")) },\n * handler: async (ctx: QueryCtx, { projectId }) => {\n * return ctx.db\n * .query(\"tasks\")\n * .withIndex(\"by_project\", (q) =>\n * projectId ? q.eq(\"projectId\", projectId) : q\n * )\n * .collect();\n * },\n * });\n * ```\n *\n * @param config - The {@link FunctionConfig} describing the args schema,\n * optional return-value schema, and handler function.\n */\nexport function query<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"query\", TContext, Infer<TValidator>, TResult>;\nexport function query<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\"query\", TContext, InferArgs<TArgsShape>, TResult>;\nexport function query<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"query\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"query\", config);\n}\n\n/**\n * Define a Syncore mutation.\n *\n * Mutations are the write layer of Syncore. Every mutation runs inside an\n * **atomic SQLite transaction**: if the handler throws, all writes are rolled\n * back. After a successful commit Syncore automatically invalidates and\n * re-executes every active query whose read-set overlaps the changed tables.\n *\n * Mutations receive a {@link MutationCtx}, which extends the query context\n * with `ctx.db` write methods and a `ctx.scheduler` for scheduling deferred\n * work.\n *\n * ```ts\n * // syncore/functions/tasks.ts\n * import { mutation } from \"syncorejs\";\n * import { s } from \"syncorejs\";\n * import type { MutationCtx } from \"../_generated/server\";\n *\n * export const create = mutation({\n * args: { title: s.string() },\n * returns: s.id(\"tasks\"),\n * handler: async (ctx: MutationCtx, { title }) => {\n * return ctx.db.insert(\"tasks\", {\n * title,\n * status: \"todo\",\n * projectId: null,\n * });\n * },\n * });\n * ```\n *\n * @param config - The {@link FunctionConfig} describing the args schema,\n * optional return-value schema, and handler function.\n */\nexport function mutation<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"mutation\", TContext, Infer<TValidator>, TResult>;\nexport function mutation<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"mutation\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n>;\nexport function mutation<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"mutation\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"mutation\", config);\n}\n\n/**\n * Define a Syncore action.\n *\n * Actions are the escape hatch for work that goes beyond reading and writing\n * the local database. They run **outside** of any transaction, which means\n * they can:\n *\n * - Call external APIs (HTTP, WebSocket, etc.)\n * - Perform CPU-intensive or long-running work\n * - Invoke other Syncore functions via `ctx.runMutation` / `ctx.runQuery`\n * - Schedule deferred jobs via `ctx.scheduler`\n *\n * Because actions are non-transactional, database writes must be delegated to\n * a mutation. This keeps write atomicity in mutations while actions handle\n * side effects.\n *\n * ```ts\n * // syncore/functions/ai.ts\n * import { action } from \"syncorejs\";\n * import { s } from \"syncorejs\";\n * import type { ActionCtx } from \"../_generated/server\";\n * import { api } from \"../_generated/api\";\n *\n * export const summarise = action({\n * args: { taskId: s.id(\"tasks\") },\n * handler: async (ctx: ActionCtx, { taskId }) => {\n * const task = await ctx.runQuery(api.tasks.get, { id: taskId });\n * const summary = await fetchSummaryFromApi(task.title);\n * await ctx.runMutation(api.tasks.setSummary, { taskId, summary });\n * },\n * });\n * ```\n *\n * @param config - The {@link FunctionConfig} describing the args schema,\n * optional return-value schema, and handler function.\n */\nexport function action<\n TContext = unknown,\n TValidator extends Validator<unknown, unknown, string> = Validator<\n unknown,\n unknown,\n string\n >,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, Infer<TValidator>, TResult> & {\n args: TValidator;\n }\n): SyncoreFunctionDefinition<\"action\", TContext, Infer<TValidator>, TResult>;\nexport function action<\n TContext = unknown,\n TArgsShape extends ValidatorMap = ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"action\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n>;\nexport function action<\n TContext = unknown,\n TArgsShape extends Validator<unknown, unknown, string> | ValidatorMap =\n ValidatorMap,\n TResult = unknown\n>(\n config: FunctionConfig<TContext, InferArgs<TArgsShape>, TResult> & {\n args: TArgsShape;\n }\n): SyncoreFunctionDefinition<\n \"action\",\n TContext,\n InferArgs<TArgsShape>,\n TResult\n> {\n return createFunctionDefinition(\"action\", config);\n}\n\n/**\n * Runs a recurring job repeatedly at a fixed time interval.\n *\n * At least one of `seconds`, `minutes`, or `hours` must be provided; multiple\n * fields are additive (e.g. `{ hours: 1, minutes: 30 }` fires every 90 minutes).\n *\n * ```ts\n * crons.interval(\"refresh-cache\", { minutes: 15 }, api.cache.refresh);\n * ```\n */\nexport interface RecurringIntervalSchedule {\n type: \"interval\";\n /** Number of seconds to add to the interval. */\n seconds?: number;\n /** Number of minutes to add to the interval. */\n minutes?: number;\n /** Number of hours to add to the interval. */\n hours?: number;\n}\n\n/**\n * Runs a recurring job once a day at a specific wall-clock time.\n *\n * ```ts\n * crons.daily(\"nightly-report\", { hour: 2, minute: 0 }, api.reports.generate);\n * ```\n */\nexport interface RecurringDailySchedule {\n type: \"daily\";\n /** Hour of day to run (0–23, in UTC unless `timezone` is provided). */\n hour: number;\n /** Minute of hour to run (0–59). */\n minute: number;\n /**\n * IANA timezone name (e.g. `\"America/New_York\"`). Defaults to UTC when\n * omitted.\n */\n timezone?: string;\n}\n\n/**\n * Runs a recurring job once a week on a specific day and time.\n *\n * ```ts\n * crons.weekly(\n * \"weekly-digest\",\n * { dayOfWeek: \"monday\", hour: 9, minute: 0, timezone: \"Europe/London\" },\n * api.email.weeklyDigest\n * );\n * ```\n */\nexport interface RecurringWeeklySchedule {\n type: \"weekly\";\n /** Day of the week on which to fire. */\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n /** Hour of day to run (0–23, in UTC unless `timezone` is provided). */\n hour: number;\n /** Minute of hour to run (0–59). */\n minute: number;\n /**\n * IANA timezone name (e.g. `\"America/New_York\"`). Defaults to UTC when\n * omitted.\n */\n timezone?: string;\n}\n\n/**\n * Union of all supported recurring-schedule shapes.\n *\n * Pass this (or one of its members) to {@link RecurringJobDefinition.schedule}\n * or to the fluent helpers on {@link CronJobs}.\n */\nexport type RecurringSchedule =\n | RecurringIntervalSchedule\n | RecurringDailySchedule\n | RecurringWeeklySchedule;\n\n/**\n * Determines how the scheduler reacts when a job run is missed (e.g. because\n * the runtime was offline when the job was supposed to fire).\n *\n * - `\"catch_up\"` — Run the job once for every missed execution window. Use for\n * jobs where every run matters (e.g. per-minute metrics collection).\n * - `\"skip\"` — Skip all missed runs and resume on the next scheduled tick.\n * Safe default when running the job twice in quick succession would be\n * harmful.\n * - `\"run_once_if_missed\"` — If any runs were missed, execute the job exactly\n * once to “catch up”, then continue on the normal schedule.\n * - `\"windowed\"` — Catch up, but only within a specific time window. Missed\n * runs older than `windowMs` milliseconds are discarded.\n *\n * @example\n * ```ts\n * const policy: MisfirePolicy = { type: \"windowed\", windowMs: 5 * 60_000 };\n * ```\n */\nexport type MisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n\n/**\n * A single entry in the recurring-job registry.\n *\n * You can construct these manually and pass them to `scheduler.recurringJobs`,\n * but the fluent {@link CronJobs} builder is usually more readable.\n */\nexport interface RecurringJobDefinition {\n /** Unique name used to identify this job in the scheduler and devtools UI. */\n name: string;\n /** When and how often this job should run. */\n schedule: RecurringSchedule;\n /** The function to invoke. Must be a mutation or action reference. */\n function: FunctionReference<\"mutation\" | \"action\">;\n /** Arguments forwarded to the function on every invocation. */\n args: Record<string, unknown>;\n /** How to handle missed executions. */\n misfirePolicy: MisfirePolicy;\n}\n\n/**\n * Fluent builder for declaring the recurring (cron) jobs of a Syncore app.\n *\n * Instantiate with {@link cronJobs} and chain calls to `.interval()`, `.daily()`,\n * or `.weekly()`. Pass the resulting instance's `.jobs` array to\n * `scheduler.recurringJobs` in your runtime options.\n *\n * ```ts\n * // syncore/crons.ts\n * import { cronJobs } from \"syncorejs\";\n * import { api } from \"./_generated/api\";\n *\n * const crons = cronJobs();\n *\n * crons.interval(\"refresh-feed\", { minutes: 10 }, api.feed.refresh);\n * crons.daily(\"send-digest\", { hour: 8, minute: 0 }, api.email.digest);\n * crons.weekly(\"weekly-cleanup\", { dayOfWeek: \"sunday\", hour: 3, minute: 0 }, api.db.vacuum);\n *\n * export default crons;\n * ```\n *\n * Then in your runtime setup:\n * ```ts\n * createNodeSyncoreRuntime({\n * ...,\n * scheduler: { recurringJobs: crons.jobs },\n * });\n * ```\n */\nexport class CronJobs {\n readonly jobs: RecurringJobDefinition[] = [];\n\n /**\n * Register a job that fires repeatedly at a fixed time interval.\n *\n * @param name - Unique identifier for this job.\n * @param schedule - Interval fields (`seconds`, `minutes`, `hours`).\n * @param functionReference - Mutation or action to invoke.\n * @param args - Arguments forwarded on every invocation.\n * @param misfirePolicy - How to handle runs missed while the runtime was\n * offline. Defaults to `{ type: \"catch_up\" }`.\n */\n interval(\n name: string,\n schedule: Omit<RecurringIntervalSchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"interval\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n\n /**\n * Register a job that fires once a day at a given wall-clock time.\n *\n * @param name - Unique identifier for this job.\n * @param schedule - `hour` (0–23), `minute` (0–59), optional `timezone`.\n * @param functionReference - Mutation or action to invoke.\n * @param args - Arguments forwarded on every invocation.\n * @param misfirePolicy - How to handle runs missed while the runtime was\n * offline. Defaults to `{ type: \"catch_up\" }`.\n */\n daily(\n name: string,\n schedule: Omit<RecurringDailySchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"daily\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n\n /**\n * Register a job that fires once a week on a given day and time.\n *\n * @param name - Unique identifier for this job.\n * @param schedule - `dayOfWeek`, `hour` (0–23), `minute` (0–59),\n * optional `timezone`.\n * @param functionReference - Mutation or action to invoke.\n * @param args - Arguments forwarded on every invocation.\n * @param misfirePolicy - How to handle runs missed while the runtime was\n * offline. Defaults to `{ type: \"catch_up\" }`.\n */\n weekly(\n name: string,\n schedule: Omit<RecurringWeeklySchedule, \"type\">,\n functionReference: FunctionReference<\"mutation\" | \"action\">,\n args: Record<string, unknown> = {},\n misfirePolicy: MisfirePolicy = { type: \"catch_up\" }\n ): this {\n this.jobs.push({\n name,\n schedule: { type: \"weekly\", ...schedule },\n function: functionReference,\n args,\n misfirePolicy\n });\n return this;\n }\n}\n\n/**\n * Create a new {@link CronJobs} builder for declaring recurring Syncore jobs.\n *\n * @example\n * ```ts\n * // syncore/crons.ts\n * import { cronJobs } from \"syncorejs\";\n * import { api } from \"./_generated/api\";\n *\n * const crons = cronJobs();\n * crons.interval(\"sync\", { minutes: 5 }, api.sync.run);\n * export default crons;\n * ```\n */\nexport function cronJobs(): CronJobs {\n return new CronJobs();\n}\n"],"mappings":";;AAqPA,SAAS,yBAMP,MACA,QAG4E;CAa5E,OAAO;EACL;EACA,eAdoB,YAAY,OAAO,IAAI,IACxC,OAAO,OAKP,sBAAsB,OAAO,IAAoB;EASpD,GAAI,OAAO,UAAU,EAAE,kBAAkB,OAAO,QAAQ,IAAI,CAAC;EAC7D,SAAS,OAAO;CAClB;AACF;AA0DA,SAAgB,MAMd,QAQA;CACA,OAAO,yBAAyB,SAAS,MAAM;AACjD;AA+DA,SAAgB,SAMd,QAQA;CACA,OAAO,yBAAyB,YAAY,MAAM;AACpD;AAiEA,SAAgB,OAMd,QAQA;CACA,OAAO,yBAAyB,UAAU,MAAM;AAClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+JA,IAAa,WAAb,MAAsB;CACpB,OAA0C,CAAC;;;;;;;;;;;CAY3C,SACE,MACA,UACA,mBACA,OAAgC,CAAC,GACjC,gBAA+B,EAAE,MAAM,WAAW,GAC5C;EACN,KAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAY,GAAG;GAAS;GAC1C,UAAU;GACV;GACA;EACF,CAAC;EACD,OAAO;CACT;;;;;;;;;;;CAYA,MACE,MACA,UACA,mBACA,OAAgC,CAAC,GACjC,gBAA+B,EAAE,MAAM,WAAW,GAC5C;EACN,KAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAS,GAAG;GAAS;GACvC,UAAU;GACV;GACA;EACF,CAAC;EACD,OAAO;CACT;;;;;;;;;;;;CAaA,OACE,MACA,UACA,mBACA,OAAgC,CAAC,GACjC,gBAA+B,EAAE,MAAM,WAAW,GAC5C;EACN,KAAK,KAAK,KAAK;GACb;GACA,UAAU;IAAE,MAAM;IAAU,GAAG;GAAS;GACxC,UAAU;GACV;GACA;EACF,CAAC;EACD,OAAO;CACT;AACF;;;;;;;;;;;;;;;AAgBA,SAAgB,WAAqB;CACnC,OAAO,IAAI,SAAS;AACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"id.d.mts","names":[],"sources":["../../src/runtime/id.ts"],"mappings":";;AAQA;;;;;;;iBAAgB,UAAA,CAAA"}
1
+ {"version":3,"file":"id.d.mts","names":[],"sources":["../../src/runtime/id.ts"],"mappings":";;AAQA;;;;AAA0B;;;iBAAV,UAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"id.mjs","names":[],"sources":["../../src/runtime/id.ts"],"sourcesContent":["/**\n * Generate a random UUID v4 string.\n *\n * Prefers `crypto.randomUUID()` when available (secure contexts, Node 19+,\n * web workers). Falls back to building a v4 UUID from\n * `crypto.getRandomValues()` for non-secure contexts such as `http://`\n * dev servers.\n */\nexport function generateId(): string {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n // Fallback: build a UUID v4 from getRandomValues.\n // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n\n // Set version (4) and variant (10xx) bits per RFC 4122.\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\"\n );\n\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32)\n ].join(\"-\");\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,aAAqB;AACnC,KACE,OAAO,WAAW,eAClB,OAAO,OAAO,eAAe,WAE7B,QAAO,OAAO,YAAY;CAK5B,MAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,QAAO,gBAAgB,MAAM;AAG7B,OAAM,KAAM,MAAM,KAAM,KAAQ;AAChC,OAAM,KAAM,MAAM,KAAM,KAAQ;CAEhC,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KACpE,GACD;AAED,QAAO;EACL,IAAI,MAAM,GAAG,EAAE;EACf,IAAI,MAAM,GAAG,GAAG;EAChB,IAAI,MAAM,IAAI,GAAG;EACjB,IAAI,MAAM,IAAI,GAAG;EACjB,IAAI,MAAM,IAAI,GAAG;EAClB,CAAC,KAAK,IAAI"}
1
+ {"version":3,"file":"id.mjs","names":[],"sources":["../../src/runtime/id.ts"],"sourcesContent":["/**\n * Generate a random UUID v4 string.\n *\n * Prefers `crypto.randomUUID()` when available (secure contexts, Node 19+,\n * web workers). Falls back to building a v4 UUID from\n * `crypto.getRandomValues()` for non-secure contexts such as `http://`\n * dev servers.\n */\nexport function generateId(): string {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n // Fallback: build a UUID v4 from getRandomValues.\n // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n\n // Set version (4) and variant (10xx) bits per RFC 4122.\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\"\n );\n\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32)\n ].join(\"-\");\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,aAAqB;CACnC,IACE,OAAO,WAAW,eAClB,OAAO,OAAO,eAAe,YAE7B,OAAO,OAAO,WAAW;CAK3B,MAAM,QAAQ,IAAI,WAAW,EAAE;CAC/B,OAAO,gBAAgB,KAAK;CAG5B,MAAM,KAAM,MAAM,KAAM,KAAQ;CAChC,MAAM,KAAM,MAAM,KAAM,KAAQ;CAEhC,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KACpE,EACF;CAEA,OAAO;EACL,IAAI,MAAM,GAAG,CAAC;EACd,IAAI,MAAM,GAAG,EAAE;EACf,IAAI,MAAM,IAAI,EAAE;EAChB,IAAI,MAAM,IAAI,EAAE;EAChB,IAAI,MAAM,IAAI,EAAE;CAClB,EAAE,KAAK,GAAG;AACZ"}
@@ -1,9 +1,11 @@
1
1
  import { devtoolsScopesForEvent } from "./shared.mjs";
2
2
  //#region src/runtime/internal/engines/devtoolsEngine.ts
3
3
  var DevtoolsEngine = class {
4
+ deps;
4
5
  recentEvents = [];
5
6
  listeners = /* @__PURE__ */ new Set();
6
7
  invalidationListeners = /* @__PURE__ */ new Set();
8
+ nextSequence = 1;
7
9
  constructor(deps) {
8
10
  this.deps = deps;
9
11
  }
@@ -43,11 +45,15 @@ var DevtoolsEngine = class {
43
45
  for (const listener of this.invalidationListeners) listener(scopeSet);
44
46
  }
45
47
  emit(event) {
46
- this.recentEvents.unshift(event);
47
- this.recentEvents.splice(24);
48
- this.deps.sink?.emit(event);
49
- this.notifyScopes(devtoolsScopesForEvent(event));
50
- for (const listener of this.listeners) listener(event);
48
+ const sequencedEvent = {
49
+ ...event,
50
+ sequence: event.sequence ?? this.nextSequence++
51
+ };
52
+ this.recentEvents.push(sequencedEvent);
53
+ this.recentEvents.splice(0, Math.max(0, this.recentEvents.length - 24));
54
+ this.deps.sink?.emit(sequencedEvent);
55
+ this.notifyScopes(devtoolsScopesForEvent(sequencedEvent));
56
+ for (const listener of this.listeners) listener(sequencedEvent);
51
57
  }
52
58
  async forceRefresh(reason, handlers, meta = {}, scopes = []) {
53
59
  const scopeSet = new Set(scopes);
@@ -1 +1 @@
1
- {"version":3,"file":"devtoolsEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/devtoolsEngine.ts"],"sourcesContent":["import type {\n SyncoreActiveQueryInfo,\n SyncoreDevtoolsEvent,\n SyncoreRuntimeSummary\n} from \"@syncore/devtools-protocol\";\nimport type {\n ImpactScope,\n DevtoolsLiveQueryScope,\n DevtoolsLiveQuerySnapshot,\n DevtoolsSink\n} from \"../../runtime.js\";\nimport { devtoolsScopesForEvent, type DevtoolsEventMeta } from \"./shared.js\";\n\ntype DevtoolsEngineDeps = {\n runtimeId: string;\n platform: string;\n sink?: DevtoolsSink;\n getActiveQueryInfos: () => SyncoreActiveQueryInfo[];\n getSchemaTables: () => Promise<DevtoolsLiveQuerySnapshot[\"schemaTables\"]>;\n};\n\nexport class DevtoolsEngine {\n private readonly recentEvents: SyncoreDevtoolsEvent[] = [];\n private readonly listeners = new Set<(event: SyncoreDevtoolsEvent) => void>();\n private readonly invalidationListeners = new Set<\n (scopes: Set<DevtoolsLiveQueryScope>) => void\n >();\n\n constructor(private readonly deps: DevtoolsEngineDeps) {}\n\n getRuntimeSummary(): SyncoreRuntimeSummary {\n return {\n runtimeId: this.deps.runtimeId,\n platform: this.deps.platform,\n connectedAt: Date.now(),\n activeQueryCount: this.deps.getActiveQueryInfos().length,\n recentEventCount: this.recentEvents.length\n };\n }\n\n getActiveQueryInfos(): SyncoreActiveQueryInfo[] {\n return this.deps.getActiveQueryInfos();\n }\n\n async getLiveSnapshot(): Promise<DevtoolsLiveQuerySnapshot> {\n return {\n summary: this.getRuntimeSummary(),\n activeQueries: this.getActiveQueryInfos(),\n schemaTables: await this.deps.getSchemaTables()\n };\n }\n\n subscribeEvents(listener: (event: SyncoreDevtoolsEvent) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n subscribeInvalidations(\n listener: (scopes: Set<DevtoolsLiveQueryScope>) => void\n ): () => void {\n this.invalidationListeners.add(listener);\n return () => {\n this.invalidationListeners.delete(listener);\n };\n }\n\n notifyScopes(scopes: Iterable<DevtoolsLiveQueryScope>): void {\n const scopeSet = new Set(scopes);\n for (const listener of this.invalidationListeners) {\n listener(scopeSet);\n }\n }\n\n emit(event: SyncoreDevtoolsEvent): void {\n this.recentEvents.unshift(event);\n this.recentEvents.splice(24);\n this.deps.sink?.emit(event);\n this.notifyScopes(devtoolsScopesForEvent(event));\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n async forceRefresh(\n reason: string,\n handlers: {\n refreshQueriesForScopes: (\n scopes: Set<ImpactScope>,\n reason: string\n ) => Promise<void>;\n },\n meta: DevtoolsEventMeta = {},\n scopes: Iterable<ImpactScope> = []\n ): Promise<void> {\n const scopeSet = new Set(scopes);\n if (scopeSet.size > 0) {\n await handlers.refreshQueriesForScopes(scopeSet, reason);\n }\n this.notifyScopes(\n scopeSet.size > 0 ? toDevtoolsScopes(scopeSet) : [\"all\"]\n );\n this.emit({\n type: \"log\",\n runtimeId: this.deps.runtimeId,\n level: \"info\",\n message: reason,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n }\n}\n\nfunction toDevtoolsScopes(\n scopes: Iterable<ImpactScope>\n): DevtoolsLiveQueryScope[] {\n const resolved: DevtoolsLiveQueryScope[] = [];\n for (const scope of scopes) {\n if (\n scope.startsWith(\"row:\") ||\n !(scope.startsWith(\"table:\") || scope.startsWith(\"storage:\")) &&\n scope !== \"runtime.summary\" &&\n scope !== \"runtime.activeQueries\" &&\n scope !== \"schema.tables\" &&\n scope !== \"scheduler.jobs\"\n ) {\n continue;\n }\n resolved.push(scope as DevtoolsLiveQueryScope);\n }\n return resolved.length > 0 ? resolved : [\"all\"];\n}\n"],"mappings":";;AAqBA,IAAa,iBAAb,MAA4B;CAC1B,eAAwD,EAAE;CAC1D,4BAA6B,IAAI,KAA4C;CAC7E,wCAAyC,IAAI,KAE1C;CAEH,YAAY,MAA2C;AAA1B,OAAA,OAAA;;CAE7B,oBAA2C;AACzC,SAAO;GACL,WAAW,KAAK,KAAK;GACrB,UAAU,KAAK,KAAK;GACpB,aAAa,KAAK,KAAK;GACvB,kBAAkB,KAAK,KAAK,qBAAqB,CAAC;GAClD,kBAAkB,KAAK,aAAa;GACrC;;CAGH,sBAAgD;AAC9C,SAAO,KAAK,KAAK,qBAAqB;;CAGxC,MAAM,kBAAsD;AAC1D,SAAO;GACL,SAAS,KAAK,mBAAmB;GACjC,eAAe,KAAK,qBAAqB;GACzC,cAAc,MAAM,KAAK,KAAK,iBAAiB;GAChD;;CAGH,gBAAgB,UAA6D;AAC3E,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,uBACE,UACY;AACZ,OAAK,sBAAsB,IAAI,SAAS;AACxC,eAAa;AACX,QAAK,sBAAsB,OAAO,SAAS;;;CAI/C,aAAa,QAAgD;EAC3D,MAAM,WAAW,IAAI,IAAI,OAAO;AAChC,OAAK,MAAM,YAAY,KAAK,sBAC1B,UAAS,SAAS;;CAItB,KAAK,OAAmC;AACtC,OAAK,aAAa,QAAQ,MAAM;AAChC,OAAK,aAAa,OAAO,GAAG;AAC5B,OAAK,KAAK,MAAM,KAAK,MAAM;AAC3B,OAAK,aAAa,uBAAuB,MAAM,CAAC;AAChD,OAAK,MAAM,YAAY,KAAK,UAC1B,UAAS,MAAM;;CAInB,MAAM,aACJ,QACA,UAMA,OAA0B,EAAE,EAC5B,SAAgC,EAAE,EACnB;EACf,MAAM,WAAW,IAAI,IAAI,OAAO;AAChC,MAAI,SAAS,OAAO,EAClB,OAAM,SAAS,wBAAwB,UAAU,OAAO;AAE1D,OAAK,aACH,SAAS,OAAO,IAAI,iBAAiB,SAAS,GAAG,CAAC,MAAM,CACzD;AACD,OAAK,KAAK;GACR,MAAM;GACN,WAAW,KAAK,KAAK;GACrB,OAAO;GACP,SAAS;GACT,WAAW,KAAK,KAAK;GACrB,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,QAAQ,GAAG,EAAE;GAC/C,CAAC;;;AAIN,SAAS,iBACP,QAC0B;CAC1B,MAAM,WAAqC,EAAE;AAC7C,MAAK,MAAM,SAAS,QAAQ;AAC1B,MACE,MAAM,WAAW,OAAO,IACxB,EAAE,MAAM,WAAW,SAAS,IAAI,MAAM,WAAW,WAAW,KAC1D,UAAU,qBACV,UAAU,2BACV,UAAU,mBACV,UAAU,iBAEZ;AAEF,WAAS,KAAK,MAAgC;;AAEhD,QAAO,SAAS,SAAS,IAAI,WAAW,CAAC,MAAM"}
1
+ {"version":3,"file":"devtoolsEngine.mjs","names":[],"sources":["../../../../src/runtime/internal/engines/devtoolsEngine.ts"],"sourcesContent":["import type {\n SyncoreActiveQueryInfo,\n SyncoreDevtoolsEvent,\n SyncoreRuntimeSummary\n} from \"@syncore/devtools-protocol\";\nimport type {\n ImpactScope,\n DevtoolsLiveQueryScope,\n DevtoolsLiveQuerySnapshot,\n DevtoolsSink\n} from \"../../runtime.js\";\nimport { devtoolsScopesForEvent, type DevtoolsEventMeta } from \"./shared.js\";\n\ntype DevtoolsEngineDeps = {\n runtimeId: string;\n platform: string;\n sink?: DevtoolsSink;\n getActiveQueryInfos: () => SyncoreActiveQueryInfo[];\n getSchemaTables: () => Promise<DevtoolsLiveQuerySnapshot[\"schemaTables\"]>;\n};\n\nexport class DevtoolsEngine {\n private readonly recentEvents: SyncoreDevtoolsEvent[] = [];\n private readonly listeners = new Set<(event: SyncoreDevtoolsEvent) => void>();\n private readonly invalidationListeners = new Set<\n (scopes: Set<DevtoolsLiveQueryScope>) => void\n >();\n private nextSequence = 1;\n\n constructor(private readonly deps: DevtoolsEngineDeps) {}\n\n getRuntimeSummary(): SyncoreRuntimeSummary {\n return {\n runtimeId: this.deps.runtimeId,\n platform: this.deps.platform,\n connectedAt: Date.now(),\n activeQueryCount: this.deps.getActiveQueryInfos().length,\n recentEventCount: this.recentEvents.length\n };\n }\n\n getActiveQueryInfos(): SyncoreActiveQueryInfo[] {\n return this.deps.getActiveQueryInfos();\n }\n\n async getLiveSnapshot(): Promise<DevtoolsLiveQuerySnapshot> {\n return {\n summary: this.getRuntimeSummary(),\n activeQueries: this.getActiveQueryInfos(),\n schemaTables: await this.deps.getSchemaTables()\n };\n }\n\n subscribeEvents(listener: (event: SyncoreDevtoolsEvent) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n subscribeInvalidations(\n listener: (scopes: Set<DevtoolsLiveQueryScope>) => void\n ): () => void {\n this.invalidationListeners.add(listener);\n return () => {\n this.invalidationListeners.delete(listener);\n };\n }\n\n notifyScopes(scopes: Iterable<DevtoolsLiveQueryScope>): void {\n const scopeSet = new Set(scopes);\n for (const listener of this.invalidationListeners) {\n listener(scopeSet);\n }\n }\n\n emit(event: SyncoreDevtoolsEvent): void {\n const sequencedEvent = {\n ...event,\n sequence: event.sequence ?? this.nextSequence++\n };\n this.recentEvents.push(sequencedEvent);\n this.recentEvents.splice(0, Math.max(0, this.recentEvents.length - 24));\n this.deps.sink?.emit(sequencedEvent);\n this.notifyScopes(devtoolsScopesForEvent(sequencedEvent));\n for (const listener of this.listeners) {\n listener(sequencedEvent);\n }\n }\n\n async forceRefresh(\n reason: string,\n handlers: {\n refreshQueriesForScopes: (\n scopes: Set<ImpactScope>,\n reason: string\n ) => Promise<unknown>;\n },\n meta: DevtoolsEventMeta = {},\n scopes: Iterable<ImpactScope> = []\n ): Promise<void> {\n const scopeSet = new Set(scopes);\n if (scopeSet.size > 0) {\n await handlers.refreshQueriesForScopes(scopeSet, reason);\n }\n this.notifyScopes(\n scopeSet.size > 0 ? toDevtoolsScopes(scopeSet) : [\"all\"]\n );\n this.emit({\n type: \"log\",\n runtimeId: this.deps.runtimeId,\n level: \"info\",\n message: reason,\n timestamp: Date.now(),\n ...(meta.origin ? { origin: meta.origin } : {})\n });\n }\n}\n\nfunction toDevtoolsScopes(\n scopes: Iterable<ImpactScope>\n): DevtoolsLiveQueryScope[] {\n const resolved: DevtoolsLiveQueryScope[] = [];\n for (const scope of scopes) {\n if (\n scope.startsWith(\"row:\") ||\n !(scope.startsWith(\"table:\") || scope.startsWith(\"storage:\")) &&\n scope !== \"runtime.summary\" &&\n scope !== \"runtime.activeQueries\" &&\n scope !== \"schema.tables\" &&\n scope !== \"scheduler.jobs\"\n ) {\n continue;\n }\n resolved.push(scope as DevtoolsLiveQueryScope);\n }\n return resolved.length > 0 ? resolved : [\"all\"];\n}\n"],"mappings":";;AAqBA,IAAa,iBAAb,MAA4B;CAQG;CAP7B,eAAwD,CAAC;CACzD,4BAA6B,IAAI,IAA2C;CAC5E,wCAAyC,IAAI,IAE3C;CACF,eAAuB;CAEvB,YAAY,MAA2C;EAA1B,KAAA,OAAA;CAA2B;CAExD,oBAA2C;EACzC,OAAO;GACL,WAAW,KAAK,KAAK;GACrB,UAAU,KAAK,KAAK;GACpB,aAAa,KAAK,IAAI;GACtB,kBAAkB,KAAK,KAAK,oBAAoB,EAAE;GAClD,kBAAkB,KAAK,aAAa;EACtC;CACF;CAEA,sBAAgD;EAC9C,OAAO,KAAK,KAAK,oBAAoB;CACvC;CAEA,MAAM,kBAAsD;EAC1D,OAAO;GACL,SAAS,KAAK,kBAAkB;GAChC,eAAe,KAAK,oBAAoB;GACxC,cAAc,MAAM,KAAK,KAAK,gBAAgB;EAChD;CACF;CAEA,gBAAgB,UAA6D;EAC3E,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,uBACE,UACY;EACZ,KAAK,sBAAsB,IAAI,QAAQ;EACvC,aAAa;GACX,KAAK,sBAAsB,OAAO,QAAQ;EAC5C;CACF;CAEA,aAAa,QAAgD;EAC3D,MAAM,WAAW,IAAI,IAAI,MAAM;EAC/B,KAAK,MAAM,YAAY,KAAK,uBAC1B,SAAS,QAAQ;CAErB;CAEA,KAAK,OAAmC;EACtC,MAAM,iBAAiB;GACrB,GAAG;GACH,UAAU,MAAM,YAAY,KAAK;EACnC;EACA,KAAK,aAAa,KAAK,cAAc;EACrC,KAAK,aAAa,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,aAAa,SAAS,EAAE,CAAC;EACtE,KAAK,KAAK,MAAM,KAAK,cAAc;EACnC,KAAK,aAAa,uBAAuB,cAAc,CAAC;EACxD,KAAK,MAAM,YAAY,KAAK,WAC1B,SAAS,cAAc;CAE3B;CAEA,MAAM,aACJ,QACA,UAMA,OAA0B,CAAC,GAC3B,SAAgC,CAAC,GAClB;EACf,MAAM,WAAW,IAAI,IAAI,MAAM;EAC/B,IAAI,SAAS,OAAO,GAClB,MAAM,SAAS,wBAAwB,UAAU,MAAM;EAEzD,KAAK,aACH,SAAS,OAAO,IAAI,iBAAiB,QAAQ,IAAI,CAAC,KAAK,CACzD;EACA,KAAK,KAAK;GACR,MAAM;GACN,WAAW,KAAK,KAAK;GACrB,OAAO;GACP,SAAS;GACT,WAAW,KAAK,IAAI;GACpB,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;EAC/C,CAAC;CACH;AACF;AAEA,SAAS,iBACP,QAC0B;CAC1B,MAAM,WAAqC,CAAC;CAC5C,KAAK,MAAM,SAAS,QAAQ;EAC1B,IACE,MAAM,WAAW,MAAM,KACvB,EAAE,MAAM,WAAW,QAAQ,KAAK,MAAM,WAAW,UAAU,MACzD,UAAU,qBACV,UAAU,2BACV,UAAU,mBACV,UAAU,kBAEZ;EAEF,SAAS,KAAK,KAA+B;CAC/C;CACA,OAAO,SAAS,SAAS,IAAI,WAAW,CAAC,KAAK;AAChD"}
@@ -1,6 +1,6 @@
1
1
  import { toCanonicalComponentFunctionName } from "../../components.mjs";
2
2
  import { generateId } from "../../id.mjs";
3
- import { fieldExpression, normalizeOptionalArgs, omitSystemFields, quoteIdentifier, resolveSearchIndexTableName, splitSchedulerArgs, stableStringify } from "./shared.mjs";
3
+ import { createDevtoolsPreview, fieldExpression, normalizeOptionalArgs, omitSystemFields, quoteIdentifier, resolveSearchIndexTableName, splitSchedulerArgs, stableStringify } from "./shared.mjs";
4
4
  import { createEmptyExecutionResult } from "../transactionCoordinator.mjs";
5
5
  //#region src/runtime/internal/engines/executionEngine.ts
6
6
  const DEFAULT_MISFIRE_POLICY = { type: "catch_up" };
@@ -141,6 +141,9 @@ var RuntimeSearchIndexBuilder = class {
141
141
  }
142
142
  };
143
143
  var RuntimeQueryBuilder = class {
144
+ executeQuery;
145
+ tableName;
146
+ dependencyCollector;
144
147
  orderDirection = "asc";
145
148
  source = { type: "table" };
146
149
  filterExpression;
@@ -150,10 +153,11 @@ var RuntimeQueryBuilder = class {
150
153
  this.dependencyCollector = dependencyCollector;
151
154
  }
152
155
  withIndex(indexName, builder) {
156
+ const indexRange = builder?.(new RuntimeIndexRangeBuilder()).build() ?? [];
153
157
  this.source = {
154
158
  type: "index",
155
159
  name: indexName,
156
- range: builder?.(new RuntimeIndexRangeBuilder()).build() ?? []
160
+ range: indexRange
157
161
  };
158
162
  return this;
159
163
  }
@@ -215,6 +219,7 @@ var RuntimeQueryBuilder = class {
215
219
  }
216
220
  };
217
221
  var ExecutionEngine = class {
222
+ deps;
218
223
  constructor(deps) {
219
224
  this.deps = deps;
220
225
  }
@@ -233,26 +238,35 @@ var ExecutionEngine = class {
233
238
  async runQuery(reference, args = {}, meta = {}) {
234
239
  const definition = this.resolveFunction(reference, "query");
235
240
  const dependencyCollector = /* @__PURE__ */ new Set();
241
+ const executionId = meta.executionId ?? generateId();
236
242
  const startedAt = Date.now();
237
243
  const result = await this.invokeFunction(definition, args, {
244
+ executionId,
238
245
  mutationDepth: 0,
239
246
  changedTables: /* @__PURE__ */ new Set(),
247
+ documentChanges: [],
240
248
  storageChanges: [],
241
249
  dependencyCollector,
242
250
  componentMetadata: definition.__syncoreComponent
243
251
  });
252
+ const completedAt = Date.now();
244
253
  this.deps.devtools.emit({
245
254
  type: "query.executed",
246
255
  runtimeId: this.deps.runtimeId,
247
256
  queryId: reference.name,
248
257
  functionName: reference.name,
258
+ executionId,
259
+ ...meta.parentExecutionId ? { parentExecutionId: meta.parentExecutionId } : {},
249
260
  ...definition.__syncoreComponent ? {
250
261
  componentPath: definition.__syncoreComponent.componentPath,
251
262
  componentName: definition.__syncoreComponent.componentName
252
263
  } : {},
253
264
  dependencies: [...dependencyCollector],
254
- durationMs: Date.now() - startedAt,
255
- timestamp: Date.now(),
265
+ argsPreview: createDevtoolsPreview(args),
266
+ resultPreview: createDevtoolsPreview(result),
267
+ readScopes: [...dependencyCollector],
268
+ durationMs: completedAt - startedAt,
269
+ timestamp: completedAt,
256
270
  ...meta.origin ? { origin: meta.origin } : {}
257
271
  });
258
272
  return result;
@@ -260,69 +274,100 @@ var ExecutionEngine = class {
260
274
  async runMutation(reference, args = {}, meta = {}) {
261
275
  const definition = this.resolveFunction(reference, "mutation");
262
276
  const mutationId = generateId();
277
+ const executionId = meta.executionId ?? mutationId;
263
278
  const startedAt = Date.now();
264
279
  const execution = await this.deps.transactionCoordinator.runInTransaction(async (transactionState) => this.invokeFunction(definition, args, {
280
+ executionId,
265
281
  mutationDepth: 1,
266
282
  changedTables: transactionState.changedTables,
283
+ documentChanges: transactionState.documentChanges,
267
284
  storageChanges: transactionState.storageChanges,
268
285
  componentMetadata: definition.__syncoreComponent
269
286
  }));
270
- await this.finalizeStatefulExecution(mutationId, execution, Date.now() - startedAt);
287
+ const completedAt = Date.now();
288
+ const impact = this.collectStatefulExecutionImpact(execution);
271
289
  this.deps.devtools.emit({
272
290
  type: "mutation.committed",
273
291
  runtimeId: this.deps.runtimeId,
274
292
  mutationId,
275
293
  functionName: reference.name,
294
+ executionId,
295
+ ...meta.parentExecutionId ? { parentExecutionId: meta.parentExecutionId } : {},
276
296
  ...definition.__syncoreComponent ? {
277
297
  componentPath: definition.__syncoreComponent.componentPath,
278
298
  componentName: definition.__syncoreComponent.componentName
279
299
  } : {},
280
300
  changedTables: [...execution.changedTables],
281
- durationMs: Date.now() - startedAt,
282
- timestamp: Date.now(),
301
+ argsPreview: createDevtoolsPreview(args),
302
+ resultPreview: createDevtoolsPreview(execution.result),
303
+ writeScopes: [...impact.changedScopes],
304
+ changedScopes: [...impact.changedScopes],
305
+ changedDocumentsPreview: execution.documentChanges,
306
+ invalidatedQueryIds: impact.invalidatedQueryIds,
307
+ durationMs: completedAt - startedAt,
308
+ timestamp: completedAt,
283
309
  ...meta.origin ? { origin: meta.origin } : {}
284
310
  });
311
+ await this.publishStatefulExecutionEffects(executionId, execution, impact.changedScopes);
285
312
  return execution.result;
286
313
  }
287
314
  async runAction(reference, args = {}, meta = {}) {
288
315
  const definition = this.resolveFunction(reference, "action");
289
316
  const actionId = generateId();
317
+ const executionId = meta.executionId ?? actionId;
290
318
  const startedAt = Date.now();
291
319
  const state = this.deps.transactionCoordinator.createState();
292
320
  try {
293
321
  const result = await this.invokeFunction(definition, args, {
322
+ executionId,
294
323
  mutationDepth: 0,
295
324
  changedTables: state.changedTables,
325
+ documentChanges: state.documentChanges,
296
326
  storageChanges: state.storageChanges,
297
327
  componentMetadata: definition.__syncoreComponent
298
328
  });
299
- await this.finalizeStatefulExecution(actionId, createEmptyExecutionResult(result, state), Date.now() - startedAt);
329
+ const completedAt = Date.now();
330
+ const execution = createEmptyExecutionResult(result, state);
331
+ const impact = this.collectStatefulExecutionImpact(execution);
300
332
  this.deps.devtools.emit({
301
333
  type: "action.completed",
302
334
  runtimeId: this.deps.runtimeId,
303
335
  actionId,
304
336
  functionName: reference.name,
337
+ executionId,
338
+ ...meta.parentExecutionId ? { parentExecutionId: meta.parentExecutionId } : {},
305
339
  ...definition.__syncoreComponent ? {
306
340
  componentPath: definition.__syncoreComponent.componentPath,
307
341
  componentName: definition.__syncoreComponent.componentName
308
342
  } : {},
309
- durationMs: Date.now() - startedAt,
310
- timestamp: Date.now(),
343
+ argsPreview: createDevtoolsPreview(args),
344
+ resultPreview: createDevtoolsPreview(result),
345
+ writeScopes: [...impact.changedScopes],
346
+ changedScopes: [...impact.changedScopes],
347
+ changedDocumentsPreview: state.documentChanges,
348
+ invalidatedQueryIds: impact.invalidatedQueryIds,
349
+ durationMs: completedAt - startedAt,
350
+ timestamp: completedAt,
311
351
  ...meta.origin ? { origin: meta.origin } : {}
312
352
  });
353
+ await this.publishStatefulExecutionEffects(executionId, execution, impact.changedScopes);
313
354
  return result;
314
355
  } catch (error) {
356
+ const completedAt = Date.now();
315
357
  this.deps.devtools.emit({
316
358
  type: "action.completed",
317
359
  runtimeId: this.deps.runtimeId,
318
360
  actionId,
319
361
  functionName: reference.name,
362
+ executionId,
363
+ ...meta.parentExecutionId ? { parentExecutionId: meta.parentExecutionId } : {},
320
364
  ...definition.__syncoreComponent ? {
321
365
  componentPath: definition.__syncoreComponent.componentPath,
322
366
  componentName: definition.__syncoreComponent.componentName
323
367
  } : {},
324
- durationMs: Date.now() - startedAt,
325
- timestamp: Date.now(),
368
+ argsPreview: createDevtoolsPreview(args),
369
+ durationMs: completedAt - startedAt,
370
+ timestamp: completedAt,
326
371
  ...meta.origin ? { origin: meta.origin } : {},
327
372
  error: error instanceof Error ? error.message : String(error)
328
373
  });
@@ -331,28 +376,47 @@ var ExecutionEngine = class {
331
376
  }
332
377
  async runDevtoolsMutation(callback, meta = {}) {
333
378
  const mutationId = generateId();
379
+ const executionId = meta.executionId ?? mutationId;
334
380
  const startedAt = Date.now();
335
381
  const execution = await this.deps.transactionCoordinator.runInTransaction(async (transactionState) => callback({ db: this.createDatabaseWriter({
382
+ executionId,
336
383
  mutationDepth: 1,
337
384
  changedTables: transactionState.changedTables,
385
+ documentChanges: transactionState.documentChanges,
338
386
  storageChanges: transactionState.storageChanges
339
387
  }) }));
340
- await this.finalizeStatefulExecution(mutationId, execution, Date.now() - startedAt);
388
+ const completedAt = Date.now();
389
+ const impact = this.collectStatefulExecutionImpact(execution);
341
390
  this.deps.devtools.emit({
342
391
  type: "mutation.committed",
343
392
  runtimeId: this.deps.runtimeId,
344
393
  mutationId,
345
394
  functionName: "__devtools__/mutation",
395
+ executionId,
396
+ ...meta.parentExecutionId ? { parentExecutionId: meta.parentExecutionId } : {},
346
397
  changedTables: [...execution.changedTables],
347
- durationMs: Date.now() - startedAt,
348
- timestamp: Date.now(),
398
+ argsPreview: createDevtoolsPreview({ source: "dashboard" }),
399
+ resultPreview: createDevtoolsPreview(execution.result),
400
+ writeScopes: [...impact.changedScopes],
401
+ changedScopes: [...impact.changedScopes],
402
+ changedDocumentsPreview: execution.documentChanges,
403
+ invalidatedQueryIds: impact.invalidatedQueryIds,
404
+ durationMs: completedAt - startedAt,
405
+ timestamp: completedAt,
349
406
  ...meta.origin ? { origin: meta.origin } : {}
350
407
  });
408
+ await this.publishStatefulExecutionEffects(executionId, execution, impact.changedScopes);
351
409
  return execution.result;
352
410
  }
353
- async finalizeStatefulExecution(executionId, execution, durationMs) {
411
+ collectStatefulExecutionImpact(execution) {
354
412
  const changedScopes = collectChangedScopes(execution.changedTables, execution.storageChanges);
355
- if (changedScopes.size > 0) await this.deps.reactivity.refreshQueriesForScopes(changedScopes, `Execution ${executionId} touched ${[...changedScopes].join(", ")}`);
413
+ return {
414
+ changedScopes,
415
+ invalidatedQueryIds: changedScopes.size > 0 ? this.deps.reactivity.getInvalidatedQueryIdsForScopes(changedScopes) : []
416
+ };
417
+ }
418
+ async publishStatefulExecutionEffects(executionId, execution, changedScopes) {
419
+ if (changedScopes.size > 0) await this.deps.reactivity.refreshQueriesForScopes(changedScopes, `Execution ${executionId} touched ${[...changedScopes].join(", ")}`, { executionId });
356
420
  if (execution.changedTables.size > 0) await this.deps.reactivity.publishExternalChange({
357
421
  scope: "database",
358
422
  reason: "commit",
@@ -368,8 +432,10 @@ var ExecutionEngine = class {
368
432
  }, "query");
369
433
  const dependencyCollector = /* @__PURE__ */ new Set();
370
434
  await this.invokeFunction(definition, args, {
435
+ executionId: generateId(),
371
436
  mutationDepth: 0,
372
437
  changedTables: /* @__PURE__ */ new Set(),
438
+ documentChanges: [],
373
439
  storageChanges: [],
374
440
  dependencyCollector,
375
441
  componentMetadata: definition.__syncoreComponent
@@ -444,19 +510,21 @@ var ExecutionEngine = class {
444
510
  capabilities: callerMetadata.grantedCapabilities
445
511
  } } : {},
446
512
  scheduler,
447
- runQuery: (reference, ...args) => this.runQuery(this.resolveReferenceForCaller(reference, "query", callerMetadata), normalizeOptionalArgs(args)),
513
+ runQuery: (reference, ...args) => this.runQuery(this.resolveReferenceForCaller(reference, "query", callerMetadata), normalizeOptionalArgs(args), state.executionId ? { parentExecutionId: state.executionId } : {}),
448
514
  runMutation: (reference, ...args) => {
449
515
  const resolvedReference = this.resolveReferenceForCaller(reference, "mutation", callerMetadata);
450
516
  const normalizedArgs = normalizeOptionalArgs(args);
451
517
  if (kind === "mutation") return this.deps.driver.withSavepoint(`sp_${generateId().replace(/-/g, "_")}`, () => this.invokeFunction(this.resolveFunction(resolvedReference, "mutation", callerMetadata), normalizedArgs, {
518
+ ...state.executionId ? { executionId: state.executionId } : {},
452
519
  mutationDepth: state.mutationDepth + 1,
453
520
  changedTables: state.changedTables,
521
+ documentChanges: state.documentChanges,
454
522
  storageChanges: state.storageChanges,
455
523
  componentMetadata: callerMetadata
456
524
  }));
457
- return this.runMutation(resolvedReference, normalizedArgs);
525
+ return this.runMutation(resolvedReference, normalizedArgs, state.executionId ? { parentExecutionId: state.executionId } : {});
458
526
  },
459
- runAction: (reference, ...args) => this.runAction(this.resolveReferenceForCaller(reference, "action", callerMetadata), normalizeOptionalArgs(args))
527
+ runAction: (reference, ...args) => this.runAction(this.resolveReferenceForCaller(reference, "action", callerMetadata), normalizeOptionalArgs(args), state.executionId ? { parentExecutionId: state.executionId } : {})
460
528
  };
461
529
  }
462
530
  createDatabaseReader(state) {
@@ -496,6 +564,17 @@ var ExecutionEngine = class {
496
564
  _json: json
497
565
  });
498
566
  state.changedTables.add(scopedTableName);
567
+ state.documentChanges.push({
568
+ table: scopedTableName,
569
+ id,
570
+ operation: "insert",
571
+ fields: Object.keys(validated),
572
+ afterPreview: createDevtoolsPreview({
573
+ _id: id,
574
+ _creationTime: creationTime,
575
+ ...validated
576
+ })
577
+ });
499
578
  return id;
500
579
  },
501
580
  patch: async (tableName, id, value) => {
@@ -512,21 +591,45 @@ var ExecutionEngine = class {
512
591
  const row = await this.deps.driver.get(`SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
513
592
  if (row) await this.deps.schema.syncSearchIndexes(scopedTableName, row);
514
593
  state.changedTables.add(scopedTableName);
594
+ state.documentChanges.push({
595
+ table: scopedTableName,
596
+ id,
597
+ operation: "patch",
598
+ fields: Object.keys(value),
599
+ beforePreview: createDevtoolsPreview(current),
600
+ afterPreview: createDevtoolsPreview(row ? this.deps.schema.deserializeDocument(scopedTableName, row) : validated)
601
+ });
515
602
  },
516
603
  replace: async (tableName, id, value) => {
517
604
  const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
518
605
  const validated = this.deps.schema.validateDocument(scopedTableName, value);
606
+ const current = await reader.get(tableName, id);
519
607
  await this.deps.driver.run(`UPDATE ${quoteIdentifier(scopedTableName)} SET _json = ? WHERE _id = ?`, [stableStringify(validated), id]);
520
608
  const row = await this.deps.driver.get(`SELECT _id, _creationTime, _json FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
521
609
  if (!row) throw new Error(`Document "${id}" does not exist in "${scopedTableName}".`);
522
610
  await this.deps.schema.syncSearchIndexes(scopedTableName, row);
523
611
  state.changedTables.add(scopedTableName);
612
+ state.documentChanges.push({
613
+ table: scopedTableName,
614
+ id,
615
+ operation: "replace",
616
+ fields: Object.keys(validated),
617
+ ...current ? { beforePreview: createDevtoolsPreview(current) } : {},
618
+ afterPreview: createDevtoolsPreview(this.deps.schema.deserializeDocument(scopedTableName, row))
619
+ });
524
620
  },
525
621
  delete: async (tableName, id) => {
526
622
  const scopedTableName = this.resolveTableName(tableName, state.componentMetadata);
623
+ const current = await reader.get(tableName, id);
527
624
  await this.deps.driver.run(`DELETE FROM ${quoteIdentifier(scopedTableName)} WHERE _id = ?`, [id]);
528
625
  await this.deps.schema.removeSearchIndexes(scopedTableName, id);
529
626
  state.changedTables.add(scopedTableName);
627
+ state.documentChanges.push({
628
+ table: scopedTableName,
629
+ id,
630
+ operation: "delete",
631
+ ...current ? { beforePreview: createDevtoolsPreview(current) } : {}
632
+ });
530
633
  }
531
634
  };
532
635
  }