Skip to content
This repository has been archived by the owner on Feb 10, 2025. It is now read-only.

Commit

Permalink
feat(cloudflare): add runtime persistence directory option (#23)
Browse files Browse the repository at this point in the history
Co-authored-by: Sarah Rainsberger <[email protected]>
  • Loading branch information
alexanderniebuhr and sarah11918 authored Oct 19, 2023
1 parent c3b2b59 commit 4a03af2
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 21 deletions.
7 changes: 7 additions & 0 deletions .changeset/rich-foxes-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@astrojs/cloudflare': minor
---

Adds a new property `persistTo` which allows setting the directory for local state files when using Cloudflare runtime with `astro dev`. This is useful when you want to persist state between restarts of the dev server, for example when using KV, D1, R2 to store data.

Additionally, updates the format of the `runtime` configuration and adds a warning when the deprecated format is used. The current format is now `runtime: { mode: 'off' | 'local', persistTo: string }`. See [runtime documentation](https://docs.astro.build/en/guides/integrations-guide/cloudflare/#runtime) for more information.
1 change: 1 addition & 0 deletions packages/cloudflare/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Astro cloudflare directory mode creates a function directory
functions
.mf
.wrangler
14 changes: 11 additions & 3 deletions packages/cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,25 @@ export default defineConfig({

### `runtime`

`runtime: "off" | "local"`
`runtime: { mode: "off" | "local", persistTo: string }`

default `"off"`
default `{ mode: 'off', persistTo: '' }`

Determines whether and how the Cloudflare Runtime is added to `astro dev`.

The Cloudflare Runtime includes [Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/bindings), [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables), and the [cf object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties). Read more about [accessing the Cloudflare Runtime](#cloudflare-runtime).

The `mode` property defines how the runtime is added to `astro dev`:

- `local`: uses bindings mocking and locally static placeholders
- `off`: no access to the Cloudflare runtime using `astro dev`. You can alternatively use [Preview with Wrangler](#preview-with-wrangler)

The `persistTo` property defines where the local runtime is persisted to when using `mode: local`. This value is a directory relative to your `astro dev` execution path.

The default value is set to `.wrangler/state/v3` to match the default path Wrangler uses. This means both tools are able to access and use the local state.

Whichever directory is set in `persistTo`, `.wrangler` or your custom value, must be added to `.gitignore`.

```diff lang="js"
// astro.config.mjs
import { defineConfig } from 'astro/config';
Expand All @@ -205,7 +213,7 @@ import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare({
+ runtime: 'local',
+ runtime: { mode: 'local' },
}),
});
```
Expand Down
53 changes: 44 additions & 9 deletions packages/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { wasmModuleLoader } from './utils/wasm-module-loader.js';
export type { AdvancedRuntime } from './entrypoints/server.advanced.js';
export type { DirectoryRuntime } from './entrypoints/server.directory.js';

type CF_RUNTIME = { mode: 'off' } | { mode: 'remote' } | { mode: 'local'; persistTo: string };
type Options = {
mode?: 'directory' | 'advanced';
functionPerRoute?: boolean;
Expand All @@ -43,11 +44,18 @@ type Options = {
exclude?: string[];
};
/**
* Going forward only the object API should be used. The modes work as known before:
* 'off': current behaviour (wrangler is needed)
* 'local': use a static req.cf object, and env vars defined in wrangler.toml & .dev.vars (astro dev is enough)
* 'remote': use a dynamic real-live req.cf object, and env vars defined in wrangler.toml & .dev.vars (astro dev is enough)
*/
runtime?: 'off' | 'local' | 'remote';
runtime?:
| 'off'
| 'local'
| 'remote'
| { mode: 'off' }
| { mode: 'remote' }
| { mode: 'local'; persistTo?: string };
wasmModuleImports?: boolean;
};

Expand All @@ -59,6 +67,14 @@ interface BuildConfig {
split?: boolean;
}

const RUNTIME_WARNING = `You are using a deprecated string format for the \`runtime\` API. Please update to the current format for better support.
Example:
Old Format: 'local'
Current Format: { mode: 'local', persistTo: '.wrangler/state/v3' }
Please refer to our runtime documentation for more details on the format. https://docs.astro.build/en/guides/integrations-guide/cloudflare/#runtime`;

export default function createIntegration(args?: Options): AstroIntegration {
let _config: AstroConfig;
let _buildConfig: BuildConfig;
Expand All @@ -69,7 +85,21 @@ export default function createIntegration(args?: Options): AstroIntegration {

const isModeDirectory = args?.mode === 'directory';
const functionPerRoute = args?.functionPerRoute ?? false;
const runtimeMode = args?.runtime ?? 'off';

let runtimeMode: CF_RUNTIME = { mode: 'off' };
if (args?.runtime === 'remote') {
runtimeMode = { mode: 'remote' };
} else if (args?.runtime === 'local') {
runtimeMode = { mode: 'local', persistTo: '.wrangler/state/v3' };
} else if (
typeof args?.runtime === 'object' &&
args?.runtime.mode === 'local' &&
args.runtime.persistTo === undefined
) {
runtimeMode = { mode: 'local', persistTo: '.wrangler/state/v3' };
} else {
runtimeMode = args?.runtime as CF_RUNTIME;
}

return {
name: '@astrojs/cloudflare',
Expand All @@ -93,7 +123,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
},
});
},
'astro:config:done': ({ setAdapter, config }) => {
'astro:config:done': ({ setAdapter, config, logger }) => {
setAdapter(getAdapter({ isModeDirectory, functionPerRoute }));
_config = config;
_buildConfig = config.build;
Expand All @@ -109,12 +139,17 @@ export default function createIntegration(args?: Options): AstroIntegration {
'[@astrojs/cloudflare] `base: "${SERVER_BUILD_FOLDER}"` is not allowed. Please change your `base` config to something else.'
);
}

if (typeof args?.runtime === 'string') {
logger.warn(RUNTIME_WARNING);
}
},
'astro:server:setup': ({ server }) => {
if (runtimeMode !== 'off') {
if (runtimeMode.mode === 'local') {
const typedRuntimeMode = runtimeMode;
server.middlewares.use(async function middleware(req, res, next) {
try {
const cf = await getCFObject(runtimeMode);
const cf = await getCFObject(typedRuntimeMode.mode);
const vars = await getEnvVars();
const D1Bindings = await getD1Bindings();
const R2Bindings = await getR2Bindings();
Expand All @@ -134,13 +169,13 @@ export default function createIntegration(args?: Options): AstroIntegration {
cachePersist: true,
cacheWarnUsage: true,
d1Databases: D1Bindings,
d1Persist: true,
d1Persist: `${typedRuntimeMode.persistTo}/d1`,
r2Buckets: R2Bindings,
r2Persist: true,
r2Persist: `${typedRuntimeMode.persistTo}/r2`,
kvNamespaces: KVBindings,
kvPersist: true,
kvPersist: `${typedRuntimeMode.persistTo}/kv`,
durableObjects: DOBindings,
durableObjectsPersist: true,
durableObjectsPersist: `${typedRuntimeMode.persistTo}/do`,
});
await _mf.ready;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';


export default defineConfig({
adapter: cloudflare({
runtime: 'local'
runtime: {
mode: 'local',
},
}),
output: 'server',
});
3 changes: 3 additions & 0 deletions packages/cloudflare/test/fixtures/dev-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"dependencies": {
"@astrojs/cloudflare": "workspace:*",
"astro": "^3.2.3"
},
"devDependencies": {
"wrangler": "^3.13.1"
}
}
37 changes: 30 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4a03af2

Please sign in to comment.