Files
WRNexusJS/packages/native/src/browser.ts
T
2026-07-12 15:55:18 +05:30

122 lines
4.0 KiB
TypeScript

import type { NativeCapability } from "./types.ts";
type ShareOptions = { title?: string; text?: string; url?: string };
type PositionOptions = globalThis.PositionOptions;
export const browserCapabilities: Record<string, NativeCapability> = {
"clipboard.write": {
browser: {
supported: () => typeof navigator !== "undefined" && !!navigator.clipboard?.writeText,
run: (options) =>
navigator.clipboard.writeText(String((options as { text?: unknown })?.text ?? "")),
},
},
share: {
browser: {
supported: () => typeof navigator !== "undefined" && typeof navigator.share === "function",
run: (options) => navigator.share(options as ShareOptions),
},
},
geolocation: {
browser: {
supported: () => typeof navigator !== "undefined" && !!navigator.geolocation,
run: (options) =>
new Promise((resolve, reject) =>
navigator.geolocation.getCurrentPosition(resolve, reject, options as PositionOptions),
),
},
},
network: {
browser: {
supported: () => typeof navigator !== "undefined",
run: () => ({ connected: navigator.onLine }),
},
},
camera: {
browser: {
supported: () => typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia,
run: (options) =>
navigator.mediaDevices.getUserMedia({ video: options ?? true, audio: false }),
},
},
"storage.get": {
browser: {
supported: () => typeof localStorage !== "undefined",
run: (options) => ({
value: localStorage.getItem(String((options as { key?: unknown })?.key ?? "")),
}),
},
},
"storage.set": {
browser: {
supported: () => typeof localStorage !== "undefined",
run: (options) => {
const value = options as { key?: unknown; value?: unknown };
localStorage.setItem(String(value?.key ?? ""), String(value?.value ?? ""));
},
},
},
"notifications.schedule": {
browser: {
supported: () => typeof Notification !== "undefined",
run: async (options) => {
if (Notification.permission === "default") await Notification.requestPermission();
if (Notification.permission !== "granted")
throw new Error("Notification permission was not granted");
const value = options as { title?: string; body?: string };
return new Notification(value?.title ?? "Notification", { body: value?.body });
},
},
},
"device.info": {
browser: {
supported: () => typeof navigator !== "undefined",
run: () => ({
platform: "web",
userAgent: navigator.userAgent,
language: navigator.language,
}),
},
},
haptics: {
browser: {
supported: () => typeof navigator !== "undefined" && typeof navigator.vibrate === "function",
run: (options) => navigator.vibrate((options as { duration?: number })?.duration ?? 20),
},
},
"filesystem.read": {
browser: {
supported: () => typeof window !== "undefined" && "showOpenFilePicker" in window,
run: async () => {
const picker = (
window as unknown as Window & {
showOpenFilePicker(): Promise<Array<{ getFile(): Promise<File> }>>;
}
).showOpenFilePicker;
const [handle] = await picker.call(window);
return handle?.getFile();
},
},
},
"filesystem.write": {
browser: {
supported: () => typeof window !== "undefined" && "showSaveFilePicker" in window,
run: async (options) => {
const picker = (
window as unknown as Window & {
showSaveFilePicker(): Promise<{
createWritable(): Promise<{
write(value: unknown): Promise<void>;
close(): Promise<void>;
}>;
}>;
}
).showSaveFilePicker;
const writable = await (await picker.call(window)).createWritable();
await writable.write((options as { data?: unknown })?.data ?? "");
await writable.close();
},
},
},
};