Skip to content

Commit

Permalink
fix: deferred finally uncaught errors (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
hairyf committed May 22, 2023
1 parent 601b80e commit 984a006
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 25 deletions.
24 changes: 13 additions & 11 deletions packages/@react/src/composable/useOverlay.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { delay as _delay, noop } from '@overlays/core'
import { delay, noop } from '@overlays/core'
import type { Dispatch, SetStateAction } from 'react'
import { useContext, useEffect } from 'react'

Expand Down Expand Up @@ -68,22 +68,24 @@ export function useOverlay(options: UseOverlayOptions = {}) {
const { immediate = true, duration = 0, automatic = true } = options
const context = useContext(Context)
const dec = Reflect.get(context, 'in_dec')
const meta = dec ? useDeclarative(options) : context
const overlay = dec ? useDeclarative(options) : context
const { setVisible, vanish, deferred } = overlay

// The component directly obtains the default value
// vanish will have no effect, and no watch will be performed.
async function destroy() {
setVisible(false)
await delay(duration)
vanish?.()
return Promise.resolve()
}
useMount(() => immediate && setVisible(true))
useMount(() => {
immediate && meta.setVisible?.(true)
if (!dec && automatic) {
meta.deferred?.finally(async () => {
meta.setVisible(false)
await _delay(duration)
meta.vanish?.()
})
}
if (!dec && automatic)
deferred?.then(destroy).catch(destroy)
})

return meta as UseOverlayReturn
return overlay as UseOverlayReturn
}

export function useDeclarative(options: UseOverlayOptions = {}) {
Expand Down
12 changes: 9 additions & 3 deletions packages/@svelte/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,18 @@ function instance($$self: any, $$props: any, $$invalidate: any) {
let { visible = false } = $$props
const { duration = 0, immediate = true } = getContext<UseOverlayOptions>(injectOptionsKey) || {}
const { deferred, vanish } = getContext<UseOverlayReturn>(injectOverlayKey)
deferred?.finally(async () => {

// The component directly obtains the default value
// vanish will have no effect, and no watch will be performed.
async function destroy() {
$$invalidate(0, visible = false)
await delay(duration)
vanish()
})
vanish?.()
return Promise.resolve()
}
onMount(() => immediate && $$invalidate(0, visible = true))
deferred?.then(destroy).catch(destroy)

$$self.$$set = ($$props2: any) => {
if ('visible' in $$props2)
$$invalidate(0, visible = $$props2.visible)
Expand Down
23 changes: 12 additions & 11 deletions packages/@vue/src/composable/useOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,26 @@ export interface UseOverlayReturn {
*/
export function useOverlay(options: UseOverlayOptions = {}) {
const { duration = 0, immediate = true, model = 'visible', automatic = true } = options
const meta = inject(OverlayMetaKey, useDeclarative(model, options))
const dec = Reflect.get(meta, 'in_dec')
const overlay = inject(OverlayMetaKey, useDeclarative(model, options))
const dec = Reflect.get(overlay, 'in_dec')
const { visible, deferred, vanish } = overlay

// The component directly obtains the default value
// vanish will have no effect, and no watch will be performed.
if (!dec && automatic) {
meta.deferred?.finally(async () => {
meta.visible.value = false
await delay(duration)
meta.vanish?.()
})
async function destroy() {
visible.value = false
await delay(duration)
vanish?.()
return Promise.resolve()
}

if (!dec && automatic)
deferred?.then(destroy).catch(destroy)
if (!dec && immediate)
onMounted(() => meta.visible.value = true)
onMounted(() => visible.value = true)

provide(OverlayMetaKey, null)

return meta
return overlay
}

export function useDeclarative(model: string, options: UseOverlayOptions = {}) {
Expand Down

0 comments on commit 984a006

Please sign in to comment.