querysub 0.41.0 → 0.42.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/package.json
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SocketFunctionClientHook } from "socket-function/SocketFunctionTypes";
|
|
2
|
+
import { cache, lazy } from "socket-function/src/caching";
|
|
3
|
+
import { decodeCborx, encodeCborx } from "../../misc/cloneHelpers";
|
|
4
|
+
import { sha256 } from "js-sha256";
|
|
5
|
+
import { errorToUndefined } from "../../errors";
|
|
6
|
+
import { isNode } from "typesafecss";
|
|
7
|
+
|
|
8
|
+
let getRootDirectory = lazy(async () => {
|
|
9
|
+
await navigator.storage.persist();
|
|
10
|
+
return navigator.storage.getDirectory();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const getBrowserLargeFileCache = cache((name: string) => new BrowserLargeFileCache(name));
|
|
14
|
+
|
|
15
|
+
export class BrowserLargeFileCache {
|
|
16
|
+
constructor(private name: string) { }
|
|
17
|
+
|
|
18
|
+
private getDir = lazy(async () => {
|
|
19
|
+
let root = await getRootDirectory();
|
|
20
|
+
return await root.getDirectoryHandle(this.name, { create: true });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
public async set(key: string, value: Buffer) {
|
|
24
|
+
let dir = await this.getDir();
|
|
25
|
+
let file = await dir.getFileHandle(key, { create: true });
|
|
26
|
+
let writable = await file.createWritable();
|
|
27
|
+
await writable.write(value);
|
|
28
|
+
await writable.close();
|
|
29
|
+
}
|
|
30
|
+
public async get(key: string): Promise<Buffer | undefined> {
|
|
31
|
+
let dir = await this.getDir();
|
|
32
|
+
try {
|
|
33
|
+
let file = await dir.getFileHandle(key, { create: false });
|
|
34
|
+
let readable = await file.getFile();
|
|
35
|
+
return Buffer.from(await readable.arrayBuffer());
|
|
36
|
+
} catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Cache key = [args, functionName, classGuid]
|
|
43
|
+
* - Not nodeId, as that change so frequently, so caching based on server is not usually useful.
|
|
44
|
+
* - If you want to cache based on nodeId, pass it as an unused arg.
|
|
45
|
+
*
|
|
46
|
+
* Uses a file per key, and never cleans them up. So... basically, this sucks, but, it should
|
|
47
|
+
* work for a few specific functions with large and consistent values.
|
|
48
|
+
*/
|
|
49
|
+
export const cacheCalls: SocketFunctionClientHook = async config => {
|
|
50
|
+
if (isNode()) return;
|
|
51
|
+
|
|
52
|
+
let { args, functionName, classGuid } = config.call;
|
|
53
|
+
let bucket = sha256(JSON.stringify({ functionName, classGuid }));
|
|
54
|
+
let cache = getBrowserLargeFileCache(bucket);
|
|
55
|
+
let key = sha256(encodeCborx(args));
|
|
56
|
+
let cachedValue = await cache.get(key);
|
|
57
|
+
if (cachedValue) {
|
|
58
|
+
config.overrideResult = decodeCborx(cachedValue);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
config.onResult.push(async (result) => {
|
|
62
|
+
await errorToUndefined(cache.set(key, encodeCborx(result)));
|
|
63
|
+
});
|
|
64
|
+
};
|
|
@@ -10,7 +10,7 @@ import { getSyncedController } from "../../library-components/SyncedController";
|
|
|
10
10
|
import { getBrowserUrlNode } from "../../-f-node-discovery/NodeDiscovery";
|
|
11
11
|
import { formatDateTime, formatNiceDateTime, formatNumber, formatTime } from "socket-function/src/formatting/format";
|
|
12
12
|
import { Anchor } from "../../library-components/ATag";
|
|
13
|
-
import { cache, cacheLimited, cacheShallowConfigArgEqual } from "socket-function/src/caching";
|
|
13
|
+
import { cache, cacheLimited, cacheShallowConfigArgEqual, lazy } from "socket-function/src/caching";
|
|
14
14
|
import { InputLabel, InputLabelURL } from "../../library-components/InputLabel";
|
|
15
15
|
import { DropdownSelector } from "../../library-components/DropdownSelector";
|
|
16
16
|
import { Table, TableType } from "../../5-diagnostics/Table";
|
|
@@ -30,6 +30,7 @@ import { getNodeIdLocation } from "socket-function/src/nodeCache";
|
|
|
30
30
|
import { decodeNodeId, encodeNodeId, getMachineId } from "../../-a-auth/certs";
|
|
31
31
|
import { Button } from "../../library-components/Button";
|
|
32
32
|
import { TimeRangeSelector } from "../../library-components/TimeRangeSelector";
|
|
33
|
+
import { BrowserLargeFileCache, cacheCalls } from "./BrowserLargeFileCache";
|
|
33
34
|
|
|
34
35
|
// TODO: Realtime log mode, by reading from the previous length forward, to add buffers
|
|
35
36
|
// to what we already read.
|
|
@@ -550,10 +551,15 @@ export const DiskLoggerController = SocketFunction.register(
|
|
|
550
551
|
new DiskLoggerControllerBase(),
|
|
551
552
|
() => ({
|
|
552
553
|
getRemoteLogFiles: {},
|
|
553
|
-
getRemoteLogBuffer: {
|
|
554
|
+
getRemoteLogBuffer: {
|
|
555
|
+
compress: true,
|
|
556
|
+
clientHooks: [cacheCalls]
|
|
557
|
+
},
|
|
554
558
|
|
|
555
559
|
getLogFiles: {},
|
|
556
|
-
getLogBuffer: {
|
|
560
|
+
getLogBuffer: {
|
|
561
|
+
compress: true,
|
|
562
|
+
},
|
|
557
563
|
}),
|
|
558
564
|
() => ({
|
|
559
565
|
hooks: [assertIsManagementUser],
|