fix type errors in autosave utils

keep the code around in case we revisit later
This commit is contained in:
Justin Edmund 2025-12-11 19:04:13 -08:00
parent 97bdccd218
commit 640a0d1c19
2 changed files with 59 additions and 8 deletions

View file

@ -70,6 +70,9 @@ export function createAutoSaveStore<TPayload, TResponse = unknown>(
function schedule() {
if (timer) clearTimeout(timer)
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug(`[AutoSave] Scheduled (${debounceMs}ms debounce)`)
}
timer = setTimeout(() => void run(), debounceMs)
}
@ -80,24 +83,44 @@ export function createAutoSaveStore<TPayload, TResponse = unknown>(
}
const payload = opts.getPayload()
if (!payload) return
if (!payload) {
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Skipped: getPayload returned null/undefined')
}
return
}
const hash = safeHash(payload)
if (lastSentHash && hash === lastSentHash) return
if (lastSentHash && hash === lastSentHash) {
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Skipped: payload unchanged (hash match)')
}
return
}
if (controller) controller.abort()
controller = new AbortController()
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Saving...', { hashChanged: lastSentHash !== hash })
}
setStatus('saving')
lastError = null
try {
const res = await opts.save(payload, { signal: controller.signal })
lastSentHash = hash
setStatus('saved')
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Saved successfully')
}
if (opts.onSaved) opts.onSaved(res, { prime })
} catch (e: unknown) {
if (e?.name === 'AbortError') {
} catch (e) {
if (e instanceof Error && e.name === 'AbortError') {
// Newer save superseded this one
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Aborted: superseded by newer save')
}
return
}
if (typeof navigator !== 'undefined' && navigator.onLine === false) {
@ -105,7 +128,10 @@ export function createAutoSaveStore<TPayload, TResponse = unknown>(
} else {
setStatus('error')
}
lastError = e?.message || 'Auto-save failed'
lastError = e instanceof Error ? e.message : 'Auto-save failed'
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
console.debug('[AutoSave] Error:', lastError)
}
}
}

View file

@ -10,6 +10,7 @@
lastSavedAt?: Date | string | null
showTimestamp?: boolean
compact?: boolean
onclick?: () => void
}
let {
@ -19,7 +20,8 @@
error: errorProp,
lastSavedAt,
showTimestamp = true,
compact = true
compact = true,
onclick
}: Props = $props()
// Support both old subscription-based stores and new reactive values
@ -81,12 +83,19 @@
</script>
{#if label}
<div class="autosave-status" class:compact>
<button
type="button"
class="autosave-status"
class:compact
class:clickable={!!onclick && status !== 'saving'}
onclick={onclick}
disabled={status === 'saving'}
>
{#if status === 'saving'}
<span class="spinner" aria-hidden="true"></span>
{/if}
<span class="text">{label}</span>
</div>
</button>
{/if}
<style lang="scss">
@ -96,10 +105,26 @@
gap: 6px;
color: $gray-40;
font-size: 0.875rem;
background: none;
border: none;
padding: 0;
font-family: inherit;
&.compact {
font-size: 0.75rem;
}
&.clickable {
cursor: pointer;
&:hover {
color: $gray-20;
}
}
&:disabled {
cursor: default;
}
}
.spinner {