sliftutils 1.1.4 → 1.2.0
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
|
@@ -296,6 +296,7 @@ declare module "sliftutils/misc/zip" {
|
|
|
296
296
|
import { MaybePromise } from "socket-function/src/types";
|
|
297
297
|
export declare class Zip {
|
|
298
298
|
static gzip(buffer: Buffer, level?: number): Promise<Buffer>;
|
|
299
|
+
static gzipSync(buffer: Buffer, level?: number): Buffer;
|
|
299
300
|
static gunzip(buffer: Buffer): MaybePromise<Buffer>;
|
|
300
301
|
static gunzipAsyncBase(buffer: Buffer): Promise<Buffer>;
|
|
301
302
|
static gunzipUntracked(buffer: Buffer): Promise<Buffer>;
|
|
@@ -1121,6 +1122,9 @@ declare module "sliftutils/storage/PrivateFileSystemStorage" {
|
|
|
1121
1122
|
|
|
1122
1123
|
declare module "sliftutils/storage/StorageObservable" {
|
|
1123
1124
|
import { IStorage, IStorageSync } from "./IStorage";
|
|
1125
|
+
export declare const storagePendingAccesses: {
|
|
1126
|
+
value: number;
|
|
1127
|
+
};
|
|
1124
1128
|
export declare class StorageSync<T> implements IStorageSync<T> {
|
|
1125
1129
|
storage: IStorage<T>;
|
|
1126
1130
|
private config?;
|
|
@@ -1160,6 +1164,13 @@ declare module "sliftutils/storage/StorageObservable" {
|
|
|
1160
1164
|
reloadKey(key: string): void;
|
|
1161
1165
|
reset(): Promise<void>;
|
|
1162
1166
|
}
|
|
1167
|
+
export declare function waitUntilNextLoad(): Promise<void>;
|
|
1168
|
+
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
declare module "sliftutils/storage/StorageObservableAsync" {
|
|
1172
|
+
/** Reruns the code until all StorageSyncs accessed have loaded their values. Not efficient,although will usually be O(values accessed), just due to how loading works (it won't be quadratic). */
|
|
1173
|
+
export declare function rerunCodeUntilAllLoaded<T>(code: () => T): Promise<T>;
|
|
1163
1174
|
|
|
1164
1175
|
}
|
|
1165
1176
|
|
package/misc/zip.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { MaybePromise } from "socket-function/src/types";
|
|
4
4
|
export declare class Zip {
|
|
5
5
|
static gzip(buffer: Buffer, level?: number): Promise<Buffer>;
|
|
6
|
+
static gzipSync(buffer: Buffer, level?: number): Buffer;
|
|
6
7
|
static gunzip(buffer: Buffer): MaybePromise<Buffer>;
|
|
7
8
|
static gunzipAsyncBase(buffer: Buffer): Promise<Buffer>;
|
|
8
9
|
static gunzipUntracked(buffer: Buffer): Promise<Buffer>;
|
package/misc/zip.ts
CHANGED
|
@@ -24,6 +24,13 @@ export class Zip {
|
|
|
24
24
|
return await doStream(new CompressionStream("gzip"), buffer);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
@measureFnc
|
|
28
|
+
public static gzipSync(buffer: Buffer, level?: number): Buffer {
|
|
29
|
+
if (isNode()) {
|
|
30
|
+
return Buffer.from(zlib.gzipSync(buffer, { level }));
|
|
31
|
+
}
|
|
32
|
+
return Buffer.from(pako.deflate(buffer));
|
|
33
|
+
}
|
|
27
34
|
public static gunzip(buffer: Buffer): MaybePromise<Buffer> {
|
|
28
35
|
// Switch to the synchronous version if the buffer is small. This is a lot faster in Node.js and clientside.
|
|
29
36
|
// - On tests of random small amounts of data, this seems to be up to 7X faster (on node). However, on non-random data, on the actual data we're using, it seems to be almost 50 times faster. So... definitely worth it...
|
package/package.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { IStorage, IStorageSync } from "./IStorage";
|
|
2
|
+
export declare const storagePendingAccesses: {
|
|
3
|
+
value: number;
|
|
4
|
+
};
|
|
2
5
|
export declare class StorageSync<T> implements IStorageSync<T> {
|
|
3
6
|
storage: IStorage<T>;
|
|
4
7
|
private config?;
|
|
@@ -38,3 +41,4 @@ export declare class StorageSync<T> implements IStorageSync<T> {
|
|
|
38
41
|
reloadKey(key: string): void;
|
|
39
42
|
reset(): Promise<void>;
|
|
40
43
|
}
|
|
44
|
+
export declare function waitUntilNextLoad(): Promise<void>;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { observable } from "mobx";
|
|
2
2
|
import { deepFreezeObject, freezeObject, isDefined } from "../misc/types";
|
|
3
3
|
import { IStorage, IStorageSync } from "./IStorage";
|
|
4
|
+
import { PromiseObj } from "socket-function/src/misc";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
export const storagePendingAccesses = { value: 0 };
|
|
7
|
+
|
|
8
|
+
// NOTE: At around 500K values (depending on their size to some degree), this will take about 2 minutes to load. But once it does it will be fast. So... keep that in mind. I recommend not exceeding 100K.
|
|
6
9
|
export class StorageSync<T> implements IStorageSync<T> {
|
|
7
10
|
cached = observable.map<string, T | undefined>(undefined, { deep: false });
|
|
8
11
|
infoCached = observable.map<string, { size: number; lastModified: number } | undefined>(undefined, { deep: false });
|
|
@@ -85,6 +88,7 @@ export class StorageSync<T> implements IStorageSync<T> {
|
|
|
85
88
|
public async getPromise(key: string): Promise<T | undefined> {
|
|
86
89
|
let value = this.cached.get(key);
|
|
87
90
|
if (value === undefined) {
|
|
91
|
+
storagePendingAccesses.value++;
|
|
88
92
|
value = await this.storage.get(key);
|
|
89
93
|
if (value !== undefined && this.cached.get(key) === undefined) {
|
|
90
94
|
if (this.config?.freeze === "shallow") {
|
|
@@ -94,15 +98,19 @@ export class StorageSync<T> implements IStorageSync<T> {
|
|
|
94
98
|
}
|
|
95
99
|
this.cached.set(key, value);
|
|
96
100
|
}
|
|
101
|
+
triggerLoad();
|
|
97
102
|
}
|
|
98
103
|
return value;
|
|
99
104
|
}
|
|
100
105
|
private pendingGetKeys: Promise<string[]> | undefined;
|
|
101
106
|
public async getKeysPromise(): Promise<string[]> {
|
|
107
|
+
if (this.loadedKeys) {
|
|
108
|
+
return Array.from(this.keys);
|
|
109
|
+
}
|
|
110
|
+
storagePendingAccesses.value++;
|
|
102
111
|
if (this.pendingGetKeys) {
|
|
103
112
|
return this.pendingGetKeys;
|
|
104
113
|
}
|
|
105
|
-
if (this.loadedKeys) return Array.from(this.keys);
|
|
106
114
|
this.loadedKeys = true;
|
|
107
115
|
this.pendingGetKeys = this.storage.getKeys();
|
|
108
116
|
void this.pendingGetKeys.finally(() => {
|
|
@@ -113,6 +121,7 @@ export class StorageSync<T> implements IStorageSync<T> {
|
|
|
113
121
|
this.keys = new Set(keys);
|
|
114
122
|
this.synced.keySeqNum++;
|
|
115
123
|
}
|
|
124
|
+
triggerLoad();
|
|
116
125
|
return Array.from(this.keys);
|
|
117
126
|
}
|
|
118
127
|
|
|
@@ -140,4 +149,20 @@ export class StorageSync<T> implements IStorageSync<T> {
|
|
|
140
149
|
this.synced.keySeqNum++;
|
|
141
150
|
await this.storage.reset();
|
|
142
151
|
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let waitUntilNextLoadWatchers: PromiseObj<void>[] = [];
|
|
155
|
+
export function waitUntilNextLoad(): Promise<void> {
|
|
156
|
+
let promise = new PromiseObj<void>();
|
|
157
|
+
waitUntilNextLoadWatchers.push(promise);
|
|
158
|
+
return promise.promise;
|
|
159
|
+
}
|
|
160
|
+
function triggerLoad() {
|
|
161
|
+
let watchers = waitUntilNextLoadWatchers;
|
|
162
|
+
waitUntilNextLoadWatchers = [];
|
|
163
|
+
void Promise.resolve().finally(() => {
|
|
164
|
+
for (let watcher of watchers) {
|
|
165
|
+
watcher.resolve();
|
|
166
|
+
}
|
|
167
|
+
});
|
|
143
168
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { storagePendingAccesses, waitUntilNextLoad } from "./StorageObservable";
|
|
2
|
+
|
|
3
|
+
/** Reruns the code until all StorageSyncs accessed have loaded their values. Not efficient,although will usually be O(values accessed), just due to how loading works (it won't be quadratic). */
|
|
4
|
+
export async function rerunCodeUntilAllLoaded<T>(code: () => T): Promise<T> {
|
|
5
|
+
while (true) {
|
|
6
|
+
let beforeAccesses = storagePendingAccesses.value;
|
|
7
|
+
try {
|
|
8
|
+
let result = await code();
|
|
9
|
+
if (storagePendingAccesses.value === beforeAccesses) {
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
} catch (error) {
|
|
13
|
+
if (storagePendingAccesses.value === beforeAccesses) {
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
console.log(`Rerunning synchronous check as loading starting while evaluating code. Function name`, code);
|
|
18
|
+
await waitUntilNextLoad();
|
|
19
|
+
}
|
|
20
|
+
}
|