@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.d.ts
CHANGED
package/dist/index.global.js
CHANGED
|
@@ -245,9 +245,16 @@ var Novely = (() => {
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
// src/utils.ts
|
|
248
|
-
var matchAction = ({ getContext, push, forward }, values) => {
|
|
248
|
+
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
249
249
|
return (action, props, { ctx, data }) => {
|
|
250
250
|
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
251
|
+
if (action !== "say") {
|
|
252
|
+
onBeforeActionCall({
|
|
253
|
+
action,
|
|
254
|
+
props,
|
|
255
|
+
ctx: context
|
|
256
|
+
});
|
|
257
|
+
}
|
|
251
258
|
return values[action]({
|
|
252
259
|
ctx: context,
|
|
253
260
|
data,
|
|
@@ -412,7 +419,7 @@ var Novely = (() => {
|
|
|
412
419
|
var getActionsFromPath = (story, path, filter) => {
|
|
413
420
|
let current = story;
|
|
414
421
|
let precurrent;
|
|
415
|
-
let
|
|
422
|
+
let ignoreNestedBefore = null;
|
|
416
423
|
let index = 0;
|
|
417
424
|
let skipPreserve = void 0;
|
|
418
425
|
const skip = /* @__PURE__ */ new Set();
|
|
@@ -433,11 +440,11 @@ var Novely = (() => {
|
|
|
433
440
|
if (isNumber(val)) {
|
|
434
441
|
index++;
|
|
435
442
|
let startIndex = 0;
|
|
436
|
-
if (
|
|
437
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index),
|
|
443
|
+
if (ignoreNestedBefore) {
|
|
444
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index), ignoreNestedBefore);
|
|
438
445
|
if (prev) {
|
|
439
446
|
startIndex = prev[1];
|
|
440
|
-
|
|
447
|
+
ignoreNestedBefore = null;
|
|
441
448
|
}
|
|
442
449
|
}
|
|
443
450
|
for (let i = startIndex; i <= val; i++) {
|
|
@@ -472,7 +479,7 @@ var Novely = (() => {
|
|
|
472
479
|
current = story[val];
|
|
473
480
|
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
474
481
|
current = blocks.pop();
|
|
475
|
-
|
|
482
|
+
ignoreNestedBefore = type.slice(0, -5);
|
|
476
483
|
}
|
|
477
484
|
}
|
|
478
485
|
return {
|
|
@@ -656,6 +663,9 @@ var Novely = (() => {
|
|
|
656
663
|
}
|
|
657
664
|
};
|
|
658
665
|
var getResourseType = async (request, url) => {
|
|
666
|
+
if (!isCSSImage(url)) {
|
|
667
|
+
return "other";
|
|
668
|
+
}
|
|
659
669
|
const extension = getUrlFileExtension(url);
|
|
660
670
|
if (HOWLER_SUPPORTED_FILE_FORMATS.has(extension)) {
|
|
661
671
|
return "audio";
|
|
@@ -769,6 +779,68 @@ var Novely = (() => {
|
|
|
769
779
|
}
|
|
770
780
|
return path;
|
|
771
781
|
};
|
|
782
|
+
var isBlockingAction = (action) => {
|
|
783
|
+
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
784
|
+
};
|
|
785
|
+
var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
786
|
+
const collection = [];
|
|
787
|
+
let action = refer(path);
|
|
788
|
+
while (true) {
|
|
789
|
+
if (action == void 0) {
|
|
790
|
+
const { exitImpossible } = exitPath({
|
|
791
|
+
path,
|
|
792
|
+
refer
|
|
793
|
+
});
|
|
794
|
+
if (exitImpossible) {
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (!action) {
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
if (isBlockingAction(action)) {
|
|
802
|
+
const [name, ...props] = action;
|
|
803
|
+
if (name === "choice") {
|
|
804
|
+
const choiceProps = props;
|
|
805
|
+
for (let i = 0; i < choiceProps.length; i++) {
|
|
806
|
+
const branchContent = choiceProps[i];
|
|
807
|
+
if (!Array.isArray(branchContent))
|
|
808
|
+
continue;
|
|
809
|
+
const virtualPath = klona(path);
|
|
810
|
+
virtualPath.push(["choice", i], [null, 0]);
|
|
811
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
812
|
+
path: virtualPath,
|
|
813
|
+
refer
|
|
814
|
+
});
|
|
815
|
+
collection.push(...innerActions);
|
|
816
|
+
}
|
|
817
|
+
} else if (name === "condition") {
|
|
818
|
+
const conditionProps = props;
|
|
819
|
+
const conditions = Object.keys(conditionProps[1]);
|
|
820
|
+
for (const condition of conditions) {
|
|
821
|
+
const virtualPath = klona(path);
|
|
822
|
+
virtualPath.push(["condition", condition], [null, 0]);
|
|
823
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
824
|
+
path: virtualPath,
|
|
825
|
+
refer
|
|
826
|
+
});
|
|
827
|
+
collection.push(...innerActions);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
collection.push(action);
|
|
833
|
+
if (action[0] === "jump") {
|
|
834
|
+
path = [["jump", action[1]], [null, 0]];
|
|
835
|
+
} else if (action[0] == "block") {
|
|
836
|
+
path.push(["block", action[1]], [null, 0]);
|
|
837
|
+
} else {
|
|
838
|
+
nextPath(path);
|
|
839
|
+
}
|
|
840
|
+
action = refer(path);
|
|
841
|
+
}
|
|
842
|
+
return collection;
|
|
843
|
+
};
|
|
772
844
|
|
|
773
845
|
// ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
774
846
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -1087,6 +1159,31 @@ var Novely = (() => {
|
|
|
1087
1159
|
const intime = (value) => {
|
|
1088
1160
|
return times.add(value), value;
|
|
1089
1161
|
};
|
|
1162
|
+
const handleAssetsPreloading = async () => {
|
|
1163
|
+
const { preloadAudioBlocking, preloadImageBlocking } = renderer.misc;
|
|
1164
|
+
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
1165
|
+
return limitAssetsDownload(async () => {
|
|
1166
|
+
const type = await getResourseType(request, asset);
|
|
1167
|
+
switch (type) {
|
|
1168
|
+
case "audio": {
|
|
1169
|
+
await preloadAudioBlocking(asset);
|
|
1170
|
+
break;
|
|
1171
|
+
}
|
|
1172
|
+
case "image": {
|
|
1173
|
+
await preloadImageBlocking(asset);
|
|
1174
|
+
break;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
});
|
|
1179
|
+
await Promise.allSettled(list);
|
|
1180
|
+
ASSETS_TO_PRELOAD.clear();
|
|
1181
|
+
};
|
|
1182
|
+
const assetsToPreloadAdd = (asset) => {
|
|
1183
|
+
if (!PRELOADED_ASSETS.has(asset)) {
|
|
1184
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1090
1187
|
const scriptBase = async (part) => {
|
|
1091
1188
|
Object.assign(story, flattenStory(part));
|
|
1092
1189
|
let loadingIsShown = false;
|
|
@@ -1098,31 +1195,14 @@ var Novely = (() => {
|
|
|
1098
1195
|
if (!loadingIsShown) {
|
|
1099
1196
|
renderer.ui.showLoading();
|
|
1100
1197
|
}
|
|
1101
|
-
|
|
1102
|
-
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
1103
|
-
return limitAssetsDownload(async () => {
|
|
1104
|
-
const type = await getResourseType(request, asset);
|
|
1105
|
-
switch (type) {
|
|
1106
|
-
case "audio": {
|
|
1107
|
-
await preloadAudioBlocking(asset);
|
|
1108
|
-
break;
|
|
1109
|
-
}
|
|
1110
|
-
case "image": {
|
|
1111
|
-
await preloadImageBlocking(asset);
|
|
1112
|
-
break;
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
});
|
|
1116
|
-
});
|
|
1117
|
-
await Promise.allSettled(list);
|
|
1198
|
+
await handleAssetsPreloading();
|
|
1118
1199
|
}
|
|
1119
|
-
ASSETS_TO_PRELOAD.clear();
|
|
1120
1200
|
await dataLoaded.promise;
|
|
1121
1201
|
renderer.ui.hideLoading();
|
|
1122
1202
|
if (!initialScreenWasShown) {
|
|
1123
1203
|
initialScreenWasShown = true;
|
|
1124
1204
|
if (initialScreen === "game") {
|
|
1125
|
-
restore();
|
|
1205
|
+
restore(void 0);
|
|
1126
1206
|
} else {
|
|
1127
1207
|
renderer.ui.showScreen(initialScreen);
|
|
1128
1208
|
}
|
|
@@ -1131,6 +1211,33 @@ var Novely = (() => {
|
|
|
1131
1211
|
const script = (part) => {
|
|
1132
1212
|
return limitScript(() => scriptBase(part));
|
|
1133
1213
|
};
|
|
1214
|
+
const checkAndAddToPreloadingList = (action2, props) => {
|
|
1215
|
+
if (action2 === "showBackground") {
|
|
1216
|
+
if (isImageAsset(props[0])) {
|
|
1217
|
+
assetsToPreloadAdd(props[0]);
|
|
1218
|
+
}
|
|
1219
|
+
if (props[0] && typeof props[0] === "object") {
|
|
1220
|
+
for (const value of Object.values(props[0])) {
|
|
1221
|
+
if (!isImageAsset(value))
|
|
1222
|
+
continue;
|
|
1223
|
+
assetsToPreloadAdd(value);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
if (isAudioAction(action2) && isString(props[0])) {
|
|
1228
|
+
assetsToPreloadAdd(props[0]);
|
|
1229
|
+
}
|
|
1230
|
+
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1231
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
1232
|
+
if (Array.isArray(images)) {
|
|
1233
|
+
for (const asset of images) {
|
|
1234
|
+
assetsToPreloadAdd(asset);
|
|
1235
|
+
}
|
|
1236
|
+
} else {
|
|
1237
|
+
assetsToPreloadAdd(images);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1134
1241
|
const action = new Proxy({}, {
|
|
1135
1242
|
get(_, action2) {
|
|
1136
1243
|
if (action2 in renderer.actions) {
|
|
@@ -1138,31 +1245,7 @@ var Novely = (() => {
|
|
|
1138
1245
|
}
|
|
1139
1246
|
return (...props) => {
|
|
1140
1247
|
if (preloadAssets === "blocking") {
|
|
1141
|
-
|
|
1142
|
-
if (isImageAsset(props[0])) {
|
|
1143
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1144
|
-
}
|
|
1145
|
-
if (props[0] && typeof props[0] === "object") {
|
|
1146
|
-
for (const value of Object.values(props[0])) {
|
|
1147
|
-
if (!isImageAsset(value))
|
|
1148
|
-
continue;
|
|
1149
|
-
ASSETS_TO_PRELOAD.add(value);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
if (isAudioAction(action2) && isString(props[0])) {
|
|
1154
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1155
|
-
}
|
|
1156
|
-
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1157
|
-
const images = characters[props[0]].emotions[props[1]];
|
|
1158
|
-
if (Array.isArray(images)) {
|
|
1159
|
-
for (const asset of images) {
|
|
1160
|
-
ASSETS_TO_PRELOAD.add(asset);
|
|
1161
|
-
}
|
|
1162
|
-
} else {
|
|
1163
|
-
ASSETS_TO_PRELOAD.add(images);
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1248
|
+
checkAndAddToPreloadingList(action2, props);
|
|
1166
1249
|
}
|
|
1167
1250
|
return [action2, ...props];
|
|
1168
1251
|
};
|
|
@@ -1289,7 +1372,12 @@ var Novely = (() => {
|
|
|
1289
1372
|
return prev.saves.push(save2), prev;
|
|
1290
1373
|
});
|
|
1291
1374
|
}
|
|
1292
|
-
|
|
1375
|
+
const context = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1376
|
+
const stack = useStack(context);
|
|
1377
|
+
stack.value = save2;
|
|
1378
|
+
context.meta.restoring = context.meta.goingBack = false;
|
|
1379
|
+
renderer.ui.showScreen("game");
|
|
1380
|
+
render(context);
|
|
1293
1381
|
};
|
|
1294
1382
|
const set = (save2, ctx) => {
|
|
1295
1383
|
const stack = useStack(ctx || MAIN_CONTEXT_KEY);
|
|
@@ -1344,8 +1432,8 @@ var Novely = (() => {
|
|
|
1344
1432
|
data: latest[1]
|
|
1345
1433
|
});
|
|
1346
1434
|
}
|
|
1347
|
-
const lastQueueItem = queue.at(-1)
|
|
1348
|
-
const lastQueueItemRequiresUserAction =
|
|
1435
|
+
const lastQueueItem = queue.at(-1);
|
|
1436
|
+
const lastQueueItemRequiresUserAction = lastQueueItem && isBlockingAction(lastQueueItem);
|
|
1349
1437
|
await run((item) => {
|
|
1350
1438
|
if (!latest)
|
|
1351
1439
|
return;
|
|
@@ -1512,6 +1600,40 @@ var Novely = (() => {
|
|
|
1512
1600
|
matchActionOptions.push(ctx);
|
|
1513
1601
|
if (!ctx.meta.preview)
|
|
1514
1602
|
interactivity(true);
|
|
1603
|
+
},
|
|
1604
|
+
onBeforeActionCall({ action: action2, props, ctx }) {
|
|
1605
|
+
if (preloadAssets !== "automatic")
|
|
1606
|
+
return;
|
|
1607
|
+
if (ctx.meta.preview || ctx.meta.restoring)
|
|
1608
|
+
return;
|
|
1609
|
+
if (!isBlockingAction([action2, ...props]))
|
|
1610
|
+
return;
|
|
1611
|
+
try {
|
|
1612
|
+
const collection = collectActionsBeforeBlockingAction({
|
|
1613
|
+
path: nextPath(klona(useStack(ctx).value[0])),
|
|
1614
|
+
refer
|
|
1615
|
+
});
|
|
1616
|
+
for (const [action3, ...props2] of collection) {
|
|
1617
|
+
checkAndAddToPreloadingList(action3, props2);
|
|
1618
|
+
}
|
|
1619
|
+
const { preloadAudioBlocking, preloadImage } = renderer.misc;
|
|
1620
|
+
ASSETS_TO_PRELOAD.forEach(async (asset) => {
|
|
1621
|
+
ASSETS_TO_PRELOAD.delete(asset);
|
|
1622
|
+
const type = await getResourseType(request, asset);
|
|
1623
|
+
switch (type) {
|
|
1624
|
+
case "audio": {
|
|
1625
|
+
preloadAudioBlocking(asset);
|
|
1626
|
+
break;
|
|
1627
|
+
}
|
|
1628
|
+
case "image": {
|
|
1629
|
+
preloadImage(asset);
|
|
1630
|
+
break;
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
} catch (cause) {
|
|
1635
|
+
console.error(cause);
|
|
1636
|
+
}
|
|
1515
1637
|
}
|
|
1516
1638
|
};
|
|
1517
1639
|
const match = matchAction(matchActionOptions, {
|
|
@@ -1793,6 +1915,9 @@ var Novely = (() => {
|
|
|
1793
1915
|
render(ctx);
|
|
1794
1916
|
},
|
|
1795
1917
|
preload({ ctx, push }, [source]) {
|
|
1918
|
+
if (DEV && preloadAssets !== "lazy") {
|
|
1919
|
+
console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
|
|
1920
|
+
}
|
|
1796
1921
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1797
1922
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
1798
1923
|
}
|