{"id":22160395,"url":"https://github.com/rozek/y-localforage","last_synced_at":"2025-06-11T16:02:47.863Z","repository":{"id":177002276,"uuid":"659838222","full_name":"rozek/y-localforage","owner":"rozek","description":"a simple Yjs storage provider using localForage for persistence","archived":false,"fork":false,"pushed_at":"2024-09-27T15:44:52.000Z","size":114,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-09T15:07:10.122Z","etag":null,"topics":["localforage","localforage-wrapper","yjs","yjs-provider"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/rozek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2023-06-28T17:08:03.000Z","updated_at":"2024-09-27T15:44:56.000Z","dependencies_parsed_at":"2024-02-16T14:46:28.900Z","dependency_job_id":"738d7e0f-b3dc-4dca-997e-5d14589080af","html_url":"https://github.com/rozek/y-localforage","commit_stats":null,"previous_names":["rozek/y-localforage"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rozek/y-localforage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozek%2Fy-localforage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozek%2Fy-localforage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozek%2Fy-localforage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozek%2Fy-localforage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rozek","download_url":"https://codeload.github.com/rozek/y-localforage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozek%2Fy-localforage/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259292920,"owners_count":22835502,"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":["localforage","localforage-wrapper","yjs","yjs-provider"],"created_at":"2024-12-02T04:07:41.782Z","updated_at":"2025-06-11T16:02:47.811Z","avatar_url":"https://github.com/rozek.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# y-localforage #\n\na simple [Yjs](https://docs.yjs.dev/) storage provider using [localForage](https://localforage.github.io/localForage/) for persistence\n\n[Yjs](https://github.com/yjs/yjs) provides a complete ecosystem for (persisting and) sharing \"Conflict-free replicated data types\" (CRDT) among multiple clients using a variety of persistence and communication providers. [LocalForage](https://github.com/localForage/localForage) is a simple storage library for JavaScript which wraps IndexedDB, WebSQL and other storage technologies in a common, `localStorage`-like API.\n\nThis module implements a simple Yjs storage provider for browser-based applications which uses an arbitrary `localForage` store for persistance - this means: **if there is a `localForage` \"driver\" for a storage of your choice, you can use this module to immediately instantiate a Yjs provider for it**.\n\nIn addition to other database providers `y-localforage`\n\n* contains an `isSynced` property which reflects the main document's own current synchronization status,\n* and an `isFullySynced` property which includes the synchronization state of any subdocs,\n* emits additional events (`sync-started`, `sync-continued`, `sync-finished` and `sync-aborted`) which inform about synchronization progress for the main document,\n* and `subdoc-synced` which informs about a given subdoc being successfully synchronized,\n* sends a `load` event to the main doc and any subdoc as soon as that `Y.Doc` has been fully loaded from persistence,\n* automatically persists any subdocs as well, and\n* includes rudimentary error handling which breaks down the provider upon failure (which means that you have to re-incarnate the provider after the cause for this failure has been removed).\n\n`y-localforage` always tries to keep your data safe and not to overwrite or even delete previously written updates. Even a failure normally only means that the last update could not be written but all the previous ones are still safe.\n\n\u003e **Important: do not use the \"copy\" feature for `Y.Doc`s, i.e., do not create a `Y.Doc` instance with the same GUID as another one - `Y.Doc` copies do not \"synchronize\" as described in the docs anyway.**\n\n**NPM users**: please consider the [Github README](https://github.com/rozek/y-localforage/blob/main/README.md) for the latest description of this package (as updating the docs would otherwise always require a new NPM package version)\n\n\u003e Just a small note: if you like this work and plan to use it, consider \"starring\" this repository (you will find the \"Star\" button on the top right of this page), so that I know which of my repositories to take most care of.\n\n## Installation ##\n\n`y-localforage` may be used as an ECMAScript module (ESM), a CommonJS or AMD module or from a global variable.\n\nYou may either install the package into your build environment using [NPM](https://docs.npmjs.com/) with the command\n\n```\nnpm install y-localforage localforage\n```\n\nor load the plain script files directly\n\n```html\n\u003cscript src=\"https://unpkg.com/localforage\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/y-localforage\"\u003e\u003c/script\u003e\n```\n\n## Access ##\n\nHow to access the package depends on the type of module you prefer\n\n* ESM (or Svelte): `import { LocalForageProvider } from 'y-localforage'`\n* CommonJS: `const LocalForageProvider = require('y-localforage')`\n* AMD: `require(['y-localforage'], (LocalForageProvider) =\u003e {...})`\n\nAlternatively, you may access the global variable `LocalForageProvider` directly.\n\nNote for ECMAScript module users: all module functions and values are exported individually, thus allowing your bundler to perform some \"tree-shaking\" in order to include actually used functions or values (together with their dependencies) only.\n\n## Usage within Svelte ##\n\nFor Svelte, it is recommended to import the package in a module context. From then on, its exports may be used as usual:\n\n```html\n\u003cscript context=\"module\"\u003e\n  import * as Y from 'yjs'\n  import { LocalForageProvider } from 'y-localforage'\n\u003c/script\u003e\n\n\u003cscript\u003e\n  localforage.config({\n    driver: [localforage.INDEXEDDB, localforage.WEBSQL]\n  })\n\n  localforage.ready(function () {\n    const DocStore = localforage.createInstance({\n      name:'Yjs-Persistence'\n    })\n\n    const sharedDoc   = new Y.Doc()\n    const Persistence = new LocalForageProvider(DocStore, sharedDoc)\n    ...\n  })\n\u003c/script\u003e\n```\n\n## Usage as ECMAscript, CommonJS or AMD Module (or as a global Variable) ##\n\nLet's assume that you already \"required\" or \"imported\" (or simply loaded) the module according to your local environment. In that case, you may use it as follows:\n\n```javascript\n  ...\n  localforage.config({\n    driver: [localforage.INDEXEDDB, localforage.WEBSQL]\n  })\n\n  localforage.ready(function () {\n    const DocStore = localforage.createInstance({\n      name:'Yjs-Persistence'\n    })\n\n    const sharedDoc   = new Y.Doc()\n    const Persistence = new LocalForageProvider(DocStore, sharedDoc)\n    ...\n  })\n```\n\n## API Reference ##\n\nThe following documentation shows method signatures as used by TypeScript - if you prefer plain JavaScript, just ignore the type annotations.\n\n### Constructor ###\n\n* **`LocalForageProvider (Store:any, sharedDoc:Y.Doc, UpdateLimit:number = 500)`**\u003cbr\u003ecreates a new instance of `LocalForageProvider` which synchronizes the given `sharedDoc` on the given localForage `Store`. `UpdateLimit` indicates how many updates should be appended to the `Store` before they will be compacted into a single one\n\n### Properties ###\n\n* **`isSynced`**\u003cbr\u003ereturns `true` while the initially given `Y.Doc` and this provider are in-sync - or `false` otherwise. Please note, that `isSynced` does not inform about the synchronization status of any \"subdocs\"\n* **`isFullySynced`**\u003cbr\u003ereturns `true` while the initially given `Y.Doc` and all its \"subdocs\" are in-sync - or `false` otherwise\n\n### Methods ###\n\n* **`SubDocIsSynced (SubDoc:Y.Doc):boolean`**\u003cbr\u003ereturns `true` while the given `SubDoc` (of this provider's shared `Y.Doc`) and its provider are in-sync - or `false` otherwise. `SubDocIsSynced` also returns `false` if `SubDoc` is not a subdoc of this provider's shared `Y.Doc`\n* **`async destroy ():Promise\u003cvoid\u003e`**\u003cbr\u003estops any activities of this provider and deletes any persistence entries of this provider's shared `Y.Doc` and its subdocs. **Warning**: this method completely destroys any written data and cannot be undone!\n\n### Events ###\n\n* **`on('sync-started', Handler:(Provider:LocalForageProvider, Progress:number) =\u003e void)`**\u003cbr\u003ethe `sync-started` event is fired whenever a synchronization between this provider and its associated `Y.Doc` has begun. `Provider` contains a reference to this provider and `Progress` is always `0.0`\n* **`on('sync-continued', Handler:(Provider:LocalForageProvider, Progress:number) =\u003e void)`**\u003cbr\u003ethe `sync-continued` event may be fired several times while a synchronization between this provider and its associated `Y.Doc` is in progress if this synchronization can not be completed instantaneously. `Provider` contains a reference to this provider and `Progress` is a number between `0.0` and `1.0` indicating how much has already been synchronized. Please note: depending on how many new updates are generated (in contrast to how many have been synchronized during that time) the reported `Progress` may not always increase but may even decrease sometimes\n* **`on('sync-finished', Handler:(Provider:LocalForageProvider, Progress:number) =\u003e void)`**\u003cbr\u003ethe `sync-finished` event is fired whenever a synchronization between this provider and its associated `Y.Doc` has finished. `Provider` contains a reference to this provider and `Progress` is always `1.0`\n* **`on('sync-aborted', Handler:(Provider:LocalForageProvider, Progress:number) =\u003e void)`**\u003cbr\u003ethe `sync-aborted` event is fired when a synchronization between this provider and its associated `Y.Doc` has been aborted (e.g., because the space on localStorage was exhausted or the provider was destroyed). `Provider` contains a reference to this provider and `Progress` is always `1.0`. After such an event, the `Provider` remains unusable and has to be created again\n* **`on('synced', Handler:(Provider:LocalForageProvider) =\u003e void`**\u003cbr\u003ethe `synced` event works like in any other Yjs provider and is fired whenever (initially or after an update to the associated `Y.Doc`) this provider gets in-sync again\n* **`on('subdoc-synced', Handler:(Provider:LocalForageProvider, SubDoc:Y.Doc) =\u003e void`**\u003cbr\u003ethe `subdoc-synced` event is fired whenever any \"subdoc\" of this provider's main `Y.Doc` has been successfully synchronized. `Provider` contains a reference to this provider and `SubDoc` a reference to the synchronized subdoc\n\n## Build Instructions ##\n\nYou may easily build this package yourself.\n\nJust install [NPM](https://docs.npmjs.com/) according to the instructions for your platform and follow these steps:\n\n1. either clone this repository using [git](https://git-scm.com/) or [download a ZIP archive](https://github.com/rozek/y-localforage/archive/refs/heads/main.zip) with its contents to your disk and unpack it there \n2. open a shell and navigate to the root directory of this repository\n3. run `npm install` in order to install the complete build environment\n4. execute `npm run build` to create a new build\n\nYou may also look into the author's [build-configuration-study](https://github.com/rozek/build-configuration-study) for a general description of his build environment.\n\n## License ##\n\n[MIT License](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frozek%2Fy-localforage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frozek%2Fy-localforage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frozek%2Fy-localforage/lists"}