@zimi/remote 0.2.1-alpha.7 → 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
@@ -5,4 +5,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"}
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.7",
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
@@ -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,