init project
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
# `@rolldown/binding-wasm32-wasi`
|
||||
|
||||
This is the **wasm32-wasip1-threads** binary for `@rolldown/binding`
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@rolldown/binding-wasm32-wasi",
|
||||
"version": "1.2.1",
|
||||
"main": "rolldown-binding.wasi.cjs",
|
||||
"files": [
|
||||
"rolldown-binding.wasm32-wasi.wasm",
|
||||
"rolldown-binding.wasi.cjs",
|
||||
"rolldown-binding.wasi.d.cts",
|
||||
"rolldown-binding.wasi-browser.js",
|
||||
"wasi-worker.mjs",
|
||||
"wasi-worker-browser.mjs"
|
||||
],
|
||||
"description": "Fast JavaScript/TypeScript bundler in Rust with Rollup-compatible API.",
|
||||
"keywords": [
|
||||
"bundler",
|
||||
"esbuild",
|
||||
"parcel",
|
||||
"rolldown",
|
||||
"rollup",
|
||||
"webpack"
|
||||
],
|
||||
"homepage": "https://rolldown.rs/",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.13.0 || >=23.5.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rolldown/rolldown.git",
|
||||
"directory": "packages/rolldown"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "public"
|
||||
},
|
||||
"types": "rolldown-binding.wasi.d.cts",
|
||||
"browser": "rolldown-binding.wasi-browser.js",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.2.0",
|
||||
"@emnapi/core": "2.0.0-alpha.3",
|
||||
"@emnapi/runtime": "2.0.0-alpha.3"
|
||||
}
|
||||
}
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
import {
|
||||
emnapiAsyncWorkPlugin as __emnapiAsyncWorkPlugin,
|
||||
emnapiTSFNPlugin as __emnapiTSFNPlugin,
|
||||
createOnMessage as __wasmCreateOnMessageForFsProxy,
|
||||
instantiateNapiModule as __emnapiInstantiateNapiModule,
|
||||
WASI as __WASI,
|
||||
} from '@napi-rs/wasm-runtime'
|
||||
import { createContext as __emnapiCreateContext } from '@emnapi/runtime'
|
||||
import { memfs } from '@napi-rs/wasm-runtime/fs'
|
||||
|
||||
|
||||
export const { fs: __fs, vol: __volume } = memfs()
|
||||
|
||||
const __wasi = new __WASI({
|
||||
version: 'preview1',
|
||||
fs: __fs,
|
||||
preopens: {
|
||||
'/': '/',
|
||||
},
|
||||
})
|
||||
|
||||
const __wasmUrl = new URL('./rolldown-binding.wasm32-wasi.wasm', import.meta.url).href
|
||||
const __wasmResponse = await globalThis.fetch(__wasmUrl)
|
||||
if (!__wasmResponse.ok) {
|
||||
throw new Error(
|
||||
'Failed to fetch WASI module ' +
|
||||
__wasmUrl +
|
||||
': ' +
|
||||
__wasmResponse.status +
|
||||
' ' +
|
||||
(__wasmResponse.statusText || 'Unknown Status'),
|
||||
)
|
||||
}
|
||||
const __wasmFile = await __wasmResponse.arrayBuffer()
|
||||
|
||||
const __sharedMemory = new WebAssembly.Memory({
|
||||
initial: 16384,
|
||||
maximum: 65536,
|
||||
shared: true,
|
||||
})
|
||||
|
||||
let __emnapiContext
|
||||
|
||||
const __wasiDisposeSymbol = Symbol.for('napi.rs.wasi.dispose')
|
||||
const __wasiWorkers = new Set()
|
||||
let __napiInstance
|
||||
let __emnapiContextDestroyed = false
|
||||
let __emnapiContextDestroyPromise
|
||||
let __emnapiWasmEnvCleanupPrepared = false
|
||||
let __wasiDisposed = false
|
||||
let __wasiDisposePromise
|
||||
let __completeWasiDisposal = function() {}
|
||||
|
||||
function __isThenable(value) {
|
||||
return (
|
||||
value !== null &&
|
||||
(typeof value === 'object' || typeof value === 'function') &&
|
||||
typeof value.then === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
function __createCleanupError(errors, message) {
|
||||
if (errors.length === 1) {
|
||||
return errors[0]
|
||||
}
|
||||
const __AggregateError = globalThis.AggregateError
|
||||
if (typeof __AggregateError === 'function') {
|
||||
return new __AggregateError(errors, message)
|
||||
}
|
||||
const error = new Error(message)
|
||||
error.errors = errors
|
||||
return error
|
||||
}
|
||||
|
||||
function __attachCleanupErrors(error, cleanupErrors) {
|
||||
if (cleanupErrors.length === 0) {
|
||||
return error
|
||||
}
|
||||
const cleanupError = __createCleanupError(
|
||||
cleanupErrors,
|
||||
'WASI binding cleanup failed',
|
||||
)
|
||||
try {
|
||||
if (
|
||||
error &&
|
||||
(typeof error === 'object' || typeof error === 'function')
|
||||
) {
|
||||
if (error.cause === undefined) {
|
||||
error.cause = cleanupError
|
||||
if (error.cause === cleanupError) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
if (Array.isArray(error.cleanupErrors)) {
|
||||
error.cleanupErrors.push(cleanupError)
|
||||
return error
|
||||
} else {
|
||||
const attachedCleanupErrors = [cleanupError]
|
||||
error.cleanupErrors = attachedCleanupErrors
|
||||
if (error.cleanupErrors === attachedCleanupErrors) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
const aggregate = __createCleanupError(
|
||||
[error, cleanupError],
|
||||
'WASI binding initialization and cleanup failed',
|
||||
)
|
||||
try {
|
||||
aggregate.cause = error
|
||||
} catch {}
|
||||
return aggregate
|
||||
}
|
||||
|
||||
function __prepareWasmEnvCleanup() {
|
||||
if (__emnapiWasmEnvCleanupPrepared) {
|
||||
return
|
||||
}
|
||||
const prepare = __napiInstance?.exports?.napi_prepare_wasm_env_cleanup
|
||||
if (typeof prepare === 'function') {
|
||||
prepare()
|
||||
}
|
||||
__emnapiWasmEnvCleanupPrepared = true
|
||||
}
|
||||
|
||||
function __destroyEmnapiContext() {
|
||||
if (__emnapiContextDestroyed || __emnapiContext === undefined) {
|
||||
__emnapiContextDestroyed = true
|
||||
return
|
||||
}
|
||||
if (__emnapiContextDestroyPromise) {
|
||||
return __emnapiContextDestroyPromise
|
||||
}
|
||||
|
||||
__prepareWasmEnvCleanup()
|
||||
const result = __emnapiContext.destroy()
|
||||
if (!__isThenable(result)) {
|
||||
__emnapiContextDestroyed = true
|
||||
return
|
||||
}
|
||||
|
||||
const destroyPromise = Promise.resolve(result).then(
|
||||
(value) => {
|
||||
__emnapiContextDestroyed = true
|
||||
return value
|
||||
},
|
||||
(error) => {
|
||||
__emnapiContextDestroyPromise = undefined
|
||||
throw error
|
||||
},
|
||||
)
|
||||
__emnapiContextDestroyPromise = destroyPromise
|
||||
return destroyPromise
|
||||
}
|
||||
|
||||
function __terminateWasiWorkers() {
|
||||
const cleanupErrors = []
|
||||
const pending = []
|
||||
|
||||
for (const worker of __wasiWorkers) {
|
||||
let result
|
||||
try {
|
||||
result = worker.terminate()
|
||||
} catch (error) {
|
||||
cleanupErrors.push(error)
|
||||
continue
|
||||
}
|
||||
if (__isThenable(result)) {
|
||||
pending.push(
|
||||
Promise.resolve(result).then(
|
||||
() => {
|
||||
__wasiWorkers.delete(worker)
|
||||
},
|
||||
(error) => {
|
||||
cleanupErrors.push(error)
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
__wasiWorkers.delete(worker)
|
||||
}
|
||||
}
|
||||
|
||||
const finish = () => {
|
||||
if (cleanupErrors.length > 0) {
|
||||
throw __createCleanupError(
|
||||
cleanupErrors,
|
||||
'Failed to terminate WASI workers',
|
||||
)
|
||||
}
|
||||
}
|
||||
return pending.length > 0 ? Promise.all(pending).then(finish) : finish()
|
||||
}
|
||||
|
||||
function __finishWasiDisposal() {
|
||||
const workerResult = __terminateWasiWorkers()
|
||||
if (__isThenable(workerResult)) {
|
||||
return Promise.resolve(workerResult).then(__completeWasiDisposal)
|
||||
}
|
||||
return __completeWasiDisposal()
|
||||
}
|
||||
|
||||
function __startWasiDisposal() {
|
||||
const destroyResult = __destroyEmnapiContext()
|
||||
if (__isThenable(destroyResult)) {
|
||||
return Promise.resolve(destroyResult).then(__finishWasiDisposal)
|
||||
}
|
||||
return __finishWasiDisposal()
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes this generated WASI binding.
|
||||
*
|
||||
* Access this function with:
|
||||
* binding[Symbol.for('napi.rs.wasi.dispose')]()
|
||||
*/
|
||||
function __disposeWasiBinding() {
|
||||
if (__wasiDisposePromise) {
|
||||
return __wasiDisposePromise
|
||||
}
|
||||
if (__wasiDisposed) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
let resolveDispose
|
||||
let rejectDispose
|
||||
const disposePromise = new Promise((resolve, reject) => {
|
||||
resolveDispose = resolve
|
||||
rejectDispose = reject
|
||||
})
|
||||
__wasiDisposePromise = disposePromise
|
||||
|
||||
let result
|
||||
try {
|
||||
result = __startWasiDisposal()
|
||||
} catch (error) {
|
||||
__wasiDisposePromise = undefined
|
||||
rejectDispose(error)
|
||||
return disposePromise
|
||||
}
|
||||
|
||||
Promise.resolve(result).then(
|
||||
(value) => {
|
||||
__wasiDisposed = true
|
||||
resolveDispose(value)
|
||||
},
|
||||
(error) => {
|
||||
__wasiDisposePromise = undefined
|
||||
rejectDispose(error)
|
||||
},
|
||||
)
|
||||
return disposePromise
|
||||
}
|
||||
|
||||
function __publishWasiDispose(exports) {
|
||||
Object.defineProperty(exports, __wasiDisposeSymbol, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: __disposeWasiBinding,
|
||||
writable: false,
|
||||
})
|
||||
}
|
||||
|
||||
function __finishWasiInitializationRollback(cleanupErrors) {
|
||||
let workerResult
|
||||
try {
|
||||
workerResult = __terminateWasiWorkers()
|
||||
} catch (cleanupError) {
|
||||
cleanupErrors.push(cleanupError)
|
||||
return cleanupErrors
|
||||
}
|
||||
if (__isThenable(workerResult)) {
|
||||
return Promise.resolve(workerResult)
|
||||
.catch((cleanupError) => {
|
||||
cleanupErrors.push(cleanupError)
|
||||
})
|
||||
.then(() => cleanupErrors)
|
||||
}
|
||||
return cleanupErrors
|
||||
}
|
||||
|
||||
function __rollbackWasiInitialization() {
|
||||
const cleanupErrors = []
|
||||
let destroyResult
|
||||
try {
|
||||
destroyResult = __destroyEmnapiContext()
|
||||
} catch (cleanupError) {
|
||||
cleanupErrors.push(cleanupError)
|
||||
return __finishWasiInitializationRollback(cleanupErrors)
|
||||
}
|
||||
if (__isThenable(destroyResult)) {
|
||||
return Promise.resolve(destroyResult)
|
||||
.catch((cleanupError) => {
|
||||
cleanupErrors.push(cleanupError)
|
||||
})
|
||||
.then(() => __finishWasiInitializationRollback(cleanupErrors))
|
||||
}
|
||||
return __finishWasiInitializationRollback(cleanupErrors)
|
||||
}
|
||||
|
||||
let __wasiModule
|
||||
let __napiModule
|
||||
|
||||
try {
|
||||
__emnapiContext = __emnapiCreateContext({ autoDestroy: false })
|
||||
__emnapiContext.suppressDestroy()
|
||||
|
||||
;({
|
||||
instance: __napiInstance,
|
||||
module: __wasiModule,
|
||||
napiModule: __napiModule,
|
||||
} = await __emnapiInstantiateNapiModule(__wasmFile, {
|
||||
context: __emnapiContext,
|
||||
asyncWorkPoolSize: 4,
|
||||
plugins: [__emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
|
||||
wasi: __wasi,
|
||||
onCreateWorker() {
|
||||
const worker = new Worker(new URL('@rolldown/binding-wasm32-wasi/wasi-worker-browser.mjs', import.meta.url), {
|
||||
type: 'module',
|
||||
})
|
||||
__wasiWorkers.add(worker)
|
||||
worker.addEventListener('message', __wasmCreateOnMessageForFsProxy(__fs))
|
||||
|
||||
worker.addEventListener('message', (event) => {
|
||||
if (event.data && typeof event.data === 'object' && event.data.type === 'error') {
|
||||
const __CustomEvent = globalThis.CustomEvent
|
||||
if (
|
||||
typeof globalThis.dispatchEvent === 'function' &&
|
||||
typeof __CustomEvent === 'function'
|
||||
) {
|
||||
globalThis.dispatchEvent(
|
||||
new __CustomEvent('napi-rs-worker-error', { detail: event.data }),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return worker
|
||||
},
|
||||
overwriteImports(importObject) {
|
||||
importObject.env = {
|
||||
...importObject.env,
|
||||
...importObject.napi,
|
||||
...importObject.emnapi,
|
||||
memory: __sharedMemory,
|
||||
}
|
||||
return importObject
|
||||
},
|
||||
beforeInit({ instance }) {
|
||||
__napiInstance = instance
|
||||
for (const name of Object.keys(instance.exports)) {
|
||||
if (name.startsWith('__napi_register__')) {
|
||||
instance.exports[name]()
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
__publishWasiDispose(__napiModule.exports)
|
||||
} catch (error) {
|
||||
const cleanupErrors = await __rollbackWasiInitialization()
|
||||
throw __attachCleanupErrors(error, cleanupErrors)
|
||||
}
|
||||
export default __napiModule.exports
|
||||
export const LegalCommentsMode = __napiModule.exports.LegalCommentsMode
|
||||
export const minify = __napiModule.exports.minify
|
||||
export const minifySync = __napiModule.exports.minifySync
|
||||
export const Severity = __napiModule.exports.Severity
|
||||
export const ParseResult = __napiModule.exports.ParseResult
|
||||
export const ExportExportNameKind = __napiModule.exports.ExportExportNameKind
|
||||
export const ExportImportNameKind = __napiModule.exports.ExportImportNameKind
|
||||
export const ExportLocalNameKind = __napiModule.exports.ExportLocalNameKind
|
||||
export const ImportNameKind = __napiModule.exports.ImportNameKind
|
||||
export const parse = __napiModule.exports.parse
|
||||
export const parseSync = __napiModule.exports.parseSync
|
||||
export const rawTransferSupported = __napiModule.exports.rawTransferSupported
|
||||
export const ResolverFactory = __napiModule.exports.ResolverFactory
|
||||
export const EnforceExtension = __napiModule.exports.EnforceExtension
|
||||
export const ModuleType = __napiModule.exports.ModuleType
|
||||
export const sync = __napiModule.exports.sync
|
||||
export const HelperMode = __napiModule.exports.HelperMode
|
||||
export const isolatedDeclaration = __napiModule.exports.isolatedDeclaration
|
||||
export const isolatedDeclarationSync = __napiModule.exports.isolatedDeclarationSync
|
||||
export const moduleRunnerTransform = __napiModule.exports.moduleRunnerTransform
|
||||
export const moduleRunnerTransformSync = __napiModule.exports.moduleRunnerTransformSync
|
||||
export const transform = __napiModule.exports.transform
|
||||
export const transformSync = __napiModule.exports.transformSync
|
||||
export const BindingBundleEndEventData = __napiModule.exports.BindingBundleEndEventData
|
||||
export const BindingBundleErrorEventData = __napiModule.exports.BindingBundleErrorEventData
|
||||
export const BindingBundler = __napiModule.exports.BindingBundler
|
||||
export const BindingCallableBuiltinPlugin = __napiModule.exports.BindingCallableBuiltinPlugin
|
||||
export const BindingChunkingContext = __napiModule.exports.BindingChunkingContext
|
||||
export const BindingDecodedMap = __napiModule.exports.BindingDecodedMap
|
||||
export const BindingDevEngine = __napiModule.exports.BindingDevEngine
|
||||
export const BindingLoadPluginContext = __napiModule.exports.BindingLoadPluginContext
|
||||
export const BindingMagicString = __napiModule.exports.BindingMagicString
|
||||
export const BindingModuleInfo = __napiModule.exports.BindingModuleInfo
|
||||
export const BindingNormalizedOptions = __napiModule.exports.BindingNormalizedOptions
|
||||
export const BindingOutputAsset = __napiModule.exports.BindingOutputAsset
|
||||
export const BindingOutputChunk = __napiModule.exports.BindingOutputChunk
|
||||
export const BindingPluginContext = __napiModule.exports.BindingPluginContext
|
||||
export const BindingRenderedChunk = __napiModule.exports.BindingRenderedChunk
|
||||
export const BindingRenderedChunkMeta = __napiModule.exports.BindingRenderedChunkMeta
|
||||
export const BindingRenderedModule = __napiModule.exports.BindingRenderedModule
|
||||
export const BindingSourceMap = __napiModule.exports.BindingSourceMap
|
||||
export const BindingTransformPluginContext = __napiModule.exports.BindingTransformPluginContext
|
||||
export const BindingWatcher = __napiModule.exports.BindingWatcher
|
||||
export const BindingWatcherBundler = __napiModule.exports.BindingWatcherBundler
|
||||
export const BindingWatcherChangeData = __napiModule.exports.BindingWatcherChangeData
|
||||
export const BindingWatcherEvent = __napiModule.exports.BindingWatcherEvent
|
||||
export const ParallelJsPluginRegistry = __napiModule.exports.ParallelJsPluginRegistry
|
||||
export const TraceSubscriberGuard = __napiModule.exports.TraceSubscriberGuard
|
||||
export const TsconfigCache = __napiModule.exports.TsconfigCache
|
||||
export const BindingAttachDebugInfo = __napiModule.exports.BindingAttachDebugInfo
|
||||
export const BindingBuiltinPluginName = __napiModule.exports.BindingBuiltinPluginName
|
||||
export const BindingChunkModuleOrderBy = __napiModule.exports.BindingChunkModuleOrderBy
|
||||
export const BindingErrorStage = __napiModule.exports.BindingErrorStage
|
||||
export const BindingLogLevel = __napiModule.exports.BindingLogLevel
|
||||
export const BindingPluginOrder = __napiModule.exports.BindingPluginOrder
|
||||
export const BindingPropertyReadSideEffects = __napiModule.exports.BindingPropertyReadSideEffects
|
||||
export const BindingPropertyWriteSideEffects = __napiModule.exports.BindingPropertyWriteSideEffects
|
||||
export const BindingRebuildStrategy = __napiModule.exports.BindingRebuildStrategy
|
||||
export const collapseSourcemaps = __napiModule.exports.collapseSourcemaps
|
||||
export const enhancedTransform = __napiModule.exports.enhancedTransform
|
||||
export const enhancedTransformSync = __napiModule.exports.enhancedTransformSync
|
||||
export const FilterTokenKind = __napiModule.exports.FilterTokenKind
|
||||
export const initTraceSubscriber = __napiModule.exports.initTraceSubscriber
|
||||
export const registerPlugins = __napiModule.exports.registerPlugins
|
||||
export const resolveTsconfig = __napiModule.exports.resolveTsconfig
|
||||
export const shutdownAsyncRuntime = __napiModule.exports.shutdownAsyncRuntime
|
||||
export const startAsyncRuntime = __napiModule.exports.startAsyncRuntime
|
||||
+722
@@ -0,0 +1,722 @@
|
||||
// napi-rs-artifact-metadata:{"version":2,"rootEntry":"binding.cjs","exports":["LegalCommentsMode","minify","minifySync","Severity","ParseResult","ExportExportNameKind","ExportImportNameKind","ExportLocalNameKind","ImportNameKind","parse","parseSync","rawTransferSupported","ResolverFactory","EnforceExtension","ModuleType","sync","HelperMode","isolatedDeclaration","isolatedDeclarationSync","moduleRunnerTransform","moduleRunnerTransformSync","transform","transformSync","BindingBundleEndEventData","BindingBundleErrorEventData","BindingBundler","BindingCallableBuiltinPlugin","BindingChunkingContext","BindingDecodedMap","BindingDevEngine","BindingLoadPluginContext","BindingMagicString","BindingModuleInfo","BindingNormalizedOptions","BindingOutputAsset","BindingOutputChunk","BindingPluginContext","BindingRenderedChunk","BindingRenderedChunkMeta","BindingRenderedModule","BindingSourceMap","BindingTransformPluginContext","BindingWatcher","BindingWatcherBundler","BindingWatcherChangeData","BindingWatcherEvent","ParallelJsPluginRegistry","TraceSubscriberGuard","TsconfigCache","BindingAttachDebugInfo","BindingBuiltinPluginName","BindingChunkModuleOrderBy","BindingErrorStage","BindingLogLevel","BindingPluginOrder","BindingPropertyReadSideEffects","BindingPropertyWriteSideEffects","BindingRebuildStrategy","collapseSourcemaps","enhancedTransform","enhancedTransformSync","FilterTokenKind","initTraceSubscriber","registerPlugins","resolveTsconfig","shutdownAsyncRuntime","startAsyncRuntime"],"managedRootEntries":["browser.js","binding.cjs","rolldown-binding.wasm","rolldown-binding.debug.wasm"]}
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
const __nodeFs = require('node:fs')
|
||||
const __nodePath = require('node:path')
|
||||
const { WASI: __nodeWASI } = require('node:wasi')
|
||||
const { Worker } = require('node:worker_threads')
|
||||
|
||||
const {
|
||||
emnapiAsyncWorkPlugin: __emnapiAsyncWorkPlugin,
|
||||
emnapiTSFNPlugin: __emnapiTSFNPlugin,
|
||||
createOnMessage: __wasmCreateOnMessageForFsProxy,
|
||||
instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync,
|
||||
} = require('@napi-rs/wasm-runtime')
|
||||
const { createContext: __emnapiCreateContext } = require('@emnapi/runtime')
|
||||
|
||||
function __getWasiWorkerExecArgv() {
|
||||
const __workerExecArgv = []
|
||||
for (let __index = 0; __index < process.execArgv.length; __index += 1) {
|
||||
const __arg = process.execArgv[__index]
|
||||
if (
|
||||
__arg === '--input-type' ||
|
||||
__arg === '--eval' ||
|
||||
__arg === '-e' ||
|
||||
__arg === '--print' ||
|
||||
__arg === '-p'
|
||||
) {
|
||||
__index += 1
|
||||
continue
|
||||
}
|
||||
if (
|
||||
__arg.startsWith('--input-type=') ||
|
||||
__arg.startsWith('--eval=') ||
|
||||
__arg.startsWith('--print=')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
__workerExecArgv.push(__arg)
|
||||
}
|
||||
return __workerExecArgv
|
||||
}
|
||||
|
||||
function __isInvalidWasiWorkerExecArgv(errorMessage, argument) {
|
||||
const __equalsIndex = argument.indexOf('=')
|
||||
const __argumentName =
|
||||
__equalsIndex === -1 ? argument : argument.slice(0, __equalsIndex)
|
||||
return (
|
||||
errorMessage.includes(': ' + __argumentName + ',') ||
|
||||
errorMessage.includes(': ' + __argumentName + '=') ||
|
||||
errorMessage.endsWith(': ' + __argumentName) ||
|
||||
errorMessage.includes(', ' + __argumentName + ',') ||
|
||||
errorMessage.includes(', ' + __argumentName + '=') ||
|
||||
errorMessage.endsWith(', ' + __argumentName)
|
||||
)
|
||||
}
|
||||
|
||||
function __removeInvalidWasiWorkerExecArgv(execArgv, error) {
|
||||
if (typeof error.message !== 'string') {
|
||||
return
|
||||
}
|
||||
const __workerExecArgv = []
|
||||
let __removed = false
|
||||
for (let __index = 0; __index < execArgv.length; __index += 1) {
|
||||
const __arg = execArgv[__index]
|
||||
if (
|
||||
__arg.startsWith('-') &&
|
||||
__isInvalidWasiWorkerExecArgv(error.message, __arg)
|
||||
) {
|
||||
__removed = true
|
||||
if (
|
||||
!__arg.includes('=') &&
|
||||
__index + 1 < execArgv.length &&
|
||||
!execArgv[__index + 1].startsWith('-')
|
||||
) {
|
||||
__index += 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
__workerExecArgv.push(__arg)
|
||||
}
|
||||
return __removed ? __workerExecArgv : undefined
|
||||
}
|
||||
|
||||
function __createWasiWorker(filename) {
|
||||
let __workerExecArgv = __getWasiWorkerExecArgv()
|
||||
while (true) {
|
||||
try {
|
||||
return new Worker(filename, {
|
||||
env: process.env,
|
||||
execArgv: __workerExecArgv,
|
||||
})
|
||||
} catch (error) {
|
||||
if (!error || error.code !== 'ERR_WORKER_INVALID_EXEC_ARGV') {
|
||||
throw error
|
||||
}
|
||||
const __nextWorkerExecArgv =
|
||||
__removeInvalidWasiWorkerExecArgv(__workerExecArgv, error)
|
||||
if (!__nextWorkerExecArgv) {
|
||||
throw error
|
||||
}
|
||||
__workerExecArgv = __nextWorkerExecArgv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const __rootDir = __nodePath.parse(process.cwd()).root
|
||||
|
||||
const __wasi = new __nodeWASI({
|
||||
version: 'preview1',
|
||||
env: process.env,
|
||||
preopens: {
|
||||
[__rootDir]: __rootDir,
|
||||
}
|
||||
})
|
||||
|
||||
const __sharedMemory = new WebAssembly.Memory({
|
||||
initial: 16384,
|
||||
maximum: 65536,
|
||||
shared: true,
|
||||
})
|
||||
|
||||
let __wasmFilePath = __nodePath.join(__dirname, 'rolldown-binding.wasm32-wasi.wasm')
|
||||
const __wasmDebugFilePath = __nodePath.join(__dirname, 'rolldown-binding.wasm32-wasi.debug.wasm')
|
||||
|
||||
if (__nodeFs.existsSync(__wasmDebugFilePath)) {
|
||||
__wasmFilePath = __wasmDebugFilePath
|
||||
} else if (!__nodeFs.existsSync(__wasmFilePath)) {
|
||||
const __wasiPackageEntry = require.resolve('@rolldown/binding-wasm32-wasi')
|
||||
const __packagedWasmFilePath = __nodePath.join(
|
||||
__nodePath.dirname(__wasiPackageEntry),
|
||||
'rolldown-binding.wasm32-wasi.wasm',
|
||||
)
|
||||
if (!__nodeFs.existsSync(__packagedWasmFilePath)) {
|
||||
throw new Error(
|
||||
'@rolldown/binding-wasm32-wasi is installed but is missing rolldown-binding.wasm32-wasi.wasm.',
|
||||
)
|
||||
}
|
||||
__wasmFilePath = __packagedWasmFilePath
|
||||
}
|
||||
|
||||
const __wasmFile = __nodeFs.readFileSync(__wasmFilePath)
|
||||
let __emnapiContext
|
||||
|
||||
const __wasiDisposeSymbol = Symbol.for('napi.rs.wasi.dispose')
|
||||
const __wasiWorkers = new Set()
|
||||
let __napiInstance
|
||||
let __emnapiContextDestroyed = false
|
||||
let __emnapiContextDestroyPromise
|
||||
let __emnapiWasmEnvCleanupPrepared = false
|
||||
let __wasiDisposed = false
|
||||
let __wasiDisposePromise
|
||||
let __completeWasiDisposal = function() {}
|
||||
|
||||
function __isThenable(value) {
|
||||
return (
|
||||
value !== null &&
|
||||
(typeof value === 'object' || typeof value === 'function') &&
|
||||
typeof value.then === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
function __createCleanupError(errors, message) {
|
||||
if (errors.length === 1) {
|
||||
return errors[0]
|
||||
}
|
||||
const __AggregateError = globalThis.AggregateError
|
||||
if (typeof __AggregateError === 'function') {
|
||||
return new __AggregateError(errors, message)
|
||||
}
|
||||
const error = new Error(message)
|
||||
error.errors = errors
|
||||
return error
|
||||
}
|
||||
|
||||
function __attachCleanupErrors(error, cleanupErrors) {
|
||||
if (cleanupErrors.length === 0) {
|
||||
return error
|
||||
}
|
||||
const cleanupError = __createCleanupError(
|
||||
cleanupErrors,
|
||||
'WASI binding cleanup failed',
|
||||
)
|
||||
try {
|
||||
if (
|
||||
error &&
|
||||
(typeof error === 'object' || typeof error === 'function')
|
||||
) {
|
||||
if (error.cause === undefined) {
|
||||
error.cause = cleanupError
|
||||
if (error.cause === cleanupError) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
if (Array.isArray(error.cleanupErrors)) {
|
||||
error.cleanupErrors.push(cleanupError)
|
||||
return error
|
||||
} else {
|
||||
const attachedCleanupErrors = [cleanupError]
|
||||
error.cleanupErrors = attachedCleanupErrors
|
||||
if (error.cleanupErrors === attachedCleanupErrors) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
const aggregate = __createCleanupError(
|
||||
[error, cleanupError],
|
||||
'WASI binding initialization and cleanup failed',
|
||||
)
|
||||
try {
|
||||
aggregate.cause = error
|
||||
} catch {}
|
||||
return aggregate
|
||||
}
|
||||
|
||||
function __prepareWasmEnvCleanup() {
|
||||
if (__emnapiWasmEnvCleanupPrepared) {
|
||||
return
|
||||
}
|
||||
const prepare = __napiInstance?.exports?.napi_prepare_wasm_env_cleanup
|
||||
if (typeof prepare === 'function') {
|
||||
prepare()
|
||||
}
|
||||
__emnapiWasmEnvCleanupPrepared = true
|
||||
}
|
||||
|
||||
function __destroyEmnapiContext() {
|
||||
if (__emnapiContextDestroyed || __emnapiContext === undefined) {
|
||||
__emnapiContextDestroyed = true
|
||||
return
|
||||
}
|
||||
if (__emnapiContextDestroyPromise) {
|
||||
return __emnapiContextDestroyPromise
|
||||
}
|
||||
|
||||
__prepareWasmEnvCleanup()
|
||||
const result = __emnapiContext.destroy()
|
||||
if (!__isThenable(result)) {
|
||||
__emnapiContextDestroyed = true
|
||||
return
|
||||
}
|
||||
|
||||
const destroyPromise = Promise.resolve(result).then(
|
||||
(value) => {
|
||||
__emnapiContextDestroyed = true
|
||||
return value
|
||||
},
|
||||
(error) => {
|
||||
__emnapiContextDestroyPromise = undefined
|
||||
throw error
|
||||
},
|
||||
)
|
||||
__emnapiContextDestroyPromise = destroyPromise
|
||||
return destroyPromise
|
||||
}
|
||||
|
||||
function __terminateWasiWorkers() {
|
||||
const cleanupErrors = []
|
||||
const pending = []
|
||||
|
||||
for (const worker of __wasiWorkers) {
|
||||
let result
|
||||
try {
|
||||
result = worker.terminate()
|
||||
} catch (error) {
|
||||
cleanupErrors.push(error)
|
||||
continue
|
||||
}
|
||||
if (__isThenable(result)) {
|
||||
pending.push(
|
||||
Promise.resolve(result).then(
|
||||
() => {
|
||||
__wasiWorkers.delete(worker)
|
||||
},
|
||||
(error) => {
|
||||
cleanupErrors.push(error)
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
__wasiWorkers.delete(worker)
|
||||
}
|
||||
}
|
||||
|
||||
const finish = () => {
|
||||
if (cleanupErrors.length > 0) {
|
||||
throw __createCleanupError(
|
||||
cleanupErrors,
|
||||
'Failed to terminate WASI workers',
|
||||
)
|
||||
}
|
||||
}
|
||||
return pending.length > 0 ? Promise.all(pending).then(finish) : finish()
|
||||
}
|
||||
|
||||
function __finishWasiDisposal() {
|
||||
const workerResult = __terminateWasiWorkers()
|
||||
if (__isThenable(workerResult)) {
|
||||
return Promise.resolve(workerResult).then(__completeWasiDisposal)
|
||||
}
|
||||
return __completeWasiDisposal()
|
||||
}
|
||||
|
||||
function __startWasiDisposal() {
|
||||
const destroyResult = __destroyEmnapiContext()
|
||||
if (__isThenable(destroyResult)) {
|
||||
return Promise.resolve(destroyResult).then(__finishWasiDisposal)
|
||||
}
|
||||
return __finishWasiDisposal()
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes this generated WASI binding.
|
||||
*
|
||||
* Access this function with:
|
||||
* binding[Symbol.for('napi.rs.wasi.dispose')]()
|
||||
*/
|
||||
function __disposeWasiBinding() {
|
||||
if (__wasiDisposePromise) {
|
||||
return __wasiDisposePromise
|
||||
}
|
||||
if (__wasiDisposed) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
let resolveDispose
|
||||
let rejectDispose
|
||||
const disposePromise = new Promise((resolve, reject) => {
|
||||
resolveDispose = resolve
|
||||
rejectDispose = reject
|
||||
})
|
||||
__wasiDisposePromise = disposePromise
|
||||
|
||||
let result
|
||||
try {
|
||||
result = __startWasiDisposal()
|
||||
} catch (error) {
|
||||
__wasiDisposePromise = undefined
|
||||
rejectDispose(error)
|
||||
return disposePromise
|
||||
}
|
||||
|
||||
Promise.resolve(result).then(
|
||||
(value) => {
|
||||
__wasiDisposed = true
|
||||
resolveDispose(value)
|
||||
},
|
||||
(error) => {
|
||||
__wasiDisposePromise = undefined
|
||||
rejectDispose(error)
|
||||
},
|
||||
)
|
||||
return disposePromise
|
||||
}
|
||||
|
||||
function __publishWasiDispose(exports) {
|
||||
Object.defineProperty(exports, __wasiDisposeSymbol, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: __disposeWasiBinding,
|
||||
writable: false,
|
||||
})
|
||||
}
|
||||
|
||||
function __finishWasiInitializationRollback(cleanupErrors) {
|
||||
let workerResult
|
||||
try {
|
||||
workerResult = __terminateWasiWorkers()
|
||||
} catch (cleanupError) {
|
||||
cleanupErrors.push(cleanupError)
|
||||
return cleanupErrors
|
||||
}
|
||||
if (__isThenable(workerResult)) {
|
||||
return Promise.resolve(workerResult)
|
||||
.catch((cleanupError) => {
|
||||
cleanupErrors.push(cleanupError)
|
||||
})
|
||||
.then(() => cleanupErrors)
|
||||
}
|
||||
return cleanupErrors
|
||||
}
|
||||
|
||||
function __rollbackWasiInitialization() {
|
||||
const cleanupErrors = []
|
||||
let destroyResult
|
||||
try {
|
||||
destroyResult = __destroyEmnapiContext()
|
||||
} catch (cleanupError) {
|
||||
cleanupErrors.push(cleanupError)
|
||||
return __finishWasiInitializationRollback(cleanupErrors)
|
||||
}
|
||||
if (__isThenable(destroyResult)) {
|
||||
return Promise.resolve(destroyResult)
|
||||
.catch((cleanupError) => {
|
||||
cleanupErrors.push(cleanupError)
|
||||
})
|
||||
.then(() => __finishWasiInitializationRollback(cleanupErrors))
|
||||
}
|
||||
return __finishWasiInitializationRollback(cleanupErrors)
|
||||
}
|
||||
|
||||
const __wasiRollbackRegistrySymbol = Symbol.for('napi.rs.wasi.rollback.registry.v1')
|
||||
const __wasiRollbackRegistryKey =
|
||||
typeof __filename === 'string' ? __filename : __wasmFilePath
|
||||
|
||||
function __getWasiRollbackRegistry() {
|
||||
const existing = process[__wasiRollbackRegistrySymbol]
|
||||
if (existing !== undefined) {
|
||||
if (!(existing instanceof Map)) {
|
||||
throw new TypeError(
|
||||
'The process-wide NAPI-RS WASI rollback registry is invalid',
|
||||
)
|
||||
}
|
||||
return existing
|
||||
}
|
||||
const registry = new Map()
|
||||
Object.defineProperty(process, __wasiRollbackRegistrySymbol, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: registry,
|
||||
writable: false,
|
||||
})
|
||||
return registry
|
||||
}
|
||||
|
||||
const __wasiRollbackRegistry = __getWasiRollbackRegistry()
|
||||
|
||||
function __completeWasiInitializationRollback(record, cleanupErrors) {
|
||||
try {
|
||||
if (cleanupErrors.length === 0) {
|
||||
if (
|
||||
__wasiRollbackRegistry.get(__wasiRollbackRegistryKey) === record
|
||||
) {
|
||||
__wasiRollbackRegistry.delete(__wasiRollbackRegistryKey)
|
||||
}
|
||||
return
|
||||
}
|
||||
record.error = __attachCleanupErrors(record.error, cleanupErrors)
|
||||
} catch (cleanupError) {
|
||||
try {
|
||||
record.error = __createCleanupError(
|
||||
[record.error, cleanupError],
|
||||
'WASI binding initialization and cleanup failed',
|
||||
)
|
||||
} catch {}
|
||||
} finally {
|
||||
record.active = false
|
||||
record.promise = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function __runWasiInitializationRollback(record) {
|
||||
if (record.active) {
|
||||
return
|
||||
}
|
||||
record.active = true
|
||||
|
||||
let rollbackResult
|
||||
try {
|
||||
rollbackResult = record.rollback()
|
||||
} catch (cleanupError) {
|
||||
__completeWasiInitializationRollback(record, [cleanupError])
|
||||
return
|
||||
}
|
||||
|
||||
if (!__isThenable(rollbackResult)) {
|
||||
__completeWasiInitializationRollback(record, rollbackResult)
|
||||
return
|
||||
}
|
||||
|
||||
record.promise = Promise.resolve(rollbackResult).then(
|
||||
(cleanupErrors) => {
|
||||
__completeWasiInitializationRollback(record, cleanupErrors)
|
||||
},
|
||||
(cleanupError) => {
|
||||
__completeWasiInitializationRollback(record, [cleanupError])
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
const __pendingWasiRollback = __wasiRollbackRegistry.get(
|
||||
__wasiRollbackRegistryKey,
|
||||
)
|
||||
if (__pendingWasiRollback !== undefined) {
|
||||
__runWasiInitializationRollback(__pendingWasiRollback)
|
||||
throw __pendingWasiRollback.error
|
||||
}
|
||||
|
||||
let __wasiModule
|
||||
let __napiModule
|
||||
let __wasiExitListenerRegistered = false
|
||||
|
||||
function __removeWasiExitListener() {
|
||||
if (
|
||||
__wasiExitListenerRegistered &&
|
||||
typeof process.removeListener === 'function'
|
||||
) {
|
||||
process.removeListener('exit', __disposeWasiBindingAtExit)
|
||||
}
|
||||
__wasiExitListenerRegistered = false
|
||||
}
|
||||
|
||||
function __disposeWasiBindingAtExit() {
|
||||
__wasiExitListenerRegistered = false
|
||||
try {
|
||||
const result = __disposeWasiBinding()
|
||||
if (__isThenable(result)) {
|
||||
void Promise.resolve(result).catch(() => {})
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function __registerWasiExitListener() {
|
||||
if (
|
||||
!__wasiExitListenerRegistered &&
|
||||
typeof process.once === 'function'
|
||||
) {
|
||||
process.once('exit', __disposeWasiBindingAtExit)
|
||||
__wasiExitListenerRegistered = true
|
||||
}
|
||||
}
|
||||
|
||||
__completeWasiDisposal = __removeWasiExitListener
|
||||
|
||||
function __captureEmnapiAutoDestroyListener() {
|
||||
if (
|
||||
typeof process.prependListener !== 'function' ||
|
||||
typeof process.removeListener !== 'function'
|
||||
) {
|
||||
return
|
||||
}
|
||||
let __autoDestroyListener
|
||||
const __captureListener = (__event, __listener) => {
|
||||
if (__event === 'beforeExit' && __autoDestroyListener === undefined) {
|
||||
__autoDestroyListener = __listener
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Run before existing newListener hooks so a hook that registers its own
|
||||
// beforeExit listener cannot be mistaken for emnapi's registration.
|
||||
process.prependListener('newListener', __captureListener)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
return () => {
|
||||
try {
|
||||
process.removeListener('newListener', __captureListener)
|
||||
} catch {}
|
||||
if (__autoDestroyListener !== undefined) {
|
||||
try {
|
||||
process.removeListener('beforeExit', __autoDestroyListener)
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
|
||||
try {
|
||||
__emnapiContext = __emnapiCreateContext({ autoDestroy: false })
|
||||
// emnapi 2.x still registers an unconditional once-listener for
|
||||
// beforeExit that auto-destroys the context, and suppressDestroy() only
|
||||
// neutralizes its callback without removing it. This loader owns cleanup
|
||||
// through its 'exit' listener, so emnapi's listener is captured and
|
||||
// removed; suppressDestroy() remains the safety net when removal fails.
|
||||
__emnapiContext.suppressDestroy()
|
||||
} finally {
|
||||
// Remove only the exact emnapi callback captured above.
|
||||
__finishAutoDestroyCapture?.()
|
||||
}
|
||||
|
||||
;({
|
||||
instance: __napiInstance,
|
||||
module: __wasiModule,
|
||||
napiModule: __napiModule,
|
||||
} = __emnapiInstantiateNapiModuleSync(__wasmFile, {
|
||||
context: __emnapiContext,
|
||||
asyncWorkPoolSize: (function() {
|
||||
const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
|
||||
// NaN > 0 is false
|
||||
if (threadsSizeFromEnv > 0) {
|
||||
return threadsSizeFromEnv
|
||||
} else {
|
||||
return 4
|
||||
}
|
||||
})(),
|
||||
reuseWorker: true,
|
||||
plugins: [__emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
|
||||
wasi: __wasi,
|
||||
onCreateWorker() {
|
||||
const worker = __createWasiWorker(__nodePath.join(__dirname, 'wasi-worker.mjs'))
|
||||
__wasiWorkers.add(worker)
|
||||
worker.onmessage = ({ data }) => {
|
||||
__wasmCreateOnMessageForFsProxy(__nodeFs)(data)
|
||||
}
|
||||
|
||||
// The main thread of Node.js waits for all the active handles before exiting.
|
||||
// But Rust threads are never waited without `thread::join`.
|
||||
// So here we hack the code of Node.js to prevent the workers from being referenced (active).
|
||||
// According to https://github.com/nodejs/node/blob/19e0d472728c79d418b74bddff588bea70a403d0/lib/internal/worker.js#L415,
|
||||
// a worker is consist of two handles: kPublicPort and kHandle.
|
||||
{
|
||||
const kPublicPort = Object.getOwnPropertySymbols(worker).find(s =>
|
||||
s.toString().includes("kPublicPort")
|
||||
);
|
||||
if (kPublicPort) {
|
||||
worker[kPublicPort].ref = () => {};
|
||||
}
|
||||
|
||||
const kHandle = Object.getOwnPropertySymbols(worker).find(s =>
|
||||
s.toString().includes("kHandle")
|
||||
);
|
||||
if (kHandle) {
|
||||
worker[kHandle].ref = () => {};
|
||||
}
|
||||
|
||||
worker.unref();
|
||||
}
|
||||
return worker
|
||||
},
|
||||
overwriteImports(importObject) {
|
||||
importObject.env = {
|
||||
...importObject.env,
|
||||
...importObject.napi,
|
||||
...importObject.emnapi,
|
||||
memory: __sharedMemory,
|
||||
}
|
||||
return importObject
|
||||
},
|
||||
beforeInit({ instance }) {
|
||||
__napiInstance = instance
|
||||
for (const name of Object.keys(instance.exports)) {
|
||||
if (name.startsWith('__napi_register__')) {
|
||||
instance.exports[name]()
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
__publishWasiDispose(__napiModule.exports)
|
||||
__registerWasiExitListener()
|
||||
} catch (error) {
|
||||
const rollback = {
|
||||
active: false,
|
||||
error,
|
||||
promise: undefined,
|
||||
rollback: __rollbackWasiInitialization,
|
||||
}
|
||||
__wasiRollbackRegistry.set(__wasiRollbackRegistryKey, rollback)
|
||||
__runWasiInitializationRollback(rollback)
|
||||
throw rollback.error
|
||||
}
|
||||
module.exports = __napiModule.exports
|
||||
module.exports.LegalCommentsMode = __napiModule.exports.LegalCommentsMode
|
||||
module.exports.minify = __napiModule.exports.minify
|
||||
module.exports.minifySync = __napiModule.exports.minifySync
|
||||
module.exports.Severity = __napiModule.exports.Severity
|
||||
module.exports.ParseResult = __napiModule.exports.ParseResult
|
||||
module.exports.ExportExportNameKind = __napiModule.exports.ExportExportNameKind
|
||||
module.exports.ExportImportNameKind = __napiModule.exports.ExportImportNameKind
|
||||
module.exports.ExportLocalNameKind = __napiModule.exports.ExportLocalNameKind
|
||||
module.exports.ImportNameKind = __napiModule.exports.ImportNameKind
|
||||
module.exports.parse = __napiModule.exports.parse
|
||||
module.exports.parseSync = __napiModule.exports.parseSync
|
||||
module.exports.rawTransferSupported = __napiModule.exports.rawTransferSupported
|
||||
module.exports.ResolverFactory = __napiModule.exports.ResolverFactory
|
||||
module.exports.EnforceExtension = __napiModule.exports.EnforceExtension
|
||||
module.exports.ModuleType = __napiModule.exports.ModuleType
|
||||
module.exports.sync = __napiModule.exports.sync
|
||||
module.exports.HelperMode = __napiModule.exports.HelperMode
|
||||
module.exports.isolatedDeclaration = __napiModule.exports.isolatedDeclaration
|
||||
module.exports.isolatedDeclarationSync = __napiModule.exports.isolatedDeclarationSync
|
||||
module.exports.moduleRunnerTransform = __napiModule.exports.moduleRunnerTransform
|
||||
module.exports.moduleRunnerTransformSync = __napiModule.exports.moduleRunnerTransformSync
|
||||
module.exports.transform = __napiModule.exports.transform
|
||||
module.exports.transformSync = __napiModule.exports.transformSync
|
||||
module.exports.BindingBundleEndEventData = __napiModule.exports.BindingBundleEndEventData
|
||||
module.exports.BindingBundleErrorEventData = __napiModule.exports.BindingBundleErrorEventData
|
||||
module.exports.BindingBundler = __napiModule.exports.BindingBundler
|
||||
module.exports.BindingCallableBuiltinPlugin = __napiModule.exports.BindingCallableBuiltinPlugin
|
||||
module.exports.BindingChunkingContext = __napiModule.exports.BindingChunkingContext
|
||||
module.exports.BindingDecodedMap = __napiModule.exports.BindingDecodedMap
|
||||
module.exports.BindingDevEngine = __napiModule.exports.BindingDevEngine
|
||||
module.exports.BindingLoadPluginContext = __napiModule.exports.BindingLoadPluginContext
|
||||
module.exports.BindingMagicString = __napiModule.exports.BindingMagicString
|
||||
module.exports.BindingModuleInfo = __napiModule.exports.BindingModuleInfo
|
||||
module.exports.BindingNormalizedOptions = __napiModule.exports.BindingNormalizedOptions
|
||||
module.exports.BindingOutputAsset = __napiModule.exports.BindingOutputAsset
|
||||
module.exports.BindingOutputChunk = __napiModule.exports.BindingOutputChunk
|
||||
module.exports.BindingPluginContext = __napiModule.exports.BindingPluginContext
|
||||
module.exports.BindingRenderedChunk = __napiModule.exports.BindingRenderedChunk
|
||||
module.exports.BindingRenderedChunkMeta = __napiModule.exports.BindingRenderedChunkMeta
|
||||
module.exports.BindingRenderedModule = __napiModule.exports.BindingRenderedModule
|
||||
module.exports.BindingSourceMap = __napiModule.exports.BindingSourceMap
|
||||
module.exports.BindingTransformPluginContext = __napiModule.exports.BindingTransformPluginContext
|
||||
module.exports.BindingWatcher = __napiModule.exports.BindingWatcher
|
||||
module.exports.BindingWatcherBundler = __napiModule.exports.BindingWatcherBundler
|
||||
module.exports.BindingWatcherChangeData = __napiModule.exports.BindingWatcherChangeData
|
||||
module.exports.BindingWatcherEvent = __napiModule.exports.BindingWatcherEvent
|
||||
module.exports.ParallelJsPluginRegistry = __napiModule.exports.ParallelJsPluginRegistry
|
||||
module.exports.TraceSubscriberGuard = __napiModule.exports.TraceSubscriberGuard
|
||||
module.exports.TsconfigCache = __napiModule.exports.TsconfigCache
|
||||
module.exports.BindingAttachDebugInfo = __napiModule.exports.BindingAttachDebugInfo
|
||||
module.exports.BindingBuiltinPluginName = __napiModule.exports.BindingBuiltinPluginName
|
||||
module.exports.BindingChunkModuleOrderBy = __napiModule.exports.BindingChunkModuleOrderBy
|
||||
module.exports.BindingErrorStage = __napiModule.exports.BindingErrorStage
|
||||
module.exports.BindingLogLevel = __napiModule.exports.BindingLogLevel
|
||||
module.exports.BindingPluginOrder = __napiModule.exports.BindingPluginOrder
|
||||
module.exports.BindingPropertyReadSideEffects = __napiModule.exports.BindingPropertyReadSideEffects
|
||||
module.exports.BindingPropertyWriteSideEffects = __napiModule.exports.BindingPropertyWriteSideEffects
|
||||
module.exports.BindingRebuildStrategy = __napiModule.exports.BindingRebuildStrategy
|
||||
module.exports.collapseSourcemaps = __napiModule.exports.collapseSourcemaps
|
||||
module.exports.enhancedTransform = __napiModule.exports.enhancedTransform
|
||||
module.exports.enhancedTransformSync = __napiModule.exports.enhancedTransformSync
|
||||
module.exports.FilterTokenKind = __napiModule.exports.FilterTokenKind
|
||||
module.exports.initTraceSubscriber = __napiModule.exports.initTraceSubscriber
|
||||
module.exports.registerPlugins = __napiModule.exports.registerPlugins
|
||||
module.exports.resolveTsconfig = __napiModule.exports.resolveTsconfig
|
||||
module.exports.shutdownAsyncRuntime = __napiModule.exports.shutdownAsyncRuntime
|
||||
module.exports.startAsyncRuntime = __napiModule.exports.startAsyncRuntime
|
||||
+3112
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+59
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
instantiateNapiModuleSync,
|
||||
MessageHandler,
|
||||
WASI,
|
||||
createFsProxy,
|
||||
emnapiAsyncWorkPlugin,
|
||||
emnapiTSFNPlugin,
|
||||
} from '@napi-rs/wasm-runtime'
|
||||
import { memfsExported as __memfsExported } from '@napi-rs/wasm-runtime/fs'
|
||||
|
||||
const fs = createFsProxy(__memfsExported)
|
||||
|
||||
const errorOutputs = []
|
||||
|
||||
const handler = new MessageHandler({
|
||||
onLoad({ wasmModule, wasmMemory }) {
|
||||
const wasi = new WASI({
|
||||
fs,
|
||||
preopens: {
|
||||
'/': '/',
|
||||
},
|
||||
print: function () {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log.apply(console, arguments)
|
||||
},
|
||||
printErr: function() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error.apply(console, arguments)
|
||||
|
||||
errorOutputs.push([...arguments])
|
||||
},
|
||||
})
|
||||
return instantiateNapiModuleSync(wasmModule, {
|
||||
childThread: true,
|
||||
wasi,
|
||||
// The wasm links a "basic" emnapi archive (no C async-work /
|
||||
// threadsafe-function implementations), so every thread that
|
||||
// instantiates it must provide the JavaScript implementations
|
||||
// through the emnapi plugins.
|
||||
plugins: [emnapiAsyncWorkPlugin, emnapiTSFNPlugin],
|
||||
overwriteImports(importObject) {
|
||||
importObject.env = {
|
||||
...importObject.env,
|
||||
...importObject.napi,
|
||||
...importObject.emnapi,
|
||||
memory: wasmMemory,
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
onError(error) {
|
||||
postMessage({ type: 'error', error, errorOutputs })
|
||||
errorOutputs.length = 0
|
||||
}
|
||||
})
|
||||
|
||||
globalThis.onmessage = function (e) {
|
||||
handler.handle(e)
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import fs from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import { parse } from "node:path";
|
||||
import { WASI } from "node:wasi";
|
||||
import { parentPort, Worker } from "node:worker_threads";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const {
|
||||
instantiateNapiModuleSync,
|
||||
MessageHandler,
|
||||
getDefaultContext,
|
||||
emnapiAsyncWorkPlugin,
|
||||
emnapiTSFNPlugin,
|
||||
} = require("@napi-rs/wasm-runtime");
|
||||
|
||||
if (parentPort) {
|
||||
parentPort.on("message", (data) => {
|
||||
globalThis.onmessage({ data });
|
||||
});
|
||||
}
|
||||
|
||||
Object.assign(globalThis, {
|
||||
self: globalThis,
|
||||
require,
|
||||
Worker,
|
||||
importScripts: function (f) {
|
||||
;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
|
||||
},
|
||||
postMessage: function (msg) {
|
||||
if (parentPort) {
|
||||
parentPort.postMessage(msg);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const emnapiContext = getDefaultContext();
|
||||
|
||||
const __rootDir = parse(process.cwd()).root;
|
||||
|
||||
const handler = new MessageHandler({
|
||||
onLoad({ wasmModule, wasmMemory }) {
|
||||
const wasi = new WASI({
|
||||
version: 'preview1',
|
||||
env: process.env,
|
||||
preopens: {
|
||||
[__rootDir]: __rootDir,
|
||||
},
|
||||
});
|
||||
|
||||
return instantiateNapiModuleSync(wasmModule, {
|
||||
childThread: true,
|
||||
wasi,
|
||||
context: emnapiContext,
|
||||
// The wasm links a "basic" emnapi archive (no C async-work /
|
||||
// threadsafe-function implementations), so every thread that
|
||||
// instantiates it must provide the JavaScript implementations
|
||||
// through the emnapi plugins.
|
||||
plugins: [emnapiAsyncWorkPlugin, emnapiTSFNPlugin],
|
||||
overwriteImports(importObject) {
|
||||
importObject.env = {
|
||||
...importObject.env,
|
||||
...importObject.napi,
|
||||
...importObject.emnapi,
|
||||
memory: wasmMemory
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
globalThis.onmessage = function (e) {
|
||||
handler.handle(e);
|
||||
};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# `@rolldown/binding-win32-x64-msvc`
|
||||
|
||||
This is the **x86_64-pc-windows-msvc** binary for `@rolldown/binding`
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@rolldown/binding-win32-x64-msvc",
|
||||
"version": "1.2.1",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"main": "rolldown-binding.win32-x64-msvc.node",
|
||||
"files": [
|
||||
"rolldown-binding.win32-x64-msvc.node"
|
||||
],
|
||||
"description": "Fast JavaScript/TypeScript bundler in Rust with Rollup-compatible API.",
|
||||
"keywords": [
|
||||
"bundler",
|
||||
"esbuild",
|
||||
"parcel",
|
||||
"rolldown",
|
||||
"rollup",
|
||||
"webpack"
|
||||
],
|
||||
"homepage": "https://rolldown.rs/",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rolldown/rolldown.git",
|
||||
"directory": "packages/rolldown"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "public"
|
||||
},
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026-present, rolldown/plugins repository contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
# @rolldown/pluginutils [](https://npmx.dev/package/@rolldown/pluginutils)
|
||||
|
||||
Plugin utilities for [Rolldown](https://rolldown.rs).
|
||||
|
||||
Includes regex helpers for plugin hook filters, composable filter expressions, and a helper for filtering out Vite-serve-only plugins.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pnpm add -D @rolldown/pluginutils
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { exactRegex, prefixRegex, makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils'
|
||||
```
|
||||
|
||||
All filter helpers are also exposed via the `/filter` subpath:
|
||||
|
||||
```ts
|
||||
import { and, or, id, include } from '@rolldown/pluginutils/filter'
|
||||
```
|
||||
|
||||
## Regex helpers
|
||||
|
||||
### `exactRegex`
|
||||
|
||||
- **Type:** `(str: string, flags?: string) => RegExp`
|
||||
|
||||
Constructs a `RegExp` that matches the exact string specified. Useful as a plugin hook filter.
|
||||
|
||||
```ts
|
||||
import { exactRegex } from '@rolldown/pluginutils'
|
||||
|
||||
const plugin = {
|
||||
name: 'plugin',
|
||||
resolveId: {
|
||||
filter: { id: exactRegex('foo') },
|
||||
handler(id) {}, // only called for `foo`
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `prefixRegex`
|
||||
|
||||
- **Type:** `(str: string, flags?: string) => RegExp`
|
||||
|
||||
Constructs a `RegExp` that matches values starting with the specified prefix.
|
||||
|
||||
```ts
|
||||
import { prefixRegex } from '@rolldown/pluginutils'
|
||||
|
||||
const plugin = {
|
||||
name: 'plugin',
|
||||
resolveId: {
|
||||
filter: { id: prefixRegex('foo') },
|
||||
handler(id) {}, // called for IDs starting with `foo`
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `makeIdFiltersToMatchWithQuery`
|
||||
|
||||
- **Type:** `(input: string | RegExp | (string | RegExp)[]) => string | RegExp | (string | RegExp)[]`
|
||||
|
||||
Converts an id filter so that it also matches ids that include a query string.
|
||||
|
||||
```ts
|
||||
import { makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils'
|
||||
|
||||
const plugin = {
|
||||
name: 'plugin',
|
||||
transform: {
|
||||
filter: { id: makeIdFiltersToMatchWithQuery(['**/*.js', /\.ts$/]) },
|
||||
// Matches:
|
||||
// foo.js, foo.js?foo, foo.txt?foo.js,
|
||||
// foo.ts, foo.ts?foo, foo.txt?foo.ts
|
||||
handler(code, id) {},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Composable filters
|
||||
|
||||
[Composable filter expressions](https://rolldown.rs/apis/plugin-api/hook-filters#composable-filters) for use cases where a simple `id`/`include`/`exclude` is not enough. For example, when a plugin needs to combine `id`, `moduleType`, `code`, and `query` conditions.
|
||||
|
||||
```ts
|
||||
import { and, code, id, include, interpreter, moduleType, or } from '@rolldown/pluginutils'
|
||||
|
||||
const expr = include(and(or(id(/\.tsx?$/), id(/\.jsx?$/)), moduleType('tsx'), code(/import React/)))
|
||||
|
||||
interpreter(expr, sourceCode, sourceId, 'tsx') // boolean
|
||||
```
|
||||
|
||||
### Builders
|
||||
|
||||
| Builder | Description |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `and(...exprs)` | All operands must match. |
|
||||
| `or(...exprs)` | At least one operand must match. |
|
||||
| `not(expr)` | Negates the operand. |
|
||||
| `id(pattern, params?)` | Match the module id. `pattern` is `string` or `RegExp`. `params.cleanUrl` strips the query/hash before matching. |
|
||||
| `importerId(pattern, params?)` | Match the importer's id. Same shape as `id`. |
|
||||
| `moduleType(type)` | Match Rolldown's module type (`'js'`, `'jsx'`, `'ts'`, `'tsx'`, `'json'`, `'text'`, `'base64'`, `'dataurl'`, `'binary'`, `'empty'`, or a custom string). |
|
||||
| `code(pattern)` | Match the module source. `string` matches with `includes`; `RegExp` with `test`. |
|
||||
| `query(key, pattern)` | Match a single query parameter. `pattern` is `boolean` (key presence/truthiness), `string` (exact value), or `RegExp` (value pattern). |
|
||||
| `queries(obj)` | Shorthand for `and(...)` over multiple `query` entries. |
|
||||
| `include(expr)` | Top-level wrapper marking `expr` as an inclusion rule. |
|
||||
| `exclude(expr)` | Top-level wrapper marking `expr` as an exclusion rule. |
|
||||
|
||||
### `interpreter`
|
||||
|
||||
- **Type:** `(exprs, code?, id?, moduleType?, importerId?) => boolean`
|
||||
|
||||
Evaluates one or more top-level expressions against the given inputs. Returns `true` when at least one `include` matches and no `exclude` matches; when no `include` is present, defaults to `true` unless an `exclude` matches.
|
||||
|
||||
The argument required by each expression must be provided. For example, evaluating an `id(...)` expression without passing `id` will throw.
|
||||
|
||||
## `filterVitePlugins`
|
||||
|
||||
- **Type:** `<T>(plugins: T | T[] | null | undefined | false) => T[]`
|
||||
|
||||
Removes Vite plugins that target the dev server (`apply: 'serve'`) from a (possibly nested) plugin array. Plugins whose `apply` is a function are invoked with a `command: 'build'` context to decide. Useful when reusing a Vite plugin array inside a Rolldown config.
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'rolldown'
|
||||
import { filterVitePlugins } from '@rolldown/pluginutils'
|
||||
import viteReact from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: filterVitePlugins([
|
||||
viteReact(),
|
||||
{
|
||||
name: 'dev-only',
|
||||
apply: 'serve', // filtered out
|
||||
// ...
|
||||
},
|
||||
]),
|
||||
})
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
//#region src/utils.ts
|
||||
const postfixRE = /[?#].*$/;
|
||||
function cleanUrl(url) {
|
||||
return url.replace(postfixRE, "");
|
||||
}
|
||||
function extractQueryWithoutFragment(url) {
|
||||
const questionMarkIndex = url.indexOf("?");
|
||||
if (questionMarkIndex === -1) return "";
|
||||
const fragmentIndex = url.indexOf("#", questionMarkIndex);
|
||||
if (fragmentIndex === -1) return url.substring(questionMarkIndex);
|
||||
else return url.substring(questionMarkIndex, fragmentIndex);
|
||||
}
|
||||
//#endregion
|
||||
//#region src/filter/composable-filters.ts
|
||||
var And = class {
|
||||
kind;
|
||||
args;
|
||||
constructor(...args) {
|
||||
if (args.length === 0) throw new Error("`And` expects at least one operand");
|
||||
this.args = args;
|
||||
this.kind = "and";
|
||||
}
|
||||
};
|
||||
var Or = class {
|
||||
kind;
|
||||
args;
|
||||
constructor(...args) {
|
||||
if (args.length === 0) throw new Error("`Or` expects at least one operand");
|
||||
this.args = args;
|
||||
this.kind = "or";
|
||||
}
|
||||
};
|
||||
var Not = class {
|
||||
kind;
|
||||
expr;
|
||||
constructor(expr) {
|
||||
this.expr = expr;
|
||||
this.kind = "not";
|
||||
}
|
||||
};
|
||||
var Id = class {
|
||||
kind;
|
||||
pattern;
|
||||
params;
|
||||
constructor(pattern, params) {
|
||||
this.pattern = pattern;
|
||||
this.kind = "id";
|
||||
this.params = params ?? { cleanUrl: false };
|
||||
}
|
||||
};
|
||||
var ImporterId = class {
|
||||
kind;
|
||||
pattern;
|
||||
params;
|
||||
constructor(pattern, params) {
|
||||
this.pattern = pattern;
|
||||
this.kind = "importerId";
|
||||
this.params = params ?? { cleanUrl: false };
|
||||
}
|
||||
};
|
||||
var ModuleType = class {
|
||||
kind;
|
||||
pattern;
|
||||
constructor(pattern) {
|
||||
this.pattern = pattern;
|
||||
this.kind = "moduleType";
|
||||
}
|
||||
};
|
||||
var Code = class {
|
||||
kind;
|
||||
pattern;
|
||||
constructor(expr) {
|
||||
this.pattern = expr;
|
||||
this.kind = "code";
|
||||
}
|
||||
};
|
||||
var Query = class {
|
||||
kind;
|
||||
key;
|
||||
pattern;
|
||||
constructor(key, pattern) {
|
||||
this.pattern = pattern;
|
||||
this.key = key;
|
||||
this.kind = "query";
|
||||
}
|
||||
};
|
||||
var Include = class {
|
||||
kind;
|
||||
expr;
|
||||
constructor(expr) {
|
||||
this.expr = expr;
|
||||
this.kind = "include";
|
||||
}
|
||||
};
|
||||
var Exclude = class {
|
||||
kind;
|
||||
expr;
|
||||
constructor(expr) {
|
||||
this.expr = expr;
|
||||
this.kind = "exclude";
|
||||
}
|
||||
};
|
||||
function and(...args) {
|
||||
return new And(...args);
|
||||
}
|
||||
function or(...args) {
|
||||
return new Or(...args);
|
||||
}
|
||||
function not(expr) {
|
||||
return new Not(expr);
|
||||
}
|
||||
function id(pattern, params) {
|
||||
return new Id(pattern, params);
|
||||
}
|
||||
function importerId(pattern, params) {
|
||||
return new ImporterId(pattern, params);
|
||||
}
|
||||
function moduleType(pattern) {
|
||||
return new ModuleType(pattern);
|
||||
}
|
||||
function code(pattern) {
|
||||
return new Code(pattern);
|
||||
}
|
||||
function query(key, pattern) {
|
||||
return new Query(key, pattern);
|
||||
}
|
||||
function include(expr) {
|
||||
return new Include(expr);
|
||||
}
|
||||
function exclude(expr) {
|
||||
return new Exclude(expr);
|
||||
}
|
||||
/**
|
||||
* convert a queryObject to FilterExpression like
|
||||
* ```js
|
||||
* and(query(k1, v1), query(k2, v2))
|
||||
* ```
|
||||
* @param queryFilterObject The query filter object needs to be matched.
|
||||
* @returns a `And` FilterExpression
|
||||
*/
|
||||
function queries(queryFilter) {
|
||||
return and(...Object.entries(queryFilter).map(([key, value]) => {
|
||||
return new Query(key, value);
|
||||
}));
|
||||
}
|
||||
function interpreter(exprs, code, id, moduleType, importerId) {
|
||||
let arr = [];
|
||||
if (Array.isArray(exprs)) arr = exprs;
|
||||
else arr = [exprs];
|
||||
return interpreterImpl(arr, code, id, moduleType, importerId);
|
||||
}
|
||||
function interpreterImpl(expr, code, id, moduleType, importerId, ctx = {}) {
|
||||
let hasInclude = false;
|
||||
for (const e of expr) switch (e.kind) {
|
||||
case "include":
|
||||
hasInclude = true;
|
||||
if (exprInterpreter(e.expr, code, id, moduleType, importerId, ctx)) return true;
|
||||
break;
|
||||
case "exclude":
|
||||
if (exprInterpreter(e.expr, code, id, moduleType, importerId, ctx)) return false;
|
||||
break;
|
||||
}
|
||||
return !hasInclude;
|
||||
}
|
||||
function exprInterpreter(expr, code, id, moduleType, importerId, ctx = {}) {
|
||||
switch (expr.kind) {
|
||||
case "and": return expr.args.every((e) => exprInterpreter(e, code, id, moduleType, importerId, ctx));
|
||||
case "or": return expr.args.some((e) => exprInterpreter(e, code, id, moduleType, importerId, ctx));
|
||||
case "not": return !exprInterpreter(expr.expr, code, id, moduleType, importerId, ctx);
|
||||
case "id": {
|
||||
if (id === void 0) throw new Error("`id` is required for `id` expression");
|
||||
let idToMatch = id;
|
||||
if (expr.params.cleanUrl) idToMatch = cleanUrl(idToMatch);
|
||||
return typeof expr.pattern === "string" ? idToMatch === expr.pattern : expr.pattern.test(idToMatch);
|
||||
}
|
||||
case "importerId": {
|
||||
if (importerId === void 0) return false;
|
||||
let importerIdToMatch = importerId;
|
||||
if (expr.params.cleanUrl) importerIdToMatch = cleanUrl(importerIdToMatch);
|
||||
return typeof expr.pattern === "string" ? importerIdToMatch === expr.pattern : expr.pattern.test(importerIdToMatch);
|
||||
}
|
||||
case "moduleType":
|
||||
if (moduleType === void 0) throw new Error("`moduleType` is required for `moduleType` expression");
|
||||
return moduleType === expr.pattern;
|
||||
case "code":
|
||||
if (code === void 0) throw new Error("`code` is required for `code` expression");
|
||||
return typeof expr.pattern === "string" ? code.includes(expr.pattern) : expr.pattern.test(code);
|
||||
case "query": {
|
||||
if (id === void 0) throw new Error("`id` is required for `Query` expression");
|
||||
if (!ctx.urlSearchParamsCache) {
|
||||
let queryString = extractQueryWithoutFragment(id);
|
||||
ctx.urlSearchParamsCache = new URLSearchParams(queryString);
|
||||
}
|
||||
let urlParams = ctx.urlSearchParamsCache;
|
||||
if (typeof expr.pattern === "boolean") if (expr.pattern) return urlParams.has(expr.key);
|
||||
else return !urlParams.has(expr.key);
|
||||
else if (typeof expr.pattern === "string") return urlParams.get(expr.key) === expr.pattern;
|
||||
else return expr.pattern.test(urlParams.get(expr.key) ?? "");
|
||||
}
|
||||
default: throw new Error(`Expression ${JSON.stringify(expr)} is not expected.`);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
//#region src/filter/filter-vite-plugins.ts
|
||||
/**
|
||||
* Filters out Vite plugins that have `apply: 'serve'` set.
|
||||
*
|
||||
* Since Rolldown operates in build mode, plugins marked with `apply: 'serve'`
|
||||
* are intended only for Vite's dev server and should be excluded from the build process.
|
||||
*
|
||||
* @param plugins - Array of plugins (can include nested arrays)
|
||||
* @returns Filtered array with serve-only plugins removed
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { defineConfig } from 'rolldown';
|
||||
* import { filterVitePlugins } from '@rolldown/pluginutils';
|
||||
* import viteReact from '@vitejs/plugin-react';
|
||||
*
|
||||
* export default defineConfig({
|
||||
* plugins: filterVitePlugins([
|
||||
* viteReact(),
|
||||
* {
|
||||
* name: 'dev-only',
|
||||
* apply: 'serve', // This will be filtered out
|
||||
* // ...
|
||||
* }
|
||||
* ])
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
function filterVitePlugins(plugins) {
|
||||
if (!plugins) return [];
|
||||
const pluginArray = Array.isArray(plugins) ? plugins : [plugins];
|
||||
const result = [];
|
||||
for (const plugin of pluginArray) {
|
||||
if (!plugin) continue;
|
||||
if (Array.isArray(plugin)) {
|
||||
result.push(...filterVitePlugins(plugin));
|
||||
continue;
|
||||
}
|
||||
const pluginWithApply = plugin;
|
||||
if ("apply" in pluginWithApply) {
|
||||
const applyValue = pluginWithApply.apply;
|
||||
if (typeof applyValue === "function") try {
|
||||
if (applyValue({}, {
|
||||
command: "build",
|
||||
mode: "production"
|
||||
})) result.push(plugin);
|
||||
} catch {
|
||||
result.push(plugin);
|
||||
}
|
||||
else if (applyValue === "serve") continue;
|
||||
else result.push(plugin);
|
||||
} else result.push(plugin);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/filter/simple-filters.ts
|
||||
/**
|
||||
* Constructs a RegExp that matches the exact string specified.
|
||||
*
|
||||
* This is useful for plugin hook filters.
|
||||
*
|
||||
* @param str the string to match.
|
||||
* @param flags flags for the RegExp.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { exactRegex } from '@rolldown/pluginutils';
|
||||
* const plugin = {
|
||||
* name: 'plugin',
|
||||
* resolveId: {
|
||||
* filter: { id: exactRegex('foo') },
|
||||
* handler(id) {} // will only be called for `foo`
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
function exactRegex(str, flags) {
|
||||
return new RegExp(`^${escapeRegex(str)}$`, flags);
|
||||
}
|
||||
/**
|
||||
* Constructs a RegExp that matches a value that has the specified prefix.
|
||||
*
|
||||
* This is useful for plugin hook filters.
|
||||
*
|
||||
* @param str the string to match.
|
||||
* @param flags flags for the RegExp.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { prefixRegex } from '@rolldown/pluginutils';
|
||||
* const plugin = {
|
||||
* name: 'plugin',
|
||||
* resolveId: {
|
||||
* filter: { id: prefixRegex('foo') },
|
||||
* handler(id) {} // will only be called for IDs starting with `foo`
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
function prefixRegex(str, flags) {
|
||||
return new RegExp(`^${escapeRegex(str)}`, flags);
|
||||
}
|
||||
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
|
||||
function escapeRegex(str) {
|
||||
return str.replace(escapeRegexRE, "\\$&");
|
||||
}
|
||||
function makeIdFiltersToMatchWithQuery(input) {
|
||||
if (!Array.isArray(input)) return makeIdFilterToMatchWithQuery(input);
|
||||
return input.map((i) => makeIdFilterToMatchWithQuery(i));
|
||||
}
|
||||
function makeIdFilterToMatchWithQuery(input) {
|
||||
if (typeof input === "string") return `${input}{?*,}`;
|
||||
return makeRegexIdFilterToMatchWithQuery(input);
|
||||
}
|
||||
function makeRegexIdFilterToMatchWithQuery(input) {
|
||||
return new RegExp(input.source.replace(/(?<!\\)\$/g, "(?:\\?.*)?$"), input.flags);
|
||||
}
|
||||
//#endregion
|
||||
export { queries as _, and as a, exprInterpreter as c, include as d, interpreter as f, or as g, not as h, filterVitePlugins as i, id as l, moduleType as m, makeIdFiltersToMatchWithQuery as n, code as o, interpreterImpl as p, prefixRegex as r, exclude as s, exactRegex as t, importerId as u, query as v };
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
//#region src/filter/composable-filters.d.ts
|
||||
type StringOrRegExp = string | RegExp;
|
||||
type PluginModuleType = 'js' | 'jsx' | 'ts' | 'tsx' | 'json' | 'text' | 'base64' | 'dataurl' | 'binary' | 'empty' | (string & {});
|
||||
type FilterExpressionKind = FilterExpression['kind'];
|
||||
type FilterExpression = And | Or | Not | Id | ImporterId | ModuleType | Code | Query;
|
||||
type TopLevelFilterExpression = Include | Exclude;
|
||||
declare class And {
|
||||
kind: 'and';
|
||||
args: FilterExpression[];
|
||||
constructor(...args: FilterExpression[]);
|
||||
}
|
||||
declare class Or {
|
||||
kind: 'or';
|
||||
args: FilterExpression[];
|
||||
constructor(...args: FilterExpression[]);
|
||||
}
|
||||
declare class Not {
|
||||
kind: 'not';
|
||||
expr: FilterExpression;
|
||||
constructor(expr: FilterExpression);
|
||||
}
|
||||
interface QueryFilterObject {
|
||||
[key: string]: StringOrRegExp | boolean;
|
||||
}
|
||||
interface IdParams {
|
||||
cleanUrl?: boolean;
|
||||
}
|
||||
declare class Id {
|
||||
kind: 'id';
|
||||
pattern: StringOrRegExp;
|
||||
params: IdParams;
|
||||
constructor(pattern: StringOrRegExp, params?: IdParams);
|
||||
}
|
||||
declare class ImporterId {
|
||||
kind: 'importerId';
|
||||
pattern: StringOrRegExp;
|
||||
params: IdParams;
|
||||
constructor(pattern: StringOrRegExp, params?: IdParams);
|
||||
}
|
||||
declare class ModuleType {
|
||||
kind: 'moduleType';
|
||||
pattern: PluginModuleType;
|
||||
constructor(pattern: PluginModuleType);
|
||||
}
|
||||
declare class Code {
|
||||
kind: 'code';
|
||||
pattern: StringOrRegExp;
|
||||
constructor(expr: StringOrRegExp);
|
||||
}
|
||||
declare class Query {
|
||||
kind: 'query';
|
||||
key: string;
|
||||
pattern: StringOrRegExp | boolean;
|
||||
constructor(key: string, pattern: StringOrRegExp | boolean);
|
||||
}
|
||||
declare class Include {
|
||||
kind: 'include';
|
||||
expr: FilterExpression;
|
||||
constructor(expr: FilterExpression);
|
||||
}
|
||||
declare class Exclude {
|
||||
kind: 'exclude';
|
||||
expr: FilterExpression;
|
||||
constructor(expr: FilterExpression);
|
||||
}
|
||||
declare function and(...args: FilterExpression[]): And;
|
||||
declare function or(...args: FilterExpression[]): Or;
|
||||
declare function not(expr: FilterExpression): Not;
|
||||
declare function id(pattern: StringOrRegExp, params?: IdParams): Id;
|
||||
declare function importerId(pattern: StringOrRegExp, params?: IdParams): ImporterId;
|
||||
declare function moduleType(pattern: PluginModuleType): ModuleType;
|
||||
declare function code(pattern: StringOrRegExp): Code;
|
||||
declare function query(key: string, pattern: StringOrRegExp | boolean): Query;
|
||||
declare function include(expr: FilterExpression): Include;
|
||||
declare function exclude(expr: FilterExpression): Exclude;
|
||||
/**
|
||||
* convert a queryObject to FilterExpression like
|
||||
* ```js
|
||||
* and(query(k1, v1), query(k2, v2))
|
||||
* ```
|
||||
* @param queryFilterObject The query filter object needs to be matched.
|
||||
* @returns a `And` FilterExpression
|
||||
*/
|
||||
declare function queries(queryFilter: QueryFilterObject): And;
|
||||
declare function interpreter(exprs: TopLevelFilterExpression | TopLevelFilterExpression[], code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string): boolean;
|
||||
interface InterpreterCtx {
|
||||
urlSearchParamsCache?: URLSearchParams;
|
||||
}
|
||||
declare function interpreterImpl(expr: TopLevelFilterExpression[], code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string, ctx?: InterpreterCtx): boolean;
|
||||
declare function exprInterpreter(expr: FilterExpression, code?: string, id?: string, moduleType?: PluginModuleType, importerId?: string, ctx?: InterpreterCtx): boolean;
|
||||
//#endregion
|
||||
//#region src/filter/filter-vite-plugins.d.ts
|
||||
/**
|
||||
* Filters out Vite plugins that have `apply: 'serve'` set.
|
||||
*
|
||||
* Since Rolldown operates in build mode, plugins marked with `apply: 'serve'`
|
||||
* are intended only for Vite's dev server and should be excluded from the build process.
|
||||
*
|
||||
* @param plugins - Array of plugins (can include nested arrays)
|
||||
* @returns Filtered array with serve-only plugins removed
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { defineConfig } from 'rolldown';
|
||||
* import { filterVitePlugins } from '@rolldown/pluginutils';
|
||||
* import viteReact from '@vitejs/plugin-react';
|
||||
*
|
||||
* export default defineConfig({
|
||||
* plugins: filterVitePlugins([
|
||||
* viteReact(),
|
||||
* {
|
||||
* name: 'dev-only',
|
||||
* apply: 'serve', // This will be filtered out
|
||||
* // ...
|
||||
* }
|
||||
* ])
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
declare function filterVitePlugins<T = any>(plugins: T | T[] | null | undefined | false): T[];
|
||||
//#endregion
|
||||
//#region src/filter/simple-filters.d.ts
|
||||
/**
|
||||
* Constructs a RegExp that matches the exact string specified.
|
||||
*
|
||||
* This is useful for plugin hook filters.
|
||||
*
|
||||
* @param str the string to match.
|
||||
* @param flags flags for the RegExp.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { exactRegex } from '@rolldown/pluginutils';
|
||||
* const plugin = {
|
||||
* name: 'plugin',
|
||||
* resolveId: {
|
||||
* filter: { id: exactRegex('foo') },
|
||||
* handler(id) {} // will only be called for `foo`
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
declare function exactRegex(str: string, flags?: string): RegExp;
|
||||
/**
|
||||
* Constructs a RegExp that matches a value that has the specified prefix.
|
||||
*
|
||||
* This is useful for plugin hook filters.
|
||||
*
|
||||
* @param str the string to match.
|
||||
* @param flags flags for the RegExp.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { prefixRegex } from '@rolldown/pluginutils';
|
||||
* const plugin = {
|
||||
* name: 'plugin',
|
||||
* resolveId: {
|
||||
* filter: { id: prefixRegex('foo') },
|
||||
* handler(id) {} // will only be called for IDs starting with `foo`
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
declare function prefixRegex(str: string, flags?: string): RegExp;
|
||||
type WidenString<T> = T extends string ? string : T;
|
||||
/**
|
||||
* Converts a id filter to match with an id with a query.
|
||||
*
|
||||
* @param input the id filters to convert.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { makeIdFiltersToMatchWithQuery } from '@rolldown/pluginutils';
|
||||
* const plugin = {
|
||||
* name: 'plugin',
|
||||
* transform: {
|
||||
* filter: { id: makeIdFiltersToMatchWithQuery(['**' + '/*.js', /\.ts$/]) },
|
||||
* // The handler will be called for IDs like:
|
||||
* // - foo.js
|
||||
* // - foo.js?foo
|
||||
* // - foo.txt?foo.js
|
||||
* // - foo.ts
|
||||
* // - foo.ts?foo
|
||||
* // - foo.txt?foo.ts
|
||||
* handler(code, id) {}
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
declare function makeIdFiltersToMatchWithQuery<T extends string | RegExp>(input: T): WidenString<T>;
|
||||
declare function makeIdFiltersToMatchWithQuery<T extends string | RegExp>(input: readonly T[]): WidenString<T>[];
|
||||
declare function makeIdFiltersToMatchWithQuery(input: string | RegExp | readonly (string | RegExp)[]): string | RegExp | (string | RegExp)[];
|
||||
//#endregion
|
||||
export { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { _ as queries, a as and, c as exprInterpreter, d as include, f as interpreter, g as or, h as not, i as filterVitePlugins, l as id, m as moduleType, n as makeIdFiltersToMatchWithQuery, o as code, p as interpreterImpl, r as prefixRegex, s as exclude, t as exactRegex, u as importerId, v as query } from "../filter-B_mD-HGz.mjs";
|
||||
export { and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query } from "./filter/index.mjs";
|
||||
export { FilterExpression, FilterExpressionKind, QueryFilterObject, TopLevelFilterExpression, and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { _ as queries, a as and, c as exprInterpreter, d as include, f as interpreter, g as or, h as not, i as filterVitePlugins, l as id, m as moduleType, n as makeIdFiltersToMatchWithQuery, o as code, p as interpreterImpl, r as prefixRegex, s as exclude, t as exactRegex, u as importerId, v as query } from "./filter-B_mD-HGz.mjs";
|
||||
export { and, code, exactRegex, exclude, exprInterpreter, filterVitePlugins, id, importerId, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query };
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@rolldown/pluginutils",
|
||||
"version": "1.0.1",
|
||||
"description": "Plugin utilities for Rolldown",
|
||||
"keywords": [
|
||||
"filter",
|
||||
"plugin",
|
||||
"rolldown"
|
||||
],
|
||||
"homepage": "https://github.com/rolldown/plugins/tree/main/packages/pluginutils#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/rolldown/plugins/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rolldown/plugins.git",
|
||||
"directory": "packages/pluginutils"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./filter": "./dist/filter/index.mjs",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/picomatch": "^4.0.3",
|
||||
"picomatch": "^4.0.4",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown",
|
||||
"test": "vitest --project pluginutils",
|
||||
"test:types": "vitest --project pluginutils --typecheck.only"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user