@esportsplus/template 0.14.0 → 0.15.0

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.

Potentially problematic release.


This version of @esportsplus/template might be problematic. Click here for more details.

@@ -1,4 +1,5 @@
1
1
  import { effect, root } from '@esportsplus/reactivity';
2
+ import { oncleanup } from './slot.js';
2
3
  import { className, isArray, isObject, raf, removeAttribute, setAttribute } from './utilities.js';
3
4
  import event from './event.js';
4
5
  let attributes = {}, delimiters = {
@@ -24,19 +25,24 @@ function attribute(element, name, value) {
24
25
  }
25
26
  function reactive(element, id, name, value, wait = false) {
26
27
  if (typeof value === 'function') {
27
- effect(() => {
28
+ let instance = effect(() => {
28
29
  let v = value(element);
29
30
  if (typeof v === 'function') {
30
- root(() => {
31
+ root((root) => {
32
+ instance.on('cleanup', () => root.dispose());
31
33
  reactive(element, id, name, v(element), wait);
32
34
  });
33
35
  }
36
+ else if (isArray(v) || isObject(v)) {
37
+ spread(element, v);
38
+ }
34
39
  else {
35
40
  raf.add(() => {
36
41
  update(element, id, name, v, wait);
37
42
  });
38
43
  }
39
44
  });
45
+ oncleanup(element, () => instance.dispose());
40
46
  wait = false;
41
47
  }
42
48
  else {
@@ -144,7 +150,7 @@ const spread = function (element, attributes) {
144
150
  for (let i = 0, n = attributes.length; i < n; i++) {
145
151
  let attrs = attributes[i];
146
152
  if (!isObject(attrs)) {
147
- continue;
153
+ throw new Error('@esportsplus/template: attributes must be of type `Attributes` or `Attributes[]`; Received ' + JSON.stringify(attributes));
148
154
  }
149
155
  for (let name in attrs) {
150
156
  set(element, attrs[name], name);
package/build/event.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { root } from '@esportsplus/reactivity';
2
- import { SLOT_CLEANUP } from './constants.js';
2
+ import { oncleanup } from './slot.js';
3
3
  import { addEventListener, defineProperty, parentElement } from './utilities.js';
4
4
  let capture = new Set(['onblur', 'onfocus', 'onscroll']), controllers = new Map(), keys = {}, passive = new Set([
5
5
  'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel',
@@ -38,7 +38,7 @@ export default (element, event, listener) => {
38
38
  }
39
39
  if (controller) {
40
40
  controller.listeners++;
41
- (element[SLOT_CLEANUP] ??= []).push(() => {
41
+ oncleanup(element, () => {
42
42
  if (--controller.listeners) {
43
43
  return;
44
44
  }
package/build/slot.d.ts CHANGED
@@ -17,6 +17,7 @@ declare class Slot {
17
17
  splice(start: number, stop?: number, ...groups: Elements[]): Elements[];
18
18
  unshift(...groups: Elements[]): number;
19
19
  }
20
+ declare const oncleanup: (element: Element, fn: VoidFunction) => void;
20
21
  declare const _default: (marker: Element, value: unknown) => Slot;
21
22
  export default _default;
22
- export { Slot };
23
+ export { oncleanup, Slot };
package/build/slot.js CHANGED
@@ -100,9 +100,7 @@ class Slot {
100
100
  nodes;
101
101
  text = null;
102
102
  constructor(marker) {
103
- (marker[SLOT_CLEANUP] ??= []).push(() => {
104
- this.clear();
105
- });
103
+ oncleanup(marker, () => this.clear());
106
104
  this.marker = marker;
107
105
  this.nodes = [];
108
106
  }
@@ -139,10 +137,11 @@ class Slot {
139
137
  }
140
138
  render(input) {
141
139
  if (typeof input === 'function') {
142
- effect((self) => {
140
+ let instance = effect((self) => {
143
141
  let v = input();
144
142
  if (typeof v === 'function') {
145
- root(() => {
143
+ root((root) => {
144
+ instance.on('cleanup', () => root.dispose());
146
145
  this.render(v());
147
146
  });
148
147
  }
@@ -155,6 +154,7 @@ class Slot {
155
154
  });
156
155
  }
157
156
  });
157
+ oncleanup(this.marker, () => instance.dispose());
158
158
  return this;
159
159
  }
160
160
  if (this.text) {
@@ -188,7 +188,10 @@ class Slot {
188
188
  return this.nodes.unshift(...after(this.marker, groups));
189
189
  }
190
190
  }
191
+ const oncleanup = (element, fn) => {
192
+ (element[SLOT_CLEANUP] ??= []).push(fn);
193
+ };
191
194
  export default (marker, value) => {
192
195
  return new Slot(marker).render(value);
193
196
  };
194
- export { Slot };
197
+ export { oncleanup, Slot };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "author": "ICJR",
3
3
  "dependencies": {
4
- "@esportsplus/reactivity": "^0.4.6",
4
+ "@esportsplus/reactivity": "^0.4.7",
5
5
  "@esportsplus/tasks": "^0.1.9",
6
6
  "@esportsplus/utilities": "^0.19.0"
7
7
  },
@@ -13,7 +13,7 @@
13
13
  "private": false,
14
14
  "type": "module",
15
15
  "types": "./build/index.d.ts",
16
- "version": "0.14.0",
16
+ "version": "0.15.0",
17
17
  "scripts": {
18
18
  "build": "tsc && tsc-alias",
19
19
  "-": "-"
package/src/attributes.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { effect, root } from '@esportsplus/reactivity';
2
+ import { oncleanup } from './slot';
2
3
  import { Attributes, Element } from './types';
3
4
  import { className, isArray, isObject, raf, removeAttribute, setAttribute } from './utilities';
4
5
  import event from './event';
@@ -33,20 +34,27 @@ function attribute(element: Element, name: string, value: unknown) {
33
34
 
34
35
  function reactive(element: Element, id: string, name: string, value: unknown, wait = false) {
35
36
  if (typeof value === 'function') {
36
- effect(() => {
37
- let v = (value as Function)(element);
37
+ let instance = effect(() => {
38
+ let v = (value as Function)(element);
39
+
40
+ if (typeof v === 'function') {
41
+ root((root) => {
42
+ instance.on('cleanup', () => root.dispose());
43
+ reactive(element, id, name, v(element), wait);
44
+ });
45
+ }
46
+ else if (isArray(v) || isObject(v)) {
47
+ spread(element, v as Attributes | Attributes[]);
48
+ }
49
+ else {
50
+ raf.add(() => {
51
+ update(element, id, name, v, wait);
52
+ });
53
+ }
54
+ });
55
+
56
+ oncleanup(element, () => instance.dispose());
38
57
 
39
- if (typeof v === 'function') {
40
- root(() => {
41
- reactive(element, id, name, v(element), wait);
42
- });
43
- }
44
- else {
45
- raf.add(() => {
46
- update(element, id, name, v, wait);
47
- });
48
- }
49
- });
50
58
  wait = false;
51
59
  }
52
60
  else {
@@ -184,7 +192,7 @@ const spread = function (element: Element, attributes: Attributes | Attributes[]
184
192
  let attrs = attributes[i];
185
193
 
186
194
  if (!isObject(attrs)) {
187
- continue;
195
+ throw new Error('@esportsplus/template: attributes must be of type `Attributes` or `Attributes[]`; Received ' + JSON.stringify(attributes));
188
196
  }
189
197
 
190
198
  for (let name in attrs) {
package/src/event.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { root } from '@esportsplus/reactivity';
2
- import { SLOT_CLEANUP } from './constants';
2
+ import { oncleanup } from './slot';
3
3
  import { Element } from './types';
4
4
  import { addEventListener, defineProperty, parentElement } from './utilities';
5
5
 
@@ -65,14 +65,14 @@ export default (element: Element, event: `on${string}`, listener: Function) => {
65
65
  if (controller) {
66
66
  controller.listeners++;
67
67
 
68
- ( element[SLOT_CLEANUP] ??= [] ).push(() => {
68
+ oncleanup(element, () => {
69
69
  if (--controller.listeners) {
70
70
  return;
71
71
  }
72
72
 
73
73
  controller.abort();
74
74
  controllers.set(event, null);
75
- })
75
+ });
76
76
  signal = controller.signal;
77
77
  }
78
78
 
package/src/slot.ts CHANGED
@@ -137,9 +137,7 @@ class Slot {
137
137
 
138
138
 
139
139
  constructor(marker: Element) {
140
- ( marker[SLOT_CLEANUP] ??= [] ).push(() => {
141
- this.clear();
142
- });
140
+ oncleanup(marker, () => this.clear());
143
141
 
144
142
  this.marker = marker;
145
143
  this.nodes = [];
@@ -193,23 +191,26 @@ class Slot {
193
191
 
194
192
  render(input: unknown) {
195
193
  if (typeof input === 'function') {
196
- effect((self) => {
197
- let v = (input as Function)();
198
-
199
- if (typeof v === 'function') {
200
- root(() => {
201
- this.render(v());
202
- });
203
- }
204
- else if (self.state === DIRTY) {
205
- this.render(v);
206
- }
207
- else {
208
- raf.add(() => {
194
+ let instance = effect((self) => {
195
+ let v = (input as Function)();
196
+
197
+ if (typeof v === 'function') {
198
+ root((root) => {
199
+ instance.on('cleanup', () => root.dispose());
200
+ this.render(v());
201
+ });
202
+ }
203
+ else if (self.state === DIRTY) {
209
204
  this.render(v);
210
- });
211
- }
212
- });
205
+ }
206
+ else {
207
+ raf.add(() => {
208
+ this.render(v);
209
+ });
210
+ }
211
+ });
212
+
213
+ oncleanup(this.marker, () => instance.dispose());
213
214
 
214
215
  return this;
215
216
  }
@@ -261,7 +262,12 @@ class Slot {
261
262
  }
262
263
 
263
264
 
265
+ const oncleanup = (element: Element, fn: VoidFunction) => {
266
+ ( element[SLOT_CLEANUP] ??= [] ).push(fn);
267
+ };
268
+
269
+
264
270
  export default (marker: Element, value: unknown) => {
265
271
  return new Slot(marker).render(value);
266
272
  };
267
- export { Slot };
273
+ export { oncleanup, Slot };