@driftengine/native-host 4.7.3 → 4.8.0

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/dist/canvas.d.ts CHANGED
@@ -13,12 +13,10 @@
13
13
  * drawn into the window, and copyable, to be read back by the pixel gate.
14
14
  */
15
15
  import { CanvasStyle } from './canvasStyle.ts';
16
- import { type Handlers, HostNode } from './domTree.ts';
17
- import { INPUT_TYPES, type PageDocument } from './page.ts';
16
+ import { type PageDocument } from './page.ts';
18
17
  import { PointerCapture } from './pointerCapture.ts';
19
- export interface NativeCanvas extends Handlers<(typeof INPUT_TYPES)[number]> {
20
- }
21
- export declare class NativeCanvas extends HostNode {
18
+ declare const NativeCanvas_base: abstract new () => import("./domTree.ts").HostNode & import("./domTree.ts").Handlers<"auxclick" | "blur" | "click" | "contextmenu" | "dblclick" | "focus" | "fullscreenchange" | "fullscreenerror" | "gotpointercapture" | "keydown" | "keypress" | "keyup" | "lostpointercapture" | "mousedown" | "mouseenter" | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" | "pointercancel" | "pointerdown" | "pointerenter" | "pointerleave" | "pointermove" | "pointerout" | "pointerover" | "pointerup" | "touchcancel" | "touchend" | "touchmove" | "touchstart" | "wheel">;
19
+ export declare class NativeCanvas extends NativeCanvas_base {
22
20
  /** The drawing buffer, in device pixels, which the engine sets. */
23
21
  width: number;
24
22
  height: number;
@@ -95,3 +93,4 @@ export declare class NativeCanvasContext {
95
93
  getCurrentTexture(): GPUTexture;
96
94
  private dropTexture;
97
95
  }
96
+ export {};
package/dist/canvas.js CHANGED
@@ -13,14 +13,14 @@
13
13
  * drawn into the window, and copyable, to be read back by the pixel gate.
14
14
  */
15
15
  import { CanvasStyle } from './canvasStyle.js';
16
- import { HostNode } from './domTree.js';
16
+ import { withHandlers } from './domTree.js';
17
17
  import { INPUT_TYPES } from './page.js';
18
18
  import { PointerCapture } from './pointerCapture.js';
19
19
  /* Texture usage flags, named here rather than read off a global a host may not have installed. */
20
20
  const COPY_SRC = 0x01;
21
21
  const TEXTURE_BINDING = 0x04;
22
22
  const RENDER_ATTACHMENT = 0x10;
23
- export class NativeCanvas extends HostNode {
23
+ export class NativeCanvas extends withHandlers(INPUT_TYPES) {
24
24
  /** The drawing buffer, in device pixels, which the engine sets. */
25
25
  width;
26
26
  height;
@@ -45,9 +45,6 @@ export class NativeCanvas extends HostNode {
45
45
  * reports −1 and `focus()` does nothing.
46
46
  */
47
47
  focusIndex = null;
48
- static {
49
- HostNode.handles(NativeCanvas.prototype, INPUT_TYPES);
50
- }
51
48
  constructor(width, height, pixelRatio = 1) {
52
49
  super();
53
50
  this.pixelRatio = pixelRatio;
package/dist/domTree.d.ts CHANGED
@@ -32,3 +32,13 @@ export declare class HostNode implements EventTarget {
32
32
  protected static handles(prototype: object, types: readonly string[]): void;
33
33
  private invoke;
34
34
  }
35
+ /**
36
+ * A base class whose instances carry an `on<type>` attribute for each type given.
37
+ *
38
+ * `handles` defines them on this base's prototype as accessors, and the type says so. A class body
39
+ * cannot declare one property per member of a union, and an interface merged into the class to say
40
+ * it is a merge the checker cannot hold to its initialisers. The cast below is the one place the two
41
+ * meet, and it is true by construction: the static block above it has just defined every attribute
42
+ * the type names.
43
+ */
44
+ export declare function withHandlers<Types extends string>(types: readonly Types[]): abstract new () => HostNode & Handlers<Types>;
package/dist/domTree.js CHANGED
@@ -92,8 +92,8 @@ export class HostNode {
92
92
  list.splice(at, 1);
93
93
  }
94
94
  dispatchEvent(event) {
95
- const path = [];
96
- for (let node = this; node !== null; node = node.parentNode)
95
+ const path = [this];
96
+ for (let node = this.parentNode; node !== null; node = node.parentNode)
97
97
  path.push(node);
98
98
  const dispatch = {
99
99
  target: this,
@@ -192,3 +192,20 @@ export class HostNode {
192
192
  }
193
193
  }
194
194
  }
195
+ /**
196
+ * A base class whose instances carry an `on<type>` attribute for each type given.
197
+ *
198
+ * `handles` defines them on this base's prototype as accessors, and the type says so. A class body
199
+ * cannot declare one property per member of a union, and an interface merged into the class to say
200
+ * it is a merge the checker cannot hold to its initialisers. The cast below is the one place the two
201
+ * meet, and it is true by construction: the static block above it has just defined every attribute
202
+ * the type names.
203
+ */
204
+ export function withHandlers(types) {
205
+ class Handled extends HostNode {
206
+ static {
207
+ HostNode.handles(this.prototype, types);
208
+ }
209
+ }
210
+ return Handled;
211
+ }
@@ -35,6 +35,7 @@ export interface MediaFacts {
35
35
  export declare class MediaQueryList extends HostNode {
36
36
  readonly media: string;
37
37
  private readonly answer;
38
+ onchange: ((event: Event) => unknown) | null;
38
39
  private last;
39
40
  constructor(media: string, answer: () => boolean);
40
41
  get matches(): boolean;
@@ -44,9 +45,6 @@ export declare class MediaQueryList extends HostNode {
44
45
  /** Tell the list's listeners if its answer has flipped since they were last told. */
45
46
  recheck(): void;
46
47
  }
47
- export interface MediaQueryList {
48
- onchange: ((event: Event) => unknown) | null;
49
- }
50
48
  export declare class MediaQueries {
51
49
  private readonly facts;
52
50
  private readonly lists;
package/dist/page.d.ts CHANGED
@@ -20,20 +20,14 @@
20
20
  */
21
21
  import { UserActivation } from './activation.ts';
22
22
  import type { NativeCanvas } from './canvas.ts';
23
- import { type Handlers, HostNode } from './domTree.ts';
23
+ import { HostNode } from './domTree.ts';
24
24
  import { PageFullscreen } from './fullscreen.ts';
25
25
  import { MediaQueries, type MediaQueryList } from './mediaQueries.ts';
26
26
  import { PointerCapture } from './pointerCapture.ts';
27
27
  /** Every input event a page can be told of, which each of the three nodes answers `on…` for. */
28
28
  export declare const INPUT_TYPES: readonly ["keydown", "keypress", "keyup", "focus", "blur", "wheel", "contextmenu", "click", "dblclick", "auxclick", "mousedown", "mouseup", "mousemove", "mouseover", "mouseout", "mouseenter", "mouseleave", "pointerdown", "pointerup", "pointermove", "pointerover", "pointerout", "pointerenter", "pointerleave", "pointercancel", "gotpointercapture", "lostpointercapture", "touchstart", "touchmove", "touchend", "touchcancel", "fullscreenchange", "fullscreenerror"];
29
- type InputType = (typeof INPUT_TYPES)[number];
30
- declare const WINDOW_TYPES: readonly ['resize', 'beforeunload', 'gamepadconnected', 'gamepaddisconnected'];
31
- declare const DOCUMENT_TYPES: readonly ['visibilitychange', 'pointerlockchange', 'pointerlockerror', 'fullscreenchange', 'fullscreenerror'];
32
- export interface PageWindow extends Handlers<InputType | (typeof WINDOW_TYPES)[number]> {
33
- }
34
- export interface PageDocument extends Handlers<InputType | (typeof DOCUMENT_TYPES)[number]> {
35
- }
36
- export declare class PageWindow extends HostNode {
29
+ declare const PageWindow_base: abstract new () => HostNode & import("./domTree.ts").Handlers<"auxclick" | "beforeunload" | "blur" | "click" | "contextmenu" | "dblclick" | "focus" | "fullscreenchange" | "fullscreenerror" | "gamepadconnected" | "gamepaddisconnected" | "gotpointercapture" | "keydown" | "keypress" | "keyup" | "lostpointercapture" | "mousedown" | "mouseenter" | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" | "pointercancel" | "pointerdown" | "pointerenter" | "pointerleave" | "pointermove" | "pointerout" | "pointerover" | "pointerup" | "resize" | "touchcancel" | "touchend" | "touchmove" | "touchstart" | "wheel">;
30
+ export declare class PageWindow extends PageWindow_base {
37
31
  canvas: NativeCanvas | null;
38
32
  /** Answered by the page, which knows what a query asks about (`mediaQueries.ts`). */
39
33
  matchMedia: (query: string) => MediaQueryList;
@@ -41,7 +35,8 @@ export declare class PageWindow extends HostNode {
41
35
  get innerHeight(): number;
42
36
  get devicePixelRatio(): number;
43
37
  }
44
- export declare class PageDocument extends HostNode {
38
+ declare const PageDocument_base: abstract new () => HostNode & import("./domTree.ts").Handlers<"auxclick" | "blur" | "click" | "contextmenu" | "dblclick" | "focus" | "fullscreenchange" | "fullscreenerror" | "gotpointercapture" | "keydown" | "keypress" | "keyup" | "lostpointercapture" | "mousedown" | "mouseenter" | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" | "pointercancel" | "pointerdown" | "pointerenter" | "pointerleave" | "pointerlockchange" | "pointerlockerror" | "pointermove" | "pointerout" | "pointerover" | "pointerup" | "touchcancel" | "touchend" | "touchmove" | "touchstart" | "visibilitychange" | "wheel">;
39
+ export declare class PageDocument extends PageDocument_base {
45
40
  visibilityState: DocumentVisibilityState;
46
41
  pointerLockElement: Element | null;
47
42
  /** What is focused: the canvas, once it is focusable and asked, or nothing. */
package/dist/page.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * say so; a packaged game is given the bridge.
20
20
  */
21
21
  import { UserActivation } from './activation.js';
22
- import { HostNode } from './domTree.js';
22
+ import { HostNode, withHandlers } from './domTree.js';
23
23
  import { installEventClasses } from './eventClasses.js';
24
24
  import { PageFullscreen } from './fullscreen.js';
25
25
  import { MediaQueries } from './mediaQueries.js';
@@ -42,7 +42,7 @@ const DOCUMENT_TYPES = [
42
42
  'fullscreenchange',
43
43
  'fullscreenerror',
44
44
  ];
45
- export class PageWindow extends HostNode {
45
+ export class PageWindow extends withHandlers([...INPUT_TYPES, ...WINDOW_TYPES]) {
46
46
  canvas = null;
47
47
  /** Answered by the page, which knows what a query asks about (`mediaQueries.ts`). */
48
48
  matchMedia = () => {
@@ -57,11 +57,8 @@ export class PageWindow extends HostNode {
57
57
  get devicePixelRatio() {
58
58
  return this.canvas?.pixelRatio ?? 1;
59
59
  }
60
- static {
61
- HostNode.handles(PageWindow.prototype, [...INPUT_TYPES, ...WINDOW_TYPES]);
62
- }
63
60
  }
64
- export class PageDocument extends HostNode {
61
+ export class PageDocument extends withHandlers([...INPUT_TYPES, ...DOCUMENT_TYPES]) {
65
62
  visibilityState = 'visible';
66
63
  pointerLockElement = null;
67
64
  /** What is focused: the canvas, once it is focusable and asked, or nothing. */
@@ -94,9 +91,6 @@ export class PageDocument extends HostNode {
94
91
  createElement(tag) {
95
92
  throw new Error(`[driftengine] the native host has no DOM to make a <${tag}> in`);
96
93
  }
97
- static {
98
- HostNode.handles(PageDocument.prototype, [...INPUT_TYPES, ...DOCUMENT_TYPES]);
99
- }
100
94
  }
101
95
  export class HostPage {
102
96
  window = new PageWindow();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driftengine/native-host",
3
- "version": "4.7.3",
3
+ "version": "4.8.0",
4
4
  "description": "The engine on a native window and a native WebGPU device, with no browser between them",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -37,13 +37,13 @@
37
37
  "node-web-audio-api": "2.2.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@driftengine/audio": "4.7.3"
40
+ "@driftengine/audio": "4.8.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@driftengine/core": "4.7.3",
44
- "@driftengine/package": "4.7.3",
45
- "@driftengine/texture": "4.7.3",
46
- "@driftengine/ui2d": "4.7.3"
43
+ "@driftengine/core": "4.8.0",
44
+ "@driftengine/package": "4.8.0",
45
+ "@driftengine/texture": "4.8.0",
46
+ "@driftengine/ui2d": "4.8.0"
47
47
  },
48
48
  "peerDependenciesMeta": {
49
49
  "@driftengine/texture": {
package/src/canvas.ts CHANGED
@@ -14,7 +14,7 @@
14
14
  */
15
15
 
16
16
  import { CanvasStyle } from './canvasStyle.ts';
17
- import { type Handlers, HostNode } from './domTree.ts';
17
+ import { withHandlers } from './domTree.ts';
18
18
  import { INPUT_TYPES, type PageDocument } from './page.ts';
19
19
  import { PointerCapture } from './pointerCapture.ts';
20
20
 
@@ -23,10 +23,7 @@ const COPY_SRC = 0x01;
23
23
  const TEXTURE_BINDING = 0x04;
24
24
  const RENDER_ATTACHMENT = 0x10;
25
25
 
26
- /* The attributes `HostNode.handles` defines below, declared for the checker. */
27
- export interface NativeCanvas extends Handlers<(typeof INPUT_TYPES)[number]> {}
28
-
29
- export class NativeCanvas extends HostNode {
26
+ export class NativeCanvas extends withHandlers(INPUT_TYPES) {
30
27
  /** The drawing buffer, in device pixels, which the engine sets. */
31
28
  width: number;
32
29
  height: number;
@@ -53,10 +50,6 @@ export class NativeCanvas extends HostNode {
53
50
  */
54
51
  private focusIndex: number | null = null;
55
52
 
56
- static {
57
- HostNode.handles(NativeCanvas.prototype, INPUT_TYPES);
58
- }
59
-
60
53
  constructor(width: number, height: number, pixelRatio = 1) {
61
54
  super();
62
55
  this.pixelRatio = pixelRatio;
package/src/domTree.ts CHANGED
@@ -125,8 +125,8 @@ export class HostNode implements EventTarget {
125
125
  }
126
126
 
127
127
  dispatchEvent(event: Event): boolean {
128
- const path: HostNode[] = [];
129
- for (let node: HostNode | null = this; node !== null; node = node.parentNode) path.push(node);
128
+ const path: HostNode[] = [this];
129
+ for (let node = this.parentNode; node !== null; node = node.parentNode) path.push(node);
130
130
  const dispatch: Dispatch = {
131
131
  target: this,
132
132
  current: null,
@@ -213,3 +213,23 @@ export class HostNode implements EventTarget {
213
213
  }
214
214
  }
215
215
  }
216
+
217
+ /**
218
+ * A base class whose instances carry an `on<type>` attribute for each type given.
219
+ *
220
+ * `handles` defines them on this base's prototype as accessors, and the type says so. A class body
221
+ * cannot declare one property per member of a union, and an interface merged into the class to say
222
+ * it is a merge the checker cannot hold to its initialisers. The cast below is the one place the two
223
+ * meet, and it is true by construction: the static block above it has just defined every attribute
224
+ * the type names.
225
+ */
226
+ export function withHandlers<Types extends string>(
227
+ types: readonly Types[],
228
+ ): abstract new () => HostNode & Handlers<Types> {
229
+ abstract class Handled extends HostNode {
230
+ static {
231
+ HostNode.handles(this.prototype, types);
232
+ }
233
+ }
234
+ return Handled as unknown as abstract new () => HostNode & Handlers<Types>;
235
+ }
@@ -82,6 +82,8 @@ function nameAndValue(condition: string): [string, string | null] {
82
82
  }
83
83
 
84
84
  export class MediaQueryList extends HostNode {
85
+ /* Defined on the prototype by `HostNode.handles` below; declared here for the checker. */
86
+ declare onchange: ((event: Event) => unknown) | null;
85
87
  private last: boolean;
86
88
  constructor(
87
89
  readonly media: string,
@@ -112,10 +114,6 @@ export class MediaQueryList extends HostNode {
112
114
  }
113
115
  }
114
116
 
115
- export interface MediaQueryList {
116
- onchange: ((event: Event) => unknown) | null;
117
- }
118
-
119
117
  export class MediaQueries {
120
118
  private readonly lists: MediaQueryList[] = [];
121
119
  private readonly unknown = new Set<string>();
package/src/page.ts CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
  import { UserActivation } from './activation.ts';
23
23
  import type { NativeCanvas } from './canvas.ts';
24
- import { type Handlers, HostNode } from './domTree.ts';
24
+ import { HostNode, withHandlers } from './domTree.ts';
25
25
  import { installEventClasses } from './eventClasses.ts';
26
26
  import { PageFullscreen } from './fullscreen.ts';
27
27
  import { MediaQueries, type MediaQueryList } from './mediaQueries.ts';
@@ -38,7 +38,6 @@ export const INPUT_TYPES = [
38
38
  ...['touchstart', 'touchmove', 'touchend', 'touchcancel', 'fullscreenchange', 'fullscreenerror'],
39
39
  ] as const;
40
40
 
41
- type InputType = (typeof INPUT_TYPES)[number];
42
41
  const WINDOW_TYPES = ['resize', 'beforeunload', 'gamepadconnected', 'gamepaddisconnected'] as const;
43
42
  const DOCUMENT_TYPES = [
44
43
  'visibilitychange',
@@ -48,11 +47,7 @@ const DOCUMENT_TYPES = [
48
47
  'fullscreenerror',
49
48
  ] as const;
50
49
 
51
- /* The attributes `HostNode.handles` defines below, declared for the checker. */
52
- export interface PageWindow extends Handlers<InputType | (typeof WINDOW_TYPES)[number]> {}
53
- export interface PageDocument extends Handlers<InputType | (typeof DOCUMENT_TYPES)[number]> {}
54
-
55
- export class PageWindow extends HostNode {
50
+ export class PageWindow extends withHandlers([...INPUT_TYPES, ...WINDOW_TYPES]) {
56
51
  canvas: NativeCanvas | null = null;
57
52
  /** Answered by the page, which knows what a query asks about (`mediaQueries.ts`). */
58
53
  matchMedia: (query: string) => MediaQueryList = () => {
@@ -67,12 +62,9 @@ export class PageWindow extends HostNode {
67
62
  get devicePixelRatio(): number {
68
63
  return this.canvas?.pixelRatio ?? 1;
69
64
  }
70
- static {
71
- HostNode.handles(PageWindow.prototype, [...INPUT_TYPES, ...WINDOW_TYPES]);
72
- }
73
65
  }
74
66
 
75
- export class PageDocument extends HostNode {
67
+ export class PageDocument extends withHandlers([...INPUT_TYPES, ...DOCUMENT_TYPES]) {
76
68
  visibilityState: DocumentVisibilityState = 'visible';
77
69
  pointerLockElement: Element | null = null;
78
70
  /** What is focused: the canvas, once it is focusable and asked, or nothing. */
@@ -112,10 +104,6 @@ export class PageDocument extends HostNode {
112
104
  createElement(tag: string): never {
113
105
  throw new Error(`[driftengine] the native host has no DOM to make a <${tag}> in`);
114
106
  }
115
-
116
- static {
117
- HostNode.handles(PageDocument.prototype, [...INPUT_TYPES, ...DOCUMENT_TYPES]);
118
- }
119
107
  }
120
108
 
121
109
  export interface HostPageOptions {