@stencil/store 2.2.1 → 2.2.2
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/index.cjs +109 -21
- package/dist/index.js +90 -21
- package/dist/utils.d.ts +1 -1
- package/package.json +14 -13
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var StencilCore = require('@stencil/core');
|
|
4
|
+
|
|
5
|
+
function _interopNamespaceDefault(e) {
|
|
6
|
+
var n = Object.create(null);
|
|
7
|
+
if (e) {
|
|
8
|
+
Object.keys(e).forEach(function (k) {
|
|
9
|
+
if (k !== 'default') {
|
|
10
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
11
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return e[k]; }
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
n.default = e;
|
|
19
|
+
return Object.freeze(n);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var StencilCore__namespace = /*#__PURE__*/_interopNamespaceDefault(StencilCore);
|
|
4
23
|
|
|
5
24
|
const appendToMap = (map, propName, value) => {
|
|
6
|
-
|
|
7
|
-
if (!
|
|
8
|
-
|
|
25
|
+
let refs = map.get(propName);
|
|
26
|
+
if (!refs) {
|
|
27
|
+
refs = [];
|
|
28
|
+
map.set(propName, refs);
|
|
9
29
|
}
|
|
10
|
-
|
|
11
|
-
|
|
30
|
+
if (!refs.some((ref) => ref.deref() === value)) {
|
|
31
|
+
refs.push(new WeakRef(value));
|
|
12
32
|
}
|
|
13
33
|
};
|
|
14
34
|
const debounce = (fn, ms) => {
|
|
@@ -36,33 +56,54 @@ const debounce = (fn, ms) => {
|
|
|
36
56
|
const isConnected = (maybeElement) => !('isConnected' in maybeElement) || maybeElement.isConnected;
|
|
37
57
|
const cleanupElements = debounce((map) => {
|
|
38
58
|
for (let key of map.keys()) {
|
|
39
|
-
|
|
59
|
+
const refs = map.get(key).filter((ref) => {
|
|
60
|
+
const elm = ref.deref();
|
|
61
|
+
return elm && isConnected(elm);
|
|
62
|
+
});
|
|
63
|
+
map.set(key, refs);
|
|
40
64
|
}
|
|
41
65
|
}, 2_000);
|
|
66
|
+
const core = StencilCore__namespace;
|
|
67
|
+
const forceUpdate = core.forceUpdate;
|
|
68
|
+
const getRenderingRef = core.getRenderingRef;
|
|
42
69
|
const stencilSubscription = () => {
|
|
43
|
-
if (typeof
|
|
70
|
+
if (typeof getRenderingRef !== 'function' || typeof forceUpdate !== 'function') {
|
|
44
71
|
// If we are not in a stencil project, we do nothing.
|
|
45
72
|
// This function is not really exported by @stencil/core.
|
|
46
73
|
return {};
|
|
47
74
|
}
|
|
75
|
+
const ensureForceUpdate = forceUpdate;
|
|
76
|
+
const ensureGetRenderingRef = getRenderingRef;
|
|
48
77
|
const elmsToUpdate = new Map();
|
|
49
78
|
return {
|
|
50
79
|
dispose: () => elmsToUpdate.clear(),
|
|
51
80
|
get: (propName) => {
|
|
52
|
-
const elm =
|
|
81
|
+
const elm = ensureGetRenderingRef();
|
|
53
82
|
if (elm) {
|
|
54
83
|
appendToMap(elmsToUpdate, propName, elm);
|
|
55
84
|
}
|
|
56
85
|
},
|
|
57
86
|
set: (propName) => {
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
|
|
87
|
+
const refs = elmsToUpdate.get(propName);
|
|
88
|
+
if (refs) {
|
|
89
|
+
const nextRefs = refs.filter((ref) => {
|
|
90
|
+
const elm = ref.deref();
|
|
91
|
+
if (!elm)
|
|
92
|
+
return false;
|
|
93
|
+
return ensureForceUpdate(elm);
|
|
94
|
+
});
|
|
95
|
+
elmsToUpdate.set(propName, nextRefs);
|
|
61
96
|
}
|
|
62
97
|
cleanupElements(elmsToUpdate);
|
|
63
98
|
},
|
|
64
99
|
reset: () => {
|
|
65
|
-
elmsToUpdate.forEach((
|
|
100
|
+
elmsToUpdate.forEach((refs) => {
|
|
101
|
+
refs.forEach((ref) => {
|
|
102
|
+
const elm = ref.deref();
|
|
103
|
+
if (elm)
|
|
104
|
+
ensureForceUpdate(elm);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
66
107
|
cleanupElements(elmsToUpdate);
|
|
67
108
|
},
|
|
68
109
|
};
|
|
@@ -70,8 +111,11 @@ const stencilSubscription = () => {
|
|
|
70
111
|
|
|
71
112
|
const unwrap = (val) => (typeof val === 'function' ? val() : val);
|
|
72
113
|
const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => {
|
|
73
|
-
const
|
|
74
|
-
|
|
114
|
+
const resolveDefaultState = () => (unwrap(defaultState) ?? {});
|
|
115
|
+
const initialState = resolveDefaultState();
|
|
116
|
+
let states = new Map(Object.entries(initialState));
|
|
117
|
+
const proxyAvailable = typeof Proxy !== 'undefined';
|
|
118
|
+
const plainState = proxyAvailable ? null : {};
|
|
75
119
|
const handlers = {
|
|
76
120
|
dispose: [],
|
|
77
121
|
get: [],
|
|
@@ -83,7 +127,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
83
127
|
const reset = () => {
|
|
84
128
|
// When resetting the state, the default state may be a function - unwrap it to invoke it.
|
|
85
129
|
// otherwise, the state won't be properly reset
|
|
86
|
-
states = new Map(Object.entries(
|
|
130
|
+
states = new Map(Object.entries(resolveDefaultState()));
|
|
131
|
+
if (!proxyAvailable) {
|
|
132
|
+
syncPlainStateKeys();
|
|
133
|
+
}
|
|
87
134
|
handlers.reset.forEach((cb) => cb());
|
|
88
135
|
};
|
|
89
136
|
const dispose = () => {
|
|
@@ -100,12 +147,14 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
100
147
|
const oldValue = states.get(propName);
|
|
101
148
|
if (shouldUpdate(value, oldValue, propName)) {
|
|
102
149
|
states.set(propName, value);
|
|
150
|
+
if (!proxyAvailable) {
|
|
151
|
+
ensurePlainProperty(propName);
|
|
152
|
+
}
|
|
103
153
|
handlers.set.forEach((cb) => cb(propName, value, oldValue));
|
|
104
154
|
}
|
|
105
155
|
};
|
|
106
|
-
const state = (
|
|
107
|
-
? {
|
|
108
|
-
: new Proxy(unwrappedState, {
|
|
156
|
+
const state = (proxyAvailable
|
|
157
|
+
? new Proxy(initialState, {
|
|
109
158
|
get(_, propName) {
|
|
110
159
|
return get(propName);
|
|
111
160
|
},
|
|
@@ -125,7 +174,11 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
125
174
|
set(propName, value);
|
|
126
175
|
return true;
|
|
127
176
|
},
|
|
128
|
-
})
|
|
177
|
+
})
|
|
178
|
+
: (() => {
|
|
179
|
+
syncPlainStateKeys();
|
|
180
|
+
return plainState;
|
|
181
|
+
})());
|
|
129
182
|
const on = (eventName, callback) => {
|
|
130
183
|
handlers[eventName].push(callback);
|
|
131
184
|
return () => {
|
|
@@ -138,7 +191,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
138
191
|
cb(newValue);
|
|
139
192
|
}
|
|
140
193
|
};
|
|
141
|
-
const resetHandler = () =>
|
|
194
|
+
const resetHandler = () => {
|
|
195
|
+
const snapshot = resolveDefaultState();
|
|
196
|
+
cb(snapshot[propName]);
|
|
197
|
+
};
|
|
142
198
|
// Register the handlers
|
|
143
199
|
const unSet = on('set', setHandler);
|
|
144
200
|
const unReset = on('reset', resetHandler);
|
|
@@ -181,6 +237,38 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
181
237
|
changeListeners.delete(listener);
|
|
182
238
|
}
|
|
183
239
|
};
|
|
240
|
+
function ensurePlainProperty(key) {
|
|
241
|
+
if (proxyAvailable || !plainState) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (Object.prototype.hasOwnProperty.call(plainState, key)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
Object.defineProperty(plainState, key, {
|
|
248
|
+
configurable: true,
|
|
249
|
+
enumerable: true,
|
|
250
|
+
get() {
|
|
251
|
+
return get(key);
|
|
252
|
+
},
|
|
253
|
+
set(value) {
|
|
254
|
+
set(key, value);
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function syncPlainStateKeys() {
|
|
259
|
+
if (proxyAvailable || !plainState) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const knownKeys = new Set(states.keys());
|
|
263
|
+
for (const key of Object.keys(plainState)) {
|
|
264
|
+
if (!knownKeys.has(key)) {
|
|
265
|
+
delete plainState[key];
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
for (const key of knownKeys) {
|
|
269
|
+
ensurePlainProperty(key);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
184
272
|
return {
|
|
185
273
|
state,
|
|
186
274
|
get,
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as StencilCore from '@stencil/core';
|
|
2
2
|
|
|
3
3
|
const appendToMap = (map, propName, value) => {
|
|
4
|
-
|
|
5
|
-
if (!
|
|
6
|
-
|
|
4
|
+
let refs = map.get(propName);
|
|
5
|
+
if (!refs) {
|
|
6
|
+
refs = [];
|
|
7
|
+
map.set(propName, refs);
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
if (!refs.some((ref) => ref.deref() === value)) {
|
|
10
|
+
refs.push(new WeakRef(value));
|
|
10
11
|
}
|
|
11
12
|
};
|
|
12
13
|
const debounce = (fn, ms) => {
|
|
@@ -34,33 +35,54 @@ const debounce = (fn, ms) => {
|
|
|
34
35
|
const isConnected = (maybeElement) => !('isConnected' in maybeElement) || maybeElement.isConnected;
|
|
35
36
|
const cleanupElements = debounce((map) => {
|
|
36
37
|
for (let key of map.keys()) {
|
|
37
|
-
|
|
38
|
+
const refs = map.get(key).filter((ref) => {
|
|
39
|
+
const elm = ref.deref();
|
|
40
|
+
return elm && isConnected(elm);
|
|
41
|
+
});
|
|
42
|
+
map.set(key, refs);
|
|
38
43
|
}
|
|
39
44
|
}, 2_000);
|
|
45
|
+
const core = StencilCore;
|
|
46
|
+
const forceUpdate = core.forceUpdate;
|
|
47
|
+
const getRenderingRef = core.getRenderingRef;
|
|
40
48
|
const stencilSubscription = () => {
|
|
41
|
-
if (typeof getRenderingRef !== 'function') {
|
|
49
|
+
if (typeof getRenderingRef !== 'function' || typeof forceUpdate !== 'function') {
|
|
42
50
|
// If we are not in a stencil project, we do nothing.
|
|
43
51
|
// This function is not really exported by @stencil/core.
|
|
44
52
|
return {};
|
|
45
53
|
}
|
|
54
|
+
const ensureForceUpdate = forceUpdate;
|
|
55
|
+
const ensureGetRenderingRef = getRenderingRef;
|
|
46
56
|
const elmsToUpdate = new Map();
|
|
47
57
|
return {
|
|
48
58
|
dispose: () => elmsToUpdate.clear(),
|
|
49
59
|
get: (propName) => {
|
|
50
|
-
const elm =
|
|
60
|
+
const elm = ensureGetRenderingRef();
|
|
51
61
|
if (elm) {
|
|
52
62
|
appendToMap(elmsToUpdate, propName, elm);
|
|
53
63
|
}
|
|
54
64
|
},
|
|
55
65
|
set: (propName) => {
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
58
|
-
|
|
66
|
+
const refs = elmsToUpdate.get(propName);
|
|
67
|
+
if (refs) {
|
|
68
|
+
const nextRefs = refs.filter((ref) => {
|
|
69
|
+
const elm = ref.deref();
|
|
70
|
+
if (!elm)
|
|
71
|
+
return false;
|
|
72
|
+
return ensureForceUpdate(elm);
|
|
73
|
+
});
|
|
74
|
+
elmsToUpdate.set(propName, nextRefs);
|
|
59
75
|
}
|
|
60
76
|
cleanupElements(elmsToUpdate);
|
|
61
77
|
},
|
|
62
78
|
reset: () => {
|
|
63
|
-
elmsToUpdate.forEach((
|
|
79
|
+
elmsToUpdate.forEach((refs) => {
|
|
80
|
+
refs.forEach((ref) => {
|
|
81
|
+
const elm = ref.deref();
|
|
82
|
+
if (elm)
|
|
83
|
+
ensureForceUpdate(elm);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
64
86
|
cleanupElements(elmsToUpdate);
|
|
65
87
|
},
|
|
66
88
|
};
|
|
@@ -68,8 +90,11 @@ const stencilSubscription = () => {
|
|
|
68
90
|
|
|
69
91
|
const unwrap = (val) => (typeof val === 'function' ? val() : val);
|
|
70
92
|
const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => {
|
|
71
|
-
const
|
|
72
|
-
|
|
93
|
+
const resolveDefaultState = () => (unwrap(defaultState) ?? {});
|
|
94
|
+
const initialState = resolveDefaultState();
|
|
95
|
+
let states = new Map(Object.entries(initialState));
|
|
96
|
+
const proxyAvailable = typeof Proxy !== 'undefined';
|
|
97
|
+
const plainState = proxyAvailable ? null : {};
|
|
73
98
|
const handlers = {
|
|
74
99
|
dispose: [],
|
|
75
100
|
get: [],
|
|
@@ -81,7 +106,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
81
106
|
const reset = () => {
|
|
82
107
|
// When resetting the state, the default state may be a function - unwrap it to invoke it.
|
|
83
108
|
// otherwise, the state won't be properly reset
|
|
84
|
-
states = new Map(Object.entries(
|
|
109
|
+
states = new Map(Object.entries(resolveDefaultState()));
|
|
110
|
+
if (!proxyAvailable) {
|
|
111
|
+
syncPlainStateKeys();
|
|
112
|
+
}
|
|
85
113
|
handlers.reset.forEach((cb) => cb());
|
|
86
114
|
};
|
|
87
115
|
const dispose = () => {
|
|
@@ -98,12 +126,14 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
98
126
|
const oldValue = states.get(propName);
|
|
99
127
|
if (shouldUpdate(value, oldValue, propName)) {
|
|
100
128
|
states.set(propName, value);
|
|
129
|
+
if (!proxyAvailable) {
|
|
130
|
+
ensurePlainProperty(propName);
|
|
131
|
+
}
|
|
101
132
|
handlers.set.forEach((cb) => cb(propName, value, oldValue));
|
|
102
133
|
}
|
|
103
134
|
};
|
|
104
|
-
const state = (
|
|
105
|
-
? {
|
|
106
|
-
: new Proxy(unwrappedState, {
|
|
135
|
+
const state = (proxyAvailable
|
|
136
|
+
? new Proxy(initialState, {
|
|
107
137
|
get(_, propName) {
|
|
108
138
|
return get(propName);
|
|
109
139
|
},
|
|
@@ -123,7 +153,11 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
123
153
|
set(propName, value);
|
|
124
154
|
return true;
|
|
125
155
|
},
|
|
126
|
-
})
|
|
156
|
+
})
|
|
157
|
+
: (() => {
|
|
158
|
+
syncPlainStateKeys();
|
|
159
|
+
return plainState;
|
|
160
|
+
})());
|
|
127
161
|
const on = (eventName, callback) => {
|
|
128
162
|
handlers[eventName].push(callback);
|
|
129
163
|
return () => {
|
|
@@ -136,7 +170,10 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
136
170
|
cb(newValue);
|
|
137
171
|
}
|
|
138
172
|
};
|
|
139
|
-
const resetHandler = () =>
|
|
173
|
+
const resetHandler = () => {
|
|
174
|
+
const snapshot = resolveDefaultState();
|
|
175
|
+
cb(snapshot[propName]);
|
|
176
|
+
};
|
|
140
177
|
// Register the handlers
|
|
141
178
|
const unSet = on('set', setHandler);
|
|
142
179
|
const unReset = on('reset', resetHandler);
|
|
@@ -179,6 +216,38 @@ const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) =>
|
|
|
179
216
|
changeListeners.delete(listener);
|
|
180
217
|
}
|
|
181
218
|
};
|
|
219
|
+
function ensurePlainProperty(key) {
|
|
220
|
+
if (proxyAvailable || !plainState) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (Object.prototype.hasOwnProperty.call(plainState, key)) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
Object.defineProperty(plainState, key, {
|
|
227
|
+
configurable: true,
|
|
228
|
+
enumerable: true,
|
|
229
|
+
get() {
|
|
230
|
+
return get(key);
|
|
231
|
+
},
|
|
232
|
+
set(value) {
|
|
233
|
+
set(key, value);
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function syncPlainStateKeys() {
|
|
238
|
+
if (proxyAvailable || !plainState) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const knownKeys = new Set(states.keys());
|
|
242
|
+
for (const key of Object.keys(plainState)) {
|
|
243
|
+
if (!knownKeys.has(key)) {
|
|
244
|
+
delete plainState[key];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const key of knownKeys) {
|
|
248
|
+
ensurePlainProperty(key);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
182
251
|
return {
|
|
183
252
|
state,
|
|
184
253
|
get,
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const appendToMap: <K, V>(map: Map<K, V[]>, propName: K, value: V) => void;
|
|
1
|
+
export declare const appendToMap: <K, V extends Object>(map: Map<K, WeakRef<V>[]>, propName: K, value: V) => void;
|
|
2
2
|
export declare const debounce: <T extends (...args: any[]) => any>(fn: T, ms: number) => ((...args: Parameters<T>) => void);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stencil/store",
|
|
3
3
|
"author": "StencilJS Team",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.2",
|
|
5
5
|
"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.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://stenciljs.com/docs/stencil-store",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"npm": ">=6.0.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"build": "run-s build
|
|
37
|
-
"build.clean": "
|
|
36
|
+
"build": "run-s build.clean build.rollup",
|
|
37
|
+
"build.clean": "rimraf dist",
|
|
38
38
|
"build.rollup": "rollup -c rollup.config.js",
|
|
39
39
|
"prettier": "npm run prettier.base -- --write",
|
|
40
|
-
"prettier.base": "prettier --cache
|
|
40
|
+
"prettier.base": "prettier --cache \"src/**/*.ts\"",
|
|
41
41
|
"prettier.dry-run": "npm run prettier.base -- --list-different",
|
|
42
42
|
"release": "np",
|
|
43
43
|
"test": "run-s test.*",
|
|
@@ -53,16 +53,17 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@ionic/prettier-config": "^4.0.0",
|
|
56
|
-
"@rollup/plugin-typescript": "^12.
|
|
57
|
-
"@stencil/core": "^4.
|
|
58
|
-
"@types/node": "^24.
|
|
59
|
-
"@vitest/coverage-v8": "^
|
|
56
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
57
|
+
"@stencil/core": "^4.38.2",
|
|
58
|
+
"@types/node": "^24.9.2",
|
|
59
|
+
"@vitest/coverage-v8": "^4.0.5",
|
|
60
60
|
"np": "^10.2.0",
|
|
61
|
-
"npm-run-all2": "^8.0.
|
|
62
|
-
"prettier": "^3.
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
61
|
+
"npm-run-all2": "^8.0.4",
|
|
62
|
+
"prettier": "^3.6.2",
|
|
63
|
+
"rimraf": "^6.0.1",
|
|
64
|
+
"rollup": "^4.52.5",
|
|
65
|
+
"typescript": "~5.9.3",
|
|
66
|
+
"vitest": "^4.0.5"
|
|
66
67
|
},
|
|
67
68
|
"prettier": "@ionic/prettier-config"
|
|
68
69
|
}
|