Skip to content

Latest commit

 

History

History
159 lines (133 loc) · 3.62 KB

README.md

File metadata and controls

159 lines (133 loc) · 3.62 KB

electron-persist

Scalable storage solution for Electron Application

Feature

  • 🚀 Fully typed with TypeScript
  • 🫙 Nearly zero dependencies: (type-fest, semver)
  • 📦 Fully customizable storage method
  • 🚛 Support migration from previous version
  • ✅ Support configuration validation

Installation

pnpm add @electron-persist/core @electron-persist/main @electron-persist/renderer

or npm

npm install @electron-persist/core @electron-persist/main @electron-persist/renderer

Usage

Config

import { Config } from '@electron-persist/core';
import { FilePersister } from '@electron-persist/main';

type ConfigType = {
  key: string;
  type: {
    magic: {
      a: number;
      b: [string, number];
    };
  }
};
const config = new Config<ConfigType>({
  persister: new FilePersister({
    path: 'config.json',
    migrator: {
      '1.0.0': (data) => {
        // migrate from 1.0.0 to 1.0.1
        return data;
      },
      '1.0.1': (data) => {
        // migrate from 1.0.1 to 1.0.2
        return data;
      },
    },
  }),
});

config.get(); // -> ConfigType
config.get('key'); // -> string
config.get('key.type.magic.a'); // -> number
config.get('key.type.magic'); // -> { a: number; b: [string, number]; }

config.set('key', 'value');
config.set('key.type.magic.b', ['string', 1]);

Electron

  • In Main
    import { Config } from '@electron-persist/core';
    import { registerConfig } from '@electron-persist/main';
    import { BrowserWindow } from 'electron';
    
    const config = new Config<ConfigType>(/* ... */);
    
    const init = () => {
      const win = new BrowserWindow(/* ... */);
      
      registerConfig(win, 'config', config);
    };
  • In Renderer
    import { Config } from '@electron-persist/core';
    import { getConfig } from '@electron-persist/renderer';
    
    // provide ipcRenderer
    const config = getConfig<ConfigType>('config', window.ipcRenderer);
    
    config.get('key.type.magic.a') // -> number;

API

Note

TODO

Core

Config

Persister

  • MemoryPersister

Validator

Migrator

Main

  • registerConfig

FilePersister

Renderer

  • getConfig

IpcRendererPersister

FAQ

How to use custom persister?

import { Config, Persister } from '@electron-persist/core';

class CustomPersister<T> extends Persister<T> {
  async getConfigVersion() {
    // load version from custom storage
  }
  
  async readData(key) {
    // read from custom storage
  }
  
  async writeData(key, value) {
    // write to custom storage
  }
}

const config = new Config<ConfigType>({
  persister: new CustomPersister(),
});

You can create a custom persister by extending Persister class and implement getConfigVersion, readData, writeData methods. For example, if you want to use localStorage as a storage method, you can implement readData and writeData methods like this:

class LocalStoragePersister<T> extends Persister<T> {
  async getConfigVersion() {
    return localStorage.getItem('config-version');
  }
  
  async readData(key) {
    return JSON.parse(localStorage.getItem(key));
  }
  
  async writeData(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  }
}

How to use custom validator?

import { Config, Validator } from '@electron-persist/core';

const validator = {
  validate: (data: unknown) => {
    if ('never' in data) throw Error('never should not be in data');
    
    return data;
  },
  fallback: {},
};

You just pass the object that has validate and fallback properties to Config constructor.