123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- import {EventEmitter} from 'node:events'
- import {compile} from './lib/compile.js'
- import {parse} from './lib/parse.js'
- import {postprocess} from './lib/postprocess.js'
- import {preprocess} from './lib/preprocess.js'
- export function stream(options) {
- const prep = preprocess()
- const tokenize = parse(options).document().write
- const comp = compile(options)
-
- let ended
-
-
- const emitter = Object.assign(new EventEmitter(), {
- end,
- pipe,
- readable: true,
- writable: true,
- write
- })
- return emitter
-
- function write(chunk, encoding, callback) {
- if (typeof encoding === 'function') {
- callback = encoding
- encoding = undefined
- }
- if (ended) {
- throw new Error('Did not expect `write` after `end`')
- }
- tokenize(prep(chunk || '', encoding))
- if (callback) {
- callback()
- }
-
- return true
- }
-
- function end(chunk, encoding, callback) {
- if (typeof chunk === 'function') {
- encoding = chunk
- chunk = undefined
- }
- if (typeof encoding === 'function') {
- callback = encoding
- encoding = undefined
- }
- write(chunk, encoding, callback)
- emitter.emit('data', comp(postprocess(tokenize(prep('', encoding, true)))))
- emitter.emit('end')
- ended = true
- return true
- }
-
- function pipe(dest, options) {
- emitter.on('data', ondata)
- emitter.on('error', onerror)
- emitter.on('end', cleanup)
- emitter.on('close', cleanup)
-
-
-
- if (!dest._isStdio && (!options || options.end !== false)) {
- emitter.on('end', onend)
- }
- dest.on('error', onerror)
- dest.on('close', cleanup)
- dest.emit('pipe', emitter)
- return dest
-
- function onend() {
- if (dest.end) {
- dest.end()
- }
- }
-
- function ondata(chunk) {
- if (dest.writable) {
- dest.write(chunk)
- }
- }
-
- function cleanup() {
- emitter.removeListener('data', ondata)
- emitter.removeListener('end', onend)
- emitter.removeListener('error', onerror)
- emitter.removeListener('end', cleanup)
- emitter.removeListener('close', cleanup)
- dest.removeListener('error', onerror)
- dest.removeListener('close', cleanup)
- }
-
- function onerror(error) {
- cleanup()
- if (!emitter.listenerCount('error')) {
- throw error
- }
- }
- }
- }
|