@openzim/libzim 3.4.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 +1 -1
- package/Changelog +12 -0
- package/README.md +36 -0
- package/binding.gyp +22 -1
- package/bundle-libzim.js +13 -5
- package/dist/index.d.ts +43 -8
- package/dist/index.js +5 -0
- package/download-libzim.js +1 -2
- package/package.json +25 -22
- package/src/archive.h +110 -91
- package/src/blob.h +31 -18
- package/src/common.h +2 -6
- package/src/contentProvider.h +134 -52
- package/src/creator.h +81 -23
- package/src/entry.h +0 -1
- package/src/illustration.h +167 -0
- package/src/index.d.ts +43 -8
- package/src/index.js +5 -0
- package/src/item.h +5 -5
- package/src/module.cc +26 -0
- package/src/openconfig.h +83 -0
- package/src/search.h +1 -14
- package/src/suggestion.h +0 -10
- package/src/writerItem.h +180 -92
- package/src/entryrange.h +0 -106
package/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
LIBZIM_VERSION=9.
|
|
1
|
+
LIBZIM_VERSION=9.4.0
|
package/Changelog
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
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
|
+
|
|
8
|
+
3.5.0
|
|
9
|
+
* NEW: Build now supports ARM64 (`aarch64`) and ARM (32‑bit)
|
|
10
|
+
* UPDATE: CI matrix extended with ARM64 Ubuntu runners
|
|
11
|
+
* UPDATE: drop Node.JS 18, add Node.JS 24
|
|
12
|
+
|
|
1
13
|
3.4.0
|
|
2
14
|
* NEW: Add new libzim 9.3.0 APIs around cache management
|
|
3
15
|
|
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
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
"link_settings": {
|
|
12
12
|
"ldflags": [
|
|
13
13
|
"<!(pkg-config --libs-only-other --libs-only-L libzim)",
|
|
14
|
+
"-Wl,-rpath,<!(pkg-config --variable=libdir libzim)>"
|
|
14
15
|
],
|
|
15
16
|
"libraries": [
|
|
16
17
|
"<!(pkg-config --libs-only-l libzim)",
|
|
17
18
|
],
|
|
18
19
|
},
|
|
19
20
|
}],
|
|
20
|
-
["libzim_local!='true' and OS=='linux'", {
|
|
21
|
+
["libzim_local!='true' and OS=='linux' and target_arch=='x64'", {
|
|
21
22
|
"include_dirs": [
|
|
22
23
|
"<(libzim_include)",
|
|
23
24
|
],
|
|
@@ -27,6 +28,26 @@
|
|
|
27
28
|
"<(libzim_dir)/lib/x86_64-linux-gnu/libzim.so.9",
|
|
28
29
|
],
|
|
29
30
|
}],
|
|
31
|
+
["libzim_local!='true' and OS=='linux' and target_arch=='arm64'", {
|
|
32
|
+
"include_dirs": [
|
|
33
|
+
"<(libzim_include)",
|
|
34
|
+
],
|
|
35
|
+
"libraries": [
|
|
36
|
+
"-Wl,-rpath,'$$ORIGIN'",
|
|
37
|
+
"-L<(libzim_dir)/lib/aarch64-rpi3-linux-gnu",
|
|
38
|
+
"<(libzim_dir)/lib/aarch64-rpi3-linux-gnu/libzim.so.9",
|
|
39
|
+
],
|
|
40
|
+
}],
|
|
41
|
+
["libzim_local!='true' and OS=='linux' and target_arch=='arm'", {
|
|
42
|
+
"include_dirs": [
|
|
43
|
+
"<(libzim_include)",
|
|
44
|
+
],
|
|
45
|
+
"libraries": [
|
|
46
|
+
"-Wl,-rpath,'$$ORIGIN'",
|
|
47
|
+
"-L<(libzim_dir)/lib/arm-linux-gnueabihf",
|
|
48
|
+
"<(libzim_dir)/lib/arm-linux-gnueabihf/libzim.so.9",
|
|
49
|
+
],
|
|
50
|
+
}],
|
|
30
51
|
["libzim_local!='true' and OS=='mac'", {
|
|
31
52
|
"include_dirs": ["<(libzim_include)"],
|
|
32
53
|
"cflags+": ["-fvisibility=hidden"],
|
package/bundle-libzim.js
CHANGED
|
@@ -16,11 +16,19 @@ if (!isMacOS && !isLinux) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (isLinux) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
const rawArch = os.arch();
|
|
20
|
+
let libDir;
|
|
21
|
+
if (rawArch === "arm64") {
|
|
22
|
+
libDir = "aarch64-rpi3-linux-gnu";
|
|
23
|
+
} else if (rawArch === "arm") {
|
|
24
|
+
libDir = "arm-linux-gnueabihf";
|
|
25
|
+
} else {
|
|
26
|
+
libDir = "x86_64-linux-gnu";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.info(`Copying libzim.so.9 from ${libDir} to build folder`);
|
|
30
|
+
exec(`cp download/lib/${libDir}/libzim.so.9 build/Release/libzim.so.9`);
|
|
31
|
+
exec("ln -sf build/Release/libzim.so.9 build/Release/libzim.so"); // convenience only, not required
|
|
24
32
|
}
|
|
25
33
|
if (isMacOS) {
|
|
26
34
|
console.info("Copying libzim.9.dylib to build folder");
|
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(
|
|
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(
|
|
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");
|
package/download-libzim.js
CHANGED
|
@@ -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 =
|
|
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": "
|
|
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": "
|
|
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"
|
|
@@ -38,36 +38,39 @@
|
|
|
38
38
|
"bugs": {
|
|
39
39
|
"url": "https://github.com/openzim/node-libzim/issues"
|
|
40
40
|
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20 <25"
|
|
43
|
+
},
|
|
41
44
|
"homepage": "https://github.com/openzim/node-libzim#readme",
|
|
42
45
|
"gypfile": true,
|
|
43
46
|
"dependencies": {
|
|
44
|
-
"@types/bindings": "^1.5.
|
|
45
|
-
"@types/jest": "^
|
|
46
|
-
"@types/node": "^
|
|
47
|
-
"axios": "^1.
|
|
47
|
+
"@types/bindings": "^1.5.5",
|
|
48
|
+
"@types/jest": "^30.0.0",
|
|
49
|
+
"@types/node": "^24.9.2",
|
|
50
|
+
"axios": "^1.13.1",
|
|
48
51
|
"bindings": "^1.5.0",
|
|
49
|
-
"dotenv": "^
|
|
52
|
+
"dotenv": "^17.2.3",
|
|
50
53
|
"exec-then": "^1.3.1",
|
|
51
54
|
"mkdirp": "^3.0.1",
|
|
52
|
-
"node-addon-api": "^8.
|
|
53
|
-
"node-gyp": "^
|
|
55
|
+
"node-addon-api": "^8.5.0",
|
|
56
|
+
"node-gyp": "^11.5.0",
|
|
54
57
|
"tqdm": "^2.0.3",
|
|
55
|
-
"ts-node": "^10.9.
|
|
56
|
-
"tsconfig-paths": "^4.
|
|
58
|
+
"ts-node": "^10.9.2",
|
|
59
|
+
"tsconfig-paths": "^4.2.0"
|
|
57
60
|
},
|
|
58
61
|
"devDependencies": {
|
|
59
|
-
"@faker-js/faker": "^
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
61
|
-
"@typescript-eslint/parser": "^5.
|
|
62
|
+
"@faker-js/faker": "^10.1.0",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
64
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
62
65
|
"eslint": "^8.57.0",
|
|
63
|
-
"eslint-config-prettier": "^8.10.
|
|
64
|
-
"eslint-plugin-prettier": "^5.
|
|
65
|
-
"nyc": "^17.
|
|
66
|
-
"prettier": "^3.
|
|
67
|
-
"ts-jest": "^29.
|
|
68
|
-
"typescript": "^5.
|
|
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"
|
|
69
72
|
},
|
|
70
73
|
"jest": {
|
|
71
74
|
"preset": "ts-jest/presets/js-with-ts"
|
|
72
75
|
}
|
|
73
|
-
}
|
|
76
|
+
}
|
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(
|
|
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::
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
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(
|
|
157
|
+
return Item::New(env, archive_->getIllustrationItem(size));
|
|
132
158
|
}
|
|
133
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
240
|
+
return Entry::New(env, archive_->getEntryByPath(path));
|
|
165
241
|
}
|
|
166
242
|
|
|
167
243
|
throw Napi::Error::New(
|
|
168
|
-
|
|
244
|
+
env, "Entry index must be a string (path) or number (index).");
|
|
169
245
|
} catch (const std::exception &err) {
|
|
170
|
-
throw Napi::Error::New(
|
|
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(
|
|
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::
|
|
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"),
|