A library to create type-safe readonly stacks
import { createKey, Stack } from "@dldc/stack";
// 1. Create a key with a name and a type
const NumKey = createKey<number>("Num");
// 2. Create a stack
const stack = new Stack();
// 3. Add a value to the stack using the key (Stack is immutable, it returns a new instance)
const stack2 = stack.with(NumKey.Provider(42));
// 4. Get the value from the stack using the key
expect(stack2.get(NumKey.Consumer)).toBe(42);
deno add jsr:@dldc/stack
To write a value to a stack, you need to create a Key
with a name and a type.
const NumKey = createKey<number>("Num");
A key is a object with three properties:
Provider
: a function used to write a value to a stackConsumer
: an object used to read a value from a stackReset
: an object used to reset a value from a stack
You can also create an empty key that will not have a value:
const EmptyKey = createEmptyKey("Empty");
Note: get()
will always return undefined
for an empty key, use has()
to
check if the key is defined.
Finally you ca define a default value for a key:
const NumKey = createKeyWithDefault<number>("Num", 42);
This key will always return a value if you try to get it from a stack (either the value that was set or the default value).
To create a new empty stack you can instantiate a new Stack
:
const stack = new Stack();
Note: The Stack constructor accept one argument, but you should NEVER use it as it is an internal implementation detail !
To write a value to a stack, you need to use the Provider
of a key and pass
it's result to the with()
method of your Stack
instance.
const stack2 = stack.with(NumKey.Provider(42));
The with()
method will return a new instance of Stack
with the new value.
The original stack
is not modified.
You can pass multiple providers to the with()
method:
const stack2 = stack.with(NumKey.Provider(42), EmptyKey.Provider());
To read a value from a stack, you need to use the Consumer
of a key and pass
it to get()
method of your Stack
instance.
const value = stack.get(NumKey.Consumer);
This will return the value that was set using the Provider
of the key or
undefined
if no value was set and the key does not have a default value.
If you expect the Key to be defined you can use the getOrFail()
method:
const value = stack.getOrFail(NumKey.Consumer);
If the key does not have a default value and no value was set, this will throw an error.
If you only want to know if a value was set, you can use the has()
method:
const hasValue = stack.has(NumKey.Consumer);
This will return true
if a value was set using the Provider
.
To reset a value from a stack, you need to use the Reset
of a key and pass it
to the with()
method of your Stack
instance.
const stack2 = stack.with(NumKey.Reset);
This will return a new instance of Stack
with the value removed. The original
stack
is not modified.
Calling has()
on a key that was reset will return false
.
Note: The stack will still hold a reference to the previous values, so don't
rely on Reset
for garbage collection. If you really need to, you can call
.dedupe()
on the stack to remove all the references to the previous values.
To inspect the content of a stack, you can use the inspect()
method. It will
return a string representation of the stack.
Note: The toString()
of a Stack
will always return Stack { ... }
, if you
want to inspect the content of a stack, you need to use the inspect()
method.
By default the inspect()
method will print a serialized version of the values
contained in the stack. You can customize this behavior by providing a
serialize
function as the last argument of createKey()
or
createKeyWithDefault()
.
const NumKey = createKey<number>("Num", (value) => value.toFixed(2));
const stack = new Stack().with(NumKey.Provider(42));
console.log(stack.inspect());
// Stack { Num: 42.00 }
This library uses @dldc/erreur to handle errors.
You can create your own Stack
, this is useful to define custom properties and
methods.
class CustomStack extends Stack {
// You need to override the `instantiate` method to return a new instance of your CustomStack
protected override instantiate(stackCore: StackCoreValue): this {
return new CustomStack(stackCore) as any;
}
}
const custom = new CustomStack();
expect(custom instanceof CustomStack).toBe(true);
expect(custom instanceof Stack).toBe(true);
For more advanced use cases, see
the definition of ZenContext
in @dldc.serve