@opennextjs/cloudflare 1.8.2 → 1.8.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.
|
@@ -87,19 +87,6 @@ interface DOIdOptions {
|
|
|
87
87
|
replicaId?: number;
|
|
88
88
|
region?: DurableObjectLocationHint;
|
|
89
89
|
}
|
|
90
|
-
export declare class DOId {
|
|
91
|
-
options: DOIdOptions;
|
|
92
|
-
shardId: string;
|
|
93
|
-
replicaId: number;
|
|
94
|
-
region?: DurableObjectLocationHint;
|
|
95
|
-
constructor(options: DOIdOptions);
|
|
96
|
-
private generateRandomNumberBetween;
|
|
97
|
-
get key(): string;
|
|
98
|
-
}
|
|
99
|
-
interface CacheTagKeyOptions {
|
|
100
|
-
doId: DOId;
|
|
101
|
-
tags: string[];
|
|
102
|
-
}
|
|
103
90
|
declare class ShardedDOTagCache implements NextModeTagCache {
|
|
104
91
|
private opts;
|
|
105
92
|
readonly mode: "nextMode";
|
|
@@ -111,29 +98,9 @@ declare class ShardedDOTagCache implements NextModeTagCache {
|
|
|
111
98
|
readonly defaultRegion: AllowedDurableObjectRegion;
|
|
112
99
|
localCache?: Cache;
|
|
113
100
|
constructor(opts?: ShardedDOTagCacheOptions);
|
|
114
|
-
private getDurableObjectStub;
|
|
115
101
|
/**
|
|
116
|
-
*
|
|
117
|
-
* @param tags The tags to generate shards for
|
|
118
|
-
* @param shardType Whether to generate shards for soft or hard tags
|
|
119
|
-
* @param generateAllShards Whether to generate all shards or only one
|
|
120
|
-
* @returns An array of TagCacheDOId and tag
|
|
102
|
+
* Public API
|
|
121
103
|
*/
|
|
122
|
-
private generateDOIdArray;
|
|
123
|
-
getClosestRegion(): "enam" | "sam" | "weur" | "apac" | "oc" | "afr";
|
|
124
|
-
/**
|
|
125
|
-
* Same tags are guaranteed to be in the same shard
|
|
126
|
-
* @param tags
|
|
127
|
-
* @returns An array of DO ids and tags
|
|
128
|
-
*/
|
|
129
|
-
groupTagsByDO({ tags, generateAllReplicas }: {
|
|
130
|
-
tags: string[];
|
|
131
|
-
generateAllReplicas?: boolean;
|
|
132
|
-
}): {
|
|
133
|
-
doId: DOId;
|
|
134
|
-
tags: string[];
|
|
135
|
-
}[];
|
|
136
|
-
private getConfig;
|
|
137
104
|
getLastRevalidated(tags: string[]): Promise<number>;
|
|
138
105
|
/**
|
|
139
106
|
* This function checks if the tags have been revalidated
|
|
@@ -150,9 +117,12 @@ declare class ShardedDOTagCache implements NextModeTagCache {
|
|
|
150
117
|
* @returns
|
|
151
118
|
*/
|
|
152
119
|
writeTags(tags: string[]): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* The following methods are public only because they are accessed from the tests
|
|
122
|
+
*/
|
|
153
123
|
performWriteTagsWithRetry(doId: DOId, tags: string[], lastModified: number, retryNumber?: number): Promise<void>;
|
|
154
|
-
getCacheInstance(): Promise<Cache | undefined>;
|
|
155
124
|
getCacheUrlKey(doId: DOId, tag: string): string;
|
|
125
|
+
getCacheInstance(): Promise<Cache | undefined>;
|
|
156
126
|
/**
|
|
157
127
|
* Get the last revalidation time for the tags from the regional cache
|
|
158
128
|
* If the cache is not enabled, it will return an empty array
|
|
@@ -168,6 +138,42 @@ declare class ShardedDOTagCache implements NextModeTagCache {
|
|
|
168
138
|
* This is used to ensure that the cache is cleared when the tags are revalidated
|
|
169
139
|
*/
|
|
170
140
|
deleteRegionalCache(optsKey: CacheTagKeyOptions): Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Same tags are guaranteed to be in the same shard
|
|
143
|
+
* @param tags
|
|
144
|
+
* @returns An array of DO ids and tags
|
|
145
|
+
*/
|
|
146
|
+
groupTagsByDO({ tags, generateAllReplicas, }: {
|
|
147
|
+
tags: string[];
|
|
148
|
+
generateAllReplicas?: boolean;
|
|
149
|
+
}): {
|
|
150
|
+
doId: DOId;
|
|
151
|
+
tags: string[];
|
|
152
|
+
}[];
|
|
153
|
+
private getDurableObjectStub;
|
|
154
|
+
/**
|
|
155
|
+
* Generates a list of DO ids for the shards and replicas
|
|
156
|
+
* @param tags The tags to generate shards for
|
|
157
|
+
* @param shardType Whether to generate shards for soft or hard tags
|
|
158
|
+
* @param generateAllShards Whether to generate all shards or only one
|
|
159
|
+
* @returns An array of TagCacheDOId and tag
|
|
160
|
+
*/
|
|
161
|
+
private generateDOIdArray;
|
|
162
|
+
private getClosestRegion;
|
|
163
|
+
private getConfig;
|
|
164
|
+
}
|
|
165
|
+
export declare class DOId {
|
|
166
|
+
options: DOIdOptions;
|
|
167
|
+
shardId: string;
|
|
168
|
+
replicaId: number;
|
|
169
|
+
region?: DurableObjectLocationHint;
|
|
170
|
+
constructor(options: DOIdOptions);
|
|
171
|
+
private generateRandomNumberBetween;
|
|
172
|
+
get key(): string;
|
|
173
|
+
}
|
|
174
|
+
interface CacheTagKeyOptions {
|
|
175
|
+
doId: DOId;
|
|
176
|
+
tags: string[];
|
|
171
177
|
}
|
|
172
178
|
declare const _default: (opts?: ShardedDOTagCacheOptions) => ShardedDOTagCache;
|
|
173
179
|
export default _default;
|
|
@@ -9,25 +9,6 @@ export const NAME = "do-sharded-tag-cache";
|
|
|
9
9
|
const SOFT_TAG_PREFIX = "_N_T_/";
|
|
10
10
|
export const DEFAULT_REGION = "enam";
|
|
11
11
|
export const AVAILABLE_REGIONS = ["enam", "weur", "apac", "sam", "afr", "oc"];
|
|
12
|
-
export class DOId {
|
|
13
|
-
options;
|
|
14
|
-
shardId;
|
|
15
|
-
replicaId;
|
|
16
|
-
region;
|
|
17
|
-
constructor(options) {
|
|
18
|
-
this.options = options;
|
|
19
|
-
const { baseShardId, shardType, numberOfReplicas, replicaId, region } = options;
|
|
20
|
-
this.shardId = `tag-${shardType};${baseShardId}`;
|
|
21
|
-
this.replicaId = replicaId ?? this.generateRandomNumberBetween(1, numberOfReplicas);
|
|
22
|
-
this.region = region;
|
|
23
|
-
}
|
|
24
|
-
generateRandomNumberBetween(min, max) {
|
|
25
|
-
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
26
|
-
}
|
|
27
|
-
get key() {
|
|
28
|
-
return `${this.shardId};replica-${this.replicaId}${this.region ? `;region-${this.region}` : ""}`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
12
|
class ShardedDOTagCache {
|
|
32
13
|
opts;
|
|
33
14
|
mode = "nextMode";
|
|
@@ -46,137 +27,11 @@ class ShardedDOTagCache {
|
|
|
46
27
|
this.enableRegionalReplication = Boolean(opts.shardReplication?.regionalReplication);
|
|
47
28
|
this.defaultRegion = opts.shardReplication?.regionalReplication?.defaultRegion ?? DEFAULT_REGION;
|
|
48
29
|
}
|
|
49
|
-
getDurableObjectStub(doId) {
|
|
50
|
-
const durableObject = getCloudflareContext().env.NEXT_TAG_CACHE_DO_SHARDED;
|
|
51
|
-
if (!durableObject)
|
|
52
|
-
throw new IgnorableError("No durable object binding for cache revalidation");
|
|
53
|
-
const id = durableObject.idFromName(doId.key);
|
|
54
|
-
debug("[shardedTagCache] - Accessing Durable Object : ", {
|
|
55
|
-
key: doId.key,
|
|
56
|
-
region: doId.region,
|
|
57
|
-
});
|
|
58
|
-
return durableObject.get(id, { locationHint: doId.region });
|
|
59
|
-
}
|
|
60
30
|
/**
|
|
61
|
-
*
|
|
62
|
-
* @param tags The tags to generate shards for
|
|
63
|
-
* @param shardType Whether to generate shards for soft or hard tags
|
|
64
|
-
* @param generateAllShards Whether to generate all shards or only one
|
|
65
|
-
* @returns An array of TagCacheDOId and tag
|
|
31
|
+
* Public API
|
|
66
32
|
*/
|
|
67
|
-
generateDOIdArray({ tags, shardType, generateAllReplicas = false, }) {
|
|
68
|
-
let replicaIndexes = [1];
|
|
69
|
-
const isSoft = shardType === "soft";
|
|
70
|
-
let numReplicas = 1;
|
|
71
|
-
if (this.opts.shardReplication) {
|
|
72
|
-
numReplicas = isSoft ? this.numSoftReplicas : this.numHardReplicas;
|
|
73
|
-
replicaIndexes = generateAllReplicas
|
|
74
|
-
? Array.from({ length: numReplicas }, (_, i) => i + 1)
|
|
75
|
-
: [undefined];
|
|
76
|
-
}
|
|
77
|
-
const regionalReplicas = replicaIndexes.flatMap((replicaId) => {
|
|
78
|
-
return tags
|
|
79
|
-
.filter((tag) => (isSoft ? tag.startsWith(SOFT_TAG_PREFIX) : !tag.startsWith(SOFT_TAG_PREFIX)))
|
|
80
|
-
.map((tag) => {
|
|
81
|
-
return {
|
|
82
|
-
doId: new DOId({
|
|
83
|
-
baseShardId: generateShardId(tag, this.opts.baseShardSize, "shard"),
|
|
84
|
-
numberOfReplicas: numReplicas,
|
|
85
|
-
shardType,
|
|
86
|
-
replicaId,
|
|
87
|
-
}),
|
|
88
|
-
tag,
|
|
89
|
-
};
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
if (!this.enableRegionalReplication)
|
|
93
|
-
return regionalReplicas;
|
|
94
|
-
// If we have regional replication enabled, we need to further duplicate the shards in all the regions
|
|
95
|
-
const regionalReplicasInAllRegions = generateAllReplicas
|
|
96
|
-
? regionalReplicas.flatMap(({ doId, tag }) => {
|
|
97
|
-
return AVAILABLE_REGIONS.map((region) => {
|
|
98
|
-
return {
|
|
99
|
-
doId: new DOId({
|
|
100
|
-
baseShardId: doId.options.baseShardId,
|
|
101
|
-
numberOfReplicas: numReplicas,
|
|
102
|
-
shardType,
|
|
103
|
-
replicaId: doId.replicaId,
|
|
104
|
-
region,
|
|
105
|
-
}),
|
|
106
|
-
tag,
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
})
|
|
110
|
-
: regionalReplicas.map(({ doId, tag }) => {
|
|
111
|
-
doId.region = this.getClosestRegion();
|
|
112
|
-
return { doId, tag };
|
|
113
|
-
});
|
|
114
|
-
return regionalReplicasInAllRegions;
|
|
115
|
-
}
|
|
116
|
-
getClosestRegion() {
|
|
117
|
-
const continent = getCloudflareContext().cf?.continent;
|
|
118
|
-
if (!continent)
|
|
119
|
-
return this.defaultRegion;
|
|
120
|
-
debug("[shardedTagCache] - Continent : ", continent);
|
|
121
|
-
switch (continent) {
|
|
122
|
-
case "AF":
|
|
123
|
-
return "afr";
|
|
124
|
-
case "AS":
|
|
125
|
-
return "apac";
|
|
126
|
-
case "EU":
|
|
127
|
-
return "weur";
|
|
128
|
-
case "NA":
|
|
129
|
-
return "enam";
|
|
130
|
-
case "OC":
|
|
131
|
-
return "oc";
|
|
132
|
-
case "SA":
|
|
133
|
-
return "sam";
|
|
134
|
-
default:
|
|
135
|
-
return this.defaultRegion;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Same tags are guaranteed to be in the same shard
|
|
140
|
-
* @param tags
|
|
141
|
-
* @returns An array of DO ids and tags
|
|
142
|
-
*/
|
|
143
|
-
groupTagsByDO({ tags, generateAllReplicas = false }) {
|
|
144
|
-
// Here we'll start by splitting soft tags from hard tags
|
|
145
|
-
// This will greatly increase the cache hit rate for the soft tag (which are the most likely to cause issue because of load)
|
|
146
|
-
const softTags = this.generateDOIdArray({ tags, shardType: "soft", generateAllReplicas });
|
|
147
|
-
const hardTags = this.generateDOIdArray({ tags, shardType: "hard", generateAllReplicas });
|
|
148
|
-
const tagIdCollection = [...softTags, ...hardTags];
|
|
149
|
-
// We then group the tags by DO id
|
|
150
|
-
const tagsByDOId = new Map();
|
|
151
|
-
for (const { doId, tag } of tagIdCollection) {
|
|
152
|
-
const doIdString = doId.key;
|
|
153
|
-
const tagsArray = tagsByDOId.get(doIdString)?.tags ?? [];
|
|
154
|
-
tagsArray.push(tag);
|
|
155
|
-
tagsByDOId.set(doIdString, {
|
|
156
|
-
// We override the doId here, but it should be the same for all tags
|
|
157
|
-
doId,
|
|
158
|
-
tags: tagsArray,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
const result = Array.from(tagsByDOId.values());
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
async getConfig() {
|
|
165
|
-
const cfEnv = getCloudflareContext().env;
|
|
166
|
-
const db = cfEnv.NEXT_TAG_CACHE_DO_SHARDED;
|
|
167
|
-
if (!db)
|
|
168
|
-
debugCache("No Durable object found");
|
|
169
|
-
const isDisabled = !!globalThis.openNextConfig
|
|
170
|
-
.dangerous?.disableTagCache;
|
|
171
|
-
return !db || isDisabled
|
|
172
|
-
? { isDisabled: true }
|
|
173
|
-
: {
|
|
174
|
-
isDisabled: false,
|
|
175
|
-
db,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
33
|
async getLastRevalidated(tags) {
|
|
179
|
-
const { isDisabled } =
|
|
34
|
+
const { isDisabled } = this.getConfig();
|
|
180
35
|
if (isDisabled)
|
|
181
36
|
return 0;
|
|
182
37
|
if (tags.length === 0)
|
|
@@ -214,7 +69,7 @@ class ShardedDOTagCache {
|
|
|
214
69
|
* @returns
|
|
215
70
|
*/
|
|
216
71
|
async hasBeenRevalidated(tags, lastModified) {
|
|
217
|
-
const { isDisabled } =
|
|
72
|
+
const { isDisabled } = this.getConfig();
|
|
218
73
|
if (isDisabled)
|
|
219
74
|
return false;
|
|
220
75
|
try {
|
|
@@ -251,7 +106,7 @@ class ShardedDOTagCache {
|
|
|
251
106
|
* @returns
|
|
252
107
|
*/
|
|
253
108
|
async writeTags(tags) {
|
|
254
|
-
const { isDisabled } =
|
|
109
|
+
const { isDisabled } = this.getConfig();
|
|
255
110
|
if (isDisabled)
|
|
256
111
|
return;
|
|
257
112
|
const shardedTagGroups = this.groupTagsByDO({ tags, generateAllReplicas: true });
|
|
@@ -262,6 +117,9 @@ class ShardedDOTagCache {
|
|
|
262
117
|
}));
|
|
263
118
|
await purgeCacheByTags(tags);
|
|
264
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* The following methods are public only because they are accessed from the tests
|
|
122
|
+
*/
|
|
265
123
|
async performWriteTagsWithRetry(doId, tags, lastModified, retryNumber = 0) {
|
|
266
124
|
try {
|
|
267
125
|
const stub = this.getDurableObjectStub(doId);
|
|
@@ -285,16 +143,15 @@ class ShardedDOTagCache {
|
|
|
285
143
|
await this.performWriteTagsWithRetry(doId, tags, lastModified, retryNumber + 1);
|
|
286
144
|
}
|
|
287
145
|
}
|
|
288
|
-
|
|
146
|
+
getCacheUrlKey(doId, tag) {
|
|
147
|
+
return `http://local.cache/shard/${doId.shardId}?tag=${encodeURIComponent(tag)}`;
|
|
148
|
+
}
|
|
289
149
|
async getCacheInstance() {
|
|
290
150
|
if (!this.localCache && this.opts.regionalCache) {
|
|
291
151
|
this.localCache = await caches.open("sharded-do-tag-cache");
|
|
292
152
|
}
|
|
293
153
|
return this.localCache;
|
|
294
154
|
}
|
|
295
|
-
getCacheUrlKey(doId, tag) {
|
|
296
|
-
return `http://local.cache/shard/${doId.shardId}?tag=${encodeURIComponent(tag)}`;
|
|
297
|
-
}
|
|
298
155
|
/**
|
|
299
156
|
* Get the last revalidation time for the tags from the regional cache
|
|
300
157
|
* If the cache is not enabled, it will return an empty array
|
|
@@ -383,5 +240,154 @@ class ShardedDOTagCache {
|
|
|
383
240
|
debugCache("Error while deleting from regional cache", e);
|
|
384
241
|
}
|
|
385
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Same tags are guaranteed to be in the same shard
|
|
245
|
+
* @param tags
|
|
246
|
+
* @returns An array of DO ids and tags
|
|
247
|
+
*/
|
|
248
|
+
groupTagsByDO({ tags, generateAllReplicas = false, }) {
|
|
249
|
+
// Here we'll start by splitting soft tags from hard tags
|
|
250
|
+
// This will greatly increase the cache hit rate for the soft tag (which are the most likely to cause issue because of load)
|
|
251
|
+
const softTags = this.generateDOIdArray({ tags, shardType: "soft", generateAllReplicas });
|
|
252
|
+
const hardTags = this.generateDOIdArray({ tags, shardType: "hard", generateAllReplicas });
|
|
253
|
+
const tagIdCollection = [...softTags, ...hardTags];
|
|
254
|
+
// We then group the tags by DO id
|
|
255
|
+
const tagsByDOId = new Map();
|
|
256
|
+
for (const { doId, tag } of tagIdCollection) {
|
|
257
|
+
const doIdString = doId.key;
|
|
258
|
+
const tagsArray = tagsByDOId.get(doIdString)?.tags ?? [];
|
|
259
|
+
tagsArray.push(tag);
|
|
260
|
+
tagsByDOId.set(doIdString, {
|
|
261
|
+
// We override the doId here, but it should be the same for all tags
|
|
262
|
+
doId,
|
|
263
|
+
tags: tagsArray,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
const result = Array.from(tagsByDOId.values());
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
// Private methods
|
|
270
|
+
getDurableObjectStub(doId) {
|
|
271
|
+
const durableObject = getCloudflareContext().env.NEXT_TAG_CACHE_DO_SHARDED;
|
|
272
|
+
if (!durableObject)
|
|
273
|
+
throw new IgnorableError("No durable object binding for cache revalidation");
|
|
274
|
+
const id = durableObject.idFromName(doId.key);
|
|
275
|
+
debug("[shardedTagCache] - Accessing Durable Object : ", {
|
|
276
|
+
key: doId.key,
|
|
277
|
+
region: doId.region,
|
|
278
|
+
});
|
|
279
|
+
return durableObject.get(id, { locationHint: doId.region });
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Generates a list of DO ids for the shards and replicas
|
|
283
|
+
* @param tags The tags to generate shards for
|
|
284
|
+
* @param shardType Whether to generate shards for soft or hard tags
|
|
285
|
+
* @param generateAllShards Whether to generate all shards or only one
|
|
286
|
+
* @returns An array of TagCacheDOId and tag
|
|
287
|
+
*/
|
|
288
|
+
generateDOIdArray({ tags, shardType, generateAllReplicas = false, }) {
|
|
289
|
+
let replicaIndexes = [1];
|
|
290
|
+
const isSoft = shardType === "soft";
|
|
291
|
+
let numReplicas = 1;
|
|
292
|
+
if (this.opts.shardReplication) {
|
|
293
|
+
numReplicas = isSoft ? this.numSoftReplicas : this.numHardReplicas;
|
|
294
|
+
replicaIndexes = generateAllReplicas
|
|
295
|
+
? Array.from({ length: numReplicas }, (_, i) => i + 1)
|
|
296
|
+
: [undefined];
|
|
297
|
+
}
|
|
298
|
+
const regionalReplicas = replicaIndexes.flatMap((replicaId) => {
|
|
299
|
+
return tags
|
|
300
|
+
.filter((tag) => (isSoft ? tag.startsWith(SOFT_TAG_PREFIX) : !tag.startsWith(SOFT_TAG_PREFIX)))
|
|
301
|
+
.map((tag) => {
|
|
302
|
+
return {
|
|
303
|
+
doId: new DOId({
|
|
304
|
+
baseShardId: generateShardId(tag, this.opts.baseShardSize, "shard"),
|
|
305
|
+
numberOfReplicas: numReplicas,
|
|
306
|
+
shardType,
|
|
307
|
+
replicaId,
|
|
308
|
+
}),
|
|
309
|
+
tag,
|
|
310
|
+
};
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
if (!this.enableRegionalReplication)
|
|
314
|
+
return regionalReplicas;
|
|
315
|
+
// If we have regional replication enabled, we need to further duplicate the shards in all the regions
|
|
316
|
+
const regionalReplicasInAllRegions = generateAllReplicas
|
|
317
|
+
? regionalReplicas.flatMap(({ doId, tag }) => {
|
|
318
|
+
return AVAILABLE_REGIONS.map((region) => {
|
|
319
|
+
return {
|
|
320
|
+
doId: new DOId({
|
|
321
|
+
baseShardId: doId.options.baseShardId,
|
|
322
|
+
numberOfReplicas: numReplicas,
|
|
323
|
+
shardType,
|
|
324
|
+
replicaId: doId.replicaId,
|
|
325
|
+
region,
|
|
326
|
+
}),
|
|
327
|
+
tag,
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
})
|
|
331
|
+
: regionalReplicas.map(({ doId, tag }) => {
|
|
332
|
+
doId.region = this.getClosestRegion();
|
|
333
|
+
return { doId, tag };
|
|
334
|
+
});
|
|
335
|
+
return regionalReplicasInAllRegions;
|
|
336
|
+
}
|
|
337
|
+
getClosestRegion() {
|
|
338
|
+
const continent = getCloudflareContext().cf?.continent;
|
|
339
|
+
if (!continent)
|
|
340
|
+
return this.defaultRegion;
|
|
341
|
+
debug("[shardedTagCache] - Continent : ", continent);
|
|
342
|
+
switch (continent) {
|
|
343
|
+
case "AF":
|
|
344
|
+
return "afr";
|
|
345
|
+
case "AS":
|
|
346
|
+
return "apac";
|
|
347
|
+
case "EU":
|
|
348
|
+
return "weur";
|
|
349
|
+
case "NA":
|
|
350
|
+
return "enam";
|
|
351
|
+
case "OC":
|
|
352
|
+
return "oc";
|
|
353
|
+
case "SA":
|
|
354
|
+
return "sam";
|
|
355
|
+
default:
|
|
356
|
+
return this.defaultRegion;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
getConfig() {
|
|
360
|
+
const cfEnv = getCloudflareContext().env;
|
|
361
|
+
const db = cfEnv.NEXT_TAG_CACHE_DO_SHARDED;
|
|
362
|
+
if (!db)
|
|
363
|
+
debugCache("No Durable object found");
|
|
364
|
+
const isDisabled = !!globalThis.openNextConfig
|
|
365
|
+
.dangerous?.disableTagCache;
|
|
366
|
+
return !db || isDisabled
|
|
367
|
+
? { isDisabled: true }
|
|
368
|
+
: {
|
|
369
|
+
isDisabled: false,
|
|
370
|
+
db,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
export class DOId {
|
|
375
|
+
options;
|
|
376
|
+
shardId;
|
|
377
|
+
replicaId;
|
|
378
|
+
region;
|
|
379
|
+
constructor(options) {
|
|
380
|
+
this.options = options;
|
|
381
|
+
const { baseShardId, shardType, numberOfReplicas, replicaId, region } = options;
|
|
382
|
+
this.shardId = `tag-${shardType};${baseShardId}`;
|
|
383
|
+
this.replicaId = replicaId ?? this.generateRandomNumberBetween(1, numberOfReplicas);
|
|
384
|
+
this.region = region;
|
|
385
|
+
}
|
|
386
|
+
generateRandomNumberBetween(min, max) {
|
|
387
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
388
|
+
}
|
|
389
|
+
get key() {
|
|
390
|
+
return `${this.shardId};replica-${this.replicaId}${this.region ? `;region-${this.region}` : ""}`;
|
|
391
|
+
}
|
|
386
392
|
}
|
|
387
393
|
export default (opts) => new ShardedDOTagCache(opts);
|
|
@@ -35,8 +35,7 @@ export async function compileConfig(configPath) {
|
|
|
35
35
|
if (!configPath) {
|
|
36
36
|
configPath = await createOpenNextConfigIfNotExistent(nextAppDir);
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
const { config, buildDir } = await compileOpenNextConfig(configPath, "", { compileEdge: true });
|
|
38
|
+
const { config, buildDir } = await compileOpenNextConfig(configPath, { compileEdge: true });
|
|
40
39
|
ensureCloudflareConfig(config);
|
|
41
40
|
return { config, buildDir };
|
|
42
41
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennextjs/cloudflare",
|
|
3
3
|
"description": "Cloudflare builder for next apps",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opennextjs-cloudflare": "dist/cli/index.js"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@dotenvx/dotenvx": "1.31.0",
|
|
46
|
-
"@opennextjs/aws": "3.7.
|
|
46
|
+
"@opennextjs/aws": "3.7.7",
|
|
47
47
|
"cloudflare": "^4.4.1",
|
|
48
48
|
"enquirer": "^2.4.1",
|
|
49
49
|
"glob": "^11.0.0",
|