@plures/praxis 1.1.0 → 1.1.2

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.
@@ -1,65 +1,65 @@
1
- /**
2
- * Praxis Reactive Logic Engine
3
- *
4
- * A Svelte 5 native implementation of the Praxis Logic Engine.
5
- * Uses Runes ($state, $derived, $effect) for fine-grained reactivity.
6
- */
7
-
8
- export interface ReactiveEngineOptions<TContext> {
9
- initialContext: TContext;
10
- initialFacts?: any[];
11
- initialMeta?: Record<string, unknown>;
12
- }
13
-
14
- export class ReactiveLogicEngine<TContext extends object> {
15
- // The single source of truth, reactive by default
16
- // We use $state.raw for things that shouldn't be deeply reactive if needed,
17
- // but for context we usually want deep reactivity.
18
- state = $state<{
19
- context: TContext;
20
- facts: any[];
21
- meta: Record<string, unknown>;
22
- }>({
23
- context: {} as TContext,
24
- facts: [],
25
- meta: {}
26
- });
27
-
28
- constructor(options: ReactiveEngineOptions<TContext>) {
29
- this.state.context = options.initialContext;
30
- this.state.facts = options.initialFacts ?? [];
31
- this.state.meta = options.initialMeta ?? {};
32
- }
33
-
34
- /**
35
- * Access the reactive context directly.
36
- * Consumers can use this in $derived() or $effect().
37
- */
38
- get context() {
39
- return this.state.context;
40
- }
41
-
42
- /**
43
- * Access the reactive facts list.
44
- */
45
- get facts() {
46
- return this.state.facts;
47
- }
48
-
49
- /**
50
- * Apply a mutation to the state.
51
- * This is the "Action" or "Rule" equivalent.
52
- *
53
- * @param mutator A function that receives the state and modifies it.
54
- */
55
- apply(mutator: (state: { context: TContext; facts: any[]; meta: Record<string, unknown> }) => void) {
56
- mutator(this.state);
57
- }
58
-
59
- /**
60
- * Access the reactive meta.
61
- */
62
- get meta() {
63
- return this.state.meta;
64
- }
65
- }
1
+ /**
2
+ * Praxis Reactive Logic Engine
3
+ *
4
+ * A Svelte 5 native implementation of the Praxis Logic Engine.
5
+ * Uses Runes ($state, $derived, $effect) for fine-grained reactivity.
6
+ */
7
+
8
+ export interface ReactiveEngineOptions<TContext> {
9
+ initialContext: TContext;
10
+ initialFacts?: any[];
11
+ initialMeta?: Record<string, unknown>;
12
+ }
13
+
14
+ export class ReactiveLogicEngine<TContext extends object> {
15
+ // The single source of truth, reactive by default
16
+ // We use $state.raw for things that shouldn't be deeply reactive if needed,
17
+ // but for context we usually want deep reactivity.
18
+ state: { context: TContext; facts: any[]; meta: Record<string, unknown> } = $state<{
19
+ context: TContext;
20
+ facts: any[];
21
+ meta: Record<string, unknown>;
22
+ }>({
23
+ context: {} as TContext,
24
+ facts: [],
25
+ meta: {}
26
+ });
27
+
28
+ constructor(options: ReactiveEngineOptions<TContext>) {
29
+ this.state.context = options.initialContext;
30
+ this.state.facts = options.initialFacts ?? [];
31
+ this.state.meta = options.initialMeta ?? {};
32
+ }
33
+
34
+ /**
35
+ * Access the reactive context directly.
36
+ * Consumers can use this in $derived() or $effect().
37
+ */
38
+ get context(): TContext {
39
+ return this.state.context;
40
+ }
41
+
42
+ /**
43
+ * Access the reactive facts list.
44
+ */
45
+ get facts(): any[] {
46
+ return this.state.facts;
47
+ }
48
+
49
+ /**
50
+ * Apply a mutation to the state.
51
+ * This is the "Action" or "Rule" equivalent.
52
+ *
53
+ * @param mutator A function that receives the state and modifies it.
54
+ */
55
+ apply(mutator: (state: { context: TContext; facts: any[]; meta: Record<string, unknown> }) => void): void {
56
+ mutator(this.state);
57
+ }
58
+
59
+ /**
60
+ * Access the reactive meta.
61
+ */
62
+ get meta(): Record<string, unknown> {
63
+ return this.state.meta;
64
+ }
65
+ }
@@ -1,67 +1,58 @@
1
- /**
2
- * Praxis Reactive Logic Engine
3
- *
4
- * A Svelte 5 native implementation of the Praxis Logic Engine.
5
- * Uses Runes ($state, $derived, $effect) for fine-grained reactivity.
6
- */
7
-
8
- console.log("Reactive Engine Loaded");
9
-
10
- export interface ReactiveEngineOptions<TContext> {
11
- initialContext: TContext;
12
- initialFacts?: any[];
13
- initialMeta?: Record<string, unknown>;
14
- }
15
-
16
- export class ReactiveLogicEngine<TContext extends object> {
17
- // The single source of truth, reactive by default
18
- // We use $state.raw for things that shouldn't be deeply reactive if needed,
19
- // but for context we usually want deep reactivity.
20
- state = $state<{
21
- context: TContext;
22
- facts: any[];
23
- meta: Record<string, unknown>;
24
- }>({
25
- context: {} as TContext,
26
- facts: [],
27
- meta: {}
28
- });
29
-
30
- constructor(options: ReactiveEngineOptions<TContext>) {
31
- this.state.context = options.initialContext;
32
- this.state.facts = options.initialFacts ?? [];
33
- this.state.meta = options.initialMeta ?? {};
34
- }
35
-
36
- /**
37
- * Access the reactive context directly.
38
- * Consumers can use this in $derived() or $effect().
39
- */
40
- get context() {
41
- return this.state.context;
42
- }
43
-
44
- /**
45
- * Access the reactive facts list.
46
- */
47
- get facts() {
48
- return this.state.facts;
49
- }
50
-
51
- /**
52
- * Apply a mutation to the state.
53
- * This is the "Action" or "Rule" equivalent.
54
- *
55
- * @param mutator A function that receives the state and modifies it.
56
- */
57
- apply(mutator: (state: { context: TContext; facts: any[]; meta: Record<string, unknown> }) => void) {
58
- mutator(this.state);
59
- }
60
-
61
- /**
62
- * Access the reactive meta.
63
- */
64
- get meta() {
65
- return this.state.meta;
66
- }
67
- }
1
+ /**
2
+ * Praxis Reactive Logic Engine
3
+ *
4
+ * A minimal TypeScript implementation of the Praxis Logic Engine.
5
+ * This variant avoids Svelte-specific reactivity primitives to remain framework-agnostic.
6
+ */
7
+
8
+ export interface ReactiveEngineOptions<TContext> {
9
+ initialContext: TContext;
10
+ initialFacts?: any[];
11
+ initialMeta?: Record<string, unknown>;
12
+ }
13
+
14
+ export class ReactiveLogicEngine<TContext extends object> {
15
+ state: { context: TContext; facts: any[]; meta: Record<string, unknown> } = {
16
+ context: {} as TContext,
17
+ facts: [],
18
+ meta: {}
19
+ };
20
+
21
+ constructor(options: ReactiveEngineOptions<TContext>) {
22
+ this.state.context = options.initialContext;
23
+ this.state.facts = options.initialFacts ?? [];
24
+ this.state.meta = options.initialMeta ?? {};
25
+ }
26
+
27
+ /**
28
+ * Access the context directly.
29
+ * Framework-specific wrappers (e.g., Svelte runes) can build on top of this value.
30
+ */
31
+ get context() {
32
+ return this.state.context;
33
+ }
34
+
35
+ /**
36
+ * Access the facts list.
37
+ */
38
+ get facts() {
39
+ return this.state.facts;
40
+ }
41
+
42
+ /**
43
+ * Apply a mutation to the state.
44
+ * This is the "Action" or "Rule" equivalent.
45
+ *
46
+ * @param mutator A function that receives the state and modifies it.
47
+ */
48
+ apply(mutator: (state: { context: TContext; facts: any[]; meta: Record<string, unknown> }) => void) {
49
+ mutator(this.state);
50
+ }
51
+
52
+ /**
53
+ * Access the metadata.
54
+ */
55
+ get meta() {
56
+ return this.state.meta;
57
+ }
58
+ }
@@ -1,150 +1,150 @@
1
- /**
2
- * Praxis Schema Loader (Common/Browser Compatible)
3
- *
4
- * Core schema loading and validation functions that don't depend on Node.js APIs.
5
- */
6
-
7
- import { load as yamlLoad } from 'js-yaml';
8
- import type { PraxisSchema, ValidationResult } from './types.js';
9
- import { validateSchema } from './types.js';
10
-
11
- /**
12
- * Loader options
13
- */
14
- export interface LoaderOptions {
15
- /** Validate schema after loading */
16
- validate?: boolean;
17
- /** Base directory for resolving relative paths */
18
- baseDir?: string;
19
- }
20
-
21
- /**
22
- * Loader result
23
- */
24
- export interface LoaderResult {
25
- /** Loaded schema */
26
- schema?: PraxisSchema;
27
- /** Validation result */
28
- validation?: ValidationResult;
29
- /** Load errors */
30
- errors: string[];
31
- }
32
-
33
- /**
34
- * Create a new empty schema
35
- */
36
- export function createSchema(name: string): PraxisSchema {
37
- return {
38
- version: '1.0.0',
39
- name,
40
- description: `Schema for ${name}`,
41
- models: [],
42
- components: [],
43
- logic: [],
44
- };
45
- }
46
-
47
- /**
48
- * Load schema from JSON string
49
- */
50
- export function loadSchemaFromJson(json: string, options: LoaderOptions = {}): LoaderResult {
51
- const errors: string[] = [];
52
-
53
- try {
54
- const schema = JSON.parse(json) as PraxisSchema;
55
-
56
- // Validate if requested
57
- let validation: ValidationResult | undefined;
58
- if (options.validate !== false) {
59
- validation = validateSchema(schema);
60
- if (!validation.valid) {
61
- errors.push('Schema validation failed:');
62
- validation.errors.forEach((error) => {
63
- errors.push(` ${error.path}: ${error.message}`);
64
- });
65
- }
66
- }
67
-
68
- return {
69
- schema,
70
- validation,
71
- errors,
72
- };
73
- } catch (error) {
74
- if (error instanceof Error) {
75
- errors.push(`Failed to parse JSON: ${error.message}`);
76
- } else {
77
- errors.push('Failed to parse JSON: Unknown error');
78
- }
79
- return { errors };
80
- }
81
- }
82
-
83
- /**
84
- * Load schema from YAML string
85
- */
86
- export function loadSchemaFromYaml(yaml: string, options: LoaderOptions = {}): LoaderResult {
87
- const errors: string[] = [];
88
-
89
- try {
90
- const schema = yamlLoad(yaml) as PraxisSchema;
91
-
92
- // Validate if requested
93
- let validation: ValidationResult | undefined;
94
- if (options.validate !== false) {
95
- validation = validateSchema(schema);
96
- if (!validation.valid) {
97
- errors.push('Schema validation failed:');
98
- validation.errors.forEach((error) => {
99
- errors.push(` ${error.path}: ${error.message}`);
100
- });
101
- }
102
- }
103
-
104
- return {
105
- schema,
106
- validation,
107
- errors,
108
- };
109
- } catch (error) {
110
- if (error instanceof Error) {
111
- errors.push(`Failed to parse YAML: ${error.message}`);
112
- } else {
113
- errors.push('Failed to parse YAML: Unknown error');
114
- }
115
- return { errors };
116
- }
117
- }
118
-
119
- /**
120
- * Validate that a loaded schema has required fields for generation
121
- */
122
- export function validateForGeneration(schema: PraxisSchema): ValidationResult {
123
- const errors: string[] = [];
124
-
125
- // Check for entities/models
126
- if (!schema.models || schema.models.length === 0) {
127
- errors.push('Schema must define at least one model for generation');
128
- }
129
-
130
- // Check that models have valid fields
131
- schema.models?.forEach((model, index) => {
132
- if (!model.fields || model.fields.length === 0) {
133
- errors.push(`Model "${model.name}" at index ${index} must have at least one field`);
134
- }
135
-
136
- model.fields?.forEach((field, fieldIndex) => {
137
- if (!field.name) {
138
- errors.push(`Field at index ${fieldIndex} in model "${model.name}" must have a name`);
139
- }
140
- if (!field.type) {
141
- errors.push(`Field "${field.name}" in model "${model.name}" must have a type`);
142
- }
143
- });
144
- });
145
-
146
- return {
147
- valid: errors.length === 0,
148
- errors: errors.map((message) => ({ path: 'schema', message })),
149
- };
150
- }
1
+ /**
2
+ * Praxis Schema Loader (Common/Browser Compatible)
3
+ *
4
+ * Core schema loading and validation functions that don't depend on Node.js APIs.
5
+ */
6
+
7
+ import { load as yamlLoad } from 'js-yaml';
8
+ import type { PraxisSchema, ValidationResult } from './types.js';
9
+ import { validateSchema } from './types.js';
10
+
11
+ /**
12
+ * Loader options
13
+ */
14
+ export interface LoaderOptions {
15
+ /** Validate schema after loading */
16
+ validate?: boolean;
17
+ /** Base directory for resolving relative paths */
18
+ baseDir?: string;
19
+ }
20
+
21
+ /**
22
+ * Loader result
23
+ */
24
+ export interface LoaderResult {
25
+ /** Loaded schema */
26
+ schema?: PraxisSchema;
27
+ /** Validation result */
28
+ validation?: ValidationResult;
29
+ /** Load errors */
30
+ errors: string[];
31
+ }
32
+
33
+ /**
34
+ * Create a new empty schema
35
+ */
36
+ export function createSchema(name: string): PraxisSchema {
37
+ return {
38
+ version: '1.0.0',
39
+ name,
40
+ description: `Schema for ${name}`,
41
+ models: [],
42
+ components: [],
43
+ logic: [],
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Load schema from JSON string
49
+ */
50
+ export function loadSchemaFromJson(json: string, options: LoaderOptions = {}): LoaderResult {
51
+ const errors: string[] = [];
52
+
53
+ try {
54
+ const schema = JSON.parse(json) as PraxisSchema;
55
+
56
+ // Validate if requested
57
+ let validation: ValidationResult | undefined;
58
+ if (options.validate !== false) {
59
+ validation = validateSchema(schema);
60
+ if (!validation.valid) {
61
+ errors.push('Schema validation failed:');
62
+ validation.errors.forEach((error) => {
63
+ errors.push(` ${error.path}: ${error.message}`);
64
+ });
65
+ }
66
+ }
67
+
68
+ return {
69
+ schema,
70
+ validation,
71
+ errors,
72
+ };
73
+ } catch (error) {
74
+ if (error instanceof Error) {
75
+ errors.push(`Failed to parse JSON: ${error.message}`);
76
+ } else {
77
+ errors.push('Failed to parse JSON: Unknown error');
78
+ }
79
+ return { errors };
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Load schema from YAML string
85
+ */
86
+ export function loadSchemaFromYaml(yaml: string, options: LoaderOptions = {}): LoaderResult {
87
+ const errors: string[] = [];
88
+
89
+ try {
90
+ const schema = yamlLoad(yaml) as PraxisSchema;
91
+
92
+ // Validate if requested
93
+ let validation: ValidationResult | undefined;
94
+ if (options.validate !== false) {
95
+ validation = validateSchema(schema);
96
+ if (!validation.valid) {
97
+ errors.push('Schema validation failed:');
98
+ validation.errors.forEach((error) => {
99
+ errors.push(` ${error.path}: ${error.message}`);
100
+ });
101
+ }
102
+ }
103
+
104
+ return {
105
+ schema,
106
+ validation,
107
+ errors,
108
+ };
109
+ } catch (error) {
110
+ if (error instanceof Error) {
111
+ errors.push(`Failed to parse YAML: ${error.message}`);
112
+ } else {
113
+ errors.push('Failed to parse YAML: Unknown error');
114
+ }
115
+ return { errors };
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Validate that a loaded schema has required fields for generation
121
+ */
122
+ export function validateForGeneration(schema: PraxisSchema): ValidationResult {
123
+ const errors: string[] = [];
124
+
125
+ // Check for entities/models
126
+ if (!schema.models || schema.models.length === 0) {
127
+ errors.push('Schema must define at least one model for generation');
128
+ }
129
+
130
+ // Check that models have valid fields
131
+ schema.models?.forEach((model, index) => {
132
+ if (!model.fields || model.fields.length === 0) {
133
+ errors.push(`Model "${model.name}" at index ${index} must have at least one field`);
134
+ }
135
+
136
+ model.fields?.forEach((field, fieldIndex) => {
137
+ if (!field.name) {
138
+ errors.push(`Field at index ${fieldIndex} in model "${model.name}" must have a name`);
139
+ }
140
+ if (!field.type) {
141
+ errors.push(`Field "${field.name}" in model "${model.name}" must have a type`);
142
+ }
143
+ });
144
+ });
145
+
146
+ return {
147
+ valid: errors.length === 0,
148
+ errors: errors.map((message) => ({ path: 'schema', message })),
149
+ };
150
+ }