Skip to content

Commit f8269af

Browse files
authored
Chore: Document Cell interface difference between system-use and spell-use (#502)
1 parent 793b453 commit f8269af

File tree

1 file changed

+52
-20
lines changed
  • typescript/packages/common-runner/src

1 file changed

+52
-20
lines changed

typescript/packages/common-runner/src/cell.ts

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { Space } from "./space.ts";
2727
* This abstracts away the paths behind an interface that e.g. the UX code or
2828
* modules that prefer cell interfaces can use.
2929
*
30+
* These methods are available in the system and in spell code:
31+
*
3032
* @method get Returns the current value of the cell.
3133
* @returns {T}
3234
*
@@ -35,35 +37,69 @@ import { Space } from "./space.ts";
3537
* @param {T} value - The new value to set.
3638
* @returns {void}
3739
*
40+
* @method update Updates multiple properties of an object cell at once.
41+
* @param {Partial<T>} values - The properties to update.
42+
* @returns {void}
43+
*
44+
* @method push Adds an item to the end of an array cell.
45+
* @param {U | DocImpl<U> | DocLink} value - The value to add, where U is the
46+
* array element type.
47+
* @returns {void}
48+
*
49+
* @method equals Compares two cells for equality.
50+
* @param {Cell<any>} other - The cell to compare with.
51+
* @returns {boolean}
52+
*
3853
* @method key Returns a new cell for the specified key path.
3954
* @param {K} valueKey - The key to access in the cell's value.
4055
* @returns {Cell<T[K]>}
4156
*
57+
* Everything below is only available in the system, not in spell code:
58+
*
59+
* @method asSchema Creates a new cell with a specific schema.
60+
* @param {JSONSchema} schema - The schema to apply.
61+
* @returns {Cell<T>} - A cell with the specified schema.
62+
*
63+
* @method withLog Creates a new cell with a specific reactivity log.
64+
* @param {ReactivityLog} log - The log to use.
65+
* @returns {Cell<T>}
66+
*
4267
* @method sink Adds a callback that is called immediately and on cell changes.
4368
* @param {function} callback - The callback to be called when the cell changes.
4469
* @returns {function} - A function to Cleanup the callback.
4570
*
46-
* @method getAsProxy Returns a value proxy for the cell.
47-
* @param {Path} path - The path to follow.
71+
* @method getAsQueryResult Returns a query result for the cell.
72+
* @param {Path} path - The optional path to follow.
73+
* @param {ReactivityLog} log - Optional reactivity log.
4874
* @returns {QueryResult<DeepKeyLookup<T, Path>>}
4975
*
50-
* @method getAsCellReference Returns a cell reference for the cell.
76+
* @method getAsDocLink Returns a document link for the cell.
5177
* @returns {DocLink}
5278
*
53-
* @method toJSON Returns a JSON pointer to the cell (not the contents!).
54-
* @returns {{"/": string}}
79+
* @method getSourceCell Returns the source cell with optional schema.
80+
* @param {JSONSchema} schema - Optional schema to apply.
81+
* @returns {Cell<T & {[TYPE]: string | undefined} & {argument: any}>}
82+
*
83+
* @method toJSON Returns a serializable doclink (not the contents) to the cell.
84+
* @returns {{cell: {"/": string} | undefined, path: PropertyKey[]}}
5585
*
5686
* @method value Returns the current value of the cell.
5787
* @returns {T}
5888
*
59-
* @method entityId Returns the current entity ID of the cell.
89+
* @property docLink The document link representing this cell.
90+
* @returns {DocLink}
91+
*
92+
* @property entityId Returns the current entity ID of the cell.
6093
* @returns {EntityId | undefined}
94+
*
95+
* @property schema Optional schema for the cell.
96+
* @returns {JSONSchema | undefined}
6197
*/
6298
export interface Cell<T> {
6399
get(): T;
64100
set(value: T): void;
65101
send(value: T): void;
66-
update(value: Partial<T>): void;
102+
update(values: Partial<T>): void;
67103
push(
68104
value:
69105
| (T extends Array<infer U> ? U : any)
@@ -248,7 +284,6 @@ function createRegularCell<T>(
248284
const self = {
249285
get: () => validateAndTransform(doc, path, schema, log, rootSchema),
250286
set: (newValue: T) => {
251-
// TODO(seefeld): This doesn't respect aliases on write. Should it?
252287
const ref = resolvePath(doc, path, log);
253288
if (
254289
prepareForSaving(
@@ -267,21 +302,18 @@ function createRegularCell<T>(
267302
}
268303
},
269304
send: (newValue: T) => self.set(newValue),
270-
update: (value: Partial<T>) => {
271-
// TODO(seefeld): This doesn't respect aliases on write. Should it?
272-
const ref = resolvePath(doc, path, log);
273-
const previousValue = ref.cell.getAtPath(ref.path);
274-
if (typeof previousValue !== "object" || previousValue === null) {
275-
throw new Error("Can't update non-object value");
305+
update: (values: Partial<T>) => {
306+
if (typeof values !== "object" || values === null) {
307+
throw new Error("Can't update with non-object value");
308+
}
309+
for (const [key, value] of Object.entries(values)) {
310+
self.key(key as keyof T).set(value as T[keyof T]);
276311
}
277-
const newValue = {
278-
...previousValue,
279-
...value,
280-
};
281-
ref.cell.setAtPath(ref.path, newValue, log);
282312
},
283313
push: (value: any) => {
284-
const ref = resolvePath(doc, path, log);
314+
// Follow aliases and references, since we want to get to an assumed
315+
// existing array.
316+
const ref = resolveLinkToValue(doc, path, log);
285317
const array = ref.cell.getAtPath(ref.path) ?? [];
286318
if (!Array.isArray(array)) {
287319
throw new Error("Can't push into non-array value");

0 commit comments

Comments
 (0)