@openzim/libzim 3.5.0 → 4.0.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/.env CHANGED
@@ -1 +1 @@
1
- LIBZIM_VERSION=9.3.0
1
+ LIBZIM_VERSION=9.4.0
package/Changelog CHANGED
@@ -1,3 +1,10 @@
1
+ 4.0.0
2
+ * NEW: Use libzim 9.4.0
3
+ * FIX: Segmentation Fault issues
4
+ * FIX: Ensure addItem operation is thread-safe / protected by a mutex
5
+ * NEW: Use new Illustration APIs
6
+ * FIX: Add prebuilt libzim for Linux aarch64
7
+
1
8
  3.5.0
2
9
  * NEW: Build now supports ARM64 (`aarch64`) and ARM (32‑bit)
3
10
  * UPDATE: CI matrix extended with ARM64 Ubuntu runners
package/README.md CHANGED
@@ -96,8 +96,44 @@ import { Archive, SuggestionSearcher, Searcher } from "@openzim/libzim";
96
96
  delete archive;
97
97
  })();
98
98
 
99
+ ## Local Development
100
+
101
+ ### Important Files
102
+ `.env` - Set environment variables for local development. Only LIBZIM_VERSION for now
103
+ `bindings.gyp` - Node-gyp build configuration file
104
+ `src/` - Source code for the Node.js bindings
105
+ `test/` - Test cases
106
+
107
+ ### Setup
108
+
109
+ ```bash
110
+ git clone git@github.com:openzim/node-libzim.git
111
+ cd node-libzim
112
+
113
+ # Will install dependencies, download libzim binary and build the bindings
114
+ npm run install
115
+
116
+ # Required in order for local binding and tests to work.
117
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/download/lib/x86_64-linux-gnu
118
+ ```
119
+
120
+ ### Iterating during development
121
+
122
+ Make your changes in `src/` and then run:
123
+ ```bash
124
+ node-gyp rebuild --debug -v && npx jest ./test/zim.test.ts
99
125
  ```
100
126
 
127
+ ### Updating libzim version
128
+ To update the libzim version used, change the `LIBZIM_VERSION` variable in
129
+ `.env` file to the desired version and run:
130
+ ```bash
131
+ npm run install
132
+ ```
133
+
134
+ If you are upgrading libzim from a major version you will need to edit the `bundle-libzim.js` file
135
+ and change the `libzim.so*` file names to match the new version.
136
+
101
137
  ## License
102
138
 
103
139
  [GPLv3](https://www.gnu.org/licenses/gpl-3.0) or later, see
package/binding.gyp CHANGED
@@ -34,8 +34,8 @@
34
34
  ],
35
35
  "libraries": [
36
36
  "-Wl,-rpath,'$$ORIGIN'",
37
- "-L<(libzim_dir)/lib/aarch64-linux-gnu",
38
- "<(libzim_dir)/lib/aarch64-linux-gnu/libzim.so.9",
37
+ "-L<(libzim_dir)/lib/aarch64-rpi3-linux-gnu",
38
+ "<(libzim_dir)/lib/aarch64-rpi3-linux-gnu/libzim.so.9",
39
39
  ],
40
40
  }],
41
41
  ["libzim_local!='true' and OS=='linux' and target_arch=='arm'", {
package/bundle-libzim.js CHANGED
@@ -19,7 +19,7 @@ if (isLinux) {
19
19
  const rawArch = os.arch();
20
20
  let libDir;
21
21
  if (rawArch === "arm64") {
22
- libDir = "aarch64-linux-gnu";
22
+ libDir = "aarch64-rpi3-linux-gnu";
23
23
  } else if (rawArch === "arm") {
24
24
  libDir = "arm-linux-gnueabihf";
25
25
  } else {
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ export declare function getClusterCacheMaxSize(): number;
2
+ export declare function getClusterCacheCurrentSize(): number;
3
+ export declare function setClusterCacheMaxSize(nbClusters: number): void;
4
+
1
5
  export class IntegrityCheck {
2
6
  static CHECKSUM: symbol;
3
7
  static DIRENT_PTRS: symbol;
@@ -104,7 +108,10 @@ export class Creator {
104
108
  content: string | ContentProvider,
105
109
  mimetype?: string,
106
110
  ): void;
107
- addIllustration(size: number, content: string | ContentProvider): void;
111
+ addIllustration(
112
+ sizeOrInfo: number | IIllustrationInfo,
113
+ content: string | ContentProvider,
114
+ ): void;
108
115
  addRedirection(
109
116
  path: string,
110
117
  title: string,
@@ -146,8 +153,35 @@ export interface EntryRange extends Iterable<Entry> {
146
153
  offset(start: number, maxResults: number): EntryRange;
147
154
  }
148
155
 
156
+ export interface IIllustrationInfo {
157
+ width?: number;
158
+ height?: number;
159
+ scale?: number;
160
+ extraAttributes?: Record<string, string>;
161
+ }
162
+
163
+ export class IllustrationInfo implements IIllustrationInfo {
164
+ constructor(info?: IIllustrationInfo | IllustrationInfo);
165
+ get width(): number;
166
+ get height(): number;
167
+ get scale(): number;
168
+ get extraAttributes(): Record<string, string>;
169
+ asMetadataItemName(): string;
170
+ static fromMetadataItemName(name: string): IllustrationInfo;
171
+ }
172
+
173
+ export class OpenConfig {
174
+ constructor();
175
+
176
+ preloadXapianDb(preload: boolean): this;
177
+ preloadDirentRanges(nbRanges: number): this;
178
+
179
+ get m_preloadXapianDb(): boolean;
180
+ get m_preloadDirentRanges(): number;
181
+ }
182
+
149
183
  export class Archive {
150
- constructor(filepath: string);
184
+ constructor(filepath: string, config?: OpenConfig);
151
185
  get filename(): string;
152
186
  get filesize(): number | bigint;
153
187
  get allEntryCount(): number;
@@ -158,8 +192,14 @@ export class Archive {
158
192
  getMetadata(name: string): string;
159
193
  getMetadataItem(name: string): Item;
160
194
  get metadataKeys(): string[];
161
- getIllustrationItem(size: number): Item;
195
+ getIllustrationItem(sizeOrInfo?: number | IIllustrationInfo): Item;
162
196
  get illustrationSizes(): Set<number>;
197
+ getIllustrationInfos(
198
+ width?: number,
199
+ height?: number,
200
+ minScale?: number,
201
+ ): IllustrationInfo[];
202
+ get illustrationInfos(): IllustrationInfo[];
163
203
  getEntryByPath(path_or_idx: string | number): Entry;
164
204
  getEntryByTitle(title_or_idx: string | number): Entry;
165
205
  getEntryByClusterOrder(idx: number): Entry;
@@ -182,14 +222,9 @@ export class Archive {
182
222
  checkIntegrity(checkType: symbol): boolean; // one of IntegrityCheck
183
223
  get isMultiPart(): boolean;
184
224
  get hasNewNamespaceScheme(): boolean;
185
- getClusterCacheMaxSize(): number;
186
- getClusterCacheCurrentSize(): number;
187
- setClusterCacheMaxSize(nbClusters: number): void;
188
225
  getDirentCacheMaxSize(): number;
189
226
  getDirentCacheCurrentSize(): number;
190
227
  setDirentCacheMaxSize(nbDirents: number): void;
191
- getDirentLookupCacheMaxSize(): number;
192
- setDirentLookupCacheMaxSize(nbRanges: number): void;
193
228
 
194
229
  static validate(zimPath: string, checksToRun: symbol[]): boolean; // list of IntegrityCheck
195
230
  }
package/dist/index.js CHANGED
@@ -2,9 +2,11 @@ import bindings from "bindings";
2
2
 
3
3
  export const {
4
4
  Archive,
5
+ OpenConfig,
5
6
  Entry,
6
7
  IntegrityCheck,
7
8
  Compression,
9
+ IllustrationInfo,
8
10
  Blob,
9
11
  Searcher,
10
12
  Query,
@@ -14,4 +16,7 @@ export const {
14
16
  FileProvider,
15
17
  StringItem,
16
18
  FileItem,
19
+ getClusterCacheMaxSize,
20
+ getClusterCacheCurrentSize,
21
+ setClusterCacheMaxSize,
17
22
  } = bindings("zim_binding");
@@ -5,7 +5,6 @@ import { mkdirp } from "mkdirp";
5
5
  import exec from "exec-then";
6
6
  import os from "os";
7
7
  import fs from "fs";
8
- import urlParser from "url";
9
8
 
10
9
  mkdirp.sync("./download");
11
10
 
@@ -46,7 +45,7 @@ const urls = [
46
45
 
47
46
  for (let url of urls) {
48
47
  console.info(`Downloading Libzim from: `, url);
49
- const filename = urlParser.parse(url).pathname.split("/").slice(-1)[0];
48
+ const filename = new URL(url).pathname.split("/").slice(-1)[0];
50
49
  const dlFile = `./download/${filename}`;
51
50
 
52
51
  try {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@openzim/libzim",
3
3
  "main": "dist/index.js",
4
4
  "types": "dist/index.d.js",
5
- "version": "3.5.0",
5
+ "version": "4.0.0",
6
6
  "description": "Libzim bindings for NodeJS",
7
7
  "type": "module",
8
8
  "scripts": {
@@ -14,8 +14,8 @@
14
14
  "build": "node-gyp rebuild -v && npm run bundle",
15
15
  "download": "node ./download-libzim.js",
16
16
  "bundle": "node ./bundle-libzim.js",
17
- "test": "jest --testPathIgnorePatterns=test/dist.test.ts",
18
- "test-mem-leak": "node -r ts-node/register test/makeLargeZim.ts",
17
+ "test": "jest --testPathIgnorePatterns=test/dist.test.ts --testPathIgnorePatterns=dist/",
18
+ "test-mem-leak": "npx tsx test/makeLargeZim.ts",
19
19
  "test:dist": "npm run build && jest",
20
20
  "lint": "npx eslint .",
21
21
  "lint:fix": "npx eslint . --fix"
@@ -44,31 +44,31 @@
44
44
  "homepage": "https://github.com/openzim/node-libzim#readme",
45
45
  "gypfile": true,
46
46
  "dependencies": {
47
- "@types/bindings": "^1.5.1",
48
- "@types/jest": "^29.5.12",
49
- "@types/node": "^18.0.6",
50
- "axios": "^1.6.0",
47
+ "@types/bindings": "^1.5.5",
48
+ "@types/jest": "^30.0.0",
49
+ "@types/node": "^24.9.2",
50
+ "axios": "^1.13.1",
51
51
  "bindings": "^1.5.0",
52
- "dotenv": "^16.0.1",
52
+ "dotenv": "^17.2.3",
53
53
  "exec-then": "^1.3.1",
54
54
  "mkdirp": "^3.0.1",
55
- "node-addon-api": "^8.0.0",
56
- "node-gyp": "^10.1.0",
55
+ "node-addon-api": "^8.5.0",
56
+ "node-gyp": "^11.5.0",
57
57
  "tqdm": "^2.0.3",
58
- "ts-node": "^10.9.1",
59
- "tsconfig-paths": "^4.0.0"
58
+ "ts-node": "^10.9.2",
59
+ "tsconfig-paths": "^4.2.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@faker-js/faker": "^8.4.1",
63
- "@typescript-eslint/eslint-plugin": "^5.59.2",
64
- "@typescript-eslint/parser": "^5.59.2",
62
+ "@faker-js/faker": "^10.1.0",
63
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
64
+ "@typescript-eslint/parser": "^5.62.0",
65
65
  "eslint": "^8.57.0",
66
- "eslint-config-prettier": "^8.10.0",
67
- "eslint-plugin-prettier": "^5.1.3",
68
- "nyc": "^17.0.0",
69
- "prettier": "^3.3.2",
70
- "ts-jest": "^29.1.5",
71
- "typescript": "^5.1.6"
66
+ "eslint-config-prettier": "^8.10.2",
67
+ "eslint-plugin-prettier": "^5.5.4",
68
+ "nyc": "^17.1.0",
69
+ "prettier": "^3.6.2",
70
+ "ts-jest": "^29.4.5",
71
+ "typescript": "^5.9.3"
72
72
  },
73
73
  "jest": {
74
74
  "preset": "ts-jest/presets/js-with-ts"
package/src/archive.h CHANGED
@@ -3,27 +3,52 @@
3
3
  #include <napi.h>
4
4
  #include <zim/archive.h>
5
5
  #include <exception>
6
+ #include <iostream>
7
+ #include <map>
6
8
  #include <memory>
7
- #include <sstream>
8
9
  #include <string>
9
10
 
10
11
  #include "entry.h"
12
+ #include "illustration.h"
11
13
  #include "item.h"
14
+ #include "openconfig.h"
12
15
 
13
16
  class Archive : public Napi::ObjectWrap<Archive> {
14
17
  public:
15
18
  explicit Archive(const Napi::CallbackInfo &info)
16
19
  : Napi::ObjectWrap<Archive>(info), archive_{nullptr} {
17
20
  Napi::Env env = info.Env();
18
- Napi::HandleScope scope(env);
19
21
 
20
22
  if (info.Length() < 1) {
21
- throw Napi::Error::New(info.Env(), "Archive requires arguments filepath");
23
+ throw Napi::Error::New(env, "Archive requires arguments filepath");
24
+ }
25
+
26
+ if (!info[0].IsString()) {
27
+ throw Napi::TypeError::New(env,
28
+ "First argument must be a string filepath.");
29
+ }
30
+
31
+ // Archive(filename: string)
32
+ // Archive(filepath: string, config: OpenConfig)
33
+ std::string filepath = info[0].As<Napi::String>();
34
+ zim::OpenConfig config{};
35
+ if (info[1].IsObject()) {
36
+ // @note: no bounds checking on info because it returns Undefined when out
37
+ // of bounds
38
+ auto obj = info[1].As<Napi::Object>();
39
+ // Check that the object is an instance of OpenConfig
40
+ // TODO(kelvinhammond): Update use of Unwrap everywhere to use
41
+ // InstanceOf and GetConstructor pattern
42
+ if (OpenConfig::InstanceOf(env, obj)) {
43
+ config = OpenConfig::Unwrap(obj)->getInternalConfig();
44
+ } else {
45
+ throw Napi::TypeError::New(
46
+ env, "Second argument must be an instance of OpenConfig.");
47
+ }
22
48
  }
23
49
 
24
50
  try {
25
- std::string filepath = info[0].ToString();
26
- archive_ = std::make_shared<zim::Archive>(filepath);
51
+ archive_ = std::make_shared<zim::Archive>(filepath, config);
27
52
  } catch (const std::exception &e) {
28
53
  throw Napi::Error::New(env, e.what());
29
54
  }
@@ -79,13 +104,8 @@ class Archive : public Napi::ObjectWrap<Archive> {
79
104
 
80
105
  Napi::Value getUuid(const Napi::CallbackInfo &info) {
81
106
  try {
82
- // TODO(kelvinhammond): convert this to
83
- // static_cast<std::string>(archive_->getUuid()) This didn't work when
84
- // building because of the below error undefined symbol:
85
- // _ZNK3zim4UuidcvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEv
86
- std::ostringstream out;
87
- out << archive_->getUuid();
88
- return Napi::Value::From(info.Env(), out.str());
107
+ return Napi::Value::From(info.Env(),
108
+ static_cast<std::string>(archive_->getUuid()));
89
109
  } catch (const std::exception &err) {
90
110
  throw Napi::Error::New(info.Env(), err.what());
91
111
  }
@@ -112,7 +132,6 @@ class Archive : public Napi::ObjectWrap<Archive> {
112
132
  Napi::Value getMetadataKeys(const Napi::CallbackInfo &info) {
113
133
  try {
114
134
  auto env = info.Env();
115
- Napi::HandleScope scope(env);
116
135
  auto res = Napi::Array::New(env);
117
136
  size_t idx = 0;
118
137
  for (const auto &key : archive_->getMetadataKeys()) {
@@ -125,22 +144,51 @@ class Archive : public Napi::ObjectWrap<Archive> {
125
144
  }
126
145
 
127
146
  Napi::Value getIllustrationItem(const Napi::CallbackInfo &info) {
147
+ auto env = info.Env();
128
148
  try {
129
- if (info.Length() > 0) {
149
+ // getIllustrationItem()
150
+ if (info.Length() < 1) {
151
+ return Item::New(env, archive_->getIllustrationItem());
152
+ }
153
+
154
+ // getIllustrationItem(size: number)
155
+ if (info[0].IsNumber()) {
130
156
  auto size = static_cast<unsigned int>(info[0].ToNumber().Uint32Value());
131
- return Item::New(info.Env(), archive_->getIllustrationItem(size));
157
+ return Item::New(env, archive_->getIllustrationItem(size));
132
158
  }
133
- return Item::New(info.Env(), archive_->getIllustrationItem());
159
+
160
+ /// getIllustration(illusInfo: object)
161
+ if (info[0].IsObject()) {
162
+ auto obj = info[0].As<Napi::Object>();
163
+
164
+ // getIllustrationItem(illusInfo: IllustrationInfo)
165
+ if (IllustrationInfo::InstanceOf(env, obj)) {
166
+ auto illusInfo =
167
+ IllustrationInfo::Unwrap(obj)->getInternalIllustrationInfo();
168
+ return Item::New(env, archive_->getIllustrationItem(illusInfo));
169
+ }
170
+
171
+ // getIllustrationItem(illusInfo: object)
172
+ auto illusInfo = IllustrationInfo::infoFrom(obj);
173
+ return Item::New(env, archive_->getIllustrationItem(illusInfo));
174
+ }
175
+
176
+ throw Napi::TypeError::New(
177
+ env,
178
+ "getIllustrationItem expects no arguments, a number size, or an "
179
+ "IllustrationInfo object.");
134
180
  } catch (const std::exception &err) {
135
- throw Napi::Error::New(info.Env(), err.what());
181
+ throw Napi::Error::New(env, err.what());
136
182
  }
137
183
  }
138
184
 
139
185
  Napi::Value getIllustrationSizes(const Napi::CallbackInfo &info) {
186
+ // Warn: Deprecated, use illustrationSizes property instead.
187
+ std::cerr << "Warning: getIllustrationSizes() is deprecated, use "
188
+ "illustrationSizes property instead."
189
+ << std::endl;
190
+ auto env = info.Env();
140
191
  try {
141
- auto env = info.Env();
142
- Napi::HandleScope scope(env);
143
-
144
192
  // returns a native Set object
145
193
  auto SetConstructor = env.Global().Get("Set").As<Napi::Function>();
146
194
  auto result = SetConstructor.New({});
@@ -150,24 +198,52 @@ class Archive : public Napi::ObjectWrap<Archive> {
150
198
  }
151
199
  return result;
152
200
  } catch (const std::exception &err) {
153
- throw Napi::Error::New(info.Env(), err.what());
201
+ throw Napi::Error::New(env, err.what());
154
202
  }
155
203
  }
156
204
 
205
+ Napi::Value getIllustrationInfos(const Napi::CallbackInfo &info) {
206
+ auto env = info.Env();
207
+
208
+ // getIllustrationInfos(w: number, h: number, minScale: number)
209
+ if (info.Length() >= 3) {
210
+ auto w = info[0].ToNumber().Uint32Value();
211
+ auto h = info[1].ToNumber().Uint32Value();
212
+ auto minScale = info[2].ToNumber().FloatValue();
213
+
214
+ auto infos = archive_->getIllustrationInfos(w, h, minScale);
215
+ auto array = Napi::Array::New(env, infos.size());
216
+ for (size_t i = 0; i < infos.size(); i++) {
217
+ array.Set(i, IllustrationInfo::New(env, infos[i]));
218
+ }
219
+ return array;
220
+ }
221
+
222
+ // getIllustrationInfos()
223
+ auto infos = archive_->getIllustrationInfos();
224
+ auto array = Napi::Array::New(env, infos.size());
225
+ for (size_t i = 0; i < infos.size(); i++) {
226
+ array.Set(i, IllustrationInfo::New(env, infos[i]));
227
+ }
228
+
229
+ return array;
230
+ }
231
+
157
232
  Napi::Value getEntryByPath(const Napi::CallbackInfo &info) {
233
+ auto env = info.Env();
158
234
  try {
159
235
  if (info[0].IsNumber()) {
160
236
  auto &&idx = info[0].ToNumber();
161
- return Entry::New(info.Env(), archive_->getEntryByPath(idx));
237
+ return Entry::New(env, archive_->getEntryByPath(idx));
162
238
  } else if (info[0].IsString()) {
163
239
  auto &&path = info[0].ToString();
164
- return Entry::New(info.Env(), archive_->getEntryByPath(path));
240
+ return Entry::New(env, archive_->getEntryByPath(path));
165
241
  }
166
242
 
167
243
  throw Napi::Error::New(
168
- info.Env(), "Entry index must be a string (path) or number (index).");
244
+ env, "Entry index must be a string (path) or number (index).");
169
245
  } catch (const std::exception &err) {
170
- throw Napi::Error::New(info.Env(), err.what());
246
+ throw Napi::Error::New(env, err.what());
171
247
  }
172
248
  }
173
249
 
@@ -386,12 +462,12 @@ class Archive : public Napi::ObjectWrap<Archive> {
386
462
  }
387
463
 
388
464
  Napi::Value checkIntegrity(const Napi::CallbackInfo &info) {
465
+ auto env = info.Env();
389
466
  try {
390
- auto env = info.Env();
391
467
  const auto &&checkType = IntegrityCheck::symbolToEnum(env, info[0]);
392
468
  return Napi::Value::From(env, archive_->checkIntegrity(checkType));
393
469
  } catch (const std::exception &err) {
394
- throw Napi::Error::New(info.Env(), err.what());
470
+ throw Napi::Error::New(env, err.what());
395
471
  }
396
472
  }
397
473
 
@@ -411,35 +487,6 @@ class Archive : public Napi::ObjectWrap<Archive> {
411
487
  }
412
488
  }
413
489
 
414
- Napi::Value getClusterCacheMaxSize(const Napi::CallbackInfo &info) {
415
- try {
416
- return Napi::Value::From(info.Env(), archive_->getClusterCacheMaxSize());
417
- } catch (const std::exception &err) {
418
- throw Napi::Error::New(info.Env(), err.what());
419
- }
420
- }
421
-
422
- Napi::Value getClusterCacheCurrentSize(const Napi::CallbackInfo &info) {
423
- try {
424
- return Napi::Value::From(info.Env(),
425
- archive_->getClusterCacheCurrentSize());
426
- } catch (const std::exception &err) {
427
- throw Napi::Error::New(info.Env(), err.what());
428
- }
429
- }
430
-
431
- void setClusterCacheMaxSize(const Napi::CallbackInfo &info) {
432
- try {
433
- if (!info[0].IsNumber()) {
434
- throw Napi::Error::New(info.Env(), "Expected a number");
435
- }
436
- auto nbClusters = info[0].As<Napi::Number>().Uint32Value();
437
- archive_->setClusterCacheMaxSize(nbClusters);
438
- } catch (const std::exception &err) {
439
- throw Napi::Error::New(info.Env(), err.what());
440
- }
441
- }
442
-
443
490
  Napi::Value getDirentCacheMaxSize(const Napi::CallbackInfo &info) {
444
491
  try {
445
492
  return Napi::Value::From(info.Env(), archive_->getDirentCacheMaxSize());
@@ -459,8 +506,9 @@ class Archive : public Napi::ObjectWrap<Archive> {
459
506
 
460
507
  void setDirentCacheMaxSize(const Napi::CallbackInfo &info) {
461
508
  try {
462
- if (!info[0].IsNumber()) {
463
- throw Napi::Error::New(info.Env(), "Expected a number");
509
+ if (info.Length() < 1 || !info[0].IsNumber()) {
510
+ throw Napi::TypeError::New(info.Env(),
511
+ "setDirentCacheMaxSize expects a number");
464
512
  }
465
513
  auto nbDirents = info[0].As<Napi::Number>().Uint32Value();
466
514
  archive_->setDirentCacheMaxSize(nbDirents);
@@ -469,30 +517,8 @@ class Archive : public Napi::ObjectWrap<Archive> {
469
517
  }
470
518
  }
471
519
 
472
- Napi::Value getDirentLookupCacheMaxSize(const Napi::CallbackInfo &info) {
473
- try {
474
- return Napi::Value::From(info.Env(),
475
- archive_->getDirentLookupCacheMaxSize());
476
- } catch (const std::exception &err) {
477
- throw Napi::Error::New(info.Env(), err.what());
478
- }
479
- }
480
-
481
- void setDirentLookupCacheMaxSize(const Napi::CallbackInfo &info) {
482
- try {
483
- if (!info[0].IsNumber()) {
484
- throw Napi::Error::New(info.Env(), "Expected a number");
485
- }
486
- auto nbRanges = info[0].As<Napi::Number>().Uint32Value();
487
- archive_->setDirentLookupCacheMaxSize(nbRanges);
488
- } catch (const std::exception &err) {
489
- throw Napi::Error::New(info.Env(), err.what());
490
- }
491
- }
492
-
493
520
  static Napi::Value validate(const Napi::CallbackInfo &info) {
494
521
  Napi::Env env = info.Env();
495
- Napi::HandleScope scope(env);
496
522
  try {
497
523
  if (info.Length() < 2) {
498
524
  throw Napi::Error::New(
@@ -524,7 +550,6 @@ class Archive : public Napi::ObjectWrap<Archive> {
524
550
 
525
551
  static void Init(Napi::Env env, Napi::Object exports,
526
552
  ModuleConstructors &constructors) {
527
- Napi::HandleScope scope(env);
528
553
  Napi::Function func = DefineClass(
529
554
  env, "Archive",
530
555
  {
@@ -542,6 +567,10 @@ class Archive : public Napi::ObjectWrap<Archive> {
542
567
  "getIllustrationItem"),
543
568
  InstanceAccessor<&Archive::getIllustrationSizes>(
544
569
  "illustrationSizes"),
570
+ InstanceMethod<&Archive::getIllustrationInfos>(
571
+ "getIllustrationInfos"),
572
+ InstanceAccessor<&Archive::getIllustrationInfos>(
573
+ "illustrationInfos"),
545
574
  InstanceMethod<&Archive::getEntryByPath>("getEntryByPath"),
546
575
  InstanceMethod<&Archive::getEntryByTitle>("getEntryByTitle"),
547
576
  InstanceMethod<&Archive::getEntryByClusterOrder>(
@@ -564,22 +593,12 @@ class Archive : public Napi::ObjectWrap<Archive> {
564
593
  InstanceAccessor<&Archive::getChecksum>("checksum"),
565
594
  InstanceMethod<&Archive::check>("check"),
566
595
  InstanceMethod<&Archive::checkIntegrity>("checkIntegrity"),
567
- InstanceMethod<&Archive::getClusterCacheMaxSize>(
568
- "getClusterCacheMaxSize"),
569
- InstanceMethod<&Archive::getClusterCacheCurrentSize>(
570
- "getClusterCacheCurrentSize"),
571
- InstanceMethod<&Archive::setClusterCacheMaxSize>(
572
- "setClusterCacheMaxSize"),
573
596
  InstanceMethod<&Archive::getDirentCacheMaxSize>(
574
597
  "getDirentCacheMaxSize"),
575
598
  InstanceMethod<&Archive::getDirentCacheCurrentSize>(
576
599
  "getDirentCacheCurrentSize"),
577
600
  InstanceMethod<&Archive::setDirentCacheMaxSize>(
578
601
  "setDirentCacheMaxSize"),
579
- InstanceMethod<&Archive::getDirentLookupCacheMaxSize>(
580
- "getDirentLookupCacheMaxSize"),
581
- InstanceMethod<&Archive::setDirentLookupCacheMaxSize>(
582
- "setDirentLookupCacheMaxSize"),
583
602
  InstanceAccessor<&Archive::isMultiPart>("isMultiPart"),
584
603
  InstanceAccessor<&Archive::hasNewNamespaceScheme>(
585
604
  "hasNewNamespaceScheme"),