Skip to content

Latest commit

 

History

History
executable file
·
150 lines (119 loc) · 3.98 KB

Stores.md

File metadata and controls

executable file
·
150 lines (119 loc) · 3.98 KB

Stores

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.

writable()

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.

readable()

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:

  1. A readable store does not offer a public set() method.
  2. 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.
<?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