From 11255958793318ddcf3dba9e2dfe088592e285cf Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Wed, 2 Apr 2025 16:02:29 +0200 Subject: [PATCH] Make element change/delete handlers have optional IDs --- docs/Elements/ElementsController.md | 45 +++++++++++++++++------------ docs/Main/FeltController.md | 45 +++++++++++++++++------------ etc/js-sdk.api.md | 16 +++++----- src/modules/elements/controller.ts | 38 ++++++++++++++++++------ src/modules/elements/schema.ts | 14 ++++----- src/modules/elements/type-tests.ts | 16 ++++++---- 6 files changed, 107 insertions(+), 67 deletions(-) diff --git a/docs/Elements/ElementsController.md b/docs/Elements/ElementsController.md index c3037c29..e7444c3b 100644 --- a/docs/Elements/ElementsController.md +++ b/docs/Elements/ElementsController.md @@ -357,12 +357,12 @@ still being created by a drawing tool. ### Parameters -| Parameter | Type | Description | -| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementChangeCallbackParams`](ElementChangeCallbackParams.md)) => `void`; } | - | -| `args.options` | \{ `id`: `string`; } | - | -| `args.options.id` | `string` | The id of the element to listen for changes to. | -| `args.handler` | (`change`: [`ElementChangeCallbackParams`](ElementChangeCallbackParams.md)) => `void` | The handler that is called when the element changes. | +| Parameter | Type | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementChangeCallbackParams`](ElementChangeCallbackParams.md)) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | - | +| `args.options.id`? | `string` | The id of the element to listen for changes to. If not provided, the listener will fire for all elements. | +| `args.handler` | (`change`: [`ElementChangeCallbackParams`](ElementChangeCallbackParams.md)) => `void` | The handler that is called when the element changes. | ### Returns @@ -386,18 +386,18 @@ unsubscribe(); ## onElementDelete() -> **onElementDelete**(`args`: \{ `options`: \{ `id`: `string`; }; `handler`: () => `void`; }): `VoidFunction` +> **onElementDelete**(`args`: \{ `options`: \{ `id`: `string`; }; `handler`: (`args`: \{ `id`: `string`; }) => `void`; }): `VoidFunction` Adds a listener for when an element is deleted. ### Parameters -| Parameter | Type | Description | -| ----------------- | -------------------------------------------------------------- | ------------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: () => `void`; } | - | -| `args.options` | \{ `id`: `string`; } | - | -| `args.options.id` | `string` | The id of the element to listen for deletions of. | -| `args.handler` | () => `void` | The handler that is called when the element is deleted. | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`args`: \{ `id`: `string`; }) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | - | +| `args.options.id`? | `string` | The id of the element to listen for deletions of. If not provided, the listener will fire for all elements. | +| `args.handler` | (`args`: \{ `id`: `string`; }) => `void` | The handler that is called when the element is deleted. | ### Returns @@ -408,13 +408,20 @@ A function to unsubscribe from the listener ### Example ```typescript +// For a specific element const unsubscribe = felt.onElementDelete({ options: { id: "element-1" }, handler: () => console.log("element-1 deleted"), }); +// For any element +const unsubscribe2 = felt.onElementDelete({ + handler: (id) => console.log(id), +}); + // later on... unsubscribe(); +unsubscribe2(); ``` *** @@ -427,12 +434,12 @@ Adds a listener for when an element group changes. ### Parameters -| Parameter | Type | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementGroupChangeCallbackParams`](ElementGroupChangeCallbackParams.md)) => `void`; } | -| `args.options` | \{ `id`: `string`; } | -| `args.options.id` | `string` | -| `args.handler` | (`change`: [`ElementGroupChangeCallbackParams`](ElementGroupChangeCallbackParams.md)) => `void` | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementGroupChangeCallbackParams`](ElementGroupChangeCallbackParams.md)) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | The options to apply to the listener. If not provided | +| `args.options.id`? | `string` | The id of the element group to listen for changes to. If not provided, the listener will fire for all element groups. | +| `args.handler` | (`change`: [`ElementGroupChangeCallbackParams`](ElementGroupChangeCallbackParams.md)) => `void` | The handler that is called when the element group changes. | ### Returns diff --git a/docs/Main/FeltController.md b/docs/Main/FeltController.md index a877e2b6..c80476db 100644 --- a/docs/Main/FeltController.md +++ b/docs/Main/FeltController.md @@ -1728,12 +1728,12 @@ still being created by a drawing tool. ### Parameters -| Parameter | Type | Description | -| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementChangeCallbackParams`](../Elements/ElementChangeCallbackParams.md)) => `void`; } | - | -| `args.options` | \{ `id`: `string`; } | - | -| `args.options.id` | `string` | The id of the element to listen for changes to. | -| `args.handler` | (`change`: [`ElementChangeCallbackParams`](../Elements/ElementChangeCallbackParams.md)) => `void` | The handler that is called when the element changes. | +| Parameter | Type | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementChangeCallbackParams`](../Elements/ElementChangeCallbackParams.md)) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | - | +| `args.options.id`? | `string` | The id of the element to listen for changes to. If not provided, the listener will fire for all elements. | +| `args.handler` | (`change`: [`ElementChangeCallbackParams`](../Elements/ElementChangeCallbackParams.md)) => `void` | The handler that is called when the element changes. | ### Returns @@ -1757,18 +1757,18 @@ unsubscribe(); ## onElementDelete() -> **onElementDelete**(`args`: \{ `options`: \{ `id`: `string`; }; `handler`: () => `void`; }): `VoidFunction` +> **onElementDelete**(`args`: \{ `options`: \{ `id`: `string`; }; `handler`: (`args`: \{ `id`: `string`; }) => `void`; }): `VoidFunction` Adds a listener for when an element is deleted. ### Parameters -| Parameter | Type | Description | -| ----------------- | -------------------------------------------------------------- | ------------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: () => `void`; } | - | -| `args.options` | \{ `id`: `string`; } | - | -| `args.options.id` | `string` | The id of the element to listen for deletions of. | -| `args.handler` | () => `void` | The handler that is called when the element is deleted. | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`args`: \{ `id`: `string`; }) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | - | +| `args.options.id`? | `string` | The id of the element to listen for deletions of. If not provided, the listener will fire for all elements. | +| `args.handler` | (`args`: \{ `id`: `string`; }) => `void` | The handler that is called when the element is deleted. | ### Returns @@ -1779,13 +1779,20 @@ A function to unsubscribe from the listener ### Example ```typescript +// For a specific element const unsubscribe = felt.onElementDelete({ options: { id: "element-1" }, handler: () => console.log("element-1 deleted"), }); +// For any element +const unsubscribe2 = felt.onElementDelete({ + handler: (id) => console.log(id), +}); + // later on... unsubscribe(); +unsubscribe2(); ``` *** @@ -1798,12 +1805,12 @@ Adds a listener for when an element group changes. ### Parameters -| Parameter | Type | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementGroupChangeCallbackParams`](../Elements/ElementGroupChangeCallbackParams.md)) => `void`; } | -| `args.options` | \{ `id`: `string`; } | -| `args.options.id` | `string` | -| `args.handler` | (`change`: [`ElementGroupChangeCallbackParams`](../Elements/ElementGroupChangeCallbackParams.md)) => `void` | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `args` | \{ `options`: \{ `id`: `string`; }; `handler`: (`change`: [`ElementGroupChangeCallbackParams`](../Elements/ElementGroupChangeCallbackParams.md)) => `void`; } | - | +| `args.options`? | \{ `id`: `string`; } | The options to apply to the listener. If not provided | +| `args.options.id`? | `string` | The id of the element group to listen for changes to. If not provided, the listener will fire for all element groups. | +| `args.handler` | (`change`: [`ElementGroupChangeCallbackParams`](../Elements/ElementGroupChangeCallbackParams.md)) => `void` | The handler that is called when the element group changes. | ### Returns diff --git a/etc/js-sdk.api.md b/etc/js-sdk.api.md index 2e118d96..b65efbee 100644 --- a/etc/js-sdk.api.md +++ b/etc/js-sdk.api.md @@ -183,8 +183,8 @@ export interface ElementsController { getElements( constraint?: GetElementsConstraint): Promise>; onElementChange(args: { - options: { - id: string; + options?: { + id?: string; }; handler: ( change: ElementChangeCallbackParams) => void; @@ -198,14 +198,16 @@ export interface ElementsController { }) => void; }): VoidFunction; onElementDelete(args: { - options: { - id: string; + options?: { + id?: string; }; - handler: () => void; + handler: (args: { + id: Element_2["id"]; + }) => void; }): VoidFunction; onElementGroupChange(args: { - options: { - id: string; + options?: { + id?: string; }; handler: (change: ElementGroupChangeCallbackParams) => void; }): VoidFunction; diff --git a/src/modules/elements/controller.ts b/src/modules/elements/controller.ts index 71d29673..4d9f3df2 100644 --- a/src/modules/elements/controller.ts +++ b/src/modules/elements/controller.ts @@ -252,11 +252,12 @@ export interface ElementsController { * ``` */ onElementChange(args: { - options: { + options?: { /** - * The id of the element to listen for changes to. + * The id of the element to listen for changes to. If not provided, + * the listener will fire for all elements. */ - id: string; + id?: string; }; /** @@ -278,27 +279,35 @@ export interface ElementsController { * @event * @example * ```typescript + * // For a specific element * const unsubscribe = felt.onElementDelete({ * options: { id: "element-1" }, * handler: () => console.log("element-1 deleted"), * }); * + * // For any element + * const unsubscribe2 = felt.onElementDelete({ + * handler: (id) => console.log(id), + * }); + * * // later on... * unsubscribe(); + * unsubscribe2(); * ``` */ onElementDelete(args: { - options: { + options?: { /** - * The id of the element to listen for deletions of. + * The id of the element to listen for deletions of. If not provided, + * the listener will fire for all elements. */ - id: string; + id?: string; }; /** * The handler that is called when the element is deleted. */ - handler: () => void; + handler: (args: { id: Element["id"] }) => void; }): VoidFunction; /** @@ -319,9 +328,20 @@ export interface ElementsController { * ``` */ onElementGroupChange(args: { - options: { - id: string; + /** + * The options to apply to the listener. If not provided + */ + options?: { + /** + * The id of the element group to listen for changes to. If + * not provided, the listener will fire for all element groups. + */ + id?: string; }; + + /** + * The handler that is called when the element group changes. + */ handler: (change: ElementGroupChangeCallbackParams) => void; }): VoidFunction; diff --git a/src/modules/elements/schema.ts b/src/modules/elements/schema.ts index 55700200..17003d53 100644 --- a/src/modules/elements/schema.ts +++ b/src/modules/elements/schema.ts @@ -45,7 +45,7 @@ const SetElementGroupVisibilityMessage = methodMessage( const OnElementChangeMessage = listenerMessageWithParams( "onElementChange", - z.object({ id: z.string() }), + z.object({ id: z.string() }).partial().optional(), ); const OnElementCreateMessage = listenerMessageNoParams("onElementCreate"); @@ -54,12 +54,12 @@ const OnElementCreateEndMessage = listenerMessageNoParams("onElementCreateEnd"); const OnElementDeleteMessage = listenerMessageWithParams( "onElementDelete", - z.object({ id: z.string() }), + z.object({ id: z.string() }).partial().optional(), ); const OnElementGroupChangeMessage = listenerMessageWithParams( "onElementGroupChange", - z.object({ id: z.string() }), + z.object({ id: z.string() }).partial().optional(), ); const CreateElementMessage = methodMessage( @@ -123,18 +123,18 @@ export type ElementsSchema = { }; listeners: { onElementChange: Listener< - zInfer, + zInfer, ElementChangeCallbackParams >; onElementGroupChange: Listener< - zInfer, + zInfer, ElementGroupChangeCallbackParams >; onElementCreate: ListenerNoOptions; onElementCreateEnd: ListenerNoOptions<{ element: Element }>; onElementDelete: Listener< - zInfer, - void + zInfer, + { id: Element["id"] } >; }; }; diff --git a/src/modules/elements/type-tests.ts b/src/modules/elements/type-tests.ts index 0cf682dc..b778f39d 100644 --- a/src/modules/elements/type-tests.ts +++ b/src/modules/elements/type-tests.ts @@ -34,9 +34,9 @@ export const elementsControllerTypeTests = { }); unsub(); - // @ts-expect-error: options are missing + // without options is allowed sdk.onElementDelete({ - handler: () => {}, + handler: (_arg: { id: string }) => {}, }); sdk.onElementDelete({ @@ -46,10 +46,14 @@ export const elementsControllerTypeTests = { }); sdk.onElementDelete({ - // @ts-expect-error: there are no args to onElementDelete handler - handler: (arg) => {}, - // @ts-expect-error: id is missing - options: {}, + // @ts-expect-error: id should be a string + handler: (_arg: { id: number }) => {}, + + // without ID is ok + options: { + // @ts-expect-error: egg is not a valid option + egg: "bacon", + }, }); }, };