tjs-lang 0.6.45 → 0.7.4

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 (95) hide show
  1. package/CLAUDE.md +70 -444
  2. package/README.md +15 -82
  3. package/bin/benchmarks.ts +7 -7
  4. package/bin/dev.ts +2 -1
  5. package/demo/autocomplete.test.ts +1 -1
  6. package/demo/docs.json +743 -47
  7. package/demo/src/demo-nav.ts +5 -5
  8. package/demo/src/index.ts +28 -36
  9. package/demo/src/module-sw.ts +1 -1
  10. package/demo/src/playground-shared.ts +17 -17
  11. package/demo/src/playground.ts +13 -1
  12. package/demo/src/style.ts +4 -1
  13. package/demo/src/tjs-playground.ts +5 -5
  14. package/demo/src/user-store.ts +2 -1
  15. package/demo/static/favicon.svg +17 -24
  16. package/demo/static/tosi-platform.json +9304 -0
  17. package/dist/index.js +176 -175
  18. package/dist/index.js.map +5 -43
  19. package/dist/scripts/compat-effect.d.ts +16 -0
  20. package/dist/scripts/compat-kysely.d.ts +13 -0
  21. package/dist/scripts/compat-radash.d.ts +13 -0
  22. package/dist/scripts/compat-superstruct.d.ts +13 -0
  23. package/dist/scripts/compat-ts-pattern.d.ts +13 -0
  24. package/dist/scripts/compat-zod.d.ts +12 -0
  25. package/dist/src/lang/emitters/from-ts.d.ts +1 -1
  26. package/dist/src/lang/emitters/js-tests.d.ts +4 -0
  27. package/dist/src/lang/emitters/js.d.ts +2 -2
  28. package/dist/src/lang/index.d.ts +1 -0
  29. package/dist/src/lang/json-schema.d.ts +40 -0
  30. package/dist/src/lang/parser-transforms.d.ts +14 -0
  31. package/dist/src/lang/runtime.d.ts +39 -20
  32. package/dist/src/types/Type.d.ts +5 -0
  33. package/dist/tjs-batteries.js +3 -4
  34. package/dist/tjs-batteries.js.map +5 -13
  35. package/dist/tjs-eval.js +47 -0
  36. package/dist/tjs-eval.js.map +7 -0
  37. package/dist/tjs-from-ts.js +58 -0
  38. package/dist/tjs-from-ts.js.map +7 -0
  39. package/dist/tjs-lang.js +349 -0
  40. package/dist/tjs-lang.js.map +7 -0
  41. package/dist/tjs-vm.js +51 -51
  42. package/dist/tjs-vm.js.map +4 -19
  43. package/docs/README.md +21 -20
  44. package/docs/WASM-QUICKSTART.md +283 -0
  45. package/docs/diagrams/architecture-shift.svg +117 -0
  46. package/docs/diagrams/compile-runtime.svg +130 -0
  47. package/docs/diagrams/icon-riff-1.svg +55 -0
  48. package/docs/diagrams/icon-riff-2.svg +62 -0
  49. package/docs/diagrams/icon-riff-3.svg +61 -0
  50. package/docs/diagrams/platform-overview.svg +114 -0
  51. package/docs/diagrams/safe-eval.svg +147 -0
  52. package/docs/eval-v4/arch-comparison.svg +277 -0
  53. package/docs/eval-v4/bundler-tree.svg +250 -0
  54. package/docs/eval-v4/http-lifecycle.svg +148 -0
  55. package/docs/function-predicate-design.md +8 -8
  56. package/docs/native-engine-integration.md +2 -2
  57. package/editors/codemirror/autocomplete.test.ts +29 -29
  58. package/package.json +24 -12
  59. package/src/cli/commands/convert.test.ts +11 -8
  60. package/src/lang/codegen.test.ts +117 -112
  61. package/src/lang/docs.test.ts +22 -22
  62. package/src/lang/docs.ts +5 -8
  63. package/src/lang/emitters/dts.test.ts +13 -13
  64. package/src/lang/emitters/from-ts.ts +36 -9
  65. package/src/lang/emitters/js-tests.ts +143 -28
  66. package/src/lang/emitters/js.ts +44 -31
  67. package/src/lang/features.test.ts +259 -43
  68. package/src/lang/from-ts.test.ts +3 -3
  69. package/src/lang/function-predicate.test.ts +1 -1
  70. package/src/lang/index.ts +8 -47
  71. package/src/lang/json-schema.test.ts +261 -0
  72. package/src/lang/json-schema.ts +167 -0
  73. package/src/lang/parser-params.ts +28 -44
  74. package/src/lang/parser-transforms.ts +255 -0
  75. package/src/lang/parser.test.ts +32 -13
  76. package/src/lang/parser.ts +49 -11
  77. package/src/lang/perf.test.ts +11 -11
  78. package/src/lang/roundtrip.test.ts +3 -3
  79. package/src/lang/runtime.test.ts +167 -0
  80. package/src/lang/runtime.ts +213 -64
  81. package/src/lang/transpiler.test.ts +21 -21
  82. package/src/lang/typescript-syntax.test.ts +11 -9
  83. package/src/types/Type.ts +38 -1
  84. package/src/use-cases/bootstrap.test.ts +7 -7
  85. package/src/use-cases/client-server.test.ts +1 -1
  86. package/src/use-cases/malicious-actor.test.ts +1 -1
  87. package/src/use-cases/rag-processor.test.ts +1 -1
  88. package/src/use-cases/sophisticated-agents.test.ts +2 -2
  89. package/src/use-cases/transpiler-llm.test.ts +1 -1
  90. package/src/use-cases/unbundled-imports.test.ts +9 -9
  91. package/tjs-lang.svg +17 -25
  92. package/dist/tjs-full.js +0 -435
  93. package/dist/tjs-full.js.map +0 -45
  94. package/dist/tjs-transpiler.js +0 -3
  95. package/dist/tjs-transpiler.js.map +0 -11
@@ -12,11 +12,11 @@ describe('generateDocs', () => {
12
12
  describe('basic output', () => {
13
13
  it('extracts function signatures in document order', () => {
14
14
  const source = `
15
- function first(x: 5) -> 10 {
15
+ function first(x: 5): 10 {
16
16
  return x * 2
17
17
  }
18
18
 
19
- function second(a: '', b: 0) -> '' {
19
+ function second(a: '', b: 0): '' {
20
20
  return a + b
21
21
  }
22
22
  `
@@ -56,12 +56,12 @@ More docs here.
56
56
  /*#
57
57
  # First Section
58
58
  */
59
- function first(x: 0) -> 0 { return x }
59
+ function first(x: 0): 0 { return x }
60
60
 
61
61
  /*#
62
62
  # Second Section
63
63
  */
64
- function second(x: 0) -> 0 { return x }
64
+ function second(x: 0): 0 { return x }
65
65
  `
66
66
  const result = generateDocs(source)
67
67
 
@@ -77,14 +77,14 @@ function second(x: 0) -> 0 { return x }
77
77
 
78
78
  describe('function signatures', () => {
79
79
  it('captures full signature with params and return type', () => {
80
- const source = `function greet(name: 'World') -> '' { return name }`
80
+ const source = `function greet(name: 'World'): '' { return name }`
81
81
  const result = generateDocs(source)
82
82
 
83
83
  const func = result.items[0] as any
84
84
  expect(func.type).toBe('function')
85
85
  expect(func.signature).toContain('greet')
86
86
  expect(func.signature).toContain("name: 'World'")
87
- expect(func.signature).toContain("-> ''")
87
+ expect(func.signature).toContain(": ''")
88
88
  })
89
89
 
90
90
  it('captures optional params with defaults', () => {
@@ -173,11 +173,11 @@ This is documentation.
173
173
  })
174
174
 
175
175
  it('renders function signatures as code blocks', () => {
176
- const source = `function double(x: 5) -> 10 { return x * 2 }`
176
+ const source = `function double(x: 5): 10 { return x * 2 }`
177
177
  const result = generateDocs(source)
178
178
 
179
179
  expect(result.markdown).toContain('```tjs')
180
- expect(result.markdown).toContain('function double(x: 5) -> 10')
180
+ expect(result.markdown).toContain('function double(x: 5): 10')
181
181
  expect(result.markdown).toContain('```')
182
182
  })
183
183
 
@@ -186,11 +186,11 @@ This is documentation.
186
186
  /*#
187
187
  Intro
188
188
  */
189
- function first(x: 0) -> 0 { return x }
189
+ function first(x: 0): 0 { return x }
190
190
  /*#
191
191
  Middle
192
192
  */
193
- function second(x: 0) -> 0 { return x }
193
+ function second(x: 0): 0 { return x }
194
194
  `
195
195
  const result = generateDocs(source)
196
196
 
@@ -208,11 +208,11 @@ function second(x: 0) -> 0 { return x }
208
208
  A collection of math functions.
209
209
  */
210
210
 
211
- function double(x: 5) -> 10 {
211
+ function double(x: 5): 10 {
212
212
  return x * 2
213
213
  }
214
214
 
215
- function triple(x: 3) -> 9 {
215
+ function triple(x: 3): 9 {
216
216
  return x * 3
217
217
  }
218
218
 
@@ -275,13 +275,13 @@ These functions are pure.
275
275
  it('handles mixed TJS and TypeScript in same file', () => {
276
276
  const source = `
277
277
  function tsFunc(x: number): number { return x }
278
- function tjsFunc(x: 0) -> 0 { return x }
278
+ function tjsFunc(x: 0): 0 { return x }
279
279
  `
280
280
  const result = generateDocs(source)
281
281
 
282
282
  expect(result.items).toHaveLength(2)
283
283
  expect((result.items[0] as any).signature).toContain(': number')
284
- expect((result.items[1] as any).signature).toContain('-> 0')
284
+ expect((result.items[1] as any).signature).toContain(': 0')
285
285
  })
286
286
  })
287
287
  })
@@ -299,7 +299,7 @@ describe('generateDocsMarkdown', () => {
299
299
  })
300
300
 
301
301
  it('renders function with type metadata', () => {
302
- const source = `function greet(name: 'World') -> '' { return name }`
302
+ const source = `function greet(name: 'World'): '' { return name }`
303
303
  const types = {
304
304
  greet: {
305
305
  params: {
@@ -313,7 +313,7 @@ describe('generateDocsMarkdown', () => {
313
313
 
314
314
  expect(result).toContain('## greet')
315
315
  expect(result).toContain('```tjs')
316
- expect(result).toContain("function greet(name: 'World') -> ''")
316
+ expect(result).toContain("function greet(name: 'World'): ''")
317
317
  expect(result).toContain('**Parameters:**')
318
318
  expect(result).toContain('`name`: string')
319
319
  expect(result).toContain('(e.g. `"World"`)')
@@ -341,13 +341,13 @@ describe('generateDocsMarkdown', () => {
341
341
  it('works without type metadata', () => {
342
342
  const source = `
343
343
  /*# Intro */
344
- function foo(x: 0) -> 0 { return x }
344
+ function foo(x: 0): 0 { return x }
345
345
  `
346
346
  const result = generateDocsMarkdown(source, undefined)
347
347
 
348
348
  expect(result).toContain('Intro')
349
349
  expect(result).toContain('## foo')
350
- expect(result).toContain('function foo(x: 0) -> 0')
350
+ expect(result).toContain('function foo(x: 0): 0')
351
351
  // No params/returns since no type metadata
352
352
  expect(result).not.toContain('**Parameters:**')
353
353
  })
@@ -355,9 +355,9 @@ function foo(x: 0) -> 0 { return x }
355
355
  it('preserves document order with interleaved docs and functions', () => {
356
356
  const source = `
357
357
  /*# Section 1 */
358
- function first(x: 0) -> 0 { return x }
358
+ function first(x: 0): 0 { return x }
359
359
  /*# Section 2 */
360
- function second(x: 0) -> 0 { return x }
360
+ function second(x: 0): 0 { return x }
361
361
  /*# Conclusion */
362
362
  `
363
363
  const types = {
@@ -409,14 +409,14 @@ function greet(name: string): string {
409
409
  const source = `
410
410
  /*# Module header */
411
411
 
412
- function first(x: 0) -> 0 {
412
+ function first(x: 0): 0 {
413
413
  /*# Comment inside first - should be ignored */
414
414
  return x
415
415
  }
416
416
 
417
417
  /*# Between first and second */
418
418
 
419
- function second(y: '') -> '' {
419
+ function second(y: ''): '' {
420
420
  /*# Comment inside second - should be ignored */
421
421
  return y
422
422
  }
package/src/lang/docs.ts CHANGED
@@ -67,10 +67,10 @@ export function generateDocs(source: string): DocResult {
67
67
 
68
68
  // Find all doc blocks and functions, sort by position
69
69
  const docPattern = /\/\*#([\s\S]*?)\*\//g
70
- // Match both TJS (-> returnType) and TypeScript (: returnType) function syntax
70
+ // Match TJS function syntax with return type annotations (:, :?, :!)
71
71
  // Return type can be quoted string with spaces (e.g. 'Hello, World!')
72
72
  const funcPattern =
73
- /function\s+(\w+)\s*\(([^)]*)\)\s*(?:(-[>?!])\s*('[^']*'|"[^"]*"|[^\s{]+)|:\s*(\w+))?\s*\{/g
73
+ /function\s+(\w+)\s*\(([^)]*)\)\s*(?:(:[?!]?)\s*('[^']*'|"[^"]*"|[^\s{]+))?\s*\{/g
74
74
 
75
75
  type Match = { type: 'doc' | 'function'; index: number; data: any }
76
76
  const matches: Match[] = []
@@ -107,14 +107,11 @@ export function generateDocs(source: string): DocResult {
107
107
  const name = match[1]
108
108
  const params = match[2]
109
109
  const returnMarker = match[3] || ''
110
- const tjsReturnType = match[4] || ''
111
- const tsReturnType = match[5] || ''
110
+ const returnType = match[4] || ''
112
111
 
113
112
  let signature = `function ${name}(${params})`
114
- if (returnMarker) {
115
- signature += ` ${returnMarker} ${tjsReturnType}`
116
- } else if (tsReturnType) {
117
- signature += `: ${tsReturnType}`
113
+ if (returnMarker && returnType) {
114
+ signature += `${returnMarker} ${returnType}`
118
115
  }
119
116
 
120
117
  matches.push({
@@ -101,7 +101,7 @@ describe('typeDescriptorToTS', () => {
101
101
  describe('generateDTS', () => {
102
102
  it('should generate declarations for exported functions', () => {
103
103
  const source = `
104
- export function greet(name: 'Alice') -> '' {
104
+ export function greet(name: 'Alice'): '' {
105
105
  return \`Hello, \${name}!\`
106
106
  }
107
107
  `
@@ -115,7 +115,7 @@ export function greet(name: 'Alice') -> '' {
115
115
 
116
116
  it('should handle optional parameters', () => {
117
117
  const source = `
118
- export function greet(name = 'world') -> '' {
118
+ export function greet(name = 'world'): '' {
119
119
  return \`Hello, \${name}!\`
120
120
  }
121
121
  `
@@ -127,7 +127,7 @@ export function greet(name = 'world') -> '' {
127
127
 
128
128
  it('should handle multiple parameters and return types', () => {
129
129
  const source = `
130
- export function add(a: 0, b: 0) -> 0 {
130
+ export function add(a: 0, b: 0): 0 {
131
131
  return a + b
132
132
  }
133
133
  `
@@ -141,11 +141,11 @@ export function add(a: 0, b: 0) -> 0 {
141
141
 
142
142
  it('should skip non-exported functions when exports exist', () => {
143
143
  const source = `
144
- function helper(x: '') -> '' {
144
+ function helper(x: ''): '' {
145
145
  return x.toUpperCase()
146
146
  }
147
147
 
148
- export function greet(name: 'Alice') -> '' {
148
+ export function greet(name: 'Alice'): '' {
149
149
  return helper(name)
150
150
  }
151
151
  `
@@ -158,7 +158,7 @@ export function greet(name: 'Alice') -> '' {
158
158
 
159
159
  it('should treat all functions as exported when no exports exist', () => {
160
160
  const source = `
161
- function add(a: 0, b: 0) -> 0 {
161
+ function add(a: 0, b: 0): 0 {
162
162
  return a + b
163
163
  }
164
164
  `
@@ -170,7 +170,7 @@ function add(a: 0, b: 0) -> 0 {
170
170
 
171
171
  it('should handle object parameter shapes', () => {
172
172
  const source = `
173
- export function createUser(user: { name: '', age: 0 }) -> { id: 0, name: '' } {
173
+ export function createUser(user: { name: '', age: 0 }): { id: 0, name: '' } {
174
174
  return { id: 1, name: user.name }
175
175
  }
176
176
  `
@@ -183,7 +183,7 @@ export function createUser(user: { name: '', age: 0 }) -> { id: 0, name: '' } {
183
183
 
184
184
  it('should handle nullable parameters', () => {
185
185
  const source = `
186
- export function find(id: 0 | null) -> '' {
186
+ export function find(id: 0 | null): '' {
187
187
  return id ? 'found' : 'not found'
188
188
  }
189
189
  `
@@ -213,7 +213,7 @@ export function area(w: 0.0, h: 0.0) {
213
213
  it('should include JSDoc from TDoc comments', () => {
214
214
  const source = `
215
215
  /*# Greet a person by name */
216
- function greet(name: 'Alice') -> '' {
216
+ function greet(name: 'Alice'): '' {
217
217
  return \`Hello, \${name}!\`
218
218
  }
219
219
  `
@@ -225,7 +225,7 @@ function greet(name: 'Alice') -> '' {
225
225
 
226
226
  it('should wrap in module declaration when moduleName is given', () => {
227
227
  const source = `
228
- export function add(a: 0, b: 0) -> 0 {
228
+ export function add(a: 0, b: 0): 0 {
229
229
  return a + b
230
230
  }
231
231
  `
@@ -239,7 +239,7 @@ export function add(a: 0, b: 0) -> 0 {
239
239
 
240
240
  it('should handle array return types', () => {
241
241
  const source = `
242
- export function getNames(count: 0) -> [''] {
242
+ export function getNames(count: 0): [''] {
243
243
  return Array(count).fill('test')
244
244
  }
245
245
  `
@@ -393,7 +393,7 @@ describe('generateDTS — Type declarations', () => {
393
393
  const source = `
394
394
  export Type Name = 'World'
395
395
 
396
- export function greet(name: Name) -> '' {
396
+ export function greet(name: Name): '' {
397
397
  return \`Hello, \${name}!\`
398
398
  }
399
399
  `
@@ -614,7 +614,7 @@ export class Point {
614
614
  }
615
615
  }
616
616
 
617
- export function greet(name: '') -> '' {
617
+ export function greet(name: ''): '' {
618
618
  return \`Hello, \${name}!\`
619
619
  }
620
620
  `
@@ -15,7 +15,7 @@
15
15
  * }
16
16
  *
17
17
  * // Output TJS:
18
- * function greet(name: '', age = 0) -> '' {
18
+ * function greet(name: '', age = 0): '' {
19
19
  * return `Hello, ${name}!`
20
20
  * }
21
21
  *
@@ -122,8 +122,15 @@ interface TypeResolutionContext {
122
122
  visited?: Set<string>
123
123
  /** Type parameter constraints and defaults from enclosing generic function/class */
124
124
  typeParams?: Map<string, { constraint?: ts.TypeNode; default?: ts.TypeNode }>
125
+ /** Cache resolved type alias/interface results to avoid redundant traversals */
126
+ resolvedCache?: Map<string, TypeInfo>
127
+ /** Current resolution depth — bail to 'any' when too deep */
128
+ depth?: number
125
129
  }
126
130
 
131
+ /** Maximum type resolution depth before degrading to 'any' */
132
+ const MAX_TYPE_DEPTH = 20
133
+
127
134
  /**
128
135
  * DOM interface types — not constructible but common in TS signatures.
129
136
  * Map to {} (opaque object) so params stay annotated and required
@@ -646,6 +653,13 @@ function typeToInfo(
646
653
  ): TypeInfo {
647
654
  if (!type) return { kind: 'any' }
648
655
 
656
+ // Bail on deeply nested type resolution to prevent exponential traversal
657
+ const depth = ctx?.depth ?? 0
658
+ if (depth > MAX_TYPE_DEPTH) return { kind: 'any' }
659
+ // Increment depth for recursive calls (mutating ctx would be wrong since
660
+ // sibling types share the same ctx; spread creates a child scope)
661
+ ctx = ctx ? { ...ctx, depth: depth + 1 } : undefined
662
+
649
663
  switch (type.kind) {
650
664
  case ts.SyntaxKind.StringKeyword:
651
665
  return { kind: 'string' }
@@ -802,17 +816,27 @@ function typeToInfo(
802
816
 
803
817
  // Resolve type aliases
804
818
  if (ctx?.typeAliases?.has(typeName)) {
819
+ // Check cache first
820
+ if (ctx.resolvedCache?.has(typeName)) {
821
+ return ctx.resolvedCache.get(typeName)!
822
+ }
805
823
  const visited = ctx.visited ?? new Set<string>()
806
824
  if (visited.has(typeName)) {
807
825
  return { kind: 'any' } // Circular reference
808
826
  }
809
827
  visited.add(typeName)
810
828
  const resolvedType = ctx.typeAliases.get(typeName)!
811
- return typeToInfo(resolvedType, { ...ctx, visited })
829
+ const result = typeToInfo(resolvedType, { ...ctx, visited })
830
+ ctx.resolvedCache?.set(typeName, result)
831
+ return result
812
832
  }
813
833
 
814
834
  // Resolve interfaces
815
835
  if (ctx?.interfaces?.has(typeName)) {
836
+ // Check cache first
837
+ if (ctx.resolvedCache?.has(typeName)) {
838
+ return ctx.resolvedCache.get(typeName)!
839
+ }
816
840
  const visited = ctx.visited ?? new Set<string>()
817
841
  if (visited.has(typeName)) {
818
842
  return { kind: 'any' } // Circular reference
@@ -851,7 +875,9 @@ function typeToInfo(
851
875
  shape[propName] = typeToInfo(member.type, { ...ctx, visited })
852
876
  }
853
877
  }
854
- return { kind: 'object', shape }
878
+ const result = { kind: 'object' as const, shape }
879
+ ctx.resolvedCache?.set(typeName, result)
880
+ return result
855
881
  }
856
882
 
857
883
  // Check type parameter constraints/defaults from enclosing context
@@ -1476,14 +1502,14 @@ function transformFunctionToTJS(
1476
1502
  const returnExample = node.type
1477
1503
  ? typeToExample(node.type, undefined, warnings, resolveCtx)
1478
1504
  : ''
1479
- // Use -! to skip signature tests - TS types are compile-time only,
1505
+ // Use :! to skip signature tests - TS types are compile-time only,
1480
1506
  // the example values won't necessarily match runtime behavior
1481
1507
  const returnAnnotation =
1482
1508
  returnExample &&
1483
1509
  returnExample !== 'undefined' &&
1484
1510
  returnExample !== 'any' &&
1485
1511
  !returnExample.startsWith('new ') // new Set(), new Map() etc. aren't valid TJS literals
1486
- ? ` -! ${returnExample}`
1512
+ ? `:! ${returnExample}`
1487
1513
  : ''
1488
1514
 
1489
1515
  // Track degraded return type
@@ -1596,7 +1622,7 @@ function emitOverloadGroup(
1596
1622
  : ''
1597
1623
  const returnAnnotation =
1598
1624
  returnExample && returnExample !== 'undefined' && returnExample !== 'any'
1599
- ? ` -! ${returnExample}`
1625
+ ? `:! ${returnExample}`
1600
1626
  : ''
1601
1627
 
1602
1628
  const { line } = sourceFile.getLineAndCharacterOfPosition(
@@ -1723,12 +1749,12 @@ function transformClassToTJS(
1723
1749
  const returnExample = member.type
1724
1750
  ? typeToExample(member.type, undefined, warnings, resolveCtx)
1725
1751
  : ''
1726
- // Use -! to skip signature tests for TS-transpiled code
1752
+ // Use :! to skip signature tests for TS-transpiled code
1727
1753
  const returnAnnotation =
1728
1754
  returnExample &&
1729
1755
  returnExample !== 'undefined' &&
1730
1756
  returnExample !== 'any'
1731
- ? ` -! ${returnExample}`
1757
+ ? `:! ${returnExample}`
1732
1758
  : ''
1733
1759
 
1734
1760
  let body = '{ }'
@@ -1769,7 +1795,7 @@ function transformClassToTJS(
1769
1795
  returnExample !== 'undefined' &&
1770
1796
  returnExample !== 'any' &&
1771
1797
  !returnExample.startsWith('new ')
1772
- ? ` -> ${returnExample}`
1798
+ ? `: ${returnExample}`
1773
1799
  : ''
1774
1800
 
1775
1801
  let body = '{ }'
@@ -2406,6 +2432,7 @@ export function fromTS(
2406
2432
  interfaces,
2407
2433
  sourceFile,
2408
2434
  warnings,
2435
+ resolvedCache: new Map(),
2409
2436
  }
2410
2437
 
2411
2438
  // Pre-scan: detect function overload groups