Skip to content

ā¬…ļø Back to Table of Contents

šŸ“„ syncRef

šŸ“Š Analysis Summary

Metric Count
šŸ”§ Functions 2
šŸ“¦ Imports 4
šŸ“ Interfaces 2
šŸ“‘ Type Aliases 12

šŸ“š Table of Contents

šŸ› ļø File Location:

šŸ“‚ packages/shared/syncRef/index.ts

šŸ“¦ Imports

Name Source
Ref vue
ConfigurableFlushSync ../utils
WatchPausableReturn ../watchPausable
watchPausable ../watchPausable

Functions

syncRef(left: Ref<L>, right: Ref<R>, [options]: Equal<L, R> extends true ? [options?: S…): () => void

Two-way refs synchronization. From the set theory perspective to restrict the option's type Check in the following order: 1. L = R 2. L ∩ R ≠ āˆ… 3. L āŠ† R 4. L ∩ R = āˆ…

Raw JSDoc
/**
 * Two-way refs synchronization.
 * From the set theory perspective to restrict the option's type
 * Check in the following order:
 * 1. L = R
 * 2. L ∩ R ≠ āˆ…
 * 3. L āŠ† R
 * 4. L ∩ R = āˆ…
 */

Calls:

  • watchers.push
  • watchPausable (from ../watchPausable)
  • watchers.forEach
  • w.pause
  • transformLTR
  • w.resume
  • transformRTL
  • w.stop
Code
export function syncRef<L, R, D extends Direction = 'both'>(
  left: Ref<L>,
  right: Ref<R>,
  ...[options]: Equal<L, R> extends true
    ? [options?: SyncRefOptions<L, R, D>]
    : [options: SyncRefOptions<L, R, D>]
) {
  const {
    flush = 'sync',
    deep = false,
    immediate = true,
    direction = 'both',
    transform = {},
  } = options || {}

  const watchers: WatchPausableReturn[] = []

  const transformLTR = ('ltr' in transform && transform.ltr) || (v => v)
  const transformRTL = ('rtl' in transform && transform.rtl) || (v => v)

  if (direction === 'both' || direction === 'ltr') {
    watchers.push(watchPausable(
      left,
      (newValue) => {
        watchers.forEach(w => w.pause())
        right.value = transformLTR(newValue) as R
        watchers.forEach(w => w.resume())
      },
      { flush, deep, immediate },
    ))
  }

  if (direction === 'both' || direction === 'rtl') {
    watchers.push(watchPausable(
      right,
      (newValue) => {
        watchers.forEach(w => w.pause())
        left.value = transformRTL(newValue) as L
        watchers.forEach(w => w.resume())
      },
      { flush, deep, immediate },
    ))
  }

  const stop = () => {
    watchers.forEach(w => w.stop())
  }

  return stop
}

Internal helpers

Declared inside another function in this file.

stop(): void

Returns: void

Calls:

  • watchers.forEach
  • w.stop
Code
() => {
    watchers.forEach(w => w.stop())
  }

Interfaces

EqualType<D extends Direction, L, R, O extends keyof Transform<L, R> = D extends 'both' ? 'ltr' | 'rtl' : D>

Interface Code
interface EqualType<
  D extends Direction,
  L,
  R,
  O extends keyof Transform<L, R> = D extends 'both' ? 'ltr' | 'rtl' : D,
> {
  transform?: SpecificFieldPartial<Pick<Transform<L, R>, O>, O>
}

Properties

Name Type Optional Description
transform SpecificFieldPartial<Pick<Transform<L, R>, O>, O> āœ“ not shown

Transform<L, R>

Interface Code
interface Transform<L, R> {
  ltr: (left: L) => R
  rtl: (right: R) => L
}

Properties

Name Type Optional Description
ltr (left: L) => R āœ— not shown
rtl (right: R) => L āœ— not shown

Type Aliases

Direction

type Direction = 'ltr' | 'rtl' | 'both';

SpecificFieldPartial<T, K extends keyof T>

type SpecificFieldPartial<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;

Equal<A, B>

/* * A = B /

type Equal<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false;

IntersectButNotEqual<A, B>

/* * A ∩ B ≠ āˆ… /

type IntersectButNotEqual<A, B> = Equal<A, B> extends true
  ? false
  : A & B extends never
    ? false
    : true;

IncludeButNotEqual<A, B>

/* * A āŠ† B /

type IncludeButNotEqual<A, B> = Equal<A, B> extends true
  ? false
  : A extends B
    ? true
    : false;

NotIntersect<A, B>

/* * A ∩ B = āˆ… /

type NotIntersect<A, B> = Equal<A, B> extends true
  ? false
  : A & B extends never
    ? true
    : false;

StrictIncludeMap<IncludeType extends 'LR' | 'RL', D extends Exclude<Direction, 'both'>, L, R>

type StrictIncludeMap<IncludeType extends 'LR' | 'RL', D extends Exclude<Direction, 'both'>, L, R> = (Equal<[IncludeType, D], ['LR', 'ltr']>
  & Equal<[IncludeType, D], ['RL', 'rtl']>) extends true
  ? {
      transform?: SpecificFieldPartial<Pick<Transform<L, R>, D>, D>
    } : {
      transform: Pick<Transform<L, R>, D>
    };

StrictIncludeType<IncludeType extends 'LR' | 'RL', D extends Direction, L, R>

type StrictIncludeType<IncludeType extends 'LR' | 'RL', D extends Direction, L, R> = D extends 'both'
  ? {
      transform: SpecificFieldPartial<Transform<L, R>, IncludeType extends 'LR' ? 'ltr' : 'rtl'>
    }
  : D extends Exclude<Direction, 'both'>
    ? StrictIncludeMap<IncludeType, D, L, R>
    : never;

IntersectButNotEqualType<D extends Direction, L, R>

type IntersectButNotEqualType<D extends Direction, L, R> = D extends 'both'
  ? {
      transform: Transform<L, R>
    }
  : D extends Exclude<Direction, 'both'>
    ? {
        transform: Pick<Transform<L, R>, D>
      }
    : never;

NotIntersectType<D extends Direction, L, R>

type NotIntersectType<D extends Direction, L, R> = IntersectButNotEqualType<D, L, R>;

TransformType<D extends Direction, L, R>

type TransformType<D extends Direction, L, R> = Equal<L, R> extends true
  // L = R
  ? EqualType<D, L, R>
  : IncludeButNotEqual<L, R> extends true
    // L āŠ† R
    ? StrictIncludeType<'LR', D, L, R>
    : IncludeButNotEqual<R, L> extends true
      // R āŠ† L
      ? StrictIncludeType<'RL', D, L, R>
      : IntersectButNotEqual<L, R> extends true
        // L ∩ R ≠ āˆ…
        ? IntersectButNotEqualType<D, L, R>
        : NotIntersect<L, R> extends true
          // L ∩ R = āˆ…
          ? NotIntersectType<D, L, R>
          : never;

SyncRefOptions<L, R, D extends Direction>

type SyncRefOptions<L, R, D extends Direction> = ConfigurableFlushSync & {
  /**
   * Watch deeply
   *
   * @default false
   */
  deep?: boolean
  /**
   * Sync values immediately
   *
   * @default true
   */
  immediate?: boolean

  /**
   * Direction of syncing. Value will be redefined if you define syncConvertors
   *
   * @default 'both'
   */
  direction?: D
} & TransformType<D, L, R>;

Generated by Syntax Scribe