@qilin-agent/util-values 0.0.0-stage → 3.1.4
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/LICENSE +21 -0
- package/README.i18n.yaml +43 -0
- package/README.md +94 -2
- package/README.zh.md +95 -0
- package/lib/index.js +923 -0
- package/lib/types/index.d.ts +78 -0
- package/lib/types/partial-json.d.ts +152 -0
- package/package.json +35 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kkutysllb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/util/values/README.md
|
|
5
|
+
/:
|
|
6
|
+
en: 6b543e93639271ad
|
|
7
|
+
zh: 397ce501111fc943
|
|
8
|
+
/qilin-agent-util-values:
|
|
9
|
+
en: dd2d4cd10fc42b58
|
|
10
|
+
zh: 42bf12c8e68b6f29
|
|
11
|
+
/qilin-agent-util-values/summary:
|
|
12
|
+
en: 680945f1c3345b16
|
|
13
|
+
zh: 9edf47099221fb65
|
|
14
|
+
/qilin-agent-util-values/table-of-contents:
|
|
15
|
+
en: 80b31a934611cb4a
|
|
16
|
+
zh: 05f3f7f9cb2fd881
|
|
17
|
+
/qilin-agent-util-values/use-this-package:
|
|
18
|
+
en: bbff250eba0f1b89
|
|
19
|
+
zh: 0a618f05cc88ee2b
|
|
20
|
+
/qilin-agent-util-values/use-this-package/validate-or-snapshot-json-data:
|
|
21
|
+
en: dc6de9f27cc98557
|
|
22
|
+
zh: 9c2bac179e536147
|
|
23
|
+
/qilin-agent-util-values/use-this-package/publish-compare-or-retain-keyed-values:
|
|
24
|
+
en: 13628af2abe3eea6
|
|
25
|
+
zh: e284bb8d3ebe38ea
|
|
26
|
+
/qilin-agent-util-values/use-this-package/close-a-discriminated-union:
|
|
27
|
+
en: f21b7bd8040a72eb
|
|
28
|
+
zh: 19548d3e537c0b5b
|
|
29
|
+
/qilin-agent-util-values/understand-the-implementation:
|
|
30
|
+
en: 997cf0e584054ace
|
|
31
|
+
zh: 5e71d64eb1e32ddd
|
|
32
|
+
/qilin-agent-util-values/understand-the-implementation/source-map:
|
|
33
|
+
en: ac05d5b0dfbf5471
|
|
34
|
+
zh: b81d399f2a7e884b
|
|
35
|
+
/qilin-agent-util-values/further-exploration:
|
|
36
|
+
en: 9119d622a41477a4
|
|
37
|
+
zh: 5acf565eac8e813d
|
|
38
|
+
/qilin-agent-util-values/known-limitations-and-deferred-work:
|
|
39
|
+
en: dc3626bb369e1230
|
|
40
|
+
zh: e292836d13ee512c
|
|
41
|
+
/qilin-agent-util-values/known-limitations-and-deferred-work/dev-note:
|
|
42
|
+
en: e67f633dc6fe7773
|
|
43
|
+
zh: 3bb0c20c93f16f98
|
package/README.md
CHANGED
|
@@ -1,3 +1,95 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "Lossless JSON validation, detached snapshots, deep freezing, structural equality, and exhaustive-union helpers for runtime packages."
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @qilin-agent/util-values
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`qilin-util-values` gives runtime packages one implementation for lossless JSON values, immutable object graphs, structural JSON equality, and exhaustive closed-union failures. Callers can validate untrusted values, detach a JSON snapshot, freeze a published value, compare JSON-compatible data, or terminate an unreachable branch without importing a capability package. The helpers hold no shared registry, constructor identity, or mutable module state.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
20
|
+
- [Dev Note](#dev-note)
|
|
21
|
+
|
|
22
|
+
-----
|
|
23
|
+
|
|
24
|
+
<a id="use-this-package"></a>
|
|
25
|
+
## Use this package
|
|
26
|
+
|
|
27
|
+
### Validate or snapshot JSON data
|
|
28
|
+
|
|
29
|
+
Use `isJsonValue()` for a predicate and `snapshotJsonValue()` when the caller also needs a detached copy. Both accept only lossless JSON roots: `null`, booleans, finite numbers other than negative zero, strings, dense intrinsic arrays, and plain or null-prototype records with enumerable string keys. Cycles, sparse arrays, symbol or non-enumerable own properties, functions, and class instances are rejected.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { isJsonValue, snapshotJsonValue, type JsonValue } from '@qilin-agent/util-values'
|
|
33
|
+
|
|
34
|
+
declare const input: unknown
|
|
35
|
+
|
|
36
|
+
if (!isJsonValue(input)) throw new TypeError('expected lossless JSON')
|
|
37
|
+
const snapshot = snapshotJsonValue(input) as JsonValue
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Publish, compare, or retain keyed values
|
|
41
|
+
|
|
42
|
+
`deepFreeze(value)` freezes an object graph in place and returns the same value. It walks enumerable string-keyed children and deliberately leaves live `AbortSignal` objects mutable. `deepEqualJson(a, b)` compares JSON-compatible arrays and records structurally; callers must validate hostile or unconstrained values before comparison.
|
|
43
|
+
|
|
44
|
+
`WeakMapWithValues<Key, Value>` combines weak object-key lookup with a strongly retained, insertion-ordered `values` set. Each value belongs to one key. The owner must call `delete(key)` or `clear()` at the corresponding lifecycle boundary; the collection does not perform automatic cleanup.
|
|
45
|
+
|
|
46
|
+
### Close a discriminated union
|
|
47
|
+
|
|
48
|
+
Use `assertNever(value, context?)` in the default branch of a closed discriminated union. A newly added variant then fails TypeScript compilation at every exhaustive switch, while a runtime value that escaped its declared type throws with the optional context label.
|
|
49
|
+
|
|
50
|
+
-----
|
|
51
|
+
|
|
52
|
+
<a id="understand-the-implementation"></a>
|
|
53
|
+
## Understand the implementation
|
|
54
|
+
|
|
55
|
+
<details>
|
|
56
|
+
<summary>Implementation internals — click to expand</summary>
|
|
57
|
+
|
|
58
|
+
The JSON validator uses an explicit work stack and tracks only the active ancestor chain, so deeply nested values do not consume the JavaScript call stack and repeated non-cyclic references remain valid. Snapshot writes use own data properties, including for names such as `__proto__`. Value operations derive their result only from their arguments; `WeakMapWithValues` stores only instance-owned associations.
|
|
59
|
+
|
|
60
|
+
### Source map
|
|
61
|
+
|
|
62
|
+
| File | Role |
|
|
63
|
+
|---|---|
|
|
64
|
+
| [`src/index.ts`](src/index.ts) | JSON value type, validation and snapshot traversal, structural equality, deep freezing, weak-key/strong-value associations, and exhaustive-union failure |
|
|
65
|
+
|
|
66
|
+
</details>
|
|
67
|
+
|
|
68
|
+
-----
|
|
69
|
+
|
|
70
|
+
<a id="further-exploration"></a>
|
|
71
|
+
## Further Exploration
|
|
72
|
+
|
|
73
|
+
- [Utility package map](../README.md) — adjacent stateless helpers.
|
|
74
|
+
- [Session subsystem](../../../docs/subsystems/session.md) — durable events that require lossless JSON.
|
|
75
|
+
- [Tools subsystem](../../../docs/subsystems/tools.md) — schema validation and canonical tool results built on `JsonValue`.
|
|
76
|
+
|
|
77
|
+
-----
|
|
78
|
+
|
|
79
|
+
## Known Limitations and Deferred Work
|
|
80
|
+
|
|
81
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
82
|
+
|
|
83
|
+
- **`deepEqualJson` assumes JSON-compatible inputs** — it is not a general object comparator and does not define semantics for prototypes, symbols, accessors, cycles, maps, or sets.
|
|
84
|
+
- **`deepFreeze` follows enumerable string-keyed children** — it does not turn arbitrary host objects into immutable data, and it intentionally skips live `AbortSignal` instances.
|
|
85
|
+
- **`WeakMapWithValues` requires explicit cleanup and unique values** — values remain strongly held until their owning key is deleted or the collection is cleared, and one value must not be shared by several keys.
|
|
86
|
+
|
|
87
|
+
<a id="dev-note"></a>
|
|
88
|
+
### Dev Note
|
|
89
|
+
|
|
90
|
+
<details>
|
|
91
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
92
|
+
|
|
93
|
+
None.
|
|
94
|
+
|
|
95
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "供运行时包使用的无损 JSON 校验、分离式快照、深度冻结、结构相等与穷尽联合类型辅助函数。"
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @qilin-agent/util-values
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`qilin-util-values` 为运行时包提供统一的无损 JSON 值、不可变对象图、JSON 结构相等和封闭联合类型穷尽失败实现。调用方可以校验不受信任的值、创建分离的 JSON 快照、冻结待发布值、比较 JSON 兼容数据,或终止不可达分支,而无需导入某个能力包。这些 helper 不持有共享注册表、constructor identity 或可变模块状态。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
20
|
+
- [开发备注](#dev-note)
|
|
21
|
+
|
|
22
|
+
-----
|
|
23
|
+
|
|
24
|
+
<a id="use-this-package"></a>
|
|
25
|
+
## 使用本包
|
|
26
|
+
|
|
27
|
+
### 校验 JSON 数据或创建快照
|
|
28
|
+
|
|
29
|
+
需要 predicate 时使用 `isJsonValue()`,还需要分离副本时使用 `snapshotJsonValue()`。两者只接受无损 JSON 根值:`null`、布尔值、除负零外的有限数字、字符串、稠密的内建数组,以及只含可枚举字符串键的普通或 null-prototype 记录。循环、稀疏数组、自有 symbol 属性或自有不可枚举属性、函数和 class 实例都会被拒绝。
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { isJsonValue, snapshotJsonValue, type JsonValue } from '@qilin-agent/util-values'
|
|
33
|
+
|
|
34
|
+
declare const input: unknown
|
|
35
|
+
|
|
36
|
+
if (!isJsonValue(input)) throw new TypeError('expected lossless JSON')
|
|
37
|
+
const snapshot = snapshotJsonValue(input) as JsonValue
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 发布、比较或保留键控值
|
|
41
|
+
|
|
42
|
+
`deepFreeze(value)` 原地冻结对象图并返回同一个值。它遍历可枚举字符串键的子项,并刻意让活跃 `AbortSignal` 对象保持可变。`deepEqualJson(a, b)` 按结构比较 JSON 兼容数组与记录;调用方必须先校验恶意或不受约束的值,再进行比较。
|
|
43
|
+
|
|
44
|
+
`WeakMapWithValues<Key, Value>` 组合弱对象键查找与强引用且保持插入顺序的 `values` set。每个 value 只属于一个 key。owner 必须在对应生命周期边界调用 `delete(key)` 或 `clear()`;该集合不执行自动清理。
|
|
45
|
+
|
|
46
|
+
### 封闭可辨识联合类型
|
|
47
|
+
|
|
48
|
+
在封闭可辨识联合类型的 default 分支中使用 `assertNever(value, context?)`。新增变体会让每个穷尽 switch 在 TypeScript 编译时失败;如果某个运行时值逃过了声明类型,该函数会抛出带可选上下文标签的错误。
|
|
49
|
+
|
|
50
|
+
-----
|
|
51
|
+
|
|
52
|
+
<a id="understand-the-implementation"></a>
|
|
53
|
+
## 理解实现
|
|
54
|
+
|
|
55
|
+
<details>
|
|
56
|
+
<summary>实现细节——点击展开</summary>
|
|
57
|
+
|
|
58
|
+
JSON 校验器使用显式工作栈,并只跟踪当前祖先链,因此深层嵌套值不会消耗 JavaScript 调用栈,重复但无循环的引用仍然有效。快照写入使用自有数据属性,包括 `__proto__` 等名称。值操作的结果只取决于传入参数;`WeakMapWithValues` 仅保存实例自有的关联。
|
|
59
|
+
|
|
60
|
+
### 源码地图
|
|
61
|
+
|
|
62
|
+
| 文件 | 职责 |
|
|
63
|
+
|---|---|
|
|
64
|
+
| [`src/index.ts`](src/index.ts) | JSON 值类型、校验与快照遍历、结构相等、深度冻结、弱键/强值关联和穷尽联合类型失败 |
|
|
65
|
+
|
|
66
|
+
</details>
|
|
67
|
+
|
|
68
|
+
-----
|
|
69
|
+
|
|
70
|
+
<a id="further-exploration"></a>
|
|
71
|
+
## 进一步探索
|
|
72
|
+
|
|
73
|
+
- [工具包映射](../README.zh.md)——相邻的无状态 helper。
|
|
74
|
+
- [会话子系统](../../../docs/subsystems/session.zh.md)——要求无损 JSON 的持久事件。
|
|
75
|
+
- [工具子系统](../../../docs/subsystems/tools.zh.md)——构建于 `JsonValue` 之上的 schema 校验与规范工具结果。
|
|
76
|
+
|
|
77
|
+
-----
|
|
78
|
+
|
|
79
|
+
## 已知限制与延期工作
|
|
80
|
+
|
|
81
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
82
|
+
|
|
83
|
+
- **`deepEqualJson` 假定输入兼容 JSON**——它不是通用对象比较器,不为 prototype、symbol、accessor、循环、map 或 set 定义语义。
|
|
84
|
+
- **`deepFreeze` 沿可枚举字符串键遍历子项**——它不会把任意宿主对象变成不可变数据,并会刻意跳过活跃 `AbortSignal` 实例。
|
|
85
|
+
- **`WeakMapWithValues` 要求显式清理且 value 唯一**——value 会保持强引用,直到 owner 删除其 key 或清空集合;同一 value 不得由多个 key 共享。
|
|
86
|
+
|
|
87
|
+
<a id="dev-note"></a>
|
|
88
|
+
### 开发备注
|
|
89
|
+
|
|
90
|
+
<details>
|
|
91
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
92
|
+
|
|
93
|
+
无。
|
|
94
|
+
|
|
95
|
+
</details>
|