@acodeninja/persist 3.3.0 → 3.3.1-next.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.
- package/docs/storage-engines.md +20 -25
- package/package.json +18 -18
- package/src/engine/storage/S3StorageEngine.js +4 -0
package/docs/storage-engines.md
CHANGED
|
@@ -23,40 +23,35 @@ export class Tag extends Persist.Model {
|
|
|
23
23
|
await connection.put(new Tag({tag: 'documentation'}));
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
###
|
|
26
|
+
### Caching and stale reads
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
The engine stamps a `Cache-Control` header on every object it writes (models,
|
|
29
|
+
find indexes, and search indexes). By default this is `no-cache`, which lets a
|
|
30
|
+
browser store the object body but requires it to revalidate against S3 (a
|
|
31
|
+
conditional GET on the ETag) before reuse — S3 answers `304 Not Modified` when
|
|
32
|
+
nothing changed, or `200` with fresh data when it did.
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
This matters in the browser: without a stored cache directive, browsers apply
|
|
35
|
+
*heuristic caching* to S3 objects and can serve a stale `_index.json` shortly
|
|
36
|
+
after a write — showing missing new records or lingering deleted ones until a
|
|
37
|
+
hard reload. Stamping `no-cache` on writes avoids this, and because the directive
|
|
38
|
+
travels on the object itself, no read-side or client configuration is needed.
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
client.middlewareStack.add(
|
|
38
|
-
(next, context) => (args) => {
|
|
39
|
-
args.request.headers['pragma'] = 'no-cache';
|
|
40
|
-
return next(args);
|
|
41
|
-
},
|
|
42
|
-
{step: 'build'},
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
client.middlewareStack.add(
|
|
46
|
-
(next, context) => (args) => {
|
|
47
|
-
args.input.ResponseCacheControl = 'no-cache';
|
|
48
|
-
return next(args);
|
|
49
|
-
},
|
|
50
|
-
{step: 'serialize'},
|
|
51
|
-
);
|
|
40
|
+
If you knowingly serve immutable data and want to opt out (or use a different
|
|
41
|
+
directive), set `cacheControl` on the engine configuration:
|
|
52
42
|
|
|
43
|
+
```javascript
|
|
53
44
|
const connection = Persist.registerConnection('remote', new S3StorageEngine({
|
|
54
45
|
bucket: 'test-bucket',
|
|
55
|
-
client,
|
|
46
|
+
client: new S3Client(),
|
|
47
|
+
cacheControl: 'max-age=31536000, immutable',
|
|
56
48
|
}));
|
|
57
49
|
```
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
> Objects written before this behaviour existed keep serving without the header
|
|
52
|
+
> until they are rewritten. Indexes fix themselves on the next mutation; to update
|
|
53
|
+
> an entire bucket at once you can run:
|
|
54
|
+
> `aws s3 cp s3://bucket s3://bucket --recursive --metadata-directive REPLACE --cache-control no-cache`
|
|
60
55
|
|
|
61
56
|
## HTTP Storage StorageEngine
|
|
62
57
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acodeninja/persist",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1-next.1",
|
|
4
4
|
"description": "A JSON based data modelling and persistence module with alternate storage mechanisms.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
8
|
-
"test:watch": "
|
|
9
|
-
"test:coverage": "
|
|
7
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
8
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
9
|
+
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --collect-coverage",
|
|
10
10
|
"lint": "eslint ./",
|
|
11
11
|
"prepare": "husky"
|
|
12
12
|
},
|
|
@@ -22,27 +22,27 @@
|
|
|
22
22
|
"provenance": true
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"ajv": "^8.
|
|
25
|
+
"ajv": "^8.20.0",
|
|
26
26
|
"ajv-errors": "^3.0.0",
|
|
27
27
|
"ajv-formats": "^3.0.1",
|
|
28
|
-
"fuse.js": "^7.
|
|
29
|
-
"lodash": "^4.
|
|
30
|
-
"slugify": "^1.6.
|
|
31
|
-
"ulid": "^
|
|
28
|
+
"fuse.js": "^7.5.0",
|
|
29
|
+
"lodash": "^4.18.1",
|
|
30
|
+
"slugify": "^1.6.9",
|
|
31
|
+
"ulid": "^3.0.2"
|
|
32
32
|
},
|
|
33
33
|
"optionalDependencies": {
|
|
34
|
-
"@aws-sdk/client-s3": "^3.
|
|
34
|
+
"@aws-sdk/client-s3": "^3.1118.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@commitlint/cli": "^
|
|
38
|
-
"@commitlint/config-conventional": "^
|
|
39
|
-
"@eslint/js": "^
|
|
40
|
-
"@jest/globals": "^
|
|
37
|
+
"@commitlint/cli": "^21.2.2",
|
|
38
|
+
"@commitlint/config-conventional": "^21.2.2",
|
|
39
|
+
"@eslint/js": "^10.0.1",
|
|
40
|
+
"@jest/globals": "^30.4.1",
|
|
41
41
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
42
|
-
"eslint": "^9.
|
|
43
|
-
"globals": "^
|
|
42
|
+
"eslint": "^10.9.1",
|
|
43
|
+
"globals": "^17.11.0",
|
|
44
44
|
"husky": "^9.1.7",
|
|
45
|
-
"jest": "^
|
|
46
|
-
"semantic-release": "^
|
|
45
|
+
"jest": "^30.4.2",
|
|
46
|
+
"semantic-release": "^25.0.9"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -15,6 +15,7 @@ class S3StorageEngine extends StorageEngine {
|
|
|
15
15
|
* @param {string} [configuration.bucket] - Hostname and protocol of the HTTP service to use (ie: https://example.com).
|
|
16
16
|
* @param {string?} [configuration.prefix] - The prefix on the host to perform operations against.
|
|
17
17
|
* @param {S3Client} [configuration.client] - The http client that implements fetch.
|
|
18
|
+
* @param {string?} [configuration.cacheControl] - Cache-Control header stamped on written objects. Defaults to 'no-cache'.
|
|
18
19
|
*/
|
|
19
20
|
constructor(configuration) {
|
|
20
21
|
super(configuration);
|
|
@@ -59,6 +60,7 @@ class S3StorageEngine extends StorageEngine {
|
|
|
59
60
|
Body: JSON.stringify(model),
|
|
60
61
|
Bucket: this.configuration.bucket,
|
|
61
62
|
ContentType: 'application/json',
|
|
63
|
+
CacheControl: this.configuration.cacheControl ?? 'no-cache',
|
|
62
64
|
}));
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -120,6 +122,7 @@ class S3StorageEngine extends StorageEngine {
|
|
|
120
122
|
Bucket: this.configuration.bucket,
|
|
121
123
|
Body: JSON.stringify(index),
|
|
122
124
|
ContentType: 'application/json',
|
|
125
|
+
CacheControl: this.configuration.cacheControl ?? 'no-cache',
|
|
123
126
|
}));
|
|
124
127
|
}
|
|
125
128
|
|
|
@@ -160,6 +163,7 @@ class S3StorageEngine extends StorageEngine {
|
|
|
160
163
|
Bucket: this.configuration.bucket,
|
|
161
164
|
Body: JSON.stringify(index),
|
|
162
165
|
ContentType: 'application/json',
|
|
166
|
+
CacheControl: this.configuration.cacheControl ?? 'no-cache',
|
|
163
167
|
}));
|
|
164
168
|
}
|
|
165
169
|
|