web-utility
Version:
Web front-end toolkit based on TypeScript
234 lines (166 loc) • 5.71 kB
Markdown
# Web utility
Web & [JavaScript runtimes][1] toolkit based on [TypeScript][2]
[][3]
[][4]
[][5]
[][6]
## Installation
```shell
npm install web-utility
```
### `index.html`
```html
<head>
<script src="https://polyfill.web-cell.dev/feature/ECMAScript.js"></script>
<script src="https://polyfill.web-cell.dev/feature/Regenerator.js"></script>
<script src="https://polyfill.web-cell.dev/feature/TextEncoder.js"></script>
<script src="https://polyfill.web-cell.dev/feature/URL.js"></script>
<script src="https://polyfill.web-cell.dev/feature/ScrollBehavior.js"></script>
<script src="https://polyfill.web-cell.dev/feature/IntersectionObserver.js"></script>
</head>
```
### `tsconfig.json`
```json
{
"compilerOptions": {
"module": "ES2021",
"moduleResolution": "Node",
"downlevelIteration": true,
"lib": ["ES2021", "DOM", "DOM.Iterable"]
}
}
```
## Usage
[API document](https://web-cell.dev/web-utility/)
### CSS Animation
1. [Watch Swipe](https://github.com/EasyWebApp/BootCell/blob/11c5d6f/source%2FMedia%2FCarousel.tsx#L200-L218)
2. [Simple Hover](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Prompt/Tooltip.tsx#L38-L43)
3. [Switch with `await`](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/TabList.tsx#L77-85)
4. [Toggle with Inline Styles](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/Collapse.tsx#L19-L38)
5. [Work with Existed Classes](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/Carousel.tsx#L82-L99)
### Function Cache
```typescript
import { cache } from 'web-utility';
const getToken = cache(async (cleaner, code) => {
const { access_token, expires_in } = await (
await fetch(`https://example.com/access_token?code=${code}`)
).json();
setTimeout(cleaner, expires_in * 1000);
return access_token;
}, 'Get Token');
Promise.all([getToken('xxx'), getToken('yyy')]).then(([first, second]) =>
console.assert(
first === second,
'Getting token for many times should return the same before deadline'
)
);
```
### DOM operation
```javascript
import { parseDOM, walkDOM, stringifyDOM } from 'web-utility';
const [root] = parseDOM('<a>Hello, <b>Web</b>!</a>');
var count = 0;
for (const { nodeName, nodeType, dataset } of walkDOM(root)) {
console.log(nodeName);
if (nodeType === Node.ELEMENT_NODE) dataset.id = ++count;
}
console.log(stringifyDOM(root)); // '<a data-id="1">Hello, <b data-id="2">Web</b>!</a>'
```
### jQuery-like DOM event delegation
```javascript
import { delegate } from 'web-utility';
document.addEventListener(
'click',
delegate('a[href]', (event, link) => {
event.preventDefault();
console.log(link.href);
})
);
```
### Message Channel
#### `index.ts`
```typescript
import { createMessageServer } from 'web-utility';
createMessageServer({
preset: () => ({ test: 1 })
});
```
#### `iframe.ts`
```typescript
import { createMessageClient } from 'web-utility';
const request = createMessageClient(globalThis.parent);
request('preset').then(console.log); // { test: 1 }
```
### Service Worker updating
```javascript
import { serviceWorkerUpdate } from 'web-utility';
const { serviceWorker } = window.navigator;
serviceWorker
?.register('/sw.js')
.then(serviceWorkerUpdate)
.then(worker => {
if (window.confirm('New version of this Web App detected, update now?'))
// Trigger the message callback listened in the Service Worker
// generated by Workbox CLI
worker.postMessage({ type: 'SKIP_WAITING' });
});
serviceWorker?.addEventListener('controllerchange', () =>
window.location.reload()
);
```
### Internationalization
Migrate to [MobX i18n][7] since v4.
### Test scripts
If you are looking for a simple alternative of [Mocha][8] or [Jest][9], just use these **Test Utility** methods with [`tsx`][10]:
```shell
npx tsx index.spec.ts
```
#### `index.spec.ts`
```typescript
import { describe, it } from 'web-utility';
class App {
name = 'test';
static create() {
return new App();
}
}
describe('My module', async () => {
const app = await it('should create an App object', async expect => {
const app = App.create();
expect(app instanceof App);
return app;
});
await it('should init an App name', expect => {
expect(app.name === 'test');
});
});
```
### CSV/TSV Parser
```typescript
import { FileHandle, open } from 'fs/promises';
import { readTextTable } from 'web-utility';
interface Article {
id: number;
title: string;
}
let fileHandle: FileHandle | undefined;
try {
fileHandle = await open('path/to/your-article.csv');
for await (const row of readTextTable<Article>(
fileHandle.createReadStream()
))
console.table(row);
} finally {
await fileHandle?.close();
}
```
[1]: https://min-common-api.proposal.wintertc.org/
[2]: https://www.typescriptlang.org/
[3]: https://libraries.io/npm/web-utility
[4]: https://github.com/EasyWebApp/web-utility/actions/workflows/main.yml
[5]: https://open.vscode.dev/EasyWebApp/web-utility
[6]: https://www.npmjs.com/package/web-utility
[7]: https://github.com/idea2app/MobX-i18n
[8]: https://mochajs.org/
[9]: https://jestjs.io/
[10]: https://tsx.is