Skip to content

shared-service/shared-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SharedService

Build Status NPM Version NPM Version

SharedService is a JavaScript library for building real-time, multi-tab applications with shared state and services. It leverages SharedWorker to synchronize UI state and actions across browser tabs, making it easy to build collaborative or multi-instance web apps.

Table of Contents

Features

  • Share UI state and actions between browser tabs using SharedWorker.
  • Centralize all data and services in a single worker for consistency.
  • Simple React integration via hooks and helpers.
  • Extensible for custom actions and data persistence.
  • Demo project and online example included.

Demo project

A TODO demo project here:

Online demo open in multiple tabs

Installation

$ npm install @shared-service/core @shared-service/react

Get Started

  1. In React app root endpoint:
import React from 'react';
import ReactDOM from 'react-dom';

import { initSharedService } from '@shared-service/react';

import App from './App';

const worker = new SharedWorker('./worker.js', { type: 'module' });
initSharedService({ port: worker.port });

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
  1. In SharedWorker file worker.js:
import { SharedServiceServer } from '@shared-service/core';

const sharedServiceServer = new SharedServiceServer({
  count: 0,
});

/*global onconnect*/
onconnect = function(e) {
  sharedServiceServer.onNewPort(e.ports[0]);
};
  1. In React component:
import React from 'react';
import { useSharedState } from '@shared-service/react';

export default function App() {
  const [count, setCount] = useSharedState('count', 0);
  return (
    <div className="App">
      <div className="Counter">
        <p>
          Counter:
          {count}
        </p>
        <button type="button" onClick={() => setCount(count + 1)}>
          +1 to global
        </button>
      </div>
    </div>
  );
}

Advanced

Run actions in SharedService

In SharedWorker file worker.js:

sharedServiceServer.registerExecutor('increaseCount', () => {
  const count = sharedServiceServer.getState('count');
  sharedServiceServer.setState('count', count + 1);
});
sharedServiceServer.registerExecutor('markAsCompleted', (id) => {
  const tasks = sharedServiceServer.getState('tasks');
  const updatedTasks = tasks.map(task => {
    if (id === task.id) {
      return {...task, completed: true }
    }
    return task;
  });
  sharedServiceServer.setState('tasks', updatedTasks);
});

In React component:

import React from 'react';
import { useSharedState } from '@shared-service/react';

export default function App() {
  const [count] = useSharedState('count', 0);
  const increaseCount = () => {
    return $sharedService.execute('increaseCount');
  };
  const markAsCompleted = () => {
    return $sharedService.execute('markAsCompleted', ['todo-id']);
  };
  return (
    <div className="App">
      <div className="Counter">
        <p>
          Counter:
          {count}
        </p>
        <button type="button" onClick={increaseCount}>
          +1 to global
        </button>
        <button type="button" onClick={markAsCompleted}>
          Click to mark as completed
        </button>
      </div>
    </div>
  );
}

Data persistence

In SharedWorker file worker.js:

import localforage from 'localforage';

async function initStorage() {
  const storage = localforage.createInstance({
    name: 'myApp',
  });
  await storage.ready();
  const keys = await storage.keys();
  const promises = keys.map((key) =>
    storage.getItem(key).then((data) => {
      sharedServiceServer.setState(key, data);
    }),
  );
  await Promise.all(promises);
  sharedServiceServer.on('stateChange', ({ key, state }) => {
    storage.setItem(key, state);
  });
}

initStorage();

TODO & Roadmap

  • Support Vue
  • Run ShareService at browser extension background and normal page
  • Run ShareService at Electron main and render process

Contributing

Contributions, issues, and feature requests are welcome! Feel free to check issues or submit a pull request.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Support

For questions, feedback, or support, open an issue on GitHub or contact the maintainers.

About

a Javascript library for building multiple tabs app with SharedWorker

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors