@tmbr/component 1.1.0 → 1.1.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.
Files changed (2) hide show
  1. package/index.js +43 -29
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { on, findOne, findAll, isArray, isDefined, isObject, isString, toJSON, traverse } from '@tmbr/utils';
2
2
  import { bindDirective, bindEvent } from './bind.js';
3
3
 
4
+ let cache;
4
5
  let queue;
5
6
  let scheduled = false;
6
7
 
7
8
  function enqueue(component) {
8
9
  queue ??= new Set();
9
10
  queue.add(component);
10
-
11
11
  if (scheduled) return;
12
12
  queueMicrotask(flush);
13
13
  scheduled = true;
@@ -20,19 +20,25 @@ function flush() {
20
20
  }
21
21
 
22
22
  function render(component) {
23
- const state = component.state;
24
- const proto = Object.getPrototypeOf(component);
25
-
26
- const context = proto === Component.prototype ? state : new Proxy(state, {
27
- has(target, key) {
28
- const own = Object.getOwnPropertyDescriptor(proto, key);
29
- return own?.get ? true : key in target;
30
- },
31
- get(target, key, receiver) {
32
- const own = Object.getOwnPropertyDescriptor(proto, key);
33
- return own?.get ? own.get.call(component) : Reflect.get(target, key, receiver);
34
- }
35
- });
23
+ cache ??= new WeakMap();
24
+ let context = cache.get(component);
25
+
26
+ if (!context) {
27
+ const proto = Object.getPrototypeOf(component);
28
+
29
+ context = proto !== Component.prototype ? new Proxy(component.state, {
30
+ has(target, key) {
31
+ const own = Object.getOwnPropertyDescriptor(proto, key);
32
+ return own?.get ? true : key in target;
33
+ },
34
+ get(target, key, receiver) {
35
+ const own = Object.getOwnPropertyDescriptor(proto, key);
36
+ return own?.get ? own.get.call(component) : Reflect.get(target, key, receiver);
37
+ }
38
+ }) : component.state;
39
+
40
+ cache.set(component, context);
41
+ }
36
42
 
37
43
  for (const apply of component.directives) apply(context);
38
44
  component.update?.(context);
@@ -86,17 +92,24 @@ export default class Component {
86
92
  : structuredClone(this.constructor.state);
87
93
 
88
94
  const instance = this;
89
- const reactive = (obj) => new Proxy(obj, {
90
- get(target, key, receiver) {
91
- const value = Reflect.get(target, key, receiver);
92
- return isArray(value) || isObject(value) ? reactive(value) : value;
93
- },
94
- set(target, key, value) {
95
- target[key] = value;
96
- enqueue(instance);
97
- return true;
98
- }
99
- });
95
+ const cache = new WeakMap();
96
+
97
+ const reactive = (obj) => {
98
+ if (cache.has(obj)) return cache.get(obj);
99
+ const proxy = new Proxy(obj, {
100
+ get(target, key, receiver) {
101
+ const value = Reflect.get(target, key, receiver);
102
+ return isArray(value) || isObject(value) ? reactive(value) : value;
103
+ },
104
+ set(target, key, value) {
105
+ target[key] = value;
106
+ enqueue(instance);
107
+ return true;
108
+ }
109
+ });
110
+ cache.set(obj, proxy);
111
+ return proxy;
112
+ };
100
113
 
101
114
  traverse(this.el, child => {
102
115
  for (const {name, value} of [...child.attributes]) {
@@ -124,8 +137,8 @@ export default class Component {
124
137
 
125
138
  on(event, target, fn) {
126
139
  const off = on(event, target, fn, this.el);
127
- this.on.destroy ??= [];
128
- this.on.destroy.push(off);
140
+ this.offs ??= [];
141
+ this.offs.push(off);
129
142
  return off;
130
143
  }
131
144
 
@@ -135,9 +148,10 @@ export default class Component {
135
148
  }
136
149
 
137
150
  destroy() {
138
- this.on.destroy?.forEach(off => off());
139
151
  this.controller?.abort();
140
152
  this.directives.length = 0;
141
- queue.delete(this);
153
+ this.offs?.forEach(off => off());
154
+ cache?.delete(this);
155
+ queue?.delete(this);
142
156
  }
143
157
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmbr/component",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "repository": "github:nikrowell/tmbr-toolkit",
5
5
  "type": "module",
6
6
  "main": "index.js",