Squash the current repository state back into one baseline commit while preserving the README reframing and repository contents. Constraint: User explicitly requested a single squashed commit with subject "asdf" Confidence: high Scope-risk: broad Reversibility: clean Directive: This commit intentionally rewrites published history; coordinate before future force-pushes Tested: git status clean; local history rewritten to one commit; force-pushed main to origin and instructkr Not-tested: Fresh clone verification after push
42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
import { useEffect, useRef } from 'react'
|
|
import { getIsRemoteMode } from '../../bootstrap/state.js'
|
|
import {
|
|
type Notification,
|
|
useNotifications,
|
|
} from '../../context/notifications.js'
|
|
import { logError } from '../../utils/log.js'
|
|
|
|
type Result = Notification | Notification[] | null
|
|
|
|
/**
|
|
* Fires notification(s) once on mount. Encapsulates the remote-mode gate and
|
|
* once-per-session ref guard that was hand-rolled across 10+ notifs/ hooks.
|
|
*
|
|
* The compute fn runs exactly once on first effect. Return null to skip,
|
|
* a Notification to fire one, or an array to fire several. Sync or async.
|
|
* Rejections are routed to logError.
|
|
*/
|
|
export function useStartupNotification(
|
|
compute: () => Result | Promise<Result>,
|
|
): void {
|
|
const { addNotification } = useNotifications()
|
|
const hasRunRef = useRef(false)
|
|
const computeRef = useRef(compute)
|
|
computeRef.current = compute
|
|
|
|
useEffect(() => {
|
|
if (getIsRemoteMode() || hasRunRef.current) return
|
|
hasRunRef.current = true
|
|
|
|
void Promise.resolve()
|
|
.then(() => computeRef.current())
|
|
.then(result => {
|
|
if (!result) return
|
|
for (const n of Array.isArray(result) ? result : [result]) {
|
|
addNotification(n)
|
|
}
|
|
})
|
|
.catch(logError)
|
|
}, [addNotification])
|
|
}
|