{"version":3,"file":"create-effect.mjs","sources":["../../../../src/effects/utils/create-effect.ts"],"sourcesContent":["import {\n    AnyResolvedKeyframe,\n    UnresolvedValueKeyframe,\n} from \"../../animation/types\"\nimport { Schedule } from \"../../frameloop/types\"\nimport { MotionValue } from \"../../value\"\nimport { MotionValueState } from \"../MotionValueState\"\n\n/**\n * Returns true if the effect knows how to write to `subject`.\n */\nexport type EffectTest<Subject extends object> = (\n    subject: unknown\n) => subject is Subject\n\n/**\n * Reads the current value of `key` from `subject`, used as the initial\n * keyframe when `animate()` creates a motion value for the subject.\n * Returns `undefined` when the value can't be read.\n *\n * `keyframes` is the target being animated to, so effects can match\n * the format of the initial value (for instance color vs numeric).\n */\nexport type EffectRead<Subject extends object> = (\n    subject: Subject,\n    key: string,\n    keyframes?: UnresolvedValueKeyframe | UnresolvedValueKeyframe[]\n) => AnyResolvedKeyframe | undefined\n\nexport interface EffectOptions<Subject extends object> {\n    test?: EffectTest<Subject>\n    read?: EffectRead<Subject>\n\n    /**\n     * Frameloop step writes are scheduled in. Defaults to `frame.render`.\n     */\n    step?: Schedule\n}\n\nexport interface Effect<Subject extends object = object>\n    extends EffectOptions<Subject> {\n    (subject: Subject, values: Record<string, MotionValue>): VoidFunction\n\n    /**\n     * Returns the motion value currently bound to `key` on `subject`, if any.\n     */\n    get(subject: Subject, key: string): MotionValue | undefined\n\n    /**\n     * Write `subject`'s pending values now rather than in the next frame,\n     * e.g. so it can be measured with a target applied.\n     */\n    flush(subject: Subject): void\n\n    /**\n     * The state holding the motion values bound to `subject`, if any have\n     * been, so they can be handed to another renderer.\n     */\n    state(subject: Subject): MotionValueState | undefined\n}\n\n/**\n * An effect that can be registered with `animate.addEffect()`.\n */\nexport interface AnimateEffect<Subject extends object = object>\n    extends Effect<Subject> {\n    test: EffectTest<Subject>\n    read: EffectRead<Subject>\n}\n\nexport type AddEffectValue<Subject extends object> = (\n    subject: Subject,\n    state: MotionValueState,\n    key: string,\n    value: MotionValue\n) => VoidFunction\n\nexport function createEffect<Subject extends object>(\n    addValue: AddEffectValue<Subject>,\n    options: EffectOptions<Subject> & {\n        test: EffectTest<Subject>\n        read: EffectRead<Subject>\n    }\n): AnimateEffect<Subject>\nexport function createEffect<Subject extends object>(\n    addValue: AddEffectValue<Subject>,\n    options?: EffectOptions<Subject>\n): Effect<Subject>\nexport function createEffect<Subject extends object>(\n    addValue: AddEffectValue<Subject>,\n    { step, ...options }: EffectOptions<Subject> = {}\n): Effect<Subject> {\n    const stateCache = new WeakMap<Subject, MotionValueState>()\n\n    const effect = (\n        subject: Subject,\n        values: Record<string, MotionValue>\n    ): VoidFunction => {\n        const state = stateCache.get(subject) ?? new MotionValueState(step)\n\n        stateCache.set(subject, state)\n\n        const subscriptions: VoidFunction[] = []\n\n        for (const key in values) {\n            const value = values[key]\n            const remove = addValue(subject, state, key, value)\n            subscriptions.push(remove)\n        }\n\n        return () => {\n            for (const cancel of subscriptions) cancel()\n        }\n    }\n\n    return Object.assign(effect, options, {\n        get: (subject: Subject, key: string) =>\n            stateCache.get(subject)?.get(key),\n        flush: (subject: Subject) => stateCache.get(subject)?.flush(),\n        state: (subject: Subject) => stateCache.get(subject),\n    })\n}\n"],"names":[],"mappings":";;AAwFM,SAAU,YAAY,CACxB,QAAiC,EACjC,EAAE,IAAI,EAAE,GAAG,OAAO,EAAA,GAA6B,EAAE,EAAA;AAEjD,IAAA,MAAM,UAAU,GAAG,IAAI,OAAO,EAA6B;AAE3D,IAAA,MAAM,MAAM,GAAG,CACX,OAAgB,EAChB,MAAmC,KACrB;AACd,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC;AAEnE,QAAA,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;QAE9B,MAAM,aAAa,GAAmB,EAAE;AAExC,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACtB,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC;AACnD,YAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9B;AAEA,QAAA,OAAO,MAAK;YACR,KAAK,MAAM,MAAM,IAAI,aAAa;AAAE,gBAAA,MAAM,EAAE;AAChD,QAAA,CAAC;AACL,IAAA,CAAC;AAED,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE;AAClC,QAAA,GAAG,EAAE,CAAC,OAAgB,EAAE,GAAW,KAC/B,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;AACrC,QAAA,KAAK,EAAE,CAAC,OAAgB,KAAK,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE;QAC7D,KAAK,EAAE,CAAC,OAAgB,KAAK,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;AACvD,KAAA,CAAC;AACN;;;;"}