@novely/core 0.29.0 → 0.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ var MAIN_CONTEXT_KEY = "$MAIN";
47
47
 
48
48
  // src/shared.ts
49
49
  var STACK_MAP = /* @__PURE__ */ new Map();
50
+ var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
50
51
 
51
52
  // src/utils.ts
52
53
  import { DEV } from "esm-env";
@@ -322,7 +323,9 @@ var createQueueProcessor = (queue, options) => {
322
323
  if (target !== params[0]) {
323
324
  return false;
324
325
  }
325
- return _action === closing || _action === action;
326
+ const musicGonnaBePaused = action === "playMusic" && _action === "pauseMusic";
327
+ const soundGonnaBePaused = action === "playSound" && _action === "pauseSound";
328
+ return musicGonnaBePaused || soundGonnaBePaused || _action === closing || _action === action;
326
329
  });
327
330
  if (skip)
328
331
  continue;
@@ -462,13 +465,23 @@ var getResourseType = async (request, url) => {
462
465
  }
463
466
  return "other";
464
467
  };
468
+ var capitalize = (str2) => {
469
+ return str2[0].toUpperCase() + str2.slice(1);
470
+ };
471
+ var getIntlLanguageDisplayName = (lang) => {
472
+ try {
473
+ const intl = new Intl.DisplayNames([lang], {
474
+ type: "language"
475
+ });
476
+ return intl.of(lang) || lang;
477
+ } catch {
478
+ return lang;
479
+ }
480
+ };
465
481
 
466
482
  // src/novely.ts
467
483
  import { dequal } from "dequal/lite";
468
484
 
469
- // src/global.ts
470
- var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
471
-
472
485
  // src/store.ts
473
486
  var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
474
487
  const subscribe = (cb) => {
@@ -504,7 +517,9 @@ var propertyIsOnObject = (object, property) => {
504
517
  }
505
518
  };
506
519
  var propertyIsUnsafe = (target, key) => {
507
- return propertyIsOnObject(target, key) && !(hasOwnProperty.call(target, key) && propertyIsEnumerable.call(target, key));
520
+ return propertyIsOnObject(target, key) && // Properties are safe to merge if they don't exist in the target yet,
521
+ !(hasOwnProperty.call(target, key) && // unsafe if they exist up the prototype chain,
522
+ propertyIsEnumerable.call(target, key));
508
523
  };
509
524
  var getEnumerableOwnPropertySymbols = (target) => {
510
525
  if (!getOwnPropertySymbols)
@@ -616,10 +631,10 @@ var flattenAllowedContent = (c, state) => {
616
631
  }
617
632
  return c;
618
633
  };
619
- var replace = (str2, obj, pluralization, actions, pr) => {
620
- return str2.replaceAll(RGX, (x, key, y) => {
634
+ var replace = (input, data, pluralization, actions, pr) => {
635
+ return input.replaceAll(RGX, (x, key, y) => {
621
636
  x = 0;
622
- y = obj;
637
+ y = data;
623
638
  const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
624
639
  if (!pathstr) {
625
640
  return "";
@@ -630,7 +645,7 @@ var replace = (str2, obj, pluralization, actions, pr) => {
630
645
  if (plural && pluralization && y && pr) {
631
646
  y = pluralization[plural][pr.select(y)];
632
647
  }
633
- const actionHandler = actions && action && actions[action];
648
+ const actionHandler = actions && action ? actions[action] : void 0;
634
649
  if (actionHandler)
635
650
  y = actionHandler(y);
636
651
  return y == null ? "" : y;
@@ -658,6 +673,23 @@ var localStorageStorage = (options) => {
658
673
  };
659
674
  };
660
675
 
676
+ // src/browser.ts
677
+ var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
678
+ if (typeof document === "undefined")
679
+ return noop;
680
+ const onVisibilityChange = () => {
681
+ if (document.visibilityState === "hidden") {
682
+ onChange();
683
+ }
684
+ };
685
+ addEventListener("visibilitychange", onVisibilityChange);
686
+ addEventListener("beforeunload", onChange);
687
+ return () => {
688
+ removeEventListener("visibilitychange", onVisibilityChange);
689
+ removeEventListener("beforeunload", onChange);
690
+ };
691
+ };
692
+
661
693
  // src/novely.ts
662
694
  import pLimit from "p-limit";
663
695
  import { DEV as DEV2 } from "esm-env";
@@ -679,7 +711,8 @@ var novely = ({
679
711
  preloadAssets = "lazy",
680
712
  parallelAssetsDownloadLimit = 15,
681
713
  fetch: request = fetch,
682
- saveOnUnload = true
714
+ saveOnUnload = true,
715
+ startKey = "start"
683
716
  }) => {
684
717
  const languages = Object.keys(translation);
685
718
  const limitScript = pLimit(1);
@@ -775,7 +808,7 @@ var novely = ({
775
808
  const getDefaultSave = (state = {}) => {
776
809
  return [
777
810
  [
778
- ["jump", "start"],
811
+ ["jump", startKey],
779
812
  [null, 0]
780
813
  ],
781
814
  state,
@@ -843,13 +876,9 @@ var novely = ({
843
876
  };
844
877
  storageDelay.then(getStoredData);
845
878
  const initial = getDefaultSave(klona(defaultState));
846
- const onVisibilityChange = () => {
847
- if (document.visibilityState === "hidden") {
848
- throttledEmergencyOnStorageDataChange();
849
- }
850
- };
851
- addEventListener("visibilitychange", onVisibilityChange);
852
- addEventListener("beforeunload", throttledEmergencyOnStorageDataChange);
879
+ const unsubscribeFromBrowserVisibilityChange = setupBrowserVisibilityChangeListeners({
880
+ onChange: throttledEmergencyOnStorageDataChange
881
+ });
853
882
  const save = (type) => {
854
883
  if (!coreData.get().dataLoaded)
855
884
  return;
@@ -1012,7 +1041,11 @@ var novely = ({
1012
1041
  };
1013
1042
  const back = async () => {
1014
1043
  const stack = useStack(MAIN_CONTEXT_KEY);
1044
+ const valueBeforeBack = stack.value;
1015
1045
  stack.back();
1046
+ if (dequal(valueBeforeBack, stack.value) && !stack.previous) {
1047
+ return;
1048
+ }
1016
1049
  await restore(stack.value);
1017
1050
  };
1018
1051
  const t = (key, lang) => {
@@ -1025,7 +1058,7 @@ var novely = ({
1025
1058
  ctx.meta.restoring = true;
1026
1059
  ctx.meta.preview = true;
1027
1060
  const processor = createQueueProcessor(queue, {
1028
- skip: /* @__PURE__ */ new Set()
1061
+ skip: EMPTY_SET
1029
1062
  });
1030
1063
  useStack(ctx).push(klona(save2));
1031
1064
  await processor.run(([action2, ...props]) => {
@@ -1061,6 +1094,13 @@ var novely = ({
1061
1094
  };
1062
1095
  return state;
1063
1096
  };
1097
+ const getLanguageDisplayName = (lang) => {
1098
+ const language = translation[lang];
1099
+ if (DEV2 && !language) {
1100
+ throw new Error(`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`);
1101
+ }
1102
+ return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
1103
+ };
1064
1104
  const renderer = createRenderer({
1065
1105
  mainContextKey: MAIN_CONTEXT_KEY,
1066
1106
  characters,
@@ -1076,7 +1116,8 @@ var novely = ({
1076
1116
  getStateFunction,
1077
1117
  languages,
1078
1118
  storageData,
1079
- coreData
1119
+ coreData,
1120
+ getLanguageDisplayName
1080
1121
  });
1081
1122
  const useStack = createUseStackFunction(renderer);
1082
1123
  useStack(MAIN_CONTEXT_KEY).push(initial);
@@ -1428,6 +1469,11 @@ var novely = ({
1428
1469
  ctx,
1429
1470
  data: stack.value[1]
1430
1471
  });
1472
+ } else if (Object.values(story).some((branch) => branch === referred)) {
1473
+ match("end", [], {
1474
+ ctx,
1475
+ data: stack.value[1]
1476
+ });
1431
1477
  } else {
1432
1478
  match("exit", [], {
1433
1479
  ctx,
@@ -1439,14 +1485,10 @@ var novely = ({
1439
1485
  interacted = value ? interacted + 1 : 0;
1440
1486
  };
1441
1487
  const templateReplace = (content, values) => {
1442
- const {
1443
- data: data2,
1444
- meta: [lang]
1445
- } = storageData.get();
1488
+ const { data: data2, meta: [lang] } = storageData.get();
1446
1489
  const obj = values || data2;
1447
- const cnt = isFunction(content) ? content(obj) : typeof content === "string" ? content : content[lang];
1448
1490
  const str2 = flattenAllowedContent(
1449
- isFunction(cnt) ? cnt(obj) : cnt,
1491
+ !isFunction(content) && !isString(content) ? content[lang] : content,
1450
1492
  obj
1451
1493
  );
1452
1494
  const t2 = translation[lang];
@@ -1546,8 +1588,7 @@ var novely = ({
1546
1588
  destroy() {
1547
1589
  dataLoaded.cancel();
1548
1590
  UIInstance.unmount();
1549
- removeEventListener("visibilitychange", onVisibilityChange);
1550
- removeEventListener("beforeunload", throttledEmergencyOnStorageDataChange);
1591
+ unsubscribeFromBrowserVisibilityChange();
1551
1592
  }
1552
1593
  };
1553
1594
  };