@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.mjs
CHANGED
|
@@ -19,6 +19,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
19
19
|
// src/lib.ts
|
|
20
20
|
var lib_exports = {};
|
|
21
21
|
__export(lib_exports, {
|
|
22
|
+
DEBUG_EMPTY_PAGE: () => DEBUG_EMPTY_PAGE,
|
|
22
23
|
OverlayParamsContext: () => OverlayParamsContext,
|
|
23
24
|
PageParamsContext: () => PageParamsContext,
|
|
24
25
|
StageContextProvider: () => StageContextProvider,
|
|
@@ -31,6 +32,7 @@ __export(lib_exports, {
|
|
|
31
32
|
createStackNavigator: () => createStackNavigator,
|
|
32
33
|
createStage: () => createStage,
|
|
33
34
|
createStaticNavigation: () => createStaticNavigation,
|
|
35
|
+
ensureArchiveVariableDefaults: () => ensureArchiveVariableDefaults,
|
|
34
36
|
executeNodeCommand: () => executeNodeCommand,
|
|
35
37
|
executePluginCommand: () => executePluginCommand,
|
|
36
38
|
fastForwardState: () => fastForwardState,
|
|
@@ -38,11 +40,16 @@ __export(lib_exports, {
|
|
|
38
40
|
getNavigator: () => getNavigator,
|
|
39
41
|
getSeekingType: () => getSeekingType,
|
|
40
42
|
getStageSize: () => getStageSize,
|
|
43
|
+
getUiData: () => getUiData,
|
|
41
44
|
globalEventListeners: () => globalEventListeners,
|
|
42
45
|
globalRequestAnimationFrameListeners: () => globalRequestAnimationFrameListeners,
|
|
46
|
+
initGlobalVariableDefaults: () => initGlobalVariableDefaults,
|
|
47
|
+
initUiData: () => initUiData,
|
|
48
|
+
loadVariablesDocument: () => loadVariablesDocument,
|
|
43
49
|
moyu: () => moyu_exports,
|
|
44
50
|
nextLine: () => nextLine,
|
|
45
51
|
registerAppStateAdapter: () => registerAppStateAdapter,
|
|
52
|
+
replaceUiData: () => replaceUiData,
|
|
46
53
|
setDefaultAutoTailMs: () => setDefaultAutoTailMs,
|
|
47
54
|
setWaiting: () => setWaiting,
|
|
48
55
|
skipState: () => skipState,
|
|
@@ -69,6 +76,7 @@ __export(lib_exports, {
|
|
|
69
76
|
useSkipCallback: () => useSkipCallback,
|
|
70
77
|
useSoundEffect: () => useSoundEffect,
|
|
71
78
|
useStageContext: () => useStageContext,
|
|
79
|
+
useUiData: () => useUiData,
|
|
72
80
|
warpState: () => warpState
|
|
73
81
|
});
|
|
74
82
|
|
|
@@ -393,6 +401,259 @@ function createRoot(options) {
|
|
|
393
401
|
};
|
|
394
402
|
}
|
|
395
403
|
|
|
404
|
+
// src/variables.ts
|
|
405
|
+
var VARIABLES_DATA_ASSET_PATH = "assets:///data/variables.json";
|
|
406
|
+
function normalizeVariableDefinitions(value) {
|
|
407
|
+
if (!Array.isArray(value)) {
|
|
408
|
+
return [];
|
|
409
|
+
}
|
|
410
|
+
return value.flatMap((entry) => {
|
|
411
|
+
if (!entry || typeof entry !== "object") {
|
|
412
|
+
return [];
|
|
413
|
+
}
|
|
414
|
+
const definition = entry;
|
|
415
|
+
if (typeof definition.id !== "string" || definition.id.length === 0) {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
return [{ id: definition.id, defaultValue: definition.defaultValue }];
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
async function loadVariablesDocument() {
|
|
422
|
+
let rawText;
|
|
423
|
+
try {
|
|
424
|
+
rawText = await executePluginCommand("system", {
|
|
425
|
+
subCommand: "readFile",
|
|
426
|
+
path: VARIABLES_DATA_ASSET_PATH
|
|
427
|
+
});
|
|
428
|
+
} catch {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
let rawData;
|
|
432
|
+
try {
|
|
433
|
+
rawData = JSON.parse(rawText);
|
|
434
|
+
} catch (error) {
|
|
435
|
+
console.error("Failed to parse variable defaults data:", error);
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
if (!rawData || typeof rawData !== "object") {
|
|
439
|
+
return {
|
|
440
|
+
archive: [],
|
|
441
|
+
global: []
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
const document = rawData;
|
|
445
|
+
return {
|
|
446
|
+
archive: normalizeVariableDefinitions(document.archive),
|
|
447
|
+
global: normalizeVariableDefinitions(document.global)
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function toVariableRecord(value) {
|
|
451
|
+
if (value instanceof Map) {
|
|
452
|
+
return Object.fromEntries(value);
|
|
453
|
+
}
|
|
454
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
455
|
+
return {};
|
|
456
|
+
}
|
|
457
|
+
return value;
|
|
458
|
+
}
|
|
459
|
+
async function ensureVariableDefaults(scope) {
|
|
460
|
+
const document = await loadVariablesDocument();
|
|
461
|
+
if (!document) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const definitions = document[scope];
|
|
465
|
+
if (definitions.length === 0) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const currentVariables = toVariableRecord(
|
|
469
|
+
await executePluginCommand(
|
|
470
|
+
"scenario",
|
|
471
|
+
scope === "global" ? { subCommand: "getPermanentVariables" } : { subCommand: "getVariables" }
|
|
472
|
+
)
|
|
473
|
+
);
|
|
474
|
+
const missingVariables = {};
|
|
475
|
+
for (const definition of definitions) {
|
|
476
|
+
if (!Object.hasOwn(currentVariables, definition.id)) {
|
|
477
|
+
missingVariables[definition.id] = definition.defaultValue;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (Object.keys(missingVariables).length === 0) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
await executePluginCommand(
|
|
484
|
+
"scenario",
|
|
485
|
+
scope === "global" ? {
|
|
486
|
+
subCommand: "setPermanentVariables",
|
|
487
|
+
variables: missingVariables
|
|
488
|
+
} : {
|
|
489
|
+
subCommand: "setVariables",
|
|
490
|
+
variables: missingVariables
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
reportRuntimeDebugVariablesSet(scope, missingVariables);
|
|
494
|
+
}
|
|
495
|
+
async function initGlobalVariableDefaults() {
|
|
496
|
+
await ensureVariableDefaults("global");
|
|
497
|
+
}
|
|
498
|
+
async function ensureArchiveVariableDefaults() {
|
|
499
|
+
await ensureVariableDefaults("archive");
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/debug/variableMonitor.ts
|
|
503
|
+
var sendRuntimeDebugVariableMessage = null;
|
|
504
|
+
var allowlistCache = null;
|
|
505
|
+
var allowlistPromise = null;
|
|
506
|
+
var variableEmissionSuspended = false;
|
|
507
|
+
function createEmptyAllowlist() {
|
|
508
|
+
return {
|
|
509
|
+
archive: /* @__PURE__ */ new Set(),
|
|
510
|
+
global: /* @__PURE__ */ new Set()
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function isJsonValue(value) {
|
|
514
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
if (Array.isArray(value)) {
|
|
518
|
+
return value.every((item) => isJsonValue(item));
|
|
519
|
+
}
|
|
520
|
+
if (!value || typeof value !== "object") {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
return Object.values(value).every((item) => isJsonValue(item));
|
|
524
|
+
}
|
|
525
|
+
async function loadRuntimeDebugVariableAllowlist() {
|
|
526
|
+
const document = await loadVariablesDocument();
|
|
527
|
+
if (!document) {
|
|
528
|
+
return createEmptyAllowlist();
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
archive: new Set(document.archive.map((def) => def.id)),
|
|
532
|
+
global: new Set(document.global.map((def) => def.id))
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function toJsonValueRecord(value) {
|
|
536
|
+
if (value instanceof Map) {
|
|
537
|
+
return Object.fromEntries(
|
|
538
|
+
Array.from(value.entries()).flatMap(([key, entryValue]) => {
|
|
539
|
+
if (typeof key !== "string" || !isJsonValue(entryValue)) {
|
|
540
|
+
return [];
|
|
541
|
+
}
|
|
542
|
+
return [[key, entryValue]];
|
|
543
|
+
})
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
547
|
+
return {};
|
|
548
|
+
}
|
|
549
|
+
return Object.fromEntries(
|
|
550
|
+
Object.entries(value).flatMap(([key, entryValue]) => {
|
|
551
|
+
if (!isJsonValue(entryValue)) {
|
|
552
|
+
return [];
|
|
553
|
+
}
|
|
554
|
+
return [[key, entryValue]];
|
|
555
|
+
})
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
function filterVariablesByAllowlist(scope, values, allowlist) {
|
|
559
|
+
const allowedIds = allowlist[scope];
|
|
560
|
+
if (allowedIds.size === 0) {
|
|
561
|
+
return {};
|
|
562
|
+
}
|
|
563
|
+
return Object.fromEntries(
|
|
564
|
+
Object.entries(values).flatMap(([key, value]) => allowedIds.has(key) ? [[key, value]] : [])
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
function hasRecordEntries(value) {
|
|
568
|
+
return !!value && Object.keys(value).length > 0;
|
|
569
|
+
}
|
|
570
|
+
async function ensureRuntimeDebugVariableAllowlist() {
|
|
571
|
+
if (allowlistCache) {
|
|
572
|
+
return allowlistCache;
|
|
573
|
+
}
|
|
574
|
+
if (!allowlistPromise) {
|
|
575
|
+
allowlistPromise = loadRuntimeDebugVariableAllowlist().then((allowlist) => {
|
|
576
|
+
allowlistCache = allowlist;
|
|
577
|
+
return allowlist;
|
|
578
|
+
}).finally(() => {
|
|
579
|
+
allowlistPromise = null;
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return allowlistPromise;
|
|
583
|
+
}
|
|
584
|
+
async function emitRuntimeDebugVariablesChanged(scope, variables) {
|
|
585
|
+
const sender = sendRuntimeDebugVariableMessage;
|
|
586
|
+
if (!sender || variableEmissionSuspended) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const allowlist = await ensureRuntimeDebugVariableAllowlist();
|
|
590
|
+
if (!sendRuntimeDebugVariableMessage || sendRuntimeDebugVariableMessage !== sender || variableEmissionSuspended) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const filtered = filterVariablesByAllowlist(scope, variables, allowlist);
|
|
594
|
+
if (!hasRecordEntries(filtered)) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
sender({
|
|
598
|
+
type: "variables:changed",
|
|
599
|
+
archiveSet: scope === "archive" ? filtered : void 0,
|
|
600
|
+
globalSet: scope === "global" ? filtered : void 0
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
function setRuntimeDebugVariableMessageSender(sender) {
|
|
604
|
+
sendRuntimeDebugVariableMessage = sender;
|
|
605
|
+
if (sender) {
|
|
606
|
+
void ensureRuntimeDebugVariableAllowlist();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function setRuntimeDebugVariableEmissionSuspended(suspended) {
|
|
610
|
+
variableEmissionSuspended = suspended;
|
|
611
|
+
}
|
|
612
|
+
function resetRuntimeDebugVariableMonitor() {
|
|
613
|
+
sendRuntimeDebugVariableMessage = null;
|
|
614
|
+
allowlistCache = null;
|
|
615
|
+
allowlistPromise = null;
|
|
616
|
+
variableEmissionSuspended = false;
|
|
617
|
+
}
|
|
618
|
+
function reportRuntimeDebugVariableSet(scope, key, value) {
|
|
619
|
+
if (key.length === 0) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
void emitRuntimeDebugVariablesChanged(scope, {
|
|
623
|
+
[key]: value
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
function reportRuntimeDebugVariablesSet(scope, variables) {
|
|
627
|
+
if (Object.keys(variables).length === 0) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
void emitRuntimeDebugVariablesChanged(scope, variables);
|
|
631
|
+
}
|
|
632
|
+
async function syncRuntimeDebugVariablesSnapshot(reason) {
|
|
633
|
+
const sender = sendRuntimeDebugVariableMessage;
|
|
634
|
+
if (!sender) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const [allowlist, archiveVariables2, globalVariables2] = await Promise.all([
|
|
638
|
+
ensureRuntimeDebugVariableAllowlist(),
|
|
639
|
+
executePluginCommand("scenario", {
|
|
640
|
+
subCommand: "getVariables"
|
|
641
|
+
}),
|
|
642
|
+
executePluginCommand("scenario", {
|
|
643
|
+
subCommand: "getPermanentVariables"
|
|
644
|
+
})
|
|
645
|
+
]);
|
|
646
|
+
if (!sendRuntimeDebugVariableMessage || sendRuntimeDebugVariableMessage !== sender) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
sender({
|
|
650
|
+
type: "variables:snapshot",
|
|
651
|
+
reason,
|
|
652
|
+
archive: filterVariablesByAllowlist("archive", toJsonValueRecord(archiveVariables2), allowlist),
|
|
653
|
+
global: filterVariablesByAllowlist("global", toJsonValueRecord(globalVariables2), allowlist)
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
396
657
|
// src/sandbox.ts
|
|
397
658
|
var JS_GLOBAL_KEYS = new Set(Object.getOwnPropertyNames(globalThis));
|
|
398
659
|
var JS_GLOBAL_KEYS_EXCLUDED = /* @__PURE__ */ new Set(["window", "globalThis", "LOCAL", "ARCHIVE", "GLOBAL"]);
|
|
@@ -443,6 +704,7 @@ var archiveVariables = new Proxy(
|
|
|
443
704
|
name: key,
|
|
444
705
|
value
|
|
445
706
|
});
|
|
707
|
+
reportRuntimeDebugVariableSet("archive", key, value);
|
|
446
708
|
return true;
|
|
447
709
|
}
|
|
448
710
|
return false;
|
|
@@ -468,6 +730,7 @@ var globalVariables = new Proxy(
|
|
|
468
730
|
key,
|
|
469
731
|
value
|
|
470
732
|
});
|
|
733
|
+
reportRuntimeDebugVariableSet("global", key, value);
|
|
471
734
|
return true;
|
|
472
735
|
}
|
|
473
736
|
return false;
|
|
@@ -475,7 +738,7 @@ var globalVariables = new Proxy(
|
|
|
475
738
|
}
|
|
476
739
|
);
|
|
477
740
|
function safeEval(code, sandbox) {
|
|
478
|
-
const
|
|
741
|
+
const proxy5 = new Proxy(sandbox, {
|
|
479
742
|
has(target, key) {
|
|
480
743
|
if (typeof key === "string" && JS_GLOBAL_KEYS.has(key)) {
|
|
481
744
|
return false;
|
|
@@ -483,7 +746,7 @@ function safeEval(code, sandbox) {
|
|
|
483
746
|
return key in target || key === "LOCAL" || key === "ARCHIVE" || key === "GLOBAL" || key === "window" || key === "globalThis";
|
|
484
747
|
},
|
|
485
748
|
get(target, key) {
|
|
486
|
-
if (key === "window" || key === "globalThis") return
|
|
749
|
+
if (key === "window" || key === "globalThis") return proxy5;
|
|
487
750
|
if (key === "LOCAL") return localVariables;
|
|
488
751
|
if (key === "ARCHIVE") return archiveVariables;
|
|
489
752
|
if (key === "GLOBAL") return globalVariables;
|
|
@@ -495,7 +758,7 @@ function safeEval(code, sandbox) {
|
|
|
495
758
|
return true;
|
|
496
759
|
}
|
|
497
760
|
});
|
|
498
|
-
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(
|
|
761
|
+
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(proxy5)(proxy5);
|
|
499
762
|
}
|
|
500
763
|
globalThis.__moyu_eval_sandbox = (code) => {
|
|
501
764
|
try {
|
|
@@ -683,6 +946,7 @@ import { proxy, useSnapshot } from "valtio";
|
|
|
683
946
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
684
947
|
var PageParamsContext = createContext(void 0);
|
|
685
948
|
var OverlayParamsContext = createContext(void 0);
|
|
949
|
+
var DEBUG_EMPTY_PAGE = "debug-empty";
|
|
686
950
|
var overlayIdCounter = 0;
|
|
687
951
|
var generateOverlayId = () => {
|
|
688
952
|
return `overlay-${++overlayIdCounter}-${Date.now()}`;
|
|
@@ -710,6 +974,12 @@ function createStackNavigator(options) {
|
|
|
710
974
|
for (const [key, config] of Object.entries(options.pages)) {
|
|
711
975
|
normalizedPages[key] = normalizeDescriptor(config);
|
|
712
976
|
}
|
|
977
|
+
if (normalizedPages[DEBUG_EMPTY_PAGE]) {
|
|
978
|
+
throw new Error(`Navigation Error: Page name "${DEBUG_EMPTY_PAGE}" is reserved.`);
|
|
979
|
+
}
|
|
980
|
+
normalizedPages[DEBUG_EMPTY_PAGE] = {
|
|
981
|
+
component: () => null
|
|
982
|
+
};
|
|
713
983
|
const normalizedOverlays = {};
|
|
714
984
|
if (options.overlays) {
|
|
715
985
|
for (const [key, config] of Object.entries(options.overlays)) {
|
|
@@ -739,6 +1009,9 @@ function createStackNavigator(options) {
|
|
|
739
1009
|
hasPage: (page) => {
|
|
740
1010
|
return normalizedPages[page] !== void 0;
|
|
741
1011
|
},
|
|
1012
|
+
hasOverlay: (overlay) => {
|
|
1013
|
+
return normalizedOverlays[overlay] !== void 0;
|
|
1014
|
+
},
|
|
742
1015
|
goBack: () => {
|
|
743
1016
|
console.warn("goBack() not implemented yet");
|
|
744
1017
|
},
|
|
@@ -826,6 +1099,7 @@ var debugState = proxy2({
|
|
|
826
1099
|
active: false,
|
|
827
1100
|
checkpoints: {},
|
|
828
1101
|
currentCursor: null,
|
|
1102
|
+
currentStory: null,
|
|
829
1103
|
restoring: false,
|
|
830
1104
|
lastError: null
|
|
831
1105
|
});
|
|
@@ -869,9 +1143,37 @@ function reportDebugSessionError(error) {
|
|
|
869
1143
|
function clearLocalRuntimeState() {
|
|
870
1144
|
debugState.checkpoints = {};
|
|
871
1145
|
debugState.currentCursor = null;
|
|
1146
|
+
debugState.currentStory = null;
|
|
872
1147
|
debugState.restoring = false;
|
|
873
1148
|
debugState.lastError = null;
|
|
874
1149
|
}
|
|
1150
|
+
async function restartJumpStoryFromHead(targetStory, currentStory) {
|
|
1151
|
+
debugState.checkpoints = {};
|
|
1152
|
+
debugState.currentCursor = null;
|
|
1153
|
+
debugState.currentStory = null;
|
|
1154
|
+
if (targetStory) {
|
|
1155
|
+
if (appStateAdapter?.restartStoryFromHead) {
|
|
1156
|
+
await appStateAdapter.restartStoryFromHead({
|
|
1157
|
+
story: targetStory,
|
|
1158
|
+
entry: "entry"
|
|
1159
|
+
});
|
|
1160
|
+
} else if (currentStory === targetStory && appStateAdapter?.restartCurrentStoryFromHead) {
|
|
1161
|
+
await appStateAdapter.restartCurrentStoryFromHead();
|
|
1162
|
+
} else {
|
|
1163
|
+
throw new Error("Restarting the target story from head is not supported by the app state adapter");
|
|
1164
|
+
}
|
|
1165
|
+
debugState.currentCursor = await executeScenarioCommand({
|
|
1166
|
+
subCommand: "getExecutionCursor"
|
|
1167
|
+
});
|
|
1168
|
+
debugState.currentStory = debugState.currentCursor?.story ?? targetStory;
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
if (!appStateAdapter?.restartCurrentStoryFromHead) {
|
|
1172
|
+
throw new Error("Restarting the current story from head is not supported by the app state adapter");
|
|
1173
|
+
}
|
|
1174
|
+
await appStateAdapter.restartCurrentStoryFromHead();
|
|
1175
|
+
debugState.currentCursor = null;
|
|
1176
|
+
}
|
|
875
1177
|
async function doSettleActiveSeek(op, clearSlot, error) {
|
|
876
1178
|
if (!op) {
|
|
877
1179
|
return;
|
|
@@ -900,6 +1202,11 @@ async function settleActiveWarp(error) {
|
|
|
900
1202
|
activeWarp = null;
|
|
901
1203
|
}, error);
|
|
902
1204
|
}
|
|
1205
|
+
async function clearLocalDebugSessionRuntimeState() {
|
|
1206
|
+
await settleActiveFastForward(new Error("Debug session runtime state cleared"));
|
|
1207
|
+
await settleActiveWarp(new Error("Debug session runtime state cleared"));
|
|
1208
|
+
clearLocalRuntimeState();
|
|
1209
|
+
}
|
|
903
1210
|
async function clearRemoteCheckpoints() {
|
|
904
1211
|
await executeScenarioCommand({ subCommand: "clearCheckpoints" });
|
|
905
1212
|
}
|
|
@@ -924,6 +1231,7 @@ async function syncLocalWarpCheckpoint(targetMarkerId) {
|
|
|
924
1231
|
appState: appStateAdapter ? await appStateAdapter.capture() : void 0
|
|
925
1232
|
};
|
|
926
1233
|
debugState.currentCursor = checkpointCursor;
|
|
1234
|
+
debugState.currentStory = checkpointCursor.story;
|
|
927
1235
|
debugState.checkpoints[targetMarkerId] = checkpoint;
|
|
928
1236
|
await currentConfig.onMarkerEnter(checkpoint);
|
|
929
1237
|
}
|
|
@@ -947,9 +1255,16 @@ function notifyMarkerEnter(checkpoint) {
|
|
|
947
1255
|
reportDebugSessionError(error);
|
|
948
1256
|
}
|
|
949
1257
|
}
|
|
950
|
-
async function prepareJumpStart(markerId) {
|
|
1258
|
+
async function prepareJumpStart(markerId, options) {
|
|
1259
|
+
const currentStory = debugState.currentStory ?? debugState.currentCursor?.story ?? null;
|
|
1260
|
+
const targetStory = options?.story;
|
|
1261
|
+
let restartedFromHead = false;
|
|
1262
|
+
if (targetStory && targetStory !== currentStory) {
|
|
1263
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
1264
|
+
restartedFromHead = true;
|
|
1265
|
+
}
|
|
951
1266
|
const checkpoint = debugState.checkpoints[markerId];
|
|
952
|
-
if (checkpoint) {
|
|
1267
|
+
if (!restartedFromHead && checkpoint && (!targetStory || checkpoint.cursor.story === targetStory)) {
|
|
953
1268
|
const restored2 = await executeScenarioCommand({
|
|
954
1269
|
subCommand: "restoreCheckpoint",
|
|
955
1270
|
key: markerId
|
|
@@ -961,6 +1276,7 @@ async function prepareJumpStart(markerId) {
|
|
|
961
1276
|
await appStateAdapter.restore(checkpoint.appState);
|
|
962
1277
|
}
|
|
963
1278
|
debugState.currentCursor = checkpoint.cursor;
|
|
1279
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
964
1280
|
return false;
|
|
965
1281
|
}
|
|
966
1282
|
const lookup = await executeScenarioCommand({
|
|
@@ -968,16 +1284,15 @@ async function prepareJumpStart(markerId) {
|
|
|
968
1284
|
key: markerId
|
|
969
1285
|
});
|
|
970
1286
|
if (!lookup.markerExists) {
|
|
971
|
-
throw new Error(
|
|
1287
|
+
throw new Error(
|
|
1288
|
+
targetStory ? `Marker ${markerId} is not available in story ${targetStory}` : `Marker ${markerId} is not available in the current story`
|
|
1289
|
+
);
|
|
972
1290
|
}
|
|
973
1291
|
const startCheckpointKey = lookup.checkpointKey ?? null;
|
|
974
1292
|
if (!startCheckpointKey) {
|
|
975
|
-
if (!
|
|
976
|
-
|
|
1293
|
+
if (!restartedFromHead) {
|
|
1294
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
977
1295
|
}
|
|
978
|
-
await appStateAdapter.restartCurrentStoryFromHead();
|
|
979
|
-
debugState.checkpoints = {};
|
|
980
|
-
debugState.currentCursor = null;
|
|
981
1296
|
return true;
|
|
982
1297
|
}
|
|
983
1298
|
const startCheckpoint = debugState.checkpoints[startCheckpointKey];
|
|
@@ -995,6 +1310,7 @@ async function prepareJumpStart(markerId) {
|
|
|
995
1310
|
await appStateAdapter.restore(startCheckpoint.appState);
|
|
996
1311
|
}
|
|
997
1312
|
debugState.currentCursor = startCheckpoint.cursor;
|
|
1313
|
+
debugState.currentStory = startCheckpoint.cursor.story;
|
|
998
1314
|
return true;
|
|
999
1315
|
}
|
|
1000
1316
|
function handleMarkerEnter(marker) {
|
|
@@ -1007,6 +1323,7 @@ function handleMarkerEnter(marker) {
|
|
|
1007
1323
|
appState: captureCheckpointAppStateSync()
|
|
1008
1324
|
};
|
|
1009
1325
|
debugState.currentCursor = checkpoint.cursor;
|
|
1326
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
1010
1327
|
debugState.checkpoints[marker.markerId] = checkpoint;
|
|
1011
1328
|
notifyMarkerEnter(checkpoint);
|
|
1012
1329
|
if (activeFastForward?.targetMarkerId === marker.markerId) {
|
|
@@ -1067,11 +1384,11 @@ async function runWarp(options) {
|
|
|
1067
1384
|
await completion;
|
|
1068
1385
|
}
|
|
1069
1386
|
var debugSessionController = {
|
|
1070
|
-
async restoreCheckpoint(markerId) {
|
|
1387
|
+
async restoreCheckpoint(markerId, options) {
|
|
1071
1388
|
debugState.restoring = true;
|
|
1072
1389
|
debugState.lastError = null;
|
|
1073
1390
|
try {
|
|
1074
|
-
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId));
|
|
1391
|
+
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId, options));
|
|
1075
1392
|
if (needsFastForward) {
|
|
1076
1393
|
await runFastForwardToMarker(markerId);
|
|
1077
1394
|
}
|
|
@@ -1087,7 +1404,7 @@ var debugSessionController = {
|
|
|
1087
1404
|
debugState.restoring = true;
|
|
1088
1405
|
debugState.lastError = null;
|
|
1089
1406
|
try {
|
|
1090
|
-
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId));
|
|
1407
|
+
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId, options));
|
|
1091
1408
|
if (needsWarp) {
|
|
1092
1409
|
await runWarp(options);
|
|
1093
1410
|
}
|
|
@@ -1098,14 +1415,26 @@ var debugSessionController = {
|
|
|
1098
1415
|
debugState.restoring = false;
|
|
1099
1416
|
}
|
|
1100
1417
|
},
|
|
1101
|
-
async
|
|
1418
|
+
async switchRoute(routeName, params) {
|
|
1102
1419
|
return enqueueDebugOperation(async () => {
|
|
1103
1420
|
debugState.lastError = null;
|
|
1104
1421
|
try {
|
|
1105
|
-
|
|
1106
|
-
|
|
1422
|
+
const navigator = getNavigator();
|
|
1423
|
+
if (navigator.hasPage(routeName)) {
|
|
1424
|
+
if (!appStateAdapter?.switchPage) {
|
|
1425
|
+
throw new Error("Page switching is not supported by the app state adapter");
|
|
1426
|
+
}
|
|
1427
|
+
await appStateAdapter.switchPage(routeName, params);
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
if (navigator.hasOverlay(routeName)) {
|
|
1431
|
+
if (!appStateAdapter?.switchOverlay) {
|
|
1432
|
+
throw new Error("Overlay switching is not supported by the app state adapter");
|
|
1433
|
+
}
|
|
1434
|
+
await appStateAdapter.switchOverlay(routeName, params);
|
|
1435
|
+
return;
|
|
1107
1436
|
}
|
|
1108
|
-
|
|
1437
|
+
throw new Error(`Route "${routeName}" not found`);
|
|
1109
1438
|
} catch (error) {
|
|
1110
1439
|
debugState.lastError = toErrorMessage(error);
|
|
1111
1440
|
throw error;
|
|
@@ -1170,6 +1499,7 @@ async function startDebugSession(config = {}) {
|
|
|
1170
1499
|
debugState.currentCursor = await executeScenarioCommand({
|
|
1171
1500
|
subCommand: "getExecutionCursor"
|
|
1172
1501
|
});
|
|
1502
|
+
debugState.currentStory = debugState.currentCursor?.story ?? null;
|
|
1173
1503
|
} catch (error) {
|
|
1174
1504
|
debugState.active = false;
|
|
1175
1505
|
clearLocalRuntimeState();
|
|
@@ -1206,22 +1536,6 @@ async function stopDebugSession() {
|
|
|
1206
1536
|
debugState.active = false;
|
|
1207
1537
|
clearLocalRuntimeState();
|
|
1208
1538
|
}
|
|
1209
|
-
function clearDebugSessionRuntimeState() {
|
|
1210
|
-
clearLocalRuntimeState();
|
|
1211
|
-
void settleActiveFastForward(new Error("Debug session runtime state cleared"));
|
|
1212
|
-
void settleActiveWarp(new Error("Debug session runtime state cleared"));
|
|
1213
|
-
if (!debugState.active) {
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
void enqueueDebugOperation(async () => {
|
|
1217
|
-
try {
|
|
1218
|
-
await clearRemoteCheckpoints();
|
|
1219
|
-
} catch (error) {
|
|
1220
|
-
debugState.lastError = toErrorMessage(error);
|
|
1221
|
-
await currentConfig.onError(error);
|
|
1222
|
-
}
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1225
1539
|
function useDebugSession() {
|
|
1226
1540
|
const snapshot = useSnapshot2(debugState);
|
|
1227
1541
|
return {
|
|
@@ -1230,10 +1544,83 @@ function useDebugSession() {
|
|
|
1230
1544
|
stopDebugSession,
|
|
1231
1545
|
restoreCheckpoint: debugSessionController.restoreCheckpoint,
|
|
1232
1546
|
warp: debugSessionController.warp,
|
|
1233
|
-
|
|
1547
|
+
switchRoute: debugSessionController.switchRoute
|
|
1234
1548
|
};
|
|
1235
1549
|
}
|
|
1236
1550
|
|
|
1551
|
+
// src/ui.ts
|
|
1552
|
+
import { proxy as proxy3, useSnapshot as useSnapshot3 } from "valtio";
|
|
1553
|
+
var UI_DATA_ASSET_PATH = "assets:///data/ui.json";
|
|
1554
|
+
var activeUiSchema = null;
|
|
1555
|
+
var uiDataState = proxy3({});
|
|
1556
|
+
var uiRuntimeState = proxy3({
|
|
1557
|
+
initialized: false,
|
|
1558
|
+
error: null
|
|
1559
|
+
});
|
|
1560
|
+
function applyUiData(nextData) {
|
|
1561
|
+
for (const key of Object.keys(uiDataState)) {
|
|
1562
|
+
delete uiDataState[key];
|
|
1563
|
+
}
|
|
1564
|
+
Object.assign(uiDataState, nextData);
|
|
1565
|
+
uiRuntimeState.initialized = true;
|
|
1566
|
+
uiRuntimeState.error = null;
|
|
1567
|
+
}
|
|
1568
|
+
async function initUiData(schema) {
|
|
1569
|
+
uiRuntimeState.initialized = false;
|
|
1570
|
+
uiRuntimeState.error = null;
|
|
1571
|
+
activeUiSchema = schema;
|
|
1572
|
+
let rawData;
|
|
1573
|
+
try {
|
|
1574
|
+
const rawText = await Promise.resolve(
|
|
1575
|
+
executePluginCommand("system", {
|
|
1576
|
+
subCommand: "readFile",
|
|
1577
|
+
path: UI_DATA_ASSET_PATH
|
|
1578
|
+
})
|
|
1579
|
+
);
|
|
1580
|
+
rawData = JSON.parse(rawText);
|
|
1581
|
+
} catch (error) {
|
|
1582
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1583
|
+
uiRuntimeState.error = message;
|
|
1584
|
+
throw new Error(`Failed to initialize UI data: ${message}`);
|
|
1585
|
+
}
|
|
1586
|
+
const parsed = schema.safeParse(rawData);
|
|
1587
|
+
if (!parsed.success) {
|
|
1588
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1589
|
+
throw new Error(`Invalid UI data: ${parsed.error.message}`);
|
|
1590
|
+
}
|
|
1591
|
+
applyUiData(parsed.data);
|
|
1592
|
+
}
|
|
1593
|
+
function replaceUiData(rawData) {
|
|
1594
|
+
if (!activeUiSchema) {
|
|
1595
|
+
throw new Error("UI data schema has not been initialized. Call initUiData() first.");
|
|
1596
|
+
}
|
|
1597
|
+
const parsed = activeUiSchema.safeParse(rawData);
|
|
1598
|
+
if (!parsed.success) {
|
|
1599
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1600
|
+
throw new Error(`Invalid replacement UI data: ${parsed.error.message}`);
|
|
1601
|
+
}
|
|
1602
|
+
applyUiData(parsed.data);
|
|
1603
|
+
}
|
|
1604
|
+
function getUiData(name) {
|
|
1605
|
+
if (!uiRuntimeState.initialized) {
|
|
1606
|
+
throw new Error("UI data has not been initialized. Call initUiData() before reading it.");
|
|
1607
|
+
}
|
|
1608
|
+
if (!(name in uiDataState)) {
|
|
1609
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1610
|
+
}
|
|
1611
|
+
return uiDataState[name];
|
|
1612
|
+
}
|
|
1613
|
+
function useUiData(name) {
|
|
1614
|
+
if (!uiRuntimeState.initialized) {
|
|
1615
|
+
throw new Error("UI data has not been initialized. Call initUiData() before rendering UI pages.");
|
|
1616
|
+
}
|
|
1617
|
+
const snapshot = useSnapshot3(uiDataState);
|
|
1618
|
+
if (!(name in snapshot)) {
|
|
1619
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1620
|
+
}
|
|
1621
|
+
return snapshot[name];
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1237
1624
|
// src/debug/runtime.ts
|
|
1238
1625
|
var currentConnection = null;
|
|
1239
1626
|
var currentController = null;
|
|
@@ -1242,11 +1629,14 @@ function getRuntimeWebSocket() {
|
|
|
1242
1629
|
return globalThis.WebSocket ?? null;
|
|
1243
1630
|
}
|
|
1244
1631
|
function isJumpRequestMessage(message) {
|
|
1245
|
-
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");
|
|
1632
|
+
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");
|
|
1246
1633
|
}
|
|
1247
1634
|
function isRouteRequestMessage(message) {
|
|
1248
1635
|
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));
|
|
1249
1636
|
}
|
|
1637
|
+
function isUiReplaceMessage(message) {
|
|
1638
|
+
return message.type === "ui:replace" && typeof message.sessionId === "string";
|
|
1639
|
+
}
|
|
1250
1640
|
function sendRuntimeDebugMessage(socket, message) {
|
|
1251
1641
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1252
1642
|
if (!RuntimeWebSocket || socket.readyState !== RuntimeWebSocket.OPEN) {
|
|
@@ -1267,18 +1657,37 @@ function flushBufferedRequestMessages(socket, sessionId) {
|
|
|
1267
1657
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1268
1658
|
}
|
|
1269
1659
|
}
|
|
1660
|
+
async function syncRuntimeDebugVariablesSnapshotSafe(reason) {
|
|
1661
|
+
try {
|
|
1662
|
+
await syncRuntimeDebugVariablesSnapshot(reason);
|
|
1663
|
+
} catch (error) {
|
|
1664
|
+
console.error("[debug] failed to sync runtime variables snapshot:", error);
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1270
1667
|
function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
1668
|
+
if (isUiReplaceMessage(message)) {
|
|
1669
|
+
try {
|
|
1670
|
+
replaceUiData(message.data);
|
|
1671
|
+
} catch (error) {
|
|
1672
|
+
console.error("[debug] failed to replace runtime UI data:", error);
|
|
1673
|
+
}
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1271
1676
|
const controller = currentController;
|
|
1272
1677
|
if (!controller) {
|
|
1273
1678
|
bufferRequestMessage(message);
|
|
1274
1679
|
return;
|
|
1275
1680
|
}
|
|
1276
1681
|
if (isJumpRequestMessage(message)) {
|
|
1682
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1277
1683
|
const runJump = message.strategy === "warp" ? controller.warp({
|
|
1278
1684
|
markerId: message.markerId,
|
|
1685
|
+
story: message.story,
|
|
1279
1686
|
boundary: message.boundary
|
|
1280
|
-
}).then(() => true) : controller.restoreCheckpoint(message.markerId
|
|
1281
|
-
|
|
1687
|
+
}).then(() => true) : controller.restoreCheckpoint(message.markerId, {
|
|
1688
|
+
story: message.story
|
|
1689
|
+
});
|
|
1690
|
+
void runJump.then(async (restored) => {
|
|
1282
1691
|
if (!restored) {
|
|
1283
1692
|
sendRuntimeDebugMessage(socket, {
|
|
1284
1693
|
type: "jump:error",
|
|
@@ -1287,6 +1696,7 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1287
1696
|
markerId: message.markerId,
|
|
1288
1697
|
error: "Checkpoint not found"
|
|
1289
1698
|
});
|
|
1699
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1290
1700
|
return;
|
|
1291
1701
|
}
|
|
1292
1702
|
sendRuntimeDebugMessage(socket, {
|
|
@@ -1295,7 +1705,8 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1295
1705
|
requestId: message.requestId,
|
|
1296
1706
|
markerId: message.markerId
|
|
1297
1707
|
});
|
|
1298
|
-
|
|
1708
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-done");
|
|
1709
|
+
}).catch(async (error) => {
|
|
1299
1710
|
sendRuntimeDebugMessage(socket, {
|
|
1300
1711
|
type: "jump:error",
|
|
1301
1712
|
sessionId,
|
|
@@ -1303,17 +1714,22 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1303
1714
|
markerId: message.markerId,
|
|
1304
1715
|
error: error instanceof Error ? error.message : String(error)
|
|
1305
1716
|
});
|
|
1717
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1718
|
+
}).finally(() => {
|
|
1719
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1306
1720
|
});
|
|
1307
1721
|
return;
|
|
1308
1722
|
}
|
|
1309
|
-
|
|
1723
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1724
|
+
void controller.switchRoute(message.page, message.params).then(async () => {
|
|
1310
1725
|
sendRuntimeDebugMessage(socket, {
|
|
1311
1726
|
type: "route:done",
|
|
1312
1727
|
sessionId,
|
|
1313
1728
|
requestId: message.requestId,
|
|
1314
1729
|
page: message.page
|
|
1315
1730
|
});
|
|
1316
|
-
|
|
1731
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-done");
|
|
1732
|
+
}).catch(async (error) => {
|
|
1317
1733
|
sendRuntimeDebugMessage(socket, {
|
|
1318
1734
|
type: "route:error",
|
|
1319
1735
|
sessionId,
|
|
@@ -1321,6 +1737,9 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1321
1737
|
page: message.page,
|
|
1322
1738
|
error: error instanceof Error ? error.message : String(error)
|
|
1323
1739
|
});
|
|
1740
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-error");
|
|
1741
|
+
}).finally(() => {
|
|
1742
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1324
1743
|
});
|
|
1325
1744
|
}
|
|
1326
1745
|
async function readDebugParams() {
|
|
@@ -1345,6 +1764,7 @@ async function stopRuntimeDebugSession() {
|
|
|
1345
1764
|
const connection = currentConnection;
|
|
1346
1765
|
currentConnection = null;
|
|
1347
1766
|
currentController = null;
|
|
1767
|
+
resetRuntimeDebugVariableMonitor();
|
|
1348
1768
|
clearBufferedRequestMessages();
|
|
1349
1769
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1350
1770
|
await stopDebugSession();
|
|
@@ -1391,6 +1811,13 @@ async function startRuntimeDebugSession() {
|
|
|
1391
1811
|
}
|
|
1392
1812
|
}).then((controller) => {
|
|
1393
1813
|
currentController = controller;
|
|
1814
|
+
setRuntimeDebugVariableMessageSender((message) => {
|
|
1815
|
+
sendRuntimeDebugMessage(socket, {
|
|
1816
|
+
...message,
|
|
1817
|
+
sessionId
|
|
1818
|
+
});
|
|
1819
|
+
});
|
|
1820
|
+
void syncRuntimeDebugVariablesSnapshotSafe("init");
|
|
1394
1821
|
flushBufferedRequestMessages(socket, sessionId);
|
|
1395
1822
|
}).catch((error) => {
|
|
1396
1823
|
console.error("[debug] failed to start runtime debug session:", error);
|
|
@@ -1403,6 +1830,7 @@ async function startRuntimeDebugSession() {
|
|
|
1403
1830
|
}
|
|
1404
1831
|
currentConnection = null;
|
|
1405
1832
|
currentController = null;
|
|
1833
|
+
resetRuntimeDebugVariableMonitor();
|
|
1406
1834
|
clearBufferedRequestMessages();
|
|
1407
1835
|
void stopDebugSession();
|
|
1408
1836
|
};
|
|
@@ -1429,6 +1857,10 @@ async function startRuntimeDebugSession() {
|
|
|
1429
1857
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1430
1858
|
return;
|
|
1431
1859
|
}
|
|
1860
|
+
if (isUiReplaceMessage(message)) {
|
|
1861
|
+
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1432
1864
|
if (message.type && message.type !== "session:init") {
|
|
1433
1865
|
console.debug("[debug] runtime received message:", message);
|
|
1434
1866
|
}
|
|
@@ -1540,13 +1972,13 @@ async function terminateCurrentScenario() {
|
|
|
1540
1972
|
await executePluginCommand("scenario", {
|
|
1541
1973
|
subCommand: "terminateStory"
|
|
1542
1974
|
});
|
|
1543
|
-
|
|
1975
|
+
await clearLocalDebugSessionRuntimeState();
|
|
1544
1976
|
} catch (error) {
|
|
1545
1977
|
console.error("Failed to terminate scenario:", error);
|
|
1546
1978
|
}
|
|
1547
1979
|
}
|
|
1548
1980
|
async function startScenarioSession(session, config) {
|
|
1549
|
-
|
|
1981
|
+
await clearLocalDebugSessionRuntimeState();
|
|
1550
1982
|
for (const story of config.stories) {
|
|
1551
1983
|
if (!isCurrentScenarioSession(session)) return;
|
|
1552
1984
|
try {
|
|
@@ -1662,49 +2094,31 @@ function useScenario(stories, startName, entryName, goNextOnLoad = false) {
|
|
|
1662
2094
|
|
|
1663
2095
|
// src/hooks/useSoundEffect.ts
|
|
1664
2096
|
import { useCallback, useEffect as useEffect2 } from "react";
|
|
1665
|
-
var LOADED_SOUNDS = /* @__PURE__ */ new Set();
|
|
1666
2097
|
function useSoundEffect(src) {
|
|
1667
2098
|
useEffect2(() => {
|
|
1668
|
-
const loadSound = async () => {
|
|
1669
|
-
try {
|
|
1670
|
-
await executePluginCommand("audio", {
|
|
1671
|
-
subCommand: "load",
|
|
1672
|
-
name: src,
|
|
1673
|
-
src
|
|
1674
|
-
});
|
|
1675
|
-
} catch (error) {
|
|
1676
|
-
console.error(`Failed to load sound effect ${src}:`, error);
|
|
1677
|
-
}
|
|
1678
|
-
LOADED_SOUNDS.add(src);
|
|
1679
|
-
};
|
|
1680
|
-
let needRelease = false;
|
|
1681
|
-
if (!LOADED_SOUNDS.has(src)) {
|
|
1682
|
-
void loadSound();
|
|
1683
|
-
needRelease = true;
|
|
1684
|
-
}
|
|
1685
2099
|
return () => {
|
|
1686
|
-
|
|
1687
|
-
|
|
2100
|
+
try {
|
|
2101
|
+
if (src) {
|
|
1688
2102
|
executePluginCommand("audio", {
|
|
1689
2103
|
subCommand: "release",
|
|
1690
|
-
name: src
|
|
2104
|
+
name: src,
|
|
2105
|
+
silentFail: true
|
|
1691
2106
|
});
|
|
1692
|
-
} catch (error) {
|
|
1693
|
-
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1694
2107
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
if (needRelease) {
|
|
1698
|
-
releaseSound();
|
|
2108
|
+
} catch (error) {
|
|
2109
|
+
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1699
2110
|
}
|
|
1700
2111
|
};
|
|
1701
2112
|
}, [src]);
|
|
1702
2113
|
return useCallback(() => {
|
|
1703
2114
|
try {
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
2115
|
+
if (src) {
|
|
2116
|
+
executePluginCommand("audio", {
|
|
2117
|
+
subCommand: "loadAndPlay",
|
|
2118
|
+
name: src,
|
|
2119
|
+
src
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
1708
2122
|
} catch (error) {
|
|
1709
2123
|
console.error(`Failed to play sound effect ${src}:`, error);
|
|
1710
2124
|
}
|
|
@@ -1713,25 +2127,25 @@ function useSoundEffect(src) {
|
|
|
1713
2127
|
|
|
1714
2128
|
// src/hooks/useStage.ts
|
|
1715
2129
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, createElement, useCallback as useCallback2 } from "react";
|
|
1716
|
-
import { proxy as
|
|
2130
|
+
import { proxy as proxy4, useSnapshot as useSnapshot4 } from "valtio";
|
|
1717
2131
|
var SKIP_INTERVAL_MS = 80;
|
|
1718
2132
|
var DEFAULT_FAST_FORWARD_STEP_LIMIT = 1e4;
|
|
1719
2133
|
var DEFAULT_FAST_FORWARD_TIME_LIMIT_MS = 3e3;
|
|
1720
2134
|
var autoRuntime = {
|
|
1721
2135
|
defaultTailMs: 0
|
|
1722
2136
|
};
|
|
1723
|
-
var skipState =
|
|
1724
|
-
var autoState =
|
|
1725
|
-
var fastForwardState =
|
|
1726
|
-
var warpState =
|
|
2137
|
+
var skipState = proxy4({ active: false });
|
|
2138
|
+
var autoState = proxy4({ active: false });
|
|
2139
|
+
var fastForwardState = proxy4({ active: false });
|
|
2140
|
+
var warpState = proxy4({ active: false });
|
|
1727
2141
|
function useIsSkipping() {
|
|
1728
|
-
return
|
|
2142
|
+
return useSnapshot4(skipState).active;
|
|
1729
2143
|
}
|
|
1730
2144
|
function useIsAutoing() {
|
|
1731
|
-
return
|
|
2145
|
+
return useSnapshot4(autoState).active;
|
|
1732
2146
|
}
|
|
1733
2147
|
function useIsSeeking() {
|
|
1734
|
-
return
|
|
2148
|
+
return useSnapshot4(fastForwardState).active;
|
|
1735
2149
|
}
|
|
1736
2150
|
function getSeekingType() {
|
|
1737
2151
|
if (warpState.active) return "warp";
|
|
@@ -2437,6 +2851,7 @@ function useBeforeHandleCommandCallback(callback) {
|
|
|
2437
2851
|
// src/lib.ts
|
|
2438
2852
|
export * from "@react-spring/core";
|
|
2439
2853
|
export {
|
|
2854
|
+
DEBUG_EMPTY_PAGE,
|
|
2440
2855
|
OverlayParamsContext,
|
|
2441
2856
|
PageParamsContext,
|
|
2442
2857
|
StageContextProvider,
|
|
@@ -2449,6 +2864,7 @@ export {
|
|
|
2449
2864
|
createStackNavigator,
|
|
2450
2865
|
createStage,
|
|
2451
2866
|
createStaticNavigation,
|
|
2867
|
+
ensureArchiveVariableDefaults,
|
|
2452
2868
|
executeNodeCommand,
|
|
2453
2869
|
executePluginCommand,
|
|
2454
2870
|
fastForwardState,
|
|
@@ -2456,11 +2872,16 @@ export {
|
|
|
2456
2872
|
getNavigator,
|
|
2457
2873
|
getSeekingType,
|
|
2458
2874
|
getStageSize,
|
|
2875
|
+
getUiData,
|
|
2459
2876
|
globalEventListeners,
|
|
2460
2877
|
globalRequestAnimationFrameListeners,
|
|
2878
|
+
initGlobalVariableDefaults,
|
|
2879
|
+
initUiData,
|
|
2880
|
+
loadVariablesDocument,
|
|
2461
2881
|
moyu_exports as moyu,
|
|
2462
2882
|
nextLine,
|
|
2463
2883
|
registerAppStateAdapter,
|
|
2884
|
+
replaceUiData,
|
|
2464
2885
|
setDefaultAutoTailMs,
|
|
2465
2886
|
setWaiting,
|
|
2466
2887
|
skipState,
|
|
@@ -2487,5 +2908,6 @@ export {
|
|
|
2487
2908
|
useSkipCallback,
|
|
2488
2909
|
useSoundEffect,
|
|
2489
2910
|
useStageContext,
|
|
2911
|
+
useUiData,
|
|
2490
2912
|
warpState
|
|
2491
2913
|
};
|