@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
@@ -6,7 +6,6 @@ var core = require('@tramvai/core');
6
6
  var tokensCommon = require('@tramvai/tokens-common');
7
7
  var tokensServerPrivate = require('@tramvai/tokens-server-private');
8
8
  var tokensRouter = require('@tramvai/tokens-router');
9
- var moduleClientHints = require('@tramvai/module-client-hints');
10
9
  var tokensServer = require('@tramvai/tokens-server');
11
10
  var tokensMetrics = require('@tramvai/tokens-metrics');
12
11
  var papi = require('@tramvai/papi');
@@ -16,21 +15,21 @@ var getPageRenderMode = require('./utils/getPageRenderMode.js');
16
15
  var cacheKey = require('./utils/cacheKey.js');
17
16
  var backgroundFetchService = require('./staticPages/backgroundFetchService.js');
18
17
  var staticPagesService = require('./staticPages/staticPagesService.js');
18
+ var fileSystemCache = require('./staticPages/fileSystemCache.js');
19
+ var privateTokens = require('./private-tokens.js');
19
20
 
20
- const STATIC_PAGES_BACKGROUND_FETCH_SERVICE = core.createToken();
21
- const STATIC_PAGES_GET_CACHE_KEY_TOKEN = core.createToken();
22
- const STATIC_PAGES_CACHE_HIT_METRIC_TOKEN = core.createToken();
23
- const STATIC_PAGES_SERVICE = core.createToken();
24
21
  const staticPagesProviders = [
25
22
  core.provide({
26
- provide: STATIC_PAGES_CACHE_HIT_METRIC_TOKEN,
23
+ provide: privateTokens.STATIC_PAGES_CACHE_METRICS_TOKEN,
27
24
  scope: core.Scope.SINGLETON,
28
25
  useFactory: ({ metrics }) => {
29
- return metrics.counter({
30
- name: 'static_pages_cache_hit',
31
- help: 'Total static pages returned from cache',
32
- labelNames: [],
33
- });
26
+ return {
27
+ hit: metrics.counter({
28
+ name: 'static_pages_cache_hit',
29
+ help: 'Total static pages returned from cache',
30
+ labelNames: [],
31
+ }),
32
+ };
34
33
  },
35
34
  deps: {
36
35
  metrics: tokensMetrics.METRICS_MODULE_TOKEN,
@@ -54,40 +53,143 @@ const staticPagesProviders = [
54
53
  provide: tokens.STATIC_PAGES_OPTIONS_TOKEN,
55
54
  useValue: {
56
55
  // @TODO: unique ttl per pages
57
- ttl: 60 * 1000,
58
- // @TODO: too much, better save to file-system
59
- maxSize: 1000,
56
+ ttl: 5 * 60 * 1000,
57
+ maxSize: 100,
58
+ allowStale: true,
59
+ allowedHeaders: [],
60
60
  },
61
61
  }),
62
62
  core.provide({
63
- provide: STATIC_PAGES_GET_CACHE_KEY_TOKEN,
64
- useFactory: ({ requestManager, userAgent }) => {
63
+ provide: tokens.STATIC_PAGES_KEY_TOKEN,
64
+ useFactory: () => {
65
65
  return () => {
66
- const deviceType = userAgent.mobileOS ? 'mobile' : 'desktop';
67
- return cacheKey.getCacheKey({
68
- method: requestManager.getMethod(),
69
- host: requestManager.getHost(),
70
- path: requestManager.getParsedUrl().pathname,
71
- deviceType,
72
- });
66
+ return '';
67
+ };
68
+ },
69
+ }),
70
+ core.provide({
71
+ provide: tokens.STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN,
72
+ useValue: ({ ttl }) => {
73
+ // prevent browser caching for pages in development mode
74
+ if (process.env.NODE_ENV === 'development') {
75
+ return 'private, no-cache, no-store, max-age=0, must-revalidate';
76
+ }
77
+ return `public, max-age=${ttl / 1000}`;
78
+ },
79
+ }),
80
+ core.provide({
81
+ provide: tokens.STATIC_PAGES_FS_CACHE_ENABLED,
82
+ useValue: () => false,
83
+ }),
84
+ core.provide({
85
+ provide: tokens.STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN,
86
+ useFactory: () => {
87
+ return {
88
+ directory: process.env.__TRAMVAI_OUTPUT_STATIC ?? 'dist/static',
89
+ maxSize: 1000,
90
+ ttl: 5 * 60 * 1000,
91
+ allowStale: true,
92
+ };
93
+ },
94
+ }),
95
+ core.provide({
96
+ provide: privateTokens.STATIC_PAGES_FS_CACHE_METRICS_TOKEN,
97
+ scope: core.Scope.SINGLETON,
98
+ useFactory: ({ metrics }) => {
99
+ return {
100
+ hit: metrics.counter({
101
+ name: 'static_pages_fs_cache_hit',
102
+ help: 'Total static pages returned from file system cache',
103
+ labelNames: [],
104
+ }),
105
+ miss: metrics.counter({
106
+ name: 'static_pages_fs_cache_miss',
107
+ help: 'Total static pages not found in file system cache',
108
+ labelNames: [],
109
+ }),
110
+ size: metrics.gauge({
111
+ name: 'static_pages_fs_cache_size',
112
+ help: 'Number of files in file system cache',
113
+ labelNames: [],
114
+ }),
115
+ bytes: metrics.gauge({
116
+ name: 'static_pages_fs_cache_bytes',
117
+ help: 'Total size of files in file system cache in bytes',
118
+ labelNames: [],
119
+ }),
73
120
  };
74
121
  },
75
122
  deps: {
76
- requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
77
- userAgent: moduleClientHints.USER_AGENT_TOKEN,
123
+ metrics: tokensMetrics.METRICS_MODULE_TOKEN,
124
+ },
125
+ }),
126
+ core.provide({
127
+ provide: privateTokens.STATIC_PAGES_FS_CACHE_TOKEN,
128
+ scope: core.Scope.SINGLETON,
129
+ useFactory: ({ fsCacheEnabled, fsCacheOptions, logger, metrics }) => {
130
+ if (!fsCacheEnabled()) {
131
+ return null;
132
+ }
133
+ return new fileSystemCache.FileSystemCache({
134
+ ...fsCacheOptions,
135
+ logger,
136
+ metrics,
137
+ });
138
+ },
139
+ deps: {
140
+ fsCacheEnabled: tokens.STATIC_PAGES_FS_CACHE_ENABLED,
141
+ fsCacheOptions: tokens.STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN,
142
+ logger: tokensCommon.LOGGER_TOKEN,
143
+ metrics: privateTokens.STATIC_PAGES_FS_CACHE_METRICS_TOKEN,
144
+ },
145
+ }),
146
+ core.provide({
147
+ provide: core.commandLineListTokens.init,
148
+ multi: true,
149
+ scope: core.Scope.SINGLETON,
150
+ useFactory: ({ fsCache, fsCacheEnabled }) => {
151
+ return async function initFileSystemCache() {
152
+ if (fsCacheEnabled() && fsCache) {
153
+ await fsCache.init();
154
+ }
155
+ };
156
+ },
157
+ deps: {
158
+ fsCache: privateTokens.STATIC_PAGES_FS_CACHE_TOKEN,
159
+ fsCacheEnabled: tokens.STATIC_PAGES_FS_CACHE_ENABLED,
78
160
  },
79
161
  }),
80
162
  core.provide({
81
163
  provide: tokens.STATIC_PAGES_SHOULD_USE_CACHE,
82
164
  useFactory: ({ requestManager }) => {
83
165
  return () => {
84
- return !requestManager.getHeader('x-tramvai-static-page-revalidate');
166
+ return (!requestManager.getHeader('x-tramvai-static-page-revalidate') &&
167
+ !requestManager.getHeader('x-tramvai-prerender'));
85
168
  };
86
169
  },
87
170
  deps: {
88
171
  requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
89
172
  },
90
173
  }),
174
+ core.provide({
175
+ provide: privateTokens.STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE,
176
+ useFactory: ({ requestManager, pageService, router, defaultRenderMode, fileSystemCache }) => {
177
+ return () => getPageRenderMode.getPageRenderMode({
178
+ pageService,
179
+ router,
180
+ requestManager,
181
+ defaultRenderMode,
182
+ fileSystemCache,
183
+ });
184
+ },
185
+ deps: {
186
+ requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
187
+ router: core.optional(tokensRouter.ROUTER_TOKEN),
188
+ pageService: core.optional(tokensRouter.PAGE_SERVICE_TOKEN),
189
+ defaultRenderMode: tokens.PAGE_RENDER_DEFAULT_MODE,
190
+ fileSystemCache: core.optional(privateTokens.STATIC_PAGES_FS_CACHE_TOKEN),
191
+ },
192
+ }),
91
193
  core.provide({
92
194
  provide: tokens.STATIC_PAGES_BACKGROUND_FETCH_ENABLED,
93
195
  useValue: () => {
@@ -101,32 +203,35 @@ const staticPagesProviders = [
101
203
  },
102
204
  }),
103
205
  core.provide({
104
- provide: STATIC_PAGES_BACKGROUND_FETCH_SERVICE,
206
+ provide: privateTokens.STATIC_PAGES_BACKGROUND_FETCH_SERVICE,
105
207
  scope: core.Scope.SINGLETON,
106
208
  useClass: backgroundFetchService.BackgroundFetchService,
107
209
  deps: {
108
210
  logger: tokensCommon.LOGGER_TOKEN,
211
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
109
212
  backgroundFetchEnabled: tokens.STATIC_PAGES_BACKGROUND_FETCH_ENABLED,
110
213
  },
111
214
  }),
112
215
  core.provide({
113
- provide: STATIC_PAGES_SERVICE,
216
+ provide: tokens.STATIC_PAGES_SERVICE,
114
217
  scope: core.Scope.REQUEST,
115
218
  useClass: staticPagesService.StaticPagesService,
116
219
  deps: {
117
- getCacheKey: STATIC_PAGES_GET_CACHE_KEY_TOKEN,
220
+ staticPagesKey: tokens.STATIC_PAGES_KEY_TOKEN,
118
221
  requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
119
222
  responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
120
223
  response: tokensServerPrivate.FASTIFY_RESPONSE,
121
224
  environmentManager: tokensCommon.ENV_MANAGER_TOKEN,
122
- userAgent: moduleClientHints.USER_AGENT_TOKEN,
123
225
  logger: tokensCommon.LOGGER_TOKEN,
124
226
  cache: tokens.STATIC_PAGES_CACHE_TOKEN,
227
+ fsCache: privateTokens.STATIC_PAGES_FS_CACHE_TOKEN,
228
+ fsCacheEnabled: tokens.STATIC_PAGES_FS_CACHE_ENABLED,
125
229
  modifyCache: { token: tokens.STATIC_PAGES_MODIFY_CACHE, optional: true },
126
230
  shouldUseCache: tokens.STATIC_PAGES_SHOULD_USE_CACHE,
127
- backgroundFetchService: STATIC_PAGES_BACKGROUND_FETCH_SERVICE,
231
+ backgroundFetchService: privateTokens.STATIC_PAGES_BACKGROUND_FETCH_SERVICE,
128
232
  options: tokens.STATIC_PAGES_OPTIONS_TOKEN,
129
233
  cache5xxResponse: tokens.STATIC_PAGES_CACHE_5xx_RESPONSE,
234
+ cacheControlFactory: tokens.STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN,
130
235
  },
131
236
  }),
132
237
  core.provide({
@@ -139,22 +244,61 @@ const staticPagesProviders = [
139
244
  provide: staticPagesCommandLine
140
245
  ? core.commandLineListTokens[staticPagesCommandLine]
141
246
  : core.commandLineListTokens.customerStart,
142
- useFactory: ({ staticPagesService, staticPagesCacheHitMetric, logger }) => {
143
- logger('static-pages');
144
- return function staticPagesFromCache() {
145
- if (staticPagesService.shouldUseCache()) {
146
- staticPagesService.respond(() => {
147
- // @TODO: маска урла на этом этапе?
148
- staticPagesCacheHitMetric.inc();
149
- throw new error.StopCommandLineRunnerError();
247
+ useFactory: ({ staticPagesService, staticPagesCacheMetrics, logger, requestManager, responseManager, staticPagesKey, linkPrefetchManager, resolvePageRenderMode, router, pageRegistry, }) => {
248
+ const log = logger('static-pages');
249
+ return async function staticPagesFromCache() {
250
+ const isPrerenderRequest = !!requestManager.getHeader('x-tramvai-prerender');
251
+ const { pathname } = requestManager.getParsedUrl();
252
+ const route = router?.getCurrentRoute() ?? router?.resolve(pathname);
253
+ // prefetch route only for `tramvai static` because it can be async and slow in runtime
254
+ if (isPrerenderRequest) {
255
+ log.debug(`Should prefetch route and component to determine if page is static: ${pathname}`);
256
+ await linkPrefetchManager.prefetch(pathname);
257
+ // for already resolved routes we can prefetch page component in runtime without significant performance impact
258
+ }
259
+ else if (route) {
260
+ log.debug(`Should prefetch page component to determine if page is static: ${pathname}`);
261
+ await pageRegistry?.resolve(route).catch((error) => {
262
+ if (!route.redirect) {
263
+ log.info(`${pathname} page component for prefetch failed: ${error.message}`);
264
+ }
150
265
  });
151
266
  }
267
+ const isStatic = resolvePageRenderMode() === 'static';
268
+ const shouldUseCache = staticPagesService.shouldUseCache();
269
+ if (isStatic) {
270
+ responseManager.setHeader('X-Tramvai-Static-Page-Key', staticPagesKey());
271
+ // we need to tell for `tramvai static` prerendering command that this page has `static` render mode,
272
+ // and also provide route info to generate list of static routes in `dist/client/meta.json`.
273
+ // this list will be used in `STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE` to determine render mode of the page in runtime before route resolving.
274
+ if (isPrerenderRequest && route) {
275
+ responseManager.setHeader('X-Tramvai-Static-Page-Route', JSON.stringify(route));
276
+ }
277
+ if (shouldUseCache) {
278
+ log.debug(`Should use static pages cache: ${pathname}`);
279
+ await staticPagesService.respond(() => {
280
+ log.debug(`Successful static page response from cache: ${pathname}`);
281
+ staticPagesCacheMetrics.hit.inc();
282
+ throw new error.StopCommandLineRunnerError();
283
+ });
284
+ }
285
+ else {
286
+ log.debug(`Static pages cache is not used for this request: ${pathname}`);
287
+ }
288
+ }
152
289
  };
153
290
  },
154
291
  deps: {
155
- staticPagesService: STATIC_PAGES_SERVICE,
156
- staticPagesCacheHitMetric: STATIC_PAGES_CACHE_HIT_METRIC_TOKEN,
292
+ staticPagesService: tokens.STATIC_PAGES_SERVICE,
293
+ staticPagesCacheMetrics: privateTokens.STATIC_PAGES_CACHE_METRICS_TOKEN,
157
294
  logger: tokensCommon.LOGGER_TOKEN,
295
+ requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
296
+ responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
297
+ staticPagesKey: tokens.STATIC_PAGES_KEY_TOKEN,
298
+ linkPrefetchManager: tokensRouter.LINK_PREFETCH_MANAGER_TOKEN,
299
+ resolvePageRenderMode: privateTokens.STATIC_PAGES_RESOLVE_PAGE_RENDER_MODE,
300
+ router: core.optional(tokensRouter.ROUTER_TOKEN),
301
+ pageRegistry: core.optional(tokensRouter.PAGE_REGISTRY_TOKEN),
158
302
  },
159
303
  });
160
304
  };
@@ -164,38 +308,57 @@ const staticPagesProviders = [
164
308
  staticPagesCommandLine: { token: tokens.STATIC_PAGES_COMMAND_LINE, optional: true },
165
309
  },
166
310
  }),
167
- core.provide({
168
- provide: core.commandLineListTokens.clear,
169
- useFactory: ({ staticPagesService, pageService, defaultRenderMode }) => {
170
- return function cacheStaticPages() {
171
- const isStaticPage = getPageRenderMode.getPageRenderMode({ pageService, defaultRenderMode }) === 'static';
172
- if (!isStaticPage) {
173
- return;
174
- }
175
- staticPagesService.revalidate();
176
- };
177
- },
178
- deps: {
179
- staticPagesService: STATIC_PAGES_SERVICE,
180
- pageService: tokensRouter.PAGE_SERVICE_TOKEN,
181
- defaultRenderMode: tokens.PAGE_RENDER_DEFAULT_MODE,
182
- },
183
- }),
184
311
  core.provide({
185
312
  provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
186
- useFactory: ({ staticPagesCache }) => {
313
+ useFactory: ({ staticPagesCache, fsCache, fsCacheEnabled, logger }) => {
187
314
  return papi.createPapiMethod({
188
315
  path: '/revalidate/',
189
316
  method: 'post',
190
- async handler({ body = {} }) {
191
- const { path } = body;
192
- const pathKey = `/${path}/`;
193
- if (!path) {
317
+ async handler({ body = {}, headers }) {
318
+ const log = logger('static-pages:revalidate');
319
+ const { pathname, key = '' } = body;
320
+ if (!pathname) {
321
+ log.info({
322
+ event: 'revalidate-all',
323
+ request: body,
324
+ headers,
325
+ });
194
326
  staticPagesCache.clear();
327
+ if (fsCacheEnabled() && fsCache) {
328
+ await fsCache.clear();
329
+ }
195
330
  }
196
- else if (staticPagesCache.has(pathKey)) {
197
- staticPagesCache.set(pathKey, new Map());
198
- // @TODO: revalidate request with background fetch?
331
+ else {
332
+ const cacheKey$1 = cacheKey.getCacheKey({ pathname, key });
333
+ log.info({
334
+ event: 'revalidate-path',
335
+ request: body,
336
+ cacheKey: cacheKey$1,
337
+ });
338
+ if (key) {
339
+ if (staticPagesCache.has(cacheKey$1)) {
340
+ staticPagesCache.delete(cacheKey$1);
341
+ }
342
+ if (fsCacheEnabled() && fsCache && fsCache.has(cacheKey$1)) {
343
+ await fsCache.delete(cacheKey$1);
344
+ }
345
+ }
346
+ else {
347
+ const memoryCaches = staticPagesCache.dump();
348
+ for (const entry of memoryCaches) {
349
+ if (entry[0].startsWith(`${pathname}^`)) {
350
+ staticPagesCache.delete(entry[0]);
351
+ }
352
+ }
353
+ if (fsCacheEnabled() && fsCache) {
354
+ const fsCaches = fsCache.dump();
355
+ for (const entry of fsCaches) {
356
+ if (entry[0].startsWith(`${pathname}^`)) {
357
+ fsCache.delete(entry[0]);
358
+ }
359
+ }
360
+ }
361
+ }
199
362
  }
200
363
  return 'Success';
201
364
  },
@@ -203,12 +366,11 @@ const staticPagesProviders = [
203
366
  },
204
367
  deps: {
205
368
  staticPagesCache: tokens.STATIC_PAGES_CACHE_TOKEN,
369
+ fsCache: privateTokens.STATIC_PAGES_FS_CACHE_TOKEN,
370
+ fsCacheEnabled: tokens.STATIC_PAGES_FS_CACHE_ENABLED,
371
+ logger: tokensCommon.LOGGER_TOKEN,
206
372
  },
207
373
  }),
208
374
  ];
209
375
 
210
- exports.STATIC_PAGES_BACKGROUND_FETCH_SERVICE = STATIC_PAGES_BACKGROUND_FETCH_SERVICE;
211
- exports.STATIC_PAGES_CACHE_HIT_METRIC_TOKEN = STATIC_PAGES_CACHE_HIT_METRIC_TOKEN;
212
- exports.STATIC_PAGES_GET_CACHE_KEY_TOKEN = STATIC_PAGES_GET_CACHE_KEY_TOKEN;
213
- exports.STATIC_PAGES_SERVICE = STATIC_PAGES_SERVICE;
214
376
  exports.staticPagesProviders = staticPagesProviders;
@@ -14,5 +14,19 @@ const STATIC_PAGES_OPTIONS_TOKEN = createToken('static pages options');
14
14
  const STATIC_PAGES_COMMAND_LINE = createToken('static pages command line');
15
15
  const STATIC_PAGES_MODIFY_CACHE = createToken('static pages modify cache', { multi: true });
16
16
  const STATIC_PAGES_CACHE_5xx_RESPONSE = createToken('static pages cache 5xx response');
17
+ /**
18
+ * Token that computes the current cache key for a page variation
19
+ * For example: 'mobile', 'desktop', or empty string for default variation
20
+ * Used in combination with pathname to create the full cache key
21
+ */
22
+ const STATIC_PAGES_KEY_TOKEN = createToken('static pages key', {
23
+ scope: Scope.REQUEST,
24
+ });
25
+ const STATIC_PAGES_FS_CACHE_ENABLED = createToken('static pages file system cache enabled', { scope: Scope.SINGLETON });
26
+ const STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN = createToken('static pages file system cache options', { scope: Scope.SINGLETON });
27
+ const STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN = createToken('static pages cache-control header', {
28
+ scope: Scope.REQUEST,
29
+ });
30
+ const STATIC_PAGES_SERVICE = createToken('static pages service');
17
31
 
18
- 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 };
32
+ 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 };
package/lib/tokens.d.ts CHANGED
@@ -1,87 +1,145 @@
1
1
  import type { TramvaiRenderMode } from '@tramvai/tokens-render';
2
2
  import type { Cache, ResponseManager } from '@tramvai/tokens-common';
3
+ import { StaticPagesService } from './staticPages/staticPagesService';
3
4
  export declare const PAGE_RENDER_FALLBACK_COMPONENT_PREFIX: string & {
4
- __type?: "base token";
5
+ __type?: "base token" | undefined;
5
6
  };
6
7
  /**
7
8
  * @deprecated Use token `TRAMVAI_RENDER_MODE` from `@tramvai/tokens-render`
8
9
  */
9
10
  export declare const PAGE_RENDER_DEFAULT_MODE: ("ssr" & {
10
- __type?: "base token";
11
+ __type?: "base token" | undefined;
11
12
  }) | ("client" & {
12
- __type?: "base token";
13
+ __type?: "base token" | undefined;
13
14
  }) | ("static" & {
14
- __type?: "base token";
15
+ __type?: "base token" | undefined;
15
16
  }) | ((() => TramvaiRenderMode) & {
16
- __type?: "base token";
17
+ __type?: "base token" | undefined;
17
18
  });
18
19
  export declare const PAGE_RENDER_WRAPPER_TYPE: ("layout" & {
19
- __type?: "base token";
20
+ __type?: "base token" | undefined;
20
21
  }) | ("content" & {
21
- __type?: "base token";
22
+ __type?: "base token" | undefined;
22
23
  }) | ("page" & {
23
- __type?: "base token";
24
+ __type?: "base token" | undefined;
24
25
  });
25
26
  export declare const PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT: (import("react").ComponentClass<any, any> & {
26
- __type?: "base token";
27
+ __type?: "base token" | undefined;
27
28
  }) | (import("react").FunctionComponent<any> & {
28
- __type?: "base token";
29
+ __type?: "base token" | undefined;
29
30
  });
30
31
  export interface StaticPagesCacheEntry {
31
32
  updatedAt: number;
32
33
  headers: ReturnType<ResponseManager['getHeaders']>;
33
34
  status: ReturnType<ResponseManager['getStatus']>;
34
35
  body: string;
36
+ source: 'memory' | 'fs';
35
37
  }
36
38
  export interface StaticPagesOptions {
37
39
  /**
38
40
  * Static page cache live time in milliseconds
39
- * @default 60000
41
+ * @default 300000
40
42
  */
41
43
  ttl: number;
42
44
  /**
43
- * Cached static page maximum size
44
- * @default 1000
45
+ * Cached static page maximum size in memory
46
+ * @default 100
45
47
  */
46
48
  maxSize: number;
49
+ /**
50
+ * Whether to allow stale entries to be returned
51
+ * @default true
52
+ */
53
+ allowStale: boolean;
54
+ /**
55
+ * Whitelist of headers, that are allowed to be passed from client request to backround cache revalidation request,
56
+ * and allowed to be cached and returned with the cached response
57
+ * @default []
58
+ */
59
+ allowedHeaders: string[];
47
60
  }
48
- export declare const STATIC_PAGES_CACHE_TOKEN: Cache<Map<string, StaticPagesCacheEntry>> & {
49
- __type?: "base token";
61
+ export declare const STATIC_PAGES_CACHE_TOKEN: Cache<StaticPagesCacheEntry> & {
62
+ __type?: "base token" | undefined;
50
63
  };
51
64
  export declare const STATIC_PAGES_SHOULD_USE_CACHE: (() => boolean) & {
52
- __type?: "multi token";
65
+ __type?: "multi token" | undefined;
53
66
  };
54
67
  export declare const STATIC_PAGES_BACKGROUND_FETCH_ENABLED: (() => boolean) & {
55
- __type?: "base token";
68
+ __type?: "base token" | undefined;
56
69
  };
57
70
  export declare const STATIC_PAGES_OPTIONS_TOKEN: StaticPagesOptions & {
58
- __type?: "base token";
71
+ __type?: "base token" | undefined;
59
72
  };
60
- export declare const STATIC_PAGES_COMMAND_LINE: ("init" & {
61
- __type?: "base token";
73
+ export declare const STATIC_PAGES_COMMAND_LINE: ("clear" & {
74
+ __type?: "base token" | undefined;
75
+ }) | ("init" & {
76
+ __type?: "base token" | undefined;
62
77
  }) | ("listen" & {
63
- __type?: "base token";
78
+ __type?: "base token" | undefined;
64
79
  }) | ("customerStart" & {
65
- __type?: "base token";
80
+ __type?: "base token" | undefined;
66
81
  }) | ("resolveUserDeps" & {
67
- __type?: "base token";
82
+ __type?: "base token" | undefined;
68
83
  }) | ("resolvePageDeps" & {
69
- __type?: "base token";
84
+ __type?: "base token" | undefined;
70
85
  }) | ("generatePage" & {
71
- __type?: "base token";
72
- }) | ("clear" & {
73
- __type?: "base token";
86
+ __type?: "base token" | undefined;
74
87
  }) | ("spaTransition" & {
75
- __type?: "base token";
88
+ __type?: "base token" | undefined;
76
89
  }) | ("afterSpaTransition" & {
77
- __type?: "base token";
90
+ __type?: "base token" | undefined;
78
91
  }) | ("close" & {
79
- __type?: "base token";
92
+ __type?: "base token" | undefined;
80
93
  });
81
94
  export declare const STATIC_PAGES_MODIFY_CACHE: ((entry: StaticPagesCacheEntry) => StaticPagesCacheEntry) & {
82
- __type?: "multi token";
95
+ __type?: "multi token" | undefined;
83
96
  };
84
97
  export declare const STATIC_PAGES_CACHE_5xx_RESPONSE: (() => boolean) & {
85
- __type?: "base token";
98
+ __type?: "base token" | undefined;
99
+ };
100
+ /**
101
+ * Token that computes the current cache key for a page variation
102
+ * For example: 'mobile', 'desktop', or empty string for default variation
103
+ * Used in combination with pathname to create the full cache key
104
+ */
105
+ export declare const STATIC_PAGES_KEY_TOKEN: (() => string) & {
106
+ __type?: "base token" | undefined;
107
+ };
108
+ export interface FileSystemCacheOptions {
109
+ /**
110
+ * Directory where static HTML files are stored
111
+ * @default 'dist/static'
112
+ */
113
+ directory: string;
114
+ /**
115
+ * Maximum number of files to keep in cache
116
+ * @default 1000
117
+ */
118
+ maxSize: number;
119
+ /**
120
+ * TTL for cache entries in milliseconds
121
+ * @default 300000
122
+ */
123
+ ttl: number;
124
+ /**
125
+ * Whether to allow stale entries to be returned
126
+ * @default true
127
+ */
128
+ allowStale: boolean;
129
+ }
130
+ export declare const STATIC_PAGES_FS_CACHE_ENABLED: (() => boolean) & {
131
+ __type?: "base token" | undefined;
132
+ };
133
+ export declare const STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN: FileSystemCacheOptions & {
134
+ __type?: "base token" | undefined;
135
+ };
136
+ export declare const STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN: ((entry: {
137
+ ttl: number;
138
+ updatedAt: number;
139
+ }) => string) & {
140
+ __type?: "base token" | undefined;
141
+ };
142
+ export declare const STATIC_PAGES_SERVICE: StaticPagesService & {
143
+ __type?: "base token" | undefined;
86
144
  };
87
145
  //# sourceMappingURL=tokens.d.ts.map
package/lib/tokens.es.js CHANGED
@@ -14,5 +14,19 @@ const STATIC_PAGES_OPTIONS_TOKEN = createToken('static pages options');
14
14
  const STATIC_PAGES_COMMAND_LINE = createToken('static pages command line');
15
15
  const STATIC_PAGES_MODIFY_CACHE = createToken('static pages modify cache', { multi: true });
16
16
  const STATIC_PAGES_CACHE_5xx_RESPONSE = createToken('static pages cache 5xx response');
17
+ /**
18
+ * Token that computes the current cache key for a page variation
19
+ * For example: 'mobile', 'desktop', or empty string for default variation
20
+ * Used in combination with pathname to create the full cache key
21
+ */
22
+ const STATIC_PAGES_KEY_TOKEN = createToken('static pages key', {
23
+ scope: Scope.REQUEST,
24
+ });
25
+ const STATIC_PAGES_FS_CACHE_ENABLED = createToken('static pages file system cache enabled', { scope: Scope.SINGLETON });
26
+ const STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN = createToken('static pages file system cache options', { scope: Scope.SINGLETON });
27
+ const STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN = createToken('static pages cache-control header', {
28
+ scope: Scope.REQUEST,
29
+ });
30
+ const STATIC_PAGES_SERVICE = createToken('static pages service');
17
31
 
18
- 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 };
32
+ 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 };
package/lib/tokens.js CHANGED
@@ -18,6 +18,20 @@ const STATIC_PAGES_OPTIONS_TOKEN = dippy.createToken('static pages options');
18
18
  const STATIC_PAGES_COMMAND_LINE = dippy.createToken('static pages command line');
19
19
  const STATIC_PAGES_MODIFY_CACHE = dippy.createToken('static pages modify cache', { multi: true });
20
20
  const STATIC_PAGES_CACHE_5xx_RESPONSE = dippy.createToken('static pages cache 5xx response');
21
+ /**
22
+ * Token that computes the current cache key for a page variation
23
+ * For example: 'mobile', 'desktop', or empty string for default variation
24
+ * Used in combination with pathname to create the full cache key
25
+ */
26
+ const STATIC_PAGES_KEY_TOKEN = dippy.createToken('static pages key', {
27
+ scope: dippy.Scope.REQUEST,
28
+ });
29
+ const STATIC_PAGES_FS_CACHE_ENABLED = dippy.createToken('static pages file system cache enabled', { scope: dippy.Scope.SINGLETON });
30
+ const STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN = dippy.createToken('static pages file system cache options', { scope: dippy.Scope.SINGLETON });
31
+ const STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN = dippy.createToken('static pages cache-control header', {
32
+ scope: dippy.Scope.REQUEST,
33
+ });
34
+ const STATIC_PAGES_SERVICE = dippy.createToken('static pages service');
21
35
 
22
36
  exports.PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT = PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT;
23
37
  exports.PAGE_RENDER_DEFAULT_MODE = PAGE_RENDER_DEFAULT_MODE;
@@ -25,8 +39,13 @@ exports.PAGE_RENDER_FALLBACK_COMPONENT_PREFIX = PAGE_RENDER_FALLBACK_COMPONENT_P
25
39
  exports.PAGE_RENDER_WRAPPER_TYPE = PAGE_RENDER_WRAPPER_TYPE;
26
40
  exports.STATIC_PAGES_BACKGROUND_FETCH_ENABLED = STATIC_PAGES_BACKGROUND_FETCH_ENABLED;
27
41
  exports.STATIC_PAGES_CACHE_5xx_RESPONSE = STATIC_PAGES_CACHE_5xx_RESPONSE;
42
+ exports.STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN = STATIC_PAGES_CACHE_CONTROL_HEADER_TOKEN;
28
43
  exports.STATIC_PAGES_CACHE_TOKEN = STATIC_PAGES_CACHE_TOKEN;
29
44
  exports.STATIC_PAGES_COMMAND_LINE = STATIC_PAGES_COMMAND_LINE;
45
+ exports.STATIC_PAGES_FS_CACHE_ENABLED = STATIC_PAGES_FS_CACHE_ENABLED;
46
+ exports.STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN = STATIC_PAGES_FS_CACHE_OPTIONS_TOKEN;
47
+ exports.STATIC_PAGES_KEY_TOKEN = STATIC_PAGES_KEY_TOKEN;
30
48
  exports.STATIC_PAGES_MODIFY_CACHE = STATIC_PAGES_MODIFY_CACHE;
31
49
  exports.STATIC_PAGES_OPTIONS_TOKEN = STATIC_PAGES_OPTIONS_TOKEN;
50
+ exports.STATIC_PAGES_SERVICE = STATIC_PAGES_SERVICE;
32
51
  exports.STATIC_PAGES_SHOULD_USE_CACHE = STATIC_PAGES_SHOULD_USE_CACHE;