Stores are observable objects that contain a value.
Each store has a subscribe() method which allows the execution of a callable whenever the value of the store changes, this callable provides the new value of the store as a parameter.
Stores can be of 2 types:
- Readable stores
- Writable stores
Both stores implement the subscribe and get methods, but only the Writable store implements the set method.
namespace CatPaw\Store;
/**
* @param mixed $value The initial value of the store
* @return Writable
*/
function writable($value);
A writable store's value can be set on creation or some time after by using the set() method.
<?php
use function CatPaw\Store\writable;
function main() {
$store = writable("A"); //set on creation
echo $store->get().PHP_EOL; //will print "A"
$store->set("B"); //changing the value
echo $store->get().PHP_EOL; //will print "B"
}
As mentioned above stores provide a subscribe() method.
This method makes it possible to watch over the value of the store.
Once called, the subscribe() method will return itself a function, which when called will cancel the store subscription.
<?php
use function CatPaw\Store\writable;
function main() {
$store = writable("A");
$unsubscribe = $store->subscribe(function($value) {
echo $value.PHP_EOL;
});
$store->set("B");
$unsubscribe();
// Unsubscribing here means the
// following `$store->set("C")` call
// will not trigger any subscribers.
$store->set("C");
}
The above code will print
A
B
to the console.
It won't print C because by the time C is set, $unsubscribe() has already been invoked.
namespace CatPaw\Store;
/**
* @param mixed $value initial value of the store
* @param false|Closure $start
* @return Readable
*/
function readable($value, $start = false);
A readable store is very similar to a writable store.
Two things differentiate a readable store from a writable one:
- A readable store does not offer a public set() method.
- A readable store requires a start callable when created, this callable will be invoked when the first subscriber subscribes to the store.
The start callable takes 1 parameter and should return a function.
- The parameter is a $set function which can be used to set the store's value.
- The function it returns is a cleanup function.
It will be invoked when there are no subscribers left.
- The parameter is a $set function which can be used to set the store's value.
<?php
use function CatPaw\Store\readable;
use function CatPaw\Store\writable;
function main() {
$unsubscribers = [];
$counter = writable(0);
$unsubscribeAll = function() use (&$unsubscribers) {
foreach ($unsubscribers as $unsubscribe) {
$unsubscribe();
}
};
$store = readable("default", function($set) {
$set("hello world");
return function() {
echo "All subscribers have unsubscribed\n";
};
});
$unsubscribers[] = $store->subscribe(function($value) use (&$counter) {
$counter->set($counter->get() + 1);
echo "new value received: $value".PHP_EOL;
});
$unsubscribers[] = $store->subscribe(function($value) use (&$counter) {
$counter->set($counter->get() + 1);
echo "new value received: $value".PHP_EOL;
});
$unsubscribers[] = $store->subscribe(function($value) use (&$counter) {
$counter->set($counter->get() + 1);
echo "new value received: $value".PHP_EOL;
});
$counter->subscribe(function(int $counter) use($unsubscribeAll) {
if($counter < 6){
return;
}
$unsubscribeAll();
});
}
this code will output
new value received: default
new value received: default
new value received: default
new value received: hello world
new value received: hello world
new value received: hello world
All subscribers have unsubscribed