Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V3] Add generic to runtime event handlers #4042

Open
wants to merge 2 commits into
base: v3-alpha
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions v3/internal/runtime/desktop/@wailsio/runtime/src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ The electron alternative for Go

/* jshint esversion: 9 */

/**
* @typedef {import("./types").WailsEvent} WailsEvent
/**
* @template D
* @callback WailsEventCallback
* @param {WailsEvent<D>} event
* @return {void}
*/

import {newRuntimeCallerWithID, objectNames} from "./runtime";

import {EventTypes} from "./event_types";
Expand All @@ -38,8 +42,14 @@ class Listener {
};
}
}

/**
* @template [D=unknown]
*/
export class WailsEvent {
/**
* @param {string} name - The name of the event
* @param {D} data - The data emitted by the event
*/
constructor(name, data = null) {
this.name = name;
this.data = data;
Expand Down Expand Up @@ -67,11 +77,12 @@ function dispatchWailsEvent(event) {
/**
* Register a callback function to be called multiple times for a specific event.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event to register the callback for.
* @param {function} callback - The callback function to be called when the event is triggered.
* @param {WailsEventCallback<D>} callback - The callback function to be called when the event is triggered.
* @param {number} maxCallbacks - The maximum number of times the callback can be called for the event. Once the maximum number is reached, the callback will no longer be called.
*
@return {function} - A function that, when called, will unregister the callback from the event.
@return {() => void} - A function that, when called, will unregister the callback from the event.
*/
export function OnMultiple(eventName, callback, maxCallbacks) {
let listeners = eventListeners.get(eventName) || [];
Expand All @@ -84,17 +95,19 @@ export function OnMultiple(eventName, callback, maxCallbacks) {
/**
* Registers a callback function to be executed when the specified event occurs.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event.
* @param {function} callback - The callback function to be executed. It takes no parameters.
* @return {function} - A function that, when called, will unregister the callback from the event. */
* @param {WailsEventCallback<D>} callback - The callback function to be executed.
* @return {() => void} - A function that, when called, will unregister the callback from the event. */
export function On(eventName, callback) { return OnMultiple(eventName, callback, -1); }

/**
* Registers a callback function to be executed only once for the specified event.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event.
* @param {function} callback - The function to be executed when the event occurs.
* @return {function} - A function that, when called, will unregister the callback from the event.
* @param {WailsEventCallback<D>} callback - The function to be executed when the event occurs.
* @return {() => void} - A function that, when called, will unregister the callback from the event.
*/
export function Once(eventName, callback) { return OnMultiple(eventName, callback, 1); }

Expand Down
37 changes: 24 additions & 13 deletions v3/internal/runtime/desktop/@wailsio/runtime/types/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,31 @@ export function setup(): void;
/**
* Register a callback function to be called multiple times for a specific event.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event to register the callback for.
* @param {function} callback - The callback function to be called when the event is triggered.
* @param {WailsEventCallback<D>} callback - The callback function to be called when the event is triggered.
* @param {number} maxCallbacks - The maximum number of times the callback can be called for the event. Once the maximum number is reached, the callback will no longer be called.
*
@return {function} - A function that, when called, will unregister the callback from the event.
@return {() => void} - A function that, when called, will unregister the callback from the event.
*/
export function OnMultiple(eventName: string, callback: Function, maxCallbacks: number): Function;
export function OnMultiple<D = unknown>(eventName: string, callback: WailsEventCallback<D>, maxCallbacks: number): () => void;
/**
* Registers a callback function to be executed when the specified event occurs.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event.
* @param {function} callback - The callback function to be executed. It takes no parameters.
* @return {function} - A function that, when called, will unregister the callback from the event. */
export function On(eventName: string, callback: Function): Function;
* @param {WailsEventCallback<D>} callback - The callback function to be executed.
* @return {() => void} - A function that, when called, will unregister the callback from the event. */
export function On<D = unknown>(eventName: string, callback: WailsEventCallback<D>): () => void;
/**
* Registers a callback function to be executed only once for the specified event.
*
* @template [D=unknown]
* @param {string} eventName - The name of the event.
* @param {function} callback - The function to be executed when the event occurs.
* @return {function} - A function that, when called, will unregister the callback from the event.
* @param {WailsEventCallback<D>} callback - The function to be executed when the event occurs.
* @return {() => void} - A function that, when called, will unregister the callback from the event.
*/
export function Once(eventName: string, callback: Function): Function;
export function Once<D = unknown>(eventName: string, callback: WailsEventCallback<D>): () => void;
/**
* Removes event listeners for the specified event names.
*
Expand Down Expand Up @@ -232,8 +235,16 @@ export const Types: {
ThemeChanged: string;
};
};
export class WailsEvent {
constructor(name: any, data?: any);
name: any;
data: any;
/**
* @template [D=unknown]
*/
export class WailsEvent<D = unknown> {
/**
* @param {string} name - The name of the event
* @param {D} data - The data emitted by the event
*/
constructor(name: string, data?: D);
name: string;
data: D;
}
export type WailsEventCallback<D> = (event: WailsEvent<D>) => void;
4 changes: 2 additions & 2 deletions v3/internal/templates/base/frontend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ window.doGreet = () => {
});
}

Events.On('time', (time) => {
timeElement.innerText = time.data;
Events.On('time', (timeValue) => {
timeElement.innerText = timeValue.data;
});
2 changes: 1 addition & 1 deletion v3/internal/templates/lit-ts/frontend/src/my-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class MyElement extends LitElement {

constructor() {
super();
Events.On('time', (timeValue: { data: string }) => {
Events.On<string>('time', (timeValue) => {
this.time = timeValue.data;
});
}
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/preact-ts/frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function App() {
}

useEffect(() => {
Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
setTime(timeValue.data);
});
}, []);
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/qwik-ts/frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const App = component$(() => {
}

useVisibleTask$(() => {
Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
time.value = timeValue.data;
});
// Reload WML so it picks up the wml tags
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/react-swc-ts/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function App() {
}

useEffect(() => {
Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
setTime(timeValue.data);
});
// Reload WML so it picks up the wml tags
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/react-ts/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function App() {
}

useEffect(() => {
Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
setTime(timeValue.data);
});
// Reload WML so it picks up the wml tags
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/solid-ts/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function App() {
}

onMount(() => {
Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
setTime(timeValue.data);
});
});
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/svelte-ts/frontend/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
});
}

Events.On('time', (timeValue: any) => {
Events.On<string>('time', (timeValue) => {
time = timeValue.data;
});
Comment on lines +21 to 23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider wrapping event listener in onMount.

While the generic type addition is good, the event listener should be wrapped in Svelte's onMount lifecycle function to prevent potential memory leaks and ensure proper cleanup.

+import { onMount } from 'svelte';

-Events.On<string>('time', (timeValue) => {
-  time = timeValue.data;
-});
+onMount(() => {
+  Events.On<string>('time', (timeValue) => {
+    time = timeValue.data;
+  });
+});

Committable suggestion skipped: line range outside the PR's diff.

</script>
Expand Down
2 changes: 1 addition & 1 deletion v3/internal/templates/vanilla-ts/frontend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ greetButton.addEventListener('click', () => {
});
});

Events.On('time', (time: {data: any}) => {
Events.On<string>('time', (time) => {
timeElement.innerText = time.data;
});
4 changes: 2 additions & 2 deletions v3/internal/templates/vanilla/frontend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ window.doGreet = () => {
});
}

Events.On('time', (time) => {
timeElement.innerText = time.data;
Events.On('time', (timeValue) => {
timeElement.innerText = timeValue.data;
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const doGreet = () => {
}

onMounted(() => {
Events.On('time', (timeValue: { data: string }) => {
Events.On<string>('time', (timeValue) => {
time.value = timeValue.data;
});
})
Expand Down