girgen 0.3.8 → 0.3.9

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.
Files changed (3) hide show
  1. package/README.md +207 -0
  2. package/bin/girgen.js +2 -0
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -1,3 +1,210 @@
1
1
  # GirGen
2
2
 
3
3
  GIR Parser and type generator.
4
+
5
+ ## Install
6
+
7
+ There are pre built binaries for `linux-x64` and `linux-arm64` published on NPM.
8
+
9
+ ```sh
10
+ npm install girgen -D
11
+ ./node_modules/.bin/girgen --help
12
+ ```
13
+
14
+ Otherwise you can install from crates.io using `cargo`.
15
+
16
+ ```sh
17
+ cargo install girgen --root .
18
+ ./bin/girgen --help
19
+ ```
20
+
21
+ ## TypeScript
22
+
23
+ Generate a standalone package that contains every namespace found in the given
24
+ directories.
25
+
26
+ ```sh
27
+ girgen typescript --help
28
+ ```
29
+
30
+ > [!TIP]
31
+ >
32
+ > You can use the Gnome flatpak SDK to acquire GIR files on systems that don't
33
+ > have them in one place, e.g NixOS or when you are targeting Flatpak.
34
+ >
35
+ > ```sh
36
+ > flatpak run --command=cp --filesystem=home org.gnome.Sdk -r /usr/share/gir-1.0 gir-1.0
37
+ > girgen -d gir-1.0 typescript
38
+ > ```
39
+
40
+ By default it will generate the package to `.types/gi` which you can then source
41
+ in `tsconfig.json`.
42
+
43
+ ```json
44
+ {
45
+ "compilerOptions": {
46
+ "lib": ["es2024"], // don't forget to specify a `lib` to avoid sourcing TypeScript's `dom` lib
47
+ "skipLibCheck": true, // it's recommended to turn this on
48
+ "typeRoots": [".types"]
49
+ }
50
+ }
51
+ ```
52
+
53
+ > [!TIP]
54
+ >
55
+ > Don't forget to gitignore generated files.
56
+ >
57
+ > ```sh
58
+ > echo ".types/gi/" > .gitignore
59
+ > ```
60
+
61
+ Note that when using `--alias` flag to generate non version imports such as
62
+ `gi://Gtk` make sure to ignore the version you don't need so that it does not
63
+ end up as a union of the two versions.
64
+
65
+ ```sh
66
+ girgen typescript -i Gtk-3.0 --alias
67
+ ```
68
+
69
+ ### TypeScript Annotations
70
+
71
+ GObject has a few additional concepts about class methods and properties that
72
+ cannot be expressed with TypeScript alone. For these girgen generates type only
73
+ fields on classes and interfaces.
74
+
75
+ We have annotations for:
76
+
77
+ - signals
78
+ - readable properties
79
+ - writable properties
80
+ - construct-only properties
81
+
82
+ When implementing a GObject subclass you might want to annotate a subset of
83
+ these or all of these depending on usecase.
84
+
85
+ Every class that inherits from GObject is going to include a namespace
86
+ containing type declarations where each member is written in `kebab-case`:
87
+
88
+ ```ts
89
+ namespace MyClass {
90
+ export interface SignalSignatures extends GObject.Object.SignalSignatures {
91
+ // simple signal
92
+ "my-signal"(arg: number): void
93
+ // detailed signals are annotated with the `::{}` suffix
94
+ "my-detailed-signal::{}"(arg: number): void
95
+ }
96
+
97
+ // ReadableProperties is also used for notify signal annotations
98
+ export interface ReadableProperties
99
+ extends GObject.Object.ReadableProperties {
100
+ // property which has a public getter
101
+ "my-prop": number
102
+ }
103
+
104
+ export interface WritableProperties
105
+ extends GObject.Object.WritableProperties {
106
+ // property which has a public setter
107
+ "my-prop": number
108
+ }
109
+
110
+ export interface ConstructOnlyProperties
111
+ extends GObject.Object.ConstructOnlyProperties {
112
+ // property which can only be set at construction
113
+ "my-ctor-prop": number
114
+ }
115
+ }
116
+ ```
117
+
118
+ And the Class will refer to these using special `$` prefixed fields:
119
+
120
+ > [!IMPORTANT]
121
+ >
122
+ > These fields don't exist at runtime, they are used by other APIs to introspect
123
+ > GObjects.
124
+
125
+ ```ts
126
+ class MyClass extends GObject.Object {
127
+ declare readonly $signals: MyClass.SignalSignatures
128
+ declare readonly $readableProperties: MyClass.ReadableProperties
129
+ declare readonly $writableProperties: MyClass.WritableProperties
130
+ declare readonly $constructOnlyProperties: MyClass.ConstructOnlyProperties
131
+
132
+ static {
133
+ GObject.registerClass(
134
+ {
135
+ Signals: {
136
+ "my-signal": {
137
+ param_types: [GObject.TYPE_DOUBLE],
138
+ },
139
+ "my-detailed-signal": {
140
+ param_types: [GObject.TYPE_DOUBLE],
141
+ flags: GObject.SignalFlags.DETAILED,
142
+ },
143
+ },
144
+ Properties: {
145
+ "my-prop": GObject.ParamSpec.double(
146
+ "my-prop",
147
+ null,
148
+ null,
149
+ GObject.ParamFlags.READWRITE,
150
+ -GObject.Double.MAX_VALUE,
151
+ GObject.Double.MAX_VALUE,
152
+ ),
153
+ "my-ctor-prop": GObject.ParamSpec.double(
154
+ "my-ctor-prop",
155
+ null,
156
+ null,
157
+ GObject.ParamFlags.CONSTRUCT_ONLY,
158
+ -GObject.Double.MAX_VALUE,
159
+ GObject.Double.MAX_VALUE,
160
+ ),
161
+ },
162
+ },
163
+ MyClass,
164
+ )
165
+ }
166
+
167
+ // GObject.ConstructorProps can be used to infer props from the annotations
168
+ constructor(props: Partial<GObject.ConstructorProps<MyClass>>) {
169
+ super(props)
170
+
171
+ // note that properties will be annotated as camelCase
172
+ console.log(props.myProp, props.myCtorProp)
173
+ }
174
+ }
175
+ ```
176
+
177
+ Methods such as `connect()`, `emit()`, `notify()` will infer from these
178
+ annotations.
179
+
180
+ ```ts
181
+ const instance = new MyClass()
182
+
183
+ instance.connect("my-signal", (source, arg) => {
184
+ console.log(arg)
185
+ })
186
+
187
+ instance.connect("my-detailed-signal::detail", (source, arg) => {
188
+ console.log(arg)
189
+ })
190
+
191
+ instance.connect("notify::my-prop", (_, pspec) => {
192
+ console.log(pspec.name)
193
+ })
194
+ ```
195
+
196
+ Due to how TypeScript `this` type works, you need to annotate `this` or use a
197
+ typecast to correctly infer types within the class.
198
+
199
+ ```ts
200
+ class MyClass {
201
+ myFn(this: MyClass) {
202
+ this.emit("my-signal", 0)
203
+ }
204
+
205
+ myFn() {
206
+ const self = this as MyClass
207
+ self.emit("my-signal", 0)
208
+ }
209
+ }
210
+ ```
package/bin/girgen.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { arch, platform, argv, exit } from "node:process"
4
4
  import { spawnSync } from "node:child_process"
5
+ import { chmod } from "node:fs/promises"
5
6
 
6
7
  const supportedPlatforms = ["linux-x64", "linux-arm64"]
7
8
  const target = `${platform}-${arch}`
@@ -11,6 +12,7 @@ if (!supportedPlatforms.includes(target)) {
11
12
  }
12
13
 
13
14
  const cli = import.meta.resolve(`@girgen/${target}`).replace("file://", "")
15
+ await chmod(cli, 0o755)
14
16
 
15
17
  const processResult = spawnSync(cli, argv.slice(2), {
16
18
  stdio: "inherit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "girgen",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "author": "Aylur",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -23,8 +23,8 @@
23
23
  "@types/node": "latest"
24
24
  },
25
25
  "optionalDependencies": {
26
- "@girgen/linux-x64": "0.3.8",
27
- "@girgen/linux-arm64": "0.3.8"
26
+ "@girgen/linux-x64": "0.3.9",
27
+ "@girgen/linux-arm64": "0.3.9"
28
28
  },
29
29
  "files": [
30
30
  "bin"