@adbl/cells 0.0.10 → 0.0.11

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.
@@ -166,7 +166,7 @@ export class Cell {
166
166
  #effects = [];
167
167
 
168
168
  /**
169
- * @type {Array<[WeakRef<DerivedCell<any>>, () => any]>}
169
+ * @type {Array<WeakRef<DerivedCell<any>>>}
170
170
  */
171
171
  #derivedCells = [];
172
172
 
@@ -176,7 +176,7 @@ export class Cell {
176
176
  */
177
177
  get derivedCells() {
178
178
  // @ts-ignore
179
- return this.#derivedCells.map((cell) => cell[0].deref()).filter(Boolean);
179
+ return this.#derivedCells.map((cell) => cell.deref()).filter(Boolean);
180
180
  }
181
181
 
182
182
  /**
@@ -222,14 +222,11 @@ export class Cell {
222
222
 
223
223
  if (currentlyComputedValue !== undefined) {
224
224
  const isAlreadySubscribed = this.#derivedCells.some(
225
- (ref) => ref[0].deref() === currentlyComputedValue[0]
225
+ (ref) => ref.deref() === currentlyComputedValue
226
226
  );
227
227
  if (isAlreadySubscribed) return this.wvalue;
228
228
 
229
- this.#derivedCells.push([
230
- new WeakRef(currentlyComputedValue[0]),
231
- currentlyComputedValue[1],
232
- ]);
229
+ this.#derivedCells.push(new WeakRef(currentlyComputedValue));
233
230
  }
234
231
 
235
232
  return this.wvalue;
@@ -401,11 +398,11 @@ export class Cell {
401
398
  effect(this.wvalue);
402
399
  }
403
400
 
404
- const deref = dependent[0].deref();
401
+ const deref = dependent.deref();
405
402
  if (deref === undefined) continue;
406
403
 
407
404
  const computedCell = deref;
408
- const computedFn = dependent[1];
405
+ const computedFn = deref.computedFn;
409
406
 
410
407
  if (root.batchNestingLevel > 0) {
411
408
  root.batchedEffects.set(
@@ -422,9 +419,7 @@ export class Cell {
422
419
  }
423
420
  }
424
421
  // Periodically drop dead references.
425
- this.#derivedCells = this.#derivedCells.filter(
426
- (ref) => ref[0].deref() !== undefined
427
- );
422
+ this.#derivedCells = this.#derivedCells.filter((ref) => ref.deref());
428
423
 
429
424
  // global effects
430
425
  for (const [options, effect] of root.globalPostEffects) {
@@ -555,12 +550,14 @@ export class Cell {
555
550
  static derived = (callback) => new DerivedCell(callback);
556
551
 
557
552
  /**
553
+ * @template X
558
554
  * Batches all the effects created to run only once.
559
- * @param {() => void} callback - The function to be executed in a batched manner.
555
+ * @param {() => X} callback - The function to be executed in a batched manner.
556
+ * @returns {X} The return value of the callback.
560
557
  */
561
558
  static batch = (callback) => {
562
559
  root.batchNestingLevel++;
563
- callback();
560
+ const value = callback();
564
561
  root.batchNestingLevel--;
565
562
  if (root.batchNestingLevel === 0) {
566
563
  for (const [effect, args] of root.batchedEffects) {
@@ -568,6 +565,7 @@ export class Cell {
568
565
  }
569
566
  root.batchedEffects = new Map();
570
567
  }
568
+ return value;
571
569
  };
572
570
 
573
571
  /**
@@ -650,19 +648,22 @@ export class Cell {
650
648
  pending.value = true;
651
649
  error.value = null;
652
650
  data.value = null;
653
- try {
654
- initialInput = input;
655
- const result = await getter(/** @type {X} */ (input));
656
- data.value = result;
657
- } catch (e) {
658
- if (e instanceof Error) {
659
- error.value = e;
660
- } else {
661
- throw e;
651
+
652
+ await Cell.batch(async () => {
653
+ try {
654
+ initialInput = input;
655
+ const result = await getter(/** @type {X} */ (input));
656
+ data.value = result;
657
+ } catch (e) {
658
+ if (e instanceof Error) {
659
+ error.value = e;
660
+ } else {
661
+ throw e;
662
+ }
663
+ } finally {
664
+ pending.value = false;
662
665
  }
663
- } finally {
664
- pending.value = false;
665
- }
666
+ });
666
667
  }
667
668
 
668
669
  /**
@@ -673,6 +674,7 @@ export class Cell {
673
674
  if (changeLoadingState) {
674
675
  pending.value = true;
675
676
  }
677
+
676
678
  try {
677
679
  const result = await getter(
678
680
  /** @type {X} */ (newInput ?? initialInput)
@@ -715,14 +717,18 @@ export class DerivedCell extends Cell {
715
717
  super();
716
718
  // Ensures that the cell is derived every time the computing function is called.
717
719
  const derivationWrapper = () => {
718
- activeComputedValues.push([this, derivationWrapper]);
720
+ activeComputedValues.push(this);
719
721
  const value = computedFn();
720
722
  activeComputedValues.pop();
721
723
  return value;
722
724
  };
723
725
  this.setValue(derivationWrapper());
726
+ this.computedFn = computedFn;
724
727
  }
725
728
 
729
+ /** @type {() => T} */
730
+ computedFn;
731
+
726
732
  /**
727
733
  * @readonly
728
734
  */
@@ -822,6 +828,8 @@ export class SourceCell extends Cell {
822
828
  this.setValue(this.#proxy(value));
823
829
  if (typeof value === 'object' && value !== null) {
824
830
  this.#originalObject = value;
831
+ } else {
832
+ this.#originalObject = undefined;
825
833
  }
826
834
  this.update();
827
835
  }
package/library/root.js CHANGED
@@ -39,6 +39,6 @@ export const root = {
39
39
  /**
40
40
  * A value representing the computed values that are currently being calculated.
41
41
  * It is an array so it can keep track of nested computed values.
42
- * @type {[DerivedCell, () => any][]}
42
+ * @type {DerivedCell[]}
43
43
  */
44
44
  export const activeComputedValues = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adbl/cells",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "A simple implementation of reactive updates for JavaScript",
5
5
  "main": "index.js",
6
6
  "private": false,
@@ -90,10 +90,12 @@ export class Cell<T extends unknown> {
90
90
  */
91
91
  static derived: <T_2>(callback: () => T_2) => DerivedCell<T_2>;
92
92
  /**
93
+ * @template X
93
94
  * Batches all the effects created to run only once.
94
- * @param {() => void} callback - The function to be executed in a batched manner.
95
+ * @param {() => X} callback - The function to be executed in a batched manner.
96
+ * @returns {X} The return value of the callback.
95
97
  */
96
- static batch: (callback: () => void) => void;
98
+ static batch: <X>(callback: () => X) => X;
97
99
  /**
98
100
  * Checks if the provided value is an instance of the Cell class.
99
101
  * @template [T=any]
@@ -140,7 +142,7 @@ export class Cell<T extends unknown> {
140
142
  *
141
143
  * run('input');
142
144
  */
143
- static async<X, Y>(getter: (input: X) => Promise<Y>): AsyncRequestAtoms<X, Y>;
145
+ static async<X_1, Y>(getter: (input: X_1) => Promise<Y>): AsyncRequestAtoms<X_1, Y>;
144
146
  /**
145
147
  * @readonly
146
148
  * @returns {Array<DerivedCell<any>>}
@@ -224,6 +226,8 @@ export class DerivedCell<T extends unknown> extends Cell<T> {
224
226
  * @param {() => T} computedFn - A function that generates the value of the computed.
225
227
  */
226
228
  constructor(computedFn: () => T);
229
+ /** @type {() => T} */
230
+ computedFn: () => T;
227
231
  /**
228
232
  * @readonly
229
233
  */
@@ -7,9 +7,9 @@ export namespace root {
7
7
  /**
8
8
  * A value representing the computed values that are currently being calculated.
9
9
  * It is an array so it can keep track of nested computed values.
10
- * @type {[DerivedCell, () => any][]}
10
+ * @type {DerivedCell[]}
11
11
  */
12
- export const activeComputedValues: [import("./classes.js").DerivedCell<any>, () => any][];
12
+ export const activeComputedValues: import("./classes.js").DerivedCell<any>[];
13
13
  export type Watchable = import('./classes.js').Cell<any>;
14
14
  export type DerivedCell = import('./classes.js').DerivedCell<any>;
15
15
  export type GlobalEffectOptions = {