@stencil/store 1.5.0 → 2.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/README.md +74 -1
- package/dist/index.js +11 -4
- package/dist/index.mjs +11 -4
- package/dist/observable-map.d.ts +3 -1
- package/package.json +14 -10
package/README.md
CHANGED
|
@@ -77,9 +77,53 @@ const MyGlobalCounter = () => {
|
|
|
77
77
|
|
|
78
78
|
## API
|
|
79
79
|
|
|
80
|
-
### `createStore<T>(initialState?: T, shouldUpdate?)`
|
|
80
|
+
### `createStore<T>(initialState?: T | (() => T), shouldUpdate?)`
|
|
81
81
|
|
|
82
82
|
Create a new store with the given initial state. The type is inferred from `initialState`, or can be passed as the generic type `T`.
|
|
83
|
+
`initialState` can be a function that returns the actual initial state. This feature is just in case you have deep objects that mutate
|
|
84
|
+
as otherwise we cannot keep track of those.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const { reset, state } = createStore(() => ({
|
|
88
|
+
pageA: {
|
|
89
|
+
count: 1
|
|
90
|
+
},
|
|
91
|
+
pageB: {
|
|
92
|
+
count: 1
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
state.pageA.count = 2;
|
|
97
|
+
state.pageB.count = 3;
|
|
98
|
+
|
|
99
|
+
reset();
|
|
100
|
+
|
|
101
|
+
state.pageA.count; // 1
|
|
102
|
+
state.pageB.count; // 1
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Please, bear in mind that the object needs to be created inside the function, not just referenced. The following example won't work
|
|
106
|
+
as you might want it to, as the returned object is always the same one.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const object = {
|
|
110
|
+
pageA: {
|
|
111
|
+
count: 1
|
|
112
|
+
},
|
|
113
|
+
pageB: {
|
|
114
|
+
count: 1
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const { reset, state } = createStore(() => object);
|
|
118
|
+
|
|
119
|
+
state.pageA.count = 2;
|
|
120
|
+
state.pageB.count = 3;
|
|
121
|
+
|
|
122
|
+
reset();
|
|
123
|
+
|
|
124
|
+
state.pageA.count; // 2
|
|
125
|
+
state.pageB.count; // 3
|
|
126
|
+
```
|
|
83
127
|
|
|
84
128
|
By default, store performs a exact comparison (`===`) between the new value, and the previous one in order to prevent unnecessary rerenders, however, this behaviour can be changed by providing a `shouldUpdate` function through the second argument. When this function returns `false`, the value won't be updated. By providing a custom `shouldUpdate()` function, applications can create their own fine-grained change detection logic, beyond the default `===`. This may be useful for certain use-cases to avoid any expensive re-rendering.
|
|
85
129
|
|
|
@@ -121,6 +165,35 @@ Reset the store to its initial state.
|
|
|
121
165
|
|
|
122
166
|
Use the given subscriptions in the store. A subscription is an object that defines one or more of the properties `get`, `set` or `reset`.
|
|
123
167
|
|
|
168
|
+
```ts
|
|
169
|
+
const { reset, state, use } = createStore({ a: 1, b: 2});
|
|
170
|
+
|
|
171
|
+
const unlog = use({
|
|
172
|
+
get: (key) => {
|
|
173
|
+
console.log(`Someone's reading prop ${key}`);
|
|
174
|
+
},
|
|
175
|
+
set: (key, newValue, oldValue) => {
|
|
176
|
+
console.log(`Prop ${key} changed from ${oldValue} to ${newValue}`);
|
|
177
|
+
},
|
|
178
|
+
reset: () => {
|
|
179
|
+
console.log('Store got reset');
|
|
180
|
+
},
|
|
181
|
+
dispose: () => {
|
|
182
|
+
console.log('Store got disposed');
|
|
183
|
+
},
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
state.a; // Someone's reading prop a
|
|
187
|
+
state.b = 3; // Prop b changed from 2 to 3
|
|
188
|
+
reset(); // Store got reset
|
|
189
|
+
|
|
190
|
+
unlog();
|
|
191
|
+
|
|
192
|
+
state.a; // Nothing is logged
|
|
193
|
+
state.b = 5; // Nothing is logged
|
|
194
|
+
reset(); // Nothing is logged
|
|
195
|
+
```
|
|
196
|
+
|
|
124
197
|
#### `store.dispose()`
|
|
125
198
|
|
|
126
199
|
Resets the store and all the internal state of the store that should not survive between tests.
|
package/dist/index.js
CHANGED
|
@@ -70,8 +70,10 @@ const stencilSubscription = () => {
|
|
|
70
70
|
};
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
const unwrap = (val) => (typeof val === 'function' ? val() : val);
|
|
73
74
|
const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => {
|
|
74
|
-
|
|
75
|
+
const unwrappedState = unwrap(defaultState);
|
|
76
|
+
let states = new Map(Object.entries(unwrappedState !== null && unwrappedState !== void 0 ? unwrappedState : {}));
|
|
75
77
|
const handlers = {
|
|
76
78
|
dispose: [],
|
|
77
79
|
get: [],
|
|
@@ -79,7 +81,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
79
81
|
reset: [],
|
|
80
82
|
};
|
|
81
83
|
const reset = () => {
|
|
82
|
-
|
|
84
|
+
var _a;
|
|
85
|
+
// When resetting the state, the default state may be a function - unwrap it to invoke it.
|
|
86
|
+
// otherwise, the state won't be properly reset
|
|
87
|
+
states = new Map(Object.entries((_a = unwrap(defaultState)) !== null && _a !== void 0 ? _a : {}));
|
|
83
88
|
handlers.reset.forEach((cb) => cb());
|
|
84
89
|
};
|
|
85
90
|
const dispose = () => {
|
|
@@ -101,7 +106,7 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
101
106
|
};
|
|
102
107
|
const state = (typeof Proxy === 'undefined'
|
|
103
108
|
? {}
|
|
104
|
-
: new Proxy(
|
|
109
|
+
: new Proxy(unwrappedState, {
|
|
105
110
|
get(_, propName) {
|
|
106
111
|
return get(propName);
|
|
107
112
|
},
|
|
@@ -134,7 +139,9 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
134
139
|
cb(newValue);
|
|
135
140
|
}
|
|
136
141
|
});
|
|
137
|
-
|
|
142
|
+
// We need to unwrap the defaultState because it might be a function.
|
|
143
|
+
// Otherwise we might not be sending the right reset value.
|
|
144
|
+
const unReset = on('reset', () => cb(unwrap(defaultState)[propName]));
|
|
138
145
|
return () => {
|
|
139
146
|
unSet();
|
|
140
147
|
unReset();
|
package/dist/index.mjs
CHANGED
|
@@ -66,8 +66,10 @@ const stencilSubscription = () => {
|
|
|
66
66
|
};
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
const unwrap = (val) => (typeof val === 'function' ? val() : val);
|
|
69
70
|
const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => {
|
|
70
|
-
|
|
71
|
+
const unwrappedState = unwrap(defaultState);
|
|
72
|
+
let states = new Map(Object.entries(unwrappedState !== null && unwrappedState !== void 0 ? unwrappedState : {}));
|
|
71
73
|
const handlers = {
|
|
72
74
|
dispose: [],
|
|
73
75
|
get: [],
|
|
@@ -75,7 +77,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
75
77
|
reset: [],
|
|
76
78
|
};
|
|
77
79
|
const reset = () => {
|
|
78
|
-
|
|
80
|
+
var _a;
|
|
81
|
+
// When resetting the state, the default state may be a function - unwrap it to invoke it.
|
|
82
|
+
// otherwise, the state won't be properly reset
|
|
83
|
+
states = new Map(Object.entries((_a = unwrap(defaultState)) !== null && _a !== void 0 ? _a : {}));
|
|
79
84
|
handlers.reset.forEach((cb) => cb());
|
|
80
85
|
};
|
|
81
86
|
const dispose = () => {
|
|
@@ -97,7 +102,7 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
97
102
|
};
|
|
98
103
|
const state = (typeof Proxy === 'undefined'
|
|
99
104
|
? {}
|
|
100
|
-
: new Proxy(
|
|
105
|
+
: new Proxy(unwrappedState, {
|
|
101
106
|
get(_, propName) {
|
|
102
107
|
return get(propName);
|
|
103
108
|
},
|
|
@@ -130,7 +135,9 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
130
135
|
cb(newValue);
|
|
131
136
|
}
|
|
132
137
|
});
|
|
133
|
-
|
|
138
|
+
// We need to unwrap the defaultState because it might be a function.
|
|
139
|
+
// Otherwise we might not be sending the right reset value.
|
|
140
|
+
const unReset = on('reset', () => cb(unwrap(defaultState)[propName]));
|
|
134
141
|
return () => {
|
|
135
142
|
unSet();
|
|
136
143
|
unReset();
|
package/dist/observable-map.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ObservableMap } from './types';
|
|
2
|
+
declare type Invocable<T> = T | (() => T);
|
|
2
3
|
export declare const createObservableMap: <T extends {
|
|
3
4
|
[key: string]: any;
|
|
4
|
-
}>(defaultState?: T
|
|
5
|
+
}>(defaultState?: Invocable<T>, shouldUpdate?: (newV: any, oldValue: any, prop: keyof T) => boolean) => ObservableMap<T>;
|
|
6
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stencil/store",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Store is a lightweight shared state library by the StencilJS core team. Implements a simple key/value map that efficiently re-renders components when necessary.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "rm -rf dist && tsc -p . && npm run rollup",
|
|
10
|
-
"
|
|
10
|
+
"prettier": "prettier --write 'src/**/*.ts'",
|
|
11
|
+
"prettier.dry-run": "prettier --check 'src/**/*.ts'",
|
|
11
12
|
"release": "np",
|
|
12
13
|
"rollup": "rollup -c rollup.config.js",
|
|
13
14
|
"test": "jest",
|
|
14
|
-
"test.ci": "npm run test && npm run
|
|
15
|
-
"test.prettier": "prettier --check 'src/**/*.ts'",
|
|
15
|
+
"test.ci": "npm run test && npm run prettier.dry-run",
|
|
16
16
|
"version": "npm run build"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
@@ -30,21 +30,25 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"homepage": "https://stenciljs.com/docs/stencil-store",
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@stencil/core": ">=
|
|
33
|
+
"@stencil/core": ">=2.0.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@stencil/core": "^2.8.0",
|
|
37
|
-
"@types/jest": "^
|
|
38
|
-
"jest": "^
|
|
39
|
-
"jest-cli": "^
|
|
37
|
+
"@types/jest": "^28.1.1",
|
|
38
|
+
"jest": "^28.1.1",
|
|
39
|
+
"jest-cli": "^28.1.1",
|
|
40
40
|
"np": "^7.4.0",
|
|
41
41
|
"prettier": "^2.2.1",
|
|
42
42
|
"rollup": "^2.39.0",
|
|
43
|
-
"ts-jest": "^
|
|
44
|
-
"typescript": "^4.
|
|
43
|
+
"ts-jest": "^28.0.4",
|
|
44
|
+
"typescript": "^4.7.3"
|
|
45
45
|
},
|
|
46
46
|
"repository": {
|
|
47
47
|
"type": "git",
|
|
48
48
|
"url": "git://github.com/ionic-team/stencil-store.git"
|
|
49
|
+
},
|
|
50
|
+
"volta": {
|
|
51
|
+
"node": "16.15.0",
|
|
52
|
+
"npm": "8.11.0"
|
|
49
53
|
}
|
|
50
54
|
}
|