@calcit/procs 0.13.42 → 0.13.44

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.
Files changed (68) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/RFCs/04-15-match-syntax-rfc.md +14 -8
  3. package/RFCs/04-15-type-directed-optimization-catalog.md +20 -14
  4. package/RFCs/08-05-systematic-nil-reduction-rfc.md +16 -5
  5. package/editing-history/20260823-0401-guard-range-progress.md +9 -0
  6. package/editing-history/20260824-0318-range-backend-consistency.md +13 -0
  7. package/editing-history/20260824-0645-unit-truthiness-review.md +6 -0
  8. package/editing-history/20260824-0655-project-module-merge-review.md +4 -0
  9. package/editing-history/20260824-0705-unit-effect-return-review.md +5 -0
  10. package/editing-history/20260824-1540-scaffold-data-kind-schema.md +6 -0
  11. package/editing-history/20260824-2119-validate-number-call-metadata.md +8 -0
  12. package/editing-history/20260824-2155-stable-js-struct-layout.md +11 -0
  13. package/editing-history/20260824-2224-struct-index-review-followups.md +7 -0
  14. package/editing-history/20260824-2233-indexed-struct-js-regressions.md +5 -0
  15. package/editing-history/20260824-2256-dynamic-method-analysis.md +9 -0
  16. package/editing-history/20260824-2329-dynamic-method-review-followups.md +7 -0
  17. package/editing-history/202608241525-release-01343.md +5 -0
  18. package/editing-history/202608241731-contiguous-executable-calls.md +34 -0
  19. package/editing-history/202608241920-borrowed-syntax-arguments.md +34 -0
  20. package/editing-history/202608241924-unify-editing-history-directory.md +7 -0
  21. package/editing-history/202608242013-typed-native-number-ops.md +34 -0
  22. package/editing-history/20260825-0020-indexed-enum-match.md +34 -0
  23. package/editing-history/20260825-0100-indexed-enum-match-validation.md +7 -0
  24. package/editing-history/20260825-0120-indexed-enum-match-review.md +7 -0
  25. package/editing-history/20260825-1215-typed-literal-paths.md +56 -0
  26. package/editing-history/20260825-1344-typed-literal-path-review.md +17 -0
  27. package/editing-history/20260825-1505-typed-method-native-op.md +23 -0
  28. package/editing-history/20260825-1540-nil-unit-runtime-separation.md +15 -0
  29. package/editing-history/20260825-1725-typed-method-error-stack-review.md +10 -0
  30. package/editing-history/20260825-1733-nil-unit-doc-review.md +5 -0
  31. package/editing-history/20260825-1758-nil-unit-review-followup.md +6 -0
  32. package/editing-history/20260825-1845-release-01344.md +6 -0
  33. package/examples/bench_enum_match.rs +41 -0
  34. package/lib/calcit-data.d.mts +4 -0
  35. package/lib/calcit-data.mjs +59 -9
  36. package/lib/calcit.procs.d.mts +17 -9
  37. package/lib/calcit.procs.mjs +104 -57
  38. package/lib/custom-formatter.mjs +12 -3
  39. package/lib/js-cirru.mjs +6 -5
  40. package/lib/js-impl.mjs +4 -3
  41. package/lib/js-primes.d.mts +1 -1
  42. package/lib/js-primes.mjs +22 -18
  43. package/lib/js-struct-def.mjs +4 -6
  44. package/lib/js-struct-value.d.mts +5 -1
  45. package/lib/js-struct-value.mjs +66 -38
  46. package/lib/package.json +8 -2
  47. package/package.json +8 -2
  48. package/ts-src/calcit-data.mts +54 -9
  49. package/ts-src/calcit.procs.mts +107 -61
  50. package/ts-src/custom-formatter.mts +12 -3
  51. package/ts-src/js-cirru.mts +6 -5
  52. package/ts-src/js-impl.mts +4 -3
  53. package/ts-src/js-primes.mts +5 -1
  54. package/ts-src/js-struct-def.mts +4 -6
  55. package/ts-src/js-struct-value.mts +78 -33
  56. /package/{history → editing-history}/202608191501-release-01326.md +0 -0
  57. /package/{history → editing-history}/202608191628-revert-transparent-union-types.md +0 -0
  58. /package/{history → editing-history}/202608191741-release-01327.md +0 -0
  59. /package/{history → editing-history}/202608212020-release-01328.md +0 -0
  60. /package/{2026082200-release-01330.md → editing-history/2026082200-release-01330.md} +0 -0
  61. /package/{2026082200-same-package-module-meta.md → editing-history/2026082200-same-package-module-meta.md} +0 -0
  62. /package/{2026082200-transitive-module-loading.md → editing-history/2026082200-transitive-module-loading.md} +0 -0
  63. /package/{2026082222-release-01331.md → editing-history/2026082222-release-01331.md} +0 -0
  64. /package/{history → editing-history}/2026082223-release-01332.md +0 -0
  65. /package/{history → editing-history}/2026082223-same-package-namespaces.md +0 -0
  66. /package/{history → editing-history}/2026082300-fix-cross-package-namespace-merge.md +0 -0
  67. /package/{history → editing-history}/2026082300-release-01333.md +0 -0
  68. /package/{history → editing-history}/2026082316-release-01334.md +0 -0
@@ -1,7 +1,17 @@
1
1
  import { initTernaryTreeMap, Hash, insert } from "@calcit/ternary-tree";
2
2
  import { CalcitValue } from "./js-primes.mjs";
3
3
  import { CalcitImpl } from "./js-impl.mjs";
4
- import { newTag, castTag, toString, CalcitTag, getStringName, findInFields } from "./calcit-data.mjs";
4
+ import {
5
+ newTag,
6
+ castTag,
7
+ toString,
8
+ CalcitTag,
9
+ getStringName,
10
+ findInFields,
11
+ compareTagNames,
12
+ canonicalizeTagPairs,
13
+ tagNamesAreCanonical,
14
+ } from "./calcit-data.mjs";
5
15
 
6
16
  import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
7
17
 
@@ -15,18 +25,18 @@ export class CalcitStructValue {
15
25
  cachedHash: Hash;
16
26
  constructor(name: CalcitTag, fields: Array<CalcitTag>, values?: Array<CalcitValue>, structRef?: CalcitStructDef) {
17
27
  this.name = name;
18
- let fieldNames = fields.map(castTag);
19
- this.fields = fields;
20
- if (values != null) {
21
- if (values.length !== fields.length) {
22
- throw new Error("fields/values length not match");
23
- }
24
- this.values = values;
25
- } else {
26
- this.values = new Array(fieldNames.length);
27
- }
28
+ const fieldNames = fields.map(castTag);
29
+ const sourceValues = values ?? new Array(fieldNames.length);
30
+ const [canonicalFields, canonicalValues] = canonicalizeTagPairs(fieldNames, sourceValues, "CalcitStructValue");
31
+ this.fields = canonicalFields;
32
+ this.values = canonicalValues;
28
33
  this.cachedHash = null;
29
- this.structRef = structRef || new CalcitStructDef(name, fields, new Array(fields.length).fill(null));
34
+ this.structRef =
35
+ structRef == null
36
+ ? new CalcitStructDef(name, canonicalFields, new Array(canonicalFields.length).fill(null))
37
+ : tagNamesAreCanonical(structRef.fields)
38
+ ? structRef
39
+ : new CalcitStructDef(structRef.name, structRef.fields, structRef.fieldTypes, structRef.impls);
30
40
  }
31
41
  get(k: CalcitValue) {
32
42
  let field = castTag(k);
@@ -63,6 +73,40 @@ export class CalcitStructValue {
63
73
  }
64
74
  return new CalcitStructValue(this.name, this.fields, values, this.structRef);
65
75
  }
76
+ nthAt(index: CalcitValue, field: CalcitValue): CalcitValue {
77
+ const idx = checkedStructIndex(index, "&struct:nth");
78
+ this.assertFieldAt(idx, field, "&struct:nth");
79
+ return this.values[idx];
80
+ }
81
+ assocAt(index: CalcitValue, field: CalcitValue, value: CalcitValue): CalcitStructValue {
82
+ const idx = checkedStructIndex(index, "&struct:assoc-at");
83
+ this.assertFieldAt(idx, field, "&struct:assoc-at");
84
+ const values = this.values.slice();
85
+ values[idx] = value;
86
+ return new CalcitStructValue(this.name, this.fields, values, this.structRef);
87
+ }
88
+ withAt(...triples: CalcitValue[]): CalcitStructValue {
89
+ if (triples.length === 0 || triples.length % 3 !== 0) {
90
+ throw new Error("&struct:with-at expected index/tag/value triples");
91
+ }
92
+ const values = this.values.slice();
93
+ for (let base = 0; base < triples.length; base += 3) {
94
+ const idx = checkedStructIndex(triples[base], "&struct:with-at");
95
+ this.assertFieldAt(idx, triples[base + 1], "&struct:with-at");
96
+ values[idx] = triples[base + 2];
97
+ }
98
+ return new CalcitStructValue(this.name, this.fields, values, this.structRef);
99
+ }
100
+ private assertFieldAt(idx: number, field: CalcitValue, operation: string): void {
101
+ if (idx >= this.fields.length) {
102
+ throw new Error(`${operation} index ${idx} out of range for struct '${this.name.value}' with ${this.fields.length} fields`);
103
+ }
104
+ const fieldTag = castTag(field);
105
+ const expectedTag = this.fields[idx];
106
+ if (expectedTag.value !== fieldTag.value) {
107
+ throw new Error(`${operation} index ${idx} expects field :${expectedTag.value}, but received :${fieldTag.value}`);
108
+ }
109
+ }
66
110
  /** return -1 for missing */
67
111
  findIndex(k: CalcitValue) {
68
112
  let field = castTag(k);
@@ -97,35 +141,21 @@ export class CalcitStructValue {
97
141
  }
98
142
 
99
143
  export let new_struct_value = (name: CalcitValue, ...fields: Array<CalcitValue>): CalcitValue => {
100
- let fieldNames = fields.map(castTag).sort((x, y) => {
101
- if (x.idx < y.idx) {
102
- return -1;
103
- } else if (x.idx > y.idx) {
104
- return 1;
105
- } else {
106
- throw new Error(`Unexpected duplication in struct fields: ${x.toString()}`);
107
- }
108
- });
144
+ let fieldNames = fields.map(castTag).sort(compareTagNames);
145
+ assertUniqueFields(fieldNames, "Unexpected duplication in struct fields");
109
146
  return new CalcitStructValue(castTag(name), fieldNames);
110
147
  };
111
148
 
112
149
  export let new_impl_struct_value = (impl: CalcitImpl, name: CalcitValue, ...fields: Array<CalcitValue>): CalcitValue => {
113
- let fieldNames = fields.map(castTag).sort((x, y) => {
114
- if (x.idx < y.idx) {
115
- return -1;
116
- } else if (x.idx > y.idx) {
117
- return 1;
118
- } else {
119
- throw new Error(`Unexpected duplication in struct fields: ${x.toString()}`);
120
- }
121
- });
150
+ let fieldNames = fields.map(castTag).sort(compareTagNames);
151
+ assertUniqueFields(fieldNames, "Unexpected duplication in struct fields");
122
152
  let nameTag = castTag(name);
123
153
  let structRef = new CalcitStructDef(nameTag, fieldNames, new Array(fieldNames.length).fill(null), [impl]);
124
154
  return new CalcitStructValue(nameTag, fieldNames, undefined, structRef);
125
155
  };
126
156
 
127
157
  /** Loose record: `?{} :field1 val1 :field2 val2` – record without a declared struct.
128
- * Fields are sorted by tag index. The record name is "?" (sentinel). */
158
+ * Fields use the same lexical layout as named structs. The record name is "_". */
129
159
  export let _$q__$M_ = (...xs: Array<CalcitValue>): CalcitValue => {
130
160
  if (xs.length % 2 !== 0) {
131
161
  throw new Error("?{} expected pairs of :field value");
@@ -134,10 +164,10 @@ export let _$q__$M_ = (...xs: Array<CalcitValue>): CalcitValue => {
134
164
  for (let i = 0; i < xs.length; i += 2) {
135
165
  pairs.push([castTag(xs[i]), xs[i + 1]]);
136
166
  }
137
- pairs.sort((a, b) => a[0].idx - b[0].idx);
167
+ pairs.sort((a, b) => compareTagNames(a[0], b[0]));
138
168
  // Check for duplicate fields after sorting
139
169
  for (let i = 1; i < pairs.length; i++) {
140
- if (pairs[i][0].idx === pairs[i - 1][0].idx) {
170
+ if (pairs[i][0].value === pairs[i - 1][0].value) {
141
171
  throw new Error(`?{} received duplicate field: :${getStringName(pairs[i][0])}`);
142
172
  }
143
173
  }
@@ -147,6 +177,21 @@ export let _$q__$M_ = (...xs: Array<CalcitValue>): CalcitValue => {
147
177
  return new CalcitStructValue(looseTag, fieldNames, values);
148
178
  };
149
179
 
180
+ function checkedStructIndex(value: CalcitValue, operation: string): number {
181
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
182
+ throw new Error(`${operation} expected a non-negative integer index, but received: ${value}`);
183
+ }
184
+ return value;
185
+ }
186
+
187
+ function assertUniqueFields(fields: CalcitTag[], message: string): void {
188
+ for (let idx = 1; idx < fields.length; idx++) {
189
+ if (fields[idx - 1].value === fields[idx].value) {
190
+ throw new Error(`${message}: ${fields[idx].toString()}`);
191
+ }
192
+ }
193
+ }
194
+
150
195
  export let fieldsEqual = (xs: Array<CalcitTag>, ys: Array<CalcitTag>): boolean => {
151
196
  if (xs === ys) {
152
197
  return true; // special case, referential equal