Copy-paste plugins for common cross-cutting concerns. Each recipe is a
self-contained BlacPlugin that you can drop into your app and tweak. All
recipes use only @blac/core imports so they work without any extra
dependencies unless noted.
For the plugin authoring API that every recipe is built on, see
Plugin Authoring. For the official first-party plugins see
Plugin Overview.
Plugins execute in install order. Keep these rules in mind when you compose
several recipes together:
Persistence first. If you layer a logging plugin on top of a
persistence plugin, the logger will see the post-hydration state. That is
usually what you want — logging will then record the initial restored
value rather than the constructor default.
Sinks last. Send-to-server plugins (Sentry, audit log) should be
installed after any transforming or filtering plugins so they see the final
view of the state.
Hook throws are not caught. If onStateChange throws, the exception
propagates synchronously out of the flush and the remaining plugins in the
chain are skipped. Guard any I/O inside a try/catch in your hooks rather
than letting errors bubble.
A hand-rolled localStorage-backed persistence plugin is the same
onCreated + onStateChange shape as the official persistence
plugin, just backed by localStorage instead of
IndexedDB and without the .persist() registration API. Rather than
re-deriving that adapter here, see:
Persistence: custom storage adapter
for the adapter interface, or reach for @blac/plugin-persist with a
localStorage-backed IndexedDbPersistAdapter directly.
The debounced-save recipe below if you want a hand-rolled plugin (no
.persist() API) that batches writes.
Wraps any synchronous write with a debounce so rapid state changes only
trigger one write per quiet window. Useful when state changes on every
keystroke and the save target (IndexedDB, a remote API) is slow.
import{
functiongetPluginManager(): PluginManager
Get the global plugin manager
getPluginManager,
type
(alias) interfaceBlacPlugin
importBlacPlugin
BlaC plugin hook surface.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
BlacPlugin,
type
typePathSet=Set<number>|typeofALL_PATHS
PathSet,
constALL_PATHS:typeofALL_PATHS
ALL_PATHS,
}from'@blac/core';
// --- Recipe: debounced-save wrapper ---
type
typeSaveFn=(key: string,state: unknown)=>void
SaveFn=(
key:string
key: string,
state:unknown
state: unknown)=>void;
interface
interfaceDebouncedSaveOptions
DebouncedSaveOptions{
/**
* Synchronous or async function that does the actual write.
* Called once per quiet window per instance.
*/
DebouncedSaveOptions.save: SaveFn
Synchronous or async function that does the actual write.
Called once per quiet window per instance.
save:
typeSaveFn=(key: string,state: unknown)=>void
SaveFn;
/** Milliseconds of inactivity before flushing. Default: 300. */
DebouncedSaveOptions.debounceMs?:number|undefined
Milliseconds of inactivity before flushing. Default: 300.
debounceMs?: number;
/** Key prefix. Default: "blac". */
DebouncedSaveOptions.prefix?:string|undefined
Key prefix. Default: "blac".
prefix?: string;
/** Optional set of class names to include. Omit to include all. */
DebouncedSaveOptions.include?:string[] |undefined
Optional set of class names to include. Omit to include all.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
BlacPlugin{
const
constdebounceMs: number
debounceMs=
opts:DebouncedSaveOptions
opts.
DebouncedSaveOptions.debounceMs?:number|undefined
Milliseconds of inactivity before flushing. Default: 300.
debounceMs??300;
const
constprefix: string
prefix=
opts:DebouncedSaveOptions
opts.
DebouncedSaveOptions.prefix?:string|undefined
Key prefix. Default: "blac".
prefix??'blac';
const
constincludeSet: Set<string>| null
includeSet=
opts:DebouncedSaveOptions
opts.
DebouncedSaveOptions.include?:string[] |undefined
Optional set of class names to include. Omit to include all.
Fires once per channel flush with the changed PathSet.
paths may be ALL_PATHS when the change spans every path.
prev/next are the coalesced before/after states for the flush.
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c) return;
if (
constincludeSet: Set<string>| null
includeSet&&!
constincludeSet: Set<string>
includeSet.
Set<string>.has(value: string): boolean
@returns ― a boolean indicating whether an element with the specified value exists in the Set or not.
has(
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name)) return;
const
constkey: string
key=`${
constprefix: string
prefix}:${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name}:${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
@returns ― Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
get(
constkey: string
key);
if (
constexisting: number | undefined
existing!==
varundefined
undefined)
functionclearTimeout(id: number | undefined): void
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c) return;
const
constkey: string
key=`${
constprefix: string
prefix}:${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name}:${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
@returns ― Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
get(
constkey: string
key);
if (
constexisting: number | undefined
existing!==
varundefined
undefined) {
// Flush immediately on disposal — don't lose the last state.
functionclearTimeout(id: number | undefined): void
The setItem() method of the Storage interface, when passed a key name and value, will add that key to the given Storage object, or update that key's value if it already exists.
Broadcasts state changes to other browser tabs via BroadcastChannel and
applies incoming updates through the hydration API. Use this when multiple
tabs show the same app and you want them to stay in sync (e.g. a shopping
cart or an auth session).
import{
functiongetPluginManager(): PluginManager
Get the global plugin manager
getPluginManager,
type
(alias) interfaceBlacPlugin
importBlacPlugin
BlaC plugin hook surface.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map((
typeT: StateContainerConstructor<S>
T)=>
typeT: StateContainerConstructor<S>
T.
Function.name: string
Returns the name of the function. Function names are read-only and can not be changed.
name));
let
letchannel: BroadcastChannel | null
channel:
interfaceBroadcastChannel
The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel, except the object that sent the message.
Fires once when the plugin is installed. ctx.container is undefined
here — onInstall is global to the plugin, not per-container.
onInstall(
ctx:PluginContext
ctx){
if (typeof
varBroadcastChannel:{
new(name: string): BroadcastChannel;
prototype: BroadcastChannel;
}
The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel, except the object that sent the message.
The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel, except the object that sent the message.
Returns the value of the first element in the array where predicate is true, and undefined
otherwise.
@param ― predicate find calls predicate once for each element of the array, in ascending
order, until it finds one where predicate returns true. If such an element is found, find
immediately returns that element value. Otherwise, find returns undefined.
@param ― thisArg If provided, it will be used as the this value for each invocation of
predicate. If it is not provided, undefined is used instead.
find(
(
typeT: StateContainerConstructor<S>
T)=>
typeT: StateContainerConstructor<S>
T.
Function.name: string
Returns the name of the function. Function names are read-only and can not be changed.
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.id: string
id!==
constmsg: SyncMessage
msg.
SyncMessage.instanceId: string
instanceId) continue;
const
constkey: string
key=`${
constmsg: SyncMessage
msg.
SyncMessage.className: string
className}:${
constmsg: SyncMessage
msg.
SyncMessage.instanceId: string
instanceId}`;
constreceiving: Set<string>
receiving.
Set<string>.add(value: string): Set<string>
Appends a new element with a specified value to the end of the Set.
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then(()=>
constreceiving: Set<string>
receiving.
Set<string>.delete(value: string): boolean
Removes a specified value from the Set.
@returns ― Returns true if an element in the Set existed and has been removed, or false if the element does not exist.
delete(
constkey: string
key));
}
};
},
BlacPlugin.onUninstall?(): void
onUninstall(){
letchannel: BroadcastChannel | null
channel?.
BroadcastChannel.close(): void
The close() method of the BroadcastChannel interface terminates the connection to the underlying channel, allowing the object to be garbage collected. This is a necessary step to perform as there is no other way for a browser to know that this channel is not needed anymore.
Fires once per channel flush with the changed PathSet.
paths may be ALL_PATHS when the change spans every path.
prev/next are the coalesced before/after states for the flush.
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c||!
letchannel: BroadcastChannel | null
channel) return;
if (!
consttargetNames: Set<string>
targetNames.
Set<string>.has(value: string): boolean
@returns ― a boolean indicating whether an element with the specified value exists in the Set or not.
has(
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.name: string
name)) return;
const
constkey: string
key=`${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.name: string
name}:${
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.id: string
id}`;
if (
constreceiving: Set<string>
receiving.
Set<string>.has(value: string): boolean
@returns ― a boolean indicating whether an element with the specified value exists in the Set or not.
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.name: string
name,
SyncMessage.instanceId: string
instanceId:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<Sextendsobject=any>.id: string
id,
SyncMessage.state: unknown
state:
constpayload: unknown
payload,
};
letchannel: BroadcastChannel
channel.
BroadcastChannel.postMessage(message: any): void
The postMessage() method of the BroadcastChannel interface sends a message, which can be of any kind of Object, to each listener in any browsing context with the same origin. The message is transmitted as a message event targeted at each BroadcastChannel bound to the channel.
Adds a Sentry breadcrumb for each state change. Because breadcrumbs are sent
with every event, this gives you a state-change timeline attached to error
reports — similar to Redux DevTools’ action history but visible in Sentry.
import{getPluginManager}from'@blac/core';
importtype{BlacPlugin,PathSet}from'@blac/core';
import*asSentryfrom'@sentry/browser';
// --- Recipe: Sentry breadcrumb sink ---
interfaceSentryPluginOptions{
/** Classes to include. Omit to include all blocs. */
include?: string[];
/** Classes to exclude. */
exclude?: string[];
/**
* Strip sensitive fields from state before attaching to the breadcrumb.
* Called with the full next state; return the shape you want Sentry to see.
* REQUIRED if your state contains PII, tokens, or health data.
Writes a structured log entry for every state change, creation, and
disposal. Useful for compliance or debugging — you can pipe entries to your
existing logging infrastructure, a remote endpoint, or a circular buffer.
import{
functiongetPluginManager(): PluginManager
Get the global plugin manager
getPluginManager,
type
(alias) interfaceBlacPlugin
importBlacPlugin
BlaC plugin hook surface.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
State-change events carry the PathSet of paths that changed in the flush.
Lifecycle events (onCreated, onDestroyed) are not tied to a state change
and so do not carry paths.
Hook firing model:
onCreated fires synchronously when a container is first acquired.
onStateChange fires once per channel flush (microtask-coalesced).
prev is the state before the first emit of the flush; next is the
state at flush time; paths is the set of paths marked during the flush.
onDestroyed fires synchronously when a container is disposed (after
its system 'dispose' event).
The ref/deps hooks (onRefAcquired, onRefReleased, onDepsChanged) are
devtools-only — they drive devtools-connect and are orthogonal to the
state-change event payload.
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c||!
constallowed:(name: string)=> boolean
allowed(
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Called with each new entry. Wire to console.log, a remote endpoint,
or push into a circular buffer.
onEntry({
AuditEntry.kind: AuditEventKind
kind:'created',
AuditEntry.className: string
className:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name,
AuditEntry.instanceId: string
instanceId:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.id: string
id,
AuditEntry.timestamp: number
timestamp:
varDate: DateConstructor
Enables basic storage and retrieval of dates and times.
Date.
DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).
now(),
AuditEntry.next?:unknown
next:
constsan:(state: unknown,name: string)=> unknown
san(
constc: StateContainer<any, any, any>
c.
StructuralContainer<any>.state: any
state,
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Fires once per channel flush with the changed PathSet.
paths may be ALL_PATHS when the change spans every path.
prev/next are the coalesced before/after states for the flush.
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c||!
constallowed:(name: string)=> boolean
allowed(
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
Called with each new entry. Wire to console.log, a remote endpoint,
or push into a circular buffer.
onEntry({
AuditEntry.kind: AuditEventKind
kind:'state-changed',
AuditEntry.className: string
className:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name,
AuditEntry.instanceId: string
instanceId:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.id: string
id,
AuditEntry.timestamp: number
timestamp:
varDate: DateConstructor
Enables basic storage and retrieval of dates and times.
Date.
DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).
now(),
AuditEntry.prev?:unknown
prev:
constsan:(state: unknown,name: string)=> unknown
san(
prev:Sextendsobject=any
prev,
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name),
AuditEntry.next?:unknown
next:
constsan:(state: unknown,name: string)=> unknown
san(
next:Sextendsobject=any
next,
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name),
AuditEntry.paths?:string[] |undefined
Human-readable changed paths, or "(all)" for a full-replace.
paths:
constchangedPaths: string[]
changedPaths,
});
},
BlacPlugin.onDestroyed?(ctx: PluginContext): void
Fires when a container is disposed.
ctx.container is the disposed container (still queryable, but its
isDisposed is true by the time this fires).
The container this event is about. undefined only for onInstall,
which fires once at plugin install time before any container is known.
container;
if (!
constc: StateContainer<any, any, any>| undefined
c||!
constallowed:(name: string)=> boolean
allowed(
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
Called with each new entry. Wire to console.log, a remote endpoint,
or push into a circular buffer.
onEntry({
AuditEntry.kind: AuditEventKind
kind:'disposed',
AuditEntry.className: string
className:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name,
AuditEntry.instanceId: string
instanceId:
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.id: string
id,
AuditEntry.timestamp: number
timestamp:
varDate: DateConstructor
Enables basic storage and retrieval of dates and times.
Date.
DateConstructor.now(): number
Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).
now(),
AuditEntry.prev?:unknown
prev:
constsan:(state: unknown,name: string)=> unknown
san(
constc: StateContainer<any, any, any>
c.
StructuralContainer<any>.state: any
state,
constc: StateContainer<any, any, any>
c.
StateContainer<any,any,any>.$blac: BlacMeta<any>
Reserved meta namespace: identity (name/id/debug/createdAt),
lifecycle (disposed/dependencies), and the hydration sub-surface.
Own, frozen, branded data property — buildTrackedProxy only intercepts
prototype getters, so this own property and its closure-based getters are
proxy-safe. See
createMeta
.
$blac.
BlacMeta<any>.name: string
name),
});
},
};
}
// Example: log to console with a circular buffer of the last 100 entries.
Called with each new entry. Wire to console.log, a remote endpoint,
or push into a circular buffer.
onEntry(
entry:AuditEntry
entry){
if (
constauditEntries: AuditEntry[]
auditEntries.
Array<T>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.
length>=100)
constauditEntries: AuditEntry[]
auditEntries.
Array<AuditEntry>.shift(): AuditEntry|undefined
Removes the first element from an array and returns it.
If the array is empty, undefined is returned and the array is not modified.
shift();
constauditEntries: AuditEntry[]
auditEntries.
Array<AuditEntry>.push(...items: AuditEntry[]): number
Appends new elements to the end of an array, and returns the new length of the array.
@param ― items New elements to add to the array.
push(
entry:AuditEntry
entry);
varconsole: Console
console.
Console.debug(...data: any[]): void
The console.debug() static method outputs a message to the console at the "debug" log level. The message is only displayed to the user if the console is configured to display debug output. In most cases, the log level is configured within the console UI. This log level might correspond to the Debug or Verbose log level.