Skip to content

Commit 3c17279

Browse files
YummYumekbond
authored andcommitted
[Live] Add signature overload for on and off methods of component
1 parent 9c5a2f3 commit 3c17279

File tree

7 files changed

+48
-26
lines changed

7 files changed

+48
-26
lines changed

src/LiveComponent/assets/dist/Component/index.d.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
import { BackendInterface } from '../Backend/Backend';
22
import ValueStore from './ValueStore';
3+
import BackendRequest from '../Backend/BackendRequest';
34
import { ElementDriver } from './ElementDriver';
45
import { PluginInterface } from './plugins/PluginInterface';
56
import BackendResponse from '../Backend/BackendResponse';
7+
type MaybePromise<T = void> = T | Promise<T>;
8+
export type ComponentHooks = {
9+
'connect': (component: Component) => MaybePromise;
10+
'disconnect': (component: Component) => MaybePromise;
11+
'request:started': (requestConfig: any) => MaybePromise;
12+
'render:finished': (component: Component) => MaybePromise;
13+
'response:error': (backendResponse: BackendResponse, controls: {
14+
displayError: boolean;
15+
}) => MaybePromise;
16+
'loading.state.started': (element: HTMLElement, request: BackendRequest) => MaybePromise;
17+
'loading.state.finished': (element: HTMLElement) => MaybePromise;
18+
'model:set': (model: string, value: any, component: Component) => MaybePromise;
19+
};
20+
export type ComponentHookName = keyof ComponentHooks;
21+
export type ComponentHookCallback<T extends string = ComponentHookName> = T extends ComponentHookName ? ComponentHooks[T] : (...args: any[]) => MaybePromise;
622
export default class Component {
723
readonly element: HTMLElement;
824
readonly name: string;
@@ -30,8 +46,8 @@ export default class Component {
3046
addPlugin(plugin: PluginInterface): void;
3147
connect(): void;
3248
disconnect(): void;
33-
on(hookName: string, callback: (...args: any[]) => void): void;
34-
off(hookName: string, callback: (...args: any[]) => void): void;
49+
on<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
50+
off<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
3551
set(model: string, value: any, reRender?: boolean, debounce?: number | boolean): Promise<BackendResponse>;
3652
getData(model: string): any;
3753
action(name: string, args?: any, debounce?: number | boolean): Promise<BackendResponse>;
@@ -55,3 +71,4 @@ export default class Component {
5571
_updateFromParentProps(props: any): void;
5672
}
5773
export declare function proxifyComponent(component: Component): Component;
74+
export {};
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export default class {
22
private hooks;
3-
register(hookName: string, callback: () => void): void;
4-
unregister(hookName: string, callback: () => void): void;
3+
register(hookName: string, callback: (...args: any[]) => void): void;
4+
unregister(hookName: string, callback: (...args: any[]) => void): void;
55
triggerHook(hookName: string, ...args: any[]): void;
66
}

src/LiveComponent/assets/dist/PollingDirector.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/// <reference types="node" />
21
import Component from './Component';
32
export default class {
43
component: Component;
@@ -7,7 +6,7 @@ export default class {
76
actionName: string;
87
duration: number;
98
}>;
10-
pollingIntervals: NodeJS.Timer[];
9+
pollingIntervals: number[];
1110
constructor(component: Component);
1211
addPoll(actionName: string, duration: number): void;
1312
startAllPolling(): void;

src/LiveComponent/assets/dist/live_controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2625,7 +2625,7 @@ class PollingDirector {
26252625
this.component.action(actionName, {}, 0);
26262626
};
26272627
}
2628-
const timer = setInterval(() => {
2628+
const timer = window.setInterval(() => {
26292629
callback();
26302630
}, duration);
26312631
this.pollingIntervals.push(timer);

src/LiveComponent/assets/src/Component/index.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ import { findComponents, registerComponent, unregisterComponent } from '../Compo
1414

1515
declare const Turbo: any;
1616

17+
type MaybePromise<T = void> = T | Promise<T>;
18+
19+
export type ComponentHooks = {
20+
'connect': (component: Component) => MaybePromise,
21+
'disconnect': (component: Component) => MaybePromise,
22+
'request:started': (requestConfig: any) => MaybePromise,
23+
'render:finished': (component: Component) => MaybePromise,
24+
'response:error': (backendResponse: BackendResponse, controls: { displayError: boolean }) => MaybePromise,
25+
'loading.state.started': (element: HTMLElement, request: BackendRequest) => MaybePromise,
26+
'loading.state.finished': (element: HTMLElement) => MaybePromise,
27+
'model:set': (model: string, value: any, component: Component) => MaybePromise,
28+
};
29+
30+
export type ComponentHookName = keyof ComponentHooks;
31+
32+
export type ComponentHookCallback<T extends string = ComponentHookName> = T extends ComponentHookName
33+
? ComponentHooks[T]
34+
: (...args: any[]) => MaybePromise;
35+
1736
export default class Component {
1837
readonly element: HTMLElement;
1938
readonly name: string;
@@ -109,24 +128,11 @@ export default class Component {
109128
this.externalMutationTracker.stop();
110129
}
111130

112-
/**
113-
* Add a named hook to the component. Available hooks are:
114-
*
115-
* * connect (component: Component) => {}
116-
* * disconnect (component: Component) => {}
117-
* * request:started (requestConfig: any) => {}
118-
* * render:started (html: string, response: BackendResponse, controls: { shouldRender: boolean }) => {}
119-
* * render:finished (component: Component) => {}
120-
* * response:error (backendResponse: BackendResponse, controls: { displayError: boolean }) => {}
121-
* * loading.state:started (element: HTMLElement, request: BackendRequest) => {}
122-
* * loading.state:finished (element: HTMLElement) => {}
123-
* * model:set (model: string, value: any, component: Component) => {}
124-
*/
125-
on(hookName: string, callback: (...args: any[]) => void): void {
131+
on<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void {
126132
this.hooks.register(hookName, callback);
127133
}
128134

129-
off(hookName: string, callback: (...args: any[]) => void): void {
135+
off<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void {
130136
this.hooks.unregister(hookName, callback);
131137
}
132138

src/LiveComponent/assets/src/HookManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
export default class {
22
private hooks: Map<string, Array<(...args: any[]) => void>> = new Map();
33

4-
register(hookName: string, callback: () => void): void {
4+
register(hookName: string, callback: (...args: any[]) => void): void {
55
const hooks = this.hooks.get(hookName) || [];
66
hooks.push(callback);
77
this.hooks.set(hookName, hooks);
88
}
99

10-
unregister(hookName: string, callback: () => void): void {
10+
unregister(hookName: string, callback: (...args: any[]) => void): void {
1111
const hooks = this.hooks.get(hookName) || [];
1212
const index = hooks.indexOf(callback);
1313
if (index === -1) {

src/LiveComponent/assets/src/PollingDirector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default class {
44
component: Component;
55
isPollingActive = true;
66
polls: Array<{ actionName: string; duration: number }>;
7-
pollingIntervals: NodeJS.Timer[] = [];
7+
pollingIntervals: number[] = [];
88

99
constructor(component: Component) {
1010
this.component = component;
@@ -55,7 +55,7 @@ export default class {
5555
};
5656
}
5757

58-
const timer = setInterval(() => {
58+
const timer = window.setInterval(() => {
5959
callback();
6060
}, duration);
6161
this.pollingIntervals.push(timer);

0 commit comments

Comments
 (0)