Skip to content

Commit fd53472

Browse files
committed
update
1 parent cfdd744 commit fd53472

23 files changed

Lines changed: 242 additions & 165 deletions

File tree

.vscode/launch.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
{
2-
// 使用 IntelliSense 了解相关属性。
2+
// 使用 IntelliSense 了解相关属性。
33
// 悬停以查看现有属性的描述。
44
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"name": "Bun: Debug Current File",
9+
"type": "node",
10+
"request": "launch",
11+
"runtimeExecutable": "bun",
12+
"runtimeArgs": [
13+
"--inspect"
14+
],
15+
"program": "${file}",
16+
"cwd": "${workspaceFolder}/packages/native",
17+
"skipFiles": [
18+
"<node_internals>/**"
19+
],
20+
"sourceMaps": true,
21+
"console": "integratedTerminal"
22+
},
723
{
824
"name": "ts-node",
925
"type": "node",

bun.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/native/src/__tests__/features/forward.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,32 @@ describe("转发发布和订阅", async () => {
4848
otherEmitter.emit("data", 1);
4949
expect(events).toEqual([1]);
5050
});
51+
test("转发订阅和发布事件迭代器", async () => {
52+
const otherEmitter = new FastEvent();
53+
const emitter = new FastEvent({
54+
onAddBeforeListener: (type, listener, options) => {
55+
if (type.startsWith("@")) {
56+
return otherEmitter.on(type.substring(1), options);
57+
}
58+
},
59+
onBeforeExecuteListener: (message, args) => {
60+
if (message.type.startsWith("@")) {
61+
message.type = message.type.substring(1);
62+
return otherEmitter.emit(message as any, args);
63+
}
64+
},
65+
});
66+
const events: any[] = [];
67+
const messages = emitter.on("@data");
68+
// 订阅otherEmitter的data事件
69+
otherEmitter.emit("data", 1);
70+
otherEmitter.emit("data", 2);
71+
otherEmitter.emit("data", 3);
72+
for await (const message of messages) {
73+
events.push(message.payload);
74+
if (events.length === 3) break;
75+
}
76+
77+
expect(events).toEqual([1, 2, 3]);
78+
});
5179
});

packages/native/src/event.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import { isPromise } from "./utils/isPromise";
6969
import { resolveValue } from "./utils/resolveValue";
7070
import { AfterExecuteListenerHook, FastEventHooks } from "./types/FastEventHooks";
7171
import { ItemOf } from "../../viewer/src/types";
72+
import { isAsyncIterable } from "./utils/isAsyncIterable";
7273

7374
/**
7475
* FastEvent 事件发射器类
@@ -168,6 +169,10 @@ export class FastEvent<
168169
get id() {
169170
return this._options.id!;
170171
}
172+
/** 获取事件发射器的唯一标识符 */
173+
get title() {
174+
return this._options.title || this.id || "FastEvent";
175+
}
171176
get hooks(): FastEventHooks {
172177
if (!this._hooks) {
173178
this._hooks = {
@@ -430,7 +435,16 @@ export class FastEvent<
430435
) as FastEventIteratorOptions;
431436
const iterator = createAsyncEventIterator<any>(this as any, type, iteratorOpts);
432437
iterator.create(finalOptions);
433-
this._executeHooks("AddBeforeListener", [type, iterator.listener, finalOptions]);
438+
const r = this._executeHooks("AddBeforeListener", [
439+
type,
440+
iterator.listener,
441+
finalOptions,
442+
]);
443+
if (r === false) {
444+
throw new CancelError();
445+
} else if (isAsyncIterable(r)) {
446+
return r;
447+
}
434448
return iterator;
435449
}
436450
// 执行回调
@@ -1115,9 +1129,12 @@ export class FastEvent<
11151129

11161130
// 触发时进行消息转换
11171131
if (isFunction(this._options.transform)) {
1118-
message.payload = this._options.transform.call(this, message as any);
1119-
args.rawEventType = message.type;
1120-
args.flags = (args.flags || 0) | FastEventListenerFlags.Transformed;
1132+
const transformed = this._options.transform.call(this, message as any);
1133+
if (transformed !== message) {
1134+
message.payload = transformed;
1135+
args.rawEventType = message.type;
1136+
args.flags = (args.flags || 0) | FastEventListenerFlags.Transformed;
1137+
}
11211138
}
11221139
// 执行监听器
11231140
results.push(...this._executeListeners(nodes, message, args));

packages/native/src/types/FastEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { FastEventIteratorOptions } from "../eventIterator";
1111

1212
export type FastEventOptions<Meta = Record<string, any>, Context = never> = {
1313
id: string;
14+
title: string;
1415
debug: boolean;
1516
// 事件分隔符
1617
delimiter: string;

packages/native/src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from "./isPathMatched";
77
export * from "./isSubsctiber";
88
export * from "./isClass";
99
export * from "./isFastEvent";
10+
export * from "./isAsyncIterable";
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* 判断是否为可异步迭代对象(AsyncIterable)
3+
* 即具有 Symbol.asyncIterator 方法的对象
4+
*
5+
* @param value - 要检查的值
6+
* @returns 如果是可异步迭代对象返回 true
7+
*/
8+
export function isAsyncIterable<T = any>(value: unknown): value is AsyncIterable<T> {
9+
if (value === null || typeof value !== "object") {
10+
return false;
11+
}
12+
13+
const maybeIterable = value as Partial<AsyncIterable<T>>;
14+
const asyncIteratorSymbol = Symbol.asyncIterator;
15+
16+
return (
17+
typeof (maybeIterable as any)[asyncIteratorSymbol] === "function" ||
18+
typeof (maybeIterable as any)["@@asyncIterator"] === "function"
19+
);
20+
}

packages/native/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
5151
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
5252
"emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
53-
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
53+
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
5454
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
5555
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
5656
// "outDir": "./", /* Specify an output folder for all emitted files. */
Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
import { FastEvent } from "fastevent";
22

3+
function getRandomId() {
4+
return Math.floor(Math.random() * 101);
5+
}
36
/**
47
* 创建 FastEvent 实例
58
*/
69
const emitter = new FastEvent({
710
debug: true,
11+
title: "操作事件",
12+
transform: (message) => {
13+
if (message.type === "transformed") {
14+
return `transformed-${getRandomId()}`;
15+
} else {
16+
return message;
17+
}
18+
},
819
});
920

1021
// 挂载到全局,方便调试
@@ -22,7 +33,7 @@ const subscribers: any[] = [];
2233
export function addSimpleSubscribe() {
2334
subscribers.push(
2435
emitter.on("test/simple", () => {
25-
return Math.floor(Math.random() * 101);
36+
return getRandomId();
2637
}),
2738
);
2839
}
@@ -45,7 +56,7 @@ function userLoginHandler(data: any) {
4556
emitter.on("user/login", userLoginHandler, { tag: "auth" });
4657

4758
function onAny(_message: any) {
48-
return Math.abs(Math.random() * 100);
59+
return `Any<${getRandomId()}>`;
4960
}
5061
// emitter.onAny(onAny);
5162

@@ -201,12 +212,14 @@ export function triggerTaggedEvent() {
201212
* 触发带 transform 的事件
202213
*/
203214
export function triggerTransformEvent() {
204-
emitter.emit("data/update", {
215+
emitter.emit("transformed", {
205216
items: [1, 2, 3, 4, 5],
206217
operation: "add",
207218
});
208219
}
209-
220+
emitter.on("transformed", (message) => {
221+
return message;
222+
});
210223
/**
211224
* 触发错误事件
212225
*/
@@ -254,12 +267,12 @@ export function triggerBatchEvents() {
254267
*/
255268
export function triggerWildcardEvents() {
256269
emitter.emit("user/profile", { action: "view" });
257-
setTimeout(() => {
258-
emitter.emit("user/settings", { action: "update" });
259-
}, 100);
260-
setTimeout(() => {
261-
emitter.emit("user/avatar", { action: "change" });
262-
}, 200);
270+
// setTimeout(() => {
271+
// emitter.emit("user/settings", { action: "update" });
272+
// }, 100);
273+
// setTimeout(() => {
274+
// emitter.emit("user/avatar", { action: "change" });
275+
// }, 200);
263276
}
264277

265278
/**

0 commit comments

Comments
 (0)