# web-streams-polyfill Web Streams, based on the WHATWG spec reference implementation. [![build status](https://api.travis-ci.com/MattiasBuelens/web-streams-polyfill.svg?branch=master)](https://travis-ci.com/MattiasBuelens/web-streams-polyfill) [![npm version](https://img.shields.io/npm/v/web-streams-polyfill.svg)](https://www.npmjs.com/package/web-streams-polyfill) [![license](https://img.shields.io/npm/l/web-streams-polyfill.svg)](https://github.com/MattiasBuelens/web-streams-polyfill/blob/master/LICENSE) [![Join the chat at https://gitter.im/web-streams-polyfill/Lobby](https://badges.gitter.im/web-streams-polyfill/Lobby.svg)](https://gitter.im/web-streams-polyfill/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Links - [Official spec][spec] - [Reference implementation][ref-impl] ## Usage This library comes in multiple variants: * `web-streams-polyfill`: a polyfill that replaces the native stream implementations. Recommended for use in web apps supporting older browsers through a ` ``` Usage as a Node module: ```js var streams = require("web-streams-polyfill/ponyfill"); var readable = new streams.ReadableStream(); ``` Usage as a ES2015 module: ```js import { ReadableStream } from "web-streams-polyfill/ponyfill"; const readable = new ReadableStream(); ``` ### Compatibility The `polyfill` and `ponyfill` variants work in any ES5-compatible environment that has a global `Promise`. If you need to support older browsers or Node versions that do not have a native `Promise` implementation (check the [support table][promise-support]), you must first include a `Promise` polyfill (e.g. [promise-polyfill][promise-polyfill]). The `polyfill/es6` and `ponyfill/es6` variants work in any ES2015-compatible environment. The `polyfill/es2018` and `ponyfill/es2018` variants work in any ES2018-compatible environment. [Async iterable support for `ReadableStream`][rs-asynciterator] is available in all variants, but requires an ES2018-compatible environment or a polyfill for `Symbol.asyncIterator`. [`WritableStreamDefaultController.signal`][ws-controller-signal] is available in all variants, but requires a global `AbortController` constructor. If necessary, consider using a polyfill such as [abortcontroller-polyfill]. ### Compliance The polyfill implements [version `4b6b93c` (25 Oct 2021)][spec-snapshot] of the streams specification. The polyfill is tested against the same [web platform tests][wpt] that are used by browsers to test their native implementations. The polyfill aims to pass all tests, although it allows some exceptions for practical reasons: * The `es2018` variant passes all of the tests, except for the ["bad buffers and views" tests for readable byte streams][wpt-bad-buffers]. These tests require the implementation to synchronously transfer the contents of an `ArrayBuffer`, which is not yet possible from JavaScript (although there is a [proposal][proposal-arraybuffer-transfer] to make it possible). The reference implementation "cheats" on these tests [by making a copy instead][ref-impl-transferarraybuffer], but that is unacceptable for the polyfill's performance ([#3][issue-3]). * The `es6` variant passes the same tests as the `es2018` variant, except for the [test for the prototype of `ReadableStream`'s async iterator][wpt-async-iterator-prototype]. Retrieving the correct `%AsyncIteratorPrototype%` requires using an async generator (`async function* () {}`), which is invalid syntax before ES2018. Instead, the polyfill [creates its own version][stub-async-iterator-prototype] which is functionally equivalent to the real prototype. * The `es5` variant passes the same tests as the `es6` variant, except for various tests about specific characteristics of the constructors, properties and methods. These test failures do not affect the run-time behavior of the polyfill. For example: * The `name` property of down-leveled constructors is incorrect. * The `length` property of down-leveled constructors and methods with optional arguments is incorrect. * Not all properties and methods are correctly marked as non-enumerable. * Down-leveled class methods are not correctly marked as non-constructable. The type definitions are compatible with the built-in stream types of TypeScript 3.3. ### Contributors Thanks to these people for their work on [the original polyfill][creatorrr-polyfill]: - Diwank Singh Tomer ([creatorrr](https://github.com/creatorrr)) - Anders Riutta ([ariutta](https://github.com/ariutta)) [spec]: https://streams.spec.whatwg.org [ref-impl]: https://github.com/whatwg/streams [ponyfill]: https://github.com/sindresorhus/ponyfill [promise-support]: https://kangax.github.io/compat-table/es6/#test-Promise [promise-polyfill]: https://www.npmjs.com/package/promise-polyfill [rs-asynciterator]: https://streams.spec.whatwg.org/#rs-asynciterator [ws-controller-signal]: https://streams.spec.whatwg.org/#ws-default-controller-signal [abortcontroller-polyfill]: https://www.npmjs.com/package/abortcontroller-polyfill [spec-snapshot]: https://streams.spec.whatwg.org/commit-snapshots/4b6b93c69e531e2fe45a6ed4cb1484a7ba4eb8bb/ [wpt]: https://github.com/web-platform-tests/wpt/tree/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams [wpt-bad-buffers]: https://github.com/web-platform-tests/wpt/blob/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams/readable-byte-streams/bad-buffers-and-views.any.js [proposal-arraybuffer-transfer]: https://github.com/domenic/proposal-arraybuffer-transfer [ref-impl-transferarraybuffer]: https://github.com/whatwg/streams/blob/4b6b93c69e531e2fe45a6ed4cb1484a7ba4eb8bb/reference-implementation/lib/abstract-ops/ecmascript.js#L16 [issue-3]: https://github.com/MattiasBuelens/web-streams-polyfill/issues/3 [wpt-async-iterator-prototype]: https://github.com/web-platform-tests/wpt/blob/96ca25f0f7526282c0d47e6bf6a7edd439da1968/streams/readable-streams/async-iterator.any.js#L24 [stub-async-iterator-prototype]: https://github.com/MattiasBuelens/web-streams-polyfill/blob/v2.0.0/src/target/es5/stub/async-iterator-prototype.ts [creatorrr-polyfill]: https://github.com/creatorrr/web-streams-polyfill