Loading CHANGES.md +11 −0 Original line number Diff line number Diff line Loading @@ -41,13 +41,24 @@ To be released. Note that 1.6.0 was skipped due to a mistake in the versioning. - Added `HttpMessageSignaturesSpecDeterminer` interface. - Added `--first-knock` option to `fedify lookup` command. - Fedify now supports [Cloudflare Workers]. [[#233]] - Added `Federation.processQueuedTask()` method. [[#242]] - Added `Message` type. [[#242]] - Added `WorkersKvStore` class. [[#241], [#242]] - Added `WorkersMessageQueue` class. [[#241], [#242]] - The minimum supported version of Node.js is now 22.0.0. [RFC 9421]: https://www.rfc-editor.org/rfc/rfc9421 [Cloudflare Workers]: https://workers.cloudflare.com/ [#208]: https://github.com/fedify-dev/fedify/issues/208 [#227]: https://github.com/fedify-dev/fedify/issues/227 [#233]: https://github.com/fedify-dev/fedify/issues/233 [#235]: https://github.com/fedify-dev/fedify/pull/235 [#237]: https://github.com/fedify-dev/fedify/pull/237 [#241]: https://github.com/fedify-dev/fedify/issues/241 [#242]: https://github.com/fedify-dev/fedify/pull/242 Version 1.5.3 Loading docs/.vitepress/config.mts +5 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import deflist from "markdown-it-deflist"; import footnote from "markdown-it-footnote"; import { jsrRef } from "markdown-it-jsr-ref"; import process from "node:process"; import { ModuleKind, ModuleResolutionKind, ScriptTarget } from "typescript"; import { defineConfig } from "vitepress"; import { groupIconMdPlugin, Loading Loading @@ -210,12 +211,16 @@ export default withMermaid(defineConfig({ transformerTwoslash({ twoslashOptions: { compilerOptions: { moduleResolution: ModuleResolutionKind.Bundler, module: ModuleKind.ESNext, target: ScriptTarget.ESNext, lib: ["dom", "dom.iterable", "esnext"], types: [ "dom", "dom.iterable", "esnext", "@teidesu/deno-types/full", "@cloudflare/workers-types/experimental", ], // @ts-ignore: Although it's typed as string, it's actually an array jsx: ["react-jsx"], Loading docs/manual/kv.md +50 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,56 @@ const federation = createFederation<void>({ [`PostgresKvStore`]: https://jsr.io/@fedify/postgres/doc/kv/~/PostgresKvStore [@fedify/postgres]: https://github.com/fedify-dev/postgres ### `WorkersKvStore` (Cloudflare Workers only) *This API is available since Fedify 1.6.0.* `WorkersKvStore` is a key–value store implementation for [Cloudflare Workers] that uses Cloudflare's built-in [Cloudflare Workers KV] API. It provides persistent storage and good performance for Cloudflare Workers environments. It's suitable for production use in Cloudflare Workers applications. Best for : Production use in Cloudflare Workers environments. Pros : Persistent storage, good performance, easy to set up. Cons : Only available in Cloudflare Workers runtime. ~~~~ typescript twoslash // @noErrors: 2345 import type { FederationBuilder } from "@fedify/fedify"; const builder = undefined as unknown as FederationBuilder<void>; // ---cut-before--- import type { Federation } from "@fedify/fedify"; import { WorkersKvStore } from "@fedify/fedify/x/cfworkers"; export default { async fetch(request, env, ctx) { const federation: Federation<void> = await builder.build({ kv: new WorkersKvStore(env.KV_BINDING), }); return await federation.fetch(request, { contextData: undefined }); } } satisfies ExportedHandler<{ KV_BINDING: KVNamespace<string> }>; ~~~~ > [!NOTE] > Since your `KVNamespace` is not bound to a global variable, but rather > passed as an argument to the `fetch()` method, you need to instantiate > your `Federation` object inside the `fetch()` method, rather than the top > level. > > For better organization, you probably want to use a builder pattern to > register your dispatchers and listeners before instantiating the `Federation` > object. See the [*Builder pattern for structuring* > section](./federation.md#builder-pattern-for-structuring) for details. [Cloudflare Workers]: https://workers.cloudflare.com/ [Cloudflare Workers KV]: https://developers.cloudflare.com/kv/ Implementing a custom `KvStore` ------------------------------- Loading docs/manual/mq.md +82 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,88 @@ const federation = createFederation({ [@fedify/amqp]: https://github.com/fedify-dev/amqp [RabbitMQ]: https://www.rabbitmq.com/ ### `WorkersMessageQueue` (Cloudflare Workers only) *This API is available since Fedify 1.6.0.* `WorkersMessageQueue` is a message queue implementation for [Cloudflare Workers] that uses Cloudflare's built-in [Cloudflare Queues] API. It provides scalability and high performance, making it suitable for production use in Cloudflare Workers environments. It requires a Cloudflare Queues setup and management. Best for : Production use in Cloudflare Workers environments. Pros : Persistent, reliable, scalable, easy to set up. Cons : Only available in Cloudflare Workers runtime. ~~~~ typescript twoslash // @noErrors: 2322 2345 import type { FederationBuilder, KvStore } from "@fedify/fedify"; const builder = undefined as unknown as FederationBuilder<void>; // ---cut-before--- import type { Federation, Message } from "@fedify/fedify"; import { WorkersMessageQueue } from "@fedify/fedify/x/cfworkers"; export default { async fetch(request, env, ctx) { const federation: Federation<void> = await builder.build({ // ---cut-start--- kv: undefined as unknown as KvStore, // ---cut-end--- queue: new WorkersMessageQueue(env.QUEUE_BINDING), }); // Omit the rest of the code for brevity }, // Since defining a `queue()` method is the only way to consume messages // from the queue in Cloudflare Workers, we need to define it so that // the messages can be manually processed by `Federation.processQueuedTask()` // method: async queue(batch, env, ctx) { const federation: Federation<void> = await builder.build({ // ---cut-start--- kv: undefined as unknown as KvStore, // ---cut-end--- queue: new WorkersMessageQueue(env.QUEUE_BINDING), }); for (const msg of batch.messages) { await federation.processQueuedTask( undefined, // You need to pass your context data here msg.body as Message, // You need to cast the message body to `Message` ); } } } satisfies ExportedHandler<{ QUEUE_BINDING: Queue }>; ~~~~ > [!NOTE] > Since your `Queue` is not bound to a global variable, but rather passed as > an argument to the `fetch()` and `queue()` methods, you need to instantiate > your `Federation` object inside these methods, rather than at the top level. > > For better organization, you probably want to use a builder pattern to > register your dispatchers and listeners before instantiating the `Federation` > object. See the [*Builder pattern for structuring* > section](./federation.md#builder-pattern-for-structuring) for details. > [!NOTE] > The [Cloudflare Queues] API does not provide a way to poll messages from > the queue, so `WorkersMessageQueue.listen()` method always throws > a `TypeError` when invoked. Instead, you should define a `queue()` method > in your Cloudflare worker, which will be called by the Cloudflare Queues > API when new messages are available in the queue. Inside the `queue()` > method, you need to call `Federation.processQueuedTask()` method to manually > process the messages. The `queue()` method is the only way to consume > messages from the queue in Cloudflare Workers. [Cloudflare Workers]: https://workers.cloudflare.com/ [Cloudflare Queues]: https://developers.cloudflare.com/queues/ Implementing a custom `MessageQueue` ------------------------------------ Loading docs/package.json +3 −1 Original line number Diff line number Diff line { "devDependencies": { "@braintree/sanitize-url": "^7.1.1", "@cloudflare/workers-types": "4.20250529.0", "@deno/kv": "^0.8.4", "@fedify/amqp": "^0.2.0", "@fedify/fedify": "^1.6.1-dev.828", "@fedify/fedify": "1.6.1-pr.242.863", "@fedify/postgres": "^0.3.0", "@fedify/redis": "^0.4.0", "@hono/node-server": "^1.13.7", Loading @@ -30,6 +31,7 @@ "mermaid": "^11.4.1", "postgres": "^3.4.5", "stringify-entities": "^4.0.4", "typescript": "^5.8.3", "vitepress": "^1.5.0", "vitepress-plugin-group-icons": "^1.3.5", "vitepress-plugin-llms": "^1.1.0", Loading Loading
CHANGES.md +11 −0 Original line number Diff line number Diff line Loading @@ -41,13 +41,24 @@ To be released. Note that 1.6.0 was skipped due to a mistake in the versioning. - Added `HttpMessageSignaturesSpecDeterminer` interface. - Added `--first-knock` option to `fedify lookup` command. - Fedify now supports [Cloudflare Workers]. [[#233]] - Added `Federation.processQueuedTask()` method. [[#242]] - Added `Message` type. [[#242]] - Added `WorkersKvStore` class. [[#241], [#242]] - Added `WorkersMessageQueue` class. [[#241], [#242]] - The minimum supported version of Node.js is now 22.0.0. [RFC 9421]: https://www.rfc-editor.org/rfc/rfc9421 [Cloudflare Workers]: https://workers.cloudflare.com/ [#208]: https://github.com/fedify-dev/fedify/issues/208 [#227]: https://github.com/fedify-dev/fedify/issues/227 [#233]: https://github.com/fedify-dev/fedify/issues/233 [#235]: https://github.com/fedify-dev/fedify/pull/235 [#237]: https://github.com/fedify-dev/fedify/pull/237 [#241]: https://github.com/fedify-dev/fedify/issues/241 [#242]: https://github.com/fedify-dev/fedify/pull/242 Version 1.5.3 Loading
docs/.vitepress/config.mts +5 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import deflist from "markdown-it-deflist"; import footnote from "markdown-it-footnote"; import { jsrRef } from "markdown-it-jsr-ref"; import process from "node:process"; import { ModuleKind, ModuleResolutionKind, ScriptTarget } from "typescript"; import { defineConfig } from "vitepress"; import { groupIconMdPlugin, Loading Loading @@ -210,12 +211,16 @@ export default withMermaid(defineConfig({ transformerTwoslash({ twoslashOptions: { compilerOptions: { moduleResolution: ModuleResolutionKind.Bundler, module: ModuleKind.ESNext, target: ScriptTarget.ESNext, lib: ["dom", "dom.iterable", "esnext"], types: [ "dom", "dom.iterable", "esnext", "@teidesu/deno-types/full", "@cloudflare/workers-types/experimental", ], // @ts-ignore: Although it's typed as string, it's actually an array jsx: ["react-jsx"], Loading
docs/manual/kv.md +50 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,56 @@ const federation = createFederation<void>({ [`PostgresKvStore`]: https://jsr.io/@fedify/postgres/doc/kv/~/PostgresKvStore [@fedify/postgres]: https://github.com/fedify-dev/postgres ### `WorkersKvStore` (Cloudflare Workers only) *This API is available since Fedify 1.6.0.* `WorkersKvStore` is a key–value store implementation for [Cloudflare Workers] that uses Cloudflare's built-in [Cloudflare Workers KV] API. It provides persistent storage and good performance for Cloudflare Workers environments. It's suitable for production use in Cloudflare Workers applications. Best for : Production use in Cloudflare Workers environments. Pros : Persistent storage, good performance, easy to set up. Cons : Only available in Cloudflare Workers runtime. ~~~~ typescript twoslash // @noErrors: 2345 import type { FederationBuilder } from "@fedify/fedify"; const builder = undefined as unknown as FederationBuilder<void>; // ---cut-before--- import type { Federation } from "@fedify/fedify"; import { WorkersKvStore } from "@fedify/fedify/x/cfworkers"; export default { async fetch(request, env, ctx) { const federation: Federation<void> = await builder.build({ kv: new WorkersKvStore(env.KV_BINDING), }); return await federation.fetch(request, { contextData: undefined }); } } satisfies ExportedHandler<{ KV_BINDING: KVNamespace<string> }>; ~~~~ > [!NOTE] > Since your `KVNamespace` is not bound to a global variable, but rather > passed as an argument to the `fetch()` method, you need to instantiate > your `Federation` object inside the `fetch()` method, rather than the top > level. > > For better organization, you probably want to use a builder pattern to > register your dispatchers and listeners before instantiating the `Federation` > object. See the [*Builder pattern for structuring* > section](./federation.md#builder-pattern-for-structuring) for details. [Cloudflare Workers]: https://workers.cloudflare.com/ [Cloudflare Workers KV]: https://developers.cloudflare.com/kv/ Implementing a custom `KvStore` ------------------------------- Loading
docs/manual/mq.md +82 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,88 @@ const federation = createFederation({ [@fedify/amqp]: https://github.com/fedify-dev/amqp [RabbitMQ]: https://www.rabbitmq.com/ ### `WorkersMessageQueue` (Cloudflare Workers only) *This API is available since Fedify 1.6.0.* `WorkersMessageQueue` is a message queue implementation for [Cloudflare Workers] that uses Cloudflare's built-in [Cloudflare Queues] API. It provides scalability and high performance, making it suitable for production use in Cloudflare Workers environments. It requires a Cloudflare Queues setup and management. Best for : Production use in Cloudflare Workers environments. Pros : Persistent, reliable, scalable, easy to set up. Cons : Only available in Cloudflare Workers runtime. ~~~~ typescript twoslash // @noErrors: 2322 2345 import type { FederationBuilder, KvStore } from "@fedify/fedify"; const builder = undefined as unknown as FederationBuilder<void>; // ---cut-before--- import type { Federation, Message } from "@fedify/fedify"; import { WorkersMessageQueue } from "@fedify/fedify/x/cfworkers"; export default { async fetch(request, env, ctx) { const federation: Federation<void> = await builder.build({ // ---cut-start--- kv: undefined as unknown as KvStore, // ---cut-end--- queue: new WorkersMessageQueue(env.QUEUE_BINDING), }); // Omit the rest of the code for brevity }, // Since defining a `queue()` method is the only way to consume messages // from the queue in Cloudflare Workers, we need to define it so that // the messages can be manually processed by `Federation.processQueuedTask()` // method: async queue(batch, env, ctx) { const federation: Federation<void> = await builder.build({ // ---cut-start--- kv: undefined as unknown as KvStore, // ---cut-end--- queue: new WorkersMessageQueue(env.QUEUE_BINDING), }); for (const msg of batch.messages) { await federation.processQueuedTask( undefined, // You need to pass your context data here msg.body as Message, // You need to cast the message body to `Message` ); } } } satisfies ExportedHandler<{ QUEUE_BINDING: Queue }>; ~~~~ > [!NOTE] > Since your `Queue` is not bound to a global variable, but rather passed as > an argument to the `fetch()` and `queue()` methods, you need to instantiate > your `Federation` object inside these methods, rather than at the top level. > > For better organization, you probably want to use a builder pattern to > register your dispatchers and listeners before instantiating the `Federation` > object. See the [*Builder pattern for structuring* > section](./federation.md#builder-pattern-for-structuring) for details. > [!NOTE] > The [Cloudflare Queues] API does not provide a way to poll messages from > the queue, so `WorkersMessageQueue.listen()` method always throws > a `TypeError` when invoked. Instead, you should define a `queue()` method > in your Cloudflare worker, which will be called by the Cloudflare Queues > API when new messages are available in the queue. Inside the `queue()` > method, you need to call `Federation.processQueuedTask()` method to manually > process the messages. The `queue()` method is the only way to consume > messages from the queue in Cloudflare Workers. [Cloudflare Workers]: https://workers.cloudflare.com/ [Cloudflare Queues]: https://developers.cloudflare.com/queues/ Implementing a custom `MessageQueue` ------------------------------------ Loading
docs/package.json +3 −1 Original line number Diff line number Diff line { "devDependencies": { "@braintree/sanitize-url": "^7.1.1", "@cloudflare/workers-types": "4.20250529.0", "@deno/kv": "^0.8.4", "@fedify/amqp": "^0.2.0", "@fedify/fedify": "^1.6.1-dev.828", "@fedify/fedify": "1.6.1-pr.242.863", "@fedify/postgres": "^0.3.0", "@fedify/redis": "^0.4.0", "@hono/node-server": "^1.13.7", Loading @@ -30,6 +31,7 @@ "mermaid": "^11.4.1", "postgres": "^3.4.5", "stringify-entities": "^4.0.4", "typescript": "^5.8.3", "vitepress": "^1.5.0", "vitepress-plugin-group-icons": "^1.3.5", "vitepress-plugin-llms": "^1.1.0", Loading