Skip to content

Commit

Permalink
feat(syncRef): fix infinite sync
Browse files Browse the repository at this point in the history
  • Loading branch information
chaii3 committed Aug 13, 2023
1 parent 48f4c6e commit 76294db
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
8 changes: 4 additions & 4 deletions packages/shared/syncRef/index.test.ts
Expand Up @@ -51,26 +51,26 @@ describe('syncRef', () => {

it('works with mutual convertors', () => {
const left = ref(10)
const right = ref(1)
const right = ref(2)

syncRef(left, right, {
transform: {
ltr: left => left * 2,
rtl: right => Math.round(right / 2),
rtl: right => Math.floor(right / 3),
},
})

// check immediately sync
expect(right.value).toBe(20)
expect(left.value).toBe(10)
expect(left.value).toBe(6)

left.value = 30
expect(right.value).toBe(60)
expect(left.value).toBe(30)

right.value = 10
expect(right.value).toBe(10)
expect(left.value).toBe(5)
expect(left.value).toBe(3)
})

it('works with only rtl convertor', () => {
Expand Down
30 changes: 20 additions & 10 deletions packages/shared/syncRef/index.ts
@@ -1,5 +1,6 @@
import type { Ref, WatchStopHandle } from 'vue-demi'
import { watch } from 'vue-demi'
import { pausableWatch } from '@vueuse/core'
import type { WatchPausableReturn } from '@vueuse/core'
import type { Ref } from 'vue-demi'
import type { ConfigurableFlushSync } from '../utils'

export interface SyncRefOptions<L, R = L> extends ConfigurableFlushSync {
Expand Down Expand Up @@ -37,6 +38,7 @@ export interface SyncRefOptions<L, R = L> extends ConfigurableFlushSync {
*
* @param left
* @param right
* @param options
*/
export function syncRef<L, R = L>(left: Ref<L>, right: Ref<R>, options: SyncRefOptions<L, R> = {}) {
const {
Expand All @@ -47,30 +49,38 @@ export function syncRef<L, R = L>(left: Ref<L>, right: Ref<R>, options: SyncRefO
transform = {},
} = options

let watchLeft: WatchStopHandle
let watchRight: WatchStopHandle
let watchLeft: WatchPausableReturn
let watchRight: WatchPausableReturn

const transformLTR = transform.ltr ?? (v => v)
const transformRTL = transform.rtl ?? (v => v)

if (direction === 'both' || direction === 'ltr') {
watchLeft = watch(
watchLeft = pausableWatch(
left,
newValue => right.value = transformLTR(newValue) as R,
(newValue) => {
watchRight?.pause()
right.value = transformLTR(newValue) as R
watchRight?.resume()
},
{ flush, deep, immediate },
)
}

if (direction === 'both' || direction === 'rtl') {
watchRight = watch(
watchRight = pausableWatch(
right,
newValue => left.value = transformRTL(newValue) as L,
(newValue) => {
watchLeft?.pause()
left.value = transformRTL(newValue) as L
watchLeft?.resume()
},
{ flush, deep, immediate },
)
}

return () => {
watchLeft?.()
watchRight?.()
watchLeft?.stop()
watchRight?.stop()
}
}

0 comments on commit 76294db

Please sign in to comment.