@zimi/remote 0.2.1-alpha.6 → 0.2.1-alpha.8

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.
@@ -0,0 +1,28 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { type AdaptorPackageData } from '../../index';
3
+ interface RemoteChannel {
4
+ onClientEvent(fn: (e: unknown) => void): void;
5
+ }
6
+ /**
7
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
8
+ * ```ts
9
+ * const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
10
+ *
11
+ * export const remoteAdaptor = {
12
+ * every: remoteManager.onEvery.bind(remoteManager),
13
+ * off: remoteManager.off.bind(remoteManager),
14
+ * on: remoteManager.on.bind(remoteManager),
15
+ * once: remoteManager.once.bind(remoteManager),
16
+ * emit: (e) => {
17
+ * remoteChannel.sendServerEvent(e)
18
+ * },
19
+ * } satisfies Adaptor
20
+ * ```
21
+ */
22
+ export declare class ClientSideRemoteChannelEventManager extends EventEmitter<{
23
+ [key: string]: [AdaptorPackageData];
24
+ }> {
25
+ constructor(remoteChannel: RemoteChannel);
26
+ onEvery(fn: (args: AdaptorPackageData) => void): void;
27
+ }
28
+ export {};
@@ -0,0 +1,36 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { isRemoteAdaptorData } from '../../index';
3
+ /**
4
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
5
+ * ```ts
6
+ * const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
7
+ *
8
+ * export const remoteAdaptor = {
9
+ * every: remoteManager.onEvery.bind(remoteManager),
10
+ * off: remoteManager.off.bind(remoteManager),
11
+ * on: remoteManager.on.bind(remoteManager),
12
+ * once: remoteManager.once.bind(remoteManager),
13
+ * emit: (e) => {
14
+ * remoteChannel.sendServerEvent(e)
15
+ * },
16
+ * } satisfies Adaptor
17
+ * ```
18
+ */
19
+ export class ClientSideRemoteChannelEventManager extends EventEmitter {
20
+ constructor(remoteChannel) {
21
+ super();
22
+ remoteChannel.onClientEvent((e) => {
23
+ if (!isRemoteAdaptorData(e)) {
24
+ return;
25
+ }
26
+ if (!e.name.startsWith('__REMOTE_VALUE_REQ__')) {
27
+ this.emit('__remote_every__', e);
28
+ }
29
+ this.emit(e.name, e);
30
+ });
31
+ }
32
+ onEvery(fn) {
33
+ this.on('__remote_every__', fn);
34
+ }
35
+ }
36
+ //# sourceMappingURL=client.js.map
@@ -0,0 +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,EAA2B,MAAM,aAAa,CAAA;AAM1E;;;;;;;;;;;;;;;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"}
@@ -0,0 +1,65 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { type AdaptorPackageData } from '../../index';
3
+ interface GamePlayerEntityLike {
4
+ player: {
5
+ userKey: string;
6
+ };
7
+ }
8
+ interface RemoteChannel<T extends GamePlayerEntityLike> {
9
+ onServerEvent(fn: (e: {
10
+ args: unknown;
11
+ entity: T;
12
+ }) => void): void;
13
+ }
14
+ /**
15
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
16
+ * ```ts
17
+ * const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
18
+ *
19
+ * world.onPlayerLeave(
20
+ * remoteManager.onPlayerLeave.bind(remoteManager)
21
+ * )
22
+ *
23
+ * export const remoteAdaptor = {
24
+ * every: remoteManager.onEvery.bind(remoteManager),
25
+ * off: remoteManager.off.bind(remoteManager),
26
+ * on: remoteManager.on.bind(remoteManager),
27
+ * once: remoteManager.once.bind(remoteManager),
28
+ * emit: (e) => {
29
+ * const entity = getEntity(e.targetDeviceId)
30
+ * if (!entity) {
31
+ * console.error('entity not found')
32
+ * return
33
+ * }
34
+ * remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
35
+ * },
36
+ * } satisfies Adaptor
37
+ *
38
+ * ```
39
+ */
40
+ export declare class ServerSideRemoteChannelEventManager<T extends GamePlayerEntityLike> extends EventEmitter<{
41
+ [key: string]: [AdaptorPackageData];
42
+ }> {
43
+ entityMap: [string, T][];
44
+ constructor(remoteChannel: RemoteChannel<T>);
45
+ onPlayerLeave(e: {
46
+ entity: T;
47
+ }): void;
48
+ onEvery(fn: (args: AdaptorPackageData) => void): void;
49
+ waitForRegister(entity: T): Promise<void>;
50
+ getEntity(deviceId: string): T | undefined;
51
+ getIdByEntity(entity: T): string | undefined;
52
+ remoteTo(config: {
53
+ target: T;
54
+ }): {
55
+ targetDeviceId: string;
56
+ };
57
+ remoteTo(config: {
58
+ target: T;
59
+ timeoutMs: number;
60
+ }): {
61
+ targetDeviceId: string;
62
+ timeoutMs: number;
63
+ };
64
+ }
65
+ export {};
@@ -0,0 +1,89 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { isRemoteAdaptorData, isRemoteValueEvent, } from '../../index';
3
+ /**
4
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
5
+ * ```ts
6
+ * const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
7
+ *
8
+ * world.onPlayerLeave(
9
+ * remoteManager.onPlayerLeave.bind(remoteManager)
10
+ * )
11
+ *
12
+ * export const remoteAdaptor = {
13
+ * every: remoteManager.onEvery.bind(remoteManager),
14
+ * off: remoteManager.off.bind(remoteManager),
15
+ * on: remoteManager.on.bind(remoteManager),
16
+ * once: remoteManager.once.bind(remoteManager),
17
+ * emit: (e) => {
18
+ * const entity = getEntity(e.targetDeviceId)
19
+ * if (!entity) {
20
+ * console.error('entity not found')
21
+ * return
22
+ * }
23
+ * remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
24
+ * },
25
+ * } satisfies Adaptor
26
+ *
27
+ * ```
28
+ */
29
+ export class ServerSideRemoteChannelEventManager extends EventEmitter {
30
+ constructor(remoteChannel) {
31
+ super();
32
+ Object.defineProperty(this, "entityMap", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: []
37
+ });
38
+ remoteChannel.onServerEvent((e) => {
39
+ const { args } = e;
40
+ if (!isRemoteAdaptorData(args)) {
41
+ return;
42
+ }
43
+ const prevItem = this.entityMap.find((item) => item[1].player.userKey === e.entity.player.userKey);
44
+ if (prevItem) {
45
+ prevItem[0] = args.deviceId;
46
+ prevItem[1] = e.entity;
47
+ }
48
+ else {
49
+ this.entityMap.push([args.deviceId, e.entity]);
50
+ }
51
+ if (!isRemoteValueEvent(args.name)) {
52
+ this.emit('__remote_every__', args);
53
+ }
54
+ this.emit(args.name, args);
55
+ });
56
+ }
57
+ onPlayerLeave(e) {
58
+ this.entityMap = this.entityMap.filter((item) => item[1].player.userKey !== e.entity.player.userKey);
59
+ }
60
+ onEvery(fn) {
61
+ this.on('__remote_every__', fn);
62
+ }
63
+ waitForRegister(entity) {
64
+ return new Promise((resolve) => {
65
+ if (this.entityMap.some(([_, en]) => en.player.userKey === entity.player.userKey)) {
66
+ resolve();
67
+ return;
68
+ }
69
+ this.once('__remote_every__', () => {
70
+ resolve();
71
+ });
72
+ });
73
+ }
74
+ getEntity(deviceId) {
75
+ var _a;
76
+ return (_a = this.entityMap.find((item) => item[0] === deviceId)) === null || _a === void 0 ? void 0 : _a[1];
77
+ }
78
+ getIdByEntity(entity) {
79
+ var _a;
80
+ return (_a = this.entityMap.find((item) => item[1].player.userKey === entity.player.userKey)) === null || _a === void 0 ? void 0 : _a[0];
81
+ }
82
+ remoteTo({ target, ...rest }) {
83
+ return {
84
+ targetDeviceId: this.getIdByEntity(target),
85
+ ...rest,
86
+ };
87
+ }
88
+ }
89
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
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
@@ -1,8 +1,8 @@
1
1
  export { Remote, isRemoteAdaptorData } from './remote';
2
- export type { AdaptorPackageData, Adaptor } from './adaptor';
2
+ export type { Adaptor, AdaptorCallback, AdaptorPackageData } from './adaptor';
3
3
  export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from './response';
4
4
  export { createIframeAdaptor } from './adaptors/iframe';
5
5
  export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
6
6
  export type { ToFunc } from './remoteValue/type';
7
7
  export { remoteValue } from './remoteValue/remoteValue';
8
- export { exposeToRemote } from './remoteValue/exposeToRemote';
8
+ export { exposeToRemote, isRemoteValueEvent, } from './remoteValue/exposeToRemote';
package/dist/index.js CHANGED
@@ -3,5 +3,5 @@ export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from
3
3
  export { createIframeAdaptor } from './adaptors/iframe';
4
4
  export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
5
5
  export { remoteValue } from './remoteValue/remoteValue';
6
- export { exposeToRemote } from './remoteValue/exposeToRemote';
6
+ export { exposeToRemote, isRemoteValueEvent, } from './remoteValue/exposeToRemote';
7
7
  //# 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;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,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;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,EACL,cAAc,EACd,kBAAkB,GACnB,MAAM,8BAA8B,CAAA"}
@@ -11,5 +11,6 @@ interface ExposeProps {
11
11
  */
12
12
  onRequest?: (e: AdaptorPackageData) => void | Promise<void>;
13
13
  }
14
+ export declare function isRemoteValueEvent(eventName: string): boolean;
14
15
  export declare function exposeToRemote<T extends object>(obj: T, options: ExposeProps): () => void;
15
16
  export {};
@@ -2,6 +2,9 @@ import { RemoteError, response } from '../response';
2
2
  function defaultOnRequest(e) {
3
3
  return e;
4
4
  }
5
+ export function isRemoteValueEvent(eventName) {
6
+ return eventName.startsWith('__REMOTE_VALUE_REQ__');
7
+ }
5
8
  export function exposeToRemote(obj, options) {
6
9
  const { globalName, adaptor, exposeTo, onRequest = defaultOnRequest, } = options;
7
10
  const callback = async (e) => {
@@ -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,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;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"}
@@ -4,6 +4,7 @@ type RemoteValueProps = Pick<AdaptorPackageData, 'deviceId' | 'targetDeviceId'>
4
4
  globalName: string;
5
5
  adaptor: Adaptor;
6
6
  timeoutMs?: number;
7
+ log?: boolean;
7
8
  };
8
9
  /**
9
10
  * @example
@@ -5,10 +5,13 @@ function noop() {
5
5
  function geneProxy(paths, props) {
6
6
  return new Proxy(noop, {
7
7
  apply(target, thisArg, argArray) {
8
- const { adaptor, globalName, timeoutMs = 30000, ...restProps } = props;
8
+ const { adaptor, globalName, timeoutMs = 30000, log = false, ...restProps } = props;
9
9
  const randomStr = Math.random().toString(36).slice(2);
10
10
  const name = `__REMOTE_VALUE_REQ__${globalName}`;
11
11
  const responseName = `__REMOTE_VALUE_RES__${[globalName, ...paths].join('.')}-${randomStr}`;
12
+ if (log) {
13
+ console.log(`[remoteValue] [${restProps.deviceId}] 正在访问远端 [${restProps.targetDeviceId}] 的变量: "${[globalName, ...paths].join('.')}"`);
14
+ }
12
15
  return new Promise((resolve, reject) => {
13
16
  let timer;
14
17
  const callback = (e) => {
@@ -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;AAWD,SAAS,SAAS,CAAmB,KAAe,EAAE,KAAuB;IAC3E,OAAO,IAAI,KAAK,CAAY,IAA4B,EAAE;QACxD,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ;YAC7B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAA;YACtE,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,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;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"}
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.6",
4
+ "version": "0.2.1-alpha.8",
5
5
  "author": "xiaomingTang",
6
6
  "description": "call remote functions as local",
7
7
  "private": false,
@@ -0,0 +1,43 @@
1
+ import EventEmitter from 'eventemitter3'
2
+ import { isRemoteAdaptorData, type AdaptorPackageData } from '../../index'
3
+
4
+ interface RemoteChannel {
5
+ onClientEvent(fn: (e: unknown) => void): void
6
+ }
7
+
8
+ /**
9
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
10
+ * ```ts
11
+ * const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
12
+ *
13
+ * export const remoteAdaptor = {
14
+ * every: remoteManager.onEvery.bind(remoteManager),
15
+ * off: remoteManager.off.bind(remoteManager),
16
+ * on: remoteManager.on.bind(remoteManager),
17
+ * once: remoteManager.once.bind(remoteManager),
18
+ * emit: (e) => {
19
+ * remoteChannel.sendServerEvent(e)
20
+ * },
21
+ * } satisfies Adaptor
22
+ * ```
23
+ */
24
+ export class ClientSideRemoteChannelEventManager extends EventEmitter<{
25
+ [key: string]: [AdaptorPackageData]
26
+ }> {
27
+ constructor(remoteChannel: RemoteChannel) {
28
+ super()
29
+ remoteChannel.onClientEvent((e) => {
30
+ if (!isRemoteAdaptorData(e)) {
31
+ return
32
+ }
33
+ if (!e.name.startsWith('__REMOTE_VALUE_REQ__')) {
34
+ this.emit('__remote_every__', e)
35
+ }
36
+ this.emit(e.name, e)
37
+ })
38
+ }
39
+
40
+ onEvery(fn: (args: AdaptorPackageData) => void): void {
41
+ this.on('__remote_every__', fn)
42
+ }
43
+ }
@@ -0,0 +1,123 @@
1
+ import EventEmitter from 'eventemitter3'
2
+ import {
3
+ isRemoteAdaptorData,
4
+ isRemoteValueEvent,
5
+ type AdaptorPackageData,
6
+ } from '../../index'
7
+
8
+ interface GamePlayerEntityLike {
9
+ player: {
10
+ userKey: string
11
+ }
12
+ }
13
+
14
+ interface RemoteChannel<T extends GamePlayerEntityLike> {
15
+ onServerEvent(fn: (e: { args: unknown; entity: T }) => void): void
16
+ }
17
+
18
+ /**
19
+ * 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
20
+ * ```ts
21
+ * const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
22
+ *
23
+ * world.onPlayerLeave(
24
+ * remoteManager.onPlayerLeave.bind(remoteManager)
25
+ * )
26
+ *
27
+ * export const remoteAdaptor = {
28
+ * every: remoteManager.onEvery.bind(remoteManager),
29
+ * off: remoteManager.off.bind(remoteManager),
30
+ * on: remoteManager.on.bind(remoteManager),
31
+ * once: remoteManager.once.bind(remoteManager),
32
+ * emit: (e) => {
33
+ * const entity = getEntity(e.targetDeviceId)
34
+ * if (!entity) {
35
+ * console.error('entity not found')
36
+ * return
37
+ * }
38
+ * remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
39
+ * },
40
+ * } satisfies Adaptor
41
+ *
42
+ * ```
43
+ */
44
+ export class ServerSideRemoteChannelEventManager<
45
+ T extends GamePlayerEntityLike,
46
+ > extends EventEmitter<{
47
+ [key: string]: [AdaptorPackageData]
48
+ }> {
49
+ entityMap: [string, T][] = []
50
+
51
+ constructor(remoteChannel: RemoteChannel<T>) {
52
+ super()
53
+ remoteChannel.onServerEvent((e) => {
54
+ const { args } = e
55
+ if (!isRemoteAdaptorData(args)) {
56
+ return
57
+ }
58
+ const prevItem = this.entityMap.find(
59
+ (item) => item[1].player.userKey === e.entity.player.userKey
60
+ )
61
+ if (prevItem) {
62
+ prevItem[0] = args.deviceId
63
+ prevItem[1] = e.entity
64
+ } else {
65
+ this.entityMap.push([args.deviceId, e.entity])
66
+ }
67
+ if (!isRemoteValueEvent(args.name)) {
68
+ this.emit('__remote_every__', args)
69
+ }
70
+ this.emit(args.name, args)
71
+ })
72
+ }
73
+
74
+ onPlayerLeave(e: { entity: T }) {
75
+ this.entityMap = this.entityMap.filter(
76
+ (item) => item[1].player.userKey !== e.entity.player.userKey
77
+ )
78
+ }
79
+
80
+ onEvery(fn: (args: AdaptorPackageData) => void): void {
81
+ this.on('__remote_every__', fn)
82
+ }
83
+
84
+ waitForRegister(entity: T) {
85
+ return new Promise<void>((resolve) => {
86
+ if (
87
+ this.entityMap.some(
88
+ ([_, en]) => en.player.userKey === entity.player.userKey
89
+ )
90
+ ) {
91
+ resolve()
92
+ return
93
+ }
94
+ this.once('__remote_every__', () => {
95
+ resolve()
96
+ })
97
+ })
98
+ }
99
+
100
+ getEntity(deviceId: string): T | undefined {
101
+ return this.entityMap.find((item) => item[0] === deviceId)?.[1]
102
+ }
103
+
104
+ getIdByEntity(entity: T): string | undefined {
105
+ return this.entityMap.find(
106
+ (item) => item[1].player.userKey === entity.player.userKey
107
+ )?.[0]
108
+ }
109
+
110
+ remoteTo(config: { target: T }): {
111
+ targetDeviceId: string
112
+ }
113
+ remoteTo(config: { target: T; timeoutMs: number }): {
114
+ targetDeviceId: string
115
+ timeoutMs: number
116
+ }
117
+ remoteTo({ target, ...rest }: { target: T; timeoutMs?: number }) {
118
+ return {
119
+ targetDeviceId: this.getIdByEntity(target),
120
+ ...rest,
121
+ }
122
+ }
123
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Remote, isRemoteAdaptorData } from './remote'
2
- export type { AdaptorPackageData, Adaptor } from './adaptor'
2
+ export type { Adaptor, AdaptorCallback, AdaptorPackageData } from './adaptor'
3
3
  export {
4
4
  RemoteError,
5
5
  RemoteNotFoundError,
@@ -10,4 +10,7 @@ export { createIframeAdaptor } from './adaptors/iframe'
10
10
  export { createHttpAdaptor, remoteEventManager } from './adaptors/http'
11
11
  export type { ToFunc } from './remoteValue/type'
12
12
  export { remoteValue } from './remoteValue/remoteValue'
13
- export { exposeToRemote } from './remoteValue/exposeToRemote'
13
+ export {
14
+ exposeToRemote,
15
+ isRemoteValueEvent,
16
+ } from './remoteValue/exposeToRemote'
@@ -18,6 +18,10 @@ function defaultOnRequest(e: AdaptorPackageData) {
18
18
  return e
19
19
  }
20
20
 
21
+ export function isRemoteValueEvent(eventName: string) {
22
+ return eventName.startsWith('__REMOTE_VALUE_REQ__')
23
+ }
24
+
21
25
  export function exposeToRemote<T extends object>(obj: T, options: ExposeProps) {
22
26
  const {
23
27
  globalName,
@@ -13,16 +13,29 @@ type RemoteValueProps = Pick<
13
13
  globalName: string
14
14
  adaptor: Adaptor
15
15
  timeoutMs?: number
16
+ log?: boolean
16
17
  }
17
18
 
18
19
  function geneProxy<T extends object>(paths: string[], props: RemoteValueProps) {
19
20
  return new Proxy<ToFunc<T>>(noop as unknown as ToFunc<T>, {
20
21
  apply(target, thisArg, argArray) {
21
- const { adaptor, globalName, timeoutMs = 30000, ...restProps } = props
22
+ const {
23
+ adaptor,
24
+ globalName,
25
+ timeoutMs = 30000,
26
+ log = false,
27
+ ...restProps
28
+ } = props
22
29
  const randomStr = Math.random().toString(36).slice(2)
23
30
  const name = `__REMOTE_VALUE_REQ__${globalName}`
24
31
  const responseName = `__REMOTE_VALUE_RES__${[globalName, ...paths].join('.')}-${randomStr}`
25
32
 
33
+ if (log) {
34
+ console.log(
35
+ `[remoteValue] [${restProps.deviceId}] 正在访问远端 [${restProps.targetDeviceId}] 的变量: "${[globalName, ...paths].join('.')}"`
36
+ )
37
+ }
38
+
26
39
  return new Promise((resolve, reject) => {
27
40
  let timer: NodeJS.Timeout | undefined
28
41
  const callback: AdaptorCallback = (e) => {