@mmapp/player-core 0.1.0-alpha.1

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.
Files changed (63) hide show
  1. package/dist/index.d.mts +1436 -0
  2. package/dist/index.d.ts +1436 -0
  3. package/dist/index.js +4828 -0
  4. package/dist/index.mjs +4762 -0
  5. package/package.json +35 -0
  6. package/package.json.backup +35 -0
  7. package/src/__tests__/actions.test.ts +187 -0
  8. package/src/__tests__/blueprint-e2e.test.ts +706 -0
  9. package/src/__tests__/blueprint-test-runner.test.ts +680 -0
  10. package/src/__tests__/core-functions.test.ts +78 -0
  11. package/src/__tests__/dsl-compiler.test.ts +1382 -0
  12. package/src/__tests__/dsl-grammar.test.ts +1682 -0
  13. package/src/__tests__/events.test.ts +200 -0
  14. package/src/__tests__/expression.test.ts +296 -0
  15. package/src/__tests__/failure-policies.test.ts +110 -0
  16. package/src/__tests__/frontend-context.test.ts +182 -0
  17. package/src/__tests__/integration.test.ts +256 -0
  18. package/src/__tests__/security.test.ts +190 -0
  19. package/src/__tests__/state-machine.test.ts +450 -0
  20. package/src/__tests__/testing-engine.test.ts +671 -0
  21. package/src/actions/dispatcher.ts +80 -0
  22. package/src/actions/index.ts +7 -0
  23. package/src/actions/types.ts +25 -0
  24. package/src/dsl/compiler/component-mapper.ts +289 -0
  25. package/src/dsl/compiler/field-mapper.ts +187 -0
  26. package/src/dsl/compiler/index.ts +82 -0
  27. package/src/dsl/compiler/manifest-compiler.ts +76 -0
  28. package/src/dsl/compiler/symbol-table.ts +214 -0
  29. package/src/dsl/compiler/utils.ts +48 -0
  30. package/src/dsl/compiler/view-compiler.ts +286 -0
  31. package/src/dsl/compiler/workflow-compiler.ts +600 -0
  32. package/src/dsl/index.ts +66 -0
  33. package/src/dsl/ir-migration.ts +221 -0
  34. package/src/dsl/ir-types.ts +416 -0
  35. package/src/dsl/lexer.ts +579 -0
  36. package/src/dsl/parser.ts +115 -0
  37. package/src/dsl/types.ts +256 -0
  38. package/src/events/event-bus.ts +68 -0
  39. package/src/events/index.ts +9 -0
  40. package/src/events/pattern-matcher.ts +61 -0
  41. package/src/events/types.ts +27 -0
  42. package/src/expression/evaluator.ts +676 -0
  43. package/src/expression/functions.ts +214 -0
  44. package/src/expression/index.ts +13 -0
  45. package/src/expression/types.ts +64 -0
  46. package/src/index.ts +61 -0
  47. package/src/state-machine/index.ts +16 -0
  48. package/src/state-machine/interpreter.ts +319 -0
  49. package/src/state-machine/types.ts +89 -0
  50. package/src/testing/action-trace.ts +209 -0
  51. package/src/testing/blueprint-test-runner.ts +214 -0
  52. package/src/testing/graph-walker.ts +249 -0
  53. package/src/testing/index.ts +69 -0
  54. package/src/testing/nrt-comparator.ts +199 -0
  55. package/src/testing/nrt-types.ts +230 -0
  56. package/src/testing/test-actions.ts +645 -0
  57. package/src/testing/test-compiler.ts +278 -0
  58. package/src/testing/test-runner.ts +444 -0
  59. package/src/testing/types.ts +231 -0
  60. package/src/validation/definition-validator.ts +812 -0
  61. package/src/validation/index.ts +13 -0
  62. package/tsconfig.json +26 -0
  63. package/vitest.config.ts +8 -0
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@mmapp/player-core",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Framework-agnostic workflow engine for browser-side state machines, expression evaluation, and event-driven reactions",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup src/index.ts --format cjs,esm --dts",
17
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest --watch",
20
+ "test:coverage": "vitest --coverage",
21
+ "type-check": "tsc --noEmit"
22
+ },
23
+ "keywords": [
24
+ "workflow",
25
+ "state-machine",
26
+ "expression-engine",
27
+ "player",
28
+ "reactive"
29
+ ],
30
+ "author": "MindMatrix Team",
31
+ "license": "MIT",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@mmapp/player-core",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Framework-agnostic workflow engine for browser-side state machines, expression evaluation, and event-driven reactions",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup src/index.ts --format cjs,esm --dts",
17
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest --watch",
20
+ "test:coverage": "vitest --coverage",
21
+ "type-check": "tsc --noEmit"
22
+ },
23
+ "keywords": [
24
+ "workflow",
25
+ "state-machine",
26
+ "expression-engine",
27
+ "player",
28
+ "reactive"
29
+ ],
30
+ "author": "MindMatrix Team",
31
+ "license": "MIT",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }
@@ -0,0 +1,187 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { ActionDispatcher } from '../actions/dispatcher';
3
+ import { createEvaluator, WEB_FAILURE_POLICIES, clearExpressionCache } from '../expression';
4
+ import type { Evaluator, ExpressionContext } from '../expression/types';
5
+ import type { ActionDefinition } from '../actions/types';
6
+
7
+ describe('ActionDispatcher', () => {
8
+ let dispatcher: ActionDispatcher;
9
+ let evaluator: Evaluator;
10
+ let ctx: ExpressionContext;
11
+
12
+ beforeEach(() => {
13
+ clearExpressionCache();
14
+ dispatcher = new ActionDispatcher();
15
+ evaluator = createEvaluator({
16
+ functions: [],
17
+ failurePolicy: WEB_FAILURE_POLICIES.DURING_ACTION,
18
+ });
19
+ ctx = {
20
+ state_data: { count: 5 },
21
+ memory: {},
22
+ current_state: 'active',
23
+ status: 'ACTIVE',
24
+ count: 5,
25
+ };
26
+ });
27
+
28
+ describe('register/unregister', () => {
29
+ it('registers a handler', () => {
30
+ dispatcher.register('log', () => {});
31
+ expect(dispatcher.has('log')).toBe(true);
32
+ expect(dispatcher.size).toBe(1);
33
+ });
34
+
35
+ it('unregisters a handler', () => {
36
+ dispatcher.register('log', () => {});
37
+ dispatcher.unregister('log');
38
+ expect(dispatcher.has('log')).toBe(false);
39
+ });
40
+
41
+ it('clears all handlers', () => {
42
+ dispatcher.register('a', () => {});
43
+ dispatcher.register('b', () => {});
44
+ dispatcher.clear();
45
+ expect(dispatcher.size).toBe(0);
46
+ });
47
+ });
48
+
49
+ describe('execute', () => {
50
+ it('executes actions with registered handlers', async () => {
51
+ const handler = vi.fn();
52
+ dispatcher.register('notify', handler);
53
+
54
+ const actions: ActionDefinition[] = [
55
+ { type: 'notify', config: { message: 'hello' } },
56
+ ];
57
+
58
+ const results = await dispatcher.execute(actions, ctx);
59
+ expect(results).toHaveLength(1);
60
+ expect(results[0].success).toBe(true);
61
+ expect(results[0].type).toBe('notify');
62
+ expect(handler).toHaveBeenCalledWith({ message: 'hello' }, ctx);
63
+ });
64
+
65
+ it('returns error result for missing handlers', async () => {
66
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
67
+ const actions: ActionDefinition[] = [
68
+ { type: 'unknown', config: {} },
69
+ ];
70
+
71
+ const results = await dispatcher.execute(actions, ctx);
72
+ expect(results).toHaveLength(1);
73
+ expect(results[0].success).toBe(false);
74
+ expect(results[0].error).toContain('No handler');
75
+ warn.mockRestore();
76
+ });
77
+
78
+ it('captures handler errors without throwing', async () => {
79
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
80
+ dispatcher.register('bad', () => { throw new Error('boom'); });
81
+
82
+ const actions: ActionDefinition[] = [
83
+ { type: 'bad', config: {} },
84
+ ];
85
+
86
+ const results = await dispatcher.execute(actions, ctx);
87
+ expect(results).toHaveLength(1);
88
+ expect(results[0].success).toBe(false);
89
+ expect(results[0].error).toBe('boom');
90
+ warn.mockRestore();
91
+ });
92
+
93
+ it('executes actions sequentially', async () => {
94
+ const order: number[] = [];
95
+ dispatcher.register('step', async (config) => {
96
+ order.push(config.n as number);
97
+ });
98
+
99
+ const actions: ActionDefinition[] = [
100
+ { type: 'step', config: { n: 1 } },
101
+ { type: 'step', config: { n: 2 } },
102
+ { type: 'step', config: { n: 3 } },
103
+ ];
104
+
105
+ await dispatcher.execute(actions, ctx);
106
+ expect(order).toEqual([1, 2, 3]);
107
+ });
108
+
109
+ it('skips actions whose condition evaluates to false', async () => {
110
+ const handler = vi.fn();
111
+ dispatcher.register('conditional', handler);
112
+
113
+ const actions: ActionDefinition[] = [
114
+ { type: 'conditional', config: {}, condition: 'gt(count, 100)' },
115
+ ];
116
+
117
+ const results = await dispatcher.execute(actions, ctx, evaluator);
118
+ expect(results).toHaveLength(0); // skipped, not in results
119
+ expect(handler).not.toHaveBeenCalled();
120
+ });
121
+
122
+ it('executes actions whose condition evaluates to true', async () => {
123
+ const handler = vi.fn();
124
+ dispatcher.register('conditional', handler);
125
+
126
+ const actions: ActionDefinition[] = [
127
+ { type: 'conditional', config: { x: 1 }, condition: 'gt(count, 3)' },
128
+ ];
129
+
130
+ const results = await dispatcher.execute(actions, ctx, evaluator);
131
+ expect(results).toHaveLength(1);
132
+ expect(results[0].success).toBe(true);
133
+ });
134
+
135
+ it('skips condition check when no evaluator provided', async () => {
136
+ const handler = vi.fn();
137
+ dispatcher.register('nocond', handler);
138
+
139
+ const actions: ActionDefinition[] = [
140
+ { type: 'nocond', config: {}, condition: 'gt(count, 100)' },
141
+ ];
142
+
143
+ // Without evaluator, condition is not checked → action executes
144
+ const results = await dispatcher.execute(actions, ctx);
145
+ expect(results).toHaveLength(1);
146
+ expect(handler).toHaveBeenCalledOnce();
147
+ });
148
+
149
+ it('handles empty action list', async () => {
150
+ const results = await dispatcher.execute([], ctx);
151
+ expect(results).toHaveLength(0);
152
+ });
153
+
154
+ it('continues execution after one action fails', async () => {
155
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
156
+ const good = vi.fn();
157
+ dispatcher.register('bad', () => { throw new Error('fail'); });
158
+ dispatcher.register('good', good);
159
+
160
+ const actions: ActionDefinition[] = [
161
+ { type: 'bad', config: {} },
162
+ { type: 'good', config: {} },
163
+ ];
164
+
165
+ const results = await dispatcher.execute(actions, ctx);
166
+ expect(results).toHaveLength(2);
167
+ expect(results[0].success).toBe(false);
168
+ expect(results[1].success).toBe(true);
169
+ expect(good).toHaveBeenCalledOnce();
170
+ warn.mockRestore();
171
+ });
172
+
173
+ it('handles async handlers', async () => {
174
+ dispatcher.register('async_action', async (config) => {
175
+ await new Promise(resolve => setTimeout(resolve, 10));
176
+ });
177
+
178
+ const actions: ActionDefinition[] = [
179
+ { type: 'async_action', config: {} },
180
+ ];
181
+
182
+ const results = await dispatcher.execute(actions, ctx);
183
+ expect(results).toHaveLength(1);
184
+ expect(results[0].success).toBe(true);
185
+ });
186
+ });
187
+ });