@plures/praxis 0.2.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/README.md +191 -64
  2. package/core/codegen/docs-generator.ts +808 -0
  3. package/core/codegen/index.ts +27 -0
  4. package/core/codegen/ts-generator.ts +15 -0
  5. package/core/db-adapter/index.ts +52 -0
  6. package/core/db-adapter/sync-engine.ts +450 -0
  7. package/core/logic-engine/engine.ts +12 -0
  8. package/core/logic-engine/index.ts +16 -0
  9. package/core/logic-engine/protocol.ts +16 -0
  10. package/core/logic-engine/psf-adapter.ts +269 -0
  11. package/core/logic-engine/rules.ts +16 -0
  12. package/core/schema-engine/compiler.ts +431 -0
  13. package/core/schema-engine/generator.ts +635 -0
  14. package/core/schema-engine/index.ts +18 -0
  15. package/core/schema-engine/psf.ts +664 -0
  16. package/core/schema-engine/types.ts +63 -0
  17. package/core/schema-engine/validator.ts +541 -0
  18. package/dist/core/codegen/docs-generator.d.ts +123 -0
  19. package/dist/core/codegen/docs-generator.d.ts.map +1 -0
  20. package/dist/core/codegen/docs-generator.js +674 -0
  21. package/dist/core/codegen/docs-generator.js.map +1 -0
  22. package/dist/core/codegen/index.d.ts +11 -0
  23. package/dist/core/codegen/index.d.ts.map +1 -0
  24. package/dist/core/codegen/index.js +13 -0
  25. package/dist/core/codegen/index.js.map +1 -0
  26. package/dist/core/codegen/ts-generator.d.ts +8 -0
  27. package/dist/core/codegen/ts-generator.d.ts.map +1 -0
  28. package/dist/core/codegen/ts-generator.js +8 -0
  29. package/dist/core/codegen/ts-generator.js.map +1 -0
  30. package/dist/core/db-adapter/index.d.ts +18 -0
  31. package/dist/core/db-adapter/index.d.ts.map +1 -0
  32. package/dist/core/db-adapter/index.js +23 -0
  33. package/dist/core/db-adapter/index.js.map +1 -0
  34. package/dist/core/db-adapter/sync-engine.d.ts +180 -0
  35. package/dist/core/db-adapter/sync-engine.d.ts.map +1 -0
  36. package/dist/core/db-adapter/sync-engine.js +342 -0
  37. package/dist/core/db-adapter/sync-engine.js.map +1 -0
  38. package/dist/core/logic-engine/engine.d.ts +8 -0
  39. package/dist/core/logic-engine/engine.d.ts.map +1 -0
  40. package/dist/core/logic-engine/engine.js +8 -0
  41. package/dist/core/logic-engine/engine.js.map +1 -0
  42. package/dist/core/logic-engine/index.d.ts +16 -0
  43. package/dist/core/logic-engine/index.d.ts.map +1 -0
  44. package/dist/core/logic-engine/index.js +16 -0
  45. package/dist/core/logic-engine/index.js.map +1 -0
  46. package/dist/core/logic-engine/protocol.d.ts +7 -0
  47. package/dist/core/logic-engine/protocol.d.ts.map +1 -0
  48. package/dist/core/logic-engine/protocol.js +7 -0
  49. package/dist/core/logic-engine/protocol.js.map +1 -0
  50. package/dist/core/logic-engine/psf-adapter.d.ts +88 -0
  51. package/dist/core/logic-engine/psf-adapter.d.ts.map +1 -0
  52. package/dist/core/logic-engine/psf-adapter.js +207 -0
  53. package/dist/core/logic-engine/psf-adapter.js.map +1 -0
  54. package/dist/core/logic-engine/rules.d.ts +7 -0
  55. package/dist/core/logic-engine/rules.d.ts.map +1 -0
  56. package/dist/core/logic-engine/rules.js +7 -0
  57. package/dist/core/logic-engine/rules.js.map +1 -0
  58. package/dist/core/schema-engine/compiler.d.ts +198 -0
  59. package/dist/core/schema-engine/compiler.d.ts.map +1 -0
  60. package/dist/core/schema-engine/compiler.js +262 -0
  61. package/dist/core/schema-engine/compiler.js.map +1 -0
  62. package/dist/core/schema-engine/generator.d.ts +115 -0
  63. package/dist/core/schema-engine/generator.d.ts.map +1 -0
  64. package/dist/core/schema-engine/generator.js +506 -0
  65. package/dist/core/schema-engine/generator.js.map +1 -0
  66. package/dist/core/schema-engine/index.d.ts +18 -0
  67. package/dist/core/schema-engine/index.d.ts.map +1 -0
  68. package/dist/core/schema-engine/index.js +18 -0
  69. package/dist/core/schema-engine/index.js.map +1 -0
  70. package/dist/core/schema-engine/psf.d.ts +612 -0
  71. package/dist/core/schema-engine/psf.d.ts.map +1 -0
  72. package/dist/core/schema-engine/psf.js +45 -0
  73. package/dist/core/schema-engine/psf.js.map +1 -0
  74. package/dist/core/schema-engine/types.d.ts +10 -0
  75. package/dist/core/schema-engine/types.d.ts.map +1 -0
  76. package/dist/core/schema-engine/types.js +7 -0
  77. package/dist/core/schema-engine/types.js.map +1 -0
  78. package/dist/core/schema-engine/validator.d.ts +140 -0
  79. package/dist/core/schema-engine/validator.d.ts.map +1 -0
  80. package/dist/core/schema-engine/validator.js +407 -0
  81. package/dist/core/schema-engine/validator.js.map +1 -0
  82. package/dist/src/adapters/cli.d.ts.map +1 -0
  83. package/dist/src/adapters/cli.js.map +1 -0
  84. package/dist/src/cli/commands/auth.d.ts.map +1 -0
  85. package/dist/src/cli/commands/auth.js.map +1 -0
  86. package/dist/src/cli/commands/build.d.ts +23 -0
  87. package/dist/src/cli/commands/build.d.ts.map +1 -0
  88. package/dist/src/cli/commands/build.js +162 -0
  89. package/dist/src/cli/commands/build.js.map +1 -0
  90. package/dist/src/cli/commands/canvas.d.ts +23 -0
  91. package/dist/src/cli/commands/canvas.d.ts.map +1 -0
  92. package/dist/src/cli/commands/canvas.js +215 -0
  93. package/dist/src/cli/commands/canvas.js.map +1 -0
  94. package/dist/src/cli/commands/cloud.d.ts.map +1 -0
  95. package/dist/src/cli/commands/cloud.js.map +1 -0
  96. package/dist/src/cli/commands/create.d.ts +21 -0
  97. package/dist/src/cli/commands/create.d.ts.map +1 -0
  98. package/dist/src/cli/commands/create.js +621 -0
  99. package/dist/src/cli/commands/create.js.map +1 -0
  100. package/dist/src/cli/commands/dev.d.ts +21 -0
  101. package/dist/src/cli/commands/dev.d.ts.map +1 -0
  102. package/dist/src/cli/commands/dev.js +71 -0
  103. package/dist/src/cli/commands/dev.js.map +1 -0
  104. package/dist/src/cli/commands/generate.d.ts.map +1 -0
  105. package/dist/src/cli/commands/generate.js.map +1 -0
  106. package/dist/src/cli/commands/orchestrate.d.ts +44 -0
  107. package/dist/src/cli/commands/orchestrate.d.ts.map +1 -0
  108. package/dist/src/cli/commands/orchestrate.js +150 -0
  109. package/dist/src/cli/commands/orchestrate.js.map +1 -0
  110. package/dist/{cli → src/cli}/index.d.ts.map +1 -1
  111. package/dist/{cli → src/cli}/index.js +53 -21
  112. package/dist/src/cli/index.js.map +1 -0
  113. package/dist/src/cloud/auth.d.ts.map +1 -0
  114. package/dist/src/cloud/auth.js.map +1 -0
  115. package/dist/src/cloud/billing.d.ts.map +1 -0
  116. package/dist/src/cloud/billing.js.map +1 -0
  117. package/dist/src/cloud/client.d.ts.map +1 -0
  118. package/dist/src/cloud/client.js.map +1 -0
  119. package/dist/src/cloud/index.d.ts.map +1 -0
  120. package/dist/src/cloud/index.js.map +1 -0
  121. package/dist/src/cloud/marketplace.d.ts.map +1 -0
  122. package/dist/src/cloud/marketplace.js.map +1 -0
  123. package/dist/src/cloud/provisioning.d.ts.map +1 -0
  124. package/dist/src/cloud/provisioning.js.map +1 -0
  125. package/dist/src/cloud/relay/endpoints.d.ts.map +1 -0
  126. package/dist/src/cloud/relay/endpoints.js.map +1 -0
  127. package/dist/src/cloud/relay/health/index.d.ts.map +1 -0
  128. package/dist/src/cloud/relay/health/index.js.map +1 -0
  129. package/dist/src/cloud/relay/stats/index.d.ts.map +1 -0
  130. package/dist/src/cloud/relay/stats/index.js.map +1 -0
  131. package/dist/src/cloud/relay/sync/index.d.ts.map +1 -0
  132. package/dist/src/cloud/relay/sync/index.js.map +1 -0
  133. package/dist/src/cloud/relay/usage/index.d.ts.map +1 -0
  134. package/dist/src/cloud/relay/usage/index.js.map +1 -0
  135. package/dist/src/cloud/sponsors.d.ts.map +1 -0
  136. package/dist/src/cloud/sponsors.js.map +1 -0
  137. package/dist/src/cloud/types.d.ts.map +1 -0
  138. package/dist/src/cloud/types.js.map +1 -0
  139. package/dist/src/components/index.d.ts.map +1 -0
  140. package/dist/src/components/index.js.map +1 -0
  141. package/dist/src/core/actors.d.ts.map +1 -0
  142. package/dist/src/core/actors.js.map +1 -0
  143. package/dist/src/core/component/generator.d.ts.map +1 -0
  144. package/dist/{core → src/core}/component/generator.js +45 -3
  145. package/dist/src/core/component/generator.js.map +1 -0
  146. package/dist/src/core/engine.d.ts.map +1 -0
  147. package/dist/src/core/engine.js.map +1 -0
  148. package/dist/src/core/introspection.d.ts.map +1 -0
  149. package/dist/src/core/introspection.js.map +1 -0
  150. package/dist/src/core/logic/generator.d.ts.map +1 -0
  151. package/dist/{core → src/core}/logic/generator.js +35 -4
  152. package/dist/src/core/logic/generator.js.map +1 -0
  153. package/dist/src/core/pluresdb/adapter.d.ts +72 -0
  154. package/dist/src/core/pluresdb/adapter.d.ts.map +1 -0
  155. package/dist/src/core/pluresdb/adapter.js +73 -0
  156. package/dist/src/core/pluresdb/adapter.js.map +1 -0
  157. package/dist/src/core/pluresdb/generator.d.ts.map +1 -0
  158. package/dist/{core → src/core}/pluresdb/generator.js +33 -4
  159. package/dist/src/core/pluresdb/generator.js.map +1 -0
  160. package/dist/src/core/pluresdb/index.d.ts +15 -0
  161. package/dist/src/core/pluresdb/index.d.ts.map +1 -0
  162. package/dist/src/core/pluresdb/index.js +11 -0
  163. package/dist/src/core/pluresdb/index.js.map +1 -0
  164. package/dist/src/core/pluresdb/schema-registry.d.ts +104 -0
  165. package/dist/src/core/pluresdb/schema-registry.d.ts.map +1 -0
  166. package/dist/src/core/pluresdb/schema-registry.js +130 -0
  167. package/dist/src/core/pluresdb/schema-registry.js.map +1 -0
  168. package/dist/src/core/pluresdb/store.d.ts +199 -0
  169. package/dist/src/core/pluresdb/store.d.ts.map +1 -0
  170. package/dist/src/core/pluresdb/store.js +344 -0
  171. package/dist/src/core/pluresdb/store.js.map +1 -0
  172. package/dist/src/core/protocol.d.ts.map +1 -0
  173. package/dist/src/core/protocol.js.map +1 -0
  174. package/dist/src/core/rules.d.ts.map +1 -0
  175. package/dist/src/core/rules.js.map +1 -0
  176. package/dist/src/core/schema/loader.d.ts.map +1 -0
  177. package/dist/src/core/schema/loader.js.map +1 -0
  178. package/dist/src/core/schema/normalize.d.ts.map +1 -0
  179. package/dist/src/core/schema/normalize.js.map +1 -0
  180. package/dist/src/core/schema/types.d.ts.map +1 -0
  181. package/dist/src/core/schema/types.js.map +1 -0
  182. package/dist/src/dsl/index.d.ts.map +1 -0
  183. package/dist/src/dsl/index.js.map +1 -0
  184. package/dist/src/dsl.d.ts.map +1 -0
  185. package/dist/src/dsl.js.map +1 -0
  186. package/dist/src/examples/advanced-todo/index.d.ts.map +1 -0
  187. package/dist/src/examples/advanced-todo/index.js.map +1 -0
  188. package/dist/src/examples/auth-basic/index.d.ts.map +1 -0
  189. package/dist/src/examples/auth-basic/index.js.map +1 -0
  190. package/dist/src/examples/cart/index.d.ts.map +1 -0
  191. package/dist/src/examples/cart/index.js.map +1 -0
  192. package/dist/src/examples/hero-ecommerce/index.d.ts.map +1 -0
  193. package/dist/src/examples/hero-ecommerce/index.js.map +1 -0
  194. package/dist/src/examples/svelte-counter/index.d.ts.map +1 -0
  195. package/dist/src/examples/svelte-counter/index.js.map +1 -0
  196. package/dist/src/flows.d.ts.map +1 -0
  197. package/dist/src/flows.js.map +1 -0
  198. package/dist/{index.d.ts → src/index.d.ts} +12 -2
  199. package/dist/src/index.d.ts.map +1 -0
  200. package/dist/{index.js → src/index.js} +6 -1
  201. package/dist/src/index.js.map +1 -0
  202. package/dist/src/integrations/code-canvas.d.ts +265 -0
  203. package/dist/src/integrations/code-canvas.d.ts.map +1 -0
  204. package/dist/src/integrations/code-canvas.js +451 -0
  205. package/dist/src/integrations/code-canvas.js.map +1 -0
  206. package/dist/src/integrations/pluresdb.d.ts +117 -0
  207. package/dist/src/integrations/pluresdb.d.ts.map +1 -0
  208. package/dist/src/integrations/pluresdb.js +117 -0
  209. package/dist/src/integrations/pluresdb.js.map +1 -0
  210. package/dist/src/integrations/state-docs.d.ts +191 -0
  211. package/dist/src/integrations/state-docs.d.ts.map +1 -0
  212. package/dist/src/integrations/state-docs.js +515 -0
  213. package/dist/src/integrations/state-docs.js.map +1 -0
  214. package/dist/src/integrations/svelte.d.ts.map +1 -0
  215. package/dist/src/integrations/svelte.js.map +1 -0
  216. package/dist/src/integrations/tauri.d.ts +360 -0
  217. package/dist/src/integrations/tauri.d.ts.map +1 -0
  218. package/dist/src/integrations/tauri.js +278 -0
  219. package/dist/src/integrations/tauri.js.map +1 -0
  220. package/dist/src/integrations/unum.d.ts +159 -0
  221. package/dist/src/integrations/unum.d.ts.map +1 -0
  222. package/dist/src/integrations/unum.js +240 -0
  223. package/dist/src/integrations/unum.js.map +1 -0
  224. package/dist/src/registry.d.ts.map +1 -0
  225. package/dist/src/registry.js.map +1 -0
  226. package/dist/{runtime → src/runtime}/terminal-adapter.d.ts +58 -7
  227. package/dist/src/runtime/terminal-adapter.d.ts.map +1 -0
  228. package/dist/src/runtime/terminal-adapter.js +239 -0
  229. package/dist/src/runtime/terminal-adapter.js.map +1 -0
  230. package/dist/src/step.d.ts.map +1 -0
  231. package/dist/src/step.js.map +1 -0
  232. package/dist/src/types.d.ts.map +1 -0
  233. package/dist/{cloud → src}/types.js.map +1 -1
  234. package/dist/tools/cli/commands/index.d.ts +7 -0
  235. package/dist/tools/cli/commands/index.d.ts.map +1 -0
  236. package/dist/tools/cli/commands/index.js +7 -0
  237. package/dist/tools/cli/commands/index.js.map +1 -0
  238. package/dist/tools/cli/index.d.ts +8 -0
  239. package/dist/tools/cli/index.d.ts.map +1 -0
  240. package/dist/tools/cli/index.js +9 -0
  241. package/dist/tools/cli/index.js.map +1 -0
  242. package/dist/tools/watcher/index.d.ts +105 -0
  243. package/dist/tools/watcher/index.d.ts.map +1 -0
  244. package/dist/tools/watcher/index.js +213 -0
  245. package/dist/tools/watcher/index.js.map +1 -0
  246. package/dist/ui/canvas/canvas-projection.d.ts +78 -0
  247. package/dist/ui/canvas/canvas-projection.d.ts.map +1 -0
  248. package/dist/ui/canvas/canvas-projection.js +416 -0
  249. package/dist/ui/canvas/canvas-projection.js.map +1 -0
  250. package/dist/ui/canvas/canvas-state.d.ts +200 -0
  251. package/dist/ui/canvas/canvas-state.d.ts.map +1 -0
  252. package/dist/ui/canvas/canvas-state.js +464 -0
  253. package/dist/ui/canvas/canvas-state.js.map +1 -0
  254. package/dist/ui/canvas/components/index.d.ts +95 -0
  255. package/dist/ui/canvas/components/index.d.ts.map +1 -0
  256. package/dist/ui/canvas/components/index.js +19 -0
  257. package/dist/ui/canvas/components/index.js.map +1 -0
  258. package/dist/ui/canvas/index.d.ts +32 -0
  259. package/dist/ui/canvas/index.d.ts.map +1 -0
  260. package/dist/ui/canvas/index.js +32 -0
  261. package/dist/ui/canvas/index.js.map +1 -0
  262. package/dist/ui/svelte-generator/index.d.ts +9 -0
  263. package/dist/ui/svelte-generator/index.d.ts.map +1 -0
  264. package/dist/ui/svelte-generator/index.js +11 -0
  265. package/dist/ui/svelte-generator/index.js.map +1 -0
  266. package/dist/ui/svelte-generator/psf-generator.d.ts +128 -0
  267. package/dist/ui/svelte-generator/psf-generator.d.ts.map +1 -0
  268. package/dist/ui/svelte-generator/psf-generator.js +506 -0
  269. package/dist/ui/svelte-generator/psf-generator.js.map +1 -0
  270. package/docs/README.md +155 -0
  271. package/docs/core/building-extensions.md +553 -0
  272. package/docs/core/cli-usage.md +498 -0
  273. package/docs/core/code-canvas-sync.md +468 -0
  274. package/docs/core/logic-engine.md +566 -0
  275. package/docs/core/pluresdb-integration.md +646 -0
  276. package/docs/core/schema-model.md +414 -0
  277. package/docs/core/ui-generation.md +580 -0
  278. package/docs/core/what-is-praxis.md +240 -0
  279. package/docs/tutorials/README.md +84 -0
  280. package/docs/tutorials/ecommerce-cart.md +631 -0
  281. package/docs/tutorials/first-app.md +529 -0
  282. package/docs/tutorials/form-builder.md +620 -0
  283. package/docs/tutorials/todo-pluresdb.md +589 -0
  284. package/package.json +16 -16
  285. package/src/__tests__/canvas-components.test.ts +450 -0
  286. package/src/__tests__/cli-create.test.ts +178 -0
  287. package/src/__tests__/code-canvas-integration.test.ts +277 -0
  288. package/src/__tests__/docs-generator.test.ts +181 -0
  289. package/src/__tests__/generators.test.ts +3 -2
  290. package/src/__tests__/pluresdb.test.ts +457 -0
  291. package/src/__tests__/psf-schema-engine.test.ts +450 -0
  292. package/src/__tests__/state-docs-integration.test.ts +297 -0
  293. package/src/__tests__/tauri-integration.test.ts +298 -0
  294. package/src/__tests__/terminal-node.test.ts +1 -1
  295. package/src/__tests__/unum-integration.test.ts +142 -0
  296. package/src/cli/commands/build.ts +203 -0
  297. package/src/cli/commands/canvas.ts +246 -0
  298. package/src/cli/commands/create.ts +666 -0
  299. package/src/cli/commands/dev.ts +95 -0
  300. package/src/cli/commands/orchestrate.ts +212 -0
  301. package/src/cli/index.ts +48 -21
  302. package/src/core/component/generator.ts +45 -3
  303. package/src/core/logic/generator.ts +39 -4
  304. package/src/core/pluresdb/adapter.ts +117 -0
  305. package/src/core/pluresdb/generator.ts +33 -4
  306. package/src/core/pluresdb/index.ts +37 -0
  307. package/src/core/pluresdb/schema-registry.ts +162 -0
  308. package/src/core/pluresdb/store.ts +446 -0
  309. package/src/index.ts +109 -0
  310. package/src/integrations/code-canvas.ts +717 -0
  311. package/src/integrations/pluresdb.ts +140 -29
  312. package/src/integrations/state-docs.ts +710 -0
  313. package/src/integrations/tauri.ts +638 -0
  314. package/src/integrations/unum.ts +395 -0
  315. package/src/runtime/terminal-adapter.ts +184 -23
  316. package/dist/adapters/cli.d.ts.map +0 -1
  317. package/dist/adapters/cli.js.map +0 -1
  318. package/dist/cli/commands/auth.d.ts.map +0 -1
  319. package/dist/cli/commands/auth.js.map +0 -1
  320. package/dist/cli/commands/cloud.d.ts.map +0 -1
  321. package/dist/cli/commands/cloud.js.map +0 -1
  322. package/dist/cli/commands/generate.d.ts.map +0 -1
  323. package/dist/cli/commands/generate.js.map +0 -1
  324. package/dist/cli/index.js.map +0 -1
  325. package/dist/cloud/auth.d.ts.map +0 -1
  326. package/dist/cloud/auth.js.map +0 -1
  327. package/dist/cloud/billing.d.ts.map +0 -1
  328. package/dist/cloud/billing.js.map +0 -1
  329. package/dist/cloud/client.d.ts.map +0 -1
  330. package/dist/cloud/client.js.map +0 -1
  331. package/dist/cloud/index.d.ts.map +0 -1
  332. package/dist/cloud/index.js.map +0 -1
  333. package/dist/cloud/marketplace.d.ts.map +0 -1
  334. package/dist/cloud/marketplace.js.map +0 -1
  335. package/dist/cloud/provisioning.d.ts.map +0 -1
  336. package/dist/cloud/provisioning.js.map +0 -1
  337. package/dist/cloud/relay/endpoints.d.ts.map +0 -1
  338. package/dist/cloud/relay/endpoints.js.map +0 -1
  339. package/dist/cloud/relay/health/index.d.ts.map +0 -1
  340. package/dist/cloud/relay/health/index.js.map +0 -1
  341. package/dist/cloud/relay/stats/index.d.ts.map +0 -1
  342. package/dist/cloud/relay/stats/index.js.map +0 -1
  343. package/dist/cloud/relay/sync/index.d.ts.map +0 -1
  344. package/dist/cloud/relay/sync/index.js.map +0 -1
  345. package/dist/cloud/relay/usage/index.d.ts.map +0 -1
  346. package/dist/cloud/relay/usage/index.js.map +0 -1
  347. package/dist/cloud/sponsors.d.ts.map +0 -1
  348. package/dist/cloud/sponsors.js.map +0 -1
  349. package/dist/cloud/types.d.ts.map +0 -1
  350. package/dist/components/index.d.ts.map +0 -1
  351. package/dist/components/index.js.map +0 -1
  352. package/dist/core/actors.d.ts.map +0 -1
  353. package/dist/core/actors.js.map +0 -1
  354. package/dist/core/component/generator.d.ts.map +0 -1
  355. package/dist/core/component/generator.js.map +0 -1
  356. package/dist/core/engine.d.ts.map +0 -1
  357. package/dist/core/engine.js.map +0 -1
  358. package/dist/core/introspection.d.ts.map +0 -1
  359. package/dist/core/introspection.js.map +0 -1
  360. package/dist/core/logic/generator.d.ts.map +0 -1
  361. package/dist/core/logic/generator.js.map +0 -1
  362. package/dist/core/pluresdb/generator.d.ts.map +0 -1
  363. package/dist/core/pluresdb/generator.js.map +0 -1
  364. package/dist/core/protocol.d.ts.map +0 -1
  365. package/dist/core/protocol.js.map +0 -1
  366. package/dist/core/rules.d.ts.map +0 -1
  367. package/dist/core/rules.js.map +0 -1
  368. package/dist/core/schema/loader.d.ts.map +0 -1
  369. package/dist/core/schema/loader.js.map +0 -1
  370. package/dist/core/schema/normalize.d.ts.map +0 -1
  371. package/dist/core/schema/normalize.js.map +0 -1
  372. package/dist/core/schema/types.d.ts.map +0 -1
  373. package/dist/core/schema/types.js.map +0 -1
  374. package/dist/dsl/index.d.ts.map +0 -1
  375. package/dist/dsl/index.js.map +0 -1
  376. package/dist/dsl.d.ts.map +0 -1
  377. package/dist/dsl.js.map +0 -1
  378. package/dist/examples/advanced-todo/index.d.ts.map +0 -1
  379. package/dist/examples/advanced-todo/index.js.map +0 -1
  380. package/dist/examples/auth-basic/index.d.ts.map +0 -1
  381. package/dist/examples/auth-basic/index.js.map +0 -1
  382. package/dist/examples/cart/index.d.ts.map +0 -1
  383. package/dist/examples/cart/index.js.map +0 -1
  384. package/dist/examples/hero-ecommerce/index.d.ts.map +0 -1
  385. package/dist/examples/hero-ecommerce/index.js.map +0 -1
  386. package/dist/examples/svelte-counter/index.d.ts.map +0 -1
  387. package/dist/examples/svelte-counter/index.js.map +0 -1
  388. package/dist/flows.d.ts.map +0 -1
  389. package/dist/flows.js.map +0 -1
  390. package/dist/index.d.ts.map +0 -1
  391. package/dist/index.js.map +0 -1
  392. package/dist/integrations/pluresdb.d.ts +0 -56
  393. package/dist/integrations/pluresdb.d.ts.map +0 -1
  394. package/dist/integrations/pluresdb.js +0 -46
  395. package/dist/integrations/pluresdb.js.map +0 -1
  396. package/dist/integrations/svelte.d.ts.map +0 -1
  397. package/dist/integrations/svelte.js.map +0 -1
  398. package/dist/registry.d.ts.map +0 -1
  399. package/dist/registry.js.map +0 -1
  400. package/dist/runtime/terminal-adapter.d.ts.map +0 -1
  401. package/dist/runtime/terminal-adapter.js +0 -113
  402. package/dist/runtime/terminal-adapter.js.map +0 -1
  403. package/dist/step.d.ts.map +0 -1
  404. package/dist/step.js.map +0 -1
  405. package/dist/types.d.ts.map +0 -1
  406. package/dist/types.js.map +0 -1
  407. /package/dist/{adapters → src/adapters}/cli.d.ts +0 -0
  408. /package/dist/{adapters → src/adapters}/cli.js +0 -0
  409. /package/dist/{cli → src/cli}/commands/auth.d.ts +0 -0
  410. /package/dist/{cli → src/cli}/commands/auth.js +0 -0
  411. /package/dist/{cli → src/cli}/commands/cloud.d.ts +0 -0
  412. /package/dist/{cli → src/cli}/commands/cloud.js +0 -0
  413. /package/dist/{cli → src/cli}/commands/generate.d.ts +0 -0
  414. /package/dist/{cli → src/cli}/commands/generate.js +0 -0
  415. /package/dist/{cli → src/cli}/index.d.ts +0 -0
  416. /package/dist/{cloud → src/cloud}/auth.d.ts +0 -0
  417. /package/dist/{cloud → src/cloud}/auth.js +0 -0
  418. /package/dist/{cloud → src/cloud}/billing.d.ts +0 -0
  419. /package/dist/{cloud → src/cloud}/billing.js +0 -0
  420. /package/dist/{cloud → src/cloud}/client.d.ts +0 -0
  421. /package/dist/{cloud → src/cloud}/client.js +0 -0
  422. /package/dist/{cloud → src/cloud}/index.d.ts +0 -0
  423. /package/dist/{cloud → src/cloud}/index.js +0 -0
  424. /package/dist/{cloud → src/cloud}/marketplace.d.ts +0 -0
  425. /package/dist/{cloud → src/cloud}/marketplace.js +0 -0
  426. /package/dist/{cloud → src/cloud}/provisioning.d.ts +0 -0
  427. /package/dist/{cloud → src/cloud}/provisioning.js +0 -0
  428. /package/dist/{cloud → src/cloud}/relay/endpoints.d.ts +0 -0
  429. /package/dist/{cloud → src/cloud}/relay/endpoints.js +0 -0
  430. /package/dist/{cloud → src/cloud}/relay/health/index.d.ts +0 -0
  431. /package/dist/{cloud → src/cloud}/relay/health/index.js +0 -0
  432. /package/dist/{cloud → src/cloud}/relay/stats/index.d.ts +0 -0
  433. /package/dist/{cloud → src/cloud}/relay/stats/index.js +0 -0
  434. /package/dist/{cloud → src/cloud}/relay/sync/index.d.ts +0 -0
  435. /package/dist/{cloud → src/cloud}/relay/sync/index.js +0 -0
  436. /package/dist/{cloud → src/cloud}/relay/usage/index.d.ts +0 -0
  437. /package/dist/{cloud → src/cloud}/relay/usage/index.js +0 -0
  438. /package/dist/{cloud → src/cloud}/sponsors.d.ts +0 -0
  439. /package/dist/{cloud → src/cloud}/sponsors.js +0 -0
  440. /package/dist/{cloud → src/cloud}/types.d.ts +0 -0
  441. /package/dist/{cloud → src/cloud}/types.js +0 -0
  442. /package/dist/{components → src/components}/index.d.ts +0 -0
  443. /package/dist/{components → src/components}/index.js +0 -0
  444. /package/dist/{core → src/core}/actors.d.ts +0 -0
  445. /package/dist/{core → src/core}/actors.js +0 -0
  446. /package/dist/{core → src/core}/component/generator.d.ts +0 -0
  447. /package/dist/{core → src/core}/engine.d.ts +0 -0
  448. /package/dist/{core → src/core}/engine.js +0 -0
  449. /package/dist/{core → src/core}/introspection.d.ts +0 -0
  450. /package/dist/{core → src/core}/introspection.js +0 -0
  451. /package/dist/{core → src/core}/logic/generator.d.ts +0 -0
  452. /package/dist/{core → src/core}/pluresdb/generator.d.ts +0 -0
  453. /package/dist/{core → src/core}/protocol.d.ts +0 -0
  454. /package/dist/{core → src/core}/protocol.js +0 -0
  455. /package/dist/{core → src/core}/rules.d.ts +0 -0
  456. /package/dist/{core → src/core}/rules.js +0 -0
  457. /package/dist/{core → src/core}/schema/loader.d.ts +0 -0
  458. /package/dist/{core → src/core}/schema/loader.js +0 -0
  459. /package/dist/{core → src/core}/schema/normalize.d.ts +0 -0
  460. /package/dist/{core → src/core}/schema/normalize.js +0 -0
  461. /package/dist/{core → src/core}/schema/types.d.ts +0 -0
  462. /package/dist/{core → src/core}/schema/types.js +0 -0
  463. /package/dist/{dsl → src/dsl}/index.d.ts +0 -0
  464. /package/dist/{dsl → src/dsl}/index.js +0 -0
  465. /package/dist/{dsl.d.ts → src/dsl.d.ts} +0 -0
  466. /package/dist/{dsl.js → src/dsl.js} +0 -0
  467. /package/dist/{examples → src/examples}/advanced-todo/index.d.ts +0 -0
  468. /package/dist/{examples → src/examples}/advanced-todo/index.js +0 -0
  469. /package/dist/{examples → src/examples}/auth-basic/index.d.ts +0 -0
  470. /package/dist/{examples → src/examples}/auth-basic/index.js +0 -0
  471. /package/dist/{examples → src/examples}/cart/index.d.ts +0 -0
  472. /package/dist/{examples → src/examples}/cart/index.js +0 -0
  473. /package/dist/{examples → src/examples}/hero-ecommerce/index.d.ts +0 -0
  474. /package/dist/{examples → src/examples}/hero-ecommerce/index.js +0 -0
  475. /package/dist/{examples → src/examples}/svelte-counter/index.d.ts +0 -0
  476. /package/dist/{examples → src/examples}/svelte-counter/index.js +0 -0
  477. /package/dist/{flows.d.ts → src/flows.d.ts} +0 -0
  478. /package/dist/{flows.js → src/flows.js} +0 -0
  479. /package/dist/{integrations → src/integrations}/svelte.d.ts +0 -0
  480. /package/dist/{integrations → src/integrations}/svelte.js +0 -0
  481. /package/dist/{registry.d.ts → src/registry.d.ts} +0 -0
  482. /package/dist/{registry.js → src/registry.js} +0 -0
  483. /package/dist/{step.d.ts → src/step.d.ts} +0 -0
  484. /package/dist/{step.js → src/step.js} +0 -0
  485. /package/dist/{types.d.ts → src/types.d.ts} +0 -0
  486. /package/dist/{types.js → src/types.js} +0 -0
@@ -157,12 +157,41 @@ export class PluresDBGenerator {
157
157
  // Generate initialization function
158
158
  lines.push('/**');
159
159
  lines.push(' * Initialize PluresDB');
160
+ lines.push(' * @returns Configured PluresDB instance');
160
161
  lines.push(' */');
161
162
  lines.push('export function initDB() {');
162
- lines.push(' // TODO: Implement PluresDB initialization');
163
- lines.push(' // return createPluresDB(dbConfig);');
164
- lines.push(' console.log(\'PluresDB config ready:\', dbConfig);');
165
- lines.push(' return null;');
163
+ lines.push(' // Create and configure PluresDB instance');
164
+ lines.push(' const db = createInMemoryDB();');
165
+ lines.push(' ');
166
+ lines.push(' // Initialize stores based on configuration');
167
+ lines.push(' for (const storeDef of dbConfig.stores) {');
168
+ lines.push(' // Pre-create store paths');
169
+ lines.push(' db.set(`stores/${storeDef.name}/_meta`, {');
170
+ lines.push(' keyPath: storeDef.keyPath,');
171
+ lines.push(' indexes: storeDef.indexes,');
172
+ lines.push(' createdAt: Date.now(),');
173
+ lines.push(' });');
174
+ lines.push(' }');
175
+ lines.push(' ');
176
+ lines.push(' console.log(`PluresDB initialized: ${dbConfig.name}`);');
177
+ lines.push(' return db;');
178
+ lines.push('}');
179
+ lines.push('');
180
+ lines.push('/**');
181
+ lines.push(' * Get store by name');
182
+ lines.push(' */');
183
+ lines.push('export function getStore(db: ReturnType<typeof createInMemoryDB>, storeName: string) {');
184
+ lines.push(' const storeDef = dbConfig.stores.find(s => s.name === storeName);');
185
+ lines.push(' if (!storeDef) {');
186
+ lines.push(' throw new Error(`Store "${storeName}" not found in configuration`);');
187
+ lines.push(' }');
188
+ lines.push(' return {');
189
+ lines.push(' get: (key: string) => db.get(`stores/${storeName}/${key}`),');
190
+ lines.push(' set: (key: string, value: unknown) => db.set(`stores/${storeName}/${key}`, value),');
191
+ lines.push(' delete: (key: string) => db.delete(`stores/${storeName}/${key}`),');
192
+ lines.push(' watch: (key: string, callback: (data: unknown) => void) => ');
193
+ lines.push(' db.watch(`stores/${storeName}/${key}`, callback),');
194
+ lines.push(' };');
166
195
  lines.push('}');
167
196
 
168
197
  return {
@@ -0,0 +1,37 @@
1
+ /**
2
+ * PluresDB Integration Module
3
+ *
4
+ * This module exports all PluresDB-related types and functions for Praxis.
5
+ * It provides the core adapter layer, store, and schema registry.
6
+ */
7
+
8
+ // Adapter - Core interface and in-memory implementation
9
+ export type { PraxisDB, UnsubscribeFn } from "./adapter.js";
10
+ export { InMemoryPraxisDB, createInMemoryDB } from "./adapter.js";
11
+
12
+ // Store - Manages facts, events, and reactive updates
13
+ export type { EventStreamEntry, PraxisDBStoreOptions, RuleErrorHandler } from "./store.js";
14
+ export {
15
+ PraxisDBStore,
16
+ createPraxisDBStore,
17
+ PRAXIS_PATHS,
18
+ getFactPath,
19
+ getEventPath,
20
+ generateId,
21
+ } from "./store.js";
22
+
23
+ // Schema Registry - Schema definitions in PluresDB
24
+ export type { StoredSchema } from "./schema-registry.js";
25
+ export {
26
+ PraxisSchemaRegistry,
27
+ createSchemaRegistry,
28
+ registerSchema,
29
+ getSchemaPath,
30
+ } from "./schema-registry.js";
31
+
32
+ // Config Generator - Generate PluresDB config from schemas
33
+ export type {
34
+ PluresDBGeneratorOptions,
35
+ GeneratedPluresDBFile,
36
+ } from "./generator.js";
37
+ export { PluresDBGenerator, createPluresDBGenerator } from "./generator.js";
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Praxis Schema Registry for PluresDB
3
+ *
4
+ * Registers Praxis schema definitions in PluresDB for type-safe storage
5
+ * and cross-agent schema discovery.
6
+ */
7
+
8
+ import type { PraxisDB } from "./adapter.js";
9
+ import type { PraxisSchema } from "../schema/types.js";
10
+ import { PRAXIS_PATHS } from "./store.js";
11
+
12
+ /**
13
+ * Get the path for a schema in PluresDB
14
+ * @param schemaName The schema name
15
+ */
16
+ export function getSchemaPath(schemaName: string): string {
17
+ return `${PRAXIS_PATHS.SCHEMAS}/${schemaName}`;
18
+ }
19
+
20
+ /**
21
+ * Stored schema entry with metadata
22
+ */
23
+ export interface StoredSchema {
24
+ /** The schema definition */
25
+ schema: PraxisSchema;
26
+ /** When the schema was registered */
27
+ registeredAt: number;
28
+ /** Schema version */
29
+ version: string;
30
+ }
31
+
32
+ /**
33
+ * PraxisSchemaRegistry
34
+ *
35
+ * Manages schema definitions in PluresDB.
36
+ * Schemas are stored under `/_praxis/schemas/<schemaName>`
37
+ */
38
+ export class PraxisSchemaRegistry {
39
+ private db: PraxisDB;
40
+
41
+ constructor(db: PraxisDB) {
42
+ this.db = db;
43
+ }
44
+
45
+ /**
46
+ * Register a schema in PluresDB
47
+ *
48
+ * @param schema The schema to register
49
+ */
50
+ async register(schema: PraxisSchema): Promise<void> {
51
+ const path = getSchemaPath(schema.name);
52
+
53
+ const storedSchema: StoredSchema = {
54
+ schema,
55
+ registeredAt: Date.now(),
56
+ version: schema.version,
57
+ };
58
+
59
+ await this.db.set(path, storedSchema);
60
+ }
61
+
62
+ /**
63
+ * Get a schema by name
64
+ *
65
+ * @param schemaName The schema name
66
+ * @returns The stored schema or undefined if not found
67
+ */
68
+ async get(schemaName: string): Promise<StoredSchema | undefined> {
69
+ const path = getSchemaPath(schemaName);
70
+ return this.db.get<StoredSchema>(path);
71
+ }
72
+
73
+ /**
74
+ * Check if a schema is registered
75
+ *
76
+ * @param schemaName The schema name
77
+ * @returns True if the schema exists
78
+ */
79
+ async exists(schemaName: string): Promise<boolean> {
80
+ const stored = await this.get(schemaName);
81
+ return stored !== undefined;
82
+ }
83
+
84
+ /**
85
+ * Update a schema (replaces existing)
86
+ *
87
+ * @param schema The updated schema
88
+ */
89
+ async update(schema: PraxisSchema): Promise<void> {
90
+ await this.register(schema);
91
+ }
92
+
93
+ /**
94
+ * List all registered schema names
95
+ *
96
+ * Implementation note: This method uses an index stored at `/_praxis/schemas/_index`.
97
+ * When using InMemoryPraxisDB, schemas must be registered using `registerWithIndex()`
98
+ * for them to appear in this listing. When using a full PluresDB implementation,
99
+ * native listing capabilities should be used instead.
100
+ *
101
+ * @returns Array of registered schema names
102
+ */
103
+ async list(): Promise<string[]> {
104
+ const indexPath = `${PRAXIS_PATHS.SCHEMAS}/_index`;
105
+ const index = await this.db.get<string[]>(indexPath);
106
+ return index ?? [];
107
+ }
108
+
109
+ /**
110
+ * Register a schema and update the index
111
+ *
112
+ * @param schema The schema to register
113
+ */
114
+ async registerWithIndex(schema: PraxisSchema): Promise<void> {
115
+ // Register the schema
116
+ await this.register(schema);
117
+
118
+ // Update the index
119
+ const indexPath = `${PRAXIS_PATHS.SCHEMAS}/_index`;
120
+ const existingIndex = await this.db.get<string[]>(indexPath) ?? [];
121
+
122
+ if (!existingIndex.includes(schema.name)) {
123
+ await this.db.set(indexPath, [...existingIndex, schema.name]);
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Register a schema in PluresDB
130
+ *
131
+ * Convenience function for one-off schema registration.
132
+ *
133
+ * @param db The PraxisDB instance
134
+ * @param schema The schema to register
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const db = createInMemoryDB();
139
+ * await registerSchema(db, {
140
+ * version: "1.0.0",
141
+ * name: "MyApp",
142
+ * description: "My application schema"
143
+ * });
144
+ * ```
145
+ */
146
+ export async function registerSchema(
147
+ db: PraxisDB,
148
+ schema: PraxisSchema
149
+ ): Promise<void> {
150
+ const registry = new PraxisSchemaRegistry(db);
151
+ await registry.registerWithIndex(schema);
152
+ }
153
+
154
+ /**
155
+ * Create a PraxisSchemaRegistry instance
156
+ *
157
+ * @param db The PraxisDB instance
158
+ * @returns PraxisSchemaRegistry instance
159
+ */
160
+ export function createSchemaRegistry(db: PraxisDB): PraxisSchemaRegistry {
161
+ return new PraxisSchemaRegistry(db);
162
+ }
@@ -0,0 +1,446 @@
1
+ /**
2
+ * PraxisDB Store
3
+ *
4
+ * Connects Praxis Facts, Events, Rules, and Constraints to PluresDB.
5
+ * Provides CRDT-backed storage for facts and append-only event streams.
6
+ */
7
+
8
+ // Declare process for TypeScript in non-Node environments (e.g., Deno)
9
+ declare const process: { env: { [key: string]: string | undefined } } | undefined;
10
+
11
+ import type { PraxisDB, UnsubscribeFn } from "./adapter.js";
12
+ import type { PraxisRegistry } from "../rules.js";
13
+ import type { PraxisFact, PraxisEvent, PraxisState } from "../protocol.js";
14
+
15
+ /**
16
+ * Key paths for Praxis data in PluresDB
17
+ */
18
+ export const PRAXIS_PATHS = {
19
+ /** Base path for all Praxis data */
20
+ BASE: "/_praxis",
21
+ /** Path for facts storage */
22
+ FACTS: "/_praxis/facts",
23
+ /** Path for events storage */
24
+ EVENTS: "/_praxis/events",
25
+ /** Path for schema registry */
26
+ SCHEMAS: "/_praxis/schemas",
27
+ } as const;
28
+
29
+ /**
30
+ * Generate a fact key path
31
+ * @param factTag The fact type tag
32
+ * @param id Optional unique identifier for the fact instance
33
+ */
34
+ export function getFactPath(factTag: string, id?: string): string {
35
+ if (id) {
36
+ return `${PRAXIS_PATHS.FACTS}/${factTag}/${id}`;
37
+ }
38
+ return `${PRAXIS_PATHS.FACTS}/${factTag}`;
39
+ }
40
+
41
+ /**
42
+ * Generate an event stream key path
43
+ * @param eventTag The event type tag
44
+ */
45
+ export function getEventPath(eventTag: string): string {
46
+ return `${PRAXIS_PATHS.EVENTS}/${eventTag}`;
47
+ }
48
+
49
+ /**
50
+ * Generate a unique ID for facts or events
51
+ * Uses timestamp and random string for uniqueness
52
+ */
53
+ export function generateId(): string {
54
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
55
+ }
56
+
57
+ /**
58
+ * Event stream entry with timestamp
59
+ */
60
+ export interface EventStreamEntry {
61
+ /** The event data */
62
+ event: PraxisEvent;
63
+ /** Timestamp when the event was appended */
64
+ timestamp: number;
65
+ /** Optional sequence number */
66
+ sequence?: number;
67
+ }
68
+
69
+ /**
70
+ * Options for creating a PraxisDBStore
71
+ */
72
+ export interface PraxisDBStoreOptions<TContext = unknown> {
73
+ /** The PraxisDB instance to use */
74
+ db: PraxisDB;
75
+ /** The PraxisRegistry for rules and constraints */
76
+ registry: PraxisRegistry<TContext>;
77
+ /** Initial context for rule evaluation */
78
+ initialContext?: TContext;
79
+ }
80
+
81
+ /**
82
+ * PraxisDBStore
83
+ *
84
+ * Manages persistence and reactive updates for Praxis state in PluresDB.
85
+ *
86
+ * - Facts are stored as CRDT-backed documents under `/_praxis/facts/<factTag>/<id>`
87
+ * - Events are stored as append-only streams under `/_praxis/events/<eventTag>`
88
+ * - Rules are triggered automatically when watched keys change
89
+ * - Constraints are run before writing mutated state
90
+ */
91
+ /**
92
+ * Error handler callback for rule execution errors
93
+ */
94
+ export type RuleErrorHandler = (ruleId: string, error: unknown) => void;
95
+
96
+ /**
97
+ * Default error handler that logs to console
98
+ */
99
+ const defaultErrorHandler: RuleErrorHandler = (ruleId, error) => {
100
+ // Default behavior: silent in production, can be overridden
101
+ if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") {
102
+ console.error(`Error executing rule "${ruleId}":`, error);
103
+ }
104
+ };
105
+
106
+ export class PraxisDBStore<TContext = unknown> {
107
+ private db: PraxisDB;
108
+ private registry: PraxisRegistry<TContext>;
109
+ private context: TContext;
110
+ private subscriptions: UnsubscribeFn[] = [];
111
+ private factWatchers = new Map<string, Set<(facts: PraxisFact[]) => void>>();
112
+ private onRuleError: RuleErrorHandler;
113
+
114
+ constructor(options: PraxisDBStoreOptions<TContext> & { onRuleError?: RuleErrorHandler }) {
115
+ this.db = options.db;
116
+ this.registry = options.registry;
117
+ this.context = options.initialContext ?? ({} as TContext);
118
+ this.onRuleError = options.onRuleError ?? defaultErrorHandler;
119
+ }
120
+
121
+ /**
122
+ * Store a fact in PluresDB
123
+ *
124
+ * Facts are stored under `/_praxis/facts/<factTag>/<id>`
125
+ * If no id is provided in the payload, a timestamp-based id is used.
126
+ *
127
+ * @param fact The fact to store
128
+ * @returns Promise that resolves when the fact is stored
129
+ */
130
+ async storeFact(fact: PraxisFact): Promise<void> {
131
+ // Run constraints before storing
132
+ const constraintResult = await this.checkConstraints([fact]);
133
+ if (!constraintResult.valid) {
134
+ throw new Error(`Constraint violation: ${constraintResult.errors.join(", ")}`);
135
+ }
136
+
137
+ await this.persistFact(fact);
138
+
139
+ // Trigger rule evaluation - facts stored directly may trigger derived computations
140
+ await this.triggerRules([fact]);
141
+ }
142
+
143
+ /**
144
+ * Store multiple facts in PluresDB
145
+ *
146
+ * @param facts The facts to store
147
+ */
148
+ async storeFacts(facts: PraxisFact[]): Promise<void> {
149
+ // Run constraints before storing
150
+ const constraintResult = await this.checkConstraints(facts);
151
+ if (!constraintResult.valid) {
152
+ throw new Error(`Constraint violation: ${constraintResult.errors.join(", ")}`);
153
+ }
154
+
155
+ for (const fact of facts) {
156
+ await this.persistFact(fact);
157
+ }
158
+
159
+ // Trigger rule evaluation
160
+ await this.triggerRules(facts);
161
+ }
162
+
163
+ /**
164
+ * Internal method to persist a fact without constraint checking
165
+ * Used by both storeFact and derived fact storage
166
+ */
167
+ private async persistFact(fact: PraxisFact): Promise<void> {
168
+ const payload = fact.payload as Record<string, unknown> | undefined;
169
+ const id = (payload?.id as string) ?? generateId();
170
+ const path = getFactPath(fact.tag, id);
171
+ await this.db.set(path, fact);
172
+ }
173
+
174
+ /**
175
+ * Get a fact by tag and id
176
+ *
177
+ * @param factTag The fact type tag
178
+ * @param id The fact id
179
+ * @returns The fact or undefined if not found
180
+ */
181
+ async getFact(factTag: string, id: string): Promise<PraxisFact | undefined> {
182
+ const path = getFactPath(factTag, id);
183
+ return this.db.get<PraxisFact>(path);
184
+ }
185
+
186
+ /**
187
+ * Append an event to the event stream
188
+ *
189
+ * Events are stored as append-only streams under `/_praxis/events/<eventTag>`
190
+ *
191
+ * @param event The event to append
192
+ */
193
+ async appendEvent(event: PraxisEvent): Promise<void> {
194
+ const path = getEventPath(event.tag);
195
+
196
+ // Get existing events for this tag
197
+ const existingEvents = await this.db.get<EventStreamEntry[]>(path) ?? [];
198
+
199
+ // Create new entry
200
+ const entry: EventStreamEntry = {
201
+ event,
202
+ timestamp: Date.now(),
203
+ sequence: existingEvents.length,
204
+ };
205
+
206
+ // Append and store
207
+ const newEvents = [...existingEvents, entry];
208
+ await this.db.set(path, newEvents);
209
+
210
+ // Trigger rules with this event
211
+ await this.triggerRulesForEvents([event]);
212
+ }
213
+
214
+ /**
215
+ * Append multiple events to their respective streams
216
+ *
217
+ * @param events The events to append
218
+ */
219
+ async appendEvents(events: PraxisEvent[]): Promise<void> {
220
+ // Group events by tag for efficient storage
221
+ const eventsByTag = new Map<string, PraxisEvent[]>();
222
+ for (const event of events) {
223
+ const existing = eventsByTag.get(event.tag) ?? [];
224
+ eventsByTag.set(event.tag, [...existing, event]);
225
+ }
226
+
227
+ // Append each group
228
+ for (const [tag, tagEvents] of eventsByTag) {
229
+ const path = getEventPath(tag);
230
+ const existingEvents = await this.db.get<EventStreamEntry[]>(path) ?? [];
231
+ let sequence = existingEvents.length;
232
+
233
+ const newEntries = tagEvents.map(event => ({
234
+ event,
235
+ timestamp: Date.now(),
236
+ sequence: sequence++,
237
+ }));
238
+
239
+ await this.db.set(path, [...existingEvents, ...newEntries]);
240
+ }
241
+
242
+ // Trigger rules
243
+ await this.triggerRulesForEvents(events);
244
+ }
245
+
246
+ /**
247
+ * Get events from a stream
248
+ *
249
+ * @param eventTag The event type tag
250
+ * @param options Query options
251
+ * @returns Array of event stream entries
252
+ */
253
+ async getEvents(
254
+ eventTag: string,
255
+ options?: { since?: number; limit?: number }
256
+ ): Promise<EventStreamEntry[]> {
257
+ const path = getEventPath(eventTag);
258
+ const events = await this.db.get<EventStreamEntry[]>(path) ?? [];
259
+
260
+ let result = events;
261
+
262
+ if (options?.since !== undefined) {
263
+ const sinceTimestamp = options.since;
264
+ result = result.filter(e => e.timestamp > sinceTimestamp);
265
+ }
266
+
267
+ if (options?.limit !== undefined) {
268
+ result = result.slice(-options.limit);
269
+ }
270
+
271
+ return result;
272
+ }
273
+
274
+ /**
275
+ * Watch a fact path for changes
276
+ *
277
+ * @param factTag The fact type tag to watch
278
+ * @param callback Called when facts of this type change
279
+ * @returns Unsubscribe function
280
+ */
281
+ watchFacts(factTag: string, callback: (facts: PraxisFact[]) => void): UnsubscribeFn {
282
+ const path = getFactPath(factTag);
283
+
284
+ // Register the callback
285
+ if (!this.factWatchers.has(factTag)) {
286
+ this.factWatchers.set(factTag, new Set());
287
+ }
288
+ const watchers = this.factWatchers.get(factTag);
289
+ if (watchers) {
290
+ watchers.add(callback);
291
+ }
292
+
293
+ // Watch the path in the DB
294
+ const unsubscribe = this.db.watch<PraxisFact>(path, (fact) => {
295
+ callback([fact]);
296
+ });
297
+
298
+ this.subscriptions.push(unsubscribe);
299
+
300
+ return () => {
301
+ unsubscribe();
302
+ this.factWatchers.get(factTag)?.delete(callback);
303
+ };
304
+ }
305
+
306
+ /**
307
+ * Check constraints against the current state with new facts
308
+ */
309
+ private async checkConstraints(
310
+ newFacts: PraxisFact[]
311
+ ): Promise<{ valid: boolean; errors: string[] }> {
312
+ const constraints = this.registry.getAllConstraints();
313
+ const errors: string[] = [];
314
+
315
+ // Build a minimal state for constraint checking
316
+ const state: PraxisState & { context: TContext } = {
317
+ context: this.context,
318
+ facts: newFacts,
319
+ meta: {},
320
+ };
321
+
322
+ for (const constraint of constraints) {
323
+ try {
324
+ const result = constraint.impl(state);
325
+ if (result === false) {
326
+ errors.push(`Constraint "${constraint.id}" violated`);
327
+ } else if (typeof result === "string") {
328
+ errors.push(result);
329
+ }
330
+ } catch (error) {
331
+ errors.push(
332
+ `Error checking constraint "${constraint.id}": ${error instanceof Error ? error.message : String(error)}`
333
+ );
334
+ }
335
+ }
336
+
337
+ return {
338
+ valid: errors.length === 0,
339
+ errors,
340
+ };
341
+ }
342
+
343
+ /**
344
+ * Trigger rules when new facts are added
345
+ *
346
+ * This method is called after facts are stored. It can be extended
347
+ * for derived fact computation where rules generate new facts based
348
+ * on existing facts. Currently implemented as a hook point for future
349
+ * enhancements.
350
+ *
351
+ * @param _newFacts The newly stored facts (unused in current implementation)
352
+ */
353
+ private async triggerRules(_newFacts: PraxisFact[]): Promise<void> {
354
+ // Rules are typically triggered by events, not facts
355
+ // This method serves as a hook for derived fact computation
356
+ // which can be implemented by subclasses or future enhancements
357
+ }
358
+
359
+ /**
360
+ * Trigger rules when events are appended
361
+ */
362
+ private async triggerRulesForEvents(events: PraxisEvent[]): Promise<void> {
363
+ const rules = this.registry.getAllRules();
364
+
365
+ // Build state for rule evaluation
366
+ const state: PraxisState & { context: TContext } = {
367
+ context: this.context,
368
+ facts: [],
369
+ meta: {},
370
+ };
371
+
372
+ // Execute each rule
373
+ const derivedFacts: PraxisFact[] = [];
374
+ for (const rule of rules) {
375
+ try {
376
+ const facts = rule.impl(state, events);
377
+ derivedFacts.push(...facts);
378
+ } catch (error) {
379
+ this.onRuleError(rule.id, error);
380
+ }
381
+ }
382
+
383
+ // Store derived facts (without re-triggering rules to avoid infinite loops)
384
+ if (derivedFacts.length > 0) {
385
+ const constraintResult = await this.checkConstraints(derivedFacts);
386
+ if (constraintResult.valid) {
387
+ for (const fact of derivedFacts) {
388
+ await this.persistFact(fact);
389
+ }
390
+ }
391
+ }
392
+ }
393
+
394
+ /**
395
+ * Update the context
396
+ */
397
+ updateContext(context: TContext): void {
398
+ this.context = context;
399
+ }
400
+
401
+ /**
402
+ * Get the current context
403
+ */
404
+ getContext(): TContext {
405
+ return this.context;
406
+ }
407
+
408
+ /**
409
+ * Dispose of all subscriptions
410
+ */
411
+ dispose(): void {
412
+ for (const unsubscribe of this.subscriptions) {
413
+ unsubscribe();
414
+ }
415
+ this.subscriptions = [];
416
+ this.factWatchers.clear();
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Create a new PraxisDBStore
422
+ *
423
+ * @param db The PraxisDB instance to use
424
+ * @param registry The PraxisRegistry for rules and constraints
425
+ * @param initialContext Optional initial context
426
+ * @param onRuleError Optional error handler for rule execution errors
427
+ * @returns PraxisDBStore instance
428
+ *
429
+ * @example
430
+ * ```typescript
431
+ * const db = createInMemoryDB();
432
+ * const registry = new PraxisRegistry();
433
+ * const store = createPraxisDBStore(db, registry);
434
+ *
435
+ * await store.storeFact({ tag: "UserLoggedIn", payload: { userId: "alice" } });
436
+ * await store.appendEvent({ tag: "LOGIN", payload: { username: "alice" } });
437
+ * ```
438
+ */
439
+ export function createPraxisDBStore<TContext = unknown>(
440
+ db: PraxisDB,
441
+ registry: PraxisRegistry<TContext>,
442
+ initialContext?: TContext,
443
+ onRuleError?: RuleErrorHandler
444
+ ): PraxisDBStore<TContext> {
445
+ return new PraxisDBStore({ db, registry, initialContext, onRuleError });
446
+ }