@novely/core 0.33.3 → 0.35.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 +95 -24
- package/dist/index.global.js +120 -20
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +120 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,20 @@ interface CharacterHandle {
|
|
|
75
75
|
animate: (timeout: number, classes: string[]) => void;
|
|
76
76
|
emotions: Record<string, HTMLImageElement[]>;
|
|
77
77
|
}
|
|
78
|
+
type CustomActionHandle = {
|
|
79
|
+
/**
|
|
80
|
+
* Function to remove custom action from screen (and from your state if any completely)
|
|
81
|
+
*/
|
|
82
|
+
remove: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Function that will give action root (element which you should add to the screen because custom actions rendered into that element)
|
|
85
|
+
*/
|
|
86
|
+
setMountElement: (mountElement: null | HTMLDivElement) => void;
|
|
87
|
+
/**
|
|
88
|
+
* Function that will give you clean function provided by custom action.
|
|
89
|
+
*/
|
|
90
|
+
setClear: (clear: () => void) => void;
|
|
91
|
+
};
|
|
78
92
|
type AudioHandle = {
|
|
79
93
|
stop: () => void;
|
|
80
94
|
pause: () => void;
|
|
@@ -93,8 +107,7 @@ type Context = {
|
|
|
93
107
|
music: Set<string>;
|
|
94
108
|
sounds: Set<string>;
|
|
95
109
|
}, resolve: () => void) => void;
|
|
96
|
-
custom: (fn: CustomHandler<Lang, State
|
|
97
|
-
clearCustom: (fn: CustomHandler<Lang, State>) => void;
|
|
110
|
+
custom: (fn: CustomHandler<Lang, State>) => CustomActionHandle;
|
|
98
111
|
/**
|
|
99
112
|
* Clears all mentioned actions except for preserved one
|
|
100
113
|
* @param preserve Action that should not be cleared
|
|
@@ -213,6 +226,7 @@ type RendererInit<$Language extends Lang, $Characters extends Record<string, Cha
|
|
|
213
226
|
preview: (save: Save<State>, name: string) => Promise<void>;
|
|
214
227
|
removeContext: (name: string) => void;
|
|
215
228
|
getStateFunction: (context: string) => StateFunction<State>;
|
|
229
|
+
clearCustomAction: (ctx: Context, customAction: CustomHandler) => void;
|
|
216
230
|
getLanguageDisplayName: (lang: Lang) => string;
|
|
217
231
|
};
|
|
218
232
|
|
|
@@ -499,46 +513,102 @@ type FunctionableValue<T> = T | (() => T);
|
|
|
499
513
|
type CustomHandlerGetResultDataFunction = (data?: Record<string, unknown>) => Record<string, unknown>;
|
|
500
514
|
type CustomHandlerGetResult<I extends boolean> = {
|
|
501
515
|
/**
|
|
502
|
-
*
|
|
516
|
+
* Element for the custom action to be rendered into
|
|
503
517
|
*/
|
|
504
|
-
|
|
518
|
+
element: I extends true ? HTMLDivElement : null;
|
|
505
519
|
/**
|
|
506
|
-
*
|
|
520
|
+
* Root node
|
|
507
521
|
*/
|
|
508
|
-
|
|
522
|
+
root: HTMLElement;
|
|
523
|
+
};
|
|
524
|
+
type CustomHandlerFunctionGetFn = <I extends boolean = true>(insert?: I) => CustomHandlerGetResult<I>;
|
|
525
|
+
type CustomHandlerFunctionParameters<L extends string, S extends State> = {
|
|
509
526
|
/**
|
|
510
|
-
*
|
|
527
|
+
* Returns:
|
|
528
|
+
* - Root where entire novely is mounted
|
|
529
|
+
* - Element in which custom action could be mounted
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```ts
|
|
533
|
+
* // pass `true` to insert element to the DOM
|
|
534
|
+
* const { root, element } = getDomNodes(true);
|
|
535
|
+
* ```
|
|
511
536
|
*/
|
|
512
|
-
|
|
537
|
+
getDomNodes: CustomHandlerFunctionGetFn;
|
|
513
538
|
/**
|
|
514
|
-
*
|
|
539
|
+
* Renderer Context
|
|
515
540
|
*/
|
|
516
|
-
|
|
541
|
+
rendererContext: Context;
|
|
517
542
|
/**
|
|
518
|
-
*
|
|
543
|
+
* Function to work with custom action's state
|
|
544
|
+
*/
|
|
545
|
+
data: CustomHandlerGetResultDataFunction;
|
|
546
|
+
/**
|
|
547
|
+
* Function to set cleanup handler
|
|
519
548
|
*/
|
|
520
549
|
clear: (fn: () => void) => void;
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
550
|
+
/**
|
|
551
|
+
* Remove's custom handler instance
|
|
552
|
+
*/
|
|
553
|
+
remove: () => void;
|
|
554
|
+
/**
|
|
555
|
+
* Context's state function
|
|
556
|
+
*/
|
|
528
557
|
state: StateFunction<S>;
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
558
|
+
/**
|
|
559
|
+
* Game flags (aka game states)
|
|
560
|
+
*/
|
|
561
|
+
flags: {
|
|
562
|
+
restoring: boolean;
|
|
563
|
+
goingBack: boolean;
|
|
564
|
+
preview: boolean;
|
|
565
|
+
};
|
|
566
|
+
/**
|
|
567
|
+
* Game language
|
|
568
|
+
*/
|
|
532
569
|
lang: L;
|
|
533
570
|
};
|
|
534
571
|
type CustomHandlerFunction<L extends string, S extends State> = (parameters: CustomHandlerFunctionParameters<L, S>) => Thenable<void>;
|
|
535
|
-
type
|
|
572
|
+
type CustomHandlerCalling = {
|
|
573
|
+
/**
|
|
574
|
+
* Call only the last custom action of this type or not. Does not affect other custom actions
|
|
575
|
+
* @example
|
|
576
|
+
* ```ts
|
|
577
|
+
* ['custom', customSomething1]
|
|
578
|
+
* ['custom', customSomething1]
|
|
579
|
+
* ['custom', customSomething1] <-- Run only that
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
536
582
|
callOnlyLatest?: boolean;
|
|
583
|
+
/**
|
|
584
|
+
* Manually check should be skipped or not during restore
|
|
585
|
+
* @param getNext Function which will return next actions in queue
|
|
586
|
+
*/
|
|
587
|
+
skipOnRestore?: (getNext: () => Exclude<ValidAction, ValidAction[]>[]) => boolean;
|
|
588
|
+
};
|
|
589
|
+
type CustomHandlerInfo = CustomHandlerCalling & {
|
|
590
|
+
/**
|
|
591
|
+
* When true interacting with it will be saved in history
|
|
592
|
+
*/
|
|
537
593
|
requireUserAction?: boolean;
|
|
594
|
+
/**
|
|
595
|
+
* When player is going back we clear every custom action. But we can ignore clearing that.
|
|
596
|
+
*/
|
|
538
597
|
skipClearOnGoingBack?: boolean;
|
|
598
|
+
/**
|
|
599
|
+
* Id by which we will determine what action is which
|
|
600
|
+
*
|
|
601
|
+
* It IS recommended to pass this property as it will speed up that check and make it more reliable
|
|
602
|
+
*/
|
|
539
603
|
id?: string | symbol;
|
|
604
|
+
/**
|
|
605
|
+
* Key by which we will save the data in the `get` function provided to custom action.
|
|
606
|
+
*
|
|
607
|
+
* It can be a name of action or more specific thing. In example for custom `showCharacter` it may be `show-character-${character}
|
|
608
|
+
*/
|
|
540
609
|
key: string;
|
|
541
610
|
};
|
|
611
|
+
type CustomHandler<L extends string = string, S extends State = State> = CustomHandlerFunction<L, S> & CustomHandlerInfo;
|
|
542
612
|
interface ActionInputOnInputMeta<L extends string, S extends State> {
|
|
543
613
|
/**
|
|
544
614
|
* Input Element itself
|
|
@@ -594,7 +664,8 @@ type ChoiceCheckFunctionProps<L extends string, S extends State> = {
|
|
|
594
664
|
type ChoiceCheckFunction<L extends string, S extends State> = (props: ChoiceCheckFunctionProps<L, S>) => boolean;
|
|
595
665
|
type ConditionCheckFunction<S extends State, R extends string | true | false> = (state: S) => R;
|
|
596
666
|
type FunctionAction<L extends string, S extends State> = (props: FunctionActionProps<L, S>) => Thenable<void>;
|
|
597
|
-
type
|
|
667
|
+
type ActionInputSetupCleanup = () => void;
|
|
668
|
+
type ActionInputSetup = (input: HTMLInputElement) => ActionInputSetupCleanup | void;
|
|
598
669
|
type BackgroundImage = Partial<Record<'portrait' | 'landscape' | 'all', string>> & Record<string, string>;
|
|
599
670
|
type VoiceAction<L extends Lang> = (params: string | Partial<Record<L, string>>) => ValidAction;
|
|
600
671
|
type ActionProxy<Characters extends Record<string, Character>, Languages extends Lang, S extends State> = {
|
|
@@ -765,4 +836,4 @@ declare const novely: <$Language extends string, $Characters extends Record<stri
|
|
|
765
836
|
*/
|
|
766
837
|
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>>;
|
|
767
838
|
|
|
768
|
-
export { type ActionInputOnInputMeta, type ActionInputSetup, type ActionProxy, type AllowedContent, type AudioHandle, type BackgroundImage, type BaseTranslationStrings, type Character, type CharacterHandle, type ConditionParams, type Context, type CoreData, type CustomHandler, type CustomHandlerFunctionGetFn, type CustomHandlerFunctionParameters, type CustomHandlerGetResult, type CustomHandlerGetResultDataFunction, type Data, type DeepPartial, type DefaultActionProxy, EN, type Emotions, type FunctionableValue, type GetActionParameters, type InputHandler, JP, KK, type Lang, type NovelyInit, type NovelyScreen, type Path, type PluralType, type Pluralization, RU, type Renderer, type RendererInit, type Save, type Stack, type StackHolder, type State, type StateFunction, type Storage, type StorageData, type StorageMeta, type Stored, type Story, type TextContent, type Thenable, type TranslationActions, type TypeEssentials, type TypewriterSpeed, type ValidAction, extendAction, localStorageStorage, novely };
|
|
839
|
+
export { type ActionInputOnInputMeta, type ActionInputSetup, type ActionInputSetupCleanup, type ActionProxy, type AllowedContent, type AudioHandle, type BackgroundImage, type BaseTranslationStrings, type Character, type CharacterHandle, type ConditionParams, type Context, type CoreData, type CustomActionHandle, type CustomHandler, type CustomHandlerFunctionGetFn, type CustomHandlerFunctionParameters, type CustomHandlerGetResult, type CustomHandlerGetResultDataFunction, type Data, type DeepPartial, type DefaultActionProxy, EN, type Emotions, type FunctionableValue, type GetActionParameters, type InputHandler, JP, KK, type Lang, type NovelyInit, type NovelyScreen, type Path, type PluralType, type Pluralization, RU, type Renderer, type RendererInit, type Save, type Stack, type StackHolder, type State, type StateFunction, type Storage, type StorageData, type StorageMeta, type Stored, type Story, type TextContent, type Thenable, type TranslationActions, type TypeEssentials, type TypewriterSpeed, type ValidAction, extendAction, localStorageStorage, novely };
|
package/dist/index.global.js
CHANGED
|
@@ -210,6 +210,7 @@ var Novely = (() => {
|
|
|
210
210
|
|
|
211
211
|
// src/shared.ts
|
|
212
212
|
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
213
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
213
214
|
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
214
215
|
|
|
215
216
|
// ../../node_modules/.pnpm/esm-env@1.0.0/node_modules/esm-env/prod-ssr.js
|
|
@@ -496,18 +497,31 @@ var Novely = (() => {
|
|
|
496
497
|
}
|
|
497
498
|
keep.add(action);
|
|
498
499
|
if (action === "function" || action === "custom") {
|
|
499
|
-
if (action === "custom"
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
500
|
+
if (action === "custom") {
|
|
501
|
+
const fn = params[0];
|
|
502
|
+
if ("callOnlyLatest" in fn && fn.callOnlyLatest) {
|
|
503
|
+
const notLatest = next(i).some(([, func]) => {
|
|
504
|
+
if (!isFunction(func))
|
|
505
|
+
return false;
|
|
506
|
+
const c0 = func;
|
|
507
|
+
const c1 = fn;
|
|
508
|
+
const isIdenticalID = Boolean(c0.id && c1.id && c0.id === c1.id);
|
|
509
|
+
const isIdenticalByReference = c0 === c1;
|
|
510
|
+
return isIdenticalID || isIdenticalByReference || str(c0) === str(c1);
|
|
511
|
+
});
|
|
512
|
+
if (notLatest)
|
|
513
|
+
continue;
|
|
514
|
+
} else if ("skipOnRestore" in fn && fn.skipOnRestore) {
|
|
515
|
+
let getNext = () => {
|
|
516
|
+
const nextActions = next(i);
|
|
517
|
+
getNext = () => {
|
|
518
|
+
return nextActions;
|
|
519
|
+
};
|
|
520
|
+
return nextActions;
|
|
521
|
+
};
|
|
522
|
+
if (fn.skipOnRestore(getNext))
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
511
525
|
}
|
|
512
526
|
processedQueue.push(item);
|
|
513
527
|
} else if (action === "showCharacter" || action === "playSound" || action === "playMusic" || action === "voice") {
|
|
@@ -930,6 +944,76 @@ var Novely = (() => {
|
|
|
930
944
|
});
|
|
931
945
|
};
|
|
932
946
|
|
|
947
|
+
// src/custom-action.ts
|
|
948
|
+
var createCustomActionNode = (id) => {
|
|
949
|
+
const div = document.createElement("div");
|
|
950
|
+
div.setAttribute("data-id", id);
|
|
951
|
+
return div;
|
|
952
|
+
};
|
|
953
|
+
var getCustomActionHolder = (ctx, fn) => {
|
|
954
|
+
const cached = CUSTOM_ACTION_MAP.get(ctx.id + fn.key);
|
|
955
|
+
if (cached) {
|
|
956
|
+
return cached;
|
|
957
|
+
}
|
|
958
|
+
const holder = {
|
|
959
|
+
cleanup: noop,
|
|
960
|
+
node: null,
|
|
961
|
+
fn,
|
|
962
|
+
localData: {}
|
|
963
|
+
};
|
|
964
|
+
CUSTOM_ACTION_MAP.set(ctx.id + fn.key, holder);
|
|
965
|
+
return holder;
|
|
966
|
+
};
|
|
967
|
+
var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, remove: renderersRemove }) => {
|
|
968
|
+
const holder = getCustomActionHolder(ctx, fn);
|
|
969
|
+
const flags = {
|
|
970
|
+
...ctx.meta
|
|
971
|
+
};
|
|
972
|
+
const getDomNodes = (insert = true) => {
|
|
973
|
+
if (holder.node || !insert) {
|
|
974
|
+
return {
|
|
975
|
+
element: holder.node,
|
|
976
|
+
root: ctx.root
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
holder.node = insert ? createCustomActionNode(fn.key) : null;
|
|
980
|
+
setMountElement(holder.node);
|
|
981
|
+
return {
|
|
982
|
+
element: holder.node,
|
|
983
|
+
root: ctx.root
|
|
984
|
+
};
|
|
985
|
+
};
|
|
986
|
+
const clear = (func) => {
|
|
987
|
+
setClear(holder.cleanup = () => {
|
|
988
|
+
func();
|
|
989
|
+
holder.node = null;
|
|
990
|
+
holder.cleanup = noop;
|
|
991
|
+
setMountElement(null);
|
|
992
|
+
setClear(noop);
|
|
993
|
+
});
|
|
994
|
+
};
|
|
995
|
+
const data = (updatedData) => {
|
|
996
|
+
if (updatedData) {
|
|
997
|
+
return holder.localData = updatedData;
|
|
998
|
+
}
|
|
999
|
+
return holder.localData;
|
|
1000
|
+
};
|
|
1001
|
+
const remove = () => {
|
|
1002
|
+
holder.cleanup();
|
|
1003
|
+
renderersRemove();
|
|
1004
|
+
};
|
|
1005
|
+
return fn({
|
|
1006
|
+
flags,
|
|
1007
|
+
lang,
|
|
1008
|
+
state,
|
|
1009
|
+
data,
|
|
1010
|
+
clear,
|
|
1011
|
+
remove,
|
|
1012
|
+
rendererContext: ctx,
|
|
1013
|
+
getDomNodes
|
|
1014
|
+
});
|
|
1015
|
+
};
|
|
1016
|
+
|
|
933
1017
|
// src/storage.ts
|
|
934
1018
|
var localStorageStorage = (options) => {
|
|
935
1019
|
return {
|
|
@@ -1250,7 +1334,7 @@ var Novely = (() => {
|
|
|
1250
1334
|
}
|
|
1251
1335
|
const [action2, fn] = element;
|
|
1252
1336
|
if (action2 === "custom") {
|
|
1253
|
-
context.
|
|
1337
|
+
getCustomActionHolder(context, fn).cleanup();
|
|
1254
1338
|
}
|
|
1255
1339
|
}
|
|
1256
1340
|
}
|
|
@@ -1375,6 +1459,9 @@ var Novely = (() => {
|
|
|
1375
1459
|
}
|
|
1376
1460
|
return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
|
|
1377
1461
|
};
|
|
1462
|
+
const clearCustomAction = (ctx, fn) => {
|
|
1463
|
+
getCustomActionHolder(ctx, fn).cleanup();
|
|
1464
|
+
};
|
|
1378
1465
|
const renderer = createRenderer({
|
|
1379
1466
|
mainContextKey: MAIN_CONTEXT_KEY,
|
|
1380
1467
|
characters,
|
|
@@ -1388,6 +1475,7 @@ var Novely = (() => {
|
|
|
1388
1475
|
preview,
|
|
1389
1476
|
removeContext,
|
|
1390
1477
|
getStateFunction,
|
|
1478
|
+
clearCustomAction,
|
|
1391
1479
|
languages,
|
|
1392
1480
|
storageData,
|
|
1393
1481
|
coreData,
|
|
@@ -1631,19 +1719,31 @@ var Novely = (() => {
|
|
|
1631
1719
|
forward
|
|
1632
1720
|
);
|
|
1633
1721
|
},
|
|
1634
|
-
custom({ ctx, push }, [
|
|
1635
|
-
if (
|
|
1722
|
+
custom({ ctx, push }, [fn]) {
|
|
1723
|
+
if (fn.requireUserAction) {
|
|
1636
1724
|
ctx.clearBlockingActions(void 0);
|
|
1637
1725
|
}
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1726
|
+
const state = getStateFunction(ctx);
|
|
1727
|
+
const lang = storageData.get().meta[0];
|
|
1728
|
+
const result = handleCustomAction(ctx, fn, {
|
|
1729
|
+
...ctx.custom(fn),
|
|
1730
|
+
state,
|
|
1731
|
+
lang
|
|
1732
|
+
});
|
|
1733
|
+
const next2 = () => {
|
|
1734
|
+
if (fn.requireUserAction && !ctx.meta.preview) {
|
|
1642
1735
|
enmemory(ctx);
|
|
1643
1736
|
interactivity(true);
|
|
1644
1737
|
}
|
|
1645
1738
|
push();
|
|
1646
|
-
}
|
|
1739
|
+
};
|
|
1740
|
+
if (!ctx.meta.restoring) {
|
|
1741
|
+
if (isPromise(result)) {
|
|
1742
|
+
result.then(next2);
|
|
1743
|
+
} else {
|
|
1744
|
+
next2();
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1647
1747
|
return result;
|
|
1648
1748
|
},
|
|
1649
1749
|
vibrate({ ctx, push }, pattern) {
|