@plures/praxis 1.1.2 → 1.1.3

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 (33) hide show
  1. package/README.md +67 -6
  2. package/dist/browser/chunk-R45WXWKH.js +345 -0
  3. package/dist/browser/index.d.ts +171 -11
  4. package/dist/browser/index.js +279 -277
  5. package/dist/browser/integrations/svelte.d.ts +3 -1
  6. package/dist/browser/integrations/svelte.js +7 -0
  7. package/dist/browser/{engine-BjdqxeXG.d.ts → reactive-engine.svelte-C9OpcTHf.d.ts} +87 -1
  8. package/dist/node/chunk-R45WXWKH.js +345 -0
  9. package/dist/node/components/index.d.cts +2 -2
  10. package/dist/node/components/index.d.ts +2 -2
  11. package/dist/node/index.cjs +343 -8
  12. package/dist/node/index.d.cts +108 -15
  13. package/dist/node/index.d.ts +108 -15
  14. package/dist/node/index.js +279 -278
  15. package/dist/node/integrations/svelte.cjs +357 -2
  16. package/dist/node/integrations/svelte.d.cts +3 -1
  17. package/dist/node/integrations/svelte.d.ts +3 -1
  18. package/dist/node/integrations/svelte.js +6 -0
  19. package/dist/node/{engine-CVJobhHm.d.cts → reactive-engine.svelte-1M4m_C_v.d.cts} +87 -1
  20. package/dist/node/{engine-1iqLe6_P.d.ts → reactive-engine.svelte-ChNFn4Hj.d.ts} +87 -1
  21. package/dist/node/{terminal-adapter-XLtCjjb_.d.cts → terminal-adapter-CDzxoLKR.d.cts} +68 -1
  22. package/dist/node/{terminal-adapter-07HGftGQ.d.ts → terminal-adapter-CWka-yL8.d.ts} +68 -1
  23. package/package.json +3 -2
  24. package/src/__tests__/reactive-engine.test.ts +516 -0
  25. package/src/core/pluresdb/README.md +156 -0
  26. package/src/core/pluresdb/adapter.ts +165 -0
  27. package/src/core/pluresdb/index.ts +3 -3
  28. package/src/core/reactive-engine.svelte.ts +88 -19
  29. package/src/core/reactive-engine.ts +284 -22
  30. package/src/index.browser.ts +12 -0
  31. package/src/index.ts +12 -0
  32. package/src/integrations/pluresdb.ts +2 -2
  33. package/src/integrations/svelte.ts +8 -0
@@ -1,3 +1,8 @@
1
+ import {
2
+ ReactiveLogicEngine,
3
+ createReactiveEngine
4
+ } from "../chunk-R45WXWKH.js";
5
+
1
6
  // src/integrations/svelte.ts
2
7
  function createPraxisStore(engine) {
3
8
  let currentState = engine.getState();
@@ -288,10 +293,12 @@ function createHistoryEngine(engine, options = {}) {
288
293
  }
289
294
  export {
290
295
  HistoryStateManager,
296
+ ReactiveLogicEngine,
291
297
  createContextStore,
292
298
  createDerivedStore,
293
299
  createHistoryEngine,
294
300
  createPraxisStore,
301
+ createReactiveEngine,
295
302
  usePraxisContext,
296
303
  usePraxisEngine,
297
304
  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,345 @@
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
+ // Use Svelte's $state rune for automatic reactivity
269
+ $.state($.proxy({ context: {}, facts: [], meta: {} }))
270
+ );
271
+ get state() {
272
+ return $.get(this.#state);
273
+ }
274
+ set state(value) {
275
+ $.set(this.#state, value, true);
276
+ }
277
+ _engine;
278
+ constructor(options) {
279
+ this.state.context = options.initialContext;
280
+ this.state.facts = options.initialFacts ?? [];
281
+ this.state.meta = options.initialMeta ?? {};
282
+ if (options.registry) {
283
+ this._engine = createPraxisEngine({
284
+ initialContext: options.initialContext,
285
+ registry: options.registry
286
+ });
287
+ } else {
288
+ this._engine = createPraxisEngine({
289
+ initialContext: options.initialContext,
290
+ registry: new PraxisRegistry()
291
+ });
292
+ }
293
+ }
294
+ /**
295
+ * Access the reactive context.
296
+ * In Svelte 5 components, changes to this object will automatically trigger updates.
297
+ */
298
+ get context() {
299
+ return this.state.context;
300
+ }
301
+ /**
302
+ * Access the reactive facts list.
303
+ */
304
+ get facts() {
305
+ return this.state.facts;
306
+ }
307
+ /**
308
+ * Access the reactive metadata.
309
+ */
310
+ get meta() {
311
+ return this.state.meta;
312
+ }
313
+ /**
314
+ * Apply a mutation to the state.
315
+ * Changes will automatically trigger Svelte reactivity.
316
+ *
317
+ * @param mutator A function that receives the state and modifies it.
318
+ */
319
+ apply(mutator) {
320
+ mutator(this.state);
321
+ }
322
+ /**
323
+ * Process events through the logic engine and update reactive state.
324
+ *
325
+ * @param events Events to process
326
+ */
327
+ step(events) {
328
+ const result = this._engine.step(events);
329
+ this.state.context = result.state.context;
330
+ this.state.facts = result.state.facts;
331
+ this.state.meta = result.state.meta ?? {};
332
+ }
333
+ };
334
+ function createReactiveEngine(options) {
335
+ return new ReactiveLogicEngine(options);
336
+ }
337
+
338
+ export {
339
+ PRAXIS_PROTOCOL_VERSION,
340
+ PraxisRegistry,
341
+ LogicEngine,
342
+ createPraxisEngine,
343
+ ReactiveLogicEngine,
344
+ createReactiveEngine
345
+ };
@@ -1,5 +1,5 @@
1
- import { T as TerminalAdapter } from '../terminal-adapter-XLtCjjb_.cjs';
2
- export { c as createTerminalAdapter } from '../terminal-adapter-XLtCjjb_.cjs';
1
+ import { T as TerminalAdapter } from '../terminal-adapter-CDzxoLKR.cjs';
2
+ export { c as createTerminalAdapter } from '../terminal-adapter-CDzxoLKR.cjs';
3
3
  import '../schema.cjs';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { T as TerminalAdapter } from '../terminal-adapter-07HGftGQ.js';
2
- export { c as createTerminalAdapter } from '../terminal-adapter-07HGftGQ.js';
1
+ import { T as TerminalAdapter } from '../terminal-adapter-CWka-yL8.js';
2
+ export { c as createTerminalAdapter } from '../terminal-adapter-CWka-yL8.js';
3
3
  import '../schema.js';
4
4
 
5
5
  /**