@zimi/remote 0.1.0 → 0.1.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,8 @@
1
- # @zimi/remote
2
-
3
- 像调用本地函数一样调用远端的函数
1
+ > 代码见 [@zimi/remote](https://github.com/xiaomingTang/xiaoming/tree/master/%40zimi/remote)
4
2
 
5
3
  - 本地可以是浏览器、服务器,甚至一些受限的 `js` 子集
6
- - 远端可以是任何语言,如 `Java`
7
- - 对远端响应的数据格式也不严格限制
4
+ - 远端可以是任何终端,如 `iframe` / `Java` 服务器 等
5
+ - 对远端响应的数据格式也不严格限制(可以集中解析)
8
6
 
9
7
  ## install
10
8
  ```
@@ -13,7 +11,22 @@ pnpm i @zimi/remote
13
11
 
14
12
  ## examples
15
13
 
16
- ### iframe 与父级通信
14
+ ### 使用示例
15
+
16
+ ```ts
17
+
18
+ // 远端
19
+ remote.register('something', async (params: Whatever) => {
20
+ return WhatYouWant
21
+ })
22
+
23
+ // 本地
24
+ // res === WhatYouWant
25
+ const res = await remote._.something(xxx)
26
+
27
+ ```
28
+
29
+ ### iframe 与父级相互调用
17
30
 
18
31
  ```ts
19
32
  // 1. 声明各自能提供的函数类型
@@ -37,13 +50,14 @@ export type FuncsFromChild = {
37
50
  import { Remote, createIframeAdaptor } from '@zimi/remote'
38
51
 
39
52
  function getOpWindow() {
40
- return (document.getElementById('child-iframe') as HTMLIFrameElement | null)?.contentWindow
53
+ return document.querySelector<HTMLIFrameElement>('#child-iframe')?.contentWindow
41
54
  }
42
55
 
43
56
  // 我们提供了生成 iframe adaptor 的工具函数
44
57
  // 你也可以参考实现自己的 adaptor, 没多少代码
45
58
  const adaptor = createIframeAdaptor({
46
59
  onEmit: (data) => {
60
+ // 此处仅为示意,业务场景下应当限制对方的域名
47
61
  getOpWindow()?.postMessage(data, '*')
48
62
  },
49
63
  })
@@ -70,6 +84,7 @@ function getOpWindow() {
70
84
  // 你也可以参考实现自己的 adaptor, 没多少代码
71
85
  const adaptor = createIframeAdaptor({
72
86
  onEmit: (data) => {
87
+ // 此处仅为示意,业务场景下应当限制对方的域名
73
88
  getOpWindow()?.postMessage(data, '*')
74
89
  },
75
90
  })
@@ -182,3 +197,16 @@ await remote._.xxx(anyData)
182
197
  ### 与其他端通信(如 websocket)略
183
198
 
184
199
  你可以看看 `iframe adaptor` / `http adaptor` 源码,包含空行也就 30 行,依葫芦画瓢很轻易就能写一个。
200
+
201
+ ## 与 rpc 相比的优势
202
+
203
+ - 不局限于与服务端的通信,无论对方是任何端,只要能与 js 通信,就能使用该包;
204
+ - 相互通信,不存在“主从”的概念,通信双方是平等的;
205
+ - 类型严格;
206
+ - 包较底层,对项目整体的侵入较小,几乎不限制对方的响应的数据格式(因为可以自由解析对方的响应,即自由 emit);
207
+
208
+ ## 协议
209
+
210
+ > 由于通信双方是平等的,所以 B 调用 A 的流程也是一样的
211
+
212
+ ![protocol.png](https://cdn.16px.cc/public/2024-12-08/fm5up4GM9UCz.png?r=1682x836)
@@ -1,13 +1,13 @@
1
- import EventEmitter from 'eventemitter3';
2
- import type { Adaptor, AdaptorPackageData } from '../adaptor';
3
- declare class RemoteEventManager extends EventEmitter<{
4
- [key: string]: [AdaptorPackageData];
5
- }> {
6
- EVERY_EVENT_NAME: string;
7
- onEvery(fn: (data: AdaptorPackageData) => void): void;
8
- }
9
- export declare const remoteEventManager: RemoteEventManager;
10
- export declare function createHttpAdaptor({ onEmit, }: {
11
- onEmit: (data: AdaptorPackageData) => void;
12
- }): Adaptor;
13
- export {};
1
+ import EventEmitter from 'eventemitter3';
2
+ import type { Adaptor, AdaptorPackageData } from '../adaptor';
3
+ declare class RemoteEventManager extends EventEmitter<{
4
+ [key: string]: [AdaptorPackageData];
5
+ }> {
6
+ EVERY_EVENT_NAME: string;
7
+ onEvery(fn: (data: AdaptorPackageData) => void): void;
8
+ }
9
+ export declare const remoteEventManager: RemoteEventManager;
10
+ export declare function createHttpAdaptor({ onEmit, }: {
11
+ onEmit: (data: AdaptorPackageData) => void;
12
+ }): Adaptor;
13
+ export {};
@@ -1,26 +1,27 @@
1
- import EventEmitter from 'eventemitter3';
2
- class RemoteEventManager extends EventEmitter {
3
- constructor() {
4
- super(...arguments);
5
- Object.defineProperty(this, "EVERY_EVENT_NAME", {
6
- enumerable: true,
7
- configurable: true,
8
- writable: true,
9
- value: '__remote_every__'
10
- });
11
- }
12
- onEvery(fn) {
13
- this.on(this.EVERY_EVENT_NAME, fn);
14
- }
15
- }
16
- export const remoteEventManager = new RemoteEventManager();
17
- export function createHttpAdaptor({ onEmit, }) {
18
- const adaptor = {
19
- every: remoteEventManager.onEvery.bind(remoteEventManager),
20
- once: remoteEventManager.once.bind(remoteEventManager),
21
- off: remoteEventManager.off.bind(remoteEventManager),
22
- emit: onEmit,
23
- };
24
- return adaptor;
25
- }
1
+ import EventEmitter from 'eventemitter3';
2
+ class RemoteEventManager extends EventEmitter {
3
+ constructor() {
4
+ super(...arguments);
5
+ Object.defineProperty(this, "EVERY_EVENT_NAME", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: '__remote_every__'
10
+ });
11
+ }
12
+ onEvery(fn) {
13
+ this.on(this.EVERY_EVENT_NAME, fn);
14
+ }
15
+ }
16
+ export const remoteEventManager = new RemoteEventManager();
17
+ export function createHttpAdaptor({ onEmit, }) {
18
+ const adaptor = {
19
+ every: remoteEventManager.onEvery.bind(remoteEventManager),
20
+ on: remoteEventManager.on.bind(remoteEventManager),
21
+ once: remoteEventManager.once.bind(remoteEventManager),
22
+ off: remoteEventManager.off.bind(remoteEventManager),
23
+ emit: onEmit,
24
+ };
25
+ return adaptor;
26
+ }
26
27
  //# sourceMappingURL=http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/adaptors/http.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAIxC,MAAM,kBAAmB,SAAQ,YAE/B;IAFF;;QAGE;;;;mBAAmB,kBAAkB;WAAA;IAKvC,CAAC;IAHC,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACpC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAA;AAE1D,MAAM,UAAU,iBAAiB,CAAC,EAChC,MAAM,GAGP;IACC,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC1D,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACtD,GAAG,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACpD,IAAI,EAAE,MAAM;KACb,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/adaptors/http.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAIxC,MAAM,kBAAmB,SAAQ,YAE/B;IAFF;;QAGE;;;;mBAAmB,kBAAkB;WAAA;IAKvC,CAAC;IAHC,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACpC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAA;AAE1D,MAAM,UAAU,iBAAiB,CAAC,EAChC,MAAM,GAGP;IACC,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC1D,EAAE,EAAE,kBAAkB,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAClD,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACtD,GAAG,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACpD,IAAI,EAAE,MAAM;KACb,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Adaptor, AdaptorPackageData } from '../adaptor';
2
- export declare function createIframeAdaptor({ onEmit, }: {
3
- onEmit: (data: AdaptorPackageData) => void;
4
- }): Adaptor;
1
+ import type { Adaptor, AdaptorPackageData } from '../adaptor';
2
+ export declare function createIframeAdaptor({ onEmit, }: {
3
+ onEmit: (data: AdaptorPackageData) => void;
4
+ }): Adaptor;
@@ -1,38 +1,39 @@
1
- import EventEmitter from 'eventemitter3';
2
- import { isRemoteAdaptorData } from '../remote';
3
- class RemoteEventManager extends EventEmitter {
4
- constructor() {
5
- super();
6
- Object.defineProperty(this, "EVERY_EVENT_NAME", {
7
- enumerable: true,
8
- configurable: true,
9
- writable: true,
10
- value: '__remote_every__'
11
- });
12
- if (typeof window === 'undefined') {
13
- return;
14
- }
15
- window.addEventListener('message', (event) => {
16
- const { data } = event;
17
- if (isRemoteAdaptorData(data)) {
18
- this.emit(data.name, data);
19
- // 一定要抛出 every 事件,remote 包基于此处理远端的响应
20
- this.emit(this.EVERY_EVENT_NAME, data);
21
- }
22
- });
23
- }
24
- onEvery(fn) {
25
- this.on(this.EVERY_EVENT_NAME, fn);
26
- }
27
- }
28
- export function createIframeAdaptor({ onEmit, }) {
29
- const remoteEventManager = new RemoteEventManager();
30
- const adaptor = {
31
- every: remoteEventManager.onEvery.bind(remoteEventManager),
32
- once: remoteEventManager.once.bind(remoteEventManager),
33
- off: remoteEventManager.off.bind(remoteEventManager),
34
- emit: onEmit,
35
- };
36
- return adaptor;
37
- }
1
+ import EventEmitter from 'eventemitter3';
2
+ import { isRemoteAdaptorData } from '../remote';
3
+ class RemoteEventManager extends EventEmitter {
4
+ constructor() {
5
+ super();
6
+ Object.defineProperty(this, "EVERY_EVENT_NAME", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: '__remote_every__'
11
+ });
12
+ if (typeof window === 'undefined') {
13
+ return;
14
+ }
15
+ window.addEventListener('message', (event) => {
16
+ const { data } = event;
17
+ if (isRemoteAdaptorData(data)) {
18
+ this.emit(data.name, data);
19
+ // 一定要抛出 every 事件,remote 包基于此处理远端的响应
20
+ this.emit(this.EVERY_EVENT_NAME, data);
21
+ }
22
+ });
23
+ }
24
+ onEvery(fn) {
25
+ this.on(this.EVERY_EVENT_NAME, fn);
26
+ }
27
+ }
28
+ export function createIframeAdaptor({ onEmit, }) {
29
+ const remoteEventManager = new RemoteEventManager();
30
+ const adaptor = {
31
+ every: remoteEventManager.onEvery.bind(remoteEventManager),
32
+ on: remoteEventManager.on.bind(remoteEventManager),
33
+ once: remoteEventManager.once.bind(remoteEventManager),
34
+ off: remoteEventManager.off.bind(remoteEventManager),
35
+ emit: onEmit,
36
+ };
37
+ return adaptor;
38
+ }
38
39
  //# sourceMappingURL=iframe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"iframe.js","sourceRoot":"","sources":["../../src/adaptors/iframe.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAI/C,MAAM,kBAAmB,SAAQ,YAE/B;IAGA;QACE,KAAK,EAAE,CAAA;QAHT;;;;mBAAmB,kBAAkB;WAAA;QAInC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,OAAM;SACP;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;YACtB,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE;gBAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBAC1B,oCAAoC;gBACpC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAA;aACvC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACpC,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,MAAM,GAGP;IACC,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAA;IAEnD,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC1D,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACtD,GAAG,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACpD,IAAI,EAAE,MAAM;KACb,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
1
+ {"version":3,"file":"iframe.js","sourceRoot":"","sources":["../../src/adaptors/iframe.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAI/C,MAAM,kBAAmB,SAAQ,YAE/B;IAGA;QACE,KAAK,EAAE,CAAA;QAHT;;;;mBAAmB,kBAAkB;WAAA;QAInC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3C,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;YACtB,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBAC1B,oCAAoC;gBACpC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAA;YACxC,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACpC,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,MAAM,GAGP;IACC,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAA;IAEnD,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC1D,EAAE,EAAE,kBAAkB,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAClD,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACtD,GAAG,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACpD,IAAI,EAAE,MAAM;KACb,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { Remote, isRemoteAdaptorData } from './remote';
2
- export type { AdaptorPackageData, Adaptor } from './adaptor';
3
- export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from './response';
4
- export { createIframeAdaptor } from './adaptors/iframe';
5
- export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
1
+ export { Remote, isRemoteAdaptorData } from './remote';
2
+ export type { AdaptorPackageData, Adaptor } from './adaptor';
3
+ export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from './response';
4
+ export { createIframeAdaptor } from './adaptors/iframe';
5
+ export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
6
+ export { remoteValue, exposeToRemote } from './remoteValue';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- export { Remote, isRemoteAdaptorData } from './remote';
2
- export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from './response';
3
- export { createIframeAdaptor } from './adaptors/iframe';
4
- export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
1
+ export { Remote, isRemoteAdaptorData } from './remote';
2
+ export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from './response';
3
+ export { createIframeAdaptor } from './adaptors/iframe';
4
+ export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
5
+ export { remoteValue, exposeToRemote } from './remoteValue';
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACvE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
package/dist/remote.d.ts CHANGED
@@ -1,79 +1,79 @@
1
- import type { Adaptor, AdaptorPackageData } from './adaptor';
2
- type LogFunc = (...data: unknown[]) => void;
3
- type RemoteCallableFunc = (data: any) => Promise<any>;
4
- interface RemoteFuncRecords {
5
- [key: string]: RemoteCallableFunc;
6
- }
7
- type FuncMapWithConfig<T extends RemoteFuncRecords> = {
8
- [K in keyof T]: T[K] extends (data: infer Arg) => Promise<infer Ret> ? (data: Arg, config?: {
9
- timeoutMs?: number;
10
- targetDeviceId?: string;
11
- }) => Promise<Ret> : never;
12
- };
13
- type RegisteredFunc<T extends RemoteCallableFunc> = T extends (data: infer Arg) => infer Ret ? (data: Arg, ctx: {
14
- /**
15
- * 对方的设备 id
16
- */
17
- deviceId: string;
18
- }) => Ret : never;
19
- export declare class Remote<
20
- /**
21
- * MF means my functions
22
- */
23
- MF extends RemoteFuncRecords,
24
- /**
25
- * OF means others functions
26
- */
27
- OF extends RemoteFuncRecords> {
28
- private adaptor;
29
- debug: boolean;
30
- private log;
31
- /**
32
- * (调用对方函数时的)默认超时时间,单位 ms
33
- * @default 30000
34
- */
35
- private defaultTimeoutMs;
36
- private map;
37
- private deviceIdValue;
38
- /**
39
- * 设备 id 应该唯一,用于区分不同设备。
40
- * 你可以在任何时候修改(更新)它。
41
- * @default ''
42
- */
43
- get deviceId(): string;
44
- set deviceId(deviceId: string);
45
- constructor(adaptor: Adaptor, config?: {
46
- /**
47
- * 设备 id 应该唯一,用于区分不同设备。
48
- * 你可以在任何时候修改(更新)它。
49
- * @default ''
50
- */
51
- deviceId?: string;
52
- /**
53
- * (调用对方函数时的)默认超时时间,单位 ms
54
- * @default 30000
55
- */
56
- defaultTimeoutMs?: number;
57
- debug?: boolean;
58
- /**
59
- * 格式化 AdaptorPackageData 的函数,
60
- * 用于调试时输出日志。
61
- * @default JSON.stringify
62
- */
63
- log?: LogFunc;
64
- });
65
- /**
66
- * 调用其他端的方法;会等待对方响应。
67
- * 不能直接使用该方法,应该使用 proxy。
68
- * @WARNING 不能用于响应其他端。
69
- */
70
- private callAsync;
71
- /**
72
- * 注册方法,供对方调用;
73
- */
74
- register<K extends keyof MF>(name: K, callback: RegisteredFunc<MF[K]>): void;
75
- _: FuncMapWithConfig<OF>;
76
- self: MF;
77
- }
78
- export declare function isRemoteAdaptorData(data: unknown): data is AdaptorPackageData;
79
- export {};
1
+ import type { Adaptor, AdaptorPackageData } from './adaptor';
2
+ type LogFunc = (...data: unknown[]) => void;
3
+ type RemoteCallableFunc = (data: any) => Promise<any>;
4
+ interface RemoteFuncRecords {
5
+ [key: string]: RemoteCallableFunc;
6
+ }
7
+ type FuncMapWithConfig<T extends RemoteFuncRecords> = {
8
+ [K in keyof T]: T[K] extends (data: infer Arg) => Promise<infer Ret> ? (data: Arg, config?: {
9
+ timeoutMs?: number;
10
+ targetDeviceId?: string;
11
+ }) => Promise<Ret> : never;
12
+ };
13
+ type RegisteredFunc<T extends RemoteCallableFunc> = T extends (data: infer Arg) => infer Ret ? (data: Arg, ctx: {
14
+ /**
15
+ * 对方的设备 id
16
+ */
17
+ deviceId: string;
18
+ }) => Ret : never;
19
+ export declare class Remote<
20
+ /**
21
+ * MF means my functions
22
+ */
23
+ MF extends RemoteFuncRecords,
24
+ /**
25
+ * OF means others functions
26
+ */
27
+ OF extends RemoteFuncRecords> {
28
+ private adaptor;
29
+ debug: boolean;
30
+ private log;
31
+ /**
32
+ * (调用对方函数时的)默认超时时间,单位 ms
33
+ * @default 30000
34
+ */
35
+ private defaultTimeoutMs;
36
+ private map;
37
+ private deviceIdValue;
38
+ /**
39
+ * 设备 id 应该唯一,用于区分不同设备。
40
+ * 你可以在任何时候修改(更新)它。
41
+ * @default ''
42
+ */
43
+ get deviceId(): string;
44
+ set deviceId(deviceId: string);
45
+ constructor(adaptor: Adaptor, config?: {
46
+ /**
47
+ * 设备 id 应该唯一,用于区分不同设备。
48
+ * 你可以在任何时候修改(更新)它。
49
+ * @default ''
50
+ */
51
+ deviceId?: string;
52
+ /**
53
+ * (调用对方函数时的)默认超时时间,单位 ms
54
+ * @default 30000
55
+ */
56
+ defaultTimeoutMs?: number;
57
+ debug?: boolean;
58
+ /**
59
+ * 格式化 AdaptorPackageData 的函数,
60
+ * 用于调试时输出日志。
61
+ * @default JSON.stringify
62
+ */
63
+ log?: LogFunc;
64
+ });
65
+ /**
66
+ * 调用其他端的方法;会等待对方响应。
67
+ * 不能直接使用该方法,应该使用 proxy。
68
+ * @WARNING 不能用于响应其他端。
69
+ */
70
+ private callAsync;
71
+ /**
72
+ * 注册方法,供对方调用;
73
+ */
74
+ register<K extends keyof MF>(name: K, callback: RegisteredFunc<MF[K]>): void;
75
+ _: FuncMapWithConfig<OF>;
76
+ self: MF;
77
+ }
78
+ export declare function isRemoteAdaptorData(data: unknown): data is AdaptorPackageData;
79
+ export {};