Skip to content

Commit

Permalink
[fix] some Compatibility bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
TechQuery committed Sep 2, 2024
1 parent b473788 commit c0d1867
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 47 deletions.
1 change: 1 addition & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ npm install koajax
<script src="https://polyfill.web-cell.dev/feature/ECMAScript.js"></script>
<script src="https://polyfill.web-cell.dev/feature/TextEncoder.js"></script>
<script src="https://polyfill.web-cell.dev/feature/AbortController.js"></script>
<script src="https://polyfill.web-cell.dev/feature/Stream.js"></script>
</head>
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koajax",
"version": "2.1.0-rc.0",
"version": "3.0.0",
"license": "LGPL-3.0",
"author": "[email protected]",
"description": "HTTP Client based on Koa-like middlewares",
Expand Down
73 changes: 29 additions & 44 deletions source/HTTPRequest.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import 'core-js/es/object/from-entries';
import 'core-js/es/string/match-all';
import 'core-js/es/promise/with-resolvers';
import 'web-streams-polyfill/polyfill/es5';
import 'core-js/es/string/match-all';
import type { ReadableStream } from 'web-streams-polyfill';
import { parseJSON } from 'web-utility';

import {
parseDocument,
ProgressData,
readAs,
streamFromProgress
} from './utility';
import { parseDocument, ProgressData, streamFromProgress } from './utility';

export enum BodyRequestMethods {
POST = 'POST',
Expand Down Expand Up @@ -81,15 +76,15 @@ export const parseHeaders = (raw: string): Response['headers'] =>
)
);
export function parseBody<T>(raw: string, contentType: string): T {
if (contentType.includes('text')) return raw as T;

if (contentType.includes('json')) return parseJSON(raw);

if (contentType.match(/html|xml/))
try {
return parseDocument(raw, contentType) as T;
} catch {}

if (contentType.includes('text')) return raw as T;

return new TextEncoder().encode(raw).buffer as T;
}

Expand Down Expand Up @@ -201,46 +196,35 @@ export function requestFetch<B>({
body,
signal: signals[0] && AbortSignal.any(signals)
});
const stream1 = Promise.withResolvers<ReadableStream<Uint8Array>>(),
stream2 = Promise.withResolvers<ReadableStream<Uint8Array>>();

responsePromise
.then(response => {
const streams = response.body.tee();

stream1.resolve(streams[0]);
stream2.resolve(streams[1]);
})
.catch(reason => {
stream1.reject(reason);
stream2.reject(reason);
});

return {
response: parseResponse(responsePromise, stream1.promise, responseType),
download: iterateFetchBody(responsePromise, stream2.promise)
response: parseResponse(responsePromise, responseType),
download: iterateFetchBody(responsePromise)
};
}

export async function parseResponse<B>(
responsePromise: Promise<globalThis.Response>,
streamPromise: Promise<ReadableStream<Uint8Array>>,
responseType: Request['responseType']
): Promise<Response<B>> {
const response = await responsePromise;
const { status, statusText, headers } = response;
const { status, statusText, headers, body } = (
await responsePromise
).clone();

const contentType = headers.get('Content-Type') || '';

const header = parseHeaders(
[...headers].map(([key, value]) => `${key}: ${value}`).join('\n')
);
const stream = await streamPromise;
const body =
const rBody =
status === 204
? undefined
: await parseFetchBody<B>(stream, contentType, responseType);

return { status, statusText, headers: header, body };
: await parseFetchBody<B>(
body as ReadableStream<Uint8Array>,
contentType,
responseType
);
return { status, statusText, headers: header, body: rBody };
}

export async function parseFetchBody<B>(
Expand All @@ -258,21 +242,22 @@ export async function parseFetchBody<B>(

if (responseType === 'arraybuffer') return blob.arrayBuffer() as B;

const text = (await readAs(blob, 'text').result) as string;

return parseBody<B>(text, contentType);
return parseBody<B>(await blob.text(), contentType);
}

export async function* iterateFetchBody(
responsePromise: Promise<globalThis.Response>,
bodyPromise: Promise<ReadableStream<Uint8Array>>
responsePromise: Promise<globalThis.Response>
) {
const response = await responsePromise,
body = await bodyPromise;
const total = +response.headers.get('Content-Length');
const { headers, body } = (await responsePromise).clone();

for await (const { byteLength } of body)
yield { total, loaded: byteLength };
const total = +headers.get('Content-Length');
var loaded = 0;

for await (const { byteLength } of body as ReadableStream<Uint8Array>) {
loaded += byteLength;

yield { total, loaded };
}
}

export const request = <B>(options: Request): RequestResult<B> =>
Expand Down
2 changes: 1 addition & 1 deletion source/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export const streamFromProgress = <T extends ProgressEventTarget>(target: T) =>
};
}
);
enum FileMethod {
export enum FileMethod {
text = 'readAsText',
dataURL = 'readAsDataURL',
binaryString = 'readAsBinaryString',
Expand Down
15 changes: 14 additions & 1 deletion test/Request-Client.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { HTTPClient, request, requestFetch } from '../source';
import { Blob } from 'buffer';

import { HTTPClient, ProgressData, request, requestFetch } from '../source';
import { XMLHttpRequest } from './XMLHttpRequest';
// @ts-ignore
// https://github.com/jsdom/jsdom/issues/2555#issuecomment-1864762292
global.Blob = Blob;
// @ts-ignore
global.XMLHttpRequest = XMLHttpRequest;

describe('HTTP Request', () => {
Expand All @@ -9,6 +14,14 @@ describe('HTTP Request', () => {
path: 'https://api.github.com/users/TechQuery',
responseType: 'json'
});
expect(Symbol.asyncIterator in download).toBeTruthy();

var progress: ProgressData = { loaded: 0, total: 0 };

for await (const part of download) progress = part;

expect(progress.loaded).toBeGreaterThanOrEqual(progress.total);

const { body } = await response;

expect(body).toMatchObject({ login: 'TechQuery' });
Expand Down

0 comments on commit c0d1867

Please sign in to comment.