@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.
Files changed (3) hide show
  1. package/README.md +21 -1
  2. package/dist/index.js +45 -2
  3. 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 it via WebSocket on a separate port.
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 { resolve } from 'node:path';
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
- worker = await unstable_startWorker({ config: tempConfigPath });
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oselvar/sveltekit-add-worker-exports",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "Vite plugin that adds Durable Object and Workflow exports to SvelteKit Cloudflare workers",
5
5
  "type": "module",
6
6
  "publishConfig": {