GithubHelp home page GithubHelp logo

elite174 / solid-undo-redo Goto Github PK

View Code? Open in Web Editor NEW
10.0 1.0 0.0 265 KB

A list-based (O(1)) implementation of undo-redo for signals!

Home Page: https://solid-undo-redo.vercel.app

License: MIT License

HTML 1.65% CSS 0.18% TypeScript 97.01% JavaScript 1.16%
history redo solidjs undo undo-redo time-travel

solid-undo-redo's Introduction

solid-undo-redo

version npm

A small library for undo-redo operations! Make signals with history. The implementation is list-based, so it works in O(1) instead of O(n)!

Features

  • Make undo or redo operations
  • Set your history length
  • React on undo and redo events with callbacks
  • Turn your history into reactive iterator

Installation

npm i solid-undo-redo

pnpm add solid-undo-redo

yarn add solid-undo-redo

Usage

import { createSignalWithHistory } from "solid-undo-redo";

const [value, setValue, history] = createSignalWithHistory<number | undefined>(
  undefined,
  { historyLength: 10 }
);

setValue(1);

// Since we haven't provided the initial value (undefined)
// the history length equals to 1
console.assert(history.size() === 1);

// Since the history length is 1
// we can't do undo and redo
console.assert(history.isUndoPossible() === false);
console.assert(history.isRedoPossible() === false);

setValue(2);

// We added new value to the history
console.assert(history.size() === 2);

// Now we can make undo operation
console.assert(history.isUndoPossible() === true);
// However we can't do redo because we're at the end
// of our history
console.assert(history.isRedoPossible() === false);

// let's add some undo/redo listeners
history.registerCallback("undo", (currentValue, previousValue) =>
  console.log(`Undo: ${currentValue}, ${previousValue}`)
);

history.registerCallback("redo", (currentValue, previousValue) => {
  console.log(`Redo: ${currentValue}, ${previousValue}`);
});

// Don't forget to remove these listeners with api.removeCallback
// when you don't need them!

history.undo();
// You'll see in the console "Undo: 1, 2"

// Now we can't make undo operations
// because we're at the beginning of our history
console.assert(history.isUndoPossible() === false);
// But we can do redo!
console.assert(history.isRedoPossible() === true);

history.redo();
// You'll see in the console "Redo: 2, 1"

// Let's have a look at our history
console.log(history.toArray()); // [1, 2]

// You can also use history.arraySignal
// To get a reactive accessor of the history array

// Now let's clear our history and callbacks
history.dispose();

Docs

function createSignalWithHistory<T>(
  initialValue?: T,
  options?: SignalWithHistoryOptions<T | undefined>
): SignalWithHistory<T | undefined>;

type CallbackTypeMap<T> = {
  undo: (currentValue: T, previousValue: T) => void;
  redo: (currentValue: T, previousValue: T) => void;
};

export interface SignalWithHistoryOptions<T> {
  /**
   * Max history length
   * @default 100
   */
  historyLength?: number;
  /**
   * Solid signal options
   */
  signalOptions?: SignalOptions<T> | undefined;
}

export type History<T> = {
  undo: VoidFunction;
  redo: VoidFunction;

  /**
   * Cleas the history
   * @param clearCurrentValue - clears current value if set to true
   * @default false
   */
  clear: (clearCurrentValue?: boolean) => void;

  /** Reactive signal which indicates if undo operation is possible */
  isUndoPossible: Accessor<boolean>;
  /** Reactive signal which indicates if redo operation is possible */
  isRedoPossible: Accessor<boolean>;

  /**
   * Reactive generator function which is retriggered
   * when the history changes
   */
  createHistoryIterator: () => Generator<T, void, unknown>;

  /**
   * Reactive signal which shows the current history length
   */
  size: Accessor<number>;

  /** Register callback for undo/redo */
  registerCallback: <CallbackType extends keyof CallbackTypeMap<T>>(
    type: CallbackType,
    listener: CallbackTypeMap<T>[CallbackType]
  ) => void;

  /** Remove callback for undo/redo */
  removeCallback: <CallbackType extends keyof CallbackTypeMap<T>>(
    type: CallbackType,
    listener: CallbackTypeMap<T>[CallbackType]
  ) => void;

  /** Returns non-reactive history array */
  toArray: () => Array<T>;

  /** Reactive signal of history array */
  arraySignal: Accessor<Array<T>>;

  /** Clear all registered callbacks and history */
  dispose: VoidFunction;
};

export type SignalWithHistory<T> = [
  /** Reactive accessor for the value */
  get: Accessor<T>,
  /** Setter function for the value */
  set: Setter<T>,
  history: History<T>
];

solid-undo-redo's People

Contributors

dependabot[bot] avatar elite174 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.