yeow-api 0.2.112 → 0.2.114
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/package.json +1 -1
- package/src/core.ts +6 -0
- package/src/env.ts +20 -0
- package/src/event.ts +7 -1
- package/src/global.d.ts +1 -0
- package/src/http.ts +13 -1
- package/src/message.ts +19 -0
- package/src/player.ts +16 -5
- package/src/server.ts +3 -2
- package/src/worker.ts +150 -0
package/package.json
CHANGED
package/src/core.ts
CHANGED
|
@@ -51,6 +51,7 @@ export { assets, read as assetsRead, readSync as assetsReadSync,
|
|
|
51
51
|
extractDir as assetsExtractDir, extractDirSync as assetsExtractDirSync } from './assets.js';
|
|
52
52
|
export { path } from './path.js';
|
|
53
53
|
export { listen, respond, close, request, requestSync } from './http.js';
|
|
54
|
+
export type { RespondOptions } from './http.js';
|
|
54
55
|
export { logError } from './log-error.js';
|
|
55
56
|
export { InstanceId, GUIHandle, BossBarHandle, InventoryHandle } from './instance-id.js';
|
|
56
57
|
export type { ItemStack } from './item.js';
|
|
@@ -90,3 +91,8 @@ export type { MaterialInfo } from './material.js';
|
|
|
90
91
|
export { registerService, registerNativeService, request as serviceRequest, subscribe as serviceSubscribe, publish as servicePublish } from './service.js';
|
|
91
92
|
export type { ServiceResult, NativeServiceResult } from './service.js';
|
|
92
93
|
export { log, Logger } from './log.js';
|
|
94
|
+
export type { Message } from './message.js';
|
|
95
|
+
export { getEnv } from './env.js';
|
|
96
|
+
export type { EnvInfo } from './env.js';
|
|
97
|
+
export { createWorker, Worker, onMessage, postMessage } from './worker.js';
|
|
98
|
+
export type { WorkerOptions } from './worker.js';
|
package/src/env.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** env 通道返回的运行时环境信息(同步)。 */
|
|
2
|
+
export interface EnvInfo {
|
|
3
|
+
/** CPU 逻辑核心数。 */
|
|
4
|
+
cpus: number;
|
|
5
|
+
/** JVM 总内存(字节)。 */
|
|
6
|
+
memory: number;
|
|
7
|
+
/** 系统架构(如 `windows-x64` / `linux-x64` / `linux-arm64`)。 */
|
|
8
|
+
arch: string;
|
|
9
|
+
/** Minecraft 版本(如 `1.21.4`)。 */
|
|
10
|
+
minecraftVersion: string;
|
|
11
|
+
/** 运行时信息。 */
|
|
12
|
+
yeow: { platform: string; version: string };
|
|
13
|
+
/** epoch 微秒时间戳。 */
|
|
14
|
+
now: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** 获取运行时环境信息(同步;含微秒时间戳)。 */
|
|
18
|
+
export function getEnv(): EnvInfo {
|
|
19
|
+
return $send('env', {}) as EnvInfo;
|
|
20
|
+
}
|
package/src/event.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { call } from './task.js';
|
|
2
2
|
import { Player } from './player.js';
|
|
3
3
|
import { Location } from './location.js';
|
|
4
|
+
import type { Message } from './message.js';
|
|
4
5
|
|
|
5
6
|
// ── Event Data Interfaces ──────────────────────────────────────────
|
|
6
7
|
|
|
@@ -40,7 +41,8 @@ export interface PlayerCommandEvent {
|
|
|
40
41
|
}
|
|
41
42
|
export interface PlayerDeathEvent {
|
|
42
43
|
player: Player;
|
|
43
|
-
|
|
44
|
+
/** 死亡消息(Message 对象):`{key, args}` 可翻译组件(客户端本地化)+ `{text}` 纯文本兜底,同时传递。 */
|
|
45
|
+
deathMessage: Message;
|
|
44
46
|
deathType: string;
|
|
45
47
|
cancelled?: boolean;
|
|
46
48
|
}
|
|
@@ -179,6 +181,10 @@ export interface PlayerItemConsumeEvent {
|
|
|
179
181
|
export interface PlayerAdvancementDoneEvent {
|
|
180
182
|
player: Player;
|
|
181
183
|
advancement: string;
|
|
184
|
+
/** 进度标题(Message 对象,`{text}` 纯文本;隐藏进度时缺失)。 */
|
|
185
|
+
title?: Message;
|
|
186
|
+
/** 进度描述(Message 对象,`{text}` 纯文本;隐藏进度时缺失)。 */
|
|
187
|
+
description?: Message;
|
|
182
188
|
}
|
|
183
189
|
export interface PlayerToggleSneakEvent {
|
|
184
190
|
player: Player;
|
package/src/global.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ declare global {
|
|
|
11
11
|
function _unregisterCallback(id: string): void;
|
|
12
12
|
function _getCurrentCbStack(): { stack: string; outer: unknown } | null;
|
|
13
13
|
function _attachCbStack(err: unknown): void;
|
|
14
|
+
function reportError(e: unknown): void;
|
|
14
15
|
|
|
15
16
|
// ── init.js 注入的标准环境(lib 为 ESNext,不含 DOM——自行声明)──
|
|
16
17
|
interface YeowConsole {
|
package/src/http.ts
CHANGED
|
@@ -7,6 +7,18 @@ interface HttpResult {
|
|
|
7
7
|
err?: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/** HTTP 响应选项(respond)。 */
|
|
11
|
+
export interface RespondOptions {
|
|
12
|
+
/** HTTP 状态码(默认 200)。 */
|
|
13
|
+
status?: number;
|
|
14
|
+
/** 文本响应体(UTF-8)。 */
|
|
15
|
+
body?: string;
|
|
16
|
+
/** base64 编码的**二进制**响应体(与 body 互斥,优先)——如从 assets 读取的资源包等。 */
|
|
17
|
+
bodyBase64?: string;
|
|
18
|
+
/** 响应头。 */
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
function _sendHttp(payload: Record<string, unknown>): HttpResult {
|
|
11
23
|
const r = $send('http', payload);
|
|
12
24
|
if (!r) return {};
|
|
@@ -31,7 +43,7 @@ export function listen(callback: (req: Record<string, unknown>) => void, port?:
|
|
|
31
43
|
return result;
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
export function respond(serverId: string, connId: string, opts:
|
|
46
|
+
export function respond(serverId: string, connId: string, opts: RespondOptions = {}): void {
|
|
35
47
|
_sendHttp({ t: 'respond', p: { serverId, connId, ...opts } });
|
|
36
48
|
}
|
|
37
49
|
|
package/src/message.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message —— 可翻译组件 / 纯文本的统一消息对象。
|
|
3
|
+
*
|
|
4
|
+
* - `{ key, args? }`:Minecraft 翻译键组件(如死亡消息 `death.attack.player`),
|
|
5
|
+
* 由客户端按语言本地化;`args` 为翻译参数(字符串/数字/嵌套 Message)
|
|
6
|
+
* - `{ text }`:纯文本(MiniMessage/legacy 解析)——所有实现**至少应支持 text 字段**
|
|
7
|
+
* - 两者同时存在时 `key` 优先
|
|
8
|
+
*
|
|
9
|
+
* 发送消息 API(`player.sendMessage`、`broadcast`、`sendActionBar` 等)与
|
|
10
|
+
* 事件字段(如 `playerDeath.deathMessage`)均接受该对象或纯字符串。
|
|
11
|
+
*/
|
|
12
|
+
export interface Message {
|
|
13
|
+
/** Minecraft 翻译键(如 `death.attack.player`)。 */
|
|
14
|
+
key?: string;
|
|
15
|
+
/** 翻译参数(字符串/数字/嵌套 Message)。 */
|
|
16
|
+
args?: (string | number | Message)[];
|
|
17
|
+
/** 纯文本(MiniMessage 解析;key 缺失时使用)。 */
|
|
18
|
+
text?: string;
|
|
19
|
+
}
|
package/src/player.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { call, post } from './task.js';
|
|
|
2
2
|
import type { TaskOptions } from './task.js';
|
|
3
3
|
import { Location, LocationData } from './location.js';
|
|
4
4
|
import type { ItemStack } from './item.js';
|
|
5
|
+
import type { Message } from './message.js';
|
|
5
6
|
|
|
6
7
|
interface PlayerData {
|
|
7
8
|
uuid: string;
|
|
@@ -116,8 +117,8 @@ export class Player {
|
|
|
116
117
|
get totalExperience(): number { return call<number>('player.getTotalExperience', { uuid: this.uuid }); }
|
|
117
118
|
getTotalExperience(options?: TaskOptions): Promise<number> { return post<number>('player.getTotalExperience', { uuid: this.uuid }, options); }
|
|
118
119
|
|
|
119
|
-
sendMessage(msg: string, options?: TaskOptions): Promise<void> { return post('player.sendMessage', { uuid: this.uuid, message: msg }, options); }
|
|
120
|
-
sendMessageSync(msg: string, options?: TaskOptions): void { call('player.sendMessage', { uuid: this.uuid, message: msg }, options); }
|
|
120
|
+
sendMessage(msg: string | Message, options?: TaskOptions): Promise<void> { return post('player.sendMessage', { uuid: this.uuid, message: msg }, options); }
|
|
121
|
+
sendMessageSync(msg: string | Message, options?: TaskOptions): void { call('player.sendMessage', { uuid: this.uuid, message: msg }, options); }
|
|
121
122
|
kick(reason?: string, options?: TaskOptions): Promise<void> { return post('player.kick', { uuid: this.uuid, reason }, options); }
|
|
122
123
|
kickSync(reason?: string, options?: TaskOptions): void { call('player.kick', { uuid: this.uuid, reason }, options); }
|
|
123
124
|
sendTitle(title?: string, subtitle?: string, fadeIn?: number, stay?: number, fadeOut?: number, options?: TaskOptions): Promise<void> {
|
|
@@ -140,13 +141,23 @@ export class Player {
|
|
|
140
141
|
hasPermissionSync(node: string, options?: TaskOptions): boolean {
|
|
141
142
|
return call<boolean>('player.hasPermission', { uuid: this.uuid, permission: node }, options);
|
|
142
143
|
}
|
|
144
|
+
/** 以玩家身份执行命令(**不含 `/` 前缀**,如 `say hi`;前缀会自动剥离;与服务器 `dispatchCommand`(控制台)相对)。 */
|
|
145
|
+
performCommand(cmd: string, options?: TaskOptions): Promise<boolean> {
|
|
146
|
+
return post<boolean>('player.performCommand', { uuid: this.uuid, command: cmd.replace(/^\//, '') }, options);
|
|
147
|
+
}
|
|
148
|
+
performCommandSync(cmd: string, options?: TaskOptions): boolean {
|
|
149
|
+
return call<boolean>('player.performCommand', { uuid: this.uuid, command: cmd.replace(/^\//, '') }, options);
|
|
150
|
+
}
|
|
143
151
|
teleport(loc: Location, options?: TaskOptions): Promise<void> { return post('player.teleport', { uuid: this.uuid, ...loc.toObject() }, options); }
|
|
144
152
|
teleportSync(loc: Location, options?: TaskOptions): void { call('player.teleport', { uuid: this.uuid, ...loc.toObject() }, options); }
|
|
145
|
-
sendActionBar(message: string, options?: TaskOptions): Promise<void> { return post('player.sendActionBar', { uuid: this.uuid, message }, options); }
|
|
146
|
-
sendActionBarSync(message: string, options?: TaskOptions): void { call('player.sendActionBar', { uuid: this.uuid, message }, options); }
|
|
147
|
-
sendResourcePack(url: string, hash?: string, prompt?: string, force?: boolean, options?: TaskOptions): Promise<void> {
|
|
153
|
+
sendActionBar(message: string | Message, options?: TaskOptions): Promise<void> { return post('player.sendActionBar', { uuid: this.uuid, message }, options); }
|
|
154
|
+
sendActionBarSync(message: string | Message, options?: TaskOptions): void { call('player.sendActionBar', { uuid: this.uuid, message }, options); }
|
|
155
|
+
sendResourcePack(url: string, hash?: string, prompt?: string | Message, force?: boolean, options?: TaskOptions): Promise<void> {
|
|
148
156
|
return post('player.sendResourcePack', { uuid: this.uuid, url, hash, prompt, force }, options);
|
|
149
157
|
}
|
|
158
|
+
sendResourcePackSync(url: string, hash?: string, prompt?: string | Message, force?: boolean, options?: TaskOptions): void {
|
|
159
|
+
call('player.sendResourcePack', { uuid: this.uuid, url, hash, prompt, force }, options);
|
|
160
|
+
}
|
|
150
161
|
getItemInMainHand(options?: TaskOptions): Promise<ItemStack | null> { return post<ItemStack | null>('player.getItemInMainHand', { uuid: this.uuid }, options); }
|
|
151
162
|
getItemInMainHandSync(options?: TaskOptions): ItemStack | null { return call<ItemStack | null>('player.getItemInMainHand', { uuid: this.uuid }, options); }
|
|
152
163
|
getItemInOffHand(options?: TaskOptions): Promise<ItemStack | null> { return post<ItemStack | null>('player.getItemInOffHand', { uuid: this.uuid }, options); }
|
package/src/server.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { call, post } from './task.js';
|
|
2
2
|
import type { TaskOptions } from './task.js';
|
|
3
|
+
import type { Message } from './message.js';
|
|
3
4
|
|
|
4
|
-
export function broadcast(msg: string, options?: TaskOptions): Promise<void> { return post('server.broadcast', { message: msg }, options); }
|
|
5
|
-
export function broadcastSync(msg: string, options?: TaskOptions): void { call('server.broadcast', { message: msg }, options); }
|
|
5
|
+
export function broadcast(msg: string | Message, options?: TaskOptions): Promise<void> { return post('server.broadcast', { message: msg }, options); }
|
|
6
|
+
export function broadcastSync(msg: string | Message, options?: TaskOptions): void { call('server.broadcast', { message: msg }, options); }
|
|
6
7
|
export function dispatchCommand(cmd: string, options?: TaskOptions): Promise<boolean> { return post<boolean>('command.dispatch', { command: cmd }, options); }
|
|
7
8
|
export function dispatchCommandSync(cmd: string, options?: TaskOptions): boolean { return call<boolean>('command.dispatch', { command: cmd }, options); }
|
|
8
9
|
export function setMotd(motd: string, options?: TaskOptions): Promise<void> { return post('server.setMotd', { motd }, options); }
|
package/src/worker.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export interface WorkerOptions {
|
|
2
|
+
/** Worker 名(必填;不允许 'main';同一主插件内不重复,全局可重复)。 */
|
|
3
|
+
name: string;
|
|
4
|
+
/** 资源路径(通过 `getAssetsPath` 获取);与 `code` 互斥(不可同时传递)。 */
|
|
5
|
+
entry?: string;
|
|
6
|
+
/** 代码字符串;与 `entry` 互斥。 */
|
|
7
|
+
code?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let _seq = 0;
|
|
11
|
+
/** 本主插件已创建的 worker 名(同主插件内唯一校验;unload 后允许重建)。 */
|
|
12
|
+
const _created: Record<string, boolean> = {};
|
|
13
|
+
/** 主插件侧:每个 worker 的 onMessage 回调 id。 */
|
|
14
|
+
const _msgCbs: Record<string, string> = {};
|
|
15
|
+
|
|
16
|
+
function _sendWorker(payload: Record<string, unknown>): unknown {
|
|
17
|
+
const r = $send('worker', payload);
|
|
18
|
+
if (r == null) return undefined;
|
|
19
|
+
if ((r as any)?.err) throw new Error((r as any).err);
|
|
20
|
+
return r;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 内部:异步调用 worker 通道(cb 回调)。 */
|
|
24
|
+
function _sendWorkerAsync(t: string, p: Record<string, unknown>): Promise<void> {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const cbId = _registerCallback((result: unknown) => {
|
|
27
|
+
if ((result as any)?.err) reject(new Error((result as any).err));
|
|
28
|
+
else resolve();
|
|
29
|
+
});
|
|
30
|
+
_sendWorker({ t, p: { ...p, cb: cbId } });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Worker —— 虚拟插件(独立 QuickJS 上下文 + 线程)。
|
|
36
|
+
*
|
|
37
|
+
* - 事件/命令/服务以独立实体注册;调度器任务独立统计
|
|
38
|
+
* - 共享主插件的**数据目录**与**权限**
|
|
39
|
+
* - 不能创建新的 Worker(嵌套被拒绝)
|
|
40
|
+
* - **创建后无法销毁,只能卸载**(卸载物理销毁 JS 上下文,句柄保留——可重新 load)
|
|
41
|
+
* - 主插件卸载时连带卸载;/yeow 管理命令不覆盖 Worker;profiler 会统计(标记 created by 主插件)
|
|
42
|
+
* - Worker 的 JS 错误与主插件同样回传(dev 模式经 source-map 定位)
|
|
43
|
+
*/
|
|
44
|
+
export class Worker {
|
|
45
|
+
private readonly name: string;
|
|
46
|
+
private readonly entry?: string;
|
|
47
|
+
private readonly code?: string;
|
|
48
|
+
private readonly key: string;
|
|
49
|
+
private _loaded = false;
|
|
50
|
+
private _onMessage: ((msg: any) => void) | null = null;
|
|
51
|
+
/** 内部 workerId(主插件 JS 侧分配;跨主插件可重复)。 */
|
|
52
|
+
readonly id: string;
|
|
53
|
+
|
|
54
|
+
constructor(name: string, entry: string | undefined, code: string | undefined) {
|
|
55
|
+
this.name = name;
|
|
56
|
+
this.entry = entry;
|
|
57
|
+
this.code = code;
|
|
58
|
+
this.id = 'worker_' + (++_seq);
|
|
59
|
+
this.key = (__plugin?.name || 'unknown') + ':' + name;
|
|
60
|
+
// 主插件侧 onMessage 回调(worker → main 时 Java 投递到这里)
|
|
61
|
+
_msgCbs[this.id] = _registerCallback((msg: unknown) => {
|
|
62
|
+
const cb = this._onMessage;
|
|
63
|
+
if (cb) { try { cb(msg); } catch (e) { console.error('[worker] onMessage error', e); } }
|
|
64
|
+
}, { persistent: true });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 注册接收 Worker 发来的消息。 */
|
|
68
|
+
onMessage(cb: (msg: any) => void): void {
|
|
69
|
+
this._onMessage = cb;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 启动 Worker:执行 init.js → worker-inject.js → Worker 代码 → INIT → LOAD(已加载为 no-op)。 */
|
|
73
|
+
load(): Promise<void> {
|
|
74
|
+
if (this._loaded) return Promise.resolve();
|
|
75
|
+
this._loaded = true;
|
|
76
|
+
return _sendWorkerAsync('load', { name: this.name });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** 卸载 Worker(物理销毁 JS 上下文并清理其事件/命令/服务/任务;句柄保留,可重新 load)。 */
|
|
80
|
+
unload(): Promise<void> {
|
|
81
|
+
this._loaded = false;
|
|
82
|
+
return _sendWorkerAsync('unload', { name: this.name });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 向 Worker 发送消息(其 onMessage 回调接收;未 load 时抛错)。 */
|
|
86
|
+
postMessage(msg: Record<string, unknown>): Promise<void> {
|
|
87
|
+
return _sendWorkerAsync('post', { name: this.name, msg });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** 重载 Worker 代码(需已 load;旧上下文销毁、新代码重新加载)。 */
|
|
91
|
+
reload(): Promise<void> {
|
|
92
|
+
const p: Record<string, unknown> = { name: this.name };
|
|
93
|
+
if (this.entry) p.entry = this.entry;
|
|
94
|
+
else p.code = this.code;
|
|
95
|
+
return _sendWorkerAsync('reload', p);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 创建 Worker(虚拟插件):**仅注册到注册表并返回句柄**——`worker.load()` 才真正启动
|
|
101
|
+
* (执行 init.js → worker-inject.js → Worker 代码 → INIT → LOAD)。
|
|
102
|
+
*
|
|
103
|
+
* `entry`(资源路径,经 getAssetsPath)与 `code` 二选一,同时传递抛错;
|
|
104
|
+
* `name` 必填、非 'main'、同主插件内不重复。
|
|
105
|
+
*/
|
|
106
|
+
export function createWorker(options: WorkerOptions): Worker {
|
|
107
|
+
const name = options?.name;
|
|
108
|
+
if (!name || typeof name !== 'string' || name.trim() === '') {
|
|
109
|
+
throw new Error('createWorker: name is required');
|
|
110
|
+
}
|
|
111
|
+
if (name === 'main') {
|
|
112
|
+
throw new Error('createWorker: name must not be "main"');
|
|
113
|
+
}
|
|
114
|
+
if (options.entry && options.code) {
|
|
115
|
+
throw new Error('createWorker: entry and code cannot be passed together');
|
|
116
|
+
}
|
|
117
|
+
if (!options.entry && !options.code) {
|
|
118
|
+
throw new Error('createWorker: either entry or code is required');
|
|
119
|
+
}
|
|
120
|
+
const key = (__plugin?.name || 'unknown') + ':' + name;
|
|
121
|
+
if (_created[key]) {
|
|
122
|
+
throw new Error('createWorker: duplicate worker name "' + name + '" in plugin ' + (__plugin?.name || 'unknown'));
|
|
123
|
+
}
|
|
124
|
+
_created[key] = true;
|
|
125
|
+
const w = new Worker(name, options.entry, options.code);
|
|
126
|
+
// 注册到运行时注册表(同步;重复/非法名抛错)
|
|
127
|
+
const p: Record<string, unknown> = { name, msgCb: _msgCbs[w.id] };
|
|
128
|
+
if (options.entry) p.entry = options.entry;
|
|
129
|
+
else p.code = options.code;
|
|
130
|
+
_sendWorker({ t: 'create', p });
|
|
131
|
+
return w;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ── Worker 侧 API(仅 Worker 环境可用)──────────────────────────────
|
|
135
|
+
|
|
136
|
+
const _isWorker = typeof (globalThis as any).__workerId !== 'undefined';
|
|
137
|
+
|
|
138
|
+
/** Worker 侧:注册消息接收回调(主插件 `worker.postMessage` 触发)。主插件环境调用抛错。 */
|
|
139
|
+
export function onMessage(cb: (msg: any) => void): void {
|
|
140
|
+
if (!_isWorker) throw new Error('onMessage is only available inside a Worker');
|
|
141
|
+
(globalThis as any)._workerOnMessage = (msg: any) => {
|
|
142
|
+
try { cb(msg); } catch (e) { reportError(e); }
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Worker 侧:向主插件发送消息(主插件侧 `worker.onMessage` 回调接收)。主插件环境调用抛错。 */
|
|
147
|
+
export function postMessage(msg: Record<string, unknown>): void {
|
|
148
|
+
if (!_isWorker) throw new Error('postMessage is only available inside a Worker');
|
|
149
|
+
_sendWorker({ t: 'postToMain', p: { msg } });
|
|
150
|
+
}
|