@novely/core 0.47.2 → 0.48.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 CHANGED
@@ -544,6 +544,10 @@ interface NovelyInit<$Language extends Lang, $Characters extends Record<string,
544
544
  * ```
545
545
  */
546
546
  startKey?: 'start' | (string & Record<never, never>);
547
+ /**
548
+ * Typewriter speed set by default
549
+ */
550
+ defaultTypewriterSpeed?: TypewriterSpeed;
547
551
  }
548
552
  type StateFunction<S extends State> = {
549
553
  (value: DeepPartial<S> | ((prev: S) => S)): void;
@@ -672,9 +676,9 @@ type CustomHandlerCalling = {
672
676
  callOnlyLatest?: boolean;
673
677
  /**
674
678
  * Manually check should be skipped or not during restore
675
- * @param getNext Function which will return next actions in queue
679
+ * @param nextActions Next actions in the restoring queue
676
680
  */
677
- skipOnRestore?: (getNext: () => Exclude<ValidAction, ValidAction[]>[]) => boolean;
681
+ skipOnRestore?: (nextActions: Exclude<ValidAction, ValidAction[]>[]) => boolean;
678
682
  };
679
683
  type CustomHandlerInfo = CustomHandlerCalling & {
680
684
  /**
@@ -854,7 +858,7 @@ type ChoiceParams<T> = T extends TypeEssentials<infer $Lang, infer $State, any,
854
858
  type FunctionParams<T> = T extends TypeEssentials<infer $Lang, infer $State, any, any> ? FunctionActionProps<$Lang, $State> : never;
855
859
  type InputHandler<T> = T extends TypeEssentials<infer $Lang, infer $State, any, any> ? ActionInputOnInputMeta<$Lang, $State> : never;
856
860
 
857
- declare const novely: <$Language extends string, $Characters extends Record<string, Character<$Language>>, $State extends State, $Data extends Data, $Actions extends Record<string, (...args: any[]) => ValidAction>>({ characters, characterAssetSizes, defaultEmotions, storage, storageDelay, renderer: createRenderer, initialScreen, translation, state: defaultState, data: defaultData, autosaves, migrations, throttleTimeout, getLanguage, overrideLanguage, askBeforeExit, preloadAssets, parallelAssetsDownloadLimit, fetch: request, cloneFunction: clone, saveOnUnload, startKey, }: NovelyInit<$Language, $Characters, $State, $Data, $Actions>) => {
861
+ declare const novely: <$Language extends string, $Characters extends Record<string, Character<$Language>>, $State extends State, $Data extends Data, $Actions extends Record<string, (...args: any[]) => ValidAction>>({ characters, characterAssetSizes, defaultEmotions, storage, storageDelay, renderer: createRenderer, initialScreen, translation, state: defaultState, data: defaultData, autosaves, migrations, throttleTimeout, getLanguage, overrideLanguage, askBeforeExit, preloadAssets, parallelAssetsDownloadLimit, fetch: request, cloneFunction: clone, saveOnUnload, startKey, defaultTypewriterSpeed, }: NovelyInit<$Language, $Characters, $State, $Data, $Actions>) => {
858
862
  /**
859
863
  * Function to set game script
860
864
  *
@@ -882,7 +886,8 @@ declare const novely: <$Language extends string, $Characters extends Record<stri
882
886
  */
883
887
  action: $Actions & ActionProxy<$Characters, $Language, $State> & VirtualActions<$Characters, $Language, $State>;
884
888
  /**
885
- * @deprecated Will be removed BUT replaced with state passed into actions as a parameter
889
+ * State bound to `$MAIN` game context
890
+ * @deprecated Use `state` function provided from action arguments
886
891
  */
887
892
  state: StateFunction<State>;
888
893
  /**
@@ -965,6 +970,7 @@ declare const novely: <$Language extends string, $Characters extends Record<stri
965
970
  setStorageData: (data: StorageData<$Language, $Data>) => void;
966
971
  };
967
972
 
973
+ type Part = Record<string, (...args: any[]) => ValidAction>;
968
974
  /**
969
975
  * Extens core action with custom actions
970
976
  * @param base Actions object you will extend, `engine.action`
@@ -978,7 +984,7 @@ declare const novely: <$Language extends string, $Characters extends Record<stri
978
984
  * })
979
985
  * ```
980
986
  */
981
- declare const extendAction: <Part0 extends Record<string, (...args: any[]) => ValidAction>, Part1 extends Record<string, (...args: any[]) => ValidAction>>(base: Part0, extension: Part1) => Readonly<Assign<Part0, Part1>>;
987
+ declare const extendAction: <Part0 extends Part, Part1 extends Part>(base: Part0, extension: Part1) => Readonly<Assign<Part0, Part1>>;
982
988
 
983
989
  /**
984
990
  * Memoizes and returns an asset selection object based on provided file variants.
@@ -494,7 +494,7 @@ var Novely = (() => {
494
494
  // src/utilities/match-action.ts
495
495
  var matchAction = (callbacks, values) => {
496
496
  const { getContext, onBeforeActionCall, push, forward } = callbacks;
497
- return (action, props, { ctx, data }) => {
497
+ const match = (action, props, { ctx, data }) => {
498
498
  const context = typeof ctx === "string" ? getContext(ctx) : ctx;
499
499
  onBeforeActionCall({
500
500
  action,
@@ -517,6 +517,10 @@ var Novely = (() => {
517
517
  props
518
518
  );
519
519
  };
520
+ return {
521
+ match,
522
+ nativeActions: Object.keys(values)
523
+ };
520
524
  };
521
525
 
522
526
  // src/utilities/ungrupped.ts
@@ -847,17 +851,16 @@ var Novely = (() => {
847
851
  if (action === "custom") {
848
852
  const fn = params[0];
849
853
  if ("callOnlyLatest" in fn && fn.callOnlyLatest) {
850
- const notLatest = next(i).some(([, func]) => {
851
- if (!isFunction(func)) return false;
852
- const c0 = func;
853
- const c1 = fn;
854
- const isIdenticalID = Boolean(c0.id && c1.id && c0.id === c1.id);
855
- const isIdenticalByReference = c0 === c1;
856
- return isIdenticalID || isIdenticalByReference || String(c0) === String(c1);
854
+ const notLatest = next(i).some(([name, func]) => {
855
+ if (name !== "custom") return;
856
+ const isIdenticalId = Boolean(func.id && fn.id && func.id === fn.id);
857
+ const isIdenticalByReference = func === fn;
858
+ const isIdenticalByCode = String(func) === String(fn);
859
+ return isIdenticalId || isIdenticalByReference || isIdenticalByCode;
857
860
  });
858
861
  if (notLatest) continue;
859
862
  } else if ("skipOnRestore" in fn && fn.skipOnRestore) {
860
- if (fn.skipOnRestore(() => next(i))) {
863
+ if (fn.skipOnRestore(next(i))) {
861
864
  continue;
862
865
  }
863
866
  }
@@ -906,7 +909,8 @@ var Novely = (() => {
906
909
  const next2 = array.slice(j);
907
910
  const characterWillAnimate = next2.some(([__action, __character]) => action === __action);
908
911
  const hasBlockingActions = next2.some((item2) => options.skip.has(item2));
909
- return characterWillAnimate && hasBlockingActions;
912
+ const differentCharacterWillAnimate = !hasBlockingActions && next2.some(([__action, __character]) => __action === action && __character !== params[0]);
913
+ return characterWillAnimate && hasBlockingActions || differentCharacterWillAnimate;
910
914
  });
911
915
  if (skip) continue;
912
916
  processedQueue.push(item);
@@ -1365,6 +1369,69 @@ var Novely = (() => {
1365
1369
  });
1366
1370
  };
1367
1371
 
1372
+ // src/utilities/actions.ts
1373
+ var VIRTUAL_ACTIONS = ["say"];
1374
+ var buildActionObject = ({
1375
+ rendererActions,
1376
+ nativeActions,
1377
+ characters,
1378
+ preloadAssets,
1379
+ storageData
1380
+ }) => {
1381
+ const allActions = [...nativeActions, ...VIRTUAL_ACTIONS];
1382
+ const object = { ...rendererActions };
1383
+ for (let action of allActions) {
1384
+ object[action] = (...props) => {
1385
+ if (action === "say") {
1386
+ action = "dialog";
1387
+ const [character] = props;
1388
+ if (DEV && !characters[character]) {
1389
+ throw new Error(`Attempt to call Say action with unknown character "${character}"`);
1390
+ }
1391
+ } else if (action === "choice") {
1392
+ if (props.slice(1).every((choice) => !Array.isArray(choice))) {
1393
+ for (let i = 1; i < props.length; i++) {
1394
+ const choice = props[i];
1395
+ props[i] = [
1396
+ choice.title,
1397
+ flatActions(choice.children),
1398
+ choice.active,
1399
+ choice.visible,
1400
+ choice.onSelect,
1401
+ choice.image
1402
+ ];
1403
+ }
1404
+ } else {
1405
+ for (let i = 1; i < props.length; i++) {
1406
+ const choice = props[i];
1407
+ if (Array.isArray(choice)) {
1408
+ choice[1] = flatActions(choice[1]);
1409
+ }
1410
+ }
1411
+ }
1412
+ } else if (action === "condition") {
1413
+ const actions = props[1];
1414
+ for (const key in actions) {
1415
+ actions[key] = flatActions(actions[key]);
1416
+ }
1417
+ }
1418
+ if (preloadAssets === "blocking") {
1419
+ huntAssets({
1420
+ action,
1421
+ props,
1422
+ mode: preloadAssets,
1423
+ characters,
1424
+ lang: getLanguageFromStore(storageData),
1425
+ volume: getVolumeFromStore(storageData),
1426
+ handle: enqueueAssetForPreloading
1427
+ });
1428
+ }
1429
+ return [action, ...props];
1430
+ };
1431
+ }
1432
+ return object;
1433
+ };
1434
+
1368
1435
  // src/novely.ts
1369
1436
  var novely = ({
1370
1437
  characters,
@@ -1388,7 +1455,8 @@ var Novely = (() => {
1388
1455
  fetch: request = fetch,
1389
1456
  cloneFunction: clone = klona,
1390
1457
  saveOnUnload = true,
1391
- startKey = "start"
1458
+ startKey = "start",
1459
+ defaultTypewriterSpeed = DEFAULT_TYPEWRITER_SPEED
1392
1460
  }) => {
1393
1461
  const languages = Object.keys(translation);
1394
1462
  const limitScript = pLimit(1);
@@ -1433,61 +1501,6 @@ var Novely = (() => {
1433
1501
  const script = (part) => {
1434
1502
  return limitScript(() => scriptBase(part));
1435
1503
  };
1436
- const action = new Proxy({}, {
1437
- get(_, action2) {
1438
- if (action2 in renderer.actions) {
1439
- return renderer.actions[action2];
1440
- }
1441
- return (...props) => {
1442
- if (action2 === "say") {
1443
- action2 = "dialog";
1444
- const [character] = props;
1445
- if (DEV && !characters[character]) {
1446
- throw new Error(`Attempt to call Say action with unknown character "${character}"`);
1447
- }
1448
- } else if (action2 === "choice") {
1449
- const actions = props.slice(1);
1450
- if (actions.every((choice) => !Array.isArray(choice))) {
1451
- for (let i = 1; i < props.length; i++) {
1452
- const choice = props[i];
1453
- props[i] = [
1454
- choice.title,
1455
- flatActions(choice.children),
1456
- choice.active,
1457
- choice.visible,
1458
- choice.onSelect,
1459
- choice.image
1460
- ];
1461
- }
1462
- } else {
1463
- for (let i = 1; i < props.length; i++) {
1464
- const choice = props[i];
1465
- if (Array.isArray(choice)) {
1466
- choice[1] = flatActions(choice[1]);
1467
- }
1468
- }
1469
- }
1470
- } else if (action2 === "condition") {
1471
- const actions = props[1];
1472
- for (const key in actions) {
1473
- actions[key] = flatActions(actions[key]);
1474
- }
1475
- }
1476
- if (preloadAssets === "blocking") {
1477
- huntAssets({
1478
- action: action2,
1479
- props,
1480
- mode: preloadAssets,
1481
- characters,
1482
- lang: getLanguageFromStore(storageData),
1483
- volume: getVolumeFromStore(storageData),
1484
- handle: enqueueAssetForPreloading
1485
- });
1486
- }
1487
- return [action2, ...props];
1488
- };
1489
- }
1490
- });
1491
1504
  const getDefaultSave = (state) => {
1492
1505
  return [
1493
1506
  [
@@ -1557,7 +1570,7 @@ var Novely = (() => {
1557
1570
  if (overrideLanguage || !stored.meta[0]) {
1558
1571
  stored.meta[0] = getLanguageWithoutParameters();
1559
1572
  }
1560
- stored.meta[1] ||= DEFAULT_TYPEWRITER_SPEED;
1573
+ stored.meta[1] ||= defaultTypewriterSpeed;
1561
1574
  stored.meta[2] ??= 1;
1562
1575
  stored.meta[3] ??= 1;
1563
1576
  stored.meta[4] ??= 1;
@@ -1965,7 +1978,7 @@ var Novely = (() => {
1965
1978
  }
1966
1979
  }
1967
1980
  };
1968
- const match = matchAction(matchActionOptions, {
1981
+ const { match, nativeActions } = matchAction(matchActionOptions, {
1969
1982
  wait({ ctx, data: data2, push }, [time]) {
1970
1983
  if (ctx.meta.restoring) return;
1971
1984
  setTimeout(push, isFunction(time) ? time(data2) : time);
@@ -2263,6 +2276,13 @@ var Novely = (() => {
2263
2276
  }
2264
2277
  }
2265
2278
  });
2279
+ const action = buildActionObject({
2280
+ rendererActions: renderer.actions,
2281
+ nativeActions,
2282
+ characters,
2283
+ preloadAssets,
2284
+ storageData
2285
+ });
2266
2286
  const render = (ctx) => {
2267
2287
  const stack = useStack(ctx);
2268
2288
  const [path, state] = stack.value;
@@ -2357,7 +2377,8 @@ var Novely = (() => {
2357
2377
  */
2358
2378
  action,
2359
2379
  /**
2360
- * @deprecated Will be removed BUT replaced with state passed into actions as a parameter
2380
+ * State bound to `$MAIN` game context
2381
+ * @deprecated Use `state` function provided from action arguments
2361
2382
  */
2362
2383
  state: getStateFunction(MAIN_CONTEXT_KEY),
2363
2384
  /**
@@ -2452,11 +2473,10 @@ var Novely = (() => {
2452
2473
 
2453
2474
  // src/extend-actions.ts
2454
2475
  var extendAction = (base, extension) => {
2455
- return new Proxy({}, {
2456
- get(_, key, receiver) {
2457
- return Reflect.get(key in extension ? extension : base, key, receiver);
2458
- }
2459
- });
2476
+ return {
2477
+ ...extension,
2478
+ ...base
2479
+ };
2460
2480
  };
2461
2481
 
2462
2482
  // src/translations.ts