Installations
npm install observable-types
Developer Guide
Typescript
✅ Yes
Module System
ESM
Node Version
18.13.0
NPM Version
8.19.3
Score
64.8
Supply Chain
96.9
Quality
88.3
Maintenance
100
Vulnerability
100
License
Releases
Unable to fetch releases
Bundle Size
5.29 kB
Minified
2.05 kB
Minified + Gzipped
Total Downloads
Cumulative downloads
Total Downloads
689689
Last day
0%
Compared to previous day
Last week
5,700%
Compared to previous week
Last month
-47.7%
Compared to previous month
Last year
0%
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
ObservableTypes
A collection of TypeScript/JavaScript utilities designed to render simple or structured data collections (e.g.: Arrays of strings or Arrays of Objects) in the DOM and manage all sorts of updates in an efficient manner without using a Virtual DOM and minimal boilerplate.
With these you can create reactive collections and manage operations on them in either an imperative or functional style.
This library has reactive bindings exposed through the Observable/Observer interfaces (e.g.: RxJS) and integrates seamlessly with Observable UI libraries such as Rimmel.js which have first-class support for them.
Features
ObservableTypes expose both the Observable and the Observer interfaces (like the Rx.Subject), which makes them suitable for piping, streaming and merging with other reactive event streams.
It also enables you to create data collections where changes are described as event streams.
You can also subscribe to any event stream to feed your collections.
Installation
Install via npm:
1npm install observable-types
Then import it into your project:
1import { Collection, CollectionSink } from 'observable-types';
Key Concepts
Collection
A Collection
is a hybrid construct that implements the Array
, the Observable
and Observer
interfaces.
It behaves just like an Array, with all its standard methods such as push
, pop
, splice
, etc.
These will emit semantic notifications for rendering so they can use them to make changes in a UI in efficient ways without the need to perform any complicated or anyways heavy diffing work. E.G.: .push()
becomes an instruction like "append an item to the bottom of the view".
Additional semantic operations are also available, most notably .move(from, to)
, to enable efficient drag'n'drop operations by only specifying which item needs to move and where.
Basic Example:
1import { Collection } from 'observable-types'; 2 3// Construct an Item from a value 4const Item = (value: string | number) => 5 ({ value, created: Date.now() }); 6 7// Create a simple Collection and pass the 8// Item constructor for type integrity 9const myList = Collection([1, 2, 3], Item); 10 11 12// Create a stream of "unshift" operations. 13// `data` is Observable, so it can be 14// piped and subscribed to. 15const insertions = data.observe('unshift'); 16 17// Do something when items are inserted 18insertions.subscribe((e) => { 19 console.log(`Added`, ...e, ' to the top'); 20}); 21 22 23// Finally, modify the collection 24myArray.unshift('new stuff'); 25// Logs: "Added {value: 'new stuff', ... } to the top" 26 27myArray.push('other stuff'); 28// Logs nothing, as we're only listening for 29// 'unshift' events
Collection API
- assign(newItems: T[]): Replaces the entire array with a new array of items.
- move(src: number, dst: number, count: number): Moves a set of items from one index to another within the collection.
- observe(prop: string): Returns an Observable that emits changes for the specified operation (e.g., 'push', 'splice').
- toArray(): Returns the underlying array as a standard array.
- push(...items: T[]): Adds new items to the end of the collection and emits a reactive update.
CollectionSink
CollectionSink
is an adapter used to render a Collection
into an HTML container and make efficient updates based on the semantic notifications emitted by the Collection
.
Since the Collection
notifications are semantic, they give enough information to render changes in the most efficient way without having to perform any diffing.
All you need is the collection and a template to use for rendering new items.
Observable Types best shine when used with an Observable-aware UI library such as Rimmel, in which connecting an observable stream to the DOM is as trivial as putting it in the template:
Example 1 (with Rimmel templates)
1import { Collection, CollectionSink } from 'observable-types'; 2import { rml, Value } from 'rimmel'; 3 4const Item = (title) => ({ title }); 5const ItemTemplate = item => `<li>${item.title}</li>`; 6const list = Collection([], Item); 7const listView = CollectionSink(list, ItemTemplate); 8 9document.body.innerHTML = rml` 10 <h1>List</h1> 11 <ul> 12 ${listView} 13 </ul> 14 15 <input placeholder="new stuff" onchange="${Value(items)}">Add</button> 16`;
It's not mandatory to use any UI library, though. In fact, you can also live without and imperatively sink an Observable Collection down the DOM by passing it a target node.
Example 2 (with no UI library):
1import type { ObservableItem } from 'observable-types'; 2import { Collection, CollectionSink } from 'observable-types'; 3 4interface I { 5 title: string; 6 timestamp: number; 7} 8 9const Item = (title: string): I => ({ title, timestamp: Date.now() }); 10const ItemTemplate = (item: ObservableItem<I>) => `<li>${item.title}</li>`; 11const items = Collection(['Item 1', 'Item 2'].map(i=>Item(i)), Item); 12const renderer = CollectionSink(items, ItemTemplate); 13 14// Bind to a DOM element 15items.subscribe(renderer.sink(document.querySelector('#app'))); 16 17// Make changes to see them rendered 18setTimeout(() => items.push(Item('Item 3')), 1000); 19setTimeout(() => items.move(0, 1), 2000); 20setTimeout(() => items.pop(), 3000); 21setTimeout(() => items.shift(), 4000);
Playground
Check out the following Kitchen Sink Application where you can play and experiment with the whole feature set
Contributing
Contributions are welcome! Please feel free to open issues or submit pull requests.
Development Setup
Clone the repository.
Install dependencies:
1# Copy code 2npm install 3npm test 4vite
License
This project is licensed under the MIT License.
No vulnerabilities found.
No security vulnerabilities found.
Other packages similar to observable-types
@types/zen-observable
TypeScript definitions for zen-observable
zen-observable-ts
Thin wrapper around zen-observable and @types/zen-observable, to support ESM exports as well as CommonJS exports
@sjz/types-observable
Typings for https://github.com/tc39/proposal-observable
observable-mixin
Makes your types observable