From 5e97e79d5aaed1561ae3fde8b6ac07e15c91805d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Filho?= Date: Mon, 2 Jun 2025 15:32:36 -0300 Subject: [PATCH] fix: streamline stream polyfills and enhance process, module, setInterval --- .../stream/context/stream.context.js | 29 +++--- .../src/polyfills/stream/stream.polyfills.js | 85 +++++++++++------ packages/unenv-preset/src/index.ts | 3 +- .../src/polyfills/node/globals/process.cjs | 6 ++ .../polyfills/node/globals/set-interval.js | 21 +++++ .../unenv-preset/src/polyfills/node/module.js | 94 +++++++++++++------ 6 files changed, 162 insertions(+), 76 deletions(-) create mode 100644 packages/unenv-preset/src/polyfills/node/globals/set-interval.js diff --git a/packages/bundler/src/polyfills/stream/context/stream.context.js b/packages/bundler/src/polyfills/stream/context/stream.context.js index 4f9dec57..787a6f7b 100644 --- a/packages/bundler/src/polyfills/stream/context/stream.context.js +++ b/packages/bundler/src/polyfills/stream/context/stream.context.js @@ -1,21 +1,16 @@ /* eslint-disable */ import stream from 'node:stream'; -export var { Duplex } = stream; -export var { Writable } = stream; -export var { Readable } = stream; -export var { Transform } = stream; -export var { PassThrough } = stream; -export var { Stream } = stream; -export var { prototype } = stream; +const localStream = {}; +export const { Duplex, Writable, Readable, Transform, PassThrough, Stream } = stream; +export const { prototype } = stream; -export default { - Duplex, - Writable, - Readable, - Transform, - PassThrough, - Stream, - stream, - prototype, -}; +localStream.Duplex = Duplex; +localStream.Writable = Writable; +localStream.Readable = Readable; +localStream.Transform = Transform; +localStream.PassThrough = PassThrough; +localStream.Stream = Stream; +localStream.prototype = prototype; + +export default localStream; diff --git a/packages/bundler/src/polyfills/stream/stream.polyfills.js b/packages/bundler/src/polyfills/stream/stream.polyfills.js index f91de692..a6e836da 100644 --- a/packages/bundler/src/polyfills/stream/stream.polyfills.js +++ b/packages/bundler/src/polyfills/stream/stream.polyfills.js @@ -1,30 +1,60 @@ /* eslint-disable */ -/** This polyfill is referenced in #build/bundlers/polyfills/polyfills-manager.js - * +/** * STREAM_CONTEXT is defined in runtime.env.js for use on the local server */ -export var { Duplex } = STREAM_CONTEXT; -export var { Writable } = STREAM_CONTEXT; -export var { Readable } = STREAM_CONTEXT; -export var { Transform } = STREAM_CONTEXT; -export var { PassThrough } = STREAM_CONTEXT; -export var { Stream } = STREAM_CONTEXT; -export var { prototype } = STREAM_CONTEXT; +const localStream = {}; +const { Duplex, Writable, Readable, Transform, PassThrough, Stream } = STREAM_CONTEXT; +export const { prototype } = STREAM_CONTEXT; + +localStream.Duplex = Duplex; +localStream.Writable = Writable; +localStream.Readable = Readable; +localStream.Transform = Transform; +localStream.PassThrough = PassThrough; +localStream.Stream = Stream; +localStream.prototype = prototype; Readable.toWeb = function (readable) { + let onData, onEnd, onError; + let closed = false; const stream = new ReadableStream({ start(controller) { - readable.on('data', (chunk) => { - controller.enqueue(chunk); - }); - readable.on('end', () => { - controller.close(); - }); - readable.on('error', (error) => { - controller.error(error); + onData = (chunk) => { + if (!closed) controller.enqueue(chunk); + }; + onEnd = () => { + if (!closed) { + closed = true; + controller.close(); + } + }; + onError = (error) => { + if (!closed) { + closed = true; + controller.error(error); + } + }; + + readable.on('data', onData); + readable.on('end', onEnd); + readable.on('error', onError); + + readable.on('close', () => { + if (!closed) { + closed = true; + controller.close(); + } }); }, + cancel(reason) { + readable.off('data', onData); + readable.off('end', onEnd); + readable.off('error', onError); + if (typeof readable.destroy === 'function') { + readable.destroy(reason); + } + }, }); return stream; }; @@ -45,12 +75,14 @@ Readable.fromWeb = function (webStream) { }); }; -Writable.toWeb = function (webStream) { +Writable.fromWeb = function (webStream) { const writer = webStream.getWriter(); writer.closed.catch((error) => { - console.error('WritableStream closed with error:', error); - console.error('Error details:', error?.message, error?.stack); + if (error) { + console.error('WritableStream closed with error:', error); + console.error('Error details:', error?.message, error?.stack); + } }); return new Writable({ @@ -92,13 +124,6 @@ Writable.toWeb = function (webStream) { }); }; -export default { - Duplex, - Writable, - Readable, - Transform, - PassThrough, - Stream, - stream: STREAM_CONTEXT, - prototype, -}; +export { Duplex, PassThrough, Readable, Stream, Transform, Writable }; + +export default localStream; diff --git a/packages/unenv-preset/src/index.ts b/packages/unenv-preset/src/index.ts index 69ccad17..a1325a90 100644 --- a/packages/unenv-preset/src/index.ts +++ b/packages/unenv-preset/src/index.ts @@ -12,7 +12,8 @@ export default { __dirname: `${polyfillsPath}/node/globals/path-dirname.js`, __filename: `${polyfillsPath}/node/globals/path-filename.js`, process: `${polyfillsPath}/node/globals/process.cjs`, - performance: `${polyfillsPath}/node/globals/performance.js`, + performance: `unenv/polyfill/performance`, + setInterval: `${polyfillsPath}/node/globals/set-interval.js`, }, alias: { 'azion/utils': 'azion/utils', diff --git a/packages/unenv-preset/src/polyfills/node/globals/process.cjs b/packages/unenv-preset/src/polyfills/node/globals/process.cjs index 6e6e524e..7be5f3ed 100644 --- a/packages/unenv-preset/src/polyfills/node/globals/process.cjs +++ b/packages/unenv-preset/src/polyfills/node/globals/process.cjs @@ -1,5 +1,7 @@ /* eslint-disable */ // shim for using process in browser +globalThis.startTime = globalThis.startTime || Date.now(); + var processShim = (module.exports = {}); /* @@ -189,6 +191,10 @@ processShim.emit = noop; processShim.prependListener = noop; processShim.prependOnceListener = noop; +processShim.uptime = function () { + return (Date.now() - globalThis.startTime) / 1000; +}; + processShim.listeners = function (name) { return []; }; diff --git a/packages/unenv-preset/src/polyfills/node/globals/set-interval.js b/packages/unenv-preset/src/polyfills/node/globals/set-interval.js new file mode 100644 index 00000000..ac4a6aca --- /dev/null +++ b/packages/unenv-preset/src/polyfills/node/globals/set-interval.js @@ -0,0 +1,21 @@ +const _setInterval = globalThis.setInterval; +const _clearInterval = globalThis.clearInterval; + +globalThis.setInterval = (...args) => { + const id = _setInterval(...args); + if (typeof id === 'object' && id !== null) { + // this is necessary for compatibility with the Sentry library and node's timers + if (typeof id.unref !== 'function') { + id.unref = () => {}; + } + return id; + } + return { + id, + unref: () => {}, + ref: () => {}, + clear: () => _clearInterval(id), + }; +}; + +export default globalThis.setInterval; diff --git a/packages/unenv-preset/src/polyfills/node/module.js b/packages/unenv-preset/src/polyfills/node/module.js index 506d7038..35c2b9ea 100644 --- a/packages/unenv-preset/src/polyfills/node/module.js +++ b/packages/unenv-preset/src/polyfills/node/module.js @@ -8,7 +8,7 @@ function unimplemented() { throw new Error('Not implemented yet!'); } -const builtinModules = [ +var builtinModules = [ '_http_agent', '_http_client', '_http_common', @@ -84,34 +84,72 @@ function _nodeModulePaths(...args) { /* EMPTY */ } -// Crie um objeto para exportação -const moduleExports = { - builtinModules: builtinModules, - _cache: null, - _pathCache: null, - _extensions: null, - globalPaths: null, - _debug: unimplemented, - _findPath: unimplemented, - _nodeModulePaths: _nodeModulePaths, - _resolveLookupPaths: unimplemented, - _load: _load, +function _resolveFilename(...args) { + /* EMPTY */ +} + +const Module = {}; + +// Adicione as propriedades estáticas esperadas +Module.builtinModules = builtinModules; +Module._cache = null; +Module._pathCache = null; +Module._extensions = null; +Module.globalPaths = null; +Module._debug = unimplemented; +Module._findPath = unimplemented; +Module._nodeModulePaths = _nodeModulePaths; +Module._resolveLookupPaths = unimplemented; +Module._load = _load; +Module._resolveFilename = _resolveFilename; +Module.createRequireFromPath = unimplemented; +Module.createRequire = createRequire; +Module._initPaths = unimplemented; +Module._preloadModules = unimplemented; +Module.syncBuiltinESMExports = unimplemented; +Module.runMain = unimplemented; +Module.findSourceMap = unimplemented; +Module.SourceMap = unimplemented; +Module.require = unimplemented; +const _prototype = { + require: unimplemented, + resolve: unimplemented, + paths: [], + id: '', + filename: '', + loaded: false, + children: [], + exports: {}, + _compile: unimplemented, _resolveFilename: unimplemented, - createRequireFromPath: unimplemented, - createRequire: createRequire, - _initPaths: unimplemented, - _preloadModules: unimplemented, - syncBuiltinESMExports: unimplemented, - Module: unimplemented, - runMain: unimplemented, - findSourceMap: unimplemented, - SourceMap: unimplemented, }; -Object.defineProperty(moduleExports, '_resolveFilename', { - value: unimplemented, - writable: true, - configurable: true, -}); +export default Module; + +export var _cache = null, + _pathCache = null, + _extensions = null, + globalPaths = null; + +export { + unimplemented as _debug, + unimplemented as _findPath, + unimplemented as _initPaths, + unimplemented as _load, + unimplemented as _nodeModulePaths, + unimplemented as _preloadModules, + unimplemented as _resolveFilename, + unimplemented as _resolveLookupPaths, + builtinModules, + createRequire as createRequire, + createRequire as createRequireFromPath, + unimplemented as findSourceMap, + Module, + _prototype as prototype, + unimplemented as require, + unimplemented as runMain, + unimplemented as SourceMap, + unimplemented as syncBuiltinESMExports, +}; -export default moduleExports; +/* eslint-enable */