a simple Yjs storage provider persisting in localStorage (for educational purposes only!)
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.
This module implements a simple Yjs storage provider for browser-based applications which uses localStorage for persistance. In addition to other database providers it
- contains an
isSynced
property which reflects the main document's current synchronization status, - emits additional events (
sync-started
,sync-continued
,sync-finished
andsync-aborted
) which inform about synchronization progress for the main document, - recognizes subdocs (which will then automatically be persisted as well), and
- 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).
y-localstorage
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.
Important: do not use the "copy" feature for
Y.Doc
s, i.e., do not create aY.Doc
instance with the same GUID as another one -Y.Doc
copies do not "synchronize" as described in the docs anyway.
NPM users: please consider the Github README for the latest description of this package (as updating the docs would otherwise always require a new NPM package version)
Nota bene: do not use this provider in production - it has solely be written for educational purposes!
y-localstorage
may be used as an ECMAScript module (ESM), a CommonJS or AMD module or from a global variable.
You may either install the package into your build environment using NPM with the command
npm install y-localstorage
or load the plain script file directly
<script src="https://unpkg.com/y-localstorage"></script>
How to access the package depends on the type of module you prefer
- ESM (or Svelte):
import { LocalStorageProvider } from 'y-localstorage'
- CommonJS:
const LocalStorageProvider = require('y-localstorage')
- AMD:
require(['y-localstorage'], (LocalStorageProvider) => {...})
Alternatively, you may access the global variable LocalStorageProvider
directly.
Note 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.
For Svelte, it is recommended to import the package in a module context. From then on, its exports may be used as usual:
<script context="module">
import * as Y from 'yjs'
import { LocalStorageProvider } from 'y-localstorage'
</script>
<script>
const sharedDoc = new Y.Doc()
const Persistence = new LocalStorageProvider('local-persistence', sharedDoc)
...
</script>
Let'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:
...
const Persistence = new LocalStorageProvider('local-persistence', sharedDoc)
...
The following documentation shows method signatures as used by TypeScript - if you prefer plain JavaScript, just ignore the type annotations.
LocalStorageProvider (DocName:string, sharedDoc:Y.Doc, CounterLimit:number = 5)
creates a new instance ofLocalStorageProvider
which synchronizes the givensharedDoc
onlocalStorage
.DocName
is used as a prefix for the keys under which updates ofsharedDoc
are stored.CounterLimit
indicates how many updates will just be appended tolocalStorage
before they will be compacted into a single one
isSynced
returnstrue
while the initially givenY.Doc
and this provider are in-sync - orfalse
otherwise
on('sync-started', Handler:(Provider:LocalStorageProvider, Progress:number) => void)
thesync-started
event is fired whenever a synchronization between this provider and its associatedY.Doc
has begun.Provider
contains a reference to this provider andProgress
is always0.0
on('sync-continued', Handler:(Provider:LocalStorageProvider, Progress:number) => void)
thesync-continued
event may be fired several times while a synchronization between this provider and its associatedY.Doc
is in progress if this synchronization can not be completed instantaneously.Provider
contains a reference to this provider andProgress
is a number between0.0
and1.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 reportedProgress
may not always increase but may even decrease sometimeson('sync-finished', Handler:(Provider:LocalStorageProvider, Progress:number) => void)
thesync-finished
event is fired whenever a synchronization between this provider and its associatedY.Doc
has finished.Provider
contains a reference to this provider andProgress
is always1.0
on('sync-aborted', Handler:(Provider:LocalStorageProvider, Progress:number) => void)
thesync-aborted
event is fired when a synchronization between this provider and its associatedY.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 andProgress
is always1.0
. After such an event, theProvider
remains unusable and has to be created againon('synced', Handler:(Provider:LocalStorageProvider) => void
thesynced
event works like in any other Yjs provider and is fired whenever (initially or after an update to the associatedY.Doc
) this provider gets in-sync again
You may easily build this package yourself.
Just install NPM according to the instructions for your platform and follow these steps:
- either clone this repository using git or download a ZIP archive with its contents to your disk and unpack it there
- open a shell and navigate to the root directory of this repository
- run
npm install
in order to install the complete build environment - execute
npm run build
to create a new build
You may also look into the author's build-configuration-study for a general description of his build environment.