UNPKG

@cloudflare/puppeteer

Version:

A high-level API to control headless Chrome over the DevTools Protocol

74 lines (65 loc) 2.23 kB
/** * @license * Copyright 2025 Google Inc. * SPDX-License-Identifier: Apache-2.0 */ const HEADER_SIZE = 4; // Uint32 const MAX_MESSAGE_SIZE = 1048575; // Workers size is < 1MB const FIRST_CHUNK_DATA_SIZE = MAX_MESSAGE_SIZE - HEADER_SIZE; export const messageToChunks = (data: string): Uint8Array[] => { const encoder = new TextEncoder(); const encodedUint8Array = encoder.encode(data); // We only include the header into the first chunk const firstChunk = new Uint8Array( Math.min(MAX_MESSAGE_SIZE, HEADER_SIZE + encodedUint8Array.length) ); const view = new DataView(firstChunk.buffer); view.setUint32(0, encodedUint8Array.length, true); firstChunk.set( encodedUint8Array.slice(0, FIRST_CHUNK_DATA_SIZE), HEADER_SIZE ); const chunks: Uint8Array[] = [firstChunk]; for (let i = FIRST_CHUNK_DATA_SIZE; i < data.length; i += MAX_MESSAGE_SIZE) { chunks.push(encodedUint8Array.slice(i, i + MAX_MESSAGE_SIZE)); } return chunks; }; export const chunksToMessage = ( chunks: Uint8Array[], sessionid: string ): string | null => { if (chunks.length === 0) { return null; } const emptyBuffer = new Uint8Array(0); const firstChunk = chunks[0] || emptyBuffer; const view = new DataView(firstChunk.buffer); const expectedBytes = view.getUint32(0, true); let totalBytes = -HEADER_SIZE; for (let i = 0; i < chunks.length; ++i) { const curChunk = chunks[i] || emptyBuffer; totalBytes += curChunk.length; if (totalBytes > expectedBytes) { throw new Error( `Should have gotten the exact number of bytes but we got more. SessionID: ${sessionid}` ); } if (totalBytes === expectedBytes) { const chunksToCombine = chunks.splice(0, i + 1); chunksToCombine[0] = firstChunk.subarray(HEADER_SIZE); const combined = new Uint8Array(expectedBytes); let offset = 0; for (let j = 0; j <= i; ++j) { const chunk = chunksToCombine[j] || emptyBuffer; combined.set(chunk, offset); offset += chunk.length; } const decoder = new TextDecoder(); // return decoder.decode(combined) const message = decoder.decode(combined); return message; } } return null; };