@oscarpalmer/abydon 0.20.0 → 0.21.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.
@@ -215,18 +215,10 @@ var Computed = class extends Reactive {
215
215
  constructor(callback, options) {
216
216
  super(NAME_COMPUTED, void 0, options);
217
217
  this.effect.instance = effect(() => {
218
- if (!this.effect.dirty) return;
219
- const previousComputed = ACTIVE.computed;
220
- ACTIVE.computed = this;
221
- const value = callback();
222
- ACTIVE.computed = previousComputed;
223
- if (!this.state.equal(this.state.value, value)) {
224
- this.state.value = value;
225
- for (const computed of this.state.computeds) computed.effect.dirty = true;
226
- for (const effect of this.state.effects) BATCH.handlers.add(effect);
227
- for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
218
+ if (this.effect.dirty) {
219
+ setValue$2(this, this.state, callback);
220
+ this.effect.dirty = false;
228
221
  }
229
- this.effect.dirty = false;
230
222
  });
231
223
  }
232
224
  /**
@@ -248,6 +240,34 @@ var Computed = class extends Reactive {
248
240
  function computed(callback, options) {
249
241
  return new Computed(callback, options);
250
242
  }
243
+ function setAndEmit$1(state, value) {
244
+ if (state.equal(state.value, value)) return;
245
+ state.value = value;
246
+ for (const computed of state.computeds) computed.effect.dirty = true;
247
+ for (const effect of state.effects) BATCH.handlers.add(effect);
248
+ for (const [, subscription] of state.subscriptions) subscription.callback(value);
249
+ flushHandlers();
250
+ }
251
+ function setValue$2(instance, state, callback) {
252
+ const previousComputed = ACTIVE.computed;
253
+ ACTIVE.computed = instance;
254
+ try {
255
+ const value = callback();
256
+ if (value instanceof Promise) {
257
+ state.promise = value;
258
+ value.then((resolvedValue) => {
259
+ if (state.promise === value) {
260
+ state.promise = void 0;
261
+ setAndEmit$1(state, resolvedValue);
262
+ }
263
+ }).catch(() => {
264
+ if (state.promise === value) state.promise = void 0;
265
+ });
266
+ } else setAndEmit$1(state, value);
267
+ } finally {
268
+ ACTIVE.computed = previousComputed;
269
+ }
270
+ }
251
271
  //#endregion
252
272
  //#region node_modules/@oscarpalmer/mora/dist/helpers/value.mjs
253
273
  function emitValue(state) {
@@ -291,10 +311,7 @@ var Signal = class extends Reactive {
291
311
  * @param value New value
292
312
  */
293
313
  set(value) {
294
- if (!this.state.equal(this.state.value, value)) {
295
- this.state.value = value;
296
- emitValue(this.state);
297
- }
314
+ setValue$1(this.state, value);
298
315
  }
299
316
  /**
300
317
  * Update the value _(based on the current value)_
@@ -304,14 +321,33 @@ var Signal = class extends Reactive {
304
321
  this.set(callback(this.state.value));
305
322
  }
306
323
  };
307
- /**
308
- * Create a reactive value
309
- * @param value Initial value
310
- * @param options Reactivity options
311
- * @returns Reactive value
312
- */
324
+ function setAndEmit(state, value) {
325
+ if (!state.equal(state.value, value)) {
326
+ state.value = value;
327
+ emitValue(state);
328
+ }
329
+ }
330
+ function setValue$1(state, value) {
331
+ try {
332
+ let actual = value;
333
+ if (typeof value === "function") actual = value();
334
+ if (actual instanceof Promise) {
335
+ state.promise = actual;
336
+ actual.then((value) => {
337
+ if (actual === state.promise) {
338
+ state.promise = void 0;
339
+ setAndEmit(state, value);
340
+ }
341
+ }).catch(() => {
342
+ if (actual === state.promise) state.promise = void 0;
343
+ });
344
+ } else setAndEmit(state, actual);
345
+ } catch {}
346
+ }
313
347
  function signal(value, options) {
314
- return new Signal(value, options);
348
+ const instance = new Signal(void 0, options);
349
+ instance.set(value);
350
+ return instance;
315
351
  }
316
352
  //#endregion
317
353
  //#region node_modules/@oscarpalmer/mora/dist/helpers/proxy.mjs
@@ -329,21 +365,44 @@ function getReactiveValueInProxy(reactive, mapped, key, isArray) {
329
365
  }
330
366
  return item;
331
367
  }
332
- function setProxyValue(proxy, value) {
333
- startBatch();
334
- const proxyKeys = Object.keys(proxy);
335
- const valueKeys = Object.keys(value);
336
- let { length } = proxyKeys;
337
- for (let index = 0; index < length; index += 1) {
338
- const key = proxyKeys[index];
339
- proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
368
+ function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
369
+ if (array && first === "length") {
370
+ state.value.length = second;
371
+ return;
340
372
  }
341
- length = valueKeys.length;
342
- for (let index = 0; index < length; index += 1) {
343
- const key = valueKeys[index];
344
- if (!proxyKeys.includes(key)) proxy[key] = value[key];
373
+ if (isObject(first)) {
374
+ setObject(state, first);
375
+ return;
345
376
  }
346
- stopBatch();
377
+ const property = isProperty(first);
378
+ if (array && property && Number.isNaN(first)) return;
379
+ let actual = property ? second : first;
380
+ if (typeof actual === "function") try {
381
+ actual = actual();
382
+ } catch {
383
+ return;
384
+ }
385
+ if (actual instanceof Promise) {
386
+ if (property) {
387
+ state.promises ??= /* @__PURE__ */ new Map();
388
+ state.promises.set(first, actual);
389
+ } else state.promise = actual;
390
+ actual.then((value) => {
391
+ if (property && state.promises.get(first) === actual) {
392
+ state.promises.delete(first);
393
+ setProperty(state, first, value);
394
+ return;
395
+ }
396
+ if (!property && isObject(value) && state.promise === actual) {
397
+ state.promise = void 0;
398
+ setObject(state, value);
399
+ }
400
+ }).catch(() => {
401
+ if (property && state.promises.get(first) === actual) state.promises.delete(first);
402
+ else if (!property && state.promise === actual) state.promise = void 0;
403
+ });
404
+ } else if (property) setProperty(state, first, actual);
405
+ else if (isObject(actual)) setObject(state, actual);
347
406
  }
348
407
  function setValueInProxy(parameters) {
349
408
  const { isArray, length, property, state, target, value } = parameters;
@@ -426,7 +485,7 @@ var ReactiveArray = class extends Reactive {
426
485
  }
427
486
  peek(value) {
428
487
  if (value === "length") return this.#size.peek();
429
- return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
488
+ return typeof value === "number" ? this.state.value.at(value) : this.state.value.slice();
430
489
  }
431
490
  /**
432
491
  * Remove and return the last item of the array
@@ -444,9 +503,7 @@ var ReactiveArray = class extends Reactive {
444
503
  return this.state.value.push(...items);
445
504
  }
446
505
  set(first, second) {
447
- if (first == null || Array.isArray(first)) this.state.value.splice(0, this.state.value.length, ...first ?? []);
448
- else if (first === "length") this.length = second;
449
- else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
506
+ setProxyValue(true, this.state, isArrayValue, isArrayIndex, setArray$1, setAtIndex, first, second);
450
507
  }
451
508
  /**
452
509
  * Remove and return the first item of the array
@@ -486,18 +543,20 @@ var ReactiveArray = class extends Reactive {
486
543
  if (updated == null || Array.isArray(updated)) this.set(updated);
487
544
  }
488
545
  };
489
- /**
490
- * Create a reactive array
491
- * @param value Initial array of items
492
- * @param options Reactivity options
493
- * @returns Reactive array
494
- */
495
546
  function array(value, options) {
496
- return new ReactiveArray(Array.isArray(value) ? value : [], options);
547
+ const instance = new ReactiveArray([], options);
548
+ instance.set(value);
549
+ return instance;
550
+ }
551
+ function isArrayIndex(value) {
552
+ return typeof value === "number";
553
+ }
554
+ function isArrayValue(value) {
555
+ return value == null || Array.isArray(value);
497
556
  }
498
557
  function updateArray(type, array, state, length) {
499
558
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
500
- const previousArray = affectsLength ? [] : [...array];
559
+ const previousArray = affectsLength ? [] : array.slice();
501
560
  const previousLength = array.length;
502
561
  return (...args) => {
503
562
  const result = array[type](...args);
@@ -508,12 +567,15 @@ function updateArray(type, array, state, length) {
508
567
  return result;
509
568
  };
510
569
  }
511
- function setAtIndex(array, index, value) {
512
- const actual = index < 0 ? array.length + index : index;
513
- if (actual > -1) array[actual] = value;
570
+ function setArray$1(state, value) {
571
+ state.value.splice(0, state.value.length, ...value ?? []);
572
+ }
573
+ function setAtIndex(state, index, value) {
574
+ const actual = index < 0 ? state.value.length + index : index;
575
+ if (actual > -1) state.value[actual] = value;
514
576
  }
515
577
  //#endregion
516
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
578
+ //#region node_modules/@oscarpalmer/mora/node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
517
579
  /**
518
580
  * Is the value a key?
519
581
  * @param value Value to check
@@ -527,39 +589,13 @@ function isKey(value) {
527
589
  * @param value Value to check
528
590
  * @returns `true` if the value is a plain object, otherwise `false`
529
591
  */
530
- function isPlainObject(value) {
592
+ function isPlainObject$2(value) {
531
593
  if (value === null || typeof value !== "object") return false;
532
594
  if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
533
595
  const prototype = Object.getPrototypeOf(value);
534
596
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
535
597
  }
536
598
  //#endregion
537
- //#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
538
- /**
539
- * Get the string value from any value
540
- * @param value Original value
541
- * @returns String representation of the value
542
- */
543
- function getString(value) {
544
- if (typeof value === "string") return value;
545
- if (value == null) return "";
546
- if (typeof value === "function") return getString(value());
547
- if (typeof value !== "object") return String(value);
548
- const asString = String(value.valueOf?.() ?? value);
549
- return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
550
- }
551
- //#endregion
552
- //#region node_modules/@oscarpalmer/atoms/dist/is.mjs
553
- /**
554
- * Is the value `undefined`, `null`, or a whitespace-only string?
555
- * @param value Value to check
556
- * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
557
- */
558
- function isNullableOrWhitespace(value) {
559
- return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
560
- }
561
- const EXPRESSION_WHITESPACE$1 = /^\s*$/;
562
- //#endregion
563
599
  //#region node_modules/@oscarpalmer/mora/dist/value/store.mjs
564
600
  var Store = class extends Reactive {
565
601
  #keyed = /* @__PURE__ */ new Map();
@@ -588,8 +624,7 @@ var Store = class extends Reactive {
588
624
  return isKey(key) ? this.state.value[key] : { ...this.state.value };
589
625
  }
590
626
  set(first, second) {
591
- if (isKey(first)) this.state.value[first] = second;
592
- else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
627
+ setProxyValue(false, this.state, isStoreObject, isKey, setObject, setProperty, first, second);
593
628
  }
594
629
  subscribe(first, second) {
595
630
  if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
@@ -600,19 +635,78 @@ var Store = class extends Reactive {
600
635
  * @param callback Callback to update the value
601
636
  */
602
637
  update(callback) {
603
- const updated = callback({ ...this.state.value });
604
- if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
638
+ const updated = callback(this.state.value);
639
+ if (updated == null || isPlainObject$2(updated)) setObject(this.state, updated);
605
640
  }
606
641
  };
642
+ function isStoreObject(value) {
643
+ return value == null || isPlainObject$2(value);
644
+ }
645
+ function setObject(state, value) {
646
+ startBatch();
647
+ const actual = value ?? {};
648
+ const proxy = state.value;
649
+ const proxyKeys = Object.keys(proxy);
650
+ const actualKeys = Object.keys(actual);
651
+ let { length } = proxyKeys;
652
+ for (let index = 0; index < length; index += 1) {
653
+ const key = proxyKeys[index];
654
+ proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
655
+ }
656
+ length = actualKeys.length;
657
+ for (let index = 0; index < length; index += 1) {
658
+ const key = actualKeys[index];
659
+ if (!proxyKeys.includes(key)) proxy[key] = actual[key];
660
+ }
661
+ stopBatch();
662
+ }
663
+ function setProperty(state, key, value) {
664
+ state.value[key] = value;
665
+ }
666
+ function store(value, options) {
667
+ const instance = new Store({}, options);
668
+ instance.set(value);
669
+ return instance;
670
+ }
671
+ //#endregion
672
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
607
673
  /**
608
- * Create a reactive store
609
- * @param value Initial object value
610
- * @param options Reactivity options
611
- * @returns Reactive store
674
+ * Is the value a plain object?
675
+ * @param value Value to check
676
+ * @returns `true` if the value is a plain object, otherwise `false`
612
677
  */
613
- function store(value, options) {
614
- return new Store(isPlainObject(value) ? value : {}, options);
678
+ function isPlainObject$1(value) {
679
+ if (value === null || typeof value !== "object") return false;
680
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
681
+ const prototype = Object.getPrototypeOf(value);
682
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
683
+ }
684
+ //#endregion
685
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
686
+ /**
687
+ * Get the string value from any value
688
+ * @param value Original value
689
+ * @returns String representation of the value
690
+ */
691
+ function getString$1(value) {
692
+ if (typeof value === "string") return value;
693
+ if (value == null) return "";
694
+ if (typeof value === "function") return getString$1(value());
695
+ if (typeof value !== "object") return String(value);
696
+ const asString = String(value.valueOf?.() ?? value);
697
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
698
+ }
699
+ //#endregion
700
+ //#region node_modules/@oscarpalmer/atoms/dist/is.mjs
701
+ /**
702
+ * Is the value `undefined`, `null`, or stringified as a whitespace-only string?
703
+ * @param value Value to check
704
+ * @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
705
+ */
706
+ function isNullableOrWhitespace$1(value) {
707
+ return value == null || EXPRESSION_WHITESPACE$2.test(getString$1(value));
615
708
  }
709
+ const EXPRESSION_WHITESPACE$2 = /^\s*$/;
616
710
  //#endregion
617
711
  //#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
618
712
  /**
@@ -649,6 +743,341 @@ const CHILD_NODE_TYPES = new Set([
649
743
  Node.DOCUMENT_TYPE_NODE
650
744
  ]);
651
745
  //#endregion
746
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
747
+ /**
748
+ * Is the value a number?
749
+ * @param value Value to check
750
+ * @returns `true` if the value is a `number`, otherwise `false`
751
+ */
752
+ function isNumber(value) {
753
+ return typeof value === "number" && !Number.isNaN(value);
754
+ }
755
+ /**
756
+ * Is the value a plain object?
757
+ * @param value Value to check
758
+ * @returns `true` if the value is a plain object, otherwise `false`
759
+ */
760
+ function isPlainObject(value) {
761
+ if (value === null || typeof value !== "object") return false;
762
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
763
+ const prototype = Object.getPrototypeOf(value);
764
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
765
+ }
766
+ //#endregion
767
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/array/compact.mjs
768
+ function compact(array, strict) {
769
+ if (!Array.isArray(array)) return [];
770
+ if (strict === true) return array.filter(Boolean);
771
+ const { length } = array;
772
+ const compacted = [];
773
+ for (let index = 0; index < length; index += 1) {
774
+ const item = array[index];
775
+ if (item != null) compacted.push(item);
776
+ }
777
+ return compacted;
778
+ }
779
+ //#endregion
780
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
781
+ /**
782
+ * Get the string value from any value
783
+ * @param value Original value
784
+ * @returns String representation of the value
785
+ */
786
+ function getString(value) {
787
+ if (typeof value === "string") return value;
788
+ if (value == null) return "";
789
+ if (typeof value === "function") return getString(value());
790
+ if (typeof value !== "object") return String(value);
791
+ const asString = String(value.valueOf?.() ?? value);
792
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
793
+ }
794
+ /**
795
+ * Join an array of values into a string
796
+ * @param value Array of values
797
+ * @param delimiter Delimiter to use between values
798
+ * @returns Joined string
799
+ */
800
+ function join(value, delimiter) {
801
+ return compact(value).map(getString).join(typeof delimiter === "string" ? delimiter : "");
802
+ }
803
+ /**
804
+ * Split a string into words _(and other readable parts)_
805
+ * @param value Original string
806
+ * @returns Array of words found in the string
807
+ */
808
+ function words(value) {
809
+ return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
810
+ }
811
+ const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
812
+ //#endregion
813
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/is.mjs
814
+ /**
815
+ * Is the value `undefined`, `null`, or a whitespace-only string?
816
+ * @param value Value to check
817
+ * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
818
+ */
819
+ function isNullableOrWhitespace(value) {
820
+ return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
821
+ }
822
+ const EXPRESSION_WHITESPACE$1 = /^\s*$/;
823
+ //#endregion
824
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
825
+ /**
826
+ * Clamp a number between a minimum and maximum value
827
+ * @param value Value to clamp
828
+ * @param minimum Minimum value
829
+ * @param maximum Maximum value
830
+ * @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
831
+ * @returns Clamped value
832
+ */
833
+ function clamp(value, minimum, maximum, loop) {
834
+ if (![
835
+ value,
836
+ minimum,
837
+ maximum
838
+ ].every(isNumber)) return NaN;
839
+ if (value < minimum) return loop === true ? maximum : minimum;
840
+ return value > maximum ? loop === true ? minimum : maximum : value;
841
+ }
842
+ //#endregion
843
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/sized.mjs
844
+ function getSizedMaximum(first, second) {
845
+ let actual;
846
+ if (typeof first === "number") actual = first;
847
+ else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
848
+ return clamp(actual, 1, MAXIMUM_ABSOLUTE);
849
+ }
850
+ const MAXIMUM_ABSOLUTE = 16777216;
851
+ const MAXIMUM_DEFAULT = 1048576;
852
+ //#endregion
853
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/sized/map.mjs
854
+ /**
855
+ * A Map with a maximum size
856
+ *
857
+ * Behavior is similar to a _LRU_-cache, where the least recently used entries are removed
858
+ */
859
+ var SizedMap = class extends Map {
860
+ /**
861
+ * The maximum size of the Map
862
+ */
863
+ #maximumSize;
864
+ /**
865
+ * Is the Map full?
866
+ */
867
+ get full() {
868
+ return super.size >= this.#maximumSize;
869
+ }
870
+ get maximum() {
871
+ return this.#maximumSize;
872
+ }
873
+ constructor(first, second) {
874
+ const maximum = getSizedMaximum(first, second);
875
+ super();
876
+ this.#maximumSize = maximum;
877
+ if (Array.isArray(first)) {
878
+ const { length } = first;
879
+ if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
880
+ else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
881
+ }
882
+ }
883
+ /**
884
+ * @inheritdoc
885
+ */
886
+ get(key) {
887
+ if (super.has(key)) {
888
+ const value = super.get(key);
889
+ this.#setValue(key, value, true);
890
+ return value;
891
+ }
892
+ }
893
+ /**
894
+ * @inheritdoc
895
+ */
896
+ set(key, value) {
897
+ return this.#setValue(key, value, super.has(key));
898
+ }
899
+ #setValue(key, value, has) {
900
+ if (has) super.delete(key);
901
+ else if (super.size >= this.#maximumSize) super.delete(super.keys().next().value);
902
+ super.set(key, value);
903
+ return this;
904
+ }
905
+ };
906
+ //#endregion
907
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
908
+ var Memoized = class {
909
+ #state;
910
+ /**
911
+ * Maximum cache size
912
+ */
913
+ get maximum() {
914
+ return this.#state.cache?.maximum ?? NaN;
915
+ }
916
+ /**
917
+ * Current cache size
918
+ */
919
+ get size() {
920
+ return this.#state.cache?.size ?? NaN;
921
+ }
922
+ constructor(callback, options) {
923
+ const cache = new SizedMap(options.cacheSize);
924
+ const getter = (...parameters) => {
925
+ const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), SEPARATOR));
926
+ if (cache.has(key)) return cache.get(key);
927
+ const value = callback(...parameters);
928
+ cache.set(key, value);
929
+ return value;
930
+ };
931
+ this.#state = {
932
+ cache,
933
+ getter
934
+ };
935
+ }
936
+ /**
937
+ * Clear the cache
938
+ */
939
+ clear() {
940
+ this.#state.cache?.clear();
941
+ }
942
+ /**
943
+ * Delete a result from the cache
944
+ * @param key Key to delete
945
+ * @returns `true` if the key existed and was removed, otherwise `false`
946
+ */
947
+ delete(key) {
948
+ return this.#state.cache?.delete(key) ?? false;
949
+ }
950
+ /**
951
+ * Destroy the instance _(clearing its cache and removing its callback)_
952
+ */
953
+ destroy() {
954
+ this.#state.cache?.clear();
955
+ this.#state.cache = void 0;
956
+ this.#state.getter = void 0;
957
+ }
958
+ /**
959
+ * Get a result from the cache
960
+ * @param key Key to get
961
+ * @returns Cached result or `undefined` if it does not exist
962
+ */
963
+ get(key) {
964
+ return this.#state.cache?.get(key);
965
+ }
966
+ /**
967
+ * Does the result exist?
968
+ * @param key Key to check
969
+ * @returns `true` if the result exists, otherwise `false`
970
+ */
971
+ has(key) {
972
+ return this.#state.cache?.has(key) ?? false;
973
+ }
974
+ /**
975
+ * Run the callback with the provided parameters
976
+ * @param parameters Parameters to pass to the callback
977
+ * @returns Cached or computed _(then cached)_ result
978
+ */
979
+ run(...parameters) {
980
+ if (this.#state.cache == null || this.#state.getter == null) throw new Error("The Memoized instance has been destroyed");
981
+ return this.#state.getter(...parameters);
982
+ }
983
+ };
984
+ function getMemoizationOptions(input) {
985
+ const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
986
+ return {
987
+ cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
988
+ cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE
989
+ };
990
+ }
991
+ /**
992
+ * Memoize a function, caching and retrieving results based on the first parameter
993
+ * @param callback Callback to memoize
994
+ * @param options Memoization options
995
+ * @returns Memoized instance
996
+ */
997
+ function memoize(callback, options) {
998
+ return new Memoized(callback, getMemoizationOptions(options));
999
+ }
1000
+ const DEFAULT_CACHE_SIZE = 1024;
1001
+ const SEPARATOR = "_";
1002
+ //#endregion
1003
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/string/case.mjs
1004
+ /**
1005
+ * Convert a string to camel case _(thisIsCamelCase)_
1006
+ * @param value String to convert
1007
+ * @returns Camel-cased string
1008
+ */
1009
+ function camelCase(value) {
1010
+ return toCase(CASE_CAMEL, value, true, false);
1011
+ }
1012
+ /**
1013
+ * Capitalize the first letter of a string _(and lowercase the rest)_
1014
+ * @param value String to capitalize
1015
+ * @returns Capitalized string
1016
+ */
1017
+ function capitalize(value) {
1018
+ if (typeof value !== "string" || value.length === 0) return "";
1019
+ memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
1020
+ return memoizedCapitalize.run(value);
1021
+ }
1022
+ /**
1023
+ * Convert a string to kebab case _(this-is-kebab-case)_
1024
+ * @param value String to convert
1025
+ * @returns Kebab-cased string
1026
+ */
1027
+ function kebabCase(value) {
1028
+ return toCase(CASE_KEBAB, value, false, false);
1029
+ }
1030
+ function toCase(type, value, capitalizeAny, capitalizeFirst) {
1031
+ caseMemoizers[type] ??= memoize(toCaseCallback.bind({
1032
+ type,
1033
+ capitalizeAny,
1034
+ capitalizeFirst
1035
+ }));
1036
+ return caseMemoizers[type].run(value);
1037
+ }
1038
+ function toCaseCallback(value) {
1039
+ if (typeof value !== "string") return "";
1040
+ if (value.length < 1) return value;
1041
+ const { capitalizeAny, capitalizeFirst, type } = this;
1042
+ const parts = words(value);
1043
+ const partsLength = parts.length;
1044
+ const cased = [];
1045
+ for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
1046
+ const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === S ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
1047
+ const itemsLength = items.length;
1048
+ const partResult = [];
1049
+ let itemCount = 0;
1050
+ for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
1051
+ const item = items[itemIndex];
1052
+ if (item.length === 0) continue;
1053
+ if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
1054
+ else partResult.push(capitalize(item));
1055
+ itemCount += 1;
1056
+ }
1057
+ cased.push(join(partResult, delimiters[type]));
1058
+ }
1059
+ return join(cased, delimiters[type]);
1060
+ }
1061
+ const CASE_CAMEL = "camel";
1062
+ const CASE_KEBAB = "kebab";
1063
+ const CASE_PASCAL = "pascal";
1064
+ const CASE_SNAKE = "snake";
1065
+ const DELIMTER_EMPTY = "";
1066
+ const DELIMITER_HYPHEN = "-";
1067
+ const DELIMITER_UNDERSCORE = "_";
1068
+ const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
1069
+ const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
1070
+ const REPLACEMENT_CAMEL_CASE = "$1-$2";
1071
+ const S = "s";
1072
+ const caseMemoizers = {};
1073
+ const delimiters = {
1074
+ [CASE_CAMEL]: DELIMTER_EMPTY,
1075
+ [CASE_KEBAB]: DELIMITER_HYPHEN,
1076
+ [CASE_PASCAL]: DELIMTER_EMPTY,
1077
+ [CASE_SNAKE]: DELIMITER_UNDERSCORE
1078
+ };
1079
+ let memoizedCapitalize;
1080
+ //#endregion
652
1081
  //#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
653
1082
  function setElementValue(element, first, second, third, callback) {
654
1083
  if (!isHTMLOrSVGElement(element)) return;
@@ -657,8 +1086,9 @@ function setElementValue(element, first, second, third, callback) {
657
1086
  }
658
1087
  function setElementValues(element, first, second, third, callback) {
659
1088
  if (!isHTMLOrSVGElement(element)) return;
1089
+ const dispatch = third !== false;
660
1090
  if (typeof first === "string") {
661
- callback(element, first, second, third);
1091
+ callback(element, kebabCase(first), second, dispatch);
662
1092
  return;
663
1093
  }
664
1094
  const isArray = Array.isArray(first);
@@ -670,7 +1100,7 @@ function setElementValues(element, first, second, third, callback) {
670
1100
  const { length } = entries;
671
1101
  for (let index = 0; index < length; index += 1) {
672
1102
  const entry = entries[index];
673
- if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
1103
+ if (typeof entry === "object" && typeof entry?.name === "string") callback(element, kebabCase(entry.name), entry.value, dispatch);
674
1104
  }
675
1105
  }
676
1106
  function updateElementValue(element, key, value, set, remove, isBoolean, json) {
@@ -678,6 +1108,25 @@ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
678
1108
  else set.call(element, key, json ? JSON.stringify(value) : String(value));
679
1109
  }
680
1110
  //#endregion
1111
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/property.mjs
1112
+ function updateProperty$1(element, name, value, dispatch) {
1113
+ let property = name;
1114
+ if (!(property in element)) property = camelCase(name);
1115
+ if (!(property in element) || Object.is(element[property], value)) return;
1116
+ element[property] = value;
1117
+ const event = dispatch && elementEvents[element.tagName]?.[property];
1118
+ if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
1119
+ }
1120
+ const elementEvents = {
1121
+ DETAILS: { open: "toggle" },
1122
+ INPUT: {
1123
+ checked: "change",
1124
+ value: "input"
1125
+ },
1126
+ SELECT: { value: "change" },
1127
+ TEXTAREA: { value: "input" }
1128
+ };
1129
+ //#endregion
681
1130
  //#region node_modules/@oscarpalmer/toretto/dist/internal/attribute.mjs
682
1131
  function badAttributeHandler(name, value) {
683
1132
  if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
@@ -707,6 +1156,7 @@ function handleAttribute(callback, decode, first, second) {
707
1156
  name = first;
708
1157
  value = second;
709
1158
  }
1159
+ if (name != null) name = kebabCase(name);
710
1160
  if (decode && value != null) value = decodeAttribute(value);
711
1161
  return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
712
1162
  }
@@ -719,9 +1169,6 @@ function _isBadAttribute(first, second, decode) {
719
1169
  function _isBooleanAttribute(first, decode) {
720
1170
  return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
721
1171
  }
722
- function _isEmptyNonBooleanAttribute(first, second, decode) {
723
- return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
724
- }
725
1172
  function _isInvalidBooleanAttribute(first, second, decode) {
726
1173
  return handleAttribute(booleanAttributeHandler, decode, first, second);
727
1174
  }
@@ -729,18 +1176,12 @@ function isValidSourceAttribute(name, value) {
729
1176
  return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
730
1177
  }
731
1178
  function updateAttribute(element, name, value, dispatch) {
732
- const normalizedName = name.toLowerCase();
733
- const isBoolean = booleanAttributesSet.has(normalizedName);
734
- const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
735
- if (name in element) updateProperty$1(element, normalizedName, next, dispatch);
1179
+ const lowerCaseName = name.toLowerCase();
1180
+ const isBoolean = booleanAttributesSet.has(lowerCaseName);
1181
+ const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
1182
+ if (isBoolean || dispatchedAttributes.has(name)) updateProperty$1(element, name, next, dispatch);
736
1183
  updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
737
1184
  }
738
- function updateProperty$1(element, name, value, dispatch) {
739
- if (Object.is(element[name], value)) return;
740
- element[name] = value;
741
- const event = dispatch !== false && elementEvents[element.tagName]?.[name];
742
- if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
743
- }
744
1185
  const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
745
1186
  const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
746
1187
  const EXPRESSION_EVENT_NAME$1 = /^on/i;
@@ -779,19 +1220,15 @@ const booleanAttributes = Object.freeze([
779
1220
  "selected"
780
1221
  ]);
781
1222
  const booleanAttributesSet = new Set(booleanAttributes);
782
- const elementEvents = {
783
- DETAILS: { open: "toggle" },
784
- INPUT: {
785
- checked: "change",
786
- value: "input"
787
- },
788
- SELECT: { value: "change" },
789
- TEXTAREA: { value: "input" }
790
- };
1223
+ const dispatchedAttributes = new Set([
1224
+ "checked",
1225
+ "open",
1226
+ "value"
1227
+ ]);
791
1228
  const formElement = document.createElement("form");
792
1229
  let textArea;
793
1230
  //#endregion
794
- //#region node_modules/@oscarpalmer/toretto/dist/attribute/set.mjs
1231
+ //#region node_modules/@oscarpalmer/toretto/dist/attribute/set.attribute.mjs
795
1232
  function setAttribute$1(element, first, second, third) {
796
1233
  setElementValue(element, first, second, third, updateAttribute);
797
1234
  }
@@ -799,8 +1236,9 @@ function setAttribute$1(element, first, second, third) {
799
1236
  //#region node_modules/@oscarpalmer/toretto/dist/html/sanitize.mjs
800
1237
  function handleElement(element, depth) {
801
1238
  if (depth === 0) {
802
- const removable = element.querySelectorAll(REMOVE_SELECTOR);
803
- for (const item of removable) item.remove();
1239
+ const removable = [...element.querySelectorAll(REMOVE_SELECTOR)];
1240
+ const { length } = removable;
1241
+ for (let index = 0; index < length; index += 1) removable[index].remove();
804
1242
  }
805
1243
  sanitizeAttributes(element, [...element.attributes]);
806
1244
  }
@@ -819,7 +1257,7 @@ function sanitizeAttributes(element, attributes) {
819
1257
  const { length } = attributes;
820
1258
  for (let index = 0; index < length; index += 1) {
821
1259
  const { name, value } = attributes[index];
822
- if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
1260
+ if (_isBadAttribute(name, value, false)) element.removeAttribute(name);
823
1261
  else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute$1(element, name, true);
824
1262
  }
825
1263
  }
@@ -865,16 +1303,22 @@ function createHtml(value) {
865
1303
  function createTemplate(value, options) {
866
1304
  const template = document.createElement(TEMPLATE_TAG);
867
1305
  template.innerHTML = createHtml(value);
868
- if (typeof value === "string" && options.cache) templates[value] = template;
1306
+ if (typeof value === "string" && options.cache) templates.set(value, template);
869
1307
  return template;
870
1308
  }
1309
+ function getComment(index) {
1310
+ return COMMENT_TEMPLATE.replace(COMMENT_INDEX, String(index));
1311
+ }
871
1312
  function getHtml(value) {
872
1313
  return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
873
1314
  }
874
- function getNodes(value, options) {
1315
+ function getNodes(value, options, nodes) {
875
1316
  if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
876
1317
  const template = getTemplate(value, options);
877
- return template == null ? [] : [...template.content.cloneNode(true).childNodes];
1318
+ if (template == null) return [];
1319
+ const cloned = [...template.content.cloneNode(true).childNodes];
1320
+ if (nodes != null) replaceComments(cloned, nodes);
1321
+ return cloned;
878
1322
  }
879
1323
  function getOptions$1(input) {
880
1324
  const options = isPlainObject(input) ? input : {};
@@ -885,37 +1329,96 @@ function getParser() {
885
1329
  parser ??= new DOMParser();
886
1330
  return parser;
887
1331
  }
1332
+ function getTagged(strings, values) {
1333
+ const tagged = {
1334
+ nodes: [],
1335
+ template: ""
1336
+ };
1337
+ const stringsLength = strings.length;
1338
+ let nodeIndex = 0;
1339
+ for (let stringIndex = 0; stringIndex < stringsLength; stringIndex += 1) {
1340
+ const value = values[stringIndex];
1341
+ tagged.template += strings[stringIndex];
1342
+ if (value instanceof Node) {
1343
+ tagged.nodes.push(value);
1344
+ tagged.template += getComment(nodeIndex);
1345
+ nodeIndex += 1;
1346
+ } else if (hasNodes(value)) {
1347
+ const items = [...value];
1348
+ const itemsLength = items.length;
1349
+ for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
1350
+ const item = items[itemIndex];
1351
+ if (item instanceof Node) {
1352
+ tagged.nodes.push(item);
1353
+ tagged.template += getComment(nodeIndex);
1354
+ nodeIndex += 1;
1355
+ } else tagged.template += getString(item);
1356
+ }
1357
+ } else if (Array.isArray(value)) {
1358
+ const valueLength = value.length;
1359
+ for (let valueIndex = 0; valueIndex < valueLength; valueIndex += 1) tagged.template += getString(value[valueIndex]);
1360
+ } else tagged.template += getString(value);
1361
+ }
1362
+ return tagged;
1363
+ }
888
1364
  function getTemplate(value, options) {
889
1365
  if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
890
1366
  if (value.trim().length === 0) return;
891
- let template = templates[value];
1367
+ let template = templates.get(value);
892
1368
  if (template != null) return template;
893
1369
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
894
1370
  return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
895
1371
  }
896
- const html$1 = ((value, options) => {
897
- return getNodes(value, getOptions$1(options));
898
- });
1372
+ function hasNodes(value) {
1373
+ if (value instanceof HTMLCollection || value instanceof NodeList) return true;
1374
+ return Array.isArray(value) && value.some((item) => item instanceof Node);
1375
+ }
1376
+ function html$1(first, ...second) {
1377
+ if (isTagged(first)) {
1378
+ const tagged = getTagged(first, second);
1379
+ return getNodes(tagged.template, getOptions$1(), tagged.nodes);
1380
+ }
1381
+ return getNodes(first, getOptions$1(second[0]));
1382
+ }
1383
+ /**
1384
+ * Clear cache of template elements
1385
+ */
899
1386
  html$1.clear = () => {
900
- templates = {};
1387
+ templates.clear();
901
1388
  };
1389
+ /**
1390
+ * Remove cached template element for an HTML string or id
1391
+ * @param template HTML string or id for a template element
1392
+ */
902
1393
  html$1.remove = (template) => {
903
- if (typeof template !== "string" || templates[template] == null) return;
904
- const keys = Object.keys(templates);
905
- const { length } = keys;
906
- const updated = {};
907
- for (let index = 0; index < length; index += 1) {
908
- const key = keys[index];
909
- if (key !== template) updated[key] = templates[key];
910
- }
911
- templates = updated;
1394
+ templates.delete(template);
912
1395
  };
1396
+ function isTagged(value) {
1397
+ return Array.isArray(value) && Array.isArray(value.raw);
1398
+ }
1399
+ function replaceComments(origin, replacements) {
1400
+ const nodes = [...origin];
1401
+ const { length } = nodes;
1402
+ for (let nodeIndex = 0; nodeIndex < length; nodeIndex += 1) {
1403
+ const node = nodes[nodeIndex];
1404
+ if (node instanceof Comment) {
1405
+ const [, index] = EXPRESSION_COMMENT.exec(node.textContent) ?? [];
1406
+ if (index != null) node.replaceWith(replacements[Number(index)]);
1407
+ continue;
1408
+ }
1409
+ if (node.hasChildNodes()) replaceComments(node.childNodes, replacements);
1410
+ }
1411
+ }
1412
+ const COMMENT_INDEX = "<index>";
1413
+ const COMMENT_TEMPLATE = `<!--toretto.node:${COMMENT_INDEX}-->`;
1414
+ const EXPRESSION_COMMENT = /^toretto\.node:(\d+)$/;
913
1415
  const EXPRESSION_ID = /^[a-z][\w-]*$/i;
914
1416
  const PARSE_TYPE_HTML = "text/html";
915
1417
  const TEMPLATE_TAG = "template";
916
1418
  const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
1419
+ const templates = new SizedMap(128);
917
1420
  let parser;
918
- let templates = {};
1421
+ window.templates = templates;
919
1422
  //#endregion
920
1423
  //#region src/constants.ts
921
1424
  const ARRAY_COMPARISON_ADDED = "added";
@@ -1022,7 +1525,7 @@ function handleItems(state, items) {
1022
1525
  const item = items[index];
1023
1526
  const identifier = state.identify(item);
1024
1527
  if (identifier == null) throw new TypeError(ERROR_IDENTIFIER_TYPE);
1025
- const key = getString(identifier);
1528
+ const key = getString$1(identifier);
1026
1529
  if (keys.has(key)) throw new Error(ERROR_IDENTIFIER_DUPLICATE.replace("<>", key));
1027
1530
  let instance = state.instances[key];
1028
1531
  if (instance == null) {
@@ -1066,7 +1569,7 @@ const states = /* @__PURE__ */ new WeakMap();
1066
1569
  function createNodes(value) {
1067
1570
  if (isFragment(value)) return value.get();
1068
1571
  if (isChildNode(value)) return [value];
1069
- return [new Text(getString(value))];
1572
+ return [new Text(getString$1(value))];
1070
1573
  }
1071
1574
  function isInputElement(node) {
1072
1575
  return node instanceof HTMLInputElement || node instanceof HTMLSelectElement;
@@ -1104,7 +1607,14 @@ function delegatedEventHandler(event) {
1104
1607
  const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
1105
1608
  const items = event.composedPath();
1106
1609
  const { length } = items;
1610
+ let cancelled = false;
1107
1611
  let target = items[0];
1612
+ const originalStopPropagation = event.stopPropagation;
1613
+ event.stopPropagation = function() {
1614
+ cancelled = true;
1615
+ originalStopPropagation.call(event);
1616
+ };
1617
+ event.stopImmediatePropagation = event.stopPropagation.bind(event);
1108
1618
  Object.defineProperties(event, {
1109
1619
  currentTarget: {
1110
1620
  configurable: true,
@@ -1124,7 +1634,7 @@ function delegatedEventHandler(event) {
1124
1634
  target = item;
1125
1635
  for (const listener of listeners) {
1126
1636
  listener.call(item, event);
1127
- if (event.cancelBubble) return;
1637
+ if (cancelled) return;
1128
1638
  }
1129
1639
  }
1130
1640
  }
@@ -1169,7 +1679,7 @@ const EVENT_TYPES = new Set([
1169
1679
  const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
1170
1680
  const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
1171
1681
  //#endregion
1172
- //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
1682
+ //#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
1173
1683
  /**
1174
1684
  * A function that does nothing, which can be useful, I guess…
1175
1685
  */
@@ -1422,8 +1932,8 @@ function setReactiveValueForSingle(item, comment, value) {
1422
1932
  else item.nodes = setText(item, comment, value);
1423
1933
  }
1424
1934
  function setText(item, comment, value) {
1425
- const isNullable = isNullableOrWhitespace(value);
1426
- if (item.text != null) item.text.textContent = isNullable ? "" : getString(value);
1935
+ const isNullable = isNullableOrWhitespace$1(value);
1936
+ if (item.text != null) item.text.textContent = isNullable ? "" : getString$1(value);
1427
1937
  let result = false;
1428
1938
  if (item.nodes != null) {
1429
1939
  replaceText(item, comment, isNullable);
@@ -1517,7 +2027,7 @@ function handleExpression(data, prefix, expression) {
1517
2027
  return `${prefix}${expressions}`;
1518
2028
  }
1519
2029
  if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
1520
- return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
2030
+ return isNullableOrWhitespace$1(expression) ? prefix : `${prefix}${expression}`;
1521
2031
  }
1522
2032
  function parse(data) {
1523
2033
  if (data.template != null) return data.template;
@@ -1575,7 +2085,7 @@ var Fragment = class {
1575
2085
  * @returns Fragment
1576
2086
  */
1577
2087
  configure(configuration) {
1578
- const actual = isPlainObject(configuration) ? configuration : {};
2088
+ const actual = isPlainObject$1(configuration) ? configuration : {};
1579
2089
  if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
1580
2090
  if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
1581
2091
  return this;
@@ -1,2 +1,42 @@
1
- import { t as Fragment } from "./fragment-9qTBAvtR.mjs";
1
+ import { FragmentConfiguration } from "./models.mjs";
2
+
3
+ //#region src/fragment.d.ts
4
+ declare class Fragment {
5
+ #private;
6
+ /**
7
+ * Fragment identifier
8
+ */
9
+ get identifier(): unknown;
10
+ constructor(strings: TemplateStringsArray, expressions: unknown[]);
11
+ /**
12
+ * Append the fragment to the given element
13
+ * @param element Element to append to
14
+ */
15
+ appendTo(element: Element): void;
16
+ /**
17
+ * Configure the fragment
18
+ * @param configuration Configuration options
19
+ * @returns Fragment
20
+ */
21
+ configure(configuration: FragmentConfiguration): Fragment;
22
+ /**
23
+ * Get a list of the fragment's nodes
24
+ * @returns List of nodes
25
+ */
26
+ get(): ChildNode[];
27
+ /**
28
+ * Set an identifier for the fragment
29
+ *
30
+ * _An identifier can be used to uniquely identify a fragment,
31
+ * which helps prevent re-rendering in certain scenarios._
32
+ * @param identifier Identifier
33
+ * @returns Fragment
34
+ */
35
+ identify(identifier: unknown): Fragment;
36
+ /**
37
+ * Remove the fragment from the DOM
38
+ */
39
+ remove(): void;
40
+ }
41
+ //#endregion
2
42
  export { Fragment };
@@ -1,4 +1,5 @@
1
- import { a as FragmentsState, t as Fragment } from "./fragment-9qTBAvtR.mjs";
1
+ import { FragmentsState } from "./models.mjs";
2
+ import { Fragment } from "./fragment.mjs";
2
3
  import { ReactiveArray } from "@oscarpalmer/mora";
3
4
 
4
5
  //#region src/fragments.d.ts
@@ -1,5 +1,5 @@
1
1
  import { ARRAY_COMPARISON_ADDED, ARRAY_COMPARISON_DISSIMILAR, ARRAY_COMPARISON_REMOVED } from "../constants.mjs";
2
- import { t as Fragment } from "../fragment-9qTBAvtR.mjs";
2
+ import { Fragment } from "../fragment.mjs";
3
3
  import { Fragments } from "../fragments.mjs";
4
4
 
5
5
  //#region src/helpers/index.d.ts
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Fragment } from "./fragment-9qTBAvtR.mjs";
1
+ import { Fragment } from "./fragment.mjs";
2
2
  import { Fragments } from "./fragments.mjs";
3
3
  import { ReactiveArray } from "@oscarpalmer/mora";
4
4
  export * from "@oscarpalmer/mora";
package/dist/models.d.mts CHANGED
@@ -1,2 +1,44 @@
1
- import { a as FragmentsState, i as FragmentItem, n as FragmentConfiguration, r as FragmentData } from "./fragment-9qTBAvtR.mjs";
1
+ import { Fragment } from "./fragment.mjs";
2
+ import { Reactive, ReactiveArray, Unsubscribe } from "@oscarpalmer/mora";
3
+
4
+ //#region src/models.d.ts
5
+ type FragmentConfiguration = {
6
+ /**
7
+ * Should the template be cached? _(defaults to `true`)_
8
+ */
9
+ cache?: boolean;
10
+ /**
11
+ * Identifier for the fragment
12
+ *
13
+ * _(An identifier can be used to uniquely identify a fragment,
14
+ * which helps prevent re-rendering in certain scenarios)_
15
+ */
16
+ identifier?: unknown;
17
+ };
18
+ type FragmentData = {
19
+ expressions: unknown[];
20
+ items: FragmentItem[];
21
+ mora: MoraData;
22
+ strings: TemplateStringsArray;
23
+ template?: string;
24
+ values: unknown[];
25
+ };
26
+ type FragmentItem = {
27
+ fragments?: Fragment[];
28
+ nodes?: ChildNode[];
29
+ text?: Text;
30
+ };
31
+ type FragmentsState = {
32
+ array: ReactiveArray<unknown>;
33
+ fragment: (item: unknown) => Fragment;
34
+ identify: (item: unknown) => unknown;
35
+ instances: Record<string, Fragment>;
36
+ mapped: ReactiveArray<Fragment>;
37
+ subscriber: Unsubscribe | undefined;
38
+ };
39
+ type MoraData = {
40
+ subscribers: Set<() => void>;
41
+ values: Set<Reactive<unknown>>;
42
+ };
43
+ //#endregion
2
44
  export { FragmentConfiguration, FragmentData, FragmentItem, FragmentsState };
@@ -1,4 +1,4 @@
1
- import { r as FragmentData } from "../../fragment-9qTBAvtR.mjs";
1
+ import { FragmentData } from "../../models.mjs";
2
2
 
3
3
  //#region src/node/attribute/index.d.ts
4
4
  declare function mapAttributes(data: FragmentData, element: HTMLElement | SVGElement): void;
@@ -1,4 +1,4 @@
1
- import { r as FragmentData } from "../../fragment-9qTBAvtR.mjs";
1
+ import { FragmentData } from "../../models.mjs";
2
2
 
3
3
  //#region src/node/attribute/value.d.ts
4
4
  declare function setAttribute(data: FragmentData, element: HTMLElement | SVGElement, name: string, value: unknown): void;
@@ -1,4 +1,4 @@
1
- import { r as FragmentData } from "../fragment-9qTBAvtR.mjs";
1
+ import { FragmentData } from "../models.mjs";
2
2
 
3
3
  //#region src/node/index.d.ts
4
4
  declare function mapNodes(data: FragmentData, nodes: ChildNode[]): void;
@@ -1,4 +1,4 @@
1
- import { r as FragmentData } from "../fragment-9qTBAvtR.mjs";
1
+ import { FragmentData } from "../models.mjs";
2
2
  import { Reactive } from "@oscarpalmer/mora";
3
3
 
4
4
  //#region src/node/value.d.ts
package/dist/parse.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as FragmentData } from "./fragment-9qTBAvtR.mjs";
1
+ import { FragmentData } from "./models.mjs";
2
2
 
3
3
  //#region src/parse.d.ts
4
4
  declare function parse(data: FragmentData): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/abydon",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "keywords": [
5
5
  "components",
6
6
  "dom",
@@ -42,15 +42,15 @@
42
42
  "test:leak": "npx vp test run --detect-async-leaks --coverage"
43
43
  },
44
44
  "dependencies": {
45
- "@oscarpalmer/atoms": "^0.165",
46
- "@oscarpalmer/mora": "^0.27",
47
- "@oscarpalmer/toretto": "^0.41"
45
+ "@oscarpalmer/atoms": "^0.183",
46
+ "@oscarpalmer/mora": "^0.28",
47
+ "@oscarpalmer/toretto": "^0.42"
48
48
  },
49
49
  "devDependencies": {
50
- "@oscarpalmer/oui": "^0.19",
51
- "@types/node": "^25.5",
50
+ "@oscarpalmer/oui": "^0.20",
51
+ "@types/node": "^25.6",
52
52
  "@vitest/coverage-istanbul": "^4.1",
53
- "jsdom": "^28.1",
53
+ "jsdom": "^29",
54
54
  "tsdown": "^0.21",
55
55
  "typescript": "^5.9",
56
56
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
@@ -1,82 +0,0 @@
1
- import { Reactive, ReactiveArray, Unsubscribe } from "@oscarpalmer/mora";
2
-
3
- //#region src/models.d.ts
4
- type FragmentConfiguration = {
5
- /**
6
- * Should the template be cached? _(defaults to `true`)_
7
- */
8
- cache?: boolean;
9
- /**
10
- * Identifier for the fragment
11
- *
12
- * _(An identifier can be used to uniquely identify a fragment,
13
- * which helps prevent re-rendering in certain scenarios)_
14
- */
15
- identifier?: unknown;
16
- };
17
- type FragmentData = {
18
- expressions: unknown[];
19
- items: FragmentItem[];
20
- mora: MoraData;
21
- strings: TemplateStringsArray;
22
- template?: string;
23
- values: unknown[];
24
- };
25
- type FragmentItem = {
26
- fragments?: Fragment[];
27
- nodes?: ChildNode[];
28
- text?: Text;
29
- };
30
- type FragmentsState = {
31
- array: ReactiveArray<unknown>;
32
- fragment: (item: unknown) => Fragment;
33
- identify: (item: unknown) => unknown;
34
- instances: Record<string, Fragment>;
35
- mapped: ReactiveArray<Fragment>;
36
- subscriber: Unsubscribe | undefined;
37
- };
38
- type MoraData = {
39
- subscribers: Set<() => void>;
40
- values: Set<Reactive<unknown>>;
41
- };
42
- //#endregion
43
- //#region src/fragment.d.ts
44
- declare class Fragment {
45
- #private;
46
- /**
47
- * Fragment identifier
48
- */
49
- get identifier(): unknown;
50
- constructor(strings: TemplateStringsArray, expressions: unknown[]);
51
- /**
52
- * Append the fragment to the given element
53
- * @param element Element to append to
54
- */
55
- appendTo(element: Element): void;
56
- /**
57
- * Configure the fragment
58
- * @param configuration Configuration options
59
- * @returns Fragment
60
- */
61
- configure(configuration: FragmentConfiguration): Fragment;
62
- /**
63
- * Get a list of the fragment's nodes
64
- * @returns List of nodes
65
- */
66
- get(): ChildNode[];
67
- /**
68
- * Set an identifier for the fragment
69
- *
70
- * _An identifier can be used to uniquely identify a fragment,
71
- * which helps prevent re-rendering in certain scenarios._
72
- * @param identifier Identifier
73
- * @returns Fragment
74
- */
75
- identify(identifier: unknown): Fragment;
76
- /**
77
- * Remove the fragment from the DOM
78
- */
79
- remove(): void;
80
- }
81
- //#endregion
82
- export { FragmentsState as a, FragmentItem as i, FragmentConfiguration as n, FragmentData as r, Fragment as t };