@griddo/cx 1.75.222 → 1.75.224

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/gatsby-node.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { StoreMode } from "./src/types/global";
2
1
  import type { GatsbyNode } from "gatsby";
3
2
 
4
3
  import path from "path";
@@ -9,20 +8,24 @@ import { RobotsService } from "./src/services/robots";
9
8
  import { StoreService } from "./src/services/store";
10
9
  import { initCache } from "./src/utils/cache";
11
10
  import { prepareStaticFolder, updateDist } from "./src/utils/folders";
12
- import { logInfo, logPageSize, msToSec, splash } from "./src/utils/shared";
11
+ import {
12
+ logInfo,
13
+ logPageSize,
14
+ msToSec,
15
+ // sanitizeApiCache,
16
+ splash,
17
+ } from "./src/utils/shared";
13
18
  import { generateBuildReport, generateSitemaps } from "./src/utils/sites";
14
19
 
15
20
  dotenv.config();
16
21
 
17
- // Envs
18
- const GRIDDO_STORE_MODE = (process.env.GRIDDO_STORE_MODE ||
19
- "file") as StoreMode;
20
-
21
22
  // Consts
22
23
  const PUBLIC_FOLDER = path.resolve(__dirname, "./public");
23
24
  const STORE_DIR_PATH = path.resolve(__dirname, "./store/");
25
+ // const API_CACHE_FOLDER = path.resolve(__dirname, "./apiCache");
24
26
  const REPORT_FILE = path.resolve(PUBLIC_FOLDER, "__build-report__.json");
25
- const envVars: Record<string, any> = {};
27
+ const griddoEnvs: Record<string, any> = {};
28
+ const otherEnvs: Record<string, any> = {};
26
29
 
27
30
  // -----------------------------------------------------------------------------
28
31
  // onPreInit
@@ -34,21 +37,26 @@ export const onPreInit = async () => {
34
37
 
35
38
  Object.keys(process.env)
36
39
  .filter((key) => key.startsWith("GRIDDO"))
37
- .forEach((key) => (envVars[key] = process.env[key]));
40
+ .forEach((key) => (griddoEnvs[key] = process.env[key]));
41
+
42
+ Object.keys(process.env)
43
+ .filter((key) => !key.startsWith("GRIDDO"))
44
+ .forEach((key) => (otherEnvs[key] = process.env[key]));
38
45
 
39
46
  console.log("%%%");
40
47
  console.log("- GRIDDO ENVS VARS -");
41
- console.log(envVars);
42
- console.log("- ALL ENVS VARS -");
43
- console.log(process.env);
48
+ console.log(griddoEnvs);
49
+ console.log("- OTHER ENVS -");
50
+ console.log(otherEnvs);
44
51
  console.log("%%%");
45
52
 
46
- StoreService.init(STORE_DIR_PATH, {
47
- sanitize: true,
48
- mode: GRIDDO_STORE_MODE,
49
- });
53
+ StoreService.init(STORE_DIR_PATH, { sanitize: true });
50
54
  await StoreService.createBuildSource();
51
55
 
56
+ // Remove old cahe page files
57
+ // TODO: Use disabled
58
+ // sanitizeApiCache(API_CACHE_FOLDER);
59
+
52
60
  console.log("\n✨ onPreInit\n");
53
61
  };
54
62
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/cx",
3
3
  "description": "Griddo SSG based on Gatsby",
4
- "version": "1.75.222",
4
+ "version": "1.75.224",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Diego M. Béjar <diego.bejar@secuoyas.com>",
@@ -64,7 +64,7 @@
64
64
  "react-helmet": "^6.0.0"
65
65
  },
66
66
  "devDependencies": {
67
- "@griddo/eslint-config-back": "^1.75.222",
67
+ "@griddo/eslint-config-back": "^1.75.224",
68
68
  "@types/babel__core": "^7.20.0",
69
69
  "@types/babel__preset-env": "^7.9.2",
70
70
  "@types/csvtojson": "^2.0.0",
@@ -112,5 +112,5 @@
112
112
  "publishConfig": {
113
113
  "access": "public"
114
114
  },
115
- "gitHead": "f417b394d6830b80fc15f2fd691b620a34d74b2e"
115
+ "gitHead": "1c4e2c06dd6fbee54a37eba2c8f2ebd27b38781f"
116
116
  }
@@ -78,14 +78,14 @@ class DistributorService {
78
78
  * @param props
79
79
  * @param props.page The Page object
80
80
  * @param props.component.data The ReferenceField, always in the data prop.
81
- * @param props.cached Boolean that indicates cache use.
81
+ * @param props.cacheKey A cache key to manage cached files or using fetch
82
82
  * @returns The ContentType data.
83
83
  */
84
84
  static async fetchContentTypeData(props: FetchDataProps) {
85
85
  const {
86
86
  page,
87
87
  component: { data },
88
- cached,
88
+ cacheKey,
89
89
  } = props;
90
90
 
91
91
  // Distrubutor with `hasDistributorDat: true` but without `data` prop
@@ -98,7 +98,11 @@ class DistributorService {
98
98
  }
99
99
 
100
100
  const body = this.getBody(data, page);
101
- const response = await SitesService.getDistributorData(page, body, cached);
101
+ const response = await SitesService.getDistributorData(
102
+ page,
103
+ body,
104
+ cacheKey
105
+ );
102
106
 
103
107
  return response;
104
108
  }
@@ -108,14 +112,15 @@ class DistributorService {
108
112
  *
109
113
  * @param props
110
114
  * @param props.page The APIPage object
111
- * @param props.cached Boolean that indicates cache use.
115
+ * @param props.cacheKey A cache key to manage cached files or using fetch
112
116
  */
113
117
  static async getDistributorData({
114
118
  page,
115
- cached = false,
119
+ cacheKey = "",
116
120
  }: {
117
121
  page: APIPageObject;
118
- cached: boolean;
122
+ /** Reference id to manage cache between renders. */
123
+ cacheKey: string;
119
124
  }) {
120
125
  try {
121
126
  const { template } = page;
@@ -155,7 +160,7 @@ class DistributorService {
155
160
  if (component.hasDistributorData) {
156
161
  component.queriedItems = await this.fetchContentTypeData({
157
162
  page,
158
- cached,
163
+ cacheKey,
159
164
  component,
160
165
  });
161
166
  }
@@ -52,13 +52,13 @@ class SitesService {
52
52
  /**
53
53
  * Fetch a page object from API.
54
54
  */
55
- static async getPage(id: number, cached: unknown) {
55
+ static async getPage(id: number, cacheKey: string) {
56
56
  const {
57
57
  GET_PAGE: [prefix, suffix],
58
58
  } = ENDPOINTS;
59
59
  const response = await get<PageResponse>({
60
60
  endpoint: `${prefix}${id}${suffix}`,
61
- cached,
61
+ cacheKey,
62
62
  });
63
63
 
64
64
  return response;
@@ -67,13 +67,13 @@ class SitesService {
67
67
  /**
68
68
  * Get site info
69
69
  */
70
- static async getInfo(id: number, cached: boolean) {
70
+ static async getInfo(id: number, cacheKey = "") {
71
71
  const {
72
72
  INFO: [prefix, suffix],
73
73
  } = ENDPOINTS;
74
74
  const response = await get<Site>({
75
75
  endpoint: `${prefix}${id}${suffix}`,
76
- cached,
76
+ cacheKey,
77
77
  });
78
78
 
79
79
  return response;
@@ -82,13 +82,13 @@ class SitesService {
82
82
  /**
83
83
  * TODO: JSDoc
84
84
  */
85
- static async getLanguages(id: number, cached = false) {
85
+ static async getLanguages(id: number, cacheKey = "") {
86
86
  const {
87
87
  LANGUAGES: [prefix, suffix],
88
88
  } = ENDPOINTS;
89
89
  const response = await get<LanguagesResponse>({
90
90
  endpoint: `${prefix}${id}${suffix}`,
91
- cached,
91
+ cacheKey,
92
92
  });
93
93
 
94
94
  return response;
@@ -129,7 +129,7 @@ class SitesService {
129
129
  static async getDistributorData(
130
130
  page: Core.Page,
131
131
  body: DistributorBody,
132
- cached: boolean
132
+ cacheKey: string
133
133
  ) {
134
134
  const {
135
135
  GET_DISTRIBUTOR_DATA: [prefix, suffix],
@@ -139,7 +139,7 @@ class SitesService {
139
139
  endpoint: `${prefix}${id}${suffix}`,
140
140
  body,
141
141
  headers: { lang },
142
- cached,
142
+ cacheKey,
143
143
  });
144
144
 
145
145
  return response;
@@ -162,13 +162,13 @@ class SitesService {
162
162
  /**
163
163
  * TODO: JSDoc
164
164
  */
165
- static async getSocials(id: number, cached: boolean) {
165
+ static async getSocials(id: number, cacheKey = "") {
166
166
  const {
167
167
  SOCIALS: [prefix, suffix],
168
168
  } = ENDPOINTS;
169
169
  const response = await get<SocialsResponse>({
170
170
  endpoint: `${prefix}${id}${suffix}`,
171
- cached,
171
+ cacheKey,
172
172
  });
173
173
 
174
174
  return response;
@@ -177,13 +177,13 @@ class SitesService {
177
177
  /**
178
178
  * TODO: JSDoc
179
179
  */
180
- static async getPages(id: number, cached = false) {
180
+ static async getPages(id: number, cacheKey = "") {
181
181
  const {
182
182
  GET_PAGES: [prefix, suffix],
183
183
  } = ENDPOINTS;
184
184
  const response = await get<AllPagesResponse>({
185
185
  endpoint: `${prefix}${id}${suffix}`,
186
- cached,
186
+ cacheKey,
187
187
  });
188
188
 
189
189
  return response;
@@ -21,17 +21,17 @@
21
21
  // │ Build metadata │ //
22
22
  // └─────────────────────────┘ //
23
23
 
24
- import type { BuildProcessData, StoreMode } from "../types/global";
24
+ import type { BuildProcessData } from "../types/global";
25
25
  import type { GatsbyPageObject, PageAdditionalInfo } from "../types/pages";
26
26
  import type { Site } from "../types/sites";
27
27
 
28
28
  import fs from "fs";
29
29
  import fsp from "fs/promises";
30
30
  import path from "path";
31
- import v8 from "v8";
32
31
 
33
32
  import chalk from "chalk";
34
33
  import dotenv from "dotenv";
34
+ import fsx from "fs-extra";
35
35
  import pLimit from "p-limit";
36
36
 
37
37
  import { DistributorService } from "./distributors";
@@ -73,15 +73,11 @@ const UNWANTED_PAGE_PROPS = ["editorID", "parentEditorID"];
73
73
  * Store service to fetch, process and save object pages and sites data to be
74
74
  * consumed by other services (Griddo itself, Gatsby, etc.)
75
75
  *
76
- * Modes:
77
- * - { File mode } save the objects as json files in the file system (json DB)
78
- * - { Memory mode } save the objects in an array.
79
- *
80
76
  * @example
81
77
  * import { StoreService } from "./store"
82
78
  *
83
79
  * // Init the store service.
84
- * StoreService.init("foo/pages", { mode: "file", ... })
80
+ * StoreService.init("foo/pages", { sanitize: true })
85
81
  * // Save the data into files.
86
82
  * await StoreService.createBuildSource()
87
83
  * // Consume the pages as an interator.
@@ -89,7 +85,6 @@ const UNWANTED_PAGE_PROPS = ["editorID", "parentEditorID"];
89
85
  */
90
86
  class StoreService {
91
87
  static basePath: string;
92
- static mode: "file" | "memory";
93
88
  static sanitize? = false;
94
89
  static pages: Array<GatsbyPageObject> = [];
95
90
  static sitesToPublish: Array<Site>;
@@ -102,39 +97,28 @@ class StoreService {
102
97
  * @param basePath The path to store the page files.
103
98
  * @param options An object configuration
104
99
  * @param options.mode Store mode
105
- * @todo Avoid initialize the Store with a `basePath` in memory mode.
106
100
  */
107
- public static init(
108
- basePath: string,
109
- options: { mode: StoreMode; sanitize?: boolean }
110
- ) {
101
+ public static init(basePath: string, options: { sanitize?: boolean }) {
111
102
  this.sanitize = options?.sanitize;
112
- const { mode } = options;
113
103
  const griddoCxThreads = parseInt(GRIDDO_API_CONCURRENCY_COUNT || "10");
114
- const modeString = mode === "file" ? "File mode" : "Memory mode";
115
104
 
116
105
  console.log(`🧶 Processing API page calls with ${griddoCxThreads} threads`);
117
- console.log(`📦 Griddo Store initialized - ${chalk.italic(modeString)}`);
106
+ console.log(`📦 Griddo Store initialized`);
118
107
 
119
108
  if (this.sanitize) {
120
109
  console.log(`🏥 Sanitize pages enabled`);
121
110
  }
122
111
 
123
- if (mode === "file") {
124
- this.basePath = basePath;
125
- this.mode = mode;
126
-
127
- if (fs.existsSync(basePath)) {
128
- fs.rmSync(basePath, { recursive: true });
129
- }
112
+ this.basePath = basePath;
130
113
 
131
- if (!fs.existsSync(basePath)) {
132
- fs.mkdirSync(basePath);
133
- }
114
+ // Remove old store
115
+ if (fs.existsSync(basePath)) {
116
+ fs.rmSync(basePath, { recursive: true });
117
+ }
134
118
 
135
- if (!fs.existsSync(path.resolve(basePath))) {
136
- fs.mkdirSync(path.resolve(basePath));
137
- }
119
+ // Create new store
120
+ if (!fs.existsSync(basePath)) {
121
+ fs.mkdirSync(basePath);
138
122
  }
139
123
  }
140
124
 
@@ -186,7 +170,7 @@ class StoreService {
186
170
  headers,
187
171
  footers,
188
172
  socials,
189
- } = await getSiteData(siteId, false);
173
+ } = await getSiteData(siteId);
190
174
 
191
175
  const {
192
176
  cloudinaryName,
@@ -280,7 +264,7 @@ class StoreService {
280
264
  // for the data.
281
265
  const template = await DistributorService.getDistributorData({
282
266
  page,
283
- cached: !!RENDER_ID,
267
+ cacheKey: RENDER_ID,
284
268
  });
285
269
 
286
270
  // MultiPage Query
@@ -358,9 +342,9 @@ class StoreService {
358
342
 
359
343
  // Save build data to store
360
344
  await this.savePages(gatsbyPageObjects); // gatsbyPageObjects is always an array regardless of whether it's just one page
361
- this.saveSitesToPublish(sitesToPublish);
362
- this.saveBuildProcessData(BUILD_PROCESS_DATA);
363
- this.saveCreatedPages(CREATED_PAGES);
345
+ this.setSitesToPublish(sitesToPublish);
346
+ this.setBuildProcessData(BUILD_PROCESS_DATA);
347
+ this.setCreatedPages(CREATED_PAGES);
364
348
  };
365
349
 
366
350
  const griddoCxThreads = parseInt(GRIDDO_API_CONCURRENCY_COUNT || "10");
@@ -383,57 +367,49 @@ class StoreService {
383
367
  }
384
368
 
385
369
  /**
386
- * Get all pages data from the Store.
387
- * If the Store is in file mode `getPages` will return a Generator of pages.
388
- * If the Store is in memory mode `getPages` will return an array of pages.
389
- */
390
- public static getPages() {
391
- return this.mode === "file"
392
- ? this.getPagesFromFiles()
393
- : this.getPagesFromMemory();
394
- }
395
-
396
- /**
397
- * Save the pages into the Store.
370
+ * Save the pages into the file system.
398
371
  *
399
372
  * @param pages An array of pages to save in the store.
400
373
  */
401
374
  public static async savePages(pages: Array<GatsbyPageObject>) {
402
- // WARNS: This mutate the page objects and could hurt the build render
403
- // performance.
404
375
  if (this.sanitize) {
405
376
  pages.forEach((page) => removeProperties(page, UNWANTED_PAGE_PROPS));
406
377
  }
407
378
 
408
- return this.mode === "file"
409
- ? await this.savePagesToFiles(pages)
410
- : this.savePagesToMemory(pages);
379
+ const promises = pages.map(async (pageObject) => {
380
+ const filename = `${createSha256(pageObject.path)}.json`;
381
+ const fileContent = JSON.stringify(pageObject);
382
+ const filePath = path.resolve(this.basePath, filename);
383
+ await fsp.writeFile(filePath, fileContent);
384
+ });
385
+
386
+ await Promise.all(promises);
411
387
  }
412
388
 
413
389
  /**
414
- * Save site to publish data in the Store.
390
+ * Set site to publish data in the Store.
415
391
  *
416
392
  * @param sites An array of sites to be published.
417
393
  */
418
- public static saveSitesToPublish(sites: Array<Site>) {
394
+ public static setSitesToPublish(sites: Array<Site>) {
419
395
  this.sitesToPublish = sites;
420
396
  }
421
397
 
422
398
  /**
423
- * Save the build process data in the Store.
399
+ * Set the build process data in the Store.
424
400
  *
425
401
  * @param buildProcessData An object that represents a build process data.
426
402
  */
427
- public static saveBuildProcessData(buildProcessData: BuildProcessData) {
403
+ public static setBuildProcessData(buildProcessData: BuildProcessData) {
428
404
  this.buildProcessData = buildProcessData;
429
405
  }
430
406
 
431
407
  /**
432
- * Save the created pages in the Store.
408
+ * Set the created pages in the Store.
433
409
  *
434
410
  * @param pages An array of pages ids.
435
411
  */
436
- public static saveCreatedPages(pages: Array<number>) {
412
+ public static setCreatedPages(pages: Array<number>) {
437
413
  this.createdPages = pages;
438
414
  }
439
415
 
@@ -451,7 +427,7 @@ class StoreService {
451
427
  /**
452
428
  * Return an iterator with pages read from the file system.
453
429
  */
454
- private static *getPagesFromFiles() {
430
+ public static *getPages() {
455
431
  const pagesDirPath = path.resolve(this.basePath);
456
432
  const jsonFilePaths = walk(pagesDirPath).filter(
457
433
  (file) => path.extname(file) === ".json"
@@ -459,52 +435,17 @@ class StoreService {
459
435
 
460
436
  for (const filePath of jsonFilePaths) {
461
437
  try {
462
- const jsonContent = fs.readFileSync(filePath, "utf-8");
463
- const page = JSON.parse(jsonContent) as GatsbyPageObject;
464
- page.size = fs.statSync(filePath).size / 1024;
438
+ const fileStats = fs.statSync(filePath);
439
+ const page = fsx.readJSONSync(filePath, {
440
+ encoding: "utf-8",
441
+ }) as GatsbyPageObject;
442
+ page.size = fileStats.size / 1024;
465
443
  yield page;
466
- } catch {
467
- console.error(`Error: The file ${filePath} doesn't exist`);
444
+ } catch (error) {
445
+ console.error(`Error: The file ${filePath} doesn't exist`, error);
468
446
  }
469
447
  }
470
448
  }
471
-
472
- /**
473
- * Get the pages from the Store from the memory.
474
- */
475
- private static getPagesFromMemory() {
476
- return this.pages;
477
- }
478
-
479
- /**
480
- * Save pages to the file system.
481
- *
482
- * @param pages An array of final pages to save into the file system.
483
- */
484
- private static async savePagesToFiles(pages: Array<GatsbyPageObject>) {
485
- const promises = pages.map(async (pageObject) => {
486
- const filename = `${createSha256(pageObject.path)}.json`;
487
- const fileContent = JSON.stringify(pageObject);
488
- const filePath = path.resolve(this.basePath, filename);
489
- await fsp.writeFile(filePath, fileContent);
490
- });
491
-
492
- await Promise.all(promises);
493
- }
494
-
495
- /**
496
- * Save pages to the memory.
497
- *
498
- * @param pages An array of final pages to save into the memory
499
- */
500
- private static savePagesToMemory(pages: Array<GatsbyPageObject>) {
501
- const pagesWithSize = pages.map((page) => {
502
- const size = v8.serialize(page).byteLength / 1024;
503
-
504
- return { ...page, size };
505
- });
506
- this.pages.push(...pagesWithSize);
507
- }
508
449
  }
509
450
 
510
451
  export { StoreService };
package/src/types/api.ts CHANGED
@@ -112,8 +112,8 @@ export interface APIRequest {
112
112
  endpoint: string;
113
113
  /** The parameters to be sent in the request body. */
114
114
  body?: unknown;
115
- /** Indicates whether to use the cache to get the response from the API. */
116
- cached?: unknown;
115
+ /** Reference id to manage cache between renders. */
116
+ cacheKey?: string;
117
117
  /** Number of connection attempts (in case it fails on the first attempt). */
118
118
  attempt?: number;
119
119
  /** Headers for the post api fetch */
@@ -1,9 +1,6 @@
1
1
  import type { EndSiteRenderBody } from "./api";
2
2
  import type { Core, Fields } from "@griddo/core";
3
3
 
4
- // TODO: JSDoc
5
- export type StoreMode = "memory" | "file";
6
-
7
4
  // TODO: JSDoc
8
5
  export interface Settings {
9
6
  apiVersion?: string;
@@ -50,7 +47,8 @@ export interface FetchDataProps {
50
47
  component: {
51
48
  data: Fields.Reference<unknown>;
52
49
  };
53
- cached: boolean;
50
+ /** Reference id to manage cache between renders. */
51
+ cacheKey: string;
54
52
  }
55
53
 
56
54
  // TODO: JSDoc
@@ -5,7 +5,7 @@ import type { Core, Fields } from "@griddo/core";
5
5
 
6
6
  // TODO: In @griddo/core the type Core.Page has header/footer as React-Types,
7
7
  // but API return `number | null`.
8
- export type APIPageObject = Core.Page & {
8
+ export type APIPageObject = Core.Page & { id: number } & {
9
9
  header: number | null;
10
10
  footer: number | null;
11
11
  };