native-document 1.0.251 → 1.0.252

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-document",
3
- "version": "1.0.251",
3
+ "version": "1.0.252",
4
4
  "description": "A reactive JavaScript framework that preserves native DOM simplicity without sacrificing modern features",
5
5
  "author": "AfroCodeur <https://github.com/afrocodeur>",
6
6
  "license": "MIT",
@@ -678,6 +678,60 @@ ObservableItem.prototype.sync = function(targetObservable) {
678
678
  };
679
679
  };
680
680
 
681
+ /**
682
+ * Subscribes to the observable and re-runs the callback whenever the value changes.
683
+ * The callback can mutate $currentValue directly or return a new value to set.
684
+ * A lock prevents re-entrant calls caused by mutations inside the callback.
685
+ *
686
+ * @param {(current: *, operations: *) => *|void} fn - Callback receiving the current value and
687
+ * the triggering operation. If a value is returned, it is applied via .set().
688
+ * If nothing is returned, no set is performed.
689
+ * @param {boolean} [autoCall=true] - If true, the callback is called immediately upon registration.
690
+ * @returns {this}
691
+ *
692
+ * @example
693
+ * // Mutate directly
694
+ * $items.watch((current) => {
695
+ * if(!current.find(i => i.day === 'mon')) {
696
+ * current.push({ day: 'mon', enabled: false });
697
+ * }
698
+ * });
699
+ *
700
+ * @example
701
+ * // Return a new value
702
+ * $items.watch((current) => {
703
+ * return DAYS.map(day =>
704
+ * current.find(i => i.day === day) ?? { day, enabled: false }
705
+ * );
706
+ * });
707
+ *
708
+ * @example
709
+ * // Disable auto-call
710
+ * $items.watch((current) => { ... }, false);
711
+ */
712
+ ObservableItem.prototype.watch = function(fn, autoCall = true) {
713
+ let locked = false;
714
+
715
+ const handler = (value, prev, operations) => {
716
+ if(locked) return;
717
+ locked = true;
718
+ try {
719
+ const result = fn(this.$currentValue, operations);
720
+ if(result !== undefined) {
721
+ this.set(result);
722
+ }
723
+ }
724
+ finally {
725
+ locked = false;
726
+ }
727
+ };
728
+
729
+ this.subscribe(handler);
730
+ autoCall && handler(this.$currentValue, null, null);
731
+
732
+ return this;
733
+ };
734
+
681
735
 
682
736
  ObservableItem.prototype.fnSet = function(value) {
683
737
  return () => this.set(value);
@@ -90,6 +90,8 @@ export interface ObservableItem<T = any> {
90
90
  get(key: string | number): any;
91
91
  when(value: T): ObservableWhen<T>;
92
92
 
93
+ watch(fn: (current: this['$currentValue'], operations: ObservableOperation | null) => typeof this['$currentValue'] | void, autoCall?: boolean): this;
94
+
93
95
  persist(key: string, options?: {
94
96
  get?: (value: any) => T;
95
97
  set?: (value: T) => any;