|
| 1 | +import type { HubInstance } from '@devframes/hub/initiate' |
| 2 | +import { createUi } from '@devframes/hub-ui' |
| 3 | +import { DEVFRAMES_HUB_BASE, initHub } from '@devframes/hub/initiate' |
| 4 | +import { createA11yDevframe } from '@devframes/plugin-a11y' |
| 5 | +import { createAssetsDevframe } from '@devframes/plugin-assets' |
| 6 | +import { createCodeServerDevframe } from '@devframes/plugin-code-server' |
| 7 | +import { createDataInspectorDevframe } from '@devframes/plugin-data-inspector' |
| 8 | +import { createGitDevframe } from '@devframes/plugin-git' |
| 9 | +import { createInspectDevframe } from '@devframes/plugin-inspect' |
| 10 | +import { createMessagesDevframe } from '@devframes/plugin-messages' |
| 11 | +import { createOgDevframe } from '@devframes/plugin-og' |
| 12 | +import { createTerminalsDevframe } from '@devframes/plugin-terminals' |
| 13 | + |
| 14 | +// One `initHub` call, memoized on globalThis so a dev-time reload returns the |
| 15 | +// live hub instead of leaking transports. No `ws` option is passed: on Deno, |
| 16 | +// WebSockets arrive as fetch upgrades rather than `node:http` `upgrade` |
| 17 | +// events, so `src/server.ts` binds Deno's own transport to the hub context |
| 18 | +// and answers the upgrade route itself — the socket rides the app's own |
| 19 | +// origin with no side-car port. |
| 20 | +const globalRef = globalThis as { __hubDenoMinimal?: HubInstance } |
| 21 | + |
| 22 | +export const hub: HubInstance = globalRef.__hubDenoMinimal ??= initHub({ |
| 23 | + base: DEVFRAMES_HUB_BASE, |
| 24 | + // Every built-in plugin, dogfooded end to end through the hub mount path. |
| 25 | + // `data-inspector`'s default id carries `:` (a route-param marker), so it |
| 26 | + // gets a colon-free id override to be a valid `<base><id>/` segment; the |
| 27 | + // assets watcher is off since this host demonstrates mounting, not authoring. |
| 28 | + devframes: [ |
| 29 | + createGitDevframe(), |
| 30 | + createTerminalsDevframe(), |
| 31 | + createCodeServerDevframe(), |
| 32 | + createInspectDevframe(), |
| 33 | + createDataInspectorDevframe({ id: 'devframes_plugin_data-inspector' }), |
| 34 | + createA11yDevframe(), |
| 35 | + createMessagesDevframe(), |
| 36 | + createOgDevframe(), |
| 37 | + createAssetsDevframe({ watch: false }), |
| 38 | + ], |
| 39 | + // Rebrand the reference UI to Deno's own navy — one field, no CSS: |
| 40 | + // `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, |
| 41 | + // which the dock reads at connect time and feeds into `--devframe-primary` |
| 42 | + // (see `@devframes/hub-ui`'s `primary-ramp.css`). |
| 43 | + ui: createUi({ branding: { primaryColor: '#70ffaf', productName: 'Devframes on Deno' } }), |
| 44 | + // Gate with devframe's interactive OTP (the default). The hub prints a |
| 45 | + // 6-digit code + magic link on startup, and the reference UI's authorization |
| 46 | + // view exchanges it for a bearer token. See docs/guide/security.md. |
| 47 | + configure(ctx) { |
| 48 | + ctx.commands.register({ |
| 49 | + id: 'example:hub-deno-minimal:ping', |
| 50 | + title: 'Deno Hub · Ping', |
| 51 | + icon: 'ph:bell-duotone', |
| 52 | + category: 'kit', |
| 53 | + handler: () => 'pong', |
| 54 | + }) |
| 55 | + ctx.rpc.register({ |
| 56 | + name: 'example:hub-deno-minimal:probe', |
| 57 | + type: 'query', |
| 58 | + jsonSerializable: true, |
| 59 | + handler: () => 'pong', |
| 60 | + }) |
| 61 | + }, |
| 62 | +}) |
| 63 | + |
| 64 | +/** The host page — one script tag turns any page into a devtools host. */ |
| 65 | +export const hostPage = `<!doctype html> |
| 66 | +<html lang="en"> |
| 67 | + <head> |
| 68 | + <meta charset="UTF-8" /> |
| 69 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 70 | + <title>Deno Devframe Hub</title> |
| 71 | + </head> |
| 72 | + <body style="font-family: system-ui; padding: 2rem"> |
| 73 | + <h1>Deno Devframe Hub</h1> |
| 74 | + <p>This page is the host app. The devtools ride along:</p> |
| 75 | + <ul> |
| 76 | + <li>the floating dock (bottom of this page) is <code>/__devframes/embedded.js</code></li> |
| 77 | + <li>the standalone viewer lives at <a href="/__devframes/">/__devframes/</a></li> |
| 78 | + <li>discovery: <a href="/__devframes/__index.json">__index.json</a> · <a href="/__devframes/__connection.json">__connection.json</a></li> |
| 79 | + </ul> |
| 80 | + <script type="module" src="/__devframes/embedded.js"></script> |
| 81 | + </body> |
| 82 | +</html>` |
0 commit comments