• Stars
    star
    293
  • Rank 141,748 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A tiny implementation of RxJS that actually works, for learning

Toy RxJS

A tiny implementation of RxJS that actually works, for learning.

Usage

npm install toy-rx

const Rx = require('toy-rx')
Rx.Observable.fromEvent = require('toy-rx/fromEvent')
Rx.Observable.prototype.map = require('toy-rx/map')
Rx.Observable.prototype.filter = require('toy-rx/filter')
Rx.Observable.prototype.delay = require('toy-rx/delay')

Rx.Observable.fromEvent(document, 'click')
  .delay(500)
  .map(ev => ev.clientX)
  .filter(x => x < 200)
  .subscribe({
    next: x => console.log(x),
    error: e => console.error(e),
    complete: () => {},
  })

Why

I made this so people can look into the implementation of a simple RxJS and feel like they can actually understand it. I mean, the implementation is literally this below:

class Subscription {
  constructor(unsubscribe) {
    this.unsubscribe = unsubscribe;
  }
}

class Subscriber extends Subscription {
  constructor(observer) {
    super(function unsubscribe() {});
    this.observer = observer;
  }

  next(x) {
    this.observer.next(x);
  }

  error(e) {
    this.observer.error(e);
    this.unsubscribe();
  }

  complete() {
    this.observer.complete();
    this.unsubscribe();
  }
}

class Observable {
  constructor(subscribe) {
    this.subscribe = subscribe;
  }

  static create(subscribe) {
    return new Observable(function internalSubscribe(observer) {
      const subscriber = new Subscriber(observer);
      const subscription = subscribe(subscriber);
      subscriber.unsubscribe = subscription.unsubscribe.bind(subscription);
      return subscription;
    });
  }
}

class Subject extends Observable {
  constructor() {
    super(function subscribe(observer) {
      this.observers.push(observer);
      return new Subscription(() => {
        const index = this.observers.indexOf(observer);
        if (index >= 0) this.observers.splice(index, 1);
      });
    });
    this.observers = [];
  }

  next(x) {
    this.observers.forEach((observer) => observer.next(x));
  }

  error(e) {
    this.observers.forEach((observer) => observer.error(e));
  }

  complete() {
    this.observers.forEach((observer) => observer.complete());
  }
}

See? It fit easily in a README and you weren't scared of looking at it even though it's source code. That was index.js.

Where are all the operators? Well, here's map for instance:

function map(transformFn) {
  const inObservable = this;
  const outObservable = Rx.Observable.create(function subscribe(outObserver) {
    const inObserver = {
      next: (x) => {
        try {
          var y = transformFn(x);
        } catch (e) {
          outObserver.error(e);
          return;
        }
        outObserver.next(y);
      },
      error: (e) => {
        outObserver.error(e);
      },
      complete: () => {
        outObserver.complete();
      }
    };
    return inObservable.subscribe(inObserver);
  });
  return outObservable;
}

What about filter, and combineLatest and all the rest? Just look for yourself, don't be afraid to click on the JS files in this project.

How is this different to the official RxJS?

This is just meant for education. It's missing a ton of stuff that the official RxJS covers, such as:

  • Subscribe supports partial Observer objects
  • Subscribe supports functions as arguments
  • Dozens of useful operators
  • The wonderful and underrated Lift Architecture
  • Schedulers (and in turn, testing with marble diagrams)
  • Corner cases covered against bugs
  • Thorough documentation and examples
  • Thorough tests
  • TypeScript support

Overall, this project is a simplification of RxJS which describes "close enough" how RxJS works, but has a lot of holes and bugs because we deliberately are not taking care of many corner cases in this code.

Use this project to gain confidence peeking into the implementation of a library and get familiar with RxJS internals.

Contributing

Don't bother submitting PRs for this project to add more operators and more bug safety. Let's just keep this simple enough to read for any developer with a few minutes of free time.

More Repositories

1

rxmarbles

Interactive diagrams of Rx Observables
JavaScript
4,181
star
2

xstream

An extremely intuitive, small, and fast functional reactive stream library for JavaScript
TypeScript
2,349
star
3

flux-challenge

A frontend challenge to test UI architectures and solutions
JavaScript
1,653
star
4

callbag-basics

๐Ÿ‘œ Tiny and fast reactive/iterable programming library
JavaScript
1,649
star
5

react-native-node

Run a separate Node.js process behind a React Native app
Java
1,109
star
6

matrixmultiplication.xyz

TypeScript
1,049
star
7

manyverse

A social network off the grid (real repo at https://gitlab.com/staltz/manyverse)
TypeScript
924
star
8

prevent-smoosh

Don't let TC39 use smoosh or smooshMap
JavaScript
736
star
9

use-profunctor-state

React Hook for state management with profunctor lenses
JavaScript
334
star
10

comver

MIGRATED TO https://gitlab.com/staltz/comver
333
star
11

rxjs-training

(From 2015) RxJS Workshop exercises for MLOC.js
JavaScript
319
star
12

cycle-onionify

MIGRATED! This was transfered to https://cycle.js.org/api/state.html
JavaScript
284
star
13

dat-installer

Download, install, and update Android apps through Dat
TypeScript
279
star
14

zii

Chain function calls using a prototype function z
JavaScript
230
star
15

easy-ssb-pub

An easy-to-host server that runs an SSB "Pub"
JavaScript
211
star
16

html-looks-like

Assert that an HTML string looks approximately the same as another HTML
TypeScript
178
star
17

mvi-example

A demo of the Model-View-Intent architecture with Virtual DOM renderer, for single-page apps.
JavaScript
153
star
18

hyperpunk

A cyberpunk theme for HyperTerm
JavaScript
126
star
19

zig-nodejs-example

Node.js Native Module written in Zig
Zig
123
star
20

ssb-room

A server to find and connect to other SSB peers โ€“ a meeting place. AGPL-3.0
JavaScript
109
star
21

prevent-global-this

Don't let TC39 use globalThis
JavaScript
88
star
22

react-native-emoji-modal

Feature-complete Emoji picker for React Native
TypeScript
78
star
23

switch-path

switch case for URLs, a small tool for routing in JavaScript
TypeScript
77
star
24

react-propify-methods

A React utility to convert instance methods to props with Observables
JavaScript
75
star
25

ttosa

CSV data for Time Till Open Source Alternative
74
star
26

staltz.com

JavaScript
70
star
27

feedpunk

A scuttlebutt client in the terminal
JavaScript
58
star
28

promisify-4loc

Promisify a callback-style function in just 4 lines of code
JavaScript
58
star
29

rxtween

A library for creating RxJS Observables related to animation
JavaScript
57
star
30

git-done

The simplest TODO-based task tracker integrated into git.
Python
51
star
31

gun-asyncstorage

Use Gun.js in React Native through AsyncStorage
TypeScript
51
star
32

with-profunctor-state

React HOC for state management with profunctor lenses
JavaScript
46
star
33

fantasy-observable

A specification for interoperability of push-based data sources in JavaScript
42
star
34

ts-multipick

TypeScript Pick utility, but deeper: Pick2, Pick3, Pick4, ...
TypeScript
40
star
35

noderify

JavaScript
35
star
36

react-human-time

React component that periodically calls human-time
JavaScript
33
star
37

promisify-tuple

Promisify a callback-style function, resolving with [err,val]
JavaScript
31
star
38

intact

A simpler musical notation that works well with LinnStrument
GDScript
29
star
39

combineLatestObj

A convenient flavor of Rx.Observable.combineLatest to return an object
JavaScript
29
star
40

css2obj

Tagged template literal that takes CSS and returns a JavaScript object suitable for free-style
JavaScript
28
star
41

callbag-subject

๐Ÿ‘œ A callbag listener sink which is also a listenable source
JavaScript
27
star
42

cycle-custom-elementify

Converts a Cycle.js app to a custom element (Web Component)
TypeScript
26
star
43

ziii

Right-compose functions with a z() utility function
JavaScript
25
star
44

something-something

JavaScript
24
star
45

react-native-ssb-client

ssb-client for React Native apps that use nodejs-mobile-react-native
TypeScript
24
star
46

chai-virtual-dom

Chai assertion helpers for virtual-dom elements
JavaScript
24
star
47

callbag-share

๐Ÿ‘œ Callbag operator that broadcasts a single source to multiple sinks
JavaScript
22
star
48

uphill-rxjs-workshop

HTML
22
star
49

clarify-error

Add some additional context to a JavaScript error
JavaScript
22
star
50

callbag-pseudo-rxjs

๐Ÿ‘œ Proof of concept that implements a subset of RxJS using callbags
JavaScript
21
star
51

fp-js-workshop

Pragmatic functional programming in JavaScript - Workshop material
JavaScript
21
star
52

mvi-wc-poc

Proof-of-Concept of Web Components functioning in a Virtual DOM architecture (Model-View-Intent)
JavaScript
20
star
53

react-native-android-packagemanager

Call some PackageManager APIs from React Native
Java
19
star
54

pull-awaitable

Convert a pull-stream into an AsyncIterable, and use for-await-of
JavaScript
18
star
55

multiserver-worker

A multiserver plugin for Web Workers
JavaScript
18
star
56

pull-flat-list

FlatList React Native component capable of scrolling through pull-streams
TypeScript
16
star
57

callbag-to-awaitable

๐Ÿ‘œ Use async-await to consume a pullable callbag source
JavaScript
16
star
58

callbag-pipe

๐Ÿ‘œ Utility function for plugging callbags together in chain
JavaScript
16
star
59

ssb-mirror

JavaScript
16
star
60

ssb-keys-mnemonic

Module that converts from/to SSB keys and BIP39 mnemonic codes
JavaScript
15
star
61

callbag-interval

๐Ÿ‘œ A callbag listenable source that sends incremental numbers every x milliseconds.
JavaScript
15
star
62

poc-ssb-mobile

JavaScript
15
star
63

quicktask

Tiny microtask queue scheduler for all environments
TypeScript
15
star
64

react-mutant-hoc

A utility to make React components easily consume Mutant observables
JavaScript
14
star
65

jace

just another compiler experiment
Haskell
14
star
66

callbag-observe

๐Ÿ‘œ Callbag listener sink that receives data from any listenable source
JavaScript
14
star
67

frontmen-workshop

JavaScript
14
star
68

callbag-worker

๐Ÿ‘œ Callbag utilities for communicating with a Web Worker
JavaScript
13
star
69

mutant-attachable

Utility for React components to easily subscribe to Mutant streams
TypeScript
13
star
70

multiserver-dht

A multiserver plugin that uses a Distributed Hash Table
JavaScript
13
star
71

react-xstream-hoc

A utility to make React components easily consume xstream streams
JavaScript
13
star
72

ssb-keys-neon

A drop-in replacement of ssb-keys, implemented in Rust and delivered as a native module in Node.js
Rust
13
star
73

ssb-roadmap

MIGRATED to https://gitlab.com/staltz/ssb-roadmap
12
star
74

electron-ssb-client

Secure Scuttlebutt API for (Renderer process) Electron apps
TypeScript
11
star
75

ppppp-sync

JavaScript
11
star
76

amicispace

JavaScript
11
star
77

pull-worker

Convert a Web Worker API to a duplex pull-stream
JavaScript
11
star
78

callbag-for-each

๐Ÿ‘œ Callbag sink that consume both pullable and listenable sources
JavaScript
11
star
79

react-native-process-shim

Shim the Node.js process for React Native's JS runtime
JavaScript
10
star
80

cycle-native-navigation

Cycle.js drivers for react-native-navigation
TypeScript
10
star
81

cleanjs-example

Example of Cycle.js app passing the eslint-config-cleanjs lint
JavaScript
9
star
82

callbag-from-iter

๐Ÿ‘œ Convert an iterable or iterator to a callbag pullable source
JavaScript
9
star
83

pull-stream-from-promise

MIGRATED TO https://gitlab.com/staltz/pull-stream-from-promise
9
star
84

pull-rn-channel

Convert a Node.js Mobile 'channel' to a duplex pull-stream
JavaScript
9
star
85

ssb-minibutt

Experimental
JavaScript
9
star
86

callbag-to-async-iterable

๐Ÿ‘œ Convert any pullable callbag source to an AsyncIterable
JavaScript
8
star
87

ssb-discovery-swarm

Scuttlebot plugin that exchanges invites with other sbots in a DHT
JavaScript
8
star
88

ppppp-db

JavaScript
8
star
89

pull-thenable

Convert a pull-stream into a thenable
JavaScript
8
star
90

callbag-map

๐Ÿ‘œ Callbag operator that applies a transformation on data passing through it
JavaScript
8
star
91

callbag-merge

๐Ÿ‘œ Callbag factory that merges data from multiple callbag sources
JavaScript
8
star
92

dagsync

Work in progress
JavaScript
8
star
93

callbag-concat

๐Ÿ‘œ Callbag factory that concatenates data from multiple callbag sources
JavaScript
8
star
94

trustnet-org

work in progress
JavaScript
8
star
95

software-below-the-poverty-line

Dataset for my blog post
8
star
96

callbag-flatten

๐Ÿ‘œ Callbag operator that flattens a higher-order callbag source
JavaScript
7
star
97

frontmania-rxjs-workshop

HTML
7
star
98

callbag-take

๐Ÿ‘œ Callbag operator that limits the total amount of data sent through
JavaScript
7
star
99

tallbag-for-each-poc-static-graph

Tallbag sink that consume both pullable and listenable sources
JavaScript
7
star
100

elementify

Proof of concept elementify() helper for Cycle.js DOM
TypeScript
7
star