UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

135 lines 16.2 kB
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