{"id":13695680,"url":"https://github.com/sdgluck/fetch-background-sync","last_synced_at":"2025-09-04T09:08:30.528Z","repository":{"id":57234725,"uuid":"52563169","full_name":"sdgluck/fetch-background-sync","owner":"sdgluck","description":":v: Proxy fetch requests through the Background Sync API","archived":false,"fork":false,"pushed_at":"2017-07-30T13:29:28.000Z","size":404,"stargazers_count":127,"open_issues_count":1,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-29T00:45:51.441Z","etag":null,"topics":["background-sync","service-workers"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sdgluck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-25T23:03:53.000Z","updated_at":"2025-07-28T09:00:43.000Z","dependencies_parsed_at":"2022-09-15T06:50:42.824Z","dependency_job_id":null,"html_url":"https://github.com/sdgluck/fetch-background-sync","commit_stats":null,"previous_names":["sdgluck/fetch-sync"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sdgluck/fetch-background-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdgluck%2Ffetch-background-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdgluck%2Ffetch-background-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdgluck%2Ffetch-background-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdgluck%2Ffetch-background-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sdgluck","download_url":"https://codeload.github.com/sdgluck/fetch-background-sync/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdgluck%2Ffetch-background-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273581225,"owners_count":25131393,"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","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["background-sync","service-workers"],"created_at":"2024-08-02T18:00:32.250Z","updated_at":"2025-09-04T09:08:30.471Z","avatar_url":"https://github.com/sdgluck.png","language":"JavaScript","funding_links":[],"categories":["Tools","JavaScript"],"sub_categories":[],"readme":"# fetch-sync\n\n\u003e Proxy fetch requests through the [Background Sync API](https://github.com/WICG/BackgroundSync/blob/master/explainer.md)\n\nMade with ❤ at [@outlandish](http://www.twitter.com/outlandish)\n\n\u003ca href=\"http://badge.fury.io/js/fetch-sync\"\u003e\u003cimg alt=\"npm version\" src=\"https://badge.fury.io/js/fetch-sync.svg\"\u003e\u003c/a\u003e\n[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n\nFetch Sync allows you to proxy fetch requests through the Background Sync API so that they are\nhonoured if made when the UA is offline! Hooray!\n\nCheck out a [live demo here](https://sdgluck.github.io/fetch-sync/).\n\n- Make requests offline that will be sent when the UA regains connectivity (even if the web page is no longer open).\n- Responses are forwarded back to the client as soon as they are received.\n- Implements a familiar fetch-like API: similar function signature and the same return type (a Response).\n- Make named requests that have their response stored in an IDBStore which you can collect in subsequent user sessions.\n- Manage sync operations with `fetchSync.{get,getAll,cancel,cancelAll}()`.\n- Can be used with existing Service Worker infrastructures with `importScripts`, or handles SW registration for you.\n- If the browser does not support Background Sync, the library will fall back on normal `fetch` requests.\n\n## Install\n\n```sh\nnpm install fetch-sync --save\n```\n\n## Table of Contents\n\n- [Requirements](#requirements)\n- [Support](#support)\n- __[Import](#import)__\n- __[Initialise](#initialise)__\n- __[Usage](#usage)__\n- __[Sync API](#sync-api)__\n- [Dependencies](#dependencies)\n- [Test](#test)\n- [Development](#development)\n- [Contributing](#contributing)\n- [Author \u0026 License](author--license)\n\n## Requirements\n\nThe library utilises some new technologies so currently only works in some browsers. It definitely works in\n[Chrome Canary](https://www.google.co.uk/chrome/browser/canary.html)\nwith the `experimental-web-platform-features` flag enabled.\n\nThe browser must support:\n\n- [Background Sync](https://github.com/WICG/BackgroundSync/blob/master/explainer.md)\n- [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)\n- [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n- [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)\n- [Promise] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n## Support\n\nChrome Canary | Chrome | Firefox | IE | Opera | Safari\n:------------:|:------:|:-------:|:--:|:-----:|:-----:\n✔             |✔      |✘       |✘   |✘     |✘\n\n## Import\n\n__Client__\n\n```js\n// ES6\nimport fetchSync from 'fetch-sync'\n```\n\n```js\n// CommonJS\nvar fetchSync = require('fetch-sync')\n```\n\n```html\n\u003c!-- Script, using minified dist --\u003e\n\u003cscript src=\"/node_modules/fetch-sync/dist/fetch-sync.min.js\"\u003e\u003c/script\u003e\n```\n\n__Worker__\n\nSee [Initialise](#initialise) for details on importing and registering the service worker.\n\n## Initialise\n\n__Existing Service Worker__\n\nIf your application already uses a Service Worker, you can import the fetch-sync worker using `importScripts`:\n\n```js\nimportScripts('node_modules/fetch-sync/dist/fetch-sync.sw.min.js')\n```\n\nAnd then call `fetchSync.init()` somewhere in your application's initialisation procedure.\n\n__No Service Worker__\n\nfetch-sync can handle registration if you don't use a SW already...\n\nEither serve the fetch-sync worker file with a header `\"Service-Worker-Allowed : /\"`, or to avoid configuring headers,\ncreate a Service Worker script in the root of your project and use the method above for 'Existing Service Worker'.\n\nThen see the example under [Usage](#usage) for the `fetchSync.init()` method.\n\n## Usage\n\n### `fetchSync.init([options]) : Promise`\n\nInitialise fetchSync.\n\n- __options__ {Object} _(optional)_ options object\n\nLook at the documentation for [`sw-register`](https://github.com/sdgluck/sw-register)\navailable options and for more details on Service Worker registration.\n\nExample:\n\n```js\n// Import client lib...\n\n// ES6\nimport fetchSync from 'fetch-sync'\n\n// ES5\nvar fetchSync = require('fetch-sync')\n```\n\n```html\n\u003c!-- Script, using bundled dist --\u003e\n\u003cscript src=\"/node_modules/fetch-sync/dist/fetch-sync.min.js\"\u003e\u003c/script\u003e\n```\n\n```js\n// Initialise, passing in worker lib location...\n\nfetchSync.init({\n  url: 'node_modules/fetch-sync/dist/fetch-sync.sw.js',\n  scope: '\u003cwebsite address\u003e' // e.g. 'http://localhost:8000'\n})\n```\n\n### `fetchSync([name, ]request[, options]) : Sync`\n\nPerform a [`sync`](https://github.com/WICG/BackgroundSync/blob/master/explainer.md#one-off-synchronization) Background Sync operation.\n\n- [__name__] {String} _(optional)_ name of the sync operation\n- __request__ {String|Request} URL or an instance of fetch Request\n- [__options__] {Object} _(optional)_ [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch) object\n\nReturns a Promise that resolves on success of the fetch request. Rejects if a sync exists with this name already.\n\nThere are also some properties/methods on the Promise. See the [Sync API](#sync-api) for more details.\n\nIf called with a `name`:\n\n- the response will be stored and can be retrieved later using e.g. `fetchSync.get('name').then(sync =\u003e sync.response)`.\n- the response will not automatically be removed from the IDBStore in the worker. You should request\nthat a named sync be removed manually by using `sync.remove()`.\n- see the [Sync API](#sync-api) for more details.\n\nExamples:\n\n- named GET\n\n    ```js\n    fetchSync('GetMessages', '/messages')\n      .then((response) =\u003e response.json())\n      .then((json) =\u003e console.log(json.foo))\n    ```\n\n- unnamed POST\n\n    ```js\n    const post = fetchSync('/update-profile', {\n      method: 'POST',\n      body: { name: '' }\n    })\n\n    // cancel the sync...\n    post.cancel()\n    ```\n\n- unnamed with options\n\n    ```js\n    const headers = new Headers();\n\n    headers.append('Authorization', 'Basic abcdefghijklmnopqrstuvwxyz');\n\n    // `fetchSync` accepts the same args as `fetch`...\n    fetchSync('/send-message', { headers })\n    ```\n\n- named with options\n\n    ```js\n    fetchSync('/get-messages', { headers })\n    ```\n\n- unnamed with Request\n\n    ```js\n    fetchSync(\n      new Request('/messages')\n    )\n    ```\n\n### `fetchSync.get(name) : Sync`\n\nGet a sync by its name.\n\n- __name__ {String} name of the sync operation to get\n\nReturns a Promise that resolves with success of the sync operation or reject if sync operation is not found.\n\nThere are also some properties/methods on the Promise. See the [Sync API](#sync-api) for more details.\n\nExample:\n\n```js\nfetchSync('SendMessage', '/message', { body: 'Hello, World!' })\n\nconst sync = fetchSync.get('SendMessage')\n\nsync.then((response) =\u003e {\n  if (response.ok) {\n    alert(`Your message was received at ${new Date(sync.syncedOn).toDateString()}.`\n  } else {\n    alert('Message failed to send.')\n  }\n})\n```\n\n### `fetchSync.getAll() : Array\u003cSync\u003e`\n\nGet all sync operations.\n\nReturns an array of all sync operations (named and unnamed).\n\nExample:\n\n```js\nfetchSync.getAll()\n  .then((syncs) =\u003e syncs.forEach(sync =\u003e sync.cancel()))\n```\n\n### `fetchSync.cancel(name) : Promise`\n\nCancel the sync with the given `name`.\n\n- __name__ {String} name of the sync operation to cancel\n\nExample:\n\n```js\nfetchSync('Update', '/update', { body })\nfetchSync.cancel('Update')\n```\n\n### `fetchSync.cancelAll() : Promise`\n\nCancel all syncs, named and unnamed.\n\n## Sync API\n\n### `sync.cancel() : Promise`\n\nCancels the sync operation.\n\nReturns a Promise of success of the cancellation.\n\nExample:\n\n```js\nconst sync = fetchSync.get('Update')\nsync.cancel()\n```\n\n### `sync.id`\n\nThe unique ID of the sync operation. This will be its name if it has one.\n\n### `sync.name`\n\nThe name of the sync operation if it has one.\n\n### `sync.createdOn`\n\nThe time that the sync operation was created.\n\n### `sync.syncedOn`\n\nThe time that the sync operation was completed.\n\n## Dependencies\n\n- [idb-wrapper](https://github.com/jensarps/IDBWrapper)\n- [msgr](https://github.com/sdgluck/msgr)\n- [sw-register](https://github.com/sdgluck/sw-register)\n- [serialise-request](https://github.com/sdgluck/serialise-request)\n- [serialise-response](https://github.com/sdgluck/serialise-response)\n- [mini-defer](https://github.com/sdgluck/mini-defer)\n\n## Test\n\nAs the library depends on Service Workers and no headless browser has (good enough) support for Service Workers\nthat would allow tests to be executed within the console, tests are ran through the browser using\n[Mocha](https://github.com/mochajs/mocha) and [Chai](https://github.com/chaijs/chai).\n\nOn running `npm test` an Express server will be started at `localhost:8000`.\n\nRun the tests:\n\n```sh\n$ cd fetch-sync\n$ npm test\n```\n\n## Development\n\nThe library is bundled by [Webpack](https://github.com/webpack/webpack)\nand transpiled by [Babel](https://github.com/babel/babel).\n\n- Install dependencies: `npm install`\n- Start Webpack in a console: `npm run watch`\n- Start the test server in another: `npm test`\n- Navigate to `http://localhost:8000`\n\n## Contributing\n\nAll pull requests and issues welcome!\n\nIf you're not sure how, check out Kent C. Dodds'\n[great video tutorials on egghead.io](https://egghead.io/lessons/javascript-identifying-how-to-contribute-to-an-open-source-project-on-github)!\n\n## Author \u0026 License\n\n`fetch-sync` was created by [Sam Gluck](https://twitter.com/sdgluck) and is released under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdgluck%2Ffetch-background-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsdgluck%2Ffetch-background-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdgluck%2Ffetch-background-sync/lists"}