immer-rxjs
TypeScript icon, indicating that this package has built-in type declarations

3.4.2 • Public • Published

immer-rxjs

This small library helps you use Immer with RxJS. It exports only one function, you can use it to replace rxjs's map operator.

update in 3.0.0

At beginning I want to compute and reapply patches by fast-json-patch so I could be sure if the produced value is structurally identical to previous value, the result will be identically be the same, but late on I find that is a bad idea (you should use immer the right way and don't worry about it) so I turned it off by default in 2.0.0 and removed it in 3.0.0.

Usage

Let's just review the final source code here:

import produce from "immer";
import { pipe } from "rxjs";
import { scan } from "rxjs/operators";
function defaultMapFn(current, last) {
    Object.assign(last, current);
}
export default function produceOperator(fn, initValue) {
    if (fn === void 0) { fn = defaultMapFn; }
    if (initValue === void 0) { initValue = produce({}, function () { }); }
    return pipe(scan(function (last, current) {
        return produce(last, function (draft) {
            return fn(current, draft);
        });
    }, initValue));
}

so how we use it:

produce()

import produce from 'immer-rxjs'
source$.pipe(produce(producer))

The produce function is like Immer's Curried producers except that it expect new value from source$ (like action of curried producer) be the first argument and draft to be the second.

You can edit draft object like in immer producer:

import {produce} from 'immer-rxjs'
 
source$.pipe(
  produce((newValueFromSource, draft) {
    // draft will be previous value you produced here, starting with an empty object
    draft.someProp = newValueFromSource.someProp
  })
)

or you can just return new value from it, that way you can treat it like a map operator replacement. but it's not recommended as below

not recommended to do this since it return new object every time:

import immerMap from 'immer-rxjs'
const sub$ = new Subject();
sub$
  .pipe(
    immerMap((a) => ({ ...a, b: a.b + 1 })),
    bufferCount(2)
  )
  .subscribe(([v1, v2]) => {
    console.log(v1); // {b: 3}
    console.log(v2); // {b: 3}
    console.log(v1 === v2); // false
  });
sub$.next({ b: 2 });
sub$.next({ b: 2 });

this is better

import immerMap from 'immer-rxjs'
const sub$ = new Subject();
sub$
  .pipe(
    immerMap((a, draft) => {
      Object.assign(draft, { b: a.b + 1 });
    }),
    bufferCount(2)
  )
  .subscribe(([v1, v2]) => {
    console.log(v1); // {b: 3}
    console.log(v2); // {b: 3}
    console.log(v1 === v2); // true
  });
sub$.next({ b: 2 });
sub$.next({ b: 2 });

immerify()

default fn is (current, last) => {Object.assign(last, current)}, you can do:

import immerify from 'immer-rxjs'
const sub$ = new Subject();
sub$
  .pipe(immerify())
  .subscribe(([v1, v2]) => {
    console.log(v1); // {b: 2}
    console.log(v2); // {b: 2}
    console.log(v1 === v2); // true
  });
sub$.next({ b: 2 });
sub$.next({ b: 2 });

License

MIT

Readme

Keywords

Package Sidebar

Install

npm i immer-rxjs

Weekly Downloads

0

Version

3.4.2

License

MIT

Unpacked Size

7.27 kB

Total Files

6

Last publish

Collaborators

  • undozen