@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
135 lines • 16.2 kB
JavaScript
import '@iotize/tap/service/impl/interface';
import { Buffer } from 'buffer';
import { Observable } from 'rxjs';
import { TAP_REQUEST_FRAME_HEADER_LENGTH } from '@iotize/tap/client/api';
export const DEFAULT_TAP_REQUEST_MAX_SIZE_OPTIONS = {
maxRequestByteSize: 180,
maxResponseByteSize: 200,
};
/**
* Compute tap request call size for a multi request
* @param chunk
* @returns
*/
export const computeMultiTapRequestCallSize = (chunk) => {
let bodyLength = computeBodyLength(chunk);
return (2 + // Request length
TAP_REQUEST_FRAME_HEADER_LENGTH + // GET /A/B/C
bodyLength +
1 // expected return code
);
};
/**
* @deprecated use computeMultiTapRequestCallSize instead
*/
export const computeTapRequestCallSize = computeMultiTapRequestCallSize;
export function createSingleChunkMultiTapRequestCalls(calls, index = 0, { maxResponseByteSize, maxRequestByteSize, } = DEFAULT_TAP_REQUEST_MAX_SIZE_OPTIONS) {
let totalResponseByteSize = 0;
let totalRequestByteSize = 0;
const chunck = [];
if (index >= calls.length) {
return {
calls: [],
nextIndex: undefined,
};
}
for (; index < calls.length; index++) {
const { call, responseBodySize } = calls[index];
const tapRequestByteSize = computeMultiTapRequestCallSize(call);
totalResponseByteSize += computeMultiTapResponseSize(responseBodySize);
totalRequestByteSize += tapRequestByteSize;
if (chunck.length > 0 &&
(totalResponseByteSize > maxResponseByteSize ||
totalRequestByteSize > maxRequestByteSize)) {
return {
calls: chunck,
nextIndex: index,
};
}
else {
chunck.push(call);
}
}
return {
nextIndex: undefined,
calls: chunck,
};
}
export function chunkMultiTapRequestCalls(calls, options = DEFAULT_TAP_REQUEST_MAX_SIZE_OPTIONS) {
let chuncks = [];
let nextIndex = 0;
while (nextIndex !== undefined) {
const nextChunk = createSingleChunkMultiTapRequestCalls(calls, nextIndex, options);
nextIndex = nextChunk.nextIndex;
chuncks.push(nextChunk.calls);
}
return chuncks;
}
export function createMultiTapRequestCallChuncksExecutor(tap, chunks) {
return new Observable((emitter) => {
let stop = false;
(async () => {
try {
for (let index = 0; index < chunks.length; index++) {
if (stop) {
return;
}
const chunck = chunks[index];
let responses;
if (chunck.length === 1) {
responses = [await tap.lwm2m.execute(chunck[0])];
}
else {
responses = await tap.service.interface.executeMultipleCalls(chunck);
}
emitter.next({
index,
responses,
});
}
emitter.complete();
}
catch (err) {
emitter.error(err);
}
})();
return () => {
stop = true;
};
});
}
function computeBodyLength(chunk) {
if (chunk.body !== undefined) {
if (chunk.body instanceof Uint8Array || chunk.body instanceof Buffer) {
return chunk.body.length;
}
else {
if (chunk.bodyEncoder) {
try {
const encoded = typeof chunk.bodyEncoder === 'function'
? chunk.bodyEncoder(chunk.body)
: chunk.bodyEncoder.encode(chunk.body);
return encoded.length;
}
catch (err) {
console.warn(`Filed to encode body to compute body length`, chunk, err);
return 0;
}
}
else {
console.warn(`Found body but no body encoder provider to this Tap request`, chunk);
return 0;
}
}
}
else {
return 0;
}
}
function computeMultiTapResponseSize(responseBodySize) {
return (responseBodySize +
2 + // multi_response_frame.response_len
1 // tap_response_frame.status;
);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktcmVxdWVzdHMtdXRpbGl0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL211bHRpLXJlcXVlc3RzL211bHRpLXJlcXVlc3RzLXV0aWxpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxvQ0FBb0MsQ0FBQztBQUc1QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFekUsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQUc7SUFDbEQsa0JBQWtCLEVBQUUsR0FBRztJQUN2QixtQkFBbUIsRUFBRSxHQUFHO0NBQ3pCLENBQUM7QUFPRjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsQ0FBQyxLQUFzQixFQUFFLEVBQUU7SUFDdkUsSUFBSSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUMsT0FBTyxDQUNMLENBQUMsR0FBRyxpQkFBaUI7UUFDckIsK0JBQStCLEdBQUcsYUFBYTtRQUMvQyxVQUFVO1FBQ1YsQ0FBQyxDQUFDLHVCQUF1QjtLQUMxQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyw4QkFBOEIsQ0FBQztBQUV4RSxNQUFNLFVBQVUscUNBQXFDLENBQ25ELEtBQTJELEVBQzNELFFBQWdCLENBQUMsRUFDakIsRUFDRSxtQkFBbUIsRUFDbkIsa0JBQWtCLE1BSWhCLG9DQUFvQztJQUV4QyxJQUFJLHFCQUFxQixHQUFHLENBQUMsQ0FBQztJQUM5QixJQUFJLG9CQUFvQixHQUFHLENBQUMsQ0FBQztJQUU3QixNQUFNLE1BQU0sR0FBc0IsRUFB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Q0FBQztJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0FBQ0gsQ0FBQztBQUNELFNBQVMsMkJBQTJCLENBQUMsZ0JBQXdCO0lBQzNELE9BQU8sQ0FDTCxnQkFBZ0I7UUFDaEIsQ0FBQyxHQUFHLG9DQUFvQztRQUN4QyxDQUFDLENBQUMsNkJBQTZCO0tBQ2hDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdAaW90aXplL3RhcC9zZXJ2aWNlL2ltcGwvaW50ZXJmYWNlJztcblxuaW1wb3J0IHsgU2VydmljZUNhbGxUeXBlLCBUYXAsIFRhcFJlc3BvbnNlIH0gZnJvbSAnQGlvdGl6ZS90YXAnO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRBUF9SRVFVRVNUX0ZSQU1FX0hFQURFUl9MRU5HVEggfSBmcm9tICdAaW90aXplL3RhcC9jbGllbnQvYXBpJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEFQX1JFUVVFU1RfTUFYX1NJWkVfT1BUSU9OUyA9IHtcbiAgbWF4UmVxdWVzdEJ5dGVTaXplOiAxODAsXG4gIG1heFJlc3BvbnNlQnl0ZVNpemU6IDIwMCxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgRml4ZWRSZXNwb25zZUJvZHlTaXplU2VydmljZUNhbGw8Qm9keVR5cGUsIFJldHVyblR5cGU+IHtcbiAgY2FsbDogU2VydmljZUNhbGxUeXBlPEJvZHlUeXBlLCBSZXR1cm5UeXBlPjtcbiAgcmVzcG9uc2VCb2R5U2l6ZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGFwIHJlcXVlc3QgY2FsbCBzaXplIGZvciBhIG11bHRpIHJlcXVlc3RcbiAqIEBwYXJhbSBjaHVua1xuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXB1dGVNdWx0aVRhcFJlcXVlc3RDYWxsU2l6ZSA9IChjaHVuazogU2VydmljZUNhbGxUeXBlKSA9PiB7XG4gIGxldCBib2R5TGVuZ3RoID0gY29tcHV0ZUJvZHlMZW5ndGgoY2h1bmspO1xuICByZXR1cm4gKFxuICAgIDIgKyAvLyBSZXF1ZXN0IGxlbmd0aFxuICAgIFRBUF9SRVFVRVNUX0ZSQU1FX0hFQURFUl9MRU5HVEggKyAvLyBHRVQgL0EvQi9DXG4gICAgYm9keUxlbmd0aCArXG4gICAgMSAvLyBleHBlY3RlZCByZXR1cm4gY29kZVxuICApO1xufTtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCB1c2UgY29tcHV0ZU11bHRpVGFwUmVxdWVzdENhbGxTaXplIGluc3RlYWRcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXB1dGVUYXBSZXF1ZXN0Q2FsbFNpemUgPSBjb21wdXRlTXVsdGlUYXBSZXF1ZXN0Q2FsbFNpemU7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTaW5nbGVDaHVua011bHRpVGFwUmVxdWVzdENhbGxzKFxuICBjYWxsczogRml4ZWRSZXNwb25zZUJvZHlTaXplU2VydmljZUNhbGw8dW5rbm93biwgdW5rbm93bj5bXSxcbiAgaW5kZXg6IG51bWJlciA9IDAsXG4gIHtcbiAgICBtYXhSZXNwb25zZUJ5dGVTaXplLFxuICAgIG1heFJlcXVlc3RCeXRlU2l6ZSxcbiAgfToge1xuICAgIG1heFJlc3BvbnNlQnl0ZVNpemU6IG51bWJlcjtcbiAgICBtYXhSZXF1ZXN0Qnl0ZVNpemU6IG51bWJlcjtcbiAgfSA9IERFRkFVTFRfVEFQX1JFUVVFU1RfTUFYX1NJWkVfT1BUSU9OU1xuKSB7XG4gIGxldCB0b3RhbFJlc3BvbnNlQnl0ZVNpemUgPSAwO1xuICBsZXQgdG90YWxSZXF1ZXN0Qnl0ZVNpemUgPSAwO1xuXG4gIGNvbnN0IGNodW5jazogU2VydmljZUNhbGxUeXBlW10gPSBbXTtcbiAgaWYgKGluZGV4ID49IGNhbGxzLmxlbmd0aCkge1xuICAgIHJldHVybiB7XG4gICAgICBjYWxsczogW10sXG4gICAgICBuZXh0SW5kZXg6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9XG4gIGZvciAoOyBpbmRleCA8IGNhbGxzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgIGNvbnN0IHsgY2FsbCwgcmVzcG9uc2VCb2R5U2l6ZSB9ID0gY2FsbHNbaW5kZXhdO1xuICAgIGNvbnN0IHRhcFJlcXVlc3RCeXRlU2l6ZSA9IGNvbXB1dGVNdWx0aVRhcFJlcXVlc3RDYWxsU2l6ZShjYWxsKTtcbiAgICB0b3RhbFJlc3BvbnNlQnl0ZVNpemUgKz0gY29tcHV0ZU11bHRpVGFwUmVzcG9uc2VTaXplKHJlc3BvbnNlQm9keVNpemUpO1xuICAgIHRvdGFsUmVxdWVzdEJ5dGVTaXplICs9IHRhcFJlcXVlc3RCeXRlU2l6ZTtcbiAgICBpZiAoXG4gICAgICBjaHVuY2subGVuZ3RoID4gMCAmJlxuICAgICAgKHRvdGFsUmVzcG9uc2VCeXRlU2l6ZSA+IG1heFJlc3BvbnNlQnl0ZVNpemUgfHxcbiAgICAgICAgdG90YWxSZXF1ZXN0Qnl0ZVNpemUgPiBtYXhSZXF1ZXN0Qnl0ZVNpemUpXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYWxsczogY2h1bmNrLFxuICAgICAgICBuZXh0SW5kZXg6IGluZGV4LFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2h1bmNrLnB1c2goY2FsbCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgbmV4dEluZGV4OiB1bmRlZmluZWQsXG4gICAgY2FsbHM6IGNodW5jayxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNodW5rTXVsdGlUYXBSZXF1ZXN0Q2FsbHMoXG4gIGNhbGxzOiBGaXhlZFJlc3BvbnNlQm9keVNpemVTZXJ2aWNlQ2FsbDx1bmtub3duLCB1bmtub3duPltdLFxuICBvcHRpb25zOiB7XG4gICAgbWF4UmVxdWVzdEJ5dGVTaXplOiBudW1iZXI7XG4gICAgbWF4UmVzcG9uc2VCeXRlU2l6ZTogbnVtYmVyO1xuICB9ID0gREVGQVVMVF9UQVBfUkVRVUVTVF9NQVhfU0laRV9PUFRJT05TXG4pOiBTZXJ2aWNlQ2FsbFR5cGVbXVtdIHtcbiAgbGV0IGNodW5ja3M6IFNlcnZpY2VDYWxsVHlwZVtdW10gPSBbXTtcbiAgbGV0IG5leHRJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkID0gMDtcbiAgd2hpbGUgKG5leHRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgbmV4dENodW5rID0gY3JlYXRlU2luZ2xlQ2h1bmtNdWx0aVRhcFJlcXVlc3RDYWxscyhcbiAgICAgIGNhbGxzLFxuICAgICAgbmV4dEluZGV4LFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gICAgbmV4dEluZGV4ID0gbmV4dENodW5rLm5leHRJbmRleDtcbiAgICBjaHVuY2tzLnB1c2gobmV4dENodW5rLmNhbGxzKTtcbiAgfVxuICByZXR1cm4gY2h1bmNrcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU11bHRpVGFwUmVxdWVzdENhbGxDaHVuY2tzRXhlY3V0b3IoXG4gIHRhcDogVGFwLFxuICBjaHVua3M6IFNlcnZpY2VDYWxsVHlwZVtdW11cbikge1xuICByZXR1cm4gbmV3IE9ic2VydmFibGU8eyBpbmRleDogbnVtYmVyOyByZXNwb25zZXM6IFRhcFJlc3BvbnNlPHVua25vd24+W10gfT4oXG4gICAgKGVtaXR0ZXIpID0+IHtcbiAgICAgIGxldCBzdG9wID0gZmFsc2U7XG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjaHVua3MubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBpZiAoc3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjaHVuY2sgPSBjaHVua3NbaW5kZXhdO1xuICAgICAgICAgICAgbGV0IHJlc3BvbnNlczogVGFwUmVzcG9uc2U8dW5rbm93bj5bXTtcbiAgICAgICAgICAgIGlmIChjaHVuY2subGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgIHJlc3BvbnNlcyA9IFthd2FpdCB0YXAubHdtMm0uZXhlY3V0ZShjaHVuY2tbMF0pXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc3BvbnNlcyA9IGF3YWl0IHRhcC5zZXJ2aWNlLmludGVyZmFjZS5leGVjdXRlTXVsdGlwbGVDYWxscyhcbiAgICAgICAgICAgICAgICBjaHVuY2tcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVtaXR0ZXIubmV4dCh7XG4gICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICByZXNwb25zZXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZW1pdHRlci5jb21wbGV0ZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBlbWl0dGVyLmVycm9yKGVycik7XG4gICAgICAgIH1cbiAgICAgIH0pKCk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBzdG9wID0gdHJ1ZTtcbiAgICAgIH07XG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQm9keUxlbmd0aChjaHVuazogU2VydmljZUNhbGxUeXBlPGFueSwgYW55Pik6IG51bWJlciB7XG4gIGlmIChjaHVuay5ib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoY2h1bmsuYm9keSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgfHwgY2h1bmsuYm9keSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGNodW5rLmJvZHkubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2h1bmsuYm9keUVuY29kZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBlbmNvZGVkID1cbiAgICAgICAgICAgIHR5cGVvZiBjaHVuay5ib2R5RW5jb2RlciA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICA/IGNodW5rLmJvZHlFbmNvZGVyKGNodW5rLmJvZHkpXG4gICAgICAgICAgICAgIDogY2h1bmsuYm9keUVuY29kZXIuZW5jb2RlKGNodW5rLmJvZHkpO1xuICAgICAgICAgIHJldHVybiBlbmNvZGVkLmxlbmd0aDtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYEZpbGVkIHRvIGVuY29kZSBib2R5IHRvIGNvbXB1dGUgYm9keSBsZW5ndGhgLFxuICAgICAgICAgICAgY2h1bmssXG4gICAgICAgICAgICBlcnJcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYEZvdW5kIGJvZHkgYnV0IG5vIGJvZHkgZW5jb2RlciBwcm92aWRlciB0byB0aGlzIFRhcCByZXF1ZXN0YCxcbiAgICAgICAgICBjaHVua1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVNdWx0aVRhcFJlc3BvbnNlU2l6ZShyZXNwb25zZUJvZHlTaXplOiBudW1iZXIpIHtcbiAgcmV0dXJuIChcbiAgICByZXNwb25zZUJvZHlTaXplICtcbiAgICAyICsgLy8gbXVsdGlfcmVzcG9uc2VfZnJhbWUucmVzcG9uc2VfbGVuXG4gICAgMSAvLyB0YXBfcmVzcG9uc2VfZnJhbWUuc3RhdHVzO1xuICApO1xufVxuIl19