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

lrureplaysubject

v1.0.0

Published

LRUReplaySubject is an RxJS utility that combines an LRU cache with a replay subject, efficiently managing memory by evicting old items while replaying recent events to new subscribers.

Downloads

18

Readme

LRU Replay Subject

Overview

LRUReplaySubject is a specialized implementation of RxJS Subject that combines the functionalities of least-recently-used (LRU) caching with replaying capabilities. This ensures efficient memory usage by retaining frequently accessed items and re-emitting them to new subscribers in descending order of recent usage.

Features

  • LRU Cache Implementation: Efficiently caches and manages data using QuickLRU.
  • Replay Cached Values: Emits cached values to new subscribers.
  • Configurable Cache: Supports maxSize and maxAge limits for the cache.
  • Eviction Notifications: Notifies about evicted items via onEviction.

Installation

npm install lrureplaysubject

Usage

Real-World Example: Stock Price Feed

Let's consider a real-world scenario where you have a real-time stock price feed, and you want to cache and replay the most recent prices to new subscribers.

import { LRUReplaySubject, shareLRUReplay } from 'lrureplaysubject';
import { interval, Subject } from 'rxjs';
import { map, take } from 'rxjs/operators';

// Simulate a real-time stock price feed
const stockPriceFeed = interval(1000).pipe(
    take(10), // Simulate 10 stock price updates
    map(i => ({ symbol: 'AAPL', price: (150 + i).toFixed(2) })) // Generate example stock price data
);

// Create an LRUReplaySubject with custom configuration
const lruReplaySubject = new LRUReplaySubject({
    maxSize: 5, // Keep the last 5 prices
    maxAge: 1000 * 60, // 1 minute
    onEviction: new Subject() // Subject to handle evictions
});

// Log eviction notifications (Optional)
lruReplaySubject.onEviction.subscribe((value) => {
    console.log('Evicted:', value);
});

// Share the observable using LRUReplaySubject
const sharedObservable = stockPriceFeed.pipe(
    shareLRUReplay({
        maxSize: 5,
        maxAge: 1000 * 60 // 1 minute
    })
);

// Subscribe to the shared observable to receive real-time updates
const subscription1 = sharedObservable.subscribe({
    next: value => console.log('[Subscriber 1] Received:', value),
    error: err => console.error('[Subscriber 1] Error:', err),
    complete: () => console.log('[Subscriber 1] Completed')
});

// Simulate a new subscriber joining after some initial values are emitted
setTimeout(() => {
    const subscription2 = sharedObservable.subscribe({
        next: value => console.log('[Subscriber 2] Received:', value),
        error: err => console.error('[Subscriber 2] Error:', err),
        complete: () => console.log('[Subscriber 2] Completed')
    });

    // Clean up the new subscriber
    setTimeout(() => {
        subscription2.unsubscribe();
    }, 7000); // Unsubscribe after 7 seconds
}, 5000); // New subscriber joins after 5 seconds

// Clean up the original subscriber
setTimeout(() => {
    subscription1.unsubscribe();
}, 15000); // Unsubscribe after 15 seconds

Additional Examples from Test Cases

1. Eviction on Exceeding maxSize

import { LRUReplaySubject } from 'lrureplaysubject';
import { Subject } from 'rxjs';

const onEvictionSubject = new Subject();
onEvictionSubject.subscribe(value => {
    console.log('Evicted:', value);
});

const lruSubject = new LRUReplaySubject({ maxSize: 1, onEviction: onEvictionSubject });
lruSubject.next(1); // Adds item 1
lruSubject.next(2); // Item 1 is evicted, item 2 is added

// Subscribe to the subject to receive cached values
lruSubject.subscribe(value => {
    console.log('Received:', value);
});

// Output: "Evicted: 1"
// Output: "Received: 2" (Only item 2 is in the cache)

2. Eviction on Exceeding maxAge

import { LRUReplaySubject } from 'lrureplaysubject';
import { Subject } from 'rxjs';

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const onEvictionSubject = new Subject();
onEvictionSubject.subscribe(value => {
    console.log('Evicted:', value);
});

const lruSubject = new LRUReplaySubject({
    maxSize: 5,
    maxAge: 1000 // 1 second
});

// Add an item and delay to see the effect of maxAge
lruSubject.next({ id: 1, value: 'test1' });

delay(1500).then(() => {
    lruSubject.next({ id: 2, value: 'test2' });

    // Subscribe to the subject to receive cached values
    lruSubject.subscribe(value => {
        console.log('Received:', value);
    });

    // Output: "Evicted: { id: 1, value: 'test1' }"
    // Output: "Received: { id: 2, value: 'test2' }" (Only item 2 is in the cache)
});

API Documentation

Detailed API documentation can be found in API.md.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Homepage

For more information, visit the homepage.