@zimi/remote 0.2.1-alpha.9 → 0.2.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
@@ -212,3 +212,74 @@ await remote._.xxx(anyData)
212
212
  > 由于通信双方是平等的,所以 B 调用 A 的流程也是一样的
213
213
 
214
214
  ![protocol.png](https://cdn.16px.cc/public/2024-12-08/fm5up4GM9UCz.png?r=1682x836)
215
+
216
+ ---
217
+ ---
218
+
219
+ ## remote value
220
+
221
+ > 像使用 local value 一样使用 remote value
222
+
223
+ **首先强调一遍,这个包是一个通信的包,不负责权限控制,需要使用者在业务层面进行恰当的处理,控制好什么该暴露,什么不该暴露。**
224
+
225
+ 如果我们(暂且称为 甲 端)需要访问其他端(可能是服务器,也可能是其他 iframe or whatever,暂且称为 乙 端)的一些数据/对象/方法,我们通常是这么做的:
226
+
227
+ // 乙 端
228
+ ```ts
229
+ const obj = {
230
+ value: number,
231
+ setValue: (newValue: number) => {
232
+ obj.value = newValue
233
+ }
234
+ }
235
+
236
+ register({
237
+ method: 'get',
238
+ name: 'getValue',
239
+ handler: () => {
240
+ return obj.value
241
+ }
242
+ })
243
+
244
+ register({
245
+ method: 'post',
246
+ name: 'setValue',
247
+ handler: (newValue: string) => {
248
+ obj.setValue(newValue)
249
+ }
250
+ })
251
+ ```
252
+
253
+ // 甲 端
254
+ ```ts
255
+ const value = await fetch.get('getValue')
256
+ await fetch.post('setValue', newValue)
257
+ ```
258
+
259
+ 有没有感觉在重复劳动?我 乙 端已经有了一个现成的`obj`,可是我还是需要在`register`处“封装”一下。
260
+
261
+ ---
262
+
263
+ 那么,**下面这个**怎么样:
264
+
265
+ // 乙 端
266
+ ```ts
267
+ exposeToRemote(obj, config)
268
+ ```
269
+
270
+ // 甲 端
271
+ ```ts
272
+ import { type obj } from '/path/to/obj'
273
+
274
+ const remoteObj = remoteValue<typeof obj>(config)
275
+
276
+ // 很遗憾没能实现 await remoteObj.value 直接取值,
277
+ // 无论是值还是函数,必须在后面加一个括号调用,才能取到结果。
278
+ const value = await remoteObj.value()
279
+ const subValue = await remoteObj.deep.path.to.value()
280
+
281
+ await remoteObj.setValue(newValue)
282
+ await remoteObj.deep.path.to.func(...params)
283
+ ```
284
+
285
+ **再次强调一遍,这个包是一个通信的包,不负责权限控制,需要使用者在业务层面进行恰当的处理,控制好什么该暴露,什么不该暴露。**
package/dist/adaptor.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export interface AdaptorPackageData {
1
+ export interface AdaptorPackageData<D = unknown> {
2
2
  /**
3
3
  * 自身设备 id,应确保唯一性(对方能凭借该 deviceId 找到该设备)
4
4
  */
@@ -11,7 +11,7 @@ export interface AdaptorPackageData {
11
11
  * 远程调用的对方的方法名
12
12
  */
13
13
  name: string;
14
- data: unknown;
14
+ data: D;
15
15
  /**
16
16
  * 所需回调的方法名(如果需要回调的话)
17
17
  */
@@ -17,6 +17,15 @@ interface RemoteChannel {
17
17
  * remoteChannel.sendServerEvent(e)
18
18
  * },
19
19
  * } satisfies Adaptor
20
+ *
21
+ * export const remote = new Remote<RemoteFuncsFromClient, RemoteFuncsFromServer>(
22
+ * remoteAdaptor,
23
+ * {
24
+ * deviceId: `client-${Math.random().toString(36).slice(2)}`,
25
+ * }
26
+ * )
27
+ *
28
+ * void remote._.initConnection()
20
29
  * ```
21
30
  */
22
31
  export declare class ClientSideRemoteChannelEventManager extends EventEmitter<{
@@ -14,6 +14,15 @@ import { isRemoteAdaptorData } from '../../remote';
14
14
  * remoteChannel.sendServerEvent(e)
15
15
  * },
16
16
  * } satisfies Adaptor
17
+ *
18
+ * export const remote = new Remote<RemoteFuncsFromClient, RemoteFuncsFromServer>(
19
+ * remoteAdaptor,
20
+ * {
21
+ * deviceId: `client-${Math.random().toString(36).slice(2)}`,
22
+ * }
23
+ * )
24
+ *
25
+ * void remote._.initConnection()
17
26
  * ```
18
27
  */
19
28
  export class ClientSideRemoteChannelEventManager extends EventEmitter {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/client.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAOlD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,mCAAoC,SAAQ,YAEvD;IACA,YAAY,aAA4B;QACtC,KAAK,EAAE,CAAA;QACP,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,OAAM;YACR,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;YAClC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/client.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAOlD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,mCAAoC,SAAQ,YAEvD;IACA,YAAY,aAA4B;QACtC,KAAK,EAAE,CAAA;QACP,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,OAAM;YACR,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;YAClC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;CACF"}
@@ -26,7 +26,7 @@ interface RemoteChannel<T extends GamePlayerEntityLike> {
26
26
  * on: remoteManager.on.bind(remoteManager),
27
27
  * once: remoteManager.once.bind(remoteManager),
28
28
  * emit: (e) => {
29
- * const entity = getEntity(e.targetDeviceId)
29
+ * const entity = remoteManager.getEntity(e.targetDeviceId)
30
30
  * if (!entity) {
31
31
  * console.error('entity not found')
32
32
  * return
@@ -35,6 +35,21 @@ interface RemoteChannel<T extends GamePlayerEntityLike> {
35
35
  * },
36
36
  * } satisfies Adaptor
37
37
  *
38
+ * export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(
39
+ * remoteAdaptor,
40
+ * {
41
+ * deviceId: 'server',
42
+ * }
43
+ * )
44
+ *
45
+ * remote.register('initConnection', async () => {
46
+ * // 什么也不干,单纯的让客户端在服务端“备案”
47
+ * })
48
+ *
49
+ * export const getEntity = remoteManager.getEntity.bind(remoteManager)
50
+ * export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)
51
+ * export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)
52
+ * export const remoteTo = remoteManager.remoteTo.bind(remoteManager)
38
53
  * ```
39
54
  */
40
55
  export declare class ServerSideRemoteChannelEventManager<T extends GamePlayerEntityLike> extends EventEmitter<{
@@ -16,7 +16,7 @@ import { isRemoteValueEvent } from '../../remoteValue/exposeToRemote';
16
16
  * on: remoteManager.on.bind(remoteManager),
17
17
  * once: remoteManager.once.bind(remoteManager),
18
18
  * emit: (e) => {
19
- * const entity = getEntity(e.targetDeviceId)
19
+ * const entity = remoteManager.getEntity(e.targetDeviceId)
20
20
  * if (!entity) {
21
21
  * console.error('entity not found')
22
22
  * return
@@ -25,6 +25,21 @@ import { isRemoteValueEvent } from '../../remoteValue/exposeToRemote';
25
25
  * },
26
26
  * } satisfies Adaptor
27
27
  *
28
+ * export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(
29
+ * remoteAdaptor,
30
+ * {
31
+ * deviceId: 'server',
32
+ * }
33
+ * )
34
+ *
35
+ * remote.register('initConnection', async () => {
36
+ * // 什么也不干,单纯的让客户端在服务端“备案”
37
+ * })
38
+ *
39
+ * export const getEntity = remoteManager.getEntity.bind(remoteManager)
40
+ * export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)
41
+ * export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)
42
+ * export const remoteTo = remoteManager.remoteTo.bind(remoteManager)
28
43
  * ```
29
44
  */
30
45
  export class ServerSideRemoteChannelEventManager extends EventEmitter {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/server.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export * from './adaptor';
3
3
  export * from './response';
4
4
  export * from './remoteValue/remoteValue';
5
5
  export * from './remoteValue/exposeToRemote';
6
- export type { ToFunc } from './remoteValue/type';
6
+ export type { ToFunc, RemoteCallData } from './remoteValue/type';
7
7
  export * from './adaptors/iframe';
8
8
  export * from './adaptors/http';
9
9
  export * from './adaptors/dao3/client';
@@ -1,4 +1,6 @@
1
1
  import { Adaptor, AdaptorPackageData } from '../adaptor';
2
+ import { RemoteCallData } from './type';
3
+ type AdaptorData = AdaptorPackageData<RemoteCallData>;
2
4
  interface ExposeProps {
3
5
  globalName: string;
4
6
  adaptor: Adaptor;
@@ -7,9 +9,32 @@ interface ExposeProps {
7
9
  */
8
10
  exposeTo: string[];
9
11
  /**
10
- * 你可以在该回调中抛错,以阻止远程调用
12
+ * 你可以在该回调中抛错,以阻止远程调用,
13
+ * 也可以修改传入的 data
11
14
  */
12
- onRequest?: (e: AdaptorPackageData) => void | Promise<void>;
15
+ onRequest?: (e: AdaptorData) => RemoteCallData | Promise<RemoteCallData>;
16
+ /**
17
+ * 如果你想要自定义处理函数,
18
+ * 需要谨慎且完善地处理各种 paths, args,
19
+ * 以避免远程调用时出现未预期的错误。
20
+ *
21
+ * ---
22
+ *
23
+ * 我的默认处理程序谨供参考:
24
+ * ``` ts
25
+ * let target = obj
26
+ * for (let i = 0; i < data.paths.length; i += 1) {
27
+ * target = target[data.paths[i] as keyof typeof target] as typeof target
28
+ * }
29
+ * if (target instanceof Function) {
30
+ * return target(...data.args)
31
+ * }
32
+ * return target
33
+ * ```
34
+ *
35
+ * @returns 返回值将会被发送给远程调用方,可以是立即数,也可以是 Promise(Promise 会 await 后再返回)
36
+ */
37
+ handler?: (e: AdaptorData) => unknown;
13
38
  }
14
39
  export declare function isRemoteValueEvent(eventName: string): boolean;
15
40
  export declare function exposeToRemote<T extends object>(obj: T, options: ExposeProps): () => void;
@@ -1,31 +1,34 @@
1
1
  import { RemoteError, response } from '../response';
2
2
  function defaultOnRequest(e) {
3
- return e;
3
+ return e.data;
4
4
  }
5
+ const geneDefaultHandler = (obj) => ({ data }) => {
6
+ let target = obj;
7
+ for (let i = 0; i < data.paths.length; i += 1) {
8
+ target = target[data.paths[i]];
9
+ }
10
+ if (target instanceof Function) {
11
+ return target(...data.args);
12
+ }
13
+ return target;
14
+ };
5
15
  export function isRemoteValueEvent(eventName) {
6
16
  return eventName.startsWith('__REMOTE_VALUE_REQ__');
7
17
  }
8
18
  export function exposeToRemote(obj, options) {
9
- const { globalName, adaptor, exposeTo, onRequest = defaultOnRequest, } = options;
19
+ const { globalName, adaptor, exposeTo, handler: inputHandler, onRequest = defaultOnRequest, } = options;
10
20
  const callback = async (e) => {
11
21
  var _a, _b;
12
22
  try {
13
- await onRequest(e);
23
+ const data = await onRequest(e);
14
24
  if (!exposeTo.includes(e.deviceId) && !exposeTo.includes('*')) {
15
25
  throw new RemoteError('permission denied');
16
26
  }
17
- const { paths, args } = e.data;
18
- let target = obj;
19
- for (let i = 0; i < paths.length; i += 1) {
20
- target = target[paths[i]];
21
- }
22
- let res;
23
- if (target instanceof Function) {
24
- res = await target(...args);
25
- }
26
- else {
27
- res = target;
28
- }
27
+ const handler = inputHandler !== null && inputHandler !== void 0 ? inputHandler : geneDefaultHandler(obj);
28
+ const res = await handler({
29
+ ...e,
30
+ data,
31
+ });
29
32
  adaptor.emit({
30
33
  name: (_a = e.callbackName) !== null && _a !== void 0 ? _a : 'IMPOSSIBLE_NO_CALLBACK_NAME',
31
34
  deviceId: e.targetDeviceId,
@@ -1 +1 @@
1
- {"version":3,"file":"exposeToRemote.js","sourceRoot":"","sources":["../../src/remoteValue/exposeToRemote.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAenD,SAAS,gBAAgB,CAAC,CAAqB;IAC7C,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,SAAS,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAmB,GAAM,EAAE,OAAoB;IAC3E,MAAM,EACJ,UAAU,EACV,OAAO,EACP,QAAQ,EACR,SAAS,GAAG,gBAAgB,GAC7B,GAAG,OAAO,CAAA;IACX,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAqB,EAAE,EAAE;;QAC/C,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,CAAC,CAAC,CAAA;YAClB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAA;YAC5C,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,IAA4C,CAAA;YACtE,IAAI,MAAM,GAAG,GAAG,CAAA;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAwB,CAAkB,CAAA;YACnE,CAAC;YACD,IAAI,GAAY,CAAA;YAChB,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;gBAC/B,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,MAAM,CAAA;YACd,CAAC;YACD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aAC5B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aACnD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC5D,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"exposeToRemote.js","sourceRoot":"","sources":["../../src/remoteValue/exposeToRemote.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAyCnD,SAAS,gBAAgB,CAAC,CAAc;IACtC,OAAO,CAAC,CAAC,IAAI,CAAA;AACf,CAAC;AAED,MAAM,kBAAkB,GACtB,CAAC,GAAG,EAAE,EAAE,CACR,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;IACX,IAAI,MAAM,GAAG,GAAG,CAAA;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAwB,CAAkB,CAAA;IACxE,CAAC;IACD,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAEH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,SAAS,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAmB,GAAM,EAAE,OAAoB;IAC3E,MAAM,EACJ,UAAU,EACV,OAAO,EACP,QAAQ,EACR,OAAO,EAAE,YAAY,EACrB,SAAS,GAAG,gBAAgB,GAC7B,GAAG,OAAO,CAAA;IACX,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAqB,EAAE,EAAE;;QAC/C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,CAAgB,CAAC,CAAA;YAC9C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAA;YAC5C,CAAC;YACD,MAAM,OAAO,GAAG,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,kBAAkB,CAAC,GAAG,CAAC,CAAA;YACvD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;gBACxB,GAAG,CAAC;gBACJ,IAAI;aACL,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aAC5B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aACnD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC5D,CAAC,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"remoteValue.js","sourceRoot":"","sources":["../../src/remoteValue/remoteValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAY,MAAM,aAAa,CAAA;AAIvE,SAAS,IAAI;IACX,OAAO;AACT,CAAC;AAYD,SAAS,SAAS,CAAmB,KAAe,EAAE,KAAuB;IAC3E,OAAO,IAAI,KAAK,CAAY,IAA4B,EAAE;QACxD,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ;YAC7B,MAAM,EACJ,OAAO,EACP,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,GAAG,GAAG,KAAK,EACX,GAAG,SAAS,EACb,GAAG,KAAK,CAAA;YACT,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACrD,MAAM,IAAI,GAAG,uBAAuB,UAAU,EAAE,CAAA;YAChD,MAAM,YAAY,GAAG,uBAAuB,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAA;YAE3F,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACT,kBAAkB,SAAS,CAAC,QAAQ,aAAa,SAAS,CAAC,cAAc,WAAW,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CACxH,CAAA;YACH,CAAC;YAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,IAAI,KAAiC,CAAA;gBACrC,MAAM,QAAQ,GAAoB,CAAC,CAAC,EAAE,EAAE;;oBACtC,YAAY,CAAC,KAAK,CAAC,CAAA;oBACnB,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;oBACvC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAC,CAAC,CAAC,IAA4C,0CAAE,IAAI,CAAC,CAAA;oBAChE,CAAC;gBACH,CAAC,CAAA;gBACD,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;gBACpC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;oBACnC,MAAM,CACJ,IAAI,kBAAkB,CACpB,YAAY,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC/C,CACF,CAAA;gBACH,CAAC,EAAE,SAAS,CAAC,CAAA;gBACb,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI;oBACJ,YAAY,EAAE,YAAY;oBAC1B,GAAG,SAAS;oBACZ,IAAI,EAAE;wBACJ,KAAK;wBACL,IAAI,EAAE,QAAQ;qBACf;iBACF,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,OAAO,SAAS,CAAC,CAAC,GAAG,KAAK,EAAE,IAAc,CAAC,EAAE,KAAK,CAAC,CAAA;QACrD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAmB,KAAuB;IACnE,OAAO,SAAS,CAAI,EAAE,EAAE,KAAK,CAAC,CAAA;AAChC,CAAC"}
1
+ {"version":3,"file":"remoteValue.js","sourceRoot":"","sources":["../../src/remoteValue/remoteValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAY,MAAM,aAAa,CAAA;AAIvE,SAAS,IAAI;IACX,OAAO;AACT,CAAC;AAYD,SAAS,SAAS,CAAmB,KAAe,EAAE,KAAuB;IAC3E,OAAO,IAAI,KAAK,CAAY,IAA4B,EAAE;QACxD,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ;YAC7B,MAAM,EACJ,OAAO,EACP,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,GAAG,GAAG,KAAK,EACX,GAAG,SAAS,EACb,GAAG,KAAK,CAAA;YACT,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACrD,MAAM,IAAI,GAAG,uBAAuB,UAAU,EAAE,CAAA;YAChD,MAAM,YAAY,GAAG,uBAAuB,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAA;YAE3F,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACT,kBAAkB,SAAS,CAAC,QAAQ,aAAa,SAAS,CAAC,cAAc,WAAW,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CACxH,CAAA;YACH,CAAC;YAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,IAAI,KAAiC,CAAA;gBACrC,MAAM,QAAQ,GAAoB,CAAC,CAAC,EAAE,EAAE;;oBACtC,YAAY,CAAC,KAAK,CAAC,CAAA;oBACnB,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;oBACvC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAC,CAAC,CAAC,IAA4C,0CAAE,IAAI,CAAC,CAAA;oBAChE,CAAC;gBACH,CAAC,CAAA;gBACD,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;gBACpC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;oBACnC,MAAM,CACJ,IAAI,kBAAkB,CACpB,YAAY,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC/C,CACF,CAAA;gBACH,CAAC,EAAE,SAAS,CAAC,CAAA;gBACb,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI;oBACJ,YAAY,EAAE,YAAY;oBAC1B,GAAG,SAAS;oBACZ,IAAI,EAAE;wBACJ,KAAK;wBACL,IAAI,EAAE,QAAQ;qBACU;iBAC3B,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,OAAO,SAAS,CAAC,CAAC,GAAG,KAAK,EAAE,IAAc,CAAC,EAAE,KAAK,CAAC,CAAA;QACrD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAmB,KAAuB;IACnE,OAAO,SAAS,CAAI,EAAE,EAAE,KAAK,CAAC,CAAA;AAChC,CAAC"}
@@ -6,6 +6,10 @@ type HasFunc<T> = T extends (...args: unknown[]) => unknown ? true : T extends u
6
6
  export type ToFunc<T extends object> = {
7
7
  [K in keyof T]: T[K] extends (...args: infer Args) => infer Ret ? (...args: Args) => Promise<Awaited<Ret>> : HasFunc<T[K]> extends false ? () => Promise<T[K]> : T[K] extends object ? ToFunc<T[K]> : never;
8
8
  };
9
+ export interface RemoteCallData {
10
+ paths: string[];
11
+ args: unknown[];
12
+ }
9
13
  type Assert<T extends true> = T;
10
14
  interface TestObj {
11
15
  a1: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zimi/remote",
3
3
  "license": "MIT",
4
- "version": "0.2.1-alpha.9",
4
+ "version": "0.2.1",
5
5
  "author": "xiaomingTang",
6
6
  "description": "call remote functions as local",
7
7
  "private": false,
package/src/adaptor.ts CHANGED
@@ -1,4 +1,4 @@
1
- export interface AdaptorPackageData {
1
+ export interface AdaptorPackageData<D = unknown> {
2
2
  /**
3
3
  * 自身设备 id,应确保唯一性(对方能凭借该 deviceId 找到该设备)
4
4
  */
@@ -11,7 +11,7 @@ export interface AdaptorPackageData {
11
11
  * 远程调用的对方的方法名
12
12
  */
13
13
  name: string
14
- data: unknown
14
+ data: D
15
15
  /**
16
16
  * 所需回调的方法名(如果需要回调的话)
17
17
  */
@@ -20,6 +20,15 @@ interface RemoteChannel {
20
20
  * remoteChannel.sendServerEvent(e)
21
21
  * },
22
22
  * } satisfies Adaptor
23
+ *
24
+ * export const remote = new Remote<RemoteFuncsFromClient, RemoteFuncsFromServer>(
25
+ * remoteAdaptor,
26
+ * {
27
+ * deviceId: `client-${Math.random().toString(36).slice(2)}`,
28
+ * }
29
+ * )
30
+ *
31
+ * void remote._.initConnection()
23
32
  * ```
24
33
  */
25
34
  export class ClientSideRemoteChannelEventManager extends EventEmitter<{
@@ -28,7 +28,7 @@ interface RemoteChannel<T extends GamePlayerEntityLike> {
28
28
  * on: remoteManager.on.bind(remoteManager),
29
29
  * once: remoteManager.once.bind(remoteManager),
30
30
  * emit: (e) => {
31
- * const entity = getEntity(e.targetDeviceId)
31
+ * const entity = remoteManager.getEntity(e.targetDeviceId)
32
32
  * if (!entity) {
33
33
  * console.error('entity not found')
34
34
  * return
@@ -37,6 +37,21 @@ interface RemoteChannel<T extends GamePlayerEntityLike> {
37
37
  * },
38
38
  * } satisfies Adaptor
39
39
  *
40
+ * export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(
41
+ * remoteAdaptor,
42
+ * {
43
+ * deviceId: 'server',
44
+ * }
45
+ * )
46
+ *
47
+ * remote.register('initConnection', async () => {
48
+ * // 什么也不干,单纯的让客户端在服务端“备案”
49
+ * })
50
+ *
51
+ * export const getEntity = remoteManager.getEntity.bind(remoteManager)
52
+ * export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)
53
+ * export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)
54
+ * export const remoteTo = remoteManager.remoteTo.bind(remoteManager)
40
55
  * ```
41
56
  */
42
57
  export class ServerSideRemoteChannelEventManager<
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export * from './response'
4
4
 
5
5
  export * from './remoteValue/remoteValue'
6
6
  export * from './remoteValue/exposeToRemote'
7
- export type { ToFunc } from './remoteValue/type'
7
+ export type { ToFunc, RemoteCallData } from './remoteValue/type'
8
8
 
9
9
  export * from './adaptors/iframe'
10
10
  export * from './adaptors/http'
@@ -1,5 +1,8 @@
1
1
  import { Adaptor, AdaptorPackageData } from '../adaptor'
2
2
  import { RemoteError, response } from '../response'
3
+ import { RemoteCallData } from './type'
4
+
5
+ type AdaptorData = AdaptorPackageData<RemoteCallData>
3
6
 
4
7
  interface ExposeProps {
5
8
  globalName: string
@@ -9,15 +12,51 @@ interface ExposeProps {
9
12
  */
10
13
  exposeTo: string[]
11
14
  /**
12
- * 你可以在该回调中抛错,以阻止远程调用
15
+ * 你可以在该回调中抛错,以阻止远程调用,
16
+ * 也可以修改传入的 data
17
+ */
18
+ onRequest?: (e: AdaptorData) => RemoteCallData | Promise<RemoteCallData>
19
+ /**
20
+ * 如果你想要自定义处理函数,
21
+ * 需要谨慎且完善地处理各种 paths, args,
22
+ * 以避免远程调用时出现未预期的错误。
23
+ *
24
+ * ---
25
+ *
26
+ * 我的默认处理程序谨供参考:
27
+ * ``` ts
28
+ * let target = obj
29
+ * for (let i = 0; i < data.paths.length; i += 1) {
30
+ * target = target[data.paths[i] as keyof typeof target] as typeof target
31
+ * }
32
+ * if (target instanceof Function) {
33
+ * return target(...data.args)
34
+ * }
35
+ * return target
36
+ * ```
37
+ *
38
+ * @returns 返回值将会被发送给远程调用方,可以是立即数,也可以是 Promise(Promise 会 await 后再返回)
13
39
  */
14
- onRequest?: (e: AdaptorPackageData) => void | Promise<void>
40
+ handler?: (e: AdaptorData) => unknown
15
41
  }
16
42
 
17
- function defaultOnRequest(e: AdaptorPackageData) {
18
- return e
43
+ function defaultOnRequest(e: AdaptorData) {
44
+ return e.data
19
45
  }
20
46
 
47
+ const geneDefaultHandler: <T>(obj: T) => (data: AdaptorData) => unknown =
48
+ (obj) =>
49
+ ({ data }) => {
50
+ let target = obj
51
+ for (let i = 0; i < data.paths.length; i += 1) {
52
+ target = target[data.paths[i] as keyof typeof target] as typeof target
53
+ }
54
+ if (target instanceof Function) {
55
+ return target(...data.args)
56
+ }
57
+ return target
58
+ }
59
+
21
60
  export function isRemoteValueEvent(eventName: string) {
22
61
  return eventName.startsWith('__REMOTE_VALUE_REQ__')
23
62
  }
@@ -27,25 +66,20 @@ export function exposeToRemote<T extends object>(obj: T, options: ExposeProps) {
27
66
  globalName,
28
67
  adaptor,
29
68
  exposeTo,
69
+ handler: inputHandler,
30
70
  onRequest = defaultOnRequest,
31
71
  } = options
32
72
  const callback = async (e: AdaptorPackageData) => {
33
73
  try {
34
- await onRequest(e)
74
+ const data = await onRequest(e as AdaptorData)
35
75
  if (!exposeTo.includes(e.deviceId) && !exposeTo.includes('*')) {
36
76
  throw new RemoteError('permission denied')
37
77
  }
38
- const { paths, args } = e.data as { paths: string[]; args: unknown[] }
39
- let target = obj
40
- for (let i = 0; i < paths.length; i += 1) {
41
- target = target[paths[i] as keyof typeof target] as typeof target
42
- }
43
- let res: unknown
44
- if (target instanceof Function) {
45
- res = await target(...args)
46
- } else {
47
- res = target
48
- }
78
+ const handler = inputHandler ?? geneDefaultHandler(obj)
79
+ const res = await handler({
80
+ ...e,
81
+ data,
82
+ })
49
83
  adaptor.emit({
50
84
  name: e.callbackName ?? 'IMPOSSIBLE_NO_CALLBACK_NAME',
51
85
  deviceId: e.targetDeviceId,
@@ -1,6 +1,6 @@
1
1
  import { RemoteError, RemoteTimeoutError, response } from '../response'
2
2
  import { Adaptor, AdaptorCallback, AdaptorPackageData } from '../adaptor'
3
- import type { ToFunc } from './type'
3
+ import type { RemoteCallData, ToFunc } from './type'
4
4
 
5
5
  function noop() {
6
6
  // pass
@@ -62,7 +62,7 @@ function geneProxy<T extends object>(paths: string[], props: RemoteValueProps) {
62
62
  data: {
63
63
  paths,
64
64
  args: argArray,
65
- },
65
+ } satisfies RemoteCallData,
66
66
  })
67
67
  })
68
68
  },
@@ -20,6 +20,11 @@ export type ToFunc<T extends object> = {
20
20
  : never
21
21
  }
22
22
 
23
+ export interface RemoteCallData {
24
+ paths: string[]
25
+ args: unknown[]
26
+ }
27
+
23
28
  // 下面的都是测试代码,用于测试 ToFunc
24
29
 
25
30
  type Assert<T extends true> = T