heliumts 0.5.9 → 0.5.10
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/client/cache.ts"],"names":[],"mappings":"AAqCA,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhE;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/client/cache.ts"],"names":[],"mappings":"AAqCA,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhE;AAsBD,wBAAgB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAYjD;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,QAM5D;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAYxC;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,QAqBlD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,cAK1E;AAED,wBAAgB,aAAa,SAkB5B;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAEtE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAW/E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEnD"}
|
package/dist/client/cache.js
CHANGED
|
@@ -26,6 +26,19 @@ const DEFAULT_TTL = 5 * 60 * 1000; // 5 minutes
|
|
|
26
26
|
export function cacheKey(methodId, args) {
|
|
27
27
|
return JSON.stringify([methodId, args ?? null]);
|
|
28
28
|
}
|
|
29
|
+
function methodIdFromKey(key) {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(key);
|
|
32
|
+
if (!Array.isArray(parsed) || parsed.length < 1) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const [methodId] = parsed;
|
|
36
|
+
return typeof methodId === "string" ? methodId : undefined;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
29
42
|
function isExpired(entry) {
|
|
30
43
|
if (!entry.ttl) {
|
|
31
44
|
return false;
|
|
@@ -64,11 +77,17 @@ export function has(key) {
|
|
|
64
77
|
export function invalidateByMethod(methodId) {
|
|
65
78
|
let invalidated = false;
|
|
66
79
|
for (const key of store.keys()) {
|
|
67
|
-
if (key
|
|
80
|
+
if (methodIdFromKey(key) === methodId) {
|
|
68
81
|
store.delete(key);
|
|
69
82
|
invalidated = true;
|
|
70
83
|
}
|
|
71
84
|
}
|
|
85
|
+
for (const key of pendingFetches.keys()) {
|
|
86
|
+
if (methodIdFromKey(key) === methodId) {
|
|
87
|
+
pendingFetches.delete(key);
|
|
88
|
+
invalidated = true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
72
91
|
if (invalidated || listeners.size) {
|
|
73
92
|
for (const listener of listeners) {
|
|
74
93
|
listener(methodId);
|
package/dist/client/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/client/cache.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/client/cache.ts"],"names":[],"mappings":"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","sourcesContent":["interface CacheEntry {\n value: unknown;\n timestamp: number;\n ttl?: number; // TTL in milliseconds\n}\n\n// Preserve cache across HMR by attaching to window in dev mode\nlet store: Map<string, CacheEntry>;\nlet listeners: Set<(methodId: string) => void>;\nlet pendingFetches: Map<string, Promise<unknown>>;\n\nif (typeof window !== \"undefined\" && import.meta.env?.DEV) {\n const globalWindow = window as typeof window & {\n __heliumCacheStore?: Map<string, CacheEntry>;\n __heliumCacheListeners?: Set<(methodId: string) => void>;\n __heliumPendingFetches?: Map<string, Promise<unknown>>;\n };\n if (!globalWindow.__heliumCacheStore) {\n globalWindow.__heliumCacheStore = new Map();\n }\n if (!globalWindow.__heliumCacheListeners) {\n globalWindow.__heliumCacheListeners = new Set();\n }\n if (!globalWindow.__heliumPendingFetches) {\n globalWindow.__heliumPendingFetches = new Map();\n }\n store = globalWindow.__heliumCacheStore;\n listeners = globalWindow.__heliumCacheListeners;\n pendingFetches = globalWindow.__heliumPendingFetches;\n} else {\n store = new Map();\n listeners = new Set();\n pendingFetches = new Map();\n}\n\nconst DEFAULT_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport function cacheKey(methodId: string, args: unknown): string {\n return JSON.stringify([methodId, args ?? null]);\n}\n\nfunction methodIdFromKey(key: string): string | undefined {\n try {\n const parsed = JSON.parse(key);\n if (!Array.isArray(parsed) || parsed.length < 1) {\n return undefined;\n }\n const [methodId] = parsed;\n return typeof methodId === \"string\" ? methodId : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isExpired(entry: CacheEntry): boolean {\n if (!entry.ttl) {\n return false;\n }\n return Date.now() - entry.timestamp > entry.ttl;\n}\n\nexport function get<T>(key: string): T | undefined {\n const entry = store.get(key);\n if (!entry) {\n return undefined;\n }\n\n if (isExpired(entry)) {\n store.delete(key);\n return undefined;\n }\n\n return entry.value as T | undefined;\n}\n\nexport function set(key: string, value: unknown, ttl?: number) {\n store.set(key, {\n value,\n timestamp: Date.now(),\n ttl: ttl ?? DEFAULT_TTL,\n });\n}\n\nexport function has(key: string): boolean {\n const entry = store.get(key);\n if (!entry) {\n return false;\n }\n\n if (isExpired(entry)) {\n store.delete(key);\n return false;\n }\n\n return true;\n}\n\nexport function invalidateByMethod(methodId: string) {\n let invalidated = false;\n for (const key of store.keys()) {\n if (methodIdFromKey(key) === methodId) {\n store.delete(key);\n invalidated = true;\n }\n }\n\n for (const key of pendingFetches.keys()) {\n if (methodIdFromKey(key) === methodId) {\n pendingFetches.delete(key);\n invalidated = true;\n }\n }\n\n if (invalidated || listeners.size) {\n for (const listener of listeners) {\n listener(methodId);\n }\n }\n}\n\nexport function subscribeInvalidations(listener: (methodId: string) => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function invalidateAll() {\n const methodIds = new Set<string>();\n for (const key of store.keys()) {\n try {\n const parsed = JSON.parse(key);\n if (Array.isArray(parsed) && parsed.length > 0) {\n methodIds.add(parsed[0]);\n }\n } catch {\n // Ignore malformed keys\n }\n }\n store.clear();\n for (const methodId of methodIds) {\n for (const listener of listeners) {\n listener(methodId);\n }\n }\n}\n\n/**\n * Check if a fetch is currently pending for a given cache key.\n */\nexport function isPending(key: string): boolean {\n return pendingFetches.has(key);\n}\n\n/**\n * Get an existing pending fetch promise, or undefined if none.\n */\nexport function getPendingFetch<T>(key: string): Promise<T> | undefined {\n return pendingFetches.get(key) as Promise<T> | undefined;\n}\n\n/**\n * Register a pending fetch. Returns the promise.\n * If a fetch for this key is already pending, returns the existing promise.\n */\nexport function setPendingFetch<T>(key: string, promise: Promise<T>): Promise<T> {\n const existing = pendingFetches.get(key);\n if (existing) {\n return existing as Promise<T>;\n }\n pendingFetches.set(key, promise);\n // Clean up when done\n promise.finally(() => {\n pendingFetches.delete(key);\n });\n return promise;\n}\n\n/**\n * Clear a pending fetch (if you need to cancel/reset).\n */\nexport function clearPendingFetch(key: string): void {\n pendingFetches.delete(key);\n}\n"]}
|