Skip to content

fix: streamline stream polyfills and enhance process, module, setInterval #169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions packages/bundler/src/polyfills/stream/context/stream.context.js
Original file line number Diff line number Diff line change
@@ -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;
85 changes: 55 additions & 30 deletions packages/bundler/src/polyfills/stream/stream.polyfills.js
Original file line number Diff line number Diff line change
@@ -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;
};
Expand All @@ -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({
Expand Down Expand Up @@ -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;
3 changes: 2 additions & 1 deletion packages/unenv-preset/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* eslint-disable */
// shim for using process in browser
globalThis.startTime = globalThis.startTime || Date.now();

var processShim = (module.exports = {});

/*
Expand Down Expand Up @@ -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 [];
};
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
94 changes: 66 additions & 28 deletions packages/unenv-preset/src/polyfills/node/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function unimplemented() {
throw new Error('Not implemented yet!');
}

const builtinModules = [
var builtinModules = [
'_http_agent',
'_http_client',
'_http_common',
Expand Down Expand Up @@ -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 */