@oh-my-pi/pi-utils 18.4.1 → 18.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/types/index.d.ts +12 -0
- package/package.json +2 -2
- package/src/index.ts +39 -0
package/CHANGELOG.md
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -43,3 +43,15 @@ export * from "./version.js";
|
|
|
43
43
|
export * from "./which.js";
|
|
44
44
|
export * from "./yaml-config.js";
|
|
45
45
|
export declare function structuredCloneJSON<T>(value: T): T;
|
|
46
|
+
/**
|
|
47
|
+
* Deep-copies a JSON-shaped tree (arrays and plain or null-prototype objects)
|
|
48
|
+
* so later mutation of the source can never reach the copy. Strings and other
|
|
49
|
+
* primitives are immutable and shared, so the cost is O(containers) instead of
|
|
50
|
+
* `structuredClone`'s O(bytes) — the difference matters for hot paths that
|
|
51
|
+
* re-copy large string payloads (e.g. streamed tool-call arguments) per delta.
|
|
52
|
+
*
|
|
53
|
+
* Copies own enumerable string keys only. Any other object (class instance,
|
|
54
|
+
* Date, Map, inherited-prototype object) is copied with {@link structuredCloneJSON}.
|
|
55
|
+
* Not cycle-safe: callers MUST pass acyclic data, as any JSON-serializable value is.
|
|
56
|
+
*/
|
|
57
|
+
export declare function cloneJsonTree<T>(value: T): T;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-utils",
|
|
3
|
-
"version": "18.4.
|
|
3
|
+
"version": "18.4.2",
|
|
4
4
|
"description": "Shared utilities for pi packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@oh-my-pi/pi-natives": "18.4.
|
|
60
|
+
"@oh-my-pi/pi-natives": "18.4.2"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/bun": "^1.3.14"
|
package/src/index.ts
CHANGED
|
@@ -63,3 +63,42 @@ export function structuredCloneJSON<T>(value: T): T {
|
|
|
63
63
|
}
|
|
64
64
|
return JSON.parse(JSON.stringify(value)) as T;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Deep-copies a JSON-shaped tree (arrays and plain or null-prototype objects)
|
|
69
|
+
* so later mutation of the source can never reach the copy. Strings and other
|
|
70
|
+
* primitives are immutable and shared, so the cost is O(containers) instead of
|
|
71
|
+
* `structuredClone`'s O(bytes) — the difference matters for hot paths that
|
|
72
|
+
* re-copy large string payloads (e.g. streamed tool-call arguments) per delta.
|
|
73
|
+
*
|
|
74
|
+
* Copies own enumerable string keys only. Any other object (class instance,
|
|
75
|
+
* Date, Map, inherited-prototype object) is copied with {@link structuredCloneJSON}.
|
|
76
|
+
* Not cycle-safe: callers MUST pass acyclic data, as any JSON-serializable value is.
|
|
77
|
+
*/
|
|
78
|
+
export function cloneJsonTree<T>(value: T): T {
|
|
79
|
+
return cloneJsonNode(value) as T;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isJsonRecord(value: object): value is Record<string, unknown> {
|
|
83
|
+
const proto = Object.getPrototypeOf(value);
|
|
84
|
+
return proto === Object.prototype || proto === null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function cloneJsonNode(value: unknown): unknown {
|
|
88
|
+
if (value === null || typeof value !== "object") return value;
|
|
89
|
+
if (Array.isArray(value)) return value.map(cloneJsonNode);
|
|
90
|
+
if (!isJsonRecord(value)) return structuredCloneJSON(value);
|
|
91
|
+
const out: Record<string, unknown> = {};
|
|
92
|
+
for (const key in value) {
|
|
93
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
94
|
+
const child = cloneJsonNode(value[key]);
|
|
95
|
+
// Assigning `__proto__` would swap the copy's prototype instead of
|
|
96
|
+
// creating the own data property JSON.parse produces.
|
|
97
|
+
if (key === "__proto__") {
|
|
98
|
+
Object.defineProperty(out, key, { value: child, enumerable: true, writable: true, configurable: true });
|
|
99
|
+
} else {
|
|
100
|
+
out[key] = child;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|