diff options
author | 2022-07-02 01:28:45 -0700 | |
---|---|---|
committer | 2022-07-02 01:36:04 -0700 | |
commit | f6002b799b34dadaab1ea6701569b8a096fbe7e0 (patch) | |
tree | 4a2df22e283fffc1010e4351db5fc1c528496c7b | |
parent | 874344eead8939075f06de367265209a9aad32ff (diff) | |
download | bun-f6002b799b34dadaab1ea6701569b8a096fbe7e0.tar.gz bun-f6002b799b34dadaab1ea6701569b8a096fbe7e0.tar.zst bun-f6002b799b34dadaab1ea6701569b8a096fbe7e0.zip |
Delete `BunStream`
-rw-r--r-- | src/bun.js/bindings/BunStream.cpp | 527 | ||||
-rw-r--r-- | src/bun.js/bindings/BunStream.h | 89 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 24 | ||||
-rw-r--r-- | src/bun.js/node/node_fs.zig | 47 | ||||
-rw-r--r-- | src/bun.js/node/types.zig | 946 |
5 files changed, 13 insertions, 1620 deletions
diff --git a/src/bun.js/bindings/BunStream.cpp b/src/bun.js/bindings/BunStream.cpp deleted file mode 100644 index 2dbb53562..000000000 --- a/src/bun.js/bindings/BunStream.cpp +++ /dev/null @@ -1,527 +0,0 @@ -#include "BunStream.h" -#include "JavaScriptCore/JSMicrotask.h" -#include "JavaScriptCore/ObjectConstructor.h" - -namespace WebCore { -using JSGlobalObject = JSC::JSGlobalObject; -using Exception = JSC::Exception; -using JSValue = JSC::JSValue; -using JSString = JSC::JSString; -using JSModuleLoader = JSC::JSModuleLoader; -using JSModuleRecord = JSC::JSModuleRecord; -using Identifier = JSC::Identifier; -using SourceOrigin = JSC::SourceOrigin; -using JSObject = JSC::JSObject; -using JSNonFinalObject = JSC::JSNonFinalObject; -namespace JSCastingHelpers = JSC::JSCastingHelpers; - -static ReadableEvent getReadableEvent(const WTF::String& eventName); -static ReadableEvent getReadableEvent(const WTF::String& eventName) -{ - if (eventName == "close") - return ReadableEvent__Close; - else if (eventName == "data") - return ReadableEvent__Data; - else if (eventName == "end") - return ReadableEvent__End; - else if (eventName == "error") - return ReadableEvent__Error; - else if (eventName == "pause") - return ReadableEvent__Pause; - else if (eventName == "readable") - return ReadableEvent__Readable; - else if (eventName == "resume") - return ReadableEvent__Resume; - else if (eventName == "open") - return ReadableEvent__Open; - else - return ReadableEventUser; -} - -static WritableEvent getWritableEvent(const WTF::String& eventName); -static WritableEvent getWritableEvent(const WTF::String& eventName) -{ - if (eventName == "close") - return WritableEvent__Close; - else if (eventName == "drain") - return WritableEvent__Drain; - else if (eventName == "error") - return WritableEvent__Error; - else if (eventName == "finish") - return WritableEvent__Finish; - else if (eventName == "pipe") - return WritableEvent__Pipe; - else if (eventName == "unpipe") - return WritableEvent__Unpipe; - else if (eventName == "open") - return WritableEvent__Open; - else - return WritableEventUser; -} - -// clang-format off -#define DEFINE_CALLBACK_FUNCTION_BODY(TypeName, ZigFunction) JSC::VM& vm = globalObject->vm(); \ - auto* thisObject = JSC::jsDynamicCast<TypeName*>( callFrame->thisValue()); \ - auto scope = DECLARE_THROW_SCOPE(vm); \ - if (!thisObject) \ - return throwVMTypeError(globalObject, scope); \ - auto argCount = static_cast<uint16_t>(callFrame->argumentCount()); \ - WTF::Vector<JSC::EncodedJSValue, 16> arguments; \ - arguments.reserveInitialCapacity(argCount); \ - if (argCount) { \ - for (uint16_t i = 0; i < argCount; ++i) { \ - arguments.uncheckedAppend(JSC::JSValue::encode(callFrame->uncheckedArgument(i))); \ - } \ - } \ - JSC::JSValue result = JSC::JSValue::decode( \ - ZigFunction(thisObject->state, globalObject, reinterpret_cast<JSC__JSValue*>(arguments.data()), argCount) \ - ); \ - JSC::JSObject *obj = result.getObject(); \ - if (UNLIKELY(obj != nullptr && obj->isErrorInstance())) { \ - scope.throwException(globalObject, obj); \ - return JSC::JSValue::encode(JSC::jsUndefined()); \ - } \ - if (UNLIKELY(scope.exception())) \ - return JSC::JSValue::encode(JSC::jsUndefined()); \ - return JSC::JSValue::encode(result); - -// clang-format on -// static JSC_DECLARE_HOST_FUNCTION(Writable__addEventListener); -// static JSC_DECLARE_HOST_FUNCTION(Readable__addEventListener); -// static JSC_DECLARE_HOST_FUNCTION(Writable__prependListener); -// static JSC_DECLARE_HOST_FUNCTION(Readable__prependListener); -// static JSC_DECLARE_HOST_FUNCTION(Writable__prependOnceListener); -// static JSC_DECLARE_HOST_FUNCTION(Readable__prependOnceListener); -// static JSC_DECLARE_HOST_FUNCTION(Writable__setMaxListeners); -// static JSC_DECLARE_HOST_FUNCTION(Readable__setMaxListeners); -// static JSC_DECLARE_HOST_FUNCTION(Writable__getMaxListeners); -// static JSC_DECLARE_HOST_FUNCTION(Readable__getMaxListeners); -// static JSC_DECLARE_HOST_FUNCTION(Readable__setDefaultEncoding); -static JSC_DECLARE_HOST_FUNCTION(Readable__on); -// static JSC_DECLARE_HOST_FUNCTION(Readable__off); -static JSC_DECLARE_HOST_FUNCTION(Readable__once); -static JSC_DECLARE_HOST_FUNCTION(Readable__pause); -static JSC_DECLARE_HOST_FUNCTION(Readable__pipe); -static JSC_DECLARE_HOST_FUNCTION(Readable__read); -static JSC_DECLARE_HOST_FUNCTION(Readable__resume); -static JSC_DECLARE_HOST_FUNCTION(Readable__unpipe); -static JSC_DECLARE_HOST_FUNCTION(Readable__unshift); - -static JSC_DECLARE_HOST_FUNCTION(Writable__close); -// static JSC_DECLARE_HOST_FUNCTION(Writable__off); -static JSC_DECLARE_HOST_FUNCTION(Writable__cork); -static JSC_DECLARE_HOST_FUNCTION(Writable__destroy); -static JSC_DECLARE_HOST_FUNCTION(Writable__end); -static JSC_DECLARE_HOST_FUNCTION(Writable__on); -static JSC_DECLARE_HOST_FUNCTION(Writable__once); -static JSC_DECLARE_HOST_FUNCTION(Writable__uncork); -static JSC_DECLARE_HOST_FUNCTION(Writable__write); - -static JSC_DEFINE_HOST_FUNCTION(Readable__on, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - - if (callFrame->argumentCount() < 2) { - return JSC::JSValue::encode(JSC::jsUndefined()); - } - JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - auto thisObject = JSC::jsDynamicCast<WebCore::Readable*>(callFrame->thisValue()); - if (UNLIKELY(!thisObject)) { - scope.release(); - JSC::throwVMTypeError(globalObject, scope); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto eventName = callFrame->argument(0).toStringOrNull(globalObject); - if (UNLIKELY(!eventName)) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - ReadableEvent event = getReadableEvent(eventName->value(globalObject)); - if (event == ReadableEventUser) { - // TODO: - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto listener = callFrame->argument(1); - JSC::JSObject* object = listener.getObject(); - if (UNLIKELY(!object) || !listener.isCallable()) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - Bun__Readable__addEventListener(thisObject->state, globalObject, event, - JSC::JSValue::encode(listener), true); - - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); -} - -extern "C" Bun__Readable* JSC__JSValue__getReadableStreamState(JSC__JSValue value, JSC__VM* vm) -{ - auto* thisObject = JSC::jsDynamicCast<WebCore::Readable*>(JSC::JSValue::decode(value)); - if (UNLIKELY(!thisObject)) { - return nullptr; - } - return thisObject->state; -} -extern "C" Bun__Writable* JSC__JSValue__getWritableStreamState(JSC__JSValue value, JSC__VM* vm) -{ - auto* thisObject = JSC::jsDynamicCast<WebCore::Writable*>(JSC::JSValue::decode(value)); - if (UNLIKELY(!thisObject)) { - return nullptr; - } - return thisObject->state; -} - -const JSC::ClassInfo Readable::s_info = { "Readable"_s, &Base::s_info, nullptr, nullptr, - CREATE_METHOD_TABLE(Readable) }; - -const JSC::ClassInfo Writable::s_info = { "Writable"_s, &Base::s_info, nullptr, nullptr, - CREATE_METHOD_TABLE(Writable) }; - -static JSC_DEFINE_HOST_FUNCTION(Readable__once, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - - if (callFrame->argumentCount() < 2) { - return JSC::JSValue::encode(JSC::jsUndefined()); - } - JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - auto thisObject = JSC::jsDynamicCast<WebCore::Readable*>(callFrame->thisValue()); - if (UNLIKELY(!thisObject)) { - scope.release(); - JSC::throwVMTypeError(globalObject, scope); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto eventName = callFrame->argument(0).toStringOrNull(globalObject); - if (UNLIKELY(!eventName)) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - ReadableEvent event = getReadableEvent(eventName->value(globalObject)); - if (event == ReadableEventUser) { - // TODO: - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto listener = callFrame->argument(1); - JSC::JSObject* object = listener.getObject(); - if (UNLIKELY(!object) || !listener.isCallable()) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - Bun__Readable__addEventListener(thisObject->state, globalObject, event, - JSC::JSValue::encode(listener), true); - - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); -} - -static JSC_DEFINE_HOST_FUNCTION(Writable__on, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - - if (callFrame->argumentCount() < 2) { - return JSC::JSValue::encode(JSC::jsUndefined()); - } - JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - auto thisObject = JSC::jsDynamicCast<WebCore::Writable*>(callFrame->thisValue()); - if (UNLIKELY(!thisObject)) { - scope.release(); - JSC::throwVMTypeError(globalObject, scope); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto eventName = callFrame->argument(0).toStringOrNull(globalObject); - if (UNLIKELY(!eventName)) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - WritableEvent event = getWritableEvent(eventName->value(globalObject)); - if (event == WritableEventUser) { - // TODO: - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto listener = callFrame->argument(1); - JSC::JSObject* object = listener.getObject(); - if (UNLIKELY(!object) || !listener.isCallable()) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - Bun__Writable__addEventListener(thisObject->state, globalObject, event, - JSC::JSValue::encode(listener), false); - - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); -} - -static JSC_DEFINE_HOST_FUNCTION(Writable__once, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - - if (callFrame->argumentCount() < 2) { - return JSC::JSValue::encode(JSC::jsUndefined()); - } - JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - auto thisObject = JSC::jsDynamicCast<WebCore::Writable*>(callFrame->thisValue()); - if (UNLIKELY(!thisObject)) { - scope.release(); - JSC::throwVMTypeError(globalObject, scope); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto eventName = callFrame->argument(0).toStringOrNull(globalObject); - if (UNLIKELY(!eventName)) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - WritableEvent event = getWritableEvent(eventName->value(globalObject)); - if (event == WritableEventUser) { - // TODO: - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto listener = callFrame->argument(1); - JSC::JSObject* object = listener.getObject(); - if (UNLIKELY(!object) || !listener.isCallable()) { - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - Bun__Writable__addEventListener(thisObject->state, globalObject, event, - JSC::JSValue::encode(listener), true); - - scope.release(); - return JSC::JSValue::encode(JSC::jsUndefined()); -} - -static JSC_DEFINE_HOST_FUNCTION(Readable__read, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__read); -} - -static JSC_DEFINE_HOST_FUNCTION(Readable__pipe, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__pipe); -} - -static JSC_DEFINE_HOST_FUNCTION(Readable__resume, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__resume); -} -static JSC_DEFINE_HOST_FUNCTION(Readable__unpipe, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__unpipe); -} -static JSC_DEFINE_HOST_FUNCTION(Readable__pause, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__pause); -} -static JSC_DEFINE_HOST_FUNCTION(Readable__unshift, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Readable, Bun__Readable__unshift); -} - -// static JSC_DECLARE_HOST_FUNCTION(Readable__isPaused); -// static JSC_DECLARE_HOST_FUNCTION(Writable__setDefaultEncoding); - -// static DEFINE_CALLBACK_FUNCTION(Writable__setDefaultEncoding, WebCore::Writable, -// Bun__Writable__setDefaultEncoding); - -static JSC_DEFINE_HOST_FUNCTION(Writable__write, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__write); -} -static JSC_DEFINE_HOST_FUNCTION(Writable__end, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__end); -} -static JSC_DEFINE_HOST_FUNCTION(Writable__close, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__close); -} -static JSC_DEFINE_HOST_FUNCTION(Writable__destroy, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__destroy); -} -static JSC_DEFINE_HOST_FUNCTION(Writable__cork, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__cork); -} -static JSC_DEFINE_HOST_FUNCTION(Writable__uncork, - (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) -{ - DEFINE_CALLBACK_FUNCTION_BODY(WebCore::Writable, Bun__Writable__uncork); -} - -extern "C" JSC__JSValue Bun__Readable__create(Bun__Readable* state, - JSC__JSGlobalObject* globalObject) -{ - JSC::JSValue result = JSC::JSValue(Readable::create( - globalObject->vm(), state, - Readable::createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype()))); - - return JSC::JSValue::encode(result); -} -extern "C" JSC__JSValue Bun__Writable__create(Bun__Writable* state, - JSC__JSGlobalObject* globalObject) -{ - JSC::JSValue result = JSC::JSValue(Writable::create( - globalObject->vm(), state, - Writable::createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype()))); - - return JSC::JSValue::encode(result); -} - -Readable::~Readable() -{ - if (this->state) { - Bun__Readable__deinit(this->state); - } -} - -Writable::~Writable() -{ - if (this->state) { - Bun__Writable__deinit(this->state); - } -} - -void Readable::finishCreation(JSC::VM& vm) -{ - Base::finishCreation(vm); - auto clientData = WebCore::clientData(vm); - auto* globalObject = this->globalObject(); - - putDirect(vm, clientData->builtinNames().onPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().onPublicName().string(), Readable__on), - 0); - putDirect(vm, clientData->builtinNames().oncePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().oncePublicName().string(), - Readable__once), - 0); - putDirect(vm, clientData->builtinNames().pausePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().pausePublicName().string(), - Readable__pause), - 0); - putDirect(vm, clientData->builtinNames().pipePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().pipePublicName().string(), - Readable__pipe), - 0); - putDirect(vm, clientData->builtinNames().readPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().readPublicName().string(), - Readable__read), - 0); - putDirect(vm, clientData->builtinNames().resumePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().resumePublicName().string(), - Readable__resume), - 0); - putDirect(vm, clientData->builtinNames().unpipePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().unpipePublicName().string(), - Readable__unpipe), - 0); - putDirect(vm, clientData->builtinNames().unshiftPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().unshiftPublicName().string(), - Readable__unshift), - 0); -} - -void Writable::finishCreation(JSC::VM& vm) -{ - Base::finishCreation(vm); - auto clientData = WebCore::clientData(vm); - - auto* globalObject = this->globalObject(); - - putDirect(vm, clientData->builtinNames().onPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().onPublicName().string(), Writable__on), - 0); - - putDirect(vm, clientData->builtinNames().oncePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().oncePublicName().string(), - Writable__once), - 0); - - putDirect(vm, clientData->builtinNames().closePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().closePublicName().string(), - Writable__close), - 0); - putDirect(vm, clientData->builtinNames().corkPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().corkPublicName().string(), - Writable__cork), - 0); - putDirect(vm, clientData->builtinNames().destroyPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().destroyPublicName().string(), - Writable__destroy), - 0); - putDirect(vm, clientData->builtinNames().endPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().endPublicName().string(), Writable__end), - 0); - putDirect(vm, clientData->builtinNames().onPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().onPublicName().string(), Writable__on), - 0); - putDirect(vm, clientData->builtinNames().oncePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().oncePublicName().string(), - Writable__once), - 0); - putDirect(vm, clientData->builtinNames().uncorkPublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().uncorkPublicName().string(), - Writable__uncork), - 0); - putDirect(vm, clientData->builtinNames().writePublicName(), - JSFunction::create(vm, globalObject, 2, - clientData->builtinNames().writePublicName().string(), - Writable__write), - 0); -} - -} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/BunStream.h b/src/bun.js/bindings/BunStream.h deleted file mode 100644 index 64837c219..000000000 --- a/src/bun.js/bindings/BunStream.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include "BunBuiltinNames.h" -#include "BunClientData.h" -#include "root.h" - -namespace WebCore { - -using namespace JSC; - -class Readable : public JSC::JSNonFinalObject { - using Base = JSC::JSNonFinalObject; - -public: - Bun__Readable* state; - Readable(JSC::VM& vm, Bun__Readable* readable, JSC::Structure* structure) - : Base(vm, structure) - { - state = readable; - } - - ~Readable(); - - DECLARE_INFO; - - static constexpr unsigned StructureFlags = Base::StructureFlags; - - template<typename CellType, SubspaceAccess> static GCClient::IsoSubspace* subspaceFor(VM& vm) - { - return &vm.plainObjectSpace(); - } - - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, - JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, - JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); - } - - static Readable* create(JSC::VM& vm, Bun__Readable* state, JSC::Structure* structure) - { - Readable* accessor = new (NotNull, JSC::allocateCell<WebCore::Readable>(vm)) Readable(vm, state, structure); - accessor->finishCreation(vm); - return accessor; - } - - void finishCreation(JSC::VM& vm); -}; - -class Writable : public JSC::JSNonFinalObject { - using Base = JSC::JSNonFinalObject; - -public: - Bun__Writable* state; - Writable(JSC::VM& vm, Bun__Writable* writable, JSC::Structure* structure) - : Base(vm, structure) - { - state = writable; - } - - DECLARE_INFO; - - static constexpr unsigned StructureFlags = Base::StructureFlags; - - template<typename CellType, SubspaceAccess> static GCClient::IsoSubspace* subspaceFor(VM& vm) - { - return &vm.plainObjectSpace(); - } - - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, - JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, - JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); - } - - static Writable* create(JSC::VM& vm, Bun__Writable* state, JSC::Structure* structure) - { - - Writable* accessor = new (NotNull, JSC::allocateCell<Writable>(vm)) Writable(vm, state, structure); - accessor->finishCreation(vm); - return accessor; - } - ~Writable(); - - void finishCreation(JSC::VM& vm); -}; - -} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index d87ffd8c1..aff961154 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -173,10 +173,6 @@ pub const ZigErrorType = extern struct { } }; -/// do not use this reference directly, use JSC.Node.Readable -pub const NodeReadableStream = JSC.Node.Readable.State; -/// do not use this reference directly, use JSC.Node.Writable -pub const NodeWritableStream = JSC.Node.Writable.State; pub const NodePath = JSC.Node.Path; // Web Streams @@ -2521,24 +2517,22 @@ pub const HTTPDebugServerRequestContext = JSC.API.DebugServer.RequestContext; pub const HTTPDebugSSLServerRequestContext = JSC.API.DebugSSLServer.RequestContext; comptime { - WebSocketHTTPClient.shim.ref(); - WebSocketHTTSPClient.shim.ref(); - WebSocketClient.shim.ref(); - WebSocketClientTLS.shim.ref(); + if (!is_bindgen) { + WebSocketHTTPClient.shim.ref(); + WebSocketHTTSPClient.shim.ref(); + WebSocketClient.shim.ref(); + WebSocketClientTLS.shim.ref(); - HTTPServerRequestContext.shim.ref(); - HTTPSSLServerRequestContext.shim.ref(); - HTTPDebugServerRequestContext.shim.ref(); - HTTPDebugSSLServerRequestContext.shim.ref(); + HTTPServerRequestContext.shim.ref(); + HTTPSSLServerRequestContext.shim.ref(); + HTTPDebugServerRequestContext.shim.ref(); + HTTPDebugSSLServerRequestContext.shim.ref(); - if (!is_bindgen) { _ = Process.getTitle; _ = Process.setTitle; _ = Zig__getAPIGlobals; _ = Zig__getAPIConstructors; - NodeReadableStream.shim.ref(); Bun.Timer.shim.ref(); - NodeWritableStream.shim.ref(); NodePath.shim.ref(); JSReadableStreamBlob.shim.ref(); JSArrayBufferSink.shim.ref(); diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 3cacb57b2..5cd17804b 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -2306,8 +2306,6 @@ const Return = struct { pub const WatchFile = void; pub const Utimes = void; - pub const CreateReadStream = *JSC.Node.Stream; - pub const CreateWriteStream = *JSC.Node.Stream; pub const Chown = void; pub const Lutimes = void; }; @@ -3611,47 +3609,10 @@ pub const NodeFS = struct { _ = flavor; return Maybe(Return.Watch).todo; } - pub fn createReadStream(this: *NodeFS, args: Arguments.CreateReadStream, comptime flavor: Flavor) Maybe(Return.CreateReadStream) { - _ = args; - _ = this; - _ = flavor; - var stream = bun.default_allocator.create(JSC.Node.Stream) catch unreachable; - stream.* = JSC.Node.Stream{ - .sink = .{ - .readable = JSC.Node.Readable{ - .stream = stream, - .globalObject = args.global_object, - }, - }, - .sink_type = .readable, - .content = undefined, - .content_type = undefined, - .allocator = bun.default_allocator, - }; - - args.file.copyToStream(args.flags, args.autoClose, args.mode, bun.default_allocator, stream) catch unreachable; - args.copyToState(&stream.sink.readable.state); - return Maybe(Return.CreateReadStream){ .result = stream }; + pub fn createReadStream(_: *NodeFS, _: Arguments.CreateReadStream, comptime _: Flavor) Maybe(Return.CreateReadStream) { + return Maybe(Return.CreateReadStream).todo; } - pub fn createWriteStream(this: *NodeFS, args: Arguments.CreateWriteStream, comptime flavor: Flavor) Maybe(Return.CreateWriteStream) { - _ = args; - _ = this; - _ = flavor; - var stream = bun.default_allocator.create(JSC.Node.Stream) catch unreachable; - stream.* = JSC.Node.Stream{ - .sink = .{ - .writable = JSC.Node.Writable{ - .stream = stream, - .globalObject = args.global_object, - }, - }, - .sink_type = .writable, - .content = undefined, - .content_type = undefined, - .allocator = bun.default_allocator, - }; - args.file.copyToStream(args.flags, args.autoClose, args.mode, bun.default_allocator, stream) catch unreachable; - args.copyToState(&stream.sink.writable.state); - return Maybe(Return.CreateWriteStream){ .result = stream }; + pub fn createWriteStream(_: *NodeFS, _: Arguments.CreateWriteStream, comptime _: Flavor) Maybe(Return.CreateWriteStream) { + return Maybe(Return.CreateWriteStream).todo; } }; diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 5fea3af8d..2e704037e 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -659,36 +659,6 @@ pub const PathOrFileDescriptor = union(Tag) { }; } - pub fn copyToStream(this: PathOrFileDescriptor, flags: FileSystemFlags, auto_close: bool, mode: Mode, allocator: std.mem.Allocator, stream: *Stream) !void { - switch (this) { - .fd => |fd| { - stream.content = Stream.Content{ - .file = .{ - .fd = fd, - .flags = flags, - .mode = mode, - }, - }; - stream.content_type = .file; - }, - .path => |path| { - stream.content = Stream.Content{ - .file_path = .{ - .path = PathString.init(std.mem.span(try allocator.dupeZ(u8, path.slice()))), - .auto_close = auto_close, - .file = .{ - .fd = std.math.maxInt(FileDescriptor), - .flags = flags, - .mode = mode, - }, - .opened = false, - }, - }; - stream.content_type = .file_path; - }, - } - } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?PathOrFileDescriptor { const first = arguments.next() orelse return null; @@ -1246,917 +1216,6 @@ pub const Emitter = struct { } }; -// pub fn Untag(comptime Union: type) type { -// const info: std.builtin.TypeInfo.Union = @typeInfo(Union); -// const tag = info.tag_type orelse @compileError("Must be tagged"); -// return struct { -// pub const Tag = tag; -// pub const Union = -// }; -// } - -pub const Stream = struct { - sink_type: Sink.Type, - sink: Sink, - content: Content, - content_type: Content.Type, - allocator: std.mem.Allocator, - - pub fn open(this: *Stream) ?JSC.Node.Syscall.Error { - switch (Syscall.open(this.content.file_path.path.sliceAssumeZ(), @enumToInt(this.content.file_path.file.flags))) { - .err => |err| { - return err.withPath(this.content.file_path.path.slice()); - }, - .result => |fd| { - this.content.file_path.file.fd = fd; - this.content.file_path.opened = true; - this.emit(.open); - return null; - }, - } - } - - pub fn getFd(this: *Stream) FileDescriptor { - return switch (this.content_type) { - .file => this.content.file.fd, - .file_path => if (comptime Environment.allow_assert) brk: { - std.debug.assert(this.content.file_path.opened); - break :brk this.content.file_path.file.fd; - } else this.content.file_path.file.fd, - else => unreachable, - }; - } - - pub fn close(this: *Stream) ?JSC.Node.Syscall.Error { - const fd = this.getFd(); - - // Don't ever close stdin, stdout, or stderr - // we are assuming that these are always 0 1 2, which is not strictly true in some cases - if (fd <= 2) { - return null; - } - - if (Syscall.close(fd)) |err| { - return err; - } - - switch (this.content_type) { - .file_path => { - this.content.file_path.opened = false; - this.content.file_path.file.fd = std.math.maxInt(FileDescriptor); - }, - .file => { - this.content.file.fd = std.math.maxInt(FileDescriptor); - }, - else => {}, - } - - this.emit(.Close); - } - - const CommonEvent = enum { Error, Open, Close }; - pub fn emit(this: *Stream, comptime event: CommonEvent) void { - switch (this.sink_type) { - .readable => { - switch (comptime event) { - .Open => this.sink.readable.emit(.Open), - .Close => this.sink.readable.emit(.Close), - else => unreachable, - } - }, - .writable => { - switch (comptime event) { - .Open => this.sink.writable.emit(.Open), - .Close => this.sink.writable.emit(.Close), - else => unreachable, - } - }, - } - } - - // This allocates a new stream object - pub fn toJS(this: *Stream, ctx: JSC.C.JSContextRef, _: JSC.C.ExceptionRef) JSC.C.JSValueRef { - switch (this.sink_type) { - .readable => { - var readable = &this.sink.readable.state; - return readable.create( - ctx.ptr(), - ).asObjectRef(); - }, - .writable => { - var writable = &this.sink.writable.state; - return writable.create( - ctx.ptr(), - ).asObjectRef(); - }, - } - } - - pub fn deinit(this: *Stream) void { - this.allocator.destroy(this); - } - - pub const Sink = union { - readable: Readable, - writable: Writable, - - pub const Type = enum(u8) { - readable, - writable, - }; - }; - - pub const Consumed = u52; - - const Response = struct { - bytes: [8]u8 = std.mem.zeroes([8]u8), - }; - - const Error = union(Type) { - Syscall: Syscall.Error, - JavaScript: JSC.JSValue, - Internal: anyerror, - - pub const Type = enum { - Syscall, - JavaScript, - Internal, - }; - }; - - pub const Content = union { - file: File, - file_path: FilePath, - socket: Socket, - buffer: *Buffer, - stream: *Stream, - javascript: JSC.JSValue, - - pub fn getFile(this: *Content, content_type: Content.Type) *File { - return switch (content_type) { - .file => &this.file, - .file_path => &this.file_path.file, - else => unreachable, - }; - } - - pub const File = struct { - fd: FileDescriptor, - flags: FileSystemFlags, - mode: Mode, - size: Consumed = std.math.maxInt(Consumed), - - // pub fn read(this: *File, comptime chunk_type: Content.Type, chunk: Source.Type.of(chunk_type)) Response {} - - pub inline fn setPermissions(this: File) meta.ReturnOf(Syscall.fchmod) { - return Syscall.fchmod(this.fd, this.mode); - } - }; - - pub const FilePath = struct { - path: PathString, - auto_close: bool = false, - file: File = File{ .fd = std.math.maxInt(FileDescriptor), .mode = 0o666, .flags = FileSystemFlags.@"r" }, - opened: bool = false, - - // pub fn read(this: *File, comptime chunk_type: Content.Type, chunk: Source.Type.of(chunk_type)) Response {} - }; - - pub const Socket = struct { - fd: FileDescriptor, - flags: FileSystemFlags, - - // pub fn write(this: *File, comptime chunk_type: Source.Type, chunk: Source.Type.of(chunk_type)) Response {} - // pub fn read(this: *File, comptime chunk_type: Source.Type, chunk: Source.Type.of(chunk_type)) Response {} - }; - - pub const Type = enum(u8) { - file, - file_path, - socket, - buffer, - stream, - javascript, - }; - }; -}; - -pub const Writable = struct { - state: State = State{}, - emitter: EventEmitter = EventEmitter{}, - - connection: ?*Stream = null, - globalObject: ?*JSC.JSGlobalObject = null, - - // workaround https://github.com/ziglang/zig/issues/6611 - stream: *Stream = undefined, - pipeline: Pipeline = Pipeline{}, - started: bool = false, - - pub const Chunk = struct { - data: StringOrBuffer, - encoding: Encoding = Encoding.utf8, - - pub fn init(allocator: std.mem.Allocator, size: u32) !Chunk { - var bytes = try allocator.alloc(u8, size); - return Chunk{ - .data = JSC.ArrayBuffer.fromBytes(bytes, JSC.JSValue.JSType.Uint8Array), - }; - } - }; - - pub const Pipe = struct { - source: *Stream, - destination: *Stream, - chunk: ?*Chunk = null, - // Might be the end of the stream - // or it might just be another stream - next: ?*Pipe = null, - - pub fn start(this: *Pipe, pipeline: *Pipeline, chunk: ?*Chunk) void { - this.run(pipeline, chunk, null); - } - - var disable_clonefile = false; - - fn runCloneFileWithFallback(pipeline: *Pipeline, source: *Stream.Content, destination: *Stream.Content) void { - switch (Syscall.clonefile(source.path.sliceAssumeZ(), destination.path.sliceAssumeZ())) { - .result => return, - .err => |err| { - switch (err.getErrno()) { - // these are retryable - .ENOTSUP, .EXDEV, .EXIST, .EIO, .ENOTDIR => |call| { - if (call == .ENOTSUP) { - disable_clonefile = true; - } - - return runCopyfile( - false, - pipeline, - source, - .file_path, - destination, - .file_path, - ); - }, - else => { - pipeline.err = err; - return; - }, - } - }, - } - } - - fn runCopyfile( - must_open_files: bool, - pipeline: *Pipeline, - source: *Stream.Content, - source_type: Stream.Content.Type, - destination: *Stream.Content, - destination_type: Stream.Content.Type, - is_end: bool, - ) void { - do_the_work: { - // fallback-only - if (destination_type == .file_path and source_type == .file_path and !destination.file_path.opened and !must_open_files) { - switch (Syscall.copyfile(source.path.sliceAssumeZ(), destination.path.sliceAssumeZ(), 0)) { - .err => |err| { - pipeline.err = err; - - return; - }, - .result => break :do_the_work, - } - } - - defer { - if (source_type == .file_path and source.file_path.auto_close and source.file_path.opened) { - if (source.stream.close()) |err| { - if (pipeline.err == null) { - pipeline.err = err; - } - } - } - - if (is_end and destination_type == .file_path and destination.file_path.auto_close and destination.file_path.opened) { - if (destination.stream.close()) |err| { - if (pipeline.err == null) { - pipeline.err = err; - } - } - } - } - - if (source_type == .file_path and !source.file_path.opened) { - if (source.stream.open()) |err| { - pipeline.err = err; - return; - } - } - - const source_fd = if (source_type == .file_path) - source.file_path.file.fd - else - source.file.fd; - - if (destination == .file_path and !destination.file_path.opened) { - if (destination.stream.open()) |err| { - pipeline.err = err; - return; - } - } - - const dest_fd = if (destination_type == .file_path) - destination.file_path.file.fd - else - destination.file.fd; - - switch (Syscall.fcopyfile(source_fd, dest_fd, 0)) { - .err => |err| { - pipeline.err = err; - return; - }, - .result => break :do_the_work, - } - } - - switch (destination.getFile(destination_type).setPermissions()) { - .err => |err| { - destination.stream.emitError(err); - pipeline.err = err; - return; - }, - .result => return, - } - } - - // fn runGeneric(this: *Pipe, pipeline: *Pipeline) !void { - // var source = this.source; - // var destination = this.destination; - // const source_content_type = source.content_type; - // const destination_content_type = destination.content_type; - - // if (this.chunk == null) { - // this.chunk = try this.source.allocator.create(Chunk); - // this.chunk.?.* = try Chunk.init(this.source.allocator, this.source.sink.readable.state.highwater_mark); - // } - - // source.readInto - // } - - pub fn run(this: *Pipe, pipeline: *Pipeline) void { - var source = this.source; - var destination = this.destination; - const source_content_type = source.content_type; - const destination_content_type = destination.content_type; - - if (pipeline.err != null) return; - - switch (FastPath.get( - source_content_type, - destination_content_type, - pipeline.head == this, - pipeline.tail == this, - )) { - .clonefile => { - if (comptime !Environment.isMac) unreachable; - if (destination.content.file_path.opened) { - runCopyfile( - // Can we skip sending a .open event? - (!source.content.file_path.auto_close and !source.content.file_path.opened) or (!destination.content.file_path.auto_close and !destination.content.file_path.opened), - pipeline, - &source.content, - .file_path, - &destination.content, - .file_path, - this.next == null, - ); - } else { - runCloneFileWithFallback(pipeline, source.content.file_path, destination.content.file_path); - } - }, - .copyfile => { - if (comptime !Environment.isMac) unreachable; - runCopyfile( - // Can we skip sending a .open event? - (!source.content.file_path.auto_close and !source.content.file_path.opened) or (!destination.content.file_path.auto_close and !destination.content.file_path.opened), - pipeline, - &source.content, - source_content_type, - &destination.content, - destination_content_type, - this.next == null, - ); - }, - else => {}, - } - } - - pub const FastPath = enum { - none, - clonefile, - sendfile, - copyfile, - copy_file_range, - - pub fn get(source: Stream.Content.Type, destination: Stream.Content.Type, is_head: bool, is_tail: bool) FastPath { - _ = is_tail; - if (comptime Environment.isMac) { - if (is_head) { - if (source == .file_path and destination == .file_path and !disable_clonefile) - return .clonefile; - - if ((source == .file or source == .file_path) and (destination == .file or destination == .file_path)) { - return .copyfile; - } - } - } - - return FastPath.none; - } - }; - }; - - pub const Pipeline = struct { - head: ?*Pipe = null, - tail: ?*Pipe = null, - - // Preallocate a single pipe so that - preallocated_tail_pipe: Pipe = undefined, - - /// Does the data exit at any point to JavaScript? - closed_loop: bool = true, - - // If there is a pending error, this is the error - err: ?Syscall.Error = null, - - pub const StartTask = struct { - writable: *Writable, - pub fn run(this: *StartTask) void { - var writable = this.writable; - var head = writable.pipeline.head orelse return; - if (writable.started) { - return; - } - writable.started = true; - - head.start(&writable.pipeline, null); - } - }; - }; - - pub fn appendReadable(this: *Writable, readable: *Stream) void { - if (comptime Environment.allow_assert) { - std.debug.assert(readable.sink_type == .readable); - } - - if (this.pipeline.tail == null) { - this.pipeline.head = &this.pipeline.preallocated_tail_pipe; - this.pipeline.head.?.* = Pipe{ - .destination = this.stream, - .source = readable, - }; - this.pipeline.tail = this.pipeline.head; - return; - } - - var pipe = readable.allocator.create(Pipe) catch unreachable; - pipe.* = Pipe{ - .source = readable, - .destination = this.stream, - }; - this.pipeline.tail.?.next = pipe; - this.pipeline.tail = pipe; - } - - pub const EventEmitter = Emitter.New(Events); - - pub fn emit(this: *Writable, event: Events, value: JSC.JSValue) void { - if (this.shouldSkipEvent(event)) return; - - this.emitter.emit(event, this.globalObject.?, value); - } - - pub inline fn shouldEmitEvent(this: *const Writable, event: Events) bool { - return switch (event) { - .Close => this.state.emit_close and this.emitter.listeners.get(.Close).list.len > 0, - .Drain => this.emitter.listeners.get(.Drain).list.len > 0, - .Error => this.emitter.listeners.get(.Error).list.len > 0, - .Finish => this.emitter.listeners.get(.Finish).list.len > 0, - .Pipe => this.emitter.listeners.get(.Pipe).list.len > 0, - .Unpipe => this.emitter.listeners.get(.Unpipe).list.len > 0, - .Open => this.emitter.listeners.get(.Open).list.len > 0, - }; - } - - pub const State = extern struct { - highwater_mark: u32 = 256_000, - encoding: Encoding = Encoding.utf8, - start: i32 = 0, - destroyed: bool = false, - ended: bool = false, - corked: bool = false, - finished: bool = false, - emit_close: bool = true, - - pub fn deinit(state: *State) callconv(.C) void { - if (comptime is_bindgen) return; - - var stream = state.getStream(); - stream.deinit(); - } - - pub fn create(state: *State, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue { - return shim.cppFn("create", .{ state, globalObject }); - } - - // i know. - pub inline fn getStream(state: *State) *Stream { - return getWritable(state).stream; - } - - pub inline fn getWritable(state: *State) *Writable { - return @fieldParentPtr(Writable, "state", state); - } - - pub fn addEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void { - if (comptime is_bindgen) return; - var writable = state.getWritable(); - writable.emitter.addListener(global.ref(), event, .{ - .once = is_once, - .callback = callback, - }) catch unreachable; - } - - pub fn removeEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue) callconv(.C) bool { - if (comptime is_bindgen) return true; - var writable = state.getWritable(); - return writable.emitter.removeListener(global.ref(), event, callback); - } - - pub fn prependEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void { - if (comptime is_bindgen) return; - var writable = state.getWritable(); - writable.emitter.prependListener(global.ref(), event, .{ - .once = is_once, - .callback = callback, - }) catch unreachable; - } - - pub fn write(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - pub fn end(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - pub fn close(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - pub fn destroy(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - pub fn cork(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - pub fn uncork(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub const Flowing = enum(u8) { - pending, - yes, - paused, - }; - - pub const shim = Shimmer("Bun", "Writable", @This()); - pub const name = "Bun__Writable"; - pub const include = "BunStream.h"; - pub const namespace = shim.namespace; - - pub const Export = shim.exportFunctions(.{ - .@"deinit" = deinit, - .@"addEventListener" = addEventListener, - .@"removeEventListener" = removeEventListener, - .@"prependEventListener" = prependEventListener, - .@"write" = write, - .@"end" = end, - .@"close" = close, - .@"destroy" = destroy, - .@"cork" = cork, - .@"uncork" = uncork, - }); - - pub const Extern = [_][]const u8{"create"}; - - comptime { - if (!is_bindgen) { - @export(deinit, .{ .name = Export[0].symbol_name }); - @export(addEventListener, .{ .name = Export[1].symbol_name }); - @export(removeEventListener, .{ .name = Export[2].symbol_name }); - @export(prependEventListener, .{ .name = Export[3].symbol_name }); - @export(write, .{ .name = Export[4].symbol_name }); - @export(end, .{ .name = Export[5].symbol_name }); - @export(close, .{ .name = Export[6].symbol_name }); - @export(destroy, .{ .name = Export[7].symbol_name }); - @export(cork, .{ .name = Export[8].symbol_name }); - @export(uncork, .{ .name = Export[9].symbol_name }); - } - } - }; - - pub const Events = enum(u8) { - Close, - Drain, - Error, - Finish, - Pipe, - Unpipe, - Open, - - pub const name = "WritableEvent"; - }; -}; - -pub const Readable = struct { - state: State = State{}, - emitter: EventEmitter = EventEmitter{}, - stream: *Stream = undefined, - destination: ?*Writable = null, - globalObject: ?*JSC.JSGlobalObject = null, - - pub const EventEmitter = Emitter.New(Events); - - pub fn emit(this: *Readable, event: Events, comptime ValueType: type, value: JSC.JSValue) void { - _ = ValueType; - if (this.shouldEmitEvent(event)) return; - - this.emitter.emit(event, this.globalObject.?, value); - } - - pub fn shouldEmitEvent(this: *Readable, event: Events) bool { - return switch (event) { - .Close => this.state.emit_close and this.emitter.listeners.get(.Close).list.len > 0, - .Data => this.emitter.listeners.get(.Data).list.len > 0, - .End => this.state.emit_end and this.emitter.listeners.get(.End).list.len > 0, - .Error => this.emitter.listeners.get(.Error).list.len > 0, - .Pause => this.emitter.listeners.get(.Pause).list.len > 0, - .Readable => this.emitter.listeners.get(.Readable).list.len > 0, - .Resume => this.emitter.listeners.get(.Resume).list.len > 0, - .Open => this.emitter.listeners.get(.Open).list.len > 0, - }; - } - - pub const Events = enum(u8) { - Close, - Data, - End, - Error, - Pause, - Readable, - Resume, - Open, - - pub const name = "ReadableEvent"; - }; - - // This struct is exposed to JavaScript - pub const State = extern struct { - highwater_mark: u32 = 256_000, - encoding: Encoding = Encoding.utf8, - - start: i32 = 0, - end: i32 = std.math.maxInt(i32), - - readable: bool = false, - aborted: bool = false, - did_read: bool = false, - ended: bool = false, - flowing: Flowing = Flowing.pending, - - emit_close: bool = true, - emit_end: bool = true, - - // i know. - pub inline fn getStream(state: *State) *Stream { - return getReadable(state).stream; - } - - pub inline fn getReadable(state: *State) *Readable { - return @fieldParentPtr(Readable, "state", state); - } - - pub const Flowing = enum(u8) { - pending, - yes, - paused, - }; - - pub const shim = Shimmer("Bun", "Readable", @This()); - pub const name = "Bun__Readable"; - pub const include = "BunStream.h"; - pub const namespace = shim.namespace; - - pub fn create( - state: *State, - globalObject: *JSC.JSGlobalObject, - ) callconv(.C) JSC.JSValue { - return shim.cppFn("create", .{ state, globalObject }); - } - - pub fn deinit(state: *State) callconv(.C) void { - if (comptime is_bindgen) return; - var stream = state.getStream(); - stream.deinit(); - } - - pub fn addEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void { - if (comptime is_bindgen) return; - var readable = state.getReadable(); - - readable.emitter.addListener(global.ref(), event, .{ - .once = is_once, - .callback = callback, - }) catch unreachable; - } - - pub fn removeEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue) callconv(.C) bool { - if (comptime is_bindgen) return true; - var readable = state.getReadable(); - return readable.emitter.removeListener(global.ref(), event, callback); - } - - pub fn prependEventListener(state: *State, global: *JSC.JSGlobalObject, event: Events, callback: JSC.JSValue, is_once: bool) callconv(.C) void { - if (comptime is_bindgen) return; - var readable = state.getReadable(); - readable.emitter.prependListener(global.ref(), event, .{ - .once = is_once, - .callback = callback, - }) catch unreachable; - } - - pub fn pipe(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - if (len < 1) { - return JSC.toInvalidArguments("Writable is required", .{}, global.ref()); - } - const args: []const JSC.JSValue = args_ptr[0..len]; - var writable_state: *Writable.State = args[0].getWritableStreamState(global.vm()) orelse { - return JSC.toInvalidArguments("Expected Writable but didn't receive it", .{}, global.ref()); - }; - writable_state.getWritable().appendReadable(state.getStream()); - return JSC.JSValue.jsUndefined(); - } - - pub fn unpipe(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub fn unshift(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub fn read(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub fn pause(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub fn @"resume"(state: *State, global: *JSC.JSGlobalObject, args_ptr: [*]const JSC.JSValue, len: u16) callconv(.C) JSC.JSValue { - if (comptime is_bindgen) return JSC.JSValue.jsUndefined(); - _ = state; - _ = global; - _ = args_ptr; - _ = len; - - return JSC.JSValue.jsUndefined(); - } - - pub const Export = shim.exportFunctions(.{ - .@"deinit" = deinit, - .@"addEventListener" = addEventListener, - .@"removeEventListener" = removeEventListener, - .@"prependEventListener" = prependEventListener, - .@"pipe" = pipe, - .@"unpipe" = unpipe, - .@"unshift" = unshift, - .@"read" = read, - .@"pause" = pause, - .@"resume" = State.@"resume", - }); - - pub const Extern = [_][]const u8{"create"}; - - comptime { - if (!is_bindgen) { - @export(deinit, .{ - .name = Export[0].symbol_name, - }); - @export(addEventListener, .{ - .name = Export[1].symbol_name, - }); - @export(removeEventListener, .{ - .name = Export[2].symbol_name, - }); - @export(prependEventListener, .{ - .name = Export[3].symbol_name, - }); - @export( - pipe, - .{ .name = Export[4].symbol_name }, - ); - @export( - unpipe, - .{ .name = Export[5].symbol_name }, - ); - @export( - unshift, - .{ .name = Export[6].symbol_name }, - ); - @export( - read, - .{ .name = Export[7].symbol_name }, - ); - @export( - pause, - .{ .name = Export[8].symbol_name }, - ); - @export( - State.@"resume", - .{ .name = Export[9].symbol_name }, - ); - } - } - }; -}; - pub const Path = struct { pub const shim = Shimmer("Bun", "Path", @This()); pub const name = "Bun__Path"; @@ -2694,10 +1753,5 @@ pub const Process = struct { comptime { std.testing.refAllDecls(Process); - std.testing.refAllDecls(Stream); - std.testing.refAllDecls(Readable); std.testing.refAllDecls(Path); - std.testing.refAllDecls(Writable); - std.testing.refAllDecls(Writable.State); - std.testing.refAllDecls(Readable.State); } |