@novely/core 0.0.0-beta.5 → 0.0.0-beta.6

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/index.d.ts CHANGED
@@ -40,17 +40,15 @@ type DeepPartial<T> = unknown extends T ? T : T extends object ? {
40
40
  [P in keyof T]?: T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : DeepPartial<T[P]>;
41
41
  } : T;
42
42
 
43
- type ValidAction = ['choice', [number]] | ['clear', []] | ['condition', [() => boolean, Record<string, ValidAction[]>]] | ['dialog', [string | undefined, DialogContent, string | undefined]] | ['end', []] | ['showBackground', [string]] | ['playMusic', [string]] | ['stopMusic', [string]] | ['jump', [string]] | ['showCharacter', [string, keyof Character['emotions'], string?, string?]] | ['hideCharacter', [string, string?, string?, number?]] | ['animateCharacter', [string, number, ...string[]]] | ['wait', [number]] | ['function', [() => Thenable<void>]] | ['input', [string, (meta: {
43
+ type ValidAction = ['choice', [number]] | ['clear', []] | ['condition', [() => boolean, Record<string, ValidAction[]>]] | ['dialog', [string | undefined, Unwrappable, string | undefined]] | ['end', []] | ['showBackground', [string]] | ['playMusic', [string]] | ['stopMusic', [string]] | ['jump', [string]] | ['showCharacter', [string, keyof Character['emotions'], string?, string?]] | ['hideCharacter', [string, string?, string?, number?]] | ['animateCharacter', [string, number, ...string[]]] | ['wait', [number]] | ['function', [() => Thenable<void>]] | ['input', [string, (meta: {
44
44
  input: HTMLInputElement;
45
45
  error: (error: string) => void;
46
46
  event: InputEvent & {
47
47
  currentTarget: HTMLInputElement;
48
48
  };
49
- }) => void, ((input: HTMLInputElement) => void)?]] | ['custom', [CustomHandler]] | ['vibrate', [...number[]]] | ['next', []] | ['text', [...string[]]] | ValidAction[];
49
+ }) => void, ((input: HTMLInputElement) => void)?]] | ['custom', [CustomHandler]] | ['vibrate', [...number[]]] | ['next', []] | ['text', [...string[]]] | ['exit'] | ValidAction[];
50
50
  type Story = Record<string, ValidAction[]>;
51
- type DialogContent = string | ((lang: string, obj: Record<string, unknown>) => string);
52
- type ChoiceContent = string | ((lang: string, obj: Record<string, unknown>) => string);
53
- type TextContent = string | ((lang: string, obj: Record<string, unknown>) => string);
51
+ type Unwrappable = string | ((lang: string, obj: Record<string, unknown>) => string);
54
52
  type CustomHandlerGetResultDataFunction = {
55
53
  (data?: Record<string, unknown>): Record<string, unknown>;
56
54
  };
@@ -81,16 +79,16 @@ type CustomHandler = CustomHandlerFunction & {
81
79
  };
82
80
  type ActionProxyProvider<Characters extends Record<string, Character>> = {
83
81
  choice: {
84
- (...choices: ([ChoiceContent, ValidAction[]] | [ChoiceContent, ValidAction[], () => boolean])[]): ValidAction;
85
- (question: string, ...choices: ([ChoiceContent, ValidAction[]] | [ChoiceContent, ValidAction[], () => boolean])[]): ValidAction;
82
+ (...choices: ([Unwrappable, ValidAction[]] | [Unwrappable, ValidAction[], () => boolean])[]): ValidAction;
83
+ (question: Unwrappable, ...choices: ([Unwrappable, ValidAction[]] | [Unwrappable, ValidAction[], () => boolean])[]): ValidAction;
86
84
  };
87
85
  clear: () => ValidAction;
88
86
  condition: <T extends string | true | false>(condition: () => T, variants: Record<T extends true ? 'true' : T extends false ? 'false' : T, ValidAction[]>) => ValidAction;
89
87
  exit: () => ValidAction;
90
88
  dialog: {
91
- <C extends keyof Characters>(person: C, content: DialogContent, emotion?: keyof Characters[C]['emotions']): ValidAction;
92
- (person: undefined, content: DialogContent, emotion?: undefined): ValidAction;
93
- (person: string, content: DialogContent, emotion?: undefined): ValidAction;
89
+ <C extends keyof Characters>(person: C, content: Unwrappable, emotion?: keyof Characters[C]['emotions']): ValidAction;
90
+ (person: undefined, content: Unwrappable, emotion?: undefined): ValidAction;
91
+ (person: string, content: Unwrappable, emotion?: undefined): ValidAction;
94
92
  };
95
93
  end: () => ValidAction;
96
94
  showBackground: (background: string) => ValidAction;
@@ -108,7 +106,7 @@ type ActionProxyProvider<Characters extends Record<string, Character>> = {
108
106
  };
109
107
  wait: (time: number) => ValidAction;
110
108
  function: (fn: () => Thenable<void>) => ValidAction;
111
- input: (question: string, onInput: (meta: {
109
+ input: (question: Unwrappable, onInput: (meta: {
112
110
  input: HTMLInputElement;
113
111
  error: (error: string) => void;
114
112
  event: InputEvent & {
@@ -118,7 +116,7 @@ type ActionProxyProvider<Characters extends Record<string, Character>> = {
118
116
  custom: (handler: CustomHandler) => ValidAction;
119
117
  vibrate: (...pattern: number[]) => ValidAction;
120
118
  next: () => ValidAction;
121
- text: (...text: TextContent[]) => ValidAction;
119
+ text: (...text: Unwrappable[]) => ValidAction;
122
120
  };
123
121
  type DefaultActionProxyProvider = ActionProxyProvider<Record<string, Character>>;
124
122
  type GetActionParameters<T extends Capitalize<keyof DefaultActionProxyProvider>> = Parameters<DefaultActionProxyProvider[Uncapitalize<T>]>;
@@ -222,7 +220,7 @@ interface NovelyInit<Languages extends string, Characters extends Record<string,
222
220
  */
223
221
  state?: StateScheme;
224
222
  }
225
- declare const novely: <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends _novely_t9n.T9N<Languages, string, string>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen, t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {
223
+ declare const novely: <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends _novely_t9n.T9N<Languages, string>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen, t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {
226
224
  withStory: (s: Story) => void;
227
225
  action: ActionProxyProvider<Characters>;
228
226
  render: () => void;
@@ -233,4 +231,4 @@ declare const novely: <Languages extends string, Characters extends Record<strin
233
231
  t: Inter["t"];
234
232
  };
235
233
 
236
- export { ActionProxyProvider, AudioHandle, Character, CharacterHandle, ChoiceContent, CustomHandler, CustomHandlerGetResult, CustomHandlerGetResultDataFunction, DefaultActionProxyProvider, DialogContent, Emotions, GetActionParameters, Path, Renderer, RendererInit, RendererStore, Storage, StorageData, Stored, Story, TextContent, Thenable, ValidAction, localStorageStorage, novely };
234
+ export { ActionProxyProvider, AudioHandle, Character, CharacterHandle, CustomHandler, CustomHandlerGetResult, CustomHandlerGetResultDataFunction, DefaultActionProxyProvider, Emotions, GetActionParameters, Path, Renderer, RendererInit, RendererStore, Storage, StorageData, Stored, Story, Thenable, Unwrappable, ValidAction, localStorageStorage, novely };
@@ -256,13 +256,25 @@ var Novely = (() => {
256
256
  ]);
257
257
 
258
258
  // ../t9n/dist/index.js
259
- var u = /{{(.*?)}}/g;
260
- var g = (r, i, s, a) => r.replace(u, (e, t, n) => {
261
- e = 0, n = i, t = t.trim();
262
- let l = t.split("@"), o;
263
- for (l.length > 1 && ([t, o] = l), t = t.split("."); n && e < t.length; )
264
- n = n[t[e++]];
265
- return o && s && a && n && (n = s[o][a.select(n)]), n ?? "";
259
+ var S = (t, i) => {
260
+ let a = [];
261
+ for (let r of i) {
262
+ if (!t)
263
+ break;
264
+ let [e, s] = t.split(r, 2);
265
+ a.push(e), t = s;
266
+ }
267
+ return a.push(t), a;
268
+ };
269
+ var d = /{{(.*?)}}/g;
270
+ var c = (t, i, a, r, e) => t.replace(d, (s, p, n) => {
271
+ s = 0, n = i;
272
+ let [m, o, g] = S(p.trim(), ["@", "%"]), l = m.split(".");
273
+ for (; n && s < l.length; )
274
+ n = n[l[s++]];
275
+ o && a && n && e && (n = a[o][e.select(n)]);
276
+ let u = r && g && r[g];
277
+ return u && (n = u(n)), n ?? "";
266
278
  });
267
279
 
268
280
  // src/novely.ts
@@ -422,7 +434,7 @@ var Novely = (() => {
422
434
  if (action2 === "function" || action2 === "custom") {
423
435
  if (action2 === "custom" && meta[0].callOnlyLatest) {
424
436
  const next2 = indexedQueue.slice(i + 1);
425
- const latest2 = !next2.some(([_action, _meta]) => str(_meta[0]) === str(meta[0]));
437
+ const latest2 = !next2.some(([_action, _meta]) => _meta && meta && str(_meta[0]) === str(meta[0]));
426
438
  if (!latest2)
427
439
  continue;
428
440
  }
@@ -488,9 +500,9 @@ var Novely = (() => {
488
500
  },
489
501
  dialog([character, content, emotion]) {
490
502
  const name = (() => {
491
- const c = character, cs = characters;
503
+ const c2 = character, cs = characters;
492
504
  const lang = $.get().meta[0];
493
- return c ? c in cs ? typeof cs[c].name === "string" ? cs[c].name : cs[c].name[lang] : c : "";
505
+ return c2 ? c2 in cs ? typeof cs[c2].name === "string" ? cs[c2].name : cs[c2].name[lang] : c2 : "";
494
506
  })();
495
507
  renderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);
496
508
  },
@@ -509,7 +521,7 @@ var Novely = (() => {
509
521
  const unwrapped = choices.map(([content, action2, visible]) => {
510
522
  return [unwrap(content), action2, visible];
511
523
  });
512
- renderer.choices(question, unwrapped)((selected) => {
524
+ renderer.choices(unwrap(question), unwrapped)((selected) => {
513
525
  enmemory();
514
526
  stack.value[0].push(["choice", isWithoutQuestion ? selected : selected + 1], [null, 0]), render();
515
527
  });
@@ -539,7 +551,7 @@ var Novely = (() => {
539
551
  renderer.ui.showScreen("mainmenu");
540
552
  },
541
553
  input([question, onInput, setup]) {
542
- renderer.input(question, onInput, setup)(forward);
554
+ renderer.input(unwrap(question), onInput, setup)(forward);
543
555
  },
544
556
  custom([handler]) {
545
557
  const result = renderer.custom(handler, goingBack, () => {
@@ -613,7 +625,7 @@ var Novely = (() => {
613
625
  };
614
626
  const render = () => {
615
627
  const referred = refer();
616
- if (!(referred && Array.isArray(referred)))
628
+ if (!Array.isArray(referred))
617
629
  return;
618
630
  const [action2, ...props] = referred;
619
631
  match(action2, props);
@@ -629,7 +641,7 @@ var Novely = (() => {
629
641
  const unwrap = (content) => {
630
642
  const lang = $.get().meta[0];
631
643
  const data = state();
632
- return g(typeof content === "function" ? content(lang, data) : content, data);
644
+ return c(typeof content === "function" ? content(lang, data) : content, data);
633
645
  };
634
646
  return {
635
647
  withStory,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/.pnpm/deepmerge@4.3.0/node_modules/deepmerge/dist/cjs.js","../src/index.ts","../src/utils.ts","../src/store.ts","../src/novely.ts","../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/json/index.mjs","../src/constants.ts","../../t9n/src/translation.ts","../../t9n/src/translations.ts","../src/storage.ts"],"sourcesContent":["'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn Object.propertyIsEnumerable.call(target, symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n","export type { ValidAction, Story, ActionProxyProvider, DefaultActionProxyProvider, GetActionParameters, DialogContent, ChoiceContent, TextContent, CustomHandler, CustomHandlerGetResult, CustomHandlerGetResultDataFunction, } from './action'\nexport type { Emotions, Character } from './character'\nexport type { CharacterHandle, AudioHandle, RendererStore, Renderer, RendererInit } from './renderer'\nexport type { Storage } from './storage'\nexport type { Thenable, Path, StorageData } from './types'\nexport type { Stored } from './store'\nexport type { BaseTranslationStrings } from '@novely/t9n';\n\nexport { novely } from './novely'\nexport { localStorageStorage } from './storage'","import type { ActionProxyProvider, CustomHandler } from './action'\nimport type { Character } from './character'\nimport type { Save, Thenable } from './types'\n\ntype MatchActionMap = {\n [Key in keyof ActionProxyProvider<Record<string, Character>>]: (data: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>) => void;\n}\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n custom: (value: [handler: CustomHandler]) => Thenable<void>;\n}\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n return (action: keyof MatchActionMap, props: any) => {\n return values[action](props);\n }\n}\n\nconst isNumber = (val: unknown): val is number => {\n return typeof val === 'number';\n}\n\nconst isNull = (val: unknown): val is null => {\n return val === null;\n}\n\nconst isString = (val: unknown): val is string => {\n return typeof val === 'string';\n}\n\nconst isCSSImage = (str: string) => {\n const startsWith = String.prototype.startsWith.bind(str);\n\n return startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n}\n\nconst str = (value: unknown) => {\n return String(value);\n}\n\nconst isUserRequiredAction = (action: keyof MatchActionMapComplete, meta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>) => {\n return action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n}\n\nconst getDefaultSave = (state = {}) => {\n return [[[null, 'start'], [null, 0]], state, [Date.now(), 'auto']] as Save;\n}\n\nconst getLanguage = (languages: string[], language = navigator.language) => {\n if (languages.includes(language)) {\n return language;\n } else if (languages.includes((language = language.substring(0, 2)))) {\n return language;\n } else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n return language\n }\n\n /**\n * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n */\n return 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 let throttled = false, savedArgs: any, savedThis: any;\n\n function wrapper() {\n if (throttled) {\n savedArgs = arguments;\n // @ts-ignore\n savedThis = this;\n\n return;\n }\n\n // @ts-ignore\n fn.apply(this, arguments);\n\n throttled = false;\n }\n\n setTimeout(function () {\n throttled = false;\n\n if (savedArgs) {\n wrapper.apply(savedThis, savedArgs);\n savedArgs = savedThis = null;\n }\n }, ms);\n\n return wrapper as unknown as (...args: Parameters<Fn>) => void;\n}\n\nexport { matchAction, isNumber, isNull, isString, isCSSImage, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle }","type Stored<T> = {\n subscribe: (cb: (value: T) => void) => () => void;\n update: (fn: (prev: T) => T) => void;\n get: () => T;\n}\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n const subscribe = (cb: (value: T) => void) => {\n subscribers.add(cb), cb(current);\n\n return () => {\n subscribers.delete(cb);\n }\n };\n\n const push = (value: T) => {\n subscribers.forEach((cb) => cb(value))\n };\n\n const update = (fn: (prev: T) => T) => {\n push((current = fn(current)));\n };\n\n const get = () => {\n return current;\n };\n\n return { subscribe, update, get } as const;\n};\n\nexport { store }\nexport type { Stored }","import type { Character } from './character';\nimport type { ActionProxyProvider, GetActionParameters, Story, ValidAction, DialogContent, ChoiceContent, CustomHandler } from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, StorageData, DeepPartial } from './types'\nimport type { Renderer, RendererInit } from './renderer'\nimport type { SetupT9N } from '@novely/t9n'\nimport { matchAction, isNumber, isNull, isString, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle } from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge'\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State> {\n /**\n * An array of languages supported by the game.\n */\n languages: Languages[];\n /**\n * An object containing the characters in the game.\n */\n characters: Characters;\n /**\n * An object that provides access to the game's storage system.\n */\n storage: Storage;\n /**\n * A function that returns a Renderer object used to display the game's content\n */\n renderer: (characters: RendererInit) => Renderer;\n /**\n * An optional property that specifies the initial screen to display when the game starts\n */\n initialScreen?: \"mainmenu\" | \"game\" | \"saves\" | \"settings\";\n /**\n * An object containing the translation functions used in the game\n */\n t9n: Inter;\n /**\n * Initial state value\n */\n state?: StateScheme;\n}\n\nconst novely = <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen = \"mainmenu\", t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {\n let story: Story;\n\n // @todo: find bug here\n const withStory = (s: Story) => {\n /**\n * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n */\n story = Object.fromEntries(Object.entries(s).map(([name, items]) => {\n const flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n return item.flatMap((data) => {\n const type = data[0];\n\n /**\n * This is not just an action like `['name', ...arguments]`, but an array of actions\n */\n if (Array.isArray(type)) return flat(data as ValidAction[]);\n\n return [data as ValidAction];\n });\n };\n\n return [name, flat(items)];\n }));\n\n /**\n * When `initialScreen` is not a game, we can safely show it\n */\n if (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n }\n\n const action = new Proxy({} as ActionProxyProvider<Characters>, {\n get(_, prop) {\n return (...props: Parameters<ActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]>) => {\n return [prop, ...props];\n }\n }\n });\n\n function state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n function state(): StateScheme;\n function state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n if (!value) return stack.value[1] as StateScheme | void;\n\n const prev = stack.value[1];\n const val = typeof value === 'function' ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n stack.value[1] = val as StateScheme;\n }\n\n const createStack = (current: Save, stack = [current]) => {\n return {\n get value() {\n return stack.at(-1)!;\n },\n set value(value: Save) {\n stack[stack.length - 1] = value;\n },\n back() {\n if (stack.length > 1) stack.pop(), goingBack = true;\n },\n push(value: Save) {\n stack.push(value);\n },\n clear() {\n stack = [getDefaultSave(klona(defaultState))];\n }\n }\n }\n\n /**\n * 1) Novely rendered using the `initialData`, you can still start new game or `load` an empty one - this is scary, imagine losing your progress\n * 2) Actual stored data is loaded, language and etc is changed \n */\n const initialData: StorageData = {\n saves: [],\n meta: [getLanguage(languages)]\n };\n\n const $ = store(initialData);\n\n let initialDataLoaded = false;\n\n const onStorageDataChange = (value: StorageData) => {\n if (initialDataLoaded) storage.set(value);\n };\n\n const throttledOnStorageDataChange = throttle(onStorageDataChange, 120);\n\n $.subscribe(throttledOnStorageDataChange);\n\n storage.get().then(stored => {\n /**\n * Default `localStorageStorage` cannot determine preferred language, and returns empty array\n */\n stored.meta[0] ||= getLanguage(languages);\n\n /**\n * Now the next store updates will entail saving via storage.set\n */\n initialDataLoaded = true;\n\n $.update(() => stored);\n\n /**\n * When initialScreen is game, then we will load it, but after the data is loaded\n */\n if (initialScreen === 'game') restore();\n });\n\n const initial = getDefaultSave(klona(defaultState));\n const stack = createStack(initial);\n\n const save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n if (!initialDataLoaded) return;\n\n $.update(prev => {\n const date = stack.value[2][0];\n const isLatest = prev.saves.findIndex(value => value[2][0] === date) === prev.saves.length - 1;\n\n /**\n * Обновим дату и тип\n */\n stack.value[2][0] = Date.now();\n stack.value[2][1] = type;\n\n if (override) {\n /**\n * Перезапишем\n */\n if (isLatest) {\n /**\n * Сохранения хранятся в массиве. Нельзя перезаписать любое последнее\n * \n * Если перезаписывать старое сохранение, то они не будут идти в хронологическом порядке\n */\n prev.saves[prev.saves.length - 1] = stack.value;\n } else {\n prev.saves.push(stack.value);\n }\n } else {\n /**\n * Добавляем текущее сохранение\n */\n prev.saves.push(stack.value);\n }\n\n /**\n * Устанавливаем новое значение\n */\n return prev;\n });\n }\n\n const newGame = () => {\n if (!initialDataLoaded) return;\n\n const save = getDefaultSave(klona(defaultState));\n\n $.update(prev => {\n prev.saves.push(save), restore(save);\n\n return prev;\n });\n }\n\n /**\n * Устанавливает сохранение\n */\n const set = (save: Save) => {\n stack.value = save;\n\n return restore(save);\n }\n\n let restoring = false;\n let goingBack = false;\n\n /**\n * Визуально восстанавливает историю\n */\n const restore = async (save?: Save) => {\n if (!initialDataLoaded) return;\n\n let latest = save ? save : $.get().saves.at(-1);\n\n /**\n * Если нет сохранённой игры, то запустим ту, которая уже есть\n */\n if (!latest) {\n $.update(() => ({ saves: [initial], meta: [getLanguage(languages)] }));\n\n latest = klona(initial);\n }\n\n restoring = true, stack.value = latest;\n\n /**\n * Показать экран игры\n */\n renderer.ui.showScreen('game');\n\n match('clear', [goingBack]);\n\n /**\n * Текущий элемент в истории\n */\n let current: any = story;\n /**\n * Текущий элемент `[null, int]`\n */\n let index = 0;\n\n /**\n * Число элементов `[null, int]`\n */\n const max = stack.value[0].reduce((acc, [type, val]) => {\n if (isNull(type) && isNumber(val)) return acc + 1;\n\n return acc;\n }, 0);\n\n const queue = [] as [any, any][];\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n if (isString(val)) {\n current = current[val];\n } else if (isNumber(val)) {\n index++;\n\n /**\n * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n */\n for (let i = 0; i < val; i++) {\n const [action, ...meta] = current[i];\n\n /**\n * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n */\n if (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n if (index === max && i === val) {\n queue.push([action, meta]);\n } else {\n continue;\n }\n }\n\n queue.push([action, meta]);\n }\n\n current = current[val];\n }\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n const indexedQueue = queue.map((value, index) => value.concat(index) as [ValidAction[0], ValidAction[1], number]);\n\n for await (const [action, meta, i] of indexedQueue) {\n if (action === 'function' || action === 'custom') {\n /**\n * Если `callOnlyLatest` - `true`\n */\n if (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n /**\n * Вычислим `latest` или нет\n */\n const next = indexedQueue.slice(i + 1);\n const latest = !next.some(([_action, _meta]) => str(_meta[0]) === str(meta[0]));\n\n if (!latest) continue;\n }\n\n /**\n * Action может возвращать Promise. Нужно подожать его `resolve`\n */\n const result = match(action, meta);\n\n /**\n * Дождёмся окончания\n */\n if (result && 'then' in result) await result;\n } else {\n match(action as keyof ActionProxyProvider<Record<string, Character<string>>>, meta);\n }\n }\n\n restoring = false, goingBack = false, render();\n }\n\n const refer = () => {\n let current: any = story;\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n current = current[val];\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n return current;\n }\n\n const renderer = createRenderer({\n characters,\n set,\n restore,\n save,\n newGame,\n stack,\n languages,\n t: t9n.i,\n $\n });\n\n const match = matchAction({\n wait([time]) {\n /**\n * `restoring` может поменяться на `true` перед тем как запуститься `push` из `setTimeout`\n */\n if (!restoring) setTimeout(push, time);\n },\n showBackground([background]) {\n renderer.background(background);\n push()\n },\n playMusic([source]) {\n renderer.music(source, 'music').play();\n push()\n },\n stopMusic([source]) {\n renderer.music(source, 'music').stop();\n push()\n },\n showCharacter([character, emotion, className, style]) {\n const handle = renderer.character(character);\n\n handle.append(className, style);\n handle.withEmotion(emotion)();\n\n push()\n },\n hideCharacter([character, className, style, duration]) {\n const handle = renderer.character(character);\n\n handle.remove(className, style, duration)(push);\n },\n dialog([character, content, emotion]) {\n /**\n * Имя персонажа, с учетом выбранного языка\n */\n const name = (() => {\n const c = character, cs = characters;\n const lang = $.get().meta[0];\n\n return c ? c in cs ? typeof cs[c].name === 'string' ? cs[c].name as string : (cs[c].name as Record<string, string>)[lang] : c : '';\n })();\n\n renderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n },\n function([fn]) {\n const result = fn();\n\n if (!restoring) result ? result.then(push) : push();\n\n return result;\n },\n choice([question, ...choices]) {\n const isWithoutQuestion = Array.isArray(question);\n\n if (isWithoutQuestion) {\n /**\n * Первый элемент может быть как строкой, так и элементов выбора\n */\n choices.unshift(question as unknown as [ChoiceContent, ValidAction[], () => boolean]);\n /**\n * Значит, текст не требуется\n */\n question = '';\n }\n\n const unwrapped = choices.map(([content, action, visible]) => {\n return [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n });\n\n renderer.choices(question, unwrapped)((selected) => {\n enmemory();\n\n /**\n * Если был вопрос, то `index` смещается на единицу назад, поэтому нужно добавить единицу\n */\n stack.value[0].push(['choice', isWithoutQuestion ? selected : selected + 1], [null, 0]), render();\n });\n },\n jump([scene]) {\n stack.value[0] = [[null, scene], [null, 0]];\n\n renderer.clear(false)(() => {\n if (!restoring) render();\n })\n },\n clear() {\n try {\n navigator.vibrate(0)\n } finally {\n renderer.clear(goingBack)(push);\n }\n },\n condition([condition]) {\n const value = condition();\n\n if (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n },\n end() {\n /**\n * Save Current Game\n */\n save(false, 'auto');\n /**\n * Clear the Scene\n */\n match('clear', []);\n /**\n * Go to the main menu\n */\n renderer.ui.showScreen('mainmenu');\n },\n input([question, onInput, setup]) {\n renderer.input(question, onInput, setup)(forward);\n },\n custom([handler]) {\n const result = renderer.custom(handler, goingBack, () => {\n if (!restoring && handler.requireUserAction) enmemory();\n if (!restoring) push();\n });\n\n return result;\n },\n vibrate(pattern) {\n try {\n navigator.vibrate(pattern)\n } finally {\n push()\n }\n },\n next() {\n push();\n },\n animateCharacter([character, timeout, ...classes]) {\n const handler: CustomHandler = () => {\n const char = renderer.store.characters[character];\n\n /**\n * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n */\n if (!char) return;\n\n const target = char.canvas;\n\n /**\n * Character is not found\n */\n if (!target) return;\n\n const classNames = classes.filter(className => !target.classList.contains(className));\n\n target.classList.add(...classNames);\n\n setTimeout(() => {\n target.classList.remove(...classNames);\n }, timeout);\n }\n\n handler.callOnlyLatest = true;\n\n return renderer.custom(handler, goingBack, () => { }), push();\n },\n text(text) {\n renderer.text(text.map(unwrap).join(' '), forward);\n },\n exit() {\n const path = stack.value[0];\n\n for (let i = path.length - 1; i > 0; i--) {\n if (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n stack.value[0] = path.slice(0, i);\n next();\n\n break;\n }\n\n render();\n }\n });\n\n const enmemory = () => {\n if (restoring) return;\n\n const current = klona(stack.value);\n\n current[0] = klona(stack.value[0]);\n\n current[2][0] = new Date().valueOf();\n current[2][1] = 'auto';\n\n stack.push(current);\n }\n\n const next = () => {\n const path = stack.value[0];\n /**\n * Последний элемент пути\n */\n const last = path[path.length - 1]!;\n\n /**\n * Если он вида `[null, int]` - увеличивает `int`\n */\n if (isNull(last[0]) && isNumber(last[1])) {\n last[1] = last[1] + 1;\n return;\n }\n\n /**\n * Иначе добавляет новое `[null int]`\n */\n path.push([null, 0]);\n }\n\n const render = () => {\n const referred = refer();\n\n if (!(referred && Array.isArray(referred))) return;\n\n const [action, ...props] = referred;\n\n match(action, props);\n }\n\n const push = () => {\n if (!restoring) next(), render();\n }\n\n const forward = () => {\n enmemory();\n push();\n }\n\n const unwrap = (content: DialogContent | ChoiceContent) => {\n const lang = $.get().meta[0];\n const data = state();\n\n return replaceT9N(typeof content === 'function' ? content(lang, data) : content, data);\n }\n\n return {\n withStory,\n action,\n render,\n state,\n t: t9n.t as Inter['t'],\n }\n}\n\nexport { novely }\n","export function klona(val) {\n\tvar k, out, tmp;\n\n\tif (Array.isArray(val)) {\n\t\tout = Array(k=val.length);\n\t\twhile (k--) out[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\treturn out;\n\t}\n\n\tif (Object.prototype.toString.call(val) === '[object Object]') {\n\t\tout = {}; // null\n\t\tfor (k in val) {\n\t\t\tif (k === '__proto__') {\n\t\t\t\tObject.defineProperty(out, k, {\n\t\t\t\t\tvalue: klona(val[k]),\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tout[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n\n\treturn val;\n}\n","const SKIPPED_DURING_RESTORE = new Set([\n 'dialog',\n 'input',\n 'vibrate',\n 'text'\n] as const);\n\nexport { SKIPPED_DURING_RESTORE }","import type { BaseTranslationStrings } from './translations';\n\ntype PluralType = Intl.LDMLPluralRule;\ntype FunctionalSetupT9N = <LanguageKey extends string, PluralKey extends string, StringKey extends string>(parameters: { [Lang in LanguageKey]: { pluralization: { [Plural in PluralKey]: Partial<Record<PluralType, string>> }; internal: { [Key in BaseTranslationStrings]: string }; strings: { [Str in StringKey]: string } } }) => T9N<LanguageKey, PluralKey, StringKey>\ntype SetupT9N<LanguageKey extends string> = <PluralKey extends string, StringKey extends string>(parameters: { [Lang in LanguageKey]: { pluralization: { [Plural in PluralKey]: Partial<Record<PluralType, string>> }; internal: { [Key in BaseTranslationStrings]: string }; strings: { [Str in StringKey]: string } } }) => T9N<LanguageKey, PluralKey, StringKey>\n\ntype T9N<LanguageKey extends string, _PluralKey extends string, StringKey extends string> = {\n t(key: StringKey): (lang: LanguageKey | (string & {}), obj: Record<string, unknown>) => string;\n i(key: StringKey, lang: LanguageKey | (string & {})): string;\n}\n\nconst RGX = /{{(.*?)}}/g;\n\nconst replace = (str: string, obj: Record<string, unknown>, pluralization?: Record<string, Record<string, PluralType>>, pr?: Intl.PluralRules) => {\n return str.replace(RGX, (x: any, key: any, y: any) => {\n x = 0;\n y = obj;\n\n key = (key as string).trim();\n\n let at = (key as string).split('@');\n let plural: string | undefined;\n\n if (at.length > 1) {\n ([key, plural] = at);\n }\n\n key = (key as string).split('.');\n\n while (y && x < key.length) {\n y = y[key[x++]];\n }\n\n if (plural && pluralization && pr && y) {\n y = pluralization[plural][pr!.select(y)];\n }\n\n return y != null ? y : '';\n });\n}\n\nconst createT9N: FunctionalSetupT9N = (parameters) => {\n let locale: string | undefined;\n let pr: Intl.PluralRules | undefined;\n\n return {\n t(key) {\n return (lang, obj) => {\n /**\n * At first run `locale` and `pr` are not defined.\n * When `locale` changes, `pr` should be updated`\n */\n if (!locale || !pr || lang != locale) {\n pr = new Intl.PluralRules(locale = lang);\n }\n\n // @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n return replace(parameters[lang]['strings'][key], obj, parameters[lang]['pluralization']);\n }\n },\n i(key, lang) {\n // @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n return parameters[lang]['internal'][key] as string;\n }\n }\n}\n\nexport { createT9N, replace }\nexport type { SetupT9N, T9N, FunctionalSetupT9N } ","const RU = {\n 'NewGame': 'Новая игра',\n 'HomeScreen': 'Главный экран',\n 'ToTheGame': 'К игре',\n 'Language': 'Язык',\n 'NoSaves': 'Сохранений нет',\n 'LoadSave': 'Загрузить',\n 'Saves': 'Сохранения',\n 'Settings': 'Настройки',\n 'Sumbit': 'Подтвердить',\n 'GoBack': 'Назад',\n 'DoSave': 'Сохранение',\n 'Auto': 'Авто',\n 'Stop': 'Стоп',\n 'Exit': 'Выход',\n 'Automatic': 'Автоматическое',\n 'Manual': 'Ручное',\n 'Remove': 'Удалить',\n 'LoadASaveFrom': 'Загрузить сохранение от',\n 'DeleteASaveFrom': 'Удалить сохранение от',\n};\n\nconst EN = {\n 'NewGame': 'New Game',\n 'HomeScreen': 'Home Screen',\n 'ToTheGame': 'To the Game',\n 'Language': 'Language',\n 'NoSaves': 'No saves',\n 'LoadSave': 'Load',\n 'Saves': 'Saves',\n 'Settings': 'Settings',\n 'Sumbit': 'Submit',\n 'GoBack': 'Go back',\n 'DoSave': 'Save',\n 'Auto': 'Auto',\n 'Stop': 'Stop',\n 'Exit': 'Exit',\n 'Automatic': 'Automatic',\n 'Manual': 'Manual',\n 'Remove': 'Remove',\n 'LoadASaveFrom': 'Load a save from',\n 'DeleteASaveFrom': 'Delete a save from',\n};\n\nconst JP = {\n 'NewGame': '新しいゲーム',\n 'HomeScreen': 'ホーム画面',\n 'ToTheGame': 'ゲームへ',\n 'Language': '言語',\n 'NoSaves': 'セーブがありません',\n 'LoadSave': 'ロード',\n 'Saves': 'セーブ',\n 'Settings': '設定',\n 'Sumbit': '提出する',\n 'GoBack': '戻る',\n 'DoSave': 'セーブする',\n 'Auto': 'オート',\n 'Stop': '停止',\n 'Exit': '終了する',\n 'Automatic': '自動',\n 'Manual': '手動',\n 'Remove': '削除する',\n 'LoadASaveFrom': 'からセーブを読み込む',\n 'DeleteASaveFrom': 'からセーブを削除する',\n};\n\ntype BaseTranslationStrings = keyof typeof RU;\n\nexport { RU, EN, JP }\nexport type { BaseTranslationStrings }","import type { StorageData } from './types'\n\ninterface LocalStorageStorageSettings {\n key: string\n}\n\ninterface Storage {\n get: () => Promise<StorageData>;\n set: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n return {\n async get() {\n const value = localStorage.getItem(options.key);\n\n return value ? JSON.parse(value) : { saves: [], meta: [] };\n },\n async set(data) {\n localStorage.setItem(options.key, JSON.stringify(data));\n }\n }\n}\n\nexport type { Storage }\nexport { localStorageStorage }"],"mappings":"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","names":["isMergeableObject","deepmerge","RGX","replace","str","obj","pluralization","pr","x","key","y","at","plural","deepmerge","stack","save","action","index","next","latest"]}
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/deepmerge@4.3.0/node_modules/deepmerge/dist/cjs.js","../src/index.ts","../src/utils.ts","../src/store.ts","../src/novely.ts","../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/json/index.mjs","../src/constants.ts","../../t9n/src/lib.ts","../../t9n/src/translation.ts","../../t9n/src/translations.ts","../src/storage.ts"],"sourcesContent":["'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn Object.propertyIsEnumerable.call(target, symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n","export type { ValidAction, Story, ActionProxyProvider, DefaultActionProxyProvider, GetActionParameters, Unwrappable, CustomHandler, CustomHandlerGetResult, CustomHandlerGetResultDataFunction, } from './action'\nexport type { Emotions, Character } from './character'\nexport type { CharacterHandle, AudioHandle, RendererStore, Renderer, RendererInit } from './renderer'\nexport type { Storage } from './storage'\nexport type { Thenable, Path, StorageData } from './types'\nexport type { Stored } from './store'\nexport type { BaseTranslationStrings } from '@novely/t9n';\n\nexport { novely } from './novely'\nexport { localStorageStorage } from './storage'","import type { ActionProxyProvider, CustomHandler } from './action'\nimport type { Character } from './character'\nimport type { Save, Thenable } from './types'\n\ntype MatchActionMap = {\n [Key in keyof ActionProxyProvider<Record<string, Character>>]: (data: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>) => void;\n}\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n custom: (value: [handler: CustomHandler]) => Thenable<void>;\n}\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n return (action: keyof MatchActionMap, props: any) => {\n return values[action](props);\n }\n}\n\nconst isNumber = (val: unknown): val is number => {\n return typeof val === 'number';\n}\n\nconst isNull = (val: unknown): val is null => {\n return val === null;\n}\n\nconst isString = (val: unknown): val is string => {\n return typeof val === 'string';\n}\n\nconst isCSSImage = (str: string) => {\n const startsWith = String.prototype.startsWith.bind(str);\n\n return startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n}\n\nconst str = (value: unknown) => {\n return String(value);\n}\n\nconst isUserRequiredAction = (action: keyof MatchActionMapComplete, meta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>) => {\n return action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n}\n\nconst getDefaultSave = (state = {}) => {\n return [[[null, 'start'], [null, 0]], state, [Date.now(), 'auto']] as Save;\n}\n\nconst getLanguage = (languages: string[], language = navigator.language) => {\n if (languages.includes(language)) {\n return language;\n } else if (languages.includes((language = language.substring(0, 2)))) {\n return language;\n } else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n return language\n }\n\n /**\n * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n */\n return 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 let throttled = false, savedArgs: any, savedThis: any;\n\n function wrapper() {\n if (throttled) {\n savedArgs = arguments;\n // @ts-ignore\n savedThis = this;\n\n return;\n }\n\n // @ts-ignore\n fn.apply(this, arguments);\n\n throttled = false;\n }\n\n setTimeout(function () {\n throttled = false;\n\n if (savedArgs) {\n wrapper.apply(savedThis, savedArgs);\n savedArgs = savedThis = null;\n }\n }, ms);\n\n return wrapper as unknown as (...args: Parameters<Fn>) => void;\n}\n\nexport { matchAction, isNumber, isNull, isString, isCSSImage, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle }","type Stored<T> = {\n subscribe: (cb: (value: T) => void) => () => void;\n update: (fn: (prev: T) => T) => void;\n get: () => T;\n}\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n const subscribe = (cb: (value: T) => void) => {\n subscribers.add(cb), cb(current);\n\n return () => {\n subscribers.delete(cb);\n }\n };\n\n const push = (value: T) => {\n subscribers.forEach((cb) => cb(value))\n };\n\n const update = (fn: (prev: T) => T) => {\n push((current = fn(current)));\n };\n\n const get = () => {\n return current;\n };\n\n return { subscribe, update, get } as const;\n};\n\nexport { store }\nexport type { Stored }","import type { Character } from './character';\nimport type { ActionProxyProvider, GetActionParameters, Story, ValidAction, Unwrappable, CustomHandler } from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, StorageData, DeepPartial } from './types'\nimport type { Renderer, RendererInit } from './renderer'\nimport type { SetupT9N } from '@novely/t9n'\nimport { matchAction, isNumber, isNull, isString, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle } from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge'\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State> {\n /**\n * An array of languages supported by the game.\n */\n languages: Languages[];\n /**\n * An object containing the characters in the game.\n */\n characters: Characters;\n /**\n * An object that provides access to the game's storage system.\n */\n storage: Storage;\n /**\n * A function that returns a Renderer object used to display the game's content\n */\n renderer: (characters: RendererInit) => Renderer;\n /**\n * An optional property that specifies the initial screen to display when the game starts\n */\n initialScreen?: \"mainmenu\" | \"game\" | \"saves\" | \"settings\";\n /**\n * An object containing the translation functions used in the game\n */\n t9n: Inter;\n /**\n * Initial state value\n */\n state?: StateScheme;\n}\n\nconst novely = <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen = \"mainmenu\", t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {\n let story: Story;\n\n // @todo: find bug here\n const withStory = (s: Story) => {\n /**\n * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n */\n story = Object.fromEntries(Object.entries(s).map(([name, items]) => {\n const flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n return item.flatMap((data) => {\n const type = data[0];\n\n /**\n * This is not just an action like `['name', ...arguments]`, but an array of actions\n */\n if (Array.isArray(type)) return flat(data as ValidAction[]);\n\n return [data as ValidAction];\n });\n };\n\n return [name, flat(items)];\n }));\n\n /**\n * When `initialScreen` is not a game, we can safely show it\n */\n if (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n }\n\n const action = new Proxy({} as ActionProxyProvider<Characters>, {\n get(_, prop) {\n return (...props: Parameters<ActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]>) => {\n return [prop, ...props];\n }\n }\n });\n\n function state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n function state(): StateScheme;\n function state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n if (!value) return stack.value[1] as StateScheme | void;\n\n const prev = stack.value[1];\n const val = typeof value === 'function' ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n stack.value[1] = val as StateScheme;\n }\n\n const createStack = (current: Save, stack = [current]) => {\n return {\n get value() {\n return stack.at(-1)!;\n },\n set value(value: Save) {\n stack[stack.length - 1] = value;\n },\n back() {\n if (stack.length > 1) stack.pop(), goingBack = true;\n },\n push(value: Save) {\n stack.push(value);\n },\n clear() {\n stack = [getDefaultSave(klona(defaultState))];\n }\n }\n }\n\n /**\n * 1) Novely rendered using the `initialData`, you can still start new game or `load` an empty one - this is scary, imagine losing your progress\n * 2) Actual stored data is loaded, language and etc is changed \n */\n const initialData: StorageData = {\n saves: [],\n meta: [getLanguage(languages)]\n };\n\n const $ = store(initialData);\n\n let initialDataLoaded = false;\n\n const onStorageDataChange = (value: StorageData) => {\n if (initialDataLoaded) storage.set(value);\n };\n\n const throttledOnStorageDataChange = throttle(onStorageDataChange, 120);\n\n $.subscribe(throttledOnStorageDataChange);\n\n storage.get().then(stored => {\n /**\n * Default `localStorageStorage` cannot determine preferred language, and returns empty array\n */\n stored.meta[0] ||= getLanguage(languages);\n\n /**\n * Now the next store updates will entail saving via storage.set\n */\n initialDataLoaded = true;\n\n $.update(() => stored);\n\n /**\n * When initialScreen is game, then we will load it, but after the data is loaded\n */\n if (initialScreen === 'game') restore();\n });\n\n const initial = getDefaultSave(klona(defaultState));\n const stack = createStack(initial);\n\n const save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n if (!initialDataLoaded) return;\n\n $.update(prev => {\n const date = stack.value[2][0];\n const isLatest = prev.saves.findIndex(value => value[2][0] === date) === prev.saves.length - 1;\n\n /**\n * Обновим дату и тип\n */\n stack.value[2][0] = Date.now();\n stack.value[2][1] = type;\n\n if (override) {\n /**\n * Перезапишем\n */\n if (isLatest) {\n /**\n * Сохранения хранятся в массиве. Нельзя перезаписать любое последнее\n * \n * Если перезаписывать старое сохранение, то они не будут идти в хронологическом порядке\n */\n prev.saves[prev.saves.length - 1] = stack.value;\n } else {\n prev.saves.push(stack.value);\n }\n } else {\n /**\n * Добавляем текущее сохранение\n */\n prev.saves.push(stack.value);\n }\n\n /**\n * Устанавливаем новое значение\n */\n return prev;\n });\n }\n\n const newGame = () => {\n if (!initialDataLoaded) return;\n\n const save = getDefaultSave(klona(defaultState));\n\n $.update(prev => {\n prev.saves.push(save), restore(save);\n\n return prev;\n });\n }\n\n /**\n * Устанавливает сохранение\n */\n const set = (save: Save) => {\n stack.value = save;\n\n return restore(save);\n }\n\n let restoring = false;\n let goingBack = false;\n\n /**\n * Визуально восстанавливает историю\n */\n const restore = async (save?: Save) => {\n if (!initialDataLoaded) return;\n\n let latest = save ? save : $.get().saves.at(-1);\n\n /**\n * Если нет сохранённой игры, то запустим ту, которая уже есть\n */\n if (!latest) {\n $.update(() => ({ saves: [initial], meta: [getLanguage(languages)] }));\n\n latest = klona(initial);\n }\n\n restoring = true, stack.value = latest;\n\n /**\n * Показать экран игры\n */\n renderer.ui.showScreen('game');\n\n match('clear', [goingBack]);\n\n /**\n * Текущий элемент в истории\n */\n let current: any = story;\n /**\n * Текущий элемент `[null, int]`\n */\n let index = 0;\n\n /**\n * Число элементов `[null, int]`\n */\n const max = stack.value[0].reduce((acc, [type, val]) => {\n if (isNull(type) && isNumber(val)) return acc + 1;\n\n return acc;\n }, 0);\n\n const queue = [] as [any, any][];\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n if (isString(val)) {\n current = current[val];\n } else if (isNumber(val)) {\n index++;\n\n /**\n * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n */\n for (let i = 0; i < val; i++) {\n const [action, ...meta] = current[i];\n\n /**\n * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n */\n if (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n if (index === max && i === val) {\n queue.push([action, meta]);\n } else {\n continue;\n }\n }\n\n queue.push([action, meta]);\n }\n\n current = current[val];\n }\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n const indexedQueue = queue.map((value, index) => value.concat(index) as [ValidAction[0], ValidAction[1], number]);\n\n for await (const [action, meta, i] of indexedQueue) {\n if (action === 'function' || action === 'custom') {\n /**\n * Если `callOnlyLatest` - `true`\n */\n if (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n /**\n * Вычислим `latest` или нет\n */\n const next = indexedQueue.slice(i + 1);\n const latest = !next.some(([_action, _meta]) => _meta && meta && str(_meta[0]) === str(meta[0]));\n\n if (!latest) continue;\n }\n\n /**\n * Action может возвращать Promise. Нужно подожать его `resolve`\n */\n const result = match(action, meta);\n\n /**\n * Дождёмся окончания\n */\n if (result && 'then' in result) await result;\n } else {\n match(action as keyof ActionProxyProvider<Record<string, Character<string>>>, meta);\n }\n }\n\n restoring = false, goingBack = false, render();\n }\n\n const refer = () => {\n let current: any = story;\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n current = current[val];\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n return current;\n }\n\n const renderer = createRenderer({\n characters,\n set,\n restore,\n save,\n newGame,\n stack,\n languages,\n t: t9n.i,\n $\n });\n\n const match = matchAction({\n wait([time]) {\n /**\n * `restoring` может поменяться на `true` перед тем как запуститься `push` из `setTimeout`\n */\n if (!restoring) setTimeout(push, time);\n },\n showBackground([background]) {\n renderer.background(background);\n push()\n },\n playMusic([source]) {\n renderer.music(source, 'music').play();\n push()\n },\n stopMusic([source]) {\n renderer.music(source, 'music').stop();\n push()\n },\n showCharacter([character, emotion, className, style]) {\n const handle = renderer.character(character);\n\n handle.append(className, style);\n handle.withEmotion(emotion)();\n\n push()\n },\n hideCharacter([character, className, style, duration]) {\n const handle = renderer.character(character);\n\n handle.remove(className, style, duration)(push);\n },\n dialog([character, content, emotion]) {\n /**\n * Имя персонажа, с учетом выбранного языка\n */\n const name = (() => {\n const c = character, cs = characters;\n const lang = $.get().meta[0];\n\n return c ? c in cs ? typeof cs[c].name === 'string' ? cs[c].name as string : (cs[c].name as Record<string, string>)[lang] : c : '';\n })();\n\n renderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n },\n function([fn]) {\n const result = fn();\n\n if (!restoring) result ? result.then(push) : push();\n\n return result;\n },\n choice([question, ...choices]) {\n const isWithoutQuestion = Array.isArray(question);\n\n if (isWithoutQuestion) {\n /**\n * Первый элемент может быть как строкой, так и элементов выбора\n */\n choices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n /**\n * Значит, текст не требуется\n */\n question = '';\n }\n\n const unwrapped = choices.map(([content, action, visible]) => {\n return [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n });\n\n renderer.choices(unwrap(question), unwrapped)((selected) => {\n enmemory();\n\n /**\n * Если был вопрос, то `index` смещается на единицу назад, поэтому нужно добавить единицу\n */\n stack.value[0].push(['choice', isWithoutQuestion ? selected : selected + 1], [null, 0]), render();\n });\n },\n jump([scene]) {\n stack.value[0] = [[null, scene], [null, 0]];\n\n renderer.clear(false)(() => {\n if (!restoring) render();\n })\n },\n clear() {\n try {\n navigator.vibrate(0)\n } finally {\n renderer.clear(goingBack)(push);\n }\n },\n condition([condition]) {\n const value = condition();\n\n if (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n },\n end() {\n /**\n * Save Current Game\n */\n save(false, 'auto');\n /**\n * Clear the Scene\n */\n match('clear', []);\n /**\n * Go to the main menu\n */\n renderer.ui.showScreen('mainmenu');\n },\n input([question, onInput, setup]) {\n renderer.input(unwrap(question), onInput, setup)(forward);\n },\n custom([handler]) {\n const result = renderer.custom(handler, goingBack, () => {\n if (!restoring && handler.requireUserAction) enmemory();\n if (!restoring) push();\n });\n\n return result;\n },\n vibrate(pattern) {\n try {\n navigator.vibrate(pattern)\n } finally {\n push()\n }\n },\n next() {\n push();\n },\n animateCharacter([character, timeout, ...classes]) {\n const handler: CustomHandler = () => {\n const char = renderer.store.characters[character];\n\n /**\n * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n */\n if (!char) return;\n\n const target = char.canvas;\n\n /**\n * Character is not found\n */\n if (!target) return;\n\n const classNames = classes.filter(className => !target.classList.contains(className));\n\n target.classList.add(...classNames);\n\n setTimeout(() => {\n target.classList.remove(...classNames);\n }, timeout);\n }\n\n handler.callOnlyLatest = true;\n\n return renderer.custom(handler, goingBack, () => { }), push();\n },\n text(text) {\n renderer.text(text.map(unwrap).join(' '), forward);\n },\n exit() {\n const path = stack.value[0];\n\n for (let i = path.length - 1; i > 0; i--) {\n if (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n stack.value[0] = path.slice(0, i);\n next();\n\n break;\n }\n\n render();\n }\n });\n\n const enmemory = () => {\n if (restoring) return;\n\n const current = klona(stack.value);\n\n current[0] = klona(stack.value[0]);\n\n current[2][0] = new Date().valueOf();\n current[2][1] = 'auto';\n\n stack.push(current);\n }\n\n const next = () => {\n const path = stack.value[0];\n /**\n * Последний элемент пути\n */\n const last = path[path.length - 1]!;\n\n /**\n * Если он вида `[null, int]` - увеличивает `int`\n */\n if (isNull(last[0]) && isNumber(last[1])) {\n last[1] = last[1] + 1;\n return;\n }\n\n /**\n * Иначе добавляет новое `[null int]`\n */\n path.push([null, 0]);\n }\n\n const render = () => {\n const referred = refer();\n\n if (!Array.isArray(referred)) return;\n\n const [action, ...props] = referred;\n\n match(action, props);\n }\n\n const push = () => {\n if (!restoring) next(), render();\n }\n\n const forward = () => {\n enmemory();\n push();\n }\n\n const unwrap = (content: Unwrappable) => {\n const lang = $.get().meta[0];\n const data = state();\n\n return replaceT9N(typeof content === 'function' ? content(lang, data) : content, data);\n }\n\n return {\n withStory,\n action,\n render,\n state,\n t: t9n.t as Inter['t'],\n }\n}\n\nexport { novely }\n","export function klona(val) {\n\tvar k, out, tmp;\n\n\tif (Array.isArray(val)) {\n\t\tout = Array(k=val.length);\n\t\twhile (k--) out[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\treturn out;\n\t}\n\n\tif (Object.prototype.toString.call(val) === '[object Object]') {\n\t\tout = {}; // null\n\t\tfor (k in val) {\n\t\t\tif (k === '__proto__') {\n\t\t\t\tObject.defineProperty(out, k, {\n\t\t\t\t\tvalue: klona(val[k]),\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tout[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n\n\treturn val;\n}\n","const SKIPPED_DURING_RESTORE = new Set([\n 'dialog',\n 'input',\n 'vibrate',\n 'text'\n] as const);\n\nexport { SKIPPED_DURING_RESTORE }","const split = (input: string, delimeters: string[]) => {\n const output: (string | undefined)[] = [];\n\n for (const delimeter of delimeters) {\n if (!input) break;\n\n const [start, end] = input.split(delimeter, 2);\n\n output.push(start); input = end;\n }\n\n output.push(input);\n\n return output;\n}\n\nexport { split }","import type { BaseTranslationStrings } from './translations';\nimport { split } from './lib';\n\ntype PluralType = Intl.LDMLPluralRule;\ntype FunctionalSetupT9N = <LanguageKey extends string, PluralKey extends string, StringKey extends string, Actions extends string>(parameters: { [Lang in LanguageKey]: { pluralization: { [Plural in PluralKey]: Partial<Record<PluralType, string>> }; internal: { [Key in BaseTranslationStrings]: string }; strings: { [Str in StringKey]: string }; actions?: { [Action in Actions]?: (value: string) => string; } } }) => T9N<LanguageKey, StringKey>\ntype SetupT9N<LanguageKey extends string> = <PluralKey extends string, StringKey extends string, Actions extends string>(parameters: { [Lang in LanguageKey]: { pluralization: { [Plural in PluralKey]: Partial<Record<PluralType, string>> }; internal: { [Key in BaseTranslationStrings]: string }; strings: { [Str in StringKey]: string }; actions?: { [Action in Actions]?: (value: string) => string; } } }) => T9N<LanguageKey, StringKey>\n\ntype T9N<LanguageKey extends string, StringKey extends string> = {\n t(key: StringKey): (lang: LanguageKey | (string & {}), obj: Record<string, unknown>) => string;\n i(key: StringKey, lang: LanguageKey | (string & {})): string;\n}\n\nconst RGX = /{{(.*?)}}/g;\n\nconst replace = (str: string, obj: Record<string, unknown>, pluralization?: Record<string, Record<string, PluralType>>, actions?: Partial<Record<string, (str: string) => string>>, pr?: Intl.PluralRules) => {\n return str.replace(RGX, (x: any, key: string, y: any) => {\n x = 0;\n y = obj;\n\n const [pathstr, plural, action] = split(key.trim(), ['@', '%']);\n\n let path = pathstr!.split('.');\n\n while (y && x < path.length) y = y[path[x++]];\n\n if (plural && pluralization && y && pr) {\n y = pluralization[plural][pr.select(y)];\n }\n\n const actionHandler = actions && action && actions[action];\n\n if (actionHandler) y = actionHandler(y);\n\n return y != null ? y : '';\n });\n}\n\nconst createT9N: FunctionalSetupT9N = (parameters) => {\n let locale: string | undefined;\n let pr: Intl.PluralRules | undefined;\n\n return {\n t(key) {\n return (lang, obj) => {\n /**\n * At first run `locale` and `pr` are not defined.\n * When `locale` changes, `pr` should be updated`\n */\n if (!locale || !pr || lang != locale) {\n pr = new Intl.PluralRules(locale = lang);\n }\n\n // @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n return replace(parameters[lang]['strings'][key], obj, parameters[lang]['pluralization'], parameters[lang]['actions'], pr);\n }\n },\n i(key, lang) {\n // @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n return parameters[lang]['internal'][key] as string;\n }\n }\n}\n\nexport { createT9N, replace }\nexport type { SetupT9N, T9N, FunctionalSetupT9N } ","const RU = {\n 'NewGame': 'Новая игра',\n 'HomeScreen': 'Главный экран',\n 'ToTheGame': 'К игре',\n 'Language': 'Язык',\n 'NoSaves': 'Сохранений нет',\n 'LoadSave': 'Загрузить',\n 'Saves': 'Сохранения',\n 'Settings': 'Настройки',\n 'Sumbit': 'Подтвердить',\n 'GoBack': 'Назад',\n 'DoSave': 'Сохранение',\n 'Auto': 'Авто',\n 'Stop': 'Стоп',\n 'Exit': 'Выход',\n 'Automatic': 'Автоматическое',\n 'Manual': 'Ручное',\n 'Remove': 'Удалить',\n 'LoadASaveFrom': 'Загрузить сохранение от',\n 'DeleteASaveFrom': 'Удалить сохранение от',\n};\n\nconst EN = {\n 'NewGame': 'New Game',\n 'HomeScreen': 'Home Screen',\n 'ToTheGame': 'To the Game',\n 'Language': 'Language',\n 'NoSaves': 'No saves',\n 'LoadSave': 'Load',\n 'Saves': 'Saves',\n 'Settings': 'Settings',\n 'Sumbit': 'Submit',\n 'GoBack': 'Go back',\n 'DoSave': 'Save',\n 'Auto': 'Auto',\n 'Stop': 'Stop',\n 'Exit': 'Exit',\n 'Automatic': 'Automatic',\n 'Manual': 'Manual',\n 'Remove': 'Remove',\n 'LoadASaveFrom': 'Load a save from',\n 'DeleteASaveFrom': 'Delete a save from',\n};\n\nconst JP = {\n 'NewGame': '新しいゲーム',\n 'HomeScreen': 'ホーム画面',\n 'ToTheGame': 'ゲームへ',\n 'Language': '言語',\n 'NoSaves': 'セーブがありません',\n 'LoadSave': 'ロード',\n 'Saves': 'セーブ',\n 'Settings': '設定',\n 'Sumbit': '提出する',\n 'GoBack': '戻る',\n 'DoSave': 'セーブする',\n 'Auto': 'オート',\n 'Stop': '停止',\n 'Exit': '終了する',\n 'Automatic': '自動',\n 'Manual': '手動',\n 'Remove': '削除する',\n 'LoadASaveFrom': 'からセーブを読み込む',\n 'DeleteASaveFrom': 'からセーブを削除する',\n};\n\ntype BaseTranslationStrings = keyof typeof RU;\n\nexport { RU, EN, JP }\nexport type { BaseTranslationStrings }","import type { StorageData } from './types'\n\ninterface LocalStorageStorageSettings {\n key: string\n}\n\ninterface Storage {\n get: () => Promise<StorageData>;\n set: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n return {\n async get() {\n const value = localStorage.getItem(options.key);\n\n return value ? JSON.parse(value) : { saves: [], meta: [] };\n },\n async set(data) {\n localStorage.setItem(options.key, JSON.stringify(data));\n }\n }\n}\n\nexport type { Storage }\nexport { localStorageStorage }"],"mappings":"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","names":["isMergeableObject","deepmerge","split","input","delimeters","output","delimeter","start","end","RGX","replace","str","obj","pluralization","actions","pr","x","key","y","pathstr","plural","action","path","actionHandler","deepmerge","stack","save","action","index","next","latest","c"]}
package/dist/index.js CHANGED
@@ -243,7 +243,7 @@ var novely = ({ characters, storage, renderer: createRenderer, initialScreen = "
243
243
  if (action2 === "function" || action2 === "custom") {
244
244
  if (action2 === "custom" && meta[0].callOnlyLatest) {
245
245
  const next2 = indexedQueue.slice(i + 1);
246
- const latest2 = !next2.some(([_action, _meta]) => str(_meta[0]) === str(meta[0]));
246
+ const latest2 = !next2.some(([_action, _meta]) => _meta && meta && str(_meta[0]) === str(meta[0]));
247
247
  if (!latest2)
248
248
  continue;
249
249
  }
@@ -330,7 +330,7 @@ var novely = ({ characters, storage, renderer: createRenderer, initialScreen = "
330
330
  const unwrapped = choices.map(([content, action2, visible]) => {
331
331
  return [unwrap(content), action2, visible];
332
332
  });
333
- renderer.choices(question, unwrapped)((selected) => {
333
+ renderer.choices(unwrap(question), unwrapped)((selected) => {
334
334
  enmemory();
335
335
  stack.value[0].push(["choice", isWithoutQuestion ? selected : selected + 1], [null, 0]), render();
336
336
  });
@@ -360,7 +360,7 @@ var novely = ({ characters, storage, renderer: createRenderer, initialScreen = "
360
360
  renderer.ui.showScreen("mainmenu");
361
361
  },
362
362
  input([question, onInput, setup]) {
363
- renderer.input(question, onInput, setup)(forward);
363
+ renderer.input(unwrap(question), onInput, setup)(forward);
364
364
  },
365
365
  custom([handler]) {
366
366
  const result = renderer.custom(handler, goingBack, () => {
@@ -434,7 +434,7 @@ var novely = ({ characters, storage, renderer: createRenderer, initialScreen = "
434
434
  };
435
435
  const render = () => {
436
436
  const referred = refer();
437
- if (!(referred && Array.isArray(referred)))
437
+ if (!Array.isArray(referred))
438
438
  return;
439
439
  const [action2, ...props] = referred;
440
440
  match(action2, props);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/store.ts","../src/novely.ts","../src/constants.ts","../src/storage.ts"],"sourcesContent":["import type { ActionProxyProvider, CustomHandler } from './action'\nimport type { Character } from './character'\nimport type { Save, Thenable } from './types'\n\ntype MatchActionMap = {\n [Key in keyof ActionProxyProvider<Record<string, Character>>]: (data: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>) => void;\n}\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n custom: (value: [handler: CustomHandler]) => Thenable<void>;\n}\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n return (action: keyof MatchActionMap, props: any) => {\n return values[action](props);\n }\n}\n\nconst isNumber = (val: unknown): val is number => {\n return typeof val === 'number';\n}\n\nconst isNull = (val: unknown): val is null => {\n return val === null;\n}\n\nconst isString = (val: unknown): val is string => {\n return typeof val === 'string';\n}\n\nconst isCSSImage = (str: string) => {\n const startsWith = String.prototype.startsWith.bind(str);\n\n return startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n}\n\nconst str = (value: unknown) => {\n return String(value);\n}\n\nconst isUserRequiredAction = (action: keyof MatchActionMapComplete, meta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>) => {\n return action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n}\n\nconst getDefaultSave = (state = {}) => {\n return [[[null, 'start'], [null, 0]], state, [Date.now(), 'auto']] as Save;\n}\n\nconst getLanguage = (languages: string[], language = navigator.language) => {\n if (languages.includes(language)) {\n return language;\n } else if (languages.includes((language = language.substring(0, 2)))) {\n return language;\n } else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n return language\n }\n\n /**\n * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n */\n return 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 let throttled = false, savedArgs: any, savedThis: any;\n\n function wrapper() {\n if (throttled) {\n savedArgs = arguments;\n // @ts-ignore\n savedThis = this;\n\n return;\n }\n\n // @ts-ignore\n fn.apply(this, arguments);\n\n throttled = false;\n }\n\n setTimeout(function () {\n throttled = false;\n\n if (savedArgs) {\n wrapper.apply(savedThis, savedArgs);\n savedArgs = savedThis = null;\n }\n }, ms);\n\n return wrapper as unknown as (...args: Parameters<Fn>) => void;\n}\n\nexport { matchAction, isNumber, isNull, isString, isCSSImage, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle }","type Stored<T> = {\n subscribe: (cb: (value: T) => void) => () => void;\n update: (fn: (prev: T) => T) => void;\n get: () => T;\n}\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n const subscribe = (cb: (value: T) => void) => {\n subscribers.add(cb), cb(current);\n\n return () => {\n subscribers.delete(cb);\n }\n };\n\n const push = (value: T) => {\n subscribers.forEach((cb) => cb(value))\n };\n\n const update = (fn: (prev: T) => T) => {\n push((current = fn(current)));\n };\n\n const get = () => {\n return current;\n };\n\n return { subscribe, update, get } as const;\n};\n\nexport { store }\nexport type { Stored }","import type { Character } from './character';\nimport type { ActionProxyProvider, GetActionParameters, Story, ValidAction, DialogContent, ChoiceContent, CustomHandler } from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, StorageData, DeepPartial } from './types'\nimport type { Renderer, RendererInit } from './renderer'\nimport type { SetupT9N } from '@novely/t9n'\nimport { matchAction, isNumber, isNull, isString, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle } from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge'\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State> {\n /**\n * An array of languages supported by the game.\n */\n languages: Languages[];\n /**\n * An object containing the characters in the game.\n */\n characters: Characters;\n /**\n * An object that provides access to the game's storage system.\n */\n storage: Storage;\n /**\n * A function that returns a Renderer object used to display the game's content\n */\n renderer: (characters: RendererInit) => Renderer;\n /**\n * An optional property that specifies the initial screen to display when the game starts\n */\n initialScreen?: \"mainmenu\" | \"game\" | \"saves\" | \"settings\";\n /**\n * An object containing the translation functions used in the game\n */\n t9n: Inter;\n /**\n * Initial state value\n */\n state?: StateScheme;\n}\n\nconst novely = <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen = \"mainmenu\", t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {\n let story: Story;\n\n // @todo: find bug here\n const withStory = (s: Story) => {\n /**\n * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n */\n story = Object.fromEntries(Object.entries(s).map(([name, items]) => {\n const flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n return item.flatMap((data) => {\n const type = data[0];\n\n /**\n * This is not just an action like `['name', ...arguments]`, but an array of actions\n */\n if (Array.isArray(type)) return flat(data as ValidAction[]);\n\n return [data as ValidAction];\n });\n };\n\n return [name, flat(items)];\n }));\n\n /**\n * When `initialScreen` is not a game, we can safely show it\n */\n if (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n }\n\n const action = new Proxy({} as ActionProxyProvider<Characters>, {\n get(_, prop) {\n return (...props: Parameters<ActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]>) => {\n return [prop, ...props];\n }\n }\n });\n\n function state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n function state(): StateScheme;\n function state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n if (!value) return stack.value[1] as StateScheme | void;\n\n const prev = stack.value[1];\n const val = typeof value === 'function' ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n stack.value[1] = val as StateScheme;\n }\n\n const createStack = (current: Save, stack = [current]) => {\n return {\n get value() {\n return stack.at(-1)!;\n },\n set value(value: Save) {\n stack[stack.length - 1] = value;\n },\n back() {\n if (stack.length > 1) stack.pop(), goingBack = true;\n },\n push(value: Save) {\n stack.push(value);\n },\n clear() {\n stack = [getDefaultSave(klona(defaultState))];\n }\n }\n }\n\n /**\n * 1) Novely rendered using the `initialData`, you can still start new game or `load` an empty one - this is scary, imagine losing your progress\n * 2) Actual stored data is loaded, language and etc is changed \n */\n const initialData: StorageData = {\n saves: [],\n meta: [getLanguage(languages)]\n };\n\n const $ = store(initialData);\n\n let initialDataLoaded = false;\n\n const onStorageDataChange = (value: StorageData) => {\n if (initialDataLoaded) storage.set(value);\n };\n\n const throttledOnStorageDataChange = throttle(onStorageDataChange, 120);\n\n $.subscribe(throttledOnStorageDataChange);\n\n storage.get().then(stored => {\n /**\n * Default `localStorageStorage` cannot determine preferred language, and returns empty array\n */\n stored.meta[0] ||= getLanguage(languages);\n\n /**\n * Now the next store updates will entail saving via storage.set\n */\n initialDataLoaded = true;\n\n $.update(() => stored);\n\n /**\n * When initialScreen is game, then we will load it, but after the data is loaded\n */\n if (initialScreen === 'game') restore();\n });\n\n const initial = getDefaultSave(klona(defaultState));\n const stack = createStack(initial);\n\n const save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n if (!initialDataLoaded) return;\n\n $.update(prev => {\n const date = stack.value[2][0];\n const isLatest = prev.saves.findIndex(value => value[2][0] === date) === prev.saves.length - 1;\n\n /**\n * Обновим дату и тип\n */\n stack.value[2][0] = Date.now();\n stack.value[2][1] = type;\n\n if (override) {\n /**\n * Перезапишем\n */\n if (isLatest) {\n /**\n * Сохранения хранятся в массиве. Нельзя перезаписать любое последнее\n * \n * Если перезаписывать старое сохранение, то они не будут идти в хронологическом порядке\n */\n prev.saves[prev.saves.length - 1] = stack.value;\n } else {\n prev.saves.push(stack.value);\n }\n } else {\n /**\n * Добавляем текущее сохранение\n */\n prev.saves.push(stack.value);\n }\n\n /**\n * Устанавливаем новое значение\n */\n return prev;\n });\n }\n\n const newGame = () => {\n if (!initialDataLoaded) return;\n\n const save = getDefaultSave(klona(defaultState));\n\n $.update(prev => {\n prev.saves.push(save), restore(save);\n\n return prev;\n });\n }\n\n /**\n * Устанавливает сохранение\n */\n const set = (save: Save) => {\n stack.value = save;\n\n return restore(save);\n }\n\n let restoring = false;\n let goingBack = false;\n\n /**\n * Визуально восстанавливает историю\n */\n const restore = async (save?: Save) => {\n if (!initialDataLoaded) return;\n\n let latest = save ? save : $.get().saves.at(-1);\n\n /**\n * Если нет сохранённой игры, то запустим ту, которая уже есть\n */\n if (!latest) {\n $.update(() => ({ saves: [initial], meta: [getLanguage(languages)] }));\n\n latest = klona(initial);\n }\n\n restoring = true, stack.value = latest;\n\n /**\n * Показать экран игры\n */\n renderer.ui.showScreen('game');\n\n match('clear', [goingBack]);\n\n /**\n * Текущий элемент в истории\n */\n let current: any = story;\n /**\n * Текущий элемент `[null, int]`\n */\n let index = 0;\n\n /**\n * Число элементов `[null, int]`\n */\n const max = stack.value[0].reduce((acc, [type, val]) => {\n if (isNull(type) && isNumber(val)) return acc + 1;\n\n return acc;\n }, 0);\n\n const queue = [] as [any, any][];\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n if (isString(val)) {\n current = current[val];\n } else if (isNumber(val)) {\n index++;\n\n /**\n * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n */\n for (let i = 0; i < val; i++) {\n const [action, ...meta] = current[i];\n\n /**\n * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n */\n if (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n if (index === max && i === val) {\n queue.push([action, meta]);\n } else {\n continue;\n }\n }\n\n queue.push([action, meta]);\n }\n\n current = current[val];\n }\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n const indexedQueue = queue.map((value, index) => value.concat(index) as [ValidAction[0], ValidAction[1], number]);\n\n for await (const [action, meta, i] of indexedQueue) {\n if (action === 'function' || action === 'custom') {\n /**\n * Если `callOnlyLatest` - `true`\n */\n if (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n /**\n * Вычислим `latest` или нет\n */\n const next = indexedQueue.slice(i + 1);\n const latest = !next.some(([_action, _meta]) => str(_meta[0]) === str(meta[0]));\n\n if (!latest) continue;\n }\n\n /**\n * Action может возвращать Promise. Нужно подожать его `resolve`\n */\n const result = match(action, meta);\n\n /**\n * Дождёмся окончания\n */\n if (result && 'then' in result) await result;\n } else {\n match(action as keyof ActionProxyProvider<Record<string, Character<string>>>, meta);\n }\n }\n\n restoring = false, goingBack = false, render();\n }\n\n const refer = () => {\n let current: any = story;\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n current = current[val];\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n return current;\n }\n\n const renderer = createRenderer({\n characters,\n set,\n restore,\n save,\n newGame,\n stack,\n languages,\n t: t9n.i,\n $\n });\n\n const match = matchAction({\n wait([time]) {\n /**\n * `restoring` может поменяться на `true` перед тем как запуститься `push` из `setTimeout`\n */\n if (!restoring) setTimeout(push, time);\n },\n showBackground([background]) {\n renderer.background(background);\n push()\n },\n playMusic([source]) {\n renderer.music(source, 'music').play();\n push()\n },\n stopMusic([source]) {\n renderer.music(source, 'music').stop();\n push()\n },\n showCharacter([character, emotion, className, style]) {\n const handle = renderer.character(character);\n\n handle.append(className, style);\n handle.withEmotion(emotion)();\n\n push()\n },\n hideCharacter([character, className, style, duration]) {\n const handle = renderer.character(character);\n\n handle.remove(className, style, duration)(push);\n },\n dialog([character, content, emotion]) {\n /**\n * Имя персонажа, с учетом выбранного языка\n */\n const name = (() => {\n const c = character, cs = characters;\n const lang = $.get().meta[0];\n\n return c ? c in cs ? typeof cs[c].name === 'string' ? cs[c].name as string : (cs[c].name as Record<string, string>)[lang] : c : '';\n })();\n\n renderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n },\n function([fn]) {\n const result = fn();\n\n if (!restoring) result ? result.then(push) : push();\n\n return result;\n },\n choice([question, ...choices]) {\n const isWithoutQuestion = Array.isArray(question);\n\n if (isWithoutQuestion) {\n /**\n * Первый элемент может быть как строкой, так и элементов выбора\n */\n choices.unshift(question as unknown as [ChoiceContent, ValidAction[], () => boolean]);\n /**\n * Значит, текст не требуется\n */\n question = '';\n }\n\n const unwrapped = choices.map(([content, action, visible]) => {\n return [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n });\n\n renderer.choices(question, unwrapped)((selected) => {\n enmemory();\n\n /**\n * Если был вопрос, то `index` смещается на единицу назад, поэтому нужно добавить единицу\n */\n stack.value[0].push(['choice', isWithoutQuestion ? selected : selected + 1], [null, 0]), render();\n });\n },\n jump([scene]) {\n stack.value[0] = [[null, scene], [null, 0]];\n\n renderer.clear(false)(() => {\n if (!restoring) render();\n })\n },\n clear() {\n try {\n navigator.vibrate(0)\n } finally {\n renderer.clear(goingBack)(push);\n }\n },\n condition([condition]) {\n const value = condition();\n\n if (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n },\n end() {\n /**\n * Save Current Game\n */\n save(false, 'auto');\n /**\n * Clear the Scene\n */\n match('clear', []);\n /**\n * Go to the main menu\n */\n renderer.ui.showScreen('mainmenu');\n },\n input([question, onInput, setup]) {\n renderer.input(question, onInput, setup)(forward);\n },\n custom([handler]) {\n const result = renderer.custom(handler, goingBack, () => {\n if (!restoring && handler.requireUserAction) enmemory();\n if (!restoring) push();\n });\n\n return result;\n },\n vibrate(pattern) {\n try {\n navigator.vibrate(pattern)\n } finally {\n push()\n }\n },\n next() {\n push();\n },\n animateCharacter([character, timeout, ...classes]) {\n const handler: CustomHandler = () => {\n const char = renderer.store.characters[character];\n\n /**\n * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n */\n if (!char) return;\n\n const target = char.canvas;\n\n /**\n * Character is not found\n */\n if (!target) return;\n\n const classNames = classes.filter(className => !target.classList.contains(className));\n\n target.classList.add(...classNames);\n\n setTimeout(() => {\n target.classList.remove(...classNames);\n }, timeout);\n }\n\n handler.callOnlyLatest = true;\n\n return renderer.custom(handler, goingBack, () => { }), push();\n },\n text(text) {\n renderer.text(text.map(unwrap).join(' '), forward);\n },\n exit() {\n const path = stack.value[0];\n\n for (let i = path.length - 1; i > 0; i--) {\n if (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n stack.value[0] = path.slice(0, i);\n next();\n\n break;\n }\n\n render();\n }\n });\n\n const enmemory = () => {\n if (restoring) return;\n\n const current = klona(stack.value);\n\n current[0] = klona(stack.value[0]);\n\n current[2][0] = new Date().valueOf();\n current[2][1] = 'auto';\n\n stack.push(current);\n }\n\n const next = () => {\n const path = stack.value[0];\n /**\n * Последний элемент пути\n */\n const last = path[path.length - 1]!;\n\n /**\n * Если он вида `[null, int]` - увеличивает `int`\n */\n if (isNull(last[0]) && isNumber(last[1])) {\n last[1] = last[1] + 1;\n return;\n }\n\n /**\n * Иначе добавляет новое `[null int]`\n */\n path.push([null, 0]);\n }\n\n const render = () => {\n const referred = refer();\n\n if (!(referred && Array.isArray(referred))) return;\n\n const [action, ...props] = referred;\n\n match(action, props);\n }\n\n const push = () => {\n if (!restoring) next(), render();\n }\n\n const forward = () => {\n enmemory();\n push();\n }\n\n const unwrap = (content: DialogContent | ChoiceContent) => {\n const lang = $.get().meta[0];\n const data = state();\n\n return replaceT9N(typeof content === 'function' ? content(lang, data) : content, data);\n }\n\n return {\n withStory,\n action,\n render,\n state,\n t: t9n.t as Inter['t'],\n }\n}\n\nexport { novely }\n","const SKIPPED_DURING_RESTORE = new Set([\n 'dialog',\n 'input',\n 'vibrate',\n 'text'\n] as const);\n\nexport { SKIPPED_DURING_RESTORE }","import type { StorageData } from './types'\n\ninterface LocalStorageStorageSettings {\n key: string\n}\n\ninterface Storage {\n get: () => Promise<StorageData>;\n set: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n return {\n async get() {\n const value = localStorage.getItem(options.key);\n\n return value ? JSON.parse(value) : { saves: [], meta: [] };\n },\n async set(data) {\n localStorage.setItem(options.key, JSON.stringify(data));\n }\n }\n}\n\nexport type { Storage }\nexport { localStorageStorage }"],"mappings":"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","names":["stack","save","action","index","next","latest"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/store.ts","../src/novely.ts","../src/constants.ts","../src/storage.ts"],"sourcesContent":["import type { ActionProxyProvider, CustomHandler } from './action'\nimport type { Character } from './character'\nimport type { Save, Thenable } from './types'\n\ntype MatchActionMap = {\n [Key in keyof ActionProxyProvider<Record<string, Character>>]: (data: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>) => void;\n}\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n custom: (value: [handler: CustomHandler]) => Thenable<void>;\n}\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n return (action: keyof MatchActionMap, props: any) => {\n return values[action](props);\n }\n}\n\nconst isNumber = (val: unknown): val is number => {\n return typeof val === 'number';\n}\n\nconst isNull = (val: unknown): val is null => {\n return val === null;\n}\n\nconst isString = (val: unknown): val is string => {\n return typeof val === 'string';\n}\n\nconst isCSSImage = (str: string) => {\n const startsWith = String.prototype.startsWith.bind(str);\n\n return startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n}\n\nconst str = (value: unknown) => {\n return String(value);\n}\n\nconst isUserRequiredAction = (action: keyof MatchActionMapComplete, meta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>) => {\n return action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n}\n\nconst getDefaultSave = (state = {}) => {\n return [[[null, 'start'], [null, 0]], state, [Date.now(), 'auto']] as Save;\n}\n\nconst getLanguage = (languages: string[], language = navigator.language) => {\n if (languages.includes(language)) {\n return language;\n } else if (languages.includes((language = language.substring(0, 2)))) {\n return language;\n } else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n return language\n }\n\n /**\n * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n */\n return 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 let throttled = false, savedArgs: any, savedThis: any;\n\n function wrapper() {\n if (throttled) {\n savedArgs = arguments;\n // @ts-ignore\n savedThis = this;\n\n return;\n }\n\n // @ts-ignore\n fn.apply(this, arguments);\n\n throttled = false;\n }\n\n setTimeout(function () {\n throttled = false;\n\n if (savedArgs) {\n wrapper.apply(savedThis, savedArgs);\n savedArgs = savedThis = null;\n }\n }, ms);\n\n return wrapper as unknown as (...args: Parameters<Fn>) => void;\n}\n\nexport { matchAction, isNumber, isNull, isString, isCSSImage, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle }","type Stored<T> = {\n subscribe: (cb: (value: T) => void) => () => void;\n update: (fn: (prev: T) => T) => void;\n get: () => T;\n}\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n const subscribe = (cb: (value: T) => void) => {\n subscribers.add(cb), cb(current);\n\n return () => {\n subscribers.delete(cb);\n }\n };\n\n const push = (value: T) => {\n subscribers.forEach((cb) => cb(value))\n };\n\n const update = (fn: (prev: T) => T) => {\n push((current = fn(current)));\n };\n\n const get = () => {\n return current;\n };\n\n return { subscribe, update, get } as const;\n};\n\nexport { store }\nexport type { Stored }","import type { Character } from './character';\nimport type { ActionProxyProvider, GetActionParameters, Story, ValidAction, Unwrappable, CustomHandler } from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, StorageData, DeepPartial } from './types'\nimport type { Renderer, RendererInit } from './renderer'\nimport type { SetupT9N } from '@novely/t9n'\nimport { matchAction, isNumber, isNull, isString, str, isUserRequiredAction, getDefaultSave, getLanguage, throttle } from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge'\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State> {\n /**\n * An array of languages supported by the game.\n */\n languages: Languages[];\n /**\n * An object containing the characters in the game.\n */\n characters: Characters;\n /**\n * An object that provides access to the game's storage system.\n */\n storage: Storage;\n /**\n * A function that returns a Renderer object used to display the game's content\n */\n renderer: (characters: RendererInit) => Renderer;\n /**\n * An optional property that specifies the initial screen to display when the game starts\n */\n initialScreen?: \"mainmenu\" | \"game\" | \"saves\" | \"settings\";\n /**\n * An object containing the translation functions used in the game\n */\n t9n: Inter;\n /**\n * Initial state value\n */\n state?: StateScheme;\n}\n\nconst novely = <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends ReturnType<SetupT9N<Languages>>, StateScheme extends State>({ characters, storage, renderer: createRenderer, initialScreen = \"mainmenu\", t9n, languages, state: defaultState }: NovelyInit<Languages, Characters, Inter, StateScheme>) => {\n let story: Story;\n\n // @todo: find bug here\n const withStory = (s: Story) => {\n /**\n * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n */\n story = Object.fromEntries(Object.entries(s).map(([name, items]) => {\n const flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n return item.flatMap((data) => {\n const type = data[0];\n\n /**\n * This is not just an action like `['name', ...arguments]`, but an array of actions\n */\n if (Array.isArray(type)) return flat(data as ValidAction[]);\n\n return [data as ValidAction];\n });\n };\n\n return [name, flat(items)];\n }));\n\n /**\n * When `initialScreen` is not a game, we can safely show it\n */\n if (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n }\n\n const action = new Proxy({} as ActionProxyProvider<Characters>, {\n get(_, prop) {\n return (...props: Parameters<ActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]>) => {\n return [prop, ...props];\n }\n }\n });\n\n function state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n function state(): StateScheme;\n function state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n if (!value) return stack.value[1] as StateScheme | void;\n\n const prev = stack.value[1];\n const val = typeof value === 'function' ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n stack.value[1] = val as StateScheme;\n }\n\n const createStack = (current: Save, stack = [current]) => {\n return {\n get value() {\n return stack.at(-1)!;\n },\n set value(value: Save) {\n stack[stack.length - 1] = value;\n },\n back() {\n if (stack.length > 1) stack.pop(), goingBack = true;\n },\n push(value: Save) {\n stack.push(value);\n },\n clear() {\n stack = [getDefaultSave(klona(defaultState))];\n }\n }\n }\n\n /**\n * 1) Novely rendered using the `initialData`, you can still start new game or `load` an empty one - this is scary, imagine losing your progress\n * 2) Actual stored data is loaded, language and etc is changed \n */\n const initialData: StorageData = {\n saves: [],\n meta: [getLanguage(languages)]\n };\n\n const $ = store(initialData);\n\n let initialDataLoaded = false;\n\n const onStorageDataChange = (value: StorageData) => {\n if (initialDataLoaded) storage.set(value);\n };\n\n const throttledOnStorageDataChange = throttle(onStorageDataChange, 120);\n\n $.subscribe(throttledOnStorageDataChange);\n\n storage.get().then(stored => {\n /**\n * Default `localStorageStorage` cannot determine preferred language, and returns empty array\n */\n stored.meta[0] ||= getLanguage(languages);\n\n /**\n * Now the next store updates will entail saving via storage.set\n */\n initialDataLoaded = true;\n\n $.update(() => stored);\n\n /**\n * When initialScreen is game, then we will load it, but after the data is loaded\n */\n if (initialScreen === 'game') restore();\n });\n\n const initial = getDefaultSave(klona(defaultState));\n const stack = createStack(initial);\n\n const save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n if (!initialDataLoaded) return;\n\n $.update(prev => {\n const date = stack.value[2][0];\n const isLatest = prev.saves.findIndex(value => value[2][0] === date) === prev.saves.length - 1;\n\n /**\n * Обновим дату и тип\n */\n stack.value[2][0] = Date.now();\n stack.value[2][1] = type;\n\n if (override) {\n /**\n * Перезапишем\n */\n if (isLatest) {\n /**\n * Сохранения хранятся в массиве. Нельзя перезаписать любое последнее\n * \n * Если перезаписывать старое сохранение, то они не будут идти в хронологическом порядке\n */\n prev.saves[prev.saves.length - 1] = stack.value;\n } else {\n prev.saves.push(stack.value);\n }\n } else {\n /**\n * Добавляем текущее сохранение\n */\n prev.saves.push(stack.value);\n }\n\n /**\n * Устанавливаем новое значение\n */\n return prev;\n });\n }\n\n const newGame = () => {\n if (!initialDataLoaded) return;\n\n const save = getDefaultSave(klona(defaultState));\n\n $.update(prev => {\n prev.saves.push(save), restore(save);\n\n return prev;\n });\n }\n\n /**\n * Устанавливает сохранение\n */\n const set = (save: Save) => {\n stack.value = save;\n\n return restore(save);\n }\n\n let restoring = false;\n let goingBack = false;\n\n /**\n * Визуально восстанавливает историю\n */\n const restore = async (save?: Save) => {\n if (!initialDataLoaded) return;\n\n let latest = save ? save : $.get().saves.at(-1);\n\n /**\n * Если нет сохранённой игры, то запустим ту, которая уже есть\n */\n if (!latest) {\n $.update(() => ({ saves: [initial], meta: [getLanguage(languages)] }));\n\n latest = klona(initial);\n }\n\n restoring = true, stack.value = latest;\n\n /**\n * Показать экран игры\n */\n renderer.ui.showScreen('game');\n\n match('clear', [goingBack]);\n\n /**\n * Текущий элемент в истории\n */\n let current: any = story;\n /**\n * Текущий элемент `[null, int]`\n */\n let index = 0;\n\n /**\n * Число элементов `[null, int]`\n */\n const max = stack.value[0].reduce((acc, [type, val]) => {\n if (isNull(type) && isNumber(val)) return acc + 1;\n\n return acc;\n }, 0);\n\n const queue = [] as [any, any][];\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n if (isString(val)) {\n current = current[val];\n } else if (isNumber(val)) {\n index++;\n\n /**\n * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n */\n for (let i = 0; i < val; i++) {\n const [action, ...meta] = current[i];\n\n /**\n * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n */\n if (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n if (index === max && i === val) {\n queue.push([action, meta]);\n } else {\n continue;\n }\n }\n\n queue.push([action, meta]);\n }\n\n current = current[val];\n }\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n const indexedQueue = queue.map((value, index) => value.concat(index) as [ValidAction[0], ValidAction[1], number]);\n\n for await (const [action, meta, i] of indexedQueue) {\n if (action === 'function' || action === 'custom') {\n /**\n * Если `callOnlyLatest` - `true`\n */\n if (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n /**\n * Вычислим `latest` или нет\n */\n const next = indexedQueue.slice(i + 1);\n const latest = !next.some(([_action, _meta]) => _meta && meta && str(_meta[0]) === str(meta[0]));\n\n if (!latest) continue;\n }\n\n /**\n * Action может возвращать Promise. Нужно подожать его `resolve`\n */\n const result = match(action, meta);\n\n /**\n * Дождёмся окончания\n */\n if (result && 'then' in result) await result;\n } else {\n match(action as keyof ActionProxyProvider<Record<string, Character<string>>>, meta);\n }\n }\n\n restoring = false, goingBack = false, render();\n }\n\n const refer = () => {\n let current: any = story;\n\n for (const [type, val] of stack.value[0]) {\n if (type === null) {\n current = current[val];\n } else if (type === 'choice') {\n current = current[val as number + 1][1];\n } else if (type === 'condition') {\n current = current[2][val];\n }\n }\n\n return current;\n }\n\n const renderer = createRenderer({\n characters,\n set,\n restore,\n save,\n newGame,\n stack,\n languages,\n t: t9n.i,\n $\n });\n\n const match = matchAction({\n wait([time]) {\n /**\n * `restoring` может поменяться на `true` перед тем как запуститься `push` из `setTimeout`\n */\n if (!restoring) setTimeout(push, time);\n },\n showBackground([background]) {\n renderer.background(background);\n push()\n },\n playMusic([source]) {\n renderer.music(source, 'music').play();\n push()\n },\n stopMusic([source]) {\n renderer.music(source, 'music').stop();\n push()\n },\n showCharacter([character, emotion, className, style]) {\n const handle = renderer.character(character);\n\n handle.append(className, style);\n handle.withEmotion(emotion)();\n\n push()\n },\n hideCharacter([character, className, style, duration]) {\n const handle = renderer.character(character);\n\n handle.remove(className, style, duration)(push);\n },\n dialog([character, content, emotion]) {\n /**\n * Имя персонажа, с учетом выбранного языка\n */\n const name = (() => {\n const c = character, cs = characters;\n const lang = $.get().meta[0];\n\n return c ? c in cs ? typeof cs[c].name === 'string' ? cs[c].name as string : (cs[c].name as Record<string, string>)[lang] : c : '';\n })();\n\n renderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n },\n function([fn]) {\n const result = fn();\n\n if (!restoring) result ? result.then(push) : push();\n\n return result;\n },\n choice([question, ...choices]) {\n const isWithoutQuestion = Array.isArray(question);\n\n if (isWithoutQuestion) {\n /**\n * Первый элемент может быть как строкой, так и элементов выбора\n */\n choices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n /**\n * Значит, текст не требуется\n */\n question = '';\n }\n\n const unwrapped = choices.map(([content, action, visible]) => {\n return [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n });\n\n renderer.choices(unwrap(question), unwrapped)((selected) => {\n enmemory();\n\n /**\n * Если был вопрос, то `index` смещается на единицу назад, поэтому нужно добавить единицу\n */\n stack.value[0].push(['choice', isWithoutQuestion ? selected : selected + 1], [null, 0]), render();\n });\n },\n jump([scene]) {\n stack.value[0] = [[null, scene], [null, 0]];\n\n renderer.clear(false)(() => {\n if (!restoring) render();\n })\n },\n clear() {\n try {\n navigator.vibrate(0)\n } finally {\n renderer.clear(goingBack)(push);\n }\n },\n condition([condition]) {\n const value = condition();\n\n if (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n },\n end() {\n /**\n * Save Current Game\n */\n save(false, 'auto');\n /**\n * Clear the Scene\n */\n match('clear', []);\n /**\n * Go to the main menu\n */\n renderer.ui.showScreen('mainmenu');\n },\n input([question, onInput, setup]) {\n renderer.input(unwrap(question), onInput, setup)(forward);\n },\n custom([handler]) {\n const result = renderer.custom(handler, goingBack, () => {\n if (!restoring && handler.requireUserAction) enmemory();\n if (!restoring) push();\n });\n\n return result;\n },\n vibrate(pattern) {\n try {\n navigator.vibrate(pattern)\n } finally {\n push()\n }\n },\n next() {\n push();\n },\n animateCharacter([character, timeout, ...classes]) {\n const handler: CustomHandler = () => {\n const char = renderer.store.characters[character];\n\n /**\n * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n */\n if (!char) return;\n\n const target = char.canvas;\n\n /**\n * Character is not found\n */\n if (!target) return;\n\n const classNames = classes.filter(className => !target.classList.contains(className));\n\n target.classList.add(...classNames);\n\n setTimeout(() => {\n target.classList.remove(...classNames);\n }, timeout);\n }\n\n handler.callOnlyLatest = true;\n\n return renderer.custom(handler, goingBack, () => { }), push();\n },\n text(text) {\n renderer.text(text.map(unwrap).join(' '), forward);\n },\n exit() {\n const path = stack.value[0];\n\n for (let i = path.length - 1; i > 0; i--) {\n if (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n stack.value[0] = path.slice(0, i);\n next();\n\n break;\n }\n\n render();\n }\n });\n\n const enmemory = () => {\n if (restoring) return;\n\n const current = klona(stack.value);\n\n current[0] = klona(stack.value[0]);\n\n current[2][0] = new Date().valueOf();\n current[2][1] = 'auto';\n\n stack.push(current);\n }\n\n const next = () => {\n const path = stack.value[0];\n /**\n * Последний элемент пути\n */\n const last = path[path.length - 1]!;\n\n /**\n * Если он вида `[null, int]` - увеличивает `int`\n */\n if (isNull(last[0]) && isNumber(last[1])) {\n last[1] = last[1] + 1;\n return;\n }\n\n /**\n * Иначе добавляет новое `[null int]`\n */\n path.push([null, 0]);\n }\n\n const render = () => {\n const referred = refer();\n\n if (!Array.isArray(referred)) return;\n\n const [action, ...props] = referred;\n\n match(action, props);\n }\n\n const push = () => {\n if (!restoring) next(), render();\n }\n\n const forward = () => {\n enmemory();\n push();\n }\n\n const unwrap = (content: Unwrappable) => {\n const lang = $.get().meta[0];\n const data = state();\n\n return replaceT9N(typeof content === 'function' ? content(lang, data) : content, data);\n }\n\n return {\n withStory,\n action,\n render,\n state,\n t: t9n.t as Inter['t'],\n }\n}\n\nexport { novely }\n","const SKIPPED_DURING_RESTORE = new Set([\n 'dialog',\n 'input',\n 'vibrate',\n 'text'\n] as const);\n\nexport { SKIPPED_DURING_RESTORE }","import type { StorageData } from './types'\n\ninterface LocalStorageStorageSettings {\n key: string\n}\n\ninterface Storage {\n get: () => Promise<StorageData>;\n set: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n return {\n async get() {\n const value = localStorage.getItem(options.key);\n\n return value ? JSON.parse(value) : { saves: [], meta: [] };\n },\n async set(data) {\n localStorage.setItem(options.key, JSON.stringify(data));\n }\n }\n}\n\nexport type { Storage }\nexport { localStorageStorage }"],"mappings":"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","names":["stack","save","action","index","next","latest"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novely/core",
3
3
  "description": "Novely - powerful visual novel engine for creating interactive stories and games with branching narratives and rich multimedia content.",
4
- "version": "0.0.0-beta.5",
4
+ "version": "0.0.0-beta.6",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "types": "./dist/index.d.ts",