parse-sax.js 1.2 KB

123456789101112131415161718192021222324252627282930
  1. const {SaxesParser} = require('saxes');
  2. const {PassThrough} = require('readable-stream');
  3. const {bufferToString} = require('./browser-buffer-decode');
  4. module.exports = async function* (iterable) {
  5. // TODO: Remove once node v8 is deprecated
  6. // Detect and upgrade old streams
  7. if (iterable.pipe && !iterable[Symbol.asyncIterator]) {
  8. iterable = iterable.pipe(new PassThrough());
  9. }
  10. const saxesParser = new SaxesParser();
  11. let error;
  12. saxesParser.on('error', err => {
  13. error = err;
  14. });
  15. let events = [];
  16. saxesParser.on('opentag', value => events.push({eventType: 'opentag', value}));
  17. saxesParser.on('text', value => events.push({eventType: 'text', value}));
  18. saxesParser.on('closetag', value => events.push({eventType: 'closetag', value}));
  19. for await (const chunk of iterable) {
  20. saxesParser.write(bufferToString(chunk));
  21. // saxesParser.write and saxesParser.on() are synchronous,
  22. // so we can only reach the below line once all events have been emitted
  23. if (error) throw error;
  24. // As a performance optimization, we gather all events instead of passing
  25. // them one by one, which would cause each event to go through the event queue
  26. yield events;
  27. events = [];
  28. }
  29. };