@oselvar/sveltekit-add-worker-exports 0.1.3 → 0.3.0
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 +21 -1
- package/dist/index.js +45 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A Vite plugin that makes Durable Objects and Workflows work with SvelteKit on Cl
|
|
|
4
4
|
|
|
5
5
|
**Build mode:** SvelteKit's `adapter-cloudflare` generates `_worker.js` with only a default export (the fetch handler). Cloudflare Workers requires Durable Object and Workflow classes to be **named exports**. This plugin post-processes the build output to merge your named exports with SvelteKit's default export.
|
|
6
6
|
|
|
7
|
-
**Dev mode:** `getPlatformProxy` (used by `adapter-cloudflare` in dev) can't run internal Durable Objects. This plugin starts a separate wrangler dev server that runs the real DO worker with hot-reload. Clients connect directly to
|
|
7
|
+
**Dev mode:** `getPlatformProxy` (used by `adapter-cloudflare` in dev) can't run internal Durable Objects or Workflows. This plugin starts a separate wrangler dev server that runs the real DO/Workflow worker with hot-reload. SvelteKit `+server.ts` handlers call DOs through `platform.env.MY_DO.<rpc>()` as usual — the plugin rewrites those bindings to point at the sidecar via wrangler's dev registry, so cross-worker calls Just Work. Clients can also connect directly to the sidecar via WebSocket on a separate port (see below).
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -21,9 +21,12 @@ Create a worker entry point that exports your Durable Object classes and a defau
|
|
|
21
21
|
```typescript
|
|
22
22
|
// src/lib/server/index.ts
|
|
23
23
|
export { MyDurableObject } from './MyDurableObject';
|
|
24
|
+
export { MyWorkflow } from './MyWorkflow';
|
|
24
25
|
export { default } from './devHandler';
|
|
25
26
|
```
|
|
26
27
|
|
|
28
|
+
Workflow classes (extending `WorkflowEntrypoint`) are exported the same way as Durable Objects — the plugin merges them into `_worker.js` as named exports. Declare them in `wrangler.jsonc` under `workflows`, and they become available as bindings (e.g. `env.MY_WORKFLOW.create({ params })`) in both dev and production.
|
|
29
|
+
|
|
27
30
|
Both the dev handler and the production SvelteKit route need to do the same thing: validate the upgrade header and forward the request to a Durable Object. Extract that into a small helper so the two callers stay in sync:
|
|
28
31
|
|
|
29
32
|
```typescript
|
|
@@ -84,6 +87,23 @@ export default defineConfig({
|
|
|
84
87
|
});
|
|
85
88
|
```
|
|
86
89
|
|
|
90
|
+
Point `adapter-cloudflare`'s platform proxy at the generated `.platform-proxy-wrangler.jsonc`. The plugin writes this file with internal Durable Object bindings rewritten to cross-worker form (each gets a `script_name` pointing at the sidecar). Workflows and migrations are stripped — calling a Workflow from `platform.env` in vite dev isn't supported, but it works in production. Without this config path, `getPlatformProxy` would try to run the classes itself and warn that it can't:
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// svelte.config.js
|
|
94
|
+
import adapter from '@sveltejs/adapter-cloudflare';
|
|
95
|
+
|
|
96
|
+
export default {
|
|
97
|
+
kit: {
|
|
98
|
+
adapter: adapter({
|
|
99
|
+
platformProxy: {
|
|
100
|
+
configPath: '.platform-proxy-wrangler.jsonc'
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
```
|
|
106
|
+
|
|
87
107
|
### Dev mode: connecting to Durable Objects
|
|
88
108
|
|
|
89
109
|
In dev mode, the plugin starts a wrangler dev server on a separate port and injects `__DEV_WORKER_PORT__` as a compile-time constant. Use it to connect your client:
|
package/dist/index.js
CHANGED
|
@@ -17,10 +17,31 @@
|
|
|
17
17
|
* @see https://github.com/sveltejs/kit/issues/1712
|
|
18
18
|
*/
|
|
19
19
|
import { build } from 'esbuild';
|
|
20
|
+
import { existsSync } from 'node:fs';
|
|
20
21
|
import { access, readFile, rename, writeFile, unlink } from 'node:fs/promises';
|
|
21
|
-
import {
|
|
22
|
+
import { homedir } from 'node:os';
|
|
23
|
+
import { join, resolve } from 'node:path';
|
|
22
24
|
import { parse as parseJsonc } from 'jsonc-parser';
|
|
23
25
|
const DEFAULT_DEV_PORT = 8787;
|
|
26
|
+
/**
|
|
27
|
+
* Mirrors wrangler's internal getRegistryPath() — wrangler doesn't export it.
|
|
28
|
+
* Workers register themselves under this path so cross-worker `script_name`
|
|
29
|
+
* bindings can find each other.
|
|
30
|
+
*/
|
|
31
|
+
function getWranglerRegistryPath() {
|
|
32
|
+
if (process.env.WRANGLER_REGISTRY_PATH)
|
|
33
|
+
return process.env.WRANGLER_REGISTRY_PATH;
|
|
34
|
+
const legacy = join(homedir(), '.wrangler');
|
|
35
|
+
if (existsSync(legacy))
|
|
36
|
+
return join(legacy, 'registry');
|
|
37
|
+
if (process.platform === 'darwin') {
|
|
38
|
+
return join(homedir(), 'Library', 'Preferences', '.wrangler', 'registry');
|
|
39
|
+
}
|
|
40
|
+
if (process.platform === 'win32') {
|
|
41
|
+
return join(process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming'), '.wrangler', 'registry');
|
|
42
|
+
}
|
|
43
|
+
return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config'), '.wrangler', 'registry');
|
|
44
|
+
}
|
|
24
45
|
/**
|
|
25
46
|
* Returns two Vite plugins: one for build (patches _worker.js) and one for
|
|
26
47
|
* dev (starts a wrangler dev server for Durable Objects).
|
|
@@ -76,6 +97,7 @@ function devPlugin(options) {
|
|
|
76
97
|
const devPort = options.devPort ?? DEFAULT_DEV_PORT;
|
|
77
98
|
let worker = null;
|
|
78
99
|
let tempConfigPath = null;
|
|
100
|
+
let proxyConfigPath = null;
|
|
79
101
|
return {
|
|
80
102
|
name: 'add-worker-exports-dev',
|
|
81
103
|
apply: 'serve',
|
|
@@ -99,7 +121,25 @@ function devPlugin(options) {
|
|
|
99
121
|
delete devConfig.assets;
|
|
100
122
|
tempConfigPath = resolve('.dev-worker-wrangler.jsonc');
|
|
101
123
|
await writeFile(tempConfigPath, JSON.stringify(devConfig, null, '\t'));
|
|
102
|
-
|
|
124
|
+
// Also write a wrangler config for adapter-cloudflare's getPlatformProxy
|
|
125
|
+
// (used by vite dev for platform.env). It can't run internal DOs or
|
|
126
|
+
// Workflows itself -- those are served by the sidecar above. Rewrite
|
|
127
|
+
// internal DO bindings as cross-worker bindings (script_name pointing
|
|
128
|
+
// at the sidecar) so platform.env.MY_DO calls in +server.ts reach the
|
|
129
|
+
// sidecar via the wrangler dev registry. Workflows and migrations get
|
|
130
|
+
// stripped (Workflow bindings have no script_name equivalent).
|
|
131
|
+
const proxyConfig = parseJsonc(rawJson);
|
|
132
|
+
if (proxyConfig.durable_objects?.bindings) {
|
|
133
|
+
proxyConfig.durable_objects.bindings = proxyConfig.durable_objects.bindings.map((b) => b.script_name ? b : { ...b, script_name: devConfig.name });
|
|
134
|
+
}
|
|
135
|
+
delete proxyConfig.workflows;
|
|
136
|
+
delete proxyConfig.migrations;
|
|
137
|
+
proxyConfigPath = resolve('.platform-proxy-wrangler.jsonc');
|
|
138
|
+
await writeFile(proxyConfigPath, JSON.stringify(proxyConfig, null, '\t'));
|
|
139
|
+
worker = await unstable_startWorker({
|
|
140
|
+
config: tempConfigPath,
|
|
141
|
+
dev: { registry: getWranglerRegistryPath() }
|
|
142
|
+
});
|
|
103
143
|
server.httpServer?.on('close', async () => {
|
|
104
144
|
if (worker) {
|
|
105
145
|
await worker.dispose();
|
|
@@ -108,6 +148,9 @@ function devPlugin(options) {
|
|
|
108
148
|
if (tempConfigPath) {
|
|
109
149
|
await unlink(tempConfigPath).catch(() => { });
|
|
110
150
|
}
|
|
151
|
+
if (proxyConfigPath) {
|
|
152
|
+
await unlink(proxyConfigPath).catch(() => { });
|
|
153
|
+
}
|
|
111
154
|
});
|
|
112
155
|
}
|
|
113
156
|
};
|
package/package.json
CHANGED