@adonix.org/cloud-spark 0.0.184 → 0.0.186

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
@@ -9,20 +9,11 @@
9
9
 
10
10
  **_Ignite_** your Cloudflare Workers with a type-safe library for rapid development.
11
11
 
12
- Get instant access to common essentials:
12
+ CloudSpark provides a logical foundation for building Cloudflare Workers. It works well for simple workers or projects that grow in complexity, helping keep code organized and functionality scalable. It is lightweight and designed to let you focus on the logic that powers your worker.
13
13
 
14
- - Method & Route dispatch
15
- - CORS
16
- - Caching
17
- - WebSockets
14
+ :bulb: If you are new to _Cloudflare Workers_, create a free [Cloudflare account](https://dash.cloudflare.com/sign-up) and install their command line interface [Wrangler](#cowboy_hat_face-wrangler).
18
15
 
19
- And then explore:
20
-
21
- - Custom Middleware
22
- - Nested Workers
23
- - Advanced Routing
24
-
25
- :bulb: If you are new to _Cloudflare Workers_, create a free [Cloudflare account](https://dash.cloudflare.com/sign-up) and install their command line interface [Wrangler](#cowboy_hat_face-wrangler). Detailed worker documentation can also be found [here](https://developers.cloudflare.com/workers/).
16
+ Detailed worker documentation can also be found [here](https://developers.cloudflare.com/workers/).
26
17
 
27
18
  <br>
28
19
 
@@ -36,22 +27,16 @@ npm install @adonix.org/cloud-spark
36
27
 
37
28
  ## :rocket: Quickstart
38
29
 
39
- :page_facing_up: hello-world.ts
30
+ :page_facing_up: index.ts
40
31
 
41
32
  ```ts
42
33
  import { BasicWorker, TextResponse } from "@adonix.org/cloud-spark";
43
34
 
44
- export class HelloWorld extends BasicWorker {
35
+ class HelloWorld extends BasicWorker {
45
36
  get() {
46
37
  return this.response(TextResponse, "Hi from Cloud Spark!");
47
38
  }
48
39
  }
49
- ```
50
-
51
- :page_facing_up: index.ts
52
-
53
- ```ts
54
- import { HelloWorld } from "./hello-world";
55
40
 
56
41
  export default HelloWorld.ignite();
57
42
  ```
@@ -68,84 +53,359 @@ And it's ready on http://localhost:8787
68
53
 
69
54
  ## :arrow_right: Basic Worker
70
55
 
71
- As shown in the [Quickstart](#rocket-quickstart), BasicWorker is the base class for building Cloudflare Workers with this library. It handles common tasks, including:
56
+ As shown in the [Quickstart](#rocket-quickstart), BasicWorker is the base class for building Cloudflare Workers with CloudSpark. It handles common tasks, including:
72
57
 
73
58
  - Dispatching incoming HTTP requests to the corresponding handler (GET, POST, PUT, etc.).
74
- - Catching unhandled errors and returning a structured 500 InternalServerError.
75
59
  - Providing defaults for standard HTTP behavior, such as HEAD requests and OPTIONS responses.
76
60
  - Ensuring type safety and consistent response formatting.
61
+ - Support for built-in and custom middleware.
62
+ - Catching unhandled errors.
77
63
 
78
- Subclasses only need to implement the HTTP methods that their Worker will handle. Each method can be overridden independently, and additional functionality such as middleware can be added as needed.
64
+ Subclasses only need to implement the HTTP methods that their worker will handle. Each method can be overridden independently, and additional functionality such as [middleware](#gear-middleware) can be added as needed.
79
65
 
80
- ## :hammer_and_wrench: Basic Worker API
66
+ Building on the [Quickstart](#rocket-quickstart), what follows is a more complete example:
81
67
 
82
- #### `getAllowedMethods(): Method[]`
68
+ :page_facing_up: index.ts
83
69
 
84
- Returns the HTTP methods supported by this Worker.
70
+ ```ts
71
+ import { BasicWorker, JsonResponse, Method, POST, TextResponse } from "@adonix.org/cloud-spark";
72
+
73
+ /**
74
+ * To access the Cloudflare runtime properties:
75
+ * • this.request — the incoming Request
76
+ * • this.env — environment bindings (KV, R2, etc.)
77
+ * • this.ctx — the execution context for background tasks
78
+ */
79
+ export class MyWorker extends BasicWorker {
80
+ /**
81
+ * Override to allow additional method support for the worker.
82
+ * GET and HEAD requests are always allowed.
83
+ *
84
+ * Default: GET, HEAD, OPTIONS
85
+ *
86
+ * For OPTIONS requests, the default response is:
87
+ * 204 No Content
88
+ * "Allow" response header contains all allowed methods.
89
+ *
90
+ * If a requested method is not listed, the response is:
91
+ * 405 Method Not Allowed
92
+ *
93
+ * If an allowed method isn’t implemented, the response is:
94
+ * GET or HEAD: 404 Not Found
95
+ * All other methods: 501 Not Implemented
96
+ *
97
+ * This example adds POST method support to the defaults.
98
+ */
99
+ public override getAllowedMethods(): Method[] {
100
+ return [...super.getAllowedMethods(), POST];
101
+ }
85
102
 
86
- - **Default:** `[GET, HEAD, OPTIONS]`
87
- - **Notes:** Subclasses must override to allow additional methods. Any request using a method not listed will automatically return a `405 Method Not Allowed` response.
103
+ /**
104
+ * Example handler for GET requests that returns a simple
105
+ * text response.
106
+ */
107
+ protected override get(): Promise<Response> {
108
+ return this.response(TextResponse, "Hello from Cloud Spark!");
109
+ }
88
110
 
89
- #### `get(): Promise<Response>`
111
+ /**
112
+ * Example handler for POST requests that echoes the
113
+ * incoming JSON.
114
+ */
115
+ protected override async post(): Promise<Response> {
116
+ const json = await this.request.json();
117
+ // Do something with the request JSON.
90
118
 
91
- Override this method to handle `GET` requests.
119
+ return this.response(JsonResponse, json);
120
+ }
92
121
 
93
- - **Default behavior:** Returns a `404 Not Found`.
94
- - **Notes:** Typically used to return content or data for read requests.
122
+ /**
123
+ * Supported BasicWorker request methods:
124
+ * protected override get(): Promise<Response>
125
+ * protected override put(): Promise<Response>
126
+ * protected override post(): Promise<Response>
127
+ * protected override patch(): Promise<Response>
128
+ * protected override delete(): Promise<Response>
129
+ *
130
+ * Implementations are provided but can be overridden for:
131
+ * protected override head(): Promise<Response>
132
+ * protected override options(): Promise<Response>
133
+ */
134
+ }
95
135
 
96
- #### `head(): Promise<Response>`
136
+ /**
137
+ * Connects this worker to the Cloudflare runtime.
138
+ */
139
+ export default MyWorker.ignite();
140
+ ```
97
141
 
98
- Handles `HEAD` requests.
142
+ <br>
99
143
 
100
- - **Default behavior:** Performs a `GET` request internally and strips the body.
101
- - **Notes:** Rarely needs to be overridden; ensures compliance with [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.2).
144
+ ## :twisted_rightwards_arrows: Route Worker
102
145
 
103
- #### `post(): Promise<Response>`
146
+ RouteWorker extends [BasicWorker](#arrow_right-basic-worker) to provide route-based request handling making it easy to define multiple endpoints in a single worker. It provides:
104
147
 
105
- Override to handle `POST` requests.
148
+ - Registering routes individually or in bulk.
149
+ - Matching incoming requests to registered routes by HTTP method and path.
150
+ - Support for URL path patterns using [path-to-regexp](https://github.com/pillarjs/path-to-regexp) syntax.
151
+ - Dispatching requests to either a callback function or another worker.
106
152
 
107
- - **Default behavior:** Returns `501 Method Not Implemented`.
108
- - **Notes:** Ideal for form submissions, JSON payloads, or resource creation.
153
+ Example:
109
154
 
110
- #### `put(): Promise<Response>`
155
+ :page_facing_up: index.ts
111
156
 
112
- Override to handle `PUT` requests.
157
+ ```ts
158
+ import { BasicWorker, GET, PathParams, RouteWorker, TextResponse } from "@adonix.org/cloud-spark";
159
+
160
+ /**
161
+ * An example worker with path routing.
162
+ */
163
+ class GreetingWorker extends RouteWorker {
164
+ /**
165
+ * Called before request processing to enable worker
166
+ * initialization without overriding the constructor.
167
+ */
168
+ protected override init(): void {
169
+ /**
170
+ * Example of path-to-regexp and local method routing.
171
+ */
172
+ this.route(GET, "/hello/:name", this.hello);
173
+
174
+ /**
175
+ * Example of simple path to a nested worker.
176
+ */
177
+ this.route(GET, "/goodbye", GoodbyeWorker);
178
+ }
113
179
 
114
- - **Default behavior:** Returns `501 Method Not Implemented`.
115
- - **Notes:** Used for full resource creation or replacement.
180
+ /**
181
+ * Path parameters are provided via path-to-regexp parsing
182
+ * of the request path.
183
+ *
184
+ * For example, http://localhost:8787/hello/Inigo will yield
185
+ * the text response "Hello Inigo!"
186
+ */
187
+ protected hello(params: PathParams): Promise<Response> {
188
+ return this.response(TextResponse, `Hello ${params["name"]}!`);
189
+ }
190
+ }
116
191
 
117
- #### `patch(): Promise<Response>`
192
+ /**
193
+ * An example nested BasicWorker.
194
+ *
195
+ * The original request, env, and ctx are passed to the nested
196
+ * worker via the constructor.
197
+ *
198
+ * RouteWorkers may also be nested to access path parameters.
199
+ */
200
+ class GoodbyeWorker extends BasicWorker {
201
+ /**
202
+ * GET handler for the "/goodbye" path.
203
+ */
204
+ protected override get(): Promise<Response> {
205
+ return this.response(TextResponse, "Goodbye!");
206
+ }
207
+ }
118
208
 
119
- Override to handle `PATCH` requests.
209
+ /**
210
+ * Connects GreetingWorker to the Cloudflare runtime.
211
+ */
212
+ export default GreetingWorker.ignite();
213
+ ```
120
214
 
121
- - **Default behavior:** Returns `501 Method Not Implemented`.
122
- - **Notes:** Used for partial updates to existing resources.
215
+ :bulb: Requests with no matching route fall back to the corresponding [BasicWorker](#arrow_right-basic-worker) method.
123
216
 
124
- #### `delete(): Promise<Response>`
217
+ <br>
125
218
 
126
- Override to handle `DELETE` requests.
219
+ ## :gear: Middleware
127
220
 
128
- - **Default behavior:** Returns `501 Method Not Implemented`.
129
- - **Notes:** Used to remove resources.
221
+ Middleware extends your worker’s behavior in a modular way. Each middleware can inspect the incoming request, return a custom response early, or modify the response produced by later handlers. It’s a simple way to add logic such as authentication checks, request logging, or response transformations without touching your core code.
130
222
 
131
- #### `options(): Promise<Response>`
223
+ CloudSpark includes built-in middleware for common functionality like caching and CORS, and you can easily create your own to handle behavior specific to your application.
132
224
 
133
- Override to handle `OPTIONS` requests.
225
+ ### CORS
134
226
 
135
- - **Default behavior:** Returns `200 OK` with the `Allow` header listing supported methods.
136
- - **Notes:** `GET`, `HEAD`, and `OPTIONS` are included by default.
227
+ Register the built-in CORS middleware as follows:
137
228
 
138
- <br>
229
+ :page_facing_up: index.ts
139
230
 
140
- ## :twisted_rightwards_arrows: Route Worker
231
+ ```ts
232
+ import { BasicWorker, cors } from "@adonix.org/cloud-spark";
233
+
234
+ class MyWorker extends BasicWorker {
235
+ /**
236
+ * Register middleware in the init method.
237
+ */
238
+ protected override init(): void {
239
+ /**
240
+ * Create and register the built-in CORS middleware
241
+ * with default options:
242
+ *
243
+ * {
244
+ * allowedOrigins: ["*"],
245
+ * allowedHeaders: ["Content-Type"],
246
+ * exposedHeaders: [],
247
+ * allowCredentials: false,
248
+ * maxAge: 300,
249
+ * }
250
+ *
251
+ */
252
+ this.use(cors());
253
+
254
+ /**
255
+ * To override specific default CORS options:
256
+ *
257
+ * this.use(cors({ allowedOrigins: ["https://www.adonix.org"], maxAge: 604800 }));
258
+ *
259
+ */
260
+ }
261
+ }
262
+ ```
141
263
 
142
- <br>
264
+ :bulb: The middleware adds CORS headers to the response **ONLY** if the request includes an `Origin` header.
143
265
 
144
- ## :left_right_arrow: Web Sockets
266
+ ### Cache
267
+
268
+ CloudSpark includes built-in caching middleware that stores responses for improving performance. Only responses that are safe to cache are stored, including:
269
+
270
+ - Responses to GET requests with a 200 OK status.
271
+ - Responses that specify a time-to-live via `Cache-Control` headers (max-age or s-maxage).
272
+ - Responses with `Vary` headers are fully supported, so the cache respects variations based on headers like `Accept-Language`.
273
+ - Responses that **do not** include user-specific data (such as Set-Cookie or requests with Authorization/Cookie headers).
274
+
275
+ Other types of responses (non-GET, errors, partial content, or requests marked no-store) are never cached. This ensures caching is safe and consistent with HTTP standards.
276
+
277
+ Register the built-in cache middleware as follows:
278
+
279
+ :page_facing_up: index.ts
280
+
281
+ ```ts
282
+ import { BasicWorker, cache, CacheControl, JsonResponse, Time } from "@adonix.org/cloud-spark";
283
+
284
+ class MyWorker extends BasicWorker {
285
+ /**
286
+ * Enable middleware in the worker init method.
287
+ */
288
+ protected override init(): void {
289
+ /**
290
+ * Create and register the built-in cache middleware.
291
+ */
292
+ this.use(cache());
293
+
294
+ /**
295
+ * Optionally pass settings to the cache function:
296
+ *
297
+ * name — the name of the cache storage to use. If omitted,
298
+ * the default cache is used.
299
+ * getKey — a function that maps the incoming request to a
300
+ * cache key.
301
+ * Built-in key functions include:
302
+ * • sortSearchParams (Default)
303
+ * • stripSearchParams
304
+ *
305
+ * this.use(cache({
306
+ * name: "my-cache",
307
+ * getKey: stripSearchParams,
308
+ * }));
309
+ *
310
+ */
311
+ }
312
+
313
+ /**
314
+ * Create a cacheable response.
315
+ */
316
+ protected override get(): Promise<Response> {
317
+ /**
318
+ * Example JSON message.
319
+ */
320
+ const json = {
321
+ message: "Hi from Cloud Spark!",
322
+ timestamp: new Date().toLocaleString(),
323
+ };
324
+
325
+ /**
326
+ * Cache the response for 10 seconds.
327
+ */
328
+ const cc: CacheControl = {
329
+ "s-maxage": 10 * Time.Second,
330
+ };
331
+
332
+ return this.response(JsonResponse, json, cc);
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Connects MyWorker to the Cloudflare runtime.
338
+ */
339
+ export default MyWorker.ignite();
340
+ ```
341
+
342
+ :bulb: The `cf-cache-status` response header will contain **HIT** when serving from the cache.
343
+
344
+ ### WebSocket
345
+
346
+ The WebSocket middleware ensures upgrade requests are valid before they reach your handler. You can provide a path (default: `"/"`) and register multiple instances for multiple paths. Invalid upgrade requests are intercepted, and the correct error response is returned.
347
+
348
+ A valid WebSocket upgrade request must use the `GET` method and include the following:
349
+
350
+ | Header | Value |
351
+ | --------------------- | --------- |
352
+ | Connection | Upgrade |
353
+ | Upgrade | websocket |
354
+ | Sec-WebSocket-Version | 13 |
355
+
356
+ Register the built-in websocket middleware as follows:
357
+
358
+ :page_facing_up: index.ts
359
+
360
+ ```ts
361
+ import { GET, PathParams, RouteWorker, websocket } from "@adonix.org/cloud-spark";
362
+
363
+ class ChatWorker extends RouteWorker {
364
+ /**
365
+ * Register both the upgrade route and middleware.
366
+ */
367
+ protected override init(): void {
368
+ /**
369
+ * Route for WebSocket upgrades.
370
+ */
371
+ this.route(GET, "/chat/:room", this.upgrade);
372
+
373
+ /**
374
+ * Register WebSocket middleware to match the
375
+ * upgrade route.
376
+ */
377
+ this.use(websocket("/chat/:room"));
378
+ }
379
+
380
+ /**
381
+ * Handles WebSocket upgrade requests.
382
+ *
383
+ * Expects a DurableObject binding named CHAT
384
+ * in wrangler.jsonc
385
+ */
386
+ protected upgrade(params: PathParams): Promise<Response> {
387
+ const room = params["room"];
388
+ const chat = this.env.CHAT;
389
+
390
+ /**
391
+ * Request has already been validated by the
392
+ * WebSocket middleware.
393
+ */
394
+ return chat.get(chat.idFromName(room)).fetch(this.request);
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Connects ChatWorker to the Cloudflare runtime.
400
+ */
401
+ export default ChatWorker.ignite();
402
+ ```
403
+
404
+ ### Custom
145
405
 
146
406
  <br>
147
407
 
148
- ## :gear: Middleware
408
+ ## :left_right_arrow: Web Sockets
149
409
 
150
410
  <br>
151
411
 
package/dist/index.d.ts CHANGED
@@ -419,7 +419,7 @@ declare function cors(init?: CorsInit): Middleware;
419
419
  * - Only validates the upgrade request; it does **not** perform the actual WebSocket upgrade.
420
420
  * - Ensures the request:
421
421
  * - Uses the `GET` method.
422
- * - Matches the specified path, supporting `path-to-regex` style patterns
422
+ * - Matches the specified path, supporting `path-to-regexp` style patterns
423
423
  * (e.g., `/chat/:name`).
424
424
  * - Contains required WebSocket headers:
425
425
  * - `Connection: Upgrade`
@@ -429,7 +429,7 @@ declare function cors(init?: CorsInit): Middleware;
429
429
  * the next middleware or origin handler.
430
430
  *
431
431
  * @param path - The URL path to intercept for WebSocket upgrades. Defaults to `/`.
432
- * Supports dynamic segments using `path-to-regex` syntax.
432
+ * Supports dynamic segments using `path-to-regexp` syntax.
433
433
  * @returns A {@link Middleware} instance that can be used in your middleware chain.
434
434
  *
435
435
  * @example
@@ -725,7 +725,7 @@ declare abstract class BaseWorker implements Worker {
725
725
  * @param args Additional constructor arguments
726
726
  * @returns A Promise resolving to the {@link Response} object
727
727
  */
728
- protected response<Ctor extends new (...args: any[]) => {
728
+ response<Ctor extends new (...args: any[]) => {
729
729
  response(): Promise<Response>;
730
730
  }>(ResponseClass: Ctor, ...args: ConstructorParameters<Ctor>): Promise<Response>;
731
731
  /**
@@ -828,7 +828,7 @@ declare abstract class RouteWorker extends BasicWorker {
828
828
  * - A Worker subclass that will handle the request.
829
829
  *
830
830
  * @param method - HTTP method for the route (`GET`, `POST`, etc.).
831
- * @param path - URL path pattern (path-to-regex, e.g., "/users/:id").
831
+ * @param path - URL path pattern (path-to-regexp, e.g., "/users/:id").
832
832
  * @param handler - The function or Worker class to run when the route matches.
833
833
  * @returns The current worker instance, allowing method chaining.
834
834
  */
@@ -838,7 +838,7 @@ declare abstract class RouteWorker extends BasicWorker {
838
838
  *
839
839
  * Each route should be a tuple `[method, path, handler]` where:
840
840
  * - `method` - HTTP method for the route (`GET`, `POST`, etc.).
841
- * - `path` - URL path pattern (path-to-regex e.g., "/users/:id").
841
+ * - `path` - URL path pattern (path-to-regexp e.g., "/users/:id").
842
842
  * - `handler` - A function that receives URL parameters or a Worker subclass
843
843
  * that will handle the request.
844
844
  *