@byok-sdk/cloud 0.1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/dist/auth/bearer.d.ts +25 -0
  4. package/dist/auth/device-proof.d.ts +38 -0
  5. package/dist/auth/plane.d.ts +67 -0
  6. package/dist/auth/tokens.d.ts +37 -0
  7. package/dist/auth/verify.d.ts +22 -0
  8. package/dist/board-projection.d.ts +9 -0
  9. package/dist/capabilities.d.ts +71 -0
  10. package/dist/cloud.d.ts +123 -0
  11. package/dist/composition/in-memory.d.ts +55 -0
  12. package/dist/coordination-client.d.ts +87 -0
  13. package/dist/coordination.d.ts +29 -0
  14. package/dist/crypto/port.d.ts +44 -0
  15. package/dist/crypto/web-crypto.d.ts +28 -0
  16. package/dist/errors.d.ts +45 -0
  17. package/dist/handlers/auth.d.ts +21 -0
  18. package/dist/handlers/blobs.d.ts +39 -0
  19. package/dist/handlers/board.d.ts +21 -0
  20. package/dist/handlers/capabilities.d.ts +14 -0
  21. package/dist/handlers/events.d.ts +33 -0
  22. package/dist/handlers/messages.d.ts +28 -0
  23. package/dist/handlers/presence.d.ts +13 -0
  24. package/dist/handlers/shared.d.ts +30 -0
  25. package/dist/handlers/truth.d.ts +15 -0
  26. package/dist/inbound.d.ts +35 -0
  27. package/dist/index.d.ts +57 -0
  28. package/dist/index.js +2419 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/router/registry.d.ts +56 -0
  31. package/dist/stores/in-memory/blobs.d.ts +89 -0
  32. package/dist/stores/in-memory/dedup.d.ts +17 -0
  33. package/dist/stores/in-memory/device-directory.d.ts +19 -0
  34. package/dist/stores/in-memory/index.d.ts +36 -0
  35. package/dist/stores/in-memory/nonces.d.ts +22 -0
  36. package/dist/stores/in-memory/pairing-codes.d.ts +18 -0
  37. package/dist/stores/in-memory/proof-receipts.d.ts +11 -0
  38. package/dist/stores/in-memory/rate-limiter.d.ts +13 -0
  39. package/dist/stores/in-memory/receipts.d.ts +21 -0
  40. package/dist/stores/in-memory/sequence.d.ts +11 -0
  41. package/dist/stores/in-memory/task-attempts.d.ts +36 -0
  42. package/dist/stores/ports-contract.d.ts +20 -0
  43. package/dist/stores/ports.d.ts +309 -0
  44. package/dist/tenant-stores.d.ts +124 -0
  45. package/dist/truth/contract.d.ts +149 -0
  46. package/dist/truth/errors.d.ts +8 -0
  47. package/package.json +52 -0
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The reference {@link CloudCrypto}, built entirely on the WebCrypto API that
3
+ * Node >=20, Cloudflare Workers, and Deno all expose as `globalThis.crypto`.
4
+ *
5
+ * No `node:crypto`, no dependency: the point of the port is that a hosted
6
+ * composition stays runtime-neutral, and an adapter that reached for a Node
7
+ * built-in here would make that claim false for the default composition.
8
+ */
9
+ import type { CloudCrypto } from './port';
10
+ export declare function base64UrlEncode(bytes: Uint8Array): string;
11
+ /**
12
+ * Decode base64url. Returns `undefined` rather than throwing for input that
13
+ * is not base64url at all — every caller here is verifying attacker-supplied
14
+ * material, where "not decodable" and "does not verify" must be the same
15
+ * answer.
16
+ */
17
+ export declare function base64UrlDecode(value: string): Uint8Array | undefined;
18
+ /**
19
+ * WebCrypto's own types are derived from the runtime's `globalThis.crypto`
20
+ * rather than named directly: `CryptoKey`/`SubtleCrypto`/`KeyUsage` are DOM
21
+ * lib globals, and this package compiles without the DOM lib (a Workers build
22
+ * has no DOM either). Deriving keeps the types exact without pulling in a
23
+ * `node:` import or widening `lib`.
24
+ */
25
+ export type SubtleCryptoLike = typeof globalThis.crypto.subtle;
26
+ export type CryptoKeyLike = Awaited<ReturnType<SubtleCryptoLike['importKey']>>;
27
+ export type KeyUsageLike = Parameters<SubtleCryptoLike['importKey']>[4][number];
28
+ export declare function createWebCrypto(): CloudCrypto;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The one error taxonomy for `@byok-sdk/cloud`.
3
+ *
4
+ * Same idiom as `@byok-sdk/core`'s `errors.ts`: one class, code-based branching,
5
+ * so a composition maps failures onto HTTP with a code table instead of an
6
+ * `instanceof` chain. Cloud does not re-export core's codes — a cloud error is
7
+ * about the hosted surface (a store contract the composition broke, a
8
+ * declaration the host mis-configured), and core errors travel up unchanged.
9
+ */
10
+ export declare const CLOUD_ERROR_CODES: {
11
+ /** A pairing code that is unknown, expired, or already redeemed (§6.1). */
12
+ readonly pairing_code_invalid: 'pairing_code_invalid';
13
+ /** The composition handed a device row whose tenant is not a mintable `TenantId`. */
14
+ readonly device_tenant_invalid: 'device_tenant_invalid';
15
+ /**
16
+ * The mailbox assigned a row `seq` that disagrees with the delivery `seq`
17
+ * baked into the enqueued envelope. Loud rather than silent: those two
18
+ * numbers ARE the daemon's redelivery cursor, and a composition whose
19
+ * mailbox numbers rows differently from `DeviceSequenceStore` would
20
+ * mis-deliver every subsequent poll.
21
+ */
22
+ readonly mailbox_seq_mismatch: 'mailbox_seq_mismatch';
23
+ /** A capability declaration the host supplied that core refused. */
24
+ readonly capability_declaration_invalid: 'capability_declaration_invalid';
25
+ /**
26
+ * The declaration names a capability this composition cannot serve, so the
27
+ * deployment would publish a surface it does not have (ADR-010).
28
+ *
29
+ * Construction-time and fatal. A client learns what a deployment supports by
30
+ * READING the declaration and is entitled to act on it without probing, so a
31
+ * declaration that over-states is not a degraded deployment — it is a
32
+ * deployment whose one honest interface lies.
33
+ */
34
+ readonly capability_over_declared: 'capability_over_declared';
35
+ /** Host-supplied board labels or coordination input exceeded the explicit contract. */
36
+ readonly coordination_input_invalid: 'coordination_input_invalid';
37
+ /** A progress/activity batch exceeded the configured event or byte ceiling. */
38
+ readonly activity_batch_too_large: 'activity_batch_too_large';
39
+ };
40
+ export type CloudErrorCode = (typeof CLOUD_ERROR_CODES)[keyof typeof CLOUD_ERROR_CODES];
41
+ export declare class ByokCloudError extends Error {
42
+ readonly code: CloudErrorCode;
43
+ constructor(code: CloudErrorCode, message: string, options?: ErrorOptions);
44
+ }
45
+ export declare function isCloudError(value: unknown, code?: CloudErrorCode): value is ByokCloudError;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auth v2 (docs/protocol.md §6): pair, challenge, token.
3
+ *
4
+ * Byte-for-byte the same request/response DTOs the daemon already speaks,
5
+ * because they come from `@byok-sdk/protocol` rather than from a hosted copy of
6
+ * them. The behavior differences a hosted surface DOES make are two, both
7
+ * narrowing:
8
+ *
9
+ * - a pairing code that is unknown, expired, or already used gets one 401 with
10
+ * one message (the reference server names the reason);
11
+ * - an unknown device and a revoked device were already indistinguishable on
12
+ * the reference server, and stay so here.
13
+ */
14
+ import type { Context } from 'hono';
15
+ import type { AuthPlane } from '../auth/plane';
16
+ export interface AuthRouteDeps {
17
+ readonly auth: AuthPlane;
18
+ }
19
+ export declare function pairHandler(deps: AuthRouteDeps): (c: Context) => Promise<Response>;
20
+ export declare function challengeHandler(deps: AuthRouteDeps): (c: Context) => Promise<Response>;
21
+ export declare function tokenHandler(deps: AuthRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Blob flows (§7).
3
+ *
4
+ * Two route classes on purpose: `POST /byok/blobs` and `GET
5
+ * /byok/blobs/:id/url` are bearer-authed and therefore tenant-closed (a
6
+ * download URL is minted only for a blob the caller's own tenant owns, and a
7
+ * foreign blob is indistinguishable from a missing one); the two `/content`
8
+ * routes are presigned, because they are meant to be hit directly — by a
9
+ * browser, by a `PUT` from a daemon that holds only the signed URL — with no
10
+ * JWT in scope at all. The HMAC signature over the blob id plus its expiry IS
11
+ * the credential there, which is why those two carry the `presigned` class in
12
+ * the route inventory rather than being lumped in with the device routes.
13
+ *
14
+ * The split runs all the way down: the bearer-authed pair reaches blobs only
15
+ * through the tenant facade and never holds a naked store, and the presigned
16
+ * pair holds only a {@link BlobContentProxy} and no bearer deps. A composition
17
+ * without a proxy does not mount them (`cloud.ts`).
18
+ */
19
+ import type { Context } from 'hono';
20
+ import type { BlobContentProxy } from '../stores/ports';
21
+ import { type DeviceRouteDeps } from './shared';
22
+ /** The three bearer-authed routes: everything they touch goes through the tenant facade. */
23
+ export interface BlobRouteDeps extends DeviceRouteDeps {
24
+ readonly maxBlobSizeBytes: number;
25
+ }
26
+ /** Reservation and presign grants deliberately share one expiry horizon. */
27
+ export declare const BLOB_RESERVATION_TTL_MS: number;
28
+ /**
29
+ * The two presigned routes. No bearer deps at all — there is no principal to
30
+ * build a facade from, and the proxy is the only thing they need.
31
+ */
32
+ export interface BlobContentRouteDeps {
33
+ readonly contentProxy: BlobContentProxy;
34
+ }
35
+ export declare function createBlobHandler(deps: BlobRouteDeps): (c: Context) => Promise<Response>;
36
+ export declare function finalizeBlobHandler(deps: BlobRouteDeps): (c: Context) => Promise<Response>;
37
+ export declare function blobDownloadUrlHandler(deps: BlobRouteDeps): (c: Context) => Promise<Response>;
38
+ export declare function blobUploadContentHandler(deps: BlobContentRouteDeps): (c: Context) => Promise<Response>;
39
+ export declare function blobDownloadContentHandler(deps: BlobContentRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,21 @@
1
+ import { type BoardPage } from '@byok-sdk/core';
2
+ import type { Context } from 'hono';
3
+ import { type DeviceRouteDeps } from './shared';
4
+ export declare const DEFAULT_BOARD_PAGE_LIMIT = 50;
5
+ export declare const DEFAULT_BOARD_STREAM_QUERY_INTERVAL_MS = 5000;
6
+ export declare const DEFAULT_BOARD_STREAM_HEARTBEAT_INTERVAL_MS = 15000;
7
+ export declare const DEFAULT_BOARD_STREAM_RECONCILIATION_INTERVAL_MS = 120000;
8
+ export interface BoardRouteDeps extends DeviceRouteDeps {
9
+ readonly pageLimit: number;
10
+ }
11
+ export interface BoardStreamRouteDeps extends BoardRouteDeps {
12
+ readonly queryIntervalMs: number;
13
+ readonly heartbeatIntervalMs: number;
14
+ readonly reconciliationIntervalMs: number;
15
+ }
16
+ export declare function boardListHandler(deps: BoardRouteDeps): (c: Context) => Promise<Response>;
17
+ export declare function boardClaimHandler(deps: DeviceRouteDeps): (c: Context) => Promise<Response>;
18
+ export declare function boardUnclaimHandler(deps: DeviceRouteDeps): (c: Context) => Promise<Response>;
19
+ export declare function boardStatusHandler(deps: DeviceRouteDeps): (c: Context) => Promise<Response>;
20
+ export declare function boardStreamHandler(deps: BoardStreamRouteDeps): (c: Context) => Promise<Response>;
21
+ export type BoardPollResponse = BoardPage;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `GET /byok/capabilities` — the declaration route (ADR-010).
3
+ *
4
+ * Public by design: a client has to be able to read what a deployment supports
5
+ * before it holds a credential, and the declaration is a deployment-level
6
+ * fact, not a tenant-level one. Nothing tenant-scoped may ever be added to
7
+ * this response for exactly that reason.
8
+ */
9
+ import type { Context } from 'hono';
10
+ import type { CapabilityDeclaration } from '@byok-sdk/core';
11
+ export interface CapabilitiesRouteDeps {
12
+ readonly declaration: CapabilityDeclaration;
13
+ }
14
+ export declare function capabilitiesHandler(deps: CapabilitiesRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * `GET /byok/events?cursor=N` — the long-poll receive half (§8).
3
+ *
4
+ * Three properties the daemon's transport depends on, reproduced against the
5
+ * core mailbox rather than an in-process outbox:
6
+ *
7
+ * - **Reading is not acknowledging.** `readAfter` never moves the cursor. The
8
+ * ONLY ack is the cursor the daemon brings back on its NEXT poll, after it
9
+ * has durably processed what it was handed — which is why the ack below
10
+ * happens before the read, against the incoming `cursor`, and why a poll
11
+ * that hands back the same cursor replays the same page forever.
12
+ * - **The ack is monotonic.** A cursor at or below what the device already
13
+ * acked carries no new information and is not an ack attempt; only a
14
+ * strictly higher one advances. The store's own
15
+ * `mailbox_cursor_regression` guard stays the authority on going backwards
16
+ * (asserted directly in `src/__tests__/mailbox-cursor.test.ts`).
17
+ * - **The hold.** An empty poll is held open instead of answered immediately,
18
+ * so an idle daemon is not a busy-loop. The hold is a bounded re-read, not a
19
+ * registered waiter: a waiter map is exactly the cross-request state a
20
+ * stateless handler may not keep (S3.5 boxes 14-15), and a second cloud
21
+ * instance would not see it anyway.
22
+ */
23
+ import type { Context } from 'hono';
24
+ import { type DeviceRouteDeps } from './shared';
25
+ export interface EventsRouteDeps extends DeviceRouteDeps {
26
+ /** How long an empty poll is held open, ms. */
27
+ readonly longPollHoldMs: number;
28
+ /** How often the mailbox is re-read while holding, ms. */
29
+ readonly longPollIntervalMs: number;
30
+ /** Max rows per response. */
31
+ readonly pageLimit: number;
32
+ }
33
+ export declare function eventsHandler(deps: EventsRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `POST /byok/messages` — the long-poll send half (§8.2).
3
+ *
4
+ * A device long-polling for cloud -> daemon traffic has no live socket to
5
+ * carry its own outbound envelopes; this batches them over authed HTTP. Every
6
+ * envelope goes through the same gate (`../inbound.ts`) in the same order, so
7
+ * claim/progress/complete behave identically no matter which transport carried
8
+ * them.
9
+ *
10
+ * The batch stays tolerant at the schema level — one malformed envelope must
11
+ * not 400 the whole request — so only a structurally invalid `Envelope` or an
12
+ * oversized batch (`MAX_MESSAGES_PER_BATCH`) fails the request outright.
13
+ *
14
+ * Rate limiting is per REQUEST, not per envelope: the moment any envelope
15
+ * comes back `rate_limited`, the rest of the batch is abandoned (its bucket is
16
+ * empty, so every remaining envelope would limit too) and the WHOLE request
17
+ * answers 429. Envelopes processed earlier in the same batch already took
18
+ * effect — there are no rollback semantics here — which is safe because every
19
+ * `task.*` type is idempotent (§9): a client that retries the same batch gets
20
+ * `duplicate` for whatever already landed.
21
+ */
22
+ import type { Context } from 'hono';
23
+ import type { ActivityBounds } from '../coordination';
24
+ import { type DeviceRouteDeps } from './shared';
25
+ export interface MessagesRouteDeps extends DeviceRouteDeps {
26
+ readonly activityBounds: ActivityBounds;
27
+ }
28
+ export declare function messagesHandler(deps: MessagesRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,13 @@
1
+ import type { Context } from 'hono';
2
+ import { type ActivityBounds } from '../coordination';
3
+ import { type DeviceRouteDeps } from './shared';
4
+ export interface PresenceRouteDeps extends DeviceRouteDeps {
5
+ readonly ttlMs: number;
6
+ readonly minimumIntervalMs: number;
7
+ readonly detailMaxBytes: number;
8
+ }
9
+ export interface ActivityRouteDeps extends DeviceRouteDeps {
10
+ readonly bounds: ActivityBounds;
11
+ }
12
+ export declare function presencePublishHandler(deps: PresenceRouteDeps): (c: Context) => Promise<Response>;
13
+ export declare function activityAppendHandler(deps: ActivityRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The two things every device-facing handler starts from: a tolerant JSON body
3
+ * read, and the bearer -> principal -> tenant-closed-facade step.
4
+ *
5
+ * Once {@link authenticateDevice} has answered, a handler holds a
6
+ * `TenantStores` and a `DevicePrincipal` and never sees a `TenantId` again.
7
+ */
8
+ import type { Context } from 'hono';
9
+ import type { DevicePrincipal } from '@byok-sdk/core';
10
+ import { type BearerAuthDeps } from '../auth/bearer';
11
+ import { type CloudRootStores, type TenantStores } from '../tenant-stores';
12
+ /** Every error response on this surface is `{ error }` — the same shape the reference server uses. */
13
+ export interface ErrorBody {
14
+ readonly error: string;
15
+ }
16
+ export declare function readJsonBody(c: Context): Promise<unknown>;
17
+ export interface DeviceRouteDeps {
18
+ readonly bearer: BearerAuthDeps;
19
+ readonly root: CloudRootStores;
20
+ }
21
+ export interface AuthenticatedDeviceContext {
22
+ readonly device: DevicePrincipal;
23
+ readonly stores: TenantStores;
24
+ }
25
+ /**
26
+ * `undefined` means "answer 401" — and it means that for a missing header, a
27
+ * forged token, an expired token, a revoked device, a product mismatch, and a
28
+ * token whose tenant does not own the device, indistinguishably.
29
+ */
30
+ export declare function authenticateDevice(c: Context, deps: DeviceRouteDeps): Promise<AuthenticatedDeviceContext | undefined>;
@@ -0,0 +1,15 @@
1
+ import type { Context } from 'hono';
2
+ import { type DeviceProofAuthDeps } from '../auth/device-proof';
3
+ import { type TruthCommitter, type TruthObjectDownloads } from '../truth/contract';
4
+ export declare const DEVICE_PROOF_HEADER = "x-byok-device-proof";
5
+ export declare const DEFAULT_MAX_TRUTH_REQUEST_BYTES: number;
6
+ export declare const MAX_DEVICE_PROOF_HEADER_BYTES: number;
7
+ export interface TruthRouteDeps {
8
+ readonly proof: DeviceProofAuthDeps;
9
+ readonly truth: TruthCommitter;
10
+ readonly objectDownloads: TruthObjectDownloads;
11
+ readonly maxRequestBytes: number;
12
+ }
13
+ export declare function truthManifestHandler(deps: TruthRouteDeps): (c: Context) => Promise<Response>;
14
+ export declare function truthGetHandler(deps: TruthRouteDeps): (c: Context) => Promise<Response>;
15
+ export declare function truthPutHandler(deps: TruthRouteDeps): (c: Context) => Promise<Response>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The single inbound choke point for every daemon -> cloud envelope.
3
+ *
4
+ * The reference server runs this gate inside a live `ConnectionHub`; here it
5
+ * is a pure function over a tenant-closed facade, so the same order holds with
6
+ * no connection, no session, and no cross-request state:
7
+ *
8
+ * 0. **rate limit** — one token per inbound envelope, debited BEFORE anything
9
+ * else, so a flood of garbage-typed envelopes costs the same budget as a
10
+ * flood of well-formed ones. S3a's reference limiter allows everything; the
11
+ * seam is what matters at this position.
12
+ * 1. **type-allow** — only `DAEMON_TO_SERVER_TYPES` may pass. A server ->
13
+ * daemon type arriving inbound, or anything unrecognized, is rejected
14
+ * before it is dispatched or counted accepted.
15
+ * 2. **ownership** — an envelope for a task already owned by a DIFFERENT
16
+ * device is dropped, never force-failed: force-failing on an authz mismatch
17
+ * would let an attacker who merely guesses a `taskId` kill the real owner's
18
+ * task. A task with no owner yet, or that this tenant does not have at all,
19
+ * is not rejected here — the store's own no-op-on-missing behavior covers
20
+ * the latter, and it covers it per tenant, so a guessed id from another
21
+ * tenant writes nothing anywhere.
22
+ * 3. **dedup** — an envelope id already seen from this device is a no-op. The
23
+ * wire is at-least-once (§9); this makes processing at-most-once.
24
+ * 4. **apply** — the lifecycle write.
25
+ *
26
+ * A duplicate is still a wire-level success (§8.2): it just did not re-run
27
+ * anything. Only `rejected`/`rate_limited` are excluded from `accepted`.
28
+ */
29
+ import { type Envelope } from '@byok-sdk/protocol';
30
+ import { type ActivityBounds } from './coordination';
31
+ import type { TenantStores } from './tenant-stores';
32
+ export type InboundOutcome = 'accepted' | 'duplicate' | 'rejected' | 'rate_limited';
33
+ /** Receipt key a task's terminal is recorded under — the idempotency seam S3b's journal will share. */
34
+ export declare function terminalReceiptKey(taskId: string): string;
35
+ export declare function handleInboundEnvelope(stores: TenantStores, deviceId: string, envelope: Envelope, activityBounds?: ActivityBounds): Promise<InboundOutcome>;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * `@byok-sdk/cloud` — the hosted device surface.
3
+ *
4
+ * Cloud sits BESIDE `@byok-sdk/server`, not above it (§12.1): `cloud → core +
5
+ * protocol`, and never `cloud → server`. The self-hosted embedded coordinator
6
+ * stays the self-hosted option; this package serves the same frozen v1 device
7
+ * wire contract statelessly, over `@byok-sdk/core` ports plus the cloud-local auth
8
+ * and task ports in `stores/ports.ts`.
9
+ *
10
+ * `src/__tests__/constraints.test.ts` asserts the properties this export list
11
+ * implies: no `@byok-sdk/server` import, no `node:` import, no module-level
12
+ * mutable state, no session/Running map, and no route mounted outside the I1
13
+ * registry.
14
+ */
15
+ export { isTenantId, tenantId } from '@byok-sdk/core';
16
+ export type { TenantId } from '@byok-sdk/core';
17
+ export { createByokCloud } from './cloud';
18
+ export type { ByokCloud, ByokCloudOptions, EnqueueOfferInput, EnqueuedOffer } from './cloud';
19
+ export { DEFAULT_EVENTS_PAGE_LIMIT, DEFAULT_LONG_POLL_HOLD_MS, DEFAULT_LONG_POLL_INTERVAL_MS, DEFAULT_MAX_BLOB_SIZE_BYTES, } from './cloud';
20
+ export { DEFAULT_BOARD_PAGE_LIMIT, DEFAULT_BOARD_STREAM_HEARTBEAT_INTERVAL_MS, DEFAULT_BOARD_STREAM_QUERY_INTERVAL_MS, DEFAULT_BOARD_STREAM_RECONCILIATION_INTERVAL_MS, } from './handlers/board';
21
+ export { createInMemoryByokCloud } from './composition/in-memory';
22
+ export type { InMemoryByokCloud, InMemoryByokCloudOptions } from './composition/in-memory';
23
+ export { ByokCloudError, CLOUD_ERROR_CODES, isCloudError } from './errors';
24
+ export type { CloudErrorCode } from './errors';
25
+ export { CLOUD_CAPABILITIES, CapabilitiesResponseSchema, declares, fullCapabilityDeclaration, } from './capabilities';
26
+ export type { CapabilitiesResponse, CloudCapability, FullCapabilityDeclarationOptions, } from './capabilities';
27
+ export { CloudRouteRegistry, ROUTE_CLASSES, ROUTE_METHODS, routeKey } from './router/registry';
28
+ export type { CloudRouteHandler, RouteClass, RouteDescriptor, RouteMethod } from './router/registry';
29
+ export { ACCESS_TOKEN_TTL_SECONDS, createHmacTokenSigner } from './auth/tokens';
30
+ export type { AccessTokenClaims, TokenSigner } from './auth/tokens';
31
+ export { NONCE_SIGNING_DOMAIN, verifyNonceSignature } from './auth/verify';
32
+ export { authenticateBearer, extractBearerToken } from './auth/bearer';
33
+ export type { BearerAuthDeps } from './auth/bearer';
34
+ export { DEFAULT_DEVICE_PROOF_CLOCK_SKEW_MS, DEFAULT_DEVICE_PROOF_MAX_LIFETIME_MS, MAX_DEVICE_PROOF_CLOCK_SKEW_MS, MAX_DEVICE_PROOF_MAX_LIFETIME_MS, authenticateDeviceProof, } from './auth/device-proof';
35
+ export type { AuthenticatedDeviceProof, DeviceProofAuthDeps, DeviceProofRequestBinding, } from './auth/device-proof';
36
+ export { DEVICE_IDENTITY_PROOF_KEY_EPOCH, DEVICE_IDENTITY_PROOF_KEY_ID, PAIRING_CODE_TTL_MS, createAuthPlane, } from './auth/plane';
37
+ export type { AuthPlane, AuthPlaneDeps, MintedAccessToken, PairInput } from './auth/plane';
38
+ export { createWebCrypto } from './crypto/web-crypto';
39
+ export type { CloudCrypto } from './crypto/port';
40
+ export { handleInboundEnvelope, terminalReceiptKey } from './inbound';
41
+ export type { InboundOutcome } from './inbound';
42
+ export { tenantStoresFor } from './tenant-stores';
43
+ export type { TenantBoundActivity, TenantBoundBoard, CloudRootStores, TenantBoundBlobs, TenantBoundDedup, TenantBoundDevices, TenantBoundMailbox, TenantBoundPresence, TenantBoundQuota, TenantBoundRateLimiter, TenantBoundReceipts, TenantBoundSequence, TenantBoundTaskAttempts, TenantStores, } from './tenant-stores';
44
+ export { DEFAULT_ACTIVITY_BOUNDS, DEFAULT_ACTIVITY_CAPACITY, DEFAULT_ACTIVITY_MAX_BYTES, DEFAULT_ACTIVITY_MAX_EVENTS, DEFAULT_ACTIVITY_TTL_MS, DEFAULT_BOARD_CHANNEL_MAX_BYTES, DEFAULT_BOARD_TITLE_MAX_BYTES, DEFAULT_PRESENCE_DETAIL_MAX_BYTES, DEFAULT_PRESENCE_MINIMUM_INTERVAL_MS, DEFAULT_PRESENCE_TTL_MS, } from './coordination';
45
+ export type { ActivityBounds } from './coordination';
46
+ export { BoardFeedClient, BoardFeedRetryableError, BoardFeedStoppedError } from './coordination-client';
47
+ export type { BoardFeedClientOptions, BoardFeedItem, BoardFeedMode, BoardFeedPage, BoardFeedRead, } from './coordination-client';
48
+ export { TRUTH_BATCH_MAX_RECORDS, TRUTH_INLINE_CONTENT_TYPE, TRUTH_LABEL_MAX_LENGTH, TRUTH_MANIFEST_MAX_LIMIT, TRUTH_RECORD_CAPABILITY, TRUTH_RECORD_KEY_MAX_LENGTH, TRUTH_REQUEST_ID_MAX_LENGTH, TruthBodyInputSchema, TruthCommitResponseSchema, TruthRecordKeySchema, TruthRecordMetadataSchema, TruthWriteRequestSchema, truthManifestMetadata, truthRecordMetadata, } from './truth/contract';
49
+ export { DEFAULT_MAX_TRUTH_REQUEST_BYTES, DEVICE_PROOF_HEADER, MAX_DEVICE_PROOF_HEADER_BYTES, } from './handlers/truth';
50
+ export type { PreparedTruthWrite, TruthBodyInput, TruthCommitInput, TruthCommitResponse, TruthCommitResult, TruthCommitter, TruthObjectDownloads, TruthRecordMetadata, TruthWriteRequest, } from './truth/contract';
51
+ export { TruthCommitError, isTruthCommitError } from './truth/errors';
52
+ export type { TruthCommitErrorCode } from './truth/errors';
53
+ export { CLOUD_STORE_NAMES, TASK_ATTEMPT_STATUSES } from './stores/ports';
54
+ export { CLOUD_PORT_INTERFACES, CLOUD_PORT_METHODS } from './stores/ports-contract';
55
+ export type { BlobContent, BlobContentProxy, BlobDeclaration, BlobObservation, BlobWriteResult, CloudBlobStore, CloudStoreName, CloudStores, DeviceDirectory, DeviceRecord, DeviceRegistration, DeviceSequenceStore, InboundDedupStore, InboundRateLimiter, NonceStore, PairingCodeClaims, PairingCodeInfo, PairingCodeIssueInput, PairingCodeStore, ProofRequestReceipt, ProofRequestReceiptInput, ProofRequestReceiptStore, RequestReceipt, RequestReceiptStore, TaskAttempt, TaskAttemptStatus, TaskAttemptStore, } from './stores/ports';
56
+ export { AllowAllRateLimiter, BLOB_URL_TTL_MS, DEDUP_RING_CAPACITY, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryDeviceDirectory, InMemoryDeviceSequenceStore, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryRequestReceiptStore, InMemoryProofRequestReceiptStore, InMemoryTaskAttemptStore, NONCE_TTL_MS, createInMemoryBlobs, createInMemoryCloudStores, } from './stores/in-memory/index';
57
+ export type { InMemoryBlobStoreOptions, InMemoryBlobs, InMemoryCloudComposition, } from './stores/in-memory/index';