UNPKG

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
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