diff --git a/packages/pinia-orm/src/cache/WeakCache.ts b/packages/pinia-orm/src/cache/WeakCache.ts index fa2adfb4b..bd735b179 100644 --- a/packages/pinia-orm/src/cache/WeakCache.ts +++ b/packages/pinia-orm/src/cache/WeakCache.ts @@ -1,8 +1,28 @@ +interface ValueRef { + deref(): V | undefined +} + +/** + * Fallback for environments without WeakRef support (e.g. Cloudflare + * Workers). Values are held strongly instead of crashing. + */ +class StrongRef implements ValueRef { + #value: V + + constructor (value: V) { + this.#value = value + } + + deref (): V { + return this.#value + } +} + export class WeakCache implements Map { // @ts-expect-error dont know readonly [Symbol.toStringTag]: string - #map = new Map>() + #map = new Map>() has (key: K) { return !!(this.#map.has(key) && this.#map.get(key)?.deref()) @@ -25,7 +45,7 @@ export class WeakCache implements Map { } set (key: K, value: V) { - this.#map.set(key, new WeakRef(value)) + this.#map.set(key, typeof WeakRef === 'undefined' ? new StrongRef(value) : new WeakRef(value)) return this } diff --git a/packages/pinia-orm/tests/unit/cache/Weakcache.spec.ts b/packages/pinia-orm/tests/unit/cache/Weakcache.spec.ts index c37c4d5cb..2f3aa2da5 100644 --- a/packages/pinia-orm/tests/unit/cache/Weakcache.spec.ts +++ b/packages/pinia-orm/tests/unit/cache/Weakcache.spec.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import { WeakCache } from '../../../src/cache/WeakCache' @@ -72,4 +72,17 @@ describe('unit/support/Weakcache', () => { cache.clear() expect(cache.size).toEqual(0) }) + + it('falls back to strong references when WeakRef is not available', () => { + vi.stubGlobal('WeakRef', undefined) + + const fallbackCache = new WeakCache() + fallbackCache.set('key1', data) + + expect(fallbackCache.get('key1')).toEqual(data) + expect(fallbackCache.has('key1')).toBeTruthy() + expect([...fallbackCache.values()]).toEqual([data]) + + vi.unstubAllGlobals() + }) })