Skip to content

Commit 70a7227

Browse files
authored
feat(runner): add resolveAsCell() method to Cell API (#1916)
feat(runner): add `resolveAsCell()` method to Cell API Adds a new `resolveAsCell()` method that resolves a cell reference to the actual cell it points to. This is useful when accessing data via .key() and wanting a direct reference to the final underlying document, e.g. to create an id for it. The method is equivalent to wrapping the current schema in `Cell<>` and calling `.get()`, providing a more convenient API for this common pattern. Includes test coverage for resolving nested cell references.
1 parent cfec7f7 commit 70a7227

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

packages/api/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface Cell<T = any> {
2626
push(...value: T extends (infer U)[] ? U[] : never): void;
2727
equals(other: Cell<any>): boolean;
2828
key<K extends keyof T>(valueKey: K): Cell<T[K]>;
29+
resolveAsCell(): Cell<T>;
2930
}
3031

3132
// Cell type with only public methods

packages/runner/src/cell.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ import { ContextualFlowControl } from "./cfc.ts";
7373
* @returns {void}
7474
*
7575
* @method push Adds an item to the end of an array cell.
76-
* @param {U | Cell<U>} value - The value to add, where U is
77-
* the array element type.
76+
* @param {U | Cell<U>} value - The value to add, where U is the array element
77+
* type.
7878
* @returns {void}
7979
*
8080
* @method equals Compares two cells for equality.
@@ -102,6 +102,10 @@ import { ContextualFlowControl } from "./cfc.ts";
102102
* @method sync Syncs the cell to the storage.
103103
* @returns {Promise<void>}
104104
*
105+
* @method resolveAsCell Resolves the cell to a new cell with the resolved link.
106+
* Equivalent to `cell.getAsSchema(<current schema wrapped in Cell<>).get()`
107+
* @returns {Cell<T>}
108+
*
105109
* @method getAsQueryResult Returns a query result for the cell.
106110
* @param {Path} path - The optional path to follow.
107111
* @param {ReactivityLog} log - Optional reactivity log.
@@ -197,6 +201,7 @@ declare module "@commontools/api" {
197201
withTx(tx?: IExtendedStorageTransaction): Cell<T>;
198202
sink(callback: (value: Readonly<T>) => Cancel | undefined | void): Cancel;
199203
sync(): Promise<Cell<T>> | Cell<T>;
204+
resolveAsCell(): Cell<T>;
200205
getAsQueryResult<Path extends PropertyKey[]>(
201206
path?: Readonly<Path>,
202207
tx?: IExtendedStorageTransaction,
@@ -646,6 +651,11 @@ export class RegularCell<T> implements Cell<T> {
646651
return this.runtime.storageManager.syncCell<T>(this);
647652
}
648653

654+
resolveAsCell(): Cell<T> {
655+
const link = resolveLink(this.runtime.readTx(this.tx), this.link);
656+
return createCell(this.runtime, link, this.tx, true, this.synced);
657+
}
658+
649659
getAsQueryResult<Path extends PropertyKey[]>(
650660
path?: Readonly<Path>,
651661
tx?: IExtendedStorageTransaction,

packages/runner/test/cell.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,4 +3642,33 @@ describe("Cell success callbacks", () => {
36423642
expect(link0.id).not.toBe(link1.id);
36433643
});
36443644
});
3645+
3646+
describe("resolveAsCell", () => {
3647+
it("should resolve a cell reference to the actual cell", () => {
3648+
const innerCell = runtime.getCell<number>(
3649+
space,
3650+
"inner-cell",
3651+
{ type: "number" },
3652+
tx,
3653+
);
3654+
innerCell.set(42);
3655+
3656+
const outerCell = runtime.getCell<{ inner: unknown }>(
3657+
space,
3658+
"outer-cell",
3659+
{
3660+
type: "object",
3661+
properties: {
3662+
inner: { type: "number" },
3663+
},
3664+
},
3665+
tx,
3666+
);
3667+
outerCell.set({ inner: innerCell });
3668+
3669+
const resolvedCell = outerCell.key("inner").resolveAsCell();
3670+
3671+
expect(resolvedCell.equals(innerCell)).toBe(true);
3672+
});
3673+
});
36453674
});

packages/static/assets/types/commontools.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface Cell<T = any> {
1717
push(...value: T extends (infer U)[] ? U[] : never): void;
1818
equals(other: Cell<any>): boolean;
1919
key<K extends keyof T>(valueKey: K): Cell<T[K]>;
20+
resolveAsCell(): Cell<T>;
2021
}
2122
export interface Stream<T> {
2223
send(event: T): void;

0 commit comments

Comments
 (0)