init project
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
// @ts-check
|
||||
|
||||
/** @import { DevRuntime } from './runtime-extra-dev-common.js' */
|
||||
|
||||
/** @type {typeof DevRuntime} */
|
||||
// @ts-expect-error -- there's no way to declare a variable by JSDoc
|
||||
var BaseDevRuntime = DevRuntime;
|
||||
|
||||
class ModuleHotContext {
|
||||
/**
|
||||
* @type {{ deps: [string], fn: (moduleExports: Record<string, any>[]) => void }[]}
|
||||
*/
|
||||
acceptCallbacks = [];
|
||||
/**
|
||||
* @param {string} moduleId
|
||||
* @param {InstanceType<BaseDevRuntime>} devRuntime
|
||||
*/
|
||||
constructor(moduleId, devRuntime) {
|
||||
this.moduleId = moduleId;
|
||||
this.devRuntime = devRuntime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @param {(mod: Record<string, any>) => void} cb
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* @param {...any} args
|
||||
* @returns {void}
|
||||
*/
|
||||
accept(...args) {
|
||||
if (args.length === 1) {
|
||||
const [cb] = /** @type {[(mod: Record<string, any>) => void]} */ (args);
|
||||
const acceptingPath = this.moduleId;
|
||||
this.acceptCallbacks.push({
|
||||
deps: [acceptingPath],
|
||||
fn: cb,
|
||||
});
|
||||
} else if (args.length === 0) {}
|
||||
else {
|
||||
throw new Error('Invalid arguments for `import.meta.hot.accept`');
|
||||
}
|
||||
}
|
||||
|
||||
invalidate() {
|
||||
socket.send(JSON.stringify({
|
||||
type: 'hmr:invalidate',
|
||||
moduleId: this.moduleId,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultDevRuntime extends BaseDevRuntime {
|
||||
/**
|
||||
* @type {Map<string, ModuleHotContext>}
|
||||
*/
|
||||
moduleHotContexts = new Map();
|
||||
/**
|
||||
* @override
|
||||
* @param {string} moduleId
|
||||
*/
|
||||
createModuleHotContext(moduleId) {
|
||||
const hotContext = new ModuleHotContext(moduleId, this);
|
||||
this.moduleHotContexts.set(moduleId, hotContext);
|
||||
return hotContext;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {string} url */
|
||||
function loadScript(url) {
|
||||
var script = document.createElement('script');
|
||||
script.src = url;
|
||||
script.type = 'module';
|
||||
script.onerror = function() {
|
||||
console.error('Failed to load script: ' + url);
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
console.debug('HMR runtime loaded', '$ADDR');
|
||||
// Generate client ID immediately at runtime initialization
|
||||
// This ensures the client ID is available before any lazy imports
|
||||
const clientId = crypto.randomUUID();
|
||||
const addr = new URL('ws://$ADDR');
|
||||
addr.searchParams.set('clientId', clientId);
|
||||
|
||||
const socket = new WebSocket(addr);
|
||||
|
||||
(/** @type {any} */ (globalThis)).__rolldown_runtime__ ??=
|
||||
new DefaultDevRuntime(clientId);
|
||||
|
||||
/** @param {MessageEvent} event */
|
||||
socket.onmessage = function(event) {
|
||||
const data = JSON.parse(event.data);
|
||||
console.debug('Received message:', data);
|
||||
if (data.type === 'connected') {
|
||||
// Server acknowledged the connection
|
||||
console.debug('[hmr]: Connection established with server');
|
||||
} else if (data.type === 'hmr:update') {
|
||||
if (typeof process === 'object') {
|
||||
import(data.path);
|
||||
console.debug(`[hmr]: Importing HMR patch: ${data.path}`);
|
||||
} else {
|
||||
console.debug(`[hmr]: Loading HMR patch: ${data.path}`);
|
||||
loadScript(data.url);
|
||||
}
|
||||
} else if (data.type === 'hmr:reload') {
|
||||
console.log('[hmr]: Full reload required, reloading page');
|
||||
if (typeof location !== 'undefined') {
|
||||
location.reload();
|
||||
} else {
|
||||
console.log('[hmr]: location is undefined, cannot reload page');
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user