@mmapp/react 0.1.0-alpha.1 → 0.1.0-alpha.4
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/README.md +112 -0
- package/dist/index.d.mts +1378 -94
- package/dist/index.d.ts +1378 -94
- package/dist/index.js +1094 -1309
- package/dist/index.mjs +1038 -1296
- package/package.json +4 -3
- package/package.json.backup +0 -41
- package/src/Blueprint.ts +0 -216
- package/src/__tests__/Blueprint.test.ts +0 -106
- package/src/__tests__/action-context.test.ts +0 -166
- package/src/__tests__/actionCreators.test.ts +0 -179
- package/src/__tests__/builders.test.ts +0 -336
- package/src/__tests__/defineBlueprint-composition.test.ts +0 -106
- package/src/__tests__/factories.test.ts +0 -229
- package/src/__tests__/loader.test.ts +0 -159
- package/src/__tests__/logger.test.ts +0 -70
- package/src/__tests__/type-inference.test.ts +0 -160
- package/src/__tests__/typed-transitions.test.ts +0 -126
- package/src/__tests__/useModuleConfig.test.ts +0 -61
- package/src/actionCreators.ts +0 -132
- package/src/actions.ts +0 -547
- package/src/atoms/index.ts +0 -600
- package/src/authoring.ts +0 -92
- package/src/browser-player.ts +0 -783
- package/src/builders.ts +0 -1342
- package/src/components/ExperienceWorkflowBridge.tsx +0 -123
- package/src/components/PlayerProvider.tsx +0 -43
- package/src/components/atoms/index.tsx +0 -269
- package/src/components/index.ts +0 -36
- package/src/conditions.ts +0 -692
- package/src/config/defineBlueprint.ts +0 -329
- package/src/config/defineModel.ts +0 -753
- package/src/config/defineWorkspace.ts +0 -24
- package/src/core/WorkflowRuntime.ts +0 -153
- package/src/factories.ts +0 -425
- package/src/grammar/index.ts +0 -173
- package/src/hooks/index.ts +0 -106
- package/src/hooks/useAuth.ts +0 -288
- package/src/hooks/useChannel.ts +0 -304
- package/src/hooks/useComputed.ts +0 -154
- package/src/hooks/useDomainSubscription.ts +0 -110
- package/src/hooks/useDuringAction.ts +0 -99
- package/src/hooks/useExperienceState.ts +0 -59
- package/src/hooks/useExpressionLibrary.ts +0 -129
- package/src/hooks/useForm.ts +0 -352
- package/src/hooks/useGeolocation.ts +0 -207
- package/src/hooks/useMapView.ts +0 -259
- package/src/hooks/useMiddleware.ts +0 -291
- package/src/hooks/useModel.ts +0 -363
- package/src/hooks/useModule.ts +0 -59
- package/src/hooks/useModuleConfig.ts +0 -61
- package/src/hooks/useMutation.ts +0 -237
- package/src/hooks/useNotification.ts +0 -151
- package/src/hooks/useOnChange.ts +0 -30
- package/src/hooks/useOnEnter.ts +0 -59
- package/src/hooks/useOnEvent.ts +0 -37
- package/src/hooks/useOnExit.ts +0 -27
- package/src/hooks/useOnTransition.ts +0 -30
- package/src/hooks/usePackage.ts +0 -128
- package/src/hooks/useParams.ts +0 -33
- package/src/hooks/usePlayer.ts +0 -308
- package/src/hooks/useQuery.ts +0 -184
- package/src/hooks/useRealtimeQuery.ts +0 -222
- package/src/hooks/useRole.ts +0 -191
- package/src/hooks/useRouteParams.ts +0 -100
- package/src/hooks/useRouter.ts +0 -347
- package/src/hooks/useServerAction.ts +0 -178
- package/src/hooks/useServerState.ts +0 -284
- package/src/hooks/useToast.ts +0 -164
- package/src/hooks/useTransition.ts +0 -39
- package/src/hooks/useView.ts +0 -102
- package/src/hooks/useWhileIn.ts +0 -48
- package/src/hooks/useWorkflow.ts +0 -63
- package/src/index.ts +0 -465
- package/src/loader/experience-workflow-loader.ts +0 -192
- package/src/loader/index.ts +0 -6
- package/src/local/LocalEngine.ts +0 -388
- package/src/local/LocalEngineAdapter.ts +0 -175
- package/src/local/LocalEngineContext.ts +0 -30
- package/src/logger.ts +0 -37
- package/src/mixins.ts +0 -1160
- package/src/providers/RuntimeContext.ts +0 -20
- package/src/providers/WorkflowProvider.tsx +0 -28
- package/src/routing/instance-key.ts +0 -107
- package/src/server/transition-context.ts +0 -172
- package/src/testing/index.ts +0 -9
- package/src/testing/useBlueprintTestRunner.ts +0 -91
- package/src/testing/useGraphAnalysis.ts +0 -18
- package/src/testing/useTestRunner.ts +0 -77
- package/src/testing.ts +0 -995
- package/src/types/workflow-inference.ts +0 -158
- package/src/types.ts +0 -114
- package/tsconfig.json +0 -27
- package/vitest.config.ts +0 -8
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { model, field, state, transition, TypedTransitionBuilder } from '../builders';
|
|
3
|
-
import { setField, logEvent } from '../actions';
|
|
4
|
-
|
|
5
|
-
describe('TypedTransitionBuilder — type-safe state references', () => {
|
|
6
|
-
it('accepts a callback that builds a typed transition', () => {
|
|
7
|
-
const result = model('invoice')
|
|
8
|
-
.state('draft', state.initial())
|
|
9
|
-
.state('sent')
|
|
10
|
-
.state('paid', state.end())
|
|
11
|
-
.transition('send', t => t.from('draft').to('sent'))
|
|
12
|
-
.build();
|
|
13
|
-
|
|
14
|
-
expect(result.transitions.send.from).toBe('draft');
|
|
15
|
-
expect(result.transitions.send.to).toBe('sent');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('supports require, roles, and when in callback form', () => {
|
|
19
|
-
const result = model('invoice')
|
|
20
|
-
.state('draft', state.initial())
|
|
21
|
-
.state('review')
|
|
22
|
-
.state('approved', state.end())
|
|
23
|
-
.transition('submit', t =>
|
|
24
|
-
t.from('draft').to('review').require('amount', 'title')
|
|
25
|
-
)
|
|
26
|
-
.transition('approve', t =>
|
|
27
|
-
t.from('review').to('approved').roles('manager').when('state_data.amount < 10000')
|
|
28
|
-
)
|
|
29
|
-
.build();
|
|
30
|
-
|
|
31
|
-
expect(result.transitions.submit.requiredFields).toEqual(['amount', 'title']);
|
|
32
|
-
expect(result.transitions.approve.roles).toEqual(['manager']);
|
|
33
|
-
expect(result.transitions.approve.conditions).toHaveLength(1);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('supports auto transitions in callback form', () => {
|
|
37
|
-
const result = model('pipeline')
|
|
38
|
-
.state('processing', state.initial())
|
|
39
|
-
.state('done', state.end())
|
|
40
|
-
.transition('complete', t =>
|
|
41
|
-
t.from('processing').to('done').auto()
|
|
42
|
-
)
|
|
43
|
-
.build();
|
|
44
|
-
|
|
45
|
-
expect(result.transitions.complete.auto).toBe(true);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('supports multiple from states in callback form', () => {
|
|
49
|
-
const result = model('order')
|
|
50
|
-
.state('placed', state.initial())
|
|
51
|
-
.state('confirmed')
|
|
52
|
-
.state('cancelled', state.end())
|
|
53
|
-
.transition('cancel', t => t.from('placed', 'confirmed').to('cancelled'))
|
|
54
|
-
.build();
|
|
55
|
-
|
|
56
|
-
expect(result.transitions.cancel.from).toEqual(['placed', 'confirmed']);
|
|
57
|
-
expect(result.transitions.cancel.to).toBe('cancelled');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('coexists with untyped transition() calls', () => {
|
|
61
|
-
const result = model('test')
|
|
62
|
-
.state('a', state.initial())
|
|
63
|
-
.state('b')
|
|
64
|
-
.state('c', state.end())
|
|
65
|
-
// typed callback
|
|
66
|
-
.transition('ab', t => t.from('a').to('b'))
|
|
67
|
-
// untyped existing API
|
|
68
|
-
.transition('bc', transition.from('b').to('c'))
|
|
69
|
-
.build();
|
|
70
|
-
|
|
71
|
-
expect(result.transitions.ab).toEqual({ from: 'a', to: 'b' });
|
|
72
|
-
expect(result.transitions.bc).toEqual({ from: 'b', to: 'c' });
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('coexists with plain object descriptors', () => {
|
|
76
|
-
const result = model('test')
|
|
77
|
-
.state('x', state.initial())
|
|
78
|
-
.state('y', state.end())
|
|
79
|
-
.transition('go', { from: 'x', to: 'y' })
|
|
80
|
-
.build();
|
|
81
|
-
|
|
82
|
-
expect(result.transitions.go.from).toBe('x');
|
|
83
|
-
expect(result.transitions.go.to).toBe('y');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('supports description in callback form', () => {
|
|
87
|
-
const result = model('test')
|
|
88
|
-
.state('a', state.initial())
|
|
89
|
-
.state('b', state.end())
|
|
90
|
-
.transition('go', t => t.from('a').to('b').description('Move from a to b'))
|
|
91
|
-
.build();
|
|
92
|
-
|
|
93
|
-
expect(result.transitions.go.description).toBe('Move from a to b');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('supports do() with actions in callback form', () => {
|
|
97
|
-
const result = model('test')
|
|
98
|
-
.state('a', state.initial())
|
|
99
|
-
.state('b', state.end())
|
|
100
|
-
.transition('go', t =>
|
|
101
|
-
t.from('a').to('b').do(setField('status', '"done"'), logEvent('completed'))
|
|
102
|
-
)
|
|
103
|
-
.build();
|
|
104
|
-
|
|
105
|
-
expect(result.transitions.go.actions).toHaveLength(2);
|
|
106
|
-
expect(result.transitions.go.actions![0].type).toBe('set_field');
|
|
107
|
-
expect(result.transitions.go.actions![1].type).toBe('log_event');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('TypedTransitionBuilder class standalone', () => {
|
|
112
|
-
it('builds a valid TransitionDescriptor', () => {
|
|
113
|
-
const builder = new TypedTransitionBuilder<'a' | 'b'>();
|
|
114
|
-
builder.from('a').to('b').require('name');
|
|
115
|
-
const desc = builder.build();
|
|
116
|
-
|
|
117
|
-
expect(desc.from).toBe('a');
|
|
118
|
-
expect(desc.to).toBe('b');
|
|
119
|
-
expect(desc.requiredFields).toEqual(['name']);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('throws when from/to are missing', () => {
|
|
123
|
-
const builder = new TypedTransitionBuilder<'a'>();
|
|
124
|
-
expect(() => builder.build()).toThrow('from() is required');
|
|
125
|
-
});
|
|
126
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for useModuleConfig — config merging and module lookup.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
6
|
-
import {
|
|
7
|
-
setInstalledModules,
|
|
8
|
-
setModuleConfigDefaults,
|
|
9
|
-
getInstalledModule,
|
|
10
|
-
getInstalledModules,
|
|
11
|
-
type InstalledModuleRef,
|
|
12
|
-
} from '../hooks/useModuleConfig';
|
|
13
|
-
|
|
14
|
-
describe('useModuleConfig store', () => {
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
setInstalledModules([]);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('stores and retrieves installed modules', () => {
|
|
20
|
-
const modules: InstalledModuleRef[] = [
|
|
21
|
-
{ slug: 'mod-auth', moduleId: 'auth-001', config: { layout: 'card' } },
|
|
22
|
-
{ slug: 'mod-notif', moduleId: 'notif-001' },
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
setInstalledModules(modules);
|
|
26
|
-
|
|
27
|
-
expect(getInstalledModules()).toHaveLength(2);
|
|
28
|
-
expect(getInstalledModule('mod-auth')?.config?.layout).toBe('card');
|
|
29
|
-
expect(getInstalledModule('mod-notif')).toBeDefined();
|
|
30
|
-
expect(getInstalledModule('mod-unknown')).toBeUndefined();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('stores routeConfig and slotMapping on installed module', () => {
|
|
34
|
-
setInstalledModules([{
|
|
35
|
-
slug: 'mod-auth',
|
|
36
|
-
moduleId: 'auth-001',
|
|
37
|
-
routeConfig: { prefix: '/auth', routes: { '/login': '/' } },
|
|
38
|
-
slotMapping: { 'auth:profile': 'app:settings' },
|
|
39
|
-
}]);
|
|
40
|
-
|
|
41
|
-
const mod = getInstalledModule('mod-auth');
|
|
42
|
-
expect(mod?.routeConfig?.prefix).toBe('/auth');
|
|
43
|
-
expect(mod?.routeConfig?.routes?.['/login']).toBe('/');
|
|
44
|
-
expect(mod?.slotMapping?.['auth:profile']).toBe('app:settings');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('setModuleConfigDefaults works', () => {
|
|
48
|
-
setModuleConfigDefaults('mod-auth', { layout: 'split', methods: ['email'] });
|
|
49
|
-
|
|
50
|
-
// Config defaults are stored and can be merged with install-time config
|
|
51
|
-
// (useModuleConfig hook merges them, but we test the store directly here)
|
|
52
|
-
setInstalledModules([{
|
|
53
|
-
slug: 'mod-auth',
|
|
54
|
-
moduleId: 'auth-001',
|
|
55
|
-
config: { layout: 'card' },
|
|
56
|
-
}]);
|
|
57
|
-
|
|
58
|
-
const mod = getInstalledModule('mod-auth');
|
|
59
|
-
expect(mod?.config?.layout).toBe('card'); // install-time wins
|
|
60
|
-
});
|
|
61
|
-
});
|
package/src/actionCreators.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @mindmatrix/react/actionCreators — Type-safe action reference factories.
|
|
3
|
-
*
|
|
4
|
-
* Replaces stringly-typed `serverAction("authenticate", {...})` calls with
|
|
5
|
-
* typed action creators that catch typos at compile time.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import { createActions } from '@mindmatrix/react';
|
|
10
|
-
*
|
|
11
|
-
* const actions = createActions({
|
|
12
|
-
* authenticate: { handler: 'actions/auth.server.ts' },
|
|
13
|
-
* destroySession: { handler: 'actions/auth.server.ts' },
|
|
14
|
-
* resetPassword: { handler: 'actions/auth.server.ts' },
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
* // Usage in models — fully typed, autocomplete on action names:
|
|
18
|
-
* .do(actions.authenticate({ method: 'login' }))
|
|
19
|
-
* .do(actions.destroySession())
|
|
20
|
-
*
|
|
21
|
-
* // Typo = TypeScript compile error:
|
|
22
|
-
* .do(actions.autenticate({}))
|
|
23
|
-
* // ~~~~~~~~~~~~ Property 'autenticate' does not exist
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @module
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import type { ActionDefinition } from './config/defineModel';
|
|
30
|
-
|
|
31
|
-
// =============================================================================
|
|
32
|
-
// Action Manifest & Creators
|
|
33
|
-
// =============================================================================
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Configuration for a single action in the manifest.
|
|
37
|
-
*/
|
|
38
|
-
export interface ActionManifestEntry {
|
|
39
|
-
/** The handler file path (e.g., 'actions/auth.server.ts'). */
|
|
40
|
-
handler: string;
|
|
41
|
-
/** Optional function name within the handler file. */
|
|
42
|
-
functionName?: string;
|
|
43
|
-
/** Optional description for documentation. */
|
|
44
|
-
description?: string;
|
|
45
|
-
/** Action execution mode. Default: 'auto'. */
|
|
46
|
-
mode?: 'auto' | 'manual';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* A manifest mapping action names to their configuration.
|
|
51
|
-
*/
|
|
52
|
-
export type ActionManifest = Record<string, ActionManifestEntry>;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* A typed action creator function returned for each manifest entry.
|
|
56
|
-
* Accepts optional config and returns an ActionDefinition.
|
|
57
|
-
*/
|
|
58
|
-
export type ActionCreator = (config?: Record<string, unknown>) => ActionDefinition;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Maps an ActionManifest to an object of typed action creators.
|
|
62
|
-
* Each key from the manifest becomes a callable action creator.
|
|
63
|
-
*/
|
|
64
|
-
export type ActionCreators<M extends ActionManifest> = {
|
|
65
|
-
readonly [K in keyof M]: ActionCreator;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Convert a camelCase or PascalCase string to kebab-case.
|
|
70
|
-
* @internal
|
|
71
|
-
*/
|
|
72
|
-
function toKebab(str: string): string {
|
|
73
|
-
return str
|
|
74
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
75
|
-
.replace(/[_.:\s]+/g, '-')
|
|
76
|
-
.toLowerCase();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Create typed action creators from an actions manifest.
|
|
81
|
-
*
|
|
82
|
-
* Each key in the manifest becomes a function that returns an {@link ActionDefinition}
|
|
83
|
-
* compatible with `.do()`, `onEnter`, `onExit`, and other action slots.
|
|
84
|
-
*
|
|
85
|
-
* The action type is `server:{kebab-case-name}` and the handler path is stored
|
|
86
|
-
* in the config for the build pipeline to resolve.
|
|
87
|
-
*
|
|
88
|
-
* @param manifest - Object mapping action names to their configuration.
|
|
89
|
-
* @returns An object with the same keys, where each value is a typed action creator.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```typescript
|
|
93
|
-
* const actions = createActions({
|
|
94
|
-
* authenticate: { handler: 'actions/auth.server.ts' },
|
|
95
|
-
* destroySession: { handler: 'actions/auth.server.ts' },
|
|
96
|
-
* sendWelcomeEmail: { handler: 'actions/email.server.ts', mode: 'manual' },
|
|
97
|
-
* });
|
|
98
|
-
*
|
|
99
|
-
* // Returns ActionDefinition:
|
|
100
|
-
* actions.authenticate({ method: 'login' })
|
|
101
|
-
* // => { id: 'server-authenticate', type: 'server:authenticate',
|
|
102
|
-
* // mode: 'auto', config: { method: 'login', __handler: 'actions/auth.server.ts' } }
|
|
103
|
-
*
|
|
104
|
-
* actions.destroySession()
|
|
105
|
-
* // => { id: 'server-destroy-session', type: 'server:destroySession',
|
|
106
|
-
* // mode: 'auto', config: { __handler: 'actions/auth.server.ts' } }
|
|
107
|
-
* ```
|
|
108
|
-
*/
|
|
109
|
-
export function createActions<const M extends ActionManifest>(manifest: M): ActionCreators<M> {
|
|
110
|
-
const creators = {} as Record<string, ActionCreator>;
|
|
111
|
-
|
|
112
|
-
for (const [name, entry] of Object.entries(manifest)) {
|
|
113
|
-
creators[name] = (config?: Record<string, unknown>): ActionDefinition => {
|
|
114
|
-
const actionConfig: Record<string, unknown> = {
|
|
115
|
-
...config,
|
|
116
|
-
__handler: entry.handler,
|
|
117
|
-
};
|
|
118
|
-
if (entry.functionName) {
|
|
119
|
-
actionConfig.__functionName = entry.functionName;
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
id: `server-${toKebab(name)}`,
|
|
123
|
-
type: `server:${name}`,
|
|
124
|
-
mode: entry.mode ?? 'auto',
|
|
125
|
-
config: actionConfig,
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return creators as ActionCreators<M>;
|
|
131
|
-
}
|
|
132
|
-
|