@gjsify/node-gi 0.26.0 → 0.27.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/README.md CHANGED
@@ -86,16 +86,44 @@ vendored as-is — gjsify ships its own dual (GJS + Node) example/test infra.
86
86
  ## Requirements
87
87
 
88
88
  - Node.js ≥ 20
89
- - A C++ toolchain (`g++`/`clang`, `make`), `node-gyp`
90
- - GLib ≥ 2.80 development headers exposing `girepository-2.0`
91
- (Fedora: `glib2-devel gobject-introspection-devel gcc-c++`;
92
- Debian/Ubuntu: `libglib2.0-dev libgirepository-2.0-dev g++`)
89
+ - **No C++ toolchain on the four prebuilt targets.** The published tarball ships
90
+ `prebuilds/<platform>-<arch>/node_gi.node` for `linux-x64`, `linux-arm64`,
91
+ `darwin-arm64` and `win32-x64` (`package.json#gjsify.platforms`), and the
92
+ `install` script (`scripts/install.mjs`) uses it instead of building: a source
93
+ build is the FALLBACK for a host with no prebuild, not the default. Force it
94
+ with `NODE_GI_BUILD_FROM_SOURCE=1` (or npm's `--build-from-source`); skip it
95
+ entirely with `NODE_GI_SKIP_NATIVE_BUILD=1`.
96
+ - For a source build only: a C++ toolchain (`g++`/`clang`, `make`), `node-gyp`,
97
+ and GLib ≥ 2.80 development headers exposing `girepository-2.0` + cairo
98
+ (Fedora: `glib2-devel gobject-introspection-devel cairo-devel gcc-c++`;
99
+ Debian/Ubuntu: `libglib2.0-dev libgirepository-2.0-dev libcairo2-dev g++`)
93
100
  - At runtime, the target libraries' typelibs must be installed (same as `gi://`
94
- under GJS) — **except on macOS arm64**, where the optional
95
- [`@gjsify/gtk-runtime-darwin-arm64`](../gtk-runtime-darwin-arm64) bundle ships a
96
- relocated GTK/GI runtime so the display-free surface works with no Homebrew GTK
97
- (Phase 2). node-gi auto-detects the bundle at load and prepends its typelib dir
98
- to the GIRepository search path (`gtk-runtime.js`).
101
+ under GJS) — **except on macOS (both arm64 and Intel x64) and Windows x64**,
102
+ where a batteries-included, relocated GTK/GI runtime bundle ships so `gi://`
103
+ works with no Homebrew/gvsbuild GTK (Phase 2). node-gi auto-detects a bundle at
104
+ load and prepends its typelib dir to the GIRepository search path
105
+ (`gtk-runtime.js`) — nothing in that loader keys on a specific target, so each
106
+ new bundle is found by the mechanism that found the first.
107
+ - **Those bundles are a MANUAL install today.**
108
+ [`@gjsify/gtk-runtime-darwin-arm64`](../gtk-runtime-darwin-arm64),
109
+ [`@gjsify/gtk-runtime-darwin-x64`](../gtk-runtime-darwin-x64) and
110
+ [`@gjsify/gtk-runtime-win32-x64`](../gtk-runtime-win32-x64) are published, and
111
+ node-gi finds whichever one is present in the tree — but **no
112
+ package declares them as a dependency**, so nothing installs them for you.
113
+ Install the one for your platform alongside node-gi:
114
+
115
+ ```bash
116
+ npm install @gjsify/gtk-runtime-win32-x64 # Windows x64
117
+ npm install @gjsify/gtk-runtime-darwin-arm64 # macOS Apple silicon
118
+ npm install @gjsify/gtk-runtime-darwin-x64 # macOS Intel
119
+ ```
120
+
121
+ All three declare `os`/`cpu`, so npm/yarn/pnpm skip them off-platform. Making them
122
+ `optionalDependencies` of this package (which would remove the manual step
123
+ without any consumer-side platform branching) is pending two decisions outside
124
+ this package — the ADR-0003 dependency-direction rule between node-gi's tier
125
+ and the bundles', and `os`/`cpu` filtering in `gjsify install`'s native
126
+ backend, which currently places foreign-platform optional deps.
99
127
  - **Node.js ≥ 20, Bun ≥ 1.3, or Deno ≥ 2** — the addon is Node-API, so one binary
100
128
  runs on all three (see [Runtimes](#runtimes-node--bun--deno)).
101
129
 
@@ -153,7 +181,7 @@ blocking loop remain Node-only (the uv co-pump).
153
181
  ## Build & test
154
182
 
155
183
  ```bash
156
- npm install # builds the native addon via node-gyp (install script)
184
+ npm install # prebuild if one is staged, else node-gyp (scripts/install.mjs)
157
185
  npm test # node --test (full suite, Node — authoritative)
158
186
  npm run test:gc # node --test --expose-gc (toggle-ref GC-stress leg)
159
187
  npm run test:bun # conformance subset on Bun (needs `bun`)
@@ -170,7 +198,15 @@ and the bun/deno runner defaults to it — without that, a stale staged prebuild
170
198
  silently shadows your build. CI's cross-runtime job sets `NODE_GI_NATIVE=prebuild`
171
199
  to keep validating the prebuild load path with a freshly staged binary.
172
200
  `NODE_GI_NATIVE` accepts `build`, `prebuild`, or an explicit path to a
173
- `node_gi.node`.
201
+ `node_gi.node`. That candidate order lives in `native-paths.js` and is shared
202
+ with the `install` script, so the binary the guard decides not to rebuild is
203
+ by construction the binary the loader looks for.
204
+
205
+ In a checkout `prebuilds/` is gitignored, so `npm install` here always runs the
206
+ source build — as do the `npm install --foreground-scripts` steps in
207
+ `node-gi.yml` and the `node-gi-prebuild-*` legs in `release.yml`, which need
208
+ `build/Release/node_gi.node` for `scripts/stage-prebuild.mjs`. Set
209
+ `NODE_GI_BUILD_FROM_SOURCE=1` to force it regardless of a staged prebuild.
174
210
 
175
211
  Two debug-only env vars instrument the toggle-ref / teardown machinery (both
176
212
  parsed once at first use, zero cost when unset — never set them in production):
@@ -866,7 +902,7 @@ Shader/buffer/texture breadth (a three.js triangle/teapot) is the remaining
866
902
  follow-up — the seam + context stack are proven.
867
903
 
868
904
  The tests self-skip without a display, without a `gjsify` CLI, or without the
869
- committed `Gwebgl-0.1` prebuild (`packages/framework/webgl/prebuilds/linux-*`,
905
+ committed `Gwebgl-0.1` prebuild (`packages/framework/webgl-linux-*/prebuilds/`,
870
906
  which the test itself puts on `GI_TYPELIB_PATH`/`LD_LIBRARY_PATH`); the bridge
871
907
  test additionally skips when `@gjsify/webgl` is not built. The fixture build
872
908
  needs a WORKSPACE-built `@gjsify/cli` (point `GJSIFY_BIN` at
@@ -1005,6 +1041,15 @@ marker and wires the env (`GSETTINGS_SCHEMA_DIR` / `GDK_PIXBUF_MODULE_FILE` /
1005
1041
  `XDG_DATA_DIRS` / `FONTCONFIG_*`); a display-free bundle carries no marker, so the
1006
1042
  wiring is a strict no-op and that load is byte-unchanged.
1007
1043
 
1044
+ The bundle is not pulled in automatically — `npm install
1045
+ @gjsify/gtk-runtime-win32-x64` alongside node-gi (see
1046
+ [Requirements](#requirements)). `resolveGtkRuntimeBundle()` finds it wherever the
1047
+ package manager placed it: an explicit `GJSIFY_GTK_RUNTIME` dir, a staged
1048
+ `prebuilds/<target>/gtk/`, the sibling monorepo checkout, or
1049
+ `require.resolve('@gjsify/gtk-runtime-<target>')` — the last of which covers a
1050
+ hoisted `node_modules/@gjsify/gtk-runtime-win32-x64`, so no loader change is
1051
+ needed if the dependency edge is ever declared.
1052
+
1008
1053
  ### Adwaita widget breadth realizes + reacts + renders
1009
1054
 
1010
1055
  Beyond one window's chrome: a representative slice of the REAL Libadwaita widget
package/cairo.d.ts CHANGED
@@ -19,136 +19,136 @@ export const SurfaceType: CairoEnum;
19
19
 
20
20
  /** cairo drawing context (`cairo_t`). */
21
21
  export class Context {
22
- constructor(surface: Surface);
23
- save(): void;
24
- restore(): void;
25
- newPath(): void;
26
- closePath(): void;
27
- moveTo(x: number, y: number): void;
28
- lineTo(x: number, y: number): void;
29
- relMoveTo(dx: number, dy: number): void;
30
- relLineTo(dx: number, dy: number): void;
31
- rectangle(x: number, y: number, width: number, height: number): void;
32
- arc(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
33
- arcNegative(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
34
- curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void;
35
- fill(): void;
36
- fillPreserve(): void;
37
- stroke(): void;
38
- strokePreserve(): void;
39
- paint(): void;
40
- paintWithAlpha(alpha: number): void;
41
- clip(): void;
42
- clipPreserve(): void;
43
- translate(tx: number, ty: number): void;
44
- scale(sx: number, sy: number): void;
45
- rotate(angle: number): void;
46
- setSourceRGB(red: number, green: number, blue: number): void;
47
- setSourceRGBA(red: number, green: number, blue: number, alpha: number): void;
48
- setSource(pattern: Pattern): void;
49
- setSourceSurface(surface: Surface, x: number, y: number): void;
50
- /** The context's current source pattern (own reference; concrete subclass). */
51
- getSource(): Pattern;
52
- identityMatrix(): void;
53
- newSubPath(): void;
54
- /** User → device coordinates as `[x, y]` (GJS return shape). */
55
- userToDevice(x: number, y: number): [number, number];
56
- /** User → device distance (ignores translation) as `[dx, dy]`. */
57
- userToDeviceDistance(dx: number, dy: number): [number, number];
58
- /** Device → user coordinates as `[x, y]`. */
59
- deviceToUser(x: number, y: number): [number, number];
60
- /** Device → user distance (ignores translation) as `[dx, dy]`. */
61
- deviceToUserDistance(dx: number, dy: number): [number, number];
62
- /** Copy the current path into an owned {@link Path} handle. */
63
- copyPath(): Path;
64
- /** Like {@link copyPath} but with curves flattened to line segments. */
65
- copyPathFlat(): Path;
66
- appendPath(path: Path): void;
67
- /**
68
- * Set the stroke dash pattern. GJS semantics: holes/undefined entries are
69
- * skipped, a non-positive value throws, an empty array disables dashing.
70
- */
71
- setDash(dashes: number[], offset: number): void;
72
- getDashCount(): number;
73
- /**
74
- * The current dash pattern as `[dashes, offset]`.
75
- * Note: GJS ships only `getDashCount`; this is a node-gi convenience.
76
- */
77
- getDash(): [number[], number];
78
- inFill(x: number, y: number): boolean;
79
- inStroke(x: number, y: number): boolean;
80
- setLineWidth(width: number): void;
81
- getLineWidth(): number;
82
- setLineCap(lineCap: number): void;
83
- setLineJoin(lineJoin: number): void;
84
- setFillRule(fillRule: number): void;
85
- setAntialias(antialias: number): void;
86
- setOperator(op: number): void;
87
- setMiterLimit(limit: number): void;
88
- setTolerance(tolerance: number): void;
89
- status(): number;
90
- $dispose(): void;
22
+ constructor(surface: Surface);
23
+ save(): void;
24
+ restore(): void;
25
+ newPath(): void;
26
+ closePath(): void;
27
+ moveTo(x: number, y: number): void;
28
+ lineTo(x: number, y: number): void;
29
+ relMoveTo(dx: number, dy: number): void;
30
+ relLineTo(dx: number, dy: number): void;
31
+ rectangle(x: number, y: number, width: number, height: number): void;
32
+ arc(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
33
+ arcNegative(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
34
+ curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void;
35
+ fill(): void;
36
+ fillPreserve(): void;
37
+ stroke(): void;
38
+ strokePreserve(): void;
39
+ paint(): void;
40
+ paintWithAlpha(alpha: number): void;
41
+ clip(): void;
42
+ clipPreserve(): void;
43
+ translate(tx: number, ty: number): void;
44
+ scale(sx: number, sy: number): void;
45
+ rotate(angle: number): void;
46
+ setSourceRGB(red: number, green: number, blue: number): void;
47
+ setSourceRGBA(red: number, green: number, blue: number, alpha: number): void;
48
+ setSource(pattern: Pattern): void;
49
+ setSourceSurface(surface: Surface, x: number, y: number): void;
50
+ /** The context's current source pattern (own reference; concrete subclass). */
51
+ getSource(): Pattern;
52
+ identityMatrix(): void;
53
+ newSubPath(): void;
54
+ /** User → device coordinates as `[x, y]` (GJS return shape). */
55
+ userToDevice(x: number, y: number): [number, number];
56
+ /** User → device distance (ignores translation) as `[dx, dy]`. */
57
+ userToDeviceDistance(dx: number, dy: number): [number, number];
58
+ /** Device → user coordinates as `[x, y]`. */
59
+ deviceToUser(x: number, y: number): [number, number];
60
+ /** Device → user distance (ignores translation) as `[dx, dy]`. */
61
+ deviceToUserDistance(dx: number, dy: number): [number, number];
62
+ /** Copy the current path into an owned {@link Path} handle. */
63
+ copyPath(): Path;
64
+ /** Like {@link copyPath} but with curves flattened to line segments. */
65
+ copyPathFlat(): Path;
66
+ appendPath(path: Path): void;
67
+ /**
68
+ * Set the stroke dash pattern. GJS semantics: holes/undefined entries are
69
+ * skipped, a non-positive value throws, an empty array disables dashing.
70
+ */
71
+ setDash(dashes: number[], offset: number): void;
72
+ getDashCount(): number;
73
+ /**
74
+ * The current dash pattern as `[dashes, offset]`.
75
+ * Note: GJS ships only `getDashCount`; this is a node-gi convenience.
76
+ */
77
+ getDash(): [number[], number];
78
+ inFill(x: number, y: number): boolean;
79
+ inStroke(x: number, y: number): boolean;
80
+ setLineWidth(width: number): void;
81
+ getLineWidth(): number;
82
+ setLineCap(lineCap: number): void;
83
+ setLineJoin(lineJoin: number): void;
84
+ setFillRule(fillRule: number): void;
85
+ setAntialias(antialias: number): void;
86
+ setOperator(op: number): void;
87
+ setMiterLimit(limit: number): void;
88
+ setTolerance(tolerance: number): void;
89
+ status(): number;
90
+ $dispose(): void;
91
91
  }
92
92
 
93
93
  /** cairo surface base class (`cairo_surface_t`). */
94
94
  export class Surface {
95
- getType(): number;
96
- status(): number;
97
- flush(): void;
98
- finish(): void;
99
- writeToPNG(filename: string): void;
100
- $dispose(): void;
95
+ getType(): number;
96
+ status(): number;
97
+ flush(): void;
98
+ finish(): void;
99
+ writeToPNG(filename: string): void;
100
+ $dispose(): void;
101
101
  }
102
102
 
103
103
  /** cairo image surface (`cairo_image_surface_*`). */
104
104
  export class ImageSurface extends Surface {
105
- constructor(format: number, width: number, height: number);
106
- static create(format: number, width: number, height: number): ImageSurface;
107
- static createFromPNG(filename: string): ImageSurface;
108
- getWidth(): number;
109
- getHeight(): number;
110
- getStride(): number;
111
- getFormat(): number;
112
- /** Raw pixel buffer as a fresh Uint8Array copy (length = stride * height). */
113
- getData(): Uint8Array;
105
+ constructor(format: number, width: number, height: number);
106
+ static create(format: number, width: number, height: number): ImageSurface;
107
+ static createFromPNG(filename: string): ImageSurface;
108
+ getWidth(): number;
109
+ getHeight(): number;
110
+ getStride(): number;
111
+ getFormat(): number;
112
+ /** Raw pixel buffer as a fresh Uint8Array copy (length = stride * height). */
113
+ getData(): Uint8Array;
114
114
  }
115
115
 
116
116
  /** cairo pattern base class (`cairo_pattern_t`). */
117
117
  export class Pattern {
118
- getType(): number;
119
- status(): number;
120
- $dispose(): void;
118
+ getType(): number;
119
+ status(): number;
120
+ $dispose(): void;
121
121
  }
122
122
 
123
123
  /** solid-color pattern. */
124
124
  export class SolidPattern extends Pattern {
125
- static createRGB(red: number, green: number, blue: number): SolidPattern;
126
- static createRGBA(red: number, green: number, blue: number, alpha: number): SolidPattern;
125
+ static createRGB(red: number, green: number, blue: number): SolidPattern;
126
+ static createRGBA(red: number, green: number, blue: number, alpha: number): SolidPattern;
127
127
  }
128
128
 
129
129
  /** gradient base class — shared color-stop API. */
130
130
  export class Gradient extends Pattern {
131
- addColorStopRGB(offset: number, red: number, green: number, blue: number): void;
132
- addColorStopRGBA(offset: number, red: number, green: number, blue: number, alpha: number): void;
131
+ addColorStopRGB(offset: number, red: number, green: number, blue: number): void;
132
+ addColorStopRGBA(offset: number, red: number, green: number, blue: number, alpha: number): void;
133
133
  }
134
134
 
135
135
  /** linear gradient (`cairo_pattern_create_linear`). */
136
136
  export class LinearGradient extends Gradient {
137
- constructor(x0: number, y0: number, x1: number, y1: number);
137
+ constructor(x0: number, y0: number, x1: number, y1: number);
138
138
  }
139
139
 
140
140
  /** radial gradient (`cairo_pattern_create_radial`). */
141
141
  export class RadialGradient extends Gradient {
142
- constructor(cx0: number, cy0: number, radius0: number, cx1: number, cy1: number, radius1: number);
142
+ constructor(cx0: number, cy0: number, radius0: number, cx1: number, cy1: number, radius1: number);
143
143
  }
144
144
 
145
145
  /** surface-backed pattern (`cairo_pattern_create_for_surface`). */
146
146
  export class SurfacePattern extends Pattern {
147
- constructor(surface: Surface);
148
- setExtend(extend: number): void;
149
- getExtend(): number;
150
- setFilter(filter: number): void;
151
- getFilter(): number;
147
+ constructor(surface: Surface);
148
+ setExtend(extend: number): void;
149
+ getExtend(): number;
150
+ setFilter(filter: number): void;
151
+ getFilter(): number;
152
152
  }
153
153
 
154
154
  /**
@@ -159,29 +159,29 @@ export class Path {}
159
159
 
160
160
  /** The GJS `cairo` module object (`import cairo from 'cairo'`). */
161
161
  declare const cairo: {
162
- Antialias: CairoEnum;
163
- Content: CairoEnum;
164
- Extend: CairoEnum;
165
- FillRule: CairoEnum;
166
- Filter: CairoEnum;
167
- FontSlant: CairoEnum;
168
- FontWeight: CairoEnum;
169
- Format: CairoEnum;
170
- LineCap: CairoEnum;
171
- LineJoin: CairoEnum;
172
- Operator: CairoEnum;
173
- PatternType: CairoEnum;
174
- SurfaceType: CairoEnum;
175
- Context: typeof Context;
176
- Surface: typeof Surface;
177
- ImageSurface: typeof ImageSurface;
178
- Pattern: typeof Pattern;
179
- SolidPattern: typeof SolidPattern;
180
- Gradient: typeof Gradient;
181
- LinearGradient: typeof LinearGradient;
182
- RadialGradient: typeof RadialGradient;
183
- SurfacePattern: typeof SurfacePattern;
184
- Path: typeof Path;
162
+ Antialias: CairoEnum;
163
+ Content: CairoEnum;
164
+ Extend: CairoEnum;
165
+ FillRule: CairoEnum;
166
+ Filter: CairoEnum;
167
+ FontSlant: CairoEnum;
168
+ FontWeight: CairoEnum;
169
+ Format: CairoEnum;
170
+ LineCap: CairoEnum;
171
+ LineJoin: CairoEnum;
172
+ Operator: CairoEnum;
173
+ PatternType: CairoEnum;
174
+ SurfaceType: CairoEnum;
175
+ Context: typeof Context;
176
+ Surface: typeof Surface;
177
+ ImageSurface: typeof ImageSurface;
178
+ Pattern: typeof Pattern;
179
+ SolidPattern: typeof SolidPattern;
180
+ Gradient: typeof Gradient;
181
+ LinearGradient: typeof LinearGradient;
182
+ RadialGradient: typeof RadialGradient;
183
+ SurfacePattern: typeof SurfacePattern;
184
+ Path: typeof Path;
185
185
  };
186
186
 
187
187
  export default cairo;