refcount.ts 772 B

1234567891011121314151617181920212223242526272829303132
  1. import { onCleanup } from "solid-js"
  2. export function createRefCountMap<T>(
  3. create: (key: string) => T,
  4. remove?: (key: string) => void,
  5. identity: (key: string) => string = (key) => key,
  6. ) {
  7. const items = new Map<string, T>()
  8. const refCounts = new Map<string, number>()
  9. return (key: string) => {
  10. const id = identity(key)
  11. onCleanup(() => {
  12. refCounts.set(id, (refCounts.get(id) ?? 0) - 1)
  13. if (refCounts.get(id) === 0) {
  14. remove?.(id)
  15. items.delete(id)
  16. refCounts.delete(id)
  17. }
  18. })
  19. const cached = items.get(id)
  20. if (cached) {
  21. refCounts.set(id, (refCounts.get(id) ?? 0) + 1)
  22. return cached
  23. }
  24. const item = create(key)
  25. items.set(id, item)
  26. refCounts.set(id, 1)
  27. return item
  28. }
  29. }