@tramvai/module-server 7.5.3 → 7.11.0
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/README.md +30 -0
- package/lib/server/etag/fnv1a.d.ts +7 -0
- package/lib/server/etag/fnv1a.es.js +87 -0
- package/lib/server/etag/fnv1a.js +91 -0
- package/lib/server/etag/providers.d.ts +19 -0
- package/lib/server/etag/providers.es.js +63 -0
- package/lib/server/etag/providers.js +67 -0
- package/lib/server.es.js +2 -0
- package/lib/server.js +2 -0
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -236,6 +236,36 @@ HTTP/1.1 200 OK
|
|
|
236
236
|
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
+
### ETag header
|
|
240
|
+
|
|
241
|
+
Tramvai support [ETag header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag) generation for application pages - it can speed up the page loading for repeated visits.
|
|
242
|
+
|
|
243
|
+
:::warning
|
|
244
|
+
|
|
245
|
+
ETag generation is a heavy operation for a big pages and can negatively affect the application performance.
|
|
246
|
+
|
|
247
|
+
:::
|
|
248
|
+
|
|
249
|
+
:::warning
|
|
250
|
+
|
|
251
|
+
ETag generation is incompatible with `@tramvai/module-opentelementry`, because request trace id is injected to the page HTML content in `<meta name="traceparent" />` tag.
|
|
252
|
+
|
|
253
|
+
:::
|
|
254
|
+
|
|
255
|
+
To enable ETag header, provide `ETAG_OPTIONS_TOKEN` token:
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const provider = provide({
|
|
259
|
+
provide: ETAG_OPTIONS_TOKEN,
|
|
260
|
+
useValue: {
|
|
261
|
+
enabled: true,
|
|
262
|
+
// by default, ETag is generated based on the content of the page, which is not the best option for performance,
|
|
263
|
+
// you can pass `weak: true` parameter to generate weak ETag based on the hash of the initial state of the page, which can be faster
|
|
264
|
+
weak: false,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
239
269
|
## How to
|
|
240
270
|
|
|
241
271
|
### Setting `keepAliveTimeout` for the server
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/**
|
|
3
|
+
* @reference https://github.com/fastify/fastify-etag/blob/main/fnv1a.js
|
|
4
|
+
* Work faster than `etag` and `fnv-plus` libraries
|
|
5
|
+
*/
|
|
6
|
+
export declare function fnv1a(str: string | Buffer): number;
|
|
7
|
+
//# sourceMappingURL=fnv1a.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* eslint-disable no-bitwise, @typescript-eslint/no-shadow */
|
|
2
|
+
// MIT License
|
|
3
|
+
//
|
|
4
|
+
// Copyright (c) desudesutalk (https://github.com/desudesutalk)
|
|
5
|
+
// Copyright (c) Travis Webb <me@traviswebb.com>
|
|
6
|
+
// Copyright (c) SukkaW <hi@skk.moe> (https://skk.moe)
|
|
7
|
+
//
|
|
8
|
+
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
9
|
+
// copy of this software and associated documentation files (the "Software"),
|
|
10
|
+
// to deal in the Software without restriction, including without limitation
|
|
11
|
+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
12
|
+
// and/or sell copies of the Software, and to permit persons to whom the Software
|
|
13
|
+
// is furnished to do so, subject to the following conditions:
|
|
14
|
+
//
|
|
15
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
// copies or substantial portions of the Software.
|
|
17
|
+
//
|
|
18
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
19
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
20
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
21
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
23
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
|
+
// The fnv1a implementation is created by @desudesutalk (https://github.com/desudesutalk) in
|
|
25
|
+
// https://github.com/tjwebb/fnv-plus/pull/9, and contributed to Travis Webb's
|
|
26
|
+
// "fnv-plus" library. @SukkaW (https://github.com/SukkaW) modifies it to support Buffers w/o
|
|
27
|
+
// sacrificing performance
|
|
28
|
+
/**
|
|
29
|
+
* @reference https://github.com/fastify/fastify-etag/blob/main/fnv1a.js
|
|
30
|
+
* Work faster than `etag` and `fnv-plus` libraries
|
|
31
|
+
*/
|
|
32
|
+
// eslint-disable-next-line max-statements
|
|
33
|
+
function fnv1a(str) {
|
|
34
|
+
const l = str.length - 3;
|
|
35
|
+
let i = 0;
|
|
36
|
+
let t0 = 0;
|
|
37
|
+
let v0 = 0x9dc5;
|
|
38
|
+
let t1 = 0;
|
|
39
|
+
let v1 = 0x811c;
|
|
40
|
+
let get;
|
|
41
|
+
if (str instanceof Buffer) {
|
|
42
|
+
get = (i) => str[i];
|
|
43
|
+
}
|
|
44
|
+
else if (typeof str === 'string') {
|
|
45
|
+
get = (i) => str.charCodeAt(i);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
throw new TypeError('input must be a string or a buffer');
|
|
49
|
+
}
|
|
50
|
+
while (i < l) {
|
|
51
|
+
v0 ^= get(i++);
|
|
52
|
+
t0 = v0 * 403;
|
|
53
|
+
t1 = v1 * 403;
|
|
54
|
+
t1 += v0 << 8;
|
|
55
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
56
|
+
v0 = t0 & 65535;
|
|
57
|
+
v0 ^= get(i++);
|
|
58
|
+
t0 = v0 * 403;
|
|
59
|
+
t1 = v1 * 403;
|
|
60
|
+
t1 += v0 << 8;
|
|
61
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
62
|
+
v0 = t0 & 65535;
|
|
63
|
+
v0 ^= get(i++);
|
|
64
|
+
t0 = v0 * 403;
|
|
65
|
+
t1 = v1 * 403;
|
|
66
|
+
t1 += v0 << 8;
|
|
67
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
68
|
+
v0 = t0 & 65535;
|
|
69
|
+
v0 ^= get(i++);
|
|
70
|
+
t0 = v0 * 403;
|
|
71
|
+
t1 = v1 * 403;
|
|
72
|
+
t1 += v0 << 8;
|
|
73
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
74
|
+
v0 = t0 & 65535;
|
|
75
|
+
}
|
|
76
|
+
while (i < l + 3) {
|
|
77
|
+
v0 ^= get(i++);
|
|
78
|
+
t0 = v0 * 403;
|
|
79
|
+
t1 = v1 * 403;
|
|
80
|
+
t1 += v0 << 8;
|
|
81
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
82
|
+
v0 = t0 & 65535;
|
|
83
|
+
}
|
|
84
|
+
return ((v1 << 16) >>> 0) + v0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { fnv1a };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
/* eslint-disable no-bitwise, @typescript-eslint/no-shadow */
|
|
6
|
+
// MIT License
|
|
7
|
+
//
|
|
8
|
+
// Copyright (c) desudesutalk (https://github.com/desudesutalk)
|
|
9
|
+
// Copyright (c) Travis Webb <me@traviswebb.com>
|
|
10
|
+
// Copyright (c) SukkaW <hi@skk.moe> (https://skk.moe)
|
|
11
|
+
//
|
|
12
|
+
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
13
|
+
// copy of this software and associated documentation files (the "Software"),
|
|
14
|
+
// to deal in the Software without restriction, including without limitation
|
|
15
|
+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
16
|
+
// and/or sell copies of the Software, and to permit persons to whom the Software
|
|
17
|
+
// is furnished to do so, subject to the following conditions:
|
|
18
|
+
//
|
|
19
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
// copies or substantial portions of the Software.
|
|
21
|
+
//
|
|
22
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
23
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
24
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
25
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
26
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
27
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
+
// The fnv1a implementation is created by @desudesutalk (https://github.com/desudesutalk) in
|
|
29
|
+
// https://github.com/tjwebb/fnv-plus/pull/9, and contributed to Travis Webb's
|
|
30
|
+
// "fnv-plus" library. @SukkaW (https://github.com/SukkaW) modifies it to support Buffers w/o
|
|
31
|
+
// sacrificing performance
|
|
32
|
+
/**
|
|
33
|
+
* @reference https://github.com/fastify/fastify-etag/blob/main/fnv1a.js
|
|
34
|
+
* Work faster than `etag` and `fnv-plus` libraries
|
|
35
|
+
*/
|
|
36
|
+
// eslint-disable-next-line max-statements
|
|
37
|
+
function fnv1a(str) {
|
|
38
|
+
const l = str.length - 3;
|
|
39
|
+
let i = 0;
|
|
40
|
+
let t0 = 0;
|
|
41
|
+
let v0 = 0x9dc5;
|
|
42
|
+
let t1 = 0;
|
|
43
|
+
let v1 = 0x811c;
|
|
44
|
+
let get;
|
|
45
|
+
if (str instanceof Buffer) {
|
|
46
|
+
get = (i) => str[i];
|
|
47
|
+
}
|
|
48
|
+
else if (typeof str === 'string') {
|
|
49
|
+
get = (i) => str.charCodeAt(i);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
throw new TypeError('input must be a string or a buffer');
|
|
53
|
+
}
|
|
54
|
+
while (i < l) {
|
|
55
|
+
v0 ^= get(i++);
|
|
56
|
+
t0 = v0 * 403;
|
|
57
|
+
t1 = v1 * 403;
|
|
58
|
+
t1 += v0 << 8;
|
|
59
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
60
|
+
v0 = t0 & 65535;
|
|
61
|
+
v0 ^= get(i++);
|
|
62
|
+
t0 = v0 * 403;
|
|
63
|
+
t1 = v1 * 403;
|
|
64
|
+
t1 += v0 << 8;
|
|
65
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
66
|
+
v0 = t0 & 65535;
|
|
67
|
+
v0 ^= get(i++);
|
|
68
|
+
t0 = v0 * 403;
|
|
69
|
+
t1 = v1 * 403;
|
|
70
|
+
t1 += v0 << 8;
|
|
71
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
72
|
+
v0 = t0 & 65535;
|
|
73
|
+
v0 ^= get(i++);
|
|
74
|
+
t0 = v0 * 403;
|
|
75
|
+
t1 = v1 * 403;
|
|
76
|
+
t1 += v0 << 8;
|
|
77
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
78
|
+
v0 = t0 & 65535;
|
|
79
|
+
}
|
|
80
|
+
while (i < l + 3) {
|
|
81
|
+
v0 ^= get(i++);
|
|
82
|
+
t0 = v0 * 403;
|
|
83
|
+
t1 = v1 * 403;
|
|
84
|
+
t1 += v0 << 8;
|
|
85
|
+
v1 = (t1 + (t0 >>> 16)) & 65535;
|
|
86
|
+
v0 = t0 & 65535;
|
|
87
|
+
}
|
|
88
|
+
return ((v1 << 16) >>> 0) + v0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exports.fnv1a = fnv1a;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
export declare const providers: (import("@tinkoff/dippy").Provider<{
|
|
4
|
+
etagOptions: {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
weak?: boolean;
|
|
7
|
+
} & {
|
|
8
|
+
__type?: "base token";
|
|
9
|
+
};
|
|
10
|
+
storage: import("async_hooks").AsyncLocalStorage<import("@tramvai/tokens-common").AsyncLocalStorageState> & {
|
|
11
|
+
__type?: "base token";
|
|
12
|
+
};
|
|
13
|
+
}, (app: import("fastify").FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>) => void> | import("@tinkoff/dippy").Provider<unknown, {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
weak?: boolean;
|
|
16
|
+
} & {
|
|
17
|
+
__type?: "base token";
|
|
18
|
+
}>)[];
|
|
19
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { provide } from '@tinkoff/dippy';
|
|
2
|
+
import { REQUEST_MANAGER_TOKEN, RESPONSE_MANAGER_TOKEN, CONTEXT_TOKEN, ASYNC_LOCAL_STORAGE_TOKEN } from '@tramvai/tokens-common';
|
|
3
|
+
import { ETAG_OPTIONS_TOKEN } from '@tramvai/tokens-server';
|
|
4
|
+
import { WEB_FASTIFY_APP_INIT_TOKEN } from '@tramvai/tokens-server-private';
|
|
5
|
+
import { fnv1a } from './fnv1a.es.js';
|
|
6
|
+
|
|
7
|
+
const providers = [
|
|
8
|
+
provide({
|
|
9
|
+
provide: WEB_FASTIFY_APP_INIT_TOKEN,
|
|
10
|
+
useFactory: ({ etagOptions, storage }) => {
|
|
11
|
+
return (app) => {
|
|
12
|
+
if (!etagOptions.enabled) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
app.addHook('onSend', function (req, reply, payload, done) {
|
|
16
|
+
const di = storage.getStore()?.tramvaiRequestDi;
|
|
17
|
+
if (di) {
|
|
18
|
+
const requestManager = di.get(REQUEST_MANAGER_TOKEN);
|
|
19
|
+
const responseManager = di.get(RESPONSE_MANAGER_TOKEN);
|
|
20
|
+
const context = di.get(CONTEXT_TOKEN);
|
|
21
|
+
const currentEtag = responseManager.getHeader('etag');
|
|
22
|
+
if (!currentEtag) {
|
|
23
|
+
const prefix = etagOptions.weak ? 'W/"' : '"';
|
|
24
|
+
const etag = `${prefix +
|
|
25
|
+
fnv1a(etagOptions.weak
|
|
26
|
+
? // TODO: customize weak strategy
|
|
27
|
+
JSON.stringify(context.dehydrate().dispatcher)
|
|
28
|
+
: responseManager.getBody()).toString(36)}"`;
|
|
29
|
+
responseManager.setHeader('etag', etag);
|
|
30
|
+
reply.header('etag', etag);
|
|
31
|
+
}
|
|
32
|
+
const etag = responseManager.getHeader('etag');
|
|
33
|
+
const ifNoneMatch = requestManager.getHeader('if-none-match');
|
|
34
|
+
if (ifNoneMatch === etag ||
|
|
35
|
+
ifNoneMatch === `W/${etag}` ||
|
|
36
|
+
`W/${ifNoneMatch}` === etag) {
|
|
37
|
+
reply.code(304);
|
|
38
|
+
done(null, '');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
done(null, payload);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
done(null, payload);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
deps: {
|
|
51
|
+
etagOptions: ETAG_OPTIONS_TOKEN,
|
|
52
|
+
storage: ASYNC_LOCAL_STORAGE_TOKEN,
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
provide({
|
|
56
|
+
provide: ETAG_OPTIONS_TOKEN,
|
|
57
|
+
useValue: {
|
|
58
|
+
enabled: false,
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
export { providers };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dippy = require('@tinkoff/dippy');
|
|
6
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
7
|
+
var tokensServer = require('@tramvai/tokens-server');
|
|
8
|
+
var tokensServerPrivate = require('@tramvai/tokens-server-private');
|
|
9
|
+
var fnv1a = require('./fnv1a.js');
|
|
10
|
+
|
|
11
|
+
const providers = [
|
|
12
|
+
dippy.provide({
|
|
13
|
+
provide: tokensServerPrivate.WEB_FASTIFY_APP_INIT_TOKEN,
|
|
14
|
+
useFactory: ({ etagOptions, storage }) => {
|
|
15
|
+
return (app) => {
|
|
16
|
+
if (!etagOptions.enabled) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
app.addHook('onSend', function (req, reply, payload, done) {
|
|
20
|
+
const di = storage.getStore()?.tramvaiRequestDi;
|
|
21
|
+
if (di) {
|
|
22
|
+
const requestManager = di.get(tokensCommon.REQUEST_MANAGER_TOKEN);
|
|
23
|
+
const responseManager = di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
|
|
24
|
+
const context = di.get(tokensCommon.CONTEXT_TOKEN);
|
|
25
|
+
const currentEtag = responseManager.getHeader('etag');
|
|
26
|
+
if (!currentEtag) {
|
|
27
|
+
const prefix = etagOptions.weak ? 'W/"' : '"';
|
|
28
|
+
const etag = `${prefix +
|
|
29
|
+
fnv1a.fnv1a(etagOptions.weak
|
|
30
|
+
? // TODO: customize weak strategy
|
|
31
|
+
JSON.stringify(context.dehydrate().dispatcher)
|
|
32
|
+
: responseManager.getBody()).toString(36)}"`;
|
|
33
|
+
responseManager.setHeader('etag', etag);
|
|
34
|
+
reply.header('etag', etag);
|
|
35
|
+
}
|
|
36
|
+
const etag = responseManager.getHeader('etag');
|
|
37
|
+
const ifNoneMatch = requestManager.getHeader('if-none-match');
|
|
38
|
+
if (ifNoneMatch === etag ||
|
|
39
|
+
ifNoneMatch === `W/${etag}` ||
|
|
40
|
+
`W/${ifNoneMatch}` === etag) {
|
|
41
|
+
reply.code(304);
|
|
42
|
+
done(null, '');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
done(null, payload);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
done(null, payload);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
deps: {
|
|
55
|
+
etagOptions: tokensServer.ETAG_OPTIONS_TOKEN,
|
|
56
|
+
storage: tokensCommon.ASYNC_LOCAL_STORAGE_TOKEN,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
dippy.provide({
|
|
60
|
+
provide: tokensServer.ETAG_OPTIONS_TOKEN,
|
|
61
|
+
useValue: {
|
|
62
|
+
enabled: false,
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
exports.providers = providers;
|
package/lib/server.es.js
CHANGED
|
@@ -28,6 +28,7 @@ import { KeepAliveModule } from './modules/keepAlive.es.js';
|
|
|
28
28
|
import { ServerTimingModule } from './modules/serverTiming.es.js';
|
|
29
29
|
import { EarlyHintsModule } from './modules/earlyHints/index.es.js';
|
|
30
30
|
import { ServerResponseTaskManager } from './server/taskManager.es.js';
|
|
31
|
+
import { providers } from './server/etag/providers.es.js';
|
|
31
32
|
|
|
32
33
|
if (typeof setDefaultResultOrder === 'function') {
|
|
33
34
|
setDefaultResultOrder('ipv4first');
|
|
@@ -57,6 +58,7 @@ ServerModule = __decorate([
|
|
|
57
58
|
process.env.NODE_ENV !== 'production' && DebugHttpRequestsModule,
|
|
58
59
|
].filter(Boolean),
|
|
59
60
|
providers: [
|
|
61
|
+
...providers,
|
|
60
62
|
provide({
|
|
61
63
|
provide: SERVER_FACTORY_TOKEN,
|
|
62
64
|
scope: Scope.SINGLETON,
|
package/lib/server.js
CHANGED
|
@@ -31,6 +31,7 @@ var keepAlive = require('./modules/keepAlive.js');
|
|
|
31
31
|
var serverTiming = require('./modules/serverTiming.js');
|
|
32
32
|
var index = require('./modules/earlyHints/index.js');
|
|
33
33
|
var taskManager = require('./server/taskManager.js');
|
|
34
|
+
var providers = require('./server/etag/providers.js');
|
|
34
35
|
|
|
35
36
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
36
37
|
|
|
@@ -64,6 +65,7 @@ exports.ServerModule = tslib.__decorate([
|
|
|
64
65
|
process.env.NODE_ENV !== 'production' && debugRequests.DebugHttpRequestsModule,
|
|
65
66
|
].filter(Boolean),
|
|
66
67
|
providers: [
|
|
68
|
+
...providers.providers,
|
|
67
69
|
core.provide({
|
|
68
70
|
provide: tokensServerPrivate.SERVER_FACTORY_TOKEN,
|
|
69
71
|
scope: core.Scope.SINGLETON,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.11.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"browser": "lib/browser.js",
|
|
6
6
|
"main": "lib/server.js",
|
|
@@ -30,29 +30,29 @@
|
|
|
30
30
|
"@tinkoff/monkeypatch": "7.0.1",
|
|
31
31
|
"@tinkoff/terminus": "0.6.1",
|
|
32
32
|
"@tinkoff/url": "0.13.1",
|
|
33
|
-
"@tramvai/module-cache-warmup": "7.
|
|
34
|
-
"@tramvai/module-metrics": "7.
|
|
35
|
-
"@tramvai/papi": "7.
|
|
33
|
+
"@tramvai/module-cache-warmup": "7.11.0",
|
|
34
|
+
"@tramvai/module-metrics": "7.11.0",
|
|
35
|
+
"@tramvai/papi": "7.11.0",
|
|
36
36
|
"@tramvai/safe-strings": "0.10.1",
|
|
37
|
-
"@tramvai/tokens-router": "7.
|
|
38
|
-
"@tramvai/tokens-server": "7.
|
|
39
|
-
"@tramvai/tokens-server-private": "7.
|
|
37
|
+
"@tramvai/tokens-router": "7.11.0",
|
|
38
|
+
"@tramvai/tokens-server": "7.11.0",
|
|
39
|
+
"@tramvai/tokens-server-private": "7.11.0",
|
|
40
40
|
"afterframe": "^1.0.2",
|
|
41
41
|
"fastify": "^5.6.2",
|
|
42
42
|
"http-proxy-middleware": "^2.0.2",
|
|
43
|
-
"undici": "^7.
|
|
43
|
+
"undici": "^7.24.4"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@tinkoff/dippy": "0.13.2",
|
|
47
47
|
"@tinkoff/utils": "^2.1.2",
|
|
48
|
-
"@tramvai/cli": "7.
|
|
49
|
-
"@tramvai/core": "7.
|
|
50
|
-
"@tramvai/module-common": "7.
|
|
51
|
-
"@tramvai/module-environment": "7.
|
|
52
|
-
"@tramvai/react": "7.
|
|
53
|
-
"@tramvai/tokens-common": "7.
|
|
54
|
-
"@tramvai/tokens-core-private": "7.
|
|
55
|
-
"@tramvai/tokens-render": "7.
|
|
48
|
+
"@tramvai/cli": "7.11.0",
|
|
49
|
+
"@tramvai/core": "7.11.0",
|
|
50
|
+
"@tramvai/module-common": "7.11.0",
|
|
51
|
+
"@tramvai/module-environment": "7.11.0",
|
|
52
|
+
"@tramvai/react": "7.11.0",
|
|
53
|
+
"@tramvai/tokens-common": "7.11.0",
|
|
54
|
+
"@tramvai/tokens-core-private": "7.11.0",
|
|
55
|
+
"@tramvai/tokens-render": "7.11.0",
|
|
56
56
|
"react": ">=16.14.0",
|
|
57
57
|
"react-dom": ">=16.14.0",
|
|
58
58
|
"tslib": "^2.4.0"
|