| import { t as createHooks } from "./hooks-K8FOq4rl.mjs"; | ||
| import module from "node:module"; | ||
| import process from "node:process"; | ||
| import { createBirpc } from "birpc"; | ||
| import Debug from "debug"; | ||
| //#region src/utils/debug.ts | ||
| const debug = Debug("unloader"); | ||
| //#endregion | ||
| //#region src/rpc.ts | ||
| const mainFunctions = { | ||
| log(...messages) { | ||
| console.info(...messages); | ||
| }, | ||
| debug(...args) { | ||
| debug(...args); | ||
| }, | ||
| enableSourceMap(enabled) { | ||
| process.setSourceMapsEnabled(enabled); | ||
| } | ||
| }; | ||
| function createRpc(port) { | ||
| return createBirpc(mainFunctions, { | ||
| post: (data) => port.postMessage(data), | ||
| on: (fn) => port.on("message", fn) | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/api.ts | ||
| function register(inlineConfig) { | ||
| if (!module.register) throw new Error(`This version of Node.js (${process.version}) does not support module.register(). Please upgrade to Node v20.6 and above.`); | ||
| const { port1, port2 } = new MessageChannel(); | ||
| const rpc = createRpc(port1); | ||
| port1.unref(); | ||
| const data = { | ||
| port: port2, | ||
| inlineConfig | ||
| }; | ||
| const transferList = [port2]; | ||
| module.register("./worker.mjs", { | ||
| parentURL: import.meta.url, | ||
| data, | ||
| transferList | ||
| }); | ||
| return () => rpc.deactivate(); | ||
| } | ||
| function registerSync(inlineConfig) { | ||
| const registerHooks = module.registerHooks; | ||
| if (!registerHooks) throw new Error(`This version of Node.js (${process.version}) does not support module.registerHooks(). Please upgrade to Node v22.15 or v23.5 and above.`); | ||
| const { init, resolve, load, deactivate } = createHooks(); | ||
| const context = { | ||
| log: (message) => console.info(message), | ||
| debug | ||
| }; | ||
| if (init.sync(context, inlineConfig).sourcemap && !process.sourceMapsEnabled) process.setSourceMapsEnabled(true); | ||
| registerHooks({ | ||
| resolve: resolve.sync, | ||
| load: load.sync | ||
| }); | ||
| return deactivate; | ||
| } | ||
| //#endregion | ||
| export { registerSync as n, register as t }; |
| import process from "node:process"; | ||
| import path from "node:path"; | ||
| import remapping from "@jridgewell/remapping"; | ||
| import { getIsAsync } from "quansync"; | ||
| import { quansync } from "quansync/macro"; | ||
| import { loadConfig } from "unconfig"; | ||
| import { Buffer } from "node:buffer"; | ||
| import { fileURLToPath, pathToFileURL } from "node:url"; | ||
| //#region src/utils/config.ts | ||
| const loadConfig$1 = quansync(function* () { | ||
| const { config } = yield loadConfig({ | ||
| sources: [{ | ||
| files: "unloader.config", | ||
| extensions: [ | ||
| "ts", | ||
| "mts", | ||
| "cts", | ||
| "js", | ||
| "mjs", | ||
| "cjs", | ||
| "json", | ||
| "" | ||
| ] | ||
| }], | ||
| cwd: process.cwd(), | ||
| defaults: {} | ||
| }); | ||
| return config; | ||
| }); | ||
| //#endregion | ||
| //#region src/utils/map.ts | ||
| function attachSourceMap(map, code) { | ||
| if (map) { | ||
| if (!map.sourcesContent || map.sourcesContent.length === 0) map.sourcesContent = [code]; | ||
| code += `\n//# sourceMappingURL=${toUrl(map)}`; | ||
| } | ||
| return code; | ||
| } | ||
| function toUrl(map) { | ||
| return `data:application/json;charset=utf-8;base64,${Buffer.from(map.toString()).toString("base64")}`; | ||
| } | ||
| //#endregion | ||
| //#region src/utils/url.ts | ||
| function urlToPath(url) { | ||
| if (!url) return url; | ||
| return url.startsWith("file://") ? fileURLToPath(url) : url; | ||
| } | ||
| function pathToUrl(isRequire, path$1) { | ||
| if (isRequire || path$1.startsWith("file://") || path$1.startsWith("data://") || path$1.startsWith("node:")) return path$1; | ||
| return pathToFileURL(path$1).href; | ||
| } | ||
| //#endregion | ||
| //#region src/hooks.ts | ||
| function createHooks() { | ||
| let config; | ||
| let deactivated = false; | ||
| let pluginContext; | ||
| const init = quansync(function* (context, inlineConfig) { | ||
| pluginContext = context; | ||
| config = inlineConfig || (yield loadConfig$1()); | ||
| for (const plugin of config.plugins || []) config = plugin.options?.(config) || config; | ||
| for (const plugin of config.plugins || []) { | ||
| yield plugin.buildStart?.(context); | ||
| context.debug(`loaded plugin: %s`, plugin.name); | ||
| } | ||
| return config; | ||
| }); | ||
| const resolve = quansync(function* (specifier, context, nextResolve) { | ||
| if (deactivated) return nextResolve(specifier, context); | ||
| const isRequire = !Array.isArray(context.conditions) || context.conditions[0] === "require"; | ||
| pluginContext?.debug(`resolving %s with context %o`, specifier, context); | ||
| if (config?.plugins && pluginContext) for (const plugin of config.plugins) { | ||
| const resolve$1 = createResolve(nextResolve, isRequire, pluginContext.debug); | ||
| const isAsync = yield getIsAsync(); | ||
| const result = yield plugin.resolveId?.call({ resolve: isAsync ? resolve$1 : resolve$1.sync }, urlToPath(specifier), urlToPath(context.parentURL), { | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (result) { | ||
| let output; | ||
| if (typeof result === "string") output = { | ||
| url: pathToUrl(isRequire, result), | ||
| importAttributes: context.importAttributes, | ||
| shortCircuit: true | ||
| }; | ||
| else output = { | ||
| url: pathToUrl(isRequire, result.id), | ||
| format: result.format, | ||
| importAttributes: result.attributes || context.importAttributes, | ||
| shortCircuit: true | ||
| }; | ||
| pluginContext.debug(`resolved %s to %s with format %s`, specifier, output.url, output.format); | ||
| return output; | ||
| } | ||
| } | ||
| return nextResolve(specifier, context); | ||
| }); | ||
| const load = quansync(function* (url, context, nextLoad) { | ||
| if (deactivated || !config?.plugins) return nextLoad(url, context); | ||
| pluginContext?.debug(`load %s with context %o`, url, context); | ||
| let result; | ||
| const defaultFormat = context.format || "module"; | ||
| const maps = []; | ||
| for (const plugin of config.plugins) { | ||
| const loadResult = yield plugin.load?.(urlToPath(url), { | ||
| format: context.format, | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (loadResult) { | ||
| if (isModuleSource(loadResult)) result = { | ||
| source: loadResult, | ||
| format: defaultFormat, | ||
| shortCircuit: true | ||
| }; | ||
| else { | ||
| if (loadResult.map) maps.unshift(loadResult.map); | ||
| result = { | ||
| source: loadResult.code, | ||
| format: loadResult.format || defaultFormat, | ||
| shortCircuit: true | ||
| }; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| result ||= yield nextLoad(url, context); | ||
| for (const plugin of config.plugins) { | ||
| const transformResult = yield plugin.transform?.(result.source || "", urlToPath(url), { | ||
| format: result.format, | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (transformResult) if (isModuleSource(transformResult)) result = { | ||
| ...result, | ||
| source: transformResult | ||
| }; | ||
| else { | ||
| if (transformResult.map) maps.unshift(transformResult.map); | ||
| result = { | ||
| ...result, | ||
| source: transformResult.code, | ||
| format: transformResult.format || result.format | ||
| }; | ||
| } | ||
| } | ||
| if (maps.length && typeof result.source === "string") result.source = attachSourceMap(remapping(maps, () => null), result.source); | ||
| return result; | ||
| }); | ||
| const deactivate = () => { | ||
| deactivated = true; | ||
| }; | ||
| return { | ||
| init, | ||
| resolve, | ||
| load, | ||
| deactivate | ||
| }; | ||
| } | ||
| function createResolve(nextResolve, isRequire, debug) { | ||
| return quansync(function* (source, importer, options) { | ||
| if (!path.isAbsolute(source) && importer) source = path.resolve(importer, "..", source); | ||
| try { | ||
| const resolved = yield nextResolve(pathToUrl(isRequire, source), { | ||
| parentURL: importer, | ||
| conditions: options?.conditions, | ||
| importAttributes: options?.attributes | ||
| }); | ||
| debug("resolved %s to %s with format %s", source, resolved.url, resolved.format); | ||
| return { | ||
| id: urlToPath(resolved.url), | ||
| attributes: resolved.importAttributes, | ||
| format: resolved.format | ||
| }; | ||
| } catch (error) { | ||
| debug("error resolving %s: %o", source, error); | ||
| return null; | ||
| } | ||
| }); | ||
| } | ||
| function isModuleSource(v) { | ||
| return typeof v === "string" || ArrayBuffer.isView(v) || v instanceof ArrayBuffer; | ||
| } | ||
| //#endregion | ||
| export { loadConfig$1 as n, createHooks as t }; |
| import { ImportAttributes, ModuleFormat, ModuleSource } from "node:module"; | ||
| import { QuansyncAwaitableGenerator } from "quansync"; | ||
| import { QuansyncFn } from "quansync/macro"; | ||
| import { MessagePort, Transferable } from "node:worker_threads"; | ||
| //#region src/plugin.d.ts | ||
| type Awaitable<T> = T | Promise<T>; | ||
| type FalsyValue = null | undefined | false | void; | ||
| interface ResolveMeta { | ||
| /** | ||
| * Export conditions of the relevant `package.json` | ||
| */ | ||
| conditions: string[]; | ||
| /** | ||
| * An object whose key-value pairs represent the assertions for the module to import | ||
| */ | ||
| attributes: ImportAttributes; | ||
| } | ||
| interface ResolvedId { | ||
| attributes?: ImportAttributes; | ||
| /** | ||
| * The absolute URL to which this input resolves | ||
| */ | ||
| id: string; | ||
| /** | ||
| * A hint to the load hook (it might be ignored) | ||
| */ | ||
| format?: ModuleFormat | (string & {}) | null | undefined; | ||
| } | ||
| interface LoadResult { | ||
| /** | ||
| * The source for Node.js to evaluate | ||
| */ | ||
| code?: ModuleSource | undefined; | ||
| map?: any; | ||
| format?: ModuleFormat; | ||
| } | ||
| interface PluginContext { | ||
| port?: MessagePort; | ||
| log: (message: any, transferList?: Transferable[]) => void; | ||
| debug: (...args: any[]) => void; | ||
| } | ||
| type ConditionalAwaitable<C, T> = (C extends true ? T : Awaitable<T>) | QuansyncAwaitableGenerator<T>; | ||
| type ResolveFn<Sync = false> = (source: string, importer?: string, options?: ResolveMeta) => ConditionalAwaitable<Sync, ResolvedId | null>; | ||
| interface Plugin<Sync = false> { | ||
| name: string; | ||
| options?: (config: UnloaderConfig<Sync>) => UnloaderConfig<Sync> | FalsyValue; | ||
| buildStart?: (context: PluginContext) => ConditionalAwaitable<Sync, void>; | ||
| resolveId?: (this: { | ||
| resolve: ResolveFn<Sync>; | ||
| }, source: string, importer: string | undefined, options: ResolveMeta) => ConditionalAwaitable<Sync, string | ResolvedId | FalsyValue>; | ||
| load?: (id: string, options: ResolveMeta & { | ||
| format: ModuleFormat | (string & {}) | null | undefined; | ||
| }) => ConditionalAwaitable<Sync, ModuleSource | LoadResult | FalsyValue>; | ||
| transform?: (code: ModuleSource, id: string, options: ResolveMeta & { | ||
| format: string | null | undefined; | ||
| }) => ConditionalAwaitable<Sync, ModuleSource | LoadResult | FalsyValue>; | ||
| } | ||
| //#endregion | ||
| //#region src/utils/config.d.ts | ||
| interface UnloaderConfig<Sync = false> { | ||
| sourcemap?: boolean; | ||
| plugins?: Plugin<Sync>[]; | ||
| } | ||
| declare const loadConfig: QuansyncFn<UnloaderConfig, []>; | ||
| //#endregion | ||
| //#region src/api.d.ts | ||
| declare function register(inlineConfig?: string): () => Promise<void>; | ||
| declare function registerSync(inlineConfig?: UnloaderConfig<true>): () => void; | ||
| //#endregion | ||
| //#region src/index.d.ts | ||
| declare function defineConfig(config: UnloaderConfig): UnloaderConfig; | ||
| declare function defineSyncConfig(config: UnloaderConfig<true>): UnloaderConfig<true>; | ||
| //#endregion | ||
| export { Awaitable, ConditionalAwaitable, FalsyValue, LoadResult, Plugin, PluginContext, ResolveFn, ResolveMeta, ResolvedId, UnloaderConfig, defineConfig, defineSyncConfig, loadConfig, register, registerSync }; |
| import { n as loadConfig } from "./hooks-K8FOq4rl.mjs"; | ||
| import { n as registerSync, t as register } from "./api-BuPeS9Bb.mjs"; | ||
| //#region src/index.ts | ||
| function defineConfig(config) { | ||
| return config; | ||
| } | ||
| function defineSyncConfig(config) { | ||
| return config; | ||
| } | ||
| //#endregion | ||
| export { defineConfig, defineSyncConfig, loadConfig, register, registerSync }; |
| export { }; |
| import "./hooks-K8FOq4rl.mjs"; | ||
| import { n as registerSync } from "./api-BuPeS9Bb.mjs"; | ||
| //#region src/register-sync.ts | ||
| registerSync(); | ||
| //#endregion | ||
| export { }; |
| export { }; |
| import "./hooks-K8FOq4rl.mjs"; | ||
| import { t as register } from "./api-BuPeS9Bb.mjs"; | ||
| //#region src/register.ts | ||
| register(); | ||
| //#endregion | ||
| export { }; |
| import { InitializeHook, LoadHook, ResolveHook } from "node:module"; | ||
| import { MessagePort } from "node:worker_threads"; | ||
| //#region src/worker.d.ts | ||
| interface Data { | ||
| port: MessagePort; | ||
| inlineConfig?: string; | ||
| } | ||
| declare const threadFunctions: { | ||
| deactivate(): void; | ||
| }; | ||
| type ThreadFunctions = typeof threadFunctions; | ||
| declare const initialize: InitializeHook; | ||
| declare const resolve: ResolveHook; | ||
| declare const load: LoadHook; | ||
| //#endregion | ||
| export { Data, ThreadFunctions, initialize, load, resolve }; |
| import { t as createHooks } from "./hooks-K8FOq4rl.mjs"; | ||
| import process from "node:process"; | ||
| import { createBirpc } from "birpc"; | ||
| //#region src/worker.ts | ||
| let data; | ||
| const hooks = createHooks(); | ||
| const threadFunctions = { deactivate() { | ||
| hooks.deactivate(); | ||
| } }; | ||
| let rpc; | ||
| const initialize = async (_data) => { | ||
| data = _data; | ||
| const { port } = data; | ||
| rpc = createBirpc(threadFunctions, { | ||
| post: (data$1) => port.postMessage(data$1), | ||
| on: (fn) => port.on("message", fn) | ||
| }); | ||
| const context = { | ||
| port, | ||
| log: (...args) => rpc.log(...args), | ||
| debug: (...args) => rpc.debug(...args) | ||
| }; | ||
| let inlineConfig; | ||
| if (data.inlineConfig) inlineConfig = (await import(data.inlineConfig)).default; | ||
| if ((await hooks.init(context, inlineConfig)).sourcemap && !process.sourceMapsEnabled) rpc.enableSourceMap(true); | ||
| }; | ||
| const resolve = hooks.resolve.async; | ||
| const load = hooks.load.async; | ||
| //#endregion | ||
| export { initialize, load, resolve }; |
+26
-25
| { | ||
| "name": "unloader", | ||
| "version": "0.5.0", | ||
| "version": "0.6.0", | ||
| "description": "Node.js loader with a Rollup-like interface.", | ||
@@ -20,9 +20,10 @@ "type": "module", | ||
| ], | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "main": "./dist/index.mjs", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.mts", | ||
| "exports": { | ||
| ".": "./dist/index.js", | ||
| "./register": "./dist/register.js", | ||
| "./register-sync": "./dist/register-sync.js", | ||
| ".": "./dist/index.mjs", | ||
| "./register": "./dist/register.mjs", | ||
| "./register-sync": "./dist/register-sync.mjs", | ||
| "./worker": "./dist/worker.mjs", | ||
| "./package.json": "./package.json" | ||
@@ -34,25 +35,25 @@ }, | ||
| "dependencies": { | ||
| "@jridgewell/remapping": "^2.3.4", | ||
| "birpc": "^2.5.0", | ||
| "debug": "^4.4.1", | ||
| "quansync": "^0.2.10", | ||
| "unconfig": "^7.3.2" | ||
| "@jridgewell/remapping": "^2.3.5", | ||
| "birpc": "^2.8.0", | ||
| "debug": "^4.4.3", | ||
| "quansync": "^0.2.11", | ||
| "unconfig": "^7.4.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@quansync/fs": "^0.1.4", | ||
| "@sxzz/eslint-config": "^7.1.2", | ||
| "@sxzz/prettier-config": "^2.2.3", | ||
| "@quansync/fs": "^0.1.5", | ||
| "@sxzz/eslint-config": "^7.2.8", | ||
| "@sxzz/prettier-config": "^2.2.4", | ||
| "@types/debug": "^4.1.12", | ||
| "@types/node": "^24.2.1", | ||
| "bumpp": "^10.2.2", | ||
| "eslint": "^9.33.0", | ||
| "magic-string": "^0.30.17", | ||
| "@types/node": "^24.10.0", | ||
| "bumpp": "^10.3.1", | ||
| "eslint": "^9.39.1", | ||
| "magic-string": "^0.30.21", | ||
| "prettier": "^3.6.2", | ||
| "tsdown": "^0.13.4", | ||
| "tsx": "^4.20.3", | ||
| "typescript": "^5.9.2", | ||
| "unplugin-quansync": "^0.4.3" | ||
| "tsdown": "^0.16.1", | ||
| "tsx": "^4.20.6", | ||
| "typescript": "^5.9.3", | ||
| "unplugin-quansync": "^0.4.5" | ||
| }, | ||
| "engines": { | ||
| "node": "^18.19.0 || >=20.6.0" | ||
| "node": ">=20.19.0" | ||
| }, | ||
@@ -68,4 +69,4 @@ "prettier": "@sxzz/prettier-config", | ||
| "format": "prettier --cache --write .", | ||
| "release": "bumpp && pnpm publish" | ||
| "release": "bumpp" | ||
| } | ||
| } |
| import { createHooks } from "./hooks-D5Gbo2El.js"; | ||
| import module from "node:module"; | ||
| import process from "node:process"; | ||
| import { createBirpc } from "birpc"; | ||
| import Debug from "debug"; | ||
| //#region src/utils/debug.ts | ||
| const debug = Debug("unloader"); | ||
| //#endregion | ||
| //#region src/rpc.ts | ||
| const mainFunctions = { | ||
| log(...messages) { | ||
| console.info(...messages); | ||
| }, | ||
| debug(...args) { | ||
| debug(...args); | ||
| }, | ||
| enableSourceMap(enabled) { | ||
| process.setSourceMapsEnabled(enabled); | ||
| } | ||
| }; | ||
| function createRpc(port) { | ||
| const rpc = createBirpc(mainFunctions, { | ||
| post: (data) => port.postMessage(data), | ||
| on: (fn) => port.on("message", fn) | ||
| }); | ||
| return rpc; | ||
| } | ||
| //#endregion | ||
| //#region src/api.ts | ||
| function register(inlineConfig) { | ||
| if (!module.register) throw new Error(`This version of Node.js (${process.version}) does not support module.register(). Please upgrade to Node v18.19 or v20.6 and above.`); | ||
| const { port1, port2 } = new MessageChannel(); | ||
| const rpc = createRpc(port1); | ||
| port1.unref(); | ||
| const data = { | ||
| port: port2, | ||
| inlineConfig | ||
| }; | ||
| const transferList = [port2]; | ||
| module.register("./worker.js", { | ||
| parentURL: import.meta.url, | ||
| data, | ||
| transferList | ||
| }); | ||
| return () => rpc.deactivate(); | ||
| } | ||
| function registerSync(inlineConfig) { | ||
| const registerHooks = module.registerHooks; | ||
| if (!registerHooks) throw new Error(`This version of Node.js (${process.version}) does not support module.registerHooks(). Please upgrade to Node v22.15 or v23.5 and above.`); | ||
| const { init, resolve, load, deactivate } = createHooks(); | ||
| const context = { | ||
| log: (message) => console.info(message), | ||
| debug | ||
| }; | ||
| const config = init.sync(context, inlineConfig); | ||
| if (config.sourcemap && !process.sourceMapsEnabled) process.setSourceMapsEnabled(true); | ||
| registerHooks({ | ||
| resolve: resolve.sync, | ||
| load: load.sync | ||
| }); | ||
| return deactivate; | ||
| } | ||
| //#endregion | ||
| export { register, registerSync }; |
| import process from "node:process"; | ||
| import path from "node:path"; | ||
| import remapping from "@jridgewell/remapping"; | ||
| import { getIsAsync } from "quansync"; | ||
| import { quansync } from "quansync/macro"; | ||
| import { loadConfig } from "unconfig"; | ||
| import { Buffer } from "node:buffer"; | ||
| import { fileURLToPath, pathToFileURL } from "node:url"; | ||
| //#region src/utils/config.ts | ||
| const loadConfig$1 = quansync(function* () { | ||
| const { config } = yield loadConfig({ | ||
| sources: [{ | ||
| files: "unloader.config", | ||
| extensions: [ | ||
| "ts", | ||
| "mts", | ||
| "cts", | ||
| "js", | ||
| "mjs", | ||
| "cjs", | ||
| "json", | ||
| "" | ||
| ] | ||
| }], | ||
| cwd: process.cwd(), | ||
| defaults: {} | ||
| }); | ||
| return config; | ||
| }); | ||
| //#endregion | ||
| //#region src/utils/map.ts | ||
| function attachSourceMap(map, code) { | ||
| if (map) { | ||
| if (!map.sourcesContent || map.sourcesContent.length === 0) map.sourcesContent = [code]; | ||
| code += `\n//# sourceMappingURL=${toUrl(map)}`; | ||
| } | ||
| return code; | ||
| } | ||
| function toUrl(map) { | ||
| return `data:application/json;charset=utf-8;base64,${Buffer.from(map.toString()).toString("base64")}`; | ||
| } | ||
| //#endregion | ||
| //#region src/utils/url.ts | ||
| function urlToPath(url) { | ||
| if (!url) return url; | ||
| return url.startsWith("file://") ? fileURLToPath(url) : url; | ||
| } | ||
| function pathToUrl(isRequire, path$1) { | ||
| if (isRequire || path$1.startsWith("file://") || path$1.startsWith("data://") || path$1.startsWith("node:")) return path$1; | ||
| return pathToFileURL(path$1).href; | ||
| } | ||
| //#endregion | ||
| //#region src/hooks.ts | ||
| function createHooks() { | ||
| let config; | ||
| let deactivated = false; | ||
| let pluginContext; | ||
| const init = quansync(function* (context, inlineConfig) { | ||
| pluginContext = context; | ||
| config = inlineConfig || (yield loadConfig$1()); | ||
| for (const plugin of config.plugins || []) config = plugin.options?.(config) || config; | ||
| for (const plugin of config.plugins || []) { | ||
| yield plugin.buildStart?.(context); | ||
| context.debug(`loaded plugin: %s`, plugin.name); | ||
| } | ||
| return config; | ||
| }); | ||
| const resolve = quansync(function* (specifier, context, nextResolve) { | ||
| if (deactivated) return nextResolve(specifier, context); | ||
| const isRequire = !Array.isArray(context.conditions) || context.conditions[0] === "require"; | ||
| pluginContext?.debug(`resolving %s with context %o`, specifier, context); | ||
| if (config?.plugins && pluginContext) for (const plugin of config.plugins) { | ||
| const resolve$1 = createResolve(nextResolve, isRequire, pluginContext.debug); | ||
| const isAsync = yield getIsAsync(); | ||
| const result = yield plugin.resolveId?.call({ resolve: isAsync ? resolve$1 : resolve$1.sync }, urlToPath(specifier), urlToPath(context.parentURL), { | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (result) { | ||
| let output; | ||
| if (typeof result === "string") output = { | ||
| url: pathToUrl(isRequire, result), | ||
| importAttributes: context.importAttributes, | ||
| shortCircuit: true | ||
| }; | ||
| else output = { | ||
| url: pathToUrl(isRequire, result.id), | ||
| format: result.format, | ||
| importAttributes: result.attributes || context.importAttributes, | ||
| shortCircuit: true | ||
| }; | ||
| pluginContext.debug(`resolved %s to %s with format %s`, specifier, output.url, output.format); | ||
| return output; | ||
| } | ||
| } | ||
| return nextResolve(specifier, context); | ||
| }); | ||
| const load = quansync(function* (url, context, nextLoad) { | ||
| if (deactivated || !config?.plugins) return nextLoad(url, context); | ||
| pluginContext?.debug(`load %s with context %o`, url, context); | ||
| let result; | ||
| const defaultFormat = context.format || "module"; | ||
| const maps = []; | ||
| for (const plugin of config.plugins) { | ||
| const loadResult = yield plugin.load?.(urlToPath(url), { | ||
| format: context.format, | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (loadResult) { | ||
| if (isModuleSource(loadResult)) result = { | ||
| source: loadResult, | ||
| format: defaultFormat, | ||
| shortCircuit: true | ||
| }; | ||
| else { | ||
| if (loadResult.map) maps.unshift(loadResult.map); | ||
| result = { | ||
| source: loadResult.code, | ||
| format: loadResult.format || defaultFormat, | ||
| shortCircuit: true | ||
| }; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| result ||= yield nextLoad(url, context); | ||
| for (const plugin of config.plugins) { | ||
| const transformResult = yield plugin.transform?.(result.source || "", urlToPath(url), { | ||
| format: result.format, | ||
| conditions: context.conditions, | ||
| attributes: context.importAttributes | ||
| }); | ||
| if (transformResult) if (isModuleSource(transformResult)) result = { | ||
| ...result, | ||
| source: transformResult | ||
| }; | ||
| else { | ||
| if (transformResult.map) maps.unshift(transformResult.map); | ||
| result = { | ||
| ...result, | ||
| source: transformResult.code, | ||
| format: transformResult.format || result.format | ||
| }; | ||
| } | ||
| } | ||
| if (maps.length && typeof result.source === "string") { | ||
| const map = remapping(maps, () => null); | ||
| const code = attachSourceMap(map, result.source); | ||
| result.source = code; | ||
| } | ||
| return result; | ||
| }); | ||
| const deactivate = () => { | ||
| deactivated = true; | ||
| }; | ||
| return { | ||
| init, | ||
| resolve, | ||
| load, | ||
| deactivate | ||
| }; | ||
| } | ||
| function createResolve(nextResolve, isRequire, debug) { | ||
| return quansync(function* (source, importer, options) { | ||
| if (!path.isAbsolute(source) && importer) source = path.resolve(importer, "..", source); | ||
| try { | ||
| const resolved = yield nextResolve(pathToUrl(isRequire, source), { | ||
| parentURL: importer, | ||
| conditions: options?.conditions, | ||
| importAttributes: options?.attributes | ||
| }); | ||
| debug("resolved %s to %s with format %s", source, resolved.url, resolved.format); | ||
| return { | ||
| id: urlToPath(resolved.url), | ||
| attributes: resolved.importAttributes, | ||
| format: resolved.format | ||
| }; | ||
| } catch (error) { | ||
| debug("error resolving %s: %o", source, error); | ||
| return null; | ||
| } | ||
| }); | ||
| } | ||
| function isModuleSource(v) { | ||
| return typeof v === "string" || ArrayBuffer.isView(v) || v instanceof ArrayBuffer; | ||
| } | ||
| //#endregion | ||
| export { createHooks, loadConfig$1 as loadConfig }; |
| import { ImportAttributes, ModuleFormat, ModuleSource } from "node:module"; | ||
| import { QuansyncAwaitableGenerator } from "quansync"; | ||
| import { QuansyncFn } from "quansync/macro"; | ||
| import { MessagePort, Transferable } from "node:worker_threads"; | ||
| //#region src/plugin.d.ts | ||
| type Awaitable<T> = T | Promise<T>; | ||
| type FalsyValue = null | undefined | false | void; | ||
| interface ResolveMeta { | ||
| /** | ||
| * Export conditions of the relevant `package.json` | ||
| */ | ||
| conditions: string[]; | ||
| /** | ||
| * An object whose key-value pairs represent the assertions for the module to import | ||
| */ | ||
| attributes: ImportAttributes; | ||
| } | ||
| interface ResolvedId { | ||
| attributes?: ImportAttributes; | ||
| /** | ||
| * The absolute URL to which this input resolves | ||
| */ | ||
| id: string; | ||
| /** | ||
| * A hint to the load hook (it might be ignored) | ||
| */ | ||
| format?: ModuleFormat | (string & {}) | null | undefined; | ||
| } | ||
| interface LoadResult { | ||
| /** | ||
| * The source for Node.js to evaluate | ||
| */ | ||
| code?: ModuleSource | undefined; | ||
| map?: any; | ||
| format?: ModuleFormat; | ||
| } | ||
| interface PluginContext { | ||
| port?: MessagePort; | ||
| log: (message: any, transferList?: Transferable[]) => void; | ||
| debug: (...args: any[]) => void; | ||
| } | ||
| type ConditionalAwaitable<C, T> = (C extends true ? T : Awaitable<T>) | QuansyncAwaitableGenerator<T>; | ||
| type ResolveFn<Sync = false> = (source: string, importer?: string, options?: ResolveMeta) => ConditionalAwaitable<Sync, ResolvedId | null>; | ||
| interface Plugin<Sync = false> { | ||
| name: string; | ||
| options?: (config: UnloaderConfig<Sync>) => UnloaderConfig<Sync> | FalsyValue; | ||
| buildStart?: (context: PluginContext) => ConditionalAwaitable<Sync, void>; | ||
| resolveId?: (this: { | ||
| resolve: ResolveFn<Sync>; | ||
| }, source: string, importer: string | undefined, options: ResolveMeta) => ConditionalAwaitable<Sync, string | ResolvedId | FalsyValue>; | ||
| load?: (id: string, options: ResolveMeta & { | ||
| format: ModuleFormat | (string & {}) | null | undefined; | ||
| }) => ConditionalAwaitable<Sync, ModuleSource | LoadResult | FalsyValue>; | ||
| transform?: (code: ModuleSource, id: string, options: ResolveMeta & { | ||
| format: string | null | undefined; | ||
| }) => ConditionalAwaitable<Sync, ModuleSource | LoadResult | FalsyValue>; | ||
| } | ||
| //#endregion | ||
| //#region src/utils/config.d.ts | ||
| interface UnloaderConfig<Sync = false> { | ||
| sourcemap?: boolean; | ||
| plugins?: Plugin<Sync>[]; | ||
| } | ||
| declare const loadConfig: QuansyncFn<UnloaderConfig, []>; | ||
| //#endregion | ||
| //#region src/api.d.ts | ||
| declare function register(inlineConfig?: string): () => Promise<void>; | ||
| declare function registerSync(inlineConfig?: UnloaderConfig<true>): () => void; | ||
| //#endregion | ||
| //#region src/index.d.ts | ||
| declare function defineConfig(config: UnloaderConfig): UnloaderConfig; | ||
| declare function defineSyncConfig(config: UnloaderConfig<true>): UnloaderConfig<true>; | ||
| //#endregion | ||
| export { Awaitable, ConditionalAwaitable, FalsyValue, LoadResult, Plugin, PluginContext, ResolveFn, ResolveMeta, ResolvedId, UnloaderConfig, defineConfig, defineSyncConfig, loadConfig, register, registerSync }; |
| import { loadConfig } from "./hooks-D5Gbo2El.js"; | ||
| import { register, registerSync } from "./api-CVKxaUrp.js"; | ||
| //#region src/index.ts | ||
| function defineConfig(config) { | ||
| return config; | ||
| } | ||
| function defineSyncConfig(config) { | ||
| return config; | ||
| } | ||
| //#endregion | ||
| export { defineConfig, defineSyncConfig, loadConfig, register, registerSync }; |
| export { }; |
| import "./hooks-D5Gbo2El.js"; | ||
| import { registerSync } from "./api-CVKxaUrp.js"; | ||
| //#region src/register-sync.ts | ||
| registerSync(); | ||
| //#endregion |
| export { }; |
| import "./hooks-D5Gbo2El.js"; | ||
| import { register } from "./api-CVKxaUrp.js"; | ||
| //#region src/register.ts | ||
| register(); | ||
| //#endregion |
| import { InitializeHook, LoadHook, ResolveHook } from "node:module"; | ||
| import { MessagePort } from "node:worker_threads"; | ||
| //#region src/worker.d.ts | ||
| interface Data { | ||
| port: MessagePort; | ||
| inlineConfig?: string; | ||
| } | ||
| declare const threadFunctions: { | ||
| deactivate(): void; | ||
| }; | ||
| type ThreadFunctions = typeof threadFunctions; | ||
| declare const initialize: InitializeHook; | ||
| declare const resolve: ResolveHook; | ||
| declare const load: LoadHook; | ||
| //#endregion | ||
| export { Data, ThreadFunctions, initialize, load, resolve }; |
| import { createHooks } from "./hooks-D5Gbo2El.js"; | ||
| import process from "node:process"; | ||
| import { createBirpc } from "birpc"; | ||
| //#region src/worker.ts | ||
| let data; | ||
| const hooks = createHooks(); | ||
| const threadFunctions = { deactivate() { | ||
| hooks.deactivate(); | ||
| } }; | ||
| let rpc; | ||
| const initialize = async (_data) => { | ||
| data = _data; | ||
| const { port } = data; | ||
| rpc = createBirpc(threadFunctions, { | ||
| post: (data$1) => port.postMessage(data$1), | ||
| on: (fn) => port.on("message", fn) | ||
| }); | ||
| const context = { | ||
| port, | ||
| log: (...args) => rpc.log(...args), | ||
| debug: (...args) => rpc.debug(...args) | ||
| }; | ||
| let inlineConfig; | ||
| if (data.inlineConfig) inlineConfig = (await import(data.inlineConfig)).default; | ||
| const config = await hooks.init(context, inlineConfig); | ||
| if (config.sourcemap && !process.sourceMapsEnabled) rpc.enableSourceMap(true); | ||
| }; | ||
| const resolve = hooks.resolve.async; | ||
| const load = hooks.load.async; | ||
| //#endregion | ||
| export { initialize, load, resolve }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
20240
-0.16%294
-24.03%Updated
Updated
Updated
Updated
Updated