sliftutils 1.7.9 → 1.7.11

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 (92) hide show
  1. package/bin/storageserver.js +4 -0
  2. package/{teststorage → examplestorage}/browser.tsx +18 -22
  3. package/{teststorage/server.ts → examplestorage/exampleserver.ts} +4 -6
  4. package/index.d.ts +770 -84
  5. package/misc/dist/environment.ts.cache +3 -3
  6. package/misc/dist/getSecret.ts.cache +139 -0
  7. package/misc/dist/strings.ts.cache +13 -0
  8. package/misc/dist/zip.ts.cache +9 -0
  9. package/misc/getSecret.ts +38 -16
  10. package/misc/https/cloudflareHelpers.d.ts +19 -0
  11. package/misc/https/cloudflareHelpers.ts +69 -0
  12. package/misc/https/dist/certs.ts.cache +115 -179
  13. package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
  14. package/misc/https/dist/dns.ts.cache +112 -100
  15. package/misc/https/dist/hostServer.ts.cache +130 -0
  16. package/misc/https/dist/httpsCerts.ts.cache +24 -5
  17. package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
  18. package/misc/https/dns.d.ts +41 -8
  19. package/misc/https/dns.ts +104 -106
  20. package/misc/https/hostServer.d.ts +0 -3
  21. package/misc/https/hostServer.ts +12 -8
  22. package/package.json +3 -2
  23. package/render-utils/dist/observer.tsx.cache +3 -2
  24. package/spec.txt +0 -55
  25. package/storage/ArchivesDisk.d.ts +67 -0
  26. package/storage/ArchivesDisk.ts +369 -0
  27. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
  28. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
  29. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
  30. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
  31. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
  32. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
  33. package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
  34. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
  35. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
  36. package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
  37. package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
  38. package/storage/IArchives.d.ts +127 -1
  39. package/storage/IArchives.ts +201 -1
  40. package/storage/backblaze.d.ts +29 -2
  41. package/storage/backblaze.ts +214 -78
  42. package/storage/dist/ArchivesDisk.ts.cache +373 -0
  43. package/storage/dist/FileFolderAPI.tsx.cache +508 -65
  44. package/storage/dist/IArchives.ts.cache +44 -0
  45. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
  46. package/storage/dist/JSONStorage.ts.cache +6 -2
  47. package/storage/dist/PendingManager.tsx.cache +1 -1
  48. package/storage/dist/TransactionStorage.ts.cache +231 -92
  49. package/storage/dist/backblaze.ts.cache +797 -0
  50. package/storage/dist/fileSystemPointer.ts.cache +36 -3
  51. package/storage/dist/remoteFileStorage.ts.cache +495 -0
  52. package/storage/remoteStorage/ArchivesRemote.d.ts +34 -18
  53. package/storage/remoteStorage/ArchivesRemote.ts +85 -65
  54. package/storage/remoteStorage/ArchivesUrl.d.ts +48 -0
  55. package/storage/remoteStorage/ArchivesUrl.ts +86 -0
  56. package/storage/remoteStorage/accessPage.tsx +111 -28
  57. package/storage/remoteStorage/blobStore.d.ts +128 -25
  58. package/storage/remoteStorage/blobStore.ts +757 -290
  59. package/storage/remoteStorage/cliArgs.d.ts +1 -0
  60. package/storage/remoteStorage/cliArgs.ts +9 -0
  61. package/storage/remoteStorage/createArchives.d.ts +85 -0
  62. package/storage/remoteStorage/createArchives.ts +612 -0
  63. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
  64. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
  65. package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
  66. package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
  67. package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
  68. package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
  69. package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
  70. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
  71. package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
  72. package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
  73. package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
  74. package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
  75. package/storage/remoteStorage/grantAccess.js +4 -0
  76. package/storage/remoteStorage/grantAccessCli.d.ts +1 -0
  77. package/storage/remoteStorage/grantAccessCli.ts +27 -0
  78. package/storage/remoteStorage/remoteConfig.d.ts +29 -0
  79. package/storage/remoteStorage/remoteConfig.ts +194 -0
  80. package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
  81. package/storage/remoteStorage/sourceWrapper.ts +223 -0
  82. package/storage/remoteStorage/spec.md +31 -0
  83. package/storage/remoteStorage/storageController.d.ts +30 -27
  84. package/storage/remoteStorage/storageController.ts +297 -159
  85. package/storage/remoteStorage/storageServer.d.ts +6 -0
  86. package/storage/remoteStorage/storageServer.ts +88 -94
  87. package/storage/remoteStorage/storageServerCli.d.ts +1 -0
  88. package/storage/remoteStorage/storageServerCli.ts +38 -0
  89. package/storage/remoteStorage/storageServerState.d.ts +43 -0
  90. package/storage/remoteStorage/storageServerState.ts +540 -0
  91. package/testsite/server.ts +0 -2
  92. package/yarn.lock +11 -6
package/index.d.ts CHANGED
@@ -136,25 +136,81 @@ declare module "sliftutils/misc/https/certs" {
136
136
 
137
137
  }
138
138
 
139
+ declare module "sliftutils/misc/https/cloudflareHelpers" {
140
+ /// <reference types="node" />
141
+ /// <reference types="node" />
142
+ export type CloudflareCreds = {
143
+ key: string;
144
+ /** Set for legacy global API keys, which auth via X-Auth-Email/X-Auth-Key. Absent for API tokens, which auth via Authorization: Bearer. */
145
+ email?: string;
146
+ };
147
+ export declare const getCloudflareCreds: {
148
+ (): Promise<CloudflareCreds>;
149
+ reset(): void;
150
+ set(newValue: Promise<CloudflareCreds>): void;
151
+ };
152
+ export declare function cloudflareGETCall<T>(path: string, params?: {
153
+ [key: string]: string;
154
+ }): Promise<T>;
155
+ export declare function cloudflarePOSTCall<T>(path: string, params: {
156
+ [key: string]: unknown;
157
+ }): Promise<T>;
158
+ export declare function cloudflareCall<T>(path: string, payload: Buffer, method: string): Promise<T>;
159
+
160
+ }
161
+
139
162
  declare module "sliftutils/misc/https/dns" {
163
+ /** Parses our tag back out; 0 (i.e. always stale) when it's absent or unparseable. */
164
+ export declare function freshnessTime(comment?: string): number;
165
+ export declare const hasDNSWritePermissions: {
166
+ (): Promise<boolean>;
167
+ reset(): void;
168
+ set(newValue: Promise<boolean>): void;
169
+ };
170
+ export declare const getZoneId: {
171
+ (key: string): Promise<string>;
172
+ clear(key: string): void;
173
+ clearAll(): void;
174
+ forceSet(key: string, value: Promise<string>): void;
175
+ getAllKeys(): string[];
176
+ get(key: string): Promise<string> | undefined;
177
+ };
140
178
  export declare function getRecordsRaw(type: string, key: string): Promise<{
141
179
  id: string;
142
180
  type: string;
143
181
  name: string;
144
182
  content: string;
145
183
  proxied: boolean;
184
+ modified_on: string;
185
+ comment?: string | undefined;
146
186
  }[]>;
187
+ /** Cloudflare's batch endpoint applies deletes, then patches, then posts in a single database
188
+ * transaction. We route edits (patches) through here because the standalone PATCH/PUT verbs
189
+ * aren't usable in our setup, and because it lets "remove others + assert target" happen
190
+ * without a window where the name resolves to nothing. */
191
+ export declare function batchRecords(zoneId: string, batch: {
192
+ deletes?: {
193
+ id: string;
194
+ }[];
195
+ patches?: {
196
+ id: string;
197
+ comment?: string;
198
+ }[];
199
+ posts?: {
200
+ type: string;
201
+ name: string;
202
+ content: string;
203
+ ttl: number;
204
+ proxied: boolean;
205
+ comment?: string;
206
+ }[];
207
+ }): Promise<void>;
147
208
  export declare function getRecords(type: string, key: string): Promise<string[]>;
148
209
  export declare function deleteRecord(type: string, key: string, value: string): Promise<void>;
149
- /** Removes all existing records (unless the record is already present) */
150
- export declare function setRecord(type: string, key: string, value: string, proxied?: "proxied"): Promise<void>;
210
+ /** Removes all existing records (unless the record is already present and fresh) */
211
+ export declare function setRecord(type: string, key: string, value: string, proxied?: "proxied", staleAfter?: number): Promise<void>;
151
212
  /** Keeps existing records */
152
- export declare function addRecord(type: string, key: string, value: string, proxied?: "proxied"): Promise<void>;
153
- /** Provide Cloudflare credentials directly (an API token, or a path to a file containing one), instead of relying on ./cloudflare.json */
154
- export declare function setCloudflareCredentials(config: {
155
- key?: string;
156
- path?: string;
157
- }): void;
213
+ export declare function addRecord(type: string, key: string, value: string, proxied?: "proxied", staleAfter?: number): Promise<void>;
158
214
 
159
215
  }
160
216
 
@@ -163,9 +219,6 @@ declare module "sliftutils/misc/https/hostServer" {
163
219
  /** Full domain to host on (e.g. "testsite.example.com"). The HTTPS cert is created for this domain and *.domain, so using a subdomain never touches the root domain (beyond its _acme-challenge TXT record). */
164
220
  domain: string;
165
221
  port: number;
166
- /** Cloudflare API token (or a path to a file containing one). If neither is given, ./cloudflare.json is used. */
167
- cloudflareApiToken?: string;
168
- cloudflareApiTokenPath?: string;
169
222
  /** Creates an unproxied A record pointing domain at this machine (publicIp, or our detected external IP) */
170
223
  setDNSRecord?: boolean;
171
224
  publicIp?: string;
@@ -796,6 +849,77 @@ declare module "sliftutils/render-utils/observer" {
796
849
 
797
850
  }
798
851
 
852
+ declare module "sliftutils/storage/ArchivesDisk" {
853
+ /// <reference types="node" />
854
+ /// <reference types="node" />
855
+ import { IArchives, ArchiveFileInfo, ArchivesConfig } from "./IArchives";
856
+ export declare class ArchivesDisk implements IArchives {
857
+ private folder;
858
+ constructor(folder: string);
859
+ private filesDir;
860
+ private uploadsDir;
861
+ private handles;
862
+ private largeUploads;
863
+ private nextLargeUploadId;
864
+ init: {
865
+ (): Promise<void>;
866
+ reset(): void;
867
+ set(newValue: Promise<void>): void;
868
+ };
869
+ getDebugName(): string;
870
+ getConfig(): Promise<ArchivesConfig>;
871
+ hasWriteAccess(): Promise<boolean>;
872
+ private filePath;
873
+ set(key: string, data: Buffer, config?: {
874
+ lastModified?: number;
875
+ }): Promise<void>;
876
+ del(key: string): Promise<void>;
877
+ get(key: string, config?: {
878
+ range?: {
879
+ start: number;
880
+ end: number;
881
+ };
882
+ }): Promise<Buffer | undefined>;
883
+ get2(key: string, config?: {
884
+ range?: {
885
+ start: number;
886
+ end: number;
887
+ };
888
+ }): Promise<{
889
+ data: Buffer;
890
+ writeTime: number;
891
+ size: number;
892
+ } | undefined>;
893
+ getInfo(key: string): Promise<{
894
+ writeTime: number;
895
+ size: number;
896
+ } | undefined>;
897
+ find(prefix: string, config?: {
898
+ shallow?: boolean;
899
+ type: "files" | "folders";
900
+ }): Promise<string[]>;
901
+ findInfo(prefix: string, config?: {
902
+ shallow?: boolean;
903
+ type?: "files" | "folders";
904
+ }): Promise<ArchiveFileInfo[]>;
905
+ private collectFiles;
906
+ setLargeFile(config: {
907
+ path: string;
908
+ getNextData(): Promise<Buffer | undefined>;
909
+ }): Promise<void>;
910
+ startLargeUpload(): Promise<string>;
911
+ appendLargeUpload(id: string, data: Buffer): Promise<void>;
912
+ finishLargeUpload(id: string, key: string): Promise<void>;
913
+ cancelLargeUpload(id: string): Promise<void>;
914
+ getURL(path: string): Promise<string>;
915
+ }
916
+ export declare function applyFindInfoShape(files: ArchiveFileInfo[], prefix: string, config?: {
917
+ shallow?: boolean;
918
+ type?: "files" | "folders";
919
+ }): ArchiveFileInfo[];
920
+
921
+ }
922
+
799
923
  declare module "sliftutils/storage/BulkDatabase2/BulkDatabase2" {
800
924
  import { BulkDatabaseBase, ReactiveDeps, BulkDatabase2Config, BulkFileInfoListing, MergeAttemptResult } from "./BulkDatabaseBase";
801
925
  export { BulkDatabaseBase, noopReactiveDeps, bulkDatabase2Timing } from "./BulkDatabaseBase";
@@ -1972,26 +2096,143 @@ declare module "sliftutils/storage/FileFolderAPI" {
1972
2096
  declare module "sliftutils/storage/IArchives" {
1973
2097
  /// <reference types="node" />
1974
2098
  /// <reference types="node" />
2099
+ export declare const MAX_LAST_MODIFIED_FUTURE: number;
2100
+ export declare const IMMUTABLE_CACHE_TIME: number;
2101
+ export declare function assertValidLastModified(lastModified: number): void;
2102
+ export type RemoteConfig = {
2103
+ version?: number;
2104
+ sources: RemoteConfigBase[];
2105
+ };
2106
+ /**
2107
+ string arguments will be a url, looking like:
2108
+ https://storage2.vidgridweb.com:4445/file/exampleaccount/examplebucket/storage/storagerouting.json
2109
+ https://f002.backblazeb2.com/file/querysubtest-com-public-immutable/storage/storagerouting.json
2110
+ - These map to { url }, with the type inferred from the url
2111
+ - Hosted urls are /file/<account>/<bucketName>/..., backblaze urls are /file/<bucketName>/...
2112
+
2113
+ NOTE: If we do not have right access to these, then it becomes a read-only IArchives, where we solely read using the url form (which might throw due to not having access as well). UNLESS Our configuration explicitly has public: false, in which case, we don't even hit the URL and we throw on access.
2114
+
2115
+ NOTE: If we're in the browser, we should allow downloading the files via the URL form (if it's a public bucket), however, we won't allow writing, because their servers do not allow secure browser writes.
2116
+ */
2117
+ export type RemoteConfigBase = string | HostedConfig | BackblazeConfig;
2118
+ export type CommonConfig = {
2119
+ /** By default a server hosting this bucket eagerly copies this source's full contents onto its own disk (on top of the lazy read-through caching). Set this to be a front end for a very large database without copying the full database - reads still down-cache individual files on demand. */
2120
+ noFullSync?: boolean;
2121
+ /** Bytes of read-cache this server's disk may hold; least-recently-used files are deleted from disk to stay under it (only ever when another source verifiably holds the file - the only copy is never deleted). Requires noFullSync (a full copy can't be bounded). */
2122
+ readerDiskLimit?: number;
2123
+ /** The write times ([startMs, endMs]) this source is valid for (see ArchivesSource.validWindow for the synchronization semantics). Required on object configs: configuration changes must be SCHEDULED (a new source becomes valid at a future time while the old one's window ends), not flipped instantly. Plain URL-string sources default to FULL_VALID_WINDOW - once you're writing object configs, you're doing something complicated enough to think about when things change. */
2124
+ validWindow: [number, number];
2125
+ /** Sharding: the fraction of the key space this source handles, as [start, end) over [0, 1) (keys are routed by getRoute in remoteConfig.ts). Defaults to FULL_ROUTE (unsharded). At every point in time the sources' routes must fully cover [0, 1), or some keys could never be read. */
2126
+ route?: [number, number];
2127
+ };
2128
+ export type HostedConfig = CommonConfig & {
2129
+ type: "remote";
2130
+ url: string;
2131
+ accountName?: string;
2132
+ public?: boolean;
2133
+ fast?: boolean;
2134
+ writeDelay?: number;
2135
+ rawDisk?: boolean;
2136
+ immutable?: boolean;
2137
+ };
2138
+ export type BackblazeConfig = CommonConfig & {
2139
+ type: "backblaze";
2140
+ url: string;
2141
+ public?: boolean;
2142
+ immutable?: boolean;
2143
+ };
2144
+ export declare const FULL_VALID_WINDOW: [number, number];
1975
2145
  export type ArchiveFileInfo = {
1976
2146
  path: string;
1977
2147
  createTime: number;
1978
2148
  size: number;
1979
2149
  };
2150
+ export type SyncActivity = {
2151
+ type: "metadataScan" | "fullSync";
2152
+ sourceDebugName: string;
2153
+ startTime: number;
2154
+ doneFiles?: number;
2155
+ totalFiles?: number;
2156
+ doneBytes?: number;
2157
+ totalBytes?: number;
2158
+ };
2159
+ export type ArchivesConfig = {
2160
+ supportsChangesAfter?: boolean;
2161
+ remoteConfig?: RemoteConfig;
2162
+ index?: {
2163
+ fileCount: number;
2164
+ byteCount: number;
2165
+ };
2166
+ indexSources?: {
2167
+ debugName: string;
2168
+ fileCount: number;
2169
+ byteCount: number;
2170
+ }[];
2171
+ readerDiskLimit?: number;
2172
+ syncing?: SyncActivity[];
2173
+ };
2174
+ export type ArchivesSource = {
2175
+ source: IArchives;
2176
+ validWindow: [number, number];
2177
+ route?: [number, number];
2178
+ noFullSync?: boolean;
2179
+ };
2180
+ export declare const WRITE_PAST_WINDOW_GRACE: number;
2181
+ export declare const STORAGE_WRONG_VALID_WINDOW = "REMOTE_STORAGE_WRONG_VALID_WINDOW_a7c1f04e";
2182
+ export declare const STORAGE_WRONG_ROUTE = "REMOTE_STORAGE_WRONG_ROUTE_c94d2e17";
2183
+ export declare const FULL_ROUTE: [number, number];
2184
+ export declare const VARIABLE_SHARD = "VARIABLE_SHARD_f0234jfah08fgyhfgyssdds83nmp";
2185
+ export declare function windowAcceptsWrites(validWindow: [number, number] | undefined): boolean;
2186
+ export type ArchivesSyncSourceStatus = {
2187
+ debugName: string;
2188
+ validWindow: [number, number];
2189
+ route?: [number, number];
2190
+ noFullSync?: boolean;
2191
+ supportsChangesAfter: boolean;
2192
+ initialScanComplete: boolean;
2193
+ scannedCount: number;
2194
+ };
2195
+ export type ArchivesSyncStatus = {
2196
+ allScansComplete: boolean;
2197
+ indexSize: number;
2198
+ sources: ArchivesSyncSourceStatus[];
2199
+ };
1980
2200
  export interface IArchives {
1981
2201
  getDebugName(): string;
2202
+ /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc).
2203
+ * Checked without writing anything. */
2204
+ hasWriteAccess(): Promise<boolean>;
1982
2205
  get(fileName: string, config?: {
1983
2206
  range?: {
1984
2207
  start: number;
1985
2208
  end: number;
1986
2209
  };
1987
2210
  }): Promise<Buffer | undefined>;
1988
- set(fileName: string, data: Buffer): Promise<void>;
2211
+ get2(fileName: string, config?: {
2212
+ range?: {
2213
+ start: number;
2214
+ end: number;
2215
+ };
2216
+ }): Promise<{
2217
+ data: Buffer;
2218
+ writeTime: number;
2219
+ size: number;
2220
+ } | undefined>;
2221
+ /**
2222
+ * lastModified stamps the write with that last-write time instead of now. If it is OLDER than
2223
+ * the file's current last-write time the write no-ops (so delayed / synchronized writes can
2224
+ * never clobber newer data). Times more than 15 minutes in the future are rejected.
2225
+ */
2226
+ set(fileName: string, data: Buffer, config?: {
2227
+ lastModified?: number;
2228
+ }): Promise<void>;
1989
2229
  del(fileName: string): Promise<void>;
1990
2230
  /** Streams a file too large to hold in memory. getNextData returns undefined when done. */
1991
2231
  setLargeFile(config: {
1992
2232
  path: string;
1993
2233
  getNextData(): Promise<Buffer | undefined>;
1994
2234
  }): Promise<void>;
2235
+ /** writeTime is the last-write time — see ArchiveFileInfo.createTime, which is the same value. */
1995
2236
  getInfo(fileName: string): Promise<{
1996
2237
  writeTime: number;
1997
2238
  size: number;
@@ -2006,6 +2247,15 @@ declare module "sliftutils/storage/IArchives" {
2006
2247
  }): Promise<ArchiveFileInfo[]>;
2007
2248
  /** Only works for public buckets (private buckets are API-access only). */
2008
2249
  getURL(path: string): Promise<string>;
2250
+ /** The bucket's configuration, which tells whether the optional functions are supported. */
2251
+ getConfig(): Promise<ArchivesConfig>;
2252
+ /**
2253
+ * All files changed after the given time. Only exists when getConfig().supportsChangesAfter;
2254
+ * backed by an index, so it is fast (unlike a full findInfo scan). Deletions are not reported.
2255
+ */
2256
+ getChangesAfter?(time: number): Promise<ArchiveFileInfo[]>;
2257
+ /** Synchronization introspection, for backends that synchronize from sources (see BlobStore). */
2258
+ getSyncStatus?(): Promise<ArchivesSyncStatus>;
2009
2259
  }
2010
2260
 
2011
2261
  }
@@ -2266,7 +2516,7 @@ declare module "sliftutils/storage/TransactionStorage" {
2266
2516
  declare module "sliftutils/storage/backblaze" {
2267
2517
  /// <reference types="node" />
2268
2518
  /// <reference types="node" />
2269
- import { IArchives } from "./IArchives";
2519
+ import { IArchives, ArchivesConfig } from "./IArchives";
2270
2520
  export declare class ArchivesBackblaze implements IArchives {
2271
2521
  private config;
2272
2522
  constructor(config: {
@@ -2274,6 +2524,7 @@ declare module "sliftutils/storage/backblaze" {
2274
2524
  public?: boolean;
2275
2525
  immutable?: boolean;
2276
2526
  cacheTime?: number;
2527
+ allowedOrigins?: string[];
2277
2528
  });
2278
2529
  private bucketName;
2279
2530
  private bucketId;
@@ -2282,6 +2533,7 @@ declare module "sliftutils/storage/backblaze" {
2282
2533
  private log;
2283
2534
  getDebugName(): string;
2284
2535
  private getBucketAPI;
2536
+ private currentReset;
2285
2537
  private last503Reset;
2286
2538
  private apiRetryLogic;
2287
2539
  get(fileName: string, config?: {
@@ -2291,7 +2543,21 @@ declare module "sliftutils/storage/backblaze" {
2291
2543
  };
2292
2544
  retryCount?: number;
2293
2545
  }): Promise<Buffer | undefined>;
2294
- set(fileName: string, data: Buffer): Promise<void>;
2546
+ get2(fileName: string, config?: {
2547
+ range?: {
2548
+ start: number;
2549
+ end: number;
2550
+ };
2551
+ }): Promise<{
2552
+ data: Buffer;
2553
+ writeTime: number;
2554
+ size: number;
2555
+ } | undefined>;
2556
+ getConfig(): Promise<ArchivesConfig>;
2557
+ hasWriteAccess(): Promise<boolean>;
2558
+ set(fileName: string, data: Buffer, config?: {
2559
+ lastModified?: number;
2560
+ }): Promise<void>;
2295
2561
  del(fileName: string): Promise<void>;
2296
2562
  setLargeFile(config: {
2297
2563
  path: string;
@@ -2314,6 +2580,17 @@ declare module "sliftutils/storage/backblaze" {
2314
2580
  size: number;
2315
2581
  }[]>;
2316
2582
  assertPathValid(path: string): Promise<void>;
2583
+ move(config: {
2584
+ path: string;
2585
+ target: IArchives;
2586
+ targetPath: string;
2587
+ copyInstead?: boolean;
2588
+ }): Promise<void>;
2589
+ copy(config: {
2590
+ path: string;
2591
+ target: IArchives;
2592
+ targetPath: string;
2593
+ }): Promise<void>;
2317
2594
  getURL(path: string): Promise<string>;
2318
2595
  getDownloadAuthorization(config: {
2319
2596
  fileNamePrefix?: string;
@@ -2574,23 +2851,16 @@ declare module "sliftutils/storage/remoteFileStorage" {
2574
2851
  declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2575
2852
  /// <reference types="node" />
2576
2853
  /// <reference types="node" />
2577
- import { IArchives, ArchiveFileInfo } from "../IArchives";
2854
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus } from "../IArchives";
2578
2855
  export type ArchivesRemoteConfig = {
2579
- address: string;
2580
- port: number;
2581
- account: string;
2582
- bucketName: string;
2583
- public?: boolean;
2584
- fast?: boolean;
2585
- writeDelay?: number;
2856
+ url: string;
2857
+ accountName?: string;
2858
+ waitForAccess?: boolean;
2586
2859
  };
2587
- export declare function buildPublicFileURL(config: {
2860
+ export declare function parseStorageUrl(url: string): {
2588
2861
  address: string;
2589
2862
  port: number;
2590
- account: string;
2591
- bucketName: string;
2592
- path: string;
2593
- }): string;
2863
+ };
2594
2864
  export declare function authenticateStorage(config: {
2595
2865
  address: string;
2596
2866
  port: number;
@@ -2602,16 +2872,24 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2602
2872
  export declare class ArchivesRemote implements IArchives {
2603
2873
  private config;
2604
2874
  constructor(config: ArchivesRemoteConfig);
2875
+ private parsed;
2876
+ private account;
2877
+ private bucketName;
2605
2878
  private nodeId;
2606
2879
  private controller;
2607
- private setupDone;
2608
2880
  private lastDeniedLog;
2609
2881
  getDebugName(): string;
2882
+ isConnected(): boolean;
2883
+ ping(): Promise<void>;
2610
2884
  private authenticate;
2611
2885
  private callAuthed;
2612
- waitingForAccess(): Promise<string | undefined>;
2613
- private onAccessDenied;
2614
- private ensureSetup;
2886
+ waitingForAccess(): Promise<{
2887
+ link: string;
2888
+ machineId: string;
2889
+ ip: string;
2890
+ } | undefined>;
2891
+ hasWriteAccess(): Promise<boolean>;
2892
+ private registerAccessRequest;
2615
2893
  private call;
2616
2894
  get(fileName: string, config?: {
2617
2895
  range?: {
@@ -2619,7 +2897,19 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2619
2897
  end: number;
2620
2898
  };
2621
2899
  }): Promise<Buffer | undefined>;
2622
- set(fileName: string, data: Buffer): Promise<void>;
2900
+ get2(fileName: string, config?: {
2901
+ range?: {
2902
+ start: number;
2903
+ end: number;
2904
+ };
2905
+ }): Promise<{
2906
+ data: Buffer;
2907
+ writeTime: number;
2908
+ size: number;
2909
+ } | undefined>;
2910
+ set(fileName: string, data: Buffer, config?: {
2911
+ lastModified?: number;
2912
+ }): Promise<void>;
2623
2913
  del(fileName: string): Promise<void>;
2624
2914
  getInfo(fileName: string): Promise<{
2625
2915
  writeTime: number;
@@ -2633,6 +2923,9 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2633
2923
  shallow?: boolean;
2634
2924
  type: "files" | "folders";
2635
2925
  }): Promise<string[]>;
2926
+ getChangesAfter(time: number): Promise<ArchiveFileInfo[]>;
2927
+ getConfig(): Promise<ArchivesConfig>;
2928
+ getSyncStatus(): Promise<ArchivesSyncStatus>;
2636
2929
  setLargeFile(config: {
2637
2930
  path: string;
2638
2931
  getNextData(): Promise<Buffer | undefined>;
@@ -2642,6 +2935,58 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2642
2935
 
2643
2936
  }
2644
2937
 
2938
+ declare module "sliftutils/storage/remoteStorage/ArchivesUrl" {
2939
+ /// <reference types="node" />
2940
+ /// <reference types="node" />
2941
+ import { IArchives, ArchiveFileInfo, ArchivesConfig } from "../IArchives";
2942
+ export declare class ArchivesUrl implements IArchives {
2943
+ private base;
2944
+ constructor(base: string);
2945
+ getDebugName(): string;
2946
+ private readOnlyError;
2947
+ get(fileName: string, config?: {
2948
+ range?: {
2949
+ start: number;
2950
+ end: number;
2951
+ };
2952
+ }): Promise<Buffer | undefined>;
2953
+ get2(fileName: string, config?: {
2954
+ range?: {
2955
+ start: number;
2956
+ end: number;
2957
+ };
2958
+ }): Promise<{
2959
+ data: Buffer;
2960
+ writeTime: number;
2961
+ size: number;
2962
+ } | undefined>;
2963
+ getInfo(fileName: string): Promise<{
2964
+ writeTime: number;
2965
+ size: number;
2966
+ } | undefined>;
2967
+ set(fileName: string, data: Buffer, config?: {
2968
+ lastModified?: number;
2969
+ }): Promise<void>;
2970
+ del(fileName: string): Promise<void>;
2971
+ setLargeFile(config: {
2972
+ path: string;
2973
+ getNextData(): Promise<Buffer | undefined>;
2974
+ }): Promise<void>;
2975
+ find(prefix: string, config?: {
2976
+ shallow?: boolean;
2977
+ type: "files" | "folders";
2978
+ }): Promise<string[]>;
2979
+ findInfo(prefix: string, config?: {
2980
+ shallow?: boolean;
2981
+ type: "files" | "folders";
2982
+ }): Promise<ArchiveFileInfo[]>;
2983
+ getURL(path: string): Promise<string>;
2984
+ getConfig(): Promise<ArchivesConfig>;
2985
+ hasWriteAccess(): Promise<boolean>;
2986
+ }
2987
+
2988
+ }
2989
+
2645
2990
  declare module "sliftutils/storage/remoteStorage/accessPage" {
2646
2991
  export {};
2647
2992
 
@@ -2650,45 +2995,143 @@ declare module "sliftutils/storage/remoteStorage/accessPage" {
2650
2995
  declare module "sliftutils/storage/remoteStorage/blobStore" {
2651
2996
  /// <reference types="node" />
2652
2997
  /// <reference types="node" />
2653
- import { ArchiveFileInfo } from "../IArchives";
2998
+ import { ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, SyncActivity } from "../IArchives";
2654
2999
  export declare const DEFAULT_FAST_WRITE_DELAY: number;
2655
3000
  export type WriteConfig = {
2656
3001
  fast?: boolean;
2657
3002
  writeDelay?: number;
3003
+ lastModified?: number;
3004
+ };
3005
+ export type IBucketStore = {
3006
+ get(fileName: string, config?: {
3007
+ range?: {
3008
+ start: number;
3009
+ end: number;
3010
+ };
3011
+ }): Promise<Buffer | undefined>;
3012
+ get2(fileName: string, config?: {
3013
+ range?: {
3014
+ start: number;
3015
+ end: number;
3016
+ };
3017
+ }): Promise<{
3018
+ data: Buffer;
3019
+ writeTime: number;
3020
+ size: number;
3021
+ } | undefined>;
3022
+ set(fileName: string, data: Buffer, config?: WriteConfig): Promise<void>;
3023
+ del(fileName: string, config?: WriteConfig): Promise<void>;
3024
+ getInfo(fileName: string): Promise<{
3025
+ writeTime: number;
3026
+ size: number;
3027
+ } | undefined>;
3028
+ findInfo(prefix: string, config?: {
3029
+ shallow?: boolean;
3030
+ type?: "files" | "folders";
3031
+ }): Promise<ArchiveFileInfo[]>;
3032
+ getChangesAfter?(time: number): Promise<ArchiveFileInfo[]>;
3033
+ getSyncStatus?(): Promise<ArchivesSyncStatus>;
3034
+ getSyncProgress?(): {
3035
+ index: {
3036
+ fileCount: number;
3037
+ byteCount: number;
3038
+ };
3039
+ syncing: SyncActivity[];
3040
+ };
3041
+ computeIndexTotals?(): Promise<{
3042
+ fileCount: number;
3043
+ byteCount: number;
3044
+ }>;
3045
+ startLargeUpload(): Promise<string>;
3046
+ appendLargeUpload(id: string, data: Buffer): Promise<void>;
3047
+ finishLargeUpload(id: string, key: string): Promise<void>;
3048
+ cancelLargeUpload(id: string): Promise<void>;
2658
3049
  };
2659
- export declare class BlobStore {
3050
+ export declare class BlobStore implements IBucketStore {
2660
3051
  private folder;
2661
- constructor(folder: string);
2662
- private memCache;
2663
- private overlay;
2664
- private writeQueue;
2665
- private openBlobs;
2666
- private largeUploads;
2667
- private nextLargeUploadId;
2668
- private currentBlobNumber;
2669
- private currentBlobOffset;
2670
- private currentBlobFd;
3052
+ private sources;
3053
+ private config?;
3054
+ constructor(folder: string, sources: ArchivesSource[], config?: {
3055
+ onIndexChanged?: ((key: string) => void) | undefined;
3056
+ readerDiskLimit?: number | undefined;
3057
+ } | undefined);
3058
+ private stopped;
2671
3059
  private index;
2672
- private deadBytes;
2673
- private blobsDir;
3060
+ private mem;
3061
+ private indexFileCount;
3062
+ private indexByteCount;
3063
+ private sourceFileCounts;
3064
+ private sourceByteCounts;
3065
+ private syncActivities;
3066
+ private dirty;
3067
+ private overlay;
3068
+ private sourceStates;
2674
3069
  init: {
2675
3070
  (): Promise<void>;
2676
3071
  reset(): void;
2677
3072
  set(newValue: Promise<void>): void;
2678
3073
  };
2679
- private blobName;
2680
- private blobPath;
2681
- private getBlobHandle;
2682
- private closeBlobHandle;
2683
- private addDeadBytes;
2684
- private appendData;
3074
+ dispose(): Promise<void>;
3075
+ private loadIndex;
3076
+ private countEntry;
2685
3077
  private setIndexEntry;
3078
+ private deleteIndexEntry;
3079
+ /** The cheap always-current totals plus any in-progress background synchronization. */
3080
+ getSyncProgress(): {
3081
+ index: {
3082
+ fileCount: number;
3083
+ byteCount: number;
3084
+ };
3085
+ sources: {
3086
+ debugName: string;
3087
+ fileCount: number;
3088
+ byteCount: number;
3089
+ }[];
3090
+ readerDiskLimit?: number;
3091
+ syncing: SyncActivity[];
3092
+ };
3093
+ /** Walks the whole index for exact totals - more expensive than getSyncProgress, but immune to
3094
+ * any drift in the maintained counters (and loads the index first, so it's never cold zeros). */
3095
+ computeIndexTotals(): Promise<{
3096
+ fileCount: number;
3097
+ byteCount: number;
3098
+ sources: {
3099
+ debugName: string;
3100
+ fileCount: number;
3101
+ byteCount: number;
3102
+ }[];
3103
+ }>;
3104
+ private flushIndex;
3105
+ private runSourceSync;
3106
+ private scanSource;
3107
+ private reconcileSource;
3108
+ private applyScanned;
3109
+ private pollChanges;
3110
+ private copySourceFiles;
3111
+ private waitForRequiredScans;
3112
+ private checkMissingKey;
3113
+ private getIndexEntry;
3114
+ get(key: string, config?: {
3115
+ range?: {
3116
+ start: number;
3117
+ end: number;
3118
+ };
3119
+ }): Promise<Buffer | undefined>;
3120
+ get2(key: string, config?: {
3121
+ range?: {
3122
+ start: number;
3123
+ end: number;
3124
+ };
3125
+ }): Promise<{
3126
+ data: Buffer;
3127
+ writeTime: number;
3128
+ size: number;
3129
+ } | undefined>;
3130
+ private cacheRead;
2686
3131
  set(key: string, data: Buffer, config?: WriteConfig): Promise<void>;
2687
3132
  del(key: string, config?: WriteConfig): Promise<void>;
2688
- get(key: string, range?: {
2689
- start: number;
2690
- end: number;
2691
- }): Promise<Buffer | undefined>;
3133
+ private getWritableSources;
3134
+ private writeToSources;
2692
3135
  getInfo(key: string): Promise<{
2693
3136
  writeTime: number;
2694
3137
  size: number;
@@ -2697,12 +3140,194 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
2697
3140
  shallow?: boolean;
2698
3141
  type?: "files" | "folders";
2699
3142
  }): Promise<ArchiveFileInfo[]>;
3143
+ getChangesAfter(time: number): Promise<ArchiveFileInfo[]>;
3144
+ getSyncStatus(): Promise<ArchivesSyncStatus>;
3145
+ private getDiskSource;
2700
3146
  startLargeUpload(): Promise<string>;
2701
3147
  appendLargeUpload(id: string, data: Buffer): Promise<void>;
2702
3148
  finishLargeUpload(id: string, key: string): Promise<void>;
2703
3149
  cancelLargeUpload(id: string): Promise<void>;
2704
3150
  private flushOverlay;
2705
- private compact;
3151
+ private evicting;
3152
+ private enforceDiskLimit;
3153
+ private cleanupTombstones;
3154
+ }
3155
+
3156
+ }
3157
+
3158
+ declare module "sliftutils/storage/remoteStorage/cliArgs" {
3159
+ export declare function getArg(name: string): string | undefined;
3160
+
3161
+ }
3162
+
3163
+ declare module "sliftutils/storage/remoteStorage/createArchives" {
3164
+ /// <reference types="node" />
3165
+ /// <reference types="node" />
3166
+ import { IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus } from "../IArchives";
3167
+ export declare function createApiArchives(source: HostedConfig | BackblazeConfig): IArchives;
3168
+ export declare class ArchivesChain implements IArchives {
3169
+ private configured;
3170
+ private activeConfig;
3171
+ private statePromise;
3172
+ private initRetryDelay;
3173
+ private initRetryTimer;
3174
+ private pollTimer;
3175
+ private disposed;
3176
+ constructor(config: RemoteConfig | RemoteConfigBase);
3177
+ getDebugName(): string;
3178
+ private getState;
3179
+ private init;
3180
+ private buildSources;
3181
+ private startConfigPoll;
3182
+ private checkForNewConfig;
3183
+ private run;
3184
+ private runWrite;
3185
+ private request;
3186
+ waitingForAccess(): Promise<{
3187
+ link: string;
3188
+ machineId: string;
3189
+ ip: string;
3190
+ } | undefined>;
3191
+ get(fileName: string, config?: {
3192
+ range?: {
3193
+ start: number;
3194
+ end: number;
3195
+ };
3196
+ }): Promise<Buffer | undefined>;
3197
+ get2(fileName: string, config?: {
3198
+ range?: {
3199
+ start: number;
3200
+ end: number;
3201
+ };
3202
+ }): Promise<{
3203
+ data: Buffer;
3204
+ writeTime: number;
3205
+ size: number;
3206
+ } | undefined>;
3207
+ getInfo(fileName: string): Promise<{
3208
+ writeTime: number;
3209
+ size: number;
3210
+ } | undefined>;
3211
+ private selectCoveringSources;
3212
+ private runOnApi;
3213
+ find(prefix: string, config?: {
3214
+ shallow?: boolean;
3215
+ type: "files" | "folders";
3216
+ }): Promise<string[]>;
3217
+ findInfo(prefix: string, config?: {
3218
+ shallow?: boolean;
3219
+ type: "files" | "folders";
3220
+ }): Promise<ArchiveFileInfo[]>;
3221
+ getChangesAfter(time: number): Promise<ArchiveFileInfo[]>;
3222
+ getSyncStatus(): Promise<ArchivesSyncStatus>;
3223
+ getConfig(): Promise<ArchivesConfig>;
3224
+ /** True only when EVERY write-receiving source would accept our writes (partial write access
3225
+ * desynchronizes sources, so it counts as no access). */
3226
+ hasWriteAccess(): Promise<boolean>;
3227
+ private assertNotBareVariableShard;
3228
+ set(fileName: string, data: Buffer, config?: {
3229
+ lastModified?: number;
3230
+ }): Promise<void>;
3231
+ del(fileName: string): Promise<void>;
3232
+ /** Writes a key containing the VARIABLE_SHARD sentinel: picks the lowest-latency up write
3233
+ * shard, materializes the key with a random value inside that shard's route, writes it, and
3234
+ * returns the FULL key actually written (the caller needs it to ever read the value back).
3235
+ * Unlike normal writes this CAN move to another shard when the preferred one is down (error +
3236
+ * socket down, same rule as reads) - each shard receives a different key, so write
3237
+ * consistency is preserved. */
3238
+ setVariableShard(key: string, data: Buffer, config?: {
3239
+ lastModified?: number;
3240
+ }): Promise<string>;
3241
+ setLargeFile(config: {
3242
+ path: string;
3243
+ getNextData(): Promise<Buffer | undefined>;
3244
+ }): Promise<void>;
3245
+ getURL(path: string): Promise<string>;
3246
+ dispose(): void;
3247
+ }
3248
+ export declare function createArchives(config: RemoteConfig | RemoteConfigBase): ArchivesChain;
3249
+
3250
+ }
3251
+
3252
+ declare module "sliftutils/storage/remoteStorage/grantAccessCli" {
3253
+ export {};
3254
+
3255
+ }
3256
+
3257
+ declare module "sliftutils/storage/remoteStorage/remoteConfig" {
3258
+ /// <reference types="node" />
3259
+ /// <reference types="node" />
3260
+ import { RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig } from "../IArchives";
3261
+ export declare const ROUTING_FILE = "storage/storagerouting.json";
3262
+ /** The variable-shard route override embedded in the key ("<sentinel>_<value>", see VARIABLE_SHARD), or undefined when the key has no sentinel or the sentinel has no value yet. */
3263
+ export declare function parseVariableRoute(key: string): number | undefined;
3264
+ /** Where a key routes in [0, 1). A materialized variable-shard suffix completely overrides the hash. */
3265
+ export declare function getRoute(key: string): number;
3266
+ export declare function routeContains(route: [number, number] | undefined, value: number): boolean;
3267
+ export declare function routesOverlap(a: [number, number] | undefined, b: [number, number] | undefined): boolean;
3268
+ /** The overlap of two route ranges, or undefined when they don't overlap. */
3269
+ export declare function routeIntersection(a: [number, number] | undefined, b: [number, number] | undefined): [number, number] | undefined;
3270
+ export declare function getConfigVersion(config: RemoteConfig): number;
3271
+ /** Strips the routing-file suffix, leaving the bucket's public base URL (file paths append to it). */
3272
+ export declare function getBucketBaseUrl(url: string): string;
3273
+ export declare function buildFileUrl(baseUrl: string, filePath: string): string;
3274
+ export declare function parseHostedUrl(url: string): {
3275
+ address: string;
3276
+ port: number;
3277
+ account: string;
3278
+ bucketName: string;
3279
+ };
3280
+ export declare function parseBackblazeUrl(url: string): {
3281
+ bucketName: string;
3282
+ };
3283
+ export declare function normalizeSource(source: RemoteConfigBase): HostedConfig | BackblazeConfig;
3284
+ export declare function normalizeRemoteConfig(config: RemoteConfig | RemoteConfigBase): RemoteConfig;
3285
+ export declare function parseRoutingData(data: Buffer): RemoteConfig;
3286
+ export declare function serializeRemoteConfig(config: RemoteConfig): Buffer;
3287
+
3288
+ }
3289
+
3290
+ declare module "sliftutils/storage/remoteStorage/sourceWrapper" {
3291
+ import { IArchives, HostedConfig, BackblazeConfig } from "../IArchives";
3292
+ import { ArchivesUrl } from "./ArchivesUrl";
3293
+ export declare const RETRY_START_DELAY: number;
3294
+ export declare const RETRY_MAX_DELAY: number;
3295
+ export declare const RETRY_GROWTH = 1.5;
3296
+ export declare class SourceWrapper {
3297
+ config: HostedConfig | BackblazeConfig;
3298
+ private background;
3299
+ api?: IArchives;
3300
+ url?: ArchivesUrl;
3301
+ writeBlocked?: string;
3302
+ private remote?;
3303
+ private disposed;
3304
+ private reconnectRunning;
3305
+ private accessCache?;
3306
+ private constructor();
3307
+ static create(config: HostedConfig | BackblazeConfig, options?: {
3308
+ background?: boolean;
3309
+ }): Promise<SourceWrapper>;
3310
+ getDebugName(): string;
3311
+ isConnected(): boolean;
3312
+ /** Call after a request failed while isConnected() was false: starts (if not already running)
3313
+ * the background reconnect loop. Never blocks - the failed request still throws. */
3314
+ noteFailure(): void;
3315
+ private reconnectLoop;
3316
+ private checkAccess;
3317
+ read<T>(run: (archives: IArchives) => Promise<T>): Promise<T>;
3318
+ hasWriteAccess(): Promise<boolean>;
3319
+ private pings;
3320
+ private pingTimer;
3321
+ /** Starts measuring this source's latency (for variable-shard target preference). Only hosted
3322
+ * remotes are pinged; our own local server counts as 0, everything else as Infinity. */
3323
+ startPinging(): void;
3324
+ /** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our
3325
+ * own in-process server, which is the best possible target (0). */
3326
+ getLatency(): number;
3327
+ /** Writes always go through the API, so a permission error throws to the caller on every write
3328
+ * (and access granted in the meantime is picked up automatically). */
3329
+ write<T>(run: (archives: IArchives) => Promise<T>): Promise<T>;
3330
+ dispose(): void;
2706
3331
  }
2707
3332
 
2708
3333
  }
@@ -2710,9 +3335,7 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
2710
3335
  declare module "sliftutils/storage/remoteStorage/storageController" {
2711
3336
  /// <reference types="node" />
2712
3337
  /// <reference types="node" />
2713
- import { ArchiveFileInfo } from "../IArchives";
2714
- import type { BlobStore } from "./blobStore";
2715
- import type { IStorage } from "../IStorage";
3338
+ import { ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus } from "../IArchives";
2716
3339
  export declare const REMOTE_STORAGE_CLASS_GUID = "RemoteStorageController-b7e42a91";
2717
3340
  export declare const STORAGE_AUTH_PURPOSE = "remoteStorage-auth-1";
2718
3341
  export declare const STORAGE_NOT_AUTHENTICATED = "REMOTE_STORAGE_NOT_AUTHENTICATED_cf2f7b1e";
@@ -2735,34 +3358,15 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
2735
3358
  ip: string;
2736
3359
  time: number;
2737
3360
  };
2738
- export type BucketConfig = {
2739
- public?: boolean;
2740
- fast?: boolean;
2741
- writeDelay?: number;
2742
- };
2743
3361
  export type AccessState = {
2744
3362
  machineId: string;
2745
3363
  ip: string;
2746
3364
  hasAccess: boolean;
2747
- listAccessCommand: string;
2748
3365
  grantAccessCommand?: string;
2749
- machines?: (AccessRequest & {
2750
- trusted: boolean;
2751
- })[];
2752
- };
2753
- export type StorageServerState = {
2754
- domain: string;
2755
- port: number;
2756
- rootDomain: string;
2757
- sshTarget: string;
2758
- serverCommand: string;
2759
- blobStore: BlobStore;
2760
- trust: IStorage<TrustRecord>;
2761
- requests: IStorage<AccessRequest[]>;
2762
- buckets: IStorage<BucketConfig>;
3366
+ trustedMachines?: TrustRecord[];
2763
3367
  };
2764
- export declare function setStorageServerState(state: StorageServerState): void;
2765
3368
  export declare const RemoteStorageController: import("socket-function/SocketFunctionTypes").SocketRegistered<{
3369
+ ping: () => Promise<void>;
2766
3370
  authenticate: (token: AuthToken) => Promise<{
2767
3371
  machineId: string;
2768
3372
  ip: string;
@@ -2774,14 +3378,23 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
2774
3378
  grantAccessCommand: string;
2775
3379
  }>;
2776
3380
  getAccessState: (account: string) => Promise<AccessState>;
3381
+ listRequestsForIP: (account: string, ip: string) => Promise<AccessRequest[]>;
3382
+ grantAccess: (requestId: string) => Promise<TrustRecord>;
2777
3383
  adminListRequests: (ip: string) => Promise<AccessRequest[]>;
2778
3384
  adminGrantAccess: (requestId: string) => Promise<TrustRecord>;
2779
- ensureBucket: (account: string, bucketName: string, config: BucketConfig) => Promise<void>;
2780
3385
  get: (account: string, bucketName: string, path: string, range?: {
2781
3386
  start: number;
2782
3387
  end: number;
2783
3388
  }) => Promise<Buffer | undefined>;
2784
- set: (account: string, bucketName: string, path: string, data: Buffer) => Promise<void>;
3389
+ get2: (account: string, bucketName: string, path: string, range?: {
3390
+ start: number;
3391
+ end: number;
3392
+ }) => Promise<{
3393
+ data: Buffer;
3394
+ writeTime: number;
3395
+ size: number;
3396
+ } | undefined>;
3397
+ set: (account: string, bucketName: string, path: string, data: Buffer, lastModified?: number) => Promise<void>;
2785
3398
  del: (account: string, bucketName: string, path: string) => Promise<void>;
2786
3399
  getInfo: (account: string, bucketName: string, path: string) => Promise<{
2787
3400
  writeTime: number;
@@ -2791,17 +3404,90 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
2791
3404
  shallow?: boolean;
2792
3405
  type?: "files" | "folders";
2793
3406
  }) => Promise<ArchiveFileInfo[]>;
3407
+ getChangesAfter: (account: string, bucketName: string, time: number) => Promise<ArchiveFileInfo[]>;
3408
+ getArchivesConfig: (account: string, bucketName: string) => Promise<ArchivesConfig>;
3409
+ getIndexInfo: (account: string, bucketName: string) => Promise<{
3410
+ fileCount: number;
3411
+ byteCount: number;
3412
+ sources: {
3413
+ debugName: string;
3414
+ fileCount: number;
3415
+ byteCount: number;
3416
+ }[];
3417
+ } | undefined>;
3418
+ getSyncStatus: (account: string, bucketName: string) => Promise<ArchivesSyncStatus>;
2794
3419
  startLargeFile: (account: string, bucketName: string, path: string) => Promise<string>;
2795
3420
  uploadPart: (uploadId: string, data: Buffer) => Promise<void>;
2796
3421
  finishLargeFile: (uploadId: string) => Promise<void>;
2797
3422
  cancelLargeFile: (uploadId: string) => Promise<void>;
2798
- getPublicFile: (account: string, bucketName: string, path: string) => Promise<Buffer>;
3423
+ httpEntry: (config?: {
3424
+ requireCalls?: string[];
3425
+ cacheTime?: number;
3426
+ }) => Promise<Buffer>;
2799
3427
  }>;
2800
3428
 
2801
3429
  }
2802
3430
 
2803
3431
  declare module "sliftutils/storage/remoteStorage/storageServer" {
2804
3432
  import "./accessPage";
3433
+ export type HostStorageServerConfig = {
3434
+ url: string;
3435
+ folder: string;
3436
+ lowSpaceThresholdBytes?: number;
3437
+ };
3438
+ export declare function hostStorageServer(config: HostStorageServerConfig): Promise<void>;
3439
+
3440
+ }
3441
+
3442
+ declare module "sliftutils/storage/remoteStorage/storageServerCli" {
3443
+ export {};
3444
+
3445
+ }
3446
+
3447
+ declare module "sliftutils/storage/remoteStorage/storageServerState" {
3448
+ /// <reference types="node" />
3449
+ /// <reference types="node" />
3450
+ import { IBucketStore } from "./blobStore";
3451
+ import { RemoteConfig, HostedConfig, IArchives } from "../IArchives";
3452
+ import type { IStorage } from "../IStorage";
3453
+ import type { AccessRequest, TrustRecord } from "./storageController";
3454
+ export type StorageServerConfig = {
3455
+ domain: string;
3456
+ port: number;
3457
+ rootDomain: string;
3458
+ sshTarget: string;
3459
+ serverCommand: string;
3460
+ folder: string;
3461
+ };
3462
+ export declare function setStorageServerConfig(value: StorageServerConfig): void;
3463
+ export declare function getStorageServerConfig(): StorageServerConfig;
3464
+ export declare function getStorageServerConfigOptional(): StorageServerConfig | undefined;
3465
+ export declare function setWritesRejectedReason(reason: string | undefined): void;
3466
+ export declare function getWritesRejectedReason(): string | undefined;
3467
+ export declare function assertWritesAllowed(): void;
3468
+ export declare function getTrust(): Promise<IStorage<TrustRecord>>;
3469
+ export declare function getRequests(): Promise<IStorage<AccessRequest[]>>;
3470
+ /** Makes machineIds the complete trust list for the account: machines not in the list lose access, machines already trusted keep their existing record, and missing ones are added. */
3471
+ export declare function setTrustedMachines(config: {
3472
+ account: string;
3473
+ machineIds: string[];
3474
+ }): Promise<void>;
3475
+ export type LoadedBucket = {
3476
+ account: string;
3477
+ bucketName: string;
3478
+ routing: RemoteConfig;
3479
+ routingJSON: string;
3480
+ selfEntries: HostedConfig[];
3481
+ self: HostedConfig | undefined;
3482
+ store: IBucketStore;
3483
+ };
3484
+ export declare function getLoadedBucket(account: string, bucketName: string): Promise<LoadedBucket | undefined>;
3485
+ export declare function assertMutable(bucket: LoadedBucket, filePath: string, writeTime: number): Promise<void>;
3486
+ export declare function writeBucketFile(account: string, bucketName: string, filePath: string, data: Buffer, config?: {
3487
+ lastModified?: number;
3488
+ }): Promise<void>;
3489
+ export declare function deleteBucketFile(account: string, bucketName: string, filePath: string): Promise<void>;
3490
+ export declare function getLocalArchives(account: string, bucketName: string): IArchives;
2805
3491
 
2806
3492
  }
2807
3493