From 09783a86490a7fabb8ccdbd12238601fe4d951b8 Mon Sep 17 00:00:00 2001 From: Asko Nõmm Date: Sun, 20 Apr 2025 18:49:27 +0300 Subject: Closes #1 --- src/shapex.test.ts | 20 ++++++------ src/shapex.ts | 93 +++++++++++++++++++++++++++++------------------------- 2 files changed, 59 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/shapex.test.ts b/src/shapex.test.ts index de40708..5c555b0 100644 --- a/src/shapex.test.ts +++ b/src/shapex.test.ts @@ -56,12 +56,10 @@ describe("dispatch", () => { const $ = ShapeX({ counter: 1 }); - const testEventCb: EventCallback = ( + const testEventCb: EventCallback = ( state, // deno-lint-ignore no-unused-vars - arg1, - // deno-lint-ignore no-unused-vars - arg2 + data ) => ({ state, }); @@ -69,10 +67,10 @@ describe("dispatch", () => { const callback = spy(testEventCb); $.subscribe("test-event", callback); - $.dispatch("test-event", "arg1-value", "arg2-value"); + $.dispatch("test-event", "arg1-value"); assertSpyCall(callback, 0, { - args: [{ counter: 1 }, "arg1-value", "arg2-value"], + args: [{ counter: 1 }, "arg1-value"], }); }); @@ -111,7 +109,7 @@ describe("dispatch", () => { $.subscribe("parent-event", (state) => ({ state, - dispatch: { eventName: "nested-event" }, + dispatch: { to: "nested-event" }, })); $.dispatch("parent-event"); @@ -136,9 +134,9 @@ describe("dispatch", () => { $.subscribe("parent-event", (state) => ({ state, dispatch: [ - { eventName: "nested-event-1" }, + { to: "nested-event-1" }, { - eventName: "nested-event-2", + to: "nested-event-2", }, ], })); @@ -156,14 +154,14 @@ describe("dispatch", () => { const $ = ShapeX({ counter: 1 }); // deno-lint-ignore no-unused-vars - const cb: EventCallback = (state, arg) => ({ state }); + const cb: EventCallback = (state, arg) => ({ state }); const spyCb = spy(cb); $.subscribe("nested-event", spyCb); $.subscribe("parent-event", (state) => ({ state, - dispatch: { eventName: "nested-event", args: ["arg-value"] }, + dispatch: { to: "nested-event", withData: "arg-value" }, })); $.dispatch("parent-event"); diff --git a/src/shapex.ts b/src/shapex.ts index d12e159..d36e5e4 100644 --- a/src/shapex.ts +++ b/src/shapex.ts @@ -2,9 +2,9 @@ * Dispatches an event with a given name and passes on * given arguments to it. */ -export type SubscriptionResponseDispatch = { - eventName: string; - args?: unknown[]; +export type SubscriptionResponseDispatch = { + to: string; + withData?: W; }; /** @@ -12,27 +12,29 @@ export type SubscriptionResponseDispatch = { * if you want to update state, and/or optionally also any events you * might want to dispatch. */ -export type SubscriptionResponse = { +export type SubscriptionResponse = { state?: T; - dispatch?: SubscriptionResponseDispatch | SubscriptionResponseDispatch[]; + dispatch?: + | SubscriptionResponseDispatch + | SubscriptionResponseDispatch[]; }; -const isSubscriptionResponseList = ( - dispatch: SubscriptionResponseDispatch | SubscriptionResponseDispatch[] -): dispatch is SubscriptionResponseDispatch[] => Array.isArray(dispatch); +const isSubscriptionResponseList = ( + dispatch: SubscriptionResponseDispatch | SubscriptionResponseDispatch[] +): dispatch is SubscriptionResponseDispatch[] => Array.isArray(dispatch); /** * A callback passed to subcriptions, called when the event * that the subscription is listening to is called. */ -export type EventCallback = ( +export type EventCallback = ( state: T, - ...args: S -) => SubscriptionResponse; + data?: W +) => SubscriptionResponse; -type Subscription = { +type Subscription = { listener: string; - callback: EventCallback; + callback: EventCallback; once: boolean; }; @@ -43,16 +45,16 @@ export type ShapeXInstance = { /** * Subcribe to an event. */ - subscribe: ( + subscribe: ( listener: string, - callback: EventCallback + callback: EventCallback ) => number; /** * Subscribe to an event once. */ - subscribeOnce: ( + subscribeOnce: ( listener: string, - callback: EventCallback + callback: EventCallback ) => number; /** @@ -63,7 +65,7 @@ export type ShapeXInstance = { /** * Get the number of subscriptions for an event. */ - subscriptionCount: (eventName: string) => number; + subscriptionCount: (to: string) => number; /** * Get the subscriptions for an event. @@ -73,7 +75,7 @@ export type ShapeXInstance = { /** * Dispatch an event. */ - dispatch: (eventName: string, ...args: S) => void; + dispatch: (to: string, withData?: W) => void; /** * Get the current state. @@ -93,7 +95,7 @@ export default function ShapeX( let _state = initialState; const _subscriptions: Map< string, - Array> + Array> > = new Map(); let subscriptionId = 0; @@ -101,12 +103,12 @@ export default function ShapeX( * Subcribe to an event. * * @param {string} listener - * @param {EventCallback} callback + * @param {EventCallback} callback * @returns */ - const subscribe = ( + const subscribe = ( listener: string, - callback: EventCallback + callback: EventCallback ): number => { if (!_subscriptions.has(listener)) { _subscriptions.set(listener, []); @@ -116,7 +118,7 @@ export default function ShapeX( if (subscriptions) { subscriptions.push({ listener, - callback: callback as unknown as EventCallback, + callback: callback as unknown as EventCallback, once: false, }); } @@ -131,9 +133,9 @@ export default function ShapeX( * @param {EventCallback} callback * @returns */ - const subscribeOnce = ( + const subscribeOnce = ( listener: string, - callback: EventCallback + callback: EventCallback ): number => { if (!_subscriptions.has(listener)) { _subscriptions.set(listener, []); @@ -143,7 +145,7 @@ export default function ShapeX( if (subscriptions) { subscriptions.push({ listener, - callback: callback as unknown as EventCallback, + callback: callback as unknown as EventCallback, once: true, }); } @@ -221,25 +223,25 @@ export default function ShapeX( /** * Dispatches an event with the given name and arguments. * - * @param {string} eventName The name of the event to dispatch. - * @param {unknown[]} args The arguments to pass to the event listeners. + * @param {string} to The name of the event to dispatch. + * @param {unknown[]} withData The arguments to pass to the event listeners. * @returns {void} */ - const dispatch = ( - eventName: string, - ...args: S + const dispatch = ( + to: string, + withData?: W ): void => { - if (!_subscriptions.has(eventName)) { + if (!_subscriptions.has(to)) { return; } - const scopedSubsriptions = _subscriptions.get(eventName) ?? []; - const remainingSubscriptions = [] as Array>; + const scopedSubsriptions = _subscriptions.get(to) ?? []; + const remainingSubscriptions = [] as Array>; let callbackCount = 0; for (const subscription of scopedSubsriptions) { - const callback = subscription.callback as unknown as EventCallback; - const response = callback(_state, ...args); + const callback = subscription.callback as unknown as EventCallback; + const response = withData ? callback(_state, withData) : callback(_state); // Updates state, and checks for state changes, and if any changes present, // fires a dispatch for all the state listeners (if there are any). @@ -256,13 +258,18 @@ export default function ShapeX( if (response.dispatch) { if (isSubscriptionResponseList(response.dispatch)) { for (const dispatchee of response.dispatch) { - dispatch(dispatchee.eventName, ...(dispatchee.args ?? [])); + if (dispatchee.withData) { + dispatch(dispatchee.to, dispatchee.withData); + } else { + dispatch(dispatchee.to); + } } } else { - dispatch( - response.dispatch.eventName, - ...(response.dispatch.args ?? []) - ); + if (response.dispatch.withData) { + dispatch(response.dispatch.to, response.dispatch.withData); + } else { + dispatch(response.dispatch.to); + } } } @@ -273,7 +280,7 @@ export default function ShapeX( } } - _subscriptions.set(eventName, remainingSubscriptions); + _subscriptions.set(to, remainingSubscriptions); }; /** -- cgit v1.2.3