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":"devtools-auth.mjs","names":[],"sources":["../src/devtools-auth.ts"],"sourcesContent":["import { randomBytes, timingSafeEqual } from \"node:crypto\";\n\nconst TOKEN_ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nexport function sanitizeDevtoolsToken(value: string | undefined): string | null {\n if (!value) {\n return null;\n }\n const sanitized = value.replace(/[^A-Za-z0-9]/g, \"\");\n return sanitized.length > 0 ? sanitized : null;\n}\n\nexport function generateDevtoolsToken(length = 20): string {\n let token = \"\";\n while (token.length < length) {\n const bytes = randomBytes(length);\n for (const byte of bytes) {\n if (byte >= 248) {\n continue;\n }\n token += TOKEN_ALPHABET[byte % TOKEN_ALPHABET.length];\n if (token.length === length) {\n break;\n }\n }\n }\n return token;\n}\n\nexport function readDevtoolsTokenFromUrl(requestUrl: string | undefined): string | null {\n if (!requestUrl) {\n return null;\n }\n try {\n const url = new URL(requestUrl, \"ws://localhost\");\n return url.searchParams.get(\"token\") ?? url.searchParams.get(\"hubToken\");\n } catch {\n return null;\n }\n}\n\nexport function isAllowedDashboardOrigin(\n originHeader: string | undefined,\n dashboardPort: number\n): boolean {\n if (!originHeader) {\n return false;\n }\n try {\n const origin = new URL(originHeader);\n if (!isLoopbackHostname(origin.hostname)) {\n return false;\n }\n const expectedPort = String(dashboardPort);\n const originPort =\n origin.port ||\n (origin.protocol === \"https:\" ? \"443\" : origin.protocol === \"http:\" ? \"80\" : \"\");\n return originPort === expectedPort;\n } catch {\n return false;\n }\n}\n\nexport function isAuthorizedDashboardRequest(input: {\n requestUrl: string | undefined;\n originHeader: string | undefined;\n dashboardPort: number;\n expectedToken: string;\n}): boolean {\n if (!isAllowedDashboardOrigin(input.originHeader, input.dashboardPort)) {\n return false;\n }\n const providedToken = readDevtoolsTokenFromUrl(input.requestUrl);\n if (!providedToken) {\n return false;\n }\n return tokensMatch(providedToken, input.expectedToken);\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return (\n normalized === \"localhost\" ||\n normalized === \"127.0.0.1\" ||\n normalized === \"::1\" ||\n normalized === \"[::1]\"\n );\n}\n\nfunction tokensMatch(left: string, right: string): boolean {\n const leftBuffer = Buffer.from(left, \"utf8\");\n const rightBuffer = Buffer.from(right, \"utf8\");\n if (leftBuffer.length !== rightBuffer.length) {\n return false;\n }\n return timingSafeEqual(leftBuffer, rightBuffer);\n}\n"],"mappings":";;AAEA,MAAM,iBAAiB;AAEvB,SAAgB,sBAAsB,OAA0C;AAC9E,KAAI,CAAC,MACH,QAAO;CAET,MAAM,YAAY,MAAM,QAAQ,iBAAiB,GAAG;AACpD,QAAO,UAAU,SAAS,IAAI,YAAY;;AAG5C,SAAgB,sBAAsB,SAAS,IAAY;CACzD,IAAI,QAAQ;AACZ,QAAO,MAAM,SAAS,QAAQ;EAC5B,MAAM,QAAQ,YAAY,OAAO;AACjC,OAAK,MAAM,QAAQ,OAAO;AACxB,OAAI,QAAQ,IACV;AAEF,YAAS,eAAe,OAAO;AAC/B,OAAI,MAAM,WAAW,OACnB;;;AAIN,QAAO;;AAGT,SAAgB,yBAAyB,YAA+C;AACtF,KAAI,CAAC,WACH,QAAO;AAET,KAAI;EACF,MAAM,MAAM,IAAI,IAAI,YAAY,iBAAiB;AACjD,SAAO,IAAI,aAAa,IAAI,QAAQ,IAAI,IAAI,aAAa,IAAI,WAAW;SAClE;AACN,SAAO;;;AAIX,SAAgB,yBACd,cACA,eACS;AACT,KAAI,CAAC,aACH,QAAO;AAET,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,aAAa;AACpC,MAAI,CAAC,mBAAmB,OAAO,SAAS,CACtC,QAAO;EAET,MAAM,eAAe,OAAO,cAAc;AAI1C,UAFE,OAAO,SACN,OAAO,aAAa,WAAW,QAAQ,OAAO,aAAa,UAAU,OAAO,SACzD;SAChB;AACN,SAAO;;;AAIX,SAAgB,6BAA6B,OAKjC;AACV,KAAI,CAAC,yBAAyB,MAAM,cAAc,MAAM,cAAc,CACpE,QAAO;CAET,MAAM,gBAAgB,yBAAyB,MAAM,WAAW;AAChE,KAAI,CAAC,cACH,QAAO;AAET,QAAO,YAAY,eAAe,MAAM,cAAc;;AAGxD,SAAS,mBAAmB,UAA2B;CACrD,MAAM,aAAa,SAAS,aAAa;AACzC,QACE,eAAe,eACf,eAAe,eACf,eAAe,SACf,eAAe;;AAInB,SAAS,YAAY,MAAc,OAAwB;CACzD,MAAM,aAAa,OAAO,KAAK,MAAM,OAAO;CAC5C,MAAM,cAAc,OAAO,KAAK,OAAO,OAAO;AAC9C,KAAI,WAAW,WAAW,YAAY,OACpC,QAAO;AAET,QAAO,gBAAgB,YAAY,YAAY"}
1
+ {"version":3,"file":"devtools-auth.mjs","names":[],"sources":["../src/devtools-auth.ts"],"sourcesContent":["import { randomBytes, timingSafeEqual } from \"node:crypto\";\n\nconst TOKEN_ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nexport function sanitizeDevtoolsToken(value: string | undefined): string | null {\n if (!value) {\n return null;\n }\n const sanitized = value.replace(/[^A-Za-z0-9]/g, \"\");\n return sanitized.length > 0 ? sanitized : null;\n}\n\nexport function generateDevtoolsToken(length = 20): string {\n let token = \"\";\n while (token.length < length) {\n const bytes = randomBytes(length);\n for (const byte of bytes) {\n if (byte >= 248) {\n continue;\n }\n token += TOKEN_ALPHABET[byte % TOKEN_ALPHABET.length];\n if (token.length === length) {\n break;\n }\n }\n }\n return token;\n}\n\nexport function readDevtoolsTokenFromUrl(requestUrl: string | undefined): string | null {\n if (!requestUrl) {\n return null;\n }\n try {\n const url = new URL(requestUrl, \"ws://localhost\");\n return url.searchParams.get(\"token\") ?? url.searchParams.get(\"hubToken\");\n } catch {\n return null;\n }\n}\n\nexport function isAllowedDashboardOrigin(\n originHeader: string | undefined,\n dashboardPort: number\n): boolean {\n if (!originHeader) {\n return false;\n }\n try {\n const origin = new URL(originHeader);\n if (!isLoopbackHostname(origin.hostname)) {\n return false;\n }\n const expectedPort = String(dashboardPort);\n const originPort =\n origin.port ||\n (origin.protocol === \"https:\" ? \"443\" : origin.protocol === \"http:\" ? \"80\" : \"\");\n return originPort === expectedPort;\n } catch {\n return false;\n }\n}\n\nexport function isAuthorizedDashboardRequest(input: {\n requestUrl: string | undefined;\n originHeader: string | undefined;\n dashboardPort: number;\n expectedToken: string;\n}): boolean {\n if (!isAllowedDashboardOrigin(input.originHeader, input.dashboardPort)) {\n return false;\n }\n const providedToken = readDevtoolsTokenFromUrl(input.requestUrl);\n if (!providedToken) {\n return false;\n }\n return tokensMatch(providedToken, input.expectedToken);\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return (\n normalized === \"localhost\" ||\n normalized === \"127.0.0.1\" ||\n normalized === \"::1\" ||\n normalized === \"[::1]\"\n );\n}\n\nfunction tokensMatch(left: string, right: string): boolean {\n const leftBuffer = Buffer.from(left, \"utf8\");\n const rightBuffer = Buffer.from(right, \"utf8\");\n if (leftBuffer.length !== rightBuffer.length) {\n return false;\n }\n return timingSafeEqual(leftBuffer, rightBuffer);\n}\n"],"mappings":";;AAEA,MAAM,iBAAiB;AAEvB,SAAgB,sBAAsB,OAA0C;CAC9E,IAAI,CAAC,OACH,OAAO;CAET,MAAM,YAAY,MAAM,QAAQ,iBAAiB,EAAE;CACnD,OAAO,UAAU,SAAS,IAAI,YAAY;AAC5C;AAEA,SAAgB,sBAAsB,SAAS,IAAY;CACzD,IAAI,QAAQ;CACZ,OAAO,MAAM,SAAS,QAAQ;EAC5B,MAAM,QAAQ,YAAY,MAAM;EAChC,KAAK,MAAM,QAAQ,OAAO;GACxB,IAAI,QAAQ,KACV;GAEF,SAAS,eAAe,OAAO;GAC/B,IAAI,MAAM,WAAW,QACnB;EAEJ;CACF;CACA,OAAO;AACT;AAEA,SAAgB,yBAAyB,YAA+C;CACtF,IAAI,CAAC,YACH,OAAO;CAET,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,YAAY,gBAAgB;EAChD,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK,IAAI,aAAa,IAAI,UAAU;CACzE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,yBACd,cACA,eACS;CACT,IAAI,CAAC,cACH,OAAO;CAET,IAAI;EACF,MAAM,SAAS,IAAI,IAAI,YAAY;EACnC,IAAI,CAAC,mBAAmB,OAAO,QAAQ,GACrC,OAAO;EAET,MAAM,eAAe,OAAO,aAAa;EAIzC,QAFE,OAAO,SACN,OAAO,aAAa,WAAW,QAAQ,OAAO,aAAa,UAAU,OAAO,SACzD;CACxB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,6BAA6B,OAKjC;CACV,IAAI,CAAC,yBAAyB,MAAM,cAAc,MAAM,aAAa,GACnE,OAAO;CAET,MAAM,gBAAgB,yBAAyB,MAAM,UAAU;CAC/D,IAAI,CAAC,eACH,OAAO;CAET,OAAO,YAAY,eAAe,MAAM,aAAa;AACvD;AAEA,SAAS,mBAAmB,UAA2B;CACrD,MAAM,aAAa,SAAS,YAAY;CACxC,OACE,eAAe,eACf,eAAe,eACf,eAAe,SACf,eAAe;AAEnB;AAEA,SAAS,YAAY,MAAc,OAAwB;CACzD,MAAM,aAAa,OAAO,KAAK,MAAM,MAAM;CAC3C,MAAM,cAAc,OAAO,KAAK,OAAO,MAAM;CAC7C,IAAI,WAAW,WAAW,YAAY,QACpC,OAAO;CAET,OAAO,gBAAgB,YAAY,WAAW;AAChD"}
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.mts","names":[],"sources":["../../src/runtime/components.ts"],"mappings":"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"}
1
+ {"version":3,"file":"components.d.mts","names":[],"sources":["../../src/runtime/components.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","names":[],"sources":["../../src/runtime/components.ts"],"sourcesContent":["import {\n SyncoreSchema,\n TableDefinition,\n defineSchema,\n type AnyTableDefinition,\n type Validator\n} from \"@syncore/schema\";\nimport type { SyncoreDevtoolsEvent } from \"@syncore/devtools-protocol\";\nimport {\n type FunctionReference,\n type FunctionReferenceFor,\n type SyncoreFunctionDefinition,\n type SyncoreFunctionKind\n} from \"./functions.js\";\nimport type {\n JsonObject,\n RegisteredSyncoreFunction,\n SyncoreDataModel,\n SyncoreFunctionRegistry\n} from \"./runtime.js\";\n\nexport type ComponentPath = string;\n\nexport type SyncoreCoreCapability =\n | \"storage\"\n | \"scheduler\"\n | \"devtools\"\n | \"ownTables\"\n | \"publicExports\"\n | \"internalActions\";\n\nexport type SyncoreHostServiceName =\n | \"http\"\n | \"notifications\"\n | \"secureStore\"\n | \"filesystem\"\n | \"backgroundTasks\"\n | \"crypto\";\n\nexport type SyncoreRequestedCapability =\n | SyncoreCoreCapability\n | `host:${SyncoreHostServiceName}`;\n\nexport type AnySyncoreFunctionDefinition = SyncoreFunctionDefinition<\n SyncoreFunctionKind,\n any,\n any,\n unknown\n>;\n\nexport type SyncoreFunctionTree = {\n readonly [key: string]:\n | AnySyncoreFunctionDefinition\n | SyncoreFunctionTree\n | undefined;\n};\n\nexport interface SyncoreComponentHookContext {\n runtimeId: string;\n platform: string;\n componentPath: ComponentPath;\n componentName: string;\n version: string;\n config: unknown;\n capabilities: readonly SyncoreRequestedCapability[];\n emitDevtools(event: SyncoreDevtoolsEvent): void;\n}\n\nexport interface SyncoreComponent<\n TConfig = unknown,\n TSchema extends SyncoreDataModel | undefined =\n | SyncoreDataModel\n | undefined,\n TPublic extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined,\n TInternal extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined\n> {\n readonly kind: \"syncore.component\";\n readonly name: string;\n readonly version: string;\n readonly config?: Validator<TConfig>;\n readonly requestedCapabilities?: readonly SyncoreRequestedCapability[];\n readonly schema?: TSchema;\n readonly public?: TPublic;\n readonly internal?: TInternal;\n readonly dependencies?: readonly string[];\n onStart?(context: SyncoreComponentHookContext): Promise<void> | void;\n onStop?(context: SyncoreComponentHookContext): Promise<void> | void;\n}\n\nexport interface SyncoreComponentInstall<\n TComponent extends SyncoreComponent = SyncoreComponent,\n TChildren extends SyncoreComponentsManifest = SyncoreComponentsManifest\n> {\n readonly kind: \"syncore.component.install\";\n readonly component: TComponent;\n readonly source: string;\n readonly config?: TComponent extends SyncoreComponent<infer TConfig, any, any, any>\n ? TConfig\n : unknown;\n readonly capabilities?: readonly SyncoreRequestedCapability[];\n readonly bindings?: Record<string, string>;\n readonly children?: TChildren;\n}\n\nexport type SyncoreComponentsManifest = Record<string, SyncoreComponentInstall>;\n\nexport interface SyncoreComponentFunctionMetadata {\n componentPath: ComponentPath;\n componentName: string;\n version: string;\n visibility: \"public\" | \"internal\";\n localName: string;\n localTables: Record<string, string>;\n grantedCapabilities: readonly SyncoreRequestedCapability[];\n bindings: Record<string, string>;\n}\n\nexport interface ResolvedSyncoreComponent {\n alias: string;\n path: ComponentPath;\n source: string;\n name: string;\n version: string;\n config: unknown;\n grantedCapabilities: readonly SyncoreRequestedCapability[];\n requestedCapabilities: readonly SyncoreRequestedCapability[];\n bindings: Record<string, string>;\n schema: SyncoreDataModel | undefined;\n public: SyncoreFunctionTree | undefined;\n internal: SyncoreFunctionTree | undefined;\n publicEntries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }>;\n internalEntries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }>;\n localTables: Record<string, string>;\n onStart: SyncoreComponent[\"onStart\"] | undefined;\n onStop: SyncoreComponent[\"onStop\"] | undefined;\n children: ResolvedSyncoreComponent[];\n}\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\ntype PublicFunctionTreeOf<TComponent> = TComponent extends SyncoreComponent<\n any,\n any,\n infer TPublic,\n any\n>\n ? NonNullable<TPublic>\n : never;\n\nexport type FunctionReferencesForTree<TTree extends SyncoreFunctionTree> = Simplify<{\n [TKey in keyof TTree]: TTree[TKey] extends AnySyncoreFunctionDefinition\n ? FunctionReferenceFor<TTree[TKey]>\n : Record<string, unknown>;\n}>;\n\nexport type InstalledComponentApi<\n TInstall extends SyncoreComponentInstall\n> = Simplify<\n FunctionReferencesForTree<PublicFunctionTreeOf<TInstall[\"component\"]>> &\n Record<string, unknown>\n>;\n\nexport type InstalledComponentsApi<\n TManifest extends SyncoreComponentsManifest\n> = Simplify<{\n [TAlias in keyof TManifest]: InstalledComponentApi<TManifest[TAlias]>;\n}>;\n\ntype TablesOfSchema<TSchema extends SyncoreDataModel> = TSchema[\"tables\"];\n\nexport function defineComponent<\n TConfig = unknown,\n TSchema extends SyncoreDataModel | undefined =\n | SyncoreDataModel\n | undefined,\n TPublic extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined,\n TInternal extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined\n>(\n component: Omit<\n SyncoreComponent<TConfig, TSchema, TPublic, TInternal>,\n \"kind\"\n >\n): SyncoreComponent<TConfig, TSchema, TPublic, TInternal> {\n return {\n kind: \"syncore.component\",\n ...component\n };\n}\n\nexport function installComponent<\n TComponent extends SyncoreComponent,\n TChildren extends SyncoreComponentsManifest = {}\n>(install: {\n component: TComponent;\n source: string;\n config?: TComponent extends SyncoreComponent<infer TConfig, any, any, any>\n ? TConfig\n : unknown;\n capabilities?: readonly SyncoreRequestedCapability[];\n bindings?: Record<string, string>;\n children?: TChildren;\n}): SyncoreComponentInstall<TComponent, TChildren> {\n return {\n kind: \"syncore.component.install\",\n ...install\n };\n}\n\nexport function defineComponents<TManifest extends SyncoreComponentsManifest>(\n components: TManifest\n): TManifest {\n return components;\n}\n\nexport function createBindingFunctionReference<\n TKind extends SyncoreFunctionKind,\n TArgs = JsonObject,\n TResult = unknown\n>(\n kind: TKind,\n bindingName: string,\n functionName: string\n): FunctionReference<TKind, TArgs, TResult> {\n return {\n kind,\n name: `binding:${bindingName}/${functionName}`\n };\n}\n\nexport function composeProjectSchema<\n TRootSchema extends SyncoreDataModel\n>(\n rootSchema: TRootSchema,\n manifest?: SyncoreComponentsManifest\n): SyncoreSchema<TablesOfSchema<TRootSchema> & Record<string, AnyTableDefinition>> {\n const tables: Record<string, AnyTableDefinition> = {\n ...rootSchema.tables\n };\n\n for (const component of resolveComponentsManifest(manifest)) {\n for (const [physicalTableName, tableDefinition] of composeComponentTables(\n component\n )) {\n if (tables[physicalTableName]) {\n throw new Error(\n `Component table collision detected for ${JSON.stringify(physicalTableName)}.`\n );\n }\n tables[physicalTableName] = tableDefinition;\n }\n }\n\n return defineSchema(tables) as unknown as SyncoreSchema<\n TablesOfSchema<TRootSchema> & Record<string, AnyTableDefinition>\n >;\n}\n\nexport function composeProjectFunctionRegistry(\n rootFunctions: SyncoreFunctionRegistry,\n manifest?: SyncoreComponentsManifest\n): SyncoreFunctionRegistry {\n const registry: Record<string, RegisteredSyncoreFunction> = {};\n for (const [name, definition] of Object.entries(rootFunctions)) {\n if (definition) {\n registry[name] = definition;\n }\n }\n\n for (const component of resolveComponentsManifest(manifest)) {\n appendResolvedComponentFunctions(registry, component);\n }\n\n return registry;\n}\n\nexport function createInstalledComponentsApi<\n TManifest extends SyncoreComponentsManifest\n>(manifest: TManifest): InstalledComponentsApi<TManifest> {\n return createInstalledComponentsApiObject(resolveComponentsManifest(manifest)) as InstalledComponentsApi<TManifest>;\n}\n\nexport function resolveComponentsManifest(\n manifest?: SyncoreComponentsManifest\n): ResolvedSyncoreComponent[] {\n if (!manifest) {\n return [];\n }\n\n return Object.entries(manifest)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([alias, install]) => resolveInstalledComponent(alias, install, []));\n}\n\nexport function toCanonicalComponentFunctionName(\n componentPath: ComponentPath,\n visibility: \"public\" | \"internal\",\n localName: string\n): string {\n return [\"components\", componentPath, visibility, localName]\n .filter(Boolean)\n .join(\"/\");\n}\n\nexport function createComponentPhysicalTableName(\n componentPath: ComponentPath,\n tableName: string\n): string {\n const pathPart = sanitizeComponentPath(componentPath);\n return `__syncore_component__${pathPart}__${tableName}`;\n}\n\nfunction resolveInstalledComponent(\n alias: string,\n install: SyncoreComponentInstall,\n parentPath: string[]\n): ResolvedSyncoreComponent {\n const pathSegments = [...parentPath, alias];\n const componentPath = pathSegments.join(\"/\");\n const component = install.component;\n const requestedCapabilities = [\n ...(component.requestedCapabilities ?? [])\n ];\n const localTables = createLocalTableMap(componentPath, component.schema);\n const defaultCapabilities = new Set<SyncoreRequestedCapability>(\n component.schema ? [\"ownTables\"] : []\n );\n if (component.public) {\n defaultCapabilities.add(\"publicExports\");\n }\n if (component.internal) {\n defaultCapabilities.add(\"internalActions\");\n }\n const grantedCapabilities = Array.from(\n new Set([\n ...defaultCapabilities,\n ...(install.capabilities ?? requestedCapabilities)\n ])\n );\n\n for (const capability of requestedCapabilities) {\n if (!grantedCapabilities.includes(capability)) {\n throw new Error(\n `Component ${JSON.stringify(component.name)} at ${JSON.stringify(componentPath)} requested capability ${JSON.stringify(capability)} but it was not granted.`\n );\n }\n }\n\n if (component.config) {\n component.config.parse(install.config);\n }\n\n const bindings = { ...(install.bindings ?? {}) };\n for (const dependency of component.dependencies ?? []) {\n if (!bindings[dependency]) {\n throw new Error(\n `Component ${JSON.stringify(component.name)} at ${JSON.stringify(componentPath)} requires binding ${JSON.stringify(dependency)}.`\n );\n }\n }\n\n const children = Object.entries(install.children ?? {})\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([childAlias, childInstall]) =>\n resolveInstalledComponent(childAlias, childInstall, pathSegments)\n );\n\n return {\n alias,\n path: componentPath,\n source: install.source,\n name: component.name,\n version: component.version,\n config: install.config,\n grantedCapabilities,\n requestedCapabilities,\n bindings,\n schema: component.schema,\n public: component.public,\n internal: component.internal,\n publicEntries: flattenComponentFunctionTree(\n component.public,\n componentPath,\n component.name,\n component.version,\n \"public\",\n localTables,\n grantedCapabilities,\n bindings\n ),\n internalEntries: flattenComponentFunctionTree(\n component.internal,\n componentPath,\n component.name,\n component.version,\n \"internal\",\n localTables,\n grantedCapabilities,\n bindings\n ),\n localTables,\n onStart: component.onStart,\n onStop: component.onStop,\n children\n };\n}\n\nfunction createLocalTableMap(\n componentPath: string,\n schema?: SyncoreDataModel\n): Record<string, string> {\n if (!schema) {\n return {};\n }\n return Object.fromEntries(\n schema.tableNames().map((tableName) => [\n tableName,\n createComponentPhysicalTableName(componentPath, tableName)\n ])\n );\n}\n\nfunction composeComponentTables(\n component: ResolvedSyncoreComponent\n): Array<[string, AnyTableDefinition]> {\n const entries: Array<[string, AnyTableDefinition]> = [];\n if (component.schema) {\n for (const localTableName of component.schema.tableNames()) {\n const original = component.schema.getTable(localTableName);\n const cloned = new TableDefinition(original.validator, {\n ...original.options,\n tableName: localTableName,\n componentPath: component.path,\n componentName: component.name\n });\n for (const index of original.indexes) {\n if (index.fields.length > 0) {\n cloned.index(index.name, [...index.fields] as [string, ...string[]]);\n }\n }\n for (const index of original.searchIndexes) {\n cloned.searchIndex(index.name, {\n searchField: index.searchField,\n filterFields: [...index.filterFields]\n });\n }\n entries.push([component.localTables[localTableName]!, cloned]);\n }\n }\n for (const child of component.children) {\n entries.push(...composeComponentTables(child));\n }\n return entries;\n}\n\nfunction appendResolvedComponentFunctions(\n registry: Record<string, RegisteredSyncoreFunction>,\n component: ResolvedSyncoreComponent\n): void {\n for (const entry of component.publicEntries) {\n registry[entry.canonicalName] = entry.definition;\n }\n for (const entry of component.internalEntries) {\n registry[entry.canonicalName] = entry.definition;\n }\n for (const child of component.children) {\n appendResolvedComponentFunctions(registry, child);\n }\n}\n\nfunction flattenComponentFunctionTree(\n tree: SyncoreFunctionTree | undefined,\n componentPath: string,\n componentName: string,\n version: string,\n visibility: \"public\" | \"internal\",\n localTables: Record<string, string>,\n grantedCapabilities: readonly SyncoreRequestedCapability[],\n bindings: Record<string, string>,\n prefix: string[] = []\n): Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n}> {\n if (!tree) {\n return [];\n }\n\n const entries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }> = [];\n\n for (const [key, value] of Object.entries(tree).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n if (!value) {\n continue;\n }\n if (isFunctionDefinition(value)) {\n const localName = [...prefix, key].join(\"/\");\n entries.push({\n localName,\n canonicalName: toCanonicalComponentFunctionName(\n componentPath,\n visibility,\n localName\n ),\n definition: decorateComponentFunctionDefinition(value, {\n componentPath,\n componentName,\n version,\n visibility,\n localName,\n localTables,\n grantedCapabilities,\n bindings\n })\n });\n continue;\n }\n entries.push(\n ...flattenComponentFunctionTree(\n value,\n componentPath,\n componentName,\n version,\n visibility,\n localTables,\n grantedCapabilities,\n bindings,\n [...prefix, key]\n )\n );\n }\n\n return entries;\n}\n\nfunction decorateComponentFunctionDefinition(\n definition: AnySyncoreFunctionDefinition,\n metadata: SyncoreComponentFunctionMetadata\n): RegisteredSyncoreFunction {\n return {\n ...definition,\n __syncoreComponent: metadata\n } as RegisteredSyncoreFunction;\n}\n\nfunction createInstalledComponentsApiObject(\n components: ResolvedSyncoreComponent[]\n): Record<string, unknown> {\n return Object.fromEntries(\n components.map((component) => [\n component.alias,\n createInstalledComponentApiNode(component)\n ])\n );\n}\n\nfunction createInstalledComponentApiNode(\n component: ResolvedSyncoreComponent\n): Record<string, unknown> {\n const node: Record<string, unknown> = {};\n for (const entry of component.publicEntries) {\n assignFunctionReference(\n node,\n entry.localName.split(\"/\"),\n {\n kind: entry.definition.kind,\n name: entry.canonicalName\n }\n );\n }\n for (const child of component.children) {\n node[child.alias] = createInstalledComponentApiNode(child);\n }\n return node;\n}\n\nfunction assignFunctionReference(\n node: Record<string, unknown>,\n pathParts: string[],\n reference: FunctionReference\n): void {\n const [head, ...tail] = pathParts;\n if (!head) {\n return;\n }\n if (tail.length === 0) {\n node[head] = reference;\n return;\n }\n const child =\n node[head] && typeof node[head] === \"object\"\n ? (node[head] as Record<string, unknown>)\n : {};\n node[head] = child;\n assignFunctionReference(child, tail, reference);\n}\n\nfunction isFunctionDefinition(value: unknown): value is AnySyncoreFunctionDefinition {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n \"kind\" in (value as Record<string, unknown>) &&\n \"argsValidator\" in (value as Record<string, unknown>) &&\n \"handler\" in (value as Record<string, unknown>)\n );\n}\n\nfunction sanitizeComponentPath(componentPath: string): string {\n return componentPath.replace(/[^a-zA-Z0-9_]+/g, \"_\");\n}\n"],"mappings":";;AAsLA,SAAgB,gBAYd,WAIwD;AACxD,QAAO;EACL,MAAM;EACN,GAAG;EACJ;;AAGH,SAAgB,iBAGd,SASiD;AACjD,QAAO;EACL,MAAM;EACN,GAAG;EACJ;;AAGH,SAAgB,iBACd,YACW;AACX,QAAO;;AAGT,SAAgB,+BAKd,MACA,aACA,cAC0C;AAC1C,QAAO;EACL;EACA,MAAM,WAAW,YAAY,GAAG;EACjC;;AAGH,SAAgB,qBAGd,YACA,UACiF;CACjF,MAAM,SAA6C,EACjD,GAAG,WAAW,QACf;AAED,MAAK,MAAM,aAAa,0BAA0B,SAAS,CACzD,MAAK,MAAM,CAAC,mBAAmB,oBAAoB,uBACjD,UACD,EAAE;AACD,MAAI,OAAO,mBACT,OAAM,IAAI,MACR,0CAA0C,KAAK,UAAU,kBAAkB,CAAC,GAC7E;AAEH,SAAO,qBAAqB;;AAIhC,QAAO,aAAa,OAAO;;AAK7B,SAAgB,+BACd,eACA,UACyB;CACzB,MAAM,WAAsD,EAAE;AAC9D,MAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,cAAc,CAC5D,KAAI,WACF,UAAS,QAAQ;AAIrB,MAAK,MAAM,aAAa,0BAA0B,SAAS,CACzD,kCAAiC,UAAU,UAAU;AAGvD,QAAO;;AAGT,SAAgB,6BAEd,UAAwD;AACxD,QAAO,mCAAmC,0BAA0B,SAAS,CAAC;;AAGhF,SAAgB,0BACd,UAC4B;AAC5B,KAAI,CAAC,SACH,QAAO,EAAE;AAGX,QAAO,OAAO,QAAQ,SAAS,CAC5B,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,MAAM,CAAC,CACpD,KAAK,CAAC,OAAO,aAAa,0BAA0B,OAAO,SAAS,EAAE,CAAC,CAAC;;AAG7E,SAAgB,iCACd,eACA,YACA,WACQ;AACR,QAAO;EAAC;EAAc;EAAe;EAAY;EAAU,CACxD,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,SAAgB,iCACd,eACA,WACQ;AAER,QAAO,wBADU,sBAAsB,cAAc,CACb,IAAI;;AAG9C,SAAS,0BACP,OACA,SACA,YAC0B;CAC1B,MAAM,eAAe,CAAC,GAAG,YAAY,MAAM;CAC3C,MAAM,gBAAgB,aAAa,KAAK,IAAI;CAC5C,MAAM,YAAY,QAAQ;CAC1B,MAAM,wBAAwB,CAC5B,GAAI,UAAU,yBAAyB,EAAE,CAC1C;CACD,MAAM,cAAc,oBAAoB,eAAe,UAAU,OAAO;CACxE,MAAM,sBAAsB,IAAI,IAC9B,UAAU,SAAS,CAAC,YAAY,GAAG,EAAE,CACtC;AACD,KAAI,UAAU,OACZ,qBAAoB,IAAI,gBAAgB;AAE1C,KAAI,UAAU,SACZ,qBAAoB,IAAI,kBAAkB;CAE5C,MAAM,sBAAsB,MAAM,KAChC,IAAI,IAAI,CACN,GAAG,qBACH,GAAI,QAAQ,gBAAgB,sBAC7B,CAAC,CACH;AAED,MAAK,MAAM,cAAc,sBACvB,KAAI,CAAC,oBAAoB,SAAS,WAAW,CAC3C,OAAM,IAAI,MACR,aAAa,KAAK,UAAU,UAAU,KAAK,CAAC,MAAM,KAAK,UAAU,cAAc,CAAC,wBAAwB,KAAK,UAAU,WAAW,CAAC,0BACpI;AAIL,KAAI,UAAU,OACZ,WAAU,OAAO,MAAM,QAAQ,OAAO;CAGxC,MAAM,WAAW,EAAE,GAAI,QAAQ,YAAY,EAAE,EAAG;AAChD,MAAK,MAAM,cAAc,UAAU,gBAAgB,EAAE,CACnD,KAAI,CAAC,SAAS,YACZ,OAAM,IAAI,MACR,aAAa,KAAK,UAAU,UAAU,KAAK,CAAC,MAAM,KAAK,UAAU,cAAc,CAAC,oBAAoB,KAAK,UAAU,WAAW,CAAC,GAChI;CAIL,MAAM,WAAW,OAAO,QAAQ,QAAQ,YAAY,EAAE,CAAC,CACpD,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,MAAM,CAAC,CACpD,KAAK,CAAC,YAAY,kBACjB,0BAA0B,YAAY,cAAc,aAAa,CAClE;AAEH,QAAO;EACL;EACA,MAAM;EACN,QAAQ,QAAQ;EAChB,MAAM,UAAU;EAChB,SAAS,UAAU;EACnB,QAAQ,QAAQ;EAChB;EACA;EACA;EACA,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,UAAU,UAAU;EACpB,eAAe,6BACb,UAAU,QACV,eACA,UAAU,MACV,UAAU,SACV,UACA,aACA,qBACA,SACD;EACD,iBAAiB,6BACf,UAAU,UACV,eACA,UAAU,MACV,UAAU,SACV,YACA,aACA,qBACA,SACD;EACD;EACA,SAAS,UAAU;EACnB,QAAQ,UAAU;EAClB;EACD;;AAGH,SAAS,oBACP,eACA,QACwB;AACxB,KAAI,CAAC,OACH,QAAO,EAAE;AAEX,QAAO,OAAO,YACZ,OAAO,YAAY,CAAC,KAAK,cAAc,CACrC,WACA,iCAAiC,eAAe,UAAU,CAC3D,CAAC,CACH;;AAGH,SAAS,uBACP,WACqC;CACrC,MAAM,UAA+C,EAAE;AACvD,KAAI,UAAU,OACZ,MAAK,MAAM,kBAAkB,UAAU,OAAO,YAAY,EAAE;EAC1D,MAAM,WAAW,UAAU,OAAO,SAAS,eAAe;EAC1D,MAAM,SAAS,IAAI,gBAAgB,SAAS,WAAW;GACrD,GAAG,SAAS;GACZ,WAAW;GACX,eAAe,UAAU;GACzB,eAAe,UAAU;GAC1B,CAAC;AACF,OAAK,MAAM,SAAS,SAAS,QAC3B,KAAI,MAAM,OAAO,SAAS,EACxB,QAAO,MAAM,MAAM,MAAM,CAAC,GAAG,MAAM,OAAO,CAA0B;AAGxE,OAAK,MAAM,SAAS,SAAS,cAC3B,QAAO,YAAY,MAAM,MAAM;GAC7B,aAAa,MAAM;GACnB,cAAc,CAAC,GAAG,MAAM,aAAa;GACtC,CAAC;AAEJ,UAAQ,KAAK,CAAC,UAAU,YAAY,iBAAkB,OAAO,CAAC;;AAGlE,MAAK,MAAM,SAAS,UAAU,SAC5B,SAAQ,KAAK,GAAG,uBAAuB,MAAM,CAAC;AAEhD,QAAO;;AAGT,SAAS,iCACP,UACA,WACM;AACN,MAAK,MAAM,SAAS,UAAU,cAC5B,UAAS,MAAM,iBAAiB,MAAM;AAExC,MAAK,MAAM,SAAS,UAAU,gBAC5B,UAAS,MAAM,iBAAiB,MAAM;AAExC,MAAK,MAAM,SAAS,UAAU,SAC5B,kCAAiC,UAAU,MAAM;;AAIrD,SAAS,6BACP,MACA,eACA,eACA,SACA,YACA,aACA,qBACA,UACA,SAAmB,EAAE,EAKpB;AACD,KAAI,CAAC,KACH,QAAO,EAAE;CAGX,MAAM,UAID,EAAE;AAEP,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,WAC7D,KAAK,cAAc,MAAM,CAC1B,EAAE;AACD,MAAI,CAAC,MACH;AAEF,MAAI,qBAAqB,MAAM,EAAE;GAC/B,MAAM,YAAY,CAAC,GAAG,QAAQ,IAAI,CAAC,KAAK,IAAI;AAC5C,WAAQ,KAAK;IACX;IACA,eAAe,iCACb,eACA,YACA,UACD;IACD,YAAY,oCAAoC,OAAO;KACrD;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACD,CAAC;IACH,CAAC;AACF;;AAEF,UAAQ,KACN,GAAG,6BACD,OACA,eACA,eACA,SACA,YACA,aACA,qBACA,UACA,CAAC,GAAG,QAAQ,IAAI,CACjB,CACF;;AAGH,QAAO;;AAGT,SAAS,oCACP,YACA,UAC2B;AAC3B,QAAO;EACL,GAAG;EACH,oBAAoB;EACrB;;AAGH,SAAS,mCACP,YACyB;AACzB,QAAO,OAAO,YACZ,WAAW,KAAK,cAAc,CAC5B,UAAU,OACV,gCAAgC,UAAU,CAC3C,CAAC,CACH;;AAGH,SAAS,gCACP,WACyB;CACzB,MAAM,OAAgC,EAAE;AACxC,MAAK,MAAM,SAAS,UAAU,cAC5B,yBACE,MACA,MAAM,UAAU,MAAM,IAAI,EAC1B;EACE,MAAM,MAAM,WAAW;EACvB,MAAM,MAAM;EACb,CACF;AAEH,MAAK,MAAM,SAAS,UAAU,SAC5B,MAAK,MAAM,SAAS,gCAAgC,MAAM;AAE5D,QAAO;;AAGT,SAAS,wBACP,MACA,WACA,WACM;CACN,MAAM,CAAC,MAAM,GAAG,QAAQ;AACxB,KAAI,CAAC,KACH;AAEF,KAAI,KAAK,WAAW,GAAG;AACrB,OAAK,QAAQ;AACb;;CAEF,MAAM,QACJ,KAAK,SAAS,OAAO,KAAK,UAAU,WAC/B,KAAK,QACN,EAAE;AACR,MAAK,QAAQ;AACb,yBAAwB,OAAO,MAAM,UAAU;;AAGjD,SAAS,qBAAqB,OAAuD;AACnF,QACE,QAAQ,MAAM,IACd,OAAO,UAAU,YACjB,UAAW,SACX,mBAAoB,SACpB,aAAc;;AAIlB,SAAS,sBAAsB,eAA+B;AAC5D,QAAO,cAAc,QAAQ,mBAAmB,IAAI"}
1
+ {"version":3,"file":"components.mjs","names":[],"sources":["../../src/runtime/components.ts"],"sourcesContent":["import {\n SyncoreSchema,\n TableDefinition,\n defineSchema,\n type AnyTableDefinition,\n type Validator\n} from \"@syncore/schema\";\nimport type { SyncoreDevtoolsEvent } from \"@syncore/devtools-protocol\";\nimport {\n type FunctionReference,\n type FunctionReferenceFor,\n type SyncoreFunctionDefinition,\n type SyncoreFunctionKind\n} from \"./functions.js\";\nimport type {\n JsonObject,\n RegisteredSyncoreFunction,\n SyncoreDataModel,\n SyncoreFunctionRegistry\n} from \"./runtime.js\";\n\nexport type ComponentPath = string;\n\nexport type SyncoreCoreCapability =\n | \"storage\"\n | \"scheduler\"\n | \"devtools\"\n | \"ownTables\"\n | \"publicExports\"\n | \"internalActions\";\n\nexport type SyncoreHostServiceName =\n | \"http\"\n | \"notifications\"\n | \"secureStore\"\n | \"filesystem\"\n | \"backgroundTasks\"\n | \"crypto\";\n\nexport type SyncoreRequestedCapability =\n | SyncoreCoreCapability\n | `host:${SyncoreHostServiceName}`;\n\nexport type AnySyncoreFunctionDefinition = SyncoreFunctionDefinition<\n SyncoreFunctionKind,\n any,\n any,\n unknown\n>;\n\nexport type SyncoreFunctionTree = {\n readonly [key: string]:\n | AnySyncoreFunctionDefinition\n | SyncoreFunctionTree\n | undefined;\n};\n\nexport interface SyncoreComponentHookContext {\n runtimeId: string;\n platform: string;\n componentPath: ComponentPath;\n componentName: string;\n version: string;\n config: unknown;\n capabilities: readonly SyncoreRequestedCapability[];\n emitDevtools(event: SyncoreDevtoolsEvent): void;\n}\n\nexport interface SyncoreComponent<\n TConfig = unknown,\n TSchema extends SyncoreDataModel | undefined =\n | SyncoreDataModel\n | undefined,\n TPublic extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined,\n TInternal extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined\n> {\n readonly kind: \"syncore.component\";\n readonly name: string;\n readonly version: string;\n readonly config?: Validator<TConfig>;\n readonly requestedCapabilities?: readonly SyncoreRequestedCapability[];\n readonly schema?: TSchema;\n readonly public?: TPublic;\n readonly internal?: TInternal;\n readonly dependencies?: readonly string[];\n onStart?(context: SyncoreComponentHookContext): Promise<void> | void;\n onStop?(context: SyncoreComponentHookContext): Promise<void> | void;\n}\n\nexport interface SyncoreComponentInstall<\n TComponent extends SyncoreComponent = SyncoreComponent,\n TChildren extends SyncoreComponentsManifest = SyncoreComponentsManifest\n> {\n readonly kind: \"syncore.component.install\";\n readonly component: TComponent;\n readonly source: string;\n readonly config?: TComponent extends SyncoreComponent<infer TConfig, any, any, any>\n ? TConfig\n : unknown;\n readonly capabilities?: readonly SyncoreRequestedCapability[];\n readonly bindings?: Record<string, string>;\n readonly children?: TChildren;\n}\n\nexport type SyncoreComponentsManifest = Record<string, SyncoreComponentInstall>;\n\nexport interface SyncoreComponentFunctionMetadata {\n componentPath: ComponentPath;\n componentName: string;\n version: string;\n visibility: \"public\" | \"internal\";\n localName: string;\n localTables: Record<string, string>;\n grantedCapabilities: readonly SyncoreRequestedCapability[];\n bindings: Record<string, string>;\n}\n\nexport interface ResolvedSyncoreComponent {\n alias: string;\n path: ComponentPath;\n source: string;\n name: string;\n version: string;\n config: unknown;\n grantedCapabilities: readonly SyncoreRequestedCapability[];\n requestedCapabilities: readonly SyncoreRequestedCapability[];\n bindings: Record<string, string>;\n schema: SyncoreDataModel | undefined;\n public: SyncoreFunctionTree | undefined;\n internal: SyncoreFunctionTree | undefined;\n publicEntries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }>;\n internalEntries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }>;\n localTables: Record<string, string>;\n onStart: SyncoreComponent[\"onStart\"] | undefined;\n onStop: SyncoreComponent[\"onStop\"] | undefined;\n children: ResolvedSyncoreComponent[];\n}\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\ntype PublicFunctionTreeOf<TComponent> = TComponent extends SyncoreComponent<\n any,\n any,\n infer TPublic,\n any\n>\n ? NonNullable<TPublic>\n : never;\n\nexport type FunctionReferencesForTree<TTree extends SyncoreFunctionTree> = Simplify<{\n [TKey in keyof TTree]: TTree[TKey] extends AnySyncoreFunctionDefinition\n ? FunctionReferenceFor<TTree[TKey]>\n : Record<string, unknown>;\n}>;\n\nexport type InstalledComponentApi<\n TInstall extends SyncoreComponentInstall\n> = Simplify<\n FunctionReferencesForTree<PublicFunctionTreeOf<TInstall[\"component\"]>> &\n Record<string, unknown>\n>;\n\nexport type InstalledComponentsApi<\n TManifest extends SyncoreComponentsManifest\n> = Simplify<{\n [TAlias in keyof TManifest]: InstalledComponentApi<TManifest[TAlias]>;\n}>;\n\ntype TablesOfSchema<TSchema extends SyncoreDataModel> = TSchema[\"tables\"];\n\nexport function defineComponent<\n TConfig = unknown,\n TSchema extends SyncoreDataModel | undefined =\n | SyncoreDataModel\n | undefined,\n TPublic extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined,\n TInternal extends SyncoreFunctionTree | undefined =\n | SyncoreFunctionTree\n | undefined\n>(\n component: Omit<\n SyncoreComponent<TConfig, TSchema, TPublic, TInternal>,\n \"kind\"\n >\n): SyncoreComponent<TConfig, TSchema, TPublic, TInternal> {\n return {\n kind: \"syncore.component\",\n ...component\n };\n}\n\nexport function installComponent<\n TComponent extends SyncoreComponent,\n TChildren extends SyncoreComponentsManifest = {}\n>(install: {\n component: TComponent;\n source: string;\n config?: TComponent extends SyncoreComponent<infer TConfig, any, any, any>\n ? TConfig\n : unknown;\n capabilities?: readonly SyncoreRequestedCapability[];\n bindings?: Record<string, string>;\n children?: TChildren;\n}): SyncoreComponentInstall<TComponent, TChildren> {\n return {\n kind: \"syncore.component.install\",\n ...install\n };\n}\n\nexport function defineComponents<TManifest extends SyncoreComponentsManifest>(\n components: TManifest\n): TManifest {\n return components;\n}\n\nexport function createBindingFunctionReference<\n TKind extends SyncoreFunctionKind,\n TArgs = JsonObject,\n TResult = unknown\n>(\n kind: TKind,\n bindingName: string,\n functionName: string\n): FunctionReference<TKind, TArgs, TResult> {\n return {\n kind,\n name: `binding:${bindingName}/${functionName}`\n };\n}\n\nexport function composeProjectSchema<\n TRootSchema extends SyncoreDataModel\n>(\n rootSchema: TRootSchema,\n manifest?: SyncoreComponentsManifest\n): SyncoreSchema<TablesOfSchema<TRootSchema> & Record<string, AnyTableDefinition>> {\n const tables: Record<string, AnyTableDefinition> = {\n ...rootSchema.tables\n };\n\n for (const component of resolveComponentsManifest(manifest)) {\n for (const [physicalTableName, tableDefinition] of composeComponentTables(\n component\n )) {\n if (tables[physicalTableName]) {\n throw new Error(\n `Component table collision detected for ${JSON.stringify(physicalTableName)}.`\n );\n }\n tables[physicalTableName] = tableDefinition;\n }\n }\n\n return defineSchema(tables) as unknown as SyncoreSchema<\n TablesOfSchema<TRootSchema> & Record<string, AnyTableDefinition>\n >;\n}\n\nexport function composeProjectFunctionRegistry(\n rootFunctions: SyncoreFunctionRegistry,\n manifest?: SyncoreComponentsManifest\n): SyncoreFunctionRegistry {\n const registry: Record<string, RegisteredSyncoreFunction> = {};\n for (const [name, definition] of Object.entries(rootFunctions)) {\n if (definition) {\n registry[name] = definition;\n }\n }\n\n for (const component of resolveComponentsManifest(manifest)) {\n appendResolvedComponentFunctions(registry, component);\n }\n\n return registry;\n}\n\nexport function createInstalledComponentsApi<\n TManifest extends SyncoreComponentsManifest\n>(manifest: TManifest): InstalledComponentsApi<TManifest> {\n return createInstalledComponentsApiObject(resolveComponentsManifest(manifest)) as InstalledComponentsApi<TManifest>;\n}\n\nexport function resolveComponentsManifest(\n manifest?: SyncoreComponentsManifest\n): ResolvedSyncoreComponent[] {\n if (!manifest) {\n return [];\n }\n\n return Object.entries(manifest)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([alias, install]) => resolveInstalledComponent(alias, install, []));\n}\n\nexport function toCanonicalComponentFunctionName(\n componentPath: ComponentPath,\n visibility: \"public\" | \"internal\",\n localName: string\n): string {\n return [\"components\", componentPath, visibility, localName]\n .filter(Boolean)\n .join(\"/\");\n}\n\nexport function createComponentPhysicalTableName(\n componentPath: ComponentPath,\n tableName: string\n): string {\n const pathPart = sanitizeComponentPath(componentPath);\n return `__syncore_component__${pathPart}__${tableName}`;\n}\n\nfunction resolveInstalledComponent(\n alias: string,\n install: SyncoreComponentInstall,\n parentPath: string[]\n): ResolvedSyncoreComponent {\n const pathSegments = [...parentPath, alias];\n const componentPath = pathSegments.join(\"/\");\n const component = install.component;\n const requestedCapabilities = [\n ...(component.requestedCapabilities ?? [])\n ];\n const localTables = createLocalTableMap(componentPath, component.schema);\n const defaultCapabilities = new Set<SyncoreRequestedCapability>(\n component.schema ? [\"ownTables\"] : []\n );\n if (component.public) {\n defaultCapabilities.add(\"publicExports\");\n }\n if (component.internal) {\n defaultCapabilities.add(\"internalActions\");\n }\n const grantedCapabilities = Array.from(\n new Set([\n ...defaultCapabilities,\n ...(install.capabilities ?? requestedCapabilities)\n ])\n );\n\n for (const capability of requestedCapabilities) {\n if (!grantedCapabilities.includes(capability)) {\n throw new Error(\n `Component ${JSON.stringify(component.name)} at ${JSON.stringify(componentPath)} requested capability ${JSON.stringify(capability)} but it was not granted.`\n );\n }\n }\n\n if (component.config) {\n component.config.parse(install.config);\n }\n\n const bindings = { ...(install.bindings ?? {}) };\n for (const dependency of component.dependencies ?? []) {\n if (!bindings[dependency]) {\n throw new Error(\n `Component ${JSON.stringify(component.name)} at ${JSON.stringify(componentPath)} requires binding ${JSON.stringify(dependency)}.`\n );\n }\n }\n\n const children = Object.entries(install.children ?? {})\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([childAlias, childInstall]) =>\n resolveInstalledComponent(childAlias, childInstall, pathSegments)\n );\n\n return {\n alias,\n path: componentPath,\n source: install.source,\n name: component.name,\n version: component.version,\n config: install.config,\n grantedCapabilities,\n requestedCapabilities,\n bindings,\n schema: component.schema,\n public: component.public,\n internal: component.internal,\n publicEntries: flattenComponentFunctionTree(\n component.public,\n componentPath,\n component.name,\n component.version,\n \"public\",\n localTables,\n grantedCapabilities,\n bindings\n ),\n internalEntries: flattenComponentFunctionTree(\n component.internal,\n componentPath,\n component.name,\n component.version,\n \"internal\",\n localTables,\n grantedCapabilities,\n bindings\n ),\n localTables,\n onStart: component.onStart,\n onStop: component.onStop,\n children\n };\n}\n\nfunction createLocalTableMap(\n componentPath: string,\n schema?: SyncoreDataModel\n): Record<string, string> {\n if (!schema) {\n return {};\n }\n return Object.fromEntries(\n schema.tableNames().map((tableName) => [\n tableName,\n createComponentPhysicalTableName(componentPath, tableName)\n ])\n );\n}\n\nfunction composeComponentTables(\n component: ResolvedSyncoreComponent\n): Array<[string, AnyTableDefinition]> {\n const entries: Array<[string, AnyTableDefinition]> = [];\n if (component.schema) {\n for (const localTableName of component.schema.tableNames()) {\n const original = component.schema.getTable(localTableName);\n const cloned = new TableDefinition(original.validator, {\n ...original.options,\n tableName: localTableName,\n componentPath: component.path,\n componentName: component.name\n });\n for (const index of original.indexes) {\n if (index.fields.length > 0) {\n cloned.index(index.name, [...index.fields] as [string, ...string[]]);\n }\n }\n for (const index of original.searchIndexes) {\n cloned.searchIndex(index.name, {\n searchField: index.searchField,\n filterFields: [...index.filterFields]\n });\n }\n entries.push([component.localTables[localTableName]!, cloned]);\n }\n }\n for (const child of component.children) {\n entries.push(...composeComponentTables(child));\n }\n return entries;\n}\n\nfunction appendResolvedComponentFunctions(\n registry: Record<string, RegisteredSyncoreFunction>,\n component: ResolvedSyncoreComponent\n): void {\n for (const entry of component.publicEntries) {\n registry[entry.canonicalName] = entry.definition;\n }\n for (const entry of component.internalEntries) {\n registry[entry.canonicalName] = entry.definition;\n }\n for (const child of component.children) {\n appendResolvedComponentFunctions(registry, child);\n }\n}\n\nfunction flattenComponentFunctionTree(\n tree: SyncoreFunctionTree | undefined,\n componentPath: string,\n componentName: string,\n version: string,\n visibility: \"public\" | \"internal\",\n localTables: Record<string, string>,\n grantedCapabilities: readonly SyncoreRequestedCapability[],\n bindings: Record<string, string>,\n prefix: string[] = []\n): Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n}> {\n if (!tree) {\n return [];\n }\n\n const entries: Array<{\n localName: string;\n canonicalName: string;\n definition: RegisteredSyncoreFunction;\n }> = [];\n\n for (const [key, value] of Object.entries(tree).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n if (!value) {\n continue;\n }\n if (isFunctionDefinition(value)) {\n const localName = [...prefix, key].join(\"/\");\n entries.push({\n localName,\n canonicalName: toCanonicalComponentFunctionName(\n componentPath,\n visibility,\n localName\n ),\n definition: decorateComponentFunctionDefinition(value, {\n componentPath,\n componentName,\n version,\n visibility,\n localName,\n localTables,\n grantedCapabilities,\n bindings\n })\n });\n continue;\n }\n entries.push(\n ...flattenComponentFunctionTree(\n value,\n componentPath,\n componentName,\n version,\n visibility,\n localTables,\n grantedCapabilities,\n bindings,\n [...prefix, key]\n )\n );\n }\n\n return entries;\n}\n\nfunction decorateComponentFunctionDefinition(\n definition: AnySyncoreFunctionDefinition,\n metadata: SyncoreComponentFunctionMetadata\n): RegisteredSyncoreFunction {\n return {\n ...definition,\n __syncoreComponent: metadata\n } as RegisteredSyncoreFunction;\n}\n\nfunction createInstalledComponentsApiObject(\n components: ResolvedSyncoreComponent[]\n): Record<string, unknown> {\n return Object.fromEntries(\n components.map((component) => [\n component.alias,\n createInstalledComponentApiNode(component)\n ])\n );\n}\n\nfunction createInstalledComponentApiNode(\n component: ResolvedSyncoreComponent\n): Record<string, unknown> {\n const node: Record<string, unknown> = {};\n for (const entry of component.publicEntries) {\n assignFunctionReference(\n node,\n entry.localName.split(\"/\"),\n {\n kind: entry.definition.kind,\n name: entry.canonicalName\n }\n );\n }\n for (const child of component.children) {\n node[child.alias] = createInstalledComponentApiNode(child);\n }\n return node;\n}\n\nfunction assignFunctionReference(\n node: Record<string, unknown>,\n pathParts: string[],\n reference: FunctionReference\n): void {\n const [head, ...tail] = pathParts;\n if (!head) {\n return;\n }\n if (tail.length === 0) {\n node[head] = reference;\n return;\n }\n const child =\n node[head] && typeof node[head] === \"object\"\n ? (node[head] as Record<string, unknown>)\n : {};\n node[head] = child;\n assignFunctionReference(child, tail, reference);\n}\n\nfunction isFunctionDefinition(value: unknown): value is AnySyncoreFunctionDefinition {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n \"kind\" in (value as Record<string, unknown>) &&\n \"argsValidator\" in (value as Record<string, unknown>) &&\n \"handler\" in (value as Record<string, unknown>)\n );\n}\n\nfunction sanitizeComponentPath(componentPath: string): string {\n return componentPath.replace(/[^a-zA-Z0-9_]+/g, \"_\");\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.d.mts","names":[],"sources":["../../src/runtime/devtools.ts"],"mappings":";;;;UA8BiB,0BAAA;EACf,MAAA,EAAQ,gBAAA;EACR,MAAA,EAAQ,gBAAA;EACR,SAAA,EAAW,qBAAA,CAAsB,gBAAA;EACjC,KAAA,EAAO,mBAAA,CAAoB,gBAAA;EAC3B,GAAA,GAAM,kBAAA;AAAA;AAAA,KAGI,eAAA;AAAA,UAEK,mBAAA;EACf,IAAA,EAAM,eAAA;EACN,UAAA;EACA,WAAA;EACA,aAAA;EACA,cAAA,EAAgB,sBAAA;AAAA;AAAA,UAGD,qBAAA;EACf,OAAA;EACA,IAAA;EACA,cAAA;AAAA;AAAA,UAGe,kBAAA;EACf,mBAAA,CAAoB,KAAA,WAAgB,mBAAA;EACpC,aAAA,CACE,QAAA,EAAU,mBAAA,EACV,QAAA,EAAU,eAAA;EAEZ,gBAAA,CAAiB,YAAA,UAAsB,KAAA,WAAgB,qBAAA;AAAA;AAAA,KAG7C,sBAAA,IACV,OAAA,EAAS,6BAAA,KACN,OAAA,CAAQ,mCAAA;AAAA,KAED,4BAAA,IACV,OAAA,EAAS,wCAAA;AAAA,UAGM,wBAAA;EACf,SAAA,CACE,cAAA,UACA,OAAA,EAAS,kCAAA,EACT,QAAA,EAAU,4BAAA,GACT,OAAA;EACH,WAAA,CAAY,cAAA;EACZ,OAAA;AAAA;AAAA,iBAYc,4BAAA,CACd,IAAA,EAAM,0BAAA,GACL,sBAAA;AAAA,iBAuNa,8BAAA,CACd,IAAA,EAAM,0BAAA,GACL,wBAAA"}
1
+ {"version":3,"file":"devtools.d.mts","names":[],"sources":["../../src/runtime/devtools.ts"],"mappings":";;;;UA+BiB,0BAAA;EACf,MAAA,EAAQ,gBAAA;EACR,MAAA,EAAQ,gBAAA;EACR,SAAA,EAAW,qBAAA,CAAsB,gBAAA;EACjC,KAAA,EAAO,mBAAA,CAAoB,gBAAA;EAC3B,GAAA,GAAM,kBAAA;AAAA;AAAA,KAGI,eAAA;AAAA,UAEK,mBAAA;EACf,IAAA,EAAM,eAAA;EACN,UAAA;EACA,WAAA;EACA,aAAA;EACA,cAAA,EAAgB,sBAAsB;AAAA;AAAA,UAGvB,qBAAA;EACf,OAAA;EACA,IAAA;EACA,cAAA;AAAA;AAAA,UAGe,kBAAA;EACf,mBAAA,CAAoB,KAAA,WAAgB,mBAAA;EACpC,aAAA,CACE,QAAA,EAAU,mBAAA,EACV,QAAA,EAAU,eAAA;EAEZ,gBAAA,CAAiB,YAAA,UAAsB,KAAA,WAAgB,qBAAA;AAAA;AAAA,KAG7C,sBAAA,IACV,OAAA,EAAS,6BAAA,KACN,OAAA,CAAQ,mCAAA;AAAA,KAED,4BAAA,IACV,OAAiD,EAAxC,wCAAwC;AAAA,UAGlC,wBAAA;EACf,SAAA,CACE,cAAA,UACA,OAAA,EAAS,kCAAA,EACT,QAAA,EAAU,4BAAA,GACT,OAAA;EACH,WAAA,CAAY,cAAA;EACZ,OAAA;AAAA;AAAA,iBAYc,4BAAA,CACd,IAAA,EAAM,0BAAA,GACL,sBAAsB;AAAA,iBAyRT,8BAAA,CACd,IAAA,EAAM,0BAAA,GACL,wBAAwB"}
@@ -1,4 +1,4 @@
1
- import { parseCanonicalComponentFunctionName, parseComponentScopedIdentifier, safeReadRecurringSchedule } from "./internal/engines/shared.mjs";
1
+ import { parseCanonicalComponentFunctionName, parseComponentScopedIdentifier, quoteIdentifier, safeReadRecurringSchedule } from "./internal/engines/shared.mjs";
2
2
  import { createFunctionReference } from "./runtime.mjs";
3
3
  import { describeValidator } from "../../schema/index.js";
4
4
  //#region src/runtime/devtools.ts
@@ -36,10 +36,12 @@ function createDevtoolsCommandHandler(deps) {
36
36
  }
37
37
  }
38
38
  case "data.insert": try {
39
+ const id = await runDevtoolsMutation(admin, async (ctx) => ctx.db.insert(payload.table, payload.document), { origin: "dashboard" });
40
+ notifyDataMutationScopes(admin, payload.table);
39
41
  return {
40
42
  kind: "data.mutate.result",
41
43
  success: true,
42
- id: await runDevtoolsMutation(admin, async (ctx) => ctx.db.insert(payload.table, payload.document), { origin: "dashboard" })
44
+ id
43
45
  };
44
46
  } catch (error) {
45
47
  return {
@@ -53,6 +55,7 @@ function createDevtoolsCommandHandler(deps) {
53
55
  await ctx.db.patch(payload.table, payload.id, payload.fields);
54
56
  return null;
55
57
  }, { origin: "dashboard" });
58
+ notifyDataMutationScopes(admin, payload.table);
56
59
  return {
57
60
  kind: "data.mutate.result",
58
61
  success: true,
@@ -70,6 +73,7 @@ function createDevtoolsCommandHandler(deps) {
70
73
  await ctx.db.delete(payload.table, payload.id);
71
74
  return null;
72
75
  }, { origin: "dashboard" });
76
+ notifyDataMutationScopes(admin, payload.table);
73
77
  return {
74
78
  kind: "data.mutate.result",
75
79
  success: true
@@ -81,6 +85,51 @@ function createDevtoolsCommandHandler(deps) {
81
85
  error: error instanceof Error ? error.message : String(error)
82
86
  };
83
87
  }
88
+ case "data.export": try {
89
+ const requestedTables = payload.tables && payload.tables.length > 0 ? payload.tables : deps.schema.tableNames();
90
+ return {
91
+ kind: "data.export.result",
92
+ tables: await Promise.all(requestedTables.map(async (name) => {
93
+ const result = await queryTable(driver, name);
94
+ return {
95
+ name,
96
+ rows: result.rows,
97
+ totalCount: result.totalCount
98
+ };
99
+ }))
100
+ };
101
+ } catch (error) {
102
+ return {
103
+ kind: "data.export.result",
104
+ tables: [],
105
+ error: error instanceof Error ? error.message : String(error)
106
+ };
107
+ }
108
+ case "data.referenceOptions": {
109
+ const limit = Math.min(Math.max(payload.limit ?? 100, 1), 200);
110
+ const offset = Math.max(payload.offset ?? 0, 0);
111
+ try {
112
+ const result = await queryReferenceOptions(driver, payload.table, payload.search, limit, offset);
113
+ return {
114
+ kind: "data.referenceOptions.result",
115
+ table: payload.table,
116
+ rows: result.rows,
117
+ totalCount: result.totalCount,
118
+ offset,
119
+ hasMore: offset + result.rows.length < result.totalCount
120
+ };
121
+ } catch (error) {
122
+ return {
123
+ kind: "data.referenceOptions.result",
124
+ table: payload.table,
125
+ rows: [],
126
+ totalCount: 0,
127
+ offset,
128
+ hasMore: false,
129
+ error: error instanceof Error ? error.message : String(error)
130
+ };
131
+ }
132
+ }
84
133
  case "sql.read": try {
85
134
  const sqlSupport = requireDevtoolsSqlSupport(sql);
86
135
  const databasePath = admin.getDriverDatabasePath();
@@ -135,9 +184,9 @@ function createDevtoolsCommandHandler(deps) {
135
184
  case "scheduler.update": try {
136
185
  const updated = await admin.updateScheduledJob({
137
186
  id: payload.jobId,
138
- schedule: payload.schedule,
139
187
  args: payload.args,
140
- misfirePolicy: payload.misfirePolicy,
188
+ ...payload.schedule ? { schedule: payload.schedule } : {},
189
+ ...payload.misfirePolicy ? { misfirePolicy: payload.misfirePolicy } : {},
141
190
  ...payload.runAt !== void 0 ? { runAt: payload.runAt } : {}
142
191
  });
143
192
  const updatedJob = (updated ? await listSchedulerJobs(driver) : []).find((job) => job.id === payload.jobId);
@@ -311,12 +360,16 @@ async function resolveSubscriptionPayload(payload, deps) {
311
360
  }
312
361
  }
313
362
  async function queryTable(driver, table, filters, limit) {
314
- let sql = `SELECT _id, _creationTime, _json FROM "${table}"`;
363
+ let sql = `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(table)}`;
315
364
  const params = [];
316
- if (filters && filters.length > 0) sql += ` WHERE ${filters.map((filter) => {
317
- params.push(normalizeFilterValue(filter));
318
- return `json_extract(_json, '$.${filter.field}') ${filterOperatorToSql(filter.operator)} ?`;
319
- }).join(" AND ")}`;
365
+ const whereClauses = [];
366
+ if (filters && filters.length > 0) {
367
+ for (const filter of filters) {
368
+ whereClauses.push(filterToSql(filter));
369
+ params.push(normalizeFilterValue(filter));
370
+ }
371
+ sql += ` WHERE ${whereClauses.join(" AND ")}`;
372
+ }
320
373
  sql += " ORDER BY _creationTime DESC";
321
374
  if (limit) sql += ` LIMIT ${limit}`;
322
375
  return {
@@ -325,7 +378,30 @@ async function queryTable(driver, table, filters, limit) {
325
378
  _creationTime: row._creationTime,
326
379
  ...JSON.parse(row._json)
327
380
  })),
328
- totalCount: (await driver.get(`SELECT COUNT(*) as count FROM "${table}"`))?.count ?? 0
381
+ totalCount: (await driver.get(`SELECT COUNT(*) as count FROM ${quoteIdentifier(table)}${whereClauses.length > 0 ? ` WHERE ${whereClauses.join(" AND ")}` : ""}`, params))?.count ?? 0
382
+ };
383
+ }
384
+ async function queryReferenceOptions(driver, table, search, limit, offset) {
385
+ let sql = `SELECT _id, _creationTime, _json FROM ${quoteIdentifier(table)}`;
386
+ const params = [];
387
+ const trimmedSearch = search?.trim();
388
+ const whereClause = trimmedSearch ? " WHERE _id LIKE ? OR _json LIKE ?" : "";
389
+ if (trimmedSearch) {
390
+ const like = `%${trimmedSearch}%`;
391
+ params.push(like, like);
392
+ }
393
+ sql += `${whereClause} ORDER BY _creationTime DESC LIMIT ? OFFSET ?`;
394
+ return {
395
+ rows: (await driver.all(sql, [
396
+ ...params,
397
+ limit,
398
+ offset
399
+ ])).map((row) => ({
400
+ _id: row._id,
401
+ _creationTime: row._creationTime,
402
+ ...JSON.parse(row._json)
403
+ })),
404
+ totalCount: (await driver.get(`SELECT COUNT(*) as count FROM ${quoteIdentifier(table)}${whereClause}`, params))?.count ?? 0
329
405
  };
330
406
  }
331
407
  async function getSchemaTables(driver, schema) {
@@ -337,7 +413,8 @@ async function getSchemaTables(driver, schema) {
337
413
  return {
338
414
  name: fieldName,
339
415
  type: field.validator.kind,
340
- optional: field.optional
416
+ optional: field.optional,
417
+ ...field.validator.kind === "id" && field.validator.tableName ? { referenceTable: field.validator.tableName } : {}
341
418
  };
342
419
  }) : [];
343
420
  fields.unshift({
@@ -349,12 +426,7 @@ async function getSchemaTables(driver, schema) {
349
426
  type: "number",
350
427
  optional: false
351
428
  });
352
- let documentCount = 0;
353
- try {
354
- documentCount = (await driver.get(`SELECT COUNT(*) as count FROM "${name}"`))?.count ?? 0;
355
- } catch {
356
- documentCount = 0;
357
- }
429
+ const documentCount = await driver.get(`SELECT COUNT(*) as count FROM "${name}"`).then((countRow) => countRow?.count ?? 0).catch(() => 0);
358
430
  return {
359
431
  name,
360
432
  ...table.options.tableName ? { displayName: table.options.tableName } : {},
@@ -410,12 +482,18 @@ function listFunctions(functions) {
410
482
  const descriptor = {
411
483
  name,
412
484
  type: fn.kind,
413
- file: inferFileFromFunctionName(name),
414
485
  owner: componentFunction ? "component" : "root",
486
+ namespace: inferFunctionNamespace(name),
487
+ metadataAvailable: componentFunction !== null || name.includes(":"),
415
488
  ...componentFunction ? {
489
+ file: `components/${componentFunction.componentPath}`,
490
+ modulePath: componentFunction.componentPath,
416
491
  componentPath: componentFunction.componentPath,
417
492
  visibility: componentFunction.visibility,
418
493
  localName: componentFunction.localName
494
+ } : inferFileFromFunctionName(name) ? {
495
+ file: inferFileFromFunctionName(name),
496
+ modulePath: inferFunctionNamespace(name)
419
497
  } : {}
420
498
  };
421
499
  const argsDesc = describeValidator(fn.argsValidator);
@@ -428,15 +506,41 @@ function inferFileFromFunctionName(name) {
428
506
  if (componentFunction) return `components/${componentFunction.componentPath}`;
429
507
  const parts = name.split(":");
430
508
  if (parts.length > 1) return `${parts[0]}.ts`;
431
- return "unknown";
509
+ return "";
510
+ }
511
+ function inferFunctionNamespace(name) {
512
+ const componentFunction = parseCanonicalComponentFunctionName(name);
513
+ if (componentFunction) return componentFunction.componentPath;
514
+ if (name.includes(":")) return name.split(":")[0] ?? "root";
515
+ if (name.includes("/")) return name.split("/")[0] ?? "root";
516
+ return "root";
432
517
  }
433
518
  function normalizeFilterValue(filter) {
519
+ const value = coerceFilterValue(filter.value);
434
520
  switch (filter.operator) {
435
- case "contains": return `%${String(filter.value)}%`;
436
- case "startsWith": return `${String(filter.value)}%`;
437
- default: return filter.value;
521
+ case "contains": return `%${String(value)}%`;
522
+ case "startsWith": return `${String(value)}%`;
523
+ default: return value;
438
524
  }
439
525
  }
526
+ function filterToSql(filter) {
527
+ const operator = filterOperatorToSql(filter.operator);
528
+ if (filter.field === "_id") return `_id ${operator} ?`;
529
+ if (filter.field === "_creationTime") return `_creationTime ${operator} ?`;
530
+ return `json_extract(_json, ${JSON.stringify(`$.${filter.field}`)}) ${operator} ?`;
531
+ }
532
+ function coerceFilterValue(value) {
533
+ if (typeof value !== "string") return value;
534
+ const trimmed = value.trim();
535
+ if (trimmed === "true") return true;
536
+ if (trimmed === "false") return false;
537
+ if (trimmed === "null") return null;
538
+ if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) {
539
+ const numberValue = Number(trimmed);
540
+ if (Number.isFinite(numberValue)) return numberValue;
541
+ }
542
+ return value;
543
+ }
440
544
  function filterOperatorToSql(operator) {
441
545
  switch (operator) {
442
546
  case "eq": return "=";
@@ -491,6 +595,9 @@ function capitalize(value) {
491
595
  async function runDevtoolsMutation(admin, callback, meta) {
492
596
  return admin.runDevtoolsMutation(callback, meta);
493
597
  }
598
+ function notifyDataMutationScopes(admin, tableName) {
599
+ admin.notifyDevtoolsScopes(["schema.tables", `table:${tableName}`]);
600
+ }
494
601
  function scopesForSubscription(payload, sql) {
495
602
  switch (payload.kind) {
496
603
  case "runtime.summary": return new Set(["runtime.summary"]);
@@ -517,7 +624,7 @@ function intersects(a, b) {
517
624
  return false;
518
625
  }
519
626
  function requireDevtoolsSqlSupport(sql) {
520
- if (!sql) throw new Error("SQL devtools are only available in Node-hosted runtimes.");
627
+ if (!sql) throw new Error("SQL Console is not available for this runtime.");
521
628
  return sql;
522
629
  }
523
630
  //#endregion