@isardsat/editorial-server 6.6.2 → 6.6.4

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.
@@ -1,7 +1,44 @@
1
1
  import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
2
2
  import { EditorialDataItemSchema, EditorialDataSchema, EditorialSchemaSchema, } from "@isardsat/editorial-common";
3
+ function createCache() {
4
+ let schemaCache = null;
5
+ const contentCache = new Map();
6
+ const ttl = 5 * 60 * 1000; // 5 minutes TTL
7
+ function isExpired(entry) {
8
+ return Date.now() - entry.timestamp > ttl;
9
+ }
10
+ return {
11
+ async getSchema(storage) {
12
+ if (schemaCache && !isExpired(schemaCache)) {
13
+ return schemaCache.data;
14
+ }
15
+ const schema = await storage.getSchema();
16
+ schemaCache = { data: schema, timestamp: Date.now() };
17
+ return schema;
18
+ },
19
+ async getContent(storage, options = {}) {
20
+ const mode = options.production ? "production" : "preview";
21
+ const langSuffix = options.lang ? `-${options.lang}` : "";
22
+ const cacheKey = `${mode}${langSuffix}`;
23
+ const cachedEntry = contentCache.get(cacheKey);
24
+ if (cachedEntry && !isExpired(cachedEntry)) {
25
+ return cachedEntry.data;
26
+ }
27
+ const content = await storage.getContent(options);
28
+ contentCache.set(cacheKey, { data: content, timestamp: Date.now() });
29
+ return content;
30
+ },
31
+ invalidateSchema() {
32
+ schemaCache = null;
33
+ },
34
+ invalidateContent() {
35
+ contentCache.clear();
36
+ },
37
+ };
38
+ }
3
39
  export function createDataRoutes(config, storage) {
4
40
  const app = new OpenAPIHono();
41
+ const cache = createCache();
5
42
  const publicFilesUrl = config.filesUrl;
6
43
  app.openapi(createRoute({
7
44
  method: "get",
@@ -17,7 +54,7 @@ export function createDataRoutes(config, storage) {
17
54
  },
18
55
  },
19
56
  }), async (c) => {
20
- const schema = await storage.getSchema();
57
+ const schema = await cache.getSchema(storage);
21
58
  return c.json(schema);
22
59
  });
23
60
  app.openapi(createRoute({
@@ -47,7 +84,7 @@ export function createDataRoutes(config, storage) {
47
84
  },
48
85
  }), async (c) => {
49
86
  const { preview } = c.req.valid("query");
50
- const content = await storage.getContent({ production: !preview });
87
+ const content = await cache.getContent(storage, { production: !preview });
51
88
  return c.json(content);
52
89
  });
53
90
  app.openapi(createRoute({
@@ -88,8 +125,11 @@ export function createDataRoutes(config, storage) {
88
125
  const { itemType } = c.req.valid("param");
89
126
  const { lang, preview } = c.req.valid("query");
90
127
  const origin = preview ? new URL(c.req.url).origin : publicFilesUrl;
91
- const content = await storage.getContent({ production: !preview });
92
- const schema = await storage.getSchema();
128
+ const content = await cache.getContent(storage, {
129
+ production: !preview,
130
+ lang,
131
+ });
132
+ const schema = await cache.getSchema(storage);
93
133
  const collection = content[itemType];
94
134
  if (!collection) {
95
135
  return c.notFound();
@@ -142,7 +182,7 @@ export function createDataRoutes(config, storage) {
142
182
  }), async (c) => {
143
183
  const { itemType } = c.req.valid("param");
144
184
  const { preview } = c.req.valid("query");
145
- const content = await storage.getContent({ production: !preview });
185
+ const content = await cache.getContent(storage, { production: !preview });
146
186
  return c.json(Object.keys(content[itemType]));
147
187
  });
148
188
  app.openapi(createRoute({
@@ -187,8 +227,11 @@ export function createDataRoutes(config, storage) {
187
227
  const { itemType, id } = c.req.valid("param");
188
228
  const { lang, preview } = c.req.valid("query");
189
229
  const origin = preview ? new URL(c.req.url).origin : publicFilesUrl;
190
- const content = await storage.getContent({ production: !preview });
191
- const schema = await storage.getSchema();
230
+ const content = await cache.getContent(storage, {
231
+ production: !preview,
232
+ lang,
233
+ });
234
+ const schema = await cache.getSchema(storage);
192
235
  const collection = content[itemType];
193
236
  if (!collection) {
194
237
  return c.notFound();
@@ -252,6 +295,7 @@ export function createDataRoutes(config, storage) {
252
295
  }), async (c) => {
253
296
  const itemAtts = await c.req.json();
254
297
  const newItem = await storage.createItem(itemAtts);
298
+ cache.invalidateContent();
255
299
  return c.json(newItem);
256
300
  });
257
301
  app.openapi(createRoute({
@@ -290,6 +334,7 @@ export function createDataRoutes(config, storage) {
290
334
  }), async (c) => {
291
335
  const itemAtts = await c.req.json();
292
336
  const newItem = await storage.updateItem(itemAtts);
337
+ cache.invalidateContent();
293
338
  return c.json(newItem);
294
339
  });
295
340
  app.openapi(createRoute({
@@ -320,6 +365,7 @@ export function createDataRoutes(config, storage) {
320
365
  }), async (c) => {
321
366
  const { itemType, id } = c.req.valid("param");
322
367
  await storage.deleteItem({ type: itemType, id });
368
+ cache.invalidateContent();
323
369
  return c.json(true, 200);
324
370
  });
325
371
  return app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isardsat/editorial-server",
3
- "version": "6.6.2",
3
+ "version": "6.6.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,8 +14,8 @@
14
14
  "hono": "^4.6.20",
15
15
  "yaml": "^2.7.0",
16
16
  "zod": "^3.24.1",
17
- "@isardsat/editorial-admin": "^6.6.2",
18
- "@isardsat/editorial-common": "^6.6.2"
17
+ "@isardsat/editorial-admin": "^6.6.4",
18
+ "@isardsat/editorial-common": "^6.6.4"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@tsconfig/node22": "^22.0.0",