@compforge/harness-common 0.5.9 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,11 @@ view during initialize, so concurrent consumers share them and dispose before th
27
27
  Dependency graphs must be acyclic. A failed initialization permits retry only after successful cleanup;
28
28
  failed cleanup poisons that key and is reported again when the root manager is disposed.
29
29
 
30
+ Use `clients.create({ createClient })` for a fresh caller-owned client. The caller may dispose it as soon as its work
31
+ finishes; dependencies acquired through `get` remain available to other clients until root disposal. The root also
32
+ disposes created clients as an idempotent safety net. Use `get` when callers should share the client itself; borrowers
33
+ must not dispose those shared instances. Neither API constructs anything before it is called.
34
+
30
35
  `FileDataSource` declares a nonempty group of distinct `paths` that can be acquired together.
31
36
  `FileClient.read` obtains the whole group once and returns one `FileReadResult` per declared path,
32
37
  in order: `{ path, status: "ok", bytes }` or `{ path, status: "error", error }`. Empty files succeed;
@@ -9,5 +9,11 @@ export declare class ClientManager {
9
9
  readonly signal: AbortSignal;
10
10
  constructor(signal?: AbortSignal);
11
11
  get<C extends Client>(provider: ClientProvider<C>): Promise<C>;
12
+ /**
13
+ * @spec Create a caller-owned client that can be disposed before this root scope ends.
14
+ * @rule Dependencies acquired with get remain shared until root disposal; create never caches by identity.
15
+ * @why Short-lived protocol clients borrow longer-lived transports. Root disposal remains an idempotent safety net.
16
+ */
17
+ create<C extends Client>(factory: Pick<ClientProvider<C>, "createClient">): Promise<C>;
12
18
  dispose(): Promise<void>;
13
19
  }
@@ -14,8 +14,18 @@ export class ClientManager {
14
14
  this.signal = signal ? AbortSignal.any([signal, this.#controller.signal]) : this.#controller.signal;
15
15
  }
16
16
  get(provider) {
17
+ return this.#acquire(provider.clientKey, provider);
18
+ }
19
+ /**
20
+ * @spec Create a caller-owned client that can be disposed before this root scope ends.
21
+ * @rule Dependencies acquired with get remain shared until root disposal; create never caches by identity.
22
+ * @why Short-lived protocol clients borrow longer-lived transports. Root disposal remains an idempotent safety net.
23
+ */
24
+ create(factory) {
25
+ return this.#acquire(Symbol("owned client"), factory);
26
+ }
27
+ #acquire(key, provider) {
17
28
  this.signal.throwIfAborted();
18
- const key = provider.clientKey;
19
29
  const existing = this.#clients.get(key);
20
30
  if (existing)
21
31
  return existing;
@@ -1,4 +1,9 @@
1
- /** A protocol client owns its initialization and idempotent cleanup, including partial initialization. */
1
+ /**
2
+ * Managed access lifecycle, implemented by protocol clients and resource-owning transports.
3
+ * @spec Initialization failure still requires disposal of every partially created resource.
4
+ * @spec Successful disposal means owned work has ended; borrowed dependencies belong to their manager.
5
+ * @rule A timeout waiting for cleanup is a cleanup failure, never proof that resources were released.
6
+ */
2
7
  export interface Client {
3
8
  initialize(): Promise<void>;
4
9
  dispose(): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compforge/harness-common",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "Execution-neutral client lifecycle and datasource contracts for harnesses",
5
5
  "type": "module",
6
6
  "scripts": {