shablon 0.0.1-rc.6 → 0.0.1-rc.8
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 +0 -2
- package/package.json +1 -1
- package/src/state.js +37 -24
- package/src/template.js +4 -2
package/README.md
CHANGED
|
@@ -174,8 +174,6 @@ data.activity = "rest"
|
|
|
174
174
|
Watch registers a callback function that fires on initialization and
|
|
175
175
|
every time any of its evaluated `store` reactive properties change.
|
|
176
176
|
|
|
177
|
-
Note that for reactive getters, initially the watch `trackedFunc` will be invoked twice because we register a second internal watcher to cache the getter value.
|
|
178
|
-
|
|
179
177
|
It returns a "watcher" object that could be used to `unwatch()` the registered listener.
|
|
180
178
|
|
|
181
179
|
_Optionally also accepts a second callback function that is excluded from the evaluated
|
package/package.json
CHANGED
package/src/state.js
CHANGED
|
@@ -12,7 +12,7 @@ let pathsSubsSym = Symbol();
|
|
|
12
12
|
let unwatchedSym = Symbol();
|
|
13
13
|
let onRemoveSym = Symbol();
|
|
14
14
|
let skipSym = Symbol();
|
|
15
|
-
let
|
|
15
|
+
let detachedSym = Symbol();
|
|
16
16
|
|
|
17
17
|
let pathSeparator = "/";
|
|
18
18
|
|
|
@@ -234,28 +234,26 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
234
234
|
// if not invoked inside a watch function, call the original
|
|
235
235
|
// getter to ensure that an up-to-date value is computed
|
|
236
236
|
if (!activeWatcher) {
|
|
237
|
-
return descriptors[prop]
|
|
237
|
+
return descriptors[prop].get.call(obj);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
getterProp = prop;
|
|
241
241
|
|
|
242
242
|
// replace with an internal property so that reactive statements can be cached
|
|
243
243
|
prop = "@@" + prop;
|
|
244
|
-
Object.defineProperty(obj, prop, { writable: true, enumerable: false });
|
|
245
244
|
}
|
|
246
245
|
|
|
247
|
-
//
|
|
246
|
+
// detached child?
|
|
247
|
+
let isDetached;
|
|
248
248
|
if (!obj[skipSym] && obj[parentSym]) {
|
|
249
249
|
let props = [];
|
|
250
250
|
let activeObj = obj;
|
|
251
251
|
|
|
252
|
-
let isEvicted = false;
|
|
253
|
-
|
|
254
252
|
// travel up to the root proxy
|
|
255
253
|
// (aka. x.a.b*.c -> x)
|
|
256
254
|
while (activeObj?.[parentSym]) {
|
|
257
|
-
if (activeObj[
|
|
258
|
-
|
|
255
|
+
if (activeObj[detachedSym]) {
|
|
256
|
+
isDetached = true;
|
|
259
257
|
}
|
|
260
258
|
|
|
261
259
|
props.push(activeObj[parentSym][1]);
|
|
@@ -268,9 +266,9 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
268
266
|
// (we want: x.a.b(old).c -> x -> x.a.b(new).c)
|
|
269
267
|
//
|
|
270
268
|
// note: this technically could "leak" but for our case it should be fine
|
|
271
|
-
// because the
|
|
269
|
+
// because the detached object will become again garbage collectable
|
|
272
270
|
// once the related watcher(s) are removed
|
|
273
|
-
if (
|
|
271
|
+
if (isDetached) {
|
|
274
272
|
for (let i = props.length - 1; i >= 0; i--) {
|
|
275
273
|
activeObj[skipSym] = true;
|
|
276
274
|
let item = activeObj?.[props[i]];
|
|
@@ -321,16 +319,21 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
321
319
|
|
|
322
320
|
let propPaths = [currentPath];
|
|
323
321
|
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
// and
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
322
|
+
// ---
|
|
323
|
+
// NB! Disable for now because of the nonblocking and delayed
|
|
324
|
+
// nature of the current MutationObserver implementation for the `onunmount` hook
|
|
325
|
+
// leading to unexpected and delayed watch calls in methods like `Array.map`.
|
|
326
|
+
// ---
|
|
327
|
+
// if (isDetached) {
|
|
328
|
+
// // always construct all parent paths ("x.a.b.c" => ["a", "a.b", "a.b.c"])
|
|
329
|
+
// // because a store child object can be passed as argument to a function
|
|
330
|
+
// // and in that case the parents proxy get trap will not be invoked,
|
|
331
|
+
// // and their path will not be registered
|
|
332
|
+
// let parts = currentPath.split(pathSeparator);
|
|
333
|
+
// while (parts.pop() && parts.length) {
|
|
334
|
+
// propPaths.push(parts.join(pathSeparator));
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
334
337
|
|
|
335
338
|
// initialize a watcher paths tracking set (if not already)
|
|
336
339
|
activeWatcher[pathsSubsSym] = activeWatcher[pathsSubsSym] || new Set();
|
|
@@ -360,14 +363,24 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
360
363
|
|
|
361
364
|
let getFunc = descriptors[getterProp].get.bind(obj);
|
|
362
365
|
|
|
363
|
-
let getWatcher = watch(getFunc, (result) =>
|
|
366
|
+
let getWatcher = watch(getFunc, (result) => {
|
|
367
|
+
if (!obj.hasOwnProperty(prop)) {
|
|
368
|
+
Object.defineProperty(obj, prop, {
|
|
369
|
+
writable: true,
|
|
370
|
+
enumerable: false,
|
|
371
|
+
value: result,
|
|
372
|
+
});
|
|
373
|
+
} else {
|
|
374
|
+
receiver[prop] = result;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
364
377
|
|
|
365
378
|
getWatcher[onRemoveSym] = () => {
|
|
366
379
|
descriptors[getterProp]?.watchers?.delete(watcherId);
|
|
367
380
|
};
|
|
368
381
|
|
|
369
382
|
// update with the cached get value after the above watch initialization
|
|
370
|
-
propVal = obj[prop]
|
|
383
|
+
propVal = obj[prop];
|
|
371
384
|
}
|
|
372
385
|
}
|
|
373
386
|
|
|
@@ -381,9 +394,9 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
381
394
|
|
|
382
395
|
let oldValue = obj[prop];
|
|
383
396
|
|
|
384
|
-
// mark as "
|
|
397
|
+
// mark as "detached" in case a proxy child object/array is being replaced
|
|
385
398
|
if (oldValue?.[parentSym]) {
|
|
386
|
-
oldValue[
|
|
399
|
+
oldValue[detachedSym] = true;
|
|
387
400
|
}
|
|
388
401
|
|
|
389
402
|
// update the stored parent reference in case of index change (e.g. unshift)
|
package/src/template.js
CHANGED
|
@@ -117,10 +117,12 @@ function tag(tagName, attrs = {}, ...children) {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
const result = val(el, attr);
|
|
121
|
+
|
|
120
122
|
if (useSetAttr) {
|
|
121
|
-
el.setAttribute(attr,
|
|
123
|
+
el.setAttribute(attr, result);
|
|
122
124
|
} else {
|
|
123
|
-
el[attr] =
|
|
125
|
+
el[attr] = result;
|
|
124
126
|
}
|
|
125
127
|
});
|
|
126
128
|
}
|