@novely/core 0.40.3 → 0.42.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.d.ts +30 -8
- package/dist/index.global.js +113 -84
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +113 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "
|
|
2
|
+
var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
|
|
3
3
|
var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
|
|
4
4
|
var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
|
|
5
|
+
var VIRTUAL_ACTIONS = /* @__PURE__ */ new Set(["say", "choiceExtended"]);
|
|
5
6
|
var AUDIO_ACTIONS = /* @__PURE__ */ new Set([
|
|
6
7
|
"playMusic",
|
|
7
8
|
"stopMusic",
|
|
@@ -53,55 +54,6 @@ var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
|
53
54
|
|
|
54
55
|
// src/utils.ts
|
|
55
56
|
import { DEV as DEV2 } from "esm-env";
|
|
56
|
-
|
|
57
|
-
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
58
|
-
function set(obj, key, val) {
|
|
59
|
-
if (typeof val.value === "object") val.value = klona(val.value);
|
|
60
|
-
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
61
|
-
Object.defineProperty(obj, key, val);
|
|
62
|
-
} else obj[key] = val.value;
|
|
63
|
-
}
|
|
64
|
-
function klona(x) {
|
|
65
|
-
if (typeof x !== "object") return x;
|
|
66
|
-
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
67
|
-
if (str2 === "[object Object]") {
|
|
68
|
-
tmp = Object.create(x.__proto__ || null);
|
|
69
|
-
} else if (str2 === "[object Array]") {
|
|
70
|
-
tmp = Array(x.length);
|
|
71
|
-
} else if (str2 === "[object Set]") {
|
|
72
|
-
tmp = /* @__PURE__ */ new Set();
|
|
73
|
-
x.forEach(function(val) {
|
|
74
|
-
tmp.add(klona(val));
|
|
75
|
-
});
|
|
76
|
-
} else if (str2 === "[object Map]") {
|
|
77
|
-
tmp = /* @__PURE__ */ new Map();
|
|
78
|
-
x.forEach(function(val, key) {
|
|
79
|
-
tmp.set(klona(key), klona(val));
|
|
80
|
-
});
|
|
81
|
-
} else if (str2 === "[object Date]") {
|
|
82
|
-
tmp = /* @__PURE__ */ new Date(+x);
|
|
83
|
-
} else if (str2 === "[object RegExp]") {
|
|
84
|
-
tmp = new RegExp(x.source, x.flags);
|
|
85
|
-
} else if (str2 === "[object DataView]") {
|
|
86
|
-
tmp = new x.constructor(klona(x.buffer));
|
|
87
|
-
} else if (str2 === "[object ArrayBuffer]") {
|
|
88
|
-
tmp = x.slice(0);
|
|
89
|
-
} else if (str2.slice(-6) === "Array]") {
|
|
90
|
-
tmp = new x.constructor(x);
|
|
91
|
-
}
|
|
92
|
-
if (tmp) {
|
|
93
|
-
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
94
|
-
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
95
|
-
}
|
|
96
|
-
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
97
|
-
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
98
|
-
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return tmp || x;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// src/utils.ts
|
|
105
57
|
import { memoize as memoize2 } from "es-toolkit/function";
|
|
106
58
|
|
|
107
59
|
// src/asset.ts
|
|
@@ -239,13 +191,11 @@ var isAsset = (suspect) => {
|
|
|
239
191
|
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
240
192
|
return (action, props, { ctx, data }) => {
|
|
241
193
|
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
248
|
-
}
|
|
194
|
+
onBeforeActionCall({
|
|
195
|
+
action,
|
|
196
|
+
props,
|
|
197
|
+
ctx: context
|
|
198
|
+
});
|
|
249
199
|
return values[action]({
|
|
250
200
|
ctx: context,
|
|
251
201
|
data,
|
|
@@ -733,7 +683,7 @@ var nextPath = (path) => {
|
|
|
733
683
|
var isBlockingAction = (action) => {
|
|
734
684
|
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
735
685
|
};
|
|
736
|
-
var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
686
|
+
var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
737
687
|
const collection = [];
|
|
738
688
|
let action = refer(path);
|
|
739
689
|
while (true) {
|
|
@@ -756,11 +706,12 @@ var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
|
756
706
|
for (let i = 0; i < choiceProps.length; i++) {
|
|
757
707
|
const branchContent = choiceProps[i];
|
|
758
708
|
if (!Array.isArray(branchContent)) continue;
|
|
759
|
-
const virtualPath =
|
|
709
|
+
const virtualPath = clone(path);
|
|
760
710
|
virtualPath.push(["choice", i], [null, 0]);
|
|
761
711
|
const innerActions = collectActionsBeforeBlockingAction({
|
|
762
712
|
path: virtualPath,
|
|
763
|
-
refer
|
|
713
|
+
refer,
|
|
714
|
+
clone
|
|
764
715
|
});
|
|
765
716
|
collection.push(...innerActions);
|
|
766
717
|
}
|
|
@@ -768,11 +719,12 @@ var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
|
768
719
|
const conditionProps = props;
|
|
769
720
|
const conditions = Object.keys(conditionProps[1]);
|
|
770
721
|
for (const condition of conditions) {
|
|
771
|
-
const virtualPath =
|
|
722
|
+
const virtualPath = clone(path);
|
|
772
723
|
virtualPath.push(["condition", condition], [null, 0]);
|
|
773
724
|
const innerActions = collectActionsBeforeBlockingAction({
|
|
774
725
|
path: virtualPath,
|
|
775
|
-
refer
|
|
726
|
+
refer,
|
|
727
|
+
clone
|
|
776
728
|
});
|
|
777
729
|
collection.push(...innerActions);
|
|
778
730
|
}
|
|
@@ -854,6 +806,53 @@ var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
|
854
806
|
return { subscribe, update, set: set2, get };
|
|
855
807
|
};
|
|
856
808
|
|
|
809
|
+
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
810
|
+
function set(obj, key, val) {
|
|
811
|
+
if (typeof val.value === "object") val.value = klona(val.value);
|
|
812
|
+
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
813
|
+
Object.defineProperty(obj, key, val);
|
|
814
|
+
} else obj[key] = val.value;
|
|
815
|
+
}
|
|
816
|
+
function klona(x) {
|
|
817
|
+
if (typeof x !== "object") return x;
|
|
818
|
+
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
819
|
+
if (str2 === "[object Object]") {
|
|
820
|
+
tmp = Object.create(x.__proto__ || null);
|
|
821
|
+
} else if (str2 === "[object Array]") {
|
|
822
|
+
tmp = Array(x.length);
|
|
823
|
+
} else if (str2 === "[object Set]") {
|
|
824
|
+
tmp = /* @__PURE__ */ new Set();
|
|
825
|
+
x.forEach(function(val) {
|
|
826
|
+
tmp.add(klona(val));
|
|
827
|
+
});
|
|
828
|
+
} else if (str2 === "[object Map]") {
|
|
829
|
+
tmp = /* @__PURE__ */ new Map();
|
|
830
|
+
x.forEach(function(val, key) {
|
|
831
|
+
tmp.set(klona(key), klona(val));
|
|
832
|
+
});
|
|
833
|
+
} else if (str2 === "[object Date]") {
|
|
834
|
+
tmp = /* @__PURE__ */ new Date(+x);
|
|
835
|
+
} else if (str2 === "[object RegExp]") {
|
|
836
|
+
tmp = new RegExp(x.source, x.flags);
|
|
837
|
+
} else if (str2 === "[object DataView]") {
|
|
838
|
+
tmp = new x.constructor(klona(x.buffer));
|
|
839
|
+
} else if (str2 === "[object ArrayBuffer]") {
|
|
840
|
+
tmp = x.slice(0);
|
|
841
|
+
} else if (str2.slice(-6) === "Array]") {
|
|
842
|
+
tmp = new x.constructor(x);
|
|
843
|
+
}
|
|
844
|
+
if (tmp) {
|
|
845
|
+
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
846
|
+
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
847
|
+
}
|
|
848
|
+
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
849
|
+
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
850
|
+
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
return tmp || x;
|
|
854
|
+
}
|
|
855
|
+
|
|
857
856
|
// src/translation.ts
|
|
858
857
|
var RGX = /{{(.*?)}}/g;
|
|
859
858
|
var split = (input, delimeters) => {
|
|
@@ -1103,6 +1102,14 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
1103
1102
|
}
|
|
1104
1103
|
return;
|
|
1105
1104
|
}
|
|
1105
|
+
if (action === "choice") {
|
|
1106
|
+
for (let i = 1; i < props.length; i++) {
|
|
1107
|
+
const data = props[i];
|
|
1108
|
+
if (Array.isArray(data)) {
|
|
1109
|
+
handle(handleImageAsset(data[4]));
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1106
1113
|
};
|
|
1107
1114
|
|
|
1108
1115
|
// src/novely.ts
|
|
@@ -1126,6 +1133,7 @@ var novely = ({
|
|
|
1126
1133
|
preloadAssets = "lazy",
|
|
1127
1134
|
parallelAssetsDownloadLimit = 15,
|
|
1128
1135
|
fetch: request = fetch,
|
|
1136
|
+
cloneFunction: clone = klona,
|
|
1129
1137
|
saveOnUnload = true,
|
|
1130
1138
|
startKey = "start"
|
|
1131
1139
|
}) => {
|
|
@@ -1178,6 +1186,28 @@ var novely = ({
|
|
|
1178
1186
|
return renderer.actions[action2];
|
|
1179
1187
|
}
|
|
1180
1188
|
return (...props) => {
|
|
1189
|
+
if (VIRTUAL_ACTIONS.has(action2)) {
|
|
1190
|
+
if (action2 === "say") {
|
|
1191
|
+
action2 = "dialog";
|
|
1192
|
+
const [character] = props;
|
|
1193
|
+
if (DEV3 && !characters[character]) {
|
|
1194
|
+
throw new Error(`Attempt to call Say action with unknown character "${character}"`);
|
|
1195
|
+
}
|
|
1196
|
+
} else if (action2 === "choiceExtended") {
|
|
1197
|
+
action2 = "choice";
|
|
1198
|
+
const choices = props[1];
|
|
1199
|
+
const mappedChoices = choices.map((choice) => [
|
|
1200
|
+
choice.title,
|
|
1201
|
+
choice.children,
|
|
1202
|
+
choice.active,
|
|
1203
|
+
choice.visible,
|
|
1204
|
+
choice.image
|
|
1205
|
+
]);
|
|
1206
|
+
for (let i = 0; i < mappedChoices.length; i++) {
|
|
1207
|
+
props[i + 1] = mappedChoices[i];
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1181
1211
|
if (preloadAssets === "blocking") {
|
|
1182
1212
|
huntAssets({
|
|
1183
1213
|
action: action2,
|
|
@@ -1193,7 +1223,7 @@ var novely = ({
|
|
|
1193
1223
|
};
|
|
1194
1224
|
}
|
|
1195
1225
|
});
|
|
1196
|
-
const getDefaultSave = (state
|
|
1226
|
+
const getDefaultSave = (state) => {
|
|
1197
1227
|
return [
|
|
1198
1228
|
[
|
|
1199
1229
|
["jump", startKey],
|
|
@@ -1215,7 +1245,7 @@ var novely = ({
|
|
|
1215
1245
|
};
|
|
1216
1246
|
const initialData = {
|
|
1217
1247
|
saves: [],
|
|
1218
|
-
data:
|
|
1248
|
+
data: clone(defaultData),
|
|
1219
1249
|
meta: [getLanguageWithoutParameters(), DEFAULT_TYPEWRITER_SPEED, 1, 1, 1]
|
|
1220
1250
|
};
|
|
1221
1251
|
const storageData = store(initialData);
|
|
@@ -1265,7 +1295,7 @@ var novely = ({
|
|
|
1265
1295
|
storageData.set(stored);
|
|
1266
1296
|
};
|
|
1267
1297
|
storageDelay.then(getStoredData);
|
|
1268
|
-
const initial = getDefaultSave(
|
|
1298
|
+
const initial = getDefaultSave(clone(defaultState));
|
|
1269
1299
|
const unsubscribeFromBrowserVisibilityChange = setupBrowserVisibilityChangeListeners({
|
|
1270
1300
|
onChange: throttledEmergencyOnStorageDataChange
|
|
1271
1301
|
});
|
|
@@ -1273,7 +1303,7 @@ var novely = ({
|
|
|
1273
1303
|
if (!coreData.get().dataLoaded) return;
|
|
1274
1304
|
if (!autosaves && type === "auto") return;
|
|
1275
1305
|
const stack = useStack(MAIN_CONTEXT_KEY);
|
|
1276
|
-
const current =
|
|
1306
|
+
const current = clone(stack.value);
|
|
1277
1307
|
storageData.update((prev) => {
|
|
1278
1308
|
const replace2 = () => {
|
|
1279
1309
|
prev.saves[prev.saves.length - 1] = current;
|
|
@@ -1303,7 +1333,7 @@ var novely = ({
|
|
|
1303
1333
|
};
|
|
1304
1334
|
const newGame = () => {
|
|
1305
1335
|
if (!coreData.get().dataLoaded) return;
|
|
1306
|
-
const save2 = getDefaultSave(
|
|
1336
|
+
const save2 = getDefaultSave(clone(defaultState));
|
|
1307
1337
|
if (autosaves) {
|
|
1308
1338
|
storageData.update((prev) => {
|
|
1309
1339
|
return prev.saves.push(save2), prev;
|
|
@@ -1332,7 +1362,7 @@ var novely = ({
|
|
|
1332
1362
|
if (!coreData.get().dataLoaded) return;
|
|
1333
1363
|
let latest = save2 || storageData.get().saves.at(-1);
|
|
1334
1364
|
if (!latest) {
|
|
1335
|
-
latest =
|
|
1365
|
+
latest = clone(initial);
|
|
1336
1366
|
storageData.update((prev) => {
|
|
1337
1367
|
prev.saves.push(latest);
|
|
1338
1368
|
return prev;
|
|
@@ -1444,7 +1474,7 @@ var novely = ({
|
|
|
1444
1474
|
const processor = createQueueProcessor(queue, {
|
|
1445
1475
|
skip: EMPTY_SET
|
|
1446
1476
|
});
|
|
1447
|
-
useStack(ctx).push(
|
|
1477
|
+
useStack(ctx).push(clone(save2));
|
|
1448
1478
|
const assets = [];
|
|
1449
1479
|
await processor.run(([action2, ...props]) => {
|
|
1450
1480
|
if (isAudioAction(action2)) return;
|
|
@@ -1539,7 +1569,7 @@ var novely = ({
|
|
|
1539
1569
|
const enmemory = (ctx) => {
|
|
1540
1570
|
if (ctx.meta.restoring) return;
|
|
1541
1571
|
const stack = useStack(ctx);
|
|
1542
|
-
const current =
|
|
1572
|
+
const current = clone(stack.value);
|
|
1543
1573
|
current[2][1] = "auto";
|
|
1544
1574
|
stack.push(current);
|
|
1545
1575
|
save("auto");
|
|
@@ -1567,8 +1597,9 @@ var novely = ({
|
|
|
1567
1597
|
if (!isBlockingAction([action2, ...props])) return;
|
|
1568
1598
|
try {
|
|
1569
1599
|
const collection = collectActionsBeforeBlockingAction({
|
|
1570
|
-
path: nextPath(
|
|
1571
|
-
refer
|
|
1600
|
+
path: nextPath(clone(useStack(ctx).value[0])),
|
|
1601
|
+
refer,
|
|
1602
|
+
clone
|
|
1572
1603
|
});
|
|
1573
1604
|
for (const [action3, ...props2] of collection) {
|
|
1574
1605
|
huntAssets({
|
|
@@ -1686,15 +1717,6 @@ var novely = ({
|
|
|
1686
1717
|
forward
|
|
1687
1718
|
);
|
|
1688
1719
|
},
|
|
1689
|
-
say({ ctx, data: data2 }, [character, content]) {
|
|
1690
|
-
if (DEV3 && !characters[character]) {
|
|
1691
|
-
throw new Error(`Attempt to call Say action with unknown character "${character}"`);
|
|
1692
|
-
}
|
|
1693
|
-
match("dialog", [character, content], {
|
|
1694
|
-
ctx,
|
|
1695
|
-
data: data2
|
|
1696
|
-
});
|
|
1697
|
-
},
|
|
1698
1720
|
function({ ctx, push }, [fn]) {
|
|
1699
1721
|
const { restoring, goingBack, preview: preview2 } = ctx.meta;
|
|
1700
1722
|
const result = fn({
|
|
@@ -1715,15 +1737,20 @@ var novely = ({
|
|
|
1715
1737
|
choices.unshift(question);
|
|
1716
1738
|
question = "";
|
|
1717
1739
|
}
|
|
1718
|
-
const transformedChoices = choices.map(([content, action2, visible]) => {
|
|
1719
|
-
const
|
|
1740
|
+
const transformedChoices = choices.map(([content, action2, active, visible, image]) => {
|
|
1741
|
+
const activeValue = !active || active({
|
|
1742
|
+
lang: getLanguageFromStore(storageData),
|
|
1743
|
+
state: getStateAtCtx(ctx)
|
|
1744
|
+
});
|
|
1745
|
+
const visibleValue = !visible || visible({
|
|
1720
1746
|
lang: getLanguageFromStore(storageData),
|
|
1721
1747
|
state: getStateAtCtx(ctx)
|
|
1722
1748
|
});
|
|
1723
|
-
|
|
1749
|
+
const imageValue = image ? handleImageAsset(image) : "";
|
|
1750
|
+
if (DEV3 && action2.length === 0 && (!activeValue && !visibleValue)) {
|
|
1724
1751
|
console.warn(`Choice children should not be empty, either add content there or make item not selectable`);
|
|
1725
1752
|
}
|
|
1726
|
-
return [templateReplace(content, data2),
|
|
1753
|
+
return [templateReplace(content, data2), activeValue, visibleValue, imageValue];
|
|
1727
1754
|
});
|
|
1728
1755
|
if (DEV3 && transformedChoices.length === 0) {
|
|
1729
1756
|
throw new Error(`Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`);
|
|
@@ -1950,7 +1977,7 @@ var novely = ({
|
|
|
1950
1977
|
c: null
|
|
1951
1978
|
};
|
|
1952
1979
|
const getCurrentStorageData = () => {
|
|
1953
|
-
return coreData.get().dataLoaded ?
|
|
1980
|
+
return coreData.get().dataLoaded ? clone(storageData.get()) : null;
|
|
1954
1981
|
};
|
|
1955
1982
|
const setStorageData = (data2) => {
|
|
1956
1983
|
if (destroyed) {
|