@momoyu-ink/kit 0.6.0 → 0.7.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-B5T-ZMWr.d.mts → jsx-dev-runtime-CKclO27C.d.mts} +27 -1
- package/dist/{jsx-dev-runtime-B5T-ZMWr.d.ts → jsx-dev-runtime-CKclO27C.d.ts} +27 -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 +520 -67
- package/dist/lib.d.mts +49 -9
- package/dist/lib.d.ts +49 -9
- package/dist/lib.mjs +528 -67
- 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,10 +414,290 @@ 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
|
-
var JS_GLOBAL_KEYS_EXCLUDED = /* @__PURE__ */ new Set(["window", "globalThis", "ARCHIVE", "GLOBAL"]);
|
|
412
|
-
JS_GLOBAL_KEYS_EXCLUDED.forEach((key) =>
|
|
672
|
+
var JS_GLOBAL_KEYS_EXCLUDED = /* @__PURE__ */ new Set(["window", "globalThis", "LOCAL", "ARCHIVE", "GLOBAL"]);
|
|
673
|
+
JS_GLOBAL_KEYS_EXCLUDED.forEach((key) => {
|
|
674
|
+
JS_GLOBAL_KEYS.delete(key);
|
|
675
|
+
});
|
|
676
|
+
var localVariables = new Proxy(
|
|
677
|
+
{},
|
|
678
|
+
{
|
|
679
|
+
get(_, key) {
|
|
680
|
+
if (typeof key === "string") {
|
|
681
|
+
return executePluginCommand("scenario", {
|
|
682
|
+
subCommand: "getLocalVariable",
|
|
683
|
+
name: key
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return void 0;
|
|
687
|
+
},
|
|
688
|
+
set(_, key, value) {
|
|
689
|
+
if (typeof key === "string") {
|
|
690
|
+
executePluginCommand("scenario", {
|
|
691
|
+
subCommand: "setLocalVariable",
|
|
692
|
+
name: key,
|
|
693
|
+
value
|
|
694
|
+
});
|
|
695
|
+
return true;
|
|
696
|
+
}
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
);
|
|
413
701
|
var archiveVariables = new Proxy(
|
|
414
702
|
{},
|
|
415
703
|
{
|
|
@@ -429,6 +717,7 @@ var archiveVariables = new Proxy(
|
|
|
429
717
|
name: key,
|
|
430
718
|
value
|
|
431
719
|
});
|
|
720
|
+
reportRuntimeDebugVariableSet("archive", key, value);
|
|
432
721
|
return true;
|
|
433
722
|
}
|
|
434
723
|
return false;
|
|
@@ -454,6 +743,7 @@ var globalVariables = new Proxy(
|
|
|
454
743
|
key,
|
|
455
744
|
value
|
|
456
745
|
});
|
|
746
|
+
reportRuntimeDebugVariableSet("global", key, value);
|
|
457
747
|
return true;
|
|
458
748
|
}
|
|
459
749
|
return false;
|
|
@@ -461,15 +751,16 @@ var globalVariables = new Proxy(
|
|
|
461
751
|
}
|
|
462
752
|
);
|
|
463
753
|
function safeEval(code, sandbox) {
|
|
464
|
-
const
|
|
754
|
+
const proxy5 = new Proxy(sandbox, {
|
|
465
755
|
has(target, key) {
|
|
466
756
|
if (typeof key === "string" && JS_GLOBAL_KEYS.has(key)) {
|
|
467
757
|
return false;
|
|
468
758
|
}
|
|
469
|
-
return key in target || key === "ARCHIVE" || key === "GLOBAL" || key === "window" || key === "globalThis";
|
|
759
|
+
return key in target || key === "LOCAL" || key === "ARCHIVE" || key === "GLOBAL" || key === "window" || key === "globalThis";
|
|
470
760
|
},
|
|
471
761
|
get(target, key) {
|
|
472
|
-
if (key === "window" || key === "globalThis") return
|
|
762
|
+
if (key === "window" || key === "globalThis") return proxy5;
|
|
763
|
+
if (key === "LOCAL") return localVariables;
|
|
473
764
|
if (key === "ARCHIVE") return archiveVariables;
|
|
474
765
|
if (key === "GLOBAL") return globalVariables;
|
|
475
766
|
if (key === Symbol.unscopables) return void 0;
|
|
@@ -480,7 +771,7 @@ function safeEval(code, sandbox) {
|
|
|
480
771
|
return true;
|
|
481
772
|
}
|
|
482
773
|
});
|
|
483
|
-
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(
|
|
774
|
+
return new Function("sandbox", `with(sandbox) { return (${code}) }`).bind(proxy5)(proxy5);
|
|
484
775
|
}
|
|
485
776
|
globalThis.__moyu_eval_sandbox = (code) => {
|
|
486
777
|
try {
|
|
@@ -667,6 +958,7 @@ var import_valtio = require("valtio");
|
|
|
667
958
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
668
959
|
var PageParamsContext = (0, import_react2.createContext)(void 0);
|
|
669
960
|
var OverlayParamsContext = (0, import_react2.createContext)(void 0);
|
|
961
|
+
var DEBUG_EMPTY_PAGE = "debug-empty";
|
|
670
962
|
var overlayIdCounter = 0;
|
|
671
963
|
var generateOverlayId = () => {
|
|
672
964
|
return `overlay-${++overlayIdCounter}-${Date.now()}`;
|
|
@@ -694,6 +986,12 @@ function createStackNavigator(options) {
|
|
|
694
986
|
for (const [key, config] of Object.entries(options.pages)) {
|
|
695
987
|
normalizedPages[key] = normalizeDescriptor(config);
|
|
696
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
|
+
};
|
|
697
995
|
const normalizedOverlays = {};
|
|
698
996
|
if (options.overlays) {
|
|
699
997
|
for (const [key, config] of Object.entries(options.overlays)) {
|
|
@@ -723,6 +1021,9 @@ function createStackNavigator(options) {
|
|
|
723
1021
|
hasPage: (page) => {
|
|
724
1022
|
return normalizedPages[page] !== void 0;
|
|
725
1023
|
},
|
|
1024
|
+
hasOverlay: (overlay) => {
|
|
1025
|
+
return normalizedOverlays[overlay] !== void 0;
|
|
1026
|
+
},
|
|
726
1027
|
goBack: () => {
|
|
727
1028
|
console.warn("goBack() not implemented yet");
|
|
728
1029
|
},
|
|
@@ -810,6 +1111,7 @@ var debugState = (0, import_valtio2.proxy)({
|
|
|
810
1111
|
active: false,
|
|
811
1112
|
checkpoints: {},
|
|
812
1113
|
currentCursor: null,
|
|
1114
|
+
currentStory: null,
|
|
813
1115
|
restoring: false,
|
|
814
1116
|
lastError: null
|
|
815
1117
|
});
|
|
@@ -853,9 +1155,37 @@ function reportDebugSessionError(error) {
|
|
|
853
1155
|
function clearLocalRuntimeState() {
|
|
854
1156
|
debugState.checkpoints = {};
|
|
855
1157
|
debugState.currentCursor = null;
|
|
1158
|
+
debugState.currentStory = null;
|
|
856
1159
|
debugState.restoring = false;
|
|
857
1160
|
debugState.lastError = null;
|
|
858
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
|
+
}
|
|
859
1189
|
async function doSettleActiveSeek(op, clearSlot, error) {
|
|
860
1190
|
if (!op) {
|
|
861
1191
|
return;
|
|
@@ -908,6 +1238,7 @@ async function syncLocalWarpCheckpoint(targetMarkerId) {
|
|
|
908
1238
|
appState: appStateAdapter ? await appStateAdapter.capture() : void 0
|
|
909
1239
|
};
|
|
910
1240
|
debugState.currentCursor = checkpointCursor;
|
|
1241
|
+
debugState.currentStory = checkpointCursor.story;
|
|
911
1242
|
debugState.checkpoints[targetMarkerId] = checkpoint;
|
|
912
1243
|
await currentConfig.onMarkerEnter(checkpoint);
|
|
913
1244
|
}
|
|
@@ -931,9 +1262,16 @@ function notifyMarkerEnter(checkpoint) {
|
|
|
931
1262
|
reportDebugSessionError(error);
|
|
932
1263
|
}
|
|
933
1264
|
}
|
|
934
|
-
async function prepareJumpStart(markerId) {
|
|
1265
|
+
async function prepareJumpStart(markerId, options) {
|
|
1266
|
+
const currentStory = debugState.currentStory ?? debugState.currentCursor?.story ?? null;
|
|
1267
|
+
const targetStory = options?.story;
|
|
1268
|
+
let restartedFromHead = false;
|
|
1269
|
+
if (targetStory && targetStory !== currentStory) {
|
|
1270
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
1271
|
+
restartedFromHead = true;
|
|
1272
|
+
}
|
|
935
1273
|
const checkpoint = debugState.checkpoints[markerId];
|
|
936
|
-
if (checkpoint) {
|
|
1274
|
+
if (!restartedFromHead && checkpoint && (!targetStory || checkpoint.cursor.story === targetStory)) {
|
|
937
1275
|
const restored2 = await executeScenarioCommand({
|
|
938
1276
|
subCommand: "restoreCheckpoint",
|
|
939
1277
|
key: markerId
|
|
@@ -945,6 +1283,7 @@ async function prepareJumpStart(markerId) {
|
|
|
945
1283
|
await appStateAdapter.restore(checkpoint.appState);
|
|
946
1284
|
}
|
|
947
1285
|
debugState.currentCursor = checkpoint.cursor;
|
|
1286
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
948
1287
|
return false;
|
|
949
1288
|
}
|
|
950
1289
|
const lookup = await executeScenarioCommand({
|
|
@@ -952,16 +1291,15 @@ async function prepareJumpStart(markerId) {
|
|
|
952
1291
|
key: markerId
|
|
953
1292
|
});
|
|
954
1293
|
if (!lookup.markerExists) {
|
|
955
|
-
throw new Error(
|
|
1294
|
+
throw new Error(
|
|
1295
|
+
targetStory ? `Marker ${markerId} is not available in story ${targetStory}` : `Marker ${markerId} is not available in the current story`
|
|
1296
|
+
);
|
|
956
1297
|
}
|
|
957
1298
|
const startCheckpointKey = lookup.checkpointKey ?? null;
|
|
958
1299
|
if (!startCheckpointKey) {
|
|
959
|
-
if (!
|
|
960
|
-
|
|
1300
|
+
if (!restartedFromHead) {
|
|
1301
|
+
await restartJumpStoryFromHead(targetStory, currentStory);
|
|
961
1302
|
}
|
|
962
|
-
await appStateAdapter.restartCurrentStoryFromHead();
|
|
963
|
-
debugState.checkpoints = {};
|
|
964
|
-
debugState.currentCursor = null;
|
|
965
1303
|
return true;
|
|
966
1304
|
}
|
|
967
1305
|
const startCheckpoint = debugState.checkpoints[startCheckpointKey];
|
|
@@ -979,6 +1317,7 @@ async function prepareJumpStart(markerId) {
|
|
|
979
1317
|
await appStateAdapter.restore(startCheckpoint.appState);
|
|
980
1318
|
}
|
|
981
1319
|
debugState.currentCursor = startCheckpoint.cursor;
|
|
1320
|
+
debugState.currentStory = startCheckpoint.cursor.story;
|
|
982
1321
|
return true;
|
|
983
1322
|
}
|
|
984
1323
|
function handleMarkerEnter(marker) {
|
|
@@ -991,6 +1330,7 @@ function handleMarkerEnter(marker) {
|
|
|
991
1330
|
appState: captureCheckpointAppStateSync()
|
|
992
1331
|
};
|
|
993
1332
|
debugState.currentCursor = checkpoint.cursor;
|
|
1333
|
+
debugState.currentStory = checkpoint.cursor.story;
|
|
994
1334
|
debugState.checkpoints[marker.markerId] = checkpoint;
|
|
995
1335
|
notifyMarkerEnter(checkpoint);
|
|
996
1336
|
if (activeFastForward?.targetMarkerId === marker.markerId) {
|
|
@@ -1051,11 +1391,11 @@ async function runWarp(options) {
|
|
|
1051
1391
|
await completion;
|
|
1052
1392
|
}
|
|
1053
1393
|
var debugSessionController = {
|
|
1054
|
-
async restoreCheckpoint(markerId) {
|
|
1394
|
+
async restoreCheckpoint(markerId, options) {
|
|
1055
1395
|
debugState.restoring = true;
|
|
1056
1396
|
debugState.lastError = null;
|
|
1057
1397
|
try {
|
|
1058
|
-
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId));
|
|
1398
|
+
const needsFastForward = await enqueueDebugOperation(async () => prepareJumpStart(markerId, options));
|
|
1059
1399
|
if (needsFastForward) {
|
|
1060
1400
|
await runFastForwardToMarker(markerId);
|
|
1061
1401
|
}
|
|
@@ -1071,7 +1411,7 @@ var debugSessionController = {
|
|
|
1071
1411
|
debugState.restoring = true;
|
|
1072
1412
|
debugState.lastError = null;
|
|
1073
1413
|
try {
|
|
1074
|
-
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId));
|
|
1414
|
+
const needsWarp = await enqueueDebugOperation(async () => prepareJumpStart(options.markerId, options));
|
|
1075
1415
|
if (needsWarp) {
|
|
1076
1416
|
await runWarp(options);
|
|
1077
1417
|
}
|
|
@@ -1082,14 +1422,26 @@ var debugSessionController = {
|
|
|
1082
1422
|
debugState.restoring = false;
|
|
1083
1423
|
}
|
|
1084
1424
|
},
|
|
1085
|
-
async
|
|
1425
|
+
async switchRoute(routeName, params) {
|
|
1086
1426
|
return enqueueDebugOperation(async () => {
|
|
1087
1427
|
debugState.lastError = null;
|
|
1088
1428
|
try {
|
|
1089
|
-
|
|
1090
|
-
|
|
1429
|
+
const navigator = getNavigator();
|
|
1430
|
+
if (navigator.hasPage(routeName)) {
|
|
1431
|
+
if (!appStateAdapter?.switchPage) {
|
|
1432
|
+
throw new Error("Page switching is not supported by the app state adapter");
|
|
1433
|
+
}
|
|
1434
|
+
await appStateAdapter.switchPage(routeName, params);
|
|
1435
|
+
return;
|
|
1091
1436
|
}
|
|
1092
|
-
|
|
1437
|
+
if (navigator.hasOverlay(routeName)) {
|
|
1438
|
+
if (!appStateAdapter?.switchOverlay) {
|
|
1439
|
+
throw new Error("Overlay switching is not supported by the app state adapter");
|
|
1440
|
+
}
|
|
1441
|
+
await appStateAdapter.switchOverlay(routeName, params);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
throw new Error(`Route "${routeName}" not found`);
|
|
1093
1445
|
} catch (error) {
|
|
1094
1446
|
debugState.lastError = toErrorMessage(error);
|
|
1095
1447
|
throw error;
|
|
@@ -1154,6 +1506,7 @@ async function startDebugSession(config = {}) {
|
|
|
1154
1506
|
debugState.currentCursor = await executeScenarioCommand({
|
|
1155
1507
|
subCommand: "getExecutionCursor"
|
|
1156
1508
|
});
|
|
1509
|
+
debugState.currentStory = debugState.currentCursor?.story ?? null;
|
|
1157
1510
|
} catch (error) {
|
|
1158
1511
|
debugState.active = false;
|
|
1159
1512
|
clearLocalRuntimeState();
|
|
@@ -1214,10 +1567,83 @@ function useDebugSession() {
|
|
|
1214
1567
|
stopDebugSession,
|
|
1215
1568
|
restoreCheckpoint: debugSessionController.restoreCheckpoint,
|
|
1216
1569
|
warp: debugSessionController.warp,
|
|
1217
|
-
|
|
1570
|
+
switchRoute: debugSessionController.switchRoute
|
|
1218
1571
|
};
|
|
1219
1572
|
}
|
|
1220
1573
|
|
|
1574
|
+
// src/ui.ts
|
|
1575
|
+
var import_valtio3 = require("valtio");
|
|
1576
|
+
var UI_DATA_ASSET_PATH = "assets:///data/ui.json";
|
|
1577
|
+
var activeUiSchema = null;
|
|
1578
|
+
var uiDataState = (0, import_valtio3.proxy)({});
|
|
1579
|
+
var uiRuntimeState = (0, import_valtio3.proxy)({
|
|
1580
|
+
initialized: false,
|
|
1581
|
+
error: null
|
|
1582
|
+
});
|
|
1583
|
+
function applyUiData(nextData) {
|
|
1584
|
+
for (const key of Object.keys(uiDataState)) {
|
|
1585
|
+
delete uiDataState[key];
|
|
1586
|
+
}
|
|
1587
|
+
Object.assign(uiDataState, nextData);
|
|
1588
|
+
uiRuntimeState.initialized = true;
|
|
1589
|
+
uiRuntimeState.error = null;
|
|
1590
|
+
}
|
|
1591
|
+
async function initUiData(schema) {
|
|
1592
|
+
uiRuntimeState.initialized = false;
|
|
1593
|
+
uiRuntimeState.error = null;
|
|
1594
|
+
activeUiSchema = schema;
|
|
1595
|
+
let rawData;
|
|
1596
|
+
try {
|
|
1597
|
+
const rawText = await Promise.resolve(
|
|
1598
|
+
executePluginCommand("system", {
|
|
1599
|
+
subCommand: "readFile",
|
|
1600
|
+
path: UI_DATA_ASSET_PATH
|
|
1601
|
+
})
|
|
1602
|
+
);
|
|
1603
|
+
rawData = JSON.parse(rawText);
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1606
|
+
uiRuntimeState.error = message;
|
|
1607
|
+
throw new Error(`Failed to initialize UI data: ${message}`);
|
|
1608
|
+
}
|
|
1609
|
+
const parsed = schema.safeParse(rawData);
|
|
1610
|
+
if (!parsed.success) {
|
|
1611
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1612
|
+
throw new Error(`Invalid UI data: ${parsed.error.message}`);
|
|
1613
|
+
}
|
|
1614
|
+
applyUiData(parsed.data);
|
|
1615
|
+
}
|
|
1616
|
+
function replaceUiData(rawData) {
|
|
1617
|
+
if (!activeUiSchema) {
|
|
1618
|
+
throw new Error("UI data schema has not been initialized. Call initUiData() first.");
|
|
1619
|
+
}
|
|
1620
|
+
const parsed = activeUiSchema.safeParse(rawData);
|
|
1621
|
+
if (!parsed.success) {
|
|
1622
|
+
uiRuntimeState.error = parsed.error.message;
|
|
1623
|
+
throw new Error(`Invalid replacement UI data: ${parsed.error.message}`);
|
|
1624
|
+
}
|
|
1625
|
+
applyUiData(parsed.data);
|
|
1626
|
+
}
|
|
1627
|
+
function getUiData(name) {
|
|
1628
|
+
if (!uiRuntimeState.initialized) {
|
|
1629
|
+
throw new Error("UI data has not been initialized. Call initUiData() before reading it.");
|
|
1630
|
+
}
|
|
1631
|
+
if (!(name in uiDataState)) {
|
|
1632
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1633
|
+
}
|
|
1634
|
+
return uiDataState[name];
|
|
1635
|
+
}
|
|
1636
|
+
function useUiData(name) {
|
|
1637
|
+
if (!uiRuntimeState.initialized) {
|
|
1638
|
+
throw new Error("UI data has not been initialized. Call initUiData() before rendering UI pages.");
|
|
1639
|
+
}
|
|
1640
|
+
const snapshot = (0, import_valtio3.useSnapshot)(uiDataState);
|
|
1641
|
+
if (!(name in snapshot)) {
|
|
1642
|
+
throw new Error(`UI data "${name}" is not available.`);
|
|
1643
|
+
}
|
|
1644
|
+
return snapshot[name];
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1221
1647
|
// src/debug/runtime.ts
|
|
1222
1648
|
var currentConnection = null;
|
|
1223
1649
|
var currentController = null;
|
|
@@ -1226,11 +1652,14 @@ function getRuntimeWebSocket() {
|
|
|
1226
1652
|
return globalThis.WebSocket ?? null;
|
|
1227
1653
|
}
|
|
1228
1654
|
function isJumpRequestMessage(message) {
|
|
1229
|
-
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");
|
|
1655
|
+
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");
|
|
1230
1656
|
}
|
|
1231
1657
|
function isRouteRequestMessage(message) {
|
|
1232
1658
|
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));
|
|
1233
1659
|
}
|
|
1660
|
+
function isUiReplaceMessage(message) {
|
|
1661
|
+
return message.type === "ui:replace" && typeof message.sessionId === "string";
|
|
1662
|
+
}
|
|
1234
1663
|
function sendRuntimeDebugMessage(socket, message) {
|
|
1235
1664
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1236
1665
|
if (!RuntimeWebSocket || socket.readyState !== RuntimeWebSocket.OPEN) {
|
|
@@ -1251,18 +1680,37 @@ function flushBufferedRequestMessages(socket, sessionId) {
|
|
|
1251
1680
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1252
1681
|
}
|
|
1253
1682
|
}
|
|
1683
|
+
async function syncRuntimeDebugVariablesSnapshotSafe(reason) {
|
|
1684
|
+
try {
|
|
1685
|
+
await syncRuntimeDebugVariablesSnapshot(reason);
|
|
1686
|
+
} catch (error) {
|
|
1687
|
+
console.error("[debug] failed to sync runtime variables snapshot:", error);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1254
1690
|
function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
1691
|
+
if (isUiReplaceMessage(message)) {
|
|
1692
|
+
try {
|
|
1693
|
+
replaceUiData(message.data);
|
|
1694
|
+
} catch (error) {
|
|
1695
|
+
console.error("[debug] failed to replace runtime UI data:", error);
|
|
1696
|
+
}
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1255
1699
|
const controller = currentController;
|
|
1256
1700
|
if (!controller) {
|
|
1257
1701
|
bufferRequestMessage(message);
|
|
1258
1702
|
return;
|
|
1259
1703
|
}
|
|
1260
1704
|
if (isJumpRequestMessage(message)) {
|
|
1705
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1261
1706
|
const runJump = message.strategy === "warp" ? controller.warp({
|
|
1262
1707
|
markerId: message.markerId,
|
|
1708
|
+
story: message.story,
|
|
1263
1709
|
boundary: message.boundary
|
|
1264
|
-
}).then(() => true) : controller.restoreCheckpoint(message.markerId
|
|
1265
|
-
|
|
1710
|
+
}).then(() => true) : controller.restoreCheckpoint(message.markerId, {
|
|
1711
|
+
story: message.story
|
|
1712
|
+
});
|
|
1713
|
+
void runJump.then(async (restored) => {
|
|
1266
1714
|
if (!restored) {
|
|
1267
1715
|
sendRuntimeDebugMessage(socket, {
|
|
1268
1716
|
type: "jump:error",
|
|
@@ -1271,6 +1719,7 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1271
1719
|
markerId: message.markerId,
|
|
1272
1720
|
error: "Checkpoint not found"
|
|
1273
1721
|
});
|
|
1722
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1274
1723
|
return;
|
|
1275
1724
|
}
|
|
1276
1725
|
sendRuntimeDebugMessage(socket, {
|
|
@@ -1279,7 +1728,8 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1279
1728
|
requestId: message.requestId,
|
|
1280
1729
|
markerId: message.markerId
|
|
1281
1730
|
});
|
|
1282
|
-
|
|
1731
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-done");
|
|
1732
|
+
}).catch(async (error) => {
|
|
1283
1733
|
sendRuntimeDebugMessage(socket, {
|
|
1284
1734
|
type: "jump:error",
|
|
1285
1735
|
sessionId,
|
|
@@ -1287,17 +1737,22 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1287
1737
|
markerId: message.markerId,
|
|
1288
1738
|
error: error instanceof Error ? error.message : String(error)
|
|
1289
1739
|
});
|
|
1740
|
+
await syncRuntimeDebugVariablesSnapshotSafe("jump-error");
|
|
1741
|
+
}).finally(() => {
|
|
1742
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1290
1743
|
});
|
|
1291
1744
|
return;
|
|
1292
1745
|
}
|
|
1293
|
-
|
|
1746
|
+
setRuntimeDebugVariableEmissionSuspended(true);
|
|
1747
|
+
void controller.switchRoute(message.page, message.params).then(async () => {
|
|
1294
1748
|
sendRuntimeDebugMessage(socket, {
|
|
1295
1749
|
type: "route:done",
|
|
1296
1750
|
sessionId,
|
|
1297
1751
|
requestId: message.requestId,
|
|
1298
1752
|
page: message.page
|
|
1299
1753
|
});
|
|
1300
|
-
|
|
1754
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-done");
|
|
1755
|
+
}).catch(async (error) => {
|
|
1301
1756
|
sendRuntimeDebugMessage(socket, {
|
|
1302
1757
|
type: "route:error",
|
|
1303
1758
|
sessionId,
|
|
@@ -1305,6 +1760,9 @@ function handleRuntimeDebugRequest(socket, sessionId, message) {
|
|
|
1305
1760
|
page: message.page,
|
|
1306
1761
|
error: error instanceof Error ? error.message : String(error)
|
|
1307
1762
|
});
|
|
1763
|
+
await syncRuntimeDebugVariablesSnapshotSafe("route-error");
|
|
1764
|
+
}).finally(() => {
|
|
1765
|
+
setRuntimeDebugVariableEmissionSuspended(false);
|
|
1308
1766
|
});
|
|
1309
1767
|
}
|
|
1310
1768
|
async function readDebugParams() {
|
|
@@ -1329,6 +1787,7 @@ async function stopRuntimeDebugSession() {
|
|
|
1329
1787
|
const connection = currentConnection;
|
|
1330
1788
|
currentConnection = null;
|
|
1331
1789
|
currentController = null;
|
|
1790
|
+
resetRuntimeDebugVariableMonitor();
|
|
1332
1791
|
clearBufferedRequestMessages();
|
|
1333
1792
|
const RuntimeWebSocket = getRuntimeWebSocket();
|
|
1334
1793
|
await stopDebugSession();
|
|
@@ -1375,6 +1834,13 @@ async function startRuntimeDebugSession() {
|
|
|
1375
1834
|
}
|
|
1376
1835
|
}).then((controller) => {
|
|
1377
1836
|
currentController = controller;
|
|
1837
|
+
setRuntimeDebugVariableMessageSender((message) => {
|
|
1838
|
+
sendRuntimeDebugMessage(socket, {
|
|
1839
|
+
...message,
|
|
1840
|
+
sessionId
|
|
1841
|
+
});
|
|
1842
|
+
});
|
|
1843
|
+
void syncRuntimeDebugVariablesSnapshotSafe("init");
|
|
1378
1844
|
flushBufferedRequestMessages(socket, sessionId);
|
|
1379
1845
|
}).catch((error) => {
|
|
1380
1846
|
console.error("[debug] failed to start runtime debug session:", error);
|
|
@@ -1387,6 +1853,7 @@ async function startRuntimeDebugSession() {
|
|
|
1387
1853
|
}
|
|
1388
1854
|
currentConnection = null;
|
|
1389
1855
|
currentController = null;
|
|
1856
|
+
resetRuntimeDebugVariableMonitor();
|
|
1390
1857
|
clearBufferedRequestMessages();
|
|
1391
1858
|
void stopDebugSession();
|
|
1392
1859
|
};
|
|
@@ -1413,6 +1880,10 @@ async function startRuntimeDebugSession() {
|
|
|
1413
1880
|
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1414
1881
|
return;
|
|
1415
1882
|
}
|
|
1883
|
+
if (isUiReplaceMessage(message)) {
|
|
1884
|
+
handleRuntimeDebugRequest(socket, sessionId, message);
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1416
1887
|
if (message.type && message.type !== "session:init") {
|
|
1417
1888
|
console.debug("[debug] runtime received message:", message);
|
|
1418
1889
|
}
|
|
@@ -1646,49 +2117,31 @@ function useScenario(stories, startName, entryName, goNextOnLoad = false) {
|
|
|
1646
2117
|
|
|
1647
2118
|
// src/hooks/useSoundEffect.ts
|
|
1648
2119
|
var import_react4 = require("react");
|
|
1649
|
-
var LOADED_SOUNDS = /* @__PURE__ */ new Set();
|
|
1650
2120
|
function useSoundEffect(src) {
|
|
1651
2121
|
(0, import_react4.useEffect)(() => {
|
|
1652
|
-
const loadSound = async () => {
|
|
1653
|
-
try {
|
|
1654
|
-
await executePluginCommand("audio", {
|
|
1655
|
-
subCommand: "load",
|
|
1656
|
-
name: src,
|
|
1657
|
-
src
|
|
1658
|
-
});
|
|
1659
|
-
} catch (error) {
|
|
1660
|
-
console.error(`Failed to load sound effect ${src}:`, error);
|
|
1661
|
-
}
|
|
1662
|
-
LOADED_SOUNDS.add(src);
|
|
1663
|
-
};
|
|
1664
|
-
let needRelease = false;
|
|
1665
|
-
if (!LOADED_SOUNDS.has(src)) {
|
|
1666
|
-
void loadSound();
|
|
1667
|
-
needRelease = true;
|
|
1668
|
-
}
|
|
1669
2122
|
return () => {
|
|
1670
|
-
|
|
1671
|
-
|
|
2123
|
+
try {
|
|
2124
|
+
if (src) {
|
|
1672
2125
|
executePluginCommand("audio", {
|
|
1673
2126
|
subCommand: "release",
|
|
1674
|
-
name: src
|
|
2127
|
+
name: src,
|
|
2128
|
+
silentFail: true
|
|
1675
2129
|
});
|
|
1676
|
-
} catch (error) {
|
|
1677
|
-
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1678
2130
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
if (needRelease) {
|
|
1682
|
-
releaseSound();
|
|
2131
|
+
} catch (error) {
|
|
2132
|
+
console.error(`Failed to release sound effect ${src}:`, error);
|
|
1683
2133
|
}
|
|
1684
2134
|
};
|
|
1685
2135
|
}, [src]);
|
|
1686
2136
|
return (0, import_react4.useCallback)(() => {
|
|
1687
2137
|
try {
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
2138
|
+
if (src) {
|
|
2139
|
+
executePluginCommand("audio", {
|
|
2140
|
+
subCommand: "loadAndPlay",
|
|
2141
|
+
name: src,
|
|
2142
|
+
src
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
1692
2145
|
} catch (error) {
|
|
1693
2146
|
console.error(`Failed to play sound effect ${src}:`, error);
|
|
1694
2147
|
}
|
|
@@ -1697,25 +2150,25 @@ function useSoundEffect(src) {
|
|
|
1697
2150
|
|
|
1698
2151
|
// src/hooks/useStage.ts
|
|
1699
2152
|
var import_react5 = require("react");
|
|
1700
|
-
var
|
|
2153
|
+
var import_valtio4 = require("valtio");
|
|
1701
2154
|
var SKIP_INTERVAL_MS = 80;
|
|
1702
2155
|
var DEFAULT_FAST_FORWARD_STEP_LIMIT = 1e4;
|
|
1703
2156
|
var DEFAULT_FAST_FORWARD_TIME_LIMIT_MS = 3e3;
|
|
1704
2157
|
var autoRuntime = {
|
|
1705
2158
|
defaultTailMs: 0
|
|
1706
2159
|
};
|
|
1707
|
-
var skipState = (0,
|
|
1708
|
-
var autoState = (0,
|
|
1709
|
-
var fastForwardState = (0,
|
|
1710
|
-
var warpState = (0,
|
|
2160
|
+
var skipState = (0, import_valtio4.proxy)({ active: false });
|
|
2161
|
+
var autoState = (0, import_valtio4.proxy)({ active: false });
|
|
2162
|
+
var fastForwardState = (0, import_valtio4.proxy)({ active: false });
|
|
2163
|
+
var warpState = (0, import_valtio4.proxy)({ active: false });
|
|
1711
2164
|
function useIsSkipping() {
|
|
1712
|
-
return (0,
|
|
2165
|
+
return (0, import_valtio4.useSnapshot)(skipState).active;
|
|
1713
2166
|
}
|
|
1714
2167
|
function useIsAutoing() {
|
|
1715
|
-
return (0,
|
|
2168
|
+
return (0, import_valtio4.useSnapshot)(autoState).active;
|
|
1716
2169
|
}
|
|
1717
2170
|
function useIsSeeking() {
|
|
1718
|
-
return (0,
|
|
2171
|
+
return (0, import_valtio4.useSnapshot)(fastForwardState).active;
|
|
1719
2172
|
}
|
|
1720
2173
|
function getSeekingType() {
|
|
1721
2174
|
if (warpState.active) return "warp";
|