textiot
Version:
A framework for building web and native (IoT) Dapps on the IPFS network
127 lines (126 loc) • 4.44 kB
JavaScript
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);
}
});
};
;