diff --git a/index.html b/index.html index aab1fb7..84bbbca 100644 --- a/index.html +++ b/index.html @@ -40,14 +40,16 @@ background: #efeaea; color: #151517; } - + + a:visited, a:active, a { color: #B0D944; outline: none; text-decoration: none; } + #logo { float: left; margin-right: 2rem; margin-left: 0.65rem; margin-top: -0.1rem; } - + nav { height: 146px; float: left; @@ -55,15 +57,20 @@ padding-top: 2em; margin-right: 30rem; } - + nav > a { display: block; } - + section { + display: none; + } + + + section:target { display: block; } - + pre { background: none; color: #B0D944; @@ -96,29 +103,29 @@ margin-top: .75rem; user-select: none; } - + h1 { padding: .5rem; border-right: 1px solid #B0D944; border-bottom: 1px solid #B0D944; display: inline-block; padding-right: 0.75em; padding-left: 0.5em; font-weight: bold; font-size: 1.6rem; margin-block-start: 0.67em; margin-block-end: 0.67em; } blockquote { outline: 1px solid #323532; margin-inline-start: 0; margin-inline-end: 0; display: block; margin-block-start: 1rem; margin-block-end: 0; padding: 1px; font-size: .825rem } blockquote::before { content: "ℹ"; float: left; font-size: 1.625rem; margin-left: 1rem; margin-right: 0.625rem; } .col { max-width: 63rem; margin: 0 auto; margin-top: 1rem; } - + #back, #mode { - width: 32px; - height: 32px; - position: absolute; - right: 0.4rem; - cursor: pointer; - user-select: none; - opacity: .65; - } + width: 32px; + height: 32px; + position: absolute; + right: 0.4rem; + cursor: pointer; + user-select: none; + opacity: .65; + } - #back { - top: 10px; - } + #back { + top: 10px; + } - #mode { - top: 60px; - } + #mode { + top: 60px; + } #bar { backdrop-filter: blur(64px); @@ -154,10 +161,10 @@ app-router[data-load="docs-viewer"] a[href='/documentation'], app-router[data-load="docs-viewer"] a:active[href='/documentation'], app-router[data-load="docs-viewer"] a:visited[href='/documentation'] { color: rgb(78, 250, 92); } - +
- +
           __ \    _ \   _` |   __|
@@ -196,14 +204,18 @@
         
-
-
-
- -
-
-
- +
+
+
+ +
+
+
+ +
+
+
+
diff --git a/lib/devtools-inspector.js b/lib/devtools-inspector.js new file mode 100644 index 0000000..635d51c --- /dev/null +++ b/lib/devtools-inspector.js @@ -0,0 +1,147 @@ +/* eslint-env browser */ +import http from 'http' +import { WebSocketServer } from 'ws' +import { Client } from 'pear-inspect' + +customElements.define('devtools-inspector', class extends HTMLElement { + constructor () { + super() + this.template = document.createElement('template') + this.template.innerHTML = ` +
+ + +

Inspector

+
+ This acts as a link between chrome://inspect and debugging Pear apps +
+
    +
  1. Run a pear app with "pear dev . --inspect"
  2. +
  3. The outputted key should be added here
  4. +
  5. In Chrome, open chrome://inspect and the app should appear under Targets
  6. +
+
+
+ +

+
+
+

No apps availble. Add a key above, to start debugging.

+
+
+ ` + this.root = this.attachShadow({ mode: 'open' }) + this.root.appendChild(this.template.content.cloneNode(true)) + + this.$addKeyForm = this.root.querySelector('#add-key-form') + this.$addKey = this.root.querySelector('#add-key') + this.$addKeyError = this.root.querySelector('#add-key-error') + this.$apps = this.root.querySelector('#apps') + this.$noApps = this.root.querySelector('#no-apps') + this.apps = new Map() + + this.$addKeyForm.addEventListener('submit', e => { + e.preventDefault() + const key = this.$addKey.value + if (key.length === 0) { + this.$addKeyError.textContent = '' + return + } + if (key.length !== 64) { + this.$addKeyError.textContent = 'Key needs to be 64 characters long' + return + } + + const sessionId = generateUuid() + this.apps.set(sessionId, { publicKey: key }) + this.$addKey.value = '' + this.$addKeyError.textContent = '' + this.renderApps() + }) + + const httpServer = http.createServer() + const wsServer = new WebSocketServer({ noServer: true }) + + httpServer.listen(9229, () => console.log('[httpServer] running on port 9229')) + httpServer.on('request', (req, res) => { + if (req.url !== '/json/list') { + res.writeHead(404) + res.end() + return + } + + const targets = [...this.apps].map(([sessionId]) => ({ + description: 'node.js instance', // `Pear app: ${app.name}`, + devtoolsFrontendUrl: `devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=127.0.0.1:9229/${sessionId}`, + devtoolsFrontendUrlCompat: `devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/${sessionId}`, + faviconUrl: 'https://nodejs.org/static/images/favicons/favicon.ico', + id: sessionId, + title: 'index.js', + type: 'node', + url: `file:///path/to/some/file/index.js`, + webSocketDebuggerUrl: `ws://127.0.0.1:9229/${sessionId}` + })) + + res.writeHead(200, { + 'Content-Type': 'application/json; charset=UTF-8', + 'Cache-Control': 'no-cache', + 'Content-Length': JSON.stringify(targets).length + }) + res.end(JSON.stringify(targets)) + }) + httpServer.on('upgrade', (request, socket, head) => { + console.log(`[httpServer] UPGRADE. url=${request.url}`) + const sessionId = request.url.substr(1) + const sessionIdExists = this.apps.has(sessionId) + if (!sessionIdExists) return socket.destroy() + + wsServer.handleUpgrade(request, socket, head, ws => wsServer.emit('connection', ws, request)) + }) + + wsServer.on('connection', (devtoolsSocket, request) => { + const sessionId = request.url.substr(1) + const app = this.apps.get(sessionId) + if (!app) return devtoolsSocket.destroy() + const { publicKey } = app + const inspectorClient = new Client({ publicKey: Buffer.from(publicKey, 'hex') }) + inspectorClient.on('message', msg => { + devtoolsSocket.send(JSON.stringify(msg)) + }) + devtoolsSocket.on('message', msg => { + inspectorClient.send(JSON.parse(msg)) + }) + }) + } + + renderApps () { + const content = [...this.apps.values()].map(app => ` +
+
Public key: ${app.publicKey}
+
+ `) + this.$apps.innerHTML = content + + if (this.apps.size > 0) this.$noApps.remove() + } +}) + +// Can't use `uuid` module for some reason as it results in a throw with `crypto` when importing +function generateUuid () { + var result, i, j + result = '' + for (j = 0; j < 32; j++) { + if (j == 8 || j == 12 || j == 16 || j == 20) + result = result + '-' + i = Math.floor(Math.random() * 16).toString(16) + result = result + i + } + return result +} diff --git a/package.json b/package.json index 7e911e7..bb435c0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,12 @@ } }, "dependencies": { - "redhat-overpass-font": "^1.0.0" + "bare-path": "^2.1.0", + "pear-inspect": "github:holepunchto/pear-inspect#v1.0.1", + "redhat-overpass-font": "^1.0.0", + "ws": "^8.16.0" + }, + "optionalDependencies": { + "bufferutil": "^4.0.8" } }