Detect when svelte store is not used anymore

I'm making a custom svelte store by wrapping around a svelte writable store.

I want to detect when that store is not subscribed by any component; when the subscription count is 0

My objective is to clear some heavy external resources (websockets) that were tied to the custom store when no one is using it.

Currently, I'm counting the subscriptions and unsubscriptions by wrapping around subscribe( ) method. It works as expected. But It looks like a nasty hack to me.

My question: Is there a standard / clean way to achieve this behavior in Svelte?

If not, can someone with more experience in Javascipt and svelte confirm whether this is legit?

Demo on : https://svelte.dev/repl/f4e24fb5c56f457a94bf9cf645955b9f?version=3.43.1

import { writable } from 'svelte/store';

// Instanciate the store
export let store = MakeStore();

// By design, I want a function that returns a custom svelte store
export function MakeStore(initialValue = null) {

        const { subscribe, set, update } = writable(initialValue);

        let subscribercount = 0;

        let wsubscribe = function (run, callback) {
            subscribercount++;
            console.log("subscribercount++", subscribercount);

            let wunsubscribe = subscribe(run, callback);
            return () => {
                subscribercount--;
                console.log("subscribercount--", subscribercount);

                if (subscribercount == 0) {

                    // -------------------------------
                    // Free up resources
                    // I want a clean way to get here
                    // -------------------------------
                    console.log("Cleaning up...");
                }
                return wunsubscribe();
            }
        }

        // Some external calls here

        let store = {
            subscribe: wsubscribe,
            set: newvalue => {
                set(newvalue);
                // Some external calls here
            },
            update: update
        };

        // Some external calls here

        return store;
    }


1 answer

  • answered 2021-10-12 17:03 Stephane Vanraes

    Yes, it's built into the store and documented here

    from the docs

    If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a set function which changes the value of the store. It must return a stop function that is called when the subscriber count goes from one to zero.

    so you would do for example:

    const count = writable(0, () => {
        console.log('got a subscriber');
        return () => console.log('no more subscribers');
    });
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum