@oscarpalmer/abydon 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.
@@ -358,14 +358,14 @@ function setAtIndex(array$1, index, value) {
358
358
  function isKey(value) {
359
359
  return typeof value === "number" || typeof value === "string";
360
360
  }
361
- function isPlainObject$1(value) {
361
+ function isPlainObject(value) {
362
362
  if (value === null || typeof value !== "object") return false;
363
363
  if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
364
364
  const prototype = Object.getPrototypeOf(value);
365
365
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
366
366
  }
367
367
 
368
- function getString$1(value) {
368
+ function getString(value) {
369
369
  if (typeof value === "string") return value;
370
370
  if (value == null) return "";
371
371
  if (typeof value !== "object") return String(value);
@@ -374,7 +374,7 @@ function getString$1(value) {
374
374
  }
375
375
 
376
376
  function isNullableOrWhitespace(value) {
377
- return value == null || EXPRESSION_WHITESPACE.test(getString$1(value));
377
+ return value == null || EXPRESSION_WHITESPACE.test(getString(value));
378
378
  }
379
379
  var EXPRESSION_WHITESPACE = /^\s*$/;
380
380
 
@@ -397,7 +397,7 @@ var Store = class extends Reactive {
397
397
  }
398
398
  set(first, second) {
399
399
  if (isKey(first)) this.state.value[first] = second;
400
- else if (first == null || isPlainObject$1(first)) setProxyValue(this.state.value, first ?? {});
400
+ else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
401
401
  }
402
402
  subscribe(first, second) {
403
403
  if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
@@ -405,11 +405,11 @@ var Store = class extends Reactive {
405
405
  }
406
406
  update(callback) {
407
407
  const updated = callback({ ...this.state.value });
408
- if (updated == null || isPlainObject$1(updated)) setProxyValue(this.state.value, updated ?? {});
408
+ if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
409
409
  }
410
410
  };
411
411
  function store(value, options) {
412
- return new Store(isPlainObject$1(value) ? value : {}, options);
412
+ return new Store(isPlainObject(value) ? value : {}, options);
413
413
  }
414
414
 
415
415
  function isChildNode(value) {
@@ -426,21 +426,6 @@ var CHILD_NODE_TYPES = new Set([
426
426
  Node.DOCUMENT_TYPE_NODE
427
427
  ]);
428
428
 
429
- function getString(value) {
430
- if (typeof value === "string") return value;
431
- if (value == null) return "";
432
- if (typeof value !== "object") return String(value);
433
- const asString = String(value.valueOf?.() ?? value);
434
- return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
435
- }
436
-
437
- function isPlainObject(value) {
438
- if (value === null || typeof value !== "object") return false;
439
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
440
- const prototype = Object.getPrototypeOf(value);
441
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
442
- }
443
-
444
429
  function isAttribute(value) {
445
430
  return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
446
431
  }
@@ -524,14 +509,6 @@ const booleanAttributes = Object.freeze([
524
509
  "selected"
525
510
  ]);
526
511
 
527
- function getOptions$1(input) {
528
- const options = isPlainObject(input) ? input : {};
529
- options.sanitizeBooleanAttributes = typeof options.sanitizeBooleanAttributes === "boolean" ? options.sanitizeBooleanAttributes : true;
530
- return options;
531
- }
532
- function sanitize(value, options) {
533
- return sanitizeNodes$1(Array.isArray(value) ? value : [value], getOptions$1(options));
534
- }
535
512
  function sanitizeAttributes(element, attributes, options) {
536
513
  const { length } = attributes;
537
514
  for (let index = 0; index < length; index += 1) {
@@ -545,50 +522,179 @@ function sanitizeNodes$1(nodes, options) {
545
522
  const { length } = nodes;
546
523
  for (let index = 0; index < length; index += 1) {
547
524
  const node = actual[index];
548
- if (node instanceof Element) sanitizeAttributes(node, [...node.attributes], options);
525
+ if (node instanceof Element) {
526
+ const scripts = node.querySelectorAll("script");
527
+ for (const script of scripts) script.remove();
528
+ sanitizeAttributes(node, [...node.attributes], options);
529
+ }
549
530
  if (node.hasChildNodes()) sanitizeNodes$1([...node.childNodes], options);
550
531
  }
551
532
  return nodes;
552
533
  }
553
534
 
554
- function createTemplate(html$1) {
535
+ function createTemplate(html$1, ignore) {
555
536
  const template = document.createElement("template");
556
537
  template.innerHTML = html$1;
557
- templates[html$1] = template;
538
+ if (!ignore) templates[html$1] = template;
558
539
  return template;
559
540
  }
560
- function getTemplate(value) {
541
+ function getHtml(value, options) {
542
+ if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
543
+ const template = value instanceof HTMLTemplateElement ? value : getTemplate(value, options.ignoreCache);
544
+ if (template == null) return [];
545
+ const cloned = template.content.cloneNode(true);
546
+ const scripts = cloned.querySelectorAll("script");
547
+ for (const script of scripts) script.remove();
548
+ cloned.normalize();
549
+ return sanitizeNodes$1([...cloned.childNodes], options);
550
+ }
551
+ function getOptions$1(input) {
552
+ const options = isPlainObject(input) ? input : {};
553
+ options.ignoreCache = typeof options.ignoreCache === "boolean" ? options.ignoreCache : false;
554
+ options.sanitizeBooleanAttributes = typeof options.sanitizeBooleanAttributes === "boolean" ? options.sanitizeBooleanAttributes : true;
555
+ return options;
556
+ }
557
+ function getTemplate(value, ignore) {
561
558
  if (typeof value !== "string" || value.trim().length === 0) return;
562
559
  let template = templates[value];
563
560
  if (template != null) return template;
564
561
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
565
- template = element instanceof HTMLTemplateElement ? element : createTemplate(value);
566
- templates[value] = template;
562
+ template = element instanceof HTMLTemplateElement ? element : createTemplate(value, ignore);
567
563
  return template;
568
564
  }
569
- var html$1 = ((value, sanitization) => {
570
- if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
571
- let options;
572
- if (sanitization == null || sanitization === true) options = {};
573
- else options = sanitization === false ? void 0 : sanitization;
574
- const template = value instanceof HTMLTemplateElement ? value : getTemplate(value);
575
- if (template == null) return [];
576
- const cloned = template.content.cloneNode(true);
577
- const scripts = cloned.querySelectorAll("script");
578
- const { length } = scripts;
579
- for (let index = 0; index < length; index += 1) scripts[index].remove();
580
- cloned.normalize();
581
- return options != null ? sanitize([...cloned.childNodes], options) : [...cloned.childNodes];
565
+ var html$1 = ((value, options) => {
566
+ return getHtml(value, getOptions$1(options));
582
567
  });
583
568
  html$1.clear = () => {
584
569
  templates = {};
585
570
  };
586
571
  html$1.remove = (template) => {
587
- if (typeof template === "string") templates[template] = void 0;
572
+ if (typeof template !== "string" || templates[template] == null) return;
573
+ const keys = Object.keys(templates);
574
+ const { length } = keys;
575
+ const updated = {};
576
+ for (let index = 0; index < length; index += 1) {
577
+ const key = keys[index];
578
+ if (key !== template) updated[key] = templates[key];
579
+ }
580
+ templates = updated;
588
581
  };
589
582
  var EXPRESSION_ID = /^[a-z][\w-]*$/i;
590
583
  var templates = {};
591
584
 
585
+ function compareArrays(first, second) {
586
+ const firstIsLarger = first.length > second.length;
587
+ const from = firstIsLarger ? first : second;
588
+ const to = firstIsLarger ? second : first;
589
+ if (!from
590
+ .filter(key => to.includes(key))
591
+ .every((key, index) => to[index] === key)) {
592
+ return 'dissimilar';
593
+ }
594
+ return firstIsLarger ? 'removed' : 'added';
595
+ }
596
+ function isFragment(value) {
597
+ return (typeof value === 'object' &&
598
+ value != null &&
599
+ '$fragment' in value &&
600
+ value.$fragment === true);
601
+ }
602
+ function isFragments(value) {
603
+ return (typeof value === 'object' &&
604
+ value != null &&
605
+ '$fragments' in value &&
606
+ value.$fragments === true);
607
+ }
608
+
609
+ class Fragments {
610
+ #state;
611
+ /**
612
+ * Fragment items
613
+ */
614
+ get items() {
615
+ return this.#state.mapped;
616
+ }
617
+ constructor(items, identify, fragment) {
618
+ Object.defineProperty(this, '$fragments', {
619
+ value: true,
620
+ });
621
+ this.#state = {
622
+ fragment,
623
+ identify,
624
+ array: items,
625
+ instances: {},
626
+ mapped: array([]),
627
+ subscriber: undefined,
628
+ };
629
+ states.set(this, this.#state);
630
+ initializeFragments(this.#state);
631
+ }
632
+ }
633
+ function handleFragments(item, remove) {
634
+ const state = isFragments(item) ? states.get(item) : item;
635
+ if (state != null) {
636
+ (remove ? removeFragments$1 : initializeFragments)(state);
637
+ }
638
+ }
639
+ function handleItems(state, items) {
640
+ const keys = new Set();
641
+ const mapped = [];
642
+ const { length } = items;
643
+ for (let index = 0; index < length; index += 1) {
644
+ const item = items[index];
645
+ const identifier = state.identify(item);
646
+ if (identifier == null) {
647
+ throw new Error('Identifier cannot be null or undefined');
648
+ }
649
+ const key = getString(identifier);
650
+ if (keys.has(key)) {
651
+ throw new Error(`Duplicate identifier found: "${key}"`);
652
+ }
653
+ let instance = state.instances[key];
654
+ if (instance == null) {
655
+ instance = state.fragment(item);
656
+ if (!isFragment(instance)) {
657
+ throw new Error('Fragment function must return a Fragment instance');
658
+ }
659
+ }
660
+ instance.identify(key);
661
+ state.instances[key] = instance;
662
+ keys.add(key);
663
+ mapped.push(instance);
664
+ }
665
+ state.mapped.set(mapped);
666
+ updateFragments(state, keys);
667
+ }
668
+ function initializeFragments(state) {
669
+ state.subscriber ??= state.array.subscribe(items => {
670
+ handleItems(state, items);
671
+ });
672
+ }
673
+ function removeFragments$1(state) {
674
+ state.subscriber?.();
675
+ updateFragments(state);
676
+ state.subscriber = undefined;
677
+ }
678
+ function updateFragments(state, active) {
679
+ const next = {};
680
+ const previous = { ...state.instances };
681
+ const keys = Object.keys(previous);
682
+ const { length } = keys;
683
+ for (let index = 0; index < length; index += 1) {
684
+ const key = keys[index];
685
+ if (active?.has(key)) {
686
+ next[key] = previous[key];
687
+ }
688
+ else {
689
+ previous[key].remove();
690
+ }
691
+ }
692
+ state.instances = next;
693
+ active?.clear();
694
+ }
695
+ //
696
+ const states = new WeakMap();
697
+
592
698
  const ABORT_CONTROLLERS = new WeakMap();
593
699
  const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
594
700
  const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
@@ -630,24 +736,6 @@ function removeEvents(element) {
630
736
  ABORT_CONTROLLERS.delete(element);
631
737
  }
632
738
 
633
- function compareArrays(first, second) {
634
- const firstIsLarger = first.length > second.length;
635
- const from = firstIsLarger ? first : second;
636
- const to = firstIsLarger ? second : first;
637
- if (!from
638
- .filter(key => to.includes(key))
639
- .every((key, index) => to[index] === key)) {
640
- return 'dissimilar';
641
- }
642
- return firstIsLarger ? 'removed' : 'added';
643
- }
644
- function isFragment(value) {
645
- return (typeof value === 'object' &&
646
- value != null &&
647
- '$fragment' in value &&
648
- value.$fragment === true);
649
- }
650
-
651
739
  function createNodes(value) {
652
740
  if (isFragment(value)) {
653
741
  return value.get();
@@ -655,7 +743,7 @@ function createNodes(value) {
655
743
  if (isChildNode(value)) {
656
744
  return [value];
657
745
  }
658
- return [new Text(getString$1(value))];
746
+ return [new Text(getString(value))];
659
747
  }
660
748
  function removeNodes(nodes) {
661
749
  sanitizeNodes(nodes);
@@ -725,7 +813,7 @@ function setStyle(data, element, name, value) {
725
813
  element.style.removeProperty(property);
726
814
  }
727
815
  else {
728
- element.style.setProperty(property, value === true ? unit : getString$1(value));
816
+ element.style.setProperty(property, value === true ? unit : getString(value));
729
817
  }
730
818
  }
731
819
  if (isReactive(value)) {
@@ -849,6 +937,16 @@ function removeFragments(fragments) {
849
937
  }
850
938
  }
851
939
  }
940
+ function replaceText(item, comment, isNullable) {
941
+ let to;
942
+ if (isNullable) {
943
+ to = [comment];
944
+ }
945
+ else {
946
+ to = item.text == null ? [] : [item.text];
947
+ }
948
+ replaceNodes(item.nodes ?? [], to);
949
+ }
852
950
  function setArray(item, comment, value) {
853
951
  if (value.length === 0) {
854
952
  return {
@@ -913,7 +1011,12 @@ function setReactiveValueForArray(item, comment, value) {
913
1011
  const result = setArray(item, comment, value);
914
1012
  item.fragments = typeof result === 'boolean' ? undefined : result?.fragments;
915
1013
  if (typeof result === 'boolean') {
916
- item.nodes = result ? item.text == null ? [] : [item.text] : undefined;
1014
+ if (result) {
1015
+ item.nodes = item.text == null ? [] : [item.text];
1016
+ }
1017
+ else {
1018
+ item.nodes = undefined;
1019
+ }
917
1020
  }
918
1021
  else {
919
1022
  item.nodes = result?.nodes;
@@ -932,11 +1035,11 @@ function setReactiveValueForSingle(item, comment, value) {
932
1035
  function setText(item, comment, value) {
933
1036
  const isNullable = isNullableOrWhitespace(value);
934
1037
  if (item.text != null) {
935
- item.text.textContent = isNullable ? '' : getString$1(value);
1038
+ item.text.textContent = isNullable ? '' : getString(value);
936
1039
  }
937
1040
  let result = false;
938
1041
  if (item.nodes != null) {
939
- replaceNodes(item.nodes, isNullable ? [comment] : item.text == null ? [] : [item.text]);
1042
+ replaceText(item, comment, isNullable);
940
1043
  result = !isNullable;
941
1044
  }
942
1045
  else if (isNullable && comment.parentNode == null) {
@@ -949,7 +1052,9 @@ function setText(item, comment, value) {
949
1052
  result = true;
950
1053
  }
951
1054
  removeFragments(item.fragments);
952
- return result ? item.text == null ? [] : [item.text] : undefined;
1055
+ if (result) {
1056
+ return item.text == null ? [] : [item.text];
1057
+ }
953
1058
  }
954
1059
 
955
1060
  function mapNode(data, comment) {
@@ -980,6 +1085,10 @@ function mapValue(data, comment, value) {
980
1085
  case typeof value === 'function':
981
1086
  setComputedValue(data, comment, value);
982
1087
  break;
1088
+ case isFragments(value):
1089
+ handleFragments(value, false);
1090
+ setReactiveValue(data, comment, value.items);
1091
+ break;
983
1092
  case isReactive(value):
984
1093
  setReactiveValue(data, comment, value);
985
1094
  break;
@@ -1033,34 +1142,22 @@ function parse(data) {
1033
1142
  return data.template;
1034
1143
  }
1035
1144
 
1036
- function calculate() {
1037
- return new Promise((resolve) => {
1038
- const values = [];
1039
- let last;
1040
- function step(now) {
1041
- if (last != null) values.push(now - last);
1042
- last = now;
1043
- if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM));
1044
- else requestAnimationFrame(step);
1045
- }
1046
- requestAnimationFrame(step);
1047
- });
1048
- }
1049
- var CALCULATION_TOTAL = 10;
1050
- var CALCULATION_TRIM = 4;
1051
- calculate().then((value) => {
1052
- });
1053
-
1054
1145
  class Fragment {
1055
1146
  #data;
1056
1147
  #configuration = {
1057
1148
  identifier: undefined,
1058
1149
  ignoreCache: false,
1059
1150
  };
1151
+ /**
1152
+ * Fragment identifier
1153
+ */
1060
1154
  get identifier() {
1061
1155
  return this.#configuration.identifier;
1062
1156
  }
1063
1157
  constructor(strings, expressions) {
1158
+ Object.defineProperty(this, '$fragment', {
1159
+ value: true,
1160
+ });
1064
1161
  this.#data = {
1065
1162
  expressions,
1066
1163
  strings,
@@ -1071,18 +1168,21 @@ class Fragment {
1071
1168
  },
1072
1169
  values: [],
1073
1170
  };
1074
- Object.defineProperty(this, '$fragment', {
1075
- value: true,
1076
- });
1077
1171
  }
1078
1172
  /**
1079
- * Appends the fragment to the given element
1173
+ * Append the fragment to the given element
1174
+ * @param element Element to append to
1080
1175
  */
1081
1176
  appendTo(element) {
1082
1177
  element.append(...this.get());
1083
1178
  }
1179
+ /**
1180
+ * Configure the fragment
1181
+ * @param configuration Configuration options
1182
+ * @returns Fragment
1183
+ */
1084
1184
  configure(configuration) {
1085
- const actual = isPlainObject$1(configuration) ? configuration : {};
1185
+ const actual = isPlainObject(configuration) ? configuration : {};
1086
1186
  if (actual.identifier !== undefined) {
1087
1187
  this.#configuration.identifier = actual.identifier;
1088
1188
  }
@@ -1092,33 +1192,44 @@ class Fragment {
1092
1192
  return this;
1093
1193
  }
1094
1194
  /**
1095
- * Gets a list of the fragment's nodes
1195
+ * Get a list of the fragment's nodes
1196
+ * @returns List of nodes
1096
1197
  */
1097
1198
  get() {
1098
1199
  const data = this.#data;
1099
1200
  if (data.items.length === 0) {
1100
1201
  const parsed = parse(data);
1101
1202
  const templated = html$1(parsed, {
1203
+ ignoreCache: this.#configuration.ignoreCache,
1102
1204
  sanitizeBooleanAttributes: false,
1103
1205
  });
1104
- if (this.#configuration.ignoreCache) {
1105
- html$1.remove(parsed);
1106
- }
1107
1206
  data.items.splice(0, data.items.length, ...templated.map(node => ({
1108
1207
  nodes: [node],
1109
1208
  })));
1110
- mapNodes(data, data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes ?? []));
1209
+ mapNodes(data, data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ??
1210
+ item.nodes ??
1211
+ []));
1111
1212
  }
1112
1213
  return [
1113
- ...data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes ?? []),
1214
+ ...data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ??
1215
+ item.nodes ??
1216
+ []),
1114
1217
  ];
1115
1218
  }
1219
+ /**
1220
+ * Set an identifier for the fragment
1221
+ *
1222
+ * _An identifier can be used to uniquely identify a fragment,
1223
+ * which helps prevent re-rendering in certain scenarios._
1224
+ * @param identifier Identifier
1225
+ * @returns Fragment
1226
+ */
1116
1227
  identify(identifier) {
1117
1228
  this.#configuration.identifier = identifier;
1118
1229
  return this;
1119
1230
  }
1120
1231
  /**
1121
- * Removes the fragment from the DOM
1232
+ * Remove the fragment from the DOM
1122
1233
  */
1123
1234
  remove() {
1124
1235
  removeFragment(this.#data);
@@ -1126,16 +1237,23 @@ class Fragment {
1126
1237
  }
1127
1238
  function removeFragment(data) {
1128
1239
  removeMora(data);
1129
- const { length } = data.items;
1240
+ let { length } = data.items;
1130
1241
  for (let index = 0; index < length; index += 1) {
1131
1242
  const { fragments, nodes } = data.items[index];
1132
- const length = fragments?.length ?? 0;
1133
- for (let index = 0; index < length; index += 1) {
1134
- fragments?.[index]?.remove();
1243
+ const fragmentsLength = fragments?.length ?? 0;
1244
+ for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) {
1245
+ fragments?.[fragmentIndex]?.remove();
1135
1246
  }
1136
1247
  removeNodes(nodes ?? []);
1137
1248
  }
1138
1249
  data.items.length = 0;
1250
+ length = data.values.length;
1251
+ for (let index = 0; index < length; index += 1) {
1252
+ const value = data.values[index];
1253
+ if (isFragments(value)) {
1254
+ handleFragments(value, true);
1255
+ }
1256
+ }
1139
1257
  }
1140
1258
  function removeMora(data) {
1141
1259
  const unsubscribers = [...data.mora.subscribers];
@@ -1146,8 +1264,11 @@ function removeMora(data) {
1146
1264
  }
1147
1265
  }
1148
1266
 
1267
+ function fragments(array, identify, fragment) {
1268
+ return new Fragments(array, identify, fragment);
1269
+ }
1149
1270
  function html(strings, ...values) {
1150
1271
  return new Fragment(strings, values);
1151
1272
  }
1152
1273
 
1153
- export { array, computed, effect, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
1274
+ export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
package/dist/fragment.js CHANGED
@@ -1,13 +1,21 @@
1
1
  import { parse } from "./parse.js";
2
+ import { isFragments } from "./helpers/index.js";
3
+ import { handleFragments } from "./fragments.js";
2
4
  import { removeNodes } from "./helpers/dom.js";
3
5
  import { mapNodes } from "./node/index.js";
6
+ import { isPlainObject } from "@oscarpalmer/atoms/is";
4
7
  import { html } from "@oscarpalmer/toretto/html";
5
8
  var Fragment = class {
6
9
  #data;
10
+ #configuration = {
11
+ identifier: void 0,
12
+ ignoreCache: false
13
+ };
7
14
  get identifier() {
8
- return this.#data.identifier;
15
+ return this.#configuration.identifier;
9
16
  }
10
17
  constructor(strings, expressions) {
18
+ Object.defineProperty(this, "$fragment", { value: true });
11
19
  this.#data = {
12
20
  expressions,
13
21
  strings,
@@ -18,22 +26,30 @@ var Fragment = class {
18
26
  },
19
27
  values: []
20
28
  };
21
- Object.defineProperty(this, "$fragment", { value: true });
22
29
  }
23
30
  appendTo(element) {
24
31
  element.append(...this.get());
25
32
  }
33
+ configure(configuration) {
34
+ const actual = isPlainObject(configuration) ? configuration : {};
35
+ if (actual.identifier !== void 0) this.#configuration.identifier = actual.identifier;
36
+ if (typeof actual.ignoreCache === "boolean") this.#configuration.ignoreCache = actual.ignoreCache;
37
+ return this;
38
+ }
26
39
  get() {
27
40
  const data = this.#data;
28
41
  if (data.items.length === 0) {
29
- const templated = html(parse(data), { sanitizeBooleanAttributes: false });
42
+ const templated = html(parse(data), {
43
+ ignoreCache: this.#configuration.ignoreCache,
44
+ sanitizeBooleanAttributes: false
45
+ });
30
46
  data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
31
- mapNodes(data, data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes));
47
+ mapNodes(data, data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []));
32
48
  }
33
- return [...data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes)];
49
+ return [...data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? [])];
34
50
  }
35
51
  identify(identifier) {
36
- this.#data.identifier = identifier;
52
+ this.#configuration.identifier = identifier;
37
53
  return this;
38
54
  }
39
55
  remove() {
@@ -42,14 +58,19 @@ var Fragment = class {
42
58
  };
43
59
  function removeFragment(data) {
44
60
  removeMora(data);
45
- const { length } = data.items;
61
+ let { length } = data.items;
46
62
  for (let index = 0; index < length; index += 1) {
47
63
  const { fragments, nodes } = data.items[index];
48
- const { length: length$1 } = fragments ?? [];
49
- for (let index$1 = 0; index$1 < length$1; index$1 += 1) fragments?.[index$1]?.remove();
50
- removeNodes(nodes);
64
+ const fragmentsLength = fragments?.length ?? 0;
65
+ for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) fragments?.[fragmentIndex]?.remove();
66
+ removeNodes(nodes ?? []);
67
+ }
68
+ data.items.length = 0;
69
+ length = data.values.length;
70
+ for (let index = 0; index < length; index += 1) {
71
+ const value = data.values[index];
72
+ if (isFragments(value)) handleFragments(value, true);
51
73
  }
52
- data.items.splice(0, length);
53
74
  }
54
75
  function removeMora(data) {
55
76
  const unsubscribers = [...data.mora.subscribers];