@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.
- package/FRAMEWORK.md +106 -15
- package/README.md +275 -53
- package/dist/browser/adapter-TM4IS5KT.js +12 -0
- package/dist/browser/chunk-JQ64KMLN.js +141 -0
- package/dist/browser/chunk-LE2ZJYFC.js +154 -0
- package/dist/browser/chunk-VOMLVI6V.js +197 -0
- package/dist/browser/engine-YJZV4SLD.js +8 -0
- package/dist/browser/index.d.ts +300 -11
- package/dist/browser/index.js +334 -325
- package/dist/browser/integrations/svelte.d.ts +3 -1
- package/dist/browser/integrations/svelte.js +8 -0
- package/dist/browser/{engine-BjdqxeXG.d.ts → reactive-engine.svelte-C9OpcTHf.d.ts} +87 -1
- package/dist/node/adapter-K6DOX6XS.js +13 -0
- package/dist/node/chunk-JQ64KMLN.js +141 -0
- package/dist/node/chunk-LE2ZJYFC.js +154 -0
- package/dist/node/chunk-S54337I5.js +446 -0
- package/dist/node/chunk-VOMLVI6V.js +197 -0
- package/dist/node/cli/index.cjs +1444 -889
- package/dist/node/cli/index.js +9 -0
- package/dist/node/components/index.d.cts +2 -2
- package/dist/node/components/index.d.ts +2 -2
- package/dist/node/docs-JFNYTOJA.js +102 -0
- package/dist/node/engine-2DQBKBJC.js +9 -0
- package/dist/node/index.cjs +747 -234
- package/dist/node/index.d.cts +237 -15
- package/dist/node/index.d.ts +237 -15
- package/dist/node/index.js +339 -767
- package/dist/node/integrations/svelte.cjs +357 -2
- package/dist/node/integrations/svelte.d.cts +3 -1
- package/dist/node/integrations/svelte.d.ts +3 -1
- package/dist/node/integrations/svelte.js +7 -0
- package/dist/node/{engine-CVJobhHm.d.cts → reactive-engine.svelte-1M4m_C_v.d.cts} +87 -1
- package/dist/node/{engine-1iqLe6_P.d.ts → reactive-engine.svelte-ChNFn4Hj.d.ts} +87 -1
- package/dist/node/{terminal-adapter-XLtCjjb_.d.cts → terminal-adapter-CDzxoLKR.d.cts} +68 -1
- package/dist/node/{terminal-adapter-07HGftGQ.d.ts → terminal-adapter-CWka-yL8.d.ts} +68 -1
- package/package.json +3 -2
- package/src/__tests__/reactive-engine.test.ts +516 -0
- package/src/cli/commands/docs.ts +147 -0
- package/src/cli/index.ts +21 -0
- package/src/core/pluresdb/README.md +156 -0
- package/src/core/pluresdb/adapter.ts +165 -0
- package/src/core/pluresdb/index.ts +3 -3
- package/src/core/reactive-engine.svelte.ts +93 -19
- package/src/core/reactive-engine.ts +284 -22
- package/src/index.browser.ts +16 -0
- package/src/index.ts +16 -0
- package/src/integrations/pluresdb.ts +2 -2
- package/src/integrations/svelte.ts +8 -0
- package/src/integrations/unified.ts +350 -0
package/dist/browser/index.js
CHANGED
|
@@ -1,315 +1,233 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+
PraxisRegistry,
|
|
3
|
+
ReactiveLogicEngine,
|
|
4
|
+
createReactiveEngine
|
|
5
|
+
} from "./chunk-LE2ZJYFC.js";
|
|
6
|
+
import {
|
|
7
|
+
LogicEngine,
|
|
8
|
+
PRAXIS_PROTOCOL_VERSION,
|
|
9
|
+
createPraxisEngine
|
|
10
|
+
} from "./chunk-VOMLVI6V.js";
|
|
11
|
+
import {
|
|
12
|
+
InMemoryPraxisDB,
|
|
13
|
+
PluresDBPraxisAdapter,
|
|
14
|
+
createInMemoryDB,
|
|
15
|
+
createPluresDB
|
|
16
|
+
} from "./chunk-JQ64KMLN.js";
|
|
74
17
|
|
|
75
|
-
// src/core/engine.ts
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return [...value];
|
|
88
|
-
}
|
|
89
|
-
return { ...value };
|
|
90
|
-
}
|
|
91
|
-
var LogicEngine = class {
|
|
92
|
-
state;
|
|
93
|
-
registry;
|
|
18
|
+
// src/core/reactive-engine.ts
|
|
19
|
+
var ReactiveLogicEngine2 = class _ReactiveLogicEngine {
|
|
20
|
+
_state;
|
|
21
|
+
_subscribers = /* @__PURE__ */ new Set();
|
|
22
|
+
_contextProxy;
|
|
23
|
+
_factsProxy;
|
|
24
|
+
_metaProxy;
|
|
25
|
+
_batchDepth = 0;
|
|
26
|
+
_pendingNotification = false;
|
|
27
|
+
_proxyCache = /* @__PURE__ */ new WeakMap();
|
|
28
|
+
// Array methods that mutate the array
|
|
29
|
+
static ARRAY_MUTATORS = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"];
|
|
94
30
|
constructor(options) {
|
|
95
|
-
this.
|
|
96
|
-
this.state = {
|
|
31
|
+
this._state = {
|
|
97
32
|
context: options.initialContext,
|
|
98
33
|
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
|
|
34
|
+
meta: options.initialMeta ?? {}
|
|
112
35
|
};
|
|
36
|
+
this._contextProxy = this._createReactiveProxy(this._state.context);
|
|
37
|
+
this._factsProxy = this._createReactiveProxy(this._state.facts);
|
|
38
|
+
this._metaProxy = this._createReactiveProxy(this._state.meta);
|
|
113
39
|
}
|
|
114
40
|
/**
|
|
115
|
-
*
|
|
41
|
+
* Create a reactive proxy that notifies subscribers on changes.
|
|
42
|
+
* Uses a WeakMap cache to avoid creating multiple proxies for the same object.
|
|
116
43
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
44
|
+
_createReactiveProxy(target) {
|
|
45
|
+
const cached = this._proxyCache.get(target);
|
|
46
|
+
if (cached) {
|
|
47
|
+
return cached;
|
|
48
|
+
}
|
|
49
|
+
const self = this;
|
|
50
|
+
const handler = {
|
|
51
|
+
get(obj, prop) {
|
|
52
|
+
const value = Reflect.get(obj, prop);
|
|
53
|
+
if (value && typeof value === "object") {
|
|
54
|
+
return self._createReactiveProxy(value);
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(obj) && typeof value === "function") {
|
|
57
|
+
if (_ReactiveLogicEngine.ARRAY_MUTATORS.includes(prop)) {
|
|
58
|
+
return function(...args) {
|
|
59
|
+
const result = value.apply(obj, args);
|
|
60
|
+
self._notify();
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
},
|
|
67
|
+
set(obj, prop, value) {
|
|
68
|
+
const oldValue = obj[prop];
|
|
69
|
+
const result = Reflect.set(obj, prop, value);
|
|
70
|
+
if (oldValue !== value) {
|
|
71
|
+
self._notify();
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
},
|
|
75
|
+
deleteProperty(obj, prop) {
|
|
76
|
+
const result = Reflect.deleteProperty(obj, prop);
|
|
77
|
+
self._notify();
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
137
80
|
};
|
|
138
|
-
|
|
81
|
+
const proxy = new Proxy(target, handler);
|
|
82
|
+
this._proxyCache.set(target, proxy);
|
|
83
|
+
return proxy;
|
|
139
84
|
}
|
|
140
85
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* @param events Events to process
|
|
144
|
-
* @param config Step configuration
|
|
145
|
-
* @returns Result with new state and diagnostics
|
|
86
|
+
* Notify all subscribers of state changes
|
|
146
87
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
}
|
|
88
|
+
_notify() {
|
|
89
|
+
if (this._batchDepth > 0) {
|
|
90
|
+
this._pendingNotification = true;
|
|
91
|
+
return;
|
|
171
92
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
facts:
|
|
93
|
+
const currentState = {
|
|
94
|
+
context: this._contextProxy,
|
|
95
|
+
facts: this._factsProxy,
|
|
96
|
+
meta: this._metaProxy
|
|
175
97
|
};
|
|
176
|
-
|
|
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
|
-
}
|
|
98
|
+
this._subscribers.forEach((callback) => {
|
|
186
99
|
try {
|
|
187
|
-
|
|
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
|
-
}
|
|
100
|
+
callback(currentState);
|
|
201
101
|
} catch (error) {
|
|
202
|
-
|
|
203
|
-
kind: "constraint-violation",
|
|
204
|
-
message: `Error checking constraint "${constraintId}": ${error instanceof Error ? error.message : String(error)}`,
|
|
205
|
-
data: { constraintId, error }
|
|
206
|
-
});
|
|
102
|
+
console.error("Error in reactive engine subscriber:", error);
|
|
207
103
|
}
|
|
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
|
-
};
|
|
104
|
+
});
|
|
247
105
|
}
|
|
248
106
|
/**
|
|
249
|
-
*
|
|
107
|
+
* Get the full state object
|
|
250
108
|
*/
|
|
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
109
|
get state() {
|
|
274
|
-
return
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
constructor(options) {
|
|
280
|
-
this.state.context = options.initialContext;
|
|
281
|
-
this.state.facts = options.initialFacts ?? [];
|
|
282
|
-
this.state.meta = options.initialMeta ?? {};
|
|
110
|
+
return {
|
|
111
|
+
context: this._contextProxy,
|
|
112
|
+
facts: this._factsProxy,
|
|
113
|
+
meta: this._metaProxy
|
|
114
|
+
};
|
|
283
115
|
}
|
|
284
116
|
/**
|
|
285
|
-
* Access the reactive context
|
|
286
|
-
*
|
|
117
|
+
* Access the reactive context.
|
|
118
|
+
* Changes to this object will trigger subscriber notifications.
|
|
287
119
|
*/
|
|
288
120
|
get context() {
|
|
289
|
-
return this.
|
|
121
|
+
return this._contextProxy;
|
|
290
122
|
}
|
|
291
123
|
/**
|
|
292
124
|
* Access the reactive facts list.
|
|
125
|
+
* Changes to this array will trigger subscriber notifications.
|
|
293
126
|
*/
|
|
294
127
|
get facts() {
|
|
295
|
-
return this.
|
|
128
|
+
return this._factsProxy;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Access the reactive metadata.
|
|
132
|
+
* Changes to this object will trigger subscriber notifications.
|
|
133
|
+
*/
|
|
134
|
+
get meta() {
|
|
135
|
+
return this._metaProxy;
|
|
296
136
|
}
|
|
297
137
|
/**
|
|
298
138
|
* Apply a mutation to the state.
|
|
299
139
|
* This is the "Action" or "Rule" equivalent.
|
|
140
|
+
* Mutations are batched - notifications only happen once per apply call.
|
|
300
141
|
*
|
|
301
142
|
* @param mutator A function that receives the state and modifies it.
|
|
302
143
|
*/
|
|
303
144
|
apply(mutator) {
|
|
304
|
-
|
|
145
|
+
this._batchDepth++;
|
|
146
|
+
try {
|
|
147
|
+
mutator({
|
|
148
|
+
context: this._contextProxy,
|
|
149
|
+
facts: this._factsProxy,
|
|
150
|
+
meta: this._metaProxy
|
|
151
|
+
});
|
|
152
|
+
} finally {
|
|
153
|
+
this._batchDepth--;
|
|
154
|
+
if (this._batchDepth === 0 && this._pendingNotification) {
|
|
155
|
+
this._pendingNotification = false;
|
|
156
|
+
this._notify();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
305
159
|
}
|
|
306
160
|
/**
|
|
307
|
-
*
|
|
161
|
+
* Subscribe to state changes.
|
|
162
|
+
* Returns an unsubscribe function.
|
|
163
|
+
*
|
|
164
|
+
* @param callback Function to call when state changes
|
|
165
|
+
* @returns Unsubscribe function
|
|
308
166
|
*/
|
|
309
|
-
|
|
310
|
-
|
|
167
|
+
subscribe(callback) {
|
|
168
|
+
this._subscribers.add(callback);
|
|
169
|
+
try {
|
|
170
|
+
callback({
|
|
171
|
+
context: this._contextProxy,
|
|
172
|
+
facts: this._factsProxy,
|
|
173
|
+
meta: this._metaProxy
|
|
174
|
+
});
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error("Error in reactive engine subscriber:", error);
|
|
177
|
+
}
|
|
178
|
+
return () => {
|
|
179
|
+
this._subscribers.delete(callback);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Create a derived/computed value from the state.
|
|
184
|
+
* The selector function will be called whenever the state changes.
|
|
185
|
+
*
|
|
186
|
+
* @param selector Function to extract derived value from state
|
|
187
|
+
* @returns Object with subscribe method for reactive updates
|
|
188
|
+
*/
|
|
189
|
+
$derived(selector) {
|
|
190
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
191
|
+
let currentValue = selector({
|
|
192
|
+
context: this._contextProxy,
|
|
193
|
+
facts: this._factsProxy,
|
|
194
|
+
meta: this._metaProxy
|
|
195
|
+
});
|
|
196
|
+
this.subscribe(() => {
|
|
197
|
+
const newValue = selector({
|
|
198
|
+
context: this._contextProxy,
|
|
199
|
+
facts: this._factsProxy,
|
|
200
|
+
meta: this._metaProxy
|
|
201
|
+
});
|
|
202
|
+
if (newValue !== currentValue) {
|
|
203
|
+
currentValue = newValue;
|
|
204
|
+
subscribers.forEach((callback) => {
|
|
205
|
+
try {
|
|
206
|
+
callback(currentValue);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error("Error in derived value subscriber:", error);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
subscribe: (callback) => {
|
|
215
|
+
subscribers.add(callback);
|
|
216
|
+
try {
|
|
217
|
+
callback(currentValue);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error("Error in derived value subscriber:", error);
|
|
220
|
+
}
|
|
221
|
+
return () => {
|
|
222
|
+
subscribers.delete(callback);
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
};
|
|
311
226
|
}
|
|
312
227
|
};
|
|
228
|
+
function createReactiveEngine2(options) {
|
|
229
|
+
return new ReactiveLogicEngine2(options);
|
|
230
|
+
}
|
|
313
231
|
|
|
314
232
|
// src/core/actors.ts
|
|
315
233
|
var ActorManager = class {
|
|
@@ -398,7 +316,7 @@ var ActorManager = class {
|
|
|
398
316
|
/**
|
|
399
317
|
* Notify active actors of a state change
|
|
400
318
|
*/
|
|
401
|
-
async notifyStateChange(
|
|
319
|
+
async notifyStateChange(state) {
|
|
402
320
|
if (!this.engine) {
|
|
403
321
|
return;
|
|
404
322
|
}
|
|
@@ -406,7 +324,7 @@ var ActorManager = class {
|
|
|
406
324
|
for (const actorId of this.activeActors) {
|
|
407
325
|
const actor = this.actors.get(actorId);
|
|
408
326
|
if (actor?.onStateChange) {
|
|
409
|
-
const result = actor.onStateChange(
|
|
327
|
+
const result = actor.onStateChange(state, this.engine);
|
|
410
328
|
if (result instanceof Promise) {
|
|
411
329
|
promises.push(result);
|
|
412
330
|
}
|
|
@@ -1147,14 +1065,14 @@ var PraxisDBStore = class {
|
|
|
1147
1065
|
async checkConstraints(newFacts) {
|
|
1148
1066
|
const constraints = this.registry.getAllConstraints();
|
|
1149
1067
|
const errors = [];
|
|
1150
|
-
const
|
|
1068
|
+
const state = {
|
|
1151
1069
|
context: this.context,
|
|
1152
1070
|
facts: newFacts,
|
|
1153
1071
|
meta: {}
|
|
1154
1072
|
};
|
|
1155
1073
|
for (const constraint of constraints) {
|
|
1156
1074
|
try {
|
|
1157
|
-
const result = constraint.impl(
|
|
1075
|
+
const result = constraint.impl(state);
|
|
1158
1076
|
if (result === false) {
|
|
1159
1077
|
errors.push(`Constraint "${constraint.id}" violated`);
|
|
1160
1078
|
} else if (typeof result === "string") {
|
|
@@ -1188,7 +1106,7 @@ var PraxisDBStore = class {
|
|
|
1188
1106
|
*/
|
|
1189
1107
|
async triggerRulesForEvents(events) {
|
|
1190
1108
|
const rules = this.registry.getAllRules();
|
|
1191
|
-
const
|
|
1109
|
+
const state = {
|
|
1192
1110
|
context: this.context,
|
|
1193
1111
|
facts: [],
|
|
1194
1112
|
meta: {}
|
|
@@ -1196,7 +1114,7 @@ var PraxisDBStore = class {
|
|
|
1196
1114
|
const derivedFacts = [];
|
|
1197
1115
|
for (const rule of rules) {
|
|
1198
1116
|
try {
|
|
1199
|
-
const facts = rule.impl(
|
|
1117
|
+
const facts = rule.impl(state, events);
|
|
1200
1118
|
derivedFacts.push(...facts);
|
|
1201
1119
|
} catch (error) {
|
|
1202
1120
|
this.onRuleError(rule.id, error);
|
|
@@ -1238,54 +1156,6 @@ function createPraxisDBStore(db, registry, initialContext, onRuleError) {
|
|
|
1238
1156
|
return new PraxisDBStore({ db, registry, initialContext, onRuleError });
|
|
1239
1157
|
}
|
|
1240
1158
|
|
|
1241
|
-
// src/core/pluresdb/adapter.ts
|
|
1242
|
-
var InMemoryPraxisDB = class {
|
|
1243
|
-
store = /* @__PURE__ */ new Map();
|
|
1244
|
-
watchers = /* @__PURE__ */ new Map();
|
|
1245
|
-
async get(key) {
|
|
1246
|
-
return this.store.get(key);
|
|
1247
|
-
}
|
|
1248
|
-
async set(key, value) {
|
|
1249
|
-
this.store.set(key, value);
|
|
1250
|
-
const keyWatchers = this.watchers.get(key);
|
|
1251
|
-
if (keyWatchers) {
|
|
1252
|
-
for (const callback of keyWatchers) {
|
|
1253
|
-
callback(value);
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
watch(key, callback) {
|
|
1258
|
-
if (!this.watchers.has(key)) {
|
|
1259
|
-
this.watchers.set(key, /* @__PURE__ */ new Set());
|
|
1260
|
-
}
|
|
1261
|
-
const watchers = this.watchers.get(key);
|
|
1262
|
-
const wrappedCallback = (val) => callback(val);
|
|
1263
|
-
watchers.add(wrappedCallback);
|
|
1264
|
-
return () => {
|
|
1265
|
-
watchers.delete(wrappedCallback);
|
|
1266
|
-
if (watchers.size === 0) {
|
|
1267
|
-
this.watchers.delete(key);
|
|
1268
|
-
}
|
|
1269
|
-
};
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Get all keys (for testing/debugging)
|
|
1273
|
-
*/
|
|
1274
|
-
keys() {
|
|
1275
|
-
return Array.from(this.store.keys());
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Clear all data (for testing)
|
|
1279
|
-
*/
|
|
1280
|
-
clear() {
|
|
1281
|
-
this.store.clear();
|
|
1282
|
-
this.watchers.clear();
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
1285
|
-
function createInMemoryDB() {
|
|
1286
|
-
return new InMemoryPraxisDB();
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
1159
|
// src/core/pluresdb/schema-registry.ts
|
|
1290
1160
|
function getSchemaPath(schemaName) {
|
|
1291
1161
|
return `${PRAXIS_PATHS.SCHEMAS}/${schemaName}`;
|
|
@@ -2733,8 +2603,8 @@ function createMockTauriBridge() {
|
|
|
2733
2603
|
function createTauriPraxisAdapter(options) {
|
|
2734
2604
|
const { bridge, statePath = "praxis-state.json", eventsPath = "praxis-events.json" } = options;
|
|
2735
2605
|
return {
|
|
2736
|
-
async saveState(
|
|
2737
|
-
const json = JSON.stringify(
|
|
2606
|
+
async saveState(state) {
|
|
2607
|
+
const json = JSON.stringify(state, null, 2);
|
|
2738
2608
|
await bridge.fs.writeTextFile(statePath, json);
|
|
2739
2609
|
},
|
|
2740
2610
|
async loadState() {
|
|
@@ -2833,19 +2703,154 @@ function generateTauriConfig(config) {
|
|
|
2833
2703
|
plugins: Object.fromEntries((config.plugins || []).map((p) => [p.name, p.config || {}]))
|
|
2834
2704
|
};
|
|
2835
2705
|
}
|
|
2706
|
+
|
|
2707
|
+
// src/integrations/unified.ts
|
|
2708
|
+
async function createUnifiedApp(config) {
|
|
2709
|
+
const { createPraxisEngine: createPraxisEngine2 } = await import("./engine-YJZV4SLD.js");
|
|
2710
|
+
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-TM4IS5KT.js");
|
|
2711
|
+
const db = config.db || createInMemoryDB2();
|
|
2712
|
+
const pluresdb = createPluresDBAdapter({
|
|
2713
|
+
db,
|
|
2714
|
+
registry: config.registry,
|
|
2715
|
+
initialContext: config.initialContext
|
|
2716
|
+
});
|
|
2717
|
+
const engine = createPraxisEngine2({
|
|
2718
|
+
initialContext: config.initialContext,
|
|
2719
|
+
registry: config.registry
|
|
2720
|
+
});
|
|
2721
|
+
pluresdb.attachEngine(engine);
|
|
2722
|
+
const disposers = [];
|
|
2723
|
+
let unum;
|
|
2724
|
+
let channel;
|
|
2725
|
+
if (config.enableUnum) {
|
|
2726
|
+
const fullIdentity = config.unumIdentity ? {
|
|
2727
|
+
...config.unumIdentity,
|
|
2728
|
+
id: generateId(),
|
|
2729
|
+
createdAt: Date.now()
|
|
2730
|
+
} : void 0;
|
|
2731
|
+
unum = await createUnumAdapter({
|
|
2732
|
+
db,
|
|
2733
|
+
identity: fullIdentity,
|
|
2734
|
+
realtime: true
|
|
2735
|
+
});
|
|
2736
|
+
channel = await unum.createChannel(
|
|
2737
|
+
config.unumIdentity?.name || "praxis-app",
|
|
2738
|
+
[]
|
|
2739
|
+
);
|
|
2740
|
+
const unumDisposer = attachUnumToEngine(engine, unum, channel.id);
|
|
2741
|
+
disposers.push(unumDisposer);
|
|
2742
|
+
}
|
|
2743
|
+
let docs;
|
|
2744
|
+
let generateDocs2;
|
|
2745
|
+
if (config.enableDocs && config.docsConfig) {
|
|
2746
|
+
docs = createStateDocsGenerator({
|
|
2747
|
+
projectTitle: config.docsConfig.projectTitle,
|
|
2748
|
+
target: config.docsConfig.target || "./docs"
|
|
2749
|
+
});
|
|
2750
|
+
generateDocs2 = () => {
|
|
2751
|
+
const module = {
|
|
2752
|
+
rules: config.registry.getAllRules(),
|
|
2753
|
+
constraints: config.registry.getAllConstraints()
|
|
2754
|
+
};
|
|
2755
|
+
return docs.generateFromModule(module);
|
|
2756
|
+
};
|
|
2757
|
+
}
|
|
2758
|
+
let canvas;
|
|
2759
|
+
if (config.schema) {
|
|
2760
|
+
canvas = schemaToCanvas(config.schema, { layout: "hierarchical" });
|
|
2761
|
+
}
|
|
2762
|
+
return {
|
|
2763
|
+
engine,
|
|
2764
|
+
pluresdb,
|
|
2765
|
+
unum,
|
|
2766
|
+
channel,
|
|
2767
|
+
docs,
|
|
2768
|
+
canvas,
|
|
2769
|
+
generateDocs: generateDocs2,
|
|
2770
|
+
dispose: () => {
|
|
2771
|
+
pluresdb.dispose();
|
|
2772
|
+
if (unum) {
|
|
2773
|
+
unum.disconnect().catch((err) => {
|
|
2774
|
+
console.warn("Warning: Error during Unum disconnect:", err);
|
|
2775
|
+
});
|
|
2776
|
+
}
|
|
2777
|
+
for (const disposer of disposers) {
|
|
2778
|
+
disposer();
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
async function attachAllIntegrations(engine, registry, options = {}) {
|
|
2784
|
+
const { createInMemoryDB: createInMemoryDB2 } = await import("./adapter-TM4IS5KT.js");
|
|
2785
|
+
const db = options.db || createInMemoryDB2();
|
|
2786
|
+
const pluresdb = createPluresDBAdapter({
|
|
2787
|
+
db,
|
|
2788
|
+
registry,
|
|
2789
|
+
initialContext: engine.getContext()
|
|
2790
|
+
});
|
|
2791
|
+
pluresdb.attachEngine(engine);
|
|
2792
|
+
const disposers = [];
|
|
2793
|
+
let unum;
|
|
2794
|
+
let channel;
|
|
2795
|
+
if (options.enableUnum) {
|
|
2796
|
+
const fullIdentity = options.unumIdentity ? {
|
|
2797
|
+
...options.unumIdentity,
|
|
2798
|
+
id: generateId(),
|
|
2799
|
+
createdAt: Date.now()
|
|
2800
|
+
} : void 0;
|
|
2801
|
+
unum = await createUnumAdapter({
|
|
2802
|
+
db,
|
|
2803
|
+
identity: fullIdentity,
|
|
2804
|
+
realtime: true
|
|
2805
|
+
});
|
|
2806
|
+
channel = await unum.createChannel(
|
|
2807
|
+
options.unumIdentity?.name || "praxis-app",
|
|
2808
|
+
[]
|
|
2809
|
+
);
|
|
2810
|
+
const unumDisposer = attachUnumToEngine(engine, unum, channel.id);
|
|
2811
|
+
disposers.push(unumDisposer);
|
|
2812
|
+
}
|
|
2813
|
+
let docs;
|
|
2814
|
+
if (options.enableDocs && options.docsConfig) {
|
|
2815
|
+
docs = createStateDocsGenerator({
|
|
2816
|
+
projectTitle: options.docsConfig.projectTitle,
|
|
2817
|
+
target: options.docsConfig.target || "./docs"
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
return {
|
|
2821
|
+
pluresdb,
|
|
2822
|
+
unum,
|
|
2823
|
+
channel,
|
|
2824
|
+
docs,
|
|
2825
|
+
dispose: () => {
|
|
2826
|
+
pluresdb.dispose();
|
|
2827
|
+
if (unum) {
|
|
2828
|
+
unum.disconnect().catch((err) => {
|
|
2829
|
+
console.warn("Warning: Error during Unum disconnect:", err);
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2832
|
+
for (const disposer of disposers) {
|
|
2833
|
+
disposer();
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2836
2838
|
export {
|
|
2837
2839
|
ActorManager,
|
|
2840
|
+
ReactiveLogicEngine2 as FrameworkAgnosticReactiveEngine,
|
|
2838
2841
|
InMemoryPraxisDB,
|
|
2839
2842
|
LogicEngine,
|
|
2840
2843
|
PRAXIS_PATHS,
|
|
2841
2844
|
PRAXIS_PROTOCOL_VERSION,
|
|
2842
2845
|
PluresDBGenerator,
|
|
2846
|
+
PluresDBPraxisAdapter,
|
|
2843
2847
|
PraxisDBStore,
|
|
2844
2848
|
PraxisRegistry,
|
|
2845
2849
|
PraxisSchemaRegistry,
|
|
2846
2850
|
ReactiveLogicEngine,
|
|
2847
2851
|
RegistryIntrospector,
|
|
2848
2852
|
StateDocsGenerator,
|
|
2853
|
+
attachAllIntegrations,
|
|
2849
2854
|
attachTauriToEngine,
|
|
2850
2855
|
attachToEngine,
|
|
2851
2856
|
attachUnumToEngine,
|
|
@@ -2853,19 +2858,23 @@ export {
|
|
|
2853
2858
|
canvasToSchema,
|
|
2854
2859
|
canvasToYaml,
|
|
2855
2860
|
createCanvasEditor,
|
|
2861
|
+
createReactiveEngine2 as createFrameworkAgnosticReactiveEngine,
|
|
2856
2862
|
createInMemoryDB,
|
|
2857
2863
|
createIntrospector,
|
|
2858
2864
|
createMockTauriBridge,
|
|
2865
|
+
createPluresDB,
|
|
2859
2866
|
createPluresDBAdapter,
|
|
2860
2867
|
createPluresDBGenerator,
|
|
2861
2868
|
createPraxisDBStore,
|
|
2862
2869
|
createPraxisEngine,
|
|
2870
|
+
createReactiveEngine,
|
|
2863
2871
|
createSchema,
|
|
2864
2872
|
createSchemaRegistry,
|
|
2865
2873
|
createSchemaTemplate,
|
|
2866
2874
|
createStateDocsGenerator,
|
|
2867
2875
|
createTauriPraxisAdapter,
|
|
2868
2876
|
createTimerActor,
|
|
2877
|
+
createUnifiedApp,
|
|
2869
2878
|
createUnumAdapter,
|
|
2870
2879
|
defineConstraint,
|
|
2871
2880
|
defineEvent,
|