Home

Awesome

limu 🍋

limu is short for love immutable, born for efficient creation and operation of immutable object, based on shallow copy on read and mark modified on write mechanism.

<p align="center"> <a href="https://concentjs.github.io/concent-doc"> <img width="260" src="https://raw.githubusercontent.com/fantasticsoul/assets/master/limu/limu.png"> </a> </p>

It is fast, It is nearly more than 2 or 20 times faster than immer in different situations. Click this online perf demo to review the amazing result.

No freeze by default, limu is 10 times or more faster than Immer in most scenarios

Pay attention, limu can only run on JavaScript runtime that supports proxy

Performance ⚡️

No freeze by default, limu is 10 times or more faster than Immer in most scenarios after 3.7 version, limu is now the fastest immutable js lib of all ( faster than immer and mutative ).

test 1 (inspired by this immer case )

test 2 test 2

The performance testing process is as follows

git clone https://github.com/tnfe/limu
cd limu
npm i
cd benchmark
npm i
node opBigData.js // trigger test execution, the console echoes the result
# or
node caseOnlyRead.js
npm run s1
npm run s2
npm run s3
npm run s4

You are very welcome to submit your test to the benchmark directory or test directory

Quick Start

install

npm i limu

apis

import { produce, createDraft, finishDraft } from 'limu';

produce

const baseState = {
  a: 1,
  b: [1, 2, 3],
  c: {
    c1: { n: 1 },
    c2: { m: 2 },
  },
};
const nextState = produce(baseState, (draft) => {
  draft.a = 2;
  draft.b['2'] = 100;
});

console.log(nextState === baseState); // false
console.log(nextState.a === baseState.a); // false
console.log(nextState.b === baseState.b); // false
console.log(nextState.c === baseState.c); // true

Currying call

const producer = produce((draft) => {
  draft.a = 2;
  draft.b['2'] = 100;
});
const nextState = producer(baseState);

createDraft, finishDraft

const draft = createDraft(baseState);
draft.a = 2;
draft.b = [];
const nextState = finishDraft(draft);

console.log(nextState === baseState); // false
console.log(nextState.a === baseState.a); // false
console.log(nextState.b === baseState.b); // false
console.log(nextState.c === baseState.c); // true

Experience limu on the console

logo

As limu is an immutable js library based on shallow copy on read and mark modified on write. Based on this mechanism, so it is more friendly to debugging. You can copy the following code to the console experience

there are 2 ways to quickly experience limu and compare limu with immer.

function loadJs(url) {
  const dom = document.createElement('script');
  dom.src = url;
  document.body.appendChild(dom);
}

loadJs('https://unpkg.com/limu@3.5.5/dist/limu.min.js'); // load limu umd bundle
loadJs('https://unpkg.com/immer@9.0.21/dist/immer.umd.production.min.js'); // load immer umd bundle

Then you can paste below codes to run

function oneCase(produce) {
  const demo = { info: Array.from(Array(10000).keys()) };
  produce(demo, (draft) => {
    draft.info[2000] = 0;
  });
}

function runBenchmark(produce, label) {
  const start = Date.now();
  const limit = 100;
  for (let i = 0; i < limit; i++) {
    oneCase(produce);
  }
  console.log(`${label} avg spend ${(Date.now() - start) / limit} ms`);
}

function run() {
  immer.setAutoFreeze(false);
  runBenchmark(immer.produce, 'immer,');
  runBenchmark(limu.produce, 'limu,');
}
lib = window.limu; // or lib = window.immer
const base = {
  a: 1,
  b: { b1: 1, b2: 2, b3: { b31: 1 } },
  c: [1, 2, 3],
  d: { d1: 1000 },
};
const draft = lib.createDraft(base);
draft.a = 200;
draft.b.b1 = 100;
console.log(draft);
draft.c.push(4);
const final = lib.finishDraft(draft);
console.log(base === final); // false
console.log(base.a === final.a); // false
console.log(base.b === final.b); // false
console.log(base.b.b3 === final.b.b3); // true
console.log(base.c === final.c); // false
console.log(base.d === final.d); //true

Higher observability will greatly improve the development and debugging experience, as shown in the figure below, after unfolding the limu draft, you can observe all data nodes of the draft in real time

<img width="574" alt="image" src="https://github.com/unadlib/mutative/assets/7334950/2f90b07d-e2e3-4104-916c-8c0add935b41">

And the immer or mutative expansion is like this <img width="618" alt="image" src="https://github.com/unadlib/mutative/assets/7334950/44500c66-d691-4d29-b856-fa490d2bdf8f">

License

Copyright (c) Tencent Corporation. All rights reserved.

Limu is released under the MIT License(https://opensource.org/licenses/MIT)