A live collection
This is the JavaScript used by the first playground preset. Edit and run it in the interactive playground, including its HTML and CSS.
import {BehaviorSubject} from 'rxjs';
import {SourceCache, filter, sort, bind} from '@wieslawsoltes/dynamicdataweb';
const cache=new SourceCache(x=>x.id);
const predicate=new BehaviorSubject(()=>true);
let nextId=9, revision=0;
function render(items){
const body=document.querySelector('#rows'); body.replaceChildren();
for(const item of items){const row=body.insertRow();for(const value of [item.name,item.weight,item.active?'Active':'Paused'])row.insertCell().textContent=value;}
document.querySelector('#count').textContent=items.length+' visible';
}
const subscription=cache.connect().pipe(filter(predicate),sort((a,b)=>a.name.localeCompare(b.name)),bind(render)).subscribe();
cache.edit(updater=>{for(let i=1;i<=8;i++)updater.addOrUpdate({id:i,name:'Module '+i,weight:20+i*9,active:i%3!==0});});
document.querySelector('#filter').onchange=e=>predicate.next(e.target.value==='active'?x=>x.active:e.target.value==='heavy'?x=>x.weight>50:()=>true);
document.querySelector('#batch').onclick=()=>{revision++;cache.edit(updater=>{for(let i=1;i<=8;i++)updater.addOrUpdate({id:i,name:'Module '+i,weight:(i*17+revision*13)%100,active:(i+revision)%3!==0});});console.log('Committed atomic batch',revision);};
document.querySelector('#add').onclick=()=>{const id=nextId++;cache.addOrUpdate({id,name:'Module '+id,weight:64,active:true});};
window.addEventListener('pagehide',()=>{subscription.unsubscribe();predicate.complete();cache.dispose();});
console.log('Filter → sort → bind pipeline connected.');Show the HTML host
<div class="toolbar"><label>Show <select id="filter"><option value="all">All modules</option><option value="active">Active only</option><option value="heavy">Weight over 50</option></select></label><button id="batch">Batch update</button><button id="add">Add item</button><output id="count"></output></div><table><thead><tr><th>Module</th><th>Weight</th><th>Status</th></tr></thead><tbody id="rows"></tbody></table><p class="hint">Generated demonstration data. Filter, sort and binding are computed by DynamicDataWeb.</p>How it works
Respond to changes, not snapshots
Connect to a collection once. Compose the view with operators, then update the source while the pipeline handles propagation.
Install rxjs alongside the library. Use SourceCache for keyed entities and SourceList for ordered values. Subscribe to activate a pipeline.
Own the lifetime
Unsubscribe every owned pipeline, complete your subjects, and dispose the source when its owner goes away.
The playground replaces its entire isolated frame on each run. In your application, use the framework’s unmount or disposal hook instead. Do not dispose a shared model while another view still owns it.
Read the lifecycle guide →Know the contract
Source repositories can contain work newer than the published package. The showcase uses @wieslawsoltes/dynamicdataweb@0.1.1.