@forgezero/runtime 0.1.9 → 0.1.11
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 +543 -46
- package/dist/audit.d.ts +21 -5
- package/dist/audit.js +32 -8
- package/dist/jobs.d.ts +7 -0
- package/dist/jobs.js +56 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -35,50 +35,50 @@ Every row links to the detailed explanation and named-import/example area below.
|
|
|
35
35
|
|
|
36
36
|
| public entry | short description | runtime | details |
|
|
37
37
|
|---|---|---|---|
|
|
38
|
-
| @forgezero/runtime/query | Provider-neutral typed function contracts: decode untrusted input, run with caller-supplied services or storage, and strictly validate the result without coupling business logic to ForgeZero or ArangoDB. | portable | [
|
|
39
|
-
| @forgezero/runtime/jobs | Background work that never overlaps itself, advances a cursor only on success, and can be paused and inspected. | portable | [
|
|
40
|
-
| @forgezero/runtime/queue | Memory-only keyed work queue — awaited results, parallel across keys and strictly sequential within one; clustered callers atomically claim ownership in their own business store before submitting. | portable | [
|
|
41
|
-
| @forgezero/runtime/outbox | Write the event with the record, deliver it after, in order per key with backoff and a dead-letter queue. | portable | [
|
|
42
|
-
| @forgezero/runtime/audit | Append-only records chained by hash, with a verifier that names the first altered entry. | portable | [
|
|
43
|
-
| @forgezero/runtime/backup | Encrypted, chunked, verified snapshots to object storage — and the restore that reads them back. | portable | [
|
|
44
|
-
| @forgezero/runtime/notify | Render a named template to text and HTML, escaped per part, refusing to send with a blank where a value should be. | portable | [
|
|
45
|
-
| @forgezero/runtime/notify/templates | The six transactional messages ForgeZero sends. | portable | [
|
|
46
|
-
| @forgezero/runtime/calendar | Billing periods computed from an anchor, working days, holidays and due dates. | portable | [
|
|
47
|
-
| @forgezero/runtime/compliance | Screening as a decision record — tiers, rules and lists, failing closed when a list is unreachable. | portable | [
|
|
48
|
-
| @forgezero/runtime/totp | RFC 6238 TOTP on the existing HMAC — base32, an asymmetric window, and replay left to the caller. | portable | [
|
|
49
|
-
| @forgezero/runtime/passkey | Passkeys for sites that are not us. A vault-held credential is as unphishable as one in a security chip provided the RP ID check never slips — `evil-example.com` ends with `example.com` and is a different site. | portable | [
|
|
50
|
-
| @forgezero/runtime/phrase | BIP-39 recovery phrases, and the salted verifier that proves one without being able to reconstruct it. | portable | [
|
|
51
|
-
| @forgezero/runtime/snp | Parse an AMD SEV-SNP attestation report at the firmware ABI offsets, and compare a TCB component by component so a microcode bump cannot mask a firmware downgrade. | portable | [
|
|
52
|
-
| @forgezero/runtime/importers | Read secrets out of a .env, a CSV, or a Bitwarden or 1Password export — skipping what cannot be understood rather than guessing, and never putting a value in an error. | portable | [
|
|
53
|
-
| @forgezero/runtime/openssh | OpenSSH wire encoding, so a derived ed25519 key becomes a line that pastes into authorized_keys. | portable | [
|
|
54
|
-
| @forgezero/runtime/ssh-cert | OpenSSH certificates, so access expires instead of having to be hunted down. Takes a signing FUNCTION rather than a secret key, which is what lets the CA live in a vault that never hands it out. | portable | [
|
|
55
|
-
| @forgezero/runtime/slip10 | SLIP-0010 derivation for ed25519, hardened-only — BIP-32 does not work on this curve and produces halves that do not correspond. | portable | [
|
|
56
|
-
| @forgezero/runtime/identity | Hybrid Ed25519 + ML-DSA-65 request signing. One canonical string, so the compute agent that signs inside a guest and the API that verifies cannot drift — which two implementations of it certainly would. | portable | [
|
|
57
|
-
| @forgezero/runtime/schema | Validate against JSON Schema, restrict what a caller may declare, and describe a schema as a form. | portable | [
|
|
58
|
-
| @forgezero/runtime/schema/typebox | The TypeBox validator behind that interface. | portable | [
|
|
59
|
-
| @forgezero/runtime/finance/discounts | Promotions as arithmetic over integer minor units. They never stack — one winner — and a percentage rounds down, because rounding a discount up gives away a unit of currency per invoice forever. | portable | [
|
|
60
|
-
| @forgezero/runtime/finance/money | Exact amounts in minor units with the asset attached, so two currencies cannot be added. | portable | [
|
|
61
|
-
| @forgezero/runtime/finance/venues | Trading venues, market types and symbols as data — spot, margin and futures behind one order model. | portable | [
|
|
62
|
-
| @forgezero/runtime/finance/ledger | Double-entry postings and derived balances. A hold is a posting, not a lock — the queue does the ordering. | portable | [
|
|
63
|
-
| @forgezero/runtime/finance/commission | Profit net of flows, a high-water mark, the tier split and the referral share of our income. | portable | [
|
|
64
|
-
| @forgezero/runtime/finance/rates | What an asset is worth in USD, and how old that answer is. A peg never ages; a quote always does. | portable | [
|
|
65
|
-
| @forgezero/runtime/finance/transfers | Deposits and withdrawals as ordered pipelines, with screening reserved at position zero. | portable | [
|
|
66
|
-
| @forgezero/runtime/finance/chain | Which chains exist, their confirmation depth by value band, assets and explorers — as data an admin edits. | portable | [
|
|
67
|
-
| @forgezero/runtime/finance/custody | Derive CREATE2 deposit addresses and EIP-712 custody digests — arithmetic over a seed and a salt, needing no credential and no node. | portable | [
|
|
68
|
-
| @forgezero/runtime/finance/derive | Declare a field ForgeZero generates rather than the tenant supplying: BIP-44 path arithmetic, and the choice of who is capable of generating the key. | portable | [
|
|
69
|
-
| @forgezero/runtime/finance/tax | Which jurisdiction may tax a sale, who accounts for it, and the three ways to be zero that report differently. Rates are data. | portable | [
|
|
70
|
-
| @forgezero/runtime/finance/storage | Write an amount so it is both exact and sortable: an authoritative string, and a number that is only an index. | portable | [
|
|
71
|
-
| @forgezero/runtime/realtime | Provider-neutral realtime audience, shard, event and delivery contracts. | portable | [
|
|
72
|
-
| @forgezero/runtime/passkey-hybrid | Versioned WebAuthn PRF plus ML-DSA companion proof construction and verification. | portable | [
|
|
73
|
-
| @forgezero/runtime/otpauth | Parse and render otpauth URIs without binding enrolment to a UI framework. | portable | [
|
|
74
|
-
| @forgezero/runtime/pipeline | Typed ordered application-pipeline execution with explicit evidence. | portable | [
|
|
75
|
-
| @forgezero/runtime/finance/chain-addresses | Chain-address derivation records and validation independent of a node provider. | portable | [
|
|
76
|
-
| @forgezero/runtime/finance/chain-deposits | Provider-neutral deposit observation, confirmation and credit transitions. | portable | [
|
|
77
|
-
| @forgezero/runtime/finance/chain-withdrawals | Provider-neutral withdrawal approval, broadcast and finality transitions. | portable | [
|
|
78
|
-
| @forgezero/runtime/finance/chain-reconcile | Deterministic reconciliation between chain observations and durable transfer state. | portable | [
|
|
79
|
-
| @forgezero/runtime/finance/market | Market order, fill and quote contracts independent of any exchange adapter. | portable | [
|
|
80
|
-
| @forgezero/runtime/custody-share | Threshold-share parsing, validation and reconstruction. | portable | [
|
|
81
|
-
| @forgezero/runtime/custody-crypto | Hybrid ML-KEM-768 plus X25519 custody-share sealing and opening. | portable | [
|
|
38
|
+
| @forgezero/runtime/query | Provider-neutral typed function contracts: decode untrusted input, run with caller-supplied services or storage, and strictly validate the result without coupling business logic to ForgeZero or ArangoDB. | portable | [Reference + usage](#forgezero-runtime-query) |
|
|
39
|
+
| @forgezero/runtime/jobs | Background work that never overlaps itself, advances a cursor only on success, and can be paused and inspected. | portable | [Reference + usage](#forgezero-runtime-jobs) |
|
|
40
|
+
| @forgezero/runtime/queue | Memory-only keyed work queue — awaited results, parallel across keys and strictly sequential within one; clustered callers atomically claim ownership in their own business store before submitting. | portable | [Reference + usage](#forgezero-runtime-queue) |
|
|
41
|
+
| @forgezero/runtime/outbox | Write the event with the record, deliver it after, in order per key with backoff and a dead-letter queue. | portable | [Reference + usage](#forgezero-runtime-outbox) |
|
|
42
|
+
| @forgezero/runtime/audit | Append-only records chained by hash, with a verifier that names the first altered entry. | portable | [Reference + usage](#forgezero-runtime-audit) |
|
|
43
|
+
| @forgezero/runtime/backup | Encrypted, chunked, verified snapshots to object storage — and the restore that reads them back. | portable | [Reference + usage](#forgezero-runtime-backup) |
|
|
44
|
+
| @forgezero/runtime/notify | Render a named template to text and HTML, escaped per part, refusing to send with a blank where a value should be. | portable | [Reference + usage](#forgezero-runtime-notify) |
|
|
45
|
+
| @forgezero/runtime/notify/templates | The six transactional messages ForgeZero sends. | portable | [Reference + usage](#forgezero-runtime-notify-templates) |
|
|
46
|
+
| @forgezero/runtime/calendar | Billing periods computed from an anchor, working days, holidays and due dates. | portable | [Reference + usage](#forgezero-runtime-calendar) |
|
|
47
|
+
| @forgezero/runtime/compliance | Screening as a decision record — tiers, rules and lists, failing closed when a list is unreachable. | portable | [Reference + usage](#forgezero-runtime-compliance) |
|
|
48
|
+
| @forgezero/runtime/totp | RFC 6238 TOTP on the existing HMAC — base32, an asymmetric window, and replay left to the caller. | portable | [Reference + usage](#forgezero-runtime-totp) |
|
|
49
|
+
| @forgezero/runtime/passkey | Passkeys for sites that are not us. A vault-held credential is as unphishable as one in a security chip provided the RP ID check never slips — `evil-example.com` ends with `example.com` and is a different site. | portable | [Reference + usage](#forgezero-runtime-passkey) |
|
|
50
|
+
| @forgezero/runtime/phrase | BIP-39 recovery phrases, and the salted verifier that proves one without being able to reconstruct it. | portable | [Reference + usage](#forgezero-runtime-phrase) |
|
|
51
|
+
| @forgezero/runtime/snp | Parse an AMD SEV-SNP attestation report at the firmware ABI offsets, and compare a TCB component by component so a microcode bump cannot mask a firmware downgrade. | portable | [Reference + usage](#forgezero-runtime-snp) |
|
|
52
|
+
| @forgezero/runtime/importers | Read secrets out of a .env, a CSV, or a Bitwarden or 1Password export — skipping what cannot be understood rather than guessing, and never putting a value in an error. | portable | [Reference + usage](#forgezero-runtime-importers) |
|
|
53
|
+
| @forgezero/runtime/openssh | OpenSSH wire encoding, so a derived ed25519 key becomes a line that pastes into authorized_keys. | portable | [Reference + usage](#forgezero-runtime-openssh) |
|
|
54
|
+
| @forgezero/runtime/ssh-cert | OpenSSH certificates, so access expires instead of having to be hunted down. Takes a signing FUNCTION rather than a secret key, which is what lets the CA live in a vault that never hands it out. | portable | [Reference + usage](#forgezero-runtime-ssh-cert) |
|
|
55
|
+
| @forgezero/runtime/slip10 | SLIP-0010 derivation for ed25519, hardened-only — BIP-32 does not work on this curve and produces halves that do not correspond. | portable | [Reference + usage](#forgezero-runtime-slip10) |
|
|
56
|
+
| @forgezero/runtime/identity | Hybrid Ed25519 + ML-DSA-65 request signing. One canonical string, so the compute agent that signs inside a guest and the API that verifies cannot drift — which two implementations of it certainly would. | portable | [Reference + usage](#forgezero-runtime-identity) |
|
|
57
|
+
| @forgezero/runtime/schema | Validate against JSON Schema, restrict what a caller may declare, and describe a schema as a form. | portable | [Reference + usage](#forgezero-runtime-schema) |
|
|
58
|
+
| @forgezero/runtime/schema/typebox | The TypeBox validator behind that interface. | portable | [Reference + usage](#forgezero-runtime-schema-typebox) |
|
|
59
|
+
| @forgezero/runtime/finance/discounts | Promotions as arithmetic over integer minor units. They never stack — one winner — and a percentage rounds down, because rounding a discount up gives away a unit of currency per invoice forever. | portable | [Reference + usage](#forgezero-runtime-finance-discounts) |
|
|
60
|
+
| @forgezero/runtime/finance/money | Exact amounts in minor units with the asset attached, so two currencies cannot be added. | portable | [Reference + usage](#forgezero-runtime-finance-money) |
|
|
61
|
+
| @forgezero/runtime/finance/venues | Trading venues, market types and symbols as data — spot, margin and futures behind one order model. | portable | [Reference + usage](#forgezero-runtime-finance-venues) |
|
|
62
|
+
| @forgezero/runtime/finance/ledger | Double-entry postings and derived balances. A hold is a posting, not a lock — the queue does the ordering. | portable | [Reference + usage](#forgezero-runtime-finance-ledger) |
|
|
63
|
+
| @forgezero/runtime/finance/commission | Profit net of flows, a high-water mark, the tier split and the referral share of our income. | portable | [Reference + usage](#forgezero-runtime-finance-commission) |
|
|
64
|
+
| @forgezero/runtime/finance/rates | What an asset is worth in USD, and how old that answer is. A peg never ages; a quote always does. | portable | [Reference + usage](#forgezero-runtime-finance-rates) |
|
|
65
|
+
| @forgezero/runtime/finance/transfers | Deposits and withdrawals as ordered pipelines, with screening reserved at position zero. | portable | [Reference + usage](#forgezero-runtime-finance-transfers) |
|
|
66
|
+
| @forgezero/runtime/finance/chain | Which chains exist, their confirmation depth by value band, assets and explorers — as data an admin edits. | portable | [Reference + usage](#forgezero-runtime-finance-chain) |
|
|
67
|
+
| @forgezero/runtime/finance/custody | Derive CREATE2 deposit addresses and EIP-712 custody digests — arithmetic over a seed and a salt, needing no credential and no node. | portable | [Reference + usage](#forgezero-runtime-finance-custody) |
|
|
68
|
+
| @forgezero/runtime/finance/derive | Declare a field ForgeZero generates rather than the tenant supplying: BIP-44 path arithmetic, and the choice of who is capable of generating the key. | portable | [Reference + usage](#forgezero-runtime-finance-derive) |
|
|
69
|
+
| @forgezero/runtime/finance/tax | Which jurisdiction may tax a sale, who accounts for it, and the three ways to be zero that report differently. Rates are data. | portable | [Reference + usage](#forgezero-runtime-finance-tax) |
|
|
70
|
+
| @forgezero/runtime/finance/storage | Write an amount so it is both exact and sortable: an authoritative string, and a number that is only an index. | portable | [Reference + usage](#forgezero-runtime-finance-storage) |
|
|
71
|
+
| @forgezero/runtime/realtime | Provider-neutral realtime audience, shard, event and delivery contracts. | portable | [Reference + usage](#forgezero-runtime-realtime) |
|
|
72
|
+
| @forgezero/runtime/passkey-hybrid | Versioned WebAuthn PRF plus ML-DSA companion proof construction and verification. | portable | [Reference + usage](#forgezero-runtime-passkey-hybrid) |
|
|
73
|
+
| @forgezero/runtime/otpauth | Parse and render otpauth URIs without binding enrolment to a UI framework. | portable | [Reference + usage](#forgezero-runtime-otpauth) |
|
|
74
|
+
| @forgezero/runtime/pipeline | Typed ordered application-pipeline execution with explicit evidence. | portable | [Reference + usage](#forgezero-runtime-pipeline) |
|
|
75
|
+
| @forgezero/runtime/finance/chain-addresses | Chain-address derivation records and validation independent of a node provider. | portable | [Reference + usage](#forgezero-runtime-finance-chain-addresses) |
|
|
76
|
+
| @forgezero/runtime/finance/chain-deposits | Provider-neutral deposit observation, confirmation and credit transitions. | portable | [Reference + usage](#forgezero-runtime-finance-chain-deposits) |
|
|
77
|
+
| @forgezero/runtime/finance/chain-withdrawals | Provider-neutral withdrawal approval, broadcast and finality transitions. | portable | [Reference + usage](#forgezero-runtime-finance-chain-withdrawals) |
|
|
78
|
+
| @forgezero/runtime/finance/chain-reconcile | Deterministic reconciliation between chain observations and durable transfer state. | portable | [Reference + usage](#forgezero-runtime-finance-chain-reconcile) |
|
|
79
|
+
| @forgezero/runtime/finance/market | Market order, fill and quote contracts independent of any exchange adapter. | portable | [Reference + usage](#forgezero-runtime-finance-market) |
|
|
80
|
+
| @forgezero/runtime/custody-share | Threshold-share parsing, validation and reconstruction. | portable | [Reference + usage](#forgezero-runtime-custody-share) |
|
|
81
|
+
| @forgezero/runtime/custody-crypto | Hybrid ML-KEM-768 plus X25519 custody-share sealing and opening. | portable | [Reference + usage](#forgezero-runtime-custody-crypto) |
|
|
82
82
|
|
|
83
83
|
## Commands
|
|
84
84
|
|
|
@@ -148,19 +148,22 @@ const order = await runFindOrder.execute(stores, { orderKey: 'ord_123' });
|
|
|
148
148
|
<a id="forgezero-runtime-jobs"></a>
|
|
149
149
|
## @forgezero/runtime/jobs
|
|
150
150
|
|
|
151
|
-
Background work that never overlaps itself, advances a cursor only on success, and can be paused and inspected. This entry exposes
|
|
151
|
+
Background work that never overlaps itself, advances a cursor only on success, and can be paused and inspected. This entry exposes 12 named value exports and 14 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
|
|
152
152
|
|
|
153
153
|
```text
|
|
154
154
|
import {
|
|
155
|
+
JobFenceLostError,
|
|
155
156
|
VERSION,
|
|
156
157
|
createScheduler,
|
|
157
158
|
cursorJob,
|
|
158
159
|
defineJob,
|
|
159
160
|
everyMs,
|
|
161
|
+
forEachFenced,
|
|
160
162
|
memoryLock,
|
|
161
163
|
nextWallClockAt,
|
|
162
164
|
storeLock,
|
|
163
165
|
systemClock,
|
|
166
|
+
withJobFence,
|
|
164
167
|
} from '@forgezero/runtime/jobs';
|
|
165
168
|
|
|
166
169
|
import type {
|
|
@@ -181,6 +184,18 @@ import type {
|
|
|
181
184
|
} from '@forgezero/runtime/jobs';
|
|
182
185
|
```
|
|
183
186
|
|
|
187
|
+
## @forgezero/runtime/jobs — Use this entry point
|
|
188
|
+
|
|
189
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
190
|
+
|
|
191
|
+
```text
|
|
192
|
+
import {
|
|
193
|
+
JobFenceLostError,
|
|
194
|
+
} from '@forgezero/runtime/jobs';
|
|
195
|
+
|
|
196
|
+
export const selectedCapability = JobFenceLostError;
|
|
197
|
+
```
|
|
198
|
+
|
|
184
199
|
<a id="forgezero-runtime-queue"></a>
|
|
185
200
|
## @forgezero/runtime/queue
|
|
186
201
|
|
|
@@ -205,6 +220,18 @@ import type {
|
|
|
205
220
|
} from '@forgezero/runtime/queue';
|
|
206
221
|
```
|
|
207
222
|
|
|
223
|
+
## @forgezero/runtime/queue — Use this entry point
|
|
224
|
+
|
|
225
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
226
|
+
|
|
227
|
+
```text
|
|
228
|
+
import {
|
|
229
|
+
QueueKeyStoppedError,
|
|
230
|
+
} from '@forgezero/runtime/queue';
|
|
231
|
+
|
|
232
|
+
export const selectedCapability = QueueKeyStoppedError;
|
|
233
|
+
```
|
|
234
|
+
|
|
208
235
|
<a id="forgezero-runtime-outbox"></a>
|
|
209
236
|
## @forgezero/runtime/outbox
|
|
210
237
|
|
|
@@ -236,10 +263,22 @@ import type {
|
|
|
236
263
|
} from '@forgezero/runtime/outbox';
|
|
237
264
|
```
|
|
238
265
|
|
|
266
|
+
## @forgezero/runtime/outbox — Use this entry point
|
|
267
|
+
|
|
268
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
import {
|
|
272
|
+
DEFAULT_POLICY,
|
|
273
|
+
} from '@forgezero/runtime/outbox';
|
|
274
|
+
|
|
275
|
+
export const selectedCapability = DEFAULT_POLICY;
|
|
276
|
+
```
|
|
277
|
+
|
|
239
278
|
<a id="forgezero-runtime-audit"></a>
|
|
240
279
|
## @forgezero/runtime/audit
|
|
241
280
|
|
|
242
|
-
Append-only records chained by hash, with a verifier that names the first altered entry. This entry exposes 12 named value exports and
|
|
281
|
+
Append-only records chained by hash, with a verifier that names the first altered entry. This entry exposes 12 named value exports and 12 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
|
|
243
282
|
|
|
244
283
|
```text
|
|
245
284
|
import {
|
|
@@ -261,16 +300,30 @@ import type {
|
|
|
261
300
|
AppendOptions,
|
|
262
301
|
AuditChain,
|
|
263
302
|
AuditChainOptions,
|
|
303
|
+
AuditDigesterResolver,
|
|
264
304
|
AuditEntry,
|
|
265
305
|
AuditExport,
|
|
266
306
|
AuditRecord,
|
|
267
307
|
AuditStore,
|
|
308
|
+
AuditVerifyOptions,
|
|
268
309
|
ChainVerdict,
|
|
269
310
|
Digester,
|
|
270
311
|
EffectAuditRecord,
|
|
271
312
|
} from '@forgezero/runtime/audit';
|
|
272
313
|
```
|
|
273
314
|
|
|
315
|
+
## @forgezero/runtime/audit — Use this entry point
|
|
316
|
+
|
|
317
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
318
|
+
|
|
319
|
+
```text
|
|
320
|
+
import {
|
|
321
|
+
AuditChainError,
|
|
322
|
+
} from '@forgezero/runtime/audit';
|
|
323
|
+
|
|
324
|
+
export const selectedCapability = AuditChainError;
|
|
325
|
+
```
|
|
326
|
+
|
|
274
327
|
<a id="forgezero-runtime-backup"></a>
|
|
275
328
|
## @forgezero/runtime/backup
|
|
276
329
|
|
|
@@ -305,6 +358,18 @@ import type {
|
|
|
305
358
|
} from '@forgezero/runtime/backup';
|
|
306
359
|
```
|
|
307
360
|
|
|
361
|
+
## @forgezero/runtime/backup — Use this entry point
|
|
362
|
+
|
|
363
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
364
|
+
|
|
365
|
+
```text
|
|
366
|
+
import {
|
|
367
|
+
BackupError,
|
|
368
|
+
} from '@forgezero/runtime/backup';
|
|
369
|
+
|
|
370
|
+
export const selectedCapability = BackupError;
|
|
371
|
+
```
|
|
372
|
+
|
|
308
373
|
<a id="forgezero-runtime-notify"></a>
|
|
309
374
|
## @forgezero/runtime/notify
|
|
310
375
|
|
|
@@ -337,6 +402,18 @@ import type {
|
|
|
337
402
|
} from '@forgezero/runtime/notify';
|
|
338
403
|
```
|
|
339
404
|
|
|
405
|
+
## @forgezero/runtime/notify — Use this entry point
|
|
406
|
+
|
|
407
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
408
|
+
|
|
409
|
+
```text
|
|
410
|
+
import {
|
|
411
|
+
CHANNELS,
|
|
412
|
+
} from '@forgezero/runtime/notify';
|
|
413
|
+
|
|
414
|
+
export const selectedCapability = CHANNELS;
|
|
415
|
+
```
|
|
416
|
+
|
|
340
417
|
<a id="forgezero-runtime-notify-templates"></a>
|
|
341
418
|
## @forgezero/runtime/notify/templates
|
|
342
419
|
|
|
@@ -359,6 +436,18 @@ import type {
|
|
|
359
436
|
} from '@forgezero/runtime/notify/templates';
|
|
360
437
|
```
|
|
361
438
|
|
|
439
|
+
## @forgezero/runtime/notify/templates — Use this entry point
|
|
440
|
+
|
|
441
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
442
|
+
|
|
443
|
+
```text
|
|
444
|
+
import {
|
|
445
|
+
TEMPLATES,
|
|
446
|
+
} from '@forgezero/runtime/notify/templates';
|
|
447
|
+
|
|
448
|
+
export const selectedCapability = TEMPLATES;
|
|
449
|
+
```
|
|
450
|
+
|
|
362
451
|
<a id="forgezero-runtime-calendar"></a>
|
|
363
452
|
## @forgezero/runtime/calendar
|
|
364
453
|
|
|
@@ -391,6 +480,18 @@ import type {
|
|
|
391
480
|
} from '@forgezero/runtime/calendar';
|
|
392
481
|
```
|
|
393
482
|
|
|
483
|
+
## @forgezero/runtime/calendar — Use this entry point
|
|
484
|
+
|
|
485
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
486
|
+
|
|
487
|
+
```text
|
|
488
|
+
import {
|
|
489
|
+
CalendarError,
|
|
490
|
+
} from '@forgezero/runtime/calendar';
|
|
491
|
+
|
|
492
|
+
export const selectedCapability = CalendarError;
|
|
493
|
+
```
|
|
494
|
+
|
|
394
495
|
<a id="forgezero-runtime-compliance"></a>
|
|
395
496
|
## @forgezero/runtime/compliance
|
|
396
497
|
|
|
@@ -425,6 +526,18 @@ import type {
|
|
|
425
526
|
} from '@forgezero/runtime/compliance';
|
|
426
527
|
```
|
|
427
528
|
|
|
529
|
+
## @forgezero/runtime/compliance — Use this entry point
|
|
530
|
+
|
|
531
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
532
|
+
|
|
533
|
+
```text
|
|
534
|
+
import {
|
|
535
|
+
ComplianceError,
|
|
536
|
+
} from '@forgezero/runtime/compliance';
|
|
537
|
+
|
|
538
|
+
export const selectedCapability = ComplianceError;
|
|
539
|
+
```
|
|
540
|
+
|
|
428
541
|
<a id="forgezero-runtime-totp"></a>
|
|
429
542
|
## @forgezero/runtime/totp
|
|
430
543
|
|
|
@@ -454,6 +567,18 @@ import type {
|
|
|
454
567
|
} from '@forgezero/runtime/totp';
|
|
455
568
|
```
|
|
456
569
|
|
|
570
|
+
## @forgezero/runtime/totp — Use this entry point
|
|
571
|
+
|
|
572
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
573
|
+
|
|
574
|
+
```text
|
|
575
|
+
import {
|
|
576
|
+
DEFAULT_DIGITS,
|
|
577
|
+
} from '@forgezero/runtime/totp';
|
|
578
|
+
|
|
579
|
+
export const selectedCapability = DEFAULT_DIGITS;
|
|
580
|
+
```
|
|
581
|
+
|
|
457
582
|
<a id="forgezero-runtime-passkey"></a>
|
|
458
583
|
## @forgezero/runtime/passkey
|
|
459
584
|
|
|
@@ -481,6 +606,18 @@ import type {
|
|
|
481
606
|
} from '@forgezero/runtime/passkey';
|
|
482
607
|
```
|
|
483
608
|
|
|
609
|
+
## @forgezero/runtime/passkey — Use this entry point
|
|
610
|
+
|
|
611
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
612
|
+
|
|
613
|
+
```text
|
|
614
|
+
import {
|
|
615
|
+
FLAG_BE,
|
|
616
|
+
} from '@forgezero/runtime/passkey';
|
|
617
|
+
|
|
618
|
+
export const selectedCapability = FLAG_BE;
|
|
619
|
+
```
|
|
620
|
+
|
|
484
621
|
<a id="forgezero-runtime-phrase"></a>
|
|
485
622
|
## @forgezero/runtime/phrase
|
|
486
623
|
|
|
@@ -498,6 +635,18 @@ import {
|
|
|
498
635
|
} from '@forgezero/runtime/phrase';
|
|
499
636
|
```
|
|
500
637
|
|
|
638
|
+
## @forgezero/runtime/phrase — Use this entry point
|
|
639
|
+
|
|
640
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
641
|
+
|
|
642
|
+
```text
|
|
643
|
+
import {
|
|
644
|
+
PHRASE_SALT_BYTES,
|
|
645
|
+
} from '@forgezero/runtime/phrase';
|
|
646
|
+
|
|
647
|
+
export const selectedCapability = PHRASE_SALT_BYTES;
|
|
648
|
+
```
|
|
649
|
+
|
|
501
650
|
<a id="forgezero-runtime-snp"></a>
|
|
502
651
|
## @forgezero/runtime/snp
|
|
503
652
|
|
|
@@ -519,6 +668,18 @@ import type {
|
|
|
519
668
|
} from '@forgezero/runtime/snp';
|
|
520
669
|
```
|
|
521
670
|
|
|
671
|
+
## @forgezero/runtime/snp — Use this entry point
|
|
672
|
+
|
|
673
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
674
|
+
|
|
675
|
+
```text
|
|
676
|
+
import {
|
|
677
|
+
REPORT_BYTES,
|
|
678
|
+
} from '@forgezero/runtime/snp';
|
|
679
|
+
|
|
680
|
+
export const selectedCapability = REPORT_BYTES;
|
|
681
|
+
```
|
|
682
|
+
|
|
522
683
|
<a id="forgezero-runtime-importers"></a>
|
|
523
684
|
## @forgezero/runtime/importers
|
|
524
685
|
|
|
@@ -543,6 +704,18 @@ import type {
|
|
|
543
704
|
} from '@forgezero/runtime/importers';
|
|
544
705
|
```
|
|
545
706
|
|
|
707
|
+
## @forgezero/runtime/importers — Use this entry point
|
|
708
|
+
|
|
709
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
710
|
+
|
|
711
|
+
```text
|
|
712
|
+
import {
|
|
713
|
+
IMPORT_FORMATS,
|
|
714
|
+
} from '@forgezero/runtime/importers';
|
|
715
|
+
|
|
716
|
+
export const selectedCapability = IMPORT_FORMATS;
|
|
717
|
+
```
|
|
718
|
+
|
|
546
719
|
<a id="forgezero-runtime-openssh"></a>
|
|
547
720
|
## @forgezero/runtime/openssh
|
|
548
721
|
|
|
@@ -559,6 +732,18 @@ import {
|
|
|
559
732
|
} from '@forgezero/runtime/openssh';
|
|
560
733
|
```
|
|
561
734
|
|
|
735
|
+
## @forgezero/runtime/openssh — Use this entry point
|
|
736
|
+
|
|
737
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
738
|
+
|
|
739
|
+
```text
|
|
740
|
+
import {
|
|
741
|
+
OpenSshError,
|
|
742
|
+
} from '@forgezero/runtime/openssh';
|
|
743
|
+
|
|
744
|
+
export const selectedCapability = OpenSshError;
|
|
745
|
+
```
|
|
746
|
+
|
|
562
747
|
<a id="forgezero-runtime-ssh-cert"></a>
|
|
563
748
|
## @forgezero/runtime/ssh-cert
|
|
564
749
|
|
|
@@ -583,6 +768,18 @@ import type {
|
|
|
583
768
|
} from '@forgezero/runtime/ssh-cert';
|
|
584
769
|
```
|
|
585
770
|
|
|
771
|
+
## @forgezero/runtime/ssh-cert — Use this entry point
|
|
772
|
+
|
|
773
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
774
|
+
|
|
775
|
+
```text
|
|
776
|
+
import {
|
|
777
|
+
CERT_TYPE_HOST,
|
|
778
|
+
} from '@forgezero/runtime/ssh-cert';
|
|
779
|
+
|
|
780
|
+
export const selectedCapability = CERT_TYPE_HOST;
|
|
781
|
+
```
|
|
782
|
+
|
|
586
783
|
<a id="forgezero-runtime-slip10"></a>
|
|
587
784
|
## @forgezero/runtime/slip10
|
|
588
785
|
|
|
@@ -602,6 +799,18 @@ import type {
|
|
|
602
799
|
} from '@forgezero/runtime/slip10';
|
|
603
800
|
```
|
|
604
801
|
|
|
802
|
+
## @forgezero/runtime/slip10 — Use this entry point
|
|
803
|
+
|
|
804
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
805
|
+
|
|
806
|
+
```text
|
|
807
|
+
import {
|
|
808
|
+
HARDENED_OFFSET,
|
|
809
|
+
} from '@forgezero/runtime/slip10';
|
|
810
|
+
|
|
811
|
+
export const selectedCapability = HARDENED_OFFSET;
|
|
812
|
+
```
|
|
813
|
+
|
|
605
814
|
<a id="forgezero-runtime-identity"></a>
|
|
606
815
|
## @forgezero/runtime/identity
|
|
607
816
|
|
|
@@ -637,6 +846,18 @@ import type {
|
|
|
637
846
|
} from '@forgezero/runtime/identity';
|
|
638
847
|
```
|
|
639
848
|
|
|
849
|
+
## @forgezero/runtime/identity — Use this entry point
|
|
850
|
+
|
|
851
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
852
|
+
|
|
853
|
+
```text
|
|
854
|
+
import {
|
|
855
|
+
CLOCK_SKEW_SECONDS,
|
|
856
|
+
} from '@forgezero/runtime/identity';
|
|
857
|
+
|
|
858
|
+
export const selectedCapability = CLOCK_SKEW_SECONDS;
|
|
859
|
+
```
|
|
860
|
+
|
|
640
861
|
<a id="forgezero-runtime-schema"></a>
|
|
641
862
|
## @forgezero/runtime/schema
|
|
642
863
|
|
|
@@ -750,6 +971,18 @@ import type {
|
|
|
750
971
|
} from '@forgezero/runtime/finance/discounts';
|
|
751
972
|
```
|
|
752
973
|
|
|
974
|
+
## @forgezero/runtime/finance/discounts — Use this entry point
|
|
975
|
+
|
|
976
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
977
|
+
|
|
978
|
+
```text
|
|
979
|
+
import {
|
|
980
|
+
DiscountError,
|
|
981
|
+
} from '@forgezero/runtime/finance/discounts';
|
|
982
|
+
|
|
983
|
+
export const selectedCapability = DiscountError;
|
|
984
|
+
```
|
|
985
|
+
|
|
753
986
|
<a id="forgezero-runtime-finance-money"></a>
|
|
754
987
|
## @forgezero/runtime/finance/money
|
|
755
988
|
|
|
@@ -788,6 +1021,18 @@ import type {
|
|
|
788
1021
|
} from '@forgezero/runtime/finance/money';
|
|
789
1022
|
```
|
|
790
1023
|
|
|
1024
|
+
## @forgezero/runtime/finance/money — Use this entry point
|
|
1025
|
+
|
|
1026
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1027
|
+
|
|
1028
|
+
```text
|
|
1029
|
+
import {
|
|
1030
|
+
ASSETS,
|
|
1031
|
+
} from '@forgezero/runtime/finance/money';
|
|
1032
|
+
|
|
1033
|
+
export const selectedCapability = ASSETS;
|
|
1034
|
+
```
|
|
1035
|
+
|
|
791
1036
|
<a id="forgezero-runtime-finance-venues"></a>
|
|
792
1037
|
## @forgezero/runtime/finance/venues
|
|
793
1038
|
|
|
@@ -825,6 +1070,18 @@ import type {
|
|
|
825
1070
|
} from '@forgezero/runtime/finance/venues';
|
|
826
1071
|
```
|
|
827
1072
|
|
|
1073
|
+
## @forgezero/runtime/finance/venues — Use this entry point
|
|
1074
|
+
|
|
1075
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1076
|
+
|
|
1077
|
+
```text
|
|
1078
|
+
import {
|
|
1079
|
+
MARKET_TYPES,
|
|
1080
|
+
} from '@forgezero/runtime/finance/venues';
|
|
1081
|
+
|
|
1082
|
+
export const selectedCapability = MARKET_TYPES;
|
|
1083
|
+
```
|
|
1084
|
+
|
|
828
1085
|
<a id="forgezero-runtime-finance-ledger"></a>
|
|
829
1086
|
## @forgezero/runtime/finance/ledger
|
|
830
1087
|
|
|
@@ -865,6 +1122,18 @@ import type {
|
|
|
865
1122
|
} from '@forgezero/runtime/finance/ledger';
|
|
866
1123
|
```
|
|
867
1124
|
|
|
1125
|
+
## @forgezero/runtime/finance/ledger — Use this entry point
|
|
1126
|
+
|
|
1127
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1128
|
+
|
|
1129
|
+
```text
|
|
1130
|
+
import {
|
|
1131
|
+
ACCOUNT_KINDS,
|
|
1132
|
+
} from '@forgezero/runtime/finance/ledger';
|
|
1133
|
+
|
|
1134
|
+
export const selectedCapability = ACCOUNT_KINDS;
|
|
1135
|
+
```
|
|
1136
|
+
|
|
868
1137
|
<a id="forgezero-runtime-finance-commission"></a>
|
|
869
1138
|
## @forgezero/runtime/finance/commission
|
|
870
1139
|
|
|
@@ -893,6 +1162,18 @@ import type {
|
|
|
893
1162
|
} from '@forgezero/runtime/finance/commission';
|
|
894
1163
|
```
|
|
895
1164
|
|
|
1165
|
+
## @forgezero/runtime/finance/commission — Use this entry point
|
|
1166
|
+
|
|
1167
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1168
|
+
|
|
1169
|
+
```text
|
|
1170
|
+
import {
|
|
1171
|
+
CommissionError,
|
|
1172
|
+
} from '@forgezero/runtime/finance/commission';
|
|
1173
|
+
|
|
1174
|
+
export const selectedCapability = CommissionError;
|
|
1175
|
+
```
|
|
1176
|
+
|
|
896
1177
|
<a id="forgezero-runtime-finance-rates"></a>
|
|
897
1178
|
## @forgezero/runtime/finance/rates
|
|
898
1179
|
|
|
@@ -924,6 +1205,18 @@ import type {
|
|
|
924
1205
|
} from '@forgezero/runtime/finance/rates';
|
|
925
1206
|
```
|
|
926
1207
|
|
|
1208
|
+
## @forgezero/runtime/finance/rates — Use this entry point
|
|
1209
|
+
|
|
1210
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1211
|
+
|
|
1212
|
+
```text
|
|
1213
|
+
import {
|
|
1214
|
+
BASE_ASSET,
|
|
1215
|
+
} from '@forgezero/runtime/finance/rates';
|
|
1216
|
+
|
|
1217
|
+
export const selectedCapability = BASE_ASSET;
|
|
1218
|
+
```
|
|
1219
|
+
|
|
927
1220
|
<a id="forgezero-runtime-finance-transfers"></a>
|
|
928
1221
|
## @forgezero/runtime/finance/transfers
|
|
929
1222
|
|
|
@@ -952,6 +1245,18 @@ import type {
|
|
|
952
1245
|
} from '@forgezero/runtime/finance/transfers';
|
|
953
1246
|
```
|
|
954
1247
|
|
|
1248
|
+
## @forgezero/runtime/finance/transfers — Use this entry point
|
|
1249
|
+
|
|
1250
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1251
|
+
|
|
1252
|
+
```text
|
|
1253
|
+
import {
|
|
1254
|
+
DIRECTIONS,
|
|
1255
|
+
} from '@forgezero/runtime/finance/transfers';
|
|
1256
|
+
|
|
1257
|
+
export const selectedCapability = DIRECTIONS;
|
|
1258
|
+
```
|
|
1259
|
+
|
|
955
1260
|
<a id="forgezero-runtime-finance-chain"></a>
|
|
956
1261
|
## @forgezero/runtime/finance/chain
|
|
957
1262
|
|
|
@@ -979,6 +1284,18 @@ import type {
|
|
|
979
1284
|
} from '@forgezero/runtime/finance/chain';
|
|
980
1285
|
```
|
|
981
1286
|
|
|
1287
|
+
## @forgezero/runtime/finance/chain — Use this entry point
|
|
1288
|
+
|
|
1289
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1290
|
+
|
|
1291
|
+
```text
|
|
1292
|
+
import {
|
|
1293
|
+
ADDRESS_SCHEMES,
|
|
1294
|
+
} from '@forgezero/runtime/finance/chain';
|
|
1295
|
+
|
|
1296
|
+
export const selectedCapability = ADDRESS_SCHEMES;
|
|
1297
|
+
```
|
|
1298
|
+
|
|
982
1299
|
<a id="forgezero-runtime-finance-custody"></a>
|
|
983
1300
|
## @forgezero/runtime/finance/custody
|
|
984
1301
|
|
|
@@ -997,6 +1314,18 @@ import {
|
|
|
997
1314
|
} from '@forgezero/runtime/finance/custody';
|
|
998
1315
|
```
|
|
999
1316
|
|
|
1317
|
+
## @forgezero/runtime/finance/custody — Use this entry point
|
|
1318
|
+
|
|
1319
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1320
|
+
|
|
1321
|
+
```text
|
|
1322
|
+
import {
|
|
1323
|
+
CustodyError,
|
|
1324
|
+
} from '@forgezero/runtime/finance/custody';
|
|
1325
|
+
|
|
1326
|
+
export const selectedCapability = CustodyError;
|
|
1327
|
+
```
|
|
1328
|
+
|
|
1000
1329
|
<a id="forgezero-runtime-finance-derive"></a>
|
|
1001
1330
|
## @forgezero/runtime/finance/derive
|
|
1002
1331
|
|
|
@@ -1025,6 +1354,18 @@ import type {
|
|
|
1025
1354
|
} from '@forgezero/runtime/finance/derive';
|
|
1026
1355
|
```
|
|
1027
1356
|
|
|
1357
|
+
## @forgezero/runtime/finance/derive — Use this entry point
|
|
1358
|
+
|
|
1359
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1360
|
+
|
|
1361
|
+
```text
|
|
1362
|
+
import {
|
|
1363
|
+
CUSTODY,
|
|
1364
|
+
} from '@forgezero/runtime/finance/derive';
|
|
1365
|
+
|
|
1366
|
+
export const selectedCapability = CUSTODY;
|
|
1367
|
+
```
|
|
1368
|
+
|
|
1028
1369
|
<a id="forgezero-runtime-finance-tax"></a>
|
|
1029
1370
|
## @forgezero/runtime/finance/tax
|
|
1030
1371
|
|
|
@@ -1053,6 +1394,18 @@ import type {
|
|
|
1053
1394
|
} from '@forgezero/runtime/finance/tax';
|
|
1054
1395
|
```
|
|
1055
1396
|
|
|
1397
|
+
## @forgezero/runtime/finance/tax — Use this entry point
|
|
1398
|
+
|
|
1399
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1400
|
+
|
|
1401
|
+
```text
|
|
1402
|
+
import {
|
|
1403
|
+
TREATMENTS,
|
|
1404
|
+
} from '@forgezero/runtime/finance/tax';
|
|
1405
|
+
|
|
1406
|
+
export const selectedCapability = TREATMENTS;
|
|
1407
|
+
```
|
|
1408
|
+
|
|
1056
1409
|
<a id="forgezero-runtime-finance-storage"></a>
|
|
1057
1410
|
## @forgezero/runtime/finance/storage
|
|
1058
1411
|
|
|
@@ -1075,6 +1428,18 @@ import type {
|
|
|
1075
1428
|
} from '@forgezero/runtime/finance/storage';
|
|
1076
1429
|
```
|
|
1077
1430
|
|
|
1431
|
+
## @forgezero/runtime/finance/storage — Use this entry point
|
|
1432
|
+
|
|
1433
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1434
|
+
|
|
1435
|
+
```text
|
|
1436
|
+
import {
|
|
1437
|
+
SORT_FIELD,
|
|
1438
|
+
} from '@forgezero/runtime/finance/storage';
|
|
1439
|
+
|
|
1440
|
+
export const selectedCapability = SORT_FIELD;
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1078
1443
|
<a id="forgezero-runtime-realtime"></a>
|
|
1079
1444
|
## @forgezero/runtime/realtime
|
|
1080
1445
|
|
|
@@ -1108,6 +1473,18 @@ import type {
|
|
|
1108
1473
|
} from '@forgezero/runtime/realtime';
|
|
1109
1474
|
```
|
|
1110
1475
|
|
|
1476
|
+
## @forgezero/runtime/realtime — Use this entry point
|
|
1477
|
+
|
|
1478
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1479
|
+
|
|
1480
|
+
```text
|
|
1481
|
+
import {
|
|
1482
|
+
REALTIME_MAX_BATCH_BYTES,
|
|
1483
|
+
} from '@forgezero/runtime/realtime';
|
|
1484
|
+
|
|
1485
|
+
export const selectedCapability = REALTIME_MAX_BATCH_BYTES;
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1111
1488
|
<a id="forgezero-runtime-passkey-hybrid"></a>
|
|
1112
1489
|
## @forgezero/runtime/passkey-hybrid
|
|
1113
1490
|
|
|
@@ -1133,6 +1510,18 @@ import type {
|
|
|
1133
1510
|
} from '@forgezero/runtime/passkey-hybrid';
|
|
1134
1511
|
```
|
|
1135
1512
|
|
|
1513
|
+
## @forgezero/runtime/passkey-hybrid — Use this entry point
|
|
1514
|
+
|
|
1515
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1516
|
+
|
|
1517
|
+
```text
|
|
1518
|
+
import {
|
|
1519
|
+
PASSKEY_HYBRID_SUITE,
|
|
1520
|
+
} from '@forgezero/runtime/passkey-hybrid';
|
|
1521
|
+
|
|
1522
|
+
export const selectedCapability = PASSKEY_HYBRID_SUITE;
|
|
1523
|
+
```
|
|
1524
|
+
|
|
1136
1525
|
<a id="forgezero-runtime-otpauth"></a>
|
|
1137
1526
|
## @forgezero/runtime/otpauth
|
|
1138
1527
|
|
|
@@ -1151,6 +1540,18 @@ import type {
|
|
|
1151
1540
|
} from '@forgezero/runtime/otpauth';
|
|
1152
1541
|
```
|
|
1153
1542
|
|
|
1543
|
+
## @forgezero/runtime/otpauth — Use this entry point
|
|
1544
|
+
|
|
1545
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1546
|
+
|
|
1547
|
+
```text
|
|
1548
|
+
import {
|
|
1549
|
+
formatOtpAuth,
|
|
1550
|
+
} from '@forgezero/runtime/otpauth';
|
|
1551
|
+
|
|
1552
|
+
export const selectedCapability = formatOtpAuth;
|
|
1553
|
+
```
|
|
1554
|
+
|
|
1154
1555
|
<a id="forgezero-runtime-pipeline"></a>
|
|
1155
1556
|
## @forgezero/runtime/pipeline
|
|
1156
1557
|
|
|
@@ -1173,6 +1574,18 @@ import type {
|
|
|
1173
1574
|
} from '@forgezero/runtime/pipeline';
|
|
1174
1575
|
```
|
|
1175
1576
|
|
|
1577
|
+
## @forgezero/runtime/pipeline — Use this entry point
|
|
1578
|
+
|
|
1579
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1580
|
+
|
|
1581
|
+
```text
|
|
1582
|
+
import {
|
|
1583
|
+
GIT_PROVIDERS,
|
|
1584
|
+
} from '@forgezero/runtime/pipeline';
|
|
1585
|
+
|
|
1586
|
+
export const selectedCapability = GIT_PROVIDERS;
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1176
1589
|
<a id="forgezero-runtime-finance-chain-addresses"></a>
|
|
1177
1590
|
## @forgezero/runtime/finance/chain-addresses
|
|
1178
1591
|
|
|
@@ -1198,6 +1611,18 @@ import type {
|
|
|
1198
1611
|
} from '@forgezero/runtime/finance/chain-addresses';
|
|
1199
1612
|
```
|
|
1200
1613
|
|
|
1614
|
+
## @forgezero/runtime/finance/chain-addresses — Use this entry point
|
|
1615
|
+
|
|
1616
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1617
|
+
|
|
1618
|
+
```text
|
|
1619
|
+
import {
|
|
1620
|
+
AddressError,
|
|
1621
|
+
} from '@forgezero/runtime/finance/chain-addresses';
|
|
1622
|
+
|
|
1623
|
+
export const selectedCapability = AddressError;
|
|
1624
|
+
```
|
|
1625
|
+
|
|
1201
1626
|
<a id="forgezero-runtime-finance-chain-deposits"></a>
|
|
1202
1627
|
## @forgezero/runtime/finance/chain-deposits
|
|
1203
1628
|
|
|
@@ -1224,6 +1649,18 @@ import type {
|
|
|
1224
1649
|
} from '@forgezero/runtime/finance/chain-deposits';
|
|
1225
1650
|
```
|
|
1226
1651
|
|
|
1652
|
+
## @forgezero/runtime/finance/chain-deposits — Use this entry point
|
|
1653
|
+
|
|
1654
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1655
|
+
|
|
1656
|
+
```text
|
|
1657
|
+
import {
|
|
1658
|
+
DepositError,
|
|
1659
|
+
} from '@forgezero/runtime/finance/chain-deposits';
|
|
1660
|
+
|
|
1661
|
+
export const selectedCapability = DepositError;
|
|
1662
|
+
```
|
|
1663
|
+
|
|
1227
1664
|
<a id="forgezero-runtime-finance-chain-withdrawals"></a>
|
|
1228
1665
|
## @forgezero/runtime/finance/chain-withdrawals
|
|
1229
1666
|
|
|
@@ -1256,6 +1693,18 @@ import type {
|
|
|
1256
1693
|
} from '@forgezero/runtime/finance/chain-withdrawals';
|
|
1257
1694
|
```
|
|
1258
1695
|
|
|
1696
|
+
## @forgezero/runtime/finance/chain-withdrawals — Use this entry point
|
|
1697
|
+
|
|
1698
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1699
|
+
|
|
1700
|
+
```text
|
|
1701
|
+
import {
|
|
1702
|
+
WITHDRAWAL_STATES,
|
|
1703
|
+
} from '@forgezero/runtime/finance/chain-withdrawals';
|
|
1704
|
+
|
|
1705
|
+
export const selectedCapability = WITHDRAWAL_STATES;
|
|
1706
|
+
```
|
|
1707
|
+
|
|
1259
1708
|
<a id="forgezero-runtime-finance-chain-reconcile"></a>
|
|
1260
1709
|
## @forgezero/runtime/finance/chain-reconcile
|
|
1261
1710
|
|
|
@@ -1279,6 +1728,18 @@ import type {
|
|
|
1279
1728
|
} from '@forgezero/runtime/finance/chain-reconcile';
|
|
1280
1729
|
```
|
|
1281
1730
|
|
|
1731
|
+
## @forgezero/runtime/finance/chain-reconcile — Use this entry point
|
|
1732
|
+
|
|
1733
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1734
|
+
|
|
1735
|
+
```text
|
|
1736
|
+
import {
|
|
1737
|
+
DISCREPANCY_KINDS,
|
|
1738
|
+
} from '@forgezero/runtime/finance/chain-reconcile';
|
|
1739
|
+
|
|
1740
|
+
export const selectedCapability = DISCREPANCY_KINDS;
|
|
1741
|
+
```
|
|
1742
|
+
|
|
1282
1743
|
<a id="forgezero-runtime-finance-market"></a>
|
|
1283
1744
|
## @forgezero/runtime/finance/market
|
|
1284
1745
|
|
|
@@ -1307,6 +1768,18 @@ import type {
|
|
|
1307
1768
|
} from '@forgezero/runtime/finance/market';
|
|
1308
1769
|
```
|
|
1309
1770
|
|
|
1771
|
+
## @forgezero/runtime/finance/market — Use this entry point
|
|
1772
|
+
|
|
1773
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1774
|
+
|
|
1775
|
+
```text
|
|
1776
|
+
import {
|
|
1777
|
+
MarketError,
|
|
1778
|
+
} from '@forgezero/runtime/finance/market';
|
|
1779
|
+
|
|
1780
|
+
export const selectedCapability = MarketError;
|
|
1781
|
+
```
|
|
1782
|
+
|
|
1310
1783
|
<a id="forgezero-runtime-custody-share"></a>
|
|
1311
1784
|
## @forgezero/runtime/custody-share
|
|
1312
1785
|
|
|
@@ -1335,6 +1808,18 @@ import type {
|
|
|
1335
1808
|
} from '@forgezero/runtime/custody-share';
|
|
1336
1809
|
```
|
|
1337
1810
|
|
|
1811
|
+
## @forgezero/runtime/custody-share — Use this entry point
|
|
1812
|
+
|
|
1813
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1814
|
+
|
|
1815
|
+
```text
|
|
1816
|
+
import {
|
|
1817
|
+
PROBE_BYTES,
|
|
1818
|
+
} from '@forgezero/runtime/custody-share';
|
|
1819
|
+
|
|
1820
|
+
export const selectedCapability = PROBE_BYTES;
|
|
1821
|
+
```
|
|
1822
|
+
|
|
1338
1823
|
<a id="forgezero-runtime-custody-crypto"></a>
|
|
1339
1824
|
## @forgezero/runtime/custody-crypto
|
|
1340
1825
|
|
|
@@ -1356,6 +1841,18 @@ import type {
|
|
|
1356
1841
|
} from '@forgezero/runtime/custody-crypto';
|
|
1357
1842
|
```
|
|
1358
1843
|
|
|
1844
|
+
## @forgezero/runtime/custody-crypto — Use this entry point
|
|
1845
|
+
|
|
1846
|
+
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
|
|
1847
|
+
|
|
1848
|
+
```text
|
|
1849
|
+
import {
|
|
1850
|
+
deriveKey,
|
|
1851
|
+
} from '@forgezero/runtime/custody-crypto';
|
|
1852
|
+
|
|
1853
|
+
export const selectedCapability = deriveKey;
|
|
1854
|
+
```
|
|
1855
|
+
|
|
1359
1856
|
## 1. Install, then import a subpath
|
|
1360
1857
|
|
|
1361
1858
|
There is no root export, and that is deliberate. `import from "@forgezero/runtime"` is meant to fail rather than resolve to whichever module happened to be listed first — a bare import that silently works is how a project ends up depending on the whole package to use one function. Every module is its own entry point, so a bundler includes what you imported and nothing else.
|
package/dist/audit.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export interface AuditRecord extends AuditEntry {
|
|
|
74
74
|
/** The previous record's `digest`, or `GENESIS_DIGEST` for the first. */
|
|
75
75
|
previousDigest: string;
|
|
76
76
|
digest: string;
|
|
77
|
+
/** Explicit because one realm may span locked (plain) and unlocked (sealed) periods. */
|
|
78
|
+
digestMode?: 'sha256' | 'hmac-sha256-v1';
|
|
77
79
|
}
|
|
78
80
|
/**
|
|
79
81
|
* The bytes that get hashed.
|
|
@@ -111,6 +113,7 @@ export interface AuditStore {
|
|
|
111
113
|
}
|
|
112
114
|
export interface AppendOptions {
|
|
113
115
|
digester?: Digester;
|
|
116
|
+
digestMode?: AuditRecord['digestMode'];
|
|
114
117
|
now?: () => number;
|
|
115
118
|
}
|
|
116
119
|
/**
|
|
@@ -137,6 +140,12 @@ export interface ChainVerdict {
|
|
|
137
140
|
reason?: AuditChainError['code'];
|
|
138
141
|
message?: string;
|
|
139
142
|
}
|
|
143
|
+
export type AuditDigesterResolver = (record: AuditRecord) => Digester | Promise<Digester>;
|
|
144
|
+
export interface AuditVerifyOptions {
|
|
145
|
+
digester?: Digester;
|
|
146
|
+
digesterForRecord?: AuditDigesterResolver;
|
|
147
|
+
expectGenesis?: boolean;
|
|
148
|
+
}
|
|
140
149
|
/**
|
|
141
150
|
* Walk a chain and report the FIRST break.
|
|
142
151
|
*
|
|
@@ -150,10 +159,7 @@ export interface ChainVerdict {
|
|
|
150
159
|
* predecessor; a full chain that does not start at genesis has been truncated
|
|
151
160
|
* from the front, which is exactly the deletion this is meant to catch.
|
|
152
161
|
*/
|
|
153
|
-
export declare function verifyChain(records: readonly AuditRecord[], options?:
|
|
154
|
-
digester?: Digester;
|
|
155
|
-
expectGenesis?: boolean;
|
|
156
|
-
}): Promise<ChainVerdict>;
|
|
162
|
+
export declare function verifyChain(records: readonly AuditRecord[], options?: AuditVerifyOptions): Promise<ChainVerdict>;
|
|
157
163
|
export interface AuditExport {
|
|
158
164
|
realm?: string;
|
|
159
165
|
fromSequence: number;
|
|
@@ -181,7 +187,7 @@ export declare function exportRange(store: AuditStore, args: {
|
|
|
181
187
|
realm?: string;
|
|
182
188
|
fromSequence: number;
|
|
183
189
|
toSequence: number;
|
|
184
|
-
}, options?: AppendOptions): Promise<AuditExport>;
|
|
190
|
+
}, options?: AppendOptions & Pick<AuditVerifyOptions, 'digesterForRecord'>): Promise<AuditExport>;
|
|
185
191
|
/**
|
|
186
192
|
* Check an export against the anchor somebody kept.
|
|
187
193
|
*
|
|
@@ -192,6 +198,7 @@ export declare function exportRange(store: AuditStore, args: {
|
|
|
192
198
|
*/
|
|
193
199
|
export declare function verifyExport(slice: AuditExport, options?: {
|
|
194
200
|
digester?: Digester;
|
|
201
|
+
digesterForRecord?: AuditDigesterResolver;
|
|
195
202
|
expectSealDigest?: string;
|
|
196
203
|
}): Promise<ChainVerdict>;
|
|
197
204
|
/**
|
|
@@ -215,6 +222,15 @@ export interface EffectAuditRecord {
|
|
|
215
222
|
}
|
|
216
223
|
export interface AuditChainOptions extends AppendOptions {
|
|
217
224
|
store: AuditStore;
|
|
225
|
+
/** Selects a digest at append time, allowing locked/plain and unlocked/sealed records in one chain. */
|
|
226
|
+
digesterForEntry?: (entry: AuditEntry) => Promise<Required<Pick<AppendOptions, 'digester' | 'digestMode'>>>;
|
|
227
|
+
/** Selects the verifier from the record's authenticated mode marker. */
|
|
228
|
+
digesterForRecord?: AuditDigesterResolver;
|
|
229
|
+
/** Retry only a store-declared optimistic sequence collision, never arbitrary failures. */
|
|
230
|
+
retryAppend?: {
|
|
231
|
+
attempts: number;
|
|
232
|
+
conflict(error: unknown): boolean;
|
|
233
|
+
};
|
|
218
234
|
/** Called when an append fails. Silence here is how a trail dies unnoticed. */
|
|
219
235
|
onError?: (error: unknown, entry: AuditEntry) => void;
|
|
220
236
|
}
|
package/dist/audit.js
CHANGED
|
@@ -323,7 +323,7 @@ class AuditChainError extends Error {
|
|
|
323
323
|
var GENESIS_DIGEST = "0".repeat(64);
|
|
324
324
|
function canonicalise(record) {
|
|
325
325
|
const detail = record.detail ? Object.keys(record.detail).sort().map((key) => `${key}=${String(record.detail[key])}`).join("\x1F") : "";
|
|
326
|
-
|
|
326
|
+
const fields = [
|
|
327
327
|
record.sequence,
|
|
328
328
|
record.previousDigest,
|
|
329
329
|
record.atMs,
|
|
@@ -335,7 +335,10 @@ function canonicalise(record) {
|
|
|
335
335
|
record.targetKey ?? "",
|
|
336
336
|
record.reason ?? "",
|
|
337
337
|
detail
|
|
338
|
-
]
|
|
338
|
+
];
|
|
339
|
+
if (record.digestMode !== undefined)
|
|
340
|
+
fields.push(record.digestMode);
|
|
341
|
+
return fields.join("\x1E");
|
|
339
342
|
}
|
|
340
343
|
var hashDigester = (input) => sha256(input);
|
|
341
344
|
var sealedDigester = (key) => {
|
|
@@ -351,7 +354,8 @@ async function appendRecord(store, entry, options = {}) {
|
|
|
351
354
|
...entry,
|
|
352
355
|
sequence: (previous?.sequence ?? 0) + 1,
|
|
353
356
|
atMs: (options.now ?? Date.now)(),
|
|
354
|
-
previousDigest: previous?.digest ?? GENESIS_DIGEST
|
|
357
|
+
previousDigest: previous?.digest ?? GENESIS_DIGEST,
|
|
358
|
+
...options.digestMode ? { digestMode: options.digestMode } : {}
|
|
355
359
|
};
|
|
356
360
|
const record = { ...unsigned, digest: await digester(canonicalise(unsigned)) };
|
|
357
361
|
await store.append(record);
|
|
@@ -393,7 +397,8 @@ async function verifyChain(records, options = {}) {
|
|
|
393
397
|
};
|
|
394
398
|
}
|
|
395
399
|
}
|
|
396
|
-
const
|
|
400
|
+
const recordDigester = options.digesterForRecord ? await options.digesterForRecord(record) : digester;
|
|
401
|
+
const expected = await recordDigester(canonicalise(record));
|
|
397
402
|
if (!timingSafeEqual(expected, record.digest)) {
|
|
398
403
|
return {
|
|
399
404
|
ok: false,
|
|
@@ -418,6 +423,7 @@ async function exportRange(store, args, options = {}) {
|
|
|
418
423
|
}
|
|
419
424
|
const verdict = await verifyChain(records, {
|
|
420
425
|
digester,
|
|
426
|
+
digesterForRecord: options.digesterForRecord,
|
|
421
427
|
expectGenesis: args.fromSequence <= 1
|
|
422
428
|
});
|
|
423
429
|
if (!verdict.ok) {
|
|
@@ -437,6 +443,7 @@ async function verifyExport(slice, options = {}) {
|
|
|
437
443
|
const digester = options.digester ?? hashDigester;
|
|
438
444
|
const verdict = await verifyChain(slice.records, {
|
|
439
445
|
digester,
|
|
446
|
+
digesterForRecord: options.digesterForRecord,
|
|
440
447
|
expectGenesis: slice.anchorDigest === GENESIS_DIGEST
|
|
441
448
|
});
|
|
442
449
|
if (!verdict.ok)
|
|
@@ -475,13 +482,30 @@ function createAuditChain(options) {
|
|
|
475
482
|
const digester = options.digester ?? hashDigester;
|
|
476
483
|
const queue = createQueue();
|
|
477
484
|
const enqueue = (realm, run) => queue.run(realm ?? "\x00platform", run).result;
|
|
485
|
+
const append = (entry) => enqueue(entry.realm, async () => {
|
|
486
|
+
const attempts = Math.max(1, Math.min(options.retryAppend?.attempts ?? 1, 32));
|
|
487
|
+
for (let attempt = 0;attempt < attempts; attempt += 1) {
|
|
488
|
+
const selected = options.digesterForEntry ? await options.digesterForEntry(entry) : { digester, digestMode: options.digestMode };
|
|
489
|
+
try {
|
|
490
|
+
return await appendRecord(options.store, entry, { ...options, ...selected });
|
|
491
|
+
} catch (error) {
|
|
492
|
+
if (attempt + 1 >= attempts || !options.retryAppend?.conflict(error))
|
|
493
|
+
throw error;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
throw new Error("audit: append retry exhausted");
|
|
497
|
+
});
|
|
478
498
|
return {
|
|
479
|
-
append
|
|
499
|
+
append,
|
|
480
500
|
verify: async (realm, fromSequence = 1, toSequence = Number.MAX_SAFE_INTEGER) => {
|
|
481
501
|
const records = await options.store.range(realm, fromSequence, toSequence);
|
|
482
|
-
return verifyChain(records, {
|
|
502
|
+
return verifyChain(records, {
|
|
503
|
+
digester,
|
|
504
|
+
digesterForRecord: options.digesterForRecord,
|
|
505
|
+
expectGenesis: fromSequence <= 1
|
|
506
|
+
});
|
|
483
507
|
},
|
|
484
|
-
export: (args) => exportRange(options.store, args, { ...options, digester }),
|
|
508
|
+
export: (args) => exportRange(options.store, args, { ...options, digester, digesterForRecord: options.digesterForRecord }),
|
|
485
509
|
sink: {
|
|
486
510
|
write(record) {
|
|
487
511
|
const entry = {
|
|
@@ -498,7 +522,7 @@ function createAuditChain(options) {
|
|
|
498
522
|
},
|
|
499
523
|
...record.outcome === "denied" && record.code ? { reason: record.code } : {}
|
|
500
524
|
};
|
|
501
|
-
|
|
525
|
+
append(entry).catch((error) => options.onError?.(error, entry));
|
|
502
526
|
}
|
|
503
527
|
}
|
|
504
528
|
};
|
package/dist/jobs.d.ts
CHANGED
|
@@ -85,6 +85,13 @@ export interface JobContext {
|
|
|
85
85
|
holdsLock(): Promise<boolean>;
|
|
86
86
|
log(message: string, detail?: Record<string, unknown>): void;
|
|
87
87
|
}
|
|
88
|
+
export declare class JobFenceLostError extends Error {
|
|
89
|
+
constructor();
|
|
90
|
+
}
|
|
91
|
+
/** Check/renew the distributed fence immediately before one mutation. */
|
|
92
|
+
export declare function withJobFence<T>(context: JobContext, mutate: () => Promise<T>): Promise<T>;
|
|
93
|
+
/** Sequential mutation helper; a lost fence stops before the next item is touched. */
|
|
94
|
+
export declare function forEachFenced<T>(context: JobContext, items: Iterable<T>, mutate: (item: T, index: number) => Promise<void>): Promise<void>;
|
|
88
95
|
export interface JobResult {
|
|
89
96
|
/** A resolved run may still report an operational failure without throwing. */
|
|
90
97
|
ok?: boolean;
|
package/dist/jobs.js
CHANGED
|
@@ -410,6 +410,27 @@ function storeLock(store, clock = systemClock) {
|
|
|
410
410
|
release: (key, fence) => store.clear(key, fence)
|
|
411
411
|
};
|
|
412
412
|
}
|
|
413
|
+
|
|
414
|
+
class JobFenceLostError extends Error {
|
|
415
|
+
constructor() {
|
|
416
|
+
super("job: distributed lease was lost; refusing further mutation");
|
|
417
|
+
this.name = "JobFenceLostError";
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function withJobFence(context, mutate) {
|
|
421
|
+
if (context.signal.aborted)
|
|
422
|
+
throw context.signal.reason ?? new Error("job: aborted");
|
|
423
|
+
if (!await context.holdsLock())
|
|
424
|
+
throw new JobFenceLostError;
|
|
425
|
+
return mutate();
|
|
426
|
+
}
|
|
427
|
+
async function forEachFenced(context, items, mutate) {
|
|
428
|
+
let index = 0;
|
|
429
|
+
for (const item of items) {
|
|
430
|
+
await withJobFence(context, () => mutate(item, index));
|
|
431
|
+
index += 1;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
413
434
|
function defineJob(spec) {
|
|
414
435
|
if (!spec.key.trim())
|
|
415
436
|
throw new Error("A job needs a key — it is the lock key and the report key.");
|
|
@@ -460,12 +481,29 @@ function createScheduler(options) {
|
|
|
460
481
|
const report = reports.get(job.key);
|
|
461
482
|
const leaseMs = job.leaseMs ?? (job.every ? everyMs(job.every) * 4 : 60000);
|
|
462
483
|
let lease;
|
|
484
|
+
let leaseHeld = true;
|
|
485
|
+
let renewTimer;
|
|
463
486
|
if (!job.unlocked) {
|
|
464
487
|
lease = await lock.acquire(job.key, leaseMs);
|
|
465
488
|
if (!lease) {
|
|
466
489
|
report.skippedLocked += 1;
|
|
467
490
|
return;
|
|
468
491
|
}
|
|
492
|
+
const renewEveryMs = Math.max(1, Math.floor(leaseMs / 3));
|
|
493
|
+
const scheduleRenewal = () => {
|
|
494
|
+
renewTimer = setTimeout(async () => {
|
|
495
|
+
if (!lease || !leaseHeld)
|
|
496
|
+
return;
|
|
497
|
+
try {
|
|
498
|
+
leaseHeld = await lock.renew(job.key, lease.fence, leaseMs);
|
|
499
|
+
} catch {
|
|
500
|
+
leaseHeld = false;
|
|
501
|
+
}
|
|
502
|
+
if (leaseHeld)
|
|
503
|
+
scheduleRenewal();
|
|
504
|
+
}, renewEveryMs);
|
|
505
|
+
};
|
|
506
|
+
scheduleRenewal();
|
|
469
507
|
}
|
|
470
508
|
report.state = "running";
|
|
471
509
|
report.lastStartedAtMs = clock.now();
|
|
@@ -473,7 +511,18 @@ function createScheduler(options) {
|
|
|
473
511
|
try {
|
|
474
512
|
const result = await job.run({
|
|
475
513
|
signal: controller.signal,
|
|
476
|
-
holdsLock: async () =>
|
|
514
|
+
holdsLock: async () => {
|
|
515
|
+
if (!lease)
|
|
516
|
+
return true;
|
|
517
|
+
if (!leaseHeld)
|
|
518
|
+
return false;
|
|
519
|
+
try {
|
|
520
|
+
leaseHeld = await lock.renew(job.key, lease.fence, leaseMs);
|
|
521
|
+
} catch {
|
|
522
|
+
leaseHeld = false;
|
|
523
|
+
}
|
|
524
|
+
return leaseHeld;
|
|
525
|
+
},
|
|
477
526
|
log: (message, detail) => options.onLog?.(job.key, message, detail)
|
|
478
527
|
});
|
|
479
528
|
report.lastResult = result ?? undefined;
|
|
@@ -491,6 +540,8 @@ function createScheduler(options) {
|
|
|
491
540
|
report.consecutiveFailures += 1;
|
|
492
541
|
options.onError?.(job.key, error);
|
|
493
542
|
} finally {
|
|
543
|
+
if (renewTimer)
|
|
544
|
+
clearTimeout(renewTimer);
|
|
494
545
|
report.runs += 1;
|
|
495
546
|
report.lastFinishedAtMs = clock.now();
|
|
496
547
|
report.lastDurationMs = clock.now() - startedAt;
|
|
@@ -644,13 +695,16 @@ function cursorJob(spec) {
|
|
|
644
695
|
}
|
|
645
696
|
var VERSION = "0.1.0";
|
|
646
697
|
export {
|
|
698
|
+
withJobFence,
|
|
647
699
|
systemClock,
|
|
648
700
|
storeLock,
|
|
649
701
|
nextWallClockAt,
|
|
650
702
|
memoryLock,
|
|
703
|
+
forEachFenced,
|
|
651
704
|
everyMs,
|
|
652
705
|
defineJob,
|
|
653
706
|
cursorJob,
|
|
654
707
|
createScheduler,
|
|
655
|
-
VERSION
|
|
708
|
+
VERSION,
|
|
709
|
+
JobFenceLostError
|
|
656
710
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgezero/runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
"prepublishOnly": "bun ../tools/package-task.ts prepublish runtime"
|
|
191
191
|
},
|
|
192
192
|
"dependencies": {
|
|
193
|
-
"@forgezero/access": "^0.1.
|
|
193
|
+
"@forgezero/access": "^0.1.7"
|
|
194
194
|
},
|
|
195
195
|
"peerDependencies": {
|
|
196
196
|
"@noble/ciphers": "^2.2.0",
|