@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,315 +1,225 @@
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
- };
1
+ import {
2
+ LogicEngine,
3
+ PRAXIS_PROTOCOL_VERSION,
4
+ PraxisRegistry,
5
+ ReactiveLogicEngine,
6
+ createPraxisEngine,
7
+ createReactiveEngine
8
+ } from "./chunk-R45WXWKH.js";
74
9
 
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;
10
+ // src/core/reactive-engine.ts
11
+ var ReactiveLogicEngine2 = class _ReactiveLogicEngine {
12
+ _state;
13
+ _subscribers = /* @__PURE__ */ new Set();
14
+ _contextProxy;
15
+ _factsProxy;
16
+ _metaProxy;
17
+ _batchDepth = 0;
18
+ _pendingNotification = false;
19
+ _proxyCache = /* @__PURE__ */ new WeakMap();
20
+ // Array methods that mutate the array
21
+ static ARRAY_MUTATORS = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"];
94
22
  constructor(options) {
95
- this.registry = options.registry;
96
- this.state = {
23
+ this._state = {
97
24
  context: options.initialContext,
98
25
  facts: options.initialFacts ?? [],
99
- meta: options.initialMeta ?? {},
100
- protocolVersion: PRAXIS_PROTOCOL_VERSION
26
+ meta: options.initialMeta ?? {}
101
27
  };
28
+ this._contextProxy = this._createReactiveProxy(this._state.context);
29
+ this._factsProxy = this._createReactiveProxy(this._state.facts);
30
+ this._metaProxy = this._createReactiveProxy(this._state.meta);
102
31
  }
103
32
  /**
104
- * Get the current state (immutable copy)
33
+ * Create a reactive proxy that notifies subscribers on changes.
34
+ * Uses a WeakMap cache to avoid creating multiple proxies for the same object.
105
35
  */
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
36
+ _createReactiveProxy(target) {
37
+ const cached = this._proxyCache.get(target);
38
+ if (cached) {
39
+ return cached;
40
+ }
41
+ const self = this;
42
+ const handler = {
43
+ get(obj, prop) {
44
+ const value = Reflect.get(obj, prop);
45
+ if (value && typeof value === "object") {
46
+ return self._createReactiveProxy(value);
47
+ }
48
+ if (Array.isArray(obj) && typeof value === "function") {
49
+ if (_ReactiveLogicEngine.ARRAY_MUTATORS.includes(prop)) {
50
+ return function(...args) {
51
+ const result = value.apply(obj, args);
52
+ self._notify();
53
+ return result;
54
+ };
55
+ }
56
+ }
57
+ return value;
58
+ },
59
+ set(obj, prop, value) {
60
+ const oldValue = obj[prop];
61
+ const result = Reflect.set(obj, prop, value);
62
+ if (oldValue !== value) {
63
+ self._notify();
64
+ }
65
+ return result;
66
+ },
67
+ deleteProperty(obj, prop) {
68
+ const result = Reflect.deleteProperty(obj, prop);
69
+ self._notify();
70
+ return result;
71
+ }
112
72
  };
73
+ const proxy = new Proxy(target, handler);
74
+ this._proxyCache.set(target, proxy);
75
+ return proxy;
113
76
  }
114
77
  /**
115
- * Get the current context
116
- */
117
- getContext() {
118
- return safeClone(this.state.context);
119
- }
120
- /**
121
- * Get current facts
78
+ * Notify all subscribers of state changes
122
79
  */
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
- }
80
+ _notify() {
81
+ if (this._batchDepth > 0) {
82
+ this._pendingNotification = true;
83
+ return;
171
84
  }
172
- newState = {
173
- ...newState,
174
- facts: [...newState.facts, ...newFacts]
85
+ const currentState = {
86
+ context: this._contextProxy,
87
+ facts: this._factsProxy,
88
+ meta: this._metaProxy
175
89
  };
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
- }
90
+ this._subscribers.forEach((callback) => {
186
91
  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
- }
92
+ callback(currentState);
201
93
  } 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
- });
94
+ console.error("Error in reactive engine subscriber:", error);
207
95
  }
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
- };
96
+ });
247
97
  }
248
98
  /**
249
- * Reset the engine to initial state
99
+ * Get the full state object
250
100
  */
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
101
  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 ?? {};
102
+ return {
103
+ context: this._contextProxy,
104
+ facts: this._factsProxy,
105
+ meta: this._metaProxy
106
+ };
283
107
  }
284
108
  /**
285
- * Access the reactive context directly.
286
- * Consumers can use this in $derived() or $effect().
109
+ * Access the reactive context.
110
+ * Changes to this object will trigger subscriber notifications.
287
111
  */
288
112
  get context() {
289
- return this.state.context;
113
+ return this._contextProxy;
290
114
  }
291
115
  /**
292
116
  * Access the reactive facts list.
117
+ * Changes to this array will trigger subscriber notifications.
293
118
  */
294
119
  get facts() {
295
- return this.state.facts;
120
+ return this._factsProxy;
121
+ }
122
+ /**
123
+ * Access the reactive metadata.
124
+ * Changes to this object will trigger subscriber notifications.
125
+ */
126
+ get meta() {
127
+ return this._metaProxy;
296
128
  }
297
129
  /**
298
130
  * Apply a mutation to the state.
299
131
  * This is the "Action" or "Rule" equivalent.
132
+ * Mutations are batched - notifications only happen once per apply call.
300
133
  *
301
134
  * @param mutator A function that receives the state and modifies it.
302
135
  */
303
136
  apply(mutator) {
304
- mutator(this.state);
137
+ this._batchDepth++;
138
+ try {
139
+ mutator({
140
+ context: this._contextProxy,
141
+ facts: this._factsProxy,
142
+ meta: this._metaProxy
143
+ });
144
+ } finally {
145
+ this._batchDepth--;
146
+ if (this._batchDepth === 0 && this._pendingNotification) {
147
+ this._pendingNotification = false;
148
+ this._notify();
149
+ }
150
+ }
305
151
  }
306
152
  /**
307
- * Access the reactive meta.
153
+ * Subscribe to state changes.
154
+ * Returns an unsubscribe function.
155
+ *
156
+ * @param callback Function to call when state changes
157
+ * @returns Unsubscribe function
308
158
  */
309
- get meta() {
310
- return this.state.meta;
159
+ subscribe(callback) {
160
+ this._subscribers.add(callback);
161
+ try {
162
+ callback({
163
+ context: this._contextProxy,
164
+ facts: this._factsProxy,
165
+ meta: this._metaProxy
166
+ });
167
+ } catch (error) {
168
+ console.error("Error in reactive engine subscriber:", error);
169
+ }
170
+ return () => {
171
+ this._subscribers.delete(callback);
172
+ };
173
+ }
174
+ /**
175
+ * Create a derived/computed value from the state.
176
+ * The selector function will be called whenever the state changes.
177
+ *
178
+ * @param selector Function to extract derived value from state
179
+ * @returns Object with subscribe method for reactive updates
180
+ */
181
+ $derived(selector) {
182
+ const subscribers = /* @__PURE__ */ new Set();
183
+ let currentValue = selector({
184
+ context: this._contextProxy,
185
+ facts: this._factsProxy,
186
+ meta: this._metaProxy
187
+ });
188
+ this.subscribe(() => {
189
+ const newValue = selector({
190
+ context: this._contextProxy,
191
+ facts: this._factsProxy,
192
+ meta: this._metaProxy
193
+ });
194
+ if (newValue !== currentValue) {
195
+ currentValue = newValue;
196
+ subscribers.forEach((callback) => {
197
+ try {
198
+ callback(currentValue);
199
+ } catch (error) {
200
+ console.error("Error in derived value subscriber:", error);
201
+ }
202
+ });
203
+ }
204
+ });
205
+ return {
206
+ subscribe: (callback) => {
207
+ subscribers.add(callback);
208
+ try {
209
+ callback(currentValue);
210
+ } catch (error) {
211
+ console.error("Error in derived value subscriber:", error);
212
+ }
213
+ return () => {
214
+ subscribers.delete(callback);
215
+ };
216
+ }
217
+ };
311
218
  }
312
219
  };
220
+ function createReactiveEngine2(options) {
221
+ return new ReactiveLogicEngine2(options);
222
+ }
313
223
 
314
224
  // src/core/actors.ts
315
225
  var ActorManager = class {
@@ -398,7 +308,7 @@ var ActorManager = class {
398
308
  /**
399
309
  * Notify active actors of a state change
400
310
  */
401
- async notifyStateChange(state2) {
311
+ async notifyStateChange(state) {
402
312
  if (!this.engine) {
403
313
  return;
404
314
  }
@@ -406,7 +316,7 @@ var ActorManager = class {
406
316
  for (const actorId of this.activeActors) {
407
317
  const actor = this.actors.get(actorId);
408
318
  if (actor?.onStateChange) {
409
- const result = actor.onStateChange(state2, this.engine);
319
+ const result = actor.onStateChange(state, this.engine);
410
320
  if (result instanceof Promise) {
411
321
  promises.push(result);
412
322
  }
@@ -1147,14 +1057,14 @@ var PraxisDBStore = class {
1147
1057
  async checkConstraints(newFacts) {
1148
1058
  const constraints = this.registry.getAllConstraints();
1149
1059
  const errors = [];
1150
- const state2 = {
1060
+ const state = {
1151
1061
  context: this.context,
1152
1062
  facts: newFacts,
1153
1063
  meta: {}
1154
1064
  };
1155
1065
  for (const constraint of constraints) {
1156
1066
  try {
1157
- const result = constraint.impl(state2);
1067
+ const result = constraint.impl(state);
1158
1068
  if (result === false) {
1159
1069
  errors.push(`Constraint "${constraint.id}" violated`);
1160
1070
  } else if (typeof result === "string") {
@@ -1188,7 +1098,7 @@ var PraxisDBStore = class {
1188
1098
  */
1189
1099
  async triggerRulesForEvents(events) {
1190
1100
  const rules = this.registry.getAllRules();
1191
- const state2 = {
1101
+ const state = {
1192
1102
  context: this.context,
1193
1103
  facts: [],
1194
1104
  meta: {}
@@ -1196,7 +1106,7 @@ var PraxisDBStore = class {
1196
1106
  const derivedFacts = [];
1197
1107
  for (const rule of rules) {
1198
1108
  try {
1199
- const facts = rule.impl(state2, events);
1109
+ const facts = rule.impl(state, events);
1200
1110
  derivedFacts.push(...facts);
1201
1111
  } catch (error) {
1202
1112
  this.onRuleError(rule.id, error);
@@ -1285,6 +1195,93 @@ var InMemoryPraxisDB = class {
1285
1195
  function createInMemoryDB() {
1286
1196
  return new InMemoryPraxisDB();
1287
1197
  }
1198
+ var PluresDBPraxisAdapter = class {
1199
+ db;
1200
+ watchers = /* @__PURE__ */ new Map();
1201
+ pollIntervals = /* @__PURE__ */ new Map();
1202
+ lastValues = /* @__PURE__ */ new Map();
1203
+ pollInterval;
1204
+ constructor(config) {
1205
+ if ("get" in config && "put" in config) {
1206
+ this.db = config;
1207
+ this.pollInterval = 1e3;
1208
+ } else {
1209
+ this.db = config.db;
1210
+ this.pollInterval = config.pollInterval ?? 1e3;
1211
+ }
1212
+ }
1213
+ async get(key) {
1214
+ try {
1215
+ const value = await this.db.get(key);
1216
+ return value;
1217
+ } catch (error) {
1218
+ return void 0;
1219
+ }
1220
+ }
1221
+ async set(key, value) {
1222
+ await this.db.put(key, value);
1223
+ this.lastValues.set(key, value);
1224
+ const keyWatchers = this.watchers.get(key);
1225
+ if (keyWatchers) {
1226
+ for (const callback of keyWatchers) {
1227
+ callback(value);
1228
+ }
1229
+ }
1230
+ }
1231
+ watch(key, callback) {
1232
+ if (!this.watchers.has(key)) {
1233
+ this.watchers.set(key, /* @__PURE__ */ new Set());
1234
+ }
1235
+ const watchers = this.watchers.get(key);
1236
+ const wrappedCallback = (val) => callback(val);
1237
+ watchers.add(wrappedCallback);
1238
+ if (!this.pollIntervals.has(key)) {
1239
+ const interval = setInterval(async () => {
1240
+ try {
1241
+ const value = await this.db.get(key);
1242
+ const lastValue = this.lastValues.get(key);
1243
+ if (JSON.stringify(value) !== JSON.stringify(lastValue)) {
1244
+ this.lastValues.set(key, value);
1245
+ const currentWatchers = this.watchers.get(key);
1246
+ if (currentWatchers) {
1247
+ for (const cb of currentWatchers) {
1248
+ cb(value);
1249
+ }
1250
+ }
1251
+ }
1252
+ } catch (error) {
1253
+ }
1254
+ }, this.pollInterval);
1255
+ this.pollIntervals.set(key, interval);
1256
+ }
1257
+ return () => {
1258
+ watchers.delete(wrappedCallback);
1259
+ if (watchers.size === 0) {
1260
+ this.watchers.delete(key);
1261
+ const interval = this.pollIntervals.get(key);
1262
+ if (interval) {
1263
+ clearInterval(interval);
1264
+ this.pollIntervals.delete(key);
1265
+ }
1266
+ this.lastValues.delete(key);
1267
+ }
1268
+ };
1269
+ }
1270
+ /**
1271
+ * Clean up all resources
1272
+ */
1273
+ dispose() {
1274
+ for (const interval of this.pollIntervals.values()) {
1275
+ clearInterval(interval);
1276
+ }
1277
+ this.pollIntervals.clear();
1278
+ this.watchers.clear();
1279
+ this.lastValues.clear();
1280
+ }
1281
+ };
1282
+ function createPluresDB(config) {
1283
+ return new PluresDBPraxisAdapter(config);
1284
+ }
1288
1285
 
1289
1286
  // src/core/pluresdb/schema-registry.ts
1290
1287
  function getSchemaPath(schemaName) {
@@ -2733,8 +2730,8 @@ function createMockTauriBridge() {
2733
2730
  function createTauriPraxisAdapter(options) {
2734
2731
  const { bridge, statePath = "praxis-state.json", eventsPath = "praxis-events.json" } = options;
2735
2732
  return {
2736
- async saveState(state2) {
2737
- const json = JSON.stringify(state2, null, 2);
2733
+ async saveState(state) {
2734
+ const json = JSON.stringify(state, null, 2);
2738
2735
  await bridge.fs.writeTextFile(statePath, json);
2739
2736
  },
2740
2737
  async loadState() {
@@ -2835,11 +2832,13 @@ function generateTauriConfig(config) {
2835
2832
  }
2836
2833
  export {
2837
2834
  ActorManager,
2835
+ ReactiveLogicEngine2 as FrameworkAgnosticReactiveEngine,
2838
2836
  InMemoryPraxisDB,
2839
2837
  LogicEngine,
2840
2838
  PRAXIS_PATHS,
2841
2839
  PRAXIS_PROTOCOL_VERSION,
2842
2840
  PluresDBGenerator,
2841
+ PluresDBPraxisAdapter,
2843
2842
  PraxisDBStore,
2844
2843
  PraxisRegistry,
2845
2844
  PraxisSchemaRegistry,
@@ -2853,13 +2852,16 @@ export {
2853
2852
  canvasToSchema,
2854
2853
  canvasToYaml,
2855
2854
  createCanvasEditor,
2855
+ createReactiveEngine2 as createFrameworkAgnosticReactiveEngine,
2856
2856
  createInMemoryDB,
2857
2857
  createIntrospector,
2858
2858
  createMockTauriBridge,
2859
+ createPluresDB,
2859
2860
  createPluresDBAdapter,
2860
2861
  createPluresDBGenerator,
2861
2862
  createPraxisDBStore,
2862
2863
  createPraxisEngine,
2864
+ createReactiveEngine,
2863
2865
  createSchema,
2864
2866
  createSchemaRegistry,
2865
2867
  createSchemaTemplate,
@@ -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