diff --git a/.changeset/little-numbers-report.md b/.changeset/little-numbers-report.md new file mode 100644 index 000000000000..741c1817995d --- /dev/null +++ b/.changeset/little-numbers-report.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/unenv-preset": patch +--- + +Revert "Drop `node:process` polyfill when v2 is available" diff --git a/packages/unenv-preset/package.json b/packages/unenv-preset/package.json index 6a8544c7b45c..c6346fb55a16 100644 --- a/packages/unenv-preset/package.json +++ b/packages/unenv-preset/package.json @@ -49,7 +49,7 @@ }, "peerDependencies": { "unenv": "2.0.0-rc.21", - "workerd": "^1.20250924.0" + "workerd": "^1.20250927.0" }, "peerDependenciesMeta": { "workerd": { diff --git a/packages/unenv-preset/src/preset.ts b/packages/unenv-preset/src/preset.ts index 07252886fd03..70e026217c03 100644 --- a/packages/unenv-preset/src/preset.ts +++ b/packages/unenv-preset/src/preset.ts @@ -47,7 +47,7 @@ const nativeModules = [ ]; // Modules implemented via a mix of workerd APIs and polyfills. -const hybridModules = ["console"]; +const hybridModules = ["console", "process"]; /** * Creates the Cloudflare preset for the given compatibility date and compatibility flags @@ -72,7 +72,6 @@ export function getCloudflarePreset({ const http2Overrides = getHttp2Overrides(compat); const osOverrides = getOsOverrides(compat); const fsOverrides = getFsOverrides(compat); - const processOverrides = getProcessOverrides(compat); // "dynamic" as they depend on the compatibility date and flags const dynamicNativeModules = [ @@ -81,7 +80,6 @@ export function getCloudflarePreset({ ...http2Overrides.nativeModules, ...osOverrides.nativeModules, ...fsOverrides.nativeModules, - ...processOverrides.nativeModules, ]; // "dynamic" as they depend on the compatibility date and flags @@ -91,7 +89,6 @@ export function getCloudflarePreset({ ...http2Overrides.hybridModules, ...osOverrides.hybridModules, ...fsOverrides.hybridModules, - ...processOverrides.hybridModules, ]; return { @@ -125,7 +122,7 @@ export function getCloudflarePreset({ clearImmediate: false, setImmediate: false, console: "@cloudflare/unenv-preset/node/console", - ...processOverrides.inject, + process: "@cloudflare/unenv-preset/node/process", }, polyfill: ["@cloudflare/unenv-preset/polyfill/performance"], external: dynamicNativeModules.flatMap((p) => [p, `node:${p}`]), @@ -308,48 +305,3 @@ function getFsOverrides({ hybridModules: [], }; } - -/** - * Returns the overrides for `node:process` and `node:fs/promises` - * - * The native process v2 implementation: - * - is enabled starting from 2025-09-15 - * - can be enabled with the "enable_nodejs_process_v2" flag - * - can be disabled with the "disable_nodejs_process_v2" flag - */ -function getProcessOverrides({ - compatibilityDate, - compatibilityFlags, -}: { - compatibilityDate: string; - compatibilityFlags: string[]; -}): { - nativeModules: string[]; - hybridModules: string[]; - inject: { process: string | false }; -} { - const disabledV2ByFlag = compatibilityFlags.includes( - "disable_nodejs_process_v2" - ); - - const enabledV2ByFlag = compatibilityFlags.includes( - "enable_nodejs_process_v2" - ); - const enabledV2ByDate = compatibilityDate >= "2025-09-15"; - - const isV2 = (enabledV2ByFlag || enabledV2ByDate) && !disabledV2ByFlag; - - return isV2 - ? { - nativeModules: ["process"], - hybridModules: [], - // We can use the native global, return `false` to drop the unenv default - inject: { process: false }, - } - : { - nativeModules: [], - hybridModules: ["process"], - // Use the module default export as the global `process` - inject: { process: "@cloudflare/unenv-preset/node/process" }, - }; -} diff --git a/packages/unenv-preset/src/runtime/node/process.ts b/packages/unenv-preset/src/runtime/node/process.ts index 18dc84d7355e..3b6576636d63 100644 --- a/packages/unenv-preset/src/runtime/node/process.ts +++ b/packages/unenv-preset/src/runtime/node/process.ts @@ -1,6 +1,3 @@ -// The polyfill is only used with the process v1 native implementation -// process v2 implements all the APIs from workerd v1.20250924.0 - import { hrtime as UnenvHrTime } from "unenv/node/internal/process/hrtime"; import { Process as UnenvProcess } from "unenv/node/internal/process/process"; @@ -19,38 +16,83 @@ export const getBuiltinModule: NodeJS.Process["getBuiltinModule"] = const workerdProcess = getBuiltinModule("node:process"); +// Workerd has 2 different implementation for `node:process` +// +// See: +// - [workerd `process` v1](https://github.com/cloudflare/workerd/blob/main/src/node/internal/legacy_process.ts) +// - [workerd `process` v2](https://github.com/cloudflare/workerd/blob/main/src/node/internal/public_process.ts) +// - [`enable_nodejs_process_v2` flag](https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp) +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const isWorkerdProcessV2 = (globalThis as any).Cloudflare.compatibilityFlags + .enable_nodejs_process_v2; + const unenvProcess = new UnenvProcess({ env: globalProcess.env, - hrtime: UnenvHrTime, + // `hrtime` is only available from workerd process v2 + hrtime: isWorkerdProcessV2 ? workerdProcess.hrtime : UnenvHrTime, // `nextTick` is available from workerd process v1 nextTick: workerdProcess.nextTick, }); -// APIs implemented by workerd process in both v1 and v2 +// APIs implemented by workerd module in both v1 and v2 // Note that `env`, `hrtime` and `nextTick` are always retrieved from `unenv` export const { exit, features, platform } = workerdProcess; +// APIs that can be implemented by either `unenv` or `workerd`. +// They are always retrieved from `unenv` which might use their `workerd` implementation. +export const { + // Always implemented by workerd + env, + // Only implemented in workerd v2 + hrtime, + // Always implemented by workerd + nextTick, +} = unenvProcess; + +// APIs that are not implemented by `workerd` (whether v1 or v2) +// They are retrieved from `unenv`. export const { _channel, - _debugEnd, - _debugProcess, _disconnect, _events, _eventsCount, + _handleQueue, + _maxListeners, + _pendingMessage, + _send, + assert, + disconnect, + mainModule, +} = unenvProcess; + +// API that are only implemented starting from v2 of workerd process +// They are retrieved from unenv when process v1 is used +export const { + // @ts-expect-error `_debugEnd` is missing typings + _debugEnd, + // @ts-expect-error `_debugProcess` is missing typings + _debugProcess, + // @ts-expect-error `_exiting` is missing typings _exiting, + // @ts-expect-error `_fatalException` is missing typings _fatalException, + // @ts-expect-error `_getActiveHandles` is missing typings _getActiveHandles, + // @ts-expect-error `_getActiveRequests` is missing typings _getActiveRequests, - _handleQueue, + // @ts-expect-error `_kill` is missing typings _kill, + // @ts-expect-error `_linkedBinding` is missing typings _linkedBinding, - _maxListeners, - _pendingMessage, + // @ts-expect-error `_preload_modules` is missing typings _preload_modules, + // @ts-expect-error `_rawDebug` is missing typings _rawDebug, - _send, + // @ts-expect-error `_startProfilerIdleNotifier` is missing typings _startProfilerIdleNotifier, + // @ts-expect-error `_stopProfilerIdleNotifier` is missing typings _stopProfilerIdleNotifier, + // @ts-expect-error `_tickCallback` is missing typings _tickCallback, abort, addListener, @@ -58,8 +100,8 @@ export const { arch, argv, argv0, - assert, availableMemory, + // @ts-expect-error `binding` is missing typings binding, channel, chdir, @@ -69,12 +111,11 @@ export const { cpuUsage, cwd, debugPort, - disconnect, dlopen, + // @ts-expect-error `domain` is missing typings domain, emit, emitWarning, - env, eventNames, execArgv, execPath, @@ -88,19 +129,19 @@ export const { getMaxListeners, getuid, hasUncaughtExceptionCaptureCallback, - hrtime, + // @ts-expect-error `initgroups` is missing typings initgroups, kill, listenerCount, listeners, loadEnvFile, - mainModule, memoryUsage, + // @ts-expect-error `moduleLoadList` is missing typings moduleLoadList, - nextTick, off, on, once, + // @ts-expect-error `openStdin` is missing typings openStdin, permission, pid, @@ -108,6 +149,7 @@ export const { prependListener, prependOnceListener, rawListeners, + // @ts-expect-error `reallyExit` is missing typings reallyExit, ref, release, @@ -136,7 +178,7 @@ export const { uptime, version, versions, -} = unenvProcess; +} = isWorkerdProcessV2 ? workerdProcess : unenvProcess; const _process = { abort, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 226eaa001685..3832540ed7de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2172,8 +2172,8 @@ importers: specifier: 2.0.0-rc.21 version: 2.0.0-rc.21 workerd: - specifier: ^1.20250924.0 - version: 1.20250927.0 + specifier: ^1.20250927.0 + version: 1.20251001.0 devDependencies: '@types/node-unenv': specifier: npm:@types/node@^22.14.0 @@ -4493,12 +4493,6 @@ packages: cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-64@1.20250927.0': - resolution: {integrity: sha512-rFtXu/qhZziGOltjhHUCdlqP9wLUhf/CmnjJS0hXffGRAVxsCXhJw+7Vlr+hyRSHjHRhEV+gBFc4pHzT10Stzw==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - '@cloudflare/workerd-darwin-64@1.20251001.0': resolution: {integrity: sha512-y1ST/cCscaRewWRnsHZdWbgiLJbki5UMGd0hMo/FLqjlztwPeDgQ5CGm5jMiCDdw/IBCpWxEukftPYR34rWNog==} engines: {node: '>=16'} @@ -4517,12 +4511,6 @@ packages: cpu: [arm64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20250927.0': - resolution: {integrity: sha512-BcNlLVfPyctLjFeIJENhK7OZFkfaysHVA6G6KT1lwum+BaVOutebweLo2zOrH7UQCMDYdpkQOeb5nLDctvs8YA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20251001.0': resolution: {integrity: sha512-+z4QHHZ/Yix82zLFYS+ZS2UV09IENFPwDCEKUWfnrM9Km2jOOW3Ua4hJNob1EgQUYs8fFZo7k5O/tpwxMsSbbQ==} engines: {node: '>=16'} @@ -4541,12 +4529,6 @@ packages: cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-64@1.20250927.0': - resolution: {integrity: sha512-3c+RuyMj3CkaFS9mmVJyX6nNUdTn2kdWgPrpPoj7VbtU2BEGkrH1a4VAgIAiUh/tYRGUeY3owrUhqCv6L7HmJQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - '@cloudflare/workerd-linux-64@1.20251001.0': resolution: {integrity: sha512-hGS+O2V9Mm2XjJUaB9ZHMA5asDUaDjKko42e+accbew0PQR7zrAl1afdII6hMqCLV4tk4GAjvhv281pN4g48rg==} engines: {node: '>=16'} @@ -4565,12 +4547,6 @@ packages: cpu: [arm64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20250927.0': - resolution: {integrity: sha512-/XtcZnIryAgLvums08r5xiSm5hYfRfUuj2iq/5Jl+Yysx1BmPjYLqjcIIXNATrzpKUrxf3AkvpSI75MBcePgpA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - '@cloudflare/workerd-linux-arm64@1.20251001.0': resolution: {integrity: sha512-QYaMK+pRgt28N7CX1JlJ+ToegJF9LxzqdT7MjWqPgVj9D2WTyIhBVYl3wYjJRcgOlnn+DRt42+li4T64CPEeuA==} engines: {node: '>=16'} @@ -4589,12 +4565,6 @@ packages: cpu: [x64] os: [win32] - '@cloudflare/workerd-windows-64@1.20250927.0': - resolution: {integrity: sha512-+m124IiM149QvvzAOrO766uTdILqXJZqzZjqTaMTaWXegjjsJwGSL6v9d71TSFntEwxeXnpJPBkVWyKZFjqrvg==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - '@cloudflare/workerd-windows-64@1.20251001.0': resolution: {integrity: sha512-ospnDR/FlyRvrv9DSHuxDAXmzEBLDUiAHQrQHda1iUH9HqxnNQ8giz9VlPfq7NIRc7bQ1ZdIYPGLJOY4Q366Ng==} engines: {node: '>=16'} @@ -13168,11 +13138,6 @@ packages: engines: {node: '>=16'} hasBin: true - workerd@1.20250927.0: - resolution: {integrity: sha512-6kyAGPGYNvn5mbpCJJ48VebN7QGSrvU/WJXgd4EQz20PyqjJAxHcEGGAJ+0Da0u/ewrN1+6fuMKQ1ALLBPiTWg==} - engines: {node: '>=16'} - hasBin: true - workerd@1.20251001.0: resolution: {integrity: sha512-oT/K4YWNhmwpVmGeaHNmF7mLRfgjszlVr7lJtpS4jx5khmxmMzWZEEQRrJEpgzeHP6DOq9qWLPNT0bjMK7TchQ==} engines: {node: '>=16'} @@ -14478,9 +14443,6 @@ snapshots: '@cloudflare/workerd-darwin-64@1.20250417.0': optional: true - '@cloudflare/workerd-darwin-64@1.20250927.0': - optional: true - '@cloudflare/workerd-darwin-64@1.20251001.0': optional: true @@ -14490,9 +14452,6 @@ snapshots: '@cloudflare/workerd-darwin-arm64@1.20250417.0': optional: true - '@cloudflare/workerd-darwin-arm64@1.20250927.0': - optional: true - '@cloudflare/workerd-darwin-arm64@1.20251001.0': optional: true @@ -14502,9 +14461,6 @@ snapshots: '@cloudflare/workerd-linux-64@1.20250417.0': optional: true - '@cloudflare/workerd-linux-64@1.20250927.0': - optional: true - '@cloudflare/workerd-linux-64@1.20251001.0': optional: true @@ -14514,9 +14470,6 @@ snapshots: '@cloudflare/workerd-linux-arm64@1.20250417.0': optional: true - '@cloudflare/workerd-linux-arm64@1.20250927.0': - optional: true - '@cloudflare/workerd-linux-arm64@1.20251001.0': optional: true @@ -14526,9 +14479,6 @@ snapshots: '@cloudflare/workerd-windows-64@1.20250417.0': optional: true - '@cloudflare/workerd-windows-64@1.20250927.0': - optional: true - '@cloudflare/workerd-windows-64@1.20251001.0': optional: true @@ -23592,14 +23542,6 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20250417.0 '@cloudflare/workerd-windows-64': 1.20250417.0 - workerd@1.20250927.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20250927.0 - '@cloudflare/workerd-darwin-arm64': 1.20250927.0 - '@cloudflare/workerd-linux-64': 1.20250927.0 - '@cloudflare/workerd-linux-arm64': 1.20250927.0 - '@cloudflare/workerd-windows-64': 1.20250927.0 - workerd@1.20251001.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20251001.0