@lens-image/core 0.1.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.
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/cjs/adapters/memory.d.ts +55 -0
- package/dist/cjs/adapters/memory.d.ts.map +1 -0
- package/dist/cjs/adapters/memory.js +84 -0
- package/dist/cjs/adapters/memory.js.map +1 -0
- package/dist/cjs/browser.d.ts +46 -0
- package/dist/cjs/browser.d.ts.map +1 -0
- package/dist/cjs/browser.js +79 -0
- package/dist/cjs/browser.js.map +1 -0
- package/dist/cjs/bytes.d.ts +18 -0
- package/dist/cjs/bytes.d.ts.map +1 -0
- package/dist/cjs/bytes.js +31 -0
- package/dist/cjs/bytes.js.map +1 -0
- package/dist/cjs/cache.d.ts +43 -0
- package/dist/cjs/cache.d.ts.map +1 -0
- package/dist/cjs/cache.js +77 -0
- package/dist/cjs/cache.js.map +1 -0
- package/dist/cjs/concurrency.d.ts +35 -0
- package/dist/cjs/concurrency.d.ts.map +1 -0
- package/dist/cjs/concurrency.js +82 -0
- package/dist/cjs/concurrency.js.map +1 -0
- package/dist/cjs/engines/index.d.ts +20 -0
- package/dist/cjs/engines/index.d.ts.map +1 -0
- package/dist/cjs/engines/index.js +38 -0
- package/dist/cjs/engines/index.js.map +1 -0
- package/dist/cjs/engines/passthrough.d.ts +41 -0
- package/dist/cjs/engines/passthrough.d.ts.map +1 -0
- package/dist/cjs/engines/passthrough.js +66 -0
- package/dist/cjs/engines/passthrough.js.map +1 -0
- package/dist/cjs/engines/sharp.d.ts +58 -0
- package/dist/cjs/engines/sharp.d.ts.map +1 -0
- package/dist/cjs/engines/sharp.js +243 -0
- package/dist/cjs/engines/sharp.js.map +1 -0
- package/dist/cjs/errors.d.ts +90 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +97 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/format.d.ts +33 -0
- package/dist/cjs/format.d.ts.map +1 -0
- package/dist/cjs/format.js +102 -0
- package/dist/cjs/format.js.map +1 -0
- package/dist/cjs/hash.d.ts +19 -0
- package/dist/cjs/hash.d.ts.map +1 -0
- package/dist/cjs/hash.js +43 -0
- package/dist/cjs/hash.js.map +1 -0
- package/dist/cjs/index.d.ts +56 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +110 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/naming.d.ts +48 -0
- package/dist/cjs/naming.d.ts.map +1 -0
- package/dist/cjs/naming.js +95 -0
- package/dist/cjs/naming.js.map +1 -0
- package/dist/cjs/optimizer.d.ts +89 -0
- package/dist/cjs/optimizer.d.ts.map +1 -0
- package/dist/cjs/optimizer.js +667 -0
- package/dist/cjs/optimizer.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/retry.d.ts +55 -0
- package/dist/cjs/retry.d.ts.map +1 -0
- package/dist/cjs/retry.js +129 -0
- package/dist/cjs/retry.js.map +1 -0
- package/dist/cjs/server/handler.d.ts +80 -0
- package/dist/cjs/server/handler.d.ts.map +1 -0
- package/dist/cjs/server/handler.js +155 -0
- package/dist/cjs/server/handler.js.map +1 -0
- package/dist/cjs/sniff.d.ts +37 -0
- package/dist/cjs/sniff.d.ts.map +1 -0
- package/dist/cjs/sniff.js +442 -0
- package/dist/cjs/sniff.js.map +1 -0
- package/dist/cjs/source.d.ts +45 -0
- package/dist/cjs/source.d.ts.map +1 -0
- package/dist/cjs/source.js +221 -0
- package/dist/cjs/source.js.map +1 -0
- package/dist/cjs/srcset.d.ts +66 -0
- package/dist/cjs/srcset.d.ts.map +1 -0
- package/dist/cjs/srcset.js +81 -0
- package/dist/cjs/srcset.js.map +1 -0
- package/dist/cjs/types.d.ts +441 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +12 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/validation.d.ts +38 -0
- package/dist/cjs/validation.d.ts.map +1 -0
- package/dist/cjs/validation.js +79 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/adapters/memory.d.ts +55 -0
- package/dist/esm/adapters/memory.d.ts.map +1 -0
- package/dist/esm/adapters/memory.js +80 -0
- package/dist/esm/adapters/memory.js.map +1 -0
- package/dist/esm/browser.d.ts +46 -0
- package/dist/esm/browser.d.ts.map +1 -0
- package/dist/esm/browser.js +49 -0
- package/dist/esm/browser.js.map +1 -0
- package/dist/esm/bytes.d.ts +18 -0
- package/dist/esm/bytes.d.ts.map +1 -0
- package/dist/esm/bytes.js +28 -0
- package/dist/esm/bytes.js.map +1 -0
- package/dist/esm/cache.d.ts +43 -0
- package/dist/esm/cache.d.ts.map +1 -0
- package/dist/esm/cache.js +73 -0
- package/dist/esm/cache.js.map +1 -0
- package/dist/esm/concurrency.d.ts +35 -0
- package/dist/esm/concurrency.d.ts.map +1 -0
- package/dist/esm/concurrency.js +78 -0
- package/dist/esm/concurrency.js.map +1 -0
- package/dist/esm/engines/index.d.ts +20 -0
- package/dist/esm/engines/index.d.ts.map +1 -0
- package/dist/esm/engines/index.js +30 -0
- package/dist/esm/engines/index.js.map +1 -0
- package/dist/esm/engines/passthrough.d.ts +41 -0
- package/dist/esm/engines/passthrough.d.ts.map +1 -0
- package/dist/esm/engines/passthrough.js +63 -0
- package/dist/esm/engines/passthrough.js.map +1 -0
- package/dist/esm/engines/sharp.d.ts +58 -0
- package/dist/esm/engines/sharp.d.ts.map +1 -0
- package/dist/esm/engines/sharp.js +206 -0
- package/dist/esm/engines/sharp.js.map +1 -0
- package/dist/esm/errors.d.ts +90 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +91 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/format.d.ts +33 -0
- package/dist/esm/format.d.ts.map +1 -0
- package/dist/esm/format.js +93 -0
- package/dist/esm/format.js.map +1 -0
- package/dist/esm/hash.d.ts +19 -0
- package/dist/esm/hash.d.ts.map +1 -0
- package/dist/esm/hash.js +38 -0
- package/dist/esm/hash.js.map +1 -0
- package/dist/esm/index.d.ts +56 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +54 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/naming.d.ts +48 -0
- package/dist/esm/naming.d.ts.map +1 -0
- package/dist/esm/naming.js +88 -0
- package/dist/esm/naming.js.map +1 -0
- package/dist/esm/optimizer.d.ts +89 -0
- package/dist/esm/optimizer.d.ts.map +1 -0
- package/dist/esm/optimizer.js +663 -0
- package/dist/esm/optimizer.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/retry.d.ts +55 -0
- package/dist/esm/retry.d.ts.map +1 -0
- package/dist/esm/retry.js +123 -0
- package/dist/esm/retry.js.map +1 -0
- package/dist/esm/server/handler.d.ts +80 -0
- package/dist/esm/server/handler.d.ts.map +1 -0
- package/dist/esm/server/handler.js +151 -0
- package/dist/esm/server/handler.js.map +1 -0
- package/dist/esm/sniff.d.ts +37 -0
- package/dist/esm/sniff.d.ts.map +1 -0
- package/dist/esm/sniff.js +435 -0
- package/dist/esm/sniff.js.map +1 -0
- package/dist/esm/source.d.ts +45 -0
- package/dist/esm/source.d.ts.map +1 -0
- package/dist/esm/source.js +183 -0
- package/dist/esm/source.js.map +1 -0
- package/dist/esm/srcset.d.ts +66 -0
- package/dist/esm/srcset.d.ts.map +1 -0
- package/dist/esm/srcset.js +76 -0
- package/dist/esm/srcset.js.map +1 -0
- package/dist/esm/types.d.ts +441 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +11 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/validation.d.ts +38 -0
- package/dist/esm/validation.d.ts.map +1 -0
- package/dist/esm/validation.js +74 -0
- package/dist/esm/validation.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Result caching.
|
|
4
|
+
*
|
|
5
|
+
* The expensive part of an optimize run is the encode, and the result is a pure
|
|
6
|
+
* function of (source bytes, options). So the cache key is a hash of both, and
|
|
7
|
+
* a hit skips encoding *and* uploading entirely.
|
|
8
|
+
*
|
|
9
|
+
* Three strategies, in increasing order of how much they trust the world:
|
|
10
|
+
*
|
|
11
|
+
* - `'memory'` - process-lifetime LRU. Fast, but a fresh deploy starts cold and
|
|
12
|
+
* a second instance does the work again.
|
|
13
|
+
* - `'storage'` - memory, plus `adapter.exists()` so a warm bucket short-circuits
|
|
14
|
+
* a cold process.
|
|
15
|
+
* - a {@link CacheStore} - your own Redis/SQLite, shared across instances.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.nullCacheStore = exports.MemoryCacheStore = void 0;
|
|
19
|
+
/**
|
|
20
|
+
* A bounded LRU map.
|
|
21
|
+
*
|
|
22
|
+
* Insertion-ordered `Map` iteration gives us the eviction order for free: the
|
|
23
|
+
* first key `keys().next()` yields is the least recently used, because reads
|
|
24
|
+
* re-insert.
|
|
25
|
+
*/
|
|
26
|
+
class MemoryCacheStore {
|
|
27
|
+
#entries = new Map();
|
|
28
|
+
#max;
|
|
29
|
+
/** @param max - Entries to keep before evicting the least recently used. */
|
|
30
|
+
constructor(max = 500) {
|
|
31
|
+
this.#max = Math.max(1, Math.floor(max));
|
|
32
|
+
}
|
|
33
|
+
get(key) {
|
|
34
|
+
const value = this.#entries.get(key);
|
|
35
|
+
if (value === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
// Re-insert to mark as most recently used.
|
|
38
|
+
this.#entries.delete(key);
|
|
39
|
+
this.#entries.set(key, value);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
set(key, value) {
|
|
43
|
+
if (this.#entries.has(key))
|
|
44
|
+
this.#entries.delete(key);
|
|
45
|
+
this.#entries.set(key, value);
|
|
46
|
+
while (this.#entries.size > this.#max) {
|
|
47
|
+
const oldest = this.#entries.keys().next();
|
|
48
|
+
if (oldest.done)
|
|
49
|
+
break;
|
|
50
|
+
this.#entries.delete(oldest.value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
delete(key) {
|
|
54
|
+
this.#entries.delete(key);
|
|
55
|
+
}
|
|
56
|
+
/** Drops every entry. */
|
|
57
|
+
clear() {
|
|
58
|
+
this.#entries.clear();
|
|
59
|
+
}
|
|
60
|
+
/** Current entry count. Handy in tests and metrics. */
|
|
61
|
+
get size() {
|
|
62
|
+
return this.#entries.size;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.MemoryCacheStore = MemoryCacheStore;
|
|
66
|
+
/**
|
|
67
|
+
* A cache store that never stores anything.
|
|
68
|
+
*
|
|
69
|
+
* Lets the optimizer treat "caching off" as just another store, rather than
|
|
70
|
+
* branching on null at every call site.
|
|
71
|
+
*/
|
|
72
|
+
exports.nullCacheStore = {
|
|
73
|
+
get: () => undefined,
|
|
74
|
+
set: () => undefined,
|
|
75
|
+
delete: () => undefined,
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAIH;;;;;;GAMG;AACH,MAAa,gBAAgB;IAClB,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC7C,IAAI,CAAS;IAEtB,4EAA4E;IAC5E,YAAY,GAAG,GAAG,GAAG;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1C,2CAA2C;QAC3C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAqB;QACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE9B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI;gBAAE,MAAM;YACvB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,yBAAyB;IACzB,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,uDAAuD;IACvD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF;AA1CD,4CA0CC;AAED;;;;;GAKG;AACU,QAAA,cAAc,GAAe;IACxC,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;IACpB,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;IACpB,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS;CACxB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A ~40-line replacement for `p-map` / `p-limit`.
|
|
3
|
+
*
|
|
4
|
+
* Unbounded `Promise.all` over image encodes is how you turn a 12-variant
|
|
5
|
+
* upload into an out-of-memory crash: sharp holds the full decoded bitmap per
|
|
6
|
+
* in-flight job, so twelve 4K photos is several gigabytes of RSS.
|
|
7
|
+
*/
|
|
8
|
+
/** Outcome of one task in a {@link mapLimit} run. */
|
|
9
|
+
export type Settled<T> = {
|
|
10
|
+
readonly status: 'fulfilled';
|
|
11
|
+
readonly value: T;
|
|
12
|
+
readonly index: number;
|
|
13
|
+
} | {
|
|
14
|
+
readonly status: 'rejected';
|
|
15
|
+
readonly reason: unknown;
|
|
16
|
+
readonly index: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Runs `worker` over `items` with at most `limit` in flight, preserving input
|
|
20
|
+
* order in the output.
|
|
21
|
+
*
|
|
22
|
+
* Unlike `Promise.all`, one rejection does not discard the work that succeeded:
|
|
23
|
+
* every task settles and you get a per-item verdict. That is what makes
|
|
24
|
+
* "the AVIF encoder died but the WebP is fine" a warning instead of a failure.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const results = await mapLimit(variants, 4, (v) => encodeAndUpload(v));
|
|
29
|
+
* const ok = results.filter((r) => r.status === 'fulfilled');
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function mapLimit<T, R>(items: readonly T[], limit: number, worker: (item: T, index: number) => Promise<R>, signal?: AbortSignal): Promise<Settled<R>[]>;
|
|
33
|
+
/** Sleep that rejects promptly when the signal fires, instead of after the delay. */
|
|
34
|
+
export declare function delay(ms: number, signal?: AbortSignal): Promise<void>;
|
|
35
|
+
//# sourceMappingURL=concurrency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/concurrency.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,qDAAqD;AACrD,MAAM,MAAM,OAAO,CAAC,CAAC,IACjB;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAkCvB;AAED,qFAAqF;AACrF,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBrE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A ~40-line replacement for `p-map` / `p-limit`.
|
|
4
|
+
*
|
|
5
|
+
* Unbounded `Promise.all` over image encodes is how you turn a 12-variant
|
|
6
|
+
* upload into an out-of-memory crash: sharp holds the full decoded bitmap per
|
|
7
|
+
* in-flight job, so twelve 4K photos is several gigabytes of RSS.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.mapLimit = mapLimit;
|
|
11
|
+
exports.delay = delay;
|
|
12
|
+
const errors_js_1 = require("./errors.js");
|
|
13
|
+
/**
|
|
14
|
+
* Runs `worker` over `items` with at most `limit` in flight, preserving input
|
|
15
|
+
* order in the output.
|
|
16
|
+
*
|
|
17
|
+
* Unlike `Promise.all`, one rejection does not discard the work that succeeded:
|
|
18
|
+
* every task settles and you get a per-item verdict. That is what makes
|
|
19
|
+
* "the AVIF encoder died but the WebP is fine" a warning instead of a failure.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const results = await mapLimit(variants, 4, (v) => encodeAndUpload(v));
|
|
24
|
+
* const ok = results.filter((r) => r.status === 'fulfilled');
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
async function mapLimit(items, limit, worker, signal) {
|
|
28
|
+
if (items.length === 0)
|
|
29
|
+
return [];
|
|
30
|
+
const size = Math.max(1, Math.min(Math.floor(limit) || 1, items.length));
|
|
31
|
+
const results = new Array(items.length);
|
|
32
|
+
let cursor = 0;
|
|
33
|
+
const runners = Array.from({ length: size }, async () => {
|
|
34
|
+
for (;;) {
|
|
35
|
+
const index = cursor++;
|
|
36
|
+
if (index >= items.length)
|
|
37
|
+
return;
|
|
38
|
+
// Stop handing out work once aborted, but let in-flight tasks settle so
|
|
39
|
+
// adapters get a chance to clean up rather than being orphaned.
|
|
40
|
+
if (signal?.aborted) {
|
|
41
|
+
results[index] = {
|
|
42
|
+
status: 'rejected',
|
|
43
|
+
index,
|
|
44
|
+
reason: new errors_js_1.LensError('ABORTED', 'Task was skipped because the run was aborted.'),
|
|
45
|
+
};
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
results[index] = { status: 'fulfilled', value: await worker(items[index], index), index };
|
|
50
|
+
}
|
|
51
|
+
catch (reason) {
|
|
52
|
+
results[index] = { status: 'rejected', reason, index };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
await Promise.all(runners);
|
|
57
|
+
(0, errors_js_1.throwIfAborted)(signal, 'run');
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
/** Sleep that rejects promptly when the signal fires, instead of after the delay. */
|
|
61
|
+
function delay(ms, signal) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
if (signal?.aborted) {
|
|
64
|
+
reject(new errors_js_1.LensError('ABORTED', 'Delay was aborted.'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Deliberately NOT unref'd. A pending retry backoff is real outstanding
|
|
68
|
+
// work: unref-ing it lets Node drain the event loop and exit (or a test
|
|
69
|
+
// runner declare the turn over) while an upload is still waiting to be
|
|
70
|
+
// retried, silently dropping it.
|
|
71
|
+
const timer = setTimeout(() => {
|
|
72
|
+
signal?.removeEventListener('abort', onAbort);
|
|
73
|
+
resolve();
|
|
74
|
+
}, ms);
|
|
75
|
+
function onAbort() {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
reject(new errors_js_1.LensError('ABORTED', 'Delay was aborted.'));
|
|
78
|
+
}
|
|
79
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=concurrency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/concurrency.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAuBH,4BAuCC;AAGD,sBAqBC;AApFD,2CAAwD;AAOxD;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,QAAQ,CAC5B,KAAmB,EACnB,KAAa,EACb,MAA8C,EAC9C,MAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,KAAK,CAAa,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;QACtD,SAAS,CAAC;YACR,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;YACvB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO;YAElC,wEAAwE;YACxE,gEAAgE;YAChE,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,GAAG;oBACf,MAAM,EAAE,UAAU;oBAClB,KAAK;oBACL,MAAM,EAAE,IAAI,qBAAS,CAAC,SAAS,EAAE,+CAA+C,CAAC;iBAClF,CAAC;gBACF,SAAS;YACX,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;YACjG,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,IAAA,0BAAc,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,qFAAqF;AACrF,SAAgB,KAAK,CAAC,EAAU,EAAE,MAAoB;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,qBAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QACD,wEAAwE;QACxE,wEAAwE;QACxE,uEAAuE;QACvE,iCAAiC;QACjC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,SAAS,OAAO;YACd,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,qBAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Engine selection. */
|
|
2
|
+
import type { ImageEngine } from './../types.js';
|
|
3
|
+
export { createSharpEngine, resetSharpCache, type SharpEngineOptions } from './sharp.js';
|
|
4
|
+
export { createPassthroughEngine, type PassthroughEngineOptions } from './passthrough.js';
|
|
5
|
+
/**
|
|
6
|
+
* Picks the best engine available in this process.
|
|
7
|
+
*
|
|
8
|
+
* Returns the sharp engine when sharp can be imported, otherwise the
|
|
9
|
+
* passthrough engine. Detection happens once and is memoised - an optimizer
|
|
10
|
+
* constructed at module scope should not pay for a dynamic import on every call.
|
|
11
|
+
*
|
|
12
|
+
* Note that the passthrough fallback is not silent: it throws a message naming
|
|
13
|
+
* sharp the first time you ask it to actually resize something. The goal is
|
|
14
|
+
* that "I forgot to install sharp" surfaces as one clear error rather than as
|
|
15
|
+
* mysteriously unprocessed images.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectEngine(): Promise<ImageEngine>;
|
|
18
|
+
/** Test seam: forget the memoised engine detection. */
|
|
19
|
+
export declare function resetEngineDetection(): void;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engines/index.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAIxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,uBAAuB,EAAE,KAAK,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAI1F;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAMzD;AAED,uDAAuD;AACvD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Engine selection. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createPassthroughEngine = exports.resetSharpCache = exports.createSharpEngine = void 0;
|
|
5
|
+
exports.detectEngine = detectEngine;
|
|
6
|
+
exports.resetEngineDetection = resetEngineDetection;
|
|
7
|
+
const passthrough_js_1 = require("./passthrough.js");
|
|
8
|
+
const sharp_js_1 = require("./sharp.js");
|
|
9
|
+
var sharp_js_2 = require("./sharp.js");
|
|
10
|
+
Object.defineProperty(exports, "createSharpEngine", { enumerable: true, get: function () { return sharp_js_2.createSharpEngine; } });
|
|
11
|
+
Object.defineProperty(exports, "resetSharpCache", { enumerable: true, get: function () { return sharp_js_2.resetSharpCache; } });
|
|
12
|
+
var passthrough_js_2 = require("./passthrough.js");
|
|
13
|
+
Object.defineProperty(exports, "createPassthroughEngine", { enumerable: true, get: function () { return passthrough_js_2.createPassthroughEngine; } });
|
|
14
|
+
let detected;
|
|
15
|
+
/**
|
|
16
|
+
* Picks the best engine available in this process.
|
|
17
|
+
*
|
|
18
|
+
* Returns the sharp engine when sharp can be imported, otherwise the
|
|
19
|
+
* passthrough engine. Detection happens once and is memoised - an optimizer
|
|
20
|
+
* constructed at module scope should not pay for a dynamic import on every call.
|
|
21
|
+
*
|
|
22
|
+
* Note that the passthrough fallback is not silent: it throws a message naming
|
|
23
|
+
* sharp the first time you ask it to actually resize something. The goal is
|
|
24
|
+
* that "I forgot to install sharp" surfaces as one clear error rather than as
|
|
25
|
+
* mysteriously unprocessed images.
|
|
26
|
+
*/
|
|
27
|
+
async function detectEngine() {
|
|
28
|
+
detected ??= (async () => {
|
|
29
|
+
const sharp = (0, sharp_js_1.createSharpEngine)();
|
|
30
|
+
return (await sharp.supports('webp')) ? sharp : (0, passthrough_js_1.createPassthroughEngine)();
|
|
31
|
+
})();
|
|
32
|
+
return detected;
|
|
33
|
+
}
|
|
34
|
+
/** Test seam: forget the memoised engine detection. */
|
|
35
|
+
function resetEngineDetection() {
|
|
36
|
+
detected = undefined;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engines/index.ts"],"names":[],"mappings":";AAAA,wBAAwB;;;AAuBxB,oCAMC;AAGD,oDAEC;AAhCD,qDAA2D;AAC3D,yCAA+C;AAG/C,uCAAyF;AAAhF,6GAAA,iBAAiB,OAAA;AAAE,2GAAA,eAAe,OAAA;AAC3C,mDAA0F;AAAjF,yHAAA,uBAAuB,OAAA;AAEhC,IAAI,QAA0C,CAAC;AAE/C;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,YAAY;IAChC,QAAQ,KAAK,CAAC,KAAK,IAAI,EAAE;QACvB,MAAM,KAAK,GAAG,IAAA,4BAAiB,GAAE,CAAC;QAClC,OAAO,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,wCAAuB,GAAE,CAAC;IAC5E,CAAC,CAAC,EAAE,CAAC;IACL,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uDAAuD;AACvD,SAAgB,oBAAoB;IAClC,QAAQ,GAAG,SAAS,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A codec-free {@link ImageEngine}.
|
|
3
|
+
*
|
|
4
|
+
* It cannot resize or transcode - it has no decoder. What it *can* do is read
|
|
5
|
+
* dimensions from the header and hand the original bytes back unchanged, which
|
|
6
|
+
* covers three real cases:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Tests.** Deterministic, instant, no native binary in CI.
|
|
9
|
+
* 2. **Store-only pipelines.** Validate, content-hash, key and upload an image
|
|
10
|
+
* without re-encoding it.
|
|
11
|
+
* 3. **Graceful degradation.** When sharp is missing, the optimizer can still
|
|
12
|
+
* store the original rather than failing the whole request - the user's
|
|
13
|
+
* upload survives, just unoptimised.
|
|
14
|
+
*/
|
|
15
|
+
import type { ImageEngine } from './../types.js';
|
|
16
|
+
/** Options for {@link createPassthroughEngine}. */
|
|
17
|
+
export interface PassthroughEngineOptions {
|
|
18
|
+
/**
|
|
19
|
+
* What to do when asked for work it cannot do.
|
|
20
|
+
*
|
|
21
|
+
* - `'throw'` (default) - a clear `ENCODE_FAILED`, so the optimizer records a
|
|
22
|
+
* warning and moves to the next format.
|
|
23
|
+
* - `'ignore'` - return the original bytes with their true dimensions. Honest
|
|
24
|
+
* about what happened, because the result reports the real output size.
|
|
25
|
+
*/
|
|
26
|
+
readonly onUnsupported?: 'throw' | 'ignore';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates the passthrough engine.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // Validate and store originals, no codec required.
|
|
34
|
+
* const optimizer = new ImageOptimizer({
|
|
35
|
+
* engine: createPassthroughEngine(),
|
|
36
|
+
* adapter: new LocalAdapter({ root: './uploads' }),
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function createPassthroughEngine(options?: PassthroughEngineOptions): ImageEngine;
|
|
41
|
+
//# sourceMappingURL=passthrough.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../../src/engines/passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAgB,WAAW,EAA2C,MAAM,eAAe,CAAC;AAExG,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACvC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B,GAAG,WAAW,CA4C3F"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A codec-free {@link ImageEngine}.
|
|
4
|
+
*
|
|
5
|
+
* It cannot resize or transcode - it has no decoder. What it *can* do is read
|
|
6
|
+
* dimensions from the header and hand the original bytes back unchanged, which
|
|
7
|
+
* covers three real cases:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Tests.** Deterministic, instant, no native binary in CI.
|
|
10
|
+
* 2. **Store-only pipelines.** Validate, content-hash, key and upload an image
|
|
11
|
+
* without re-encoding it.
|
|
12
|
+
* 3. **Graceful degradation.** When sharp is missing, the optimizer can still
|
|
13
|
+
* store the original rather than failing the whole request - the user's
|
|
14
|
+
* upload survives, just unoptimised.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.createPassthroughEngine = createPassthroughEngine;
|
|
18
|
+
const errors_js_1 = require("./../errors.js");
|
|
19
|
+
const sniff_js_1 = require("./../sniff.js");
|
|
20
|
+
/**
|
|
21
|
+
* Creates the passthrough engine.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* // Validate and store originals, no codec required.
|
|
26
|
+
* const optimizer = new ImageOptimizer({
|
|
27
|
+
* engine: createPassthroughEngine(),
|
|
28
|
+
* adapter: new LocalAdapter({ root: './uploads' }),
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function createPassthroughEngine(options = {}) {
|
|
33
|
+
const { onUnsupported = 'throw' } = options;
|
|
34
|
+
return {
|
|
35
|
+
name: 'passthrough',
|
|
36
|
+
supports() {
|
|
37
|
+
// It can "produce" any format only in the sense of not changing it. The
|
|
38
|
+
// optimizer relies on transform() to reject genuine conversions.
|
|
39
|
+
return true;
|
|
40
|
+
},
|
|
41
|
+
async probe(input) {
|
|
42
|
+
return (0, sniff_js_1.sniff)(input);
|
|
43
|
+
},
|
|
44
|
+
async transform(input, op) {
|
|
45
|
+
const meta = (0, sniff_js_1.sniff)(input);
|
|
46
|
+
const sameFormat = meta.format === op.format;
|
|
47
|
+
const needsResize = op.resize !== undefined &&
|
|
48
|
+
((op.resize.width !== undefined && op.resize.width !== meta.width) ||
|
|
49
|
+
(op.resize.height !== undefined && op.resize.height !== meta.height));
|
|
50
|
+
if ((!sameFormat || needsResize) && onUnsupported === 'throw') {
|
|
51
|
+
throw new errors_js_1.LensError('ENCODE_FAILED', `The passthrough engine cannot ${!sameFormat ? `convert ${meta.format} to ${op.format}` : 'resize images'}. ` +
|
|
52
|
+
'Install sharp (`npm install sharp`) to enable real image processing.', { details: { engine: 'passthrough', format: op.format, detected: meta.format } });
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
// Copy so a caller mutating the result cannot corrupt the source buffer
|
|
56
|
+
// that other variants in the same run are still reading from.
|
|
57
|
+
data: input.slice(),
|
|
58
|
+
format: (sameFormat ? op.format : meta.format) ?? op.format,
|
|
59
|
+
width: meta.width,
|
|
60
|
+
height: meta.height,
|
|
61
|
+
size: input.byteLength,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=passthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough.js","sourceRoot":"","sources":["../../../src/engines/passthrough.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AA+BH,0DA4CC;AAzED,8CAA2C;AAC3C,4CAAsC;AAgBtC;;;;;;;;;;;GAWG;AACH,SAAgB,uBAAuB,CAAC,UAAoC,EAAE;IAC5E,MAAM,EAAE,aAAa,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,aAAa;QAEnB,QAAQ;YACN,wEAAwE;YACxE,iEAAiE;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,KAAiB;YAC3B,OAAO,IAAA,gBAAK,EAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,KAAiB,EAAE,EAAe;YAChD,MAAM,IAAI,GAAG,IAAA,gBAAK,EAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,KAAM,EAAE,CAAC,MAAiB,CAAC;YACzD,MAAM,WAAW,GACf,EAAE,CAAC,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;oBAChE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAE1E,IAAI,CAAC,CAAC,UAAU,IAAI,WAAW,CAAC,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;gBAC9D,MAAM,IAAI,qBAAS,CACjB,eAAe,EACf,iCAAiC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI;oBAC3G,sEAAsE,EACxE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CACjF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,wEAAwE;gBACxE,8DAA8D;gBAC9D,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE;gBACnB,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAE,IAAI,CAAC,MAAsB,CAAC,IAAI,EAAE,CAAC,MAAM;gBAC5E,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,KAAK,CAAC,UAAU;aACvB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sharp-backed {@link ImageEngine}.
|
|
3
|
+
*
|
|
4
|
+
* ### Why this is not a dependency
|
|
5
|
+
*
|
|
6
|
+
* `@lens-image/core` declares sharp as an *optional peer*. Nothing in this file is
|
|
7
|
+
* evaluated until you actually call the engine, and the import is dynamic, so
|
|
8
|
+
* `npm install @lens-image/core` pulls in zero packages and installs zero native
|
|
9
|
+
* binaries. If you never resize an image - you only validate and re-key, say -
|
|
10
|
+
* you never need sharp at all.
|
|
11
|
+
*
|
|
12
|
+
* The moment you do need it, you run `npm install sharp` yourself, which means
|
|
13
|
+
* the native binary, its platform matrix and its release cadence are all
|
|
14
|
+
* visible in *your* lockfile rather than smuggled in under ours.
|
|
15
|
+
*/
|
|
16
|
+
import type { ImageEngine } from './../types.js';
|
|
17
|
+
/** Options for {@link createSharpEngine}. */
|
|
18
|
+
export interface SharpEngineOptions {
|
|
19
|
+
/**
|
|
20
|
+
* libvips operation cache. Defaults to `false`.
|
|
21
|
+
*
|
|
22
|
+
* sharp caches decoded operations globally, which is a memory leak shaped
|
|
23
|
+
* like a performance feature in a long-lived server that processes unbounded
|
|
24
|
+
* user uploads. Turn it on only if you re-process the same images repeatedly.
|
|
25
|
+
*/
|
|
26
|
+
readonly cache?: false | {
|
|
27
|
+
memory?: number;
|
|
28
|
+
files?: number;
|
|
29
|
+
items?: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* libvips worker threads per operation. Defaults to sharp's own choice.
|
|
33
|
+
*
|
|
34
|
+
* Set this to 1 when you are already running several optimize jobs in
|
|
35
|
+
* parallel: `concurrency: 4` in Lens plus 4 libvips threads each is 16
|
|
36
|
+
* threads fighting over the same cores.
|
|
37
|
+
*/
|
|
38
|
+
readonly threads?: number;
|
|
39
|
+
/** Pixel limit handed to sharp's own decoder guard. Default 100 megapixels. */
|
|
40
|
+
readonly pixelLimit?: number;
|
|
41
|
+
/** Pull every frame of an animated GIF/WebP through the pipeline. Default `false`. */
|
|
42
|
+
readonly animated?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates an {@link ImageEngine} backed by sharp.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const optimizer = new ImageOptimizer({
|
|
50
|
+
* engine: createSharpEngine({ threads: 1 }), // we do our own parallelism
|
|
51
|
+
* adapter,
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function createSharpEngine(options?: SharpEngineOptions): ImageEngine;
|
|
56
|
+
/** Test seam: forget the memoised sharp module. */
|
|
57
|
+
export declare function resetSharpCache(): void;
|
|
58
|
+
//# sourceMappingURL=sharp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../../src/engines/sharp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAgB,WAAW,EAA2C,MAAM,eAAe,CAAC;AAoExG,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7E;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAuG/E;AAkDD,mDAAmD;AACnD,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|