@global-cache/core 0.2.3
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/README.md +5 -0
- package/dist/client/api.d.ts +21 -0
- package/dist/client/api.d.ts.map +1 -0
- package/dist/client/api.js +43 -0
- package/dist/client/api.js.map +1 -0
- package/dist/client/index.d.ts +27 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +135 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/types.d.ts +12 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +3 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/utils/http-error.d.ts +3 -0
- package/dist/client/utils/http-error.d.ts.map +1 -0
- package/dist/client/utils/http-error.js +13 -0
- package/dist/client/utils/http-error.js.map +1 -0
- package/dist/client/utils/http-json.d.ts +14 -0
- package/dist/client/utils/http-json.d.ts.map +1 -0
- package/dist/client/utils/http-json.js +29 -0
- package/dist/client/utils/http-json.js.map +1 -0
- package/dist/client/utils/http-query.d.ts +9 -0
- package/dist/client/utils/http-query.d.ts.map +1 -0
- package/dist/client/utils/http-query.js +25 -0
- package/dist/client/utils/http-query.js.map +1 -0
- package/dist/client/utils/preview-value.d.ts +2 -0
- package/dist/client/utils/preview-value.d.ts.map +1 -0
- package/dist/client/utils/preview-value.js +16 -0
- package/dist/client/utils/preview-value.js.map +1 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/server/config.d.ts +15 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +18 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/error.d.ts +3 -0
- package/dist/server/error.d.ts.map +1 -0
- package/dist/server/error.js +9 -0
- package/dist/server/error.js.map +1 -0
- package/dist/server/getter.d.ts +35 -0
- package/dist/server/getter.d.ts.map +1 -0
- package/dist/server/getter.js +109 -0
- package/dist/server/getter.js.map +1 -0
- package/dist/server/index.d.ts +14 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +73 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/clear.d.ts +2 -0
- package/dist/server/routes/clear.d.ts.map +1 -0
- package/dist/server/routes/clear.js +15 -0
- package/dist/server/routes/clear.js.map +1 -0
- package/dist/server/routes/get-stale-list.d.ts +7 -0
- package/dist/server/routes/get-stale-list.d.ts.map +1 -0
- package/dist/server/routes/get-stale-list.js +20 -0
- package/dist/server/routes/get-stale-list.js.map +1 -0
- package/dist/server/routes/get-stale.d.ts +7 -0
- package/dist/server/routes/get-stale.d.ts.map +1 -0
- package/dist/server/routes/get-stale.js +20 -0
- package/dist/server/routes/get-stale.js.map +1 -0
- package/dist/server/routes/get.d.ts +9 -0
- package/dist/server/routes/get.d.ts.map +1 -0
- package/dist/server/routes/get.js +23 -0
- package/dist/server/routes/get.js.map +1 -0
- package/dist/server/routes/set.d.ts +9 -0
- package/dist/server/routes/set.d.ts.map +1 -0
- package/dist/server/routes/set.js +18 -0
- package/dist/server/routes/set.js.map +1 -0
- package/dist/server/setter.d.ts +12 -0
- package/dist/server/setter.d.ts.map +1 -0
- package/dist/server/setter.js +37 -0
- package/dist/server/setter.js.map +1 -0
- package/dist/server/storage/index.d.ts +6 -0
- package/dist/server/storage/index.d.ts.map +1 -0
- package/dist/server/storage/index.js +14 -0
- package/dist/server/storage/index.js.map +1 -0
- package/dist/server/storage/multi-instance/index.d.ts +9 -0
- package/dist/server/storage/multi-instance/index.d.ts.map +1 -0
- package/dist/server/storage/multi-instance/index.js +10 -0
- package/dist/server/storage/multi-instance/index.js.map +1 -0
- package/dist/server/storage/single-instance/fs.d.ts +16 -0
- package/dist/server/storage/single-instance/fs.d.ts.map +1 -0
- package/dist/server/storage/single-instance/fs.js +59 -0
- package/dist/server/storage/single-instance/fs.js.map +1 -0
- package/dist/server/storage/single-instance/index.d.ts +11 -0
- package/dist/server/storage/single-instance/index.d.ts.map +1 -0
- package/dist/server/storage/single-instance/index.js +33 -0
- package/dist/server/storage/single-instance/index.js.map +1 -0
- package/dist/server/storage/single-instance/memory.d.ts +15 -0
- package/dist/server/storage/single-instance/memory.d.ts.map +1 -0
- package/dist/server/storage/single-instance/memory.js +41 -0
- package/dist/server/storage/single-instance/memory.js.map +1 -0
- package/dist/server/storage/types.d.ts +14 -0
- package/dist/server/storage/types.d.ts.map +1 -0
- package/dist/server/storage/types.js +3 -0
- package/dist/server/storage/types.js.map +1 -0
- package/dist/server/utils/express.d.ts +8 -0
- package/dist/server/utils/express.d.ts.map +1 -0
- package/dist/server/utils/express.js +15 -0
- package/dist/server/utils/express.js.map +1 -0
- package/dist/shared/debug.d.ts +4 -0
- package/dist/shared/debug.d.ts.map +1 -0
- package/dist/shared/debug.js +14 -0
- package/dist/shared/debug.js.map +1 -0
- package/dist/shared/logger.d.ts +2 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +5 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/sig.d.ts +23 -0
- package/dist/shared/sig.d.ts.map +1 -0
- package/dist/shared/sig.js +53 -0
- package/dist/shared/sig.js.map +1 -0
- package/dist/shared/ttl.d.ts +8 -0
- package/dist/shared/ttl.d.ts.map +1 -0
- package/dist/shared/ttl.js +25 -0
- package/dist/shared/ttl.js.map +1 -0
- package/dist/shared/utils/object.d.ts +2 -0
- package/dist/shared/utils/object.d.ts.map +1 -0
- package/dist/shared/utils/object.js +9 -0
- package/dist/shared/utils/object.js.map +1 -0
- package/dist/shared/value-info.d.ts +18 -0
- package/dist/shared/value-info.d.ts.map +1 -0
- package/dist/shared/value-info.js +32 -0
- package/dist/shared/value-info.js.map +1 -0
- package/package.json +41 -0
- package/src/client/api.ts +51 -0
- package/src/client/index.ts +137 -0
- package/src/client/types.ts +14 -0
- package/src/client/utils/http-error.ts +8 -0
- package/src/client/utils/http-json.ts +32 -0
- package/src/client/utils/http-query.ts +24 -0
- package/src/client/utils/preview-value.ts +10 -0
- package/src/config.ts +79 -0
- package/src/index.ts +2 -0
- package/src/server/config.ts +29 -0
- package/src/server/error.ts +7 -0
- package/src/server/getter.ts +138 -0
- package/src/server/index.ts +81 -0
- package/src/server/routes/clear.ts +15 -0
- package/src/server/routes/get-stale-list.ts +27 -0
- package/src/server/routes/get-stale.ts +27 -0
- package/src/server/routes/get.ts +31 -0
- package/src/server/routes/set.ts +27 -0
- package/src/server/setter.ts +35 -0
- package/src/server/storage/index.ts +16 -0
- package/src/server/storage/multi-instance/index.ts +7 -0
- package/src/server/storage/single-instance/fs.ts +64 -0
- package/src/server/storage/single-instance/index.ts +32 -0
- package/src/server/storage/single-instance/memory.ts +43 -0
- package/src/server/storage/types.ts +13 -0
- package/src/server/utils/express.ts +14 -0
- package/src/shared/debug.ts +7 -0
- package/src/shared/logger.ts +1 -0
- package/src/shared/sig.ts +84 -0
- package/src/shared/ttl.ts +19 -0
- package/src/shared/utils/object.ts +4 -0
- package/src/shared/value-info.ts +40 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FilesystemStorage = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* File system storage implementation.
|
|
9
|
+
*/
|
|
10
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
class FilesystemStorage {
|
|
13
|
+
constructor(basePath) {
|
|
14
|
+
this.basePath = basePath;
|
|
15
|
+
}
|
|
16
|
+
async load(key) {
|
|
17
|
+
const filePath = this.getFilePath(key);
|
|
18
|
+
const fileExists = node_fs_1.default.existsSync(filePath);
|
|
19
|
+
if (!fileExists)
|
|
20
|
+
return;
|
|
21
|
+
const content = await node_fs_1.default.promises.readFile(filePath, 'utf8');
|
|
22
|
+
// todo: json parse safe (with warning)
|
|
23
|
+
const storedInfo = JSON.parse(content);
|
|
24
|
+
return {
|
|
25
|
+
key,
|
|
26
|
+
state: 'computed',
|
|
27
|
+
persistent: true,
|
|
28
|
+
computedAt: storedInfo.computedAt,
|
|
29
|
+
value: storedInfo.value,
|
|
30
|
+
sig: storedInfo.sig,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async save({ key, value, sig }) {
|
|
34
|
+
const computedAt = Date.now();
|
|
35
|
+
const storedInfo = { computedAt, sig, value };
|
|
36
|
+
const content = JSON.stringify(storedInfo, null, 2);
|
|
37
|
+
const filePath = this.getFilePath(key);
|
|
38
|
+
await node_fs_1.default.promises.mkdir(node_path_1.default.dirname(filePath), { recursive: true });
|
|
39
|
+
await node_fs_1.default.promises.writeFile(filePath, content, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
async delete(key) {
|
|
42
|
+
const filePath = this.getFilePath(key);
|
|
43
|
+
if (node_fs_1.default.existsSync(filePath)) {
|
|
44
|
+
await node_fs_1.default.promises.rm(filePath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
getFilePath(key) {
|
|
48
|
+
return node_path_1.default.join(this.basePath, `${filenamify(key)}.json`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.FilesystemStorage = FilesystemStorage;
|
|
52
|
+
// eslint-disable-next-line no-control-regex
|
|
53
|
+
const filenameReservedRegex = /[<>:"/\\|?*\u0000-\u001F]/g;
|
|
54
|
+
function filenamify(s, replacement = '-') {
|
|
55
|
+
return s
|
|
56
|
+
.replace(filenameReservedRegex, replacement) // prettier-ignore
|
|
57
|
+
.replace(/\s+/g, replacement); // additionally replace spaces
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../../src/server/storage/single-instance/fs.ts"],"names":[],"mappings":";;;;;;AAAA;;GAEG;AACH,sDAAyB;AACzB,0DAA6B;AAU7B,MAAa,iBAAiB;IAC5B,YAAoB,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAExC,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,iBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,MAAM,OAAO,GAAG,MAAM,iBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7D,uCAAuC;QACvC,MAAM,UAAU,GAAe,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnD,OAAO;YACL,GAAG;YACH,KAAK,EAAE,UAAU;YACjB,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,GAAG,EAAE,UAAU,CAAC,GAAG;SACpB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAoB;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAe,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,iBAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,iBAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,iBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,iBAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,GAAW;QAC7B,OAAO,mBAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;CACF;AAzCD,8CAyCC;AAED,4CAA4C;AAC5C,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAC3D,SAAS,UAAU,CAAC,CAAS,EAAE,WAAW,GAAG,GAAG;IAC9C,OAAO,CAAC;SACL,OAAO,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC,kBAAkB;SAC9D,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,8BAA8B;AACjE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-instance mode of Global Storage Server.
|
|
3
|
+
* - non-persistent values are stored in memory
|
|
4
|
+
* - presistent values are stored on file system
|
|
5
|
+
* - compute-listeners are implemented via memory
|
|
6
|
+
*/
|
|
7
|
+
import { MemoryStorage } from './memory';
|
|
8
|
+
import { FilesystemStorage } from './fs';
|
|
9
|
+
export declare function getMemoryStorage(runId: string): MemoryStorage;
|
|
10
|
+
export declare function getFsStorage(basePath: string): FilesystemStorage;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/storage/single-instance/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAQzC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,iBAO7C;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,qBAO5C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMemoryStorage = getMemoryStorage;
|
|
4
|
+
exports.getFsStorage = getFsStorage;
|
|
5
|
+
/**
|
|
6
|
+
* Single-instance mode of Global Storage Server.
|
|
7
|
+
* - non-persistent values are stored in memory
|
|
8
|
+
* - presistent values are stored on file system
|
|
9
|
+
* - compute-listeners are implemented via memory
|
|
10
|
+
*/
|
|
11
|
+
const memory_1 = require("./memory");
|
|
12
|
+
const fs_1 = require("./fs");
|
|
13
|
+
// In-memory storage of test runs with values
|
|
14
|
+
const memoryStorageMap = new Map();
|
|
15
|
+
const fsStorageMap = new Map();
|
|
16
|
+
// todo: cleanup old testRuns from the map
|
|
17
|
+
function getMemoryStorage(runId) {
|
|
18
|
+
let storage = memoryStorageMap.get(runId);
|
|
19
|
+
if (!storage) {
|
|
20
|
+
storage = new memory_1.MemoryStorage();
|
|
21
|
+
memoryStorageMap.set(runId, storage);
|
|
22
|
+
}
|
|
23
|
+
return storage;
|
|
24
|
+
}
|
|
25
|
+
function getFsStorage(basePath) {
|
|
26
|
+
let storage = fsStorageMap.get(basePath);
|
|
27
|
+
if (!storage) {
|
|
28
|
+
storage = new fs_1.FilesystemStorage(basePath);
|
|
29
|
+
fsStorageMap.set(basePath, storage);
|
|
30
|
+
}
|
|
31
|
+
return storage;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/storage/single-instance/index.ts"],"names":[],"mappings":";;AAeA,4CAOC;AAED,oCAOC;AA/BD;;;;;GAKG;AACH,qCAAyC;AACzC,6BAAyC;AAEzC,6CAA6C;AAC7C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAC;AAE1D,0CAA0C;AAE1C,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,IAAI,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,sBAAa,EAAE,CAAC;QAC9B,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,YAAY,CAAC,QAAgB;IAC3C,IAAI,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,sBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC1C,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TestRunValueInfo } from '../../../shared/value-info';
|
|
2
|
+
import { ITestRunStorage } from '../types';
|
|
3
|
+
export declare class MemoryStorage implements ITestRunStorage {
|
|
4
|
+
private values;
|
|
5
|
+
private listeners;
|
|
6
|
+
load(key: string): Promise<TestRunValueInfo | undefined>;
|
|
7
|
+
loadByPrefix(prefix: string): Promise<TestRunValueInfo[]>;
|
|
8
|
+
save(valueInfo: TestRunValueInfo, { notify }?: {
|
|
9
|
+
notify?: boolean | undefined;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
clear(): Promise<void>;
|
|
12
|
+
wait(key: string): Promise<TestRunValueInfo>;
|
|
13
|
+
private notify;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/server/storage/single-instance/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAI3C,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,SAAS,CAA2C;IAEtD,IAAI,CAAC,GAAG,EAAE,MAAM;IAIhB,YAAY,CAAC,MAAM,EAAE,MAAM;IAI3B,IAAI,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,MAAc,EAAE;;KAAK;IAKzD,KAAK;IAIL,IAAI,CAAC,GAAG,EAAE,MAAM;IAQtB,OAAO,CAAC,MAAM;CAQf"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryStorage = void 0;
|
|
4
|
+
class MemoryStorage {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.values = new Map();
|
|
7
|
+
this.listeners = new Map();
|
|
8
|
+
}
|
|
9
|
+
async load(key) {
|
|
10
|
+
return this.values.get(key);
|
|
11
|
+
}
|
|
12
|
+
async loadByPrefix(prefix) {
|
|
13
|
+
return [...this.values.values()].filter((valueInfo) => valueInfo.key.startsWith(prefix));
|
|
14
|
+
}
|
|
15
|
+
async save(valueInfo, { notify = false } = {}) {
|
|
16
|
+
this.values.set(valueInfo.key, valueInfo);
|
|
17
|
+
if (notify)
|
|
18
|
+
this.notify(valueInfo);
|
|
19
|
+
}
|
|
20
|
+
async clear() {
|
|
21
|
+
this.values.clear();
|
|
22
|
+
}
|
|
23
|
+
async wait(key) {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
const listeners = this.listeners.get(key) || [];
|
|
26
|
+
listeners.push(resolve);
|
|
27
|
+
this.listeners.set(key, listeners);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
notify(valueInfo) {
|
|
31
|
+
const listeners = this.listeners.get(valueInfo.key);
|
|
32
|
+
try {
|
|
33
|
+
listeners?.forEach((resolve) => resolve(valueInfo));
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
this.listeners.delete(valueInfo.key);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.MemoryStorage = MemoryStorage;
|
|
41
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../../src/server/storage/single-instance/memory.ts"],"names":[],"mappings":";;;AAKA,MAAa,aAAa;IAA1B;QACU,WAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;QAC7C,cAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAmC9D,CAAC;IAjCC,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAA2B,EAAE,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,EAAE;QAC7D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1C,IAAI,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,OAAO,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAChD,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,SAA2B;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;CACF;AArCD,sCAqCC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TestRunValueInfo } from '../../shared/value-info';
|
|
2
|
+
export type ITestRunStorage = {
|
|
3
|
+
load(key: string): Promise<TestRunValueInfo | undefined>;
|
|
4
|
+
save(valueInfo: TestRunValueInfo, options?: {
|
|
5
|
+
notify?: boolean;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
wait(key: string): Promise<TestRunValueInfo>;
|
|
8
|
+
};
|
|
9
|
+
export type IPersistentStorage = {
|
|
10
|
+
load(key: string): Promise<TestRunValueInfo | undefined>;
|
|
11
|
+
save(valueInfo: TestRunValueInfo): Promise<void>;
|
|
12
|
+
delete(key: string): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/server/storage/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,SAAS,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/server/storage/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
/**
|
|
4
|
+
* Start server.
|
|
5
|
+
* See: https://github.com/nodejs/node/issues/21482#issuecomment-626025579
|
|
6
|
+
*/
|
|
7
|
+
export declare function startExpressServer(app: express.Express, port?: number): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
|
|
8
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/server/utils/express.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,SAAI,iFAMtE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startExpressServer = startExpressServer;
|
|
4
|
+
/**
|
|
5
|
+
* Start server.
|
|
6
|
+
* See: https://github.com/nodejs/node/issues/21482#issuecomment-626025579
|
|
7
|
+
*/
|
|
8
|
+
async function startExpressServer(app, port = 0) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const server = app.listen(port);
|
|
11
|
+
server.once('listening', () => resolve(server));
|
|
12
|
+
server.once('error', reject);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/server/utils/express.ts"],"names":[],"mappings":";;AAOA,gDAMC;AAVD;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CAAC,GAAoB,EAAE,IAAI,GAAG,CAAC;IACrE,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/shared/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,KAAK,gBAAwB,CAAC;AAC3C,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,SAAS,MAAM,SAGpD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.debugKey = exports.debug = void 0;
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
8
|
+
exports.debug = (0, debug_1.default)('global-cache');
|
|
9
|
+
const debugKey = (key, message) => {
|
|
10
|
+
const debug = (0, debug_1.default)(`global-cache:${key}`);
|
|
11
|
+
debug(message);
|
|
12
|
+
};
|
|
13
|
+
exports.debugKey = debugKey;
|
|
14
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/shared/debug.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAEb,QAAA,KAAK,GAAG,IAAA,eAAK,EAAC,cAAc,CAAC,CAAC;AACpC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,EAAE;IACvD,MAAM,KAAK,GAAG,IAAA,eAAK,EAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;AACjB,CAAC,CAAC;AAHW,QAAA,QAAQ,YAGnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,SAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the calling signature for a given key:
|
|
3
|
+
* ttl + stack + computeFn body
|
|
4
|
+
*
|
|
5
|
+
* Signature is used to invalidate the key in case of changes in the calling code.
|
|
6
|
+
* Signature is computed on client and sent to the server.
|
|
7
|
+
* Server compares the signature with the stored one and invalidates the key if they differ.
|
|
8
|
+
*/
|
|
9
|
+
import { TTL } from './ttl';
|
|
10
|
+
type SingatureParams = {
|
|
11
|
+
fn: Function;
|
|
12
|
+
stack: string;
|
|
13
|
+
ttl?: TTL;
|
|
14
|
+
};
|
|
15
|
+
export type SignatureMismatch = {
|
|
16
|
+
field: 'fn' | 'stack' | 'ttl' | 'sig';
|
|
17
|
+
value1: unknown;
|
|
18
|
+
value2: unknown;
|
|
19
|
+
};
|
|
20
|
+
export declare function calcSignature({ ttl, stack, fn }: SingatureParams): string;
|
|
21
|
+
export declare function checkSignature(key: string, storedSigStr: string, currentSigStr: string): SignatureMismatch | undefined;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=sig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sig.d.ts","sourceRoot":"","sources":["../../src/shared/sig.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,KAAK,eAAe,GAAG;IACrB,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AAQF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,UAOhE;AAGD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,iBAAiB,GAAG,SAAS,CAwB/B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Calculate the calling signature for a given key:
|
|
4
|
+
* ttl + stack + computeFn body
|
|
5
|
+
*
|
|
6
|
+
* Signature is used to invalidate the key in case of changes in the calling code.
|
|
7
|
+
* Signature is computed on client and sent to the server.
|
|
8
|
+
* Server compares the signature with the stored one and invalidates the key if they differ.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.calcSignature = calcSignature;
|
|
12
|
+
exports.checkSignature = checkSignature;
|
|
13
|
+
function calcSignature({ ttl, stack, fn }) {
|
|
14
|
+
// todo: use hashing?
|
|
15
|
+
// todo: remove spaces and newlines from stack and computeFn?
|
|
16
|
+
const fnBody = fn.toString().replace(/[\n\s]+/g, ' ');
|
|
17
|
+
const obj = { ttl, stack, fn: fnBody };
|
|
18
|
+
return JSON.stringify(obj);
|
|
19
|
+
}
|
|
20
|
+
// eslint-disable-next-line visual/complexity
|
|
21
|
+
function checkSignature(key, storedSigStr, currentSigStr) {
|
|
22
|
+
const storedSig = parseSignatureSafe(storedSigStr);
|
|
23
|
+
const currentSig = parseSignatureSafe(currentSigStr);
|
|
24
|
+
// fallback to string comparison if parsing failed for any of the signatures
|
|
25
|
+
// todo: remove in the future releases
|
|
26
|
+
if (!storedSig || !currentSig) {
|
|
27
|
+
return storedSigStr !== currentSigStr
|
|
28
|
+
? createSignatureMismatch('sig', storedSigStr, currentSigStr)
|
|
29
|
+
: undefined;
|
|
30
|
+
}
|
|
31
|
+
// checking stack first -> allows to navigate to the code by click in IDE.
|
|
32
|
+
if (storedSig.stack !== currentSig.stack) {
|
|
33
|
+
return createSignatureMismatch('stack', storedSig.stack, currentSig.stack);
|
|
34
|
+
}
|
|
35
|
+
if (storedSig.ttl !== currentSig.ttl) {
|
|
36
|
+
return createSignatureMismatch('ttl', storedSig.ttl, currentSig.ttl);
|
|
37
|
+
}
|
|
38
|
+
if (storedSig.fn !== currentSig.fn) {
|
|
39
|
+
return createSignatureMismatch('fn', storedSig.fn, currentSig.fn);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function createSignatureMismatch(field, value1, value2) {
|
|
43
|
+
return { field, value1, value2 };
|
|
44
|
+
}
|
|
45
|
+
function parseSignatureSafe(sigStr) {
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(sigStr);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=sig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sig.js","sourceRoot":"","sources":["../../src/shared/sig.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAsBH,sCAOC;AAGD,wCA4BC;AAtCD,SAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAmB;IAC/D,qBAAqB;IACrB,6DAA6D;IAC7D,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,GAAG,GAAiB,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAErD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,6CAA6C;AAC7C,SAAgB,cAAc,CAC5B,GAAW,EACX,YAAoB,EACpB,aAAqB;IAErB,MAAM,SAAS,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAErD,4EAA4E;IAC5E,sCAAsC;IACtC,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,OAAO,YAAY,KAAK,aAAa;YACnC,CAAC,CAAC,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,aAAa,CAAC;YAC7D,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED,0EAA0E;IAC1E,IAAI,SAAS,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;QACzC,OAAO,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,SAAS,CAAC,GAAG,KAAK,UAAU,CAAC,GAAG,EAAE,CAAC;QACrC,OAAO,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,SAAS,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE,EAAE,CAAC;QACnC,OAAO,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAiC,EACjC,MAAe,EACf,MAAe;IAEf,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAc;IACxC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAiB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { StringValue } from 'ms';
|
|
2
|
+
export type TTL = number | StringValue | 'infinite';
|
|
3
|
+
/**
|
|
4
|
+
* TTL can be a stringified number or a string like "1h" or "infinite".
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseTTL(ttl: string | number | undefined): number | undefined;
|
|
7
|
+
export declare function isExpired(computedAt: number | undefined, ttl: number): boolean;
|
|
8
|
+
//# sourceMappingURL=ttl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ttl.d.ts","sourceRoot":"","sources":["../../src/shared/ttl.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAGrC,MAAM,MAAM,GAAG,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;AAEpD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,sBAKxD;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,WAGpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseTTL = parseTTL;
|
|
7
|
+
exports.isExpired = isExpired;
|
|
8
|
+
const ms_1 = __importDefault(require("ms"));
|
|
9
|
+
/**
|
|
10
|
+
* TTL can be a stringified number or a string like "1h" or "infinite".
|
|
11
|
+
*/
|
|
12
|
+
function parseTTL(ttl) {
|
|
13
|
+
if (ttl === '' || ttl === undefined)
|
|
14
|
+
return undefined;
|
|
15
|
+
if (ttl === 'infinite')
|
|
16
|
+
return -1;
|
|
17
|
+
const ttlNumber = Number(ttl);
|
|
18
|
+
return Number.isNaN(ttlNumber) ? (0, ms_1.default)(ttl) : ttlNumber;
|
|
19
|
+
}
|
|
20
|
+
function isExpired(computedAt, ttl) {
|
|
21
|
+
if (!computedAt || ttl === -1)
|
|
22
|
+
return false;
|
|
23
|
+
return Date.now() > computedAt + ttl;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ttl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ttl.js","sourceRoot":"","sources":["../../src/shared/ttl.ts"],"names":[],"mappings":";;;;;AAQA,4BAKC;AAED,8BAGC;AAlBD,4CAAqC;AAKrC;;GAEG;AACH,SAAgB,QAAQ,CAAC,GAAgC;IACvD,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,GAAG,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAA,YAAE,EAAC,GAAkB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAgB,SAAS,CAAC,UAA8B,EAAE,GAAW;IACnE,IAAI,CAAC,UAAU,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,GAAG,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/object.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAGzF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeUndefined = removeUndefined;
|
|
4
|
+
function removeUndefined(obj) {
|
|
5
|
+
if (!obj)
|
|
6
|
+
return;
|
|
7
|
+
return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== undefined));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/shared/utils/object.ts"],"names":[],"mappings":";;AAAA,0CAGC;AAHD,SAAgB,eAAe,CAAoC,GAAO;IACxE,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAM,CAAC;AAClG,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Value info in the scope of particular test run.
|
|
3
|
+
*/
|
|
4
|
+
export type TestRunValueInfo = {
|
|
5
|
+
key: string;
|
|
6
|
+
sig: string;
|
|
7
|
+
state: 'computing' | 'computed' | 'error';
|
|
8
|
+
computedAt?: number;
|
|
9
|
+
value?: unknown;
|
|
10
|
+
persistent?: boolean;
|
|
11
|
+
prevValue?: unknown;
|
|
12
|
+
errorMessage?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function updateValueInfo(valueInfo: TestRunValueInfo, props: Partial<TestRunValueInfo>): TestRunValueInfo & Partial<TestRunValueInfo>;
|
|
15
|
+
export declare function setComputed(valueInfo: TestRunValueInfo, value: unknown): void;
|
|
16
|
+
export declare function setError(valueInfo: TestRunValueInfo, errorMessage: string): void;
|
|
17
|
+
export declare function getStaleValue(valueInfo?: TestRunValueInfo | null): unknown;
|
|
18
|
+
//# sourceMappingURL=value-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-info.d.ts","sourceRoot":"","sources":["../../src/shared/value-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,eAAe,CAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,gDAE5F;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,QAOtE;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,QAOzE;AAED,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,WAEhE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Value info in the scope of particular test run.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateValueInfo = updateValueInfo;
|
|
7
|
+
exports.setComputed = setComputed;
|
|
8
|
+
exports.setError = setError;
|
|
9
|
+
exports.getStaleValue = getStaleValue;
|
|
10
|
+
function updateValueInfo(valueInfo, props) {
|
|
11
|
+
return Object.assign(valueInfo, props);
|
|
12
|
+
}
|
|
13
|
+
function setComputed(valueInfo, value) {
|
|
14
|
+
updateValueInfo(valueInfo, {
|
|
15
|
+
state: 'computed',
|
|
16
|
+
value,
|
|
17
|
+
computedAt: Date.now(),
|
|
18
|
+
errorMessage: undefined,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function setError(valueInfo, errorMessage) {
|
|
22
|
+
updateValueInfo(valueInfo, {
|
|
23
|
+
state: 'error',
|
|
24
|
+
errorMessage,
|
|
25
|
+
value: undefined,
|
|
26
|
+
computedAt: undefined,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function getStaleValue(valueInfo) {
|
|
30
|
+
return valueInfo?.persistent ? valueInfo.prevValue : valueInfo?.value;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=value-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-info.js","sourceRoot":"","sources":["../../src/shared/value-info.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAaH,0CAEC;AAED,kCAOC;AAED,4BAOC;AAED,sCAEC;AAxBD,SAAgB,eAAe,CAAC,SAA2B,EAAE,KAAgC;IAC3F,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,SAAgB,WAAW,CAAC,SAA2B,EAAE,KAAc;IACrE,eAAe,CAAC,SAAS,EAAE;QACzB,KAAK,EAAE,UAAU;QACjB,KAAK;QACL,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;QACtB,YAAY,EAAE,SAAS;KACxB,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,QAAQ,CAAC,SAA2B,EAAE,YAAoB;IACxE,eAAe,CAAC,SAAS,EAAE;QACzB,KAAK,EAAE,OAAO;QACd,YAAY;QACZ,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,SAAS;KACtB,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,aAAa,CAAC,SAAmC;IAC/D,OAAO,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC;AACxE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@global-cache/core",
|
|
3
|
+
"description": "Key-value cache for sharing data between parallel workers.",
|
|
4
|
+
"version": "0.2.3",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.js",
|
|
8
|
+
"./server": "./dist/server/index.js",
|
|
9
|
+
"./package.json": "./package.json"
|
|
10
|
+
},
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=20"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.build.json",
|
|
21
|
+
"test": "vitest run --no-cache --testTimeout 5000 --dir ./test",
|
|
22
|
+
"test:d": "DEBUG=global-cache* npm t",
|
|
23
|
+
"release": "release-it"
|
|
24
|
+
},
|
|
25
|
+
"release-it": {
|
|
26
|
+
"git": false
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@types/debug": "^4.1.12",
|
|
30
|
+
"@types/express": "^5.0.3",
|
|
31
|
+
"@types/ms": "^2.1.0",
|
|
32
|
+
"debug": "^4.4.1",
|
|
33
|
+
"express": "^5.1.0",
|
|
34
|
+
"ms": "^2.1.3"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"funding": "https://github.com/sponsors/vitalets",
|
|
40
|
+
"license": "MIT"
|
|
41
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { GetValueParams, GetValueResponse } from '../server/routes/get';
|
|
2
|
+
import type { SetValueParams, SetValueResponse } from '../server/routes/set';
|
|
3
|
+
import type { GetStaleParams, SetStaleResponse } from '../server/routes/get-stale';
|
|
4
|
+
import type { GetStaleListParams, SetStaleListResponse } from '../server/routes/get-stale-list';
|
|
5
|
+
import { TTL } from '../shared/ttl';
|
|
6
|
+
import { HttpJson } from './utils/http-json';
|
|
7
|
+
import { prepareQueryParams } from './utils/http-query';
|
|
8
|
+
import { throwIfHttpError } from './utils/http-error';
|
|
9
|
+
import { getStaleValue } from '../shared/value-info';
|
|
10
|
+
|
|
11
|
+
export class StorageApi {
|
|
12
|
+
private http: HttpJson;
|
|
13
|
+
|
|
14
|
+
constructor(serverUrl: string, runId: string) {
|
|
15
|
+
const baseUrl = new URL(`/run/${runId}/`, serverUrl).toString();
|
|
16
|
+
this.http = new HttpJson(baseUrl);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async get({ key, sig, ttl }: { key: string; sig: string; ttl?: TTL }) {
|
|
20
|
+
const params: GetValueParams = prepareQueryParams({ key, sig, ttl });
|
|
21
|
+
const res = await this.http.get('get', params);
|
|
22
|
+
await throwIfHttpError(res, `Failed to get key "${key}":`);
|
|
23
|
+
return (await res.json()) as GetValueResponse;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async set({ key, value, error }: { key: string; value: unknown; error?: Error }) {
|
|
27
|
+
const body: SetValueParams = { key, value, error: error?.message };
|
|
28
|
+
const res = await this.http.post('set', body);
|
|
29
|
+
await throwIfHttpError(res, `Failed to save key "${key}":`);
|
|
30
|
+
return (await res.json()) as SetValueResponse;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getStale({ key }: GetStaleParams) {
|
|
34
|
+
const res = await this.http.get('get-stale', { key });
|
|
35
|
+
await throwIfHttpError(res, `Failed to get stale key "${key}":`);
|
|
36
|
+
const valueInfo = (await res.json()) as SetStaleResponse;
|
|
37
|
+
return getStaleValue(valueInfo);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async getStaleList({ prefix }: GetStaleListParams) {
|
|
41
|
+
const res = await this.http.get('get-stale-list', { prefix });
|
|
42
|
+
await throwIfHttpError(res, `Failed to get stale list for prefix "${prefix}":`);
|
|
43
|
+
const valueInfoList = (await res.json()) as SetStaleListResponse;
|
|
44
|
+
return valueInfoList.map((valueInfo) => getStaleValue(valueInfo));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async clear() {
|
|
48
|
+
const res = await this.http.post('clear');
|
|
49
|
+
await throwIfHttpError(res, 'Failed to clear session:');
|
|
50
|
+
}
|
|
51
|
+
}
|