@nudojs/core 0.3.0 → 0.3.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.
Files changed (123) hide show
  1. package/dist/chunk-BU4A6XJ3.js +6856 -0
  2. package/dist/exec.d.ts +2 -0
  3. package/dist/exec.js +168 -0
  4. package/dist/index-CVYjXnwU.d.ts +902 -0
  5. package/dist/index.d.ts +64 -710
  6. package/dist/index.js +3258 -8426
  7. package/package.json +18 -5
  8. package/CHANGELOG.md +0 -34
  9. package/src/__tests__/environment.test.ts +0 -48
  10. package/src/__tests__/fn-sig-impl.test.ts +0 -57
  11. package/src/__tests__/ops-refined.test.ts +0 -196
  12. package/src/__tests__/ops.test.ts +0 -84
  13. package/src/__tests__/type-value-phase2.test.ts +0 -117
  14. package/src/__tests__/type-value-phase3.test.ts +0 -94
  15. package/src/__tests__/type-value-refined.test.ts +0 -210
  16. package/src/__tests__/type-value.test.ts +0 -319
  17. package/src/algebra/__tests__/abs-native.test.ts +0 -176
  18. package/src/algebra/__tests__/arithmetic.test.ts +0 -170
  19. package/src/algebra/__tests__/ast-eval.test.ts +0 -154
  20. package/src/algebra/__tests__/bridge.test.ts +0 -160
  21. package/src/algebra/__tests__/call-budget.test.ts +0 -117
  22. package/src/algebra/__tests__/check-case-consistency.test.ts +0 -69
  23. package/src/algebra/__tests__/check-gold.test.ts +0 -290
  24. package/src/algebra/__tests__/check-json.test.ts +0 -57
  25. package/src/algebra/__tests__/check-mini-repo.test.ts +0 -49
  26. package/src/algebra/__tests__/check-real-commander.test.ts +0 -43
  27. package/src/algebra/__tests__/check-real-packages.test.ts +0 -165
  28. package/src/algebra/__tests__/check-recall-gold.test.ts +0 -1024
  29. package/src/algebra/__tests__/check-require-dep-memo.test.ts +0 -45
  30. package/src/algebra/__tests__/check-return-contract.test.ts +0 -90
  31. package/src/algebra/__tests__/check-shape-gold.test.ts +0 -303
  32. package/src/algebra/__tests__/check-source-memo.test.ts +0 -204
  33. package/src/algebra/__tests__/check.test.ts +0 -69
  34. package/src/algebra/__tests__/denote.test.ts +0 -77
  35. package/src/algebra/__tests__/diagnostics.test.ts +0 -64
  36. package/src/algebra/__tests__/differential.test.ts +0 -124
  37. package/src/algebra/__tests__/div-mod.test.ts +0 -38
  38. package/src/algebra/__tests__/example0.test.ts +0 -103
  39. package/src/algebra/__tests__/exec-analyze-throws.test.ts +0 -60
  40. package/src/algebra/__tests__/exec-async.test.ts +0 -46
  41. package/src/algebra/__tests__/exec-bpath.test.ts +0 -193
  42. package/src/algebra/__tests__/exec-class.test.ts +0 -56
  43. package/src/algebra/__tests__/exec-e2e.test.ts +0 -97
  44. package/src/algebra/__tests__/exec-generator.test.ts +0 -53
  45. package/src/algebra/__tests__/exec-inherit-default.test.ts +0 -111
  46. package/src/algebra/__tests__/exec-optional-nested.test.ts +0 -87
  47. package/src/algebra/__tests__/exec-rest.test.ts +0 -55
  48. package/src/algebra/__tests__/exec-spread-forof.test.ts +0 -85
  49. package/src/algebra/__tests__/exec-static-computed.test.ts +0 -61
  50. package/src/algebra/__tests__/exec-switch.test.ts +0 -74
  51. package/src/algebra/__tests__/exec-trycatch.test.ts +0 -71
  52. package/src/algebra/__tests__/fn-fp-memo.test.ts +0 -166
  53. package/src/algebra/__tests__/fn-fp-multidecl.test.ts +0 -49
  54. package/src/algebra/__tests__/format.test.ts +0 -34
  55. package/src/algebra/__tests__/generalize-memo.test.ts +0 -285
  56. package/src/algebra/__tests__/generalize.test.ts +0 -113
  57. package/src/algebra/__tests__/hash-source.test.ts +0 -19
  58. package/src/algebra/__tests__/hof.test.ts +0 -80
  59. package/src/algebra/__tests__/inlay.test.ts +0 -30
  60. package/src/algebra/__tests__/language.test.ts +0 -77
  61. package/src/algebra/__tests__/leq.test.ts +0 -109
  62. package/src/algebra/__tests__/load-deps-fp-memo.test.ts +0 -132
  63. package/src/algebra/__tests__/methods.test.ts +0 -37
  64. package/src/algebra/__tests__/node-types.test.ts +0 -26
  65. package/src/algebra/__tests__/nudo-constraints.ts +0 -46
  66. package/src/algebra/__tests__/objects.test.ts +0 -117
  67. package/src/algebra/__tests__/parse-source-cache.test.ts +0 -42
  68. package/src/algebra/__tests__/refine-import.test.ts +0 -109
  69. package/src/algebra/__tests__/stable-source-key-block.test.ts +0 -23
  70. package/src/algebra/__tests__/stable-source-key.test.ts +0 -31
  71. package/src/algebra/__tests__/surface.test.ts +0 -41
  72. package/src/algebra/__tests__/this-inherit.test.ts +0 -130
  73. package/src/algebra/abs-fn.ts +0 -49
  74. package/src/algebra/abs-modules.ts +0 -139
  75. package/src/algebra/abs.ts +0 -206
  76. package/src/algebra/arithmetic.ts +0 -691
  77. package/src/algebra/ast-eval.ts +0 -1763
  78. package/src/algebra/bridge.ts +0 -350
  79. package/src/algebra/builtins.ts +0 -373
  80. package/src/algebra/check-report.ts +0 -150
  81. package/src/algebra/check.ts +0 -1867
  82. package/src/algebra/constraint.ts +0 -304
  83. package/src/algebra/denote.ts +0 -166
  84. package/src/algebra/diagnostics.ts +0 -210
  85. package/src/algebra/exec/call.ts +0 -29
  86. package/src/algebra/exec/calls.ts +0 -96
  87. package/src/algebra/exec/class-registry.ts +0 -29
  88. package/src/algebra/exec/class.ts +0 -329
  89. package/src/algebra/exec/index.ts +0 -6
  90. package/src/algebra/exec/member-diag.ts +0 -141
  91. package/src/algebra/exec/run.ts +0 -341
  92. package/src/algebra/exec/runtime.ts +0 -583
  93. package/src/algebra/exec/transpile.ts +0 -993
  94. package/src/algebra/fn-fp.ts +0 -294
  95. package/src/algebra/format.ts +0 -91
  96. package/src/algebra/generalize.ts +0 -776
  97. package/src/algebra/hash-source.ts +0 -27
  98. package/src/algebra/index.ts +0 -34
  99. package/src/algebra/inlay.ts +0 -198
  100. package/src/algebra/language.ts +0 -289
  101. package/src/algebra/leak.ts +0 -68
  102. package/src/algebra/leq.ts +0 -301
  103. package/src/algebra/load-deps-fp.ts +0 -97
  104. package/src/algebra/methods.ts +0 -128
  105. package/src/algebra/objects.ts +0 -251
  106. package/src/algebra/parse-source.ts +0 -64
  107. package/src/algebra/phi.ts +0 -42
  108. package/src/algebra/pred.ts +0 -395
  109. package/src/algebra/refine.ts +0 -227
  110. package/src/algebra/stable-source-key.ts +0 -81
  111. package/src/algebra/surface.ts +0 -206
  112. package/src/algebra/template.ts +0 -143
  113. package/src/algebra/term.ts +0 -119
  114. package/src/environment.ts +0 -74
  115. package/src/index.ts +0 -73
  116. package/src/mock-helpers.ts +0 -166
  117. package/src/ops.ts +0 -191
  118. package/src/refinements/range.ts +0 -86
  119. package/src/refinements/template-predicates.ts +0 -11
  120. package/src/refinements/template.ts +0 -176
  121. package/src/strip-types.ts +0 -236
  122. package/src/type-value.ts +0 -513
  123. package/tsconfig.json +0 -8
package/src/type-value.ts DELETED
@@ -1,513 +0,0 @@
1
- import type { Node } from "@babel/types";
2
- import type { Environment } from "./environment.ts";
3
- // 注意:isTemplate 必须来自 template-predicates.ts(只含 `import type` 反向边)
4
- // 而非 template.ts——后者运行时依赖本模块(T、typeValueToString),会构成环。
5
- import { isTemplate } from "./refinements/template-predicates.ts";
6
-
7
- // --- 评估 IR:不是类型系统本体,是 Abs 的外延投影格式 ---
8
-
9
- export type LiteralValue = string | number | boolean | bigint | null | undefined;
10
-
11
- // `thisVal` is the bound receiver when the signature is invoked as a method
12
- // or through Function.prototype.call/apply (e.g. Object.prototype.toString
13
- // brand computation needs it); direct calls leave it undefined.
14
- export type SigImpl = (args: TypeValue[], thisVal?: TypeValue) => TypeValue | undefined;
15
-
16
- export type FunctionSignature = {
17
- paramTypes: TypeValue[];
18
- returnType: TypeValue;
19
- throwsType: TypeValue;
20
- impl?: SigImpl;
21
- };
22
-
23
- export type Refinement = {
24
- name: string;
25
- meta: Record<string, unknown>;
26
- check?: (value: unknown) => boolean;
27
- ops?: Record<string, (self: TypeValue, other: TypeValue) => TypeValue | undefined>;
28
- methods?: Record<string, (self: TypeValue, args: TypeValue[]) => TypeValue | undefined>;
29
- properties?: Record<string, (self: TypeValue) => TypeValue | undefined>;
30
- };
31
-
32
- export type TypeValue =
33
- | { kind: "literal"; value: LiteralValue }
34
- | {
35
- kind: "primitive";
36
- type: "number" | "string" | "boolean" | "bigint" | "symbol";
37
- }
38
- | { kind: "refined"; base: TypeValue; refinement: Refinement }
39
- | { kind: "object"; properties: Record<string, TypeValue>; id: symbol }
40
- | { kind: "array"; element: TypeValue }
41
- | { kind: "tuple"; elements: TypeValue[] }
42
- | {
43
- kind: "function";
44
- params: string[];
45
- body: Node;
46
- closure: Environment;
47
- }
48
- | { kind: "promise"; value: TypeValue }
49
- | { kind: "instance"; className: string; properties: Record<string, TypeValue> }
50
- | { kind: "union"; members: TypeValue[] }
51
- | { kind: "never" }
52
- | { kind: "unknown" };
53
-
54
- // --- T: static factory ---
55
-
56
- function createUnion(...members: TypeValue[]): TypeValue {
57
- return simplifyUnion(members);
58
- }
59
-
60
- export const T = {
61
- literal: (value: LiteralValue): TypeValue => ({ kind: "literal", value }),
62
- number: { kind: "primitive", type: "number" } as TypeValue,
63
- string: { kind: "primitive", type: "string" } as TypeValue,
64
- boolean: { kind: "primitive", type: "boolean" } as TypeValue,
65
- bigint: { kind: "primitive", type: "bigint" } as TypeValue,
66
- symbol: { kind: "primitive", type: "symbol" } as TypeValue,
67
- null: { kind: "literal", value: null } as TypeValue,
68
- undefined: { kind: "literal", value: undefined } as TypeValue,
69
- unknown: { kind: "unknown" } as TypeValue,
70
- never: { kind: "never" } as TypeValue,
71
-
72
- object: (properties: Record<string, TypeValue>): TypeValue => ({
73
- kind: "object",
74
- properties,
75
- id: Symbol("object"),
76
- }),
77
- array: (element: TypeValue): TypeValue => ({ kind: "array", element }),
78
- tuple: (elements: TypeValue[]): TypeValue => ({ kind: "tuple", elements }),
79
- promise: (value: TypeValue): TypeValue => ({ kind: "promise", value }),
80
- instanceOf: (className: string, properties: Record<string, TypeValue> = {}): TypeValue => ({
81
- kind: "instance",
82
- className,
83
- properties,
84
- }),
85
- union: createUnion,
86
- fn: (
87
- params: string[],
88
- body: Node,
89
- closure: Environment,
90
- ): TypeValue => ({
91
- kind: "function",
92
- params,
93
- body,
94
- closure,
95
- }),
96
- refine: (base: TypeValue, refinement: Refinement): TypeValue => ({
97
- kind: "refined",
98
- base,
99
- refinement,
100
- }),
101
- fnSig: (
102
- paramTypes: TypeValue[],
103
- returnType: TypeValue,
104
- throwsType: TypeValue = { kind: "never" },
105
- impl?: SigImpl,
106
- ): TypeValue => {
107
- const dummy = {
108
- kind: "function" as const,
109
- params: paramTypes.map((_p, i) => `_arg${i}`),
110
- body: { type: "BlockStatement", body: [], directives: [] } as unknown as Node,
111
- closure: null as unknown as Environment,
112
- };
113
- (dummy as any)._signature = { paramTypes, returnType, throwsType, impl } satisfies FunctionSignature;
114
- return dummy;
115
- },
116
- } as const;
117
-
118
- // --- Helpers ---
119
-
120
- export function typeValueEquals(a: TypeValue, b: TypeValue): boolean {
121
- if (a.kind !== b.kind) return false;
122
- if (a.kind === "literal" && b.kind === "literal") return a.value === b.value;
123
- if (a.kind === "primitive" && b.kind === "primitive") return a.type === b.type;
124
- if (a.kind === "never" && b.kind === "never") return true;
125
- if (a.kind === "unknown" && b.kind === "unknown") return true;
126
- if (a.kind === "refined" && b.kind === "refined") {
127
- return a.refinement.name === b.refinement.name && typeValueEquals(a.base, b.base);
128
- }
129
- if (a.kind === "promise" && b.kind === "promise") {
130
- return typeValueEquals(a.value, b.value);
131
- }
132
- if (a.kind === "instance" && b.kind === "instance") {
133
- return a.className === b.className;
134
- }
135
- if (a.kind === "union" && b.kind === "union") {
136
- return (
137
- a.members.length === b.members.length &&
138
- a.members.every((m, i) => typeValueEquals(m, b.members[i]))
139
- );
140
- }
141
- return a === b;
142
- }
143
-
144
- export function simplifyUnion(members: TypeValue[]): TypeValue {
145
- // Fast path: empty or single element
146
- if (members.length === 0) return T.never;
147
- if (members.length === 1) return members[0].kind === "never" ? T.never : members[0];
148
-
149
- // Fast path: two non-union elements, check equality first
150
- if (members.length === 2) {
151
- const a = members[0];
152
- const b = members[1];
153
- // Only use fast path if neither is a union (need flattening)
154
- if (a.kind !== "union" && b.kind !== "union") {
155
- if (a.kind === "never") return b.kind === "never" ? T.never : b;
156
- if (b.kind === "never") return a;
157
- if (typeValueEquals(a, b)) return a;
158
- if (a.kind === "unknown" || b.kind === "unknown") return T.unknown;
159
- // 吸收律:字面量被共存的 widening 基类型吸收(3 | number → number)
160
- const aBase = absorbablePrimitiveBase(a);
161
- if (aBase !== undefined && typeValueEquals(aBase, b)) return b;
162
- const bBase = absorbablePrimitiveBase(b);
163
- if (bBase !== undefined && typeValueEquals(bBase, a)) return a;
164
- return { kind: "union", members: [a, b] };
165
- }
166
- }
167
-
168
- const flat: TypeValue[] = [];
169
- for (const m of members) {
170
- if (m.kind === "never") continue;
171
- if (m.kind === "union") {
172
- flat.push(...m.members);
173
- } else {
174
- flat.push(m);
175
- }
176
- }
177
-
178
- const deduped: TypeValue[] = [];
179
- for (const m of flat) {
180
- if (!deduped.some((d) => typeValueEquals(d, m))) {
181
- deduped.push(m);
182
- }
183
- }
184
-
185
- // 吸收律:成员中存在某字面量/模板字面量的 widening 基类型(非字面量
186
- // number/string/boolean/bigint)时,删去该字面量成员(3 | number → number、
187
- // "a" | string → string)。不同基底(1 | "a")、纯字面量联合("a" | "b")、
188
- // null/undefined 字面量不受影响;filter 保序,成员顺序稳定。
189
- const primitives = deduped.filter((m) => m.kind === "primitive");
190
- const absorbed =
191
- primitives.length > 0
192
- ? deduped.filter((m) => {
193
- const base = absorbablePrimitiveBase(m);
194
- return base === undefined || !primitives.some((p) => typeValueEquals(p, base));
195
- })
196
- : deduped;
197
-
198
- if (absorbed.length === 0) return T.never;
199
- if (absorbed.length === 1) return absorbed[0];
200
- if (absorbed.some((m) => m.kind === "unknown")) return T.unknown;
201
- return { kind: "union", members: absorbed };
202
- }
203
-
204
- /**
205
- * 吸收律辅助:返回 tv 可被吸收进的原语基类型(number/string/boolean/bigint)。
206
- * 仅数字/字符串/布尔/bigint 字面量与模板字面量(refined over T.string)有值;
207
- * null/undefined 字面量 widen 后仍是字面量、基类型原语与其余类型不参与吸收
208
- * (基类型自身不能被自己吸收,否则纯原语联合 number | string 会被误删)。
209
- */
210
- function absorbablePrimitiveBase(tv: TypeValue): TypeValue | undefined {
211
- if (tv.kind === "literal") {
212
- const widened = widenLiteral(tv);
213
- return widened.kind === "primitive" ? widened : undefined;
214
- }
215
- if (isTemplate(tv)) return T.string;
216
- return undefined;
217
- }
218
-
219
- export function widenLiteral(tv: TypeValue): TypeValue {
220
- if (tv.kind !== "literal") return tv;
221
- const v = tv.value;
222
- if (typeof v === "number") return T.number;
223
- if (typeof v === "string") return T.string;
224
- if (typeof v === "boolean") return T.boolean;
225
- // 吸收律要求 bigint 字面量能 widen 到 T.bigint
226
- if (typeof v === "bigint") return T.bigint;
227
- if (v === null) return T.null;
228
- if (v === undefined) return T.undefined;
229
- return T.unknown;
230
- }
231
-
232
- /**
233
- * union 成员全部为同原语基底的字面量且数量 > maxLiterals 时塌缩为该基类型;
234
- * 非 union、混合类型、或数量不超限的原样返回。
235
- *
236
- * 复用 simplifyUnion(内含吸收律与去重):先让「基类型已在场」的字面量被吸收
237
- * (3 | number → number),再对剩余的纯字面量联合做阈值坍缩(1|2|…|20 → number)。
238
- * 两步不冲突也不重复:吸收只删基类型已在场的字面量,阈值坍缩只处理无基类型
239
- * 在场的纯字面量联合。
240
- */
241
- export function collapseLiteralUnion(tv: TypeValue, maxLiterals: number): TypeValue {
242
- if (tv.kind !== "union") return tv;
243
- if (tv.members.length <= maxLiterals) return tv;
244
- const simplified = simplifyUnion(tv.members);
245
- if (simplified.kind !== "union") return simplified;
246
- // 保守:成员中含非字面量(如显式 T.number 未吸收掉的异构成员)时不塌缩
247
- if (!simplified.members.every((m) => m.kind === "literal")) return simplified;
248
- const first = widenLiteral(simplified.members[0]);
249
- if (!simplified.members.every((m) => typeValueEquals(widenLiteral(m), first))) return simplified;
250
- return first;
251
- }
252
-
253
- export function isSubtypeOf(a: TypeValue, b: TypeValue): boolean {
254
- if (b.kind === "unknown") return true;
255
- if (a.kind === "never") return true;
256
- if (typeValueEquals(a, b)) return true;
257
-
258
- if (a.kind === "literal" && b.kind === "primitive") {
259
- const v = a.value;
260
- if (b.type === "number" && typeof v === "number") return true;
261
- if (b.type === "string" && typeof v === "string") return true;
262
- if (b.type === "boolean" && typeof v === "boolean") return true;
263
- return false;
264
- }
265
-
266
- if (a.kind === "literal" && b.kind === "refined") {
267
- if (!isSubtypeOf(a, b.base)) return false;
268
- return b.refinement.check ? b.refinement.check(a.value) : false;
269
- }
270
-
271
- if (a.kind === "refined") {
272
- if (b.kind === "refined" && a.refinement.name === b.refinement.name) {
273
- return isSubtypeOf(a.base, b.base);
274
- }
275
- return isSubtypeOf(a.base, b);
276
- }
277
-
278
- if (a.kind === "object" && b.kind === "object") {
279
- return Object.entries(b.properties).every(
280
- ([k, bv]) => k in a.properties && isSubtypeOf(a.properties[k], bv),
281
- );
282
- }
283
-
284
- if (a.kind === "array" && b.kind === "array") {
285
- return isSubtypeOf(a.element, b.element);
286
- }
287
-
288
- if (a.kind === "tuple" && b.kind === "tuple") {
289
- return (
290
- a.elements.length === b.elements.length &&
291
- a.elements.every((el, i) => isSubtypeOf(el, b.elements[i]))
292
- );
293
- }
294
-
295
- if (a.kind === "tuple" && b.kind === "array") {
296
- return a.elements.every((el) => isSubtypeOf(el, b.element));
297
- }
298
-
299
- if (a.kind === "promise" && b.kind === "promise") {
300
- return isSubtypeOf(a.value, b.value);
301
- }
302
-
303
- if (a.kind === "instance" && b.kind === "instance") {
304
- return a.className === b.className || isErrorSubclass(a.className, b.className);
305
- }
306
-
307
- if (a.kind === "union") {
308
- return a.members.every((m) => isSubtypeOf(m, b));
309
- }
310
-
311
- if (b.kind === "union") {
312
- return b.members.some((m) => isSubtypeOf(a, m));
313
- }
314
-
315
- return false;
316
- }
317
-
318
- const errorHierarchy: Record<string, string> = {
319
- TypeError: "Error",
320
- SyntaxError: "Error",
321
- RangeError: "Error",
322
- ReferenceError: "Error",
323
- URIError: "Error",
324
- EvalError: "Error",
325
- };
326
-
327
- function isErrorSubclass(child: string, parent: string): boolean {
328
- if (child === parent) return true;
329
- const sup = errorHierarchy[child];
330
- return sup ? isErrorSubclass(sup, parent) : false;
331
- }
332
-
333
- export function deepCloneTypeValue(tv: TypeValue, idMap?: Map<symbol, symbol>): TypeValue {
334
- const map = idMap ?? new Map<symbol, symbol>();
335
- if (tv.kind === "object") {
336
- let newId = map.get(tv.id);
337
- if (!newId) {
338
- newId = Symbol("object");
339
- map.set(tv.id, newId);
340
- }
341
- const newProps: Record<string, TypeValue> = {};
342
- for (const [k, v] of Object.entries(tv.properties)) {
343
- newProps[k] = deepCloneTypeValue(v, map);
344
- }
345
- return { kind: "object", properties: newProps, id: newId };
346
- }
347
- if (tv.kind === "array") {
348
- return { kind: "array", element: deepCloneTypeValue(tv.element, map) };
349
- }
350
- if (tv.kind === "tuple") {
351
- return { kind: "tuple", elements: tv.elements.map((e) => deepCloneTypeValue(e, map)) };
352
- }
353
- if (tv.kind === "promise") {
354
- return { kind: "promise", value: deepCloneTypeValue(tv.value, map) };
355
- }
356
- if (tv.kind === "instance") {
357
- const newProps: Record<string, TypeValue> = {};
358
- for (const [k, v] of Object.entries(tv.properties)) {
359
- newProps[k] = deepCloneTypeValue(v, map);
360
- }
361
- return { kind: "instance", className: tv.className, properties: newProps };
362
- }
363
- if (tv.kind === "refined") {
364
- return { kind: "refined", base: deepCloneTypeValue(tv.base, map), refinement: tv.refinement };
365
- }
366
- if (tv.kind === "union") {
367
- return simplifyUnion(tv.members.map((m) => deepCloneTypeValue(m, map)));
368
- }
369
- return tv;
370
- }
371
-
372
- export function mergeObjectProperties(
373
- a: TypeValue & { kind: "object" },
374
- b: TypeValue & { kind: "object" },
375
- ): TypeValue {
376
- const allKeys = new Set([...Object.keys(a.properties), ...Object.keys(b.properties)]);
377
- const merged: Record<string, TypeValue> = {};
378
- for (const k of allKeys) {
379
- const av = a.properties[k];
380
- const bv = b.properties[k];
381
- if (av && bv) {
382
- merged[k] = simplifyUnion([av, bv]);
383
- } else {
384
- merged[k] = av ?? bv;
385
- }
386
- }
387
- return { kind: "object", properties: merged, id: a.id };
388
- }
389
-
390
- export function typeValueToString(tv: TypeValue): string {
391
- // Self-referential structures (x.y = x surviving a clone) would recurse
392
- // infinitely: a seen-set renders revisits as an ellipsis token.
393
- return typeValueToStringInner(tv, new Set());
394
- }
395
-
396
- function typeValueToStringInner(tv: TypeValue, seen: Set<object>, depth = 0): string {
397
- // Path-scoped seen-set: a node renders "…" only while its own expansion
398
- // is on the stack (a true cycle); shared singletons (T.number in two
399
- // slots) still render in full. A depth cap bounds fixture-scale DAGs
400
- // whose repeated shared substructure would otherwise explode the string.
401
- if (depth > 48) return "…";
402
- const recur = (inner: TypeValue): string => {
403
- if (inner && typeof inner === "object") {
404
- if (seen.has(inner)) return "…";
405
- seen.add(inner);
406
- const out = typeValueToStringInner(inner, seen, depth + 1);
407
- seen.delete(inner);
408
- return out;
409
- }
410
- return typeValueToStringInner(inner, seen, depth + 1);
411
- };
412
- switch (tv.kind) {
413
- case "literal": {
414
- const v = tv.value;
415
- if (v === null) return "null";
416
- if (v === undefined) return "undefined";
417
- if (typeof v === "string") return JSON.stringify(v);
418
- return String(v);
419
- }
420
- case "primitive":
421
- return tv.type;
422
- case "refined":
423
- return tv.refinement.name;
424
- case "object": {
425
- const entries = Object.entries(tv.properties);
426
- if (entries.length === 0) return "{}";
427
- const inner = entries
428
- .map(([k, v]) => `${k}: ${recur(v)}`)
429
- .join(", ");
430
- return `{ ${inner} }`;
431
- }
432
- case "array":
433
- return `${recur(tv.element)}[]`;
434
- case "tuple": {
435
- const inner = tv.elements.map(recur).join(", ");
436
- return `[${inner}]`;
437
- }
438
- case "function": {
439
- const sig = getFnSig(tv);
440
- if (sig) {
441
- const params = sig.paramTypes.map((p, i) => `${tv.params[i]}: ${recur(p)}`).join(", ");
442
- return `(${params}) => ${recur(sig.returnType)}`;
443
- }
444
- const params = tv.params.join(", ");
445
- return `(${params}) => ...`;
446
- }
447
- case "promise":
448
- return `Promise<${recur(tv.value)}>`;
449
- case "instance": {
450
- const entries = Object.entries(tv.properties);
451
- if (entries.length === 0) return tv.className;
452
- const inner = entries
453
- .map(([k, v]) => `${k}: ${recur(v)}`)
454
- .join(", ");
455
- return `${tv.className} { ${inner} }`;
456
- }
457
- case "union": {
458
- return tv.members.map(recur).join(" | ");
459
- }
460
- case "never":
461
- return "never";
462
- case "unknown":
463
- return "unknown";
464
- }
465
- }
466
-
467
- export function narrowType(
468
- tv: TypeValue,
469
- predicate: (member: TypeValue) => boolean,
470
- ): TypeValue {
471
- if (tv.kind === "union") {
472
- return simplifyUnion(tv.members.filter(predicate));
473
- }
474
- return predicate(tv) ? tv : T.never;
475
- }
476
-
477
- export function subtractType(
478
- tv: TypeValue,
479
- predicate: (member: TypeValue) => boolean,
480
- ): TypeValue {
481
- return narrowType(tv, (m) => !predicate(m));
482
- }
483
-
484
- export function getPrimitiveTypeOf(tv: TypeValue): string | undefined {
485
- if (tv.kind === "literal") {
486
- const v = tv.value;
487
- if (v === null) return "object";
488
- return typeof v;
489
- }
490
- if (tv.kind === "primitive") return tv.type;
491
- if (tv.kind === "refined") return getPrimitiveTypeOf(tv.base);
492
- if (tv.kind === "object") return "object";
493
- if (tv.kind === "array" || tv.kind === "tuple") return "object";
494
- if (tv.kind === "function") return "function";
495
- if (tv.kind === "promise") return "object";
496
- if (tv.kind === "instance") return "object";
497
- return undefined;
498
- }
499
-
500
- export function getRefinedBase(tv: TypeValue): TypeValue {
501
- return tv.kind === "refined" ? getRefinedBase(tv.base) : tv;
502
- }
503
-
504
- export function isFnSig(tv: TypeValue): boolean {
505
- return tv.kind === "function" && "_signature" in tv;
506
- }
507
-
508
- export function getFnSig(tv: TypeValue): FunctionSignature | undefined {
509
- if (tv.kind === "function" && "_signature" in tv) {
510
- return (tv as any)._signature as FunctionSignature;
511
- }
512
- return undefined;
513
- }
package/tsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src"
6
- },
7
- "include": ["src"]
8
- }