单测
This commit is contained in:
@ -11,7 +11,7 @@ export class ExtServer implements IServer {
|
||||
});
|
||||
}
|
||||
|
||||
onConnect(callback: (eventName: string, con: IConnect) => void) {
|
||||
onConnect(callback: (con: IConnect) => void) {
|
||||
this.EE.on("connect", callback);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import EventEmitter from "eventemitter3";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
export interface IServer {
|
||||
onConnect: (callback: (eventName: string, con: IConnect) => void) => void;
|
||||
onConnect: (callback: (con: IConnect) => void) => void;
|
||||
}
|
||||
|
||||
export interface IConnect {
|
||||
@ -18,8 +18,8 @@ export class Server {
|
||||
|
||||
constructor(private connect: IServer) {
|
||||
this.EE = new EventEmitter();
|
||||
this.connect.onConnect((eventName, con) => {
|
||||
this.EE.emit(eventName, con);
|
||||
this.connect.onConnect((con) => {
|
||||
this.EE.emit("connection", con);
|
||||
});
|
||||
}
|
||||
|
||||
@ -31,20 +31,21 @@ export class Server {
|
||||
export class Connect {
|
||||
private EE: EventEmitter;
|
||||
|
||||
private con: IConnect;
|
||||
|
||||
constructor(
|
||||
private id: string | IConnect,
|
||||
private con: IConnect
|
||||
con?: IConnect
|
||||
) {
|
||||
this.EE = new EventEmitter();
|
||||
if (arguments.length === 1) {
|
||||
this.con = id as IConnect;
|
||||
this.con.onMessage((message) => {
|
||||
const data = message as { eventName: string; data: unknown[]; messageId: string };
|
||||
data.data.push(this.callbackFunc(data.messageId));
|
||||
this.EE.emit(data.eventName, ...data.data);
|
||||
this.messageHandler(message);
|
||||
});
|
||||
} else {
|
||||
// 子连接
|
||||
this.con = con!;
|
||||
this.con.onMessage((message) => {
|
||||
const data = message as { eventName: string; data: unknown; id: string };
|
||||
if (data.eventName === "subcon") {
|
||||
@ -60,13 +61,13 @@ export class Connect {
|
||||
}
|
||||
|
||||
private callbackFunc(msgId: string): (...data: unknown[]) => void {
|
||||
return function (...data: unknown[]) {
|
||||
return (...data: unknown[]) => {
|
||||
this.con.postMessage({ eventName: "callback", data, messageId: msgId });
|
||||
};
|
||||
}
|
||||
|
||||
private messageHandler(data: unknown) {
|
||||
const subData = data.data as { eventName: string; data: unknown[]; messageId: string };
|
||||
const subData = data as { eventName: string; data: unknown[]; messageId: string };
|
||||
subData.data.push(this.callbackFunc(subData.messageId));
|
||||
this.EE.emit(subData.eventName, ...subData.data);
|
||||
}
|
||||
|
42
packages/message/message.test.ts
Normal file
42
packages/message/message.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
// @vitest-environment jsdom
|
||||
import { expect, test, vi } from "vitest";
|
||||
import { Server, Connect } from ".";
|
||||
import { connect, WindowServer } from "./window";
|
||||
|
||||
test("server", async () => {
|
||||
const myFunc = vi.fn();
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
con.onMessage((message) => {
|
||||
myFunc(message);
|
||||
});
|
||||
});
|
||||
const client = connect(window, window);
|
||||
client.postMessage("hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
expect(myFunc).toHaveBeenCalledTimes(2);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
});
|
||||
|
||||
test("connect", async () => {
|
||||
const myFunc = vi.fn();
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
const wrapCon = new Connect(con);
|
||||
wrapCon.on("hello", (message) => {
|
||||
myFunc(message);
|
||||
wrapCon.emit("world", "world");
|
||||
});
|
||||
});
|
||||
const client = new Connect(connect(window, window));
|
||||
client.on("world", (message) => {
|
||||
myFunc(message);
|
||||
});
|
||||
client.emit("hello", "hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
expect(myFunc).toHaveBeenCalledTimes(3);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
expect(myFunc).toHaveBeenCalledWith("world");
|
||||
});
|
60
packages/message/window.ts
Normal file
60
packages/message/window.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import EventEmitter from "eventemitter3";
|
||||
import { IConnect, IServer } from ".";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
export class WindowServer implements IServer {
|
||||
private EE: EventEmitter;
|
||||
|
||||
constructor(win: Window) {
|
||||
this.EE = new EventEmitter();
|
||||
win.addEventListener("message", (event) => {
|
||||
if (event.data.type === "connect") {
|
||||
this.EE.emit("connection", new WindowConnect(event.data.connectId, event.target as Window, win));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onConnect(callback: (con: IConnect) => void) {
|
||||
this.EE.on("connection", callback);
|
||||
}
|
||||
}
|
||||
|
||||
export function connect(source: Window, target: Window) {
|
||||
const con = new WindowConnect(uuidv4(), source, target);
|
||||
con.postMessage({ type: "connect" });
|
||||
return con;
|
||||
}
|
||||
|
||||
export class WindowConnect implements IConnect {
|
||||
private EE: EventEmitter;
|
||||
|
||||
constructor(
|
||||
private id: string,
|
||||
private source: Window,
|
||||
private target: Window
|
||||
) {
|
||||
this.EE = new EventEmitter();
|
||||
this.source.addEventListener("message", (event) => {
|
||||
if (event.data.id === id) {
|
||||
this.EE.emit("message", event.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
postMessage(message: unknown) {
|
||||
this.target.postMessage(message, "*");
|
||||
}
|
||||
|
||||
onMessage(callback: (message: unknown) => void) {
|
||||
this.EE.on("message", callback);
|
||||
}
|
||||
|
||||
onDisconnect(callback: () => void) {
|
||||
this.EE.on("disconnect", callback);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.EE.emit("disconnect");
|
||||
this.EE.removeAllListeners();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user