{"id":18537930,"url":"https://github.com/easywebapp/web-utility","last_synced_at":"2025-04-09T17:37:11.009Z","repository":{"id":40454809,"uuid":"244638109","full_name":"EasyWebApp/web-utility","owner":"EasyWebApp","description":"Web front-end toolkit based on TypeScript","archived":false,"fork":false,"pushed_at":"2025-02-20T15:05:12.000Z","size":731,"stargazers_count":12,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T09:11:38.152Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://web-cell.dev/web-utility/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EasyWebApp.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://paypal.me/TechQuery","https://tech-query.me/image/TechQuery-Alipay.jpg"]}},"created_at":"2020-03-03T13:05:32.000Z","updated_at":"2025-02-20T15:04:32.000Z","dependencies_parsed_at":"2024-06-18T20:06:01.657Z","dependency_job_id":"54fb6f5d-a036-4c95-9fbd-7e24eba05768","html_url":"https://github.com/EasyWebApp/web-utility","commit_stats":{"total_commits":57,"total_committers":5,"mean_commits":11.4,"dds":"0.33333333333333337","last_synced_commit":"c3c27e50e70a4b0e9f5c1a8f426b7b3ae0794355"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EasyWebApp%2Fweb-utility","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EasyWebApp%2Fweb-utility/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EasyWebApp%2Fweb-utility/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EasyWebApp%2Fweb-utility/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EasyWebApp","download_url":"https://codeload.github.com/EasyWebApp/web-utility/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248078329,"owners_count":21044089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T19:41:18.626Z","updated_at":"2025-04-09T17:37:10.682Z","avatar_url":"https://github.com/EasyWebApp.png","language":"TypeScript","funding_links":["https://paypal.me/TechQuery","https://tech-query.me/image/TechQuery-Alipay.jpg"],"categories":[],"sub_categories":[],"readme":"# Web utility\n\n**Web front-end** toolkit based on [TypeScript][1]\n\n[![NPM Dependency](https://img.shields.io/librariesio/github/EasyWebApp/web-utility.svg)][2]\n[![CI \u0026 CD](https://github.com/EasyWebApp/web-utility/actions/workflows/main.yml/badge.svg)][3]\n\n[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)][4]\n\n[![NPM](https://nodei.co/npm/web-utility.png?downloads=true\u0026downloadRank=true\u0026stars=true)][5]\n\n## Installation\n\n```shell\nnpm install web-utility\n```\n\n### `index.html`\n\n```html\n\u003chead\u003e\n    \u003cscript src=\"https://polyfill.web-cell.dev/feature/Regenerator.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://polyfill.web-cell.dev/feature/TextEncoder.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://polyfill.web-cell.dev/feature/URL.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://polyfill.web-cell.dev/feature/ScrollBehavior.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://polyfill.web-cell.dev/feature/IntersectionObserver.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n```\n\n### `tsconfig.json`\n\n```json\n{\n    \"compilerOptions\": {\n        \"module\": \"ES2021\",\n        \"moduleResolution\": \"Node\",\n        \"downlevelIteration\": true,\n        \"lib\": [\"ES2021\", \"DOM\", \"DOM.Iterable\"]\n    }\n}\n```\n\n## Usage\n\n[API document](https://web-cell.dev/web-utility/)\n\n### CSS Animation\n\n1. [Watch Swipe](https://github.com/EasyWebApp/BootCell/blob/11c5d6f/source%2FMedia%2FCarousel.tsx#L200-L218)\n\n2. [Simple Hover](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Prompt/Tooltip.tsx#L38-L43)\n\n3. [Switch with `await`](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/TabList.tsx#L77-85)\n\n4. [Toggle with Inline Styles](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/Collapse.tsx#L19-L38)\n\n5. [Work with Existed Classes](https://github.com/EasyWebApp/BootCell/blob/a41bbc1/source/Content/Carousel.tsx#L82-L99)\n\n### Function Cache\n\n```typescript\nimport { cache } from 'web-utility';\n\nconst getToken = cache(async (cleaner, code) =\u003e {\n    const { access_token, expires_in } = await (\n        await fetch(`https://example.com/access_token?code=${code}`)\n    ).json();\n\n    setTimeout(cleaner, expires_in * 1000);\n\n    return access_token;\n}, 'Get Token');\n\nPromise.all([getToken('xxx'), getToken('yyy')]).then(([first, second]) =\u003e\n    console.assert(\n        first === second,\n        'Getting token for many times should return the same before deadline'\n    )\n);\n```\n\n### DOM operation\n\n```javascript\nimport { parseDOM, walkDOM, stringifyDOM } from 'web-utility';\n\nconst [root] = parseDOM('\u003ca\u003eHello, \u003cb\u003eWeb\u003c/b\u003e!\u003c/a\u003e');\n\nvar count = 0;\n\nfor (const { nodeName, nodeType, dataset } of walkDOM(root)) {\n    console.log(nodeName);\n\n    if (nodeType === Node.ELEMENT_NODE) dataset.id = ++count;\n}\n\nconsole.log(stringifyDOM(root)); // '\u003ca data-id=\"1\"\u003eHello, \u003cb data-id=\"2\"\u003eWeb\u003c/b\u003e!\u003c/a\u003e'\n```\n\n### jQuery-like DOM event delegation\n\n```javascript\nimport { delegate } from 'web-utility';\n\ndocument.addEventListener(\n    'click',\n    delegate('a[href]', (event, link) =\u003e {\n        event.preventDefault();\n\n        console.log(link.href);\n    })\n);\n```\n\n### Message Channel\n\n#### `index.ts`\n\n```typescript\nimport { createMessageServer } from 'web-utility';\n\ncreateMessageServer({\n    preset: () =\u003e ({ test: 1 })\n});\n```\n\n#### `iframe.ts`\n\n```typescript\nimport { createMessageClient } from 'web-utility';\n\nconst request = createMessageClient(globalThis.parent);\n\nrequest('preset').then(console.log); // { test: 1 }\n```\n\n### Service Worker updating\n\n```javascript\nimport { serviceWorkerUpdate } from 'web-utility';\n\nconst { serviceWorker } = window.navigator;\n\nserviceWorker\n    ?.register('/sw.js')\n    .then(serviceWorkerUpdate)\n    .then(worker =\u003e {\n        if (window.confirm('New version of this Web App detected, update now?'))\n            // Trigger the message callback listened in the Service Worker\n            // generated by Workbox CLI\n            worker.postMessage({ type: 'SKIP_WAITING' });\n    });\n\nserviceWorker?.addEventListener('controllerchange', () =\u003e\n    window.location.reload()\n);\n```\n\n### Internationalization\n\nMigrate to [MobX i18n][9] since v4.\n\n### Test scripts\n\nIf you are looking for a simple alternative of [Mocha][6] or [Jest][7], just use these **Test Utility** methods with [`ts-node`][8]:\n\n```shell\nnpx ts-node index.spec.ts\n```\n\n#### `index.spec.ts`\n\n```typescript\nimport { describe, it } from 'web-utility';\n\nclass App {\n    name = 'test';\n\n    static create() {\n        return new App();\n    }\n}\n\ndescribe('My module', async () =\u003e {\n    const app = await it('should create an App object', async expect =\u003e {\n        const app = App.create();\n\n        expect(app instanceof App);\n\n        return app;\n    });\n\n    await it('should init an App name', expect =\u003e {\n        expect(app.name === 'test');\n    });\n});\n```\n\n[1]: https://www.typescriptlang.org/\n[2]: https://libraries.io/npm/web-utility\n[3]: https://github.com/EasyWebApp/web-utility/actions/workflows/main.yml\n[4]: https://open.vscode.dev/EasyWebApp/web-utility\n[5]: https://nodei.co/npm/web-utility/\n[6]: https://mochajs.org/\n[7]: https://jestjs.io/\n[8]: https://typestrong.org/ts-node/\n[9]: https://github.com/idea2app/MobX-i18n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasywebapp%2Fweb-utility","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasywebapp%2Fweb-utility","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasywebapp%2Fweb-utility/lists"}