@plures/praxis 1.1.2 → 1.2.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 (49) hide show
  1. package/FRAMEWORK.md +106 -15
  2. package/README.md +275 -53
  3. package/dist/browser/adapter-TM4IS5KT.js +12 -0
  4. package/dist/browser/chunk-JQ64KMLN.js +141 -0
  5. package/dist/browser/chunk-LE2ZJYFC.js +154 -0
  6. package/dist/browser/chunk-VOMLVI6V.js +197 -0
  7. package/dist/browser/engine-YJZV4SLD.js +8 -0
  8. package/dist/browser/index.d.ts +300 -11
  9. package/dist/browser/index.js +334 -325
  10. package/dist/browser/integrations/svelte.d.ts +3 -1
  11. package/dist/browser/integrations/svelte.js +8 -0
  12. package/dist/browser/{engine-BjdqxeXG.d.ts → reactive-engine.svelte-C9OpcTHf.d.ts} +87 -1
  13. package/dist/node/adapter-K6DOX6XS.js +13 -0
  14. package/dist/node/chunk-JQ64KMLN.js +141 -0
  15. package/dist/node/chunk-LE2ZJYFC.js +154 -0
  16. package/dist/node/chunk-S54337I5.js +446 -0
  17. package/dist/node/chunk-VOMLVI6V.js +197 -0
  18. package/dist/node/cli/index.cjs +1444 -889
  19. package/dist/node/cli/index.js +9 -0
  20. package/dist/node/components/index.d.cts +2 -2
  21. package/dist/node/components/index.d.ts +2 -2
  22. package/dist/node/docs-JFNYTOJA.js +102 -0
  23. package/dist/node/engine-2DQBKBJC.js +9 -0
  24. package/dist/node/index.cjs +747 -234
  25. package/dist/node/index.d.cts +237 -15
  26. package/dist/node/index.d.ts +237 -15
  27. package/dist/node/index.js +339 -767
  28. package/dist/node/integrations/svelte.cjs +357 -2
  29. package/dist/node/integrations/svelte.d.cts +3 -1
  30. package/dist/node/integrations/svelte.d.ts +3 -1
  31. package/dist/node/integrations/svelte.js +7 -0
  32. package/dist/node/{engine-CVJobhHm.d.cts → reactive-engine.svelte-1M4m_C_v.d.cts} +87 -1
  33. package/dist/node/{engine-1iqLe6_P.d.ts → reactive-engine.svelte-ChNFn4Hj.d.ts} +87 -1
  34. package/dist/node/{terminal-adapter-XLtCjjb_.d.cts → terminal-adapter-CDzxoLKR.d.cts} +68 -1
  35. package/dist/node/{terminal-adapter-07HGftGQ.d.ts → terminal-adapter-CWka-yL8.d.ts} +68 -1
  36. package/package.json +3 -2
  37. package/src/__tests__/reactive-engine.test.ts +516 -0
  38. package/src/cli/commands/docs.ts +147 -0
  39. package/src/cli/index.ts +21 -0
  40. package/src/core/pluresdb/README.md +156 -0
  41. package/src/core/pluresdb/adapter.ts +165 -0
  42. package/src/core/pluresdb/index.ts +3 -3
  43. package/src/core/reactive-engine.svelte.ts +93 -19
  44. package/src/core/reactive-engine.ts +284 -22
  45. package/src/index.browser.ts +16 -0
  46. package/src/index.ts +16 -0
  47. package/src/integrations/pluresdb.ts +2 -2
  48. package/src/integrations/svelte.ts +8 -0
  49. package/src/integrations/unified.ts +350 -0
@@ -1,4 +1,5 @@
1
- import { L as LogicEngine, P as PraxisState, a as PraxisEvent } from '../engine-BjdqxeXG.js';
1
+ import { L as LogicEngine, P as PraxisState, a as PraxisEvent } from '../reactive-engine.svelte-C9OpcTHf.js';
2
+ export { p as ReactiveEngineOptions, q as ReactiveLogicEngine, r as createReactiveEngine } from '../reactive-engine.svelte-C9OpcTHf.js';
2
3
 
3
4
  /**
4
5
  * Svelte v5 Integration
@@ -9,6 +10,7 @@ import { L as LogicEngine, P as PraxisState, a as PraxisEvent } from '../engine-
9
10
  * Features:
10
11
  * - Store-based API for backward compatibility
11
12
  * - Runes-based composables for Svelte 5
13
+ * - createReactiveEngine for easy reactive engine setup
12
14
  * - Snapshot support for time-travel debugging
13
15
  * - History state pattern implementation
14
16
  * - Automatic cleanup and subscription management
@@ -1,3 +1,9 @@
1
+ import {
2
+ ReactiveLogicEngine,
3
+ createReactiveEngine
4
+ } from "../chunk-LE2ZJYFC.js";
5
+ import "../chunk-VOMLVI6V.js";
6
+
1
7
  // src/integrations/svelte.ts
2
8
  function createPraxisStore(engine) {
3
9
  let currentState = engine.getState();
@@ -288,10 +294,12 @@ function createHistoryEngine(engine, options = {}) {
288
294
  }
289
295
  export {
290
296
  HistoryStateManager,
297
+ ReactiveLogicEngine,
291
298
  createContextStore,
292
299
  createDerivedStore,
293
300
  createHistoryEngine,
294
301
  createPraxisStore,
302
+ createReactiveEngine,
295
303
  usePraxisContext,
296
304
  usePraxisEngine,
297
305
  usePraxisSubscription
@@ -330,4 +330,90 @@ declare class LogicEngine<TContext = unknown> {
330
330
  */
331
331
  declare function createPraxisEngine<TContext = unknown>(options: PraxisEngineOptions<TContext>): LogicEngine<TContext>;
332
332
 
333
- export { type ConstraintDescriptor as C, LogicEngine as L, type PraxisState as P, type RuleDescriptor as R, type PraxisEvent as a, PraxisRegistry as b, type PraxisFact as c, type RuleFn as d, type ConstraintFn as e, type PraxisModule as f, type PraxisDiagnostics as g, type PraxisStepConfig as h, type PraxisStepResult as i, type PraxisStepFn as j, PRAXIS_PROTOCOL_VERSION as k, type RuleId as l, type ConstraintId as m, type PraxisEngineOptions as n, createPraxisEngine as o };
333
+ /**
334
+ * Praxis Reactive Logic Engine - Svelte 5 Implementation
335
+ *
336
+ * This version uses Svelte 5 runes ($state) for built-in reactivity.
337
+ * The state object is automatically reactive when used in Svelte components.
338
+ */
339
+
340
+ interface ReactiveEngineOptions<TContext> {
341
+ initialContext: TContext;
342
+ initialFacts?: any[];
343
+ initialMeta?: Record<string, unknown>;
344
+ registry?: PraxisRegistry<TContext>;
345
+ }
346
+ /**
347
+ * Reactive Logic Engine using Svelte 5 runes.
348
+ * Combines the standard LogicEngine with reactive state management.
349
+ */
350
+ declare class ReactiveLogicEngine<TContext extends object> {
351
+ state: {
352
+ context: TContext;
353
+ facts: any[];
354
+ meta: Record<string, unknown>;
355
+ };
356
+ private _engine;
357
+ constructor(options: ReactiveEngineOptions<TContext>);
358
+ /**
359
+ * Access the reactive context.
360
+ * In Svelte 5 components, changes to this object will automatically trigger updates.
361
+ */
362
+ get context(): TContext;
363
+ /**
364
+ * Access the reactive facts list.
365
+ */
366
+ get facts(): any[];
367
+ /**
368
+ * Access the reactive metadata.
369
+ */
370
+ get meta(): Record<string, unknown>;
371
+ /**
372
+ * Apply a mutation to the state.
373
+ * Changes will automatically trigger Svelte reactivity.
374
+ *
375
+ * @param mutator A function that receives the state and modifies it.
376
+ */
377
+ apply(mutator: (state: {
378
+ context: TContext;
379
+ facts: any[];
380
+ meta: Record<string, unknown>;
381
+ }) => void): void;
382
+ /**
383
+ * Process events through the logic engine and update reactive state.
384
+ *
385
+ * @param events Events to process
386
+ */
387
+ step(events: PraxisEvent[]): void;
388
+ }
389
+ /**
390
+ * Create a reactive logic engine with Svelte 5 runes.
391
+ *
392
+ * @param options Configuration options
393
+ * @returns A reactive logic engine instance
394
+ *
395
+ * @example
396
+ * ```svelte
397
+ * <script lang="ts">
398
+ * import { createReactiveEngine } from '@plures/praxis/svelte';
399
+ *
400
+ * const engine = createReactiveEngine({
401
+ * initialContext: { count: 0 },
402
+ * registry
403
+ * });
404
+ *
405
+ * // Use $derived for computed values
406
+ * const count = $derived(engine.context.count);
407
+ * const doubled = $derived(engine.context.count * 2);
408
+ *
409
+ * function increment() {
410
+ * engine.step([Increment.create({ amount: 1 })]);
411
+ * }
412
+ * </script>
413
+ *
414
+ * <button on:click={increment}>Count: {count}, Doubled: {doubled}</button>
415
+ * ```
416
+ */
417
+ declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
418
+
419
+ export { type ConstraintDescriptor as C, LogicEngine as L, type PraxisState as P, type RuleDescriptor as R, type PraxisEvent as a, PraxisRegistry as b, type PraxisFact as c, type RuleFn as d, type ConstraintFn as e, type PraxisModule as f, type PraxisDiagnostics as g, type PraxisStepConfig as h, type PraxisStepResult as i, type PraxisStepFn as j, PRAXIS_PROTOCOL_VERSION as k, type RuleId as l, type ConstraintId as m, type PraxisEngineOptions as n, createPraxisEngine as o, type ReactiveEngineOptions as p, ReactiveLogicEngine as q, createReactiveEngine as r };
@@ -0,0 +1,13 @@
1
+ import {
2
+ InMemoryPraxisDB,
3
+ PluresDBPraxisAdapter,
4
+ createInMemoryDB,
5
+ createPluresDB
6
+ } from "./chunk-JQ64KMLN.js";
7
+ import "./chunk-QGM4M3NI.js";
8
+ export {
9
+ InMemoryPraxisDB,
10
+ PluresDBPraxisAdapter,
11
+ createInMemoryDB,
12
+ createPluresDB
13
+ };
@@ -0,0 +1,141 @@
1
+ // src/core/pluresdb/adapter.ts
2
+ var InMemoryPraxisDB = class {
3
+ store = /* @__PURE__ */ new Map();
4
+ watchers = /* @__PURE__ */ new Map();
5
+ async get(key) {
6
+ return this.store.get(key);
7
+ }
8
+ async set(key, value) {
9
+ this.store.set(key, value);
10
+ const keyWatchers = this.watchers.get(key);
11
+ if (keyWatchers) {
12
+ for (const callback of keyWatchers) {
13
+ callback(value);
14
+ }
15
+ }
16
+ }
17
+ watch(key, callback) {
18
+ if (!this.watchers.has(key)) {
19
+ this.watchers.set(key, /* @__PURE__ */ new Set());
20
+ }
21
+ const watchers = this.watchers.get(key);
22
+ const wrappedCallback = (val) => callback(val);
23
+ watchers.add(wrappedCallback);
24
+ return () => {
25
+ watchers.delete(wrappedCallback);
26
+ if (watchers.size === 0) {
27
+ this.watchers.delete(key);
28
+ }
29
+ };
30
+ }
31
+ /**
32
+ * Get all keys (for testing/debugging)
33
+ */
34
+ keys() {
35
+ return Array.from(this.store.keys());
36
+ }
37
+ /**
38
+ * Clear all data (for testing)
39
+ */
40
+ clear() {
41
+ this.store.clear();
42
+ this.watchers.clear();
43
+ }
44
+ };
45
+ function createInMemoryDB() {
46
+ return new InMemoryPraxisDB();
47
+ }
48
+ var PluresDBPraxisAdapter = class {
49
+ db;
50
+ watchers = /* @__PURE__ */ new Map();
51
+ pollIntervals = /* @__PURE__ */ new Map();
52
+ lastValues = /* @__PURE__ */ new Map();
53
+ pollInterval;
54
+ constructor(config) {
55
+ if ("get" in config && "put" in config) {
56
+ this.db = config;
57
+ this.pollInterval = 1e3;
58
+ } else {
59
+ this.db = config.db;
60
+ this.pollInterval = config.pollInterval ?? 1e3;
61
+ }
62
+ }
63
+ async get(key) {
64
+ try {
65
+ const value = await this.db.get(key);
66
+ return value;
67
+ } catch (error) {
68
+ return void 0;
69
+ }
70
+ }
71
+ async set(key, value) {
72
+ await this.db.put(key, value);
73
+ this.lastValues.set(key, value);
74
+ const keyWatchers = this.watchers.get(key);
75
+ if (keyWatchers) {
76
+ for (const callback of keyWatchers) {
77
+ callback(value);
78
+ }
79
+ }
80
+ }
81
+ watch(key, callback) {
82
+ if (!this.watchers.has(key)) {
83
+ this.watchers.set(key, /* @__PURE__ */ new Set());
84
+ }
85
+ const watchers = this.watchers.get(key);
86
+ const wrappedCallback = (val) => callback(val);
87
+ watchers.add(wrappedCallback);
88
+ if (!this.pollIntervals.has(key)) {
89
+ const interval = setInterval(async () => {
90
+ try {
91
+ const value = await this.db.get(key);
92
+ const lastValue = this.lastValues.get(key);
93
+ if (JSON.stringify(value) !== JSON.stringify(lastValue)) {
94
+ this.lastValues.set(key, value);
95
+ const currentWatchers = this.watchers.get(key);
96
+ if (currentWatchers) {
97
+ for (const cb of currentWatchers) {
98
+ cb(value);
99
+ }
100
+ }
101
+ }
102
+ } catch (error) {
103
+ }
104
+ }, this.pollInterval);
105
+ this.pollIntervals.set(key, interval);
106
+ }
107
+ return () => {
108
+ watchers.delete(wrappedCallback);
109
+ if (watchers.size === 0) {
110
+ this.watchers.delete(key);
111
+ const interval = this.pollIntervals.get(key);
112
+ if (interval) {
113
+ clearInterval(interval);
114
+ this.pollIntervals.delete(key);
115
+ }
116
+ this.lastValues.delete(key);
117
+ }
118
+ };
119
+ }
120
+ /**
121
+ * Clean up all resources
122
+ */
123
+ dispose() {
124
+ for (const interval of this.pollIntervals.values()) {
125
+ clearInterval(interval);
126
+ }
127
+ this.pollIntervals.clear();
128
+ this.watchers.clear();
129
+ this.lastValues.clear();
130
+ }
131
+ };
132
+ function createPluresDB(config) {
133
+ return new PluresDBPraxisAdapter(config);
134
+ }
135
+
136
+ export {
137
+ InMemoryPraxisDB,
138
+ createInMemoryDB,
139
+ PluresDBPraxisAdapter,
140
+ createPluresDB
141
+ };
@@ -0,0 +1,154 @@
1
+ import {
2
+ createPraxisEngine
3
+ } from "./chunk-VOMLVI6V.js";
4
+
5
+ // src/core/rules.ts
6
+ var PraxisRegistry = class {
7
+ rules = /* @__PURE__ */ new Map();
8
+ constraints = /* @__PURE__ */ new Map();
9
+ /**
10
+ * Register a rule
11
+ */
12
+ registerRule(descriptor) {
13
+ if (this.rules.has(descriptor.id)) {
14
+ throw new Error(`Rule with id "${descriptor.id}" already registered`);
15
+ }
16
+ this.rules.set(descriptor.id, descriptor);
17
+ }
18
+ /**
19
+ * Register a constraint
20
+ */
21
+ registerConstraint(descriptor) {
22
+ if (this.constraints.has(descriptor.id)) {
23
+ throw new Error(`Constraint with id "${descriptor.id}" already registered`);
24
+ }
25
+ this.constraints.set(descriptor.id, descriptor);
26
+ }
27
+ /**
28
+ * Register a module (all its rules and constraints)
29
+ */
30
+ registerModule(module) {
31
+ for (const rule of module.rules) {
32
+ this.registerRule(rule);
33
+ }
34
+ for (const constraint of module.constraints) {
35
+ this.registerConstraint(constraint);
36
+ }
37
+ }
38
+ /**
39
+ * Get a rule by ID
40
+ */
41
+ getRule(id) {
42
+ return this.rules.get(id);
43
+ }
44
+ /**
45
+ * Get a constraint by ID
46
+ */
47
+ getConstraint(id) {
48
+ return this.constraints.get(id);
49
+ }
50
+ /**
51
+ * Get all registered rule IDs
52
+ */
53
+ getRuleIds() {
54
+ return Array.from(this.rules.keys());
55
+ }
56
+ /**
57
+ * Get all registered constraint IDs
58
+ */
59
+ getConstraintIds() {
60
+ return Array.from(this.constraints.keys());
61
+ }
62
+ /**
63
+ * Get all rules
64
+ */
65
+ getAllRules() {
66
+ return Array.from(this.rules.values());
67
+ }
68
+ /**
69
+ * Get all constraints
70
+ */
71
+ getAllConstraints() {
72
+ return Array.from(this.constraints.values());
73
+ }
74
+ };
75
+
76
+ // src/core/reactive-engine.svelte.ts
77
+ import * as $ from "svelte/internal/client";
78
+ var ReactiveLogicEngine = class {
79
+ #state = (
80
+ // Use Svelte's $state rune for automatic reactivity
81
+ $.state($.proxy({ context: {}, facts: [], meta: {} }))
82
+ );
83
+ get state() {
84
+ return $.get(this.#state);
85
+ }
86
+ set state(value) {
87
+ $.set(this.#state, value, true);
88
+ }
89
+ _engine;
90
+ constructor(options) {
91
+ this.state.context = options.initialContext;
92
+ this.state.facts = options.initialFacts ?? [];
93
+ this.state.meta = options.initialMeta ?? {};
94
+ if (options.registry) {
95
+ this._engine = createPraxisEngine({
96
+ initialContext: options.initialContext,
97
+ registry: options.registry
98
+ });
99
+ } else {
100
+ this._engine = createPraxisEngine({
101
+ initialContext: options.initialContext,
102
+ registry: new PraxisRegistry()
103
+ });
104
+ }
105
+ }
106
+ /**
107
+ * Access the reactive context.
108
+ * In Svelte 5 components, changes to this object will automatically trigger updates.
109
+ */
110
+ get context() {
111
+ return this.state.context;
112
+ }
113
+ /**
114
+ * Access the reactive facts list.
115
+ */
116
+ get facts() {
117
+ return this.state.facts;
118
+ }
119
+ /**
120
+ * Access the reactive metadata.
121
+ */
122
+ get meta() {
123
+ return this.state.meta;
124
+ }
125
+ /**
126
+ * Apply a mutation to the state.
127
+ * Changes will automatically trigger Svelte reactivity.
128
+ *
129
+ * @param mutator A function that receives the state and modifies it.
130
+ */
131
+ apply(mutator) {
132
+ mutator(this.state);
133
+ }
134
+ /**
135
+ * Process events through the logic engine and update reactive state.
136
+ *
137
+ * @param events Events to process
138
+ */
139
+ step(events) {
140
+ const result = this._engine.step(events);
141
+ this.state.context = result.state.context;
142
+ this.state.facts = result.state.facts;
143
+ this.state.meta = result.state.meta ?? {};
144
+ }
145
+ };
146
+ function createReactiveEngine(options) {
147
+ return new ReactiveLogicEngine(options);
148
+ }
149
+
150
+ export {
151
+ PraxisRegistry,
152
+ ReactiveLogicEngine,
153
+ createReactiveEngine
154
+ };