s3db.js 19.0.1-next.a0f32580 → 19.0.1-next.c969d2da
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/concerns/plugin-storage.js +20 -17
- package/dist/concerns/plugin-storage.js.map +1 -1
- package/dist/s3db.cjs +22 -19
- package/dist/s3db.cjs.map +1 -1
- package/dist/s3db.es.js +22 -19
- package/dist/s3db.es.js.map +1 -1
- package/dist/types/concerns/plugin-storage.d.ts +9 -1
- package/dist/types/concerns/plugin-storage.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/concerns/plugin-storage.ts +28 -17
package/dist/s3db.es.js
CHANGED
|
@@ -18248,8 +18248,8 @@ class Database extends SafeEventEmitter {
|
|
|
18248
18248
|
})();
|
|
18249
18249
|
this.version = '1';
|
|
18250
18250
|
this.s3dbVersion = (() => {
|
|
18251
|
-
const [ok, , version] = tryFnSync(() => (typeof globalThis['19.0.1-next.
|
|
18252
|
-
? globalThis['19.0.1-next.
|
|
18251
|
+
const [ok, , version] = tryFnSync(() => (typeof globalThis['19.0.1-next.c969d2da'] !== 'undefined' && globalThis['19.0.1-next.c969d2da'] !== '19.0.1-next.c969d2da'
|
|
18252
|
+
? globalThis['19.0.1-next.c969d2da']
|
|
18253
18253
|
: 'latest'));
|
|
18254
18254
|
return ok ? version : 'latest';
|
|
18255
18255
|
})();
|
|
@@ -19526,7 +19526,8 @@ class PluginStorage {
|
|
|
19526
19526
|
pluginSlug;
|
|
19527
19527
|
_lock;
|
|
19528
19528
|
_sequence;
|
|
19529
|
-
|
|
19529
|
+
_now;
|
|
19530
|
+
constructor(client, pluginSlug, options = {}) {
|
|
19530
19531
|
if (!client) {
|
|
19531
19532
|
throw new PluginStorageError('PluginStorage requires a client instance', {
|
|
19532
19533
|
operation: 'constructor',
|
|
@@ -19542,6 +19543,8 @@ class PluginStorage {
|
|
|
19542
19543
|
}
|
|
19543
19544
|
this.client = client;
|
|
19544
19545
|
this.pluginSlug = pluginSlug;
|
|
19546
|
+
// Use arrow function to capture Date.now dynamically (enables FakeTimers mocking)
|
|
19547
|
+
this._now = options.now ?? (() => Date.now());
|
|
19545
19548
|
this._lock = new DistributedLock(this, {
|
|
19546
19549
|
keyGenerator: (name) => this.getPluginKey(null, 'locks', name)
|
|
19547
19550
|
});
|
|
@@ -19566,7 +19569,7 @@ class PluginStorage {
|
|
|
19566
19569
|
const { ttl, behavior = 'body-overflow', contentType = 'application/json', ifMatch, ifNoneMatch } = options;
|
|
19567
19570
|
const dataToSave = { ...data };
|
|
19568
19571
|
if (ttl && typeof ttl === 'number' && ttl > 0) {
|
|
19569
|
-
dataToSave._expiresAt =
|
|
19572
|
+
dataToSave._expiresAt = this._now() + (ttl * 1000);
|
|
19570
19573
|
}
|
|
19571
19574
|
const { metadata, body } = this._applyBehavior(dataToSave, behavior);
|
|
19572
19575
|
const putParams = {
|
|
@@ -19647,7 +19650,7 @@ class PluginStorage {
|
|
|
19647
19650
|
}
|
|
19648
19651
|
const expiresAt = (data._expiresat || data._expiresAt);
|
|
19649
19652
|
if (expiresAt) {
|
|
19650
|
-
if (
|
|
19653
|
+
if (this._now() > expiresAt) {
|
|
19651
19654
|
await this.delete(key);
|
|
19652
19655
|
return null;
|
|
19653
19656
|
}
|
|
@@ -19776,7 +19779,7 @@ class PluginStorage {
|
|
|
19776
19779
|
if (!expiresAt) {
|
|
19777
19780
|
return false;
|
|
19778
19781
|
}
|
|
19779
|
-
return
|
|
19782
|
+
return this._now() > expiresAt;
|
|
19780
19783
|
}
|
|
19781
19784
|
async getTTL(key) {
|
|
19782
19785
|
const [ok, , response] = await tryFn(() => this.client.getObject(key));
|
|
@@ -19804,7 +19807,7 @@ class PluginStorage {
|
|
|
19804
19807
|
if (!expiresAt) {
|
|
19805
19808
|
return null;
|
|
19806
19809
|
}
|
|
19807
|
-
const remaining = Math.max(0, expiresAt -
|
|
19810
|
+
const remaining = Math.max(0, expiresAt - this._now());
|
|
19808
19811
|
return Math.floor(remaining / 1000);
|
|
19809
19812
|
}
|
|
19810
19813
|
async touch(key, additionalSeconds) {
|
|
@@ -19945,7 +19948,7 @@ class PluginStorage {
|
|
|
19945
19948
|
}
|
|
19946
19949
|
// Check expiration
|
|
19947
19950
|
const expiresAt = (data._expiresat || data._expiresAt);
|
|
19948
|
-
if (expiresAt &&
|
|
19951
|
+
if (expiresAt && this._now() > expiresAt) {
|
|
19949
19952
|
await this.delete(key);
|
|
19950
19953
|
return { data: null, version: null };
|
|
19951
19954
|
}
|
|
@@ -20014,7 +20017,7 @@ class PluginStorage {
|
|
|
20014
20017
|
const newValue = currentValue + amount;
|
|
20015
20018
|
parsedMetadata.value = newValue;
|
|
20016
20019
|
if (options.ttl) {
|
|
20017
|
-
parsedMetadata._expiresAt =
|
|
20020
|
+
parsedMetadata._expiresAt = this._now() + (options.ttl * 1000);
|
|
20018
20021
|
}
|
|
20019
20022
|
const encodedMetadata = {};
|
|
20020
20023
|
for (const [metaKey, metaValue] of Object.entries(parsedMetadata)) {
|
|
@@ -20051,7 +20054,7 @@ class PluginStorage {
|
|
|
20051
20054
|
value: initialValue + increment,
|
|
20052
20055
|
name,
|
|
20053
20056
|
resourceName,
|
|
20054
|
-
createdAt:
|
|
20057
|
+
createdAt: this._now()
|
|
20055
20058
|
}, { behavior: 'body-only' });
|
|
20056
20059
|
return initialValue;
|
|
20057
20060
|
}
|
|
@@ -20059,7 +20062,7 @@ class PluginStorage {
|
|
|
20059
20062
|
await this.set(valueKey, {
|
|
20060
20063
|
...data,
|
|
20061
20064
|
value: currentValue + increment,
|
|
20062
|
-
updatedAt:
|
|
20065
|
+
updatedAt: this._now()
|
|
20063
20066
|
}, { behavior: 'body-only' });
|
|
20064
20067
|
return currentValue;
|
|
20065
20068
|
});
|
|
@@ -20078,13 +20081,13 @@ class PluginStorage {
|
|
|
20078
20081
|
async _withSequenceLock(lockKey, options, callback) {
|
|
20079
20082
|
const { ttl = 30, timeout = 5000 } = options;
|
|
20080
20083
|
const token = idGenerator();
|
|
20081
|
-
const startTime =
|
|
20084
|
+
const startTime = this._now();
|
|
20082
20085
|
let attempt = 0;
|
|
20083
20086
|
while (true) {
|
|
20084
20087
|
const payload = {
|
|
20085
20088
|
token,
|
|
20086
|
-
acquiredAt:
|
|
20087
|
-
_expiresAt:
|
|
20089
|
+
acquiredAt: this._now(),
|
|
20090
|
+
_expiresAt: this._now() + (ttl * 1000)
|
|
20088
20091
|
};
|
|
20089
20092
|
const [ok, err] = await tryFn(() => this.set(lockKey, payload, {
|
|
20090
20093
|
behavior: 'body-only',
|
|
@@ -20104,13 +20107,13 @@ class PluginStorage {
|
|
|
20104
20107
|
if (!isPreconditionFailure(err)) {
|
|
20105
20108
|
throw err;
|
|
20106
20109
|
}
|
|
20107
|
-
if (timeout !== undefined &&
|
|
20110
|
+
if (timeout !== undefined && this._now() - startTime >= timeout) {
|
|
20108
20111
|
return null;
|
|
20109
20112
|
}
|
|
20110
20113
|
const current = await this.get(lockKey);
|
|
20111
20114
|
if (!current)
|
|
20112
20115
|
continue;
|
|
20113
|
-
if (current._expiresAt &&
|
|
20116
|
+
if (current._expiresAt && this._now() > current._expiresAt) {
|
|
20114
20117
|
await tryFn(() => this.delete(lockKey));
|
|
20115
20118
|
continue;
|
|
20116
20119
|
}
|
|
@@ -20135,9 +20138,9 @@ class PluginStorage {
|
|
|
20135
20138
|
value,
|
|
20136
20139
|
name,
|
|
20137
20140
|
resourceName,
|
|
20138
|
-
createdAt: data?.createdAt ||
|
|
20139
|
-
updatedAt:
|
|
20140
|
-
resetAt:
|
|
20141
|
+
createdAt: data?.createdAt || this._now(),
|
|
20142
|
+
updatedAt: this._now(),
|
|
20143
|
+
resetAt: this._now()
|
|
20141
20144
|
}, { behavior: 'body-only' });
|
|
20142
20145
|
return true;
|
|
20143
20146
|
});
|