From c2bb6b6fe37684ef6f57df6fb263b0fbace4a9d0 Mon Sep 17 00:00:00 2001 From: Steven Vandevelde Date: Sat, 17 May 2025 22:46:32 +0200 Subject: [PATCH] fix: input/native-fs uri improvements --- deno.lock | 1 + package-lock.json | 35 ++++++++++++++----------- package.json | 2 +- src/pages/input/native-fs/_applet.astro | 25 +++++++++++------- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/deno.lock b/deno.lock index f04e3cf..287d2df 100644 --- a/deno.lock +++ b/deno.lock @@ -35,6 +35,7 @@ "npm:sass@^1.87.0", "npm:spellcaster@6", "npm:throttle-debounce@^5.0.2", + "npm:uri-js@^4.4.1", "npm:xxh32@^2.0.5" ] } diff --git a/package-lock.json b/package-lock.json index 3507cdb..14ee467 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "@atcute/cid": "^2.2.2", "@picocss/pico": "^2.1.1", "@web-applets/sdk": "https://gitpkg.vercel.app/unternet-co/web-applets/sdk?feat/child-context&scripts.postinstall=npm%20i%20%40types%2Fnode%20%26%26%20npx%20tsc", - "fast-uri": "^3.0.6", "iconoir": "^7.11.0", "idb-keyval": "^6.2.1", "native-file-system-adapter": "^3.0.1", "query-string": "^9.1.2", "spellcaster": "^6.0.0", "throttle-debounce": "^5.0.2", + "uri-js": "^4.4.1", "xxh32": "^2.0.5" }, "devDependencies": { @@ -2630,21 +2630,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ] - }, "node_modules/fdir": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", @@ -4514,6 +4499,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/purgecss": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-7.0.2.tgz", @@ -5547,6 +5541,15 @@ } } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 7719265..57523b4 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,13 @@ "@atcute/cid": "^2.2.2", "@picocss/pico": "^2.1.1", "@web-applets/sdk": "https://gitpkg.vercel.app/unternet-co/web-applets/sdk?feat/child-context&scripts.postinstall=npm%20i%20%40types%2Fnode%20%26%26%20npx%20tsc", - "fast-uri": "^3.0.6", "iconoir": "^7.11.0", "idb-keyval": "^6.2.1", "native-file-system-adapter": "^3.0.1", "query-string": "^9.1.2", "spellcaster": "^6.0.0", "throttle-debounce": "^5.0.2", + "uri-js": "^4.4.1", "xxh32": "^2.0.5" }, "devDependencies": { diff --git a/src/pages/input/native-fs/_applet.astro b/src/pages/input/native-fs/_applet.astro index 3af21b4..9fd9149 100644 --- a/src/pages/input/native-fs/_applet.astro +++ b/src/pages/input/native-fs/_applet.astro @@ -3,12 +3,14 @@ import { applets } from "@web-applets/sdk"; import { type FileSystemDirectoryHandle, showDirectoryPicker } from "native-file-system-adapter"; + import * as URI from "uri-js"; import QS from "query-string"; - import URI from "fast-uri"; import type { Track } from "@applets/core/types.d.ts"; import { isAudioFile } from "@scripts/inputs/common"; + import manifest from "./_manifest.json"; + type Handles = Record; // TODO: Add ability to list cached tracks from other devices (ie. unknown handle ids) @@ -18,6 +20,7 @@ //////////////////////////////////////////// const IDB_PREFIX = "@applets/input/native-fs"; const IDB_HANDLES = `${IDB_PREFIX}/handles`; + const INPUT_SCHEME = manifest.input_properties.scheme; const context = applets.register(); @@ -25,6 +28,14 @@ // ACTIONS //////////////////////////////////////////// const isAvailable = async (fileUri: string) => { + const isSupported = !!(globalThis as any).showDirectoryPicker; + if (!isSupported) { + console.warn( + "`input/native-fs` is not supported on this platform, missing File System Access API.", + ); + return false; + } + const handles = await fetchHandles(); const uri = URI.parse(fileUri); return uri.host && !!handles[uri.host]; @@ -79,20 +90,17 @@ const resolve = async (fileUri: string) => { const uri = URI.parse(fileUri); - if (uri.scheme !== "file+local") return undefined; + if (uri.scheme !== INPUT_SCHEME) return undefined; if (!uri.host || !uri.path) return undefined; const handles = await fetchHandles(); const handle = handles[uri.host]; if (!handle) return undefined; - const parts = (uri.path.startsWith("/") ? uri.path.slice(1) : uri.path) - .split("/") - .map((a) => decodeURIComponent(a)); + const path = URI.unescapeComponent(uri.path); + const parts = (path.startsWith("/") ? path.slice(1) : path).split("/"); const filename = parts[parts.length - 1]; - console.log(parts); - const dirHandle = await parts .slice(0, -1) .reduce( @@ -101,7 +109,6 @@ part: string, ): Promise => { const h = await acc; - console.log("→", part); return await h.getDirectoryHandle(part); }, Promise.resolve(handle), @@ -168,7 +175,7 @@ for await (const item of dir.values()) { if (item.kind === "file" && isAudioFile(item.name)) { const uri = URI.serialize({ - scheme: "file+local", + scheme: INPUT_SCHEME, host: rootHandleId, path: `${path.length ? "/" + path.join("/") : ""}/${item.name}`, }); -- 2.51.2