From d785fb57699c47b74d720de7fc9de4f9a15919bc Mon Sep 17 00:00:00 2001 From: xaviergonz Date: Mon, 24 Feb 2025 00:48:19 +0100 Subject: [PATCH] add auto key generation in snapshot if missing --- packages/mobx-bonsai/src/node/nodeTypeKey.ts | 15 +++++++++++++-- packages/mobx-bonsai/test/node/node.test.ts | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/mobx-bonsai/src/node/nodeTypeKey.ts b/packages/mobx-bonsai/src/node/nodeTypeKey.ts index 0fea08d..46022ae 100644 --- a/packages/mobx-bonsai/src/node/nodeTypeKey.ts +++ b/packages/mobx-bonsai/src/node/nodeTypeKey.ts @@ -4,6 +4,7 @@ import { Dispose, disposeOnce } from "../utils/disposeOnce" import { assertIsNode, node } from "./node" import mitt from "mitt" import { IsNever, MarkOptional } from "ts-essentials" +import { getGlobalConfig } from "../globalConfig" /** * A unique key indicating the type of a node. This constant is used internally to identify node types. @@ -139,7 +140,7 @@ export interface NodeType): TNode + snapshot(data: MarkOptional): TNode /** * Retrieves the key associated with the given node. @@ -310,10 +311,20 @@ export function nodeType( }>() const snapshot = (data: MarkOptional) => { - return { + const sn = { ...data, [nodeTypeKey]: type, } as TNode + + // generate key if missing + if (nodeTypeObj.key !== undefined) { + const key = nodeTypeObj.getKey(sn) + if (key === undefined) { + ;(sn as any)[nodeTypeObj.key] = getGlobalConfig().keyGenerator() + } + } + + return sn } const nodeTypeObj: NodeType = (data: MarkOptional) => { diff --git a/packages/mobx-bonsai/test/node/node.test.ts b/packages/mobx-bonsai/test/node/node.test.ts index 3977426..8611979 100644 --- a/packages/mobx-bonsai/test/node/node.test.ts +++ b/packages/mobx-bonsai/test/node/node.test.ts @@ -256,3 +256,14 @@ it("setting a plain value of an existing unique node should result in a single r configure({ enforceActions: "always" }) } }) + +test("auto generates key if missing in snapshot", () => { + type Todo = TNode<"todo", { id: string; title: string }> + using tTodo = nodeType("todo").with({ key: "id" }) + + const node = tTodo.snapshot({ + title: "Test Todo", + // id is omitted intentionally + }) + expect(node.id).toBe("id-1") +})