Last active
February 3, 2026 07:42
-
-
Save tripolskypetr/72ff5790828100ba377144c381e27905 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Subject, singleshot, randomString } from "functools-kit"; | |
| declare global { | |
| interface Window { | |
| onFetchApiResponse: (requestId: string, text: string) => void; | |
| AndroidBinding: { | |
| beginFetchApi: (requestId: string, url: string, totalChunks: number) => void; | |
| sendFetchApiChunk: (requestId: string, chunkIndex: number, chunk: string) => void; | |
| endFetchApi: (requestId: string, contentLength: number) => void; | |
| }; | |
| } | |
| } | |
| const CHUNK_SIZE = 500; | |
| const requestWrapper = new class { | |
| _responseSubject = new Subject<[string, string]>(); | |
| _listenForAnswer = singleshot(() => { | |
| window.onFetchApiResponse = (requestId: string, text: string) => { | |
| this._responseSubject.next([requestId, text]); | |
| } | |
| }) | |
| _sendChunked = (requestId: string, path: string, body: string) => { | |
| const totalChunks = Math.ceil(body.length / CHUNK_SIZE); | |
| const contentLength = new Blob([body]).size; | |
| window.AndroidBinding.beginFetchApi(requestId, path, totalChunks); | |
| for (let i = 0; i < totalChunks; i++) { | |
| const chunk = body.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE); | |
| window.AndroidBinding.sendFetchApiChunk(requestId, i, chunk); | |
| } | |
| window.AndroidBinding.endFetchApi(requestId, contentLength); | |
| } | |
| send = async (path: string, body: string) => { | |
| if (window.AndroidBinding?.beginFetchApi) { | |
| const requestId = randomString(); | |
| this._listenForAnswer(); | |
| this._sendChunked(requestId, path, body); | |
| const response = await this._responseSubject | |
| .filter(([id]) => id === requestId) | |
| .map(([, text]) => text) | |
| .toPromise(); | |
| return JSON.parse(response); | |
| } | |
| const response = await fetch(path, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body, | |
| }); | |
| return await response.json(); | |
| } | |
| } | |
| // Использование | |
| const payload = { foo: "bar", data: "..." }; | |
| const body = JSON.stringify(payload); | |
| const result = await requestWrapper.send("/api/endpoint", body); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment