Skip to content

Commit ff0901e

Browse files
authored
feat: Upgrade dependencies and refactor chunk creation (#25)
1 parent 89c7f23 commit ff0901e

File tree

8 files changed

+333
-114
lines changed

8 files changed

+333
-114
lines changed

bun.lock

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
"ts-morph": "^26.0.0"
3939
},
4040
"devDependencies": {
41-
"@eslint/js": "^9.34.0",
41+
"@eslint/js": "^9.35.0",
4242
"@prettier/sync": "^0.6.1",
4343
"@sinclair/typebox-codegen": "^0.11.1",
4444
"@types/bun": "^1.2.21",
45-
"@typescript-eslint/eslint-plugin": "^8.41.0",
46-
"@typescript-eslint/parser": "^8.41.0",
47-
"eslint": "^9.34.0",
45+
"@typescript-eslint/eslint-plugin": "^8.42.0",
46+
"@typescript-eslint/parser": "^8.42.0",
47+
"eslint": "^9.35.0",
4848
"eslint-config-prettier": "^10.1.8",
4949
"eslint-plugin-no-relative-import-paths": "^1.6.1",
5050
"eslint-plugin-prettier": "^5.5.4",
@@ -54,7 +54,7 @@
5454
"prettier": "^3.6.2",
5555
"prettier-plugin-organize-imports": "^4.2.0",
5656
"tsc-alias": "^1.8.16",
57-
"typescript-eslint": "^8.41.0"
57+
"typescript-eslint": "^8.42.0"
5858
},
5959
"peerDependencies": {
6060
"typescript": "~5.9.2"

src/traverse/chunk-large-types.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { NodeGraph } from '@daxserver/validation-schema-codegen/traverse/node-graph'
2+
import type { TraversedNode } from '@daxserver/validation-schema-codegen/traverse/types'
3+
import { resolverStore } from '@daxserver/validation-schema-codegen/utils/resolver-store'
4+
import { Node, SourceFile } from 'ts-morph'
5+
6+
const CHUNK_SIZE = 20
7+
8+
export const shouldChunkUnion = (node: Node): boolean => {
9+
if (Node.isUnionTypeNode(node)) {
10+
return node.getTypeNodes().length >= CHUNK_SIZE
11+
}
12+
13+
// Handle IndexedAccessType that resolves to large unions (e.g., typeof sites[number])
14+
if (Node.isIndexedAccessTypeNode(node)) {
15+
const typeChecker = node.getProject().getTypeChecker()
16+
const type = typeChecker.getTypeAtLocation(node)
17+
if (type.isUnion()) {
18+
return type.getUnionTypes().length >= CHUNK_SIZE
19+
}
20+
}
21+
22+
return false
23+
}
24+
25+
export const createChunkNodes = (
26+
node: Node,
27+
parentTypeName: string,
28+
nodeGraph: NodeGraph,
29+
maincodeNodeIds: Set<string>,
30+
requiredNodeIds: Set<string>,
31+
sourceFile: SourceFile,
32+
addToRequired: boolean = true,
33+
): string[] => {
34+
let typeTexts: string[] = []
35+
36+
if (Node.isUnionTypeNode(node)) {
37+
typeTexts = node.getTypeNodes().map((n) => n.getText())
38+
} else if (Node.isIndexedAccessTypeNode(node)) {
39+
// Handle IndexedAccessType by resolving to union types
40+
const typeChecker = node.getProject().getTypeChecker()
41+
const type = typeChecker.getTypeAtLocation(node)
42+
if (type.isUnion()) {
43+
typeTexts = type.getUnionTypes().map((t) => t.getText())
44+
}
45+
}
46+
47+
if (typeTexts.length === 0) {
48+
return []
49+
}
50+
const chunks: string[][] = []
51+
52+
// Create chunks of 20 items each
53+
for (let i = 0; i < typeTexts.length; i += CHUNK_SIZE) {
54+
chunks.push(typeTexts.slice(i, i + CHUNK_SIZE))
55+
}
56+
57+
const chunkReferences: string[] = []
58+
59+
// scratch file for chunk nodes (once per parent)
60+
const scratchSourceFile = node.getProject().createSourceFile(
61+
`__chunks_${parentTypeName}_${Date.now()}.ts`,
62+
'',
63+
{ overwrite: true },
64+
)
65+
66+
// Create chunk nodes
67+
for (let i = 0; i < chunks.length; i++) {
68+
const chunkName = `${parentTypeName}_Chunk${i + 1}`
69+
const chunkQualifiedName = resolverStore.generateQualifiedName(chunkName, sourceFile)
70+
71+
chunkReferences.push(chunkQualifiedName)
72+
maincodeNodeIds.add(chunkQualifiedName)
73+
if (addToRequired) {
74+
requiredNodeIds.add(chunkQualifiedName)
75+
}
76+
77+
// Create a new union node with only the chunk's type texts
78+
const chunkTypeTexts = chunks[i]!
79+
80+
// Create a synthetic union node for this chunk
81+
const chunkAlias = scratchSourceFile.addTypeAlias({
82+
name: chunkName,
83+
type: chunkTypeTexts.join(' | '),
84+
})
85+
const chunkTypeNode = chunkAlias.getTypeNode()!
86+
87+
const chunkTraversedNode: TraversedNode = {
88+
node: chunkTypeNode, // Use the chunk-specific union node
89+
type: 'chunk',
90+
originalName: chunkName,
91+
qualifiedName: chunkQualifiedName,
92+
isImported: false,
93+
isMainCode: true,
94+
isChunk: true,
95+
chunkReferences: [], // Chunk nodes don't need references to other chunks
96+
}
97+
98+
nodeGraph.addTypeNode(chunkQualifiedName, chunkTraversedNode)
99+
100+
// Add to ResolverStore
101+
resolverStore.addTypeMapping({
102+
originalName: chunkName,
103+
sourceFile,
104+
})
105+
}
106+
107+
return chunkReferences
108+
}
109+
110+
export const markChunksAsRequired = (
111+
parentQualifiedName: string,
112+
nodeGraph: NodeGraph,
113+
requiredNodeIds: Set<string>,
114+
): void => {
115+
const parentNode = nodeGraph.getNode(parentQualifiedName)
116+
if (parentNode?.chunkReferences) {
117+
for (const chunkRef of parentNode.chunkReferences) {
118+
requiredNodeIds.add(chunkRef)
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)