@plures/praxis 1.4.0 → 2.0.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/dist/browser/{chunk-N63K4KWS.js → chunk-4IRUGWR3.js} +1 -1
- package/dist/browser/chunk-6MVRT7CK.js +363 -0
- 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 +150 -0
- package/dist/browser/factory/index.js +15 -0
- package/dist/browser/index.d.ts +277 -3
- package/dist/browser/index.js +425 -60
- package/dist/browser/integrations/svelte.d.ts +4 -2
- package/dist/browser/integrations/svelte.js +3 -2
- package/dist/browser/project/index.d.ts +177 -0
- package/dist/browser/project/index.js +19 -0
- package/dist/browser/reactive-engine.svelte-BwWadvAW.d.ts +224 -0
- package/dist/browser/rule-result-DcXWe9tn.d.ts +206 -0
- package/dist/browser/rules-BaWMqxuG.d.ts +277 -0
- package/dist/browser/unified/index.d.ts +239 -0
- package/dist/browser/unified/index.js +20 -0
- package/dist/node/chunk-6MVRT7CK.js +363 -0
- 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-7M3HV4XR.js → chunk-WFRHXZBP.js} +3 -3
- package/dist/node/cli/index.cjs +48 -0
- package/dist/node/cli/index.js +2 -2
- package/dist/node/{engine-FEN5IYZ5.js → engine-VFHCIEM4.js} +2 -1
- package/dist/node/index.cjs +2114 -0
- package/dist/node/index.d.cts +964 -280
- package/dist/node/index.d.ts +964 -280
- package/dist/node/index.js +575 -10
- package/dist/node/integrations/svelte.d.cts +3 -2
- package/dist/node/integrations/svelte.d.ts +3 -2
- package/dist/node/integrations/svelte.js +3 -2
- package/dist/node/{reactive-engine.svelte-DekxqFu0.d.ts → reactive-engine.svelte-BBZLMzus.d.ts} +3 -79
- package/dist/node/{reactive-engine.svelte-Cg0Yc2Hs.d.cts → reactive-engine.svelte-Cbq_V20o.d.cts} +3 -79
- package/dist/node/rule-result-B9GMivAn.d.cts +80 -0
- package/dist/node/rule-result-Bo3sFMmN.d.ts +80 -0
- package/dist/node/{server-SYZPDULV.js → server-FKLVY57V.js} +4 -2
- package/dist/node/unified/index.cjs +484 -0
- package/dist/node/unified/index.d.cts +240 -0
- package/dist/node/unified/index.d.ts +240 -0
- package/dist/node/unified/index.js +21 -0
- package/dist/node/{validate-TQGVIG7G.js → validate-BY7JNY7H.js} +2 -1
- package/package.json +38 -11
- package/src/__tests__/chronos-project.test.ts +799 -0
- package/src/__tests__/decision-ledger.test.ts +857 -402
- 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/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/index.browser.ts +103 -0
- package/src/index.ts +98 -0
- package/src/unified/__tests__/unified.test.ts +396 -0
- package/src/unified/core.ts +517 -0
- package/src/unified/index.ts +32 -0
- package/src/unified/rules.ts +66 -0
- package/src/unified/types.ts +148 -0
- package/dist/browser/reactive-engine.svelte-DjynI82A.d.ts +0 -688
- package/dist/node/chunk-FWOXU4MM.js +0 -487
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { L as LogicEngine } from '../reactive-engine.svelte-BwWadvAW.js';
|
|
2
|
+
export { R as ReactiveEngineOptions, a as ReactiveLogicEngine, c as createReactiveEngine } from '../reactive-engine.svelte-BwWadvAW.js';
|
|
3
|
+
import { P as PraxisState, a as PraxisEvent } from '../rule-result-DcXWe9tn.js';
|
|
4
|
+
import '../rules-BaWMqxuG.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Svelte v5 Integration
|
|
@@ -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,177 @@
|
|
|
1
|
+
import { d as PraxisModule } from '../rules-BaWMqxuG.js';
|
|
2
|
+
import '../rule-result-DcXWe9tn.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Praxis Project Logic — Types
|
|
6
|
+
*
|
|
7
|
+
* Types for developer workflow rules: gates, semver contracts,
|
|
8
|
+
* commit generation, and branch management.
|
|
9
|
+
*/
|
|
10
|
+
type GateStatus = 'open' | 'closed' | 'blocked';
|
|
11
|
+
interface GateConfig {
|
|
12
|
+
/** Expectations that must be satisfied for the gate to open */
|
|
13
|
+
expects: string[];
|
|
14
|
+
/** Action when gate is satisfied */
|
|
15
|
+
onSatisfied?: string;
|
|
16
|
+
/** Action when gate is violated */
|
|
17
|
+
onViolation?: string;
|
|
18
|
+
}
|
|
19
|
+
interface GateState {
|
|
20
|
+
name: string;
|
|
21
|
+
status: GateStatus;
|
|
22
|
+
/** Which expectations are satisfied */
|
|
23
|
+
satisfied: string[];
|
|
24
|
+
/** Which expectations are not satisfied */
|
|
25
|
+
unsatisfied: string[];
|
|
26
|
+
/** Timestamp of last status change */
|
|
27
|
+
lastChanged: number;
|
|
28
|
+
}
|
|
29
|
+
interface SemverContractConfig {
|
|
30
|
+
/** Files/sources that contain version strings */
|
|
31
|
+
sources: string[];
|
|
32
|
+
/** Invariants about version consistency */
|
|
33
|
+
invariants: string[];
|
|
34
|
+
}
|
|
35
|
+
interface SemverReport {
|
|
36
|
+
/** Whether all sources have consistent versions */
|
|
37
|
+
consistent: boolean;
|
|
38
|
+
/** Version found in each source */
|
|
39
|
+
versions: Record<string, string>;
|
|
40
|
+
/** Invariant violations */
|
|
41
|
+
violations: string[];
|
|
42
|
+
}
|
|
43
|
+
interface PraxisDiff {
|
|
44
|
+
/** Rules added since last commit */
|
|
45
|
+
rulesAdded: string[];
|
|
46
|
+
/** Rules removed */
|
|
47
|
+
rulesRemoved: string[];
|
|
48
|
+
/** Rules modified */
|
|
49
|
+
rulesModified: string[];
|
|
50
|
+
/** Contracts added */
|
|
51
|
+
contractsAdded: string[];
|
|
52
|
+
/** Contracts removed */
|
|
53
|
+
contractsRemoved: string[];
|
|
54
|
+
/** Expectations added */
|
|
55
|
+
expectationsAdded: string[];
|
|
56
|
+
/** Expectations removed */
|
|
57
|
+
expectationsRemoved: string[];
|
|
58
|
+
/** Gate state changes */
|
|
59
|
+
gateChanges: Array<{
|
|
60
|
+
gate: string;
|
|
61
|
+
from: GateStatus;
|
|
62
|
+
to: GateStatus;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
interface BranchRulesConfig {
|
|
66
|
+
/** Naming convention pattern (e.g., 'feat/{name}', 'fix/{issue}') */
|
|
67
|
+
naming: string;
|
|
68
|
+
/** Conditions required for merge */
|
|
69
|
+
mergeConditions: string[];
|
|
70
|
+
}
|
|
71
|
+
interface PredefinedGateConfig {
|
|
72
|
+
/** Whether to enable this gate */
|
|
73
|
+
enabled?: boolean;
|
|
74
|
+
/** Custom expectations to add */
|
|
75
|
+
additionalExpects?: string[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Praxis Project Logic
|
|
80
|
+
*
|
|
81
|
+
* Developer workflow rules: gates, semver contracts, commit message
|
|
82
|
+
* generation from behavioral deltas, and branch management.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { defineGate, semverContract, commitFromState } from '@plures/praxis/project';
|
|
87
|
+
*
|
|
88
|
+
* const testGate = defineGate('test', {
|
|
89
|
+
* expects: ['all-tests-pass', 'no-type-errors'],
|
|
90
|
+
* onSatisfied: 'merge-allowed',
|
|
91
|
+
* onViolation: 'merge-blocked',
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* const diff = { rulesAdded: ['auth/login'], ... };
|
|
95
|
+
* const message = commitFromState(diff);
|
|
96
|
+
* // → "feat(rules): add auth/login rule"
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Context type for gates. Apps extend their context with gate state.
|
|
102
|
+
*/
|
|
103
|
+
interface GateContext {
|
|
104
|
+
gates?: Record<string, GateState>;
|
|
105
|
+
expectations?: Record<string, boolean>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Define a feature gate — a condition that must be satisfied before
|
|
109
|
+
* proceeding with a workflow step (deploy, merge, release, etc.).
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const testGate = defineGate('test', {
|
|
114
|
+
* expects: ['all-tests-pass', 'no-type-errors'],
|
|
115
|
+
* onSatisfied: 'deploy-allowed',
|
|
116
|
+
* onViolation: 'deploy-blocked',
|
|
117
|
+
* });
|
|
118
|
+
* registry.registerModule(testGate);
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
declare function defineGate(name: string, config: GateConfig): PraxisModule<GateContext>;
|
|
122
|
+
/**
|
|
123
|
+
* Create a semver contract module that checks version consistency
|
|
124
|
+
* across multiple sources (package.json, Cargo.toml, etc.).
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const version = semverContract({
|
|
129
|
+
* sources: ['package.json', 'src/version.ts', 'README.md'],
|
|
130
|
+
* invariants: ['All sources must have the same version'],
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
declare function semverContract(config: SemverContractConfig): PraxisModule;
|
|
135
|
+
/**
|
|
136
|
+
* Generate a conventional commit message from a behavioral delta.
|
|
137
|
+
*
|
|
138
|
+
* Unlike file-based commit messages, this describes WHAT behavioral
|
|
139
|
+
* changes occurred — rule additions, contract changes, expectation shifts.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const msg = commitFromState({
|
|
144
|
+
* rulesAdded: ['auth/login', 'auth/logout'],
|
|
145
|
+
* contractsAdded: ['auth/login'],
|
|
146
|
+
* ...empty
|
|
147
|
+
* });
|
|
148
|
+
* // → "feat(rules): add auth/login, auth/logout\n\nContracts added: auth/login"
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function commitFromState(diff: PraxisDiff): string;
|
|
152
|
+
/**
|
|
153
|
+
* Create branch management rules.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const branches = branchRules({
|
|
158
|
+
* naming: 'feat/{name}',
|
|
159
|
+
* mergeConditions: ['tests-pass', 'review-approved'],
|
|
160
|
+
* });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function branchRules(config: BranchRulesConfig): PraxisModule;
|
|
164
|
+
/**
|
|
165
|
+
* Create a lint gate — blocks workflow until linting passes.
|
|
166
|
+
*/
|
|
167
|
+
declare function lintGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
168
|
+
/**
|
|
169
|
+
* Create a format gate — blocks workflow until formatting is correct.
|
|
170
|
+
*/
|
|
171
|
+
declare function formatGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
172
|
+
/**
|
|
173
|
+
* Create an expectation gate — blocks workflow until expectations are verified.
|
|
174
|
+
*/
|
|
175
|
+
declare function expectationGate(config?: PredefinedGateConfig): PraxisModule<GateContext>;
|
|
176
|
+
|
|
177
|
+
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,224 @@
|
|
|
1
|
+
import { b as PraxisFact, P as PraxisState, a as PraxisEvent, c as PraxisStepResult, d as PraxisStepConfig, e as PraxisDiagnostics } from './rule-result-DcXWe9tn.js';
|
|
2
|
+
import { P as PraxisRegistry } from './rules-BaWMqxuG.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Praxis Logic Engine
|
|
6
|
+
*
|
|
7
|
+
* The logic engine manages state, processes events through rules,
|
|
8
|
+
* checks constraints, and provides a strongly-typed API for application logic.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Options for creating a Praxis engine
|
|
13
|
+
*/
|
|
14
|
+
interface PraxisEngineOptions<TContext = unknown> {
|
|
15
|
+
/** Initial context */
|
|
16
|
+
initialContext: TContext;
|
|
17
|
+
/** Registry of rules and constraints */
|
|
18
|
+
registry: PraxisRegistry<TContext>;
|
|
19
|
+
/** Initial facts (optional) */
|
|
20
|
+
initialFacts?: PraxisFact[];
|
|
21
|
+
/** Initial metadata (optional) */
|
|
22
|
+
initialMeta?: Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Fact deduplication strategy (default: 'last-write-wins').
|
|
25
|
+
*
|
|
26
|
+
* - 'none': facts accumulate without dedup (original behavior)
|
|
27
|
+
* - 'last-write-wins': only keep the latest fact per tag (most common)
|
|
28
|
+
* - 'append': keep all facts but cap at maxFacts
|
|
29
|
+
*/
|
|
30
|
+
factDedup?: 'none' | 'last-write-wins' | 'append';
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of facts to retain (default: 1000).
|
|
33
|
+
* When exceeded, oldest facts are evicted (FIFO).
|
|
34
|
+
* Set to 0 for unlimited (not recommended).
|
|
35
|
+
*/
|
|
36
|
+
maxFacts?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The Praxis Logic Engine
|
|
40
|
+
*
|
|
41
|
+
* Manages application logic through facts, events, rules, and constraints.
|
|
42
|
+
* The engine is strongly typed and functional - all state updates are immutable.
|
|
43
|
+
*/
|
|
44
|
+
declare class LogicEngine<TContext = unknown> {
|
|
45
|
+
private state;
|
|
46
|
+
private readonly registry;
|
|
47
|
+
private readonly factDedup;
|
|
48
|
+
private readonly maxFacts;
|
|
49
|
+
constructor(options: PraxisEngineOptions<TContext>);
|
|
50
|
+
/**
|
|
51
|
+
* Get the current state (immutable copy)
|
|
52
|
+
*/
|
|
53
|
+
getState(): Readonly<PraxisState & {
|
|
54
|
+
context: TContext;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Get the current context
|
|
58
|
+
*/
|
|
59
|
+
getContext(): TContext;
|
|
60
|
+
/**
|
|
61
|
+
* Get current facts
|
|
62
|
+
*/
|
|
63
|
+
getFacts(): PraxisFact[];
|
|
64
|
+
/**
|
|
65
|
+
* Process events through the engine.
|
|
66
|
+
* Applies all registered rules and checks all registered constraints.
|
|
67
|
+
*
|
|
68
|
+
* @param events Events to process
|
|
69
|
+
* @returns Result with new state and diagnostics
|
|
70
|
+
*/
|
|
71
|
+
step(events: PraxisEvent[]): PraxisStepResult;
|
|
72
|
+
/**
|
|
73
|
+
* Process events with specific rule and constraint configuration.
|
|
74
|
+
*
|
|
75
|
+
* @param events Events to process
|
|
76
|
+
* @param config Step configuration
|
|
77
|
+
* @returns Result with new state and diagnostics
|
|
78
|
+
*/
|
|
79
|
+
stepWithConfig(events: PraxisEvent[], config: PraxisStepConfig): PraxisStepResult;
|
|
80
|
+
/**
|
|
81
|
+
* Update the context directly (for exceptional cases).
|
|
82
|
+
* Generally, context should be updated through rules.
|
|
83
|
+
*
|
|
84
|
+
* @param updater Function that produces new context from old context
|
|
85
|
+
*/
|
|
86
|
+
updateContext(updater: (context: TContext) => TContext): void;
|
|
87
|
+
/**
|
|
88
|
+
* Atomically update context AND process events in a single call.
|
|
89
|
+
*
|
|
90
|
+
* This avoids the fragile pattern of calling updateContext() then step()
|
|
91
|
+
* separately, where rules could see stale context if the ordering is wrong.
|
|
92
|
+
*
|
|
93
|
+
* @param updater Function that produces new context from old context
|
|
94
|
+
* @param events Events to process after context is updated
|
|
95
|
+
* @returns Result with new state and diagnostics
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* engine.stepWithContext(
|
|
99
|
+
* ctx => ({ ...ctx, sprintName: sprint.name, items: sprint.items }),
|
|
100
|
+
* [{ tag: 'sprint.update', payload: { name: sprint.name } }]
|
|
101
|
+
* );
|
|
102
|
+
*/
|
|
103
|
+
stepWithContext(updater: (context: TContext) => TContext, events: PraxisEvent[]): PraxisStepResult;
|
|
104
|
+
/**
|
|
105
|
+
* Add facts directly (for exceptional cases).
|
|
106
|
+
* Generally, facts should be added through rules.
|
|
107
|
+
*
|
|
108
|
+
* @param facts Facts to add
|
|
109
|
+
*/
|
|
110
|
+
addFacts(facts: PraxisFact[]): void;
|
|
111
|
+
/**
|
|
112
|
+
* Check all constraints without processing any events.
|
|
113
|
+
*
|
|
114
|
+
* Useful for validation-only scenarios (e.g., form validation,
|
|
115
|
+
* pre-save checks) where you want constraint diagnostics without
|
|
116
|
+
* triggering any rules.
|
|
117
|
+
*
|
|
118
|
+
* @returns Array of constraint violation diagnostics (empty = all passing)
|
|
119
|
+
*/
|
|
120
|
+
checkConstraints(): PraxisDiagnostics[];
|
|
121
|
+
/**
|
|
122
|
+
* Clear all facts
|
|
123
|
+
*/
|
|
124
|
+
clearFacts(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Reset the engine to initial state
|
|
127
|
+
*/
|
|
128
|
+
reset(options: PraxisEngineOptions<TContext>): void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Create a new Praxis logic engine.
|
|
132
|
+
*
|
|
133
|
+
* @param options Engine options
|
|
134
|
+
* @returns New LogicEngine instance
|
|
135
|
+
*/
|
|
136
|
+
declare function createPraxisEngine<TContext = unknown>(options: PraxisEngineOptions<TContext>): LogicEngine<TContext>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Praxis Reactive Logic Engine - Svelte 5 Implementation
|
|
140
|
+
*
|
|
141
|
+
* This version uses Svelte 5 runes ($state) for built-in reactivity.
|
|
142
|
+
* The state object is automatically reactive when used in Svelte components.
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
interface ReactiveEngineOptions<TContext> {
|
|
146
|
+
initialContext: TContext;
|
|
147
|
+
initialFacts?: any[];
|
|
148
|
+
initialMeta?: Record<string, unknown>;
|
|
149
|
+
registry?: PraxisRegistry<TContext>;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Reactive Logic Engine using Svelte 5 runes.
|
|
153
|
+
* Combines the standard LogicEngine with reactive state management.
|
|
154
|
+
*/
|
|
155
|
+
declare class ReactiveLogicEngine<TContext extends object> {
|
|
156
|
+
state: {
|
|
157
|
+
context: TContext;
|
|
158
|
+
facts: any[];
|
|
159
|
+
meta: Record<string, unknown>;
|
|
160
|
+
};
|
|
161
|
+
private _engine;
|
|
162
|
+
constructor(options: ReactiveEngineOptions<TContext>);
|
|
163
|
+
/**
|
|
164
|
+
* Access the reactive context.
|
|
165
|
+
* In Svelte 5 components, changes to this object will automatically trigger updates.
|
|
166
|
+
*/
|
|
167
|
+
get context(): TContext;
|
|
168
|
+
/**
|
|
169
|
+
* Access the reactive facts list.
|
|
170
|
+
*/
|
|
171
|
+
get facts(): any[];
|
|
172
|
+
/**
|
|
173
|
+
* Access the reactive metadata.
|
|
174
|
+
*/
|
|
175
|
+
get meta(): Record<string, unknown>;
|
|
176
|
+
/**
|
|
177
|
+
* Apply a mutation to the state.
|
|
178
|
+
* Changes will automatically trigger Svelte reactivity.
|
|
179
|
+
*
|
|
180
|
+
* @param mutator A function that receives the state and modifies it.
|
|
181
|
+
*/
|
|
182
|
+
apply(mutator: (state: {
|
|
183
|
+
context: TContext;
|
|
184
|
+
facts: any[];
|
|
185
|
+
meta: Record<string, unknown>;
|
|
186
|
+
}) => void): void;
|
|
187
|
+
/**
|
|
188
|
+
* Process events through the logic engine and update reactive state.
|
|
189
|
+
*
|
|
190
|
+
* @param events Events to process
|
|
191
|
+
*/
|
|
192
|
+
step(events: PraxisEvent[]): void;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Create a reactive logic engine with Svelte 5 runes.
|
|
196
|
+
*
|
|
197
|
+
* @param options Configuration options
|
|
198
|
+
* @returns A reactive logic engine instance
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```svelte
|
|
202
|
+
* <script lang="ts">
|
|
203
|
+
* import { createReactiveEngine } from '@plures/praxis/svelte';
|
|
204
|
+
*
|
|
205
|
+
* const engine = createReactiveEngine({
|
|
206
|
+
* initialContext: { count: 0 },
|
|
207
|
+
* registry
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* // Use $derived for computed values
|
|
211
|
+
* const count = $derived(engine.context.count);
|
|
212
|
+
* const doubled = $derived(engine.context.count * 2);
|
|
213
|
+
*
|
|
214
|
+
* function increment() {
|
|
215
|
+
* engine.step([Increment.create({ amount: 1 })]);
|
|
216
|
+
* }
|
|
217
|
+
* </script>
|
|
218
|
+
*
|
|
219
|
+
* <button on:click={increment}>Count: {count}, Doubled: {doubled}</button>
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
declare function createReactiveEngine<TContext extends object>(options: ReactiveEngineOptions<TContext>): ReactiveLogicEngine<TContext>;
|
|
223
|
+
|
|
224
|
+
export { LogicEngine as L, type PraxisEngineOptions as P, type ReactiveEngineOptions as R, ReactiveLogicEngine as a, createPraxisEngine as b, createReactiveEngine as c };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Praxis Protocol
|
|
3
|
+
*
|
|
4
|
+
* Language-neutral, JSON-friendly protocol that forms the foundation of Praxis.
|
|
5
|
+
* This protocol is designed to be stable and portable across languages (TypeScript, C#, PowerShell, etc.)
|
|
6
|
+
*
|
|
7
|
+
* The protocol defines the conceptual core of the engine:
|
|
8
|
+
* - Pure, deterministic, data in → data out
|
|
9
|
+
* - No side effects, no global state
|
|
10
|
+
* - All higher-level TypeScript APIs are built on top of this protocol
|
|
11
|
+
*
|
|
12
|
+
* ## Protocol Versioning
|
|
13
|
+
*
|
|
14
|
+
* The Praxis protocol follows semantic versioning (MAJOR.MINOR.PATCH):
|
|
15
|
+
* - MAJOR: Breaking changes to core protocol types or semantics
|
|
16
|
+
* - MINOR: Backward-compatible additions to protocol (new optional fields)
|
|
17
|
+
* - PATCH: Clarifications, documentation updates, no functional changes
|
|
18
|
+
*
|
|
19
|
+
* Current version: 1.0.0
|
|
20
|
+
*
|
|
21
|
+
* ### Stability Guarantees
|
|
22
|
+
*
|
|
23
|
+
* 1. **Core Types Stability**: The following types are considered stable and will not
|
|
24
|
+
* change in backward-incompatible ways within the same major version:
|
|
25
|
+
* - PraxisFact (tag, payload structure)
|
|
26
|
+
* - PraxisEvent (tag, payload structure)
|
|
27
|
+
* - PraxisState (context, facts, meta structure)
|
|
28
|
+
* - PraxisStepFn signature
|
|
29
|
+
*
|
|
30
|
+
* 2. **JSON Compatibility**: All protocol types will remain JSON-serializable.
|
|
31
|
+
* No non-JSON-safe types (functions, symbols, etc.) will be added to the protocol.
|
|
32
|
+
*
|
|
33
|
+
* 3. **Cross-Language Compatibility**: Protocol changes will be coordinated across
|
|
34
|
+
* all official language implementations (TypeScript, C#, PowerShell) to ensure
|
|
35
|
+
* interoperability.
|
|
36
|
+
*
|
|
37
|
+
* 4. **Migration Path**: Major version changes will be accompanied by:
|
|
38
|
+
* - Migration guide
|
|
39
|
+
* - Deprecation warnings in previous version
|
|
40
|
+
* - Compatibility shims where possible
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Protocol version following semantic versioning
|
|
44
|
+
*/
|
|
45
|
+
declare const PRAXIS_PROTOCOL_VERSION: "1.0.0";
|
|
46
|
+
/**
|
|
47
|
+
* A fact is a typed proposition about the domain.
|
|
48
|
+
* Examples: UserLoggedIn, CartItem, NetworkOnline
|
|
49
|
+
*/
|
|
50
|
+
interface PraxisFact {
|
|
51
|
+
/** Tag identifying the fact type */
|
|
52
|
+
tag: string;
|
|
53
|
+
/** Payload containing the fact data */
|
|
54
|
+
payload: unknown;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* An event is a temporally ordered fact meant to drive change.
|
|
58
|
+
* Examples: LOGIN, LOGOUT, ADD_TO_CART
|
|
59
|
+
*/
|
|
60
|
+
interface PraxisEvent {
|
|
61
|
+
/** Tag identifying the event type */
|
|
62
|
+
tag: string;
|
|
63
|
+
/** Payload containing the event data */
|
|
64
|
+
payload: unknown;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The state of the Praxis engine at a point in time.
|
|
68
|
+
*/
|
|
69
|
+
interface PraxisState {
|
|
70
|
+
/** Application context (domain-specific data) */
|
|
71
|
+
context: unknown;
|
|
72
|
+
/** Current facts about the domain */
|
|
73
|
+
facts: PraxisFact[];
|
|
74
|
+
/**
|
|
75
|
+
* Events currently being processed in this step.
|
|
76
|
+
* Available to rules during execution — guaranteed to contain the exact
|
|
77
|
+
* events passed to step()/stepWithContext().
|
|
78
|
+
* Empty outside of step execution.
|
|
79
|
+
*/
|
|
80
|
+
events?: PraxisEvent[];
|
|
81
|
+
/** Optional metadata (timestamps, version, etc.) */
|
|
82
|
+
meta?: Record<string, unknown>;
|
|
83
|
+
/** Protocol version (for cross-language compatibility) */
|
|
84
|
+
protocolVersion?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Diagnostic information about constraint violations or rule errors.
|
|
88
|
+
*/
|
|
89
|
+
interface PraxisDiagnostics {
|
|
90
|
+
/** Kind of diagnostic */
|
|
91
|
+
kind: 'constraint-violation' | 'rule-error';
|
|
92
|
+
/** Human-readable message */
|
|
93
|
+
message: string;
|
|
94
|
+
/** Additional diagnostic data */
|
|
95
|
+
data?: unknown;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Configuration for a step execution.
|
|
99
|
+
* Specifies which rules and constraints to apply.
|
|
100
|
+
*/
|
|
101
|
+
interface PraxisStepConfig {
|
|
102
|
+
/** IDs of rules to apply during this step */
|
|
103
|
+
ruleIds: string[];
|
|
104
|
+
/** IDs of constraints to check during this step */
|
|
105
|
+
constraintIds: string[];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Result of a step execution.
|
|
109
|
+
*/
|
|
110
|
+
interface PraxisStepResult {
|
|
111
|
+
/** New state after applying rules and checking constraints */
|
|
112
|
+
state: PraxisState;
|
|
113
|
+
/** Diagnostics from rule execution and constraint checking */
|
|
114
|
+
diagnostics: PraxisDiagnostics[];
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The core step function of the Praxis engine.
|
|
118
|
+
*
|
|
119
|
+
* This is the conceptual heart of the engine:
|
|
120
|
+
* - Takes current state, events, and configuration
|
|
121
|
+
* - Applies rules and checks constraints
|
|
122
|
+
* - Returns new state and diagnostics
|
|
123
|
+
*
|
|
124
|
+
* Pure, deterministic, data in → data out.
|
|
125
|
+
* No side effects, no global state.
|
|
126
|
+
*/
|
|
127
|
+
type PraxisStepFn = (state: PraxisState, events: PraxisEvent[], config: PraxisStepConfig) => PraxisStepResult;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The result of evaluating a rule. Every rule MUST return one of:
|
|
131
|
+
* - `RuleResult.emit(facts)` — rule produced facts
|
|
132
|
+
* - `RuleResult.noop(reason?)` — rule evaluated but had nothing to say
|
|
133
|
+
* - `RuleResult.skip(reason?)` — rule decided to skip (preconditions not met)
|
|
134
|
+
* - `RuleResult.retract(tags)` — rule retracts previously emitted facts
|
|
135
|
+
*/
|
|
136
|
+
declare class RuleResult {
|
|
137
|
+
/** The kind of result */
|
|
138
|
+
readonly kind: 'emit' | 'noop' | 'skip' | 'retract';
|
|
139
|
+
/** Facts produced (only for 'emit') */
|
|
140
|
+
readonly facts: PraxisFact[];
|
|
141
|
+
/** Fact tags to retract (only for 'retract') */
|
|
142
|
+
readonly retractTags: string[];
|
|
143
|
+
/** Optional reason (for noop/skip/retract — useful for debugging) */
|
|
144
|
+
readonly reason?: string;
|
|
145
|
+
/** The rule ID that produced this result (set by engine) */
|
|
146
|
+
ruleId?: string;
|
|
147
|
+
private constructor();
|
|
148
|
+
/**
|
|
149
|
+
* Rule produced facts.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* return RuleResult.emit([
|
|
153
|
+
* { tag: 'sprint.behind', payload: { deficit: 5 } }
|
|
154
|
+
* ]);
|
|
155
|
+
*/
|
|
156
|
+
static emit(facts: PraxisFact[]): RuleResult;
|
|
157
|
+
/**
|
|
158
|
+
* Rule evaluated but had nothing to report.
|
|
159
|
+
* Unlike returning [], this is explicit and traceable.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* if (ctx.completedHours >= expectedHours) {
|
|
163
|
+
* return RuleResult.noop('Sprint is on pace');
|
|
164
|
+
* }
|
|
165
|
+
*/
|
|
166
|
+
static noop(reason?: string): RuleResult;
|
|
167
|
+
/**
|
|
168
|
+
* Rule decided to skip because preconditions were not met.
|
|
169
|
+
* Distinct from noop: skip means "I can't evaluate", noop means "I evaluated and found nothing".
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* if (!ctx.sprintName) {
|
|
173
|
+
* return RuleResult.skip('No active sprint');
|
|
174
|
+
* }
|
|
175
|
+
*/
|
|
176
|
+
static skip(reason?: string): RuleResult;
|
|
177
|
+
/**
|
|
178
|
+
* Rule retracts previously emitted facts by tag.
|
|
179
|
+
* Used when a condition that previously produced facts is no longer true.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* // Sprint was behind, but caught up
|
|
183
|
+
* if (ctx.completedHours >= expectedHours) {
|
|
184
|
+
* return RuleResult.retract(['sprint.behind'], 'Sprint caught up');
|
|
185
|
+
* }
|
|
186
|
+
*/
|
|
187
|
+
static retract(tags: string[], reason?: string): RuleResult;
|
|
188
|
+
/** Whether this result produced facts */
|
|
189
|
+
get hasFacts(): boolean;
|
|
190
|
+
/** Whether this result retracts facts */
|
|
191
|
+
get hasRetractions(): boolean;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* A rule function that returns a typed RuleResult.
|
|
195
|
+
* New API — replaces the old PraxisFact[] return type.
|
|
196
|
+
*/
|
|
197
|
+
type TypedRuleFn<TContext = unknown> = (state: PraxisState & {
|
|
198
|
+
context: TContext;
|
|
199
|
+
events: PraxisEvent[];
|
|
200
|
+
}, events: PraxisEvent[]) => RuleResult;
|
|
201
|
+
/**
|
|
202
|
+
* Convenience: create a fact object (just a shorthand)
|
|
203
|
+
*/
|
|
204
|
+
declare function fact(tag: string, payload: unknown): PraxisFact;
|
|
205
|
+
|
|
206
|
+
export { type PraxisState as P, RuleResult as R, type TypedRuleFn as T, type PraxisEvent as a, type PraxisFact as b, type PraxisStepResult as c, type PraxisStepConfig as d, type PraxisDiagnostics as e, PRAXIS_PROTOCOL_VERSION as f, type PraxisStepFn as g, fact as h };
|