@calcit/procs 0.13.59 → 0.13.61
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/.yarn/install-state.gz +0 -0
- package/RFCs/08-29-snapshot-symbol-keys-and-tag-match-deprecation-rfc.md +39 -0
- package/RFCs/README.md +2 -1
- package/build.rs +26 -4
- package/editing-history/202608291043-tag-match-snapshot-symbol-keys.md +27 -0
- package/editing-history/202608291125-purge-events-on-async-cancel.md +18 -0
- package/editing-history/202608291143-preserve-terminal-on-cancel-purge.md +17 -0
- package/editing-history/202608291202-release-0.13.60.md +5 -0
- package/editing-history/202608291249-host-capability-boundary.md +6 -0
- package/editing-history/202608291811-snapshot-mutation-version-guard.md +24 -0
- package/editing-history/202608291814-caps-manifest-argument-order.md +3 -0
- package/editing-history/202608291822-quote-mutation-guard-path.md +3 -0
- package/editing-history/202608291827-release-0.13.61.md +3 -0
- package/lib/package.json +1 -1
- package/package.json +1 -1
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Snapshot Symbol Keys and `tag-match` Deprecation RFC
|
|
2
|
+
|
|
3
|
+
Status: Implemented / 已实现
|
|
4
|
+
|
|
5
|
+
## 中文
|
|
6
|
+
|
|
7
|
+
### 背景
|
|
8
|
+
|
|
9
|
+
Architecture 文件已经用 Symbol 表示 definition FQN,而 `calcit.cirru` 的 `:files` 与 `:defs` key 仍由 formatter 写成 String。两套持久化表示增加了工具转换成本,也使“标识符”和“普通文本”的语义边界不一致。与此同时,宏 `tag-match` 会在展开后丢失原生 enum 分支结构,不利于穷尽性、payload arity、类型推断及后端优化;原生 `match` 已具备替代条件。
|
|
10
|
+
|
|
11
|
+
### 决策
|
|
12
|
+
|
|
13
|
+
1. Snapshot loader 对 namespace/definition key 同时接受 String 与 Symbol。
|
|
14
|
+
2. Snapshot formatter 和 writer 只输出 Symbol key,形成“宽读、窄写”的单向迁移。
|
|
15
|
+
3. String 与 Symbol 归一化后重名时立即报错,不允许 HashMap 静默覆盖。
|
|
16
|
+
4. runtime、format migration 与 detailed snapshot 读取路径共享同一兼容规则。
|
|
17
|
+
5. `tag-match` 标记普通 `:deprecated`;`analyze deprecated` 会报告调用,`analyze quality` 会把调用计入 `deprecatedCalls`。新代码及迁移代码使用原生 `match`。
|
|
18
|
+
|
|
19
|
+
### 兼容性
|
|
20
|
+
|
|
21
|
+
旧 Snapshot 无需先手工修改即可读取。首次执行 `calcit calcit.cirru edit format` 后会产生标识符 key 的规范化 diff,应单独审阅并提交。新版本写出的 Symbol key 不保证旧 Calcit formatter 可读,因此项目必须先升级工具链再格式化。
|
|
22
|
+
|
|
23
|
+
## English
|
|
24
|
+
|
|
25
|
+
### Context
|
|
26
|
+
|
|
27
|
+
Architecture files already represent definition FQNs as Symbols, while the `calcit.cirru` formatter still writes `:files` and `:defs` keys as Strings. Maintaining two persistent representations adds conversion work and blurs the semantic boundary between identifiers and text. The `tag-match` macro also hides native enum branch structure after expansion, limiting exhaustiveness, payload-arity, type-inference, and backend optimization passes; native `match` now covers its intended use.
|
|
28
|
+
|
|
29
|
+
### Decision
|
|
30
|
+
|
|
31
|
+
1. Snapshot loaders accept both String and Symbol namespace/definition keys.
|
|
32
|
+
2. Snapshot formatters and writers emit only Symbol keys, providing a wide-read/narrow-write migration.
|
|
33
|
+
3. A normalized String/Symbol collision is rejected explicitly instead of being silently overwritten by a HashMap insertion.
|
|
34
|
+
4. Runtime, format-migration, and detailed-snapshot readers share the same compatibility rule.
|
|
35
|
+
5. `tag-match` receives the ordinary `:deprecated` tag. `analyze deprecated` reports calls and `analyze quality` includes them in `deprecatedCalls`. New and migrated code uses native `match`.
|
|
36
|
+
|
|
37
|
+
### Compatibility
|
|
38
|
+
|
|
39
|
+
Legacy Snapshots remain readable without manual edits. The first `calcit calcit.cirru edit format` run produces a canonical identifier-key diff that should be reviewed and committed separately. Because older Calcit formatters are not guaranteed to read newly written Symbol keys, projects must upgrade their toolchain before formatting.
|
package/RFCs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RFC 整理索引
|
|
2
2
|
|
|
3
|
-
更新时间:2026-08-
|
|
3
|
+
更新时间:2026-08-29
|
|
4
4
|
|
|
5
5
|
## 目录原则
|
|
6
6
|
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
| `08-21-static-type-system-evolution-roadmap.md` | Draft | 借鉴 Rust/MoonBit 推进 Unknown/Dynamic 分离、穷尽性、局部推断、trait coherence 与框架类型化。 |
|
|
51
51
|
| `08-23-typed-option-query-ergonomics-rfc.md` | Withdrawn | 生态采用率为零;`get-or` 等六个宏已移除,直接使用查询返回的 `Option` 与 `.unwrap-or`。 |
|
|
52
52
|
| `08-23-option-result-binding-macros-rfc.md` | Partial | 保留已有 Respo 使用的 `option:let`;移除未采用的 `result:let`,Result 链直接使用 `.and-then`。 |
|
|
53
|
+
| `08-29-snapshot-symbol-keys-and-tag-match-deprecation-rfc.md` | Implemented | Snapshot namespace/definition key 宽读 String/Symbol、窄写 Symbol;`tag-match` 普通废弃并迁移到原生 `match`。 |
|
|
53
54
|
|
|
54
55
|
## 已执行的清理
|
|
55
56
|
|
package/build.rs
CHANGED
|
@@ -107,6 +107,26 @@ pub struct Snapshot {
|
|
|
107
107
|
pub files: HashMap<String, FileInSnapShot>,
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
fn parse_snapshot_identifier_key(value: &Edn, owner: &str) -> Result<String, String> {
|
|
111
|
+
match value {
|
|
112
|
+
Edn::Str(text) | Edn::Symbol(text) if !text.is_empty() => Ok(text.to_string()),
|
|
113
|
+
Edn::Str(_) | Edn::Symbol(_) => Err(format!("{owner}: snapshot identifier key cannot be empty")),
|
|
114
|
+
other => Err(format!(
|
|
115
|
+
"{owner}: snapshot identifier key must be a String or Symbol, got {}",
|
|
116
|
+
format_edn_preview(other)
|
|
117
|
+
)),
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
fn insert_snapshot_identifier<T>(target: &mut HashMap<String, T>, name: String, value: T, owner: &str) -> Result<(), String> {
|
|
122
|
+
if target.insert(name.clone(), value).is_some() {
|
|
123
|
+
return Err(format!(
|
|
124
|
+
"{owner}: duplicate snapshot identifier `{name}` after normalizing String/Symbol keys"
|
|
125
|
+
));
|
|
126
|
+
}
|
|
127
|
+
Ok(())
|
|
128
|
+
}
|
|
129
|
+
|
|
110
130
|
fn parse_snapshot_entry(data: Edn) -> Result<SnapshotEntry, String> {
|
|
111
131
|
let map = data.view_map().map_err(|e| format!("entry must be a map: {e}"))?;
|
|
112
132
|
let ns_def = |key: &str| match map.get_or_nil(key) {
|
|
@@ -516,9 +536,10 @@ fn parse_file_in_snapshot(edn: Edn, file_name: &str) -> Result<FileInSnapShot, S
|
|
|
516
536
|
other => return Err(format!("{file_name}: expected `:defs` map, got {}", format_edn_preview(other))),
|
|
517
537
|
};
|
|
518
538
|
for (def_key, def_value) in &map.0 {
|
|
519
|
-
let name
|
|
539
|
+
let name = parse_snapshot_identifier_key(def_key, &format!("{file_name}/:defs"))?;
|
|
520
540
|
let owner = format!("{file_name}/{name}");
|
|
521
|
-
|
|
541
|
+
let entry = parse_code_entry(def_value.clone(), &owner)?;
|
|
542
|
+
insert_snapshot_identifier(&mut defs, name, entry, &format!("{file_name}/:defs"))?;
|
|
522
543
|
}
|
|
523
544
|
}
|
|
524
545
|
_ => {}
|
|
@@ -535,8 +556,9 @@ fn parse_files(edn: Edn) -> Result<HashMap<String, FileInSnapShot>, String> {
|
|
|
535
556
|
Edn::Map(map) => {
|
|
536
557
|
let mut result = HashMap::with_capacity(map.0.len());
|
|
537
558
|
for (key, value) in map.0 {
|
|
538
|
-
let name
|
|
539
|
-
|
|
559
|
+
let name = parse_snapshot_identifier_key(&key, "snapshot/:files")?;
|
|
560
|
+
let file = parse_file_in_snapshot(value, &name)?;
|
|
561
|
+
insert_snapshot_identifier(&mut result, name, file, "snapshot/:files")?;
|
|
540
562
|
}
|
|
541
563
|
Ok(result)
|
|
542
564
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# `tag-match` deprecation and Snapshot Symbol identifier keys
|
|
2
|
+
|
|
3
|
+
## 中文概要
|
|
4
|
+
|
|
5
|
+
- 将 `calcit.core/tag-match` 标记为普通 `:deprecated`,迁移说明指向原生 `match`;废弃调用继续进入 `analyze deprecated` 与 quality 的 `deprecatedCalls`。
|
|
6
|
+
- 将 core 内 18 个 Option/Result、collection destructuring 与 IO helper 的实际调用迁移到 `match`,并同步迁移相关 examples 和 definition-attached tests;core deprecated 分析归零。
|
|
7
|
+
- 为保留的兼容宏补充 validated pattern-list 类型断言,使专门的 legacy runtime test 不产生类型告警。
|
|
8
|
+
- Snapshot runtime、format migration、detailed snapshot 和 build-script reader 对 `:files` namespace key、`:defs` definition key 同时接受旧 String 与新 Symbol。
|
|
9
|
+
- Snapshot writer 只输出 Symbol identifier key;String/Symbol 归一化重名时明确报错,避免 HashMap 静默覆盖。
|
|
10
|
+
- core Snapshot 经新版 writer 完成 Symbol key 规范化;build.rs 同步支持该格式。
|
|
11
|
+
|
|
12
|
+
## English summary
|
|
13
|
+
|
|
14
|
+
- Marked `calcit.core/tag-match` with the ordinary `:deprecated` tag and directed migration to native `match`; calls remain part of deprecated analysis and the quality `deprecatedCalls` budget.
|
|
15
|
+
- Migrated 18 real core Option/Result, collection-destructuring, and IO-helper call sites to `match`, including related examples and definition-attached tests; core deprecated analysis now reports zero calls.
|
|
16
|
+
- Added validated pattern-list type assertions inside the retained compatibility macro so its dedicated legacy runtime test remains warning-free.
|
|
17
|
+
- Made runtime, format-migration, detailed-snapshot, and build-script readers accept both legacy String and canonical Symbol namespace/definition keys.
|
|
18
|
+
- Made Snapshot writers emit only Symbol identifier keys and reject normalized String/Symbol collisions instead of silently overwriting entries.
|
|
19
|
+
- Canonicalized the bundled core Snapshot to Symbol keys and updated `build.rs` to consume the format.
|
|
20
|
+
|
|
21
|
+
## Verification notes
|
|
22
|
+
|
|
23
|
+
- Rust library tests: 580 passed.
|
|
24
|
+
- Core attached tests: 223 passed.
|
|
25
|
+
- `analyze deprecated --deps`: 0 core calls after migration.
|
|
26
|
+
- Temporary legacy-String Snapshot formatted to Symbol keys and reloaded through `query context`.
|
|
27
|
+
- Full Rust, strict clippy, JS/IR/WASM, and Agent interface checks passed before commit/PR.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Async cancellation must purge accepted Emit events
|
|
2
|
+
|
|
3
|
+
When a Calcit callback cancels its own native async task, later Emit events may
|
|
4
|
+
already have been detached from the shared queue into the same host drain
|
|
5
|
+
batch. Moving the registry handle to Closing blocks new producer events, but a
|
|
6
|
+
queue-only purge cannot see that detached batch.
|
|
7
|
+
|
|
8
|
+
The cancellation path now purges events still held by the queue immediately
|
|
9
|
+
after `begin_close`. Drain also treats an Emit observed after the task entered
|
|
10
|
+
Closing as cancellation cleanup: it is discarded without a lifecycle error.
|
|
11
|
+
This is safe because the registry cannot reserve an Emit sequence after
|
|
12
|
+
Closing. Reserved Complete/Fail events remain deliverable for exactly-once
|
|
13
|
+
termination.
|
|
14
|
+
|
|
15
|
+
当 Calcit callback 在同一轮 drain 中取消 native async task 时,后续 Emit 可能
|
|
16
|
+
已经随 batch 从共享队列取出,普通 queue purge 无法再看到它们。取消流程现在会在
|
|
17
|
+
`begin_close` 后立即清理队列;drain 遇到 Closing task 的 Emit 时将其视为取消清理,
|
|
18
|
+
静默 discard,而 terminal 事件仍利用预留容量完成 exactly-once 收尾。
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Preserve queued terminal events during cancellation purge
|
|
2
|
+
|
|
3
|
+
Review identified that a task may already have queued Complete/Fail behind an
|
|
4
|
+
earlier Emit when the Emit callback requests cancellation. Purging every event
|
|
5
|
+
would remove that terminal while the registry still remembers its terminal
|
|
6
|
+
claim, leaving the task stuck in Closing.
|
|
7
|
+
|
|
8
|
+
Cancellation now performs a selective Emit-only purge. Queue metadata removes
|
|
9
|
+
the same event sequences and bytes while preserving any queued terminal and
|
|
10
|
+
its exactly-once claim. Tests cover an Emit and Complete already queued before
|
|
11
|
+
cancel, verify only the Emit is purged, and drain the preserved terminal to a
|
|
12
|
+
finished task.
|
|
13
|
+
|
|
14
|
+
review 指出取消发生时 Complete/Fail 可能已经排在较早 Emit 后面。全量 purge 会
|
|
15
|
+
删除 terminal,却保留 registry 的 terminal claim,导致 task 永久停在 Closing。
|
|
16
|
+
现在取消只按 sequence 清理 Emit,并同步更新 bytes 与 purged metrics;测试覆盖
|
|
17
|
+
取消前 Emit 与 Complete 已同时入队,确认 terminal 被保留并正常完成。
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Release 0.13.60
|
|
2
|
+
|
|
3
|
+
- Bumped the Rust crate and npm package versions together from `0.13.59` to `0.13.60`.
|
|
4
|
+
- This release includes canonical snapshot identifier keys and corrected async FFI task cancellation: queued `Emit` events are purged without dropping terminal completion or failure events.
|
|
5
|
+
- The async cancellation change prevents stale callback delivery while preserving deterministic task teardown for native modules.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Host capability ownership boundary
|
|
2
|
+
|
|
3
|
+
- Added the architecture rule that separates Calcit core, pure/typed libraries, host adapters, `calcit_native_ffi`, and macros.
|
|
4
|
+
- Documented the current native/Node/browser/WASM capability matrix and canonical JSON, `FsPath`, clock, and typed FFI capability surfaces.
|
|
5
|
+
- Defined required backend evidence, explicit unavailable behavior, macro expansion permissions, module migration order, and the review checklist for new effects.
|
|
6
|
+
- Linked the new architecture document from the installation hub and native FFI reference.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Snapshot mutation toolchain guard
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
Calcit 0.13.60 writes canonical symbol keys for Snapshot namespaces and definitions. A globally installed newer CLI could therefore rewrite a project whose `deps.cirru` and CI still pin an older reader, leaving the project unreadable to its declared toolchain.
|
|
6
|
+
|
|
7
|
+
## Change
|
|
8
|
+
|
|
9
|
+
- Added a shared preflight that reads the `deps.cirru` adjacent to the selected Snapshot.
|
|
10
|
+
- Snapshot-writing `edit`, `tree`, `config`, and cursor operations now reject an exact `:calcit-version` mismatch before loading or writing the target file.
|
|
11
|
+
- Read-only commands, dry-runs, cursor navigation, projects without `deps.cirru`, and legacy manifests without `:calcit-version` remain usable.
|
|
12
|
+
- Invalid non-string or non-semver declarations fail with a manifest-specific diagnostic.
|
|
13
|
+
- The failure explains both safe paths: use the pinned Calcit release, or explicitly upgrade the project with `caps <deps-file> upgrade --all`.
|
|
14
|
+
|
|
15
|
+
## Verification
|
|
16
|
+
|
|
17
|
+
- Unit coverage for matching, absent, mismatched, and invalid declarations.
|
|
18
|
+
- Real-project smoke confirmed `config show` remains readable while `edit format` is blocked without changing the Snapshot hash.
|
|
19
|
+
- `cargo fmt --check`
|
|
20
|
+
- `cargo clippy --all-targets -- -D warnings`
|
|
21
|
+
- `cargo test`
|
|
22
|
+
- `yarn compile`
|
|
23
|
+
- `yarn check-agent-interface` (17/17)
|
|
24
|
+
- `yarn check-all` (Calcit core 223/223, JS/IR/WASM and performance checks)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Preserve `caps` manifest argument order in mutation guidance
|
|
2
|
+
|
|
3
|
+
The custom `deps.cirru` path is a top-level `caps` positional argument. Guidance must use `caps <deps-file> upgrade --all`; placing the path after `upgrade --all` makes argh parse it as a dependency package name. The mismatch regression test now locks the correct ordering.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Quote the manifest path in mutation guidance
|
|
2
|
+
|
|
3
|
+
The Snapshot toolchain guard now renders the adjacent `deps.cirru` path with the existing shell quoting helper. A regression fixture uses a directory containing whitespace and verifies the suggested `caps '<deps-file>' upgrade --all` command remains a single shell argument. The fixture identity also combines a timestamp with an atomic sequence so parallel tests cannot share a manifest.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Release 0.13.61
|
|
2
|
+
|
|
3
|
+
Patch release for the Snapshot mutation toolchain guard from PR #517. Snapshot-writing CLI commands now reject a mismatch with adjacent `deps.cirru :calcit-version` before any write, while read-only and dry-run workflows remain available. Diagnostics preserve custom manifest paths, argument order, and shell quoting.
|
package/lib/package.json
CHANGED