@gjsify/file-chooser 0.0.0-stage → 0.61.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 +59 -2
- package/lib/esm/_virtual/_rolldown/runtime.js +1 -0
- package/lib/esm/conformance.js +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/platform.gtk.js +1 -0
- package/lib/esm/platform.js +1 -0
- package/lib/esm/platform.native.js +1 -0
- package/lib/esm/platform.web.js +1 -0
- package/lib/types/conformance.d.ts +2 -0
- package/lib/types/index.browser.spec.d.ts +2 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.gjs.spec.d.ts +2 -0
- package/lib/types/platform.d.ts +1 -0
- package/lib/types/platform.gtk.d.ts +17 -0
- package/lib/types/platform.native.d.ts +30 -0
- package/lib/types/platform.web.d.ts +30 -0
- package/package.json +81 -5
package/README.md
CHANGED
|
@@ -1,3 +1,60 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @gjsify/file-chooser
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`Gtk.FileDialog`, `Gtk.FileFilter` and `Gio.File` as one import on GJS, the browser and
|
|
4
|
+
NativeScript ([ADR 0100](../../../docs/adr/0100-file-dialog-and-gio-file-run-on-the-browser-and-nativescript.md)).
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { FileDialog, FileFilter, File, ListStore, promisify } from '@gjsify/file-chooser';
|
|
8
|
+
|
|
9
|
+
promisify(FileDialog.prototype, 'open', 'open_finish');
|
|
10
|
+
promisify(File.prototype, 'load_contents_async', 'load_contents_finish');
|
|
11
|
+
|
|
12
|
+
const filter = FileFilter.new();
|
|
13
|
+
filter.set_name('Assembly');
|
|
14
|
+
filter.add_suffix('asm');
|
|
15
|
+
const filters = new ListStore({ item_type: FileFilter.$gtype });
|
|
16
|
+
filters.append(filter);
|
|
17
|
+
|
|
18
|
+
const file = await new FileDialog({ filters }).open(window, null);
|
|
19
|
+
const [contents] = await file.load_contents_async(null);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Target | What you get |
|
|
23
|
+
|---|---|
|
|
24
|
+
| GJS | the native `gi://` classes, by identity; the xdg portal is the dialog |
|
|
25
|
+
| browser | File System Access where `showSaveFilePicker` exists, otherwise a self-drawn Adwaita dialog over the Origin Private File System |
|
|
26
|
+
| NativeScript (Android) | the Storage Access Framework (`ACTION_OPEN_DOCUMENT` / `ACTION_CREATE_DOCUMENT`) |
|
|
27
|
+
|
|
28
|
+
The package is a strict SUBSET of the GJS API: the same names and semantics, and anything outside
|
|
29
|
+
the subset (`File.new_for_uri`, `get_parent`, `query_exists`, non-modal dialogs, `open_multiple`,
|
|
30
|
+
glob patterns other than `*.ext` and `*`, …) throws `UnsupportedGObjectError` rather than guessing.
|
|
31
|
+
|
|
32
|
+
## Recommended import path
|
|
33
|
+
|
|
34
|
+
- An app written against `gi://` that you build with `gjsify build --gi-renderer` needs nothing
|
|
35
|
+
from here: `gi://Gtk` and `gi://Gio` already resolve to the renderer, which carries the same
|
|
36
|
+
subset.
|
|
37
|
+
- Code that imports `@gjsify/file-chooser` gets the right door per target through gjsify's
|
|
38
|
+
platform files (`platform.gtk.ts` / `platform.web.ts` / `platform.native.ts`). A bundler
|
|
39
|
+
without those chains gets the base, which has no driver: every `open`/`save` rejects
|
|
40
|
+
`Gtk.DialogError.FAILED` until you call `registerFileChooserDriver()`.
|
|
41
|
+
|
|
42
|
+
## Behaviour you should know about
|
|
43
|
+
|
|
44
|
+
- **A save is not atomic on the ports.** `replace_async` truncates and writes in place; GJS writes
|
|
45
|
+
a temporary file and renames it. A crash mid-write leaves a partial file on the web and Android.
|
|
46
|
+
- **OPFS is invisible to the file manager.** On a browser without File System Access, files live
|
|
47
|
+
in the origin's private storage. The dialog's "Upload…" copies a picked file in; nothing is ever
|
|
48
|
+
saved as a download.
|
|
49
|
+
- **Persistence is the app's call.** The browser may evict OPFS under storage pressure; call
|
|
50
|
+
`navigator.storage.persist()` yourself if your files must survive that.
|
|
51
|
+
- **Android filters by MIME type.** An extension-only filter (`add_suffix('asm')`) opens `*/*`
|
|
52
|
+
and accepts any pick: the filter is a hint, as is usual on Android.
|
|
53
|
+
- **`etag` is `null` on the ports**; the browser has no user activation outside a gesture, so a
|
|
54
|
+
dialog opened then rejects `Gtk.DialogError.FAILED`.
|
|
55
|
+
- **iOS has no picker yet**: `open`/`save` reject `FAILED`.
|
|
56
|
+
|
|
57
|
+
## Conformance
|
|
58
|
+
|
|
59
|
+
`@gjsify/file-chooser/conformance` exports `FILE_CHOOSER_VECTORS` and `driveFileChooserVectors`,
|
|
60
|
+
the same vectors that run against real GJS, for anyone writing a driver of their own.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.defineProperty,__name=(t,n)=>e(t,`name`,{value:n,configurable:!0});export{__name};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FILE_CHOOSER_ROWS as e,FILE_CHOOSER_VECTORS as t,driveFileChooserVectors as n,promisifyFileChooser as r}from"@gjsify/adwaita-core/conformance";export{e as FILE_CHOOSER_ROWS,t as FILE_CHOOSER_VECTORS,n as driveFileChooserVectors,r as promisifyFileChooser};
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Bytes as e,DialogError as t,File as n,FileCreateFlags as r,FileDialog as i,FileFilter as a,FileOutputStream as o,GLibError as s,IOErrorEnum as c,ListStore as l,OutputStream as u,promisify as d,registerFileChooserDriver as f}from"./platform.js";export{e as Bytes,t as DialogError,n as File,r as FileCreateFlags,i as FileDialog,a as FileFilter,o as FileOutputStream,s as GLibError,c as IOErrorEnum,l as ListStore,u as OutputStream,d as promisify,f as registerFileChooserDriver};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://Gio?version=2.0";import t from"gi://GLib?version=2.0";import n from"gi://Gtk?version=4.0";const r=n.FileDialog,i=n.FileFilter,a=n.DialogError,o=e.File,s=e.ListStore,c=e.OutputStream,l=e.FileOutputStream,u=e.FileCreateFlags,d=e.IOErrorEnum,f=e._promisify,p=t.Bytes,m=t.Error;function registerFileChooserDriver(e){throw Error(`registerFileChooserDriver() has no effect on GJS: Gtk.FileDialog is native there and the xdg portal is its driver (ADR 0101).`)}export{p as Bytes,a as DialogError,o as File,u as FileCreateFlags,r as FileDialog,i as FileFilter,l as FileOutputStream,m as GLibError,d as IOErrorEnum,s as ListStore,c as OutputStream,f as promisify,registerFileChooserDriver};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DialogError as e,FileCreateFlags as t,GLibBytes as n,GLibError as r,GioFile as i,GioFileOutputStream as a,GioListStore as o,GioOutputStream as s,GtkFileDialog as c,GtkFileFilter as l,IOErrorEnum as u,promisify as d,registerFileChooserDriver as f}from"@gjsify/adwaita-core";export{n as Bytes,e as DialogError,i as File,t as FileCreateFlags,c as FileDialog,l as FileFilter,a as FileOutputStream,r as GLibError,u as IOErrorEnum,o as ListStore,s as OutputStream,d as promisify,f as registerFileChooserDriver};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerFileChooserDriver as e}from"@gjsify/adwaita-core";import{GLib as t,Gio as n,Gtk as r}from"@gjsify/adwaita-nativescript";const i=r.FileDialog,a=r.FileFilter,o=r.DialogError,s=n.File,c=n.ListStore,l=n.OutputStream,u=n.FileOutputStream,d=n.FileCreateFlags,f=n.IOErrorEnum,p=n._promisify,m=t.Bytes,h=t.Error;export{m as Bytes,o as DialogError,s as File,d as FileCreateFlags,i as FileDialog,a as FileFilter,u as FileOutputStream,h as GLibError,f as IOErrorEnum,c as ListStore,l as OutputStream,p as promisify,e as registerFileChooserDriver};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerFileChooserDriver as e}from"@gjsify/adwaita-core";import{GLib as t,Gio as n,Gtk as r}from"@gjsify/adwaita-web";const i=r.FileDialog,a=r.FileFilter,o=r.DialogError,s=n.File,c=n.ListStore,l=n.OutputStream,u=n.FileOutputStream,d=n.FileCreateFlags,f=n.IOErrorEnum,p=n._promisify,m=t.Bytes,h=t.Error;export{m as Bytes,o as DialogError,s as File,d as FileCreateFlags,i as FileDialog,a as FileFilter,u as FileOutputStream,h as GLibError,f as IOErrorEnum,c as ListStore,l as OutputStream,p as promisify,e as registerFileChooserDriver};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { FILE_CHOOSER_ROWS, FILE_CHOOSER_VECTORS, driveFileChooserVectors, promisifyFileChooser, } from '@gjsify/adwaita-core/conformance';
|
|
2
|
+
export type { FileChooserNamespaces, FileChooserRow, FileChooserSubject, FileChooserVector, ScriptedPick, } from '@gjsify/adwaita-core/conformance';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { FileDialog, FileFilter, File, ListStore, OutputStream, FileOutputStream, FileCreateFlags, IOErrorEnum, DialogError, Bytes, GLibError, promisify, registerFileChooserDriver, } from './platform.js';
|
|
2
|
+
export type { FileChooserDriver, FileChooserHandle, FileChooserRequest, FileChooserWriter } from '@gjsify/adwaita-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GtkFileDialog as FileDialog, GtkFileFilter as FileFilter, GioFile as File, GioListStore as ListStore, GioOutputStream as OutputStream, GioFileOutputStream as FileOutputStream, FileCreateFlags, IOErrorEnum, DialogError, GLibBytes as Bytes, GLibError, promisify, registerFileChooserDriver, } from '@gjsify/adwaita-core';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Gio from 'gi://Gio?version=2.0';
|
|
2
|
+
import GLib from 'gi://GLib?version=2.0';
|
|
3
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
4
|
+
import type { FileChooserDriver } from '@gjsify/adwaita-core';
|
|
5
|
+
export declare const FileDialog: typeof Gtk.FileDialog;
|
|
6
|
+
export declare const FileFilter: typeof Gtk.FileFilter;
|
|
7
|
+
export declare const DialogError: typeof Gtk.DialogError;
|
|
8
|
+
export declare const File: Gio.FileNamespace & (new () => Gio.File);
|
|
9
|
+
export declare const ListStore: typeof Gio.ListStore;
|
|
10
|
+
export declare const OutputStream: typeof Gio.OutputStream;
|
|
11
|
+
export declare const FileOutputStream: typeof Gio.FileOutputStream;
|
|
12
|
+
export declare const FileCreateFlags: typeof Gio.FileCreateFlags;
|
|
13
|
+
export declare const IOErrorEnum: typeof Gio.IOErrorEnum;
|
|
14
|
+
export declare const promisify: typeof Gio._promisify;
|
|
15
|
+
export declare const Bytes: typeof GLib.Bytes;
|
|
16
|
+
export declare const GLibError: typeof GLib.Error;
|
|
17
|
+
export declare function registerFileChooserDriver(_next: FileChooserDriver | null): FileChooserDriver | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Gio, GLib, Gtk } from '@gjsify/adwaita-nativescript';
|
|
2
|
+
import { registerFileChooserDriver } from '@gjsify/adwaita-core';
|
|
3
|
+
export declare const FileDialog: typeof Gtk.FileDialog;
|
|
4
|
+
export declare const FileFilter: typeof Gtk.FileFilter;
|
|
5
|
+
export declare const DialogError: Readonly<{
|
|
6
|
+
FAILED: number;
|
|
7
|
+
CANCELLED: number;
|
|
8
|
+
DISMISSED: number;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const File: typeof Gio.File;
|
|
11
|
+
export declare const ListStore: typeof Gio.ListStore;
|
|
12
|
+
export declare const OutputStream: typeof Gio.OutputStream;
|
|
13
|
+
export declare const FileOutputStream: typeof Gio.FileOutputStream;
|
|
14
|
+
export declare const FileCreateFlags: Readonly<{
|
|
15
|
+
NONE: 0;
|
|
16
|
+
PRIVATE: 1;
|
|
17
|
+
REPLACE_DESTINATION: 2;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const IOErrorEnum: Readonly<{
|
|
20
|
+
FAILED: number;
|
|
21
|
+
NOT_FOUND: number;
|
|
22
|
+
NOT_SUPPORTED: number;
|
|
23
|
+
CLOSED: number;
|
|
24
|
+
CANCELLED: number;
|
|
25
|
+
PENDING: number;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const promisify: typeof Gio._promisify;
|
|
28
|
+
export declare const Bytes: typeof GLib.Bytes;
|
|
29
|
+
export declare const GLibError: typeof GLib.Error;
|
|
30
|
+
export { registerFileChooserDriver };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Gio, GLib, Gtk } from '@gjsify/adwaita-web';
|
|
2
|
+
import { registerFileChooserDriver } from '@gjsify/adwaita-core';
|
|
3
|
+
export declare const FileDialog: typeof Gtk.FileDialog;
|
|
4
|
+
export declare const FileFilter: typeof Gtk.FileFilter;
|
|
5
|
+
export declare const DialogError: Readonly<{
|
|
6
|
+
FAILED: number;
|
|
7
|
+
CANCELLED: number;
|
|
8
|
+
DISMISSED: number;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const File: typeof Gio.File;
|
|
11
|
+
export declare const ListStore: typeof Gio.ListStore;
|
|
12
|
+
export declare const OutputStream: typeof Gio.OutputStream;
|
|
13
|
+
export declare const FileOutputStream: typeof Gio.FileOutputStream;
|
|
14
|
+
export declare const FileCreateFlags: Readonly<{
|
|
15
|
+
NONE: 0;
|
|
16
|
+
PRIVATE: 1;
|
|
17
|
+
REPLACE_DESTINATION: 2;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const IOErrorEnum: Readonly<{
|
|
20
|
+
FAILED: number;
|
|
21
|
+
NOT_FOUND: number;
|
|
22
|
+
NOT_SUPPORTED: number;
|
|
23
|
+
CLOSED: number;
|
|
24
|
+
CANCELLED: number;
|
|
25
|
+
PENDING: number;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const promisify: typeof Gio._promisify;
|
|
28
|
+
export declare const Bytes: typeof GLib.Bytes;
|
|
29
|
+
export declare const GLibError: typeof GLib.Error;
|
|
30
|
+
export { registerFileChooserDriver };
|
package/package.json
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@gjsify/file-chooser",
|
|
3
|
+
"version": "0.61.0",
|
|
4
|
+
"description": "Gtk.FileDialog, Gtk.FileFilter and Gio.File as one import on GJS, the browser and NativeScript: the native classes on GJS, File System Access or a self-drawn OPFS dialog on the web, the Storage Access Framework on Android",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"gjs",
|
|
7
|
+
"gtk",
|
|
8
|
+
"gio",
|
|
9
|
+
"file-dialog",
|
|
10
|
+
"file-system-access",
|
|
11
|
+
"opfs",
|
|
12
|
+
"nativescript",
|
|
13
|
+
"storage-access-framework"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "lib/esm/index.js",
|
|
17
|
+
"module": "lib/esm/index.js",
|
|
18
|
+
"types": "lib/types/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./lib/types/index.d.ts",
|
|
22
|
+
"default": "./lib/esm/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./conformance": {
|
|
25
|
+
"types": "./lib/types/conformance.d.ts",
|
|
26
|
+
"default": "./lib/esm/conformance.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"lib",
|
|
32
|
+
"!lib/types/**/*.spec.d.ts",
|
|
33
|
+
"!lib/types/test.d.mts"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"clear": "gjsify clear lib tmp tsconfig.tsbuildinfo test.gjs.mjs dist",
|
|
37
|
+
"check": "gjsify tsc --noEmit",
|
|
38
|
+
"build": "gjsify run build:gjsify && gjsify run build:types",
|
|
39
|
+
"build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}' 'src/test.browser.{mts,ts}'",
|
|
40
|
+
"build:types": "gjsify tsc",
|
|
41
|
+
"build:test": "gjsify run build:test:gjs",
|
|
42
|
+
"build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
|
|
43
|
+
"build:test:browser": "gjsify build src/test.browser.mts --app browser --outfile dist/test.browser.mjs",
|
|
44
|
+
"test": "gjsify run build:gjsify && gjsify run build:test && gjsify run test:gjs",
|
|
45
|
+
"test:gjs": "gjsify run test.gjs.mjs"
|
|
46
|
+
},
|
|
47
|
+
"gjsify": {
|
|
48
|
+
"runtimes": {
|
|
49
|
+
"gjs": "polyfill",
|
|
50
|
+
"node": "none",
|
|
51
|
+
"browser": "polyfill",
|
|
52
|
+
"nativescript": "polyfill"
|
|
53
|
+
},
|
|
54
|
+
"tier": 3
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@gjsify/adwaita-core": "^0.61.0",
|
|
58
|
+
"@gjsify/adwaita-nativescript": "^0.61.0",
|
|
59
|
+
"@gjsify/adwaita-web": "^0.61.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@girs/gio-2.0": "5.4.0",
|
|
63
|
+
"@girs/gjs": "5.4.0",
|
|
64
|
+
"@girs/glib-2.0": "5.4.0",
|
|
65
|
+
"@girs/gtk-4.0": "5.4.0",
|
|
66
|
+
"@gjsify/cli": "^0.61.0",
|
|
67
|
+
"@gjsify/unit": "^0.61.0",
|
|
68
|
+
"@types/node": "^25.9.2",
|
|
69
|
+
"typescript": "^6.0.3"
|
|
70
|
+
},
|
|
71
|
+
"author": "Pascal Garber <pascal@artandcode.studio>",
|
|
72
|
+
"license": "MIT",
|
|
73
|
+
"repository": {
|
|
74
|
+
"type": "git",
|
|
75
|
+
"url": "git+https://github.com/gjsify/gjsify.git",
|
|
76
|
+
"directory": "packages/framework/file-chooser"
|
|
77
|
+
},
|
|
78
|
+
"bugs": {
|
|
79
|
+
"url": "https://github.com/gjsify/gjsify/issues"
|
|
80
|
+
},
|
|
81
|
+
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/framework/file-chooser#readme"
|
|
82
|
+
}
|