Add CompressionStream and DecompressionStream Web APIs

Implements the missing CompressionStream and DecompressionStream Web APIs to support libraries like @zip.js/zip.js@2.8.8 that require these APIs.

The implementation uses Node.js zlib streams as the backing implementation and wraps them in TransformStream-based APIs following the same pattern as TextEncoderStream.

Changes:
- Add src/js/builtins/CompressionStream.ts and DecompressionStream.ts with builtin implementations
- Add C++ bindings (JSCompressionStream.* and JSDecompressionStream.*)
- Register classes in ZigGlobalObject, DOMIsoSubspaces, DOMClientIsoSubspaces, and DOMConstructors
- Add private field symbols to BunBuiltinNames.h

Supports "deflate", "deflate-raw", and "gzip" compression formats as per the Compression Streams API spec.

Fixes #24161

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Bot
2025-10-28 19:54:25 +00:00
parent eb77bdd286
commit f197b4e59d
12 changed files with 668 additions and 0 deletions

View File

@@ -126,6 +126,8 @@
#include "JSTextEncoder.h"
#include "JSTextEncoderStream.h"
#include "JSTextDecoderStream.h"
#include "JSCompressionStream.h"
#include "JSDecompressionStream.h"
#include "JSTransformStream.h"
#include "JSTransformStreamDefaultController.h"
#include "JSURLSearchParams.h"
@@ -993,6 +995,8 @@ WEBCORE_GENERATED_CONSTRUCTOR_GETTER(SubtleCrypto);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextEncoder);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextEncoderStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextDecoderStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(CompressionStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(DecompressionStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStream)
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStreamDefaultController)
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(URLSearchParams);

View File

@@ -79,6 +79,8 @@
TextDecoderStream TextDecoderStreamConstructorCallback PropertyCallback
TextEncoder TextEncoderConstructorCallback PropertyCallback
TextEncoderStream TextEncoderStreamConstructorCallback PropertyCallback
CompressionStream CompressionStreamConstructorCallback PropertyCallback
DecompressionStream DecompressionStreamConstructorCallback PropertyCallback
TransformStream TransformStreamConstructorCallback PropertyCallback
TransformStreamDefaultController TransformStreamDefaultControllerConstructorCallback PropertyCallback
URL DOMURLConstructorCallback DontEnum|PropertyCallback

View File

@@ -509,6 +509,8 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoder;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoderStream;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoderStreamEncoder;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCompressionStream;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDecompressionStream;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTransitionEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTreeWalker;

View File

@@ -435,6 +435,8 @@ enum class DOMConstructorID : uint16_t {
TextEncoder,
TextEncoderStream,
TextEncoderStreamEncoder,
CompressionStream,
DecompressionStream,
TextEvent,
TransitionEvent,
TreeWalker,

View File

@@ -494,6 +494,8 @@ public:
std::unique_ptr<IsoSubspace> m_subspaceForTextEncoder;
std::unique_ptr<IsoSubspace> m_subspaceForTextEncoderStream;
// std::unique_ptr<IsoSubspace> m_subspaceForTextEncoderStreamEncoder;
std::unique_ptr<IsoSubspace> m_subspaceForCompressionStream;
std::unique_ptr<IsoSubspace> m_subspaceForDecompressionStream;
// std::unique_ptr<IsoSubspace> m_subspaceForTextEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForTransitionEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForTreeWalker;

View File

@@ -0,0 +1,168 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSCompressionStream.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMBuiltinConstructor.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMWrapperCache.h"
// #include "CompressionStreamBuiltins.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
namespace WebCore {
using namespace JSC;
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsCompressionStreamConstructor);
class JSCompressionStreamPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSCompressionStreamPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSCompressionStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSCompressionStreamPrototype>(vm)) JSCompressionStreamPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCompressionStreamPrototype, Base);
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());
}
private:
JSCompressionStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCompressionStreamPrototype, JSCompressionStreamPrototype::Base);
using JSCompressionStreamDOMConstructor = JSDOMBuiltinConstructor<JSCompressionStream>;
template<> const ClassInfo JSCompressionStreamDOMConstructor::s_info = { "CompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCompressionStreamDOMConstructor) };
template<> JSValue JSCompressionStreamDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSCompressionStreamDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "CompressionStream"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSCompressionStream::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
template<> FunctionExecutable* JSCompressionStreamDOMConstructor::initializeExecutable(VM& vm)
{
return compressionStreamInitializeCompressionStreamCodeGenerator(vm);
}
/* Hash table for prototype */
static const HashTableValue JSCompressionStreamPrototypeTableValues[] = {
{ "constructor"_s, static_cast<unsigned>(PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsCompressionStreamConstructor, 0 } },
{ "readable"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinAccessorType, compressionStreamReadableCodeGenerator, 0 } },
{ "writable"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinAccessorType, compressionStreamWritableCodeGenerator, 0 } },
};
const ClassInfo JSCompressionStreamPrototype::s_info = { "CompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCompressionStreamPrototype) };
void JSCompressionStreamPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSCompressionStream::info(), JSCompressionStreamPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSCompressionStream::s_info = { "CompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCompressionStream) };
JSCompressionStream::JSCompressionStream(Structure* structure, JSDOMGlobalObject& globalObject)
: JSDOMObject(structure, globalObject)
{
}
JSObject* JSCompressionStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
auto* structure = JSCompressionStreamPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype());
structure->setMayBePrototype(true);
return JSCompressionStreamPrototype::create(vm, &globalObject, structure);
}
JSObject* JSCompressionStream::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSCompressionStream>(vm, globalObject);
}
JSValue JSCompressionStream::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSCompressionStreamDOMConstructor, DOMConstructorID::CompressionStream>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSCompressionStream::destroy(JSC::JSCell* cell)
{
JSCompressionStream* thisObject = static_cast<JSCompressionStream*>(cell);
thisObject->JSCompressionStream::~JSCompressionStream();
}
JSC_DEFINE_CUSTOM_GETTER(jsCompressionStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSCompressionStreamPrototype*>(JSValue::decode(thisValue));
if (!prototype) [[unlikely]]
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSCompressionStream::getConstructor(vm, prototype->globalObject()));
}
JSC::GCClient::IsoSubspace* JSCompressionStream::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSCompressionStream, UseCustomHeapCellType::No>(
vm, [](auto& spaces) { return spaces.m_clientSubspaceForCompressionStream.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCompressionStream = std::forward<decltype(space)>(space); }, [](auto& spaces) { return spaces.m_subspaceForCompressionStream.get(); }, [](auto& spaces, auto&& space) { spaces.m_subspaceForCompressionStream = std::forward<decltype(space)>(space); });
}
}

View File

@@ -0,0 +1,64 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMWrapper.h"
namespace WebCore {
class JSCompressionStream : public JSDOMObject {
public:
using Base = JSDOMObject;
static JSCompressionStream* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
JSCompressionStream* ptr = new (NotNull, JSC::allocateCell<JSCompressionStream>(vm)) JSCompressionStream(structure, *globalObject);
ptr->finishCreation(vm);
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
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(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
protected:
JSCompressionStream(JSC::Structure*, JSDOMGlobalObject&);
DECLARE_DEFAULT_FINISH_CREATION;
};
} // namespace WebCore

View File

@@ -0,0 +1,168 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSDecompressionStream.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMBuiltinConstructor.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMWrapperCache.h"
// #include "DecompressionStreamBuiltins.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
namespace WebCore {
using namespace JSC;
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsDecompressionStreamConstructor);
class JSDecompressionStreamPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSDecompressionStreamPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSDecompressionStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSDecompressionStreamPrototype>(vm)) JSDecompressionStreamPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDecompressionStreamPrototype, Base);
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());
}
private:
JSDecompressionStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDecompressionStreamPrototype, JSDecompressionStreamPrototype::Base);
using JSDecompressionStreamDOMConstructor = JSDOMBuiltinConstructor<JSDecompressionStream>;
template<> const ClassInfo JSDecompressionStreamDOMConstructor::s_info = { "DecompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDecompressionStreamDOMConstructor) };
template<> JSValue JSDecompressionStreamDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSDecompressionStreamDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "DecompressionStream"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSDecompressionStream::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
template<> FunctionExecutable* JSDecompressionStreamDOMConstructor::initializeExecutable(VM& vm)
{
return decompressionStreamInitializeDecompressionStreamCodeGenerator(vm);
}
/* Hash table for prototype */
static const HashTableValue JSDecompressionStreamPrototypeTableValues[] = {
{ "constructor"_s, static_cast<unsigned>(PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsDecompressionStreamConstructor, 0 } },
{ "readable"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinAccessorType, decompressionStreamReadableCodeGenerator, 0 } },
{ "writable"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinAccessorType, decompressionStreamWritableCodeGenerator, 0 } },
};
const ClassInfo JSDecompressionStreamPrototype::s_info = { "DecompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDecompressionStreamPrototype) };
void JSDecompressionStreamPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSDecompressionStream::info(), JSDecompressionStreamPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSDecompressionStream::s_info = { "DecompressionStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDecompressionStream) };
JSDecompressionStream::JSDecompressionStream(Structure* structure, JSDOMGlobalObject& globalObject)
: JSDOMObject(structure, globalObject)
{
}
JSObject* JSDecompressionStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
auto* structure = JSDecompressionStreamPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype());
structure->setMayBePrototype(true);
return JSDecompressionStreamPrototype::create(vm, &globalObject, structure);
}
JSObject* JSDecompressionStream::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSDecompressionStream>(vm, globalObject);
}
JSValue JSDecompressionStream::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSDecompressionStreamDOMConstructor, DOMConstructorID::DecompressionStream>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSDecompressionStream::destroy(JSC::JSCell* cell)
{
JSDecompressionStream* thisObject = static_cast<JSDecompressionStream*>(cell);
thisObject->JSDecompressionStream::~JSDecompressionStream();
}
JSC_DEFINE_CUSTOM_GETTER(jsDecompressionStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSDecompressionStreamPrototype*>(JSValue::decode(thisValue));
if (!prototype) [[unlikely]]
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSDecompressionStream::getConstructor(vm, prototype->globalObject()));
}
JSC::GCClient::IsoSubspace* JSDecompressionStream::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSDecompressionStream, UseCustomHeapCellType::No>(
vm, [](auto& spaces) { return spaces.m_clientSubspaceForDecompressionStream.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForDecompressionStream = std::forward<decltype(space)>(space); }, [](auto& spaces) { return spaces.m_subspaceForDecompressionStream.get(); }, [](auto& spaces, auto&& space) { spaces.m_subspaceForDecompressionStream = std::forward<decltype(space)>(space); });
}
}

View File

@@ -0,0 +1,64 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMWrapper.h"
namespace WebCore {
class JSDecompressionStream : public JSDOMObject {
public:
using Base = JSDOMObject;
static JSDecompressionStream* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
JSDecompressionStream* ptr = new (NotNull, JSC::allocateCell<JSDecompressionStream>(vm)) JSDecompressionStream(structure, *globalObject);
ptr->finishCreation(vm);
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
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(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
protected:
JSDecompressionStream(JSC::Structure*, JSDOMGlobalObject&);
DECLARE_DEFAULT_FINISH_CREATION;
};
} // namespace WebCore

View File

@@ -258,6 +258,10 @@ using namespace JSC;
macro(textDecoderStreamTransform) \
macro(textEncoderStreamEncoder) \
macro(textEncoderStreamTransform) \
macro(compressionStreamTransform) \
macro(compressionStreamCompressor) \
macro(decompressionStreamTransform) \
macro(decompressionStreamDecompressor) \
macro(toClass) \
macro(toNamespacedPath) \
macro(trace) \

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2025 Anthropic PBC. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
export function initializeCompressionStream(format) {
// Validate format
if (format !== "deflate" && format !== "deflate-raw" && format !== "gzip") {
throw new TypeError(`The provided value '${format}' is not a valid enum value of type CompressionFormat.`);
}
const zlib = require("node:zlib");
let compressor;
// Create the appropriate compressor based on the format
if (format === "deflate") {
compressor = zlib.createDeflate();
} else if (format === "deflate-raw") {
compressor = zlib.createDeflateRaw();
} else if (format === "gzip") {
compressor = zlib.createGzip();
}
const startAlgorithm = () => {
return Promise.$resolve();
};
const transformAlgorithm = chunk => {
return new Promise((resolve, reject) => {
compressor.write(chunk, err => {
if (err) reject(err);
else resolve();
});
});
};
const flushAlgorithm = () => {
return new Promise((resolve, reject) => {
compressor.end(err => {
if (err) reject(err);
else resolve();
});
});
};
const transform = $createTransformStream(startAlgorithm, transformAlgorithm, flushAlgorithm);
$putByIdDirectPrivate(this, "compressionStreamTransform", transform);
$putByIdDirectPrivate(this, "compressionStreamCompressor", compressor);
// Set up event handlers to pipe compressed data through the transform stream
compressor.on("data", chunk => {
const transformStream = $getByIdDirectPrivate(this, "compressionStreamTransform");
const controller = $getByIdDirectPrivate(transformStream, "controller");
$transformStreamDefaultControllerEnqueue(controller, chunk);
});
return this;
}
$getter;
export function readable() {
const transform = $getByIdDirectPrivate(this, "compressionStreamTransform");
if (!transform) throw $ERR_INVALID_THIS("CompressionStream");
return $getByIdDirectPrivate(transform, "readable");
}
$getter;
export function writable() {
const transform = $getByIdDirectPrivate(this, "compressionStreamTransform");
if (!transform) throw $ERR_INVALID_THIS("CompressionStream");
return $getByIdDirectPrivate(transform, "writable");
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2025 Anthropic PBC. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
export function initializeDecompressionStream(format) {
// Validate format
if (format !== "deflate" && format !== "deflate-raw" && format !== "gzip") {
throw new TypeError(`The provided value '${format}' is not a valid enum value of type CompressionFormat.`);
}
const zlib = require("node:zlib");
let decompressor;
// Create the appropriate decompressor based on the format
if (format === "deflate") {
decompressor = zlib.createInflate();
} else if (format === "deflate-raw") {
decompressor = zlib.createInflateRaw();
} else if (format === "gzip") {
decompressor = zlib.createGunzip();
}
const startAlgorithm = () => {
return Promise.$resolve();
};
const transformAlgorithm = chunk => {
return new Promise((resolve, reject) => {
decompressor.write(chunk, err => {
if (err) reject(err);
else resolve();
});
});
};
const flushAlgorithm = () => {
return new Promise((resolve, reject) => {
decompressor.end(err => {
if (err) reject(err);
else resolve();
});
});
};
const transform = $createTransformStream(startAlgorithm, transformAlgorithm, flushAlgorithm);
$putByIdDirectPrivate(this, "decompressionStreamTransform", transform);
$putByIdDirectPrivate(this, "decompressionStreamDecompressor", decompressor);
// Set up event handlers to pipe decompressed data through the transform stream
decompressor.on("data", chunk => {
const transformStream = $getByIdDirectPrivate(this, "decompressionStreamTransform");
const controller = $getByIdDirectPrivate(transformStream, "controller");
$transformStreamDefaultControllerEnqueue(controller, chunk);
});
return this;
}
$getter;
export function readable() {
const transform = $getByIdDirectPrivate(this, "decompressionStreamTransform");
if (!transform) throw $ERR_INVALID_THIS("DecompressionStream");
return $getByIdDirectPrivate(transform, "readable");
}
$getter;
export function writable() {
const transform = $getByIdDirectPrivate(this, "decompressionStreamTransform");
if (!transform) throw $ERR_INVALID_THIS("DecompressionStream");
return $getByIdDirectPrivate(transform, "writable");
}