@calcit/procs 0.13.0 → 0.13.1

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,6 @@
1
+ # 发布 0.13.1
2
+
3
+ - 将 Cargo crate 与 npm package 的版本同步升级到 0.13.1。
4
+ - 本 patch 修复自递归 nominal struct 的类型注解解析,避免 Optional 自引用在定义时递归展开。
5
+ - record、struct 与 enum 的展示名称统一为 symbol;JS DevTools formatter 同步展示 nominal 定义与 enum payload。
6
+ - 发布前通过 Rust、TypeScript 与全量集成验证。
@@ -0,0 +1,28 @@
1
+ # Recursive nominal types and symbol presentation
2
+
3
+ ## Background
4
+
5
+ `defstruct` field annotations eagerly resolved a reference to their own
6
+ definition. A recursive field such as `(:: 'Optional Node)` therefore expanded
7
+ `Node` while it was being declared and could exhaust the Rust stack. In
8
+ addition, nominal record, struct, and enum names were displayed as tags even
9
+ though they are type symbols.
10
+
11
+ ## Changes
12
+
13
+ - Preserve a strict self-reference as `TypeRef` during type annotation parsing,
14
+ while keeping normal trait reference resolution unchanged.
15
+ - Add native and snapshot regression coverage for nil and nested recursive
16
+ nodes, plus a required recursive field that produces a regular type error.
17
+ - Render record, struct, and enum names as quoted symbols in Rust and the JS
18
+ runtime.
19
+ - Extend the browser custom formatter to expose nominal struct field types and
20
+ enum payload types, with structured runtime checks for the formatter output.
21
+
22
+ ## Verification
23
+
24
+ - `cargo fmt --check`
25
+ - `cargo clippy -- -D warnings`
26
+ - `cargo test`
27
+ - `yarn compile`
28
+ - `yarn check-all`
@@ -2,6 +2,8 @@ import { isLiteral } from "./js-primes.mjs";
2
2
  import { CalcitSymbol, CalcitTag } from "./calcit-data.mjs";
3
3
  import { CalcitRef } from "./js-ref.mjs";
4
4
  import { CalcitRecord } from "./js-record.mjs";
5
+ import { CalcitStruct } from "./js-struct.mjs";
6
+ import { CalcitEnum } from "./js-enum.mjs";
5
7
  import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
6
8
  import { CalcitList, CalcitSliceList } from "./js-list.mjs";
7
9
  import { CalcitSet } from "./js-set.mjs";
@@ -149,15 +151,22 @@ export let load_console_formatter_$x_ = () => {
149
151
  }, `${obj.len()}`), preview);
150
152
  }
151
153
  if (obj instanceof CalcitRecord) {
154
+ let name = new CalcitSymbol(obj.name.value);
152
155
  if (obj.structRef.impls.length > 0) {
153
- let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, span({}, "%{}"), span({ marginLeft: "6px" }, embedObject(obj.structRef.impls[0])), span({ marginLeft: "6px" }, embedObject(obj.name)), span({ marginLeft: "6px" }, `...`));
156
+ let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, span({}, "%{}"), span({ marginLeft: "6px" }, embedObject(obj.structRef.impls[0])), span({ marginLeft: "6px" }, embedObject(name)), span({ marginLeft: "6px" }, `...`));
154
157
  return ret;
155
158
  }
156
159
  else {
157
- let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, `%{} ${obj.name} ...`);
160
+ let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, "%{} ", embedObject(name), " ...");
158
161
  return ret;
159
162
  }
160
163
  }
164
+ if (obj instanceof CalcitStruct) {
165
+ return div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, "%struct ", embedObject(new CalcitSymbol(obj.name.value)), " ...");
166
+ }
167
+ if (obj instanceof CalcitEnum) {
168
+ return div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, "%enum ", embedObject(new CalcitSymbol(obj.prototype.name.value)), " ...");
169
+ }
161
170
  if (obj instanceof CalcitTuple) {
162
171
  if (obj.impls.length > 0) {
163
172
  let ret = div({ marginRight: "16px" }, div({ display: "inline-block", color: hsl(300, 100, 40) }, "%::"), div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.impls[0])), div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.tag)));
@@ -200,6 +209,9 @@ export let load_console_formatter_$x_ = () => {
200
209
  if (obj instanceof CalcitRecord) {
201
210
  return obj.fields.length > 0;
202
211
  }
212
+ if (obj instanceof CalcitStruct || obj instanceof CalcitEnum) {
213
+ return obj instanceof CalcitStruct ? obj.fields.length > 0 : obj.prototype.fields.length > 0;
214
+ }
203
215
  return false;
204
216
  },
205
217
  body: (obj, config) => {
@@ -255,6 +267,20 @@ export let load_console_formatter_$x_ = () => {
255
267
  }
256
268
  return ret;
257
269
  }
270
+ if (obj instanceof CalcitStruct) {
271
+ let ret = table({ color: hsl(280, 80, 60), borderLeft: "1px solid #eee" });
272
+ for (let idx = 0; idx < obj.fields.length; idx++) {
273
+ ret.push(tr({}, td({ paddingLeft: "8px", verticalAlign: "top", whiteSpace: "pre", minWidth: "40px" }, embedObject(obj.fields[idx])), td({ paddingLeft: "8px" }, embedObject(obj.fieldTypes[idx]))));
274
+ }
275
+ return ret;
276
+ }
277
+ if (obj instanceof CalcitEnum) {
278
+ let ret = table({ color: hsl(280, 80, 60), borderLeft: "1px solid #eee" });
279
+ for (let idx = 0; idx < obj.prototype.fields.length; idx++) {
280
+ ret.push(tr({}, td({ paddingLeft: "8px", verticalAlign: "top", whiteSpace: "pre", minWidth: "40px" }, embedObject(obj.prototype.fields[idx])), td({ paddingLeft: "8px" }, embedObject(obj.prototype.values[idx]))));
281
+ }
282
+ return ret;
283
+ }
258
284
  return null;
259
285
  },
260
286
  },
package/lib/js-enum.mjs CHANGED
@@ -24,6 +24,6 @@ export class CalcitEnum {
24
24
  return new CalcitEnum(this.prototype.withImpls(nextImpls));
25
25
  }
26
26
  toString() {
27
- return `(%enum :${this.prototype.name.value})`;
27
+ return `(%enum '${this.prototype.name.value})`;
28
28
  }
29
29
  }
package/lib/js-record.mjs CHANGED
@@ -64,7 +64,7 @@ export class CalcitRecord {
64
64
  }
65
65
  toString(disableJsDataWarning = false) {
66
66
  // Optimize string building using array join instead of concatenation
67
- const parts = ["(%{} ", this.name.toString()];
67
+ const parts = ["(%{} '", this.name.value];
68
68
  for (let idx = 0; idx < this.fields.length; idx++) {
69
69
  parts.push(" (", this.fields[idx].toString(), " ", toString(this.values[idx], true, disableJsDataWarning), ")");
70
70
  }
package/lib/js-struct.mjs CHANGED
@@ -24,7 +24,7 @@ export class CalcitStruct {
24
24
  if (this.fields.length !== this.fieldTypes.length) {
25
25
  throw new Error("CalcitStruct: fields and fieldTypes length mismatch");
26
26
  }
27
- const parts = ["(%struct :", this.name.value];
27
+ const parts = ["(%struct '", this.name.value];
28
28
  for (let idx = 0; idx < this.fields.length; idx++) {
29
29
  const field = this.fields[idx];
30
30
  const fieldType = this.fieldTypes[idx];
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
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.0",
3
+ "version": "0.13.1",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
@@ -3,6 +3,8 @@ import { CalcitSymbol, CalcitTag } from "./calcit-data.mjs";
3
3
  import { CalcitRef } from "./js-ref.mjs";
4
4
 
5
5
  import { CalcitRecord } from "./js-record.mjs";
6
+ import { CalcitStruct } from "./js-struct.mjs";
7
+ import { CalcitEnum } from "./js-enum.mjs";
6
8
  import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
7
9
  import { CalcitList, CalcitSliceList } from "./js-list.mjs";
8
10
  import { CalcitSet } from "./js-set.mjs";
@@ -180,20 +182,42 @@ export let load_console_formatter_$x_ = () => {
180
182
  );
181
183
  }
182
184
  if (obj instanceof CalcitRecord) {
185
+ let name = new CalcitSymbol(obj.name.value);
183
186
  if (obj.structRef.impls.length > 0) {
184
187
  let ret: any[] = div(
185
188
  { color: hsl(280, 80, 60, 0.4), maxWidth: "100%" },
186
189
  span({}, "%{}"),
187
190
  span({ marginLeft: "6px" }, embedObject(obj.structRef.impls[0])),
188
- span({ marginLeft: "6px" }, embedObject(obj.name)),
191
+ span({ marginLeft: "6px" }, embedObject(name)),
189
192
  span({ marginLeft: "6px" }, `...`)
190
193
  );
191
194
  return ret;
192
195
  } else {
193
- let ret: any[] = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, `%{} ${obj.name} ...`);
196
+ let ret: any[] = div(
197
+ { color: hsl(280, 80, 60, 0.4), maxWidth: "100%" },
198
+ "%{} ",
199
+ embedObject(name),
200
+ " ..."
201
+ );
194
202
  return ret;
195
203
  }
196
204
  }
205
+ if (obj instanceof CalcitStruct) {
206
+ return div(
207
+ { color: hsl(280, 80, 60, 0.4), maxWidth: "100%" },
208
+ "%struct ",
209
+ embedObject(new CalcitSymbol(obj.name.value)),
210
+ " ..."
211
+ );
212
+ }
213
+ if (obj instanceof CalcitEnum) {
214
+ return div(
215
+ { color: hsl(280, 80, 60, 0.4), maxWidth: "100%" },
216
+ "%enum ",
217
+ embedObject(new CalcitSymbol(obj.prototype.name.value)),
218
+ " ..."
219
+ );
220
+ }
197
221
  if (obj instanceof CalcitTuple) {
198
222
  if (obj.impls.length > 0) {
199
223
  let ret: any[] = div(
@@ -255,6 +279,9 @@ export let load_console_formatter_$x_ = () => {
255
279
  if (obj instanceof CalcitRecord) {
256
280
  return obj.fields.length > 0;
257
281
  }
282
+ if (obj instanceof CalcitStruct || obj instanceof CalcitEnum) {
283
+ return obj instanceof CalcitStruct ? obj.fields.length > 0 : obj.prototype.fields.length > 0;
284
+ }
258
285
  return false;
259
286
  },
260
287
  body: (obj, config) => {
@@ -330,6 +357,32 @@ export let load_console_formatter_$x_ = () => {
330
357
  }
331
358
  return ret;
332
359
  }
360
+ if (obj instanceof CalcitStruct) {
361
+ let ret: any[] = table({ color: hsl(280, 80, 60), borderLeft: "1px solid #eee" });
362
+ for (let idx = 0; idx < obj.fields.length; idx++) {
363
+ ret.push(
364
+ tr(
365
+ {},
366
+ td({ paddingLeft: "8px", verticalAlign: "top", whiteSpace: "pre", minWidth: "40px" }, embedObject(obj.fields[idx])),
367
+ td({ paddingLeft: "8px" }, embedObject(obj.fieldTypes[idx]))
368
+ )
369
+ );
370
+ }
371
+ return ret;
372
+ }
373
+ if (obj instanceof CalcitEnum) {
374
+ let ret: any[] = table({ color: hsl(280, 80, 60), borderLeft: "1px solid #eee" });
375
+ for (let idx = 0; idx < obj.prototype.fields.length; idx++) {
376
+ ret.push(
377
+ tr(
378
+ {},
379
+ td({ paddingLeft: "8px", verticalAlign: "top", whiteSpace: "pre", minWidth: "40px" }, embedObject(obj.prototype.fields[idx])),
380
+ td({ paddingLeft: "8px" }, embedObject(obj.prototype.values[idx]))
381
+ )
382
+ );
383
+ }
384
+ return ret;
385
+ }
333
386
 
334
387
  return null;
335
388
  },
@@ -31,6 +31,6 @@ export class CalcitEnum {
31
31
  }
32
32
 
33
33
  toString(): string {
34
- return `(%enum :${this.prototype.name.value})`;
34
+ return `(%enum '${this.prototype.name.value})`;
35
35
  }
36
36
  }
@@ -70,7 +70,7 @@ export class CalcitRecord {
70
70
  }
71
71
  toString(disableJsDataWarning: boolean = false): string {
72
72
  // Optimize string building using array join instead of concatenation
73
- const parts = ["(%{} ", this.name.toString()];
73
+ const parts = ["(%{} '", this.name.value];
74
74
  for (let idx = 0; idx < this.fields.length; idx++) {
75
75
  parts.push(" (", this.fields[idx].toString(), " ", toString(this.values[idx], true, disableJsDataWarning), ")");
76
76
  }
@@ -33,7 +33,7 @@ export class CalcitStruct {
33
33
  if (this.fields.length !== this.fieldTypes.length) {
34
34
  throw new Error("CalcitStruct: fields and fieldTypes length mismatch");
35
35
  }
36
- const parts: string[] = ["(%struct :", this.name.value];
36
+ const parts: string[] = ["(%struct '", this.name.value];
37
37
  for (let idx = 0; idx < this.fields.length; idx++) {
38
38
  const field = this.fields[idx];
39
39
  const fieldType = this.fieldTypes[idx];