@statelyai/sdk 0.20.2 → 0.20.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/dist/embed.mjs +1 -1
- package/dist/index.mjs +3 -3
- package/dist/{inspect-CwN52e61.mjs → inspect-DU-gHyef.mjs} +1 -1
- package/dist/inspect.mjs +2 -2
- package/dist/{statelyPragma-Cnj58Rua.mjs → statelyPragma-Cesya0Pk.mjs} +748 -64
- package/dist/sync.mjs +1 -1
- package/dist/{version-C-1n7MoR.mjs → version-DoNMw8g6.mjs} +1 -1
- package/package.json +3 -3
package/dist/embed.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as createEventRegistry, o as createPendingExportManager, r as createPostMessageTransport, s as toInitMessage, t as SDK_VERSION } from "./version-
|
|
1
|
+
import { a as createEventRegistry, o as createPendingExportManager, r as createPostMessageTransport, s as toInitMessage, t as SDK_VERSION } from "./version-DoNMw8g6.mjs";
|
|
2
2
|
import { t as EDITOR_PROTOCOL_VERSION } from "./editorHostProtocol-D_h4y3rX.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/embed.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { EMBED_DOCUMENT_LANGUAGES, EMBED_DOCUMENT_LIMITS, INSPECTION_PROTOCOL_VERSION, INSPECTION_ROOM_QUERY_PARAM, createInspectionActorId, createInspectionRoomUrls, getInspectionRoomId } from "./protocol.mjs";
|
|
2
|
-
import { i as createWebSocketTransport, r as createPostMessageTransport } from "./version-
|
|
2
|
+
import { i as createWebSocketTransport, r as createPostMessageTransport } from "./version-DoNMw8g6.mjs";
|
|
3
3
|
import { t as EDITOR_PROTOCOL_VERSION } from "./editorHostProtocol-D_h4y3rX.mjs";
|
|
4
4
|
import { createStatelyEmbed } from "./embed.mjs";
|
|
5
5
|
import { n as createRemoteEditorSyncBackend, r as fetchEditorSyncAccess, t as EditorHostSession } from "./editorHostSession-CCTwvUOB.mjs";
|
|
6
6
|
import { n as StudioApiError, r as createStatelyClient, t as DEFAULT_STATELY_BASE_URL } from "./studio-DHGspwII.mjs";
|
|
7
|
-
import { a as RawCode, c as eventsSchemaToTSType, d as jsonSchemaToTSType, l as graphToMachineConfig, m as serializeJS, n as getStatelyPragma, o as contextSchemaToTSType, p as raw, r as upsertStatelyPragma, t as findStatelyPragmaAttachments, u as graphToXStateTS } from "./statelyPragma-
|
|
7
|
+
import { a as RawCode, c as eventsSchemaToTSType, d as jsonSchemaToTSType, l as graphToMachineConfig, m as serializeJS, n as getStatelyPragma, o as contextSchemaToTSType, p as raw, r as upsertStatelyPragma, t as findStatelyPragmaAttachments, u as graphToXStateTS } from "./statelyPragma-Cesya0Pk.mjs";
|
|
8
8
|
import { createS3AssetUploadAdapter, createSupabaseAssetUploadAdapter } from "./assetStorage.mjs";
|
|
9
|
-
import { n as createStatelyInspector, t as createInspector } from "./inspect-
|
|
9
|
+
import { n as createStatelyInspector, t as createInspector } from "./inspect-DU-gHyef.mjs";
|
|
10
10
|
import { createAuthorizationHeader, getCredentialToken } from "./auth.mjs";
|
|
11
11
|
import { buildAuthorizeUrl, createPkcePair, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, refreshToken, registerOAuthClient } from "./oauth.mjs";
|
|
12
12
|
import { StatelyApiError, createStatelyApiClient, createStatelyApiUrl } from "./api.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { INSPECTION_PROTOCOL_VERSION, createInspectionRoomUrls, getInspectionRoomId } from "./protocol.mjs";
|
|
2
|
-
import { a as createEventRegistry, i as createWebSocketTransport, n as inspectionRuntime, o as createPendingExportManager, t as SDK_VERSION } from "./version-
|
|
2
|
+
import { a as createEventRegistry, i as createWebSocketTransport, n as inspectionRuntime, o as createPendingExportManager, t as SDK_VERSION } from "./version-DoNMw8g6.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/openBrowser.ts
|
|
5
5
|
async function openBrowser(url) {
|
package/dist/inspect.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./version-
|
|
2
|
-
import { n as createStatelyInspector, t as createInspector } from "./inspect-
|
|
1
|
+
import "./version-DoNMw8g6.mjs";
|
|
2
|
+
import { n as createStatelyInspector, t as createInspector } from "./inspect-DU-gHyef.mjs";
|
|
3
3
|
|
|
4
4
|
export { createInspector, createStatelyInspector };
|
|
@@ -2636,7 +2636,8 @@ function formatEventParam(event) {
|
|
|
2636
2636
|
return "undefined";
|
|
2637
2637
|
}
|
|
2638
2638
|
function formatStringParam(value) {
|
|
2639
|
-
|
|
2639
|
+
if (typeof value === "string") return `'${value}'`;
|
|
2640
|
+
return isCodeExpression$1(value) ? serializeJS(value) : "undefined";
|
|
2640
2641
|
}
|
|
2641
2642
|
function formatInlineObject(value) {
|
|
2642
2643
|
return `{ ${Object.entries(value).filter(([, item]) => item !== void 0).map(([key, item]) => `${formatObjectKey(key)}: ${serializeJS(item)}`).join(", ")} }`;
|
|
@@ -3013,6 +3014,123 @@ const INLINE_EXPRESSION_DIRECTIVE_FIELDS = [
|
|
|
3013
3014
|
"initialInput",
|
|
3014
3015
|
"route"
|
|
3015
3016
|
];
|
|
3017
|
+
const EXACT_SEMVER$1 = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
3018
|
+
function parseProfileSpecifier(specifier) {
|
|
3019
|
+
const separator = specifier.lastIndexOf("@");
|
|
3020
|
+
const name = specifier.slice(0, separator);
|
|
3021
|
+
const version = specifier.slice(separator + 1);
|
|
3022
|
+
if (separator <= 0 || !/^@[^/]+\/[^@/]+$/.test(name) || !version) throw new Error(`Invalid profile specifier: ${specifier}`);
|
|
3023
|
+
return {
|
|
3024
|
+
name,
|
|
3025
|
+
version,
|
|
3026
|
+
kind: EXACT_SEMVER$1.test(version) ? "exact" : "range"
|
|
3027
|
+
};
|
|
3028
|
+
}
|
|
3029
|
+
function normalizeProfileRef(profile) {
|
|
3030
|
+
return profile === "xstate-v5" || profile === "xstate-v6-alpha" ? normalizeMachineProfile(profile) : profile;
|
|
3031
|
+
}
|
|
3032
|
+
/** Stately's semantic projection of the LangGraph 1.x APIs across runtimes. */
|
|
3033
|
+
const LANGGRAPH_PROFILE = "@statelyai/langgraph@1.0.0";
|
|
3034
|
+
const LANGGRAPH_PROFILE_MANIFEST = {
|
|
3035
|
+
profile: LANGGRAPH_PROFILE,
|
|
3036
|
+
name: "LangGraph",
|
|
3037
|
+
description: "LangGraph 1.x graph semantics for Python and JavaScript/TypeScript source.",
|
|
3038
|
+
restrictFormatsToListed: true,
|
|
3039
|
+
authoring: {
|
|
3040
|
+
terminology: {
|
|
3041
|
+
node: "node",
|
|
3042
|
+
edge: "edge",
|
|
3043
|
+
graph: "graph"
|
|
3044
|
+
},
|
|
3045
|
+
nodeTypes: [
|
|
3046
|
+
{
|
|
3047
|
+
kind: "node",
|
|
3048
|
+
label: "Node",
|
|
3049
|
+
description: "Graph API node",
|
|
3050
|
+
authorable: true
|
|
3051
|
+
},
|
|
3052
|
+
{
|
|
3053
|
+
kind: "task",
|
|
3054
|
+
label: "Task",
|
|
3055
|
+
description: "Functional API task",
|
|
3056
|
+
authorable: true
|
|
3057
|
+
},
|
|
3058
|
+
{
|
|
3059
|
+
kind: "entrypoint",
|
|
3060
|
+
label: "Entrypoint",
|
|
3061
|
+
description: "Functional API entrypoint",
|
|
3062
|
+
authorable: true
|
|
3063
|
+
},
|
|
3064
|
+
{
|
|
3065
|
+
kind: "agent",
|
|
3066
|
+
label: "Agent",
|
|
3067
|
+
description: "Prebuilt agent",
|
|
3068
|
+
authorable: true
|
|
3069
|
+
},
|
|
3070
|
+
{
|
|
3071
|
+
kind: "end",
|
|
3072
|
+
label: "END",
|
|
3073
|
+
description: "Terminal sentinel",
|
|
3074
|
+
authorable: true,
|
|
3075
|
+
terminal: true
|
|
3076
|
+
}
|
|
3077
|
+
],
|
|
3078
|
+
edgeTypes: [
|
|
3079
|
+
{
|
|
3080
|
+
kind: "edge",
|
|
3081
|
+
label: "Edge",
|
|
3082
|
+
description: "Direct route",
|
|
3083
|
+
authorable: true
|
|
3084
|
+
},
|
|
3085
|
+
{
|
|
3086
|
+
kind: "conditional",
|
|
3087
|
+
label: "Conditional edge",
|
|
3088
|
+
description: "Runtime-routed branch",
|
|
3089
|
+
authorable: true
|
|
3090
|
+
},
|
|
3091
|
+
{
|
|
3092
|
+
kind: "call",
|
|
3093
|
+
label: "Call",
|
|
3094
|
+
description: "Functional API call",
|
|
3095
|
+
authorable: true
|
|
3096
|
+
}
|
|
3097
|
+
],
|
|
3098
|
+
attachments: {},
|
|
3099
|
+
supportsInitialNode: false,
|
|
3100
|
+
supportsTargetlessEdges: false,
|
|
3101
|
+
supportsReenterEdges: false
|
|
3102
|
+
},
|
|
3103
|
+
operations: {
|
|
3104
|
+
simulate: false,
|
|
3105
|
+
validate: false,
|
|
3106
|
+
export: false
|
|
3107
|
+
},
|
|
3108
|
+
formats: [
|
|
3109
|
+
{
|
|
3110
|
+
format: "python",
|
|
3111
|
+
import: true,
|
|
3112
|
+
export: false,
|
|
3113
|
+
sourcePreserving: true
|
|
3114
|
+
},
|
|
3115
|
+
{
|
|
3116
|
+
format: "typescript",
|
|
3117
|
+
import: true,
|
|
3118
|
+
export: false,
|
|
3119
|
+
sourcePreserving: true
|
|
3120
|
+
},
|
|
3121
|
+
{
|
|
3122
|
+
format: "javascript",
|
|
3123
|
+
import: true,
|
|
3124
|
+
export: false,
|
|
3125
|
+
sourcePreserving: true
|
|
3126
|
+
}
|
|
3127
|
+
],
|
|
3128
|
+
features: {
|
|
3129
|
+
graphApi: true,
|
|
3130
|
+
functionalApi: true,
|
|
3131
|
+
prebuiltAgents: true
|
|
3132
|
+
}
|
|
3133
|
+
};
|
|
3016
3134
|
const XSTATE_FORMATS = [
|
|
3017
3135
|
{
|
|
3018
3136
|
format: "typescript",
|
|
@@ -3037,16 +3155,99 @@ const XSTATE_FORMATS = [
|
|
|
3037
3155
|
export: true
|
|
3038
3156
|
}
|
|
3039
3157
|
];
|
|
3158
|
+
const XSTATE_AUTHORING = {
|
|
3159
|
+
terminology: {
|
|
3160
|
+
node: "state",
|
|
3161
|
+
edge: "transition",
|
|
3162
|
+
graph: "machine"
|
|
3163
|
+
},
|
|
3164
|
+
nodeTypes: [
|
|
3165
|
+
{
|
|
3166
|
+
kind: "normal",
|
|
3167
|
+
label: "Normal",
|
|
3168
|
+
description: "Basic state",
|
|
3169
|
+
authorable: true,
|
|
3170
|
+
canContain: true
|
|
3171
|
+
},
|
|
3172
|
+
{
|
|
3173
|
+
kind: "parallel",
|
|
3174
|
+
label: "Parallel",
|
|
3175
|
+
description: "Concurrent child states",
|
|
3176
|
+
authorable: true,
|
|
3177
|
+
canContain: true
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
kind: "final",
|
|
3181
|
+
label: "Final",
|
|
3182
|
+
description: "Terminal state",
|
|
3183
|
+
authorable: true,
|
|
3184
|
+
terminal: true
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
kind: "history",
|
|
3188
|
+
label: "History",
|
|
3189
|
+
description: "Restores previous state",
|
|
3190
|
+
authorable: true
|
|
3191
|
+
},
|
|
3192
|
+
{
|
|
3193
|
+
kind: "choice",
|
|
3194
|
+
label: "Choice",
|
|
3195
|
+
description: "Guarded eventless routing",
|
|
3196
|
+
authorable: true
|
|
3197
|
+
}
|
|
3198
|
+
],
|
|
3199
|
+
edgeTypes: [{
|
|
3200
|
+
kind: "transition",
|
|
3201
|
+
label: "Transition",
|
|
3202
|
+
authorable: true
|
|
3203
|
+
}],
|
|
3204
|
+
attachments: {
|
|
3205
|
+
actions: true,
|
|
3206
|
+
guards: true,
|
|
3207
|
+
invokes: true,
|
|
3208
|
+
tags: true
|
|
3209
|
+
},
|
|
3210
|
+
supportsInitialNode: true,
|
|
3211
|
+
supportsTargetlessEdges: true,
|
|
3212
|
+
supportsReenterEdges: true
|
|
3213
|
+
};
|
|
3040
3214
|
const XSTATE_PROFILE_MANIFESTS = [{
|
|
3041
3215
|
profile: XSTATE_V5_PROFILE,
|
|
3042
3216
|
name: "XState v5",
|
|
3043
|
-
formats: [...XSTATE_FORMATS]
|
|
3217
|
+
formats: [...XSTATE_FORMATS],
|
|
3218
|
+
authoring: XSTATE_AUTHORING,
|
|
3219
|
+
operations: {
|
|
3220
|
+
simulate: true,
|
|
3221
|
+
validate: true,
|
|
3222
|
+
export: true
|
|
3223
|
+
}
|
|
3044
3224
|
}, {
|
|
3045
3225
|
profile: XSTATE_V6_PROFILE,
|
|
3046
3226
|
name: "XState v6",
|
|
3047
|
-
formats: [...XSTATE_FORMATS]
|
|
3227
|
+
formats: [...XSTATE_FORMATS],
|
|
3228
|
+
authoring: XSTATE_AUTHORING,
|
|
3229
|
+
operations: {
|
|
3230
|
+
simulate: true,
|
|
3231
|
+
validate: true,
|
|
3232
|
+
export: true
|
|
3233
|
+
}
|
|
3048
3234
|
}];
|
|
3049
|
-
const PROFILE_MANIFESTS = new Map(XSTATE_PROFILE_MANIFESTS.map((manifest) => [manifest.profile, manifest]));
|
|
3235
|
+
const PROFILE_MANIFESTS = new Map([...XSTATE_PROFILE_MANIFESTS, LANGGRAPH_PROFILE_MANIFEST].map((manifest) => [manifest.profile, manifest]));
|
|
3236
|
+
function getProfileManifest(profile) {
|
|
3237
|
+
return PROFILE_MANIFESTS.get(profile);
|
|
3238
|
+
}
|
|
3239
|
+
function isXStateV6ProfileRef(profile) {
|
|
3240
|
+
let current = normalizeProfileRef(profile);
|
|
3241
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3242
|
+
while (!seen.has(current)) {
|
|
3243
|
+
if (isXStateV6Profile(current)) return true;
|
|
3244
|
+
seen.add(current);
|
|
3245
|
+
const parent = getProfileManifest(current)?.extends;
|
|
3246
|
+
if (!parent || parseProfileSpecifier(parent).kind !== "exact") return false;
|
|
3247
|
+
current = parent;
|
|
3248
|
+
}
|
|
3249
|
+
return false;
|
|
3250
|
+
}
|
|
3050
3251
|
const XSTATE_V6_FN_TRANSITION_META = "@statelyai.xstate.v6.fnTransition";
|
|
3051
3252
|
const XSTATE_V6_FN_SOURCE_META = "@statelyai.xstate.v6.fnSource";
|
|
3052
3253
|
function sourceFile(source) {
|
|
@@ -3060,7 +3261,193 @@ function unwrapExpression(node) {
|
|
|
3060
3261
|
if (ts.isAsExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isParenthesizedExpression(node)) return unwrapExpression(node.expression);
|
|
3061
3262
|
return node;
|
|
3062
3263
|
}
|
|
3264
|
+
function canReplaceIdentifier(node) {
|
|
3265
|
+
const parent = node.parent;
|
|
3266
|
+
if (ts.isPropertyAccessExpression(parent) && parent.name === node) return false;
|
|
3267
|
+
if (ts.isPropertyAssignment(parent) && parent.name === node) return false;
|
|
3268
|
+
if (ts.isMethodDeclaration(parent) && parent.name === node) return false;
|
|
3269
|
+
return true;
|
|
3270
|
+
}
|
|
3271
|
+
function bindingNameContains(name, identifier) {
|
|
3272
|
+
if (ts.isIdentifier(name)) return name.text === identifier;
|
|
3273
|
+
return name.elements.some((element) => ts.isBindingElement(element) && bindingNameContains(element.name, identifier));
|
|
3274
|
+
}
|
|
3275
|
+
function scopeBindsName(node, identifier) {
|
|
3276
|
+
if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.parameters.some((parameter) => bindingNameContains(parameter.name, identifier))) return true;
|
|
3277
|
+
if (ts.isCatchClause(node) && node.variableDeclaration) return bindingNameContains(node.variableDeclaration.name, identifier);
|
|
3278
|
+
if (ts.isBlock(node)) return node.statements.some((statement) => {
|
|
3279
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContains(declaration.name, identifier));
|
|
3280
|
+
return ts.isFunctionDeclaration(statement) && statement.name?.text === identifier;
|
|
3281
|
+
});
|
|
3282
|
+
if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer)) return node.initializer.declarations.some((declaration) => bindingNameContains(declaration.name, identifier));
|
|
3283
|
+
return false;
|
|
3284
|
+
}
|
|
3285
|
+
function isShadowedWithinExpression(node, expression) {
|
|
3286
|
+
let ancestor = node.parent;
|
|
3287
|
+
while (ancestor && ancestor !== expression.parent) {
|
|
3288
|
+
if (scopeBindsName(ancestor, node.text)) return true;
|
|
3289
|
+
ancestor = ancestor.parent;
|
|
3290
|
+
}
|
|
3291
|
+
return false;
|
|
3292
|
+
}
|
|
3293
|
+
function replacementText(node, expression) {
|
|
3294
|
+
if (ts.isShorthandPropertyAssignment(node.parent) && node.parent.name === node) return `${node.text}: (${expression})`;
|
|
3295
|
+
return `(${expression})`;
|
|
3296
|
+
}
|
|
3297
|
+
function isSafeInlineExpression(expression) {
|
|
3298
|
+
let safe = true;
|
|
3299
|
+
function visit(node) {
|
|
3300
|
+
if (ts.isCallExpression(node) || ts.isNewExpression(node) || ts.isAwaitExpression(node) || ts.isYieldExpression(node) || ts.isDeleteExpression(node) || ts.isPostfixUnaryExpression(node) || ts.isPrefixUnaryExpression(node) && (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) || ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {
|
|
3301
|
+
safe = false;
|
|
3302
|
+
return;
|
|
3303
|
+
}
|
|
3304
|
+
ts.forEachChild(node, visit);
|
|
3305
|
+
}
|
|
3306
|
+
visit(expression);
|
|
3307
|
+
return safe;
|
|
3308
|
+
}
|
|
3309
|
+
function hasUnsafeVariableInitializer(node) {
|
|
3310
|
+
let unsafe = false;
|
|
3311
|
+
function visit(current) {
|
|
3312
|
+
if (unsafe) return;
|
|
3313
|
+
if (current !== node && (ts.isArrowFunction(current) || ts.isFunctionExpression(current) || ts.isFunctionDeclaration(current))) return;
|
|
3314
|
+
if (ts.isVariableDeclaration(current) && current.initializer && !isSafeInlineExpression(current.initializer)) {
|
|
3315
|
+
unsafe = true;
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
ts.forEachChild(current, visit);
|
|
3319
|
+
}
|
|
3320
|
+
visit(node);
|
|
3321
|
+
return unsafe;
|
|
3322
|
+
}
|
|
3323
|
+
function resolvedExpressionText(expression, bindings, resolving = /* @__PURE__ */ new Set()) {
|
|
3324
|
+
const source = expression.getSourceFile();
|
|
3325
|
+
const start = expression.getStart(source);
|
|
3326
|
+
const replacements = [];
|
|
3327
|
+
function visit(node) {
|
|
3328
|
+
if (ts.isIdentifier(node) && canReplaceIdentifier(node) && !isShadowedWithinExpression(node, expression)) {
|
|
3329
|
+
const binding = bindings.get(node.text);
|
|
3330
|
+
if (binding && !ts.isFunctionDeclaration(binding) && isSafeInlineExpression(binding) && binding !== expression && !resolving.has(node.text)) {
|
|
3331
|
+
const nextResolving = new Set(resolving).add(node.text);
|
|
3332
|
+
replacements.push({
|
|
3333
|
+
start: node.getStart(source) - start,
|
|
3334
|
+
end: node.getEnd() - start,
|
|
3335
|
+
text: replacementText(node, resolvedExpressionText(binding, bindings, nextResolving))
|
|
3336
|
+
});
|
|
3337
|
+
return;
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
ts.forEachChild(node, visit);
|
|
3341
|
+
}
|
|
3342
|
+
visit(expression);
|
|
3343
|
+
let result = expression.getText(source);
|
|
3344
|
+
for (const replacement of replacements.sort((a, b) => b.start - a.start)) result = result.slice(0, replacement.start) + replacement.text + result.slice(replacement.end);
|
|
3345
|
+
return result;
|
|
3346
|
+
}
|
|
3347
|
+
function typeNodeToJsonSchema(node) {
|
|
3348
|
+
if (ts.isParenthesizedTypeNode(node)) return typeNodeToJsonSchema(node.type);
|
|
3349
|
+
if (ts.isLiteralTypeNode(node)) {
|
|
3350
|
+
const literal = node.literal;
|
|
3351
|
+
if (ts.isStringLiteral(literal) || ts.isNumericLiteral(literal)) return { const: ts.isNumericLiteral(literal) ? Number(literal.text) : literal.text };
|
|
3352
|
+
if (literal.kind === ts.SyntaxKind.TrueKeyword) return { const: true };
|
|
3353
|
+
if (literal.kind === ts.SyntaxKind.FalseKeyword) return { const: false };
|
|
3354
|
+
return null;
|
|
3355
|
+
}
|
|
3356
|
+
if (ts.isUnionTypeNode(node)) {
|
|
3357
|
+
const members = node.types.map(typeNodeToJsonSchema);
|
|
3358
|
+
if (members.some((member) => !member)) return null;
|
|
3359
|
+
const constants = members.map((member) => member?.const);
|
|
3360
|
+
if (constants.every((value) => value !== void 0)) return { enum: constants };
|
|
3361
|
+
return { anyOf: members };
|
|
3362
|
+
}
|
|
3363
|
+
if (ts.isArrayTypeNode(node)) {
|
|
3364
|
+
const items = typeNodeToJsonSchema(node.elementType);
|
|
3365
|
+
return items ? {
|
|
3366
|
+
type: "array",
|
|
3367
|
+
items
|
|
3368
|
+
} : null;
|
|
3369
|
+
}
|
|
3370
|
+
if (ts.isTupleTypeNode(node)) {
|
|
3371
|
+
const items = node.elements.map((element) => typeNodeToJsonSchema(element));
|
|
3372
|
+
if (items.some((item) => !item)) return null;
|
|
3373
|
+
return {
|
|
3374
|
+
type: "array",
|
|
3375
|
+
items,
|
|
3376
|
+
minItems: items.length,
|
|
3377
|
+
maxItems: items.length
|
|
3378
|
+
};
|
|
3379
|
+
}
|
|
3380
|
+
if (ts.isTypeLiteralNode(node)) {
|
|
3381
|
+
const properties = {};
|
|
3382
|
+
const required = [];
|
|
3383
|
+
for (const member of node.members) {
|
|
3384
|
+
if (!ts.isPropertySignature(member) || !member.type || !member.name) return null;
|
|
3385
|
+
const name = propName(member.name);
|
|
3386
|
+
const schema = typeNodeToJsonSchema(member.type);
|
|
3387
|
+
if (!name || !schema) return null;
|
|
3388
|
+
properties[name] = schema;
|
|
3389
|
+
if (!member.questionToken) required.push(name);
|
|
3390
|
+
}
|
|
3391
|
+
return {
|
|
3392
|
+
type: "object",
|
|
3393
|
+
properties,
|
|
3394
|
+
...required.length ? { required } : void 0,
|
|
3395
|
+
additionalProperties: false
|
|
3396
|
+
};
|
|
3397
|
+
}
|
|
3398
|
+
switch (node.kind) {
|
|
3399
|
+
case ts.SyntaxKind.StringKeyword: return { type: "string" };
|
|
3400
|
+
case ts.SyntaxKind.NumberKeyword: return { type: "number" };
|
|
3401
|
+
case ts.SyntaxKind.BooleanKeyword: return { type: "boolean" };
|
|
3402
|
+
case ts.SyntaxKind.NullKeyword: return { type: "null" };
|
|
3403
|
+
case ts.SyntaxKind.UnknownKeyword:
|
|
3404
|
+
case ts.SyntaxKind.AnyKeyword: return {};
|
|
3405
|
+
default: return null;
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
function typesCallSchema(node) {
|
|
3409
|
+
const value = unwrapExpression(node);
|
|
3410
|
+
if (!ts.isCallExpression(value) || value.expression.getText() !== "types" || value.typeArguments?.length !== 1) return null;
|
|
3411
|
+
return typeNodeToJsonSchema(value.typeArguments[0]);
|
|
3412
|
+
}
|
|
3413
|
+
function schemasObjectToValue(node) {
|
|
3414
|
+
const value = unwrapExpression(node);
|
|
3415
|
+
if (!ts.isObjectLiteralExpression(value)) return null;
|
|
3416
|
+
const result = {};
|
|
3417
|
+
for (const property of value.properties) {
|
|
3418
|
+
if (!ts.isPropertyAssignment(property)) continue;
|
|
3419
|
+
const key = propName(property.name);
|
|
3420
|
+
if (!key) continue;
|
|
3421
|
+
if (key === "events" && ts.isObjectLiteralExpression(property.initializer)) {
|
|
3422
|
+
const events = {};
|
|
3423
|
+
for (const eventProperty of property.initializer.properties) {
|
|
3424
|
+
if (!ts.isPropertyAssignment(eventProperty)) continue;
|
|
3425
|
+
const eventType = propName(eventProperty.name);
|
|
3426
|
+
const schema = typesCallSchema(eventProperty.initializer);
|
|
3427
|
+
if (eventType && schema) events[eventType] = schema;
|
|
3428
|
+
}
|
|
3429
|
+
result.events = events;
|
|
3430
|
+
continue;
|
|
3431
|
+
}
|
|
3432
|
+
const schema = typesCallSchema(property.initializer);
|
|
3433
|
+
if (!schema) continue;
|
|
3434
|
+
result[key] = key === "context" ? schema.properties ?? {} : schema;
|
|
3435
|
+
}
|
|
3436
|
+
return result;
|
|
3437
|
+
}
|
|
3063
3438
|
function propertyContext(parent, key) {
|
|
3439
|
+
if (parent.setupValue && (key === "actions" || key === "guards" || key === "actors" || key === "delays")) return {
|
|
3440
|
+
v6: parent.v6,
|
|
3441
|
+
implementationMap: true
|
|
3442
|
+
};
|
|
3443
|
+
if (parent.implementationMap) return {
|
|
3444
|
+
v6: parent.v6,
|
|
3445
|
+
implementationValue: true
|
|
3446
|
+
};
|
|
3447
|
+
if (parent.effectArgumentValue) return {
|
|
3448
|
+
v6: parent.v6,
|
|
3449
|
+
effectArgumentValue: true
|
|
3450
|
+
};
|
|
3064
3451
|
if (parent.invokeValue && key === "src") return {
|
|
3065
3452
|
v6: parent.v6,
|
|
3066
3453
|
actorSourceValue: true
|
|
@@ -3078,6 +3465,14 @@ function propertyContext(parent, key) {
|
|
|
3078
3465
|
assignmentMap: true,
|
|
3079
3466
|
transitionContext: true
|
|
3080
3467
|
};
|
|
3468
|
+
if (key === "context") return {
|
|
3469
|
+
v6: parent.v6,
|
|
3470
|
+
machineContextValue: true
|
|
3471
|
+
};
|
|
3472
|
+
if (parent.transitionValue && key === "target") return {
|
|
3473
|
+
v6: parent.v6,
|
|
3474
|
+
targetValue: true
|
|
3475
|
+
};
|
|
3081
3476
|
if (parent.assignmentMap) return {
|
|
3082
3477
|
v6: parent.v6,
|
|
3083
3478
|
assignmentValue: true
|
|
@@ -3124,14 +3519,11 @@ function propertyContext(parent, key) {
|
|
|
3124
3519
|
};
|
|
3125
3520
|
return { v6: parent.v6 };
|
|
3126
3521
|
}
|
|
3127
|
-
function fallbackFunctionTransition(fn
|
|
3128
|
-
return {
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
[XSTATE_V6_FN_SOURCE_META]: fn.getText()
|
|
3133
|
-
}
|
|
3134
|
-
};
|
|
3522
|
+
function fallbackFunctionTransition(fn) {
|
|
3523
|
+
return { meta: {
|
|
3524
|
+
[XSTATE_V6_FN_TRANSITION_META]: true,
|
|
3525
|
+
[XSTATE_V6_FN_SOURCE_META]: fn.getText()
|
|
3526
|
+
} };
|
|
3135
3527
|
}
|
|
3136
3528
|
function conditionText(cond) {
|
|
3137
3529
|
return cond.negated ? `!(${cond.text})` : cond.text;
|
|
@@ -3152,7 +3544,7 @@ function hashString(value) {
|
|
|
3152
3544
|
return (hash >>> 0).toString(36);
|
|
3153
3545
|
}
|
|
3154
3546
|
function inlineGuardCode(params, condition) {
|
|
3155
|
-
return `${params} => ${condition}`;
|
|
3547
|
+
return `${params} => ${condition.trimStart().startsWith("{") ? `(${condition})` : condition}`;
|
|
3156
3548
|
}
|
|
3157
3549
|
function guardFromConditions(conds, params) {
|
|
3158
3550
|
const simplified = simplifyConditions(conds);
|
|
@@ -3188,7 +3580,7 @@ function transitionFromValue(value, actions) {
|
|
|
3188
3580
|
function expressionBranches(expression, bindings, depth) {
|
|
3189
3581
|
const node = unwrapExpression(expression);
|
|
3190
3582
|
if (ts.isConditionalExpression(node)) {
|
|
3191
|
-
const cond = node.condition
|
|
3583
|
+
const cond = resolvedExpressionText(node.condition, bindings);
|
|
3192
3584
|
return [...expressionBranches(node.whenTrue, bindings, depth + 1).map((branch) => ({
|
|
3193
3585
|
...branch,
|
|
3194
3586
|
conds: [{ text: cond }, ...branch.conds]
|
|
@@ -3201,7 +3593,7 @@ function expressionBranches(expression, bindings, depth) {
|
|
|
3201
3593
|
}))];
|
|
3202
3594
|
}
|
|
3203
3595
|
if (ts.isBinaryExpression(node) && (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken || node.operatorToken.kind === ts.SyntaxKind.BarBarToken)) {
|
|
3204
|
-
const cond = node.left
|
|
3596
|
+
const cond = resolvedExpressionText(node.left, bindings);
|
|
3205
3597
|
if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) return [...expressionBranches(node.right, bindings, depth + 1).map((branch) => ({
|
|
3206
3598
|
...branch,
|
|
3207
3599
|
conds: [{ text: cond }, ...branch.conds]
|
|
@@ -3259,7 +3651,7 @@ function expressionStatementAction(statement, enqName, bindings) {
|
|
|
3259
3651
|
if (ts.isIdentifier(callee) && callee.text === enqName) return {
|
|
3260
3652
|
type: "xstate.expr",
|
|
3261
3653
|
params: {
|
|
3262
|
-
code: expression
|
|
3654
|
+
code: resolvedExpressionText(expression, bindings),
|
|
3263
3655
|
lang: "ts"
|
|
3264
3656
|
}
|
|
3265
3657
|
};
|
|
@@ -3269,7 +3661,7 @@ function expressionStatementAction(statement, enqName, bindings) {
|
|
|
3269
3661
|
const args = expression.arguments;
|
|
3270
3662
|
const value = (index) => {
|
|
3271
3663
|
const arg = args[index];
|
|
3272
|
-
return arg && ts.isExpression(arg) ? expressionToValue(arg, bindings, {}, 0) : void 0;
|
|
3664
|
+
return arg && ts.isExpression(arg) ? expressionToValue(arg, bindings, { effectArgumentValue: true }, 0) : void 0;
|
|
3273
3665
|
};
|
|
3274
3666
|
const spreadOpts = (index) => {
|
|
3275
3667
|
const opts = value(index);
|
|
@@ -3358,7 +3750,7 @@ function statementBranches(statements, bindings, enqName, prefixes = [{
|
|
|
3358
3750
|
}
|
|
3359
3751
|
}
|
|
3360
3752
|
if (ts.isIfStatement(statement)) {
|
|
3361
|
-
const cond = statement.expression
|
|
3753
|
+
const cond = resolvedExpressionText(statement.expression, scopedBindings);
|
|
3362
3754
|
const thenBranches = statementBranches(ts.isBlock(statement.thenStatement) ? statement.thenStatement.statements : [statement.thenStatement], scopedBindings, enqName, [{
|
|
3363
3755
|
...prefix,
|
|
3364
3756
|
conds: [...prefix.conds, { text: cond }]
|
|
@@ -3382,7 +3774,14 @@ function statementBranches(statements, bindings, enqName, prefixes = [{
|
|
|
3382
3774
|
continue;
|
|
3383
3775
|
}
|
|
3384
3776
|
if (ts.isSwitchStatement(statement)) {
|
|
3385
|
-
|
|
3777
|
+
if (statement.caseBlock.clauses.some((clause) => clause.statements.length === 0)) {
|
|
3778
|
+
nextOpen.push({
|
|
3779
|
+
...prefix,
|
|
3780
|
+
unknown: true
|
|
3781
|
+
});
|
|
3782
|
+
continue;
|
|
3783
|
+
}
|
|
3784
|
+
const expr = resolvedExpressionText(statement.expression, scopedBindings);
|
|
3386
3785
|
const prior = [];
|
|
3387
3786
|
for (const clause of statement.caseBlock.clauses) {
|
|
3388
3787
|
const ownCond = ts.isCaseClause(clause) ? { text: `${expr} === ${clause.expression.getText()}` } : null;
|
|
@@ -3419,9 +3818,11 @@ function guardParams(fn) {
|
|
|
3419
3818
|
return `(${param.getText()})`;
|
|
3420
3819
|
}
|
|
3421
3820
|
function normalizeFunctionTransition(fn, bindings, depth) {
|
|
3422
|
-
|
|
3423
|
-
const
|
|
3424
|
-
|
|
3821
|
+
if (fn.body && ts.isBlock(fn.body) && hasUnsafeVariableInitializer(fn.body)) return fallbackFunctionTransition(fn);
|
|
3822
|
+
const branches = ts.isArrowFunction(fn) && !ts.isBlock(fn.body) ? expressionBranches(fn.body, bindings, depth + 1) : fn.body && ts.isBlock(fn.body) ? statementBranches(fn.body.statements, bindings, enqueueParamName(fn)) : [];
|
|
3823
|
+
if (branches.some((branch) => branch.unknown)) return fallbackFunctionTransition(fn);
|
|
3824
|
+
const transitions = branches.map((branch) => {
|
|
3825
|
+
const transition = transitionFromValue(branch.result, branch.actions);
|
|
3425
3826
|
if (!transition) return null;
|
|
3426
3827
|
if (typeof transition === "string") {
|
|
3427
3828
|
const guard = guardFromConditions(branch.conds, guardParams(fn));
|
|
@@ -3438,7 +3839,7 @@ function normalizeFunctionTransition(fn, bindings, depth) {
|
|
|
3438
3839
|
}).filter((transition) => Boolean(transition));
|
|
3439
3840
|
if (transitions.length === 1) return transitions[0];
|
|
3440
3841
|
if (transitions.length > 1) return transitions;
|
|
3441
|
-
return fallbackFunctionTransition(fn
|
|
3842
|
+
return fallbackFunctionTransition(fn);
|
|
3442
3843
|
}
|
|
3443
3844
|
function inlineAction(fn) {
|
|
3444
3845
|
return {
|
|
@@ -3483,11 +3884,24 @@ function objectLiteralToValue(node, bindings, context, depth, overrides = /* @__
|
|
|
3483
3884
|
result[key] = overrides.get(key);
|
|
3484
3885
|
continue;
|
|
3485
3886
|
}
|
|
3887
|
+
if (context.v6 && key === "schemas" && ts.isPropertyAssignment(property)) {
|
|
3888
|
+
const schemas = schemasObjectToValue(property.initializer);
|
|
3889
|
+
if (schemas) {
|
|
3890
|
+
result[key] = schemas;
|
|
3891
|
+
continue;
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3486
3894
|
if (ts.isShorthandPropertyAssignment(property)) {
|
|
3487
|
-
|
|
3895
|
+
const childContext = propertyContext(context, key);
|
|
3896
|
+
const childValue = expressionToValue(property.name, bindings, childContext, depth + 1);
|
|
3897
|
+
if (childContext.implementationValue && childValue === void 0) continue;
|
|
3898
|
+
result[key] = childValue;
|
|
3488
3899
|
continue;
|
|
3489
3900
|
}
|
|
3490
|
-
|
|
3901
|
+
const childContext = propertyContext(context, key);
|
|
3902
|
+
const childValue = expressionToValue(property.initializer, bindings, childContext, depth + 1);
|
|
3903
|
+
if (childContext.implementationValue && childValue === void 0) continue;
|
|
3904
|
+
result[key] = childValue;
|
|
3491
3905
|
}
|
|
3492
3906
|
if (context.transitionValue && "to" in result) {
|
|
3493
3907
|
const to = result.to;
|
|
@@ -3513,6 +3927,23 @@ function objectLiteralToValue(node, bindings, context, depth, overrides = /* @__
|
|
|
3513
3927
|
function expressionToValue(expression, bindings, context = {}, depth = 0) {
|
|
3514
3928
|
if (depth > 30) return void 0;
|
|
3515
3929
|
const node = unwrapExpression(expression);
|
|
3930
|
+
if (context.implementationValue) {
|
|
3931
|
+
if (ts.isIdentifier(node)) {
|
|
3932
|
+
const binding = bindings.get(node.text);
|
|
3933
|
+
if (binding) return inlineCodeExpression(ts.isFunctionDeclaration(binding) ? binding.getText() : unwrapExpression(binding).getText());
|
|
3934
|
+
return;
|
|
3935
|
+
}
|
|
3936
|
+
return inlineCodeExpression(node.getText());
|
|
3937
|
+
}
|
|
3938
|
+
if (context.machineContextValue && (ts.isArrowFunction(node) || ts.isFunctionExpression(node))) return inlineCodeExpression(node.getText());
|
|
3939
|
+
if (context.targetValue) {
|
|
3940
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
|
|
3941
|
+
if (ts.isIdentifier(node)) {
|
|
3942
|
+
const binding = bindings.get(node.text);
|
|
3943
|
+
if (binding && !ts.isFunctionDeclaration(binding)) return expressionToValue(binding, bindings, context, depth + 1);
|
|
3944
|
+
}
|
|
3945
|
+
return inlineCodeExpression(resolvedExpressionText(node, bindings));
|
|
3946
|
+
}
|
|
3516
3947
|
if (context.actorSourceValue) {
|
|
3517
3948
|
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
|
|
3518
3949
|
if (ts.isIdentifier(node)) {
|
|
@@ -3534,6 +3965,10 @@ function expressionToValue(expression, bindings, context = {}, depth = 0) {
|
|
|
3534
3965
|
if (node.kind === ts.SyntaxKind.TrueKeyword) return context.ioValue ? inlineCodeExpression("true") : true;
|
|
3535
3966
|
if (node.kind === ts.SyntaxKind.FalseKeyword) return context.ioValue ? inlineCodeExpression("false") : false;
|
|
3536
3967
|
if (node.kind === ts.SyntaxKind.NullKeyword) return context.ioValue ? inlineCodeExpression("null") : null;
|
|
3968
|
+
if (context.effectArgumentValue && !ts.isObjectLiteralExpression(node) && !ts.isArrayLiteralExpression(node)) {
|
|
3969
|
+
if (ts.isIdentifier(node) && node.text === "undefined") return void 0;
|
|
3970
|
+
return inlineCodeExpression(resolvedExpressionText(node, bindings));
|
|
3971
|
+
}
|
|
3537
3972
|
if (context.ioPropertyValue) {
|
|
3538
3973
|
if (ts.isIdentifier(node) && node.text === "undefined") return void 0;
|
|
3539
3974
|
if (ts.isIdentifier(node)) {
|
|
@@ -3548,7 +3983,7 @@ function expressionToValue(expression, bindings, context = {}, depth = 0) {
|
|
|
3548
3983
|
const binding = bindings.get(node.text);
|
|
3549
3984
|
if (binding && !ts.isFunctionDeclaration(binding)) return expressionToValue(binding, bindings, context, depth + 1);
|
|
3550
3985
|
}
|
|
3551
|
-
return wrapAssignExpression(node
|
|
3986
|
+
return wrapAssignExpression(resolvedExpressionText(node, bindings));
|
|
3552
3987
|
}
|
|
3553
3988
|
if (context.transitionContext && !ts.isObjectLiteralExpression(node)) return inlineCodeExpression(node.getText());
|
|
3554
3989
|
if (context.ioValue && !ts.isObjectLiteralExpression(node)) return inlineCodeExpression(node.getText());
|
|
@@ -3628,10 +4063,20 @@ function isCreateMachineCall(node) {
|
|
|
3628
4063
|
if (ts.isPropertyAccessExpression(expression)) return expression.name.text === "createMachine";
|
|
3629
4064
|
return false;
|
|
3630
4065
|
}
|
|
4066
|
+
function setupCallForCreateMachine(node, bindings) {
|
|
4067
|
+
if (!ts.isPropertyAccessExpression(node.expression)) return null;
|
|
4068
|
+
let receiver = unwrapExpression(node.expression.expression);
|
|
4069
|
+
if (ts.isIdentifier(receiver)) {
|
|
4070
|
+
const binding = bindings.get(receiver.text);
|
|
4071
|
+
if (binding && !ts.isFunctionDeclaration(binding)) receiver = unwrapExpression(binding);
|
|
4072
|
+
}
|
|
4073
|
+
return ts.isCallExpression(receiver) && ts.isIdentifier(receiver.expression) && receiver.expression.text === "setup" ? receiver : null;
|
|
4074
|
+
}
|
|
3631
4075
|
function hasV6Syntax(source) {
|
|
3632
4076
|
const file = sourceFile(source);
|
|
3633
4077
|
const bindings = collectBindings(file);
|
|
3634
4078
|
let found = false;
|
|
4079
|
+
const visitedSyntaxBindings = /* @__PURE__ */ new Set();
|
|
3635
4080
|
function containsFunction(expression, seenBindings = /* @__PURE__ */ new Set()) {
|
|
3636
4081
|
if (ts.isFunctionDeclaration(expression)) return true;
|
|
3637
4082
|
const node = unwrapExpression(expression);
|
|
@@ -3652,8 +4097,16 @@ function hasV6Syntax(source) {
|
|
|
3652
4097
|
if (ts.isCallExpression(node)) return ts.isIdentifier(node.expression) && containsFunction(node.expression, seenBindings) || node.arguments.some((argument) => ts.isExpression(argument) && containsFunction(argument, seenBindings));
|
|
3653
4098
|
return false;
|
|
3654
4099
|
}
|
|
3655
|
-
function
|
|
4100
|
+
function visitSyntax(node) {
|
|
3656
4101
|
if (found) return;
|
|
4102
|
+
if (ts.isIdentifier(node)) {
|
|
4103
|
+
const binding = bindings.get(node.text);
|
|
4104
|
+
if (binding && !visitedSyntaxBindings.has(binding)) {
|
|
4105
|
+
visitedSyntaxBindings.add(binding);
|
|
4106
|
+
visitSyntax(binding);
|
|
4107
|
+
}
|
|
4108
|
+
if (found) return;
|
|
4109
|
+
}
|
|
3657
4110
|
if (ts.isPropertyAssignment(node) && (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name))) {
|
|
3658
4111
|
const key = node.name.text;
|
|
3659
4112
|
if (key === "triggers" || key === "internalEvents" || key === "matches" || key === "actorSources" || key === "timeout" || key === "onTimeout" || key === "choice" || key === "route") {
|
|
@@ -3665,9 +4118,19 @@ function hasV6Syntax(source) {
|
|
|
3665
4118
|
return;
|
|
3666
4119
|
}
|
|
3667
4120
|
}
|
|
3668
|
-
ts.forEachChild(node,
|
|
4121
|
+
ts.forEachChild(node, visitSyntax);
|
|
3669
4122
|
}
|
|
3670
|
-
|
|
4123
|
+
function visitMachineCalls(node) {
|
|
4124
|
+
if (ts.isCallExpression(node) && isCreateMachineCall(node)) {
|
|
4125
|
+
const config = node.arguments[0];
|
|
4126
|
+
if (config) visitSyntax(config);
|
|
4127
|
+
const setupConfig = setupCallForCreateMachine(node, bindings)?.arguments[0];
|
|
4128
|
+
if (setupConfig) visitSyntax(setupConfig);
|
|
4129
|
+
return;
|
|
4130
|
+
}
|
|
4131
|
+
ts.forEachChild(node, visitMachineCalls);
|
|
4132
|
+
}
|
|
4133
|
+
visitMachineCalls(file);
|
|
3671
4134
|
return found;
|
|
3672
4135
|
}
|
|
3673
4136
|
function detectXStateSourceProfile(source) {
|
|
@@ -3695,7 +4158,18 @@ function extractXStateMachineConfigs(source, options = {}) {
|
|
|
3695
4158
|
const arg = node.arguments[0];
|
|
3696
4159
|
if (!arg) return;
|
|
3697
4160
|
const value = expressionToValue(arg, bindings, { v6: profile === "xstate-v6-alpha" });
|
|
3698
|
-
if (value && typeof value === "object" && !Array.isArray(value))
|
|
4161
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
4162
|
+
const setupArg = setupCallForCreateMachine(node, bindings)?.arguments[0];
|
|
4163
|
+
const setupValue = setupArg ? expressionToValue(setupArg, bindings, {
|
|
4164
|
+
v6: profile === "xstate-v6-alpha",
|
|
4165
|
+
setupValue: true
|
|
4166
|
+
}) : null;
|
|
4167
|
+
const setupRecord = setupValue && typeof setupValue === "object" && !Array.isArray(setupValue) ? Object.fromEntries(Object.entries(setupValue).filter(([, item]) => !(item && typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0))) : {};
|
|
4168
|
+
found.push({
|
|
4169
|
+
...setupRecord,
|
|
4170
|
+
...value
|
|
4171
|
+
});
|
|
4172
|
+
}
|
|
3699
4173
|
}
|
|
3700
4174
|
visit(file);
|
|
3701
4175
|
return found;
|
|
@@ -3777,7 +4251,8 @@ function isRequiredProperty(key, def, required) {
|
|
|
3777
4251
|
return typeof def === "object" && def !== null && def.required === true;
|
|
3778
4252
|
}
|
|
3779
4253
|
function graphToXStateTS(graph, options = {}) {
|
|
3780
|
-
const
|
|
4254
|
+
const inferredXStateVersion = isXStateV6ProfileRef(graph.data.profile ?? "xstate-v5") ? 6 : 5;
|
|
4255
|
+
const { exportStyle = "named", targetLanguage = "typescript", xstateVersion = inferredXStateVersion, ...configOptions } = options;
|
|
3781
4256
|
const schemas = graph.data.schemas;
|
|
3782
4257
|
const impls = filterInlineImplementations(graph.data.implementations);
|
|
3783
4258
|
const supportsTypeSyntax = targetLanguage === "typescript";
|
|
@@ -3789,12 +4264,14 @@ function graphToXStateTS(graph, options = {}) {
|
|
|
3789
4264
|
const hasSetup = hasSchemas || hasActions || hasGuards || hasActors || hasDelays;
|
|
3790
4265
|
const builtInActions = getUsedBuiltInActions(graph, xstateVersion);
|
|
3791
4266
|
const actorSourceImports = getActorSourceImports(graph);
|
|
4267
|
+
const implementationImports = getImplementationImports(impls);
|
|
3792
4268
|
const imports = buildImports({
|
|
3793
4269
|
hasSetup,
|
|
3794
4270
|
hasActors,
|
|
3795
4271
|
actors: impls?.actors ?? [],
|
|
3796
4272
|
builtInActions,
|
|
3797
4273
|
actorSourceImports,
|
|
4274
|
+
implementationImports,
|
|
3798
4275
|
usesTypes: xstateVersion === 6 && supportsTypeSyntax && hasSchemas
|
|
3799
4276
|
});
|
|
3800
4277
|
const machineConfig = xstateVersion === 6 ? toV6MachineConfig(graphToMachineConfig(graph, configOptions)) : toV5MachineConfig(graphToMachineConfig(graph, configOptions));
|
|
@@ -3875,9 +4352,9 @@ function toV6MachineConfig(machineConfig) {
|
|
|
3875
4352
|
return mapV6MachineConfig(machineConfig);
|
|
3876
4353
|
}
|
|
3877
4354
|
function mapV6MachineConfig(value, context = {}) {
|
|
4355
|
+
if (context.transitionValue) return toV6TransitionValue(value);
|
|
3878
4356
|
if (Array.isArray(value)) return value.map((item) => mapV6MachineConfig(item, context));
|
|
3879
4357
|
if (!value || typeof value !== "object") return value;
|
|
3880
|
-
if (context.transitionValue) return toV6TransitionValue(value);
|
|
3881
4358
|
const result = {};
|
|
3882
4359
|
for (const [key, item] of Object.entries(value)) {
|
|
3883
4360
|
if (key === "entry" || key === "exit" || key === "actions") {
|
|
@@ -3903,7 +4380,7 @@ function mapV6TransitionMap(value) {
|
|
|
3903
4380
|
return result;
|
|
3904
4381
|
}
|
|
3905
4382
|
function toV6TransitionValue(value) {
|
|
3906
|
-
if (Array.isArray(value)) return value.map((item) => toV6TransitionValue(item));
|
|
4383
|
+
if (Array.isArray(value)) return buildV6TransitionFunction(value) ?? value.map((item) => toV6TransitionValue(item));
|
|
3907
4384
|
if (!value || typeof value !== "object") return value;
|
|
3908
4385
|
const transition = value;
|
|
3909
4386
|
if (transition.guard || transition.description || transition.input !== void 0) return mapV6MachineConfig(transition);
|
|
@@ -3920,6 +4397,63 @@ function toV6TransitionValue(value) {
|
|
|
3920
4397
|
context
|
|
3921
4398
|
}) ?? mapV6MachineConfig(transition);
|
|
3922
4399
|
}
|
|
4400
|
+
function guardCondition(value) {
|
|
4401
|
+
const expression = inlineExpr(value);
|
|
4402
|
+
if (!expression) return value === void 0 ? { condition: "true" } : null;
|
|
4403
|
+
const arrow = expression.indexOf("=>");
|
|
4404
|
+
if (arrow < 0) return null;
|
|
4405
|
+
const params = expression.slice(0, arrow).trim();
|
|
4406
|
+
const body = expression.slice(arrow + 2).trim();
|
|
4407
|
+
if (body.startsWith("{")) return null;
|
|
4408
|
+
return {
|
|
4409
|
+
condition: body,
|
|
4410
|
+
firstParam: params.startsWith("(") && params.endsWith(")") ? params.slice(1, -1).trim() : params
|
|
4411
|
+
};
|
|
4412
|
+
}
|
|
4413
|
+
function buildV6TransitionFunction(transitions) {
|
|
4414
|
+
const branches = [];
|
|
4415
|
+
let authoredFirstParam;
|
|
4416
|
+
for (const item of transitions) {
|
|
4417
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return;
|
|
4418
|
+
const transition = item;
|
|
4419
|
+
if (transition.description !== void 0 || transition.input !== void 0 || transition.matches !== void 0) return;
|
|
4420
|
+
const guard = guardCondition(transition.guard);
|
|
4421
|
+
if (!guard) return;
|
|
4422
|
+
if (guard.firstParam) {
|
|
4423
|
+
if (authoredFirstParam && authoredFirstParam !== guard.firstParam) return;
|
|
4424
|
+
authoredFirstParam = guard.firstParam;
|
|
4425
|
+
}
|
|
4426
|
+
const actionValue = transition.actions;
|
|
4427
|
+
const effects = (Array.isArray(actionValue) ? actionValue : actionValue === void 0 ? [] : [actionValue]).map(actionToV6Effect);
|
|
4428
|
+
if (effects.some((effect) => !effect)) return;
|
|
4429
|
+
const rendered = renderV6Effects(effects.filter((effect) => Boolean(effect)), transition.context === void 0 ? void 0 : serializeJS(unwrapTemplateExpressions(transition.context)));
|
|
4430
|
+
const returnValue = buildV6TransitionReturnValue({
|
|
4431
|
+
target: typeof transition.target === "string" ? transition.target : void 0,
|
|
4432
|
+
reenter: transition.reenter === true,
|
|
4433
|
+
meta: transition.meta
|
|
4434
|
+
}, rendered.contextValue);
|
|
4435
|
+
if (!returnValue) return;
|
|
4436
|
+
const body = [...rendered.statements.map(formatV6Statement), `return ${returnValue};`];
|
|
4437
|
+
if (body.length === 0) return;
|
|
4438
|
+
if (guard.condition === "true") branches.push(...body.map((line) => ` ${line}`));
|
|
4439
|
+
else {
|
|
4440
|
+
branches.push(` if (${guard.condition}) {`);
|
|
4441
|
+
branches.push(...body.map((line) => ` ${line}`));
|
|
4442
|
+
branches.push(" }");
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
if (branches.length === 0) return;
|
|
4446
|
+
const referenced = branches.join("\n");
|
|
4447
|
+
const inferredBindings = [
|
|
4448
|
+
"context",
|
|
4449
|
+
"event",
|
|
4450
|
+
"actions",
|
|
4451
|
+
"children",
|
|
4452
|
+
"self",
|
|
4453
|
+
"system"
|
|
4454
|
+
].filter((name) => new RegExp(`\\b${name}\\b`).test(referenced));
|
|
4455
|
+
return raw(`(${authoredFirstParam ?? (inferredBindings.length ? `{ ${inferredBindings.join(", ")} }` : "_")}, enq) => {\n${branches.join("\n")}\n}`);
|
|
4456
|
+
}
|
|
3923
4457
|
function toV6ActionField(actions) {
|
|
3924
4458
|
if (actions.length === 1) {
|
|
3925
4459
|
const expr = inlineExpr(actions[0]);
|
|
@@ -3930,16 +4464,41 @@ function toV6ActionField(actions) {
|
|
|
3930
4464
|
function buildV6ActionFunction(actions, transition) {
|
|
3931
4465
|
const effects = actions.map(actionToV6Effect);
|
|
3932
4466
|
if (effects.some((effect) => !effect)) return void 0;
|
|
3933
|
-
const
|
|
3934
|
-
|
|
3935
|
-
|
|
4467
|
+
const explicitContext = transition?.context === void 0 ? void 0 : serializeJS(unwrapTemplateExpressions(transition.context));
|
|
4468
|
+
const rendered = renderV6Effects(effects.filter((effect) => Boolean(effect)), explicitContext);
|
|
4469
|
+
const statements = rendered.statements;
|
|
4470
|
+
let returnValue = rendered.contextValue ? `{ context: ${rendered.contextValue} }` : void 0;
|
|
4471
|
+
if (transition) returnValue = buildV6TransitionReturnValue(transition, rendered.contextValue);
|
|
4472
|
+
if (statements.length === 0 && !returnValue) return void 0;
|
|
4473
|
+
const referenced = [...statements, returnValue ?? ""].join("\n");
|
|
4474
|
+
const bindings = [
|
|
4475
|
+
"context",
|
|
4476
|
+
"event",
|
|
4477
|
+
"actions",
|
|
4478
|
+
"children",
|
|
4479
|
+
"self",
|
|
4480
|
+
"system"
|
|
4481
|
+
].filter((name) => new RegExp(`\\b${name}\\b`).test(referenced));
|
|
4482
|
+
return raw(`(${bindings.length ? `{ ${bindings.join(", ")} }` : "_"}, enq) => {\n${[...statements.map((statement) => ` ${formatV6Statement(statement)}`), ...returnValue ? [` return ${returnValue};`] : []].join("\n")}\n}`);
|
|
4483
|
+
}
|
|
4484
|
+
function formatV6Statement(statement) {
|
|
4485
|
+
return statement === "{" || statement === "}" || statement.endsWith(";") ? statement : `${statement};`;
|
|
4486
|
+
}
|
|
4487
|
+
function renderV6Effects(effects, finalContext) {
|
|
4488
|
+
if (!(finalContext !== void 0 || effects.some((effect) => effect.contextValue))) return { statements: effects.flatMap((effect) => effect.statements ?? []) };
|
|
4489
|
+
const statements = ["let nextContext = context"];
|
|
4490
|
+
const inCurrentContext = (statement) => {
|
|
4491
|
+
statements.push("{", " const context = nextContext", ` ${statement}`, "}");
|
|
4492
|
+
};
|
|
3936
4493
|
for (const effect of effects) {
|
|
3937
|
-
|
|
3938
|
-
contextValue = effect
|
|
4494
|
+
for (const statement of effect.statements ?? []) inCurrentContext(statement);
|
|
4495
|
+
if (effect.contextValue) inCurrentContext(`nextContext = { ...nextContext, ...(${effect.contextValue}) }`);
|
|
3939
4496
|
}
|
|
3940
|
-
if (
|
|
3941
|
-
|
|
3942
|
-
|
|
4497
|
+
if (finalContext !== void 0) inCurrentContext(`nextContext = { ...nextContext, ...(${finalContext}) }`);
|
|
4498
|
+
return {
|
|
4499
|
+
statements,
|
|
4500
|
+
contextValue: "nextContext"
|
|
4501
|
+
};
|
|
3943
4502
|
}
|
|
3944
4503
|
function unwrapTemplateExpressions(value) {
|
|
3945
4504
|
if (typeof value === "string") {
|
|
@@ -3987,6 +4546,8 @@ function inlineExpr(value) {
|
|
|
3987
4546
|
function actionToV6Effect(action) {
|
|
3988
4547
|
const expr = inlineExpr(action);
|
|
3989
4548
|
if (expr) {
|
|
4549
|
+
const assignment = getV6AssignmentContextValue(expr);
|
|
4550
|
+
if (assignment) return { contextValue: assignment };
|
|
3990
4551
|
if (expr.startsWith("enq(") || expr.startsWith("enq.")) return { statements: [expr] };
|
|
3991
4552
|
const builtIn = expr.match(/^(raise|emit|sendTo|cancel|log|spawnChild|stopChild)\(([\s\S]*)\)$/);
|
|
3992
4553
|
if (builtIn) {
|
|
@@ -4016,45 +4577,127 @@ function actionToV6Effect(action) {
|
|
|
4016
4577
|
return { statements: [`enq.spawn(${serializeJS(params.src)}${options})`] };
|
|
4017
4578
|
}
|
|
4018
4579
|
if (type === "xstate.stopChild") return { statements: [`enq.stop(${serializeJS(params.actorRef)})`] };
|
|
4019
|
-
if (type === "xstate.assign") {
|
|
4020
|
-
|
|
4021
|
-
return {
|
|
4022
|
-
contextValue,
|
|
4023
|
-
returnValue: `{ context: ${contextValue} }`
|
|
4024
|
-
};
|
|
4025
|
-
}
|
|
4580
|
+
if (type === "xstate.assign") return { contextValue: serializeJS(params.assignment ?? params) };
|
|
4581
|
+
if (!type.startsWith("xstate.")) return { statements: [`enq(${/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(type) ? `actions.${type}` : `actions[${serializeJS(type)}]`}${Object.keys(params).length > 0 ? `, ${serializeJS(params)}` : ""})`] };
|
|
4026
4582
|
return null;
|
|
4027
4583
|
}
|
|
4584
|
+
function getV6AssignmentArgs(code, includeAll = false) {
|
|
4585
|
+
const entries = [
|
|
4586
|
+
"context",
|
|
4587
|
+
"event",
|
|
4588
|
+
"self",
|
|
4589
|
+
"children",
|
|
4590
|
+
"system"
|
|
4591
|
+
].filter((name) => includeAll || new RegExp(`\\b${name}\\b`).test(code));
|
|
4592
|
+
if (includeAll || /\bspawn\b/.test(code)) entries.push("spawn: enq.spawn");
|
|
4593
|
+
return `{ ${entries.join(", ")} }`;
|
|
4594
|
+
}
|
|
4595
|
+
function getV6AssignmentContextValue(code) {
|
|
4596
|
+
const parsed = parseSingleExpression(code);
|
|
4597
|
+
const expression = parsed?.expression;
|
|
4598
|
+
if (!expression || !ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "assign" || expression.arguments.length !== 1) return;
|
|
4599
|
+
const [assignment] = expression.arguments;
|
|
4600
|
+
if (!assignment) return;
|
|
4601
|
+
if (ts.isArrowFunction(assignment) || ts.isFunctionExpression(assignment)) {
|
|
4602
|
+
const source = assignment.getText(parsed.source);
|
|
4603
|
+
return `(${source})(${getV6AssignmentArgs(source)})`;
|
|
4604
|
+
}
|
|
4605
|
+
if (!ts.isObjectLiteralExpression(assignment)) return getDynamicV6AssignmentContextValue(assignment.getText(parsed.source));
|
|
4606
|
+
const properties = [];
|
|
4607
|
+
for (const property of assignment.properties) {
|
|
4608
|
+
if (ts.isPropertyAssignment(property)) {
|
|
4609
|
+
const value = property.initializer;
|
|
4610
|
+
const source = value.getText(parsed.source);
|
|
4611
|
+
properties.push(`${property.name.getText(parsed.source)}: ${ts.isArrowFunction(value) || ts.isFunctionExpression(value) ? `(${source})(${getV6AssignmentArgs(source)})` : source}`);
|
|
4612
|
+
continue;
|
|
4613
|
+
}
|
|
4614
|
+
if (ts.isMethodDeclaration(property) && property.body) {
|
|
4615
|
+
const source = property.getText(parsed.source);
|
|
4616
|
+
const params = property.parameters.map((param) => param.getText(parsed.source)).join(", ");
|
|
4617
|
+
properties.push(`${property.name.getText(parsed.source)}: (function (${params}) ${property.body.getText(parsed.source)})(${getV6AssignmentArgs(source)})`);
|
|
4618
|
+
continue;
|
|
4619
|
+
}
|
|
4620
|
+
if (ts.isShorthandPropertyAssignment(property)) {
|
|
4621
|
+
properties.push(property.getText(parsed.source));
|
|
4622
|
+
continue;
|
|
4623
|
+
}
|
|
4624
|
+
return getDynamicV6AssignmentContextValue(assignment.getText(parsed.source));
|
|
4625
|
+
}
|
|
4626
|
+
return `{ ${properties.join(", ")} }`;
|
|
4627
|
+
}
|
|
4628
|
+
function getDynamicV6AssignmentContextValue(assignment) {
|
|
4629
|
+
const args = getV6AssignmentArgs(assignment, true);
|
|
4630
|
+
return `((assignment) => typeof assignment === 'function'
|
|
4631
|
+
? assignment(${args})
|
|
4632
|
+
: Object.fromEntries(Object.entries(assignment).map(([key, value]) => [
|
|
4633
|
+
key,
|
|
4634
|
+
typeof value === 'function' ? value(${args}) : value,
|
|
4635
|
+
])))(${assignment})`;
|
|
4636
|
+
}
|
|
4028
4637
|
function actionOptions(params, consumedKeys) {
|
|
4029
4638
|
const rest = Object.fromEntries(Object.entries(params).filter(([key, value]) => !consumedKeys.includes(key) && value !== void 0));
|
|
4030
4639
|
return Object.keys(rest).length ? `, ${serializeJS(rest)}` : "";
|
|
4031
4640
|
}
|
|
4032
|
-
function buildImports({ hasSetup, hasActors, actors, builtInActions, actorSourceImports, usesTypes }) {
|
|
4641
|
+
function buildImports({ hasSetup, hasActors, actors, builtInActions, actorSourceImports, implementationImports, usesTypes }) {
|
|
4033
4642
|
const xstateImports = [];
|
|
4034
4643
|
if (hasSetup) xstateImports.push("setup");
|
|
4035
4644
|
else xstateImports.push("createMachine");
|
|
4036
4645
|
for (const name of builtInActions) xstateImports.push(name);
|
|
4037
4646
|
for (const name of actorSourceImports) xstateImports.push(name);
|
|
4647
|
+
for (const name of implementationImports) xstateImports.push(name);
|
|
4038
4648
|
if (usesTypes) xstateImports.push("types");
|
|
4039
4649
|
if (hasActors) {
|
|
4040
4650
|
if (actors.length > 0) xstateImports.push("fromPromise");
|
|
4041
4651
|
}
|
|
4042
4652
|
return `import { ${[...new Set(xstateImports)].join(", ")} } from 'xstate';`;
|
|
4043
4653
|
}
|
|
4654
|
+
const XSTATE_ACTOR_LOGIC_HELPERS = new Set([
|
|
4655
|
+
"createMachine",
|
|
4656
|
+
"createAsyncLogic",
|
|
4657
|
+
"fromPromise",
|
|
4658
|
+
"fromCallback",
|
|
4659
|
+
"fromObservable",
|
|
4660
|
+
"fromEventObservable",
|
|
4661
|
+
"fromTransition"
|
|
4662
|
+
]);
|
|
4663
|
+
const XSTATE_IMPLEMENTATION_HELPERS = new Set([
|
|
4664
|
+
...Object.values(BUILTIN_ACTION_IMPORTS),
|
|
4665
|
+
"enqueueActions",
|
|
4666
|
+
"sendParent",
|
|
4667
|
+
"forwardTo",
|
|
4668
|
+
"stop",
|
|
4669
|
+
"and",
|
|
4670
|
+
"or",
|
|
4671
|
+
"not",
|
|
4672
|
+
"stateIn",
|
|
4673
|
+
...XSTATE_ACTOR_LOGIC_HELPERS
|
|
4674
|
+
]);
|
|
4675
|
+
function getImplementationImports(impls) {
|
|
4676
|
+
const imports = /* @__PURE__ */ new Set();
|
|
4677
|
+
if (!impls) return imports;
|
|
4678
|
+
for (const implementation of [
|
|
4679
|
+
...impls.actions,
|
|
4680
|
+
...impls.guards,
|
|
4681
|
+
...impls.actors,
|
|
4682
|
+
...impls.delays
|
|
4683
|
+
]) {
|
|
4684
|
+
const code = implementation.code?.body;
|
|
4685
|
+
if (!code) continue;
|
|
4686
|
+
const source = ts.createSourceFile("implementation.ts", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
4687
|
+
function visit(node) {
|
|
4688
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && XSTATE_IMPLEMENTATION_HELPERS.has(node.expression.text)) imports.add(node.expression.text);
|
|
4689
|
+
ts.forEachChild(node, visit);
|
|
4690
|
+
}
|
|
4691
|
+
visit(source);
|
|
4692
|
+
}
|
|
4693
|
+
return imports;
|
|
4694
|
+
}
|
|
4044
4695
|
function getActorSourceImports(graph) {
|
|
4045
4696
|
const imports = /* @__PURE__ */ new Set();
|
|
4046
|
-
const candidates = [
|
|
4047
|
-
"createAsyncLogic",
|
|
4048
|
-
"fromPromise",
|
|
4049
|
-
"fromCallback",
|
|
4050
|
-
"fromObservable",
|
|
4051
|
-
"fromEventObservable",
|
|
4052
|
-
"fromTransition"
|
|
4053
|
-
];
|
|
4054
4697
|
for (const node of graph.nodes) for (const invoke of node.data.invokes ?? []) {
|
|
4055
4698
|
const expression = invoke.srcExpression?.expr;
|
|
4056
4699
|
if (!expression) continue;
|
|
4057
|
-
for (const candidate of
|
|
4700
|
+
for (const candidate of XSTATE_ACTOR_LOGIC_HELPERS) if (new RegExp(`\\b${candidate}\\b`).test(expression)) imports.add(candidate);
|
|
4058
4701
|
}
|
|
4059
4702
|
return imports;
|
|
4060
4703
|
}
|
|
@@ -4141,11 +4784,27 @@ function buildGuardsBlock(guards, options) {
|
|
|
4141
4784
|
function buildActorsBlock(actors, options) {
|
|
4142
4785
|
const block = {};
|
|
4143
4786
|
for (const actor of actors) if (actor.code?.body) {
|
|
4787
|
+
const inlineExpression = getActorLogicExpression(actor.code.body);
|
|
4788
|
+
if (inlineExpression) {
|
|
4789
|
+
block[actor.name] = raw(inlineExpression);
|
|
4790
|
+
continue;
|
|
4791
|
+
}
|
|
4792
|
+
const functionExpression = stripExportDefault(actor.code.body);
|
|
4793
|
+
if (isCompleteFunctionExpression(functionExpression)) {
|
|
4794
|
+
block[actor.name] = raw(`fromPromise(${functionExpression})`);
|
|
4795
|
+
continue;
|
|
4796
|
+
}
|
|
4144
4797
|
const inputType = options.includeTypeSyntax && hasSchemaProperties(actor.inputSchema) ? `: ${jsonSchemaToTSType(actor.inputSchema)}` : "";
|
|
4145
4798
|
block[actor.name] = raw(`fromPromise(async ({ input }${inputType ? `: { input${inputType} }` : ""}) => {\n ${dedent(actor.code.body)}\n})`);
|
|
4146
4799
|
} else block[actor.name] = raw(`fromPromise(async ({ input }) => {\n // TODO: implement ${actor.name}\n})`);
|
|
4147
4800
|
return block;
|
|
4148
4801
|
}
|
|
4802
|
+
function getActorLogicExpression(code) {
|
|
4803
|
+
const parsed = parseSingleExpression(stripExportDefault(code));
|
|
4804
|
+
const expression = parsed?.expression;
|
|
4805
|
+
if (!parsed || !expression || !ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || !XSTATE_ACTOR_LOGIC_HELPERS.has(expression.expression.text)) return;
|
|
4806
|
+
return parsed.candidate;
|
|
4807
|
+
}
|
|
4149
4808
|
function buildDelaysBlock(delays) {
|
|
4150
4809
|
const block = {};
|
|
4151
4810
|
for (const delay of delays) if (delay.code?.body) {
|
|
@@ -4154,6 +4813,11 @@ function buildDelaysBlock(delays) {
|
|
|
4154
4813
|
block[delay.name] = raw(inlineExpression);
|
|
4155
4814
|
continue;
|
|
4156
4815
|
}
|
|
4816
|
+
const constantExpression = getConstantImplementationExpression(delay.code.body);
|
|
4817
|
+
if (constantExpression) {
|
|
4818
|
+
block[delay.name] = raw(constantExpression);
|
|
4819
|
+
continue;
|
|
4820
|
+
}
|
|
4157
4821
|
block[delay.name] = raw(`function ({ context, event }) {\n ${dedent(delay.code.body)}\n}`);
|
|
4158
4822
|
} else block[delay.name] = raw(`function () {\n // TODO: implement ${delay.name}\n return 1000;\n}`);
|
|
4159
4823
|
return block;
|
|
@@ -4170,17 +4834,37 @@ function buildDelaysBlock(delays) {
|
|
|
4170
4834
|
function getInlineExpression(code) {
|
|
4171
4835
|
const stripped = stripExportDefault(code);
|
|
4172
4836
|
if (stripped !== code.trim()) return stripped;
|
|
4173
|
-
return isCompleteFunctionExpression(stripped) ? stripped : void 0;
|
|
4837
|
+
return isCompleteFunctionExpression(stripped) || isCompleteXStateHelperExpression(stripped) ? stripped : void 0;
|
|
4174
4838
|
}
|
|
4175
|
-
|
|
4176
|
-
function isCompleteFunctionExpression(code) {
|
|
4839
|
+
function parseSingleExpression(code) {
|
|
4177
4840
|
const candidate = code.trim().replace(/;$/, "");
|
|
4178
|
-
const source = ts.createSourceFile("
|
|
4179
|
-
if ((source.parseDiagnostics ?? []).length > 0 || source.statements.length !== 1) return
|
|
4841
|
+
const source = ts.createSourceFile("implementation.ts", `(${candidate})`, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
4842
|
+
if ((source.parseDiagnostics ?? []).length > 0 || source.statements.length !== 1) return;
|
|
4180
4843
|
const [statement] = source.statements;
|
|
4181
|
-
if (!statement || !ts.isExpressionStatement(statement)) return
|
|
4844
|
+
if (!statement || !ts.isExpressionStatement(statement)) return;
|
|
4182
4845
|
let expression = statement.expression;
|
|
4183
4846
|
if (ts.isParenthesizedExpression(expression)) expression = expression.expression;
|
|
4847
|
+
return {
|
|
4848
|
+
candidate,
|
|
4849
|
+
expression,
|
|
4850
|
+
source
|
|
4851
|
+
};
|
|
4852
|
+
}
|
|
4853
|
+
function getConstantImplementationExpression(code) {
|
|
4854
|
+
const parsed = parseSingleExpression(code);
|
|
4855
|
+
if (!parsed) return;
|
|
4856
|
+
const { candidate, expression } = parsed;
|
|
4857
|
+
if (ts.isStringLiteral(expression) || ts.isNumericLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression) || expression.kind === ts.SyntaxKind.TrueKeyword || expression.kind === ts.SyntaxKind.FalseKeyword || expression.kind === ts.SyntaxKind.NullKeyword || ts.isPrefixUnaryExpression(expression) && ts.isNumericLiteral(expression.operand)) return candidate;
|
|
4858
|
+
}
|
|
4859
|
+
function isCompleteXStateHelperExpression(code) {
|
|
4860
|
+
const expression = parseSingleExpression(code)?.expression;
|
|
4861
|
+
if (!expression) return false;
|
|
4862
|
+
return ts.isCallExpression(expression) && ts.isIdentifier(expression.expression) && XSTATE_IMPLEMENTATION_HELPERS.has(expression.expression.text);
|
|
4863
|
+
}
|
|
4864
|
+
/** True when `code` is a single function or arrow-function expression. */
|
|
4865
|
+
function isCompleteFunctionExpression(code) {
|
|
4866
|
+
const expression = parseSingleExpression(code)?.expression;
|
|
4867
|
+
if (!expression) return false;
|
|
4184
4868
|
return ts.isFunctionExpression(expression) || ts.isArrowFunction(expression);
|
|
4185
4869
|
}
|
|
4186
4870
|
const colorSchema = _enum([
|
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as createStatelyClient } from "./studio-DHGspwII.mjs";
|
|
2
|
-
import { f as normalizeMachineProfile, h as xstateSourceToConfig, i as INLINE_EXPRESSION_DIRECTIVE_FIELDS, m as serializeJS, n as getStatelyPragma, r as upsertStatelyPragma, s as detectXStateSourceProfile, t as findStatelyPragmaAttachments, u as graphToXStateTS } from "./statelyPragma-
|
|
2
|
+
import { f as normalizeMachineProfile, h as xstateSourceToConfig, i as INLINE_EXPRESSION_DIRECTIVE_FIELDS, m as serializeJS, n as getStatelyPragma, r as upsertStatelyPragma, s as detectXStateSourceProfile, t as findStatelyPragmaAttachments, u as graphToXStateTS } from "./statelyPragma-Cesya0Pk.mjs";
|
|
3
3
|
import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
|
|
4
4
|
import * as ts$1 from "typescript";
|
|
5
5
|
import ts from "typescript";
|
|
@@ -328,7 +328,7 @@ function createWebSocketTransport(options) {
|
|
|
328
328
|
|
|
329
329
|
//#endregion
|
|
330
330
|
//#region src/version.ts
|
|
331
|
-
const SDK_VERSION = "0.20.
|
|
331
|
+
const SDK_VERSION = "0.20.3";
|
|
332
332
|
function inspectionRuntime() {
|
|
333
333
|
if (typeof window !== "undefined") return "browser";
|
|
334
334
|
if (typeof process !== "undefined" && process.versions?.node) return "node";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/sdk",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bin": {
|
|
6
6
|
"stately-sdk": "./dist/bin.mjs"
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"jsdom": "^27.4.0",
|
|
94
94
|
"tsdown": "0.21.0-beta.2",
|
|
95
95
|
"vitest": "^3.2.4",
|
|
96
|
-
"@statelyai/api-contract": "0.3.
|
|
97
|
-
"@statelyai/graph-tools": "0.1.
|
|
96
|
+
"@statelyai/api-contract": "0.3.4",
|
|
97
|
+
"@statelyai/graph-tools": "0.1.1"
|
|
98
98
|
},
|
|
99
99
|
"engines": {
|
|
100
100
|
"node": ">=22.4"
|