@react-text-game/core 0.1.0 → 0.2.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/README.md +68 -22
- package/dist/game.d.ts +1 -1
- package/dist/game.d.ts.map +1 -1
- package/dist/game.js.map +1 -1
- package/dist/{baseGameObject.d.ts → gameObjects/baseGameObject.d.ts} +1 -1
- package/dist/gameObjects/baseGameObject.d.ts.map +1 -0
- package/dist/{baseGameObject.js → gameObjects/baseGameObject.js} +2 -2
- package/dist/gameObjects/baseGameObject.js.map +1 -0
- package/dist/gameObjects/fabric.d.ts +19 -0
- package/dist/gameObjects/fabric.d.ts.map +1 -0
- package/dist/gameObjects/fabric.js +18 -0
- package/dist/gameObjects/fabric.js.map +1 -0
- package/dist/gameObjects/index.d.ts +3 -0
- package/dist/gameObjects/index.d.ts.map +1 -0
- package/dist/gameObjects/index.js +3 -0
- package/dist/gameObjects/index.js.map +1 -0
- package/dist/gameObjects/simpleObject.d.ts +62 -0
- package/dist/gameObjects/simpleObject.d.ts.map +1 -0
- package/dist/gameObjects/simpleObject.js +98 -0
- package/dist/gameObjects/simpleObject.js.map +1 -0
- package/dist/hooks/useGameEntity.d.ts +1 -1
- package/dist/hooks/useGameEntity.d.ts.map +1 -1
- package/dist/hooks/useGameEntity.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/tests/game.test.js +4 -68
- package/dist/tests/game.test.js.map +1 -1
- package/dist/tests/helpers/index.d.ts +2 -0
- package/dist/tests/helpers/index.d.ts.map +1 -0
- package/dist/tests/helpers/index.js +2 -0
- package/dist/tests/helpers/index.js.map +1 -0
- package/dist/tests/helpers/setupMockStorage.d.ts +10 -0
- package/dist/tests/helpers/setupMockStorage.d.ts.map +1 -0
- package/dist/tests/helpers/setupMockStorage.js +31 -0
- package/dist/tests/helpers/setupMockStorage.js.map +1 -0
- package/dist/tests/mocks/MockStorage.d.ts +14 -0
- package/dist/tests/mocks/MockStorage.d.ts.map +1 -0
- package/dist/tests/mocks/MockStorage.js +43 -0
- package/dist/tests/mocks/MockStorage.js.map +1 -0
- package/dist/tests/mocks/index.d.ts +2 -0
- package/dist/tests/mocks/index.d.ts.map +1 -0
- package/dist/tests/mocks/index.js +2 -0
- package/dist/tests/mocks/index.js.map +1 -0
- package/dist/tests/simpleObject.test.d.ts +2 -0
- package/dist/tests/simpleObject.test.d.ts.map +1 -0
- package/dist/tests/simpleObject.test.js +377 -0
- package/dist/tests/simpleObject.test.js.map +1 -0
- package/package.json +4 -2
- package/dist/baseGameObject.d.ts.map +0 -1
- package/dist/baseGameObject.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,36 +8,51 @@ A powerful, reactive text-based game engine built for React applications. This p
|
|
|
8
8
|
- **Multiple Passage Types** - Story, Interactive Map, and Widget passages
|
|
9
9
|
- **Flexible Save System** - JSONPath-based storage with auto-save support
|
|
10
10
|
- **Entity Registry** - Automatic registration and proxying of game objects
|
|
11
|
+
- **Factory-Based Entities** - Plain-object factories for beginners with class-based escape hatches
|
|
11
12
|
- **Type-Safe** - Full TypeScript support with comprehensive types
|
|
12
13
|
- **React Hooks** - Built-in hooks for seamless React integration
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
16
17
|
```bash
|
|
18
|
+
# bun
|
|
17
19
|
bun add @react-text-game/core
|
|
20
|
+
|
|
21
|
+
# npm
|
|
22
|
+
npm install @react-text-game/core
|
|
23
|
+
|
|
24
|
+
# yarn
|
|
25
|
+
yarn add @react-text-game/core
|
|
26
|
+
|
|
27
|
+
# pnpm
|
|
28
|
+
pnpm add @react-text-game/core
|
|
18
29
|
```
|
|
19
30
|
|
|
20
31
|
## Quick Start
|
|
21
32
|
|
|
22
33
|
```tsx
|
|
23
|
-
import { Game,
|
|
34
|
+
import { Game, createEntity, newStory } from '@react-text-game/core';
|
|
24
35
|
|
|
25
36
|
// IMPORTANT: Initialize the game first
|
|
26
37
|
await Game.init({
|
|
27
38
|
// your game options
|
|
28
39
|
});
|
|
29
40
|
|
|
30
|
-
// Create a game entity
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
41
|
+
// Create a game entity with the factory (recommended)
|
|
42
|
+
const player = createEntity('player', {
|
|
43
|
+
name: 'Hero',
|
|
44
|
+
stats: {
|
|
45
|
+
health: 100,
|
|
46
|
+
mana: 50
|
|
47
|
+
},
|
|
48
|
+
inventory: [] as string[],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Direct property updates automatically stay reactive
|
|
52
|
+
player.stats.health -= 10;
|
|
39
53
|
|
|
40
|
-
|
|
54
|
+
// Persist manual changes when you need them stored
|
|
55
|
+
player.save();
|
|
41
56
|
|
|
42
57
|
// Create a story passage
|
|
43
58
|
const introStory = newStory('intro', () => [
|
|
@@ -48,7 +63,7 @@ const introStory = newStory('intro', () => [
|
|
|
48
63
|
},
|
|
49
64
|
{
|
|
50
65
|
type: 'text',
|
|
51
|
-
content: `Hello, ${player.
|
|
66
|
+
content: `Hello, ${player.name}!`
|
|
52
67
|
},
|
|
53
68
|
{
|
|
54
69
|
type: 'actions',
|
|
@@ -65,6 +80,8 @@ const introStory = newStory('intro', () => [
|
|
|
65
80
|
Game.jumpTo(introStory);
|
|
66
81
|
```
|
|
67
82
|
|
|
83
|
+
> Prefer writing classes? Jump to [Advanced Entities](#advanced-entities-basegameobject) for a drop-in replacement using inheritance.
|
|
84
|
+
|
|
68
85
|
## Core Concepts
|
|
69
86
|
|
|
70
87
|
### Game
|
|
@@ -102,27 +119,56 @@ Game.enableAutoSave();
|
|
|
102
119
|
Game.loadFromSessionStorage();
|
|
103
120
|
```
|
|
104
121
|
|
|
105
|
-
###
|
|
122
|
+
### Entities
|
|
123
|
+
|
|
124
|
+
#### Entity Factory (`createEntity`) — Recommended Starting Point
|
|
106
125
|
|
|
107
|
-
|
|
126
|
+
The simplest way to model game state is with the `createEntity` factory. You
|
|
127
|
+
provide a unique id and a plain object describing the initial state; the engine
|
|
128
|
+
wraps it in a `SimpleObject` that:
|
|
108
129
|
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
130
|
+
- Registers itself with the game automatically
|
|
131
|
+
- Exposes variables as direct properties (`player.health`, not `player.variables.health`)
|
|
132
|
+
- Keeps nested objects/arrays reactive via deep proxies
|
|
133
|
+
- Requires explicit `save()` calls so you stay in control of persistence cadence
|
|
113
134
|
|
|
114
135
|
```typescript
|
|
136
|
+
import { createEntity } from '@react-text-game/core';
|
|
137
|
+
|
|
138
|
+
const player = createEntity('player', {
|
|
139
|
+
name: 'Hero',
|
|
140
|
+
health: 100,
|
|
141
|
+
inventory: {
|
|
142
|
+
gold: 50,
|
|
143
|
+
items: [] as string[],
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
player.health -= 5; // direct property access
|
|
148
|
+
player.inventory.items.push('sword');
|
|
149
|
+
player.save(); // persist changes when you decide to
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Advanced Entities (`BaseGameObject`)
|
|
153
|
+
|
|
154
|
+
Prefer a class-based design, private fields, or inheritance? Extend
|
|
155
|
+
`BaseGameObject` directly—the same registration and storage hooks remain
|
|
156
|
+
available:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { BaseGameObject } from '@react-text-game/core';
|
|
160
|
+
|
|
115
161
|
class Inventory extends BaseGameObject<{ items: string[] }> {
|
|
116
162
|
constructor() {
|
|
117
163
|
super({
|
|
118
164
|
id: 'inventory',
|
|
119
|
-
variables: { items: [] }
|
|
165
|
+
variables: { items: [] },
|
|
120
166
|
});
|
|
121
167
|
}
|
|
122
168
|
|
|
123
169
|
addItem(item: string) {
|
|
124
170
|
this._variables.items.push(item);
|
|
125
|
-
this.save();
|
|
171
|
+
this.save();
|
|
126
172
|
}
|
|
127
173
|
}
|
|
128
174
|
```
|
|
@@ -578,8 +624,8 @@ function PlayerStats({ player }) {
|
|
|
578
624
|
|
|
579
625
|
return (
|
|
580
626
|
<div>
|
|
581
|
-
Health: {reactivePlayer.
|
|
582
|
-
{/*
|
|
627
|
+
Health: {reactivePlayer.health}
|
|
628
|
+
{/* Direct property access stays reactive */}
|
|
583
629
|
</div>
|
|
584
630
|
);
|
|
585
631
|
}
|
package/dist/game.d.ts
CHANGED
package/dist/game.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../src/game.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../src/game.ts"],"names":[],"mappings":"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"}
|
package/dist/game.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game.js","sourceRoot":"","sources":["../src/game.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"game.js","sourceRoot":"","sources":["../src/game.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseGameObject.d.ts","sourceRoot":"","sources":["../../src/gameObjects/baseGameObject.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAY,MAAM,QAAQ,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,cAAc,CAAC,aAAa,SAAS,YAAY,GAAG,YAAY;IACzE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IAEzC;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC;IAEpC;;;;;;OAMG;gBACS,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,aAAa,CAAA;KAAE;IAM5D;;;;OAIG;IACH,IAAI,SAAS,IAAI,aAAa,CAE7B;IAED;;;;;OAKG;IACH,OAAO,KAAK,IAAI,GAEf;IAED;;;;;;;;;;OAUG;IACH,IAAI;IAWJ;;;;;;;;;;OAUG;IACH,IAAI;CAGP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseGameObject.js","sourceRoot":"","sources":["../../src/gameObjects/baseGameObject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,cAAc;IACf,MAAM,CAAC,QAAQ,GAAa,IAAI,CAAC;IAEzC;;;OAGG;IACM,EAAE,CAAS;IAEpB;;;OAGG;IACO,UAAU,CAAgB;IAEpC;;;;;;OAMG;IACH,YAAY,KAAgD;QACxD,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,IAAK,EAAoB,CAAC;QAC3D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,IAAY,IAAI;QACZ,OAAO,GAAG,cAAc,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,EAAc,CAAC;IAC9D,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI;QACA,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAkB,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACJ,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI;QACA,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { InitVarsType } from "../types";
|
|
2
|
+
import { SimpleObject } from "./simpleObject";
|
|
3
|
+
/**
|
|
4
|
+
* Convenience factory that wraps {@link SimpleObject} creation.
|
|
5
|
+
*
|
|
6
|
+
* This function mirrors the fabric-style APIs used for passages so entity
|
|
7
|
+
* authors can define state in plain objects and still get reactive behaviour.
|
|
8
|
+
* The created entity is registered with the game engine via the
|
|
9
|
+
* `BaseGameObject` constructor and exposes its variables as direct
|
|
10
|
+
* properties.
|
|
11
|
+
*
|
|
12
|
+
* @param id - Unique identifier used for registry lookups and persistence.
|
|
13
|
+
* @param variables - Initial reactive state for the entity. Nested objects and
|
|
14
|
+
* arrays are supported and proxied.
|
|
15
|
+
* @returns A `SimpleObject` instance that can be used anywhere a
|
|
16
|
+
* `BaseGameObject` is expected.
|
|
17
|
+
*/
|
|
18
|
+
export declare const createEntity: <Vars extends InitVarsType>(id: string, variables: Vars) => SimpleObject<Vars>;
|
|
19
|
+
//# sourceMappingURL=fabric.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric.d.ts","sourceRoot":"","sources":["../../src/gameObjects/fabric.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,GAAI,IAAI,SAAS,YAAY,EAClD,IAAI,MAAM,EACV,WAAW,IAAI,uBACqB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SimpleObject } from "./simpleObject";
|
|
2
|
+
/**
|
|
3
|
+
* Convenience factory that wraps {@link SimpleObject} creation.
|
|
4
|
+
*
|
|
5
|
+
* This function mirrors the fabric-style APIs used for passages so entity
|
|
6
|
+
* authors can define state in plain objects and still get reactive behaviour.
|
|
7
|
+
* The created entity is registered with the game engine via the
|
|
8
|
+
* `BaseGameObject` constructor and exposes its variables as direct
|
|
9
|
+
* properties.
|
|
10
|
+
*
|
|
11
|
+
* @param id - Unique identifier used for registry lookups and persistence.
|
|
12
|
+
* @param variables - Initial reactive state for the entity. Nested objects and
|
|
13
|
+
* arrays are supported and proxied.
|
|
14
|
+
* @returns A `SimpleObject` instance that can be used anywhere a
|
|
15
|
+
* `BaseGameObject` is expected.
|
|
16
|
+
*/
|
|
17
|
+
export const createEntity = (id, variables) => new SimpleObject({ id, variables });
|
|
18
|
+
//# sourceMappingURL=fabric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric.js","sourceRoot":"","sources":["../../src/gameObjects/fabric.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CACxB,EAAU,EACV,SAAe,EACjB,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gameObjects/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gameObjects/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { InitVarsType } from "../types";
|
|
2
|
+
import { BaseGameObject } from "./baseGameObject";
|
|
3
|
+
/**
|
|
4
|
+
* Internal implementation that augments {@link BaseGameObject} with
|
|
5
|
+
* property accessors for each variable field.
|
|
6
|
+
*
|
|
7
|
+
* Consumers interact with the exported `SimpleObject` type alias/factory,
|
|
8
|
+
* but documenting this class clarifies how deep proxying and manual save hooks
|
|
9
|
+
* are wired under the hood.
|
|
10
|
+
*/
|
|
11
|
+
declare class SimpleObjectImpl<VariablesType extends InitVarsType> extends BaseGameObject<VariablesType> {
|
|
12
|
+
private proxyCache;
|
|
13
|
+
constructor(props: {
|
|
14
|
+
id: string;
|
|
15
|
+
variables?: VariablesType;
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Checks if a value should be wrapped in a proxy
|
|
19
|
+
* Returns true for plain objects and arrays, false for primitives and special types
|
|
20
|
+
*/
|
|
21
|
+
private isProxyableObject;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a deep proxy that intercepts property access at all levels
|
|
24
|
+
* Any modification to nested properties will trigger save()
|
|
25
|
+
*/
|
|
26
|
+
private createDeepProxy;
|
|
27
|
+
/**
|
|
28
|
+
* Overrides load() to clear proxy cache after loading from storage.
|
|
29
|
+
* This ensures that any cached proxies for nested objects are invalidated.
|
|
30
|
+
*/
|
|
31
|
+
load(): void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Type representing a SimpleObject instance with direct property access.
|
|
35
|
+
* Combines BaseGameObject functionality with variable properties.
|
|
36
|
+
*/
|
|
37
|
+
export type SimpleObject<VariablesType extends InitVarsType> = SimpleObjectImpl<VariablesType> & VariablesType;
|
|
38
|
+
/**
|
|
39
|
+
* SimpleObject provides direct property access to game entity variables.
|
|
40
|
+
*
|
|
41
|
+
* Instead of accessing `entity._variables.health`, you can use `entity.health` directly.
|
|
42
|
+
* Supports nested objects with deep reactivity.
|
|
43
|
+
*
|
|
44
|
+
* @template VariablesType - The type of variables stored in this object
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const player = new SimpleObject({
|
|
49
|
+
* id: 'player',
|
|
50
|
+
* variables: { health: 100, mana: 50 }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* player.health = 75; // Direct access
|
|
54
|
+
* player.health += 25; // Operators work
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare const SimpleObject: new <VariablesType extends InitVarsType>(props: {
|
|
58
|
+
id: string;
|
|
59
|
+
variables?: VariablesType;
|
|
60
|
+
}) => SimpleObject<VariablesType>;
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=simpleObject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleObject.d.ts","sourceRoot":"","sources":["../../src/gameObjects/simpleObject.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;GAOG;AACH,cAAM,gBAAgB,CAAC,aAAa,SAAS,YAAY,CAAE,SAAQ,cAAc,CAAC,aAAa,CAAC;IAC5F,OAAO,CAAC,UAAU,CAAiC;gBAEvC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,aAAa,CAAA;KAAE;IAgC5D;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAYvB;;;OAGG;IACH,IAAI,IAAI,IAAI;CAKf;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,aAAa,SAAS,YAAY,IACvD,gBAAgB,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;AAEpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAuB,KAC5C,aAAa,SAAS,YAAY,EAElC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,aAAa,CAAA;CAAE,KAC/C,YAAY,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { proxy } from "valtio";
|
|
2
|
+
import { BaseGameObject } from "./baseGameObject";
|
|
3
|
+
/**
|
|
4
|
+
* Internal implementation that augments {@link BaseGameObject} with
|
|
5
|
+
* property accessors for each variable field.
|
|
6
|
+
*
|
|
7
|
+
* Consumers interact with the exported `SimpleObject` type alias/factory,
|
|
8
|
+
* but documenting this class clarifies how deep proxying and manual save hooks
|
|
9
|
+
* are wired under the hood.
|
|
10
|
+
*/
|
|
11
|
+
class SimpleObjectImpl extends BaseGameObject {
|
|
12
|
+
proxyCache = new WeakMap();
|
|
13
|
+
constructor(props) {
|
|
14
|
+
super(props);
|
|
15
|
+
// for each of variables register getter and setter, so we can do like this:
|
|
16
|
+
// const player = new SimpleObject({ id: 'player', variables: { health: 100 } });
|
|
17
|
+
// player.health = 50;
|
|
18
|
+
// console.log(player.health); // 50
|
|
19
|
+
// Also supports nested objects:
|
|
20
|
+
// const player = new SimpleObject({ id: 'player', variables: { health: { mental: 20, physical: 30 } } });
|
|
21
|
+
// player.health.mental += 20;
|
|
22
|
+
if (props.variables) {
|
|
23
|
+
for (const key of Object.keys(props.variables)) {
|
|
24
|
+
Object.defineProperty(this, key, {
|
|
25
|
+
get: () => {
|
|
26
|
+
const value = this._variables[key];
|
|
27
|
+
// If it's an object (but not Date or other special types), wrap it in a deep proxy
|
|
28
|
+
if (this.isProxyableObject(value)) {
|
|
29
|
+
return this.createDeepProxy(value);
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
},
|
|
33
|
+
set: (value) => {
|
|
34
|
+
this._variables[key] = value;
|
|
35
|
+
// Note: does not auto-save. Call save() manually to persist changes.
|
|
36
|
+
},
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks if a value should be wrapped in a proxy
|
|
45
|
+
* Returns true for plain objects and arrays, false for primitives and special types
|
|
46
|
+
*/
|
|
47
|
+
isProxyableObject(value) {
|
|
48
|
+
return (value !== null &&
|
|
49
|
+
typeof value === "object" &&
|
|
50
|
+
!(value instanceof Date) &&
|
|
51
|
+
!(value instanceof RegExp) &&
|
|
52
|
+
!(value instanceof Map) &&
|
|
53
|
+
!(value instanceof Set));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a deep proxy that intercepts property access at all levels
|
|
57
|
+
* Any modification to nested properties will trigger save()
|
|
58
|
+
*/
|
|
59
|
+
createDeepProxy(obj) {
|
|
60
|
+
// Return cached proxy if it exists to avoid creating multiple proxies for the same object
|
|
61
|
+
if (this.proxyCache.has(obj)) {
|
|
62
|
+
return this.proxyCache.get(obj);
|
|
63
|
+
}
|
|
64
|
+
const proxy_ = proxy(obj);
|
|
65
|
+
this.proxyCache.set(obj, proxy_);
|
|
66
|
+
return proxy_;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Overrides load() to clear proxy cache after loading from storage.
|
|
70
|
+
* This ensures that any cached proxies for nested objects are invalidated.
|
|
71
|
+
*/
|
|
72
|
+
load() {
|
|
73
|
+
super.load();
|
|
74
|
+
// Clear the proxy cache so new proxies are created for the loaded data
|
|
75
|
+
this.proxyCache = new WeakMap();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* SimpleObject provides direct property access to game entity variables.
|
|
80
|
+
*
|
|
81
|
+
* Instead of accessing `entity._variables.health`, you can use `entity.health` directly.
|
|
82
|
+
* Supports nested objects with deep reactivity.
|
|
83
|
+
*
|
|
84
|
+
* @template VariablesType - The type of variables stored in this object
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const player = new SimpleObject({
|
|
89
|
+
* id: 'player',
|
|
90
|
+
* variables: { health: 100, mana: 50 }
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* player.health = 75; // Direct access
|
|
94
|
+
* player.health += 25; // Operators work
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export const SimpleObject = SimpleObjectImpl;
|
|
98
|
+
//# sourceMappingURL=simpleObject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleObject.js","sourceRoot":"","sources":["../../src/gameObjects/simpleObject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAI/B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,gBAAqD,SAAQ,cAA6B;IACpF,UAAU,GAAG,IAAI,OAAO,EAAkB,CAAC;IAEnD,YAAY,KAAgD;QACxD,KAAK,CAAC,KAAK,CAAC,CAAC;QAEb,4EAA4E;QAC5E,iFAAiF;QACjF,sBAAsB;QACtB,oCAAoC;QACpC,gCAAgC;QAChC,0GAA0G;QAC1G,8BAA8B;QAC9B,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE;oBAC7B,GAAG,EAAE,GAAG,EAAE;wBACN,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAA0B,CAAC,CAAC;wBAC1D,mFAAmF;wBACnF,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;4BAChC,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;wBACvC,CAAC;wBACD,OAAO,KAAK,CAAC;oBACjB,CAAC;oBACD,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;wBACX,IAAI,CAAC,UAAU,CAAC,GAA0B,CAAC,GAAG,KAAK,CAAC;wBACpD,qEAAqE;oBACzE,CAAC;oBACD,UAAU,EAAE,IAAI;oBAChB,YAAY,EAAE,IAAI;iBACrB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,KAAc;QACpC,OAAO,CACH,KAAK,KAAK,IAAI;YACd,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC;YACxB,CAAC,CAAC,KAAK,YAAY,MAAM,CAAC;YAC1B,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC;YACvB,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC,CAC1B,CAAC;IACN,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,GAAW;QAC/B,0FAA0F;QAC1F,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QACrC,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAEjC,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,IAAI;QACA,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,uEAAuE;QACvE,IAAI,CAAC,UAAU,GAAG,IAAI,OAAO,EAAkB,CAAC;IACpD,CAAC;CACJ;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,gBAII,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseGameObject } from "../
|
|
1
|
+
import { BaseGameObject } from "../gameObjects";
|
|
2
2
|
/**
|
|
3
3
|
* Monitors changes to a given game entity by wrapping it in a Valtio proxy.
|
|
4
4
|
* This hook enables React components to automatically re-render when the entity's state changes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGameEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/useGameEntity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useGameEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/useGameEntity.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAoC9C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,cAAc,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAexE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGameEntity.js","sourceRoot":"","sources":["../../src/hooks/useGameEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"useGameEntity.js","sourceRoot":"","sources":["../../src/hooks/useGameEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAG7B,MAAM,eAAe,GAAG,CAAC,EAAU,EAAE,EAAE,CACnC;IACI,EAAE;IACF,0DAA0D;IAC1D,+BAA+B;IAC/B,0DAA0D;IAC1D,EAAE;IACF,WAAW,EAAE,2CAA2C;IACxD,EAAE;IACF,oBAAoB;IACpB,qEAAqE;IACrE,iEAAiE;IACjE,EAAE;IACF,aAAa;IACb,2DAA2D;IAC3D,+BAA+B;IAC/B,EAAE;IACF,SAAS,EAAE,8CAA8C;IACzD,2EAA2E;IAC3E,EAAE;IACF,YAAY;IACZ,0BAA0B;IAC1B,kDAAkD;IAClD,OAAO;IACP,EAAE;IACF,kBAAkB;IAClB,kBAAkB,EAAE,0BAA0B;IAC9C,sDAAsD;IACtD,kEAAkE;IAClE,EAAE;IACF,0DAA0D;IAC1D,EAAE;CACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEjB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAA2B,UAAa;IACjE,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAEzD,IAAI,CAAC;QACD,OAAO,QAAQ,CAAC,aAAa,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,iEAAiE;QACjE,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC7B,MAAM,YAAY,GAAG,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACJ,MAAM,KAAK,CAAC,CAAC,gCAAgC;QACjD,CAAC;IACL,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseGameObject } from "./baseGameObject";
|
|
2
1
|
import { Game } from "./game";
|
|
2
|
+
import { BaseGameObject, createEntity } from "./gameObjects";
|
|
3
3
|
import type { NewOptions, Options } from "./options";
|
|
4
4
|
import { InteractiveMap, newInteractiveMap } from "./passages/interactiveMap";
|
|
5
5
|
import { Passage } from "./passages/passage";
|
|
@@ -8,5 +8,5 @@ import { newWidget, Widget } from "./passages/widget";
|
|
|
8
8
|
export * from "./constants";
|
|
9
9
|
export * from "./hooks";
|
|
10
10
|
export type * from "./types";
|
|
11
|
-
export { BaseGameObject, Game, InteractiveMap, newInteractiveMap, NewOptions, newStory, newWidget, Options, Passage, Story, Widget, };
|
|
11
|
+
export { BaseGameObject, createEntity, Game, InteractiveMap, newInteractiveMap, NewOptions, newStory, newWidget, Options, Passage, Story, Widget, };
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,mBAAmB,QAAQ,CAAC;AAE5B,OAAO,EACH,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,MAAM,GACT,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { BaseGameObject } from "./baseGameObject";
|
|
2
1
|
import { Game } from "./game";
|
|
2
|
+
import { BaseGameObject, createEntity } from "./gameObjects";
|
|
3
3
|
import { InteractiveMap, newInteractiveMap } from "./passages/interactiveMap";
|
|
4
4
|
import { Passage } from "./passages/passage";
|
|
5
5
|
import { newStory, Story } from "./passages/story";
|
|
6
6
|
import { newWidget, Widget } from "./passages/widget";
|
|
7
7
|
export * from "./constants";
|
|
8
8
|
export * from "./hooks";
|
|
9
|
-
export { BaseGameObject, Game, InteractiveMap, newInteractiveMap, newStory, newWidget, Passage, Story, Widget, };
|
|
9
|
+
export { BaseGameObject, createEntity, Game, InteractiveMap, newInteractiveMap, newStory, newWidget, Passage, Story, Widget, };
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AAGxB,OAAO,EACH,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,cAAc,EACd,iBAAiB,EAEjB,QAAQ,EACR,SAAS,EAET,OAAO,EACP,KAAK,EACL,MAAM,GACT,CAAC"}
|
package/dist/tests/game.test.js
CHANGED
|
@@ -1,51 +1,9 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import { BaseGameObject } from "../baseGameObject";
|
|
3
2
|
import { SYSTEM_PASSAGE_NAMES } from "../constants";
|
|
4
3
|
import { Game } from "../game";
|
|
4
|
+
import { BaseGameObject } from "../gameObjects";
|
|
5
5
|
import { Passage } from "../passages/passage";
|
|
6
|
-
import {
|
|
7
|
-
// Create a mock storage that properly handles setState/getState
|
|
8
|
-
class MockStorage {
|
|
9
|
-
static state = {};
|
|
10
|
-
static getValue(jsonPath) {
|
|
11
|
-
// Simple implementation that handles our test cases
|
|
12
|
-
const path = jsonPath.replace(/^\$\./, "").split(".");
|
|
13
|
-
let current = this.state;
|
|
14
|
-
for (const key of path) {
|
|
15
|
-
if (current && typeof current === "object" && key in current) {
|
|
16
|
-
current = current[key];
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return [current];
|
|
23
|
-
}
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
25
|
-
static setValue(jsonPath, value, _isSystem = false) {
|
|
26
|
-
const path = jsonPath.replace(/^\$\./, "").split(".");
|
|
27
|
-
let current = this.state;
|
|
28
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
29
|
-
const key = path[i];
|
|
30
|
-
if (!(key in current)) {
|
|
31
|
-
current[key] = {};
|
|
32
|
-
}
|
|
33
|
-
current = current[key];
|
|
34
|
-
}
|
|
35
|
-
current[path[path.length - 1]] = value;
|
|
36
|
-
}
|
|
37
|
-
static getState() {
|
|
38
|
-
// Return a deep clone to avoid reference issues
|
|
39
|
-
return JSON.parse(JSON.stringify(this.state));
|
|
40
|
-
}
|
|
41
|
-
static setState(state) {
|
|
42
|
-
// Deep clone the incoming state to avoid reference issues
|
|
43
|
-
this.state = JSON.parse(JSON.stringify(state));
|
|
44
|
-
}
|
|
45
|
-
static reset() {
|
|
46
|
-
this.state = {};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
6
|
+
import { setupMockStorage, teardownMockStorage } from "../tests/helpers";
|
|
49
7
|
// Test helper classes
|
|
50
8
|
class TestEntity extends BaseGameObject {
|
|
51
9
|
constructor(id, health = 100, name = "Test") {
|
|
@@ -81,37 +39,15 @@ let testCounter = 0;
|
|
|
81
39
|
function uniqueId(prefix) {
|
|
82
40
|
return `${prefix}-${testCounter++}`;
|
|
83
41
|
}
|
|
84
|
-
// Store original Storage methods
|
|
85
|
-
const originalStorageMethods = {
|
|
86
|
-
getValue: Storage.getValue.bind(Storage),
|
|
87
|
-
setValue: Storage.setValue.bind(Storage),
|
|
88
|
-
getState: Storage.getState.bind(Storage),
|
|
89
|
-
setState: Storage.setState.bind(Storage),
|
|
90
|
-
};
|
|
91
42
|
describe("Game", () => {
|
|
92
43
|
beforeEach(async () => {
|
|
93
|
-
|
|
94
|
-
Storage.getValue = MockStorage.getValue.bind(MockStorage);
|
|
95
|
-
Storage.setValue = MockStorage.setValue.bind(MockStorage);
|
|
96
|
-
Storage.getState = MockStorage.getState.bind(MockStorage);
|
|
97
|
-
Storage.setState = MockStorage.setState.bind(MockStorage);
|
|
98
|
-
// Reset mock storage
|
|
99
|
-
MockStorage.reset();
|
|
100
|
-
// Clear session storage
|
|
44
|
+
setupMockStorage();
|
|
101
45
|
sessionStorage.clear();
|
|
102
|
-
// Re-initialize the game for each test
|
|
103
46
|
await Game.init({ gameName: "Test Game", isDevMode: true });
|
|
104
47
|
});
|
|
105
48
|
afterEach(() => {
|
|
106
|
-
// Reset game state after each test to ensure clean state
|
|
107
49
|
Game._resetForTesting();
|
|
108
|
-
|
|
109
|
-
MockStorage.reset();
|
|
110
|
-
// Restore original Storage methods
|
|
111
|
-
Storage.getValue = originalStorageMethods.getValue;
|
|
112
|
-
Storage.setValue = originalStorageMethods.setValue;
|
|
113
|
-
Storage.getState = originalStorageMethods.getState;
|
|
114
|
-
Storage.setState = originalStorageMethods.setState;
|
|
50
|
+
teardownMockStorage();
|
|
115
51
|
});
|
|
116
52
|
describe("Initialization", () => {
|
|
117
53
|
test("sets default options on init", () => {
|