@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/src/writerItem.h
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
#include <exception>
|
|
8
8
|
#include <functional>
|
|
9
9
|
#include <future>
|
|
10
|
+
#include <iostream>
|
|
10
11
|
#include <memory>
|
|
11
12
|
#include <optional>
|
|
12
13
|
#include <string>
|
|
13
14
|
#include <string_view>
|
|
14
15
|
#include <thread>
|
|
16
|
+
#include <utility>
|
|
15
17
|
|
|
16
18
|
#include "blob.h"
|
|
17
19
|
#include "common.h"
|
|
@@ -89,18 +91,156 @@ class IndexDataWrapper : public zim::writer::IndexData {
|
|
|
89
91
|
std::optional<GeoPosition> position_;
|
|
90
92
|
};
|
|
91
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Wraps a the getIndexData JS function to a ThreadSafeFunction
|
|
96
|
+
*/
|
|
97
|
+
class GetIndexDataTSFN {
|
|
98
|
+
public:
|
|
99
|
+
using IndexDataWrapperPtr = std::shared_ptr<IndexDataWrapper>;
|
|
100
|
+
|
|
101
|
+
GetIndexDataTSFN() = delete;
|
|
102
|
+
|
|
103
|
+
GetIndexDataTSFN(Napi::Env &env, Napi::Function &indexDataFunc) {
|
|
104
|
+
tsfn_ =
|
|
105
|
+
TSFN::New(env,
|
|
106
|
+
indexDataFunc, // JavaScript function called asynchronously
|
|
107
|
+
"GetIndexDataTSFN", // name
|
|
108
|
+
0, // max queue size (0 = unlimited).
|
|
109
|
+
1, // initial thread count
|
|
110
|
+
nullptr); // context
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
~GetIndexDataTSFN() { tsfn_.Release(); }
|
|
114
|
+
|
|
115
|
+
IndexDataWrapperPtr getIndexData() {
|
|
116
|
+
try {
|
|
117
|
+
DataType promise;
|
|
118
|
+
auto future = promise.get_future();
|
|
119
|
+
tsfn_.NonBlockingCall(&promise);
|
|
120
|
+
return future.get();
|
|
121
|
+
} catch (const std::exception &e) {
|
|
122
|
+
std::cerr << "GetIndexDataTSFN getIndexData() exception: " << e.what()
|
|
123
|
+
<< std::endl;
|
|
124
|
+
throw std::runtime_error(
|
|
125
|
+
std::string("Error in GetIndexDataTSFN getIndexData(): ") + e.what());
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private:
|
|
130
|
+
using DataType = std::promise<IndexDataWrapperPtr>;
|
|
131
|
+
using Context = void;
|
|
132
|
+
|
|
133
|
+
static void CallJs(Napi::Env env, Napi::Function callback, Context *context,
|
|
134
|
+
DataType *data) {
|
|
135
|
+
// Is the JavaScript environment still available to call into, eg. the TSFN
|
|
136
|
+
// is not aborted
|
|
137
|
+
if (env != nullptr) {
|
|
138
|
+
try {
|
|
139
|
+
// call getIndexData(): object
|
|
140
|
+
auto result = callback.Call({});
|
|
141
|
+
if (result.IsObject()) {
|
|
142
|
+
auto indexData =
|
|
143
|
+
std::make_shared<IndexDataWrapper>(result.As<Napi::Object>());
|
|
144
|
+
data->set_value(indexData);
|
|
145
|
+
} else {
|
|
146
|
+
data->set_exception(std::make_exception_ptr(
|
|
147
|
+
std::runtime_error("Expected an object from getIndexData")));
|
|
148
|
+
}
|
|
149
|
+
} catch (const std::exception &e) {
|
|
150
|
+
data->set_exception(std::make_exception_ptr(e));
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
data->set_exception(std::make_exception_ptr(
|
|
154
|
+
std::runtime_error("Environment is shut down")));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
using TSFN = Napi::TypedThreadSafeFunction<Context, DataType, CallJs>;
|
|
159
|
+
|
|
160
|
+
private:
|
|
161
|
+
TSFN tsfn_;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Wraps a the getContentProvider JS function to a ThreadSafeFunction
|
|
166
|
+
*/
|
|
167
|
+
class GetContentProviderTSFN {
|
|
168
|
+
public:
|
|
169
|
+
using ContentProviderWrapperPtr = std::unique_ptr<ContentProviderWrapper>;
|
|
170
|
+
|
|
171
|
+
GetContentProviderTSFN() = delete;
|
|
172
|
+
|
|
173
|
+
GetContentProviderTSFN(Napi::Env &env, Napi::Function &providerFunc) {
|
|
174
|
+
tsfn_ =
|
|
175
|
+
TSFN::New(env,
|
|
176
|
+
providerFunc, // JavaScript function called asynchronously
|
|
177
|
+
"GetContentProviderTSFN", // name
|
|
178
|
+
0, // max queue size (0 = unlimited).
|
|
179
|
+
1, // initial thread count
|
|
180
|
+
nullptr); // context
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
~GetContentProviderTSFN() { tsfn_.Release(); }
|
|
184
|
+
|
|
185
|
+
ContentProviderWrapperPtr getContentProvider() {
|
|
186
|
+
try {
|
|
187
|
+
DataType promise;
|
|
188
|
+
auto future = promise.get_future();
|
|
189
|
+
tsfn_.NonBlockingCall(&promise);
|
|
190
|
+
return future.get();
|
|
191
|
+
} catch (const std::exception &e) {
|
|
192
|
+
std::cerr << "GetContentProviderTSFN getContentProvider() exception: "
|
|
193
|
+
<< e.what() << std::endl;
|
|
194
|
+
throw std::runtime_error(
|
|
195
|
+
std::string(
|
|
196
|
+
"Error in GetContentProviderTSFN getContentProvider(): ") +
|
|
197
|
+
e.what());
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private:
|
|
202
|
+
using DataType = std::promise<ContentProviderWrapperPtr>;
|
|
203
|
+
using Context = void;
|
|
204
|
+
|
|
205
|
+
static void CallJs(Napi::Env env, Napi::Function callback, Context *context,
|
|
206
|
+
DataType *data) {
|
|
207
|
+
// Is the JavaScript environment still available to call into, eg. the
|
|
208
|
+
// TSFN is not aborted
|
|
209
|
+
if (env != nullptr) {
|
|
210
|
+
try {
|
|
211
|
+
// call getContentProvider(): object
|
|
212
|
+
auto result = callback.Call({});
|
|
213
|
+
if (result.IsObject()) {
|
|
214
|
+
auto provider = std::make_unique<ContentProviderWrapper>(
|
|
215
|
+
env, result.As<Napi::Object>());
|
|
216
|
+
data->set_value(std::move(provider));
|
|
217
|
+
} else {
|
|
218
|
+
data->set_exception(std::make_exception_ptr(std::runtime_error(
|
|
219
|
+
"Expected an object from getContentProvider")));
|
|
220
|
+
}
|
|
221
|
+
} catch (const std::exception &e) {
|
|
222
|
+
data->set_exception(std::make_exception_ptr(e));
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
data->set_exception(std::make_exception_ptr(
|
|
226
|
+
std::runtime_error("Environment is shut down")));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
using TSFN = Napi::TypedThreadSafeFunction<Context, DataType, CallJs>;
|
|
231
|
+
|
|
232
|
+
private:
|
|
233
|
+
TSFN tsfn_;
|
|
234
|
+
};
|
|
235
|
+
|
|
92
236
|
/**
|
|
93
237
|
* Wraps a JS World Item to a zim::writer::Item
|
|
94
238
|
*
|
|
95
|
-
* NOTE:
|
|
239
|
+
* NOTE: MUST BE initialized on the main thread
|
|
96
240
|
*/
|
|
97
241
|
class ItemWrapper : public zim::writer::Item {
|
|
98
242
|
public:
|
|
99
|
-
ItemWrapper(Napi::Env env, Napi::Object item)
|
|
100
|
-
: MAIN_THREAD_ID{}, item_{}, hasIndexDataImpl_{false} {
|
|
101
|
-
MAIN_THREAD_ID = std::this_thread::get_id();
|
|
102
|
-
item_ = Napi::Persistent(item);
|
|
103
|
-
|
|
243
|
+
ItemWrapper(Napi::Env env, Napi::Object item) {
|
|
104
244
|
path_ = item.Get("path").ToString();
|
|
105
245
|
title_ = item.Get("title").ToString();
|
|
106
246
|
mimeType_ = item.Get("mimeType").ToString();
|
|
@@ -118,9 +258,8 @@ class ItemWrapper : public zim::writer::Item {
|
|
|
118
258
|
}
|
|
119
259
|
|
|
120
260
|
auto indexDataFunc = indexDataFuncValue.As<Napi::Function>();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
env, indexDataFunc, "ItemWrapper.indexData", 0, 1);
|
|
261
|
+
getIndexDataTSFN_ =
|
|
262
|
+
std::make_unique<GetIndexDataTSFN>(env, indexDataFunc);
|
|
124
263
|
}
|
|
125
264
|
|
|
126
265
|
auto providerFuncValue = item.Get("getContentProvider");
|
|
@@ -128,16 +267,8 @@ class ItemWrapper : public zim::writer::Item {
|
|
|
128
267
|
throw std::runtime_error("getContentProvider must be a function");
|
|
129
268
|
}
|
|
130
269
|
auto providerFunc = providerFuncValue.As<Napi::Function>();
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
env, providerFunc, "ItemWrapper.contentProvider", 5, 1);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
~ItemWrapper() {
|
|
137
|
-
if (hasIndexDataImpl_) {
|
|
138
|
-
indexDataTSNF_.Release();
|
|
139
|
-
}
|
|
140
|
-
contentProviderTSNF_.Release();
|
|
270
|
+
getContentProviderTSFN_ =
|
|
271
|
+
std::make_unique<GetContentProviderTSFN>(env, providerFunc);
|
|
141
272
|
}
|
|
142
273
|
|
|
143
274
|
std::string getPath() const override { return path_; }
|
|
@@ -154,31 +285,11 @@ class ItemWrapper : public zim::writer::Item {
|
|
|
154
285
|
return zim::writer::Item::getIndexData();
|
|
155
286
|
}
|
|
156
287
|
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
return data.IsObject()
|
|
160
|
-
? std::make_shared<IndexDataWrapper>(data.ToObject())
|
|
161
|
-
: nullptr;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// called from a thread
|
|
165
|
-
using IndexDataWrapperPtr = std::shared_ptr<IndexDataWrapper>;
|
|
166
|
-
std::promise<IndexDataWrapperPtr> promise;
|
|
167
|
-
auto future = promise.get_future();
|
|
168
|
-
|
|
169
|
-
auto callback = [&promise, this](Napi::Env env, Napi::Function idxFunc) {
|
|
170
|
-
auto data = idxFunc.Call(item_.Value(), {});
|
|
171
|
-
promise.set_value(
|
|
172
|
-
data.IsObject() ? std::make_shared<IndexDataWrapper>(data.ToObject())
|
|
173
|
-
: nullptr);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
auto status = indexDataTSNF_.BlockingCall(callback);
|
|
177
|
-
if (status != napi_ok) {
|
|
178
|
-
throw std::runtime_error("Error calling indexData ThreadSafeFunction");
|
|
288
|
+
if (getIndexDataTSFN_ == nullptr) {
|
|
289
|
+
throw std::runtime_error("Error: getIndexDataTSFN_ is null");
|
|
179
290
|
}
|
|
180
291
|
|
|
181
|
-
return
|
|
292
|
+
return getIndexDataTSFN_->getIndexData();
|
|
182
293
|
}
|
|
183
294
|
|
|
184
295
|
/**
|
|
@@ -187,65 +298,23 @@ class ItemWrapper : public zim::writer::Item {
|
|
|
187
298
|
*/
|
|
188
299
|
std::unique_ptr<zim::writer::ContentProvider> getContentProvider()
|
|
189
300
|
const override {
|
|
190
|
-
|
|
191
|
-
auto env = contentProviderFunc_.Env();
|
|
192
|
-
auto provider = contentProviderFunc_.Call(item_.Value(), {});
|
|
193
|
-
if (provider.IsObject()) {
|
|
194
|
-
return std::make_unique<ContentProviderWrapper>(env,
|
|
195
|
-
provider.ToObject());
|
|
196
|
-
} else if (provider.IsNull() || provider.IsUndefined()) {
|
|
197
|
-
return nullptr;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
throw std::runtime_error(
|
|
201
|
-
"getContentProvider must return an object or null");
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
using ContentProviderWrapperPtr = std::unique_ptr<ContentProviderWrapper>;
|
|
205
|
-
std::promise<ContentProviderWrapperPtr> promise;
|
|
206
|
-
auto future = promise.get_future();
|
|
207
|
-
|
|
208
|
-
auto callback = [&promise, this](Napi::Env env,
|
|
209
|
-
Napi::Function providerFunc) {
|
|
210
|
-
auto provider = providerFunc.Call(item_.Value(), {});
|
|
211
|
-
if (provider.IsObject()) {
|
|
212
|
-
auto ptr =
|
|
213
|
-
std::make_unique<ContentProviderWrapper>(env, provider.ToObject());
|
|
214
|
-
promise.set_value(std::move(ptr));
|
|
215
|
-
} else if (provider.IsNull() || provider.IsUndefined()) {
|
|
216
|
-
promise.set_value(nullptr);
|
|
217
|
-
} else {
|
|
218
|
-
throw std::runtime_error(
|
|
219
|
-
"getContentProvider must return an object or null");
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
auto status = contentProviderTSNF_.BlockingCall(callback);
|
|
224
|
-
if (status != napi_ok) {
|
|
225
|
-
throw std::runtime_error(
|
|
226
|
-
"Error calling contentProvider ThreadSafeFunction");
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return future.get();
|
|
301
|
+
return getContentProviderTSFN_->getContentProvider();
|
|
230
302
|
}
|
|
231
303
|
|
|
232
304
|
private:
|
|
233
|
-
std::thread::id MAIN_THREAD_ID;
|
|
234
|
-
// js world reference, could be an ObjectWrap provider or custom js object
|
|
235
|
-
Napi::ObjectReference item_;
|
|
236
|
-
|
|
237
305
|
std::string path_;
|
|
238
306
|
std::string title_;
|
|
239
307
|
std::string mimeType_;
|
|
240
308
|
zim::writer::Hints hints_;
|
|
241
309
|
bool hasIndexDataImpl_;
|
|
242
310
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
Napi::FunctionReference contentProviderFunc_;
|
|
246
|
-
Napi::ThreadSafeFunction contentProviderTSNF_;
|
|
311
|
+
std::unique_ptr<GetContentProviderTSFN> getContentProviderTSFN_;
|
|
312
|
+
std::unique_ptr<GetIndexDataTSFN> getIndexDataTSFN_;
|
|
247
313
|
};
|
|
248
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Wraps a zim::writer::StringItem
|
|
317
|
+
*/
|
|
249
318
|
class StringItem : public Napi::ObjectWrap<StringItem> {
|
|
250
319
|
public:
|
|
251
320
|
explicit StringItem(const Napi::CallbackInfo &info)
|
|
@@ -340,9 +409,17 @@ class StringItem : public Napi::ObjectWrap<StringItem> {
|
|
|
340
409
|
|
|
341
410
|
// TODO(kelvinhammond): implement getIndexData for StringItem and FileItem
|
|
342
411
|
|
|
412
|
+
static bool InstanceOf(Napi::Env env, Napi::Object obj) {
|
|
413
|
+
Napi::FunctionReference &constructor = GetConstructor(env);
|
|
414
|
+
return obj.InstanceOf(constructor.Value());
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
static Napi::FunctionReference &GetConstructor(Napi::Env env) {
|
|
418
|
+
return env.GetInstanceData<ModuleConstructors>()->stringItem;
|
|
419
|
+
}
|
|
420
|
+
|
|
343
421
|
static void Init(Napi::Env env, Napi::Object exports,
|
|
344
422
|
ModuleConstructors &constructors) {
|
|
345
|
-
Napi::HandleScope scope(env);
|
|
346
423
|
Napi::Function func =
|
|
347
424
|
DefineClass(env, "StringItem",
|
|
348
425
|
{
|
|
@@ -362,6 +439,9 @@ class StringItem : public Napi::ObjectWrap<StringItem> {
|
|
|
362
439
|
std::shared_ptr<zim::writer::StringItem> item_;
|
|
363
440
|
};
|
|
364
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Wraps a zim::writer::FileItem
|
|
444
|
+
*/
|
|
365
445
|
class FileItem : public Napi::ObjectWrap<FileItem> {
|
|
366
446
|
public:
|
|
367
447
|
explicit FileItem(const Napi::CallbackInfo &info)
|
|
@@ -439,9 +519,17 @@ class FileItem : public Napi::ObjectWrap<FileItem> {
|
|
|
439
519
|
}
|
|
440
520
|
}
|
|
441
521
|
|
|
522
|
+
static bool InstanceOf(Napi::Env env, Napi::Object obj) {
|
|
523
|
+
Napi::FunctionReference &constructor = GetConstructor(env);
|
|
524
|
+
return obj.InstanceOf(constructor.Value());
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
static Napi::FunctionReference &GetConstructor(Napi::Env env) {
|
|
528
|
+
return env.GetInstanceData<ModuleConstructors>()->fileItem;
|
|
529
|
+
}
|
|
530
|
+
|
|
442
531
|
static void Init(Napi::Env env, Napi::Object exports,
|
|
443
532
|
ModuleConstructors &constructors) {
|
|
444
|
-
Napi::HandleScope scope(env);
|
|
445
533
|
Napi::Function func = DefineClass(
|
|
446
534
|
env, "FileItem",
|
|
447
535
|
{
|
package/src/entryrange.h
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <napi.h>
|
|
4
|
-
#include <zim/entry.h>
|
|
5
|
-
#include <exception>
|
|
6
|
-
#include <memory>
|
|
7
|
-
|
|
8
|
-
#include "entry.h"
|
|
9
|
-
|
|
10
|
-
class EntryRange : public Napi::ObjectWrap<EntryRange> {
|
|
11
|
-
public:
|
|
12
|
-
static constexpr const char *ENTRY_RANGE_CONSTRUCTOR_NAME = "EntryRange";
|
|
13
|
-
|
|
14
|
-
explicit EntryRange(const Napi::CallbackInfo &info)
|
|
15
|
-
: Napi::ObjectWrap<EntryRange>(info) {
|
|
16
|
-
auto env = info.Env();
|
|
17
|
-
|
|
18
|
-
if (!info[0].IsExternal()) {
|
|
19
|
-
throw Napi::Error::New(
|
|
20
|
-
env, "EntryRange must be constructed internally by another class.");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (info[0].IsExternal()) {
|
|
24
|
-
try {
|
|
25
|
-
entry_ = std::make_shared<zim::Entry>(
|
|
26
|
-
*info[0].As<Napi::External<zim::Entry>>().Data());
|
|
27
|
-
} catch (const std::exception &err) {
|
|
28
|
-
throw Napi::Error::New(env, err.what());
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
template <typename RangeT>
|
|
34
|
-
static Napi::Object New(Napi::Env env, RangeT range) {
|
|
35
|
-
Napi::Function iterator = Napi::Function::New(
|
|
36
|
-
env, [range](const Napi::CallbackInfo &info) mutable -> Napi::Value {
|
|
37
|
-
Napi::Env env = info.Env();
|
|
38
|
-
Napi::Object iter = Napi::Object::New(env);
|
|
39
|
-
|
|
40
|
-
auto it = range.begin();
|
|
41
|
-
iter["next"] = Napi::Function::New(
|
|
42
|
-
env,
|
|
43
|
-
[range,
|
|
44
|
-
it](const Napi::CallbackInfo &info) mutable -> Napi::Value {
|
|
45
|
-
Napi::Env env = info.Env();
|
|
46
|
-
Napi::Object res = Napi::Object::New(env);
|
|
47
|
-
if (it != range.end()) {
|
|
48
|
-
res["done"] = false;
|
|
49
|
-
res["value"] = Entry::New(env, zim::Entry(*it));
|
|
50
|
-
it++;
|
|
51
|
-
} else {
|
|
52
|
-
res["done"] = true;
|
|
53
|
-
}
|
|
54
|
-
return res;
|
|
55
|
-
});
|
|
56
|
-
return iter;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
auto offset = Napi::Function::New(
|
|
60
|
-
env, [range](const Napi::CallbackInfo &info) -> Napi::Value {
|
|
61
|
-
if (info.Length() < 2) {
|
|
62
|
-
throw Napi::Error::New(
|
|
63
|
-
info.Env(), "start and maxResults are required for offset.");
|
|
64
|
-
}
|
|
65
|
-
if (!(info[0].IsNumber() && info[1].IsNumber())) {
|
|
66
|
-
throw Napi::Error::New(
|
|
67
|
-
info.Env(), "start and maxResults must be of type Number.");
|
|
68
|
-
}
|
|
69
|
-
auto start = info[0].ToNumber();
|
|
70
|
-
auto maxResults = info[1].ToNumber();
|
|
71
|
-
return NewEntryRange(info.Env(), range.offset(start, maxResults));
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
auto size = Napi::Value::From(env, range.size());
|
|
75
|
-
|
|
76
|
-
auto &constructor = env.GetInstanceData<ConstructorsMap>()->at(
|
|
77
|
-
ENTRY_RANGE_CONSTRUCTOR_NAME);
|
|
78
|
-
return constructor.New({iterator, size, offset});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
Napi::Value getSize(const Napi::CallbackInfo &info) {
|
|
82
|
-
try {
|
|
83
|
-
return Napi::Value::From(info.Env(), entry_->getIndex());
|
|
84
|
-
} catch (const std::exception &err) {
|
|
85
|
-
throw Napi::Error::New(info.Env(), err.what());
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
static void Init(Napi::Env env, Napi::Object exports,
|
|
90
|
-
ConstructorsMap &constructors) {
|
|
91
|
-
Napi::HandleScope scope(env);
|
|
92
|
-
Napi::Function func =
|
|
93
|
-
DefineClass(env, "EntryRange",
|
|
94
|
-
{
|
|
95
|
-
InstanceAccessor<&EntryRange::getSize>("size"),
|
|
96
|
-
InstanceMethod<&EntryRange::getItem>("getItem"),
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
exports.Set("EntryRange", func);
|
|
100
|
-
constructors.insert_or_assign(ENTRY_RANGE_CONSTRUCTOR_NAME,
|
|
101
|
-
Napi::Persistent(func));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private:
|
|
105
|
-
std::shared_ptr<zim::Entry> entry_;
|
|
106
|
-
};
|