@velajs/cloudflare 1.10.1 → 1.22.1

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.
@@ -0,0 +1,141 @@
1
+ import { Type } from "@velajs/vela";
2
+ import { DurableObject } from "cloudflare:workers";
3
+ //#region src/root-module.d.ts
4
+ /** A static module, or a module graph built from this Worker's native environment. */
5
+ type CloudflareRoot<T extends object> = Type | {
6
+ create(env: T): Type;
7
+ };
8
+ //#endregion
9
+ //#region src/websocket/do-pitr.d.ts
10
+ /**
11
+ * Durable Object point-in-time recovery (PITR) — thin, testable wrappers over a
12
+ * SQLite-backed DO's native bookmark API. A SQLite Durable Object exposes three
13
+ * storage methods (last-30-days PITR):
14
+ *
15
+ * - `getCurrentBookmark()` — an opaque bookmark for the storage's current state.
16
+ * - `getBookmarkForTime(t)` — the bookmark closest to a wall-clock instant.
17
+ * - `onNextSessionRestoreBookmark(b)` — arm a restore to bookmark `b`; the DO
18
+ * restores to it the next time it starts a session, and the call RETURNS a
19
+ * bookmark for the state JUST BEFORE the restore (the undo handle).
20
+ *
21
+ * These methods are ABSENT on a non-SQLite DO (key-value storage) and in some
22
+ * local-dev runtimes, so this module models storage structurally with all three
23
+ * methods OPTIONAL and degrades to a typed {@link DoPitrUnavailableError} (a
24
+ * `code: 'PITR_UNAVAILABLE'`, HTTP 409 error) rather than an
25
+ * `undefined is not a function` TypeError when a needed method is missing.
26
+ *
27
+ * Neither wrapper aborts the DO — `armDoPitr` only ARMS the restore and returns
28
+ * the undo bookmark; the caller (the WS-DO RPC method) decides whether to
29
+ * `ctx.abort()` to apply it immediately vs. on the next natural restart.
30
+ *
31
+ * This file is `cloudflare:workers`-free and pulls in NOTHING from `@velajs/vela`
32
+ * or `@velajs/studio` — it is the raw capability the studio `TimeTravelPort`
33
+ * wraps. Dependency direction is one-way: studio → cloudflare, never the reverse.
34
+ */
35
+ /**
36
+ * The subset of `DurableObjectStorage` this module touches, with every method
37
+ * OPTIONAL so it structurally models a non-SQLite DO whose storage has none of
38
+ * them. A real `DurableObjectStorage` (whose methods are required) is assignable
39
+ * to this shape.
40
+ */
41
+ interface DoPitrStorage {
42
+ getCurrentBookmark?(): Promise<string>;
43
+ getBookmarkForTime?(timestamp: number | Date): Promise<string>;
44
+ onNextSessionRestoreBookmark?(bookmark: string): Promise<string>;
45
+ }
46
+ /** A read of a DO's current bookmark (+ the by-time bookmark when a time is given). */
47
+ interface DoPitrBookmarkRead {
48
+ /** The bookmark for the DO storage's current state. */
49
+ current: string;
50
+ /** The bookmark closest to the requested time (only when `time` was passed). */
51
+ forTime?: string;
52
+ }
53
+ /** Arming input for {@link armDoPitr}: a target (bookmark WINS over time) + restart intent. */
54
+ interface DoPitrArmOptions {
55
+ /** An explicit target bookmark. Takes precedence over `time`. */
56
+ bookmark?: string;
57
+ /** A wall-clock target (epoch ms, ISO string, or Date), resolved to a bookmark. */
58
+ time?: number | string | Date;
59
+ /** Caller intent to restart-now; recorded on the result. `armDoPitr` never aborts. */
60
+ restart?: boolean;
61
+ }
62
+ /** The result of arming a PITR restore (before any restart is applied). */
63
+ interface DoPitrArmResult {
64
+ /** The bookmark the restore is armed to. */
65
+ restoredTo: string;
66
+ /** The bookmark for the pre-restore state — restore to this to undo. */
67
+ undoBookmark: string;
68
+ /** Whether a restart-now was requested (the RPC layer performs the actual abort). */
69
+ restarted: boolean;
70
+ }
71
+ /** The RPC surface a PITR-capable Vela WebSocket DO stub exposes to a Worker. */
72
+ interface VelaDoPitrRpc {
73
+ pitrCurrentBookmark(): Promise<DoPitrBookmarkRead>;
74
+ pitrBookmarkForTime(time: number | string): Promise<DoPitrBookmarkRead>;
75
+ pitrArmRestore(opts: DoPitrArmOptions): Promise<DoPitrArmResult>;
76
+ }
77
+ /** Structural view of a DO id (avoids depending on `@cloudflare/workers-types` downstream). */
78
+ interface DoPitrId {
79
+ toString(): string;
80
+ readonly name?: string | null;
81
+ }
82
+ /**
83
+ * Structural view of a DO namespace binding whose stubs speak the PITR RPC. A
84
+ * downstream (the studio `@velajs/studio/cloudflare` port) types the app's
85
+ * namespace binding as this shape to reach the PITR methods without importing
86
+ * `@cloudflare/workers-types`.
87
+ */
88
+ interface DoPitrNamespace {
89
+ idFromName(name: string): DoPitrId;
90
+ get(id: DoPitrId): VelaDoPitrRpc;
91
+ }
92
+ /**
93
+ * Thrown when a DO's storage lacks the SQLite bookmark API (non-SQLite DO, or a
94
+ * local runtime without PITR). Carries a stable `code` + HTTP 409 `status`, and
95
+ * a recognizable `name`/message so the studio port can map it to
96
+ * `TIMETRAVEL_UNAVAILABLE` even after the error crosses the Worker→DO RPC hop
97
+ * (which preserves `name` + `message`, not arbitrary own-properties).
98
+ */
99
+ declare class DoPitrUnavailableError extends Error {
100
+ readonly code = "PITR_UNAVAILABLE";
101
+ readonly status = 409;
102
+ constructor(message?: string);
103
+ }
104
+ /**
105
+ * True when `error` signals DO PITR unavailability. Robust across the Worker→DO
106
+ * RPC hop: checks the `code` own-property (same process) AND the `name` / message
107
+ * sentinel (survive RPC serialization) so a downstream can classify it either way.
108
+ */
109
+ declare function isDoPitrUnavailable(error: unknown): boolean;
110
+ /**
111
+ * Read a DO's current bookmark, and — when `time` is given — the bookmark closest
112
+ * to that instant. Throws {@link DoPitrUnavailableError} when a needed method is
113
+ * absent, never `undefined is not a function`.
114
+ */
115
+ declare function readDoPitrBookmark(storage: DoPitrStorage, time?: number | string | Date): Promise<DoPitrBookmarkRead>;
116
+ /**
117
+ * Arm a PITR restore. Resolves the target (an explicit `bookmark` WINS over
118
+ * `time`), arms it via `onNextSessionRestoreBookmark`, and returns the undo
119
+ * bookmark the DO reports for the pre-restore state. Does NOT abort — the caller
120
+ * decides whether to restart now. Throws {@link DoPitrUnavailableError} when the
121
+ * arming API (or the by-time resolver a `time` target needs) is absent.
122
+ */
123
+ declare function armDoPitr(storage: DoPitrStorage, opts: DoPitrArmOptions): Promise<DoPitrArmResult>;
124
+ //#endregion
125
+ //#region src/nonce/nonce.durable-object.d.ts
126
+ /**
127
+ * SQLite Durable Object that atomically consumes nonces.
128
+ *
129
+ * Export this class from the Worker entry and register it through a Wrangler
130
+ * `new_sqlite_classes` migration. `INSERT ... ON CONFLICT DO NOTHING RETURNING`
131
+ * is the single-use decision; all SQL runs synchronously before the RPC method
132
+ * yields, and the nonce primary key is the final concurrency boundary.
133
+ */
134
+ declare class VelaNonceDurableObject extends DurableObject<Record<string, unknown>> {
135
+ private sql?;
136
+ constructor(ctx: DurableObjectState, env: Record<string, unknown>);
137
+ claim(nonce: string, expEpochSeconds: number): Promise<boolean>;
138
+ }
139
+ //#endregion
140
+ export { DoPitrId as a, DoPitrUnavailableError as c, isDoPitrUnavailable as d, readDoPitrBookmark as f, DoPitrBookmarkRead as i, VelaDoPitrRpc as l, DoPitrArmOptions as n, DoPitrNamespace as o, CloudflareRoot as p, DoPitrArmResult as r, DoPitrStorage as s, VelaNonceDurableObject as t, armDoPitr as u };
141
+ //# sourceMappingURL=nonce.durable-object-Df3_42Sy.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velajs/cloudflare",
3
- "version": "1.10.1",
3
+ "version": "1.22.1",
4
4
  "description": "Cloudflare Workers integration for Vela framework",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -14,15 +14,16 @@
14
14
  "r2",
15
15
  "vela"
16
16
  ],
17
- "homepage": "https://github.com/velajs/cloudflare#readme",
17
+ "homepage": "https://github.com/velajs/vela/tree/main/packages/cloudflare#readme",
18
18
  "bugs": {
19
- "url": "https://github.com/velajs/cloudflare/issues"
19
+ "url": "https://github.com/velajs/vela/issues"
20
20
  },
21
21
  "license": "MIT",
22
22
  "author": "ksh",
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/velajs/cloudflare.git"
25
+ "url": "git+https://github.com/velajs/vela.git",
26
+ "directory": "packages/cloudflare"
26
27
  },
27
28
  "files": [
28
29
  "dist",
@@ -38,29 +39,35 @@
38
39
  ".": {
39
40
  "types": "./dist/index.d.ts",
40
41
  "import": "./dist/index.js"
42
+ },
43
+ "./durable-objects": {
44
+ "types": "./dist/durable-objects.d.ts",
45
+ "import": "./dist/durable-objects.js"
41
46
  }
42
47
  },
43
48
  "devDependencies": {
44
- "@arethetypeswrong/cli": "^0.18.5",
45
- "@changesets/cli": "^2.31.0",
46
- "@cloudflare/workers-types": "^4.20260624.1",
47
- "@swc/core": "^1.15.43",
48
- "@velajs/feature-flags": "^0.1.0",
49
- "@velajs/vela": "^1.17.0",
50
- "hono": "^4.12.27",
51
- "oxfmt": "^0.58.0",
52
- "oxlint": "^1.73.0",
53
- "publint": "^0.3.21",
54
- "tsdown": "^0.22.4",
55
- "typescript": "^7.0.2",
56
- "unplugin-swc": "^1.5.9",
57
- "vitest": "^4.1.10"
49
+ "@arethetypeswrong/cli": "0.18.5",
50
+ "@changesets/cli": "3.0.1",
51
+ "@cloudflare/vitest-plugin": "1.1.13",
52
+ "@cloudflare/workers-types": "5.20260920.1",
53
+ "@swc/core": "1.15.43",
54
+ "hono": "4.13.8",
55
+ "oxfmt": "0.58.0",
56
+ "oxlint": "1.73.0",
57
+ "publint": "0.3.21",
58
+ "tsdown": "0.23.0",
59
+ "typescript": "7.0.2",
60
+ "unplugin-swc": "1.5.9",
61
+ "vitest": "4.1.10",
62
+ "zod": "^3.25.76",
63
+ "@velajs/feature-flags": "1.22.1",
64
+ "@velajs/vela": "1.22.1"
58
65
  },
59
66
  "peerDependencies": {
60
67
  "@cloudflare/workers-types": ">=4",
61
- "@velajs/feature-flags": "^0.1.0",
62
- "@velajs/vela": ">=1.17.0",
63
- "hono": ">=4"
68
+ "hono": ">=4",
69
+ "@velajs/feature-flags": "^1.22.1",
70
+ "@velajs/vela": "^1.22.1"
64
71
  },
65
72
  "peerDependenciesMeta": {
66
73
  "@velajs/feature-flags": {
@@ -70,18 +77,19 @@
70
77
  "engines": {
71
78
  "node": ">=24"
72
79
  },
80
+ "publishConfig": {
81
+ "access": "public"
82
+ },
73
83
  "scripts": {
74
84
  "build": "tsdown",
75
85
  "test": "vitest run",
76
- "typecheck": "tsc --noEmit",
86
+ "test:workers": "vitest run --config vitest.config.workers.ts",
87
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
77
88
  "lint": "oxlint .",
78
89
  "format": "oxfmt .",
79
90
  "format:check": "oxfmt --check .",
80
91
  "publint": "publint",
81
92
  "attw": "attw --pack . --profile esm-only",
82
- "changeset": "changeset",
83
- "version-packages": "changeset version",
84
- "release": "pnpm build && changeset publish",
85
- "verify": "pnpm lint && pnpm format:check && pnpm build && pnpm typecheck && pnpm test && pnpm publint && pnpm attw"
93
+ "verify": "pnpm lint && pnpm format:check && pnpm build && pnpm typecheck && pnpm test && pnpm test:workers && pnpm publint && pnpm attw"
86
94
  }
87
95
  }