@kawaijs/runtime 0.1.10 → 0.1.12
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/README.md +16 -4
- package/dist/continue-link.d.ts +25 -0
- package/dist/continue-link.d.ts.map +1 -0
- package/dist/continue-link.js +144 -0
- package/dist/continue-link.js.map +1 -0
- package/dist/evaluator.d.ts +15 -2
- package/dist/evaluator.d.ts.map +1 -1
- package/dist/evaluator.js +157 -35
- package/dist/evaluator.js.map +1 -1
- package/dist/history.d.ts +5 -0
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +14 -0
- package/dist/history.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/save.d.ts +28 -4
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +130 -9
- package/dist/save.js.map +1 -1
- package/dist/state.d.ts +55 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +109 -4
- package/dist/state.js.map +1 -1
- package/dist/vm.d.ts +71 -6
- package/dist/vm.d.ts.map +1 -1
- package/dist/vm.js +696 -30
- package/dist/vm.js.map +1 -1
- package/package.json +10 -2
package/dist/save.d.ts
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StoryPackage } from '@kawaijs/ast';
|
|
2
|
+
import type { DialogueHistoryEntry } from './history.js';
|
|
3
|
+
import { type Snapshot, type StoryState } from './state.js';
|
|
4
|
+
export declare const CURRENT_SAVE_SCHEMA_VERSION = 2;
|
|
2
5
|
export interface SaveSlot {
|
|
6
|
+
readonly schemaVersion?: number;
|
|
7
|
+
readonly storyHash?: string;
|
|
3
8
|
readonly id: string;
|
|
4
9
|
readonly name: string;
|
|
5
10
|
readonly timestamp: number;
|
|
6
11
|
readonly snapshot: Snapshot;
|
|
7
12
|
readonly previewText?: string;
|
|
8
13
|
readonly screenshotUrl?: string;
|
|
14
|
+
/** Persisted dialogue backlog (schema v2+). */
|
|
15
|
+
readonly historyEntries?: readonly DialogueHistoryEntry[];
|
|
9
16
|
}
|
|
17
|
+
export type LoadFailureReason = 'not_found' | 'corrupt' | 'incompatible_schema' | 'incompatible_story';
|
|
18
|
+
export interface LoadResult {
|
|
19
|
+
readonly success: boolean;
|
|
20
|
+
readonly slot?: SaveSlot;
|
|
21
|
+
readonly reason?: LoadFailureReason;
|
|
22
|
+
}
|
|
23
|
+
export declare function fnv1a(str: string): string;
|
|
24
|
+
export declare function computeStoryHash(story: StoryPackage): string;
|
|
25
|
+
/** Explicit v1 → v2: add historyEntries (empty if missing). */
|
|
26
|
+
export declare function migrateSaveV1ToV2(slot: SaveSlot): SaveSlot;
|
|
27
|
+
/**
|
|
28
|
+
* Migrate / normalize a parsed save slot to the current schema.
|
|
29
|
+
* Returns null if the slot cannot be recovered.
|
|
30
|
+
*/
|
|
31
|
+
export declare function migrateSaveSlot(raw: unknown): SaveSlot | null;
|
|
10
32
|
export interface StorageAdapter {
|
|
11
33
|
getItem(key: string): string | null | Promise<string | null>;
|
|
12
34
|
setItem(key: string, value: string): void | Promise<void>;
|
|
@@ -27,9 +49,11 @@ export declare class SaveManager {
|
|
|
27
49
|
private readonly storage;
|
|
28
50
|
private readonly storagePrefix;
|
|
29
51
|
constructor(storage?: StorageAdapter, storagePrefix?: string);
|
|
30
|
-
saveSlot(slotId: string, snapshot: Snapshot, previewText?: string): Promise<SaveSlot>;
|
|
31
|
-
loadSlot(slotId: string): Promise<
|
|
52
|
+
saveSlot(slotId: string, snapshot: Snapshot, previewText?: string, storyHash?: string, historyEntries?: readonly DialogueHistoryEntry[]): Promise<SaveSlot>;
|
|
53
|
+
loadSlot(slotId: string, expectedStoryHash?: string): Promise<LoadResult>;
|
|
32
54
|
deleteSlot(slotId: string): Promise<void>;
|
|
33
|
-
listSlots(totalSlots?: number): Promise<(SaveSlot | null)[]>;
|
|
55
|
+
listSlots(totalSlots?: number, expectedStoryHash?: string): Promise<(SaveSlot | null)[]>;
|
|
34
56
|
}
|
|
57
|
+
/** @internal helper for tests */
|
|
58
|
+
export type { StoryState };
|
|
35
59
|
//# sourceMappingURL=save.d.ts.map
|
package/dist/save.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"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"}
|
package/dist/save.js
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
+
import { normalizeStoryState } from './state.js';
|
|
2
|
+
export const CURRENT_SAVE_SCHEMA_VERSION = 2;
|
|
3
|
+
export function fnv1a(str) {
|
|
4
|
+
let hash = 0x811c9dc5;
|
|
5
|
+
for (let i = 0; i < str.length; i++) {
|
|
6
|
+
hash ^= str.charCodeAt(i);
|
|
7
|
+
hash = Math.imul(hash, 0x01000193);
|
|
8
|
+
}
|
|
9
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
10
|
+
}
|
|
11
|
+
export function computeStoryHash(story) {
|
|
12
|
+
const sortedLabels = Object.keys(story.labels ?? {}).sort();
|
|
13
|
+
const parts = [];
|
|
14
|
+
parts.push(`start:${story.meta?.startLabel ?? 'start'}`);
|
|
15
|
+
for (const label of sortedLabels) {
|
|
16
|
+
parts.push(`label:${label}`);
|
|
17
|
+
const instructions = story.labels[label] ?? [];
|
|
18
|
+
for (const inst of instructions) {
|
|
19
|
+
const { loc: _, ...rest } = inst;
|
|
20
|
+
parts.push(JSON.stringify(rest));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return fnv1a(parts.join('\n'));
|
|
24
|
+
}
|
|
25
|
+
function normalizeHistoryEntries(raw) {
|
|
26
|
+
if (!Array.isArray(raw))
|
|
27
|
+
return [];
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const item of raw) {
|
|
30
|
+
if (!item || typeof item !== 'object')
|
|
31
|
+
continue;
|
|
32
|
+
const e = item;
|
|
33
|
+
if (typeof e['text'] !== 'string')
|
|
34
|
+
continue;
|
|
35
|
+
out.push({
|
|
36
|
+
id: typeof e['id'] === 'string' ? e['id'] : `hist_${out.length}`,
|
|
37
|
+
speaker: typeof e['speaker'] === 'string' ? e['speaker'] : undefined,
|
|
38
|
+
speakerDisplayName: typeof e['speakerDisplayName'] === 'string' ? e['speakerDisplayName'] : undefined,
|
|
39
|
+
text: e['text'],
|
|
40
|
+
timestamp: typeof e['timestamp'] === 'number' ? e['timestamp'] : 0
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/** Explicit v1 → v2: add historyEntries (empty if missing). */
|
|
46
|
+
export function migrateSaveV1ToV2(slot) {
|
|
47
|
+
return {
|
|
48
|
+
...slot,
|
|
49
|
+
schemaVersion: 2,
|
|
50
|
+
historyEntries: slot.historyEntries ? [...slot.historyEntries] : [],
|
|
51
|
+
snapshot: {
|
|
52
|
+
...slot.snapshot,
|
|
53
|
+
historyLength: typeof slot.snapshot.historyLength === 'number'
|
|
54
|
+
? slot.snapshot.historyLength
|
|
55
|
+
: (slot.historyEntries?.length ?? 0)
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Migrate / normalize a parsed save slot to the current schema.
|
|
61
|
+
* Returns null if the slot cannot be recovered.
|
|
62
|
+
*/
|
|
63
|
+
export function migrateSaveSlot(raw) {
|
|
64
|
+
if (!raw || typeof raw !== 'object')
|
|
65
|
+
return null;
|
|
66
|
+
const slot = raw;
|
|
67
|
+
const snapshotRaw = slot['snapshot'];
|
|
68
|
+
if (!snapshotRaw || typeof snapshotRaw !== 'object')
|
|
69
|
+
return null;
|
|
70
|
+
const snap = snapshotRaw;
|
|
71
|
+
const normalizedState = normalizeStoryState(snap['state']);
|
|
72
|
+
if (!normalizedState)
|
|
73
|
+
return null;
|
|
74
|
+
const id = typeof slot['id'] === 'string' ? slot['id'] : 'unknown';
|
|
75
|
+
const timestamp = typeof slot['timestamp'] === 'number' ? slot['timestamp'] : Date.now();
|
|
76
|
+
const rawVersion = typeof slot['schemaVersion'] === 'number' ? slot['schemaVersion'] : 1;
|
|
77
|
+
let migrated = {
|
|
78
|
+
schemaVersion: rawVersion,
|
|
79
|
+
storyHash: typeof slot['storyHash'] === 'string' ? slot['storyHash'] : undefined,
|
|
80
|
+
id,
|
|
81
|
+
name: typeof slot['name'] === 'string' ? slot['name'] : `Slot ${id}`,
|
|
82
|
+
timestamp,
|
|
83
|
+
snapshot: {
|
|
84
|
+
id: typeof snap['id'] === 'string' ? snap['id'] : `snap_${timestamp}`,
|
|
85
|
+
timestamp: typeof snap['timestamp'] === 'number' ? snap['timestamp'] : timestamp,
|
|
86
|
+
state: normalizedState,
|
|
87
|
+
historyLength: typeof snap['historyLength'] === 'number' ? snap['historyLength'] : undefined
|
|
88
|
+
},
|
|
89
|
+
previewText: typeof slot['previewText'] === 'string' ? slot['previewText'] : undefined,
|
|
90
|
+
screenshotUrl: typeof slot['screenshotUrl'] === 'string' ? slot['screenshotUrl'] : undefined,
|
|
91
|
+
historyEntries: normalizeHistoryEntries(slot['historyEntries'])
|
|
92
|
+
};
|
|
93
|
+
if (migrated.schemaVersion === undefined || migrated.schemaVersion < 2) {
|
|
94
|
+
migrated = migrateSaveV1ToV2(migrated);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
migrated = {
|
|
98
|
+
...migrated,
|
|
99
|
+
schemaVersion: CURRENT_SAVE_SCHEMA_VERSION
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return migrated;
|
|
103
|
+
}
|
|
1
104
|
export class MemoryStorageAdapter {
|
|
2
105
|
store = new Map();
|
|
3
106
|
getItem(key) {
|
|
@@ -34,39 +137,57 @@ export class SaveManager {
|
|
|
34
137
|
this.storage = storage ?? (typeof localStorage !== 'undefined' ? new LocalStorageAdapter() : new MemoryStorageAdapter());
|
|
35
138
|
this.storagePrefix = storagePrefix;
|
|
36
139
|
}
|
|
37
|
-
async saveSlot(slotId, snapshot, previewText) {
|
|
140
|
+
async saveSlot(slotId, snapshot, previewText, storyHash = '', historyEntries = []) {
|
|
38
141
|
const slot = {
|
|
142
|
+
schemaVersion: CURRENT_SAVE_SCHEMA_VERSION,
|
|
143
|
+
storyHash,
|
|
39
144
|
id: slotId,
|
|
40
145
|
name: `Slot ${slotId}`,
|
|
41
146
|
timestamp: Date.now(),
|
|
42
147
|
snapshot,
|
|
43
|
-
previewText
|
|
148
|
+
previewText,
|
|
149
|
+
historyEntries: [...historyEntries]
|
|
44
150
|
};
|
|
45
151
|
const key = `${this.storagePrefix}${slotId}`;
|
|
46
152
|
await this.storage.setItem(key, JSON.stringify(slot));
|
|
47
153
|
return slot;
|
|
48
154
|
}
|
|
49
|
-
async loadSlot(slotId) {
|
|
155
|
+
async loadSlot(slotId, expectedStoryHash) {
|
|
50
156
|
const key = `${this.storagePrefix}${slotId}`;
|
|
51
157
|
const raw = await this.storage.getItem(key);
|
|
52
158
|
if (!raw)
|
|
53
|
-
return
|
|
159
|
+
return { success: false, reason: 'not_found' };
|
|
54
160
|
try {
|
|
55
|
-
|
|
161
|
+
const parsed = JSON.parse(raw);
|
|
162
|
+
const slot = migrateSaveSlot(parsed);
|
|
163
|
+
if (!slot) {
|
|
164
|
+
return { success: false, reason: 'corrupt' };
|
|
165
|
+
}
|
|
166
|
+
const rawObj = parsed;
|
|
167
|
+
if (typeof rawObj['schemaVersion'] === 'number' && rawObj['schemaVersion'] > CURRENT_SAVE_SCHEMA_VERSION) {
|
|
168
|
+
return { success: false, reason: 'incompatible_schema', slot };
|
|
169
|
+
}
|
|
170
|
+
// When a story hash is expected, require a matching hash (reject missing hashes).
|
|
171
|
+
if (expectedStoryHash) {
|
|
172
|
+
if (!slot.storyHash || slot.storyHash !== expectedStoryHash) {
|
|
173
|
+
return { success: false, reason: 'incompatible_story', slot };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { success: true, slot };
|
|
56
177
|
}
|
|
57
178
|
catch {
|
|
58
|
-
return
|
|
179
|
+
return { success: false, reason: 'corrupt' };
|
|
59
180
|
}
|
|
60
181
|
}
|
|
61
182
|
async deleteSlot(slotId) {
|
|
62
183
|
const key = `${this.storagePrefix}${slotId}`;
|
|
63
184
|
await this.storage.removeItem(key);
|
|
64
185
|
}
|
|
65
|
-
async listSlots(totalSlots = 6) {
|
|
186
|
+
async listSlots(totalSlots = 6, expectedStoryHash) {
|
|
66
187
|
const slots = [];
|
|
67
188
|
for (let i = 1; i <= totalSlots; i++) {
|
|
68
|
-
const
|
|
69
|
-
slots.push(slot);
|
|
189
|
+
const res = await this.loadSlot(String(i), expectedStoryHash);
|
|
190
|
+
slots.push(res.success && res.slot ? res.slot : null);
|
|
70
191
|
}
|
|
71
192
|
return slots;
|
|
72
193
|
}
|
package/dist/save.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save.js","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import type { ChoiceOption } from '@kawaijs/ast';
|
|
1
|
+
import type { ChoiceOption, HotspotOption } from '@kawaijs/ast';
|
|
2
2
|
export interface CharacterState {
|
|
3
3
|
readonly expression?: string;
|
|
4
4
|
readonly position?: string;
|
|
5
|
+
readonly transition?: string;
|
|
6
|
+
readonly layer?: string;
|
|
7
|
+
readonly z?: number;
|
|
8
|
+
readonly cssAnimation?: {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly durationMs?: number;
|
|
11
|
+
/** Bumps so the same animation can re-trigger. */
|
|
12
|
+
readonly token?: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface AchievementState {
|
|
16
|
+
readonly id: string;
|
|
17
|
+
readonly title?: string;
|
|
18
|
+
readonly description?: string;
|
|
19
|
+
readonly unlockedAt: number;
|
|
5
20
|
}
|
|
6
21
|
export interface DialogueState {
|
|
7
22
|
readonly speaker?: string;
|
|
@@ -9,10 +24,19 @@ export interface DialogueState {
|
|
|
9
24
|
readonly speakerColor?: string;
|
|
10
25
|
readonly text: string;
|
|
11
26
|
}
|
|
27
|
+
export interface VfxState {
|
|
28
|
+
readonly effect: 'rain' | 'snow' | 'sakura' | 'fog' | 'tint' | 'stop';
|
|
29
|
+
readonly intensity?: number | string;
|
|
30
|
+
readonly color?: string;
|
|
31
|
+
}
|
|
12
32
|
export interface VisualState {
|
|
13
33
|
readonly background: string | null;
|
|
14
34
|
readonly transition: string | null;
|
|
15
35
|
readonly characters: Record<string, CharacterState>;
|
|
36
|
+
readonly vfx: VfxState | null;
|
|
37
|
+
readonly activeCG: string | null;
|
|
38
|
+
/** Default layer name applied to subsequent shows without an explicit layer. */
|
|
39
|
+
readonly defaultLayer: string | null;
|
|
16
40
|
}
|
|
17
41
|
export interface AudioState {
|
|
18
42
|
readonly music: string | null;
|
|
@@ -31,6 +55,29 @@ export interface StoryState {
|
|
|
31
55
|
readonly audio: AudioState;
|
|
32
56
|
readonly dialogue: DialogueState | null;
|
|
33
57
|
readonly choices: readonly ChoiceOption[] | null;
|
|
58
|
+
/** Clickable stage/CG regions waiting for a player pick. */
|
|
59
|
+
readonly hotspots: readonly HotspotOption[] | null;
|
|
60
|
+
/** CSS theme token applied on the player root (`data-kawa-theme`). */
|
|
61
|
+
readonly theme: string | null;
|
|
62
|
+
/** Named style tokens keyed by UI target (dialogue, stage, root, choices). */
|
|
63
|
+
readonly styleClasses: Readonly<Record<string, string>>;
|
|
64
|
+
readonly unlockedCGs: Record<string, boolean>;
|
|
65
|
+
/** Unlocked achievements / exportable flags. */
|
|
66
|
+
readonly achievements: Readonly<Record<string, AchievementState>>;
|
|
67
|
+
/** Active language code for `{t:key}` string tables. */
|
|
68
|
+
readonly lang: string | null;
|
|
69
|
+
/**
|
|
70
|
+
* When set, the presentation layer should auto-advance after this many ms.
|
|
71
|
+
* Click/keyboard advance may skip the remaining delay.
|
|
72
|
+
*/
|
|
73
|
+
readonly pendingPauseMs: number | null;
|
|
74
|
+
/** Text prompt waiting for the player (`input` directive). */
|
|
75
|
+
readonly pendingInput: {
|
|
76
|
+
readonly variable: string;
|
|
77
|
+
readonly prompt: string;
|
|
78
|
+
} | null;
|
|
79
|
+
/** When false, the dialogue window should be hidden (`window hide`). */
|
|
80
|
+
readonly windowVisible: boolean;
|
|
34
81
|
readonly isWaitingForInput: boolean;
|
|
35
82
|
readonly isFinished: boolean;
|
|
36
83
|
}
|
|
@@ -38,7 +85,14 @@ export interface Snapshot {
|
|
|
38
85
|
readonly id: string;
|
|
39
86
|
readonly timestamp: number;
|
|
40
87
|
readonly state: StoryState;
|
|
88
|
+
/** Dialogue history length at snapshot time — used to trim backlog on rollback. */
|
|
89
|
+
readonly historyLength?: number;
|
|
41
90
|
}
|
|
42
91
|
export declare function createInitialState(startLabel?: string): StoryState;
|
|
92
|
+
/**
|
|
93
|
+
* Normalize a partially-shaped / older save state into a full StoryState.
|
|
94
|
+
* Returns null when the payload is too corrupt to recover.
|
|
95
|
+
*/
|
|
96
|
+
export declare function normalizeStoryState(raw: unknown): StoryState | null;
|
|
43
97
|
export declare function cloneState(state: StoryState): StoryState;
|
|
44
98
|
//# sourceMappingURL=state.d.ts.map
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/state.js
CHANGED
|
@@ -3,11 +3,14 @@ export function createInitialState(startLabel = 'start') {
|
|
|
3
3
|
currentLabel: startLabel,
|
|
4
4
|
instructionPointer: 0,
|
|
5
5
|
callStack: [],
|
|
6
|
-
variables:
|
|
6
|
+
variables: Object.create(null),
|
|
7
7
|
visual: {
|
|
8
8
|
background: null,
|
|
9
9
|
transition: null,
|
|
10
|
-
characters: {}
|
|
10
|
+
characters: {},
|
|
11
|
+
vfx: null,
|
|
12
|
+
activeCG: null,
|
|
13
|
+
defaultLayer: null
|
|
11
14
|
},
|
|
12
15
|
audio: {
|
|
13
16
|
music: null,
|
|
@@ -15,24 +18,126 @@ export function createInitialState(startLabel = 'start') {
|
|
|
15
18
|
},
|
|
16
19
|
dialogue: null,
|
|
17
20
|
choices: null,
|
|
21
|
+
hotspots: null,
|
|
22
|
+
theme: null,
|
|
23
|
+
styleClasses: Object.create(null),
|
|
24
|
+
unlockedCGs: Object.create(null),
|
|
25
|
+
achievements: Object.create(null),
|
|
26
|
+
lang: null,
|
|
27
|
+
pendingPauseMs: null,
|
|
28
|
+
pendingInput: null,
|
|
29
|
+
windowVisible: true,
|
|
18
30
|
isWaitingForInput: false,
|
|
19
31
|
isFinished: false
|
|
20
32
|
};
|
|
21
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Normalize a partially-shaped / older save state into a full StoryState.
|
|
36
|
+
* Returns null when the payload is too corrupt to recover.
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeStoryState(raw) {
|
|
39
|
+
if (!raw || typeof raw !== 'object')
|
|
40
|
+
return null;
|
|
41
|
+
const s = raw;
|
|
42
|
+
if (typeof s['currentLabel'] !== 'string' || typeof s['instructionPointer'] !== 'number') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const base = createInitialState(s['currentLabel']);
|
|
46
|
+
const visualRaw = (s['visual'] && typeof s['visual'] === 'object' ? s['visual'] : {});
|
|
47
|
+
const audioRaw = (s['audio'] && typeof s['audio'] === 'object' ? s['audio'] : {});
|
|
48
|
+
const dialogueRaw = s['dialogue'] && typeof s['dialogue'] === 'object' ? s['dialogue'] : null;
|
|
49
|
+
const callStack = Array.isArray(s['callStack'])
|
|
50
|
+
? s['callStack']
|
|
51
|
+
.filter((f) => !!f && typeof f === 'object')
|
|
52
|
+
.map(f => ({
|
|
53
|
+
returnLabel: typeof f['returnLabel'] === 'string' ? f['returnLabel'] : base.currentLabel,
|
|
54
|
+
returnPointer: typeof f['returnPointer'] === 'number' ? f['returnPointer'] : 0
|
|
55
|
+
}))
|
|
56
|
+
: [];
|
|
57
|
+
const charactersRaw = visualRaw['characters'] && typeof visualRaw['characters'] === 'object'
|
|
58
|
+
? visualRaw['characters']
|
|
59
|
+
: {};
|
|
60
|
+
return {
|
|
61
|
+
currentLabel: s['currentLabel'],
|
|
62
|
+
instructionPointer: s['instructionPointer'],
|
|
63
|
+
callStack,
|
|
64
|
+
variables: s['variables'] && typeof s['variables'] === 'object'
|
|
65
|
+
? Object.assign(Object.create(null), s['variables'])
|
|
66
|
+
: Object.create(null),
|
|
67
|
+
visual: {
|
|
68
|
+
background: typeof visualRaw['background'] === 'string' ? visualRaw['background'] : null,
|
|
69
|
+
transition: typeof visualRaw['transition'] === 'string' ? visualRaw['transition'] : null,
|
|
70
|
+
characters: { ...charactersRaw },
|
|
71
|
+
vfx: visualRaw['vfx'] ?? null,
|
|
72
|
+
activeCG: typeof visualRaw['activeCG'] === 'string' ? visualRaw['activeCG'] : null,
|
|
73
|
+
defaultLayer: typeof visualRaw['defaultLayer'] === 'string' ? visualRaw['defaultLayer'] : null
|
|
74
|
+
},
|
|
75
|
+
audio: {
|
|
76
|
+
music: typeof audioRaw['music'] === 'string' ? audioRaw['music'] : null,
|
|
77
|
+
voice: typeof audioRaw['voice'] === 'string' ? audioRaw['voice'] : null
|
|
78
|
+
},
|
|
79
|
+
dialogue: dialogueRaw && typeof dialogueRaw['text'] === 'string'
|
|
80
|
+
? {
|
|
81
|
+
speaker: typeof dialogueRaw['speaker'] === 'string' ? dialogueRaw['speaker'] : undefined,
|
|
82
|
+
speakerDisplayName: typeof dialogueRaw['speakerDisplayName'] === 'string'
|
|
83
|
+
? dialogueRaw['speakerDisplayName']
|
|
84
|
+
: undefined,
|
|
85
|
+
speakerColor: typeof dialogueRaw['speakerColor'] === 'string' ? dialogueRaw['speakerColor'] : undefined,
|
|
86
|
+
text: dialogueRaw['text']
|
|
87
|
+
}
|
|
88
|
+
: null,
|
|
89
|
+
choices: Array.isArray(s['choices']) ? s['choices'] : null,
|
|
90
|
+
hotspots: null, // never restore mid-hotspot from saves
|
|
91
|
+
theme: typeof s['theme'] === 'string' ? s['theme'] : null,
|
|
92
|
+
styleClasses: s['styleClasses'] && typeof s['styleClasses'] === 'object'
|
|
93
|
+
? Object.assign(Object.create(null), s['styleClasses'])
|
|
94
|
+
: Object.create(null),
|
|
95
|
+
unlockedCGs: s['unlockedCGs'] && typeof s['unlockedCGs'] === 'object'
|
|
96
|
+
? Object.assign(Object.create(null), s['unlockedCGs'])
|
|
97
|
+
: Object.create(null),
|
|
98
|
+
achievements: s['achievements'] && typeof s['achievements'] === 'object'
|
|
99
|
+
? Object.assign(Object.create(null), s['achievements'])
|
|
100
|
+
: Object.create(null),
|
|
101
|
+
lang: typeof s['lang'] === 'string' ? s['lang'] : null,
|
|
102
|
+
pendingPauseMs: typeof s['pendingPauseMs'] === 'number' ? s['pendingPauseMs'] : null,
|
|
103
|
+
pendingInput: null, // never restore mid-prompt from saves
|
|
104
|
+
windowVisible: s['windowVisible'] === false ? false : true,
|
|
105
|
+
isWaitingForInput: Boolean(s['isWaitingForInput']),
|
|
106
|
+
isFinished: Boolean(s['isFinished'])
|
|
107
|
+
};
|
|
108
|
+
}
|
|
22
109
|
export function cloneState(state) {
|
|
23
110
|
return {
|
|
24
111
|
currentLabel: state.currentLabel,
|
|
25
112
|
instructionPointer: state.instructionPointer,
|
|
26
113
|
callStack: state.callStack.map(frame => ({ ...frame })),
|
|
27
|
-
variables:
|
|
114
|
+
variables: Object.assign(Object.create(null), state.variables),
|
|
28
115
|
visual: {
|
|
29
116
|
background: state.visual.background,
|
|
30
117
|
transition: state.visual.transition,
|
|
31
|
-
|
|
118
|
+
vfx: state.visual.vfx ? { ...state.visual.vfx } : null,
|
|
119
|
+
activeCG: state.visual.activeCG,
|
|
120
|
+
defaultLayer: state.visual.defaultLayer,
|
|
121
|
+
characters: Object.fromEntries(Object.entries(state.visual.characters).map(([k, v]) => [
|
|
122
|
+
k,
|
|
123
|
+
{
|
|
124
|
+
...v,
|
|
125
|
+
cssAnimation: v.cssAnimation ? { ...v.cssAnimation } : undefined
|
|
126
|
+
}
|
|
127
|
+
]))
|
|
32
128
|
},
|
|
33
129
|
audio: { ...state.audio },
|
|
34
130
|
dialogue: state.dialogue ? { ...state.dialogue } : null,
|
|
35
131
|
choices: state.choices ? state.choices.map(c => ({ ...c })) : null,
|
|
132
|
+
hotspots: state.hotspots ? state.hotspots.map(h => ({ ...h })) : null,
|
|
133
|
+
theme: state.theme,
|
|
134
|
+
styleClasses: Object.assign(Object.create(null), state.styleClasses),
|
|
135
|
+
unlockedCGs: Object.assign(Object.create(null), state.unlockedCGs),
|
|
136
|
+
achievements: Object.assign(Object.create(null), state.achievements),
|
|
137
|
+
lang: state.lang,
|
|
138
|
+
pendingPauseMs: state.pendingPauseMs ?? null,
|
|
139
|
+
pendingInput: state.pendingInput ? { ...state.pendingInput } : null,
|
|
140
|
+
windowVisible: state.windowVisible !== false,
|
|
36
141
|
isWaitingForInput: state.isWaitingForInput,
|
|
37
142
|
isFinished: state.isFinished
|
|
38
143
|
};
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/vm.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StoryPackage } from '@kawaijs/ast';
|
|
2
|
-
import { type StoryState } from './state.js';
|
|
2
|
+
import { type AchievementState, type StoryState } from './state.js';
|
|
3
3
|
import { HistoryManager } from './history.js';
|
|
4
|
-
import { SaveManager } from './save.js';
|
|
4
|
+
import { SaveManager, type SaveSlot, type LoadResult } from './save.js';
|
|
5
5
|
export interface AudioEvent {
|
|
6
6
|
readonly action: 'play' | 'stop';
|
|
7
7
|
readonly channel: 'music' | 'sound' | 'voice';
|
|
@@ -9,32 +9,74 @@ export interface AudioEvent {
|
|
|
9
9
|
readonly fade?: number;
|
|
10
10
|
readonly loop?: boolean;
|
|
11
11
|
}
|
|
12
|
+
export interface CameraEvent {
|
|
13
|
+
readonly action: 'shake' | 'vpunch' | 'hpunch' | 'flash';
|
|
14
|
+
readonly duration?: number;
|
|
15
|
+
}
|
|
12
16
|
export type StateChangeListener = (state: StoryState) => void;
|
|
13
17
|
export type AudioEventListener = (event: AudioEvent) => void;
|
|
18
|
+
export type CameraEventListener = (event: CameraEvent) => void;
|
|
19
|
+
export type TickListener = (deltaMs: number, totalTimeMs: number) => void;
|
|
20
|
+
export type ErrorListener = (error: Error) => void;
|
|
21
|
+
export interface VMOptions {
|
|
22
|
+
readonly saveManager?: SaveManager;
|
|
23
|
+
readonly maxSnapshots?: number;
|
|
24
|
+
readonly maxCallDepth?: number;
|
|
25
|
+
/** Hard cap on instructions executed in a single burst (prevents infinite jump loops). */
|
|
26
|
+
readonly maxInstructionsPerBurst?: number;
|
|
27
|
+
}
|
|
14
28
|
export declare class StoryVM {
|
|
29
|
+
readonly storyHash: string;
|
|
15
30
|
private readonly story;
|
|
16
31
|
private state;
|
|
17
32
|
private snapshotStack;
|
|
18
33
|
private readonly historyManager;
|
|
19
34
|
private readonly saveManager;
|
|
35
|
+
private readonly maxSnapshots;
|
|
36
|
+
private readonly maxCallDepth;
|
|
37
|
+
private readonly maxInstructionsPerBurst;
|
|
20
38
|
private stateChangeListeners;
|
|
21
39
|
private audioEventListeners;
|
|
40
|
+
private cameraEventListeners;
|
|
41
|
+
private errorListeners;
|
|
42
|
+
private tickListeners;
|
|
43
|
+
private executionTrace;
|
|
44
|
+
private virtualTimeMs;
|
|
22
45
|
private isExecuting;
|
|
23
|
-
constructor(story: StoryPackage,
|
|
46
|
+
constructor(story: StoryPackage, saveManagerOrOptions?: SaveManager | VMOptions);
|
|
24
47
|
getState(): StoryState;
|
|
48
|
+
getStory(): StoryPackage;
|
|
25
49
|
getHistoryManager(): HistoryManager;
|
|
26
50
|
getSaveManager(): SaveManager;
|
|
51
|
+
getExecutionTrace(): readonly string[];
|
|
52
|
+
clearExecutionTrace(): void;
|
|
53
|
+
private recordTrace;
|
|
54
|
+
getVirtualTime(): number;
|
|
55
|
+
tick(deltaMs: number): void;
|
|
56
|
+
onTick(listener: TickListener): () => void;
|
|
27
57
|
onStateChange(listener: StateChangeListener): () => void;
|
|
28
58
|
onAudioEvent(listener: AudioEventListener): () => void;
|
|
29
|
-
|
|
59
|
+
onCameraEvent(listener: CameraEventListener): () => void;
|
|
60
|
+
onError(listener: ErrorListener): () => void;
|
|
61
|
+
private emitCameraEvent;
|
|
62
|
+
private emitError;
|
|
63
|
+
start(atLabel?: string): void;
|
|
30
64
|
/**
|
|
31
65
|
* Advances the story to the next dialogue, choice, or scene event.
|
|
32
66
|
*/
|
|
33
67
|
next(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Completes a pending `input` prompt and continues the story.
|
|
70
|
+
*/
|
|
71
|
+
submitInput(value: string): void;
|
|
34
72
|
/**
|
|
35
73
|
* Selects an option from the current choice menu.
|
|
36
74
|
*/
|
|
37
75
|
choose(choiceIndex: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* Selects a clickable hotspot and jumps to its target label.
|
|
78
|
+
*/
|
|
79
|
+
selectHotspot(id: string): void;
|
|
38
80
|
/**
|
|
39
81
|
* Jumps directly to a label.
|
|
40
82
|
*/
|
|
@@ -44,13 +86,36 @@ export declare class StoryVM {
|
|
|
44
86
|
*/
|
|
45
87
|
rollback(): boolean;
|
|
46
88
|
canRollback(): boolean;
|
|
47
|
-
save(slotId: string): Promise<
|
|
48
|
-
load(slotId: string): Promise<boolean>;
|
|
89
|
+
save(slotId: string): Promise<SaveSlot>;
|
|
90
|
+
load(slotId: string, validateStoryHash?: boolean): Promise<boolean>;
|
|
91
|
+
loadWithDetails(slotId: string, validateStoryHash?: boolean): Promise<LoadResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Restore from an in-memory SaveSlot (continue-links, imported saves).
|
|
94
|
+
* Validates storyHash when present on the slot.
|
|
95
|
+
*/
|
|
96
|
+
loadFromSlot(slot: SaveSlot, validateStoryHash?: boolean): LoadResult;
|
|
97
|
+
private applyLoadedSlot;
|
|
98
|
+
/**
|
|
99
|
+
* Emit stop/play audio events so the presentation layer matches restored state
|
|
100
|
+
* after load or rollback (snapshots store track ids but not live Audio elements).
|
|
101
|
+
*/
|
|
102
|
+
private resyncAudio;
|
|
49
103
|
private executeUntilWaiting;
|
|
50
104
|
private executeInstruction;
|
|
51
105
|
private captureSnapshot;
|
|
52
106
|
private recordSnapshot;
|
|
53
107
|
private notifyStateChanged;
|
|
54
108
|
private emitAudioEvent;
|
|
109
|
+
private persistAchievement;
|
|
110
|
+
/** Merge locally persisted achievements into the current state (call after start/load). */
|
|
111
|
+
hydrateAchievements(): void;
|
|
112
|
+
/** Export achievements as a plain JSON-serializable object (itch / analytics). */
|
|
113
|
+
exportAchievementsJson(): {
|
|
114
|
+
storyHash: string;
|
|
115
|
+
exportedAt: number;
|
|
116
|
+
achievements: AchievementState[];
|
|
117
|
+
};
|
|
118
|
+
/** Set active language for `{t:key}` lookups (also used by `?lang=`). */
|
|
119
|
+
setLang(code: string): void;
|
|
55
120
|
}
|
|
56
121
|
//# sourceMappingURL=vm.d.ts.map
|