Skip to content

Commit

Permalink
fix(reactant-share): fix delegate() type issue
Browse files Browse the repository at this point in the history
  • Loading branch information
unadlib committed May 24, 2024
1 parent 182e842 commit bf2034f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/reactant-share/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class AppView extends ViewModule {
component() {
const count = useConnector(() => this.counter.count);
return (
<button type="button" onClick={() => delegate(this.counter, 'increase', [])}>
<button type="button" onClick={() => delegate(this.counter, 'increase')}>
{count}
</button>
);
Expand Down
13 changes: 7 additions & 6 deletions packages/reactant-share/src/delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ import { PortDetector } from './modules/portDetector';
* ```
* reference: https://en.wikipedia.org/wiki/Actor_model
*/
export const delegate: ProxyExec = (module, key, args, options = {}) => {
export const delegate = ((module, key, args, options = {}) => {
const method = module[key];
const _args = args ?? [];
if (typeof key !== 'string') {
throw new Error(
`'delegate()' is valid only for method name with string type.`
Expand All @@ -60,7 +61,7 @@ export const delegate: ProxyExec = (module, key, args, options = {}) => {
`The property '${key}'' must be a method in class '${module.constructor.name}'.`
);
}
if (!Array.isArray(args)) {
if (!Array.isArray(_args)) {
throw new Error(`The parameters of the method '${key}' must be an array.`);
}
const target: Service & ProxyExecutor = module;
Expand All @@ -79,7 +80,7 @@ export const delegate: ProxyExec = (module, key, args, options = {}) => {
return target[proxyExecutorKey]({
module: target[identifierKey]!,
method: key,
args,
args: _args,
});
}
// If the port is not a client, it just run the method in server port.
Expand All @@ -99,10 +100,10 @@ export const delegate: ProxyExec = (module, key, args, options = {}) => {
{
module: target[identifierKey]!,
method: key,
args,
args: _args,
}
);
}
}
return (method as Function).apply(target, args);
};
return (method as Function).apply(target, _args);
}) as ProxyExec;
1 change: 1 addition & 0 deletions packages/reactant-share/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export { delegate } from './delegate';
export { fork } from './fork';
export { mockPairTransports } from './mockPairTransports';
export { createBroadcastTransport } from './createTransport';
export { applyMethod } from './applyMethod';

export type { IRouterOptions } from './modules/router';
export type { ICoworkerOptions } from './modules/coworker';
Expand Down
43 changes: 32 additions & 11 deletions packages/reactant-share/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,37 @@ export type FunctionKeys<T> = Exclude<
void
>;

type ProxyArgs<
F extends (...args: any[]) => any,
O extends EmitParameter<any>['respond']
> = Parameters<F> extends []
? [
/**
* Pass in the parameters for this method.
*/
args?: Parameters<F>,
/**
* proxy execution options
*/
options?: { respond?: O; portName?: string; clientIds?: string[] } & Pick<
EmitParameter<any>,
Exclude<keyof EmitParameter<any>, 'name' | 'respond'>
>
]
: [
/**
* Pass in the parameters for this method.
*/
args: Parameters<F>,
/**
* proxy execution options
*/
options?: { respond?: O; portName?: string; clientIds?: string[] } & Pick<
EmitParameter<any>,
Exclude<keyof EmitParameter<any>, 'name' | 'respond'>
>
];

export type ProxyExec = <
T extends Record<string | number | symbol, any>,
K extends FunctionKeys<T>,
Expand All @@ -219,17 +250,7 @@ export type ProxyExec = <
* Specify the name of a method in this module.
*/
key: K,
/**
* Pass in the parameters for this method.
*/
args: Parameters<T[K]>,
/**
* proxy execution options
*/
options?: { respond?: O; portName?: string; clientIds?: string[] } & Pick<
EmitParameter<any>,
Exclude<keyof EmitParameter<any>, 'name' | 'respond'>
>
...args: ProxyArgs<T[K], O>
) => O extends false
? void
: ReturnType<T[K]> extends Promise<infer R>
Expand Down
20 changes: 12 additions & 8 deletions packages/reactant-share/test/coworker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ describe('base', () => {
<button
id="decrease"
type="button"
onClick={() => delegate(this.counter, 'decrease', [])}
onClick={() => delegate(this.counter, 'decrease')}
>
-
</button>
<div id="count">{count}</div>
<button
id="increase"
type="button"
onClick={() => delegate(this.counter, 'increase', [])}
onClick={() => delegate(this.counter, 'increase')}
>
+
</button>
Expand Down Expand Up @@ -360,9 +360,14 @@ describe('base', () => {
expect(serverApp.instance.counter.num).toBe(4);
expect(result2).toBe(4);

const result3 = await delegate(clientApp.instance.counter, 'setNum', [5], {
respond: false,
});
const result3 = await delegate(
clientApp.instance.counter,
'setNum',
[5],
{
respond: false,
}
);

expect(clientApp.instance.counter.num).toBe(3);
expect(serverApp.instance.counter.num).toBe(5);
Expand Down Expand Up @@ -787,7 +792,7 @@ describe('base', () => {

expect(coworkerApp.container.get(ProxyCounter).count).toBe(0);

await delegate(serverApp.container.get(ProxyCounter), 'increase', []);
await delegate(serverApp.container.get(ProxyCounter), 'increase');
expect(coworkerApp.container.get(ProxyCounter).count).toBe(1);
expect(serverApp.container.get(ProxyCounter).count).toBe(1);
expect(subscribeOnClientFn.mock.calls.length).toBe(0);
Expand Down Expand Up @@ -839,8 +844,7 @@ describe('base', () => {

await delegate(
serverApp.container.get<ProxyCounter>('counter0'),
'increase',
[]
'increase'
);
expect(
counterCoworkerApp.container.get<ProxyCounter>('counter0').count
Expand Down

0 comments on commit bf2034f

Please sign in to comment.