@paroicms/server-image-cache-engine 0.25.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 (66) hide show
  1. package/README.md +3 -0
  2. package/ddl/image-cache.ddl.sql +32 -0
  3. package/dist/api.d.ts +6 -0
  4. package/dist/api.js +23 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/constants.d.ts +3 -0
  7. package/dist/constants.js +7 -0
  8. package/dist/constants.js.map +1 -0
  9. package/dist/database/PaCacheDependency.entity.d.ts +4 -0
  10. package/dist/database/PaCacheDependency.entity.js +30 -0
  11. package/dist/database/PaCacheDependency.entity.js.map +1 -0
  12. package/dist/database/PaImageCache.entity.d.ts +13 -0
  13. package/dist/database/PaImageCache.entity.js +71 -0
  14. package/dist/database/PaImageCache.entity.js.map +1 -0
  15. package/dist/database/PaImageCacheDependency.entity.d.ts +4 -0
  16. package/dist/database/PaImageCacheDependency.entity.js +30 -0
  17. package/dist/database/PaImageCacheDependency.entity.js.map +1 -0
  18. package/dist/database/PaImageCacheKey.entity.d.ts +5 -0
  19. package/dist/database/PaImageCacheKey.entity.js +35 -0
  20. package/dist/database/PaImageCacheKey.entity.js.map +1 -0
  21. package/dist/database/image-file-variant.entity.d.ts +13 -0
  22. package/dist/database/image-file-variant.entity.js +71 -0
  23. package/dist/database/image-file-variant.entity.js.map +1 -0
  24. package/dist/database/queries.d.ts +48 -0
  25. package/dist/database/queries.js +176 -0
  26. package/dist/database/queries.js.map +1 -0
  27. package/dist/db-init/db-init.d.ts +10 -0
  28. package/dist/db-init/db-init.js +35 -0
  29. package/dist/db-init/db-init.js.map +1 -0
  30. package/dist/db-init/ddl-migration.d.ts +12 -0
  31. package/dist/db-init/ddl-migration.js +51 -0
  32. package/dist/db-init/ddl-migration.js.map +1 -0
  33. package/dist/default-bo-favicon.d.ts +3 -0
  34. package/dist/default-bo-favicon.js +107 -0
  35. package/dist/default-bo-favicon.js.map +1 -0
  36. package/dist/engine-types.d.ts +45 -0
  37. package/dist/engine-types.js +3 -0
  38. package/dist/engine-types.js.map +1 -0
  39. package/dist/image-cache-engine.d.ts +48 -0
  40. package/dist/image-cache-engine.js +139 -0
  41. package/dist/image-cache-engine.js.map +1 -0
  42. package/dist/image-processor-setup.d.ts +8 -0
  43. package/dist/image-processor-setup.js +33 -0
  44. package/dist/image-processor-setup.js.map +1 -0
  45. package/dist/internal/compute-variant-size.d.ts +11 -0
  46. package/dist/internal/compute-variant-size.js +91 -0
  47. package/dist/internal/compute-variant-size.js.map +1 -0
  48. package/dist/internal/engine-context.d.ts +17 -0
  49. package/dist/internal/engine-context.js +26 -0
  50. package/dist/internal/engine-context.js.map +1 -0
  51. package/dist/internal/internal.types.d.ts +18 -0
  52. package/dist/internal/internal.types.js +3 -0
  53. package/dist/internal/internal.types.js.map +1 -0
  54. package/dist/internal/resizer.d.ts +20 -0
  55. package/dist/internal/resizer.js +67 -0
  56. package/dist/internal/resizer.js.map +1 -0
  57. package/dist/internal/task-processor.d.ts +2 -0
  58. package/dist/internal/task-processor.js +62 -0
  59. package/dist/internal/task-processor.js.map +1 -0
  60. package/dist/original-images-processing.d.ts +21 -0
  61. package/dist/original-images-processing.js +93 -0
  62. package/dist/original-images-processing.js.map +1 -0
  63. package/dist/public-helpers.d.ts +2 -0
  64. package/dist/public-helpers.js +8 -0
  65. package/dist/public-helpers.js.map +1 -0
  66. package/package.json +37 -0
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOrOpenMainCn = void 0;
4
+ const server_lib_1 = require("@paroicms/server-lib");
5
+ const path_1 = require("path");
6
+ const constants_1 = require("../constants");
7
+ const PaImageCache_entity_1 = require("../database/PaImageCache.entity");
8
+ const PaImageCacheKey_entity_1 = require("../database/PaImageCacheKey.entity");
9
+ const ddl_migration_1 = require("./ddl-migration");
10
+ async function createOrOpenMainCn({ sqliteFile, siteName, appLog, }) {
11
+ const { logNextQuery, typeOrmLogger } = (0, server_lib_1.createSqlLogger)({ appLog, siteName, dbSchemaName: ddl_migration_1.dbSchemaName });
12
+ const { mainCn } = await (0, server_lib_1.createOrOpenSqliteConnection)({
13
+ siteName: siteName,
14
+ canCreate: true,
15
+ dbSchemaName: ddl_migration_1.dbSchemaName,
16
+ sqliteFile,
17
+ ddlFile: (0, path_1.join)(constants_1.packageDir, "ddl", "image-cache.ddl.sql"),
18
+ migrateDb,
19
+ entities: [PaImageCache_entity_1.PaImageCacheEntity, PaImageCacheKey_entity_1.PaImageCacheKeyEntity],
20
+ logger: typeOrmLogger,
21
+ });
22
+ async function migrateDb(cn) {
23
+ const dbVersion = await (0, ddl_migration_1.getDbVersion)(cn, { siteName });
24
+ if (dbVersion !== ddl_migration_1.currentVariantsDbSchemaVersion) {
25
+ await (0, ddl_migration_1.migrateMediasDb)(cn, {
26
+ fromVersion: dbVersion,
27
+ siteName,
28
+ appLog,
29
+ });
30
+ }
31
+ }
32
+ return { mainCn, logNextQuery };
33
+ }
34
+ exports.createOrOpenMainCn = createOrOpenMainCn;
35
+ //# sourceMappingURL=db-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-init.js","sourceRoot":"","sources":["../../src/db-init/db-init.ts"],"names":[],"mappings":";;;AAAA,qDAA6F;AAC7F,+BAA4B;AAE5B,4CAA0C;AAC1C,yEAAqE;AACrE,+EAA2E;AAC3E,mDAKyB;AAElB,KAAK,UAAU,kBAAkB,CAAC,EACvC,UAAU,EACV,QAAQ,EACR,MAAM,GACmD;IACzD,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,IAAA,4BAAe,EAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAZ,4BAAY,EAAE,CAAC,CAAC;IAE5F,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAA,yCAA4B,EAAC;QACpD,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,IAAI;QACf,YAAY,EAAZ,4BAAY;QACZ,UAAU;QACV,OAAO,EAAE,IAAA,WAAI,EAAC,sBAAU,EAAE,KAAK,EAAE,qBAAqB,CAAC;QACvD,SAAS;QACT,QAAQ,EAAE,CAAC,wCAAkB,EAAE,8CAAqB,CAAC;QACrD,MAAM,EAAE,aAAa;KACtB,CAAC,CAAC;IAEH,KAAK,UAAU,SAAS,CAAC,EAAc;QACrC,MAAM,SAAS,GAAG,MAAM,IAAA,4BAAY,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvD,IAAI,SAAS,KAAK,8CAA8B,EAAE,CAAC;YACjD,MAAM,IAAA,+BAAe,EAAC,EAAE,EAAE;gBACxB,WAAW,EAAE,SAAS;gBACtB,QAAQ;gBACR,MAAM;aACP,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAClC,CAAC;AA9BD,gDA8BC"}
@@ -0,0 +1,12 @@
1
+ import { AppLog } from "@paroicms/server-lib";
2
+ import { DataSource } from "typeorm";
3
+ export declare const dbSchemaName = "image-cache";
4
+ export declare const currentVariantsDbSchemaVersion = 4;
5
+ export declare function getDbVersion(cn: DataSource, { siteName }: {
6
+ siteName: string;
7
+ }): Promise<number>;
8
+ export declare function migrateMediasDb(cn: DataSource, { fromVersion, siteName, appLog }: {
9
+ fromVersion: number;
10
+ siteName: string;
11
+ appLog: AppLog;
12
+ }): Promise<void>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrateMediasDb = exports.getDbVersion = exports.currentVariantsDbSchemaVersion = exports.dbSchemaName = void 0;
4
+ const data_formatters_lib_1 = require("@paroi/data-formatters-lib");
5
+ exports.dbSchemaName = "image-cache";
6
+ exports.currentVariantsDbSchemaVersion = 4;
7
+ async function getDbVersion(cn, { siteName }) {
8
+ const [row] = await cn.query(`select dbVersion from PaDbMetadata where dbSchema = '${exports.dbSchemaName}'`);
9
+ if (!row)
10
+ throw new Error(`[${siteName}] missing dbSchema '${exports.dbSchemaName}' in database`);
11
+ return (0, data_formatters_lib_1.nbVal)(row.dbVersion, { varName: "dbVersion" });
12
+ }
13
+ exports.getDbVersion = getDbVersion;
14
+ async function migrateMediasDb(cn, { fromVersion, siteName, appLog }) {
15
+ const toVersion = exports.currentVariantsDbSchemaVersion;
16
+ let currentVersion = fromVersion;
17
+ if (currentVersion < 4) {
18
+ await cn.query("drop table if exists PaImageVariant");
19
+ await cn.query("drop table if exists PaImageCache");
20
+ await cn.query("drop table if exists PaImageCacheKey");
21
+ await cn.query("drop table if exists PaImageCacheDependency");
22
+ await cn.query(`create table PaImageCache (
23
+ id integer not null primary key autoincrement,
24
+ imageUid varchar(36) not null,
25
+ variantName varchar(250) not null,
26
+ mediaType varchar(100) not null,
27
+ weightB integer not null,
28
+ width integer not null,
29
+ height integer not null,
30
+ ts timestamp not null default current_timestamp,
31
+ lastUseTs timestamp not null default current_timestamp,
32
+ binaryFile blob not null,
33
+ unique (imageUid, variantName)
34
+ )`);
35
+ await cn.query(`create table PaImageCacheKey (
36
+ imageCacheId integer not null references PaImageCache (id) on delete cascade,
37
+ cacheKey varchar(250) not null,
38
+ used tinyint(1) not null default 1,
39
+ primary key (imageCacheId, cacheKey)
40
+ )`);
41
+ await cn.query("create index PaImageCacheKey_cacheKey_index on PaImageCacheKey (cacheKey)");
42
+ await cn.query(`update PaDbMetadata set dbVersion = 4 where dbSchema = '${exports.dbSchemaName}'`);
43
+ currentVersion = 4;
44
+ }
45
+ if (currentVersion !== toVersion) {
46
+ throw new Error(`[${siteName}] version of ${exports.dbSchemaName} database should be '${toVersion}', but is '${currentVersion}'`);
47
+ }
48
+ appLog.info(`[${siteName}] ${exports.dbSchemaName} database was migrated from ${fromVersion} to ${currentVersion}`);
49
+ }
50
+ exports.migrateMediasDb = migrateMediasDb;
51
+ //# sourceMappingURL=ddl-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ddl-migration.js","sourceRoot":"","sources":["../../src/db-init/ddl-migration.ts"],"names":[],"mappings":";;;AAAA,oEAAmD;AAKtC,QAAA,YAAY,GAAG,aAAa,CAAC;AAC7B,QAAA,8BAA8B,GAAG,CAAC,CAAC;AAEzC,KAAK,UAAU,YAAY,CAAC,EAAc,EAAE,EAAE,QAAQ,EAAwB;IACnF,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAC1B,wDAAwD,oBAAY,GAAG,CACxE,CAAC;IACF,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,QAAQ,uBAAuB,oBAAY,eAAe,CAAC,CAAC;IAC1F,OAAO,IAAA,2BAAK,EAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AACxD,CAAC;AAND,oCAMC;AAEM,KAAK,UAAU,eAAe,CACnC,EAAc,EACd,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAA6D;IAE5F,MAAM,SAAS,GAAG,sCAA8B,CAAC;IACjD,IAAI,cAAc,GAAG,WAAW,CAAC;IACjC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,EAAE,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACtD,MAAM,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACpD,MAAM,EAAE,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,KAAK,CAAC;;;;;;;;;;;;EAYjB,CAAC,CAAC;QACA,MAAM,EAAE,CAAC,KAAK,CAAC;;;;;EAKjB,CAAC,CAAC;QACA,MAAM,EAAE,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC5F,MAAM,EAAE,CAAC,KAAK,CAAC,2DAA2D,oBAAY,GAAG,CAAC,CAAC;QAC3F,cAAc,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,IAAI,QAAQ,gBAAgB,oBAAY,wBAAwB,SAAS,cAAc,cAAc,GAAG,CACzG,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,IAAI,CACT,IAAI,QAAQ,KAAK,oBAAY,+BAA+B,WAAW,OAAO,cAAc,EAAE,CAC/F,CAAC;AACJ,CAAC;AA1CD,0CA0CC"}
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { OriginalImage } from "./original-images-processing";
3
+ export declare function createDefaultBoFavicon(binaryFile: Buffer): Promise<OriginalImage>;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createDefaultBoFavicon = void 0;
7
+ const sharp_1 = __importDefault(require("sharp"));
8
+ const image_processor_setup_1 = require("./image-processor-setup");
9
+ const resizer_1 = require("./internal/resizer");
10
+ const drawPixelByChannels = {
11
+ 1: drawPixel1Channel,
12
+ 2: drawPixel2Channels,
13
+ 3: drawPixel3Channels,
14
+ 4: drawPixel4Channels,
15
+ };
16
+ async function createDefaultBoFavicon(binaryFile) {
17
+ const sharpInst = (0, sharp_1.default)(binaryFile);
18
+ const metadata = await (0, image_processor_setup_1.sharpQueue)(() => sharpInst.metadata());
19
+ if (metadata.width === undefined || metadata.height === undefined) {
20
+ throw new Error("cannot get image size");
21
+ }
22
+ const dim = Math.min(metadata.width, metadata.height, 128);
23
+ const { data, info } = await (0, image_processor_setup_1.sharpQueue)(() => sharpInst
24
+ .resize({
25
+ width: dim,
26
+ height: dim,
27
+ fit: "cover",
28
+ })
29
+ .ensureAlpha()
30
+ .raw()
31
+ .toBuffer({ resolveWithObject: true }));
32
+ const { width, height, channels } = info;
33
+ const drawPixel = drawPixelByChannels[channels];
34
+ drawThePattern({ data, drawPixel, width: dim, channels });
35
+ const result = await (0, image_processor_setup_1.sharpQueue)(() => (0, sharp_1.default)(data, { raw: { width, height, channels } })
36
+ .webp({
37
+ lossless: true,
38
+ })
39
+ .toBuffer({ resolveWithObject: true }));
40
+ const mediaType = (0, resizer_1.convertSharpFormatToMediaType)(result.info.format);
41
+ return {
42
+ width: result.info.width,
43
+ height: result.info.height,
44
+ weightB: result.info.size,
45
+ mediaType,
46
+ lossless: mediaType === "image/png" || mediaType === "image/webp",
47
+ binaryFile: result.data,
48
+ };
49
+ }
50
+ exports.createDefaultBoFavicon = createDefaultBoFavicon;
51
+ function drawThePattern({ data, drawPixel, width, channels, }) {
52
+ const minX = Math.trunc(width * 0.05);
53
+ let maxX = Math.trunc(width * 0.45);
54
+ let w = maxX - minX;
55
+ if (w <= 0)
56
+ return;
57
+ if (w % 2 === 1) {
58
+ // ensure even width
59
+ ++w;
60
+ ++maxX;
61
+ if (maxX >= width)
62
+ return;
63
+ }
64
+ const minY = minX; // it's a square
65
+ const maxY = maxX;
66
+ const startX = minX + w / 2 - 1;
67
+ let curX = startX;
68
+ let curEndX = curX + 2;
69
+ let inc = true;
70
+ for (let y = minY; y < maxY; ++y) {
71
+ for (let x = curX; x < curEndX; ++x) {
72
+ const index = (y * width + x) * channels;
73
+ drawPixel(data, index);
74
+ }
75
+ if (inc) {
76
+ --curX;
77
+ ++curEndX;
78
+ if (curX <= minX || curEndX >= maxX) {
79
+ inc = false;
80
+ }
81
+ }
82
+ else {
83
+ ++curX;
84
+ --curEndX;
85
+ if (curX > startX) {
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ function drawPixel1Channel(data, index) {
92
+ data[index] = 200;
93
+ }
94
+ function drawPixel2Channels(data, index) {
95
+ drawPixel1Channel(data, index);
96
+ data[index + 1] = 255;
97
+ }
98
+ function drawPixel3Channels(data, index) {
99
+ data[index] = 240;
100
+ data[index + 1] = 60;
101
+ data[index + 2] = 60;
102
+ }
103
+ function drawPixel4Channels(data, index) {
104
+ drawPixel3Channels(data, index);
105
+ data[index + 3] = 255;
106
+ }
107
+ //# sourceMappingURL=default-bo-favicon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-bo-favicon.js","sourceRoot":"","sources":["../src/default-bo-favicon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /// <reference types="node" />
2
+ export interface ImageVariantStorage {
3
+ type: "sqlite";
4
+ file: string;
5
+ }
6
+ export type GetOriginalImage = (uid: string) => Promise<Buffer>;
7
+ export type VariantName = CompleteVariantName | AutoWidthVariantName | AutoHeightVariantName | AutoWidthOrHeightVariantName;
8
+ export type CompleteVariantName = `${number}x${number}`;
9
+ export type AutoWidthVariantName = `x${number}`;
10
+ export type AutoHeightVariantName = `${number}x`;
11
+ export type AutoWidthOrHeightVariantName = `x${number}x`;
12
+ export interface VariantSize {
13
+ width: number;
14
+ height: number;
15
+ completeVariantName: CompleteVariantName;
16
+ }
17
+ export interface NewVariantImage extends VariantSize {
18
+ mediaType: string;
19
+ }
20
+ export interface NewImageProps {
21
+ imageRef: ImageRef;
22
+ variantName: string;
23
+ autoCrop?: boolean;
24
+ mediaType?: string;
25
+ dependsOnCacheKey: string;
26
+ }
27
+ export interface ImageRef {
28
+ imageUid: string;
29
+ height: number;
30
+ width: number;
31
+ mediaType: string;
32
+ avgWidth?: number;
33
+ avgHeight?: number;
34
+ }
35
+ export interface ImageVariantWithBinary {
36
+ mediaType: string;
37
+ width: number;
38
+ height: number;
39
+ weightB: number;
40
+ binaryFile: Buffer;
41
+ /**
42
+ * Timestamp as ISO string.
43
+ */
44
+ lastModified: string;
45
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=engine-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-types.js","sourceRoot":"","sources":["../src/engine-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { ImageCompressionQualityPolicy } from "@paroicms/anywhere-lib";
2
+ import { AppLog } from "@paroicms/server-lib";
3
+ import { CompleteVariantName, GetOriginalImage, ImageRef, ImageVariantStorage, ImageVariantWithBinary, NewImageProps, NewVariantImage, VariantName } from "./engine-types";
4
+ import { VariantEngineContext } from "./internal/engine-context";
5
+ export interface CreateImageCacheEngineOptions {
6
+ siteName: string;
7
+ storage: ImageVariantStorage;
8
+ getOriginalImage: GetOriginalImage;
9
+ appLog?: AppLog;
10
+ qualityPolicy: ImageCompressionQualityPolicy[];
11
+ /**
12
+ * For example: `"14d"`. Leave `undefined` to keep cache data undefinitely.
13
+ */
14
+ timeToIdle?: string;
15
+ }
16
+ export declare function createImageCacheEngine(options: CreateImageCacheEngineOptions): Promise<ImageCacheEngine>;
17
+ export declare class ImageCacheEngine {
18
+ #private;
19
+ constructor(context: VariantEngineContext);
20
+ getImageVariantWithBinary({ imageUid, variantName, }: {
21
+ imageUid: string;
22
+ variantName: CompleteVariantName;
23
+ }): Promise<ImageVariantWithBinary | undefined>;
24
+ resetCacheKey(options: {
25
+ cacheKey: string;
26
+ }): Promise<void>;
27
+ makeImageAvailable(params: NewImageProps): NewVariantImage;
28
+ getOrCreateImageWithBinary(params: NewImageProps): Promise<ImageVariantWithBinary | undefined>;
29
+ conditionallyCreateImageVariantWithBinary(media: ImageRef, options: {
30
+ authorisedVariantNames: VariantName[];
31
+ variantName: CompleteVariantName;
32
+ dependsOnCacheKey: string;
33
+ }): Promise<ImageVariantWithBinary | undefined>;
34
+ invalidate(options: {
35
+ imageUid: string;
36
+ variantName?: string;
37
+ } | {
38
+ imageUids: string[];
39
+ } | {
40
+ cacheKeys: string[];
41
+ }): Promise<void>;
42
+ /**
43
+ * Delete the images that have no cacheKey and that have not been used recently.
44
+ */
45
+ cleanUnusedValues(): Promise<void>;
46
+ clearCache(): Promise<void>;
47
+ close(): Promise<void>;
48
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageCacheEngine = exports.createImageCacheEngine = void 0;
4
+ const async_lib_1 = require("@paroi/async-lib");
5
+ const queries_1 = require("./database/queries");
6
+ const compute_variant_size_1 = require("./internal/compute-variant-size");
7
+ const engine_context_1 = require("./internal/engine-context");
8
+ const task_processor_1 = require("./internal/task-processor");
9
+ async function createImageCacheEngine(options) {
10
+ const context = await (0, engine_context_1.createVariantEngineContext)(options);
11
+ return new ImageCacheEngine(context);
12
+ }
13
+ exports.createImageCacheEngine = createImageCacheEngine;
14
+ class ImageCacheEngine {
15
+ #processing = false;
16
+ #context;
17
+ constructor(context) {
18
+ this.#context = context;
19
+ }
20
+ async getImageVariantWithBinary({ imageUid, variantName, }) {
21
+ this.#checkStatus();
22
+ const taskKey = `${imageUid}:${variantName}`;
23
+ const pth = this.#context.pendingTasks.get(taskKey);
24
+ if (pth)
25
+ return pth.promise;
26
+ const found = await (0, queries_1.fetchImageVariantWithBinary)(this.#context, {
27
+ imageUid,
28
+ variantName,
29
+ });
30
+ return found ? found.variant : undefined;
31
+ }
32
+ async resetCacheKey(options) {
33
+ await (0, queries_1.markCacheKeyAsUnused)(this.#context, options);
34
+ }
35
+ makeImageAvailable(params) {
36
+ this.#checkStatus();
37
+ const imageUid = params.imageRef.imageUid;
38
+ const { width, height, completeVariantName } = (0, compute_variant_size_1.computeVariantSize)(params);
39
+ const taskKey = `${imageUid}:${completeVariantName}`;
40
+ if (!this.#context.pendingTasks.has(taskKey)) {
41
+ this.#context.queue.push({
42
+ taskKey,
43
+ variantName: completeVariantName,
44
+ imageUid,
45
+ imageSize: {
46
+ width,
47
+ height,
48
+ },
49
+ mediaType: params.imageRef.mediaType,
50
+ changeMediaTypeTo: params.mediaType,
51
+ dependsOnCacheKey: params.dependsOnCacheKey,
52
+ });
53
+ this.#context.pendingTasks.set(taskKey, (0, async_lib_1.promiseToHandle)());
54
+ this.#startQueue();
55
+ }
56
+ return {
57
+ width,
58
+ height,
59
+ completeVariantName,
60
+ mediaType: params.mediaType ?? params.imageRef.mediaType,
61
+ };
62
+ }
63
+ async getOrCreateImageWithBinary(params) {
64
+ this.#checkStatus();
65
+ const variant = this.makeImageAvailable(params);
66
+ return await this.getImageVariantWithBinary({
67
+ imageUid: params.imageRef.imageUid,
68
+ variantName: variant.completeVariantName,
69
+ });
70
+ }
71
+ async conditionallyCreateImageVariantWithBinary(media, options) {
72
+ this.#checkStatus();
73
+ const authorized = (0, compute_variant_size_1.findAuthorizedVariantSize)(media, options);
74
+ if (!authorized)
75
+ return;
76
+ const available = this.makeImageAvailable({
77
+ autoCrop: false,
78
+ variantName: authorized.completeVariantName,
79
+ imageRef: media,
80
+ dependsOnCacheKey: options.dependsOnCacheKey,
81
+ });
82
+ if (available.completeVariantName !== authorized.completeVariantName) {
83
+ throw new Error(`mismatch variants '${available.completeVariantName}' and '${authorized.completeVariantName}'`);
84
+ }
85
+ return await this.getImageVariantWithBinary({
86
+ imageUid: media.imageUid,
87
+ variantName: available.completeVariantName,
88
+ });
89
+ }
90
+ async invalidate(options) {
91
+ this.#checkStatus();
92
+ if ("cacheKeys" in options) {
93
+ await (0, queries_1.deleteVariantsByDependencies)(this.#context.cn, options);
94
+ }
95
+ else {
96
+ await (0, queries_1.deleteVariants)(this.#context.cn, options);
97
+ }
98
+ }
99
+ /**
100
+ * Delete the images that have no cacheKey and that have not been used recently.
101
+ */
102
+ async cleanUnusedValues() {
103
+ this.#checkStatus();
104
+ const count = await (0, queries_1.deleteUnusedVariants)(this.#context);
105
+ if (count !== undefined && count > 0) {
106
+ this.#context.appLog.debug(`[${this.#context.siteName}] ${count} unused cache image were deleted`);
107
+ }
108
+ }
109
+ async clearCache() {
110
+ this.#checkStatus();
111
+ await (0, queries_1.clearVariantCache)(this.#context);
112
+ this.#context.appLog.debug(`[${this.#context.siteName}] cache is cleared`);
113
+ }
114
+ #startQueue() {
115
+ if (this.#processing)
116
+ return;
117
+ this.#processing = true;
118
+ void (0, task_processor_1.processAllPending)(this.#context)
119
+ .catch((error) => {
120
+ this.#context.appLog.error("Error when proccessing =>", error);
121
+ })
122
+ .then(() => {
123
+ this.#processing = false;
124
+ });
125
+ }
126
+ async close() {
127
+ if (this.#context.status === "destroyed")
128
+ return;
129
+ this.#context.status = "destroyed";
130
+ await this.#context.mainCn.destroy();
131
+ }
132
+ #checkStatus() {
133
+ if (this.#context.status !== "ready") {
134
+ throw new Error(`ImageCacheEngine is ${this.#context.status}`);
135
+ }
136
+ }
137
+ }
138
+ exports.ImageCacheEngine = ImageCacheEngine;
139
+ //# sourceMappingURL=image-cache-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-cache-engine.js","sourceRoot":"","sources":["../src/image-cache-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { AppLog } from "@paroicms/server-lib";
2
+ export declare let sharpQueue: <T extends () => Promise<any>>(task: T) => ReturnType<T>;
3
+ export interface SetupImageProcessorOptions {
4
+ cpuCoresPerFile?: number;
5
+ oneSharpAtATime?: boolean;
6
+ appLog: AppLog;
7
+ }
8
+ export declare function setupImageProcessor({ cpuCoresPerFile, oneSharpAtATime, appLog, }: SetupImageProcessorOptions): void;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.setupImageProcessor = exports.sharpQueue = void 0;
7
+ const async_lib_1 = require("@paroi/async-lib");
8
+ const sharp_1 = __importDefault(require("sharp"));
9
+ exports.sharpQueue = execImmediately;
10
+ function setupImageProcessor({ cpuCoresPerFile, oneSharpAtATime, appLog, }) {
11
+ if (cpuCoresPerFile !== undefined) {
12
+ const oldValue = sharp_1.default.concurrency();
13
+ // https://sharp.pixelplumbing.com/api-utility#concurrency
14
+ sharp_1.default.concurrency(cpuCoresPerFile);
15
+ appLog.info(`Set sharp concurrency (cpu cores per file) to '${cpuCoresPerFile}' (was ${oldValue})`);
16
+ }
17
+ if (oneSharpAtATime !== undefined) {
18
+ if (oneSharpAtATime) {
19
+ exports.sharpQueue = (0, async_lib_1.createAsyncQueue)({
20
+ delayMs: 50,
21
+ });
22
+ }
23
+ else {
24
+ exports.sharpQueue = execImmediately;
25
+ }
26
+ appLog.info(`${oneSharpAtATime ? "Enable" : "Disable"} mode "one sharp at a time"`);
27
+ }
28
+ }
29
+ exports.setupImageProcessor = setupImageProcessor;
30
+ function execImmediately(task) {
31
+ return task();
32
+ }
33
+ //# sourceMappingURL=image-processor-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-processor-setup.js","sourceRoot":"","sources":["../src/image-processor-setup.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAoD;AAEpD,kDAA0B;AAEf,QAAA,UAAU,GAA6D,eAAe,CAAC;AAQlG,SAAgB,mBAAmB,CAAC,EAClC,eAAe,EACf,eAAe,EACf,MAAM,GACqB;IAC3B,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,eAAK,CAAC,WAAW,EAAE,CAAC;QACrC,0DAA0D;QAC1D,eAAK,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CACT,kDAAkD,eAAe,UAAU,QAAQ,GAAG,CACvF,CAAC;IACJ,CAAC;IACD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,eAAe,EAAE,CAAC;YACpB,kBAAU,GAAG,IAAA,4BAAgB,EAAC;gBAC5B,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,kBAAU,GAAG,eAAe,CAAC;QAC/B,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,6BAA6B,CAAC,CAAC;IACtF,CAAC;AACH,CAAC;AAvBD,kDAuBC;AAED,SAAS,eAAe,CAA+B,IAAO;IAC5D,OAAO,IAAI,EAAmB,CAAC;AACjC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { CompleteVariantName, ImageRef, VariantName, VariantSize } from "../engine-types";
2
+ export declare function findAuthorizedVariantSize(media: ImageRef, options: {
3
+ authorisedVariantNames: VariantName[];
4
+ variantName: CompleteVariantName;
5
+ }): VariantSize | undefined;
6
+ export interface ComputeVariantSizeParams {
7
+ imageRef: Pick<ImageRef, "width" | "height" | "avgWidth" | "avgHeight">;
8
+ variantName: string;
9
+ autoCrop?: boolean;
10
+ }
11
+ export declare function computeVariantSize({ imageRef, variantName, autoCrop, }: ComputeVariantSizeParams): VariantSize;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeVariantSize = exports.findAuthorizedVariantSize = void 0;
4
+ const data_formatters_lib_1 = require("@paroi/data-formatters-lib");
5
+ const public_helpers_1 = require("../public-helpers");
6
+ function findAuthorizedVariantSize(media, options) {
7
+ for (const variantName of options.authorisedVariantNames) {
8
+ const variantSize = computeVariantSize({
9
+ variantName,
10
+ imageRef: media,
11
+ });
12
+ if (variantSize.completeVariantName === options.variantName)
13
+ return variantSize;
14
+ }
15
+ }
16
+ exports.findAuthorizedVariantSize = findAuthorizedVariantSize;
17
+ function computeVariantSize({ imageRef, variantName, autoCrop, }) {
18
+ if (!(0, public_helpers_1.isVariantName)(variantName)) {
19
+ throw new Error(`This variantName ${variantName} is not handled.`);
20
+ }
21
+ const splittedVariantName = variantName.split("x");
22
+ if (splittedVariantName.length === 3) {
23
+ const value = splittedVariantName[1];
24
+ if (imageRef.height > imageRef.width) {
25
+ variantName = `x${value}`;
26
+ }
27
+ else if (imageRef.width > imageRef.height) {
28
+ variantName = `${value}x`;
29
+ }
30
+ else {
31
+ variantName = `${value}x`;
32
+ }
33
+ }
34
+ const v = parseVariantName(variantName);
35
+ if (v.height !== undefined && v.width !== undefined) {
36
+ return toVariantSize(reduceSizeIfNecessary({ width: v.width, height: v.height }, imageRef));
37
+ }
38
+ const autoCropAvg = autoCrop && imageRef.avgHeight !== undefined && imageRef.avgWidth !== undefined
39
+ ? {
40
+ width: imageRef.avgWidth,
41
+ height: imageRef.avgHeight,
42
+ }
43
+ : undefined;
44
+ if (v.width !== undefined && v.height === undefined) {
45
+ const targetHeight = autoCropAvg
46
+ ? Math.round((v.width * autoCropAvg.height) / autoCropAvg.width)
47
+ : Math.round((v.width * imageRef.height) / imageRef.width);
48
+ return toVariantSize(reduceSizeIfNecessary({ width: v.width, height: targetHeight }, imageRef));
49
+ }
50
+ if (v.height !== undefined && v.width === undefined) {
51
+ const targetWidth = autoCropAvg
52
+ ? Math.round((v.height * autoCropAvg.width) / autoCropAvg.height)
53
+ : Math.round((v.height * imageRef.width) / imageRef.height);
54
+ return toVariantSize(reduceSizeIfNecessary({ width: targetWidth, height: v.height }, imageRef));
55
+ }
56
+ throw new Error(`Invalid variant '${variantName}'`);
57
+ }
58
+ exports.computeVariantSize = computeVariantSize;
59
+ function parseVariantName(variantName) {
60
+ const [width, height] = variantName.split("x");
61
+ return {
62
+ width: width === "" ? undefined : (0, data_formatters_lib_1.nbVal)(width),
63
+ height: height === "" ? undefined : (0, data_formatters_lib_1.nbVal)(height),
64
+ };
65
+ }
66
+ function reduceSizeIfNecessary(preferredSize, actualSize) {
67
+ const diffW = actualSize.width - preferredSize.width;
68
+ const diffH = actualSize.height - preferredSize.height;
69
+ if (diffW >= 0 && diffH >= 0) {
70
+ return preferredSize;
71
+ }
72
+ if (diffW < diffH) {
73
+ return {
74
+ width: actualSize.width,
75
+ height: Math.round((actualSize.width * preferredSize.height) / preferredSize.width),
76
+ };
77
+ }
78
+ else {
79
+ return {
80
+ width: Math.round((actualSize.height * preferredSize.width) / preferredSize.height),
81
+ height: actualSize.height,
82
+ };
83
+ }
84
+ }
85
+ function toVariantSize(size) {
86
+ return {
87
+ ...size,
88
+ completeVariantName: `${size.width}x${size.height}`,
89
+ };
90
+ }
91
+ //# sourceMappingURL=compute-variant-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-variant-size.js","sourceRoot":"","sources":["../../src/internal/compute-variant-size.ts"],"names":[],"mappings":"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"}