sliftutils 1.7.51 → 1.7.52

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.
package/index.d.ts CHANGED
@@ -858,7 +858,7 @@ declare module "sliftutils/render-utils/observer" {
858
858
  declare module "sliftutils/storage/ArchivesDisk" {
859
859
  /// <reference types="node" />
860
860
  /// <reference types="node" />
861
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, SetConfig } from "./IArchives";
861
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, SetConfig } from "./IArchives";
862
862
  export declare class ArchivesDisk implements IArchives {
863
863
  private folder;
864
864
  constructor(folder: string);
@@ -879,18 +879,8 @@ declare module "sliftutils/storage/ArchivesDisk" {
879
879
  private filePath;
880
880
  set(key: string, data: Buffer, config?: SetConfig): Promise<string>;
881
881
  del(key: string): Promise<void>;
882
- get(key: string, config?: {
883
- range?: {
884
- start: number;
885
- end: number;
886
- };
887
- }): Promise<Buffer | undefined>;
888
- get2(key: string, config?: {
889
- range?: {
890
- start: number;
891
- end: number;
892
- };
893
- }): Promise<{
882
+ get(key: string, config?: GetConfig): Promise<Buffer | undefined>;
883
+ get2(key: string, config?: GetConfig): Promise<{
894
884
  data: Buffer;
895
885
  writeTime: number;
896
886
  size: number;
@@ -2149,6 +2139,14 @@ declare module "sliftutils/storage/IArchives" {
2149
2139
  allowedOrigins?: string[];
2150
2140
  };
2151
2141
  export declare const FULL_VALID_WINDOW: [number, number];
2142
+ export type GetConfig = {
2143
+ range?: {
2144
+ start: number;
2145
+ end: number;
2146
+ };
2147
+ /** Read ONLY from the primary source - the one writes would target - and throw when it cannot serve the read, instead of falling back across the redundant sources. */
2148
+ noFallbacks?: boolean;
2149
+ };
2152
2150
  export type ChangesAfterConfig = {
2153
2151
  time: number;
2154
2152
  /** Only keys routing into one of these [start, end) ranges. Only scanning passes this - it lets a store syncing a partial shard ask for just its slice. */
@@ -2235,18 +2233,16 @@ declare module "sliftutils/storage/IArchives" {
2235
2233
  getDebugName(): string;
2236
2234
  /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc). Checked without writing anything. */
2237
2235
  hasWriteAccess(): Promise<boolean>;
2238
- get(fileName: string, config?: {
2239
- range?: {
2240
- start: number;
2241
- end: number;
2242
- };
2243
- }): Promise<Buffer | undefined>;
2244
- get2(fileName: string, config?: {
2245
- range?: {
2246
- start: number;
2247
- end: number;
2248
- };
2249
- }): Promise<{
2236
+ /**
2237
+ * Reads automatically fall back across the redundant sources unless config.noFallbacks is set.
2238
+ * A fallback copy can lag the write target, so a caller reading state in order to mutate it
2239
+ * (e.g. x++), where acting on previous state would cause big issues, should pass noFallbacks -
2240
+ * and try/catch the read, handling the catch case (the primary being down now throws instead
2241
+ * of degrading to a stale copy).
2242
+ */
2243
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
2244
+ /** See get for the fallback semantics (and when to pass noFallbacks). */
2245
+ get2(fileName: string, config?: GetConfig): Promise<{
2250
2246
  data: Buffer;
2251
2247
  writeTime: number;
2252
2248
  size: number;
@@ -2555,7 +2551,7 @@ declare module "sliftutils/storage/TransactionStorage" {
2555
2551
  declare module "sliftutils/storage/backblaze" {
2556
2552
  /// <reference types="node" />
2557
2553
  /// <reference types="node" />
2558
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, SetConfig } from "./IArchives";
2554
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, SetConfig } from "./IArchives";
2559
2555
  export declare class ArchivesBackblaze implements IArchives {
2560
2556
  private config;
2561
2557
  constructor(config: {
@@ -2575,19 +2571,8 @@ declare module "sliftutils/storage/backblaze" {
2575
2571
  private currentReset;
2576
2572
  private last503Reset;
2577
2573
  private apiRetryLogic;
2578
- get(fileName: string, config?: {
2579
- range?: {
2580
- start: number;
2581
- end: number;
2582
- };
2583
- retryCount?: number;
2584
- }): Promise<Buffer | undefined>;
2585
- get2(fileName: string, config?: {
2586
- range?: {
2587
- start: number;
2588
- end: number;
2589
- };
2590
- }): Promise<{
2574
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
2575
+ get2(fileName: string, config?: GetConfig): Promise<{
2591
2576
  data: Buffer;
2592
2577
  writeTime: number;
2593
2578
  size: number;
@@ -2870,7 +2855,7 @@ declare module "sliftutils/storage/remoteFileStorage" {
2870
2855
  declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2871
2856
  /// <reference types="node" />
2872
2857
  /// <reference types="node" />
2873
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, SetConfig } from "../IArchives";
2858
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, GetConfig, SetConfig } from "../IArchives";
2874
2859
  export type ArchivesRemoteConfig = {
2875
2860
  url: string;
2876
2861
  waitForAccess?: boolean;
@@ -2909,18 +2894,8 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2909
2894
  hasWriteAccess(): Promise<boolean>;
2910
2895
  private registerAccessRequest;
2911
2896
  private call;
2912
- get(fileName: string, config?: {
2913
- range?: {
2914
- start: number;
2915
- end: number;
2916
- };
2917
- }): Promise<Buffer | undefined>;
2918
- get2(fileName: string, config?: {
2919
- range?: {
2920
- start: number;
2921
- end: number;
2922
- };
2923
- }): Promise<{
2897
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
2898
+ get2(fileName: string, config?: GetConfig): Promise<{
2924
2899
  data: Buffer;
2925
2900
  writeTime: number;
2926
2901
  size: number;
@@ -2955,24 +2930,14 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2955
2930
  declare module "sliftutils/storage/remoteStorage/ArchivesUrl" {
2956
2931
  /// <reference types="node" />
2957
2932
  /// <reference types="node" />
2958
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig } from "../IArchives";
2933
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig } from "../IArchives";
2959
2934
  export declare class ArchivesUrl implements IArchives {
2960
2935
  private base;
2961
2936
  constructor(base: string);
2962
2937
  getDebugName(): string;
2963
2938
  private readOnlyError;
2964
- get(fileName: string, config?: {
2965
- range?: {
2966
- start: number;
2967
- end: number;
2968
- };
2969
- }): Promise<Buffer | undefined>;
2970
- get2(fileName: string, config?: {
2971
- range?: {
2972
- start: number;
2973
- end: number;
2974
- };
2975
- }): Promise<{
2939
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
2940
+ get2(fileName: string, config?: GetConfig): Promise<{
2976
2941
  data: Buffer;
2977
2942
  writeTime: number;
2978
2943
  size: number;
@@ -3013,7 +2978,7 @@ declare module "sliftutils/storage/remoteStorage/accessPage" {
3013
2978
  declare module "sliftutils/storage/remoteStorage/blobStore" {
3014
2979
  /// <reference types="node" />
3015
2980
  /// <reference types="node" />
3016
- import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, ChangesAfterConfig, SyncActivity } from "../IArchives";
2981
+ import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, ChangesAfterConfig, GetConfig, SyncActivity } from "../IArchives";
3017
2982
  export declare const DEFAULT_FAST_WRITE_DELAY: number;
3018
2983
  export declare const WINDOW_END_FLUSH_MARGIN: number;
3019
2984
  export type WriteConfig = {
@@ -3022,18 +2987,8 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3022
2987
  lastModified?: number;
3023
2988
  };
3024
2989
  export type IBucketStore = {
3025
- get(fileName: string, config?: {
3026
- range?: {
3027
- start: number;
3028
- end: number;
3029
- };
3030
- }): Promise<Buffer | undefined>;
3031
- get2(fileName: string, config?: {
3032
- range?: {
3033
- start: number;
3034
- end: number;
3035
- };
3036
- }): Promise<{
2990
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
2991
+ get2(fileName: string, config?: GetConfig): Promise<{
3037
2992
  data: Buffer;
3038
2993
  writeTime: number;
3039
2994
  size: number;
@@ -3169,18 +3124,8 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3169
3124
  private waitForRequiredScans;
3170
3125
  private checkMissingKey;
3171
3126
  private getIndexEntry;
3172
- get(key: string, config?: {
3173
- range?: {
3174
- start: number;
3175
- end: number;
3176
- };
3177
- }): Promise<Buffer | undefined>;
3178
- get2(key: string, config?: {
3179
- range?: {
3180
- start: number;
3181
- end: number;
3182
- };
3183
- }): Promise<{
3127
+ get(key: string, config?: GetConfig): Promise<Buffer | undefined>;
3128
+ get2(key: string, config?: GetConfig): Promise<{
3184
3129
  data: Buffer;
3185
3130
  writeTime: number;
3186
3131
  size: number;
@@ -3221,7 +3166,7 @@ declare module "sliftutils/storage/remoteStorage/cliArgs" {
3221
3166
  declare module "sliftutils/storage/remoteStorage/createArchives" {
3222
3167
  /// <reference types="node" />
3223
3168
  /// <reference types="node" />
3224
- import { IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, SetConfig } from "../IArchives";
3169
+ import { IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, GetConfig, SetConfig } from "../IArchives";
3225
3170
  import { ServerBucketInfo, ActiveBucketInfo } from "./storageServerState";
3226
3171
  /** The address, port, account, and bucket name a bucket routing URL addresses. Throws when the URL isn't a hosted bucket routing URL (https://host:port/file/<account>/<bucketName>/storage/storagerouting.json). */
3227
3172
  export { parseHostedUrl, parseBackblazeUrl, getBucketBaseUrl } from "./remoteConfig";
@@ -3268,18 +3213,8 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3268
3213
  machineId: string;
3269
3214
  ip: string;
3270
3215
  } | undefined>;
3271
- get(fileName: string, config?: {
3272
- range?: {
3273
- start: number;
3274
- end: number;
3275
- };
3276
- }): Promise<Buffer | undefined>;
3277
- get2(fileName: string, config?: {
3278
- range?: {
3279
- start: number;
3280
- end: number;
3281
- };
3282
- }): Promise<{
3216
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
3217
+ get2(fileName: string, config?: GetConfig): Promise<{
3283
3218
  data: Buffer;
3284
3219
  writeTime: number;
3285
3220
  size: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.51",
3
+ "version": "1.7.52",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, SetConfig } from "./IArchives";
3
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, SetConfig } from "./IArchives";
4
4
  export declare class ArchivesDisk implements IArchives {
5
5
  private folder;
6
6
  constructor(folder: string);
@@ -21,18 +21,8 @@ export declare class ArchivesDisk implements IArchives {
21
21
  private filePath;
22
22
  set(key: string, data: Buffer, config?: SetConfig): Promise<string>;
23
23
  del(key: string): Promise<void>;
24
- get(key: string, config?: {
25
- range?: {
26
- start: number;
27
- end: number;
28
- };
29
- }): Promise<Buffer | undefined>;
30
- get2(key: string, config?: {
31
- range?: {
32
- start: number;
33
- end: number;
34
- };
35
- }): Promise<{
24
+ get(key: string, config?: GetConfig): Promise<Buffer | undefined>;
25
+ get2(key: string, config?: GetConfig): Promise<{
36
26
  data: Buffer;
37
27
  writeTime: number;
38
28
  size: number;
@@ -3,7 +3,7 @@ import path from "path";
3
3
  import { lazy } from "socket-function/src/caching";
4
4
  import { runInfinitePoll } from "socket-function/src/batching";
5
5
  import { sort, binarySearchBasic } from "socket-function/src/misc";
6
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, SetConfig, assertValidLastModified } from "./IArchives";
6
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, SetConfig, assertValidLastModified } from "./IArchives";
7
7
  import { filterChanges } from "./remoteStorage/remoteConfig";
8
8
 
9
9
  // The base file-system IArchives: storage is one-to-one with the file system, every key is exactly one real file under <folder>/files, so the file system itself is the index. File handles are cached and reused, and closed once idle (see FileHandleCache). All operations on a file run in serial, so they can't collide with each other or with handle closing. Used as the disk synchronization source of BlobStore (see remoteStorage/blobStore.ts).
@@ -180,12 +180,12 @@ export class ArchivesDisk implements IArchives {
180
180
  });
181
181
  }
182
182
 
183
- public async get(key: string, config?: { range?: { start: number; end: number } }): Promise<Buffer | undefined> {
183
+ public async get(key: string, config?: GetConfig): Promise<Buffer | undefined> {
184
184
  let result = await this.get2(key, config);
185
185
  return result && result.data || undefined;
186
186
  }
187
187
 
188
- public async get2(key: string, config?: { range?: { start: number; end: number } }): Promise<{ data: Buffer; writeTime: number; size: number } | undefined> {
188
+ public async get2(key: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number } | undefined> {
189
189
  await this.init();
190
190
  let range = config?.range;
191
191
  let filePath = this.filePath(key);
@@ -48,6 +48,14 @@ export type BackblazeConfig = CommonConfig & {
48
48
  allowedOrigins?: string[];
49
49
  };
50
50
  export declare const FULL_VALID_WINDOW: [number, number];
51
+ export type GetConfig = {
52
+ range?: {
53
+ start: number;
54
+ end: number;
55
+ };
56
+ /** Read ONLY from the primary source - the one writes would target - and throw when it cannot serve the read, instead of falling back across the redundant sources. */
57
+ noFallbacks?: boolean;
58
+ };
51
59
  export type ChangesAfterConfig = {
52
60
  time: number;
53
61
  /** Only keys routing into one of these [start, end) ranges. Only scanning passes this - it lets a store syncing a partial shard ask for just its slice. */
@@ -134,18 +142,16 @@ export interface IArchives {
134
142
  getDebugName(): string;
135
143
  /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc). Checked without writing anything. */
136
144
  hasWriteAccess(): Promise<boolean>;
137
- get(fileName: string, config?: {
138
- range?: {
139
- start: number;
140
- end: number;
141
- };
142
- }): Promise<Buffer | undefined>;
143
- get2(fileName: string, config?: {
144
- range?: {
145
- start: number;
146
- end: number;
147
- };
148
- }): Promise<{
145
+ /**
146
+ * Reads automatically fall back across the redundant sources unless config.noFallbacks is set.
147
+ * A fallback copy can lag the write target, so a caller reading state in order to mutate it
148
+ * (e.g. x++), where acting on previous state would cause big issues, should pass noFallbacks -
149
+ * and try/catch the read, handling the catch case (the primary being down now throws instead
150
+ * of degrading to a stale copy).
151
+ */
152
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
153
+ /** See get for the fallback semantics (and when to pass noFallbacks). */
154
+ get2(fileName: string, config?: GetConfig): Promise<{
149
155
  data: Buffer;
150
156
  writeTime: number;
151
157
  size: number;
@@ -86,6 +86,12 @@ export const FULL_VALID_WINDOW: [number, number] = [0, Number.MAX_SAFE_INTEGER];
86
86
 
87
87
 
88
88
 
89
+ export type GetConfig = {
90
+ range?: { start: number; end: number };
91
+ /** Read ONLY from the primary source - the one writes would target - and throw when it cannot serve the read, instead of falling back across the redundant sources. */
92
+ noFallbacks?: boolean;
93
+ };
94
+
89
95
  export type ChangesAfterConfig = {
90
96
  time: number;
91
97
  /** Only keys routing into one of these [start, end) ranges. Only scanning passes this - it lets a store syncing a partial shard ask for just its slice. */
@@ -231,8 +237,16 @@ export interface IArchives {
231
237
  getDebugName(): string;
232
238
  /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc). Checked without writing anything. */
233
239
  hasWriteAccess(): Promise<boolean>;
234
- get(fileName: string, config?: { range?: { start: number; end: number } }): Promise<Buffer | undefined>;
235
- get2(fileName: string, config?: { range?: { start: number; end: number } }): Promise<{ data: Buffer; writeTime: number; size: number } | undefined>;
240
+ /**
241
+ * Reads automatically fall back across the redundant sources unless config.noFallbacks is set.
242
+ * A fallback copy can lag the write target, so a caller reading state in order to mutate it
243
+ * (e.g. x++), where acting on previous state would cause big issues, should pass noFallbacks -
244
+ * and try/catch the read, handling the catch case (the primary being down now throws instead
245
+ * of degrading to a stale copy).
246
+ */
247
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
248
+ /** See get for the fallback semantics (and when to pass noFallbacks). */
249
+ get2(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number } | undefined>;
236
250
  /**
237
251
  * lastModified stamps the write with that last-write time instead of now. If it is OLDER than
238
252
  * the file's current last-write time the write no-ops (so delayed / synchronized writes can
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, SetConfig } from "./IArchives";
3
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, SetConfig } from "./IArchives";
4
4
  export declare class ArchivesBackblaze implements IArchives {
5
5
  private config;
6
6
  constructor(config: {
@@ -20,19 +20,8 @@ export declare class ArchivesBackblaze implements IArchives {
20
20
  private currentReset;
21
21
  private last503Reset;
22
22
  private apiRetryLogic;
23
- get(fileName: string, config?: {
24
- range?: {
25
- start: number;
26
- end: number;
27
- };
28
- retryCount?: number;
29
- }): Promise<Buffer | undefined>;
30
- get2(fileName: string, config?: {
31
- range?: {
32
- start: number;
33
- end: number;
34
- };
35
- }): Promise<{
23
+ get(fileName: string, config?: GetConfig): Promise<Buffer | undefined>;
24
+ get2(fileName: string, config?: GetConfig): Promise<{
36
25
  data: Buffer;
37
26
  writeTime: number;
38
27
  size: number;
@@ -9,7 +9,7 @@ import debugbreak from "debugbreak";
9
9
  import dns from "dns";
10
10
  import { getSecret } from "../misc/getSecret";
11
11
  import { httpsRequest, HttpsResponseInfo } from "socket-function/src/https";
12
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, SetConfig, assertValidLastModified, IMMUTABLE_CACHE_TIME } from "./IArchives";
12
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, SetConfig, assertValidLastModified, IMMUTABLE_CACHE_TIME } from "./IArchives";
13
13
  import { filterChanges } from "./remoteStorage/remoteConfig";
14
14
 
15
15
  type BackblazeCreds = {
@@ -622,11 +622,11 @@ export class ArchivesBackblaze implements IArchives {
622
622
  }
623
623
  }
624
624
 
625
- public async get(fileName: string, config?: { range?: { start: number; end: number; }; retryCount?: number }): Promise<Buffer | undefined> {
625
+ public async get(fileName: string, config?: GetConfig): Promise<Buffer | undefined> {
626
626
  let result = await this.get2(fileName, config);
627
627
  return result && result.data || undefined;
628
628
  }
629
- public async get2(fileName: string, config?: { range?: { start: number; end: number; } }): Promise<{ data: Buffer; writeTime: number; size: number } | undefined> {
629
+ public async get2(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number } | undefined> {
630
630
  let downloading = true;
631
631
  try {
632
632
  let time = Date.now();