Giter Site home page Giter Site logo

enterstudio / observable-diff-operator Goto Github PK

View Code? Open in Web Editor NEW

This project forked from dxcx/observable-diff-operator

0.0 0.0 0.0 40 KB

implementation of observable toDiff fromDiff

License: GNU Affero General Public License v3.0

TypeScript 68.27% JavaScript 31.73%

observable-diff-operator's Introduction

observable-diff-operator

Greenkeeper badge NPM version Build Status Coverage Status Standard Version

this is fromDiff / toDiff logic implementation for observables.

those operators are meant for sending observables over network: Example diagram

Wrapping observers for Examples

to use the logic, you will need to simply wrap observables using your observables implementation, for example, RxJs:

import { Observable } from 'rxjs';
import { fromDiffObserver, IObservableDiff, toDiffObserver } from 'observable-diff-operator';

export function fromDiffWrap<T>(obs: Observable<IObservableDiff>): Observable<T> {
  return new Observable((observer) => {
    return obs.subscribe(fromDiffObserver(observer));
  });
}

export function toDiffWrap<T>(obs: Observable<T>): Observable<IObservableDiff> {
  return new Observable((observer) => {
    return obs.subscribe(toDiffObserver(observer));
  });
}

NOTE: for rxjs, rxjs-diff-operator will give the same result but as embeded operator instead of converting observables.

Operators:

toDiff

signature: toDiffObserver<T>(Observer<IObservableDiff>): Observer<T>

Description

toDiff operator is used to convert output of an obsersvable stream, into a stream that contains diff information. this operator is inteded to be used on the server.

Example
//emit (1,2,3,4,5)
const source = Rx.Observable.from([1,2,3,4,5]);
//add 10 to each value
const example = toDiffWrap(source);
//output: { type: "init", payload: 1, isObject: false }, { type: "update", payload: 2 }, ...
const subscribe = example.subscribe(val => console.log(val));

fromDiff

signature: fromDiffObserver<T>(Observer<T>): Observable<IObservableDiff>

Description

fromDiff operator is used to convert output of an diff obsersvable stream (see toDiff above), into a stream that contains diff information. this operator is inteded to be used on the client.

Example
//emit diff information
const source = Rx.Observable.from([{ type: "init", payload: 1, isObject: false }, { type: "update", payload: 2 }, { type: "complete" }]);
//add 10 to each value
const example = fromDiffWrap(source);
//output: 1, 2
const subscribe = example.subscribe(val => console.log(val));

Deep-Dive:

Protocol

the protocol contains 4 message types:

  • init
    • must be the first message on the line.
    • contains isObject property which represents the payload type on the stream.
    • contains intial payload (not a diff)
  • update
    • sent for each next on the original observable
    • contains payload property as raw value (simple values) or diff object (objects/arrays)
  • error
    • sent for errors on the original observable
    • contains payload of error message
  • complete
    • sent when original observable is complete.

Handling Objects:

diffing simple values is not efficient, the real power of this operator comes when dealing with array or objects. for that, deep-diff is being used.

Object example:

given the input of:

{
  "value": 1,
},
{
  "value": 2,
},
{
  "value": 3,
},
{
  "value": 4,
},
{
  "value": 5,
},

this output will be emitted:

{
    "isObject": true,
    "payload": {
        "value": 1,
    },
    "type": "init",
}, {
    "payload": [
        {
            "kind": "E",
            "lhs": 1,
            "path": [
                "value",
            ],
            "rhs": 2,
        },
    ],
    "type": "update",
}, {
    "payload": [
        {
            "kind": "E",
            "lhs": 2,
            "path": [
                "value",
            ],
            "rhs": 3,
        },
    ],
    "type": "update",
}, {
    "payload": [
        {
            "kind": "E",
            "lhs": 3,
            "path": [
                "value",
            ],
            "rhs": 4,
        },
    ],
    "type": "update",
}, {
    "payload": [
        {
            "kind": "E",
            "lhs": 4,
            "path": [
                "value",
            ],
            "rhs": 5,
        },
    ],
    "type": "update",
}, {
    "type": "complete",
}

Observable with an error example:

given the input of:

let obs: Observable<{ value: number }> = Observable.of(1, 2, 3, 4, 5)
.map((v: number, i: number) => {
    if ( i === 2 ) {
        throw new Error('testing errors');
    }

    return { value: v };
});

this output will be emitted:

{
    "isObject": true,
    "payload": {
        "value": 1,
    },
    "type": "init",
}, {
    "payload": [
        {
            "kind": "E",
            "lhs": 1,
            "path": [
                "value",
            ],
            "rhs": 2,
        },
    ],
    "type": "update",
}, {
    "payload": "testing errors",
    "type": "error",
}

Contributions

Contributions, issues and feature requests are very welcome. If you are using this package and fixed a bug for yourself, please consider submitting a PR!

observable-diff-operator's People

Contributors

dxcx avatar greenkeeper[bot] 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.