yeow-api 0.2.30 → 0.2.31

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.30",
3
+ "version": "0.2.31",
4
4
  "description": "Yeow API �?TypeScript OOP wrappers over the task protocol",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/command.ts CHANGED
@@ -13,14 +13,19 @@ export interface CommandPayload {
13
13
  readonly label: string;
14
14
  }
15
15
 
16
+ type CompleterFn = (sender: CommandSender, args: string[]) => string[];
17
+ export interface ManualCompleter {
18
+ manualRelease: true;
19
+ handler: (sender: CommandSender, args: string[], release: (result: string[]) => void) => void;
20
+ }
21
+
16
22
  export interface CommandOptions {
17
23
  description?: string;
18
24
  usage?: string;
19
25
  permission?: string;
20
26
  aliases?: string[];
21
27
  executor: (payload: CommandPayload) => void;
22
- /** Optional tab completer. Receives (sender, args) and returns completion suggestions. */
23
- completer?: (sender: CommandSender, args: string[]) => string[];
28
+ completer?: CompleterFn | ManualCompleter;
24
29
  }
25
30
 
26
31
  export function registerCommand(name: string, options: CommandOptions): boolean {
@@ -40,8 +45,30 @@ export function registerCommand(name: string, options: CommandOptions): boolean
40
45
 
41
46
  let compCbId = '';
42
47
  if (completer) {
43
- compCbId = (globalThis as any)._registerCallback((data: any) => {
44
- return completer(data.sender, data.args);
48
+ let manualRelease = false;
49
+ let completerFn: Function;
50
+ if (typeof completer === 'object' && (completer as any).manualRelease) {
51
+ manualRelease = true;
52
+ completerFn = (completer as any).handler;
53
+ } else {
54
+ completerFn = completer as CompleterFn;
55
+ }
56
+
57
+ compCbId = (globalThis as any)._registerCallback((data: any, release: Function) => {
58
+ try {
59
+ if (manualRelease) {
60
+ completerFn(data.sender, data.args, release);
61
+ } else {
62
+ const result = completerFn(data.sender, data.args);
63
+ if (result && typeof result.then === 'function') {
64
+ release([]); // async → release immediate, use ManualCompleter for async
65
+ } else {
66
+ release(result || []);
67
+ }
68
+ }
69
+ } catch (e) {
70
+ release([]);
71
+ }
45
72
  }, { persistent: true });
46
73
  }
47
74
 
package/src/event.ts CHANGED
@@ -301,9 +301,20 @@ function adaptEvent(type: string, data: any): any {
301
301
 
302
302
  // ── EventOn/EventOff ───────────────────────────────────────────────
303
303
 
304
- export function eventOn<K extends keyof EventMap>(eventType: K, handler: (e: EventMap[K]) => void): () => void {
305
- const wrapper = (data: any) => handler(data as EventMap[K]);
304
+ export function eventOn<K extends keyof EventMap>(
305
+ eventType: K,
306
+ handler: ((e: EventMap[K]) => void) | ((e: EventMap[K], release: (result?: any) => void) => void),
307
+ options?: { manualRelease?: boolean }
308
+ ): () => void {
309
+ const wrapper = (data: any, release?: Function) => {
310
+ if (options?.manualRelease) {
311
+ (handler as any)(data as EventMap[K], release);
312
+ } else {
313
+ (handler as any)(data as EventMap[K]);
314
+ }
315
+ };
306
316
  (wrapper as any)._raw = handler;
317
+ (wrapper as any)._manualRelease = !!options?.manualRelease;
307
318
 
308
319
  if (!(globalThis as any).__yeowEventHandlers) (globalThis as any).__yeowEventHandlers = {};
309
320
  if (!(globalThis as any).__yeowEventHandlers[eventType]) {
@@ -333,16 +344,14 @@ export function eventOff(eventType: string, handler: Function): void {
333
344
 
334
345
  // ── _onEvent dispatcher (called from init.js) ──────────────────────
335
346
 
336
- (globalThis as any)._onEvent = (eventType: string, data: any): any => {
347
+ (globalThis as any)._onEvent = (eventType: string, data: any, release: Function): void => {
337
348
  const handlers = (globalThis as any).__yeowEventHandlers?.[eventType];
338
- if (!handlers?.length) return {};
349
+ if (!handlers?.length) { release({}); return; }
339
350
 
340
351
  const cancellable = data?._cancellable;
341
- const mods: Record<string, any> = {};
342
-
343
352
  const wrapped = adaptEvent(eventType, data);
344
-
345
353
  const localMods: Record<string, any> = {};
354
+
346
355
  if (cancellable) {
347
356
  Object.defineProperty(wrapped, 'cancelled', {
348
357
  get: () => localMods.cancelled || false,
@@ -351,9 +360,24 @@ export function eventOff(eventType: string, handler: Function): void {
351
360
  });
352
361
  }
353
362
 
354
- for (const handler of handlers) {
363
+ const finish = () => {
364
+ if (cancellable && localMods.cancelled) release({ cancelled: true });
365
+ else release({});
366
+ };
367
+
368
+ for (const wrapper of handlers) {
355
369
  try {
356
- handler(wrapped);
370
+ if ((wrapper as any)._manualRelease) {
371
+ wrapper(wrapped, release);
372
+ return;
373
+ }
374
+ const result = wrapper(wrapped);
375
+ if (result && typeof result.then === 'function') {
376
+ // Async handler — release immediately with sync mods only.
377
+ // Awaiting async operations in event handlers requires manualRelease: true.
378
+ finish();
379
+ return;
380
+ }
357
381
  } catch (e: any) {
358
382
  const errInfo: any = {
359
383
  message: e?.message || String(e),
@@ -369,6 +393,6 @@ export function eventOff(eventType: string, handler: Function): void {
369
393
  (globalThis as any).$send('reportError', errInfo);
370
394
  }
371
395
  }
372
- if (cancellable && localMods.cancelled) mods.cancelled = true;
373
- return mods;
396
+
397
+ finish();
374
398
  };
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@ export { Entity, LivingEntity } from './entity.js';
6
6
  export { Block } from './block.js';
7
7
  export { Inventory } from './inventory.js';
8
8
  export { registerCommand } from './command.js';
9
- export type { CommandOptions, CommandPayload, CommandSender } from './command.js';
9
+ export type { CommandOptions, CommandPayload, CommandSender, ManualCompleter } from './command.js';
10
10
  export { eventOn, eventOff } from './event.js';
11
11
  export type {
12
12
  PlayerJoinEvent, PlayerQuitEvent, PlayerChatEvent, PlayerMoveEvent,