@plures/praxis 0.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 +420 -0
- package/LICENSE +21 -0
- package/README.md +1310 -0
- package/dist/adapters/cli.d.ts +43 -0
- package/dist/adapters/cli.d.ts.map +1 -0
- package/dist/adapters/cli.js +126 -0
- package/dist/adapters/cli.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +26 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +233 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/cloud.d.ts +27 -0
- package/dist/cli/commands/cloud.d.ts.map +1 -0
- package/dist/cli/commands/cloud.js +232 -0
- package/dist/cli/commands/cloud.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +25 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +168 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +179 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cloud/auth.d.ts +51 -0
- package/dist/cloud/auth.d.ts.map +1 -0
- package/dist/cloud/auth.js +194 -0
- package/dist/cloud/auth.js.map +1 -0
- package/dist/cloud/billing.d.ts +184 -0
- package/dist/cloud/billing.d.ts.map +1 -0
- package/dist/cloud/billing.js +179 -0
- package/dist/cloud/billing.js.map +1 -0
- package/dist/cloud/client.d.ts +39 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +176 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/index.d.ts +44 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +44 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/marketplace.d.ts +166 -0
- package/dist/cloud/marketplace.d.ts.map +1 -0
- package/dist/cloud/marketplace.js +159 -0
- package/dist/cloud/marketplace.js.map +1 -0
- package/dist/cloud/provisioning.d.ts +110 -0
- package/dist/cloud/provisioning.d.ts.map +1 -0
- package/dist/cloud/provisioning.js +148 -0
- package/dist/cloud/provisioning.js.map +1 -0
- package/dist/cloud/relay/endpoints.d.ts +62 -0
- package/dist/cloud/relay/endpoints.d.ts.map +1 -0
- package/dist/cloud/relay/endpoints.js +217 -0
- package/dist/cloud/relay/endpoints.js.map +1 -0
- package/dist/cloud/relay/health/index.d.ts +5 -0
- package/dist/cloud/relay/health/index.d.ts.map +1 -0
- package/dist/cloud/relay/health/index.js +9 -0
- package/dist/cloud/relay/health/index.js.map +1 -0
- package/dist/cloud/relay/stats/index.d.ts +5 -0
- package/dist/cloud/relay/stats/index.d.ts.map +1 -0
- package/dist/cloud/relay/stats/index.js +9 -0
- package/dist/cloud/relay/stats/index.js.map +1 -0
- package/dist/cloud/relay/sync/index.d.ts +5 -0
- package/dist/cloud/relay/sync/index.d.ts.map +1 -0
- package/dist/cloud/relay/sync/index.js +9 -0
- package/dist/cloud/relay/sync/index.js.map +1 -0
- package/dist/cloud/relay/usage/index.d.ts +5 -0
- package/dist/cloud/relay/usage/index.d.ts.map +1 -0
- package/dist/cloud/relay/usage/index.js +9 -0
- package/dist/cloud/relay/usage/index.js.map +1 -0
- package/dist/cloud/sponsors.d.ts +81 -0
- package/dist/cloud/sponsors.d.ts.map +1 -0
- package/dist/cloud/sponsors.js +130 -0
- package/dist/cloud/sponsors.js.map +1 -0
- package/dist/cloud/types.d.ts +169 -0
- package/dist/cloud/types.d.ts.map +1 -0
- package/dist/cloud/types.js +7 -0
- package/dist/cloud/types.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +17 -0
- package/dist/components/index.js.map +1 -0
- package/dist/core/actors.d.ts +95 -0
- package/dist/core/actors.d.ts.map +1 -0
- package/dist/core/actors.js +158 -0
- package/dist/core/actors.js.map +1 -0
- package/dist/core/component/generator.d.ts +122 -0
- package/dist/core/component/generator.d.ts.map +1 -0
- package/dist/core/component/generator.js +307 -0
- package/dist/core/component/generator.js.map +1 -0
- package/dist/core/engine.d.ts +92 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +199 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/introspection.d.ts +141 -0
- package/dist/core/introspection.d.ts.map +1 -0
- package/dist/core/introspection.js +208 -0
- package/dist/core/introspection.js.map +1 -0
- package/dist/core/logic/generator.d.ts +76 -0
- package/dist/core/logic/generator.d.ts.map +1 -0
- package/dist/core/logic/generator.js +339 -0
- package/dist/core/logic/generator.js.map +1 -0
- package/dist/core/pluresdb/generator.d.ts +58 -0
- package/dist/core/pluresdb/generator.d.ts.map +1 -0
- package/dist/core/pluresdb/generator.js +162 -0
- package/dist/core/pluresdb/generator.js.map +1 -0
- package/dist/core/protocol.d.ts +121 -0
- package/dist/core/protocol.d.ts.map +1 -0
- package/dist/core/protocol.js +46 -0
- package/dist/core/protocol.js.map +1 -0
- package/dist/core/rules.d.ts +120 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +81 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema/loader.d.ts +47 -0
- package/dist/core/schema/loader.d.ts.map +1 -0
- package/dist/core/schema/loader.js +189 -0
- package/dist/core/schema/loader.js.map +1 -0
- package/dist/core/schema/normalize.d.ts +72 -0
- package/dist/core/schema/normalize.d.ts.map +1 -0
- package/dist/core/schema/normalize.js +190 -0
- package/dist/core/schema/normalize.js.map +1 -0
- package/dist/core/schema/types.d.ts +370 -0
- package/dist/core/schema/types.d.ts.map +1 -0
- package/dist/core/schema/types.js +161 -0
- package/dist/core/schema/types.js.map +1 -0
- package/dist/dsl/index.d.ts +152 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +132 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl.d.ts +124 -0
- package/dist/dsl.d.ts.map +1 -0
- package/dist/dsl.js +130 -0
- package/dist/dsl.js.map +1 -0
- package/dist/examples/advanced-todo/index.d.ts +55 -0
- package/dist/examples/advanced-todo/index.d.ts.map +1 -0
- package/dist/examples/advanced-todo/index.js +222 -0
- package/dist/examples/advanced-todo/index.js.map +1 -0
- package/dist/examples/auth-basic/index.d.ts +17 -0
- package/dist/examples/auth-basic/index.d.ts.map +1 -0
- package/dist/examples/auth-basic/index.js +122 -0
- package/dist/examples/auth-basic/index.js.map +1 -0
- package/dist/examples/cart/index.d.ts +19 -0
- package/dist/examples/cart/index.d.ts.map +1 -0
- package/dist/examples/cart/index.js +202 -0
- package/dist/examples/cart/index.js.map +1 -0
- package/dist/examples/hero-ecommerce/index.d.ts +39 -0
- package/dist/examples/hero-ecommerce/index.d.ts.map +1 -0
- package/dist/examples/hero-ecommerce/index.js +506 -0
- package/dist/examples/hero-ecommerce/index.js.map +1 -0
- package/dist/examples/svelte-counter/index.d.ts +31 -0
- package/dist/examples/svelte-counter/index.d.ts.map +1 -0
- package/dist/examples/svelte-counter/index.js +123 -0
- package/dist/examples/svelte-counter/index.js.map +1 -0
- package/dist/flows.d.ts +125 -0
- package/dist/flows.d.ts.map +1 -0
- package/dist/flows.js +160 -0
- package/dist/flows.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/pluresdb.d.ts +56 -0
- package/dist/integrations/pluresdb.d.ts.map +1 -0
- package/dist/integrations/pluresdb.js +46 -0
- package/dist/integrations/pluresdb.js.map +1 -0
- package/dist/integrations/svelte.d.ts +306 -0
- package/dist/integrations/svelte.d.ts.map +1 -0
- package/dist/integrations/svelte.js +447 -0
- package/dist/integrations/svelte.js.map +1 -0
- package/dist/registry.d.ts +94 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +181 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime/terminal-adapter.d.ts +105 -0
- package/dist/runtime/terminal-adapter.d.ts.map +1 -0
- package/dist/runtime/terminal-adapter.js +113 -0
- package/dist/runtime/terminal-adapter.js.map +1 -0
- package/dist/step.d.ts +34 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +111 -0
- package/dist/step.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/docs/MONETIZATION.md +394 -0
- package/docs/TERMINAL_NODE.md +588 -0
- package/docs/guides/canvas.md +389 -0
- package/docs/guides/getting-started.md +347 -0
- package/docs/guides/history-state-pattern.md +618 -0
- package/docs/guides/orchestration.md +617 -0
- package/docs/guides/parallel-state-pattern.md +767 -0
- package/docs/guides/svelte-integration.md +691 -0
- package/package.json +96 -0
- package/src/__tests__/actors.test.ts +270 -0
- package/src/__tests__/billing.test.ts +175 -0
- package/src/__tests__/cloud.test.ts +247 -0
- package/src/__tests__/dsl.test.ts +154 -0
- package/src/__tests__/edge-cases.test.ts +475 -0
- package/src/__tests__/engine.test.ts +137 -0
- package/src/__tests__/generators.test.ts +270 -0
- package/src/__tests__/introspection.test.ts +321 -0
- package/src/__tests__/protocol.test.ts +40 -0
- package/src/__tests__/provisioning.test.ts +162 -0
- package/src/__tests__/schema.test.ts +241 -0
- package/src/__tests__/svelte-integration.test.ts +431 -0
- package/src/__tests__/terminal-node.test.ts +352 -0
- package/src/adapters/cli.ts +175 -0
- package/src/cli/commands/auth.ts +271 -0
- package/src/cli/commands/cloud.ts +281 -0
- package/src/cli/commands/generate.ts +225 -0
- package/src/cli/index.ts +190 -0
- package/src/cloud/README.md +383 -0
- package/src/cloud/auth.ts +245 -0
- package/src/cloud/billing.ts +336 -0
- package/src/cloud/client.ts +221 -0
- package/src/cloud/index.ts +121 -0
- package/src/cloud/marketplace.ts +303 -0
- package/src/cloud/provisioning.ts +254 -0
- package/src/cloud/relay/endpoints.ts +307 -0
- package/src/cloud/relay/health/function.json +17 -0
- package/src/cloud/relay/health/index.ts +10 -0
- package/src/cloud/relay/host.json +15 -0
- package/src/cloud/relay/local.settings.json +8 -0
- package/src/cloud/relay/stats/function.json +17 -0
- package/src/cloud/relay/stats/index.ts +10 -0
- package/src/cloud/relay/sync/function.json +17 -0
- package/src/cloud/relay/sync/index.ts +10 -0
- package/src/cloud/relay/usage/function.json +17 -0
- package/src/cloud/relay/usage/index.ts +10 -0
- package/src/cloud/sponsors.ts +213 -0
- package/src/cloud/types.ts +198 -0
- package/src/components/README.md +125 -0
- package/src/components/TerminalNode.svelte +457 -0
- package/src/components/index.ts +46 -0
- package/src/core/actors.ts +205 -0
- package/src/core/component/generator.ts +432 -0
- package/src/core/engine.ts +243 -0
- package/src/core/introspection.ts +329 -0
- package/src/core/logic/generator.ts +420 -0
- package/src/core/pluresdb/generator.ts +229 -0
- package/src/core/protocol.ts +132 -0
- package/src/core/rules.ts +167 -0
- package/src/core/schema/loader.ts +247 -0
- package/src/core/schema/normalize.ts +322 -0
- package/src/core/schema/types.ts +557 -0
- package/src/dsl/index.ts +218 -0
- package/src/dsl.ts +214 -0
- package/src/examples/advanced-todo/App.svelte +506 -0
- package/src/examples/advanced-todo/README.md +371 -0
- package/src/examples/advanced-todo/index.ts +309 -0
- package/src/examples/auth-basic/index.ts +163 -0
- package/src/examples/cart/index.ts +259 -0
- package/src/examples/hero-ecommerce/index.ts +657 -0
- package/src/examples/svelte-counter/index.ts +168 -0
- package/src/flows.ts +268 -0
- package/src/index.ts +154 -0
- package/src/integrations/pluresdb.ts +93 -0
- package/src/integrations/svelte.ts +617 -0
- package/src/registry.ts +223 -0
- package/src/runtime/terminal-adapter.ts +175 -0
- package/src/step.ts +151 -0
- package/src/types.ts +70 -0
- package/templates/basic-app/README.md +147 -0
- package/templates/fullstack-app/README.md +279 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Praxis Schema System
|
|
3
|
+
*
|
|
4
|
+
* Declarative schema definitions for generating models, components, logic, and documentation.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Validate a Praxis schema
|
|
8
|
+
*/
|
|
9
|
+
export function validateSchema(schema) {
|
|
10
|
+
const errors = [];
|
|
11
|
+
// Basic validation
|
|
12
|
+
if (!schema.version) {
|
|
13
|
+
errors.push({ path: 'version', message: 'Schema version is required' });
|
|
14
|
+
}
|
|
15
|
+
if (!schema.name) {
|
|
16
|
+
errors.push({ path: 'name', message: 'Schema name is required' });
|
|
17
|
+
}
|
|
18
|
+
// Validate models
|
|
19
|
+
if (schema.models) {
|
|
20
|
+
schema.models.forEach((model, index) => {
|
|
21
|
+
if (!model.name) {
|
|
22
|
+
errors.push({
|
|
23
|
+
path: `models[${index}].name`,
|
|
24
|
+
message: 'Model name is required',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (!model.fields || model.fields.length === 0) {
|
|
28
|
+
errors.push({
|
|
29
|
+
path: `models[${index}].fields`,
|
|
30
|
+
message: 'Model must have at least one field',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// Validate components
|
|
36
|
+
if (schema.components) {
|
|
37
|
+
schema.components.forEach((component, index) => {
|
|
38
|
+
if (!component.name) {
|
|
39
|
+
errors.push({
|
|
40
|
+
path: `components[${index}].name`,
|
|
41
|
+
message: 'Component name is required',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!component.type) {
|
|
45
|
+
errors.push({
|
|
46
|
+
path: `components[${index}].type`,
|
|
47
|
+
message: 'Component type is required',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Validate logic definitions
|
|
53
|
+
if (schema.logic) {
|
|
54
|
+
schema.logic.forEach((logic, logicIndex) => {
|
|
55
|
+
// Validate fact tags
|
|
56
|
+
if (logic.facts) {
|
|
57
|
+
logic.facts.forEach((fact, factIndex) => {
|
|
58
|
+
if (!fact.tag) {
|
|
59
|
+
errors.push({
|
|
60
|
+
path: `logic[${logicIndex}].facts[${factIndex}].tag`,
|
|
61
|
+
message: 'Fact tag is required',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else if (!isValidIdentifier(fact.tag)) {
|
|
65
|
+
errors.push({
|
|
66
|
+
path: `logic[${logicIndex}].facts[${factIndex}].tag`,
|
|
67
|
+
message: `Fact tag "${fact.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Validate event tags
|
|
73
|
+
if (logic.events) {
|
|
74
|
+
logic.events.forEach((event, eventIndex) => {
|
|
75
|
+
if (!event.tag) {
|
|
76
|
+
errors.push({
|
|
77
|
+
path: `logic[${logicIndex}].events[${eventIndex}].tag`,
|
|
78
|
+
message: 'Event tag is required',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else if (!isValidIdentifier(event.tag)) {
|
|
82
|
+
errors.push({
|
|
83
|
+
path: `logic[${logicIndex}].events[${eventIndex}].tag`,
|
|
84
|
+
message: `Event tag "${event.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Validate orchestration nodes
|
|
92
|
+
if (schema.orchestration?.nodes) {
|
|
93
|
+
schema.orchestration.nodes.forEach((node, index) => {
|
|
94
|
+
if (!node.id) {
|
|
95
|
+
errors.push({
|
|
96
|
+
path: `orchestration.nodes[${index}].id`,
|
|
97
|
+
message: 'Node id is required',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (!node.type) {
|
|
101
|
+
errors.push({
|
|
102
|
+
path: `orchestration.nodes[${index}].type`,
|
|
103
|
+
message: 'Node type is required',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Validate terminal node specific props
|
|
107
|
+
if (node.type === 'terminal' && node.props) {
|
|
108
|
+
const props = node.props;
|
|
109
|
+
if (props.inputMode && !['text', 'widget'].includes(props.inputMode)) {
|
|
110
|
+
errors.push({
|
|
111
|
+
path: `orchestration.nodes[${index}].props.inputMode`,
|
|
112
|
+
message: 'Terminal node inputMode must be "text" or "widget"',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (props.history && !Array.isArray(props.history)) {
|
|
116
|
+
errors.push({
|
|
117
|
+
path: `orchestration.nodes[${index}].props.history`,
|
|
118
|
+
message: 'Terminal node history must be an array',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
valid: errors.length === 0,
|
|
126
|
+
errors,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a string is a valid JavaScript identifier
|
|
131
|
+
*/
|
|
132
|
+
function isValidIdentifier(str) {
|
|
133
|
+
// JavaScript identifier must start with letter, $, or _
|
|
134
|
+
// and can contain letters, digits, $, or _
|
|
135
|
+
const identifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
136
|
+
// Also check that it's not a reserved keyword
|
|
137
|
+
const reservedKeywords = [
|
|
138
|
+
'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
|
|
139
|
+
'default', 'delete', 'do', 'else', 'export', 'extends', 'finally',
|
|
140
|
+
'for', 'function', 'if', 'import', 'in', 'instanceof', 'new',
|
|
141
|
+
'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof',
|
|
142
|
+
'var', 'void', 'while', 'with', 'yield', 'let', 'static',
|
|
143
|
+
'enum', 'await', 'implements', 'interface', 'package', 'private',
|
|
144
|
+
'protected', 'public',
|
|
145
|
+
];
|
|
146
|
+
return identifierRegex.test(str) && !reservedKeywords.includes(str);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Create a basic schema template
|
|
150
|
+
*/
|
|
151
|
+
export function createSchemaTemplate(name) {
|
|
152
|
+
return {
|
|
153
|
+
version: '1.0.0',
|
|
154
|
+
name,
|
|
155
|
+
description: `Schema for ${name}`,
|
|
156
|
+
models: [],
|
|
157
|
+
components: [],
|
|
158
|
+
logic: [],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/schema/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoYH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,mBAAmB;IACnB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,kBAAkB;IAClB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACrC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,UAAU,KAAK,QAAQ;oBAC7B,OAAO,EAAE,wBAAwB;iBAClC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,UAAU,KAAK,UAAU;oBAC/B,OAAO,EAAE,oCAAoC;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;YAC7C,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,cAAc,KAAK,QAAQ;oBACjC,OAAO,EAAE,4BAA4B;iBACtC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,cAAc,KAAK,QAAQ;oBACjC,OAAO,EAAE,4BAA4B;iBACtC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6BAA6B;IAC7B,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;YACzC,qBAAqB;YACrB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;oBACtC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;wBACd,MAAM,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,SAAS,UAAU,WAAW,SAAS,OAAO;4BACpD,OAAO,EAAE,sBAAsB;yBAChC,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACxC,MAAM,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,SAAS,UAAU,WAAW,SAAS,OAAO;4BACpD,OAAO,EAAE,aAAa,IAAI,CAAC,GAAG,mIAAmI;yBAClK,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAED,sBAAsB;YACtB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;oBACzC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,SAAS,UAAU,YAAY,UAAU,OAAO;4BACtD,OAAO,EAAE,uBAAuB;yBACjC,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzC,MAAM,CAAC,IAAI,CAAC;4BACV,IAAI,EAAE,SAAS,UAAU,YAAY,UAAU,OAAO;4BACtD,OAAO,EAAE,cAAc,KAAK,CAAC,GAAG,mIAAmI;yBACpK,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+BAA+B;IAC/B,IAAI,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,uBAAuB,KAAK,MAAM;oBACxC,OAAO,EAAE,qBAAqB;iBAC/B,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,uBAAuB,KAAK,QAAQ;oBAC1C,OAAO,EAAE,uBAAuB;iBACjC,CAAC,CAAC;YACL,CAAC;YAED,wCAAwC;YACxC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAmC,CAAC;gBACvD,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;oBACrE,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,uBAAuB,KAAK,mBAAmB;wBACrD,OAAO,EAAE,oDAAoD;qBAC9D,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;oBACnD,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,uBAAuB,KAAK,iBAAiB;wBACnD,OAAO,EAAE,wCAAwC;qBAClD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,wDAAwD;IACxD,2CAA2C;IAC3C,MAAM,eAAe,GAAG,4BAA4B,CAAC;IAErD,8CAA8C;IAC9C,MAAM,gBAAgB,GAAG;QACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU;QAClE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;QACjE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK;QAC5D,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ;QAC7D,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ;QACxD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS;QAChE,WAAW,EAAE,QAAQ;KACtB,CAAC;IAEF,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI;QACJ,WAAW,EAAE,cAAc,IAAI,EAAE;QACjC,MAAM,EAAE,EAAE;QACV,UAAU,EAAE,EAAE;QACd,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSL Helpers
|
|
3
|
+
*
|
|
4
|
+
* Ergonomic TypeScript helpers for defining facts, events, rules, constraints, and flows.
|
|
5
|
+
* These produce both strongly-typed APIs and serializable descriptors.
|
|
6
|
+
*/
|
|
7
|
+
import type { PraxisEvent, PraxisFact } from "../core/protocol.js";
|
|
8
|
+
import type { RuleDescriptor, ConstraintDescriptor, PraxisModule, RuleFn, ConstraintFn } from "../core/rules.js";
|
|
9
|
+
/**
|
|
10
|
+
* Strongly typed fact definition
|
|
11
|
+
*/
|
|
12
|
+
export interface FactDefinition<TTag extends string, TPayload> {
|
|
13
|
+
tag: TTag;
|
|
14
|
+
create(payload: TPayload): PraxisFact & {
|
|
15
|
+
tag: TTag;
|
|
16
|
+
payload: TPayload;
|
|
17
|
+
};
|
|
18
|
+
is(fact: PraxisFact): fact is PraxisFact & {
|
|
19
|
+
tag: TTag;
|
|
20
|
+
payload: TPayload;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Define a typed fact
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const UserLoggedIn = defineFact<"UserLoggedIn", { userId: string }>("UserLoggedIn");
|
|
28
|
+
* const fact = UserLoggedIn.create({ userId: "123" });
|
|
29
|
+
* if (UserLoggedIn.is(fact)) {
|
|
30
|
+
* console.log(fact.payload.userId); // Type-safe!
|
|
31
|
+
* }
|
|
32
|
+
*/
|
|
33
|
+
export declare function defineFact<TTag extends string, TPayload>(tag: TTag): FactDefinition<TTag, TPayload>;
|
|
34
|
+
/**
|
|
35
|
+
* Strongly typed event definition
|
|
36
|
+
*/
|
|
37
|
+
export interface EventDefinition<TTag extends string, TPayload> {
|
|
38
|
+
tag: TTag;
|
|
39
|
+
create(payload: TPayload): PraxisEvent & {
|
|
40
|
+
tag: TTag;
|
|
41
|
+
payload: TPayload;
|
|
42
|
+
};
|
|
43
|
+
is(event: PraxisEvent): event is PraxisEvent & {
|
|
44
|
+
tag: TTag;
|
|
45
|
+
payload: TPayload;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Define a typed event
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const Login = defineEvent<"LOGIN", { username: string; password: string }>("LOGIN");
|
|
53
|
+
* const event = Login.create({ username: "alice", password: "secret" });
|
|
54
|
+
*/
|
|
55
|
+
export declare function defineEvent<TTag extends string, TPayload>(tag: TTag): EventDefinition<TTag, TPayload>;
|
|
56
|
+
/**
|
|
57
|
+
* Options for defining a rule
|
|
58
|
+
*/
|
|
59
|
+
export interface DefineRuleOptions<TContext = unknown> {
|
|
60
|
+
id: string;
|
|
61
|
+
description: string;
|
|
62
|
+
impl: RuleFn<TContext>;
|
|
63
|
+
meta?: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Define a rule
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const loginRule = defineRule({
|
|
70
|
+
* id: "auth.login",
|
|
71
|
+
* description: "Process login event",
|
|
72
|
+
* impl: (state, events) => {
|
|
73
|
+
* const loginEvent = events.find(Login.is);
|
|
74
|
+
* if (loginEvent) {
|
|
75
|
+
* return [UserLoggedIn.create({ userId: loginEvent.payload.username })];
|
|
76
|
+
* }
|
|
77
|
+
* return [];
|
|
78
|
+
* }
|
|
79
|
+
* });
|
|
80
|
+
*/
|
|
81
|
+
export declare function defineRule<TContext = unknown>(options: DefineRuleOptions<TContext>): RuleDescriptor<TContext>;
|
|
82
|
+
/**
|
|
83
|
+
* Options for defining a constraint
|
|
84
|
+
*/
|
|
85
|
+
export interface DefineConstraintOptions<TContext = unknown> {
|
|
86
|
+
id: string;
|
|
87
|
+
description: string;
|
|
88
|
+
impl: ConstraintFn<TContext>;
|
|
89
|
+
meta?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Define a constraint
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* const maxCartItems = defineConstraint({
|
|
96
|
+
* id: "cart.maxItems",
|
|
97
|
+
* description: "Cart cannot exceed 100 items",
|
|
98
|
+
* impl: (state) => {
|
|
99
|
+
* const itemCount = state.context.items?.length ?? 0;
|
|
100
|
+
* return itemCount <= 100 || `Cart has ${itemCount} items, maximum is 100`;
|
|
101
|
+
* }
|
|
102
|
+
* });
|
|
103
|
+
*/
|
|
104
|
+
export declare function defineConstraint<TContext = unknown>(options: DefineConstraintOptions<TContext>): ConstraintDescriptor<TContext>;
|
|
105
|
+
/**
|
|
106
|
+
* Options for defining a module
|
|
107
|
+
*/
|
|
108
|
+
export interface DefineModuleOptions<TContext = unknown> {
|
|
109
|
+
rules?: RuleDescriptor<TContext>[];
|
|
110
|
+
constraints?: ConstraintDescriptor<TContext>[];
|
|
111
|
+
meta?: Record<string, unknown>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Define a module (bundle of rules and constraints)
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* const authModule = defineModule({
|
|
118
|
+
* rules: [loginRule, logoutRule],
|
|
119
|
+
* constraints: [maxSessionsConstraint],
|
|
120
|
+
* meta: { version: "1.0.0" }
|
|
121
|
+
* });
|
|
122
|
+
*/
|
|
123
|
+
export declare function defineModule<TContext = unknown>(options: DefineModuleOptions<TContext>): PraxisModule<TContext>;
|
|
124
|
+
/**
|
|
125
|
+
* Helper to filter events by definition
|
|
126
|
+
*/
|
|
127
|
+
export declare function filterEvents<TTag extends string, TPayload>(events: PraxisEvent[], definition: EventDefinition<TTag, TPayload>): Array<PraxisEvent & {
|
|
128
|
+
tag: TTag;
|
|
129
|
+
payload: TPayload;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Helper to filter facts by definition
|
|
133
|
+
*/
|
|
134
|
+
export declare function filterFacts<TTag extends string, TPayload>(facts: PraxisFact[], definition: FactDefinition<TTag, TPayload>): Array<PraxisFact & {
|
|
135
|
+
tag: TTag;
|
|
136
|
+
payload: TPayload;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Helper to find first event matching definition
|
|
140
|
+
*/
|
|
141
|
+
export declare function findEvent<TTag extends string, TPayload>(events: PraxisEvent[], definition: EventDefinition<TTag, TPayload>): (PraxisEvent & {
|
|
142
|
+
tag: TTag;
|
|
143
|
+
payload: TPayload;
|
|
144
|
+
}) | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Helper to find first fact matching definition
|
|
147
|
+
*/
|
|
148
|
+
export declare function findFact<TTag extends string, TPayload>(facts: PraxisFact[], definition: FactDefinition<TTag, TPayload>): (PraxisFact & {
|
|
149
|
+
tag: TTag;
|
|
150
|
+
payload: TPayload;
|
|
151
|
+
}) | undefined;
|
|
152
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dsl/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSL Helpers
|
|
3
|
+
*
|
|
4
|
+
* Ergonomic TypeScript helpers for defining facts, events, rules, constraints, and flows.
|
|
5
|
+
* These produce both strongly-typed APIs and serializable descriptors.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Define a typed fact
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const UserLoggedIn = defineFact<"UserLoggedIn", { userId: string }>("UserLoggedIn");
|
|
12
|
+
* const fact = UserLoggedIn.create({ userId: "123" });
|
|
13
|
+
* if (UserLoggedIn.is(fact)) {
|
|
14
|
+
* console.log(fact.payload.userId); // Type-safe!
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
export function defineFact(tag) {
|
|
18
|
+
return {
|
|
19
|
+
tag,
|
|
20
|
+
create(payload) {
|
|
21
|
+
return { tag, payload };
|
|
22
|
+
},
|
|
23
|
+
is(fact) {
|
|
24
|
+
return fact.tag === tag;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Define a typed event
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const Login = defineEvent<"LOGIN", { username: string; password: string }>("LOGIN");
|
|
33
|
+
* const event = Login.create({ username: "alice", password: "secret" });
|
|
34
|
+
*/
|
|
35
|
+
export function defineEvent(tag) {
|
|
36
|
+
return {
|
|
37
|
+
tag,
|
|
38
|
+
create(payload) {
|
|
39
|
+
return { tag, payload };
|
|
40
|
+
},
|
|
41
|
+
is(event) {
|
|
42
|
+
return event.tag === tag;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Define a rule
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const loginRule = defineRule({
|
|
51
|
+
* id: "auth.login",
|
|
52
|
+
* description: "Process login event",
|
|
53
|
+
* impl: (state, events) => {
|
|
54
|
+
* const loginEvent = events.find(Login.is);
|
|
55
|
+
* if (loginEvent) {
|
|
56
|
+
* return [UserLoggedIn.create({ userId: loginEvent.payload.username })];
|
|
57
|
+
* }
|
|
58
|
+
* return [];
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
*/
|
|
62
|
+
export function defineRule(options) {
|
|
63
|
+
return {
|
|
64
|
+
id: options.id,
|
|
65
|
+
description: options.description,
|
|
66
|
+
impl: options.impl,
|
|
67
|
+
meta: options.meta,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Define a constraint
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const maxCartItems = defineConstraint({
|
|
75
|
+
* id: "cart.maxItems",
|
|
76
|
+
* description: "Cart cannot exceed 100 items",
|
|
77
|
+
* impl: (state) => {
|
|
78
|
+
* const itemCount = state.context.items?.length ?? 0;
|
|
79
|
+
* return itemCount <= 100 || `Cart has ${itemCount} items, maximum is 100`;
|
|
80
|
+
* }
|
|
81
|
+
* });
|
|
82
|
+
*/
|
|
83
|
+
export function defineConstraint(options) {
|
|
84
|
+
return {
|
|
85
|
+
id: options.id,
|
|
86
|
+
description: options.description,
|
|
87
|
+
impl: options.impl,
|
|
88
|
+
meta: options.meta,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Define a module (bundle of rules and constraints)
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* const authModule = defineModule({
|
|
96
|
+
* rules: [loginRule, logoutRule],
|
|
97
|
+
* constraints: [maxSessionsConstraint],
|
|
98
|
+
* meta: { version: "1.0.0" }
|
|
99
|
+
* });
|
|
100
|
+
*/
|
|
101
|
+
export function defineModule(options) {
|
|
102
|
+
return {
|
|
103
|
+
rules: options.rules ?? [],
|
|
104
|
+
constraints: options.constraints ?? [],
|
|
105
|
+
meta: options.meta,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Helper to filter events by definition
|
|
110
|
+
*/
|
|
111
|
+
export function filterEvents(events, definition) {
|
|
112
|
+
return events.filter(definition.is);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Helper to filter facts by definition
|
|
116
|
+
*/
|
|
117
|
+
export function filterFacts(facts, definition) {
|
|
118
|
+
return facts.filter(definition.is);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Helper to find first event matching definition
|
|
122
|
+
*/
|
|
123
|
+
export function findEvent(events, definition) {
|
|
124
|
+
return events.find(definition.is);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Helper to find first fact matching definition
|
|
128
|
+
*/
|
|
129
|
+
export function findFact(facts, definition) {
|
|
130
|
+
return facts.find(definition.is);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dsl/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,GAAS;IAET,OAAO;QACL,GAAG;QACH,MAAM,CAAC,OAAiB;YACtB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,EAAE,CAAC,IAAgB;YACjB,OAAO,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC;AAWD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,GAAS;IAET,OAAO;QACL,GAAG;QACH,MAAM,CAAC,OAAiB;YACtB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,EAAE,CAAC,KAAkB;YACnB,OAAO,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC;AAYD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CACxB,OAAoC;IAEpC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC;AAYD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAA0C;IAE1C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC;AAWD;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAsC;IAEtC,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;QACtC,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAqB,EACrB,UAA2C;IAE3C,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,KAAmB,EACnB,UAA0C;IAE1C,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CACvB,MAAqB,EACrB,UAA2C;IAE3C,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAmB,EACnB,UAA0C;IAE1C,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/dsl.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSL for defining rules and constraints in Praxis.
|
|
3
|
+
* Rules are condition-action pairs that fire when conditions are met.
|
|
4
|
+
* Constraints are invariants that must hold true in valid states.
|
|
5
|
+
*/
|
|
6
|
+
import type { PraxisState, PraxisEvent, Effect } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* A condition function that checks if a rule should fire.
|
|
9
|
+
*/
|
|
10
|
+
export type Condition<S extends PraxisState = PraxisState, E extends PraxisEvent = PraxisEvent> = (state: S, event: E) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* An action function that produces effects when a rule fires.
|
|
13
|
+
*/
|
|
14
|
+
export type Action<S extends PraxisState = PraxisState, E extends PraxisEvent = PraxisEvent> = (state: S, event: E) => Effect[];
|
|
15
|
+
/**
|
|
16
|
+
* A rule that fires when its condition is met.
|
|
17
|
+
*/
|
|
18
|
+
export interface Rule<S extends PraxisState = PraxisState, E extends PraxisEvent = PraxisEvent> {
|
|
19
|
+
/** Unique identifier for the rule */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Human-readable description of what the rule does */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Priority for rule execution (higher numbers = higher priority) */
|
|
24
|
+
priority?: number;
|
|
25
|
+
/** Condition that must be true for the rule to fire */
|
|
26
|
+
when: Condition<S, E>;
|
|
27
|
+
/** Action to execute when the rule fires */
|
|
28
|
+
then: Action<S, E>;
|
|
29
|
+
/** Optional event type filter - only check this rule for matching events */
|
|
30
|
+
eventType?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A constraint that must hold true in valid states.
|
|
34
|
+
*/
|
|
35
|
+
export interface Constraint<S extends PraxisState = PraxisState> {
|
|
36
|
+
/** Unique identifier for the constraint */
|
|
37
|
+
id: string;
|
|
38
|
+
/** Human-readable description of the constraint */
|
|
39
|
+
description?: string;
|
|
40
|
+
/** Function that returns true if the constraint is satisfied */
|
|
41
|
+
check: (state: S) => boolean;
|
|
42
|
+
/** Error message to return when constraint is violated */
|
|
43
|
+
errorMessage?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Result of checking a constraint.
|
|
47
|
+
*/
|
|
48
|
+
export interface ConstraintViolation {
|
|
49
|
+
constraintId: string;
|
|
50
|
+
message: string;
|
|
51
|
+
state?: PraxisState;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* DSL builder for creating rules with a fluent interface.
|
|
55
|
+
*/
|
|
56
|
+
export declare class RuleBuilder<S extends PraxisState = PraxisState, E extends PraxisEvent = PraxisEvent> {
|
|
57
|
+
private rule;
|
|
58
|
+
/**
|
|
59
|
+
* Set the rule ID.
|
|
60
|
+
*/
|
|
61
|
+
id(id: string): this;
|
|
62
|
+
/**
|
|
63
|
+
* Set the rule description.
|
|
64
|
+
*/
|
|
65
|
+
describe(description: string): this;
|
|
66
|
+
/**
|
|
67
|
+
* Set the rule priority.
|
|
68
|
+
*/
|
|
69
|
+
priority(priority: number): this;
|
|
70
|
+
/**
|
|
71
|
+
* Set the event type filter.
|
|
72
|
+
*/
|
|
73
|
+
on(eventType: string): this;
|
|
74
|
+
/**
|
|
75
|
+
* Set the condition for when the rule should fire.
|
|
76
|
+
*/
|
|
77
|
+
when(condition: Condition<S, E>): this;
|
|
78
|
+
/**
|
|
79
|
+
* Set the action to execute when the rule fires.
|
|
80
|
+
*/
|
|
81
|
+
then(action: Action<S, E>): this;
|
|
82
|
+
/**
|
|
83
|
+
* Build the final rule.
|
|
84
|
+
*/
|
|
85
|
+
build(): Rule<S, E>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* DSL builder for creating constraints with a fluent interface.
|
|
89
|
+
*/
|
|
90
|
+
export declare class ConstraintBuilder<S extends PraxisState = PraxisState> {
|
|
91
|
+
private constraint;
|
|
92
|
+
/**
|
|
93
|
+
* Set the constraint ID.
|
|
94
|
+
*/
|
|
95
|
+
id(id: string): this;
|
|
96
|
+
/**
|
|
97
|
+
* Set the constraint description.
|
|
98
|
+
*/
|
|
99
|
+
describe(description: string): this;
|
|
100
|
+
/**
|
|
101
|
+
* Set the constraint check function.
|
|
102
|
+
*/
|
|
103
|
+
check(check: (state: S) => boolean): this;
|
|
104
|
+
/**
|
|
105
|
+
* Set the error message for constraint violations.
|
|
106
|
+
*/
|
|
107
|
+
message(errorMessage: string): this;
|
|
108
|
+
/**
|
|
109
|
+
* Build the final constraint.
|
|
110
|
+
*/
|
|
111
|
+
build(): Constraint<S>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Factory functions for creating rules and constraints using the DSL.
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* Create a new rule using the fluent builder API.
|
|
118
|
+
*/
|
|
119
|
+
export declare function rule<S extends PraxisState = PraxisState, E extends PraxisEvent = PraxisEvent>(): RuleBuilder<S, E>;
|
|
120
|
+
/**
|
|
121
|
+
* Create a new constraint using the fluent builder API.
|
|
122
|
+
*/
|
|
123
|
+
export declare function constraint<S extends PraxisState = PraxisState>(): ConstraintBuilder<S>;
|
|
124
|
+
//# sourceMappingURL=dsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsl.d.ts","sourceRoot":"","sources":["../src/dsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,SAAS,CACnB,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,SAAS,WAAW,GAAG,WAAW,IACjC,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,MAAM,CAChB,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,SAAS,WAAW,GAAG,WAAW,IACjC,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,IAAI,CACnB,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,SAAS,WAAW,GAAG,WAAW;IAEnC,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IAC7D,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;IAC7B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,WAAW,CACtB,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,SAAS,WAAW,GAAG,WAAW;IAEnC,OAAO,CAAC,IAAI,CAA2B;IAEvC;;OAEG;IACH,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKpB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKhC;;OAEG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK3B;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IAKtC;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IAKhC;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;CAYpB;AAED;;GAEG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IAChE,OAAO,CAAC,UAAU,CAA8B;IAEhD;;OAEG;IACH,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKpB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI;IAKzC;;OAEG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC;CASvB;AAED;;GAEG;AAEH;;GAEG;AACH,wBAAgB,IAAI,CAClB,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,SAAS,WAAW,GAAG,WAAW,KAChC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAErB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,KAAK,iBAAiB,CAAC,CAAC,CAAC,CAEtF"}
|