@novely/core 0.35.0 → 0.36.0-beta.1
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 +178 -53
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +178 -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,31 @@ 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
|
+
};
|
|
991
|
+
const assetsToPreloadAdd = (asset) => {
|
|
992
|
+
if (!PRELOADED_ASSETS.has(asset)) {
|
|
993
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
994
|
+
}
|
|
995
|
+
};
|
|
899
996
|
const scriptBase = async (part) => {
|
|
900
997
|
Object.assign(story, flattenStory(part));
|
|
901
998
|
let loadingIsShown = false;
|
|
@@ -907,31 +1004,14 @@ var novely = ({
|
|
|
907
1004
|
if (!loadingIsShown) {
|
|
908
1005
|
renderer.ui.showLoading();
|
|
909
1006
|
}
|
|
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);
|
|
1007
|
+
await handleAssetsPreloading();
|
|
927
1008
|
}
|
|
928
|
-
ASSETS_TO_PRELOAD.clear();
|
|
929
1009
|
await dataLoaded.promise;
|
|
930
1010
|
renderer.ui.hideLoading();
|
|
931
1011
|
if (!initialScreenWasShown) {
|
|
932
1012
|
initialScreenWasShown = true;
|
|
933
1013
|
if (initialScreen === "game") {
|
|
934
|
-
restore();
|
|
1014
|
+
restore(void 0);
|
|
935
1015
|
} else {
|
|
936
1016
|
renderer.ui.showScreen(initialScreen);
|
|
937
1017
|
}
|
|
@@ -940,6 +1020,33 @@ var novely = ({
|
|
|
940
1020
|
const script = (part) => {
|
|
941
1021
|
return limitScript(() => scriptBase(part));
|
|
942
1022
|
};
|
|
1023
|
+
const checkAndAddToPreloadingList = (action2, props) => {
|
|
1024
|
+
if (action2 === "showBackground") {
|
|
1025
|
+
if (isImageAsset(props[0])) {
|
|
1026
|
+
assetsToPreloadAdd(props[0]);
|
|
1027
|
+
}
|
|
1028
|
+
if (props[0] && typeof props[0] === "object") {
|
|
1029
|
+
for (const value of Object.values(props[0])) {
|
|
1030
|
+
if (!isImageAsset(value))
|
|
1031
|
+
continue;
|
|
1032
|
+
assetsToPreloadAdd(value);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (isAudioAction(action2) && isString(props[0])) {
|
|
1037
|
+
assetsToPreloadAdd(props[0]);
|
|
1038
|
+
}
|
|
1039
|
+
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1040
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
1041
|
+
if (Array.isArray(images)) {
|
|
1042
|
+
for (const asset of images) {
|
|
1043
|
+
assetsToPreloadAdd(asset);
|
|
1044
|
+
}
|
|
1045
|
+
} else {
|
|
1046
|
+
assetsToPreloadAdd(images);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
943
1050
|
const action = new Proxy({}, {
|
|
944
1051
|
get(_, action2) {
|
|
945
1052
|
if (action2 in renderer.actions) {
|
|
@@ -947,31 +1054,7 @@ var novely = ({
|
|
|
947
1054
|
}
|
|
948
1055
|
return (...props) => {
|
|
949
1056
|
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
|
-
}
|
|
1057
|
+
checkAndAddToPreloadingList(action2, props);
|
|
975
1058
|
}
|
|
976
1059
|
return [action2, ...props];
|
|
977
1060
|
};
|
|
@@ -1098,7 +1181,12 @@ var novely = ({
|
|
|
1098
1181
|
return prev.saves.push(save2), prev;
|
|
1099
1182
|
});
|
|
1100
1183
|
}
|
|
1101
|
-
|
|
1184
|
+
const context = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1185
|
+
const stack = useStack(context);
|
|
1186
|
+
stack.value = save2;
|
|
1187
|
+
context.meta.restoring = context.meta.goingBack = false;
|
|
1188
|
+
renderer.ui.showScreen("game");
|
|
1189
|
+
render(context);
|
|
1102
1190
|
};
|
|
1103
1191
|
const set = (save2, ctx) => {
|
|
1104
1192
|
const stack = useStack(ctx || MAIN_CONTEXT_KEY);
|
|
@@ -1153,8 +1241,8 @@ var novely = ({
|
|
|
1153
1241
|
data: latest[1]
|
|
1154
1242
|
});
|
|
1155
1243
|
}
|
|
1156
|
-
const lastQueueItem = queue.at(-1)
|
|
1157
|
-
const lastQueueItemRequiresUserAction =
|
|
1244
|
+
const lastQueueItem = queue.at(-1);
|
|
1245
|
+
const lastQueueItemRequiresUserAction = lastQueueItem && isBlockingAction(lastQueueItem);
|
|
1158
1246
|
await run((item) => {
|
|
1159
1247
|
if (!latest)
|
|
1160
1248
|
return;
|
|
@@ -1321,6 +1409,40 @@ var novely = ({
|
|
|
1321
1409
|
matchActionOptions.push(ctx);
|
|
1322
1410
|
if (!ctx.meta.preview)
|
|
1323
1411
|
interactivity(true);
|
|
1412
|
+
},
|
|
1413
|
+
onBeforeActionCall({ action: action2, props, ctx }) {
|
|
1414
|
+
if (preloadAssets !== "automatic")
|
|
1415
|
+
return;
|
|
1416
|
+
if (ctx.meta.preview || ctx.meta.restoring)
|
|
1417
|
+
return;
|
|
1418
|
+
if (!isBlockingAction([action2, ...props]))
|
|
1419
|
+
return;
|
|
1420
|
+
try {
|
|
1421
|
+
const collection = collectActionsBeforeBlockingAction({
|
|
1422
|
+
path: nextPath(klona(useStack(ctx).value[0])),
|
|
1423
|
+
refer
|
|
1424
|
+
});
|
|
1425
|
+
for (const [action3, ...props2] of collection) {
|
|
1426
|
+
checkAndAddToPreloadingList(action3, props2);
|
|
1427
|
+
}
|
|
1428
|
+
const { preloadAudioBlocking, preloadImage } = renderer.misc;
|
|
1429
|
+
ASSETS_TO_PRELOAD.forEach(async (asset) => {
|
|
1430
|
+
ASSETS_TO_PRELOAD.delete(asset);
|
|
1431
|
+
const type = await getResourseType(request, asset);
|
|
1432
|
+
switch (type) {
|
|
1433
|
+
case "audio": {
|
|
1434
|
+
preloadAudioBlocking(asset);
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1437
|
+
case "image": {
|
|
1438
|
+
preloadImage(asset);
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
} catch (cause) {
|
|
1444
|
+
console.error(cause);
|
|
1445
|
+
}
|
|
1324
1446
|
}
|
|
1325
1447
|
};
|
|
1326
1448
|
const match = matchAction(matchActionOptions, {
|
|
@@ -1602,6 +1724,9 @@ var novely = ({
|
|
|
1602
1724
|
render(ctx);
|
|
1603
1725
|
},
|
|
1604
1726
|
preload({ ctx, push }, [source]) {
|
|
1727
|
+
if (DEV2 && preloadAssets !== "lazy") {
|
|
1728
|
+
console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
|
|
1729
|
+
}
|
|
1605
1730
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1606
1731
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
1607
1732
|
}
|