@momoyu-ink/kit 0.7.1 → 0.8.0
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/{jsx-dev-runtime-CKclO27C.d.mts → jsx-dev-runtime-BCxm528Z.d.mts} +4 -0
- package/dist/{jsx-dev-runtime-CKclO27C.d.ts → jsx-dev-runtime-BCxm528Z.d.ts} +4 -0
- package/dist/jsx-dev-runtime.d.mts +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/jsx-runtime.d.mts +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/lib.cjs +120 -10
- package/dist/lib.d.mts +42 -2
- package/dist/lib.d.ts +42 -2
- package/dist/lib.mjs +120 -10
- package/package.json +1 -1
|
@@ -134,6 +134,10 @@ type JsonValue = number | string | boolean | Array<JsonValue> | {
|
|
|
134
134
|
type ScenarioCommand = {
|
|
135
135
|
subCommand: 'addStory';
|
|
136
136
|
name: string;
|
|
137
|
+
} | {
|
|
138
|
+
subCommand: 'replaceStoryData';
|
|
139
|
+
name: string;
|
|
140
|
+
content: string;
|
|
137
141
|
} | {
|
|
138
142
|
subCommand: 'removeStory';
|
|
139
143
|
name: string;
|
|
@@ -134,6 +134,10 @@ type JsonValue = number | string | boolean | Array<JsonValue> | {
|
|
|
134
134
|
type ScenarioCommand = {
|
|
135
135
|
subCommand: 'addStory';
|
|
136
136
|
name: string;
|
|
137
|
+
} | {
|
|
138
|
+
subCommand: 'replaceStoryData';
|
|
139
|
+
name: string;
|
|
140
|
+
content: string;
|
|
137
141
|
} | {
|
|
138
142
|
subCommand: 'removeStory';
|
|
139
143
|
name: string;
|
package/dist/jsx-runtime.d.mts
CHANGED
package/dist/jsx-runtime.d.ts
CHANGED
package/dist/lib.cjs
CHANGED
|
@@ -1222,6 +1222,36 @@ async function clearLocalDebugSessionRuntimeState() {
|
|
|
1222
1222
|
async function clearRemoteCheckpoints() {
|
|
1223
1223
|
await executeScenarioCommand({ subCommand: "clearCheckpoints" });
|
|
1224
1224
|
}
|
|
1225
|
+
function pruneLocalStoryCheckpoints(story, preserved) {
|
|
1226
|
+
debugState.checkpoints = Object.fromEntries(
|
|
1227
|
+
Object.entries(debugState.checkpoints).filter(([key, checkpoint]) => {
|
|
1228
|
+
if (checkpoint.cursor.story !== story) {
|
|
1229
|
+
return true;
|
|
1230
|
+
}
|
|
1231
|
+
return preserved.has(key);
|
|
1232
|
+
})
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
async function syncCurrentExecutionCursor(fallbackStory = null) {
|
|
1236
|
+
debugState.currentCursor = await executeScenarioCommand({
|
|
1237
|
+
subCommand: "getExecutionCursor"
|
|
1238
|
+
});
|
|
1239
|
+
debugState.currentStory = debugState.currentCursor?.story ?? fallbackStory;
|
|
1240
|
+
}
|
|
1241
|
+
async function executeRestartBoundary(boundary, story) {
|
|
1242
|
+
if (boundary.kind === "checkpoint") {
|
|
1243
|
+
await debugSessionController.restoreCheckpoint(boundary.checkpointKey, { story });
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
if (!appStateAdapter?.restartStoryFromHead) {
|
|
1247
|
+
throw new Error("Restarting a story from an explicit entry is not supported by the app state adapter");
|
|
1248
|
+
}
|
|
1249
|
+
await appStateAdapter.restartStoryFromHead({
|
|
1250
|
+
story: boundary.story,
|
|
1251
|
+
entry: boundary.kind === "restart-story" ? boundary.entry : boundary.paragraph
|
|
1252
|
+
});
|
|
1253
|
+
await syncCurrentExecutionCursor(boundary.story);
|
|
1254
|
+
}
|
|
1225
1255
|
async function syncLocalWarpCheckpoint(targetMarkerId) {
|
|
1226
1256
|
const cursor = await executeScenarioCommand({
|
|
1227
1257
|
subCommand: "getExecutionCursor"
|
|
@@ -1281,15 +1311,17 @@ async function prepareJumpStart(markerId, options) {
|
|
|
1281
1311
|
subCommand: "restoreCheckpoint",
|
|
1282
1312
|
key: markerId
|
|
1283
1313
|
});
|
|
1284
|
-
if (
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1314
|
+
if (restored2) {
|
|
1315
|
+
if (appStateAdapter) {
|
|
1316
|
+
await appStateAdapter.restore(checkpoint.appState);
|
|
1317
|
+
}
|
|
1318
|
+
debugState.currentCursor = checkpoint.cursor;
|
|
1319
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
1320
|
+
return false;
|
|
1289
1321
|
}
|
|
1290
|
-
debugState.
|
|
1291
|
-
|
|
1292
|
-
|
|
1322
|
+
debugState.checkpoints = Object.fromEntries(
|
|
1323
|
+
Object.entries(debugState.checkpoints).filter(([key]) => key !== markerId)
|
|
1324
|
+
);
|
|
1293
1325
|
}
|
|
1294
1326
|
const lookup = await executeScenarioCommand({
|
|
1295
1327
|
subCommand: "getFastForwardCheckpoint",
|
|
@@ -1309,7 +1341,8 @@ async function prepareJumpStart(markerId, options) {
|
|
|
1309
1341
|
}
|
|
1310
1342
|
const startCheckpoint = debugState.checkpoints[startCheckpointKey];
|
|
1311
1343
|
if (!startCheckpoint) {
|
|
1312
|
-
|
|
1344
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
1345
|
+
return true;
|
|
1313
1346
|
}
|
|
1314
1347
|
const restored = await executeScenarioCommand({
|
|
1315
1348
|
subCommand: "restoreCheckpoint",
|
|
@@ -1452,6 +1485,46 @@ var debugSessionController = {
|
|
|
1452
1485
|
throw error;
|
|
1453
1486
|
}
|
|
1454
1487
|
});
|
|
1488
|
+
},
|
|
1489
|
+
async replaceStory(options) {
|
|
1490
|
+
debugState.restoring = true;
|
|
1491
|
+
debugState.lastError = null;
|
|
1492
|
+
try {
|
|
1493
|
+
const outcome = await enqueueDebugOperation(
|
|
1494
|
+
async () => executeScenarioCommand({
|
|
1495
|
+
subCommand: "replaceStoryData",
|
|
1496
|
+
name: options.story,
|
|
1497
|
+
content: options.content
|
|
1498
|
+
})
|
|
1499
|
+
);
|
|
1500
|
+
if (outcome.plan.mode === "invalidate-only") {
|
|
1501
|
+
pruneLocalStoryCheckpoints(options.story, /* @__PURE__ */ new Set());
|
|
1502
|
+
}
|
|
1503
|
+
if (outcome.plan.mode === "reposition") {
|
|
1504
|
+
if (!outcome.plan.boundary) {
|
|
1505
|
+
throw new Error("Story replace outcome is missing an executable boundary");
|
|
1506
|
+
}
|
|
1507
|
+
const seekMode = options.seekMode ?? "warp";
|
|
1508
|
+
const replaceTargetMarkerId = options.targetMarkerId ?? outcome.plan.targetMarkerId;
|
|
1509
|
+
await executeRestartBoundary(outcome.plan.boundary, options.story);
|
|
1510
|
+
if (replaceTargetMarkerId && !(outcome.plan.boundary.kind === "checkpoint" && outcome.plan.boundary.checkpointKey === replaceTargetMarkerId)) {
|
|
1511
|
+
if (seekMode === "warp") {
|
|
1512
|
+
await runWarp({
|
|
1513
|
+
markerId: replaceTargetMarkerId,
|
|
1514
|
+
boundary: "after"
|
|
1515
|
+
});
|
|
1516
|
+
} else if (seekMode === "fast-forward") {
|
|
1517
|
+
await runFastForwardToMarker(replaceTargetMarkerId);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
return outcome;
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
debugState.lastError = toErrorMessage(error);
|
|
1524
|
+
throw error;
|
|
1525
|
+
} finally {
|
|
1526
|
+
debugState.restoring = false;
|
|
1527
|
+
}
|
|
1455
1528
|
}
|
|
1456
1529
|
};
|
|
1457
1530
|
function registerAppStateAdapter(adapter) {
|
|
@@ -1556,7 +1629,8 @@ function useDebugSession() {
|
|
|
1556
1629
|
stopDebugSession,
|
|
1557
1630
|
restoreCheckpoint: debugSessionController.restoreCheckpoint,
|
|
1558
1631
|
warp: debugSessionController.warp,
|
|
1559
|
-
switchRoute: debugSessionController.switchRoute
|
|
1632
|
+
switchRoute: debugSessionController.switchRoute,
|
|
1633
|
+
replaceStory: debugSessionController.replaceStory
|
|
1560
1634
|
};
|
|
1561
1635
|
}
|
|
1562
1636
|
|
|
@@ -1646,6 +1720,9 @@ function isJumpRequestMessage(message) {
|
|
|
1646
1720
|
function isRouteRequestMessage(message) {
|
|
1647
1721
|
return message.type === "route:request" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.page === "string" && (message.params === void 0 || typeof message.params === "object" && message.params !== null && !Array.isArray(message.params));
|
|
1648
1722
|
}
|
|
1723
|
+
function isStoryReplaceMessage(message) {
|
|
1724
|
+
return message.type === "story:replace" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.story === "string" && typeof message.content === "string" && (message.seekMode === void 0 || message.seekMode === "off" || message.seekMode === "fast-forward" || message.seekMode === "warp") && (message.targetMarkerId === void 0 || typeof message.targetMarkerId === "string");
|
|
1725
|
+
}
|
|
1649
1726
|
function isUiReplaceMessage(message) {
|
|
1650
1727
|
return message.type === "ui:replace" && typeof message.sessionId === "string";
|
|
1651
1728
|
}
|
|
@@ -1732,6 +1809,35 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1732
1809
|
});
|
|
1733
1810
|
return;
|
|
1734
1811
|
}
|
|
1812
|
+
if (isStoryReplaceMessage(message)) {
|
|
1813
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1814
|
+
void controller.replaceStory({
|
|
1815
|
+
story: message.story,
|
|
1816
|
+
content: message.content,
|
|
1817
|
+
seekMode: message.seekMode,
|
|
1818
|
+
targetMarkerId: message.targetMarkerId
|
|
1819
|
+
}).then(async () => {
|
|
1820
|
+
sendRuntimeDebugMessage(socket, {
|
|
1821
|
+
type: "story:replace:done",
|
|
1822
|
+
sessionId,
|
|
1823
|
+
requestId: message.requestId,
|
|
1824
|
+
story: message.story
|
|
1825
|
+
});
|
|
1826
|
+
await syncRuntimeDebugVariablesSnapshotSafe("story-replace-done");
|
|
1827
|
+
}).catch(async (error) => {
|
|
1828
|
+
sendRuntimeDebugMessage(socket, {
|
|
1829
|
+
type: "story:replace:error",
|
|
1830
|
+
sessionId,
|
|
1831
|
+
requestId: message.requestId,
|
|
1832
|
+
story: message.story,
|
|
1833
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1834
|
+
});
|
|
1835
|
+
await syncRuntimeDebugVariablesSnapshotSafe("story-replace-error");
|
|
1836
|
+
}).finally(() => {
|
|
1837
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1838
|
+
});
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1735
1841
|
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1736
1842
|
void controller.switchRoute(message.page, message.params).then(async () => {
|
|
1737
1843
|
sendRuntimeDebugMessage(socket, {
|
|
@@ -1869,6 +1975,10 @@ async function startRuntimeDebugSession() {
|
|
|
1869
1975
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1870
1976
|
return;
|
|
1871
1977
|
}
|
|
1978
|
+
if (isStoryReplaceMessage(message)) {
|
|
1979
|
+
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1872
1982
|
if (isUiReplaceMessage(message)) {
|
|
1873
1983
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1874
1984
|
return;
|
package/dist/lib.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactElement, Component, ForwardRefExoticComponent, CSSProperties, FC, ComponentType } from 'react';
|
|
3
|
-
import { M as MouseEvent, a as MoyuEvent, C as Command, b as MaybePromise, J as JSX, c as JsonValue } from './jsx-dev-runtime-
|
|
4
|
-
export { A as AudioCommand, d as AudioSettings, B as BubbleEvent, D as DetailedMoyuProps, E as EffectParams, G as GamepadCommand, K as KeyboardEvent, e as KeyboardEventKind, f as MakeNullOptional, g as MouseEventKind, h as MoyuAnimationAttributes, i as MoyuBackdropAttributes, j as MoyuClipAttributes, k as MoyuContainerAttributes, l as MoyuEventHandler, m as MoyuFilterAttributes, n as MoyuListenerAttributes, o as MoyuNodeAttributes, p as MoyuSpriteAttributes, q as MoyuTextAttributes, r as MoyuVideoAttributes, N as Node, S as ScenarioCommand, s as SystemCommand, T as TextCommand, t as TouchEvent, u as TouchEventKind, v as Tuple2, w as Tuple3, x as Tuple4, W as WindowState, y as createBubbleEvent, z as getStageSize } from './jsx-dev-runtime-
|
|
3
|
+
import { M as MouseEvent, a as MoyuEvent, C as Command, b as MaybePromise, J as JSX, c as JsonValue } from './jsx-dev-runtime-BCxm528Z.mjs';
|
|
4
|
+
export { A as AudioCommand, d as AudioSettings, B as BubbleEvent, D as DetailedMoyuProps, E as EffectParams, G as GamepadCommand, K as KeyboardEvent, e as KeyboardEventKind, f as MakeNullOptional, g as MouseEventKind, h as MoyuAnimationAttributes, i as MoyuBackdropAttributes, j as MoyuClipAttributes, k as MoyuContainerAttributes, l as MoyuEventHandler, m as MoyuFilterAttributes, n as MoyuListenerAttributes, o as MoyuNodeAttributes, p as MoyuSpriteAttributes, q as MoyuTextAttributes, r as MoyuVideoAttributes, N as Node, S as ScenarioCommand, s as SystemCommand, T as TextCommand, t as TouchEvent, u as TouchEventKind, v as Tuple2, w as Tuple3, x as Tuple4, W as WindowState, y as createBubbleEvent, z as getStageSize } from './jsx-dev-runtime-BCxm528Z.mjs';
|
|
5
5
|
import { FluidValue } from '@react-spring/shared';
|
|
6
6
|
import { ElementType, AssignableKeys, ComponentPropsWithRef } from '@react-spring/types';
|
|
7
7
|
import { Snapshot } from 'valtio';
|
|
@@ -522,6 +522,34 @@ type ExecutionCursor = {
|
|
|
522
522
|
markerId?: string;
|
|
523
523
|
};
|
|
524
524
|
|
|
525
|
+
type ExecutableRestartBoundary = {
|
|
526
|
+
kind: 'checkpoint';
|
|
527
|
+
checkpointKey: string;
|
|
528
|
+
} | {
|
|
529
|
+
kind: 'restart-story';
|
|
530
|
+
story: string;
|
|
531
|
+
entry: string;
|
|
532
|
+
} | {
|
|
533
|
+
kind: 'restart-paragraph';
|
|
534
|
+
story: string;
|
|
535
|
+
paragraph: string;
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
type StoryReplaceMode = 'noop' | 'reposition' | 'invalidate-only';
|
|
539
|
+
|
|
540
|
+
type StoryReplaceExecutionPlan = {
|
|
541
|
+
mode: StoryReplaceMode;
|
|
542
|
+
boundary?: ExecutableRestartBoundary;
|
|
543
|
+
targetMarkerId?: string;
|
|
544
|
+
changedControlFlow: boolean;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
type StoryReplaceOutcome = {
|
|
548
|
+
story: string;
|
|
549
|
+
currentStoryAffected: boolean;
|
|
550
|
+
plan: StoryReplaceExecutionPlan;
|
|
551
|
+
};
|
|
552
|
+
|
|
525
553
|
/** Flow control interface passed to every handler. */
|
|
526
554
|
interface GameControl {
|
|
527
555
|
/** Timed wait — blocks auto-advance. Engine fires scenariowaitingcancelled on timeout or skip. */
|
|
@@ -695,6 +723,12 @@ interface DebugSessionController {
|
|
|
695
723
|
restoreCheckpoint(markerId: string, options?: DebugJumpTargetOptions): Promise<boolean>;
|
|
696
724
|
warp(options: DebugWarpOptions): Promise<void>;
|
|
697
725
|
switchRoute(routeName: string, params?: Record<string, unknown>): Promise<void>;
|
|
726
|
+
replaceStory(options: {
|
|
727
|
+
story: string;
|
|
728
|
+
content: string;
|
|
729
|
+
seekMode?: 'off' | 'fast-forward' | 'warp';
|
|
730
|
+
targetMarkerId?: string;
|
|
731
|
+
}): Promise<StoryReplaceOutcome>;
|
|
698
732
|
}
|
|
699
733
|
interface DebugStoryStartOptions {
|
|
700
734
|
story: string;
|
|
@@ -718,6 +752,12 @@ declare function useDebugSession(): {
|
|
|
718
752
|
restoreCheckpoint: (markerId: string, options?: DebugJumpTargetOptions) => Promise<boolean>;
|
|
719
753
|
warp: (options: DebugWarpOptions) => Promise<void>;
|
|
720
754
|
switchRoute: (routeName: string, params?: Record<string, unknown>) => Promise<void>;
|
|
755
|
+
replaceStory: (options: {
|
|
756
|
+
story: string;
|
|
757
|
+
content: string;
|
|
758
|
+
seekMode?: "off" | "fast-forward" | "warp";
|
|
759
|
+
targetMarkerId?: string;
|
|
760
|
+
}) => Promise<StoryReplaceOutcome>;
|
|
721
761
|
active: boolean;
|
|
722
762
|
checkpoints: {
|
|
723
763
|
readonly [x: string]: {
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactElement, Component, ForwardRefExoticComponent, CSSProperties, FC, ComponentType } from 'react';
|
|
3
|
-
import { M as MouseEvent, a as MoyuEvent, C as Command, b as MaybePromise, J as JSX, c as JsonValue } from './jsx-dev-runtime-
|
|
4
|
-
export { A as AudioCommand, d as AudioSettings, B as BubbleEvent, D as DetailedMoyuProps, E as EffectParams, G as GamepadCommand, K as KeyboardEvent, e as KeyboardEventKind, f as MakeNullOptional, g as MouseEventKind, h as MoyuAnimationAttributes, i as MoyuBackdropAttributes, j as MoyuClipAttributes, k as MoyuContainerAttributes, l as MoyuEventHandler, m as MoyuFilterAttributes, n as MoyuListenerAttributes, o as MoyuNodeAttributes, p as MoyuSpriteAttributes, q as MoyuTextAttributes, r as MoyuVideoAttributes, N as Node, S as ScenarioCommand, s as SystemCommand, T as TextCommand, t as TouchEvent, u as TouchEventKind, v as Tuple2, w as Tuple3, x as Tuple4, W as WindowState, y as createBubbleEvent, z as getStageSize } from './jsx-dev-runtime-
|
|
3
|
+
import { M as MouseEvent, a as MoyuEvent, C as Command, b as MaybePromise, J as JSX, c as JsonValue } from './jsx-dev-runtime-BCxm528Z.js';
|
|
4
|
+
export { A as AudioCommand, d as AudioSettings, B as BubbleEvent, D as DetailedMoyuProps, E as EffectParams, G as GamepadCommand, K as KeyboardEvent, e as KeyboardEventKind, f as MakeNullOptional, g as MouseEventKind, h as MoyuAnimationAttributes, i as MoyuBackdropAttributes, j as MoyuClipAttributes, k as MoyuContainerAttributes, l as MoyuEventHandler, m as MoyuFilterAttributes, n as MoyuListenerAttributes, o as MoyuNodeAttributes, p as MoyuSpriteAttributes, q as MoyuTextAttributes, r as MoyuVideoAttributes, N as Node, S as ScenarioCommand, s as SystemCommand, T as TextCommand, t as TouchEvent, u as TouchEventKind, v as Tuple2, w as Tuple3, x as Tuple4, W as WindowState, y as createBubbleEvent, z as getStageSize } from './jsx-dev-runtime-BCxm528Z.js';
|
|
5
5
|
import { FluidValue } from '@react-spring/shared';
|
|
6
6
|
import { ElementType, AssignableKeys, ComponentPropsWithRef } from '@react-spring/types';
|
|
7
7
|
import { Snapshot } from 'valtio';
|
|
@@ -522,6 +522,34 @@ type ExecutionCursor = {
|
|
|
522
522
|
markerId?: string;
|
|
523
523
|
};
|
|
524
524
|
|
|
525
|
+
type ExecutableRestartBoundary = {
|
|
526
|
+
kind: 'checkpoint';
|
|
527
|
+
checkpointKey: string;
|
|
528
|
+
} | {
|
|
529
|
+
kind: 'restart-story';
|
|
530
|
+
story: string;
|
|
531
|
+
entry: string;
|
|
532
|
+
} | {
|
|
533
|
+
kind: 'restart-paragraph';
|
|
534
|
+
story: string;
|
|
535
|
+
paragraph: string;
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
type StoryReplaceMode = 'noop' | 'reposition' | 'invalidate-only';
|
|
539
|
+
|
|
540
|
+
type StoryReplaceExecutionPlan = {
|
|
541
|
+
mode: StoryReplaceMode;
|
|
542
|
+
boundary?: ExecutableRestartBoundary;
|
|
543
|
+
targetMarkerId?: string;
|
|
544
|
+
changedControlFlow: boolean;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
type StoryReplaceOutcome = {
|
|
548
|
+
story: string;
|
|
549
|
+
currentStoryAffected: boolean;
|
|
550
|
+
plan: StoryReplaceExecutionPlan;
|
|
551
|
+
};
|
|
552
|
+
|
|
525
553
|
/** Flow control interface passed to every handler. */
|
|
526
554
|
interface GameControl {
|
|
527
555
|
/** Timed wait — blocks auto-advance. Engine fires scenariowaitingcancelled on timeout or skip. */
|
|
@@ -695,6 +723,12 @@ interface DebugSessionController {
|
|
|
695
723
|
restoreCheckpoint(markerId: string, options?: DebugJumpTargetOptions): Promise<boolean>;
|
|
696
724
|
warp(options: DebugWarpOptions): Promise<void>;
|
|
697
725
|
switchRoute(routeName: string, params?: Record<string, unknown>): Promise<void>;
|
|
726
|
+
replaceStory(options: {
|
|
727
|
+
story: string;
|
|
728
|
+
content: string;
|
|
729
|
+
seekMode?: 'off' | 'fast-forward' | 'warp';
|
|
730
|
+
targetMarkerId?: string;
|
|
731
|
+
}): Promise<StoryReplaceOutcome>;
|
|
698
732
|
}
|
|
699
733
|
interface DebugStoryStartOptions {
|
|
700
734
|
story: string;
|
|
@@ -718,6 +752,12 @@ declare function useDebugSession(): {
|
|
|
718
752
|
restoreCheckpoint: (markerId: string, options?: DebugJumpTargetOptions) => Promise<boolean>;
|
|
719
753
|
warp: (options: DebugWarpOptions) => Promise<void>;
|
|
720
754
|
switchRoute: (routeName: string, params?: Record<string, unknown>) => Promise<void>;
|
|
755
|
+
replaceStory: (options: {
|
|
756
|
+
story: string;
|
|
757
|
+
content: string;
|
|
758
|
+
seekMode?: "off" | "fast-forward" | "warp";
|
|
759
|
+
targetMarkerId?: string;
|
|
760
|
+
}) => Promise<StoryReplaceOutcome>;
|
|
721
761
|
active: boolean;
|
|
722
762
|
checkpoints: {
|
|
723
763
|
readonly [x: string]: {
|
package/dist/lib.mjs
CHANGED
|
@@ -1210,6 +1210,36 @@ async function clearLocalDebugSessionRuntimeState() {
|
|
|
1210
1210
|
async function clearRemoteCheckpoints() {
|
|
1211
1211
|
await executeScenarioCommand({ subCommand: "clearCheckpoints" });
|
|
1212
1212
|
}
|
|
1213
|
+
function pruneLocalStoryCheckpoints(story, preserved) {
|
|
1214
|
+
debugState.checkpoints = Object.fromEntries(
|
|
1215
|
+
Object.entries(debugState.checkpoints).filter(([key, checkpoint]) => {
|
|
1216
|
+
if (checkpoint.cursor.story !== story) {
|
|
1217
|
+
return true;
|
|
1218
|
+
}
|
|
1219
|
+
return preserved.has(key);
|
|
1220
|
+
})
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
async function syncCurrentExecutionCursor(fallbackStory = null) {
|
|
1224
|
+
debugState.currentCursor = await executeScenarioCommand({
|
|
1225
|
+
subCommand: "getExecutionCursor"
|
|
1226
|
+
});
|
|
1227
|
+
debugState.currentStory = debugState.currentCursor?.story ?? fallbackStory;
|
|
1228
|
+
}
|
|
1229
|
+
async function executeRestartBoundary(boundary, story) {
|
|
1230
|
+
if (boundary.kind === "checkpoint") {
|
|
1231
|
+
await debugSessionController.restoreCheckpoint(boundary.checkpointKey, { story });
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (!appStateAdapter?.restartStoryFromHead) {
|
|
1235
|
+
throw new Error("Restarting a story from an explicit entry is not supported by the app state adapter");
|
|
1236
|
+
}
|
|
1237
|
+
await appStateAdapter.restartStoryFromHead({
|
|
1238
|
+
story: boundary.story,
|
|
1239
|
+
entry: boundary.kind === "restart-story" ? boundary.entry : boundary.paragraph
|
|
1240
|
+
});
|
|
1241
|
+
await syncCurrentExecutionCursor(boundary.story);
|
|
1242
|
+
}
|
|
1213
1243
|
async function syncLocalWarpCheckpoint(targetMarkerId) {
|
|
1214
1244
|
const cursor = await executeScenarioCommand({
|
|
1215
1245
|
subCommand: "getExecutionCursor"
|
|
@@ -1269,15 +1299,17 @@ async function prepareJumpStart(markerId, options) {
|
|
|
1269
1299
|
subCommand: "restoreCheckpoint",
|
|
1270
1300
|
key: markerId
|
|
1271
1301
|
});
|
|
1272
|
-
if (
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1302
|
+
if (restored2) {
|
|
1303
|
+
if (appStateAdapter) {
|
|
1304
|
+
await appStateAdapter.restore(checkpoint.appState);
|
|
1305
|
+
}
|
|
1306
|
+
debugState.currentCursor = checkpoint.cursor;
|
|
1307
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
1308
|
+
return false;
|
|
1277
1309
|
}
|
|
1278
|
-
debugState.
|
|
1279
|
-
|
|
1280
|
-
|
|
1310
|
+
debugState.checkpoints = Object.fromEntries(
|
|
1311
|
+
Object.entries(debugState.checkpoints).filter(([key]) => key !== markerId)
|
|
1312
|
+
);
|
|
1281
1313
|
}
|
|
1282
1314
|
const lookup = await executeScenarioCommand({
|
|
1283
1315
|
subCommand: "getFastForwardCheckpoint",
|
|
@@ -1297,7 +1329,8 @@ async function prepareJumpStart(markerId, options) {
|
|
|
1297
1329
|
}
|
|
1298
1330
|
const startCheckpoint = debugState.checkpoints[startCheckpointKey];
|
|
1299
1331
|
if (!startCheckpoint) {
|
|
1300
|
-
|
|
1332
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
1333
|
+
return true;
|
|
1301
1334
|
}
|
|
1302
1335
|
const restored = await executeScenarioCommand({
|
|
1303
1336
|
subCommand: "restoreCheckpoint",
|
|
@@ -1440,6 +1473,46 @@ var debugSessionController = {
|
|
|
1440
1473
|
throw error;
|
|
1441
1474
|
}
|
|
1442
1475
|
});
|
|
1476
|
+
},
|
|
1477
|
+
async replaceStory(options) {
|
|
1478
|
+
debugState.restoring = true;
|
|
1479
|
+
debugState.lastError = null;
|
|
1480
|
+
try {
|
|
1481
|
+
const outcome = await enqueueDebugOperation(
|
|
1482
|
+
async () => executeScenarioCommand({
|
|
1483
|
+
subCommand: "replaceStoryData",
|
|
1484
|
+
name: options.story,
|
|
1485
|
+
content: options.content
|
|
1486
|
+
})
|
|
1487
|
+
);
|
|
1488
|
+
if (outcome.plan.mode === "invalidate-only") {
|
|
1489
|
+
pruneLocalStoryCheckpoints(options.story, /* @__PURE__ */ new Set());
|
|
1490
|
+
}
|
|
1491
|
+
if (outcome.plan.mode === "reposition") {
|
|
1492
|
+
if (!outcome.plan.boundary) {
|
|
1493
|
+
throw new Error("Story replace outcome is missing an executable boundary");
|
|
1494
|
+
}
|
|
1495
|
+
const seekMode = options.seekMode ?? "warp";
|
|
1496
|
+
const replaceTargetMarkerId = options.targetMarkerId ?? outcome.plan.targetMarkerId;
|
|
1497
|
+
await executeRestartBoundary(outcome.plan.boundary, options.story);
|
|
1498
|
+
if (replaceTargetMarkerId && !(outcome.plan.boundary.kind === "checkpoint" && outcome.plan.boundary.checkpointKey === replaceTargetMarkerId)) {
|
|
1499
|
+
if (seekMode === "warp") {
|
|
1500
|
+
await runWarp({
|
|
1501
|
+
markerId: replaceTargetMarkerId,
|
|
1502
|
+
boundary: "after"
|
|
1503
|
+
});
|
|
1504
|
+
} else if (seekMode === "fast-forward") {
|
|
1505
|
+
await runFastForwardToMarker(replaceTargetMarkerId);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
return outcome;
|
|
1510
|
+
} catch (error) {
|
|
1511
|
+
debugState.lastError = toErrorMessage(error);
|
|
1512
|
+
throw error;
|
|
1513
|
+
} finally {
|
|
1514
|
+
debugState.restoring = false;
|
|
1515
|
+
}
|
|
1443
1516
|
}
|
|
1444
1517
|
};
|
|
1445
1518
|
function registerAppStateAdapter(adapter) {
|
|
@@ -1544,7 +1617,8 @@ function useDebugSession() {
|
|
|
1544
1617
|
stopDebugSession,
|
|
1545
1618
|
restoreCheckpoint: debugSessionController.restoreCheckpoint,
|
|
1546
1619
|
warp: debugSessionController.warp,
|
|
1547
|
-
switchRoute: debugSessionController.switchRoute
|
|
1620
|
+
switchRoute: debugSessionController.switchRoute,
|
|
1621
|
+
replaceStory: debugSessionController.replaceStory
|
|
1548
1622
|
};
|
|
1549
1623
|
}
|
|
1550
1624
|
|
|
@@ -1634,6 +1708,9 @@ function isJumpRequestMessage(message) {
|
|
|
1634
1708
|
function isRouteRequestMessage(message) {
|
|
1635
1709
|
return message.type === "route:request" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.page === "string" && (message.params === void 0 || typeof message.params === "object" && message.params !== null && !Array.isArray(message.params));
|
|
1636
1710
|
}
|
|
1711
|
+
function isStoryReplaceMessage(message) {
|
|
1712
|
+
return message.type === "story:replace" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.story === "string" && typeof message.content === "string" && (message.seekMode === void 0 || message.seekMode === "off" || message.seekMode === "fast-forward" || message.seekMode === "warp") && (message.targetMarkerId === void 0 || typeof message.targetMarkerId === "string");
|
|
1713
|
+
}
|
|
1637
1714
|
function isUiReplaceMessage(message) {
|
|
1638
1715
|
return message.type === "ui:replace" && typeof message.sessionId === "string";
|
|
1639
1716
|
}
|
|
@@ -1720,6 +1797,35 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1720
1797
|
});
|
|
1721
1798
|
return;
|
|
1722
1799
|
}
|
|
1800
|
+
if (isStoryReplaceMessage(message)) {
|
|
1801
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1802
|
+
void controller.replaceStory({
|
|
1803
|
+
story: message.story,
|
|
1804
|
+
content: message.content,
|
|
1805
|
+
seekMode: message.seekMode,
|
|
1806
|
+
targetMarkerId: message.targetMarkerId
|
|
1807
|
+
}).then(async () => {
|
|
1808
|
+
sendRuntimeDebugMessage(socket, {
|
|
1809
|
+
type: "story:replace:done",
|
|
1810
|
+
sessionId,
|
|
1811
|
+
requestId: message.requestId,
|
|
1812
|
+
story: message.story
|
|
1813
|
+
});
|
|
1814
|
+
await syncRuntimeDebugVariablesSnapshotSafe("story-replace-done");
|
|
1815
|
+
}).catch(async (error) => {
|
|
1816
|
+
sendRuntimeDebugMessage(socket, {
|
|
1817
|
+
type: "story:replace:error",
|
|
1818
|
+
sessionId,
|
|
1819
|
+
requestId: message.requestId,
|
|
1820
|
+
story: message.story,
|
|
1821
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1822
|
+
});
|
|
1823
|
+
await syncRuntimeDebugVariablesSnapshotSafe("story-replace-error");
|
|
1824
|
+
}).finally(() => {
|
|
1825
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1826
|
+
});
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1723
1829
|
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1724
1830
|
void controller.switchRoute(message.page, message.params).then(async () => {
|
|
1725
1831
|
sendRuntimeDebugMessage(socket, {
|
|
@@ -1857,6 +1963,10 @@ async function startRuntimeDebugSession() {
|
|
|
1857
1963
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1858
1964
|
return;
|
|
1859
1965
|
}
|
|
1966
|
+
if (isStoryReplaceMessage(message)) {
|
|
1967
|
+
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1860
1970
|
if (isUiReplaceMessage(message)) {
|
|
1861
1971
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1862
1972
|
return;
|