From ae1292a14bf5c29544a5f7a49e65b994410f87de Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 29 Apr 2026 18:27:21 +0200 Subject: refactor: make mask renderer dispatch explicit Made-with: Cursor --- apps/web/src/masks/registry.ts | 68 ++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 42 deletions(-) (limited to 'apps/web/src/masks/registry.ts') diff --git a/apps/web/src/masks/registry.ts b/apps/web/src/masks/registry.ts index 0bcf1cf0..64ab2f60 100644 --- a/apps/web/src/masks/registry.ts +++ b/apps/web/src/masks/registry.ts @@ -2,11 +2,11 @@ import { MAX_FEATHER } from "@/masks/feather"; import type { ParamDefinition } from "@/params"; import type { BaseMaskParams, + Mask, MaskDefaultContext, MaskDefinition, - MaskInteractionResult, - MaskSnapArgs, - MaskSnapResult, + MaskParamUpdateArgs, + MaskRenderer, MaskType, } from "@/masks/types"; import type { HugeiconsIconProps } from "@hugeicons/react"; @@ -17,6 +17,16 @@ export type MaskIconProps = { strokeWidth?: number; }; +type RegisteredMaskWithoutId = Mask extends infer TMask + ? TMask extends Mask + ? Omit + : never + : never; + +export type MaskDefinitionForRegistration = { + [TType in MaskType]: MaskDefinition; +}[MaskType]; + const BASE_MASK_PARAM_DEFINITIONS: ParamDefinition< keyof BaseMaskParams & string >[] = [ @@ -50,28 +60,15 @@ const BASE_MASK_PARAM_DEFINITIONS: ParamDefinition< export interface RegisteredMaskDefinition { type: MaskType; name: string; - features: MaskDefinition["features"]; + features: MaskDefinition["features"]; params: ParamDefinition[]; - renderer: MaskDefinition["renderer"]; - interaction: { - getInteraction(args: { - params: BaseMaskParams; - bounds: Parameters< - MaskDefinition["interaction"]["getInteraction"] - >[0]["bounds"]; - displayScale: number; - scaleX: number; - scaleY: number; - }): MaskInteractionResult; - snap?(args: MaskSnapArgs): MaskSnapResult; - }; - isActive?: (params: BaseMaskParams) => boolean; - buildDefault( - context: MaskDefaultContext, - ): ReturnType["buildDefault"]>; + renderer: MaskRenderer; + interaction: MaskDefinition["interaction"]; + isActive?(params: BaseMaskParams): boolean; + buildDefault(context: MaskDefaultContext): RegisteredMaskWithoutId; computeParamUpdate( - args: Parameters["computeParamUpdate"]>[0], - ): ReturnType["computeParamUpdate"]>; + args: MaskParamUpdateArgs, + ): ReturnType; icon: MaskIconProps; } @@ -83,11 +80,11 @@ export class MasksRegistry extends DefinitionRegistry< super("mask"); } - registerMask({ + registerMask({ definition, icon, }: { - definition: MaskDefinition; + definition: MaskDefinitionForRegistration; icon: MaskIconProps; }): void { const withBaseParams: RegisteredMaskDefinition = { @@ -96,23 +93,10 @@ export class MasksRegistry extends DefinitionRegistry< features: definition.features, params: [...definition.params, ...BASE_MASK_PARAM_DEFINITIONS], renderer: definition.renderer, - interaction: { - getInteraction(args) { - return definition.interaction.getInteraction(args as never); - }, - snap: definition.interaction.snap - ? (args) => definition.interaction.snap?.(args as never) as never - : undefined, - }, - isActive: definition.isActive - ? (params) => definition.isActive?.(params as TParams) ?? true - : undefined, - buildDefault(context) { - return definition.buildDefault(context); - }, - computeParamUpdate(args) { - return definition.computeParamUpdate(args as never); - }, + interaction: definition.interaction, + isActive: definition.isActive, + buildDefault: definition.buildDefault, + computeParamUpdate: definition.computeParamUpdate, icon, }; this.register({ -- cgit v1.3.1