{"version":3,"file":"index.cjs","sources":[""],"sourcesContent":["import { getStorage } from \"../getStorage/index.ts\";\n\nexport type TStorageController<TSchema extends Record<string, unknown>> = {\n  clear: () => boolean;\n  get: <TKey extends Extract<keyof TSchema, string>>(\n    key: TKey,\n    fallback?: TSchema[TKey]\n  ) => TSchema[TKey] | undefined;\n  has: (key: Extract<keyof TSchema, string>) => boolean;\n  remove: (key: Extract<keyof TSchema, string>) => boolean;\n  set: <TKey extends Extract<keyof TSchema, string>>(key: TKey, value: TSchema[TKey]) => boolean;\n};\n\nexport type TCreateStorageArgs = Parameters<typeof createStorage>;\n\nexport type TCreateStorageReturn = ReturnType<typeof createStorage>;\n\n/**\n * Creates a typed, JSON-backed and SSR-safe storage namespace.\n * Operations return fallbacks or `false` when storage is unavailable.\n * @template TSchema\n * @param {{ namespace?: string; storage?: Storage|null; onError?: (error: unknown) => void; }} [options={}] Options; namespace defaults to \"flowerkit\"\n * @returns {TStorageController<TSchema>} Storage controller\n * @throws {TypeError} createStorage: options are invalid\n * @example\n * const settings = createStorage<{ theme: \"light\"|\"dark\" }>({ namespace: \"app\" });\n * settings.set(\"theme\", \"dark\");\n * @example\n * // Persist a typed shopping cart and restore it with a fallback\n * const cartStorage = createStorage<{ items: Array<{ id: string; quantity: number; }> }>({\n *   namespace: \"shop\",\n * });\n * cartStorage.set(\"items\", cartItems);\n * const savedItems = cartStorage.get(\"items\", []);\n */\nexport const createStorage = <TSchema extends Record<string, unknown> = Record<string, unknown>>(\n  options: {\n    namespace?: string;\n    onError?: (error: unknown) => void;\n    storage?: Storage | null;\n  } = {}\n): TStorageController<TSchema> => {\n  if (!options || typeof options !== \"object\" || Array.isArray(options)) {\n    throw new TypeError(\"createStorage: options must be a plain object\");\n  }\n  const {\n    namespace = \"flowerkit\",\n    onError,\n    storage = getStorage(),\n  } = options;\n  if (typeof namespace !== \"string\" || namespace.trim().length === 0) {\n    throw new TypeError(\"createStorage: namespace must be a non-empty string\");\n  }\n  if (onError !== undefined && typeof onError !== \"function\") {\n    throw new TypeError(\"createStorage: onError must be a function if provided\");\n  }\n  const prefix = `${namespace}:`;\n  const getKey = (key: string): string => `${prefix}${key}`;\n  const fail = (error: unknown): false => {\n    onError?.(error);\n    return false;\n  };\n\n  return {\n    clear: (): boolean => {\n      if (!storage) {\n        return false;\n      }\n      try {\n        const keys = Array.from({ length: storage.length }, (_, index) => storage.key(index))\n          .filter((key): key is string => Boolean(key?.startsWith(prefix)));\n        keys.forEach((key) => storage.removeItem(key));\n        return true;\n      } catch (error) {\n        return fail(error);\n      }\n    },\n    get: (key, fallback) => {\n      if (!storage) {\n        return fallback;\n      }\n      try {\n        const value = storage.getItem(getKey(key));\n        return value === null ? fallback : JSON.parse(value);\n      } catch (error) {\n        fail(error);\n        return fallback;\n      }\n    },\n    has: (key): boolean => {\n      if (!storage) {\n        return false;\n      }\n      try {\n        return storage.getItem(getKey(key)) !== null;\n      } catch (error) {\n        return fail(error);\n      }\n    },\n    remove: (key): boolean => {\n      if (!storage) {\n        return false;\n      }\n      try {\n        storage.removeItem(getKey(key));\n        return true;\n      } catch (error) {\n        return fail(error);\n      }\n    },\n    set: (key, value): boolean => {\n      if (!storage) {\n        return false;\n      }\n      try {\n        const serialized = JSON.stringify(value);\n        if (serialized === undefined) {\n          throw new TypeError(\"createStorage: value must be JSON-serializable\");\n        }\n        storage.setItem(getKey(key), serialized);\n        return true;\n      } catch (error) {\n        return fail(error);\n      }\n    },\n  };\n};\n"],"names":["createStorage","options","Array","isArray","TypeError","namespace","onError","storage","getStorage","trim","length","undefined","prefix","getKey","key","fail","error","clear","keys","from","_","index","filter","Boolean","startsWith","forEach","removeItem","get","fallback","value","getItem","JSON","parse","has","remove","set","serialized","stringify","setItem"],"mappings":"sGAmCO,MAAMA,cAAgB,CAC3BC,QAII,MAEJ,IAAKA,gBAAkBA,UAAY,UAAYC,MAAMC,QAAQF,SAC3D,MAAM,IAAIG,UAAU,iDAEtB,MAAMC,UACJA,UAAY,YAAWC,QACvBA,QAAOC,QACPA,QAAUC,MAAAA,cACRP,QACJ,UAAWI,YAAc,UAAYA,UAAUI,OAAOC,SAAW,EAC/D,MAAM,IAAIN,UAAU,uDAEtB,GAAIE,eAAYK,UAAoBL,UAAY,WAC9C,MAAM,IAAIF,UAAU,yDAEtB,MAAMQ,OAAS,GAAGP,aAClB,MAAMQ,OAAUC,KAAwB,GAAGF,SAASE,MACpD,MAAMC,KAAQC,QACZV,UAAUU,OACV,OAAO,OAGT,MAAO,CACLC,MAAO,KACL,IAAKV,QACH,OAAO,MAET,IACE,MAAMW,KAAOhB,MAAMiB,KAAK,CAAET,OAAQH,QAAQG,QAAU,CAACU,EAAGC,QAAUd,QAAQO,IAAIO,QAC3EC,OAAQR,KAAuBS,QAAQT,KAAKU,WAAWZ,UAC1DM,KAAKO,QAASX,KAAQP,QAAQmB,WAAWZ,MACzC,OAAO,IACT,CAAE,MAAOE,OACP,OAAOD,KAAKC,MACd,GAEFW,IAAK,CAACb,IAAKc,YACT,IAAKrB,QACH,OAAOqB,SAET,IACE,MAAMC,MAAQtB,QAAQuB,QAAQjB,OAAOC,MACrC,OAAOe,QAAU,KAAOD,SAAWG,KAAKC,MAAMH,MAChD,CAAE,MAAOb,OACPD,KAAKC,OACL,OAAOY,QACT,GAEFK,IAAMnB,MACJ,IAAKP,QACH,OAAO,MAET,IACE,OAAOA,QAAQuB,QAAQjB,OAAOC,QAAU,IAC1C,CAAE,MAAOE,OACP,OAAOD,KAAKC,MACd,GAEFkB,OAASpB,MACP,IAAKP,QACH,OAAO,MAET,IACEA,QAAQmB,WAAWb,OAAOC,MAC1B,OAAO,IACT,CAAE,MAAOE,OACP,OAAOD,KAAKC,MACd,GAEFmB,IAAK,CAACrB,IAAKe,SACT,IAAKtB,QACH,OAAO,MAET,IACE,MAAM6B,WAAaL,KAAKM,UAAUR,OAClC,GAAIO,kBAAezB,EACjB,MAAM,IAAIP,UAAU,kDAEtBG,QAAQ+B,QAAQzB,OAAOC,KAAMsB,YAC7B,OAAO,IACT,CAAE,MAAOpB,OACP,OAAOD,KAAKC,MACd"}