@novely/core 0.12.5 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -229,15 +229,79 @@ function klona(val) {
229
229
  return val;
230
230
  }
231
231
 
232
+ // src/translation.ts
233
+ var RGX = /{{(.*?)}}/g;
234
+ var split = (input, delimeters) => {
235
+ const output = [];
236
+ for (const delimeter of delimeters) {
237
+ if (!input)
238
+ break;
239
+ const [start, end] = input.split(delimeter, 2);
240
+ output.push(start);
241
+ input = end;
242
+ }
243
+ output.push(input);
244
+ return output;
245
+ };
246
+ var unwrap = (c) => {
247
+ if (Array.isArray(c)) {
248
+ return c.map((item) => unwrap(item)).join("<br>");
249
+ }
250
+ if (typeof c === "function") {
251
+ return unwrap(c());
252
+ }
253
+ return c;
254
+ };
255
+ var replace = (str2, obj, pluralization, actions, pr) => {
256
+ return unwrap(str2).replaceAll(RGX, (x, key, y) => {
257
+ x = 0;
258
+ y = obj;
259
+ const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
260
+ if (!pathstr) {
261
+ return "";
262
+ }
263
+ const path = pathstr.split(".");
264
+ while (y && x < path.length)
265
+ y = y[path[x++]];
266
+ if (plural && pluralization && y && pr) {
267
+ y = pluralization[plural][pr.select(y)];
268
+ }
269
+ const actionHandler = actions && action && actions[action];
270
+ if (actionHandler)
271
+ y = actionHandler(y);
272
+ return y == null ? "" : y;
273
+ });
274
+ };
275
+
276
+ // src/storage.ts
277
+ var localStorageStorage = (options) => {
278
+ return {
279
+ async get() {
280
+ const fallback = { saves: [], data: {}, meta: [] };
281
+ try {
282
+ const value = localStorage.getItem(options.key);
283
+ return value ? JSON.parse(value) : fallback;
284
+ } catch {
285
+ return fallback;
286
+ }
287
+ },
288
+ async set(data) {
289
+ try {
290
+ localStorage.setItem(options.key, JSON.stringify(data));
291
+ } catch {
292
+ }
293
+ }
294
+ };
295
+ };
296
+
232
297
  // src/novely.ts
233
- import { replace as replaceT9N } from "@novely/t9n";
234
298
  var novely = ({
235
299
  characters,
236
- storage,
300
+ storage = localStorageStorage({ key: "novely-game-storage" }),
237
301
  storageDelay = Promise.resolve(),
238
302
  renderer: createRenderer,
239
303
  initialScreen = "mainmenu",
240
- t9n,
304
+ translation,
241
305
  languages,
242
306
  state: defaultState,
243
307
  data: defaultData,
@@ -358,6 +422,9 @@ var novely = ({
358
422
  storage.set(value);
359
423
  };
360
424
  const throttledOnStorageDataChange = throttle(onStorageDataChange, throttleTimeout);
425
+ const throttledEmergencyOnStorageDataChange = throttle(() => {
426
+ onStorageDataChange($.get());
427
+ }, 10);
361
428
  $.subscribe(throttledOnStorageDataChange);
362
429
  const getStoredData = async () => {
363
430
  let stored = await storage.get();
@@ -385,12 +452,10 @@ var novely = ({
385
452
  const stack = createStack(initial);
386
453
  addEventListener("visibilitychange", () => {
387
454
  if (document.visibilityState === "hidden") {
388
- onStorageDataChange($.get());
455
+ throttledEmergencyOnStorageDataChange();
389
456
  }
390
457
  });
391
- addEventListener("beforeunload", () => {
392
- onStorageDataChange($.get());
393
- });
458
+ addEventListener("beforeunload", throttledEmergencyOnStorageDataChange);
394
459
  const save = (override = false, type = override ? "auto" : "manual") => {
395
460
  if (!$$.get().dataLoaded)
396
461
  return;
@@ -597,6 +662,9 @@ var novely = ({
597
662
  const back = () => {
598
663
  return stack.back(), restore(stack.value);
599
664
  };
665
+ const t = (key, lang) => {
666
+ return translation[lang].internal[key];
667
+ };
600
668
  const renderer = createRenderer({
601
669
  characters,
602
670
  set,
@@ -605,9 +673,9 @@ var novely = ({
605
673
  newGame,
606
674
  exit,
607
675
  back,
676
+ t,
608
677
  stack,
609
678
  languages,
610
- t: t9n.i,
611
679
  $,
612
680
  $$
613
681
  });
@@ -654,7 +722,7 @@ var novely = ({
654
722
  }
655
723
  return c || "";
656
724
  })();
657
- const run = renderer.dialog(unwrap(content), unwrap(name), character, emotion);
725
+ const run = renderer.dialog(unwrap2(content), unwrap2(name), character, emotion);
658
726
  run(forward, goingBack);
659
727
  },
660
728
  function([fn]) {
@@ -670,10 +738,10 @@ var novely = ({
670
738
  question = "";
671
739
  }
672
740
  const unwrapped = choices.map(([content, action2, visible]) => {
673
- return [unwrap(content), action2, visible];
741
+ return [unwrap2(content), action2, visible];
674
742
  });
675
743
  const run = renderer.choices(
676
- unwrap(question),
744
+ unwrap2(question),
677
745
  unwrapped
678
746
  );
679
747
  run((selected) => {
@@ -712,7 +780,7 @@ var novely = ({
712
780
  times.clear();
713
781
  },
714
782
  input([question, onInput, setup]) {
715
- renderer.input(unwrap(question), onInput, setup)(forward);
783
+ renderer.input(unwrap2(question), onInput, setup)(forward);
716
784
  },
717
785
  custom([handler]) {
718
786
  const result = renderer.custom(handler, goingBack, () => {
@@ -752,7 +820,7 @@ var novely = ({
752
820
  match("custom", [handler]);
753
821
  },
754
822
  text(text) {
755
- renderer.text(text.map((content) => unwrap(content)).join(" "), forward, goingBack);
823
+ renderer.text(text.map((content) => unwrap2(content)).join(" "), forward, goingBack);
756
824
  },
757
825
  exit() {
758
826
  if (restoring)
@@ -844,7 +912,7 @@ var novely = ({
844
912
  const interactivity = (value = false) => {
845
913
  interacted = value ? interacted + 1 : 0;
846
914
  };
847
- const unwrap = (content, global = false) => {
915
+ const unwrap2 = (content, global = false) => {
848
916
  const {
849
917
  data: data2,
850
918
  meta: [lang]
@@ -852,7 +920,11 @@ var novely = ({
852
920
  const obj = global ? data2 : state();
853
921
  const cnt = isFunction(content) ? content(lang, obj) : typeof content === "string" ? content : content[lang];
854
922
  const str2 = isFunction(cnt) ? cnt() : cnt;
855
- return replaceT9N(str2, obj);
923
+ const trans = translation[lang];
924
+ if (trans.actions || trans.plural) {
925
+ return replace(str2, obj, trans.plural, trans.actions, new Intl.PluralRules(trans.tag || lang));
926
+ }
927
+ return replace(str2, obj);
856
928
  };
857
929
  function data(value) {
858
930
  if (!value)
@@ -885,28 +957,149 @@ var novely = ({
885
957
  * Unwraps translatable content to a string value
886
958
  */
887
959
  unwrap(content) {
888
- return unwrap(content, true);
889
- },
890
- /**
891
- * Function that is used for translation
892
- */
893
- t: t9n.t
960
+ return unwrap2(content, true);
961
+ }
894
962
  };
895
963
  };
896
964
 
897
- // src/storage.ts
898
- var localStorageStorage = (options) => {
899
- return {
900
- async get() {
901
- const value = localStorage.getItem(options.key);
902
- return value ? JSON.parse(value) : { saves: [], data: {}, meta: [] };
903
- },
904
- async set(data) {
905
- localStorage.setItem(options.key, JSON.stringify(data));
906
- }
907
- };
965
+ // src/translations.ts
966
+ var RU = {
967
+ NewGame: "\u041D\u043E\u0432\u0430\u044F \u0438\u0433\u0440\u0430",
968
+ HomeScreen: "\u0413\u043B\u0430\u0432\u043D\u044B\u0439 \u044D\u043A\u0440\u0430\u043D",
969
+ ToTheGame: "\u041A \u0438\u0433\u0440\u0435",
970
+ Language: "\u042F\u0437\u044B\u043A",
971
+ NoSaves: "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0439 \u043D\u0435\u0442",
972
+ LoadSave: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C",
973
+ Saves: "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F",
974
+ Settings: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
975
+ Sumbit: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C",
976
+ GoBack: "\u041D\u0430\u0437\u0430\u0434",
977
+ DoSave: "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435",
978
+ Auto: "\u0410\u0432\u0442\u043E",
979
+ Stop: "\u0421\u0442\u043E\u043F",
980
+ Exit: "\u0412\u044B\u0445\u043E\u0434",
981
+ Automatic: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u043E\u0435",
982
+ Manual: "\u0420\u0443\u0447\u043D\u043E\u0435",
983
+ Remove: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C",
984
+ LoadASaveFrom: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u043E\u0442",
985
+ DeleteASaveFrom: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u043E\u0442",
986
+ TextSpeed: "\u0421\u043A\u043E\u0440\u043E\u0441\u0442\u044C \u0422\u0435\u043A\u0441\u0442\u0430",
987
+ TextSpeedSlow: "\u041C\u0435\u0434\u043B\u0435\u043D\u043D\u0430\u044F",
988
+ TextSpeedMedium: "\u0421\u0440\u0435\u0434\u043D\u044F\u044F",
989
+ TextSpeedFast: "\u0411\u044B\u0441\u0442\u0440\u0430\u044F",
990
+ TextSpeedAuto: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0430\u044F",
991
+ CompleteText: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442",
992
+ GoForward: "\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u0432\u043F\u0435\u0440\u0451\u0434",
993
+ ExitDialogWarning: "\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B, \u0447\u0442\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0432\u044B\u0439\u0442\u0438? \u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D.",
994
+ ExitDialogExit: "\u0412\u044B\u0439\u0442\u0438",
995
+ ExitDialogBack: "\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u0432 \u0438\u0433\u0440\u0443",
996
+ OpenMenu: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u043D\u044E",
997
+ CloseMenu: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u043D\u044E"
998
+ };
999
+ var EN = {
1000
+ NewGame: "New Game",
1001
+ HomeScreen: "Home Screen",
1002
+ ToTheGame: "To the Game",
1003
+ Language: "Language",
1004
+ NoSaves: "No saves",
1005
+ LoadSave: "Load",
1006
+ Saves: "Saves",
1007
+ Settings: "Settings",
1008
+ Sumbit: "Submit",
1009
+ GoBack: "Go back",
1010
+ DoSave: "Save",
1011
+ Auto: "Auto",
1012
+ Stop: "Stop",
1013
+ Exit: "Exit",
1014
+ Automatic: "Automatic",
1015
+ Manual: "Manual",
1016
+ Remove: "Remove",
1017
+ LoadASaveFrom: "Load a save from",
1018
+ DeleteASaveFrom: "Delete a save from",
1019
+ TextSpeed: "Text Speed",
1020
+ TextSpeedSlow: "Slow",
1021
+ TextSpeedMedium: "Medium",
1022
+ TextSpeedFast: "Fast",
1023
+ TextSpeedAuto: "Auto",
1024
+ CompleteText: "Complete text",
1025
+ GoForward: "Go forward",
1026
+ ExitDialogWarning: "Are you sure you want to exit? Progress will be saved.",
1027
+ ExitDialogExit: "Exit",
1028
+ ExitDialogBack: "Return to game",
1029
+ OpenMenu: "Open menu",
1030
+ CloseMenu: "Close menu"
1031
+ };
1032
+ var KK = {
1033
+ NewGame: "\u0416\u0430\u04A3\u0430 \u043E\u0439\u044B\u043D",
1034
+ HomeScreen: "\u041D\u0435\u0433\u0456\u0437\u0433\u0456 \u044D\u043A\u0440\u0430\u043D",
1035
+ ToTheGame: "\u041E\u0439\u044B\u043D\u0493\u0430",
1036
+ Language: "\u0422\u0456\u043B",
1037
+ NoSaves: "\u0421\u0430\u049B\u0442\u0430\u0443 \u0436\u043E\u049B",
1038
+ LoadSave: "\u0416\u04AF\u043A\u0442\u0435\u0443",
1039
+ Saves: "\u0421\u0430\u049B\u0442\u0430\u0443",
1040
+ Settings: "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043B\u0435\u0440",
1041
+ Sumbit: "\u0420\u0430\u0441\u0442\u0430\u0443",
1042
+ GoBack: "\u0410\u0440\u0442\u049B\u0430",
1043
+ DoSave: "\u0421\u0430\u049B\u0442\u0430\u0443",
1044
+ Auto: "\u0410\u0432\u0442\u043E",
1045
+ Stop: "\u0422\u043E\u049B\u0442\u0430",
1046
+ Exit: "\u0428\u044B\u0493\u0443",
1047
+ Automatic: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0442\u044B",
1048
+ Manual: "\u049A\u043E\u043B\u043C\u0435\u043D",
1049
+ Remove: "\u0416\u043E\u044E",
1050
+ LoadASaveFrom: "\u0421\u0430\u049B\u0442\u0430\u0443\u0434\u044B \u0436\u04AF\u043A\u0442\u0435\u0443",
1051
+ DeleteASaveFrom: "\u0421\u0430\u049B\u0442\u0430\u0443\u0434\u044B \u0436\u043E\u044E",
1052
+ TextSpeed: "\u041C\u04D9\u0442\u0456\u043D \u0416\u044B\u043B\u0434\u0430\u043C\u0434\u044B\u0493\u044B",
1053
+ TextSpeedSlow: "\u0411\u0430\u044F\u0443",
1054
+ TextSpeedMedium: "\u041E\u0440\u0442\u0430\u0448\u0430",
1055
+ TextSpeedFast: "\u0416\u044B\u043B\u0434\u0430\u043C",
1056
+ TextSpeedAuto: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0442\u044B",
1057
+ CompleteText: "\u041C\u04D9\u0442\u0456\u043D\u0434\u0456 \u0430\u044F\u049B\u0442\u0430\u0443",
1058
+ GoForward: "\u0410\u043B\u0493\u0430 \u0436\u044B\u043B\u0436\u0443",
1059
+ ExitDialogWarning: "\u0421\u0456\u0437 \u0448\u044B\u049B\u049B\u044B\u04A3\u044B\u0437 \u043A\u0435\u043B\u0435\u0442\u0456\u043D\u0456\u043D\u0435 \u0441\u0435\u043D\u0456\u043C\u0434\u0456\u0441\u0456\u0437 \u0431\u0435? \u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u0441\u0430\u049B\u0442\u0430\u043B\u0430\u0434\u044B",
1060
+ ExitDialogExit: "\u0428\u044B\u0493\u0443",
1061
+ ExitDialogBack: "\u041E\u0439\u044B\u043D\u0493\u0430 \u043E\u0440\u0430\u043B\u0443",
1062
+ OpenMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0430\u0448\u044B\u04A3\u044B\u0437",
1063
+ CloseMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0436\u0430\u0431\u0443"
1064
+ };
1065
+ var JP = {
1066
+ NewGame: "\u300C\u65B0\u3057\u3044\u30B2\u30FC\u30E0\u300D",
1067
+ HomeScreen: "\u30DB\u30FC\u30E0\u753B\u9762",
1068
+ ToTheGame: "\u300C\u30B2\u30FC\u30E0\u306B\u623B\u308B\u300D",
1069
+ Language: "\u8A00\u8A9E",
1070
+ NoSaves: "\u30CE\u30FC\u30BB\u30FC\u30D6",
1071
+ LoadSave: "\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
1072
+ Saves: "\u4FDD\u5B58",
1073
+ Settings: "\u8A2D\u5B9A",
1074
+ Sumbit: "\u78BA\u8A8D",
1075
+ GoBack: "\u300C\u623B\u308B\u300D",
1076
+ DoSave: "\u4FDD\u5B58",
1077
+ Auto: "\u30AA\u30FC\u30C8",
1078
+ Stop: "\u6B62\u307E\u308C",
1079
+ Exit: "\u51FA\u53E3",
1080
+ Automatic: "\u81EA\u52D5",
1081
+ Manual: "\u30DE\u30CB\u30E5\u30A2\u30EB",
1082
+ Remove: "\u524A\u9664",
1083
+ LoadASaveFrom: "\u30ED\u30FC\u30C9\u30BB\u30FC\u30D6\u304B\u3089",
1084
+ DeleteASaveFrom: "\u304B\u3089\u4FDD\u5B58\u3092\u524A\u9664",
1085
+ TextSpeed: "\u30C6\u30AD\u30B9\u30C8\u30B9\u30D4\u30FC\u30C9",
1086
+ TextSpeedSlow: "\u300C\u9045\u3044\u300D",
1087
+ TextSpeedMedium: "\u30DF\u30C7\u30A3\u30A2\u30E0",
1088
+ TextSpeedFast: "\u300C\u901F\u3044\u300D",
1089
+ TextSpeedAuto: "\u81EA\u52D5",
1090
+ CompleteText: "\u30C6\u30AD\u30B9\u30C8\u3092\u5B8C\u6210\u3055\u305B\u308B",
1091
+ GoForward: "\u5148\u306B\u884C\u304F",
1092
+ ExitDialogWarning: "\u672C\u5F53\u306B\u7D42\u4E86\u3057\u307E\u3059\u304B\uFF1F\u9032\u884C\u72B6\u6CC1\u306F\u4FDD\u5B58\u3055\u308C\u307E\u3059",
1093
+ ExitDialogExit: "\u7D42\u4E86",
1094
+ ExitDialogBack: "\u30B2\u30FC\u30E0\u306B\u623B\u308B",
1095
+ OpenMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u958B\u304F",
1096
+ CloseMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B"
908
1097
  };
909
1098
  export {
1099
+ EN,
1100
+ JP,
1101
+ KK,
1102
+ RU,
910
1103
  localStorageStorage,
911
1104
  novely
912
1105
  };