npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

stream-lite

v4.0.0

Published

Minimalistic and modular functional reactive programming library with familiar interface and tiny footprint.

Downloads

60

Readme

✨ Features:

  • Extremely small.
  • Familiar interface (mostly replicating RxJS's API)
  • Modular. Add as little or as much functionality as you want
  • Lazy streams (only active once subscribed to)
  • Only "hot" streams
  • Pipeable operators support
  • Fantasy Observable compliant
  • More than 50 operators and factories available

🔧 Installation

Assuming you use npm as your package manager:

npm install --save stream-lite

This package includes both a CommonJS and ES2015 based modules. You can use them from Node environment or if you are building for the browser you can use a module bundler like Webpack, Browserify, or Rollup. If you want to experiment and play around with Amnis without a module bundler or you don't use one - that's OK. The stream-lite npm package includes precompiled production and development UMD builds in the umd folder. You can just drop a UMD build as a <script> tag on a page. The UMD builds make stream-lite available as a window.stream global variable and include all the functionality.

<script type="application/javascript" src="https://unpkg.com/stream-lite"></script>

📦🔨 Import and Usage

The following guide assumes you use ES2015+ but you don't have to. There are a few different ways of importing the functionality that you need.

To import the entire set of functionality:

import Stream from 'stream-lite'
import 'stream/add/all'

Stream
  .of(1,2,3)
  .map(x => x * 2)
  .subscribe(x => console.log(x))

However the stream-lite module encourages shipping only the scripts that you will actually use. One way of doing that is to add to Stream's prototype only the methods you actually need:

import Stream from 'stream-lite'
import 'stream-lite/add/statics/of'
import 'stream-lite/add/operators/map'

Stream
  .of(1,2,3)
  .map(x => x * 2)
  .subscribe(x => console.log(x))

To not add static methods to Stream, you can import them as pure functions:

import {of} from 'stream-lite/statics'
import 'stream-lite/add/operators/map'

of(1,2,3)
  .map(x => x * 2)
  .subscribe(x => console.log(x))

To take this one step further and avoid patching the Stream's prototype altogether, you can use pipeable operators. If you are not familiar with pipeable operators you can learn about them here.

import {of} from 'stream-lite/statics'
import {map, filter} from 'stream-lite/operators'

of(1,2,3).pipe(
  filter(x => x % 2 === 0),
  map(x => x * 2)
)
  .subscribe(x => console.log(x))

The stream-lite core also provides a pipeable subscribe for your convenience. So you can bring the subscribe method inside your pipe and write the code above like so:

import {subscribe} from 'stream-lite'
import {of} from 'stream-lite/statics'
import {map, filter} from 'stream-lite/operators'

of(1,2,3).pipe(
  filter(x => x % 2 === 0),
  map(x => x * 2),
  subscribe(x => console.log(x))
)

Or if you use the proposed JavaScript pipe operator:

import {subscribe} from 'stream-lite'
import {of} from 'stream-lite/statics'
import {map, filter} from 'stream-lite/operators'

of(1,2,3)
  |> filter(x => x % 2 === 0)
  |> map(x => x * 2)
  |> subscribe(x => console.log(x))

Please note: This additional syntax requires transpiler support.

🎉 Size

The stream-lite package is built to bring as little overhead to your project as possible.

core

The core of the library includes the create function and a few prototype methods, like subscribe and pipe. This core is ~1KB gzipped.

common

A common usage will probably include around 15 most common methods and operators, which should bring about 1.8KB to your app if you use tree-shaking. 😍

everything

If for some reason you feel the need to import all available operators and factories, that option is also available. That includes more than 50 operators and factories, and will make your app heavier by about 3.5KB gzipped.

📋 API

The vast majority of factories and operators are too similar to the API of RxJS, so most links will point you to RxJS documentation. However there are some that don't exist in RxJS or ones with a different API. Those are marked with an astrix (*) and their documentation you will find below. Operators marked with 🚩 are also available as statics.

Factories

Methods and Operators

subscribe

You can call it in two different ways: Either passing three callbacks in this following order: next, error, complete.

import {of} from 'stream-lite/statics'

of(1, 2, 3).subscribe(
  x => console.log(x),
  err => console.error("There's an error!", err),
  () => console.log("We're done")
)

Or passing a subscription object with the next, error, complete functions as keys.

import {of} from 'stream-lite/statics'

of(1, 2, 3).subscribe({
  next: x => console.log(x),
  error: err => console.error("There's an error!", err),
  complete: () => console.log("We're done")
})

You can also use a pipeable version of subscribe:

import {subscribe} from 'stream-lite'
import {of} from 'stream-lite/statics'
import {map} from 'stream-lite/operators'

of(1,2,3).pipe(
  map(x => x * 2),
  subscribe(x => console.log(x))
)

create

This is the only thing that is included in the core object exported from stream-lite. Most use-cases for creating a stream involve calling other factory functions, like fromEvent or fromPromise, etc. Those are all abstractions on top of the create factory. Usually you want to use those. However, sometimes you may need more control and the way you achieve that in stream-lite is different from RxJS.

Creating a stream with a producer

A Producer is a simple JavaScript object with start and stop functions. start function will be called when the first subscriber subscribes to it. stop function will be called when the last subscriber unsubscribes or the stream completes or it errors. Here is an example of a producer that is used inside the interval factory (except with step parameter hard-coded):

const producer = {
  counter: 0,
  id: 0,
  start: function(consumer) {
    this.id = setInterval(() => consumer.next(this.counter++), 1000)
  },
  stop: function() {
    clearInterval(this.id)
  }
}

Armed with that producer we can now easily create a new stream:

import {create} from 'stream-lite'

const myIntervalStream = create(producer) 

When subscribed to it will start emitting values every second.

Creating a stream without a producer

Sometimes you just want to create an empty stream and manually push values into it. You can achieve this functionality by calling create with no parameters:

import {create} from 'stream-lite'

const manuallyControlledStream = create() 

manuallyControlledStream.subscribe(x => console.log(x))

manuallyControlledStream.next(1)
manuallyControlledStream.next(2)
// logs 1, 2

This is sort of similar to how you would use RxJs's Subject.

fromArray

Equivalent to calling RxJS's from with an array.

fromObservable

Equivalent to calling RxJS's from with an observable.

error

Same as RxJS's _throw but with a friendlier name.

scan

Mostly equivalent to calling RxJS's scan except currently it requires an initial value parameter.

flatMap

Alias: mergeMap.

Equivalent to RxJS's flatMap without the support for an optional 3rd parameter concurrent.

combine

Simply an alias for combineLatest.

withValue

Allows to emit an extra parameter in addition to one emitted from source stream.

import {subscribe} from 'stream-lite'
import {of} from 'stream-lite/statics'
import {withValue} from 'stream-lite/operators'

of(4)
  |> withValue(x => x / 2)
  |> subscribe(x => console.log(x)) // logs [4, 2]

🙏 License

MIT