@cortexkit/anthropic-auth-core 2.2.7 → 2.3.0
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/dist/index.d.ts +1 -0
- package/dist/index.js +2691 -894
- package/dist/internal-types/claustrum/consumer.d.ts +77 -2
- package/dist/internal-types/claustrum/custody.d.ts +36 -1
- package/dist/internal-types/claustrum/hub.d.ts +195 -0
- package/dist/internal-types/claustrum/index.d.ts +13 -3
- package/dist/internal-types/claustrum/quota-writer.d.ts +8 -1
- package/dist/internal-types/claustrum/roster.d.ts +49 -1
- package/dist/internal-types/fs/refresh-file-lock.d.ts +1 -1
- package/dist/internal-types/quota/commit-interval.d.ts +9 -0
- package/dist/internal-types/setup/register.d.ts +2 -0
- package/dist/internal-types/store/attribution.d.ts +5 -0
- package/dist/internal-types/store/mutate.d.ts +2 -0
- package/dist/internal-types/store/pool.d.ts +22 -0
- package/dist/internal-types/store/runtime.d.ts +2 -0
- package/dist/internal-types/store/settings.d.ts +1 -1
- package/dist/native-account-runtime.d.ts +1 -0
- package/dist/native-enrollment-authority.d.ts +2 -0
- package/dist/native-runtime-registry.d.ts +2 -2
- package/dist/native-vault-runtime.d.ts +2 -2
- package/dist/oauth-origin.d.ts +51 -0
- package/dist/relay.d.ts +6 -0
- package/package.json +2 -2
|
@@ -3,8 +3,9 @@ import type { QuotaObservation } from '../quota/index.js';
|
|
|
3
3
|
import type { RoutingRow } from '../routing/index.js';
|
|
4
4
|
import { type ClaustrumFamily, type ClaustrumScopedAttempt, type ClaustrumScopedClient, type IdentityParser, type KeptReceiptState, type VaultGrantReach } from './custody.js';
|
|
5
5
|
import { type ClaustrumLogger } from './errors.js';
|
|
6
|
+
import type { CustodyLease } from './hub.js';
|
|
6
7
|
import { type InsulaQuotaOptions, type InsulaQuotaResult } from './insula.js';
|
|
7
|
-
import { type AccountMapper, type QuotaReceipt, type ReorderVaultRosterResult, type VaultRosterFile } from './roster.js';
|
|
8
|
+
import { type AccountMapper, type ProjectionOptions, type QuotaReceipt, type ReorderVaultRosterResult, type VaultRosterFile } from './roster.js';
|
|
8
9
|
import { type WatchMode } from './watch.js';
|
|
9
10
|
export interface ClaustrumConsumerOptions<Q = QuotaObservation> {
|
|
10
11
|
/**
|
|
@@ -17,6 +18,14 @@ export interface ClaustrumConsumerOptions<Q = QuotaObservation> {
|
|
|
17
18
|
tokenPath: string;
|
|
18
19
|
family: ClaustrumFamily;
|
|
19
20
|
connect: () => Promise<ClaustrumScopedClient>;
|
|
21
|
+
/**
|
|
22
|
+
* How long one `connect()` attempt may take before this consumer treats the
|
|
23
|
+
* vault as unreachable (default 10 s). A connect that never settles would
|
|
24
|
+
* otherwise leave every later `refresh()` waiting on the same promise. After
|
|
25
|
+
* the limit the waiters get an unreachable error, the next `refresh()`
|
|
26
|
+
* connects again, and a client that arrives late is closed.
|
|
27
|
+
*/
|
|
28
|
+
connectTimeoutMs?: number;
|
|
20
29
|
/**
|
|
21
30
|
* Whether the plugin currently takes its accounts from the vault (custody
|
|
22
31
|
* mode) rather than from local logins. Checked before every discovery,
|
|
@@ -65,6 +74,72 @@ export interface ClaustrumWatchState {
|
|
|
65
74
|
readonly vault: WatchMode;
|
|
66
75
|
readonly insula?: WatchMode;
|
|
67
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* What a hub member asks of the `ClaustrumDiscoveryHub` that built it.
|
|
79
|
+
* Package-internal: the hub implements it, and `/claustrum` exports neither
|
|
80
|
+
* it nor `createHubMember`.
|
|
81
|
+
*/
|
|
82
|
+
export interface HubMemberPort {
|
|
83
|
+
readonly provider: string;
|
|
84
|
+
/** The member's `start()`: make sure the hub's own driver runs. */
|
|
85
|
+
start(): void;
|
|
86
|
+
/**
|
|
87
|
+
* One hub refresh, coalesced across members (one list, one fan-out).
|
|
88
|
+
* Undefined while vault mode is off, or when the connection it ran on was
|
|
89
|
+
* ended before its fan-out finished. `errors` holds each member's own
|
|
90
|
+
* commit error; a failed list rejects instead.
|
|
91
|
+
*/
|
|
92
|
+
refresh(): Promise<HubRefreshOutcome | undefined>;
|
|
93
|
+
/**
|
|
94
|
+
* The hub's authority read. The hub, not the member, decides what a false
|
|
95
|
+
* read means: it runs its inactive transition on the first one.
|
|
96
|
+
*/
|
|
97
|
+
readAuthority(): Promise<boolean>;
|
|
98
|
+
acquire(signal?: AbortSignal): Promise<CustodyLease>;
|
|
99
|
+
/** False once a lease was released or its connection ended. */
|
|
100
|
+
leaseLive(lease: CustodyLease): boolean;
|
|
101
|
+
/** The hub's grant reach, only while `view` is the view it was read with. */
|
|
102
|
+
grantReach(view: string | undefined): VaultGrantReach | undefined;
|
|
103
|
+
watchMode(): WatchMode;
|
|
104
|
+
keptReceiptState(): KeptReceiptState;
|
|
105
|
+
/** Apply the union of every member's roster in memory to kept receipts. */
|
|
106
|
+
retainUnion(): void;
|
|
107
|
+
forget(credentialId: string): void;
|
|
108
|
+
/** The member closed: the hub stops committing and pushing to it. */
|
|
109
|
+
detach(): void;
|
|
110
|
+
}
|
|
111
|
+
export interface HubRefreshOutcome {
|
|
112
|
+
readonly errors: ReadonlyMap<string, unknown>;
|
|
113
|
+
}
|
|
114
|
+
/** What the hub may do to one member's memory. Package-internal. */
|
|
115
|
+
export interface HubMemberHooks {
|
|
116
|
+
/**
|
|
117
|
+
* Set the roster in memory as a consumer's own refresh does (pending quota
|
|
118
|
+
* readings included) and notify `onRoster` when its view changed.
|
|
119
|
+
*/
|
|
120
|
+
install(roster: VaultRosterFile): void;
|
|
121
|
+
/** Vault mode went off: forget the roster. */
|
|
122
|
+
reset(): void;
|
|
123
|
+
roster(): VaultRosterFile | undefined;
|
|
124
|
+
projection(): ProjectionOptions;
|
|
125
|
+
onError(error: unknown): void;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* How long one connect attempt may take by default. It bounds a connect that
|
|
129
|
+
* never settles; the client's own handshake limit is not guaranteed to cover
|
|
130
|
+
* every stall, and callers waiting on discovery need an answer either way.
|
|
131
|
+
*/
|
|
132
|
+
export declare const DEFAULT_CONNECT_TIMEOUT_MS = 10000;
|
|
133
|
+
/**
|
|
134
|
+
* Build the consumer for one hub member. `options` holds only what the member
|
|
135
|
+
* uses: the hub's roster path for this member and the member's own fields.
|
|
136
|
+
* Hub-mode paths never read `tokenPath`, `family` or `connect`, which the hub
|
|
137
|
+
* owns. Package-internal: only `ClaustrumDiscoveryHub.member` calls it.
|
|
138
|
+
*/
|
|
139
|
+
export declare function createHubMember<Q>(port: HubMemberPort, options: ClaustrumConsumerOptions<Q>): {
|
|
140
|
+
consumer: ClaustrumConsumer<Q>;
|
|
141
|
+
hooks: HubMemberHooks;
|
|
142
|
+
};
|
|
68
143
|
export interface SendOptions {
|
|
69
144
|
/**
|
|
70
145
|
* What kind of request this is (for example `model`, `quota`, `profile`),
|
|
@@ -179,6 +254,6 @@ export declare class ClaustrumConsumer<Q = QuotaObservation> {
|
|
|
179
254
|
*/
|
|
180
255
|
recordAccountQuota(routeId: string, accountIdentity: string, observation: QuotaObservation): Promise<boolean>;
|
|
181
256
|
close(): void;
|
|
182
|
-
/** Close immediately;
|
|
257
|
+
/** Close immediately; background work gets 2 s and the quota writer its own 1 s. */
|
|
183
258
|
dispose(): Promise<void>;
|
|
184
259
|
}
|
|
@@ -22,10 +22,35 @@ export interface ClaustrumFamily {
|
|
|
22
22
|
category: string;
|
|
23
23
|
apiKeys?: boolean;
|
|
24
24
|
}
|
|
25
|
+
/** Non-secret classification facts, including rows decoded by older clients. */
|
|
26
|
+
export interface VaultRowFacts {
|
|
27
|
+
readonly credentialId: string;
|
|
28
|
+
readonly credentialType: string;
|
|
29
|
+
readonly authMethod?: string;
|
|
30
|
+
readonly refreshAdapter?: string;
|
|
31
|
+
readonly providerIds?: readonly string[];
|
|
32
|
+
readonly categories: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
/** A policy that partitions one category without requiring one OAuth adapter. */
|
|
35
|
+
export interface ClassifyingClaustrumFamily<Code extends string> {
|
|
36
|
+
category: string;
|
|
37
|
+
refusalCodes: readonly Code[];
|
|
38
|
+
classify(row: VaultRowFacts): {
|
|
39
|
+
kind: 'not-mine';
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'mine';
|
|
42
|
+
member: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'refused';
|
|
45
|
+
code: Code;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export type ClaustrumFamilyInput = ClaustrumFamily | ClassifyingClaustrumFamily<string>;
|
|
25
49
|
/** One vault credential this consumer may serve. Never carries bearer material. */
|
|
26
50
|
export interface VaultCredential {
|
|
27
51
|
readonly credentialId: string;
|
|
28
52
|
readonly credentialType: VaultCredentialType;
|
|
53
|
+
readonly member?: string;
|
|
29
54
|
/**
|
|
30
55
|
* The provider account the credential logs into, when the vault's adapter
|
|
31
56
|
* claims one. Absent means the adapter makes no claim, not a mismatch.
|
|
@@ -47,6 +72,7 @@ export type SkippedVaultReason = 'empty credential id' | 'duplicate credential i
|
|
|
47
72
|
*/
|
|
48
73
|
export interface SkippedVaultRecord {
|
|
49
74
|
readonly credentialId?: string;
|
|
75
|
+
readonly member?: string;
|
|
50
76
|
readonly reason: SkippedVaultReason;
|
|
51
77
|
}
|
|
52
78
|
/**
|
|
@@ -82,6 +108,13 @@ export interface VaultInventory {
|
|
|
82
108
|
readonly view: string;
|
|
83
109
|
readonly credentials: readonly VaultCredential[];
|
|
84
110
|
readonly skipped: readonly SkippedVaultRecord[];
|
|
111
|
+
/** Classifying families only: fixed refusal codes, never classifier errors. */
|
|
112
|
+
readonly refused?: readonly {
|
|
113
|
+
credentialId?: string;
|
|
114
|
+
code: string;
|
|
115
|
+
}[];
|
|
116
|
+
/** Classifying families only: rows outside this family's responsibility. */
|
|
117
|
+
readonly notMine?: number;
|
|
85
118
|
/**
|
|
86
119
|
* The consumer's grants, as the vault's list reply named them. Undefined means unknown
|
|
87
120
|
* (the vault or client predates the fields), never zero grants.
|
|
@@ -221,7 +254,7 @@ export declare class ClaustrumScopedCustody {
|
|
|
221
254
|
#private;
|
|
222
255
|
constructor(options: {
|
|
223
256
|
client: ClaustrumScopedClient;
|
|
224
|
-
family:
|
|
257
|
+
family: ClaustrumFamilyInput;
|
|
225
258
|
tokenPath?: string;
|
|
226
259
|
readToken?: () => Promise<EnrollmentTokenFile>;
|
|
227
260
|
parseIdentity?: IdentityParser;
|
|
@@ -296,4 +329,6 @@ export declare class ClaustrumScopedCustody {
|
|
|
296
329
|
*/
|
|
297
330
|
watchRoster(options: ClaustrumRosterWatchOptions): ClaustrumRosterWatch;
|
|
298
331
|
close(): void;
|
|
332
|
+
/** Stop immediately; allow token reads 2 s and share an owner's timeout warning. */
|
|
333
|
+
dispose(onTimeout?: (pendingOperations: number) => void): Promise<void>;
|
|
299
334
|
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { QuotaObservation } from '../quota/index.js';
|
|
2
|
+
import { type ClaustrumConsumer } from './consumer.js';
|
|
3
|
+
import { type ClassifyingClaustrumFamily, type ClaustrumScopedClient, ClaustrumScopedCustody, type IdentityParser, type KeptReceiptState, type VaultGrantReach } from './custody.js';
|
|
4
|
+
import { type ClaustrumLogger } from './errors.js';
|
|
5
|
+
import { type AccountMapper, type VaultRosterFile } from './roster.js';
|
|
6
|
+
import { type WatchMode } from './watch.js';
|
|
7
|
+
export interface ClaustrumDiscoveryHubOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The plugin's owner-only state directory. Member rosters live under
|
|
10
|
+
* `<stateDir>/rosters/<hostGeneration>/<fingerprint>/<provider>.json`.
|
|
11
|
+
*/
|
|
12
|
+
stateDir: string;
|
|
13
|
+
/**
|
|
14
|
+
* Which host generation this process runs (for example `opencode1`,
|
|
15
|
+
* `opencode2` or `pi`). Hosts that classify rows differently keep separate
|
|
16
|
+
* roster directories.
|
|
17
|
+
*/
|
|
18
|
+
hostGeneration: string;
|
|
19
|
+
/**
|
|
20
|
+
* Everything the plugin's classifier decides with, as plain JSON: the
|
|
21
|
+
* exact object it hands the classifier (its version, the supported-table
|
|
22
|
+
* entries, the reserved provider set and every host fact it reads). The
|
|
23
|
+
* hub hashes it, with the member set, `routePrefix` and `mapAccount`, into
|
|
24
|
+
* the roster key, so processes whose classifiers or projections could
|
|
25
|
+
* disagree never share a roster file. Configuration that `mapAccount`
|
|
26
|
+
* reads, beyond its own source text, belongs here too.
|
|
27
|
+
*/
|
|
28
|
+
classifierInput: unknown;
|
|
29
|
+
/**
|
|
30
|
+
* Every provider the plugin serves on this host, fixed for the hub's life.
|
|
31
|
+
* Each is the `member` a classified row names and a roster file name, so
|
|
32
|
+
* it is lowercase ASCII: letters, digits, `.`, `_` and `-`.
|
|
33
|
+
*/
|
|
34
|
+
members: readonly string[];
|
|
35
|
+
/** Prefix of every member's vault route ids; part of the roster key. */
|
|
36
|
+
routePrefix?: string;
|
|
37
|
+
/**
|
|
38
|
+
* How every member presents a vault credential (the credential names its
|
|
39
|
+
* member). Part of the roster key by its source text.
|
|
40
|
+
*/
|
|
41
|
+
mapAccount?: AccountMapper;
|
|
42
|
+
/** This host's enrollment token, written by setup. */
|
|
43
|
+
tokenPath: string;
|
|
44
|
+
/**
|
|
45
|
+
* The plugin's classifying family. A legacy `ClaustrumFamily` names no
|
|
46
|
+
* member for any row and is refused.
|
|
47
|
+
*/
|
|
48
|
+
family: ClassifyingClaustrumFamily<string>;
|
|
49
|
+
connect: () => Promise<ClaustrumScopedClient>;
|
|
50
|
+
/**
|
|
51
|
+
* How long one `connect()` attempt may take before the hub treats the vault
|
|
52
|
+
* as unreachable (default 10 s, as `ClaustrumConsumerOptions`). The hub's
|
|
53
|
+
* connect is shared by every member waiting for a lease, so an attempt that
|
|
54
|
+
* never settles would hold every one of them; after the limit they get an
|
|
55
|
+
* unreachable error and the next acquire connects again.
|
|
56
|
+
*/
|
|
57
|
+
connectTimeoutMs?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Whether the plugin takes its accounts from the vault. Read from local
|
|
60
|
+
* state only, never from the vault: on every hub tick, and when a member
|
|
61
|
+
* refreshes or authorizes. The first false read revokes every lease,
|
|
62
|
+
* closes the connection and clears every member.
|
|
63
|
+
*/
|
|
64
|
+
isCustodyActive?: () => boolean | Promise<boolean>;
|
|
65
|
+
parseIdentity?: IdentityParser;
|
|
66
|
+
/** As `ClaustrumConsumerOptions.requireAssertion`, for every member. */
|
|
67
|
+
requireAssertion?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* How often the hub ticks (default 5 s). A tick reads authority, installs
|
|
70
|
+
* member roster files another writer changed under the same view, and
|
|
71
|
+
* lists when a list is due: on every tick while no vault watch is open,
|
|
72
|
+
* when a pending member's retry is due (a member the last list did not
|
|
73
|
+
* commit, retried with a backoff), otherwise every five minutes as a
|
|
74
|
+
* safety net.
|
|
75
|
+
*/
|
|
76
|
+
pollIntervalMs?: number;
|
|
77
|
+
setTimeoutImpl?: typeof setTimeout;
|
|
78
|
+
clearTimeoutImpl?: typeof clearTimeout;
|
|
79
|
+
now?: () => number;
|
|
80
|
+
logger?: ClaustrumLogger;
|
|
81
|
+
/**
|
|
82
|
+
* Errors of the hub's own tick, list and watch. A failed list and a vault
|
|
83
|
+
* refusal of the watch also reach every member's `onError`.
|
|
84
|
+
*/
|
|
85
|
+
onError?: (error: unknown) => void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* What one hub member takes: only what is per provider. The hub owns the
|
|
89
|
+
* roster path, the enrollment token, the family, the connection, the
|
|
90
|
+
* authority check, the poll timer and the projection inputs that are part of
|
|
91
|
+
* the roster key (`routePrefix`, `mapAccount`), so none of them can be given
|
|
92
|
+
* here. The type parameter matches the consumer `member` returns; members
|
|
93
|
+
* have no insula source.
|
|
94
|
+
*/
|
|
95
|
+
export interface ClaustrumHubMemberOptions<_Q = QuotaObservation> {
|
|
96
|
+
/**
|
|
97
|
+
* Ids of the plugin's local pool rows; no vault route id may equal one.
|
|
98
|
+
* Read on every projection and install, so it may change at any time.
|
|
99
|
+
*/
|
|
100
|
+
reservedRouteIds?: () => Iterable<string>;
|
|
101
|
+
/** As `ClaustrumConsumerOptions.onRoster`: once per change of view. */
|
|
102
|
+
onRoster?: (roster: VaultRosterFile) => void;
|
|
103
|
+
/** This member's own failures, such as a roster commit that failed. */
|
|
104
|
+
onError?: (error: unknown) => void;
|
|
105
|
+
logger?: ClaustrumLogger;
|
|
106
|
+
}
|
|
107
|
+
/** What a lease may do with the shared custody. */
|
|
108
|
+
export type ClaustrumLeasedCustody = Pick<ClaustrumScopedCustody, 'authorize' | 'reportFailure' | 'forget' | 'keptReceiptState'>;
|
|
109
|
+
/**
|
|
110
|
+
* One acquisition of the hub's shared custody. `custody` throws `closed`
|
|
111
|
+
* after `release()`, and once the connection it belongs to ended for any
|
|
112
|
+
* reason, vault mode going off included. `release()` is idempotent.
|
|
113
|
+
*/
|
|
114
|
+
export interface CustodyLease {
|
|
115
|
+
readonly custody: ClaustrumLeasedCustody;
|
|
116
|
+
/** The connection this lease belongs to; each new connection counts up. */
|
|
117
|
+
readonly generation: number;
|
|
118
|
+
release(): void;
|
|
119
|
+
}
|
|
120
|
+
/** The rows the hub's last complete discovery refused or left to others. */
|
|
121
|
+
export interface ClaustrumHubRefusals {
|
|
122
|
+
readonly view: string;
|
|
123
|
+
readonly refused: readonly {
|
|
124
|
+
credentialId?: string;
|
|
125
|
+
code: string;
|
|
126
|
+
}[];
|
|
127
|
+
readonly notMine: number;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* One discovery hub per host process: the only vault connection and the only
|
|
131
|
+
* `ClaustrumScopedCustody`, one vault watch and one list per refresh, fanned
|
|
132
|
+
* out to one roster per provider. Members (`member()`) are ordinary
|
|
133
|
+
* `ClaustrumConsumer`s that never connect, list or watch themselves; each
|
|
134
|
+
* holds a custody lease. The connection stays open while vault mode is on,
|
|
135
|
+
* because the hub's own discovery holds a lease of its own, and closes when
|
|
136
|
+
* the last lease of a connection is released, when vault mode goes off, or
|
|
137
|
+
* at `close()`.
|
|
138
|
+
*/
|
|
139
|
+
export declare class ClaustrumDiscoveryHub {
|
|
140
|
+
#private;
|
|
141
|
+
constructor(options: ClaustrumDiscoveryHubOptions);
|
|
142
|
+
/** The roster file member `provider` reads and the hub commits. */
|
|
143
|
+
rosterPath(provider: string): string;
|
|
144
|
+
/**
|
|
145
|
+
* Build the consumer for `provider`, once. It is an ordinary
|
|
146
|
+
* `ClaustrumConsumer` whose roster path is `rosterPath(provider)`; it
|
|
147
|
+
* connects, lists and watches only through this hub.
|
|
148
|
+
*/
|
|
149
|
+
member<Q = QuotaObservation>(provider: string, options: ClaustrumHubMemberOptions<Q>): ClaustrumConsumer<Q>;
|
|
150
|
+
/**
|
|
151
|
+
* Take a lease on the current connection, connecting first when there is
|
|
152
|
+
* none. The acquirer's count is taken before anything is awaited, so a
|
|
153
|
+
* release elsewhere meanwhile cannot end the connection under it. An abort
|
|
154
|
+
* or a failed connect gives that count back; an acquirer whose connection
|
|
155
|
+
* ended while it waited tries once more on the current one. Rejects with
|
|
156
|
+
* `not-active` while vault mode is off.
|
|
157
|
+
*/
|
|
158
|
+
acquire(signal?: AbortSignal): Promise<CustodyLease>;
|
|
159
|
+
/** The current connection and its lease count, for status and tests. */
|
|
160
|
+
leaseState(): {
|
|
161
|
+
readonly generation?: number;
|
|
162
|
+
readonly count: number;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Start the hub's tick, which runs until `close()`. While vault mode is
|
|
166
|
+
* off a tick only reads authority and makes no vault request.
|
|
167
|
+
*/
|
|
168
|
+
start(): void;
|
|
169
|
+
/**
|
|
170
|
+
* List once and commit every member, as a tick does. Resolves once every
|
|
171
|
+
* member's memory holds its new roster. Rejects when the list fails; a
|
|
172
|
+
* member's own commit error goes to that member's `onError`.
|
|
173
|
+
*/
|
|
174
|
+
refresh(): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Rows the last discovery every member committed refused, with their fixed
|
|
177
|
+
* codes, and how many rows it left to other plugins. Undefined while
|
|
178
|
+
* unknown: before a complete discovery, and while vault mode is off.
|
|
179
|
+
*/
|
|
180
|
+
refusals(): ClaustrumHubRefusals | undefined;
|
|
181
|
+
/** The grant reach of the same discovery as `refusals()`. */
|
|
182
|
+
grantReach(): VaultGrantReach | undefined;
|
|
183
|
+
/** How the hub learns about changes; `polling` until a watch is open. */
|
|
184
|
+
watchState(): WatchMode;
|
|
185
|
+
/** The shared custody's kept receipts, host-wide. */
|
|
186
|
+
keptReceiptState(): KeptReceiptState;
|
|
187
|
+
/**
|
|
188
|
+
* Stop the tick and the watch and close the connection. Members are not
|
|
189
|
+
* closed; they fail `closed` from then on. Use `dispose()` to also allow
|
|
190
|
+
* in-flight discovery up to two seconds to release its file handles.
|
|
191
|
+
*/
|
|
192
|
+
close(): void;
|
|
193
|
+
/** Close immediately, then join background work for at most two seconds. */
|
|
194
|
+
dispose(): Promise<void>;
|
|
195
|
+
}
|
|
@@ -2,21 +2,31 @@ import { type ClaustrumClientOptions } from '@cortexkit/claustrum-client';
|
|
|
2
2
|
import type { ClaustrumScopedClient } from './custody.js';
|
|
3
3
|
export { ClaustrumCredentialError, type ClaustrumReporterSource, type EnrollmentTokenFile, } from '@cortexkit/claustrum-client';
|
|
4
4
|
export { ClaustrumUnreachableError, classifyVaultFailure, VAULT_FAILURE_CLASSES, type VaultFailureClass, } from './availability.js';
|
|
5
|
-
export { ClaustrumConsumer, type ClaustrumConsumerOptions, type ClaustrumWatchState, type SendOptions, } from './consumer.js';
|
|
6
|
-
export { type AccountIdentitySource, type ClaustrumFamily, type ClaustrumRosterWatch, type ClaustrumRosterWatchOptions, type ClaustrumScopedAttempt, type ClaustrumScopedClient, ClaustrumScopedCustody, type ClaustrumScopedIdentity, decideScopedRetryAfter401, type IdentityParser, isScopedCredentialRotation, KEPT_RECEIPT_MARGIN_MS, type KeptReceiptState, type ScopedRetryReason, SERVING_MARGIN_MS, type SkippedVaultReason, type SkippedVaultRecord, type VaultCredential, type VaultCredentialType, type VaultGrantReach, type VaultGrantTuple, type VaultInventory, } from './custody.js';
|
|
5
|
+
export { ClaustrumConsumer, type ClaustrumConsumerOptions, type ClaustrumWatchState, DEFAULT_CONNECT_TIMEOUT_MS, type SendOptions, } from './consumer.js';
|
|
6
|
+
export { type AccountIdentitySource, type ClassifyingClaustrumFamily, type ClaustrumFamily, type ClaustrumFamilyInput, type ClaustrumRosterWatch, type ClaustrumRosterWatchOptions, type ClaustrumScopedAttempt, type ClaustrumScopedClient, ClaustrumScopedCustody, type ClaustrumScopedIdentity, decideScopedRetryAfter401, type IdentityParser, isScopedCredentialRotation, KEPT_RECEIPT_MARGIN_MS, type KeptReceiptState, type ScopedRetryReason, SERVING_MARGIN_MS, type SkippedVaultReason, type SkippedVaultRecord, type VaultCredential, type VaultCredentialType, type VaultGrantReach, type VaultGrantTuple, type VaultInventory, type VaultRowFacts, } from './custody.js';
|
|
7
7
|
export { type ClaustrumEnrollmentClient, type ClaustrumEnrollmentConnection, type ClaustrumEnrollmentDisconnectResult, ClaustrumEnrollmentManager, type ClaustrumEnrollmentPaths, type ClaustrumEnrollmentResetResult, type ClaustrumEnrollmentStatus, classifyEnrollmentError, connectClaustrumEnrollmentClient, disconnectClaustrumEnrollment, type EnrollmentDisposition, enrollmentAuthority, enrollmentName, getClaustrumEnrollmentPaths, hostEnrollmentPaths, RETRYABLE_ENROLLMENT_CODES, readClaustrumEnrollmentStatus, readClaustrumEnrollmentToken, resetClaustrumEnrollmentState, TERMINAL_ENROLLMENT_CODES, } from './enrollment.js';
|
|
8
8
|
export { ClaustrumConsumerError, type ClaustrumConsumerFailureKind, type ClaustrumLogger, } from './errors.js';
|
|
9
9
|
export { assertHostSlotMatchesMode, assertNotCustodyPlaceholder, CUSTODY_PLACEHOLDER_PREFIX, classifyHostSlot, custodyPlaceholder, custodyPlaceholderKey, type HostSlotContent, isCustodyPlaceholder, isCustodyPlaceholderValue, } from './host-slot.js';
|
|
10
|
+
export { ClaustrumDiscoveryHub, type ClaustrumDiscoveryHubOptions, type ClaustrumHubMemberOptions, type ClaustrumHubRefusals, type ClaustrumLeasedCustody, type CustodyLease, } from './hub.js';
|
|
10
11
|
export { acquireInsulaQuotaSource, type InsulaQuotaContext, type InsulaQuotaLookup, type InsulaQuotaMiss, type InsulaQuotaOptions, type InsulaQuotaReading, type InsulaQuotaResult, type InsulaQuotaSource, type InsulaUsageEntry, type InsulaUsageTransport, type InsulaUsageWatch, type InsulaUsageWindow, type InsulaWatchOptions, } from './insula.js';
|
|
11
12
|
export { acceptAccount, type DeclinedAccount, declineAccount, isDeclined, } from './interlock.js';
|
|
12
13
|
export { drainVaultQuota } from './quota-writer.js';
|
|
13
|
-
export { type AccountMapper, acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, type MutateVaultRosterOptions, mutateVaultRoster, type ProjectionOptions, projectVaultRoster, type QuotaReceipt, type ReorderVaultRosterOptions, type ReorderVaultRosterResult, readVaultRoster, recordVaultAccountQuota, recordVaultQuota, refreshVaultRoster, reorderVaultRoster, resolveVaultPrimary, type VaultPrimary, type VaultPrimaryBinding, type VaultPrimaryUnavailableReason, type VaultRosterFile, type VaultRosterLockContext, type VaultRosterRow, vaultRoutingRows, } from './roster.js';
|
|
14
|
+
export { type AccountMapper, acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, type MutateVaultRosterOptions, mutateVaultRoster, type ProjectionOptions, projectVaultRoster, type QuotaReceipt, type ReorderVaultRosterOptions, type ReorderVaultRosterResult, readVaultRoster, recordVaultAccountQuota, recordVaultQuota, refreshVaultRoster, reorderVaultRoster, resolveVaultPrimary, type VaultPrimary, type VaultPrimaryBinding, type VaultPrimaryUnavailableReason, type VaultRosterFile, type VaultRosterLockContext, type VaultRosterRow, type VaultRosterSeed, vaultRosterSeed, vaultRoutingRows, } from './roster.js';
|
|
14
15
|
export { type ChangeNotice, ChangeNoticeReader, RESUBSCRIBE_BACKOFF_MS, SAFETY_POLL_MS, ScopedRosterWatch, type ScopedRosterWatchOptions, type ScopedWatchEnd, type ScopedWatchHandle, type ScopedWatchNoticeShape, type ScopedWatchSource, WATCH_RETRY_MS, type WatchMode, } from './watch.js';
|
|
16
|
+
/** How long `connectClaustrumScopedClient` waits by default. */
|
|
17
|
+
export declare const SCOPED_CONNECT_TIMEOUT_MS = 10000;
|
|
15
18
|
/**
|
|
16
19
|
* Connect the client that lists and fetches this consumer's vault credentials
|
|
17
20
|
* on the request path. `connectionFile` is required: this library
|
|
18
21
|
* reads no environment, so the plugin resolves the vault's connection file.
|
|
22
|
+
*
|
|
23
|
+
* The wait is bounded by `connectTimeoutMs` (default 10 s) so a connect that
|
|
24
|
+
* never settles cannot leave a consumer with a pending connection forever; the
|
|
25
|
+
* caller then gets an unreachable error and may try again. A socket handshake
|
|
26
|
+
* has its own limit, but local reads before it (the connection file) do not,
|
|
27
|
+
* and a client that arrives after this deadline is closed, not returned.
|
|
19
28
|
*/
|
|
20
29
|
export declare function connectClaustrumScopedClient(options: ClaustrumClientOptions & {
|
|
21
30
|
connectionFile: string;
|
|
31
|
+
connectTimeoutMs?: number;
|
|
22
32
|
}): Promise<ClaustrumScopedClient>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type QuotaCommitTimer } from '../quota/commit-interval.js';
|
|
1
2
|
import { type QuotaObservation } from '../quota/index.js';
|
|
2
3
|
import { type QuotaReceipt, type VaultRosterFile } from './roster.js';
|
|
3
4
|
export type VaultQuotaPublication = {
|
|
@@ -8,11 +9,17 @@ export type VaultQuotaPublication = {
|
|
|
8
9
|
};
|
|
9
10
|
type Listener = (publication: VaultQuotaPublication) => void;
|
|
10
11
|
/** Retain the shared writer; the last consumer's close drains it. */
|
|
11
|
-
export declare function retainVaultQuotaWriter(path: string, listener: Listener): () => Promise<void>;
|
|
12
|
+
export declare function retainVaultQuotaWriter(path: string, listener: Listener, clock?: QuotaCommitTimer): () => Promise<void>;
|
|
12
13
|
/** Enqueue without filesystem work; each quota field retains its own receipt fence. */
|
|
13
14
|
export declare function enqueueVaultQuota(path: string, publication: VaultQuotaPublication): Promise<boolean>;
|
|
14
15
|
/** Overlay uncommitted observations when a consumer reloads the durable roster. */
|
|
15
16
|
export declare function pendingVaultQuota(path: string, roster: VaultRosterFile | undefined): VaultRosterFile | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Whether this process holds quota readings for `path` that no commit of the
|
|
19
|
+
* durable roster has written yet, so a reader of the file alone is not seeing
|
|
20
|
+
* everything this process would publish.
|
|
21
|
+
*/
|
|
22
|
+
export declare function hasPendingVaultQuota(path: string): boolean;
|
|
16
23
|
/** Wait at most timeoutMs for detached publication; shutdown loss is acceptable. */
|
|
17
24
|
export declare function drainVaultQuota(path: string, timeoutMs?: number): Promise<void>;
|
|
18
25
|
export {};
|
|
@@ -62,7 +62,25 @@ export interface ProjectionOptions {
|
|
|
62
62
|
routePrefix?: string;
|
|
63
63
|
mapAccount?: AccountMapper;
|
|
64
64
|
now?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Preferences carried over from another roster file, used only when there
|
|
67
|
+
* is no previous roster: its declines become this roster's declines, and
|
|
68
|
+
* its account order sorts the rows this inventory produces. No row of the
|
|
69
|
+
* seed is ever projected, so a seed cannot make an account routable.
|
|
70
|
+
*/
|
|
71
|
+
seed?: VaultRosterSeed;
|
|
72
|
+
}
|
|
73
|
+
/** The preferences one roster file can pass to a first projection elsewhere. */
|
|
74
|
+
export interface VaultRosterSeed {
|
|
75
|
+
readonly declined: readonly DeclinedAccount[];
|
|
76
|
+
/** Accounts in the seed roster's order, matched by account, then by id. */
|
|
77
|
+
readonly order: readonly {
|
|
78
|
+
readonly credentialId: string;
|
|
79
|
+
readonly accountIdentity?: string;
|
|
80
|
+
}[];
|
|
65
81
|
}
|
|
82
|
+
/** Declines and account order of `roster`, and nothing else of it. */
|
|
83
|
+
export declare function vaultRosterSeed(roster: VaultRosterFile): VaultRosterSeed;
|
|
66
84
|
export declare const DEFAULT_ROUTE_PREFIX = "vault:";
|
|
67
85
|
/**
|
|
68
86
|
* Project the vault's list onto the previous roster. Pure: callers serialize
|
|
@@ -87,6 +105,12 @@ export declare function projectVaultRoster(previous: VaultRosterFile | undefined
|
|
|
87
105
|
* reaches admission.
|
|
88
106
|
*/
|
|
89
107
|
export declare function vaultRoutingRows(roster: VaultRosterFile | undefined): RoutingRow[];
|
|
108
|
+
/**
|
|
109
|
+
* `roster` as `readVaultRoster` decodes it from the file that holds it, so a
|
|
110
|
+
* committed roster and a later read of its file compare equal. Package
|
|
111
|
+
* internal: not exported from `/claustrum`.
|
|
112
|
+
*/
|
|
113
|
+
export declare function decodedVaultRoster(roster: VaultRosterFile): VaultRosterFile;
|
|
90
114
|
export declare function readVaultRoster(path: string): Promise<VaultRosterFile | undefined>;
|
|
91
115
|
/** The ownership assertion available to a roster mutation callback. */
|
|
92
116
|
export interface VaultRosterLockContext {
|
|
@@ -190,6 +214,16 @@ export declare function applyVaultQuota(current: VaultRosterFile | undefined, in
|
|
|
190
214
|
kept: boolean;
|
|
191
215
|
};
|
|
192
216
|
export declare function forgetPendingVaultDiscovery(path: string): void;
|
|
217
|
+
/**
|
|
218
|
+
* Whether `error` from a roster commit at `path` means another writer had the
|
|
219
|
+
* roster at that moment, not that the commit itself failed: the discovery
|
|
220
|
+
* lease was busy before any roster existed, the write lock stayed busy, or a
|
|
221
|
+
* lock this commit held was lost. On Windows the same lock steps can reject
|
|
222
|
+
* with a PrivateFileError instead (a lock file that could not be read or
|
|
223
|
+
* replaced while another process held it), so a PrivateFileError naming one
|
|
224
|
+
* of this roster's lock files counts the same on every OS.
|
|
225
|
+
*/
|
|
226
|
+
export declare function isVaultRosterLockRefusal(path: string, error: unknown): boolean;
|
|
193
227
|
/**
|
|
194
228
|
* Discover and commit the roster. The lease covers the list call and the
|
|
195
229
|
* commit, not just the write: an opaque view cannot tell a delayed old reply
|
|
@@ -197,7 +231,8 @@ export declare function forgetPendingVaultDiscovery(path: string): void;
|
|
|
197
231
|
* failed list, or custody switching off mid-run, never writes anything; a
|
|
198
232
|
* peer holding the lease means its last committed roster is served instead.
|
|
199
233
|
* A write-lock timeout keeps the discovered inventory for the next poll,
|
|
200
|
-
* unless a peer has superseded its base view in the meantime.
|
|
234
|
+
* unless a peer has superseded its base view in the meantime. A list that
|
|
235
|
+
* would write the file the roster already holds takes no write lock at all.
|
|
201
236
|
*/
|
|
202
237
|
export declare function refreshVaultRoster(options: {
|
|
203
238
|
path: string;
|
|
@@ -206,6 +241,19 @@ export declare function refreshVaultRoster(options: {
|
|
|
206
241
|
signal?: AbortSignal;
|
|
207
242
|
projection?: ProjectionOptions | (() => ProjectionOptions);
|
|
208
243
|
onInventory?: (inventory: VaultInventory) => void;
|
|
244
|
+
/**
|
|
245
|
+
* For a caller that listed before taking this path's discovery lease (the
|
|
246
|
+
* discovery hub lists once for several rosters): the view this roster file
|
|
247
|
+
* held before that list. `custody.discover` then returns that list. It is
|
|
248
|
+
* held to the rule a kept discovery is held to below: it is projected only
|
|
249
|
+
* while the file still holds this view or the list's own view. Otherwise
|
|
250
|
+
* another process committed since the list, and the file is returned
|
|
251
|
+
* unchanged. No discovery is kept for a later call, because such a caller
|
|
252
|
+
* lists again.
|
|
253
|
+
*/
|
|
254
|
+
listedOver?: {
|
|
255
|
+
readonly view: string | undefined;
|
|
256
|
+
};
|
|
209
257
|
}): Promise<VaultRosterFile | undefined>;
|
|
210
258
|
/**
|
|
211
259
|
* A host-owned main account as last verified from the vault: the plugin's
|
|
@@ -28,7 +28,7 @@ type RefreshFileLockOptions = {
|
|
|
28
28
|
onContended?: () => void;
|
|
29
29
|
/** Synchronous, never awaited; throws and returned promise/thenable rejections are isolated. */
|
|
30
30
|
onRenewalTimer?: (event: 'scheduled' | 'cancelled') => void;
|
|
31
|
-
onStep?: (step: 'stale-marker-stat' | 'stale-marker-claimed' | 'stale-lock-observed' | 'lock-read-ready' | 'lock-missing' | 'stale-lock-confirmed' | 'stale-lock-removed' | 'stale-lock-recreated' | 'eviction-marker-acquired' | 'renewal-owner-confirmed' | 'renewal-marker-unavailable' | 'renewal-write-fenced' | 'renewal-write-ready' | 'renewal-write-finished' | 'relinquish-read' | 'renewal-finished' | 'release-owner-confirmed') => void | Promise<void>;
|
|
31
|
+
onStep?: (step: 'stale-marker-stat' | 'stale-marker-claimed' | 'stale-lock-observed' | 'lease-contention-read-ready' | 'lock-read-ready' | 'lock-missing' | 'stale-lock-confirmed' | 'stale-lock-removed' | 'stale-lock-recreated' | 'eviction-marker-acquired' | 'renewal-owner-confirmed' | 'renewal-marker-unavailable' | 'renewal-write-fenced' | 'renewal-write-ready' | 'renewal-write-finished' | 'relinquish-read' | 'renewal-finished' | 'release-owner-confirmed') => void | Promise<void>;
|
|
32
32
|
};
|
|
33
33
|
/** Filesystem leases share wall time across all callers and processes. */
|
|
34
34
|
export declare function acquireRefreshFileLock(options: RefreshFileLockOptions): Promise<RefreshFileLock | null>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const QUOTA_COMMIT_INTERVAL_MS = 30000;
|
|
2
|
+
export interface QuotaCommitTimer {
|
|
3
|
+
now(): number;
|
|
4
|
+
schedule(delayMs: number, run: () => Promise<void>): {
|
|
5
|
+
cancel(): void;
|
|
6
|
+
unref?(): void;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare const quotaCommitTimer: QuotaCommitTimer;
|
|
@@ -3,6 +3,8 @@ export interface PlannedWrite {
|
|
|
3
3
|
path: string;
|
|
4
4
|
content: string;
|
|
5
5
|
changed: boolean;
|
|
6
|
+
existingLocalEntries?: string[];
|
|
7
|
+
existingNpmEntries?: string[];
|
|
6
8
|
}
|
|
7
9
|
/** Edit only array entries so unrelated JSONC text, including comments, survives. */
|
|
8
10
|
export declare function updatePluginConfig(text: string, key: 'plugin' | 'plugins', pkg: string, version: string): string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type StoreContext } from './mutate.js';
|
|
1
2
|
import { type StoreRuntime } from './runtime.js';
|
|
3
|
+
import { type PoolRow } from './schema.js';
|
|
2
4
|
/**
|
|
3
5
|
* What a pull or refresh captured about its row (named by id alongside) when
|
|
4
6
|
* it was issued. A result applies only while the row with that id still has
|
|
@@ -20,6 +22,9 @@ export interface Attribution {
|
|
|
20
22
|
credentialEpoch: number;
|
|
21
23
|
identity?: string;
|
|
22
24
|
}
|
|
25
|
+
export declare function assertQuotaEpoch(id: string, attribution: Attribution): void;
|
|
26
|
+
export declare function assertQuotaRow(id: string, attribution: Attribution, row: PoolRow | undefined): asserts row is PoolRow;
|
|
27
|
+
export declare function mergedQuota(ctx: StoreContext, id: string, stored: unknown, observation: unknown): unknown;
|
|
23
28
|
/**
|
|
24
29
|
* Merges a quota observation into a row's stored map under the store locks,
|
|
25
30
|
* after attribution passes. Needs no row lock, so it is permitted from
|
|
@@ -52,6 +52,8 @@ export type ReadResult = ({
|
|
|
52
52
|
kind?: 'snapshot-contended';
|
|
53
53
|
retryable?: true;
|
|
54
54
|
};
|
|
55
|
+
/** Settings need only the config classification, not a joined roster snapshot. */
|
|
56
|
+
export declare function readPoolConfig(path: string): Promise<import("./schema.js").ConfigClassification>;
|
|
55
57
|
/**
|
|
56
58
|
* Validate config/state/config bytes without locks. Roster replacement writes
|
|
57
59
|
* config before deleting old state credentials. Re-read a changed config so an
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { QuotaCommitTimer } from '../quota/commit-interval.js';
|
|
1
2
|
import { type Attribution } from './attribution.js';
|
|
2
3
|
import type { PoolOperationError } from './errors.js';
|
|
3
4
|
import type { PoolLogger } from './hooks.js';
|
|
@@ -16,6 +17,23 @@ export interface OpenPoolStoreOptions {
|
|
|
16
17
|
configPath: string;
|
|
17
18
|
statePath: string;
|
|
18
19
|
quota: QuotaCodec;
|
|
20
|
+
/**
|
|
21
|
+
* Opt in to detached, coalesced quota publication, with any `quota` codec.
|
|
22
|
+
* Each accepted observation is queued whole for its row and binding, and
|
|
23
|
+
* the queue is applied in arrival order through `quota.merge` under the
|
|
24
|
+
* store locks, so the codec's own merge decides which fields a newer or
|
|
25
|
+
* older reading replaces. Accepted readings appear in read/load
|
|
26
|
+
* immediately, merged the same way; the returned promise still rejects
|
|
27
|
+
* current-row refusals before queueing. Await dispose or close at shutdown
|
|
28
|
+
* to attempt a bounded drain; readings still pending at its timeout are
|
|
29
|
+
* discarded. Normal quota commits are at least 30 seconds apart; a full
|
|
30
|
+
* queue commits early so response handling never waits for that interval.
|
|
31
|
+
*/
|
|
32
|
+
coalesceQuota?: boolean;
|
|
33
|
+
/** Bounded quota drain on close/dispose, in milliseconds; defaults to 1,000. */
|
|
34
|
+
quotaDrainTimeoutMs?: number;
|
|
35
|
+
/** Monotonic clock and scheduling seam for detached quota commits. */
|
|
36
|
+
quotaCommitTimer?: QuotaCommitTimer;
|
|
19
37
|
/**
|
|
20
38
|
* The codec of the provider state kept beside each row's credential (see
|
|
21
39
|
* `ProviderStateCodec`). Without it no row shows a provider state, and
|
|
@@ -189,6 +207,10 @@ export interface PoolStore {
|
|
|
189
207
|
}>;
|
|
190
208
|
refresh(id: string, provider: ProviderRefresh, options?: RefreshOptions): Promise<RefreshOutcome>;
|
|
191
209
|
recordQuota(id: string, attribution: Attribution, observation: unknown): Promise<void>;
|
|
210
|
+
/** Drain opted-in quota publication; subsequent coalesced readings refuse. Idempotent. */
|
|
211
|
+
close(): Promise<void>;
|
|
212
|
+
/** Same bounded quota drain as close(). Does not wait for provider pull hooks. */
|
|
213
|
+
dispose(): Promise<void>;
|
|
192
214
|
/** Fires a pull for a row admission refused for want of a reading. */
|
|
193
215
|
requestReading(id: string): void;
|
|
194
216
|
/** Resolves once every pull fired so far has settled. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Attribution } from './attribution.js';
|
|
1
2
|
import { type PoolOperation, PoolOperationError } from './errors.js';
|
|
2
3
|
import { type ReadResult, type StoreContext } from './mutate.js';
|
|
3
4
|
import type { PoolLockOptions, PoolLockSpec } from './refresh-lock.js';
|
|
@@ -10,6 +11,7 @@ export interface StoreRuntime {
|
|
|
10
11
|
providerLock: PoolLockSpec;
|
|
11
12
|
rowLockOptions: Partial<PoolLockOptions>;
|
|
12
13
|
firePull(id: string, reason: PullReason): void;
|
|
14
|
+
publishQuota?: (id: string, attribution: Attribution, observation: unknown) => Promise<void>;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* The row lock's (name, path): keyed by the row's recorded wire identity when
|
|
@@ -50,7 +50,7 @@ export type UpdateSettingsResult = {
|
|
|
50
50
|
/** `unchanged` when the mutator left the settings as they were; nothing was written. */
|
|
51
51
|
outcome: 'updated' | 'unchanged';
|
|
52
52
|
};
|
|
53
|
-
/** Reads the settings without taking a lock or writing anything. */
|
|
53
|
+
/** Reads only the config's settings, without taking a lock or writing anything. */
|
|
54
54
|
export declare function readPoolSettings(rt: StoreRuntime): Promise<SettingsRead>;
|
|
55
55
|
/**
|
|
56
56
|
* One locked read-modify-write of the plugin's settings in the config file
|