@momoyu-ink/kit 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{jsx-dev-runtime-CFlTWFj5.d.mts → jsx-dev-runtime-CKclO27C.d.mts} +13 -1
- package/dist/{jsx-dev-runtime-CFlTWFj5.d.ts → jsx-dev-runtime-CKclO27C.d.ts} +13 -1
- 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 +496 -82
- package/dist/lib.d.mts +49 -9
- package/dist/lib.d.ts +49 -9
- package/dist/lib.mjs +504 -82
- package/package.json +1 -1
package/dist/lib.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/lib.ts
|
|
32
32
|
var lib_exports = {};
|
|
33
33
|
__export(lib_exports, {
|
|
34
|
+
DEBUG_EMPTY_PAGE: () => DEBUG_EMPTY_PAGE,
|
|
34
35
|
OverlayParamsContext: () => OverlayParamsContext,
|
|
35
36
|
PageParamsContext: () => PageParamsContext,
|
|
36
37
|
StageContextProvider: () => StageContextProvider,
|
|
@@ -43,6 +44,7 @@ __export(lib_exports, {
|
|
|
43
44
|
createStackNavigator: () => createStackNavigator,
|
|
44
45
|
createStage: () => createStage,
|
|
45
46
|
createStaticNavigation: () => createStaticNavigation,
|
|
47
|
+
ensureArchiveVariableDefaults: () => ensureArchiveVariableDefaults,
|
|
46
48
|
executeNodeCommand: () => executeNodeCommand,
|
|
47
49
|
executePluginCommand: () => executePluginCommand,
|
|
48
50
|
fastForwardState: () => fastForwardState,
|
|
@@ -50,11 +52,16 @@ __export(lib_exports, {
|
|
|
50
52
|
getNavigator: () => getNavigator,
|
|
51
53
|
getSeekingType: () => getSeekingType,
|
|
52
54
|
getStageSize: () => getStageSize,
|
|
55
|
+
getUiData: () => getUiData,
|
|
53
56
|
globalEventListeners: () => globalEventListeners,
|
|
54
57
|
globalRequestAnimationFrameListeners: () => globalRequestAnimationFrameListeners,
|
|
58
|
+
initGlobalVariableDefaults: () => initGlobalVariableDefaults,
|
|
59
|
+
initUiData: () => initUiData,
|
|
60
|
+
loadVariablesDocument: () => loadVariablesDocument,
|
|
55
61
|
moyu: () => moyu_exports,
|
|
56
62
|
nextLine: () => nextLine,
|
|
57
63
|
registerAppStateAdapter: () => registerAppStateAdapter,
|
|
64
|
+
replaceUiData: () => replaceUiData,
|
|
58
65
|
setDefaultAutoTailMs: () => setDefaultAutoTailMs,
|
|
59
66
|
setWaiting: () => setWaiting,
|
|
60
67
|
skipState: () => skipState,
|
|
@@ -81,6 +88,7 @@ __export(lib_exports, {
|
|
|
81
88
|
useSkipCallback: () => useSkipCallback,
|
|
82
89
|
useSoundEffect: () => useSoundEffect,
|
|
83
90
|
useStageContext: () => useStageContext,
|
|
91
|
+
useUiData: () => useUiData,
|
|
84
92
|
warpState: () => warpState
|
|
85
93
|
});
|
|
86
94
|
module.exports = __toCommonJS(lib_exports);
|
|
@@ -406,6 +414,259 @@ function createRoot(options) {
|
|
|
406
414
|
};
|
|
407
415
|
}
|
|
408
416
|
|
|
417
|
+
// src/variables.ts
|
|
418
|
+
var VARIABLES_DATA_ASSET_PATH = "assets:///data/variables.json";
|
|
419
|
+
function normalizeVariableDefinitions(value) {
|
|
420
|
+
if (!Array.isArray(value)) {
|
|
421
|
+
return [];
|
|
422
|
+
}
|
|
423
|
+
return value.flatMap((entry) => {
|
|
424
|
+
if (!entry || typeof entry !== "object") {
|
|
425
|
+
return [];
|
|
426
|
+
}
|
|
427
|
+
const definition = entry;
|
|
428
|
+
if (typeof definition.id !== "string" || definition.id.length === 0) {
|
|
429
|
+
return [];
|
|
430
|
+
}
|
|
431
|
+
return [{ id: definition.id, defaultValue: definition.defaultValue }];
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
async function loadVariablesDocument() {
|
|
435
|
+
let rawText;
|
|
436
|
+
try {
|
|
437
|
+
rawText = await executePluginCommand("system", {
|
|
438
|
+
subCommand: "readFile",
|
|
439
|
+
path: VARIABLES_DATA_ASSET_PATH
|
|
440
|
+
});
|
|
441
|
+
} catch {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
let rawData;
|
|
445
|
+
try {
|
|
446
|
+
rawData = JSON.parse(rawText);
|
|
447
|
+
} catch (error) {
|
|
448
|
+
console.error("Failed to parse variable defaults data:", error);
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
if (!rawData || typeof rawData !== "object") {
|
|
452
|
+
return {
|
|
453
|
+
archive: [],
|
|
454
|
+
global: []
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
const document = rawData;
|
|
458
|
+
return {
|
|
459
|
+
archive: normalizeVariableDefinitions(document.archive),
|
|
460
|
+
global: normalizeVariableDefinitions(document.global)
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function toVariableRecord(value) {
|
|
464
|
+
if (value instanceof Map) {
|
|
465
|
+
return Object.fromEntries(value);
|
|
466
|
+
}
|
|
467
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
468
|
+
return {};
|
|
469
|
+
}
|
|
470
|
+
return value;
|
|
471
|
+
}
|
|
472
|
+
async function ensureVariableDefaults(scope) {
|
|
473
|
+
const document = await loadVariablesDocument();
|
|
474
|
+
if (!document) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const definitions = document[scope];
|
|
478
|
+
if (definitions.length === 0) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const currentVariables = toVariableRecord(
|
|
482
|
+
await executePluginCommand(
|
|
483
|
+
"scenario",
|
|
484
|
+
scope === "global" ? { subCommand: "getPermanentVariables" } : { subCommand: "getVariables" }
|
|
485
|
+
)
|
|
486
|
+
);
|
|
487
|
+
const missingVariables = {};
|
|
488
|
+
for (const definition of definitions) {
|
|
489
|
+
if (!Object.hasOwn(currentVariables, definition.id)) {
|
|
490
|
+
missingVariables[definition.id] = definition.defaultValue;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if (Object.keys(missingVariables).length === 0) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
await executePluginCommand(
|
|
497
|
+
"scenario",
|
|
498
|
+
scope === "global" ? {
|
|
499
|
+
subCommand: "setPermanentVariables",
|
|
500
|
+
variables: missingVariables
|
|
501
|
+
} : {
|
|
502
|
+
subCommand: "setVariables",
|
|
503
|
+
variables: missingVariables
|
|
504
|
+
}
|
|
505
|
+
);
|
|
506
|
+
reportRuntimeDebugVariablesSet(scope, missingVariables);
|
|
507
|
+
}
|
|
508
|
+
async function initGlobalVariableDefaults() {
|
|
509
|
+
await ensureVariableDefaults("global");
|
|
510
|
+
}
|
|
511
|
+
async function ensureArchiveVariableDefaults() {
|
|
512
|
+
await ensureVariableDefaults("archive");
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// src/debug/variableMonitor.ts
|
|
516
|
+
var sendRuntimeDebugVariableMessage = null;
|
|
517
|
+
var allowlistCache = null;
|
|
518
|
+
var allowlistPromise = null;
|
|
519
|
+
var variableEmissionSuspended = false;
|
|
520
|
+
function createEmptyAllowlist() {
|
|
521
|
+
return {
|
|
522
|
+
archive: /* @__PURE__ */ new Set(),
|
|
523
|
+
global: /* @__PURE__ */ new Set()
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function isJsonValue(value) {
|
|
527
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
if (Array.isArray(value)) {
|
|
531
|
+
return value.every((item) => isJsonValue(item));
|
|
532
|
+
}
|
|
533
|
+
if (!value || typeof value !== "object") {
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
return Object.values(value).every((item) => isJsonValue(item));
|
|
537
|
+
}
|
|
538
|
+
async function loadRuntimeDebugVariableAllowlist() {
|
|
539
|
+
const document = await loadVariablesDocument();
|
|
540
|
+
if (!document) {
|
|
541
|
+
return createEmptyAllowlist();
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
archive: new Set(document.archive.map((def) => def.id)),
|
|
545
|
+
global: new Set(document.global.map((def) => def.id))
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function toJsonValueRecord(value) {
|
|
549
|
+
if (value instanceof Map) {
|
|
550
|
+
return Object.fromEntries(
|
|
551
|
+
Array.from(value.entries()).flatMap(([key, entryValue]) => {
|
|
552
|
+
if (typeof key !== "string" || !isJsonValue(entryValue)) {
|
|
553
|
+
return [];
|
|
554
|
+
}
|
|
555
|
+
return [[key, entryValue]];
|
|
556
|
+
})
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
560
|
+
return {};
|
|
561
|
+
}
|
|
562
|
+
return Object.fromEntries(
|
|
563
|
+
Object.entries(value).flatMap(([key, entryValue]) => {
|
|
564
|
+
if (!isJsonValue(entryValue)) {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
return [[key, entryValue]];
|
|
568
|
+
})
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
function filterVariablesByAllowlist(scope, values, allowlist) {
|
|
572
|
+
const allowedIds = allowlist[scope];
|
|
573
|
+
if (allowedIds.size === 0) {
|
|
574
|
+
return {};
|
|
575
|
+
}
|
|
576
|
+
return Object.fromEntries(
|
|
577
|
+
Object.entries(values).flatMap(([key, value]) => allowedIds.has(key) ? [[key, value]] : [])
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
function hasRecordEntries(value) {
|
|
581
|
+
return !!value && Object.keys(value).length > 0;
|
|
582
|
+
}
|
|
583
|
+
async function ensureRuntimeDebugVariableAllowlist() {
|
|
584
|
+
if (allowlistCache) {
|
|
585
|
+
return allowlistCache;
|
|
586
|
+
}
|
|
587
|
+
if (!allowlistPromise) {
|
|
588
|
+
allowlistPromise = loadRuntimeDebugVariableAllowlist().then((allowlist) => {
|
|
589
|
+
allowlistCache = allowlist;
|
|
590
|
+
return allowlist;
|
|
591
|
+
}).finally(() => {
|
|
592
|
+
allowlistPromise = null;
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
return allowlistPromise;
|
|
596
|
+
}
|
|
597
|
+
async function emitRuntimeDebugVariablesChanged(scope, variables) {
|
|
598
|
+
const sender = sendRuntimeDebugVariableMessage;
|
|
599
|
+
if (!sender || variableEmissionSuspended) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const allowlist = await ensureRuntimeDebugVariableAllowlist();
|
|
603
|
+
if (!sendRuntimeDebugVariableMessage || sendRuntimeDebugVariableMessage !== sender || variableEmissionSuspended) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
const filtered = filterVariablesByAllowlist(scope, variables, allowlist);
|
|
607
|
+
if (!hasRecordEntries(filtered)) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
sender({
|
|
611
|
+
type: "variables:changed",
|
|
612
|
+
archiveSet: scope === "archive" ? filtered : void 0,
|
|
613
|
+
globalSet: scope === "global" ? filtered : void 0
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
function setRuntimeDebugVariableMessageSender(sender) {
|
|
617
|
+
sendRuntimeDebugVariableMessage = sender;
|
|
618
|
+
if (sender) {
|
|
619
|
+
void ensureRuntimeDebugVariableAllowlist();
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function setRuntimeDebugVariableEmissionSuspended(suspended) {
|
|
623
|
+
variableEmissionSuspended = suspended;
|
|
624
|
+
}
|
|
625
|
+
function resetRuntimeDebugVariableMonitor() {
|
|
626
|
+
sendRuntimeDebugVariableMessage = null;
|
|
627
|
+
allowlistCache = null;
|
|
628
|
+
allowlistPromise = null;
|
|
629
|
+
variableEmissionSuspended = false;
|
|
630
|
+
}
|
|
631
|
+
function reportRuntimeDebugVariableSet(scope, key, value) {
|
|
632
|
+
if (key.length === 0) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
void emitRuntimeDebugVariablesChanged(scope, {
|
|
636
|
+
[key]: value
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
function reportRuntimeDebugVariablesSet(scope, variables) {
|
|
640
|
+
if (Object.keys(variables).length === 0) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
void emitRuntimeDebugVariablesChanged(scope, variables);
|
|
644
|
+
}
|
|
645
|
+
async function syncRuntimeDebugVariablesSnapshot(reason) {
|
|
646
|
+
const sender = sendRuntimeDebugVariableMessage;
|
|
647
|
+
if (!sender) {
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
const [allowlist, archiveVariables2, globalVariables2] = await Promise.all([
|
|
651
|
+
ensureRuntimeDebugVariableAllowlist(),
|
|
652
|
+
executePluginCommand("scenario", {
|
|
653
|
+
subCommand: "getVariables"
|
|
654
|
+
}),
|
|
655
|
+
executePluginCommand("scenario", {
|
|
656
|
+
subCommand: "getPermanentVariables"
|
|
657
|
+
})
|
|
658
|
+
]);
|
|
659
|
+
if (!sendRuntimeDebugVariableMessage || sendRuntimeDebugVariableMessage !== sender) {
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
sender({
|
|
663
|
+
type: "variables:snapshot",
|
|
664
|
+
reason,
|
|
665
|
+
archive: filterVariablesByAllowlist("archive", toJsonValueRecord(archiveVariables2), allowlist),
|
|
666
|
+
global: filterVariablesByAllowlist("global", toJsonValueRecord(globalVariables2), allowlist)
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
|
|
409
670
|
// src/sandbox.ts
|
|
410
671
|
var JS_GLOBAL_KEYS = new Set(Object.getOwnPropertyNames(globalThis));
|
|
411
672
|
var JS_GLOBAL_KEYS_EXCLUDED = /* @__PURE__ */ new Set(["window", "globalThis", "LOCAL", "ARCHIVE", "GLOBAL"]);
|
|
@@ -456,6 +717,7 @@ var archiveVariables = new Proxy(
|
|
|
456
717
|
name: key,
|
|
457
718
|
value
|
|
458
719
|
});
|
|
720
|
+
reportRuntimeDebugVariableSet("archive", key, value);
|
|
459
721
|
return true;
|
|
460
722
|
}
|
|
461
723
|
return false;
|
|
@@ -481,6 +743,7 @@ var globalVariables = new Proxy(
|
|
|
481
743
|
key,
|
|
482
744
|
value
|
|
483
745
|
});
|
|
746
|
+
reportRuntimeDebugVariableSet("global", key, value);
|
|
484
747
|
return true;
|
|
485
748
|
}
|
|
486
749
|
return false;
|
|
@@ -488,7 +751,7 @@ var globalVariables = new Proxy(
|
|
|
488
751
|
}
|
|
489
752
|
);
|
|
490
753
|
function safeEval(code, sandbox) {
|
|
491
|
-
const
|
|
754
|
+
const proxy5 = new Proxy(sandbox, {
|
|
492
755
|
has(target, key) {
|
|
493
756
|
if (typeof key === "string" && JS_GLOBAL_KEYS.has(key)) {
|
|
494
757
|
return false;
|
|
@@ -496,7 +759,7 @@ function safeEval(code, sandbox) {
|
|
|
496
759
|
return key in target || key === "LOCAL" || key === "ARCHIVE" || key === "GLOBAL" || key === "window" || key === "globalThis";
|
|
497
760
|
},
|
|
498
761
|
get(target, key) {
|
|
499
|
-
if (key === "window" || key === "globalThis") return
|
|
762
|
+
if (key === "window" || key === "globalThis") return proxy5;
|
|
500
763
|
if (key === "LOCAL") return localVariables;
|
|
501
764
|
if (key === "ARCHIVE") return archiveVariables;
|
|
502
765
|
if (key === "GLOBAL") return globalVariables;
|
|
@@ -508,7 +771,7 @@ function safeEval(code, sandbox) {
|
|
|
508
771
|
return true;
|
|
509
772
|
}
|
|
510
773
|
});
|
|
511
|
-
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(
|
|
774
|
+
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(proxy5)(proxy5);
|
|
512
775
|
}
|
|
513
776
|
globalThis.__moyu_eval_sandbox = (code) => {
|
|
514
777
|
try {
|
|
@@ -695,6 +958,7 @@ var import_valtio = require("valtio");
|
|
|
695
958
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
696
959
|
var PageParamsContext = (0, import_react2.createContext)(void 0);
|
|
697
960
|
var OverlayParamsContext = (0, import_react2.createContext)(void 0);
|
|
961
|
+
var DEBUG_EMPTY_PAGE = "debug-empty";
|
|
698
962
|
var overlayIdCounter = 0;
|
|
699
963
|
var generateOverlayId = () => {
|
|
700
964
|
return `overlay-${++overlayIdCounter}-${Date.now()}`;
|
|
@@ -722,6 +986,12 @@ function createStackNavigator(options) {
|
|
|
722
986
|
for (const [key, config] of Object.entries(options.pages)) {
|
|
723
987
|
normalizedPages[key] = normalizeDescriptor(config);
|
|
724
988
|
}
|
|
989
|
+
if (normalizedPages[DEBUG_EMPTY_PAGE]) {
|
|
990
|
+
throw new Error(`Navigation Error: Page name "${DEBUG_EMPTY_PAGE}" is reserved.`);
|
|
991
|
+
}
|
|
992
|
+
normalizedPages[DEBUG_EMPTY_PAGE] = {
|
|
993
|
+
component: () => null
|
|
994
|
+
};
|
|
725
995
|
const normalizedOverlays = {};
|
|
726
996
|
if (options.overlays) {
|
|
727
997
|
for (const [key, config] of Object.entries(options.overlays)) {
|
|
@@ -751,6 +1021,9 @@ function createStackNavigator(options) {
|
|
|
751
1021
|
hasPage: (page) => {
|
|
752
1022
|
return normalizedPages[page] !== void 0;
|
|
753
1023
|
},
|
|
1024
|
+
hasOverlay: (overlay) => {
|
|
1025
|
+
return normalizedOverlays[overlay] !== void 0;
|
|
1026
|
+
},
|
|
754
1027
|
goBack: () => {
|
|
755
1028
|
console.warn("goBack() not implemented yet");
|
|
756
1029
|
},
|
|
@@ -838,6 +1111,7 @@ var debugState = (0, import_valtio2.proxy)({
|
|
|
838
1111
|
active: false,
|
|
839
1112
|
checkpoints: {},
|
|
840
1113
|
currentCursor: null,
|
|
1114
|
+
currentStory: null,
|
|
841
1115
|
restoring: false,
|
|
842
1116
|
lastError: null
|
|
843
1117
|
});
|
|
@@ -881,9 +1155,37 @@ function reportDebugSessionError(error) {
|
|
|
881
1155
|
function clearLocalRuntimeState() {
|
|
882
1156
|
debugState.checkpoints = {};
|
|
883
1157
|
debugState.currentCursor = null;
|
|
1158
|
+
debugState.currentStory = null;
|
|
884
1159
|
debugState.restoring = false;
|
|
885
1160
|
debugState.lastError = null;
|
|
886
1161
|
}
|
|
1162
|
+
async function restartJumpStoryFromHead(targetStory, currentStory) {
|
|
1163
|
+
debugState.checkpoints = {};
|
|
1164
|
+
debugState.currentCursor = null;
|
|
1165
|
+
debugState.currentStory = null;
|
|
1166
|
+
if (targetStory) {
|
|
1167
|
+
if (appStateAdapter?.restartStoryFromHead) {
|
|
1168
|
+
await appStateAdapter.restartStoryFromHead({
|
|
1169
|
+
story: targetStory,
|
|
1170
|
+
entry: "entry"
|
|
1171
|
+
});
|
|
1172
|
+
} else if (currentStory === targetStory && appStateAdapter?.restartCurrentStoryFromHead) {
|
|
1173
|
+
await appStateAdapter.restartCurrentStoryFromHead();
|
|
1174
|
+
} else {
|
|
1175
|
+
throw new Error("Restarting the target story from head is not supported by the app state adapter");
|
|
1176
|
+
}
|
|
1177
|
+
debugState.currentCursor = await executeScenarioCommand({
|
|
1178
|
+
subCommand: "getExecutionCursor"
|
|
1179
|
+
});
|
|
1180
|
+
debugState.currentStory = debugState.currentCursor?.story ?? targetStory;
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
if (!appStateAdapter?.restartCurrentStoryFromHead) {
|
|
1184
|
+
throw new Error("Restarting the current story from head is not supported by the app state adapter");
|
|
1185
|
+
}
|
|
1186
|
+
await appStateAdapter.restartCurrentStoryFromHead();
|
|
1187
|
+
debugState.currentCursor = null;
|
|
1188
|
+
}
|
|
887
1189
|
async function doSettleActiveSeek(op, clearSlot, error) {
|
|
888
1190
|
if (!op) {
|
|
889
1191
|
return;
|
|
@@ -912,6 +1214,11 @@ async function settleActiveWarp(error) {
|
|
|
912
1214
|
activeWarp = null;
|
|
913
1215
|
}, error);
|
|
914
1216
|
}
|
|
1217
|
+
async function clearLocalDebugSessionRuntimeState() {
|
|
1218
|
+
await settleActiveFastForward(new Error("Debug session runtime state cleared"));
|
|
1219
|
+
await settleActiveWarp(new Error("Debug session runtime state cleared"));
|
|
1220
|
+
clearLocalRuntimeState();
|
|
1221
|
+
}
|
|
915
1222
|
async function clearRemoteCheckpoints() {
|
|
916
1223
|
await executeScenarioCommand({ subCommand: "clearCheckpoints" });
|
|
917
1224
|
}
|
|
@@ -936,6 +1243,7 @@ async function syncLocalWarpCheckpoint(targetMarkerId) {
|
|
|
936
1243
|
appState: appStateAdapter ? await appStateAdapter.capture() : void 0
|
|
937
1244
|
};
|
|
938
1245
|
debugState.currentCursor = checkpointCursor;
|
|
1246
|
+
debugState.currentStory = checkpointCursor.story;
|
|
939
1247
|
debugState.checkpoints[targetMarkerId] = checkpoint;
|
|
940
1248
|
await currentConfig.onMarkerEnter(checkpoint);
|
|
941
1249
|
}
|
|
@@ -959,9 +1267,16 @@ function notifyMarkerEnter(checkpoint) {
|
|
|
959
1267
|
reportDebugSessionError(error);
|
|
960
1268
|
}
|
|
961
1269
|
}
|
|
962
|
-
async function prepareJumpStart(markerId) {
|
|
1270
|
+
async function prepareJumpStart(markerId, options) {
|
|
1271
|
+
const currentStory = debugState.currentStory ?? debugState.currentCursor?.story ?? null;
|
|
1272
|
+
const targetStory = options?.story;
|
|
1273
|
+
let restartedFromHead = false;
|
|
1274
|
+
if (targetStory && targetStory !== currentStory) {
|
|
1275
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
1276
|
+
restartedFromHead = true;
|
|
1277
|
+
}
|
|
963
1278
|
const checkpoint = debugState.checkpoints[markerId];
|
|
964
|
-
if (checkpoint) {
|
|
1279
|
+
if (!restartedFromHead && checkpoint && (!targetStory || checkpoint.cursor.story === targetStory)) {
|
|
965
1280
|
const restored2 = await executeScenarioCommand({
|
|
966
1281
|
subCommand: "restoreCheckpoint",
|
|
967
1282
|
key: markerId
|
|
@@ -973,6 +1288,7 @@ async function prepareJumpStart(markerId) {
|
|
|
973
1288
|
await appStateAdapter.restore(checkpoint.appState);
|
|
974
1289
|
}
|
|
975
1290
|
debugState.currentCursor = checkpoint.cursor;
|
|
1291
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
976
1292
|
return false;
|
|
977
1293
|
}
|
|
978
1294
|
const lookup = await executeScenarioCommand({
|
|
@@ -980,16 +1296,15 @@ async function prepareJumpStart(markerId) {
|
|
|
980
1296
|
key: markerId
|
|
981
1297
|
});
|
|
982
1298
|
if (!lookup.markerExists) {
|
|
983
|
-
throw new Error(
|
|
1299
|
+
throw new Error(
|
|
1300
|
+
targetStory ? `Marker ${markerId} is not available in story ${targetStory}` : `Marker ${markerId} is not available in the current story`
|
|
1301
|
+
);
|
|
984
1302
|
}
|
|
985
1303
|
const startCheckpointKey = lookup.checkpointKey ?? null;
|
|
986
1304
|
if (!startCheckpointKey) {
|
|
987
|
-
if (!
|
|
988
|
-
|
|
1305
|
+
if (!restartedFromHead) {
|
|
1306
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
989
1307
|
}
|
|
990
|
-
await appStateAdapter.restartCurrentStoryFromHead();
|
|
991
|
-
debugState.checkpoints = {};
|
|
992
|
-
debugState.currentCursor = null;
|
|
993
1308
|
return true;
|
|
994
1309
|
}
|
|
995
1310
|
const startCheckpoint = debugState.checkpoints[startCheckpointKey];
|
|
@@ -1007,6 +1322,7 @@ async function prepareJumpStart(markerId) {
|
|
|
1007
1322
|
await appStateAdapter.restore(startCheckpoint.appState);
|
|
1008
1323
|
}
|
|
1009
1324
|
debugState.currentCursor = startCheckpoint.cursor;
|
|
1325
|
+
debugState.currentStory = startCheckpoint.cursor.story;
|
|
1010
1326
|
return true;
|
|
1011
1327
|
}
|
|
1012
1328
|
function handleMarkerEnter(marker) {
|
|
@@ -1019,6 +1335,7 @@ function handleMarkerEnter(marker) {
|
|
|
1019
1335
|
appState: captureCheckpointAppStateSync()
|
|
1020
1336
|
};
|
|
1021
1337
|
debugState.currentCursor = checkpoint.cursor;
|
|
1338
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
1022
1339
|
debugState.checkpoints[marker.markerId] = checkpoint;
|
|
1023
1340
|
notifyMarkerEnter(checkpoint);
|
|
1024
1341
|
if (activeFastForward?.targetMarkerId === marker.markerId) {
|
|
@@ -1079,11 +1396,11 @@ async function runWarp(options) {
|
|
|
1079
1396
|
await completion;
|
|
1080
1397
|
}
|
|
1081
1398
|
var debugSessionController = {
|
|
1082
|
-
async restoreCheckpoint(markerId) {
|
|
1399
|
+
async restoreCheckpoint(markerId, options) {
|
|
1083
1400
|
debugState.restoring = true;
|
|
1084
1401
|
debugState.lastError = null;
|
|
1085
1402
|
try {
|
|
1086
|
-
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId));
|
|
1403
|
+
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId, options));
|
|
1087
1404
|
if (needsFastForward) {
|
|
1088
1405
|
await runFastForwardToMarker(markerId);
|
|
1089
1406
|
}
|
|
@@ -1099,7 +1416,7 @@ var debugSessionController = {
|
|
|
1099
1416
|
debugState.restoring = true;
|
|
1100
1417
|
debugState.lastError = null;
|
|
1101
1418
|
try {
|
|
1102
|
-
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId));
|
|
1419
|
+
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId, options));
|
|
1103
1420
|
if (needsWarp) {
|
|
1104
1421
|
await runWarp(options);
|
|
1105
1422
|
}
|
|
@@ -1110,14 +1427,26 @@ var debugSessionController = {
|
|
|
1110
1427
|
debugState.restoring = false;
|
|
1111
1428
|
}
|
|
1112
1429
|
},
|
|
1113
|
-
async
|
|
1430
|
+
async switchRoute(routeName, params) {
|
|
1114
1431
|
return enqueueDebugOperation(async () => {
|
|
1115
1432
|
debugState.lastError = null;
|
|
1116
1433
|
try {
|
|
1117
|
-
|
|
1118
|
-
|
|
1434
|
+
const navigator = getNavigator();
|
|
1435
|
+
if (navigator.hasPage(routeName)) {
|
|
1436
|
+
if (!appStateAdapter?.switchPage) {
|
|
1437
|
+
throw new Error("Page switching is not supported by the app state adapter");
|
|
1438
|
+
}
|
|
1439
|
+
await appStateAdapter.switchPage(routeName, params);
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
if (navigator.hasOverlay(routeName)) {
|
|
1443
|
+
if (!appStateAdapter?.switchOverlay) {
|
|
1444
|
+
throw new Error("Overlay switching is not supported by the app state adapter");
|
|
1445
|
+
}
|
|
1446
|
+
await appStateAdapter.switchOverlay(routeName, params);
|
|
1447
|
+
return;
|
|
1119
1448
|
}
|
|
1120
|
-
|
|
1449
|
+
throw new Error(`Route "${routeName}" not found`);
|
|
1121
1450
|
} catch (error) {
|
|
1122
1451
|
debugState.lastError = toErrorMessage(error);
|
|
1123
1452
|
throw error;
|
|
@@ -1182,6 +1511,7 @@ async function startDebugSession(config = {}) {
|
|
|
1182
1511
|
debugState.currentCursor = await executeScenarioCommand({
|
|
1183
1512
|
subCommand: "getExecutionCursor"
|
|
1184
1513
|
});
|
|
1514
|
+
debugState.currentStory = debugState.currentCursor?.story ?? null;
|
|
1185
1515
|
} catch (error) {
|
|
1186
1516
|
debugState.active = false;
|
|
1187
1517
|
clearLocalRuntimeState();
|
|
@@ -1218,22 +1548,6 @@ async function stopDebugSession() {
|
|
|
1218
1548
|
debugState.active = false;
|
|
1219
1549
|
clearLocalRuntimeState();
|
|
1220
1550
|
}
|
|
1221
|
-
function clearDebugSessionRuntimeState() {
|
|
1222
|
-
clearLocalRuntimeState();
|
|
1223
|
-
void settleActiveFastForward(new Error("Debug session runtime state cleared"));
|
|
1224
|
-
void settleActiveWarp(new Error("Debug session runtime state cleared"));
|
|
1225
|
-
if (!debugState.active) {
|
|
1226
|
-
return;
|
|
1227
|
-
}
|
|
1228
|
-
void enqueueDebugOperation(async () => {
|
|
1229
|
-
try {
|
|
1230
|
-
await clearRemoteCheckpoints();
|
|
1231
|
-
} catch (error) {
|
|
1232
|
-
debugState.lastError = toErrorMessage(error);
|
|
1233
|
-
await currentConfig.onError(error);
|
|
1234
|
-
}
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
1551
|
function useDebugSession() {
|
|
1238
1552
|
const snapshot = (0, import_valtio2.useSnapshot)(debugState);
|
|
1239
1553
|
return {
|
|
@@ -1242,10 +1556,83 @@ function useDebugSession() {
|
|
|
1242
1556
|
stopDebugSession,
|
|
1243
1557
|
restoreCheckpoint: debugSessionController.restoreCheckpoint,
|
|
1244
1558
|
warp: debugSessionController.warp,
|
|
1245
|
-
|
|
1559
|
+
switchRoute: debugSessionController.switchRoute
|
|
1246
1560
|
};
|
|
1247
1561
|
}
|
|
1248
1562
|
|
|
1563
|
+
// src/ui.ts
|
|
1564
|
+
var import_valtio3 = require("valtio");
|
|
1565
|
+
var UI_DATA_ASSET_PATH = "assets:///data/ui.json";
|
|
1566
|
+
var activeUiSchema = null;
|
|
1567
|
+
var uiDataState = (0, import_valtio3.proxy)({});
|
|
1568
|
+
var uiRuntimeState = (0, import_valtio3.proxy)({
|
|
1569
|
+
initialized: false,
|
|
1570
|
+
error: null
|
|
1571
|
+
});
|
|
1572
|
+
function applyUiData(nextData) {
|
|
1573
|
+
for (const key of Object.keys(uiDataState)) {
|
|
1574
|
+
delete uiDataState[key];
|
|
1575
|
+
}
|
|
1576
|
+
Object.assign(uiDataState, nextData);
|
|
1577
|
+
uiRuntimeState.initialized = true;
|
|
1578
|
+
uiRuntimeState.error = null;
|
|
1579
|
+
}
|
|
1580
|
+
async function initUiData(schema) {
|
|
1581
|
+
uiRuntimeState.initialized = false;
|
|
1582
|
+
uiRuntimeState.error = null;
|
|
1583
|
+
activeUiSchema = schema;
|
|
1584
|
+
let rawData;
|
|
1585
|
+
try {
|
|
1586
|
+
const rawText = await Promise.resolve(
|
|
1587
|
+
executePluginCommand("system", {
|
|
1588
|
+
subCommand: "readFile",
|
|
1589
|
+
path: UI_DATA_ASSET_PATH
|
|
1590
|
+
})
|
|
1591
|
+
);
|
|
1592
|
+
rawData = JSON.parse(rawText);
|
|
1593
|
+
} catch (error) {
|
|
1594
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1595
|
+
uiRuntimeState.error = message;
|
|
1596
|
+
throw new Error(`Failed to initialize UI data: ${message}`);
|
|
1597
|
+
}
|
|
1598
|
+
const parsed = schema.safeParse(rawData);
|
|
1599
|
+
if (!parsed.success) {
|
|
1600
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1601
|
+
throw new Error(`Invalid UI data: ${parsed.error.message}`);
|
|
1602
|
+
}
|
|
1603
|
+
applyUiData(parsed.data);
|
|
1604
|
+
}
|
|
1605
|
+
function replaceUiData(rawData) {
|
|
1606
|
+
if (!activeUiSchema) {
|
|
1607
|
+
throw new Error("UI data schema has not been initialized. Call initUiData() first.");
|
|
1608
|
+
}
|
|
1609
|
+
const parsed = activeUiSchema.safeParse(rawData);
|
|
1610
|
+
if (!parsed.success) {
|
|
1611
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1612
|
+
throw new Error(`Invalid replacement UI data: ${parsed.error.message}`);
|
|
1613
|
+
}
|
|
1614
|
+
applyUiData(parsed.data);
|
|
1615
|
+
}
|
|
1616
|
+
function getUiData(name) {
|
|
1617
|
+
if (!uiRuntimeState.initialized) {
|
|
1618
|
+
throw new Error("UI data has not been initialized. Call initUiData() before reading it.");
|
|
1619
|
+
}
|
|
1620
|
+
if (!(name in uiDataState)) {
|
|
1621
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1622
|
+
}
|
|
1623
|
+
return uiDataState[name];
|
|
1624
|
+
}
|
|
1625
|
+
function useUiData(name) {
|
|
1626
|
+
if (!uiRuntimeState.initialized) {
|
|
1627
|
+
throw new Error("UI data has not been initialized. Call initUiData() before rendering UI pages.");
|
|
1628
|
+
}
|
|
1629
|
+
const snapshot = (0, import_valtio3.useSnapshot)(uiDataState);
|
|
1630
|
+
if (!(name in snapshot)) {
|
|
1631
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1632
|
+
}
|
|
1633
|
+
return snapshot[name];
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1249
1636
|
// src/debug/runtime.ts
|
|
1250
1637
|
var currentConnection = null;
|
|
1251
1638
|
var currentController = null;
|
|
@@ -1254,11 +1641,14 @@ function getRuntimeWebSocket() {
|
|
|
1254
1641
|
return globalThis.WebSocket ?? null;
|
|
1255
1642
|
}
|
|
1256
1643
|
function isJumpRequestMessage(message) {
|
|
1257
|
-
return message.type === "jump:request" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.markerId === "string" && (message.boundary === void 0 || message.boundary === "before" || message.boundary === "after") && (message.strategy === void 0 || message.strategy === "fast-forward" || message.strategy === "warp");
|
|
1644
|
+
return message.type === "jump:request" && typeof message.sessionId === "string" && typeof message.requestId === "number" && typeof message.markerId === "string" && (message.story === void 0 || typeof message.story === "string") && (message.boundary === void 0 || message.boundary === "before" || message.boundary === "after") && (message.strategy === void 0 || message.strategy === "fast-forward" || message.strategy === "warp");
|
|
1258
1645
|
}
|
|
1259
1646
|
function isRouteRequestMessage(message) {
|
|
1260
1647
|
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));
|
|
1261
1648
|
}
|
|
1649
|
+
function isUiReplaceMessage(message) {
|
|
1650
|
+
return message.type === "ui:replace" && typeof message.sessionId === "string";
|
|
1651
|
+
}
|
|
1262
1652
|
function sendRuntimeDebugMessage(socket, message) {
|
|
1263
1653
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1264
1654
|
if (!RuntimeWebSocket || socket.readyState !== RuntimeWebSocket.OPEN) {
|
|
@@ -1279,18 +1669,37 @@ function flushBufferedRequestMessages(socket, sessionId) {
|
|
|
1279
1669
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1280
1670
|
}
|
|
1281
1671
|
}
|
|
1672
|
+
async function syncRuntimeDebugVariablesSnapshotSafe(reason) {
|
|
1673
|
+
try {
|
|
1674
|
+
await syncRuntimeDebugVariablesSnapshot(reason);
|
|
1675
|
+
} catch (error) {
|
|
1676
|
+
console.error("[debug] failed to sync runtime variables snapshot:", error);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1282
1679
|
function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
1680
|
+
if (isUiReplaceMessage(message)) {
|
|
1681
|
+
try {
|
|
1682
|
+
replaceUiData(message.data);
|
|
1683
|
+
} catch (error) {
|
|
1684
|
+
console.error("[debug] failed to replace runtime UI data:", error);
|
|
1685
|
+
}
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1283
1688
|
const controller = currentController;
|
|
1284
1689
|
if (!controller) {
|
|
1285
1690
|
bufferRequestMessage(message);
|
|
1286
1691
|
return;
|
|
1287
1692
|
}
|
|
1288
1693
|
if (isJumpRequestMessage(message)) {
|
|
1694
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1289
1695
|
const runJump = message.strategy === "warp" ? controller.warp({
|
|
1290
1696
|
markerId: message.markerId,
|
|
1697
|
+
story: message.story,
|
|
1291
1698
|
boundary: message.boundary
|
|
1292
|
-
}).then(() => true) : controller.restoreCheckpoint(message.markerId
|
|
1293
|
-
|
|
1699
|
+
}).then(() => true) : controller.restoreCheckpoint(message.markerId, {
|
|
1700
|
+
story: message.story
|
|
1701
|
+
});
|
|
1702
|
+
void runJump.then(async (restored) => {
|
|
1294
1703
|
if (!restored) {
|
|
1295
1704
|
sendRuntimeDebugMessage(socket, {
|
|
1296
1705
|
type: "jump:error",
|
|
@@ -1299,6 +1708,7 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1299
1708
|
markerId: message.markerId,
|
|
1300
1709
|
error: "Checkpoint not found"
|
|
1301
1710
|
});
|
|
1711
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1302
1712
|
return;
|
|
1303
1713
|
}
|
|
1304
1714
|
sendRuntimeDebugMessage(socket, {
|
|
@@ -1307,7 +1717,8 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1307
1717
|
requestId: message.requestId,
|
|
1308
1718
|
markerId: message.markerId
|
|
1309
1719
|
});
|
|
1310
|
-
|
|
1720
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-done");
|
|
1721
|
+
}).catch(async (error) => {
|
|
1311
1722
|
sendRuntimeDebugMessage(socket, {
|
|
1312
1723
|
type: "jump:error",
|
|
1313
1724
|
sessionId,
|
|
@@ -1315,17 +1726,22 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1315
1726
|
markerId: message.markerId,
|
|
1316
1727
|
error: error instanceof Error ? error.message : String(error)
|
|
1317
1728
|
});
|
|
1729
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1730
|
+
}).finally(() => {
|
|
1731
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1318
1732
|
});
|
|
1319
1733
|
return;
|
|
1320
1734
|
}
|
|
1321
|
-
|
|
1735
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1736
|
+
void controller.switchRoute(message.page, message.params).then(async () => {
|
|
1322
1737
|
sendRuntimeDebugMessage(socket, {
|
|
1323
1738
|
type: "route:done",
|
|
1324
1739
|
sessionId,
|
|
1325
1740
|
requestId: message.requestId,
|
|
1326
1741
|
page: message.page
|
|
1327
1742
|
});
|
|
1328
|
-
|
|
1743
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-done");
|
|
1744
|
+
}).catch(async (error) => {
|
|
1329
1745
|
sendRuntimeDebugMessage(socket, {
|
|
1330
1746
|
type: "route:error",
|
|
1331
1747
|
sessionId,
|
|
@@ -1333,6 +1749,9 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1333
1749
|
page: message.page,
|
|
1334
1750
|
error: error instanceof Error ? error.message : String(error)
|
|
1335
1751
|
});
|
|
1752
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-error");
|
|
1753
|
+
}).finally(() => {
|
|
1754
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1336
1755
|
});
|
|
1337
1756
|
}
|
|
1338
1757
|
async function readDebugParams() {
|
|
@@ -1357,6 +1776,7 @@ async function stopRuntimeDebugSession() {
|
|
|
1357
1776
|
const connection = currentConnection;
|
|
1358
1777
|
currentConnection = null;
|
|
1359
1778
|
currentController = null;
|
|
1779
|
+
resetRuntimeDebugVariableMonitor();
|
|
1360
1780
|
clearBufferedRequestMessages();
|
|
1361
1781
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1362
1782
|
await stopDebugSession();
|
|
@@ -1403,6 +1823,13 @@ async function startRuntimeDebugSession() {
|
|
|
1403
1823
|
}
|
|
1404
1824
|
}).then((controller) => {
|
|
1405
1825
|
currentController = controller;
|
|
1826
|
+
setRuntimeDebugVariableMessageSender((message) => {
|
|
1827
|
+
sendRuntimeDebugMessage(socket, {
|
|
1828
|
+
...message,
|
|
1829
|
+
sessionId
|
|
1830
|
+
});
|
|
1831
|
+
});
|
|
1832
|
+
void syncRuntimeDebugVariablesSnapshotSafe("init");
|
|
1406
1833
|
flushBufferedRequestMessages(socket, sessionId);
|
|
1407
1834
|
}).catch((error) => {
|
|
1408
1835
|
console.error("[debug] failed to start runtime debug session:", error);
|
|
@@ -1415,6 +1842,7 @@ async function startRuntimeDebugSession() {
|
|
|
1415
1842
|
}
|
|
1416
1843
|
currentConnection = null;
|
|
1417
1844
|
currentController = null;
|
|
1845
|
+
resetRuntimeDebugVariableMonitor();
|
|
1418
1846
|
clearBufferedRequestMessages();
|
|
1419
1847
|
void stopDebugSession();
|
|
1420
1848
|
};
|
|
@@ -1441,6 +1869,10 @@ async function startRuntimeDebugSession() {
|
|
|
1441
1869
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1442
1870
|
return;
|
|
1443
1871
|
}
|
|
1872
|
+
if (isUiReplaceMessage(message)) {
|
|
1873
|
+
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1444
1876
|
if (message.type && message.type !== "session:init") {
|
|
1445
1877
|
console.debug("[debug] runtime received message:", message);
|
|
1446
1878
|
}
|
|
@@ -1552,13 +1984,13 @@ async function terminateCurrentScenario() {
|
|
|
1552
1984
|
await executePluginCommand("scenario", {
|
|
1553
1985
|
subCommand: "terminateStory"
|
|
1554
1986
|
});
|
|
1555
|
-
|
|
1987
|
+
await clearLocalDebugSessionRuntimeState();
|
|
1556
1988
|
} catch (error) {
|
|
1557
1989
|
console.error("Failed to terminate scenario:", error);
|
|
1558
1990
|
}
|
|
1559
1991
|
}
|
|
1560
1992
|
async function startScenarioSession(session, config) {
|
|
1561
|
-
|
|
1993
|
+
await clearLocalDebugSessionRuntimeState();
|
|
1562
1994
|
for (const story of config.stories) {
|
|
1563
1995
|
if (!isCurrentScenarioSession(session)) return;
|
|
1564
1996
|
try {
|
|
@@ -1674,49 +2106,31 @@ function useScenario(stories, startName, entryName, goNextOnLoad = false) {
|
|
|
1674
2106
|
|
|
1675
2107
|
// src/hooks/useSoundEffect.ts
|
|
1676
2108
|
var import_react4 = require("react");
|
|
1677
|
-
var LOADED_SOUNDS = /* @__PURE__ */ new Set();
|
|
1678
2109
|
function useSoundEffect(src) {
|
|
1679
2110
|
(0, import_react4.useEffect)(() => {
|
|
1680
|
-
const loadSound = async () => {
|
|
1681
|
-
try {
|
|
1682
|
-
await executePluginCommand("audio", {
|
|
1683
|
-
subCommand: "load",
|
|
1684
|
-
name: src,
|
|
1685
|
-
src
|
|
1686
|
-
});
|
|
1687
|
-
} catch (error) {
|
|
1688
|
-
console.error(`Failed to load sound effect ${src}:`, error);
|
|
1689
|
-
}
|
|
1690
|
-
LOADED_SOUNDS.add(src);
|
|
1691
|
-
};
|
|
1692
|
-
let needRelease = false;
|
|
1693
|
-
if (!LOADED_SOUNDS.has(src)) {
|
|
1694
|
-
void loadSound();
|
|
1695
|
-
needRelease = true;
|
|
1696
|
-
}
|
|
1697
2111
|
return () => {
|
|
1698
|
-
|
|
1699
|
-
|
|
2112
|
+
try {
|
|
2113
|
+
if (src) {
|
|
1700
2114
|
executePluginCommand("audio", {
|
|
1701
2115
|
subCommand: "release",
|
|
1702
|
-
name: src
|
|
2116
|
+
name: src,
|
|
2117
|
+
silentFail: true
|
|
1703
2118
|
});
|
|
1704
|
-
} catch (error) {
|
|
1705
|
-
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1706
2119
|
}
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
if (needRelease) {
|
|
1710
|
-
releaseSound();
|
|
2120
|
+
} catch (error) {
|
|
2121
|
+
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1711
2122
|
}
|
|
1712
2123
|
};
|
|
1713
2124
|
}, [src]);
|
|
1714
2125
|
return (0, import_react4.useCallback)(() => {
|
|
1715
2126
|
try {
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
2127
|
+
if (src) {
|
|
2128
|
+
executePluginCommand("audio", {
|
|
2129
|
+
subCommand: "loadAndPlay",
|
|
2130
|
+
name: src,
|
|
2131
|
+
src
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
1720
2134
|
} catch (error) {
|
|
1721
2135
|
console.error(`Failed to play sound effect ${src}:`, error);
|
|
1722
2136
|
}
|
|
@@ -1725,25 +2139,25 @@ function useSoundEffect(src) {
|
|
|
1725
2139
|
|
|
1726
2140
|
// src/hooks/useStage.ts
|
|
1727
2141
|
var import_react5 = require("react");
|
|
1728
|
-
var
|
|
2142
|
+
var import_valtio4 = require("valtio");
|
|
1729
2143
|
var SKIP_INTERVAL_MS = 80;
|
|
1730
2144
|
var DEFAULT_FAST_FORWARD_STEP_LIMIT = 1e4;
|
|
1731
2145
|
var DEFAULT_FAST_FORWARD_TIME_LIMIT_MS = 3e3;
|
|
1732
2146
|
var autoRuntime = {
|
|
1733
2147
|
defaultTailMs: 0
|
|
1734
2148
|
};
|
|
1735
|
-
var skipState = (0,
|
|
1736
|
-
var autoState = (0,
|
|
1737
|
-
var fastForwardState = (0,
|
|
1738
|
-
var warpState = (0,
|
|
2149
|
+
var skipState = (0, import_valtio4.proxy)({ active: false });
|
|
2150
|
+
var autoState = (0, import_valtio4.proxy)({ active: false });
|
|
2151
|
+
var fastForwardState = (0, import_valtio4.proxy)({ active: false });
|
|
2152
|
+
var warpState = (0, import_valtio4.proxy)({ active: false });
|
|
1739
2153
|
function useIsSkipping() {
|
|
1740
|
-
return (0,
|
|
2154
|
+
return (0, import_valtio4.useSnapshot)(skipState).active;
|
|
1741
2155
|
}
|
|
1742
2156
|
function useIsAutoing() {
|
|
1743
|
-
return (0,
|
|
2157
|
+
return (0, import_valtio4.useSnapshot)(autoState).active;
|
|
1744
2158
|
}
|
|
1745
2159
|
function useIsSeeking() {
|
|
1746
|
-
return (0,
|
|
2160
|
+
return (0, import_valtio4.useSnapshot)(fastForwardState).active;
|
|
1747
2161
|
}
|
|
1748
2162
|
function getSeekingType() {
|
|
1749
2163
|
if (warpState.active) return "warp";
|