@manyducks.co/dolla 0.78.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -286,8 +286,20 @@ var DebugHub = class {
286
286
  if (hubOptions.info === false || isString(hubOptions.info) && hubOptions.info !== hubOptions.mode || !match(name)) {
287
287
  return noOp;
288
288
  } else {
289
- const label = `%c${name}`;
290
- return _console.info.bind(_console, label, `color:${hash(label)};font-weight:bold`);
289
+ let label = `%c${name}`;
290
+ if (options.id) {
291
+ label += ` %c[uid: %c${options.id}%c]`;
292
+ } else {
293
+ label += `%c%c%c`;
294
+ }
295
+ return _console.info.bind(
296
+ _console,
297
+ label,
298
+ `color:${hash(label)};font-weight:bold`,
299
+ `color:#777`,
300
+ `color:#aaa`,
301
+ `color:#777`
302
+ );
291
303
  }
292
304
  },
293
305
  get log() {
@@ -295,8 +307,20 @@ var DebugHub = class {
295
307
  if (hubOptions.log === false || isString(hubOptions.log) && hubOptions.log !== hubOptions.mode || !match(name)) {
296
308
  return noOp;
297
309
  } else {
298
- const label = `%c${name}`;
299
- return _console.log.bind(_console, label, `color:${hash(label)};font-weight:bold`);
310
+ let label = `%c${name}`;
311
+ if (options.id) {
312
+ label += ` %c[uid: %c${options.id}%c]`;
313
+ } else {
314
+ label += `%c%c%c`;
315
+ }
316
+ return _console.log.bind(
317
+ _console,
318
+ label,
319
+ `color:${hash(label)};font-weight:bold`,
320
+ `color:#777`,
321
+ `color:#aaa`,
322
+ `color:#777`
323
+ );
300
324
  }
301
325
  },
302
326
  get warn() {
@@ -304,8 +328,20 @@ var DebugHub = class {
304
328
  if (hubOptions.warn === false || isString(hubOptions.warn) && hubOptions.warn !== hubOptions.mode || !match(name)) {
305
329
  return noOp;
306
330
  } else {
307
- const label = `%c${name}`;
308
- return _console.warn.bind(_console, label, `color:${hash(label)};font-weight:bold`);
331
+ let label = `%c${name}`;
332
+ if (options.id) {
333
+ label += ` %c[uid: %c${options.id}%c]`;
334
+ } else {
335
+ label += `%c%c%c`;
336
+ }
337
+ return _console.warn.bind(
338
+ _console,
339
+ label,
340
+ `color:${hash(label)};font-weight:bold`,
341
+ `color:#777`,
342
+ `color:#aaa`,
343
+ `color:#777`
344
+ );
309
345
  }
310
346
  },
311
347
  get error() {
@@ -313,8 +349,20 @@ var DebugHub = class {
313
349
  if (hubOptions.error === false || isString(hubOptions.error) && hubOptions.error !== hubOptions.mode || !match(name)) {
314
350
  return noOp;
315
351
  } else {
316
- const label = `%c${name}`;
317
- return _console.error.bind(_console, label, `color:${hash(label)};font-weight:bold`);
352
+ let label = `%c${name}`;
353
+ if (options.id) {
354
+ label += ` %c[uid: %c${options.id}%c]`;
355
+ } else {
356
+ label += `%c%c%c`;
357
+ }
358
+ return _console.error.bind(
359
+ _console,
360
+ label,
361
+ `color:${hash(label)};font-weight:bold`,
362
+ `color:#777`,
363
+ `color:#aaa`,
364
+ `color:#777`
365
+ );
318
366
  }
319
367
  }
320
368
  };
@@ -385,6 +433,106 @@ function makeMatcher(pattern) {
385
433
  };
386
434
  }
387
435
 
436
+ // src/nodes/cond.ts
437
+ var Conditional = class {
438
+ node;
439
+ endNode;
440
+ $predicate;
441
+ stopCallback;
442
+ thenContent;
443
+ elseContent;
444
+ connectedContent = [];
445
+ appContext;
446
+ elementContext;
447
+ initialUpdateHappened = false;
448
+ previousValue;
449
+ constructor(config) {
450
+ this.$predicate = config.$predicate;
451
+ this.thenContent = config.thenContent ? toMarkup(config.thenContent) : void 0;
452
+ this.elseContent = config.elseContent ? toMarkup(config.elseContent) : void 0;
453
+ this.appContext = config.appContext;
454
+ this.elementContext = config.elementContext;
455
+ if (this.appContext.mode === "development") {
456
+ this.node = document.createComment("Conditional");
457
+ this.endNode = document.createComment("/Conditional");
458
+ } else {
459
+ this.node = document.createTextNode("");
460
+ this.endNode = document.createTextNode("");
461
+ }
462
+ }
463
+ get connected() {
464
+ return this.node.parentNode != null;
465
+ }
466
+ connect(parent2, after) {
467
+ if (!this.connected) {
468
+ parent2.insertBefore(this.node, after?.nextSibling ?? null);
469
+ if (this.appContext.mode === "development") {
470
+ parent2.insertBefore(this.endNode, this.node.nextSibling);
471
+ }
472
+ this.stopCallback = this.$predicate.watch((value) => {
473
+ if (!this.initialUpdateHappened || value && !this.previousValue || !value && this.previousValue) {
474
+ this.update(value);
475
+ this.initialUpdateHappened = true;
476
+ this.previousValue = value;
477
+ }
478
+ });
479
+ }
480
+ }
481
+ disconnect() {
482
+ if (this.stopCallback) {
483
+ this.stopCallback();
484
+ this.stopCallback = void 0;
485
+ }
486
+ for (const handle of this.connectedContent) {
487
+ handle.disconnect();
488
+ }
489
+ this.connectedContent = [];
490
+ if (this.connected) {
491
+ this.node.parentNode?.removeChild(this.node);
492
+ this.endNode.parentNode?.removeChild(this.endNode);
493
+ }
494
+ }
495
+ update(value) {
496
+ for (const handle of this.connectedContent) {
497
+ handle.disconnect();
498
+ }
499
+ this.connectedContent = [];
500
+ if (this.node.parentNode == null) {
501
+ return;
502
+ }
503
+ if (value && this.thenContent) {
504
+ this.connectedContent = renderMarkupToDOM(this.thenContent, this);
505
+ } else if (!value && this.elseContent) {
506
+ this.connectedContent = renderMarkupToDOM(this.elseContent, this);
507
+ }
508
+ for (let i = 0; i < this.connectedContent.length; i++) {
509
+ const handle = this.connectedContent[i];
510
+ const previous = this.connectedContent[i - 1]?.node ?? this.node;
511
+ handle.connect(this.node.parentNode, previous);
512
+ }
513
+ if (this.appContext.mode === "development") {
514
+ this.node.textContent = `Conditional (${value ? "truthy" : "falsy"})`;
515
+ }
516
+ }
517
+ async setChildren(children) {
518
+ }
519
+ };
520
+
521
+ // node_modules/nanoid/index.browser.js
522
+ var nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
523
+ byte &= 63;
524
+ if (byte < 36) {
525
+ id += byte.toString(36);
526
+ } else if (byte < 62) {
527
+ id += (byte - 26).toString(36).toUpperCase();
528
+ } else if (byte > 62) {
529
+ id += "-";
530
+ } else {
531
+ id += "_";
532
+ }
533
+ return id;
534
+ }, "");
535
+
388
536
  // src/utils.ts
389
537
  function isPlainObject(value) {
390
538
  return value != null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.getPrototypeOf({});
@@ -393,6 +541,9 @@ function deepEqual(one, two) {
393
541
  if (one === two) {
394
542
  return true;
395
543
  }
544
+ if (isSignal(one) || isSignal(two)) {
545
+ return false;
546
+ }
396
547
  if (isPlainObject(one) && isPlainObject(two)) {
397
548
  const keysOne = Object.keys(one);
398
549
  const keysTwo = Object.keys(two);
@@ -449,333 +600,282 @@ function omit(keys, object) {
449
600
  return process2(object);
450
601
  }
451
602
 
452
- // src/state.ts
453
- var UNOBSERVED = Symbol("Unobserved");
454
- var OBSERVE = Symbol("Observe");
455
- function isReadable(value) {
456
- return value != null && typeof value === "object" && typeof value[OBSERVE] === "function" && typeof value.get === "function";
457
- }
458
- function isWritable(value) {
459
- return isReadable(value) && typeof value.set === "function" && typeof value.update === "function";
460
- }
461
- function $$(initialValue, config) {
462
- if (config) {
463
- return proxy(initialValue, config);
464
- } else {
465
- return writable(initialValue);
603
+ // src/signals.ts
604
+ function isSignal(value) {
605
+ if (value == null || typeof value !== "object") {
606
+ return false;
466
607
  }
608
+ if (typeof value["get"] !== "function") {
609
+ return false;
610
+ }
611
+ if (typeof value["watch"] !== "function") {
612
+ return false;
613
+ }
614
+ return true;
467
615
  }
468
- function $(...args) {
469
- if (args.length > 1) {
470
- const callback = args.pop();
471
- const readables = args.flat().map(readable);
472
- return computed(...readables, callback);
473
- } else {
474
- return readable(args[0]);
616
+ function isSettableSignal(value) {
617
+ if (value == null || typeof value !== "object") {
618
+ return false;
619
+ }
620
+ if (typeof value["set"] !== "function") {
621
+ return false;
622
+ }
623
+ if (typeof value["get"] !== "function") {
624
+ return false;
625
+ }
626
+ if (typeof value["watch"] !== "function") {
627
+ return false;
475
628
  }
629
+ return true;
476
630
  }
477
- function readable(value) {
478
- if (isWritable(value)) {
479
- return {
480
- get: value.get,
481
- [OBSERVE]: value[OBSERVE]
482
- };
631
+ function designalify(value) {
632
+ if (isSignal(value)) {
633
+ return value.get();
634
+ } else {
635
+ return value;
483
636
  }
484
- if (isReadable(value)) {
637
+ }
638
+ function signalify(value) {
639
+ if (isSignal(value)) {
485
640
  return value;
641
+ } else {
642
+ return createStaticSignal(value);
486
643
  }
644
+ }
645
+ function signal(initialValue, options) {
646
+ return createSignal(initialValue, options);
647
+ }
648
+ signal.settable = createSettableSignal;
649
+ signal.toSettable = createSettableSignalFrom;
650
+ signal.createSetter = createSignalSetter;
651
+ function createSettableSignal(initialValue, options) {
652
+ const [$value, setValue] = signal(initialValue, options);
487
653
  return {
488
- get: () => value,
489
- [OBSERVE]: (callback) => {
490
- callback(value);
491
- return function stop() {
492
- };
493
- }
654
+ get: $value.get,
655
+ watch: $value.watch,
656
+ set: setValue
494
657
  };
495
658
  }
496
- function computed(...args) {
497
- const compute = args.pop();
498
- if (typeof compute !== "function") {
499
- throw new TypeError(`Final argument must be a function. Got ${typeOf(compute)}: ${compute}`);
500
- }
501
- if (args.length < 1) {
502
- throw new Error(`Must pass at least one value before the callback function.`);
503
- }
504
- const readables = args;
505
- const observers = [];
506
- let stopCallbacks = [];
507
- let isObserving = false;
508
- let observedValues = [];
509
- let valuesChanged = [];
510
- let latestComputedValue = UNOBSERVED;
511
- let computedStopCallback;
512
- function updateValue() {
513
- if (!valuesChanged.some((x) => x)) {
514
- return;
515
- }
516
- const computedValue = compute(...observedValues);
517
- if (isReadable(computedValue)) {
518
- if (computedStopCallback) {
519
- computedStopCallback();
520
- }
521
- computedStopCallback = computedValue[OBSERVE]((current) => {
522
- latestComputedValue = current;
523
- for (const callback of observers) {
524
- callback(current);
525
- }
526
- });
527
- } else if (!deepEqual(computedValue, latestComputedValue)) {
528
- if (computedStopCallback) {
529
- computedStopCallback();
530
- computedStopCallback = void 0;
531
- }
532
- latestComputedValue = computedValue;
533
- for (const callback of observers) {
534
- callback(computedValue);
535
- }
536
- }
537
- for (let i = 0; i < observedValues.length; i++) {
538
- valuesChanged[i] = false;
539
- }
540
- }
541
- function startObserving() {
542
- if (isObserving)
543
- return;
544
- for (let i = 0; i < readables.length; i++) {
545
- const readable2 = readables[i];
546
- stopCallbacks.push(
547
- observe(readable2, (value) => {
548
- if (!deepEqual(observedValues[i], value)) {
549
- observedValues[i] = value;
550
- valuesChanged[i] = true;
551
- if (isObserving) {
552
- updateValue();
553
- }
554
- }
555
- })
556
- );
557
- }
558
- observedValues = readables.map((x) => x.get());
559
- for (let i = 0; i < observedValues.length; i++) {
560
- valuesChanged[i] = true;
561
- }
562
- isObserving = true;
563
- updateValue();
564
- }
565
- function stopObserving() {
566
- isObserving = false;
567
- for (const callback of stopCallbacks) {
568
- callback();
659
+ function createSettableSignalFrom(signal2, setter) {
660
+ return {
661
+ get: signal2.get,
662
+ watch: signal2.watch,
663
+ set: setter
664
+ };
665
+ }
666
+ function createSignalSetter(signal2, callback) {
667
+ return function setValue(nextOrCallback) {
668
+ const previous = signal2.get();
669
+ let next;
670
+ if (typeof nextOrCallback === "function") {
671
+ next = nextOrCallback(previous);
672
+ } else {
673
+ next = nextOrCallback;
569
674
  }
570
- stopCallbacks = [];
571
- }
675
+ callback(next, previous);
676
+ };
677
+ }
678
+ function createStaticSignal(value) {
572
679
  return {
573
- get: () => {
574
- if (isObserving) {
575
- return latestComputedValue;
576
- } else {
577
- return compute(...readables.map((x) => x.get()));
578
- }
680
+ get() {
681
+ return value;
579
682
  },
580
- [OBSERVE]: (callback) => {
581
- if (!isObserving) {
582
- startObserving();
683
+ watch(callback, options = {}) {
684
+ if (!options.lazy) {
685
+ callback(value);
583
686
  }
584
- callback(latestComputedValue);
585
- observers.push(callback);
586
687
  return function stop() {
587
- observers.splice(observers.indexOf(callback), 1);
588
- if (observers.length === 0) {
589
- stopObserving();
590
- }
591
688
  };
592
689
  }
593
690
  };
594
691
  }
595
- function writable(value) {
596
- if (isWritable(value)) {
597
- return value;
692
+ function createSignal(initialValue, options) {
693
+ let currentValue = initialValue;
694
+ let watchers = [];
695
+ function notify() {
696
+ for (const watcher of watchers) {
697
+ watcher(currentValue);
698
+ }
598
699
  }
599
- if (isReadable(value)) {
600
- throw new TypeError(`Failed to convert Readable into a Writable; can't add write access to a read-only value.`);
700
+ function equal(next, previous) {
701
+ if (options?.equality) {
702
+ return options.equality(next, previous);
703
+ } else {
704
+ return deepEqual(next, previous);
705
+ }
601
706
  }
602
- const observers = [];
603
- let currentValue = value;
604
- return {
605
- // ----- Readable ----- //
606
- get: () => currentValue,
607
- [OBSERVE]: (callback) => {
608
- observers.push(callback);
609
- function stop() {
610
- observers.splice(observers.indexOf(callback), 1);
611
- }
612
- callback(currentValue);
613
- return stop;
614
- },
615
- // ----- Writable ----- //
616
- set: (newValue) => {
617
- if (!deepEqual(currentValue, newValue)) {
618
- const previousValue = currentValue;
619
- currentValue = newValue;
620
- for (const callback of observers) {
621
- callback(currentValue, previousValue);
622
- }
623
- }
707
+ const $value = {
708
+ get() {
709
+ return designalify(currentValue);
624
710
  },
625
- update: (callback) => {
626
- const newValue = callback(currentValue);
627
- if (!deepEqual(currentValue, newValue)) {
628
- const previousValue = currentValue;
629
- currentValue = newValue;
630
- for (const callback2 of observers) {
631
- callback2(currentValue, previousValue);
632
- }
711
+ watch(callback, options2) {
712
+ watchers.push(callback);
713
+ if (!options2?.lazy) {
714
+ callback($value.get());
633
715
  }
716
+ return function stop() {
717
+ watchers.splice(watchers.indexOf(callback), 1);
718
+ };
634
719
  }
635
720
  };
636
- }
637
- function proxy(source, config) {
638
- if (!isReadable(source)) {
639
- throw new TypeError(`Proxy source must be a Readable.`);
640
- }
641
- return {
642
- // ----- Readable ----- //
643
- get: () => config.get(),
644
- [OBSERVE]: (callback) => {
645
- let lastComputedValue = UNOBSERVED;
646
- return observe(source, (_) => {
647
- const computedValue = config.get();
648
- if (!deepEqual(computedValue, lastComputedValue)) {
649
- callback(computedValue);
650
- lastComputedValue = computedValue;
651
- }
652
- });
653
- },
654
- // ----- Writable ----- //
655
- set: (value) => {
656
- config.set(value);
657
- },
658
- update: (callback) => {
659
- config.set(callback(config.get()));
721
+ function setValue(next) {
722
+ let value;
723
+ if (typeof next === "function") {
724
+ value = next(currentValue);
725
+ } else {
726
+ value = next;
727
+ }
728
+ if (!equal(value, currentValue)) {
729
+ currentValue = value;
730
+ notify();
660
731
  }
661
- };
662
- }
663
- function observe(...args) {
664
- const callback = args.pop();
665
- const readables = args.flat().map(readable);
666
- if (readables.length === 0) {
667
- throw new TypeError(`Expected at least one readable.`);
668
- }
669
- if (readables.length > 1) {
670
- return computed(...readables, callback)[OBSERVE](() => null);
671
- } else {
672
- return readables[0][OBSERVE](callback);
673
732
  }
733
+ return [$value, setValue];
674
734
  }
675
- function unwrap(value) {
676
- if (isReadable(value)) {
677
- return value.get();
678
- }
679
- return value;
680
- }
681
-
682
- // src/nodes/cond.ts
683
- var Conditional = class {
684
- node;
685
- endNode;
686
- $predicate;
687
- stopCallback;
688
- thenContent;
689
- elseContent;
690
- connectedContent = [];
691
- appContext;
692
- elementContext;
693
- initialUpdateHappened = false;
694
- constructor(config) {
695
- this.$predicate = config.$predicate;
696
- this.thenContent = config.thenContent ? toMarkup(config.thenContent) : void 0;
697
- this.elseContent = config.elseContent ? toMarkup(config.elseContent) : void 0;
698
- this.appContext = config.appContext;
699
- this.elementContext = config.elementContext;
700
- if (this.appContext.mode === "development") {
701
- this.node = document.createComment("Conditional");
702
- this.endNode = document.createComment("/Conditional");
735
+ var EMPTY = Symbol("EMPTY");
736
+ function derive(signals, fn, options) {
737
+ signals = signals.map((s) => {
738
+ if (isSignal(s)) {
739
+ return s;
703
740
  } else {
704
- this.node = document.createTextNode("");
705
- this.endNode = document.createTextNode("");
741
+ return createStaticSignal(s);
742
+ }
743
+ });
744
+ let previousSourceValues = new Array(signals.length).fill(EMPTY, 0, signals.length);
745
+ let currentValue;
746
+ let watchers = [];
747
+ let watching = false;
748
+ let stoppers = [];
749
+ let stopWatchingCurrentValue;
750
+ let rawCurrentValue;
751
+ function notify(value = getCurrentValue()) {
752
+ for (const watcher of watchers) {
753
+ watcher(value);
754
+ }
755
+ }
756
+ function equal(next, previous) {
757
+ if (options?.equality) {
758
+ return options.equality(next, previous);
759
+ } else {
760
+ return deepEqual(next, previous);
706
761
  }
707
762
  }
708
- get connected() {
709
- return this.node.parentNode != null;
710
- }
711
- connect(parent2, after) {
712
- if (!this.connected) {
713
- parent2.insertBefore(this.node, after?.nextSibling ?? null);
714
- if (this.appContext.mode === "development") {
715
- parent2.insertBefore(this.endNode, this.node.nextSibling);
763
+ function update() {
764
+ const sourceValues = signals.map((s) => s.get());
765
+ for (let i = 0; i < signals.length; i++) {
766
+ if (!equal(sourceValues[i], previousSourceValues[i])) {
767
+ setCurrentValue(fn(...sourceValues));
768
+ previousSourceValues = sourceValues;
769
+ break;
716
770
  }
717
- this.stopCallback = observe(this.$predicate, (current, previous) => {
718
- if (!this.initialUpdateHappened || current && !previous || !current && previous) {
719
- this.update(current);
720
- this.initialUpdateHappened = true;
721
- }
722
- });
723
771
  }
724
772
  }
725
- disconnect() {
726
- if (this.stopCallback) {
727
- this.stopCallback();
728
- this.stopCallback = void 0;
773
+ function getCurrentValue() {
774
+ if (!watching) {
775
+ update();
729
776
  }
730
- for (const handle of this.connectedContent) {
731
- handle.disconnect();
777
+ rawCurrentValue = designalify(currentValue);
778
+ return rawCurrentValue;
779
+ }
780
+ function setCurrentValue(value) {
781
+ if (value === currentValue) {
782
+ return;
732
783
  }
733
- this.connectedContent = [];
734
- if (this.connected) {
735
- this.node.parentNode?.removeChild(this.node);
736
- this.endNode.parentNode?.removeChild(this.endNode);
784
+ if (stopWatchingCurrentValue) {
785
+ stopWatchingCurrentValue();
786
+ stopWatchingCurrentValue = void 0;
787
+ }
788
+ currentValue = value;
789
+ rawCurrentValue = designalify(value);
790
+ if (isSignal(value)) {
791
+ if (watching) {
792
+ stopWatchingCurrentValue = value.watch((current) => {
793
+ const raw = designalify(current);
794
+ if (!equal(raw, rawCurrentValue)) {
795
+ rawCurrentValue = raw;
796
+ notify(raw);
797
+ }
798
+ });
799
+ }
737
800
  }
738
801
  }
739
- update(value) {
740
- for (const handle of this.connectedContent) {
741
- handle.disconnect();
802
+ function startWatchingSources() {
803
+ let startingSourceValues = [...previousSourceValues];
804
+ for (let i = 0; i < signals.length; i++) {
805
+ const signal2 = signals[i];
806
+ stoppers.push(
807
+ signal2.watch((next) => {
808
+ const previous = previousSourceValues[i];
809
+ previousSourceValues[i] = next;
810
+ if (watching && !equal(next, previous)) {
811
+ setCurrentValue(fn(...previousSourceValues));
812
+ notify(designalify(currentValue));
813
+ }
814
+ })
815
+ );
742
816
  }
743
- this.connectedContent = [];
744
- if (this.node.parentNode == null) {
745
- return;
817
+ watching = true;
818
+ for (let i = 0; i < signals.length; i++) {
819
+ if (!equal(previousSourceValues[i], startingSourceValues[i])) {
820
+ setCurrentValue(fn(...previousSourceValues));
821
+ notify(designalify(currentValue));
822
+ break;
823
+ }
746
824
  }
747
- if (value && this.thenContent) {
748
- this.connectedContent = renderMarkupToDOM(this.thenContent, this);
749
- } else if (!value && this.elseContent) {
750
- this.connectedContent = renderMarkupToDOM(this.elseContent, this);
825
+ }
826
+ function stopWatchingSources() {
827
+ for (const stop of stoppers) {
828
+ stop();
751
829
  }
752
- for (let i = 0; i < this.connectedContent.length; i++) {
753
- const handle = this.connectedContent[i];
754
- const previous = this.connectedContent[i - 1]?.node ?? this.node;
755
- handle.connect(this.node.parentNode, previous);
830
+ stoppers = [];
831
+ if (stopWatchingCurrentValue) {
832
+ stopWatchingCurrentValue();
833
+ stopWatchingCurrentValue = void 0;
756
834
  }
757
- if (this.appContext.mode === "development") {
758
- this.node.textContent = `Conditional (${value ? "truthy" : "falsy"})`;
835
+ watching = false;
836
+ }
837
+ const $value = {
838
+ get() {
839
+ return getCurrentValue();
840
+ },
841
+ watch(callback, options2) {
842
+ if (!watching) {
843
+ startWatchingSources();
844
+ }
845
+ watchers.push(callback);
846
+ if (!options2?.lazy) {
847
+ callback(getCurrentValue());
848
+ }
849
+ return function stop() {
850
+ watchers.splice(watchers.indexOf(callback), 1);
851
+ if (watching && watchers.length === 0) {
852
+ stopWatchingSources();
853
+ }
854
+ };
759
855
  }
856
+ };
857
+ return $value;
858
+ }
859
+ function watch(signals, fn) {
860
+ if (signals.length === 0) {
861
+ throw new TypeError(`Expected at least one signal.`);
760
862
  }
761
- async setChildren(children) {
863
+ if (signals.some((s) => !isSignal(s))) {
864
+ throw new TypeError(`All values must be signals`);
762
865
  }
763
- };
764
-
765
- // node_modules/nanoid/index.browser.js
766
- var nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
767
- byte &= 63;
768
- if (byte < 36) {
769
- id += byte.toString(36);
770
- } else if (byte < 62) {
771
- id += (byte - 26).toString(36).toUpperCase();
772
- } else if (byte > 62) {
773
- id += "-";
866
+ signals = signals.map((s) => {
867
+ if (isSignal(s)) {
868
+ return s;
869
+ } else {
870
+ return createStaticSignal(s);
871
+ }
872
+ });
873
+ if (signals.length > 1) {
874
+ return derive(signals, fn).watch(() => null);
774
875
  } else {
775
- id += "_";
876
+ return signals[0].watch(fn);
776
877
  }
777
- return id;
778
- }, "");
878
+ }
779
879
 
780
880
  // src/nodes/html.ts
781
881
  var isCamelCaseEventName = (key) => /^on[A-Z]/.test(key);
@@ -806,12 +906,10 @@ var HTML = class {
806
906
  this.node.dataset.uniqueId = this.uniqueId;
807
907
  }
808
908
  if (props.ref) {
809
- if (isWritable(props.ref)) {
810
- props.ref.set(this.node);
811
- } else if (isFunction(props.ref)) {
812
- props.ref(this.node);
909
+ if (isRef(props.ref)) {
910
+ props.ref.node = this.node;
813
911
  } else {
814
- throw new Error("Expected an instance of Ref. Got: " + props.ref);
912
+ throw new Error("Expected ref to be a Ref object. Got: " + props.ref);
815
913
  }
816
914
  }
817
915
  this.props = {
@@ -878,11 +976,11 @@ var HTML = class {
878
976
  applyProps(element, props) {
879
977
  const render = this.appContext.stores.get("render").instance?.exports;
880
978
  const attachProp = (value, callback, updateKey) => {
881
- if (isReadable(value)) {
979
+ if (isSignal(value)) {
882
980
  this.stopCallbacks.push(
883
- observe(value, (value2) => {
981
+ value.watch((current) => {
884
982
  render.update(() => {
885
- callback(value2);
983
+ callback(current);
886
984
  }, updateKey);
887
985
  })
888
986
  );
@@ -912,22 +1010,37 @@ var HTML = class {
912
1010
  } else if (key === "eventListeners") {
913
1011
  const values = value;
914
1012
  for (const name in values) {
915
- const listener = isReadable(value) ? (e) => value.get()(e) : value;
1013
+ const listener = isSignal(value) ? (e) => value.get()(e) : value;
916
1014
  element.addEventListener(name, listener);
917
1015
  this.stopCallbacks.push(() => {
918
1016
  element.removeEventListener(name, listener);
919
1017
  });
920
1018
  }
1019
+ } else if (key === "onClickOutside" || key === "onclickoutside") {
1020
+ const listener = (e) => {
1021
+ if (this.canClickAway && !element.contains(e.target)) {
1022
+ if (isSignal(value)) {
1023
+ value.get()(e);
1024
+ } else {
1025
+ value(e);
1026
+ }
1027
+ }
1028
+ };
1029
+ const options = { capture: true };
1030
+ window.addEventListener("click", listener, options);
1031
+ this.stopCallbacks.push(() => {
1032
+ window.removeEventListener("click", listener, options);
1033
+ });
921
1034
  } else if (key === "$$value") {
922
- if (!isWritable(value)) {
923
- throw new TypeError(`$$value property must be a Writable. Got: ${value} (${typeof value})`);
1035
+ if (!isSettableSignal(value)) {
1036
+ throw new TypeError(`$$value attribute must be a settable signal. Got: ${value}`);
924
1037
  }
925
1038
  attachProp(
926
1039
  value,
927
1040
  (current) => {
928
1041
  element.value = String(current);
929
1042
  },
930
- this.getUpdateKey("prop", "value")
1043
+ this.getUpdateKey("attr", "value")
931
1044
  );
932
1045
  const listener = (e) => {
933
1046
  const updated = toTypeOf(value.get(), e.currentTarget.value);
@@ -937,24 +1050,9 @@ var HTML = class {
937
1050
  this.stopCallbacks.push(() => {
938
1051
  element.removeEventListener("input", listener);
939
1052
  });
940
- } else if (key === "onClickOutside" || key === "onclickoutside") {
941
- const listener = (e) => {
942
- if (this.canClickAway && !element.contains(e.target)) {
943
- if (isReadable(value)) {
944
- value.get()(e);
945
- } else {
946
- value(e);
947
- }
948
- }
949
- };
950
- const options = { capture: true };
951
- window.addEventListener("click", listener, options);
952
- this.stopCallbacks.push(() => {
953
- window.removeEventListener("click", listener, options);
954
- });
955
1053
  } else if (isCamelCaseEventName(key)) {
956
1054
  const eventName = key.slice(2).toLowerCase();
957
- const listener = isReadable(value) ? (e) => value.get()(e) : value;
1055
+ const listener = isSignal(value) ? (e) => value.get()(e) : value;
958
1056
  element.addEventListener(eventName, listener);
959
1057
  this.stopCallbacks.push(() => {
960
1058
  element.removeEventListener(eventName, listener);
@@ -1075,9 +1173,9 @@ var HTML = class {
1075
1173
  element.style.cssText = "";
1076
1174
  } else if (typeof styles === "string") {
1077
1175
  element.style.cssText = styles;
1078
- } else if (isReadable(styles)) {
1176
+ } else if (isSignal(styles)) {
1079
1177
  let unapply;
1080
- const stop = observe(styles, (current) => {
1178
+ const stop = styles.watch((current) => {
1081
1179
  render.update(
1082
1180
  () => {
1083
1181
  if (isFunction(unapply)) {
@@ -1096,8 +1194,8 @@ var HTML = class {
1096
1194
  for (const key in styles) {
1097
1195
  const value = styles[key];
1098
1196
  const setProperty = key.startsWith("--") ? (key2, value2) => value2 == null ? element.style.removeProperty(key2) : element.style.setProperty(key2, value2) : (key2, value2) => element.style[key2] = value2 ?? "";
1099
- if (isReadable(value)) {
1100
- const stop = observe(value, (current) => {
1197
+ if (isSignal(value)) {
1198
+ const stop = value.watch((current) => {
1101
1199
  render.update(
1102
1200
  () => {
1103
1201
  if (current != null) {
@@ -1132,9 +1230,9 @@ var HTML = class {
1132
1230
  applyClasses(element, classes, stopCallbacks) {
1133
1231
  const render = this.appContext.stores.get("render").instance?.exports;
1134
1232
  const classStopCallbacks = [];
1135
- if (isReadable(classes)) {
1233
+ if (isSignal(classes)) {
1136
1234
  let unapply;
1137
- const stop = observe(classes, (current) => {
1235
+ const stop = classes.watch((current) => {
1138
1236
  render.update(
1139
1237
  () => {
1140
1238
  if (isFunction(unapply)) {
@@ -1152,8 +1250,8 @@ var HTML = class {
1152
1250
  const mapped = getClassMap(classes);
1153
1251
  for (const name in mapped) {
1154
1252
  const value = mapped[name];
1155
- if (isReadable(value)) {
1156
- const stop = observe(value, (current) => {
1253
+ if (isSignal(value)) {
1254
+ const stop = value.watch((current) => {
1157
1255
  render.update(() => {
1158
1256
  if (current) {
1159
1257
  element.classList.add(name);
@@ -1220,7 +1318,7 @@ var Observer = class {
1220
1318
  get connected() {
1221
1319
  return this.node.parentNode != null;
1222
1320
  }
1223
- constructor({ readables, renderFn, appContext, elementContext }) {
1321
+ constructor({ signals, renderFn, appContext, elementContext }) {
1224
1322
  this.appContext = appContext;
1225
1323
  this.elementContext = elementContext;
1226
1324
  this.renderFn = renderFn;
@@ -1231,7 +1329,7 @@ var Observer = class {
1231
1329
  start: () => {
1232
1330
  if (_stop != null)
1233
1331
  return;
1234
- _stop = observe(readables, (...values) => {
1332
+ _stop = watch(signals, (...values) => {
1235
1333
  const rendered = this.renderFn(...values);
1236
1334
  if (!isRenderable(rendered)) {
1237
1335
  console.error(rendered);
@@ -1330,7 +1428,7 @@ var Outlet = class {
1330
1428
  connect(parent2, after) {
1331
1429
  if (!this.connected) {
1332
1430
  parent2.insertBefore(this.node, after?.nextSibling ?? null);
1333
- this.stopCallback = observe(this.$children, (children) => {
1431
+ this.stopCallback = this.$children.watch((children) => {
1334
1432
  this.update(children);
1335
1433
  });
1336
1434
  }
@@ -1417,7 +1515,9 @@ function initView(config) {
1417
1515
  stores: /* @__PURE__ */ new Map(),
1418
1516
  parent: config.elementContext
1419
1517
  };
1420
- const $$children = $$(renderMarkupToDOM(config.children ?? [], { appContext, elementContext }));
1518
+ const [$children, setChildren] = signal(
1519
+ renderMarkupToDOM(config.children ?? [], { appContext, elementContext })
1520
+ );
1421
1521
  let isConnected = false;
1422
1522
  const stopObserverCallbacks = [];
1423
1523
  const connectedCallbacks = [];
@@ -1426,7 +1526,7 @@ function initView(config) {
1426
1526
  const beforeDisconnectCallbacks = [];
1427
1527
  const uniqueId = nanoid();
1428
1528
  const ctx = {
1429
- get uniqueId() {
1529
+ get uid() {
1430
1530
  return uniqueId;
1431
1531
  },
1432
1532
  name: config.view.name ?? "anonymous",
@@ -1473,28 +1573,47 @@ function initView(config) {
1473
1573
  beforeDisconnect(callback) {
1474
1574
  beforeDisconnectCallbacks.push(callback);
1475
1575
  },
1576
+ onMount(callback) {
1577
+ connectedCallbacks.push(callback);
1578
+ },
1579
+ onUnmount(callback) {
1580
+ disconnectedCallbacks.push(callback);
1581
+ },
1476
1582
  crash(error) {
1477
1583
  config.appContext.crashCollector.crash({ error, componentName: ctx.name });
1478
1584
  },
1479
- observe(...args) {
1480
- const callback = args.pop();
1585
+ watch(signals, callback) {
1481
1586
  if (isConnected) {
1482
- const stop = observe(args, callback);
1587
+ const stop = watch(signals, callback);
1483
1588
  stopObserverCallbacks.push(stop);
1589
+ return stop;
1484
1590
  } else {
1591
+ let stop;
1592
+ let stopped = false;
1485
1593
  connectedCallbacks.push(() => {
1486
- const stop = observe(args, callback);
1487
- stopObserverCallbacks.push(stop);
1594
+ if (!stopped) {
1595
+ stop = watch(signals, callback);
1596
+ stopObserverCallbacks.push(stop);
1597
+ }
1488
1598
  });
1599
+ return function stop2() {
1600
+ if (stop2 != null) {
1601
+ stopped = true;
1602
+ stop2();
1603
+ }
1604
+ };
1489
1605
  }
1490
1606
  },
1491
1607
  outlet() {
1492
- return m("$outlet", { $children: $($$children) });
1608
+ return m("$outlet", { $children });
1493
1609
  }
1494
1610
  };
1495
1611
  const debugChannel = appContext.debugHub.channel({
1496
1612
  get name() {
1497
1613
  return ctx.name;
1614
+ },
1615
+ get id() {
1616
+ return uniqueId;
1498
1617
  }
1499
1618
  });
1500
1619
  Object.defineProperties(ctx, Object.getOwnPropertyDescriptors(debugChannel));
@@ -1528,9 +1647,9 @@ function initView(config) {
1528
1647
  rendered = getRenderHandle(renderMarkupToDOM(m("$node", { value: result }), { appContext, elementContext }));
1529
1648
  } else if (isMarkup(result) || isArrayOf(isMarkup, result)) {
1530
1649
  rendered = getRenderHandle(renderMarkupToDOM(result, { appContext, elementContext }));
1531
- } else if (isReadable(result)) {
1650
+ } else if (isSignal(result)) {
1532
1651
  rendered = getRenderHandle(
1533
- renderMarkupToDOM(m("$observer", { readables: [result], renderFn: (x) => x }), { appContext, elementContext })
1652
+ renderMarkupToDOM(m("$observer", { signals: [result], renderFn: (x) => x }), { appContext, elementContext })
1534
1653
  );
1535
1654
  } else {
1536
1655
  console.warn(result, config);
@@ -1590,7 +1709,7 @@ function initView(config) {
1590
1709
  }
1591
1710
  },
1592
1711
  async setChildren(children) {
1593
- $$children.set(children);
1712
+ setChildren(children);
1594
1713
  }
1595
1714
  };
1596
1715
  return handle;
@@ -1627,7 +1746,7 @@ var Repeat = class {
1627
1746
  connect(parent2, after) {
1628
1747
  if (!this.connected) {
1629
1748
  parent2.insertBefore(this.node, after?.nextSibling ?? null);
1630
- this.stopCallback = observe(this.$items, (value) => {
1749
+ this.stopCallback = this.$items.watch((value) => {
1631
1750
  this._update(Array.from(value));
1632
1751
  });
1633
1752
  }
@@ -1675,21 +1794,23 @@ var Repeat = class {
1675
1794
  for (const potential of potentialItems) {
1676
1795
  const connected = this.connectedItems.find((item) => item.key === potential.key);
1677
1796
  if (connected) {
1678
- connected.$$value.set(potential.value);
1679
- connected.$$index.set(potential.index);
1797
+ connected.setValue(potential.value);
1798
+ connected.setIndex(potential.index);
1680
1799
  newItems[potential.index] = connected;
1681
1800
  } else {
1682
- const $$value = $$(potential.value);
1683
- const $$index = $$(potential.index);
1801
+ const [$value, setValue] = signal(potential.value);
1802
+ const [$index, setIndex] = signal(potential.index);
1684
1803
  newItems[potential.index] = {
1685
1804
  key: potential.key,
1686
- $$value,
1687
- $$index,
1805
+ $value,
1806
+ setValue,
1807
+ $index,
1808
+ setIndex,
1688
1809
  handle: initView({
1689
1810
  view: RepeatItemView,
1690
1811
  appContext: this.appContext,
1691
1812
  elementContext: this.elementContext,
1692
- props: { $value: $($$value), $index: $($$index), renderFn: this.renderFn }
1813
+ props: { $value, $index, renderFn: this.renderFn }
1693
1814
  })
1694
1815
  };
1695
1816
  }
@@ -1724,8 +1845,8 @@ var Text = class {
1724
1845
  }
1725
1846
  async connect(parent2, after = null) {
1726
1847
  if (!this.connected) {
1727
- if (isReadable(this.value)) {
1728
- this.stopCallback = observe(this.value, (value) => {
1848
+ if (isSignal(this.value)) {
1849
+ this.stopCallback = this.value.watch((value) => {
1729
1850
  this.update(value);
1730
1851
  });
1731
1852
  } else {
@@ -1776,9 +1897,9 @@ function toMarkup(renderables) {
1776
1897
  if (isString(x) || isNumber(x)) {
1777
1898
  return m("$text", { value: x });
1778
1899
  }
1779
- if (isReadable(x)) {
1900
+ if (isSignal(x)) {
1780
1901
  return m("$observer", {
1781
- readables: [x],
1902
+ signals: [x],
1782
1903
  renderFn: (x2) => x2
1783
1904
  });
1784
1905
  }
@@ -1787,6 +1908,9 @@ function toMarkup(renderables) {
1787
1908
  });
1788
1909
  }
1789
1910
  function m(type, props, ...children) {
1911
+ if (props != null) {
1912
+ _assertPropTypes(props);
1913
+ }
1790
1914
  return {
1791
1915
  [MARKUP]: true,
1792
1916
  type,
@@ -1794,8 +1918,27 @@ function m(type, props, ...children) {
1794
1918
  children: toMarkup(children)
1795
1919
  };
1796
1920
  }
1921
+ function _assertPropTypes(props) {
1922
+ if (props.ref) {
1923
+ if (!isRef(props.ref)) {
1924
+ console.warn(props.ref);
1925
+ throw new TypeError(`Prop 'ref' must be a Ref object. Got: ${props.ref}`);
1926
+ }
1927
+ }
1928
+ for (const key in props) {
1929
+ if (key.startsWith("$$")) {
1930
+ if (!isSettableSignal(props[key])) {
1931
+ throw new TypeError(`Prop '${key}' is named as a SettableSignal but value is not. Got: ${props[key]}`);
1932
+ }
1933
+ } else if (key.startsWith("$")) {
1934
+ if (!isSignal(props[key])) {
1935
+ throw new TypeError(`Prop '${key}' is named as a Signal but value is not. Got: ${props[key]}`);
1936
+ }
1937
+ }
1938
+ }
1939
+ }
1797
1940
  function cond(predicate, thenContent, elseContent) {
1798
- const $predicate = $(predicate);
1941
+ const $predicate = signalify(predicate);
1799
1942
  return m("$cond", {
1800
1943
  $predicate,
1801
1944
  thenContent,
@@ -1803,12 +1946,34 @@ function cond(predicate, thenContent, elseContent) {
1803
1946
  });
1804
1947
  }
1805
1948
  function repeat(items, keyFn, renderFn) {
1806
- const $items = $(items);
1949
+ const $items = signalify(items);
1807
1950
  return m("$repeat", { $items, keyFn, renderFn });
1808
1951
  }
1809
1952
  function portal(content, parent2) {
1810
1953
  return m("$portal", { content, parent: parent2 });
1811
1954
  }
1955
+ function ref() {
1956
+ const [$node, setNode] = signal();
1957
+ return {
1958
+ get: $node.get,
1959
+ watch: $node.watch,
1960
+ get node() {
1961
+ return $node.get();
1962
+ },
1963
+ set node(node) {
1964
+ setNode(node);
1965
+ }
1966
+ };
1967
+ }
1968
+ function isRef(value) {
1969
+ if (value == null || typeof value !== "object") {
1970
+ return false;
1971
+ }
1972
+ if (!value.hasOwnProperty("node")) {
1973
+ return false;
1974
+ }
1975
+ return true;
1976
+ }
1812
1977
  var NodeHandle = class {
1813
1978
  node;
1814
1979
  get connected() {
@@ -1874,7 +2039,7 @@ function renderMarkupToDOM(markup, ctx) {
1874
2039
  case "$observer": {
1875
2040
  const attrs = item.props;
1876
2041
  return new Observer({
1877
- readables: attrs.readables,
2042
+ signals: attrs.signals,
1878
2043
  renderFn: attrs.renderFn,
1879
2044
  appContext: ctx.appContext,
1880
2045
  elementContext: ctx.elementContext
@@ -1950,7 +2115,7 @@ function getRenderHandle(handles) {
1950
2115
  };
1951
2116
  }
1952
2117
  function isRenderable(value) {
1953
- return value == null || value === false || typeof value === "string" || typeof value === "number" || isMarkup(value) || isReadable(value) || isArrayOf(isRenderable, value);
2118
+ return value == null || value === false || typeof value === "string" || typeof value === "number" || isMarkup(value) || isSignal(value) || isArrayOf(isRenderable, value);
1954
2119
  }
1955
2120
 
1956
2121
  // src/store.ts
@@ -2010,17 +2175,26 @@ function initStore(config) {
2010
2175
  crash(error) {
2011
2176
  config.appContext.crashCollector.crash({ error, componentName: ctx.name });
2012
2177
  },
2013
- observe(...args) {
2014
- const callback = args.pop();
2015
- const readables = args.flat();
2178
+ watch(signals, callback) {
2016
2179
  if (isConnected) {
2017
- const stop = observe(readables, callback);
2180
+ const stop = watch(signals, callback);
2018
2181
  stopObserverCallbacks.push(stop);
2182
+ return stop;
2019
2183
  } else {
2184
+ let stop;
2185
+ let stopped = false;
2020
2186
  connectedCallbacks.push(() => {
2021
- const stop = observe(readables, callback);
2022
- stopObserverCallbacks.push(stop);
2187
+ if (!stopped) {
2188
+ stop = watch(signals, callback);
2189
+ stopObserverCallbacks.push(stop);
2190
+ }
2023
2191
  });
2192
+ return function() {
2193
+ if (stop != null) {
2194
+ stopped = true;
2195
+ stop();
2196
+ }
2197
+ };
2024
2198
  }
2025
2199
  }
2026
2200
  };
@@ -2087,27 +2261,27 @@ function initStore(config) {
2087
2261
  // src/stores/document.ts
2088
2262
  function DocumentStore(ctx) {
2089
2263
  ctx.name = "dolla/document";
2090
- const $$title = $$(document.title);
2091
- const $$visibility = $$(document.visibilityState);
2092
- const $$orientation = $$("landscape");
2093
- const $$colorScheme = $$("light");
2094
- ctx.observe($$title, (current) => {
2264
+ const [$title, setTitle] = signal(document.title);
2265
+ const [$visibility, setVisibility] = signal(document.visibilityState);
2266
+ const [$orientation, setOrientation] = signal("landscape");
2267
+ const [$colorScheme, setColorScheme] = signal("light");
2268
+ ctx.watch([$title], (current) => {
2095
2269
  document.title = current;
2096
2270
  });
2097
2271
  const onVisibilityChange = () => {
2098
- $$visibility.set(document.visibilityState);
2272
+ setVisibility(document.visibilityState);
2099
2273
  };
2100
2274
  const onFocus = () => {
2101
- $$visibility.set("visible");
2275
+ setVisibility("visible");
2102
2276
  };
2103
2277
  const landscapeQuery = window.matchMedia("(orientation: landscape)");
2104
2278
  function onOrientationChange(e) {
2105
- $$orientation.set(e.matches ? "landscape" : "portrait");
2279
+ setOrientation(e.matches ? "landscape" : "portrait");
2106
2280
  }
2107
2281
  onOrientationChange(landscapeQuery);
2108
2282
  const colorSchemeQuery = window.matchMedia("(prefers-color-scheme: dark)");
2109
2283
  function onColorChange(e) {
2110
- $$colorScheme.set(e.matches ? "dark" : "light");
2284
+ setColorScheme(e.matches ? "dark" : "light");
2111
2285
  }
2112
2286
  onColorChange(colorSchemeQuery);
2113
2287
  ctx.onConnected(function() {
@@ -2123,10 +2297,11 @@ function DocumentStore(ctx) {
2123
2297
  window.removeEventListener("focus", onFocus);
2124
2298
  });
2125
2299
  return {
2126
- $$title,
2127
- $visibility: $($$visibility),
2128
- $orientation: $($$orientation),
2129
- $colorScheme: $($$colorScheme)
2300
+ $title,
2301
+ setTitle,
2302
+ $visibility,
2303
+ $orientation,
2304
+ $colorScheme
2130
2305
  };
2131
2306
  }
2132
2307
 
@@ -3255,11 +3430,11 @@ function RouterStore(ctx) {
3255
3430
  ctx.onConnected(() => {
3256
3431
  ctx.info("Routes registered:", routes);
3257
3432
  });
3258
- const $$pattern = $$(null);
3259
- const $$path = $$("");
3260
- const $$params = $$({});
3261
- const $$query = $$(parseQueryParams(window.location.search));
3262
- ctx.observe($$query, (current) => {
3433
+ const [$pattern, setPattern] = signal(null);
3434
+ const [$path, setPath] = signal("");
3435
+ const [$params, setParams] = signal({});
3436
+ const [$query, setQuery] = signal(parseQueryParams(window.location.search));
3437
+ ctx.watch([$query], (current) => {
3263
3438
  const params = new URLSearchParams();
3264
3439
  for (const key in current) {
3265
3440
  params.set(key, String(current[key]));
@@ -3290,13 +3465,13 @@ function RouterStore(ctx) {
3290
3465
  const onRouteChange = async ({ location }) => {
3291
3466
  if (location.search !== lastQuery) {
3292
3467
  lastQuery = location.search;
3293
- $$query.set(parseQueryParams(location.search));
3468
+ setQuery(parseQueryParams(location.search));
3294
3469
  }
3295
3470
  const matched = matchRoutes(routes, location.pathname);
3296
3471
  if (!matched) {
3297
- $$pattern.set(null);
3298
- $$path.set(location.pathname);
3299
- $$params.set({
3472
+ setPattern(null);
3473
+ setPath(location.pathname);
3474
+ setParams({
3300
3475
  wildcard: location.pathname
3301
3476
  });
3302
3477
  return;
@@ -3365,10 +3540,10 @@ function RouterStore(ctx) {
3365
3540
  throw new TypeError(`Redirect must either be a path string or a function.`);
3366
3541
  }
3367
3542
  } else {
3368
- $$path.set(matched.path);
3369
- $$params.set(matched.params);
3370
- if (matched.pattern !== $$pattern.get()) {
3371
- $$pattern.set(matched.pattern);
3543
+ setPath(matched.path);
3544
+ setParams(matched.params);
3545
+ if (matched.pattern !== $pattern.get()) {
3546
+ setPattern(matched.pattern);
3372
3547
  const layers = matched.meta.layers;
3373
3548
  for (let i = 0; i < layers.length; i++) {
3374
3549
  const matchedLayer = layers[i];
@@ -3415,19 +3590,20 @@ function RouterStore(ctx) {
3415
3590
  /**
3416
3591
  * The currently matched route pattern, if any.
3417
3592
  */
3418
- $pattern: $($$pattern),
3593
+ $pattern,
3419
3594
  /**
3420
3595
  * The current URL path.
3421
3596
  */
3422
- $path: $($$path),
3597
+ $path,
3423
3598
  /**
3424
3599
  * The current named path params.
3425
3600
  */
3426
- $params: $($$params),
3601
+ $params,
3427
3602
  /**
3428
3603
  * The current query params. Changes to this object will be reflected in the URL.
3429
3604
  */
3430
- $$query,
3605
+ $query,
3606
+ setQuery,
3431
3607
  /**
3432
3608
  * Navigate backward. Pass a number of steps to hit the back button that many times.
3433
3609
  */
@@ -3541,10 +3717,10 @@ function LanguageStore(ctx) {
3541
3717
  }
3542
3718
  return cache.get(config.name);
3543
3719
  }
3544
- const $$isLoaded = $$(false);
3545
- const $$language = $$();
3546
- const $$translation = $$();
3547
- const $noLanguageValue = $("[NO LANGUAGE SET]");
3720
+ const [$loaded, setLoaded] = signal(false);
3721
+ const [$language, _setLanguage] = signal();
3722
+ const [$translation, setTranslation] = signal();
3723
+ const [$noLanguageValue] = signal("[NO LANGUAGE SET]");
3548
3724
  const translationCache = [];
3549
3725
  function getCached(key, values) {
3550
3726
  for (const entry of translationCache) {
@@ -3597,8 +3773,8 @@ function LanguageStore(ctx) {
3597
3773
  const lang = languages.get(realTag);
3598
3774
  try {
3599
3775
  const translation = await getTranslation(lang);
3600
- $$translation.set(translation);
3601
- $$language.set(realTag);
3776
+ setTranslation(translation);
3777
+ _setLanguage(realTag);
3602
3778
  ctx.info("set language to " + realTag);
3603
3779
  } catch (error) {
3604
3780
  if (error instanceof Error) {
@@ -3607,11 +3783,11 @@ function LanguageStore(ctx) {
3607
3783
  }
3608
3784
  }
3609
3785
  setLanguage(ctx.options.defaultLanguage ?? "auto").then(() => {
3610
- $$isLoaded.set(true);
3786
+ setLoaded(true);
3611
3787
  });
3612
3788
  return {
3613
3789
  loaded: new Promise((resolve2, reject) => {
3614
- const stop = observe($$isLoaded, (isLoaded) => {
3790
+ const stop = $loaded.watch((isLoaded) => {
3615
3791
  if (isLoaded) {
3616
3792
  setTimeout(() => {
3617
3793
  stop();
@@ -3620,8 +3796,8 @@ function LanguageStore(ctx) {
3620
3796
  }
3621
3797
  });
3622
3798
  }),
3623
- $isLoaded: $($$isLoaded),
3624
- $currentLanguage: $($$language),
3799
+ $isLoaded: $loaded,
3800
+ $currentLanguage: $language,
3625
3801
  supportedLanguages: [...languages.keys()],
3626
3802
  setLanguage,
3627
3803
  /**
@@ -3631,7 +3807,7 @@ function LanguageStore(ctx) {
3631
3807
  * @param values - A map of {{placeholder}} names and the values to replace them with.
3632
3808
  */
3633
3809
  translate(key, values) {
3634
- if (!$$language.get()) {
3810
+ if (!$language.get()) {
3635
3811
  return $noLanguageValue;
3636
3812
  }
3637
3813
  const cached = getCached(key, values);
@@ -3639,16 +3815,16 @@ function LanguageStore(ctx) {
3639
3815
  return cached;
3640
3816
  }
3641
3817
  if (values) {
3642
- const readableValues = {};
3818
+ const signalValues = {};
3643
3819
  for (const [key2, value] of Object.entries(values)) {
3644
- if (isReadable(value)) {
3645
- readableValues[key2] = value;
3820
+ if (isSignal(value)) {
3821
+ signalValues[key2] = value;
3646
3822
  }
3647
3823
  }
3648
- const readableEntries = Object.entries(readableValues);
3824
+ const readableEntries = Object.entries(signalValues);
3649
3825
  if (readableEntries.length > 0) {
3650
3826
  const readables = readableEntries.map((x) => x[1]);
3651
- const $merged = $([$$translation, ...readables], (t, ...entryValues) => {
3827
+ const $merged = derive([$translation, ...readables], (t, ...entryValues) => {
3652
3828
  const entries = entryValues.map((_, i) => readableEntries[i]);
3653
3829
  const mergedValues = {
3654
3830
  ...values
@@ -3664,7 +3840,7 @@ function LanguageStore(ctx) {
3664
3840
  return $merged;
3665
3841
  }
3666
3842
  }
3667
- const $replaced = $($$translation, (t) => {
3843
+ const $replaced = derive([$translation], (t) => {
3668
3844
  let result = resolve(t, key) || `[NO TRANSLATION: ${key}]`;
3669
3845
  if (values) {
3670
3846
  result = replaceMustaches(result, values);
@@ -3869,7 +4045,7 @@ function DialogStore(ctx) {
3869
4045
  container.style.bottom = "0";
3870
4046
  container.style.left = "0";
3871
4047
  container.style.zIndex = "99999";
3872
- const $$dialogs = $$([]);
4048
+ const [$dialogs, setDialogs] = signal([]);
3873
4049
  let activeDialogs = [];
3874
4050
  function dialogChangedCallback() {
3875
4051
  if (activeDialogs.length > 0) {
@@ -3882,7 +4058,7 @@ function DialogStore(ctx) {
3882
4058
  }
3883
4059
  }
3884
4060
  }
3885
- ctx.observe($$dialogs, (dialogs) => {
4061
+ ctx.watch([$dialogs], (dialogs) => {
3886
4062
  render.update(() => {
3887
4063
  let removed = [];
3888
4064
  let added = [];
@@ -3924,7 +4100,7 @@ function DialogStore(ctx) {
3924
4100
  }
3925
4101
  });
3926
4102
  function open(view, props) {
3927
- const $$open = $$(true);
4103
+ const $$open = signal.settable(true);
3928
4104
  let dialog;
3929
4105
  let transitionInCallback;
3930
4106
  let transitionOutCallback;
@@ -3934,12 +4110,14 @@ function DialogStore(ctx) {
3934
4110
  elementContext,
3935
4111
  props: {
3936
4112
  ...props,
3937
- $$open,
3938
- transitionIn: (callback) => {
3939
- transitionInCallback = callback;
3940
- },
3941
- transitionOut: (callback) => {
3942
- transitionOutCallback = callback;
4113
+ dialog: {
4114
+ $$open,
4115
+ transitionIn: (callback) => {
4116
+ transitionInCallback = callback;
4117
+ },
4118
+ transitionOut: (callback) => {
4119
+ transitionOutCallback = callback;
4120
+ }
3943
4121
  }
3944
4122
  }
3945
4123
  });
@@ -3953,16 +4131,16 @@ function DialogStore(ctx) {
3953
4131
  return transitionOutCallback;
3954
4132
  }
3955
4133
  };
3956
- $$dialogs.update((current) => {
4134
+ setDialogs((current) => {
3957
4135
  return [...current, dialog];
3958
4136
  });
3959
- const stopObserver = observe($$open, (value) => {
4137
+ const stopObserver = $$open.watch((value) => {
3960
4138
  if (!value) {
3961
4139
  closeDialog();
3962
4140
  }
3963
4141
  });
3964
4142
  function closeDialog() {
3965
- $$dialogs.update((current) => {
4143
+ setDialogs((current) => {
3966
4144
  return current.filter((x) => x !== dialog);
3967
4145
  });
3968
4146
  dialog = void 0;
@@ -3975,8 +4153,6 @@ function DialogStore(ctx) {
3975
4153
  };
3976
4154
  }
3977
4155
  export {
3978
- $,
3979
- $$,
3980
4156
  App,
3981
4157
  DialogStore,
3982
4158
  Fragment,
@@ -3985,12 +4161,17 @@ export {
3985
4161
  RouterStore,
3986
4162
  StoreScope,
3987
4163
  cond,
3988
- isReadable,
3989
- isWritable,
4164
+ derive,
4165
+ designalify,
4166
+ isRef,
4167
+ isSettableSignal,
4168
+ isSignal,
3990
4169
  m,
3991
- observe,
3992
4170
  portal,
4171
+ ref,
3993
4172
  repeat,
3994
- unwrap
4173
+ signal,
4174
+ signalify,
4175
+ watch
3995
4176
  };
3996
4177
  //# sourceMappingURL=index.js.map