Skip to content

Commit

Permalink
add global configuration for node key generation and update clone fun…
Browse files Browse the repository at this point in the history
…ction to use it
  • Loading branch information
xaviergonz committed Feb 23, 2025
1 parent 1670c0b commit 3804c00
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
37 changes: 37 additions & 0 deletions packages/mobx-bonsai/src/globalConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { NodeKeyGenerator, defaultNodeKeyGenerator } from "./node/utils/nodeKeyGenerator"

/**
* Global config object.
*/
export interface GlobalConfig {
/**
* Node key generator function.
*/
keyGenerator: NodeKeyGenerator
}

// defaults
let globalConfig: GlobalConfig = {
keyGenerator: defaultNodeKeyGenerator,
}

/**
* Partially sets the current global config.
*
* @param config Partial object with the new configurations. Options not included in the object won't be changed.
*/
export function setGlobalConfig(config: Partial<GlobalConfig>) {
globalConfig = Object.freeze({
...globalConfig,
...config,
})
}

/**
* Returns the current global config object.
*
* @returns
*/
export function getGlobalConfig(): Readonly<GlobalConfig> {
return globalConfig
}
18 changes: 7 additions & 11 deletions packages/mobx-bonsai/src/node/clone.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { failure } from "../error/failure"
import { getGlobalConfig } from "../globalConfig"
import { isPlainObject, isPrimitive } from "../plainTypes/checks"
import { node } from "./node"
import { getNodeTypeAndKey } from "./nodeTypeKey"
import { getSnapshot } from "./snapshot/getSnapshot"
import { NodeKeyGenerator, defaultNodeKeyGenerator } from "./utils/nodeKeyGenerator"

function deepSubstituteNodeKeys<T>(value: T, nodeKeyGenerator: NodeKeyGenerator): T {
function deepSubstituteNodeKeys<T>(value: T): T {
if (isPrimitive(value)) {
return value
}

if (Array.isArray(value)) {
return value.map((v) => deepSubstituteNodeKeys(v, nodeKeyGenerator)) as T
return value.map((v) => deepSubstituteNodeKeys(v)) as T
}

if (isPlainObject(value)) {
Expand All @@ -21,9 +21,9 @@ function deepSubstituteNodeKeys<T>(value: T, nodeKeyGenerator: NodeKeyGenerator)
const newValue: any = {}
for (const key in value) {
if (key === keyProp) {
newValue[key] = nodeKeyGenerator()
newValue[key] = getGlobalConfig().keyGenerator()
} else {
newValue[key] = deepSubstituteNodeKeys(value[key], nodeKeyGenerator)
newValue[key] = deepSubstituteNodeKeys(value[key])
}
}
return newValue
Expand All @@ -36,14 +36,10 @@ function deepSubstituteNodeKeys<T>(value: T, nodeKeyGenerator: NodeKeyGenerator)
* Clones a node. It will generate new node keys deeply.
*
* @param nodeToClone Node to clone.
* @param nodeKeyGenerator Optional node key generator.
* @returns The cloned node.
*/
export function clone<T extends object>(
nodeToClone: T,
nodeKeyGenerator = defaultNodeKeyGenerator
): T {
const snapshotWithChangedKeys = deepSubstituteNodeKeys(getSnapshot(nodeToClone), nodeKeyGenerator)
export function clone<T extends object>(nodeToClone: T): T {
const snapshotWithChangedKeys = deepSubstituteNodeKeys(getSnapshot(nodeToClone))

return node(snapshotWithChangedKeys)
}
13 changes: 13 additions & 0 deletions packages/mobx-bonsai/test/commonSetup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
import { configure } from "mobx"
import { setGlobalConfig } from "../src/globalConfig"

configure({ enforceActions: "always" })

let id = 1

setGlobalConfig({
keyGenerator() {
return `id-${id++}`
},
})

beforeEach(() => {
id = 1
})

0 comments on commit 3804c00

Please sign in to comment.