@gjsify/adwaita-gobject-native 0.61.0 → 0.63.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
@@ -99,3 +99,12 @@ above is node-gi on Linux.
99
99
  slot is `'polyfill'` rather than `'none'`, which is an exception to the convention in
100
100
  [AGENTS.md](../AGENTS.md): node-gi makes the engine measurable on Linux CI, and a leg that cannot
101
101
  run is a claim nobody checks.
102
+
103
+ ## Settings and Gio.File
104
+
105
+ `createRealGioSettingsSubject` and `createRealGioFileChooserSubject` hold ADR 0099's
106
+ `SETTINGS_VECTORS` and ADR 0100's `FILE_CHOOSER_VECTORS` to real `Gio.Settings` and `Gio.File`.
107
+ Settings needs a compiled schema directory and the `memory` backend (never dconf); the subject
108
+ reads the schema from an explicit source because the default one is fixed at first use. Without a
109
+ Gtk typelib (Android) the file-chooser subject uses a stand-in and `rowsFor` drops the rows that
110
+ are about GTK. Report: `docs/reports/2026-10-12-real-gio-settings-file.md`.
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";function patternsOf(e){if(typeof e.to_gvariant!=`function`)return e.patterns;let[,t]=e.to_gvariant().recursiveUnpack();return t.map(([,e])=>e)}const e=[/^the enum members the subset raises/,/FileFilter/,/FileDialog/],t=[/^new GLib\.Error\(domain, code, message\) reads back/,/^a GLib\.Error names its domain when printed/];function rowsFor(n,r){let i=r.filter(e=>!t.some(t=>t.test(e.rule)));return n.realGtk?i:i.filter(t=>!(t.row===`dialog`||t.row===`filter`||e.some(e=>e.test(t.rule))))}function loadGtk(e){try{return e(`Gtk`,`4.0`)}catch{return null}}function createGtkStandIn(e){let t=e(`GObject`,`2.0`),n=t.registerClass({GTypeName:`GjsifyStandInFileFilter`,Properties:{name:t.ParamSpec.string(`name`,`name`,`name`,t.ParamFlags.READWRITE,null)}},class GjsifyStandInFileFilter extends t.Object{constructor(...e){super(...e),this.patterns=[]}static new(){return new GjsifyStandInFileFilter}get_name(){return this.name}set_name(e){this.name=e}add_pattern(e){this.patterns.push(e)}});class FileDialog{constructor(e={}){this.title=null,this.modal=!0,this.initial_name=null,this.filters=null,this.default_filter=null,Object.assign(this,e)}}let r={FAILED:0,CANCELLED:1,DISMISSED:2};return Object.defineProperty(r,Symbol.for(`nodeGiErrorDomain`),{value:{name:`gtk-dialog-error-quark`}}),{FileFilter:n,FileDialog,DialogError:r}}function createRealGioFileChooserSubject(e,{dir:t,standIn:n=!1}){let r=e(`GLib`,`2.0`),i=e(`Gio`,`2.0`),a=n?null:loadGtk(e);a?.init_check?.();let o=a??createGtkStandIn(e),s=null,c=[],answer=function(e,n,a){c=[];for(let e=0;this.filters&&e<this.filters.get_n_items();e++)c.push(patternsOf(this.filters.get_item(e)));let l;if(s===null)l={error:new r.Error(o.DialogError,o.DialogError.DISMISSED,`Dismissed by user`)};else{let e=i.File.new_for_path(r.build_filenamev([t,s.basename]));s.contents?.length?e.replace_contents(s.contents,null,!1,i.FileCreateFlags.NONE,null):s.contents&&e.replace(null,!1,i.FileCreateFlags.NONE,null).close(null),l={file:e}}r.idle_add(r.PRIORITY_DEFAULT,()=>(a(this,l),r.SOURCE_REMOVE))},finish=e=>{if(`error`in e)throw e.error;return e.file};return Object.assign(o.FileDialog.prototype,{open:answer,save:answer,open_finish:finish,save_finish:finish}),{name:a?`node-gi (real Gio and Gtk)`:`node-gi (real Gio, Gtk stand-in)`,isOracle:!0,realGtk:a!==null,GLib:r,Gio:i,Gtk:o,script:e=>void(s=e),pickerFilters:()=>c,cancelled:()=>{let e=new i.Cancellable;return e.cancel(),e},dispose:()=>{let e=i.File.new_for_path(t),n=e.enumerate_children(`standard::name`,0,null);for(let e=n.next_file(null);e;e=n.next_file(null))n.get_child(e).delete(null);e.delete(null)}}}export{createRealGioFileChooserSubject,rowsFor};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{createRealGioEngine as e}from"./engine.js";import{useRealGObjectEngine as t}from"./opt-in.js";import{createRealGioListStore as n}from"./list-store.js";import{SUBSET_SUBJECT_NAME as r,createSubsetSubject as i}from"./vector-subject.js";export{r as SUBSET_SUBJECT_NAME,e as createRealGioEngine,n as createRealGioListStore,i as createSubsetSubject,t as useRealGObjectEngine};
1
+ import{createRealGioEngine as e}from"./engine.js";import{createRealGioFileChooserSubject as t,rowsFor as n}from"./file-chooser-subject.js";import{useRealGObjectEngine as r}from"./opt-in.js";import{createRealGioListStore as i}from"./list-store.js";import{SUBSET_SUBJECT_NAME as a,createSubsetSubject as o}from"./vector-subject.js";import{createRealGioSettingsSubject as s}from"./settings-subject.js";export{a as SUBSET_SUBJECT_NAME,e as createRealGioEngine,t as createRealGioFileChooserSubject,i as createRealGioListStore,s as createRealGioSettingsSubject,o as createSubsetSubject,n as rowsFor,r as useRealGObjectEngine};
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";function createRealGioSettingsSubject(e,{schemaDir:t,schemaId:n}){let r=e(`GLib`,`2.0`);r.setenv(`GSETTINGS_SCHEMA_DIR`,t,!0),r.setenv(`GSETTINGS_BACKEND`,`memory`,!0);let i=e(`Gio`,`2.0`),a=i.SettingsSchemaSource.new_from_directory(t,null,!1),o=new Proxy(i.Settings,{construct(e,t){let{schema_id:n,...r}=t[0]??{},i=n===void 0?null:a.lookup(n,!1);return Reflect.construct(e,i?[{...r,settings_schema:i}]:t)}});return{name:`node-gi (real Gio.Settings, memory backend)`,isOracle:!0,Settings:o,reset:()=>{let e=new o({schema_id:n});for(let t of e.list_keys())e.reset(t)}}}export{createRealGioSettingsSubject};
@@ -0,0 +1,38 @@
1
+ import type { RequireGi } from './engine.js';
2
+ /** What the next `open`/`save` picks: a file named `basename` (holding `contents`, if given), or a dismissal. */
3
+ export type RealScriptedPick = {
4
+ readonly basename: string;
5
+ readonly contents?: Uint8Array;
6
+ } | null;
7
+ /** The `FileChooserSubject` of `@gjsify/adwaita-core/conformance`, restated structurally. */
8
+ export interface RealGioFileChooserSubject {
9
+ readonly name: string;
10
+ readonly isOracle: boolean;
11
+ readonly GLib: any;
12
+ readonly Gio: any;
13
+ readonly Gtk: any;
14
+ script(pick: RealScriptedPick): void;
15
+ pickerFilters(): string[][];
16
+ cancelled(): unknown;
17
+ /** `true` when `Gtk` is the real namespace, `false` on the stand-in. */
18
+ readonly realGtk: boolean;
19
+ /** Removes the temporary directory the picks were made in. */
20
+ dispose(): void;
21
+ }
22
+ export interface RealGioFileChooserOptions {
23
+ /** A directory the picks land in; the subject creates files in it and `dispose` empties it. */
24
+ readonly dir: string;
25
+ /** Use the Gtk stand-in even where Gtk loads: how the Android path is exercised on a host. */
26
+ readonly standIn?: boolean;
27
+ }
28
+ /** The vectors a subject can answer: all of them on real GTK, those not about GTK otherwise. */
29
+ export declare function rowsFor<V extends {
30
+ readonly rule: string;
31
+ readonly row: string;
32
+ }>(subject: Pick<RealGioFileChooserSubject, 'realGtk'>, vectors: readonly V[]): V[];
33
+ /**
34
+ * The subject for `FILE_CHOOSER_VECTORS` over real Gio. `isOracle` is `true`: GLib and Gio ARE the
35
+ * real classes, so the subset-only refusals (a picked file has no path, a cancelled `open`,
36
+ * the ADR 0100 § 2 refusals) are skipped exactly as on the GJS leg.
37
+ */
38
+ export declare function createRealGioFileChooserSubject(requireGi: RequireGi, { dir, standIn }: RealGioFileChooserOptions): RealGioFileChooserSubject;
@@ -0,0 +1,2 @@
1
+ import type { RequireGi } from './engine.js';
2
+ export declare const realGioFileChooserSuite: (requireGi: RequireGi, standIn?: boolean) => () => Promise<void>;
@@ -4,3 +4,7 @@ export type { RequireGi } from './engine.js';
4
4
  export { createRealGioListStore } from './list-store.js';
5
5
  export type { RealGioListStore } from './list-store.js';
6
6
  export { createSubsetSubject, SUBSET_SUBJECT_NAME } from './vector-subject.js';
7
+ export { createRealGioSettingsSubject } from './settings-subject.js';
8
+ export type { RealGioSettingsOptions, RealGioSettingsSubject } from './settings-subject.js';
9
+ export { createRealGioFileChooserSubject, rowsFor } from './file-chooser-subject.js';
10
+ export type { RealGioFileChooserOptions, RealGioFileChooserSubject } from './file-chooser-subject.js';
@@ -0,0 +1,27 @@
1
+ import type { RequireGi } from './engine.js';
2
+ /** The shape `SETTINGS_VECTORS` drive; structural, so this package needs no dependency on the vectors. */
3
+ export interface RealGioSettingsSubject {
4
+ readonly name: string;
5
+ readonly isOracle: boolean;
6
+ readonly Settings: new (props: {
7
+ schema_id: string;
8
+ path?: string;
9
+ }) => {
10
+ readonly schema_id: string;
11
+ readonly path: string;
12
+ [method: string]: any;
13
+ };
14
+ /** Forgets everything written, so a vector starts from the defaults. */
15
+ reset(): void;
16
+ }
17
+ export interface RealGioSettingsOptions {
18
+ /** A directory holding the compiled `gschemas.compiled` of the schema under test. */
19
+ readonly schemaDir: string;
20
+ /** The schema id `reset` clears; the vectors' own schema. */
21
+ readonly schemaId: string;
22
+ }
23
+ /**
24
+ * The subject for `SETTINGS_VECTORS` over real Gio. `isOracle` is `true`: this is real `Gio.Settings`,
25
+ * so the subset-only refusals are skipped exactly as on the GJS leg.
26
+ */
27
+ export declare function createRealGioSettingsSubject(requireGi: RequireGi, { schemaDir, schemaId }: RealGioSettingsOptions): RealGioSettingsSubject;
@@ -0,0 +1,2 @@
1
+ import type { RequireGi } from './engine.js';
2
+ export declare const realGioSettingsSuite: (requireGi: RequireGi) => () => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/adwaita-gobject-native",
3
- "version": "0.61.0",
3
+ "version": "0.63.0",
4
4
  "description": "Real GObject behind @gjsify/adwaita-core's GObject subset — a GObjectEngine whose property store and signal bus are a live GObject reached through node-gi (ADR 0105)",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -36,12 +36,13 @@
36
36
  "adwaita"
37
37
  ],
38
38
  "dependencies": {
39
- "@gjsify/adwaita-core": "^0.61.0"
39
+ "@gjsify/adwaita-core": "^0.63.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@gjsify/cli": "^0.61.0",
42
+ "@gjsify/app-settings": "^0.63.0",
43
+ "@gjsify/cli": "^0.63.0",
43
44
  "@gjsify/node-gi": "file:../../node-gi/node-gi",
44
- "@gjsify/unit": "^0.61.0",
45
+ "@gjsify/unit": "^0.63.0",
45
46
  "@types/node": "^25.9.2",
46
47
  "typescript": "^6.0.3"
47
48
  },