Skip to content

Commit

Permalink
The Cell
Browse files Browse the repository at this point in the history
  • Loading branch information
NullVoxPopuli committed Jan 19, 2025
1 parent c0b20b6 commit 7b9e4b7
Showing 1 changed file with 42 additions and 2 deletions.
44 changes: 42 additions & 2 deletions text/1071-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ interface Cell<Value> extends Reactive<Value> {
/**
* Utility to create a Cell without the caller using the `new` keyword.
*/
static create<T>(initialValue: T): Cell<T>;
static create<T>(initialValue: T, equals?: (a: T, b: T) => boolean): Cell<T>;

/**
* The constructor takes an optional initial value and optional equals function.
*/
constructor(initialValue?: Value, equals?: (a: Value, b: Value) => boolean): {}

/**
* Function short-hand of updating the current value
Expand All @@ -105,6 +110,41 @@ interface Cell<Value> extends Reactive<Value> {
}
```

Behaviorally, the `Cell` behaves almost the same as this function:
```js
class CellPolyfill {
@tracked current;
#isFrozen = false;

constructor(initialValue) {
this.current = initialValue;
}

read() {
return this.current;
}

set(value) {
assert(`Cannot set a frozen Cell`, !this.#isFrozen);
this.current = value;
}

update(updater) {
assert(`Cannot update a frozen Cell`, !this.#isFrozen);
this.set(updater(this.read()));
}

freeze() {
this.#isFrozen = true;
}
}
```

The key difference is that with a primitive, we expose a new way for developers to decide when their value becomes dirty.
The above example, and the default value, would use the "always dirty" behavior of `() => false`.

This default value allows the `Cell` to be the backing implementation if `@tracked`, as `@tracked` values do not have equalty checking to decide when to become dirty.


### Usage

Expand Down Expand Up @@ -230,7 +270,7 @@ We can even use the example over-simplified implementation of `@tracked` from th

## Alternatives

- don't do it, we have tracked storage (tho, it is not implemented at the time of writing this RFC)
- Have the cell's equality function check value-equality of primitives, rather than _always_ dirty. This may mean that folks apps could subtly break if we changed the `@tracked` implementation. But we could maybe provide a different tracked implementation from a different import, if we want to pursue this equality checking without breaking folks existing apps.

## Unresolved questions

Expand Down

0 comments on commit 7b9e4b7

Please sign in to comment.