@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.
- package/.yarn/install-state.gz +0 -0
- package/RFCs/04-15-match-syntax-rfc.md +14 -8
- package/RFCs/04-15-type-directed-optimization-catalog.md +20 -14
- package/RFCs/08-05-systematic-nil-reduction-rfc.md +16 -5
- package/editing-history/20260823-0401-guard-range-progress.md +9 -0
- package/editing-history/20260824-0318-range-backend-consistency.md +13 -0
- package/editing-history/20260824-0645-unit-truthiness-review.md +6 -0
- package/editing-history/20260824-0655-project-module-merge-review.md +4 -0
- package/editing-history/20260824-0705-unit-effect-return-review.md +5 -0
- package/editing-history/20260824-1540-scaffold-data-kind-schema.md +6 -0
- package/editing-history/20260824-2119-validate-number-call-metadata.md +8 -0
- package/editing-history/20260824-2155-stable-js-struct-layout.md +11 -0
- package/editing-history/20260824-2224-struct-index-review-followups.md +7 -0
- package/editing-history/20260824-2233-indexed-struct-js-regressions.md +5 -0
- package/editing-history/20260824-2256-dynamic-method-analysis.md +9 -0
- package/editing-history/20260824-2329-dynamic-method-review-followups.md +7 -0
- package/editing-history/202608241525-release-01343.md +5 -0
- package/editing-history/202608241731-contiguous-executable-calls.md +34 -0
- package/editing-history/202608241920-borrowed-syntax-arguments.md +34 -0
- package/editing-history/202608241924-unify-editing-history-directory.md +7 -0
- package/editing-history/202608242013-typed-native-number-ops.md +34 -0
- package/editing-history/20260825-0020-indexed-enum-match.md +34 -0
- package/editing-history/20260825-0100-indexed-enum-match-validation.md +7 -0
- package/editing-history/20260825-0120-indexed-enum-match-review.md +7 -0
- package/editing-history/20260825-1215-typed-literal-paths.md +56 -0
- package/editing-history/20260825-1344-typed-literal-path-review.md +17 -0
- package/editing-history/20260825-1505-typed-method-native-op.md +23 -0
- package/editing-history/20260825-1540-nil-unit-runtime-separation.md +15 -0
- package/editing-history/20260825-1725-typed-method-error-stack-review.md +10 -0
- package/editing-history/20260825-1733-nil-unit-doc-review.md +5 -0
- package/editing-history/20260825-1758-nil-unit-review-followup.md +6 -0
- package/editing-history/20260825-1845-release-01344.md +6 -0
- package/examples/bench_enum_match.rs +41 -0
- package/lib/calcit-data.d.mts +4 -0
- package/lib/calcit-data.mjs +59 -9
- package/lib/calcit.procs.d.mts +17 -9
- package/lib/calcit.procs.mjs +104 -57
- package/lib/custom-formatter.mjs +12 -3
- package/lib/js-cirru.mjs +6 -5
- package/lib/js-impl.mjs +4 -3
- package/lib/js-primes.d.mts +1 -1
- package/lib/js-primes.mjs +22 -18
- package/lib/js-struct-def.mjs +4 -6
- package/lib/js-struct-value.d.mts +5 -1
- package/lib/js-struct-value.mjs +66 -38
- package/lib/package.json +8 -2
- package/package.json +8 -2
- package/ts-src/calcit-data.mts +54 -9
- package/ts-src/calcit.procs.mts +107 -61
- package/ts-src/custom-formatter.mts +12 -3
- package/ts-src/js-cirru.mts +6 -5
- package/ts-src/js-impl.mts +4 -3
- package/ts-src/js-primes.mts +5 -1
- package/ts-src/js-struct-def.mts +4 -6
- package/ts-src/js-struct-value.mts +78 -33
- /package/{history → editing-history}/202608191501-release-01326.md +0 -0
- /package/{history → editing-history}/202608191628-revert-transparent-union-types.md +0 -0
- /package/{history → editing-history}/202608191741-release-01327.md +0 -0
- /package/{history → editing-history}/202608212020-release-01328.md +0 -0
- /package/{2026082200-release-01330.md → editing-history/2026082200-release-01330.md} +0 -0
- /package/{2026082200-same-package-module-meta.md → editing-history/2026082200-same-package-module-meta.md} +0 -0
- /package/{2026082200-transitive-module-loading.md → editing-history/2026082200-transitive-module-loading.md} +0 -0
- /package/{2026082222-release-01331.md → editing-history/2026082222-release-01331.md} +0 -0
- /package/{history → editing-history}/2026082223-release-01332.md +0 -0
- /package/{history → editing-history}/2026082223-same-package-namespaces.md +0 -0
- /package/{history → editing-history}/2026082300-fix-cross-package-namespace-merge.md +0 -0
- /package/{history → editing-history}/2026082300-release-01333.md +0 -0
- /package/{history → editing-history}/2026082316-release-01334.md +0 -0
package/ts-src/calcit.procs.mts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
refsRegistry,
|
|
18
18
|
toString,
|
|
19
19
|
getStringName,
|
|
20
|
+
compareTagNames,
|
|
20
21
|
_$n__$e_,
|
|
21
22
|
hashFunction,
|
|
22
23
|
} from "./calcit-data.mjs";
|
|
@@ -71,9 +72,10 @@ export let type_of = (x: any): CalcitTag => {
|
|
|
71
72
|
if (x instanceof CalcitMap || x instanceof CalcitSliceMap) {
|
|
72
73
|
return newTag("map");
|
|
73
74
|
}
|
|
74
|
-
if (x
|
|
75
|
+
if (x === null) {
|
|
75
76
|
return newTag("nil");
|
|
76
77
|
}
|
|
78
|
+
if (x === undefined) return newTag("unit");
|
|
77
79
|
if (x instanceof CalcitRef) {
|
|
78
80
|
return newTag("ref");
|
|
79
81
|
}
|
|
@@ -252,7 +254,7 @@ export let defstruct = (name: CalcitValue, ...entries: CalcitValue[]): CalcitStr
|
|
|
252
254
|
fields.push({ tag: fieldTag, type: fieldType });
|
|
253
255
|
}
|
|
254
256
|
|
|
255
|
-
fields.sort((a, b) => a.tag
|
|
257
|
+
fields.sort((a, b) => compareTagNames(a.tag, b.tag));
|
|
256
258
|
for (let i = 1; i < fields.length; i++) {
|
|
257
259
|
if (fields[i - 1].tag.value === fields[i].tag.value) {
|
|
258
260
|
throw new Error(`defstruct duplicated field: ${fields[i].tag.toString()}`);
|
|
@@ -279,7 +281,7 @@ export let defenum = (name: CalcitValue, ...variants: CalcitValue[]): CalcitEnum
|
|
|
279
281
|
entries.push({ tag, payload });
|
|
280
282
|
}
|
|
281
283
|
|
|
282
|
-
entries.sort((a, b) => a.tag
|
|
284
|
+
entries.sort((a, b) => compareTagNames(a.tag, b.tag));
|
|
283
285
|
for (let i = 1; i < entries.length; i++) {
|
|
284
286
|
if (entries[i - 1].tag.value === entries[i].tag.value) {
|
|
285
287
|
throw new Error(`defenum duplicated variant: ${entries[i].tag.toString()}`);
|
|
@@ -324,7 +326,7 @@ export let _$n_impl_$o__$o_new = (name: CalcitValue, ...pairs: CalcitValue[]): C
|
|
|
324
326
|
}
|
|
325
327
|
entries.push({ tag: fieldTag, value });
|
|
326
328
|
}
|
|
327
|
-
entries.sort((a, b) => a.tag
|
|
329
|
+
entries.sort((a, b) => compareTagNames(a.tag, b.tag));
|
|
328
330
|
for (let i = 1; i < entries.length; i++) {
|
|
329
331
|
if (entries[i - 1].tag.value === entries[i].tag.value) {
|
|
330
332
|
throw new Error(`&impl::new duplicated field: ${entries[i].tag.toString()}`);
|
|
@@ -391,13 +393,24 @@ export function _$n_struct_$o_field_tag(x: CalcitValue, idx: CalcitValue): Calci
|
|
|
391
393
|
return x.fields[i];
|
|
392
394
|
}
|
|
393
395
|
|
|
394
|
-
export function _$n_struct_$o_nth(x: CalcitValue, idx: CalcitValue): CalcitValue {
|
|
396
|
+
export function _$n_struct_$o_nth(x: CalcitValue, idx: CalcitValue, field?: CalcitValue): CalcitValue {
|
|
395
397
|
if (!(x instanceof CalcitStructValue)) throw new Error(`&struct:nth expected a struct value, got ${x}`);
|
|
398
|
+
if (field !== undefined) return x.nthAt(idx, field);
|
|
396
399
|
const i = idx as number;
|
|
397
400
|
if (i < 0 || i >= x.values.length) throw new Error(`&struct:nth index ${i} out of range for struct with ${x.values.length} fields`);
|
|
398
401
|
return x.values[i];
|
|
399
402
|
}
|
|
400
403
|
|
|
404
|
+
export function _$n_struct_$o_assoc_at(x: CalcitValue, idx: CalcitValue, field: CalcitValue, value: CalcitValue): CalcitValue {
|
|
405
|
+
if (!(x instanceof CalcitStructValue)) throw new Error(`&struct:assoc-at expected a struct value, got ${x}`);
|
|
406
|
+
return x.assocAt(idx, field, value);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function _$n_struct_$o_with_at(x: CalcitValue, ...triples: CalcitValue[]): CalcitValue {
|
|
410
|
+
if (!(x instanceof CalcitStructValue)) throw new Error(`&struct:with-at expected a struct value, got ${x}`);
|
|
411
|
+
return x.withAt(...triples);
|
|
412
|
+
}
|
|
413
|
+
|
|
401
414
|
|
|
402
415
|
export function _$n_set_$o_count(x: CalcitValue): number {
|
|
403
416
|
if (x instanceof CalcitSet) return x.len();
|
|
@@ -449,7 +462,7 @@ export let _$n__$s_ = (x: number, y: number): number => {
|
|
|
449
462
|
};
|
|
450
463
|
|
|
451
464
|
export let _$n_str = (x: CalcitValue): string => {
|
|
452
|
-
if (x
|
|
465
|
+
if (x === null) {
|
|
453
466
|
return "";
|
|
454
467
|
}
|
|
455
468
|
if (typeof x === "string") {
|
|
@@ -675,11 +688,11 @@ export let _$n_enum_def_$o_variant_arity = function (enumPrototype: CalcitValue,
|
|
|
675
688
|
throw new Error("Expected variant to be a list");
|
|
676
689
|
};
|
|
677
690
|
|
|
678
|
-
export let _$n_enum_$o_validate = function (enumValue: CalcitValue, tag: CalcitValue):
|
|
691
|
+
export let _$n_enum_$o_validate = function (enumValue: CalcitValue, tag: CalcitValue): void {
|
|
679
692
|
if (arguments.length !== 2) throw new Error("&enum:validate takes 2 arguments");
|
|
680
693
|
if (!(enumValue instanceof CalcitEnumValue)) throw new Error("&enum:validate expects an enum value as first argument");
|
|
681
694
|
if (enumValue.enumPrototype == null) {
|
|
682
|
-
return
|
|
695
|
+
return;
|
|
683
696
|
}
|
|
684
697
|
|
|
685
698
|
const proto = assert_enum_tag_args("&enum:validate", enumValue.enumPrototype as CalcitValue, tag as CalcitTag);
|
|
@@ -696,7 +709,7 @@ export let _$n_enum_$o_validate = function (enumValue: CalcitValue, tag: CalcitV
|
|
|
696
709
|
if (expected !== actual) {
|
|
697
710
|
throw new Error(`enum variant expects ${expected} payload(s), got ${actual} for ${enumValue}`);
|
|
698
711
|
}
|
|
699
|
-
return
|
|
712
|
+
return;
|
|
700
713
|
}
|
|
701
714
|
|
|
702
715
|
throw new Error("Expected variant to be a list");
|
|
@@ -858,7 +871,7 @@ export let _$n_map_$o_dissoc = function (xs: CalcitValue, ...args: CalcitValue[]
|
|
|
858
871
|
throw new Error("`dissoc` expected a map");
|
|
859
872
|
};
|
|
860
873
|
|
|
861
|
-
export let reset_$x_ = (a: CalcitRef, v: CalcitValue):
|
|
874
|
+
export let reset_$x_ = (a: CalcitRef, v: CalcitValue): CalcitValue => {
|
|
862
875
|
if (!(a instanceof CalcitRef)) {
|
|
863
876
|
throw new Error("Expected ref for reset!");
|
|
864
877
|
}
|
|
@@ -867,10 +880,10 @@ export let reset_$x_ = (a: CalcitRef, v: CalcitValue): null => {
|
|
|
867
880
|
a.listeners.forEach((f) => {
|
|
868
881
|
f(v, prev);
|
|
869
882
|
});
|
|
870
|
-
return
|
|
883
|
+
return v;
|
|
871
884
|
};
|
|
872
885
|
|
|
873
|
-
export let add_watch = (a: CalcitRef, k: CalcitTag, f: CalcitFn):
|
|
886
|
+
export let add_watch = (a: CalcitRef, k: CalcitTag, f: CalcitFn): void => {
|
|
874
887
|
if (!(a instanceof CalcitRef)) {
|
|
875
888
|
throw new Error("Expected ref for add-watch!");
|
|
876
889
|
}
|
|
@@ -881,30 +894,57 @@ export let add_watch = (a: CalcitRef, k: CalcitTag, f: CalcitFn): null => {
|
|
|
881
894
|
throw new Error("Expected watcher function");
|
|
882
895
|
}
|
|
883
896
|
a.listeners.set(k, f);
|
|
884
|
-
return null;
|
|
885
897
|
};
|
|
886
898
|
|
|
887
|
-
export let remove_watch = (a: CalcitRef, k: CalcitTag):
|
|
899
|
+
export let remove_watch = (a: CalcitRef, k: CalcitTag): void => {
|
|
888
900
|
a.listeners.delete(k);
|
|
889
|
-
return null;
|
|
890
901
|
};
|
|
891
902
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
903
|
+
const MAX_RANGE_LENGTH = 0xffff_ffff;
|
|
904
|
+
|
|
905
|
+
export let range = (n: number, m?: number, step: number = 1): CalcitSliceList => {
|
|
906
|
+
const base = m == null ? 0 : n;
|
|
907
|
+
const bound = m == null ? n : m;
|
|
908
|
+
|
|
909
|
+
if (!Number.isFinite(base) || !Number.isFinite(bound) || !Number.isFinite(step)) {
|
|
910
|
+
throw new TypeError("&list:range expected finite numbers for base, bound, and step");
|
|
911
|
+
}
|
|
912
|
+
if (base === bound) {
|
|
913
|
+
return new CalcitSliceList([]);
|
|
914
|
+
}
|
|
915
|
+
if (step === 0 || (bound > base && step < 0) || (bound < base && step > 0)) {
|
|
916
|
+
throw new Error("&list:range cannot construct list with a step of 0 or invalid step direction");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// Avoid overflowing `bound - base` when finite endpoints have opposite signs.
|
|
920
|
+
const estimatedLength = (base < 0) !== (bound < 0)
|
|
921
|
+
? Math.ceil(Math.abs(base) / Math.abs(step) + Math.abs(bound) / Math.abs(step))
|
|
922
|
+
: Math.ceil((bound - base) / step);
|
|
923
|
+
if (!Number.isFinite(estimatedLength) || estimatedLength > MAX_RANGE_LENGTH) {
|
|
924
|
+
throw new Error("&list:range result is too large");
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const result: Array<CalcitValue> = [];
|
|
928
|
+
if (step > 0) {
|
|
929
|
+
for (let value = base; value < bound; ) {
|
|
930
|
+
result.push(value);
|
|
931
|
+
const next = value + step;
|
|
932
|
+
if (next === value) {
|
|
933
|
+
throw new Error("&list:range step does not advance the current value");
|
|
934
|
+
}
|
|
935
|
+
value = next;
|
|
899
936
|
}
|
|
900
937
|
} else {
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
938
|
+
for (let value = base; value > bound; ) {
|
|
939
|
+
result.push(value);
|
|
940
|
+
const next = value + step;
|
|
941
|
+
if (next === value) {
|
|
942
|
+
throw new Error("&list:range step does not advance the current value");
|
|
943
|
+
}
|
|
944
|
+
value = next;
|
|
905
945
|
}
|
|
906
946
|
}
|
|
907
|
-
return result;
|
|
947
|
+
return new CalcitSliceList(result);
|
|
908
948
|
};
|
|
909
949
|
|
|
910
950
|
export function _$n_list_$o_empty_$q_(xs: CalcitValue): boolean {
|
|
@@ -977,7 +1017,7 @@ export let _$n_set_$o_destruct = (xs: CalcitValue): CalcitValue => {
|
|
|
977
1017
|
throw new Error("Expect a set");
|
|
978
1018
|
};
|
|
979
1019
|
|
|
980
|
-
export let timeout_call = (duration: number, f: CalcitFn):
|
|
1020
|
+
export let timeout_call = (duration: number, f: CalcitFn): void => {
|
|
981
1021
|
if (typeof duration !== "number") {
|
|
982
1022
|
throw new Error("Expected duration in number");
|
|
983
1023
|
}
|
|
@@ -985,7 +1025,6 @@ export let timeout_call = (duration: number, f: CalcitFn): null => {
|
|
|
985
1025
|
throw new Error("Expected callback in fn");
|
|
986
1026
|
}
|
|
987
1027
|
setTimeout(f, duration);
|
|
988
|
-
return null;
|
|
989
1028
|
};
|
|
990
1029
|
|
|
991
1030
|
export let _$n_list_$o_rest = (xs: CalcitValue): CalcitList | CalcitSliceList => {
|
|
@@ -1082,13 +1121,12 @@ export let generate_id_$x_ = (): string => {
|
|
|
1082
1121
|
return `gen_id_${idCounter}_${time}`;
|
|
1083
1122
|
};
|
|
1084
1123
|
|
|
1085
|
-
export let _$n_display_stack = ():
|
|
1124
|
+
export let _$n_display_stack = (): void => {
|
|
1086
1125
|
console.trace();
|
|
1087
|
-
return null;
|
|
1088
1126
|
};
|
|
1089
1127
|
|
|
1090
1128
|
export let _$n_list_$o_slice = (xs: CalcitList, from: number, to: number): CalcitSliceList | CalcitList => {
|
|
1091
|
-
if (xs
|
|
1129
|
+
if (xs === null) {
|
|
1092
1130
|
return null;
|
|
1093
1131
|
}
|
|
1094
1132
|
let size = xs.len();
|
|
@@ -1106,7 +1144,7 @@ export let _$n_list_$o_concat = (...lists: (CalcitList | CalcitSliceList)[]): Ca
|
|
|
1106
1144
|
let result: CalcitSliceList | CalcitList = new CalcitSliceList([]);
|
|
1107
1145
|
for (let idx = 0; idx < lists.length; idx++) {
|
|
1108
1146
|
let item = lists[idx];
|
|
1109
|
-
if (item
|
|
1147
|
+
if (item === null) {
|
|
1110
1148
|
continue;
|
|
1111
1149
|
}
|
|
1112
1150
|
if (item instanceof CalcitList || item instanceof CalcitSliceList) {
|
|
@@ -1123,7 +1161,7 @@ export let _$n_list_$o_concat = (...lists: (CalcitList | CalcitSliceList)[]): Ca
|
|
|
1123
1161
|
};
|
|
1124
1162
|
|
|
1125
1163
|
export let _$n_list_$o_reverse = (xs: CalcitList): CalcitList => {
|
|
1126
|
-
if (xs
|
|
1164
|
+
if (xs === null) {
|
|
1127
1165
|
return null;
|
|
1128
1166
|
}
|
|
1129
1167
|
return xs.reverse();
|
|
@@ -1154,12 +1192,12 @@ export let round_$q_ = (a: number) => {
|
|
|
1154
1192
|
};
|
|
1155
1193
|
export let _$n_str_$o_concat = (a: string, b: string) => {
|
|
1156
1194
|
// Optimize string concatenation by avoiding unnecessary toString calls
|
|
1157
|
-
const aStr = a
|
|
1158
|
-
const bStr = b
|
|
1195
|
+
const aStr = a !== null ? toString(a, false) : "";
|
|
1196
|
+
const bStr = b !== null ? toString(b, false) : "";
|
|
1159
1197
|
return aStr + bStr;
|
|
1160
1198
|
};
|
|
1161
1199
|
export let sort = (xs: CalcitList | CalcitSliceList, f: CalcitFn): CalcitSliceList => {
|
|
1162
|
-
if (xs
|
|
1200
|
+
if (xs === null) {
|
|
1163
1201
|
return null;
|
|
1164
1202
|
}
|
|
1165
1203
|
if (xs instanceof CalcitList || xs instanceof CalcitSliceList) {
|
|
@@ -1174,10 +1212,10 @@ export let floor = (n: number): number => {
|
|
|
1174
1212
|
};
|
|
1175
1213
|
|
|
1176
1214
|
export let _$n_merge = (a: CalcitValue, b: CalcitMap | CalcitSliceMap): CalcitValue => {
|
|
1177
|
-
if (a
|
|
1215
|
+
if (a === null) {
|
|
1178
1216
|
return b;
|
|
1179
1217
|
}
|
|
1180
|
-
if (b
|
|
1218
|
+
if (b === null) {
|
|
1181
1219
|
return a;
|
|
1182
1220
|
}
|
|
1183
1221
|
if (a instanceof CalcitMap || a instanceof CalcitSliceMap) {
|
|
@@ -1217,10 +1255,10 @@ export let _$n_merge = (a: CalcitValue, b: CalcitMap | CalcitSliceMap): CalcitVa
|
|
|
1217
1255
|
};
|
|
1218
1256
|
|
|
1219
1257
|
export let _$n_merge_non_nil = (a: CalcitMap | CalcitSliceMap, b: CalcitMap | CalcitSliceMap): CalcitMap | CalcitSliceMap => {
|
|
1220
|
-
if (a
|
|
1258
|
+
if (a === null) {
|
|
1221
1259
|
return b;
|
|
1222
1260
|
}
|
|
1223
|
-
if (b
|
|
1261
|
+
if (b === null) {
|
|
1224
1262
|
return a;
|
|
1225
1263
|
}
|
|
1226
1264
|
if (!(a instanceof CalcitMap || a instanceof CalcitSliceMap)) {
|
|
@@ -1282,7 +1320,7 @@ export let _$n_include = (xs: CalcitSet, y: CalcitValue): CalcitSet => {
|
|
|
1282
1320
|
if (!(xs instanceof CalcitSet)) {
|
|
1283
1321
|
throw new Error("Expected a set");
|
|
1284
1322
|
}
|
|
1285
|
-
if (y
|
|
1323
|
+
if (y === null) {
|
|
1286
1324
|
return xs;
|
|
1287
1325
|
}
|
|
1288
1326
|
return xs.include(y);
|
|
@@ -1292,7 +1330,7 @@ export let _$n_exclude = (xs: CalcitSet, y: CalcitValue): CalcitSet => {
|
|
|
1292
1330
|
if (!(xs instanceof CalcitSet)) {
|
|
1293
1331
|
throw new Error("Expected a set");
|
|
1294
1332
|
}
|
|
1295
|
-
if (y
|
|
1333
|
+
if (y === null) {
|
|
1296
1334
|
return xs;
|
|
1297
1335
|
}
|
|
1298
1336
|
return xs.exclude(y);
|
|
@@ -1423,7 +1461,7 @@ export let aget = (x: any, name: string): any => {
|
|
|
1423
1461
|
export let aset = (x: any, name: string, v: any): any => {
|
|
1424
1462
|
return (x[name] = v);
|
|
1425
1463
|
};
|
|
1426
|
-
export let js_get =
|
|
1464
|
+
export let js_get = (x: any, name: string): any => x[name] ?? null;
|
|
1427
1465
|
export let js_set = aset;
|
|
1428
1466
|
/** generates `delete a.b` */
|
|
1429
1467
|
export let js_delete = (obj: any, name: string): any => {
|
|
@@ -1508,7 +1546,7 @@ export let quit_$x_ = (): void => {
|
|
|
1508
1546
|
};
|
|
1509
1547
|
|
|
1510
1548
|
export let turn_string = (x: CalcitValue): string => {
|
|
1511
|
-
if (x
|
|
1549
|
+
if (x === null) {
|
|
1512
1550
|
return "";
|
|
1513
1551
|
}
|
|
1514
1552
|
if (typeof x === "string") {
|
|
@@ -1551,7 +1589,7 @@ export let ends_with_$q_ = (xs: string, y: string): boolean => {
|
|
|
1551
1589
|
};
|
|
1552
1590
|
|
|
1553
1591
|
export let blank_$q_ = (x: string): boolean => {
|
|
1554
|
-
if (x
|
|
1592
|
+
if (x === null) {
|
|
1555
1593
|
return true;
|
|
1556
1594
|
}
|
|
1557
1595
|
if (typeof x === "string") {
|
|
@@ -1576,7 +1614,7 @@ export let arrayToList = (xs: Array<CalcitValue>): CalcitSliceList => {
|
|
|
1576
1614
|
};
|
|
1577
1615
|
|
|
1578
1616
|
export let listToArray = (xs: CalcitList | CalcitSliceList): Array<CalcitValue> => {
|
|
1579
|
-
if (xs
|
|
1617
|
+
if (xs === null) {
|
|
1580
1618
|
return null;
|
|
1581
1619
|
}
|
|
1582
1620
|
if (xs instanceof CalcitList || xs instanceof CalcitSliceList) {
|
|
@@ -1596,7 +1634,7 @@ export let bool_$q_ = (x: CalcitValue): boolean => {
|
|
|
1596
1634
|
return typeof x === "boolean";
|
|
1597
1635
|
};
|
|
1598
1636
|
export let nil_$q_ = (x: CalcitValue): boolean => {
|
|
1599
|
-
return x
|
|
1637
|
+
return x === null;
|
|
1600
1638
|
};
|
|
1601
1639
|
export let tag_$q_ = (x: CalcitValue): boolean => {
|
|
1602
1640
|
return x instanceof CalcitTag;
|
|
@@ -1676,7 +1714,7 @@ export let parse_cirru_edn = (code: string, options: CalcitValue) => {
|
|
|
1676
1714
|
};
|
|
1677
1715
|
|
|
1678
1716
|
type DataShapeNode =
|
|
1679
|
-
| { kind: "unit" | "bool" | "number" | "string" | "symbol" | "tag" | "buffer" | "cirru-quote" | "dynamic" }
|
|
1717
|
+
| { kind: "nil" | "unit" | "bool" | "number" | "string" | "symbol" | "tag" | "buffer" | "cirru-quote" | "dynamic" }
|
|
1680
1718
|
| { kind: "optional" | "list" | "set" | "ref"; inner: number }
|
|
1681
1719
|
| { kind: "map"; key: number; value: number }
|
|
1682
1720
|
| { kind: "map-option"; nominal: CalcitEnumDef; inner: number }
|
|
@@ -1691,7 +1729,8 @@ type DataShapeGraph = {
|
|
|
1691
1729
|
};
|
|
1692
1730
|
|
|
1693
1731
|
const typed_edn_kind = (value: any): string => {
|
|
1694
|
-
if (value
|
|
1732
|
+
if (value === null) return "nil";
|
|
1733
|
+
if (value === undefined) return "unit";
|
|
1695
1734
|
if (typeof value === "boolean") return "bool";
|
|
1696
1735
|
if (typeof value === "number") return "number";
|
|
1697
1736
|
if (typeof value === "string") return "string";
|
|
@@ -1722,9 +1761,12 @@ const decode_typed_edn_node = (graph: DataShapeGraph, nodeId: number, input: any
|
|
|
1722
1761
|
if (node == null) typed_edn_error(path, `invalid data shape node #${nodeId}`);
|
|
1723
1762
|
|
|
1724
1763
|
switch (node.kind) {
|
|
1764
|
+
case "nil":
|
|
1765
|
+
if (input === null) return null;
|
|
1766
|
+
return typed_edn_error(path, `expected Nil, got ${typed_edn_kind(input)}`);
|
|
1725
1767
|
case "unit":
|
|
1726
|
-
if (input
|
|
1727
|
-
return typed_edn_error(path, `expected
|
|
1768
|
+
if (input === undefined) return input;
|
|
1769
|
+
return typed_edn_error(path, `expected Unit, got ${typed_edn_kind(input)}`);
|
|
1728
1770
|
case "bool":
|
|
1729
1771
|
if (typeof input === "boolean") return input;
|
|
1730
1772
|
return typed_edn_error(path, `expected bool, got ${typed_edn_kind(input)}`);
|
|
@@ -1747,7 +1789,7 @@ const decode_typed_edn_node = (graph: DataShapeGraph, nodeId: number, input: any
|
|
|
1747
1789
|
if (input instanceof CalcitCirruQuote) return input;
|
|
1748
1790
|
return typed_edn_error(path, `expected cirru-quote, got ${typed_edn_kind(input)}`);
|
|
1749
1791
|
case "optional":
|
|
1750
|
-
return input
|
|
1792
|
+
return input === null ? null : decode_typed_edn_node(graph, node.inner, input, path, depth + 1);
|
|
1751
1793
|
case "list": {
|
|
1752
1794
|
if (!(input instanceof CalcitList || input instanceof CalcitSliceList)) {
|
|
1753
1795
|
return typed_edn_error(path, `expected list, got ${typed_edn_kind(input)}`);
|
|
@@ -1816,8 +1858,8 @@ const decode_typed_edn_node = (graph: DataShapeGraph, nodeId: number, input: any
|
|
|
1816
1858
|
const idx = actualNames.indexOf(name);
|
|
1817
1859
|
decodedFields.set(name, decode_typed_edn_node(graph, fieldNode, input.values[idx], `${path}.${name}`, depth + 1));
|
|
1818
1860
|
});
|
|
1819
|
-
//
|
|
1820
|
-
//
|
|
1861
|
+
// Re-align by name so values produced by older runtimes or external data
|
|
1862
|
+
// still adopt the current nominal declaration's canonical field layout.
|
|
1821
1863
|
if (decodedFields.size !== node.nominal.fields.length) {
|
|
1822
1864
|
return typed_edn_error(path, `struct :${node.nominal.name.value} decoder fields do not match its nominal declaration`);
|
|
1823
1865
|
}
|
|
@@ -1863,7 +1905,7 @@ const decode_typed_edn_node = (graph: DataShapeGraph, nodeId: number, input: any
|
|
|
1863
1905
|
|
|
1864
1906
|
export let parse_cirru_edn_as = (code: string, graph: DataShapeGraph): CalcitValue => {
|
|
1865
1907
|
if (typeof code !== "string") throw new Error(`parse-cirru-edn-as expected a string, got ${typed_edn_kind(code)}`);
|
|
1866
|
-
if (graph.version !==
|
|
1908
|
+
if (graph.version !== 2) throw new Error(`parse-cirru-edn-as expected data shape ABI version 2, got ${graph.version}`);
|
|
1867
1909
|
if (typeof graph.fingerprint !== "string" || graph.fingerprint.length === 0) {
|
|
1868
1910
|
throw new Error("parse-cirru-edn-as expected a non-empty data shape fingerprint");
|
|
1869
1911
|
}
|
|
@@ -1974,7 +2016,7 @@ const decode_runtime_map_node = (graph: DataShapeGraph, nodeId: number, input: a
|
|
|
1974
2016
|
return new CalcitSliceMap(entries.flat());
|
|
1975
2017
|
}
|
|
1976
2018
|
case "optional":
|
|
1977
|
-
return input
|
|
2019
|
+
return input === null ? null : decode_runtime_map_node(graph, node.inner, input, path, depth + 1);
|
|
1978
2020
|
case "ref":
|
|
1979
2021
|
if (!(input instanceof CalcitRef)) return map_decode_error(path, `expected atom, got ${typed_edn_kind(input)}`);
|
|
1980
2022
|
return atom(decode_runtime_map_node(graph, node.inner, input.value, `${path}.value`, depth + 1));
|
|
@@ -2007,7 +2049,7 @@ const decode_runtime_map_node = (graph: DataShapeGraph, nodeId: number, input: a
|
|
|
2007
2049
|
};
|
|
2008
2050
|
|
|
2009
2051
|
export let decode_map_as = (value: CalcitValue, graph: DataShapeGraph): CalcitValue => {
|
|
2010
|
-
if (graph.version !==
|
|
2052
|
+
if (graph.version !== 2) throw new Error(`decode-map-as expected data shape ABI version 2, got ${graph.version}`);
|
|
2011
2053
|
if (typeof graph.fingerprint !== "string" || graph.fingerprint.length === 0) {
|
|
2012
2054
|
throw new Error("decode-map-as expected a non-empty data shape fingerprint");
|
|
2013
2055
|
}
|
|
@@ -2045,7 +2087,7 @@ const cirru_quote_to_json = (value: ICirruNode): any => {
|
|
|
2045
2087
|
};
|
|
2046
2088
|
|
|
2047
2089
|
const calcit_to_json = (value: CalcitValue): any => {
|
|
2048
|
-
if (value
|
|
2090
|
+
if (value === null) return null;
|
|
2049
2091
|
if (typeof value === "string") return value;
|
|
2050
2092
|
if (typeof value === "number") {
|
|
2051
2093
|
if (Number.isFinite(value)) return value;
|
|
@@ -2102,8 +2144,10 @@ export let json_pretty = function (value: CalcitValue): string {
|
|
|
2102
2144
|
};
|
|
2103
2145
|
|
|
2104
2146
|
export let format_to_lisp = (x: CalcitValue): string => {
|
|
2105
|
-
if (x
|
|
2147
|
+
if (x === null) {
|
|
2106
2148
|
return "nil";
|
|
2149
|
+
} else if (x === undefined) {
|
|
2150
|
+
return "&unit";
|
|
2107
2151
|
} else if (x instanceof CalcitSymbol) {
|
|
2108
2152
|
return x.value;
|
|
2109
2153
|
} else if (x instanceof CalcitList || x instanceof CalcitSliceList) {
|
|
@@ -2130,8 +2174,10 @@ export let format_to_cirru = (x: CalcitValue): string => {
|
|
|
2130
2174
|
};
|
|
2131
2175
|
|
|
2132
2176
|
export let transform_code_to_cirru = (x: CalcitValue): ICirruNode => {
|
|
2133
|
-
if (x
|
|
2177
|
+
if (x === null) {
|
|
2134
2178
|
return "nil";
|
|
2179
|
+
} else if (x === undefined) {
|
|
2180
|
+
return "&unit";
|
|
2135
2181
|
} else if (x instanceof CalcitSymbol) {
|
|
2136
2182
|
return x.value;
|
|
2137
2183
|
} else if (x instanceof CalcitList || x instanceof CalcitSliceList) {
|
|
@@ -21,9 +21,12 @@ declare global {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
let embedObject = (x: CalcitValue) => {
|
|
24
|
-
if (x
|
|
24
|
+
if (x === null) {
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
|
+
if (x === undefined) {
|
|
28
|
+
return span({ whiteSpace: "pre", color: hsl(240, 70, 50) }, "&unit");
|
|
29
|
+
}
|
|
27
30
|
if (typeof x === "string") {
|
|
28
31
|
return span({ whiteSpace: "pre", color: hsl(120, 70, 50), maxWidth: "100vw" }, `|${x}`);
|
|
29
32
|
}
|
|
@@ -77,16 +80,22 @@ let td = (style: any, ...children: any[]) => {
|
|
|
77
80
|
|
|
78
81
|
/** handle null value in nested data */
|
|
79
82
|
let saveString = (v: CalcitValue) => {
|
|
83
|
+
if (v === null) {
|
|
84
|
+
return "nil";
|
|
85
|
+
}
|
|
86
|
+
if (v === undefined) {
|
|
87
|
+
return "&unit";
|
|
88
|
+
}
|
|
80
89
|
if (typeof v === "string") {
|
|
81
90
|
if (v.match(/[\s\"\n\t\,]/)) {
|
|
82
91
|
return `"|${v}"`;
|
|
83
92
|
} else {
|
|
84
93
|
return `|${v}`;
|
|
85
94
|
}
|
|
86
|
-
} else if (v
|
|
95
|
+
} else if (v.toString) {
|
|
87
96
|
return v.toString();
|
|
88
97
|
} else {
|
|
89
|
-
return
|
|
98
|
+
return String(v);
|
|
90
99
|
}
|
|
91
100
|
};
|
|
92
101
|
|
package/ts-src/js-cirru.mts
CHANGED
|
@@ -6,7 +6,7 @@ import { CalcitList, CalcitSliceList } from "./js-list.mjs";
|
|
|
6
6
|
import { CalcitStructValue } from "./js-struct-value.mjs";
|
|
7
7
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
8
8
|
import { CalcitSet } from "./js-set.mjs";
|
|
9
|
-
import { CalcitTag, CalcitSymbol, CalcitRecur, newTag } from "./calcit-data.mjs";
|
|
9
|
+
import { CalcitTag, CalcitSymbol, CalcitRecur, newTag, compareTagNames } from "./calcit-data.mjs";
|
|
10
10
|
import { CalcitEnumValue } from "./js-enum-value.mjs";
|
|
11
11
|
import { CalcitEnumDef } from "./js-enum-def.mjs";
|
|
12
12
|
import { CalcitImpl } from "./js-impl.mjs";
|
|
@@ -87,9 +87,12 @@ export let format_cirru_one_liner = (data: CalcitCirruQuote | CalcitList): strin
|
|
|
87
87
|
|
|
88
88
|
/** better use string version of Cirru EDN in future */
|
|
89
89
|
export let to_cirru_edn = (x: CalcitValue): CirruEdnFormat => {
|
|
90
|
-
if (x
|
|
90
|
+
if (x === null) {
|
|
91
91
|
return "nil";
|
|
92
92
|
}
|
|
93
|
+
if (x === undefined) {
|
|
94
|
+
throw new Error("Cirru EDN cannot encode &unit");
|
|
95
|
+
}
|
|
93
96
|
if (typeof x === "string") {
|
|
94
97
|
return `|${x}`;
|
|
95
98
|
}
|
|
@@ -352,9 +355,7 @@ const extract_cirru_edn_inner = (x: CirruEdnFormat, options: CalcitValue, preser
|
|
|
352
355
|
throw new Error(`Expected field pairs for struct, got: ${pair}`);
|
|
353
356
|
}
|
|
354
357
|
});
|
|
355
|
-
entries.sort((a, b) =>
|
|
356
|
-
return a[0].cmp(b[0]);
|
|
357
|
-
});
|
|
358
|
+
entries.sort((a, b) => compareTagNames(a[0], b[0]));
|
|
358
359
|
let fields: Array<CalcitTag> = [];
|
|
359
360
|
let values: Array<CalcitValue> = [];
|
|
360
361
|
|
package/ts-src/js-impl.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hash } from "@calcit/ternary-tree";
|
|
2
2
|
import { CalcitValue } from "./js-primes.mjs";
|
|
3
|
-
import { CalcitTag, castTag, findInFields, toString } from "./calcit-data.mjs";
|
|
3
|
+
import { CalcitTag, canonicalizeTagPairs, castTag, findInFields, toString } from "./calcit-data.mjs";
|
|
4
4
|
import type { CalcitTrait } from "./js-trait.mjs";
|
|
5
5
|
|
|
6
6
|
const CALCIT_IMPL_BRAND = Symbol.for("@calcit/procs/CalcitImpl");
|
|
@@ -44,10 +44,11 @@ export class CalcitImpl {
|
|
|
44
44
|
// optimized dependencies. A global, non-enumerable brand keeps impl values
|
|
45
45
|
// recognizable across those otherwise distinct module instances.
|
|
46
46
|
Object.defineProperty(this, CALCIT_IMPL_BRAND, { value: true });
|
|
47
|
+
const [canonicalFields, canonicalValues] = canonicalizeTagPairs(fields, values, "CalcitImpl");
|
|
47
48
|
this.name = name;
|
|
48
49
|
this.origin = origin;
|
|
49
|
-
this.fields =
|
|
50
|
-
this.values =
|
|
50
|
+
this.fields = canonicalFields;
|
|
51
|
+
this.values = canonicalValues;
|
|
51
52
|
this.cachedHash = null;
|
|
52
53
|
}
|
|
53
54
|
|
package/ts-src/js-primes.mts
CHANGED
|
@@ -32,6 +32,7 @@ export type CalcitValue =
|
|
|
32
32
|
| CalcitStructDef
|
|
33
33
|
| CalcitEnumDef
|
|
34
34
|
| CalcitCirruQuote
|
|
35
|
+
| undefined
|
|
35
36
|
| null;
|
|
36
37
|
|
|
37
38
|
export let isLiteral = (x: CalcitValue): boolean => {
|
|
@@ -46,6 +47,7 @@ export let isLiteral = (x: CalcitValue): boolean => {
|
|
|
46
47
|
|
|
47
48
|
enum PseudoTypeIndex {
|
|
48
49
|
nil,
|
|
50
|
+
unit,
|
|
49
51
|
bool,
|
|
50
52
|
number,
|
|
51
53
|
symbol,
|
|
@@ -67,7 +69,8 @@ enum PseudoTypeIndex {
|
|
|
67
69
|
|
|
68
70
|
let typeAsInt = (x: CalcitValue): number => {
|
|
69
71
|
// based on order used in Ord trait
|
|
70
|
-
if (x
|
|
72
|
+
if (x === null) return PseudoTypeIndex.nil;
|
|
73
|
+
if (x === undefined) return PseudoTypeIndex.unit;
|
|
71
74
|
let t = typeof x;
|
|
72
75
|
if (t === "boolean") return PseudoTypeIndex.bool;
|
|
73
76
|
if (t === "number") return PseudoTypeIndex.number;
|
|
@@ -107,6 +110,7 @@ export let _$n_compare = (a: CalcitValue, b: CalcitValue): number => {
|
|
|
107
110
|
if (ta === tb) {
|
|
108
111
|
switch (ta) {
|
|
109
112
|
case PseudoTypeIndex.nil:
|
|
113
|
+
case PseudoTypeIndex.unit:
|
|
110
114
|
return 0;
|
|
111
115
|
case PseudoTypeIndex.bool:
|
|
112
116
|
return rawCompare(a, b);
|
package/ts-src/js-struct-def.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CalcitTag, toString } from "./calcit-data.mjs";
|
|
1
|
+
import { CalcitTag, canonicalizeTagPairs, toString } from "./calcit-data.mjs";
|
|
2
2
|
import { CalcitValue } from "./js-primes.mjs";
|
|
3
3
|
import { CalcitImpl } from "./js-impl.mjs";
|
|
4
4
|
|
|
@@ -10,12 +10,10 @@ export class CalcitStructDef {
|
|
|
10
10
|
cachedHash: number;
|
|
11
11
|
|
|
12
12
|
constructor(name: CalcitTag, fields: CalcitTag[], fieldTypes: CalcitValue[], impls: CalcitImpl[] = []) {
|
|
13
|
-
|
|
14
|
-
throw new Error("CalcitStructDef: fields and fieldTypes length mismatch");
|
|
15
|
-
}
|
|
13
|
+
const [canonicalFields, canonicalTypes] = canonicalizeTagPairs(fields, fieldTypes, "CalcitStructDef");
|
|
16
14
|
this.name = name;
|
|
17
|
-
this.fields =
|
|
18
|
-
this.fieldTypes =
|
|
15
|
+
this.fields = canonicalFields;
|
|
16
|
+
this.fieldTypes = canonicalTypes;
|
|
19
17
|
this.impls = impls;
|
|
20
18
|
this.cachedHash = null;
|
|
21
19
|
}
|