@global-cache/core 0.4.1 → 0.5.1

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 (38) hide show
  1. package/dist/client/api.d.ts +1 -0
  2. package/dist/client/api.d.ts.map +1 -1
  3. package/dist/client/api.js +5 -0
  4. package/dist/client/api.js.map +1 -1
  5. package/dist/client/index.d.ts +4 -0
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +8 -0
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/server/getter.d.ts +0 -1
  14. package/dist/server/getter.d.ts.map +1 -1
  15. package/dist/server/getter.js +42 -29
  16. package/dist/server/getter.js.map +1 -1
  17. package/dist/server/index.d.ts.map +1 -1
  18. package/dist/server/index.js +8 -1
  19. package/dist/server/index.js.map +1 -1
  20. package/dist/server/routes/delete.d.ts +6 -0
  21. package/dist/server/routes/delete.d.ts.map +1 -0
  22. package/dist/server/routes/delete.js +19 -0
  23. package/dist/server/routes/delete.js.map +1 -0
  24. package/dist/server/storage/single-instance/memory.d.ts +15 -1
  25. package/dist/server/storage/single-instance/memory.d.ts.map +1 -1
  26. package/dist/server/storage/single-instance/memory.js +26 -1
  27. package/dist/server/storage/single-instance/memory.js.map +1 -1
  28. package/dist/server/storage/types.d.ts +3 -1
  29. package/dist/server/storage/types.d.ts.map +1 -1
  30. package/package.json +2 -2
  31. package/src/client/api.ts +7 -0
  32. package/src/client/index.ts +9 -0
  33. package/src/index.ts +1 -0
  34. package/src/server/getter.ts +46 -36
  35. package/src/server/index.ts +8 -1
  36. package/src/server/routes/delete.ts +23 -0
  37. package/src/server/storage/single-instance/memory.ts +27 -1
  38. package/src/server/storage/types.ts +3 -1
@@ -17,5 +17,6 @@ export declare class StorageApi {
17
17
  getStale({ key }: GetStaleParams): Promise<unknown>;
18
18
  getStaleList({ prefix }: GetStaleListParams): Promise<unknown[]>;
19
19
  clearTestRun(): Promise<void>;
20
+ deleteKey(key: string): Promise<void>;
20
21
  }
21
22
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4BAA4B,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAMpC,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAa;gBAEb,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM;IAQlD,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE;IAO9D,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAOzE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc;IAOhC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB;IAO3C,YAAY;CAInB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,4BAA4B,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,iCAAiC,CAAC;AAEhG,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAMpC,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAa;gBAEb,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM;IAQlD,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE;IAO9D,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAOzE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc;IAOhC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB;IAO3C,YAAY;IAKZ,SAAS,CAAC,GAAG,EAAE,MAAM;CAK5B"}
@@ -41,6 +41,11 @@ class StorageApi {
41
41
  const res = await this.http.post('clear');
42
42
  await (0, http_error_1.throwIfHttpError)(res, 'Failed to clear test run:');
43
43
  }
44
+ async deleteKey(key) {
45
+ const body = { key };
46
+ const res = await this.http.post('delete', body);
47
+ await (0, http_error_1.throwIfHttpError)(res, `Failed to delete key "${key}":`);
48
+ }
44
49
  }
45
50
  exports.StorageApi = StorageApi;
46
51
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":";;;AAKA,qDAAiD;AACjD,mDAAwD;AACxD,mDAAsD;AACtD,qDAAqD;AAErD,MAAa,UAAU;IAGrB,YAAY,SAA6B,EAAE,KAAa;QACtD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChE,IAAI,CAAC,IAAI,GAAG,IAAI,wBAAU,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAA2C;QAClE,MAAM,MAAM,GAAmB,IAAA,+BAAkB,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAA,6BAAgB,EAAC,GAAG,EAAE,sBAAsB,GAAG,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAkD;QAC7E,MAAM,IAAI,GAAmB,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACnE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAA,6BAAgB,EAAC,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAAC,CAAC;QAC5D,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAkB;QACpC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,MAAM,IAAA,6BAAgB,EAAC,GAAG,EAAE,4BAA4B,GAAG,IAAI,CAAC,CAAC;QACjE,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAC;QACzD,OAAO,IAAA,0BAAa,EAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAE,MAAM,EAAsB;QAC/C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAA,6BAAgB,EAAC,GAAG,EAAE,wCAAwC,MAAM,IAAI,CAAC,CAAC;QAChF,MAAM,aAAa,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyB,CAAC;QACjE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAA,0BAAa,EAAC,SAAS,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,IAAA,6BAAgB,EAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC;IAC3D,CAAC;CACF;AA3CD,gCA2CC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,10 @@ export declare class GlobalCacheClient<S extends DefaultKeysSchema = DefaultKeys
27
27
  * - for persistent keys it would be the old value if it was changed during this run
28
28
  */
29
29
  getStaleList<ValueType>(prefix: string): Promise<ValueType[]>;
30
+ /**
31
+ * Delete a cached value by key, forcing re-computation on the next get() call.
32
+ */
33
+ delete<K extends StringKeys<S>>(key: K): Promise<void>;
30
34
  /**
31
35
  * Reset current test run:
32
36
  * - clear all non-persistent values
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK3D,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B,qBAAa,iBAAiB,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB;IAI5E,MAAM,CAAC,MAAM,EAAE,iBAAiB;IAIhC;;;;;;OAMG;IACH,OAAO,KAAK,GAAG,GAGd;IAED;;OAEG;IAEG,GAAG,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAsDzE;;;;OAIG;IACG,QAAQ,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;IAQ9C;;;;OAIG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM;IAQ5C;;;;OAIG;IACG,YAAY;YA8BJ,YAAY;CAS3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK3D,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B,qBAAa,iBAAiB,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB;IAI5E,MAAM,CAAC,MAAM,EAAE,iBAAiB;IAIhC;;;;;;OAMG;IACH,OAAO,KAAK,GAAG,GAGd;IAED;;OAEG;IAEG,GAAG,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAsDzE;;;;OAIG;IACG,QAAQ,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;IAQ9C;;;;OAIG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM;IAQ5C;;OAEG;IACG,MAAM,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;IAM5C;;;;OAIG;IACG,YAAY;YA8BJ,YAAY;CAS3B"}
@@ -95,6 +95,14 @@ class GlobalCacheClient {
95
95
  (0, debug_1.debugKey)(prefix, `Fetched: ${values.length} value(s)`);
96
96
  return values;
97
97
  }
98
+ /**
99
+ * Delete a cached value by key, forcing re-computation on the next get() call.
100
+ */
101
+ async delete(key) {
102
+ (0, debug_1.debugKey)(key, `Deleting value...`);
103
+ await this.api.deleteKey(key);
104
+ (0, debug_1.debugKey)(key, `Deleted.`);
105
+ }
98
106
  /**
99
107
  * Reset current test run:
100
108
  * - clear all non-persistent values
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { GlobalCacheClient, DefaultKeysSchema } from './client/index.js';
2
2
  export { globalConfig, GlobalCacheConfig } from './client/config.js';
3
+ export { logger } from './shared/logger.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.globalConfig = exports.GlobalCacheClient = void 0;
3
+ exports.logger = exports.globalConfig = exports.GlobalCacheClient = void 0;
4
4
  var index_js_1 = require("./client/index.js");
5
5
  Object.defineProperty(exports, "GlobalCacheClient", { enumerable: true, get: function () { return index_js_1.GlobalCacheClient; } });
6
6
  var config_js_1 = require("./client/config.js");
7
7
  Object.defineProperty(exports, "globalConfig", { enumerable: true, get: function () { return config_js_1.globalConfig; } });
8
+ var logger_js_1 = require("./shared/logger.js");
9
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_js_1.logger; } });
8
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8CAAyE;AAAhE,6GAAA,iBAAiB,OAAA;AAC1B,gDAAqE;AAA5D,yGAAA,YAAY,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8CAAyE;AAAhE,6GAAA,iBAAiB,OAAA;AAC1B,gDAAqE;AAA5D,yGAAA,YAAY,OAAA;AACrB,gDAA4C;AAAnC,mGAAA,MAAM,OAAA"}
@@ -25,7 +25,6 @@ export declare class Getter {
25
25
  private handleSignatureMismatch;
26
26
  private handleComputed;
27
27
  private handleError;
28
- private handleSignatureChanged;
29
28
  private handleExpired;
30
29
  private handleNoValue;
31
30
  private handleDefault;
@@ -1 +1 @@
1
- {"version":3,"file":"getter.d.ts","sourceRoot":"","sources":["../../src/server/getter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,KAAK,eAAe,GAAG;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACjE,KAAK,cAAc,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAC3E,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACxD,KAAK,uBAAuB,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,cAAc,GAAG,WAAW,GAAG,uBAAuB,CAAC;AAEpG,qBAAa,MAAM;IAEf,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,iBAAiB;gBADjB,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,kBAAkB;IAIzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAmDxE,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;YAIL,sBAAsB;YAetB,aAAa;YAUb,aAAa;YAKb,aAAa;YAMb,eAAe;CAI9B"}
1
+ {"version":3,"file":"getter.d.ts","sourceRoot":"","sources":["../../src/server/getter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,KAAK,eAAe,GAAG;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACjE,KAAK,cAAc,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAC3E,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACxD,KAAK,uBAAuB,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,cAAc,GAAG,WAAW,GAAG,uBAAuB,CAAC;AAEpG,qBAAa,MAAM;IAEf,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,iBAAiB;gBADjB,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,kBAAkB;IAIzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAwCxE,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;YAIL,aAAa;YAWb,aAAa;YAwCb,aAAa;YAMb,eAAe;CAI9B"}
@@ -23,36 +23,26 @@ class Getter {
23
23
  }
24
24
  // wait if computing
25
25
  if (valueInfo?.state === 'computing') {
26
- valueInfo = await this.testRunStorage.wait(key);
26
+ valueInfo = await this.testRunStorage.waitForComputed(key);
27
27
  return valueInfo.state === 'computed'
28
28
  ? this.handleComputed(valueInfo)
29
29
  : this.handleError(valueInfo);
30
30
  }
31
- // load from persistent storage
32
- if (!valueInfo && ttl) {
33
- valueInfo = await this.persistentStorage.load(key);
34
- if (valueInfo) {
35
- const signatureMismatch = (0, sig_1.checkSignature)(key, valueInfo.sig, sig);
36
- // eslint-disable-next-line max-depth
37
- if (signatureMismatch) {
38
- return this.handleSignatureChanged(valueInfo, sig, signatureMismatch);
39
- }
40
- }
31
+ // no value in memory -- claim the key atomically before touching persistent storage,
32
+ // so concurrent callers for the same key can't all decide to recompute independently
33
+ if (!valueInfo) {
34
+ return this.handleNoValue(key, sig, ttl);
41
35
  }
42
36
  // check expired
43
- if (valueInfo?.state === 'computed' && valueInfo.persistent && ttl) {
37
+ if (valueInfo.state === 'computed' && valueInfo.persistent && ttl) {
44
38
  if ((0, ttl_1.isExpired)(valueInfo.computedAt, ttl)) {
45
39
  return this.handleExpired(valueInfo, ttl);
46
40
  }
47
41
  }
48
42
  // normal cache hit
49
- if (valueInfo?.state === 'computed') {
43
+ if (valueInfo.state === 'computed') {
50
44
  return this.handleComputed(valueInfo);
51
45
  }
52
- // no value
53
- if (!valueInfo) {
54
- return this.handleNoValue(key, sig, ttl);
55
- }
56
46
  return this.handleDefault(valueInfo);
57
47
  }
58
48
  handleSignatureMismatch(key, signatureMismatch) {
@@ -64,16 +54,6 @@ class Getter {
64
54
  handleError(valueInfo) {
65
55
  return { result: 'error', message: valueInfo.errorMessage || 'Unknown error' };
66
56
  }
67
- async handleSignatureChanged(loadedValueInfo, newSig, { field }) {
68
- await this.updateValueInfo(loadedValueInfo, {
69
- state: 'computing',
70
- sig: newSig,
71
- prevValue: loadedValueInfo.value,
72
- value: undefined,
73
- computedAt: undefined,
74
- });
75
- return { result: 'cache-miss', message: `signature changed: ${field}` };
76
- }
77
57
  async handleExpired(valueInfo, ttl) {
78
58
  await this.updateValueInfo(valueInfo, {
79
59
  state: 'computing',
@@ -83,9 +63,42 @@ class Getter {
83
63
  });
84
64
  return { result: 'cache-miss', message: `expired: ${ttl}` };
85
65
  }
66
+ // eslint-disable-next-line visual/complexity, max-statements
86
67
  async handleNoValue(key, sig, ttl) {
87
- await this.updateValueInfo({ key, state: 'computing', sig, persistent: Boolean(ttl) });
88
- return { result: 'cache-miss', message: 'no cached value' };
68
+ const placeholder = {
69
+ key,
70
+ state: 'computing',
71
+ sig,
72
+ persistent: Boolean(ttl),
73
+ };
74
+ const claimed = this.testRunStorage.claimForComputing(placeholder);
75
+ if (!claimed) {
76
+ const resolved = await this.testRunStorage.waitForComputed(key);
77
+ return resolved.state === 'computed'
78
+ ? this.handleComputed(resolved)
79
+ : this.handleError(resolved);
80
+ }
81
+ if (!ttl)
82
+ return { result: 'cache-miss', message: 'no cached value' };
83
+ // We own the 'computing' slot now, so no other concurrent caller can also decide
84
+ // to recompute this key while we consult persistent storage.
85
+ const persisted = await this.persistentStorage.load(key);
86
+ if (!persisted)
87
+ return { result: 'cache-miss', message: 'no cached value' };
88
+ const signatureMismatch = (0, sig_1.checkSignature)(key, persisted.sig, sig);
89
+ if (signatureMismatch) {
90
+ placeholder.prevValue = persisted.value;
91
+ return { result: 'cache-miss', message: `signature changed: ${signatureMismatch.field}` };
92
+ }
93
+ if ((0, ttl_1.isExpired)(persisted.computedAt, ttl)) {
94
+ placeholder.prevValue = persisted.value;
95
+ return { result: 'cache-miss', message: `expired: ${ttl}` };
96
+ }
97
+ // Persistent value is fresh and valid -- adopt it as computed, update the map entry
98
+ // (already resident via claimForComputing) and notify any waiters.
99
+ Object.assign(placeholder, persisted);
100
+ await this.testRunStorage.save(placeholder, { notify: true });
101
+ return this.handleComputed(placeholder);
89
102
  }
90
103
  async handleDefault(valueInfo) {
91
104
  const message = `old state: ${valueInfo.state}`;
@@ -1 +1 @@
1
- {"version":3,"file":"getter.js","sourceRoot":"","sources":["../../src/server/getter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getter.js","sourceRoot":"","sources":["../../src/server/getter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,uBAAuB,EAA4B,MAAM,UAAU,CAAC;AAG7E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,MAAM,CAA4B;;IAc1C,IAAI,IAAI,WAGP;IAED,IAAI,QAAQ,WAEX;IAED,IAAI,SAAS,YAEZ;IAEK,KAAK,CAAC,cAAc,CAAC,EAAE,uBAAuB;IAS9C,IAAI;CAUX;AAGD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,uBAAuB,EAA4B,MAAM,UAAU,CAAC;AAG7E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,MAAM,CAA4B;;IAe1C,IAAI,IAAI,WAGP;IAED,IAAI,QAAQ,WAEX;IAED,IAAI,SAAS,YAEZ;IAEK,KAAK,CAAC,cAAc,CAAC,EAAE,uBAAuB;IAc9C,IAAI;CAUX;AAGD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
@@ -12,6 +12,7 @@ const set_1 = require("./routes/set");
12
12
  const get_stale_1 = require("./routes/get-stale");
13
13
  const get_stale_list_1 = require("./routes/get-stale-list");
14
14
  const clear_1 = require("./routes/clear");
15
+ const delete_1 = require("./routes/delete");
15
16
  const error_1 = require("./error");
16
17
  const config_1 = require("./config");
17
18
  const express_2 = require("./utils/express");
@@ -19,13 +20,14 @@ class GlobalCacheServer {
19
20
  constructor() {
20
21
  this.app = (0, express_1.default)();
21
22
  this.server = null;
22
- this.app.use(express_1.default.json());
23
+ this.app.use(express_1.default.json({ limit: '10mb' }));
23
24
  this.app.use('/', root_1.router);
24
25
  this.app.use('/', get_1.router);
25
26
  this.app.use('/', set_1.router);
26
27
  this.app.use('/', get_stale_1.router);
27
28
  this.app.use('/', get_stale_list_1.router);
28
29
  this.app.use('/', clear_1.router);
30
+ this.app.use('/', delete_1.router);
29
31
  // Must be after all other middleware and routes
30
32
  this.app.use(error_1.errorHandler);
31
33
  }
@@ -45,6 +47,11 @@ class GlobalCacheServer {
45
47
  const config = (0, config_1.resolveConfig)(providedConfig);
46
48
  (0, config_1.setConfig)(this.app, config);
47
49
  this.server = await (0, express_2.startExpressServer)(this.app, config.port);
50
+ // unref() so the server does not prevent the Node.js process from exiting
51
+ // naturally when all other work is done (e.g. in CLI mode after tests finish).
52
+ // In VSCode / UI mode the process is kept alive by Playwright's own IPC
53
+ // channels, so the server stays up automatically for subsequent runs.
54
+ this.server.unref();
48
55
  (0, debug_1.debug)(`Starting server: done ${this.localUrl}`);
49
56
  }
50
57
  async stop() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;AASA,sDAA8B;AAC9B,2CAAwC;AACxC,wCAAoD;AACpD,sCAAkD;AAClD,sCAAkD;AAClD,kDAA6D;AAC7D,4DAAsE;AACtE,0CAA6D;AAC7D,mCAAuC;AACvC,qCAA6E;AAC7E,6CAAwE;AAExE,MAAa,iBAAiB;IAI5B;QAHQ,QAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;QAChB,WAAM,GAAuB,IAAI,CAAC;QAGxC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,aAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,YAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,YAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAa,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,uBAAiB,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,cAAiB,CAAC,CAAC;QACrC,gDAAgD;QAChD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,oBAAY,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,IAAI;QACN,MAAM,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,cAAwC;QAClD,sCAAsC;QACtC,IAAA,aAAK,EAAC,oBAAoB,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,cAAc,CAAC,CAAC;QAC7C,IAAA,kBAAS,EAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAA,4BAAkB,EAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAA,aAAK,EAAC,yBAAyB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAC5C,IAAA,aAAK,EAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,IAAA,2BAAiB,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,IAAA,aAAK,EAAC,wBAAwB,CAAC,CAAC;IAClC,CAAC;CACF;AAhDD,8CAgDC;AAED,sDAAsD;AACzC,QAAA,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Router } from 'express';
2
+ export declare const router: ReturnType<typeof Router>;
3
+ export type DeleteValueParams = {
4
+ key: string;
5
+ };
6
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/server/routes/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAE,MAAM,SAAS,CAAC;AAI1C,eAAO,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,MAAM,CAAY,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.router = void 0;
4
+ const express_1 = require("express");
5
+ const config_1 = require("../config");
6
+ const storage_1 = require("../storage");
7
+ exports.router = (0, express_1.Router)();
8
+ exports.router.post('/run/:runId/delete', async (req, res) => {
9
+ const { runId } = req.params;
10
+ const { key } = req.body;
11
+ const config = (0, config_1.getConfig)(req.app);
12
+ const { testRunStorage, persistentStorage } = (0, storage_1.getStorage)(config, runId);
13
+ const valueInfo = await testRunStorage.load(key);
14
+ await testRunStorage.delete(key);
15
+ if (valueInfo?.persistent)
16
+ await persistentStorage.delete(key);
17
+ res.end();
18
+ });
19
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/server/routes/delete.ts"],"names":[],"mappings":";;;AAAA,qCAA0C;AAC1C,sCAAsC;AACtC,wCAAwC;AAE3B,QAAA,MAAM,GAA8B,IAAA,gBAAM,GAAE,CAAC;AAM1D,cAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnD,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;IAC7B,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,IAAyB,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAA,kBAAS,EAAC,GAAG,CAAC,GAAc,CAAC,CAAC;IAE7C,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,GAAG,IAAA,oBAAU,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAExE,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,SAAS,EAAE,UAAU;QAAE,MAAM,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/D,GAAG,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC"}
@@ -8,8 +8,22 @@ export declare class MemoryStorage implements ITestRunStorage {
8
8
  save(valueInfo: TestRunValueInfo, { notify }?: {
9
9
  notify?: boolean | undefined;
10
10
  }): Promise<void>;
11
+ delete(key: string): Promise<void>;
11
12
  clear(): Promise<void>;
12
- wait(key: string): Promise<TestRunValueInfo>;
13
+ /**
14
+ * Atomically claims the key for computing if it is not yet present.
15
+ *
16
+ * Concurrent workers all call `await testRunStorage.load(key)`, which yields the event loop,
17
+ * so all of them can see `undefined` simultaneously. Using async `save()` for the initial
18
+ * write would let every worker return `cache-miss`, compute in parallel, and collide in
19
+ * `setter.set()` — which only accepts a single `'computing'` caller.
20
+ *
21
+ * Because this method has no `await`, Node.js's single-threaded event loop makes
22
+ * `Map.has()` + `Map.set()` atomic. Only the first caller gets `true` (proceeds to compute);
23
+ * all subsequent callers get `false` (and wait).
24
+ */
25
+ claimForComputing(valueInfo: TestRunValueInfo): boolean;
26
+ waitForComputed(key: string): Promise<TestRunValueInfo>;
13
27
  private notify;
14
28
  }
15
29
  //# sourceMappingURL=memory.d.ts.map
@@ -1 +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"}
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,MAAM,CAAC,GAAG,EAAE,MAAM;IAIlB,KAAK;IAIX;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO;IAMjD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAY7D,OAAO,CAAC,MAAM;CAQf"}
@@ -17,10 +17,35 @@ class MemoryStorage {
17
17
  if (notify)
18
18
  this.notify(valueInfo);
19
19
  }
20
+ async delete(key) {
21
+ this.values.delete(key);
22
+ }
20
23
  async clear() {
21
24
  this.values.clear();
22
25
  }
23
- async wait(key) {
26
+ /**
27
+ * Atomically claims the key for computing if it is not yet present.
28
+ *
29
+ * Concurrent workers all call `await testRunStorage.load(key)`, which yields the event loop,
30
+ * so all of them can see `undefined` simultaneously. Using async `save()` for the initial
31
+ * write would let every worker return `cache-miss`, compute in parallel, and collide in
32
+ * `setter.set()` — which only accepts a single `'computing'` caller.
33
+ *
34
+ * Because this method has no `await`, Node.js's single-threaded event loop makes
35
+ * `Map.has()` + `Map.set()` atomic. Only the first caller gets `true` (proceeds to compute);
36
+ * all subsequent callers get `false` (and wait).
37
+ */
38
+ claimForComputing(valueInfo) {
39
+ if (this.values.has(valueInfo.key))
40
+ return false;
41
+ this.values.set(valueInfo.key, valueInfo);
42
+ return true;
43
+ }
44
+ async waitForComputed(key) {
45
+ // Guard: if notify already fired before we registered, return immediately.
46
+ const existing = this.values.get(key);
47
+ if (existing && existing.state !== 'computing')
48
+ return existing;
24
49
  return new Promise((resolve) => {
25
50
  const listeners = this.listeners.get(key) || [];
26
51
  listeners.push(resolve);
@@ -1 +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"}
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;IA6D9D,CAAC;IA3DC,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,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,SAA2B;QAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,GAAW;QAC/B,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO,QAAQ,CAAC;QAEhE,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;AA/DD,sCA+DC"}
@@ -4,7 +4,9 @@ export type ITestRunStorage = {
4
4
  save(valueInfo: TestRunValueInfo, options?: {
5
5
  notify?: boolean;
6
6
  }): Promise<void>;
7
- wait(key: string): Promise<TestRunValueInfo>;
7
+ delete(key: string): Promise<void>;
8
+ waitForComputed(key: string): Promise<TestRunValueInfo>;
9
+ claimForComputing(valueInfo: TestRunValueInfo): boolean;
8
10
  };
9
11
  export type IPersistentStorage = {
10
12
  load(key: string): Promise<TestRunValueInfo | undefined>;
@@ -1 +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"}
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,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxD,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC;CACzD,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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@global-cache/core",
3
3
  "description": "Key-value cache for sharing data between parallel workers.",
4
- "version": "0.4.1",
4
+ "version": "0.5.1",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "README.md"
31
31
  ],
32
32
  "dependencies": {
33
- "@types/debug": "^4.1.12",
33
+ "@types/debug": "^4.1.13",
34
34
  "@types/express": "^5.0.6",
35
35
  "@types/ms": "^2.1.0",
36
36
  "debug": "^4.4.3",
package/src/client/api.ts CHANGED
@@ -2,6 +2,7 @@ import type { GetValueParams, GetValueResponse } from '../server/routes/get';
2
2
  import type { SetValueParams, SetValueResponse } from '../server/routes/set';
3
3
  import type { GetStaleParams, SetStaleResponse } from '../server/routes/get-stale';
4
4
  import type { GetStaleListParams, SetStaleListResponse } from '../server/routes/get-stale-list';
5
+ import type { DeleteValueParams } from '../server/routes/delete';
5
6
  import { TTL } from '../shared/ttl';
6
7
  import { HttpClient } from './utils/http-client';
7
8
  import { prepareQueryParams } from './utils/http-query';
@@ -51,4 +52,10 @@ export class StorageApi {
51
52
  const res = await this.http.post('clear');
52
53
  await throwIfHttpError(res, 'Failed to clear test run:');
53
54
  }
55
+
56
+ async deleteKey(key: string) {
57
+ const body: DeleteValueParams = { key };
58
+ const res = await this.http.post('delete', body);
59
+ await throwIfHttpError(res, `Failed to delete key "${key}":`);
60
+ }
54
61
  }
@@ -112,6 +112,15 @@ export class GlobalCacheClient<S extends DefaultKeysSchema = DefaultKeysSchema>
112
112
  return values as ValueType[];
113
113
  }
114
114
 
115
+ /**
116
+ * Delete a cached value by key, forcing re-computation on the next get() call.
117
+ */
118
+ async delete<K extends StringKeys<S>>(key: K) {
119
+ debugKey(key, `Deleting value...`);
120
+ await this.api.deleteKey(key);
121
+ debugKey(key, `Deleted.`);
122
+ }
123
+
115
124
  /**
116
125
  * Reset current test run:
117
126
  * - clear all non-persistent values
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { GlobalCacheClient, DefaultKeysSchema } from './client/index.js';
2
2
  export { globalConfig, GlobalCacheConfig } from './client/config.js';
3
+ export { logger } from './shared/logger.js';
@@ -33,41 +33,30 @@ export class Getter {
33
33
 
34
34
  // wait if computing
35
35
  if (valueInfo?.state === 'computing') {
36
- valueInfo = await this.testRunStorage.wait(key);
36
+ valueInfo = await this.testRunStorage.waitForComputed(key);
37
37
  return valueInfo.state === 'computed'
38
38
  ? this.handleComputed(valueInfo)
39
39
  : this.handleError(valueInfo);
40
40
  }
41
41
 
42
- // load from persistent storage
43
- if (!valueInfo && ttl) {
44
- valueInfo = await this.persistentStorage.load(key);
45
- if (valueInfo) {
46
- const signatureMismatch = checkSignature(key, valueInfo.sig, sig);
47
- // eslint-disable-next-line max-depth
48
- if (signatureMismatch) {
49
- return this.handleSignatureChanged(valueInfo, sig, signatureMismatch);
50
- }
51
- }
42
+ // no value in memory -- claim the key atomically before touching persistent storage,
43
+ // so concurrent callers for the same key can't all decide to recompute independently
44
+ if (!valueInfo) {
45
+ return this.handleNoValue(key, sig, ttl);
52
46
  }
53
47
 
54
48
  // check expired
55
- if (valueInfo?.state === 'computed' && valueInfo.persistent && ttl) {
49
+ if (valueInfo.state === 'computed' && valueInfo.persistent && ttl) {
56
50
  if (isExpired(valueInfo.computedAt, ttl)) {
57
51
  return this.handleExpired(valueInfo, ttl);
58
52
  }
59
53
  }
60
54
 
61
55
  // normal cache hit
62
- if (valueInfo?.state === 'computed') {
56
+ if (valueInfo.state === 'computed') {
63
57
  return this.handleComputed(valueInfo);
64
58
  }
65
59
 
66
- // no value
67
- if (!valueInfo) {
68
- return this.handleNoValue(key, sig, ttl);
69
- }
70
-
71
60
  return this.handleDefault(valueInfo);
72
61
  }
73
62
 
@@ -86,21 +75,6 @@ export class Getter {
86
75
  return { result: 'error', message: valueInfo.errorMessage || 'Unknown error' };
87
76
  }
88
77
 
89
- private async handleSignatureChanged(
90
- loadedValueInfo: TestRunValueInfo,
91
- newSig: string,
92
- { field }: SignatureMismatch,
93
- ): Promise<GetterCacheMiss> {
94
- await this.updateValueInfo(loadedValueInfo, {
95
- state: 'computing',
96
- sig: newSig,
97
- prevValue: loadedValueInfo.value,
98
- value: undefined,
99
- computedAt: undefined,
100
- });
101
- return { result: 'cache-miss', message: `signature changed: ${field}` };
102
- }
103
-
104
78
  private async handleExpired(valueInfo: TestRunValueInfo, ttl: number): Promise<GetterCacheMiss> {
105
79
  await this.updateValueInfo(valueInfo, {
106
80
  state: 'computing',
@@ -111,9 +85,45 @@ export class Getter {
111
85
  return { result: 'cache-miss', message: `expired: ${ttl}` };
112
86
  }
113
87
 
114
- private async handleNoValue(key: string, sig: string, ttl?: number): Promise<GetterCacheMiss> {
115
- await this.updateValueInfo({ key, state: 'computing', sig, persistent: Boolean(ttl) });
116
- return { result: 'cache-miss', message: 'no cached value' };
88
+ // eslint-disable-next-line visual/complexity, max-statements
89
+ private async handleNoValue(key: string, sig: string, ttl?: number): Promise<GetterResult> {
90
+ const placeholder: TestRunValueInfo = {
91
+ key,
92
+ state: 'computing',
93
+ sig,
94
+ persistent: Boolean(ttl),
95
+ };
96
+ const claimed = this.testRunStorage.claimForComputing(placeholder);
97
+ if (!claimed) {
98
+ const resolved = await this.testRunStorage.waitForComputed(key);
99
+ return resolved.state === 'computed'
100
+ ? this.handleComputed(resolved)
101
+ : this.handleError(resolved);
102
+ }
103
+
104
+ if (!ttl) return { result: 'cache-miss', message: 'no cached value' };
105
+
106
+ // We own the 'computing' slot now, so no other concurrent caller can also decide
107
+ // to recompute this key while we consult persistent storage.
108
+ const persisted = await this.persistentStorage.load(key);
109
+ if (!persisted) return { result: 'cache-miss', message: 'no cached value' };
110
+
111
+ const signatureMismatch = checkSignature(key, persisted.sig, sig);
112
+ if (signatureMismatch) {
113
+ placeholder.prevValue = persisted.value;
114
+ return { result: 'cache-miss', message: `signature changed: ${signatureMismatch.field}` };
115
+ }
116
+
117
+ if (isExpired(persisted.computedAt, ttl)) {
118
+ placeholder.prevValue = persisted.value;
119
+ return { result: 'cache-miss', message: `expired: ${ttl}` };
120
+ }
121
+
122
+ // Persistent value is fresh and valid -- adopt it as computed, update the map entry
123
+ // (already resident via claimForComputing) and notify any waiters.
124
+ Object.assign(placeholder, persisted);
125
+ await this.testRunStorage.save(placeholder, { notify: true });
126
+ return this.handleComputed(placeholder);
117
127
  }
118
128
 
119
129
  private async handleDefault(valueInfo: TestRunValueInfo): Promise<GetterCacheMiss> {
@@ -15,6 +15,7 @@ import { router as routeSet } from './routes/set';
15
15
  import { router as routeGetStale } from './routes/get-stale';
16
16
  import { router as routeGetStaleList } from './routes/get-stale-list';
17
17
  import { router as routeClearTestRun } from './routes/clear';
18
+ import { router as routeDeleteValue } from './routes/delete';
18
19
  import { errorHandler } from './error';
19
20
  import { GlobalCacheServerConfig, resolveConfig, setConfig } from './config';
20
21
  import { startExpressServer, stopExpressServer } from './utils/express';
@@ -24,13 +25,14 @@ export class GlobalCacheServer {
24
25
  private server: http.Server | null = null;
25
26
 
26
27
  constructor() {
27
- this.app.use(express.json());
28
+ this.app.use(express.json({ limit: '10mb' }));
28
29
  this.app.use('/', routeRoot);
29
30
  this.app.use('/', routeGet);
30
31
  this.app.use('/', routeSet);
31
32
  this.app.use('/', routeGetStale);
32
33
  this.app.use('/', routeGetStaleList);
33
34
  this.app.use('/', routeClearTestRun);
35
+ this.app.use('/', routeDeleteValue);
34
36
  // Must be after all other middleware and routes
35
37
  this.app.use(errorHandler);
36
38
  }
@@ -54,6 +56,11 @@ export class GlobalCacheServer {
54
56
  const config = resolveConfig(providedConfig);
55
57
  setConfig(this.app, config);
56
58
  this.server = await startExpressServer(this.app, config.port);
59
+ // unref() so the server does not prevent the Node.js process from exiting
60
+ // naturally when all other work is done (e.g. in CLI mode after tests finish).
61
+ // In VSCode / UI mode the process is kept alive by Playwright's own IPC
62
+ // channels, so the server stays up automatically for subsequent runs.
63
+ this.server.unref();
57
64
  debug(`Starting server: done ${this.localUrl}`);
58
65
  }
59
66
 
@@ -0,0 +1,23 @@
1
+ import { Express, Router } from 'express';
2
+ import { getConfig } from '../config';
3
+ import { getStorage } from '../storage';
4
+
5
+ export const router: ReturnType<typeof Router> = Router();
6
+
7
+ export type DeleteValueParams = {
8
+ key: string;
9
+ };
10
+
11
+ router.post('/run/:runId/delete', async (req, res) => {
12
+ const { runId } = req.params;
13
+ const { key } = req.body as DeleteValueParams;
14
+ const config = getConfig(req.app as Express);
15
+
16
+ const { testRunStorage, persistentStorage } = getStorage(config, runId);
17
+
18
+ const valueInfo = await testRunStorage.load(key);
19
+ await testRunStorage.delete(key);
20
+ if (valueInfo?.persistent) await persistentStorage.delete(key);
21
+
22
+ res.end();
23
+ });
@@ -20,11 +20,37 @@ export class MemoryStorage implements ITestRunStorage {
20
20
  if (notify) this.notify(valueInfo);
21
21
  }
22
22
 
23
+ async delete(key: string) {
24
+ this.values.delete(key);
25
+ }
26
+
23
27
  async clear() {
24
28
  this.values.clear();
25
29
  }
26
30
 
27
- async wait(key: string) {
31
+ /**
32
+ * Atomically claims the key for computing if it is not yet present.
33
+ *
34
+ * Concurrent workers all call `await testRunStorage.load(key)`, which yields the event loop,
35
+ * so all of them can see `undefined` simultaneously. Using async `save()` for the initial
36
+ * write would let every worker return `cache-miss`, compute in parallel, and collide in
37
+ * `setter.set()` — which only accepts a single `'computing'` caller.
38
+ *
39
+ * Because this method has no `await`, Node.js's single-threaded event loop makes
40
+ * `Map.has()` + `Map.set()` atomic. Only the first caller gets `true` (proceeds to compute);
41
+ * all subsequent callers get `false` (and wait).
42
+ */
43
+ claimForComputing(valueInfo: TestRunValueInfo): boolean {
44
+ if (this.values.has(valueInfo.key)) return false;
45
+ this.values.set(valueInfo.key, valueInfo);
46
+ return true;
47
+ }
48
+
49
+ async waitForComputed(key: string): Promise<TestRunValueInfo> {
50
+ // Guard: if notify already fired before we registered, return immediately.
51
+ const existing = this.values.get(key);
52
+ if (existing && existing.state !== 'computing') return existing;
53
+
28
54
  return new Promise<TestRunValueInfo>((resolve) => {
29
55
  const listeners = this.listeners.get(key) || [];
30
56
  listeners.push(resolve);
@@ -3,7 +3,9 @@ import { TestRunValueInfo } from '../../shared/value-info';
3
3
  export type ITestRunStorage = {
4
4
  load(key: string): Promise<TestRunValueInfo | undefined>;
5
5
  save(valueInfo: TestRunValueInfo, options?: { notify?: boolean }): Promise<void>;
6
- wait(key: string): Promise<TestRunValueInfo>;
6
+ delete(key: string): Promise<void>;
7
+ waitForComputed(key: string): Promise<TestRunValueInfo>;
8
+ claimForComputing(valueInfo: TestRunValueInfo): boolean;
7
9
  };
8
10
 
9
11
  export type IPersistentStorage = {