@oscarpalmer/abydon 0.10.0 → 0.12.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.
package/dist/index.js CHANGED
@@ -1,167 +1,3 @@
1
- // node_modules/@oscarpalmer/atoms/dist/js/string/index.mjs
2
- function getString(value2) {
3
- if (typeof value2 === "string") {
4
- return value2;
5
- }
6
- if (typeof value2 !== "object" || value2 == null) {
7
- return String(value2);
8
- }
9
- const valueOff = value2.valueOf?.() ?? value2;
10
- const asString = valueOff?.toString?.() ?? String(valueOff);
11
- return asString.startsWith("[object ") ? JSON.stringify(value2) : asString;
12
- }
13
- // node_modules/@oscarpalmer/atoms/dist/js/is.mjs
14
- function isNullableOrWhitespace(value2) {
15
- return value2 == null || /^\s*$/.test(getString(value2));
16
- }
17
- // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/string/index.mjs
18
- function getString2(value3) {
19
- if (typeof value3 === "string") {
20
- return value3;
21
- }
22
- if (typeof value3 !== "object" || value3 == null) {
23
- return String(value3);
24
- }
25
- const valueOff = value3.valueOf?.() ?? value3;
26
- const asString = valueOff?.toString?.() ?? String(valueOff);
27
- return asString.startsWith("[object ") ? JSON.stringify(value3) : asString;
28
- }
29
- // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/is.mjs
30
- function isPlainObject2(value3) {
31
- if (typeof value3 !== "object" || value3 === null) {
32
- return false;
33
- }
34
- const prototype = Object.getPrototypeOf(value3);
35
- return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value3) && !(Symbol.iterator in value3);
36
- }
37
-
38
- // node_modules/@oscarpalmer/toretto/dist/attribute.mjs
39
- function isBadAttribute(attribute) {
40
- return onPrefix.test(attribute.name) || sourcePrefix.test(attribute.name) && valuePrefix.test(attribute.value);
41
- }
42
- function isBooleanAttribute(name) {
43
- return booleanAttributes.includes(name.toLowerCase());
44
- }
45
- function isEmptyNonBooleanAttribute(attribute) {
46
- return !booleanAttributes.includes(attribute.name) && attribute.value.trim().length === 0;
47
- }
48
- function isInvalidBooleanAttribute(attribute) {
49
- if (!booleanAttributes.includes(attribute.name)) {
50
- return true;
51
- }
52
- const normalised = attribute.value.toLowerCase().trim();
53
- return !(normalised.length === 0 || normalised === attribute.name || attribute.name === "hidden" && normalised === "until-found");
54
- }
55
- function setAttribute(element, first, second) {
56
- if (isPlainObject2(first) && typeof first?.name === "string") {
57
- setAttributeValue(element, first.name, first.value);
58
- } else if (typeof first === "string") {
59
- setAttributeValue(element, first, second);
60
- }
61
- }
62
- function setAttributeValue(element, name, value3) {
63
- if (value3 == null) {
64
- element.removeAttribute(name);
65
- } else {
66
- element.setAttribute(name, typeof value3 === "string" ? value3 : getString2(value3));
67
- }
68
- }
69
- var booleanAttributes = Object.freeze([
70
- "async",
71
- "autofocus",
72
- "autoplay",
73
- "checked",
74
- "controls",
75
- "default",
76
- "defer",
77
- "disabled",
78
- "formnovalidate",
79
- "hidden",
80
- "inert",
81
- "ismap",
82
- "itemscope",
83
- "loop",
84
- "multiple",
85
- "muted",
86
- "nomodule",
87
- "novalidate",
88
- "open",
89
- "playsinline",
90
- "readonly",
91
- "required",
92
- "reversed",
93
- "selected"
94
- ]);
95
- var onPrefix = /^on/i;
96
- var sourcePrefix = /^(href|src|xlink:href)$/i;
97
- var valuePrefix = /(data:text\/html|javascript:)/i;
98
-
99
- // node_modules/@oscarpalmer/toretto/dist/sanitise.mjs
100
- function sanitise(value3, options) {
101
- return sanitiseNodes(Array.isArray(value3) ? value3 : [value3], {
102
- sanitiseBooleanAttributes: options?.sanitiseBooleanAttributes ?? true
103
- });
104
- }
105
- function sanitiseAttributes(element, attributes, options) {
106
- const { length } = attributes;
107
- for (let index = 0;index < length; index += 1) {
108
- const attribute2 = attributes[index];
109
- if (isBadAttribute(attribute2) || isEmptyNonBooleanAttribute(attribute2)) {
110
- element.removeAttribute(attribute2.name);
111
- } else if (options.sanitiseBooleanAttributes && isInvalidBooleanAttribute(attribute2)) {
112
- element.setAttribute(attribute2.name, "");
113
- }
114
- }
115
- }
116
- function sanitiseNodes(nodes, options) {
117
- const { length } = nodes;
118
- for (let index = 0;index < length; index += 1) {
119
- const node = nodes[index];
120
- if (node instanceof Element) {
121
- sanitiseAttributes(node, [...node.attributes], options);
122
- }
123
- sanitiseNodes([...node.childNodes], options);
124
- }
125
- return nodes;
126
- }
127
-
128
- // node_modules/@oscarpalmer/toretto/dist/html.mjs
129
- function createTemplate(html) {
130
- const template3 = document.createElement("template");
131
- template3.innerHTML = html;
132
- templates[html] = template3;
133
- return template3;
134
- }
135
- function getTemplate(value3) {
136
- if (value3.trim().length === 0) {
137
- return;
138
- }
139
- let template3;
140
- if (/^[\w-]+$/.test(value3)) {
141
- template3 = document.querySelector(`#${value3}`);
142
- }
143
- if (template3 instanceof HTMLTemplateElement) {
144
- return template3;
145
- }
146
- return templates[value3] ?? createTemplate(value3);
147
- }
148
- function html(value3, sanitisation) {
149
- const options = sanitisation == null || sanitisation === true ? {} : isPlainObject2(sanitisation) ? { ...sanitisation } : null;
150
- const template3 = value3 instanceof HTMLTemplateElement ? value3 : typeof value3 === "string" ? getTemplate(value3) : null;
151
- if (template3 == null) {
152
- return [];
153
- }
154
- const cloned = template3.content.cloneNode(true);
155
- const scripts = cloned.querySelectorAll("script");
156
- const { length } = scripts;
157
- for (let index = 0;index < length; index += 1) {
158
- scripts[index].remove();
159
- }
160
- cloned.normalize();
161
- return options != null ? sanitise([...cloned.childNodes], options) : [...cloned.childNodes];
162
- }
163
- var templates = {};
164
-
165
1
  // node_modules/@oscarpalmer/sentinel/node_modules/@oscarpalmer/atoms/dist/js/queue.mjs
166
2
  function queue(callback) {
167
3
  _atomic_queued.add(callback);
@@ -252,11 +88,11 @@ class Effect {
252
88
  }
253
89
 
254
90
  // node_modules/@oscarpalmer/sentinel/dist/helpers/is.mjs
255
- function isReactive(value3) {
256
- return isSentinel(value3, /^array|computed|signal|store$/i);
91
+ function isReactive(value) {
92
+ return isSentinel(value, /^array|computed|signal|store$/i);
257
93
  }
258
- function isSentinel(value3, expression) {
259
- return expression.test(value3?.$sentinel ?? "");
94
+ function isSentinel(value, expression) {
95
+ return expression.test(value?.$sentinel ?? "");
260
96
  }
261
97
 
262
98
  // node_modules/@oscarpalmer/sentinel/node_modules/@oscarpalmer/atoms/dist/js/function.mjs
@@ -265,22 +101,22 @@ function noop() {
265
101
 
266
102
  // node_modules/@oscarpalmer/sentinel/dist/helpers/subscription.mjs
267
103
  function subscribe(state, subscriber, key) {
268
- let set5;
104
+ let set;
269
105
  if (key != null) {
270
106
  if (state.callbacks.keys.has(key)) {
271
- set5 = state.callbacks.values.get(key);
107
+ set = state.callbacks.values.get(key);
272
108
  } else {
273
- set5 = new Set;
109
+ set = new Set;
274
110
  state.callbacks.keys.add(key);
275
- state.callbacks.values.set(key, set5);
111
+ state.callbacks.values.set(key, set);
276
112
  }
277
113
  } else {
278
- set5 = state.callbacks.any;
114
+ set = state.callbacks.any;
279
115
  }
280
- if (set5 == null || set5.has(subscriber)) {
116
+ if (set == null || set.has(subscriber)) {
281
117
  return noop;
282
118
  }
283
- set5.add(subscriber);
119
+ set.add(subscriber);
284
120
  subscriber(state.value);
285
121
  return () => {
286
122
  unsubscribe(state, subscriber, key);
@@ -288,14 +124,14 @@ function subscribe(state, subscriber, key) {
288
124
  }
289
125
  function unsubscribe(state, subscriber, key) {
290
126
  if (key != null) {
291
- const set5 = state.callbacks.values.get(key);
292
- if (set5 != null) {
127
+ const set = state.callbacks.values.get(key);
128
+ if (set != null) {
293
129
  if (subscriber == null) {
294
- set5.clear();
130
+ set.clear();
295
131
  } else {
296
- set5.delete(subscriber);
132
+ set.delete(subscriber);
297
133
  }
298
- if (set5.size === 0) {
134
+ if (set.size === 0) {
299
135
  state.callbacks.keys.delete(key);
300
136
  state.callbacks.values.delete(key);
301
137
  }
@@ -309,7 +145,7 @@ function unsubscribe(state, subscriber, key) {
309
145
  function disable(state) {
310
146
  if (state.active) {
311
147
  state.active = false;
312
- const effects = [...state.callbacks.any, ...state.callbacks.values.values()].flatMap((value3) => value3 instanceof Set ? [...value3.values()] : value3).filter((value3) => typeof value3 !== "function");
148
+ const effects = [...state.callbacks.any, ...state.callbacks.values.values()].flatMap((value) => value instanceof Set ? [...value.values()] : value).filter((value) => typeof value !== "function");
313
149
  for (const fx of effects) {
314
150
  if (typeof fx !== "function") {
315
151
  fx.reactives.delete(state);
@@ -321,8 +157,8 @@ function emit(state, keys) {
321
157
  if (state.active) {
322
158
  const subscribers = [
323
159
  ...state.callbacks.any,
324
- ...[...state.callbacks.values.entries()].filter(([key]) => keys == null || keys.includes(key)).map(([, value3]) => value3)
325
- ].flatMap((value3) => value3 instanceof Set ? [...value3.values()] : value3).map((value3) => typeof value3 === "function" ? value3 : value3.callback);
160
+ ...[...state.callbacks.values.entries()].filter(([key]) => keys == null || keys.includes(key)).map(([, value]) => value)
161
+ ].flatMap((value) => value instanceof Set ? [...value.values()] : value).map((value) => typeof value === "function" ? value : value.callback);
326
162
  for (const subsriber of subscribers) {
327
163
  if (typeof subsriber === "function") {
328
164
  queue(() => {
@@ -340,13 +176,13 @@ function enable(state) {
340
176
  }
341
177
 
342
178
  // node_modules/@oscarpalmer/sentinel/dist/helpers/value.mjs
343
- function getValue3(reactive, key) {
179
+ function getValue(reactive, key) {
344
180
  watch(reactive, typeof key === "symbol" ? undefined : key);
345
181
  return key == null ? reactive.value : Array.isArray(reactive.value) ? reactive.value.at(key) : reactive.value[key];
346
182
  }
347
- function setValue3(reactive, value3) {
348
- if (!Object.is(reactive.value, value3)) {
349
- reactive.value = value3;
183
+ function setValue(reactive, value) {
184
+ if (!Object.is(reactive.value, value)) {
185
+ reactive.value = value;
350
186
  emit(reactive);
351
187
  }
352
188
  }
@@ -365,10 +201,10 @@ var arrayOperations = new Set([
365
201
  // node_modules/@oscarpalmer/sentinel/dist/reactive/instance.mjs
366
202
  class ReactiveInstance {
367
203
  state;
368
- constructor(type, value22) {
204
+ constructor(type, value2) {
369
205
  this.$sentinel = type;
370
206
  this.state = {
371
- value: value22,
207
+ value: value2,
372
208
  active: true,
373
209
  callbacks: {
374
210
  any: new Set,
@@ -378,7 +214,7 @@ class ReactiveInstance {
378
214
  };
379
215
  }
380
216
  get() {
381
- return getValue3(this.state);
217
+ return getValue(this.state);
382
218
  }
383
219
  peek() {
384
220
  return this.state.value;
@@ -390,10 +226,10 @@ class ReactiveInstance {
390
226
  disable(this.state);
391
227
  }
392
228
  toJSON() {
393
- return getValue3(this.state);
229
+ return getValue(this.state);
394
230
  }
395
231
  toString() {
396
- return String(getValue3(this.state));
232
+ return String(getValue(this.state));
397
233
  }
398
234
  }
399
235
 
@@ -420,7 +256,7 @@ class Computed extends ReactiveValue {
420
256
  fx;
421
257
  constructor(value32) {
422
258
  super("computed", undefined);
423
- this.fx = effect(() => setValue3(this.state, value32()));
259
+ this.fx = effect(() => setValue(this.state, value32()));
424
260
  }
425
261
  run() {
426
262
  this.fx.start();
@@ -431,17 +267,189 @@ class Computed extends ReactiveValue {
431
267
  }
432
268
  // node_modules/@oscarpalmer/sentinel/dist/reactive/index.mjs
433
269
  var primitives = new Set(["boolean", "number", "string"]);
270
+ // node_modules/@oscarpalmer/atoms/dist/js/string/index.mjs
271
+ function getString2(value10) {
272
+ if (typeof value10 === "string") {
273
+ return value10;
274
+ }
275
+ if (typeof value10 !== "object" || value10 == null) {
276
+ return String(value10);
277
+ }
278
+ const valueOff = value10.valueOf?.() ?? value10;
279
+ const asString = valueOff?.toString?.() ?? String(valueOff);
280
+ return asString.startsWith("[object ") ? JSON.stringify(value10) : asString;
281
+ }
282
+ // node_modules/@oscarpalmer/atoms/dist/js/is.mjs
283
+ function isNullableOrWhitespace(value10) {
284
+ return value10 == null || /^\s*$/.test(getString2(value10));
285
+ }
286
+ // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/string/index.mjs
287
+ function getString3(value11) {
288
+ if (typeof value11 === "string") {
289
+ return value11;
290
+ }
291
+ if (typeof value11 !== "object" || value11 == null) {
292
+ return String(value11);
293
+ }
294
+ const valueOff = value11.valueOf?.() ?? value11;
295
+ const asString = valueOff?.toString?.() ?? String(valueOff);
296
+ return asString.startsWith("[object ") ? JSON.stringify(value11) : asString;
297
+ }
298
+ // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/is.mjs
299
+ function isPlainObject3(value11) {
300
+ if (typeof value11 !== "object" || value11 === null) {
301
+ return false;
302
+ }
303
+ const prototype = Object.getPrototypeOf(value11);
304
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value11) && !(Symbol.iterator in value11);
305
+ }
306
+
307
+ // node_modules/@oscarpalmer/toretto/dist/attribute.mjs
308
+ function isBadAttribute(attribute) {
309
+ return onPrefix.test(attribute.name) || sourcePrefix.test(attribute.name) && valuePrefix.test(attribute.value);
310
+ }
311
+ function isBooleanAttribute(name) {
312
+ return booleanAttributes.includes(name.toLowerCase());
313
+ }
314
+ function isEmptyNonBooleanAttribute(attribute) {
315
+ return !booleanAttributes.includes(attribute.name) && attribute.value.trim().length === 0;
316
+ }
317
+ function isInvalidBooleanAttribute(attribute) {
318
+ if (!booleanAttributes.includes(attribute.name)) {
319
+ return true;
320
+ }
321
+ const normalised = attribute.value.toLowerCase().trim();
322
+ return !(normalised.length === 0 || normalised === attribute.name || attribute.name === "hidden" && normalised === "until-found");
323
+ }
324
+ function setAttribute(element, first, second) {
325
+ if (isPlainObject3(first) && typeof first?.name === "string") {
326
+ setAttributeValue(element, first.name, first.value);
327
+ } else if (typeof first === "string") {
328
+ setAttributeValue(element, first, second);
329
+ }
330
+ }
331
+ function setAttributeValue(element, name, value11) {
332
+ if (value11 == null) {
333
+ element.removeAttribute(name);
334
+ } else {
335
+ element.setAttribute(name, typeof value11 === "string" ? value11 : getString3(value11));
336
+ }
337
+ }
338
+ var booleanAttributes = Object.freeze([
339
+ "async",
340
+ "autofocus",
341
+ "autoplay",
342
+ "checked",
343
+ "controls",
344
+ "default",
345
+ "defer",
346
+ "disabled",
347
+ "formnovalidate",
348
+ "hidden",
349
+ "inert",
350
+ "ismap",
351
+ "itemscope",
352
+ "loop",
353
+ "multiple",
354
+ "muted",
355
+ "nomodule",
356
+ "novalidate",
357
+ "open",
358
+ "playsinline",
359
+ "readonly",
360
+ "required",
361
+ "reversed",
362
+ "selected"
363
+ ]);
364
+ var onPrefix = /^on/i;
365
+ var sourcePrefix = /^(href|src|xlink:href)$/i;
366
+ var valuePrefix = /(data:text\/html|javascript:)/i;
367
+
368
+ // node_modules/@oscarpalmer/toretto/dist/sanitise.mjs
369
+ function sanitise(value11, options) {
370
+ return sanitiseNodes(Array.isArray(value11) ? value11 : [value11], {
371
+ sanitiseBooleanAttributes: options?.sanitiseBooleanAttributes ?? true
372
+ });
373
+ }
374
+ function sanitiseAttributes(element, attributes, options) {
375
+ const { length } = attributes;
376
+ for (let index = 0;index < length; index += 1) {
377
+ const attribute2 = attributes[index];
378
+ if (isBadAttribute(attribute2) || isEmptyNonBooleanAttribute(attribute2)) {
379
+ element.removeAttribute(attribute2.name);
380
+ } else if (options.sanitiseBooleanAttributes && isInvalidBooleanAttribute(attribute2)) {
381
+ element.setAttribute(attribute2.name, "");
382
+ }
383
+ }
384
+ }
385
+ function sanitiseNodes(nodes, options) {
386
+ const { length } = nodes;
387
+ for (let index = 0;index < length; index += 1) {
388
+ const node = nodes[index];
389
+ if (node instanceof Element) {
390
+ sanitiseAttributes(node, [...node.attributes], options);
391
+ }
392
+ sanitiseNodes([...node.childNodes], options);
393
+ }
394
+ return nodes;
395
+ }
396
+
397
+ // node_modules/@oscarpalmer/toretto/dist/html.mjs
398
+ function createTemplate(html) {
399
+ const template4 = document.createElement("template");
400
+ template4.innerHTML = html;
401
+ templates[html] = template4;
402
+ return template4;
403
+ }
404
+ function getTemplate(value11) {
405
+ if (value11.trim().length === 0) {
406
+ return;
407
+ }
408
+ let template4;
409
+ if (/^[\w-]+$/.test(value11)) {
410
+ template4 = document.querySelector(`#${value11}`);
411
+ }
412
+ if (template4 instanceof HTMLTemplateElement) {
413
+ return template4;
414
+ }
415
+ return templates[value11] ?? createTemplate(value11);
416
+ }
417
+ function html(value11, sanitisation) {
418
+ const options = sanitisation == null || sanitisation === true ? {} : isPlainObject3(sanitisation) ? { ...sanitisation } : null;
419
+ const template4 = value11 instanceof HTMLTemplateElement ? value11 : typeof value11 === "string" ? getTemplate(value11) : null;
420
+ if (template4 == null) {
421
+ return [];
422
+ }
423
+ const cloned = template4.content.cloneNode(true);
424
+ const scripts = cloned.querySelectorAll("script");
425
+ const { length } = scripts;
426
+ for (let index = 0;index < length; index += 1) {
427
+ scripts[index].remove();
428
+ }
429
+ cloned.normalize();
430
+ return options != null ? sanitise([...cloned.childNodes], options) : [...cloned.childNodes];
431
+ }
432
+ var templates = {};
434
433
 
435
434
  // src/helpers/index.ts
435
+ function compareArrays(first, second) {
436
+ const firstIsLarger = first.length > second.length;
437
+ const from = firstIsLarger ? first : second;
438
+ const to = firstIsLarger ? second : first;
439
+ if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) {
440
+ return "dissimilar";
441
+ }
442
+ return firstIsLarger ? "removed" : "added";
443
+ }
444
+ function isChildNode(value11) {
445
+ return value11 instanceof CharacterData || value11 instanceof Element;
446
+ }
436
447
  function isFragment(value11) {
437
448
  return typeof value11 === "object" && value11 != null && "$fragment" in value11 && value11.$fragment === true;
438
449
  }
439
- function isProperElement(value11) {
450
+ function isHTMLOrSVGElement(value11) {
440
451
  return value11 instanceof HTMLElement || value11 instanceof SVGElement;
441
452
  }
442
- function isProperNode(value11) {
443
- return value11 instanceof CharacterData || value11 instanceof Element;
444
- }
445
453
 
446
454
  // src/node/event.ts
447
455
  function getController(element) {
@@ -471,23 +479,22 @@ function mapEvent(element, name, value11) {
471
479
  }
472
480
  }
473
481
  function removeEvents(element) {
474
- if (controllers.has(element)) {
475
- controllers.get(element)?.abort();
476
- controllers.delete(element);
477
- }
482
+ controllers.get(element)?.abort(reason);
483
+ controllers.delete(element);
478
484
  }
479
485
  var controllers = new WeakMap;
480
486
  var eventNamePattern = /^@([\w-]+)(?::([a-z:]+))?$/i;
487
+ var reason = "Event removed as element was removed from document by Abydon";
481
488
 
482
489
  // src/helpers/dom.ts
483
490
  function createNodes(value11) {
484
491
  if (isFragment(value11)) {
485
492
  return value11.get();
486
493
  }
487
- if (isProperNode(value11)) {
494
+ if (isChildNode(value11)) {
488
495
  return [value11];
489
496
  }
490
- return [new Text(getString(value11))];
497
+ return [new Text(getString2(value11))];
491
498
  }
492
499
  function removeNodes(nodes) {
493
500
  sanitiseNodes2(nodes);
@@ -497,20 +504,17 @@ function removeNodes(nodes) {
497
504
  }
498
505
  }
499
506
  function replaceNodes(from, to) {
507
+ from[0]?.replaceWith(...to);
500
508
  const { length } = from;
501
- for (let index = 0;index < length; index += 1) {
502
- if (index === 0) {
503
- from[index].replaceWith(...to);
504
- } else {
505
- from[index].remove();
506
- }
509
+ for (let index = 1;index < length; index += 1) {
510
+ from[index].remove();
507
511
  }
508
512
  }
509
513
  function sanitiseNodes2(nodes) {
510
514
  const { length } = nodes;
511
515
  for (let index = 0;index < length; index += 1) {
512
516
  const node = nodes[index];
513
- if (isProperElement(node)) {
517
+ if (isHTMLOrSVGElement(node)) {
514
518
  removeEvents(node);
515
519
  }
516
520
  if (node.hasChildNodes()) {
@@ -520,21 +524,21 @@ function sanitiseNodes2(nodes) {
520
524
  }
521
525
 
522
526
  // src/node/attribute/value.ts
523
- function setAttribute2(element, name, value11) {
527
+ function setAttribute2(data, element, name, value11) {
524
528
  element.removeAttribute(name);
525
529
  switch (true) {
526
530
  case classExpression.test(name):
527
- setClasses(element, name, value11);
531
+ setClasses(data, element, name, value11);
528
532
  return;
529
533
  case stylePrefixExpression.test(name):
530
- setStyle(element, name, value11);
534
+ setStyle(data, element, name, value11);
531
535
  return;
532
536
  default:
533
- setValue5(element, name, value11);
537
+ setValue5(data, element, name, value11);
534
538
  break;
535
539
  }
536
540
  }
537
- function setClasses(element, name, value11) {
541
+ function setClasses(data, element, name, value11) {
538
542
  function update(value12) {
539
543
  if (value12 === true) {
540
544
  element.classList.add(...classes);
@@ -544,38 +548,38 @@ function setClasses(element, name, value11) {
544
548
  }
545
549
  const classes = name.slice(6).split(".");
546
550
  if (isReactive(value11)) {
547
- effect(() => {
551
+ data.sentinel.effects.add(effect(() => {
548
552
  update(value11.get());
549
- });
553
+ }));
550
554
  } else {
551
555
  update(value11);
552
556
  }
553
557
  }
554
- function setStyle(element, name, value11) {
558
+ function setStyle(data, element, name, value11) {
555
559
  function update(value12) {
556
560
  if (value12 == null || value12 === false || value12 === true && unit == null) {
557
561
  element.style.removeProperty(property);
558
562
  } else {
559
- element.style.setProperty(property, value12 === true ? unit : getString(value12));
563
+ element.style.setProperty(property, value12 === true ? unit : getString2(value12));
560
564
  }
561
565
  }
562
566
  const [, property, unit] = styleFullExpression.exec(name) ?? [];
563
567
  if (property != null) {
564
568
  if (isReactive(value11)) {
565
- effect(() => {
569
+ data.sentinel.effects.add(effect(() => {
566
570
  update(value11.get());
567
- });
571
+ }));
568
572
  } else {
569
573
  update(value11);
570
574
  }
571
575
  }
572
576
  }
573
- function setValue5(element, name, value11) {
577
+ function setValue5(data, element, name, value11) {
574
578
  const callback = isBooleanAttribute(name) && name in element ? name === "selected" ? updateSelected : updateProperty : setAttribute;
575
579
  if (isReactive(value11)) {
576
- effect(() => {
580
+ data.sentinel.effects.add(effect(() => {
577
581
  callback(element, name, value11.get());
578
- });
582
+ }));
579
583
  } else {
580
584
  callback(element, name, value11);
581
585
  }
@@ -614,25 +618,88 @@ function mapAttributes(data, element) {
614
618
  if (name.startsWith("@")) {
615
619
  mapEvent(element, name, actual);
616
620
  } else if (name.includes(".") || typeof value12 === "function" || isReactive(actual)) {
617
- mapValue(element, name, actual);
621
+ mapValue(data, element, name, actual);
618
622
  }
619
623
  }
620
624
  }
621
- function mapValue(element, name, value12) {
625
+ function mapValue(data, element, name, value12) {
622
626
  switch (true) {
623
627
  case typeof value12 === "function":
624
- setAttribute2(element, name, computed(value12));
628
+ setComputedAttribute(data, element, name, value12);
625
629
  break;
626
630
  default:
627
- setAttribute2(element, name, value12);
631
+ setAttribute2(data, element, name, value12);
628
632
  break;
629
633
  }
630
634
  }
635
+ function setComputedAttribute(data, element, name, callback) {
636
+ const value12 = computed(callback);
637
+ data.sentinel.values.add(value12);
638
+ setAttribute2(data, element, name, value12);
639
+ }
631
640
  var commentExpression = /^<!--abydon\.(\d+)-->$/;
632
641
 
633
642
  // src/node/value.ts
634
- function setNodes(nodes, comment, text, value12) {
635
- const next = createNodes(value12);
643
+ function removeFragments(fragments) {
644
+ if (fragments != null) {
645
+ const { length } = fragments;
646
+ for (let index = 0;index < length; index += 1) {
647
+ fragments[index].remove();
648
+ }
649
+ }
650
+ }
651
+ function setArray(fragments, nodes, comment, text, value12) {
652
+ if (value12.length === 0) {
653
+ return {
654
+ nodes: setText(fragments, nodes, comment, text, value12)
655
+ };
656
+ }
657
+ let templates2 = value12.filter((item) => isFragment(item) && item.identifier != null);
658
+ const identifiers = templates2.map((fragment) => fragment.identifier);
659
+ const oldIdentifiers = fragments?.map((fragment) => fragment.identifier) ?? [];
660
+ if (new Set(identifiers).size !== templates2.length) {
661
+ templates2 = [];
662
+ }
663
+ const noTemplates = templates2.length === 0;
664
+ if (noTemplates || nodes == null || oldIdentifiers.some((identifier) => identifier == null)) {
665
+ return {
666
+ fragments: noTemplates ? undefined : templates2,
667
+ nodes: setNodes(fragments, nodes, comment, text, noTemplates ? value12.flatMap((item) => createNodes(item)) : templates2.flatMap((template4) => template4.get()))
668
+ };
669
+ }
670
+ const next = templates2.map((template4) => fragments?.find((fragment) => fragment.identifier === template4.identifier) ?? template4);
671
+ const comparison = compareArrays(fragments ?? [], templates2);
672
+ if (comparison !== "removed") {
673
+ let position = nodes[0];
674
+ const before = comparison === "added" && !oldIdentifiers.includes(templates2[0].identifier);
675
+ const items = next.flatMap((fragment) => fragment.get().flatMap((node) => ({
676
+ identifier: fragment.identifier,
677
+ value: node
678
+ })));
679
+ const { length: length2 } = items;
680
+ for (let index = 0;index < length2; index += 1) {
681
+ const item = items[index];
682
+ if (comparison === "dissimilar" || !oldIdentifiers.includes(item.identifier)) {
683
+ if (index === 0 && before) {
684
+ position.before(item.value);
685
+ } else {
686
+ position.after(item.value);
687
+ }
688
+ }
689
+ position = item.value;
690
+ }
691
+ }
692
+ const toRemove = fragments?.filter((fragment) => !identifiers.includes(fragment.identifier)) ?? [];
693
+ const { length } = toRemove;
694
+ for (let index = 0;index < length; index += 1) {
695
+ toRemove[index].remove();
696
+ }
697
+ return {
698
+ fragments: next,
699
+ nodes: next.flatMap((fragment) => fragment.get())
700
+ };
701
+ }
702
+ function setNodes(fragments, nodes, comment, text, next) {
636
703
  if (nodes == null) {
637
704
  if (comment.parentNode != null) {
638
705
  replaceNodes([comment], next);
@@ -642,42 +709,50 @@ function setNodes(nodes, comment, text, value12) {
642
709
  } else {
643
710
  replaceNodes(nodes, next);
644
711
  }
712
+ removeFragments(fragments);
645
713
  return next;
646
714
  }
647
- function setReactiveNode(data, comment, reactive3) {
715
+ function setReactiveValue(data, comment, reactive3) {
648
716
  const item = data.items.find((item2) => item2.nodes.includes(comment));
649
717
  const text = new Text;
718
+ let fragments;
650
719
  let nodes;
651
- effect(() => {
720
+ data.sentinel.effects.add(effect(() => {
652
721
  const value12 = reactive3.get();
653
- const valueIsFragment = isFragment(value12);
654
- if (valueIsFragment || isProperNode(value12)) {
655
- nodes = setNodes(nodes, comment, text, value12);
722
+ if (Array.isArray(value12)) {
723
+ const result = setArray(fragments, nodes, comment, text, value12);
724
+ fragments = typeof result === "boolean" ? undefined : result?.fragments;
725
+ nodes = typeof result === "boolean" ? result ? [text] : undefined : result?.nodes;
656
726
  } else {
657
- nodes = setText(nodes, comment, text, value12) ? [text] : undefined;
727
+ const valueIsFragment = isFragment(value12);
728
+ fragments = valueIsFragment ? [value12] : undefined;
729
+ if (valueIsFragment || isChildNode(value12)) {
730
+ nodes = setNodes(fragments, nodes, comment, text, createNodes(value12));
731
+ } else {
732
+ nodes = setText(fragments, nodes, comment, text, value12);
733
+ }
658
734
  }
659
735
  if (item != null) {
660
- item.fragment = valueIsFragment ? value12 : undefined;
736
+ item.fragments = fragments;
661
737
  item.nodes = [...nodes ?? [comment]];
662
738
  }
663
- });
739
+ }));
664
740
  }
665
- function setText(nodes, comment, text, value12) {
741
+ function setText(fragments, nodes, comment, text, value12) {
666
742
  const isNullable = isNullableOrWhitespace(value12);
667
- text.textContent = isNullable ? "" : getString(value12);
743
+ text.textContent = isNullable ? "" : getString2(value12);
744
+ let result = false;
668
745
  if (nodes != null) {
669
746
  replaceNodes(nodes, [isNullable ? comment : text]);
670
- return !isNullable;
671
- }
672
- if (isNullable && comment.parentNode == null) {
747
+ result = !isNullable;
748
+ } else if (isNullable && comment.parentNode == null) {
673
749
  text.replaceWith(comment);
674
- return false;
675
- }
676
- if (!isNullable && text.parentNode == null) {
750
+ } else if (!isNullable && text.parentNode == null) {
677
751
  comment.replaceWith(text);
678
- return true;
752
+ result = true;
679
753
  }
680
- return false;
754
+ removeFragments(fragments);
755
+ return result ? [text] : undefined;
681
756
  }
682
757
 
683
758
  // src/node/index.ts
@@ -696,7 +771,7 @@ function mapNodes(data, nodes) {
696
771
  mapNode(data, node);
697
772
  continue;
698
773
  }
699
- if (isProperElement(node)) {
774
+ if (isHTMLOrSVGElement(node)) {
700
775
  mapAttributes(data, node);
701
776
  }
702
777
  if (node.hasChildNodes()) {
@@ -707,10 +782,10 @@ function mapNodes(data, nodes) {
707
782
  function mapValue2(data, comment, value13) {
708
783
  switch (true) {
709
784
  case typeof value13 === "function":
710
- setReactiveNode(data, comment, computed(value13));
785
+ setComputedValue(data, comment, value13);
711
786
  break;
712
787
  case isReactive(value13):
713
- setReactiveNode(data, comment, value13);
788
+ setReactiveValue(data, comment, value13);
714
789
  break;
715
790
  default:
716
791
  replaceComment(data, comment, value13);
@@ -721,22 +796,57 @@ function replaceComment(data, comment, value13) {
721
796
  const item = data.items.find((item2) => item2.nodes.includes(comment));
722
797
  const nodes = createNodes(value13);
723
798
  if (item != null) {
724
- item.fragment = isFragment(value13) ? value13 : undefined;
799
+ item.fragments = isFragment(value13) ? [value13] : undefined;
725
800
  item.nodes = nodes;
726
801
  }
727
802
  comment.replaceWith(...nodes);
728
803
  }
804
+ function setComputedValue(data, comment, callback) {
805
+ const value13 = computed(callback);
806
+ data.sentinel.values.add(value13);
807
+ setReactiveValue(data, comment, value13);
808
+ }
729
809
  var commentExpression2 = /^abydon\.(\d+)$/;
730
810
 
731
811
  // src/fragment.ts
812
+ function removeFragment(data) {
813
+ removeSentinels(data);
814
+ const { length } = data.items;
815
+ for (let index = 0;index < length; index += 1) {
816
+ const { fragments, nodes } = data.items[index];
817
+ const { length: length2 } = fragments ?? [];
818
+ for (let index2 = 0;index2 < length2; index2 += 1) {
819
+ fragments?.[index2]?.remove();
820
+ }
821
+ removeNodes(nodes);
822
+ }
823
+ data.items.splice(0, length);
824
+ }
825
+ function removeSentinels(data) {
826
+ const sentinels = [...data.sentinel.effects, ...data.sentinel.values];
827
+ const { length } = sentinels;
828
+ for (let index = 0;index < length; index += 1) {
829
+ sentinels[index].stop();
830
+ }
831
+ data.sentinel.effects.clear();
832
+ data.sentinel.values.clear();
833
+ }
834
+
732
835
  class Fragment {
733
836
  $fragment = true;
734
837
  data;
838
+ get identifier() {
839
+ return this.data.identifier;
840
+ }
735
841
  constructor(strings, expressions) {
736
842
  this.data = {
737
843
  expressions,
738
844
  strings,
739
845
  items: [],
846
+ sentinel: {
847
+ effects: new Set,
848
+ values: new Set
849
+ },
740
850
  values: []
741
851
  };
742
852
  }
@@ -752,20 +862,18 @@ class Fragment {
752
862
  this.data.items.splice(0, this.data.items.length, ...templated.map((node2) => ({
753
863
  nodes: [node2]
754
864
  })));
755
- mapNodes(this.data, this.data.items.flatMap((item) => item.fragment?.get() ?? item.nodes));
865
+ mapNodes(this.data, this.data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes));
756
866
  }
757
867
  return [
758
- ...this.data.items.flatMap((item) => item.fragment?.get() ?? item.nodes)
868
+ ...this.data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes)
759
869
  ];
760
870
  }
871
+ identify(identifier) {
872
+ this.data.identifier = identifier;
873
+ return this;
874
+ }
761
875
  remove() {
762
- const { length } = this.data.items;
763
- for (let index = 0;index < length; index += 1) {
764
- const { fragment, nodes } = this.data.items[index];
765
- fragment?.remove();
766
- removeNodes(nodes);
767
- }
768
- this.data.items.splice(0, length);
876
+ removeFragment(this.data);
769
877
  }
770
878
  }
771
879