@gjsify/gtk-host 0.52.0 → 0.53.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
@@ -783,17 +783,16 @@ root.render(createElement('GtkBox', null, createElement('GtkLabel', { label: 'hi
783
783
 
784
784
  ```
785
785
  --define 'process.env.NODE_ENV="production"'
786
- --exclude-globals navigator
787
786
  ```
788
787
 
789
788
  `react-reconciler/index.js` picks its bundle from `process.env.NODE_ENV`, and the
790
789
  development one reaches for `document`, `HTMLCanvasElement` and `Path2D`, which
791
790
  makes `--globals auto` inject the GTK-backed DOM registers and pull `gi://Gdk`,
792
- `GdkPixbuf`, `Pango` and `PangoCairo` into a bundle that needs none of them. Even
793
- the production `scheduler` carries `typeof navigator !== 'undefined' &&
794
- navigator.scheduling`, dead code under GJS but still a free identifier the
795
- detector answers with the same register. With both flags the bundle loads with no
796
- `document` and no `navigator`, and a vector asserts exactly that.
791
+ `GdkPixbuf`, `Pango` and `PangoCairo` into a bundle that needs none of them. With
792
+ the define the bundle loads with no `document`, and a vector asserts exactly that.
793
+ The production `scheduler` still reads `navigator.scheduling` behind a `typeof`
794
+ guard; that reference now injects Node's DOM-free `navigator` from
795
+ `@gjsify/node-globals`, so it no longer needs `--exclude-globals navigator`.
797
796
 
798
797
  `react` and `react-reconciler` are OPTIONAL peer dependencies, like `solid-js` and
799
798
  `@vue/runtime-core`.
@@ -838,6 +837,54 @@ host's own `coerce()` path. A member the installed library lacks is accepted onl
838
837
  if the GIR says it arrived in a newer release — `GtkApplicationWindow::save-state`
839
838
  is GTK 4.24 and the check runs on 4.22.4.
840
839
 
840
+ ### A class the running GTK does not have
841
+
842
+ The table is generated from **one platform's GIR**, and a platform does not build every
843
+ class that GIR describes: GTK does not build its Unix print stack on Windows, so
844
+ `GtkPrintUnixDialog` and `GtkPageSetupUnixDialog` are rows whose class no Windows
845
+ `Gtk-4.0.typelib` registers (#1446 — six assertions of this suite failed on the first
846
+ GTK-bearing Windows leg, all of them this). The rows **stay**, for two measured
847
+ reasons. The GIR says they exist in that release, and the generator reads one GIR pool
848
+ with no second platform to compare against — a platform claim derived from a NAME
849
+ (`*Unix*`) breaks precisely when it matters, on the next absent class nobody spelled
850
+ that way, and a surface should not assert what it has not measured. And the two rows
851
+ are correct on the two platforms that do build them.
852
+
853
+ What the table must never do is hand a caller a class that resolved to `undefined`.
854
+ `classOf(descriptor)` is the one place that asks the only question answerable here — does
855
+ the **running** typelib have this class — and `requireClass(descriptor)` is that answer as
856
+ a named refusal (`err.absentClass`, code `absent-class`). Every read of a row's class
857
+ goes through it: `materialize`, `setProp`, `setEventHandler`, `setAccessibility`, the two
858
+ text-sink paths and the construction probe. So an omitted class is refused **by name at
859
+ the call that needed it**, instead of dying as
860
+ `Cannot read properties of undefined (reading 'list_properties')` or `… (reading '$gtype')`
861
+ — the two messages that arrived as six failures naming two classes between them.
862
+
863
+ A test that can only run where the defect is never runs, so the absent-class path is
864
+ **simulated** in `generated.spec.ts`: a descriptor whose `ctor()` answers `undefined` —
865
+ which is literally what `Gtk.PrintUnixDialog` is on a host that does not build it — driven
866
+ through every one of those paths, each expected to refuse with the same code and the
867
+ row's name. The sweeps that walk the whole table ask `classOf`/`hasClass` and treat an
868
+ absent row as *not a row*; `descriptorProblems()` says nothing about a class it cannot
869
+ resolve, and `explains every class the installed library does not have` is where an
870
+ absence is weighed against the library version **and printed by name** — the half that was
871
+ missing, and the reason those six took a hand to attribute.
872
+
873
+ The type surfaces (`generated/props.ts`) keep both dialogs, deliberately: they describe
874
+ the GIR's release, and `gjsify tsc` cannot check a type surface against an installed
875
+ typelib (rule 5 of the section above). A renderer on a platform that lacks the class meets
876
+ the runtime refusal at the call, not a compile error.
877
+
878
+ **The obvious oracle is wrong, and that is measured.** `GObject.type_from_name` is the
879
+ one-call version of "is this class installed" and it answers in the direction that costs
880
+ a *working* row: on gjs 1.88.1 / Homebrew GTK 4.24.0 `type_from_name('GtkPrintUnixDialog')`
881
+ answers **0** while `Gtk.PrintUnixDialog` is present and constructs — a typelib registers a
882
+ class when the namespace member is first **read**, not when the typelib loads. So a table
883
+ filtered by `type_from_name` drops two rows that are really there, on the platform that has
884
+ them. A row's own `ctor()` *is* that read, which is why it answers correctly in both
885
+ directions; an oracle over the whole table has to force the registration of every class it
886
+ walks, where a row is only ever asked about when something is about to use it.
887
+
841
888
  ### A base that leaves the namespace
842
889
 
843
890
  The generator reads `@girs/<ns>/vocabulary` (ADR 0029) for Gtk and Adw — the only two that
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{adderSlots as e,addressOf as t,classPlacementKind as n,isUnparented as r,placementOf as i,unhandledPlacement as a,unhandledPolicy as o}from"../policies.js";import{installAccessibilityBackend as s,withAtContext as c}from"./at-context.js";import{describeLogRecord as l,installDiagnosticsGate as u,isEnvironmentDiagnostic as d}from"./diagnostics.js";import{descendants as f,dumpTree as p,findDescendant as m,gtkChildTypes as h,gtkChildren as g}from"./tree.js";import{windowChromeCensus as _,windowChromeProblems as v}from"./window-chrome.js";import{buildSharedTree as y}from"./shared-tree-builder.js";import{BUILTIN_DESCRIPTORS as b}from"../descriptors/index.js";import x from"gi://GObject?version=2.0";function methodsOf(e){switch(e.kind){case`none`:case`uncurated`:return[];case`single`:return[e.set];case`ordered`:return e.after?[e.append,e.after,e.remove]:[e.append,e.remove];case`indexed`:return[e.insert,e.remove];case`slotted`:return e.remove?[...Object.values(e.slots),e.remove]:Object.values(e.slots);case`keyed`:return[e.add,e.remove];case`coords`:return[e.attach,e.remove];default:return o(e)}}function placementMethodsOf(e){switch(e.kind){case`parented`:return[];case`portal`:case`toplevel`:return[e.present,e.close];default:return a(e)}}function presentArityOf(e){switch(e.kind){case`parented`:return null;case`portal`:return 1;case`toplevel`:return 0;default:return a(e)}}function descriptorProblems(e=b){let t=[];for(let r of e){let e;try{e=r.ctor()}catch(e){t.push({gtype:r.gtype,problem:`ctor() threw: ${e.message}`});continue}if(!e)continue;let a=x.type_name(e.$gtype);a!==r.gtype&&t.push({gtype:r.gtype,problem:`ctor() is ${a}, not ${r.gtype}`});for(let n of methodsOf(r.children))typeof e.prototype[n]!=`function`&&t.push({gtype:r.gtype,problem:`declares children.${n}(), which ${a} does not have`});let o=i(r);for(let n of placementMethodsOf(o))typeof e.prototype[n]!=`function`&&t.push({gtype:r.gtype,problem:`declares placement.${n}(), which ${a} does not have`});let s=presentArityOf(o);if(s!==null&&o.kind!==`parented`){let n=e.prototype[o.present];typeof n==`function`&&n.length!==s&&t.push({gtype:r.gtype,problem:`placement.${o.present}() takes ${n.length} argument(s) on ${a}, and a ${o.kind} is presented with exactly ${s}`})}let c=e.prototype.present,l=n(e.$gtype,c);if(l&&o.kind===`parented`&&typeof c==`function`&&t.push({gtype:r.gtype,problem:l===`toplevel`?`implements Gtk.Root and declares no placement, so a parent would take it as an ordinary child — which GTK accepts at exit 0, leaving a root with a parent; it needs placement: { kind: 'toplevel', … }`:`has a present() that takes a parent and declares no placement, so a parent would call its adder on it — which is g_error() and aborts the process; it needs placement: { kind: 'portal', … }`}),r.textSink){let n=e.list_properties().find(e=>e.get_name()===r.textSink);n?(n.flags&x.ParamFlags.WRITABLE)===0?t.push({gtype:r.gtype,problem:`declares a READ-ONLY textSink "${r.textSink}"`}):x.type_is_a(n.value_type,x.TYPE_STRING)||t.push({gtype:r.gtype,problem:`declares textSink "${r.textSink}", which is ${x.type_name(n.value_type)}, not a string`}):t.push({gtype:r.gtype,problem:`declares textSink "${r.textSink}", which ${a} does not have`})}if(r.children.kind===`indexed`&&r.children.perLineCap!==void 0){let n=r.children.perLineCap,i=e.list_properties().find(e=>e.get_name()===n);i?(i.flags&x.ParamFlags.WRITABLE)===0?t.push({gtype:r.gtype,problem:`declares a READ-ONLY perLineCap "${n}"`}):x.type_is_a(i.value_type,x.TYPE_UINT)||t.push({gtype:r.gtype,problem:`declares perLineCap "${n}", which is ${x.type_name(i.value_type)}, not a count`}):t.push({gtype:r.gtype,problem:`declares perLineCap "${n}", which ${a} does not have`})}t.push(...policyProblems(r,e,a))}return t}function policyProblems(t,n,r){let i=[],a=n.prototype,o=t.children,requireGetter=(e,n)=>{let o=e.replace(/^set_/,`get_`);typeof a[o]!=`function`&&i.push({gtype:t.gtype,problem:`${n} uses ${e}() but ${r} has no ${o}(), so removal cannot check whether this child is still the one in place`})};if(o.kind===`single`&&requireGetter(o.set,`children.set`),o.kind===`slotted`){for(let[e,t]of Object.entries(o.slots))t.startsWith(`set_`)&&requireGetter(t,`slot "${e}"`);for(let e of Object.keys(o.wrapSlots??{}))e in o.slots||i.push({gtype:t.gtype,problem:`wrapSlots names "${e}", which is not one of ${Object.keys(o.slots).join(`, `)}`});o.defaultSlot in o.slots||i.push({gtype:t.gtype,problem:`defaultSlot "${o.defaultSlot}" is not one of ${Object.keys(o.slots).join(`, `)}`});let n=e(o);n.length>0&&!o.remove&&i.push({gtype:t.gtype,problem:`slot(s) ${n.map(e=>`"${e}"`).join(`, `)} are adder-backed, so removal needs a "remove" method and this policy names none`})}if(o.kind===`ordered`&&o.reorder===`native`&&!o.after&&i.push({gtype:t.gtype,problem:`claims reorder: 'native' with no "after" method — reorderMode() would tell an adapter the wrong thing`}),o.kind===`keyed`){let e=a[o.add],n=o.titled?3:1;typeof e==`function`&&e.length!==n&&i.push({gtype:t.gtype,problem:`titled: ${o.titled} implies ${o.add}() takes ${n} argument(s), but ${r}'s takes ${e.length}`})}return i}function addressesOf(e){let n=[];for(let i=e.first;i;i=i.next)i.kind===`element`&&i.widget&&!r(i)&&n.push(t(i));return n}export{addressesOf,y as buildSharedTree,f as descendants,l as describeLogRecord,descriptorProblems,p as dumpTree,m as findDescendant,h as gtkChildTypes,g as gtkChildren,s as installAccessibilityBackend,u as installDiagnosticsGate,d as isEnvironmentDiagnostic,methodsOf,placementMethodsOf,presentArityOf,_ as windowChromeCensus,v as windowChromeProblems,c as withAtContext};
1
+ import"../_virtual/_rolldown/runtime.js";import{classOf as e}from"../registry.js";import{adderSlots as t,addressOf as n,classPlacementKind as r,isUnparented as i,placementOf as a,unhandledPlacement as o,unhandledPolicy as s}from"../policies.js";import{installAccessibilityBackend as c,withAtContext as l}from"./at-context.js";import{describeLogRecord as u,installDiagnosticsGate as d,isEnvironmentDiagnostic as f}from"./diagnostics.js";import{descendants as p,dumpTree as m,findDescendant as h,gtkChildTypes as g,gtkChildren as _}from"./tree.js";import{windowChromeCensus as v,windowChromeProblems as y}from"./window-chrome.js";import{buildSharedTree as b}from"./shared-tree-builder.js";import{BUILTIN_DESCRIPTORS as x}from"../descriptors/index.js";import S from"gi://GObject?version=2.0";function methodsOf(e){switch(e.kind){case`none`:case`uncurated`:return[];case`single`:return[e.set];case`ordered`:return e.after?[e.append,e.after,e.remove]:[e.append,e.remove];case`indexed`:return[e.insert,e.remove];case`slotted`:return e.remove?[...Object.values(e.slots),e.remove]:Object.values(e.slots);case`keyed`:return[e.add,e.remove];case`coords`:return[e.attach,e.remove];default:return s(e)}}function placementMethodsOf(e){switch(e.kind){case`parented`:return[];case`portal`:case`toplevel`:return[e.present,e.close];default:return o(e)}}function presentArityOf(e){switch(e.kind){case`parented`:return null;case`portal`:return 1;case`toplevel`:return 0;default:return o(e)}}function descriptorProblems(t=x){let n=[];for(let i of t){let t;try{t=e(i)}catch(e){n.push({gtype:i.gtype,problem:`ctor() threw: ${e.message}`});continue}if(!t)continue;let o=S.type_name(t.$gtype);o!==i.gtype&&n.push({gtype:i.gtype,problem:`ctor() is ${o}, not ${i.gtype}`});for(let e of methodsOf(i.children))typeof t.prototype[e]!=`function`&&n.push({gtype:i.gtype,problem:`declares children.${e}(), which ${o} does not have`});let s=a(i);for(let e of placementMethodsOf(s))typeof t.prototype[e]!=`function`&&n.push({gtype:i.gtype,problem:`declares placement.${e}(), which ${o} does not have`});let c=presentArityOf(s);if(c!==null&&s.kind!==`parented`){let e=t.prototype[s.present];typeof e==`function`&&e.length!==c&&n.push({gtype:i.gtype,problem:`placement.${s.present}() takes ${e.length} argument(s) on ${o}, and a ${s.kind} is presented with exactly ${c}`})}let l=t.prototype.present,u=r(t.$gtype,l);if(u&&s.kind===`parented`&&typeof l==`function`&&n.push({gtype:i.gtype,problem:u===`toplevel`?`implements Gtk.Root and declares no placement, so a parent would take it as an ordinary child — which GTK accepts at exit 0, leaving a root with a parent; it needs placement: { kind: 'toplevel', … }`:`has a present() that takes a parent and declares no placement, so a parent would call its adder on it — which is g_error() and aborts the process; it needs placement: { kind: 'portal', … }`}),i.textSink){let e=t.list_properties().find(e=>e.get_name()===i.textSink);e?(e.flags&S.ParamFlags.WRITABLE)===0?n.push({gtype:i.gtype,problem:`declares a READ-ONLY textSink "${i.textSink}"`}):S.type_is_a(e.value_type,S.TYPE_STRING)||n.push({gtype:i.gtype,problem:`declares textSink "${i.textSink}", which is ${S.type_name(e.value_type)}, not a string`}):n.push({gtype:i.gtype,problem:`declares textSink "${i.textSink}", which ${o} does not have`})}if(i.children.kind===`indexed`&&i.children.perLineCap!==void 0){let e=i.children.perLineCap,r=t.list_properties().find(t=>t.get_name()===e);r?(r.flags&S.ParamFlags.WRITABLE)===0?n.push({gtype:i.gtype,problem:`declares a READ-ONLY perLineCap "${e}"`}):S.type_is_a(r.value_type,S.TYPE_UINT)||n.push({gtype:i.gtype,problem:`declares perLineCap "${e}", which is ${S.type_name(r.value_type)}, not a count`}):n.push({gtype:i.gtype,problem:`declares perLineCap "${e}", which ${o} does not have`})}n.push(...policyProblems(i,t,o))}return n}function policyProblems(e,n,r){let i=[],a=n.prototype,o=e.children,requireGetter=(t,n)=>{let o=t.replace(/^set_/,`get_`);typeof a[o]!=`function`&&i.push({gtype:e.gtype,problem:`${n} uses ${t}() but ${r} has no ${o}(), so removal cannot check whether this child is still the one in place`})};if(o.kind===`single`&&requireGetter(o.set,`children.set`),o.kind===`slotted`){for(let[e,t]of Object.entries(o.slots))t.startsWith(`set_`)&&requireGetter(t,`slot "${e}"`);for(let t of Object.keys(o.wrapSlots??{}))t in o.slots||i.push({gtype:e.gtype,problem:`wrapSlots names "${t}", which is not one of ${Object.keys(o.slots).join(`, `)}`});o.defaultSlot in o.slots||i.push({gtype:e.gtype,problem:`defaultSlot "${o.defaultSlot}" is not one of ${Object.keys(o.slots).join(`, `)}`});let n=t(o);n.length>0&&!o.remove&&i.push({gtype:e.gtype,problem:`slot(s) ${n.map(e=>`"${e}"`).join(`, `)} are adder-backed, so removal needs a "remove" method and this policy names none`})}if(o.kind===`ordered`&&o.reorder===`native`&&!o.after&&i.push({gtype:e.gtype,problem:`claims reorder: 'native' with no "after" method — reorderMode() would tell an adapter the wrong thing`}),o.kind===`keyed`){let t=a[o.add],n=o.titled?3:1;typeof t==`function`&&t.length!==n&&i.push({gtype:e.gtype,problem:`titled: ${o.titled} implies ${o.add}() takes ${n} argument(s), but ${r}'s takes ${t.length}`})}return i}function addressesOf(e){let t=[];for(let r=e.first;r;r=r.next)r.kind===`element`&&r.widget&&!i(r)&&t.push(n(r));return t}export{addressesOf,b as buildSharedTree,p as descendants,u as describeLogRecord,descriptorProblems,m as dumpTree,h as findDescendant,g as gtkChildTypes,_ as gtkChildren,c as installAccessibilityBackend,d as installDiagnosticsGate,f as isEnvironmentDiagnostic,methodsOf,placementMethodsOf,presentArityOf,v as windowChromeCensus,y as windowChromeProblems,l as withAtContext};
package/lib/esm/errors.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";var GtkHostError=class extends Error{constructor(e,t){super(t),this.code=e,this.name=`GtkHostError`}};const e={unknownTag:e=>new GtkHostError(`unknown-tag`,`No descriptor registered for <${e}>. Register one with registerWidget({ gtype: '${e}', … }). Being a real GType in the installed typelib is not enough on its own.`),missingConstructProp:(e,t)=>new GtkHostError(`missing-construct-prop`,`<${e}> cannot be constructed without ${t}. In the installed library this is not an exception but a g_error(): the process ABORTS (SIGABRT, exit 134, core dump) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. Author ${t} on the element.`),unknownProp:(e,t)=>new GtkHostError(`unknown-prop`,`<${e}> has no property "${t}". Check the spelling against the installed GTK (camelCase and kebab-case both resolve), or bind it as a signal with on${t[0]?.toUpperCase()}${t.slice(1)}.`),readOnlyProp:(e,t)=>new GtkHostError(`read-only-prop`,`<${e}>.${t} is read-only in the installed GTK. Writing it is a silent no-op in GObject, so this host refuses it instead of dropping the value.`),noAccessor:(e,t,n)=>new GtkHostError(`no-accessor`,`<${e}>.${t} has to be written through its JS accessor — a null or a list cannot be handed to set_property, which guesses a GType and finds none — and GJS installed no "${n}" on this object. Assigning it anyway would create a plain JS property: no GObject write, no error, and notify::${t} never fires.`),badDetailedAction:(e,t,n)=>new GtkHostError(`bad-detailed-action`,`The menu item "${e}" names the action ${JSON.stringify(t)}, which GIO cannot parse: ${n}. In the installed GIO this is not an exception but a g_error() inside g_menu_item_set_detailed_action: the process ABORTS (SIGABRT, exit 134) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. A detailed action name is "app.act", "app.act::target" or "app.act(variant)".`),badListModel:(e,t,n)=>new GtkHostError(`bad-list-model`,`<${e}>.${t} is a Gio.ListModel and got ${n}. Write the portable list model — an array of strings or of { value, label } descriptors (ADR 0046) — or a real Gio.ListModel. Anything else reaches set_property as a value GObject cannot store: a CRITICAL at exit 0 and an EMPTY list, which a reader cannot tell from "no items yet".`),listModelMismatch:(e,t,n)=>new GtkHostError(`list-model-mismatch`,`<${e}>.${t} is a ${n}, and the portable list model becomes a Gtk.StringList — a Gio.ListModel, not a ${n}. GObject would turn that write into NULL without a diagnostic and leave the widget empty at exit 0. Wrap it yourself (Gtk.NoSelection.new(new Gtk.StringList({ strings }))), or use @gjsify/gtk-host/list for a factory-driven view.`),badAdjustment:(e,t,n)=>new GtkHostError(`bad-adjustment`,`<${e}>.${t} is a Gtk.Adjustment and got ${n}. Write the portable adjustment — an object naming any of value, lower, upper, stepIncrement, pageIncrement, pageSize (ADR 0047) — or a real Gtk.Adjustment. A bare number is refused on purpose: it would be the value, and value is a property of its own on every widget that takes an adjustment, so ${t}={3} and value={3} would be two spellings of one write.`),badAccessibility:(e,t)=>new GtkHostError(`bad-accessibility`,`<${e}> accessibility takes an object of ARIA names and got ${t}. Write accessibility={{ label: "Save", "row-index": 3 }} — one object, the names GTK's own accessibility block uses — or null to clear everything it set.`),unknownAria:(e,t)=>new GtkHostError(`unknown-aria`,`<${e}> accessibility has no name "${t}". The names are GTK's three ARIA tables — the members of GtkAccessibleProperty, GtkAccessibleState and GtkAccessibleRelation, kebab-spelled (label, has-popup, checked, row-index) — and they are NOT the widget's properties: "orientation" is settable on a GtkLabel that implements no GtkOrientable at all.`),ariaNotInstalled:(e,t,n)=>new GtkHostError(`aria-not-installed`,`<${e}> accessibility names "${t}", which this package's table has and the installed GTK's ${n} does not — it arrived in a newer release. Upgrade GTK, or drop the name: writing it anyway is two criticals and an unset slot at exit 0.`),badAriaValue:(e,t,n,r)=>new GtkHostError(`bad-aria-value`,`<${e}> accessibility "${t}" is typed ${n} in GTK's ARIA table and got ${r}. GTK builds no GValue of its own here — it reads back the one the caller passed with a fixed g_value_get_* — so a wrong type is a critical at exit 0 and nothing readable in the slot; measured, the slot still reports as SET afterwards for two of the three types it was tried on, which is why presence is not an oracle here. GJS guesses the GValue type from a NUMBER's integrality: 3 is an int and 3.5 a double, so a double slot written 3 goes missing and an integer slot written 3.5 does too.`),badAriaEnum:(e,t,n,r)=>new GtkHostError(`bad-aria-enum`,`<${e}> accessibility "${t}" expects ${r}, and "${n}" is not one of its values. The ARIA tables type these slots themselves and disagree with the widget where it matters: checked is a GtkAccessibleTristate, so "true" is a nick and the boolean true is a wrong GValue GTK drops without a word.`),ariaReference:(e,t)=>new GtkHostError(`aria-reference`,`<${e}> accessibility "${t}" points at ANOTHER widget, and this host has no way to name one: there is no id prop, and a framework ref is resolved after these props are applied. Set the relation imperatively for now — ref={(w) => w.update_relation([Gtk.AccessibleRelation.${t.toUpperCase().replace(/-/g,`_`)}], [Gtk.AccessibleList.new_from_list([other])])} — where you already hold both widgets.`),notAccessible:e=>new GtkHostError(`not-accessible`,`<${e}> is not a Gtk.Accessible, so accessibility has nowhere to go on it. Not every row of the generated table is a widget — the list carriers are plain GObjects that HOLD one — and those have no update_property at all (measured on Gtk.StringList). Put the accessibility on the widget that renders.`),badEnum:(e,t,n,r)=>new GtkHostError(`bad-enum`,`<${e}>.${t} expects ${r}, and "${n}" is not one of its values. Note that GObject accepts the wrong string SILENTLY — the property would have kept its old value.`),unknownSignal:(e,t,n)=>new GtkHostError(`unknown-signal`,`<${e}> emits no signal "${n}" (bound as ${t}). Check the spelling against the installed GTK, or use the escape hatch on:<raw-signal-name> if the name is irregular.`),signalTaken:(e,t,n,r)=>new GtkHostError(`signal-taken`,`<${e}> already binds "${r}" through ${n}, so ${t} would silently replace it — GObject has one handler per connect, and this host keeps one per signal name. Use one spelling, or combine the two callbacks yourself.`),eventModifier:(e,t)=>new GtkHostError(`event-modifier`,`${e} carries the DOM listener modifier ".${t}", which has no GObject meaning: a signal is emitted on one object and does not propagate through a tree, so there is no capture phase and nothing to be passive about. Drop the modifier (${e.slice(0,e.length-t.length)}); for GTK4's own propagation phases set "propagation-phase" on a Gtk.EventController instead.`),badString:(e,t,n)=>new GtkHostError(`bad-string`,`<${e}>.${t} is a string property and got a ${n}. Numbers and booleans are stringified; anything else has no unambiguous spelling, and GObject would have thrown from inside the next rebuild.`),badBoolean:(e,t,n)=>new GtkHostError(`bad-boolean`,`<${e}>.${t} is a boolean and got the string "${n}". JS truthiness would make "false" mean TRUE — the exact silent-wrong-value this host exists to refuse. Pass a real boolean.`),badFlags:(e,t,n,r)=>new GtkHostError(`bad-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" names a member it does not have. Join the member nicks with "|" ("spellcheck|lowercase"), or pass the numeric value. GObject would have dropped the string silently.`),blankFlags:(e,t,n,r)=>new GtkHostError(`blank-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" has an empty member. GTK reads an empty flags string as 0 — every flag cleared, no diagnostic — so this host refuses it. Drop the stray "|", or write the members you mean.`),textNotAccepted:(e,t)=>new GtkHostError(`text-not-accepted`,`<${e}> has no text sink, so the text ${JSON.stringify(t.slice(0,32))} has nowhere to go. Wrap it in a widget that takes text (<GtkLabel>), or set the property directly.`),unclaimedChild:(e,t)=>new GtkHostError(`unclaimed-child`,`<${e}> declares children: { kind: 'none' }, so it cannot adopt <${t}>. Fix one of three things: give the parent a child policy, wrap the child in a container, or set the child on a property (e.g. a "child" or "content" property).`),unknownSlot:(e,t,n)=>new GtkHostError(`unknown-slot`,`<${e}> has no slot "${t}". Known slots: ${n.length>0?n.join(`, `):`none — it declares no slot names`}.`),slotNeedsRemove:(e,t,n)=>new GtkHostError(`slot-needs-remove`,`<${e}> puts children into slot "${t}" with ${n}() and its policy names no "remove" method, so this child cannot be taken out again. A set_-prefixed slot is emptied by writing null back through the setter and needs nothing; an adder-backed one needs children.remove. Add it to the descriptor.`),rejectedChild:(e,t,n)=>new GtkHostError(`rejected-child`,`<${e}> refused <${t}>: ${n}. The container accepts only certain child types (e.g. AdwPreferencesPage takes AdwPreferencesGroup); the descriptor cannot know that, GTK does.`),uncuratedPlacement:(e,t)=>new GtkHostError(`uncurated-placement`,`<${e}> comes from the GENERATED table, which knows the tag but not how the widget adopts a child, so it cannot take <${t}>. Guessing is the one thing that is not available here: \`add\`, \`append\` and \`set_child\` all exist somewhere in GTK and calling the wrong one is a warning at exit 0. Add a curated policy for ${e} in descriptors/, or mount into a container that has one.`),siblingCycle:e=>new GtkHostError(`sibling-cycle`,`The child list of <${e}> does not terminate. A renderer linked a node to itself or into a loop; the host refuses to walk it rather than spin. This is a host or adapter bug, not an application one — please report it with the reordering that produced it.`),notAWidget:e=>new GtkHostError(`not-a-widget`,`<${e}> is not a Gtk.Widget, so it cannot be placed as a child. Non-widget GObjects (controllers, filters, models) attach to a property, not to a parent.`),occupiedSlot:(e,t,n)=>new GtkHostError(`occupied-slot`,`<${e}> already holds a child the application put there, and ${n}() takes only ONE — placing <${t}> would unparent it. GTK does that silently: no throw, no warning, exit 0, and the application's own widget is simply gone. Mount into a container of your own inside <${e}>, or clear the existing child first (${n}(null)) if replacing it is the intent.`),placementMethodMissing:(e,t,n,r)=>new GtkHostError(`placement-method-missing`,`<${e}> declares placement: { kind: '${t}', ${r}: '${n}' } and the installed class has no ${n}(). A node with this placement is placed by calling that method on the node itself — nothing goes into the parent — so without it the node can never reach the screen and never leave it. Fix the descriptor, or drop the placement and give the widget an ordinary child policy.`),unparentableChild:(e,t,n,r)=>new GtkHostError(`unparentable-child`,`<${e}> cannot adopt <${t}>: ${r}. In the installed libraries placing it anyway is not an exception — it is either a g_error() that ABORTS the process (SIGABRT, exit 134, no catch, no diagnostic) or an acceptance at exit 0 that leaves a root inside a child list — so the host refuses here while a refusal is still reportable. Declare placement: { kind: '${n}', … } on the descriptor for <${t}> so the host places it the way the library does, or, if this widget really is an ordinary child, say so with placement: { kind: 'parented' }.`),notAnElement:e=>new GtkHostError(`not-an-element`,`Only an element node owns a widget, and this node is a ${e}. A text node's content lives in its PARENT's text sink and an anchor owns nothing at all — neither has a widget to hand back. Ask the parent element instead.`),destroyedNode:e=>new GtkHostError(`destroyed-node`,`<${e}> was destroyed, so its widget is gone. Asking again would MATERIALISE a fresh, propertyless, unparented widget — \`destroy\` clears props and layout precisely so a destroyed element cannot look re-materialisable — and a caller holding that widget would be looking at nothing on screen.`),notAHostParent:e=>new GtkHostError(`not-a-host-parent`,`insert() needs a host element as the parent and got ${e}. A raw widget cannot be one: the shadow tree lives in the host's own fields, so writing them onto a GObject wrapper renders nothing and reports nothing — Vue's <Teleport to="someWidget"> hands the widget through verbatim and landed exactly here. Wrap it with adopt(widget) first, which is what mountRoot() does.`)};export{GtkHostError,e as err};
1
+ import"./_virtual/_rolldown/runtime.js";var GtkHostError=class extends Error{constructor(e,t){super(t),this.code=e,this.name=`GtkHostError`}};const e={unknownTag:e=>new GtkHostError(`unknown-tag`,`No descriptor registered for <${e}>. Register one with registerWidget({ gtype: '${e}', … }). Being a real GType in the installed typelib is not enough on its own.`),absentClass:e=>new GtkHostError(`absent-class`,`<${e}> is in the widget table and the running GTK has no class for it. The table is generated from one GIR, on one host, and a platform omits what it does not build — GTK does not build its Unix print dialogs on Windows, so no typelib there registers them. Use a widget this GTK really has (the portable print dialog is GtkPrintDialog, not GtkPrintUnixDialog), and expect the same refusal for any class a future platform drops.`),missingConstructProp:(e,t)=>new GtkHostError(`missing-construct-prop`,`<${e}> cannot be constructed without ${t}. In the installed library this is not an exception but a g_error(): the process ABORTS (SIGABRT, exit 134, core dump) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. Author ${t} on the element.`),unknownProp:(e,t)=>new GtkHostError(`unknown-prop`,`<${e}> has no property "${t}". Check the spelling against the installed GTK (camelCase and kebab-case both resolve), or bind it as a signal with on${t[0]?.toUpperCase()}${t.slice(1)}.`),readOnlyProp:(e,t)=>new GtkHostError(`read-only-prop`,`<${e}>.${t} is read-only in the installed GTK. Writing it is a silent no-op in GObject, so this host refuses it instead of dropping the value.`),noAccessor:(e,t,n)=>new GtkHostError(`no-accessor`,`<${e}>.${t} has to be written through its JS accessor — a null or a list cannot be handed to set_property, which guesses a GType and finds none — and GJS installed no "${n}" on this object. Assigning it anyway would create a plain JS property: no GObject write, no error, and notify::${t} never fires.`),badDetailedAction:(e,t,n)=>new GtkHostError(`bad-detailed-action`,`The menu item "${e}" names the action ${JSON.stringify(t)}, which GIO cannot parse: ${n}. In the installed GIO this is not an exception but a g_error() inside g_menu_item_set_detailed_action: the process ABORTS (SIGABRT, exit 134) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. A detailed action name is "app.act", "app.act::target" or "app.act(variant)".`),badListModel:(e,t,n)=>new GtkHostError(`bad-list-model`,`<${e}>.${t} is a Gio.ListModel and got ${n}. Write the portable list model — an array of strings or of { value, label } descriptors (ADR 0046) — or a real Gio.ListModel. Anything else reaches set_property as a value GObject cannot store: a CRITICAL at exit 0 and an EMPTY list, which a reader cannot tell from "no items yet".`),listModelMismatch:(e,t,n)=>new GtkHostError(`list-model-mismatch`,`<${e}>.${t} is a ${n}, and the portable list model becomes a Gtk.StringList — a Gio.ListModel, not a ${n}. GObject would turn that write into NULL without a diagnostic and leave the widget empty at exit 0. Wrap it yourself (Gtk.NoSelection.new(new Gtk.StringList({ strings }))), or use @gjsify/gtk-host/list for a factory-driven view.`),badAdjustment:(e,t,n)=>new GtkHostError(`bad-adjustment`,`<${e}>.${t} is a Gtk.Adjustment and got ${n}. Write the portable adjustment — an object naming any of value, lower, upper, stepIncrement, pageIncrement, pageSize (ADR 0047) — or a real Gtk.Adjustment. A bare number is refused on purpose: it would be the value, and value is a property of its own on every widget that takes an adjustment, so ${t}={3} and value={3} would be two spellings of one write.`),badAccessibility:(e,t)=>new GtkHostError(`bad-accessibility`,`<${e}> accessibility takes an object of ARIA names and got ${t}. Write accessibility={{ label: "Save", "row-index": 3 }} — one object, the names GTK's own accessibility block uses — or null to clear everything it set.`),unknownAria:(e,t)=>new GtkHostError(`unknown-aria`,`<${e}> accessibility has no name "${t}". The names are GTK's three ARIA tables — the members of GtkAccessibleProperty, GtkAccessibleState and GtkAccessibleRelation, kebab-spelled (label, has-popup, checked, row-index) — and they are NOT the widget's properties: "orientation" is settable on a GtkLabel that implements no GtkOrientable at all.`),ariaNotInstalled:(e,t,n)=>new GtkHostError(`aria-not-installed`,`<${e}> accessibility names "${t}", which this package's table has and the installed GTK's ${n} does not — it arrived in a newer release. Upgrade GTK, or drop the name: writing it anyway is two criticals and an unset slot at exit 0.`),badAriaValue:(e,t,n,r)=>new GtkHostError(`bad-aria-value`,`<${e}> accessibility "${t}" is typed ${n} in GTK's ARIA table and got ${r}. GTK builds no GValue of its own here — it reads back the one the caller passed with a fixed g_value_get_* — so a wrong type is a critical at exit 0 and nothing readable in the slot; measured, the slot still reports as SET afterwards for two of the three types it was tried on, which is why presence is not an oracle here. GJS guesses the GValue type from a NUMBER's integrality: 3 is an int and 3.5 a double, so a double slot written 3 goes missing and an integer slot written 3.5 does too.`),badAriaEnum:(e,t,n,r)=>new GtkHostError(`bad-aria-enum`,`<${e}> accessibility "${t}" expects ${r}, and "${n}" is not one of its values. The ARIA tables type these slots themselves and disagree with the widget where it matters: checked is a GtkAccessibleTristate, so "true" is a nick and the boolean true is a wrong GValue GTK drops without a word.`),ariaReference:(e,t)=>new GtkHostError(`aria-reference`,`<${e}> accessibility "${t}" points at ANOTHER widget, and this host has no way to name one: there is no id prop, and a framework ref is resolved after these props are applied. Set the relation imperatively for now — ref={(w) => w.update_relation([Gtk.AccessibleRelation.${t.toUpperCase().replace(/-/g,`_`)}], [Gtk.AccessibleList.new_from_list([other])])} — where you already hold both widgets.`),notAccessible:e=>new GtkHostError(`not-accessible`,`<${e}> is not a Gtk.Accessible, so accessibility has nowhere to go on it. Not every row of the generated table is a widget — the list carriers are plain GObjects that HOLD one — and those have no update_property at all (measured on Gtk.StringList). Put the accessibility on the widget that renders.`),badEnum:(e,t,n,r)=>new GtkHostError(`bad-enum`,`<${e}>.${t} expects ${r}, and "${n}" is not one of its values. Note that GObject accepts the wrong string SILENTLY — the property would have kept its old value.`),unknownSignal:(e,t,n)=>new GtkHostError(`unknown-signal`,`<${e}> emits no signal "${n}" (bound as ${t}). Check the spelling against the installed GTK, or use the escape hatch on:<raw-signal-name> if the name is irregular.`),signalTaken:(e,t,n,r)=>new GtkHostError(`signal-taken`,`<${e}> already binds "${r}" through ${n}, so ${t} would silently replace it — GObject has one handler per connect, and this host keeps one per signal name. Use one spelling, or combine the two callbacks yourself.`),eventModifier:(e,t)=>new GtkHostError(`event-modifier`,`${e} carries the DOM listener modifier ".${t}", which has no GObject meaning: a signal is emitted on one object and does not propagate through a tree, so there is no capture phase and nothing to be passive about. Drop the modifier (${e.slice(0,e.length-t.length)}); for GTK4's own propagation phases set "propagation-phase" on a Gtk.EventController instead.`),badString:(e,t,n)=>new GtkHostError(`bad-string`,`<${e}>.${t} is a string property and got a ${n}. Numbers and booleans are stringified; anything else has no unambiguous spelling, and GObject would have thrown from inside the next rebuild.`),badBoolean:(e,t,n)=>new GtkHostError(`bad-boolean`,`<${e}>.${t} is a boolean and got the string "${n}". JS truthiness would make "false" mean TRUE — the exact silent-wrong-value this host exists to refuse. Pass a real boolean.`),badFlags:(e,t,n,r)=>new GtkHostError(`bad-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" names a member it does not have. Join the member nicks with "|" ("spellcheck|lowercase"), or pass the numeric value. GObject would have dropped the string silently.`),blankFlags:(e,t,n,r)=>new GtkHostError(`blank-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" has an empty member. GTK reads an empty flags string as 0 — every flag cleared, no diagnostic — so this host refuses it. Drop the stray "|", or write the members you mean.`),textNotAccepted:(e,t)=>new GtkHostError(`text-not-accepted`,`<${e}> has no text sink, so the text ${JSON.stringify(t.slice(0,32))} has nowhere to go. Wrap it in a widget that takes text (<GtkLabel>), or set the property directly.`),unclaimedChild:(e,t)=>new GtkHostError(`unclaimed-child`,`<${e}> declares children: { kind: 'none' }, so it cannot adopt <${t}>. Fix one of three things: give the parent a child policy, wrap the child in a container, or set the child on a property (e.g. a "child" or "content" property).`),unknownSlot:(e,t,n)=>new GtkHostError(`unknown-slot`,`<${e}> has no slot "${t}". Known slots: ${n.length>0?n.join(`, `):`none — it declares no slot names`}.`),slotNeedsRemove:(e,t,n)=>new GtkHostError(`slot-needs-remove`,`<${e}> puts children into slot "${t}" with ${n}() and its policy names no "remove" method, so this child cannot be taken out again. A set_-prefixed slot is emptied by writing null back through the setter and needs nothing; an adder-backed one needs children.remove. Add it to the descriptor.`),rejectedChild:(e,t,n)=>new GtkHostError(`rejected-child`,`<${e}> refused <${t}>: ${n}. The container accepts only certain child types (e.g. AdwPreferencesPage takes AdwPreferencesGroup); the descriptor cannot know that, GTK does.`),uncuratedPlacement:(e,t)=>new GtkHostError(`uncurated-placement`,`<${e}> comes from the GENERATED table, which knows the tag but not how the widget adopts a child, so it cannot take <${t}>. Guessing is the one thing that is not available here: \`add\`, \`append\` and \`set_child\` all exist somewhere in GTK and calling the wrong one is a warning at exit 0. Add a curated policy for ${e} in descriptors/, or mount into a container that has one.`),siblingCycle:e=>new GtkHostError(`sibling-cycle`,`The child list of <${e}> does not terminate. A renderer linked a node to itself or into a loop; the host refuses to walk it rather than spin. This is a host or adapter bug, not an application one — please report it with the reordering that produced it.`),notAWidget:e=>new GtkHostError(`not-a-widget`,`<${e}> is not a Gtk.Widget, so it cannot be placed as a child. Non-widget GObjects (controllers, filters, models) attach to a property, not to a parent.`),occupiedSlot:(e,t,n)=>new GtkHostError(`occupied-slot`,`<${e}> already holds a child the application put there, and ${n}() takes only ONE — placing <${t}> would unparent it. GTK does that silently: no throw, no warning, exit 0, and the application's own widget is simply gone. Mount into a container of your own inside <${e}>, or clear the existing child first (${n}(null)) if replacing it is the intent.`),placementMethodMissing:(e,t,n,r)=>new GtkHostError(`placement-method-missing`,`<${e}> declares placement: { kind: '${t}', ${r}: '${n}' } and the installed class has no ${n}(). A node with this placement is placed by calling that method on the node itself — nothing goes into the parent — so without it the node can never reach the screen and never leave it. Fix the descriptor, or drop the placement and give the widget an ordinary child policy.`),unparentableChild:(e,t,n,r)=>new GtkHostError(`unparentable-child`,`<${e}> cannot adopt <${t}>: ${r}. In the installed libraries placing it anyway is not an exception — it is either a g_error() that ABORTS the process (SIGABRT, exit 134, no catch, no diagnostic) or an acceptance at exit 0 that leaves a root inside a child list — so the host refuses here while a refusal is still reportable. Declare placement: { kind: '${n}', … } on the descriptor for <${t}> so the host places it the way the library does, or, if this widget really is an ordinary child, say so with placement: { kind: 'parented' }.`),notAnElement:e=>new GtkHostError(`not-an-element`,`Only an element node owns a widget, and this node is a ${e}. A text node's content lives in its PARENT's text sink and an anchor owns nothing at all — neither has a widget to hand back. Ask the parent element instead.`),destroyedNode:e=>new GtkHostError(`destroyed-node`,`<${e}> was destroyed, so its widget is gone. Asking again would MATERIALISE a fresh, propertyless, unparented widget — \`destroy\` clears props and layout precisely so a destroyed element cannot look re-materialisable — and a caller holding that widget would be looking at nothing on screen.`),notAHostParent:e=>new GtkHostError(`not-a-host-parent`,`insert() needs a host element as the parent and got ${e}. A raw widget cannot be one: the shadow tree lives in the host's own fields, so writing them onto a GObject wrapper renders nothing and reports nothing — Vue's <Teleport to="someWidget"> hands the widget through verbatim and landed exactly here. Wrap it with adopt(widget) first, which is what mountRoot() does.`)};export{GtkHostError,e as err};
package/lib/esm/fonts.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{isFontFace as e,resolveFontSources as t}from"./font-dir.js";import{describeFontFamilyMatch as n,matchFontFamilies as r,matchFontFamily as i}from"./font-families.js";import{ADWAITA_UI_FONT_FAMILY as a,GNOME_UI_FONT_POINT_SIZE as o,UI_FONT_POLICIES as s,planUiFont as c,planUiFontPolicy as l}from"./ui-font.js";import u from"gi://Gtk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://GLib?version=2.0";import p from"gi://PangoCairo?version=1.0";function isUnsupportedByFontMap(e){return e instanceof f.Error&&e.matches(d.io_error_quark(),d.IOErrorEnum.NOT_SUPPORTED)}function initFonts(e={}){let i=t({...e,env:{GJSIFY_FONT_DIR:f.getenv(`GJSIFY_FONT_DIR`)??void 0,GJSIFY_GTK_RUNTIME_FONT_DIR:f.getenv(`GJSIFY_GTK_RUNTIME_FONT_DIR`)??void 0}}),a=i.find(e=>e.origin===`app`)?.dir,o=[],s=[],c=[],l=[],u=e.expectedFamilies??[];if(i.length===0&&u.length===0)return{dir:a,sources:o,uiFont:void 0,registered:s,declined:c,failed:l,families:[],matches:[]};let m=p.FontMap.get_default(),h=i.length===0?[]:familyNames(m);for(let e of i){let t=[],n=[],r=[],i=[];collectFaces(d.File.new_for_path(e.dir),t,i);for(let e of t.sort())try{m.add_font_file(e),n.push(e)}catch(t){if(isUnsupportedByFontMap(t)){r.push(e);continue}i.push({path:e,message:messageOf(t)})}s.push(...n),c.push(...r),l.push(...i),o.push({...e,registered:n,declined:r,failed:i})}let g=familyNames(m),_=i.length===0?[]:g.filter(e=>!h.includes(e)).sort(),v=r(u,g);captureUiFontBaseline();let y=e.uiFont===void 0?void 0:applyUiFontPolicy(e.uiFont);for(let e of l)console.warn(`initFonts: ${e.path} could not be read as an application font (${e.message}). Text asking for a family this application ships will render in a substituted one.`);for(let e of v)e.kind!==`exact`&&console.warn(`initFonts: ${n(e)}`);return{dir:a,sources:o,uiFont:y,registered:s,declined:c,failed:l,families:_,matches:v}}let m=!1,h;function captureUiFontBaseline(){if(m)return h;let e=u.Settings.get_default();if(e!==null)return h=e.gtk_font_name??void 0,m=!0,h}function uiFontBaseline(){return captureUiFontBaseline()}function applyUiFontPolicy(e){let t=typeof e==`string`?{policy:e}:e,n=t.settings===void 0?u.Settings.get_default():t.settings;if(n===null)return console.warn("applyUiFontPolicy: no Gtk.Settings — the toolkit is not initialised yet, so the policy was NOT applied. Call this after Gtk.init() (or from an application's `startup`), which is still before any window is built."),{next:void 0,kind:`uninitialised`,family:void 0,size:void 0};let r=captureUiFontBaseline(),i=l({...t,family:t.family??resolvedAdwaitaFamily(t.policy),current:n.gtk_font_name??void 0,baseline:r});return i.next===void 0||(n.gtk_font_name=i.next),i}function resolvedAdwaitaFamily(e){if(e!==`adwaita`)return;let t=adwaitaUiFontAvailability();if(t.match.family!==void 0)return t.match.family;console.warn(`applyUiFontPolicy: "${t.family}" is ${t.match.kind} on this font map, so asking for it will render in a substituted family. Register the runtime bundle's faces with initFonts() first, and check adwaitaUiFontAvailability() before offering this policy.`)}function adwaitaUiFontAvailability(e=a){let t=i(e,familyNames(p.FontMap.get_default()));return{family:e,match:t,available:t.kind!==`absent`}}function familyNames(e){return e.list_families().map(e=>e.get_name())}function collectFaces(t,n,r){try{let i=t.enumerate_children(`standard::name,standard::type`,d.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,null);for(let t=i.next_file(null);t!==null;t=i.next_file(null)){let a=i.get_child(t),o=a.get_path();o!==null&&(t.get_file_type()===d.FileType.DIRECTORY?collectFaces(a,n,r):e(t.get_name())&&n.push(o))}}catch(e){r.push({path:t.get_path()??``,message:messageOf(e)})}}function messageOf(e){return e instanceof f.Error||e instanceof Error?e.message:String(e)}export{a as ADWAITA_UI_FONT_FAMILY,o as GNOME_UI_FONT_POINT_SIZE,s as UI_FONT_POLICIES,adwaitaUiFontAvailability,applyUiFontPolicy,n as describeFontFamilyMatch,initFonts,isUnsupportedByFontMap,r as matchFontFamilies,i as matchFontFamily,c as planUiFont,l as planUiFontPolicy,t as resolveFontSources,uiFontBaseline};
1
+ import"./_virtual/_rolldown/runtime.js";import{isFontFace as e,resolveFontSources as t}from"./font-dir.js";import{describeFontFamilyMatch as n,matchFontFamilies as r,matchFontFamily as i}from"./font-families.js";import{ADWAITA_UI_FONT_FAMILY as a,GNOME_UI_FONT_POINT_SIZE as o,UI_FONT_POLICIES as s,planUiFont as c,planUiFontPolicy as l}from"./ui-font.js";import u from"gi://Gtk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://GLib?version=2.0";import p from"gi://PangoCairo?version=1.0";function isUnsupportedByFontMap(e){return e instanceof f.Error&&e.matches(d.io_error_quark(),d.IOErrorEnum.NOT_SUPPORTED)}const m=1;function adoptFontconfigMap(e,t){if(t.length===0||f.getenv(`PANGOCAIRO_BACKEND`)!==null)return;let n=p.FontMap.new_for_font_type(1);if(n===null)return;let r=familyNames(n);if(r.length===0)return;let i=new Map;for(let e of t)try{n.add_font_file(e)}catch(t){i.set(e,messageOf(t))}if(!familyNames(n).filter(e=>!r.includes(e)).every(t=>e.get_family(t)!==null))return n.set_default(),{map:n,before:r,failed:i}}function initFonts(e={}){let i=t({...e,env:{GJSIFY_FONT_DIR:f.getenv(`GJSIFY_FONT_DIR`)??void 0,GJSIFY_GTK_RUNTIME_FONT_DIR:f.getenv(`GJSIFY_GTK_RUNTIME_FONT_DIR`)??void 0}}),a=i.find(e=>e.origin===`app`)?.dir,o=[],s=[],c=[],l=[],u=e.expectedFamilies??[];if(i.length===0&&u.length===0)return{dir:a,sources:o,uiFont:void 0,registered:s,declined:c,failed:l,families:[],matches:[],fontconfigFallback:!1};let m=p.FontMap.get_default(),h=i.length===0?[]:familyNames(m),g=i.map(e=>({source:e,registered:[],declined:[],failed:[]}));for(let e of g){let t=[];collectFaces(d.File.new_for_path(e.source.dir),t,e.failed);for(let n of t.sort())try{m.add_font_file(n),e.registered.push(n)}catch(t){if(isUnsupportedByFontMap(t)){e.declined.push(n);continue}e.failed.push({path:n,message:messageOf(t)})}}let _=adoptFontconfigMap(m,g.flatMap(e=>e.declined));if(_!==void 0){m=_.map,h=_.before;for(let e of g){let t=e.declined;e.declined=[];for(let n of t){let t=_.failed.get(n);t===void 0?e.registered.push(n):e.failed.push({path:n,message:t})}}}for(let e of g)s.push(...e.registered),c.push(...e.declined),l.push(...e.failed),o.push({...e.source,registered:e.registered,declined:e.declined,failed:e.failed});let v=familyNames(m),y=i.length===0?[]:v.filter(e=>!h.includes(e)).sort(),b=r(u,v);captureUiFontBaseline();let x=e.uiFont===void 0?void 0:applyUiFontPolicy(e.uiFont);for(let e of l)console.warn(`initFonts: ${e.path} could not be read as an application font (${e.message}). Text asking for a family this application ships will render in a substituted one.`);for(let e of b)e.kind!==`exact`&&console.warn(`initFonts: ${n(e)}`);return{dir:a,sources:o,uiFont:x,registered:s,declined:c,failed:l,families:y,matches:b,fontconfigFallback:_!==void 0}}let h=!1,g;function captureUiFontBaseline(){if(h)return g;let e=u.Settings.get_default();if(e!==null)return g=e.gtk_font_name??void 0,h=!0,g}function uiFontBaseline(){return captureUiFontBaseline()}function applyUiFontPolicy(e){let t=typeof e==`string`?{policy:e}:e,n=t.settings===void 0?u.Settings.get_default():t.settings;if(n===null)return console.warn("applyUiFontPolicy: no Gtk.Settings — the toolkit is not initialised yet, so the policy was NOT applied. Call this after Gtk.init() (or from an application's `startup`), which is still before any window is built."),{next:void 0,kind:`uninitialised`,family:void 0,size:void 0};let r=captureUiFontBaseline(),i=l({...t,family:t.family??resolvedAdwaitaFamily(t.policy),current:n.gtk_font_name??void 0,baseline:r});return i.next===void 0||(n.gtk_font_name=i.next),i}function resolvedAdwaitaFamily(e){if(e!==`adwaita`)return;let t=adwaitaUiFontAvailability();if(t.match.family!==void 0)return t.match.family;console.warn(`applyUiFontPolicy: "${t.family}" is ${t.match.kind} on this font map, so asking for it will render in a substituted family. Register the runtime bundle's faces with initFonts() first, and check adwaitaUiFontAvailability() before offering this policy.`)}function adwaitaUiFontAvailability(e=a){let t=i(e,familyNames(p.FontMap.get_default()));return{family:e,match:t,available:t.kind!==`absent`}}function familyNames(e){return e.list_families().map(e=>e.get_name())}function collectFaces(t,n,r){try{let i=t.enumerate_children(`standard::name,standard::type`,d.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,null);for(let t=i.next_file(null);t!==null;t=i.next_file(null)){let a=i.get_child(t),o=a.get_path();o!==null&&(t.get_file_type()===d.FileType.DIRECTORY?collectFaces(a,n,r):e(t.get_name())&&n.push(o))}}catch(e){r.push({path:t.get_path()??``,message:messageOf(e)})}}function messageOf(e){return e instanceof f.Error||e instanceof Error?e.message:String(e)}export{a as ADWAITA_UI_FONT_FAMILY,m as CAIRO_FONT_TYPE_FT,o as GNOME_UI_FONT_POINT_SIZE,s as UI_FONT_POLICIES,adwaitaUiFontAvailability,applyUiFontPolicy,n as describeFontFamilyMatch,initFonts,isUnsupportedByFontMap,r as matchFontFamilies,i as matchFontFamily,c as planUiFont,l as planUiFontPolicy,t as resolveFontSources,uiFontBaseline};
package/lib/esm/host.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{reconcileStringList as n}from"./list-model.js";import{coerce as r,isConstructOnly as i,paramSpecs as a,removedValue as o,requireSpec as s,toPropertyName as c}from"./props.js";import{applyAccessibilityPlan as l,isAccessibleClass as u,planAccessibility as d}from"./accessibility.js";import{beginHostWrite as f,clearHandlers as p,endHostWrite as m,isEventProp as h,setHandler as g,toSignalName as _}from"./signals.js";import{addressOf as v,closeOutsideParent as y,detachOutsideParent as b,insertChild as x,isUnparented as S,makeDetachedContainer as C,makeWrapper as w,outsideParentOf as T,placeOutsideParent as E,refuseUnknownSlot as D,refuseUnparentable as O,removeChild as k,setterSlotOf as A,setterSlots as j,slotOccupant as M}from"./policies.js";import{lookupWidget as N,nearestRegistered as P}from"./registry.js";import F from"gi://GObject?version=2.0";function createElement(e,t){let n={kind:`element`,descriptor:N(e),widget:null,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!1,destroyed:!1,foreign:[],portalWatch:null};if(t)for(let[e,r]of Object.entries(t))setProp(n,e,r);return n}const createText=e=>({kind:`text`,data:e,parent:null,prev:null,next:null}),createAnchor=(e=``)=>({kind:`anchor`,data:e,parent:null,prev:null,next:null}),isText=e=>e.kind===`text`;function releaseWidget(e){let t=e.widget?T(e.descriptor):null;t&&y(e,t),e.widget=null,e.wrapper=null}function materialize(e){if(e.widget)return e.widget;for(let n of e.descriptor.requiresProps??[])if(!(n in e.props))throw t.missingConstructProp(e.descriptor.gtype,n);let n=e.descriptor.ctor(),i=a(n,e.descriptor.gtype),o={};for(let[t,n]of Object.entries(e.props))o[t]=r(s(i,e.descriptor.gtype,t),n,e.descriptor.gtype);f(null);try{e.widget=new n(o)}finally{m()}try{replayInto(e)}catch(t){p(e);for(let t of childSnapshot(e))t.kind===`element`&&t.attached&&(k(e,t),t.attached=!1);throw releaseWidget(e),t}return e.widget}function replayInto(e){for(let[t,n]of e.listeners)g(e,t,n);e.accessibility&&l(e.widget,d(e.descriptor.gtype,null,e.accessibility));for(let t of siblingsFrom(e.first,e))t.kind===`element`&&attach(e,t);e.textFromChildren&&flushText(e)}function setProp(e,t,l,u){if(h(t))return setEventHandler(e,t,l);if(t===`slot`)return setSlot(e,l);if(t===`accessibility`)return setAccessibility(e,l);if(t===`layout`){let t=l,n=e.parent;if(!n||!e.widget){e.layout=t;return}let r=e.layout;replaceAt(e,n,()=>{e.layout=t},()=>{e.layout=r});return}let d=c(t),p=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,d),g=l==null,_=g?o(e.descriptor,p):r(p,l,e.descriptor.gtype);e.widget!==null&&takesAccessorRoute(_)&&!i(p)&&requireAccessor(e,e.widget,d);let v=d in e.props?e.props[d]:void 0;if(g?delete e.props[d]:e.props[d]=l,e.widget){if(i(p))return rebuild(e,d,v);f(e.widget);try{n(e.widget,accessorName(d),_)||writeProperty(e.widget,d,_)}finally{m()}}}function writeProperty(e,t,n){if(!takesAccessorRoute(n)){e.set_property(t,n);return}let r=accessorName(t);e[r]=n}const accessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),takesAccessorRoute=e=>e===null||Array.isArray(e);function requireAccessor(e,n,r){let i=accessorName(r);if(!(i in n))throw t.noAccessor(e.descriptor.gtype,r,i)}function setEventHandler(e,t,n){e.widget?g(e,t,n):n&&assertSignalExists(e,t),n?e.listeners.set(t,n):e.listeners.delete(t)}function assertSignalExists(e,n){let r=_(n,e.descriptor.eventAliases).split(`::`)[0],i=e.descriptor.ctor().$gtype;if(F.signal_lookup(r,i)===0)throw t.unknownSignal(e.descriptor.gtype,n,r)}function setAccessibility(e,n){let r=n??null,i=d(e.descriptor.gtype,e.accessibility,r);if(r!==null&&!u(e.descriptor.ctor()))throw t.notAccessible(e.descriptor.gtype);e.widget&&l(e.widget,i),e.accessibility=r}function setSlot(e,t){if(e.slot===t)return;let n=e.parent;if(!n||!e.widget){e.slot=t;return}let r=e.slot;replaceAt(e,n,()=>{e.slot=t},()=>{e.slot=r})}function replaceAt(e,t,n,r){k(t,e),e.attached=!1,n();try{attach(t,e)}catch(n){r();try{attach(t,e)}catch{}throw n}}function rebuild(e,t,n){let r=e.parent;if(e.widget){p(e);for(let t of childSnapshot(e))t.kind===`element`&&(k(e,t),t.attached=!1);r&&!T(e.descriptor)&&k(r,e)}releaseWidget(e),e.attached=!1;try{materialize(e)}catch(i){t!==void 0&&(n===void 0?delete e.props[t]:e.props[t]=n);try{materialize(e),r&&attach(r,e)}catch{}throw i}r&&attach(r,e)}function setText(e,t){e.data=t,e.kind===`text`&&e.parent&&flushText(e.parent)}function setElementText(e,t){writeTextSink(e,t),e.textFromChildren=!1,destroyChildren(e)}function flushText(e){let t=``,n=!1;for(let r of childNodes(e))r.kind===`text`&&(t+=r.data,n=!0);if(t===``&&!e.textFromChildren)return;let r=e.descriptor.textSink;if(t===``&&r&&holdsElementInSetterSlot(e)){e.textFromChildren=!1,delete e.props[r];return}writeTextSink(e,t),e.textFromChildren=n}function*setterSlotChildren(e){for(let t of siblingsFrom(e.first,e))t.kind===`element`&&t.attached&&!S(t)&&A(e,t)&&(yield t)}const holdsElementInSetterSlot=e=>!setterSlotChildren(e).next().done;function writeTextSink(e,n){let i=e.descriptor.textSink;if(!i)throw t.textNotAccepted(e.descriptor.gtype,n);materialize(e);let o=e.descriptor.children,c=o.kind===`single`?o.set:null;if(c&&!holdsOursInSlot(e,null)&&appOccupant(e.widget,e.descriptor,c))throw t.occupiedSlot(e.descriptor.gtype,`text`,c);let l=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,i);f(e.widget);try{e.widget.set_property(i,r(l,n,e.descriptor.gtype))}finally{m()}e.props[i]=n;for(let t of setterSlotChildren(e))t.attached=!1}function*childNodes(e){yield*siblingsFrom(e.first,e)}function childSnapshot(e){let t=[];for(let n of siblingsFrom(e.first,e))t.push(n);return t}function*siblingsFrom(e,n){let r=0;for(let i=e;i;i=i.next){if(++r>1e5)throw t.siblingCycle(n.descriptor.gtype);yield i}}function link(e,t,n){t.parent=e,n?(t.prev=n.prev,t.next=n,n.prev?n.prev.next=t:e.first=t,n.prev=t):(t.prev=e.last,t.next=null,e.last?e.last.next=t:e.first=t,e.last=t)}function unlink(e){let t=e.parent;t&&(e.prev?e.prev.next=e.next:t.first=e.next,e.next?e.next.prev=e.prev:t.last=e.prev,e.prev=null,e.next=null,e.parent=null)}function attach(e,t){if(!e.widget)return;materialize(t);let n=T(t.descriptor);if(n){t.attached=E(e,t,n);return}O(e,t),D(e,t),ensureWrapper(e,t),refuseOccupiedSlot(e,t);let r=e.foreign.length>0?e.foreign.filter(t=>t.get_parent()===e.widget):e.foreign,i=r.length>0?r[r.length-1]:null,a=r.length;for(let n of siblingsFrom(e.first,e)){if(n===t)break;n.kind!==`element`||!n.attached||S(n)||(i=v(n),a+=1)}let o=[];for(let n of siblingsFrom(t.next,e))n.kind===`element`&&n.attached&&!S(n)&&o.push(n);x({parent:e,child:t,prevWidget:i,index:a,following:o}),t.attached=!0}function refuseOccupiedSlot(e,n){let r=A(e,n);if(r&&!holdsOursInSlot(e,n.slot)&&appOccupant(e.widget,e.descriptor,r))throw t.occupiedSlot(e.descriptor.gtype,n.descriptor.gtype,r)}function holdsOursInSlot(e,t){for(let n of siblingsFrom(e.first,e))if(n.kind===`element`&&n.attached&&n.slot===t&&!S(n))return!0;return!1}function ensureWrapper(n,r){if(r.wrapper)return;let i;try{i=w(n.descriptor,r.widget,r.slot)}catch(i){throw i instanceof e?i:t.rejectedChild(n.descriptor.gtype,r.descriptor.gtype,i.message)}i&&(r.wrapper=i)}function insert(e,t,n=null){assertHostParent(t);let r=e.parent,i=e.next,a=n===e?i:n;e.parent&&remove(e),link(t,e,a);try{e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch(t){throw unlink(e),r&&restore(e,r,i),t}}function assertHostParent(e){if(!isHostElement(e))throw t.notAHostParent(describeValue(e))}function isHostElement(e){let t=e;return!!t&&t.kind===`element`&&typeof t.descriptor==`object`}function describeValue(e){if(e==null)return String(e);if(typeof e!=`object`)return`a ${typeof e}`;let t=e.tagName;if(typeof t==`string`)return`a DOM element <${t.toLowerCase()}>`;let n=e.constructor?.$gtype,r=n?F.type_name(n)??`an unnamed GType`:null;if(r!==null&&r!==`JSObject`)return r;let i=e.constructor?.name;return i&&i!==`Object`?`a ${i}`:`a plain object`}function restore(e,t,n){try{link(t,e,n),e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch{unlink(e)}}function restoreTextSink(e){let t=e.descriptor.textSink;if(!t||e.destroyed||!e.widget)return;let n=e.descriptor.children;if(n.kind!==`single`||holdsOursInSlot(e,null)||M(e.widget,n.set))return;let i=t.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),o=e.props[t]??e.props[i];if(typeof o!=`string`||o===``)return;let c=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,t);f(e.widget);try{e.widget.set_property(t,r(c,o,e.descriptor.gtype))}finally{m()}}function remove(e){let t=e.parent;if(!t&&e.kind===`element`){let t=T(e.descriptor);t&&(b(e,t),e.attached=!1)}t&&e.kind===`element`&&(k(t,e),e.attached=!1,e.wrapper&&=(e.wrapper.set_child(null),null),restoreTextSink(t)),unlink(e),t&&e.kind===`text`&&flushText(t)}function destroyChildren(e){for(let t of childSnapshot(e))destroy(t)}function disconnectHandlers(e){p(e),e.listeners.clear()}function destroy(e){e.kind===`element`&&(destroyChildren(e),p(e),e.listeners.clear());let t=e.kind===`element`?T(e.descriptor):null;if(t&&releaseWidget(e),remove(e),e.kind===`element`){let n=e.widget;!t&&n&&typeof n.destroy==`function`&&typeof n.get_parent==`function`&&n.get_parent()===null&&n.destroy(),releaseWidget(e),e.props={},e.layout=null,e.accessibility=null,e.textFromChildren=!1,e.destroyed=!0}}function mountRoot(e,t){materialize(e),insert(e,adopt(t))}function widgetOf(e){if(e.kind!==`element`)throw t.notAnElement(e.kind);if(e.destroyed)throw t.destroyedNode(e.descriptor.gtype);return materialize(e)}const createDetachedContainer=()=>adopt(C());function adopt(e){let n=e.constructor.$gtype,r=P(n);if(!r)throw t.unknownTag(gtypeNameOf(e));return{kind:`element`,descriptor:r,widget:e,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!0,destroyed:!1,foreign:adoptedChildren(e,r),portalWatch:null}}function adoptedChildren(e,t){let n=j(t.children);if(n.length===0)return directChildren(e);let r=[];for(let i of n){let n=appOccupant(e,t,i);n&&r.push(n)}return r}function appOccupant(e,t,n){let r=M(e,n);if(!r)return null;let i=t.textSink;if(!i)return r;let a=e[i.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())];return typeof a==`string`&&a!==``?null:r}function directChildren(e){let t=[],n=e;if(typeof n.get_first_child!=`function`)return t;for(let e=n.get_first_child();e;e=e.get_next_sibling())t.push(e);return t}const gtypeNameOf=e=>F.type_name(e.constructor.$gtype),parentNode=e=>e.parent,firstChild=e=>e.first,nextSibling=e=>e.next,prevSibling=e=>e.prev;export{adopt,createAnchor,createDetachedContainer,createElement,createText,describeValue,destroy,destroyChildren,disconnectHandlers,firstChild,insert,isHostElement,isText,materialize,mountRoot,nextSibling,parentNode,prevSibling,remove,setAccessibility,setElementText,setEventHandler,setProp,setSlot,setText,widgetOf};
1
+ import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{reconcileStringList as n}from"./list-model.js";import{lookupWidget as r,nearestRegistered as i,requireClass as a}from"./registry.js";import{coerce as o,isConstructOnly as s,paramSpecs as c,removedValue as l,requireSpec as u,toPropertyName as d}from"./props.js";import{applyAccessibilityPlan as f,isAccessibleClass as p,planAccessibility as m}from"./accessibility.js";import{beginHostWrite as h,clearHandlers as g,endHostWrite as _,isEventProp as v,setHandler as y,toSignalName as b}from"./signals.js";import{addressOf as x,closeOutsideParent as S,detachOutsideParent as C,insertChild as w,isUnparented as T,makeDetachedContainer as E,makeWrapper as D,outsideParentOf as O,placeOutsideParent as k,refuseUnknownSlot as A,refuseUnparentable as j,removeChild as M,setterSlotOf as N,setterSlots as P,slotOccupant as F}from"./policies.js";import I from"gi://GObject?version=2.0";function createElement(e,t){let n={kind:`element`,descriptor:r(e),widget:null,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!1,destroyed:!1,foreign:[],portalWatch:null};if(t)for(let[e,r]of Object.entries(t))setProp(n,e,r);return n}const createText=e=>({kind:`text`,data:e,parent:null,prev:null,next:null}),createAnchor=(e=``)=>({kind:`anchor`,data:e,parent:null,prev:null,next:null}),isText=e=>e.kind===`text`;function releaseWidget(e){let t=e.widget?O(e.descriptor):null;t&&S(e,t),e.widget=null,e.wrapper=null}function materialize(e){if(e.widget)return e.widget;for(let n of e.descriptor.requiresProps??[])if(!(n in e.props))throw t.missingConstructProp(e.descriptor.gtype,n);let n=a(e.descriptor),r=c(n,e.descriptor.gtype),i={};for(let[t,n]of Object.entries(e.props))i[t]=o(u(r,e.descriptor.gtype,t),n,e.descriptor.gtype);h(null);try{e.widget=new n(i)}finally{_()}try{replayInto(e)}catch(t){g(e);for(let t of childSnapshot(e))t.kind===`element`&&t.attached&&(M(e,t),t.attached=!1);throw releaseWidget(e),t}return e.widget}function replayInto(e){for(let[t,n]of e.listeners)y(e,t,n);e.accessibility&&f(e.widget,m(e.descriptor.gtype,null,e.accessibility));for(let t of siblingsFrom(e.first,e))t.kind===`element`&&attach(e,t);e.textFromChildren&&flushText(e)}function setProp(e,t,r,i){if(v(t))return setEventHandler(e,t,r);if(t===`slot`)return setSlot(e,r);if(t===`accessibility`)return setAccessibility(e,r);if(t===`layout`){let t=r,n=e.parent;if(!n||!e.widget){e.layout=t;return}let i=e.layout;replaceAt(e,n,()=>{e.layout=t},()=>{e.layout=i});return}let f=d(t),p=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,f),m=r==null,g=m?l(e.descriptor,p):o(p,r,e.descriptor.gtype);e.widget!==null&&takesAccessorRoute(g)&&!s(p)&&requireAccessor(e,e.widget,f);let y=f in e.props?e.props[f]:void 0;if(m?delete e.props[f]:e.props[f]=r,e.widget){if(s(p))return rebuild(e,f,y);h(e.widget);try{n(e.widget,accessorName(f),g)||writeProperty(e.widget,f,g)}finally{_()}}}function writeProperty(e,t,n){if(!takesAccessorRoute(n)){e.set_property(t,n);return}let r=accessorName(t);e[r]=n}const accessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),takesAccessorRoute=e=>e===null||Array.isArray(e);function requireAccessor(e,n,r){let i=accessorName(r);if(!(i in n))throw t.noAccessor(e.descriptor.gtype,r,i)}function setEventHandler(e,t,n){e.widget?y(e,t,n):n&&assertSignalExists(e,t),n?e.listeners.set(t,n):e.listeners.delete(t)}function assertSignalExists(e,n){let r=b(n,e.descriptor.eventAliases).split(`::`)[0],i=a(e.descriptor).$gtype;if(I.signal_lookup(r,i)===0)throw t.unknownSignal(e.descriptor.gtype,n,r)}function setAccessibility(e,n){let r=n??null,i=m(e.descriptor.gtype,e.accessibility,r);if(r!==null&&!p(a(e.descriptor)))throw t.notAccessible(e.descriptor.gtype);e.widget&&f(e.widget,i),e.accessibility=r}function setSlot(e,t){if(e.slot===t)return;let n=e.parent;if(!n||!e.widget){e.slot=t;return}let r=e.slot;replaceAt(e,n,()=>{e.slot=t},()=>{e.slot=r})}function replaceAt(e,t,n,r){M(t,e),e.attached=!1,n();try{attach(t,e)}catch(n){r();try{attach(t,e)}catch{}throw n}}function rebuild(e,t,n){let r=e.parent;if(e.widget){g(e);for(let t of childSnapshot(e))t.kind===`element`&&(M(e,t),t.attached=!1);r&&!O(e.descriptor)&&M(r,e)}releaseWidget(e),e.attached=!1;try{materialize(e)}catch(i){t!==void 0&&(n===void 0?delete e.props[t]:e.props[t]=n);try{materialize(e),r&&attach(r,e)}catch{}throw i}r&&attach(r,e)}function setText(e,t){e.data=t,e.kind===`text`&&e.parent&&flushText(e.parent)}function setElementText(e,t){writeTextSink(e,t),e.textFromChildren=!1,destroyChildren(e)}function flushText(e){let t=``,n=!1;for(let r of childNodes(e))r.kind===`text`&&(t+=r.data,n=!0);if(t===``&&!e.textFromChildren)return;let r=e.descriptor.textSink;if(t===``&&r&&holdsElementInSetterSlot(e)){e.textFromChildren=!1,delete e.props[r];return}writeTextSink(e,t),e.textFromChildren=n}function*setterSlotChildren(e){for(let t of siblingsFrom(e.first,e))t.kind===`element`&&t.attached&&!T(t)&&N(e,t)&&(yield t)}const holdsElementInSetterSlot=e=>!setterSlotChildren(e).next().done;function writeTextSink(e,n){let r=e.descriptor.textSink;if(!r)throw t.textNotAccepted(e.descriptor.gtype,n);materialize(e);let i=e.descriptor.children,s=i.kind===`single`?i.set:null;if(s&&!holdsOursInSlot(e,null)&&appOccupant(e.widget,e.descriptor,s))throw t.occupiedSlot(e.descriptor.gtype,`text`,s);let l=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,r);h(e.widget);try{e.widget.set_property(r,o(l,n,e.descriptor.gtype))}finally{_()}e.props[r]=n;for(let t of setterSlotChildren(e))t.attached=!1}function*childNodes(e){yield*siblingsFrom(e.first,e)}function childSnapshot(e){let t=[];for(let n of siblingsFrom(e.first,e))t.push(n);return t}function*siblingsFrom(e,n){let r=0;for(let i=e;i;i=i.next){if(++r>1e5)throw t.siblingCycle(n.descriptor.gtype);yield i}}function link(e,t,n){t.parent=e,n?(t.prev=n.prev,t.next=n,n.prev?n.prev.next=t:e.first=t,n.prev=t):(t.prev=e.last,t.next=null,e.last?e.last.next=t:e.first=t,e.last=t)}function unlink(e){let t=e.parent;t&&(e.prev?e.prev.next=e.next:t.first=e.next,e.next?e.next.prev=e.prev:t.last=e.prev,e.prev=null,e.next=null,e.parent=null)}function attach(e,t){if(!e.widget)return;materialize(t);let n=O(t.descriptor);if(n){t.attached=k(e,t,n);return}j(e,t),A(e,t),ensureWrapper(e,t),refuseOccupiedSlot(e,t);let r=e.foreign.length>0?e.foreign.filter(t=>t.get_parent()===e.widget):e.foreign,i=r.length>0?r[r.length-1]:null,a=r.length;for(let n of siblingsFrom(e.first,e)){if(n===t)break;n.kind!==`element`||!n.attached||T(n)||(i=x(n),a+=1)}let o=[];for(let n of siblingsFrom(t.next,e))n.kind===`element`&&n.attached&&!T(n)&&o.push(n);w({parent:e,child:t,prevWidget:i,index:a,following:o}),t.attached=!0}function refuseOccupiedSlot(e,n){let r=N(e,n);if(r&&!holdsOursInSlot(e,n.slot)&&appOccupant(e.widget,e.descriptor,r))throw t.occupiedSlot(e.descriptor.gtype,n.descriptor.gtype,r)}function holdsOursInSlot(e,t){for(let n of siblingsFrom(e.first,e))if(n.kind===`element`&&n.attached&&n.slot===t&&!T(n))return!0;return!1}function ensureWrapper(n,r){if(r.wrapper)return;let i;try{i=D(n.descriptor,r.widget,r.slot)}catch(i){throw i instanceof e?i:t.rejectedChild(n.descriptor.gtype,r.descriptor.gtype,i.message)}i&&(r.wrapper=i)}function insert(e,t,n=null){assertHostParent(t);let r=e.parent,i=e.next,a=n===e?i:n;e.parent&&remove(e),link(t,e,a);try{e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch(t){throw unlink(e),r&&restore(e,r,i),t}}function assertHostParent(e){if(!isHostElement(e))throw t.notAHostParent(describeValue(e))}function isHostElement(e){let t=e;return!!t&&t.kind===`element`&&typeof t.descriptor==`object`}function describeValue(e){if(e==null)return String(e);if(typeof e!=`object`)return`a ${typeof e}`;let t=e.tagName;if(typeof t==`string`)return`a DOM element <${t.toLowerCase()}>`;let n=e.constructor?.$gtype,r=n?I.type_name(n)??`an unnamed GType`:null;if(r!==null&&r!==`JSObject`)return r;let i=e.constructor?.name;return i&&i!==`Object`?`a ${i}`:`a plain object`}function restore(e,t,n){try{link(t,e,n),e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch{unlink(e)}}function restoreTextSink(e){let t=e.descriptor.textSink;if(!t||e.destroyed||!e.widget)return;let n=e.descriptor.children;if(n.kind!==`single`||holdsOursInSlot(e,null)||F(e.widget,n.set))return;let r=t.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),i=e.props[t]??e.props[r];if(typeof i!=`string`||i===``)return;let s=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,t);h(e.widget);try{e.widget.set_property(t,o(s,i,e.descriptor.gtype))}finally{_()}}function remove(e){let t=e.parent;if(!t&&e.kind===`element`){let t=O(e.descriptor);t&&(C(e,t),e.attached=!1)}t&&e.kind===`element`&&(M(t,e),e.attached=!1,e.wrapper&&=(e.wrapper.set_child(null),null),restoreTextSink(t)),unlink(e),t&&e.kind===`text`&&flushText(t)}function destroyChildren(e){for(let t of childSnapshot(e))destroy(t)}function disconnectHandlers(e){g(e),e.listeners.clear()}function destroy(e){e.kind===`element`&&(destroyChildren(e),g(e),e.listeners.clear());let t=e.kind===`element`?O(e.descriptor):null;if(t&&releaseWidget(e),remove(e),e.kind===`element`){let n=e.widget;!t&&n&&typeof n.destroy==`function`&&typeof n.get_parent==`function`&&n.get_parent()===null&&n.destroy(),releaseWidget(e),e.props={},e.layout=null,e.accessibility=null,e.textFromChildren=!1,e.destroyed=!0}}function mountRoot(e,t){materialize(e),insert(e,adopt(t))}function widgetOf(e){if(e.kind!==`element`)throw t.notAnElement(e.kind);if(e.destroyed)throw t.destroyedNode(e.descriptor.gtype);return materialize(e)}const createDetachedContainer=()=>adopt(E());function adopt(e){let n=e.constructor.$gtype,r=i(n);if(!r)throw t.unknownTag(gtypeNameOf(e));return{kind:`element`,descriptor:r,widget:e,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!0,destroyed:!1,foreign:adoptedChildren(e,r),portalWatch:null}}function adoptedChildren(e,t){let n=P(t.children);if(n.length===0)return directChildren(e);let r=[];for(let i of n){let n=appOccupant(e,t,i);n&&r.push(n)}return r}function appOccupant(e,t,n){let r=F(e,n);if(!r)return null;let i=t.textSink;if(!i)return r;let a=e[i.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())];return typeof a==`string`&&a!==``?null:r}function directChildren(e){let t=[],n=e;if(typeof n.get_first_child!=`function`)return t;for(let e=n.get_first_child();e;e=e.get_next_sibling())t.push(e);return t}const gtypeNameOf=e=>I.type_name(e.constructor.$gtype),parentNode=e=>e.parent,firstChild=e=>e.first,nextSibling=e=>e.next,prevSibling=e=>e.prev;export{adopt,createAnchor,createDetachedContainer,createElement,createText,describeValue,destroy,destroyChildren,disconnectHandlers,firstChild,insert,isHostElement,isText,materialize,mountRoot,nextSibling,parentNode,prevSibling,remove,setAccessibility,setElementText,setEventHandler,setProp,setSlot,setText,widgetOf};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{GtkHostError as e}from"./errors.js";import{constructOnlyNames as t,isConstructOnly as n,isWritable as r,lookupEnumNick as i,paramSpecs as a,toPropertyName as o}from"./props.js";import{isEventProp as s,toSignalName as c}from"./signals.js";import{addressOf as l,isPortal as u,placementOf as d,portalOf as f,reorderMode as p}from"./policies.js";import{assertInjective as m,tagOf as h}from"./tags.js";import{clearRegistry as g,hasWidget as _,lookupWidget as v,nearestRegistered as y,registerWidget as b,registerWidgets as x,registeredTags as S}from"./registry.js";import{adopt as C,createAnchor as w,createDetachedContainer as T,createElement as E,createText as D,destroy as O,destroyChildren as k,disconnectHandlers as A,firstChild as j,insert as M,isHostElement as N,isText as P,materialize as F,mountRoot as I,nextSibling as L,parentNode as R,prevSibling as z,remove as B,setElementText as V,setEventHandler as H,setProp as U,setSlot as W,setText as G,widgetOf as K}from"./host.js";import{GENERATED_PROVENANCE as q,GENERATED_WIDGETS as J}from"./generated/widgets.js";import{GTK_DESCRIPTORS as Y}from"./descriptors/gtk.js";import{ADW_DESCRIPTORS as X}from"./descriptors/adw.js";import{BUILTIN_DESCRIPTORS as Z,CURATED_DESCRIPTORS as Q,mergeGenerated as $,registerBuiltinWidgets as ee,tableProvenance as te}from"./descriptors/index.js";import"./types.js";import{blankReason as ne,checkRendered as re,probeEnabled as ie,runHostProbe as ae,runHostProbeApp as oe,shotEvidence as se}from"./probe.js";export{X as ADW_DESCRIPTORS,Z as BUILTIN_DESCRIPTORS,Q as CURATED_DESCRIPTORS,q as GENERATED_PROVENANCE,J as GENERATED_WIDGETS,Y as GTK_DESCRIPTORS,e as GtkHostError,l as addressOf,C as adopt,m as assertInjective,ne as blankReason,re as checkRendered,g as clearRegistry,t as constructOnlyNames,w as createAnchor,T as createDetachedContainer,E as createElement,D as createText,O as destroy,k as destroyChildren,A as disconnectHandlers,j as firstChild,_ as hasWidget,M as insert,n as isConstructOnly,s as isEventProp,N as isHostElement,u as isPortal,P as isText,r as isWritable,i as lookupEnumNick,v as lookupWidget,F as materialize,$ as mergeGenerated,I as mountRoot,y as nearestRegistered,L as nextSibling,a as paramSpecs,R as parentNode,d as placementOf,f as portalOf,z as prevSibling,ie as probeEnabled,ee as registerBuiltinWidgets,b as registerWidget,x as registerWidgets,S as registeredTags,B as remove,p as reorderMode,ae as runHostProbe,oe as runHostProbeApp,V as setElementText,H as setEventHandler,U as setProp,W as setSlot,G as setText,se as shotEvidence,te as tableProvenance,h as tagOf,o as toPropertyName,c as toSignalName,K as widgetOf};
1
+ import{GtkHostError as e}from"./errors.js";import{assertInjective as t,tagOf as n}from"./tags.js";import{classOf as r,clearRegistry as i,hasClass as a,hasWidget as o,lookupWidget as s,nearestRegistered as c,registerWidget as l,registerWidgets as u,registeredTags as d,requireClass as f}from"./registry.js";import{constructOnlyNames as p,gtypeOfName as m,isConstructOnly as h,isWritable as g,lookupEnumNick as _,paramSpecs as v,toPropertyName as y}from"./props.js";import{isEventProp as b,toSignalName as x}from"./signals.js";import{addressOf as S,isPortal as C,placementOf as w,portalOf as T,reorderMode as E}from"./policies.js";import{adopt as D,createAnchor as O,createDetachedContainer as k,createElement as A,createText as j,destroy as M,destroyChildren as N,disconnectHandlers as P,firstChild as F,insert as I,isHostElement as L,isText as R,materialize as z,mountRoot as B,nextSibling as V,parentNode as H,prevSibling as U,remove as W,setElementText as G,setEventHandler as K,setProp as q,setSlot as J,setText as Y,widgetOf as X}from"./host.js";import{GENERATED_PROVENANCE as Z,GENERATED_WIDGETS as Q}from"./generated/widgets.js";import{GTK_DESCRIPTORS as $}from"./descriptors/gtk.js";import{ADW_DESCRIPTORS as ee}from"./descriptors/adw.js";import{BUILTIN_DESCRIPTORS as te,CURATED_DESCRIPTORS as ne,mergeGenerated as re,registerBuiltinWidgets as ie,tableProvenance as ae}from"./descriptors/index.js";import"./types.js";import{blankReason as oe,checkRendered as se,probeEnabled as ce,runHostProbe as le,runHostProbeApp as ue,shotEvidence as de}from"./probe.js";export{ee as ADW_DESCRIPTORS,te as BUILTIN_DESCRIPTORS,ne as CURATED_DESCRIPTORS,Z as GENERATED_PROVENANCE,Q as GENERATED_WIDGETS,$ as GTK_DESCRIPTORS,e as GtkHostError,S as addressOf,D as adopt,t as assertInjective,oe as blankReason,se as checkRendered,r as classOf,i as clearRegistry,p as constructOnlyNames,O as createAnchor,k as createDetachedContainer,A as createElement,j as createText,M as destroy,N as destroyChildren,P as disconnectHandlers,F as firstChild,m as gtypeOfName,a as hasClass,o as hasWidget,I as insert,h as isConstructOnly,b as isEventProp,L as isHostElement,C as isPortal,R as isText,g as isWritable,_ as lookupEnumNick,s as lookupWidget,z as materialize,re as mergeGenerated,B as mountRoot,c as nearestRegistered,V as nextSibling,v as paramSpecs,H as parentNode,w as placementOf,T as portalOf,U as prevSibling,ce as probeEnabled,ie as registerBuiltinWidgets,l as registerWidget,u as registerWidgets,d as registeredTags,W as remove,E as reorderMode,f as requireClass,le as runHostProbe,ue as runHostProbeApp,G as setElementText,K as setEventHandler,q as setProp,J as setSlot,Y as setText,de as shotEvidence,ae as tableProvenance,n as tagOf,y as toPropertyName,x as toSignalName,X as widgetOf};
package/lib/esm/props.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{buildAdjustment as t,isPortableAdjustment as n}from"./adjustment.js";import{buildStringList as r,isPortableListModel as i}from"./list-model.js";import{buildGioMenu as a,isPortableMenu as o}from"./menu.js";import s from"gi://GObject?version=2.0";import c from"gi://Gtk?version=4.0";import l from"gi://Adw?version=1";import u from"gi://Gdk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://Pango?version=1.0";const p=[[`Gtk`,c],[`Adw`,l],[`Gdk`,u],[`Pango`,f],[`G`,d],[`G`,s]];function toPropertyName(e){return e.includes(`-`)?e:e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase()}function withoutKeys(e,t){if(!e)return;let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n}const m=new Map;function paramSpecs(e,t){let n=m.get(t);if(n)return n;n=new Map;for(let t of e.list_properties())n.set(t.get_name(),t);return m.set(t,n),n}const isFlag=(e,t)=>(e&t)!==0,isWritable=e=>isFlag(e.flags,s.ParamFlags.WRITABLE),isConstructOnly=e=>isFlag(e.flags,s.ParamFlags.CONSTRUCT_ONLY);function constructOnlyNames(e,t){let n=[];for(let[r,i]of paramSpecs(e,t))isConstructOnly(i)&&isWritable(i)&&n.push(r);return n}function giTypeObject(e){for(let[t,n]of p){if(!e.startsWith(t))continue;let r=n[e.slice(t.length)];if(!r||typeof r!=`object`)continue;let i=r.$gtype;if(!(!i||s.type_name(i)!==e))return r}}function gtypeOfName(e){return s.type_from_name(e)||giTypeObject(e)?.$gtype}let h;const isWholeNumber=e=>/^[+-]?(?:0[xX][0-9a-fA-F]+|[0-9]+)$/.test(e.trim()),startsNumeric=e=>/^[+-]?[0-9]/.test(e.trim());function memberNickValue(e,t){let n=giTypeObject(s.type_name(e))?.[t.trim().toUpperCase().replace(/-/g,`_`)];return typeof n==`number`?n:void 0}function parseNickText(e,t){if(!isWholeNumber(t)){let n=t.split(`|`);if(n.some(startsNumeric))return n.length===1?memberNickValue(e,t):void 0}h??=new c.Builder;try{let[n,r]=h.value_from_string_type(e,t);return n&&typeof r==`number`?r:void 0}catch{return}}const hasBlankMember=e=>e.split(`|`).some(e=>e.trim().length===0),lookupEnumNick=(e,t)=>{let n=gtypeOfName(e);return n===void 0?void 0:parseNickText(n,t)};function enumMembers(e){let t=giTypeObject(e);if(t)return Object.keys(t).filter(e=>e!==`$gtype`&&typeof t[e]==`number`)}const kindOf=e=>Array.isArray(e)?`an array`:`a ${typeof e}`;function coerce(l,u,f){if(u==null)return u;let p=l.value_type;if(s.type_is_a(p,d.MenuModel.$gtype)&&o(u))return a(u);if(s.type_is_a(p,d.ListModel.$gtype)&&!(u instanceof s.Object)){if(!i(u))throw e.badListModel(f,l.get_name(),kindOf(u));if(!s.type_is_a(c.StringList.$gtype,p))throw e.listModelMismatch(f,l.get_name(),s.type_name(p));return r(u)}if(s.type_is_a(p,c.Adjustment.$gtype)&&!(u instanceof s.Object)){if(!n(u))throw e.badAdjustment(f,l.get_name(),kindOf(u));return t(u)}if(s.type_is_a(p,s.TYPE_ENUM)&&typeof u==`string`){let t=parseNickText(p,u);if(t!==void 0)return t;throw e.badEnum(f,l.get_name(),u,s.type_name(p))}if(s.type_is_a(p,s.TYPE_FLAGS)&&typeof u==`string`){let t=s.type_name(p);if(hasBlankMember(u))throw e.blankFlags(f,l.get_name(),u,t);let n=parseNickText(p,u);if(n!==void 0)return n;throw e.badFlags(f,l.get_name(),u,t)}if(s.type_is_a(p,s.TYPE_BOOLEAN)){if(typeof u==`boolean`)return u;if(u===`true`)return!0;if(u===`false`)return!1;if(typeof u==`string`)throw e.badBoolean(f,l.get_name(),u);return!!u}if(s.type_is_a(p,s.TYPE_STRING)){if(typeof u==`string`)return u;if(typeof u==`number`||typeof u==`boolean`)return String(u);throw e.badString(f,l.get_name(),typeof u)}return(s.type_is_a(p,s.TYPE_INT)||s.type_is_a(p,s.TYPE_UINT)||s.type_is_a(p,s.TYPE_INT64)||s.type_is_a(p,s.TYPE_UINT64))&&typeof u==`number`?Math.trunc(u):u}const g=[s.TYPE_BOOLEAN,s.TYPE_STRING,s.TYPE_INT,s.TYPE_UINT,s.TYPE_INT64,s.TYPE_UINT64,s.TYPE_DOUBLE,s.TYPE_FLOAT],isScalarSpec=e=>s.type_is_a(e.value_type,s.TYPE_ENUM)||g.some(t=>s.type_is_a(e.value_type,t)),toAccessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),_=new Map;function constructedDefaults(e){let t=_.get(e.gtype);if(t)return t;let n=new Map;_.set(e.gtype,n);let r=e.ctor(),i;try{let t={};for(let n of e.requiresProps??[])t[n]=``;i=new r(t)}catch{return n}for(let[t,a]of paramSpecs(r,e.gtype)){if(!isWritable(a)||isConstructOnly(a)||!isFlag(a.flags,s.ParamFlags.READABLE)||isFlag(a.flags,s.ParamFlags.DEPRECATED)||!isScalarSpec(a))continue;let e=toAccessorName(t);e in i&&n.set(t,i[e])}return i instanceof c.Window&&i.destroy(),n}function removedValue(e,t){let n=constructedDefaults(e),r=t.get_name();return n.has(r)?n.get(r):t.get_default_value()}function requireSpec(t,n,r){let i=t.get(r);if(!i)throw e.unknownProp(n,r);if(!isWritable(i))throw e.readOnlyProp(n,r);return i}export{coerce,constructOnlyNames,enumMembers,isConstructOnly,isWritable,lookupEnumNick,paramSpecs,removedValue,requireSpec,toPropertyName,withoutKeys};
1
+ import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{buildAdjustment as t,isPortableAdjustment as n}from"./adjustment.js";import{buildStringList as r,isPortableListModel as i}from"./list-model.js";import{buildGioMenu as a,isPortableMenu as o}from"./menu.js";import{requireClass as s}from"./registry.js";import c from"gi://GObject?version=2.0";import l from"gi://Gtk?version=4.0";import u from"gi://Adw?version=1";import d from"gi://Gdk?version=4.0";import f from"gi://Gio?version=2.0";import p from"gi://Pango?version=1.0";const m=[[`Gtk`,l],[`Adw`,u],[`Gdk`,d],[`Pango`,p],[`G`,f],[`G`,c]];function toPropertyName(e){return e.includes(`-`)?e:e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase()}function withoutKeys(e,t){if(!e)return;let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n}const h=new Map;function paramSpecs(e,t){let n=h.get(t);if(n)return n;n=new Map;for(let t of e.list_properties())n.set(t.get_name(),t);return h.set(t,n),n}const isFlag=(e,t)=>(e&t)!==0,isWritable=e=>isFlag(e.flags,c.ParamFlags.WRITABLE),isConstructOnly=e=>isFlag(e.flags,c.ParamFlags.CONSTRUCT_ONLY);function constructOnlyNames(e,t){let n=[];for(let[r,i]of paramSpecs(e,t))isConstructOnly(i)&&isWritable(i)&&n.push(r);return n}function giTypeObject(e){for(let[t,n]of m){if(!e.startsWith(t))continue;let r=n[e.slice(t.length)],i=r?.$gtype;if(!(!i||c.type_name(i)!==e))return r}}function gtypeOfName(e){return c.type_from_name(e)||giTypeObject(e)?.$gtype}let g;const isWholeNumber=e=>/^[+-]?(?:0[xX][0-9a-fA-F]+|[0-9]+)$/.test(e.trim()),startsNumeric=e=>/^[+-]?[0-9]/.test(e.trim());function memberNickValue(e,t){let n=giTypeObject(c.type_name(e))?.[t.trim().toUpperCase().replace(/-/g,`_`)];return typeof n==`number`?n:void 0}function parseNickText(e,t){if(!isWholeNumber(t)){let n=t.split(`|`);if(n.some(startsNumeric))return n.length===1?memberNickValue(e,t):void 0}g??=new l.Builder;try{let[n,r]=g.value_from_string_type(e,t);return n&&typeof r==`number`?r:void 0}catch{return}}const hasBlankMember=e=>e.split(`|`).some(e=>e.trim().length===0),lookupEnumNick=(e,t)=>{let n=gtypeOfName(e);return n===void 0?void 0:parseNickText(n,t)},isEnumish=e=>c.type_is_a(e,c.TYPE_ENUM)||c.type_is_a(e,c.TYPE_FLAGS);function enumMembers(e){let t=giTypeObject(e),n=t?.$gtype;if(!(!n||!isEnumish(n)))return Object.keys(t).filter(e=>e!==`$gtype`&&typeof t[e]==`number`)}const kindOf=e=>Array.isArray(e)?`an array`:`a ${typeof e}`;function coerce(s,u,d){if(u==null)return u;let p=s.value_type;if(c.type_is_a(p,f.MenuModel.$gtype)&&o(u))return a(u);if(c.type_is_a(p,f.ListModel.$gtype)&&!(u instanceof c.Object)){if(!i(u))throw e.badListModel(d,s.get_name(),kindOf(u));if(!c.type_is_a(l.StringList.$gtype,p))throw e.listModelMismatch(d,s.get_name(),c.type_name(p));return r(u)}if(c.type_is_a(p,l.Adjustment.$gtype)&&!(u instanceof c.Object)){if(!n(u))throw e.badAdjustment(d,s.get_name(),kindOf(u));return t(u)}if(c.type_is_a(p,c.TYPE_ENUM)&&typeof u==`string`){let t=parseNickText(p,u);if(t!==void 0)return t;throw e.badEnum(d,s.get_name(),u,c.type_name(p))}if(c.type_is_a(p,c.TYPE_FLAGS)&&typeof u==`string`){let t=c.type_name(p);if(hasBlankMember(u))throw e.blankFlags(d,s.get_name(),u,t);let n=parseNickText(p,u);if(n!==void 0)return n;throw e.badFlags(d,s.get_name(),u,t)}if(c.type_is_a(p,c.TYPE_BOOLEAN)){if(typeof u==`boolean`)return u;if(u===`true`)return!0;if(u===`false`)return!1;if(typeof u==`string`)throw e.badBoolean(d,s.get_name(),u);return!!u}if(c.type_is_a(p,c.TYPE_STRING)){if(typeof u==`string`)return u;if(typeof u==`number`||typeof u==`boolean`)return String(u);throw e.badString(d,s.get_name(),typeof u)}return(c.type_is_a(p,c.TYPE_INT)||c.type_is_a(p,c.TYPE_UINT)||c.type_is_a(p,c.TYPE_INT64)||c.type_is_a(p,c.TYPE_UINT64))&&typeof u==`number`?Math.trunc(u):u}const _=[c.TYPE_BOOLEAN,c.TYPE_STRING,c.TYPE_INT,c.TYPE_UINT,c.TYPE_INT64,c.TYPE_UINT64,c.TYPE_DOUBLE,c.TYPE_FLOAT],isScalarSpec=e=>c.type_is_a(e.value_type,c.TYPE_ENUM)||_.some(t=>c.type_is_a(e.value_type,t)),toAccessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),v=new Map;function constructedDefaults(e){let t=v.get(e.gtype);if(t)return t;let n=new Map;v.set(e.gtype,n);let r=s(e),i;try{let t={};for(let n of e.requiresProps??[])t[n]=``;i=new r(t)}catch{return n}for(let[t,a]of paramSpecs(r,e.gtype)){if(!isWritable(a)||isConstructOnly(a)||!isFlag(a.flags,c.ParamFlags.READABLE)||isFlag(a.flags,c.ParamFlags.DEPRECATED)||!isScalarSpec(a))continue;let e=toAccessorName(t);e in i&&n.set(t,i[e])}return i instanceof l.Window&&i.destroy(),n}function removedValue(e,t){let n=constructedDefaults(e),r=t.get_name();return n.has(r)?n.get(r):t.get_default_value()}function requireSpec(t,n,r){let i=t.get(r);if(!i)throw e.unknownProp(n,r);if(!isWritable(i))throw e.readOnlyProp(n,r);return i}export{coerce,constructOnlyNames,enumMembers,gtypeOfName,isConstructOnly,isWritable,lookupEnumNick,paramSpecs,removedValue,requireSpec,toPropertyName,withoutKeys};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{tagOf as t}from"./tags.js";import n from"gi://GObject?version=2.0";const r=new Map,i=new Map;function registerWidget(e){r.set(e.gtype,e);let n=t(e.gtype);n!==e.gtype&&i.set(n,e)}function registerWidgets(e){for(let t of e)registerWidget(t)}function lookupWidget(t){let n=r.get(t)??i.get(t);if(!n)throw e.unknownTag(t);return n}const hasWidget=e=>r.has(e)||i.has(e),registeredTags=()=>[...r.keys()].sort();function nearestRegistered(e){for(let t=e;t;t=n.type_parent(t)){let e=n.type_name(t);if(!e)break;let i=r.get(e);if(i)return i}}function clearRegistry(){r.clear(),i.clear()}export{clearRegistry,hasWidget,lookupWidget,nearestRegistered,registerWidget,registerWidgets,registeredTags};
1
+ import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{tagOf as t}from"./tags.js";import n from"gi://GObject?version=2.0";const r=new Map,i=new Map;function registerWidget(e){r.set(e.gtype,e);let n=t(e.gtype);n!==e.gtype&&i.set(n,e)}function registerWidgets(e){for(let t of e)registerWidget(t)}function lookupWidget(t){let n=r.get(t)??i.get(t);if(!n)throw e.unknownTag(t);return n}const hasWidget=e=>r.has(e)||i.has(e);function classOf(e){return e.ctor()??null}const hasClass=e=>classOf(e)!==null;function requireClass(t){let n=classOf(t);if(!n)throw e.absentClass(t.gtype);return n}const registeredTags=()=>[...r.keys()].sort();function nearestRegistered(e){for(let t=e;t;t=n.type_parent(t)){let e=n.type_name(t);if(!e)break;let i=r.get(e);if(i)return i}}function clearRegistry(){r.clear(),i.clear()}export{classOf,clearRegistry,hasClass,hasWidget,lookupWidget,nearestRegistered,registerWidget,registerWidgets,registeredTags,requireClass};
@@ -16,6 +16,25 @@ export declare class GtkHostError extends Error {
16
16
  }
17
17
  export declare const err: {
18
18
  unknownTag: (tag: string) => GtkHostError;
19
+ /**
20
+ * A row of the table naming a class the RUNNING typelib does not carry.
21
+ *
22
+ * The one absence a version cannot explain. The table is generated from one
23
+ * platform's GIR, and a platform does not BUILD every class GTK describes:
24
+ * the Unix print stack is `#ifdef`-ed out on Windows, so its two dialogs are
25
+ * in the GIR and in no `Gtk-4.0.typelib` that a Windows build produces. The
26
+ * generated half is a claim about a library release, not about this host, so
27
+ * the row is right and the class is not here — and `GtkPageSetupUnixDialog`
28
+ * is NOT the whole shape of the failure, because the next absent class is not
29
+ * spelled "Unix" either.
30
+ *
31
+ * So nothing in this host dereferences a row's class before asking: the
32
+ * refusal names the tag instead of letting `undefined.list_properties()` or
33
+ * `undefined.$gtype` report a defect against whatever row the caller happened
34
+ * to be walking. Same shape as `unknownTag` — a tag this process cannot
35
+ * honour is refused BY NAME, because GTK's own failure mode here is silence.
36
+ */
37
+ absentClass: (gtype: string) => GtkHostError;
19
38
  missingConstructProp: (tag: string, prop: string) => GtkHostError;
20
39
  unknownProp: (tag: string, prop: string) => GtkHostError;
21
40
  readOnlyProp: (tag: string, prop: string) => GtkHostError;
@@ -133,6 +133,17 @@ export interface InitFontsResult {
133
133
  * the map holds afterwards, which is what a match reads.
134
134
  */
135
135
  readonly matches: readonly FontFamilyMatch[];
136
+ /**
137
+ * `true` when this call REPLACED the process's default font map with a fontconfig-backed one
138
+ * so the faces could be registered at all — see {@link adoptFontconfigMap}.
139
+ *
140
+ * Reported because it is a whole-application consequence of one call: every widget created
141
+ * afterwards renders through FreeType instead of the platform rasteriser. It happens only
142
+ * where the default map DECLINED registration (a CoreText map — `gjsify run` on a Homebrew
143
+ * GTK), the faces brought a family that map does not already hold, fontconfig has a
144
+ * configuration of its own, and nobody pinned `PANGOCAIRO_BACKEND` (ADR 0038 § Amendment 5).
145
+ */
146
+ readonly fontconfigFallback: boolean;
136
147
  }
137
148
  /**
138
149
  * Did the font map decline runtime registration outright?
@@ -158,6 +169,18 @@ export interface InitFontsResult {
158
169
  * found and reversed instead.
159
170
  */
160
171
  export declare function isUnsupportedByFontMap(error: unknown): boolean;
172
+ /**
173
+ * `CAIRO_FONT_TYPE_FT` from `cairo.h` — the value `pango_cairo_font_map_new_for_font_type()` maps
174
+ * to its fontconfig backend.
175
+ *
176
+ * A literal rather than `gi://cairo`'s `FontType.FT`: this module runs on both legs (GJS and
177
+ * `@gjsify/node-gi`), and the enum is part of cairo's ABI, so importing a fourth namespace to
178
+ * spell one stable integer would add a load-time dependency for nothing.
179
+ *
180
+ * Exported so `fonts.spec.ts`'s independent probe spells the SAME integer rather than a second
181
+ * literal that could drift from this one silently — see § duplication instead of a helper.
182
+ */
183
+ export declare const CAIRO_FONT_TYPE_FT = 1;
161
184
  /**
162
185
  * Register every face in the application's shipped font directory with the default font map.
163
186
  *
@@ -3,9 +3,9 @@ export { GtkHostError } from './errors.js';
3
3
  export { adopt, createAnchor, createDetachedContainer, createElement, createText, destroyChildren, destroy, disconnectHandlers, firstChild, insert, isHostElement, isText, materialize, mountRoot, nextSibling, parentNode, prevSibling, remove, setElementText, setEventHandler, setProp, setSlot, setText, widgetOf, } from './host.js';
4
4
  export { addressOf, isPortal, placementOf, portalOf, reorderMode } from './policies.js';
5
5
  export { toSignalName, isEventProp } from './signals.js';
6
- export { constructOnlyNames, isConstructOnly, isWritable, lookupEnumNick, paramSpecs, toPropertyName, } from './props.js';
6
+ export { constructOnlyNames, gtypeOfName, isConstructOnly, isWritable, lookupEnumNick, paramSpecs, toPropertyName, } from './props.js';
7
7
  export { assertInjective, tagOf } from './tags.js';
8
8
  export { blankReason, checkRendered, probeEnabled, runHostProbe, runHostProbeApp, shotEvidence, type CaptureWidget, type HostProbe, type HostProbeApp, type ProbeCheck, type ShotEvidence, } from './probe.js';
9
9
  export type { AccessibilityAttribute, ElementChild, ElementChildren, JsxAttributes, RawSignalAttributes, SlotAttribute, VueAttributes, WithOnce, } from './attrs.js';
10
- export { clearRegistry, hasWidget, lookupWidget, nearestRegistered, registerWidget, registerWidgets, registeredTags, } from './registry.js';
10
+ export { clearRegistry, classOf, hasClass, hasWidget, lookupWidget, nearestRegistered, registerWidget, registerWidgets, registeredTags, requireClass, type InstalledClass, } from './registry.js';
11
11
  export { ADW_DESCRIPTORS, BUILTIN_DESCRIPTORS, CURATED_DESCRIPTORS, GENERATED_PROVENANCE, GENERATED_WIDGETS, GTK_DESCRIPTORS, mergeGenerated, registerBuiltinWidgets, tableProvenance, } from './descriptors/index.js';
@@ -23,6 +23,20 @@ export declare const isWritable: (spec: GObject.ParamSpec) => boolean;
23
23
  export declare const isConstructOnly: (spec: GObject.ParamSpec) => boolean;
24
24
  /** Construct-only property names of a class, in declaration order. */
25
25
  export declare function constructOnlyNames(klass: GObject.ObjectClass, gtypeName: string): string[];
26
+ /**
27
+ * The GType a name registers on this host, forcing the registration if it has to.
28
+ *
29
+ * `type_from_name` is asked FIRST because it is the answer that needs no table. It
30
+ * answers null until something has touched the type, which is why the table is still
31
+ * reachable at all: reading `Gio.PasswordSave` is what registers `GPasswordSave`.
32
+ *
33
+ * NEITHER BRANCH IS THE FIX ALONE, and the order is what makes the measured case work:
34
+ * a type nobody has read is absent from `type_from_name`, and a name
35
+ * {@link giTypeObject} cannot reach is absent from the table. Exported because it is
36
+ * THE answer to "does this host have that type" — a consumer gating on a GTK version
37
+ * asks here rather than walking a namespace list of its own.
38
+ */
39
+ export declare function gtypeOfName(gtypeName: string): GObject.GType | undefined;
26
40
  /**
27
41
  * The value a nick names on an enum or bitfield GType, or undefined if it names none.
28
42
  *
@@ -48,6 +62,14 @@ export declare const lookupEnumNick: (gtypeName: string, nick: string) => number
48
62
  * which is the whole remaining reason {@link GI_NAMESPACES} exists.
49
63
  *
50
64
  * `$gtype` and anything non-numeric are not members; GJS puts both on the same object.
65
+ *
66
+ * AND THE TYPE HAS TO BE ONE, or the widened {@link giTypeObject} turns this into a
67
+ * second answer rather than a wider one. It now returns a CLASS as readily as an enum,
68
+ * and a class carries no numeric members — `undefined` would be wrong (the type is
69
+ * there) and `[]` is worse (it reads as "an enum that registers nothing", which is the
70
+ * claim every caller is entitled to trust). The GType the lookup already confirmed is
71
+ * what asks, so this is the same predicate the nicks branches above are routed on
72
+ * rather than a new way of spelling it.
51
73
  */
52
74
  export declare function enumMembers(gtypeName: string): string[] | undefined;
53
75
  /**
@@ -28,7 +28,7 @@
28
28
  * The element list itself is the generated `WidgetPropsByTag`/`WidgetClassByTag`,
29
29
  * which `scripts/check-type-surfaces.mjs` already holds negative-first through its
30
30
  * `jsx` half. The React-specific plumbing below has no half yet — that gap, and
31
- * why adding one is not a one-liner, is in `status/open-todos.md`. Its RUNTIME
31
+ * why adding one is not a one-liner, is in `status/open-todos/README.md`. Its RUNTIME
32
32
  * half is `adapters/react.spec.ts`.
33
33
  */
34
34
  import type { Key, ReactElement, ReactNode, Ref } from 'react';
@@ -4,6 +4,60 @@ export declare function registerWidget(descriptor: WidgetDescriptor): void;
4
4
  export declare function registerWidgets(descriptors: readonly WidgetDescriptor[]): void;
5
5
  export declare function lookupWidget(tag: string): WidgetDescriptor;
6
6
  export declare const hasWidget: (tag: string) => boolean;
7
+ /** A row's class, in the shape every consumer here needs it. */
8
+ export type InstalledClass = GObject.ObjectClass & (new (props?: Record<string, unknown>) => GObject.Object);
9
+ /**
10
+ * The class the RUNNING typelib has for this row, or `null` when it has none.
11
+ *
12
+ * The general form of "does this GTK have that class", and the only honest place
13
+ * to ask it: the generated table is produced from ONE platform's GIR (#1446), and
14
+ * a platform does not build every class that GIR describes — GTK `#ifdef`s its
15
+ * Unix print stack out on Windows, so `GtkPrintUnixDialog` and
16
+ * `GtkPageSetupUnixDialog` are rows whose class is `undefined` there and a real
17
+ * class on Linux and macOS. Nothing narrower is available: the vocabulary comes
18
+ * from one GIR pool with no second platform to compare against, and a claim
19
+ * derived from a NAME (`*Unix*`) breaks precisely when it matters, on the next
20
+ * absent class nobody spelled that way.
21
+ *
22
+ * THE CAST is where the gap between the declared type and the runtime is
23
+ * admitted, ONCE, with the reason. `ctor` is typed as promising a constructor
24
+ * unconditionally, which is what lets `new Klass(props)` read as a constructor
25
+ * call; the promise is true on every host the table was generated on and false
26
+ * on a host that omits a class, and the admission belongs beside the question
27
+ * rather than at each of the dozen call sites.
28
+ *
29
+ * WHY THE ROW'S OWN `ctor()` IS THE ORACLE, and it is a measured trap rather
30
+ * than a stylistic choice. `GObject.type_from_name` is the one-call version of
31
+ * this question and it answers WRONG in the direction that costs a working row:
32
+ * measured on gjs 1.88.1 / Homebrew GTK 4.24.0, `type_from_name('GtkPrintUnixDialog')`
33
+ * answers **0** while `Gtk.PrintUnixDialog` is present and constructs — a typelib
34
+ * registers a class when the namespace member is first READ, not when the
35
+ * typelib loads. `ctor()` IS that read, which is why it answers correctly in
36
+ * both directions and why nothing here calls `type_from_name`. It also costs
37
+ * nothing to ask per row: an oracle over the WHOLE table has to force the
38
+ * registration of every class it walks, whereas a row is only ever asked about
39
+ * when something is about to use it.
40
+ */
41
+ export declare function classOf(descriptor: {
42
+ readonly ctor: () => unknown;
43
+ }): InstalledClass | null;
44
+ /** Whether this host has the class a row names — a table sweep's way to not be a row. */
45
+ export declare const hasClass: (descriptor: {
46
+ readonly ctor: () => unknown;
47
+ }) => boolean;
48
+ /**
49
+ * {@link classOf}, refusing BY NAME rather than handing back `undefined`.
50
+ *
51
+ * The single gate every read of a row's class goes through, so an absent class is
52
+ * one named refusal instead of six anonymous `TypeError`s — dereferencing it
53
+ * produced `Cannot read properties of undefined (reading 'list_properties')` and
54
+ * `… (reading '$gtype')` with no row in either message, which is how a
55
+ * one-platform-generated table arrived as six failures that named one class.
56
+ */
57
+ export declare function requireClass(descriptor: {
58
+ readonly gtype: string;
59
+ readonly ctor: () => unknown;
60
+ }): InstalledClass;
7
61
  /** Every registered GType name — the conformance suite walks this, so coverage is data. */
8
62
  export declare const registeredTags: () => string[];
9
63
  /**
@@ -10,9 +10,9 @@ export declare const gated: (gate: DiagnosticsGate, name: string, body: () => Pr
10
10
  * failure mode rather than taste.
11
11
  *
12
12
  * A capability can only be PROBED — nothing about `(os, env)` answers "is the Gtk
13
- * typelib reachable from this process", and `@gjsify/unit` is Tier 1 and must not
14
- * import `gi://` to find out. A probe that answers "no" makes the whole suite STAND
15
- * DOWN, and `requireAxes` cannot catch that: it only holds axes the host MATCHES.
13
+ * typelib reachable from this process". A probe that answers "no" makes the whole
14
+ * suite STAND DOWN, and `requireAxes` cannot catch that: it only holds axes the
15
+ * host MATCHES (`GJSIFY_TEST_EXPECT_AXES` can, but only on a leg that sets it).
16
16
  * So a container that lost its GTK would run zero tests and report success — the
17
17
  * green-that-checked-nothing shape, arriving through the very gate meant to widen
18
18
  * coverage. Measured once already: gated on `'Gjs'` alone, this suite built for the
@@ -426,6 +426,20 @@ export type ChildPolicy = {
426
426
  export interface GeneratedWidget {
427
427
  readonly gtype: string;
428
428
  readonly tag: string;
429
+ /**
430
+ * Availability-CONDITIONAL, and the declared type deliberately does not say so.
431
+ *
432
+ * A row comes from one platform's GIR, so on a platform whose GTK does not
433
+ * build the class this reads `Gtk.PrintUnixDialog` and gets `undefined` —
434
+ * the whole of GTK's Unix print stack is compiled out on win32 (#1446).
435
+ * Widening the signature to `| undefined` would force every `ctor()` reader
436
+ * to handle the absence, and they all handle it through ONE predicate
437
+ * instead (`classOf`/`requireClass`, `registry.ts`); annotating the signature
438
+ * as well would be a second statement of the same fact that nothing checks.
439
+ * The gap this leaves is real and deliberate: a reader that bypasses both
440
+ * gets `undefined` where the type promised a class — which is why every
441
+ * call site refuses rather than dereferences.
442
+ */
429
443
  readonly ctor: () => GObject.ObjectClass & (new (props?: Record<string, unknown>) => GObject.Object);
430
444
  }
431
445
  export interface WidgetDescriptor {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/gtk-host",
3
- "version": "0.52.0",
3
+ "version": "0.53.0",
4
4
  "description": "Framework-agnostic GTK4/Adwaita host: the element model UI-framework renderers bind to",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -75,8 +75,8 @@
75
75
  "build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}'",
76
76
  "build:types": "gjsify tsc",
77
77
  "build:test": "gjsify run build:test:gjs",
78
- "build:test:node": "gjsify build src/test.mts --app node --outfile dist/test.node.mjs --define __VUE_OPTIONS_API__=false --define __VUE_PROD_DEVTOOLS__=false --define __VUE_PROD_HYDRATION_MISMATCH_DETAILS__=false --define \"process.env.NODE_ENV='production'\" --exclude-globals navigator",
79
- "build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs --define __VUE_OPTIONS_API__=false --define __VUE_PROD_DEVTOOLS__=false --define __VUE_PROD_HYDRATION_MISMATCH_DETAILS__=false --define \"process.env.NODE_ENV='production'\" --exclude-globals navigator",
78
+ "build:test:node": "gjsify build src/test.mts --app node --outfile dist/test.node.mjs --define __VUE_OPTIONS_API__=false --define __VUE_PROD_DEVTOOLS__=false --define __VUE_PROD_HYDRATION_MISMATCH_DETAILS__=false --define \"process.env.NODE_ENV='production'\"",
79
+ "build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs --define __VUE_OPTIONS_API__=false --define __VUE_PROD_DEVTOOLS__=false --define __VUE_PROD_HYDRATION_MISMATCH_DETAILS__=false --define \"process.env.NODE_ENV='production'\"",
80
80
  "test": "gjsify run build:gjsify && gjsify run build:test && gjsify run test:gjs",
81
81
  "test:gjs": "gjsify run test.gjs.mjs",
82
82
  "test:gjs-on-node": "gjsify run build:gjsify && gjsify run build:test:node && node dist/test.node.mjs",
@@ -102,7 +102,7 @@
102
102
  "@girs/gtk-4.0": "5.4.0",
103
103
  "@girs/pango-1.0": "5.4.0",
104
104
  "@girs/pangocairo-1.0": "5.4.0",
105
- "@gjsify/adwaita-core": "^0.52.0"
105
+ "@gjsify/adwaita-core": "^0.53.0"
106
106
  },
107
107
  "peerDependencies": {
108
108
  "@vue/runtime-core": "^3.5.0",
@@ -125,10 +125,11 @@
125
125
  }
126
126
  },
127
127
  "devDependencies": {
128
- "@gjsify/cli": "^0.52.0",
128
+ "@gjsify/cli": "^0.53.0",
129
+ "@gjsify/utils": "^0.53.0",
129
130
  "@vue/runtime-core": "^3.5.0",
130
131
  "solid-js": "^1.9.0",
131
- "@gjsify/unit": "^0.52.0",
132
+ "@gjsify/unit": "^0.53.0",
132
133
  "@types/node": "^25.9.2",
133
134
  "typescript": "^6.0.3",
134
135
  "@gjsify/node-gi": "file:../../node-gi/node-gi",