mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
more targeted refresh
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { TimelineRefreshController } from './timeline-refresh'
|
||||
|
||||
describe('TimelineRefreshController', () => {
|
||||
it('refreshes only the currently registered route target', () => {
|
||||
const controller = new TimelineRefreshController()
|
||||
const first = vi.fn()
|
||||
const second = vi.fn()
|
||||
const unregisterFirst = controller.register(first)
|
||||
const unregisterSecond = controller.register(second)
|
||||
|
||||
expect(controller.refresh()).toBe(true)
|
||||
expect(first).not.toHaveBeenCalled()
|
||||
expect(second).toHaveBeenCalledOnce()
|
||||
|
||||
// A stale route cleanup cannot remove the current route's target.
|
||||
unregisterFirst()
|
||||
expect(controller.refresh()).toBe(true)
|
||||
expect(second).toHaveBeenCalledTimes(2)
|
||||
|
||||
unregisterSecond()
|
||||
expect(controller.refresh()).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* The active route's primary timeline refresh.
|
||||
*
|
||||
* App owns one controller and routes register while mounted. The guarded
|
||||
* cleanup matters during navigation: an old route must not clear a newer
|
||||
* route's callback if Svelte mounts the replacement before destroying it.
|
||||
*/
|
||||
import { getContext, setContext } from 'svelte'
|
||||
|
||||
export type TimelineRefresh = () => void
|
||||
|
||||
export class TimelineRefreshController {
|
||||
private current: TimelineRefresh | null = null
|
||||
|
||||
register(refresh: TimelineRefresh): () => void {
|
||||
this.current = refresh
|
||||
return () => {
|
||||
if (this.current === refresh) this.current = null
|
||||
}
|
||||
}
|
||||
|
||||
refresh(): boolean {
|
||||
if (!this.current) return false
|
||||
this.current()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export const TIMELINE_REFRESH = Symbol('plspace.timeline-refresh')
|
||||
|
||||
export function provideTimelineRefresh(): TimelineRefreshController {
|
||||
const controller = new TimelineRefreshController()
|
||||
setContext(TIMELINE_REFRESH, controller)
|
||||
return controller
|
||||
}
|
||||
|
||||
/** Routes remain independently renderable in tests without this context. */
|
||||
export function useTimelineRefresh(): TimelineRefreshController | null {
|
||||
return getContext<TimelineRefreshController | undefined>(TIMELINE_REFRESH) ?? null
|
||||
}
|
||||
Reference in New Issue
Block a user