sliftutils 1.7.68 → 1.7.70

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 (62) hide show
  1. package/dist/treeSummary.ts.cache +2 -2
  2. package/index.d.ts +32 -12
  3. package/misc/dist/environment.ts.cache +2 -2
  4. package/misc/dist/getSecret.ts.cache +2 -2
  5. package/misc/dist/strings.ts.cache +2 -2
  6. package/misc/dist/zip.ts.cache +2 -2
  7. package/misc/https/dist/certs.ts.cache +2 -2
  8. package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
  9. package/package.json +2 -2
  10. package/render-utils/dist/observer.tsx.cache +2 -2
  11. package/storage/ArchivesDisk.d.ts +2 -2
  12. package/storage/ArchivesDisk.ts +8 -4
  13. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +2 -2
  14. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +2 -2
  15. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +2 -2
  16. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +2 -2
  17. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +2 -2
  18. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +2 -2
  19. package/storage/BulkDatabase2/dist/blockCache.ts.cache +2 -2
  20. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +2 -2
  21. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +2 -2
  22. package/storage/BulkDatabase2/dist/streamLog.ts.cache +2 -2
  23. package/storage/BulkDatabase2/dist/syncClient.ts.cache +2 -2
  24. package/storage/IArchives.d.ts +18 -2
  25. package/storage/IArchives.ts +33 -3
  26. package/storage/backblaze.d.ts +2 -2
  27. package/storage/backblaze.ts +31 -9
  28. package/storage/dist/ArchivesDisk.ts.cache +9 -5
  29. package/storage/dist/FileFolderAPI.tsx.cache +2 -2
  30. package/storage/dist/IArchives.ts.cache +4 -3
  31. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +2 -2
  32. package/storage/dist/JSONStorage.ts.cache +2 -2
  33. package/storage/dist/PendingManager.tsx.cache +2 -2
  34. package/storage/dist/TransactionStorage.ts.cache +2 -2
  35. package/storage/dist/backblaze.ts.cache +22 -5
  36. package/storage/dist/fileSystemPointer.ts.cache +2 -2
  37. package/storage/dist/remoteFileStorage.ts.cache +2 -2
  38. package/storage/remoteStorage/ArchivesRemote.d.ts +2 -2
  39. package/storage/remoteStorage/ArchivesRemote.ts +8 -3
  40. package/storage/remoteStorage/blobStore.d.ts +1 -0
  41. package/storage/remoteStorage/blobStore.ts +31 -12
  42. package/storage/remoteStorage/createArchives.d.ts +2 -2
  43. package/storage/remoteStorage/createArchives.ts +19 -6
  44. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +4 -4
  45. package/storage/remoteStorage/dist/accessStats.ts.cache +78 -0
  46. package/storage/remoteStorage/dist/blobStore.ts.cache +34 -13
  47. package/storage/remoteStorage/dist/cliArgs.ts.cache +2 -2
  48. package/storage/remoteStorage/dist/createArchives.ts.cache +7 -4
  49. package/storage/remoteStorage/dist/deployTakeover.ts.cache +2 -2
  50. package/storage/remoteStorage/dist/intermediateSources.ts.cache +2 -2
  51. package/storage/remoteStorage/dist/remoteConfig.ts.cache +2 -2
  52. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +2 -2
  53. package/storage/remoteStorage/dist/sourcesList.ts.cache +2 -2
  54. package/storage/remoteStorage/dist/storageClientController.ts.cache +2 -2
  55. package/storage/remoteStorage/dist/storageController.ts.cache +7 -4
  56. package/storage/remoteStorage/dist/storageServerState.ts.cache +26 -6
  57. package/storage/remoteStorage/storageController.d.ts +1 -1
  58. package/storage/remoteStorage/storageController.ts +5 -2
  59. package/storage/remoteStorage/storageServer.ts +0 -1
  60. package/storage/remoteStorage/storageServerState.d.ts +4 -1
  61. package/storage/remoteStorage/storageServerState.ts +25 -5
  62. package/yarn.lock +4 -4
@@ -73,7 +73,7 @@ export declare const RemoteStorageController: import("socket-function/SocketFunc
73
73
  size: number;
74
74
  } | undefined>;
75
75
  set: (account: string, bucketName: string, path: string, data: Buffer, lastModified?: number, forceSetImmutable?: boolean, internal?: boolean) => Promise<void>;
76
- del: (account: string, bucketName: string, path: string) => Promise<void>;
76
+ del: (account: string, bucketName: string, path: string, lastModified?: number, internal?: boolean) => Promise<void>;
77
77
  getInfo: (account: string, bucketName: string, path: string, includeTombstones?: boolean) => Promise<{
78
78
  writeTime: number;
79
79
  size: number;
@@ -308,14 +308,17 @@ class RemoteStorageControllerBase {
308
308
  async set(account: string, bucketName: string, path: string, data: Buffer, lastModified?: number, forceSetImmutable?: boolean, internal?: boolean): Promise<void> {
309
309
  assertValidName(bucketName, "bucket name");
310
310
  assertValidPath(path);
311
+ if (!data.length) {
312
+ throw new Error(`set was called with an empty buffer for ${JSON.stringify(path)} in bucket ${account}/${bucketName}: an empty file IS a deletion in this system and would read back as missing - call del instead`);
313
+ }
311
314
  trackAccess({ account, operation: "set", path: `${bucketName}/${path}`, size: data.length });
312
315
  await writeBucketFile(account, bucketName, path, Buffer.from(data), { lastModified, forceSetImmutable, internal });
313
316
  }
314
- async del(account: string, bucketName: string, path: string): Promise<void> {
317
+ async del(account: string, bucketName: string, path: string, lastModified?: number, internal?: boolean): Promise<void> {
315
318
  assertValidName(bucketName, "bucket name");
316
319
  assertValidPath(path);
317
320
  trackAccess({ account, operation: "del", path: `${bucketName}/${path}` });
318
- await deleteBucketFile(account, bucketName, path);
321
+ await deleteBucketFile(account, bucketName, path, { lastModified, internal });
319
322
  }
320
323
  async getInfo(account: string, bucketName: string, path: string, includeTombstones?: boolean): Promise<{ writeTime: number; size: number } | undefined> {
321
324
  assertValidPath(path);
@@ -104,7 +104,6 @@ export async function hostStorageServer(config: HostStorageServerConfig): Promis
104
104
  .catch(e => console.error(`Disk space check failed for ${folder}:`, e));
105
105
  }, DISK_SPACE_CHECK_INTERVAL_MS);
106
106
  (interval as { unref?: () => void }).unref?.();
107
- SocketFunction.MAX_MESSAGE_SIZE = 1024 * 1024 * 384;
108
107
 
109
108
  await hostServer({
110
109
  domain,
@@ -111,5 +111,8 @@ export declare function getActiveBucket(account: string, bucketName: string): Pr
111
111
  /** Loads a bucket that exists on this server's disk into memory, which starts its synchronization and window timers, and returns its live state. Nothing is written and no other server is contacted - unlike building an ArchivesChain for it, which would probe every source and could write the routing config. Already-loaded buckets just return their state. */
112
112
  export declare function activateBucket(account: string, bucketName: string): Promise<ActiveBucketInfo | string>;
113
113
  export declare function listAccountBuckets(account: string): Promise<ServerBucketInfo[]>;
114
- export declare function deleteBucketFile(account: string, bucketName: string, filePath: string): Promise<void>;
114
+ export declare function deleteBucketFile(account: string, bucketName: string, filePath: string, config?: {
115
+ lastModified?: number;
116
+ internal?: boolean;
117
+ }): Promise<void>;
115
118
  export declare function getLocalArchives(account: string, bucketName: string): IArchives;
@@ -10,7 +10,7 @@ import { ArchivesDisk } from "../ArchivesDisk";
10
10
  import { BlobStore, IBucketStore, DEFAULT_FAST_WRITE_DELAY, WINDOW_END_FLUSH_MARGIN } from "./blobStore";
11
11
  import {
12
12
  RemoteConfig, HostedConfig, BackblazeConfig, IArchives, ArchivesSource, ArchiveFileInfo, ArchivesConfig,
13
- ArchivesSyncStatus, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig,
13
+ ArchivesSyncStatus, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig,
14
14
  STORAGE_WRONG_VALID_WINDOW, STORAGE_WRONG_ROUTE, FULL_ROUTE,
15
15
  } from "../IArchives";
16
16
  import { ROUTING_FILE, parseRoutingData, serializeRemoteConfig, parseHostedUrl, replaceHostedUrlPort, buildFileUrl, getConfigVersion, getRoute, routeContains, routeIntersection, normalizeSource } from "./remoteConfig";
@@ -1061,13 +1061,33 @@ export async function listAccountBuckets(account: string): Promise<ServerBucketI
1061
1061
  }
1062
1062
  }
1063
1063
 
1064
- export async function deleteBucketFile(account: string, bucketName: string, filePath: string): Promise<void> {
1064
+ export async function deleteBucketFile(account: string, bucketName: string, filePath: string, config?: { lastModified?: number; internal?: boolean }): Promise<void> {
1065
+ assertWritesAllowed();
1065
1066
  if (filePath === ROUTING_FILE) {
1066
1067
  throw new Error(`The routing config ${JSON.stringify(ROUTING_FILE)} cannot be deleted (overwrite it to change the bucket's configuration)`);
1067
1068
  }
1068
1069
  let loaded = await getLoadedBucket(account, bucketName);
1069
1070
  if (!loaded) return;
1070
- await loaded.store.del(filePath, getWriteConfig(loaded, Date.now(), getRoute(filePath)));
1071
+ let writeTime = config?.lastModified || Date.now();
1072
+ let route = getRoute(filePath);
1073
+ if (config?.internal) {
1074
+ if (!config.lastModified) {
1075
+ throw new Error(`Internal deletions must carry lastModified (they are synchronization pushes, ordered by their write time), deleting ${JSON.stringify(filePath)} in bucket ${account}/${bucketName}`);
1076
+ }
1077
+ // Same acceptance rule as internal writes (see SetConfig.internal): the stamp must land inside SOME window+route this server is configured for
1078
+ let covered = loaded.selfEntries.some(x => writeTime >= x.validWindow[0] && writeTime < x.validWindow[1] && routeContains(x.route, route));
1079
+ if (!covered) {
1080
+ throw new Error(`Internal deletion of ${JSON.stringify(filePath)} in bucket ${account}/${bucketName} rejected: writeTime ${writeTime} (${new Date(writeTime).toISOString()}) at route ${route} is outside every window/route this server is configured for: ${JSON.stringify(loaded.selfEntries.map(x => ({ validWindow: x.validWindow, route: x.route || FULL_ROUTE })))}`);
1081
+ }
1082
+ if (loaded.store.setInternal) {
1083
+ // setInternal treats an empty buffer as exactly a deletion: disk removal plus a tombstone index entry, no fan-out
1084
+ await loaded.store.setInternal(filePath, Buffer.alloc(0), { lastModified: writeTime });
1085
+ return;
1086
+ }
1087
+ await loaded.store.del(filePath);
1088
+ return;
1089
+ }
1090
+ await loaded.store.del(filePath, { ...getWriteConfig(loaded, writeTime, route), lastModified: writeTime });
1071
1091
  }
1072
1092
 
1073
1093
  const LARGE_FILE_PART_SIZE = 8 * 1024 * 1024;
@@ -1098,8 +1118,8 @@ class ArchivesLocalBucket implements IArchives {
1098
1118
  await writeBucketFile(this.account, this.bucketName, fileName, data, config);
1099
1119
  return fileName;
1100
1120
  }
1101
- public async del(fileName: string): Promise<void> {
1102
- await deleteBucketFile(this.account, this.bucketName, fileName);
1121
+ public async del(fileName: string, config?: DelConfig): Promise<void> {
1122
+ await deleteBucketFile(this.account, this.bucketName, fileName, config);
1103
1123
  }
1104
1124
  public async setLargeFile(config: { path: string; lastModified?: number; getNextData(): Promise<Buffer | undefined> }): Promise<void> {
1105
1125
  assertWritesAllowed();
package/yarn.lock CHANGED
@@ -1944,10 +1944,10 @@ slash@^3.0.0:
1944
1944
  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
1945
1945
  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
1946
1946
 
1947
- socket-function@^1.2.27:
1948
- version "1.2.27"
1949
- resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.2.27.tgz#7340b3a8c68fd467080e2158c94b87e6ef793c77"
1950
- integrity sha512-tOitwcUWz23JLzq7mBNFIRyPZtBPkA/+/a+DHoxWP30lMkZ5so5HTlF7vspOMpAPQFPpufgVJnWuOi87F/cxzg==
1947
+ socket-function@^1.2.29:
1948
+ version "1.2.29"
1949
+ resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.2.29.tgz#d92d996e1a30a05360623c5d8287b592c5d8b054"
1950
+ integrity sha512-THzX+uYytt7w5ck0lsNvVSAbb+j0CXtVaOraYbkBiQYS4F3S4o3ZNhWekewZ0Kp9tMSKgt+74fFtuwn5634m5Q==
1951
1951
  dependencies:
1952
1952
  "@types/pako" "^2.0.3"
1953
1953
  "@types/ws" "^8.5.3"