@gmod/trix 2.0.0 → 2.0.3
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/CHANGELOG.md +15 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +111 -177
- package/dist/index.js.map +1 -1
- package/esm/index.js +10 -9
- package/esm/index.js.map +1 -1
- package/package.json +6 -4
- package/src/index.ts +163 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# v2.0.3
|
|
2
|
+
|
|
3
|
+
- Better support adjustable prefix sizes by basing the prefix as the remainder
|
|
4
|
+
of the line length - hex address size
|
|
5
|
+
|
|
6
|
+
# v2.0.2
|
|
7
|
+
|
|
8
|
+
- Publish src directory for better source maps
|
|
9
|
+
|
|
10
|
+
# v2.0.1
|
|
11
|
+
|
|
12
|
+
- Redeploy to npm with preversion script added
|
|
13
|
+
|
|
14
|
+
# v2.0.0
|
|
15
|
+
|
|
1
16
|
- Fix issue with infinite loop
|
|
2
17
|
- Add abortsignal support
|
|
3
18
|
- Only query first word when string with multiple words is entered
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,7 @@ export default class Trix {
|
|
|
6
6
|
constructor(ixxFile: GenericFilehandle, ixFile: GenericFilehandle, maxResults?: number);
|
|
7
7
|
search(searchString: string, opts?: {
|
|
8
8
|
signal?: AbortSignal;
|
|
9
|
-
}): Promise<string
|
|
9
|
+
}): Promise<[string, string][]>;
|
|
10
10
|
private getIndex;
|
|
11
11
|
private _getBuffer;
|
|
12
|
-
private _parseIxx;
|
|
13
12
|
}
|
package/dist/index.js
CHANGED
|
@@ -46,47 +46,19 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
-
if (!m) return o;
|
|
52
|
-
var i = m.call(o), r, ar = [], e;
|
|
53
|
-
try {
|
|
54
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
-
}
|
|
56
|
-
catch (error) { e = { error: error }; }
|
|
57
|
-
finally {
|
|
58
|
-
try {
|
|
59
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
-
}
|
|
61
|
-
finally { if (e) throw e.error; }
|
|
62
|
-
}
|
|
63
|
-
return ar;
|
|
64
|
-
};
|
|
65
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
66
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
67
|
-
if (ar || !(i in from)) {
|
|
68
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
69
|
-
ar[i] = from[i];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
73
|
-
};
|
|
74
|
-
var __values = (this && this.__values) || function(o) {
|
|
75
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
76
|
-
if (m) return m.call(o);
|
|
77
|
-
if (o && typeof o.length === "number") return {
|
|
78
|
-
next: function () {
|
|
79
|
-
if (o && i >= o.length) o = void 0;
|
|
80
|
-
return { value: o && o[i++], done: !o };
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
84
|
-
};
|
|
85
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
|
|
50
|
+
var CHUNK_SIZE = 65536;
|
|
51
|
+
// this is the number of hex characters to use for the address in ixixx, see
|
|
52
|
+
// https://github.com/GMOD/ixixx-js/blob/master/src/index.ts#L182
|
|
53
|
+
var ADDRESS_SIZE = 10;
|
|
54
|
+
// https://stackoverflow.com/a/9229821/2129219
|
|
55
|
+
function uniqBy(a, key) {
|
|
56
|
+
var seen = new Set();
|
|
57
|
+
return a.filter(function (item) {
|
|
58
|
+
var k = key(item);
|
|
59
|
+
return seen.has(k) ? false : seen.add(k);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
90
62
|
var Trix = /** @class */ (function () {
|
|
91
63
|
function Trix(ixxFile, ixFile, maxResults) {
|
|
92
64
|
if (maxResults === void 0) { maxResults = 20; }
|
|
@@ -96,184 +68,146 @@ var Trix = /** @class */ (function () {
|
|
|
96
68
|
}
|
|
97
69
|
Trix.prototype.search = function (searchString, opts) {
|
|
98
70
|
return __awaiter(this, void 0, void 0, function () {
|
|
99
|
-
var resultArr, searchWords, _loop_1, this_1,
|
|
71
|
+
var resultArr, searchWords, searchWord, res, seekPosEnd, buffer, done, _loop_1, this_1, state_1;
|
|
100
72
|
return __generator(this, function (_a) {
|
|
101
73
|
switch (_a.label) {
|
|
102
74
|
case 0:
|
|
103
75
|
resultArr = [];
|
|
104
76
|
searchWords = searchString.split(' ');
|
|
105
|
-
|
|
106
|
-
|
|
77
|
+
searchWord = searchWords[0].toLowerCase();
|
|
78
|
+
return [4 /*yield*/, this._getBuffer(searchWord, opts)];
|
|
79
|
+
case 1:
|
|
80
|
+
res = _a.sent();
|
|
81
|
+
if (!res) {
|
|
82
|
+
return [2 /*return*/, []];
|
|
83
|
+
}
|
|
84
|
+
seekPosEnd = res.seekPosEnd, buffer = res.buffer;
|
|
85
|
+
done = false;
|
|
86
|
+
_loop_1 = function () {
|
|
87
|
+
var foundSomething, str, lines, hits, res2;
|
|
107
88
|
return __generator(this, function (_b) {
|
|
108
89
|
switch (_b.label) {
|
|
109
90
|
case 0:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
91
|
+
foundSomething = false;
|
|
92
|
+
str = buffer.toString();
|
|
93
|
+
lines = str
|
|
94
|
+
.slice(0, str.lastIndexOf('\n'))
|
|
95
|
+
.split('\n')
|
|
96
|
+
.filter(function (f) { return !!f; });
|
|
97
|
+
hits = lines
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
99
|
+
.filter(function (line) {
|
|
100
|
+
var word = line.split(' ')[0];
|
|
101
|
+
var match = word.startsWith(searchWord);
|
|
102
|
+
if (!foundSomething && match) {
|
|
103
|
+
foundSomething = true;
|
|
104
|
+
}
|
|
105
|
+
// we are done scanning if we are lexicographically greater than the
|
|
106
|
+
// search string
|
|
107
|
+
if (word > searchWord) {
|
|
108
|
+
done = true;
|
|
109
|
+
}
|
|
110
|
+
return match;
|
|
111
|
+
})
|
|
112
|
+
.map(function (line) {
|
|
113
|
+
var _a = line.split(' '), term = _a[0], parts = _a.slice(1);
|
|
114
|
+
return parts.map(function (elt) { return [term, elt.split(',')[0]]; });
|
|
115
|
+
})
|
|
116
|
+
.flat();
|
|
117
|
+
if (!(resultArr.length + hits.length < this_1.maxResults && !done)) return [3 /*break*/, 2];
|
|
118
|
+
return [4 /*yield*/, this_1.ixFile.read(Buffer.alloc(CHUNK_SIZE), 0, CHUNK_SIZE, seekPosEnd, opts)
|
|
119
|
+
// early break if empty response
|
|
120
|
+
];
|
|
113
121
|
case 1:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
str = buffer.toString();
|
|
124
|
-
lines = str
|
|
125
|
-
.slice(0, str.lastIndexOf('\n'))
|
|
126
|
-
.split('\n')
|
|
127
|
-
.filter(function (f) { return !!f; });
|
|
128
|
-
hits = lines
|
|
129
|
-
.filter(function (line) {
|
|
130
|
-
var word = line.split(' ')[0];
|
|
131
|
-
var match = word.startsWith(searchString);
|
|
132
|
-
if (!foundSomething && match) {
|
|
133
|
-
foundSomething = true;
|
|
134
|
-
}
|
|
135
|
-
else if (foundSomething && !match) {
|
|
136
|
-
done = true;
|
|
137
|
-
}
|
|
138
|
-
else if (word > searchString) {
|
|
139
|
-
done = true;
|
|
140
|
-
}
|
|
141
|
-
return match;
|
|
142
|
-
})
|
|
143
|
-
.map(function (line) {
|
|
144
|
-
var _a = __read(line.split(' ')), term = _a[0], parts = _a.slice(1);
|
|
145
|
-
return parts.map(function (elt) { return [term, elt.split(',')[0]]; });
|
|
146
|
-
})
|
|
147
|
-
.flat();
|
|
148
|
-
if (!hits.length) {
|
|
149
|
-
done = true;
|
|
150
|
-
}
|
|
151
|
-
if (prevLen === hits.length) {
|
|
152
|
-
done = true;
|
|
153
|
-
}
|
|
154
|
-
if (!(resultArr.length + hits.length < this_1.maxResults && !done)) return [3 /*break*/, 2];
|
|
155
|
-
return [4 /*yield*/, this_1.ixFile.read(Buffer.alloc(CHUNKSIZE), 0, CHUNKSIZE, seekPosEnd, opts)
|
|
156
|
-
//early break if empty response
|
|
157
|
-
];
|
|
158
|
-
case 1:
|
|
159
|
-
res_1 = _c.sent();
|
|
160
|
-
//early break if empty response
|
|
161
|
-
if (!res_1.bytesRead) {
|
|
162
|
-
resultArr = resultArr.concat(hits);
|
|
163
|
-
return [2 /*return*/, "break"];
|
|
164
|
-
}
|
|
165
|
-
buffer = Buffer.concat([buffer, res_1.buffer]);
|
|
166
|
-
seekPosEnd += CHUNKSIZE;
|
|
167
|
-
prevLen = hits.length;
|
|
168
|
-
return [3 /*break*/, 3];
|
|
169
|
-
case 2:
|
|
170
|
-
if (resultArr.length + hits.length >= this_1.maxResults || done) {
|
|
171
|
-
resultArr = resultArr.concat(hits);
|
|
172
|
-
return [2 /*return*/, "break"];
|
|
173
|
-
}
|
|
174
|
-
_c.label = 3;
|
|
175
|
-
case 3: return [2 /*return*/];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
};
|
|
179
|
-
_b.label = 2;
|
|
122
|
+
res2 = _b.sent();
|
|
123
|
+
// early break if empty response
|
|
124
|
+
if (!res2.bytesRead) {
|
|
125
|
+
resultArr = resultArr.concat(hits);
|
|
126
|
+
return [2 /*return*/, "break"];
|
|
127
|
+
}
|
|
128
|
+
buffer = Buffer.concat([buffer, res2.buffer]);
|
|
129
|
+
seekPosEnd += CHUNK_SIZE;
|
|
130
|
+
return [3 /*break*/, 3];
|
|
180
131
|
case 2:
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return [3 /*break*/, 2];
|
|
188
|
-
case 4: return [2 /*return*/];
|
|
132
|
+
if (resultArr.length + hits.length >= this_1.maxResults || done) {
|
|
133
|
+
resultArr = resultArr.concat(hits);
|
|
134
|
+
return [2 /*return*/, "break"];
|
|
135
|
+
}
|
|
136
|
+
_b.label = 3;
|
|
137
|
+
case 3: return [2 /*return*/];
|
|
189
138
|
}
|
|
190
139
|
});
|
|
191
140
|
};
|
|
192
141
|
this_1 = this;
|
|
193
|
-
|
|
194
|
-
_a.label = 1;
|
|
195
|
-
case 1:
|
|
196
|
-
if (!(w < searchWords.length)) return [3 /*break*/, 4];
|
|
197
|
-
return [5 /*yield**/, _loop_1(w)];
|
|
142
|
+
_a.label = 2;
|
|
198
143
|
case 2:
|
|
199
|
-
|
|
200
|
-
|
|
144
|
+
if (!!done) return [3 /*break*/, 4];
|
|
145
|
+
return [5 /*yield**/, _loop_1()];
|
|
201
146
|
case 3:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
147
|
+
state_1 = _a.sent();
|
|
148
|
+
if (state_1 === "break")
|
|
149
|
+
return [3 /*break*/, 4];
|
|
150
|
+
return [3 /*break*/, 2];
|
|
151
|
+
case 4:
|
|
152
|
+
// deduplicate results based on the detail column (resultArr[1])
|
|
153
|
+
return [2 /*return*/, uniqBy(resultArr, function (elt) { return elt[1]; }).slice(0, this.maxResults)];
|
|
205
154
|
}
|
|
206
155
|
});
|
|
207
156
|
});
|
|
208
157
|
};
|
|
209
158
|
Trix.prototype.getIndex = function (opts) {
|
|
210
|
-
return
|
|
159
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
160
|
+
var file;
|
|
161
|
+
return __generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
163
|
+
case 0: return [4 /*yield*/, this.ixxFile.readFile(__assign({ encoding: 'utf8' }, opts))];
|
|
164
|
+
case 1:
|
|
165
|
+
file = _a.sent();
|
|
166
|
+
return [2 /*return*/, file
|
|
167
|
+
.split('\n')
|
|
168
|
+
.filter(function (f) { return !!f; })
|
|
169
|
+
.map(function (line) {
|
|
170
|
+
var p = line.length - ADDRESS_SIZE;
|
|
171
|
+
var prefix = line.slice(0, p);
|
|
172
|
+
var posStr = line.slice(p);
|
|
173
|
+
var pos = Number.parseInt(posStr, 16);
|
|
174
|
+
return [prefix, pos];
|
|
175
|
+
})];
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
211
179
|
};
|
|
212
180
|
Trix.prototype._getBuffer = function (searchWord, opts) {
|
|
213
181
|
return __awaiter(this, void 0, void 0, function () {
|
|
214
|
-
var seekPosStart, seekPosEnd, indexes,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
switch (_c.label) {
|
|
182
|
+
var seekPosStart, seekPosEnd, indexes, len, res;
|
|
183
|
+
return __generator(this, function (_a) {
|
|
184
|
+
switch (_a.label) {
|
|
218
185
|
case 0:
|
|
219
186
|
seekPosStart = 0;
|
|
220
187
|
seekPosEnd = -1;
|
|
221
188
|
return [4 /*yield*/, this.getIndex(opts)];
|
|
222
189
|
case 1:
|
|
223
|
-
indexes =
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
seekPosStart = value;
|
|
233
|
-
seekPosEnd = value + 65536;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
238
|
-
finally {
|
|
239
|
-
try {
|
|
240
|
-
if (indexes_1_1 && !indexes_1_1.done && (_b = indexes_1.return)) _b.call(indexes_1);
|
|
190
|
+
indexes = _a.sent();
|
|
191
|
+
indexes.forEach(function (_a) {
|
|
192
|
+
var key = _a[0], value = _a[1];
|
|
193
|
+
var trimmedKey = key.slice(0, searchWord.length);
|
|
194
|
+
if (trimmedKey < searchWord) {
|
|
195
|
+
seekPosStart = value;
|
|
196
|
+
seekPosEnd = value + 65536;
|
|
241
197
|
}
|
|
242
|
-
|
|
243
|
-
}
|
|
198
|
+
});
|
|
244
199
|
len = seekPosEnd - seekPosStart;
|
|
245
200
|
if (len < 0) {
|
|
246
201
|
return [2 /*return*/, undefined];
|
|
247
202
|
}
|
|
248
203
|
return [4 /*yield*/, this.ixFile.read(Buffer.alloc(len), 0, len, seekPosStart, opts)];
|
|
249
204
|
case 2:
|
|
250
|
-
res =
|
|
205
|
+
res = _a.sent();
|
|
251
206
|
return [2 /*return*/, __assign(__assign({}, res), { seekPosEnd: seekPosEnd })];
|
|
252
207
|
}
|
|
253
208
|
});
|
|
254
209
|
});
|
|
255
210
|
};
|
|
256
|
-
Trix.prototype._parseIxx = function (ixxFile, opts) {
|
|
257
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
258
|
-
var file;
|
|
259
|
-
return __generator(this, function (_a) {
|
|
260
|
-
switch (_a.label) {
|
|
261
|
-
case 0: return [4 /*yield*/, ixxFile.readFile(__assign({ encoding: 'utf8' }, opts))];
|
|
262
|
-
case 1:
|
|
263
|
-
file = (_a.sent());
|
|
264
|
-
return [2 /*return*/, new Map(file
|
|
265
|
-
.split('\n')
|
|
266
|
-
.filter(function (f) { return !!f; })
|
|
267
|
-
.map(function (line) {
|
|
268
|
-
var prefix = line.slice(0, trixPrefixSize);
|
|
269
|
-
var posStr = line.slice(trixPrefixSize);
|
|
270
|
-
var pos = Number.parseInt(posStr, 16);
|
|
271
|
-
return [prefix, pos];
|
|
272
|
-
}))];
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
};
|
|
277
211
|
return Trix;
|
|
278
212
|
}());
|
|
279
213
|
exports.default = Trix;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/esm/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const TRIX_PREFIX_SIZE = 5;
|
|
4
1
|
const CHUNK_SIZE = 65536;
|
|
2
|
+
// this is the number of hex characters to use for the address in ixixx, see
|
|
3
|
+
// https://github.com/GMOD/ixixx-js/blob/master/src/index.ts#L182
|
|
4
|
+
const ADDRESS_SIZE = 10;
|
|
5
5
|
// https://stackoverflow.com/a/9229821/2129219
|
|
6
6
|
function uniqBy(a, key) {
|
|
7
|
-
|
|
7
|
+
const seen = new Set();
|
|
8
8
|
return a.filter(item => {
|
|
9
|
-
|
|
9
|
+
const k = key(item);
|
|
10
10
|
return seen.has(k) ? false : seen.add(k);
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
-
class Trix {
|
|
13
|
+
export default class Trix {
|
|
14
14
|
constructor(ixxFile, ixFile, maxResults = 20) {
|
|
15
15
|
this.ixFile = ixFile;
|
|
16
16
|
this.ixxFile = ixxFile;
|
|
@@ -88,8 +88,9 @@ class Trix {
|
|
|
88
88
|
.split('\n')
|
|
89
89
|
.filter(f => !!f)
|
|
90
90
|
.map(line => {
|
|
91
|
-
const
|
|
92
|
-
const
|
|
91
|
+
const p = line.length - ADDRESS_SIZE;
|
|
92
|
+
const prefix = line.slice(0, p);
|
|
93
|
+
const posStr = line.slice(p);
|
|
93
94
|
const pos = Number.parseInt(posStr, 16);
|
|
94
95
|
return [prefix, pos];
|
|
95
96
|
});
|
|
@@ -117,4 +118,4 @@ class Trix {
|
|
|
117
118
|
};
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
|
|
121
|
+
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.0.
|
|
2
|
+
"version": "2.0.3",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "esm/index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
8
|
-
"esm"
|
|
8
|
+
"esm",
|
|
9
|
+
"src"
|
|
9
10
|
],
|
|
10
11
|
"engines": {
|
|
11
12
|
"node": ">=10"
|
|
@@ -13,9 +14,10 @@
|
|
|
13
14
|
"scripts": {
|
|
14
15
|
"lint": "eslint --report-unused-disable-directives --max-warnings 0 --ext .js,.ts src ",
|
|
15
16
|
"prebuild": "rimraf dist esm",
|
|
16
|
-
"build:esm": "tsc --target es2018 --outDir esm",
|
|
17
|
-
"build:es5": "tsc --target es5 --outDir dist",
|
|
17
|
+
"build:esm": "tsc --target es2018 --outDir esm --module es2020",
|
|
18
|
+
"build:es5": "tsc --target es5 --outDir dist --module commonjs",
|
|
18
19
|
"build": "npm run build:esm && npm run build:es5",
|
|
20
|
+
"preversion": "npm run lint && npm test && npm run build",
|
|
19
21
|
"postversion": "git push --follow-tags",
|
|
20
22
|
"test": "jest"
|
|
21
23
|
},
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { GenericFilehandle } from 'generic-filehandle'
|
|
2
|
+
|
|
3
|
+
const CHUNK_SIZE = 65536
|
|
4
|
+
|
|
5
|
+
// this is the number of hex characters to use for the address in ixixx, see
|
|
6
|
+
// https://github.com/GMOD/ixixx-js/blob/master/src/index.ts#L182
|
|
7
|
+
const ADDRESS_SIZE = 10
|
|
8
|
+
|
|
9
|
+
// https://stackoverflow.com/a/9229821/2129219
|
|
10
|
+
function uniqBy(a: [string, string][], key: (elt: [string, string]) => string) {
|
|
11
|
+
const seen = new Set()
|
|
12
|
+
return a.filter(item => {
|
|
13
|
+
const k = key(item)
|
|
14
|
+
return seen.has(k) ? false : seen.add(k)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default class Trix {
|
|
19
|
+
private ixFile: GenericFilehandle
|
|
20
|
+
|
|
21
|
+
private ixxFile: GenericFilehandle
|
|
22
|
+
|
|
23
|
+
maxResults: number
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
ixxFile: GenericFilehandle,
|
|
27
|
+
ixFile: GenericFilehandle,
|
|
28
|
+
maxResults = 20,
|
|
29
|
+
) {
|
|
30
|
+
this.ixFile = ixFile
|
|
31
|
+
this.ixxFile = ixxFile
|
|
32
|
+
this.maxResults = maxResults
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async search(searchString: string, opts?: { signal?: AbortSignal }) {
|
|
36
|
+
let resultArr = [] as [string, string][]
|
|
37
|
+
const searchWords = searchString.split(' ')
|
|
38
|
+
|
|
39
|
+
// we only search one word at a time
|
|
40
|
+
const searchWord = searchWords[0].toLowerCase()
|
|
41
|
+
const res = await this._getBuffer(searchWord, opts)
|
|
42
|
+
if (!res) {
|
|
43
|
+
return []
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let { seekPosEnd, buffer } = res
|
|
47
|
+
let done = false
|
|
48
|
+
while (!done) {
|
|
49
|
+
let foundSomething = false
|
|
50
|
+
const str = buffer.toString()
|
|
51
|
+
|
|
52
|
+
// slice to lastIndexOf('\n') to make sure we get complete records
|
|
53
|
+
// since the buffer fetch could get halfway into a record
|
|
54
|
+
const lines = str
|
|
55
|
+
.slice(0, str.lastIndexOf('\n'))
|
|
56
|
+
.split('\n')
|
|
57
|
+
.filter(f => !!f)
|
|
58
|
+
|
|
59
|
+
const hits = lines
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
61
|
+
.filter(line => {
|
|
62
|
+
const word = line.split(' ')[0]
|
|
63
|
+
const match = word.startsWith(searchWord)
|
|
64
|
+
if (!foundSomething && match) {
|
|
65
|
+
foundSomething = true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// we are done scanning if we are lexicographically greater than the
|
|
69
|
+
// search string
|
|
70
|
+
if (word > searchWord) {
|
|
71
|
+
done = true
|
|
72
|
+
}
|
|
73
|
+
return match
|
|
74
|
+
})
|
|
75
|
+
.map(line => {
|
|
76
|
+
const [term, ...parts] = line.split(' ')
|
|
77
|
+
return parts.map(elt => [term, elt.split(',')[0]])
|
|
78
|
+
})
|
|
79
|
+
.flat() as [string, string][]
|
|
80
|
+
|
|
81
|
+
// if we are not done, and we haven't filled up maxResults with hits yet,
|
|
82
|
+
// then refetch
|
|
83
|
+
if (resultArr.length + hits.length < this.maxResults && !done) {
|
|
84
|
+
// eslint-disable-next-line no-await-in-loop
|
|
85
|
+
const res2 = await this.ixFile.read(
|
|
86
|
+
Buffer.alloc(CHUNK_SIZE),
|
|
87
|
+
0,
|
|
88
|
+
CHUNK_SIZE,
|
|
89
|
+
seekPosEnd,
|
|
90
|
+
opts,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
// early break if empty response
|
|
94
|
+
if (!res2.bytesRead) {
|
|
95
|
+
resultArr = resultArr.concat(hits)
|
|
96
|
+
break
|
|
97
|
+
}
|
|
98
|
+
buffer = Buffer.concat([buffer, res2.buffer])
|
|
99
|
+
seekPosEnd += CHUNK_SIZE
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// if we have filled up the hits, or we are detected to be done via the
|
|
103
|
+
// filtering, then return
|
|
104
|
+
else if (resultArr.length + hits.length >= this.maxResults || done) {
|
|
105
|
+
resultArr = resultArr.concat(hits)
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// deduplicate results based on the detail column (resultArr[1])
|
|
111
|
+
return uniqBy(resultArr, elt => elt[1]).slice(0, this.maxResults)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private async getIndex(opts?: { signal?: AbortSignal }) {
|
|
115
|
+
const file = await this.ixxFile.readFile({
|
|
116
|
+
encoding: 'utf8',
|
|
117
|
+
...opts,
|
|
118
|
+
})
|
|
119
|
+
return file
|
|
120
|
+
.split('\n')
|
|
121
|
+
.filter(f => !!f)
|
|
122
|
+
.map(line => {
|
|
123
|
+
const p = line.length - ADDRESS_SIZE
|
|
124
|
+
const prefix = line.slice(0, p)
|
|
125
|
+
const posStr = line.slice(p)
|
|
126
|
+
const pos = Number.parseInt(posStr, 16)
|
|
127
|
+
return [prefix, pos] as [string, number]
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private async _getBuffer(
|
|
132
|
+
searchWord: string,
|
|
133
|
+
opts?: { signal?: AbortSignal },
|
|
134
|
+
) {
|
|
135
|
+
let seekPosStart = 0
|
|
136
|
+
let seekPosEnd = -1
|
|
137
|
+
const indexes = await this.getIndex(opts)
|
|
138
|
+
indexes.forEach(([key, value]) => {
|
|
139
|
+
const trimmedKey = key.slice(0, searchWord.length)
|
|
140
|
+
if (trimmedKey < searchWord) {
|
|
141
|
+
seekPosStart = value
|
|
142
|
+
seekPosEnd = value + 65536
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// Return the buffer and its end position in the file.
|
|
147
|
+
const len = seekPosEnd - seekPosStart
|
|
148
|
+
if (len < 0) {
|
|
149
|
+
return undefined
|
|
150
|
+
}
|
|
151
|
+
const res = await this.ixFile.read(
|
|
152
|
+
Buffer.alloc(len),
|
|
153
|
+
0,
|
|
154
|
+
len,
|
|
155
|
+
seekPosStart,
|
|
156
|
+
opts,
|
|
157
|
+
)
|
|
158
|
+
return {
|
|
159
|
+
...res,
|
|
160
|
+
seekPosEnd,
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|