cdk-nextjs 0.7.7 → 0.7.9

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 (53) hide show
  1. package/.jsii +2 -2
  2. package/docs/adapter-runtime.md +1 -1
  3. package/docs/harness-coverage.md +153 -73
  4. package/lib/adapter/adapter.mjs +12 -3
  5. package/lib/adapter/aws-cache-store.d.ts +7 -0
  6. package/lib/adapter/aws-cache-store.js +12 -1
  7. package/lib/adapter/aws-cache-store.test.js +32 -1
  8. package/lib/adapter/cache-handler.d.ts +5 -3
  9. package/lib/adapter/cache-handler.js +16 -10
  10. package/lib/adapter/cache-handler.mjs +103 -26
  11. package/lib/adapter/cache-handler.test.js +44 -1
  12. package/lib/adapter/cache-utils.d.ts +22 -0
  13. package/lib/adapter/cache-utils.js +44 -1
  14. package/lib/adapter/function-groups.js +17 -4
  15. package/lib/adapter/function-groups.test.js +33 -1
  16. package/lib/adapter/memory-cache-handler.d.ts +5 -1
  17. package/lib/adapter/memory-cache-handler.js +6 -2
  18. package/lib/adapter/s3-cache-handler.d.ts +12 -1
  19. package/lib/adapter/s3-cache-handler.js +30 -8
  20. package/lib/adapter/s3-cache-handler.test.js +84 -2
  21. package/lib/adapter/use-cache-common.d.ts +13 -0
  22. package/lib/adapter/use-cache-common.js +22 -6
  23. package/lib/adapter/use-cache-common.test.js +37 -1
  24. package/lib/adapter/use-cache-default-handler.mjs +33 -10
  25. package/lib/adapter/use-cache-remote-handler.mjs +33 -12
  26. package/lib/nextjs-api.js +1 -1
  27. package/lib/nextjs-build/nextjs-build.js +1 -1
  28. package/lib/nextjs-cache.js +1 -1
  29. package/lib/nextjs-compute/nextjs-containers.js +1 -1
  30. package/lib/nextjs-compute/nextjs-functions.js +1 -1
  31. package/lib/nextjs-distribution.js +1 -1
  32. package/lib/nextjs-post-deploy.js +1 -1
  33. package/lib/nextjs-static-assets.js +1 -1
  34. package/lib/root-constructs/nextjs-base-construct.js +1 -1
  35. package/lib/root-constructs/nextjs-global-containers.js +1 -1
  36. package/lib/root-constructs/nextjs-global-functions.js +1 -1
  37. package/lib/root-constructs/nextjs-regional-containers.js +1 -1
  38. package/lib/root-constructs/nextjs-regional-functions.js +1 -1
  39. package/lib/runtime/core.js +3 -1
  40. package/lib/runtime/image-utils.d.ts +8 -9
  41. package/lib/runtime/image-utils.js +16 -1
  42. package/lib/runtime/image-utils.test.js +13 -1
  43. package/lib/runtime/image.js +9 -3
  44. package/lib/runtime/lambda.mjs +50 -15
  45. package/lib/runtime/server.mjs +50 -15
  46. package/lib/runtime/tag-manifest.d.ts +25 -0
  47. package/lib/runtime/tag-manifest.js +37 -2
  48. package/lib/runtime/tag-manifest.test.js +27 -1
  49. package/package.json +3 -3
  50. package/scripts/e2e-deploy.sh +7 -2
  51. package/scripts/e2e-harness/README.md +72 -35
  52. package/scripts/e2e-harness/screen.mjs +148 -7
  53. package/scripts/playwright-install-deps.sh +40 -0
@@ -26,19 +26,21 @@ export default class CdkNextjsCacheHandler implements CacheHandler {
26
26
  /**
27
27
  * Get cache entry
28
28
  * - Build time: Not implemented (build doesn't read cache)
29
- * - Runtime: Try memory first, then S3/DynamoDB
29
+ * - Runtime: Try memory first, then S3/DynamoDB, {@link outsideRender}
30
30
  */
31
31
  get(cacheKey: string, ctx: GetCacheHandlerContext): Promise<CacheHandlerValue | null>;
32
+ private getAtRuntime;
32
33
  /**
33
34
  * Set cache entry
34
35
  * - Build time: Write to local file cache only (or delete if data is null)
35
- * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null)
36
+ * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null),
37
+ * {@link outsideRender}
36
38
  */
37
39
  set(cacheKey: string, data: IncrementalCacheValue | null, ctx: SetCacheHandlerContext): Promise<void>;
38
40
  /**
39
41
  * Revalidate tags
40
42
  * - Build time: Not implemented
41
- * - Runtime: Delegate to S3/DynamoDB handler
43
+ * - Runtime: Delegate to S3/DynamoDB handler, {@link outsideRender}
42
44
  */
43
45
  revalidateTag(tag: string | string[], durations?: {
44
46
  expire?: number;
@@ -47,7 +47,7 @@ class CdkNextjsCacheHandler {
47
47
  }
48
48
  else {
49
49
  this.s3DynamoHandler = CdkNextjsCacheHandler.sharedS3DynamoHandler ??=
50
- new s3_cache_handler_1.S3CacheHandler({ context: options });
50
+ (0, use_cache_common_1.outsideRender)(() => new s3_cache_handler_1.S3CacheHandler({ context: options }));
51
51
  this.memoryHandler = CdkNextjsCacheHandler.sharedMemoryHandler ??=
52
52
  new memory_cache_handler_1.MemoryCacheHandler();
53
53
  }
@@ -55,7 +55,7 @@ class CdkNextjsCacheHandler {
55
55
  /**
56
56
  * Get cache entry
57
57
  * - Build time: Not implemented (build doesn't read cache)
58
- * - Runtime: Try memory first, then S3/DynamoDB
58
+ * - Runtime: Try memory first, then S3/DynamoDB, {@link outsideRender}
59
59
  */
60
60
  async get(cacheKey, ctx) {
61
61
  if (this.isBuildTime) {
@@ -63,6 +63,9 @@ class CdkNextjsCacheHandler {
63
63
  // requires; see {@link LocalFileCacheHandler.get}.
64
64
  return this.localFileHandler.get(cacheKey);
65
65
  }
66
+ return (0, use_cache_common_1.outsideRender)(() => this.getAtRuntime(cacheKey, ctx));
67
+ }
68
+ async getAtRuntime(cacheKey, ctx) {
66
69
  // Runtime: try memory first
67
70
  const memoryResult = await this.memoryHandler.get(cacheKey);
68
71
  // A memory hit is checked against the same tag markers an S3 read is.
@@ -99,7 +102,7 @@ class CdkNextjsCacheHandler {
99
102
  // copied at all: the re-render it asks for writes the fresh entry to
100
103
  // both layers.
101
104
  if (s3Result.lastModified !== -1) {
102
- await this.memoryHandler.set(cacheKey, s3Result.value, s3Result.lastModified);
105
+ await this.memoryHandler.set(cacheKey, s3Result.value, s3Result.lastModified, s3Result.cacheControl);
103
106
  }
104
107
  return s3Result;
105
108
  }
@@ -109,7 +112,8 @@ class CdkNextjsCacheHandler {
109
112
  /**
110
113
  * Set cache entry
111
114
  * - Build time: Write to local file cache only (or delete if data is null)
112
- * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null)
115
+ * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null),
116
+ * {@link outsideRender}
113
117
  */
114
118
  async set(cacheKey, data, ctx) {
115
119
  if (this.isBuildTime) {
@@ -124,14 +128,16 @@ class CdkNextjsCacheHandler {
124
128
  return;
125
129
  }
126
130
  // Runtime: both layers, where `null` is a delete.
127
- this.debug(`Cache ${data ? "write" : "delete"}: ${cacheKey}`);
128
- await this.memoryHandler.set(cacheKey, data);
129
- await this.s3DynamoHandler.set(cacheKey, data, ctx);
131
+ await (0, use_cache_common_1.outsideRender)(async () => {
132
+ this.debug(`Cache ${data ? "write" : "delete"}: ${cacheKey}`);
133
+ await this.memoryHandler.set(cacheKey, data, undefined, (0, cache_utils_1.getCacheControl)(ctx));
134
+ await this.s3DynamoHandler.set(cacheKey, data, ctx);
135
+ });
130
136
  }
131
137
  /**
132
138
  * Revalidate tags
133
139
  * - Build time: Not implemented
134
- * - Runtime: Delegate to S3/DynamoDB handler
140
+ * - Runtime: Delegate to S3/DynamoDB handler, {@link outsideRender}
135
141
  */
136
142
  async revalidateTag(tag, durations) {
137
143
  if (this.isBuildTime) {
@@ -139,7 +145,7 @@ class CdkNextjsCacheHandler {
139
145
  }
140
146
  // Memory hits are checked against the same markers (see `get`), so only
141
147
  // the S3/DynamoDB handler has anything to record.
142
- await this.s3DynamoHandler.revalidateTag(tag, durations);
148
+ await (0, use_cache_common_1.outsideRender)(() => this.s3DynamoHandler.revalidateTag(tag, durations));
143
149
  }
144
150
  /**
145
151
  * Deliberately a no-op. Next.js calls `resetRequestCache` at the start of
@@ -152,4 +158,4 @@ class CdkNextjsCacheHandler {
152
158
  async resetRequestCache() { }
153
159
  }
154
160
  exports.default = CdkNextjsCacheHandler;
155
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2NhY2hlLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7Ozs7O0VBTUU7QUFDRixzREFBc0Q7QUFDdEQsa0RBQTZCO0FBTzdCLCtDQUl1QjtBQUN2Qix5RUFBbUU7QUFDbkUsaUVBQTREO0FBQzVELHlEQUFvRDtBQUNwRCx5REFBa0Q7QUFFbEQ7O0dBRUc7QUFDSCxNQUFxQixxQkFBcUI7SUFDeEM7Ozs7Ozs7OztPQVNHO0lBQ0ssTUFBTSxDQUFDLG1CQUFtQixHQUE4QixJQUFJLENBQUM7SUFDN0QsTUFBTSxDQUFDLHFCQUFxQixHQUEwQixJQUFJLENBQUM7SUFFbEQsV0FBVyxHQUFHLElBQUEsK0JBQVksR0FBRSxDQUFDO0lBQzdCLEtBQUssR0FBRyxJQUFBLGVBQVEsRUFBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBRTNFLDBCQUEwQjtJQUNsQixnQkFBZ0IsQ0FBeUI7SUFFakQsb0RBQW9EO0lBQzVDLGFBQWEsQ0FBc0I7SUFDbkMsZUFBZSxDQUFrQjtJQUV6QyxZQUFZLE9BQTRCO1FBQ3RDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLGdEQUFxQixFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLEtBQUssQ0FDUiwrQkFBK0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxFQUFFLENBQ3JFLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxlQUFlLEdBQUcscUJBQXFCLENBQUMscUJBQXFCO2dCQUNoRSxJQUFJLGlDQUFjLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsYUFBYSxHQUFHLHFCQUFxQixDQUFDLG1CQUFtQjtnQkFDNUQsSUFBSSx5Q0FBa0IsRUFB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S0FBSyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzlELE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzdDLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxhQUFhLENBQ2pCLEdBQXNCLEVBQ3RCLFNBQStCO1FBRS9CLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLE9BQU87UUFDVCxDQUFDO1FBRUQsd0VBQXdFO1FBQ3hFLGtEQUFrRDtRQUNsRCxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsS0FBbUIsQ0FBQzs7QUFoSzdDLHdDQWlLQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gIE5leHQuanMgQ3VzdG9tIENhY2hlIEhhbmRsZXIuIFNlZTogaHR0cHM6Ly9uZXh0anMub3JnL2RvY3MvYXBwL2FwaS1yZWZlcmVuY2UvbmV4dC1jb25maWctanMvaW5jcmVtZW50YWxDYWNoZUhhbmRsZXJQYXRoXG4gIFxuICBPcmNoZXN0cmF0b3IgY2FjaGUgaGFuZGxlciB0aGF0IGNvbmRpdGlvbmFsbHkgdXNlcyBkaWZmZXJlbnQgY2FjaGluZyBzdHJhdGVnaWVzOlxuICAtIEJ1aWxkIHRpbWU6IExvY2FsRmlsZUNhY2hlSGFuZGxlciBmb3IgcHJlLWNhY2hpbmdcbiAgLSBSdW50aW1lOiBNZW1vcnlDYWNoZUhhbmRsZXIgKGZhc3QpICsgUzNEeW5hbW9DYWNoZUhhbmRsZXIgKHBlcnNpc3RlbnQpXG4qL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgZ2V0RGVidWcgZnJvbSBcImRlYnVnXCI7XG5pbXBvcnQge1xuICBDYWNoZUhhbmRsZXIsXG4gIENhY2hlSGFuZGxlclZhbHVlLFxuICBDYWNoZUhhbmRsZXJDb250ZXh0LFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9saWIvaW5jcmVtZW50YWwtY2FjaGVcIjtcbmltcG9ydCB0eXBlIHsgSW5jcmVtZW50YWxDYWNoZVZhbHVlIH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvcmVzcG9uc2UtY2FjaGVcIjtcbmltcG9ydCB7XG4gIEdldENhY2hlSGFuZGxlckNvbnRleHQsXG4gIGdldFRhZ3MsXG4gIFNldENhY2hlSGFuZGxlckNvbnRleHQsXG59IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5pbXBvcnQgeyBMb2NhbEZpbGVDYWNoZUhhbmRsZXIgfSBmcm9tIFwiLi9sb2NhbC1maWxlLWNhY2hlLWhhbmRsZXJcIjtcbmltcG9ydCB7IE1lbW9yeUNhY2hlSGFuZGxlciB9IGZyb20gXCIuL21lbW9yeS1jYWNoZS1oYW5kbGVyXCI7XG5pbXBvcnQgeyBTM0NhY2hlSGFuZGxlciB9IGZyb20gXCIuL3MzLWNhY2hlLWhhbmRsZXJcIjtcbmltcG9ydCB7IGlzQnVpbGRQaGFzZSB9IGZyb20gXCIuL3VzZS1jYWNoZS1jb21tb25cIjtcblxuLyoqXG4gKiBPcmNoZXN0cmF0b3IgY2FjaGUgaGFuZGxlciB0aGF0IGNvbmRpdGlvbmFsbHkgaW5zdGFudGlhdGVzIGhhbmRsZXJzIGJhc2VkIG9uIGVudmlyb25tZW50XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENka05leHRqc0NhY2hlSGFuZGxlciBpbXBsZW1lbnRzIENhY2hlSGFuZGxlciB7XG4gIC8qKlxuICAgKiBTaGFyZWQgc2luZ2xldG9uIGhhbmRsZXJzIGZvciBydW50aW1lLlxuICAgKlxuICAgKiBOZXh0LmpzIGNyZWF0ZXMgbXVsdGlwbGUgY2FjaGUgaGFuZGxlciBpbnN0YW5jZXMgKG9uZSBlYWNoIGZvciBBUFBfUEFHRSwgQVBQX1JPVVRFLCBGRVRDSCwgZXRjKS5cbiAgICogVXNpbmcgc2luZ2xldG9uIHBhdHRlcm4gcHJvdmlkZXM6XG4gICAqIC0gU2luZ2xlIFMzIGNsaWVudCBjb25uZWN0aW9uIHBvb2wgc2hhcmVkIGFjcm9zcyBhbGwgY2FjaGUgdHlwZXNcbiAgICogLSBVbmlmaWVkIG1lbW9yeSBjYWNoZSBhY2Nlc3NpYmxlIGJ5IGFsbCBpbnN0YW5jZXMgKGNhY2hlIGhpdHMgYmVuZWZpdCBhbGwpXG4gICAqIC0gTG93ZXIgbWVtb3J5IGZvb3RwcmludCBhbmQgZmFzdGVyIGluaXRpYWxpemF0aW9uXG4gICAqIC0gU2FtZSBDYWNoZUhhbmRsZXJDb250ZXh0IGZvciBhbGwgaW5zdGFuY2VzLCBzbyBubyBjb25maWd1cmF0aW9uIGxvc3NcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHNoYXJlZE1lbW9yeUhhbmRsZXI6IE1lbW9yeUNhY2hlSGFuZGxlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0YXRpYyBzaGFyZWRTM0R5bmFtb0hhbmRsZXI6IFMzQ2FjaGVIYW5kbGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpc0J1aWxkVGltZSA9IGlzQnVpbGRQaGFzZSgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYnVnID0gZ2V0RGVidWcoXCJjZGstbmV4dGpzOmNhY2hlLWhhbmRsZXI6b3JjaGVzdHJhdG9yXCIpO1xuXG4gIC8vIFNldCBvbmx5IGF0IGJ1aWxkIHRpbWUuXG4gIHByaXZhdGUgbG9jYWxGaWxlSGFuZGxlciE6IExvY2FsRmlsZUNhY2hlSGFuZGxlcjtcblxuICAvLyBTZXQgb25seSBhdCBydW50aW1lLCBzaGFyZWQgYWNyb3NzIGFsbCBpbnN0YW5jZXMuXG4gIHByaXZhdGUgbWVtb3J5SGFuZGxlciE6IE1lbW9yeUNhY2hlSGFuZGxlcjtcbiAgcHJpdmF0ZSBzM0R5bmFtb0hhbmRsZXIhOiBTM0NhY2hlSGFuZGxlcjtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBDYWNoZUhhbmRsZXJDb250ZXh0KSB7XG4gICAgaWYgKHRoaXMuaXNCdWlsZFRpbWUpIHtcbiAgICAgIHRoaXMubG9jYWxGaWxlSGFuZGxlciA9IG5ldyBMb2NhbEZpbGVDYWNoZUhhbmRsZXIoKTtcbiAgICAgIHRoaXMuZGVidWcoXG4gICAgICAgIGBCdWlsZC10aW1lIGNhY2hlIGRpcmVjdG9yeTogJHt0aGlzLmxvY2FsRmlsZUhhbmRsZXIuZ2V0Q2FjaGVEaXIoKX1gLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zM0R5bmFtb0hhbmRsZXIgPSBDZGtOZXh0anNDYWNoZUhhbmRsZXIuc2hhcmVkUzNEeW5hbW9IYW5kbGVyID8/PVxuICAgICAgICBuZXcgUzNDYWNoZUhhbmRsZXIoeyBjb250ZXh0OiBvcHRpb25zIH0pO1xuICAgICAgdGhpcy5tZW1vcnlIYW5kbGVyID0gQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyLnNoYXJlZE1lbW9yeUhhbmRsZXIgPz89XG4gICAgICAgIG5ldyBNZW1vcnlDYWNoZUhhbmRsZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIGVudHJ5XG4gICAqIC0gQnVpbGQgdGltZTogTm90IGltcGxlbWVudGVkIChidWlsZCBkb2Vzbid0IHJlYWQgY2FjaGUpXG4gICAqIC0gUnVudGltZTogVHJ5IG1lbW9yeSBmaXJzdCwgdGhlbiBTMy9EeW5hbW9EQlxuICAgKi9cbiAgYXN5bmMgZ2V0KFxuICAgIGNhY2hlS2V5OiBzdHJpbmcsXG4gICAgY3R4OiBHZXRDYWNoZUhhbmRsZXJDb250ZXh0LFxuICApOiBQcm9taXNlPENhY2hlSGFuZGxlclZhbHVlIHwgbnVsbD4ge1xuICAgIGlmICh0aGlzLmlzQnVpbGRUaW1lKSB7XG4gICAgICAvLyBSZWFkcyBiYWNrIHdoYXQgdGhpcyBidWlsZCB3cm90ZSwgd2hpY2ggYGNhY2hlQ29tcG9uZW50c2AgcHJlcmVuZGVyaW5nXG4gICAgICAvLyByZXF1aXJlczsgc2VlIHtAbGluayBMb2NhbEZpbGVDYWNoZUhhbmRsZXIuZ2V0fS5cbiAgICAgIHJldHVybiB0aGlzLmxvY2FsRmlsZUhhbmRsZXIuZ2V0KGNhY2hlS2V5KTtcbiAgICB9XG5cbiAgICAvLyBSdW50aW1lOiB0cnkgbWVtb3J5IGZpcnN0XG4gICAgY29uc3QgbWVtb3J5UmVzdWx0ID0gYXdhaXQgdGhpcy5tZW1vcnlIYW5kbGVyLmdldChjYWNoZUtleSk7XG4gICAgLy8gQSBtZW1vcnkgaGl0IGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgc2FtZSB0YWcgbWFya2VycyBhbiBTMyByZWFkIGlzLlxuICAgIC8vIGByZXZhbGlkYXRlVGFnYCBjYW4gb25seSBjbGVhciB0aGUgbWVtb3J5IG9mIHRoZSBpbnN0YW5jZSB0aGF0IHJhbiBpdCxcbiAgICAvLyBzbyBza2lwcGluZyB0aGUgY2hlY2sgbGVmdCBldmVyeSBvdGhlciBpbnN0YW5jZSBhbnN3ZXJpbmcgZnJvbSBtZW1vcnlcbiAgICAvLyBmb3IgdGhlIHdob2xlIG1lbW9yeSBUVEwgLSBhbmQgQ2xvdWRGcm9udCwgd2hvc2UgY29weSB0aGF0XG4gICAgLy8gYHJldmFsaWRhdGVUYWdgIGhhZCBqdXN0IGludmFsaWRhdGVkLCBjYWNoZWQgdGhlIHN0YWxlIHBhZ2UgYWdhaW4uXG4gICAgLy8gVGhlIGNoZWNrIGlzIG9uZSBEeW5hbW9EQiBgQmF0Y2hHZXRJdGVtYDsgd2hhdCB0aGUgbWVtb3J5IGxheWVyIHN0aWxsXG4gICAgLy8gc2F2ZXMgaXMgdGhlIFMzIHJlYWQgYW5kIHRoZSBwYXJzZSBvZiB0aGUgYm9keS4gQSByZXZhbGlkYXRlZCBlbnRyeSBpc1xuICAgIC8vIGRyb3BwZWQgYW5kIHJlYWQgZnJvbSBTMywgd2hpY2ggaGFuZHMgaXQgYmFjayBleHBpcmVkIG9yIGFzIGEgbWlzcy5cbiAgICBpZiAoXG4gICAgICBtZW1vcnlSZXN1bHQgJiZcbiAgICAgIChhd2FpdCB0aGlzLnMzRHluYW1vSGFuZGxlci5pc1JldmFsaWRhdGVkKFxuICAgICAgICB7XG4gICAgICAgICAgbGFzdE1vZGlmaWVkOiBtZW1vcnlSZXN1bHQubGFzdE1vZGlmaWVkLFxuICAgICAgICAgIHZhbHVlOiBtZW1vcnlSZXN1bHQudmFsdWUsXG4gICAgICAgIH0sXG4gICAgICAgIGN0eCxcbiAgICAgICAgY2FjaGVLZXksXG4gICAgICApKVxuICAgICkge1xuICAgICAgdGhpcy5kZWJ1ZyhgTWVtb3J5IGNhY2hlIFJFVkFMSURBVEVEOiAke2NhY2hlS2V5fWApO1xuICAgICAgYXdhaXQgdGhpcy5tZW1vcnlIYW5kbGVyLnNldChjYWNoZUtleSwgbnVsbCk7XG4gICAgfSBlbHNlIGlmIChtZW1vcnlSZXN1bHQpIHtcbiAgICAgIHRoaXMuZGVidWcoYE1lbW9yeSBjYWNoZSBISVQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICByZXR1cm4gbWVtb3J5UmVzdWx0O1xuICAgIH1cblxuICAgIC8vIE1lbW9yeSBtaXNzIC0gdHJ5IFMzL0R5bmFtb0RCXG4gICAgY29uc3QgczNSZXN1bHQgPSBhd2FpdCB0aGlzLnMzRHluYW1vSGFuZGxlci5nZXQoY2FjaGVLZXksIGN0eCk7XG4gICAgaWYgKHMzUmVzdWx0KSB7XG4gICAgICB0aGlzLmRlYnVnKGBTMyBjYWNoZSBISVQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICAvLyBQcm9tb3RlZCB3aXRoIHRoZSBTMyBlbnRyeSdzIG93biBgbGFzdE1vZGlmaWVkYCwgbm90IHRoZSB0aW1lIG9mIHRoZVxuICAgICAgLy8gY29weTogTmV4dC5qcyBhZ2VzIHRoZSBlbnRyeSBmcm9tIGl0IGZvciB0aW1lLWJhc2VkIHJldmFsaWRhdGlvbiwgYW5kXG4gICAgICAvLyB0aGUgdGFnIG1hcmtlcnMgYXJlIGNvbXBhcmVkIGFnYWluc3QgaXQgdG9vLiBTdGFtcGluZyBgRGF0ZS5ub3coKWBcbiAgICAgIC8vIG1hZGUgYW4gZW50cnkgdGhhdCB3YXMgZHVlIGZvciByZWdlbmVyYXRpb24gbG9vayBmcmVzaGx5IHJlbmRlcmVkLFxuICAgICAgLy8gYW5kIG9uZSBhIHNvZnQgYHJldmFsaWRhdGVUYWdgIGhhZCBtYWRlIHN0YWxlIGxvb2sgbmV3ZXIgdGhhbiB0aGVcbiAgICAgIC8vIHN0YWxlIG1hcmssIHNvIG1lbW9yeSBoaXRzIHNlcnZlZCBpdCBhcyBmcmVzaCBmb3IgdGhlIHdob2xlIG1lbW9yeVxuICAgICAgLy8gVFRMLiBBbiBlbnRyeSBhIHRhZyByZXZhbGlkYXRpb24gZXhwaXJlZCAoYGxhc3RNb2RpZmllZDogLTFgKSBpcyBub3RcbiAgICAgIC8vIGNvcGllZCBhdCBhbGw6IHRoZSByZS1yZW5kZXIgaXQgYXNrcyBmb3Igd3JpdGVzIHRoZSBmcmVzaCBlbnRyeSB0b1xuICAgICAgLy8gYm90aCBsYXllcnMuXG4gICAgICBpZiAoczNSZXN1bHQubGFzdE1vZGlmaWVkICE9PSAtMSkge1xuICAgICAgICBhd2FpdCB0aGlzLm1lbW9yeUhhbmRsZXIuc2V0KFxuICAgICAgICAgIGNhY2hlS2V5LFxuICAgICAgICAgIHMzUmVzdWx0LnZhbHVlLFxuICAgICAgICAgIHMzUmVzdWx0Lmxhc3RNb2RpZmllZCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzM1Jlc3VsdDtcbiAgICB9XG5cbiAgICB0aGlzLmRlYnVnKGBDYWNoZSBNSVNTOiAke2NhY2hlS2V5fWApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBjYWNoZSBlbnRyeVxuICAgKiAtIEJ1aWxkIHRpbWU6IFdyaXRlIHRvIGxvY2FsIGZpbGUgY2FjaGUgb25seSAob3IgZGVsZXRlIGlmIGRhdGEgaXMgbnVsbClcbiAgICogLSBSdW50aW1lOiBXcml0ZSB0byBib3RoIG1lbW9yeSBhbmQgUzMvRHluYW1vREIgKG9yIGRlbGV0ZSBpZiBkYXRhIGlzIG51bGwpXG4gICAqL1xuICBhc3luYyBzZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBkYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgfCBudWxsLFxuICAgIGN0eDogU2V0Q2FjaGVIYW5kbGVyQ29udGV4dCxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNCdWlsZFRpbWUpIHtcbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9jYWxGaWxlSGFuZGxlci5zZXQoY2FjaGVLZXksIGRhdGEsIGdldFRhZ3MoY3R4KSk7XG4gICAgICAgIHRoaXMuZGVidWcoYEJ1aWxkIGNhY2hlIHdyaXRlOiAke2NhY2hlS2V5fWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRGVsZXRlIG5vdCBpbXBsZW1lbnRlZCBmb3IgbG9jYWwgZmlsZSBjYWNoZSAoYnVpbGQtdGltZSBvbmx5IGNyZWF0ZXMgZmlsZXMpXG4gICAgICAgIHRoaXMuZGVidWcoYEJ1aWxkIGNhY2hlIGRlbGV0ZSBpZ25vcmVkOiAke2NhY2hlS2V5fWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSdW50aW1lOiBib3RoIGxheWVycywgd2hlcmUgYG51bGxgIGlzIGEgZGVsZXRlLlxuICAgIHRoaXMuZGVidWcoYENhY2hlICR7ZGF0YSA/IFwid3JpdGVcIiA6IFwiZGVsZXRlXCJ9OiAke2NhY2hlS2V5fWApO1xuICAgIGF3YWl0IHRoaXMubWVtb3J5SGFuZGxlci5zZXQoY2FjaGVLZXksIGRhdGEpO1xuICAgIGF3YWl0IHRoaXMuczNEeW5hbW9IYW5kbGVyLnNldChjYWNoZUtleSwgZGF0YSwgY3R4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZhbGlkYXRlIHRhZ3NcbiAgICogLSBCdWlsZCB0aW1lOiBOb3QgaW1wbGVtZW50ZWRcbiAgICogLSBSdW50aW1lOiBEZWxlZ2F0ZSB0byBTMy9EeW5hbW9EQiBoYW5kbGVyXG4gICAqL1xuICBhc3luYyByZXZhbGlkYXRlVGFnKFxuICAgIHRhZzogc3RyaW5nIHwgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zPzogeyBleHBpcmU/OiBudW1iZXIgfSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNCdWlsZFRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBNZW1vcnkgaGl0cyBhcmUgY2hlY2tlZCBhZ2FpbnN0IHRoZSBzYW1lIG1hcmtlcnMgKHNlZSBgZ2V0YCksIHNvIG9ubHlcbiAgICAvLyB0aGUgUzMvRHluYW1vREIgaGFuZGxlciBoYXMgYW55dGhpbmcgdG8gcmVjb3JkLlxuICAgIGF3YWl0IHRoaXMuczNEeW5hbW9IYW5kbGVyLnJldmFsaWRhdGVUYWcodGFnLCBkdXJhdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGliZXJhdGVseSBhIG5vLW9wLiBOZXh0LmpzIGNhbGxzIGByZXNldFJlcXVlc3RDYWNoZWAgYXQgdGhlIHN0YXJ0IG9mXG4gICAqIGV2ZXJ5IHJlcXVlc3QgKGBiYXNlLXNlcnZlcmAsIGBhcHAtcGFnZWAsIGBhcHAtcm91dGVgKSwgYW5kIGl0cyBvd25cbiAgICogYEZpbGVTeXN0ZW1DYWNoZWAgLSB3aG9zZSBMUlUgaXMgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cyB0aGUgc2FtZSB3YXkgdGhlXG4gICAqIG1lbW9yeSBsYXllciBpcyAtIGxlYXZlcyBpdCBlbXB0eTogdGhlIGhvb2sgaXMgZm9yIHN0YXRlIHNjb3BlZCB0byBvbmVcbiAgICogcmVxdWVzdCwgYW5kIG5vdGhpbmcgaGVyZSBpcy4gQ2xlYXJpbmcgdGhlIG1lbW9yeSBsYXllciBpbiBpdCBtZWFudCBub1xuICAgKiBlbnRyeSBldmVyIHN1cnZpdmVkIHRvIGEgc2Vjb25kIHJlcXVlc3QsIHNvIGV2ZXJ5IHJlYWQgd2VudCB0byBTMy5cbiAgICovXG4gIGFzeW5jIHJlc2V0UmVxdWVzdENhY2hlKCk6IFByb21pc2U8dm9pZD4ge31cbn1cbiJdfQ==
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2NhY2hlLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7Ozs7O0VBTUU7QUFDRixzREFBc0Q7QUFDdEQsa0RBQTZCO0FBTzdCLCtDQUt1QjtBQUN2Qix5RUFBbUU7QUFDbkUsaUVBQTREO0FBQzVELHlEQUFvRDtBQUNwRCx5REFBaUU7QUFFakU7O0dBRUc7QUFDSCxNQUFxQixxQkFBcUI7SUFDeEM7Ozs7Ozs7OztPQVNHO0lBQ0ssTUFBTSxDQUFDLG1CQUFtQixHQUE4QixJQUFJLENBQUM7SUFDN0QsTUFBTSxDQUFDLHFCQUFxQixHQUEwQixJQUFJLENBQUM7SUFFbEQsV0FBVyxHQUFHLElBQUEsK0JBQVksR0FBRSxDQUFDO0lBQzdCLEtBQUssR0FBRyxJQUFBLGVBQVEsRUFBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBRTNFLDBCQUEwQjtJQUNsQixnQkFBZ0IsQ0FBeUI7SUFFakQsb0RBQW9EO0lBQzVDLGFBQWEsQ0FBc0I7SUFDbkMsZUFBZSxDQUFrQjtJQUV6QyxZQUFZLE9BQTRCO1FBQ3RDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLGdEQUFxQixFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLEtBQUssQ0FDUiwrQkFBK0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxFQUFFLENBQ3JFLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxlQUFlLEdBQUcscUJBQXFCLENBQUMscUJBQXFCO2dCQUNoRSxJQUFBLGdDQUFhLEVBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxpQ0FBYyxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNoRSxJQUFJLENBQUMsYUFBYSxHQUFHLHFCQUFx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c3RvbSBDYWNoZSBIYW5kbGVyLiBTZWU6IGh0dHBzOi8vbmV4dGpzLm9yZy9kb2NzL2FwcC9hcGktcmVmZXJlbmNlL25leHQtY29uZmlnLWpzL2luY3JlbWVudGFsQ2FjaGVIYW5kbGVyUGF0aFxuICBcbiAgT3JjaGVzdHJhdG9yIGNhY2hlIGhhbmRsZXIgdGhhdCBjb25kaXRpb25hbGx5IHVzZXMgZGlmZmVyZW50IGNhY2hpbmcgc3RyYXRlZ2llczpcbiAgLSBCdWlsZCB0aW1lOiBMb2NhbEZpbGVDYWNoZUhhbmRsZXIgZm9yIHByZS1jYWNoaW5nXG4gIC0gUnVudGltZTogTWVtb3J5Q2FjaGVIYW5kbGVyIChmYXN0KSArIFMzRHluYW1vQ2FjaGVIYW5kbGVyIChwZXJzaXN0ZW50KVxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IGdldERlYnVnIGZyb20gXCJkZWJ1Z1wiO1xuaW1wb3J0IHtcbiAgQ2FjaGVIYW5kbGVyLFxuICBDYWNoZUhhbmRsZXJWYWx1ZSxcbiAgQ2FjaGVIYW5kbGVyQ29udGV4dCxcbn0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvbGliL2luY3JlbWVudGFsLWNhY2hlXCI7XG5pbXBvcnQgdHlwZSB7IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5pbXBvcnQge1xuICBHZXRDYWNoZUhhbmRsZXJDb250ZXh0LFxuICBnZXRDYWNoZUNvbnRyb2wsXG4gIGdldFRhZ3MsXG4gIFNldENhY2hlSGFuZGxlckNvbnRleHQsXG59IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5pbXBvcnQgeyBMb2NhbEZpbGVDYWNoZUhhbmRsZXIgfSBmcm9tIFwiLi9sb2NhbC1maWxlLWNhY2hlLWhhbmRsZXJcIjtcbmltcG9ydCB7IE1lbW9yeUNhY2hlSGFuZGxlciB9IGZyb20gXCIuL21lbW9yeS1jYWNoZS1oYW5kbGVyXCI7XG5pbXBvcnQgeyBTM0NhY2hlSGFuZGxlciB9IGZyb20gXCIuL3MzLWNhY2hlLWhhbmRsZXJcIjtcbmltcG9ydCB7IGlzQnVpbGRQaGFzZSwgb3V0c2lkZVJlbmRlciB9IGZyb20gXCIuL3VzZS1jYWNoZS1jb21tb25cIjtcblxuLyoqXG4gKiBPcmNoZXN0cmF0b3IgY2FjaGUgaGFuZGxlciB0aGF0IGNvbmRpdGlvbmFsbHkgaW5zdGFudGlhdGVzIGhhbmRsZXJzIGJhc2VkIG9uIGVudmlyb25tZW50XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENka05leHRqc0NhY2hlSGFuZGxlciBpbXBsZW1lbnRzIENhY2hlSGFuZGxlciB7XG4gIC8qKlxuICAgKiBTaGFyZWQgc2luZ2xldG9uIGhhbmRsZXJzIGZvciBydW50aW1lLlxuICAgKlxuICAgKiBOZXh0LmpzIGNyZWF0ZXMgbXVsdGlwbGUgY2FjaGUgaGFuZGxlciBpbnN0YW5jZXMgKG9uZSBlYWNoIGZvciBBUFBfUEFHRSwgQVBQX1JPVVRFLCBGRVRDSCwgZXRjKS5cbiAgICogVXNpbmcgc2luZ2xldG9uIHBhdHRlcm4gcHJvdmlkZXM6XG4gICAqIC0gU2luZ2xlIFMzIGNsaWVudCBjb25uZWN0aW9uIHBvb2wgc2hhcmVkIGFjcm9zcyBhbGwgY2FjaGUgdHlwZXNcbiAgICogLSBVbmlmaWVkIG1lbW9yeSBjYWNoZSBhY2Nlc3NpYmxlIGJ5IGFsbCBpbnN0YW5jZXMgKGNhY2hlIGhpdHMgYmVuZWZpdCBhbGwpXG4gICAqIC0gTG93ZXIgbWVtb3J5IGZvb3RwcmludCBhbmQgZmFzdGVyIGluaXRpYWxpemF0aW9uXG4gICAqIC0gU2FtZSBDYWNoZUhhbmRsZXJDb250ZXh0IGZvciBhbGwgaW5zdGFuY2VzLCBzbyBubyBjb25maWd1cmF0aW9uIGxvc3NcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHNoYXJlZE1lbW9yeUhhbmRsZXI6IE1lbW9yeUNhY2hlSGFuZGxlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0YXRpYyBzaGFyZWRTM0R5bmFtb0hhbmRsZXI6IFMzQ2FjaGVIYW5kbGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpc0J1aWxkVGltZSA9IGlzQnVpbGRQaGFzZSgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYnVnID0gZ2V0RGVidWcoXCJjZGstbmV4dGpzOmNhY2hlLWhhbmRsZXI6b3JjaGVzdHJhdG9yXCIpO1xuXG4gIC8vIFNldCBvbmx5IGF0IGJ1aWxkIHRpbWUuXG4gIHByaXZhdGUgbG9jYWxGaWxlSGFuZGxlciE6IExvY2FsRmlsZUNhY2hlSGFuZGxlcjtcblxuICAvLyBTZXQgb25seSBhdCBydW50aW1lLCBzaGFyZWQgYWNyb3NzIGFsbCBpbnN0YW5jZXMuXG4gIHByaXZhdGUgbWVtb3J5SGFuZGxlciE6IE1lbW9yeUNhY2hlSGFuZGxlcjtcbiAgcHJpdmF0ZSBzM0R5bmFtb0hhbmRsZXIhOiBTM0NhY2hlSGFuZGxlcjtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBDYWNoZUhhbmRsZXJDb250ZXh0KSB7XG4gICAgaWYgKHRoaXMuaXNCdWlsZFRpbWUpIHtcbiAgICAgIHRoaXMubG9jYWxGaWxlSGFuZGxlciA9IG5ldyBMb2NhbEZpbGVDYWNoZUhhbmRsZXIoKTtcbiAgICAgIHRoaXMuZGVidWcoXG4gICAgICAgIGBCdWlsZC10aW1lIGNhY2hlIGRpcmVjdG9yeTogJHt0aGlzLmxvY2FsRmlsZUhhbmRsZXIuZ2V0Q2FjaGVEaXIoKX1gLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zM0R5bmFtb0hhbmRsZXIgPSBDZGtOZXh0anNDYWNoZUhhbmRsZXIuc2hhcmVkUzNEeW5hbW9IYW5kbGVyID8/PVxuICAgICAgICBvdXRzaWRlUmVuZGVyKCgpID0+IG5ldyBTM0NhY2hlSGFuZGxlcih7IGNvbnRleHQ6IG9wdGlvbnMgfSkpO1xuICAgICAgdGhpcy5tZW1vcnlIYW5kbGVyID0gQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyLnNoYXJlZE1lbW9yeUhhbmRsZXIgPz89XG4gICAgICAgIG5ldyBNZW1vcnlDYWNoZUhhbmRsZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIGVudHJ5XG4gICAqIC0gQnVpbGQgdGltZTogTm90IGltcGxlbWVudGVkIChidWlsZCBkb2Vzbid0IHJlYWQgY2FjaGUpXG4gICAqIC0gUnVudGltZTogVHJ5IG1lbW9yeSBmaXJzdCwgdGhlbiBTMy9EeW5hbW9EQiwge0BsaW5rIG91dHNpZGVSZW5kZXJ9XG4gICAqL1xuICBhc3luYyBnZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBjdHg6IEdldENhY2hlSGFuZGxlckNvbnRleHQsXG4gICk6IFByb21pc2U8Q2FjaGVIYW5kbGVyVmFsdWUgfCBudWxsPiB7XG4gICAgaWYgKHRoaXMuaXNCdWlsZFRpbWUpIHtcbiAgICAgIC8vIFJlYWRzIGJhY2sgd2hhdCB0aGlzIGJ1aWxkIHdyb3RlLCB3aGljaCBgY2FjaGVDb21wb25lbnRzYCBwcmVyZW5kZXJpbmdcbiAgICAgIC8vIHJlcXVpcmVzOyBzZWUge0BsaW5rIExvY2FsRmlsZUNhY2hlSGFuZGxlci5nZXR9LlxuICAgICAgcmV0dXJuIHRoaXMubG9jYWxGaWxlSGFuZGxlci5nZXQoY2FjaGVLZXkpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0c2lkZVJlbmRlcigoKSA9PiB0aGlzLmdldEF0UnVudGltZShjYWNoZUtleSwgY3R4KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEF0UnVudGltZShcbiAgICBjYWNoZUtleTogc3RyaW5nLFxuICAgIGN0eDogR2V0Q2FjaGVIYW5kbGVyQ29udGV4dCxcbiAgKTogUHJvbWlzZTxDYWNoZUhhbmRsZXJWYWx1ZSB8IG51bGw+IHtcbiAgICAvLyBSdW50aW1lOiB0cnkgbWVtb3J5IGZpcnN0XG4gICAgY29uc3QgbWVtb3J5UmVzdWx0ID0gYXdhaXQgdGhpcy5tZW1vcnlIYW5kbGVyLmdldChjYWNoZUtleSk7XG4gICAgLy8gQSBtZW1vcnkgaGl0IGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgc2FtZSB0YWcgbWFya2VycyBhbiBTMyByZWFkIGlzLlxuICAgIC8vIGByZXZhbGlkYXRlVGFnYCBjYW4gb25seSBjbGVhciB0aGUgbWVtb3J5IG9mIHRoZSBpbnN0YW5jZSB0aGF0IHJhbiBpdCxcbiAgICAvLyBzbyBza2lwcGluZyB0aGUgY2hlY2sgbGVmdCBldmVyeSBvdGhlciBpbnN0YW5jZSBhbnN3ZXJpbmcgZnJvbSBtZW1vcnlcbiAgICAvLyBmb3IgdGhlIHdob2xlIG1lbW9yeSBUVEwgLSBhbmQgQ2xvdWRGcm9udCwgd2hvc2UgY29weSB0aGF0XG4gICAgLy8gYHJldmFsaWRhdGVUYWdgIGhhZCBqdXN0IGludmFsaWRhdGVkLCBjYWNoZWQgdGhlIHN0YWxlIHBhZ2UgYWdhaW4uXG4gICAgLy8gVGhlIGNoZWNrIGlzIG9uZSBEeW5hbW9EQiBgQmF0Y2hHZXRJdGVtYDsgd2hhdCB0aGUgbWVtb3J5IGxheWVyIHN0aWxsXG4gICAgLy8gc2F2ZXMgaXMgdGhlIFMzIHJlYWQgYW5kIHRoZSBwYXJzZSBvZiB0aGUgYm9keS4gQSByZXZhbGlkYXRlZCBlbnRyeSBpc1xuICAgIC8vIGRyb3BwZWQgYW5kIHJlYWQgZnJvbSBTMywgd2hpY2ggaGFuZHMgaXQgYmFjayBleHBpcmVkIG9yIGFzIGEgbWlzcy5cbiAgICBpZiAoXG4gICAgICBtZW1vcnlSZXN1bHQgJiZcbiAgICAgIChhd2FpdCB0aGlzLnMzRHluYW1vSGFuZGxlci5pc1JldmFsaWRhdGVkKFxuICAgICAgICB7XG4gICAgICAgICAgbGFzdE1vZGlmaWVkOiBtZW1vcnlSZXN1bHQubGFzdE1vZGlmaWVkLFxuICAgICAgICAgIHZhbHVlOiBtZW1vcnlSZXN1bHQudmFsdWUsXG4gICAgICAgIH0sXG4gICAgICAgIGN0eCxcbiAgICAgICAgY2FjaGVLZXksXG4gICAgICApKVxuICAgICkge1xuICAgICAgdGhpcy5kZWJ1ZyhgTWVtb3J5IGNhY2hlIFJFVkFMSURBVEVEOiAke2NhY2hlS2V5fWApO1xuICAgICAgYXdhaXQgdGhpcy5tZW1vcnlIYW5kbGVyLnNldChjYWNoZUtleSwgbnVsbCk7XG4gICAgfSBlbHNlIGlmIChtZW1vcnlSZXN1bHQpIHtcbiAgICAgIHRoaXMuZGVidWcoYE1lbW9yeSBjYWNoZSBISVQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICByZXR1cm4gbWVtb3J5UmVzdWx0O1xuICAgIH1cblxuICAgIC8vIE1lbW9yeSBtaXNzIC0gdHJ5IFMzL0R5bmFtb0RCXG4gICAgY29uc3QgczNSZXN1bHQgPSBhd2FpdCB0aGlzLnMzRHluYW1vSGFuZGxlci5nZXQoY2FjaGVLZXksIGN0eCk7XG4gICAgaWYgKHMzUmVzdWx0KSB7XG4gICAgICB0aGlzLmRlYnVnKGBTMyBjYWNoZSBISVQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICAvLyBQcm9tb3RlZCB3aXRoIHRoZSBTMyBlbnRyeSdzIG93biBgbGFzdE1vZGlmaWVkYCwgbm90IHRoZSB0aW1lIG9mIHRoZVxuICAgICAgLy8gY29weTogTmV4dC5qcyBhZ2VzIHRoZSBlbnRyeSBmcm9tIGl0IGZvciB0aW1lLWJhc2VkIHJldmFsaWRhdGlvbiwgYW5kXG4gICAgICAvLyB0aGUgdGFnIG1hcmtlcnMgYXJlIGNvbXBhcmVkIGFnYWluc3QgaXQgdG9vLiBTdGFtcGluZyBgRGF0ZS5ub3coKWBcbiAgICAgIC8vIG1hZGUgYW4gZW50cnkgdGhhdCB3YXMgZHVlIGZvciByZWdlbmVyYXRpb24gbG9vayBmcmVzaGx5IHJlbmRlcmVkLFxuICAgICAgLy8gYW5kIG9uZSBhIHNvZnQgYHJldmFsaWRhdGVUYWdgIGhhZCBtYWRlIHN0YWxlIGxvb2sgbmV3ZXIgdGhhbiB0aGVcbiAgICAgIC8vIHN0YWxlIG1hcmssIHNvIG1lbW9yeSBoaXRzIHNlcnZlZCBpdCBhcyBmcmVzaCBmb3IgdGhlIHdob2xlIG1lbW9yeVxuICAgICAgLy8gVFRMLiBBbiBlbnRyeSBhIHRhZyByZXZhbGlkYXRpb24gZXhwaXJlZCAoYGxhc3RNb2RpZmllZDogLTFgKSBpcyBub3RcbiAgICAgIC8vIGNvcGllZCBhdCBhbGw6IHRoZSByZS1yZW5kZXIgaXQgYXNrcyBmb3Igd3JpdGVzIHRoZSBmcmVzaCBlbnRyeSB0b1xuICAgICAgLy8gYm90aCBsYXllcnMuXG4gICAgICBpZiAoczNSZXN1bHQubGFzdE1vZGlmaWVkICE9PSAtMSkge1xuICAgICAgICBhd2FpdCB0aGlzLm1lbW9yeUhhbmRsZXIuc2V0KFxuICAgICAgICAgIGNhY2hlS2V5LFxuICAgICAgICAgIHMzUmVzdWx0LnZhbHVlLFxuICAgICAgICAgIHMzUmVzdWx0Lmxhc3RNb2RpZmllZCxcbiAgICAgICAgICBzM1Jlc3VsdC5jYWNoZUNvbnRyb2wsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gczNSZXN1bHQ7XG4gICAgfVxuXG4gICAgdGhpcy5kZWJ1ZyhgQ2FjaGUgTUlTUzogJHtjYWNoZUtleX1gKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgY2FjaGUgZW50cnlcbiAgICogLSBCdWlsZCB0aW1lOiBXcml0ZSB0byBsb2NhbCBmaWxlIGNhY2hlIG9ubHkgKG9yIGRlbGV0ZSBpZiBkYXRhIGlzIG51bGwpXG4gICAqIC0gUnVudGltZTogV3JpdGUgdG8gYm90aCBtZW1vcnkgYW5kIFMzL0R5bmFtb0RCIChvciBkZWxldGUgaWYgZGF0YSBpcyBudWxsKSxcbiAgICogICB7QGxpbmsgb3V0c2lkZVJlbmRlcn1cbiAgICovXG4gIGFzeW5jIHNldChcbiAgICBjYWNoZUtleTogc3RyaW5nLFxuICAgIGRhdGE6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSB8IG51bGwsXG4gICAgY3R4OiBTZXRDYWNoZUhhbmRsZXJDb250ZXh0LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc0J1aWxkVGltZSkge1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2NhbEZpbGVIYW5kbGVyLnNldChjYWNoZUtleSwgZGF0YSwgZ2V0VGFncyhjdHgpKTtcbiAgICAgICAgdGhpcy5kZWJ1ZyhgQnVpbGQgY2FjaGUgd3JpdGU6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEZWxldGUgbm90IGltcGxlbWVudGVkIGZvciBsb2NhbCBmaWxlIGNhY2hlIChidWlsZC10aW1lIG9ubHkgY3JlYXRlcyBmaWxlcylcbiAgICAgICAgdGhpcy5kZWJ1ZyhgQnVpbGQgY2FjaGUgZGVsZXRlIGlnbm9yZWQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFJ1bnRpbWU6IGJvdGggbGF5ZXJzLCB3aGVyZSBgbnVsbGAgaXMgYSBkZWxldGUuXG4gICAgYXdhaXQgb3V0c2lkZVJlbmRlcihhc3luYyAoKSA9PiB7XG4gICAgICB0aGlzLmRlYnVnKGBDYWNoZSAke2RhdGEgPyBcIndyaXRlXCIgOiBcImRlbGV0ZVwifTogJHtjYWNoZUtleX1gKTtcbiAgICAgIGF3YWl0IHRoaXMubWVtb3J5SGFuZGxlci5zZXQoXG4gICAgICAgIGNhY2hlS2V5LFxuICAgICAgICBkYXRhLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGdldENhY2hlQ29udHJvbChjdHgpLFxuICAgICAgKTtcbiAgICAgIGF3YWl0IHRoaXMuczNEeW5hbW9IYW5kbGVyLnNldChjYWNoZUtleSwgZGF0YSwgY3R4KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZhbGlkYXRlIHRhZ3NcbiAgICogLSBCdWlsZCB0aW1lOiBOb3QgaW1wbGVtZW50ZWRcbiAgICogLSBSdW50aW1lOiBEZWxlZ2F0ZSB0byBTMy9EeW5hbW9EQiBoYW5kbGVyLCB7QGxpbmsgb3V0c2lkZVJlbmRlcn1cbiAgICovXG4gIGFzeW5jIHJldmFsaWRhdGVUYWcoXG4gICAgdGFnOiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM/OiB7IGV4cGlyZT86IG51bWJlciB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc0J1aWxkVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE1lbW9yeSBoaXRzIGFyZSBjaGVja2VkIGFnYWluc3QgdGhlIHNhbWUgbWFya2VycyAoc2VlIGBnZXRgKSwgc28gb25seVxuICAgIC8vIHRoZSBTMy9EeW5hbW9EQiBoYW5kbGVyIGhhcyBhbnl0aGluZyB0byByZWNvcmQuXG4gICAgYXdhaXQgb3V0c2lkZVJlbmRlcigoKSA9PlxuICAgICAgdGhpcy5zM0R5bmFtb0hhbmRsZXIucmV2YWxpZGF0ZVRhZyh0YWcsIGR1cmF0aW9ucyksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxpYmVyYXRlbHkgYSBuby1vcC4gTmV4dC5qcyBjYWxscyBgcmVzZXRSZXF1ZXN0Q2FjaGVgIGF0IHRoZSBzdGFydCBvZlxuICAgKiBldmVyeSByZXF1ZXN0IChgYmFzZS1zZXJ2ZXJgLCBgYXBwLXBhZ2VgLCBgYXBwLXJvdXRlYCksIGFuZCBpdHMgb3duXG4gICAqIGBGaWxlU3lzdGVtQ2FjaGVgIC0gd2hvc2UgTFJVIGlzIHNoYXJlZCBhY3Jvc3MgcmVxdWVzdHMgdGhlIHNhbWUgd2F5IHRoZVxuICAgKiBtZW1vcnkgbGF5ZXIgaXMgLSBsZWF2ZXMgaXQgZW1wdHk6IHRoZSBob29rIGlzIGZvciBzdGF0ZSBzY29wZWQgdG8gb25lXG4gICAqIHJlcXVlc3QsIGFuZCBub3RoaW5nIGhlcmUgaXMuIENsZWFyaW5nIHRoZSBtZW1vcnkgbGF5ZXIgaW4gaXQgbWVhbnQgbm9cbiAgICogZW50cnkgZXZlciBzdXJ2aXZlZCB0byBhIHNlY29uZCByZXF1ZXN0LCBzbyBldmVyeSByZWFkIHdlbnQgdG8gUzMuXG4gICAqL1xuICBhc3luYyByZXNldFJlcXVlc3RDYWNoZSgpOiBQcm9taXNlPHZvaWQ+IHt9XG59XG4iXX0=
@@ -74119,6 +74119,22 @@ var INIT_CACHE_TAG_MANIFEST = "_cdk-nextjs-tag-manifest.json";
74119
74119
  function getTags(ctx) {
74120
74120
  return "tags" in ctx ? ctx.tags : void 0;
74121
74121
  }
74122
+ function getCacheControl(ctx) {
74123
+ return "cacheControl" in ctx ? storedCacheControl(ctx.cacheControl) : void 0;
74124
+ }
74125
+ function storedCacheControl(value) {
74126
+ if (typeof value !== "object" || value === null) {
74127
+ return void 0;
74128
+ }
74129
+ const { revalidate, expire } = value;
74130
+ if (revalidate !== false && !(typeof revalidate === "number" && Number.isFinite(revalidate) && revalidate > 0)) {
74131
+ return void 0;
74132
+ }
74133
+ if (expire !== void 0 && !Number.isFinite(expire)) {
74134
+ return void 0;
74135
+ }
74136
+ return { revalidate, expire };
74137
+ }
74122
74138
 
74123
74139
  // src/adapter/local-file-cache-handler.ts
74124
74140
  var import_debug = __toESM(require_src());
@@ -74228,6 +74244,21 @@ var import_client_dynamodb = __toESM(require_dist_cjs19());
74228
74244
  var import_client_s3 = __toESM(require_dist_cjs20());
74229
74245
  import { AsyncLocalStorage } from "node:async_hooks";
74230
74246
  import { join as join6 } from "node:path";
74247
+
74248
+ // src/runtime/tag-manifest.ts
74249
+ var OUTSIDE_REQUEST_SYMBOL = /* @__PURE__ */ Symbol.for(
74250
+ "cdk-nextjs.outside-request-context"
74251
+ );
74252
+ function outsideRequest(fn) {
74253
+ const global = globalThis;
74254
+ const run = global[OUTSIDE_REQUEST_SYMBOL];
74255
+ return run ? run(fn) : fn();
74256
+ }
74257
+ var TAG_MANIFEST_SYMBOL = /* @__PURE__ */ Symbol.for(
74258
+ "cdk-nextjs.use-cache.tag-manifest"
74259
+ );
74260
+
74261
+ // src/adapter/aws-cache-store.ts
74231
74262
  function resolveAwsCacheConfig() {
74232
74263
  return {
74233
74264
  bucketName: process.env.CDK_NEXTJS_CACHE_BUCKET_NAME || "",
@@ -74797,6 +74828,18 @@ var TrackedTagMarkers = class {
74797
74828
  }
74798
74829
  return this.caughtUpRender.run(true, render);
74799
74830
  }
74831
+ /**
74832
+ * Run `fn` outside the request's context (`outsideRequest`), keeping only
74833
+ * whether the render was {@link catchUp caught up}: a cache handler method
74834
+ * called from inside a staged render, whose clock reads and AWS SDK calls
74835
+ * would otherwise end its static stage.
74836
+ */
74837
+ outsideRender(fn) {
74838
+ const caughtUp = this.caughtUpRender.getStore();
74839
+ return outsideRequest(
74840
+ () => caughtUp ? this.caughtUpRender.run(caughtUp, fn) : fn()
74841
+ );
74842
+ }
74800
74843
  /** Whether `at` is more than the interval and the grace ago. */
74801
74844
  overdue(at) {
74802
74845
  return this.clock() - at > this.refreshIntervalMs + TAG_REFRESH_GRACE_MS;
@@ -75389,13 +75432,6 @@ var CacheBucket = class {
75389
75432
  // src/adapter/use-cache-common.ts
75390
75433
  var import_client_dynamodb2 = __toESM(require_dist_cjs19());
75391
75434
  var import_debug6 = __toESM(require_src());
75392
-
75393
- // src/runtime/tag-manifest.ts
75394
- var TAG_MANIFEST_SYMBOL = /* @__PURE__ */ Symbol.for(
75395
- "cdk-nextjs.use-cache.tag-manifest"
75396
- );
75397
-
75398
- // src/adapter/use-cache-common.ts
75399
75435
  function isBuildPhase() {
75400
75436
  return process.env.NEXT_PHASE === "phase-production-build";
75401
75437
  }
@@ -75406,6 +75442,9 @@ function numberFromEnv(name, fallback2) {
75406
75442
  }
75407
75443
  var DEFAULT_MEMORY_BYTES = 50 * 1024 * 1024;
75408
75444
  var TAG_TABLE_REQUEST_TIMEOUT_MS = 3e3;
75445
+ function outsideRender(fn) {
75446
+ return outsideRequest(sharedTagManifest).outsideRender(fn);
75447
+ }
75409
75448
  function sharedTagManifest() {
75410
75449
  const global = globalThis;
75411
75450
  if (!global[TAG_MANIFEST_SYMBOL]) {
@@ -75543,8 +75582,11 @@ var MemoryCacheHandler = class {
75543
75582
  * `Date.now()` drifts from it for as long as the process lives: an entry
75544
75583
  * stamped ahead of it looked newer than a `revalidateTag` run within the
75545
75584
  * drift, and was served for the whole memory TTL.
75585
+ *
75586
+ * `cacheControl` is the lifetime the entry was rendered with, handed back
75587
+ * from {@link get} as the S3 layer does; see `getCacheControl`.
75546
75588
  */
75547
- async set(cacheKey, data, lastModified) {
75589
+ async set(cacheKey, data, lastModified, cacheControl) {
75548
75590
  if (!data) {
75549
75591
  this.debug(`MEMORY CACHE DELETE: ${cacheKey}`);
75550
75592
  this.inMemoryCache.delete(cacheKey);
@@ -75553,7 +75595,8 @@ var MemoryCacheHandler = class {
75553
75595
  this.debug(`MEMORY CACHE SET: ${cacheKey} (${data.kind})`);
75554
75596
  const cacheHandlerValue = {
75555
75597
  lastModified: lastModified ?? markerClock(),
75556
- value: data
75598
+ value: data,
75599
+ cacheControl
75557
75600
  };
75558
75601
  const entry = {
75559
75602
  value: cacheHandlerValue,
@@ -75729,15 +75772,26 @@ var S3CacheHandler = class {
75729
75772
  * request is answered from the stale entry - stale-while-revalidate - and that
75730
75773
  * response carries the entry's original `s-maxage`, so the edge caches the
75731
75774
  * stale body again. The background render that replaces it runs in this same
75732
- * process, so `set` checks this set and invalidates the key's paths a second
75775
+ * process, so `set` checks for the key here and invalidates the key's paths a second
75733
75776
  * time once the fresh entry is in S3. Without that, the edge kept serving the
75734
75777
  * pre-revalidation page for the whole `s-maxage`.
75735
75778
  *
75736
75779
  * Expiring soft-revalidated entries outright instead would also keep the edge
75737
75780
  * right, but it turns every `revalidateTag(tag, "max")` into a blocking render
75738
75781
  * at the origin, which is the thing a profile asks not to happen.
75782
+ *
75783
+ * When the re-render fails, next 16.4's `retainPreviousCacheEntry` writes the
75784
+ * stale value back with a short lifetime: that is no regeneration, so the key
75785
+ * keeps waiting rather than invalidating the edge for a page that has not
75786
+ * changed. {@link servedStale} is how `set` recognises it.
75739
75787
  */
75740
75788
  softRevalidatedKeys = /* @__PURE__ */ new Set();
75789
+ /**
75790
+ * Every value handed out stale, by identity: the object `get` returned is the
75791
+ * one `retainPreviousCacheEntry` writes back. Weak, so a page body is held no
75792
+ * longer than the memory layer or the request holds it.
75793
+ */
75794
+ servedStale = /* @__PURE__ */ new WeakSet();
75741
75795
  /** @see buildTagManifest */
75742
75796
  buildTags;
75743
75797
  constructor(options) {
@@ -75797,12 +75851,17 @@ var S3CacheHandler = class {
75797
75851
  const parsedValue = parseCacheValue(response);
75798
75852
  if (await this.isRevalidated(parsedValue, ctx, cacheKey)) {
75799
75853
  this.debug(`S3 CACHE INVALIDATED BY TAG: ${cacheKey}`);
75800
- return isFetchCacheGet(ctx) ? null : { lastModified: EXPIRED_LAST_MODIFIED, value: parsedValue.value };
75854
+ return isFetchCacheGet(ctx) ? null : {
75855
+ lastModified: EXPIRED_LAST_MODIFIED,
75856
+ value: parsedValue.value,
75857
+ cacheControl: storedCacheControl(parsedValue.cacheControl)
75858
+ };
75801
75859
  }
75802
75860
  this.debug(`S3 CACHE HIT: ${cacheKey} (${objectKey})`);
75803
75861
  return {
75804
75862
  lastModified: parsedValue.lastModified,
75805
- value: parsedValue.value
75863
+ value: parsedValue.value,
75864
+ cacheControl: storedCacheControl(parsedValue.cacheControl)
75806
75865
  };
75807
75866
  } catch (error2) {
75808
75867
  console.error(`Error retrieving cache from S3:`, error2);
@@ -75848,7 +75907,7 @@ var S3CacheHandler = class {
75848
75907
  checkTags
75849
75908
  );
75850
75909
  if (state2 === "stale" && !isFetchCacheGet(ctx)) {
75851
- this.noteSoftRevalidated(cacheKey);
75910
+ this.noteSoftRevalidated(cacheKey, entry.value);
75852
75911
  }
75853
75912
  return state2 === "expired";
75854
75913
  }
@@ -75857,13 +75916,16 @@ var S3CacheHandler = class {
75857
75916
  * whose copy of it will need invalidating again. See
75858
75917
  * {@link softRevalidatedKeys}.
75859
75918
  */
75860
- noteSoftRevalidated(cacheKey) {
75919
+ noteSoftRevalidated(cacheKey, value) {
75861
75920
  if (!this.invalidatesCdn) {
75862
75921
  return;
75863
75922
  }
75923
+ if (typeof value === "object" && value !== null) {
75924
+ this.servedStale.add(value);
75925
+ }
75864
75926
  this.softRevalidatedKeys.delete(cacheKey);
75865
75927
  if (this.softRevalidatedKeys.size >= MAX_SOFT_REVALIDATED_KEYS) {
75866
- const oldest = this.softRevalidatedKeys.values().next().value;
75928
+ const oldest = this.softRevalidatedKeys.keys().next().value;
75867
75929
  if (oldest !== void 0) {
75868
75930
  this.softRevalidatedKeys.delete(oldest);
75869
75931
  }
@@ -75901,7 +75963,8 @@ var S3CacheHandler = class {
75901
75963
  const cacheHandlerValue = {
75902
75964
  // On the marker clock, since that is what it is compared with.
75903
75965
  lastModified: markerClock(),
75904
- value: data
75966
+ value: data,
75967
+ cacheControl: getCacheControl(ctx)
75905
75968
  };
75906
75969
  const cacheEntryWithTags = {
75907
75970
  ...cacheHandlerValue,
@@ -75910,7 +75973,7 @@ var S3CacheHandler = class {
75910
75973
  const body = serializeCacheValue(cacheEntryWithTags);
75911
75974
  await this.bucket.putJson(objectKey, body);
75912
75975
  this.debug(`S3 CACHE STORED: ${cacheKey} (${data.kind})`);
75913
- if (this.softRevalidatedKeys.delete(cacheKey)) {
75976
+ if (!this.servedStale.has(data) && this.softRevalidatedKeys.delete(cacheKey)) {
75914
75977
  const route = this.s3KeyToInvalidationPath(s3Key);
75915
75978
  if (route !== void 0) {
75916
75979
  this.debug(`SOFT REVALIDATION REGENERATED: ${cacheKey}`);
@@ -76378,19 +76441,22 @@ var CdkNextjsCacheHandler = class _CdkNextjsCacheHandler {
76378
76441
  `Build-time cache directory: ${this.localFileHandler.getCacheDir()}`
76379
76442
  );
76380
76443
  } else {
76381
- this.s3DynamoHandler = _CdkNextjsCacheHandler.sharedS3DynamoHandler ??= new S3CacheHandler({ context: options });
76444
+ this.s3DynamoHandler = _CdkNextjsCacheHandler.sharedS3DynamoHandler ??= outsideRender(() => new S3CacheHandler({ context: options }));
76382
76445
  this.memoryHandler = _CdkNextjsCacheHandler.sharedMemoryHandler ??= new MemoryCacheHandler();
76383
76446
  }
76384
76447
  }
76385
76448
  /**
76386
76449
  * Get cache entry
76387
76450
  * - Build time: Not implemented (build doesn't read cache)
76388
- * - Runtime: Try memory first, then S3/DynamoDB
76451
+ * - Runtime: Try memory first, then S3/DynamoDB, {@link outsideRender}
76389
76452
  */
76390
76453
  async get(cacheKey, ctx) {
76391
76454
  if (this.isBuildTime) {
76392
76455
  return this.localFileHandler.get(cacheKey);
76393
76456
  }
76457
+ return outsideRender(() => this.getAtRuntime(cacheKey, ctx));
76458
+ }
76459
+ async getAtRuntime(cacheKey, ctx) {
76394
76460
  const memoryResult = await this.memoryHandler.get(cacheKey);
76395
76461
  if (memoryResult && await this.s3DynamoHandler.isRevalidated(
76396
76462
  {
@@ -76413,7 +76479,8 @@ var CdkNextjsCacheHandler = class _CdkNextjsCacheHandler {
76413
76479
  await this.memoryHandler.set(
76414
76480
  cacheKey,
76415
76481
  s3Result.value,
76416
- s3Result.lastModified
76482
+ s3Result.lastModified,
76483
+ s3Result.cacheControl
76417
76484
  );
76418
76485
  }
76419
76486
  return s3Result;
@@ -76424,7 +76491,8 @@ var CdkNextjsCacheHandler = class _CdkNextjsCacheHandler {
76424
76491
  /**
76425
76492
  * Set cache entry
76426
76493
  * - Build time: Write to local file cache only (or delete if data is null)
76427
- * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null)
76494
+ * - Runtime: Write to both memory and S3/DynamoDB (or delete if data is null),
76495
+ * {@link outsideRender}
76428
76496
  */
76429
76497
  async set(cacheKey, data, ctx) {
76430
76498
  if (this.isBuildTime) {
@@ -76436,20 +76504,29 @@ var CdkNextjsCacheHandler = class _CdkNextjsCacheHandler {
76436
76504
  }
76437
76505
  return;
76438
76506
  }
76439
- this.debug(`Cache ${data ? "write" : "delete"}: ${cacheKey}`);
76440
- await this.memoryHandler.set(cacheKey, data);
76441
- await this.s3DynamoHandler.set(cacheKey, data, ctx);
76507
+ await outsideRender(async () => {
76508
+ this.debug(`Cache ${data ? "write" : "delete"}: ${cacheKey}`);
76509
+ await this.memoryHandler.set(
76510
+ cacheKey,
76511
+ data,
76512
+ void 0,
76513
+ getCacheControl(ctx)
76514
+ );
76515
+ await this.s3DynamoHandler.set(cacheKey, data, ctx);
76516
+ });
76442
76517
  }
76443
76518
  /**
76444
76519
  * Revalidate tags
76445
76520
  * - Build time: Not implemented
76446
- * - Runtime: Delegate to S3/DynamoDB handler
76521
+ * - Runtime: Delegate to S3/DynamoDB handler, {@link outsideRender}
76447
76522
  */
76448
76523
  async revalidateTag(tag, durations) {
76449
76524
  if (this.isBuildTime) {
76450
76525
  return;
76451
76526
  }
76452
- await this.s3DynamoHandler.revalidateTag(tag, durations);
76527
+ await outsideRender(
76528
+ () => this.s3DynamoHandler.revalidateTag(tag, durations)
76529
+ );
76453
76530
  }
76454
76531
  /**
76455
76532
  * Deliberately a no-op. Next.js calls `resetRequestCache` at the start of