@plures/praxis 1.4.4 → 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-6MVRT7CK.js +363 -0
- package/dist/browser/factory/index.d.ts +2 -1
- package/dist/browser/index.d.ts +7 -4
- package/dist/browser/index.js +18 -6
- package/dist/browser/integrations/svelte.d.ts +4 -3
- package/dist/browser/project/index.d.ts +2 -1
- package/dist/browser/{reactive-engine.svelte-DgVTqHLc.d.ts → reactive-engine.svelte-BwWadvAW.d.ts} +2 -1
- package/dist/browser/rule-result-DcXWe9tn.d.ts +206 -0
- package/dist/browser/{rules-i1LHpnGd.d.ts → rules-BaWMqxuG.d.ts} +2 -205
- 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/cli/index.js +1 -1
- package/dist/node/index.cjs +367 -0
- package/dist/node/index.d.cts +4 -2
- package/dist/node/index.d.ts +4 -2
- package/dist/node/index.js +19 -7
- package/dist/node/integrations/svelte.d.cts +3 -2
- package/dist/node/integrations/svelte.d.ts +3 -2
- package/dist/node/integrations/svelte.js +2 -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/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/package.json +7 -1
- package/src/index.browser.ts +20 -0
- package/src/index.ts +21 -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/node/{chunk-ZO2LU4G4.js → chunk-WFRHXZBP.js} +3 -3
- package/dist/node/{validate-5PSWJTIC.js → validate-BY7JNY7H.js} +1 -1
|
@@ -1,130 +1,4 @@
|
|
|
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;
|
|
1
|
+
import { P as PraxisState, a as PraxisEvent, R as RuleResult, b as PraxisFact } from './rule-result-DcXWe9tn.js';
|
|
128
2
|
|
|
129
3
|
/**
|
|
130
4
|
* Decision Ledger - Contract Types
|
|
@@ -225,83 +99,6 @@ interface ContractGap {
|
|
|
225
99
|
message?: string;
|
|
226
100
|
}
|
|
227
101
|
|
|
228
|
-
/**
|
|
229
|
-
* The result of evaluating a rule. Every rule MUST return one of:
|
|
230
|
-
* - `RuleResult.emit(facts)` — rule produced facts
|
|
231
|
-
* - `RuleResult.noop(reason?)` — rule evaluated but had nothing to say
|
|
232
|
-
* - `RuleResult.skip(reason?)` — rule decided to skip (preconditions not met)
|
|
233
|
-
* - `RuleResult.retract(tags)` — rule retracts previously emitted facts
|
|
234
|
-
*/
|
|
235
|
-
declare class RuleResult {
|
|
236
|
-
/** The kind of result */
|
|
237
|
-
readonly kind: 'emit' | 'noop' | 'skip' | 'retract';
|
|
238
|
-
/** Facts produced (only for 'emit') */
|
|
239
|
-
readonly facts: PraxisFact[];
|
|
240
|
-
/** Fact tags to retract (only for 'retract') */
|
|
241
|
-
readonly retractTags: string[];
|
|
242
|
-
/** Optional reason (for noop/skip/retract — useful for debugging) */
|
|
243
|
-
readonly reason?: string;
|
|
244
|
-
/** The rule ID that produced this result (set by engine) */
|
|
245
|
-
ruleId?: string;
|
|
246
|
-
private constructor();
|
|
247
|
-
/**
|
|
248
|
-
* Rule produced facts.
|
|
249
|
-
*
|
|
250
|
-
* @example
|
|
251
|
-
* return RuleResult.emit([
|
|
252
|
-
* { tag: 'sprint.behind', payload: { deficit: 5 } }
|
|
253
|
-
* ]);
|
|
254
|
-
*/
|
|
255
|
-
static emit(facts: PraxisFact[]): RuleResult;
|
|
256
|
-
/**
|
|
257
|
-
* Rule evaluated but had nothing to report.
|
|
258
|
-
* Unlike returning [], this is explicit and traceable.
|
|
259
|
-
*
|
|
260
|
-
* @example
|
|
261
|
-
* if (ctx.completedHours >= expectedHours) {
|
|
262
|
-
* return RuleResult.noop('Sprint is on pace');
|
|
263
|
-
* }
|
|
264
|
-
*/
|
|
265
|
-
static noop(reason?: string): RuleResult;
|
|
266
|
-
/**
|
|
267
|
-
* Rule decided to skip because preconditions were not met.
|
|
268
|
-
* Distinct from noop: skip means "I can't evaluate", noop means "I evaluated and found nothing".
|
|
269
|
-
*
|
|
270
|
-
* @example
|
|
271
|
-
* if (!ctx.sprintName) {
|
|
272
|
-
* return RuleResult.skip('No active sprint');
|
|
273
|
-
* }
|
|
274
|
-
*/
|
|
275
|
-
static skip(reason?: string): RuleResult;
|
|
276
|
-
/**
|
|
277
|
-
* Rule retracts previously emitted facts by tag.
|
|
278
|
-
* Used when a condition that previously produced facts is no longer true.
|
|
279
|
-
*
|
|
280
|
-
* @example
|
|
281
|
-
* // Sprint was behind, but caught up
|
|
282
|
-
* if (ctx.completedHours >= expectedHours) {
|
|
283
|
-
* return RuleResult.retract(['sprint.behind'], 'Sprint caught up');
|
|
284
|
-
* }
|
|
285
|
-
*/
|
|
286
|
-
static retract(tags: string[], reason?: string): RuleResult;
|
|
287
|
-
/** Whether this result produced facts */
|
|
288
|
-
get hasFacts(): boolean;
|
|
289
|
-
/** Whether this result retracts facts */
|
|
290
|
-
get hasRetractions(): boolean;
|
|
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;
|
|
304
|
-
|
|
305
102
|
/**
|
|
306
103
|
* Rules and Constraints System
|
|
307
104
|
*
|
|
@@ -477,4 +274,4 @@ declare class PraxisRegistry<TContext = unknown> {
|
|
|
477
274
|
private validateDescriptorContract;
|
|
478
275
|
}
|
|
479
276
|
|
|
480
|
-
export { type ConstraintDescriptor as C,
|
|
277
|
+
export { type ConstraintDescriptor as C, PraxisRegistry as P, type RuleDescriptor as R, type ConstraintFn as a, type Contract as b, type RuleFn as c, type PraxisModule as d, type ConstraintId as e, type RuleId as f };
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { e as PraxisDiagnostics, b as PraxisFact, R as RuleResult } from '../rule-result-DcXWe9tn.js';
|
|
2
|
+
export { h as fact } from '../rule-result-DcXWe9tn.js';
|
|
3
|
+
|
|
4
|
+
/** Minimal store contract — anything with subscribe() */
|
|
5
|
+
interface Subscribable<T> {
|
|
6
|
+
subscribe(cb: (value: T) => void): (() => void) | {
|
|
7
|
+
unsubscribe(): void;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/** Schema definition for a graph path */
|
|
11
|
+
interface PathSchema<T = unknown> {
|
|
12
|
+
/** The graph path (e.g., 'sprint/current') */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Default/initial value */
|
|
15
|
+
initial: T;
|
|
16
|
+
/** Optional TTL for staleness detection (ms) */
|
|
17
|
+
staleTtl?: number;
|
|
18
|
+
/** Whether this path is a collection (maps over children) */
|
|
19
|
+
collection?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Define a typed graph path.
|
|
23
|
+
* This is the primary API for declaring what data exists in your app.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const Sprint = definePath<SprintInfo | null>('sprint/current', null);
|
|
27
|
+
* const Items = definePath<WorkItem[]>('sprint/items', [], { collection: true });
|
|
28
|
+
* const Loading = definePath<boolean>('sprint/loading', false);
|
|
29
|
+
*/
|
|
30
|
+
declare function definePath<T>(path: string, initial: T, opts?: Omit<PathSchema<T>, 'path' | 'initial'>): PathSchema<T>;
|
|
31
|
+
interface QueryOptions<T> {
|
|
32
|
+
/** Filter function for collections */
|
|
33
|
+
where?: (item: T extends (infer U)[] ? U : T) => boolean;
|
|
34
|
+
/** Select/map function */
|
|
35
|
+
select?: (item: T) => unknown;
|
|
36
|
+
/** Sort comparator */
|
|
37
|
+
sort?: (a: any, b: any) => number;
|
|
38
|
+
/** Limit results */
|
|
39
|
+
limit?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A reactive reference returned by query().
|
|
43
|
+
* Has a Svelte-compatible subscribe() and a .current getter.
|
|
44
|
+
*/
|
|
45
|
+
interface ReactiveRef<T> extends Subscribable<T> {
|
|
46
|
+
/** Current value (synchronous read) */
|
|
47
|
+
readonly current: T;
|
|
48
|
+
/** Svelte store contract — subscribe returns unsubscribe fn */
|
|
49
|
+
subscribe(cb: (value: T) => void): () => void;
|
|
50
|
+
}
|
|
51
|
+
interface MutationResult {
|
|
52
|
+
/** Whether the mutation was accepted */
|
|
53
|
+
accepted: boolean;
|
|
54
|
+
/** Constraint violations that blocked the mutation (if any) */
|
|
55
|
+
violations: PraxisDiagnostics[];
|
|
56
|
+
/** Facts emitted by rules triggered by this mutation */
|
|
57
|
+
facts: PraxisFact[];
|
|
58
|
+
}
|
|
59
|
+
interface UnifiedRule {
|
|
60
|
+
/** Unique rule ID */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Human-readable description */
|
|
63
|
+
description?: string;
|
|
64
|
+
/** Graph paths this rule watches — auto-subscribed */
|
|
65
|
+
watch: string[];
|
|
66
|
+
/** Rule evaluation function — receives watched values by path */
|
|
67
|
+
evaluate: (values: Record<string, any>, facts: PraxisFact[]) => RuleResult;
|
|
68
|
+
}
|
|
69
|
+
interface UnifiedConstraint {
|
|
70
|
+
/** Unique constraint ID */
|
|
71
|
+
id: string;
|
|
72
|
+
/** Human-readable description */
|
|
73
|
+
description?: string;
|
|
74
|
+
/** Graph paths this constraint reads */
|
|
75
|
+
watch: string[];
|
|
76
|
+
/** Validation function — return true if valid, string if violated */
|
|
77
|
+
validate: (values: Record<string, any>) => true | string;
|
|
78
|
+
}
|
|
79
|
+
interface LivenessConfig {
|
|
80
|
+
/** Paths that must update within `timeoutMs` after init */
|
|
81
|
+
expect: string[];
|
|
82
|
+
/** Milliseconds to wait before flagging staleness (default: 5000) */
|
|
83
|
+
timeoutMs?: number;
|
|
84
|
+
/** Callback when a path is stale */
|
|
85
|
+
onStale?: (path: string, elapsed: number) => void;
|
|
86
|
+
}
|
|
87
|
+
interface PraxisAppConfig {
|
|
88
|
+
/** App name (used in Chronos context) */
|
|
89
|
+
name: string;
|
|
90
|
+
/** Graph schema — all paths the app uses */
|
|
91
|
+
schema: PathSchema[];
|
|
92
|
+
/** Business rules */
|
|
93
|
+
rules?: UnifiedRule[];
|
|
94
|
+
/** Constraints */
|
|
95
|
+
constraints?: UnifiedConstraint[];
|
|
96
|
+
/** Liveness monitoring */
|
|
97
|
+
liveness?: LivenessConfig;
|
|
98
|
+
/** Chronos options */
|
|
99
|
+
chronos?: {
|
|
100
|
+
batchMs?: number;
|
|
101
|
+
maxBatch?: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Praxis Unified Reactive Layer — Core
|
|
107
|
+
*
|
|
108
|
+
* createApp() → query() / mutate()
|
|
109
|
+
*
|
|
110
|
+
* The developer defines a schema + rules. Praxis handles:
|
|
111
|
+
* - Reactive state (backed by Unum graph DB)
|
|
112
|
+
* - Automatic rule evaluation on state changes
|
|
113
|
+
* - Constraint enforcement on mutations
|
|
114
|
+
* - Chronos logging for every state change
|
|
115
|
+
* - Liveness monitoring (detect broken plumbing)
|
|
116
|
+
* - Svelte-compatible store contract
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface TimelineEntry {
|
|
120
|
+
id: string;
|
|
121
|
+
timestamp: number;
|
|
122
|
+
path: string;
|
|
123
|
+
kind: 'mutation' | 'rule-eval' | 'constraint-check' | 'liveness';
|
|
124
|
+
data: Record<string, unknown>;
|
|
125
|
+
}
|
|
126
|
+
interface PraxisApp {
|
|
127
|
+
/** Reactive query — returns a Svelte-compatible store */
|
|
128
|
+
query: <T>(path: string, opts?: QueryOptions<T>) => ReactiveRef<T>;
|
|
129
|
+
/** Write to the graph — validates through constraints first */
|
|
130
|
+
mutate: (path: string, value: unknown) => MutationResult;
|
|
131
|
+
/** Batch multiple mutations atomically */
|
|
132
|
+
batch: (fn: (mutate: (path: string, value: unknown) => void) => void) => MutationResult;
|
|
133
|
+
/** Current facts */
|
|
134
|
+
facts: () => PraxisFact[];
|
|
135
|
+
/** Current constraint violations */
|
|
136
|
+
violations: () => PraxisDiagnostics[];
|
|
137
|
+
/** Timeline (Chronos entries) */
|
|
138
|
+
timeline: () => TimelineEntry[];
|
|
139
|
+
/** Force re-evaluate all rules */
|
|
140
|
+
evaluate: () => void;
|
|
141
|
+
/** Cleanup */
|
|
142
|
+
destroy: () => void;
|
|
143
|
+
/** Liveness status — which paths are stale */
|
|
144
|
+
liveness: () => Record<string, {
|
|
145
|
+
stale: boolean;
|
|
146
|
+
lastUpdated: number;
|
|
147
|
+
elapsed: number;
|
|
148
|
+
}>;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a Praxis application.
|
|
152
|
+
*
|
|
153
|
+
* This is the single entry point. It creates the reactive graph,
|
|
154
|
+
* wires rules and constraints, starts Chronos logging, and returns
|
|
155
|
+
* query() and mutate() — the only two functions a developer needs.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { createApp, definePath, defineRule } from '@plures/praxis';
|
|
160
|
+
*
|
|
161
|
+
* const Sprint = definePath<SprintInfo | null>('sprint/current', null);
|
|
162
|
+
* const Loading = definePath<boolean>('sprint/loading', false);
|
|
163
|
+
*
|
|
164
|
+
* const app = createApp({
|
|
165
|
+
* name: 'sprint-log',
|
|
166
|
+
* schema: [Sprint, Loading],
|
|
167
|
+
* rules: [sprintBehindRule, capacityRule],
|
|
168
|
+
* constraints: [noCloseWithoutHoursConstraint],
|
|
169
|
+
* });
|
|
170
|
+
*
|
|
171
|
+
* // In a Svelte component:
|
|
172
|
+
* const sprint = app.query<SprintInfo | null>('sprint/current');
|
|
173
|
+
* // $sprint is reactive — updates automatically
|
|
174
|
+
*
|
|
175
|
+
* // To write:
|
|
176
|
+
* app.mutate('sprint/current', sprintData);
|
|
177
|
+
* // Constraints validated, rules re-evaluated, Chronos logged — all automatic
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
declare function createApp(config: PraxisAppConfig): PraxisApp;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Praxis Unified — Rule DSL helpers
|
|
184
|
+
*
|
|
185
|
+
* Developers define rules as plain objects with watch paths.
|
|
186
|
+
* No manual subscriptions, no wirePraxis(), no context mapping.
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Define a rule that watches graph paths and auto-evaluates.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* const sprintBehind = defineRule({
|
|
194
|
+
* id: 'sprint.behind',
|
|
195
|
+
* watch: ['sprint/current'],
|
|
196
|
+
* evaluate: (values) => {
|
|
197
|
+
* const sprint = values['sprint/current'];
|
|
198
|
+
* if (!sprint) return RuleResult.skip('No sprint');
|
|
199
|
+
* const pace = sprint.currentDay / sprint.totalDays;
|
|
200
|
+
* const work = sprint.completedHours / sprint.totalHours;
|
|
201
|
+
* if (work >= pace) return RuleResult.retract(['sprint.behind']);
|
|
202
|
+
* return RuleResult.emit([fact('sprint.behind', { pace, work })]);
|
|
203
|
+
* }
|
|
204
|
+
* });
|
|
205
|
+
*/
|
|
206
|
+
declare function defineRule(rule: UnifiedRule): UnifiedRule;
|
|
207
|
+
/**
|
|
208
|
+
* Define a constraint that validates mutations before they're applied.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* const noCloseWithoutHours = defineConstraint({
|
|
212
|
+
* id: 'no-close-without-hours',
|
|
213
|
+
* description: 'Cannot close a work item with 0 completed hours',
|
|
214
|
+
* watch: ['sprint/items'],
|
|
215
|
+
* validate: (values) => {
|
|
216
|
+
* const items = values['sprint/items'] ?? [];
|
|
217
|
+
* const bad = items.find(i => i.state === 'Closed' && !i.completedWork);
|
|
218
|
+
* if (bad) return `Item #${bad.id} cannot be closed with 0 hours`;
|
|
219
|
+
* return true;
|
|
220
|
+
* }
|
|
221
|
+
* });
|
|
222
|
+
*/
|
|
223
|
+
declare function defineConstraint(constraint: UnifiedConstraint): UnifiedConstraint;
|
|
224
|
+
/**
|
|
225
|
+
* Compose multiple rules into a named module.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* const sprintModule = defineModule('sprint-health', [
|
|
229
|
+
* sprintBehindRule,
|
|
230
|
+
* capacityRule,
|
|
231
|
+
* endNearRule,
|
|
232
|
+
* ]);
|
|
233
|
+
*/
|
|
234
|
+
declare function defineModule(name: string, rules: UnifiedRule[]): {
|
|
235
|
+
name: string;
|
|
236
|
+
rules: UnifiedRule[];
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export { type LivenessConfig, type MutationResult, type PathSchema, type PraxisApp, type PraxisAppConfig, type QueryOptions, type ReactiveRef, RuleResult, type UnifiedConstraint, type UnifiedRule, createApp, defineConstraint, defineModule, definePath, defineRule };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createApp,
|
|
3
|
+
defineConstraint,
|
|
4
|
+
defineModule,
|
|
5
|
+
definePath,
|
|
6
|
+
defineRule
|
|
7
|
+
} from "../chunk-6MVRT7CK.js";
|
|
8
|
+
import {
|
|
9
|
+
RuleResult,
|
|
10
|
+
fact
|
|
11
|
+
} from "../chunk-IG5BJ2MT.js";
|
|
12
|
+
export {
|
|
13
|
+
RuleResult,
|
|
14
|
+
createApp,
|
|
15
|
+
defineConstraint,
|
|
16
|
+
defineModule,
|
|
17
|
+
definePath,
|
|
18
|
+
defineRule,
|
|
19
|
+
fact
|
|
20
|
+
};
|