@carddb/browser 0.1.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.
@@ -0,0 +1,76 @@
1
+ import { Cache } from '@carddb/core';
2
+ export * from '@carddb/client';
3
+
4
+ /**
5
+ * Browser-based cache implementations using localStorage/sessionStorage
6
+ */
7
+
8
+ type StorageType = 'localStorage' | 'sessionStorage';
9
+ /**
10
+ * Browser cache using localStorage or sessionStorage.
11
+ *
12
+ * Uses localStorage by default for persistent caching across sessions.
13
+ * Use sessionStorage for per-session caching that clears when the tab is closed.
14
+ *
15
+ * @example localStorage (default, persistent)
16
+ * import { CardDBClient, BrowserCache } from '@carddb/browser'
17
+ *
18
+ * const client = new CardDBClient({
19
+ * cache: new BrowserCache(),
20
+ * cacheTtl: 300 // 5 minutes
21
+ * })
22
+ *
23
+ * @example sessionStorage (per-session)
24
+ * import { CardDBClient, BrowserCache } from '@carddb/browser'
25
+ *
26
+ * const client = new CardDBClient({
27
+ * cache: new BrowserCache({ storage: 'sessionStorage' }),
28
+ * cacheTtl: 300
29
+ * })
30
+ *
31
+ * @example Custom prefix
32
+ * const cache = new BrowserCache({ prefix: 'myapp:carddb:' })
33
+ */
34
+ declare class BrowserCache implements Cache {
35
+ private storage;
36
+ private prefix;
37
+ constructor(options?: {
38
+ storage?: StorageType;
39
+ prefix?: string;
40
+ });
41
+ /**
42
+ * Get a value from the cache
43
+ */
44
+ get<T>(key: string): T | null;
45
+ /**
46
+ * Set a value in the cache
47
+ *
48
+ * @param key - The cache key
49
+ * @param value - The value to cache (must be JSON-serializable)
50
+ * @param ttl - Time to live in seconds (optional, undefined = no expiry)
51
+ */
52
+ set<T>(key: string, value: T, ttl?: number): void;
53
+ /**
54
+ * Delete a value from the cache
55
+ */
56
+ delete(key: string): void;
57
+ /**
58
+ * Clear all CardDB cached values (only keys with our prefix)
59
+ */
60
+ clear(): void;
61
+ /**
62
+ * Check if a key exists and is not expired
63
+ */
64
+ has(key: string): boolean;
65
+ /**
66
+ * Get approximate number of cached entries (only counts our prefixed keys)
67
+ */
68
+ get size(): number;
69
+ /**
70
+ * Clean up expired entries
71
+ * Call this periodically if you want to reclaim storage space from expired entries
72
+ */
73
+ cleanup(): void;
74
+ }
75
+
76
+ export { BrowserCache };
package/dist/index.js ADDED
@@ -0,0 +1,119 @@
1
+ export * from '@carddb/client';
2
+
3
+ // src/cache.ts
4
+ var BrowserCache = class {
5
+ storage;
6
+ prefix;
7
+ constructor(options = {}) {
8
+ const storageType = options.storage ?? "localStorage";
9
+ this.storage = storageType === "sessionStorage" ? globalThis.sessionStorage : globalThis.localStorage;
10
+ this.prefix = options.prefix ?? "carddb:";
11
+ }
12
+ /**
13
+ * Get a value from the cache
14
+ */
15
+ get(key) {
16
+ try {
17
+ const raw = this.storage.getItem(this.prefix + key);
18
+ if (!raw) return null;
19
+ const entry = JSON.parse(raw);
20
+ if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {
21
+ this.storage.removeItem(this.prefix + key);
22
+ return null;
23
+ }
24
+ return entry.value;
25
+ } catch {
26
+ this.storage.removeItem(this.prefix + key);
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Set a value in the cache
32
+ *
33
+ * @param key - The cache key
34
+ * @param value - The value to cache (must be JSON-serializable)
35
+ * @param ttl - Time to live in seconds (optional, undefined = no expiry)
36
+ */
37
+ set(key, value, ttl) {
38
+ try {
39
+ const entry = {
40
+ value,
41
+ expiresAt: ttl !== void 0 ? Date.now() + ttl * 1e3 : null
42
+ };
43
+ this.storage.setItem(this.prefix + key, JSON.stringify(entry));
44
+ } catch (e) {
45
+ console.warn("[CardDB] Failed to write to cache:", e);
46
+ }
47
+ }
48
+ /**
49
+ * Delete a value from the cache
50
+ */
51
+ delete(key) {
52
+ this.storage.removeItem(this.prefix + key);
53
+ }
54
+ /**
55
+ * Clear all CardDB cached values (only keys with our prefix)
56
+ */
57
+ clear() {
58
+ const keysToRemove = [];
59
+ for (let i = 0; i < this.storage.length; i++) {
60
+ const key = this.storage.key(i);
61
+ if (key && key.startsWith(this.prefix)) {
62
+ keysToRemove.push(key);
63
+ }
64
+ }
65
+ for (const key of keysToRemove) {
66
+ this.storage.removeItem(key);
67
+ }
68
+ }
69
+ /**
70
+ * Check if a key exists and is not expired
71
+ */
72
+ has(key) {
73
+ return this.get(key) !== null;
74
+ }
75
+ /**
76
+ * Get approximate number of cached entries (only counts our prefixed keys)
77
+ */
78
+ get size() {
79
+ let count = 0;
80
+ for (let i = 0; i < this.storage.length; i++) {
81
+ const key = this.storage.key(i);
82
+ if (key && key.startsWith(this.prefix)) {
83
+ count++;
84
+ }
85
+ }
86
+ return count;
87
+ }
88
+ /**
89
+ * Clean up expired entries
90
+ * Call this periodically if you want to reclaim storage space from expired entries
91
+ */
92
+ cleanup() {
93
+ const now = Date.now();
94
+ const keysToRemove = [];
95
+ for (let i = 0; i < this.storage.length; i++) {
96
+ const fullKey = this.storage.key(i);
97
+ if (fullKey && fullKey.startsWith(this.prefix)) {
98
+ try {
99
+ const raw = this.storage.getItem(fullKey);
100
+ if (raw) {
101
+ const entry = JSON.parse(raw);
102
+ if (entry.expiresAt !== null && now > entry.expiresAt) {
103
+ keysToRemove.push(fullKey);
104
+ }
105
+ }
106
+ } catch {
107
+ keysToRemove.push(fullKey);
108
+ }
109
+ }
110
+ }
111
+ for (const key of keysToRemove) {
112
+ this.storage.removeItem(key);
113
+ }
114
+ }
115
+ };
116
+
117
+ export { BrowserCache };
118
+ //# sourceMappingURL=index.js.map
119
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cache.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Browser-based cache implementations using localStorage/sessionStorage\n */\n\nimport type { Cache } from '@carddb/core'\n\ninterface CacheEntry<T> {\n value: T\n expiresAt: number | null\n}\n\ntype StorageType = 'localStorage' | 'sessionStorage'\n\n/**\n * Browser cache using localStorage or sessionStorage.\n *\n * Uses localStorage by default for persistent caching across sessions.\n * Use sessionStorage for per-session caching that clears when the tab is closed.\n *\n * @example localStorage (default, persistent)\n * import { CardDBClient, BrowserCache } from '@carddb/browser'\n *\n * const client = new CardDBClient({\n * cache: new BrowserCache(),\n * cacheTtl: 300 // 5 minutes\n * })\n *\n * @example sessionStorage (per-session)\n * import { CardDBClient, BrowserCache } from '@carddb/browser'\n *\n * const client = new CardDBClient({\n * cache: new BrowserCache({ storage: 'sessionStorage' }),\n * cacheTtl: 300\n * })\n *\n * @example Custom prefix\n * const cache = new BrowserCache({ prefix: 'myapp:carddb:' })\n */\nexport class BrowserCache implements Cache {\n private storage: Storage\n private prefix: string\n\n constructor(options: { storage?: StorageType; prefix?: string } = {}) {\n const storageType = options.storage ?? 'localStorage'\n this.storage =\n storageType === 'sessionStorage' ? globalThis.sessionStorage : globalThis.localStorage\n this.prefix = options.prefix ?? 'carddb:'\n }\n\n /**\n * Get a value from the cache\n */\n get<T>(key: string): T | null {\n try {\n const raw = this.storage.getItem(this.prefix + key)\n if (!raw) return null\n\n const entry = JSON.parse(raw) as CacheEntry<T>\n\n // Check if expired\n if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {\n this.storage.removeItem(this.prefix + key)\n return null\n }\n\n return entry.value\n } catch {\n // If parsing fails, remove the invalid entry\n this.storage.removeItem(this.prefix + key)\n return null\n }\n }\n\n /**\n * Set a value in the cache\n *\n * @param key - The cache key\n * @param value - The value to cache (must be JSON-serializable)\n * @param ttl - Time to live in seconds (optional, undefined = no expiry)\n */\n set<T>(key: string, value: T, ttl?: number): void {\n try {\n const entry: CacheEntry<T> = {\n value,\n expiresAt: ttl !== undefined ? Date.now() + ttl * 1000 : null,\n }\n this.storage.setItem(this.prefix + key, JSON.stringify(entry))\n } catch (e) {\n // Storage might be full or disabled - silently fail\n // In the future, we could implement LRU eviction here\n console.warn('[CardDB] Failed to write to cache:', e)\n }\n }\n\n /**\n * Delete a value from the cache\n */\n delete(key: string): void {\n this.storage.removeItem(this.prefix + key)\n }\n\n /**\n * Clear all CardDB cached values (only keys with our prefix)\n */\n clear(): void {\n const keysToRemove: string[] = []\n for (let i = 0; i < this.storage.length; i++) {\n const key = this.storage.key(i)\n if (key && key.startsWith(this.prefix)) {\n keysToRemove.push(key)\n }\n }\n for (const key of keysToRemove) {\n this.storage.removeItem(key)\n }\n }\n\n /**\n * Check if a key exists and is not expired\n */\n has(key: string): boolean {\n return this.get(key) !== null\n }\n\n /**\n * Get approximate number of cached entries (only counts our prefixed keys)\n */\n get size(): number {\n let count = 0\n for (let i = 0; i < this.storage.length; i++) {\n const key = this.storage.key(i)\n if (key && key.startsWith(this.prefix)) {\n count++\n }\n }\n return count\n }\n\n /**\n * Clean up expired entries\n * Call this periodically if you want to reclaim storage space from expired entries\n */\n cleanup(): void {\n const now = Date.now()\n const keysToRemove: string[] = []\n\n for (let i = 0; i < this.storage.length; i++) {\n const fullKey = this.storage.key(i)\n if (fullKey && fullKey.startsWith(this.prefix)) {\n try {\n const raw = this.storage.getItem(fullKey)\n if (raw) {\n const entry = JSON.parse(raw) as CacheEntry<unknown>\n if (entry.expiresAt !== null && now > entry.expiresAt) {\n keysToRemove.push(fullKey)\n }\n }\n } catch {\n // Invalid entry, remove it\n keysToRemove.push(fullKey)\n }\n }\n }\n\n for (const key of keysToRemove) {\n this.storage.removeItem(key)\n }\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@carddb/browser",
3
+ "version": "0.1.0",
4
+ "description": "CardDB client for browsers",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": ["dist"],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "clean": "rm -rf dist",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "bun test",
27
+ "lint": "tsc --noEmit"
28
+ },
29
+ "keywords": ["carddb", "api", "client", "graphql", "card-games", "browser", "web"],
30
+ "author": "CardDB Team",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/xtda/carddb-js.git",
35
+ "directory": "packages/browser"
36
+ },
37
+ "homepage": "https://github.com/xtda/carddb-js#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/xtda/carddb-js/issues"
40
+ },
41
+ "dependencies": {
42
+ "@carddb/client": "0.1.0",
43
+ "@carddb/core": "0.1.0"
44
+ },
45
+ "sideEffects": false
46
+ }