@rigxyz/tapd 0.4.1 → 0.5.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.
@@ -37,10 +37,21 @@ var NotInitializedError = class extends Error {
37
37
  };
38
38
 
39
39
  // src/relay-client.ts
40
+ function summarizeRelayError(body, status) {
41
+ if (typeof body === "object" && body !== null && "error" in body) {
42
+ const code = String(body.error);
43
+ if (code === "quota_exceeded") {
44
+ const limit = body.limitBytes;
45
+ const mb = typeof limit === "number" ? Math.round(limit / (1024 * 1024)) : null;
46
+ return mb ? `workspace storage limit reached (${mb} MB) \u2014 remove files and retry` : "workspace storage limit reached \u2014 remove files and retry";
47
+ }
48
+ return code;
49
+ }
50
+ return `status ${status}`;
51
+ }
40
52
  var RelayError = class extends Error {
41
53
  constructor(route, status, body) {
42
- const bodySummary = typeof body === "object" && body !== null && "error" in body ? String(body.error) : `status ${status}`;
43
- super(`relay ${route}: ${bodySummary}`);
54
+ super(`relay ${route}: ${summarizeRelayError(body, status)}`);
44
55
  this.route = route;
45
56
  this.status = status;
46
57
  this.body = body;
@@ -293,9 +304,8 @@ function joinUrl(base, suffix) {
293
304
  }
294
305
 
295
306
  // src/state-db.ts
296
- import { mkdirSync as mkdirSync2 } from "fs";
307
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync } from "fs";
297
308
  import { dirname as dirname2 } from "path";
298
- import Database from "better-sqlite3";
299
309
  var CURSOR_PREFIX = "chg_";
300
310
  function cursorGreaterThan(a, b) {
301
311
  const an = a.startsWith(CURSOR_PREFIX) ? safeBigInt(a.slice(CURSOR_PREFIX.length)) : null;
@@ -311,93 +321,109 @@ function safeBigInt(s) {
311
321
  return null;
312
322
  }
313
323
  }
314
- var SCHEMA = `
315
- CREATE TABLE IF NOT EXISTS paths (
316
- path TEXT PRIMARY KEY,
317
- last_applied_change_id TEXT,
318
- last_seen_hash TEXT,
319
- local_dirty INTEGER NOT NULL DEFAULT 0,
320
- last_scan_at TEXT
321
- );
322
-
323
- CREATE TABLE IF NOT EXISTS meta (
324
- key TEXT PRIMARY KEY,
325
- value TEXT NOT NULL
326
- );
327
- `;
324
+ var pendingFlushers = /* @__PURE__ */ new Set();
325
+ var exitHookInstalled = false;
326
+ function installExitHook() {
327
+ if (exitHookInstalled) return;
328
+ exitHookInstalled = true;
329
+ process.once("exit", () => {
330
+ for (const flush of pendingFlushers) {
331
+ try {
332
+ flush();
333
+ } catch {
334
+ }
335
+ }
336
+ });
337
+ }
338
+ function loadStore(dbPath) {
339
+ try {
340
+ const parsed = JSON.parse(readFileSync2(dbPath, "utf8"));
341
+ if (parsed && parsed.version === 1 && parsed.meta && parsed.paths) {
342
+ return { version: 1, meta: parsed.meta, paths: parsed.paths };
343
+ }
344
+ } catch {
345
+ }
346
+ return { version: 1, meta: {}, paths: {} };
347
+ }
328
348
  function openStateDb(dbPath) {
329
349
  mkdirSync2(dirname2(dbPath), { recursive: true });
330
- const db = new Database(dbPath);
331
- db.pragma("journal_mode = WAL");
332
- db.exec(SCHEMA);
333
- const stmtUpsert = db.prepare(`
334
- INSERT INTO paths (path, last_applied_change_id, last_seen_hash, local_dirty, last_scan_at)
335
- VALUES (@path, @last_applied_change_id, @last_seen_hash, @local_dirty, @last_scan_at)
336
- ON CONFLICT(path) DO UPDATE SET
337
- last_applied_change_id = excluded.last_applied_change_id,
338
- last_seen_hash = excluded.last_seen_hash,
339
- local_dirty = excluded.local_dirty,
340
- last_scan_at = excluded.last_scan_at
341
- `);
342
- const stmtGet = db.prepare(`SELECT * FROM paths WHERE path = ?`);
343
- const stmtDelete = db.prepare(`DELETE FROM paths WHERE path = ?`);
344
- const stmtListPaths = db.prepare(`SELECT path FROM paths`);
345
- const stmtSetMeta = db.prepare(`
346
- INSERT INTO meta (key, value) VALUES (?, ?)
347
- ON CONFLICT(key) DO UPDATE SET value = excluded.value
348
- `);
349
- const stmtGetMeta = db.prepare(`SELECT value FROM meta WHERE key = ?`);
350
+ const store = loadStore(dbPath);
351
+ let dirty = false;
352
+ let timer = null;
353
+ const flush = () => {
354
+ if (timer) {
355
+ clearTimeout(timer);
356
+ timer = null;
357
+ }
358
+ if (!dirty) return;
359
+ const tmp = `${dbPath}.tmp`;
360
+ writeFileSync2(tmp, JSON.stringify(store), "utf8");
361
+ renameSync(tmp, dbPath);
362
+ dirty = false;
363
+ };
364
+ const schedule = () => {
365
+ dirty = true;
366
+ if (timer) return;
367
+ timer = setTimeout(flush, 100);
368
+ timer.unref?.();
369
+ };
370
+ pendingFlushers.add(flush);
371
+ installExitHook();
350
372
  return {
351
373
  getCursor() {
352
- const row = stmtGetMeta.get("cursor");
353
- return row?.value ?? "chg_0";
374
+ return store.meta.cursor ?? "chg_0";
354
375
  },
355
376
  setCursor(cursor) {
356
- const current = stmtGetMeta.get("cursor")?.value;
377
+ const current = store.meta.cursor;
357
378
  if (current && !cursorGreaterThan(cursor, current)) return;
358
- stmtSetMeta.run("cursor", cursor);
379
+ store.meta.cursor = cursor;
380
+ schedule();
359
381
  },
360
382
  upsertPath(state) {
361
- stmtUpsert.run({
362
- path: state.path,
363
- last_applied_change_id: state.lastAppliedChangeId,
364
- last_seen_hash: state.lastSeenHash,
365
- local_dirty: state.localDirty ? 1 : 0,
366
- last_scan_at: state.lastScanAt
367
- });
383
+ store.paths[state.path] = {
384
+ lastAppliedChangeId: state.lastAppliedChangeId,
385
+ lastSeenHash: state.lastSeenHash,
386
+ localDirty: state.localDirty,
387
+ lastScanAt: state.lastScanAt
388
+ };
389
+ schedule();
368
390
  },
369
391
  getPath(path) {
370
- const row = stmtGet.get(path);
371
- if (!row) return null;
392
+ const r = store.paths[path];
393
+ if (!r) return null;
372
394
  return {
373
- path: row.path,
374
- lastAppliedChangeId: row.last_applied_change_id,
375
- lastSeenHash: row.last_seen_hash,
376
- localDirty: row.local_dirty !== 0,
377
- lastScanAt: row.last_scan_at
395
+ path,
396
+ lastAppliedChangeId: r.lastAppliedChangeId,
397
+ lastSeenHash: r.lastSeenHash,
398
+ localDirty: r.localDirty,
399
+ lastScanAt: r.lastScanAt
378
400
  };
379
401
  },
380
402
  deletePath(path) {
381
- stmtDelete.run(path);
403
+ if (path in store.paths) {
404
+ delete store.paths[path];
405
+ schedule();
406
+ }
382
407
  },
383
408
  listPaths() {
384
- return stmtListPaths.all().map((r) => r.path);
409
+ return Object.keys(store.paths);
385
410
  },
386
411
  setMeta(key, value) {
387
- stmtSetMeta.run(key, value);
412
+ store.meta[key] = value;
413
+ schedule();
388
414
  },
389
415
  getMeta(key) {
390
- const row = stmtGetMeta.get(key);
391
- return row?.value ?? null;
416
+ return store.meta[key] ?? null;
392
417
  },
393
418
  close() {
394
- db.close();
419
+ flush();
420
+ pendingFlushers.delete(flush);
395
421
  }
396
422
  };
397
423
  }
398
424
 
399
425
  // src/tapignore.ts
400
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
426
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
401
427
  import { join as join2 } from "path";
402
428
  import ignore from "ignore";
403
429
  var BUILTIN_IGNORE_LINES = [
@@ -433,7 +459,7 @@ function loadIgnore(rootDir) {
433
459
  ig.add(BUILTIN_IGNORE_LINES.join("\n"));
434
460
  const projectIgnore = join2(rootDir, ".tapignore");
435
461
  if (existsSync2(projectIgnore)) {
436
- ig.add(readFileSync2(projectIgnore, "utf8"));
462
+ ig.add(readFileSync3(projectIgnore, "utf8"));
437
463
  }
438
464
  return ig;
439
465
  }
@@ -568,7 +594,7 @@ async function hashFile(absPath) {
568
594
 
569
595
  // src/init.ts
570
596
  import { createHash as createHash2 } from "crypto";
571
- import { readFileSync as readFileSync3 } from "fs";
597
+ import { readFileSync as readFileSync4 } from "fs";
572
598
  import { join as join4 } from "path";
573
599
 
574
600
  // src/pool.ts
@@ -647,7 +673,7 @@ async function init(opts) {
647
673
  reused += 1;
648
674
  return;
649
675
  }
650
- const bytes = readFileSync3(join4(opts.rootDir, f.path));
676
+ const bytes = readFileSync4(join4(opts.rootDir, f.path));
651
677
  const actual = sha256OfBuffer(bytes);
652
678
  if (actual !== f.hash) {
653
679
  mutatedDuringScan.add(f.path);
@@ -818,10 +844,10 @@ import {
818
844
  existsSync as existsSync3,
819
845
  mkdirSync as mkdirSync3,
820
846
  readdirSync as readdirSync2,
821
- readFileSync as readFileSync4,
847
+ readFileSync as readFileSync5,
822
848
  realpathSync,
823
849
  statSync as statSync2,
824
- writeFileSync as writeFileSync2
850
+ writeFileSync as writeFileSync3
825
851
  } from "fs";
826
852
  import { dirname as dirname3, isAbsolute, join as join6, relative } from "path";
827
853
  var NAME_RE = /^[a-z0-9][a-z0-9_-]*$/;
@@ -907,14 +933,14 @@ var MOUNT_FILE_SUFFIX = ".local.json";
907
933
  function writeImportMount(rootDir, name, mount) {
908
934
  const path = importMountFile(rootDir, name);
909
935
  mkdirSync3(dirname3(path), { recursive: true });
910
- writeFileSync2(path, JSON.stringify(mount, null, 2) + "\n", { mode: 384 });
936
+ writeFileSync3(path, JSON.stringify(mount, null, 2) + "\n", { mode: 384 });
911
937
  }
912
938
  function readImportMount(rootDir, name) {
913
939
  const file = importMountFile(rootDir, name);
914
940
  if (!existsSync3(file)) return { ok: false, reason: "missing_token_file" };
915
941
  let parsed;
916
942
  try {
917
- parsed = JSON.parse(readFileSync4(file, "utf8"));
943
+ parsed = JSON.parse(readFileSync5(file, "utf8"));
918
944
  } catch {
919
945
  return { ok: false, reason: "malformed_json" };
920
946
  }
@@ -998,7 +1024,7 @@ function pathsOverlap(a, b) {
998
1024
  }
999
1025
 
1000
1026
  // src/import-invite.ts
1001
- import { existsSync as existsSync4, readFileSync as readFileSync5, rmSync } from "fs";
1027
+ import { existsSync as existsSync4, readFileSync as readFileSync6, rmSync } from "fs";
1002
1028
  import { dirname as dirname4, join as joinPath2 } from "path";
1003
1029
  var ImportValidationFailed = class extends Error {
1004
1030
  constructor(reason) {
@@ -1095,7 +1121,7 @@ function readRawMount(rootDir, name) {
1095
1121
  const file = importMountFile(rootDir, name);
1096
1122
  if (!existsSync4(file)) return null;
1097
1123
  try {
1098
- return JSON.parse(readFileSync5(file, "utf8"));
1124
+ return JSON.parse(readFileSync6(file, "utf8"));
1099
1125
  } catch {
1100
1126
  return null;
1101
1127
  }
@@ -1147,11 +1173,11 @@ import {
1147
1173
  lstatSync,
1148
1174
  mkdirSync as mkdirSync4,
1149
1175
  readdirSync as readdirSync3,
1150
- readFileSync as readFileSync6,
1151
- renameSync,
1176
+ readFileSync as readFileSync7,
1177
+ renameSync as renameSync2,
1152
1178
  rmdirSync,
1153
1179
  rmSync as rmSync2,
1154
- writeFileSync as writeFileSync3
1180
+ writeFileSync as writeFileSync4
1155
1181
  } from "fs";
1156
1182
  import { basename, dirname as dirname5, extname, join as join7, sep as sep2 } from "path";
1157
1183
  var STATE_KEY_CONFLICT_COUNT = "conflict_count";
@@ -1173,7 +1199,7 @@ function sha256Hex(bytes) {
1173
1199
  return createHash3("sha256").update(bytes).digest("hex");
1174
1200
  }
1175
1201
  function sha256OfFile(absPath) {
1176
- return `sha256:${sha256Hex(readFileSync6(absPath))}`;
1202
+ return `sha256:${sha256Hex(readFileSync7(absPath))}`;
1177
1203
  }
1178
1204
  function conflictSidecarPath(path, ev) {
1179
1205
  const dir = dirname5(path);
@@ -1306,8 +1332,8 @@ async function applyEvent(opts) {
1306
1332
  const sidecarAbs = join7(rootDir, sidecarPath);
1307
1333
  mkdirSync4(dirname5(sidecarAbs), { recursive: true });
1308
1334
  const tmp2 = `${sidecarAbs}.tap-tmp.${randomBytes(6).toString("hex")}`;
1309
- writeFileSync3(tmp2, bytes, { mode: ev.executable ? 493 : 420 });
1310
- renameSync(tmp2, sidecarAbs);
1335
+ writeFileSync4(tmp2, bytes, { mode: ev.executable ? 493 : 420 });
1336
+ renameSync2(tmp2, sidecarAbs);
1311
1337
  stateDb.upsertPath({
1312
1338
  path: ev.path,
1313
1339
  lastAppliedChangeId: ev.id,
@@ -1320,8 +1346,8 @@ async function applyEvent(opts) {
1320
1346
  }
1321
1347
  mkdirSync4(dirname5(abs), { recursive: true });
1322
1348
  const tmp = `${abs}.tap-tmp.${randomBytes(6).toString("hex")}`;
1323
- writeFileSync3(tmp, bytes, { mode: ev.executable ? 493 : 420 });
1324
- renameSync(tmp, abs);
1349
+ writeFileSync4(tmp, bytes, { mode: ev.executable ? 493 : 420 });
1350
+ renameSync2(tmp, abs);
1325
1351
  stateDb.upsertPath({
1326
1352
  path: ev.path,
1327
1353
  lastAppliedChangeId: ev.id,
@@ -1633,7 +1659,7 @@ async function startSubscription(opts) {
1633
1659
 
1634
1660
  // src/uploader.ts
1635
1661
  import { createHash as createHash4 } from "crypto";
1636
- import { readFileSync as readFileSync7 } from "fs";
1662
+ import { readFileSync as readFileSync8 } from "fs";
1637
1663
  import { join as join8 } from "path";
1638
1664
  var UPLOAD_CONCURRENCY2 = 8;
1639
1665
  function sha256OfBuffer2(bytes) {
@@ -1713,7 +1739,7 @@ async function scanAndPush(opts) {
1713
1739
  reused += 1;
1714
1740
  return;
1715
1741
  }
1716
- const bytes = readFileSync7(join8(rootDir, f.path));
1742
+ const bytes = readFileSync8(join8(rootDir, f.path));
1717
1743
  const actual = sha256OfBuffer2(bytes);
1718
1744
  if (actual !== f.hash) {
1719
1745
  mutatedPaths.add(f.path);
@@ -2022,4 +2048,4 @@ export {
2022
2048
  scanAndPush,
2023
2049
  start
2024
2050
  };
2025
- //# sourceMappingURL=chunk-JBX2ZRMD.js.map
2051
+ //# sourceMappingURL=chunk-LQWX63LP.js.map