Vue
Plexis domains expose a subscribe/snapshot interface that wires naturally into Vue’s reactivity system. This guide shows a minimal composable that initializes a ref from the current snapshot and keeps it up to date on every domain transition.
The composable
Section titled “The composable”domain.subscribe calls its listener with the latest DomainSnapshot on every transition and returns an unsubscribe function. Storing the snapshot in a ref makes it reactive — Vue components that read the ref re-render automatically when it changes. The unsubscribe function is called in onUnmounted to prevent memory leaks when the component is removed.
import { ref, onUnmounted } from 'vue';import type { Ref } from 'vue';import type { Domain, DomainSnapshot } from '@tde.io/plexis';
function useDomain<TContext extends object>( domain: Domain<TContext>,): Ref<DomainSnapshot<TContext>> { const snapshot = ref(domain.snapshot()) as Ref<DomainSnapshot<TContext>>;
const unsubscribe = domain.subscribe((next) => { snapshot.value = next; });
onUnmounted(unsubscribe);
return snapshot;}The composable returns a Ref<DomainSnapshot<TContext>> — { state, context, historyLength } — that stays synchronized with the domain.
Example component
Section titled “Example component”Define the domain once at module scope so all component instances share the same state machine.
import { defineComponent, h } from 'vue';import { ref, onUnmounted } from 'vue';import type { Ref } from 'vue';import { defineDomain, when, on, terminal } from '@tde.io/plexis';import type { Domain, DomainSnapshot } from '@tde.io/plexis';
function useDomain<TContext extends object>( domain: Domain<TContext>,): Ref<DomainSnapshot<TContext>> { const snapshot = ref(domain.snapshot()) as Ref<DomainSnapshot<TContext>>; const unsubscribe = domain.subscribe((next) => { snapshot.value = next; }); onUnmounted(unsubscribe); return snapshot;}
// Define the domain once at module scopetype ToggleCtx = { count: number };
const toggle = defineDomain<ToggleCtx>('toggle', () => { when('off', () => { on('toggle', target('on')); }); when('on', () => {}); return { context: { count: 0 }, initial: 'off' };});
// Component — re-renders on every domain transitionconst ToggleButton = defineComponent({ setup() { const { state, context } = useDomain(toggle); return () => h('div', [ h('p', `State: ${state.value} (toggled ${context.value.count} times)`), h( 'button', { onClick: () => toggle.follow('toggle') }, state.value === 'off' ? 'Turn on' : 'Turn off', ), ]); },});Because the domain is defined outside the component, multiple <ToggleButton /> instances share the same state and their refs all update together when the domain transitions.