Skip to content

shadyendless/abstract-mutable-store

 
 

Repository files navigation

Abstract Mutable Store

Unit Tests

Publish

An abstract class for creating a store that is compliant with useSyncExternalStore.

Install

npm install @charliewilco/abstract-mutable-store

Usage

AbstractStore is an abstract class that provides a common interface for creating a store that can be used with the useSyncExternalStore hook in React. It defines a set of methods for reading and updating the store's value, and for subscribing to changes to the store's value.

To use AbstractStore, simply extend the AbstractStore class and implement the required methods:

import { AbstractStore } from "@charliewilco/abstract-mutable-store";

interface State {
	count: number;
}

class CountStore extends AbstractStore<State> {
	constructor() {
		super({ count: 0 });
	}

	increment() {
		this.mutate((draft) => {
			draft.count += 1;
		});
	}

	decrement() {
		this.mutate((draft) => {
			draft.count -= 1;
		});
	}
}

const store = new CountStore();

store.subscribe((state) => {
	console.log(`Count: ${state.count}`);
});

store.increment();
store.increment();
store.decrement();

This is an abstract Class so it's not meant to be called like this:

// 🙄 🛑 DON'T DO THIS
const store = new AbstractStore({ foo: 1 });

With React

import { AbstractStore } from "@charliewilco/abstract-mutable-store";
import { useSyncExternalStore } from "react";
// React v17 or lower
// import { useSyncExternalStore } from "use-sync-external-store"

interface State {
	count: number;
}

class CountStore extends AbstractStore<State> {
	constructor() {
		super({ count: 0 });
	}

	increment() {
		this.mutate((draft) => {
			draft.count += 1;
		});
	}

	decrement() {
		this.mutate((draft) => {
			draft.count -= 1;
		});
	}
}

const store = new CountStore();

function SyncedCount() {
	const { count } = useSyncExternalStore(
		(cb) => store.subscribe(cb),
		() => store.getSnapshot()
	);

	return <h1>Count: {count}</h1>;
}

function App() {
	return (
		<div>
			<SyncedCount />
			<button onClick={() => store.increment()}>Increment</button>
		</div>
	);
}

License

The Unlicense.

About

`useSyncStore` compatible external store.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 87.6%
  • JavaScript 12.4%