@novely/core 0.29.0 → 0.29.2

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.
@@ -1,403 +0,0 @@
1
- // src/constants.ts
2
- var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
3
- var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
4
- var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
5
- var AUDIO_ACTIONS = /* @__PURE__ */ new Set([
6
- "playMusic",
7
- "stopMusic",
8
- "playSound",
9
- "stopSound",
10
- "voice",
11
- "stopVoice"
12
- ]);
13
- var EMPTY_SET = /* @__PURE__ */ new Set();
14
- var DEFAULT_TYPEWRITER_SPEED = "Medium";
15
- var MAIN_CONTEXT_KEY = "$MAIN";
16
-
17
- // src/shared.ts
18
- var STACK_MAP = /* @__PURE__ */ new Map();
19
-
20
- // src/utils.ts
21
- var matchAction = (getContext, values) => {
22
- return (action, props, { ctx, data }) => {
23
- const context = typeof ctx === "string" ? getContext(ctx) : ctx;
24
- return values[action]({
25
- ctx: context,
26
- data
27
- }, props);
28
- };
29
- };
30
- var isNumber = (val) => {
31
- return typeof val === "number";
32
- };
33
- var isNull = (val) => {
34
- return val === null;
35
- };
36
- var isString = (val) => {
37
- return typeof val === "string";
38
- };
39
- var isFunction = (val) => {
40
- return typeof val === "function";
41
- };
42
- var isPromise = (val) => {
43
- return Boolean(val) && (typeof val === "object" || isFunction(val)) && isFunction(val.then);
44
- };
45
- var isEmpty = (val) => {
46
- return typeof val === "object" && !isNull(val) && Object.keys(val).length === 0;
47
- };
48
- var isCSSImage = (str2) => {
49
- const startsWith = String.prototype.startsWith.bind(str2);
50
- return startsWith("http") || startsWith("/") || startsWith(".") || startsWith("data");
51
- };
52
- var str = String;
53
- var isUserRequiredAction = (action, meta) => {
54
- return action === "custom" && meta[0] && meta[0].requireUserAction;
55
- };
56
- var getLanguage = (languages) => {
57
- let { language } = navigator;
58
- if (languages.includes(language)) {
59
- return language;
60
- } else if (languages.includes(language = language.slice(0, 2))) {
61
- return language;
62
- } else if (language = languages.find((value) => navigator.languages.includes(value))) {
63
- return language;
64
- }
65
- return languages[0];
66
- };
67
- var throttle = (fn, ms) => {
68
- let throttled = false, savedArgs, savedThis;
69
- function wrapper(...args) {
70
- if (throttled) {
71
- savedArgs = args;
72
- savedThis = this;
73
- return;
74
- }
75
- fn.apply(this, args);
76
- throttled = true;
77
- setTimeout(function() {
78
- throttled = false;
79
- if (savedArgs) {
80
- wrapper.apply(savedThis, savedArgs);
81
- savedArgs = savedThis = null;
82
- }
83
- }, ms);
84
- }
85
- return wrapper;
86
- };
87
- var findLastIndex = (array, fn) => {
88
- for (let i = array.length - 1; i >= 0; i--) {
89
- if (fn(array[i], array[i + 1])) {
90
- return i;
91
- }
92
- }
93
- return -1;
94
- };
95
- var findLast = (array, fn) => {
96
- return array[findLastIndex(array, fn)];
97
- };
98
- var createControlledPromise = () => {
99
- const object = {
100
- resolve: null,
101
- reject: null,
102
- promise: null,
103
- cancel: null
104
- };
105
- const init = () => {
106
- const promise = new Promise((resolve, reject) => {
107
- object.reject = reject;
108
- object.resolve = (value) => {
109
- resolve({ cancelled: false, value });
110
- };
111
- object.cancel = () => {
112
- resolve({ cancelled: true, value: null });
113
- init();
114
- };
115
- });
116
- object.promise = promise;
117
- };
118
- return init(), object;
119
- };
120
- var findLastPathItemBeforeItemOfType = (path, name) => {
121
- const index = findLastIndex(path, ([_name, _value], next) => {
122
- return isNull(_name) && isNumber(_value) && next != null && next[0] === name;
123
- });
124
- return path[index];
125
- };
126
- var isBlockStatement = (statement) => {
127
- return BLOCK_STATEMENTS.has(statement);
128
- };
129
- var isBlockExitStatement = (statement) => {
130
- return BLOCK_EXIT_STATEMENTS.has(statement);
131
- };
132
- var isSkippedDuringRestore = (item) => {
133
- return SKIPPED_DURING_RESTORE.has(item);
134
- };
135
- var noop = () => {
136
- };
137
- var isAction = (element) => {
138
- return Array.isArray(element) && isString(element[0]);
139
- };
140
- var flattenStory = (story) => {
141
- const entries = Object.entries(story).map(([name, items]) => {
142
- const flat = (item) => {
143
- return item.flatMap((data) => {
144
- const type = data[0];
145
- if (Array.isArray(type))
146
- return flat(data);
147
- return [data];
148
- });
149
- };
150
- return [name, flat(items)];
151
- });
152
- return Object.fromEntries(entries);
153
- };
154
- var once = (fn) => {
155
- let ran = false;
156
- return () => {
157
- if (ran)
158
- return;
159
- ran = true;
160
- fn();
161
- };
162
- };
163
- var isExitImpossible = (path) => {
164
- const blockStatements = path.filter(([item]) => isBlockStatement(item));
165
- const blockExitStatements = path.filter(([item]) => isBlockExitStatement(item));
166
- if (blockStatements.length === 0 && blockExitStatements.length === 0) {
167
- return true;
168
- }
169
- if (blockStatements.length > blockExitStatements.length) {
170
- return false;
171
- }
172
- return !blockExitStatements.every(([name], i) => name && name.startsWith(blockStatements[i][0]));
173
- };
174
- var getOppositeAction = (action) => {
175
- const MAP = {
176
- "showCharacter": "hideCharacter",
177
- "playSound": "stopSound",
178
- "playMusic": "stopMusic",
179
- "voice": "stopVoice"
180
- };
181
- return MAP[action];
182
- };
183
- var getActionsFromPath = (story, path, raw = false) => {
184
- let current = story;
185
- let precurrent;
186
- let ignoreNested = false;
187
- let index = 0;
188
- const max = path.reduce((acc, [type, val]) => {
189
- if (isNull(type) && isNumber(val)) {
190
- return acc + 1;
191
- }
192
- return acc;
193
- }, 0);
194
- const queue = [];
195
- const blocks = [];
196
- for (const [type, val] of path) {
197
- if (type === "jump") {
198
- precurrent = story;
199
- current = current[val];
200
- } else if (type === null) {
201
- precurrent = current;
202
- if (isNumber(val)) {
203
- index++;
204
- let startIndex = 0;
205
- if (ignoreNested) {
206
- const prev = findLastPathItemBeforeItemOfType(path.slice(0, index), "block");
207
- if (prev) {
208
- startIndex = prev[1];
209
- ignoreNested = false;
210
- }
211
- }
212
- for (let i = startIndex; i <= val; i++) {
213
- const item = current[i];
214
- if (!isAction(item))
215
- continue;
216
- const [action, ...meta] = item;
217
- const push = () => {
218
- queue.push([action, meta]);
219
- };
220
- if (raw) {
221
- push();
222
- continue;
223
- }
224
- if (isSkippedDuringRestore(action) || isUserRequiredAction(action, meta)) {
225
- if (index === max && i === val) {
226
- push();
227
- }
228
- continue;
229
- } else {
230
- push();
231
- }
232
- }
233
- }
234
- current = current[val];
235
- } else if (type === "choice") {
236
- blocks.push(precurrent);
237
- current = current[val + 1][1];
238
- } else if (type === "condition") {
239
- blocks.push(precurrent);
240
- current = current[2][val];
241
- } else if (type === "block") {
242
- blocks.push(precurrent);
243
- current = story[val];
244
- } else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
245
- current = blocks.pop();
246
- ignoreNested = true;
247
- }
248
- }
249
- return queue;
250
- };
251
- var createQueueProcessor = (queue) => {
252
- const processedQueue = [];
253
- const keep = /* @__PURE__ */ new Set();
254
- const characters = /* @__PURE__ */ new Set();
255
- const audio = {
256
- music: /* @__PURE__ */ new Set(),
257
- sound: /* @__PURE__ */ new Set()
258
- };
259
- const next = (i) => queue.slice(i + 1);
260
- for (const [i, [action, meta]] of queue.entries()) {
261
- keep.add(action);
262
- if (action === "function" || action === "custom") {
263
- if (action === "custom" && meta[0].callOnlyLatest) {
264
- const notLatest = next(i).some(([, _meta]) => {
265
- if (!_meta || !meta)
266
- return false;
267
- const c0 = _meta[0];
268
- const c1 = meta[0];
269
- const isIdenticalID = c0.id && c1.id && c0.id === c1.id;
270
- const isIdenticalByReference = c0 === c1;
271
- return isIdenticalID || isIdenticalByReference || str(c0) === str(c1);
272
- });
273
- if (notLatest)
274
- continue;
275
- }
276
- processedQueue.push([action, meta]);
277
- } else if (action === "showCharacter" || action === "playSound" || action === "playMusic" || action === "voice") {
278
- const closing = getOppositeAction(action);
279
- const skip = next(i).some(([_action, _meta]) => {
280
- if (!_meta || !meta)
281
- return false;
282
- if (_meta[0] !== meta[0])
283
- return false;
284
- return _action === closing || _action === action;
285
- });
286
- if (skip)
287
- continue;
288
- if (action === "showCharacter") {
289
- characters.add(meta[0]);
290
- } else if (action === "playMusic") {
291
- audio.music.add(meta[0]);
292
- } else if (action === "playSound") {
293
- audio.sound.add(meta[0]);
294
- }
295
- processedQueue.push([action, meta]);
296
- } else if (action === "showBackground" || action === "animateCharacter" || action === "preload") {
297
- const skip = next(i).some(([_action], i2, array) => action === _action);
298
- if (skip)
299
- continue;
300
- processedQueue.push([action, meta]);
301
- } else {
302
- processedQueue.push([action, meta]);
303
- }
304
- }
305
- const run = async (match) => {
306
- for await (const [action, meta] of processedQueue) {
307
- const result = match(action, meta);
308
- if (isPromise(result)) {
309
- await result;
310
- }
311
- }
312
- processedQueue.length = 0;
313
- };
314
- const getKeep = () => {
315
- return {
316
- keep,
317
- characters,
318
- audio
319
- };
320
- };
321
- return {
322
- run,
323
- getKeep
324
- };
325
- };
326
- var getStack = (ctx) => {
327
- const { id } = ctx;
328
- const cached = STACK_MAP.get(id);
329
- if (cached)
330
- return cached;
331
- const stack = [];
332
- STACK_MAP.set(id, stack);
333
- return stack;
334
- };
335
- var createUseStackFunction = (renderer) => {
336
- const useStack = (context) => {
337
- const ctx = typeof context === "string" ? renderer.getContext(context) : context;
338
- const stack = getStack(ctx);
339
- return {
340
- get previous() {
341
- return stack.previous;
342
- },
343
- get value() {
344
- return stack.at(-1);
345
- },
346
- set value(value) {
347
- stack[stack.length - 1] = value;
348
- },
349
- back() {
350
- if (stack.length > 1) {
351
- stack.previous = stack.pop();
352
- ctx.meta.goingBack = true;
353
- }
354
- },
355
- push(value) {
356
- stack.push(value);
357
- },
358
- clear() {
359
- stack.length = 0;
360
- stack.length = 1;
361
- }
362
- };
363
- };
364
- return useStack;
365
- };
366
-
367
- export {
368
- AUDIO_ACTIONS,
369
- EMPTY_SET,
370
- DEFAULT_TYPEWRITER_SPEED,
371
- MAIN_CONTEXT_KEY,
372
- STACK_MAP,
373
- matchAction,
374
- isNumber,
375
- isNull,
376
- isString,
377
- isFunction,
378
- isPromise,
379
- isEmpty,
380
- isCSSImage,
381
- str,
382
- isUserRequiredAction,
383
- getLanguage,
384
- throttle,
385
- findLastIndex,
386
- findLast,
387
- createControlledPromise,
388
- findLastPathItemBeforeItemOfType,
389
- isBlockStatement,
390
- isBlockExitStatement,
391
- isSkippedDuringRestore,
392
- noop,
393
- isAction,
394
- flattenStory,
395
- once,
396
- isExitImpossible,
397
- getOppositeAction,
398
- getActionsFromPath,
399
- createQueueProcessor,
400
- getStack,
401
- createUseStackFunction
402
- };
403
- //# sourceMappingURL=chunk-YQR6UQKB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/shared.ts","../src/utils.ts"],"sourcesContent":["import type { TypewriterSpeed } from './types';\n\nconst SKIPPED_DURING_RESTORE = new Set(['dialog', 'choice', 'input', 'vibrate', 'text'] as const);\n\nconst BLOCK_EXIT_STATEMENTS = new Set(['choice:exit', 'condition:exit', 'block:exit'] as const);\n\nconst BLOCK_STATEMENTS = new Set(['choice', 'condition', 'block'] as const);\n\nconst AUDIO_ACTIONS = new Set([\n 'playMusic',\n 'stopMusic',\n 'playSound',\n 'stopSound',\n 'voice',\n 'stopVoice'\n] as const);\n\nconst EMPTY_SET = new Set<any>();\n\nconst DEFAULT_TYPEWRITER_SPEED: TypewriterSpeed = 'Medium';\n\n/**\n * @internal\n */\nconst MAIN_CONTEXT_KEY = '$MAIN';\n\nexport { SKIPPED_DURING_RESTORE, EMPTY_SET, DEFAULT_TYPEWRITER_SPEED, BLOCK_EXIT_STATEMENTS, BLOCK_STATEMENTS, MAIN_CONTEXT_KEY, AUDIO_ACTIONS };\n","import type { StackHolder } from './types';\n\n/**\n * @internal\n */\nconst STACK_MAP = new Map<string, StackHolder>();\n\nexport { STACK_MAP }\n","import type { ActionProxyProvider, DefaultActionProxyProvider, CustomHandler, Story, ValidAction, GetActionParameters } from './action';\nimport type { Character } from './character';\nimport type { Thenable, Path, PathItem, Save, UseStackFunctionReturnType, StackHolder } from './types';\nimport type { Context, Renderer } from './renderer';\nimport { BLOCK_STATEMENTS, BLOCK_EXIT_STATEMENTS, SKIPPED_DURING_RESTORE } from './constants';\nimport { STACK_MAP } from './shared';\n\ntype MatchActionParams = {\n\tdata: Record<string, unknown>\n\tctx: Context\n}\n\ntype MatchActionMap = {\n\t[Key in keyof DefaultActionProxyProvider]: (params: MatchActionParams, data: Parameters<DefaultActionProxyProvider[Key]>) => void;\n};\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n\tcustom: (params: MatchActionParams, value: [handler: CustomHandler]) => Thenable<void>;\n};\n\ntype MatchActionParameters = {\n\t/**\n\t * Name of context or context\n\t */\n\tctx: string | Context;\n\t/**\n\t * Data from the save\n\t */\n\tdata: Record<string, unknown>;\n}\n\nconst matchAction = <M extends MatchActionMapComplete>(getContext: (name: string) => Context, values: M) => {\n\treturn (action: keyof MatchActionMapComplete, props: any, { ctx, data }: MatchActionParameters) => {\n\t\tconst context = typeof ctx === 'string' ? getContext(ctx) : ctx;\n\n\t\treturn values[action]({\n\t\t\tctx: context,\n\t\t\tdata,\n\t\t}, props);\n\t};\n};\n\nconst isNumber = (val: unknown): val is number => {\n\treturn typeof val === 'number';\n};\n\nconst isNull = (val: unknown): val is null => {\n\treturn val === null;\n};\n\nconst isString = (val: unknown): val is string => {\n\treturn typeof val === 'string';\n};\n\nconst isFunction = (val: unknown): val is (...parameters: any[]) => any => {\n\treturn typeof val === 'function';\n};\n\nconst isPromise = (val: unknown): val is Promise<any> => {\n\treturn Boolean(val) && (typeof val === 'object' || isFunction(val)) && isFunction((val as any).then);\n};\n\nconst isEmpty = (val: unknown): val is Record<PropertyKey, never> => {\n\treturn typeof val === 'object' && !isNull(val) && Object.keys(val).length === 0;\n};\n\nconst isCSSImage = (str: string) => {\n\tconst startsWith = String.prototype.startsWith.bind(str);\n\n\treturn startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n};\n\nconst str = String;\n\nconst isUserRequiredAction = (\n\taction: keyof MatchActionMapComplete,\n\tmeta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n) => {\n\treturn action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n};\n\nconst getLanguage = (languages: string[]) => {\n\tlet { language } = navigator;\n\n\tif (languages.includes(language)) {\n\t\treturn language;\n\t} else if (languages.includes((language = language.slice(0, 2)))) {\n\t\treturn language;\n\t} else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n\t\treturn language;\n\t}\n\n\t/**\n\t * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n\t */\n\treturn languages[0];\n};\n\n/**\n * @copyright Techlead LLC\n * @see https://learn.javascript.ru/task/throttle\n */\nconst throttle = <Fn extends (...args: any[]) => any>(fn: Fn, ms: number) => {\n\tlet throttled = false,\n\t\tsavedArgs: any,\n\t\tsavedThis: any;\n\n\tfunction wrapper(this: any, ...args: any[]) {\n\t\tif (throttled) {\n\t\t\tsavedArgs = args;\n\t\t\t/* eslint-disable @typescript-eslint/no-this-alias */\n\t\t\tsavedThis = this;\n\t\t\treturn;\n\t\t}\n\n\t\tfn.apply(this, args as unknown as any[]);\n\n\t\tthrottled = true;\n\n\t\tsetTimeout(function () {\n\t\t\tthrottled = false;\n\n\t\t\tif (savedArgs) {\n\t\t\t\twrapper.apply(savedThis, savedArgs);\n\t\t\t\tsavedArgs = savedThis = null;\n\t\t\t}\n\t\t}, ms);\n\t}\n\n\treturn wrapper as unknown as (...args: Parameters<Fn>) => void;\n};\n\nconst findLastIndex = <T>(array: T[], fn: (item: T, next?: T) => boolean) => {\n\tfor (let i = array.length - 1; i >= 0; i--) {\n\t\tif (fn(array[i], array[i + 1])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n};\n\nconst findLast = <T>(array: T[], fn: (item: T, next?: T) => boolean) => {\n\treturn array[findLastIndex(array, fn)];\n}\n\ntype ControlledPromise<T> = Promise<\n\t| {\n\t\t\tvalue: T;\n\t\t\tcancelled: false;\n\t }\n\t| {\n\t\t\tvalue: null;\n\t\t\tcancelled: true;\n\t }\n>;\n\ntype ControlledPromiseObj<T> = {\n\tresolve: (value: T | PromiseLike<T>) => void;\n\treject: (reason?: any) => void;\n\n\tpromise: ControlledPromise<T>;\n\n\tcancel: () => void;\n};\n\nconst createControlledPromise = <T = void>() => {\n\tconst object = {\n\t\tresolve: null,\n\t\treject: null,\n\n\t\tpromise: null,\n\n\t\tcancel: null,\n\t} as unknown as ControlledPromiseObj<T>;\n\n\tconst init = () => {\n\t\tconst promise = new Promise((resolve, reject) => {\n\t\t\tobject.reject = reject;\n\t\t\tobject.resolve = (value) => {\n\t\t\t\tresolve({ cancelled: false, value });\n\t\t\t};\n\n\t\t\tobject.cancel = () => {\n\t\t\t\tresolve({ cancelled: true, value: null });\n\t\t\t\tinit();\n\t\t\t};\n\t\t});\n\n\t\t// @ts-expect-error Types does not match and this is expected\n\t\tobject.promise = promise;\n\t};\n\n\treturn init(), object;\n};\n\nconst findLastPathItemBeforeItemOfType = (path: Path, name: PathItem[0]) => {\n\tconst index = findLastIndex(path, ([_name, _value], next) => {\n\t\treturn isNull(_name) && isNumber(_value) && next != null && next[0] === name;\n\t});\n\n\treturn path[index] as undefined | [null, number];\n};\n\nconst isBlockStatement = (statement: unknown): statement is 'choice' | 'condition' | 'block' => {\n\treturn BLOCK_STATEMENTS.has(statement as any);\n};\n\nconst isBlockExitStatement = (\n\tstatement: unknown,\n): statement is 'choice:exit' | 'condition:exit' | 'block:exit' => {\n\treturn BLOCK_EXIT_STATEMENTS.has(statement as any);\n};\n\nconst isSkippedDuringRestore = (item: unknown): item is 'vibrate' | 'dialog' | 'input' | 'choice' | 'text' => {\n\treturn SKIPPED_DURING_RESTORE.has(item as any);\n};\n\nconst noop = () => {};\n\nconst isAction = (\n\telement: unknown,\n): element is [\n\tkeyof MatchActionMapComplete,\n\t...Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n] => {\n\treturn Array.isArray(element) && isString(element[0]);\n};\n\n/**\n * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n */\nconst flattenStory = (story: Story) => {\n\tconst entries = Object.entries(story).map(([name, items]) => {\n\t\tconst flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n\t\t\treturn item.flatMap((data) => {\n\t\t\t\tconst type = data[0];\n\n\t\t\t\t/**\n\t\t\t\t * This is not just an action like `['name', ...arguments]`, but an array of actions\n\t\t\t\t */\n\t\t\t\tif (Array.isArray(type)) return flat(data as ValidAction[]);\n\n\t\t\t\treturn [data as ValidAction];\n\t\t\t});\n\t\t};\n\n\t\treturn [name, flat(items)];\n\t});\n\n\treturn Object.fromEntries(entries);\n};\n\n/**\n * A wrapper on `fn` to make it run only once!\n * @param fn Function that needed to run no more than one time\n */\nconst once = (fn: () => void) => {\n\tlet ran = false;\n\n\treturn () => {\n\t\tif (ran) return;\n\n\t\tran = true;\n\t\tfn();\n\t};\n};\n\nconst isExitImpossible = (path: Path) => {\n\tconst blockStatements = path.filter(([item]) => isBlockStatement(item));\n\tconst blockExitStatements = path.filter(([item]) => isBlockExitStatement(item));\n\n\t/**\n\t * There were no blocks nor exits from blocks\n\t */\n\tif (blockStatements.length === 0 && blockExitStatements.length === 0) {\n\t\treturn true;\n\t}\n\n\t/**\n\t * There is block that can be exited\n\t */\n\tif (blockStatements.length > blockExitStatements.length) {\n\t\treturn false;\n\t}\n\n\treturn !blockExitStatements.every(([name], i) => name && name.startsWith(blockStatements[i][0]!))\n}\n\nconst getOppositeAction = (action: 'showCharacter' | 'playSound' | 'playMusic' | 'voice' | any) => {\n\tconst MAP = {\n\t\t'showCharacter': 'hideCharacter',\n\t\t'playSound': 'stopSound',\n\t\t'playMusic': 'stopMusic',\n\t\t'voice': 'stopVoice'\n\t} as const;\n\n\treturn MAP[action as keyof typeof MAP];\n}\n\nconst getActionsFromPath = (story: Story, path: Path, raw: boolean = false) => {\n\t/**\n\t * Current item in the story\n\t */\n\tlet current: any = story;\n\t/**\n\t * Previous `current` value\n\t */\n\tlet precurrent: any;\n\t/**\n\t * Should we ignore some actions\n\t */\n\tlet ignoreNested = false;\n\t/**\n\t * Current item of type `[null, int]`\n\t */\n\tlet index = 0;\n\n\t/**\n\t * Cound of items of type `[null, int]`\n\t */\n\tconst max = path.reduce((acc, [type, val]) => {\n\t\tif (isNull(type) && isNumber(val)) {\n\t\t\treturn acc + 1;\n\t\t}\n\n\t\treturn acc;\n\t}, 0);\n\n\tconst queue = [] as [any, any][];\n\tconst blocks = [];\n\n\tfor (const [type, val] of path) {\n\t\tif (type === 'jump') {\n\t\t\tprecurrent = story;\n\t\t\tcurrent = current[val];\n\t\t} else if (type === null) {\n\t\t\tprecurrent = current;\n\n\t\t\tif (isNumber(val)) {\n\t\t\t\tindex++;\n\n\t\t\t\tlet startIndex = 0;\n\n\t\t\t\tif (ignoreNested) {\n\t\t\t\t\tconst prev = findLastPathItemBeforeItemOfType(path.slice(0, index), 'block');\n\n\t\t\t\t\tif (prev) {\n\t\t\t\t\t\tstartIndex = prev[1];\n\t\t\t\t\t\tignoreNested = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n\t\t\t\t * Почему-то потребовалось изменить `<` на `<=`, чтобы последний action попадал сюда\n\t\t\t\t */\n\t\t\t\tfor (let i = startIndex; i <= val; i++) {\n\t\t\t\t\tconst item = current[i];\n\n\t\t\t\t\t/**\n\t\t\t\t\t * In case of broken save at least not throw\n\t\t\t\t\t * But is should not happen\n\t\t\t\t\t */\n\t\t\t\t\tif (!isAction(item)) continue;\n\n\t\t\t\t\tconst [action, ...meta] = item;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Add item to queue and action to keep\n\t\t\t\t\t */\n\t\t\t\t\tconst push = () => {\n\t\t\t\t\t\tqueue.push([action, meta]);\n\t\t\t\t\t};\n\n\t\t\t\t\t/**\n\t\t\t\t\t * In case we want pure data then just add it\n\t\t\t\t\t */\n\t\t\t\t\tif (raw) {\n\t\t\t\t\t\tpush();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n\t\t\t\t\t * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n\t\t\t\t\t */\n\t\t\t\t\tif (isSkippedDuringRestore(action) || isUserRequiredAction(action, meta)) {\n\t\t\t\t\t\tif (index === max && i === val) {\n\t\t\t\t\t\t\tpush();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpush();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrent = current[val];\n\t\t} else if (type === 'choice') {\n\t\t\tblocks.push(precurrent);\n\t\t\tcurrent = current[val + 1][1];\n\t\t} else if (type === 'condition') {\n\t\t\tblocks.push(precurrent);\n\t\t\tcurrent = current[2][val];\n\t\t} else if (type === 'block') {\n\t\t\tblocks.push(precurrent);\n\t\t\tcurrent = story[val];\n\t\t} else if (type === 'block:exit' || type === 'choice:exit' || type === 'condition:exit') {\n\t\t\tcurrent = blocks.pop();\n\t\t\tignoreNested = true;\n\t\t}\n\t}\n\n\treturn queue;\n}\n\nconst createQueueProcessor = (queue: [any, any][]) => {\n\tconst processedQueue: [any, any][] = [];\n\n\tconst keep = new Set();\n\tconst characters = new Set();\n\tconst audio = {\n\t\tmusic: new Set(),\n\t\tsound: new Set()\n\t};\n\n\t/**\n\t * Get the next actions array.\n\t */\n\tconst next = (i: number) => queue.slice(i + 1);\n\n\tfor (const [i, [action, meta]] of queue.entries()) {\n\t\t/**\n\t\t * Keep actually does not keep any actions, clear method only works with things like `dialog` which can blink and etc\n\t\t * So it's just easies to add everything in there\n\t\t */\n\t\tkeep.add(action);\n\n\t\tif (action === 'function' || action === 'custom') {\n\t\t\t/**\n\t\t\t * When `callOnlyLatest` is `true`\n\t\t\t */\n\t\t\tif (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n\t\t\t\t/**\n\t\t\t\t * We'll calculate it is `latest` or not\n\t\t\t\t */\n\t\t\t\tconst notLatest = next(i).some(([, _meta]) => {\n\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\tconst c0 = _meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\t\t\t\t\tconst c1 = meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Also check for `undefined`\n\t\t\t\t\t */\n\t\t\t\t\tconst isIdenticalID = c0.id && c1.id && c0.id === c1.id;\n\t\t\t\t\tconst isIdenticalByReference = c0 === c1;\n\n\t\t\t\t\treturn isIdenticalID || isIdenticalByReference || str(c0) === str(c1);\n\t\t\t\t});\n\n\t\t\t\tif (notLatest) continue;\n\t\t\t}\n\n\t\t\tprocessedQueue.push([action, meta]);\n\t\t} else if (action === 'showCharacter' || action === 'playSound' || action === 'playMusic' || action === 'voice') {\n\t\t\tconst closing = getOppositeAction(action);\n\n\t\t\tconst skip = next(i).some(([_action, _meta]) => {\n\t\t\t\tif (!_meta || !meta) return false;\n\t\t\t\tif (_meta[0] !== meta[0]) return false;\n\n\t\t\t\t/**\n\t\t\t\t * It either will be closed OR same action will be ran again\n\t\t\t\t */\n\t\t\t\treturn _action === closing || _action === action;\n\t\t\t});\n\n\t\t\tif (skip) continue;\n\n\t\t\t/**\n\t\t\t * Actually, we do not need check above to add there things to keep because if something was hidden already we could not keep it visible\n\t\t\t */\n\t\t\tif (action === 'showCharacter') {\n\t\t\t\tcharacters.add(meta[0])\n\t\t\t} else if (action === 'playMusic') {\n\t\t\t\taudio.music.add(meta[0])\n\t\t\t} else if (action === 'playSound') {\n\t\t\t\taudio.sound.add(meta[0])\n\t\t\t}\n\n\t\t\tprocessedQueue.push([action, meta]);\n\t\t} else if (action === 'showBackground' || action === 'animateCharacter' || action === 'preload') {\n\t\t\t/**\n\t\t\t * @todo: Также сравнивать персонажей в animateCharacter. Чтобы не просто последний запускался, а последний для персонажа.\n\t\t\t * Тем не менее таким образом могут быть лишнии анимации.\n\t\t\t * Можно проверить, что одна анимация идёт сразу за другой, а не через, например, dialog\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Такая же оптимизация применяется к фонам и анимированию персонажей, и `preload`.\n\t\t\t * Если фон изменится, то нет смысла устанавливать или предзагружать текущий\n\t\t\t */\n\t\t\tconst skip = next(i).some(([_action], i, array) => action === _action);\n\n\t\t\tif (skip) continue;\n\n\t\t\tprocessedQueue.push([action, meta]);\n\t\t} else {\n\t\t\tprocessedQueue.push([action, meta]);\n\t\t}\n\t}\n\n\tconst run = async (match: (action: keyof ActionProxyProvider<Record<string, Character>, string>, props: any) => Thenable<void>) => {\n\t\tfor await (const [action, meta] of processedQueue) {\n\t\t\tconst result = match(action, meta);\n\n\t\t\tif (isPromise(result)) {\n\t\t\t\tawait result;\n\t\t\t}\n\t\t}\n\n\t\tprocessedQueue.length = 0;\n\t}\n\n\tconst getKeep = () => {\n\t\treturn {\n\t\t\tkeep,\n\t\t\tcharacters,\n\t\t\taudio\n\t\t}\n\t}\n\n\treturn {\n\t\trun,\n\t\tgetKeep\n\t}\n}\n\nconst getStack = (ctx: Context) => {\n\tconst { id } = ctx;\n\tconst cached = STACK_MAP.get(id);\n\n\tif (cached) return cached;\n\n\tconst stack = [] as unknown as StackHolder;\n\n\tSTACK_MAP.set(id, stack);\n\n\treturn stack;\n}\n\nconst createUseStackFunction = (renderer: Renderer) => {\n\tconst useStack = (context: Context | string): UseStackFunctionReturnType => {\n\t\tconst ctx = typeof context === 'string' ? renderer.getContext(context) : context;\n\t\tconst stack = getStack(ctx);\n\n\t\treturn {\n\t\t\tget previous() {\n\t\t\t\treturn stack.previous;\n\t\t\t},\n\t\t\tget value() {\n\t\t\t\treturn stack.at(-1)!;\n\t\t\t},\n\t\t\tset value(value) {\n\t\t\t\tstack[stack.length - 1] = value;\n\t\t\t},\n\n\t\t\tback() {\n\t\t\t\tif (stack.length > 1) {\n\t\t\t\t\tstack.previous = stack.pop();\n\t\t\t\t\tctx.meta.goingBack = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\tpush(value: Save) {\n\t\t\t\tstack.push(value);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tstack.length = 0;\n\t\t\t\tstack.length = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn useStack;\n}\n\nexport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetLanguage,\n\tthrottle,\n\tisFunction,\n\tfindLastIndex,\n\tfindLast,\n\tcreateControlledPromise,\n\tfindLastPathItemBeforeItemOfType,\n\tisBlockStatement,\n\tisBlockExitStatement,\n\tisSkippedDuringRestore,\n\tnoop,\n\tisAction,\n\tflattenStory,\n\tonce,\n\tisExitImpossible,\n\tgetOppositeAction,\n\tgetActionsFromPath,\n\tcreateQueueProcessor,\n\tgetStack,\n\tcreateUseStackFunction\n};\n"],"mappings":"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","names":["str","i"]}