web-streams.cjs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use strict';
  2. const parseChunked = require('./parse-chunked.cjs');
  3. const stringifyChunked = require('./stringify-chunked.cjs');
  4. const utils = require('./utils.cjs');
  5. /* eslint-env browser */
  6. function parseFromWebStream(stream) {
  7. // 2024/6/17: currently, an @@asyncIterator on a ReadableStream is not widely supported,
  8. // therefore use a fallback using a reader
  9. // https://caniuse.com/mdn-api_readablestream_--asynciterator
  10. return parseChunked.parseChunked(utils.isIterable(stream) ? stream : async function*() {
  11. const reader = stream.getReader();
  12. try {
  13. while (true) {
  14. const { value, done } = await reader.read();
  15. if (done) {
  16. break;
  17. }
  18. yield value;
  19. }
  20. } finally {
  21. reader.releaseLock();
  22. }
  23. });
  24. }
  25. function createStringifyWebStream(value, replacer, space) {
  26. // 2024/6/17: the ReadableStream.from() static method is supported
  27. // in Node.js 20.6+ and Firefox only
  28. if (typeof ReadableStream.from === 'function') {
  29. return ReadableStream.from(stringifyChunked.stringifyChunked(value, replacer, space));
  30. }
  31. // emulate ReadableStream.from()
  32. return new ReadableStream({
  33. start() {
  34. this.generator = stringifyChunked.stringifyChunked(value, replacer, space);
  35. },
  36. pull(controller) {
  37. const { value, done } = this.generator.next();
  38. if (done) {
  39. controller.close();
  40. } else {
  41. controller.enqueue(value);
  42. }
  43. },
  44. cancel() {
  45. this.generator = null;
  46. }
  47. });
  48. }
  49. exports.createStringifyWebStream = createStringifyWebStream;
  50. exports.parseFromWebStream = parseFromWebStream;