Skip to content

Commit 5c026a0

Browse files
committed
refactor: split in-page function option types
1 parent 3eb32b9 commit 5c026a0

4 files changed

Lines changed: 97 additions & 56 deletions

File tree

packages/devframe/src/in-page-channel/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export type {
3333
export function defineChannelFunction<
3434
NAME extends string,
3535
TYPE extends InPageFunctionType,
36-
ARGS extends any[] = [],
36+
ARGS extends any[],
3737
RETURN = void,
3838
const AS extends RpcArgsSchema | undefined = undefined,
3939
const RS extends RpcReturnSchema | undefined = undefined,

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ interface PageScriptOnlyProtocol {
2222
}
2323

2424
describe('Channel function definitions', () => {
25-
it('allows events without handlers', () => {
25+
it('distinguishes event, query, and action definitions', () => {
2626
defineChannelFunction({ name: 'notify', type: 'event' })
27+
defineChannelFunction({ name: 'load', handler: () => 'value' })
28+
defineChannelFunction({ name: 'load', type: 'query', handler: () => 'value' })
29+
defineChannelFunction({ name: 'save', type: 'action', handler: () => {} })
2730
})
2831

2932
it('requires handlers for request/response functions', () => {
@@ -88,8 +91,8 @@ describe('In-page script channel', () => {
8891
createPageScriptChannel<TestProtocol>({
8992
name: 'devframes:test',
9093
functions: {
91-
echo: { handler: value => value },
92-
sum: { handler: (a, b) => a + b },
94+
echo: { type: 'query', handler: value => value },
95+
sum: { type: 'action', handler: (a, b) => a + b },
9396
save: { type: 'event' },
9497
},
9598
})
@@ -99,7 +102,8 @@ describe('In-page script channel', () => {
99102
functions: {
100103
// @ts-expect-error Request/response functions require a handler.
101104
echo: { type: 'query' },
102-
sum: { handler: (a, b) => a + b },
105+
// @ts-expect-error Request/response functions require a handler.
106+
sum: { type: 'action' },
103107
save: { type: 'event' },
104108
},
105109
})

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

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,60 @@ type ProtocolHandler<F> = F extends (...args: any[]) => any
4747
*/
4848
export type InPageFunctionType = 'action' | 'event' | 'query'
4949

50+
interface InPageFunctionDefinitionBase<NAME extends string> {
51+
name: NAME
52+
jsonSerializable?: boolean
53+
}
54+
55+
interface InPageEventFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
56+
type: 'event'
57+
handler?: HANDLER
58+
}
59+
60+
interface InPageQueryFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
61+
type?: 'query'
62+
handler: HANDLER
63+
}
64+
65+
interface InPageActionFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
66+
type: 'action'
67+
handler: HANDLER
68+
}
69+
70+
type InPageFunctionDefinitionForType<
71+
NAME extends string,
72+
TYPE extends InPageFunctionType,
73+
HANDLER,
74+
> = TYPE extends 'event'
75+
? InPageEventFunctionDefinition<NAME, HANDLER>
76+
: TYPE extends 'action'
77+
? InPageActionFunctionDefinition<NAME, HANDLER>
78+
: InPageQueryFunctionDefinition<NAME, HANDLER>
79+
80+
type InPageFunctionDefinitionSchemas<
81+
AS extends RpcArgsSchema | undefined,
82+
RS extends RpcReturnSchema | undefined,
83+
> = [AS, RS] extends [undefined, undefined]
84+
? {
85+
args?: AS
86+
returns?: RS
87+
}
88+
: {
89+
/** Standard Schema array validating (and typing) the arguments. */
90+
args: AS
91+
/** Standard Schema typing the resolved return value. */
92+
returns: RS
93+
}
94+
95+
type InPageFunctionDefinitionHandler<
96+
ARGS extends any[],
97+
RETURN,
98+
AS extends RpcArgsSchema | undefined,
99+
RS extends RpcReturnSchema | undefined,
100+
> = [AS, RS] extends [undefined, undefined]
101+
? (...args: ARGS) => RETURN
102+
: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>
103+
50104
/**
51105
* An in-page channel function definition: the `defineRpcFunction` authoring
52106
* shape (`name`, `type`, Standard-Schema `args`/`returns`,
@@ -65,27 +119,11 @@ export type InPageFunctionDefinition<
65119
AS extends RpcArgsSchema | undefined = undefined,
66120
RS extends RpcReturnSchema | undefined = undefined,
67121
>
68-
= [AS, RS] extends [undefined, undefined]
69-
? ({
70-
name: NAME
71-
type?: TYPE
72-
args?: AS
73-
returns?: RS
74-
jsonSerializable?: boolean
75-
} & (TYPE extends 'event'
76-
? { handler?: (...args: ARGS) => RETURN }
77-
: { handler: (...args: ARGS) => RETURN }))
78-
: ({
79-
name: NAME
80-
type?: TYPE
81-
/** Standard Schema array validating (and typing) the arguments. */
82-
args: AS
83-
/** Standard Schema typing the resolved return value. */
84-
returns: RS
85-
jsonSerializable?: boolean
86-
} & (TYPE extends 'event'
87-
? { handler?: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>> }
88-
: { handler: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>> }))
122+
= InPageFunctionDefinitionForType<
123+
NAME,
124+
TYPE,
125+
InPageFunctionDefinitionHandler<ARGS, RETURN, AS, RS>
126+
> & InPageFunctionDefinitionSchemas<AS, RS>
89127

90128
/**
91129
* Loosely-typed definition used by the internal function registry.
@@ -107,15 +145,25 @@ interface InPageFunctionOptionBase {
107145
jsonSerializable?: boolean
108146
}
109147

148+
interface InPageEventFunctionOption<F> extends InPageFunctionOptionBase {
149+
type: 'event'
150+
handler?: ProtocolHandler<F>
151+
}
152+
153+
interface InPageQueryFunctionOption<F> extends InPageFunctionOptionBase {
154+
type?: 'query'
155+
handler: ProtocolHandler<F>
156+
}
157+
158+
interface InPageActionFunctionOption<F> extends InPageFunctionOptionBase {
159+
type: 'action'
160+
handler: ProtocolHandler<F>
161+
}
162+
110163
type InPageFunctionOption<F>
111-
= | (InPageFunctionOptionBase & {
112-
type: 'event'
113-
handler?: ProtocolHandler<F>
114-
})
115-
| (InPageFunctionOptionBase & {
116-
type?: Exclude<InPageFunctionType, 'event'>
117-
handler: ProtocolHandler<F>
118-
})
164+
= | InPageEventFunctionOption<F>
165+
| InPageQueryFunctionOption<F>
166+
| InPageActionFunctionOption<F>
119167

120168
/**
121169
* Functions implemented by {@link createPageScriptChannel}.

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

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,7 @@ export type InPageChannelErrorCode = 'timeout' |
6262
'invalid-args' |
6363
'state-uninitialized';
6464
export type InPageChannelStatus = 'connecting' | 'connected' | 'closed';
65-
export type InPageFunctionDefinition<NAME extends string, TYPE extends InPageFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined> = [AS, RS] extends [undefined, undefined] ? ({
66-
name: NAME;
67-
type?: TYPE;
68-
args?: AS;
69-
returns?: RS;
70-
jsonSerializable?: boolean;
71-
} & (TYPE extends 'event' ? {
72-
handler?: (...args: ARGS) => RETURN;
73-
} : {
74-
handler: (...args: ARGS) => RETURN;
75-
})) : ({
76-
name: NAME;
77-
type?: TYPE;
78-
args: AS;
79-
returns: RS;
80-
jsonSerializable?: boolean;
81-
} & (TYPE extends 'event' ? {
82-
handler?: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
83-
} : {
84-
handler: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
85-
}));
65+
export type InPageFunctionDefinition<NAME extends string, TYPE extends InPageFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined> = InPageFunctionDefinitionForType<NAME, TYPE, InPageFunctionDefinitionHandler<ARGS, RETURN, AS, RS>> & InPageFunctionDefinitionSchemas<AS, RS>;
8666
// #endregion
8767

8868
// #region Classes
@@ -98,7 +78,7 @@ export declare class InPageChannelError extends Error {
9878
// #region Functions
9979
export declare function connectPanelChannel<P extends InPageChannelProtocol>(_: ConnectPanelChannelOptions<P>): PanelChannel<P>;
10080
export declare function createPageScriptChannel<P extends InPageChannelProtocol>(_: CreatePageScriptChannelOptions<P>): PageScriptChannel<P>;
101-
export declare function defineChannelFunction<NAME extends string, TYPE extends InPageFunctionType, ARGS extends any[] = [], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(_: InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>): InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>;
81+
export declare function defineChannelFunction<NAME extends string, TYPE extends InPageFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(_: InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>): InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>;
10282
// #endregion
10383

10484
// #region Referenced (internal)
@@ -117,6 +97,15 @@ interface InPageChannelCommonOptions {
11797
serialize?: (_: unknown) => unknown;
11898
deserialize?: (_: unknown) => unknown;
11999
}
100+
type InPageFunctionDefinitionForType<NAME extends string, TYPE extends InPageFunctionType, HANDLER> = TYPE extends 'event' ? InPageEventFunctionDefinition<NAME, HANDLER> : TYPE extends 'action' ? InPageActionFunctionDefinition<NAME, HANDLER> : InPageQueryFunctionDefinition<NAME, HANDLER>;
101+
type InPageFunctionDefinitionHandler<ARGS extends any[], RETURN, AS extends RpcArgsSchema | undefined, RS extends RpcReturnSchema | undefined> = [AS, RS] extends [undefined, undefined] ? (...args: ARGS) => RETURN : (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
102+
type InPageFunctionDefinitionSchemas<AS extends RpcArgsSchema | undefined, RS extends RpcReturnSchema | undefined> = [AS, RS] extends [undefined, undefined] ? {
103+
args?: AS;
104+
returns?: RS;
105+
} : {
106+
args: AS;
107+
returns: RS;
108+
};
120109
type InPageFunctionType = 'action' | 'event' | 'query';
121110
interface InPageSharedStateHost<P extends InPageChannelProtocol> {
122111
get: <K extends keyof SharedStates<P> & string>(_: K, _?: {

0 commit comments

Comments
 (0)