diff --git a/src/components/BlueprintViewer.vue b/src/components/BlueprintViewer.vue
index 74f455e..6a9edf6 100644
--- a/src/components/BlueprintViewer.vue
+++ b/src/components/BlueprintViewer.vue
@@ -161,7 +161,8 @@ const funcCount = computed(() => props.blueprint.functions.length)
Lifecycle — state machine
- Composed lifecycleloadState : LoadState
+ {{ blueprint.stateMachine?.caption ?? "Composed lifecycle" }}{{ blueprint.stateMachine?.field ?? "loadState : LoadState" }}
diff --git a/src/components/StateMachine.vue b/src/components/StateMachine.vue
index ffae0fd..1abb9a6 100644
--- a/src/components/StateMachine.vue
+++ b/src/components/StateMachine.vue
@@ -36,9 +36,9 @@ const markers = (Object.keys(SM_COLORS) as (keyof typeof SM_COLORS)[]).map((k) =
}))
const init = computed(() => {
- const loading = byId.value.loading
- const cy = loading.y + loading.h / 2
- const e = edgePoint(loading, 26, cy)
+ const start = byId.value[props.machine.initId ?? "loading"]
+ const cy = start.y + start.h / 2
+ const e = edgePoint(start, 26, cy)
return { cy, path: `M31 ${cy} L ${e[0]} ${e[1]}` }
})
@@ -81,8 +81,27 @@ const KIND_LABELS: Record = {
loadMore: "loadMore()",
navigate: "navigate(δ)",
changeScope: "changeScope(s)",
+ persist: "startPersist()",
+ store: "tokenStored(t)",
+ storeFail: "storeFailed()",
+ revoke: "revoke()",
+ expire: "expired()",
+ clear: "clear()",
}
-const KIND_ORDER: SmKind[] = ["succeed", "fail", "refresh", "loadMore", "navigate", "changeScope"]
+const KIND_ORDER: SmKind[] = [
+ "succeed",
+ "fail",
+ "refresh",
+ "loadMore",
+ "navigate",
+ "changeScope",
+ "persist",
+ "store",
+ "storeFail",
+ "revoke",
+ "expire",
+ "clear",
+]
const legendItems = computed(() => {
const present = new Set(props.machine.edges.map((e) => e.kind))
diff --git a/src/data/blueprint.ts b/src/data/blueprint.ts
index afc6146..b10ec1b 100644
--- a/src/data/blueprint.ts
+++ b/src/data/blueprint.ts
@@ -58,7 +58,20 @@ export interface SmNode {
label: string
}
-export type SmKind = "succeed" | "fail" | "refresh" | "loadMore" | "navigate" | "changeScope"
+export type SmKind =
+ | "succeed"
+ | "fail"
+ | "refresh"
+ | "loadMore"
+ | "navigate"
+ | "changeScope"
+ // RememberMe persistence lifecycle
+ | "persist"
+ | "store"
+ | "storeFail"
+ | "revoke"
+ | "expire"
+ | "clear"
export interface SmEdge {
from: string
@@ -71,6 +84,13 @@ export interface SmEdge {
export interface StateMachine {
nodes: SmNode[]
edges: SmEdge[]
+ // id of the initial state (the [*] arrow points here). Defaults to "loading"
+ // for the LoadState-based machines; RememberMe starts at "notpersisted".
+ initId?: string
+ // Panel caption + field label shown above the diagram. Default to the
+ // composed-LoadState wording; capabilities with their own lifecycle override.
+ caption?: string
+ field?: string
}
export const SM_COLORS: Record = {
@@ -80,6 +100,13 @@ export const SM_COLORS: Record = {
loadMore: "#8fd0ff",
navigate: "#b79cff",
changeScope: "#67d0c0",
+ // RememberMe: green mint / red store-fail / magenta revoke / amber expiry / purple reset
+ persist: "#8fd0ff",
+ store: "#7fdca0",
+ storeFail: "#ff8f8f",
+ revoke: "#ff5c8a",
+ expire: "#ffb84d",
+ clear: "#b79cff",
init: "#4f7099",
}