How patrick-ring-motive/web-streams-shim works
1. What this repo is
- web-streams-shim is a JavaScript shim library that patches modern Web Streams / Fetch-related APIs when they exist but are incomplete.
- It is explicitly not a full polyfill for missing globals; the boundary is “extend existing runtime APIs,” not “create APIs from scratch.”
2. Primary runtime surface
- The main delivery artifact is web-streams-core.js, which is the script consumers load directly in browsers or via dynamic import.
- The package also ships .d.ts files for TypeScript consumers, so the public surface is both runtime behavior and typing augmentation.
3. Core architecture: feature-by-feature shims
- The codebase is organized as small, targeted modules rather than one monolithic patch layer.
- Each top-level file corresponds to a specific compatibility concern:
- ReadableStream-asyncIterator.js
- ReadableStream-from.js
- ReadableStreamBYOBReader.js
- ReadableStreamDefaultReader-constructor.js
- Record-body.js
- Record-bytes.js
- Record-duplex.js
- This suggests the architecture is “install only the missing pieces,” with each shim independently feature-detecting before applying changes.
4. ReadableStream subsystem
- One major subsystem is ReadableStream compatibility.
- It covers:
- async iteration support ([Symbol.asyncIterator] / values())
- ReadableStream.from(...)
- ReadableStreamDefaultReader constructor behavior
- BYOB reader-related support
- This subsystem is centered on making stream consumption patterns behave consistently across runtimes.
5. Fetch body subsystem
- Another subsystem patches body-related behavior for Request and Response.
- Files under Record-body.js and Record-bytes.js indicate consistent stream-backed body access and byte extraction.
- The architectural flow is from platform object (Request/Response) to normalized body access (body, bytes()), keeping body handling aligned across implementations.
6. Duplex compliance subsystem
- Record-duplex.js addresses the fetch “half-duplex” requirement when streaming request bodies are used.
- The README describes three places this is applied:
- property injection onto relevant prototypes
- constructor wrapping for Request and Response
- fetch wrapping to ensure options are normalized before execution
- This is the main “behavioral compatibility” layer because it alters call flow, not just surface APIs.
7. Extension layer
- The extensions/ directory is a second boundary: optional API/type extensions beyond the core shim.
- It includes:
- web-streams-extensions.js
- web-streams-extensions.d.ts
- type-extensions.js
- file.js
- location.js
- stream-record helpers
- This looks like a separate augmentation layer for environment-specific or convenience APIs, kept distinct from the core compatibility shims.
8. Type system boundary
- The presence of both .js and .d.ts files in the root and extensions/ shows the repo treats runtime patching and static typing as parallel concerns.
- web-streams-core.d.ts and extensions/web-streams-extensions.d.ts are likely used to make the global augmentations visible to TypeScript without changing runtime semantics.
9. Test architecture
- Tests live in test/test.html and test/test.js, which suggests browser-based integration testing rather than unit tests in a Node-only harness.
- That fits the repo’s purpose: verifying global API patching in a real web runtime where ReadableStream, fetch, Request, and Response behavior matters.
10. Distribution and release flow
- The GitHub Actions workflow .github/workflows/npm_publish.yml indicates automated package publishing to npm.
- This means the repo is packaged as a distributable library, with CI likely responsible for release integrity rather than deploying an app or service.
11. Operational model
- The library is fundamentally side-effect driven: load a script, detect missing behavior, patch globals, and leave native behavior untouched when already compliant.
- That makes the main dependency boundary the host runtime itself; the shim adapts to the environment instead of introducing its own app-level state.
12. How to draw the architecture
- A good diagram would show:
- host runtime globals on the left (ReadableStream, Request, Response, Blob, fetch)
- the shim package in the middle, split into feature modules
- optional extensions as a separate layer
- TypeScript declarations alongside runtime modules
- browser tests and npm publish as supporting delivery paths
- The key data flow is not request/response business logic, but API calls passing through patched constructors/methods and then delegating back to native implementations when possible.
Main entry points: web-streams-core.js Core entry · web-streams-extensions.js Extensions entry · Record-duplex.js Duplex record · Record-body.js Body record
Components 22
Host runtime
Existing platform APIs the shim patches and then delegates back to when compliant.
- ReadableStream · Stream primitives and consumption behavior provided by the host runtime.
- Request · Fetch request surface patched for body and duplex behavior.
- Response · Fetch response surface patched for body and byte access behavior.
- fetch · Network entrypoint wrapped to normalize duplex-related options.
Core shims
Primary compatibility modules loaded by the main runtime entrypoint.
- Core entry · Main script consumers load to install feature patches in the current runtime.
web-streams-core.js - Async iter · Adds async iteration and values() support to ReadableStream.
ReadableStream-asyncIterator.js - Stream from · Adds ReadableStream.from() support.
ReadableStream-from.js - BYOB reader · Adds or repairs BYOB reader behavior.
ReadableStreamBYOBReader.js - Default reader · Adjusts ReadableStreamDefaultReader constructor behavior.
ReadableStreamDefaultReader-constructor.js - Body record · Normalizes Request and Response body access.
Record-body.js - Bytes record · Adds consistent byte extraction behavior for body-backed objects.
Record-bytes.js - Duplex record · Implements half-duplex request handling and fetch option normalization.
Record-duplex.js
Extensions
Optional augmentations beyond the core compatibility surface.
- Extensions entry · Optional API and typing extensions separated from the core shims.
extensions/web-streams-extensions.js - Type extensions · Additional type/runtime extension support for optional APIs.
extensions/type-extensions.js - File helpers · Environment-specific file-related extension surface.
extensions/file.js - Location helpers · Environment-specific location-related extension surface.
extensions/location.js - Stream records · Helper modules for record/stream extension behavior.
extensions/Record-stream.js
Delivery
Type declarations, tests, and publishing automation.
- Core types · TypeScript declarations for the core runtime shim.
web-streams-core.d.ts - Ext types · TypeScript declarations for optional extensions.
extensions/web-streams-extensions.d.ts - Browser tests · Browser-based verification of global API patching.
test/test.html - Test script · Test harness executed in a browser runtime.
test/test.js - Publish CI · Automated npm publication workflow.
.github/workflows/npm_publish.yml
Connections 28
- Core entry → Async iter: loads · Main entry installs the feature-specific shim module.
- Core entry → Stream from: loads · Main entry installs the feature-specific shim module.
- Core entry → BYOB reader: loads · Main entry installs the feature-specific shim module.
- Core entry → Default reader: loads · Main entry installs the feature-specific shim module.
- Core entry → Body record: loads · Main entry installs the feature-specific shim module.
- Core entry → Bytes record: loads · Main entry installs the feature-specific shim module.
- Core entry → Duplex record: loads · Main entry installs the feature-specific shim module.
- Async iter → ReadableStream: patches · Extends ReadableStream with async iteration behavior.
- Stream from → ReadableStream: patches · Adds ReadableStream.from() to the host implementation.
- BYOB reader → ReadableStream: patches · Repairs BYOB reader-related stream behavior.
- Default reader → ReadableStream: patches · Adjusts default reader construction against host behavior.
- Body record → Request: patches · Normalizes body access on Request objects.
- Body record → Response: patches · Normalizes body access on Response objects.
- Bytes record → Request: patches · Adds consistent bytes extraction for Request bodies.
- Bytes record → Response: patches · Adds consistent bytes extraction for Response bodies.
- Duplex record → Request: wraps · Injects duplex-related request behavior.
- Duplex record → Response: wraps · Keeps response construction aligned with duplex handling.
- Duplex record → fetch: wraps · Normalizes fetch options before execution.
- Extensions entry → Type extensions: includes · Optional runtime extension package ships with its augmentation layer.
- Extensions entry → File helpers: includes · Optional runtime extension package ships file helpers.
- Extensions entry → Location helpers: includes · Optional runtime extension package ships location helpers.
- Extensions entry → Stream records: includes · Optional runtime extension package ships stream record helpers.
- Core types → Core entry: types · Type declarations mirror the core runtime surface.
- Ext types → Extensions entry: types · Type declarations mirror the optional extension surface.
- Browser tests → Test script: loads · Browser test page executes the test harness.
- Test script → Core entry: verifies · Tests exercise the main shim entrypoint in a real browser runtime.
- Publish CI → Core entry: packages · Release workflow publishes the distributable core artifact.
- Publish CI → Extensions entry: packages · Release workflow packages optional extensions as part of the release.