@defold-typescript/types 0.8.3 → 0.8.4

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.
@@ -39,6 +39,7 @@ import "../../src/engine-globals";
39
39
  import "../../src/go-overloads";
40
40
  import "../../src/message-guard";
41
41
  import "../../src/msg-overloads";
42
+ import "../../src/window-event-guard";
42
43
  import "../builtin-messages";
43
44
  import "../gui";
44
45
 
@@ -39,6 +39,7 @@ import "../../src/engine-globals";
39
39
  import "../../src/go-overloads";
40
40
  import "../../src/message-guard";
41
41
  import "../../src/msg-overloads";
42
+ import "../../src/window-event-guard";
42
43
  import "../builtin-messages";
43
44
  import "../render";
44
45
 
@@ -39,6 +39,7 @@ import "../../src/engine-globals";
39
39
  import "../../src/go-overloads";
40
40
  import "../../src/message-guard";
41
41
  import "../../src/msg-overloads";
42
+ import "../../src/window-event-guard";
42
43
  import "../builtin-messages";
43
44
 
44
45
  export { defineScript } from "../../src/lifecycle";
@@ -140,7 +140,7 @@ declare global {
140
140
  * });
141
141
  * ```
142
142
  */
143
- function set_listener(callback?: (self: unknown, event: unknown, data: unknown) => void): void;
143
+ function set_listener(callback?: (self: unknown, event: typeof WINDOW_EVENT_FOCUS_LOST | typeof WINDOW_EVENT_FOCUS_GAINED | typeof WINDOW_EVENT_RESIZED | typeof WINDOW_EVENT_ICONFIED | typeof WINDOW_EVENT_DEICONIFIED, data: Record<string | number, unknown>) => void): void;
144
144
  /**
145
145
  * Set the locking state for current mouse cursor on a PC platform.
146
146
  * This function locks or unlocks the mouse cursor to the center point of the window. While the cursor is locked,
package/index.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  import "./generated/builtin-messages";
4
4
  import "./src/msg-overloads";
5
5
  import "./src/message-guard";
6
+ import "./src/window-event-guard";
6
7
  import "./src/message-dispatch";
7
8
  import "./src/engine-globals";
8
9
  import "./generated/b2d";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defold-typescript/types",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "TypeScript types for the Defold engine's Lua APIs.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/scripts/regen.ts CHANGED
@@ -234,6 +234,7 @@ const UNIVERSAL_EXTRA_IMPORTS: readonly string[] = [
234
234
  "../../src/engine-globals",
235
235
  "../../src/msg-overloads",
236
236
  "../../src/message-guard",
237
+ "../../src/window-event-guard",
237
238
  "../../src/go-overloads",
238
239
  ];
239
240
 
package/src/emit-dts.ts CHANGED
@@ -499,6 +499,21 @@ export const TABLE_SLOT_CURATIONS: ReadonlyMap<string, TableSlotCuration> = new
499
499
  ],
500
500
  ]);
501
501
 
502
+ // Slot-keyed (`element:param:name`, mirroring TABLE_SLOT_CURATIONS) replacements
503
+ // for a callback parameter's recovered signature, used where the generic
504
+ // `recoverCallbackSignature` `unknown`-everywhere form leaves real engine type
505
+ // information on the table. The value is the full emitted function type. Honest
506
+ // only: `window.set_listener` discriminates `event` by a known constant union and
507
+ // its `data` is a bare record (only resize carries fields — `isWindowEvent` is the
508
+ // path to typed `data`), mirroring the `msg.post` (send, typed) / `isMessage`
509
+ // (receive, narrow) split.
510
+ export const CALLBACK_SIGNATURE_CURATIONS: ReadonlyMap<string, string> = new Map([
511
+ [
512
+ "window.set_listener:param:callback",
513
+ "(self: unknown, event: typeof WINDOW_EVENT_FOCUS_LOST | typeof WINDOW_EVENT_FOCUS_GAINED | typeof WINDOW_EVENT_RESIZED | typeof WINDOW_EVENT_ICONFIED | typeof WINDOW_EVENT_DEICONIFIED, data: Record<string | number, unknown>) => void",
514
+ ],
515
+ ]);
516
+
502
517
  // resource.set_atlas's `table` param and resource.get_atlas's `data` return are
503
518
  // flattened `<li><dl>` field lists whose `geometries` header is followed by the
504
519
  // `table`-typed siblings `vertices`/`uvs`/`indices` — the grouping heuristic
@@ -1200,7 +1215,11 @@ function mapSlotUnion(
1200
1215
  }
1201
1216
  }
1202
1217
  } else {
1203
- ts = mapType(token);
1218
+ const curated =
1219
+ slotKind !== undefined && slotName !== undefined
1220
+ ? CALLBACK_SIGNATURE_CURATIONS.get(tableSlotKey(elementName, slotKind, slotName))
1221
+ : undefined;
1222
+ ts = curated ?? mapType(token);
1204
1223
  }
1205
1224
  if (seen.has(ts)) continue;
1206
1225
  seen.add(ts);
@@ -0,0 +1,52 @@
1
+ /** @noSelfInFile */
2
+
3
+ // `window.set_listener` hands the callback `event` and `data` as two *separate*
4
+ // params, and the `WINDOW_EVENT_*` constants are branded numbers — so TS can
5
+ // neither correlate the two params nor use a branded number as a discriminant.
6
+ // This guard re-introduces the discriminant at the use site, narrowing the
7
+ // untyped `data` payload (only `WINDOW_EVENT_RESIZED` carries fields). It mirrors
8
+ // `isMessage` for `on_message`; the transpiler lowers the call to a bare
9
+ // `event == window.WINDOW_EVENT_*` (window-event-guard-lowering.ts), so this
10
+ // package emits no runtime Lua.
11
+ type WindowEventKind =
12
+ | typeof window.WINDOW_EVENT_FOCUS_LOST
13
+ | typeof window.WINDOW_EVENT_FOCUS_GAINED
14
+ | typeof window.WINDOW_EVENT_RESIZED
15
+ | typeof window.WINDOW_EVENT_ICONFIED
16
+ | typeof window.WINDOW_EVENT_DEICONIFIED;
17
+
18
+ type WindowEventData<K extends WindowEventKind> = K extends typeof window.WINDOW_EVENT_RESIZED
19
+ ? { width: number; height: number }
20
+ : undefined;
21
+
22
+ declare global {
23
+ /**
24
+ * Type guard for a `window.set_listener` callback: narrows the untyped `data`
25
+ * payload to its event-specific shape when `event` matches a known
26
+ * `WINDOW_EVENT_*` constant. The engine hands `event` and `data` as separate
27
+ * params and the constants are branded numbers, so TS cannot auto-narrow `data`
28
+ * from an `event === window.WINDOW_EVENT_RESIZED` check — this guard
29
+ * re-introduces the discriminant. Only `WINDOW_EVENT_RESIZED` carries fields
30
+ * (`{ width, height }`); every other event narrows `data` to `undefined`.
31
+ *
32
+ * @param event - the event constant the callback received.
33
+ * @param data - the untyped data payload the callback received.
34
+ * @param expected - the window event constant to test against (e.g. `window.WINDOW_EVENT_RESIZED`).
35
+ * @returns `true` when `event` matches `expected`, narrowing `data` to that event's payload.
36
+ * @example
37
+ * ```ts
38
+ * window.set_listener((self, event, data) => {
39
+ * if (isWindowEvent(event, data, window.WINDOW_EVENT_RESIZED)) {
40
+ * print("resized:", data.width, data.height);
41
+ * }
42
+ * });
43
+ * ```
44
+ */
45
+ function isWindowEvent<K extends WindowEventKind>(
46
+ event: unknown,
47
+ data: unknown,
48
+ expected: K,
49
+ ): data is WindowEventData<K>;
50
+ }
51
+
52
+ export {};