diff --git a/.changeset/green-masks-admire.md b/.changeset/green-masks-admire.md new file mode 100644 index 0000000000..3254a82d79 --- /dev/null +++ b/.changeset/green-masks-admire.md @@ -0,0 +1,7 @@ +--- +"@zag-js/preact": patch +"@zag-js/react": patch +"@zag-js/store": patch +--- + +Fix issue where multiple versions of @zag-js/store could lead to "proxy state is not iterable" errors. diff --git a/packages/frameworks/preact/src/use-snapshot.ts b/packages/frameworks/preact/src/use-snapshot.ts index f6e5324805..1f2796f41f 100644 --- a/packages/frameworks/preact/src/use-snapshot.ts +++ b/packages/frameworks/preact/src/use-snapshot.ts @@ -1,12 +1,12 @@ import type { Machine, StateMachine as S } from "@zag-js/core" -import { snapshot, subscribe, type Snapshot } from "@zag-js/store" +import { makeGlobal, snapshot, subscribe, type Snapshot } from "@zag-js/store" import { compact, isEqual } from "@zag-js/utils" import { useSyncExternalStore } from "preact/compat" import { useCallback, useEffect, useMemo, useRef } from "preact/hooks" import { createProxy as createProxyToCompare, isChanged } from "proxy-compare" import { useUpdateEffect } from "./use-update-effect" -const targetCache = new WeakMap() +const targetCache = makeGlobal("__zag__targetCache", () => new WeakMap()) export function useSnapshot< TContext extends Record, diff --git a/packages/frameworks/react/src/use-snapshot.ts b/packages/frameworks/react/src/use-snapshot.ts index ea467647a2..3aa7ed6bac 100644 --- a/packages/frameworks/react/src/use-snapshot.ts +++ b/packages/frameworks/react/src/use-snapshot.ts @@ -1,7 +1,7 @@ /// import type { Machine, StateMachine as S } from "@zag-js/core" -import { snapshot, subscribe, type Snapshot } from "@zag-js/store" +import { snapshot, subscribe, type Snapshot, makeGlobal } from "@zag-js/store" import { compact, isEqual } from "@zag-js/utils" import { createProxy as createProxyToCompare, isChanged } from "proxy-compare" import ReactExport, { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from "react" @@ -11,7 +11,7 @@ import { useUpdateEffect } from "./use-update-effect" //@ts-ignore const { use } = ReactExport -const targetCache = new WeakMap() +const targetCache = makeGlobal("__zag__targetCache", () => new WeakMap()) export function useSnapshot< TContext extends Record, diff --git a/packages/store/src/global.ts b/packages/store/src/global.ts new file mode 100644 index 0000000000..a91762e521 --- /dev/null +++ b/packages/store/src/global.ts @@ -0,0 +1,13 @@ +function getGlobal(): any { + if (typeof globalThis !== "undefined") return globalThis + if (typeof self !== "undefined") return self + if (typeof window !== "undefined") return window + if (typeof global !== "undefined") return global +} + +export function makeGlobal(key: string, value: () => T): T { + const g = getGlobal() + if (!g) return value() + g[key] ||= value() + return g[key] +} diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index 91e079bff4..d6534065c4 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,2 +1,3 @@ -export { proxy, ref, snapshot, subscribe, type Snapshot, type Ref } from "./proxy" +export { makeGlobal } from "./global" +export { proxy, ref, snapshot, subscribe, type Ref, type Snapshot } from "./proxy" export { proxyWithComputed } from "./proxy-computed" diff --git a/packages/store/src/proxy.ts b/packages/store/src/proxy.ts index 25c7e0db8e..144ff45b8b 100644 --- a/packages/store/src/proxy.ts +++ b/packages/store/src/proxy.ts @@ -1,6 +1,7 @@ // Credits: https://github.com/pmndrs/valtio import { getUntracked, markToTrack } from "proxy-compare" +import { makeGlobal } from "./global" const isDev = process.env.NODE_ENV !== "production" const isObject = (x: unknown): x is object => typeof x === "object" && x !== null @@ -46,8 +47,8 @@ type ProxyState = readonly [ ] // shared state -const proxyStateMap = new WeakMap() -const refSet = new WeakSet() +const proxyStateMap = makeGlobal("__zag__proxyStateMap", () => new WeakMap()) +const refSet = makeGlobal("__zag__refSet", () => new WeakSet()) const buildProxyFunction = ( objectIs = Object.is,