@byok-sdk/cloud-dataplane 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,20 +1,27 @@
1
1
  # @byok-sdk/cloud-dataplane
2
2
 
3
3
  The durable data plane for the BYOK SDK's hosted device surface: Postgres
4
- implementations of **all nine cloud-local store ports and all seven `@byok-sdk/core`
4
+ implementations of **all ten cloud-local store ports and all seven `@byok-sdk/core`
5
5
  ports**, the R2/S3 object adapter that backs the blob port, and the forward-only
6
6
  migration runner that creates the tables they read.
7
7
 
8
8
  Three store/maintenance compositions plus one transaction authority ship from here. `createPostgresCloudStores` supplies the full
9
- `CloudStores` bundle (`devices`, `pairingCodes`, `nonces`, `dedup`, `tasks`,
9
+ `CloudStores` bundle (`activity`, `devices`, `pairingCodes`, `nonces`, `dedup`, `tasks`,
10
10
  `receipts`, `proofReceipts`, `blobs`, `rateLimiter`); `createPostgresCoreStores`
11
11
  supplies the full `CoreStores` bundle (`mailbox`, `board`, `truth`, `presence`,
12
- `activity`, `objects`, `quota`). Both return every port rather than a subset,
12
+ `objects`, `quota`, `skillPacks`). Both return every port rather than a subset,
13
13
  because the conformance suites certify a composition as a whole — there is no
14
14
  partial bundle for them to run. `createPostgresCloudMaintenance` is the third,
15
15
  host-only operational composition; it is deliberately outside both port
16
16
  inventories.
17
17
 
18
+ `PostgresDeviceAssertionReplayAuthority` is a separate online security
19
+ authority for connector-binding exchanges. Its unique key makes consumption an
20
+ atomic `INSERT ... ON CONFLICT DO NOTHING` decision, and bounded expiry cleanup
21
+ keeps the short-lived ledger finite. It is intentionally not a `CloudStores`
22
+ member: hosts opt into assertion exchange explicitly, while connector sessions
23
+ and provider credentials stay outside this package.
24
+
18
25
  `PostgresTruthCommitter` is the S6 transaction authority rather than another
19
26
  raw store bundle. It owns the one transaction that couples proof receipt,
20
27
  terminal/snapshot preconditions, committed object checks, object references,
@@ -40,6 +47,48 @@ gets no table by design: persisting an allow-all would be a table that is always
40
47
  empty, and a real limiter is edge work rather than a per-request write. `blobs`
41
48
  is the R2 adapter described below.
42
49
 
50
+ ## Deployment compositions
51
+
52
+ Two entries, one data plane, and the host picks the composition explicitly —
53
+ the SDK never detects where it is running and never falls back between the two.
54
+
55
+ - **Node/VPS resident service.** Import the package root
56
+ (`@byok-sdk/cloud-dataplane`) and talk to Postgres and R2/S3 directly. The
57
+ migration runner and the cleanup/maintenance composition run in-process:
58
+ this is the entry that carries the Node-only operations.
59
+ - **Cloudflare Workers.** Import `@byok-sdk/cloud-dataplane/runtime` — the
60
+ online request path alone (pool, both store compositions, R2 blob store,
61
+ truth committer). Its graph never reaches a node builtin beyond what
62
+ `nodejs_compat` provides, so `pg` stays external in this package's build and
63
+ is satisfied by the platform: Hyperdrive terminates the database connection,
64
+ and R2 is reached over `fetch` with `aws4fetch`. Migrations and cleanup have
65
+ no place on a Worker — they read files off disk — so run them from a CI job
66
+ or an operator's Node process against the direct DSN:
67
+
68
+ ```ts
69
+ import { createByokPool, createPostgresCloudStores } from '@byok-sdk/cloud-dataplane/runtime';
70
+
71
+ const pool = createByokPool({ connectionString: env.BYOK_PG.connectionString });
72
+ ```
73
+
74
+ Pool lifecycle follows the composition. On Node/VPS the Pool is
75
+ process-scoped, and the host calls `pool.end()` at shutdown. On Workers,
76
+ create the Pool inside each `fetch`/`queue` handler — per invocation,
77
+ exactly like the `worker-smoke` probes already do — and never hold one in
78
+ module or global scope: cross-request pool reuse is forbidden, not a
79
+ preference. A Worker invocation's end cleans up its client connections, so
80
+ `pool.end()` is usually unnecessary there.
81
+
82
+ Same contracts, same SQL, same Postgres + R2 authority either way. There is no
83
+ D1 and no Durable Objects variant, and the runtime entry is a strict subset of
84
+ the root rather than a second implementation: `src/index.ts` re-exports
85
+ `src/runtime.ts` wholesale, so the two surfaces cannot drift. The boundary is
86
+ build-enforced — the runtime entry compiles under the neutral platform, which
87
+ fails the build the moment its graph reaches a node builtin — and CI exercises
88
+ the Worker composition for real through the `worker-smoke/` fixture (packaged
89
+ with `wrangler deploy --dry-run`, served by `wrangler dev` against the test
90
+ substrate; see Testing below).
91
+
43
92
  ## Blobs
44
93
 
45
94
  `blobs` mints grants and never carries a byte. `createUpload` writes the
@@ -218,6 +267,13 @@ test rather than a step someone remembers. What runs:
218
267
  SigV4 implementation, and nothing stubs a signature check. The two that are
219
268
  about retry semantics go through a fault injector wrapped around `fetch`,
220
269
  which replaces individual attempts and never answers a request itself.
270
+ - The worker suites, always for packaging and opt-in for serving:
271
+ `worker-packaging.test.ts` dry-runs `wrangler deploy` over `worker-smoke/`
272
+ on every run, and `worker-e2e.test.ts` additionally serves that fixture with
273
+ `wrangler dev` (local workerd) against the same Postgres when you set
274
+ `BYOK_TEST_WORKER_DATAPLANE=1`. CI's `dataplane` job sets it, plus the
275
+ `BYOK_REQUIRE_WORKER_DATAPLANE` flag that turns an unmet gate into a hard
276
+ failure.
221
277
 
222
278
  ## License
223
279
 
package/dist/index.d.ts CHANGED
@@ -11,20 +11,24 @@
11
11
  * authority and R2/S3-compatible storage remains the byte plane; a future
12
12
  * alternative composition must use a distinct package name rather than making
13
13
  * this authority conditional at runtime.
14
+ *
15
+ * Two entries, one online surface:
16
+ *
17
+ * - `.` (this file) is the superset: the online request path plus the Node-only
18
+ * operations — the migration runner, the migrations directory, and the
19
+ * cleanup/maintenance composition — that a resident Node/VPS service runs
20
+ * in-process.
21
+ * - `./runtime` is the Worker-loadable online surface alone, and is the single
22
+ * authority for the online export list: this file re-exports it wholesale
23
+ * rather than duplicating it, so the two entries cannot drift.
24
+ *
25
+ * The invariant that makes the split real: the `./runtime` subgraph must never
26
+ * reach a node builtin. It is enforced at build time by the neutral-platform
27
+ * tsup pass over `src/runtime.ts`, and pinned by the runtime-entry test.
14
28
  */
15
- export { createByokPool } from './pool';
16
- export type { ByokPoolOptions } from './pool';
29
+ export * from './runtime';
17
30
  export { MigrationChecksumMismatchError, MigrationFilenameError, migrate, readMigrationFiles } from './migrate';
18
31
  export type { MigrationFile, MigrationResult } from './migrate';
19
32
  export { migrationsDir } from './migrations-dir';
20
- export { PostgresDeviceDirectory, PostgresInboundDedupStore, PostgresNonceStore, PostgresPairingCodeStore, PostgresRequestReceiptStore, PostgresTaskAttemptStore, createPostgresCloudStores, } from './stores/index';
21
- export type { PostgresCloudStoreOptions, PostgresCloudStores, PostgresObjectStorageOptions, } from './stores/index';
22
- export { DEFAULT_MAX_ATTEMPTS, DEFAULT_PRESIGN_TTL_SECONDS, DEFAULT_RETRY_DELAY_MS, MAX_PRESIGN_TTL_SECONDS, MIN_PRESIGN_TTL_SECONDS, ObjectStoreRequestError, R2_BLOB_ERROR_CODES, R2BlobStoreError, R2CloudBlobStore, R2ObjectMaintenanceStore, } from './stores/index';
23
- export type { ObjectStoreFetch, R2BlobErrorCode, R2BlobStoreOptions } from './stores/index';
24
- export type { R2DeleteResult, R2ListedObject, R2ObjectMaintenance, R2ObjectMaintenanceOptions, R2ObjectPage, } from './stores/index';
25
- export { PostgresActivityStore, PostgresBoardStore, PostgresMailboxStore, PostgresObjectStore, PostgresPresenceStore, PostgresQuotaStore, PostgresTruthStore, createPostgresCoreStores, } from './stores/core/index';
26
- export type { PostgresCoreStoreOptions } from './stores/core/index';
27
33
  export { CLOUD_CLEANUP_ERROR_CODES, CloudCleanupError, PostgresCloudCleanup, createPostgresCloudMaintenance, } from './cleanup';
28
- export { PostgresTruthCommitter } from './truth-committer';
29
- export type { PostgresTruthCommitterOptions } from './truth-committer';
30
34
  export type { CleanupJobState, CloudCleanupErrorCode, CloudCleanupResult, DeadLetterPage, DeadLetterQuery, DeadLetterRef, DeadLetterReplayInput, ObjectUsageRebuildResult, PostgresCloudCleanupOptions, PostgresCloudMaintenanceOptions, TenantRetentionPolicy, TenantRetentionPolicyInput, } from './cleanup';