Improved support for debug-adapter-protocol (#4186)

* Improve support for \`debug-adapter-protocol\`

* More improvements, fix formatting in debug console

* Fix attaching

* Prepare for source maps

* Start of source map support, breakpoints work

* Source map support

* add some package.jsons

* wip

* Update package.json

* More fixes

* Make source maps safer if exception occurs

* Check bun version if it fails

* Fix console.log formatting

* Fix source maps partly

* More source map fixes

* Prepare for extension

* watch mode with dap

* Improve preview code

* Prepare for extension 2

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
Ashcon Partovi
2023-08-24 22:53:34 -07:00
committed by GitHub
parent f269432d90
commit 1480889205
73 changed files with 13542 additions and 9216 deletions

View File

@@ -0,0 +1,171 @@
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
# Logs
logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# Runtime data
pids
_.pid
_.seed
\*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
\*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
\*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
\*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*
out

View File

@@ -0,0 +1,8 @@
# bun-devtools-frontend
This is the WebKit Web Inspector bundled as standalone assets.
Two ways to use this:
- Set `?ws=hostname:port` to connect to a `bun --inspect`'d process.
- Navigate to `/inspect/hostname:port`

View File

@@ -0,0 +1,131 @@
import { build } from "esbuild";
import { copyFileSync, mkdirSync, readdirSync, rmSync, statSync } from "fs";
import { join } from "path";
try {
const basePath = join(import.meta.dir, "../../src/bun.js/WebKit/Source/WebInspectorUI/UserInterface");
const htmlPath = join(basePath, "Main.html");
const backendCommands = join(
import.meta.dir,
"../../src/bun.js/WebKit/WebKitBuild/Release/JavaScriptCore/DerivedSources/inspector/InspectorBackendCommands.js",
);
const scriptsToBundle = [];
const stylesToBundle = [];
const jsReplacementId = crypto.randomUUID() + ".js";
const cssReplacementId = crypto.randomUUID() + ".css";
const html = new HTMLRewriter()
.on("script", {
element(element) {
const src = element.getAttribute("src");
if (src && !src?.includes("External") && !src?.includes("WebKitAdditions")) {
if (scriptsToBundle.length === 0) {
element.replace("<script>var WI = {};\n</script>", { html: true });
} else {
element.remove();
}
scriptsToBundle.push(src);
}
},
})
.on("script:not([src])", {
element(element) {
element.remove();
},
})
.on("head", {
element(element) {
element.prepend(` <base href="/" /> `, { html: true });
element.append(
`
<style>
body {
--undocked-title-area-height: 0px !important;
}
</style>
<script src="${jsReplacementId}"></script>
<script>
WI.sharedApp = new WI.AppController;
WI.sharedApp.initialize();
</script>`,
{ html: true },
);
},
})
// .on("link[rel=stylesheet]", {
// element(element) {
// const href = element.getAttribute("href");
// if (href && !href?.includes("External") && !href?.includes("WebKitAdditions")) {
// element.remove();
// stylesToBundle.push(href);
// }
// },
// })
.transform(new Response(Bun.file(htmlPath)));
let htmlText = await html.text();
rmSync(join(import.meta.dir, "out"), { recursive: true, force: true });
mkdirSync(join(import.meta.dir, "out", "Protocol"), { recursive: true });
const javascript = scriptsToBundle.map(a => `import '${join(basePath, a)}';`).join("\n") + "\n";
// const css = stylesToBundle.map(a => `@import "${join(basePath, a)}";`).join("\n") + "\n";
await Bun.write(join(import.meta.dir, "out/manifest.js"), javascript);
// await Bun.write(join(import.meta.dir, "manifest.css"), css);
const jsBundle = await Bun.build({
entrypoints: [join(import.meta.dir, "out/manifest.js")],
outdir: "out",
minify: true,
});
const jsFilename = "manifest-" + jsBundle.outputs[0].hash + ".js";
// const cssBundle = await build({
// bundle: true,
// minify: true,
// write: false,
// entryPoints: [join(import.meta.dir, "manifest.css")],
// outdir: "out",
// loader: {
// ".css": "css",
// ".svg": "dataurl",
// },
// external: ["*.png"],
// plugins: [
// {
// name: "css",
// setup(build) {
// build.onResolve({ filter: new RegExp("/Images/Warning.svg") }, args => ({
// path: join(basePath, "Images/Warning.svg"),
// }));
// },
// },
// ],
// });
// const cssFilename = "manifest-" + cssBundle.outputFiles[0].hash.replaceAll("/", "_") + ".css";
htmlText = htmlText.replace(jsReplacementId, jsFilename);
// htmlText = htmlText.replace(cssReplacementId, cssFilename);
await Bun.write(join(import.meta.dir, "out", jsFilename), jsBundle.outputs[0]);
// await Bun.write(join(import.meta.dir, "out", cssFilename), cssBundle.outputFiles[0].text);
await Bun.write(join(import.meta.dir, "out", "index.html"), htmlText);
await Bun.write(join(import.meta.dir, "out", "index.html"), htmlText);
await Bun.write(join(import.meta.dir, "out", "Protocol", "InspectorBackendCommands.js"), Bun.file(backendCommands));
function recursiveCopy(src, dest) {
readdirSync(src).forEach(file => {
const srcPath = join(src, file);
const destPath = join(dest, file);
if (statSync(srcPath).isDirectory()) {
mkdirSync(destPath, { recursive: true });
recursiveCopy(srcPath, destPath);
} else {
rmSync(destPath, { force: true });
copyFileSync(srcPath, destPath);
}
});
}
recursiveCopy(basePath, join(import.meta.dir, "out"));
} catch (e) {
console.error("Failed to build. Please make sure you've ran `make jsc` locally.");
throw e;
}

Binary file not shown.

View File

@@ -0,0 +1,14 @@
{
"name": "web-inspector-bun",
"module": "index.ts",
"type": "module",
"devDependencies": {
"bun-types": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"esbuild": "^0.19.2"
}
}

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "nodenext",
"moduleDetection": "force",
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"inlineSourceMap": true,
"allowJs": true,
"noImplicitAny": false,
"outDir": "dist",
"types": ["node"]
},
"include": [".", "../bun-types/index.d.ts"]
}