isaacscript-common 6.23.0 → 7.0.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/classes/DefaultMap.d.ts +3 -3
- package/dist/classes/DefaultMap.d.ts.map +1 -1
- package/dist/classes/DefaultMap.lua +37 -0
- package/dist/features/disableInputs.d.ts +1 -1
- package/dist/features/disableInputs.d.ts.map +1 -1
- package/dist/features/runInNFrames.lua +1 -6
- package/dist/features/runNextRoom.lua +1 -6
- package/dist/features/saveDataManager/exports.d.ts +1 -1
- package/dist/features/saveDataManager/exports.d.ts.map +1 -1
- package/dist/functions/deepCopy.lua +1 -1
- package/dist/interfaces/SaveData.d.ts +15 -5
- package/dist/interfaces/SaveData.d.ts.map +1 -1
- package/dist/interfaces/SaveData.lua +66 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/classes/DefaultMap.ts +36 -7
- package/src/features/disableInputs.ts +3 -9
- package/src/features/runInNFrames.ts +1 -1
- package/src/features/runNextRoom.ts +1 -1
- package/src/features/saveDataManager/exports.ts +1 -1
- package/src/functions/deepCopy.ts +1 -1
- package/src/interfaces/SaveData.ts +223 -21
- package/src/types/index.ts +0 -1
- package/src/types/indexTypeDoc.ts +0 -1
- package/dist/types/AnyClass.d.ts +0 -2
- package/dist/types/AnyClass.d.ts.map +0 -1
- package/dist/types/AnyClass.lua +0 -2
- package/src/types/AnyClass.ts +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* A function that creates the default value for your `DefaultMap`. For example, if it was a
|
|
3
3
|
* `DefaultMap` containing maps, the factory function would be: `() => new Map()`
|
|
4
4
|
*/
|
|
5
|
-
export declare type FactoryFunction<V, Args extends unknown[]> = (...
|
|
5
|
+
export declare type FactoryFunction<V, Args extends unknown[]> = (...args: Args) => V;
|
|
6
6
|
/**
|
|
7
7
|
* `DefaultMap` is a data structure that makes working with default values easier.
|
|
8
8
|
*
|
|
@@ -95,12 +95,12 @@ export declare class DefaultMap<Key, Value, Args extends unknown[] = []> extends
|
|
|
95
95
|
* If the key exists, this will return the same thing as the normal `Map.get` method. Otherwise,
|
|
96
96
|
* it will set a default value for the provided key, and then return the default value.
|
|
97
97
|
*/
|
|
98
|
-
getAndSetDefault(key: Key, ...
|
|
98
|
+
getAndSetDefault(key: Key, ...args: Args): Value;
|
|
99
99
|
/**
|
|
100
100
|
* Returns the default value to be used for a new key. (If a factory function was provided during
|
|
101
101
|
* instantiation, this will execute the factory function.)
|
|
102
102
|
*/
|
|
103
|
-
getDefaultValue(...
|
|
103
|
+
getDefaultValue(...args: Args): Value;
|
|
104
104
|
/**
|
|
105
105
|
* Helper method for cloning the map. Returns either the default value or a reference to the
|
|
106
106
|
* factory function.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultMap.d.ts","sourceRoot":"","sources":["../../src/classes/DefaultMap.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,oBAAY,eAAe,CAAC,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"DefaultMap.d.ts","sourceRoot":"","sources":["../../src/classes/DefaultMap.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,oBAAY,eAAe,CAAC,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,qBAAa,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,OAAO,EAAE,GAAG,EAAE,CAAE,SAAQ,GAAG,CAC1E,GAAG,EACH,KAAK,CACN;IACC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,mBAAmB,CAA2C;IAEtE;;;OAGG;gBAED,6BAA6B,EAAE,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,EACnE,gBAAgB,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAqB3C;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,GAAG,KAAK;IAWhD;;;OAGG;IACH,eAAe,CAAC,GAAG,IAAI,EAAE,IAAI,GAAG,KAAK;IAYrC;;;OAGG;IACH,iBAAiB,IAAI,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC;CAW1D"}
|
|
@@ -3,6 +3,7 @@ local __TS__Class = ____lualib.__TS__Class
|
|
|
3
3
|
local Map = ____lualib.Map
|
|
4
4
|
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
|
5
5
|
local __TS__TypeOf = ____lualib.__TS__TypeOf
|
|
6
|
+
local __TS__New = ____lualib.__TS__New
|
|
6
7
|
local ____exports = {}
|
|
7
8
|
local ____types = require("functions.types")
|
|
8
9
|
local isFunction = ____types.isFunction
|
|
@@ -131,4 +132,40 @@ function DefaultMap.prototype.getConstructorArg(self)
|
|
|
131
132
|
end
|
|
132
133
|
error("A DefaultMap was incorrectly instantiated.")
|
|
133
134
|
end
|
|
135
|
+
local function test(self)
|
|
136
|
+
local myDefaultMapBoolean = __TS__New(____exports.DefaultMap, false)
|
|
137
|
+
local myDefaultMapBooleanFactory = __TS__New(
|
|
138
|
+
____exports.DefaultMap,
|
|
139
|
+
function() return false end
|
|
140
|
+
)
|
|
141
|
+
local myDefaultMapBooleanWithoutParams = __TS__New(____exports.DefaultMap, false)
|
|
142
|
+
local myDefaultMapNumber = __TS__New(____exports.DefaultMap, 123)
|
|
143
|
+
local myDefaultMapNumberFactory = __TS__New(
|
|
144
|
+
____exports.DefaultMap,
|
|
145
|
+
function() return 123 end
|
|
146
|
+
)
|
|
147
|
+
local myDefaultMapNumberWithoutParams = __TS__New(____exports.DefaultMap, 123)
|
|
148
|
+
local myDefaultMapString = __TS__New(____exports.DefaultMap, "foo")
|
|
149
|
+
local myDefaultMapStringFactory = __TS__New(
|
|
150
|
+
____exports.DefaultMap,
|
|
151
|
+
function() return "foo" end
|
|
152
|
+
)
|
|
153
|
+
local myDefaultMapStringWithoutParams = __TS__New(____exports.DefaultMap, "foo")
|
|
154
|
+
local myDefaultMapArray = __TS__New(
|
|
155
|
+
____exports.DefaultMap,
|
|
156
|
+
function() return {} end
|
|
157
|
+
)
|
|
158
|
+
local myDefaultMapArrayWithoutParams = __TS__New(
|
|
159
|
+
____exports.DefaultMap,
|
|
160
|
+
function() return {} end
|
|
161
|
+
)
|
|
162
|
+
local myDefaultMapMap = __TS__New(
|
|
163
|
+
____exports.DefaultMap,
|
|
164
|
+
function() return __TS__New(Map) end
|
|
165
|
+
)
|
|
166
|
+
local myDefaultMapMapWithoutParams = __TS__New(
|
|
167
|
+
____exports.DefaultMap,
|
|
168
|
+
function() return __TS__New(Map) end
|
|
169
|
+
)
|
|
170
|
+
end
|
|
134
171
|
return ____exports
|
|
@@ -39,7 +39,7 @@ export declare function enableAllInputsExceptFor(key: string, blacklist: Set<But
|
|
|
39
39
|
* that multiple mod features can work in tandem.
|
|
40
40
|
* @param whitelist A set of ButtonActions to allow.
|
|
41
41
|
*/
|
|
42
|
-
export declare function disableAllInputsExceptFor(key: string, whitelist: Set<ButtonAction>): void;
|
|
42
|
+
export declare function disableAllInputsExceptFor(key: string, whitelist: Set<ButtonAction> | ReadonlySet<ButtonAction>): void;
|
|
43
43
|
/**
|
|
44
44
|
* Helper function to disable only the inputs used for moving the character (or moving the cursor in
|
|
45
45
|
* the UI). This is useful because `EntityPlayer.ControlsEnabled` can be changed by the game under
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disableInputs.d.ts","sourceRoot":"","sources":["../../src/features/disableInputs.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGb,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"disableInputs.d.ts","sourceRoot":"","sources":["../../src/features/disableInputs.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGb,MAAM,8BAA8B,CAAC;AAiBtC,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAoBhD;AA+CD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,GACvD,IAAI,CAKN;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,GACvD,IAAI,CAKN;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGvD"}
|
|
@@ -60,12 +60,7 @@ end
|
|
|
60
60
|
local FEATURE_NAME = "runInNFrames"
|
|
61
61
|
v = {run = {queuedGameFunctionTuples = {}, queuedRenderFunctionTuples = {}, intervalGameFunctionTuples = {}, intervalRenderFunctionTuples = {}}}
|
|
62
62
|
function ____exports.runInNFramesInit(self, mod)
|
|
63
|
-
saveDataManager(
|
|
64
|
-
nil,
|
|
65
|
-
FEATURE_NAME,
|
|
66
|
-
v,
|
|
67
|
-
function() return false end
|
|
68
|
-
)
|
|
63
|
+
saveDataManager(nil, FEATURE_NAME, v, false)
|
|
69
64
|
mod:AddCallback(ModCallback.POST_UPDATE, postUpdate)
|
|
70
65
|
mod:AddCallback(ModCallback.POST_RENDER, postRender)
|
|
71
66
|
end
|
|
@@ -17,12 +17,7 @@ end
|
|
|
17
17
|
local FEATURE_NAME = "runNextRoom"
|
|
18
18
|
v = {run = {queuedFunctions = {}}}
|
|
19
19
|
function ____exports.runNextRoomInit(self, mod)
|
|
20
|
-
saveDataManager(
|
|
21
|
-
nil,
|
|
22
|
-
FEATURE_NAME,
|
|
23
|
-
v,
|
|
24
|
-
function() return false end
|
|
25
|
-
)
|
|
20
|
+
saveDataManager(nil, FEATURE_NAME, v, false)
|
|
26
21
|
mod:AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_REORDERED, postNewRoomReordered)
|
|
27
22
|
end
|
|
28
23
|
--- Supply a function to run on the next `POST_NEW_ROOM` callback.
|
|
@@ -92,7 +92,7 @@ import { SaveData } from "../../interfaces/SaveData";
|
|
|
92
92
|
export declare function saveDataManager<Persistent, Run, Level>(key: string, // This is the overload for the standard case with serializable data.
|
|
93
93
|
v: SaveData<Persistent, Run, Level>, conditionalFunc?: () => boolean): void;
|
|
94
94
|
export declare function saveDataManager(key: string, // This is the overload for the case when saving data is disabled.
|
|
95
|
-
v: SaveData
|
|
95
|
+
v: SaveData, conditionalFunc: false): void;
|
|
96
96
|
/**
|
|
97
97
|
* The save data manager will automatically load variables from disk at the appropriate times (i.e.
|
|
98
98
|
* when a new run is started). Use this function to explicitly force the save data manager to load
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/saveDataManager/exports.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAarD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,EACpD,GAAG,EAAE,MAAM,EAAE,qEAAqE;AAClF,CAAC,EAAE,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,EACnC,eAAe,CAAC,EAAE,MAAM,OAAO,GAC9B,IAAI,CAAC;AACR,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EAAE,kEAAkE;AAC/E,CAAC,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/saveDataManager/exports.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAarD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,EACpD,GAAG,EAAE,MAAM,EAAE,qEAAqE;AAClF,CAAC,EAAE,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,EACnC,eAAe,CAAC,EAAE,MAAM,OAAO,GAC9B,IAAI,CAAC;AACR,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EAAE,kEAAkE;AAC/E,CAAC,EAAE,QAAQ,EACX,eAAe,EAAE,KAAK,GACrB,IAAI,CAAC;AA+CR;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAQD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAK/C;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,GACrB,IAAI,CAiBN"}
|
|
@@ -210,7 +210,7 @@ function deepCopyDefaultMap(self, defaultMap, serializationType, traversalDescri
|
|
|
210
210
|
local constructorArg = ____isDefaultMap_result_0
|
|
211
211
|
if serializationType == SerializationType.SERIALIZE and not isPrimitive(nil, constructorArg) then
|
|
212
212
|
if insideMap then
|
|
213
|
-
error("Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of
|
|
213
|
+
error("Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#failed-to-deep-copy-a-defaultmap")
|
|
214
214
|
else
|
|
215
215
|
return deepCopyMap(
|
|
216
216
|
nil,
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
/// <reference types="isaac-typescript-definitions" />
|
|
4
4
|
/// <reference types="isaac-typescript-definitions" />
|
|
5
5
|
/// <reference types="isaac-typescript-definitions" />
|
|
6
|
-
import { AnyClass } from "../types";
|
|
7
6
|
/**
|
|
8
7
|
* This is the format of the object that you give to the save data manager. It will contains all of
|
|
9
8
|
* the variables for the particular mod feature.
|
|
@@ -43,17 +42,28 @@ export interface SaveData<Persistent = unknown, Run = unknown, Level = unknown>
|
|
|
43
42
|
* The recursive nature of this type is based on the `Immutable` type:
|
|
44
43
|
* https://stackoverflow.com/questions/41879327/deepreadonly-object-typescript
|
|
45
44
|
*/
|
|
46
|
-
declare type Serializable<T> = T extends
|
|
47
|
-
|
|
45
|
+
declare type Serializable<T> = T extends SerializablePrimitive ? T : T extends SerializableIsaacAPIClass ? T : T extends IsaacAPIClass ? ErrorIsaacAPIClassIsNotSerializable : T extends Array<infer U> ? SerializableArray<U> : T extends ReadonlyArray<infer U> ? SerializableReadonlyArray<U> : T extends Map<infer K, infer V> ? SerializableMap<K, V> : T extends ReadonlyMap<infer K, infer V> ? SerializableReadonlyMap<K, V> : T extends Set<infer V> ? SerializableSet<V> : T extends ReadonlySet<infer V> ? SerializableReadonlySet<V> : SerializableObject<T>;
|
|
46
|
+
/**
|
|
47
|
+
* This is mostly copied from the `Serializable` type. The difference is that we want to disallow
|
|
48
|
+
* classes with methods.
|
|
49
|
+
*/
|
|
50
|
+
declare type SerializableInsideArrayOrMap<T> = T extends SerializablePrimitive ? T : T extends SerializableIsaacAPIClass ? T : T extends IsaacAPIClass ? ErrorIsaacAPIClassIsNotSerializable : T extends Array<infer U> ? SerializableArray<U> : T extends ReadonlyArray<infer U> ? SerializableReadonlyArray<U> : T extends Map<infer K, infer V> ? SerializableMap<K, V> : T extends ReadonlyMap<infer K, infer V> ? SerializableReadonlyMap<K, V> : T extends Set<infer V> ? SerializableSet<V> : T extends ReadonlySet<infer V> ? SerializableReadonlySet<V> : T extends HasMethods<T> ? ErrorCustomClassNotSerializable : T extends Function ? FunctionIsNotSerializable : SerializableObject<T>;
|
|
48
51
|
declare type SerializablePrimitive = boolean | string | number | undefined | null;
|
|
49
52
|
declare type SerializableArray<T> = Array<SerializableInsideArrayOrMap<T>>;
|
|
53
|
+
declare type SerializableReadonlyArray<T> = ReadonlyArray<SerializableInsideArrayOrMap<T>>;
|
|
50
54
|
declare type SerializableMap<K, V> = Map<SerializableInsideArrayOrMap<K>, SerializableInsideArrayOrMap<V>>;
|
|
55
|
+
declare type SerializableReadonlyMap<K, V> = ReadonlyMap<SerializableInsideArrayOrMap<K>, SerializableInsideArrayOrMap<V>>;
|
|
51
56
|
declare type SerializableSet<T> = Set<SerializableInsideArrayOrMap<T>>;
|
|
57
|
+
declare type SerializableReadonlySet<T> = ReadonlySet<SerializableInsideArrayOrMap<T>>;
|
|
52
58
|
declare type SerializableObject<T> = {
|
|
53
59
|
[K in keyof T]: Serializable<T[K]>;
|
|
54
60
|
};
|
|
55
61
|
declare type SerializableIsaacAPIClass = Color | KColor | RNG | Vector;
|
|
56
|
-
declare type
|
|
57
|
-
|
|
62
|
+
declare type HasMethods<T> = {} extends {
|
|
63
|
+
[K in keyof T as T[K] extends Function ? K : never]-?: 1;
|
|
64
|
+
} ? never : T;
|
|
65
|
+
declare type FunctionIsNotSerializable = "Error: Functions are not serializable. For more information, see: https://isaacscript.github.io/main/gotchas#functions-are-not-serializable";
|
|
66
|
+
declare type ErrorIsaacAPIClassIsNotSerializable = "Error: Isaac API classes (such as e.g. `Entity` or `RoomConfig`) are not serializable. For more information, see: https://isaacscript.github.io/main/gotchas#isaac-api-classes-are-not-serializable";
|
|
67
|
+
declare type ErrorCustomClassNotSerializable = "Error: Custom classes with one or more methods are not serializable when inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#custom-classes-are-not-serializable";
|
|
58
68
|
export {};
|
|
59
69
|
//# sourceMappingURL=SaveData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaveData.d.ts","sourceRoot":"","sources":["../../src/interfaces/SaveData.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"SaveData.d.ts","sourceRoot":"","sources":["../../src/interfaces/SaveData.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,68 @@
|
|
|
1
|
+
local ____lualib = require("lualib_bundle")
|
|
2
|
+
local Map = ____lualib.Map
|
|
3
|
+
local __TS__New = ____lualib.__TS__New
|
|
4
|
+
local __TS__Class = ____lualib.__TS__Class
|
|
1
5
|
local ____exports = {}
|
|
6
|
+
local function test(self, _saveData)
|
|
7
|
+
end
|
|
8
|
+
do
|
|
9
|
+
local saveDataWithPrimitives = {run = {foo = 123, bar = "bar", baz = true, nested = {foo = 123, bar = "bar", baz = true}}}
|
|
10
|
+
test(nil, saveDataWithPrimitives)
|
|
11
|
+
end
|
|
12
|
+
do
|
|
13
|
+
local saveDataWithEntity = {run = {foo = {}}}
|
|
14
|
+
test(nil, saveDataWithEntity)
|
|
15
|
+
end
|
|
16
|
+
do
|
|
17
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
18
|
+
test(nil, saveDataWithMap)
|
|
19
|
+
end
|
|
20
|
+
do
|
|
21
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
22
|
+
test(nil, saveDataWithMap)
|
|
23
|
+
end
|
|
24
|
+
do
|
|
25
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
26
|
+
test(nil, saveDataWithMap)
|
|
27
|
+
end
|
|
28
|
+
do
|
|
29
|
+
local Foo = __TS__Class()
|
|
30
|
+
Foo.name = "Foo"
|
|
31
|
+
function Foo.prototype.____constructor(self)
|
|
32
|
+
self.someField = 123
|
|
33
|
+
end
|
|
34
|
+
local saveDataWithClass = {run = {foo = __TS__New(Foo)}}
|
|
35
|
+
test(nil, saveDataWithClass)
|
|
36
|
+
end
|
|
37
|
+
do
|
|
38
|
+
local Foo = __TS__Class()
|
|
39
|
+
Foo.name = "Foo"
|
|
40
|
+
function Foo.prototype.____constructor(self)
|
|
41
|
+
self.someField = 123
|
|
42
|
+
end
|
|
43
|
+
function Foo.prototype.someMethod(self)
|
|
44
|
+
end
|
|
45
|
+
local saveDataWithClassWithMethod = {run = {foo = __TS__New(Foo)}}
|
|
46
|
+
test(nil, saveDataWithClassWithMethod)
|
|
47
|
+
end
|
|
48
|
+
do
|
|
49
|
+
local Foo = __TS__Class()
|
|
50
|
+
Foo.name = "Foo"
|
|
51
|
+
function Foo.prototype.____constructor(self)
|
|
52
|
+
self.someField = 123
|
|
53
|
+
end
|
|
54
|
+
local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
|
|
55
|
+
test(nil, saveDataWithNestedClass)
|
|
56
|
+
end
|
|
57
|
+
do
|
|
58
|
+
local Foo = __TS__Class()
|
|
59
|
+
Foo.name = "Foo"
|
|
60
|
+
function Foo.prototype.____constructor(self)
|
|
61
|
+
self.someField = 123
|
|
62
|
+
end
|
|
63
|
+
function Foo.prototype.someMethod(self)
|
|
64
|
+
end
|
|
65
|
+
local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
|
|
66
|
+
test(nil, saveDataWithNestedClass)
|
|
67
|
+
end
|
|
2
68
|
return ____exports
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,9 +5,7 @@ import { isFunction, isPrimitive } from "../functions/types";
|
|
|
5
5
|
* A function that creates the default value for your `DefaultMap`. For example, if it was a
|
|
6
6
|
* `DefaultMap` containing maps, the factory function would be: `() => new Map()`
|
|
7
7
|
*/
|
|
8
|
-
export type FactoryFunction<V, Args extends unknown[]> = (
|
|
9
|
-
...extraArgs: Args
|
|
10
|
-
) => V;
|
|
8
|
+
export type FactoryFunction<V, Args extends unknown[]> = (...args: Args) => V;
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* `DefaultMap` is a data structure that makes working with default values easier.
|
|
@@ -127,13 +125,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
127
125
|
* If the key exists, this will return the same thing as the normal `Map.get` method. Otherwise,
|
|
128
126
|
* it will set a default value for the provided key, and then return the default value.
|
|
129
127
|
*/
|
|
130
|
-
getAndSetDefault(key: Key, ...
|
|
128
|
+
getAndSetDefault(key: Key, ...args: Args): Value {
|
|
131
129
|
const value = super.get(key);
|
|
132
130
|
if (value !== undefined) {
|
|
133
131
|
return value;
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
const defaultValue = this.getDefaultValue(...
|
|
134
|
+
const defaultValue = this.getDefaultValue(...args);
|
|
137
135
|
this.set(key, defaultValue);
|
|
138
136
|
return defaultValue;
|
|
139
137
|
}
|
|
@@ -142,13 +140,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
142
140
|
* Returns the default value to be used for a new key. (If a factory function was provided during
|
|
143
141
|
* instantiation, this will execute the factory function.)
|
|
144
142
|
*/
|
|
145
|
-
getDefaultValue(...
|
|
143
|
+
getDefaultValue(...args: Args): Value {
|
|
146
144
|
if (this.defaultValue !== undefined) {
|
|
147
145
|
return this.defaultValue;
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
if (this.defaultValueFactory !== undefined) {
|
|
151
|
-
return this.defaultValueFactory(...
|
|
149
|
+
return this.defaultValueFactory(...args);
|
|
152
150
|
}
|
|
153
151
|
|
|
154
152
|
error("A DefaultMap was incorrectly instantiated.");
|
|
@@ -170,3 +168,34 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
170
168
|
error("A DefaultMap was incorrectly instantiated.");
|
|
171
169
|
}
|
|
172
170
|
}
|
|
171
|
+
|
|
172
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
173
|
+
function test() {
|
|
174
|
+
// Boolean
|
|
175
|
+
const myDefaultMapBoolean = new DefaultMap<string, boolean>(false);
|
|
176
|
+
const myDefaultMapBooleanFactory = new DefaultMap<string, boolean>(
|
|
177
|
+
() => false,
|
|
178
|
+
);
|
|
179
|
+
const myDefaultMapBooleanWithoutParams = new DefaultMap(false);
|
|
180
|
+
|
|
181
|
+
// Number
|
|
182
|
+
const myDefaultMapNumber = new DefaultMap<string, number>(123);
|
|
183
|
+
const myDefaultMapNumberFactory = new DefaultMap<string, number>(() => 123);
|
|
184
|
+
const myDefaultMapNumberWithoutParams = new DefaultMap(123);
|
|
185
|
+
|
|
186
|
+
// String
|
|
187
|
+
const myDefaultMapString = new DefaultMap<string, string>("foo");
|
|
188
|
+
const myDefaultMapStringFactory = new DefaultMap<string, string>(() => "foo");
|
|
189
|
+
const myDefaultMapStringWithoutParams = new DefaultMap("foo");
|
|
190
|
+
|
|
191
|
+
// Array
|
|
192
|
+
const myDefaultMapArray = new DefaultMap<string, string[]>(() => []);
|
|
193
|
+
const myDefaultMapArrayWithoutParams = new DefaultMap(() => []);
|
|
194
|
+
|
|
195
|
+
// Map
|
|
196
|
+
const myDefaultMapMap = new DefaultMap<string, Map<string, string>>(
|
|
197
|
+
() => new Map(),
|
|
198
|
+
);
|
|
199
|
+
const myDefaultMapMapWithoutParams = new DefaultMap(() => new Map());
|
|
200
|
+
}
|
|
201
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
@@ -12,16 +12,10 @@ const FEATURE_NAME = "disableInputs";
|
|
|
12
12
|
const v = {
|
|
13
13
|
run: {
|
|
14
14
|
/** Indexed by the requesting feature key. */
|
|
15
|
-
disableInputsWithWhitelistMap: new Map<
|
|
16
|
-
string,
|
|
17
|
-
Set<ButtonAction> | ReadonlySet<ButtonAction>
|
|
18
|
-
>(),
|
|
15
|
+
disableInputsWithWhitelistMap: new Map<string, ReadonlySet<ButtonAction>>(),
|
|
19
16
|
|
|
20
17
|
/** Indexed by the requesting feature key. */
|
|
21
|
-
enableInputsWithBlacklistMap: new Map<
|
|
22
|
-
string,
|
|
23
|
-
Set<ButtonAction> | ReadonlySet<ButtonAction>
|
|
24
|
-
>(),
|
|
18
|
+
enableInputsWithBlacklistMap: new Map<string, ReadonlySet<ButtonAction>>(),
|
|
25
19
|
},
|
|
26
20
|
};
|
|
27
21
|
|
|
@@ -154,7 +148,7 @@ export function enableAllInputsExceptFor(
|
|
|
154
148
|
*/
|
|
155
149
|
export function disableAllInputsExceptFor(
|
|
156
150
|
key: string,
|
|
157
|
-
whitelist: Set<ButtonAction>,
|
|
151
|
+
whitelist: Set<ButtonAction> | ReadonlySet<ButtonAction>,
|
|
158
152
|
): void {
|
|
159
153
|
errorIfFeaturesNotInitialized(FEATURE_NAME);
|
|
160
154
|
|
|
@@ -31,7 +31,7 @@ const v = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export function runInNFramesInit(mod: Mod): void {
|
|
34
|
-
saveDataManager(FEATURE_NAME, v,
|
|
34
|
+
saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
|
|
35
35
|
|
|
36
36
|
mod.AddCallback(ModCallback.POST_UPDATE, postUpdate); // 1
|
|
37
37
|
mod.AddCallback(ModCallback.POST_RENDER, postRender); // 2
|
|
@@ -13,7 +13,7 @@ const v = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export function runNextRoomInit(mod: ModUpgraded): void {
|
|
16
|
-
saveDataManager(FEATURE_NAME, v,
|
|
16
|
+
saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
|
|
17
17
|
|
|
18
18
|
mod.AddCallbackCustom(
|
|
19
19
|
ModCallbackCustom.POST_NEW_ROOM_REORDERED,
|
|
@@ -113,7 +113,7 @@ export function saveDataManager<Persistent, Run, Level>(
|
|
|
113
113
|
): void;
|
|
114
114
|
export function saveDataManager(
|
|
115
115
|
key: string, // This is the overload for the case when saving data is disabled.
|
|
116
|
-
v: SaveData
|
|
116
|
+
v: SaveData,
|
|
117
117
|
conditionalFunc: false,
|
|
118
118
|
): void;
|
|
119
119
|
export function saveDataManager<Persistent, Run, Level>(
|
|
@@ -233,7 +233,7 @@ function deepCopyDefaultMap(
|
|
|
233
233
|
// throw a run-time error to immediately alert the end-user that their data structure is
|
|
234
234
|
// invalid.
|
|
235
235
|
error(
|
|
236
|
-
|
|
236
|
+
"Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#failed-to-deep-copy-a-defaultmap",
|
|
237
237
|
);
|
|
238
238
|
} else {
|
|
239
239
|
// In most cases, the DefaultMap will be attached to a normal table element. In this case, if
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable max-classes-per-file */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This is the format of the object that you give to the save data manager. It will contains all of
|
|
@@ -44,36 +44,238 @@ export interface SaveData<
|
|
|
44
44
|
* The recursive nature of this type is based on the `Immutable` type:
|
|
45
45
|
* https://stackoverflow.com/questions/41879327/deepreadonly-object-typescript
|
|
46
46
|
*/
|
|
47
|
-
type Serializable<T> =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
type Serializable<T> =
|
|
48
|
+
// Allow the trivial case of primitives.
|
|
49
|
+
T extends SerializablePrimitive
|
|
50
|
+
? T
|
|
51
|
+
: // Allow a specific subset of Isaac API classes that are copyable / serializable.
|
|
52
|
+
T extends SerializableIsaacAPIClass
|
|
53
|
+
? T
|
|
54
|
+
: // Disallow all other Isaac API classes.
|
|
55
|
+
T extends IsaacAPIClass
|
|
56
|
+
? ErrorIsaacAPIClassIsNotSerializable
|
|
57
|
+
: // Allow some specific "container" objects.
|
|
58
|
+
// These container objects are explicitly handled by the save data manager, but there are
|
|
59
|
+
// restrictions on the things inside of them.
|
|
60
|
+
T extends Array<infer U>
|
|
61
|
+
? SerializableArray<U>
|
|
62
|
+
: T extends ReadonlyArray<infer U>
|
|
63
|
+
? SerializableReadonlyArray<U>
|
|
64
|
+
: T extends Map<infer K, infer V>
|
|
65
|
+
? SerializableMap<K, V>
|
|
66
|
+
: T extends ReadonlyMap<infer K, infer V>
|
|
67
|
+
? SerializableReadonlyMap<K, V>
|
|
68
|
+
: T extends Set<infer V>
|
|
69
|
+
? SerializableSet<V>
|
|
70
|
+
: T extends ReadonlySet<infer V>
|
|
71
|
+
? SerializableReadonlySet<V>
|
|
72
|
+
: // Allow any other object, as long as the values are themselves serializable.
|
|
73
|
+
SerializableObject<T>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* This is mostly copied from the `Serializable` type. The difference is that we want to disallow
|
|
77
|
+
* classes with methods.
|
|
78
|
+
*/
|
|
79
|
+
type SerializableInsideArrayOrMap<T> =
|
|
80
|
+
// Allow the trivial case of primitives.
|
|
81
|
+
T extends SerializablePrimitive
|
|
82
|
+
? T
|
|
83
|
+
: // Allow a specific subset of Isaac API classes that are copyable / serializable.
|
|
84
|
+
T extends SerializableIsaacAPIClass
|
|
85
|
+
? T
|
|
86
|
+
: // Disallow all other Isaac API classes.
|
|
87
|
+
T extends IsaacAPIClass
|
|
88
|
+
? ErrorIsaacAPIClassIsNotSerializable
|
|
89
|
+
: // Allow some specific "container" objects.
|
|
90
|
+
// These container objects are explicitly handled by the save data manager, but there are
|
|
91
|
+
// restrictions on the things inside of them.
|
|
92
|
+
T extends Array<infer U>
|
|
93
|
+
? SerializableArray<U>
|
|
94
|
+
: T extends ReadonlyArray<infer U>
|
|
95
|
+
? SerializableReadonlyArray<U>
|
|
96
|
+
: T extends Map<infer K, infer V>
|
|
97
|
+
? SerializableMap<K, V>
|
|
98
|
+
: T extends ReadonlyMap<infer K, infer V>
|
|
99
|
+
? SerializableReadonlyMap<K, V>
|
|
100
|
+
: T extends Set<infer V>
|
|
101
|
+
? SerializableSet<V>
|
|
102
|
+
: T extends ReadonlySet<infer V>
|
|
103
|
+
? SerializableReadonlySet<V>
|
|
104
|
+
: // Disallow objects with functions on them (i.e. classes with methods).
|
|
105
|
+
// (This has to be after allowing maps and sets, because those have functions inside of them.)
|
|
106
|
+
T extends HasMethods<T>
|
|
107
|
+
? ErrorCustomClassNotSerializable
|
|
108
|
+
: // Disallow functions.
|
|
109
|
+
// (We can only disallow functions when inside of containers, because we want to allow classes
|
|
110
|
+
// with methods attached to normal objects.)
|
|
111
|
+
T extends Function // eslint-disable-line @typescript-eslint/ban-types
|
|
112
|
+
? FunctionIsNotSerializable
|
|
113
|
+
: // Finally, allow any other object, as long as the values are themselves serializable.
|
|
114
|
+
SerializableObject<T>;
|
|
64
115
|
|
|
65
116
|
type SerializablePrimitive = boolean | string | number | undefined | null;
|
|
66
117
|
type SerializableArray<T> = Array<SerializableInsideArrayOrMap<T>>;
|
|
118
|
+
type SerializableReadonlyArray<T> = ReadonlyArray<
|
|
119
|
+
SerializableInsideArrayOrMap<T>
|
|
120
|
+
>;
|
|
67
121
|
type SerializableMap<K, V> = Map<
|
|
68
122
|
SerializableInsideArrayOrMap<K>,
|
|
69
123
|
SerializableInsideArrayOrMap<V>
|
|
70
124
|
>;
|
|
125
|
+
type SerializableReadonlyMap<K, V> = ReadonlyMap<
|
|
126
|
+
SerializableInsideArrayOrMap<K>,
|
|
127
|
+
SerializableInsideArrayOrMap<V>
|
|
128
|
+
>;
|
|
71
129
|
type SerializableSet<T> = Set<SerializableInsideArrayOrMap<T>>;
|
|
130
|
+
type SerializableReadonlySet<T> = ReadonlySet<SerializableInsideArrayOrMap<T>>;
|
|
72
131
|
type SerializableObject<T> = { [K in keyof T]: Serializable<T[K]> };
|
|
73
132
|
type SerializableIsaacAPIClass = Color | KColor | RNG | Vector;
|
|
74
133
|
|
|
75
|
-
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
135
|
+
type HasMethods<T> = {} extends {
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
137
|
+
[K in keyof T as T[K] extends Function ? K : never]-?: 1;
|
|
138
|
+
}
|
|
139
|
+
? never
|
|
140
|
+
: T;
|
|
141
|
+
|
|
142
|
+
type FunctionIsNotSerializable =
|
|
143
|
+
"Error: Functions are not serializable. For more information, see: https://isaacscript.github.io/main/gotchas#functions-are-not-serializable";
|
|
144
|
+
|
|
145
|
+
type ErrorIsaacAPIClassIsNotSerializable =
|
|
76
146
|
"Error: Isaac API classes (such as e.g. `Entity` or `RoomConfig`) are not serializable. For more information, see: https://isaacscript.github.io/main/gotchas#isaac-api-classes-are-not-serializable";
|
|
77
147
|
|
|
78
|
-
type
|
|
79
|
-
|
|
148
|
+
type ErrorCustomClassNotSerializable =
|
|
149
|
+
"Error: Custom classes with one or more methods are not serializable when inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#custom-classes-are-not-serializable";
|
|
150
|
+
|
|
151
|
+
// -----
|
|
152
|
+
// Tests
|
|
153
|
+
// -----
|
|
154
|
+
|
|
155
|
+
function test<Persistent, Run, Level>(
|
|
156
|
+
_saveData: SaveData<Persistent, Run, Level>,
|
|
157
|
+
) {}
|
|
158
|
+
|
|
159
|
+
{
|
|
160
|
+
const saveDataWithPrimitives = {
|
|
161
|
+
run: {
|
|
162
|
+
foo: 123,
|
|
163
|
+
bar: "bar",
|
|
164
|
+
baz: true,
|
|
165
|
+
nested: {
|
|
166
|
+
foo: 123,
|
|
167
|
+
bar: "bar",
|
|
168
|
+
baz: true,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Primitives and nested primitives are allowed.
|
|
174
|
+
test(saveDataWithPrimitives);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
{
|
|
178
|
+
const saveDataWithEntity = {
|
|
179
|
+
run: {
|
|
180
|
+
foo: {} as Entity,
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// @ts-expect-error Isaac API classes are not serializable.
|
|
185
|
+
test(saveDataWithEntity);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
{
|
|
189
|
+
const saveDataWithMap = {
|
|
190
|
+
run: {
|
|
191
|
+
foo: new Map<string, string>(),
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// Maps with primitive values are allowed.
|
|
196
|
+
test(saveDataWithMap);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
{
|
|
200
|
+
const saveDataWithMap = {
|
|
201
|
+
run: {
|
|
202
|
+
foo: new Map<string, () => void>(),
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// @ts-expect-error Maps with function values are not serializable.
|
|
207
|
+
test(saveDataWithMap);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
{
|
|
211
|
+
const saveDataWithMap = {
|
|
212
|
+
run: {
|
|
213
|
+
foo: new Map<string, Map<string, string>>(),
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// Nested maps are allowed.
|
|
218
|
+
test(saveDataWithMap);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
{
|
|
222
|
+
class Foo {
|
|
223
|
+
someField = 123;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const saveDataWithClass = {
|
|
227
|
+
run: {
|
|
228
|
+
foo: new Foo(),
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Custom classes without methods are allowed.
|
|
233
|
+
test(saveDataWithClass);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
{
|
|
237
|
+
class Foo {
|
|
238
|
+
someField = 123;
|
|
239
|
+
someMethod() {} // eslint-disable-line class-methods-use-this
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const saveDataWithClassWithMethod = {
|
|
243
|
+
run: {
|
|
244
|
+
foo: new Foo(),
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Custom classes with methods are allowed.
|
|
249
|
+
test(saveDataWithClassWithMethod);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
class Foo {
|
|
254
|
+
someField = 123;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const saveDataWithNestedClass = {
|
|
258
|
+
run: {
|
|
259
|
+
fooMap: new Map<string, Foo>(),
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Nested custom classes without methods are allowed.
|
|
264
|
+
test(saveDataWithNestedClass);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
{
|
|
268
|
+
class Foo {
|
|
269
|
+
someField = 123;
|
|
270
|
+
someMethod() {} // eslint-disable-line class-methods-use-this
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const saveDataWithNestedClass = {
|
|
274
|
+
run: {
|
|
275
|
+
fooMap: new Map<string, Foo>(),
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// @ts-expect-error Nested custom classes with methods are not serializable.
|
|
280
|
+
test(saveDataWithNestedClass);
|
|
281
|
+
}
|
package/src/types/index.ts
CHANGED
package/dist/types/AnyClass.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnyClass.d.ts","sourceRoot":"","sources":["../../src/types/AnyClass.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ,GAAG,KAAK,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,OAAO,CAAC"}
|
package/dist/types/AnyClass.lua
DELETED
package/src/types/AnyClass.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type AnyClass = new (...args: readonly unknown[]) => unknown;
|