gnim 1.6.4 → 1.7.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/gnim.gresource +0 -0
- package/dist/gtk4/jsx-runtime.ts +11 -0
- package/dist/jsx/jsx.ts +5 -10
- package/dist/jsx/state.ts +87 -25
- package/package.json +5 -1
package/dist/gnim.gresource
CHANGED
|
Binary file
|
package/dist/gtk4/jsx-runtime.ts
CHANGED
|
@@ -3,6 +3,9 @@ import Gio from "gi://Gio?version=2.0"
|
|
|
3
3
|
import { configue } from "../jsx/env.js"
|
|
4
4
|
import { getType, onCleanup, Accessor, Fragment } from "../index.js"
|
|
5
5
|
|
|
6
|
+
import type Adw from "gi://Adw"
|
|
7
|
+
const adw = await import("gi://Adw").then((m) => m.default).catch(() => null)
|
|
8
|
+
|
|
6
9
|
const dummyBuilder = new Gtk.Builder()
|
|
7
10
|
|
|
8
11
|
const { intrinsicElements } = configue({
|
|
@@ -14,6 +17,14 @@ const { intrinsicElements } = configue({
|
|
|
14
17
|
]
|
|
15
18
|
return keys
|
|
16
19
|
}
|
|
20
|
+
if (adw && ctor === adw.ToggleGroup) {
|
|
21
|
+
const keys: Array<Extract<keyof Adw.ToggleGroup, string>> = [
|
|
22
|
+
"active",
|
|
23
|
+
"activeName",
|
|
24
|
+
"active_name",
|
|
25
|
+
]
|
|
26
|
+
return keys
|
|
27
|
+
}
|
|
17
28
|
},
|
|
18
29
|
setCss(object, css) {
|
|
19
30
|
if (!(object instanceof Gtk.Widget)) {
|
package/dist/jsx/jsx.ts
CHANGED
|
@@ -167,11 +167,6 @@ export function append(parent: GObject.Object, child: GObject.Object) {
|
|
|
167
167
|
return
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
if (appendChild in parent && typeof parent[appendChild] === "function") {
|
|
171
|
-
parent[appendChild](child, getType(child))
|
|
172
|
-
return
|
|
173
|
-
}
|
|
174
|
-
|
|
175
170
|
if (child instanceof Fragment) {
|
|
176
171
|
for (const ch of child) {
|
|
177
172
|
append(parent, ch)
|
|
@@ -199,12 +194,12 @@ export function append(parent: GObject.Object, child: GObject.Object) {
|
|
|
199
194
|
return
|
|
200
195
|
}
|
|
201
196
|
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
env.appendChild(parent, child)
|
|
197
|
+
if (appendChild in parent && typeof parent[appendChild] === "function") {
|
|
198
|
+
parent[appendChild](child, getType(child))
|
|
199
|
+
return
|
|
207
200
|
}
|
|
201
|
+
|
|
202
|
+
env.appendChild(parent, child)
|
|
208
203
|
}
|
|
209
204
|
|
|
210
205
|
/** @internal */
|
package/dist/jsx/state.ts
CHANGED
|
@@ -10,6 +10,8 @@ type SubscribeFunction = (callback: SubscribeCallback) => DisposeFunction
|
|
|
10
10
|
|
|
11
11
|
export type Accessed<T> = T extends Accessor<infer V> ? V : never
|
|
12
12
|
|
|
13
|
+
const empty = Symbol("empty computed value")
|
|
14
|
+
|
|
13
15
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
14
16
|
export class Accessor<T = unknown> extends Function {
|
|
15
17
|
static $gtype = GObject.TYPE_JSOBJECT as unknown as GObject.GType<Accessor>
|
|
@@ -29,7 +31,6 @@ export class Accessor<T = unknown> extends Function {
|
|
|
29
31
|
* @returns Unsubscribe function.
|
|
30
32
|
*/
|
|
31
33
|
subscribe(callback: SubscribeCallback): DisposeFunction {
|
|
32
|
-
// TODO: auto unsub when a scope is available?
|
|
33
34
|
return this.#subscribe(callback)
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -49,7 +50,38 @@ export class Accessor<T = unknown> extends Function {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
protected _call<R = T>(transform: (value: T) => R): Accessor<R> {
|
|
52
|
-
|
|
53
|
+
let value: typeof empty | R = empty
|
|
54
|
+
let unsub: DisposeFunction
|
|
55
|
+
|
|
56
|
+
const subscribers = new Set<SubscribeCallback>()
|
|
57
|
+
|
|
58
|
+
const subscribe: SubscribeFunction = (callback) => {
|
|
59
|
+
if (subscribers.size === 0) {
|
|
60
|
+
unsub = this.subscribe(() => {
|
|
61
|
+
const newValue = transform(this.get())
|
|
62
|
+
if (value !== newValue) {
|
|
63
|
+
value = newValue
|
|
64
|
+
Array.from(subscribers).forEach((cb) => cb())
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
subscribers.add(callback)
|
|
70
|
+
|
|
71
|
+
return () => {
|
|
72
|
+
subscribers.delete(callback)
|
|
73
|
+
if (subscribers.size === 0) {
|
|
74
|
+
value = empty
|
|
75
|
+
unsub()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const get = (): R => {
|
|
81
|
+
return value !== empty ? value : transform(this.get())
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return new Accessor(get, subscribe)
|
|
53
85
|
}
|
|
54
86
|
|
|
55
87
|
toString(): string {
|
|
@@ -64,8 +96,9 @@ export class Accessor<T = unknown> extends Function {
|
|
|
64
96
|
|
|
65
97
|
export interface Accessor<T> {
|
|
66
98
|
/**
|
|
67
|
-
* Create a
|
|
99
|
+
* Create a computed `Accessor` that caches its transformed value.
|
|
68
100
|
* @param transform The transformation to apply. Should be a pure function.
|
|
101
|
+
* see {@link createComputed} and {@link createComputedProducer}
|
|
69
102
|
*/
|
|
70
103
|
<R = T>(transform: (value: T) => R): Accessor<R>
|
|
71
104
|
}
|
|
@@ -104,16 +137,22 @@ export function createState<T>(init: T): State<T> {
|
|
|
104
137
|
return [new Accessor(() => currentValue, subscribe), set as Setter<T>]
|
|
105
138
|
}
|
|
106
139
|
|
|
107
|
-
const empty = Symbol("empty computed value")
|
|
108
|
-
|
|
109
140
|
function createComputedProducer<T>(fn: (track: <V>(signal: Accessor<V>) => V) => T): Accessor<T> {
|
|
110
|
-
const subscribers = new Set<SubscribeCallback>()
|
|
111
141
|
let value: typeof empty | T = empty
|
|
112
142
|
let prevDeps = new Map<Accessor, DisposeFunction>()
|
|
113
143
|
|
|
144
|
+
const subscribers = new Set<SubscribeCallback>()
|
|
145
|
+
const cache = new Map<Accessor, unknown>()
|
|
146
|
+
|
|
114
147
|
const effect = () => {
|
|
115
148
|
const deps = new Set<Accessor>()
|
|
116
|
-
|
|
149
|
+
const newValue = fn((v) => {
|
|
150
|
+
deps.add(v)
|
|
151
|
+
return (cache.get(v) as any) || v.get()
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const didChange = value !== newValue
|
|
155
|
+
value = newValue
|
|
117
156
|
|
|
118
157
|
const newDeps = new Map<Accessor, DisposeFunction>()
|
|
119
158
|
|
|
@@ -127,12 +166,21 @@ function createComputedProducer<T>(fn: (track: <V>(signal: Accessor<V>) => V) =>
|
|
|
127
166
|
|
|
128
167
|
for (const dep of deps) {
|
|
129
168
|
if (!newDeps.has(dep)) {
|
|
130
|
-
|
|
169
|
+
const dispose = dep.subscribe(() => {
|
|
170
|
+
const value = dep.get()
|
|
171
|
+
if (cache.get(dep) !== value) {
|
|
172
|
+
cache.set(dep, value)
|
|
173
|
+
effect()
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
newDeps.set(dep, dispose)
|
|
131
177
|
}
|
|
132
178
|
}
|
|
133
179
|
|
|
134
180
|
prevDeps = newDeps
|
|
135
|
-
|
|
181
|
+
if (didChange) {
|
|
182
|
+
Array.from(subscribers).forEach((cb) => cb())
|
|
183
|
+
}
|
|
136
184
|
}
|
|
137
185
|
|
|
138
186
|
const subscribe: SubscribeFunction = (callback) => {
|
|
@@ -154,7 +202,7 @@ function createComputedProducer<T>(fn: (track: <V>(signal: Accessor<V>) => V) =>
|
|
|
154
202
|
}
|
|
155
203
|
|
|
156
204
|
const get = (): T => {
|
|
157
|
-
return value
|
|
205
|
+
return value !== empty ? value : fn((v) => v.get())
|
|
158
206
|
}
|
|
159
207
|
|
|
160
208
|
return new Accessor(get, subscribe)
|
|
@@ -166,17 +214,36 @@ function createComputedArgs<
|
|
|
166
214
|
V = Args,
|
|
167
215
|
>(deps: Deps, transform?: (...args: Args) => V): Accessor<V> {
|
|
168
216
|
let dispose: Array<DisposeFunction>
|
|
217
|
+
let value: typeof empty | V = empty
|
|
218
|
+
|
|
169
219
|
const subscribers = new Set<SubscribeCallback>()
|
|
170
220
|
const cache = new Array<unknown>(deps.length)
|
|
171
221
|
|
|
222
|
+
const compute = (): V => {
|
|
223
|
+
const args = deps.map((dep, i) => {
|
|
224
|
+
if (!cache[i]) {
|
|
225
|
+
cache[i] = dep.get()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return cache[i]
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
return transform ? transform(...(args as Args)) : (args as V)
|
|
232
|
+
}
|
|
233
|
+
|
|
172
234
|
const subscribe: SubscribeFunction = (callback) => {
|
|
173
235
|
if (subscribers.size === 0) {
|
|
174
236
|
dispose = deps.map((dep, i) =>
|
|
175
237
|
dep.subscribe(() => {
|
|
176
|
-
const
|
|
177
|
-
if (cache[i] !==
|
|
238
|
+
const newValue = dep.get()
|
|
239
|
+
if (cache[i] !== newValue) {
|
|
178
240
|
cache[i] = dep.get()
|
|
179
|
-
|
|
241
|
+
|
|
242
|
+
const newValue = compute()
|
|
243
|
+
if (value !== newValue) {
|
|
244
|
+
value = newValue
|
|
245
|
+
Array.from(subscribers).forEach((cb) => cb())
|
|
246
|
+
}
|
|
180
247
|
}
|
|
181
248
|
}),
|
|
182
249
|
)
|
|
@@ -187,6 +254,7 @@ function createComputedArgs<
|
|
|
187
254
|
return () => {
|
|
188
255
|
subscribers.delete(callback)
|
|
189
256
|
if (subscribers.size === 0) {
|
|
257
|
+
value = empty
|
|
190
258
|
dispose.map((cb) => cb())
|
|
191
259
|
dispose.length = 0
|
|
192
260
|
cache.length = 0
|
|
@@ -195,15 +263,7 @@ function createComputedArgs<
|
|
|
195
263
|
}
|
|
196
264
|
|
|
197
265
|
const get = (): V => {
|
|
198
|
-
|
|
199
|
-
if (!cache[i]) {
|
|
200
|
-
cache[i] = dep.get()
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return cache[i]
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
return transform ? transform(...(args as Args)) : (args as V)
|
|
266
|
+
return value !== empty ? value : compute()
|
|
207
267
|
}
|
|
208
268
|
|
|
209
269
|
return new Accessor(get, subscribe)
|
|
@@ -303,7 +363,9 @@ export function createBinding<T>(object: GObject.Object | Gio.Settings, key: str
|
|
|
303
363
|
const get = (): T => {
|
|
304
364
|
if (object instanceof Gio.Settings) {
|
|
305
365
|
return object.get_value(key).recursiveUnpack() as T
|
|
306
|
-
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (object instanceof GObject.Object) {
|
|
307
369
|
const getter = `get_${prop.replaceAll("-", "_")}` as keyof typeof object
|
|
308
370
|
|
|
309
371
|
if (getter in object && typeof object[getter] === "function") {
|
|
@@ -312,9 +374,9 @@ export function createBinding<T>(object: GObject.Object | Gio.Settings, key: str
|
|
|
312
374
|
|
|
313
375
|
if (prop in object) return object[prop] as T
|
|
314
376
|
if (key in object) return object[key as keyof typeof object] as T
|
|
315
|
-
|
|
316
|
-
throw Error(`cannot get property ${key}`)
|
|
317
377
|
}
|
|
378
|
+
|
|
379
|
+
throw Error(`cannot get property "${key}" on "${object}"`)
|
|
318
380
|
}
|
|
319
381
|
|
|
320
382
|
return new Accessor(get, subscribe)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnim",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Aylur",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,12 +20,16 @@
|
|
|
20
20
|
"docs:preview": "vitepress preview docs"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
+
"@eslint/js": "latest",
|
|
23
24
|
"@girs/adw-1": "latest",
|
|
24
25
|
"@girs/clutter-16": "latest",
|
|
25
26
|
"@girs/gtk-3.0": "latest",
|
|
27
|
+
"@girs/gtk-4.0": "latest",
|
|
26
28
|
"@girs/soup-3.0": "latest",
|
|
29
|
+
"@girs/shell-16": "latest",
|
|
27
30
|
"@girs/st-16": "latest",
|
|
28
31
|
"@girs/gnome-shell": "latest",
|
|
32
|
+
"@girs/gjs": "latest",
|
|
29
33
|
"esbuild": "latest",
|
|
30
34
|
"eslint": "latest",
|
|
31
35
|
"typescript": "latest",
|