KoAJAX

KoAJAX

HTTP Client based on Koa-like middlewares

NPM Dependency CI & CD

NPM

Feature

Request Body

Automatic Serialized types:

  1. Pure text: string
  2. Form encoding: URLSearchParams, FormData
  3. DOM object: Node
  4. JSON object: Object
  5. Binary data: Blob, ArrayBuffer, TypedArray, DataView
  6. Stream object: ReadableStream

Response Body

Automatic Parsed type:

  1. HTML/XML: Document
  2. JSON: Object
  3. Binary data: ArrayBuffer

Usage

Browser

npm install koajax

index.html

<head>
<script src="https://polyfill.web-cell.dev/feature/Regenerator.js"></script>
<script src="https://polyfill.web-cell.dev/feature/ECMAScript.js"></script>
<script src="https://polyfill.web-cell.dev/feature/TextEncoder.js"></script>
</head>

Node.js

npm install koajax jsdom

index.js

import { HTTPClient } from 'koajax';
import { polyfill } from 'koajax/source/polyfill'

const origin = 'https://your-target-origin.com';

polyfill(origin).then(() => {
const client = new HTTPClient({
baseURI: `${origin}/api`,
responseType: 'json'
});
const { body } = await client.get('test/interface');

console.log(body);
});

Example

RESTful API with Token-based Authorization

import { HTTPClient } from 'koajax';

var token = '';

export const client = new HTTPClient().use(
async ({ request: { method, path, headers }, response }, next) => {
if (token) headers['Authorization'] = 'token ' + token;

await next();

if (method === 'POST' && path.startsWith('/session'))
token = response.headers.Token;
}
);

client.get('/path/to/your/API').then(console.log);

Up/Download files

Single HTTP request based on XMLHTTPRequest progress events

(based on Iterable Observer)

import { request } from 'koajax';

document.querySelector('input[type="file"]').onchange = async ({
target: { files }
}) => {
for (const file of files) {
const { upload, download, response } = request({
method: 'POST',
path: '/files',
body: file,
responseType: 'json'
});

for await (const { loaded } of upload)
console.log(`Upload ${file.name} : ${(loaded / file.size) * 100}%`);

const { body } = await response;

console.log(`Upload ${file.name} : ${body.url}`);
}
};

Multiple HTTP requests based on Range header

npm i native-file-system-adapter  # Web standard API polyfill
import { showSaveFilePicker } from 'native-file-system-adapter';
import { HTTPClient } from 'koajax';

const bufferClient = new HTTPClient({ responseType: 'arraybuffer' });

document.querySelector('#download').onclick = async () => {
const fileURL = 'https://your.server/with/Range/header/supported/file.zip';
const suggestedName = fileURL.split('/').at(-1);

const fileHandle = await showSaveFilePicker({ suggestedName });
const writer = await fileHandle.createWritable(),
stream = bufferClient.download();

for await (const { total, loaded, percent, buffer } of stream) {
writer.write(buffer);

console.table({ total, loaded, percent });
}
write.close();
window.alert(`File ${fileHandle.name} downloaded successfully!`);
};

Global Error fallback

npm install browser-unhandled-rejection  # Web standard API polyfill
import { auto } from 'browser-unhandled-rejection';
import { HTTPError } from 'koajax';

auto();

self.addEventListener('unhandledrejection', event => {
if (!(event.reason instanceof URIError)) return;

const { message } = (event.reason as HTTPError).body;

if (!message) return;

event.preventDefault();

self.alert(message);
});

Read Files

(based on Iterable Observer)

import { readAs } from 'koajax';

document.querySelector('input[type="file"]').onchange = async ({
target: { files }
}) => {
for (const file of files) {
const { progress, result } = readAs(file, 'dataURL');

for await (const { loaded } of progress)
console.log(
`Loading ${file.name} : ${(loaded / file.size) * 100}%`
);

const URI = await result;

console.log(`Loaded ${file.name} : ${URI}`);
}
};

Generated using TypeDoc