@stencil/store 1.5.0-0 → 2.0.1
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/LICENSE +23 -0
- 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/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright 2015-present Drifty Co.
|
|
2
|
+
http://drifty.com/
|
|
3
|
+
|
|
4
|
+
MIT License
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
a copy of this software and associated documentation files (the
|
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
+
the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be
|
|
15
|
+
included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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.1",
|
|
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
|
}
|