llm-relay 0.35.0 → 0.37.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/LICENSE +21 -0
- package/README.md +12 -0
- package/THIRD_PARTY_NOTICES.md +72 -0
- package/config.example.json +8 -2
- package/dist/accounting-store-io.d.ts +124 -0
- package/dist/accounting-store-io.js +1105 -0
- package/dist/accounting-store-io.js.map +1 -0
- package/dist/accounting-store-schema.d.ts +299 -0
- package/dist/accounting-store-schema.js +1021 -0
- package/dist/accounting-store-schema.js.map +1 -0
- package/dist/accounting-store.d.ts +73 -0
- package/dist/accounting-store.js +1523 -0
- package/dist/accounting-store.js.map +1 -0
- package/dist/accounting.d.ts +177 -0
- package/dist/accounting.js +429 -0
- package/dist/accounting.js.map +1 -0
- package/dist/anthropic.d.ts +2 -2
- package/dist/anthropic.js +22 -5
- package/dist/anthropic.js.map +1 -1
- package/dist/authEnv.d.ts +19 -0
- package/dist/authEnv.js +58 -25
- package/dist/authEnv.js.map +1 -1
- package/dist/backend.d.ts +32 -3
- package/dist/backend.js +324 -41
- package/dist/backend.js.map +1 -1
- package/dist/candidates.d.ts +28 -3
- package/dist/candidates.js +86 -13
- package/dist/candidates.js.map +1 -1
- package/dist/catalog.d.ts +1 -0
- package/dist/catalog.js +36 -12
- package/dist/catalog.js.map +1 -1
- package/dist/circuit-breaker.d.ts +49 -129
- package/dist/circuit-breaker.js +166 -223
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/cli.d.ts +47 -15
- package/dist/cli.js +475 -134
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -1
- package/dist/config.js +189 -19
- package/dist/config.js.map +1 -1
- package/dist/context-limits.js +2 -1
- package/dist/context-limits.js.map +1 -1
- package/dist/control-authorization.js +6 -4
- package/dist/control-authorization.js.map +1 -1
- package/dist/credential-fleet.d.ts +41 -0
- package/dist/credential-fleet.js +78 -0
- package/dist/credential-fleet.js.map +1 -0
- package/dist/credential-id.d.ts +13 -0
- package/dist/credential-id.js +22 -0
- package/dist/credential-id.js.map +1 -0
- package/dist/credential-select.d.ts +86 -0
- package/dist/credential-select.js +303 -0
- package/dist/credential-select.js.map +1 -0
- package/dist/dashboard/.vite/dashboard-bundle-graph.json +32 -0
- package/dist/dashboard/.vite/manifest.json +11 -0
- package/dist/dashboard/assets/index-BeZxN4Lx.css +1 -0
- package/dist/dashboard/assets/index-RtLgb7Cg.js +74 -0
- package/dist/dashboard/index.html +4 -0
- package/dist/dashboard-auth.d.ts +68 -0
- package/dist/dashboard-auth.js +225 -0
- package/dist/dashboard-auth.js.map +1 -0
- package/dist/dashboard-contract.d.ts +391 -0
- package/dist/dashboard-contract.js +619 -0
- package/dist/dashboard-contract.js.map +1 -0
- package/dist/dashboard-routes.d.ts +91 -0
- package/dist/dashboard-routes.js +688 -0
- package/dist/dashboard-routes.js.map +1 -0
- package/dist/dashboard-snapshot.d.ts +36 -0
- package/dist/dashboard-snapshot.js +1132 -0
- package/dist/dashboard-snapshot.js.map +1 -0
- package/dist/dashboard-static.d.ts +61 -0
- package/dist/dashboard-static.js +326 -0
- package/dist/dashboard-static.js.map +1 -0
- package/dist/dispatch.js +11 -6
- package/dist/dispatch.js.map +1 -1
- package/dist/dynamic-pools.js +6 -4
- package/dist/dynamic-pools.js.map +1 -1
- package/dist/kernel/contracts.d.ts +4 -0
- package/dist/kernel/request-lifecycle.js +4 -1
- package/dist/kernel/request-lifecycle.js.map +1 -1
- package/dist/key-checker.d.ts +3 -1
- package/dist/key-checker.js +35 -11
- package/dist/key-checker.js.map +1 -1
- package/dist/key-import.d.ts +29 -0
- package/dist/key-import.js +160 -0
- package/dist/key-import.js.map +1 -0
- package/dist/log.d.ts +20 -2
- package/dist/log.js +53 -2
- package/dist/log.js.map +1 -1
- package/dist/offload.d.ts +9 -0
- package/dist/offload.js +7 -1
- package/dist/offload.js.map +1 -1
- package/dist/onboarding.d.ts +3 -3
- package/dist/onboarding.js +12 -6
- package/dist/onboarding.js.map +1 -1
- package/dist/openai-dialect.d.ts +42 -0
- package/dist/openai-dialect.js +388 -0
- package/dist/openai-dialect.js.map +1 -0
- package/dist/ping/cadence.d.ts +12 -3
- package/dist/ping/cadence.js +68 -15
- package/dist/ping/cadence.js.map +1 -1
- package/dist/ping/ping.d.ts +7 -3
- package/dist/ping/ping.js +11 -35
- package/dist/ping/ping.js.map +1 -1
- package/dist/ping/probe-cache.d.ts +14 -6
- package/dist/ping/probe-cache.js +20 -5
- package/dist/ping/probe-cache.js.map +1 -1
- package/dist/ping/runtime-telemetry.d.ts +2 -1
- package/dist/ping/runtime-telemetry.js +103 -10
- package/dist/ping/runtime-telemetry.js.map +1 -1
- package/dist/pool-health.d.ts +2 -0
- package/dist/pool-health.js +29 -13
- package/dist/pool-health.js.map +1 -1
- package/dist/quota-observation.d.ts +29 -0
- package/dist/quota-observation.js +249 -0
- package/dist/quota-observation.js.map +1 -0
- package/dist/refusal-interpretation.d.ts +13 -7
- package/dist/refusal-interpretation.js +260 -33
- package/dist/refusal-interpretation.js.map +1 -1
- package/dist/registry.d.ts +13 -2
- package/dist/registry.js +12 -4
- package/dist/registry.js.map +1 -1
- package/dist/repair.d.ts +4 -2
- package/dist/repair.js +15 -1
- package/dist/repair.js.map +1 -1
- package/dist/request-log.d.ts +2 -2
- package/dist/request-log.js +9 -1
- package/dist/request-log.js.map +1 -1
- package/dist/reshaper.d.ts +76 -11
- package/dist/reshaper.js +264 -29
- package/dist/reshaper.js.map +1 -1
- package/dist/resolved-attempt.d.ts +14 -0
- package/dist/resolved-attempt.js +21 -0
- package/dist/resolved-attempt.js.map +1 -0
- package/dist/routes/admin.js +7 -1
- package/dist/routes/admin.js.map +1 -1
- package/dist/secret-file-acl.d.ts +25 -0
- package/dist/secret-file-acl.js +37 -0
- package/dist/secret-file-acl.js.map +1 -0
- package/dist/server.d.ts +28 -3
- package/dist/server.js +1774 -467
- package/dist/server.js.map +1 -1
- package/dist/session-pin.d.ts +35 -0
- package/dist/session-pin.js +136 -0
- package/dist/session-pin.js.map +1 -0
- package/dist/stream-commit.d.ts +34 -0
- package/dist/stream-commit.js +325 -0
- package/dist/stream-commit.js.map +1 -0
- package/dist/target-facts.d.ts +23 -136
- package/dist/target-facts.js +138 -179
- package/dist/target-facts.js.map +1 -1
- package/dist/telemetry.d.ts +1 -25
- package/dist/telemetry.js +52 -45
- package/dist/telemetry.js.map +1 -1
- package/dist/think-tags.d.ts +34 -0
- package/dist/think-tags.js +219 -0
- package/dist/think-tags.js.map +1 -0
- package/dist/usage-observer.d.ts +34 -0
- package/dist/usage-observer.js +322 -0
- package/dist/usage-observer.js.map +1 -0
- package/dist/winenv.js +26 -4
- package/dist/winenv.js.map +1 -1
- package/docs/dashboard-bundle-inventory.json +16 -0
- package/package.json +29 -6
- package/skills/llm-relay/SKILL.md +48 -9
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OhOkThisIsFine
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ weaker (often free) models.
|
|
|
11
11
|
```bash
|
|
12
12
|
npm install -g llm-relay
|
|
13
13
|
llm-relay onboard # collect free provider keys (NIM, Groq, Gemini, OpenRouter, ...)
|
|
14
|
+
llm-relay onboard --import keys.env # import dotenv or a FreeLLMAPI export JSON
|
|
14
15
|
llm-relay setup claude-desktop # or: llm-relay setup claude-cli
|
|
15
16
|
llm-relay # start the proxy — leave it running
|
|
16
17
|
```
|
|
@@ -22,12 +23,20 @@ llm-relay keys # are the credentials good?
|
|
|
22
23
|
llm-relay pools --probe # does every configured model actually answer?
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
With the relay still running, open its local read-only analytics in another terminal:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
llm-relay dashboard
|
|
30
|
+
```
|
|
31
|
+
|
|
25
32
|
New here? [docs/QUICKSTART.md](docs/QUICKSTART.md) is a staged setup guide you can hand
|
|
26
33
|
straight to an AI assistant ("set this up for me"). It also covers keeping the relay running
|
|
27
34
|
at login.
|
|
28
35
|
|
|
29
36
|
## What you get
|
|
30
37
|
|
|
38
|
+
- **Credential fleets** — give one provider multiple labeled, env-backed keys; the relay walks
|
|
39
|
+
slots breadth-first and keeps account faults and limits separate. [Configure fleets](docs/reference.md#provider-credential-fleets).
|
|
31
40
|
- **Pools with failover** — `model: "pool/medium"` expands to a ranked candidate list; 429s
|
|
32
41
|
and outages cascade to the next member. Free-model pools update themselves from live catalogs.
|
|
33
42
|
- **Passthrough** — Claude traffic keeps your own credentials and reaches real Anthropic
|
|
@@ -39,6 +48,9 @@ at login.
|
|
|
39
48
|
tool calls are refused, never fabricated; unrepairable calls fail clean.
|
|
40
49
|
- **Both API fronts** — Anthropic `/v1/messages` plus OpenAI `/v1/chat/completions` and
|
|
41
50
|
`/v1/responses`, translated in either direction, streaming included.
|
|
51
|
+
- **Local analytics dashboard** — `llm-relay dashboard` opens bounded request/attempt, token,
|
|
52
|
+
latency, provider/model/client/credential, quota, and cooldown views. Unknown or unavailable
|
|
53
|
+
accounting remains explicit; the dashboard never guesses a value or starts provider probes.
|
|
42
54
|
- **Honest metadata** — per-deployment limits and prices with provenance, capability scores
|
|
43
55
|
synced from four leaderboards, metadata-only logging, loopback-only binding.
|
|
44
56
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
The dashboard is compiled locally and does not load application code, fonts, images, or other
|
|
4
|
+
media from a CDN. This notice covers source packages physically represented in the production
|
|
5
|
+
dashboard bundle, generated CSS assets, and generated virtual-runtime helpers. The checked
|
|
6
|
+
inventory is `docs/dashboard-bundle-inventory.json`; `scripts/dashboard-package-check.mjs`
|
|
7
|
+
compares its JavaScript package list to Vite/Rollup's production module graph and validates the
|
|
8
|
+
manual generated-output attributions.
|
|
9
|
+
|
|
10
|
+
## Emitted package modules
|
|
11
|
+
|
|
12
|
+
| Package | License | Attribution |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `lucide-react@0.468.0` | ISC | Portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather (MIT). All other Lucide copyright is held by Lucide Contributors 2022. |
|
|
15
|
+
| `react@19.2.8` | MIT | Copyright (c) Meta Platforms, Inc. and affiliates |
|
|
16
|
+
| `react-dom@19.2.8` | MIT | Copyright (c) Meta Platforms, Inc. and affiliates |
|
|
17
|
+
| `scheduler@0.27.0` | MIT | Copyright (c) Meta Platforms, Inc. and affiliates |
|
|
18
|
+
|
|
19
|
+
## Generated stylesheet assets
|
|
20
|
+
|
|
21
|
+
| Asset source | Attribution | License |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| Tailwind Preflight, components and utilities emitted from `dashboard/src/styles.css` | `tailwindcss@3.4.19`, Copyright (c) Tailwind Labs, Inc. | MIT |
|
|
24
|
+
|
|
25
|
+
## Generated virtual-runtime helpers
|
|
26
|
+
|
|
27
|
+
| Virtual module | Attribution | License |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `vite/modulepreload-polyfill.js` | `vite@6.4.3`, Copyright (c) 2019-present VoidZero, Inc. and Vite contributors | MIT |
|
|
30
|
+
|
|
31
|
+
Dependencies not physically included in the dashboard bundle are not represented by this
|
|
32
|
+
dashboard-specific notice.
|
|
33
|
+
|
|
34
|
+
## MIT License
|
|
35
|
+
|
|
36
|
+
MIT License
|
|
37
|
+
|
|
38
|
+
Copyright (c) the copyright holders identified above
|
|
39
|
+
|
|
40
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
41
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
42
|
+
in the Software without restriction, including without limitation the rights
|
|
43
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
44
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
45
|
+
furnished to do so, subject to the following conditions:
|
|
46
|
+
|
|
47
|
+
The above copyright notice and this permission notice shall be included in all
|
|
48
|
+
copies or substantial portions of the Software.
|
|
49
|
+
|
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
51
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
52
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
53
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
54
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
55
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
56
|
+
SOFTWARE.
|
|
57
|
+
|
|
58
|
+
## ISC License
|
|
59
|
+
|
|
60
|
+
Copyright (c) the copyright holders identified above
|
|
61
|
+
|
|
62
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
63
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
64
|
+
copyright notice and this permission notice appear in all copies.
|
|
65
|
+
|
|
66
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
67
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
68
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
69
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
70
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
71
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
72
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/config.example.json
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
"nim": {
|
|
5
5
|
"base": "https://integrate.api.nvidia.com/v1",
|
|
6
6
|
"kind": "openai",
|
|
7
|
-
"
|
|
7
|
+
"credentials": [
|
|
8
|
+
{ "label": "personal", "authEnv": "NVIDIA_API_KEY" },
|
|
9
|
+
{ "label": "work", "authEnv": "NVIDIA_WORK_API_KEY" }
|
|
10
|
+
],
|
|
8
11
|
"tierType": "free"
|
|
9
12
|
},
|
|
10
13
|
"openrouter": {
|
|
@@ -77,7 +80,8 @@
|
|
|
77
80
|
"offload": {
|
|
78
81
|
"claude": { "enabled": false, "scope": "subagents" },
|
|
79
82
|
"codex": { "enabled": false, "scope": "subagents" }
|
|
80
|
-
}
|
|
83
|
+
},
|
|
84
|
+
"sticky": false
|
|
81
85
|
},
|
|
82
86
|
"mode": "repair",
|
|
83
87
|
"repair": {
|
|
@@ -89,6 +93,8 @@
|
|
|
89
93
|
"Edit",
|
|
90
94
|
"MultiEdit",
|
|
91
95
|
"NotebookEdit",
|
|
96
|
+
"shell_command",
|
|
97
|
+
"apply_patch",
|
|
92
98
|
"rm",
|
|
93
99
|
"delete",
|
|
94
100
|
"delete_file",
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deliberately small durability primitive for accounting's multi-file read model.
|
|
3
|
+
*
|
|
4
|
+
* It writes a full snapshot journal before replacing any target. A later process can
|
|
5
|
+
* therefore replay the journal after any target-write prefix without applying a delta
|
|
6
|
+
* twice. This module knows nothing about accounting's schemas; callers supply already
|
|
7
|
+
* materialised snapshots and an explicit target allow-list. Only flat, portable direct
|
|
8
|
+
* children of the root are supported for targets and the journal.
|
|
9
|
+
*
|
|
10
|
+
* Threat model: the root and its parent must be trusted and non-adversarial against
|
|
11
|
+
* concurrent same-user replacement. Race-proof filesystem containment against an actor
|
|
12
|
+
* able to rename or replace the root is out of scope; root and final reparse points are
|
|
13
|
+
* still checked before filesystem operations. Writer ownership is enforced only among
|
|
14
|
+
* instances in this process; cross-process concurrent writers are unsupported.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SNAPSHOT_JOURNAL_SCHEMA = "llm-relay.snapshot-journal.v1";
|
|
17
|
+
export declare const SNAPSHOT_JOURNAL_VERSION = 1;
|
|
18
|
+
export declare const SNAPSHOT_IO_DEFAULT_MAX_FILE_BYTES: number;
|
|
19
|
+
export declare const SNAPSHOT_IO_DEFAULT_MAX_JOURNAL_BYTES: number;
|
|
20
|
+
export declare const SNAPSHOT_IO_DEFAULT_MAX_TARGETS = 32;
|
|
21
|
+
export declare const SNAPSHOT_IO_HARD_MAX_FILE_BYTES: number;
|
|
22
|
+
/** Four schema-sized snapshots plus base64 and journal metadata fit below this ceiling. */
|
|
23
|
+
export declare const SNAPSHOT_IO_HARD_MAX_JOURNAL_BYTES: number;
|
|
24
|
+
export declare const SNAPSHOT_IO_HARD_MAX_TARGETS = 128;
|
|
25
|
+
export declare const SNAPSHOT_IO_MAX_RELATIVE_NAME_BYTES = 256;
|
|
26
|
+
export type SnapshotText = string | Uint8Array | null;
|
|
27
|
+
export type SnapshotIoStep = "before-temp-write" | "after-temp-write" | "after-file-fsync" | "after-rename" | "after-directory-fsync" | "before-journal-remove" | "after-journal-remove" | "before-delete" | "after-delete";
|
|
28
|
+
export interface SnapshotIoStepContext {
|
|
29
|
+
readonly step: SnapshotIoStep;
|
|
30
|
+
readonly phase: "journal" | "target";
|
|
31
|
+
readonly path: string;
|
|
32
|
+
readonly target: string | null;
|
|
33
|
+
}
|
|
34
|
+
/** Test seams are synchronous so a test can fail an exact persistence prefix without sleeps. */
|
|
35
|
+
export interface SnapshotJournalHooks {
|
|
36
|
+
readonly now?: () => number;
|
|
37
|
+
readonly nonce?: () => string;
|
|
38
|
+
/** Called before an fd-backed read; useful for deterministic EIO/EACCES simulations. */
|
|
39
|
+
readonly beforeRead?: (path: string) => void;
|
|
40
|
+
/** Called after fstat on the opened descriptor, for growth/swap regression tests. */
|
|
41
|
+
readonly afterOpenRead?: (path: string) => void;
|
|
42
|
+
/** Called immediately before directory fsync. Throw an error with `code` to simulate it. */
|
|
43
|
+
readonly beforeDirectoryFsync?: (path: string) => void;
|
|
44
|
+
readonly beforeStep?: (context: SnapshotIoStepContext) => void;
|
|
45
|
+
readonly afterStep?: (context: SnapshotIoStepContext) => void;
|
|
46
|
+
}
|
|
47
|
+
export interface SnapshotJournalIoOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Explicit trusted root. Its parent must not concurrently replace it with a same-user
|
|
50
|
+
* controlled path; race-proof containment against such an actor is out of scope.
|
|
51
|
+
*/
|
|
52
|
+
readonly rootDir: string;
|
|
53
|
+
/** Exact flat, portable direct-child names this instance may replace or read. */
|
|
54
|
+
readonly targets?: readonly string[];
|
|
55
|
+
/**
|
|
56
|
+
* Optional bounded namespace policy for additional flat direct-child names.
|
|
57
|
+
* The predicate is never called for unsafe names; exceptions reject the name.
|
|
58
|
+
*/
|
|
59
|
+
readonly acceptTarget?: (name: string) => boolean;
|
|
60
|
+
/** Flat, portable direct-child journal filename. */
|
|
61
|
+
readonly journalName?: string;
|
|
62
|
+
readonly maxFileBytes?: number;
|
|
63
|
+
readonly maxJournalBytes?: number;
|
|
64
|
+
readonly maxTargets?: number;
|
|
65
|
+
readonly hooks?: SnapshotJournalHooks;
|
|
66
|
+
}
|
|
67
|
+
export interface SnapshotReadOptions {
|
|
68
|
+
readonly maxBytes?: number;
|
|
69
|
+
/** When parsing reveals a corrupt or oversize target, quarantine it before returning. */
|
|
70
|
+
readonly quarantineCorrupt?: boolean;
|
|
71
|
+
}
|
|
72
|
+
export type SnapshotReadStatus = "ok" | "missing" | "oversize" | "corrupt" | "invalid-target" | "failed";
|
|
73
|
+
export interface SnapshotReadResult<T> {
|
|
74
|
+
readonly status: SnapshotReadStatus;
|
|
75
|
+
readonly value: T | null;
|
|
76
|
+
readonly error: string | null;
|
|
77
|
+
readonly quarantinedPath: string | null;
|
|
78
|
+
}
|
|
79
|
+
export type SnapshotMutationStatus = "committed" | "recovered" | "none" | "recovery-loss" | "invalid" | "failed";
|
|
80
|
+
export interface SnapshotMutationResult {
|
|
81
|
+
readonly status: SnapshotMutationStatus;
|
|
82
|
+
readonly transactionId: string | null;
|
|
83
|
+
/** A corrupt journal was quarantined. Existing targets are only a lower bound. */
|
|
84
|
+
readonly lowerBoundLoss: boolean;
|
|
85
|
+
readonly error: string | null;
|
|
86
|
+
readonly quarantinedPath: string | null;
|
|
87
|
+
/** Failed writes preserve the journal, so retrying commit/recover is safe. */
|
|
88
|
+
readonly retryable: boolean;
|
|
89
|
+
}
|
|
90
|
+
export interface SnapshotQuarantineResult {
|
|
91
|
+
readonly status: "quarantined" | "missing" | "invalid-target" | "failed";
|
|
92
|
+
readonly path: string | null;
|
|
93
|
+
readonly error: string | null;
|
|
94
|
+
}
|
|
95
|
+
export interface SnapshotWriterResult {
|
|
96
|
+
readonly status: "acquired" | "released" | "closed" | "busy" | "invalid" | "failed";
|
|
97
|
+
readonly error: string | null;
|
|
98
|
+
readonly retryable: boolean;
|
|
99
|
+
}
|
|
100
|
+
export interface SnapshotJournalIo {
|
|
101
|
+
readonly rootDir: string | null;
|
|
102
|
+
readonly journalPath: string | null;
|
|
103
|
+
readonly targetNames: readonly string[];
|
|
104
|
+
/** Effective bounded limits after defaults and hard-ceiling clamps. */
|
|
105
|
+
readonly maxFileBytes: number | null;
|
|
106
|
+
readonly maxJournalBytes: number | null;
|
|
107
|
+
readonly maxTargets: number | null;
|
|
108
|
+
readText(name: string, options?: SnapshotReadOptions): SnapshotReadResult<string>;
|
|
109
|
+
readJson<T = unknown>(name: string, validate?: (value: unknown) => value is T, options?: SnapshotReadOptions): SnapshotReadResult<T>;
|
|
110
|
+
quarantineTarget(name: string): SnapshotQuarantineResult;
|
|
111
|
+
/**
|
|
112
|
+
* Retain in-process root-scoped writer ownership across several recover/commit calls.
|
|
113
|
+
* Cross-process concurrent writers are unsupported.
|
|
114
|
+
*/
|
|
115
|
+
acquireWriter(): SnapshotWriterResult;
|
|
116
|
+
releaseWriter(): SnapshotWriterResult;
|
|
117
|
+
close(): SnapshotWriterResult;
|
|
118
|
+
/** Recover any durable journal. A missing journal is a successful no-op. */
|
|
119
|
+
recover(): SnapshotMutationResult;
|
|
120
|
+
/** A null snapshot is an explicit tombstone for that target. */
|
|
121
|
+
commit(snapshots: Readonly<Record<string, SnapshotText>>): SnapshotMutationResult;
|
|
122
|
+
}
|
|
123
|
+
/** Construction is total: malformed runtime options turn later calls into explicit invalid results. */
|
|
124
|
+
export declare function createSnapshotJournalIo(options: SnapshotJournalIoOptions): SnapshotJournalIo;
|