mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 06:04:51 +00:00
Rename ChromeStorageBackend to WebExtensionStorageBackend for cross-browser support
- Rename chrome-storage-backend.ts to web-extension-storage-backend.ts - Update to use globalThis.browser || globalThis.chrome for Firefox/Chrome compatibility - Export both names for backward compatibility - Fix tsc --preserveWatchOutput in web-ui dev script to prevent console clearing This fixes the "browser is not defined" error in Chrome extensions.
This commit is contained in:
parent
bcd109f2e9
commit
f7878c3c71
6 changed files with 95 additions and 91 deletions
|
|
@ -1,82 +0,0 @@
|
|||
import type { StorageBackend } from "../types.js";
|
||||
|
||||
// Chrome extension API types (optional)
|
||||
declare const chrome: any;
|
||||
|
||||
/**
|
||||
* Storage backend using chrome.storage.local.
|
||||
* Good for: Browser extensions, syncing across devices (with chrome.storage.sync).
|
||||
* Limits: ~10MB for local, ~100KB for sync, async API.
|
||||
*/
|
||||
export class ChromeStorageBackend implements StorageBackend {
|
||||
constructor(private prefix: string = "") {}
|
||||
|
||||
private getKey(key: string): string {
|
||||
return this.prefix ? `${this.prefix}:${key}` : key;
|
||||
}
|
||||
|
||||
async get<T = unknown>(key: string): Promise<T | null> {
|
||||
if (!chrome?.storage?.local) {
|
||||
throw new Error("chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
const result = await chrome.storage.local.get([fullKey]);
|
||||
return result[fullKey] !== undefined ? (result[fullKey] as T) : null;
|
||||
}
|
||||
|
||||
async set<T = unknown>(key: string, value: T): Promise<void> {
|
||||
if (!chrome?.storage?.local) {
|
||||
throw new Error("chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
await chrome.storage.local.set({ [fullKey]: value });
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
if (!chrome?.storage?.local) {
|
||||
throw new Error("chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
await chrome.storage.local.remove(fullKey);
|
||||
}
|
||||
|
||||
async keys(): Promise<string[]> {
|
||||
if (!chrome?.storage?.local) {
|
||||
throw new Error("chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const allData = await chrome.storage.local.get(null);
|
||||
const allKeys = Object.keys(allData);
|
||||
const prefixWithColon = this.prefix ? `${this.prefix}:` : "";
|
||||
|
||||
if (this.prefix) {
|
||||
return allKeys
|
||||
.filter((key) => key.startsWith(prefixWithColon))
|
||||
.map((key) => key.substring(prefixWithColon.length));
|
||||
}
|
||||
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
if (!chrome?.storage?.local) {
|
||||
throw new Error("chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
if (this.prefix) {
|
||||
const keysToRemove = await this.keys();
|
||||
const fullKeys = keysToRemove.map((key) => this.getKey(key));
|
||||
await chrome.storage.local.remove(fullKeys);
|
||||
} else {
|
||||
await chrome.storage.local.clear();
|
||||
}
|
||||
}
|
||||
|
||||
async has(key: string): Promise<boolean> {
|
||||
const value = await this.get(key);
|
||||
return value !== null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import type { StorageBackend } from "../types.js";
|
||||
|
||||
// Cross-browser extension API compatibility
|
||||
// @ts-expect-error - browser global exists in Firefox, chrome in Chrome
|
||||
const browserAPI = globalThis.browser || globalThis.chrome;
|
||||
|
||||
/**
|
||||
* Storage backend using browser.storage.local (Firefox) or chrome.storage.local (Chrome).
|
||||
* Good for: Browser extensions, syncing across devices (with storage.sync).
|
||||
* Limits: ~10MB for local, ~100KB for sync, async API.
|
||||
*/
|
||||
export class WebExtensionStorageBackend implements StorageBackend {
|
||||
constructor(private prefix: string = "") {}
|
||||
|
||||
private getKey(key: string): string {
|
||||
return this.prefix ? `${this.prefix}:${key}` : key;
|
||||
}
|
||||
|
||||
async get<T = unknown>(key: string): Promise<T | null> {
|
||||
if (!browserAPI?.storage?.local) {
|
||||
throw new Error("browser/chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
const result = await browserAPI.storage.local.get([fullKey]);
|
||||
return result[fullKey] !== undefined ? (result[fullKey] as T) : null;
|
||||
}
|
||||
|
||||
async set<T = unknown>(key: string, value: T): Promise<void> {
|
||||
if (!browserAPI?.storage?.local) {
|
||||
throw new Error("browser/chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
await browserAPI.storage.local.set({ [fullKey]: value });
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
if (!browserAPI?.storage?.local) {
|
||||
throw new Error("browser/chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const fullKey = this.getKey(key);
|
||||
await browserAPI.storage.local.remove(fullKey);
|
||||
}
|
||||
|
||||
async keys(): Promise<string[]> {
|
||||
if (!browserAPI?.storage?.local) {
|
||||
throw new Error("browser/chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
const allData = await browserAPI.storage.local.get(null);
|
||||
const allKeys = Object.keys(allData);
|
||||
const prefixWithColon = this.prefix ? `${this.prefix}:` : "";
|
||||
|
||||
if (this.prefix) {
|
||||
return allKeys
|
||||
.filter((key) => key.startsWith(prefixWithColon))
|
||||
.map((key) => key.substring(prefixWithColon.length));
|
||||
}
|
||||
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
if (!browserAPI?.storage?.local) {
|
||||
throw new Error("browser/chrome.storage.local is not available");
|
||||
}
|
||||
|
||||
if (this.prefix) {
|
||||
const keysToRemove = await this.keys();
|
||||
const fullKeys = keysToRemove.map((key) => this.getKey(key));
|
||||
await browserAPI.storage.local.remove(fullKeys);
|
||||
} else {
|
||||
await browserAPI.storage.local.clear();
|
||||
}
|
||||
}
|
||||
|
||||
async has(key: string): Promise<boolean> {
|
||||
const value = await this.get(key);
|
||||
return value !== null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue