shablon 0.0.1-rc.5 → 0.0.1-rc.7
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/package.json +1 -1
- package/src/state.js +44 -37
- package/src/template.js +4 -2
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
|
|
|
@@ -228,18 +228,33 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
228
228
|
return obj;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
//
|
|
231
|
+
// getter?
|
|
232
|
+
let getterProp;
|
|
233
|
+
if (descriptors[prop]?.get) {
|
|
234
|
+
// if not invoked inside a watch function, call the original
|
|
235
|
+
// getter to ensure that an up-to-date value is computed
|
|
236
|
+
if (!activeWatcher) {
|
|
237
|
+
return descriptors[prop]?.get?.call(obj);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
getterProp = prop;
|
|
241
|
+
|
|
242
|
+
// replace with an internal property so that reactive statements can be cached
|
|
243
|
+
prop = "@@" + prop;
|
|
244
|
+
Object.defineProperty(obj, prop, { writable: true, enumerable: false });
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// detached child?
|
|
248
|
+
let isDetached;
|
|
232
249
|
if (!obj[skipSym] && obj[parentSym]) {
|
|
233
250
|
let props = [];
|
|
234
251
|
let activeObj = obj;
|
|
235
252
|
|
|
236
|
-
let isEvicted = false;
|
|
237
|
-
|
|
238
253
|
// travel up to the root proxy
|
|
239
254
|
// (aka. x.a.b*.c -> x)
|
|
240
255
|
while (activeObj?.[parentSym]) {
|
|
241
|
-
if (activeObj[
|
|
242
|
-
|
|
256
|
+
if (activeObj[detachedSym]) {
|
|
257
|
+
isDetached = true;
|
|
243
258
|
}
|
|
244
259
|
|
|
245
260
|
props.push(activeObj[parentSym][1]);
|
|
@@ -252,9 +267,9 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
252
267
|
// (we want: x.a.b(old).c -> x -> x.a.b(new).c)
|
|
253
268
|
//
|
|
254
269
|
// note: this technically could "leak" but for our case it should be fine
|
|
255
|
-
// because the
|
|
270
|
+
// because the detached object will become again garbage collectable
|
|
256
271
|
// once the related watcher(s) are removed
|
|
257
|
-
if (
|
|
272
|
+
if (isDetached) {
|
|
258
273
|
for (let i = props.length - 1; i >= 0; i--) {
|
|
259
274
|
activeObj[skipSym] = true;
|
|
260
275
|
let item = activeObj?.[props[i]];
|
|
@@ -277,22 +292,6 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
277
292
|
}
|
|
278
293
|
}
|
|
279
294
|
|
|
280
|
-
// getter?
|
|
281
|
-
let getterProp;
|
|
282
|
-
if (descriptors[prop]?.get) {
|
|
283
|
-
// if not invoked inside a watch function, call the original
|
|
284
|
-
// getter to ensure that an up-to-date value is computed
|
|
285
|
-
if (!activeWatcher) {
|
|
286
|
-
return descriptors[prop]?.get?.call(obj);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
getterProp = prop;
|
|
290
|
-
|
|
291
|
-
// replace with an internal "@@prop" property so that
|
|
292
|
-
// reactive statements can be cached
|
|
293
|
-
prop = "@@" + prop;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
295
|
let propVal = obj[prop];
|
|
297
296
|
|
|
298
297
|
// directly return for functions (pop, push, etc.)
|
|
@@ -321,16 +320,21 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
321
320
|
|
|
322
321
|
let propPaths = [currentPath];
|
|
323
322
|
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
// and
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
323
|
+
// ---
|
|
324
|
+
// NB! Disable for now because of the nonblocking and delayed
|
|
325
|
+
// nature of the current MutationObserver implementation for the `onunmount` hook
|
|
326
|
+
// leading to unexpected and delayed watch calls in methods like `Array.map`.
|
|
327
|
+
// ---
|
|
328
|
+
// if (isDetached) {
|
|
329
|
+
// // always construct all parent paths ("x.a.b.c" => ["a", "a.b", "a.b.c"])
|
|
330
|
+
// // because a store child object can be passed as argument to a function
|
|
331
|
+
// // and in that case the parents proxy get trap will not be invoked,
|
|
332
|
+
// // and their path will not be registered
|
|
333
|
+
// let parts = currentPath.split(pathSeparator);
|
|
334
|
+
// while (parts.pop() && parts.length) {
|
|
335
|
+
// propPaths.push(parts.join(pathSeparator));
|
|
336
|
+
// }
|
|
337
|
+
// }
|
|
334
338
|
|
|
335
339
|
// initialize a watcher paths tracking set (if not already)
|
|
336
340
|
activeWatcher[pathsSubsSym] = activeWatcher[pathsSubsSym] || new Set();
|
|
@@ -360,11 +364,14 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
360
364
|
|
|
361
365
|
let getFunc = descriptors[getterProp].get.bind(obj);
|
|
362
366
|
|
|
363
|
-
let getWatcher = watch(() => (receiver[prop] =
|
|
367
|
+
let getWatcher = watch(getFunc, (result) => (receiver[prop] = result));
|
|
364
368
|
|
|
365
369
|
getWatcher[onRemoveSym] = () => {
|
|
366
370
|
descriptors[getterProp]?.watchers?.delete(watcherId);
|
|
367
371
|
};
|
|
372
|
+
|
|
373
|
+
// update with the cached get value after the above watch initialization
|
|
374
|
+
propVal = obj[prop]
|
|
368
375
|
}
|
|
369
376
|
}
|
|
370
377
|
|
|
@@ -378,9 +385,9 @@ function createProxy(obj, pathWatcherIds) {
|
|
|
378
385
|
|
|
379
386
|
let oldValue = obj[prop];
|
|
380
387
|
|
|
381
|
-
// mark as "
|
|
388
|
+
// mark as "detached" in case a proxy child object/array is being replaced
|
|
382
389
|
if (oldValue?.[parentSym]) {
|
|
383
|
-
oldValue[
|
|
390
|
+
oldValue[detachedSym] = true;
|
|
384
391
|
}
|
|
385
392
|
|
|
386
393
|
// 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
|
}
|