@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.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,26 @@ 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
|
+
};
|
|
1090
1182
|
const scriptBase = async (part) => {
|
|
1091
1183
|
Object.assign(story, flattenStory(part));
|
|
1092
1184
|
let loadingIsShown = false;
|
|
@@ -1098,31 +1190,14 @@ var Novely = (() => {
|
|
|
1098
1190
|
if (!loadingIsShown) {
|
|
1099
1191
|
renderer.ui.showLoading();
|
|
1100
1192
|
}
|
|
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);
|
|
1193
|
+
await handleAssetsPreloading();
|
|
1118
1194
|
}
|
|
1119
|
-
ASSETS_TO_PRELOAD.clear();
|
|
1120
1195
|
await dataLoaded.promise;
|
|
1121
1196
|
renderer.ui.hideLoading();
|
|
1122
1197
|
if (!initialScreenWasShown) {
|
|
1123
1198
|
initialScreenWasShown = true;
|
|
1124
1199
|
if (initialScreen === "game") {
|
|
1125
|
-
restore();
|
|
1200
|
+
restore(void 0);
|
|
1126
1201
|
} else {
|
|
1127
1202
|
renderer.ui.showScreen(initialScreen);
|
|
1128
1203
|
}
|
|
@@ -1131,6 +1206,33 @@ var Novely = (() => {
|
|
|
1131
1206
|
const script = (part) => {
|
|
1132
1207
|
return limitScript(() => scriptBase(part));
|
|
1133
1208
|
};
|
|
1209
|
+
const checkAndAddToPreloadingList = (action2, props) => {
|
|
1210
|
+
if (action2 === "showBackground") {
|
|
1211
|
+
if (isImageAsset(props[0])) {
|
|
1212
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1213
|
+
}
|
|
1214
|
+
if (props[0] && typeof props[0] === "object") {
|
|
1215
|
+
for (const value of Object.values(props[0])) {
|
|
1216
|
+
if (!isImageAsset(value))
|
|
1217
|
+
continue;
|
|
1218
|
+
ASSETS_TO_PRELOAD.add(value);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (isAudioAction(action2) && isString(props[0])) {
|
|
1223
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1224
|
+
}
|
|
1225
|
+
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1226
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
1227
|
+
if (Array.isArray(images)) {
|
|
1228
|
+
for (const asset of images) {
|
|
1229
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
1230
|
+
}
|
|
1231
|
+
} else {
|
|
1232
|
+
ASSETS_TO_PRELOAD.add(images);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1134
1236
|
const action = new Proxy({}, {
|
|
1135
1237
|
get(_, action2) {
|
|
1136
1238
|
if (action2 in renderer.actions) {
|
|
@@ -1138,31 +1240,7 @@ var Novely = (() => {
|
|
|
1138
1240
|
}
|
|
1139
1241
|
return (...props) => {
|
|
1140
1242
|
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
|
-
}
|
|
1243
|
+
checkAndAddToPreloadingList(action2, props);
|
|
1166
1244
|
}
|
|
1167
1245
|
return [action2, ...props];
|
|
1168
1246
|
};
|
|
@@ -1289,7 +1367,12 @@ var Novely = (() => {
|
|
|
1289
1367
|
return prev.saves.push(save2), prev;
|
|
1290
1368
|
});
|
|
1291
1369
|
}
|
|
1292
|
-
|
|
1370
|
+
const context = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1371
|
+
const stack = useStack(context);
|
|
1372
|
+
stack.value = save2;
|
|
1373
|
+
context.meta.restoring = context.meta.goingBack = false;
|
|
1374
|
+
renderer.ui.showScreen("game");
|
|
1375
|
+
render(context);
|
|
1293
1376
|
};
|
|
1294
1377
|
const set = (save2, ctx) => {
|
|
1295
1378
|
const stack = useStack(ctx || MAIN_CONTEXT_KEY);
|
|
@@ -1344,8 +1427,8 @@ var Novely = (() => {
|
|
|
1344
1427
|
data: latest[1]
|
|
1345
1428
|
});
|
|
1346
1429
|
}
|
|
1347
|
-
const lastQueueItem = queue.at(-1)
|
|
1348
|
-
const lastQueueItemRequiresUserAction =
|
|
1430
|
+
const lastQueueItem = queue.at(-1);
|
|
1431
|
+
const lastQueueItemRequiresUserAction = lastQueueItem && isBlockingAction(lastQueueItem);
|
|
1349
1432
|
await run((item) => {
|
|
1350
1433
|
if (!latest)
|
|
1351
1434
|
return;
|
|
@@ -1512,6 +1595,40 @@ var Novely = (() => {
|
|
|
1512
1595
|
matchActionOptions.push(ctx);
|
|
1513
1596
|
if (!ctx.meta.preview)
|
|
1514
1597
|
interactivity(true);
|
|
1598
|
+
},
|
|
1599
|
+
onBeforeActionCall({ action: action2, props, ctx }) {
|
|
1600
|
+
if (preloadAssets !== "automatic")
|
|
1601
|
+
return;
|
|
1602
|
+
if (ctx.meta.preview || ctx.meta.restoring)
|
|
1603
|
+
return;
|
|
1604
|
+
if (!isBlockingAction([action2, ...props]))
|
|
1605
|
+
return;
|
|
1606
|
+
try {
|
|
1607
|
+
const collection = collectActionsBeforeBlockingAction({
|
|
1608
|
+
path: nextPath(klona(useStack(ctx).value[0])),
|
|
1609
|
+
refer
|
|
1610
|
+
});
|
|
1611
|
+
for (const [action3, ...props2] of collection) {
|
|
1612
|
+
checkAndAddToPreloadingList(action3, props2);
|
|
1613
|
+
}
|
|
1614
|
+
const { preloadAudioBlocking, preloadImage } = renderer.misc;
|
|
1615
|
+
ASSETS_TO_PRELOAD.forEach(async (asset) => {
|
|
1616
|
+
ASSETS_TO_PRELOAD.delete(asset);
|
|
1617
|
+
const type = await getResourseType(request, asset);
|
|
1618
|
+
switch (type) {
|
|
1619
|
+
case "audio": {
|
|
1620
|
+
preloadAudioBlocking(asset);
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1623
|
+
case "image": {
|
|
1624
|
+
preloadImage(asset);
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
} catch (cause) {
|
|
1630
|
+
console.error(cause);
|
|
1631
|
+
}
|
|
1515
1632
|
}
|
|
1516
1633
|
};
|
|
1517
1634
|
const match = matchAction(matchActionOptions, {
|
|
@@ -1793,6 +1910,9 @@ var Novely = (() => {
|
|
|
1793
1910
|
render(ctx);
|
|
1794
1911
|
},
|
|
1795
1912
|
preload({ ctx, push }, [source]) {
|
|
1913
|
+
if (DEV && preloadAssets !== "lazy") {
|
|
1914
|
+
console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
|
|
1915
|
+
}
|
|
1796
1916
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1797
1917
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
1798
1918
|
}
|