yeow-api 0.2.30 → 0.2.33
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/assets.ts +36 -29
- package/src/block.ts +13 -11
- package/src/command.ts +88 -42
- package/src/entity.ts +30 -27
- package/src/event.ts +259 -283
- package/src/fs.ts +64 -47
- package/src/global.d.ts +32 -0
- package/src/http.ts +58 -47
- package/src/index.ts +4 -2
- package/src/inventory.ts +33 -28
- package/src/lifecycle.ts +3 -0
- package/src/location.ts +24 -11
- package/src/player.ts +48 -41
- package/src/server.ts +7 -7
- package/src/task.ts +30 -20
- package/src/world.ts +70 -33
package/src/event.ts
CHANGED
|
@@ -2,373 +2,349 @@ import { call } from './task.js';
|
|
|
2
2
|
import { Player } from './player.js';
|
|
3
3
|
import { Location } from './location.js';
|
|
4
4
|
|
|
5
|
-
// ── Event
|
|
5
|
+
// ── Event Data Interfaces ──────────────────────────────────────────
|
|
6
6
|
|
|
7
7
|
export interface PlayerJoinEvent {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
player: Player;
|
|
9
|
+
joinMessage: string;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
export interface PlayerQuitEvent {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
player: Player;
|
|
13
|
+
quitMessage: string;
|
|
15
14
|
}
|
|
16
|
-
|
|
17
15
|
export interface PlayerChatEvent {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
player: Player;
|
|
17
|
+
message: string;
|
|
18
|
+
format: string;
|
|
21
19
|
}
|
|
22
|
-
|
|
23
20
|
export interface PlayerMoveEvent {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
player: Player;
|
|
22
|
+
from: Location;
|
|
23
|
+
to: Location;
|
|
27
24
|
}
|
|
28
|
-
|
|
29
25
|
export interface PlayerInteractEvent {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
player: Player;
|
|
27
|
+
action: string;
|
|
28
|
+
material: string | null;
|
|
29
|
+
block: { x: number; y: number; z: number; type: string } | null;
|
|
34
30
|
}
|
|
35
|
-
|
|
36
31
|
export interface PlayerCommandEvent {
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
player: Player;
|
|
33
|
+
message: string;
|
|
39
34
|
}
|
|
40
|
-
|
|
41
35
|
export interface PlayerDeathEvent {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
player: Player;
|
|
37
|
+
deathMessage: string;
|
|
38
|
+
deathType: string;
|
|
45
39
|
}
|
|
46
|
-
|
|
47
40
|
export interface PlayerRespawnEvent {
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
player: Player;
|
|
42
|
+
respawnLocation: Location;
|
|
50
43
|
}
|
|
51
|
-
|
|
52
44
|
export interface PlayerDropItemEvent {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
player: Player;
|
|
46
|
+
itemType: string;
|
|
47
|
+
amount: number;
|
|
56
48
|
}
|
|
57
|
-
|
|
58
49
|
export interface PlayerPickupItemEvent {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
player: Player;
|
|
51
|
+
itemType: string;
|
|
52
|
+
amount: number;
|
|
62
53
|
}
|
|
63
|
-
|
|
64
54
|
export interface PlayerBucketFillEvent {
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
player: Player;
|
|
56
|
+
bucket: string;
|
|
67
57
|
}
|
|
68
|
-
|
|
69
58
|
export interface PlayerBucketEmptyEvent {
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
player: Player;
|
|
60
|
+
bucket: string;
|
|
72
61
|
}
|
|
73
|
-
|
|
74
62
|
export interface PlayerExpChangeEvent {
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
player: Player;
|
|
64
|
+
amount: number;
|
|
77
65
|
}
|
|
78
|
-
|
|
79
66
|
export interface PlayerLevelChangeEvent {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
player: Player;
|
|
68
|
+
oldLevel: number;
|
|
69
|
+
newLevel: number;
|
|
83
70
|
}
|
|
84
|
-
|
|
85
71
|
export interface PlayerGameModeChangeEvent {
|
|
86
|
-
|
|
87
|
-
|
|
72
|
+
player: Player;
|
|
73
|
+
newGameMode: string;
|
|
88
74
|
}
|
|
89
|
-
|
|
90
75
|
export interface FoodLevelChangeEvent {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
player: Player;
|
|
77
|
+
oldFoodLevel: number;
|
|
78
|
+
newFoodLevel: number;
|
|
94
79
|
}
|
|
95
|
-
|
|
96
80
|
export interface EntityDamageEvent {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
81
|
+
entity: string;
|
|
82
|
+
damage: number;
|
|
83
|
+
cause: string;
|
|
84
|
+
entityType: string;
|
|
101
85
|
}
|
|
102
|
-
|
|
103
86
|
export interface EntityDeathEvent {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
87
|
+
entity: string;
|
|
88
|
+
entityType: string;
|
|
89
|
+
entityName: string;
|
|
107
90
|
}
|
|
108
|
-
|
|
109
91
|
export interface EntitySpawnEvent {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
entity: string;
|
|
93
|
+
entityType: string;
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
z: number;
|
|
97
|
+
world: string;
|
|
116
98
|
}
|
|
117
|
-
|
|
118
99
|
export interface ProjectileLaunchEvent {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
100
|
+
entity: string;
|
|
101
|
+
projectileType: string;
|
|
102
|
+
shooter?: string;
|
|
122
103
|
}
|
|
123
|
-
|
|
124
104
|
export interface BlockBreakEvent {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
105
|
+
player: Player;
|
|
106
|
+
block: string;
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
z: number;
|
|
130
110
|
}
|
|
131
|
-
|
|
132
111
|
export interface BlockPlaceEvent {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
112
|
+
player: Player;
|
|
113
|
+
block: string;
|
|
114
|
+
blockAgainst: string;
|
|
115
|
+
x: number;
|
|
116
|
+
y: number;
|
|
117
|
+
z: number;
|
|
139
118
|
}
|
|
140
|
-
|
|
141
119
|
export interface InventoryOpenEvent {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
120
|
+
player: Player;
|
|
121
|
+
inventoryType: string;
|
|
122
|
+
title: string;
|
|
145
123
|
}
|
|
146
|
-
|
|
147
124
|
export interface InventoryCloseEvent {
|
|
148
|
-
|
|
149
|
-
|
|
125
|
+
player: Player;
|
|
126
|
+
inventoryType: string;
|
|
150
127
|
}
|
|
151
|
-
|
|
152
128
|
export interface ServerPingEvent {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
129
|
+
address: string;
|
|
130
|
+
numPlayers: number;
|
|
131
|
+
maxPlayers: number;
|
|
132
|
+
motd: string;
|
|
157
133
|
}
|
|
158
|
-
|
|
159
134
|
export interface PlayerTeleportEvent {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
135
|
+
player: Player;
|
|
136
|
+
from: Location;
|
|
137
|
+
to: Location;
|
|
138
|
+
cause: string;
|
|
164
139
|
}
|
|
165
|
-
|
|
166
140
|
export interface PlayerItemConsumeEvent {
|
|
167
|
-
|
|
168
|
-
|
|
141
|
+
player: Player;
|
|
142
|
+
itemType: string;
|
|
169
143
|
}
|
|
170
|
-
|
|
171
144
|
export interface EntityExplodeEvent {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
145
|
+
entity: string;
|
|
146
|
+
entityType: string;
|
|
147
|
+
x: number;
|
|
148
|
+
y: number;
|
|
149
|
+
z: number;
|
|
150
|
+
blockCount: number;
|
|
178
151
|
}
|
|
179
|
-
|
|
180
152
|
export interface EntityRegainHealthEvent {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
153
|
+
entity: string;
|
|
154
|
+
amount: number;
|
|
155
|
+
reason: string;
|
|
184
156
|
}
|
|
185
|
-
|
|
186
157
|
export interface EntityTargetEvent {
|
|
187
|
-
|
|
188
|
-
|
|
158
|
+
entity: string;
|
|
159
|
+
target: string | null;
|
|
189
160
|
}
|
|
190
|
-
|
|
191
161
|
export interface ProjectileHitEvent {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
162
|
+
entity: string;
|
|
163
|
+
projectileType: string;
|
|
164
|
+
hitEntity: string | null;
|
|
165
|
+
hitBlock: { x: number; y: number; z: number; type: string } | null;
|
|
196
166
|
}
|
|
197
|
-
|
|
198
167
|
export interface BlockFadeEvent {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
168
|
+
block: string;
|
|
169
|
+
x: number;
|
|
170
|
+
y: number;
|
|
171
|
+
z: number;
|
|
203
172
|
}
|
|
204
|
-
|
|
205
173
|
export interface BlockGrowEvent {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
174
|
+
block: string;
|
|
175
|
+
x: number;
|
|
176
|
+
y: number;
|
|
177
|
+
z: number;
|
|
210
178
|
}
|
|
211
|
-
|
|
212
179
|
export interface BlockSpreadEvent {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
180
|
+
block: string;
|
|
181
|
+
x: number;
|
|
182
|
+
y: number;
|
|
183
|
+
z: number;
|
|
217
184
|
}
|
|
218
|
-
|
|
219
185
|
export interface BlockExplodeEvent {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
186
|
+
block: string;
|
|
187
|
+
x: number;
|
|
188
|
+
y: number;
|
|
189
|
+
z: number;
|
|
224
190
|
}
|
|
225
|
-
|
|
226
191
|
export interface ServerCommandEvent {
|
|
227
|
-
|
|
228
|
-
|
|
192
|
+
command: string;
|
|
193
|
+
sender: string;
|
|
229
194
|
}
|
|
230
195
|
|
|
231
|
-
// ── Event Type Mapping ─────────────────────────────────────────────
|
|
232
|
-
|
|
233
196
|
type EventMap = {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
197
|
+
playerJoin: PlayerJoinEvent;
|
|
198
|
+
playerQuit: PlayerQuitEvent;
|
|
199
|
+
playerChat: PlayerChatEvent;
|
|
200
|
+
playerMove: PlayerMoveEvent;
|
|
201
|
+
playerInteract: PlayerInteractEvent;
|
|
202
|
+
playerCommand: PlayerCommandEvent;
|
|
203
|
+
playerDeath: PlayerDeathEvent;
|
|
204
|
+
playerRespawn: PlayerRespawnEvent;
|
|
205
|
+
playerDropItem: PlayerDropItemEvent;
|
|
206
|
+
playerPickupItem: PlayerPickupItemEvent;
|
|
207
|
+
playerBucketFill: PlayerBucketFillEvent;
|
|
208
|
+
playerBucketEmpty: PlayerBucketEmptyEvent;
|
|
209
|
+
playerExpChange: PlayerExpChangeEvent;
|
|
210
|
+
playerLevelChange: PlayerLevelChangeEvent;
|
|
211
|
+
playerGameModeChange: PlayerGameModeChangeEvent;
|
|
212
|
+
foodLevelChange: FoodLevelChangeEvent;
|
|
213
|
+
entityDamage: EntityDamageEvent;
|
|
214
|
+
entityDeath: EntityDeathEvent;
|
|
215
|
+
entitySpawn: EntitySpawnEvent;
|
|
216
|
+
entityExplode: EntityExplodeEvent;
|
|
217
|
+
entityRegainHealth: EntityRegainHealthEvent;
|
|
218
|
+
entityTarget: EntityTargetEvent;
|
|
219
|
+
projectileLaunch: ProjectileLaunchEvent;
|
|
220
|
+
projectileHit: ProjectileHitEvent;
|
|
221
|
+
blockBreak: BlockBreakEvent;
|
|
222
|
+
blockPlace: BlockPlaceEvent;
|
|
223
|
+
blockFade: BlockFadeEvent;
|
|
224
|
+
blockGrow: BlockGrowEvent;
|
|
225
|
+
blockSpread: BlockSpreadEvent;
|
|
226
|
+
blockExplode: BlockExplodeEvent;
|
|
227
|
+
inventoryOpen: InventoryOpenEvent;
|
|
228
|
+
inventoryClose: InventoryCloseEvent;
|
|
229
|
+
serverPing: ServerPingEvent;
|
|
230
|
+
serverCommand: ServerCommandEvent;
|
|
231
|
+
playerTeleport: PlayerTeleportEvent;
|
|
232
|
+
playerItemConsume: PlayerItemConsumeEvent;
|
|
270
233
|
};
|
|
271
234
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
function
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
235
|
+
type RawEvent = Record<string, unknown> & { _cancellable?: boolean };
|
|
236
|
+
|
|
237
|
+
function loc(raw: Record<string, unknown> | null): Location | null {
|
|
238
|
+
if (!raw) return null;
|
|
239
|
+
return new Location(
|
|
240
|
+
raw.x as number, raw.y as number, raw.z as number,
|
|
241
|
+
(raw.yaw as number) ?? 0, (raw.pitch as number) ?? 0, raw.world as string,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function adaptEvent<K extends keyof EventMap>(type: K, data: RawEvent): EventMap[K] {
|
|
246
|
+
const wrap: Record<string, unknown> = {};
|
|
247
|
+
for (const key of Object.keys(data)) {
|
|
248
|
+
if (key.startsWith('_')) continue;
|
|
249
|
+
wrap[key] = data[key];
|
|
250
|
+
}
|
|
251
|
+
const hasPlayer = [
|
|
252
|
+
'playerJoin', 'playerQuit', 'playerChat', 'playerMove',
|
|
253
|
+
'playerInteract', 'playerCommand', 'playerDeath', 'playerRespawn',
|
|
254
|
+
'playerTeleport', 'playerItemConsume',
|
|
255
|
+
'playerDropItem', 'playerPickupItem', 'playerBucketFill',
|
|
256
|
+
'playerBucketEmpty', 'playerExpChange', 'playerLevelChange',
|
|
257
|
+
'playerGameModeChange', 'foodLevelChange', 'blockBreak',
|
|
258
|
+
'blockPlace', 'inventoryOpen', 'inventoryClose',
|
|
259
|
+
] as K[];
|
|
260
|
+
if (hasPlayer.includes(type) && data.player) {
|
|
261
|
+
wrap.player = Player.get(data.player as string);
|
|
262
|
+
}
|
|
263
|
+
if (data.from) wrap.from = loc(data.from as Record<string, unknown>);
|
|
264
|
+
if (data.to) wrap.to = loc(data.to as Record<string, unknown>);
|
|
265
|
+
if (data.respawnLocation) wrap.respawnLocation = loc(data.respawnLocation as Record<string, unknown>);
|
|
266
|
+
return wrap as unknown as EventMap[K];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ── Event Subscription ─────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
type EventHandler<K extends keyof EventMap> = (e: EventMap[K]) => void;
|
|
272
|
+
type ManualHandler<K extends keyof EventMap> = (
|
|
273
|
+
e: EventMap[K],
|
|
274
|
+
complete: (result?: Record<string, unknown>) => void,
|
|
275
|
+
) => void;
|
|
276
|
+
|
|
277
|
+
export function eventOn<K extends keyof EventMap>(
|
|
278
|
+
eventType: K,
|
|
279
|
+
handler: EventHandler<K>,
|
|
280
|
+
): () => void;
|
|
281
|
+
export function eventOn<K extends keyof EventMap>(
|
|
282
|
+
eventType: K,
|
|
283
|
+
options: { manualRelease: true },
|
|
284
|
+
handler: ManualHandler<K>,
|
|
285
|
+
): () => void;
|
|
286
|
+
export function eventOn<K extends keyof EventMap>(
|
|
287
|
+
eventType: K,
|
|
288
|
+
handlerOrOptions: EventHandler<K> | { manualRelease?: boolean },
|
|
289
|
+
handlerOrUndef?: ManualHandler<K>,
|
|
290
|
+
): () => void {
|
|
291
|
+
const manualRelease = typeof handlerOrOptions === 'object' && handlerOrOptions?.manualRelease === true;
|
|
292
|
+
const handler = manualRelease ? handlerOrUndef! : (handlerOrOptions as EventHandler<K>);
|
|
293
|
+
const pluginName = __plugin?.name || 'unknown';
|
|
294
|
+
|
|
295
|
+
const cbId = _registerCallback((data: RawEvent) => {
|
|
296
|
+
const wrapped = adaptEvent(eventType, data);
|
|
297
|
+
const cancellable = data?._cancellable;
|
|
298
|
+
const localMods: { cancelled?: boolean } = {};
|
|
278
299
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
300
|
+
if (cancellable) {
|
|
301
|
+
Object.defineProperty(wrapped, 'cancelled', {
|
|
302
|
+
get: () => localMods.cancelled || false,
|
|
303
|
+
set: (v: boolean) => { localMods.cancelled = v; },
|
|
304
|
+
enumerable: true,
|
|
305
|
+
});
|
|
285
306
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
307
|
+
|
|
308
|
+
if (manualRelease) {
|
|
309
|
+
const complete = (result?: Record<string, unknown>) => {
|
|
310
|
+
$send('task', {
|
|
311
|
+
type: 'event.complete',
|
|
312
|
+
params: { callbackId: cbId, mods: result },
|
|
313
|
+
cb: '',
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
(handler as ManualHandler<typeof eventType>)(wrapped, complete);
|
|
317
|
+
return;
|
|
295
318
|
}
|
|
296
|
-
if (data.from) wrap.from = _loc(data.from);
|
|
297
|
-
if (data.to) wrap.to = _loc(data.to);
|
|
298
|
-
if (data.respawnLocation) wrap.respawnLocation = _loc(data.respawnLocation);
|
|
299
|
-
return wrap;
|
|
300
|
-
}
|
|
301
319
|
|
|
302
|
-
|
|
320
|
+
const result = (handler as EventHandler<typeof eventType>)(wrapped);
|
|
321
|
+
const mods = { cancelled: localMods.cancelled || false };
|
|
322
|
+
$send('task', { type: 'event.complete', params: { callbackId: cbId, mods }, cb: '' });
|
|
323
|
+
}, { persistent: true });
|
|
303
324
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
325
|
+
if (!__yeowEventHandlers) (globalThis as any).__yeowEventHandlers = {};
|
|
326
|
+
const handlers = __yeowEventHandlers!;
|
|
327
|
+
if (!handlers[eventType]) handlers[eventType] = [];
|
|
328
|
+
handlers[eventType].push({ cbId, handler, manualRelease });
|
|
307
329
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
(globalThis as any).__yeowEventHandlers[eventType] = [];
|
|
311
|
-
call('event.subscribe', {
|
|
312
|
-
pluginName: (globalThis as any).__plugin?.name || 'unknown',
|
|
313
|
-
eventType,
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
(globalThis as any).__yeowEventHandlers[eventType].push(wrapper);
|
|
317
|
-
return () => eventOff(eventType, handler);
|
|
330
|
+
call('event.subscribe', { pluginName, eventType, callbackId: String(cbId) });
|
|
331
|
+
return () => eventOff(eventType, handler);
|
|
318
332
|
}
|
|
319
333
|
|
|
320
334
|
export function eventOff(eventType: string, handler: Function): void {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
335
|
+
if (!__yeowEventHandlers) return;
|
|
336
|
+
const entries = __yeowEventHandlers[eventType];
|
|
337
|
+
if (!entries) return;
|
|
338
|
+
const idx = entries.findIndex((e) => e.handler === handler);
|
|
339
|
+
if (idx !== -1) {
|
|
340
|
+
const removed = entries.splice(idx, 1)[0];
|
|
341
|
+
if (removed.cbId) _unregisterCallback(removed.cbId);
|
|
342
|
+
}
|
|
343
|
+
if (entries.length === 0) {
|
|
344
|
+
delete __yeowEventHandlers![eventType];
|
|
345
|
+
call('event.unsubscribe', {
|
|
346
|
+
pluginName: __plugin?.name || 'unknown',
|
|
347
|
+
eventType,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
332
350
|
}
|
|
333
|
-
|
|
334
|
-
// ── _onEvent dispatcher (called from init.js) ──────────────────────
|
|
335
|
-
|
|
336
|
-
(globalThis as any)._onEvent = (eventType: string, data: any): any => {
|
|
337
|
-
const handlers = (globalThis as any).__yeowEventHandlers?.[eventType];
|
|
338
|
-
if (!handlers?.length) return {};
|
|
339
|
-
|
|
340
|
-
const cancellable = data?._cancellable;
|
|
341
|
-
const mods: Record<string, any> = {};
|
|
342
|
-
|
|
343
|
-
const wrapped = adaptEvent(eventType, data);
|
|
344
|
-
|
|
345
|
-
const localMods: Record<string, any> = {};
|
|
346
|
-
if (cancellable) {
|
|
347
|
-
Object.defineProperty(wrapped, 'cancelled', {
|
|
348
|
-
get: () => localMods.cancelled || false,
|
|
349
|
-
set: (v: boolean) => { localMods.cancelled = v; },
|
|
350
|
-
enumerable: true,
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
for (const handler of handlers) {
|
|
355
|
-
try {
|
|
356
|
-
handler(wrapped);
|
|
357
|
-
} catch (e: any) {
|
|
358
|
-
const errInfo: any = {
|
|
359
|
-
message: e?.message || String(e),
|
|
360
|
-
stack: e?.stack || '',
|
|
361
|
-
fileName: e?.fileName || 'main.js',
|
|
362
|
-
lineNumber: e?.lineNumber || 0,
|
|
363
|
-
columnNumber: e?.columnNumber || 0,
|
|
364
|
-
};
|
|
365
|
-
if (!errInfo.fileName || errInfo.fileName === 'main.js' || !errInfo.lineNumber) {
|
|
366
|
-
const m = e?.stack?.match(/at\s+(?:\S+\s+)?\(?([^\s(]+):(\d+):(\d+)\)?/);
|
|
367
|
-
if (m) { errInfo.fileName = m[1]; errInfo.lineNumber = parseInt(m[2]); errInfo.columnNumber = parseInt(m[3]); }
|
|
368
|
-
}
|
|
369
|
-
(globalThis as any).$send('reportError', errInfo);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
if (cancellable && localMods.cancelled) mods.cancelled = true;
|
|
373
|
-
return mods;
|
|
374
|
-
};
|