Skip to content

Commit 677f469

Browse files
Copilottheoephraim
andauthored
fix(cloudflare): debounce wrangler restarts and skip when env is unchanged
Agent-Logs-Url: https://github.com/dmno-dev/varlock/sessions/ef8b4df3-0fb0-4ccb-b2e2-c90dac16c7d6 Co-authored-by: theoephraim <1158956+theoephraim@users.noreply.github.com>
1 parent 0fa9019 commit 677f469

3 files changed

Lines changed: 72 additions & 1 deletion

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@varlock/cloudflare-integration": patch
3+
---
4+
5+
fix(cloudflare): debounce wrangler restarts and skip when env is unchanged
6+
7+
`varlock-wrangler dev` now caches the serialized resolved env graph and compares it
8+
after each debounced watch event. Wrangler only restarts when the resolved env has
9+
actually changed, preventing restart loops caused by spurious `fs.watch()` events
10+
on macOS (which can emit events even when file contents are identical).

framework-tests/frameworks/cloudflare/wrangler.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,58 @@ describe('Cloudflare Workers varlock-wrangler only', () => {
192192
],
193193
});
194194

195+
wranglerEnv.describeDevScenario('no restart on unchanged env content', {
196+
command: 'varlock-wrangler dev --port 18792',
197+
readyPattern: /Ready on|ready in/i,
198+
readyTimeout: 30_000,
199+
templateFiles: {
200+
'src/index.ts': { path: 'workers/basic-worker.ts', prepend: "import '@varlock/cloudflare-integration/init';\n" },
201+
'wrangler.jsonc': '_base-wrangler/wrangler.jsonc',
202+
'tsconfig.json': '_base-wrangler/tsconfig.json',
203+
},
204+
requests: [
205+
// first request — baseline
206+
{
207+
path: '/',
208+
bodyAssertions: {
209+
shouldContain: ['public_var::public-test-value'],
210+
},
211+
},
212+
// second request — write the same .env.schema content (simulates macOS spurious watch events)
213+
// use fileEditDelay so we wait without expecting a restart
214+
{
215+
path: '/',
216+
fileEdits: {
217+
'.env.schema': [
218+
'# @defaultSensitive=false @defaultRequired=infer',
219+
'# @currentEnv=$APP_ENV',
220+
'# ---',
221+
'',
222+
'# @type=enum(dev, prod)',
223+
'APP_ENV=dev',
224+
'',
225+
'PUBLIC_VAR=public-test-value',
226+
'API_URL=https://api.example.com',
227+
'',
228+
'# @sensitive',
229+
'SECRET_KEY=super-secret-value',
230+
].join('\n'),
231+
},
232+
// wait longer than the 300ms debounce to confirm no restart occurred
233+
fileEditDelay: 1500,
234+
bodyAssertions: {
235+
shouldContain: ['public_var::public-test-value'],
236+
},
237+
},
238+
],
239+
outputAssertions: [
240+
{
241+
description: 'wrangler is not restarted when env content is unchanged',
242+
shouldNotContain: ['env changed, restarting wrangler'],
243+
},
244+
],
245+
});
246+
195247
describe('invalid config', () => {
196248
wranglerEnv.describeScenario('invalid schema causes dev failure', {
197249
command: 'varlock-wrangler dev --port 18791',

packages/integrations/cloudflare/src/varlock-wrangler.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,21 @@ async function handleDev(args: Array<string>) {
413413

414414
// watch env source files for changes and restart wrangler with fresh data
415415
let restartTimeout: ReturnType<typeof setTimeout> | undefined;
416+
let cachedGraphJson = loaded.json;
416417
function scheduleRestart() {
417-
// debounce — multiple files may change at once
418+
// debounce — multiple files may change at once (e.g. editor saves multiple files,
419+
// or macOS fs.watch() emits extra events for unchanged files)
418420
if (restartTimeout) clearTimeout(restartTimeout);
419421
restartTimeout = setTimeout(() => {
420422
try {
421423
const freshLoaded = loadSerializedGraph();
424+
// compare serialized JSON strings — only restart when the resolved env actually changed
425+
if (freshLoaded.json === cachedGraphJson) {
426+
restartTimeout = undefined;
427+
return;
428+
}
429+
cachedGraphJson = freshLoaded.json;
430+
loaded = freshLoaded;
422431
cachedContent = formatEnvFileContent(freshLoaded);
423432
handle.update(cachedContent);
424433
console.log('[varlock-wrangler] env changed, restarting wrangler...');

0 commit comments

Comments
 (0)