import '../chunk-3G6RQLXK.mjs';

// src/server/tanstack.ts
var TANSTACK_R2_BUCKET_BINDING = "CIMPLIFY_CACHE_R2_BUCKET";
var TANSTACK_R2_PREFIX_ENV = "CIMPLIFY_CACHE_R2_PREFIX";
var TANSTACK_PATH_INDEX_BINDING = "CIMPLIFY_PATH_INDEX";
var TANSTACK_CACHE_NAMESPACE = "nitro";
var CIMPLIFY_TAG_PREFIX = "cimplify:";
var CIMPLIFY_CACHE_META_FIELD = "__cimplifyCache";
var EMPTY_STORAGE_KEY = "__cimplify_empty_key__";
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function stringArray(value) {
  return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
}
function metadataFrom(value) {
  if (!isRecord(value)) return void 0;
  const metadata = value[CIMPLIFY_CACHE_META_FIELD];
  return isRecord(metadata) ? metadata : void 0;
}
function cimplifyTagsFrom(candidates) {
  const seen = /* @__PURE__ */ new Set();
  for (const candidate of candidates) {
    for (const tag of candidate ?? []) {
      if (!tag.startsWith(CIMPLIFY_TAG_PREFIX) || seen.has(tag)) continue;
      seen.add(tag);
    }
  }
  return [...seen];
}
function extractTags(key, value, options, driverOptions) {
  const optionMeta = metadataFrom(options);
  const valueMeta = metadataFrom(value);
  const valueRecord = isRecord(value) ? value : void 0;
  const nestedValue = isRecord(valueRecord?.value) ? valueRecord.value : void 0;
  const configured = typeof driverOptions.tags === "function" ? driverOptions.tags(key, value, options) : driverOptions.tags;
  return cimplifyTagsFrom([
    configured,
    optionMeta?.tags,
    options?.tags,
    options?.cimplifyTags,
    options?.cacheTags,
    valueMeta?.tags,
    stringArray(valueRecord?.tags),
    stringArray(valueRecord?.cimplifyTags),
    stringArray(valueRecord?.cacheTags),
    stringArray(nestedValue?.tags),
    stringArray(nestedValue?.cimplifyTags),
    stringArray(nestedValue?.cacheTags)
  ]);
}
function extractCacheKey(key, value, options, driverOptions) {
  const configured = typeof driverOptions.cacheKey === "function" ? driverOptions.cacheKey(key, value, options) : driverOptions.cacheKey;
  if (configured) return configured;
  const optionMeta = metadataFrom(options);
  const valueMeta = metadataFrom(value);
  if (optionMeta?.cacheKey) return optionMeta.cacheKey;
  if (options?.cacheKey) return options.cacheKey;
  if (options?.cimplifyCacheKey) return options.cimplifyCacheKey;
  if (valueMeta?.cacheKey) return valueMeta.cacheKey;
  return key;
}
function extractIsFetch(key, value, options, driverOptions) {
  if (typeof driverOptions.isFetch === "function") {
    return driverOptions.isFetch(key, value, options);
  }
  if (typeof driverOptions.isFetch === "boolean") return driverOptions.isFetch;
  const optionMeta = metadataFrom(options);
  const valueMeta = metadataFrom(value);
  return Boolean(
    optionMeta?.isFetch ?? options?.isFetch ?? options?.cimplifyIsFetch ?? valueMeta?.isFetch ?? false
  );
}
function valueForStorage(value) {
  if (!isRecord(value) || !(CIMPLIFY_CACHE_META_FIELD in value)) return value;
  const { [CIMPLIFY_CACHE_META_FIELD]: _metadata, ...rest } = value;
  return rest;
}
function joinR2Parts(...parts) {
  return parts.map((part) => part.trim().replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
}
function encodeStorageKey(key) {
  return key === "" ? EMPTY_STORAGE_KEY : encodeURIComponent(key);
}
function decodeStorageKey(key) {
  if (key === EMPTY_STORAGE_KEY) return "";
  try {
    return decodeURIComponent(key);
  } catch {
    return key;
  }
}
function cimplifyTanstackR2Key(prefix, key, namespace = TANSTACK_CACHE_NAMESPACE) {
  return joinR2Parts(prefix, namespace, encodeStorageKey(key));
}
function cimplifyTanstackR2ListPrefix(prefix, base, namespace) {
  if (!base) return `${joinR2Parts(prefix, namespace)}/`;
  return cimplifyTanstackR2Key(prefix, base, namespace);
}
function storageKeyFromR2Key(prefix, namespace, key) {
  const base = `${joinR2Parts(prefix, namespace)}/`;
  const encoded = key.startsWith(base) ? key.slice(base.length) : key;
  return decodeStorageKey(encoded);
}
function pathIndexFor(env) {
  if (!env.pathIndex) return null;
  return env.pathIndex.get(env.pathIndex.idFromName(env.prefix));
}
async function resolveRuntimeEnv(options) {
  const env = await options.getEnv?.() ?? options.env;
  const r2 = env?.[TANSTACK_R2_BUCKET_BINDING];
  const prefix = options.prefix ?? env?.[TANSTACK_R2_PREFIX_ENV];
  if (!r2 || !prefix) return null;
  return {
    r2,
    prefix,
    pathIndex: env?.[TANSTACK_PATH_INDEX_BINDING]
  };
}
async function registerIndex(env, cacheKey, r2Key, tags, isFetch) {
  if (tags.length === 0) return;
  const index = pathIndexFor(env);
  if (!index) return;
  try {
    await index.indexAdd(cacheKey, r2Key, tags, isFetch);
  } catch {
  }
}
async function listR2Keys(r2, prefix) {
  const keys = [];
  let cursor;
  do {
    const page = await r2.list({ prefix, cursor });
    keys.push(...page.objects.map((object) => object.key));
    cursor = page.truncated ? page.cursor : void 0;
  } while (cursor);
  return keys;
}
async function putAndIndex(runtimeEnv, driverOptions, key, storedValue, indexValue, options) {
  const namespace = driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE;
  const r2Key = cimplifyTanstackR2Key(runtimeEnv.prefix, key, namespace);
  try {
    await runtimeEnv.r2.put(r2Key, storedValue);
  } catch {
    return;
  }
  try {
    const tags = extractTags(key, indexValue, options, driverOptions);
    if (tags.length === 0) return;
    await registerIndex(
      runtimeEnv,
      extractCacheKey(key, indexValue, options, driverOptions),
      r2Key,
      tags,
      extractIsFetch(key, indexValue, options, driverOptions)
    );
  } catch {
  }
}
async function getRawItem(driverOptions, key) {
  const runtimeEnv = await resolveRuntimeEnv(driverOptions);
  if (!runtimeEnv) return null;
  try {
    const object = await runtimeEnv.r2.get(
      cimplifyTanstackR2Key(
        runtimeEnv.prefix,
        key,
        driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE
      )
    );
    return object ? await object.text() : null;
  } catch {
    return null;
  }
}
function cimplifyTanstackCacheOptions(metadata) {
  return { [CIMPLIFY_CACHE_META_FIELD]: metadata };
}
function withCimplifyCacheMetadata(value, metadata) {
  return { ...value, [CIMPLIFY_CACHE_META_FIELD]: metadata };
}
function createCimplifyTanstackCacheDriver(options = {}) {
  const driverOptions = { ...options };
  return {
    name: "cimplify-tanstack-r2-cache",
    options: driverOptions,
    async hasItem(key) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return false;
      try {
        const object = await runtimeEnv.r2.head(
          cimplifyTanstackR2Key(
            runtimeEnv.prefix,
            key,
            driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE
          )
        );
        return Boolean(object);
      } catch {
        return false;
      }
    },
    async getItem(key) {
      const raw = await getRawItem(driverOptions, key);
      if (raw === null) return null;
      try {
        return JSON.parse(raw);
      } catch {
        return raw;
      }
    },
    async getItemRaw(key) {
      return getRawItem(driverOptions, key);
    },
    async setItem(key, value, options2) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return;
      const strippedValue = valueForStorage(value);
      await putAndIndex(
        runtimeEnv,
        driverOptions,
        key,
        JSON.stringify(strippedValue) ?? "null",
        value,
        options2
      );
    },
    async setItemRaw(key, value, options2) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return;
      await putAndIndex(runtimeEnv, driverOptions, key, value, value, options2);
    },
    async removeItem(key) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return;
      try {
        await runtimeEnv.r2.delete(
          cimplifyTanstackR2Key(
            runtimeEnv.prefix,
            key,
            driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE
          )
        );
      } catch {
      }
    },
    async getKeys(base) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return [];
      const namespace = driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE;
      try {
        const keys = await listR2Keys(
          runtimeEnv.r2,
          cimplifyTanstackR2ListPrefix(runtimeEnv.prefix, base, namespace)
        );
        return keys.map((key) => storageKeyFromR2Key(runtimeEnv.prefix, namespace, key));
      } catch {
        return [];
      }
    },
    async clear(base) {
      const runtimeEnv = await resolveRuntimeEnv(driverOptions);
      if (!runtimeEnv) return;
      const namespace = driverOptions.namespace ?? TANSTACK_CACHE_NAMESPACE;
      try {
        const keys = await listR2Keys(
          runtimeEnv.r2,
          cimplifyTanstackR2ListPrefix(runtimeEnv.prefix, base, namespace)
        );
        await Promise.all(keys.map((key) => runtimeEnv.r2.delete(key)));
      } catch {
      }
    }
  };
}
var cimplifyTanstackCacheDriver = createCimplifyTanstackCacheDriver;

export { CIMPLIFY_CACHE_META_FIELD, CIMPLIFY_TAG_PREFIX, TANSTACK_CACHE_NAMESPACE, TANSTACK_PATH_INDEX_BINDING, TANSTACK_R2_BUCKET_BINDING, TANSTACK_R2_PREFIX_ENV, cimplifyTanstackCacheDriver, cimplifyTanstackCacheOptions, cimplifyTanstackR2Key, createCimplifyTanstackCacheDriver, withCimplifyCacheMetadata };
