cursedbelt-server 4.18.0 → 4.18.1

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.
@@ -82,6 +82,8 @@ export async function servedRuntime(url, { attempts = 3, sleep = (ms) => new Pro
82
82
  }
83
83
  return null;
84
84
  }
85
+ /** How many times one table's export is asked for when wrangler says success and writes nothing. */
86
+ const EXPORT_ATTEMPTS = 3;
85
87
  /**
86
88
  * The tables a snapshot carries, from D1's own `sqlite_master` rows — every real table, and
87
89
  * none of what cannot or must not be re-inserted: a virtual table and its shadows (`_config`,
@@ -123,12 +125,23 @@ export async function pullD1ToSqlite(options) {
123
125
  let sql = '';
124
126
  for (const table of tables) {
125
127
  const dump = `${destination}.${table}.sql`;
126
- const exported = wrangler(['d1', 'export', database, '--remote', '--env=', '--table', table, '--no-schema', '--output', dump, '-y']);
128
+ // 🔴 `wrangler d1 export` has been measured answering SUCCESS and writing no file —
129
+ // collections' nightly of 2026-09-23T15:35Z refused on `derivative_retries`, and the same
130
+ // command wrote the file (32 bytes, an empty table) an hour later. So a missing file is
131
+ // asked for again, twice, before it is a refusal; a failure that persists still refuses,
132
+ // because a snapshot missing a table is not a backup.
133
+ let exported = { code: 1, stdout: '', stderr: 'not attempted' };
134
+ for (let attempt = 1; attempt <= EXPORT_ATTEMPTS; attempt++) {
135
+ exported = wrangler(['d1', 'export', database, '--remote', '--env=', '--table', table, '--no-schema', '--output', dump, '-y']);
136
+ if (exported.code !== 0 || existsSync(dump))
137
+ break;
138
+ }
127
139
  if (exported.code !== 0) {
128
140
  throw new Error(`wrangler d1 export --table ${table} failed: ${exported.stderr.trim() || exported.stdout.trim()}`);
129
141
  }
130
- if (!existsSync(dump))
131
- throw new Error(`wrangler d1 export --table ${table} reported success and wrote no file at ${dump}`);
142
+ if (!existsSync(dump)) {
143
+ throw new Error(`wrangler d1 export --table ${table} reported success ${EXPORT_ATTEMPTS} times and wrote no file at ${dump}`);
144
+ }
132
145
  sql += `${readFileSync(dump, 'utf8')}\n`;
133
146
  }
134
147
  if (!/INSERT INTO/i.test(sql)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt-server",
3
- "version": "4.18.0",
3
+ "version": "4.18.1",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The app-facing Bun/Hono server tier of the cursedbelt split — storage, sharing, activity, guard, sync. React-free; cursedbelt-core below it.",
@@ -172,6 +172,26 @@ describe('pulling D1 down — table by table, because a whole-database export re
172
172
  ).rejects.toThrow(/lists no `tracks` table/);
173
173
  });
174
174
 
175
+ test('an export that says success and writes NO file is asked again — and refuses if it never does', async () => {
176
+ const dir = scratch();
177
+ let flaky = 1;
178
+ const run: Wrangler = (args) => {
179
+ if (args[1] === 'execute') return { code: 0, stdout: JSON.stringify([{ results: MASTER }]), stderr: '' };
180
+ const table = args[args.indexOf('--table') + 1] as string;
181
+ const out = args[args.indexOf('--output') + 1] as string;
182
+ // `meta` "succeeds" once without writing — measured on collections, 2026-09-23.
183
+ if (table === 'meta' && flaky-- > 0) return { code: 0, stdout: 'Downloaded successfully', stderr: '' };
184
+ writeFileSync(out, table === 'items' ? "INSERT INTO items (id) VALUES ('i1');" : '');
185
+ return { code: 0, stdout: '', stderr: '' };
186
+ };
187
+ await pull(dir, run);
188
+ const never: Wrangler = (args) =>
189
+ args[1] === 'execute'
190
+ ? { code: 0, stdout: JSON.stringify([{ results: MASTER }]), stderr: '' }
191
+ : { code: 0, stdout: 'Downloaded successfully', stderr: '' };
192
+ await expect(pull(scratch(), never)).rejects.toThrow(/reported success 3 times and wrote no file/);
193
+ });
194
+
175
195
  test('🔴 one table failing to export THROWS — never a snapshot missing that table', async () => {
176
196
  const dir = scratch();
177
197
  const { run } = fake((table) => (table === 'meta' ? null : "INSERT INTO items (id) VALUES ('x');"));
@@ -97,6 +97,9 @@ export async function servedRuntime(
97
97
  return null;
98
98
  }
99
99
 
100
+ /** How many times one table's export is asked for when wrangler says success and writes nothing. */
101
+ const EXPORT_ATTEMPTS = 3;
102
+
100
103
  /** One `wrangler` invocation, as {@link pullD1ToSqlite} needs it. Injected so a spec runs none. */
101
104
  export type Wrangler = (args: string[]) => { code: number; stdout: string; stderr: string };
102
105
 
@@ -160,11 +163,24 @@ export async function pullD1ToSqlite(options: PullD1Options): Promise<void> {
160
163
  let sql = '';
161
164
  for (const table of tables) {
162
165
  const dump = `${destination}.${table}.sql`;
163
- const exported = wrangler(['d1', 'export', database, '--remote', '--env=', '--table', table, '--no-schema', '--output', dump, '-y']);
166
+ // 🔴 `wrangler d1 export` has been measured answering SUCCESS and writing no file —
167
+ // collections' nightly of 2026-09-23T15:35Z refused on `derivative_retries`, and the same
168
+ // command wrote the file (32 bytes, an empty table) an hour later. So a missing file is
169
+ // asked for again, twice, before it is a refusal; a failure that persists still refuses,
170
+ // because a snapshot missing a table is not a backup.
171
+ let exported = { code: 1, stdout: '', stderr: 'not attempted' };
172
+ for (let attempt = 1; attempt <= EXPORT_ATTEMPTS; attempt++) {
173
+ exported = wrangler(['d1', 'export', database, '--remote', '--env=', '--table', table, '--no-schema', '--output', dump, '-y']);
174
+ if (exported.code !== 0 || existsSync(dump)) break;
175
+ }
164
176
  if (exported.code !== 0) {
165
177
  throw new Error(`wrangler d1 export --table ${table} failed: ${exported.stderr.trim() || exported.stdout.trim()}`);
166
178
  }
167
- if (!existsSync(dump)) throw new Error(`wrangler d1 export --table ${table} reported success and wrote no file at ${dump}`);
179
+ if (!existsSync(dump)) {
180
+ throw new Error(
181
+ `wrangler d1 export --table ${table} reported success ${EXPORT_ATTEMPTS} times and wrote no file at ${dump}`,
182
+ );
183
+ }
168
184
  sql += `${readFileSync(dump, 'utf8')}\n`;
169
185
  }
170
186
  if (!/INSERT INTO/i.test(sql)) {