@mmapp/react 0.1.0-alpha.1 → 0.1.0-alpha.3
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 +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +70 -3
- package/dist/index.mjs +74 -12
- 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,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RuntimeContext — React Context for WorkflowRuntime
|
|
3
|
-
*
|
|
4
|
-
* Provides the runtime instance to all effect hooks via useRuntimeContext.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { createContext, useContext } from 'react';
|
|
8
|
-
import type { WorkflowRuntime } from '../core/WorkflowRuntime';
|
|
9
|
-
|
|
10
|
-
export const RuntimeContext = createContext<WorkflowRuntime | null>(null);
|
|
11
|
-
|
|
12
|
-
export function useRuntimeContext(): WorkflowRuntime {
|
|
13
|
-
const runtime = useContext(RuntimeContext);
|
|
14
|
-
if (!runtime) {
|
|
15
|
-
throw new Error(
|
|
16
|
-
'useRuntimeContext must be used within a WorkflowProvider or RuntimeContext.Provider'
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
return runtime;
|
|
20
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WorkflowProvider — Provider for WorkflowRuntime with QueryClient
|
|
3
|
-
*
|
|
4
|
-
* Wraps children with RuntimeContext and QueryClientProvider.
|
|
5
|
-
* Provides the runtime instance to all effect hooks and useRuntimeContext.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
9
|
-
import { RuntimeContext } from './RuntimeContext';
|
|
10
|
-
import type { WorkflowRuntime } from '../core/WorkflowRuntime';
|
|
11
|
-
|
|
12
|
-
const defaultQueryClient = new QueryClient();
|
|
13
|
-
|
|
14
|
-
export interface WorkflowProviderProps {
|
|
15
|
-
runtime: WorkflowRuntime;
|
|
16
|
-
queryClient?: QueryClient;
|
|
17
|
-
children: React.ReactNode;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function WorkflowProvider({ runtime, queryClient, children }: WorkflowProviderProps) {
|
|
21
|
-
return (
|
|
22
|
-
<QueryClientProvider client={queryClient ?? defaultQueryClient}>
|
|
23
|
-
<RuntimeContext.Provider value={runtime}>
|
|
24
|
-
{children}
|
|
25
|
-
</RuntimeContext.Provider>
|
|
26
|
-
</QueryClientProvider>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Instance Key Derivation — deterministic key generation for workflow instances.
|
|
3
|
-
*
|
|
4
|
-
* When a blueprint mounts at a route, it needs a stable instance key that
|
|
5
|
-
* uniquely identifies the workflow instance for that route + parameters.
|
|
6
|
-
*
|
|
7
|
-
* The key is derived from:
|
|
8
|
-
* sha256(blueprintSlug + ":" + layoutPath + ":" + sortedParams)
|
|
9
|
-
*
|
|
10
|
-
* This ensures:
|
|
11
|
-
* - Same route + same params → same instance (idempotent)
|
|
12
|
-
* - Different params → different instances (e.g., /chat/123 vs /chat/456)
|
|
13
|
-
* - Deterministic across page refreshes
|
|
14
|
-
* - No collision between blueprints
|
|
15
|
-
*
|
|
16
|
-
* Usage:
|
|
17
|
-
* import { deriveInstanceKey, deriveInstanceKeySync } from '@mindmatrix/react';
|
|
18
|
-
*
|
|
19
|
-
* const key = deriveInstanceKeySync('mm-chat', '/chat/[channelId]', { channelId: '123' });
|
|
20
|
-
* // → 'mm-chat:a1b2c3d4'
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
// =============================================================================
|
|
24
|
-
// Types
|
|
25
|
-
// =============================================================================
|
|
26
|
-
|
|
27
|
-
export interface InstanceKeyParams {
|
|
28
|
-
[key: string]: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// =============================================================================
|
|
32
|
-
// Key derivation
|
|
33
|
-
// =============================================================================
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Derives a deterministic instance key from blueprint slug, layout path, and route params.
|
|
37
|
-
* Uses Web Crypto API (async).
|
|
38
|
-
*/
|
|
39
|
-
export async function deriveInstanceKey(
|
|
40
|
-
blueprintSlug: string,
|
|
41
|
-
layoutPath: string,
|
|
42
|
-
params: InstanceKeyParams = {}
|
|
43
|
-
): Promise<string> {
|
|
44
|
-
const input = buildKeyInput(blueprintSlug, layoutPath, params);
|
|
45
|
-
|
|
46
|
-
// Use Web Crypto API for SHA-256
|
|
47
|
-
const encoder = new TextEncoder();
|
|
48
|
-
const data = encoder.encode(input);
|
|
49
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
50
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
51
|
-
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
52
|
-
|
|
53
|
-
// Return slug prefix + first 16 hex chars (64-bit uniqueness)
|
|
54
|
-
return `${blueprintSlug}:${hashHex.substring(0, 16)}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Derives a deterministic instance key synchronously.
|
|
59
|
-
* Uses a simple hash function (djb2) instead of SHA-256.
|
|
60
|
-
* Suitable for non-cryptographic contexts where async is inconvenient.
|
|
61
|
-
*/
|
|
62
|
-
export function deriveInstanceKeySync(
|
|
63
|
-
blueprintSlug: string,
|
|
64
|
-
layoutPath: string,
|
|
65
|
-
params: InstanceKeyParams = {}
|
|
66
|
-
): string {
|
|
67
|
-
const input = buildKeyInput(blueprintSlug, layoutPath, params);
|
|
68
|
-
const hash = djb2Hash(input);
|
|
69
|
-
return `${blueprintSlug}:${hash}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Builds the canonical key input string.
|
|
74
|
-
* Params are sorted alphabetically for determinism.
|
|
75
|
-
*/
|
|
76
|
-
function buildKeyInput(
|
|
77
|
-
blueprintSlug: string,
|
|
78
|
-
layoutPath: string,
|
|
79
|
-
params: InstanceKeyParams
|
|
80
|
-
): string {
|
|
81
|
-
const sortedParams = Object.keys(params)
|
|
82
|
-
.sort()
|
|
83
|
-
.map((k) => `${k}=${params[k]}`)
|
|
84
|
-
.join('&');
|
|
85
|
-
|
|
86
|
-
return `${blueprintSlug}:${layoutPath}:${sortedParams}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* DJB2 hash function — fast, deterministic, non-cryptographic.
|
|
91
|
-
* Returns a 16-character hex string.
|
|
92
|
-
*/
|
|
93
|
-
function djb2Hash(str: string): string {
|
|
94
|
-
let hash1 = 5381;
|
|
95
|
-
let hash2 = 52711;
|
|
96
|
-
|
|
97
|
-
for (let i = 0; i < str.length; i++) {
|
|
98
|
-
const char = str.charCodeAt(i);
|
|
99
|
-
hash1 = ((hash1 << 5) + hash1 + char) | 0; // hash * 33 + char
|
|
100
|
-
hash2 = ((hash2 << 5) + hash2 + char) | 0;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Combine both hashes for 64 bits of entropy
|
|
104
|
-
const h1 = (hash1 >>> 0).toString(16).padStart(8, '0');
|
|
105
|
-
const h2 = (hash2 >>> 0).toString(16).padStart(8, '0');
|
|
106
|
-
return h1 + h2;
|
|
107
|
-
}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TransitionContext — server-side API contract for workflow actions.
|
|
3
|
-
*
|
|
4
|
-
* This is the full server-side API available to action handlers running
|
|
5
|
-
* on the backend. The React compiler generates references to these actions,
|
|
6
|
-
* and the backend runtime provides the concrete implementation.
|
|
7
|
-
*
|
|
8
|
-
* Usage in action files (actions.server.ts):
|
|
9
|
-
* import type { TransitionContext } from '@mindmatrix/react/server';
|
|
10
|
-
*
|
|
11
|
-
* export async function notifyMembers(ctx: TransitionContext) {
|
|
12
|
-
* const channel = ctx.stateData;
|
|
13
|
-
* const members = await ctx.refs('member', { channel_id: ctx.env.instance_id });
|
|
14
|
-
* for (const member of members) {
|
|
15
|
-
* await ctx.emit('notification:send', { user_id: member.stateData.user_id });
|
|
16
|
-
* }
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* Data Model (4 layers — matching backend):
|
|
20
|
-
* 1. stateData: user-facing form data (fields)
|
|
21
|
-
* 2. memory: internal persistent state (not visible to user)
|
|
22
|
-
* 3. actionResults: results from previous actions in this transition
|
|
23
|
-
* 4. context: read-only external context injected by runtime
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
// =============================================================================
|
|
27
|
-
// Types
|
|
28
|
-
// =============================================================================
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Result from a previous action execution within the same transition.
|
|
32
|
-
*/
|
|
33
|
-
export interface ActionResult {
|
|
34
|
-
actionId: string;
|
|
35
|
-
success: boolean;
|
|
36
|
-
data?: unknown;
|
|
37
|
-
error?: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Reference to another workflow instance.
|
|
42
|
-
*/
|
|
43
|
-
export interface InstanceRef {
|
|
44
|
-
id: string;
|
|
45
|
-
slug: string;
|
|
46
|
-
currentState: string;
|
|
47
|
-
stateData: Record<string, unknown>;
|
|
48
|
-
memory: Record<string, unknown>;
|
|
49
|
-
createdAt: string;
|
|
50
|
-
updatedAt: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Query parameters for cross-instance queries.
|
|
55
|
-
*/
|
|
56
|
-
export interface RefQuery {
|
|
57
|
-
[field: string]: unknown;
|
|
58
|
-
limit?: number;
|
|
59
|
-
offset?: number;
|
|
60
|
-
orderBy?: string;
|
|
61
|
-
order?: 'asc' | 'desc';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Query parameters for the query() function.
|
|
66
|
-
*/
|
|
67
|
-
export interface QueryParams {
|
|
68
|
-
slug?: string;
|
|
69
|
-
state?: string | string[];
|
|
70
|
-
filter?: Record<string, unknown>;
|
|
71
|
-
limit?: number;
|
|
72
|
-
offset?: number;
|
|
73
|
-
orderBy?: string;
|
|
74
|
-
order?: 'asc' | 'desc';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Options for spawning a sub-workflow instance.
|
|
79
|
-
*/
|
|
80
|
-
export interface SpawnOptions {
|
|
81
|
-
/** Whether to wait for the spawned workflow to reach an end state. */
|
|
82
|
-
blocking?: boolean;
|
|
83
|
-
/** Map parent fields to child input fields. */
|
|
84
|
-
input_mapping?: Record<string, string>;
|
|
85
|
-
/** Map child output fields back to parent fields. */
|
|
86
|
-
output_mapping?: Record<string, string>;
|
|
87
|
-
/** What to do if the spawned workflow fails. */
|
|
88
|
-
on_failure?: 'fail' | 'retry' | 'transition' | 'manual';
|
|
89
|
-
/** For retry: max number of retries. */
|
|
90
|
-
max_retries?: number;
|
|
91
|
-
/** For transition: which transition to fire on failure. */
|
|
92
|
-
failure_transition?: string;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Runtime environment information available during action execution.
|
|
97
|
-
*/
|
|
98
|
-
export interface ActionEnvironment {
|
|
99
|
-
tenant_id: string;
|
|
100
|
-
user_id: string;
|
|
101
|
-
instance_id: string;
|
|
102
|
-
definition_slug: string;
|
|
103
|
-
definition_version: string;
|
|
104
|
-
current_state: string;
|
|
105
|
-
transition_name: string;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The full server-side API available to workflow action handlers.
|
|
110
|
-
*
|
|
111
|
-
* This interface matches the backend's ActionExecutionContext.
|
|
112
|
-
*/
|
|
113
|
-
export interface TransitionContext {
|
|
114
|
-
// =========================================================================
|
|
115
|
-
// Data Layers (read)
|
|
116
|
-
// =========================================================================
|
|
117
|
-
|
|
118
|
-
/** User-facing form data (workflow fields). */
|
|
119
|
-
readonly stateData: Record<string, unknown>;
|
|
120
|
-
/** Internal persistent state (not visible to users). */
|
|
121
|
-
readonly memory: Record<string, unknown>;
|
|
122
|
-
/** Results from previous actions in this transition. */
|
|
123
|
-
readonly actionResults: Record<string, ActionResult>;
|
|
124
|
-
/** Read-only external context injected by the runtime. */
|
|
125
|
-
readonly context: Record<string, unknown>;
|
|
126
|
-
|
|
127
|
-
// =========================================================================
|
|
128
|
-
// Environment
|
|
129
|
-
// =========================================================================
|
|
130
|
-
|
|
131
|
-
/** Runtime environment information. */
|
|
132
|
-
readonly env: ActionEnvironment;
|
|
133
|
-
|
|
134
|
-
// =========================================================================
|
|
135
|
-
// Cross-Instance References
|
|
136
|
-
// =========================================================================
|
|
137
|
-
|
|
138
|
-
/** Get a single instance by slug and id. */
|
|
139
|
-
ref: (slug: string, id: string) => Promise<InstanceRef>;
|
|
140
|
-
/** Query instances by slug and filter. */
|
|
141
|
-
refs: (slug: string, query: RefQuery) => Promise<InstanceRef[]>;
|
|
142
|
-
|
|
143
|
-
// =========================================================================
|
|
144
|
-
// Mutations
|
|
145
|
-
// =========================================================================
|
|
146
|
-
|
|
147
|
-
/** Set a workflow field value. */
|
|
148
|
-
setField: (field: string, value: unknown) => void;
|
|
149
|
-
/** Set an internal memory value. */
|
|
150
|
-
setMemory: (key: string, value: unknown) => void;
|
|
151
|
-
/** Emit a domain event. */
|
|
152
|
-
emit: (event: string, payload?: Record<string, unknown>) => void;
|
|
153
|
-
/** Log a message with optional structured data. */
|
|
154
|
-
log: (message: string, data?: Record<string, unknown>) => void;
|
|
155
|
-
/** Fire a transition on the current instance. */
|
|
156
|
-
transition: (name: string) => void;
|
|
157
|
-
|
|
158
|
-
// =========================================================================
|
|
159
|
-
// Cross-Instance Operations
|
|
160
|
-
// =========================================================================
|
|
161
|
-
|
|
162
|
-
/** Query workflow instances. */
|
|
163
|
-
query: <T = Record<string, unknown>>(slug: string, params: QueryParams) => Promise<T[]>;
|
|
164
|
-
/** Spawn a sub-workflow instance. */
|
|
165
|
-
spawn: (slug: string, input?: Record<string, unknown>, options?: SpawnOptions) => Promise<string>;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Server action function signature.
|
|
170
|
-
* Exported functions in *.server.ts files must match this shape.
|
|
171
|
-
*/
|
|
172
|
-
export type ServerActionFn = (ctx: TransitionContext) => void | Promise<void>;
|
package/src/testing/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Testing hooks — React integration for the Testing OS.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { useGraphAnalysis } from './useGraphAnalysis';
|
|
6
|
-
export { useTestRunner } from './useTestRunner';
|
|
7
|
-
export type { TestRunnerHandle } from './useTestRunner';
|
|
8
|
-
export { useBlueprintTestRunner } from './useBlueprintTestRunner';
|
|
9
|
-
export type { BlueprintTestRunnerHandle } from './useBlueprintTestRunner';
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useBlueprintTestRunner — React hook for executing test Blueprints.
|
|
3
|
-
*
|
|
4
|
-
* The test IS a Blueprint running on a Player. This hook wraps the
|
|
5
|
-
* Blueprint test runner with React state management.
|
|
6
|
-
*
|
|
7
|
-
* Supports two execution modes:
|
|
8
|
-
* - in-process: StateMachines in memory (sub-millisecond)
|
|
9
|
-
* - api: HTTP calls to running NestJS backend (MM Server Player)
|
|
10
|
-
*
|
|
11
|
-
* For API mode, provide an ApiTestAdapter via the config.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { useCallback, useRef, useState } from 'react';
|
|
15
|
-
import { runBlueprintTestProgram } from '@mindmatrix/player-core';
|
|
16
|
-
import type {
|
|
17
|
-
TestProgram,
|
|
18
|
-
TestProgramResult,
|
|
19
|
-
StepResult,
|
|
20
|
-
BlueprintRunnerConfig,
|
|
21
|
-
} from '@mindmatrix/player-core';
|
|
22
|
-
|
|
23
|
-
export interface BlueprintTestRunnerHandle {
|
|
24
|
-
run: (program: TestProgram) => Promise<TestProgramResult>;
|
|
25
|
-
cancel: () => void;
|
|
26
|
-
result: TestProgramResult | null;
|
|
27
|
-
running: boolean;
|
|
28
|
-
liveSteps: StepResult[];
|
|
29
|
-
mode: 'in-process' | 'api';
|
|
30
|
-
reset: () => void;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function useBlueprintTestRunner(
|
|
34
|
-
config: Omit<BlueprintRunnerConfig, 'onStepComplete' | 'onScenarioComplete' | 'abortSignal'>,
|
|
35
|
-
): BlueprintTestRunnerHandle {
|
|
36
|
-
const [result, setResult] = useState<TestProgramResult | null>(null);
|
|
37
|
-
const [running, setRunning] = useState(false);
|
|
38
|
-
const [liveSteps, setLiveSteps] = useState<StepResult[]>([]);
|
|
39
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
40
|
-
|
|
41
|
-
const run = useCallback(
|
|
42
|
-
async (program: TestProgram): Promise<TestProgramResult> => {
|
|
43
|
-
abortControllerRef.current?.abort();
|
|
44
|
-
const controller = new AbortController();
|
|
45
|
-
abortControllerRef.current = controller;
|
|
46
|
-
|
|
47
|
-
setRunning(true);
|
|
48
|
-
setResult(null);
|
|
49
|
-
setLiveSteps([]);
|
|
50
|
-
|
|
51
|
-
const runnerConfig: BlueprintRunnerConfig = {
|
|
52
|
-
...config,
|
|
53
|
-
abortSignal: controller.signal,
|
|
54
|
-
onStepComplete: (_scenarioIdx, step) => {
|
|
55
|
-
setLiveSteps(prev => [...prev, step]);
|
|
56
|
-
},
|
|
57
|
-
} as BlueprintRunnerConfig;
|
|
58
|
-
|
|
59
|
-
const programResult = await runBlueprintTestProgram(program, runnerConfig);
|
|
60
|
-
setResult(programResult);
|
|
61
|
-
setRunning(false);
|
|
62
|
-
abortControllerRef.current = null;
|
|
63
|
-
return programResult;
|
|
64
|
-
},
|
|
65
|
-
[config],
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const cancel = useCallback(() => {
|
|
69
|
-
abortControllerRef.current?.abort();
|
|
70
|
-
abortControllerRef.current = null;
|
|
71
|
-
setRunning(false);
|
|
72
|
-
}, []);
|
|
73
|
-
|
|
74
|
-
const reset = useCallback(() => {
|
|
75
|
-
abortControllerRef.current?.abort();
|
|
76
|
-
abortControllerRef.current = null;
|
|
77
|
-
setResult(null);
|
|
78
|
-
setRunning(false);
|
|
79
|
-
setLiveSteps([]);
|
|
80
|
-
}, []);
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
run,
|
|
84
|
-
cancel,
|
|
85
|
-
result,
|
|
86
|
-
running,
|
|
87
|
-
liveSteps,
|
|
88
|
-
mode: config.mode,
|
|
89
|
-
reset,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useGraphAnalysis — React hook for static analysis of workflow definitions.
|
|
3
|
-
*
|
|
4
|
-
* Wraps analyzeDefinition in useMemo for synchronous, sub-ms analysis.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useMemo } from 'react';
|
|
8
|
-
import { analyzeDefinition } from '@mindmatrix/player-core';
|
|
9
|
-
import type { PlayerWorkflowDefinition, AnalysisResult } from '@mindmatrix/player-core';
|
|
10
|
-
|
|
11
|
-
export function useGraphAnalysis(
|
|
12
|
-
definition: PlayerWorkflowDefinition | null,
|
|
13
|
-
): AnalysisResult | null {
|
|
14
|
-
return useMemo(() => {
|
|
15
|
-
if (!definition) return null;
|
|
16
|
-
return analyzeDefinition(definition);
|
|
17
|
-
}, [definition]);
|
|
18
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useTestRunner — React hook for executing test programs.
|
|
3
|
-
*
|
|
4
|
-
* Returns a handle to run test programs, cancel execution,
|
|
5
|
-
* and observe live step-by-step results.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { useCallback, useRef, useState } from 'react';
|
|
9
|
-
import { runTestProgram } from '@mindmatrix/player-core';
|
|
10
|
-
import type {
|
|
11
|
-
TestProgram,
|
|
12
|
-
TestProgramResult,
|
|
13
|
-
StepResult,
|
|
14
|
-
TestRunnerConfig,
|
|
15
|
-
} from '@mindmatrix/player-core';
|
|
16
|
-
|
|
17
|
-
export interface TestRunnerHandle {
|
|
18
|
-
run: (program: TestProgram) => Promise<TestProgramResult>;
|
|
19
|
-
cancel: () => void;
|
|
20
|
-
result: TestProgramResult | null;
|
|
21
|
-
running: boolean;
|
|
22
|
-
liveSteps: StepResult[];
|
|
23
|
-
reset: () => void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function useTestRunner(config?: Partial<TestRunnerConfig>): TestRunnerHandle {
|
|
27
|
-
const [result, setResult] = useState<TestProgramResult | null>(null);
|
|
28
|
-
const [running, setRunning] = useState(false);
|
|
29
|
-
const [liveSteps, setLiveSteps] = useState<StepResult[]>([]);
|
|
30
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
31
|
-
|
|
32
|
-
const run = useCallback(
|
|
33
|
-
async (program: TestProgram): Promise<TestProgramResult> => {
|
|
34
|
-
// Cancel any in-flight run
|
|
35
|
-
abortControllerRef.current?.abort();
|
|
36
|
-
const controller = new AbortController();
|
|
37
|
-
abortControllerRef.current = controller;
|
|
38
|
-
|
|
39
|
-
setRunning(true);
|
|
40
|
-
setResult(null);
|
|
41
|
-
setLiveSteps([]);
|
|
42
|
-
|
|
43
|
-
const runnerConfig: TestRunnerConfig = {
|
|
44
|
-
...config,
|
|
45
|
-
abortSignal: controller.signal,
|
|
46
|
-
onStepComplete: (_scenarioIdx, step) => {
|
|
47
|
-
setLiveSteps(prev => [...prev, step]);
|
|
48
|
-
config?.onStepComplete?.(_scenarioIdx, step);
|
|
49
|
-
},
|
|
50
|
-
onScenarioComplete: config?.onScenarioComplete,
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const programResult = await runTestProgram(program, runnerConfig);
|
|
54
|
-
setResult(programResult);
|
|
55
|
-
setRunning(false);
|
|
56
|
-
abortControllerRef.current = null;
|
|
57
|
-
return programResult;
|
|
58
|
-
},
|
|
59
|
-
[config],
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const cancel = useCallback(() => {
|
|
63
|
-
abortControllerRef.current?.abort();
|
|
64
|
-
abortControllerRef.current = null;
|
|
65
|
-
setRunning(false);
|
|
66
|
-
}, []);
|
|
67
|
-
|
|
68
|
-
const reset = useCallback(() => {
|
|
69
|
-
abortControllerRef.current?.abort();
|
|
70
|
-
abortControllerRef.current = null;
|
|
71
|
-
setResult(null);
|
|
72
|
-
setRunning(false);
|
|
73
|
-
setLiveSteps([]);
|
|
74
|
-
}, []);
|
|
75
|
-
|
|
76
|
-
return { run, cancel, result, running, liveSteps, reset };
|
|
77
|
-
}
|