fix(schema-form): extract the clone-spine walk and drop the unused ui-primitives dependency

This commit is contained in:
Yichen Jiang
2026-07-30 10:40:43 +08:00
parent 0d96676f35
commit ebff7db11e
4 changed files with 31 additions and 35 deletions
-1
View File
@@ -20,7 +20,6 @@
},
"license": "BSD-3-Clause",
"dependencies": {
"@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
"react": "^18.2.0",
"schemastery": "^3.18.0"
},
+31 -28
View File
@@ -117,7 +117,13 @@ export function getPath(value: unknown, path: readonly string[]): unknown {
return current
}
/** Whether a draft explicitly carries the path (its presence marks a user override). */
/**
* Whether a draft explicitly carries the path (its presence marks a user
* override, independent of the value stored there).
* @param value - root value (draft or fallback layer).
* @param path - key path from the root; array indexes as strings.
* @returns whether the path's final key exists on its parent.
*/
export function hasPath(value: unknown, path: readonly string[]): boolean {
if (path.length === 0) return value !== undefined
const parent = getPath(value, path.slice(0, -1))
@@ -134,15 +140,12 @@ function cloneContainer(container: unknown, key: string): Record<string, unknown
return /^\d+$/.test(key) ? [] : {}
}
/**
* Immutably set a nested value, materializing missing intermediate containers.
* @param root - draft root (never mutated).
* @param path - non-empty key path.
* @param value - value to store at the path.
* @returns the new draft root.
*/
export function setPath(root: Record<string, unknown>, path: readonly string[], value: unknown): Record<string, unknown> {
if (path.length === 0) throw new Error('schema-form: setPath needs a non-empty path')
/** Clone the container spine down to the leaf's parent, materializing missing intermediates. */
function cloneSpine(root: Record<string, unknown>, path: readonly string[]): {
result: Record<string, unknown>
parent: Record<string, unknown> | unknown[]
leaf: string
} {
const result = { ...root }
let target: Record<string, unknown> | unknown[] = result
for (let i = 0; i < path.length - 1; i++) {
@@ -155,9 +158,21 @@ export function setPath(root: Record<string, unknown>, path: readonly string[],
else (target)[key] = child
target = child
}
const leaf = path[path.length - 1] as string
if (Array.isArray(target)) target[Number(leaf)] = value
else (target)[leaf] = value
return { result, parent: target, leaf: path[path.length - 1] as string }
}
/**
* Immutably set a nested value, materializing missing intermediate containers.
* @param root - draft root (never mutated).
* @param path - non-empty key path.
* @param value - value to store at the path.
* @returns the new draft root.
*/
export function setPath(root: Record<string, unknown>, path: readonly string[], value: unknown): Record<string, unknown> {
if (path.length === 0) throw new Error('schema-form: setPath needs a non-empty path')
const { result, parent, leaf } = cloneSpine(root, path)
if (Array.isArray(parent)) parent[Number(leaf)] = value
else parent[leaf] = value
return result
}
@@ -172,20 +187,8 @@ export function setPath(root: Record<string, unknown>, path: readonly string[],
export function deletePath(root: Record<string, unknown>, path: readonly string[]): Record<string, unknown> {
if (path.length === 0) throw new Error('schema-form: deletePath needs a non-empty path')
if (!hasPath(root, path)) return root
const result = { ...root }
let target: Record<string, unknown> | unknown[] = result
for (let i = 0; i < path.length - 1; i++) {
const key = path[i] as string
const child = cloneContainer(
Array.isArray(target) ? target[Number(key)] : (target)[key],
path[i + 1] as string,
)
if (Array.isArray(target)) target[Number(key)] = child
else (target)[key] = child
target = child
}
const leaf = path[path.length - 1] as string
if (Array.isArray(target)) target.splice(Number(leaf), 1)
else Reflect.deleteProperty(target, leaf)
const { result, parent, leaf } = cloneSpine(root, path)
if (Array.isArray(parent)) parent.splice(Number(leaf), 1)
else Reflect.deleteProperty(parent, leaf)
return result
}
@@ -8,9 +8,6 @@
"src"
],
"references": [
{
"path": "../ui-primitives"
},
{
"path": "../../../vendor/schemastery"
},
-3
View File
@@ -956,9 +956,6 @@ importers:
packages/client/schema-form:
dependencies:
'@deepseek-ai/dsh-client-ui-primitives':
specifier: workspace:^
version: link:../ui-primitives
react:
specifier: ^18.2.0
version: 18.3.1