minigame-std
Version:
Cross-platform standard library for WeChat minigame and web browsers with unified APIs for crypto, fs, fetch, storage, and more.
216 lines (215 loc) • 5.45 kB
JavaScript
import { Ok, RESULT_VOID, tryAsyncResult, tryResult } from "happy-rusty";
import { validateSafeSocketUrl } from "./_internal.mjs";
import { bufferSourceToAb, miniGameFailureToError } from "./_internal.mjs";
import { asyncIOResultify } from "./utils.mjs";
//#region src/macros/env.ts
/**
* 如果在小游戏环境中返回 true,否则返回 false。
*/
const IS_MINA = __MINIGAME_STD_MINA__;
//#endregion
//#region src/std/socket/socket_define.ts
/**
* WebSocket 连接状态,小游戏环境可用。
* @since 1.6.0
* @example
* ```ts
* import { SocketReadyState, connectSocket } from 'minigame-std';
*
* const socket = connectSocket('wss://example.com');
* if (socket.readyState === SocketReadyState.OPEN) {
* console.log('连接已打开');
* }
* ```
*/
const SocketReadyState = {
/**
* WebSocket.CONNECTING
*/
CONNECTING: 0,
/**
* WebSocket.OPEN
*/
OPEN: 1,
/**
* WebSocket.CLOSING
*/
CLOSING: 2,
/**
* WebSocket.CLOSED
*/
CLOSED: 3
};
//#endregion
//#region src/std/socket/mina_socket.ts
/**
* @internal
* 小游戏平台的 WebSocket 实现。
*/
/**
* 创建并返回一个 WebSocket 连接。
* @param url - WebSocket 服务器的 URL。
* @param options - 透传给`wx.connectSocket`。
* @returns 返回一个实现了 ISocket 接口的 WebSocket 对象。
*/
function connectSocket$2(url, options) {
const { headers, ...rest } = options ?? {};
const socket = wx.connectSocket({
...rest,
url,
header: headers
});
return {
get readyState() {
return socket.readyState;
},
addEventListener(type, listener) {
switch (type) {
case "open":
socket.onOpen(() => {
listener();
});
return () => {};
case "close":
socket.onClose((res) => {
listener(res.code, res.reason);
});
return () => {};
case "message":
socket.onMessage((res) => {
listener(res.data);
});
return () => {};
case "error":
socket.onError((err) => {
listener(miniGameFailureToError(err));
});
return () => {};
default: throw new TypeError(`Invalid socket event type: ${type}`);
}
},
async send(data) {
const sendDataRes = tryResult(() => typeof data === "string" ? data : bufferSourceToAb(data));
if (sendDataRes.isErr()) return sendDataRes.asErr();
return (await asyncIOResultify(socket.send)({ data: sendDataRes.unwrap() })).and(RESULT_VOID);
},
close(code, reason) {
socket.close({
code,
reason
});
}
};
}
//#endregion
//#region src/std/socket/web_socket.ts
/**
* Web 平台的 WebSocket 实现。
*
* @internal
*/
/**
* 创建并返回一个 WebSocket 连接。
* @param url - WebSocket 服务器的 URL。
* @param protocols - 子协议数组。
* @returns 返回一个实现了 ISocket 接口的 WebSocket 对象。
*/
function connectSocket$1(url, protocols) {
const socket = new WebSocket(url, protocols);
socket.binaryType = "arraybuffer";
return {
get readyState() {
return socket.readyState;
},
addEventListener(type, listener) {
switch (type) {
case "open": {
const socketListener = listener;
socket.addEventListener("open", socketListener);
return () => {
socket.removeEventListener("open", socketListener);
};
}
case "close": {
const socketListener = (ev) => {
listener(ev.code, ev.reason);
};
socket.addEventListener("close", socketListener);
return () => {
socket.removeEventListener("close", socketListener);
};
}
case "message": {
const socketListener = (ev) => {
listener(ev.data);
};
socket.addEventListener("message", socketListener);
return () => {
socket.removeEventListener("message", socketListener);
};
}
case "error": {
const socketListener = () => {
listener(/* @__PURE__ */ new Error("WebSocket error"));
};
socket.addEventListener("error", socketListener);
return () => {
socket.removeEventListener("error", socketListener);
};
}
default: throw new TypeError(`Invalid socket event type: ${type}`);
}
},
send(data) {
return tryAsyncResult(() => {
socket.send(data);
});
},
close: socket.close.bind(socket)
};
}
//#endregion
//#region src/std/socket/mod.ts
/**
* WebSocket 模块,提供创建和管理 WebSocket 连接的功能。
* @module socket
*/
/**
* 创建并返回一个 WebSocket 连接。
* @param url - WebSocket 服务器的 URL。
* @param options - 可选的参数。
* @returns 返回一个实现了 ISocket 接口的 WebSocket 对象。
* @since 1.0.0
* @example
* ```ts
* const socket = connectSocket('wss://echo.websocket.org');
*
* socket.addEventListener('open', () => {
* console.log('连接已建立');
* socket.send('Hello, Server!');
* });
*
* socket.addEventListener('message', (data) => {
* console.log('收到消息:', data);
* });
*
* socket.addEventListener('close', (code, reason) => {
* console.log('连接已关闭:', code, reason);
* });
*
* socket.addEventListener('error', (error) => {
* console.error('连接错误:', error);
* });
*
* // 关闭连接
* socket.close();
* ```
*/
function connectSocket(url, options) {
const urlRes = validateSafeSocketUrl(url);
if (urlRes.isErr()) return urlRes.asErr();
return Ok(IS_MINA ? connectSocket$2(url, options) : connectSocket$1(url, options?.protocols));
}
//#endregion
export { SocketReadyState, connectSocket };
//# sourceMappingURL=socket.mjs.map