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 CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.1-rc.5",
2
+ "version": "0.0.1-rc.7",
3
3
  "name": "shablon",
4
4
  "description": "No-build JavaScript framework for Single-page applications",
5
5
  "author": "Gani Georgiev",
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 evictedSym = Symbol();
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
- // evicted child?
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[evictedSym]) {
242
- isEvicted = true;
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 evicted object will become again garbage collectable
270
+ // because the detached object will become again garbage collectable
256
271
  // once the related watcher(s) are removed
257
- if (isEvicted) {
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
- // always construct all parent paths ("x.a.b.c" => ["a", "a.b", "a.b.c"])
325
- // because a store child object can be passed as argument to a function
326
- // and in that case the parents proxy get trap will not be invoked,
327
- // and their path will not be registered
328
- if (obj[parentSym]) {
329
- let parts = currentPath.split(pathSeparator);
330
- while (parts.pop() && parts.length) {
331
- propPaths.push(parts.join(pathSeparator));
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] = getFunc()));
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 "evicted" in case a proxy child object/array is being replaced
388
+ // mark as "detached" in case a proxy child object/array is being replaced
382
389
  if (oldValue?.[parentSym]) {
383
- oldValue[evictedSym] = true;
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, val(el));
123
+ el.setAttribute(attr, result);
122
124
  } else {
123
- el[attr] = val(el);
125
+ el[attr] = result;
124
126
  }
125
127
  });
126
128
  }