5htp-core 0.6.0-97 → 0.6.0-99

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.
@@ -12,4 +12,4 @@
12
12
  .bl-2, .bh-2 { border-left: solid 1px var(--cLine); }
13
13
 
14
14
  .b-0 { border: none; }
15
- .b-1 { border-top: solid 1px var(--cLine); }
15
+ .b-1 { border: solid 1px var(--cLine); }
@@ -98,7 +98,10 @@ export type TRouteOptions = {
98
98
  redirectLogged?: string, // Redirect to this route if auth: false and user is logged
99
99
 
100
100
  // Rendering
101
- static?: boolean,
101
+ static?: {
102
+ refresh?: string,
103
+ urls: string[]
104
+ },
102
105
  canonicalParams?: string[], // For SEO + unique ID for static cache
103
106
  layout?: false | string, // The nale of the layout
104
107
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.6.0-97",
4
+ "version": "0.6.0-99",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -76,6 +76,7 @@
76
76
  "regenerator-runtime": "^0.13.9",
77
77
  "request": "^2.88.2",
78
78
  "slugify": "^1.6.6",
79
+ "source-map-support": "^0.5.21",
79
80
  "sql-formatter": "^4.0.2",
80
81
  "stopword": "^3.1.1",
81
82
  "tslog": "^4.9.1",
@@ -4,6 +4,7 @@
4
4
 
5
5
  // Set timezone
6
6
  process.env.TZ = 'UTC';
7
+ import 'source-map-support/register';
7
8
 
8
9
  // Npm
9
10
  import path from 'path';
@@ -11,6 +11,8 @@
11
11
 
12
12
  // Node
13
13
  // Npm
14
+ import got from 'got';
15
+ import hInterval from 'human-interval';
14
16
  import type express from 'express';
15
17
  import type { Request, Response, NextFunction } from 'express';
16
18
  import { v4 as uuid } from 'uuid';
@@ -137,7 +139,13 @@ export default class ServerRouter
137
139
  public ssrRoutes: TSsrUnresolvedRoute[] = [];
138
140
 
139
141
  // Cache (ex: for static pages)
140
- public cache: {[pageId: string]: string} = {}
142
+ public cache: {
143
+ [pageId: string]: {
144
+ rendered: any,
145
+ expire: number | undefined,
146
+ options: TRouteOptions["static"]
147
+ }
148
+ } = {}
141
149
 
142
150
  /*----------------------------------
143
151
  - SERVICE
@@ -157,6 +165,11 @@ export default class ServerRouter
157
165
 
158
166
  public async ready() {
159
167
 
168
+ // Every hours
169
+ setInterval(() => {
170
+ this.refreshStaticPages();
171
+ }, 1000 * 60 * 60);
172
+
160
173
  // Detect router services
161
174
  for (const serviceName in this.config.plugins) {
162
175
  this.app.register( this.config.plugins[serviceName] )
@@ -172,7 +185,6 @@ export default class ServerRouter
172
185
  // Start HTTP server
173
186
  await this.http.start();
174
187
 
175
-
176
188
  // override
177
189
  const originalLog = console.log;
178
190
  console.log = (...args: any[]) => {
@@ -209,6 +221,65 @@ export default class ServerRouter
209
221
  - ACTIONS
210
222
  ----------------------------------*/
211
223
 
224
+ private async renderStatic(
225
+ path: string,
226
+ options: TRouteOptions["static"],
227
+ rendered?: any
228
+ ) {
229
+
230
+ // Wildcard: tell that the newly rendered pages should be cached
231
+ if (path === '*')
232
+ return;
233
+
234
+ if (!rendered) {
235
+
236
+ const fullUrl = this.url(path, {}, true);
237
+ console.log('[router] renderStatic', fullUrl);
238
+
239
+ const response = await got( fullUrl, {
240
+ method: 'GET',
241
+ headers: {
242
+ 'Accept': 'text/html'
243
+ },
244
+ throwHttpErrors: false,
245
+ });
246
+
247
+ if (response.statusCode !== 200) {
248
+ console.error('renderStatic', response.statusCode, response.body);
249
+ return;
250
+ }
251
+
252
+ rendered = response.body;
253
+ }
254
+
255
+ this.cache[path] = {
256
+ rendered: rendered,
257
+ options: options,
258
+ expire: typeof options === 'object'
259
+ ? Date.now() + (hInterval(options.refresh) || 3600)
260
+ : undefined
261
+ };
262
+
263
+ }
264
+
265
+ private refreshStaticPages() {
266
+
267
+ console.log('[router] refreshStaticPages');
268
+
269
+ for (const pageId in this.cache) {
270
+ const page = this.cache[pageId];
271
+ if (page.expire && page.expire < Date.now()) {
272
+
273
+ this.renderStatic(page.path, page.options);
274
+
275
+ }
276
+ }
277
+ }
278
+
279
+
280
+
281
+
282
+
212
283
  private registerRoutes(defModules: GlobImportedWithMetas<TRouteModule>) {
213
284
  for (const routeModule of defModules) {
214
285
 
@@ -257,6 +328,14 @@ export default class ServerRouter
257
328
 
258
329
  this.routes.push(route);
259
330
 
331
+ // Add to static pages
332
+ // Should be a GET oage that don't take any parameter
333
+ if (options.static) {
334
+ for (const url of options.static.urls) {
335
+ this.renderStatic(url, options.static);
336
+ }
337
+ }
338
+
260
339
  return this;
261
340
 
262
341
  }
@@ -419,7 +498,13 @@ export default class ServerRouter
419
498
  "Cache-Control",
420
499
  "no-store, no-cache, must-revalidate, proxy-revalidate"
421
500
  );
422
- res.setHeader("Pragma", "no-cache");
501
+
502
+ // Static pages
503
+ if (this.cache[req.path]) {
504
+ console.log('[router] Get static page from cache', req.path);
505
+ res.send( this.cache[req.path].rendered );
506
+ return;
507
+ }
423
508
 
424
509
  // Create request
425
510
  let requestId = uuid();
@@ -578,6 +663,12 @@ export default class ServerRouter
578
663
  if (!response.wasProvided)
579
664
  return;
580
665
 
666
+ // Set in cache
667
+ if (route.options.static && route.options.static.urls.includes('*')) {
668
+ console.log('[router] Set in cache', response.request.path);
669
+ this.renderStatic(response.request.path, route.options.static, response.data);
670
+ }
671
+
581
672
  const timeEndResolving = Date.now();
582
673
  this.printTakenTime(timeStart, timeEndResolving);
583
674
  }
@@ -111,17 +111,6 @@ export default class ServerResponse<
111
111
  // Create response context for controllers
112
112
  const context = await this.createContext(route);
113
113
 
114
- // Static rendering
115
- const chunkId = route.options["id"];
116
- if (route.options.static &&
117
- chunkId !== undefined
118
- &&
119
- this.router.cache[ chunkId ] !== undefined
120
- ) {
121
- await this.html( this.router.cache[ chunkId ] );
122
- return;
123
- }
124
-
125
114
  // Run controller
126
115
  const content = await this.route.controller( context );
127
116
  if (content === undefined)
@@ -139,10 +128,6 @@ export default class ServerResponse<
139
128
  // Return JSON
140
129
  else
141
130
  await this.json(content);
142
-
143
- // Cache
144
- if (route.options.static)
145
- this.router.cache[ chunkId ] = this.data;
146
131
  }
147
132
 
148
133
  private updateCanonicalUrl( route: TAnyRoute ) {
package/types/icons.d.ts CHANGED
@@ -1 +1 @@
1
- export type TIcones = "solid/spinner-third"|"long-arrow-right"|"times-circle"|"brands/whatsapp"|"times"|"search"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"exclamation"|"exclamation-circle"|"solid/download"|"angle-down"|"info-circle"|"check-circle"|"home"|"user-circle"|"newspaper"|"plus-circle"|"brands/linkedin"|"brands/twitter"|"brands/facebook"|"books"|"box-full"|"planet-ringed"|"chart-bar"|"power-off"|"comment-alt"|"heart"|"chart-line"|"lock"|"eye"|"credit-card"|"at"|"key"|"bars"|"font"|"tag"|"compress"|"bolt"|"puzzle-piece"|"hourglass-half"|"hourglass-end"|"rocket"|"seedling"|"palette"|"car"|"plane"|"university"|"briefcase"|"hard-hat"|"graduation-cap"|"cogs"|"film"|"leaf"|"tshirt"|"utensils"|"globe"|"map-marked-alt"|"dumbbell"|"stethoscope"|"concierge-bell"|"book"|"shield-alt"|"gavel"|"industry"|"square-root-alt"|"pills"|"medal"|"capsules"|"balance-scale"|"praying-hands"|"shopping-cart"|"flask"|"futbol"|"microchip"|"satellite-dish"|"shipping-fast"|"passport"|"tools"|"database"|"brain"|"download"|"code"|"money-bill"|"angle-left"|"angle-right"|"paper-plane"|"brands/google"|"check"|"trash"|"meh-rolling-eyes"|"arrow-left"|"arrow-right"|"link"|"file"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"unlink"|"pen"|"plus"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"
1
+ export type TIcones = "solid/spinner-third"|"long-arrow-right"|"times-circle"|"brands/whatsapp"|"times"|"user"|"rocket"|"globe"|"bullhorn"|"briefcase"|"chart-line"|"handshake"|"ellipsis-h"|"brands/google"|"brands/reddit-alien"|"brands/linkedin-in"|"brands/github"|"robot"|"comments"|"user-friends"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"search"|"angle-down"|"info-circle"|"check-circle"|"exclamation-circle"|"chart-bar"|"power-off"|"home"|"user-circle"|"newspaper"|"plus-circle"|"brands/linkedin"|"brands/twitter"|"brands/facebook"|"comment-alt"|"heart"|"lock"|"eye"|"credit-card"|"at"|"key"|"bars"|"font"|"tag"|"compress"|"bolt"|"puzzle-piece"|"planet-ringed"|"database"|"solid/fire"|"usd-circle"|"lightbulb"|"solid/dollar-sign"|"download"|"code"|"solid/clock"|"exclamation"|"solid/download"|"seedling"|"palette"|"car"|"plane"|"university"|"hard-hat"|"graduation-cap"|"cogs"|"film"|"leaf"|"tshirt"|"utensils"|"map-marked-alt"|"dumbbell"|"stethoscope"|"concierge-bell"|"book"|"shield-alt"|"gavel"|"industry"|"square-root-alt"|"pills"|"medal"|"capsules"|"balance-scale"|"praying-hands"|"shopping-cart"|"flask"|"futbol"|"microchip"|"satellite-dish"|"shipping-fast"|"passport"|"tools"|"angle-left"|"angle-right"|"check"|"paper-plane"|"trash"|"meh-rolling-eyes"|"arrow-left"|"arrow-right"|"unlink"|"pen"|"link"|"file"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"plus"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"