@calcit/procs 0.13.65 → 0.13.67

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.
Binary file
@@ -0,0 +1,17 @@
1
+ # Dynamic nominal method receiver diagnostics / Dynamic nominal method 接收者诊断
2
+
3
+ ## 中文
4
+
5
+ - 修复 #527:当 postfix Option/Result method(如 `.unwrap-or`)的接收者仍为 `Dynamic` 时,预处理器不再静默回退为普通参数调用。
6
+ - 新增 `W_DYNAMIC_NOMINAL_METHOD_RECEIVER`,要求先通过 schema/assertion 收窄接收者;有意保留的 Dynamic 边界可显式使用对应 `option:*` / `result:*` 函数。
7
+ - 诊断只覆盖 Option/Result 的 nominal container methods,其他 Dynamic postfix methods 继续由现有 `--warn-dyn-method` / `analyze dynamic-methods` 策略审计,避免无关兼容性扩大。
8
+ - 补充单元测试、完整 snippet 预处理回归,以及 upgrade/polymorphism 文档。
9
+ - 验证通过:strict rustfmt/clippy、全部 Rust tests、Calcit core 223/223、native/JS/IR/WASM、Agent interface 17/17;使用新编译器检查最新 copyboard 与 calcium-workflow main 均通过。
10
+
11
+ ## English
12
+
13
+ - Fix #527: when a postfix Option/Result method such as `.unwrap-or` still has a `Dynamic` receiver, preprocessing no longer silently falls back to treating the method token as an ordinary argument.
14
+ - Add `W_DYNAMIC_NOMINAL_METHOD_RECEIVER`, requiring a schema/assertion-based narrowing step; an intentionally Dynamic boundary may explicitly call the corresponding `option:*` / `result:*` function.
15
+ - Scope the unconditional diagnostic to nominal Option/Result container methods. Other Dynamic postfix methods remain under the existing `--warn-dyn-method` / `analyze dynamic-methods` policy to avoid broad unrelated compatibility changes.
16
+ - Add a unit regression, a full snippet preprocessing regression, and upgrade/polymorphism documentation.
17
+ - Verification passes strict rustfmt/clippy, all Rust tests, Calcit core 223/223, native/JS/IR/WASM, and Agent interface 17/17; the new compiler also checks the latest copyboard and calcium-workflow main branches successfully.
@@ -0,0 +1,15 @@
1
+ # Review: keep JS member kinds outside nominal methods / Review:区分 JS member 与 nominal method
2
+
3
+ ## 中文
4
+
5
+ - 根据 PR #530 review,将 `W_DYNAMIC_NOMINAL_METHOD_RECEIVER` 严格限制为普通 `MethodKind::Invoke`。
6
+ - `.-field` 与 `.!method` 即使命名碰巧是 `unwrap-or`,也属于 JavaScript property/native operation,不应按 Option/Result method 诊断。
7
+ - 增加 Access/InvokeNative 反例测试,并将文档中的 `option:*` / `result:*` 明确描述为 Dynamic 边界支持的低层 API;类型化代码仍优先使用 method。
8
+ - 目标测试、strict clippy 与格式检查通过。
9
+
10
+ ## English
11
+
12
+ - Follow PR #530 review by restricting `W_DYNAMIC_NOMINAL_METHOD_RECEIVER` to ordinary `MethodKind::Invoke` calls.
13
+ - `.-field` and `.!method` remain JavaScript property/native operations even when their names happen to be `unwrap-or`; they must not be diagnosed as Option/Result methods.
14
+ - Add Access/InvokeNative negative regressions and describe `option:*` / `result:*` as supported lower-level Dynamic-boundary APIs while retaining method syntax as the typed-code preference.
15
+ - Targeted tests, strict clippy, and formatting checks pass.
@@ -0,0 +1,11 @@
1
+ # Release 0.13.66 / 发布 0.13.66
2
+
3
+ ## 中文
4
+
5
+ - 发布 Calcit 0.13.66,包含 #530 / #527 的 Dynamic Option/Result method 接收者检查期诊断。
6
+ - 同步更新 Cargo crate 与 `@calcit/procs` 版本;功能变更已通过完整 Rust、Calcit、JS、IR、WASM、Agent 与真实 copyboard/calcium-workflow 回归。
7
+
8
+ ## English
9
+
10
+ - Release Calcit 0.13.66 with the preprocessing diagnostic for Dynamic Option/Result method receivers from #530 / #527.
11
+ - Keep the Cargo crate and `@calcit/procs` versions aligned; the feature change passed the full Rust, Calcit, JS, IR, WASM, Agent, and real copyboard/calcium-workflow regressions.
@@ -0,0 +1,19 @@
1
+ # Calx scalar eligibility boundary / Calx 标量子集准入边界
2
+
3
+ ## 中文
4
+
5
+ - 为 Calx 编译目标建立第一段只读边界:直接消费真实的 typed `CompiledProgram` snapshot,不从源码文本重新推断,也不在分析失败时产生半成品 Calx program。
6
+ - 首批只接受固定参数的 `Number`/`Bool` 标量函数、`Unit` 结果、局部变量、完整 `if`、数值运算与比较、直接调用及尾位置 `recur`;`Dynamic`、Nil/absence、间接调用和未批准 host capability 都产生稳定的结构化 fallback code。
7
+ - eligibility 按入口的完整可达 direct-call closure 判断。任一 callee 不合格时,整个入口回退,并保留 definition、source tree path 与 call path;函数和 issue 使用确定排序,便于 golden 与跨仓库追踪。
8
+ - fixtures 从 Cirru source 进入正常 preprocessing,再分析不可变 snapshot;覆盖 range sum、Fibonacci、affine helper graph,以及 Dynamic callee 触发的 closure fallback。
9
+ - 当前不依赖尚未发布 `ProgramBuilder` 的 `calx_vm` git revision。等对应稳定 crate 发布后,再从同一 typed expression 降低到 `ProgramBuilder -> CalxProgram -> ValidatedProgram`。
10
+ - 验证通过:`cargo fmt --check`、strict all-target/all-feature Clippy、全部 Rust tests、`yarn compile`、Agent interface 17/17、`yarn check-all`(含 native/JS/WASM 与性能回归)。
11
+
12
+ ## English
13
+
14
+ - Establish the first read-only boundary for the Calx compilation target: consume the real typed `CompiledProgram` snapshot directly, without re-inferring from source text or emitting a partial Calx program on failure.
15
+ - Initially accept only fixed-arity `Number`/`Bool` scalar functions, `Unit` results, locals, complete `if`, numeric operations and comparisons, direct calls, and tail-position `recur`. `Dynamic`, Nil/absence, indirect calls, and unapproved host capabilities produce stable structured fallback codes.
16
+ - Decide eligibility across the entry's complete reachable direct-call closure. One ineligible callee falls back the whole entry while preserving the definition, source tree path, and call path; deterministic function and issue ordering supports golden tests and cross-repository tracking.
17
+ - Drive fixtures from Cirru source through normal preprocessing before analyzing an immutable snapshot. Coverage includes range sum, Fibonacci, an affine helper graph, and closure fallback caused by a Dynamic callee.
18
+ - Do not depend on an unpublished `calx_vm` Git revision containing `ProgramBuilder`. Once the matching stable crate is published, lower the same typed expressions through `ProgramBuilder -> CalxProgram -> ValidatedProgram`.
19
+ - Verification passes `cargo fmt --check`, strict all-target/all-feature Clippy, all Rust tests, `yarn compile`, Agent interface 17/17, and `yarn check-all` including native/JS/WASM and performance regressions.
@@ -0,0 +1,21 @@
1
+ # Calx strict program lowering / Calx 严格程序 lowering
2
+
3
+ ## 中文
4
+
5
+ - 在完整 eligibility graph 通过后,从同一份 typed `CompiledProgram` expression 先建立内部 lowering plan,再通过稳定版 `calx_vm 0.3.0` 的 `ProgramBuilder -> CalxProgram -> ValidatedProgram` 生成可执行程序;entry 映射为 `main`,其余 reachable function 使用确定的 fully-qualified name。
6
+ - 首批 lowering 覆盖 `Number`/`Bool`/`Unit`、typed parameter/local、单 binding `&let`、sequence/drop、完整 `if`、数值运算与比较、direct call、direct tail call 与 `recur`。每条生成 syntax 携带可追踪到 Calcit definition/tree path 的 synthetic source origin。
7
+ - 严格运行边界只做 `Calcit::Number <-> Calx::F64`、`Calcit::Bool <-> Calx::Bool`、void result -> `Calcit::Unit` 的精确转换。Nil、Dynamic 或其他 runtime value 在实例化 VM 前拒绝,不产生占位值。
8
+ - 只有 `Eligibility` 允许 embedding 选择 whole-kernel fallback;`Lowering`、`Build`、`Validation`、`Instantiate` 与 runtime trap 保持独立,执行失败后不会自动重跑 Calcit,避免未来 effect import 双执行。
9
+ - source-backed fixtures 实际执行 range sum、Fibonacci 与带 typed local/helper tail call 的 affine kernel,并与 native Calcit runner 做差分;Dynamic callee 继续验证整条 closure 在 lowering 前回退。
10
+ - 新依赖树复用了已有 `argh`、`cirru_parser`、`regex`,额外引入 `bincode` 及其 derive 构建依赖;同工具链 release LTO 产物从 main 基线 9,392,160 bytes 增至 9,392,368 bytes(+208 bytes),默认执行路径没有 Calx 初始化。
11
+ - 验证通过:`cargo fmt`、`cargo clippy --all-targets --all-features -- -D warnings`、`cargo test`、`yarn compile`、`yarn check-all`、`yarn check-agent-interface`(17/17),并完成 release binary size 对比。
12
+
13
+ ## English
14
+
15
+ - After the complete eligibility graph succeeds, build an internal lowering plan from the same typed `CompiledProgram` expressions, then produce an executable program through stable `calx_vm 0.3.0` and `ProgramBuilder -> CalxProgram -> ValidatedProgram`. The entry maps to `main`; other reachable functions use deterministic fully-qualified names.
16
+ - The initial lowering covers `Number`/`Bool`/`Unit`, typed parameters and locals, one-binding `&let`, sequence/drop, complete `if`, numeric operations and comparisons, direct calls, direct tail calls, and `recur`. Every generated syntax item carries a synthetic source origin traceable to a Calcit definition/tree path.
17
+ - The strict runtime boundary performs only exact `Calcit::Number <-> Calx::F64`, `Calcit::Bool <-> Calx::Bool`, and void result -> `Calcit::Unit` conversions. Nil, Dynamic, and other runtime values are rejected before VM instantiation; no placeholder value is emitted.
18
+ - Only `Eligibility` lets an embedding select whole-kernel fallback. `Lowering`, `Build`, `Validation`, `Instantiate`, and runtime traps remain distinct, and execution failures never automatically rerun Calcit, preventing future effect imports from executing twice.
19
+ - Source-backed fixtures execute range sum, Fibonacci, and an affine kernel with a typed local/helper tail call, then compare them differentially with the native Calcit runner. A Dynamic callee still proves whole-closure fallback happens before lowering.
20
+ - The dependency tree reuses the existing `argh`, `cirru_parser`, and `regex` crates, adding `bincode` and its derive-time dependencies. With the same release LTO toolchain, the binary grows from a main baseline of 9,392,160 bytes to 9,392,368 bytes (+208 bytes), with no Calx initialization on the default execution path.
21
+ - Verification passes `cargo fmt`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo test`, `yarn compile`, `yarn check-all`, and `yarn check-agent-interface` (17/17), plus a release binary-size comparison.
@@ -0,0 +1,17 @@
1
+ # Calx lowering review hardening / Calx lowering 审阅加固
2
+
3
+ ## 中文
4
+
5
+ - 处理 PR #532 review:生成阶段不再用 map 下标直接访问 `LocalId`。typed local 若没有对应的 emitted Calx local,会返回带 definition 与 source tree path 的 `CalxKernelCompileError::Lowering`,不再存在异常 snapshot 触发 panic 的路径。
6
+ - 由于 `BodyBuilder` 的 structured-control closure 只接受 `CalxBuildError`,emission context 记录首个 lowering invariant failure,并在 function 加入 `ProgramBuilder` 之前返回;不会生成或验证部分 program。
7
+ - 增加异常 lowering plan 的回归测试,固定 missing local index 的结构化错误行为。
8
+ - 从 `calcit::codegen::calx` re-export 公共错误枚举 payload 使用的 `CalxBuildError`、`CalxProgramError` 与 `CalxError`,下游无需声明匹配版本的直接依赖即可匹配错误。
9
+ - 验证通过:`cargo fmt`、590 个 library tests 与全部 binary/doc tests、`cargo clippy --all-targets --all-features -- -D warnings`、`yarn compile`、`yarn check-all`、`yarn check-agent-interface`(17/17)。
10
+
11
+ ## English
12
+
13
+ - Address PR #532 review feedback by removing direct map indexing for `LocalId` during emission. If a typed local has no emitted Calx local, lowering now returns `CalxKernelCompileError::Lowering` with its definition and source tree path instead of allowing a malformed snapshot to panic.
14
+ - Because `BodyBuilder` structured-control closures accept only `CalxBuildError`, the emission context records the first lowering invariant failure and returns it before adding the function to `ProgramBuilder`; no partial program is built or validated.
15
+ - Add a regression test for the structured missing-local error from a malformed lowering plan.
16
+ - Re-export `CalxBuildError`, `CalxProgramError`, and `CalxError` from `calcit::codegen::calx`, matching the payload types exposed by the public error enums so downstream users do not need a version-matched direct dependency merely to pattern-match errors.
17
+ - Verification passes `cargo fmt`, 590 library tests plus all binary/doc tests, `cargo clippy --all-targets --all-features -- -D warnings`, `yarn compile`, `yarn check-all`, and `yarn check-agent-interface` (17/17).
@@ -0,0 +1,16 @@
1
+ # Distinguish text length from UTF-8 wire size / 区分文本长度与 UTF-8 线协议大小
2
+
3
+ ## Summary / 概要
4
+
5
+ - Added the String receiver method `.utf8-byte-count` backed by the internal `&str:utf8-byte-count` primitive. Native and WASM read the stored UTF-8 length in O(1); generated JavaScript performs one allocation-free pass.
6
+ - 增加 String receiver method `.utf8-byte-count`,底层为 `&str:utf8-byte-count` primitive。Native/WASM O(1) 读取已存 UTF-8 长度,生成的 JavaScript 做一次无分配扫描。
7
+ - Corrected `.count` / `&str:count` to mean Unicode scalar count consistently. JavaScript no longer exposes UTF-16 code-unit length, and WASM no longer exposes UTF-8 byte length under the character-count API.
8
+ - 统一 `.count` / `&str:count` 为 Unicode scalar 数量;JavaScript 不再返回 UTF-16 code unit 数量,WASM 也不再把 UTF-8 bytes 冒充字符数。
9
+ - Added native core, JavaScript runtime, and WASM regressions for ASCII, 2/3/4-byte UTF-8 scalars and astral Unicode values.
10
+ - 增加 native core、JavaScript runtime 与 WASM 回归,覆盖 ASCII、2/3/4-byte UTF-8 scalar 与 astral Unicode。
11
+
12
+ ## Realtime motivation / 实时应用动机
13
+
14
+ Calcium Workflow previously measured patch wire bytes with an interpreted per-character fold. A 384 KiB fault-injection payload blocked the server callback for more than 20 seconds before transport backpressure could be observed. The new method gives application metrics an explicit, cross-backend wire-size operation without allocating an encoded copy or conflating it with text indexing.
15
+
16
+ Calcium Workflow 原先通过解释执行的逐字符 fold 统计 patch wire bytes。384 KiB 故障注入 payload 会阻塞 server callback 超过 20 秒,甚至来不及进入 transport backpressure。新 method 为应用指标提供显式、跨 backend 的 wire-size 操作,不分配 encoded copy,也不再与文本索引语义混淆。
@@ -0,0 +1,6 @@
1
+ # Release 0.13.67 / 发布 0.13.67
2
+
3
+ - Release the cross-backend String semantics from PR #533.
4
+ - 发布 PR #533 的跨 backend String 语义改进。
5
+ - `.count` now consistently reports Unicode scalar count; `.utf8-byte-count` reports UTF-8 wire/storage bytes.
6
+ - `.count` 统一返回 Unicode scalar 数量;`.utf8-byte-count` 返回 UTF-8 wire/storage bytes。
@@ -90,6 +90,7 @@ export declare let _$n_enum_def_$o_new: (name: CalcitValue, ...variants: CalcitV
90
90
  export declare let print: (...xs: CalcitValue[]) => void;
91
91
  export declare function _$n_list_$o_count(x: CalcitValue): number;
92
92
  export declare function _$n_str_$o_count(x: CalcitValue): number;
93
+ export declare function _$n_str_$o_utf8_byte_count(x: CalcitValue): number;
93
94
  export declare function _$n_map_$o_count(x: CalcitValue): number;
94
95
  export declare function _$n_struct_$o_count(x: CalcitValue): number;
95
96
  export declare function _$n_struct_$o_field_tag(x: CalcitValue, idx: CalcitValue): CalcitTag;
@@ -325,10 +325,42 @@ export function _$n_list_$o_count(x) {
325
325
  throw new Error(`expected a list ${x}`);
326
326
  }
327
327
  export function _$n_str_$o_count(x) {
328
- if (typeof x === "string")
329
- return x.length;
328
+ if (typeof x === "string") {
329
+ let count = 0;
330
+ for (const _scalar of x)
331
+ count += 1;
332
+ return count;
333
+ }
330
334
  throw new Error(`expected a string ${x}`);
331
335
  }
336
+ export function _$n_str_$o_utf8_byte_count(x) {
337
+ if (typeof x !== "string")
338
+ throw new Error(`&str:utf8-byte-count expected a string ${x}`);
339
+ let bytes = 0;
340
+ for (let i = 0; i < x.length; i += 1) {
341
+ const code = x.charCodeAt(i);
342
+ if (code < 0x80) {
343
+ bytes += 1;
344
+ }
345
+ else if (code < 0x800) {
346
+ bytes += 2;
347
+ }
348
+ else if (code >= 0xd800 && code <= 0xdbff && i + 1 < x.length) {
349
+ const next = x.charCodeAt(i + 1);
350
+ if (next >= 0xdc00 && next <= 0xdfff) {
351
+ bytes += 4;
352
+ i += 1;
353
+ }
354
+ else {
355
+ bytes += 3;
356
+ }
357
+ }
358
+ else {
359
+ bytes += 3;
360
+ }
361
+ }
362
+ return bytes;
363
+ }
332
364
  export function _$n_map_$o_count(x) {
333
365
  if (x instanceof CalcitMap || x instanceof CalcitSliceMap)
334
366
  return x.len();
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.13.65",
3
+ "version": "0.13.67",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.13.65",
3
+ "version": "0.13.67",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
@@ -371,10 +371,38 @@ export function _$n_list_$o_count(x: CalcitValue): number {
371
371
  throw new Error(`expected a list ${x}`);
372
372
  }
373
373
  export function _$n_str_$o_count(x: CalcitValue): number {
374
- if (typeof x === "string") return x.length;
374
+ if (typeof x === "string") {
375
+ let count = 0;
376
+ for (const _scalar of x) count += 1;
377
+ return count;
378
+ }
375
379
 
376
380
  throw new Error(`expected a string ${x}`);
377
381
  }
382
+ export function _$n_str_$o_utf8_byte_count(x: CalcitValue): number {
383
+ if (typeof x !== "string") throw new Error(`&str:utf8-byte-count expected a string ${x}`);
384
+
385
+ let bytes = 0;
386
+ for (let i = 0; i < x.length; i += 1) {
387
+ const code = x.charCodeAt(i);
388
+ if (code < 0x80) {
389
+ bytes += 1;
390
+ } else if (code < 0x800) {
391
+ bytes += 2;
392
+ } else if (code >= 0xd800 && code <= 0xdbff && i + 1 < x.length) {
393
+ const next = x.charCodeAt(i + 1);
394
+ if (next >= 0xdc00 && next <= 0xdfff) {
395
+ bytes += 4;
396
+ i += 1;
397
+ } else {
398
+ bytes += 3;
399
+ }
400
+ } else {
401
+ bytes += 3;
402
+ }
403
+ }
404
+ return bytes;
405
+ }
378
406
  export function _$n_map_$o_count(x: CalcitValue): number {
379
407
  if (x instanceof CalcitMap || x instanceof CalcitSliceMap) return x.len();
380
408