@oselvar/sveltekit-add-worker-exports 2.2.0 → 2.2.2
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 +44 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +41 -7
- package/dist/moduleRules.d.ts +13 -1
- package/dist/moduleRules.js +2 -0
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A Vite plugin that makes any class-based Cloudflare Worker export (Durable Objec
|
|
|
4
4
|
|
|
5
5
|
Works with **SvelteKit 2 and SvelteKit 3** (see [`example/`](example) and [`example-v3/`](example-v3)).
|
|
6
6
|
|
|
7
|
-
The examples below use SvelteKit 2's `platform.env`. SvelteKit 3's `adapter-cloudflare` (8.
|
|
7
|
+
The examples below use SvelteKit 2's `platform.env`. SvelteKit 3's `adapter-cloudflare` (8.x) no longer provides `event.platform`: read bindings with `import { env } from 'cloudflare:workers'` instead, as [`example-v3/`](example-v3) does. The plugin's dev-registry wiring works the same either way.
|
|
8
8
|
|
|
9
9
|
**Build mode:** SvelteKit's `adapter-cloudflare` generates `_worker.js` with only a default export (the fetch handler). Cloudflare Workers requires class-based bindings (Durable Objects, Workflows, `WorkerEntrypoint`, etc.) to be **named exports**, and non-fetch handlers (`scheduled`, `queue`, `email`, …) to be **methods on the default export**. This plugin post-processes the build output to merge both kinds onto SvelteKit's worker.
|
|
10
10
|
|
|
@@ -63,18 +63,48 @@ Point `adapter-cloudflare`'s platform proxy at the generated `.platform-proxy-wr
|
|
|
63
63
|
```javascript
|
|
64
64
|
// svelte.config.js
|
|
65
65
|
import adapter from '@sveltejs/adapter-cloudflare';
|
|
66
|
+
import { fileURLToPath } from 'node:url';
|
|
66
67
|
|
|
67
68
|
export default {
|
|
68
69
|
kit: {
|
|
69
70
|
adapter: adapter({
|
|
70
71
|
platformProxy: {
|
|
71
|
-
configPath: '.platform-proxy-wrangler.jsonc'
|
|
72
|
+
configPath: '.platform-proxy-wrangler.jsonc',
|
|
73
|
+
persist: { path: fileURLToPath(new URL('.wrangler/state', import.meta.url)) }
|
|
72
74
|
}
|
|
73
75
|
})
|
|
74
76
|
}
|
|
75
77
|
};
|
|
76
78
|
```
|
|
77
79
|
|
|
80
|
+
> [!IMPORTANT]
|
|
81
|
+
> **Always set `persist.path` to an absolute path**, as above. Leaving `persist` out is not enough: the default path is relative too. With wrangler 4.129 and later, every Workflow `create()` call in `vite dev` then fails with `Failed to wait for persisted workflow instance '…' deletion`, because miniflare rejects relative persist paths for Workflows.
|
|
82
|
+
|
|
83
|
+
On SvelteKit 3, which no longer reads `svelte.config.js`, pass the same options to `sveltekit()` in `vite.config.ts`:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// vite.config.ts (SvelteKit 3)
|
|
87
|
+
import { sveltekit } from '@sveltejs/kit/vite';
|
|
88
|
+
import adapter from '@sveltejs/adapter-cloudflare';
|
|
89
|
+
import { addWorkerExports } from '@oselvar/sveltekit-add-worker-exports';
|
|
90
|
+
import { defineConfig } from 'vite';
|
|
91
|
+
import { fileURLToPath } from 'node:url';
|
|
92
|
+
|
|
93
|
+
export default defineConfig({
|
|
94
|
+
plugins: [
|
|
95
|
+
await sveltekit({
|
|
96
|
+
adapter: adapter({
|
|
97
|
+
platformProxy: {
|
|
98
|
+
configPath: '.platform-proxy-wrangler.jsonc',
|
|
99
|
+
persist: { path: fileURLToPath(new URL('.wrangler/state', import.meta.url)) }
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}),
|
|
103
|
+
addWorkerExports({ entryPoint: 'src/lib/server/index.ts' })
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
78
108
|
The plugin auto-discovers your `wrangler.jsonc` (or `wrangler.toml`) and reads bindings, workflows, migrations, and compatibility settings from it. It overrides only the `main` entry point to point at your source entry.
|
|
79
109
|
|
|
80
110
|
### Calling Workflows
|
|
@@ -93,6 +123,8 @@ export const POST: RequestHandler = async ({ params, request, platform }) => {
|
|
|
93
123
|
|
|
94
124
|
The sidecar runs the real `WorkflowEntrypoint` class; calls reach it via the `script_name` rewrite in the platform-proxy config. This requires `wrangler >= 4.98.0` ([cloudflare/workers-sdk#13863](https://github.com/cloudflare/workers-sdk/pull/13863)).
|
|
95
125
|
|
|
126
|
+
If `create()` fails in dev with `Failed to wait for persisted workflow instance '…' deletion`, your `platformProxy.persist.path` is missing or relative. Set it to an absolute path, as shown in [Usage](#usage).
|
|
127
|
+
|
|
96
128
|
### Testing the production build locally
|
|
97
129
|
|
|
98
130
|
`vite dev` exercises your code via the wrangler-dev sidecar; it does *not* exercise the merged `_worker.js`. To verify the production wiring (named class exports + SvelteKit routes in the same worker), run wrangler against the build output:
|
|
@@ -116,6 +148,16 @@ A handy shortcut is to add a `preview` script to `package.json`:
|
|
|
116
148
|
|
|
117
149
|
> Note: `vite preview` is *not* suitable here — it only serves static assets and cannot run Durable Objects. Always use `wrangler dev` to preview the production worker.
|
|
118
150
|
|
|
151
|
+
### Wrangler environments
|
|
152
|
+
|
|
153
|
+
Set `CLOUDFLARE_ENV` to run dev against one of the `env` blocks in your wrangler config:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
CLOUDFLARE_ENV=staging pnpm dev
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The sidecar then behaves like `wrangler dev --env staging`: it uses `env.staging`'s bindings and `vars`, loads `.env.staging` / `.env.staging.local` (or `.dev.vars.staging`) on top of `.env` / `.env.local`, and registers as `<name>-dev-worker-staging`. As with wrangler, values in `.env` files override `vars`.
|
|
160
|
+
|
|
119
161
|
## Scheduled, queue, email, tail handlers
|
|
120
162
|
|
|
121
163
|
Cloudflare invokes non-fetch handlers (`scheduled`, `queue`, `email`, `tail`, `trace`) as methods on the worker's default export, not as named exports. Put them on the `default` export of your entry point and the plugin merges them onto the production worker's default alongside SvelteKit's fetch handler:
|
package/dist/index.d.ts
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
*
|
|
21
21
|
* @see https://github.com/sveltejs/kit/issues/1712
|
|
22
22
|
*/
|
|
23
|
-
import { type ModuleRule } from 'miniflare';
|
|
24
23
|
import type { Plugin } from 'vite';
|
|
25
|
-
|
|
24
|
+
import { type ModuleRule } from './moduleRules.js';
|
|
25
|
+
export { createModuleRulesPlugin, toModuleRule, WRANGLER_DEFAULT_MODULE_RULES, type ModuleRule, type ModuleRuleType, type WranglerRule } from './moduleRules.js';
|
|
26
26
|
/**
|
|
27
27
|
* Parses a wrangler config file. Picks the parser by extension:
|
|
28
28
|
* `.toml` uses smol-toml; everything else (`.jsonc`, `.json`, or no
|
|
@@ -146,3 +146,22 @@ export declare function deriveDevWorkerConfig(baseConfig: any, options: Pick<Add
|
|
|
146
146
|
* absolute path written.
|
|
147
147
|
*/
|
|
148
148
|
export declare function writeDevWorkerConfig(options: AddWorkerExportsOptions, outPath?: string): Promise<string>;
|
|
149
|
+
export type NodeJSCompatMode = 'als' | 'v1' | 'v2' | null;
|
|
150
|
+
/**
|
|
151
|
+
* Resolves the Node.js compat mode the way wrangler's own `getNodeCompat`
|
|
152
|
+
* does (workers-utils `node-compat.ts` / `compatibility-date.ts`).
|
|
153
|
+
*
|
|
154
|
+
* The dev sidecar passes it to `unstable_startWorker` as the
|
|
155
|
+
* `build.nodejsCompatMode` hook. wrangler before 4.113 doesn't derive the
|
|
156
|
+
* mode itself and falls back to the legacy nodejs compat plugin, which warns
|
|
157
|
+
* about `node:*` imports even with `nodejs_compat` enabled.
|
|
158
|
+
*
|
|
159
|
+
* This used to call miniflare's `getNodeCompat`, but miniflare
|
|
160
|
+
* 5.20261103.0-beta (shipped with wrangler 4.157+) no longer exports it, and
|
|
161
|
+
* importing a missing named export from miniflare (a CommonJS module) is a
|
|
162
|
+
* SyntaxError that stops the plugin from loading. miniflare 4's copy also
|
|
163
|
+
* predates the default-on date.
|
|
164
|
+
*
|
|
165
|
+
* Exported for tests.
|
|
166
|
+
*/
|
|
167
|
+
export declare function getNodejsCompatMode(compatibilityDate?: string, compatibilityFlags?: readonly string[]): NodeJSCompatMode;
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,6 @@ import { connect } from 'node:net';
|
|
|
28
28
|
import { homedir } from 'node:os';
|
|
29
29
|
import { join, resolve } from 'node:path';
|
|
30
30
|
import { parse as parseJsonc } from 'jsonc-parser';
|
|
31
|
-
import { getNodeCompat } from 'miniflare';
|
|
32
31
|
import { parse as parseToml } from 'smol-toml';
|
|
33
32
|
import { createModuleRulesPlugin, toModuleRule } from './moduleRules.js';
|
|
34
33
|
export { createModuleRulesPlugin, toModuleRule, WRANGLER_DEFAULT_MODULE_RULES } from './moduleRules.js';
|
|
@@ -417,6 +416,14 @@ function devPlugins(options) {
|
|
|
417
416
|
await removeDeadRegistryEntry(registryPath, registeredSidecarName);
|
|
418
417
|
worker = await unstable_startWorker({
|
|
419
418
|
config: tempConfigPath,
|
|
419
|
+
// Wrangler falls back to CLOUDFLARE_ENV when resolving the
|
|
420
|
+
// config (and the sidecar's name), but not when choosing which
|
|
421
|
+
// `.env` / `.dev.vars` files to load: without `env`, only `.env`
|
|
422
|
+
// and `.env.local` are read, and they override the env's `vars`.
|
|
423
|
+
// Passing it adds `.env.<env>` / `.dev.vars.<env>`, matching
|
|
424
|
+
// `wrangler dev --env <env>`. See
|
|
425
|
+
// https://github.com/oselvar/sveltekit-add-worker-exports/issues/11
|
|
426
|
+
env: process.env.CLOUDFLARE_ENV,
|
|
420
427
|
// `testScheduled` mounts a `/__scheduled` endpoint on the sidecar
|
|
421
428
|
// so cron handlers can be invoked manually in dev — wrangler dev
|
|
422
429
|
// never auto-fires crons. Curl
|
|
@@ -476,12 +483,39 @@ async function exists(path) {
|
|
|
476
483
|
return false;
|
|
477
484
|
}
|
|
478
485
|
}
|
|
486
|
+
/** From this compatibility date, `nodejs_compat` is on unless `no_nodejs_compat` is set. */
|
|
487
|
+
const NODEJS_COMPAT_DEFAULT_ON_DATE = '2026-08-04';
|
|
488
|
+
/** From this compatibility date, `nodejs_compat` means v2. */
|
|
489
|
+
const NODEJS_COMPAT_V2_SWITCH_OVER_DATE = '2024-09-23';
|
|
479
490
|
/**
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
* `
|
|
491
|
+
* Resolves the Node.js compat mode the way wrangler's own `getNodeCompat`
|
|
492
|
+
* does (workers-utils `node-compat.ts` / `compatibility-date.ts`).
|
|
493
|
+
*
|
|
494
|
+
* The dev sidecar passes it to `unstable_startWorker` as the
|
|
495
|
+
* `build.nodejsCompatMode` hook. wrangler before 4.113 doesn't derive the
|
|
496
|
+
* mode itself and falls back to the legacy nodejs compat plugin, which warns
|
|
497
|
+
* about `node:*` imports even with `nodejs_compat` enabled.
|
|
498
|
+
*
|
|
499
|
+
* This used to call miniflare's `getNodeCompat`, but miniflare
|
|
500
|
+
* 5.20261103.0-beta (shipped with wrangler 4.157+) no longer exports it, and
|
|
501
|
+
* importing a missing named export from miniflare (a CommonJS module) is a
|
|
502
|
+
* SyntaxError that stops the plugin from loading. miniflare 4's copy also
|
|
503
|
+
* predates the default-on date.
|
|
504
|
+
*
|
|
505
|
+
* Exported for tests.
|
|
484
506
|
*/
|
|
485
|
-
function getNodejsCompatMode(compatibilityDate, compatibilityFlags = []) {
|
|
486
|
-
|
|
507
|
+
export function getNodejsCompatMode(compatibilityDate = '2000-01-01', compatibilityFlags = []) {
|
|
508
|
+
const has = (flag) => compatibilityFlags.includes(flag);
|
|
509
|
+
const isDefaultOn = compatibilityDate >= NODEJS_COMPAT_DEFAULT_ON_DATE;
|
|
510
|
+
const isV1Enabled = has('nodejs_compat') || (isDefaultOn && !has('no_nodejs_compat'));
|
|
511
|
+
const isV2Enabled = has('nodejs_compat_v2') ||
|
|
512
|
+
(!has('no_nodejs_compat_v2') &&
|
|
513
|
+
(isDefaultOn || (isV1Enabled && compatibilityDate >= NODEJS_COMPAT_V2_SWITCH_OVER_DATE)));
|
|
514
|
+
if (isV2Enabled)
|
|
515
|
+
return 'v2';
|
|
516
|
+
if (isV1Enabled)
|
|
517
|
+
return 'v1';
|
|
518
|
+
if (has('nodejs_als'))
|
|
519
|
+
return 'als';
|
|
520
|
+
return null;
|
|
487
521
|
}
|
package/dist/moduleRules.d.ts
CHANGED
|
@@ -21,7 +21,19 @@
|
|
|
21
21
|
* (`**\/*.sql`, `**\/*.txt`) behave identically under both.
|
|
22
22
|
*/
|
|
23
23
|
import type { Plugin as EsbuildPlugin } from 'esbuild';
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Declared here rather than imported: miniflare 4 calls these `ModuleRuleType`
|
|
26
|
+
* / `ModuleRule`, miniflare 5 renamed them to `V4ModuleRuleType` /
|
|
27
|
+
* `V4ModuleRule`. The shape is identical in both, so this type-checks against
|
|
28
|
+
* whichever miniflare the consumer has.
|
|
29
|
+
*/
|
|
30
|
+
export type ModuleRuleType = 'ESModule' | 'CommonJS' | 'Text' | 'Data' | 'CompiledWasm' | 'PythonModule' | 'PythonRequirement';
|
|
31
|
+
/** A module rule in miniflare's shape. */
|
|
32
|
+
export interface ModuleRule {
|
|
33
|
+
type: ModuleRuleType;
|
|
34
|
+
include: string[];
|
|
35
|
+
fallthrough?: boolean;
|
|
36
|
+
}
|
|
25
37
|
/** A module rule as it appears in wrangler config (miniflare uses `include`). */
|
|
26
38
|
export interface WranglerRule {
|
|
27
39
|
type: ModuleRuleType;
|
package/dist/moduleRules.js
CHANGED
|
@@ -53,6 +53,8 @@ export function createModuleRulesPlugin(userRules) {
|
|
|
53
53
|
// JS rules are dropped from the match loop — esbuild's default handling is
|
|
54
54
|
// exactly their meaning — but they still participate in fallthrough
|
|
55
55
|
// finalisation above, like in wrangler.
|
|
56
|
+
// The cast pins `type` to our `ModuleRuleType`: miniflare 4 declares it as
|
|
57
|
+
// a `z.infer<…>` that TypeScript 7 doesn't narrow to the string union.
|
|
56
58
|
const kept = compileModuleRules(allRules).filter((rule) => !isJavaScriptRuleType(rule.type));
|
|
57
59
|
// Recompute which rules `compileModuleRules` dropped, so files matching
|
|
58
60
|
// only a shadowed rule get wrangler's error instead of esbuild's opaque
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oselvar/sveltekit-add-worker-exports",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Vite plugin that adds Durable Object and Workflow exports to SvelteKit Cloudflare workers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -40,16 +40,16 @@
|
|
|
40
40
|
"wrangler": ">=4"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@release-it/conventional-changelog": "^
|
|
44
|
-
"@sveltejs/kit": "^2.70.
|
|
45
|
-
"@types/node": "^26.6.
|
|
43
|
+
"@release-it/conventional-changelog": "^12.0.2",
|
|
44
|
+
"@sveltejs/kit": "^2.70.4",
|
|
45
|
+
"@types/node": "^26.6.6",
|
|
46
46
|
"esbuild": "^0.28.2",
|
|
47
|
-
"miniflare": "
|
|
48
|
-
"release-it": "^
|
|
47
|
+
"miniflare": "5.20261109.0-beta",
|
|
48
|
+
"release-it": "^21.1.2",
|
|
49
49
|
"typescript": "^7.0.2",
|
|
50
|
-
"vite": "^8.3.
|
|
51
|
-
"vitest": "^
|
|
52
|
-
"wrangler": "^4.
|
|
50
|
+
"vite": "^8.3.7",
|
|
51
|
+
"vitest": "^5.1.0",
|
|
52
|
+
"wrangler": "^4.159.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsc",
|
|
@@ -68,6 +68,6 @@
|
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"jsonc-parser": "^3.3.1",
|
|
71
|
-
"smol-toml": "^1.
|
|
71
|
+
"smol-toml": "^1.9.1"
|
|
72
72
|
}
|
|
73
73
|
}
|