@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 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
- let states = new Map(Object.entries(defaultState !== null && defaultState !== void 0 ? defaultState : {}));
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
- states = new Map(Object.entries(defaultState !== null && defaultState !== void 0 ? defaultState : {}));
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(defaultState, {
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
- const unReset = on('reset', () => cb(defaultState[propName]));
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
- let states = new Map(Object.entries(defaultState !== null && defaultState !== void 0 ? defaultState : {}));
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
- states = new Map(Object.entries(defaultState !== null && defaultState !== void 0 ? defaultState : {}));
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(defaultState, {
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
- const unReset = on('reset', () => cb(defaultState[propName]));
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();
@@ -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, shouldUpdate?: (newV: any, oldValue: any, prop: keyof T) => boolean) => ObservableMap<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": "1.5.0-0",
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
- "lint.prettier": "prettier --write 'src/**/*.ts'",
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 test.prettier",
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": ">=1.9.0"
33
+ "@stencil/core": ">=2.0.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@stencil/core": "^2.8.0",
37
- "@types/jest": "^26",
38
- "jest": "^26",
39
- "jest-cli": "^26",
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": "^26",
44
- "typescript": "^4.1.5"
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
  }