UNPKG

textiot

Version:

A framework for building web and native (IoT) Dapps on the IPFS network

127 lines (126 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.streamHandler = exports.readableWebToNode = exports.NodeReadable = exports.readableNodeToWeb = void 0; const stream_1 = require("stream"); const ponyfill_1 = require("web-streams-polyfill/ponyfill"); // polyfill TextDecoder to be backward compatible with older // nodejs that doesn't expose TextDecoder as a global variable if (typeof TextDecoder === 'undefined' && typeof require !== 'undefined') { global.TextDecoder = require('util').TextDecoder; } // https://github.com/gwicke/node-web-streams exports.readableNodeToWeb = (nodeStream) => { if (!(nodeStream instanceof stream_1.Readable)) { return nodeStream; } return new ponyfill_1.ReadableStream({ start(controller) { nodeStream.pause(); nodeStream.on('data', (chunk) => { controller.enqueue(chunk); nodeStream.pause(); }); nodeStream.on('end', () => controller.close()); nodeStream.on('error', (e) => controller.error(e)); }, pull(_controller) { nodeStream.resume(); }, cancel(_reason) { nodeStream.pause(); } }); }; class NodeReadable extends stream_1.Readable { constructor(webStream, options) { super(options); this._webStream = webStream; this._reader = webStream.getReader(); this._reading = false; } _read(size) { if (this._reading) { return; } this._reading = true; const doRead = (size) => { this._reader.read() .then((res) => { if (res.done) { // tslint:disable-next-line:no-null-keyword this.push(null); return; } if (this.push(res.value)) { return doRead(size); } else { this._reading = false; } }); }; doRead(size); } } exports.NodeReadable = NodeReadable; exports.readableWebToNode = (webStream) => { return new NodeReadable(webStream); }; // https://github.com/canjs/can-ndjson-stream exports.streamHandler = (response) => { // For cancellation let isReader; let cancellationRequest = false; return new ponyfill_1.ReadableStream({ start(controller) { const reader = exports.readableNodeToWeb(response).getReader(); isReader = reader; const decoder = new TextDecoder(); let dataBuffer = ''; const processResult = (result) => { if (result.done) { if (cancellationRequest) { return; // Immediately exit } dataBuffer = dataBuffer.trim(); if (dataBuffer.length !== 0) { try { const dataLine = JSON.parse(dataBuffer); controller.enqueue(dataLine); } catch (e) { controller.error(e); return; } } controller.close(); return; } const data = decoder.decode(result.value, { stream: true }); dataBuffer += data; const lines = dataBuffer.split('\n'); for (const line of lines) { const l = line.trim(); if (l.length > 0) { try { controller.enqueue(JSON.parse(l)); } catch (e) { controller.error(e); cancellationRequest = true; reader.cancel(undefined); return; } } } dataBuffer = lines.length > 1 ? lines[lines.length - 1] : ''; reader.read().then(processResult); }; reader.read().then(processResult); }, cancel(reason) { cancellationRequest = true; isReader.cancel(reason); } }); };