Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
A lightweight, zero dependency, RxJS-inspired library implementing the Observer pattern in JavaScript. Features AbortController-based unsubscription, supporting both synchronous and asynchronous producers.
@xan/observer
A set of tooling that encapsulates the Observer pattern in JavaScript taking inspiration from RxJS
Build
Automated by JSR
Publishing
Automated by .github\workflows\publish.yml.
Running unit tests
Run deno task test or deno task test:ci to execute the unit tests via
Deno.
Glossary And Semantics
When discussing and documenting observers, it's important to have a common language and a known set of rules around what is going on. This document is an attempt to standardize these things so we can try to control the language in our docs, and hopefully other publications about this library, so we can discuss reactive programming with this library on consistent terms.
While not all of the documentation for this library reflects this terminology, it is a goal of the team to ensure it does, and to ensure the language and names around the library use this document as a source of truth and unified language.
Major Entities
There are high level entities that are frequently discussed.
Consumer
Any system or thing that is being notified of producer notifications.
Producer
Any system or thing that is the source of values that are being pushed to the consumer.
This can be a wide variety of things, from a Promise to a simple iteration over an Array.
Subscription
A contract where a consumer is observing values pushed by a producer.
Major Actions
There are specific actions and events that occur between major entities in the library that need to be defined. These major actions are the highest level events that occur within various parts of the library.
Observation
A consumer reacting to producer notifications.
Major Concepts
Some of what we discuss is conceptual. These are mostly common traits of behaviors that can manifest in push-based reactive systems.
Multicast
The act of one producer being observed by many consumers.
Unicast
The act of one producer being observed by only one consumer.
Push
Observers are a push-based type. That means rather than having the consumer call a function or perform some other action to get a value, the consumer receives values as soon as the producer has produced them, via a registered next handler.
Pull
Pull-based systems are the opposite of push-based. In a pull-based type or system, the consumer must request each value the producer has produced manually, perhaps long after the producer has actually done so. Examples of such systems are Functions and Iterators
Other Concepts
Unhandled Errors
An "unhandled error" is any error that is not handled by a consumer-provided function, which is generally provided during the subscribe action. If no error handler was provided, the library will assume the error is "unhandled" and rethrow the error on a new callstack to prevent "producer interference".
Producer Interference
Producer interference happens when an error is allowed to unwind the library's callstack during notification. When this happens, the error could break things like for-loops in upstream sources that are notifying consumers during a multicast. That would cause the other consumers in that multicast to suddenly stop receiving values without logical explanation. The library goes out of its way to prevent producer interference by ensuring that all unhandled errors are thrown on a separate callstack.
Add Package
deno add jsr:@xan/observer
Import symbol
import * as observer from "@xan/observer";
Import directly with a jsr specifier
import * as observer from "jsr:@xan/observer";
Add Package
pnpm i jsr:@xan/observer
pnpm dlx jsr add @xan/observer
Import symbol
import * as observer from "@xan/observer";
Add Package
yarn add jsr:@xan/observer
yarn dlx jsr add @xan/observer
Import symbol
import * as observer from "@xan/observer";
Add Package
vlt install jsr:@xan/observer
Import symbol
import * as observer from "@xan/observer";
Add Package
npx jsr add @xan/observer
Import symbol
import * as observer from "@xan/observer";
Add Package
bunx jsr add @xan/observer
Import symbol
import * as observer from "@xan/observer";