@relayfile/sdk 0.10.50 → 0.10.51

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 (2) hide show
  1. package/dist/client.js +36 -34
  2. package/package.json +6 -6
package/dist/client.js CHANGED
@@ -75,6 +75,25 @@ function getFileReadCache(client) {
75
75
  return cached;
76
76
  return false;
77
77
  }
78
+ async function withFileReadCacheInvalidated(client, workspaceId, paths, attempt) {
79
+ const cache = getFileReadCache(client);
80
+ if (cache === false)
81
+ return attempt();
82
+ const evict = () => {
83
+ for (const path of paths) {
84
+ cache.evict(workspaceId, path);
85
+ }
86
+ };
87
+ // The attempt itself invalidates our knowledge, before its outcome is known.
88
+ evict();
89
+ try {
90
+ return await attempt();
91
+ }
92
+ finally {
93
+ // A concurrent read can repopulate while the request is in flight.
94
+ evict();
95
+ }
96
+ }
78
97
  function initFileReadCache(client, options) {
79
98
  if (options.readCache === false) {
80
99
  fileReadCaches.set(client, false);
@@ -1248,7 +1267,7 @@ export class RelayFileClient {
1248
1267
  async writeFile(input) {
1249
1268
  const { workspaceId, path, correlationId, baseRevision, content, contentType, encoding, contentIdentity, signal } = input;
1250
1269
  const query = buildQuery({ path, forkId: input.forkId });
1251
- const result = await this.request({
1270
+ return withFileReadCacheInvalidated(this, workspaceId, [path], () => this.request({
1252
1271
  method: "PUT",
1253
1272
  path: `/v1/workspaces/${encodeURIComponent(workspaceId)}/fs/file${query}`,
1254
1273
  correlationId,
@@ -1264,15 +1283,11 @@ export class RelayFileClient {
1264
1283
  ...(contentIdentity ? { contentIdentity } : {})
1265
1284
  },
1266
1285
  signal
1267
- });
1268
- const cache = getFileReadCache(this);
1269
- if (cache !== false)
1270
- cache.evict(workspaceId, path);
1271
- return result;
1286
+ }));
1272
1287
  }
1273
1288
  async mergeFile(input) {
1274
1289
  const query = buildQuery({ path: input.path });
1275
- const result = await this.request({
1290
+ return withFileReadCacheInvalidated(this, input.workspaceId, [input.path], () => this.request({
1276
1291
  method: "POST",
1277
1292
  path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/merge${query}`,
1278
1293
  correlationId: input.correlationId,
@@ -1291,31 +1306,22 @@ export class RelayFileClient {
1291
1306
  contentIdentity: input.contentIdentity
1292
1307
  },
1293
1308
  signal: input.signal
1294
- });
1295
- const cache = getFileReadCache(this);
1296
- if (cache !== false)
1297
- cache.evict(input.workspaceId, input.path);
1298
- return result;
1309
+ }));
1299
1310
  }
1300
1311
  async bulkWrite(input) {
1301
1312
  const query = buildQuery({ forkId: input.forkId });
1302
- const response = await this.performRequest({
1303
- method: "POST",
1304
- path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/bulk${query}`,
1305
- correlationId: input.correlationId,
1306
- body: {
1307
- files: input.files
1308
- },
1309
- signal: input.signal
1313
+ return withFileReadCacheInvalidated(this, input.workspaceId, input.files.map((file) => file.path), async () => {
1314
+ const response = await this.performRequest({
1315
+ method: "POST",
1316
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/bulk${query}`,
1317
+ correlationId: input.correlationId,
1318
+ body: {
1319
+ files: input.files
1320
+ },
1321
+ signal: input.signal
1322
+ });
1323
+ return await this.readPayload(response);
1310
1324
  });
1311
- const result = await this.readPayload(response);
1312
- const cache = getFileReadCache(this);
1313
- if (cache !== false) {
1314
- for (const file of input.files) {
1315
- cache.evict(input.workspaceId, file.path);
1316
- }
1317
- }
1318
- return result;
1319
1325
  }
1320
1326
  async issueCheckpointSeal(input) {
1321
1327
  return this.request({
@@ -1420,7 +1426,7 @@ export class RelayFileClient {
1420
1426
  }
1421
1427
  async deleteFile(input) {
1422
1428
  const query = buildQuery({ path: input.path, forkId: input.forkId });
1423
- const result = await this.request({
1429
+ return withFileReadCacheInvalidated(this, input.workspaceId, [input.path], () => this.request({
1424
1430
  method: "DELETE",
1425
1431
  path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/file${query}`,
1426
1432
  correlationId: input.correlationId,
@@ -1428,11 +1434,7 @@ export class RelayFileClient {
1428
1434
  "If-Match": input.baseRevision
1429
1435
  },
1430
1436
  signal: input.signal
1431
- });
1432
- const cache = getFileReadCache(this);
1433
- if (cache !== false)
1434
- cache.evict(input.workspaceId, input.path);
1435
- return result;
1437
+ }));
1436
1438
  }
1437
1439
  async createFork(input) {
1438
1440
  const body = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relayfile/sdk",
3
- "version": "0.10.50",
3
+ "version": "0.10.51",
4
4
  "description": "TypeScript SDK for relayfile — real-time filesystem for humans and agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,15 +59,15 @@
59
59
  "prepublishOnly": "npm run build"
60
60
  },
61
61
  "dependencies": {
62
- "@relayfile/core": "0.10.50",
62
+ "@relayfile/core": "0.10.51",
63
63
  "ignore": "^7.0.5",
64
64
  "tar": "^7.5.10"
65
65
  },
66
66
  "optionalDependencies": {
67
- "@relayfile/mount-darwin-arm64": "0.10.50",
68
- "@relayfile/mount-darwin-x64": "0.10.50",
69
- "@relayfile/mount-linux-arm64": "0.10.50",
70
- "@relayfile/mount-linux-x64": "0.10.50"
67
+ "@relayfile/mount-darwin-arm64": "0.10.51",
68
+ "@relayfile/mount-darwin-x64": "0.10.51",
69
+ "@relayfile/mount-linux-arm64": "0.10.51",
70
+ "@relayfile/mount-linux-x64": "0.10.51"
71
71
  },
72
72
  "devDependencies": {
73
73
  "typescript": "^5.7.3",