@plures/praxis 0.2.1 → 1.0.0

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 (486) hide show
  1. package/README.md +188 -61
  2. package/core/codegen/docs-generator.ts +808 -0
  3. package/core/codegen/index.ts +27 -0
  4. package/core/codegen/ts-generator.ts +15 -0
  5. package/core/db-adapter/index.ts +52 -0
  6. package/core/db-adapter/sync-engine.ts +450 -0
  7. package/core/logic-engine/engine.ts +12 -0
  8. package/core/logic-engine/index.ts +16 -0
  9. package/core/logic-engine/protocol.ts +16 -0
  10. package/core/logic-engine/psf-adapter.ts +269 -0
  11. package/core/logic-engine/rules.ts +16 -0
  12. package/core/schema-engine/compiler.ts +431 -0
  13. package/core/schema-engine/generator.ts +635 -0
  14. package/core/schema-engine/index.ts +18 -0
  15. package/core/schema-engine/psf.ts +664 -0
  16. package/core/schema-engine/types.ts +63 -0
  17. package/core/schema-engine/validator.ts +541 -0
  18. package/dist/core/codegen/docs-generator.d.ts +123 -0
  19. package/dist/core/codegen/docs-generator.d.ts.map +1 -0
  20. package/dist/core/codegen/docs-generator.js +674 -0
  21. package/dist/core/codegen/docs-generator.js.map +1 -0
  22. package/dist/core/codegen/index.d.ts +11 -0
  23. package/dist/core/codegen/index.d.ts.map +1 -0
  24. package/dist/core/codegen/index.js +13 -0
  25. package/dist/core/codegen/index.js.map +1 -0
  26. package/dist/core/codegen/ts-generator.d.ts +8 -0
  27. package/dist/core/codegen/ts-generator.d.ts.map +1 -0
  28. package/dist/core/codegen/ts-generator.js +8 -0
  29. package/dist/core/codegen/ts-generator.js.map +1 -0
  30. package/dist/core/db-adapter/index.d.ts +18 -0
  31. package/dist/core/db-adapter/index.d.ts.map +1 -0
  32. package/dist/core/db-adapter/index.js +23 -0
  33. package/dist/core/db-adapter/index.js.map +1 -0
  34. package/dist/core/db-adapter/sync-engine.d.ts +180 -0
  35. package/dist/core/db-adapter/sync-engine.d.ts.map +1 -0
  36. package/dist/core/db-adapter/sync-engine.js +342 -0
  37. package/dist/core/db-adapter/sync-engine.js.map +1 -0
  38. package/dist/core/logic-engine/engine.d.ts +8 -0
  39. package/dist/core/logic-engine/engine.d.ts.map +1 -0
  40. package/dist/core/logic-engine/engine.js +8 -0
  41. package/dist/core/logic-engine/engine.js.map +1 -0
  42. package/dist/core/logic-engine/index.d.ts +16 -0
  43. package/dist/core/logic-engine/index.d.ts.map +1 -0
  44. package/dist/core/logic-engine/index.js +16 -0
  45. package/dist/core/logic-engine/index.js.map +1 -0
  46. package/dist/core/logic-engine/protocol.d.ts +7 -0
  47. package/dist/core/logic-engine/protocol.d.ts.map +1 -0
  48. package/dist/core/logic-engine/protocol.js +7 -0
  49. package/dist/core/logic-engine/protocol.js.map +1 -0
  50. package/dist/core/logic-engine/psf-adapter.d.ts +88 -0
  51. package/dist/core/logic-engine/psf-adapter.d.ts.map +1 -0
  52. package/dist/core/logic-engine/psf-adapter.js +207 -0
  53. package/dist/core/logic-engine/psf-adapter.js.map +1 -0
  54. package/dist/core/logic-engine/rules.d.ts +7 -0
  55. package/dist/core/logic-engine/rules.d.ts.map +1 -0
  56. package/dist/core/logic-engine/rules.js +7 -0
  57. package/dist/core/logic-engine/rules.js.map +1 -0
  58. package/dist/core/schema-engine/compiler.d.ts +198 -0
  59. package/dist/core/schema-engine/compiler.d.ts.map +1 -0
  60. package/dist/core/schema-engine/compiler.js +262 -0
  61. package/dist/core/schema-engine/compiler.js.map +1 -0
  62. package/dist/core/schema-engine/generator.d.ts +115 -0
  63. package/dist/core/schema-engine/generator.d.ts.map +1 -0
  64. package/dist/core/schema-engine/generator.js +506 -0
  65. package/dist/core/schema-engine/generator.js.map +1 -0
  66. package/dist/core/schema-engine/index.d.ts +18 -0
  67. package/dist/core/schema-engine/index.d.ts.map +1 -0
  68. package/dist/core/schema-engine/index.js +18 -0
  69. package/dist/core/schema-engine/index.js.map +1 -0
  70. package/dist/core/schema-engine/psf.d.ts +612 -0
  71. package/dist/core/schema-engine/psf.d.ts.map +1 -0
  72. package/dist/core/schema-engine/psf.js +45 -0
  73. package/dist/core/schema-engine/psf.js.map +1 -0
  74. package/dist/core/schema-engine/types.d.ts +10 -0
  75. package/dist/core/schema-engine/types.d.ts.map +1 -0
  76. package/dist/core/schema-engine/types.js +7 -0
  77. package/dist/core/schema-engine/types.js.map +1 -0
  78. package/dist/core/schema-engine/validator.d.ts +140 -0
  79. package/dist/core/schema-engine/validator.d.ts.map +1 -0
  80. package/dist/core/schema-engine/validator.js +407 -0
  81. package/dist/core/schema-engine/validator.js.map +1 -0
  82. package/dist/src/adapters/cli.d.ts.map +1 -0
  83. package/dist/src/adapters/cli.js.map +1 -0
  84. package/dist/src/cli/commands/auth.d.ts.map +1 -0
  85. package/dist/src/cli/commands/auth.js.map +1 -0
  86. package/dist/src/cli/commands/build.d.ts +23 -0
  87. package/dist/src/cli/commands/build.d.ts.map +1 -0
  88. package/dist/src/cli/commands/build.js +162 -0
  89. package/dist/src/cli/commands/build.js.map +1 -0
  90. package/dist/src/cli/commands/canvas.d.ts +23 -0
  91. package/dist/src/cli/commands/canvas.d.ts.map +1 -0
  92. package/dist/src/cli/commands/canvas.js +215 -0
  93. package/dist/src/cli/commands/canvas.js.map +1 -0
  94. package/dist/src/cli/commands/cloud.d.ts.map +1 -0
  95. package/dist/src/cli/commands/cloud.js.map +1 -0
  96. package/dist/src/cli/commands/create.d.ts +21 -0
  97. package/dist/src/cli/commands/create.d.ts.map +1 -0
  98. package/dist/src/cli/commands/create.js +621 -0
  99. package/dist/src/cli/commands/create.js.map +1 -0
  100. package/dist/src/cli/commands/dev.d.ts +21 -0
  101. package/dist/src/cli/commands/dev.d.ts.map +1 -0
  102. package/dist/src/cli/commands/dev.js +71 -0
  103. package/dist/src/cli/commands/dev.js.map +1 -0
  104. package/dist/src/cli/commands/generate.d.ts.map +1 -0
  105. package/dist/src/cli/commands/generate.js.map +1 -0
  106. package/dist/src/cli/commands/orchestrate.d.ts +44 -0
  107. package/dist/src/cli/commands/orchestrate.d.ts.map +1 -0
  108. package/dist/src/cli/commands/orchestrate.js +150 -0
  109. package/dist/src/cli/commands/orchestrate.js.map +1 -0
  110. package/dist/{cli → src/cli}/index.d.ts.map +1 -1
  111. package/dist/{cli → src/cli}/index.js +53 -21
  112. package/dist/src/cli/index.js.map +1 -0
  113. package/dist/src/cloud/auth.d.ts.map +1 -0
  114. package/dist/src/cloud/auth.js.map +1 -0
  115. package/dist/src/cloud/billing.d.ts.map +1 -0
  116. package/dist/src/cloud/billing.js.map +1 -0
  117. package/dist/src/cloud/client.d.ts.map +1 -0
  118. package/dist/src/cloud/client.js.map +1 -0
  119. package/dist/src/cloud/index.d.ts.map +1 -0
  120. package/dist/src/cloud/index.js.map +1 -0
  121. package/dist/src/cloud/marketplace.d.ts.map +1 -0
  122. package/dist/src/cloud/marketplace.js.map +1 -0
  123. package/dist/src/cloud/provisioning.d.ts.map +1 -0
  124. package/dist/src/cloud/provisioning.js.map +1 -0
  125. package/dist/src/cloud/relay/endpoints.d.ts.map +1 -0
  126. package/dist/src/cloud/relay/endpoints.js.map +1 -0
  127. package/dist/src/cloud/relay/health/index.d.ts.map +1 -0
  128. package/dist/src/cloud/relay/health/index.js.map +1 -0
  129. package/dist/src/cloud/relay/stats/index.d.ts.map +1 -0
  130. package/dist/src/cloud/relay/stats/index.js.map +1 -0
  131. package/dist/src/cloud/relay/sync/index.d.ts.map +1 -0
  132. package/dist/src/cloud/relay/sync/index.js.map +1 -0
  133. package/dist/src/cloud/relay/usage/index.d.ts.map +1 -0
  134. package/dist/src/cloud/relay/usage/index.js.map +1 -0
  135. package/dist/src/cloud/sponsors.d.ts.map +1 -0
  136. package/dist/src/cloud/sponsors.js.map +1 -0
  137. package/dist/src/cloud/types.d.ts.map +1 -0
  138. package/dist/src/cloud/types.js.map +1 -0
  139. package/dist/src/components/index.d.ts.map +1 -0
  140. package/dist/src/components/index.js.map +1 -0
  141. package/dist/src/core/actors.d.ts.map +1 -0
  142. package/dist/src/core/actors.js.map +1 -0
  143. package/dist/src/core/component/generator.d.ts.map +1 -0
  144. package/dist/{core → src/core}/component/generator.js +45 -3
  145. package/dist/src/core/component/generator.js.map +1 -0
  146. package/dist/src/core/engine.d.ts.map +1 -0
  147. package/dist/src/core/engine.js.map +1 -0
  148. package/dist/src/core/introspection.d.ts.map +1 -0
  149. package/dist/src/core/introspection.js.map +1 -0
  150. package/dist/src/core/logic/generator.d.ts.map +1 -0
  151. package/dist/{core → src/core}/logic/generator.js +35 -4
  152. package/dist/src/core/logic/generator.js.map +1 -0
  153. package/dist/src/core/pluresdb/adapter.d.ts +72 -0
  154. package/dist/src/core/pluresdb/adapter.d.ts.map +1 -0
  155. package/dist/src/core/pluresdb/adapter.js +73 -0
  156. package/dist/src/core/pluresdb/adapter.js.map +1 -0
  157. package/dist/src/core/pluresdb/generator.d.ts.map +1 -0
  158. package/dist/{core → src/core}/pluresdb/generator.js +33 -4
  159. package/dist/src/core/pluresdb/generator.js.map +1 -0
  160. package/dist/src/core/pluresdb/index.d.ts +15 -0
  161. package/dist/src/core/pluresdb/index.d.ts.map +1 -0
  162. package/dist/src/core/pluresdb/index.js +11 -0
  163. package/dist/src/core/pluresdb/index.js.map +1 -0
  164. package/dist/src/core/pluresdb/schema-registry.d.ts +104 -0
  165. package/dist/src/core/pluresdb/schema-registry.d.ts.map +1 -0
  166. package/dist/src/core/pluresdb/schema-registry.js +130 -0
  167. package/dist/src/core/pluresdb/schema-registry.js.map +1 -0
  168. package/dist/src/core/pluresdb/store.d.ts +199 -0
  169. package/dist/src/core/pluresdb/store.d.ts.map +1 -0
  170. package/dist/src/core/pluresdb/store.js +344 -0
  171. package/dist/src/core/pluresdb/store.js.map +1 -0
  172. package/dist/src/core/protocol.d.ts.map +1 -0
  173. package/dist/src/core/protocol.js.map +1 -0
  174. package/dist/src/core/rules.d.ts.map +1 -0
  175. package/dist/src/core/rules.js.map +1 -0
  176. package/dist/src/core/schema/loader.d.ts.map +1 -0
  177. package/dist/src/core/schema/loader.js.map +1 -0
  178. package/dist/src/core/schema/normalize.d.ts.map +1 -0
  179. package/dist/src/core/schema/normalize.js.map +1 -0
  180. package/dist/src/core/schema/types.d.ts.map +1 -0
  181. package/dist/src/core/schema/types.js.map +1 -0
  182. package/dist/src/dsl/index.d.ts.map +1 -0
  183. package/dist/src/dsl/index.js.map +1 -0
  184. package/dist/src/dsl.d.ts.map +1 -0
  185. package/dist/src/dsl.js.map +1 -0
  186. package/dist/src/examples/advanced-todo/index.d.ts.map +1 -0
  187. package/dist/src/examples/advanced-todo/index.js.map +1 -0
  188. package/dist/src/examples/auth-basic/index.d.ts.map +1 -0
  189. package/dist/src/examples/auth-basic/index.js.map +1 -0
  190. package/dist/src/examples/cart/index.d.ts.map +1 -0
  191. package/dist/src/examples/cart/index.js.map +1 -0
  192. package/dist/src/examples/hero-ecommerce/index.d.ts.map +1 -0
  193. package/dist/src/examples/hero-ecommerce/index.js.map +1 -0
  194. package/dist/src/examples/svelte-counter/index.d.ts.map +1 -0
  195. package/dist/src/examples/svelte-counter/index.js.map +1 -0
  196. package/dist/src/flows.d.ts.map +1 -0
  197. package/dist/src/flows.js.map +1 -0
  198. package/dist/{index.d.ts → src/index.d.ts} +12 -2
  199. package/dist/src/index.d.ts.map +1 -0
  200. package/dist/{index.js → src/index.js} +6 -1
  201. package/dist/src/index.js.map +1 -0
  202. package/dist/src/integrations/code-canvas.d.ts +265 -0
  203. package/dist/src/integrations/code-canvas.d.ts.map +1 -0
  204. package/dist/src/integrations/code-canvas.js +451 -0
  205. package/dist/src/integrations/code-canvas.js.map +1 -0
  206. package/dist/src/integrations/pluresdb.d.ts +117 -0
  207. package/dist/src/integrations/pluresdb.d.ts.map +1 -0
  208. package/dist/src/integrations/pluresdb.js +117 -0
  209. package/dist/src/integrations/pluresdb.js.map +1 -0
  210. package/dist/src/integrations/state-docs.d.ts +191 -0
  211. package/dist/src/integrations/state-docs.d.ts.map +1 -0
  212. package/dist/src/integrations/state-docs.js +515 -0
  213. package/dist/src/integrations/state-docs.js.map +1 -0
  214. package/dist/src/integrations/svelte.d.ts.map +1 -0
  215. package/dist/src/integrations/svelte.js.map +1 -0
  216. package/dist/src/integrations/tauri.d.ts +360 -0
  217. package/dist/src/integrations/tauri.d.ts.map +1 -0
  218. package/dist/src/integrations/tauri.js +278 -0
  219. package/dist/src/integrations/tauri.js.map +1 -0
  220. package/dist/src/integrations/unum.d.ts +159 -0
  221. package/dist/src/integrations/unum.d.ts.map +1 -0
  222. package/dist/src/integrations/unum.js +240 -0
  223. package/dist/src/integrations/unum.js.map +1 -0
  224. package/dist/src/registry.d.ts.map +1 -0
  225. package/dist/src/registry.js.map +1 -0
  226. package/dist/{runtime → src/runtime}/terminal-adapter.d.ts +58 -7
  227. package/dist/src/runtime/terminal-adapter.d.ts.map +1 -0
  228. package/dist/src/runtime/terminal-adapter.js +237 -0
  229. package/dist/src/runtime/terminal-adapter.js.map +1 -0
  230. package/dist/src/step.d.ts.map +1 -0
  231. package/dist/src/step.js.map +1 -0
  232. package/dist/src/types.d.ts.map +1 -0
  233. package/dist/{cloud → src}/types.js.map +1 -1
  234. package/dist/tools/cli/commands/index.d.ts +7 -0
  235. package/dist/tools/cli/commands/index.d.ts.map +1 -0
  236. package/dist/tools/cli/commands/index.js +7 -0
  237. package/dist/tools/cli/commands/index.js.map +1 -0
  238. package/dist/tools/cli/index.d.ts +8 -0
  239. package/dist/tools/cli/index.d.ts.map +1 -0
  240. package/dist/tools/cli/index.js +9 -0
  241. package/dist/tools/cli/index.js.map +1 -0
  242. package/dist/tools/watcher/index.d.ts +105 -0
  243. package/dist/tools/watcher/index.d.ts.map +1 -0
  244. package/dist/tools/watcher/index.js +213 -0
  245. package/dist/tools/watcher/index.js.map +1 -0
  246. package/dist/ui/canvas/canvas-projection.d.ts +78 -0
  247. package/dist/ui/canvas/canvas-projection.d.ts.map +1 -0
  248. package/dist/ui/canvas/canvas-projection.js +416 -0
  249. package/dist/ui/canvas/canvas-projection.js.map +1 -0
  250. package/dist/ui/canvas/canvas-state.d.ts +200 -0
  251. package/dist/ui/canvas/canvas-state.d.ts.map +1 -0
  252. package/dist/ui/canvas/canvas-state.js +464 -0
  253. package/dist/ui/canvas/canvas-state.js.map +1 -0
  254. package/dist/ui/canvas/components/index.d.ts +95 -0
  255. package/dist/ui/canvas/components/index.d.ts.map +1 -0
  256. package/dist/ui/canvas/components/index.js +19 -0
  257. package/dist/ui/canvas/components/index.js.map +1 -0
  258. package/dist/ui/canvas/index.d.ts +32 -0
  259. package/dist/ui/canvas/index.d.ts.map +1 -0
  260. package/dist/ui/canvas/index.js +32 -0
  261. package/dist/ui/canvas/index.js.map +1 -0
  262. package/dist/ui/svelte-generator/index.d.ts +9 -0
  263. package/dist/ui/svelte-generator/index.d.ts.map +1 -0
  264. package/dist/ui/svelte-generator/index.js +11 -0
  265. package/dist/ui/svelte-generator/index.js.map +1 -0
  266. package/dist/ui/svelte-generator/psf-generator.d.ts +128 -0
  267. package/dist/ui/svelte-generator/psf-generator.d.ts.map +1 -0
  268. package/dist/ui/svelte-generator/psf-generator.js +506 -0
  269. package/dist/ui/svelte-generator/psf-generator.js.map +1 -0
  270. package/docs/README.md +155 -0
  271. package/docs/core/building-extensions.md +553 -0
  272. package/docs/core/cli-usage.md +498 -0
  273. package/docs/core/code-canvas-sync.md +468 -0
  274. package/docs/core/logic-engine.md +566 -0
  275. package/docs/core/pluresdb-integration.md +646 -0
  276. package/docs/core/schema-model.md +414 -0
  277. package/docs/core/ui-generation.md +580 -0
  278. package/docs/core/what-is-praxis.md +240 -0
  279. package/docs/tutorials/README.md +84 -0
  280. package/docs/tutorials/ecommerce-cart.md +631 -0
  281. package/docs/tutorials/first-app.md +529 -0
  282. package/docs/tutorials/form-builder.md +620 -0
  283. package/docs/tutorials/todo-pluresdb.md +589 -0
  284. package/package.json +1 -1
  285. package/src/__tests__/canvas-components.test.ts +450 -0
  286. package/src/__tests__/cli-create.test.ts +178 -0
  287. package/src/__tests__/code-canvas-integration.test.ts +277 -0
  288. package/src/__tests__/docs-generator.test.ts +181 -0
  289. package/src/__tests__/generators.test.ts +3 -2
  290. package/src/__tests__/pluresdb.test.ts +457 -0
  291. package/src/__tests__/psf-schema-engine.test.ts +450 -0
  292. package/src/__tests__/state-docs-integration.test.ts +297 -0
  293. package/src/__tests__/tauri-integration.test.ts +298 -0
  294. package/src/__tests__/terminal-node.test.ts +1 -1
  295. package/src/__tests__/unum-integration.test.ts +142 -0
  296. package/src/cli/commands/build.ts +203 -0
  297. package/src/cli/commands/canvas.ts +246 -0
  298. package/src/cli/commands/create.ts +666 -0
  299. package/src/cli/commands/dev.ts +95 -0
  300. package/src/cli/commands/orchestrate.ts +212 -0
  301. package/src/cli/index.ts +48 -21
  302. package/src/core/component/generator.ts +45 -3
  303. package/src/core/logic/generator.ts +39 -4
  304. package/src/core/pluresdb/adapter.ts +117 -0
  305. package/src/core/pluresdb/generator.ts +33 -4
  306. package/src/core/pluresdb/index.ts +37 -0
  307. package/src/core/pluresdb/schema-registry.ts +162 -0
  308. package/src/core/pluresdb/store.ts +443 -0
  309. package/src/index.ts +109 -0
  310. package/src/integrations/code-canvas.ts +717 -0
  311. package/src/integrations/pluresdb.ts +140 -29
  312. package/src/integrations/state-docs.ts +710 -0
  313. package/src/integrations/tauri.ts +638 -0
  314. package/src/integrations/unum.ts +395 -0
  315. package/src/runtime/terminal-adapter.ts +178 -23
  316. package/dist/adapters/cli.d.ts.map +0 -1
  317. package/dist/adapters/cli.js.map +0 -1
  318. package/dist/cli/commands/auth.d.ts.map +0 -1
  319. package/dist/cli/commands/auth.js.map +0 -1
  320. package/dist/cli/commands/cloud.d.ts.map +0 -1
  321. package/dist/cli/commands/cloud.js.map +0 -1
  322. package/dist/cli/commands/generate.d.ts.map +0 -1
  323. package/dist/cli/commands/generate.js.map +0 -1
  324. package/dist/cli/index.js.map +0 -1
  325. package/dist/cloud/auth.d.ts.map +0 -1
  326. package/dist/cloud/auth.js.map +0 -1
  327. package/dist/cloud/billing.d.ts.map +0 -1
  328. package/dist/cloud/billing.js.map +0 -1
  329. package/dist/cloud/client.d.ts.map +0 -1
  330. package/dist/cloud/client.js.map +0 -1
  331. package/dist/cloud/index.d.ts.map +0 -1
  332. package/dist/cloud/index.js.map +0 -1
  333. package/dist/cloud/marketplace.d.ts.map +0 -1
  334. package/dist/cloud/marketplace.js.map +0 -1
  335. package/dist/cloud/provisioning.d.ts.map +0 -1
  336. package/dist/cloud/provisioning.js.map +0 -1
  337. package/dist/cloud/relay/endpoints.d.ts.map +0 -1
  338. package/dist/cloud/relay/endpoints.js.map +0 -1
  339. package/dist/cloud/relay/health/index.d.ts.map +0 -1
  340. package/dist/cloud/relay/health/index.js.map +0 -1
  341. package/dist/cloud/relay/stats/index.d.ts.map +0 -1
  342. package/dist/cloud/relay/stats/index.js.map +0 -1
  343. package/dist/cloud/relay/sync/index.d.ts.map +0 -1
  344. package/dist/cloud/relay/sync/index.js.map +0 -1
  345. package/dist/cloud/relay/usage/index.d.ts.map +0 -1
  346. package/dist/cloud/relay/usage/index.js.map +0 -1
  347. package/dist/cloud/sponsors.d.ts.map +0 -1
  348. package/dist/cloud/sponsors.js.map +0 -1
  349. package/dist/cloud/types.d.ts.map +0 -1
  350. package/dist/components/index.d.ts.map +0 -1
  351. package/dist/components/index.js.map +0 -1
  352. package/dist/core/actors.d.ts.map +0 -1
  353. package/dist/core/actors.js.map +0 -1
  354. package/dist/core/component/generator.d.ts.map +0 -1
  355. package/dist/core/component/generator.js.map +0 -1
  356. package/dist/core/engine.d.ts.map +0 -1
  357. package/dist/core/engine.js.map +0 -1
  358. package/dist/core/introspection.d.ts.map +0 -1
  359. package/dist/core/introspection.js.map +0 -1
  360. package/dist/core/logic/generator.d.ts.map +0 -1
  361. package/dist/core/logic/generator.js.map +0 -1
  362. package/dist/core/pluresdb/generator.d.ts.map +0 -1
  363. package/dist/core/pluresdb/generator.js.map +0 -1
  364. package/dist/core/protocol.d.ts.map +0 -1
  365. package/dist/core/protocol.js.map +0 -1
  366. package/dist/core/rules.d.ts.map +0 -1
  367. package/dist/core/rules.js.map +0 -1
  368. package/dist/core/schema/loader.d.ts.map +0 -1
  369. package/dist/core/schema/loader.js.map +0 -1
  370. package/dist/core/schema/normalize.d.ts.map +0 -1
  371. package/dist/core/schema/normalize.js.map +0 -1
  372. package/dist/core/schema/types.d.ts.map +0 -1
  373. package/dist/core/schema/types.js.map +0 -1
  374. package/dist/dsl/index.d.ts.map +0 -1
  375. package/dist/dsl/index.js.map +0 -1
  376. package/dist/dsl.d.ts.map +0 -1
  377. package/dist/dsl.js.map +0 -1
  378. package/dist/examples/advanced-todo/index.d.ts.map +0 -1
  379. package/dist/examples/advanced-todo/index.js.map +0 -1
  380. package/dist/examples/auth-basic/index.d.ts.map +0 -1
  381. package/dist/examples/auth-basic/index.js.map +0 -1
  382. package/dist/examples/cart/index.d.ts.map +0 -1
  383. package/dist/examples/cart/index.js.map +0 -1
  384. package/dist/examples/hero-ecommerce/index.d.ts.map +0 -1
  385. package/dist/examples/hero-ecommerce/index.js.map +0 -1
  386. package/dist/examples/svelte-counter/index.d.ts.map +0 -1
  387. package/dist/examples/svelte-counter/index.js.map +0 -1
  388. package/dist/flows.d.ts.map +0 -1
  389. package/dist/flows.js.map +0 -1
  390. package/dist/index.d.ts.map +0 -1
  391. package/dist/index.js.map +0 -1
  392. package/dist/integrations/pluresdb.d.ts +0 -56
  393. package/dist/integrations/pluresdb.d.ts.map +0 -1
  394. package/dist/integrations/pluresdb.js +0 -46
  395. package/dist/integrations/pluresdb.js.map +0 -1
  396. package/dist/integrations/svelte.d.ts.map +0 -1
  397. package/dist/integrations/svelte.js.map +0 -1
  398. package/dist/registry.d.ts.map +0 -1
  399. package/dist/registry.js.map +0 -1
  400. package/dist/runtime/terminal-adapter.d.ts.map +0 -1
  401. package/dist/runtime/terminal-adapter.js +0 -113
  402. package/dist/runtime/terminal-adapter.js.map +0 -1
  403. package/dist/step.d.ts.map +0 -1
  404. package/dist/step.js.map +0 -1
  405. package/dist/types.d.ts.map +0 -1
  406. package/dist/types.js.map +0 -1
  407. /package/dist/{adapters → src/adapters}/cli.d.ts +0 -0
  408. /package/dist/{adapters → src/adapters}/cli.js +0 -0
  409. /package/dist/{cli → src/cli}/commands/auth.d.ts +0 -0
  410. /package/dist/{cli → src/cli}/commands/auth.js +0 -0
  411. /package/dist/{cli → src/cli}/commands/cloud.d.ts +0 -0
  412. /package/dist/{cli → src/cli}/commands/cloud.js +0 -0
  413. /package/dist/{cli → src/cli}/commands/generate.d.ts +0 -0
  414. /package/dist/{cli → src/cli}/commands/generate.js +0 -0
  415. /package/dist/{cli → src/cli}/index.d.ts +0 -0
  416. /package/dist/{cloud → src/cloud}/auth.d.ts +0 -0
  417. /package/dist/{cloud → src/cloud}/auth.js +0 -0
  418. /package/dist/{cloud → src/cloud}/billing.d.ts +0 -0
  419. /package/dist/{cloud → src/cloud}/billing.js +0 -0
  420. /package/dist/{cloud → src/cloud}/client.d.ts +0 -0
  421. /package/dist/{cloud → src/cloud}/client.js +0 -0
  422. /package/dist/{cloud → src/cloud}/index.d.ts +0 -0
  423. /package/dist/{cloud → src/cloud}/index.js +0 -0
  424. /package/dist/{cloud → src/cloud}/marketplace.d.ts +0 -0
  425. /package/dist/{cloud → src/cloud}/marketplace.js +0 -0
  426. /package/dist/{cloud → src/cloud}/provisioning.d.ts +0 -0
  427. /package/dist/{cloud → src/cloud}/provisioning.js +0 -0
  428. /package/dist/{cloud → src/cloud}/relay/endpoints.d.ts +0 -0
  429. /package/dist/{cloud → src/cloud}/relay/endpoints.js +0 -0
  430. /package/dist/{cloud → src/cloud}/relay/health/index.d.ts +0 -0
  431. /package/dist/{cloud → src/cloud}/relay/health/index.js +0 -0
  432. /package/dist/{cloud → src/cloud}/relay/stats/index.d.ts +0 -0
  433. /package/dist/{cloud → src/cloud}/relay/stats/index.js +0 -0
  434. /package/dist/{cloud → src/cloud}/relay/sync/index.d.ts +0 -0
  435. /package/dist/{cloud → src/cloud}/relay/sync/index.js +0 -0
  436. /package/dist/{cloud → src/cloud}/relay/usage/index.d.ts +0 -0
  437. /package/dist/{cloud → src/cloud}/relay/usage/index.js +0 -0
  438. /package/dist/{cloud → src/cloud}/sponsors.d.ts +0 -0
  439. /package/dist/{cloud → src/cloud}/sponsors.js +0 -0
  440. /package/dist/{cloud → src/cloud}/types.d.ts +0 -0
  441. /package/dist/{cloud → src/cloud}/types.js +0 -0
  442. /package/dist/{components → src/components}/index.d.ts +0 -0
  443. /package/dist/{components → src/components}/index.js +0 -0
  444. /package/dist/{core → src/core}/actors.d.ts +0 -0
  445. /package/dist/{core → src/core}/actors.js +0 -0
  446. /package/dist/{core → src/core}/component/generator.d.ts +0 -0
  447. /package/dist/{core → src/core}/engine.d.ts +0 -0
  448. /package/dist/{core → src/core}/engine.js +0 -0
  449. /package/dist/{core → src/core}/introspection.d.ts +0 -0
  450. /package/dist/{core → src/core}/introspection.js +0 -0
  451. /package/dist/{core → src/core}/logic/generator.d.ts +0 -0
  452. /package/dist/{core → src/core}/pluresdb/generator.d.ts +0 -0
  453. /package/dist/{core → src/core}/protocol.d.ts +0 -0
  454. /package/dist/{core → src/core}/protocol.js +0 -0
  455. /package/dist/{core → src/core}/rules.d.ts +0 -0
  456. /package/dist/{core → src/core}/rules.js +0 -0
  457. /package/dist/{core → src/core}/schema/loader.d.ts +0 -0
  458. /package/dist/{core → src/core}/schema/loader.js +0 -0
  459. /package/dist/{core → src/core}/schema/normalize.d.ts +0 -0
  460. /package/dist/{core → src/core}/schema/normalize.js +0 -0
  461. /package/dist/{core → src/core}/schema/types.d.ts +0 -0
  462. /package/dist/{core → src/core}/schema/types.js +0 -0
  463. /package/dist/{dsl → src/dsl}/index.d.ts +0 -0
  464. /package/dist/{dsl → src/dsl}/index.js +0 -0
  465. /package/dist/{dsl.d.ts → src/dsl.d.ts} +0 -0
  466. /package/dist/{dsl.js → src/dsl.js} +0 -0
  467. /package/dist/{examples → src/examples}/advanced-todo/index.d.ts +0 -0
  468. /package/dist/{examples → src/examples}/advanced-todo/index.js +0 -0
  469. /package/dist/{examples → src/examples}/auth-basic/index.d.ts +0 -0
  470. /package/dist/{examples → src/examples}/auth-basic/index.js +0 -0
  471. /package/dist/{examples → src/examples}/cart/index.d.ts +0 -0
  472. /package/dist/{examples → src/examples}/cart/index.js +0 -0
  473. /package/dist/{examples → src/examples}/hero-ecommerce/index.d.ts +0 -0
  474. /package/dist/{examples → src/examples}/hero-ecommerce/index.js +0 -0
  475. /package/dist/{examples → src/examples}/svelte-counter/index.d.ts +0 -0
  476. /package/dist/{examples → src/examples}/svelte-counter/index.js +0 -0
  477. /package/dist/{flows.d.ts → src/flows.d.ts} +0 -0
  478. /package/dist/{flows.js → src/flows.js} +0 -0
  479. /package/dist/{integrations → src/integrations}/svelte.d.ts +0 -0
  480. /package/dist/{integrations → src/integrations}/svelte.js +0 -0
  481. /package/dist/{registry.d.ts → src/registry.d.ts} +0 -0
  482. /package/dist/{registry.js → src/registry.js} +0 -0
  483. /package/dist/{step.d.ts → src/step.d.ts} +0 -0
  484. /package/dist/{step.js → src/step.js} +0 -0
  485. /package/dist/{types.d.ts → src/types.d.ts} +0 -0
  486. /package/dist/{types.js → src/types.js} +0 -0
@@ -0,0 +1,450 @@
1
+ /**
2
+ * Canvas Components Tests
3
+ *
4
+ * Tests for the Praxis Canvas Svelte components infrastructure.
5
+ */
6
+
7
+ import { describe, it, expect } from 'vitest';
8
+ import {
9
+ CanvasStateManager,
10
+ createCanvasStateManager,
11
+ type CanvasState,
12
+ type CanvasNodeState,
13
+ } from '../../ui/canvas/canvas-state.js';
14
+ import {
15
+ CanvasProjection,
16
+ createCanvasProjection,
17
+ type LayoutResult,
18
+ } from '../../ui/canvas/canvas-projection.js';
19
+ import type { PSFSchema } from '../../core/schema-engine/psf.js';
20
+
21
+ describe('Canvas State Manager', () => {
22
+ const testSchema: PSFSchema = {
23
+ $version: '1.0.0',
24
+ id: 'test-schema',
25
+ name: 'Test Schema',
26
+ description: 'Test schema for canvas',
27
+ createdAt: new Date().toISOString(),
28
+ modifiedAt: new Date().toISOString(),
29
+ facts: [
30
+ { id: 'fact1', tag: 'UserLoggedIn', description: 'User logged in', payloadSchema: {} },
31
+ { id: 'fact2', tag: 'CartUpdated', description: 'Cart was updated', payloadSchema: {} },
32
+ ],
33
+ events: [
34
+ { id: 'event1', tag: 'Login', description: 'Login event', payloadSchema: {} },
35
+ { id: 'event2', tag: 'AddToCart', description: 'Add to cart event', payloadSchema: {} },
36
+ ],
37
+ rules: [
38
+ { id: 'rule1', name: 'Login Rule', description: 'Handle login', triggers: ['Login'], actions: [] },
39
+ ],
40
+ constraints: [
41
+ { id: 'constraint1', name: 'Auth Required', description: 'User must be authenticated', expression: 'true' },
42
+ ],
43
+ models: [
44
+ {
45
+ id: 'model1',
46
+ name: 'User',
47
+ description: 'User model',
48
+ fields: [
49
+ { name: 'id', type: 'string', required: true },
50
+ { name: 'name', type: 'string', required: true },
51
+ ],
52
+ },
53
+ ],
54
+ components: [
55
+ { id: 'comp1', name: 'UserCard', type: 'display', model: 'User', description: 'User card component' },
56
+ ],
57
+ flows: [],
58
+ };
59
+
60
+ it('should create a canvas state manager', () => {
61
+ const manager = createCanvasStateManager();
62
+ expect(manager).toBeInstanceOf(CanvasStateManager);
63
+ });
64
+
65
+ it('should have initial state', () => {
66
+ const manager = createCanvasStateManager();
67
+ const state = manager.getState();
68
+
69
+ expect(state).toBeDefined();
70
+ expect(state.nodes).toBeInstanceOf(Map);
71
+ expect(state.edges).toBeInstanceOf(Map);
72
+ expect(state.viewport).toBeDefined();
73
+ expect(state.viewport.zoom).toBe(1);
74
+ expect(state.mode).toBe('select');
75
+ expect(state.loading).toBe(true);
76
+ });
77
+
78
+ it('should load schema into canvas state', () => {
79
+ const manager = createCanvasStateManager();
80
+ manager.loadFromSchema(testSchema);
81
+ const state = manager.getState();
82
+
83
+ expect(state.loading).toBe(false);
84
+ // 2 facts + 2 events + 1 rule + 1 constraint + 1 model + 1 component = 8 nodes
85
+ expect(state.nodes.size).toBe(8);
86
+ });
87
+
88
+ it('should load facts as nodes', () => {
89
+ const manager = createCanvasStateManager();
90
+ manager.loadFromSchema(testSchema);
91
+ const state = manager.getState();
92
+
93
+ const fact1 = state.nodes.get('fact1');
94
+ expect(fact1).toBeDefined();
95
+ expect(fact1?.type).toBe('fact');
96
+ expect(fact1?.label).toBe('UserLoggedIn');
97
+ });
98
+
99
+ it('should load events as nodes', () => {
100
+ const manager = createCanvasStateManager();
101
+ manager.loadFromSchema(testSchema);
102
+ const state = manager.getState();
103
+
104
+ const event1 = state.nodes.get('event1');
105
+ expect(event1).toBeDefined();
106
+ expect(event1?.type).toBe('event');
107
+ expect(event1?.label).toBe('Login');
108
+ });
109
+
110
+ it('should load rules as nodes with trigger edges', () => {
111
+ const manager = createCanvasStateManager();
112
+ manager.loadFromSchema(testSchema);
113
+ const state = manager.getState();
114
+
115
+ const rule1 = state.nodes.get('rule1');
116
+ expect(rule1).toBeDefined();
117
+ expect(rule1?.type).toBe('rule');
118
+ expect(rule1?.label).toBe('Login Rule');
119
+
120
+ // Check for trigger edge from event to rule
121
+ const edges = Array.from(state.edges.values());
122
+ const triggerEdge = edges.find(e => e.source === 'event1' && e.target === 'rule1');
123
+ expect(triggerEdge).toBeDefined();
124
+ expect(triggerEdge?.type).toBe('event');
125
+ expect(triggerEdge?.label).toBe('triggers');
126
+ });
127
+
128
+ it('should select a node', () => {
129
+ const manager = createCanvasStateManager();
130
+ manager.loadFromSchema(testSchema);
131
+
132
+ manager.selectNode('fact1');
133
+ const state = manager.getState();
134
+
135
+ expect(state.selection.nodes.has('fact1')).toBe(true);
136
+ expect(state.nodes.get('fact1')?.selected).toBe(true);
137
+ });
138
+
139
+ it('should support multi-selection with addToSelection', () => {
140
+ const manager = createCanvasStateManager();
141
+ manager.loadFromSchema(testSchema);
142
+
143
+ manager.selectNode('fact1');
144
+ manager.selectNode('fact2', true);
145
+ const state = manager.getState();
146
+
147
+ expect(state.selection.nodes.has('fact1')).toBe(true);
148
+ expect(state.selection.nodes.has('fact2')).toBe(true);
149
+ });
150
+
151
+ it('should move a node', () => {
152
+ const manager = createCanvasStateManager();
153
+ manager.loadFromSchema(testSchema);
154
+
155
+ manager.moveNode('fact1', { x: 100, y: 200 });
156
+ const state = manager.getState();
157
+
158
+ const node = state.nodes.get('fact1');
159
+ expect(node?.position.x).toBe(100);
160
+ expect(node?.position.y).toBe(200);
161
+ });
162
+
163
+ it('should snap to grid when moving', () => {
164
+ const manager = createCanvasStateManager();
165
+ manager.loadFromSchema(testSchema);
166
+
167
+ // Grid snap is enabled by default with size 20
168
+ manager.moveNode('fact1', { x: 105, y: 215 });
169
+ const state = manager.getState();
170
+
171
+ const node = state.nodes.get('fact1');
172
+ // With grid snap, 105 rounds to 100 (nearest multiple of 20)
173
+ // and 215 rounds to 220
174
+ expect(node?.position.x).toBe(100);
175
+ expect(node?.position.y).toBe(220);
176
+ });
177
+
178
+ it('should clear selection', () => {
179
+ const manager = createCanvasStateManager();
180
+ manager.loadFromSchema(testSchema);
181
+
182
+ manager.selectNode('fact1');
183
+ manager.selectNode('fact2', true);
184
+ manager.clearSelection();
185
+
186
+ const state = manager.getState();
187
+ expect(state.selection.nodes.size).toBe(0);
188
+ expect(state.nodes.get('fact1')?.selected).toBe(false);
189
+ expect(state.nodes.get('fact2')?.selected).toBe(false);
190
+ });
191
+
192
+ it('should set viewport', () => {
193
+ const manager = createCanvasStateManager();
194
+
195
+ manager.setViewport({ x: 50, y: 100, zoom: 1.5 });
196
+ const state = manager.getState();
197
+
198
+ expect(state.viewport.x).toBe(50);
199
+ expect(state.viewport.y).toBe(100);
200
+ expect(state.viewport.zoom).toBe(1.5);
201
+ });
202
+
203
+ it('should set mode', () => {
204
+ const manager = createCanvasStateManager();
205
+
206
+ manager.setMode('pan');
207
+ expect(manager.getState().mode).toBe('pan');
208
+
209
+ manager.setMode('connect');
210
+ expect(manager.getState().mode).toBe('connect');
211
+ });
212
+
213
+ it('should toggle grid visibility', () => {
214
+ const manager = createCanvasStateManager();
215
+ const initialVisibility = manager.getState().grid.visible;
216
+
217
+ manager.toggleGrid();
218
+ expect(manager.getState().grid.visible).toBe(!initialVisibility);
219
+
220
+ manager.toggleGrid();
221
+ expect(manager.getState().grid.visible).toBe(initialVisibility);
222
+ });
223
+
224
+ it('should support undo/redo', () => {
225
+ const manager = createCanvasStateManager();
226
+ manager.loadFromSchema(testSchema);
227
+
228
+ // Make a change with undo support
229
+ manager.selectNode('fact1');
230
+
231
+ // Undo should work
232
+ const undoResult = manager.undo();
233
+ expect(undoResult).toBe(true);
234
+
235
+ // Redo should work
236
+ const redoResult = manager.redo();
237
+ expect(redoResult).toBe(true);
238
+ });
239
+
240
+ it('should subscribe to state changes', () => {
241
+ const manager = createCanvasStateManager();
242
+ let callCount = 0;
243
+ let lastState: CanvasState | null = null;
244
+
245
+ const unsubscribe = manager.subscribe((state) => {
246
+ callCount++;
247
+ lastState = state;
248
+ });
249
+
250
+ // Initial call happens immediately
251
+ expect(callCount).toBe(1);
252
+ expect(lastState).not.toBeNull();
253
+
254
+ // Changes trigger subscriber
255
+ manager.setMode('pan');
256
+ expect(callCount).toBe(2);
257
+ expect(lastState?.mode).toBe('pan');
258
+
259
+ // Unsubscribe works
260
+ unsubscribe();
261
+ manager.setMode('select');
262
+ expect(callCount).toBe(2); // No additional calls
263
+ });
264
+
265
+ it('should export canvas state to schema', () => {
266
+ const manager = createCanvasStateManager();
267
+ manager.loadFromSchema(testSchema);
268
+
269
+ // Move a node
270
+ manager.moveNode('fact1', { x: 150, y: 300 });
271
+
272
+ // Export back to schema
273
+ const updatedSchema = manager.exportToSchema(testSchema);
274
+
275
+ expect(updatedSchema.modifiedAt).toBeDefined();
276
+
277
+ // Check that position was updated (snapped to grid size of 20)
278
+ const updatedFact = updatedSchema.facts.find(f => f.id === 'fact1');
279
+ // 150 rounded to nearest 20 = 160, 300 is already on grid
280
+ expect(updatedFact?.position).toEqual({ x: 160, y: 300 });
281
+ });
282
+ });
283
+
284
+ describe('Canvas Projection', () => {
285
+ const testSchema: PSFSchema = {
286
+ $version: '1.0.0',
287
+ id: 'test-schema',
288
+ name: 'Test Schema',
289
+ description: 'Test schema for projection',
290
+ createdAt: new Date().toISOString(),
291
+ modifiedAt: new Date().toISOString(),
292
+ facts: [
293
+ { id: 'fact1', tag: 'Fact1', description: 'Test fact', payloadSchema: {} },
294
+ { id: 'fact2', tag: 'Fact2', description: 'Test fact 2', payloadSchema: {} },
295
+ ],
296
+ events: [
297
+ { id: 'event1', tag: 'Event1', description: 'Test event', payloadSchema: {} },
298
+ ],
299
+ rules: [
300
+ { id: 'rule1', name: 'Rule1', description: 'Test rule', triggers: ['Event1'], actions: [] },
301
+ ],
302
+ constraints: [],
303
+ models: [],
304
+ components: [],
305
+ flows: [],
306
+ };
307
+
308
+ it('should create a canvas projection', () => {
309
+ const projection = createCanvasProjection();
310
+ expect(projection).toBeInstanceOf(CanvasProjection);
311
+ });
312
+
313
+ it('should project schema to layout', () => {
314
+ const projection = createCanvasProjection();
315
+ const result = projection.projectSchema(testSchema);
316
+
317
+ expect(result).toBeDefined();
318
+ expect(result.positions).toBeInstanceOf(Map);
319
+ expect(result.viewport).toBeDefined();
320
+ expect(result.bounds).toBeDefined();
321
+ });
322
+
323
+ it('should generate positions for all nodes', () => {
324
+ const projection = createCanvasProjection();
325
+ const result = projection.projectSchema(testSchema);
326
+
327
+ // 2 facts + 1 event + 1 rule = 4 nodes
328
+ expect(result.positions.size).toBe(4);
329
+
330
+ expect(result.positions.has('fact1')).toBe(true);
331
+ expect(result.positions.has('fact2')).toBe(true);
332
+ expect(result.positions.has('event1')).toBe(true);
333
+ expect(result.positions.has('rule1')).toBe(true);
334
+ });
335
+
336
+ it('should respect existing positions', () => {
337
+ const schemaWithPositions: PSFSchema = {
338
+ ...testSchema,
339
+ facts: [
340
+ { id: 'fact1', tag: 'Fact1', description: 'Test', payloadSchema: {}, position: { x: 500, y: 500 } },
341
+ ],
342
+ events: [],
343
+ rules: [],
344
+ };
345
+
346
+ const projection = createCanvasProjection({ respectExisting: true });
347
+ const result = projection.projectSchema(schemaWithPositions);
348
+
349
+ expect(result.positions.get('fact1')).toEqual({ x: 500, y: 500 });
350
+ });
351
+
352
+ it('should use hierarchical layout', () => {
353
+ const projection = createCanvasProjection({ algorithm: 'hierarchical' });
354
+ const result = projection.projectSchema(testSchema);
355
+
356
+ expect(result.positions.size).toBe(4);
357
+ // Each node should have a valid position
358
+ for (const pos of result.positions.values()) {
359
+ expect(typeof pos.x).toBe('number');
360
+ expect(typeof pos.y).toBe('number');
361
+ }
362
+ });
363
+
364
+ it('should use grid layout', () => {
365
+ const projection = createCanvasProjection({ algorithm: 'grid' });
366
+ const result = projection.projectSchema(testSchema);
367
+
368
+ expect(result.positions.size).toBe(4);
369
+ // Grid layout should have evenly spaced positions
370
+ const positions = Array.from(result.positions.values());
371
+ // All positions should be defined
372
+ positions.forEach(pos => {
373
+ expect(pos).toBeDefined();
374
+ expect(typeof pos.x).toBe('number');
375
+ expect(typeof pos.y).toBe('number');
376
+ });
377
+ });
378
+
379
+ it('should use circular layout', () => {
380
+ const projection = createCanvasProjection({ algorithm: 'circular' });
381
+ const result = projection.projectSchema(testSchema);
382
+
383
+ expect(result.positions.size).toBe(4);
384
+ // Circular layout positions should be centered around origin
385
+ const positions = Array.from(result.positions.values());
386
+ // Check that positions exist and are numbers
387
+ positions.forEach(pos => {
388
+ expect(typeof pos.x).toBe('number');
389
+ expect(typeof pos.y).toBe('number');
390
+ });
391
+ });
392
+
393
+ it('should use force-directed layout', () => {
394
+ const projection = createCanvasProjection({ algorithm: 'force' });
395
+ const result = projection.projectSchema(testSchema);
396
+
397
+ expect(result.positions.size).toBe(4);
398
+ // Force layout should spread nodes apart
399
+ const positions = Array.from(result.positions.values());
400
+ positions.forEach(pos => {
401
+ expect(typeof pos.x).toBe('number');
402
+ expect(typeof pos.y).toBe('number');
403
+ });
404
+ });
405
+
406
+ it('should calculate bounds correctly', () => {
407
+ const projection = createCanvasProjection({ algorithm: 'grid' });
408
+ const result = projection.projectSchema(testSchema);
409
+
410
+ expect(result.bounds.minX).toBeDefined();
411
+ expect(result.bounds.minY).toBeDefined();
412
+ expect(result.bounds.maxX).toBeDefined();
413
+ expect(result.bounds.maxY).toBeDefined();
414
+ expect(result.bounds.maxX).toBeGreaterThanOrEqual(result.bounds.minX);
415
+ expect(result.bounds.maxY).toBeGreaterThanOrEqual(result.bounds.minY);
416
+ });
417
+
418
+ it('should center layout when requested', () => {
419
+ const projection = createCanvasProjection({
420
+ algorithm: 'grid',
421
+ center: true,
422
+ });
423
+ const result = projection.projectSchema(testSchema);
424
+
425
+ // With centering, the average position should be near (0, 0)
426
+ let sumX = 0, sumY = 0;
427
+ for (const pos of result.positions.values()) {
428
+ sumX += pos.x;
429
+ sumY += pos.y;
430
+ }
431
+ const avgX = sumX / result.positions.size;
432
+ const avgY = sumY / result.positions.size;
433
+
434
+ // Average should be close to 0 (allowing for rounding)
435
+ expect(Math.abs(avgX)).toBeLessThan(100);
436
+ expect(Math.abs(avgY)).toBeLessThan(100);
437
+ });
438
+ });
439
+
440
+ describe('Canvas Component Props', () => {
441
+ it('should export component prop types', async () => {
442
+ const {
443
+ createCanvasStateManager,
444
+ createCanvasProjection,
445
+ } = await import('../../ui/canvas/components/index.js');
446
+
447
+ expect(createCanvasStateManager).toBeDefined();
448
+ expect(createCanvasProjection).toBeDefined();
449
+ });
450
+ });
@@ -0,0 +1,178 @@
1
+ /**
2
+ * CLI Create Command Tests
3
+ *
4
+ * Tests for the praxis create command.
5
+ */
6
+
7
+ import { describe, test, expect, beforeEach, afterEach } from 'vitest';
8
+ import { existsSync } from 'fs';
9
+ import { rm, readFile, mkdir } from 'fs/promises';
10
+ import { join } from 'path';
11
+ import { tmpdir } from 'os';
12
+ import { create, type CreateOptions } from '../cli/commands/create.js';
13
+
14
+ // Use a unique temp directory for each test run
15
+ const TEST_DIR = join(tmpdir(), 'praxis-create-tests-' + Date.now());
16
+
17
+ describe('CLI Create Command', () => {
18
+ beforeEach(async () => {
19
+ await mkdir(TEST_DIR, { recursive: true });
20
+ process.chdir(TEST_DIR);
21
+ });
22
+
23
+ afterEach(async () => {
24
+ // Clean up test directory
25
+ try {
26
+ await rm(TEST_DIR, { recursive: true, force: true });
27
+ } catch {
28
+ // Ignore cleanup errors
29
+ }
30
+ });
31
+
32
+ describe('create app', () => {
33
+ test('should create a new app with basic template', async () => {
34
+ const appName = 'my-test-app';
35
+ const options: CreateOptions = { template: 'basic' };
36
+
37
+ // Mock console.log to suppress output
38
+ const originalLog = console.log;
39
+ console.log = () => {};
40
+
41
+ try {
42
+ await create('app', appName, options);
43
+
44
+ // Verify directory structure
45
+ const appDir = join(TEST_DIR, appName);
46
+ expect(existsSync(appDir)).toBe(true);
47
+ expect(existsSync(join(appDir, 'package.json'))).toBe(true);
48
+ expect(existsSync(join(appDir, 'tsconfig.json'))).toBe(true);
49
+ expect(existsSync(join(appDir, 'vite.config.ts'))).toBe(true);
50
+ expect(existsSync(join(appDir, 'src', 'App.svelte'))).toBe(true);
51
+ expect(existsSync(join(appDir, 'src', 'main.ts'))).toBe(true);
52
+ expect(existsSync(join(appDir, 'src', 'schemas', 'app.schema.js'))).toBe(true);
53
+
54
+ // Verify package.json content
55
+ const packageJson = JSON.parse(await readFile(join(appDir, 'package.json'), 'utf-8'));
56
+ expect(packageJson.name).toBe(appName);
57
+ expect(packageJson.dependencies['@plures/praxis']).toBeDefined();
58
+ expect(packageJson.scripts.dev).toBe('vite');
59
+ expect(packageJson.scripts.generate).toBe('praxis generate');
60
+ } finally {
61
+ console.log = originalLog;
62
+ }
63
+ });
64
+
65
+ test('should fail for app with invalid name', async () => {
66
+ const originalLog = console.log;
67
+ const originalError = console.error;
68
+ const originalExit = process.exit;
69
+
70
+ console.log = () => {};
71
+ console.error = () => {};
72
+
73
+ let exitCode: number | undefined;
74
+ process.exit = ((code?: number) => {
75
+ exitCode = code;
76
+ throw new Error('process.exit called');
77
+ }) as never;
78
+
79
+ try {
80
+ await create('app', '123invalid', {});
81
+ } catch (e) {
82
+ // Expected to throw due to process.exit mock
83
+ } finally {
84
+ console.log = originalLog;
85
+ console.error = originalError;
86
+ process.exit = originalExit;
87
+ }
88
+
89
+ expect(exitCode).toBe(1);
90
+ });
91
+ });
92
+
93
+ describe('create component', () => {
94
+ test('should create a new component', async () => {
95
+ const componentName = 'MyButton';
96
+ const componentDir = join(TEST_DIR, 'components');
97
+ await mkdir(componentDir, { recursive: true });
98
+
99
+ const options: CreateOptions = { directory: componentDir };
100
+
101
+ // Mock console.log to suppress output
102
+ const originalLog = console.log;
103
+ console.log = () => {};
104
+
105
+ try {
106
+ await create('component', componentName, options);
107
+
108
+ // Verify component files
109
+ const outputDir = join(componentDir, componentName);
110
+ expect(existsSync(join(outputDir, `${componentName}.svelte`))).toBe(true);
111
+ expect(existsSync(join(outputDir, `${componentName}.schema.js`))).toBe(true);
112
+ expect(existsSync(join(outputDir, 'index.ts'))).toBe(true);
113
+
114
+ // Verify index.ts content
115
+ const indexContent = await readFile(join(outputDir, 'index.ts'), 'utf-8');
116
+ expect(indexContent).toContain(`export { default as ${componentName} }`);
117
+ } finally {
118
+ console.log = originalLog;
119
+ }
120
+ });
121
+
122
+ test('should fail without a name', async () => {
123
+ const originalLog = console.log;
124
+ const originalError = console.error;
125
+ const originalExit = process.exit;
126
+
127
+ console.log = () => {};
128
+ console.error = () => {};
129
+
130
+ let exitCode: number | undefined;
131
+ process.exit = ((code?: number) => {
132
+ exitCode = code;
133
+ throw new Error('process.exit called');
134
+ }) as never;
135
+
136
+ try {
137
+ await create('component', undefined, {});
138
+ } catch (e) {
139
+ // Expected to throw due to process.exit mock
140
+ } finally {
141
+ console.log = originalLog;
142
+ console.error = originalError;
143
+ process.exit = originalExit;
144
+ }
145
+
146
+ expect(exitCode).toBe(1);
147
+ });
148
+ });
149
+
150
+ describe('unknown type', () => {
151
+ test('should fail for unknown type', async () => {
152
+ const originalLog = console.log;
153
+ const originalError = console.error;
154
+ const originalExit = process.exit;
155
+
156
+ console.log = () => {};
157
+ console.error = () => {};
158
+
159
+ let exitCode: number | undefined;
160
+ process.exit = ((code?: number) => {
161
+ exitCode = code;
162
+ throw new Error('process.exit called');
163
+ }) as never;
164
+
165
+ try {
166
+ await create('unknown', 'test', {});
167
+ } catch (e) {
168
+ // Expected to throw due to process.exit mock
169
+ } finally {
170
+ console.log = originalLog;
171
+ console.error = originalError;
172
+ process.exit = originalExit;
173
+ }
174
+
175
+ expect(exitCode).toBe(1);
176
+ });
177
+ });
178
+ });