import { Alepha, MiddlewareMetadata, OPTIONS, Primitive, Service, Static } from "alepha";
import { DateTimeProvider, DurationLike, Timeout } from "alepha/datetime";
//#region ../../src/cache/core/providers/CacheProvider.d.ts
/**
 * Cache provider interface.
 *
 * All methods are asynchronous and return promises.
 * Values are stored as Uint8Array.
 */
declare abstract class CacheProvider {
  protected encoder: TextEncoder;
  protected decoder: TextDecoder;
  protected codes: {
    BINARY: number;
    JSON: number;
    STRING: number;
    COMPRESSED: number;
  };
  /**
   * Get the value of a key.
   *
   * @param name Cache name, used to group keys. Should be Redis-like "some:group:name" format.
   * @param key The key of the value to get.
   *
   * @return The value of the key, or undefined if the key does not exist.
   */
  abstract get(name: string, key: string): Promise<Uint8Array | undefined>;
  /**
   * Set the string value of a key.
   *
   * @param name Cache name, used to group keys. Should be Redis-like "some:group:name" format.
   * @param key The key of the value to set.
   * @param value The value to set.
   * @param ttl The time-to-live of the key, in milliseconds.
   *
   * @return The value of the key.
   */
  abstract set(name: string, key: string, value: Uint8Array, ttl?: number): Promise<Uint8Array>;
  /**
   * Remove the specified keys.
   *
   * @param name Cache name, used to group keys. Should be Redis-like "some:group:name" format.
   * @param keys The keys to delete.
   */
  abstract del(name: string, ...keys: string[]): Promise<void>;
  abstract has(name: string, key: string): Promise<boolean>;
  abstract keys(name: string, filter?: string): Promise<string[]>;
  /**
   * Remove all keys from all cache names.
   */
  abstract clear(): Promise<void>;
  /**
   * Increment the integer value of a key by the given amount.
   *
   * If the key does not exist, it is set to 0 before performing the operation.
   * This operation is atomic when using Redis.
   *
   * @param name Cache name, used to group keys.
   * @param key The key to increment.
   * @param amount The amount to increment by.
   * @returns The new value after incrementing.
   */
  abstract incr(name: string, key: string, amount: number): Promise<number>;
  /**
   * Set a typed value with automatic serialization and optional compression.
   */
  setTyped(name: string, key: string, value: unknown, options?: {
    ttl?: number;
    compress?: boolean;
  }): Promise<void>;
  /**
   * Get a typed value with automatic deserialization and optional decompression.
   */
  getTyped<T>(name: string, key: string): Promise<T | undefined>;
  /**
   * Invalidate cache keys with wildcard support.
   *
   * Keys ending in `*` are expanded via `this.keys()`.
   * Called with no keys, delegates to `this.del(name)` which clears the entire container.
   */
  invalidateKeys(name: string, keys: string[]): Promise<void>;
  /**
   * Serialize a value to a typed Uint8Array with a leading type marker byte.
   */
  protected serialize(value: unknown): Uint8Array;
  /**
   * Deserialize a typed Uint8Array back to the original value.
   */
  protected deserialize<T>(uint8Array: Uint8Array): T;
  /**
   * Compress data with gzip, prepending a COMPRESSED marker byte.
   */
  protected compress(data: Uint8Array): Promise<Uint8Array>;
  /**
   * Decompress gzipped data.
   */
  protected decompress(data: Uint8Array): Promise<Uint8Array>;
}
//#endregion
//#region ../../src/cache/core/primitives/$cache.d.ts
/**
 * Creates a cache primitive for caching with automatic management.
 *
 * **Middleware mode** (no `handler`) — usable in `use` arrays AND as a store:
 * ```ts
 * class UserService {
 *   userCache = $cache({ name: "users", ttl: [10, "minutes"] });
 *
 *   fetchUser = $pipeline({
 *     use: [this.userCache],
 *     handler: async (userId: string) => this.repo.getById(userId),
 *   });
 *
 *   async invalidateUser(userId: string) {
 *     await this.userCache.invalidate(userId);
 *   }
 * }
 * ```
 *
 * **Primitive mode** (with `handler`) — standalone callable:
 * ```ts
 * getUserData = $cache({
 *   name: "user-data",
 *   ttl: [10, "minutes"],
 *   handler: async (userId: string) => {
 *     return await database.users.findById(userId);
 *   }
 * });
 * ```
 */
declare function $cache<TReturn = string, TParameter extends any[] = any[]>(options: CachePrimitiveOptions<TReturn, TParameter> & {
  handler: (...args: TParameter) => TReturn;
}): CachePrimitiveFn<TReturn, TParameter>;
declare function $cache<TReturn = any, TParameter extends any[] = any[]>(options?: CachePrimitiveOptions<TReturn, TParameter>): CacheMiddlewareFn<TReturn>;
/**
 * Options for the in-memory L1 tier.
 */
interface CacheMemoryTierOptions {
  /**
   * TTL for the in-memory tier. Should be ≤ the remote `ttl`.
   * Bounds the cross-isolate staleness window after invalidation.
   *
   * @default min(ttl, 30s)
   */
  ttl?: DurationLike;
  /**
   * LRU bound — max entries kept in memory before eviction.
   *
   * @default 500
   */
  max?: number;
  /**
   * Also cache provider misses (`undefined`) in memory for this duration.
   * Prevents hammering the remote tier on cold/unknown keys.
   *
   * @default off
   */
  negative?: DurationLike;
}
interface CachePrimitiveOptions<TReturn = any, TParameter extends any[] = any[]> {
  /**
   * The cache name. This is useful for invalidating multiple caches at once.
   *
   * Store key as `cache:$name:$key`.
   *
   * @default Name of the key of the class.
   */
  name?: string;
  /**
   * Function which returns cached data.
   */
  handler?: (...args: TParameter) => TReturn;
  /**
   * The key generator for the cache.
   * If not provided, the arguments will be json.stringify().
   */
  key?: (...args: TParameter) => string;
  /**
   * The store provider for the cache.
   *
   * Accepts:
   * - `"memory"` — short-circuits to {@link MemoryCacheProvider} regardless
   *   of the default `CacheProvider` binding. Useful for caches that must
   *   stay process-local (e.g. ETag, HTTP client).
   * - A {@link CacheProvider} class (concrete OR abstract) — resolved via
   *   `alepha.inject(...)` at primitive construction. Use this to opt a
   *   specific cache into a non-default backend (e.g.
   *   `provider: DatabaseCacheProvider` to keep one cache in SQL while the
   *   rest of the app uses Cloudflare KV).
   * - `undefined` — falls back to whatever is bound to `CacheProvider` in
   *   the container. On Cloudflare workers this is
   *   {@link CloudflareKVProvider} by default; on Node it's
   *   {@link MemoryCacheProvider}.
   *
   * Note: passing an *abstract* class works because Alepha's DI resolves
   * through substitutions, e.g. `alepha.with({ provide: CacheProvider, use:
   * MyCacheProvider })`.
   */
  provider?: Service<CacheProvider> | "memory";
  /**
   * The time-to-live for the cache in seconds.
   * Set 0 to skip expiration.
   *
   * @default 300 (5 minutes).
   */
  ttl?: DurationLike;
  /**
   * If the cache is disabled.
   */
  disabled?: boolean;
  /**
   * Enable gzip compression for cached values.
   * Reduces storage size by 60-80% for JSON payloads at the cost of CPU.
   */
  compress?: boolean;
  /**
   * Add an in-process L1 memory tier in front of `provider`.
   *
   * Reads check memory first, fall back to the provider on miss. Writes go
   * to both tiers (write-through), so own-writes are immediately visible.
   *
   * Caveats:
   * - Per-process only. Each Worker isolate / Node process has its own L1.
   *   `invalidate()` clears the local L1 + the remote provider; other
   *   processes keep their L1 until its TTL expires.
   * - Use a short L1 TTL to bound the cross-isolate staleness window.
   *
   * @default off
   */
  memory?: true | CacheMemoryTierOptions;
  /**
   * Stale-while-revalidate window. After `ttl` expires, the cached value
   * remains servable for `stale` longer; reads in this window return the
   * stale value immediately and trigger ONE background refresh
   * (single-flight per key).
   *
   * Requires a `handler` (primitive mode) OR middleware mode wrapping a
   * handler — the cache needs to know how to recompute.
   *
   * @default off
   */
  stale?: DurationLike;
}
/**
 * Cache configuration atom.
 */
declare const cacheOptions: import("alepha").Atom<import("zod").ZodObject<{
  enabled: import("zod").ZodDefault<import("zod").ZodBoolean>;
  defaultTtl: import("zod").ZodDefault<import("zod").ZodNumber>;
}, import("zod/v4/core").$strip>, "alepha.cache.options">;
type CacheAtomOptions = Static<typeof cacheOptions.schema>;
declare module "alepha" {
  interface State {
    [cacheOptions.key]: CacheAtomOptions;
  }
}
declare const SWR_MARKER: "__swr";
type SwrEnvelope = {
  [SWR_MARKER]: 1;
  v: unknown;
  f: number;
};
type L1Entry<T> = {
  value: T | undefined;
  expiresAt: number;
  negative: boolean;
};
type ReadResult<T> = {
  value: T | undefined;
  stale: boolean;
};
declare class CachePrimitive<TReturn = any, TParameter extends any[] = any[]> extends Primitive<CachePrimitiveOptions<TReturn, TParameter>> {
  protected readonly settings: Readonly<{
    enabled: boolean;
    defaultTtl: number;
  }>;
  protected readonly dateTimeProvider: DateTimeProvider;
  readonly provider: CacheProvider;
  protected readonly memoryStore?: Map<string, L1Entry<TReturn>>;
  protected readonly memoryMax: number;
  protected readonly memoryTtlMs: number;
  protected readonly negativeTtlMs: number;
  protected readonly inflightRefreshes: Map<string, Promise<TReturn>>;
  constructor(args: ConstructorParameters<typeof Primitive<CachePrimitiveOptions<TReturn, TParameter>>>[0]);
  get container(): string;
  run(...args: TParameter): Promise<TReturn>;
  key(...args: TParameter): string;
  incr(key: string, amount?: number): Promise<number>;
  invalidate(...keys: string[]): Promise<void>;
  set(key: string, value: TReturn, ttl?: DurationLike): Promise<void>;
  get(key: string): Promise<TReturn | undefined>;
  /**
   * Internal read that also reports whether the value is stale (SWR
   * grace window). Middleware and `run()` use this to decide whether to
   * schedule a background refresh.
   */
  read(key: string): Promise<ReadResult<TReturn>>;
  /**
   * Run a handler under single-flight: concurrent callers for the same
   * key share one in-flight promise.
   */
  runSingleFlight(key: string, handler: () => Promise<TReturn> | TReturn): Promise<TReturn>;
  /**
   * Schedule a background refresh for a stale key. At most one refresh
   * per key is in-flight at any time; failures are swallowed (the stale
   * value keeps being served until expiry).
   */
  scheduleRefresh(key: string, handler: () => Promise<TReturn> | TReturn): void;
  protected $provider(): CacheProvider;
  protected isSwrEnvelope(value: unknown): value is SwrEnvelope;
  protected setL1(key: string, entry: L1Entry<TReturn>): void;
  protected delL1(key: string): void;
}
interface CachePrimitiveFn<TReturn = any, TParameter extends any[] = any[]> extends CachePrimitive<TReturn, TParameter> {
  /**
   * Run the cache primitive with the provided arguments.
   */
  (...args: TParameter): Promise<TReturn>;
}
/**
 * Cache middleware + store. Callable as middleware `(handler) => wrappedHandler`
 * AND exposes store methods (`.get()`, `.set()`, `.invalidate()`, `.incr()`).
 */
interface CacheMiddlewareFn<TReturn = any> extends CachePrimitive<TReturn, any[]> {
  <T extends (...args: any[]) => any>(handler: T): T;
  [OPTIONS]?: MiddlewareMetadata;
}
//#endregion
//#region ../../src/cache/core/providers/CloudflareKVProvider.d.ts
/**
 * KVNamespace interface matching Cloudflare's KV API.
 */
interface KVNamespace {
  get(key: string, type: "arrayBuffer"): Promise<ArrayBuffer | null>;
  get(key: string, type: "text"): Promise<string | null>;
  get(key: string, type?: "text"): Promise<string | null>;
  put(key: string, value: string | ArrayBuffer | ReadableStream, options?: KVPutOptions): Promise<void>;
  delete(key: string): Promise<void>;
  list(options?: KVListOptions): Promise<KVListResult>;
}
interface KVPutOptions {
  expiration?: number;
  expirationTtl?: number;
  metadata?: unknown;
}
interface KVListOptions {
  prefix?: string;
  limit?: number;
  cursor?: string;
}
interface KVListResult {
  keys: KVListKey[];
  list_complete: boolean;
  cursor?: string;
}
interface KVListKey {
  name: string;
  expiration?: number;
  metadata?: unknown;
}
/**
 * Default KV binding name used in wrangler configuration.
 */
declare const KV_DEFAULT_BINDING = "KV_CACHE";
/**
 * Cloudflare KV cache provider.
 *
 * Uses a KV namespace binding for all cache operations.
 * Keys are stored as: `cache:{name}:{key}`
 *
 * **Required Cloudflare binding:**
 * - `KV_CACHE` - A KV namespace binding in wrangler configuration
 *
 * @example
 * ```toml
 * # wrangler.toml - automatically generated by alepha build
 * [[kv_namespaces]]
 * binding = "KV_CACHE"
 * id = "abc123"
 * ```
 */
declare class CloudflareKVProvider extends CacheProvider {
  protected readonly alepha: Alepha;
  protected readonly log: import("alepha/logger").Logger;
  protected kv?: KVNamespace;
  protected readonly onStart: import("alepha").HookPrimitive<"start">;
  get(name: string, key: string): Promise<Uint8Array | undefined>;
  set(name: string, key: string, value: Uint8Array, ttl?: number): Promise<Uint8Array>;
  del(name: string, ...keys: string[]): Promise<void>;
  has(name: string, key: string): Promise<boolean>;
  keys(name: string, filter?: string): Promise<string[]>;
  clear(): Promise<void>;
  incr(name: string, key: string, amount: number): Promise<number>;
  /**
   * Build the full KV key: `cache:{name}:{key}`
   */
  protected prefix(...path: string[]): string;
  protected getKV(): KVNamespace;
  /**
   * List all keys matching a prefix, handling pagination.
   */
  protected listAllKeys(prefix: string): Promise<string[]>;
}
//#endregion
//#region ../../src/cache/core/providers/MemoryCacheProvider.d.ts
type CacheName = string;
type CacheKey = string;
type CacheValue = {
  data?: Uint8Array;
  timeout?: Timeout;
};
interface MemoryCacheCall {
  name: string;
  key: string;
  timestamp: number;
}
interface MemoryCacheSetCall extends MemoryCacheCall {
  value: Uint8Array;
  ttl?: number;
}
interface MemoryCacheDelCall {
  name: string;
  keys: string[];
  timestamp: number;
}
interface MemoryCacheStats {
  hits: number;
  misses: number;
  sets: number;
  deletes: number;
}
interface MemoryCacheProviderOptions {
  /**
   * Error to throw on get operations (for testing error handling)
   */
  getError?: Error | null;
  /**
   * Error to throw on set operations (for testing error handling)
   */
  setError?: Error | null;
  /**
   * Error to throw on del operations (for testing error handling)
   */
  delError?: Error | null;
}
/**
 * In-memory implementation of CacheProvider for testing.
 *
 * This provider stores all cache entries in memory, making it ideal for
 * unit tests that need to verify cache operations without touching Redis or other backends.
 *
 * @example
 * ```typescript
 * // In tests, substitute the real CacheProvider with MemoryCacheProvider
 * const alepha = Alepha.create().with({
 *   provide: CacheProvider,
 *   use: MemoryCacheProvider,
 * });
 *
 * // Run code that uses caching
 * const service = alepha.inject(MyService);
 * await service.fetchWithCache("key");
 *
 * // Verify cache behavior
 * const cache = alepha.inject(MemoryCacheProvider);
 * expect(cache.stats().misses).toBe(1);
 * await service.fetchWithCache("key");
 * expect(cache.stats().hits).toBe(1);
 * ```
 */
declare class MemoryCacheProvider extends CacheProvider {
  protected readonly dateTimeProvider: DateTimeProvider;
  protected readonly log: import("alepha/logger").Logger;
  protected store: Record<CacheName, Record<CacheKey, CacheValue>>;
  /**
   * All recorded get calls.
   */
  getCalls: MemoryCacheCall[];
  /**
   * All recorded set calls.
   */
  setCalls: MemoryCacheSetCall[];
  /**
   * All recorded del calls.
   */
  delCalls: MemoryCacheDelCall[];
  /**
   * Cache statistics.
   */
  protected _stats: MemoryCacheStats;
  /**
   * Error to throw on get (for testing error handling)
   */
  getError: Error | null;
  /**
   * Error to throw on set (for testing error handling)
   */
  setError: Error | null;
  /**
   * Error to throw on del (for testing error handling)
   */
  delError: Error | null;
  constructor(options?: MemoryCacheProviderOptions);
  get(name: string, key: string): Promise<Uint8Array | undefined>;
  set(name: string, key: string, value: Uint8Array, ttl?: number): Promise<Uint8Array>;
  del(name: string, ...keys: string[]): Promise<void>;
  has(name: string, key: string): Promise<boolean>;
  keys(name: string, filter?: string): Promise<string[]>;
  clear(): Promise<void>;
  incr(name: string, key: string, amount: number): Promise<number>;
  /**
   * Get cache statistics (hits, misses, sets, deletes).
   *
   * @example
   * ```typescript
   * expect(cache.stats().hits).toBe(1);
   * expect(cache.stats().misses).toBe(0);
   * ```
   */
  stats(): MemoryCacheStats;
  /**
   * Check if a key was set during the test.
   *
   * @example
   * ```typescript
   * expect(cache.wasSet("my-cache", "user:123")).toBe(true);
   * ```
   */
  wasSet(name: string, key?: string): boolean;
  /**
   * Check if a key was retrieved during the test.
   *
   * @example
   * ```typescript
   * expect(cache.wasGet("my-cache", "user:123")).toBe(true);
   * ```
   */
  wasGet(name: string, key?: string): boolean;
  /**
   * Check if a key was deleted during the test.
   *
   * @example
   * ```typescript
   * expect(cache.wasDeleted("my-cache", "user:123")).toBe(true);
   * ```
   */
  wasDeleted(name: string, key?: string): boolean;
  /**
   * Get the number of cached entries for a specific cache name.
   *
   * @example
   * ```typescript
   * expect(cache.size("my-cache")).toBe(5);
   * ```
   */
  size(name?: string): number;
  /**
   * Get all cache names.
   *
   * @example
   * ```typescript
   * expect(cache.names()).toContain("my-cache");
   * ```
   */
  names(): string[];
  /**
   * Reset all in-memory state (useful between tests).
   *
   * @example
   * ```typescript
   * beforeEach(() => {
   *   cache.reset();
   * });
   * ```
   */
  reset(): void;
}
//#endregion
//#region ../../src/cache/core/index.d.ts
declare module "alepha" {
  interface Hooks {
    /**
     * Fires when a cache lookup finds a value.
     */
    "cache:hit": {
      container: string;
      key: string;
    };
    /**
     * Fires when a cache lookup does not find a value.
     */
    "cache:miss": {
      container: string;
      key: string;
    };
    /**
     * Fires when a value is written to the cache.
     */
    "cache:set": {
      container: string;
      key: string;
      ttlMs?: number;
    };
    /**
     * Fires when a stale value (SWR grace window) is served and a
     * background refresh is scheduled.
     */
    "cache:stale": {
      container: string;
      key: string;
    };
    /**
     * Fires when a background SWR refresh completes successfully and
     * the value has been written back to the cache.
     */
    "cache:revalidate": {
      container: string;
      key: string;
    };
  }
}
/**
 * Type-safe caching with TTL support.
 *
 * **Features:**
 * - Cached computations with type-safe keys and values
 * - Configurable TTL
 * - Cache invalidation
 * - Automatic cache population
 * - Providers: Memory (default), Redis
 *
 * @module alepha.cache
 */
declare const AlephaCache: import("alepha").Service<import("alepha").Module>;
//#endregion
export { $cache, AlephaCache, CacheAtomOptions, CacheMemoryTierOptions, CacheMiddlewareFn, CachePrimitive, CachePrimitiveFn, CachePrimitiveOptions, CacheProvider, CloudflareKVProvider, KVListKey, KVListOptions, KVListResult, KVNamespace, KVPutOptions, KV_DEFAULT_BINDING, MemoryCacheCall, MemoryCacheDelCall, MemoryCacheProvider, MemoryCacheProviderOptions, MemoryCacheSetCall, MemoryCacheStats, cacheOptions };
//# sourceMappingURL=index.d.ts.map