@plures/praxis 1.3.0 → 1.4.4
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/dist/browser/{chunk-N63K4KWS.js → chunk-4IRUGWR3.js} +1 -1
- package/dist/browser/chunk-6SJ44Q64.js +473 -0
- package/dist/browser/chunk-BQOYZBWA.js +282 -0
- package/dist/browser/chunk-IG5BJ2MT.js +91 -0
- package/dist/browser/{chunk-MJK3IYTJ.js → chunk-JZDJU2DO.js} +4 -84
- package/dist/browser/chunk-ZEW4LJAJ.js +353 -0
- package/dist/browser/{engine-YIEGSX7U.js → engine-3B5WJPGT.js} +2 -1
- package/dist/browser/expectations/index.d.ts +180 -0
- package/dist/browser/expectations/index.js +14 -0
- package/dist/browser/factory/index.d.ts +149 -0
- package/dist/browser/factory/index.js +15 -0
- package/dist/browser/index.d.ts +274 -3
- package/dist/browser/index.js +407 -54
- package/dist/browser/integrations/svelte.d.ts +3 -2
- package/dist/browser/integrations/svelte.js +3 -2
- package/dist/browser/project/index.d.ts +176 -0
- package/dist/browser/project/index.js +19 -0
- package/dist/browser/reactive-engine.svelte-DgVTqHLc.d.ts +223 -0
- package/dist/browser/{reactive-engine.svelte-DjynI82A.d.ts → rules-i1LHpnGd.d.ts} +13 -221
- package/dist/node/chunk-2IUFZBH3.js +87 -0
- package/dist/node/{chunk-WZ6B3LZ6.js → chunk-7CSWBDFL.js} +3 -56
- package/dist/node/chunk-AZLNISFI.js +1690 -0
- package/dist/node/chunk-IG5BJ2MT.js +91 -0
- package/dist/node/{chunk-KMJWAFZV.js → chunk-JZDJU2DO.js} +4 -89
- package/dist/node/chunk-PGVSB6NR.js +59 -0
- package/dist/node/{chunk-5JQJZADT.js → chunk-ZO2LU4G4.js} +4 -4
- package/dist/node/cli/index.cjs +1126 -211
- package/dist/node/cli/index.js +21 -2
- package/dist/node/{engine-FEN5IYZ5.js → engine-VFHCIEM4.js} +2 -1
- package/dist/node/index.cjs +5623 -2765
- package/dist/node/index.d.cts +1181 -1
- package/dist/node/index.d.ts +1181 -1
- package/dist/node/index.js +1646 -79
- package/dist/node/integrations/svelte.js +4 -3
- package/dist/node/{reverse-W7THPV45.js → reverse-YD3CWIGM.js} +3 -2
- package/dist/node/rules-4DAJ4Z4N.js +7 -0
- package/dist/node/server-FKLVY57V.js +363 -0
- package/dist/node/{validate-EN3M4FUR.js → validate-5PSWJTIC.js} +5 -3
- package/package.json +50 -3
- package/src/__tests__/chronos-project.test.ts +799 -0
- package/src/__tests__/decision-ledger.test.ts +857 -402
- package/src/__tests__/expectations.test.ts +364 -0
- package/src/__tests__/factory.test.ts +426 -0
- package/src/__tests__/mcp-server.test.ts +310 -0
- package/src/__tests__/project.test.ts +396 -0
- package/src/chronos/diff.ts +336 -0
- package/src/chronos/hooks.ts +227 -0
- package/src/chronos/index.ts +83 -0
- package/src/chronos/project-chronicle.ts +198 -0
- package/src/chronos/timeline.ts +152 -0
- package/src/cli/index.ts +28 -0
- package/src/decision-ledger/analyzer-types.ts +280 -0
- package/src/decision-ledger/analyzer.ts +518 -0
- package/src/decision-ledger/contract-verification.ts +456 -0
- package/src/decision-ledger/derivation.ts +158 -0
- package/src/decision-ledger/index.ts +59 -0
- package/src/decision-ledger/report.ts +378 -0
- package/src/decision-ledger/suggestions.ts +287 -0
- package/src/expectations/expectations.ts +471 -0
- package/src/expectations/index.ts +29 -0
- package/src/expectations/types.ts +95 -0
- package/src/factory/factory.ts +634 -0
- package/src/factory/index.ts +27 -0
- package/src/factory/types.ts +64 -0
- package/src/index.browser.ts +83 -0
- package/src/index.ts +134 -0
- package/src/mcp/index.ts +33 -0
- package/src/mcp/server.ts +485 -0
- package/src/mcp/types.ts +161 -0
- package/src/project/index.ts +31 -0
- package/src/project/project.ts +423 -0
- package/src/project/types.ts +87 -0
- package/dist/node/chunk-PTH6MD6P.js +0 -487
- /package/dist/node/{chunk-R2PSBPKQ.js → chunk-TEMFJOIH.js} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ReactiveLogicEngine,
|
|
3
3
|
createReactiveEngine
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-4IRUGWR3.js";
|
|
5
|
+
import "../chunk-JZDJU2DO.js";
|
|
6
|
+
import "../chunk-IG5BJ2MT.js";
|
|
6
7
|
|
|
7
8
|
// src/integrations/svelte.ts
|
|
8
9
|
function createPraxisStore(engine) {
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { j as PraxisModule } from '../rules-i1LHpnGd.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Praxis Project Logic — Types
|
|
5
|
+
*
|
|
6
|
+
* Types for developer workflow rules: gates, semver contracts,
|
|
7
|
+
* commit generation, and branch management.
|
|
8
|
+
*/
|
|
9
|
+
type GateStatus = 'open' | 'closed' | 'blocked';
|
|
10
|
+
interface GateConfig {
|
|
11
|
+
/** Expectations that must be satisfied for the gate to open */
|
|
12
|
+
expects: string[];
|
|
13
|
+
/** Action when gate is satisfied */
|
|
14
|
+
onSatisfied?: string;
|
|
15
|
+
/** Action when gate is violated */
|
|
16
|
+
onViolation?: string;
|
|
17
|
+
}
|
|
18
|
+
interface GateState {
|
|
19
|
+
name: string;
|
|
20
|
+
status: GateStatus;
|
|
21
|
+
/** Which expectations are satisfied */
|
|
22
|
+
satisfied: string[];
|
|
23
|
+
/** Which expectations are not satisfied */
|
|
24
|
+
unsatisfied: string[];
|
|
25
|
+
/** Timestamp of last status change */
|
|
26
|
+
lastChanged: number;
|
|
27
|
+
}
|
|
28
|
+
interface SemverContractConfig {
|
|
29
|
+
/** Files/sources that contain version strings */
|
|
30
|
+
sources: string[];
|
|
31
|
+
/** Invariants about version consistency */
|
|
32
|
+
invariants: string[];
|
|
33
|
+
}
|
|
34
|
+
interface SemverReport {
|
|
35
|
+
/** Whether all sources have consistent versions */
|
|
36
|
+
consistent: boolean;
|
|
37
|
+
/** Version found in each source */
|
|
38
|
+
versions: Record<string, string>;
|
|
39
|
+
/** Invariant violations */
|
|
40
|
+
violations: string[];
|
|
41
|
+
}
|
|
42
|
+
interface PraxisDiff {
|
|
43
|
+
/** Rules added since last commit */
|
|
44
|
+
rulesAdded: string[];
|
|
45
|
+
/** Rules removed */
|
|
46
|
+
rulesRemoved: string[];
|
|
47
|
+
/** Rules modified */
|
|
48
|
+
rulesModified: string[];
|
|
49
|
+
/** Contracts added */
|
|
50
|
+
contractsAdded: string[];
|
|
51
|
+
/** Contracts removed */
|
|
52
|
+
contractsRemoved: string[];
|
|
53
|
+
/** Expectations added */
|
|
54
|
+
expectationsAdded: string[];
|
|
55
|
+
/** Expectations removed */
|
|
56
|
+
expectationsRemoved: string[];
|
|
57
|
+
/** Gate state changes */
|
|
58
|
+
gateChanges: Array<{
|
|
59
|
+
gate: string;
|
|
60
|
+
from: GateStatus;
|
|
61
|
+
to: GateStatus;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
interface BranchRulesConfig {
|
|
65
|
+
/** Naming convention pattern (e.g., 'feat/{name}', 'fix/{issue}') */
|
|
66
|
+
naming: string;
|
|
67
|
+
/** Conditions required for merge */
|
|
68
|
+
mergeConditions: string[];
|
|
69
|
+
}
|
|
70
|
+
interface PredefinedGateConfig {
|
|
71
|
+
/** Whether to enable this gate */
|
|
72
|
+
enabled?: boolean;
|
|
73
|
+
/** Custom expectations to add */
|
|
74
|
+
additionalExpects?: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Praxis Project Logic
|
|
79
|
+
*
|
|
80
|
+
* Developer workflow rules: gates, semver contracts, commit message
|
|
81
|
+
* generation from behavioral deltas, and branch management.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { defineGate, semverContract, commitFromState } from '@plures/praxis/project';
|
|
86
|
+
*
|
|
87
|
+
* const testGate = defineGate('test', {
|
|
88
|
+
* expects: ['all-tests-pass', 'no-type-errors'],
|
|
89
|
+
* onSatisfied: 'merge-allowed',
|
|
90
|
+
* onViolation: 'merge-blocked',
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* const diff = { rulesAdded: ['auth/login'], ... };
|
|
94
|
+
* const message = commitFromState(diff);
|
|
95
|
+
* // → "feat(rules): add auth/login rule"
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Context type for gates. Apps extend their context with gate state.
|
|
101
|
+
*/
|
|
102
|
+
interface GateContext {
|
|
103
|
+
gates?: Record<string, GateState>;
|
|
104
|
+
expectations?: Record<string, boolean>;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Define a feature gate — a condition that must be satisfied before
|
|
108
|
+
* proceeding with a workflow step (deploy, merge, release, etc.).
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* const testGate = defineGate('test', {
|
|
113
|
+
* expects: ['all-tests-pass', 'no-type-errors'],
|
|
114
|
+
* onSatisfied: 'deploy-allowed',
|
|
115
|
+
* onViolation: 'deploy-blocked',
|
|
116
|
+
* });
|
|
117
|
+
* registry.registerModule(testGate);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
declare function defineGate(name: string, config: GateConfig): PraxisModule<GateContext>;
|
|
121
|
+
/**
|
|
122
|
+
* Create a semver contract module that checks version consistency
|
|
123
|
+
* across multiple sources (package.json, Cargo.toml, etc.).
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const version = semverContract({
|
|
128
|
+
* sources: ['package.json', 'src/version.ts', 'README.md'],
|
|
129
|
+
* invariants: ['All sources must have the same version'],
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare function semverContract(config: SemverContractConfig): PraxisModule;
|
|
134
|
+
/**
|
|
135
|
+
* Generate a conventional commit message from a behavioral delta.
|
|
136
|
+
*
|
|
137
|
+
* Unlike file-based commit messages, this describes WHAT behavioral
|
|
138
|
+
* changes occurred — rule additions, contract changes, expectation shifts.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* const msg = commitFromState({
|
|
143
|
+
* rulesAdded: ['auth/login', 'auth/logout'],
|
|
144
|
+
* contractsAdded: ['auth/login'],
|
|
145
|
+
* ...empty
|
|
146
|
+
* });
|
|
147
|
+
* // → "feat(rules): add auth/login, auth/logout\n\nContracts added: auth/login"
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
declare function commitFromState(diff: PraxisDiff): string;
|
|
151
|
+
/**
|
|
152
|
+
* Create branch management rules.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* const branches = branchRules({
|
|
157
|
+
* naming: 'feat/{name}',
|
|
158
|
+
* mergeConditions: ['tests-pass', 'review-approved'],
|
|
159
|
+
* });
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
declare function branchRules(config: BranchRulesConfig): PraxisModule;
|
|
163
|
+
/**
|
|
164
|
+
* Create a lint gate — blocks workflow until linting passes.
|
|
165
|
+
*/
|
|
166
|
+
declare function lintGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
167
|
+
/**
|
|
168
|
+
* Create a format gate — blocks workflow until formatting is correct.
|
|
169
|
+
*/
|
|
170
|
+
declare function formatGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
171
|
+
/**
|
|
172
|
+
* Create an expectation gate — blocks workflow until expectations are verified.
|
|
173
|
+
*/
|
|
174
|
+
declare function expectationGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
175
|
+
|
|
176
|
+
export { type BranchRulesConfig, type GateConfig, type GateState, type GateStatus, type PraxisDiff, type PredefinedGateConfig, type SemverContractConfig, type SemverReport, branchRules, commitFromState, defineGate, expectationGate, formatGate, lintGate, semverContract };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
branchRules,
|
|
3
|
+
commitFromState,
|
|
4
|
+
defineGate,
|
|
5
|
+
expectationGate,
|
|
6
|
+
formatGate,
|
|
7
|
+
lintGate,
|
|
8
|
+
semverContract
|
|
9
|
+
} from "../chunk-BQOYZBWA.js";
|
|
10
|
+
import "../chunk-IG5BJ2MT.js";
|
|
11
|
+
export {
|
|
12
|
+
branchRules,
|
|
13
|
+
commitFromState,
|
|
14
|
+
defineGate,
|
|
15
|
+
expectationGate,
|
|
16
|
+
formatGate,
|
|
17
|
+
lintGate,
|
|
18
|
+
semverContract
|
|
19
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { b as PraxisRegistry, c as PraxisFact, P as PraxisState, a as PraxisEvent, d as PraxisStepResult, e as PraxisStepConfig, f as PraxisDiagnostics } from './rules-i1LHpnGd.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Praxis Logic Engine
|
|
5
|
+
*
|
|
6
|
+
* The logic engine manages state, processes events through rules,
|
|
7
|
+
* checks constraints, and provides a strongly-typed API for application logic.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Options for creating a Praxis engine
|
|
12
|
+
*/
|
|
13
|
+
interface PraxisEngineOptions<TContext = unknown> {
|
|
14
|
+
/** Initial context */
|
|
15
|
+
initialContext: TContext;
|
|
16
|
+
/** Registry of rules and constraints */
|
|
17
|
+
registry: PraxisRegistry<TContext>;
|
|
18
|
+
/** Initial facts (optional) */
|
|
19
|
+
initialFacts?: PraxisFact[];
|
|
20
|
+
/** Initial metadata (optional) */
|
|
21
|
+
initialMeta?: Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Fact deduplication strategy (default: 'last-write-wins').
|
|
24
|
+
*
|
|
25
|
+
* - 'none': facts accumulate without dedup (original behavior)
|
|
26
|
+
* - 'last-write-wins': only keep the latest fact per tag (most common)
|
|
27
|
+
* - 'append': keep all facts but cap at maxFacts
|
|
28
|
+
*/
|
|
29
|
+
factDedup?: 'none' | 'last-write-wins' | 'append';
|
|
30
|
+
/**
|
|
31
|
+
* Maximum number of facts to retain (default: 1000).
|
|
32
|
+
* When exceeded, oldest facts are evicted (FIFO).
|
|
33
|
+
* Set to 0 for unlimited (not recommended).
|
|
34
|
+
*/
|
|
35
|
+
maxFacts?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The Praxis Logic Engine
|
|
39
|
+
*
|
|
40
|
+
* Manages application logic through facts, events, rules, and constraints.
|
|
41
|
+
* The engine is strongly typed and functional - all state updates are immutable.
|
|
42
|
+
*/
|
|
43
|
+
declare class LogicEngine<TContext = unknown> {
|
|
44
|
+
private state;
|
|
45
|
+
private readonly registry;
|
|
46
|
+
private readonly factDedup;
|
|
47
|
+
private readonly maxFacts;
|
|
48
|
+
constructor(options: PraxisEngineOptions<TContext>);
|
|
49
|
+
/**
|
|
50
|
+
* Get the current state (immutable copy)
|
|
51
|
+
*/
|
|
52
|
+
getState(): Readonly<PraxisState & {
|
|
53
|
+
context: TContext;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Get the current context
|
|
57
|
+
*/
|
|
58
|
+
getContext(): TContext;
|
|
59
|
+
/**
|
|
60
|
+
* Get current facts
|
|
61
|
+
*/
|
|
62
|
+
getFacts(): PraxisFact[];
|
|
63
|
+
/**
|
|
64
|
+
* Process events through the engine.
|
|
65
|
+
* Applies all registered rules and checks all registered constraints.
|
|
66
|
+
*
|
|
67
|
+
* @param events Events to process
|
|
68
|
+
* @returns Result with new state and diagnostics
|
|
69
|
+
*/
|
|
70
|
+
step(events: PraxisEvent[]): PraxisStepResult;
|
|
71
|
+
/**
|
|
72
|
+
* Process events with specific rule and constraint configuration.
|
|
73
|
+
*
|
|
74
|
+
* @param events Events to process
|
|
75
|
+
* @param config Step configuration
|
|
76
|
+
* @returns Result with new state and diagnostics
|
|
77
|
+
*/
|
|
78
|
+
stepWithConfig(events: PraxisEvent[], config: PraxisStepConfig): PraxisStepResult;
|
|
79
|
+
/**
|
|
80
|
+
* Update the context directly (for exceptional cases).
|
|
81
|
+
* Generally, context should be updated through rules.
|
|
82
|
+
*
|
|
83
|
+
* @param updater Function that produces new context from old context
|
|
84
|
+
*/
|
|
85
|
+
updateContext(updater: (context: TContext) => TContext): void;
|
|
86
|
+
/**
|
|
87
|
+
* Atomically update context AND process events in a single call.
|
|
88
|
+
*
|
|
89
|
+
* This avoids the fragile pattern of calling updateContext() then step()
|
|
90
|
+
* separately, where rules could see stale context if the ordering is wrong.
|
|
91
|
+
*
|
|
92
|
+
* @param updater Function that produces new context from old context
|
|
93
|
+
* @param events Events to process after context is updated
|
|
94
|
+
* @returns Result with new state and diagnostics
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* engine.stepWithContext(
|
|
98
|
+
* ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
|
|
99
|
+
* [{ tag: 'sprint.update', payload: { name: sprint.name } }]
|
|
100
|
+
* );
|
|
101
|
+
*/
|
|
102
|
+
stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
|
|
103
|
+
/**
|
|
104
|
+
* Add facts directly (for exceptional cases).
|
|
105
|
+
* Generally, facts should be added through rules.
|
|
106
|
+
*
|
|
107
|
+
* @param facts Facts to add
|
|
108
|
+
*/
|
|
109
|
+
addFacts(facts: PraxisFact[]): void;
|
|
110
|
+
/**
|
|
111
|
+
* Check all constraints without processing any events.
|
|
112
|
+
*
|
|
113
|
+
* Useful for validation-only scenarios (e.g., form validation,
|
|
114
|
+
* pre-save checks) where you want constraint diagnostics without
|
|
115
|
+
* triggering any rules.
|
|
116
|
+
*
|
|
117
|
+
* @returns Array of constraint violation diagnostics (empty = all passing)
|
|
118
|
+
*/
|
|
119
|
+
checkConstraints(): PraxisDiagnostics[];
|
|
120
|
+
/**
|
|
121
|
+
* Clear all facts
|
|
122
|
+
*/
|
|
123
|
+
clearFacts(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Reset the engine to initial state
|
|
126
|
+
*/
|
|
127
|
+
reset(options: PraxisEngineOptions<TContext>): void;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Create a new Praxis logic engine.
|
|
131
|
+
*
|
|
132
|
+
* @param options Engine options
|
|
133
|
+
* @returns New LogicEngine instance
|
|
134
|
+
*/
|
|
135
|
+
declare function createPraxisEngine<TContext = unknown>(options: PraxisEngineOptions<TContext>): LogicEngine<TContext>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Praxis Reactive Logic Engine - Svelte 5 Implementation
|
|
139
|
+
*
|
|
140
|
+
* This version uses Svelte 5 runes ($state) for built-in reactivity.
|
|
141
|
+
* The state object is automatically reactive when used in Svelte components.
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
interface ReactiveEngineOptions<TContext> {
|
|
145
|
+
initialContext: TContext;
|
|
146
|
+
initialFacts?: any[];
|
|
147
|
+
initialMeta?: Record<string, unknown>;
|
|
148
|
+
registry?: PraxisRegistry<TContext>;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Reactive Logic Engine using Svelte 5 runes.
|
|
152
|
+
* Combines the standard LogicEngine with reactive state management.
|
|
153
|
+
*/
|
|
154
|
+
declare class ReactiveLogicEngine<TContext extends object> {
|
|
155
|
+
state: {
|
|
156
|
+
context: TContext;
|
|
157
|
+
facts: any[];
|
|
158
|
+
meta: Record<string, unknown>;
|
|
159
|
+
};
|
|
160
|
+
private _engine;
|
|
161
|
+
constructor(options: ReactiveEngineOptions<TContext>);
|
|
162
|
+
/**
|
|
163
|
+
* Access the reactive context.
|
|
164
|
+
* In Svelte 5 components, changes to this object will automatically trigger updates.
|
|
165
|
+
*/
|
|
166
|
+
get context(): TContext;
|
|
167
|
+
/**
|
|
168
|
+
* Access the reactive facts list.
|
|
169
|
+
*/
|
|
170
|
+
get facts(): any[];
|
|
171
|
+
/**
|
|
172
|
+
* Access the reactive metadata.
|
|
173
|
+
*/
|
|
174
|
+
get meta(): Record<string, unknown>;
|
|
175
|
+
/**
|
|
176
|
+
* Apply a mutation to the state.
|
|
177
|
+
* Changes will automatically trigger Svelte reactivity.
|
|
178
|
+
*
|
|
179
|
+
* @param mutator A function that receives the state and modifies it.
|
|
180
|
+
*/
|
|
181
|
+
apply(mutator: (state: {
|
|
182
|
+
context: TContext;
|
|
183
|
+
facts: any[];
|
|
184
|
+
meta: Record<string, unknown>;
|
|
185
|
+
}) => void): void;
|
|
186
|
+
/**
|
|
187
|
+
* Process events through the logic engine and update reactive state.
|
|
188
|
+
*
|
|
189
|
+
* @param events Events to process
|
|
190
|
+
*/
|
|
191
|
+
step(events: PraxisEvent[]): void;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create a reactive logic engine with Svelte 5 runes.
|
|
195
|
+
*
|
|
196
|
+
* @param options Configuration options
|
|
197
|
+
* @returns A reactive logic engine instance
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```svelte
|
|
201
|
+
* <script lang="ts">
|
|
202
|
+
* import { createReactiveEngine } from '@plures/praxis/svelte';
|
|
203
|
+
*
|
|
204
|
+
* const engine = createReactiveEngine({
|
|
205
|
+
* initialContext: { count: 0 },
|
|
206
|
+
* registry
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* // Use $derived for computed values
|
|
210
|
+
* const count = $derived(engine.context.count);
|
|
211
|
+
* const doubled = $derived(engine.context.count * 2);
|
|
212
|
+
*
|
|
213
|
+
* function increment() {
|
|
214
|
+
* engine.step([Increment.create({ amount: 1 })]);
|
|
215
|
+
* }
|
|
216
|
+
* </script>
|
|
217
|
+
*
|
|
218
|
+
* <button on:click={increment}>Count: {count}, Doubled: {doubled}</button>
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
|
|
222
|
+
|
|
223
|
+
export { LogicEngine as L, type PraxisEngineOptions as P, type ReactiveEngineOptions as R, ReactiveLogicEngine as a, createPraxisEngine as b, createReactiveEngine as c };
|
|
@@ -289,6 +289,18 @@ declare class RuleResult {
|
|
|
289
289
|
/** Whether this result retracts facts */
|
|
290
290
|
get hasRetractions(): boolean;
|
|
291
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* A rule function that returns a typed RuleResult.
|
|
294
|
+
* New API — replaces the old PraxisFact[] return type.
|
|
295
|
+
*/
|
|
296
|
+
type TypedRuleFn<TContext = unknown> = (state: PraxisState & {
|
|
297
|
+
context: TContext;
|
|
298
|
+
events: PraxisEvent[];
|
|
299
|
+
}, events: PraxisEvent[]) => RuleResult;
|
|
300
|
+
/**
|
|
301
|
+
* Convenience: create a fact object (just a shorthand)
|
|
302
|
+
*/
|
|
303
|
+
declare function fact(tag: string, payload: unknown): PraxisFact;
|
|
292
304
|
|
|
293
305
|
/**
|
|
294
306
|
* Rules and Constraints System
|
|
@@ -465,224 +477,4 @@ declare class PraxisRegistry<TContext = unknown> {
|
|
|
465
477
|
private validateDescriptorContract;
|
|
466
478
|
}
|
|
467
479
|
|
|
468
|
-
|
|
469
|
-
* Praxis Logic Engine
|
|
470
|
-
*
|
|
471
|
-
* The logic engine manages state, processes events through rules,
|
|
472
|
-
* checks constraints, and provides a strongly-typed API for application logic.
|
|
473
|
-
*/
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Options for creating a Praxis engine
|
|
477
|
-
*/
|
|
478
|
-
interface PraxisEngineOptions<TContext = unknown> {
|
|
479
|
-
/** Initial context */
|
|
480
|
-
initialContext: TContext;
|
|
481
|
-
/** Registry of rules and constraints */
|
|
482
|
-
registry: PraxisRegistry<TContext>;
|
|
483
|
-
/** Initial facts (optional) */
|
|
484
|
-
initialFacts?: PraxisFact[];
|
|
485
|
-
/** Initial metadata (optional) */
|
|
486
|
-
initialMeta?: Record<string, unknown>;
|
|
487
|
-
/**
|
|
488
|
-
* Fact deduplication strategy (default: 'last-write-wins').
|
|
489
|
-
*
|
|
490
|
-
* - 'none': facts accumulate without dedup (original behavior)
|
|
491
|
-
* - 'last-write-wins': only keep the latest fact per tag (most common)
|
|
492
|
-
* - 'append': keep all facts but cap at maxFacts
|
|
493
|
-
*/
|
|
494
|
-
factDedup?: 'none' | 'last-write-wins' | 'append';
|
|
495
|
-
/**
|
|
496
|
-
* Maximum number of facts to retain (default: 1000).
|
|
497
|
-
* When exceeded, oldest facts are evicted (FIFO).
|
|
498
|
-
* Set to 0 for unlimited (not recommended).
|
|
499
|
-
*/
|
|
500
|
-
maxFacts?: number;
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* The Praxis Logic Engine
|
|
504
|
-
*
|
|
505
|
-
* Manages application logic through facts, events, rules, and constraints.
|
|
506
|
-
* The engine is strongly typed and functional - all state updates are immutable.
|
|
507
|
-
*/
|
|
508
|
-
declare class LogicEngine<TContext = unknown> {
|
|
509
|
-
private state;
|
|
510
|
-
private readonly registry;
|
|
511
|
-
private readonly factDedup;
|
|
512
|
-
private readonly maxFacts;
|
|
513
|
-
constructor(options: PraxisEngineOptions<TContext>);
|
|
514
|
-
/**
|
|
515
|
-
* Get the current state (immutable copy)
|
|
516
|
-
*/
|
|
517
|
-
getState(): Readonly<PraxisState & {
|
|
518
|
-
context: TContext;
|
|
519
|
-
}>;
|
|
520
|
-
/**
|
|
521
|
-
* Get the current context
|
|
522
|
-
*/
|
|
523
|
-
getContext(): TContext;
|
|
524
|
-
/**
|
|
525
|
-
* Get current facts
|
|
526
|
-
*/
|
|
527
|
-
getFacts(): PraxisFact[];
|
|
528
|
-
/**
|
|
529
|
-
* Process events through the engine.
|
|
530
|
-
* Applies all registered rules and checks all registered constraints.
|
|
531
|
-
*
|
|
532
|
-
* @param events Events to process
|
|
533
|
-
* @returns Result with new state and diagnostics
|
|
534
|
-
*/
|
|
535
|
-
step(events: PraxisEvent[]): PraxisStepResult;
|
|
536
|
-
/**
|
|
537
|
-
* Process events with specific rule and constraint configuration.
|
|
538
|
-
*
|
|
539
|
-
* @param events Events to process
|
|
540
|
-
* @param config Step configuration
|
|
541
|
-
* @returns Result with new state and diagnostics
|
|
542
|
-
*/
|
|
543
|
-
stepWithConfig(events: PraxisEvent[], config: PraxisStepConfig): PraxisStepResult;
|
|
544
|
-
/**
|
|
545
|
-
* Update the context directly (for exceptional cases).
|
|
546
|
-
* Generally, context should be updated through rules.
|
|
547
|
-
*
|
|
548
|
-
* @param updater Function that produces new context from old context
|
|
549
|
-
*/
|
|
550
|
-
updateContext(updater: (context: TContext) => TContext): void;
|
|
551
|
-
/**
|
|
552
|
-
* Atomically update context AND process events in a single call.
|
|
553
|
-
*
|
|
554
|
-
* This avoids the fragile pattern of calling updateContext() then step()
|
|
555
|
-
* separately, where rules could see stale context if the ordering is wrong.
|
|
556
|
-
*
|
|
557
|
-
* @param updater Function that produces new context from old context
|
|
558
|
-
* @param events Events to process after context is updated
|
|
559
|
-
* @returns Result with new state and diagnostics
|
|
560
|
-
*
|
|
561
|
-
* @example
|
|
562
|
-
* engine.stepWithContext(
|
|
563
|
-
* ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
|
|
564
|
-
* [{ tag: 'sprint.update', payload: { name: sprint.name } }]
|
|
565
|
-
* );
|
|
566
|
-
*/
|
|
567
|
-
stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
|
|
568
|
-
/**
|
|
569
|
-
* Add facts directly (for exceptional cases).
|
|
570
|
-
* Generally, facts should be added through rules.
|
|
571
|
-
*
|
|
572
|
-
* @param facts Facts to add
|
|
573
|
-
*/
|
|
574
|
-
addFacts(facts: PraxisFact[]): void;
|
|
575
|
-
/**
|
|
576
|
-
* Check all constraints without processing any events.
|
|
577
|
-
*
|
|
578
|
-
* Useful for validation-only scenarios (e.g., form validation,
|
|
579
|
-
* pre-save checks) where you want constraint diagnostics without
|
|
580
|
-
* triggering any rules.
|
|
581
|
-
*
|
|
582
|
-
* @returns Array of constraint violation diagnostics (empty = all passing)
|
|
583
|
-
*/
|
|
584
|
-
checkConstraints(): PraxisDiagnostics[];
|
|
585
|
-
/**
|
|
586
|
-
* Clear all facts
|
|
587
|
-
*/
|
|
588
|
-
clearFacts(): void;
|
|
589
|
-
/**
|
|
590
|
-
* Reset the engine to initial state
|
|
591
|
-
*/
|
|
592
|
-
reset(options: PraxisEngineOptions<TContext>): void;
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Create a new Praxis logic engine.
|
|
596
|
-
*
|
|
597
|
-
* @param options Engine options
|
|
598
|
-
* @returns New LogicEngine instance
|
|
599
|
-
*/
|
|
600
|
-
declare function createPraxisEngine<TContext = unknown>(options: PraxisEngineOptions<TContext>): LogicEngine<TContext>;
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* Praxis Reactive Logic Engine - Svelte 5 Implementation
|
|
604
|
-
*
|
|
605
|
-
* This version uses Svelte 5 runes ($state) for built-in reactivity.
|
|
606
|
-
* The state object is automatically reactive when used in Svelte components.
|
|
607
|
-
*/
|
|
608
|
-
|
|
609
|
-
interface ReactiveEngineOptions<TContext> {
|
|
610
|
-
initialContext: TContext;
|
|
611
|
-
initialFacts?: any[];
|
|
612
|
-
initialMeta?: Record<string, unknown>;
|
|
613
|
-
registry?: PraxisRegistry<TContext>;
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Reactive Logic Engine using Svelte 5 runes.
|
|
617
|
-
* Combines the standard LogicEngine with reactive state management.
|
|
618
|
-
*/
|
|
619
|
-
declare class ReactiveLogicEngine<TContext extends object> {
|
|
620
|
-
state: {
|
|
621
|
-
context: TContext;
|
|
622
|
-
facts: any[];
|
|
623
|
-
meta: Record<string, unknown>;
|
|
624
|
-
};
|
|
625
|
-
private _engine;
|
|
626
|
-
constructor(options: ReactiveEngineOptions<TContext>);
|
|
627
|
-
/**
|
|
628
|
-
* Access the reactive context.
|
|
629
|
-
* In Svelte 5 components, changes to this object will automatically trigger updates.
|
|
630
|
-
*/
|
|
631
|
-
get context(): TContext;
|
|
632
|
-
/**
|
|
633
|
-
* Access the reactive facts list.
|
|
634
|
-
*/
|
|
635
|
-
get facts(): any[];
|
|
636
|
-
/**
|
|
637
|
-
* Access the reactive metadata.
|
|
638
|
-
*/
|
|
639
|
-
get meta(): Record<string, unknown>;
|
|
640
|
-
/**
|
|
641
|
-
* Apply a mutation to the state.
|
|
642
|
-
* Changes will automatically trigger Svelte reactivity.
|
|
643
|
-
*
|
|
644
|
-
* @param mutator A function that receives the state and modifies it.
|
|
645
|
-
*/
|
|
646
|
-
apply(mutator: (state: {
|
|
647
|
-
context: TContext;
|
|
648
|
-
facts: any[];
|
|
649
|
-
meta: Record<string, unknown>;
|
|
650
|
-
}) => void): void;
|
|
651
|
-
/**
|
|
652
|
-
* Process events through the logic engine and update reactive state.
|
|
653
|
-
*
|
|
654
|
-
* @param events Events to process
|
|
655
|
-
*/
|
|
656
|
-
step(events: PraxisEvent[]): void;
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Create a reactive logic engine with Svelte 5 runes.
|
|
660
|
-
*
|
|
661
|
-
* @param options Configuration options
|
|
662
|
-
* @returns A reactive logic engine instance
|
|
663
|
-
*
|
|
664
|
-
* @example
|
|
665
|
-
* ```svelte
|
|
666
|
-
* <script lang="ts">
|
|
667
|
-
* import { createReactiveEngine } from '@plures/praxis/svelte';
|
|
668
|
-
*
|
|
669
|
-
* const engine = createReactiveEngine({
|
|
670
|
-
* initialContext: { count: 0 },
|
|
671
|
-
* registry
|
|
672
|
-
* });
|
|
673
|
-
*
|
|
674
|
-
* // Use $derived for computed values
|
|
675
|
-
* const count = $derived(engine.context.count);
|
|
676
|
-
* const doubled = $derived(engine.context.count * 2);
|
|
677
|
-
*
|
|
678
|
-
* function increment() {
|
|
679
|
-
* engine.step([Increment.create({ amount: 1 })]);
|
|
680
|
-
* }
|
|
681
|
-
* </script>
|
|
682
|
-
*
|
|
683
|
-
* <button on:click={increment}>Count: {count}, Doubled: {doubled}</button>
|
|
684
|
-
* ```
|
|
685
|
-
*/
|
|
686
|
-
declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
|
|
687
|
-
|
|
688
|
-
export { type ConstraintDescriptor as C, LogicEngine as L, type PraxisState as P, type RuleDescriptor as R, type PraxisEvent as a, PraxisRegistry as b, type ConstraintFn as c, type Contract as d, type RuleFn as e, type PraxisFact as f, type PraxisModule as g, type ConstraintId as h, PRAXIS_PROTOCOL_VERSION as i, type PraxisDiagnostics as j, type PraxisEngineOptions as k, type PraxisStepConfig as l, type PraxisStepFn as m, type PraxisStepResult as n, type ReactiveEngineOptions as o, ReactiveLogicEngine as p, type RuleId as q, createPraxisEngine as r, createReactiveEngine as s };
|
|
480
|
+
export { type ConstraintDescriptor as C, type PraxisState as P, type RuleDescriptor as R, type TypedRuleFn as T, type PraxisEvent as a, PraxisRegistry as b, type PraxisFact as c, type PraxisStepResult as d, type PraxisStepConfig as e, type PraxisDiagnostics as f, type ConstraintFn as g, type Contract as h, type RuleFn as i, type PraxisModule as j, type ConstraintId as k, PRAXIS_PROTOCOL_VERSION as l, type PraxisStepFn as m, type RuleId as n, RuleResult as o, fact as p };
|