@wevu/web-apis 1.1.0 → 1.2.0

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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 1. 简介
4
4
 
5
- `@wevu/web-apis` 为小程序运行时提供一组 Web API 兼容层,重点解决第三方请求库在小程序环境中缺失 `fetch`、`Request`、`Response`、`AbortController`、`XMLHttpRequest`、`URL` 等全局对象的问题。
5
+ `@wevu/web-apis` 为小程序运行时提供一组 Web API 兼容层,重点解决第三方请求库在小程序环境中缺失 `fetch`、`Request`、`Response`、`AbortController`、`XMLHttpRequest`、`URL`、`WebSocket` 等全局对象的问题。
6
6
 
7
7
  它主要服务于:
8
8
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  - 按需安装 `fetch`、`Headers`、`Request`、`Response`
16
16
  - 提供 `AbortController` / `AbortSignal` 兼容层
17
- - 提供 `XMLHttpRequest`、`URL`、`URLSearchParams`、`Blob`、`FormData` 兼容层
17
+ - 提供 `XMLHttpRequest`、`URL`、`URLSearchParams`、`Blob`、`FormData`、`WebSocket` 兼容层
18
18
  - 自动把能力安装到可用的小程序宿主全局对象
19
19
  - 默认基于 `@wevu/api` 的请求能力完成底层转发
20
20
 
@@ -33,7 +33,7 @@ import { installRequestGlobals } from '@wevu/web-apis'
33
33
 
34
34
  installRequestGlobals()
35
35
 
36
- const response = await fetch('https://example.com/data')
36
+ const response = await fetch('https://request-globals.invalid/data')
37
37
  console.log(await response.json())
38
38
  ```
39
39
 
@@ -58,24 +58,58 @@ installRequestGlobals({
58
58
  })
59
59
  ```
60
60
 
61
+ ### 4.4 安装并使用 WebSocket
62
+
63
+ ```ts
64
+ import { installRequestGlobals } from '@wevu/web-apis'
65
+
66
+ installRequestGlobals({
67
+ targets: ['WebSocket'],
68
+ })
69
+
70
+ const socket = new WebSocket('wss://example.com/socket', ['chat'])
71
+
72
+ socket.onopen = () => {
73
+ socket.send(JSON.stringify({ type: 'ping' }))
74
+ }
75
+
76
+ socket.onmessage = (event) => {
77
+ console.log(event.data)
78
+ }
79
+
80
+ socket.onclose = (event) => {
81
+ console.log(event.code, event.reason)
82
+ }
83
+ ```
84
+
61
85
  ## 5. 主要导出
62
86
 
63
- | 导出 | 说明 |
64
- | ---------------------------------------------------------- | ---------------------------------------- |
65
- | `installRequestGlobals` | 按需安装请求相关全局对象 |
66
- | `installAbortGlobals` | 仅安装 `AbortController` / `AbortSignal` |
67
- | `fetch` | 基于小程序请求能力适配的 `fetch` 实现 |
68
- | `HeadersPolyfill` / `RequestPolyfill` / `ResponsePolyfill` | HTTP 相关兼容类 |
69
- | `URLPolyfill` / `URLSearchParamsPolyfill` | URL 相关兼容类 |
70
- | `XMLHttpRequestPolyfill` | XHR 兼容实现 |
87
+ | 导出 | 说明 |
88
+ | ---------------------------------------------------------- | ----------------------------------------------- |
89
+ | `installRequestGlobals` | 按需安装请求相关全局对象 |
90
+ | `installAbortGlobals` | 仅安装 `AbortController` / `AbortSignal` |
91
+ | `fetch` | 基于小程序请求能力适配的 `fetch` 实现 |
92
+ | `HeadersPolyfill` / `RequestPolyfill` / `ResponsePolyfill` | HTTP 相关兼容类 |
93
+ | `URLPolyfill` / `URLSearchParamsPolyfill` | URL 相关兼容类 |
94
+ | `WebSocketPolyfill` | 基于小程序 `SocketTask` 的 `WebSocket` 兼容实现 |
95
+ | `XMLHttpRequestPolyfill` | XHR 兼容实现 |
71
96
 
72
97
  ## 6. 适用场景
73
98
 
74
99
  - 在小程序环境中运行 `axios` 的 `fetch` 适配器
75
100
  - 在小程序环境中运行 `graphql-request`
101
+ - 在小程序环境中直接复用浏览器风格的 `WebSocket` 客户端代码
76
102
  - 给依赖 `URL` / `FormData` / `Blob` 的库补齐基础全局对象
77
103
 
78
- ## 7. 本地开发
104
+ ## 7. WebSocket 兼容说明
105
+
106
+ - 当前 `WebSocket` 兼容层底层桥接的是小程序 `SocketTask`
107
+ - 支持 `new WebSocket(url, protocols?)`、`send`、`close`、`readyState`、`binaryType`
108
+ - 支持 `onopen` / `onmessage` / `onerror` / `onclose` 以及 `addEventListener`
109
+ - 当前不会模拟浏览器里完整的 `bufferedAmount`、协商后的 `protocol`、`extensions`
110
+ - 如果运行时没有可用的 `connectSocket` 能力,构造时会直接抛错
111
+
112
+ ## 8. 本地开发
79
113
 
80
114
  ```bash
81
115
  pnpm --filter @wevu/web-apis build
@@ -83,7 +117,7 @@ pnpm --filter @wevu/web-apis test
83
117
  pnpm --filter @wevu/web-apis typecheck
84
118
  ```
85
119
 
86
- ## 8. 相关链接
120
+ ## 9. 相关链接
87
121
 
88
122
  - `@wevu/api`:[../weapi/README.md](../weapi/README.md)
89
123
  - `wevu`:[../wevu/README.md](../wevu/README.md)
package/dist/index.d.mts CHANGED
@@ -4,10 +4,11 @@ import { fetch } from "./fetch.mjs";
4
4
  import { HeadersPolyfill, RequestPolyfill, ResponsePolyfill } from "./http.mjs";
5
5
  import { URLPolyfill, URLSearchParamsPolyfill } from "./url.mjs";
6
6
  import { BlobPolyfill, FormDataPolyfill } from "./web.mjs";
7
+ import { WebSocketPolyfill } from "./websocket.mjs";
7
8
  import { XMLHttpRequestPolyfill } from "./xhr.mjs";
8
9
 
9
10
  //#region src/index.d.ts
10
- type WeappInjectRequestGlobalsTarget = 'fetch' | 'Headers' | 'Request' | 'Response' | 'AbortController' | 'AbortSignal' | 'XMLHttpRequest';
11
+ type WeappInjectRequestGlobalsTarget = 'fetch' | 'Headers' | 'Request' | 'Response' | 'AbortController' | 'AbortSignal' | 'XMLHttpRequest' | 'WebSocket';
11
12
  interface InstallRequestGlobalsOptions {
12
13
  targets?: WeappInjectRequestGlobalsTarget[];
13
14
  }
@@ -20,4 +21,4 @@ declare function installRequestGlobals(options?: InstallRequestGlobalsOptions):
20
21
  */
21
22
  declare function installAbortGlobals(): Record<string, any>;
22
23
  //#endregion
23
- export { AbortControllerPolyfill, AbortSignalPolyfill, BlobPolyfill, FormDataPolyfill, HeadersPolyfill, InstallRequestGlobalsOptions, RequestGlobalsEventTarget, RequestPolyfill, ResponsePolyfill, URLPolyfill, URLSearchParamsPolyfill, WeappInjectRequestGlobalsTarget, XMLHttpRequestPolyfill, fetch, installAbortGlobals, installRequestGlobals };
24
+ export { AbortControllerPolyfill, AbortSignalPolyfill, BlobPolyfill, FormDataPolyfill, HeadersPolyfill, InstallRequestGlobalsOptions, RequestGlobalsEventTarget, RequestPolyfill, ResponsePolyfill, URLPolyfill, URLSearchParamsPolyfill, WeappInjectRequestGlobalsTarget, WebSocketPolyfill, XMLHttpRequestPolyfill, fetch, installAbortGlobals, installRequestGlobals };
package/dist/index.mjs CHANGED
@@ -4,8 +4,18 @@ import { HeadersPolyfill, RequestPolyfill, ResponsePolyfill } from "./http.mjs";
4
4
  import { fetch } from "./fetch.mjs";
5
5
  import { URLPolyfill, URLSearchParamsPolyfill } from "./url.mjs";
6
6
  import { BlobPolyfill, FormDataPolyfill } from "./web.mjs";
7
+ import { WebSocketPolyfill } from "./websocket.mjs";
7
8
  import { XMLHttpRequestPolyfill } from "./xhr.mjs";
8
9
  //#region src/index.ts
10
+ function hasUsableConstructor(value, args = []) {
11
+ if (typeof value !== "function") return false;
12
+ try {
13
+ Reflect.construct(value, args);
14
+ return true;
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
9
19
  function installSingleTarget(host, target) {
10
20
  if (target === "fetch") {
11
21
  if (typeof host.fetch !== "function") host.fetch = fetch;
@@ -31,13 +41,17 @@ function installSingleTarget(host, target) {
31
41
  if (typeof host.AbortSignal !== "function") host.AbortSignal = AbortSignalPolyfill;
32
42
  return;
33
43
  }
44
+ if (target === "WebSocket") {
45
+ if (typeof host.WebSocket !== "function") host.WebSocket = WebSocketPolyfill;
46
+ return;
47
+ }
34
48
  if (target === "XMLHttpRequest" && typeof host.XMLHttpRequest !== "function") host.XMLHttpRequest = XMLHttpRequestPolyfill;
35
49
  }
36
50
  function installUrlGlobals(host) {
37
- if (typeof host.URL !== "function") host.URL = URLPolyfill;
38
- if (typeof host.URLSearchParams !== "function") host.URLSearchParams = URLSearchParamsPolyfill;
39
- if (typeof host.Blob !== "function") host.Blob = BlobPolyfill;
40
- if (typeof host.FormData !== "function") host.FormData = FormDataPolyfill;
51
+ if (!hasUsableConstructor(host.URL, ["https://request-globals.invalid"])) host.URL = URLPolyfill;
52
+ if (!hasUsableConstructor(host.URLSearchParams, ["client=graphql-request"])) host.URLSearchParams = URLSearchParamsPolyfill;
53
+ if (!hasUsableConstructor(host.Blob)) host.Blob = BlobPolyfill;
54
+ if (!hasUsableConstructor(host.FormData)) host.FormData = FormDataPolyfill;
41
55
  }
42
56
  function installGlobalBindingIfNeeded(host, target) {
43
57
  const value = host[target];
@@ -55,7 +69,8 @@ function installRequestGlobals(options = {}) {
55
69
  "Response",
56
70
  "AbortController",
57
71
  "AbortSignal",
58
- "XMLHttpRequest"
72
+ "XMLHttpRequest",
73
+ "WebSocket"
59
74
  ];
60
75
  const hosts = resolveRequestGlobalsHosts();
61
76
  const primaryHost = resolveRequestGlobalsHost();
@@ -80,4 +95,4 @@ function installAbortGlobals() {
80
95
  return installRequestGlobals({ targets: ["AbortController", "AbortSignal"] });
81
96
  }
82
97
  //#endregion
83
- export { AbortControllerPolyfill, AbortSignalPolyfill, BlobPolyfill, FormDataPolyfill, HeadersPolyfill, RequestGlobalsEventTarget, RequestPolyfill, ResponsePolyfill, URLPolyfill, URLSearchParamsPolyfill, XMLHttpRequestPolyfill, fetch, installAbortGlobals, installRequestGlobals };
98
+ export { AbortControllerPolyfill, AbortSignalPolyfill, BlobPolyfill, FormDataPolyfill, HeadersPolyfill, RequestGlobalsEventTarget, RequestPolyfill, ResponsePolyfill, URLPolyfill, URLSearchParamsPolyfill, WebSocketPolyfill, XMLHttpRequestPolyfill, fetch, installAbortGlobals, installRequestGlobals };
package/dist/web.d.mts CHANGED
@@ -7,7 +7,7 @@ declare class BlobPolyfill {
7
7
  constructor(parts?: BlobPart[], options?: {
8
8
  type?: string;
9
9
  });
10
- arrayBuffer(): Promise<any>;
10
+ arrayBuffer(): Promise<ArrayBuffer>;
11
11
  text(): Promise<string>;
12
12
  }
13
13
  type FormDataEntryValue = BlobPolyfill | string;
package/dist/web.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { cloneArrayBuffer, cloneArrayBufferView, decodeText, encodeText } from "./shared.mjs";
2
2
  //#region src/web.ts
3
3
  function normalizeBlobPart(part) {
4
- if (typeof part === "string") return encodeText(part);
4
+ if (typeof part === "string") return Promise.resolve(encodeText(part));
5
5
  if (part && typeof part === "object" && typeof part.arrayBuffer === "function") return part.arrayBuffer();
6
6
  if (part instanceof ArrayBuffer) return Promise.resolve(cloneArrayBuffer(part));
7
7
  if (ArrayBuffer.isView(part)) return Promise.resolve(cloneArrayBufferView(part));
@@ -0,0 +1,53 @@
1
+ import { RequestGlobalsEventTarget } from "./shared.mjs";
2
+ import { BlobPolyfill } from "./web.mjs";
3
+
4
+ //#region src/websocket.d.ts
5
+ type WebSocketBinaryType = 'blob' | 'arraybuffer';
6
+ type WebSocketSendData = string | ArrayBuffer | ArrayBufferView | Blob;
7
+ type WebSocketMessageData = string | ArrayBuffer | Blob | BlobPolyfill;
8
+ interface WebSocketCloseEventLike {
9
+ code: number;
10
+ reason: string;
11
+ type: 'close';
12
+ wasClean: boolean;
13
+ }
14
+ interface WebSocketErrorEventLike {
15
+ error?: unknown;
16
+ message?: string;
17
+ type: 'error';
18
+ }
19
+ interface WebSocketMessageEventLike {
20
+ data: WebSocketMessageData;
21
+ origin: string;
22
+ type: 'message';
23
+ }
24
+ declare class WebSocketPolyfill extends RequestGlobalsEventTarget {
25
+ static readonly CONNECTING = 0;
26
+ static readonly OPEN = 1;
27
+ static readonly CLOSING = 2;
28
+ static readonly CLOSED = 3;
29
+ readonly CONNECTING = 0;
30
+ readonly OPEN = 1;
31
+ readonly CLOSING = 2;
32
+ readonly CLOSED = 3;
33
+ readonly extensions = "";
34
+ readonly protocol = "";
35
+ readonly url: string;
36
+ binaryType: WebSocketBinaryType;
37
+ bufferedAmount: number;
38
+ readyState: number;
39
+ onclose: ((event: WebSocketCloseEventLike) => void) | null;
40
+ onerror: ((event: WebSocketErrorEventLike) => void) | null;
41
+ onmessage: ((event: WebSocketMessageEventLike) => void) | null;
42
+ onopen: ((event: {
43
+ type: 'open';
44
+ }) => void) | null;
45
+ private socketTask?;
46
+ constructor(url: string, protocols?: string | string[]);
47
+ close(code?: number, reason?: string): void;
48
+ send(data: WebSocketSendData): void;
49
+ private closeFromRuntime;
50
+ private emitError;
51
+ }
52
+ //#endregion
53
+ export { WebSocketPolyfill };
@@ -0,0 +1,193 @@
1
+ import { RequestGlobalsEventTarget, cloneArrayBuffer, cloneArrayBufferView } from "./shared.mjs";
2
+ import { URLPolyfill } from "./url.mjs";
3
+ import { BlobPolyfill } from "./web.mjs";
4
+ import { wpi } from "@wevu/api";
5
+ //#region src/websocket.ts
6
+ const WHITESPACE_RE = /\s/u;
7
+ function isValidProtocol(protocol) {
8
+ return [...protocol].every((char) => {
9
+ const code = char.charCodeAt(0);
10
+ return code >= 33 && code <= 126 && char !== "," && !WHITESPACE_RE.test(char);
11
+ });
12
+ }
13
+ function createDomLikeError(name, message) {
14
+ if (typeof DOMException === "function") return new DOMException(message, name);
15
+ const error = new Error(message);
16
+ error.name = name;
17
+ return error;
18
+ }
19
+ function encodeReasonLength(reason) {
20
+ if (typeof TextEncoder === "function") return new TextEncoder().encode(reason).byteLength;
21
+ return unescape(encodeURIComponent(reason)).length;
22
+ }
23
+ function normalizeCloseCode(code) {
24
+ if (code == null) return;
25
+ if (code === 1e3 || code >= 3e3 && code <= 4999) return code;
26
+ throw createDomLikeError("InvalidAccessError", `Failed to execute close: invalid code "${code}"`);
27
+ }
28
+ function normalizeCloseReason(reason) {
29
+ if (reason == null) return;
30
+ const normalized = String(reason);
31
+ if (encodeReasonLength(normalized) > 123) throw createDomLikeError("SyntaxError", "Failed to execute close: reason is longer than 123 bytes");
32
+ return normalized;
33
+ }
34
+ function resolveUrlConstructor() {
35
+ return typeof URL === "function" ? URL : URLPolyfill;
36
+ }
37
+ function normalizeProtocols(protocols) {
38
+ if (protocols == null) return;
39
+ const normalized = (Array.isArray(protocols) ? [...protocols] : [protocols]).map((protocol) => String(protocol));
40
+ const unique = /* @__PURE__ */ new Set();
41
+ for (const protocol of normalized) {
42
+ if (!isValidProtocol(protocol)) throw new SyntaxError(`Failed to construct 'WebSocket': invalid subprotocol "${protocol}"`);
43
+ if (unique.has(protocol)) throw new SyntaxError(`Failed to construct 'WebSocket': duplicated subprotocol "${protocol}"`);
44
+ unique.add(protocol);
45
+ }
46
+ return normalized;
47
+ }
48
+ function normalizeUrl(url) {
49
+ const parsed = new (resolveUrlConstructor())(String(url));
50
+ if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") throw new SyntaxError(`Failed to construct 'WebSocket': invalid URL "${url}"`);
51
+ if (parsed.hash) throw new SyntaxError(`Failed to construct 'WebSocket': URL contains fragment "${url}"`);
52
+ return parsed.toString();
53
+ }
54
+ function isSocketTask(value) {
55
+ return typeof value === "object" && value !== null && typeof value.send === "function" && typeof value.close === "function";
56
+ }
57
+ function toBinaryPayload(data) {
58
+ if (typeof data === "string") return data;
59
+ if (data instanceof ArrayBuffer) return cloneArrayBuffer(data);
60
+ if (ArrayBuffer.isView(data)) return cloneArrayBufferView(data);
61
+ if (typeof Blob !== "undefined" && data instanceof Blob) return data.arrayBuffer();
62
+ throw new TypeError("Failed to execute send: data must be a string, ArrayBuffer, ArrayBufferView or Blob");
63
+ }
64
+ function createErrorEvent(error) {
65
+ return {
66
+ type: "error",
67
+ error,
68
+ message: typeof error === "object" && error !== null && "errMsg" in error ? String(error.errMsg ?? "") : error instanceof Error ? error.message : void 0
69
+ };
70
+ }
71
+ function createCloseEvent(result) {
72
+ return {
73
+ type: "close",
74
+ code: result?.code ?? 1e3,
75
+ reason: result?.reason ?? "",
76
+ wasClean: (result?.code ?? 1e3) === 1e3
77
+ };
78
+ }
79
+ function createMessageEvent(url, data) {
80
+ return {
81
+ type: "message",
82
+ data,
83
+ origin: new (resolveUrlConstructor())(url).origin
84
+ };
85
+ }
86
+ function getRawConnectSocket() {
87
+ const adapter = wpi.getAdapter?.() ?? wpi.raw;
88
+ const target = wpi.resolveTarget?.("connectSocket");
89
+ if (!adapter || !target?.supported) return;
90
+ const method = adapter[target.target];
91
+ return typeof method === "function" ? method.bind(adapter) : void 0;
92
+ }
93
+ var WebSocketPolyfill = class WebSocketPolyfill extends RequestGlobalsEventTarget {
94
+ static CONNECTING = 0;
95
+ static OPEN = 1;
96
+ static CLOSING = 2;
97
+ static CLOSED = 3;
98
+ CONNECTING = WebSocketPolyfill.CONNECTING;
99
+ OPEN = WebSocketPolyfill.OPEN;
100
+ CLOSING = WebSocketPolyfill.CLOSING;
101
+ CLOSED = WebSocketPolyfill.CLOSED;
102
+ extensions = "";
103
+ protocol = "";
104
+ url;
105
+ binaryType = "blob";
106
+ bufferedAmount = 0;
107
+ readyState = WebSocketPolyfill.CONNECTING;
108
+ onclose = null;
109
+ onerror = null;
110
+ onmessage = null;
111
+ onopen = null;
112
+ socketTask;
113
+ constructor(url, protocols) {
114
+ super();
115
+ this.url = normalizeUrl(url);
116
+ const connectSocket = getRawConnectSocket();
117
+ if (!connectSocket) throw createDomLikeError("NotSupportedError", "WebSocket is not supported in the current mini-program runtime");
118
+ const normalizedProtocols = normalizeProtocols(protocols);
119
+ const task = connectSocket({
120
+ url: this.url,
121
+ protocols: normalizedProtocols,
122
+ fail: (error) => {
123
+ this.emitError(error);
124
+ this.closeFromRuntime();
125
+ }
126
+ });
127
+ if (!isSocketTask(task)) throw createDomLikeError("NetworkError", "Failed to create mini-program SocketTask");
128
+ this.socketTask = task;
129
+ task.onOpen(() => {
130
+ if (this.readyState !== WebSocketPolyfill.CONNECTING) return;
131
+ this.readyState = WebSocketPolyfill.OPEN;
132
+ this.dispatchEvent({ type: "open" });
133
+ });
134
+ task.onMessage((result) => {
135
+ if (this.readyState === WebSocketPolyfill.CLOSED) return;
136
+ const data = typeof result.data === "string" ? result.data : this.binaryType === "arraybuffer" ? cloneArrayBuffer(result.data) : new BlobPolyfill([cloneArrayBuffer(result.data)]);
137
+ this.dispatchEvent(createMessageEvent(this.url, data));
138
+ });
139
+ task.onError((error) => {
140
+ this.emitError(error);
141
+ });
142
+ task.onClose((result) => {
143
+ this.closeFromRuntime(result);
144
+ });
145
+ }
146
+ close(code, reason) {
147
+ if (this.readyState === WebSocketPolyfill.CLOSING || this.readyState === WebSocketPolyfill.CLOSED) return;
148
+ const normalizedCode = normalizeCloseCode(code);
149
+ const normalizedReason = normalizeCloseReason(reason);
150
+ this.readyState = WebSocketPolyfill.CLOSING;
151
+ this.socketTask?.close({
152
+ code: normalizedCode,
153
+ reason: normalizedReason,
154
+ fail: (error) => {
155
+ this.emitError(error);
156
+ }
157
+ });
158
+ }
159
+ send(data) {
160
+ if (this.readyState === WebSocketPolyfill.CONNECTING) throw createDomLikeError("InvalidStateError", "Failed to execute send: WebSocket is still in CONNECTING state");
161
+ if (this.readyState !== WebSocketPolyfill.OPEN || !this.socketTask) throw createDomLikeError("InvalidStateError", "Failed to execute send: WebSocket is not open");
162
+ const payload = toBinaryPayload(data);
163
+ if (payload instanceof Promise) {
164
+ payload.then((resolved) => {
165
+ this.socketTask?.send({
166
+ data: resolved,
167
+ fail: (error) => {
168
+ this.emitError(error);
169
+ }
170
+ });
171
+ }).catch((error) => {
172
+ this.emitError(error);
173
+ });
174
+ return;
175
+ }
176
+ this.socketTask.send({
177
+ data: payload,
178
+ fail: (error) => {
179
+ this.emitError(error);
180
+ }
181
+ });
182
+ }
183
+ closeFromRuntime(result) {
184
+ if (this.readyState === WebSocketPolyfill.CLOSED) return;
185
+ this.readyState = WebSocketPolyfill.CLOSED;
186
+ this.dispatchEvent(createCloseEvent(result));
187
+ }
188
+ emitError(error) {
189
+ this.dispatchEvent(createErrorEvent(error));
190
+ }
191
+ };
192
+ //#endregion
193
+ export { WebSocketPolyfill };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/web-apis",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "description": "Web API polyfills and global installers for mini-program runtimes",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -51,6 +51,10 @@
51
51
  "types": "./dist/web.d.mts",
52
52
  "import": "./dist/web.mjs"
53
53
  },
54
+ "./websocket": {
55
+ "types": "./dist/websocket.d.mts",
56
+ "import": "./dist/websocket.mjs"
57
+ },
54
58
  "./xhr": {
55
59
  "types": "./dist/xhr.d.mts",
56
60
  "import": "./dist/xhr.mjs"
@@ -66,7 +70,7 @@
66
70
  "node": "^20.19.0 || >=22.12.0"
67
71
  },
68
72
  "dependencies": {
69
- "@wevu/api": "0.2.2"
73
+ "@wevu/api": "0.2.3"
70
74
  },
71
75
  "publishConfig": {
72
76
  "access": "public",