yeow-api 0.2.8 → 0.2.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeow-api",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Yeow API �?TypeScript OOP wrappers over the task protocol",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/assets.ts ADDED
@@ -0,0 +1,42 @@
1
+ function _sendAssets(payload) {
2
+ const raw = $send('assets', JSON.stringify(payload));
3
+ if (!raw) return undefined;
4
+ const r = JSON.parse(raw);
5
+ if (r.err) throw new Error(r.err);
6
+ return r;
7
+ }
8
+
9
+ export function read(path) {
10
+ return new Promise((resolve, reject) => {
11
+ try { const r = _sendAssets({ t: 'read', p: { path } }); resolve(r.data); } catch(e) { reject(e); }
12
+ });
13
+ }
14
+ export function readSync(path) {
15
+ return _sendAssets({ t: 'read', p: { path } }).data;
16
+ }
17
+
18
+ export function readBase64(path) {
19
+ return new Promise((resolve, reject) => {
20
+ try { const r = _sendAssets({ t: 'readBase64', p: { path } }); resolve(r.data); } catch(e) { reject(e); }
21
+ });
22
+ }
23
+ export function readBase64Sync(path) {
24
+ return _sendAssets({ t: 'readBase64', p: { path } }).data;
25
+ }
26
+
27
+ export function extract(path, dest) {
28
+ return new Promise((resolve, reject) => {
29
+ try {
30
+ const p = { path };
31
+ if (dest) p.dest = dest;
32
+ const r = _sendAssets({ t: 'extract', p }); resolve(r.path);
33
+ } catch(e) { reject(e); }
34
+ });
35
+ }
36
+ export function extractSync(path, dest) {
37
+ const p = { path };
38
+ if (dest) p.dest = dest;
39
+ return _sendAssets({ t: 'extract', p }).path;
40
+ }
41
+
42
+ export const assets = { read, readSync, readBase64, readBase64Sync, extract, extractSync };
package/src/event.ts CHANGED
@@ -1,11 +1,226 @@
1
1
  import { call } from './task.js';
2
+ import { Player } from './player.js';
3
+ import { Location } from './location.js';
4
+
5
+ // ── Event Typed Interfaces ─────────────────────────────────────────
6
+
7
+ export interface PlayerJoinEvent {
8
+ player: Player;
9
+ joinMessage: string;
10
+ }
11
+
12
+ export interface PlayerQuitEvent {
13
+ player: Player;
14
+ quitMessage: string;
15
+ }
16
+
17
+ export interface PlayerChatEvent {
18
+ player: Player;
19
+ message: string;
20
+ format: string;
21
+ }
22
+
23
+ export interface PlayerMoveEvent {
24
+ player: Player;
25
+ from: Location;
26
+ to: Location;
27
+ }
28
+
29
+ export interface PlayerInteractEvent {
30
+ player: Player;
31
+ action: string;
32
+ material: string | null;
33
+ block: { x: number; y: number; z: number; type: string } | null;
34
+ }
35
+
36
+ export interface PlayerCommandEvent {
37
+ player: Player;
38
+ message: string;
39
+ }
40
+
41
+ export interface PlayerDeathEvent {
42
+ player: Player;
43
+ deathMessage: string;
44
+ deathType: string;
45
+ }
46
+
47
+ export interface PlayerRespawnEvent {
48
+ player: Player;
49
+ respawnLocation: Location;
50
+ }
51
+
52
+ export interface PlayerDropItemEvent {
53
+ player: Player;
54
+ itemType: string;
55
+ amount: number;
56
+ }
57
+
58
+ export interface PlayerPickupItemEvent {
59
+ player: Player;
60
+ itemType: string;
61
+ amount: number;
62
+ }
63
+
64
+ export interface PlayerBucketFillEvent {
65
+ player: Player;
66
+ bucket: string;
67
+ }
68
+
69
+ export interface PlayerBucketEmptyEvent {
70
+ player: Player;
71
+ bucket: string;
72
+ }
73
+
74
+ export interface PlayerExpChangeEvent {
75
+ player: Player;
76
+ amount: number;
77
+ }
78
+
79
+ export interface PlayerLevelChangeEvent {
80
+ player: Player;
81
+ oldLevel: number;
82
+ newLevel: number;
83
+ }
84
+
85
+ export interface PlayerGameModeChangeEvent {
86
+ player: Player;
87
+ newGameMode: string;
88
+ }
89
+
90
+ export interface FoodLevelChangeEvent {
91
+ player: Player;
92
+ oldFoodLevel: number;
93
+ newFoodLevel: number;
94
+ }
95
+
96
+ export interface EntityDamageEvent {
97
+ entity: string;
98
+ damage: number;
99
+ cause: string;
100
+ entityType: string;
101
+ }
102
+
103
+ export interface EntityDeathEvent {
104
+ entity: string;
105
+ entityType: string;
106
+ entityName: string;
107
+ }
108
+
109
+ export interface EntitySpawnEvent {
110
+ entity: string;
111
+ entityType: string;
112
+ x: number;
113
+ y: number;
114
+ z: number;
115
+ world: string;
116
+ }
117
+
118
+ export interface ProjectileLaunchEvent {
119
+ entity: string;
120
+ projectileType: string;
121
+ shooter?: string;
122
+ }
123
+
124
+ export interface BlockBreakEvent {
125
+ player: Player;
126
+ block: string;
127
+ x: number;
128
+ y: number;
129
+ z: number;
130
+ }
131
+
132
+ export interface BlockPlaceEvent {
133
+ player: Player;
134
+ block: string;
135
+ blockAgainst: string;
136
+ x: number;
137
+ y: number;
138
+ z: number;
139
+ }
140
+
141
+ export interface InventoryOpenEvent {
142
+ player: Player;
143
+ inventoryType: string;
144
+ title: string;
145
+ }
146
+
147
+ export interface InventoryCloseEvent {
148
+ player: Player;
149
+ inventoryType: string;
150
+ }
151
+
152
+ export interface ServerPingEvent {
153
+ address: string;
154
+ numPlayers: number;
155
+ maxPlayers: number;
156
+ motd: string;
157
+ }
158
+
159
+ // ── Event Type Mapping ─────────────────────────────────────────────
160
+
161
+ type EventMap = {
162
+ playerJoin: PlayerJoinEvent;
163
+ playerQuit: PlayerQuitEvent;
164
+ playerChat: PlayerChatEvent;
165
+ playerMove: PlayerMoveEvent;
166
+ playerInteract: PlayerInteractEvent;
167
+ playerCommand: PlayerCommandEvent;
168
+ playerDeath: PlayerDeathEvent;
169
+ playerRespawn: PlayerRespawnEvent;
170
+ playerDropItem: PlayerDropItemEvent;
171
+ playerPickupItem: PlayerPickupItemEvent;
172
+ playerBucketFill: PlayerBucketFillEvent;
173
+ playerBucketEmpty: PlayerBucketEmptyEvent;
174
+ playerExpChange: PlayerExpChangeEvent;
175
+ playerLevelChange: PlayerLevelChangeEvent;
176
+ playerGameModeChange: PlayerGameModeChangeEvent;
177
+ foodLevelChange: FoodLevelChangeEvent;
178
+ entityDamage: EntityDamageEvent;
179
+ entityDeath: EntityDeathEvent;
180
+ entitySpawn: EntitySpawnEvent;
181
+ projectileLaunch: ProjectileLaunchEvent;
182
+ blockBreak: BlockBreakEvent;
183
+ blockPlace: BlockPlaceEvent;
184
+ inventoryOpen: InventoryOpenEvent;
185
+ inventoryClose: InventoryCloseEvent;
186
+ serverPing: ServerPingEvent;
187
+ };
188
+
189
+ // ── Event Data Adapter ──────────────────────────────────────────────
190
+
191
+ function _loc(raw: any): Location | null {
192
+ if (!raw) return null;
193
+ return new Location(raw.x, raw.y, raw.z, raw.yaw ?? 0, raw.pitch ?? 0, raw.world);
194
+ }
195
+
196
+ function adaptEvent(type: string, data: any): any {
197
+ if (!data) return data;
198
+ const wrap: any = {};
199
+ for (const key of Object.keys(data)) {
200
+ if (key.startsWith('_')) continue;
201
+ wrap[key] = data[key];
202
+ }
203
+ switch (type) {
204
+ case 'playerJoin': case 'playerQuit': case 'playerChat': case 'playerMove':
205
+ case 'playerInteract': case 'playerCommand': case 'playerDeath': case 'playerRespawn':
206
+ case 'playerDropItem': case 'playerPickupItem': case 'playerBucketFill': case 'playerBucketEmpty':
207
+ case 'playerExpChange': case 'playerLevelChange': case 'playerGameModeChange': case 'foodLevelChange':
208
+ case 'blockBreak': case 'blockPlace': case 'inventoryOpen': case 'inventoryClose':
209
+ if (data.player) wrap.player = Player.get(data.player);
210
+ break;
211
+ }
212
+ if (data.from) wrap.from = _loc(data.from);
213
+ if (data.to) wrap.to = _loc(data.to);
214
+ if (data.respawnLocation) wrap.respawnLocation = _loc(data.respawnLocation);
215
+ return wrap;
216
+ }
217
+
218
+ // ── EventOn/EventOff ───────────────────────────────────────────────
219
+
220
+ export function eventOn<K extends keyof EventMap>(eventType: K, handler: (e: EventMap[K]) => void): () => void {
221
+ const wrapper = (data: any) => handler(adaptEvent(eventType, data) as EventMap[K]);
222
+ (wrapper as any)._raw = handler;
2
223
 
3
- export function eventOn(eventType: string, handler: (e: any) => void): () => void {
4
- // eventOn registers a handler on the JS side.
5
- // The _onEvent function in init.js dispatches SYNC_CALLBACK messages to handlers.
6
- // For now, event handlers are set up via a global registry.
7
- // This is a simplified version — full sync callback event system requires
8
- // the PluginThread to call _onEvent which processes handlers.
9
224
  if (!(globalThis as any).__yeowEventHandlers) (globalThis as any).__yeowEventHandlers = {};
10
225
  if (!(globalThis as any).__yeowEventHandlers[eventType]) {
11
226
  (globalThis as any).__yeowEventHandlers[eventType] = [];
@@ -14,14 +229,14 @@ export function eventOn(eventType: string, handler: (e: any) => void): () => voi
14
229
  eventType,
15
230
  });
16
231
  }
17
- (globalThis as any).__yeowEventHandlers[eventType].push(handler);
232
+ (globalThis as any).__yeowEventHandlers[eventType].push(wrapper);
18
233
  return () => eventOff(eventType, handler);
19
234
  }
20
235
 
21
- export function eventOff(eventType: string, handler: (e: any) => void): void {
236
+ export function eventOff(eventType: string, handler: Function): void {
22
237
  const handlers = (globalThis as any).__yeowEventHandlers?.[eventType];
23
238
  if (!handlers) return;
24
- const idx = handlers.indexOf(handler);
239
+ const idx = handlers.findIndex((h: any) => h._raw === handler || h === handler);
25
240
  if (idx !== -1) handlers.splice(idx, 1);
26
241
  if (handlers.length === 0) {
27
242
  delete (globalThis as any).__yeowEventHandlers[eventType];
@@ -32,31 +247,31 @@ export function eventOff(eventType: string, handler: (e: any) => void): void {
32
247
  }
33
248
  }
34
249
 
35
- // Install _onEvent handler called by init.js for SYNC_CALLBACK events
36
- (globalThis as any)._onEvent = (eventType: string, snapshot: any): any => {
250
+ // ── _onEvent dispatcher (called from init.js) ──────────────────────
251
+
252
+ (globalThis as any)._onEvent = (eventType: string, data: any): any => {
37
253
  const handlers = (globalThis as any).__yeowEventHandlers?.[eventType];
38
254
  if (!handlers?.length) return {};
39
255
 
40
- const cancellable = snapshot?._cancellable;
256
+ const cancellable = data?._cancellable;
41
257
  const mods: Record<string, any> = {};
42
258
 
259
+ const wrapped = adaptEvent(eventType, data);
260
+
261
+ const localMods: Record<string, any> = {};
262
+ if (cancellable) {
263
+ Object.defineProperty(wrapped, 'cancelled', {
264
+ get: () => localMods.cancelled || false,
265
+ set: (v: boolean) => { localMods.cancelled = v; },
266
+ enumerable: true,
267
+ });
268
+ }
269
+
43
270
  for (const handler of handlers) {
44
271
  try {
45
- const proxy: any = {};
46
- for (const key of Object.keys(snapshot || {})) {
47
- if (!key.startsWith('_')) proxy[key] = snapshot[key];
48
- }
49
- const localMods: Record<string, any> = {};
50
- if (cancellable) {
51
- Object.defineProperty(proxy, 'cancelled', {
52
- get: () => localMods.cancelled || false,
53
- set: (v: boolean) => { localMods.cancelled = v; },
54
- enumerable: true,
55
- });
56
- }
57
- handler(proxy);
58
- if (cancellable && localMods.cancelled) mods.cancelled = true;
272
+ handler(wrapped);
59
273
  } catch (e: any) { console.error('event:', e?.message || e); }
60
274
  }
275
+ if (cancellable && localMods.cancelled) mods.cancelled = true;
61
276
  return mods;
62
277
  };
package/src/fs.ts CHANGED
@@ -11,21 +11,37 @@ export function readFile(path) {
11
11
  try { const r = _sendFs({ t: 'readFile', p: { path } }); resolve(r.data); } catch(e) { reject(e); }
12
12
  });
13
13
  }
14
-
15
14
  export function readFileSync(path) {
16
15
  return _sendFs({ t: 'readFile', p: { path } }).data;
17
16
  }
18
17
 
18
+ export function readFileBase64(path) {
19
+ return new Promise((resolve, reject) => {
20
+ try { const r = _sendFs({ t: 'readBase64', p: { path } }); resolve(r.data); } catch(e) { reject(e); }
21
+ });
22
+ }
23
+ export function readFileBase64Sync(path) {
24
+ return _sendFs({ t: 'readBase64', p: { path } }).data;
25
+ }
26
+
19
27
  export function writeFile(path, data) {
20
28
  return new Promise((resolve, reject) => {
21
29
  try { _sendFs({ t: 'writeFile', p: { path, data } }); resolve(); } catch(e) { reject(e); }
22
30
  });
23
31
  }
24
-
25
32
  export function writeFileSync(path, data) {
26
33
  _sendFs({ t: 'writeFile', p: { path, data } });
27
34
  }
28
35
 
36
+ export function writeFileBase64(path, data) {
37
+ return new Promise((resolve, reject) => {
38
+ try { _sendFs({ t: 'writeBase64', p: { path, data } }); resolve(); } catch(e) { reject(e); }
39
+ });
40
+ }
41
+ export function writeFileBase64Sync(path, data) {
42
+ _sendFs({ t: 'writeBase64', p: { path, data } });
43
+ }
44
+
29
45
  export function existsSync(path) {
30
46
  const r = _sendFs({ t: 'exists', p: { path } });
31
47
  return r === true || String(r) === 'true';
@@ -36,17 +52,19 @@ export function deleteFile(path) {
36
52
  try { const r = _sendFs({ t: 'delete', p: { path } }); resolve(r === true || String(r) === 'true'); } catch(e) { reject(e); }
37
53
  });
38
54
  }
39
-
40
55
  export function mkdir(path) {
41
56
  return new Promise((resolve, reject) => {
42
57
  try { _sendFs({ t: 'mkdir', p: { path } }); resolve(); } catch(e) { reject(e); }
43
58
  });
44
59
  }
45
-
46
60
  export function list(path) {
47
61
  return new Promise((resolve, reject) => {
48
62
  try { const r = _sendFs({ t: 'list', p: { path } }); resolve(r); } catch(e) { reject(e); }
49
63
  });
50
64
  }
51
65
 
52
- export const fs = { readFile, readFileSync, writeFile, writeFileSync, existsSync, deleteFile, mkdir, list };
66
+ export const fs = {
67
+ readFile, readFileSync, readFileBase64, readFileBase64Sync,
68
+ writeFile, writeFileSync, writeFileBase64, writeFileBase64Sync,
69
+ existsSync, deleteFile, mkdir, list,
70
+ };
package/src/index.ts CHANGED
@@ -4,6 +4,18 @@ export { Player } from './player.js';
4
4
  export { registerCommand } from './command.js';
5
5
  export type { CommandOptions, CommandPayload, CommandSender } from './command.js';
6
6
  export { eventOn, eventOff } from './event.js';
7
+ export type {
8
+ PlayerJoinEvent, PlayerQuitEvent, PlayerChatEvent, PlayerMoveEvent,
9
+ PlayerInteractEvent, PlayerCommandEvent, PlayerDeathEvent, PlayerRespawnEvent,
10
+ PlayerDropItemEvent, PlayerPickupItemEvent, PlayerBucketFillEvent, PlayerBucketEmptyEvent,
11
+ PlayerExpChangeEvent, PlayerLevelChangeEvent, PlayerGameModeChangeEvent, FoodLevelChangeEvent,
12
+ EntityDamageEvent, EntityDeathEvent, EntitySpawnEvent, ProjectileLaunchEvent,
13
+ BlockBreakEvent, BlockPlaceEvent,
14
+ InventoryOpenEvent, InventoryCloseEvent,
15
+ ServerPingEvent,
16
+ } from './event.js';
17
+ export { onInit, onLoad } from './lifecycle.js';
7
18
  export { broadcast, getMotd, getVersion } from './server.js';
8
- export { fs, readFile, readFileSync, writeFile, writeFileSync, existsSync, deleteFile, mkdir, list } from './fs.js';
19
+ export { fs, readFile, readFileSync, readFileBase64, readFileBase64Sync, writeFile, writeFileSync, writeFileBase64, writeFileBase64Sync, existsSync, deleteFile, mkdir, list } from './fs.js';
20
+ export { assets, read as assetsRead, readSync as assetsReadSync, readBase64 as assetsReadBase64, readBase64Sync as assetsReadBase64Sync, extract as assetsExtract, extractSync as assetsExtractSync } from './assets.js';
9
21
  export { listen, respond, close, request, requestSync } from './http.js';
@@ -0,0 +1,8 @@
1
+ const _initCbs: (() => void)[] = [];
2
+ const _loadCbs: (() => void)[] = [];
3
+
4
+ export function onInit(cb: () => void): void { _initCbs.push(cb); }
5
+ export function onLoad(cb: () => void): void { _loadCbs.push(cb); }
6
+
7
+ (globalThis as any).__yeowInitCbs = _initCbs;
8
+ (globalThis as any).__yeowLoadCbs = _loadCbs;
package/src/task.ts CHANGED
@@ -1,15 +1,19 @@
1
- export function post(type: string, params: Record<string, unknown> = {}): Promise<unknown> {
1
+ export function post(type: string, params: Record<string, unknown> = {}, priority?: string): Promise<unknown> {
2
2
  return new Promise((resolve, reject) => {
3
3
  const cbId = (globalThis as any)._registerCallback((result: any) => {
4
4
  if (result?.err) reject(new Error(result.err));
5
5
  else resolve(result);
6
6
  });
7
- (globalThis as any).$send('game', JSON.stringify({ t: type, p: params, cb: cbId }));
7
+ const pld: Record<string, unknown> = { t: type, p: params, cb: cbId };
8
+ if (priority) pld._priority = priority;
9
+ (globalThis as any).$send('game', JSON.stringify(pld));
8
10
  });
9
11
  }
10
12
 
11
- export function call(type: string, params: Record<string, unknown> = {}): unknown {
12
- const raw = (globalThis as any).$send('game', JSON.stringify({ t: type, p: params }));
13
+ export function call(type: string, params: Record<string, unknown> = {}, priority?: string): unknown {
14
+ const pld: Record<string, unknown> = { t: type, p: params };
15
+ if (priority) pld._priority = priority;
16
+ const raw = (globalThis as any).$send('game', JSON.stringify(pld));
13
17
  if (!raw) return undefined;
14
18
  const r = JSON.parse(raw as string);
15
19
  if (r.err) throw new Error(r.err);