a lightweight module to sync JS objects in realtime across tabs / windows of a browser.
See this blog post for detailed information regarding the issues localsync solves.
Features
- Uses local storage event emitters to sync objects in realtime across tabs.
- Never calls the tab that the event occurred on.
- Falls back to cookie polling internally if using an unsupported browser (IE 9+ / Edge).
- Isomorphic.
- Tested with Jest.
- Written with TypeScript.
Install
yarn add localsync
OR
npm install localsync
Version 2
How to use
import { localsync } from "localsync";
const publisher = (userID, firstName, lastName) => ({
userID,
firstName,
lastName
});
const subscriber = (current, previous, url) => {
console.info(
`Another tab at url ${url} switched user from "${previous.firstName} ${previous.lastName}" to "${current.firstName} ${current.lastName}".`
);
};
const createUserSync = localsync({ channel: "user" });
const userController = createUserSync(publisher, subscriber);
userController.start(true);
if (userController.isFallback) {
console.warn(
"browser doesnt support local storage synchronization, falling back to cookie synchronization."
);
}
if (userController.isServer) {
console.debug("Detected a SSR environment.");
}
userController.trigger(1, "jimmy", "john");
userController.trigger(1, "jimmy", "john");
console.info(
userController.mechanism
);
setTimeout(() => {
userController.trigger(2, "jane", "wonka");
}, 5000);
setTimeout(() => {
if (userController.isRunning) {
userController.stop();
}
}, 10000);
API
const createSync = localsync({ channel: string, level?: LogLevel, fallback?: FallbackOptions })
const sync = createSync((publisher: (...args) => TMessage, subscriber: (message: TMessage) => void);
const { start, stop, trigger, isRunning, isFallback } = sync;
Input
name | type | default | description |
---|
channel | string | required | a string that is used for this synchronization instance. |
level | string | 'INFO' | the log level to use when tracing (ERROR , WARN , INFO , DEBUG ) |
fallback | object | see below | optional fallback options if you need more control over cookie fallback. |
FallbackOptions
name | type | default | description |
---|
pollFrequency | number | 3000 | The number in milliseconds that should be used for cookie polling |
path | string | '/' | The path to use for cookies |
secure | boolean | false | Whether to set the secure flag on cookies or not (not recommended) |
httpOnly | boolean | false | Whether to set the http only flag on cookies or not |
Output
Interface of localsync
returned controller
name | type | defaults | description |
---|
start | function | N/A | Call to start syncing. Accepts one boolean parameter (default false). If passed true, will run the synchronization on start. |
stop | function | N/A | Call to stop syncing |
trigger | function | N/A | Call to trigger a sync to occur to all other clients |
mechanism | string | `(storage | cookie |
isRunning | boolean | false | Is synchronization currently enabled |
isFallback | boolean | false | Is the selected mechanism a fallback strategy |
isServer | boolean | false | Is the current client running in a server environment |
Structure and Roadmap
localsync has a singular purpose: to synchronize events from one client to many using a common interface and the least invasive mechanism for the current browsing medium.
Internally, localsync is comprised of several small sync
packages that all adhere to the common localsync interface. The main localsync package does no actual synchronization on its own but rather determines the most appropriate synchronization strategy and calls upon the necessary packages to invoke it. All the packages with brief descriptions are listed here:
Guaranteed synchronization between clients of the same browser (Chrome :left_right_arrow: Chrome, IE :left_right_arrow: IE, etc.)
- localsync - Determines synchronization mechanism and invokes it.
Mechanism packages
Version 1 API
const sync = localsync(key: string, action: (...args) => payload, handler: payload => {}, [opts: Object])
const { start, stop, trigger, isRunning, isFallback } = sync
Input
key: a string that is used for this synchronization instance (you may have multiple instances of localsync each with different keys to sync different types of data).
action: a function that will be called when this client's trigger function is invoked. The action will be passed any arguments provided to the trigger function and should return the payload to be delivered to other clients for the given localsync key.
handler: a function that will be invoked on this client when any other client's trigger function is invoked. NOTE: This handler will NEVER be called due to this clients trigger function being called, only other clients.
opts: An optional object argument that may be specified to control how localsync operates. Supported values are shown below.
name | type | default | description |
---|
tracing | boolean | false | toggles tracing for debugging purposes |
logger | Object | console | the logger object to trace to |
loglevel | string | 'info' | the log level to use when tracing (error , warn , info , trace ) |
pollFrequency | number | 3000 | fallback: cookiesync the number in milliseconds that should be used for cookie polling |
idLength | number | 8 | fallback: cookiesync the number of characters to use for tracking the current instance (tab) |
path | string | '/' | fallback: cookiesync The path to use for cookies |
secure | boolean | false | fallback: cookiesync Whether to set the secure flag on cookies or not (not recommended) |
httpOnly | boolean | false | fallback: cookiesync Whether to set the http only flag on cookies or not |
Contributing
To setup localsync for use in development run the following steps at CLI:
git clone https://github.com/noderaider/localsync
cd localsync
yarn
yarn build
Then from your project:
npm link ../localsync/packages/localsync
Feature / bug fixes via pull requests encouraged!