@salsita-ai/sdk 0.50.0-develop.91d65bd507 → 0.50.0-develop.9239ced550

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 (212) hide show
  1. package/README.md +1 -1
  2. package/dist/application/index.d.ts +1 -0
  3. package/dist/application/index.js +1 -1
  4. package/dist/application/mount-application.d.ts +1 -1
  5. package/dist/application/mount-application.js +1 -1
  6. package/dist/application/mount-configurator.d.ts +19 -0
  7. package/dist/application/mount-configurator.js +1 -0
  8. package/dist/application/mounted-application-runtime.d.ts +4 -0
  9. package/dist/application/mounted-application-runtime.js +1 -0
  10. package/dist/application/register-web-component.d.ts +2 -0
  11. package/dist/application/register-web-component.js +1 -0
  12. package/dist/application-spec/core/enhanced-json-value.d.ts +2 -31
  13. package/dist/application-spec/core/enhanced-json-value.js +1 -1
  14. package/dist/application-spec/core/index.d.ts +1 -3
  15. package/dist/application-spec/core/index.js +1 -1
  16. package/dist/application-spec/core/markers/index.d.ts +1 -1
  17. package/dist/application-spec/core/markers/index.js +1 -1
  18. package/dist/application-spec/core/markers/msg-marker.d.ts +2 -28
  19. package/dist/application-spec/core/markers/msg-marker.js +1 -1
  20. package/dist/application-spec/core/markers/raw-eval-write-marker.d.ts +1 -1
  21. package/dist/application-spec/core/markers/raw-eval-write-marker.js +1 -1
  22. package/dist/application-spec/core/markers/raw-read-write-marker.js +1 -1
  23. package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
  24. package/dist/application-spec/generate-application/code/templates/index.d.ts +2 -6
  25. package/dist/application-spec/generate-application/code/templates/index.js +1 -1
  26. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill-bundle.d.ts +10 -0
  27. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill-bundle.js +7 -0
  28. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
  29. package/dist/application-spec/generate-application/implementations/phx-application-types.d.ts +25 -0
  30. package/dist/application-spec/generate-application/implementations/phx-application-types.js +1 -0
  31. package/dist/application-spec/generate-application/implementations/phx-domain.d.ts +36 -0
  32. package/dist/application-spec/generate-application/implementations/phx-domain.js +1 -0
  33. package/dist/application-spec/generate-application/implementations/phx-model.d.ts +24 -0
  34. package/dist/application-spec/generate-application/implementations/phx-model.js +1 -0
  35. package/dist/application-spec/generate-application/implementations/phx.d.ts +22 -0
  36. package/dist/application-spec/generate-application/implementations/phx.js +1 -0
  37. package/dist/application-spec/generate-application/index.d.ts +2 -0
  38. package/dist/application-spec/generate-application/index.js +1 -1
  39. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-model-runtime.d.ts +3 -3
  40. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +4 -2
  41. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
  42. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-spec-runtime.d.ts +16 -0
  43. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-spec-runtime.js +1 -0
  44. package/dist/application-spec/generate-application/runtime/application-runtime.d.ts +5 -0
  45. package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
  46. package/dist/application-spec/generate-application/runtime/application-spec-slice.d.ts +71 -0
  47. package/dist/application-spec/generate-application/runtime/application-spec-slice.js +1 -0
  48. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.d.ts +3 -3
  49. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +4 -2
  50. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
  51. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-spec-runtime.d.ts +16 -0
  52. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-spec-runtime.js +1 -0
  53. package/dist/application-spec/generate-application/runtime/create-application.d.ts +57 -0
  54. package/dist/application-spec/generate-application/runtime/create-application.js +1 -0
  55. package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.js +1 -1
  56. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +1 -1
  57. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.js +1 -1
  58. package/dist/application-spec/generate-application/runtime/generate-runtime-instance.d.ts +1 -1
  59. package/dist/application-spec/generate-application/runtime/generate-runtime-instance.js +1 -1
  60. package/dist/application-spec/generate-application/runtime/index.d.ts +8 -0
  61. package/dist/application-spec/generate-application/runtime/index.js +1 -0
  62. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
  63. package/dist/application-spec/generate-application/runtime/sections/expression-runtime.d.ts +1 -1
  64. package/dist/application-spec/generate-application/runtime/sections/expression-runtime.js +1 -1
  65. package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.d.ts +1 -1
  66. package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.js +1 -1
  67. package/dist/application-spec/generate-application/runtime/spec-code/resolve-spec-code.d.ts +1 -1
  68. package/dist/application-spec/generate-application/runtime/spec-runtime.d.ts +21 -0
  69. package/dist/application-spec/generate-application/runtime/spec-runtime.js +1 -0
  70. package/dist/application-spec/generate-application/runtime-spec/encoded-runtime-spec.d.ts +3 -2
  71. package/dist/application-spec/generate-application/runtime-spec/runtime-spec.d.ts +44 -9
  72. package/dist/application-spec/generate-application/runtime-spec/runtime-spec.js +1 -1
  73. package/dist/application-spec/parse-application-files/raw-spec/raw-expressions.d.ts +1 -1
  74. package/dist/application-spec/parse-application-files/raw-spec/raw-expressions.js +1 -1
  75. package/dist/client/authorized-client.d.ts +3 -1
  76. package/dist/client/authorized-client.js +1 -1
  77. package/dist/client/contract.d.ts +17 -0
  78. package/dist/client/index.d.ts +1 -1
  79. package/dist/client/local-authorized-client.d.ts +3 -1
  80. package/dist/client/local-authorized-client.js +1 -1
  81. package/dist/client/memory-authorized-client.d.ts +4 -1
  82. package/dist/client/memory-authorized-client.js +1 -1
  83. package/dist/client/phoenix-api.d.ts +228 -0
  84. package/dist/configurator/ConfiguratorApp.js +1 -1
  85. package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
  86. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +13 -0
  87. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  88. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +2 -1
  89. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
  90. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +15 -9
  91. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  92. package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.d.ts +1 -1
  93. package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.js +1 -1
  94. package/dist/configurator/ui/assistant/screenshots/tool-screenshots.d.ts +12 -4
  95. package/dist/configurator/ui/assistant/screenshots/tool-screenshots.js +1 -1
  96. package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.d.ts +8 -0
  97. package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.js +1 -0
  98. package/dist/docs/index.json +1 -1
  99. package/dist/docs/layouts/gallery/nightjar-guitar.mdx +31 -16
  100. package/dist/docs/layouts/gallery/tidepool-aquascape.mdx +205 -33
  101. package/dist/docs/phoenix/domain-model.mdx +4 -1
  102. package/dist/docs/phoenix/phoenix-cli.mdx +14 -6
  103. package/dist/docs/phoenix/project-structure.mdx +21 -17
  104. package/dist/docs/phoenix/sdk-builder-workflow.mdx +6 -4
  105. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  106. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  107. package/dist/domain/application/configurator-builder.d.ts +7 -1
  108. package/dist/domain/application/configurator-builder.js +1 -1
  109. package/dist/domain/application/index.d.ts +1 -1
  110. package/dist/domain/application/index.js +1 -1
  111. package/dist/domain/application/standard-properties.js +1 -1
  112. package/dist/domain/domain-runtime/application.d.ts +39 -0
  113. package/dist/domain/domain-runtime/application.js +1 -0
  114. package/dist/domain/domain-runtime/domain-runtime.d.ts +36 -4
  115. package/dist/domain/domain-runtime/domain-runtime.js +1 -1
  116. package/dist/domain/domain-runtime/environment/initialize.d.ts +1 -1
  117. package/dist/domain/domain-runtime/index.d.ts +1 -0
  118. package/dist/domain/domain-runtime/index.js +1 -1
  119. package/dist/domain/domain-runtime/web-component/actions.d.ts +3 -0
  120. package/dist/domain/domain-runtime/web-component/actions.js +1 -1
  121. package/dist/domain/domain-runtime/web-component/initialize.d.ts +1 -0
  122. package/dist/domain/domain-runtime/web-component/initialize.js +1 -1
  123. package/dist/domain/domain-runtime/web-component/selectors.d.ts +2 -0
  124. package/dist/domain/domain-runtime/web-component/selectors.js +1 -1
  125. package/dist/domain/domain-runtime/web-component/types.d.ts +6 -3
  126. package/dist/domain/index.d.ts +1 -0
  127. package/dist/domain/index.js +1 -1
  128. package/dist/domain/mocks/create-mock-domain-runtime.d.ts +5 -0
  129. package/dist/domain/spec/application/index.d.ts +1 -0
  130. package/dist/domain/spec/application/index.js +1 -0
  131. package/dist/{application-spec/core → domain/spec}/components/component-filter.d.ts +3 -2
  132. package/dist/domain/spec/enhanced-json-value.d.ts +30 -0
  133. package/dist/domain/spec/enhanced-json-value.js +1 -0
  134. package/dist/domain/spec/index.d.ts +5 -0
  135. package/dist/domain/spec/index.js +1 -0
  136. package/dist/domain/spec/markers/index.d.ts +2 -0
  137. package/dist/domain/spec/markers/index.js +1 -0
  138. package/dist/domain/spec/markers/msg-marker.d.ts +28 -0
  139. package/dist/domain/spec/markers/msg-marker.js +1 -0
  140. package/dist/editor/domain-editors/DomainSpecContext.js +1 -1
  141. package/dist/editor/domain-editors/apply-spec-update.d.ts +2 -1
  142. package/dist/editor/domain-editors/apply-spec-update.js +1 -1
  143. package/dist/editor/domain-editors/use-implementation-files.d.ts +0 -3
  144. package/dist/editor/domain-editors/use-implementation-files.js +1 -1
  145. package/dist/phoenix/application-spec/generate-application-spec-project.js +2 -2
  146. package/dist/phoenix/application-spec/resolve-deployment-data.d.ts +11 -0
  147. package/dist/phoenix/application-spec/resolve-deployment-data.js +2 -2
  148. package/dist/phoenix/bin.js +1 -1
  149. package/dist/phoenix/cli.js +1 -1
  150. package/dist/phoenix/commands/deploy.js +1 -1
  151. package/dist/phoenix/commands/dev.js +5 -5
  152. package/dist/phoenix/commands/generated-env-markers.d.ts +1 -0
  153. package/dist/phoenix/commands/generated-env-markers.js +1 -1
  154. package/dist/phoenix/commands/index.d.ts +1 -1
  155. package/dist/phoenix/commands/index.js +1 -1
  156. package/dist/phoenix/lingui/index.d.ts +1 -0
  157. package/dist/phoenix/lingui/index.js +1 -0
  158. package/dist/phoenix/{services → lingui}/lingui.d.ts +5 -2
  159. package/dist/phoenix/lingui/lingui.js +1 -0
  160. package/dist/phoenix/services/application-spec-project-watcher.d.ts +3 -1
  161. package/dist/phoenix/services/application-spec-project-watcher.js +2 -2
  162. package/dist/phoenix/services/index.d.ts +1 -0
  163. package/dist/phoenix/services/index.js +1 -1
  164. package/dist/phoenix/services/lingui-watcher.js +1 -1
  165. package/dist/phoenix/services/prepare-development-environment.js +1 -1
  166. package/dist/phoenix/services/vite-config.js +1 -1
  167. package/dist/react-sdk/application-runtime/common-services/analytics/analytics-service.d.ts +1 -1
  168. package/dist/react-sdk/application-runtime/common-services/initialize.d.ts +2 -2
  169. package/dist/react-sdk/application-runtime/hooks/use-access-service.js +1 -1
  170. package/dist/react-sdk/application-runtime/hooks/use-web-component-readonly-sync.d.ts +4 -11
  171. package/dist/react-sdk/application-runtime/hooks/use-web-component-readonly-sync.js +1 -1
  172. package/dist/react-sdk/application-runtime/hooks/use-web-component.d.ts +5 -0
  173. package/dist/react-sdk/application-runtime/hooks/use-web-component.js +1 -1
  174. package/dist/react-sdk/application-runtime/host-properties/actions.d.ts +15 -0
  175. package/dist/react-sdk/application-runtime/host-properties/actions.js +1 -0
  176. package/dist/react-sdk/application-runtime/host-properties/connect-host-properties.d.ts +30 -0
  177. package/dist/react-sdk/application-runtime/host-properties/connect-host-properties.js +1 -0
  178. package/dist/react-sdk/application-runtime/host-properties/domain-host-properties.d.ts +7 -0
  179. package/dist/react-sdk/application-runtime/host-properties/domain-host-properties.js +1 -0
  180. package/dist/react-sdk/application-runtime/host-properties/host-property-descriptors.d.ts +21 -0
  181. package/dist/react-sdk/application-runtime/host-properties/host-property-descriptors.js +1 -0
  182. package/dist/react-sdk/application-runtime/host-properties/host-property-scopes.d.ts +42 -0
  183. package/dist/react-sdk/application-runtime/host-properties/host-property-scopes.js +1 -0
  184. package/dist/react-sdk/application-runtime/host-properties/index.d.ts +8 -0
  185. package/dist/react-sdk/application-runtime/host-properties/index.js +1 -0
  186. package/dist/react-sdk/application-runtime/host-properties/initialize.d.ts +7 -0
  187. package/dist/react-sdk/application-runtime/host-properties/initialize.js +1 -0
  188. package/dist/react-sdk/application-runtime/host-properties/selectors.d.ts +54 -0
  189. package/dist/react-sdk/application-runtime/host-properties/selectors.js +1 -0
  190. package/dist/react-sdk/application-runtime/host-properties/types.d.ts +18 -0
  191. package/dist/react-sdk/application-runtime/host-properties/types.js +1 -0
  192. package/dist/react-sdk/application-runtime/index.d.ts +1 -0
  193. package/dist/react-sdk/application-runtime/mocks/create-mock-application-runtime.js +1 -1
  194. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +151 -9
  195. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.js +1 -1
  196. package/package.json +3 -3
  197. package/dist/phoenix/services/lingui.js +0 -1
  198. /package/dist/{application-spec/core → domain/spec/application}/application-instance.d.ts +0 -0
  199. /package/dist/{application-spec/core → domain/spec/application}/application-instance.js +0 -0
  200. /package/dist/{application-spec/core → domain/spec}/components/component-filter.js +0 -0
  201. /package/dist/{application-spec/core → domain/spec}/components/index.d.ts +0 -0
  202. /package/dist/{application-spec/core → domain/spec}/components/index.js +0 -0
  203. /package/dist/{application-spec/core → domain/spec}/components/sdk-code-ref.d.ts +0 -0
  204. /package/dist/{application-spec/core → domain/spec}/components/sdk-code-ref.js +0 -0
  205. /package/dist/{application-spec/core → domain/spec}/expressions/index.d.ts +0 -0
  206. /package/dist/{application-spec/core → domain/spec}/expressions/index.js +0 -0
  207. /package/dist/{application-spec/core → domain/spec}/expressions/relation-expression-params.d.ts +0 -0
  208. /package/dist/{application-spec/core → domain/spec}/expressions/relation-expression-params.js +0 -0
  209. /package/dist/{application-spec/core → domain/spec}/expressions/sdk-expression-implementation.d.ts +0 -0
  210. /package/dist/{application-spec/core → domain/spec}/expressions/sdk-expression-implementation.js +0 -0
  211. /package/dist/{application-spec/core → domain/spec}/markers/eval-marker.d.ts +0 -0
  212. /package/dist/{application-spec/core → domain/spec}/markers/eval-marker.js +0 -0
@@ -1,5 +1,5 @@
1
- import{mkdir as e}from"node:fs/promises";import{dirname as r}from"node:path";import{format as t}from"node:util";import{createServer as o}from"vite";import{resolveGeneratedEnvFile as s}from"@salsita-ai/common/env";import{generateProjectFiles as n}from"../application-spec/index.js";import{startEditorServer as i}from"../editor-server/index.js";import{getDevelopmentCredentialHint as a}from"../services/development-credential.js";import{ApplicationSpecProjectWatcher as l,LinguiWatcher as c,LogBus as p,MockTemplateWatcher as d,PhoenixApplication as u,PhoenixPubSub as m,PhoenixStore as w,VariantPreviewService as v,WebhookTunnelMonitor as g,createBusLogger as h,getViteDevConfig as f,patchConsole as E,setViteLogSink as b}from"../services/index.js";import{prepareDevelopmentEnvironment as S}from"../services/prepare-development-environment.js";import{createWebhookTunnelTransport as k,readOrCreateTunnelSessionId as I,startWebhookService as $}from"../services/webhook-service/index.js";import{startTui as x}from"../tui/index.js";import{FileLogger as j,createLogger as P,exists as R}from"../utils/index.js";import{buildWebhooks as T,setLogger as N,webhookLogContext as y}from"../webhooks/index.js";import{readGeneratedEnvMarkers as D}from"./generated-env-markers.js";export const runDevCommand=async(_,U)=>{let{logger:O}=U,{sdkVersion:L,projectSlug:M,environmentSlug:V,cliUseWorkspace:W,enableEditor:G,editorWsPort:Y,debug:C=!1,withLingui:H=!1,persistenceMode:B,force:X=!1,tui:q=!1,serverUrl:J,credential:Q,skipUpload:z}=_,A=null,F=null,K=null,Z=null,ee=null,er=null,et=null,eo=new j,es=new m,en=new p,ei=q&&!!process.stdout.isTTY&&!!process.stdin.isTTY,ea=!ei,el=null;q&&!ei&&O.warn("TUI requested but stdin/stdout is not an interactive terminal — falling back to plain log output. Run phoenix dev --tui directly in a terminal to use the TUI.");let ec=null,ep=O,ed=null,eu=async(t,o)=>{let n=s(".");await e(r(n),{recursive:!0}),await S({serverUrl:t.serverUrl,projectSlug:M,environmentSlug:V,credential:t.credential,outFile:n,skipUpload:o.skipUpload,overrideSchema:!0,debug:o.debug,projectVersion:L},{logger:ep})},em=()=>{el&&(el(),el=null),ec&&(ec.unmount(),ec=null,ep=P({debug:C,fileLogger:eo}))},ew=(e=0)=>ed||(ed=(async()=>{process.off("SIGINT",ev),process.off("SIGTERM",ev),process.off("uncaughtException",eg),em(),ep.debug("Shutting down...");let r=[];for(let e of[{name:"lingui watcher",close:()=>Z?.close()},{name:"project watcher",close:()=>er?.close()},{name:"mock template watcher",close:()=>ee?.close()},{name:"editor server",close:()=>K?.close()},{name:"variant previews",close:()=>et?.close()},{name:"vite server",close:()=>A?.close()},{name:"webhook tunnel",close:()=>F?.stop()}])try{ep.debug(`Shutting down ${e.name}`),await e.close()}catch(t){r.push(`${e.name}: ${t instanceof Error?t.message:String(t)}`)}r.length>0&&ep.warn(`Cleanup warnings:
2
- ${r.join("\n ")}`),ep.debug("Shutdown complete"),await eo.close(),process.exit(e)})()),ev=()=>{ew(0)},eg=e=>{em(),ep.error(`Uncaught exception: ${e.message}`),ew(1)};process.once("SIGINT",ev),process.once("SIGTERM",ev),process.once("uncaughtException",eg);try{await eo.init(".phoenix"),ep=h({bus:en,stream:"spec",debug:C,fileLogger:eo,echo:!0}),b((e,r)=>en.push("vite",e,r),{echo:ea}),N({transports:[],log:(e,...r)=>{en.push("webhook","warn"===e||"error"===e?e:"info",t(...r)),ea&&process.stdout.write(`${t(e,...r)}
3
- `)}}),es.browserConsole$.subscribe(e=>{en.push("browser",e.level,e.source?`[${e.source}] ${e.message}`:e.message);let r=`[${e.source?`browser:${e.source}`:"browser"}] ${e.message}`;eo.write("warn",r),ea&&process.stderr.write(`⚠️ ${r}
4
- `)}),ea&&(el=E(en,{echo:!0})),process.env.NODE_ENV="development",B&&(process.env.PERSISTENCE_MODE=B);let e=!B||"server"===B;e&&J&&(process.env.SERVER_URL=J);let r=e&&J?new g(J):void 0;if(ep.step("Starting development mode"),!await R("spec")){ep.error('Spec folder not found. Run "phoenix init" first.'),await ew(1);return}if(e){if(!J||!Q)throw Error("Server persistence needs a server and a credential. Run `phoenix login <workspace>`, or create a development environment in Studio and paste its .env block into .env.");let e=s("."),r=await D(e);r?.PHOENIX_PROJECT_SLUG!==M||r.PHOENIX_ENVIRONMENT_SLUG!==V||r.PHOENIX_SERVER_URL!==J?(ep.step("Preparing development deployment"),await eu({serverUrl:J,credential:Q},{skipUpload:z,debug:C})):ep.debug(`${e} matches the current development environment, skipping prepare`)}ep.step("Building project files");let{templateFiles:p}=await n({sdkVersion:L,projectSlug:M,environmentSlug:V,cliUseWorkspace:W,enableEditor:G,withLingui:H,force:X},{logger:ep});if(ep.success("Project files built successfully"),ei&&(ep=h({bus:en,stream:"spec",debug:C,fileLogger:eo}),el=E(en),ec=x(en,{onQuit:()=>void ew(0)})),H?(Z=new c({logger:ep})).start():ep.warn("Lingui is disabled: i18n messages are not extracted or compiled during dev. Pass --withLingui or set WITH_LINGUI=true to enable."),e&&(ep.step("Building webhooks"),await y.run("webhook",async()=>{await T({experimental:!0,skipNodeEnvOverride:!0,webhookEntryPoint:"./.phoenix/.swc/.phoenix/webhook.js"})})),e&&J&&Q){let e=s("."),t=await D(e);if(!t?.DEPLOYMENT_ID)throw Error(`Webhook tunnel cannot start because ${e} has no DEPLOYMENT_ID. Rerun phoenix dev to prepare the development deployment.`);let o=await I();F=await $({experimental:!0,transport:k({serverUrl:J,credential:Q,projectSlug:M,environmentSlug:V}),rejectionHint:a(Q,M),environmentSlug:V,deploymentId:t.DEPLOYMENT_ID,sessionId:o,onStatus:(e,s)=>{r?.setStatus(e,{deploymentId:t.DEPLOYMENT_ID,sessionId:o,message:s??null})},onRequest:e=>r?.record(e)}),r?.setStatus("waiting",{deploymentId:t.DEPLOYMENT_ID,sessionId:o}),F.stopped.catch(e=>{em(),ep.error(`Webhook tunnel failed: ${e instanceof Error?e.message:String(e)}`),ew(1)}),ep.success("Webhook tunnel started")}er=new l({pubsub:es,logger:ep,onRebuilt:()=>Z?.trigger(),onViteServerChange:e=>{A=e},sdkVersion:L,projectSlug:M,environmentSlug:V,cliUseWorkspace:W,enableEditor:G??!0,inlineTemplates:!1,useServer:e});let m=new w;if(et=new u({store:m,pubsub:es,variantPreviews:new v({projectRoot:process.cwd()},{store:m,logger:ep,projectWatcher:er})}),G&&Y){ep.step("Starting editor WebSocket server");let t=parseInt(Y,10);K=i({port:t,projectRoot:process.cwd(),application:et,logger:ep,logBus:en,tunnelMonitor:r,debug:C,prepareDeployment:e&&J&&Q?()=>eu({serverUrl:J,credential:Q},{skipUpload:!0,debug:!1}):void 0}),await K.ready,ep.debug(`Editor WebSocket server started on port ${t}`),(ee=new d({projectRoot:process.cwd(),pubsub:es,logger:ep})).start()}let S=await f({templateFiles:p});A=await o(S),await A.listen(),ep.step("Starting Vite dev server"),er.start(A);let j=A.resolvedUrls?.local[0];if(ei)ep.success("Vite dev server started — watching for changes"),j&&ep.info(`Preview: ${j}`),G&&Y&&ep.info(`Editor WebSocket: ws://localhost:${Y}`);else if(C)ep.success("Vite dev server started"),j&&ep.info(`Preview: ${j}`);else{let e=e=>{en.push("spec","info",e),process.stdout.write(`${e}
5
- `)};e("\n\uD83D\uDE80 Phoenix Dev Server\n"),j&&(e(`Preview: ${j}`),eo.write("info",`Preview: ${j}`)),G&&Y&&e(`Editor WebSocket: ws://localhost:${Y}`),e("\n\uD83D\uDC40 Watching for changes...\n")}}catch(e){em(),ep.error(`Dev mode failed: ${e instanceof Error?e.message:String(e)}`,e),await ew(1)}};
1
+ import{mkdir as e}from"node:fs/promises";import{dirname as t}from"node:path";import{format as r}from"node:util";import{createServer as o}from"vite";import{resolveGeneratedEnvFile as n}from"@salsita-ai/common/env";import{generateProjectFiles as s,getDeploymentFingerprint as i}from"../application-spec/index.js";import{startEditorServer as a}from"../editor-server/index.js";import{getDevelopmentCredentialHint as l}from"../services/development-credential.js";import{ApplicationSpecProjectWatcher as c,LinguiWatcher as p,LogBus as d,MockTemplateWatcher as u,PhoenixApplication as m,PhoenixPubSub as w,PhoenixStore as h,VariantPreviewService as g,WebhookTunnelMonitor as v,createBusLogger as f,getViteDevConfig as E,patchConsole as b,setViteLogSink as S}from"../services/index.js";import{prepareDevelopmentEnvironment as I}from"../services/prepare-development-environment.js";import{createWebhookTunnelTransport as P,readOrCreateTunnelSessionId as k,startWebhookService as N}from"../services/webhook-service/index.js";import{startTui as $}from"../tui/index.js";import{FileLogger as x,createLogger as y,exists as R}from"../utils/index.js";import{buildWebhooks as T,setLogger as j,webhookLogContext as _}from"../webhooks/index.js";import{readGeneratedEnvMarkers as D}from"./generated-env-markers.js";export const runDevCommand=async(O,L)=>{let{logger:U}=L,{sdkVersion:M,projectSlug:G,environmentSlug:V,cliUseWorkspace:W,enableEditor:Y,editorWsPort:C,debug:H=!1,withLingui:X=!1,persistenceMode:B,force:q=!1,tui:F=!1,serverUrl:A,credential:J,skipUpload:Q}=O,z=null,K=null,Z=null,ee=null,et=null,er=null,eo=null,en=new x,es=new w,ei=new d,ea=F&&!!process.stdout.isTTY&&!!process.stdin.isTTY,el=!ea,ec=null;F&&!ea&&U.warn("TUI requested but stdin/stdout is not an interactive terminal — falling back to plain log output. Run phoenix dev --tui directly in a terminal to use the TUI.");let ep=null,ed=U,eu=null,em=async(r,o)=>{let s=n(".");await e(t(s),{recursive:!0}),await I({serverUrl:r.serverUrl,projectSlug:G,environmentSlug:V,credential:r.credential,outFile:s,skipUpload:o.skipUpload,overrideSchema:!0,debug:o.debug,projectVersion:M},{logger:ed})},ew=null,eh=async e=>{try{let t=i(e),r=await D(n("."));if(!r||r.PHOENIX_DEPLOYMENT_FINGERPRINT===t){ew=null;return}if(ew===t)return;ew=t,ed.error("The development deployment on the server still has the domain model and deployment settings it was prepared with, not the ones the spec now declares: a running phoenix dev cannot register a change, because its webhook tunnel and the preview stay bound to the deployment they started with. Restart phoenix dev to prepare the deployment again, then open the Preview address it prints rather than reloading a tab whose address has ?cid=, which loads a configuration saved with the earlier model.")}catch(e){ed.warn(`Could not compare the spec with the development deployment: ${e instanceof Error?e.message:String(e)}. After a domain model change, restart phoenix dev to register it.`)}},eg=()=>{ec&&(ec(),ec=null),ep&&(ep.unmount(),ep=null,ed=y({debug:H,fileLogger:en}))},ev=(e=0)=>eu||(eu=(async()=>{process.off("SIGINT",ef),process.off("SIGTERM",ef),process.off("uncaughtException",eE),eg(),ed.debug("Shutting down...");let t=[];for(let e of[{name:"lingui watcher",close:()=>ee?.close()},{name:"project watcher",close:()=>er?.close()},{name:"mock template watcher",close:()=>et?.close()},{name:"editor server",close:()=>Z?.close()},{name:"variant previews",close:()=>eo?.close()},{name:"vite server",close:()=>z?.close()},{name:"webhook tunnel",close:()=>K?.stop()}])try{ed.debug(`Shutting down ${e.name}`),await e.close()}catch(r){t.push(`${e.name}: ${r instanceof Error?r.message:String(r)}`)}t.length>0&&ed.warn(`Cleanup warnings:
2
+ ${t.join("\n ")}`),ed.debug("Shutdown complete"),await en.close(),process.exit(e)})()),ef=()=>{ev(0)},eE=e=>{eg(),ed.error(`Uncaught exception: ${e.message}`),ev(1)};process.once("SIGINT",ef),process.once("SIGTERM",ef),process.once("uncaughtException",eE);try{await en.init(".phoenix"),ed=f({bus:ei,stream:"spec",debug:H,fileLogger:en,echo:!0}),S((e,t)=>ei.push("vite",e,t),{echo:el}),j({transports:[],log:(e,...t)=>{ei.push("webhook","warn"===e||"error"===e?e:"info",r(...t)),el&&process.stdout.write(`${r(e,...t)}
3
+ `)}}),es.browserConsole$.subscribe(e=>{ei.push("browser",e.level,e.source?`[${e.source}] ${e.message}`:e.message);let t=`[${e.source?`browser:${e.source}`:"browser"}] ${e.message}`;en.write("error"===e.level?"error":"warn",t),el&&process.stderr.write(`⚠️ ${t}
4
+ `)}),el&&(ec=b(ei,{echo:!0})),process.env.NODE_ENV="development",B&&(process.env.PERSISTENCE_MODE=B);let e=!B||"server"===B;e&&A&&(process.env.SERVER_URL=A);let t=e&&A?new v(A):void 0;if(ed.step("Starting development mode"),!await R("spec")){ed.error('Spec folder not found. Run "phoenix init" first.'),await ev(1);return}if(e&&(!A||!J))throw Error("Server persistence needs a server and a credential. Run `phoenix login <workspace>`, or create a development environment in Studio and paste its .env block into .env.");ed.step("Building project files");let{templateFiles:d,applicationSpec:w}=await s({sdkVersion:M,projectSlug:G,environmentSlug:V,cliUseWorkspace:W,enableEditor:Y,withLingui:X,force:q},{logger:ed});if(ed.success("Project files built successfully"),e&&A&&J){let e=n("."),t=await D(e);q||t?.PHOENIX_PROJECT_SLUG!==G||t.PHOENIX_ENVIRONMENT_SLUG!==V||t.PHOENIX_SERVER_URL!==A||t.PHOENIX_DEPLOYMENT_FINGERPRINT!==i(w)?(ed.step("Preparing development deployment"),await em({serverUrl:A,credential:J},{skipUpload:Q,debug:H})):ed.debug(`${e} matches the current development environment, skipping prepare`)}if(ea&&(ed=f({bus:ei,stream:"spec",debug:H,fileLogger:en}),ec=b(ei),ep=$(ei,{onQuit:()=>void ev(0)})),X?(ee=new p({logger:ed})).start():ed.warn("Continuous Lingui updates are disabled; missing catalogs were bootstrapped at startup. Pass --withLingui or set WITH_LINGUI=true to enable."),e&&(ed.step("Building webhooks"),await _.run("webhook",async()=>{await T({experimental:!0,skipNodeEnvOverride:!0,webhookEntryPoint:"./.phoenix/.swc/.phoenix/webhook.js"})})),e&&A&&J){let e=n("."),r=await D(e);if(!r?.DEPLOYMENT_ID)throw Error(`Webhook tunnel cannot start because ${e} has no DEPLOYMENT_ID. Rerun phoenix dev to prepare the development deployment.`);let o=await k();K=await N({experimental:!0,transport:P({serverUrl:A,credential:J,projectSlug:G,environmentSlug:V}),rejectionHint:l(J,G),environmentSlug:V,deploymentId:r.DEPLOYMENT_ID,sessionId:o,onStatus:(e,n)=>{t?.setStatus(e,{deploymentId:r.DEPLOYMENT_ID,sessionId:o,message:n??null})},onRequest:e=>t?.record(e)}),t?.setStatus("waiting",{deploymentId:r.DEPLOYMENT_ID,sessionId:o}),K.stopped.catch(e=>{eg(),ed.error(`Webhook tunnel failed: ${e instanceof Error?e.message:String(e)}`),ev(1)}),ed.success("Webhook tunnel started")}er=new c({pubsub:es,logger:ed,onRebuilt:t=>{ee?.trigger(),e&&eh(t)},onViteServerChange:e=>{z=e},sdkVersion:M,projectSlug:G,environmentSlug:V,cliUseWorkspace:W,enableEditor:Y??!0,inlineTemplates:!1,useServer:e});let I=new h;if(eo=new m({store:I,pubsub:es,variantPreviews:new g({projectRoot:process.cwd()},{store:I,logger:ed,projectWatcher:er})}),Y&&C){ed.step("Starting editor WebSocket server");let r=parseInt(C,10);Z=a({port:r,projectRoot:process.cwd(),application:eo,logger:ed,logBus:ei,tunnelMonitor:t,debug:H,prepareDeployment:e&&A&&J?()=>em({serverUrl:A,credential:J},{skipUpload:!0,debug:!1}):void 0}),await Z.ready,ed.debug(`Editor WebSocket server started on port ${r}`),(et=new u({projectRoot:process.cwd(),pubsub:es,logger:ed})).start()}let x=await E({templateFiles:d});z=await o(x),await z.listen(),ed.step("Starting Vite dev server"),er.start(z);let y=z.resolvedUrls?.local[0];if(ea)ed.success("Vite dev server started — watching for changes"),y&&ed.info(`Preview: ${y}`),Y&&C&&ed.info(`Editor WebSocket: ws://localhost:${C}`);else if(H)ed.success("Vite dev server started"),y&&ed.info(`Preview: ${y}`);else{let e=e=>{ei.push("spec","info",e),process.stdout.write(`${e}
5
+ `)};e("\n\uD83D\uDE80 Phoenix Dev Server\n"),y&&(e(`Preview: ${y}`),en.write("info",`Preview: ${y}`)),Y&&C&&e(`Editor WebSocket: ws://localhost:${C}`),e("\n\uD83D\uDC40 Watching for changes...\n")}}catch(e){eg(),ed.error(`Dev mode failed: ${e instanceof Error?e.message:String(e)}`,e),await ev(1)}};
@@ -3,5 +3,6 @@ export interface GeneratedEnvMarkers {
3
3
  readonly PHOENIX_PROJECT_SLUG?: string;
4
4
  readonly PHOENIX_ENVIRONMENT_SLUG?: string;
5
5
  readonly PHOENIX_SERVER_URL?: string;
6
+ readonly PHOENIX_DEPLOYMENT_FINGERPRINT?: string;
6
7
  }
7
8
  export declare const readGeneratedEnvMarkers: (outFile: string) => Promise<GeneratedEnvMarkers | null>;
@@ -1 +1 @@
1
- import{parse as E}from"dotenv";import{readFile as r}from"node:fs/promises";export const readGeneratedEnvMarkers=async e=>{try{let N=E(await r(e));return{DEPLOYMENT_ID:N.DEPLOYMENT_ID,PHOENIX_PROJECT_SLUG:N.PHOENIX_PROJECT_SLUG,PHOENIX_ENVIRONMENT_SLUG:N.PHOENIX_ENVIRONMENT_SLUG,PHOENIX_SERVER_URL:N.PHOENIX_SERVER_URL}}catch(E){if(E instanceof Error&&"code"in E&&"ENOENT"===E.code)return null;throw E}};
1
+ import{parse as E}from"dotenv";import{readFile as N}from"node:fs/promises";export const readGeneratedEnvMarkers=async r=>{try{let _=E(await N(r));return{DEPLOYMENT_ID:_.DEPLOYMENT_ID,PHOENIX_PROJECT_SLUG:_.PHOENIX_PROJECT_SLUG,PHOENIX_ENVIRONMENT_SLUG:_.PHOENIX_ENVIRONMENT_SLUG,PHOENIX_SERVER_URL:_.PHOENIX_SERVER_URL,PHOENIX_DEPLOYMENT_FINGERPRINT:_.PHOENIX_DEPLOYMENT_FINGERPRINT}}catch(E){if(E instanceof Error&&"code"in E&&"ENOENT"===E.code)return null;throw E}};
@@ -12,7 +12,7 @@ export { prepareDevelopmentEnvironment } from '../services/prepare-development-e
12
12
  export { prepareLocalEnvironment } from './prepare-local-environment-command.js';
13
13
  export { runFinishDeploymentCommand } from './finish-deployment-command.js';
14
14
  export { runDeploymentBuildEnvsCommand } from './deployment-build-envs-command.js';
15
- export { runDepsCommand } from './deps/index.js';
15
+ export { findSdkPeerMismatches, runDepsCommand } from './deps/index.js';
16
16
  export { runDevCommand } from './dev.js';
17
17
  export { runFixCommand } from './fix.js';
18
18
  export { runLinkCommand } from './link.js';
@@ -1 +1 @@
1
- export{runBuildCommand}from"./build.js";export{runCheckCommand}from"./check.js";export{runCleanCommand}from"./clean.js";export{runActivateDeploymentCommand}from"./activate-deployment.js";export{runCreateEnvironmentCommand}from"./create-environment.js";export{runCleanupEnvironmentCommand}from"./cleanup-environment.js";export{runListEnvironmentsCommand}from"./list-environments.js";export{runRegisterDeploymentCommand}from"./register-deployment.js";export{runPrepareDeploymentCommand}from"./prepare-deployment-command.js";export{prepareDevelopmentEnvironment}from"../services/prepare-development-environment.js";export{prepareLocalEnvironment}from"./prepare-local-environment-command.js";export{runFinishDeploymentCommand}from"./finish-deployment-command.js";export{runDeploymentBuildEnvsCommand}from"./deployment-build-envs-command.js";export{runDepsCommand}from"./deps/index.js";export{runDevCommand}from"./dev.js";export{runFixCommand}from"./fix.js";export{runLinkCommand}from"./link.js";export{runUnlinkCommand}from"./unlink.js";export{runPrepareCiCommand}from"./prepare-ci.js";export{runStoryCommand}from"./story.js";export{runStoryBuildCommand}from"./story-build.js";export{runStoryCreateCommand}from"./story-create.js";export{runStoryDevCommand}from"./story-dev.js";export{runInitCommand}from"./init.js";export{runSyncCommand}from"./sync.js";export{runChangelogCommand}from"./changelog.js";export{runDocsCommand}from"./docs.js";export{runInspectAssetsCommand}from"./inspect-assets.js";export{runScreenshotCommand}from"./screenshot.js";export{runStateCommand}from"./state.js";export{runDataCommand}from"./data.js";export{runSceneCommand}from"./scene.js";export{runVariantsCommand}from"./variants.js";export{runLoginCommand}from"./login.js";export{runLogoutCommand}from"./logout.js";export{runDeployCommand}from"./deploy.js";export{runFeedbackCommand}from"./feedback.js";export{runExtractSourcesCommand}from"./extract-sources-command.js";
1
+ export{runBuildCommand}from"./build.js";export{runCheckCommand}from"./check.js";export{runCleanCommand}from"./clean.js";export{runActivateDeploymentCommand}from"./activate-deployment.js";export{runCreateEnvironmentCommand}from"./create-environment.js";export{runCleanupEnvironmentCommand}from"./cleanup-environment.js";export{runListEnvironmentsCommand}from"./list-environments.js";export{runRegisterDeploymentCommand}from"./register-deployment.js";export{runPrepareDeploymentCommand}from"./prepare-deployment-command.js";export{prepareDevelopmentEnvironment}from"../services/prepare-development-environment.js";export{prepareLocalEnvironment}from"./prepare-local-environment-command.js";export{runFinishDeploymentCommand}from"./finish-deployment-command.js";export{runDeploymentBuildEnvsCommand}from"./deployment-build-envs-command.js";export{findSdkPeerMismatches,runDepsCommand}from"./deps/index.js";export{runDevCommand}from"./dev.js";export{runFixCommand}from"./fix.js";export{runLinkCommand}from"./link.js";export{runUnlinkCommand}from"./unlink.js";export{runPrepareCiCommand}from"./prepare-ci.js";export{runStoryCommand}from"./story.js";export{runStoryBuildCommand}from"./story-build.js";export{runStoryCreateCommand}from"./story-create.js";export{runStoryDevCommand}from"./story-dev.js";export{runInitCommand}from"./init.js";export{runSyncCommand}from"./sync.js";export{runChangelogCommand}from"./changelog.js";export{runDocsCommand}from"./docs.js";export{runInspectAssetsCommand}from"./inspect-assets.js";export{runScreenshotCommand}from"./screenshot.js";export{runStateCommand}from"./state.js";export{runDataCommand}from"./data.js";export{runSceneCommand}from"./scene.js";export{runVariantsCommand}from"./variants.js";export{runLoginCommand}from"./login.js";export{runLogoutCommand}from"./logout.js";export{runDeployCommand}from"./deploy.js";export{runFeedbackCommand}from"./feedback.js";export{runExtractSourcesCommand}from"./extract-sources-command.js";
@@ -0,0 +1 @@
1
+ export { LINGUI_CONFIG_PATH, bootstrapLinguiCatalogs, compileLingui, extractAndCompileLingui } from './lingui.js';
@@ -0,0 +1 @@
1
+ export{LINGUI_CONFIG_PATH,bootstrapLinguiCatalogs,compileLingui,extractAndCompileLingui}from"./lingui.js";
@@ -1,10 +1,11 @@
1
1
  import { type Logger } from '../utils/index.js';
2
2
  /**
3
3
  * The project's Lingui configuration, which sync generates, relative to the project root. The Lingui
4
- * CLI, the Lingui Vite plugin and the Lingui macros in the Vite builds are always given this path, so a
4
+ * CLI, the Lingui Vite plugin and the Lingui macros in the Vite builds are given this path, so a
5
5
  * `.linguirc` that earlier SDK versions left in the project root is not read. Lingui searches the
6
6
  * working directory instead only when the named file is missing; generation writes it with the rest of
7
- * `.phoenix/` before Phoenix runs Lingui or Vite.
7
+ * `.phoenix/` before Phoenix runs Lingui or Vite. Missing-catalog bootstrap compiles with a temporary
8
+ * copy that stages output while keeping every locale available for fallback reads.
8
9
  */
9
10
  export declare const LINGUI_CONFIG_PATH = ".phoenix/.linguirc";
10
11
  interface LinguiCommandContext {
@@ -12,4 +13,6 @@ interface LinguiCommandContext {
12
13
  }
13
14
  export declare const compileLingui: (context: LinguiCommandContext) => Promise<void>;
14
15
  export declare const extractAndCompileLingui: (context: LinguiCommandContext) => Promise<void>;
16
+ /** Creates only catalogs missing from a project's generated domain imports; continuous updates stay opt-in. */
17
+ export declare const bootstrapLinguiCatalogs: (locales: readonly string[], context: LinguiCommandContext) => Promise<void>;
15
18
  export {};
@@ -0,0 +1 @@
1
+ import{constants as i}from"node:fs";import{copyFile as a,mkdir as t,mkdtemp as e,readFile as o,rm as n,writeFile as s}from"node:fs/promises";import{dirname as r,join as l}from"node:path";import{exists as c,runSdkTool as g}from"../utils/index.js";export const LINGUI_CONFIG_PATH=".phoenix/.linguirc";let p=async i=>{await g({tool:{packageName:"@lingui/cli",binName:"lingui"},args:["extract","--config",LINGUI_CONFIG_PATH],description:"Extracting i18n messages",quiet:!0,extraEnv:{LC_ALL:"en_US.UTF-8"}},i)};export const compileLingui=async i=>{await g({tool:{packageName:"@lingui/cli",binName:"lingui"},args:["compile","--config",LINGUI_CONFIG_PATH],description:"Compiling i18n messages",quiet:!0},i)};export const extractAndCompileLingui=async i=>{await p(i),await compileLingui(i)};export const bootstrapLinguiCatalogs=async(p,m)=>{let u,f=(await Promise.all(p.map(async i=>await c(`src/locales/${i}/messages.ts`)?[]:[i]))).flat();if(0!==f.length)try{m.logger.info(`Bootstrapping missing i18n catalogs: ${f.join(", ")}`);let n=(await Promise.all(f.map(async i=>await c(`src/locales/${i}/messages.po`)?[]:[i]))).flat();n.length>0&&await g({tool:{packageName:"@lingui/cli",binName:"lingui"},args:["extract","--config",LINGUI_CONFIG_PATH,"--locale",n.join(",")],description:"Extracting missing i18n catalogs",quiet:!0,extraEnv:{LC_ALL:"en_US.UTF-8"}},m);let p=JSON.parse(await o(LINGUI_CONFIG_PATH,"utf-8"));if("object"!=typeof p||null===p||Array.isArray(p))throw Error(`${LINGUI_CONFIG_PATH} is not a configuration object`);u=await e(".phoenix/lingui-bootstrap-");let N=l(u,".linguirc");for(let e of(await s(N,JSON.stringify({...p,catalogsMergePath:l(u,"compiled","{locale}","messages").replaceAll("\\","/")})),await g({tool:{packageName:"@lingui/cli",binName:"lingui"},args:["compile","--config",N],description:"Compiling missing i18n catalogs",quiet:!0},m),f)){let o=l("src","locales",e,"messages.ts");await t(r(o),{recursive:!0}),await a(l(u,"compiled",e,"messages.ts"),o,i.COPYFILE_EXCL)}}catch(i){throw Error(`Cannot bootstrap i18n catalogs for ${f.join(", ")}: ${i instanceof Error?i.message:String(i)}. Fix the reported Lingui error and restart phoenix dev, or run phoenix sync to update all catalogs.`,{cause:i})}finally{void 0!==u&&await n(u,{recursive:!0,force:!0})}};
@@ -1,4 +1,5 @@
1
1
  import { type ViteDevServer } from 'vite';
2
+ import type { ApplicationSpec } from '#package/application-spec';
2
3
  import type { Logger } from '../utils/index.js';
3
4
  import type { PhoenixPubSub } from './phoenix-pubsub.js';
4
5
  import type { VariantFileEdit } from './variant-file-session.js';
@@ -8,7 +9,8 @@ export declare const IGNORED_PATTERNS: string[];
8
9
  export interface ApplicationSpecProjectWatcherConfig {
9
10
  readonly pubsub: PhoenixPubSub;
10
11
  readonly logger: Logger;
11
- readonly onRebuilt?: () => void;
12
+ /** Called with the application spec of every rebuild that succeeded. */
13
+ readonly onRebuilt?: (applicationSpec: ApplicationSpec) => void;
12
14
  readonly onViteServerChange?: (viteServer: ViteDevServer) => void;
13
15
  readonly sdkVersion: string;
14
16
  readonly projectSlug: string;
@@ -1,4 +1,4 @@
1
- import{mkdirSync as e}from"fs";import{resolve as t}from"path";import i from"promise-queue";import{Subject as s,buffer as r,debounceTime as o}from"rxjs";import{createServer as n,normalizePath as l}from"vite";import{watch as h}from"#package/watch";import{ApplicationSpecBuilder as a}from"../application-spec/application-spec-builder.js";import{logDiagnostics as c}from"../application-spec/metrics/index.js";import{syncTemplateFiles as u}from"../application-spec/template-files.js";import{buildWebhooks as p}from"../webhooks/index.js";import{getViteDevConfig as g}from"./vite-config.js";export const WATCH_PATTERNS=["spec/**/*.{yaml,yml}","src/**/*.{ts,tsx,yaml,yml,json,html,css}","templates/*.html",".env",".env.generated",".phoenix/.env.generated"];export const IGNORED_PATTERNS=["src/locales/**/*.{ts,tsx}",".phoenix/!(.env.generated)/**"];export class ApplicationSpecProjectWatcher{watcher=null;subscription=null;rebuildQueue=new i(1,1/0);changeSubject$=new s;viteServer=null;pubsub;logger;onRebuilt;onViteServerChange;builder;useServer;isShuttingDown=!1;suspended=!1;heldChanges=new Set;constructor(e){this.pubsub=e.pubsub,this.logger=e.logger,this.onRebuilt=e.onRebuilt,this.onViteServerChange=e.onViteServerChange,this.builder=new a({logger:e.logger,sdkVersion:e.sdkVersion,projectSlug:e.projectSlug,environmentSlug:e.environmentSlug,cliUseWorkspace:e.cliUseWorkspace,enableEditor:e.enableEditor,inlineTemplates:e.inlineTemplates}),this.useServer=e.useServer}start(e){this.viteServer=e,this.setupFileWatcher(),this.setupRebuildSubscription()}applyVariantFiles(e){this.rebuildQueue.add(async()=>{this.isShuttingDown||await this.rebuild(new Set(e.map(e=>e.fileName)),!1,!0)})}suspend(){this.suspended=!0}resume(){for(let e of(this.suspended=!1,this.heldChanges))this.changeSubject$.next(e);this.heldChanges.clear()}async close(){this.isShuttingDown=!0,this.watcher&&(await this.watcher.close(),this.watcher=null),this.subscription?.unsubscribe(),this.changeSubject$.complete()}setupFileWatcher(){e(t(process.cwd(),"src"),{recursive:!0}),this.watcher=h(WATCH_PATTERNS,{ignored:IGNORED_PATTERNS,cwd:process.cwd(),persistent:!0,ignoreInitial:!1}),this.watcher.on("all",(e,t)=>{if("change"===e||"add"===e||"unlink"===e){if(this.suspended)return void this.heldChanges.add(t);this.logger.info(`
1
+ import{mkdirSync as e}from"fs";import{resolve as t}from"path";import i from"promise-queue";import{Subject as s,buffer as r,debounceTime as o}from"rxjs";import{createServer as n,normalizePath as l}from"vite";import{watch as a}from"#package/watch";import{ApplicationSpecBuilder as h}from"../application-spec/application-spec-builder.js";import{logDiagnostics as c}from"../application-spec/metrics/index.js";import{syncTemplateFiles as u}from"../application-spec/template-files.js";import{buildWebhooks as p}from"../webhooks/index.js";import{getViteDevConfig as g}from"./vite-config.js";export const WATCH_PATTERNS=["spec/**/*.{yaml,yml}","src/**/*.{ts,tsx,yaml,yml,json,html,css}","templates/*.html",".env",".env.generated",".phoenix/.env.generated"];export const IGNORED_PATTERNS=["src/locales/**/*.{ts,tsx}",".phoenix/!(.env.generated)/**"];export class ApplicationSpecProjectWatcher{watcher=null;subscription=null;rebuildQueue=new i(1,1/0);changeSubject$=new s;viteServer=null;pubsub;logger;onRebuilt;onViteServerChange;builder;useServer;isShuttingDown=!1;suspended=!1;heldChanges=new Set;constructor(e){this.pubsub=e.pubsub,this.logger=e.logger,this.onRebuilt=e.onRebuilt,this.onViteServerChange=e.onViteServerChange,this.builder=new h({logger:e.logger,sdkVersion:e.sdkVersion,projectSlug:e.projectSlug,environmentSlug:e.environmentSlug,cliUseWorkspace:e.cliUseWorkspace,enableEditor:e.enableEditor,inlineTemplates:e.inlineTemplates}),this.useServer=e.useServer}start(e){this.viteServer=e,this.setupFileWatcher(),this.setupRebuildSubscription()}applyVariantFiles(e){this.rebuildQueue.add(async()=>{this.isShuttingDown||await this.rebuild(new Set(e.map(e=>e.fileName)),!1,!0)})}suspend(){this.suspended=!0}resume(){for(let e of(this.suspended=!1,this.heldChanges))this.changeSubject$.next(e);this.heldChanges.clear()}async close(){this.isShuttingDown=!0,this.watcher&&(await this.watcher.close(),this.watcher=null),this.subscription?.unsubscribe(),this.changeSubject$.complete()}setupFileWatcher(){e(t(process.cwd(),"src"),{recursive:!0}),this.watcher=a(WATCH_PATTERNS,{ignored:IGNORED_PATTERNS,cwd:process.cwd(),persistent:!0,ignoreInitial:!1}),this.watcher.on("all",(e,t)=>{if("change"===e||"add"===e||"unlink"===e){if(this.suspended)return void this.heldChanges.add(t);this.logger.info(`
2
2
  📝 Detected ${e}: ${t}`),this.changeSubject$.next(t)}})}setupRebuildSubscription(){let e=this.changeSubject$.pipe(o(10));this.subscription=this.changeSubject$.pipe(r(e)).subscribe(e=>{let t=new Set(e),i=t.has(".env");this.rebuildQueue.add(async()=>{this.isShuttingDown||(this.logger.info(`
3
3
  🔨 Rebuilding spec files...
4
- `),await this.rebuild(t,i,!1))})})}async rebuild(e,i,s){try{let r=this.viteServer;if(!r)throw Error("Cannot rebuild the project: the watcher has no Vite server yet, because it was not started. Start the watcher before applying files");let o=await u();if(this.isShuttingDown)return;let h=await this.builder.build({compile:!s});if(this.isShuttingDown)return;if(c(h.diagnostics,this.logger),!h.ok){for(let e of h.errors)this.logger.error(`[${e.code}] ${e.message}${e.file?` (${e.file})`:""}`);this.pubsub.specFile$.next({rawProjectFiles:h.rawProjectFiles,projectRoot:process.cwd()});return}this.onRebuilt?.();let{application:a,changedFiles:d}=h,w=r.moduleGraph,b=Date.now(),f=new Set,S=process.cwd(),m=e=>{let t=w.getModulesByFile(l(e));if(t)for(let e of t)w.invalidateModule(e,f,b,!0)};for(let i of e)m(t(S,i));for(let e of d)m(t(S,`.phoenix/${e.path}`));if(this.pubsub.specFile$.next({rawProjectFiles:a.rawProjectFiles,projectRoot:process.cwd(),configurationSchemaHash:a.applicationSpec.configurator.configurationSchema.hash}),this.isShuttingDown)return;if(i){if(await r.close(),this.isShuttingDown)return;let e=await g({templateFiles:o});if(this.isShuttingDown)return;let t=await n(e);if(this.isShuttingDown||(await t.listen(),this.isShuttingDown))return void await t.close();this.viteServer=t,this.onViteServerChange?.(t),this.logger.success("Vite server restarted (env changed)")}if(this.useServer&&!s){if(this.logger.step("Building webhooks"),await p({experimental:!0,skipNodeEnvOverride:!0,webhookEntryPoint:"./.phoenix/.swc/.phoenix/webhook.js",preserveExistingOutput:!0}),this.isShuttingDown)return;this.logger.success("Webhooks rebuilt successfully")}this.logger.success("Project files rebuilt successfully")}catch(e){this.logger.error(`Build failed: ${e instanceof Error?e.message:String(e)}`,e)}}}
4
+ `),await this.rebuild(t,i,!1))})})}async rebuild(e,i,s){try{let r=this.viteServer;if(!r)throw Error("Cannot rebuild the project: the watcher has no Vite server yet, because it was not started. Start the watcher before applying files");let o=await u();if(this.isShuttingDown)return;let a=await this.builder.build({compile:!s});if(this.isShuttingDown)return;if(c(a.diagnostics,this.logger),!a.ok){for(let e of a.errors)this.logger.error(`[${e.code}] ${e.message}${e.file?` (${e.file})`:""}`);this.pubsub.specFile$.next({rawProjectFiles:a.rawProjectFiles,projectRoot:process.cwd()});return}let{application:h,changedFiles:d}=a;this.onRebuilt?.(h.applicationSpec);let w=r.moduleGraph,b=Date.now(),f=new Set,S=process.cwd(),m=e=>{let t=w.getModulesByFile(l(e));if(t)for(let e of t)w.invalidateModule(e,f,b,!0)};for(let i of e)m(t(S,i));for(let e of d)m(t(S,`.phoenix/${e.path}`));if(this.pubsub.specFile$.next({rawProjectFiles:h.rawProjectFiles,projectRoot:process.cwd(),configurationSchemaHash:h.applicationSpec.configurator.configurationSchema.hash}),this.isShuttingDown)return;if(i){if(await r.close(),this.isShuttingDown)return;let e=await g({templateFiles:o});if(this.isShuttingDown)return;let t=await n(e);if(this.isShuttingDown||(await t.listen(),this.isShuttingDown))return void await t.close();this.viteServer=t,this.onViteServerChange?.(t),this.logger.success("Vite server restarted (env changed)")}if(this.useServer&&!s){if(this.logger.step("Building webhooks"),await p({experimental:!0,skipNodeEnvOverride:!0,webhookEntryPoint:"./.phoenix/.swc/.phoenix/webhook.js",preserveExistingOutput:!0}),this.isShuttingDown)return;this.logger.success("Webhooks rebuilt successfully")}this.logger.success("Project files rebuilt successfully")}catch(e){this.logger.error(`Build failed: ${e instanceof Error?e.message:String(e)}`,e)}}}
@@ -8,6 +8,7 @@ export { MockTemplateWatcher, type MockTemplateWatcherConfig } from './mock-temp
8
8
  export { ApplicationSpecProjectWatcher, type ApplicationSpecProjectWatcherConfig, } from './application-spec-project-watcher.js';
9
9
  export { ApplicationSpecStoryWatcher, type ApplicationSpecStoryWatcherConfig, } from './application-spec-story-watcher.js';
10
10
  export { LinguiWatcher, type LinguiWatcherConfig } from './lingui-watcher.js';
11
+ export { bootstrapLinguiCatalogs, extractAndCompileLingui } from '../lingui/index.js';
11
12
  export { loadMockTemplates, parseMockTemplateYaml, type LoadMockTemplatesResult, type ParsedMockTemplate, } from './spec-files.js';
12
13
  export { LOG_STREAMS, LogBus, type LogEntry, type LogLevel, type LogPage, type LogQuery, type LogStream, } from './log-bus.js';
13
14
  export { createBusLogger, type CreateBusLoggerOptions } from './bus-logger.js';
@@ -1 +1 @@
1
- export{PhoenixPubSub}from"./phoenix-pubsub.js";export{PhoenixStore}from"./phoenix-store.js";export{PhoenixApplication}from"./phoenix-application.js";export{VariantFileSession}from"./variant-file-session.js";export{VariantPreviewService}from"./variant-preview-service.js";export{MockTemplateWatcher}from"./mock-template-watcher.js";export{ApplicationSpecProjectWatcher}from"./application-spec-project-watcher.js";export{ApplicationSpecStoryWatcher}from"./application-spec-story-watcher.js";export{LinguiWatcher}from"./lingui-watcher.js";export{loadMockTemplates,parseMockTemplateYaml}from"./spec-files.js";export{LOG_STREAMS,LogBus}from"./log-bus.js";export{createBusLogger}from"./bus-logger.js";export{patchConsole}from"./console-capture.js";export{WebhookTunnelMonitor}from"./webhook-tunnel-monitor.js";export{compileWithSwc,watchWithSwc}from"./swc.js";export{STORY_DEV_MARKER_PATH,readActiveStoryDevMarker}from"./story-dev-marker.js";export{composeDefaultBanner}from"./phx-banner-plugin.js";export{getViteBuildConfigs,getViteDevConfig,setViteLogSink}from"./vite-config.js";export{getServerCredentials,removeServerCredentials,saveServerCredentials}from"./cli-credentials.js";export{createSourceArchive,extractSourceArchive}from"./source-archive.js";export{resolveSignedInDevelopmentEnvironment}from"./signed-in-development-environment.js";export{DEFAULT_PHOENIX_REGION,PHOENIX_REGIONS,PUBLIC_PHOENIX_REGIONS,getRegionServerUrl,getRegionStudioUrl}from"./phoenix-regions.js";
1
+ export{PhoenixPubSub}from"./phoenix-pubsub.js";export{PhoenixStore}from"./phoenix-store.js";export{PhoenixApplication}from"./phoenix-application.js";export{VariantFileSession}from"./variant-file-session.js";export{VariantPreviewService}from"./variant-preview-service.js";export{MockTemplateWatcher}from"./mock-template-watcher.js";export{ApplicationSpecProjectWatcher}from"./application-spec-project-watcher.js";export{ApplicationSpecStoryWatcher}from"./application-spec-story-watcher.js";export{LinguiWatcher}from"./lingui-watcher.js";export{bootstrapLinguiCatalogs,extractAndCompileLingui}from"../lingui/index.js";export{loadMockTemplates,parseMockTemplateYaml}from"./spec-files.js";export{LOG_STREAMS,LogBus}from"./log-bus.js";export{createBusLogger}from"./bus-logger.js";export{patchConsole}from"./console-capture.js";export{WebhookTunnelMonitor}from"./webhook-tunnel-monitor.js";export{compileWithSwc,watchWithSwc}from"./swc.js";export{STORY_DEV_MARKER_PATH,readActiveStoryDevMarker}from"./story-dev-marker.js";export{composeDefaultBanner}from"./phx-banner-plugin.js";export{getViteBuildConfigs,getViteDevConfig,setViteLogSink}from"./vite-config.js";export{getServerCredentials,removeServerCredentials,saveServerCredentials}from"./cli-credentials.js";export{createSourceArchive,extractSourceArchive}from"./source-archive.js";export{resolveSignedInDevelopmentEnvironment}from"./signed-in-development-environment.js";export{DEFAULT_PHOENIX_REGION,PHOENIX_REGIONS,PUBLIC_PHOENIX_REGIONS,getRegionServerUrl,getRegionStudioUrl}from"./phoenix-regions.js";
@@ -1 +1 @@
1
- import e from"promise-queue";import{Subject as t,buffer as i,debounceTime as s}from"rxjs";import{watch as r}from"#package/watch";import{compileLingui as n,extractAndCompileLingui as o}from"./lingui.js";let c=["src/**/*.{ts,tsx}","src/locales/**/*.po"],g=["src/locales/**/*.{ts,tsx}"];export class LinguiWatcher{watcher=null;subscription=null;runQueue=new e(1,1/0);changeSubject$=new t;logger;isShuttingDown=!1;constructor(e){this.logger=e.logger}start(){this.setupFileWatcher(),this.setupRunSubscription()}trigger(){this.changeSubject$.next("<codegen-rebuild>")}async close(){this.isShuttingDown=!0,this.watcher&&(await this.watcher.close(),this.watcher=null),this.subscription?.unsubscribe(),this.changeSubject$.complete()}setupFileWatcher(){this.watcher=r(c,{ignored:g,cwd:process.cwd(),ignoreInitial:!0,persistent:!0}),this.watcher.on("all",(e,t)=>{("change"===e||"add"===e||"unlink"===e)&&(this.logger.debug(`Lingui source ${e}: ${t}`),this.changeSubject$.next(t))}).on("error",e=>{this.logger.error(`Lingui watcher error: ${e instanceof Error?e.message:String(e)}`,e)})}setupRunSubscription(){let e=this.changeSubject$.pipe(s(200));this.subscription=this.changeSubject$.pipe(i(e)).subscribe(e=>{let t=e.some(e=>!e.endsWith(".po"));this.runQueue.add(async()=>{if(!this.isShuttingDown)try{t?(this.logger.info("Lingui sources changed, extracting and compiling i18n messages..."),await o({logger:this.logger})):(this.logger.info("Lingui catalogs changed, compiling i18n messages..."),await n({logger:this.logger}))}catch(e){this.logger.error(`Lingui update failed: ${e instanceof Error?e.message:String(e)}`,e)}})})}}
1
+ import e from"promise-queue";import{Subject as i,buffer as t,debounceTime as s}from"rxjs";import{watch as r}from"#package/watch";import{compileLingui as n,extractAndCompileLingui as o}from"../lingui/index.js";let c=["src/**/*.{ts,tsx}","src/locales/**/*.po"],g=["src/locales/**/*.{ts,tsx}"];export class LinguiWatcher{watcher=null;subscription=null;runQueue=new e(1,1/0);changeSubject$=new i;logger;isShuttingDown=!1;constructor(e){this.logger=e.logger}start(){this.setupFileWatcher(),this.setupRunSubscription()}trigger(){this.changeSubject$.next("<codegen-rebuild>")}async close(){this.isShuttingDown=!0,this.watcher&&(await this.watcher.close(),this.watcher=null),this.subscription?.unsubscribe(),this.changeSubject$.complete()}setupFileWatcher(){this.watcher=r(c,{ignored:g,cwd:process.cwd(),ignoreInitial:!0,persistent:!0}),this.watcher.on("all",(e,i)=>{("change"===e||"add"===e||"unlink"===e)&&(this.logger.debug(`Lingui source ${e}: ${i}`),this.changeSubject$.next(i))}).on("error",e=>{this.logger.error(`Lingui watcher error: ${e instanceof Error?e.message:String(e)}`,e)})}setupRunSubscription(){let e=this.changeSubject$.pipe(s(200));this.subscription=this.changeSubject$.pipe(t(e)).subscribe(e=>{let i=e.some(e=>!e.endsWith(".po"));this.runQueue.add(async()=>{if(!this.isShuttingDown)try{i?(this.logger.info("Lingui sources changed, extracting and compiling i18n messages..."),await o({logger:this.logger})):(this.logger.info("Lingui catalogs changed, compiling i18n messages..."),await n({logger:this.logger}))}catch(e){this.logger.error(`Lingui update failed: ${e instanceof Error?e.message:String(e)}`,e)}})})}}
@@ -1,2 +1,2 @@
1
- import{writeFile as e}from"node:fs/promises";import{createApiBaseClient as i}from"#package/client";import{resolveApplicationSpecDeploymentData as t}from"../application-spec/index.js";import{formatEnvContent as r,uploadFilesWithPresignedUrls as a}from"../utils/index.js";import{getDevelopmentCredentialHint as o,getDevelopmentHeaders as s}from"./development-credential.js";export const prepareDevelopmentEnvironment=async(n,l)=>{let{logger:p}=l,{projectSlug:d,environmentSlug:m,serverUrl:c,credential:h,outFile:v,skipUpload:f,overrideSchema:u,projectVersion:g}=n;p.step("Preparing development environment"),p.info(`Preparing development environment for project "${d}", environment "${m}"`);let E=i(c);p.debug(`Using server URL: ${c}`);let b=await t({skipUpload:f,logger:p});p.info("Preparing and activating the development deployment on the server...");let{data:P,error:$}=await E.POST("/environments/development/prepare",{body:{applicationVersion:b.applicationVersion,publishedDataHash:b.publishedDataHash,useAuthHook:b.useAuthHook,overrideSchema:u,configurationSchema:{version:b.schemaVersion,schema:b.schema},adminConfigurationSchema:b.adminSchema?{schema:b.adminSchema,version:b.adminSchemaVersion}:void 0,chat:b.chat,embeddings:b.embeddings,...b.assistant?{assistant:!0}:{},acl:{canCreate:b.aclCanCreate},privateFiles:[...b.assets.privateFilePaths],publicFiles:[...b.assets.publicFilePaths],sdkVersion:g},headers:s(h,{projectSlug:d,environmentSlug:m})});if($)throw Error(`Failed to prepare development deployment for ${d}/${m} on ${c}: ${$.message}. ${o(h,d)}`);if(!P)throw Error("No data returned from server while preparing the development deployment.");let{environmentVariables:y,privateUploadUrls:w,publicUploadUrls:F}=P;if(f)p.debug("Skipping file upload");else{p.info("Uploading files to S3...");let e={privateFiles:[...b.assets.privateFilesFullPaths].map(e=>{let i=e.replace("assets/private/",""),t=w[i];if(!t)throw Error(`No upload URL provided for private file ${i}, the server did not return a presigned URL for this file, please verify the file exists in the assets/private directory.`);return{localPath:e,uploadUrl:t}}),publicFiles:[...b.assets.publicFilesFullPaths].map(e=>{let i=e.replace("assets/public/",""),t=F[i];if(!t)throw Error(`No upload URL provided for public file ${i}, the server did not return a presigned URL for this file, please verify the file exists in the assets/public directory.`);return{localPath:e,uploadUrl:t}})};await a(e,{logger:p})}try{await e(v,`${r({...y,PHOENIX_PROJECT_SLUG:d,PHOENIX_ENVIRONMENT_SLUG:m,PHOENIX_SERVER_URL:c})}
1
+ import{writeFile as e}from"node:fs/promises";import{createApiBaseClient as i}from"#package/client";import{resolveApplicationSpecDeploymentData as t}from"../application-spec/index.js";import{formatEnvContent as r,uploadFilesWithPresignedUrls as a}from"../utils/index.js";import{getDevelopmentCredentialHint as o,getDevelopmentHeaders as s}from"./development-credential.js";export const prepareDevelopmentEnvironment=async(n,l)=>{let{logger:p}=l,{projectSlug:d,environmentSlug:m,serverUrl:c,credential:h,outFile:v,skipUpload:f,overrideSchema:u,projectVersion:E}=n;p.step("Preparing development environment"),p.info(`Preparing development environment for project "${d}", environment "${m}"`);let g=i(c);p.debug(`Using server URL: ${c}`);let P=await t({skipUpload:f,logger:p});p.info("Preparing and activating the development deployment on the server...");let{data:b,error:$}=await g.POST("/environments/development/prepare",{body:{applicationVersion:P.applicationVersion,publishedDataHash:P.publishedDataHash,useAuthHook:P.useAuthHook,overrideSchema:u,configurationSchema:{version:P.schemaVersion,schema:P.schema},adminConfigurationSchema:P.adminSchema?{schema:P.adminSchema,version:P.adminSchemaVersion}:void 0,chat:P.chat,embeddings:P.embeddings,...P.assistant?{assistant:!0}:{},acl:{canCreate:P.aclCanCreate},privateFiles:[...P.assets.privateFilePaths],publicFiles:[...P.assets.publicFilePaths],sdkVersion:E},headers:s(h,{projectSlug:d,environmentSlug:m})});if($)throw Error(`Failed to prepare development deployment for ${d}/${m} on ${c}: ${$.message}. ${o(h,d)}`);if(!b)throw Error("No data returned from server while preparing the development deployment.");let{environmentVariables:y,privateUploadUrls:N,publicUploadUrls:w}=b;if(f)p.debug("Skipping file upload");else{p.info("Uploading files to S3...");let e={privateFiles:[...P.assets.privateFilesFullPaths].map(e=>{let i=e.replace("assets/private/",""),t=N[i];if(!t)throw Error(`No upload URL provided for private file ${i}, the server did not return a presigned URL for this file, please verify the file exists in the assets/private directory.`);return{localPath:e,uploadUrl:t}}),publicFiles:[...P.assets.publicFilesFullPaths].map(e=>{let i=e.replace("assets/public/",""),t=w[i];if(!t)throw Error(`No upload URL provided for public file ${i}, the server did not return a presigned URL for this file, please verify the file exists in the assets/public directory.`);return{localPath:e,uploadUrl:t}})};await a(e,{logger:p})}try{await e(v,`${r({...y,PHOENIX_PROJECT_SLUG:d,PHOENIX_ENVIRONMENT_SLUG:m,PHOENIX_SERVER_URL:c,PHOENIX_DEPLOYMENT_FINGERPRINT:P.fingerprint})}
2
2
  `),p.debug(`Environment variables written to ${v}`)}catch{throw Error(`Failed to write environment variables to file at ${v}, please verify you have write permissions to this location.`)}p.info(`Project: ${d}`),p.info(`Environment: ${m}`),p.info(`Deployment ID: ${y.DEPLOYMENT_ID}`),p.success("Development environment prepared successfully!")};
@@ -1 +1 @@
1
- import{getConfig as e}from"@lingui/conf";import{lingui as i}from"@lingui/vite-plugin";import t from"@vitejs/plugin-react";import{mkdir as n,readFile as r,writeFile as o}from"fs/promises";import a from"lodash-es/camelCase.js";import{createRequire as s}from"node:module";import{dirname as l,resolve as m}from"path";import{createLogger as f}from"vite";import p from"vite-plugin-css-injected-by-js";import{isUsingLocalSdk as d}from"../utils/package-info.js";import{loadFrontendConfigModule as c}from"./frontend-config.js";import{LINGUI_CONFIG_PATH as g}from"./lingui.js";import{phxBannerPlugin as u}from"./phx-banner-plugin.js";import{phxCspNoncePlugin as h}from"./phx-csp-nonce-plugin.js";import{phxGlobalIsolationPlugin as b}from"./phx-global-isolation-plugin.js";import{phxLicensesPlugin as S}from"./phx-licenses-plugin.js";import{phxVariantPreviewsPlugin as y}from"./phx-variant-previews-plugin.js";let O=null;export const setViteLogSink=(e,i={})=>{O={sink:e,echo:i.echo??!1}};let x=["react","react-dom","three","@react-three/fiber","@react-three/drei","@react-three/postprocessing","its-fine","@emotion/react","@emotion/styled","@mui/material","@mui/system","@tanstack/react-query","rxjs"],D=()=>[s(import.meta.url).resolve("@lingui/babel-plugin-lingui-macro"),{linguiConfig:e({configPath:g})}],E=e=>{let i=e.DEPLOYMENT_ID;if("string"!=typeof i)throw Error("DEPLOYMENT_ID is required in runtime config");return i};export const getViteDevConfig=async e=>{var n,r;let o,a,p=d(),u=c(),h=u.readRuntimeConfig(),S=u.frontendBuildConfig,v=D(),j=Object.fromEntries((e?.templateFiles??[]).map(e=>[e,`.phoenix/${e}`]));return{...O&&{customLogger:(n=O.sink,r=O.echo,o=f(),{get hasWarned(){return o.hasWarned},info:(e,i)=>{n("info",e),r&&o.info(e,i)},warn:(e,i)=>{n("warn",e),r&&o.warn(e,i)},warnOnce:(e,i)=>{n("warn",e),r&&o.warnOnce(e,i)},error:(e,i)=>{n("error",e),r&&o.error(e,i)},clearScreen:e=>{r&&o.clearScreen(e)},hasErrorLogged:e=>o.hasErrorLogged(e)}),...O.echo?{}:{clearScreen:!1}},mode:"development",optimizeDeps:{exclude:["@swc/wasm-web"],...p&&{entries:["index.html","admin.html",...e?.templateFiles??[]],force:!0}},...p&&{resolve:{alias:(a=s(m(process.cwd(),"package.json")),x.flatMap(e=>{try{let i=l(a.resolve(`${e}/package.json`));return[{find:RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(/|$)`),replacement:`${i}$1`}]}catch{return[]}}))}},plugins:[t({babel:{plugins:[v]}}),i({configPath:g}),{name:"vite:runtime-config",apply:(e,i)=>"build"===i.command||"development"===i.mode,config:e=>{let i=u.readRuntimeConfig(),t=u.frontendBuildConfig;return{...e,define:{...e.define,"phx.frontendEnv":JSON.stringify(i),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(t.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(t.gltfDecoder)}}}},b({getDeploymentId:()=>E(u.readRuntimeConfig())}),y()],define:{"process.env":{},"import.meta.env.DEV":!0,"import.meta.env.PROD":!1,"phx.frontendEnv":JSON.stringify(h),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(S.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(S.gltfDecoder)},build:{rollupOptions:{input:{index:".phoenix/index.html",admin:".phoenix/admin.html",...j}}},root:m(process.cwd(),"./.phoenix"),server:{watch:{ignored:["./**/*.{ts,tsx}","./.swc/**","../spec/**","../src/**"]}}}};export const getViteBuildConfigs=async e=>{let s=c(),f=s.readRuntimeConfig(),d=s.frontendBuildConfig,y=D(),O=S(),x=u({sdkVersion:e.sdkVersion,banner:e.banner}),v=[{name:"salsita-configurator",entryFile:"./configurator.ts",mainScriptPath:"./configurator.ts",htmlFiles:["./index.html",...{templateFiles:e.templateFiles}.templateFiles],main:!0,format:"iife"},{name:"salsita-admin",entryFile:"./admin.ts",mainScriptPath:"./admin.ts",htmlFiles:["./admin.html"],main:!1,format:"iife"},{name:"salsita-embedded-admin",entryFile:"./embedded-admin.ts",mainScriptPath:"./embedded-admin.ts",htmlFiles:[],main:!1,format:"es"},{name:"salsita-embedded-configurator",entryFile:"./embedded-configurator.ts",mainScriptPath:"./embedded-configurator.ts",htmlFiles:[],main:!1,format:"es"}].map(c=>({plugins:[t({babel:{plugins:[y]}}),i({configPath:g}),p({useStrictCSP:!0}),h(),b({getDeploymentId:()=>E(s.readRuntimeConfig())}),{name:"vite:lib-index",writeBundle:async()=>{if(!c.htmlFiles.length)return;let i="iife"===c.format?`${c.name}.iife.js`:`${c.name}.js`;for(let t of c.htmlFiles){if(c.main&&e.enableEditor&&"./index.html"===t)continue;let a=m("./.phoenix",t),s=m("./.phoenix/dist/frontend",t);await n(l(s),{recursive:!0});let f=(await r(a,"utf-8")).replace(c.mainScriptPath,i);await o(s,f,"utf-8")}}},O,x],build:{outDir:"./dist/frontend",chunkSizeWarningLimit:4e3,lib:{entry:c.entryFile,name:a(c.name),formats:[c.format],fileName:()=>"iife"===c.format?`${c.name}.iife.js`:`${c.name}.js`},rollupOptions:{external:[],output:{assetFileNames:`${c.name}.[ext]`}},minify:!0,emptyOutDir:!1},root:m(process.cwd(),"./.phoenix"),define:{"process.env":{},"process.env.NODE_ENV":JSON.stringify("production"),"phx.frontendEnv":JSON.stringify(f),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(d.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(d.gltfDecoder)}}));return e.enableEditor?[...v,{plugins:[t({babel:{plugins:[y]}}),i({configPath:g}),p({useStrictCSP:!0}),h(),O,x],build:{outDir:"./dist/frontend",chunkSizeWarningLimit:4e3,rollupOptions:{external:[]},minify:!0,emptyOutDir:!1},root:m(process.cwd(),"./.phoenix"),define:{"process.env":{},"process.env.NODE_ENV":JSON.stringify("production"),"phx.frontendEnv":JSON.stringify(f),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(d.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(d.gltfDecoder)}}]:v};
1
+ import{getConfig as e}from"@lingui/conf";import{lingui as i}from"@lingui/vite-plugin";import t from"@vitejs/plugin-react";import{mkdir as n,readFile as r,writeFile as o}from"fs/promises";import a from"lodash-es/camelCase.js";import{createRequire as s}from"node:module";import{dirname as l,resolve as m}from"path";import{createLogger as f}from"vite";import p from"vite-plugin-css-injected-by-js";import{LINGUI_CONFIG_PATH as d}from"../lingui/index.js";import{isUsingLocalSdk as c}from"../utils/package-info.js";import{loadFrontendConfigModule as g}from"./frontend-config.js";import{phxBannerPlugin as u}from"./phx-banner-plugin.js";import{phxCspNoncePlugin as h}from"./phx-csp-nonce-plugin.js";import{phxGlobalIsolationPlugin as b}from"./phx-global-isolation-plugin.js";import{phxLicensesPlugin as S}from"./phx-licenses-plugin.js";import{phxVariantPreviewsPlugin as y}from"./phx-variant-previews-plugin.js";let O=null;export const setViteLogSink=(e,i={})=>{O={sink:e,echo:i.echo??!1}};let x=["react","react-dom","three","@react-three/fiber","@react-three/drei","@react-three/postprocessing","its-fine","@emotion/react","@emotion/styled","@mui/material","@mui/system","@tanstack/react-query","rxjs"],D=()=>[s(import.meta.url).resolve("@lingui/babel-plugin-lingui-macro"),{linguiConfig:e({configPath:d})}],E=e=>{let i=e.DEPLOYMENT_ID;if("string"!=typeof i)throw Error("DEPLOYMENT_ID is required in runtime config");return i};export const getViteDevConfig=async e=>{var n,r;let o,a,p=c(),u=g(),h=u.readRuntimeConfig(),S=u.frontendBuildConfig,v=D(),j=Object.fromEntries((e?.templateFiles??[]).map(e=>[e,`.phoenix/${e}`]));return{...O&&{customLogger:(n=O.sink,r=O.echo,o=f(),{get hasWarned(){return o.hasWarned},info:(e,i)=>{n("info",e),r&&o.info(e,i)},warn:(e,i)=>{n("warn",e),r&&o.warn(e,i)},warnOnce:(e,i)=>{n("warn",e),r&&o.warnOnce(e,i)},error:(e,i)=>{n("error",e),r&&o.error(e,i)},clearScreen:e=>{r&&o.clearScreen(e)},hasErrorLogged:e=>o.hasErrorLogged(e)}),...O.echo?{}:{clearScreen:!1}},mode:"development",optimizeDeps:{exclude:["@swc/wasm-web"],...p&&{entries:["index.html","admin.html",...e?.templateFiles??[]],force:!0}},...p&&{resolve:{alias:(a=s(m(process.cwd(),"package.json")),x.flatMap(e=>{try{let i=l(a.resolve(`${e}/package.json`));return[{find:RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(/|$)`),replacement:`${i}$1`}]}catch{return[]}}))}},plugins:[t({babel:{plugins:[v]}}),i({configPath:d}),{name:"vite:runtime-config",apply:(e,i)=>"build"===i.command||"development"===i.mode,config:e=>{let i=u.readRuntimeConfig(),t=u.frontendBuildConfig;return{...e,define:{...e.define,"phx.frontendEnv":JSON.stringify(i),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(t.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(t.gltfDecoder)}}}},b({getDeploymentId:()=>E(u.readRuntimeConfig())}),y()],define:{"process.env":{},"import.meta.env.DEV":!0,"import.meta.env.PROD":!1,"phx.frontendEnv":JSON.stringify(h),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(S.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(S.gltfDecoder)},build:{rollupOptions:{input:{index:".phoenix/index.html",admin:".phoenix/admin.html",...j}}},root:m(process.cwd(),"./.phoenix"),server:{watch:{ignored:["./**/*.{ts,tsx}","./.swc/**","../spec/**","../src/**"]}}}};export const getViteBuildConfigs=async e=>{let s=g(),f=s.readRuntimeConfig(),c=s.frontendBuildConfig,y=D(),O=S(),x=u({sdkVersion:e.sdkVersion,banner:e.banner}),v=[{name:"salsita-configurator",entryFile:"./configurator.ts",mainScriptPath:"./configurator.ts",htmlFiles:["./index.html",...{templateFiles:e.templateFiles}.templateFiles],main:!0,format:"iife"},{name:"salsita-admin",entryFile:"./admin.ts",mainScriptPath:"./admin.ts",htmlFiles:["./admin.html"],main:!1,format:"iife"},{name:"salsita-embedded-admin",entryFile:"./embedded-admin.ts",mainScriptPath:"./embedded-admin.ts",htmlFiles:[],main:!1,format:"es"},{name:"salsita-embedded-configurator",entryFile:"./embedded-configurator.ts",mainScriptPath:"./embedded-configurator.ts",htmlFiles:[],main:!1,format:"es"}].map(g=>({plugins:[t({babel:{plugins:[y]}}),i({configPath:d}),p({useStrictCSP:!0}),h(),b({getDeploymentId:()=>E(s.readRuntimeConfig())}),{name:"vite:lib-index",writeBundle:async()=>{if(!g.htmlFiles.length)return;let i="iife"===g.format?`${g.name}.iife.js`:`${g.name}.js`;for(let t of g.htmlFiles){if(g.main&&e.enableEditor&&"./index.html"===t)continue;let a=m("./.phoenix",t),s=m("./.phoenix/dist/frontend",t);await n(l(s),{recursive:!0});let f=(await r(a,"utf-8")).replace(g.mainScriptPath,i);await o(s,f,"utf-8")}}},O,x],build:{outDir:"./dist/frontend",chunkSizeWarningLimit:4e3,lib:{entry:g.entryFile,name:a(g.name),formats:[g.format],fileName:()=>"iife"===g.format?`${g.name}.iife.js`:`${g.name}.js`},rollupOptions:{external:[],output:{assetFileNames:`${g.name}.[ext]`}},minify:!0,emptyOutDir:!1},root:m(process.cwd(),"./.phoenix"),define:{"process.env":{},"process.env.NODE_ENV":JSON.stringify("production"),"phx.frontendEnv":JSON.stringify(f),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(c.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(c.gltfDecoder)}}));return e.enableEditor?[...v,{plugins:[t({babel:{plugins:[y]}}),i({configPath:d}),p({useStrictCSP:!0}),h(),O,x],build:{outDir:"./dist/frontend",chunkSizeWarningLimit:4e3,rollupOptions:{external:[]},minify:!0,emptyOutDir:!1},root:m(process.cwd(),"./.phoenix"),define:{"process.env":{},"process.env.NODE_ENV":JSON.stringify("production"),"phx.frontendEnv":JSON.stringify(f),"globalThis.PHX_SCHEMA_VALIDATOR":JSON.stringify(c.jsonSchemaValidator),"globalThis.PHX_GLTF_DECODER":JSON.stringify(c.gltfDecoder)}}]:v};
@@ -17,5 +17,5 @@ export declare const CommonAnalyticsFactory: {
17
17
  Initialized: typeof Initialized;
18
18
  ConfigurationLoaded: typeof ConfigurationLoaded;
19
19
  };
20
- export declare const initializeAnalyticsService: (config: AnyApplicationConfig, logger: Logger, isDev: boolean) => AnalyticsSystem;
20
+ export declare const initializeAnalyticsService: (config: Pick<AnyApplicationConfig, 'services' | 'defaultEnvs'>, logger: Logger, isDev: boolean) => AnalyticsSystem;
21
21
  export {};
@@ -2,6 +2,6 @@ import type { I18n } from '@lingui/core';
2
2
  import { QueryClient } from '@tanstack/react-query';
3
3
  import { type Logger } from '@salsita-ai/common/utils';
4
4
  import type { AnyApplicationConfig } from '#package/domain';
5
- export declare const initializeLogger: (config: AnyApplicationConfig, isDev: boolean) => Logger;
6
- export declare const initializeI18n: (config: AnyApplicationConfig) => I18n;
5
+ export declare const initializeLogger: (config: Pick<AnyApplicationConfig, 'services' | 'defaultEnvs' | 'version'>, isDev: boolean) => Logger;
6
+ export declare const initializeI18n: (config: Pick<AnyApplicationConfig, 'services'>) => I18n;
7
7
  export declare const createQueryClient: (logger: Logger) => QueryClient;
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{createContext as s,useContext as c,useMemo as o}from"react";import{standardWebComponentProperties as r}from"#package/domain";import{useApplicationRuntime as t,useApplicationType as i}from"../provider/index.js";import{ApplicationType as n}from"../runtime/index.js";import{useApplicationRuntimeSelector as a}from"./use-application-runtime-selector.js";import{useWebComponentPropertyValue as d}from"./use-web-component.js";let u=s(null);export const AccessServiceProvider=s=>e(u.Provider,{value:s.value,children:s.children});export const useProvidedAccessService=()=>{let e=c(u);if(null===e)throw Error("Access service not found! Render access-dependent hooks inside AccessServiceProvider.");return e};export const useAccessService=()=>{let e=i(),s=t(),c=useProvidedAccessService(),u=e===n.Admin,m=a(u?s.selectors.domainContext.admin.getIsViewMode:s.selectors.domainContext.configurator.getIsViewMode),f=d(r.readonly),p=m||u&&f;return o(()=>({...c,accessInfo:{...c.accessInfo,viewMode:p}}),[c,p])};export const useConfigurationId=()=>useProvidedAccessService().configurationId;export const useConfiguratorRawAccessService=()=>a(t().selectors.access.getConfiguratorRawAccessService);export const useAdminRawAccessService=()=>a(t().selectors.access.getAdminRawAccessService);export const useConfiguratorRawAccessInfo=()=>a(t().selectors.access.getConfiguratorRawAccessInfo);export const useAdminRawAccessInfo=()=>a(t().selectors.access.getAdminRawAccessInfo);export const useAccessInfoActions=()=>t().actions.access;
1
+ import{jsx as e}from"react/jsx-runtime";import{createContext as s,useContext as c,useMemo as o}from"react";import{useApplicationRuntime as r,useApplicationType as t}from"../provider/index.js";import{ApplicationType as i}from"../runtime/index.js";import{useApplicationRuntimeSelector as n}from"./use-application-runtime-selector.js";let a=s(null);export const AccessServiceProvider=s=>e(a.Provider,{value:s.value,children:s.children});export const useProvidedAccessService=()=>{let e=c(a);if(null===e)throw Error("Access service not found! Render access-dependent hooks inside AccessServiceProvider.");return e};export const useAccessService=()=>{let e=t(),s=r(),c=useProvidedAccessService(),a=n(e===i.Admin?s.selectors.domainContext.admin.getIsViewMode:s.selectors.domainContext.configurator.getIsViewMode);return o(()=>({...c,accessInfo:{...c.accessInfo,viewMode:a}}),[c,a])};export const useConfigurationId=()=>useProvidedAccessService().configurationId;export const useConfiguratorRawAccessService=()=>n(r().selectors.access.getConfiguratorRawAccessService);export const useAdminRawAccessService=()=>n(r().selectors.access.getAdminRawAccessService);export const useConfiguratorRawAccessInfo=()=>n(r().selectors.access.getConfiguratorRawAccessInfo);export const useAdminRawAccessInfo=()=>n(r().selectors.access.getAdminRawAccessInfo);export const useAccessInfoActions=()=>r().actions.access;
@@ -1,15 +1,8 @@
1
1
  /**
2
- * Mirrors the host's `readonly` web-component property into runtime state, where the domain reads it
3
- * as part of the effective mode.
2
+ * Does nothing. The application runtime mirrors the host's `readonly` web-component property into
3
+ * runtime state itself, from its construction on, so no component has to.
4
4
  *
5
- * Call it once at the application root. The configurator does; the admin application deliberately
6
- * does not, because `readonly` is a property of the custom element a host embeds and admin is not
7
- * embedded that way.
8
- *
9
- * Root placement means a domain lifecycle mounting in the same commit can initialize before the
10
- * first value lands, since React runs child effects before parent effects. That is harmless: nothing
11
- * reads the effective mode while initializing — persistence reads it per save request, and the
12
- * domain context picks a later change up through the expression context, whose identity `reconcile`
13
- * compares on every runtime notification.
5
+ * @deprecated The runtime keeps `readonly` in sync without it; remove the call. This hook will be
6
+ * removed in a future version.
14
7
  */
15
8
  export declare const useWebComponentReadonlySync: () => void;
@@ -1 +1 @@
1
- import{useEffect as e}from"react";import{standardWebComponentProperties as o}from"#package/domain";import{useApplicationRuntime as r}from"../provider/index.js";import{useWebComponentProperty$ as n}from"./use-web-component.js";export const useWebComponentReadonlySync=()=>{let t=r(),m=n(o.readonly);e(()=>{let e=m.subscribe(t.actions.webComponent.setReadonly);return()=>{e.unsubscribe()}},[t,m])};
1
+ export const useWebComponentReadonlySync=()=>{};
@@ -7,6 +7,11 @@ export declare const useWebComponentApi: () => WebComponentApi;
7
7
  export declare function useWebComponentProperty$<T>(property: WebComponentPropertyDescriptor<T>): BehaviorSubject<T>;
8
8
  export declare function useWebComponentPropertySetter<T>(property: WebComponentPropertyDescriptor<T>): Dispatch<SetStateAction<T>>;
9
9
  export declare const useWebComponentPropertyState: <T>(property: WebComponentPropertyDescriptor<T>) => [value: T, setValue: Dispatch<SetStateAction<T>>];
10
+ /**
11
+ * The property's current value; re-renders when it changes. A standard property the runtime
12
+ * mirrors is read from the slice its scope names, `hostProperties` or the domain's `webComponent`;
13
+ * any other property from its storage.
14
+ */
10
15
  export declare const useWebComponentPropertyValue: <T>(property: WebComponentPropertyDescriptor<T>) => T;
11
16
  export declare const useDispatchWebComponentEvent: <T, R>(event: WebComponentEventDescriptor<T, R>) => (payload: T) => Promise<R | undefined>;
12
17
  export declare const useWebcomponentGeneration: () => number;
@@ -1 +1 @@
1
- import{useCallback as e}from"react";import{useEagerObservableValue as o}from"../../domain-context/common-hooks/use-observable-selector.js";import{useApplicationRuntime as t}from"../provider/index.js";import{useApplicationRuntimeSelector as n}from"./use-application-runtime-selector.js";export const useWebComponentOptions=()=>t().selectors.commonServices.getWebComponentOptions();export const useWebComponentApi=()=>t().selectors.commonServices.getWebComponentApi();export function useWebComponentProperty$(e){return useWebComponentApi().getPropertyStorage(e).subject}export function useWebComponentPropertySetter(o){let t=useWebComponentProperty$(o);return e(e=>{let o="function"==typeof e?e(t.value):e;o!==t.value&&t.next(o)},[t])}export const useWebComponentPropertyState=e=>{let t=useWebComponentProperty$(e),n=useWebComponentPropertySetter(e);return[o(t),n]};export const useWebComponentPropertyValue=e=>o(useWebComponentProperty$(e));export const useDispatchWebComponentEvent=o=>{let t=useWebComponentApi();return e(async e=>t.dispatchEvent(o,e),[o,t])};export const useWebcomponentGeneration=()=>n(t().selectors.webComponent.getWebcomponentGeneration);
1
+ import{useCallback as e}from"react";import{useEagerObservableValue as o}from"../../domain-context/common-hooks/use-observable-selector.js";import{findMirroredHostPropertyReader as t}from"../host-properties/index.js";import{useApplicationRuntime as n}from"../provider/index.js";import{useApplicationRuntimeSelector as r}from"./use-application-runtime-selector.js";export const useWebComponentOptions=()=>n().selectors.commonServices.getWebComponentOptions();export const useWebComponentApi=()=>n().selectors.commonServices.getWebComponentApi();export function useWebComponentProperty$(e){return useWebComponentApi().getPropertyStorage(e).subject}export function useWebComponentPropertySetter(o){let t=useWebComponentProperty$(o);return e(e=>{let o="function"==typeof e?e(t.value):e;o!==t.value&&t.next(o)},[t])}export const useWebComponentPropertyState=e=>[useWebComponentPropertyValue(e),useWebComponentPropertySetter(e)];export const useWebComponentPropertyValue=e=>{let p=n(),s=useWebComponentProperty$(e),m=t(e),u=o(s,null===m);return r(()=>null===m?u:m(p.selectors))};export const useDispatchWebComponentEvent=o=>{let t=useWebComponentApi();return e(async e=>t.dispatchEvent(o,e),[o,t])};export const useWebcomponentGeneration=()=>r(n().selectors.webComponent.getWebcomponentGeneration);
@@ -0,0 +1,15 @@
1
+ import type { HostPropertyName } from './host-property-scopes.js';
2
+ import type { HostPropertiesState, HostPropertyValue } from './types.js';
3
+ interface Context {
4
+ readonly setHostProperties: (update: (state: HostPropertiesState) => HostPropertiesState) => void;
5
+ }
6
+ /**
7
+ * Internal to the runtime: only the subscription `connectHostProperties` sets up calls these. The
8
+ * runtime does not expose them on `actions`, because the host writes properties through the
9
+ * element.
10
+ */
11
+ export declare const createHostPropertiesActions: (context: Context) => {
12
+ setHostProperty: <NAME extends HostPropertyName>(name: NAME, value: HostPropertyValue<NAME>) => void;
13
+ };
14
+ export type HostPropertiesActions = ReturnType<typeof createHostPropertiesActions>;
15
+ export {};
@@ -0,0 +1 @@
1
+ import{isShallowEqual as t}from"@salsita-ai/common/utils";export const createHostPropertiesActions=o=>{let{setHostProperties:r}=o;return{setHostProperty:(o,e)=>{r(r=>t(r[o],e)?r:{...r,[o]:e})}}};
@@ -0,0 +1,30 @@
1
+ import type { WebComponentHostActions, WebComponentSelectors } from '#package/domain';
2
+ import type { WebComponentApi } from '../web-component/index.js';
3
+ import type { HostPropertiesActions } from './actions.js';
4
+ interface Context {
5
+ readonly webComponentApi: WebComponentApi;
6
+ readonly actions: HostPropertiesActions;
7
+ /** The domain's `webComponent` slice, which keeps the domain-scoped properties. */
8
+ readonly domainSelectors: WebComponentSelectors;
9
+ readonly domainActions: WebComponentHostActions;
10
+ }
11
+ /**
12
+ * The runtime-owned subscription behind the mirrored host properties: mirrors each mirrored
13
+ * property storage of the element into the slice its scope names, the application-scoped ones
14
+ * into `hostProperties` and the domain-scoped ones into the domain's `webComponent`. Either slice
15
+ * publishes only when a value changes, equal meaning shallowly equal.
16
+ *
17
+ * The runtime calls it once, right after its subject exists, and keeps it for its whole lifetime,
18
+ * as long as the element that owns the storages. The storages are `BehaviorSubject`s, so the first
19
+ * emissions replay the values the slices were initialized with and publish nothing, except a
20
+ * domain-scoped property the host set before the runtime existed. The admin application gets the
21
+ * domain-scoped properties too: its element never sets `readonly`, so the value stays `false`.
22
+ *
23
+ * Interim: the element's property storages are still the store and these slices a read mirror,
24
+ * so every mirrored value is held twice. CON-3142 makes the slice the only store (the element's
25
+ * setters and attribute parsing write it) and removes the storages and this subscription.
26
+ *
27
+ * @returns the unsubscribe, for tests and runtimes that end before their element.
28
+ */
29
+ export declare const connectHostProperties: (context: Context) => (() => void);
30
+ export {};
@@ -0,0 +1 @@
1
+ import{isShallowEqual as r}from"@salsita-ai/common/utils";import{getDomainHostProperty as o,setDomainHostProperty as t}from"./domain-host-properties.js";import{hostPropertyDescriptors as s}from"./host-property-descriptors.js";import{domainHostPropertyNames as e,hostPropertyNames as p}from"./host-property-scopes.js";export const connectHostProperties=i=>{let{webComponentApi:m,actions:c,domainSelectors:a,domainActions:b}=i,u=[...p.map(r=>m.getPropertyStorage(s[r]).subject.subscribe(o=>{c.setHostProperty(r,o)})),...e.map(e=>m.getPropertyStorage(s[e]).subject.subscribe(s=>{r(o(a,e),s)||t(b,e,s)}))];return()=>{u.forEach(r=>{r.unsubscribe()})}};
@@ -0,0 +1,7 @@
1
+ import type { WebComponentHostActions, WebComponentSelectors } from '#package/domain';
2
+ import type { DomainHostPropertyName } from './host-property-scopes.js';
3
+ import type { HostPropertyValue } from './types.js';
4
+ /** A domain-scoped property's current value in the domain's `webComponent` slice. */
5
+ export declare const getDomainHostProperty: <NAME extends DomainHostPropertyName>(selectors: WebComponentSelectors, name: NAME) => HostPropertyValue<NAME>;
6
+ /** Writes a domain-scoped property into the domain's `webComponent` slice. */
7
+ export declare const setDomainHostProperty: <NAME extends DomainHostPropertyName>(actions: WebComponentHostActions, name: NAME, value: HostPropertyValue<NAME>) => void;
@@ -0,0 +1 @@
1
+ let e={readonly:{get:e=>e.getReadonly(),set:(e,t)=>{e.setReadonly(t)}},locale:{get:e=>e.getLocale(),set:(e,t)=>{e.setLocale(t)}}};export const getDomainHostProperty=(t,o)=>e[o].get(t);export const setDomainHostProperty=(t,o,s)=>{e[o].set(t,s)};
@@ -0,0 +1,21 @@
1
+ import { type WebComponentPropertyDescriptor, type WebComponentSelectors } from '#package/domain';
2
+ import { type MirroredHostPropertyName } from './host-property-scopes.js';
3
+ import type { HostPropertiesSelectors } from './selectors.js';
4
+ import type { HostPropertyValue } from './types.js';
5
+ export declare const hostPropertyDescriptors: {
6
+ readonly [NAME in MirroredHostPropertyName]: WebComponentPropertyDescriptor<HostPropertyValue<NAME>>;
7
+ };
8
+ /** The runtime selectors of the two slices that keep mirrored properties. */
9
+ interface MirroredHostPropertySelectors {
10
+ readonly hostProperties: HostPropertiesSelectors;
11
+ readonly webComponent: WebComponentSelectors;
12
+ }
13
+ /** Reads a mirrored property's current value from the slice its scope names. */
14
+ export type MirroredHostPropertyReader<T> = (selectors: MirroredHostPropertySelectors) => T;
15
+ /**
16
+ * The reader of the mirrored property a descriptor stands for, or `null` when the runtime does not
17
+ * mirror it. The map keys each reader by its own descriptor, so a reader returns its descriptor's
18
+ * value type; a `Map` cannot state that per entry, so the overload states it once here.
19
+ */
20
+ export declare function findMirroredHostPropertyReader<T>(descriptor: WebComponentPropertyDescriptor<T>): MirroredHostPropertyReader<T> | null;
21
+ export {};
@@ -0,0 +1 @@
1
+ import{standardWebComponentProperties as e}from"#package/domain";import{getDomainHostProperty as o}from"./domain-host-properties.js";import{domainHostPropertyNames as r,hostPropertyNames as t}from"./host-property-scopes.js";export const hostPropertyDescriptors={route:e.route,expanded:e.expanded,mode:e.mode,power:e.power,presetTags:e.presetTags,locale:e.locale,readonly:e.readonly,integrationMode:e.integrationMode,sessionToken:e.sessionToken,adminSessionToken:e.adminSessionToken,refreshToken:e.refreshToken,authorizationCode:e.authorizationCode};let s=new Map([...t.map(e=>[hostPropertyDescriptors[e],o=>o.hostProperties.getHostProperty(e)]),...r.map(e=>[hostPropertyDescriptors[e],r=>o(r.webComponent,e)])]);export function findMirroredHostPropertyReader(e){return s.get(e)??null}
@@ -0,0 +1,42 @@
1
+ import { standardWebComponentProperties } from '#package/domain';
2
+ /**
3
+ * Where the runtime keeps a standard web-component property's current value:
4
+ * - `element`: only on the element, read from its property storage.
5
+ * - `application`: mirrored into the application runtime's `hostProperties` slice.
6
+ * - `domain`: mirrored into the domain runtime's `webComponent` slice, for domain systems that
7
+ * read it without the application runtime.
8
+ */
9
+ type HostPropertyScope = 'element' | 'application' | 'domain';
10
+ type StandardPropertyName = keyof typeof standardWebComponentProperties;
11
+ declare const hostPropertyScopes: {
12
+ readonly readonly: 'domain';
13
+ readonly locale: 'domain';
14
+ readonly route: 'application';
15
+ readonly expanded: 'application';
16
+ readonly mode: 'application';
17
+ readonly power: 'application';
18
+ readonly presetTags: 'application';
19
+ readonly integrationMode: 'application';
20
+ readonly sessionToken: 'application';
21
+ readonly adminSessionToken: 'application';
22
+ readonly refreshToken: 'application';
23
+ readonly authorizationCode: 'application';
24
+ readonly onEvent: 'element';
25
+ readonly onAttached: 'element';
26
+ readonly nonce: 'element';
27
+ readonly modalZIndex: 'element';
28
+ readonly containerZIndex: 'element';
29
+ readonly htmlFontSize: 'element';
30
+ };
31
+ type ScopedPropertyName<SCOPE extends HostPropertyScope> = {
32
+ [NAME in StandardPropertyName]: (typeof hostPropertyScopes)[NAME] extends SCOPE ? NAME : never;
33
+ }[StandardPropertyName];
34
+ /** The name of a standard web-component property the runtime mirrors into `hostProperties`. */
35
+ export type HostPropertyName = ScopedPropertyName<'application'>;
36
+ /** The name of a standard web-component property the runtime mirrors into the domain's `webComponent`. */
37
+ export type DomainHostPropertyName = ScopedPropertyName<'domain'>;
38
+ /** The name of a standard web-component property the runtime mirrors, into either slice. */
39
+ export type MirroredHostPropertyName = HostPropertyName | DomainHostPropertyName;
40
+ export declare const hostPropertyNames: ScopedPropertyName<"application">[];
41
+ export declare const domainHostPropertyNames: ScopedPropertyName<"domain">[];
42
+ export {};
@@ -0,0 +1 @@
1
+ import{standardWebComponentProperties as e}from"#package/domain";let o={readonly:"domain",locale:"domain",route:"application",expanded:"application",mode:"application",power:"application",presetTags:"application",integrationMode:"application",sessionToken:"application",adminSessionToken:"application",refreshToken:"application",authorizationCode:"application",onEvent:"element",onAttached:"element",nonce:"element",modalZIndex:"element",containerZIndex:"element",htmlFontSize:"element"},n=e=>n=>o[n]===e,t=Object.keys(e).filter(o=>Object.hasOwn(e,o));export const hostPropertyNames=t.filter(n("application"));export const domainHostPropertyNames=t.filter(n("domain"));
@@ -0,0 +1,8 @@
1
+ export * from './actions.js';
2
+ export * from './connect-host-properties.js';
3
+ export * from './domain-host-properties.js';
4
+ export * from './host-property-descriptors.js';
5
+ export * from './host-property-scopes.js';
6
+ export * from './initialize.js';
7
+ export * from './selectors.js';
8
+ export type * from './types.js';
@@ -0,0 +1 @@
1
+ export*from"./actions.js";export*from"./connect-host-properties.js";export*from"./domain-host-properties.js";export*from"./host-property-descriptors.js";export*from"./host-property-scopes.js";export*from"./initialize.js";export*from"./selectors.js";
@@ -0,0 +1,7 @@
1
+ import type { WebComponentApi } from '../web-component/index.js';
2
+ import type { HostPropertiesState } from './types.js';
3
+ /**
4
+ * The element's current property values. Without a web component the API's storages hold the
5
+ * defaults, so the slice does too.
6
+ */
7
+ export declare const initializeHostProperties: (webComponentApi: WebComponentApi) => HostPropertiesState;
@@ -0,0 +1 @@
1
+ import{hostPropertyDescriptors as e}from"./host-property-descriptors.js";export const initializeHostProperties=o=>{let r=r=>o.getPropertyValue(e[r]);return{route:r("route"),expanded:r("expanded"),mode:r("mode"),power:r("power"),presetTags:r("presetTags"),integrationMode:r("integrationMode"),sessionToken:r("sessionToken"),adminSessionToken:r("adminSessionToken"),refreshToken:r("refreshToken"),authorizationCode:r("authorizationCode")}};
@@ -0,0 +1,54 @@
1
+ import { type Selector } from '@salsita-ai/common/utils';
2
+ import type { HostPropertyName } from './host-property-scopes.js';
3
+ import type { HostPropertiesState } from './types.js';
4
+ export interface HostPropertiesSelectorState {
5
+ readonly hostProperties: HostPropertiesState;
6
+ }
7
+ interface Context {
8
+ readonly getState: () => HostPropertiesSelectorState;
9
+ }
10
+ type HostPropertySelectors = {
11
+ readonly [NAME in HostPropertyName]: Selector<HostPropertiesSelectorState, HostPropertiesState[NAME]>;
12
+ };
13
+ export declare const createHostPropertiesSelectors: (context: Context) => {
14
+ getHostPropertySelector: <NAME extends HostPropertyName>(name: NAME) => HostPropertySelectors[NAME];
15
+ selectRoute: Selector<HostPropertiesSelectorState, {
16
+ route: "Index";
17
+ } | {
18
+ route: "Configuration";
19
+ configurationId: string;
20
+ accessToken?: string | undefined;
21
+ } | {
22
+ readonly route: "Index";
23
+ }>;
24
+ selectExpanded: Selector<HostPropertiesSelectorState, boolean>;
25
+ selectMode: Selector<HostPropertiesSelectorState, "admin" | "configurator" | "standalone-admin">;
26
+ selectPower: Selector<HostPropertiesSelectorState, "off" | "on" | "standby">;
27
+ selectPresetTags: Selector<HostPropertiesSelectorState, string[] | null>;
28
+ selectIntegrationMode: Selector<HostPropertiesSelectorState, "handoff" | "headless" | "page" | "widget">;
29
+ selectSessionToken: Selector<HostPropertiesSelectorState, string | undefined>;
30
+ selectAdminSessionToken: Selector<HostPropertiesSelectorState, string | undefined>;
31
+ selectRefreshToken: Selector<HostPropertiesSelectorState, string | undefined>;
32
+ selectAuthorizationCode: Selector<HostPropertiesSelectorState, string | undefined>;
33
+ getHostProperty: <NAME extends HostPropertyName>(name: NAME) => HostPropertiesState[NAME];
34
+ getRoute: () => {
35
+ route: "Index";
36
+ } | {
37
+ route: "Configuration";
38
+ configurationId: string;
39
+ accessToken?: string | undefined;
40
+ } | {
41
+ readonly route: "Index";
42
+ };
43
+ getExpanded: () => boolean;
44
+ getMode: () => "admin" | "configurator" | "standalone-admin";
45
+ getPower: () => "off" | "on" | "standby";
46
+ getPresetTags: () => string[] | null;
47
+ getIntegrationMode: () => "handoff" | "headless" | "page" | "widget";
48
+ getSessionToken: () => string | undefined;
49
+ getAdminSessionToken: () => string | undefined;
50
+ getRefreshToken: () => string | undefined;
51
+ getAuthorizationCode: () => string | undefined;
52
+ };
53
+ export type HostPropertiesSelectors = ReturnType<typeof createHostPropertiesSelectors>;
54
+ export {};
@@ -0,0 +1 @@
1
+ import{createSelector as e}from"@salsita-ai/common/utils";export const createHostPropertiesSelectors=o=>{let{getState:t}=o,s=e.withTypes(),r={route:s.leaf(e=>e.hostProperties.route),expanded:s.leaf(e=>e.hostProperties.expanded),mode:s.leaf(e=>e.hostProperties.mode),power:s.leaf(e=>e.hostProperties.power),presetTags:s.leaf(e=>e.hostProperties.presetTags),integrationMode:s.leaf(e=>e.hostProperties.integrationMode),sessionToken:s.leaf(e=>e.hostProperties.sessionToken),adminSessionToken:s.leaf(e=>e.hostProperties.adminSessionToken),refreshToken:s.leaf(e=>e.hostProperties.refreshToken),authorizationCode:s.leaf(e=>e.hostProperties.authorizationCode)},n=e=>r[e];return{getHostPropertySelector:n,selectRoute:r.route,selectExpanded:r.expanded,selectMode:r.mode,selectPower:r.power,selectPresetTags:r.presetTags,selectIntegrationMode:r.integrationMode,selectSessionToken:r.sessionToken,selectAdminSessionToken:r.adminSessionToken,selectRefreshToken:r.refreshToken,selectAuthorizationCode:r.authorizationCode,getHostProperty:e=>n(e)(t()),getRoute:()=>r.route(t()),getExpanded:()=>r.expanded(t()),getMode:()=>r.mode(t()),getPower:()=>r.power(t()),getPresetTags:()=>r.presetTags(t()),getIntegrationMode:()=>r.integrationMode(t()),getSessionToken:()=>r.sessionToken(t()),getAdminSessionToken:()=>r.adminSessionToken(t()),getRefreshToken:()=>r.refreshToken(t()),getAuthorizationCode:()=>r.authorizationCode(t())}};