Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/isaac-mason/linguine
De-spaghettify your event logic! 🍝
https://github.com/isaac-mason/linguine
Last synced: 3 months ago
JSON representation
De-spaghettify your event logic! 🍝
- Host: GitHub
- URL: https://github.com/isaac-mason/linguine
- Owner: isaac-mason
- License: mit
- Created: 2022-12-07T15:14:07.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2023-10-23T03:20:12.000Z (about 1 year ago)
- Last Synced: 2024-01-02T01:14:26.582Z (about 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 821 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# linguine 🍝
De-spaghettify your event logic! Declaratively compose event logic with Topics and Streams.
## Installation
```sh
npm install linguine
yarn add linguine
```## Introduction
Linguine is a library for declaratively composing event logic.
Linguine is built around two concepts: **Topics** and **Streams**.
A **Topic** is something you can write values to. A **Stream** takes values from a Topic and manipulates them. The beauty of linguine is Streams can branch and merge, allowing you to compose complex event logic in a declarative way.
## Simple Example
```ts
import { Topic } from 'linguine'const numberTopic = new Topic()
const doubledNumberTopic = new Topic()const numberStream = numberTopic.stream()
numberStream.map((value) => value * 2).to(doubledNumberTopic)
numberStream.destroy()
```## Streams API
### `map`
Calls the given function for each value in the stream.
```ts
const topic = new Topic()// double each value
topic.stream().map((value) => value * 2)
```### `flatMap`
Calls the given function for each value in the stream, and returns multiple messages. The given function must return an array.
```ts
const topic = new Topic()// return the original value, plus the doubled value
topic.stream().flatMap((value) => [value, value * 2])
```### `filter`
Only pass values through the stream that match a predicate.
```ts
const topic = new Topic()// only pass even numbers through the stream
topic.stream().filter((value) => value % 2 === 0)
```### `forEach`
Call a function on each value in the stream.
```ts
const topic = new Topic()// log each value
topic.stream().forEach((value) => console.log(value))
```### `to`
Write each value in the stream to a topic. This is a terminal operation.
```ts
const inputTopic = new Topic()
const outputTopic = new Topic()// write each value to another topic
topic.stream().to(outputTopic)
```### `merge`
Merge two streams together.
```ts
const topicA = new Topic()
const topicB = new Topic()const streamA = topicA.stream()
const streamB = topicB.stream()// merge the two streams together
const mergedStream = streamA.merge(streamB)
```Merging streams is typesafe! The merged stream's type will be the union of the merged streams.
### `catchError`
Catches errors in the following streams.
```ts
const topic = new Topic()// catch errors in the following streams
topic.stream().catchError((error) => console.error(error))
```### `skipDuplicates`
Skip duplicate values in the stream.
```ts
const topic = new Topic()// skip duplicate values and log the results
topic
.stream()
.skipDuplicates()
.forEach((value) => console.log(value))topic.write(1)
topic.write(1)// stdout:
// `1`
```### `debounce`
Debounce the stream. A message will only be passed through the stream if there are no other messages for a given number of milliseconds.
```ts
const topic = new Topic()// debounce by 1000ms
topic
.stream()
.debounce(1000)
.forEach((value) => console.log(value))// only `2` and `3` will be logged
topic.write(1)
topic.write(2)
setTimeout(() => {
topic.write(3)
}, 1000)
```### `delay`
Delay the stream by a given number of milliseconds.
```ts
const topic = new Topic()// delay by 1000ms
topic
.stream()
.delay(1000)
.forEach((value) => console.log(value))// `1` will be logged after 1000ms
topic.write(1)
```### `throttleByTime`
Throttle the stream by time. Only one message will be passed through the stream every `ms` milliseconds, others will be ignored.
```ts
const topic = new Topic()// only pass one message through the stream every 1000ms
topic
.stream()
.throttleByTime(1000)
.forEach((value) => console.log(value))// only `1` and `3` will be logged
topic.write(1)
topic.write(2)
setTimeout(() => {
topic.write(3)
}, 1000)
```### `bufferByTime`
Buffer messages in the stream by time. Messages will be passed through the stream in batches, with each batch containing messages that were written to the stream within a given number of milliseconds of each other.
```ts
const topic = new Topic()// buffer messages by 1000ms
topic
.stream()
.bufferByTime(1000)
.forEach((values) => console.log(values))topic.write(1)
topic.write(2)
setTimeout(() => {
topic.write(3)
}, 1000)// stdout:
// `[1, 2]`
// `[3]`
```### `bufferByCount`
Buffer messages in the stream by count. Messages will be passed through the stream in batches, with each batch containing a given number of messages.
```ts
const topic = new Topic()// buffer messages in groups of 2
topic
.stream()
.bufferByCount(2)
.forEach((values) => console.log(values))topic.write(1)
topic.write(2)
topic.write(3)// stdout:
// `[1, 2]`
```### `bufferUntil`
Buffer messages in the stream until a given function returns true.
```ts
const topic = new Topic()// buffer messages until the buffer inclues the number 3
topic
.stream()
.bufferUntil((values) => values.includes(3))
.forEach((values) => console.log(values))topic.write(1)
topic.write(2)
topic.write(3)// stdout:
// `[1, 2, 3]`
```### `destroy`
Destroys the stream from the current node.
```ts
const topic = new Topic()
const stream = topic.stream()stream
.map((value) => value * 2)
.forEach((value) => console.log(value))// should log `2`
topic.write(1)// destroy the stream
stream.destroy()// should not log anything
topic.write(1)
```