@adonix.org/cloud-spark 0.0.185 → 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
@@ -61,7 +61,7 @@ As shown in the [Quickstart](#rocket-quickstart), BasicWorker is the base class
61
61
  - Support for built-in and custom middleware.
62
62
  - Catching unhandled errors.
63
63
 
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.
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.
65
65
 
66
66
  Building on the [Quickstart](#rocket-quickstart), what follows is a more complete example:
67
67
 
@@ -143,12 +143,12 @@ export default MyWorker.ignite();
143
143
 
144
144
  ## :twisted_rightwards_arrows: Route Worker
145
145
 
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:
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:
147
147
 
148
148
  - Registering routes individually or in bulk.
149
149
  - Matching incoming requests to registered routes by HTTP method and path.
150
- - Support for URL path patterns using [path-to-regex](https://github.com/pillarjs/path-to-regexp) syntax.
151
- - Dispatching requests to either a callback function or another Worker.
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.
152
152
 
153
153
  Example:
154
154
 
@@ -167,7 +167,7 @@ class GreetingWorker extends RouteWorker {
167
167
  */
168
168
  protected override init(): void {
169
169
  /**
170
- * Example of path-to-regex and local method routing.
170
+ * Example of path-to-regexp and local method routing.
171
171
  */
172
172
  this.route(GET, "/hello/:name", this.hello);
173
173
 
@@ -178,7 +178,7 @@ class GreetingWorker extends RouteWorker {
178
178
  }
179
179
 
180
180
  /**
181
- * Path parameters are provided via path-to-regex parsing
181
+ * Path parameters are provided via path-to-regexp parsing
182
182
  * of the request path.
183
183
  *
184
184
  * For example, http://localhost:8787/hello/Inigo will yield
@@ -212,14 +212,195 @@ class GoodbyeWorker extends BasicWorker {
212
212
  export default GreetingWorker.ignite();
213
213
  ```
214
214
 
215
+ :bulb: Requests with no matching route fall back to the corresponding [BasicWorker](#arrow_right-basic-worker) method.
216
+
215
217
  <br>
216
218
 
217
219
  ## :gear: Middleware
218
220
 
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.
222
+
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.
224
+
219
225
  ### CORS
220
226
 
227
+ Register the built-in CORS middleware as follows:
228
+
229
+ :page_facing_up: index.ts
230
+
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
+ ```
263
+
264
+ :bulb: The middleware adds CORS headers to the response **ONLY** if the request includes an `Origin` header.
265
+
221
266
  ### Cache
222
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
+
223
404
  ### Custom
224
405
 
225
406
  <br>
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
  *