made tiny updates
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
|
||||
import { build } from 'esbuild';
|
||||
import { readFileSync, writeFileSync, chmodSync } from 'node:fs';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const req = createRequire(import.meta.url);
|
||||
|
||||
// Node.js built-in module names (without and with the node: prefix).
|
||||
// Both forms must be listed so esbuild leaves them as-is whether the
|
||||
@@ -23,12 +26,31 @@ const NODE_BUILTINS = [
|
||||
'vm', 'worker_threads', 'zlib',
|
||||
];
|
||||
|
||||
// ── html2canvas text-embed plugin ────────────────────────────────────────────
|
||||
// Intercepts the import of html2canvas/dist/html2canvas.min.js and returns
|
||||
// its content as a default-exported string, so the proxy can serve it
|
||||
// locally (GET /__om_h2c__.js) without any CDN or runtime file reads.
|
||||
const html2canvasTextPlugin = {
|
||||
name: 'html2canvas-text',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /html2canvas\.min\.js$/ }, (args) => ({
|
||||
path: req.resolve('html2canvas/dist/html2canvas.min.js'),
|
||||
namespace: 'h2c-text',
|
||||
}));
|
||||
build.onLoad({ filter: /.*/, namespace: 'h2c-text' }, (args) => {
|
||||
const text = readFileSync(args.path, 'utf-8');
|
||||
return { contents: `export default ${JSON.stringify(text)}`, loader: 'js' };
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const SHARED_OPTIONS = {
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
target: 'node22',
|
||||
external: NODE_BUILTINS,
|
||||
plugins: [html2canvasTextPlugin],
|
||||
logLevel: 'info',
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"@originmain/renderer": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"typescript": "^5.5.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Declaration for the html2canvas minified bundle imported as a plain string.
|
||||
// The actual content is embedded at build time by the html2canvas-text esbuild
|
||||
// plugin in build.mjs — this file is only here to satisfy the TypeScript compiler.
|
||||
declare module 'html2canvas/dist/html2canvas.min.js' {
|
||||
const source: string;
|
||||
export default source;
|
||||
}
|
||||
@@ -38,23 +38,33 @@ const NEXT_PAGE_CONTENT = (componentName: string, importPath: string, isDefau
|
||||
// This file is deleted when the CLI stops (process.on('exit')).
|
||||
// Add __om_isolation__/ to your .gitignore to prevent accidental commits.
|
||||
import ${isDefault ? componentName : `{ ${componentName} }`} from '${importPath}';
|
||||
import { useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
// Expose render function for the host-to-iframe UPDATE_ISOLATION_PROPS protocol
|
||||
// IsolationPage renders the component in isolation and exposes
|
||||
// window.__OM_ISO_RENDER__ for the host-to-iframe UPDATE_ISOLATION_PROPS protocol.
|
||||
// Props are held in React state so calling __OM_ISO_RENDER__() causes a real re-render.
|
||||
function IsolationPage() {
|
||||
// Initialise from window.__OM_ISO_PROPS__ if the parent frame already set it.
|
||||
const [isoProps, setIsoProps] = useState<Record<string, unknown>>(
|
||||
() => (typeof window !== 'undefined' ? (window.__OM_ISO_PROPS__ ?? {}) : {})
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.__OM_ISO_RENDER__ = function() {
|
||||
// Force a re-render by dispatching a custom event — the component
|
||||
// reads window.__OM_ISO_PROPS__ in its own render cycle.
|
||||
// Make sure the global is initialised before the first render.
|
||||
window.__OM_ISO_PROPS__ = window.__OM_ISO_PROPS__ ?? {};
|
||||
// Register the render trigger. The host writes to window.__OM_ISO_PROPS__
|
||||
// then calls window.__OM_ISO_RENDER__(). setState with a new object reference
|
||||
// is what actually causes React to re-render the component with new props.
|
||||
window.__OM_ISO_RENDER__ = function () {
|
||||
setIsoProps({ ...(window.__OM_ISO_PROPS__ ?? {}) });
|
||||
};
|
||||
return () => {
|
||||
window.__OM_ISO_RENDER__ = undefined;
|
||||
};
|
||||
// Trigger initial render
|
||||
window.__OM_ISO_PROPS__ = window.__OM_ISO_PROPS__ || {};
|
||||
}, []);
|
||||
|
||||
// Read props from the isolation protocol global
|
||||
const props = (typeof window !== 'undefined' && window.__OM_ISO_PROPS__) ? window.__OM_ISO_PROPS__ : {};
|
||||
return <${componentName} {...(props as Record<string, unknown>)} />;
|
||||
return <${componentName} {...isoProps} />;
|
||||
}
|
||||
|
||||
export default IsolationPage;
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { IncomingMessage, ServerResponse,
|
||||
import type { Socket } from 'node:net';
|
||||
import { injectFiberHook } from './inject.js';
|
||||
import { handleIsolationRequest } from './isolation-server.js';
|
||||
import html2canvasSource from 'html2canvas/dist/html2canvas.min.js';
|
||||
|
||||
export interface ProxyOptions {
|
||||
/** Target dev server URL, e.g. "http://localhost:3000" */
|
||||
@@ -68,7 +69,25 @@ export function startProxy(opts: ProxyOptions): { close: () => void } {
|
||||
// Default port: 443 for HTTPS, 80 for HTTP — matches browser behaviour.
|
||||
const targetPort = parseInt(targetUrl.port || (isHttps ? '443' : '80'), 10);
|
||||
|
||||
// html2canvas source is embedded at build time by build.mjs's html2canvas-text
|
||||
// plugin. Convert to a Buffer once so repeated requests don't re-encode.
|
||||
const html2canvasBuf = Buffer.from(html2canvasSource, 'utf-8');
|
||||
|
||||
const server = createServer((clientReq: IncomingMessage, clientRes: ServerResponse) => {
|
||||
// ── Serve embedded html2canvas bundle (replaces CDN dependency) ───────
|
||||
// The fiber hook loads html2canvas via /__om_h2c__.js instead of unpkg so
|
||||
// the proxy works offline and is not blocked by restrictive CSP policies.
|
||||
if (clientReq.url === '/__om_h2c__.js') {
|
||||
clientRes.writeHead(200, {
|
||||
'content-type': 'application/javascript; charset=utf-8',
|
||||
'content-length': String(html2canvasBuf.byteLength),
|
||||
'cache-control': 'public, max-age=86400, immutable',
|
||||
...CORS_HEADERS,
|
||||
});
|
||||
clientRes.end(html2canvasBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Intercept /__om_isolation__/* requests ────────────────────────────
|
||||
if (clientReq.url?.startsWith('/__om_isolation__')) {
|
||||
handleIsolationRequest(clientReq, clientRes);
|
||||
|
||||
Reference in New Issue
Block a user