From 51177337d384824faa17c769e8f6146c84beb845 Mon Sep 17 00:00:00 2001 From: Guney Saramali Date: Tue, 11 Nov 2025 09:48:09 +0200 Subject: [PATCH] Feat: Unobserve a state - Currently there's set,get, delete and observe method for statemanager - Delete method even though it says halts the observations, it doesn't do it really - I experienced it on a Rangeloop created component that interacts with confirmation dialog and observe state from there. - Observation getting created when dialog was opened and I was deleting it on close, but it looks like they keep observing and interacting with multiple component same way was stacking up the obvervations. - I implemented unobserve method to overcome this and it seems to work. - This is pretty much `subscribe` and `unsubscribe` in angular. --- pkg/app/context.go | 5 +++++ pkg/app/engine.go | 1 + pkg/app/state.go | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/pkg/app/context.go b/pkg/app/context.go index 1e0853e3..86946668 100644 --- a/pkg/app/context.go +++ b/pkg/app/context.go @@ -30,6 +30,7 @@ type Context struct { handleAction func(string, UI, bool, ActionHandler) postAction func(Context, Action) observeState func(Context, string, any) Observer + unObserveState func(Context, string) getState func(Context, string, any) setState func(Context, string, any) State delState func(Context, string) @@ -279,6 +280,10 @@ func (ctx Context) ObserveState(state string, recv any) Observer { return ctx.observeState(ctx, state, recv) } +func (ctx Context) UnObserveState(state string) { + ctx.unObserveState(ctx, state) +} + // GetState fetches the value of a particular state. func (ctx Context) GetState(state string, recv any) { ctx.getState(ctx, state, recv) diff --git a/pkg/app/engine.go b/pkg/app/engine.go index 2e89765e..5e3c9936 100644 --- a/pkg/app/engine.go +++ b/pkg/app/engine.go @@ -90,6 +90,7 @@ func (e *engineX) baseContext() Context { handleAction: e.actions.Handle, postAction: e.actions.Post, observeState: e.states.Observe, + unObserveState: e.states.UnObserve, getState: e.states.Get, setState: e.states.Set, delState: e.states.Delete, diff --git a/pkg/app/state.go b/pkg/app/state.go index 9f479503..717d5fc7 100644 --- a/pkg/app/state.go +++ b/pkg/app/state.go @@ -414,6 +414,17 @@ func (m *stateManager) Delete(ctx Context, state string) { ctx.LocalStorage().Del(state) } +func (m *stateManager) UnObserve(ctx Context, state string) { + m.mutex.Lock() + defer m.mutex.Unlock() + + for src := range m.observers[state] { + if src == ctx.Src() { + delete(m.observers[state], src) + } + } +} + // Cleanup removes observers that are no longer active and cleans up any states // without observers. func (m *stateManager) Cleanup() {