Loading client/src/composables/timeoutStoreDispose.ts 0 → 100644 +30 −0 Original line number Diff line number Diff line import type { Store } from "pinia"; const referenceCountByStore = new WeakMap<Store, number>(); /** * Reference counts a store, and provides a function to safely dispose it after a timeout. * @param store store to reference count and dispose * @param timeout how long to wait before reference counting and attempting a dispose. * @returns dispose function */ export function useTimeoutStoreDispose(store: Store, timeout = 1000) { const currentReferenceCount = referenceCountByStore.get(store) ?? 0; referenceCountByStore.set(store, currentReferenceCount + 1); const disposeIfReferenceFree = () => { const referenceCount = referenceCountByStore.get(store) ?? 0; if (referenceCount <= 0) { store.$dispose(); } }; const dispose = () => { const referenceCount = referenceCountByStore.get(store) ?? 1; referenceCountByStore.set(store, referenceCount - 1); setTimeout(disposeIfReferenceFree, timeout); }; return dispose; } client/src/composables/workflowStores.ts +15 −6 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ import { useWorkflowStateStore } from "@/stores/workflowEditorStateStore"; import { useWorkflowEditorToolbarStore } from "@/stores/workflowEditorToolbarStore"; import { useWorkflowStepStore } from "@/stores/workflowStepStore"; import { useTimeoutStoreDispose } from "./timeoutStoreDispose"; /** * Creates stores scoped to a specific workflowId, and manages their lifetime. * In child components, use `useWorkflowStores` instead. Loading @@ -30,13 +32,20 @@ export function provideScopedWorkflowStores(workflowId: Ref<string> | string) { const toolbarStore = useWorkflowEditorToolbarStore(workflowId.value); const undoRedoStore = useUndoRedoStore(workflowId.value); const disposeConnectionStore = useTimeoutStoreDispose(connectionStore); const disposeStateStore = useTimeoutStoreDispose(stateStore); const disposeStepStore = useTimeoutStoreDispose(stepStore); const disposeCommentStore = useTimeoutStoreDispose(commentStore); const disposeToolbarStore = useTimeoutStoreDispose(toolbarStore); const disposeUndoRedoStore = useTimeoutStoreDispose(undoRedoStore); onScopeDispose(() => { connectionStore.$dispose(); stateStore.$dispose(); stepStore.$dispose(); commentStore.$dispose(); toolbarStore.$dispose(); undoRedoStore.$dispose(); disposeConnectionStore(); disposeStateStore(); disposeStepStore(); disposeCommentStore(); disposeToolbarStore(); disposeUndoRedoStore(); }); return { Loading Loading
client/src/composables/timeoutStoreDispose.ts 0 → 100644 +30 −0 Original line number Diff line number Diff line import type { Store } from "pinia"; const referenceCountByStore = new WeakMap<Store, number>(); /** * Reference counts a store, and provides a function to safely dispose it after a timeout. * @param store store to reference count and dispose * @param timeout how long to wait before reference counting and attempting a dispose. * @returns dispose function */ export function useTimeoutStoreDispose(store: Store, timeout = 1000) { const currentReferenceCount = referenceCountByStore.get(store) ?? 0; referenceCountByStore.set(store, currentReferenceCount + 1); const disposeIfReferenceFree = () => { const referenceCount = referenceCountByStore.get(store) ?? 0; if (referenceCount <= 0) { store.$dispose(); } }; const dispose = () => { const referenceCount = referenceCountByStore.get(store) ?? 1; referenceCountByStore.set(store, referenceCount - 1); setTimeout(disposeIfReferenceFree, timeout); }; return dispose; }
client/src/composables/workflowStores.ts +15 −6 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ import { useWorkflowStateStore } from "@/stores/workflowEditorStateStore"; import { useWorkflowEditorToolbarStore } from "@/stores/workflowEditorToolbarStore"; import { useWorkflowStepStore } from "@/stores/workflowStepStore"; import { useTimeoutStoreDispose } from "./timeoutStoreDispose"; /** * Creates stores scoped to a specific workflowId, and manages their lifetime. * In child components, use `useWorkflowStores` instead. Loading @@ -30,13 +32,20 @@ export function provideScopedWorkflowStores(workflowId: Ref<string> | string) { const toolbarStore = useWorkflowEditorToolbarStore(workflowId.value); const undoRedoStore = useUndoRedoStore(workflowId.value); const disposeConnectionStore = useTimeoutStoreDispose(connectionStore); const disposeStateStore = useTimeoutStoreDispose(stateStore); const disposeStepStore = useTimeoutStoreDispose(stepStore); const disposeCommentStore = useTimeoutStoreDispose(commentStore); const disposeToolbarStore = useTimeoutStoreDispose(toolbarStore); const disposeUndoRedoStore = useTimeoutStoreDispose(undoRedoStore); onScopeDispose(() => { connectionStore.$dispose(); stateStore.$dispose(); stepStore.$dispose(); commentStore.$dispose(); toolbarStore.$dispose(); undoRedoStore.$dispose(); disposeConnectionStore(); disposeStateStore(); disposeStepStore(); disposeCommentStore(); disposeToolbarStore(); disposeUndoRedoStore(); }); return { Loading