/**
 * The `PartitionedSemaphore` module provides a semaphore for limiting
 * concurrency across a shared permit pool while keeping waiters grouped by
 * partition key. A `PartitionedSemaphore<K>` is useful when many independent
 * groups of work compete for the same bounded resource and each group should
 * make progress without one busy group monopolizing released permits.
 *
 * **Mental model**
 *
 * - The semaphore has a fixed shared capacity measured in permits
 * - Work acquires permits with a partition key of type `K`
 * - Waiting acquisitions are tracked per partition
 * - Released permits are assigned to waiting partitions in round-robin order
 * - `withPermit` and `withPermits` acquire permits around an effect and
 *   release them when the effect exits, fails, or is interrupted
 *
 * **Common tasks**
 *
 * - Create a semaphore: {@link make}, {@link makeUnsafe}
 * - Inspect capacity and availability: {@link capacity}, {@link available}
 * - Acquire and release manually: {@link take}, {@link release}
 * - Limit a single operation per partition: {@link withPermit}
 * - Limit weighted work per partition: {@link withPermits}
 * - Run only when permits are immediately available:
 *   {@link withPermitsIfAvailable}
 *
 * **Gotchas**
 *
 * - `withPermitsIfAvailable` does not use a partition key; it only succeeds
 *   when the shared pool has enough permits immediately
 * - Acquiring more permits than the semaphore capacity never completes
 * - Requests for zero or negative permits complete without acquiring anything
 * - Non-finite capacities create an unbounded semaphore whose acquire and
 *   release operations complete immediately
 *
 * @since 4.0.0
 */
import * as Effect from "./Effect.ts";
import * as Option from "./Option.ts";
/**
 * Runtime type identifier used to mark values that implement
 * `PartitionedSemaphore`.
 *
 * **Details**
 *
 * This marker is part of the runtime representation of partitioned semaphore
 * values.
 *
 * @category type IDs
 * @since 4.0.0
 */
export declare const PartitionedTypeId: PartitionedTypeId;
/**
 * Literal type of the `PartitionedSemaphore` runtime type identifier.
 *
 * **When to use**
 *
 * Use to type fields that store the exact `PartitionedSemaphore` runtime marker.
 *
 * **Details**
 *
 * Use this type when declaring fields that must contain the exact
 * `PartitionedTypeId` marker value.
 *
 * @category type IDs
 * @since 4.0.0
 */
export type PartitionedTypeId = "~effect/PartitionedSemaphore";
/**
 * A `PartitionedSemaphore` controls access to a shared permit pool while
 * tracking waiters by partition key.
 *
 * **When to use**
 *
 * Use to coordinate shared permits across partition keys so waiting groups make
 * progress without one group monopolizing the pool.
 *
 * **Details**
 *
 * Waiting permits are distributed across partitions in round-robin order.
 *
 * @category models
 * @since 3.19.4
 */
export interface PartitionedSemaphore<in K> {
    readonly [PartitionedTypeId]: PartitionedTypeId;
    readonly capacity: number;
    readonly available: Effect.Effect<number>;
    readonly take: (key: K, permits: number) => Effect.Effect<void>;
    readonly release: (permits: number) => Effect.Effect<number>;
    readonly withPermits: (key: K, permits: number) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
    readonly withPermit: (key: K) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
    readonly withPermitsIfAvailable: (permits: number) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R>;
}
/**
 * Alias interface for a `PartitionedSemaphore` keyed by values of type `K`.
 *
 * **When to use**
 *
 * Use as an alternate exported name for a partitioned permit pool keyed by `K`.
 *
 * **Details**
 *
 * This interface does not add members beyond `PartitionedSemaphore`; it
 * provides an alternate exported name for APIs that refer to a partitioned
 * permit pool.
 *
 * @category models
 * @since 4.0.0
 */
export interface Partitioned<in K> extends PartitionedSemaphore<K> {
}
/**
 * Constructs a `PartitionedSemaphore` synchronously, outside of `Effect`.
 *
 * **When to use**
 *
 * Use when a partitioned semaphore must be constructed synchronously outside an
 * `Effect` workflow.
 *
 * **Details**
 *
 * Negative permit counts are clamped to `0`. Non-finite permit counts create
 * an unbounded semaphore whose acquire and release operations complete
 * immediately.
 *
 * @see {@link make} for creating a partitioned semaphore inside `Effect`
 *
 * @category constructors
 * @since 3.19.4
 */
export declare const makeUnsafe: <K = unknown>(options: {
    readonly permits: number;
}) => PartitionedSemaphore<K>;
/**
 * Creates a `PartitionedSemaphore` inside an `Effect`.
 *
 * **When to use**
 *
 * Use when semaphore construction should stay inside an `Effect` workflow.
 *
 * **Details**
 *
 * The `permits` option sets the shared permit capacity. The resulting
 * semaphore tracks waiters by partition key and distributes released permits
 * across waiting partitions in round-robin order.
 *
 * **Gotchas**
 *
 * Negative permit counts are clamped to `0`. Non-finite permit counts create
 * an unbounded semaphore.
 *
 * @see {@link makeUnsafe} for synchronous construction
 *
 * @category constructors
 * @since 3.19.4
 */
export declare const make: <K = unknown>(options: {
    readonly permits: number;
}) => Effect.Effect<PartitionedSemaphore<K>>;
/**
 * Gets the current number of available permits.
 *
 * **When to use**
 *
 * Use to inspect a snapshot of how many permits are currently free.
 *
 * **Details**
 *
 * Running the returned effect reads the semaphore's current availability.
 * Taking permits decreases availability, and releasing permits can increase it
 * up to the semaphore capacity.
 *
 * **Gotchas**
 *
 * Reading availability does not reserve permits.
 *
 * @see {@link capacity} for the fixed total permit capacity
 * @see {@link release} for returning permits to the shared pool
 * @see {@link withPermitsIfAvailable} for running only when permits are immediately available
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const available: <K>(self: PartitionedSemaphore<K>) => Effect.Effect<number>;
/**
 * Gets the total capacity.
 *
 * **When to use**
 *
 * Use to inspect the fixed number of permits configured for the semaphore.
 *
 * **Details**
 *
 * Capacity is stored when the semaphore is created and does not change as
 * permits are acquired or released.
 *
 * @see {@link available} for the current number of free permits
 *
 * @category getters
 * @since 4.0.0
 */
export declare const capacity: <K>(self: PartitionedSemaphore<K>) => number;
/**
 * Returns an effect that acquires the requested number of permits for the
 * given partition key.
 *
 * **When to use**
 *
 * Use to manually acquire permits for a partition when acquisition and release
 * must be controlled as separate effects.
 *
 * **Details**
 *
 * If enough permits are available, the effect completes immediately. Otherwise
 * it waits until released permits are assigned to this partition.
 *
 * **Gotchas**
 *
 * Requests for more permits than the semaphore capacity never complete.
 * Requests for zero or a negative number of permits complete without acquiring
 * anything.
 *
 * @see {@link release} for manually returning permits to the shared pool
 * @see {@link withPermits} for automatic acquire and release around an effect
 * @see {@link withPermit} for acquiring exactly one permit around an effect
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const take: {
    /**
     * Returns an effect that acquires the requested number of permits for the
     * given partition key.
     *
     * **When to use**
     *
     * Use to manually acquire permits for a partition when acquisition and release
     * must be controlled as separate effects.
     *
     * **Details**
     *
     * If enough permits are available, the effect completes immediately. Otherwise
     * it waits until released permits are assigned to this partition.
     *
     * **Gotchas**
     *
     * Requests for more permits than the semaphore capacity never complete.
     * Requests for zero or a negative number of permits complete without acquiring
     * anything.
     *
     * @see {@link release} for manually returning permits to the shared pool
     * @see {@link withPermits} for automatic acquire and release around an effect
     * @see {@link withPermit} for acquiring exactly one permit around an effect
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(key: K, permits: number): (self: PartitionedSemaphore<K>) => Effect.Effect<void>;
    /**
     * Returns an effect that acquires the requested number of permits for the
     * given partition key.
     *
     * **When to use**
     *
     * Use to manually acquire permits for a partition when acquisition and release
     * must be controlled as separate effects.
     *
     * **Details**
     *
     * If enough permits are available, the effect completes immediately. Otherwise
     * it waits until released permits are assigned to this partition.
     *
     * **Gotchas**
     *
     * Requests for more permits than the semaphore capacity never complete.
     * Requests for zero or a negative number of permits complete without acquiring
     * anything.
     *
     * @see {@link release} for manually returning permits to the shared pool
     * @see {@link withPermits} for automatic acquire and release around an effect
     * @see {@link withPermit} for acquiring exactly one permit around an effect
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(self: PartitionedSemaphore<K>, key: K, permits: number): Effect.Effect<void>;
};
/**
 * Returns an effect that releases permits back to the shared pool and returns
 * the current available permit count.
 *
 * **When to use**
 *
 * Use to manually return permits acquired with `take` when a lower-level
 * partitioned permit protocol needs explicit release control.
 *
 * **Details**
 *
 * Released permits are first assigned to waiting partitions in round-robin
 * order. Only permits not needed by waiters increase the available count,
 * which is capped at the semaphore capacity.
 *
 * @see {@link take} for manual acquisition
 * @see {@link withPermits} for automatic acquire and release around an effect
 * @see {@link available} for reading the permit count without releasing
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const release: {
    /**
     * Returns an effect that releases permits back to the shared pool and returns
     * the current available permit count.
     *
     * **When to use**
     *
     * Use to manually return permits acquired with `take` when a lower-level
     * partitioned permit protocol needs explicit release control.
     *
     * **Details**
     *
     * Released permits are first assigned to waiting partitions in round-robin
     * order. Only permits not needed by waiters increase the available count,
     * which is capped at the semaphore capacity.
     *
     * @see {@link take} for manual acquisition
     * @see {@link withPermits} for automatic acquire and release around an effect
     * @see {@link available} for reading the permit count without releasing
     *
     * @category combinators
     * @since 4.0.0
     */
    (permits: number): <K>(self: PartitionedSemaphore<K>) => Effect.Effect<number>;
    /**
     * Returns an effect that releases permits back to the shared pool and returns
     * the current available permit count.
     *
     * **When to use**
     *
     * Use to manually return permits acquired with `take` when a lower-level
     * partitioned permit protocol needs explicit release control.
     *
     * **Details**
     *
     * Released permits are first assigned to waiting partitions in round-robin
     * order. Only permits not needed by waiters increase the available count,
     * which is capped at the semaphore capacity.
     *
     * @see {@link take} for manual acquisition
     * @see {@link withPermits} for automatic acquire and release around an effect
     * @see {@link available} for reading the permit count without releasing
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(self: PartitionedSemaphore<K>, permits: number): Effect.Effect<number>;
};
/**
 * Runs an effect after acquiring permits for a partition, then releases those
 * permits when the effect exits.
 *
 * **When to use**
 *
 * Use to guard weighted partitioned work with automatic permit acquisition and
 * release around an effect.
 *
 * **Details**
 *
 * Permit acquisition may wait according to `take` semantics. Once acquired,
 * the permits are released even if the wrapped effect fails or is interrupted.
 *
 * **Gotchas**
 *
 * Requests for more permits than the semaphore capacity never complete.
 * Requests for zero or a negative number of permits run the effect without
 * acquiring anything.
 *
 * @see {@link withPermit} for the single-permit variant
 * @see {@link withPermitsIfAvailable} for running only when permits are
 * immediately available
 * @see {@link take} for manual acquisition
 * @see {@link release} for manual release
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const withPermits: {
    /**
     * Runs an effect after acquiring permits for a partition, then releases those
     * permits when the effect exits.
     *
     * **When to use**
     *
     * Use to guard weighted partitioned work with automatic permit acquisition and
     * release around an effect.
     *
     * **Details**
     *
     * Permit acquisition may wait according to `take` semantics. Once acquired,
     * the permits are released even if the wrapped effect fails or is interrupted.
     *
     * **Gotchas**
     *
     * Requests for more permits than the semaphore capacity never complete.
     * Requests for zero or a negative number of permits run the effect without
     * acquiring anything.
     *
     * @see {@link withPermit} for the single-permit variant
     * @see {@link withPermitsIfAvailable} for running only when permits are
     * immediately available
     * @see {@link take} for manual acquisition
     * @see {@link release} for manual release
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(self: PartitionedSemaphore<K>, key: K, permits: number): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
    /**
     * Runs an effect after acquiring permits for a partition, then releases those
     * permits when the effect exits.
     *
     * **When to use**
     *
     * Use to guard weighted partitioned work with automatic permit acquisition and
     * release around an effect.
     *
     * **Details**
     *
     * Permit acquisition may wait according to `take` semantics. Once acquired,
     * the permits are released even if the wrapped effect fails or is interrupted.
     *
     * **Gotchas**
     *
     * Requests for more permits than the semaphore capacity never complete.
     * Requests for zero or a negative number of permits run the effect without
     * acquiring anything.
     *
     * @see {@link withPermit} for the single-permit variant
     * @see {@link withPermitsIfAvailable} for running only when permits are
     * immediately available
     * @see {@link take} for manual acquisition
     * @see {@link release} for manual release
     *
     * @category combinators
     * @since 4.0.0
     */
    <K, A, E, R>(self: PartitionedSemaphore<K>, key: K, permits: number, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
};
/**
 * Runs an effect after acquiring one permit for a partition, then releases the
 * permit when the effect exits.
 *
 * **When to use**
 *
 * Use to guard partitioned work with exactly one permit and automatic release
 * when the effect exits.
 *
 * **Details**
 *
 * This is the single-permit variant of `withPermits`. The permit is released
 * even if the wrapped effect fails or is interrupted.
 *
 * @see {@link withPermits} for acquiring a weighted number of permits
 * @see {@link withPermitsIfAvailable} for running only when permits are
 * immediately available
 * @see {@link take} for manual acquisition
 * @see {@link release} for manual release
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const withPermit: {
    /**
     * Runs an effect after acquiring one permit for a partition, then releases the
     * permit when the effect exits.
     *
     * **When to use**
     *
     * Use to guard partitioned work with exactly one permit and automatic release
     * when the effect exits.
     *
     * **Details**
     *
     * This is the single-permit variant of `withPermits`. The permit is released
     * even if the wrapped effect fails or is interrupted.
     *
     * @see {@link withPermits} for acquiring a weighted number of permits
     * @see {@link withPermitsIfAvailable} for running only when permits are
     * immediately available
     * @see {@link take} for manual acquisition
     * @see {@link release} for manual release
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(self: PartitionedSemaphore<K>, key: K): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
    /**
     * Runs an effect after acquiring one permit for a partition, then releases the
     * permit when the effect exits.
     *
     * **When to use**
     *
     * Use to guard partitioned work with exactly one permit and automatic release
     * when the effect exits.
     *
     * **Details**
     *
     * This is the single-permit variant of `withPermits`. The permit is released
     * even if the wrapped effect fails or is interrupted.
     *
     * @see {@link withPermits} for acquiring a weighted number of permits
     * @see {@link withPermitsIfAvailable} for running only when permits are
     * immediately available
     * @see {@link take} for manual acquisition
     * @see {@link release} for manual release
     *
     * @category combinators
     * @since 4.0.0
     */
    <K, A, E, R>(self: PartitionedSemaphore<K>, key: K, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
};
/**
 * Runs an effect only when the requested permits can be acquired immediately,
 * returning the result in `Some`.
 *
 * **When to use**
 *
 * Use when guarded work should run only if the shared permit pool can provide
 * the requested permits immediately.
 *
 * **Details**
 *
 * If the permits are not available, the effect is not run and the result is
 * `None`. When permits are acquired, they are released after the wrapped
 * effect completes, fails, or is interrupted. Requests for zero or a negative
 * number of permits run the effect and return `Some`.
 *
 * @see {@link withPermits} for the keyed variant that waits until permits are
 * available for a partition
 *
 * @category combinators
 * @since 4.0.0
 */
export declare const withPermitsIfAvailable: {
    /**
     * Runs an effect only when the requested permits can be acquired immediately,
     * returning the result in `Some`.
     *
     * **When to use**
     *
     * Use when guarded work should run only if the shared permit pool can provide
     * the requested permits immediately.
     *
     * **Details**
     *
     * If the permits are not available, the effect is not run and the result is
     * `None`. When permits are acquired, they are released after the wrapped
     * effect completes, fails, or is interrupted. Requests for zero or a negative
     * number of permits run the effect and return `Some`.
     *
     * @see {@link withPermits} for the keyed variant that waits until permits are
     * available for a partition
     *
     * @category combinators
     * @since 4.0.0
     */
    <K>(self: PartitionedSemaphore<K>, permits: number): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R>;
    /**
     * Runs an effect only when the requested permits can be acquired immediately,
     * returning the result in `Some`.
     *
     * **When to use**
     *
     * Use when guarded work should run only if the shared permit pool can provide
     * the requested permits immediately.
     *
     * **Details**
     *
     * If the permits are not available, the effect is not run and the result is
     * `None`. When permits are acquired, they are released after the wrapped
     * effect completes, fails, or is interrupted. Requests for zero or a negative
     * number of permits run the effect and return `Some`.
     *
     * @see {@link withPermits} for the keyed variant that waits until permits are
     * available for a partition
     *
     * @category combinators
     * @since 4.0.0
     */
    <K, A, E, R>(self: PartitionedSemaphore<K>, permits: number, effect: Effect.Effect<A, E, R>): Effect.Effect<Option.Option<A>, E, R>;
};
//# sourceMappingURL=PartitionedSemaphore.d.ts.map