@plures/praxis 1.0.2 → 1.1.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 (518) hide show
  1. package/FRAMEWORK.md +55 -5
  2. package/LICENSE +21 -21
  3. package/README.md +162 -375
  4. package/core/codegen/docs-generator.ts +5 -2
  5. package/core/codegen/index.ts +1 -1
  6. package/core/codegen/ts-generator.ts +15 -15
  7. package/core/db-adapter/index.ts +2 -2
  8. package/core/db-adapter/sync-engine.ts +17 -6
  9. package/core/logic-engine/engine.ts +1 -1
  10. package/core/logic-engine/index.ts +2 -2
  11. package/core/logic-engine/protocol.ts +1 -1
  12. package/core/logic-engine/psf-adapter.ts +8 -4
  13. package/core/logic-engine/rules.ts +1 -1
  14. package/core/schema-engine/compiler.ts +53 -11
  15. package/core/schema-engine/generator.ts +17 -7
  16. package/core/schema-engine/index.ts +2 -2
  17. package/core/schema-engine/psf.ts +12 -3
  18. package/core/schema-engine/types.ts +3 -11
  19. package/core/schema-engine/validator.ts +112 -22
  20. package/dist/browser/engine-BjdqxeXG.d.ts +333 -0
  21. package/dist/browser/index.d.ts +3004 -0
  22. package/dist/browser/index.js +2892 -0
  23. package/dist/{src → browser}/integrations/svelte.d.ts +19 -17
  24. package/dist/browser/integrations/svelte.js +298 -0
  25. package/dist/node/auth-STARLY7I.js +207 -0
  26. package/dist/node/build-Y7OT5VBF.js +144 -0
  27. package/dist/node/canvas-UERZHJYW.js +362 -0
  28. package/dist/node/chunk-DSDC2JWZ.js +256 -0
  29. package/dist/node/chunk-FXQZXAWF.js +175 -0
  30. package/dist/node/chunk-N5Y37EUV.js +202 -0
  31. package/dist/node/chunk-QGM4M3NI.js +37 -0
  32. package/dist/node/chunk-RJMWCNHR.js +175 -0
  33. package/dist/node/chunk-SRM3OPPM.js +404 -0
  34. package/dist/node/chunk-UATVJBNV.js +175 -0
  35. package/dist/node/chunk-UY7YEBE2.js +159 -0
  36. package/dist/node/chunk-XCY2VIFX.js +143 -0
  37. package/dist/node/chunk-YXH4Y7ZZ.js +349 -0
  38. package/dist/node/cli/index.cjs +217418 -0
  39. package/dist/node/cli/index.d.cts +1 -0
  40. package/dist/node/cli/index.d.ts +1 -0
  41. package/dist/node/cli/index.js +690 -0
  42. package/dist/node/cloud/index.cjs +1043 -0
  43. package/dist/node/cloud/index.d.cts +864 -0
  44. package/dist/node/cloud/index.d.ts +864 -0
  45. package/dist/node/cloud/index.js +456 -0
  46. package/dist/node/cloud-AXOK4PSN.js +212 -0
  47. package/dist/node/component.cjs +374 -0
  48. package/dist/node/component.d.cts +125 -0
  49. package/dist/{src/core/component/generator.d.ts → node/component.d.ts} +11 -8
  50. package/dist/node/component.js +9 -0
  51. package/dist/node/components/index.cjs +216 -0
  52. package/dist/node/components/index.d.cts +43 -0
  53. package/dist/{src → node}/components/index.d.ts +8 -8
  54. package/dist/node/components/index.js +7 -0
  55. package/dist/node/create-TRLSVCNQ.js +584 -0
  56. package/dist/node/dev-PMJZUYGE.js +65 -0
  57. package/dist/node/engine-1iqLe6_P.d.ts +214 -0
  58. package/dist/node/engine-CVJobhHm.d.cts +214 -0
  59. package/dist/node/index.cjs +3247 -0
  60. package/dist/node/index.d.cts +2579 -0
  61. package/dist/node/index.d.ts +2579 -0
  62. package/dist/node/index.js +2098 -0
  63. package/dist/node/integrations/svelte.cjs +330 -0
  64. package/dist/node/integrations/svelte.d.cts +309 -0
  65. package/dist/node/integrations/svelte.d.ts +309 -0
  66. package/dist/node/integrations/svelte.js +300 -0
  67. package/dist/node/orchestrate-737TCL5H.js +127 -0
  68. package/dist/{src/core/protocol.d.ts → node/protocol-Qek7ebBl.d.cts} +11 -10
  69. package/dist/node/protocol-Qek7ebBl.d.ts +122 -0
  70. package/dist/node/schema.cjs +200 -0
  71. package/dist/{src/core/schema/types.d.ts → node/schema.d.cts} +30 -29
  72. package/dist/node/schema.d.ts +371 -0
  73. package/dist/node/schema.js +9 -0
  74. package/dist/{src/runtime/terminal-adapter.d.ts → node/terminal-adapter-07HGftGQ.d.ts} +86 -11
  75. package/dist/node/terminal-adapter-XLtCjjb_.d.cts +231 -0
  76. package/dist/node/verify-YBZ7W24H.js +213239 -0
  77. package/docs/MONETIZATION.md +21 -16
  78. package/docs/REACTIVE_REDESIGN.md +132 -0
  79. package/docs/README.md +47 -36
  80. package/docs/SVELTE_INTEGRATION_STRATEGY.md +68 -0
  81. package/docs/TERMINAL_NODE.md +27 -24
  82. package/docs/core/building-extensions.md +58 -61
  83. package/docs/core/cli-usage.md +59 -59
  84. package/docs/core/code-canvas-sync.md +28 -16
  85. package/docs/core/logic-engine.md +77 -82
  86. package/docs/core/pluresdb-integration.md +29 -39
  87. package/docs/core/schema-model.md +66 -52
  88. package/docs/core/ui-generation.md +57 -49
  89. package/docs/core/what-is-praxis.md +32 -15
  90. package/docs/guides/canvas.md +21 -5
  91. package/docs/guides/getting-started.md +13 -7
  92. package/docs/guides/history-state-pattern.md +65 -51
  93. package/docs/guides/orchestration.md +46 -32
  94. package/docs/guides/parallel-state-pattern.md +56 -72
  95. package/docs/guides/svelte-integration.md +45 -53
  96. package/docs/tutorials/README.md +16 -0
  97. package/docs/tutorials/ecommerce-cart.md +177 -95
  98. package/docs/tutorials/first-app.md +26 -41
  99. package/docs/tutorials/form-builder.md +191 -138
  100. package/docs/tutorials/todo-pluresdb.md +71 -69
  101. package/package.json +132 -96
  102. package/src/__tests__/actors.test.ts +68 -68
  103. package/src/__tests__/billing.test.ts +32 -32
  104. package/src/__tests__/canvas-components.test.ts +94 -73
  105. package/src/__tests__/cli-create.test.ts +28 -28
  106. package/src/__tests__/cloud.test.ts +36 -36
  107. package/src/__tests__/code-canvas-integration.test.ts +132 -141
  108. package/src/__tests__/docs-generator.test.ts +3 -9
  109. package/src/__tests__/dsl.test.ts +58 -64
  110. package/src/__tests__/edge-cases.test.ts +106 -108
  111. package/src/__tests__/engine.test.ts +51 -25
  112. package/src/__tests__/generators.test.ts +42 -44
  113. package/src/__tests__/introspection.test.ts +104 -114
  114. package/src/__tests__/pluresdb.test.ts +189 -187
  115. package/src/__tests__/protocol.test.ts +15 -15
  116. package/src/__tests__/provisioning.test.ts +61 -61
  117. package/src/__tests__/schema.test.ts +7 -11
  118. package/src/__tests__/state-docs-integration.test.ts +162 -145
  119. package/src/__tests__/svelte-integration.test.ts +16 -19
  120. package/src/__tests__/tauri-integration.test.ts +149 -147
  121. package/src/__tests__/terminal-node.test.ts +12 -7
  122. package/src/__tests__/unum-integration.test.ts +68 -68
  123. package/src/adapters/cli.ts +21 -15
  124. package/src/cli/commands/auth.ts +82 -78
  125. package/src/cli/commands/build.ts +29 -27
  126. package/src/cli/commands/canvas.ts +338 -127
  127. package/src/cli/commands/cloud.ts +47 -47
  128. package/src/cli/commands/create.ts +59 -47
  129. package/src/cli/commands/dev.ts +12 -12
  130. package/src/cli/commands/generate.ts +29 -40
  131. package/src/cli/commands/orchestrate.ts +24 -24
  132. package/src/cli/commands/verify.ts +49 -0
  133. package/src/cli/index.ts +21 -2
  134. package/src/cloud/README.md +28 -15
  135. package/src/cloud/auth.ts +55 -70
  136. package/src/cloud/billing.ts +59 -58
  137. package/src/cloud/client.ts +29 -35
  138. package/src/cloud/index.ts +19 -40
  139. package/src/cloud/marketplace.ts +69 -78
  140. package/src/cloud/provisioning.ts +42 -51
  141. package/src/cloud/relay/endpoints.ts +30 -34
  142. package/src/cloud/relay/health/index.ts +1 -1
  143. package/src/cloud/relay/stats/index.ts +1 -1
  144. package/src/cloud/relay/sync/index.ts +1 -1
  145. package/src/cloud/relay/usage/index.ts +1 -1
  146. package/src/cloud/sponsors.ts +31 -34
  147. package/src/cloud/types.ts +4 -4
  148. package/src/components/README.md +1 -0
  149. package/src/components/TerminalNode.svelte +457 -457
  150. package/src/components/index.ts +3 -4
  151. package/src/core/actors.ts +7 -7
  152. package/src/core/component/generator.ts +10 -28
  153. package/src/core/engine.ts +51 -24
  154. package/src/core/introspection.ts +37 -35
  155. package/src/core/logic/generator.ts +62 -62
  156. package/src/core/pluresdb/adapter.ts +8 -8
  157. package/src/core/pluresdb/generator.ts +39 -35
  158. package/src/core/pluresdb/index.ts +9 -12
  159. package/src/core/pluresdb/schema-registry.ts +22 -25
  160. package/src/core/pluresdb/store.ts +57 -57
  161. package/src/core/protocol.ts +14 -14
  162. package/src/core/reactive-engine.svelte.ts +65 -0
  163. package/src/core/reactive-engine.ts +67 -0
  164. package/src/core/rules.ts +4 -4
  165. package/src/core/schema/loader.common.ts +150 -0
  166. package/src/core/schema/loader.ts +19 -149
  167. package/src/core/schema/normalize.ts +34 -51
  168. package/src/core/schema/types.ts +47 -11
  169. package/src/dsl/index.ts +8 -8
  170. package/src/dsl.ts +11 -17
  171. package/src/examples/advanced-todo/App.svelte +506 -506
  172. package/src/examples/advanced-todo/README.md +58 -40
  173. package/src/examples/advanced-todo/index.ts +3 -3
  174. package/src/examples/auth-basic/index.ts +30 -30
  175. package/src/examples/cart/index.ts +50 -50
  176. package/src/examples/hero-ecommerce/index.ts +130 -157
  177. package/src/examples/svelte-counter/index.ts +22 -26
  178. package/src/flows.ts +6 -17
  179. package/src/index.browser.ts +204 -0
  180. package/src/index.ts +37 -42
  181. package/src/integrations/code-canvas.ts +237 -193
  182. package/src/integrations/pluresdb.ts +55 -35
  183. package/src/integrations/state-docs.ts +104 -104
  184. package/src/integrations/svelte.ts +35 -35
  185. package/src/integrations/tauri.ts +75 -73
  186. package/src/integrations/unum.ts +68 -61
  187. package/src/registry.ts +7 -14
  188. package/src/runtime/terminal-adapter.ts +31 -26
  189. package/src/step.ts +10 -16
  190. package/src/types.ts +1 -1
  191. package/templates/basic-app/README.md +6 -9
  192. package/templates/fullstack-app/README.md +10 -0
  193. package/dist/core/codegen/docs-generator.d.ts +0 -123
  194. package/dist/core/codegen/docs-generator.d.ts.map +0 -1
  195. package/dist/core/codegen/docs-generator.js +0 -674
  196. package/dist/core/codegen/docs-generator.js.map +0 -1
  197. package/dist/core/codegen/index.d.ts +0 -11
  198. package/dist/core/codegen/index.d.ts.map +0 -1
  199. package/dist/core/codegen/index.js +0 -13
  200. package/dist/core/codegen/index.js.map +0 -1
  201. package/dist/core/codegen/ts-generator.d.ts +0 -8
  202. package/dist/core/codegen/ts-generator.d.ts.map +0 -1
  203. package/dist/core/codegen/ts-generator.js +0 -8
  204. package/dist/core/codegen/ts-generator.js.map +0 -1
  205. package/dist/core/db-adapter/index.d.ts +0 -18
  206. package/dist/core/db-adapter/index.d.ts.map +0 -1
  207. package/dist/core/db-adapter/index.js +0 -23
  208. package/dist/core/db-adapter/index.js.map +0 -1
  209. package/dist/core/db-adapter/sync-engine.d.ts +0 -180
  210. package/dist/core/db-adapter/sync-engine.d.ts.map +0 -1
  211. package/dist/core/db-adapter/sync-engine.js +0 -342
  212. package/dist/core/db-adapter/sync-engine.js.map +0 -1
  213. package/dist/core/logic-engine/engine.d.ts +0 -8
  214. package/dist/core/logic-engine/engine.d.ts.map +0 -1
  215. package/dist/core/logic-engine/engine.js +0 -8
  216. package/dist/core/logic-engine/engine.js.map +0 -1
  217. package/dist/core/logic-engine/index.d.ts +0 -16
  218. package/dist/core/logic-engine/index.d.ts.map +0 -1
  219. package/dist/core/logic-engine/index.js +0 -16
  220. package/dist/core/logic-engine/index.js.map +0 -1
  221. package/dist/core/logic-engine/protocol.d.ts +0 -7
  222. package/dist/core/logic-engine/protocol.d.ts.map +0 -1
  223. package/dist/core/logic-engine/protocol.js +0 -7
  224. package/dist/core/logic-engine/protocol.js.map +0 -1
  225. package/dist/core/logic-engine/psf-adapter.d.ts +0 -88
  226. package/dist/core/logic-engine/psf-adapter.d.ts.map +0 -1
  227. package/dist/core/logic-engine/psf-adapter.js +0 -207
  228. package/dist/core/logic-engine/psf-adapter.js.map +0 -1
  229. package/dist/core/logic-engine/rules.d.ts +0 -7
  230. package/dist/core/logic-engine/rules.d.ts.map +0 -1
  231. package/dist/core/logic-engine/rules.js +0 -7
  232. package/dist/core/logic-engine/rules.js.map +0 -1
  233. package/dist/core/schema-engine/compiler.d.ts +0 -198
  234. package/dist/core/schema-engine/compiler.d.ts.map +0 -1
  235. package/dist/core/schema-engine/compiler.js +0 -262
  236. package/dist/core/schema-engine/compiler.js.map +0 -1
  237. package/dist/core/schema-engine/generator.d.ts +0 -115
  238. package/dist/core/schema-engine/generator.d.ts.map +0 -1
  239. package/dist/core/schema-engine/generator.js +0 -506
  240. package/dist/core/schema-engine/generator.js.map +0 -1
  241. package/dist/core/schema-engine/index.d.ts +0 -18
  242. package/dist/core/schema-engine/index.d.ts.map +0 -1
  243. package/dist/core/schema-engine/index.js +0 -18
  244. package/dist/core/schema-engine/index.js.map +0 -1
  245. package/dist/core/schema-engine/psf.d.ts +0 -612
  246. package/dist/core/schema-engine/psf.d.ts.map +0 -1
  247. package/dist/core/schema-engine/psf.js +0 -45
  248. package/dist/core/schema-engine/psf.js.map +0 -1
  249. package/dist/core/schema-engine/types.d.ts +0 -10
  250. package/dist/core/schema-engine/types.d.ts.map +0 -1
  251. package/dist/core/schema-engine/types.js +0 -7
  252. package/dist/core/schema-engine/types.js.map +0 -1
  253. package/dist/core/schema-engine/validator.d.ts +0 -140
  254. package/dist/core/schema-engine/validator.d.ts.map +0 -1
  255. package/dist/core/schema-engine/validator.js +0 -407
  256. package/dist/core/schema-engine/validator.js.map +0 -1
  257. package/dist/src/adapters/cli.d.ts +0 -43
  258. package/dist/src/adapters/cli.d.ts.map +0 -1
  259. package/dist/src/adapters/cli.js +0 -126
  260. package/dist/src/adapters/cli.js.map +0 -1
  261. package/dist/src/cli/commands/auth.d.ts +0 -26
  262. package/dist/src/cli/commands/auth.d.ts.map +0 -1
  263. package/dist/src/cli/commands/auth.js +0 -233
  264. package/dist/src/cli/commands/auth.js.map +0 -1
  265. package/dist/src/cli/commands/build.d.ts +0 -23
  266. package/dist/src/cli/commands/build.d.ts.map +0 -1
  267. package/dist/src/cli/commands/build.js +0 -162
  268. package/dist/src/cli/commands/build.js.map +0 -1
  269. package/dist/src/cli/commands/canvas.d.ts +0 -23
  270. package/dist/src/cli/commands/canvas.d.ts.map +0 -1
  271. package/dist/src/cli/commands/canvas.js +0 -215
  272. package/dist/src/cli/commands/canvas.js.map +0 -1
  273. package/dist/src/cli/commands/cloud.d.ts +0 -27
  274. package/dist/src/cli/commands/cloud.d.ts.map +0 -1
  275. package/dist/src/cli/commands/cloud.js +0 -232
  276. package/dist/src/cli/commands/cloud.js.map +0 -1
  277. package/dist/src/cli/commands/create.d.ts +0 -21
  278. package/dist/src/cli/commands/create.d.ts.map +0 -1
  279. package/dist/src/cli/commands/create.js +0 -621
  280. package/dist/src/cli/commands/create.js.map +0 -1
  281. package/dist/src/cli/commands/dev.d.ts +0 -21
  282. package/dist/src/cli/commands/dev.d.ts.map +0 -1
  283. package/dist/src/cli/commands/dev.js +0 -71
  284. package/dist/src/cli/commands/dev.js.map +0 -1
  285. package/dist/src/cli/commands/generate.d.ts +0 -25
  286. package/dist/src/cli/commands/generate.d.ts.map +0 -1
  287. package/dist/src/cli/commands/generate.js +0 -168
  288. package/dist/src/cli/commands/generate.js.map +0 -1
  289. package/dist/src/cli/commands/orchestrate.d.ts +0 -44
  290. package/dist/src/cli/commands/orchestrate.d.ts.map +0 -1
  291. package/dist/src/cli/commands/orchestrate.js +0 -150
  292. package/dist/src/cli/commands/orchestrate.js.map +0 -1
  293. package/dist/src/cli/index.d.ts +0 -8
  294. package/dist/src/cli/index.d.ts.map +0 -1
  295. package/dist/src/cli/index.js +0 -211
  296. package/dist/src/cli/index.js.map +0 -1
  297. package/dist/src/cloud/auth.d.ts +0 -51
  298. package/dist/src/cloud/auth.d.ts.map +0 -1
  299. package/dist/src/cloud/auth.js +0 -194
  300. package/dist/src/cloud/auth.js.map +0 -1
  301. package/dist/src/cloud/billing.d.ts +0 -184
  302. package/dist/src/cloud/billing.d.ts.map +0 -1
  303. package/dist/src/cloud/billing.js +0 -179
  304. package/dist/src/cloud/billing.js.map +0 -1
  305. package/dist/src/cloud/client.d.ts +0 -39
  306. package/dist/src/cloud/client.d.ts.map +0 -1
  307. package/dist/src/cloud/client.js +0 -176
  308. package/dist/src/cloud/client.js.map +0 -1
  309. package/dist/src/cloud/index.d.ts +0 -44
  310. package/dist/src/cloud/index.d.ts.map +0 -1
  311. package/dist/src/cloud/index.js +0 -44
  312. package/dist/src/cloud/index.js.map +0 -1
  313. package/dist/src/cloud/marketplace.d.ts +0 -166
  314. package/dist/src/cloud/marketplace.d.ts.map +0 -1
  315. package/dist/src/cloud/marketplace.js +0 -159
  316. package/dist/src/cloud/marketplace.js.map +0 -1
  317. package/dist/src/cloud/provisioning.d.ts +0 -110
  318. package/dist/src/cloud/provisioning.d.ts.map +0 -1
  319. package/dist/src/cloud/provisioning.js +0 -148
  320. package/dist/src/cloud/provisioning.js.map +0 -1
  321. package/dist/src/cloud/relay/endpoints.d.ts +0 -62
  322. package/dist/src/cloud/relay/endpoints.d.ts.map +0 -1
  323. package/dist/src/cloud/relay/endpoints.js +0 -217
  324. package/dist/src/cloud/relay/endpoints.js.map +0 -1
  325. package/dist/src/cloud/relay/health/index.d.ts +0 -5
  326. package/dist/src/cloud/relay/health/index.d.ts.map +0 -1
  327. package/dist/src/cloud/relay/health/index.js +0 -9
  328. package/dist/src/cloud/relay/health/index.js.map +0 -1
  329. package/dist/src/cloud/relay/stats/index.d.ts +0 -5
  330. package/dist/src/cloud/relay/stats/index.d.ts.map +0 -1
  331. package/dist/src/cloud/relay/stats/index.js +0 -9
  332. package/dist/src/cloud/relay/stats/index.js.map +0 -1
  333. package/dist/src/cloud/relay/sync/index.d.ts +0 -5
  334. package/dist/src/cloud/relay/sync/index.d.ts.map +0 -1
  335. package/dist/src/cloud/relay/sync/index.js +0 -9
  336. package/dist/src/cloud/relay/sync/index.js.map +0 -1
  337. package/dist/src/cloud/relay/usage/index.d.ts +0 -5
  338. package/dist/src/cloud/relay/usage/index.d.ts.map +0 -1
  339. package/dist/src/cloud/relay/usage/index.js +0 -9
  340. package/dist/src/cloud/relay/usage/index.js.map +0 -1
  341. package/dist/src/cloud/sponsors.d.ts +0 -81
  342. package/dist/src/cloud/sponsors.d.ts.map +0 -1
  343. package/dist/src/cloud/sponsors.js +0 -130
  344. package/dist/src/cloud/sponsors.js.map +0 -1
  345. package/dist/src/cloud/types.d.ts +0 -169
  346. package/dist/src/cloud/types.d.ts.map +0 -1
  347. package/dist/src/cloud/types.js +0 -7
  348. package/dist/src/cloud/types.js.map +0 -1
  349. package/dist/src/components/index.d.ts.map +0 -1
  350. package/dist/src/components/index.js +0 -17
  351. package/dist/src/components/index.js.map +0 -1
  352. package/dist/src/core/actors.d.ts +0 -95
  353. package/dist/src/core/actors.d.ts.map +0 -1
  354. package/dist/src/core/actors.js +0 -158
  355. package/dist/src/core/actors.js.map +0 -1
  356. package/dist/src/core/component/generator.d.ts.map +0 -1
  357. package/dist/src/core/component/generator.js +0 -349
  358. package/dist/src/core/component/generator.js.map +0 -1
  359. package/dist/src/core/engine.d.ts +0 -92
  360. package/dist/src/core/engine.d.ts.map +0 -1
  361. package/dist/src/core/engine.js +0 -199
  362. package/dist/src/core/engine.js.map +0 -1
  363. package/dist/src/core/introspection.d.ts +0 -141
  364. package/dist/src/core/introspection.d.ts.map +0 -1
  365. package/dist/src/core/introspection.js +0 -208
  366. package/dist/src/core/introspection.js.map +0 -1
  367. package/dist/src/core/logic/generator.d.ts +0 -76
  368. package/dist/src/core/logic/generator.d.ts.map +0 -1
  369. package/dist/src/core/logic/generator.js +0 -370
  370. package/dist/src/core/logic/generator.js.map +0 -1
  371. package/dist/src/core/pluresdb/adapter.d.ts +0 -72
  372. package/dist/src/core/pluresdb/adapter.d.ts.map +0 -1
  373. package/dist/src/core/pluresdb/adapter.js +0 -73
  374. package/dist/src/core/pluresdb/adapter.js.map +0 -1
  375. package/dist/src/core/pluresdb/generator.d.ts +0 -58
  376. package/dist/src/core/pluresdb/generator.d.ts.map +0 -1
  377. package/dist/src/core/pluresdb/generator.js +0 -191
  378. package/dist/src/core/pluresdb/generator.js.map +0 -1
  379. package/dist/src/core/pluresdb/index.d.ts +0 -15
  380. package/dist/src/core/pluresdb/index.d.ts.map +0 -1
  381. package/dist/src/core/pluresdb/index.js +0 -11
  382. package/dist/src/core/pluresdb/index.js.map +0 -1
  383. package/dist/src/core/pluresdb/schema-registry.d.ts +0 -104
  384. package/dist/src/core/pluresdb/schema-registry.d.ts.map +0 -1
  385. package/dist/src/core/pluresdb/schema-registry.js +0 -130
  386. package/dist/src/core/pluresdb/schema-registry.js.map +0 -1
  387. package/dist/src/core/pluresdb/store.d.ts +0 -199
  388. package/dist/src/core/pluresdb/store.d.ts.map +0 -1
  389. package/dist/src/core/pluresdb/store.js +0 -344
  390. package/dist/src/core/pluresdb/store.js.map +0 -1
  391. package/dist/src/core/protocol.d.ts.map +0 -1
  392. package/dist/src/core/protocol.js +0 -46
  393. package/dist/src/core/protocol.js.map +0 -1
  394. package/dist/src/core/rules.d.ts +0 -120
  395. package/dist/src/core/rules.d.ts.map +0 -1
  396. package/dist/src/core/rules.js +0 -81
  397. package/dist/src/core/rules.js.map +0 -1
  398. package/dist/src/core/schema/loader.d.ts +0 -47
  399. package/dist/src/core/schema/loader.d.ts.map +0 -1
  400. package/dist/src/core/schema/loader.js +0 -189
  401. package/dist/src/core/schema/loader.js.map +0 -1
  402. package/dist/src/core/schema/normalize.d.ts +0 -72
  403. package/dist/src/core/schema/normalize.d.ts.map +0 -1
  404. package/dist/src/core/schema/normalize.js +0 -190
  405. package/dist/src/core/schema/normalize.js.map +0 -1
  406. package/dist/src/core/schema/types.d.ts.map +0 -1
  407. package/dist/src/core/schema/types.js +0 -161
  408. package/dist/src/core/schema/types.js.map +0 -1
  409. package/dist/src/dsl/index.d.ts +0 -152
  410. package/dist/src/dsl/index.d.ts.map +0 -1
  411. package/dist/src/dsl/index.js +0 -132
  412. package/dist/src/dsl/index.js.map +0 -1
  413. package/dist/src/dsl.d.ts +0 -124
  414. package/dist/src/dsl.d.ts.map +0 -1
  415. package/dist/src/dsl.js +0 -130
  416. package/dist/src/dsl.js.map +0 -1
  417. package/dist/src/examples/advanced-todo/index.d.ts +0 -55
  418. package/dist/src/examples/advanced-todo/index.d.ts.map +0 -1
  419. package/dist/src/examples/advanced-todo/index.js +0 -222
  420. package/dist/src/examples/advanced-todo/index.js.map +0 -1
  421. package/dist/src/examples/auth-basic/index.d.ts +0 -17
  422. package/dist/src/examples/auth-basic/index.d.ts.map +0 -1
  423. package/dist/src/examples/auth-basic/index.js +0 -122
  424. package/dist/src/examples/auth-basic/index.js.map +0 -1
  425. package/dist/src/examples/cart/index.d.ts +0 -19
  426. package/dist/src/examples/cart/index.d.ts.map +0 -1
  427. package/dist/src/examples/cart/index.js +0 -202
  428. package/dist/src/examples/cart/index.js.map +0 -1
  429. package/dist/src/examples/hero-ecommerce/index.d.ts +0 -39
  430. package/dist/src/examples/hero-ecommerce/index.d.ts.map +0 -1
  431. package/dist/src/examples/hero-ecommerce/index.js +0 -506
  432. package/dist/src/examples/hero-ecommerce/index.js.map +0 -1
  433. package/dist/src/examples/svelte-counter/index.d.ts +0 -31
  434. package/dist/src/examples/svelte-counter/index.d.ts.map +0 -1
  435. package/dist/src/examples/svelte-counter/index.js +0 -123
  436. package/dist/src/examples/svelte-counter/index.js.map +0 -1
  437. package/dist/src/flows.d.ts +0 -125
  438. package/dist/src/flows.d.ts.map +0 -1
  439. package/dist/src/flows.js +0 -160
  440. package/dist/src/flows.js.map +0 -1
  441. package/dist/src/index.d.ts +0 -77
  442. package/dist/src/index.d.ts.map +0 -1
  443. package/dist/src/index.js +0 -64
  444. package/dist/src/index.js.map +0 -1
  445. package/dist/src/integrations/code-canvas.d.ts +0 -265
  446. package/dist/src/integrations/code-canvas.d.ts.map +0 -1
  447. package/dist/src/integrations/code-canvas.js +0 -451
  448. package/dist/src/integrations/code-canvas.js.map +0 -1
  449. package/dist/src/integrations/pluresdb.d.ts +0 -117
  450. package/dist/src/integrations/pluresdb.d.ts.map +0 -1
  451. package/dist/src/integrations/pluresdb.js +0 -117
  452. package/dist/src/integrations/pluresdb.js.map +0 -1
  453. package/dist/src/integrations/state-docs.d.ts +0 -191
  454. package/dist/src/integrations/state-docs.d.ts.map +0 -1
  455. package/dist/src/integrations/state-docs.js +0 -515
  456. package/dist/src/integrations/state-docs.js.map +0 -1
  457. package/dist/src/integrations/svelte.d.ts.map +0 -1
  458. package/dist/src/integrations/svelte.js +0 -447
  459. package/dist/src/integrations/svelte.js.map +0 -1
  460. package/dist/src/integrations/tauri.d.ts +0 -360
  461. package/dist/src/integrations/tauri.d.ts.map +0 -1
  462. package/dist/src/integrations/tauri.js +0 -278
  463. package/dist/src/integrations/tauri.js.map +0 -1
  464. package/dist/src/integrations/unum.d.ts +0 -159
  465. package/dist/src/integrations/unum.d.ts.map +0 -1
  466. package/dist/src/integrations/unum.js +0 -240
  467. package/dist/src/integrations/unum.js.map +0 -1
  468. package/dist/src/registry.d.ts +0 -94
  469. package/dist/src/registry.d.ts.map +0 -1
  470. package/dist/src/registry.js +0 -181
  471. package/dist/src/registry.js.map +0 -1
  472. package/dist/src/runtime/terminal-adapter.d.ts.map +0 -1
  473. package/dist/src/runtime/terminal-adapter.js +0 -239
  474. package/dist/src/runtime/terminal-adapter.js.map +0 -1
  475. package/dist/src/step.d.ts +0 -34
  476. package/dist/src/step.d.ts.map +0 -1
  477. package/dist/src/step.js +0 -111
  478. package/dist/src/step.js.map +0 -1
  479. package/dist/src/types.d.ts +0 -63
  480. package/dist/src/types.d.ts.map +0 -1
  481. package/dist/src/types.js +0 -6
  482. package/dist/src/types.js.map +0 -1
  483. package/dist/tools/cli/commands/index.d.ts +0 -7
  484. package/dist/tools/cli/commands/index.d.ts.map +0 -1
  485. package/dist/tools/cli/commands/index.js +0 -7
  486. package/dist/tools/cli/commands/index.js.map +0 -1
  487. package/dist/tools/cli/index.d.ts +0 -8
  488. package/dist/tools/cli/index.d.ts.map +0 -1
  489. package/dist/tools/cli/index.js +0 -9
  490. package/dist/tools/cli/index.js.map +0 -1
  491. package/dist/tools/watcher/index.d.ts +0 -105
  492. package/dist/tools/watcher/index.d.ts.map +0 -1
  493. package/dist/tools/watcher/index.js +0 -213
  494. package/dist/tools/watcher/index.js.map +0 -1
  495. package/dist/ui/canvas/canvas-projection.d.ts +0 -78
  496. package/dist/ui/canvas/canvas-projection.d.ts.map +0 -1
  497. package/dist/ui/canvas/canvas-projection.js +0 -416
  498. package/dist/ui/canvas/canvas-projection.js.map +0 -1
  499. package/dist/ui/canvas/canvas-state.d.ts +0 -200
  500. package/dist/ui/canvas/canvas-state.d.ts.map +0 -1
  501. package/dist/ui/canvas/canvas-state.js +0 -464
  502. package/dist/ui/canvas/canvas-state.js.map +0 -1
  503. package/dist/ui/canvas/components/index.d.ts +0 -95
  504. package/dist/ui/canvas/components/index.d.ts.map +0 -1
  505. package/dist/ui/canvas/components/index.js +0 -19
  506. package/dist/ui/canvas/components/index.js.map +0 -1
  507. package/dist/ui/canvas/index.d.ts +0 -32
  508. package/dist/ui/canvas/index.d.ts.map +0 -1
  509. package/dist/ui/canvas/index.js +0 -32
  510. package/dist/ui/canvas/index.js.map +0 -1
  511. package/dist/ui/svelte-generator/index.d.ts +0 -9
  512. package/dist/ui/svelte-generator/index.d.ts.map +0 -1
  513. package/dist/ui/svelte-generator/index.js +0 -11
  514. package/dist/ui/svelte-generator/index.js.map +0 -1
  515. package/dist/ui/svelte-generator/psf-generator.d.ts +0 -128
  516. package/dist/ui/svelte-generator/psf-generator.d.ts.map +0 -1
  517. package/dist/ui/svelte-generator/psf-generator.js +0 -506
  518. package/dist/ui/svelte-generator/psf-generator.js.map +0 -1
@@ -0,0 +1,2892 @@
1
+ // src/core/protocol.ts
2
+ var PRAXIS_PROTOCOL_VERSION = "1.0.0";
3
+
4
+ // src/core/rules.ts
5
+ var PraxisRegistry = class {
6
+ rules = /* @__PURE__ */ new Map();
7
+ constraints = /* @__PURE__ */ new Map();
8
+ /**
9
+ * Register a rule
10
+ */
11
+ registerRule(descriptor) {
12
+ if (this.rules.has(descriptor.id)) {
13
+ throw new Error(`Rule with id "${descriptor.id}" already registered`);
14
+ }
15
+ this.rules.set(descriptor.id, descriptor);
16
+ }
17
+ /**
18
+ * Register a constraint
19
+ */
20
+ registerConstraint(descriptor) {
21
+ if (this.constraints.has(descriptor.id)) {
22
+ throw new Error(`Constraint with id "${descriptor.id}" already registered`);
23
+ }
24
+ this.constraints.set(descriptor.id, descriptor);
25
+ }
26
+ /**
27
+ * Register a module (all its rules and constraints)
28
+ */
29
+ registerModule(module) {
30
+ for (const rule of module.rules) {
31
+ this.registerRule(rule);
32
+ }
33
+ for (const constraint of module.constraints) {
34
+ this.registerConstraint(constraint);
35
+ }
36
+ }
37
+ /**
38
+ * Get a rule by ID
39
+ */
40
+ getRule(id) {
41
+ return this.rules.get(id);
42
+ }
43
+ /**
44
+ * Get a constraint by ID
45
+ */
46
+ getConstraint(id) {
47
+ return this.constraints.get(id);
48
+ }
49
+ /**
50
+ * Get all registered rule IDs
51
+ */
52
+ getRuleIds() {
53
+ return Array.from(this.rules.keys());
54
+ }
55
+ /**
56
+ * Get all registered constraint IDs
57
+ */
58
+ getConstraintIds() {
59
+ return Array.from(this.constraints.keys());
60
+ }
61
+ /**
62
+ * Get all rules
63
+ */
64
+ getAllRules() {
65
+ return Array.from(this.rules.values());
66
+ }
67
+ /**
68
+ * Get all constraints
69
+ */
70
+ getAllConstraints() {
71
+ return Array.from(this.constraints.values());
72
+ }
73
+ };
74
+
75
+ // src/core/engine.ts
76
+ function safeClone(value) {
77
+ if (value === null || typeof value !== "object") {
78
+ return value;
79
+ }
80
+ if (typeof globalThis.structuredClone === "function") {
81
+ try {
82
+ return globalThis.structuredClone(value);
83
+ } catch {
84
+ }
85
+ }
86
+ if (Array.isArray(value)) {
87
+ return [...value];
88
+ }
89
+ return { ...value };
90
+ }
91
+ var LogicEngine = class {
92
+ state;
93
+ registry;
94
+ constructor(options) {
95
+ this.registry = options.registry;
96
+ this.state = {
97
+ context: options.initialContext,
98
+ facts: options.initialFacts ?? [],
99
+ meta: options.initialMeta ?? {},
100
+ protocolVersion: PRAXIS_PROTOCOL_VERSION
101
+ };
102
+ }
103
+ /**
104
+ * Get the current state (immutable copy)
105
+ */
106
+ getState() {
107
+ return {
108
+ context: safeClone(this.state.context),
109
+ facts: [...this.state.facts],
110
+ meta: this.state.meta ? safeClone(this.state.meta) : void 0,
111
+ protocolVersion: this.state.protocolVersion
112
+ };
113
+ }
114
+ /**
115
+ * Get the current context
116
+ */
117
+ getContext() {
118
+ return safeClone(this.state.context);
119
+ }
120
+ /**
121
+ * Get current facts
122
+ */
123
+ getFacts() {
124
+ return [...this.state.facts];
125
+ }
126
+ /**
127
+ * Process events through the engine.
128
+ * Applies all registered rules and checks all registered constraints.
129
+ *
130
+ * @param events Events to process
131
+ * @returns Result with new state and diagnostics
132
+ */
133
+ step(events) {
134
+ const config = {
135
+ ruleIds: this.registry.getRuleIds(),
136
+ constraintIds: this.registry.getConstraintIds()
137
+ };
138
+ return this.stepWithConfig(events, config);
139
+ }
140
+ /**
141
+ * Process events with specific rule and constraint configuration.
142
+ *
143
+ * @param events Events to process
144
+ * @param config Step configuration
145
+ * @returns Result with new state and diagnostics
146
+ */
147
+ stepWithConfig(events, config) {
148
+ const diagnostics = [];
149
+ let newState = { ...this.state };
150
+ const newFacts = [];
151
+ for (const ruleId of config.ruleIds) {
152
+ const rule = this.registry.getRule(ruleId);
153
+ if (!rule) {
154
+ diagnostics.push({
155
+ kind: "rule-error",
156
+ message: `Rule "${ruleId}" not found in registry`,
157
+ data: { ruleId }
158
+ });
159
+ continue;
160
+ }
161
+ try {
162
+ const ruleFacts = rule.impl(newState, events);
163
+ newFacts.push(...ruleFacts);
164
+ } catch (error) {
165
+ diagnostics.push({
166
+ kind: "rule-error",
167
+ message: `Error executing rule "${ruleId}": ${error instanceof Error ? error.message : String(error)}`,
168
+ data: { ruleId, error }
169
+ });
170
+ }
171
+ }
172
+ newState = {
173
+ ...newState,
174
+ facts: [...newState.facts, ...newFacts]
175
+ };
176
+ for (const constraintId of config.constraintIds) {
177
+ const constraint = this.registry.getConstraint(constraintId);
178
+ if (!constraint) {
179
+ diagnostics.push({
180
+ kind: "constraint-violation",
181
+ message: `Constraint "${constraintId}" not found in registry`,
182
+ data: { constraintId }
183
+ });
184
+ continue;
185
+ }
186
+ try {
187
+ const result = constraint.impl(newState);
188
+ if (result === false) {
189
+ diagnostics.push({
190
+ kind: "constraint-violation",
191
+ message: `Constraint "${constraintId}" violated`,
192
+ data: { constraintId, description: constraint.description }
193
+ });
194
+ } else if (typeof result === "string") {
195
+ diagnostics.push({
196
+ kind: "constraint-violation",
197
+ message: result,
198
+ data: { constraintId, description: constraint.description }
199
+ });
200
+ }
201
+ } catch (error) {
202
+ diagnostics.push({
203
+ kind: "constraint-violation",
204
+ message: `Error checking constraint "${constraintId}": ${error instanceof Error ? error.message : String(error)}`,
205
+ data: { constraintId, error }
206
+ });
207
+ }
208
+ }
209
+ this.state = newState;
210
+ return {
211
+ state: newState,
212
+ diagnostics
213
+ };
214
+ }
215
+ /**
216
+ * Update the context directly (for exceptional cases).
217
+ * Generally, context should be updated through rules.
218
+ *
219
+ * @param updater Function that produces new context from old context
220
+ */
221
+ updateContext(updater) {
222
+ this.state = {
223
+ ...this.state,
224
+ context: updater(this.state.context)
225
+ };
226
+ }
227
+ /**
228
+ * Add facts directly (for exceptional cases).
229
+ * Generally, facts should be added through rules.
230
+ *
231
+ * @param facts Facts to add
232
+ */
233
+ addFacts(facts) {
234
+ this.state = {
235
+ ...this.state,
236
+ facts: [...this.state.facts, ...facts]
237
+ };
238
+ }
239
+ /**
240
+ * Clear all facts
241
+ */
242
+ clearFacts() {
243
+ this.state = {
244
+ ...this.state,
245
+ facts: []
246
+ };
247
+ }
248
+ /**
249
+ * Reset the engine to initial state
250
+ */
251
+ reset(options) {
252
+ this.state = {
253
+ context: options.initialContext,
254
+ facts: options.initialFacts ?? [],
255
+ meta: options.initialMeta ?? {},
256
+ protocolVersion: PRAXIS_PROTOCOL_VERSION
257
+ };
258
+ }
259
+ };
260
+ function createPraxisEngine(options) {
261
+ return new LogicEngine(options);
262
+ }
263
+
264
+ // src/core/reactive-engine.svelte.ts
265
+ import * as $ from "svelte/internal/client";
266
+ var ReactiveLogicEngine = class {
267
+ #state = (
268
+ // The single source of truth, reactive by default
269
+ // We use $state.raw for things that shouldn't be deeply reactive if needed,
270
+ // but for context we usually want deep reactivity.
271
+ $.state($.proxy({ context: {}, facts: [], meta: {} }))
272
+ );
273
+ get state() {
274
+ return $.get(this.#state);
275
+ }
276
+ set state(value) {
277
+ $.set(this.#state, value, true);
278
+ }
279
+ constructor(options) {
280
+ this.state.context = options.initialContext;
281
+ this.state.facts = options.initialFacts ?? [];
282
+ this.state.meta = options.initialMeta ?? {};
283
+ }
284
+ /**
285
+ * Access the reactive context directly.
286
+ * Consumers can use this in $derived() or $effect().
287
+ */
288
+ get context() {
289
+ return this.state.context;
290
+ }
291
+ /**
292
+ * Access the reactive facts list.
293
+ */
294
+ get facts() {
295
+ return this.state.facts;
296
+ }
297
+ /**
298
+ * Apply a mutation to the state.
299
+ * This is the "Action" or "Rule" equivalent.
300
+ *
301
+ * @param mutator A function that receives the state and modifies it.
302
+ */
303
+ apply(mutator) {
304
+ mutator(this.state);
305
+ }
306
+ /**
307
+ * Access the reactive meta.
308
+ */
309
+ get meta() {
310
+ return this.state.meta;
311
+ }
312
+ };
313
+
314
+ // src/core/actors.ts
315
+ var ActorManager = class {
316
+ actors = /* @__PURE__ */ new Map();
317
+ activeActors = /* @__PURE__ */ new Set();
318
+ engine = null;
319
+ /**
320
+ * Register an actor
321
+ */
322
+ register(actor) {
323
+ if (this.actors.has(actor.id)) {
324
+ throw new Error(`Actor with id "${actor.id}" already registered`);
325
+ }
326
+ this.actors.set(actor.id, actor);
327
+ }
328
+ /**
329
+ * Unregister an actor
330
+ */
331
+ unregister(actorId) {
332
+ if (this.activeActors.has(actorId)) {
333
+ throw new Error(`Cannot unregister active actor "${actorId}". Stop it first.`);
334
+ }
335
+ this.actors.delete(actorId);
336
+ }
337
+ /**
338
+ * Attach the actor manager to an engine
339
+ */
340
+ attachEngine(engine) {
341
+ this.engine = engine;
342
+ }
343
+ /**
344
+ * Start an actor
345
+ */
346
+ async start(actorId) {
347
+ const actor = this.actors.get(actorId);
348
+ if (!actor) {
349
+ throw new Error(`Actor "${actorId}" not found`);
350
+ }
351
+ if (this.activeActors.has(actorId)) {
352
+ throw new Error(`Actor "${actorId}" is already started`);
353
+ }
354
+ if (!this.engine) {
355
+ throw new Error("Actor manager not attached to an engine");
356
+ }
357
+ this.activeActors.add(actorId);
358
+ if (actor.onStart) {
359
+ await actor.onStart(this.engine);
360
+ }
361
+ }
362
+ /**
363
+ * Stop an actor
364
+ */
365
+ async stop(actorId) {
366
+ const actor = this.actors.get(actorId);
367
+ if (!actor) {
368
+ throw new Error(`Actor "${actorId}" not found`);
369
+ }
370
+ if (!this.activeActors.has(actorId)) {
371
+ return;
372
+ }
373
+ this.activeActors.delete(actorId);
374
+ if (actor.onStop) {
375
+ await actor.onStop();
376
+ }
377
+ }
378
+ /**
379
+ * Start all registered actors
380
+ */
381
+ async startAll() {
382
+ const actorIds = Array.from(this.actors.keys());
383
+ for (const actorId of actorIds) {
384
+ if (!this.activeActors.has(actorId)) {
385
+ await this.start(actorId);
386
+ }
387
+ }
388
+ }
389
+ /**
390
+ * Stop all active actors
391
+ */
392
+ async stopAll() {
393
+ const activeIds = Array.from(this.activeActors);
394
+ for (const actorId of activeIds) {
395
+ await this.stop(actorId);
396
+ }
397
+ }
398
+ /**
399
+ * Notify active actors of a state change
400
+ */
401
+ async notifyStateChange(state2) {
402
+ if (!this.engine) {
403
+ return;
404
+ }
405
+ const promises = [];
406
+ for (const actorId of this.activeActors) {
407
+ const actor = this.actors.get(actorId);
408
+ if (actor?.onStateChange) {
409
+ const result = actor.onStateChange(state2, this.engine);
410
+ if (result instanceof Promise) {
411
+ promises.push(result);
412
+ }
413
+ }
414
+ }
415
+ await Promise.all(promises);
416
+ }
417
+ /**
418
+ * Get all registered actor IDs
419
+ */
420
+ getActorIds() {
421
+ return Array.from(this.actors.keys());
422
+ }
423
+ /**
424
+ * Get all active actor IDs
425
+ */
426
+ getActiveActorIds() {
427
+ return Array.from(this.activeActors);
428
+ }
429
+ /**
430
+ * Check if an actor is active
431
+ */
432
+ isActive(actorId) {
433
+ return this.activeActors.has(actorId);
434
+ }
435
+ };
436
+ function createTimerActor(id, intervalMs, createEvent) {
437
+ let timerId = null;
438
+ return {
439
+ id,
440
+ description: `Timer actor (${intervalMs}ms) - ${id}`,
441
+ onStart: (engine) => {
442
+ timerId = setInterval(() => {
443
+ engine.step([createEvent()]);
444
+ }, intervalMs);
445
+ },
446
+ onStop: () => {
447
+ if (timerId) {
448
+ clearInterval(timerId);
449
+ timerId = null;
450
+ }
451
+ }
452
+ };
453
+ }
454
+
455
+ // src/core/introspection.ts
456
+ var RegistryIntrospector = class {
457
+ constructor(registry) {
458
+ this.registry = registry;
459
+ }
460
+ /**
461
+ * Get basic statistics about the registry
462
+ */
463
+ getStats() {
464
+ return {
465
+ ruleCount: this.registry.getRuleIds().length,
466
+ constraintCount: this.registry.getConstraintIds().length,
467
+ moduleCount: 0,
468
+ // Modules are flattened in registry
469
+ rulesById: this.registry.getRuleIds(),
470
+ constraintsById: this.registry.getConstraintIds()
471
+ };
472
+ }
473
+ /**
474
+ * Generate a JSON schema representation of the registry
475
+ */
476
+ generateSchema(protocolVersion) {
477
+ const rules = this.registry.getAllRules().map((rule) => ({
478
+ id: rule.id,
479
+ description: rule.description,
480
+ type: "rule",
481
+ meta: rule.meta
482
+ }));
483
+ const constraints = this.registry.getAllConstraints().map((constraint) => ({
484
+ id: constraint.id,
485
+ description: constraint.description,
486
+ type: "constraint",
487
+ meta: constraint.meta
488
+ }));
489
+ return {
490
+ protocolVersion,
491
+ rules,
492
+ constraints,
493
+ meta: {
494
+ ruleCount: rules.length,
495
+ constraintCount: constraints.length
496
+ }
497
+ };
498
+ }
499
+ /**
500
+ * Generate a graph representation of the registry
501
+ *
502
+ * This creates nodes for rules and constraints.
503
+ * Edges can be inferred from metadata if rules/constraints
504
+ * document their dependencies.
505
+ */
506
+ generateGraph() {
507
+ const nodes = [];
508
+ const edges = [];
509
+ for (const rule of this.registry.getAllRules()) {
510
+ nodes.push({
511
+ id: rule.id,
512
+ type: "rule",
513
+ description: rule.description,
514
+ meta: rule.meta
515
+ });
516
+ if (rule.meta?.dependsOn) {
517
+ const deps = Array.isArray(rule.meta.dependsOn) ? rule.meta.dependsOn : [rule.meta.dependsOn];
518
+ for (const dep of deps) {
519
+ edges.push({
520
+ from: String(dep),
521
+ to: rule.id,
522
+ type: "depends-on"
523
+ });
524
+ }
525
+ }
526
+ }
527
+ for (const constraint of this.registry.getAllConstraints()) {
528
+ nodes.push({
529
+ id: constraint.id,
530
+ type: "constraint",
531
+ description: constraint.description,
532
+ meta: constraint.meta
533
+ });
534
+ if (constraint.meta?.constrains) {
535
+ const targets = Array.isArray(constraint.meta.constrains) ? constraint.meta.constrains : [constraint.meta.constrains];
536
+ for (const target of targets) {
537
+ edges.push({
538
+ from: constraint.id,
539
+ to: String(target),
540
+ type: "constrains"
541
+ });
542
+ }
543
+ }
544
+ }
545
+ return {
546
+ nodes,
547
+ edges,
548
+ meta: {
549
+ nodeCount: nodes.length,
550
+ ruleCount: nodes.filter((n) => n.type === "rule").length,
551
+ constraintCount: nodes.filter((n) => n.type === "constraint").length
552
+ }
553
+ };
554
+ }
555
+ /**
556
+ * Export graph in DOT format (Graphviz)
557
+ *
558
+ * This can be rendered with Graphviz tools or online services.
559
+ */
560
+ exportDOT() {
561
+ const graph = this.generateGraph();
562
+ const lines = [];
563
+ lines.push("digraph PraxisRegistry {");
564
+ lines.push(" rankdir=TB;");
565
+ lines.push(" node [shape=box, style=rounded];");
566
+ lines.push("");
567
+ for (const node of graph.nodes) {
568
+ const shape = node.type === "rule" ? "box" : "diamond";
569
+ const color = node.type === "rule" ? "lightblue" : "lightcoral";
570
+ const label = `${node.id}\\n${node.description}`;
571
+ lines.push(
572
+ ` "${node.id}" [label="${label}", shape=${shape}, style=filled, fillcolor=${color}];`
573
+ );
574
+ }
575
+ lines.push("");
576
+ for (const edge of graph.edges) {
577
+ const style = edge.type === "constrains" ? "dashed" : "solid";
578
+ lines.push(` "${edge.from}" -> "${edge.to}" [label="${edge.type}", style=${style}];`);
579
+ }
580
+ lines.push("}");
581
+ return lines.join("\n");
582
+ }
583
+ /**
584
+ * Export graph in Mermaid format
585
+ *
586
+ * Mermaid is a markdown-friendly diagramming language.
587
+ */
588
+ exportMermaid() {
589
+ const graph = this.generateGraph();
590
+ const lines = [];
591
+ lines.push("graph TB");
592
+ for (const node of graph.nodes) {
593
+ const shape = node.type === "rule" ? "[" : "{";
594
+ const endShape = node.type === "rule" ? "]" : "}";
595
+ const label = `${node.id}<br/>${node.description}`;
596
+ lines.push(` ${node.id}${shape}"${label}"${endShape}`);
597
+ }
598
+ lines.push("");
599
+ for (const edge of graph.edges) {
600
+ const arrow = edge.type === "constrains" ? "-.->|constrains|" : "-->|" + edge.type + "|";
601
+ lines.push(` ${edge.from} ${arrow} ${edge.to}`);
602
+ }
603
+ return lines.join("\n");
604
+ }
605
+ /**
606
+ * Get detailed information about a specific rule
607
+ */
608
+ getRuleInfo(ruleId) {
609
+ return this.registry.getRule(ruleId);
610
+ }
611
+ /**
612
+ * Get detailed information about a specific constraint
613
+ */
614
+ getConstraintInfo(constraintId) {
615
+ return this.registry.getConstraint(constraintId);
616
+ }
617
+ /**
618
+ * Search for rules by description text
619
+ */
620
+ searchRules(query) {
621
+ const lowerQuery = query.toLowerCase();
622
+ return this.registry.getAllRules().filter(
623
+ (rule) => rule.id.toLowerCase().includes(lowerQuery) || rule.description.toLowerCase().includes(lowerQuery)
624
+ );
625
+ }
626
+ /**
627
+ * Search for constraints by description text
628
+ */
629
+ searchConstraints(query) {
630
+ const lowerQuery = query.toLowerCase();
631
+ return this.registry.getAllConstraints().filter(
632
+ (constraint) => constraint.id.toLowerCase().includes(lowerQuery) || constraint.description.toLowerCase().includes(lowerQuery)
633
+ );
634
+ }
635
+ };
636
+ function createIntrospector(registry) {
637
+ return new RegistryIntrospector(registry);
638
+ }
639
+
640
+ // src/dsl/index.ts
641
+ function defineFact(tag) {
642
+ return {
643
+ tag,
644
+ create(payload) {
645
+ return { tag, payload };
646
+ },
647
+ is(fact) {
648
+ return fact.tag === tag;
649
+ }
650
+ };
651
+ }
652
+ function defineEvent(tag) {
653
+ return {
654
+ tag,
655
+ create(payload) {
656
+ return { tag, payload };
657
+ },
658
+ is(event) {
659
+ return event.tag === tag;
660
+ }
661
+ };
662
+ }
663
+ function defineRule(options) {
664
+ return {
665
+ id: options.id,
666
+ description: options.description,
667
+ impl: options.impl,
668
+ meta: options.meta
669
+ };
670
+ }
671
+ function defineConstraint(options) {
672
+ return {
673
+ id: options.id,
674
+ description: options.description,
675
+ impl: options.impl,
676
+ meta: options.meta
677
+ };
678
+ }
679
+ function defineModule(options) {
680
+ return {
681
+ rules: options.rules ?? [],
682
+ constraints: options.constraints ?? [],
683
+ meta: options.meta
684
+ };
685
+ }
686
+ function filterEvents(events, definition) {
687
+ return events.filter(definition.is);
688
+ }
689
+ function filterFacts(facts, definition) {
690
+ return facts.filter(definition.is);
691
+ }
692
+ function findEvent(events, definition) {
693
+ return events.find(definition.is);
694
+ }
695
+ function findFact(facts, definition) {
696
+ return facts.find(definition.is);
697
+ }
698
+
699
+ // src/core/schema/types.ts
700
+ function validateSchema(schema) {
701
+ const errors = [];
702
+ if (!schema.version) {
703
+ errors.push({ path: "version", message: "Schema version is required" });
704
+ }
705
+ if (!schema.name) {
706
+ errors.push({ path: "name", message: "Schema name is required" });
707
+ }
708
+ if (schema.models) {
709
+ schema.models.forEach((model, index) => {
710
+ if (!model.name) {
711
+ errors.push({
712
+ path: `models[${index}].name`,
713
+ message: "Model name is required"
714
+ });
715
+ }
716
+ if (!model.fields || model.fields.length === 0) {
717
+ errors.push({
718
+ path: `models[${index}].fields`,
719
+ message: "Model must have at least one field"
720
+ });
721
+ }
722
+ });
723
+ }
724
+ if (schema.components) {
725
+ schema.components.forEach((component, index) => {
726
+ if (!component.name) {
727
+ errors.push({
728
+ path: `components[${index}].name`,
729
+ message: "Component name is required"
730
+ });
731
+ }
732
+ if (!component.type) {
733
+ errors.push({
734
+ path: `components[${index}].type`,
735
+ message: "Component type is required"
736
+ });
737
+ }
738
+ });
739
+ }
740
+ if (schema.logic) {
741
+ schema.logic.forEach((logic, logicIndex) => {
742
+ if (logic.facts) {
743
+ logic.facts.forEach((fact, factIndex) => {
744
+ if (!fact.tag) {
745
+ errors.push({
746
+ path: `logic[${logicIndex}].facts[${factIndex}].tag`,
747
+ message: "Fact tag is required"
748
+ });
749
+ } else if (!isValidIdentifier(fact.tag)) {
750
+ errors.push({
751
+ path: `logic[${logicIndex}].facts[${factIndex}].tag`,
752
+ message: `Fact tag "${fact.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`
753
+ });
754
+ }
755
+ });
756
+ }
757
+ if (logic.events) {
758
+ logic.events.forEach((event, eventIndex) => {
759
+ if (!event.tag) {
760
+ errors.push({
761
+ path: `logic[${logicIndex}].events[${eventIndex}].tag`,
762
+ message: "Event tag is required"
763
+ });
764
+ } else if (!isValidIdentifier(event.tag)) {
765
+ errors.push({
766
+ path: `logic[${logicIndex}].events[${eventIndex}].tag`,
767
+ message: `Event tag "${event.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`
768
+ });
769
+ }
770
+ });
771
+ }
772
+ });
773
+ }
774
+ if (schema.orchestration?.nodes) {
775
+ schema.orchestration.nodes.forEach((node, index) => {
776
+ if (!node.id) {
777
+ errors.push({
778
+ path: `orchestration.nodes[${index}].id`,
779
+ message: "Node id is required"
780
+ });
781
+ }
782
+ if (!node.type) {
783
+ errors.push({
784
+ path: `orchestration.nodes[${index}].type`,
785
+ message: "Node type is required"
786
+ });
787
+ }
788
+ if (node.type === "terminal" && node.props) {
789
+ const props = node.props;
790
+ if (props.inputMode && !["text", "widget"].includes(props.inputMode)) {
791
+ errors.push({
792
+ path: `orchestration.nodes[${index}].props.inputMode`,
793
+ message: 'Terminal node inputMode must be "text" or "widget"'
794
+ });
795
+ }
796
+ if (props.history && !Array.isArray(props.history)) {
797
+ errors.push({
798
+ path: `orchestration.nodes[${index}].props.history`,
799
+ message: "Terminal node history must be an array"
800
+ });
801
+ }
802
+ }
803
+ });
804
+ }
805
+ return {
806
+ valid: errors.length === 0,
807
+ errors
808
+ };
809
+ }
810
+ function isValidIdentifier(str) {
811
+ const identifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
812
+ const reservedKeywords = [
813
+ "break",
814
+ "case",
815
+ "catch",
816
+ "class",
817
+ "const",
818
+ "continue",
819
+ "debugger",
820
+ "default",
821
+ "delete",
822
+ "do",
823
+ "else",
824
+ "export",
825
+ "extends",
826
+ "finally",
827
+ "for",
828
+ "function",
829
+ "if",
830
+ "import",
831
+ "in",
832
+ "instanceof",
833
+ "new",
834
+ "return",
835
+ "super",
836
+ "switch",
837
+ "this",
838
+ "throw",
839
+ "try",
840
+ "typeof",
841
+ "var",
842
+ "void",
843
+ "while",
844
+ "with",
845
+ "yield",
846
+ "let",
847
+ "static",
848
+ "enum",
849
+ "await",
850
+ "implements",
851
+ "interface",
852
+ "package",
853
+ "private",
854
+ "protected",
855
+ "public"
856
+ ];
857
+ return identifierRegex.test(str) && !reservedKeywords.includes(str);
858
+ }
859
+ function createSchemaTemplate(name) {
860
+ return {
861
+ version: "1.0.0",
862
+ name,
863
+ description: `Schema for ${name}`,
864
+ models: [],
865
+ components: [],
866
+ logic: []
867
+ };
868
+ }
869
+
870
+ // src/core/schema/loader.common.ts
871
+ import { load as yamlLoad } from "js-yaml";
872
+ function createSchema(name) {
873
+ return {
874
+ version: "1.0.0",
875
+ name,
876
+ description: `Schema for ${name}`,
877
+ models: [],
878
+ components: [],
879
+ logic: []
880
+ };
881
+ }
882
+ function loadSchemaFromJson(json, options = {}) {
883
+ const errors = [];
884
+ try {
885
+ const schema = JSON.parse(json);
886
+ let validation;
887
+ if (options.validate !== false) {
888
+ validation = validateSchema(schema);
889
+ if (!validation.valid) {
890
+ errors.push("Schema validation failed:");
891
+ validation.errors.forEach((error) => {
892
+ errors.push(` ${error.path}: ${error.message}`);
893
+ });
894
+ }
895
+ }
896
+ return {
897
+ schema,
898
+ validation,
899
+ errors
900
+ };
901
+ } catch (error) {
902
+ if (error instanceof Error) {
903
+ errors.push(`Failed to parse JSON: ${error.message}`);
904
+ } else {
905
+ errors.push("Failed to parse JSON: Unknown error");
906
+ }
907
+ return { errors };
908
+ }
909
+ }
910
+ function loadSchemaFromYaml(yaml, options = {}) {
911
+ const errors = [];
912
+ try {
913
+ const schema = yamlLoad(yaml);
914
+ let validation;
915
+ if (options.validate !== false) {
916
+ validation = validateSchema(schema);
917
+ if (!validation.valid) {
918
+ errors.push("Schema validation failed:");
919
+ validation.errors.forEach((error) => {
920
+ errors.push(` ${error.path}: ${error.message}`);
921
+ });
922
+ }
923
+ }
924
+ return {
925
+ schema,
926
+ validation,
927
+ errors
928
+ };
929
+ } catch (error) {
930
+ if (error instanceof Error) {
931
+ errors.push(`Failed to parse YAML: ${error.message}`);
932
+ } else {
933
+ errors.push("Failed to parse YAML: Unknown error");
934
+ }
935
+ return { errors };
936
+ }
937
+ }
938
+ function validateForGeneration(schema) {
939
+ const errors = [];
940
+ if (!schema.models || schema.models.length === 0) {
941
+ errors.push("Schema must define at least one model for generation");
942
+ }
943
+ schema.models?.forEach((model, index) => {
944
+ if (!model.fields || model.fields.length === 0) {
945
+ errors.push(`Model "${model.name}" at index ${index} must have at least one field`);
946
+ }
947
+ model.fields?.forEach((field, fieldIndex) => {
948
+ if (!field.name) {
949
+ errors.push(`Field at index ${fieldIndex} in model "${model.name}" must have a name`);
950
+ }
951
+ if (!field.type) {
952
+ errors.push(`Field "${field.name}" in model "${model.name}" must have a type`);
953
+ }
954
+ });
955
+ });
956
+ return {
957
+ valid: errors.length === 0,
958
+ errors: errors.map((message) => ({ path: "schema", message }))
959
+ };
960
+ }
961
+
962
+ // src/core/pluresdb/store.ts
963
+ var PRAXIS_PATHS = {
964
+ /** Base path for all Praxis data */
965
+ BASE: "/_praxis",
966
+ /** Path for facts storage */
967
+ FACTS: "/_praxis/facts",
968
+ /** Path for events storage */
969
+ EVENTS: "/_praxis/events",
970
+ /** Path for schema registry */
971
+ SCHEMAS: "/_praxis/schemas"
972
+ };
973
+ function getFactPath(factTag, id) {
974
+ if (id) {
975
+ return `${PRAXIS_PATHS.FACTS}/${factTag}/${id}`;
976
+ }
977
+ return `${PRAXIS_PATHS.FACTS}/${factTag}`;
978
+ }
979
+ function getEventPath(eventTag) {
980
+ return `${PRAXIS_PATHS.EVENTS}/${eventTag}`;
981
+ }
982
+ function generateId() {
983
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
984
+ }
985
+ var defaultErrorHandler = (ruleId, error) => {
986
+ if (typeof process !== "undefined" && true) {
987
+ console.error(`Error executing rule "${ruleId}":`, error);
988
+ }
989
+ };
990
+ var PraxisDBStore = class {
991
+ db;
992
+ registry;
993
+ context;
994
+ subscriptions = [];
995
+ factWatchers = /* @__PURE__ */ new Map();
996
+ onRuleError;
997
+ constructor(options) {
998
+ this.db = options.db;
999
+ this.registry = options.registry;
1000
+ this.context = options.initialContext ?? {};
1001
+ this.onRuleError = options.onRuleError ?? defaultErrorHandler;
1002
+ }
1003
+ /**
1004
+ * Store a fact in PluresDB
1005
+ *
1006
+ * Facts are stored under `/_praxis/facts/<factTag>/<id>`
1007
+ * If no id is provided in the payload, a timestamp-based id is used.
1008
+ *
1009
+ * @param fact The fact to store
1010
+ * @returns Promise that resolves when the fact is stored
1011
+ */
1012
+ async storeFact(fact) {
1013
+ const constraintResult = await this.checkConstraints([fact]);
1014
+ if (!constraintResult.valid) {
1015
+ throw new Error(`Constraint violation: ${constraintResult.errors.join(", ")}`);
1016
+ }
1017
+ await this.persistFact(fact);
1018
+ await this.triggerRules([fact]);
1019
+ }
1020
+ /**
1021
+ * Store multiple facts in PluresDB
1022
+ *
1023
+ * @param facts The facts to store
1024
+ */
1025
+ async storeFacts(facts) {
1026
+ const constraintResult = await this.checkConstraints(facts);
1027
+ if (!constraintResult.valid) {
1028
+ throw new Error(`Constraint violation: ${constraintResult.errors.join(", ")}`);
1029
+ }
1030
+ for (const fact of facts) {
1031
+ await this.persistFact(fact);
1032
+ }
1033
+ await this.triggerRules(facts);
1034
+ }
1035
+ /**
1036
+ * Internal method to persist a fact without constraint checking
1037
+ * Used by both storeFact and derived fact storage
1038
+ */
1039
+ async persistFact(fact) {
1040
+ const payload = fact.payload;
1041
+ const id = payload?.id ?? generateId();
1042
+ const path = getFactPath(fact.tag, id);
1043
+ await this.db.set(path, fact);
1044
+ }
1045
+ /**
1046
+ * Get a fact by tag and id
1047
+ *
1048
+ * @param factTag The fact type tag
1049
+ * @param id The fact id
1050
+ * @returns The fact or undefined if not found
1051
+ */
1052
+ async getFact(factTag, id) {
1053
+ const path = getFactPath(factTag, id);
1054
+ return this.db.get(path);
1055
+ }
1056
+ /**
1057
+ * Append an event to the event stream
1058
+ *
1059
+ * Events are stored as append-only streams under `/_praxis/events/<eventTag>`
1060
+ *
1061
+ * @param event The event to append
1062
+ */
1063
+ async appendEvent(event) {
1064
+ const path = getEventPath(event.tag);
1065
+ const existingEvents = await this.db.get(path) ?? [];
1066
+ const entry = {
1067
+ event,
1068
+ timestamp: Date.now(),
1069
+ sequence: existingEvents.length
1070
+ };
1071
+ const newEvents = [...existingEvents, entry];
1072
+ await this.db.set(path, newEvents);
1073
+ await this.triggerRulesForEvents([event]);
1074
+ }
1075
+ /**
1076
+ * Append multiple events to their respective streams
1077
+ *
1078
+ * @param events The events to append
1079
+ */
1080
+ async appendEvents(events) {
1081
+ const eventsByTag = /* @__PURE__ */ new Map();
1082
+ for (const event of events) {
1083
+ const existing = eventsByTag.get(event.tag) ?? [];
1084
+ eventsByTag.set(event.tag, [...existing, event]);
1085
+ }
1086
+ for (const [tag, tagEvents] of eventsByTag) {
1087
+ const path = getEventPath(tag);
1088
+ const existingEvents = await this.db.get(path) ?? [];
1089
+ let sequence = existingEvents.length;
1090
+ const newEntries = tagEvents.map((event) => ({
1091
+ event,
1092
+ timestamp: Date.now(),
1093
+ sequence: sequence++
1094
+ }));
1095
+ await this.db.set(path, [...existingEvents, ...newEntries]);
1096
+ }
1097
+ await this.triggerRulesForEvents(events);
1098
+ }
1099
+ /**
1100
+ * Get events from a stream
1101
+ *
1102
+ * @param eventTag The event type tag
1103
+ * @param options Query options
1104
+ * @returns Array of event stream entries
1105
+ */
1106
+ async getEvents(eventTag, options) {
1107
+ const path = getEventPath(eventTag);
1108
+ const events = await this.db.get(path) ?? [];
1109
+ let result = events;
1110
+ if (options?.since !== void 0) {
1111
+ const sinceTimestamp = options.since;
1112
+ result = result.filter((e) => e.timestamp > sinceTimestamp);
1113
+ }
1114
+ if (options?.limit !== void 0) {
1115
+ result = result.slice(-options.limit);
1116
+ }
1117
+ return result;
1118
+ }
1119
+ /**
1120
+ * Watch a fact path for changes
1121
+ *
1122
+ * @param factTag The fact type tag to watch
1123
+ * @param callback Called when facts of this type change
1124
+ * @returns Unsubscribe function
1125
+ */
1126
+ watchFacts(factTag, callback) {
1127
+ const path = getFactPath(factTag);
1128
+ if (!this.factWatchers.has(factTag)) {
1129
+ this.factWatchers.set(factTag, /* @__PURE__ */ new Set());
1130
+ }
1131
+ const watchers = this.factWatchers.get(factTag);
1132
+ if (watchers) {
1133
+ watchers.add(callback);
1134
+ }
1135
+ const unsubscribe = this.db.watch(path, (fact) => {
1136
+ callback([fact]);
1137
+ });
1138
+ this.subscriptions.push(unsubscribe);
1139
+ return () => {
1140
+ unsubscribe();
1141
+ this.factWatchers.get(factTag)?.delete(callback);
1142
+ };
1143
+ }
1144
+ /**
1145
+ * Check constraints against the current state with new facts
1146
+ */
1147
+ async checkConstraints(newFacts) {
1148
+ const constraints = this.registry.getAllConstraints();
1149
+ const errors = [];
1150
+ const state2 = {
1151
+ context: this.context,
1152
+ facts: newFacts,
1153
+ meta: {}
1154
+ };
1155
+ for (const constraint of constraints) {
1156
+ try {
1157
+ const result = constraint.impl(state2);
1158
+ if (result === false) {
1159
+ errors.push(`Constraint "${constraint.id}" violated`);
1160
+ } else if (typeof result === "string") {
1161
+ errors.push(result);
1162
+ }
1163
+ } catch (error) {
1164
+ errors.push(
1165
+ `Error checking constraint "${constraint.id}": ${error instanceof Error ? error.message : String(error)}`
1166
+ );
1167
+ }
1168
+ }
1169
+ return {
1170
+ valid: errors.length === 0,
1171
+ errors
1172
+ };
1173
+ }
1174
+ /**
1175
+ * Trigger rules when new facts are added
1176
+ *
1177
+ * This method is called after facts are stored. It can be extended
1178
+ * for derived fact computation where rules generate new facts based
1179
+ * on existing facts. Currently implemented as a hook point for future
1180
+ * enhancements.
1181
+ *
1182
+ * @param _newFacts The newly stored facts (unused in current implementation)
1183
+ */
1184
+ async triggerRules(_newFacts) {
1185
+ }
1186
+ /**
1187
+ * Trigger rules when events are appended
1188
+ */
1189
+ async triggerRulesForEvents(events) {
1190
+ const rules = this.registry.getAllRules();
1191
+ const state2 = {
1192
+ context: this.context,
1193
+ facts: [],
1194
+ meta: {}
1195
+ };
1196
+ const derivedFacts = [];
1197
+ for (const rule of rules) {
1198
+ try {
1199
+ const facts = rule.impl(state2, events);
1200
+ derivedFacts.push(...facts);
1201
+ } catch (error) {
1202
+ this.onRuleError(rule.id, error);
1203
+ }
1204
+ }
1205
+ if (derivedFacts.length > 0) {
1206
+ const constraintResult = await this.checkConstraints(derivedFacts);
1207
+ if (constraintResult.valid) {
1208
+ for (const fact of derivedFacts) {
1209
+ await this.persistFact(fact);
1210
+ }
1211
+ }
1212
+ }
1213
+ }
1214
+ /**
1215
+ * Update the context
1216
+ */
1217
+ updateContext(context) {
1218
+ this.context = context;
1219
+ }
1220
+ /**
1221
+ * Get the current context
1222
+ */
1223
+ getContext() {
1224
+ return this.context;
1225
+ }
1226
+ /**
1227
+ * Dispose of all subscriptions
1228
+ */
1229
+ dispose() {
1230
+ for (const unsubscribe of this.subscriptions) {
1231
+ unsubscribe();
1232
+ }
1233
+ this.subscriptions = [];
1234
+ this.factWatchers.clear();
1235
+ }
1236
+ };
1237
+ function createPraxisDBStore(db, registry, initialContext, onRuleError) {
1238
+ return new PraxisDBStore({ db, registry, initialContext, onRuleError });
1239
+ }
1240
+
1241
+ // src/core/pluresdb/adapter.ts
1242
+ var InMemoryPraxisDB = class {
1243
+ store = /* @__PURE__ */ new Map();
1244
+ watchers = /* @__PURE__ */ new Map();
1245
+ async get(key) {
1246
+ return this.store.get(key);
1247
+ }
1248
+ async set(key, value) {
1249
+ this.store.set(key, value);
1250
+ const keyWatchers = this.watchers.get(key);
1251
+ if (keyWatchers) {
1252
+ for (const callback of keyWatchers) {
1253
+ callback(value);
1254
+ }
1255
+ }
1256
+ }
1257
+ watch(key, callback) {
1258
+ if (!this.watchers.has(key)) {
1259
+ this.watchers.set(key, /* @__PURE__ */ new Set());
1260
+ }
1261
+ const watchers = this.watchers.get(key);
1262
+ const wrappedCallback = (val) => callback(val);
1263
+ watchers.add(wrappedCallback);
1264
+ return () => {
1265
+ watchers.delete(wrappedCallback);
1266
+ if (watchers.size === 0) {
1267
+ this.watchers.delete(key);
1268
+ }
1269
+ };
1270
+ }
1271
+ /**
1272
+ * Get all keys (for testing/debugging)
1273
+ */
1274
+ keys() {
1275
+ return Array.from(this.store.keys());
1276
+ }
1277
+ /**
1278
+ * Clear all data (for testing)
1279
+ */
1280
+ clear() {
1281
+ this.store.clear();
1282
+ this.watchers.clear();
1283
+ }
1284
+ };
1285
+ function createInMemoryDB() {
1286
+ return new InMemoryPraxisDB();
1287
+ }
1288
+
1289
+ // src/core/pluresdb/schema-registry.ts
1290
+ function getSchemaPath(schemaName) {
1291
+ return `${PRAXIS_PATHS.SCHEMAS}/${schemaName}`;
1292
+ }
1293
+ var PraxisSchemaRegistry = class {
1294
+ db;
1295
+ constructor(db) {
1296
+ this.db = db;
1297
+ }
1298
+ /**
1299
+ * Register a schema in PluresDB
1300
+ *
1301
+ * @param schema The schema to register
1302
+ */
1303
+ async register(schema) {
1304
+ const path = getSchemaPath(schema.name);
1305
+ const storedSchema = {
1306
+ schema,
1307
+ registeredAt: Date.now(),
1308
+ version: schema.version
1309
+ };
1310
+ await this.db.set(path, storedSchema);
1311
+ }
1312
+ /**
1313
+ * Get a schema by name
1314
+ *
1315
+ * @param schemaName The schema name
1316
+ * @returns The stored schema or undefined if not found
1317
+ */
1318
+ async get(schemaName) {
1319
+ const path = getSchemaPath(schemaName);
1320
+ return this.db.get(path);
1321
+ }
1322
+ /**
1323
+ * Check if a schema is registered
1324
+ *
1325
+ * @param schemaName The schema name
1326
+ * @returns True if the schema exists
1327
+ */
1328
+ async exists(schemaName) {
1329
+ const stored = await this.get(schemaName);
1330
+ return stored !== void 0;
1331
+ }
1332
+ /**
1333
+ * Update a schema (replaces existing)
1334
+ *
1335
+ * @param schema The updated schema
1336
+ */
1337
+ async update(schema) {
1338
+ await this.register(schema);
1339
+ }
1340
+ /**
1341
+ * List all registered schema names
1342
+ *
1343
+ * Implementation note: This method uses an index stored at `/_praxis/schemas/_index`.
1344
+ * When using InMemoryPraxisDB, schemas must be registered using `registerWithIndex()`
1345
+ * for them to appear in this listing. When using a full PluresDB implementation,
1346
+ * native listing capabilities should be used instead.
1347
+ *
1348
+ * @returns Array of registered schema names
1349
+ */
1350
+ async list() {
1351
+ const indexPath = `${PRAXIS_PATHS.SCHEMAS}/_index`;
1352
+ const index = await this.db.get(indexPath);
1353
+ return index ?? [];
1354
+ }
1355
+ /**
1356
+ * Register a schema and update the index
1357
+ *
1358
+ * @param schema The schema to register
1359
+ */
1360
+ async registerWithIndex(schema) {
1361
+ await this.register(schema);
1362
+ const indexPath = `${PRAXIS_PATHS.SCHEMAS}/_index`;
1363
+ const existingIndex = await this.db.get(indexPath) ?? [];
1364
+ if (!existingIndex.includes(schema.name)) {
1365
+ await this.db.set(indexPath, [...existingIndex, schema.name]);
1366
+ }
1367
+ }
1368
+ };
1369
+ async function registerSchema(db, schema) {
1370
+ const registry = new PraxisSchemaRegistry(db);
1371
+ await registry.registerWithIndex(schema);
1372
+ }
1373
+ function createSchemaRegistry(db) {
1374
+ return new PraxisSchemaRegistry(db);
1375
+ }
1376
+
1377
+ // src/core/pluresdb/generator.ts
1378
+ var PluresDBGenerator = class {
1379
+ options;
1380
+ constructor(options) {
1381
+ this.options = {
1382
+ dbVersion: 1,
1383
+ enableSync: false,
1384
+ autoIndex: "all",
1385
+ // Default to indexing all fields for backward compatibility
1386
+ ...options
1387
+ };
1388
+ }
1389
+ /**
1390
+ * Generate PluresDB configuration from schema
1391
+ */
1392
+ generateConfig(schema) {
1393
+ const files = [];
1394
+ files.push(this.generateConfigFile(schema));
1395
+ return files;
1396
+ }
1397
+ /**
1398
+ * Generate pluresdb-config.ts file
1399
+ */
1400
+ generateConfigFile(schema) {
1401
+ const lines = [];
1402
+ const dbName = this.options.dbName || schema.name.toLowerCase();
1403
+ lines.push("/**");
1404
+ lines.push(` * PluresDB Configuration for ${schema.name}`);
1405
+ lines.push(" * Generated from Praxis schema");
1406
+ lines.push(" */");
1407
+ lines.push("");
1408
+ lines.push("// import { createPluresDB } from '@plures/pluresdb';");
1409
+ lines.push("");
1410
+ lines.push("/**");
1411
+ lines.push(" * Database store configuration");
1412
+ lines.push(" * ");
1413
+ const autoIndexStrategy = this.options.autoIndex || "all";
1414
+ if (autoIndexStrategy === "all") {
1415
+ lines.push(" * Indexing: All string, number, and date fields are auto-indexed by default.");
1416
+ lines.push(' * For large datasets, consider using autoIndex: "explicit" to only index');
1417
+ lines.push(" * fields explicitly defined in the schema.");
1418
+ } else if (autoIndexStrategy === "explicit") {
1419
+ lines.push(" * Indexing: Only fields explicitly defined in schema indexes are indexed.");
1420
+ } else if (autoIndexStrategy === "none") {
1421
+ lines.push(" * Indexing: Auto-indexing disabled. Only explicit schema indexes are used.");
1422
+ }
1423
+ lines.push(" */");
1424
+ lines.push("export const stores = {");
1425
+ if (schema.models && schema.models.length > 0) {
1426
+ for (const model of schema.models) {
1427
+ const storeName = model.name.toLowerCase() + "s";
1428
+ const storeConfig = this.generateStoreConfig(model);
1429
+ lines.push(` ${storeName}: {`);
1430
+ lines.push(` keyPath: '${storeConfig.keyPath}',`);
1431
+ if (storeConfig.indexes.length > 0) {
1432
+ lines.push(` indexes: [${storeConfig.indexes.map((idx) => `'${idx}'`).join(", ")}],`);
1433
+ }
1434
+ lines.push(" },");
1435
+ }
1436
+ } else {
1437
+ lines.push(" // No models defined in schema");
1438
+ }
1439
+ lines.push("};");
1440
+ lines.push("");
1441
+ lines.push("/**");
1442
+ lines.push(" * Database configuration");
1443
+ lines.push(" */");
1444
+ lines.push("export const dbConfig = {");
1445
+ lines.push(` name: '${dbName}',`);
1446
+ lines.push(` version: ${this.options.dbVersion},`);
1447
+ lines.push(" stores,");
1448
+ if (this.options.enableSync) {
1449
+ lines.push(" sync: {");
1450
+ lines.push(" enabled: true,");
1451
+ if (this.options.syncEndpoint) {
1452
+ lines.push(` endpoint: '${this.options.syncEndpoint}',`);
1453
+ } else {
1454
+ lines.push(" endpoint: 'ws://localhost:8080/sync',");
1455
+ }
1456
+ lines.push(" conflictResolution: 'last-write-wins',");
1457
+ lines.push(" },");
1458
+ }
1459
+ lines.push("};");
1460
+ lines.push("");
1461
+ lines.push("/**");
1462
+ lines.push(" * Initialize PluresDB");
1463
+ lines.push(" * @returns Configured PluresDB instance");
1464
+ lines.push(" */");
1465
+ lines.push("export function initDB() {");
1466
+ lines.push(" // Create and configure PluresDB instance");
1467
+ lines.push(" const db = createInMemoryDB();");
1468
+ lines.push(" ");
1469
+ lines.push(" // Initialize stores based on configuration");
1470
+ lines.push(" for (const storeDef of dbConfig.stores) {");
1471
+ lines.push(" // Pre-create store paths");
1472
+ lines.push(" db.set(`stores/${storeDef.name}/_meta`, {");
1473
+ lines.push(" keyPath: storeDef.keyPath,");
1474
+ lines.push(" indexes: storeDef.indexes,");
1475
+ lines.push(" createdAt: Date.now(),");
1476
+ lines.push(" });");
1477
+ lines.push(" }");
1478
+ lines.push(" ");
1479
+ lines.push(" console.log(`PluresDB initialized: ${dbConfig.name}`);");
1480
+ lines.push(" return db;");
1481
+ lines.push("}");
1482
+ lines.push("");
1483
+ lines.push("/**");
1484
+ lines.push(" * Get store by name");
1485
+ lines.push(" */");
1486
+ lines.push(
1487
+ "export function getStore(db: ReturnType<typeof createInMemoryDB>, storeName: string) {"
1488
+ );
1489
+ lines.push(" const storeDef = dbConfig.stores.find(s => s.name === storeName);");
1490
+ lines.push(" if (!storeDef) {");
1491
+ lines.push(' throw new Error(`Store "${storeName}" not found in configuration`);');
1492
+ lines.push(" }");
1493
+ lines.push(" return {");
1494
+ lines.push(" get: (key: string) => db.get(`stores/${storeName}/${key}`),");
1495
+ lines.push(
1496
+ " set: (key: string, value: unknown) => db.set(`stores/${storeName}/${key}`, value),"
1497
+ );
1498
+ lines.push(" delete: (key: string) => db.delete(`stores/${storeName}/${key}`),");
1499
+ lines.push(" watch: (key: string, callback: (data: unknown) => void) => ");
1500
+ lines.push(" db.watch(`stores/${storeName}/${key}`, callback),");
1501
+ lines.push(" };");
1502
+ lines.push("}");
1503
+ return {
1504
+ path: `${this.options.outputDir}/pluresdb-config.ts`,
1505
+ content: lines.join("\n"),
1506
+ type: "config"
1507
+ };
1508
+ }
1509
+ /**
1510
+ * Generate store configuration for a model
1511
+ */
1512
+ generateStoreConfig(model) {
1513
+ const idField = model.fields.find((f) => f.name === "id" || f.name === "_id");
1514
+ const keyPath = idField ? idField.name : "id";
1515
+ const indexes = [];
1516
+ const autoIndexStrategy = this.options.autoIndex || "all";
1517
+ if (autoIndexStrategy === "all") {
1518
+ for (const field of model.fields) {
1519
+ if (field.name !== keyPath) {
1520
+ if (field.type === "string" || field.type === "number" || field.type === "date") {
1521
+ indexes.push(field.name);
1522
+ }
1523
+ }
1524
+ }
1525
+ }
1526
+ if (model.indexes) {
1527
+ for (const indexDef of model.indexes) {
1528
+ for (const fieldName of indexDef.fields) {
1529
+ if (!indexes.includes(fieldName) && fieldName !== keyPath) {
1530
+ indexes.push(fieldName);
1531
+ }
1532
+ }
1533
+ }
1534
+ }
1535
+ return {
1536
+ keyPath,
1537
+ indexes
1538
+ };
1539
+ }
1540
+ };
1541
+ function createPluresDBGenerator(outputDir, options) {
1542
+ return new PluresDBGenerator({
1543
+ outputDir,
1544
+ ...options
1545
+ });
1546
+ }
1547
+
1548
+ // src/integrations/pluresdb.ts
1549
+ function createPluresDBAdapter(options) {
1550
+ const store = createPraxisDBStore(options.db, options.registry, options.initialContext);
1551
+ const subscriptions = [];
1552
+ return {
1553
+ async persistEvents(events) {
1554
+ await store.appendEvents(events);
1555
+ },
1556
+ async persistFacts(facts) {
1557
+ await store.storeFacts(facts);
1558
+ },
1559
+ async loadEvents(query) {
1560
+ if (!query?.tag) {
1561
+ return [];
1562
+ }
1563
+ const entries = await store.getEvents(query.tag, {
1564
+ since: query.since,
1565
+ limit: query.limit
1566
+ });
1567
+ return entries.map((e) => e.event);
1568
+ },
1569
+ subscribeToEvents(callback, query) {
1570
+ if (!query?.tag) {
1571
+ return () => {
1572
+ };
1573
+ }
1574
+ const unsubscribe = store.watchFacts(query.tag, (facts) => {
1575
+ const events = facts.map((f) => ({
1576
+ tag: f.tag,
1577
+ payload: f.payload
1578
+ }));
1579
+ callback(events);
1580
+ });
1581
+ subscriptions.push(unsubscribe);
1582
+ return unsubscribe;
1583
+ },
1584
+ attachEngine(engine) {
1585
+ store.updateContext(engine.getContext());
1586
+ },
1587
+ dispose() {
1588
+ for (const unsub of subscriptions) {
1589
+ unsub();
1590
+ }
1591
+ subscriptions.length = 0;
1592
+ store.dispose();
1593
+ }
1594
+ };
1595
+ }
1596
+ function attachToEngine(store, engine) {
1597
+ store.updateContext(engine.getContext());
1598
+ return () => {
1599
+ store.dispose();
1600
+ };
1601
+ }
1602
+
1603
+ // src/integrations/unum.ts
1604
+ async function createUnumAdapter(config) {
1605
+ const { db, realtime = true } = config;
1606
+ let currentIdentity = null;
1607
+ const channels = /* @__PURE__ */ new Map();
1608
+ const subscriptions = /* @__PURE__ */ new Set();
1609
+ if (config.identity) {
1610
+ currentIdentity = {
1611
+ ...config.identity,
1612
+ id: config.identity.id || generateId2(),
1613
+ createdAt: Date.now()
1614
+ };
1615
+ await db.set(`unum/identities/${currentIdentity.id}`, currentIdentity);
1616
+ }
1617
+ async function setIdentity(identity) {
1618
+ currentIdentity = {
1619
+ ...identity,
1620
+ id: generateId2(),
1621
+ createdAt: Date.now()
1622
+ };
1623
+ await db.set(`unum/identities/${currentIdentity.id}`, currentIdentity);
1624
+ return currentIdentity;
1625
+ }
1626
+ async function getIdentity(id) {
1627
+ return await db.get(`unum/identities/${id}`);
1628
+ }
1629
+ async function createChannel(name, members) {
1630
+ const channelId = generateId2();
1631
+ const channelData = {
1632
+ id: channelId,
1633
+ name,
1634
+ members: members || [],
1635
+ createdAt: Date.now(),
1636
+ createdBy: currentIdentity?.id
1637
+ };
1638
+ await db.set(`unum/channels/${channelId}`, channelData);
1639
+ const channel = createChannelInstance(channelId, name);
1640
+ channels.set(channelId, channel);
1641
+ return channel;
1642
+ }
1643
+ async function joinChannel(channelId) {
1644
+ const existing = channels.get(channelId);
1645
+ if (existing) return existing;
1646
+ const channelData = await db.get(`unum/channels/${channelId}`);
1647
+ if (!channelData) {
1648
+ throw new Error(`Channel ${channelId} not found`);
1649
+ }
1650
+ const channel = createChannelInstance(channelData.id, channelData.name);
1651
+ channels.set(channelId, channel);
1652
+ return channel;
1653
+ }
1654
+ async function listChannels() {
1655
+ return Array.from(channels.values());
1656
+ }
1657
+ function createChannelInstance(id, name) {
1658
+ const handlers = /* @__PURE__ */ new Set();
1659
+ return {
1660
+ id,
1661
+ name,
1662
+ subscribe(handler) {
1663
+ handlers.add(handler);
1664
+ if (realtime) {
1665
+ const unsub = db.watch(`unum/channels/${id}/messages`, (data) => {
1666
+ if (data) {
1667
+ handler(data);
1668
+ }
1669
+ });
1670
+ subscriptions.add(unsub);
1671
+ }
1672
+ return () => {
1673
+ handlers.delete(handler);
1674
+ };
1675
+ },
1676
+ async publish(message) {
1677
+ const fullMessage = {
1678
+ ...message,
1679
+ id: message.id || generateId2(),
1680
+ channelId: id,
1681
+ timestamp: Date.now()
1682
+ };
1683
+ await db.set(`unum/channels/${id}/messages/${fullMessage.id}`, fullMessage);
1684
+ handlers.forEach((h) => h(fullMessage));
1685
+ },
1686
+ async getMembers() {
1687
+ const channelData = await db.get(`unum/channels/${id}`);
1688
+ if (!channelData?.members) return [];
1689
+ const members = [];
1690
+ for (const memberId of channelData.members) {
1691
+ const identity = await getIdentity(memberId);
1692
+ if (identity) members.push(identity);
1693
+ }
1694
+ return members;
1695
+ },
1696
+ async leave() {
1697
+ channels.delete(id);
1698
+ }
1699
+ };
1700
+ }
1701
+ async function broadcastEvent(channelId, event) {
1702
+ const channel = channels.get(channelId);
1703
+ if (!channel) {
1704
+ throw new Error(`Not joined to channel ${channelId}`);
1705
+ }
1706
+ await channel.publish({
1707
+ id: generateId2(),
1708
+ sender: currentIdentity || { id: "anonymous", createdAt: Date.now() },
1709
+ content: event,
1710
+ type: "event"
1711
+ });
1712
+ }
1713
+ async function broadcastFact(channelId, fact) {
1714
+ const channel = channels.get(channelId);
1715
+ if (!channel) {
1716
+ throw new Error(`Not joined to channel ${channelId}`);
1717
+ }
1718
+ await channel.publish({
1719
+ id: generateId2(),
1720
+ sender: currentIdentity || { id: "anonymous", createdAt: Date.now() },
1721
+ content: fact,
1722
+ type: "fact"
1723
+ });
1724
+ }
1725
+ function subscribeToEvents(channelId, handler) {
1726
+ const channel = channels.get(channelId);
1727
+ if (!channel) {
1728
+ throw new Error(`Not joined to channel ${channelId}`);
1729
+ }
1730
+ return channel.subscribe((message) => {
1731
+ if (message.type === "event") {
1732
+ handler(message.content);
1733
+ }
1734
+ });
1735
+ }
1736
+ function subscribeToFacts(channelId, handler) {
1737
+ const channel = channels.get(channelId);
1738
+ if (!channel) {
1739
+ throw new Error(`Not joined to channel ${channelId}`);
1740
+ }
1741
+ return channel.subscribe((message) => {
1742
+ if (message.type === "fact") {
1743
+ handler(message.content);
1744
+ }
1745
+ });
1746
+ }
1747
+ async function disconnect() {
1748
+ subscriptions.forEach((unsub) => unsub());
1749
+ subscriptions.clear();
1750
+ for (const channel of channels.values()) {
1751
+ await channel.leave();
1752
+ }
1753
+ channels.clear();
1754
+ currentIdentity = null;
1755
+ }
1756
+ return {
1757
+ get identity() {
1758
+ return currentIdentity;
1759
+ },
1760
+ setIdentity,
1761
+ getIdentity,
1762
+ createChannel,
1763
+ joinChannel,
1764
+ listChannels,
1765
+ broadcastEvent,
1766
+ broadcastFact,
1767
+ subscribeToEvents,
1768
+ subscribeToFacts,
1769
+ disconnect
1770
+ };
1771
+ }
1772
+ function generateId2() {
1773
+ return `${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 9)}`;
1774
+ }
1775
+ function attachUnumToEngine(_engine, _adapter, _channelId) {
1776
+ return () => {
1777
+ };
1778
+ }
1779
+
1780
+ // src/integrations/code-canvas.ts
1781
+ function schemaToCanvas(schema, _options = {}) {
1782
+ const nodes = [];
1783
+ const edges = [];
1784
+ let nodeId = 0;
1785
+ let yOffset = 0;
1786
+ const xSpacing = 200;
1787
+ const ySpacing = 100;
1788
+ if (schema.models) {
1789
+ schema.models.forEach((model, index) => {
1790
+ const pos = model.position && (model.position.x !== 0 || model.position.y !== 0) ? model.position : { x: 50, y: yOffset + index * ySpacing };
1791
+ const node = {
1792
+ id: model.id || `model-${nodeId++}`,
1793
+ type: "model",
1794
+ label: model.name,
1795
+ x: pos.x,
1796
+ y: pos.y,
1797
+ width: 150,
1798
+ height: 60,
1799
+ data: model,
1800
+ style: {
1801
+ backgroundColor: "#e3f2fd",
1802
+ borderColor: "#1976d2"
1803
+ }
1804
+ };
1805
+ nodes.push(node);
1806
+ });
1807
+ yOffset += schema.models.length * ySpacing + 50;
1808
+ }
1809
+ if (schema.components) {
1810
+ schema.components.forEach((component, index) => {
1811
+ const pos = component.position && (component.position.x !== 0 || component.position.y !== 0) ? component.position : { x: 50 + xSpacing, y: yOffset + index * ySpacing };
1812
+ const node = {
1813
+ id: component.id || `component-${nodeId++}`,
1814
+ type: "component",
1815
+ label: component.name,
1816
+ x: pos.x,
1817
+ y: pos.y,
1818
+ width: 150,
1819
+ height: 60,
1820
+ data: component,
1821
+ style: {
1822
+ backgroundColor: "#e8f5e9",
1823
+ borderColor: "#388e3c"
1824
+ }
1825
+ };
1826
+ nodes.push(node);
1827
+ if (component.model) {
1828
+ const modelNode = nodes.find((n) => n.type === "model" && n.label === component.model);
1829
+ if (modelNode) {
1830
+ edges.push({
1831
+ id: `edge-${edges.length}`,
1832
+ source: node.id,
1833
+ target: modelNode.id,
1834
+ type: "reference",
1835
+ label: "uses"
1836
+ });
1837
+ }
1838
+ }
1839
+ });
1840
+ yOffset += schema.components.length * ySpacing + 50;
1841
+ }
1842
+ if (schema.events) {
1843
+ schema.events.forEach((event, index) => {
1844
+ const pos = event.position && (event.position.x !== 0 || event.position.y !== 0) ? event.position : { x: 50 + xSpacing * 2, y: yOffset + index * ySpacing };
1845
+ const node = {
1846
+ id: event.id || `event-${nodeId++}`,
1847
+ type: "event",
1848
+ label: event.tag,
1849
+ x: pos.x,
1850
+ y: pos.y,
1851
+ width: 150,
1852
+ height: 50,
1853
+ data: event,
1854
+ style: {
1855
+ backgroundColor: "#fff3e0",
1856
+ borderColor: "#f57c00"
1857
+ }
1858
+ };
1859
+ nodes.push(node);
1860
+ });
1861
+ yOffset += schema.events.length * ySpacing + 30;
1862
+ }
1863
+ if (schema.facts) {
1864
+ schema.facts.forEach((fact, index) => {
1865
+ const pos = fact.position && (fact.position.x !== 0 || fact.position.y !== 0) ? fact.position : { x: 50 + xSpacing * 3, y: yOffset + index * ySpacing };
1866
+ const node = {
1867
+ id: fact.id || `fact-${nodeId++}`,
1868
+ type: "fact",
1869
+ label: fact.tag,
1870
+ x: pos.x,
1871
+ y: pos.y,
1872
+ width: 150,
1873
+ height: 50,
1874
+ data: fact,
1875
+ style: {
1876
+ backgroundColor: "#fce4ec",
1877
+ borderColor: "#c2185b"
1878
+ }
1879
+ };
1880
+ nodes.push(node);
1881
+ });
1882
+ yOffset += schema.facts.length * ySpacing + 30;
1883
+ }
1884
+ if (schema.rules) {
1885
+ schema.rules.forEach((rule, index) => {
1886
+ const pos = rule.position && (rule.position.x !== 0 || rule.position.y !== 0) ? rule.position : { x: 50 + xSpacing * 4, y: yOffset + index * ySpacing };
1887
+ const node = {
1888
+ id: rule.id || `rule-${nodeId++}`,
1889
+ type: "rule",
1890
+ label: rule.id,
1891
+ x: pos.x,
1892
+ y: pos.y,
1893
+ width: 150,
1894
+ height: 50,
1895
+ data: rule,
1896
+ style: {
1897
+ backgroundColor: "#e1f5fe",
1898
+ borderColor: "#0288d1"
1899
+ }
1900
+ };
1901
+ nodes.push(node);
1902
+ if (rule.triggers) {
1903
+ rule.triggers.forEach((trigger) => {
1904
+ const eventNode = nodes.find((n) => n.type === "event" && n.label === trigger);
1905
+ if (eventNode) {
1906
+ edges.push({
1907
+ id: `edge-${edges.length}`,
1908
+ source: eventNode.id,
1909
+ target: node.id,
1910
+ type: "event",
1911
+ label: "triggers"
1912
+ });
1913
+ }
1914
+ });
1915
+ }
1916
+ });
1917
+ yOffset += schema.rules.length * ySpacing + 30;
1918
+ }
1919
+ if (schema.constraints) {
1920
+ schema.constraints.forEach((constraint, index) => {
1921
+ const pos = constraint.position && (constraint.position.x !== 0 || constraint.position.y !== 0) ? constraint.position : { x: 50 + xSpacing * 5, y: yOffset + index * ySpacing };
1922
+ const node = {
1923
+ id: constraint.id || `constraint-${nodeId++}`,
1924
+ type: "constraint",
1925
+ label: constraint.id,
1926
+ x: pos.x,
1927
+ y: pos.y,
1928
+ width: 150,
1929
+ height: 50,
1930
+ data: constraint,
1931
+ style: {
1932
+ backgroundColor: "#ffebee",
1933
+ borderColor: "#c62828"
1934
+ }
1935
+ };
1936
+ nodes.push(node);
1937
+ });
1938
+ }
1939
+ return {
1940
+ id: `canvas-${Date.now()}`,
1941
+ name: schema.name || "Praxis Schema",
1942
+ version: schema.$version || "1.0.0",
1943
+ nodes,
1944
+ edges,
1945
+ flows: schema.flows || [],
1946
+ metadata: {
1947
+ created: Date.now(),
1948
+ modified: Date.now(),
1949
+ description: schema.description
1950
+ },
1951
+ viewport: { x: 0, y: 0, zoom: 1 }
1952
+ };
1953
+ }
1954
+ function canvasToSchema(canvas) {
1955
+ const models = [];
1956
+ const components = [];
1957
+ const events = [];
1958
+ const facts = [];
1959
+ const rules = [];
1960
+ const constraints = [];
1961
+ for (const node of canvas.nodes) {
1962
+ const position = { x: node.x, y: node.y };
1963
+ switch (node.type) {
1964
+ case "model":
1965
+ if (node.data) {
1966
+ models.push({ ...node.data, position });
1967
+ }
1968
+ break;
1969
+ case "component":
1970
+ if (node.data) {
1971
+ components.push({ ...node.data, position });
1972
+ }
1973
+ break;
1974
+ case "event":
1975
+ if (node.data) {
1976
+ events.push({ ...node.data, position });
1977
+ }
1978
+ break;
1979
+ case "fact":
1980
+ if (node.data) {
1981
+ facts.push({ ...node.data, position });
1982
+ }
1983
+ break;
1984
+ case "rule":
1985
+ if (node.data) {
1986
+ rules.push({ ...node.data, position });
1987
+ }
1988
+ break;
1989
+ case "constraint":
1990
+ if (node.data) {
1991
+ constraints.push({ ...node.data, position });
1992
+ }
1993
+ break;
1994
+ }
1995
+ }
1996
+ return {
1997
+ $version: "1.0.0",
1998
+ id: canvas.id,
1999
+ name: canvas.name,
2000
+ description: canvas.metadata?.description,
2001
+ models,
2002
+ components,
2003
+ events,
2004
+ facts,
2005
+ rules,
2006
+ constraints,
2007
+ flows: canvas.flows || [],
2008
+ metadata: canvas.metadata
2009
+ };
2010
+ }
2011
+ function canvasToYaml(canvas) {
2012
+ const lines = [
2013
+ `# ${canvas.name}`,
2014
+ `# Generated by Praxis CodeCanvas Integration`,
2015
+ `# Version: ${canvas.version}`,
2016
+ "",
2017
+ "nodes:"
2018
+ ];
2019
+ for (const node of canvas.nodes) {
2020
+ lines.push(` - id: "${node.id}"`);
2021
+ lines.push(` type: "${node.type}"`);
2022
+ lines.push(` label: "${node.label}"`);
2023
+ lines.push(` x: ${node.x}`);
2024
+ lines.push(` y: ${node.y}`);
2025
+ lines.push(` width: ${node.width}`);
2026
+ lines.push(` height: ${node.height}`);
2027
+ if (node.fsmState) {
2028
+ lines.push(` fsmState: "${node.fsmState}"`);
2029
+ }
2030
+ lines.push("");
2031
+ }
2032
+ lines.push("edges:");
2033
+ for (const edge of canvas.edges) {
2034
+ lines.push(` - id: "${edge.id}"`);
2035
+ lines.push(` source: "${edge.source}"`);
2036
+ lines.push(` target: "${edge.target}"`);
2037
+ if (edge.label) {
2038
+ lines.push(` label: "${edge.label}"`);
2039
+ }
2040
+ if (edge.type) {
2041
+ lines.push(` type: "${edge.type}"`);
2042
+ }
2043
+ lines.push("");
2044
+ }
2045
+ return lines.join("\n");
2046
+ }
2047
+ function canvasToMermaid(canvas) {
2048
+ const lines = ["graph TD"];
2049
+ for (const node of canvas.nodes) {
2050
+ let shape;
2051
+ switch (node.type) {
2052
+ case "model":
2053
+ shape = `[${node.label}]`;
2054
+ break;
2055
+ case "component":
2056
+ shape = `(${node.label})`;
2057
+ break;
2058
+ case "event":
2059
+ shape = `{{${node.label}}}`;
2060
+ break;
2061
+ case "fact":
2062
+ shape = `((${node.label}))`;
2063
+ break;
2064
+ case "rule":
2065
+ shape = `[/${node.label}/]`;
2066
+ break;
2067
+ case "constraint":
2068
+ shape = `[\\${node.label}\\]`;
2069
+ break;
2070
+ default:
2071
+ shape = `[${node.label}]`;
2072
+ }
2073
+ lines.push(` ${node.id}${shape}`);
2074
+ }
2075
+ lines.push("");
2076
+ for (const edge of canvas.edges) {
2077
+ const label = edge.label ? `|${edge.label}|` : "";
2078
+ lines.push(` ${edge.source} -->${label} ${edge.target}`);
2079
+ }
2080
+ return lines.join("\n");
2081
+ }
2082
+ function validateWithGuardian(files, activity, lifecycle) {
2083
+ const errors = [];
2084
+ const warnings = [];
2085
+ const currentState = lifecycle.find((s) => s.id === activity.activity);
2086
+ if (!currentState) {
2087
+ errors.push({
2088
+ code: "INVALID_ACTIVITY",
2089
+ message: `Activity "${activity.activity}" is not a valid lifecycle state`,
2090
+ rule: "lifecycle-state"
2091
+ });
2092
+ }
2093
+ if (activity.allowedPaths) {
2094
+ for (const file of files) {
2095
+ const allowed = activity.allowedPaths.some((pattern) => {
2096
+ const regex = new RegExp("^" + pattern.replace(/\*/g, ".*") + "$");
2097
+ return regex.test(file);
2098
+ });
2099
+ if (!allowed) {
2100
+ errors.push({
2101
+ code: "PATH_NOT_ALLOWED",
2102
+ message: `File "${file}" is not allowed during "${activity.activity}" activity`,
2103
+ file,
2104
+ rule: "allowed-paths"
2105
+ });
2106
+ }
2107
+ }
2108
+ }
2109
+ return {
2110
+ valid: errors.length === 0,
2111
+ errors,
2112
+ warnings,
2113
+ filesChecked: files,
2114
+ activity
2115
+ };
2116
+ }
2117
+ function createCanvasEditor(config) {
2118
+ const document = config.document || (config.schema ? schemaToCanvas(config.schema, { layout: config.layout }) : {
2119
+ id: `canvas-${Date.now()}`,
2120
+ name: "New Canvas",
2121
+ version: "1.0.0",
2122
+ nodes: [],
2123
+ edges: [],
2124
+ metadata: { created: Date.now(), modified: Date.now() },
2125
+ viewport: { x: 0, y: 0, zoom: 1 }
2126
+ });
2127
+ let nodeIdCounter = document.nodes.length;
2128
+ let edgeIdCounter = document.edges.length;
2129
+ return {
2130
+ document,
2131
+ addNode(node) {
2132
+ const fullNode = {
2133
+ ...node,
2134
+ id: `node-${nodeIdCounter++}`
2135
+ };
2136
+ document.nodes.push(fullNode);
2137
+ document.metadata.modified = Date.now();
2138
+ return fullNode;
2139
+ },
2140
+ removeNode(id) {
2141
+ const index = document.nodes.findIndex((n) => n.id === id);
2142
+ if (index !== -1) {
2143
+ document.nodes.splice(index, 1);
2144
+ document.edges = document.edges.filter((e) => e.source !== id && e.target !== id);
2145
+ document.metadata.modified = Date.now();
2146
+ }
2147
+ },
2148
+ addEdge(edge) {
2149
+ const fullEdge = {
2150
+ ...edge,
2151
+ id: `edge-${edgeIdCounter++}`
2152
+ };
2153
+ document.edges.push(fullEdge);
2154
+ document.metadata.modified = Date.now();
2155
+ return fullEdge;
2156
+ },
2157
+ removeEdge(id) {
2158
+ const index = document.edges.findIndex((e) => e.id === id);
2159
+ if (index !== -1) {
2160
+ document.edges.splice(index, 1);
2161
+ document.metadata.modified = Date.now();
2162
+ }
2163
+ },
2164
+ toSchema() {
2165
+ return canvasToSchema(document);
2166
+ },
2167
+ toYaml() {
2168
+ return canvasToYaml(document);
2169
+ },
2170
+ toMermaid() {
2171
+ return canvasToMermaid(document);
2172
+ }
2173
+ };
2174
+ }
2175
+
2176
+ // src/integrations/state-docs.ts
2177
+ var StateDocsGenerator = class {
2178
+ config;
2179
+ constructor(config) {
2180
+ this.config = {
2181
+ target: "./docs",
2182
+ globs: ["**/*.ts", "**/*.js"],
2183
+ visualization: {
2184
+ format: "mermaid",
2185
+ exportPng: false,
2186
+ theme: "default"
2187
+ },
2188
+ template: {
2189
+ toc: true,
2190
+ timestamp: true
2191
+ },
2192
+ ...config
2193
+ };
2194
+ }
2195
+ /**
2196
+ * Generate documentation from a Praxis schema
2197
+ */
2198
+ generateFromSchema(schema) {
2199
+ const docs = [];
2200
+ docs.push(this.generateSchemaReadme(schema));
2201
+ if (schema.models && schema.models.length > 0) {
2202
+ docs.push(this.generateModelsDoc(schema));
2203
+ }
2204
+ if (schema.components && schema.components.length > 0) {
2205
+ docs.push(this.generateComponentsDoc(schema));
2206
+ }
2207
+ if (schema.logic && schema.logic.length > 0) {
2208
+ for (const logic of schema.logic) {
2209
+ docs.push(this.generateLogicDoc(logic));
2210
+ docs.push(this.generateLogicDiagram(logic));
2211
+ }
2212
+ }
2213
+ return docs;
2214
+ }
2215
+ /**
2216
+ * Generate documentation from a Praxis registry
2217
+ */
2218
+ generateFromModule(module) {
2219
+ const docs = [];
2220
+ const rules = module.rules;
2221
+ const constraints = module.constraints;
2222
+ docs.push(this.generateRulesDoc(rules));
2223
+ docs.push(this.generateConstraintsDoc(constraints));
2224
+ docs.push(this.generateRegistryDiagram(rules, constraints));
2225
+ return docs;
2226
+ }
2227
+ /**
2228
+ * Generate the main schema README
2229
+ */
2230
+ generateSchemaReadme(schema) {
2231
+ const lines = [];
2232
+ if (this.config.template?.header) {
2233
+ lines.push(this.config.template.header);
2234
+ lines.push("");
2235
+ }
2236
+ lines.push(`# ${schema.name || this.config.projectTitle}`);
2237
+ lines.push("");
2238
+ if (schema.description) {
2239
+ lines.push(schema.description);
2240
+ lines.push("");
2241
+ }
2242
+ if (this.config.template?.toc) {
2243
+ lines.push("## Table of Contents");
2244
+ lines.push("");
2245
+ lines.push("- [Overview](#overview)");
2246
+ if (schema.models && schema.models.length > 0) {
2247
+ lines.push("- [Models](#models)");
2248
+ }
2249
+ if (schema.components && schema.components.length > 0) {
2250
+ lines.push("- [Components](#components)");
2251
+ }
2252
+ if (schema.logic && schema.logic.length > 0) {
2253
+ lines.push("- [Logic](#logic)");
2254
+ }
2255
+ lines.push("");
2256
+ }
2257
+ lines.push("## Overview");
2258
+ lines.push("");
2259
+ lines.push(`**Version:** ${schema.version}`);
2260
+ lines.push("");
2261
+ lines.push("### Statistics");
2262
+ lines.push("");
2263
+ lines.push("| Category | Count |");
2264
+ lines.push("|----------|-------|");
2265
+ lines.push(`| Models | ${schema.models?.length || 0} |`);
2266
+ lines.push(`| Components | ${schema.components?.length || 0} |`);
2267
+ lines.push(`| Logic Modules | ${schema.logic?.length || 0} |`);
2268
+ lines.push("");
2269
+ if (schema.models && schema.models.length > 0) {
2270
+ lines.push("## Models");
2271
+ lines.push("");
2272
+ for (const model of schema.models) {
2273
+ lines.push(`### ${model.name}`);
2274
+ lines.push("");
2275
+ if (model.description) {
2276
+ lines.push(model.description);
2277
+ lines.push("");
2278
+ }
2279
+ lines.push("**Fields:**");
2280
+ lines.push("");
2281
+ lines.push("| Name | Type | Required |");
2282
+ lines.push("|------|------|----------|");
2283
+ for (const field of model.fields) {
2284
+ const required = field.optional ? "No" : "Yes";
2285
+ lines.push(`| ${field.name} | ${field.type} | ${required} |`);
2286
+ }
2287
+ lines.push("");
2288
+ }
2289
+ }
2290
+ if (schema.components && schema.components.length > 0) {
2291
+ lines.push("## Components");
2292
+ lines.push("");
2293
+ for (const component of schema.components) {
2294
+ lines.push(`### ${component.name}`);
2295
+ lines.push("");
2296
+ lines.push(`**Type:** ${component.type}`);
2297
+ lines.push("");
2298
+ if (component.description) {
2299
+ lines.push(component.description);
2300
+ lines.push("");
2301
+ }
2302
+ if (component.model) {
2303
+ lines.push(`**Model:** ${component.model}`);
2304
+ lines.push("");
2305
+ }
2306
+ }
2307
+ }
2308
+ if (schema.logic && schema.logic.length > 0) {
2309
+ lines.push("## Logic");
2310
+ lines.push("");
2311
+ for (const logic of schema.logic) {
2312
+ lines.push(`### ${logic.id}`);
2313
+ lines.push("");
2314
+ if (logic.description) {
2315
+ lines.push(logic.description);
2316
+ lines.push("");
2317
+ }
2318
+ if (logic.events && logic.events.length > 0) {
2319
+ lines.push("**Events:**");
2320
+ lines.push("");
2321
+ for (const event of logic.events) {
2322
+ lines.push(`- \`${event.tag}\`: ${event.description || ""}`);
2323
+ }
2324
+ lines.push("");
2325
+ }
2326
+ if (logic.facts && logic.facts.length > 0) {
2327
+ lines.push("**Facts:**");
2328
+ lines.push("");
2329
+ for (const fact of logic.facts) {
2330
+ lines.push(`- \`${fact.tag}\`: ${fact.description || ""}`);
2331
+ }
2332
+ lines.push("");
2333
+ }
2334
+ if (logic.rules && logic.rules.length > 0) {
2335
+ lines.push("**Rules:**");
2336
+ lines.push("");
2337
+ for (const rule of logic.rules) {
2338
+ lines.push(`- \`${rule.id}\`: ${rule.description || ""}`);
2339
+ }
2340
+ lines.push("");
2341
+ }
2342
+ }
2343
+ }
2344
+ if (this.config.template?.timestamp) {
2345
+ lines.push("---");
2346
+ lines.push("");
2347
+ lines.push(`*Generated on ${(/* @__PURE__ */ new Date()).toISOString()} by State-Docs*`);
2348
+ }
2349
+ if (this.config.template?.footer) {
2350
+ lines.push("");
2351
+ lines.push(this.config.template.footer);
2352
+ }
2353
+ return {
2354
+ path: `${this.config.target}/README.md`,
2355
+ content: lines.join("\n"),
2356
+ type: "markdown"
2357
+ };
2358
+ }
2359
+ /**
2360
+ * Generate models documentation
2361
+ */
2362
+ generateModelsDoc(schema) {
2363
+ const lines = [
2364
+ "# Models",
2365
+ "",
2366
+ "This document describes all data models defined in the schema.",
2367
+ ""
2368
+ ];
2369
+ if (schema.models) {
2370
+ for (const model of schema.models) {
2371
+ lines.push(`## ${model.name}`);
2372
+ lines.push("");
2373
+ if (model.description) {
2374
+ lines.push(model.description);
2375
+ lines.push("");
2376
+ }
2377
+ lines.push("### Fields");
2378
+ lines.push("");
2379
+ lines.push("| Name | Type | Required | Description |");
2380
+ lines.push("|------|------|----------|-------------|");
2381
+ for (const field of model.fields) {
2382
+ const required = field.optional ? "No" : "Yes";
2383
+ const description = field.description || "-";
2384
+ lines.push(`| ${field.name} | \`${field.type}\` | ${required} | ${description} |`);
2385
+ }
2386
+ lines.push("");
2387
+ if (model.indexes && model.indexes.length > 0) {
2388
+ lines.push("### Indexes");
2389
+ lines.push("");
2390
+ for (const index of model.indexes) {
2391
+ lines.push(`- **${index.name}**: \`${index.fields.join(", ")}\``);
2392
+ }
2393
+ lines.push("");
2394
+ }
2395
+ }
2396
+ }
2397
+ return {
2398
+ path: `${this.config.target}/models.md`,
2399
+ content: lines.join("\n"),
2400
+ type: "markdown"
2401
+ };
2402
+ }
2403
+ /**
2404
+ * Generate components documentation
2405
+ */
2406
+ generateComponentsDoc(schema) {
2407
+ const lines = [
2408
+ "# Components",
2409
+ "",
2410
+ "This document describes all UI components defined in the schema.",
2411
+ ""
2412
+ ];
2413
+ if (schema.components) {
2414
+ for (const component of schema.components) {
2415
+ lines.push(`## ${component.name}`);
2416
+ lines.push("");
2417
+ lines.push(`**Type:** ${component.type}`);
2418
+ lines.push("");
2419
+ if (component.description) {
2420
+ lines.push(component.description);
2421
+ lines.push("");
2422
+ }
2423
+ if (component.model) {
2424
+ lines.push(
2425
+ `**Associated Model:** [${component.model}](./models.md#${component.model.toLowerCase()})`
2426
+ );
2427
+ lines.push("");
2428
+ }
2429
+ }
2430
+ }
2431
+ return {
2432
+ path: `${this.config.target}/components.md`,
2433
+ content: lines.join("\n"),
2434
+ type: "markdown"
2435
+ };
2436
+ }
2437
+ /**
2438
+ * Generate logic documentation
2439
+ */
2440
+ generateLogicDoc(logic) {
2441
+ const lines = [`# ${logic.id}`, ""];
2442
+ if (logic.description) {
2443
+ lines.push(logic.description);
2444
+ lines.push("");
2445
+ }
2446
+ if (logic.events && logic.events.length > 0) {
2447
+ lines.push("## Events");
2448
+ lines.push("");
2449
+ lines.push("| Event | Description | Payload |");
2450
+ lines.push("|-------|-------------|---------|");
2451
+ for (const event of logic.events) {
2452
+ const payload = event.payload ? Object.entries(event.payload).map(([k, v]) => `${k}: ${v}`).join(", ") : "-";
2453
+ lines.push(`| \`${event.tag}\` | ${event.description || "-"} | ${payload} |`);
2454
+ }
2455
+ lines.push("");
2456
+ }
2457
+ if (logic.facts && logic.facts.length > 0) {
2458
+ lines.push("## Facts");
2459
+ lines.push("");
2460
+ lines.push("| Fact | Description | Payload |");
2461
+ lines.push("|------|-------------|---------|");
2462
+ for (const fact of logic.facts) {
2463
+ const payload = fact.payload ? Object.entries(fact.payload).map(([k, v]) => `${k}: ${v}`).join(", ") : "-";
2464
+ lines.push(`| \`${fact.tag}\` | ${fact.description || "-"} | ${payload} |`);
2465
+ }
2466
+ lines.push("");
2467
+ }
2468
+ if (logic.rules && logic.rules.length > 0) {
2469
+ lines.push("## Rules");
2470
+ lines.push("");
2471
+ for (const rule of logic.rules) {
2472
+ lines.push(`### ${rule.id}`);
2473
+ lines.push("");
2474
+ if (rule.description) {
2475
+ lines.push(rule.description);
2476
+ lines.push("");
2477
+ }
2478
+ if (rule.priority !== void 0) {
2479
+ lines.push(`**Priority:** ${rule.priority}`);
2480
+ lines.push("");
2481
+ }
2482
+ }
2483
+ }
2484
+ if (logic.constraints && logic.constraints.length > 0) {
2485
+ lines.push("## Constraints");
2486
+ lines.push("");
2487
+ for (const constraint of logic.constraints) {
2488
+ lines.push(`### ${constraint.id}`);
2489
+ lines.push("");
2490
+ if (constraint.description) {
2491
+ lines.push(constraint.description);
2492
+ lines.push("");
2493
+ }
2494
+ if (constraint.message) {
2495
+ lines.push(`**Error Message:** ${constraint.message}`);
2496
+ lines.push("");
2497
+ }
2498
+ }
2499
+ }
2500
+ return {
2501
+ path: `${this.config.target}/logic/${logic.id}.md`,
2502
+ content: lines.join("\n"),
2503
+ type: "markdown"
2504
+ };
2505
+ }
2506
+ /**
2507
+ * Generate Mermaid diagram for logic
2508
+ */
2509
+ generateLogicDiagram(logic) {
2510
+ const lines = ["stateDiagram-v2"];
2511
+ if (logic.events && logic.facts) {
2512
+ lines.push(" [*] --> Processing");
2513
+ for (const event of logic.events) {
2514
+ lines.push(` Processing --> ${event.tag.replace(/[^a-zA-Z0-9]/g, "")}: ${event.tag}`);
2515
+ }
2516
+ for (const fact of logic.facts) {
2517
+ lines.push(` ${fact.tag.replace(/[^a-zA-Z0-9]/g, "")} --> [*]`);
2518
+ }
2519
+ }
2520
+ return {
2521
+ path: `${this.config.target}/logic/${logic.id}.mmd`,
2522
+ content: lines.join("\n"),
2523
+ type: "mermaid"
2524
+ };
2525
+ }
2526
+ /**
2527
+ * Generate rules documentation
2528
+ */
2529
+ generateRulesDoc(rules) {
2530
+ const lines = [
2531
+ "# Rules",
2532
+ "",
2533
+ "This document describes all rules registered in the Praxis engine.",
2534
+ ""
2535
+ ];
2536
+ for (const rule of rules) {
2537
+ lines.push(`## ${rule.id}`);
2538
+ lines.push("");
2539
+ if (rule.description) {
2540
+ lines.push(rule.description);
2541
+ lines.push("");
2542
+ }
2543
+ if (rule.meta?.eventType) {
2544
+ lines.push(`**Triggers on:** \`${rule.meta.eventType}\``);
2545
+ lines.push("");
2546
+ }
2547
+ if (rule.meta?.priority !== void 0) {
2548
+ lines.push(`**Priority:** ${rule.meta.priority}`);
2549
+ lines.push("");
2550
+ }
2551
+ }
2552
+ return {
2553
+ path: `${this.config.target}/rules.md`,
2554
+ content: lines.join("\n"),
2555
+ type: "markdown"
2556
+ };
2557
+ }
2558
+ /**
2559
+ * Generate constraints documentation
2560
+ */
2561
+ generateConstraintsDoc(constraints) {
2562
+ const lines = [
2563
+ "# Constraints",
2564
+ "",
2565
+ "This document describes all constraints (invariants) registered in the Praxis engine.",
2566
+ ""
2567
+ ];
2568
+ for (const constraint of constraints) {
2569
+ lines.push(`## ${constraint.id}`);
2570
+ lines.push("");
2571
+ if (constraint.description) {
2572
+ lines.push(constraint.description);
2573
+ lines.push("");
2574
+ }
2575
+ if (constraint.meta?.errorMessage) {
2576
+ lines.push(`**Error Message:** ${constraint.meta.errorMessage}`);
2577
+ lines.push("");
2578
+ }
2579
+ }
2580
+ return {
2581
+ path: `${this.config.target}/constraints.md`,
2582
+ content: lines.join("\n"),
2583
+ type: "markdown"
2584
+ };
2585
+ }
2586
+ /**
2587
+ * Generate state diagram from registry
2588
+ */
2589
+ generateRegistryDiagram(rules, constraints) {
2590
+ const lines = ["graph TD", " subgraph Rules"];
2591
+ for (const rule of rules) {
2592
+ const id = rule.id.replace(/[^a-zA-Z0-9]/g, "_");
2593
+ lines.push(` ${id}["${rule.id}"]`);
2594
+ }
2595
+ lines.push(" end");
2596
+ lines.push(" subgraph Constraints");
2597
+ for (const constraint of constraints) {
2598
+ const id = constraint.id.replace(/[^a-zA-Z0-9]/g, "_");
2599
+ lines.push(` ${id}["${constraint.id}"]`);
2600
+ }
2601
+ lines.push(" end");
2602
+ return {
2603
+ path: `${this.config.target}/state-diagram.mmd`,
2604
+ content: lines.join("\n"),
2605
+ type: "mermaid"
2606
+ };
2607
+ }
2608
+ };
2609
+ function createStateDocsGenerator(config) {
2610
+ return new StateDocsGenerator(config);
2611
+ }
2612
+ function generateDocs(schema, config) {
2613
+ const generator = createStateDocsGenerator(config);
2614
+ return generator.generateFromSchema(schema);
2615
+ }
2616
+
2617
+ // src/integrations/tauri.ts
2618
+ function createMockTauriBridge() {
2619
+ const eventHandlers = /* @__PURE__ */ new Map();
2620
+ const storage = /* @__PURE__ */ new Map();
2621
+ return {
2622
+ app: {
2623
+ name: "Mock App",
2624
+ version: "0.0.0",
2625
+ tauriVersion: "mock"
2626
+ },
2627
+ fs: {
2628
+ async readFile(path) {
2629
+ const data = storage.get(path);
2630
+ if (data instanceof Uint8Array) return data;
2631
+ throw new Error(`File not found: ${path}`);
2632
+ },
2633
+ async readTextFile(path) {
2634
+ const data = storage.get(path);
2635
+ if (typeof data === "string") return data;
2636
+ throw new Error(`File not found: ${path}`);
2637
+ },
2638
+ async writeFile(path, data) {
2639
+ storage.set(path, data);
2640
+ },
2641
+ async writeTextFile(path, data) {
2642
+ storage.set(path, data);
2643
+ },
2644
+ async exists(path) {
2645
+ return storage.has(path);
2646
+ },
2647
+ async mkdir(_path, _options) {
2648
+ },
2649
+ async remove(path, _options) {
2650
+ storage.delete(path);
2651
+ },
2652
+ async rename(oldPath, newPath) {
2653
+ const data = storage.get(oldPath);
2654
+ if (data !== void 0) {
2655
+ storage.set(newPath, data);
2656
+ storage.delete(oldPath);
2657
+ }
2658
+ },
2659
+ async readDir(_path) {
2660
+ return [];
2661
+ }
2662
+ },
2663
+ tray: {
2664
+ async setIcon(_icon) {
2665
+ },
2666
+ async setTooltip(_tooltip) {
2667
+ },
2668
+ async setMenu(_menu) {
2669
+ },
2670
+ async show() {
2671
+ },
2672
+ async hide() {
2673
+ }
2674
+ },
2675
+ notification: {
2676
+ async send(options) {
2677
+ console.log("Mock notification:", options.title, options.body);
2678
+ },
2679
+ async requestPermission() {
2680
+ return "granted";
2681
+ },
2682
+ async checkPermission() {
2683
+ return "granted";
2684
+ }
2685
+ },
2686
+ async invoke(cmd, payload) {
2687
+ console.log("Mock invoke:", cmd, payload);
2688
+ return null;
2689
+ },
2690
+ async listen(event, handler) {
2691
+ if (!eventHandlers.has(event)) {
2692
+ eventHandlers.set(event, /* @__PURE__ */ new Set());
2693
+ }
2694
+ eventHandlers.get(event).add(handler);
2695
+ return () => {
2696
+ eventHandlers.get(event)?.delete(handler);
2697
+ };
2698
+ },
2699
+ async emit(event, payload) {
2700
+ const handlers = eventHandlers.get(event);
2701
+ if (handlers) {
2702
+ const tauriEvent = { event, payload };
2703
+ handlers.forEach((h) => h(tauriEvent));
2704
+ }
2705
+ },
2706
+ window: {
2707
+ async minimize() {
2708
+ },
2709
+ async maximize() {
2710
+ },
2711
+ async unmaximize() {
2712
+ },
2713
+ async close() {
2714
+ },
2715
+ async toggleFullscreen() {
2716
+ },
2717
+ async setTitle(_title) {
2718
+ },
2719
+ async show() {
2720
+ },
2721
+ async hide() {
2722
+ },
2723
+ async focus() {
2724
+ }
2725
+ },
2726
+ async checkForUpdates() {
2727
+ return null;
2728
+ },
2729
+ async installUpdate() {
2730
+ }
2731
+ };
2732
+ }
2733
+ function createTauriPraxisAdapter(options) {
2734
+ const { bridge, statePath = "praxis-state.json", eventsPath = "praxis-events.json" } = options;
2735
+ return {
2736
+ async saveState(state2) {
2737
+ const json = JSON.stringify(state2, null, 2);
2738
+ await bridge.fs.writeTextFile(statePath, json);
2739
+ },
2740
+ async loadState() {
2741
+ try {
2742
+ const exists = await bridge.fs.exists(statePath);
2743
+ if (!exists) return null;
2744
+ const json = await bridge.fs.readTextFile(statePath);
2745
+ return JSON.parse(json);
2746
+ } catch {
2747
+ return null;
2748
+ }
2749
+ },
2750
+ async saveEvents(events) {
2751
+ const json = JSON.stringify(events, null, 2);
2752
+ await bridge.fs.writeTextFile(eventsPath, json);
2753
+ },
2754
+ async loadEvents() {
2755
+ try {
2756
+ const exists = await bridge.fs.exists(eventsPath);
2757
+ if (!exists) return [];
2758
+ const json = await bridge.fs.readTextFile(eventsPath);
2759
+ return JSON.parse(json);
2760
+ } catch {
2761
+ return [];
2762
+ }
2763
+ },
2764
+ async watchStateFile(_handler) {
2765
+ console.log("File watching not implemented in mock");
2766
+ return () => {
2767
+ };
2768
+ },
2769
+ getStatePath() {
2770
+ return statePath;
2771
+ },
2772
+ getEventsPath() {
2773
+ return eventsPath;
2774
+ }
2775
+ };
2776
+ }
2777
+ function attachTauriToEngine(engine, adapter, options = {}) {
2778
+ const { autoSave = true, saveInterval = 5e3 } = options;
2779
+ const cleanupFns = [];
2780
+ if (autoSave) {
2781
+ let saveTimer = null;
2782
+ let pendingSave = false;
2783
+ const debouncedSave = async () => {
2784
+ pendingSave = true;
2785
+ if (saveTimer) clearTimeout(saveTimer);
2786
+ saveTimer = setTimeout(async () => {
2787
+ if (pendingSave) {
2788
+ await adapter.saveState(engine.getContext());
2789
+ pendingSave = false;
2790
+ }
2791
+ }, saveInterval);
2792
+ };
2793
+ cleanupFns.push(() => {
2794
+ if (saveTimer) clearTimeout(saveTimer);
2795
+ });
2796
+ void debouncedSave;
2797
+ }
2798
+ return () => {
2799
+ cleanupFns.forEach((fn) => fn());
2800
+ };
2801
+ }
2802
+ function generateTauriConfig(config) {
2803
+ return {
2804
+ $schema: "https://raw.githubusercontent.com/tauri-apps/tauri/tauri-v2.0.0/core/tauri-config-schema/schema.json",
2805
+ productName: config.name,
2806
+ version: config.version,
2807
+ identifier: config.identifier,
2808
+ app: {
2809
+ windows: [
2810
+ {
2811
+ title: config.window?.title || config.name,
2812
+ width: config.window?.width || 800,
2813
+ height: config.window?.height || 600,
2814
+ minWidth: config.window?.minWidth,
2815
+ minHeight: config.window?.minHeight,
2816
+ resizable: config.window?.resizable ?? true,
2817
+ fullscreen: config.window?.fullscreen ?? false,
2818
+ decorations: config.window?.decorations ?? true,
2819
+ transparent: config.window?.transparent ?? false,
2820
+ alwaysOnTop: config.window?.alwaysOnTop ?? false,
2821
+ center: config.window?.center ?? true
2822
+ }
2823
+ ],
2824
+ security: {
2825
+ csp: config.security?.csp || "default-src 'self'",
2826
+ devtools: config.security?.devTools ?? false
2827
+ }
2828
+ },
2829
+ build: {
2830
+ devUrl: "http://localhost:5173",
2831
+ frontendDist: "../dist"
2832
+ },
2833
+ plugins: Object.fromEntries((config.plugins || []).map((p) => [p.name, p.config || {}]))
2834
+ };
2835
+ }
2836
+ export {
2837
+ ActorManager,
2838
+ InMemoryPraxisDB,
2839
+ LogicEngine,
2840
+ PRAXIS_PATHS,
2841
+ PRAXIS_PROTOCOL_VERSION,
2842
+ PluresDBGenerator,
2843
+ PraxisDBStore,
2844
+ PraxisRegistry,
2845
+ PraxisSchemaRegistry,
2846
+ ReactiveLogicEngine,
2847
+ RegistryIntrospector,
2848
+ StateDocsGenerator,
2849
+ attachTauriToEngine,
2850
+ attachToEngine,
2851
+ attachUnumToEngine,
2852
+ canvasToMermaid,
2853
+ canvasToSchema,
2854
+ canvasToYaml,
2855
+ createCanvasEditor,
2856
+ createInMemoryDB,
2857
+ createIntrospector,
2858
+ createMockTauriBridge,
2859
+ createPluresDBAdapter,
2860
+ createPluresDBGenerator,
2861
+ createPraxisDBStore,
2862
+ createPraxisEngine,
2863
+ createSchema,
2864
+ createSchemaRegistry,
2865
+ createSchemaTemplate,
2866
+ createStateDocsGenerator,
2867
+ createTauriPraxisAdapter,
2868
+ createTimerActor,
2869
+ createUnumAdapter,
2870
+ defineConstraint,
2871
+ defineEvent,
2872
+ defineFact,
2873
+ defineModule,
2874
+ defineRule,
2875
+ filterEvents,
2876
+ filterFacts,
2877
+ findEvent,
2878
+ findFact,
2879
+ generateDocs,
2880
+ generateId,
2881
+ generateTauriConfig,
2882
+ getEventPath,
2883
+ getFactPath,
2884
+ getSchemaPath,
2885
+ loadSchemaFromJson,
2886
+ loadSchemaFromYaml,
2887
+ registerSchema,
2888
+ schemaToCanvas,
2889
+ validateForGeneration,
2890
+ validateSchema,
2891
+ validateWithGuardian
2892
+ };