ranuts 0.2.0-alpha.0 → 0.3.0-alpha.1
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/CLAUDE.md +107 -16
- package/README.md +7 -5
- package/README.zh-CN.md +7 -5
- package/dist/chain-CTywmh_H.js +1 -0
- package/dist/{color-CRdlaDqQ.js → color-Dohr9BXX.js} +1 -1
- package/dist/enums-BAgbyGdH.js +1 -0
- package/dist/i18n-Cf5TtRb4.js +1 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -1
- package/dist/src/node/appendFile.d.ts +3 -3
- package/dist/src/node/fileInfo.d.ts +2 -2
- package/dist/src/node/index.js +1 -1
- package/dist/src/node/paresUrl.d.ts +1 -1
- package/dist/src/node/readFile.d.ts +3 -3
- package/dist/src/node/traverse.d.ts +2 -2
- package/dist/src/node/watchFile.d.ts +3 -3
- package/dist/src/node/writeFile.d.ts +3 -3
- package/dist/src/utils/async.d.ts +81 -0
- package/dist/src/utils/audioRecorder.d.ts +1 -1
- package/dist/src/utils/behavior.d.ts +12 -3
- package/dist/src/utils/bom.d.ts +68 -178
- package/dist/src/utils/bridge.d.ts +153 -0
- package/dist/src/utils/canvas.d.ts +54 -0
- package/dist/src/utils/chain.d.ts +80 -0
- package/dist/src/utils/color.d.ts +76 -4
- package/dist/src/utils/compose.d.ts +1 -1
- package/dist/src/utils/console.d.ts +19 -1
- package/dist/src/utils/debounce.d.ts +27 -5
- package/dist/src/utils/device.d.ts +31 -3
- package/dist/src/utils/dom.d.ts +5 -84
- package/dist/src/utils/error.d.ts +18 -1
- package/dist/src/utils/event.d.ts +61 -0
- package/dist/src/utils/file.d.ts +30 -0
- package/dist/src/utils/i18n/index.js +1 -0
- package/dist/src/utils/i18n.d.ts +69 -0
- package/dist/src/utils/idb.d.ts +178 -0
- package/dist/src/utils/img.d.ts +60 -4
- package/dist/src/utils/index.d.ts +48 -16
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/lang.d.ts +69 -0
- package/dist/src/utils/localePath.d.ts +62 -0
- package/dist/src/utils/memoize.d.ts +53 -5
- package/dist/src/utils/monitor.d.ts +55 -26
- package/dist/src/utils/number.d.ts +46 -9
- package/dist/src/utils/obj.d.ts +56 -31
- package/dist/src/utils/prefetch.d.ts +81 -0
- package/dist/src/utils/queue.d.ts +53 -23
- package/dist/src/utils/report.d.ts +51 -3
- package/dist/src/utils/request.d.ts +26 -7
- package/dist/src/utils/script.d.ts +26 -4
- package/dist/src/utils/segment.d.ts +62 -0
- package/dist/src/utils/signal.d.ts +35 -3
- package/dist/src/utils/storage.d.ts +57 -0
- package/dist/src/utils/str.d.ts +112 -88
- package/dist/src/utils/style.d.ts +31 -0
- package/dist/src/utils/subscribe.d.ts +5 -5
- package/dist/src/utils/throttle.d.ts +26 -13
- package/dist/src/utils/time.d.ts +38 -6
- package/dist/src/utils/tween.d.ts +40 -0
- package/dist/src/utils/visual/application.d.ts +4 -4
- package/dist/src/utils/visual/enums.d.ts +4 -4
- package/dist/src/utils/visual/graphics/graphics.d.ts +25 -25
- package/dist/src/utils/visual/graphics/graphicsData.d.ts +1 -1
- package/dist/src/utils/visual/graphics/graphicsGeometry.d.ts +6 -6
- package/dist/src/utils/visual/index.js +1 -1
- package/dist/src/utils/visual/math/matrix.d.ts +8 -8
- package/dist/src/utils/visual/math/transform.d.ts +1 -1
- package/dist/src/utils/visual/render/batchRenderer.d.ts +20 -18
- package/dist/src/utils/visual/render/utils/batch/index.d.ts +13 -13
- package/dist/src/utils/visual/render/utils/float.d.ts +13 -13
- package/dist/src/utils/visual/render/utils/verticy.d.ts +3 -3
- package/dist/src/utils/visual/render/utils/webgl/initShader.d.ts +3 -2
- package/dist/src/utils/visual/render/utils/webgpu/shaders.d.ts +2 -2
- package/dist/src/utils/visual/render/webGPURenderer.d.ts +8 -8
- package/dist/src/utils/visual/vertex/container.d.ts +17 -16
- package/dist/src/utils/worker.d.ts +76 -0
- package/dist/src/utils/zip.d.ts +162 -0
- package/dist/src/vnode/index.d.ts +1 -1
- package/dist/src/vnode/index.js +1 -1
- package/dist/src/vnode/is.d.ts +4 -0
- package/dist/test/canvas.test.d.ts +1 -0
- package/dist/test/color.test.d.ts +1 -0
- package/dist/test/tween.test.d.ts +1 -0
- package/dist/test/utils/async.test.d.ts +1 -0
- package/dist/test/utils/file-read.test.d.ts +1 -0
- package/dist/test/utils/format.test.d.ts +1 -0
- package/dist/test/utils/idb.test.d.ts +1 -0
- package/dist/test/utils/instrumentation.test.d.ts +1 -0
- package/dist/test/utils/lang.test.d.ts +1 -0
- package/dist/test/utils/locale-path.test.d.ts +1 -0
- package/dist/test/utils/media-query.test.d.ts +1 -0
- package/dist/test/utils/number-parse.test.d.ts +1 -0
- package/dist/test/utils/prefetch.test.d.ts +1 -0
- package/dist/test/utils/query-storage.test.d.ts +1 -0
- package/dist/test/utils/queue.test.d.ts +1 -0
- package/dist/test/utils/report-config.test.d.ts +1 -0
- package/dist/test/utils/report-image.test.d.ts +1 -0
- package/dist/test/utils/segment.test.d.ts +1 -0
- package/dist/test/utils/signal-once.test.d.ts +1 -0
- package/dist/test/utils/single-flight.test.d.ts +1 -0
- package/dist/test/utils/timing.test.d.ts +1 -0
- package/dist/test/utils/worker-client.test.d.ts +1 -0
- package/dist/test/utils/zip.test.d.ts +1 -0
- package/dist/umd/index.umd.cjs +1 -1
- package/dist/umd/node/node.umd.cjs +1 -1
- package/dist/umd/utils/utils.umd.cjs +1 -1
- package/dist/utils-BDtXHcK8.js +1 -0
- package/docs/API.md +306 -147
- package/package.json +32 -14
- package/dist/src/vnode/chainDom.d.ts +0 -47
- package/dist/subscribe-CINWsor3.js +0 -1
- package/dist/utils-_OxsVZmz.js +0 -1
package/dist/src/utils/bom.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { noop } from '@/utils/noop';
|
|
1
2
|
/**
|
|
2
|
-
* @description:
|
|
3
|
+
* @description: Override the browser's back-button behaviour
|
|
3
4
|
* @param {*} callback
|
|
4
5
|
* @return {*}
|
|
5
6
|
*/
|
|
6
|
-
export declare const retain: (callback?:
|
|
7
|
+
export declare const retain: (callback?: typeof noop) => void;
|
|
7
8
|
/**
|
|
8
|
-
* @description:
|
|
9
|
+
* @description: Read a named cookie
|
|
9
10
|
* @param {string} objName
|
|
10
11
|
* @return {*}
|
|
11
12
|
*/
|
|
@@ -26,7 +27,7 @@ export interface BaseReturn {
|
|
|
26
27
|
message?: string;
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
29
|
-
* @description:
|
|
30
|
+
* @description: Fetch a URL as an ArrayBuffer
|
|
30
31
|
* @param {string} src
|
|
31
32
|
* @param {RequestUrlToArraybufferOption} options
|
|
32
33
|
* @return {*}
|
|
@@ -40,43 +41,84 @@ export interface Context {
|
|
|
40
41
|
oBackingStorePixelRatio: number;
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
|
-
* @description:
|
|
44
|
+
* @description: Get the device pixel ratio
|
|
44
45
|
* @param {CanvasRenderingContext2D} context
|
|
45
46
|
* @return {*}
|
|
46
47
|
*/
|
|
47
48
|
export declare const getPixelRatio: (context: CanvasRenderingContext2D & Partial<Context>) => number;
|
|
48
49
|
export declare const createObjectURL: (src: Blob | ArrayBuffer | Response) => Promise<string>;
|
|
49
50
|
/**
|
|
50
|
-
* @description:
|
|
51
|
+
* @description: Frames per millisecond; multiply by 1000 for frames per second
|
|
51
52
|
* @return {*}
|
|
52
53
|
*/
|
|
53
54
|
export declare const getFrame: (n?: number) => Promise<number>;
|
|
54
55
|
/**
|
|
55
|
-
* @description:
|
|
56
|
-
*
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
56
|
+
* @description: Parse a URL's query string into an object. Defaults to the current
|
|
57
|
+
* `window.location.href`, so it returns `{}` under SSR unless a URL is passed.
|
|
58
|
+
*
|
|
59
|
+
* A **bare flag keeps its place** as an empty string: `?embed` and `?embed=` both yield
|
|
60
|
+
* `{ embed: '' }`. The previous implementation dropped any parameter without a value,
|
|
61
|
+
* which made `?readonly` and `?embed` — the usual way to write a boolean flag —
|
|
62
|
+
* indistinguishable from the parameter being absent. Use [`queryFlag`](#queryflag) to read
|
|
63
|
+
* such a flag as a boolean.
|
|
64
|
+
*
|
|
65
|
+
* `+` is decoded as a space and a value containing `=` is preserved (only the first `=`
|
|
66
|
+
* splits), matching `URLSearchParams`.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} url full URL or query string; defaults to the current location
|
|
69
|
+
* @return {Record<string, string>} parameters; `{}` when there are none
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* getAllQueryString('https://x.dev/a?embed&lang=zh-CN&next=/a%3Fb%3D1');
|
|
73
|
+
* // { embed: '', lang: 'zh-CN', next: '/a?b=1' }
|
|
74
|
+
* ```
|
|
64
75
|
*/
|
|
65
76
|
export declare const getAllQueryString: (url?: string) => Record<string, string>;
|
|
66
77
|
/**
|
|
67
|
-
* @description:
|
|
68
|
-
*
|
|
69
|
-
* @param {
|
|
70
|
-
* @return {
|
|
78
|
+
* @description: Alias of [`getAllQueryString`](#getallquerystring). The two used to be
|
|
79
|
+
* byte-identical copies of the same body; this one now forwards so a fix lands in both.
|
|
80
|
+
* @param {string} url full URL or query string; defaults to the current location
|
|
81
|
+
* @return {Record<string, string>}
|
|
71
82
|
*/
|
|
72
83
|
export declare const getQuery: (url?: string) => Record<string, string>;
|
|
73
84
|
/**
|
|
74
|
-
* @description:
|
|
85
|
+
* @description: Read a query parameter as a boolean flag. True for `?k`, `?k=`, `?k=1` and
|
|
86
|
+
* `?k=true` (case-insensitive); false for anything else, including an absent parameter and
|
|
87
|
+
* an explicit `?k=false`.
|
|
88
|
+
*
|
|
89
|
+
* This is the URL spelling of a boolean: `?embed`, `?readonly` and `?debug` are all written
|
|
90
|
+
* without a value most of the time, so a plain `getQuery(url).embed` check is wrong for the
|
|
91
|
+
* most common form.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} key parameter name
|
|
94
|
+
* @param {string} url full URL or query string; defaults to the current location
|
|
95
|
+
* @return {boolean}
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* queryFlag('embed', '?embed'); // true
|
|
99
|
+
* queryFlag('embed', '?embed=1'); // true
|
|
100
|
+
* queryFlag('embed', '?embed=false'); // false
|
|
101
|
+
* queryFlag('embed', '?lang=en'); // false
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare const queryFlag: (key: string, url?: string) => boolean;
|
|
105
|
+
/**
|
|
106
|
+
* @description: Whether this page is running inside an iframe. Returns false under SSR.
|
|
107
|
+
*
|
|
108
|
+
* Cross-origin embedding can make `window.parent` throw on access in some engines, so the
|
|
109
|
+
* comparison is guarded: an unreadable parent means the page is framed by a foreign origin,
|
|
110
|
+
* which still counts as embedded.
|
|
111
|
+
*
|
|
112
|
+
* @return {boolean}
|
|
113
|
+
*/
|
|
114
|
+
export declare const isInIframe: () => boolean;
|
|
115
|
+
/**
|
|
116
|
+
* @description: Turn an object into a query string and append it to a URL
|
|
75
117
|
* @return {*}
|
|
76
118
|
*/
|
|
77
119
|
export declare function appendUrl(url: string, params?: Record<string, string>): string;
|
|
78
120
|
/**
|
|
79
|
-
* @description:
|
|
121
|
+
* @description: Remove the drag event's ghost image
|
|
80
122
|
* @param {DragEvent} event
|
|
81
123
|
* @return {*}
|
|
82
124
|
*/
|
|
@@ -87,11 +129,11 @@ interface ClientRatio {
|
|
|
87
129
|
height: number;
|
|
88
130
|
}
|
|
89
131
|
/**
|
|
90
|
-
*
|
|
132
|
+
* Get the viewport size across browsers
|
|
91
133
|
*/
|
|
92
134
|
export declare const getWindow: () => ClientRatio;
|
|
93
135
|
/**
|
|
94
|
-
* @description:
|
|
136
|
+
* @description: Current network status: type, throughput, and whether the connection changed
|
|
95
137
|
*/
|
|
96
138
|
export declare const connection: () => number | undefined;
|
|
97
139
|
/**
|
|
@@ -122,173 +164,21 @@ interface ReturnType {
|
|
|
122
164
|
jitter: number;
|
|
123
165
|
}
|
|
124
166
|
/**
|
|
125
|
-
* @description:
|
|
167
|
+
* @description: Request an image (used to time the network)
|
|
126
168
|
* @param {string} url
|
|
127
169
|
* @return {Promise<ImageLoadError | number>}
|
|
128
170
|
*/
|
|
129
171
|
export declare const imageRequest: (url?: string) => Promise<number>;
|
|
130
172
|
/**
|
|
131
|
-
* @description:
|
|
173
|
+
* @description: Run a function repeatedly at a fixed interval
|
|
132
174
|
* @param {HandlerFunction} handler
|
|
133
175
|
* @param {array} params
|
|
134
176
|
*/
|
|
135
177
|
export declare const durationHandler: <T, U>(handler: (...args: T[]) => U, ...params: T[]) => ((a: number) => Promise<U>);
|
|
136
178
|
/**
|
|
137
|
-
* @description:
|
|
179
|
+
* @description: Measure the network's ping by timing requests
|
|
138
180
|
* @param {*} options
|
|
139
181
|
*/
|
|
140
182
|
export declare const networkSpeed: (options: Options) => Promise<ReturnType>;
|
|
141
183
|
export declare const isSafari: () => boolean | undefined | string;
|
|
142
|
-
export interface MessageHandler<T = unknown, R = unknown> {
|
|
143
|
-
(payload: T): Promise<R> | R;
|
|
144
|
-
}
|
|
145
|
-
export interface MessageData<T = unknown> {
|
|
146
|
-
type: string;
|
|
147
|
-
payload: T;
|
|
148
|
-
id?: string;
|
|
149
|
-
isResponse?: boolean;
|
|
150
|
-
isError?: boolean;
|
|
151
|
-
/** 通道标识:用于隔离同一窗口上的多个 bridge(默认 DEFAULT_CHANNEL) */
|
|
152
|
-
channel?: string;
|
|
153
|
-
/** 发送方实例 id:用于避免 bridge 处理自己发出的请求(自答自问) */
|
|
154
|
-
senderId?: string;
|
|
155
|
-
}
|
|
156
|
-
export interface PendingRequest<R = unknown> {
|
|
157
|
-
resolve: (value: R) => void;
|
|
158
|
-
reject: (error: unknown) => void;
|
|
159
|
-
}
|
|
160
|
-
export declare const BRIDGE_MARKER = "__ranuts_bridge__";
|
|
161
|
-
export declare const DEFAULT_CHANNEL = "default";
|
|
162
|
-
/**
|
|
163
|
-
* Bridge 注册事件,供 client 消费
|
|
164
|
-
*/
|
|
165
|
-
export declare class PostMessageBridge {
|
|
166
|
-
private targetWindow;
|
|
167
|
-
private targetOrigin;
|
|
168
|
-
private messageHandlers;
|
|
169
|
-
private pendingRequests;
|
|
170
|
-
private channel;
|
|
171
|
-
private senderId;
|
|
172
|
-
private available;
|
|
173
|
-
constructor(targetWindow?: Window, targetOrigin?: string, channel?: string);
|
|
174
|
-
private post;
|
|
175
|
-
receive: (event: MessageEvent) => void;
|
|
176
|
-
on: <T = unknown, R = unknown>(type: string, handler: MessageHandler<T, R>) => void;
|
|
177
|
-
off: (type: string) => void;
|
|
178
|
-
send: <T = unknown, R = unknown>(type: string, payload: T) => Promise<R>;
|
|
179
|
-
broadcast: <T = unknown>(data: {
|
|
180
|
-
type: string;
|
|
181
|
-
payload: T;
|
|
182
|
-
}) => void;
|
|
183
|
-
destroy: () => void;
|
|
184
|
-
}
|
|
185
|
-
export interface BridgeManagerOptions {
|
|
186
|
-
id?: string;
|
|
187
|
-
targetOrigin?: string;
|
|
188
|
-
targetWindow?: Window;
|
|
189
|
-
/** 通道标识:需要隔离同一窗口上的多个连接时显式指定,两端须一致 */
|
|
190
|
-
channel?: string;
|
|
191
|
-
}
|
|
192
|
-
export declare class BridgeManager {
|
|
193
|
-
private static instance;
|
|
194
|
-
private bridges;
|
|
195
|
-
private constructor();
|
|
196
|
-
static getInstance(): BridgeManager;
|
|
197
|
-
connectClient: ({ id, targetOrigin, targetWindow, channel, }: BridgeManagerOptions) => {
|
|
198
|
-
bridge: PostMessageBridge;
|
|
199
|
-
id: string;
|
|
200
|
-
};
|
|
201
|
-
getClient: (id: string) => PostMessageBridge | undefined;
|
|
202
|
-
removeClient: (id: string) => void;
|
|
203
|
-
removeAllClient: () => void;
|
|
204
|
-
broadcast: <T = unknown>(payload: {
|
|
205
|
-
type: string;
|
|
206
|
-
payload: T;
|
|
207
|
-
}) => void;
|
|
208
|
-
sendTo: <T = unknown, R = unknown>(id: string, type: string, payload: T) => Promise<R>;
|
|
209
|
-
}
|
|
210
|
-
export declare const bridgeManager: BridgeManager;
|
|
211
|
-
export interface BroadcastPayload {
|
|
212
|
-
type: string;
|
|
213
|
-
payload: unknown;
|
|
214
|
-
}
|
|
215
|
-
export interface CallToPayload<T = unknown> {
|
|
216
|
-
id: string;
|
|
217
|
-
type: string;
|
|
218
|
-
payload: T;
|
|
219
|
-
}
|
|
220
|
-
export declare const Client: {
|
|
221
|
-
connect: ({ id, targetWindow, targetOrigin, channel, }: BridgeManagerOptions) => {
|
|
222
|
-
bridge: PostMessageBridge;
|
|
223
|
-
id: string;
|
|
224
|
-
};
|
|
225
|
-
remove: (id: string) => void;
|
|
226
|
-
removeAll: () => void;
|
|
227
|
-
/** 广播消息到所有 Platform */
|
|
228
|
-
broadcast: (payload: BroadcastPayload) => void;
|
|
229
|
-
/** 发送消息到指定 Platform */
|
|
230
|
-
call: <T = unknown, R = unknown>({ id, type, payload }: CallToPayload<T>) => Promise<R>;
|
|
231
|
-
/** 广播消息到所有所有可以接收消息的窗口 (为了安全考虑,不建议使用) */
|
|
232
|
-
broadcastToAll: (payload: BroadcastPayload) => void;
|
|
233
|
-
};
|
|
234
|
-
export declare const initPlatform: <T = unknown, R = unknown>(events: Record<string, MessageHandler<T, R>>) => {
|
|
235
|
-
destroy: () => void;
|
|
236
|
-
};
|
|
237
|
-
export declare const Platform: {
|
|
238
|
-
init: <T = unknown, R = unknown>(events: Record<string, MessageHandler<T, R>>) => {
|
|
239
|
-
destroy: () => void;
|
|
240
|
-
};
|
|
241
|
-
};
|
|
242
|
-
/**
|
|
243
|
-
* 基于 MessagePort 的点对点桥接(方案 B,作为新 API 提供)。
|
|
244
|
-
*
|
|
245
|
-
* 与 PostMessageBridge 的「全局广播 + 过滤」不同,MessagePort 是浏览器提供的
|
|
246
|
-
* 私有点对点信道:只有握手时拿到 port 的双方能通信。因此天然规避了
|
|
247
|
-
* 跨窗口串消息、来源伪造、同窗口多桥串台、自答自问等问题,也无需 origin 过滤、
|
|
248
|
-
* 无需协议标记、无需 base64——payload 直接走结构化克隆。
|
|
249
|
-
*
|
|
250
|
-
* 典型用法:
|
|
251
|
-
* // A 窗口(发起方)
|
|
252
|
-
* const bridge = openPortBridge({ targetWindow: iframe.contentWindow, targetOrigin });
|
|
253
|
-
* const res = await bridge.send('ping', { n: 1 });
|
|
254
|
-
*
|
|
255
|
-
* // B 窗口(接收方)
|
|
256
|
-
* const bridge = await acceptPortBridge({ targetOrigin });
|
|
257
|
-
* bridge.on('ping', ({ n }) => n + 1);
|
|
258
|
-
*
|
|
259
|
-
* 也可用于已有 port 的场景(Web Worker / SharedWorker):createPortBridge(port)。
|
|
260
|
-
*/
|
|
261
|
-
export interface PortBridge {
|
|
262
|
-
on: <T = unknown, R = unknown>(type: string, handler: MessageHandler<T, R>) => void;
|
|
263
|
-
off: (type: string) => void;
|
|
264
|
-
send: <T = unknown, R = unknown>(type: string, payload: T) => Promise<R>;
|
|
265
|
-
broadcast: <T = unknown>(data: {
|
|
266
|
-
type: string;
|
|
267
|
-
payload: T;
|
|
268
|
-
}) => void;
|
|
269
|
-
destroy: () => void;
|
|
270
|
-
}
|
|
271
|
-
export interface OpenPortBridgeOptions {
|
|
272
|
-
targetWindow: Window;
|
|
273
|
-
targetOrigin?: string;
|
|
274
|
-
/** 连接名:一个页面里区分多个独立 port 连接,两端须一致(默认 'default') */
|
|
275
|
-
name?: string;
|
|
276
|
-
}
|
|
277
|
-
export interface AcceptPortBridgeOptions {
|
|
278
|
-
targetOrigin?: string;
|
|
279
|
-
name?: string;
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* 在任意 MessagePort 上构建 bridge(Web Worker / SharedWorker 或已握手的 port)。
|
|
283
|
-
*/
|
|
284
|
-
export declare const createPortBridge: (port: MessagePort) => PortBridge;
|
|
285
|
-
/**
|
|
286
|
-
* 发起方:创建 MessageChannel,把一端交给目标窗口,自己持有另一端。
|
|
287
|
-
*/
|
|
288
|
-
export declare const openPortBridge: ({ targetWindow, targetOrigin, name, }: OpenPortBridgeOptions) => PortBridge;
|
|
289
|
-
/**
|
|
290
|
-
* 接收方:等待发起方递来的 port,握手完成后返回 bridge。
|
|
291
|
-
* 返回的 Promise 在收到匹配 name 的握手消息后 resolve。
|
|
292
|
-
*/
|
|
293
|
-
export declare const acceptPortBridge: ({ targetOrigin, name, }?: AcceptPortBridgeOptions) => Promise<PortBridge>;
|
|
294
184
|
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
export interface MessageHandler<T = unknown, R = unknown> {
|
|
2
|
+
(payload: T): Promise<R> | R;
|
|
3
|
+
}
|
|
4
|
+
export interface MessageData<T = unknown> {
|
|
5
|
+
type: string;
|
|
6
|
+
payload: T;
|
|
7
|
+
id?: string;
|
|
8
|
+
isResponse?: boolean;
|
|
9
|
+
isError?: boolean;
|
|
10
|
+
/** Channel id, isolating several bridges on one window (defaults to DEFAULT_CHANNEL) */
|
|
11
|
+
channel?: string;
|
|
12
|
+
/** Sender instance id, so a bridge never answers its own request */
|
|
13
|
+
senderId?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PendingRequest<R = unknown> {
|
|
16
|
+
resolve: (value: R) => void;
|
|
17
|
+
reject: (error: unknown) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare const BRIDGE_MARKER = "__ranuts_bridge__";
|
|
20
|
+
export declare const DEFAULT_CHANNEL = "default";
|
|
21
|
+
/**
|
|
22
|
+
* Bridge registration event, consumed by the client
|
|
23
|
+
*/
|
|
24
|
+
export declare class PostMessageBridge {
|
|
25
|
+
private targetWindow;
|
|
26
|
+
private targetOrigin;
|
|
27
|
+
private messageHandlers;
|
|
28
|
+
private pendingRequests;
|
|
29
|
+
private channel;
|
|
30
|
+
private senderId;
|
|
31
|
+
private available;
|
|
32
|
+
constructor(targetWindow?: Window, targetOrigin?: string, channel?: string);
|
|
33
|
+
private post;
|
|
34
|
+
receive: (event: MessageEvent) => void;
|
|
35
|
+
on: <T = unknown, R = unknown>(type: string, handler: MessageHandler<T, R>) => void;
|
|
36
|
+
off: (type: string) => void;
|
|
37
|
+
send: <T = unknown, R = unknown>(type: string, payload: T) => Promise<R>;
|
|
38
|
+
broadcast: <T = unknown>(data: {
|
|
39
|
+
type: string;
|
|
40
|
+
payload: T;
|
|
41
|
+
}) => void;
|
|
42
|
+
destroy: () => void;
|
|
43
|
+
}
|
|
44
|
+
export interface BridgeManagerOptions {
|
|
45
|
+
id?: string;
|
|
46
|
+
targetOrigin?: string;
|
|
47
|
+
targetWindow?: Window;
|
|
48
|
+
/** Channel id; set it to isolate several connections on one window. Both ends must agree. */
|
|
49
|
+
channel?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare class BridgeManager {
|
|
52
|
+
private static instance;
|
|
53
|
+
private bridges;
|
|
54
|
+
private constructor();
|
|
55
|
+
static getInstance(): BridgeManager;
|
|
56
|
+
connectClient: ({ id, targetOrigin, targetWindow, channel, }: BridgeManagerOptions) => {
|
|
57
|
+
bridge: PostMessageBridge;
|
|
58
|
+
id: string;
|
|
59
|
+
};
|
|
60
|
+
getClient: (id: string) => PostMessageBridge | undefined;
|
|
61
|
+
removeClient: (id: string) => void;
|
|
62
|
+
removeAllClient: () => void;
|
|
63
|
+
broadcast: <T = unknown>(payload: {
|
|
64
|
+
type: string;
|
|
65
|
+
payload: T;
|
|
66
|
+
}) => void;
|
|
67
|
+
sendTo: <T = unknown, R = unknown>(id: string, type: string, payload: T) => Promise<R>;
|
|
68
|
+
}
|
|
69
|
+
export declare const bridgeManager: BridgeManager;
|
|
70
|
+
export interface BroadcastPayload {
|
|
71
|
+
type: string;
|
|
72
|
+
payload: unknown;
|
|
73
|
+
}
|
|
74
|
+
export interface CallToPayload<T = unknown> {
|
|
75
|
+
id: string;
|
|
76
|
+
type: string;
|
|
77
|
+
payload: T;
|
|
78
|
+
}
|
|
79
|
+
export declare const Client: {
|
|
80
|
+
connect: ({ id, targetWindow, targetOrigin, channel, }: BridgeManagerOptions) => {
|
|
81
|
+
bridge: PostMessageBridge;
|
|
82
|
+
id: string;
|
|
83
|
+
};
|
|
84
|
+
remove: (id: string) => void;
|
|
85
|
+
removeAll: () => void;
|
|
86
|
+
/** Broadcast to every Platform */
|
|
87
|
+
broadcast: (payload: BroadcastPayload) => void;
|
|
88
|
+
/** Send to a named Platform */
|
|
89
|
+
call: <T = unknown, R = unknown>({ id, type, payload }: CallToPayload<T>) => Promise<R>;
|
|
90
|
+
/** Broadcast to every window that can receive it (discouraged — it is a security risk) */
|
|
91
|
+
broadcastToAll: (payload: BroadcastPayload) => void;
|
|
92
|
+
};
|
|
93
|
+
export declare const initPlatform: <T = unknown, R = unknown>(events: Record<string, MessageHandler<T, R>>) => {
|
|
94
|
+
destroy: () => void;
|
|
95
|
+
};
|
|
96
|
+
export declare const Platform: {
|
|
97
|
+
init: typeof initPlatform;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* A point-to-point bridge over MessagePort.
|
|
101
|
+
*
|
|
102
|
+
* Unlike PostMessageBridge's broadcast-then-filter model, a MessagePort is a private
|
|
103
|
+
* point-to-point channel provided by the browser: only the two parties holding the port
|
|
104
|
+
* after the handshake can talk. That rules out cross-window leakage, forged origins,
|
|
105
|
+
* cross-talk between bridges on one window and self-answering by construction — with no
|
|
106
|
+
* origin filter, no protocol marker and no base64, since the payload goes straight through
|
|
107
|
+
* structured clone.
|
|
108
|
+
*
|
|
109
|
+
* Typical use:
|
|
110
|
+
* // Window A (initiator)
|
|
111
|
+
* const bridge = openPortBridge({ targetWindow: iframe.contentWindow, targetOrigin });
|
|
112
|
+
* const res = await bridge.send('ping', { n: 1 });
|
|
113
|
+
*
|
|
114
|
+
* // Window B (acceptor)
|
|
115
|
+
* const bridge = await acceptPortBridge({ targetOrigin });
|
|
116
|
+
* bridge.on('ping', ({ n }) => n + 1);
|
|
117
|
+
*
|
|
118
|
+
* It also works where a port already exists (Web Worker / SharedWorker): createPortBridge(port).
|
|
119
|
+
*/
|
|
120
|
+
export interface PortBridge {
|
|
121
|
+
on: <T = unknown, R = unknown>(type: string, handler: MessageHandler<T, R>) => void;
|
|
122
|
+
off: (type: string) => void;
|
|
123
|
+
send: <T = unknown, R = unknown>(type: string, payload: T) => Promise<R>;
|
|
124
|
+
broadcast: <T = unknown>(data: {
|
|
125
|
+
type: string;
|
|
126
|
+
payload: T;
|
|
127
|
+
}) => void;
|
|
128
|
+
destroy: () => void;
|
|
129
|
+
}
|
|
130
|
+
export interface OpenPortBridgeOptions {
|
|
131
|
+
targetWindow: Window;
|
|
132
|
+
targetOrigin?: string;
|
|
133
|
+
/** Connection name, telling independent port connections apart on one page. Both ends must agree (defaults to 'default'). */
|
|
134
|
+
name?: string;
|
|
135
|
+
}
|
|
136
|
+
export interface AcceptPortBridgeOptions {
|
|
137
|
+
targetOrigin?: string;
|
|
138
|
+
name?: string;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build a bridge on any MessagePort (a Web Worker, a SharedWorker, or a port from a completed handshake).
|
|
142
|
+
*/
|
|
143
|
+
export declare const createPortBridge: (port: MessagePort) => PortBridge;
|
|
144
|
+
/**
|
|
145
|
+
* Initiator: create a MessageChannel, hand one port to the target window and keep the other.
|
|
146
|
+
*/
|
|
147
|
+
export declare const openPortBridge: ({ targetWindow, targetOrigin, name, }: OpenPortBridgeOptions) => PortBridge;
|
|
148
|
+
/**
|
|
149
|
+
* Acceptor: wait for the port the initiator hands over and return the bridge once the
|
|
150
|
+
* handshake completes. The returned promise resolves on a handshake message with a matching
|
|
151
|
+
* name.
|
|
152
|
+
*/
|
|
153
|
+
export declare const acceptPortBridge: ({ targetOrigin, name, }?: AcceptPortBridgeOptions) => Promise<PortBridge>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description: Degrees to radians
|
|
3
|
+
* @param {number} deg angle in degrees
|
|
4
|
+
* @return {number} angle in radians
|
|
5
|
+
*/
|
|
6
|
+
export declare const getAngle: (deg: number) => number;
|
|
7
|
+
/**
|
|
8
|
+
* @description: The point on a circle at a given angle
|
|
9
|
+
* @param {number} deg angle in radians
|
|
10
|
+
* @param {number} r radius
|
|
11
|
+
* @return {[number, number]} the coordinates [x, y]
|
|
12
|
+
*/
|
|
13
|
+
export declare const getArcPointerByDeg: (deg: number, r: number) => [number, number];
|
|
14
|
+
/**
|
|
15
|
+
* @description: The tangent line at a point on a circle
|
|
16
|
+
* @param {number} x x coordinate
|
|
17
|
+
* @param {number} y y coordinate
|
|
18
|
+
* @return {Array<number>} [slope, intercept]
|
|
19
|
+
*/
|
|
20
|
+
export declare const getTangentByPointer: (x: number, y: number) => Array<number>;
|
|
21
|
+
/**
|
|
22
|
+
* @description: Trace a pie slice with arc(), including the gutter between slices.
|
|
23
|
+
* Builds the path only — no fill or stroke, so the caller decides how to paint it.
|
|
24
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
25
|
+
* @param {number} maxRadius outer radius
|
|
26
|
+
* @param {number} start start angle in radians
|
|
27
|
+
* @param {number} end end angle in radians
|
|
28
|
+
* @param {number} gutter width of the gap between slices
|
|
29
|
+
*/
|
|
30
|
+
export declare const fanShapedByArc: (ctx: CanvasRenderingContext2D, maxRadius: number, start: number, end: number, gutter: number) => void;
|
|
31
|
+
/**
|
|
32
|
+
* @description: Trace a rounded rectangle with arc(). A corner radius larger than half the
|
|
33
|
+
* shorter side is clamped to half, so adjacent corners cannot overlap. Builds the path only
|
|
34
|
+
* — no fill or stroke.
|
|
35
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
36
|
+
* @param {number[]} rest [x, y, w, h, r]
|
|
37
|
+
*/
|
|
38
|
+
export declare const roundRectByArc: (ctx: CanvasRenderingContext2D, ...[x, y, w, h, r]: number[]) => void;
|
|
39
|
+
/**
|
|
40
|
+
* @description: Translate a CSS `linear-gradient(...)` string into a Canvas CanvasGradient.
|
|
41
|
+
*
|
|
42
|
+
* createLinearGradient only takes a start and an end point, while CSS describes direction
|
|
43
|
+
* as an angle — so the circle is split into eight 45° sectors and the tangent turns the
|
|
44
|
+
* angle back into start/end coordinates on the rectangle's boundary.
|
|
45
|
+
*
|
|
46
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
47
|
+
* @param {number} x x of the rectangle's top-left corner
|
|
48
|
+
* @param {number} y y of the rectangle's top-left corner
|
|
49
|
+
* @param {number} w rectangle width
|
|
50
|
+
* @param {number} h rectangle height
|
|
51
|
+
* @param {string} background a string such as `linear-gradient(90deg, red, blue)`
|
|
52
|
+
* @return {CanvasGradient} assignable straight to fillStyle / strokeStyle
|
|
53
|
+
*/
|
|
54
|
+
export declare const getLinearGradient: (ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, background: string) => CanvasGradient;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description: Chainable DOM operations
|
|
3
|
+
* (tag) (key value) (children)
|
|
4
|
+
* @return {HTMLElement}
|
|
5
|
+
*/
|
|
6
|
+
export declare class Chain {
|
|
7
|
+
listener: Map<string, Map<string, EventListener>>;
|
|
8
|
+
element: HTMLElement;
|
|
9
|
+
constructor(tagName: string, options?: ElementCreationOptions);
|
|
10
|
+
/**
|
|
11
|
+
* @description: Create an element
|
|
12
|
+
* @param {string} tagName
|
|
13
|
+
* @param {ElementCreationOptions} options
|
|
14
|
+
* @return {Chain}
|
|
15
|
+
*/
|
|
16
|
+
create: (tagName: string, options?: ElementCreationOptions) => HTMLElement;
|
|
17
|
+
/**
|
|
18
|
+
* @description: Set an attribute on the current element
|
|
19
|
+
* @param {string} name
|
|
20
|
+
* @param {string} value
|
|
21
|
+
* @return {Chain}
|
|
22
|
+
*/
|
|
23
|
+
setAttribute: (name: string, value: string) => Chain;
|
|
24
|
+
/**
|
|
25
|
+
* @description: Remove an attribute from the current element
|
|
26
|
+
* @param {string} name
|
|
27
|
+
* @return {Chain}
|
|
28
|
+
*/
|
|
29
|
+
removeAttribute: (name: string) => Chain;
|
|
30
|
+
/**
|
|
31
|
+
* @description: Append a child to the current element
|
|
32
|
+
* @param {HTMLElement} child
|
|
33
|
+
* @return {ChainElement}
|
|
34
|
+
*/
|
|
35
|
+
append: (child: HTMLElement) => Chain;
|
|
36
|
+
/**
|
|
37
|
+
* @description: Remove a child from the current element
|
|
38
|
+
* @param {HTMLElement} child
|
|
39
|
+
* @return {Chain}
|
|
40
|
+
*/
|
|
41
|
+
remove: (child: HTMLElement) => Chain;
|
|
42
|
+
/**
|
|
43
|
+
* @description: Set the current element's text content
|
|
44
|
+
* @param {string} text
|
|
45
|
+
* @return {Chain}
|
|
46
|
+
*/
|
|
47
|
+
setTextContent: (text: string) => Chain;
|
|
48
|
+
/**
|
|
49
|
+
* @description: Set styles on the current element
|
|
50
|
+
* @param {string} name
|
|
51
|
+
* @param {string} value
|
|
52
|
+
* @return {Chain}
|
|
53
|
+
*/
|
|
54
|
+
setStyle: (name: string, value: string) => Chain;
|
|
55
|
+
private addElementByType;
|
|
56
|
+
/**
|
|
57
|
+
* @description: Append children to the current element
|
|
58
|
+
* @return {Chain}
|
|
59
|
+
*/
|
|
60
|
+
addChild: (child: Chain | Chain[] | HTMLElement | HTMLElement[]) => Chain;
|
|
61
|
+
/**
|
|
62
|
+
* @description: Add an event listener to the current element
|
|
63
|
+
* @param {string} type
|
|
64
|
+
* @param {EventListener} listener
|
|
65
|
+
* @return {Chain}
|
|
66
|
+
*/
|
|
67
|
+
listen: <K extends keyof HTMLElementEventMap>(type: K, listener: EventListener, options?: boolean | AddEventListenerOptions) => Chain;
|
|
68
|
+
/**
|
|
69
|
+
* @description: Remove an event listener from the current element
|
|
70
|
+
* @param {string} type
|
|
71
|
+
* @return {Chain}
|
|
72
|
+
*/
|
|
73
|
+
clearListener: <K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions) => Chain;
|
|
74
|
+
/**
|
|
75
|
+
* @description: Remove every event listener from the current element
|
|
76
|
+
* @return {Chain}
|
|
77
|
+
*/
|
|
78
|
+
clearAllListener: () => Chain;
|
|
79
|
+
}
|
|
80
|
+
export declare const create: (tagName: string, options?: ElementCreationOptions) => Chain;
|