NAME

PAGI::Stash - Standalone helper for per-request shared state

SYNOPSIS

use PAGI::Stash;

# Middleware sets shared state for downstream handlers
my $auth_middleware = sub ($app) {
    async sub ($scope, $receive, $send) {
        my $stash = PAGI::Stash->new($scope);
        $stash->set(user => authenticate($scope));
        await $app->($scope, $receive, $send);
    };
};

# Handler reads what middleware stored
async sub ($scope, $receive, $send) {
    my $stash = PAGI::Stash->new($scope);
    my $user  = $stash->get('user');           # dies if missing
    my $theme = $stash->get('theme', 'dark');  # default if missing
    ...
};

DESCRIPTION

PAGI::Stash wraps $scope->{'pagi.stash'} and provides a clean accessor interface with strict key checking. It is a standalone helper not attached to any protocol object.

The strict get() method dies when a key does not exist, catching typos at runtime. Use the two-argument form get($key, $default) for keys that may or may not be present.

The stash lives in the PAGI scope hashref and is shared across all middleware, handlers, and protocol objects processing the same request.

CONSTRUCTOR

new

my $stash = PAGI::Stash->new($scope);
my $stash = PAGI::Stash->new($request);   # any object with ->scope
my $stash = PAGI::Stash->new(@_);          # extra args ignored

Scope-based constructor. Resolves to the $scope->{'pagi.stash'} hashref, creating it lazily if it does not exist. Accepts a scope hashref directly, or any blessed object with a scope() method. Extra positional arguments are silently ignored.

from_data

my $stash = PAGI::Stash->from_data({ user => 'alice' });

Test convenience constructor. Wraps a raw hashref directly as the backing data, bypassing scope resolution.

METHODS

get

my $val  = $stash->get('user');            # strict: dies if missing
my $val  = $stash->get('theme', 'dark');   # permissive: returns default

With one argument, dies if the key does not exist. The error message lists available keys (10 or fewer) or reports the count.

With two arguments, returns the default if the key is missing.

set

$stash->set(user => $u);
$stash->set(user => $u, role => 'admin');
$stash->set(user => $u)->set(role => 'admin');

Sets key-value pairs. Returns $self for chaining. No-ops on zero args. Dies on odd number of args.

exists

if ($stash->exists('user')) { ... }

Returns true (1) if the key exists, false (0) otherwise.

delete

$stash->delete('user');
$stash->delete('user', 'role', 'debug');

Removes one or more keys. Returns $self for chaining.

keys

my @keys = $stash->keys;

Returns all keys in the stash.

slice

my %subset = $stash->slice('user', 'role', 'theme');

Returns a hash of key-value pairs for the requested keys. Missing keys are silently skipped.

data

my $href = $stash->data;
$href->{user} = $val;

Returns the raw backing hashref. Mutations are visible through get()/set() since they operate on the same reference.

SEE ALSO

PAGI::Session - Session data helper with the same accessor conventions