Skip to content

Commit c8dcb6b

Browse files
committed
refactor: simplify in-page channel event types
1 parent d00bf1b commit c8dcb6b

3 files changed

Lines changed: 18 additions & 29 deletions

File tree

‎packages/devframe/src/in-page-channel/events.test-d.ts‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,3 @@ it('distinguishes void actions from declared events in both directions', () => {
4646
// @ts-expect-error Functions cannot receive event listeners.
4747
panel.on('reset', () => {})
4848
})
49-
50-
it('supports omitted protocol sections without widening their keys', () => {
51-
interface FunctionsOnly { functions: { pageScript: { run: () => void } } }
52-
interface EventsOnly { events: { panel: { ready: () => void } } }
53-
expectTypeOf<Parameters<PanelChannel<FunctionsOnly>['emit']>[0]>().toEqualTypeOf<never>()
54-
expectTypeOf<Parameters<PanelChannel<EventsOnly>['call']>[0]>().toEqualTypeOf<never>()
55-
expectTypeOf<Parameters<PageScriptChannel<EventsOnly>['on']>[0]>().toEqualTypeOf<never>()
56-
})

‎packages/devframe/src/in-page-channel/types.ts‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ type PanelFunctions<P extends InPageChannelProtocol> = SideDeclarations<P, 'func
4242
type SharedStates<P extends InPageChannelProtocol>
4343
= P['sharedStates'] extends Record<string, object> ? P['sharedStates'] : Record<string, never>
4444

45-
type FunctionNames<T> = { [K in keyof T]: [T[K]] extends [never] ? never : K }[keyof T] & string
46-
4745
type FnArgs<F> = F extends (...args: infer A) => any ? A : never
4846
type FnReturn<F> = F extends (...args: any[]) => infer R ? Awaited<R> : never
4947

@@ -328,7 +326,7 @@ export interface PanelPeer<P extends InPageChannelProtocol> {
328326
/** Unique id of the panel endpoint (stable across its lifetime, not reloads). */
329327
readonly id: string
330328
/** Call one panel's function and await the result. */
331-
call: <K extends FunctionNames<PanelFunctions<P>>>(
329+
call: <K extends keyof PanelFunctions<P> & string>(
332330
name: K,
333331
...args: FnArgs<PanelFunctions<P>[K]>
334332
) => Promise<FnReturn<PanelFunctions<P>[K]>>
@@ -353,17 +351,17 @@ export interface PageScriptChannel<P extends InPageChannelProtocol> {
353351
readonly panels: readonly PanelPeer<P>[]
354352
readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>
355353
/** Fan an event out to every connected panel. */
356-
emit: <K extends FunctionNames<PanelProtocolEvents<P>>>(
354+
emit: <K extends keyof PanelProtocolEvents<P> & string>(
357355
name: K,
358356
...args: FnArgs<PanelProtocolEvents<P>[K]>
359357
) => void
360358
/** @deprecated Use `emit()` instead. */
361-
callEvent: <K extends FunctionNames<PanelProtocolEvents<P>>>(
359+
callEvent: <K extends keyof PanelProtocolEvents<P> & string>(
362360
name: K,
363361
...args: FnArgs<PanelProtocolEvents<P>[K]>
364362
) => void
365363
/** Subscribe to an event emitted by a panel. Returns an unsubscribe function. */
366-
on: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(
364+
on: <K extends keyof PageScriptProtocolEvents<P> & string>(
367365
name: K,
368366
listener: (...args: FnArgs<PageScriptProtocolEvents<P>[K]>) => void,
369367
) => () => void
@@ -402,25 +400,25 @@ export interface PanelChannel<P extends InPageChannelProtocol> {
402400
* the call is buffered and sent on connect; it rejects with code
403401
* `timeout` when `callTimeoutMs` elapses first.
404402
*/
405-
call: <K extends FunctionNames<PageScriptFunctions<P>>>(
403+
call: <K extends keyof PageScriptFunctions<P> & string>(
406404
name: K,
407405
...args: FnArgs<PageScriptFunctions<P>[K]>
408406
) => Promise<FnReturn<PageScriptFunctions<P>[K]>>
409407
/**
410408
* Emit an event to the page script. While `connecting` the event is buffered
411409
* (up to `eventBufferLimit`) and flushed on connect.
412410
*/
413-
emit: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(
411+
emit: <K extends keyof PageScriptProtocolEvents<P> & string>(
414412
name: K,
415413
...args: FnArgs<PageScriptProtocolEvents<P>[K]>
416414
) => void
417415
/** @deprecated Use `emit()` instead. */
418-
callEvent: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(
416+
callEvent: <K extends keyof PageScriptProtocolEvents<P> & string>(
419417
name: K,
420418
...args: FnArgs<PageScriptProtocolEvents<P>[K]>
421419
) => void
422420
/** Subscribe to an event emitted by the page script. Returns an unsubscribe function. */
423-
on: <K extends FunctionNames<PanelProtocolEvents<P>>>(
421+
on: <K extends keyof PanelProtocolEvents<P> & string>(
424422
name: K,
425423
listener: (...args: FnArgs<PanelProtocolEvents<P>[K]>) => void,
426424
) => () => void

‎tests/__snapshots__/tsnapi/devframe/in-page-channel.snapshot.d.ts‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// #region Interfaces
55
export interface ConnectPanelChannelOptions<Protocol extends InPageChannelProtocol = InPageChannelProtocol> extends InPageChannelCommonOptions {
66
functions: ConnectPanelChannelOptionsFunctions<Protocol>;
7-
events: { [NAME in keyof PanelProtocolEvents<Protocol> & string]: InPageEventOption<PanelProtocolEvents<Protocol>[NAME]>; };
7+
events?: { [NAME in keyof PanelProtocolEvents<Protocol> & string]?: InPageEventOption<PanelProtocolEvents<Protocol>[NAME]>; };
88
window?: Window | false;
99
targets?: Window[];
1010
transport?: MessagePort;
@@ -14,7 +14,7 @@ export interface ConnectPanelChannelOptions<Protocol extends InPageChannelProtoc
1414
}
1515
export interface CreatePageScriptChannelOptions<Protocol extends InPageChannelProtocol = InPageChannelProtocol> extends InPageChannelCommonOptions {
1616
functions: CreatePageScriptChannelOptionsFunctions<Protocol>;
17-
events: { [NAME in keyof PageScriptProtocolEvents<Protocol> & string]: InPageEventOption<PageScriptProtocolEvents<Protocol>[NAME]>; };
17+
events?: { [NAME in keyof PageScriptProtocolEvents<Protocol> & string]?: InPageEventOption<PageScriptProtocolEvents<Protocol>[NAME]>; };
1818
window?: Window | false;
1919
}
2020
export interface InPageChannelProtocol {
@@ -33,9 +33,9 @@ export interface PageScriptChannel<P extends InPageChannelProtocol> {
3333
readonly instanceId: string;
3434
readonly panels: readonly PanelPeer<P>[];
3535
readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>;
36-
emit: <K extends FunctionNames<PanelProtocolEvents<P>>>(_: K, ..._: FnArgs<PanelProtocolEvents<P>[K]>) => void;
37-
callEvent: <K extends FunctionNames<PanelProtocolEvents<P>>>(_: K, ..._: FnArgs<PanelProtocolEvents<P>[K]>) => void;
38-
on: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(_: K, _: (..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void) => () => void;
36+
emit: <K extends keyof PanelProtocolEvents<P> & string>(_: K, ..._: FnArgs<PanelProtocolEvents<P>[K]>) => void;
37+
callEvent: <K extends keyof PanelProtocolEvents<P> & string>(_: K, ..._: FnArgs<PanelProtocolEvents<P>[K]>) => void;
38+
on: <K extends keyof PageScriptProtocolEvents<P> & string>(_: K, _: (..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void) => () => void;
3939
readonly sharedState: InPageSharedStateHost<P>;
4040
addPanelPort: (_: MessagePort) => PanelPeer<P>;
4141
close: () => void;
@@ -48,16 +48,16 @@ export interface PanelChannel<P extends InPageChannelProtocol> {
4848
} | undefined;
4949
readonly events: Pick<EventEmitter<PanelChannelEvents>, 'on' | 'once'>;
5050
whenConnected: (_?: number) => Promise<void>;
51-
call: <K extends FunctionNames<PageScriptFunctions<P>>>(_: K, ..._: FnArgs<PageScriptFunctions<P>[K]>) => Promise<FnReturn<PageScriptFunctions<P>[K]>>;
52-
emit: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(_: K, ..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void;
53-
callEvent: <K extends FunctionNames<PageScriptProtocolEvents<P>>>(_: K, ..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void;
54-
on: <K extends FunctionNames<PanelProtocolEvents<P>>>(_: K, _: (..._: FnArgs<PanelProtocolEvents<P>[K]>) => void) => () => void;
51+
call: <K extends keyof PageScriptFunctions<P> & string>(_: K, ..._: FnArgs<PageScriptFunctions<P>[K]>) => Promise<FnReturn<PageScriptFunctions<P>[K]>>;
52+
emit: <K extends keyof PageScriptProtocolEvents<P> & string>(_: K, ..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void;
53+
callEvent: <K extends keyof PageScriptProtocolEvents<P> & string>(_: K, ..._: FnArgs<PageScriptProtocolEvents<P>[K]>) => void;
54+
on: <K extends keyof PanelProtocolEvents<P> & string>(_: K, _: (..._: FnArgs<PanelProtocolEvents<P>[K]>) => void) => () => void;
5555
readonly sharedState: InPageSharedStateHost<P>;
5656
close: () => void;
5757
}
5858
export interface PanelPeer<P extends InPageChannelProtocol> {
5959
readonly id: string;
60-
call: <K extends FunctionNames<PanelFunctions<P>>>(_: K, ..._: FnArgs<PanelFunctions<P>[K]>) => Promise<FnReturn<PanelFunctions<P>[K]>>;
60+
call: <K extends keyof PanelFunctions<P> & string>(_: K, ..._: FnArgs<PanelFunctions<P>[K]>) => Promise<FnReturn<PanelFunctions<P>[K]>>;
6161
close: () => void;
6262
}
6363
// #endregion
@@ -94,7 +94,6 @@ type ConnectPanelChannelOptionsFunctions<P extends InPageChannelProtocol> = { [N
9494
type CreatePageScriptChannelOptionsFunctions<P extends InPageChannelProtocol> = { [NAME in keyof PageScriptFunctions<P> & string]: InPageFunctionOption<PageScriptFunctions<P>[NAME]>; };
9595
type FnArgs<F> = F extends ((...args: infer A) => any) ? A : never;
9696
type FnReturn<F> = F extends ((...args: any[]) => infer R) ? Awaited<R> : never;
97-
type FunctionNames<T> = { [K in keyof T]: [T[K]] extends [never] ? never : K; }[keyof T] & string;
9897
interface InPageChannelCommonOptions {
9998
name: string;
10099
allowedOrigins?: string[];

0 commit comments

Comments
 (0)