{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { StateModel, StateStore } from \"@json-render/core\";\nimport { createStoreAdapter } from \"@json-render/core/store-utils\";\nimport type { StoreApi } from \"zustand\";\n\nexport type { StateStore } from \"@json-render/core\";\n\n/**\n * Options for {@link zustandStateStore}.\n */\nexport interface ZustandStateStoreOptions<S extends StateModel = StateModel> {\n  /** A Zustand vanilla store (created with `createStore` from `zustand/vanilla`). */\n  store: StoreApi<S>;\n  /**\n   * Select the json-render state slice from the Zustand store state.\n   * Defaults to `(state) => state` (the entire store is the state model).\n   */\n  selector?: (state: S) => StateModel;\n  /**\n   * Apply a state change back to the Zustand store.\n   * Defaults to a shallow merge (`store.setState(next)`) so that keys\n   * outside the json-render model are preserved. Override this if you use\n   * a selector and only want to update a nested slice, or pass\n   * `(next, s) => s.setState(next as S, true)` for full replacement.\n   */\n  updater?: (nextState: StateModel, store: StoreApi<S>) => void;\n}\n\n/**\n * Create a {@link StateStore} backed by a Zustand store.\n *\n * @example\n * ```ts\n * import { createStore } from \"zustand/vanilla\";\n * import { zustandStateStore } from \"@json-render/zustand\";\n *\n * const bearStore = createStore(() => ({ count: 0, name: \"Bear\" }));\n *\n * const store = zustandStateStore({ store: bearStore });\n *\n * <StateProvider store={store}>...</StateProvider>\n * ```\n *\n * @example Using a selector for a nested slice:\n * ```ts\n * const appStore = createStore(() => ({\n *   ui: { count: 0 },\n *   auth: { token: null },\n * }));\n *\n * const store = zustandStateStore({\n *   store: appStore,\n *   selector: (s) => s.ui,\n *   updater: (next, s) => s.setState({ ui: next }),\n * });\n * ```\n */\nexport function zustandStateStore<S extends StateModel = StateModel>(\n  options: ZustandStateStoreOptions<S>,\n): StateStore {\n  const {\n    store,\n    selector = (s: S) => s as StateModel,\n    updater = (next, s) => s.setState(next as Partial<S>),\n  } = options;\n\n  return createStoreAdapter({\n    getSnapshot: () => selector(store.getState()),\n    setSnapshot: (next) => updater(next, store),\n    subscribe(listener) {\n      let prev = selector(store.getState());\n      return store.subscribe(() => {\n        const current = selector(store.getState());\n        if (current !== prev) {\n          prev = current;\n          listener();\n          // Re-read after listener in case it triggered a synchronous dispatch;\n          // absorb that change so it doesn't fire a duplicate notification.\n          prev = selector(store.getState());\n        }\n      });\n    },\n  });\n}\n"],"mappings":";AACA,SAAS,0BAA0B;AAuD5B,SAAS,kBACd,SACY;AACZ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,MAAS;AAAA,IACrB,UAAU,CAAC,MAAM,MAAM,EAAE,SAAS,IAAkB;AAAA,EACtD,IAAI;AAEJ,SAAO,mBAAmB;AAAA,IACxB,aAAa,MAAM,SAAS,MAAM,SAAS,CAAC;AAAA,IAC5C,aAAa,CAAC,SAAS,QAAQ,MAAM,KAAK;AAAA,IAC1C,UAAU,UAAU;AAClB,UAAI,OAAO,SAAS,MAAM,SAAS,CAAC;AACpC,aAAO,MAAM,UAAU,MAAM;AAC3B,cAAM,UAAU,SAAS,MAAM,SAAS,CAAC;AACzC,YAAI,YAAY,MAAM;AACpB,iBAAO;AACP,mBAAS;AAGT,iBAAO,SAAS,MAAM,SAAS,CAAC;AAAA,QAClC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;","names":[]}