@oscarpalmer/abydon 0.13.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.
Files changed (44) hide show
  1. package/dist/abydon.full.js +790 -763
  2. package/dist/constants.js +10 -0
  3. package/dist/fragment.js +38 -17
  4. package/dist/fragments.js +74 -0
  5. package/dist/helpers/dom.js +4 -4
  6. package/dist/helpers/index.js +4 -1
  7. package/dist/index.js +5 -1
  8. package/dist/node/attribute/index.js +19 -14
  9. package/dist/node/attribute/value.js +10 -12
  10. package/dist/node/event.js +7 -9
  11. package/dist/node/index.js +9 -4
  12. package/dist/node/value.js +84 -64
  13. package/dist/parse.js +7 -7
  14. package/package.json +14 -16
  15. package/src/constants.ts +20 -0
  16. package/src/fragment.ts +92 -29
  17. package/src/fragments.ts +134 -0
  18. package/src/helpers/dom.ts +3 -3
  19. package/src/helpers/index.ts +10 -0
  20. package/src/index.ts +16 -1
  21. package/src/models.ts +18 -4
  22. package/src/node/attribute/index.ts +24 -19
  23. package/src/node/attribute/value.ts +31 -28
  24. package/src/node/event.ts +11 -12
  25. package/src/node/index.ts +15 -6
  26. package/src/node/value.ts +186 -116
  27. package/src/parse.ts +10 -3
  28. package/types/constants.d.ts +9 -0
  29. package/types/fragment.d.ts +26 -8
  30. package/types/fragments.d.ts +13 -0
  31. package/types/helpers/index.d.ts +2 -0
  32. package/types/index.d.ts +5 -1
  33. package/types/models.d.ts +16 -4
  34. package/types/fragment.d.cts +0 -27
  35. package/types/helpers/dom.d.cts +0 -7
  36. package/types/helpers/index.d.cts +0 -29
  37. package/types/index.d.cts +0 -302
  38. package/types/models.d.cts +0 -107
  39. package/types/node/attribute/index.d.cts +0 -109
  40. package/types/node/attribute/value.d.cts +0 -109
  41. package/types/node/event.d.cts +0 -7
  42. package/types/node/index.d.cts +0 -108
  43. package/types/node/value.d.cts +0 -108
  44. package/types/parse.d.cts +0 -108
@@ -6,12 +6,14 @@ import {
6
6
  setAttribute as setAttr,
7
7
  } from '@oscarpalmer/toretto/attribute';
8
8
  import type {HTMLOrSVGElement} from '@oscarpalmer/toretto/models';
9
+ import {
10
+ ATTRIBUTE_CLASS_PREFIX_LENGTH,
11
+ EXPRESSION_ATTRIBUTE_CLASS,
12
+ EXPRESSION_ATTRIBUTE_STYLE_FULL,
13
+ EXPRESSION_ATTRIBUTE_STYLE_PREFIX,
14
+ } from '../../constants';
9
15
  import type {FragmentData} from '../../models';
10
16
 
11
- const classExpression = /^class\./;
12
- const styleFullExpression = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
13
- const stylePrefixExpression = /^style\./;
14
-
15
17
  export function setAttribute(
16
18
  data: FragmentData,
17
19
  element: HTMLOrSVGElement,
@@ -21,11 +23,11 @@ export function setAttribute(
21
23
  element.removeAttribute(name);
22
24
 
23
25
  switch (true) {
24
- case classExpression.test(name):
26
+ case EXPRESSION_ATTRIBUTE_CLASS.test(name):
25
27
  setClasses(data, element, name, value);
26
28
  return;
27
29
 
28
- case stylePrefixExpression.test(name):
30
+ case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
29
31
  setStyle(data, element, name, value);
30
32
  return;
31
33
 
@@ -49,7 +51,7 @@ function setClasses(
49
51
  }
50
52
  }
51
53
 
52
- const classes = name.slice(6).split('.');
54
+ const classes = name.slice(ATTRIBUTE_CLASS_PREFIX_LENGTH).split('.');
53
55
 
54
56
  if (isReactive(value)) {
55
57
  data.mora.subscribers.add(value.subscribe(update));
@@ -64,6 +66,12 @@ function setStyle(
64
66
  name: string,
65
67
  value: unknown,
66
68
  ): void {
69
+ const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
70
+
71
+ if (property == null) {
72
+ return;
73
+ }
74
+
67
75
  function update(value: unknown): void {
68
76
  if (value == null || value === false || (value === true && unit == null)) {
69
77
  element.style.removeProperty(property);
@@ -75,14 +83,10 @@ function setStyle(
75
83
  }
76
84
  }
77
85
 
78
- const [, property, unit] = styleFullExpression.exec(name) ?? [];
79
-
80
- if (property != null) {
81
- if (isReactive(value)) {
82
- data.mora.subscribers.add(value.subscribe(update));
83
- } else {
84
- update(value);
85
- }
86
+ if (isReactive(value)) {
87
+ data.mora.subscribers.add(value.subscribe(update));
88
+ } else {
89
+ update(value);
86
90
  }
87
91
  }
88
92
 
@@ -92,12 +96,17 @@ function setValue(
92
96
  name: string,
93
97
  value: unknown,
94
98
  ): void {
95
- const callback =
96
- isBooleanAttribute(name) && name in element
97
- ? name === 'selected'
98
- ? updateSelected
99
- : updateProperty
100
- : setAttr;
99
+ let callback: (
100
+ element: HTMLOrSVGElement,
101
+ name: string,
102
+ value: unknown,
103
+ ) => void;
104
+
105
+ if (isBooleanAttribute(name) && name in element) {
106
+ callback = name === 'selected' ? updateSelected : updateProperty;
107
+ } else {
108
+ callback = setAttr;
109
+ }
101
110
 
102
111
  if (isReactive(value)) {
103
112
  data.mora.subscribers.add(
@@ -110,12 +119,6 @@ function setValue(
110
119
  }
111
120
  }
112
121
 
113
- function triggerSelectChange(select: HTMLSelectElement): void {
114
- if (select != null) {
115
- select.dispatchEvent(new Event('change', {bubbles: true}));
116
- }
117
- }
118
-
119
122
  function updateProperty(
120
123
  element: HTMLOrSVGElement,
121
124
  name: string,
@@ -133,7 +136,7 @@ function updateSelected(
133
136
  const options = [...(select?.options ?? [])];
134
137
 
135
138
  if (select != null && options.includes(element as HTMLOptionElement)) {
136
- triggerSelectChange(select);
139
+ select.dispatchEvent(new Event('change', {bubbles: true}));
137
140
  }
138
141
 
139
142
  updateProperty(element, name, value);
package/src/node/event.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  import type {HTMLOrSVGElement} from '@oscarpalmer/toretto/models';
2
-
3
- const controllers = new WeakMap<HTMLOrSVGElement, AbortController>();
4
-
5
- const eventNamePattern = /^@([\w-]+)(?::([a-z:]+))?$/i;
6
-
7
- const reason = 'Event removed as element was removed from document by Abydon';
2
+ import {
3
+ ABORT_CONTROLLERS,
4
+ EXPRESSION_EVENT_NAME,
5
+ REASON_EVENT_REMOVED,
6
+ } from '../constants';
8
7
 
9
8
  function getController(element: HTMLOrSVGElement): AbortController {
10
- let controller = controllers.get(element);
9
+ let controller = ABORT_CONTROLLERS.get(element);
11
10
 
12
11
  if (controller == null) {
13
12
  controller = new AbortController();
14
13
 
15
- controllers.set(element, controller);
14
+ ABORT_CONTROLLERS.set(element, controller);
16
15
  }
17
16
 
18
17
  return controller;
@@ -24,7 +23,7 @@ function getOptions(options: string): AddEventListenerOptions {
24
23
  return {
25
24
  capture: parts.includes('c') || parts.includes('capture'),
26
25
  once: parts.includes('o') || parts.includes('once'),
27
- passive: !parts.includes('a') && !parts.includes('active'),
26
+ passive: !(parts.includes('a') || parts.includes('active')),
28
27
  };
29
28
  }
30
29
 
@@ -35,7 +34,7 @@ export function mapEvent(
35
34
  ): void {
36
35
  element.removeAttribute(name);
37
36
 
38
- const [, type, options] = eventNamePattern.exec(name) ?? [];
37
+ const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
39
38
 
40
39
  if (typeof value === 'function' && type != null) {
41
40
  element.addEventListener(type, value as EventListener, {
@@ -46,6 +45,6 @@ export function mapEvent(
46
45
  }
47
46
 
48
47
  export function removeEvents(element: HTMLOrSVGElement): void {
49
- controllers.get(element)?.abort(reason);
50
- controllers.delete(element);
48
+ ABORT_CONTROLLERS.get(element)?.abort(REASON_EVENT_REMOVED);
49
+ ABORT_CONTROLLERS.delete(element);
51
50
  }
package/src/node/index.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
- import {computed, isReactive} from '@oscarpalmer/mora';
2
+ import {computed, isReactive, Reactive} from '@oscarpalmer/mora';
3
3
  import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
4
- import {isFragment} from '../helpers';
4
+ import {EXPRESSION_COMMENT_CONTENT} from '../constants';
5
+ import {handleFragments} from '../fragments';
6
+ import {isFragment, isFragments} from '../helpers';
5
7
  import {createNodes} from '../helpers/dom';
6
8
  import type {FragmentData} from '../models';
7
9
  import {mapAttributes} from './attribute';
8
10
  import {setReactiveValue} from './value';
9
11
 
10
- const commentExpression = /^abydon\.(\d+)$/;
11
-
12
12
  function mapNode(data: FragmentData, comment: Comment): void {
13
- const matches = commentExpression.exec(comment.textContent ?? '');
13
+ const matches = EXPRESSION_COMMENT_CONTENT.exec(comment.textContent ?? '');
14
14
  const value = matches == null ? null : data.values[+matches[1]];
15
15
 
16
16
  if (value != null) {
@@ -46,6 +46,15 @@ function mapValue(data: FragmentData, comment: Comment, value: unknown): void {
46
46
  setComputedValue(data, comment, value as GenericCallback);
47
47
  break;
48
48
 
49
+ case isFragments(value):
50
+ handleFragments(value, false);
51
+ setReactiveValue(
52
+ data,
53
+ comment,
54
+ value.items as Reactive<unknown[], unknown>,
55
+ );
56
+ break;
57
+
49
58
  case isReactive(value):
50
59
  setReactiveValue(data, comment, value);
51
60
  break;
@@ -61,7 +70,7 @@ function replaceComment(
61
70
  comment: Comment,
62
71
  value: unknown,
63
72
  ): void {
64
- const item = data.items.find(item => item.nodes.includes(comment));
73
+ const item = data.items.find(item => item.nodes?.includes(comment));
65
74
  const nodes = createNodes(value);
66
75
 
67
76
  if (item != null) {
package/src/node/value.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
- import type {Key} from '@oscarpalmer/atoms/models';
3
2
  import {getString} from '@oscarpalmer/atoms/string';
4
3
  import type {Reactive} from '@oscarpalmer/mora';
5
4
  import {isChildNode} from '@oscarpalmer/toretto/is';
@@ -8,6 +7,94 @@ import {compareArrays, isFragment} from '../helpers';
8
7
  import {createNodes, replaceNodes} from '../helpers/dom';
9
8
  import type {FragmentData, FragmentItem} from '../models';
10
9
 
10
+ //
11
+
12
+ type Identifiers = {
13
+ next: unknown[];
14
+ previous: (unknown | undefined)[];
15
+ };
16
+
17
+ type BaseItems = {
18
+ fragments: Fragment[];
19
+ templates: Fragment[];
20
+ };
21
+
22
+ type ExtendedItems = {
23
+ next: Fragment[];
24
+ } & BaseItems;
25
+
26
+ //
27
+
28
+ function addToArray(
29
+ identifiers: Identifiers,
30
+ items: ExtendedItems,
31
+ nodes: ChildNode[],
32
+ added: boolean,
33
+ ): void {
34
+ let position = nodes[0];
35
+
36
+ const before =
37
+ added && !identifiers.previous.includes(items.templates[0].identifier);
38
+
39
+ const next = items.next.flatMap(fragment =>
40
+ fragment.get().flatMap(node => ({
41
+ identifier: fragment.identifier,
42
+ value: node,
43
+ })),
44
+ );
45
+
46
+ const {length} = next;
47
+
48
+ for (let index = 0; index < length; index += 1) {
49
+ const node = next[index];
50
+
51
+ if (!(added && identifiers.previous.includes(node.identifier))) {
52
+ if (index === 0 && before) {
53
+ position.before(node.value);
54
+ } else {
55
+ position.after(node.value);
56
+ }
57
+ }
58
+
59
+ position = node.value;
60
+ }
61
+ }
62
+
63
+ function handleArray(
64
+ identifiers: Identifiers,
65
+ items: BaseItems,
66
+ nodes: ChildNode[],
67
+ ): Partial<FragmentItem> {
68
+ const next = items.templates.map(
69
+ template =>
70
+ items.fragments?.find(
71
+ fragment => fragment.identifier === template.identifier,
72
+ ) ?? template,
73
+ );
74
+
75
+ const comparison = compareArrays(items.fragments ?? [], items.templates);
76
+
77
+ if (comparison !== 'removed') {
78
+ addToArray(identifiers, {...items, next}, nodes, comparison === 'added');
79
+ }
80
+
81
+ const toRemove =
82
+ items.fragments?.filter(
83
+ fragment => !identifiers.next.includes(fragment.identifier),
84
+ ) ?? [];
85
+
86
+ const {length} = toRemove;
87
+
88
+ for (let index = 0; index < length; index += 1) {
89
+ toRemove[index].remove();
90
+ }
91
+
92
+ return {
93
+ fragments: next,
94
+ nodes: next.flatMap(fragment => fragment.get()),
95
+ };
96
+ }
97
+
11
98
  function removeFragments(fragments: Fragment[] | undefined): void {
12
99
  if (fragments != null) {
13
100
  const {length} = fragments;
@@ -18,16 +105,30 @@ function removeFragments(fragments: Fragment[] | undefined): void {
18
105
  }
19
106
  }
20
107
 
108
+ function replaceText(
109
+ item: FragmentItem,
110
+ comment: Comment,
111
+ isNullable: boolean,
112
+ ): void {
113
+ let to: ChildNode[];
114
+
115
+ if (isNullable) {
116
+ to = [comment];
117
+ } else {
118
+ to = item.text == null ? [] : [item.text];
119
+ }
120
+
121
+ replaceNodes(item.nodes ?? [], to);
122
+ }
123
+
21
124
  function setArray(
22
- fragments: Fragment[] | undefined,
23
- nodes: ChildNode[] | undefined,
125
+ item: FragmentItem,
24
126
  comment: Comment,
25
- text: Text,
26
127
  value: unknown[],
27
128
  ): Partial<FragmentItem> | boolean {
28
129
  if (value.length === 0) {
29
130
  return {
30
- nodes: setText(fragments, nodes, comment, text, value),
131
+ nodes: setText(item, comment, value),
31
132
  };
32
133
  }
33
134
 
@@ -35,10 +136,10 @@ function setArray(
35
136
  item => isFragment(item) && item.identifier != null,
36
137
  ) as Fragment[];
37
138
 
38
- const identifiers = templates.map(fragment => fragment.identifier) as Key[];
39
- const oldIdentifiers = fragments?.map(fragment => fragment.identifier) ?? [];
139
+ const next = templates.map(fragment => fragment.identifier) as unknown[];
140
+ const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
40
141
 
41
- if (new Set(identifiers).size !== templates.length) {
142
+ if (new Set(next).size !== templates.length) {
42
143
  templates = [];
43
144
  }
44
145
 
@@ -46,16 +147,14 @@ function setArray(
46
147
 
47
148
  if (
48
149
  noTemplates ||
49
- nodes == null ||
50
- oldIdentifiers.some(identifier => identifier == null)
150
+ item.nodes == null ||
151
+ previous.some(identifier => identifier == null)
51
152
  ) {
52
153
  return {
53
154
  fragments: noTemplates ? undefined : templates,
54
155
  nodes: setNodes(
55
- fragments,
56
- nodes,
156
+ item,
57
157
  comment,
58
- text,
59
158
  noTemplates
60
159
  ? value.flatMap(item => createNodes(item))
61
160
  : templates.flatMap(template => template.get()),
@@ -63,84 +162,35 @@ function setArray(
63
162
  };
64
163
  }
65
164
 
66
- const next = templates.map(
67
- template =>
68
- fragments?.find(
69
- fragment => fragment.identifier === template.identifier,
70
- ) ?? template,
165
+ return handleArray(
166
+ {
167
+ next,
168
+ previous,
169
+ },
170
+ {
171
+ templates,
172
+ fragments: item.fragments ?? [],
173
+ },
174
+ item.nodes,
71
175
  );
72
-
73
- const comparison = compareArrays(fragments ?? [], templates);
74
-
75
- if (comparison !== 'removed') {
76
- let position = nodes[0];
77
-
78
- const before =
79
- comparison === 'added' &&
80
- !oldIdentifiers.includes(templates[0].identifier);
81
-
82
- const items = next.flatMap(fragment =>
83
- fragment.get().flatMap(node => ({
84
- identifier: fragment.identifier,
85
- value: node,
86
- })),
87
- );
88
-
89
- const {length} = items;
90
-
91
- for (let index = 0; index < length; index += 1) {
92
- const item = items[index];
93
-
94
- if (
95
- comparison === 'dissimilar' ||
96
- !oldIdentifiers.includes(item.identifier)
97
- ) {
98
- if (index === 0 && before) {
99
- position.before(item.value);
100
- } else {
101
- position.after(item.value);
102
- }
103
- }
104
-
105
- position = item.value;
106
- }
107
- }
108
-
109
- const toRemove =
110
- fragments?.filter(
111
- fragment => !identifiers.includes(fragment.identifier as Key),
112
- ) ?? [];
113
-
114
- const {length} = toRemove;
115
-
116
- for (let index = 0; index < length; index += 1) {
117
- toRemove[index].remove();
118
- }
119
-
120
- return {
121
- fragments: next,
122
- nodes: next.flatMap(fragment => fragment.get()),
123
- };
124
176
  }
125
177
 
126
178
  function setNodes(
127
- fragments: Fragment[] | undefined,
128
- nodes: ChildNode[] | undefined,
179
+ item: FragmentItem,
129
180
  comment: Comment,
130
- text: Text,
131
181
  next: ChildNode[],
132
182
  ): ChildNode[] {
133
- if (nodes == null) {
183
+ if (item.nodes == null) {
134
184
  if (comment.parentNode != null) {
135
185
  replaceNodes([comment], next);
136
- } else if (text.parentNode != null) {
137
- replaceNodes([text], next);
186
+ } else if (item.text?.parentNode != null) {
187
+ replaceNodes([item.text], next);
138
188
  }
139
189
  } else {
140
- replaceNodes(nodes, next);
190
+ replaceNodes(item.nodes, next);
141
191
  }
142
192
 
143
- removeFragments(fragments);
193
+ removeFragments(item.fragments);
144
194
 
145
195
  return next;
146
196
  }
@@ -150,71 +200,91 @@ export function setReactiveValue(
150
200
  comment: Comment,
151
201
  reactive: Reactive<unknown>,
152
202
  ): void {
153
- const item = data.items.find(item => item.nodes.includes(comment));
154
- const text = new Text();
203
+ let item = data.items.find(item => item.nodes?.includes(comment));
204
+
205
+ item ??= {};
155
206
 
156
- let fragments: Fragment[] | undefined;
157
- let nodes: ChildNode[] | undefined;
207
+ item.text = new Text();
158
208
 
159
209
  data.mora.subscribers.add(
160
210
  reactive.subscribe(value => {
161
211
  if (Array.isArray(value)) {
162
- const result = setArray(fragments, nodes, comment, text, value);
163
-
164
- fragments = typeof result === 'boolean' ? undefined : result?.fragments;
165
-
166
- nodes =
167
- typeof result === 'boolean'
168
- ? result
169
- ? [text]
170
- : undefined
171
- : result?.nodes;
212
+ setReactiveValueForArray(item, comment, value);
172
213
  } else {
173
- const valueIsFragment = isFragment(value);
174
-
175
- fragments = valueIsFragment ? [value] : undefined;
176
-
177
- if (valueIsFragment || isChildNode(value)) {
178
- nodes = setNodes(fragments, nodes, comment, text, createNodes(value));
179
- } else {
180
- nodes = setText(fragments, nodes, comment, text, value);
181
- }
214
+ setReactiveValueForSingle(item, comment, value);
182
215
  }
183
216
 
184
- if (item != null) {
185
- item.fragments = fragments;
186
- item.nodes = [...(nodes ?? [comment])];
187
- }
217
+ item.nodes = [...(item.nodes ?? [comment])];
188
218
  }),
189
219
  );
190
220
  }
191
221
 
222
+ function setReactiveValueForArray(
223
+ item: FragmentItem,
224
+ comment: Comment,
225
+ value: unknown[],
226
+ ): void {
227
+ const result = setArray(item, comment, value);
228
+
229
+ item.fragments = typeof result === 'boolean' ? undefined : result?.fragments;
230
+
231
+ if (typeof result === 'boolean') {
232
+ if (result) {
233
+ item.nodes = item.text == null ? [] : [item.text];
234
+ } else {
235
+ item.nodes = undefined;
236
+ }
237
+ } else {
238
+ item.nodes = result?.nodes;
239
+ }
240
+ }
241
+
242
+ function setReactiveValueForSingle(
243
+ item: FragmentItem,
244
+ comment: Comment,
245
+ value: unknown,
246
+ ): void {
247
+ const valueIsFragment = isFragment(value);
248
+
249
+ item.fragments = valueIsFragment ? [value] : undefined;
250
+
251
+ if (valueIsFragment || isChildNode(value)) {
252
+ item.nodes = setNodes(item, comment, createNodes(value));
253
+ } else {
254
+ item.nodes = setText(item, comment, value);
255
+ }
256
+ }
257
+
192
258
  function setText(
193
- fragments: Fragment[] | undefined,
194
- nodes: ChildNode[] | undefined,
259
+ item: FragmentItem,
195
260
  comment: Comment,
196
- text: Text,
197
261
  value: unknown,
198
262
  ): ChildNode[] | undefined {
199
263
  const isNullable = isNullableOrWhitespace(value);
200
264
 
201
- text.textContent = isNullable ? '' : getString(value);
265
+ if (item.text != null) {
266
+ item.text.textContent = isNullable ? '' : getString(value);
267
+ }
202
268
 
203
269
  let result = false;
204
270
 
205
- if (nodes != null) {
206
- replaceNodes(nodes, [isNullable ? comment : text]);
271
+ if (item.nodes != null) {
272
+ replaceText(item, comment, isNullable);
207
273
 
208
274
  result = !isNullable;
209
275
  } else if (isNullable && comment.parentNode == null) {
210
- text.replaceWith(comment);
211
- } else if (!isNullable && text.parentNode == null) {
212
- comment.replaceWith(text);
276
+ item.text?.replaceWith(comment);
277
+ } else if (!isNullable && item?.text?.parentNode == null) {
278
+ if (item.text != null) {
279
+ comment.replaceWith(item.text);
280
+ }
213
281
 
214
282
  result = true;
215
283
  }
216
284
 
217
- removeFragments(fragments);
285
+ removeFragments(item.fragments);
218
286
 
219
- return result ? [text] : undefined;
287
+ if (result) {
288
+ return item.text == null ? [] : [item.text];
289
+ }
220
290
  }
package/src/parse.ts CHANGED
@@ -31,17 +31,24 @@ function handleExpression(
31
31
  }
32
32
 
33
33
  export function parse(data: FragmentData): string {
34
+ if (data.template != null) {
35
+ return data.template;
36
+ }
37
+
34
38
  const {length} = data.strings;
35
39
 
36
- let template = '';
40
+ data.template = '';
37
41
 
38
42
  for (let index = 0; index < length; index += 1) {
39
- template += handleExpression(
43
+ data.template += handleExpression(
40
44
  data,
41
45
  data.strings[index],
42
46
  data.expressions[index],
43
47
  );
44
48
  }
45
49
 
46
- return template;
50
+ data.expressions = [];
51
+ data.strings = [] as never;
52
+
53
+ return data.template;
47
54
  }
@@ -0,0 +1,9 @@
1
+ export declare const ABORT_CONTROLLERS: WeakMap<HTMLOrSVGElement, AbortController>;
2
+ export declare const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
3
+ export declare const EXPRESSION_ATTRIBUTE_CLASS: RegExp;
4
+ export declare const EXPRESSION_ATTRIBUTE_STYLE_FULL: RegExp;
5
+ export declare const EXPRESSION_ATTRIBUTE_STYLE_PREFIX: RegExp;
6
+ export declare const EXPRESSION_COMMENT_FULL: RegExp;
7
+ export declare const EXPRESSION_COMMENT_CONTENT: RegExp;
8
+ export declare const EXPRESSION_EVENT_NAME: RegExp;
9
+ export declare const REASON_EVENT_REMOVED = "Event removed as element was removed from document by Abydon";
@@ -1,20 +1,38 @@
1
- import type { Key } from '@oscarpalmer/atoms/models';
1
+ import type { FragmentConfiguration } from './models';
2
2
  export declare class Fragment {
3
- private readonly $fragment;
4
- private readonly data;
5
- get identifier(): Key | undefined;
3
+ #private;
4
+ /**
5
+ * Fragment identifier
6
+ */
7
+ get identifier(): unknown;
6
8
  constructor(strings: TemplateStringsArray, expressions: unknown[]);
7
9
  /**
8
- * Appends the fragment to the given element
10
+ * Append the fragment to the given element
11
+ * @param element Element to append to
9
12
  */
10
13
  appendTo(element: Element): void;
11
14
  /**
12
- * Gets a list of the fragment's nodes
15
+ * Configure the fragment
16
+ * @param configuration Configuration options
17
+ * @returns Fragment
18
+ */
19
+ configure(configuration: FragmentConfiguration): Fragment;
20
+ /**
21
+ * Get a list of the fragment's nodes
22
+ * @returns List of nodes
13
23
  */
14
24
  get(): ChildNode[];
15
- identify(identifier: Key): Fragment;
16
25
  /**
17
- * Removes the fragment from the DOM
26
+ * Set an identifier for the fragment
27
+ *
28
+ * _An identifier can be used to uniquely identify a fragment,
29
+ * which helps prevent re-rendering in certain scenarios._
30
+ * @param identifier Identifier
31
+ * @returns Fragment
32
+ */
33
+ identify(identifier: unknown): Fragment;
34
+ /**
35
+ * Remove the fragment from the DOM
18
36
  */
19
37
  remove(): void;
20
38
  }