@tramvai/module-page-render-mode 7.5.3 → 7.7.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.
Files changed (35) hide show
  1. package/lib/PageRenderWrapper.browser.js +4 -4
  2. package/lib/PageRenderWrapper.d.ts +1 -1
  3. package/lib/PageRenderWrapper.es.js +4 -4
  4. package/lib/PageRenderWrapper.js +3 -3
  5. package/lib/browser.js +27 -3
  6. package/lib/private-tokens.browser.js +9 -0
  7. package/lib/private-tokens.d.ts +27 -0
  8. package/lib/private-tokens.es.js +9 -0
  9. package/lib/private-tokens.js +17 -0
  10. package/lib/server.es.js +1 -1
  11. package/lib/server.js +5 -0
  12. package/lib/staticPages/backgroundFetchService.d.ts +9 -7
  13. package/lib/staticPages/backgroundFetchService.es.js +20 -20
  14. package/lib/staticPages/backgroundFetchService.js +20 -20
  15. package/lib/staticPages/fileSystemCache.d.ts +72 -0
  16. package/lib/staticPages/fileSystemCache.es.js +367 -0
  17. package/lib/staticPages/fileSystemCache.js +376 -0
  18. package/lib/staticPages/staticPagesService.d.ts +16 -9
  19. package/lib/staticPages/staticPagesService.es.js +124 -39
  20. package/lib/staticPages/staticPagesService.js +124 -39
  21. package/lib/staticPages.d.ts +410 -155
  22. package/lib/staticPages.es.js +233 -67
  23. package/lib/staticPages.js +232 -70
  24. package/lib/tokens.browser.js +15 -1
  25. package/lib/tokens.d.ts +90 -32
  26. package/lib/tokens.es.js +15 -1
  27. package/lib/tokens.js +19 -0
  28. package/lib/utils/cacheKey.d.ts +4 -6
  29. package/lib/utils/cacheKey.es.js +8 -3
  30. package/lib/utils/cacheKey.js +8 -2
  31. package/lib/utils/getPageRenderMode.browser.js +14 -2
  32. package/lib/utils/getPageRenderMode.d.ts +8 -3
  33. package/lib/utils/getPageRenderMode.es.js +14 -2
  34. package/lib/utils/getPageRenderMode.js +14 -2
  35. package/package.json +16 -14
@@ -2,20 +2,20 @@ import { jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useState, useEffect } from 'react';
3
3
  import { useDi } from '@tramvai/react';
4
4
  import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
5
- import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from './tokens.browser.js';
6
- import { getPageRenderMode } from './utils/getPageRenderMode.browser.js';
5
+ import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from './tokens.browser.js';
6
+ import { STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE } from './private-tokens.browser.js';
7
7
 
8
8
  const PageRenderWrapper = ({ children }) => {
9
9
  const [mounted, setMounted] = useState(false);
10
10
  const pageService = useDi(PAGE_SERVICE_TOKEN);
11
+ const resolvePageRenderMode = useDi(STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE);
11
12
  const fallbackKey = useDi(PAGE_RENDER_FALLBACK_COMPONENT_PREFIX);
12
- const defaultRenderMode = useDi(PAGE_RENDER_DEFAULT_MODE);
13
13
  const DefaultFallbackComponent = useDi({
14
14
  token: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
15
15
  optional: true,
16
16
  });
17
17
  const FallbackComponent = pageService.resolveComponentFromConfig(fallbackKey) || DefaultFallbackComponent;
18
- const mode = getPageRenderMode({ pageService, defaultRenderMode });
18
+ const mode = resolvePageRenderMode();
19
19
  useEffect(() => {
20
20
  if (mode === 'client') {
21
21
  setMounted(true);
@@ -1,4 +1,4 @@
1
1
  import type { PropsWithChildren } from 'react';
2
- export declare const PageRenderWrapper: ({ children }: PropsWithChildren<{}>) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const PageRenderWrapper: ({ children }: PropsWithChildren<{}>) => import("react/jsx-runtime").JSX.Element | null;
3
3
  export declare const pageRenderHOC: (WrapperPage: any) => (props: any) => import("react/jsx-runtime").JSX.Element;
4
4
  //# sourceMappingURL=PageRenderWrapper.d.ts.map
@@ -2,20 +2,20 @@ import { jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useState, useEffect } from 'react';
3
3
  import { useDi } from '@tramvai/react';
4
4
  import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
5
- import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from './tokens.es.js';
6
- import { getPageRenderMode } from './utils/getPageRenderMode.es.js';
5
+ import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from './tokens.es.js';
6
+ import { STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE } from './private-tokens.es.js';
7
7
 
8
8
  const PageRenderWrapper = ({ children }) => {
9
9
  const [mounted, setMounted] = useState(false);
10
10
  const pageService = useDi(PAGE_SERVICE_TOKEN);
11
+ const resolvePageRenderMode = useDi(STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE);
11
12
  const fallbackKey = useDi(PAGE_RENDER_FALLBACK_COMPONENT_PREFIX);
12
- const defaultRenderMode = useDi(PAGE_RENDER_DEFAULT_MODE);
13
13
  const DefaultFallbackComponent = useDi({
14
14
  token: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
15
15
  optional: true,
16
16
  });
17
17
  const FallbackComponent = pageService.resolveComponentFromConfig(fallbackKey) || DefaultFallbackComponent;
18
- const mode = getPageRenderMode({ pageService, defaultRenderMode });
18
+ const mode = resolvePageRenderMode();
19
19
  useEffect(() => {
20
20
  if (mode === 'client') {
21
21
  setMounted(true);
@@ -7,19 +7,19 @@ var react = require('react');
7
7
  var react$1 = require('@tramvai/react');
8
8
  var tokensRouter = require('@tramvai/tokens-router');
9
9
  var tokens = require('./tokens.js');
10
- var getPageRenderMode = require('./utils/getPageRenderMode.js');
10
+ var privateTokens = require('./private-tokens.js');
11
11
 
12
12
  const PageRenderWrapper = ({ children }) => {
13
13
  const [mounted, setMounted] = react.useState(false);
14
14
  const pageService = react$1.useDi(tokensRouter.PAGE_SERVICE_TOKEN);
15
+ const resolvePageRenderMode = react$1.useDi(privateTokens.STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE);
15
16
  const fallbackKey = react$1.useDi(tokens.PAGE_RENDER_FALLBACK_COMPONENT_PREFIX);
16
- const defaultRenderMode = react$1.useDi(tokens.PAGE_RENDER_DEFAULT_MODE);
17
17
  const DefaultFallbackComponent = react$1.useDi({
18
18
  token: tokens.PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
19
19
  optional: true,
20
20
  });
21
21
  const FallbackComponent = pageService.resolveComponentFromConfig(fallbackKey) || DefaultFallbackComponent;
22
- const mode = getPageRenderMode.getPageRenderMode({ pageService, defaultRenderMode });
22
+ const mode = resolvePageRenderMode();
23
23
  react.useEffect(() => {
24
24
  if (mode === 'client') {
25
25
  setMounted(true);
package/lib/browser.js CHANGED
@@ -1,13 +1,37 @@
1
- import { declareModule } from '@tramvai/core';
1
+ import { declareModule, provide } from '@tramvai/core';
2
+ import { REQUEST_MANAGER_TOKEN } from '@tramvai/tokens-common';
3
+ import { ROUTER_TOKEN, PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
2
4
  import { ForceCSRModule } from './ForceCSRModule.browser.js';
3
5
  import { sharedProviders } from './shared.browser.js';
4
- export { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_WRAPPER_TYPE, STATIC_PAGES_BACKGROUND_FETCH_ENABLED, STATIC_PAGES_CACHE_5xx_RESPONSE, STATIC_PAGES_CACHE_TOKEN, STATIC_PAGES_COMMAND_LINE, STATIC_PAGES_MODIFY_CACHE, STATIC_PAGES_OPTIONS_TOKEN, STATIC_PAGES_SHOULD_USE_CACHE } from './tokens.browser.js';
6
+ import { STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE } from './private-tokens.browser.js';
7
+ import { getPageRenderMode } from './utils/getPageRenderMode.browser.js';
8
+ import { PAGE_RENDER_DEFAULT_MODE } from './tokens.browser.js';
9
+ export { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_WRAPPER_TYPE, STATIC_PAGES_BACKGROUND_FETCH_ENABLED, STATIC_PAGES_CACHE_5xx_RESPONSE, STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN, STATIC_PAGES_CACHE_TOKEN, STATIC_PAGES_COMMAND_LINE, STATIC_PAGES_FS_CACHE_ENABLED, STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN, STATIC_PAGES_KEY_TOKEN, STATIC_PAGES_MODIFY_CACHE, STATIC_PAGES_OPTIONS_TOKEN, STATIC_PAGES_SERVICE, STATIC_PAGES_SHOULD_USE_CACHE } from './tokens.browser.js';
5
10
 
6
11
  // @todo: перенести в @tramvai/module-render
7
12
  const PageRenderModeModule = declareModule({
8
13
  name: 'PageRenderModeModule',
9
14
  imports: [ForceCSRModule],
10
- providers: [...sharedProviders],
15
+ providers: [
16
+ ...sharedProviders,
17
+ provide({
18
+ provide: STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE,
19
+ useFactory: ({ requestManager, pageService, router, defaultRenderMode }) => {
20
+ return () => getPageRenderMode({
21
+ pageService,
22
+ router,
23
+ requestManager,
24
+ defaultRenderMode,
25
+ });
26
+ },
27
+ deps: {
28
+ requestManager: REQUEST_MANAGER_TOKEN,
29
+ router: ROUTER_TOKEN,
30
+ pageService: PAGE_SERVICE_TOKEN,
31
+ defaultRenderMode: PAGE_RENDER_DEFAULT_MODE,
32
+ },
33
+ }),
34
+ ],
11
35
  });
12
36
 
13
37
  export { PageRenderModeModule };
@@ -0,0 +1,9 @@
1
+ import { createToken } from '@tramvai/core';
2
+
3
+ createToken();
4
+ createToken();
5
+ createToken();
6
+ createToken();
7
+ const STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE = createToken();
8
+
9
+ export { STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE };
@@ -0,0 +1,27 @@
1
+ import type { Counter, Gauge } from 'prom-client';
2
+ import { TramvaiRenderMode } from '@tramvai/tokens-render';
3
+ import { BackgroundFetchService } from './staticPages/backgroundFetchService';
4
+ import { FileSystemCache } from './staticPages/fileSystemCache';
5
+ export declare const STATIC_PAGES_BACKGROUND_FETCH_SERVICE: BackgroundFetchService & {
6
+ __type?: "base token" | undefined;
7
+ };
8
+ export declare const STATIC_PAGES_CACHE_METRICS_TOKEN: {
9
+ hit: Counter<any>;
10
+ } & {
11
+ __type?: "base token" | undefined;
12
+ };
13
+ export declare const STATIC_PAGES_FS_CACHE_TOKEN: (FileSystemCache & {
14
+ __type?: "base token" | undefined;
15
+ }) | null;
16
+ export declare const STATIC_PAGES_FS_CACHE_METRICS_TOKEN: {
17
+ hit: Counter<any>;
18
+ miss: Counter<any>;
19
+ size: Gauge<any>;
20
+ bytes: Gauge<any>;
21
+ } & {
22
+ __type?: "base token" | undefined;
23
+ };
24
+ export declare const STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE: (() => TramvaiRenderMode) & {
25
+ __type?: "base token" | undefined;
26
+ };
27
+ //# sourceMappingURL=private-tokens.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { createToken } from '@tramvai/core';
2
+
3
+ const STATIC_PAGES_BACKGROUND_FETCH_SERVICE = createToken();
4
+ const STATIC_PAGES_CACHE_METRICS_TOKEN = createToken();
5
+ const STATIC_PAGES_FS_CACHE_TOKEN = createToken();
6
+ const STATIC_PAGES_FS_CACHE_METRICS_TOKEN = createToken();
7
+ const STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE = createToken();
8
+
9
+ export { STATIC_PAGES_BACKGROUND_FETCH_SERVICE, STATIC_PAGES_CACHE_METRICS_TOKEN, STATIC_PAGES_FS_CACHE_METRICS_TOKEN, STATIC_PAGES_FS_CACHE_TOKEN, STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('@tramvai/core');
6
+
7
+ const STATIC_PAGES_BACKGROUND_FETCH_SERVICE = core.createToken();
8
+ const STATIC_PAGES_CACHE_METRICS_TOKEN = core.createToken();
9
+ const STATIC_PAGES_FS_CACHE_TOKEN = core.createToken();
10
+ const STATIC_PAGES_FS_CACHE_METRICS_TOKEN = core.createToken();
11
+ const STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE = core.createToken();
12
+
13
+ exports.STATIC_PAGES_BACKGROUND_FETCH_SERVICE = STATIC_PAGES_BACKGROUND_FETCH_SERVICE;
14
+ exports.STATIC_PAGES_CACHE_METRICS_TOKEN = STATIC_PAGES_CACHE_METRICS_TOKEN;
15
+ exports.STATIC_PAGES_FS_CACHE_METRICS_TOKEN = STATIC_PAGES_FS_CACHE_METRICS_TOKEN;
16
+ exports.STATIC_PAGES_FS_CACHE_TOKEN = STATIC_PAGES_FS_CACHE_TOKEN;
17
+ exports.STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE = STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE;
package/lib/server.es.js CHANGED
@@ -2,7 +2,7 @@ import { declareModule } from '@tramvai/core';
2
2
  import { ForceCSRModule } from './ForceCSRModule.es.js';
3
3
  import { sharedProviders } from './shared.es.js';
4
4
  import { staticPagesProviders } from './staticPages.es.js';
5
- export { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_WRAPPER_TYPE, STATIC_PAGES_BACKGROUND_FETCH_ENABLED, STATIC_PAGES_CACHE_5xx_RESPONSE, STATIC_PAGES_CACHE_TOKEN, STATIC_PAGES_COMMAND_LINE, STATIC_PAGES_MODIFY_CACHE, STATIC_PAGES_OPTIONS_TOKEN, STATIC_PAGES_SHOULD_USE_CACHE } from './tokens.es.js';
5
+ export { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT, PAGE_RENDER_DEFAULT_MODE, PAGE_RENDER_FALLBACK_COMPONENT_PREFIX, PAGE_RENDER_WRAPPER_TYPE, STATIC_PAGES_BACKGROUND_FETCH_ENABLED, STATIC_PAGES_CACHE_5xx_RESPONSE, STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN, STATIC_PAGES_CACHE_TOKEN, STATIC_PAGES_COMMAND_LINE, STATIC_PAGES_FS_CACHE_ENABLED, STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN, STATIC_PAGES_KEY_TOKEN, STATIC_PAGES_MODIFY_CACHE, STATIC_PAGES_OPTIONS_TOKEN, STATIC_PAGES_SERVICE, STATIC_PAGES_SHOULD_USE_CACHE } from './tokens.es.js';
6
6
 
7
7
  // @todo: перенести в @tramvai/module-render
8
8
  const PageRenderModeModule = declareModule({
package/lib/server.js CHANGED
@@ -21,9 +21,14 @@ exports.PAGE_RENDER_FALLBACK_COMPONENT_PREFIX = tokens.PAGE_RENDER_FALLBACK_COMP
21
21
  exports.PAGE_RENDER_WRAPPER_TYPE = tokens.PAGE_RENDER_WRAPPER_TYPE;
22
22
  exports.STATIC_PAGES_BACKGROUND_FETCH_ENABLED = tokens.STATIC_PAGES_BACKGROUND_FETCH_ENABLED;
23
23
  exports.STATIC_PAGES_CACHE_5xx_RESPONSE = tokens.STATIC_PAGES_CACHE_5xx_RESPONSE;
24
+ exports.STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN = tokens.STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN;
24
25
  exports.STATIC_PAGES_CACHE_TOKEN = tokens.STATIC_PAGES_CACHE_TOKEN;
25
26
  exports.STATIC_PAGES_COMMAND_LINE = tokens.STATIC_PAGES_COMMAND_LINE;
27
+ exports.STATIC_PAGES_FS_CACHE_ENABLED = tokens.STATIC_PAGES_FS_CACHE_ENABLED;
28
+ exports.STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN = tokens.STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN;
29
+ exports.STATIC_PAGES_KEY_TOKEN = tokens.STATIC_PAGES_KEY_TOKEN;
26
30
  exports.STATIC_PAGES_MODIFY_CACHE = tokens.STATIC_PAGES_MODIFY_CACHE;
27
31
  exports.STATIC_PAGES_OPTIONS_TOKEN = tokens.STATIC_PAGES_OPTIONS_TOKEN;
32
+ exports.STATIC_PAGES_SERVICE = tokens.STATIC_PAGES_SERVICE;
28
33
  exports.STATIC_PAGES_SHOULD_USE_CACHE = tokens.STATIC_PAGES_SHOULD_USE_CACHE;
29
34
  exports.PageRenderModeModule = PageRenderModeModule;
@@ -1,22 +1,24 @@
1
1
  import type { ExtractDependencyType } from '@tinkoff/dippy';
2
- import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
2
+ import type { ENV_MANAGER_TOKEN, LOGGER_TOKEN } from '@tramvai/tokens-common';
3
3
  import type { STATIC_PAGES_BACKGROUND_FETCH_ENABLED } from '../tokens';
4
4
  type Logger = ExtractDependencyType<typeof LOGGER_TOKEN>;
5
5
  type BackgroundCacheEnabled = ExtractDependencyType<typeof STATIC_PAGES_BACKGROUND_FETCH_ENABLED>;
6
6
  export declare class BackgroundFetchService {
7
7
  private requests;
8
+ private port;
9
+ private hostname;
8
10
  private log;
9
11
  private backgroundFetchEnabled;
10
- constructor({ logger, backgroundFetchEnabled, }: {
12
+ constructor({ logger, envManager, backgroundFetchEnabled, }: {
11
13
  logger: Logger;
14
+ envManager: ExtractDependencyType<typeof ENV_MANAGER_TOKEN>;
12
15
  backgroundFetchEnabled: BackgroundCacheEnabled;
13
16
  });
14
17
  enabled(): boolean;
15
- revalidate({ key, path, port, deviceType, }: {
16
- key: string;
17
- path: string;
18
- port: string;
19
- deviceType: string;
18
+ revalidate({ cacheKey, pathname, headers, }: {
19
+ cacheKey: string;
20
+ pathname: string;
21
+ headers: Record<string, string | string[] | undefined>;
20
22
  }): Promise<void | {
21
23
  body: string;
22
24
  headers: {
@@ -1,56 +1,56 @@
1
1
  import { format } from '@tinkoff/url';
2
2
 
3
- const userAgentByDeviceType = {
4
- /** Chrome on Mobile */
5
- mobile: 'Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.3071.125 Mobile Safari/537.36',
6
- /** Chrome on Desktop */
7
- desktop: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.3987.87 Safari/537.36',
8
- };
9
3
  class BackgroundFetchService {
10
4
  requests = new Set();
5
+ port;
6
+ hostname;
11
7
  log;
12
8
  backgroundFetchEnabled;
13
- constructor({ logger, backgroundFetchEnabled, }) {
9
+ constructor({ logger, envManager, backgroundFetchEnabled, }) {
14
10
  this.log = logger('static-pages');
11
+ this.port = envManager.get('PORT');
12
+ this.hostname = (envManager.get('HOST') ?? 'localhost').replace('0.0.0.0', 'localhost');
15
13
  this.backgroundFetchEnabled = backgroundFetchEnabled;
16
14
  }
17
15
  enabled() {
18
16
  return this.backgroundFetchEnabled();
19
17
  }
20
- async revalidate({ key, path, port, deviceType, }) {
21
- if (this.requests.has(key)) {
18
+ async revalidate({ cacheKey, pathname, headers, }) {
19
+ if (this.requests.has(cacheKey)) {
22
20
  return;
23
21
  }
24
22
  const revalidateUrl = format({
25
- hostname: 'localhost',
26
- port,
27
- path,
23
+ hostname: this.hostname,
24
+ port: this.port,
25
+ path: pathname,
28
26
  });
29
- this.requests.add(key);
27
+ this.requests.add(cacheKey);
30
28
  this.log.debug({
31
29
  event: 'background-fetch-init',
32
- key,
30
+ cacheKey,
33
31
  revalidateUrl,
34
32
  });
35
33
  return fetch(revalidateUrl, {
36
34
  headers: {
37
- 'User-Agent': userAgentByDeviceType[`${deviceType}`],
35
+ ...headers,
38
36
  'X-Tramvai-Static-Page-Revalidate': 'true',
39
37
  },
40
38
  signal: AbortSignal.timeout(10000),
39
+ // we need to save raw redirect response status code and headers
40
+ redirect: 'manual',
41
41
  })
42
42
  .then(async (response) => {
43
43
  const body = await response.text();
44
- const { headers, status } = response;
44
+ const { status } = response;
45
45
  this.log.debug({
46
46
  event: status >= 500 ? 'background-fetch-5xx' : 'background-fetch-success',
47
47
  status,
48
- key,
48
+ cacheKey,
49
49
  });
50
50
  return {
51
51
  body,
52
52
  // @ts-ignore outdated typings for headers in typescript
53
- headers: Object.fromEntries(headers.entries()),
53
+ headers: Object.fromEntries(response.headers.entries()),
54
54
  status,
55
55
  };
56
56
  })
@@ -58,11 +58,11 @@ class BackgroundFetchService {
58
58
  this.log.warn({
59
59
  event: 'background-fetch-error',
60
60
  error,
61
- key,
61
+ cacheKey,
62
62
  });
63
63
  })
64
64
  .finally(() => {
65
- this.requests.delete(key);
65
+ this.requests.delete(cacheKey);
66
66
  });
67
67
  }
68
68
  }
@@ -4,57 +4,57 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var url = require('@tinkoff/url');
6
6
 
7
- const userAgentByDeviceType = {
8
- /** Chrome on Mobile */
9
- mobile: 'Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.3071.125 Mobile Safari/537.36',
10
- /** Chrome on Desktop */
11
- desktop: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.3987.87 Safari/537.36',
12
- };
13
7
  class BackgroundFetchService {
14
8
  requests = new Set();
9
+ port;
10
+ hostname;
15
11
  log;
16
12
  backgroundFetchEnabled;
17
- constructor({ logger, backgroundFetchEnabled, }) {
13
+ constructor({ logger, envManager, backgroundFetchEnabled, }) {
18
14
  this.log = logger('static-pages');
15
+ this.port = envManager.get('PORT');
16
+ this.hostname = (envManager.get('HOST') ?? 'localhost').replace('0.0.0.0', 'localhost');
19
17
  this.backgroundFetchEnabled = backgroundFetchEnabled;
20
18
  }
21
19
  enabled() {
22
20
  return this.backgroundFetchEnabled();
23
21
  }
24
- async revalidate({ key, path, port, deviceType, }) {
25
- if (this.requests.has(key)) {
22
+ async revalidate({ cacheKey, pathname, headers, }) {
23
+ if (this.requests.has(cacheKey)) {
26
24
  return;
27
25
  }
28
26
  const revalidateUrl = url.format({
29
- hostname: 'localhost',
30
- port,
31
- path,
27
+ hostname: this.hostname,
28
+ port: this.port,
29
+ path: pathname,
32
30
  });
33
- this.requests.add(key);
31
+ this.requests.add(cacheKey);
34
32
  this.log.debug({
35
33
  event: 'background-fetch-init',
36
- key,
34
+ cacheKey,
37
35
  revalidateUrl,
38
36
  });
39
37
  return fetch(revalidateUrl, {
40
38
  headers: {
41
- 'User-Agent': userAgentByDeviceType[`${deviceType}`],
39
+ ...headers,
42
40
  'X-Tramvai-Static-Page-Revalidate': 'true',
43
41
  },
44
42
  signal: AbortSignal.timeout(10000),
43
+ // we need to save raw redirect response status code and headers
44
+ redirect: 'manual',
45
45
  })
46
46
  .then(async (response) => {
47
47
  const body = await response.text();
48
- const { headers, status } = response;
48
+ const { status } = response;
49
49
  this.log.debug({
50
50
  event: status >= 500 ? 'background-fetch-5xx' : 'background-fetch-success',
51
51
  status,
52
- key,
52
+ cacheKey,
53
53
  });
54
54
  return {
55
55
  body,
56
56
  // @ts-ignore outdated typings for headers in typescript
57
- headers: Object.fromEntries(headers.entries()),
57
+ headers: Object.fromEntries(response.headers.entries()),
58
58
  status,
59
59
  };
60
60
  })
@@ -62,11 +62,11 @@ class BackgroundFetchService {
62
62
  this.log.warn({
63
63
  event: 'background-fetch-error',
64
64
  error,
65
- key,
65
+ cacheKey,
66
66
  });
67
67
  })
68
68
  .finally(() => {
69
- this.requests.delete(key);
69
+ this.requests.delete(cacheKey);
70
70
  });
71
71
  }
72
72
  }
@@ -0,0 +1,72 @@
1
+ import type { ExtractDependencyType } from '@tinkoff/dippy';
2
+ import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
3
+ import type { Counter, Gauge } from 'prom-client';
4
+ import { Route } from '@tinkoff/router';
5
+ import { StaticPagesCacheEntry } from '../tokens';
6
+ type Logger = ExtractDependencyType<typeof LOGGER_TOKEN>;
7
+ interface FileMetadata {
8
+ filePath: string;
9
+ pathname: string;
10
+ key: string;
11
+ cacheKey: string;
12
+ size: number;
13
+ mtime: number;
14
+ }
15
+ export type CacheMetrics = {
16
+ hit: Counter;
17
+ miss: Counter;
18
+ size: Gauge;
19
+ bytes: Gauge;
20
+ };
21
+ export interface FileSystemCacheOptions {
22
+ /**
23
+ * Directory where static HTML files are stored
24
+ */
25
+ directory: string;
26
+ /**
27
+ * Maximum number of files to keep in cache
28
+ */
29
+ maxSize: number;
30
+ /**
31
+ * TTL for cache entries in milliseconds
32
+ */
33
+ ttl: number;
34
+ /**
35
+ * Whether to allow stale entries to be returned
36
+ */
37
+ allowStale: boolean;
38
+ }
39
+ export declare class FileSystemCache {
40
+ private directory;
41
+ private maxSize;
42
+ private ttl;
43
+ private allowStale;
44
+ private log;
45
+ private cache;
46
+ private list;
47
+ private nodes;
48
+ staticPages: Route[];
49
+ private metrics;
50
+ private limit;
51
+ constructor({ directory, maxSize, ttl, allowStale, logger, metrics, }: FileSystemCacheOptions & {
52
+ metrics: CacheMetrics;
53
+ logger: Logger;
54
+ });
55
+ init(): Promise<void>;
56
+ get(cacheKey: string): Promise<StaticPagesCacheEntry | undefined>;
57
+ set(cacheKey: string, cacheEntry: StaticPagesCacheEntry): Promise<void>;
58
+ has(cacheKey: string): boolean;
59
+ delete(cacheKey: string): Promise<boolean>;
60
+ clear(): Promise<void>;
61
+ get size(): number;
62
+ dump(): Array<[key: string, metadata: FileMetadata]>;
63
+ private scanDirectory;
64
+ private addFileToCache;
65
+ moveToHead(cacheKey: string): void;
66
+ private removeNode;
67
+ private evictTail;
68
+ private getTotalBytes;
69
+ private updateMetrics;
70
+ }
71
+ export {};
72
+ //# sourceMappingURL=fileSystemCache.d.ts.map