else clause. Try the followingexpiration (seconds since the epoch) or expirationTtl (seconds from now) ? Because I saw your this.windowMs = 60_000 // 1 minute comment, but you also have expirationTtl: this.windowMs and that would be wrong; it would be 60000 seconds.totalHits but the expiration time remains that same, thats why it is stored in resetTime. So when I am updating it, I am passing the expiration again.As of January 2022, expiration targets that are less than 60 seconds into the future are not supported. This is true for both expiration methods.
expiration attribute?expiration?WorkerKV with hono which uses expiration or expirationTtl?
WorkerKV is giving me some troubleresetTime if there's already an expiration field?expiration when we update the value, if you not it's not gonna expire.get('key') it returns an object with the expiration field, right? So if it already has that field, you can re-write it back without altering it.expiration which is fixed in time, and keep adding to it each time the request happens. is that what you want? for the expiration to be moved forward?limit. so not very many.put(); you fire and foget them until the next request where you list() and count.expiration prop. But at the end of the day it will be too expensive to use this solution for rate limiting.
WorkerKV and use DurableObjectselseexpirationexpirationexpirationexpirationexpirationexpirationexpirationexpirationexpirationexpirationexpirationTtlexpirationTtlthis.windowMs = 60_000 // 1 minuteexpirationTtl: this.windowMstotalHitsresetTimeresetTimeWorkerKVWorkerKVWorkerKVhonoget('key')limitput()list()DurableObjectsconst payload = wasCreated
? {
totalHits: payload.totalHits + 1,
resetTime: new Date(payload.resetTime)
}
: {
totalHits: 1,
resetTime: new Date(Date.now() + this.windowMs),
}if (wasCreated) {
payload = {
totalHits: payload.totalHits + 1,
resetTime: new Date(payload.resetTime),
}; // <-- semicolon here
} else { // <-- not here
payload = {
totalHits: 1,
resetTime: new Date(Date.now() + this.windowMs),
};
}const defaultPayload = {
hits: 1,
expiration: new Date(new Date().getTime() + 60_000),
}
const record = await env.NAMESPACE.get('key', { type: 'json' })
const payload = {
...defaultPayload,
...(record ?? {}), // if record is nullish, spread an empty object in its place
}
await env.NAMESPACE.put('key', payload, { expiration: payload.expiration })async increment(key: string): Promise<ClientRateLimitInfo> {
const keyWithPrefix = this.prefixKey(key);
const defaultPayload = {
totalHits: 1,
resetTime: new Date(Date.now() + this.windowMs),
}
// @ts-ignore
const record: Required<ClientRateLimitInfo> | null = await this.namespace.get<Required<ClientRateLimitInfo>>(
keyWithPrefix,
"json",
);
const payload = { ...defaultPayload, ...(record ? { totalHits: record.totalHits + 1, resetTime: new Date(record.resetTime) } : {}) }
console.log("Payload - ", payload, " Expire - ", payload.resetTime.toLocaleString(), " Current - ", new Date().toLocaleString())
await this.namespace.put(keyWithPrefix, JSON.stringify(payload), {
expirationTtl: !record ? payload.resetTime.getTime() / 1000 : undefined,
});
return payload;
}