diff --git a/packages/gguf/src/gguf.ts b/packages/gguf/src/gguf.ts index 784a8adb7..6e1527bd6 100644 --- a/packages/gguf/src/gguf.ts +++ b/packages/gguf/src/gguf.ts @@ -51,8 +51,11 @@ const HTTP_TOTAL_MAX_SIZE = 50 * 10 ** 6; /// 50MB class RangeView { private chunk: number; private buffer: ArrayBuffer; + private dataView: DataView; - readonly view: DataView; + get view(): DataView { + return this.dataView; + } constructor( public url: string, @@ -68,7 +71,7 @@ class RangeView { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.buffer = new ArrayBuffer(0, { maxByteLength: HTTP_TOTAL_MAX_SIZE }); - this.view = new DataView(this.buffer); + this.dataView = new DataView(this.buffer); } /** * Fetch a new chunk from the server @@ -84,18 +87,40 @@ class RangeView { }) ).arrayBuffer() ); + this.appendBuffer(buf); + this.chunk += 1; + } + /** + * Append new data into the buffer + */ + appendBuffer(buf: Uint8Array) { /// TODO(fix typing) // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - this.buffer.resize((this.chunk + 1) * HTTP_CHUNK_SIZE); - new Uint8Array(this.buffer).set(buf, this.chunk * HTTP_CHUNK_SIZE); - this.chunk += 1; + if (ArrayBuffer.prototype.resize) { + /// TODO(fix typing) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this.buffer.resize((this.chunk + 1) * HTTP_CHUNK_SIZE); + new Uint8Array(this.buffer).set(buf, this.chunk * HTTP_CHUNK_SIZE); + } else { + // If the browser does not support ArrayBuffer.resize, we fallback to this polyfill version + /// TODO(fix typing) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const newBuffer = new ArrayBuffer((this.chunk + 1) * HTTP_CHUNK_SIZE, { maxByteLength: HTTP_TOTAL_MAX_SIZE }); + const arrView = new Uint8Array(newBuffer); + arrView.set(new Uint8Array(this.buffer)); + arrView.set(buf, this.chunk * HTTP_CHUNK_SIZE); + this.buffer = newBuffer; + this.dataView = new DataView(this.buffer); + } } /** * Check whether we need to fetch a new chunk */ async fetchChunkIfNeeded(offset: number) { - if (this.view.byteLength - offset < HTTP_DATA_LEEWAY) { + if (this.dataView.byteLength - offset < HTTP_DATA_LEEWAY) { await this.fetchChunk(); } }