sliftutils 1.7.10 → 1.7.12

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 (84) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/examplestorage/exampleserver.ts +0 -2
  3. package/index.d.ts +301 -54
  4. package/misc/dist/environment.ts.cache +3 -3
  5. package/misc/dist/getSecret.ts.cache +139 -0
  6. package/misc/dist/strings.ts.cache +13 -0
  7. package/misc/dist/zip.ts.cache +9 -0
  8. package/misc/getSecret.ts +38 -16
  9. package/misc/https/cloudflareHelpers.d.ts +19 -0
  10. package/misc/https/cloudflareHelpers.ts +69 -0
  11. package/misc/https/dist/certs.ts.cache +115 -179
  12. package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
  13. package/misc/https/dist/dns.ts.cache +112 -100
  14. package/misc/https/dist/hostServer.ts.cache +130 -0
  15. package/misc/https/dist/httpsCerts.ts.cache +24 -5
  16. package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
  17. package/misc/https/dns.d.ts +41 -12
  18. package/misc/https/dns.ts +104 -101
  19. package/misc/https/hostServer.d.ts +0 -6
  20. package/misc/https/hostServer.ts +9 -5
  21. package/package.json +2 -2
  22. package/render-utils/dist/observer.tsx.cache +3 -2
  23. package/spec.txt +0 -90
  24. package/storage/ArchivesDisk.d.ts +2 -0
  25. package/storage/ArchivesDisk.ts +7 -3
  26. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
  27. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
  28. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
  29. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
  30. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
  31. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
  32. package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
  33. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
  34. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
  35. package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
  36. package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
  37. package/storage/IArchives.d.ts +47 -15
  38. package/storage/IArchives.ts +86 -31
  39. package/storage/backblaze.d.ts +15 -0
  40. package/storage/backblaze.ts +199 -79
  41. package/storage/dist/ArchivesDisk.ts.cache +373 -0
  42. package/storage/dist/FileFolderAPI.tsx.cache +508 -65
  43. package/storage/dist/IArchives.ts.cache +44 -0
  44. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
  45. package/storage/dist/JSONStorage.ts.cache +6 -2
  46. package/storage/dist/PendingManager.tsx.cache +1 -1
  47. package/storage/dist/TransactionStorage.ts.cache +231 -92
  48. package/storage/dist/backblaze.ts.cache +797 -0
  49. package/storage/dist/fileSystemPointer.ts.cache +36 -3
  50. package/storage/dist/remoteFileStorage.ts.cache +495 -0
  51. package/storage/remoteStorage/ArchivesRemote.d.ts +5 -1
  52. package/storage/remoteStorage/ArchivesRemote.ts +28 -8
  53. package/storage/remoteStorage/ArchivesUrl.d.ts +2 -0
  54. package/storage/remoteStorage/ArchivesUrl.ts +16 -4
  55. package/storage/remoteStorage/blobStore.d.ts +63 -3
  56. package/storage/remoteStorage/blobStore.ts +419 -101
  57. package/storage/remoteStorage/createArchives.d.ts +31 -10
  58. package/storage/remoteStorage/createArchives.ts +470 -253
  59. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
  60. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
  61. package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
  62. package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
  63. package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
  64. package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
  65. package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
  66. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
  67. package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
  68. package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
  69. package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
  70. package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
  71. package/storage/remoteStorage/remoteConfig.d.ts +8 -0
  72. package/storage/remoteStorage/remoteConfig.ts +105 -5
  73. package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
  74. package/storage/remoteStorage/sourceWrapper.ts +223 -0
  75. package/storage/remoteStorage/spec.md +31 -0
  76. package/storage/remoteStorage/storageController.d.ts +11 -0
  77. package/storage/remoteStorage/storageController.ts +109 -40
  78. package/storage/remoteStorage/storageServer.d.ts +0 -5
  79. package/storage/remoteStorage/storageServer.ts +17 -10
  80. package/storage/remoteStorage/storageServerCli.ts +0 -3
  81. package/storage/remoteStorage/storageServerState.d.ts +7 -1
  82. package/storage/remoteStorage/storageServerState.ts +230 -48
  83. package/testsite/server.ts +0 -2
  84. package/yarn.lock +11 -6
@@ -6,6 +6,10 @@ module.allowclient = true;
6
6
  // A write may not be stamped more than this far in the future, or clock skew between machines
7
7
  // would let a bad timestamp block writes for a long time.
8
8
  export const MAX_LAST_MODIFIED_FUTURE = 15 * 60 * 1000;
9
+
10
+ // How long browsers may cache files from immutable buckets (the Cache-Control max-age), shared by
11
+ // every hosting path (backblaze bucket settings and our own storage server's HTTP route)
12
+ export const IMMUTABLE_CACHE_TIME = 86400 * 1000;
9
13
  export function assertValidLastModified(lastModified: number): void {
10
14
  let max = Date.now() + MAX_LAST_MODIFIED_FUTURE;
11
15
  if (lastModified > max) {
@@ -34,14 +38,20 @@ export type RemoteConfig = {
34
38
  export type RemoteConfigBase = string | HostedConfig | BackblazeConfig;
35
39
 
36
40
  export type CommonConfig = {
37
- /** The default options for the first config in a list is DEFAULT_BASE_SYNC_OPTIONS. The rest default to DEFAULT_SYNC_OPTIONS. */
38
- syncOptions?: SyncOptions;
41
+ /** 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. */
42
+ noFullSync?: boolean;
43
+ /** 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). */
44
+ readerDiskLimit?: number;
45
+ /** 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. */
46
+ validWindow: [number, number];
47
+ /** 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. */
48
+ route?: [number, number];
39
49
  };
40
50
 
41
51
  export type HostedConfig = CommonConfig & {
42
52
  type: "remote";
43
53
 
44
- // Ex: https://storage2.vidgridweb.com:4445/file/exampleaccount/examplebucket/storage/storagerouting.json
54
+ // Ex: https://99-250-124-91.querysubtest.com:5233/file/root/uniquebucketname/storage/storagerouting.json
45
55
  // NOTE: The account and bucket name are obtained from the URL.
46
56
  url: string;
47
57
 
@@ -67,7 +77,6 @@ export type BackblazeConfig = CommonConfig & {
67
77
  // NOTE: The bucket name is obtained from the URL.
68
78
  url: string;
69
79
  // Public buckets are served over plain HTTPS GETs (getURL). Private buckets are API-access only.
70
- bucketName: string;
71
80
  public?: boolean;
72
81
  // NOTE: This isn't enforced on the backblaze level, so this is just a client-side guarantee. This can change how we cache files.
73
82
  // - Backblaze does support immutability. However, apparently, once we enable it on a bucket, we can't disable it, which is really bad, as it means if our code could ever enable it and we accidentally enable it on an important bucket, we essentially just bricked that bucket. So we should never write any code that ever tries to use backblaze to make things immutable.
@@ -77,14 +86,8 @@ export type BackblazeConfig = CommonConfig & {
77
86
  };
78
87
 
79
88
 
80
- export const DEFAULT_BASE_SYNC_OPTIONS: SyncOptions = {
81
- cacheReads: true,
82
- required: true,
83
- validWindow: [0, Number.MAX_SAFE_INTEGER],
84
- };
85
- export const DEFAULT_SYNC_OPTIONS: SyncOptions = {
86
- validWindow: [0, Number.MAX_SAFE_INTEGER],
87
- };
89
+ export const FULL_VALID_WINDOW: [number, number] = [0, Number.MAX_SAFE_INTEGER];
90
+
88
91
 
89
92
 
90
93
 
@@ -94,33 +97,83 @@ export const DEFAULT_SYNC_OPTIONS: SyncOptions = {
94
97
  // bytes served by get() were most recently written".
95
98
  export type ArchiveFileInfo = { path: string; createTime: number; size: number };
96
99
 
100
+ // An in-progress background synchronization task (see ArchivesConfig.syncing)
101
+ export type SyncActivity = {
102
+ // A metadata scan is a single listing call, so it has no incremental progress - just that it's
103
+ // running and since when. A full sync knows its exact file/byte progress.
104
+ type: "metadataScan" | "fullSync";
105
+ sourceDebugName: string;
106
+ startTime: number;
107
+ doneFiles?: number;
108
+ totalFiles?: number;
109
+ doneBytes?: number;
110
+ totalBytes?: number;
111
+ };
112
+
97
113
  export type ArchivesConfig = {
98
114
  // Whether getChangesAfter is implemented (fast change polling, instead of full rescans)
99
115
  supportsChangesAfter?: boolean;
116
+ // The bucket's full routing config (ROUTING_FILE). Absent for sources that don't have one (a
117
+ // bare disk source, or a bucket that doesn't exist yet).
118
+ remoteConfig?: RemoteConfig;
119
+ // Live index totals (tombstones excluded), kept up to date in memory on every mutation and
120
+ // recomputed on load - so any drift heals on restart
121
+ index?: { fileCount: number; byteCount: number };
122
+ // The same totals broken down by which source currently holds each file's bytes (the first
123
+ // entry is the server's own disk)
124
+ indexSources?: { debugName: string; fileCount: number; byteCount: number }[];
125
+ // The server's configured readerDiskLimit, when it runs as a bounded read cache
126
+ readerDiskLimit?: number;
127
+ // Background synchronization currently in progress (empty when idle)
128
+ syncing?: SyncActivity[];
100
129
  };
101
130
 
102
- // How a synchronization source behaves (see BlobStore, which synchronizes an index + local cache
103
- // from a list of { source, options }).
104
- export type SyncOptions = {
105
- // After the source's metadata is copied into the index, also copy the file contents over (into
106
- // the cacheReads sources), preserving their modified times.
107
- copyFiles?: boolean;
108
- // Writes are NOT written to this source (by default every source receives writes).
109
- noWriteBack?: boolean;
110
- // If a read wasn't served by this source, write the data back to it (using it as a cache), and
111
- // update the index so it becomes the new source. Set for the local disk source.
112
- cacheReads?: boolean;
113
- // Ignore values with write times outside [start, end].
131
+ // A synchronization source of a BlobStore (which synchronizes an index + local cache from them)
132
+ export type ArchivesSource = {
133
+ source: IArchives;
134
+ // From the source's CommonConfig. Values with write times outside the window are ignored when
135
+ // scanning, and once its end is sufficiently past (see windowAcceptsWrites) the source stops
136
+ // receiving writes entirely - still scanned (it holds the authoritative data for its window),
137
+ // it just stops growing.
114
138
  validWindow: [number, number];
115
- // If a file isn't in the index and this source hasn't finished its initial scan, check the
116
- // source directly before declaring the file nonexistent. Set for the disk source.
117
- required?: boolean;
139
+ // From the source's CommonConfig (intersected with the owning store's own route): only keys
140
+ // routing into [start, end) are accepted from this source's scans and sent to it in
141
+ // writes/reconciliation. The routing file is exempt - config flows everywhere. Absent = all keys.
142
+ route?: [number, number];
143
+ // From the source's CommonConfig; see there.
144
+ noFullSync?: boolean;
118
145
  };
119
- export type ArchivesSource = { source: IArchives; options: SyncOptions };
146
+
147
+ // The grace covers clock uncertainty around the window edge: a write slightly past the end doesn't
148
+ // hurt, but once clearly past, the source is an archive and must stop growing.
149
+ export const WRITE_PAST_WINDOW_GRACE = 5 * 60 * 1000;
150
+
151
+ // Error marker a server includes when a freshly-stamped write reaches it outside its valid windows
152
+ // (the client resolved its target, then time crossed a window boundary before the write landed).
153
+ // Clients detect this marker and re-resolve the currently-valid source, retrying ONCE - boundaries
154
+ // are far apart, so hitting it twice in one attempt means something is actually wrong.
155
+ export const STORAGE_WRONG_VALID_WINDOW = "REMOTE_STORAGE_WRONG_VALID_WINDOW_a7c1f04e";
156
+
157
+ // Error marker a server includes when a freshly-stamped write's key routes outside the shards this
158
+ // server handles (the client's config disagrees with the server's - clients re-resolve once)
159
+ export const STORAGE_WRONG_ROUTE = "REMOTE_STORAGE_WRONG_ROUTE_c94d2e17";
160
+
161
+ export const FULL_ROUTE: [number, number] = [0, 1];
162
+
163
+ // A key containing this sentinel doesn't have a fixed shard: setVariableShard picks the (lowest
164
+ // latency, up) write shard, appends "_<value in the shard's route>" directly after the sentinel,
165
+ // and returns the materialized key. getRoute treats that suffix as a complete route override.
166
+ export const VARIABLE_SHARD = "VARIABLE_SHARD_f0234jfah08fgyhfgyssdds83nmp";
167
+ export function windowAcceptsWrites(validWindow: [number, number] | undefined): boolean {
168
+ if (!validWindow) return true;
169
+ return validWindow[1] + WRITE_PAST_WINDOW_GRACE > Date.now();
170
+ }
120
171
 
121
172
  export type ArchivesSyncSourceStatus = {
122
173
  debugName: string;
123
- options: SyncOptions;
174
+ validWindow: [number, number];
175
+ route?: [number, number];
176
+ noFullSync?: boolean;
124
177
  supportsChangesAfter: boolean;
125
178
  initialScanComplete: boolean;
126
179
  // Files seen in this source's scans / change polls so far
@@ -135,9 +188,11 @@ export type ArchivesSyncStatus = {
135
188
 
136
189
  export interface IArchives {
137
190
  getDebugName(): string;
191
+ /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc).
192
+ * Checked without writing anything. */
193
+ hasWriteAccess(): Promise<boolean>;
138
194
  get(fileName: string, config?: { range?: { start: number; end: number } }): Promise<Buffer | undefined>;
139
- /** Like get, but also returns the last-write time of the file. get just calls get2. */
140
- get2(fileName: string, config?: { range?: { start: number; end: number } }): Promise<{ data: Buffer; writeTime: number } | undefined>;
195
+ get2(fileName: string, config?: { range?: { start: number; end: number } }): Promise<{ data: Buffer; writeTime: number; size: number } | undefined>;
141
196
  /**
142
197
  * lastModified stamps the write with that last-write time instead of now. If it is OLDER than
143
198
  * the file's current last-write time the write no-ops (so delayed / synchronized writes can
@@ -8,6 +8,7 @@ export declare class ArchivesBackblaze implements IArchives {
8
8
  public?: boolean;
9
9
  immutable?: boolean;
10
10
  cacheTime?: number;
11
+ allowedOrigins?: string[];
11
12
  });
12
13
  private bucketName;
13
14
  private bucketId;
@@ -16,6 +17,7 @@ export declare class ArchivesBackblaze implements IArchives {
16
17
  private log;
17
18
  getDebugName(): string;
18
19
  private getBucketAPI;
20
+ private currentReset;
19
21
  private last503Reset;
20
22
  private apiRetryLogic;
21
23
  get(fileName: string, config?: {
@@ -33,8 +35,10 @@ export declare class ArchivesBackblaze implements IArchives {
33
35
  }): Promise<{
34
36
  data: Buffer;
35
37
  writeTime: number;
38
+ size: number;
36
39
  } | undefined>;
37
40
  getConfig(): Promise<ArchivesConfig>;
41
+ hasWriteAccess(): Promise<boolean>;
38
42
  set(fileName: string, data: Buffer, config?: {
39
43
  lastModified?: number;
40
44
  }): Promise<void>;
@@ -60,6 +64,17 @@ export declare class ArchivesBackblaze implements IArchives {
60
64
  size: number;
61
65
  }[]>;
62
66
  assertPathValid(path: string): Promise<void>;
67
+ move(config: {
68
+ path: string;
69
+ target: IArchives;
70
+ targetPath: string;
71
+ copyInstead?: boolean;
72
+ }): Promise<void>;
73
+ copy(config: {
74
+ path: string;
75
+ target: IArchives;
76
+ targetPath: string;
77
+ }): Promise<void>;
63
78
  getURL(path: string): Promise<string>;
64
79
  getDownloadAuthorization(config: {
65
80
  fileNamePrefix?: string;