API reference › @evolu/common › Resource › SharedResourceByKey
Defined in: packages/common/src/Resource.ts:598
Shared Resources keyed by logical identity.
A map-like registry of SharedResources. Each key owns at most one current resource instance. The first acquire for a key lazily creates that key's resource; releasing the key's last Lease disposes it and removes the key from the registry.
Different keys are independent and may progress concurrently. Operations for the same key are serialized.
By default, keys use reference identity, matching native Map. Callers may
instead provide a lookup so logical equality is based on a
derived stable key.
Example
import {
all,
assertEqual,
assertSame,
createRun,
createSharedResourceByKey,
ok,
type Task,
} from "@evolu/common";
interface Connection extends Disposable {
readonly ownerId: string;
readonly send: (message: string) => void;
readonly flush: () => ReadonlyArray<string>;
}
const createConnection =
(ownerId: string): Task<Connection> =>
() => {
const pendingMessages: Array<string> = [];
return ok({
ownerId,
send: (message) => {
pendingMessages.push(message);
},
flush: () => pendingMessages.splice(0),
[Symbol.dispose]: () => {},
});
};
await using run = createRun();
await using connections = await run.ok(
createSharedResourceByKey(createConnection, {
idleDisposeAfter: "30s",
}),
);
const send = (ownerId: string, message: string): Task<void> =>
connections.use(ownerId, (connection) => () => {
connection.send(message);
return ok();
});
// Same-key calls share one connection. Work for different keys remains
// independent, so all three operations can run concurrently.
await run.ok(
all(
[
send("owner-1", "first"),
send("owner-1", "second"),
send("owner-2", "hello"),
],
{ concurrency: 3 },
),
);
// `acquireCurrent` does not create absent keys. The idle delay keeps the two
// existing connections available to enumerate and flush.
using missingLease = await run.ok(connections.acquireCurrent("owner-3"));
const messagesByOwnerId = new Map<string, ReadonlyArray<string>>();
await run.ok(
connections.forEachCurrent((connection) => {
messagesByOwnerId.set(connection.ownerId, connection.flush());
}),
);
assertSame(missingLease, undefined);
assertEqual(
messagesByOwnerId,
new Map([
["owner-1", ["first", "second"]],
["owner-2", ["hello"]],
]),
);
Extends
Methods
[asyncDispose]()
asyncDispose: PromiseLike<void>;
Defined in: node_modules/@typescript/old/lib/lib.esnext.disposable.d.ts:38
Inherited from
AsyncDisposable.[asyncDispose]
Properties
acquire
readonly acquire: (key: K) => Task<Lease<T>>;
Defined in: packages/common/src/Resource.ts:611
Acquires a Lease on the shared resource for key, creating the
resource on first use.
The same contract as SharedResource.acquire: once started, acquire runs to completion even when the caller aborts its Fiber, and the returned lease still counts as held. Registry disposal before lease transfer aborts the acquisition. Always await the result and release the lease.
acquireCurrent
readonly acquireCurrent: (key: K) => Task<
| Lease<T>
| undefined>;
Defined in: packages/common/src/Resource.ts:623
Acquires a Lease on the current resource for key without creating
one.
Waits for preceding creation or disposal for the same key to finish.
Returns undefined if no current resource remains. Registry disposal while
waiting aborts the acquisition before a lease is transferred. Registry
disposal after transfer can drain the lease before the caller resumes,
matching SharedResource.acquireCurrent.
forEachCurrent
readonly forEachCurrent: (callback: (resource: DistributiveOmit<T>, key: K) => void) => Task<void>;
Defined in: packages/common/src/Resource.ts:654
Calls callback for each current resource it can lease from keys
registered when this Task starts.
Never creates resources. A resource whose creation is in progress may be included after creation finishes; one disposed before its temporary lease is acquired is skipped. Each acquired lease stays held while later keys are awaited, and every callback runs while all acquired resources remain leased. Caller abort is observed between keys; already-collected leases are released and no callbacks run.
snapshot
readonly snapshot: () => SharedResourceByKeySnapshot<K>;
Defined in: packages/common/src/Resource.ts:659
Returns current per-key shared-resource states for monitoring/debugging.
use
readonly use: <R, E, D>(key: K, callback: (resource: DistributiveOmit<T>, created: boolean) => Task<R, E, D>) => Task<R, E, D>;
Defined in: packages/common/src/Resource.ts:635
Acquires a Lease, runs a Task with the shared resource for key,
and releases the lease after the Task settles.
Creates the resource when absent. The callback receives whether this use created the resource generation. While the registry remains running, the lease prevents ordinary idle disposal. Disposing this registry is forceful: it drains the lease and may dispose the resource before or while the callback Task runs.