@oscarpalmer/abydon 0.19.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,20 +635,79 @@ 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;
615
698
  }
616
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));
708
+ }
709
+ const EXPRESSION_WHITESPACE$2 = /^\s*$/;
710
+ //#endregion
617
711
  //#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
618
712
  /**
619
713
  * Is the value an event target?
@@ -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";
@@ -948,6 +1451,7 @@ const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(apture)$/i;
948
1451
  const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(nce)$/i;
949
1452
  const EXPRESSION_EVENT_PREFIX = /^@/;
950
1453
  const EXPRESSION_PERIOD = /\./;
1454
+ const EXPRESSION_TEXTAREA_VALUE = /<!--abydon\.(\d+)-->/;
951
1455
  const NAME_FRAGMENT = "$fragment";
952
1456
  const NAME_FRAGMENTS = "$fragments";
953
1457
  const PROPERTY_CHECKED = "checked";
@@ -1021,7 +1525,7 @@ function handleItems(state, items) {
1021
1525
  const item = items[index];
1022
1526
  const identifier = state.identify(item);
1023
1527
  if (identifier == null) throw new TypeError(ERROR_IDENTIFIER_TYPE);
1024
- const key = getString(identifier);
1528
+ const key = getString$1(identifier);
1025
1529
  if (keys.has(key)) throw new Error(ERROR_IDENTIFIER_DUPLICATE.replace("<>", key));
1026
1530
  let instance = state.instances[key];
1027
1531
  if (instance == null) {
@@ -1065,10 +1569,10 @@ const states = /* @__PURE__ */ new WeakMap();
1065
1569
  function createNodes(value) {
1066
1570
  if (isFragment(value)) return value.get();
1067
1571
  if (isChildNode(value)) return [value];
1068
- return [new Text(getString(value))];
1572
+ return [new Text(getString$1(value))];
1069
1573
  }
1070
1574
  function isInputElement(node) {
1071
- return node instanceof HTMLInputElement || node instanceof HTMLSelectElement || node instanceof HTMLTextAreaElement;
1575
+ return node instanceof HTMLInputElement || node instanceof HTMLSelectElement;
1072
1576
  }
1073
1577
  function removeNodes(nodes) {
1074
1578
  const { length } = nodes;
@@ -1103,7 +1607,14 @@ function delegatedEventHandler(event) {
1103
1607
  const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
1104
1608
  const items = event.composedPath();
1105
1609
  const { length } = items;
1610
+ let cancelled = false;
1106
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);
1107
1618
  Object.defineProperties(event, {
1108
1619
  currentTarget: {
1109
1620
  configurable: true,
@@ -1123,7 +1634,7 @@ function delegatedEventHandler(event) {
1123
1634
  target = item;
1124
1635
  for (const listener of listeners) {
1125
1636
  listener.call(item, event);
1126
- if (event.cancelBubble) return;
1637
+ if (cancelled) return;
1127
1638
  }
1128
1639
  }
1129
1640
  }
@@ -1168,7 +1679,7 @@ const EVENT_TYPES = new Set([
1168
1679
  const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
1169
1680
  const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
1170
1681
  //#endregion
1171
- //#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
1172
1683
  /**
1173
1684
  * A function that does nothing, which can be useful, I guess…
1174
1685
  */
@@ -1312,8 +1823,13 @@ function mapAttributes(data, element) {
1312
1823
  function mapValue$1(data, element, name, value) {
1313
1824
  if (typeof value === "function") setComputedAttribute(data, element, name, value);
1314
1825
  else setAttribute(data, element, name, value);
1315
- if (name === "value" && isInputElement(element) && isSignal(value)) mapEvent(element, "@on", () => {
1316
- value.set(parse$1(element.value) ?? element.value);
1826
+ if (!isInputElement(element) || !isSignal(value)) return;
1827
+ let property;
1828
+ if (name === "checked" && element.type === "checkbox") property = PROPERTY_CHECKED;
1829
+ else if (name === "value") property = PROPERTY_VALUE;
1830
+ if (property != null) mapEvent(element, "@on", () => {
1831
+ const next = element[property];
1832
+ value.set(parse$1(String(next)) ?? next);
1317
1833
  });
1318
1834
  }
1319
1835
  function setComputedAttribute(data, element, name, callback) {
@@ -1416,8 +1932,8 @@ function setReactiveValueForSingle(item, comment, value) {
1416
1932
  else item.nodes = setText(item, comment, value);
1417
1933
  }
1418
1934
  function setText(item, comment, value) {
1419
- const isNullable = isNullableOrWhitespace(value);
1420
- 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);
1421
1937
  let result = false;
1422
1938
  if (item.nodes != null) {
1423
1939
  replaceText(item, comment, isNullable);
@@ -1445,10 +1961,31 @@ function mapNodes(data, nodes) {
1445
1961
  mapNode(data, node);
1446
1962
  continue;
1447
1963
  }
1964
+ if (node instanceof HTMLTextAreaElement) mapTextarea(data, node);
1448
1965
  if (isHTMLOrSVGElement(node)) mapAttributes(data, node);
1449
1966
  if (node.hasChildNodes()) mapNodes(data, [...node.childNodes]);
1450
1967
  }
1451
1968
  }
1969
+ function mapTextarea(data, element) {
1970
+ const [, index] = EXPRESSION_TEXTAREA_VALUE.exec(element.value) ?? [];
1971
+ if (index == null) return;
1972
+ element.value = "";
1973
+ const value = data.values[Number.parseInt(index, 10)];
1974
+ if (isSignal(value)) {
1975
+ element.value = String(value.peek());
1976
+ mapEvent(element, "@on", () => {
1977
+ value.set(element.value);
1978
+ });
1979
+ return;
1980
+ }
1981
+ let reactive;
1982
+ if (typeof value === "function") reactive = computed(value);
1983
+ else if (isComputed(value)) reactive = value;
1984
+ if (reactive == null) element.value = String(value);
1985
+ else data.mora.subscribers.add(reactive.subscribe((value) => {
1986
+ element.value = String(value);
1987
+ }));
1988
+ }
1452
1989
  function mapValue(data, comment, value) {
1453
1990
  switch (true) {
1454
1991
  case typeof value === "function":
@@ -1490,7 +2027,7 @@ function handleExpression(data, prefix, expression) {
1490
2027
  return `${prefix}${expressions}`;
1491
2028
  }
1492
2029
  if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
1493
- return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
2030
+ return isNullableOrWhitespace$1(expression) ? prefix : `${prefix}${expression}`;
1494
2031
  }
1495
2032
  function parse(data) {
1496
2033
  if (data.template != null) return data.template;
@@ -1548,7 +2085,7 @@ var Fragment = class {
1548
2085
  * @returns Fragment
1549
2086
  */
1550
2087
  configure(configuration) {
1551
- const actual = isPlainObject(configuration) ? configuration : {};
2088
+ const actual = isPlainObject$1(configuration) ? configuration : {};
1552
2089
  if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
1553
2090
  if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
1554
2091
  return this;