From cef6bd975ada366e792a65a69e7a6aab6477ad38 Mon Sep 17 00:00:00 2001 From: yname Date: Fri, 16 Aug 2024 15:24:15 -0400 Subject: [PATCH] Initial Commit --- .gitignore | 1 + README.md | 3 ++ bun.lockb | Bin 0 -> 2674 bytes package.json | 5 +++ src/index.ts | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 27 +++++++++++++ 6 files changed, 142 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 bun.lockb create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..754b38d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# SourcemapGenerator + +This program watches multiple Rojo project directories for changes and builds a combined sourcemap. \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..7f5780b360025fb85ff54da75851e87f02d8633c GIT binary patch literal 2674 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p+gZx>c& z@*F5N&0HAlb!9D^fx0r&`F<1jpWDwERhMhAJ>mo^0s=M&#lV3^H$eG$Fa=OPgyLdg zXs`z|frd2n0BLR@eGy3W0O@9^IFJH^Q*4@hy$u?_RKH0-+adH?X`+5qui92yOU`_o zW3K{d?OuF(M&W3oB0w4#9t?aq)T0Z-^xp+aI0E&v0%<8A2GPU-n0`5+r%izRK`{!_3vvUo z02XE-8e|>_vj8!O4|4~I2Ju0FH1+@Z|G_juv{Oz3&0}PMn2T&Q%Z?dbz2@N;GQ|YS zik%H})Ld6Se`lVmcbxmQq)p_xLnSM&aPv;j+PgUIXr=D%m#>9nE;EwvSvH?+3T;QGV-x&$ z1#P@yZ{C%fk=P?L>rTm%LuMC>>+M#TWGDt29A%t%xY(|LMy3g~-89zn!YJ)oNalj# z3kF!!0(z{UFD!B5S`}D0d69frgGgA0@!O-;XY3z-Eh|}VzG9=|vw*37XI1p~w#^#f z(+{F6pn651RUVg3w2@hCsRhs*W^i{HqId&Tr!>IoF%HH!Lp?)1GX@4&4G62*m>5A4 zhUN?m%|LrVbt9~9V`8kc&@5dr7>A?^Xdp() +function getSourcemap(root: string): Promise { + const cached = sourcemapCache.get(root) + if (cached) { + return Promise.resolve(cached) + } + return new Promise((resolve, reject) => { + let stdout = '' + let stderr = '' + const rojo = spawn('rojo', ['sourcemap', root]) + rojo.stdout.on('data', (data) => { + stdout += data.toString() + }) + rojo.stderr.on('data', (data) => { + stderr += data.toString() + }) + rojo.on('close', (code) => { + if (code === 0) { + try { + const sourcemap = JSON.parse(stdout) + sourcemapCache.set(root, sourcemap) + resolve(sourcemap) + } catch { + reject(new Error(`Failed to parse sourcemap: ${stdout}`)) + } + } else { + reject(stderr) + } + }) + }) +} + +function prefixSourcemap(sourcemap: RojoSourcemap, prefix: string): RojoSourcemap { + return { + name: sourcemap.name, + className: sourcemap.className, + filePaths: sourcemap.filePaths?.map(path => `${prefix}/${path}`), + children: sourcemap.children?.map(child => prefixSourcemap(child, prefix)), + } +} + +async function getPrefixedSourcemap(root: string): Promise { + const sourcemap = await getSourcemap(root) + const prefixed = prefixSourcemap(sourcemap, root) + return prefixed +} + +function mergeSourcemaps(sourcemaps: RojoSourcemap[]): RojoSourcemap { + const merged: Required = { + name: '', + className: '', + filePaths: [], + children: [] + }; + + for (const sourcemap of sourcemaps) { + merged.name = sourcemap.name; + merged.className = sourcemap.className; + + if (sourcemap.filePaths) { + merged.filePaths = sourcemap.filePaths; + } + + for (const child of sourcemap.children ?? []) { + const existingChild = merged.children.findIndex(oldChild => oldChild.name === child.name); + if (existingChild !== -1) { + merged.children[existingChild] = mergeSourcemaps([merged.children[existingChild], child]); + } else { + merged.children.push(child); + } + } + } + + return merged; +} + +async function rebuild() { + const sourcemaps = await Promise.all([ + getPrefixedSourcemap('Secret'), + getPrefixedSourcemap('Core'), + ]) + const sourcemap = mergeSourcemaps(sourcemaps) + await fs.promises.writeFile('sourcemap.json', JSON.stringify(sourcemap, null, 2)) +} + +for (const root of SOURCE_ROOTS) { + fs.watch(root, {recursive:true}, () => { + sourcemapCache.delete(root) + rebuild() + }) +} + +rebuild() \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1edfb46 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags + "noUnusedLocals": true, + "noUnusedParameters": true, + "noPropertyAccessFromIndexSignature": true + } + } \ No newline at end of file