@novely/core 0.35.0 → 0.36.0-beta.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 +1 -1
- package/dist/index.global.js +173 -53
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +173 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -82,9 +82,16 @@ function klona(val) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// src/utils.ts
|
|
85
|
-
var matchAction = ({ getContext, push, forward }, values) => {
|
|
85
|
+
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
86
86
|
return (action, props, { ctx, data }) => {
|
|
87
87
|
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
88
|
+
if (action !== "say") {
|
|
89
|
+
onBeforeActionCall({
|
|
90
|
+
action,
|
|
91
|
+
props,
|
|
92
|
+
ctx: context
|
|
93
|
+
});
|
|
94
|
+
}
|
|
88
95
|
return values[action]({
|
|
89
96
|
ctx: context,
|
|
90
97
|
data,
|
|
@@ -249,7 +256,7 @@ var getOppositeAction = (action) => {
|
|
|
249
256
|
var getActionsFromPath = (story, path, filter) => {
|
|
250
257
|
let current = story;
|
|
251
258
|
let precurrent;
|
|
252
|
-
let
|
|
259
|
+
let ignoreNestedBefore = null;
|
|
253
260
|
let index = 0;
|
|
254
261
|
let skipPreserve = void 0;
|
|
255
262
|
const skip = /* @__PURE__ */ new Set();
|
|
@@ -270,11 +277,11 @@ var getActionsFromPath = (story, path, filter) => {
|
|
|
270
277
|
if (isNumber(val)) {
|
|
271
278
|
index++;
|
|
272
279
|
let startIndex = 0;
|
|
273
|
-
if (
|
|
274
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index),
|
|
280
|
+
if (ignoreNestedBefore) {
|
|
281
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index), ignoreNestedBefore);
|
|
275
282
|
if (prev) {
|
|
276
283
|
startIndex = prev[1];
|
|
277
|
-
|
|
284
|
+
ignoreNestedBefore = null;
|
|
278
285
|
}
|
|
279
286
|
}
|
|
280
287
|
for (let i = startIndex; i <= val; i++) {
|
|
@@ -309,7 +316,7 @@ var getActionsFromPath = (story, path, filter) => {
|
|
|
309
316
|
current = story[val];
|
|
310
317
|
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
311
318
|
current = blocks.pop();
|
|
312
|
-
|
|
319
|
+
ignoreNestedBefore = type.slice(0, -5);
|
|
313
320
|
}
|
|
314
321
|
}
|
|
315
322
|
return {
|
|
@@ -493,6 +500,9 @@ var fetchContentType = async (request, url) => {
|
|
|
493
500
|
}
|
|
494
501
|
};
|
|
495
502
|
var getResourseType = async (request, url) => {
|
|
503
|
+
if (!isCSSImage(url)) {
|
|
504
|
+
return "other";
|
|
505
|
+
}
|
|
496
506
|
const extension = getUrlFileExtension(url);
|
|
497
507
|
if (HOWLER_SUPPORTED_FILE_FORMATS.has(extension)) {
|
|
498
508
|
return "audio";
|
|
@@ -606,6 +616,68 @@ var nextPath = (path) => {
|
|
|
606
616
|
}
|
|
607
617
|
return path;
|
|
608
618
|
};
|
|
619
|
+
var isBlockingAction = (action) => {
|
|
620
|
+
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
621
|
+
};
|
|
622
|
+
var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
623
|
+
const collection = [];
|
|
624
|
+
let action = refer(path);
|
|
625
|
+
while (true) {
|
|
626
|
+
if (action == void 0) {
|
|
627
|
+
const { exitImpossible } = exitPath({
|
|
628
|
+
path,
|
|
629
|
+
refer
|
|
630
|
+
});
|
|
631
|
+
if (exitImpossible) {
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
if (!action) {
|
|
636
|
+
break;
|
|
637
|
+
}
|
|
638
|
+
if (isBlockingAction(action)) {
|
|
639
|
+
const [name, ...props] = action;
|
|
640
|
+
if (name === "choice") {
|
|
641
|
+
const choiceProps = props;
|
|
642
|
+
for (let i = 0; i < choiceProps.length; i++) {
|
|
643
|
+
const branchContent = choiceProps[i];
|
|
644
|
+
if (!Array.isArray(branchContent))
|
|
645
|
+
continue;
|
|
646
|
+
const virtualPath = klona(path);
|
|
647
|
+
virtualPath.push(["choice", i], [null, 0]);
|
|
648
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
649
|
+
path: virtualPath,
|
|
650
|
+
refer
|
|
651
|
+
});
|
|
652
|
+
collection.push(...innerActions);
|
|
653
|
+
}
|
|
654
|
+
} else if (name === "condition") {
|
|
655
|
+
const conditionProps = props;
|
|
656
|
+
const conditions = Object.keys(conditionProps[1]);
|
|
657
|
+
for (const condition of conditions) {
|
|
658
|
+
const virtualPath = klona(path);
|
|
659
|
+
virtualPath.push(["condition", condition], [null, 0]);
|
|
660
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
661
|
+
path: virtualPath,
|
|
662
|
+
refer
|
|
663
|
+
});
|
|
664
|
+
collection.push(...innerActions);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
collection.push(action);
|
|
670
|
+
if (action[0] === "jump") {
|
|
671
|
+
path = [["jump", action[1]], [null, 0]];
|
|
672
|
+
} else if (action[0] == "block") {
|
|
673
|
+
path.push(["block", action[1]], [null, 0]);
|
|
674
|
+
} else {
|
|
675
|
+
nextPath(path);
|
|
676
|
+
}
|
|
677
|
+
action = refer(path);
|
|
678
|
+
}
|
|
679
|
+
return collection;
|
|
680
|
+
};
|
|
609
681
|
|
|
610
682
|
// src/novely.ts
|
|
611
683
|
import { dequal } from "dequal/lite";
|
|
@@ -896,6 +968,26 @@ var novely = ({
|
|
|
896
968
|
const intime = (value) => {
|
|
897
969
|
return times.add(value), value;
|
|
898
970
|
};
|
|
971
|
+
const handleAssetsPreloading = async () => {
|
|
972
|
+
const { preloadAudioBlocking, preloadImageBlocking } = renderer.misc;
|
|
973
|
+
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
974
|
+
return limitAssetsDownload(async () => {
|
|
975
|
+
const type = await getResourseType(request, asset);
|
|
976
|
+
switch (type) {
|
|
977
|
+
case "audio": {
|
|
978
|
+
await preloadAudioBlocking(asset);
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
case "image": {
|
|
982
|
+
await preloadImageBlocking(asset);
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
await Promise.allSettled(list);
|
|
989
|
+
ASSETS_TO_PRELOAD.clear();
|
|
990
|
+
};
|
|
899
991
|
const scriptBase = async (part) => {
|
|
900
992
|
Object.assign(story, flattenStory(part));
|
|
901
993
|
let loadingIsShown = false;
|
|
@@ -907,31 +999,14 @@ var novely = ({
|
|
|
907
999
|
if (!loadingIsShown) {
|
|
908
1000
|
renderer.ui.showLoading();
|
|
909
1001
|
}
|
|
910
|
-
|
|
911
|
-
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
912
|
-
return limitAssetsDownload(async () => {
|
|
913
|
-
const type = await getResourseType(request, asset);
|
|
914
|
-
switch (type) {
|
|
915
|
-
case "audio": {
|
|
916
|
-
await preloadAudioBlocking(asset);
|
|
917
|
-
break;
|
|
918
|
-
}
|
|
919
|
-
case "image": {
|
|
920
|
-
await preloadImageBlocking(asset);
|
|
921
|
-
break;
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
});
|
|
925
|
-
});
|
|
926
|
-
await Promise.allSettled(list);
|
|
1002
|
+
await handleAssetsPreloading();
|
|
927
1003
|
}
|
|
928
|
-
ASSETS_TO_PRELOAD.clear();
|
|
929
1004
|
await dataLoaded.promise;
|
|
930
1005
|
renderer.ui.hideLoading();
|
|
931
1006
|
if (!initialScreenWasShown) {
|
|
932
1007
|
initialScreenWasShown = true;
|
|
933
1008
|
if (initialScreen === "game") {
|
|
934
|
-
restore();
|
|
1009
|
+
restore(void 0);
|
|
935
1010
|
} else {
|
|
936
1011
|
renderer.ui.showScreen(initialScreen);
|
|
937
1012
|
}
|
|
@@ -940,6 +1015,33 @@ var novely = ({
|
|
|
940
1015
|
const script = (part) => {
|
|
941
1016
|
return limitScript(() => scriptBase(part));
|
|
942
1017
|
};
|
|
1018
|
+
const checkAndAddToPreloadingList = (action2, props) => {
|
|
1019
|
+
if (action2 === "showBackground") {
|
|
1020
|
+
if (isImageAsset(props[0])) {
|
|
1021
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1022
|
+
}
|
|
1023
|
+
if (props[0] && typeof props[0] === "object") {
|
|
1024
|
+
for (const value of Object.values(props[0])) {
|
|
1025
|
+
if (!isImageAsset(value))
|
|
1026
|
+
continue;
|
|
1027
|
+
ASSETS_TO_PRELOAD.add(value);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
if (isAudioAction(action2) && isString(props[0])) {
|
|
1032
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1033
|
+
}
|
|
1034
|
+
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1035
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
1036
|
+
if (Array.isArray(images)) {
|
|
1037
|
+
for (const asset of images) {
|
|
1038
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
1039
|
+
}
|
|
1040
|
+
} else {
|
|
1041
|
+
ASSETS_TO_PRELOAD.add(images);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
943
1045
|
const action = new Proxy({}, {
|
|
944
1046
|
get(_, action2) {
|
|
945
1047
|
if (action2 in renderer.actions) {
|
|
@@ -947,31 +1049,7 @@ var novely = ({
|
|
|
947
1049
|
}
|
|
948
1050
|
return (...props) => {
|
|
949
1051
|
if (preloadAssets === "blocking") {
|
|
950
|
-
|
|
951
|
-
if (isImageAsset(props[0])) {
|
|
952
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
953
|
-
}
|
|
954
|
-
if (props[0] && typeof props[0] === "object") {
|
|
955
|
-
for (const value of Object.values(props[0])) {
|
|
956
|
-
if (!isImageAsset(value))
|
|
957
|
-
continue;
|
|
958
|
-
ASSETS_TO_PRELOAD.add(value);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
if (isAudioAction(action2) && isString(props[0])) {
|
|
963
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
964
|
-
}
|
|
965
|
-
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
966
|
-
const images = characters[props[0]].emotions[props[1]];
|
|
967
|
-
if (Array.isArray(images)) {
|
|
968
|
-
for (const asset of images) {
|
|
969
|
-
ASSETS_TO_PRELOAD.add(asset);
|
|
970
|
-
}
|
|
971
|
-
} else {
|
|
972
|
-
ASSETS_TO_PRELOAD.add(images);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
1052
|
+
checkAndAddToPreloadingList(action2, props);
|
|
975
1053
|
}
|
|
976
1054
|
return [action2, ...props];
|
|
977
1055
|
};
|
|
@@ -1098,7 +1176,12 @@ var novely = ({
|
|
|
1098
1176
|
return prev.saves.push(save2), prev;
|
|
1099
1177
|
});
|
|
1100
1178
|
}
|
|
1101
|
-
|
|
1179
|
+
const context = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1180
|
+
const stack = useStack(context);
|
|
1181
|
+
stack.value = save2;
|
|
1182
|
+
context.meta.restoring = context.meta.goingBack = false;
|
|
1183
|
+
renderer.ui.showScreen("game");
|
|
1184
|
+
render(context);
|
|
1102
1185
|
};
|
|
1103
1186
|
const set = (save2, ctx) => {
|
|
1104
1187
|
const stack = useStack(ctx || MAIN_CONTEXT_KEY);
|
|
@@ -1153,8 +1236,8 @@ var novely = ({
|
|
|
1153
1236
|
data: latest[1]
|
|
1154
1237
|
});
|
|
1155
1238
|
}
|
|
1156
|
-
const lastQueueItem = queue.at(-1)
|
|
1157
|
-
const lastQueueItemRequiresUserAction =
|
|
1239
|
+
const lastQueueItem = queue.at(-1);
|
|
1240
|
+
const lastQueueItemRequiresUserAction = lastQueueItem && isBlockingAction(lastQueueItem);
|
|
1158
1241
|
await run((item) => {
|
|
1159
1242
|
if (!latest)
|
|
1160
1243
|
return;
|
|
@@ -1321,6 +1404,40 @@ var novely = ({
|
|
|
1321
1404
|
matchActionOptions.push(ctx);
|
|
1322
1405
|
if (!ctx.meta.preview)
|
|
1323
1406
|
interactivity(true);
|
|
1407
|
+
},
|
|
1408
|
+
onBeforeActionCall({ action: action2, props, ctx }) {
|
|
1409
|
+
if (preloadAssets !== "automatic")
|
|
1410
|
+
return;
|
|
1411
|
+
if (ctx.meta.preview || ctx.meta.restoring)
|
|
1412
|
+
return;
|
|
1413
|
+
if (!isBlockingAction([action2, ...props]))
|
|
1414
|
+
return;
|
|
1415
|
+
try {
|
|
1416
|
+
const collection = collectActionsBeforeBlockingAction({
|
|
1417
|
+
path: nextPath(klona(useStack(ctx).value[0])),
|
|
1418
|
+
refer
|
|
1419
|
+
});
|
|
1420
|
+
for (const [action3, ...props2] of collection) {
|
|
1421
|
+
checkAndAddToPreloadingList(action3, props2);
|
|
1422
|
+
}
|
|
1423
|
+
const { preloadAudioBlocking, preloadImage } = renderer.misc;
|
|
1424
|
+
ASSETS_TO_PRELOAD.forEach(async (asset) => {
|
|
1425
|
+
ASSETS_TO_PRELOAD.delete(asset);
|
|
1426
|
+
const type = await getResourseType(request, asset);
|
|
1427
|
+
switch (type) {
|
|
1428
|
+
case "audio": {
|
|
1429
|
+
preloadAudioBlocking(asset);
|
|
1430
|
+
break;
|
|
1431
|
+
}
|
|
1432
|
+
case "image": {
|
|
1433
|
+
preloadImage(asset);
|
|
1434
|
+
break;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
} catch (cause) {
|
|
1439
|
+
console.error(cause);
|
|
1440
|
+
}
|
|
1324
1441
|
}
|
|
1325
1442
|
};
|
|
1326
1443
|
const match = matchAction(matchActionOptions, {
|
|
@@ -1602,6 +1719,9 @@ var novely = ({
|
|
|
1602
1719
|
render(ctx);
|
|
1603
1720
|
},
|
|
1604
1721
|
preload({ ctx, push }, [source]) {
|
|
1722
|
+
if (DEV2 && preloadAssets !== "lazy") {
|
|
1723
|
+
console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
|
|
1724
|
+
}
|
|
1605
1725
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1606
1726
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
1607
1727
|
}
|