@scrabble-solver/dictionaries 2.8.2 → 2.8.4
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/build/Dictionaries.js +37 -110
- package/build/constants/index.js +2 -2
- package/build/index.js +1 -1
- package/build/lib/DiskCache.js +29 -91
- package/build/lib/LayeredCache.js +37 -101
- package/build/lib/MemoryCache.js +16 -17
- package/build/lib/createAsyncProxy.js +14 -58
- package/build/lib/createCacheTimestampComparator.js +4 -4
- package/build/lib/downloadDictionary.js +10 -54
- package/build/lib/getDictionaryFilepath.js +4 -4
- package/build/lib/index.d.ts +0 -2
- package/build/lib/index.js +1 -5
- package/package.json +6 -6
- package/src/lib/DiskCache.ts +2 -4
- package/src/lib/LayeredCache.ts +17 -8
- package/src/lib/index.ts +0 -2
- package/build/lib/readFile.d.ts +0 -2
- package/build/lib/readFile.js +0 -57
- package/build/lib/writeFile.d.ts +0 -2
- package/build/lib/writeFile.js +0 -57
- package/src/lib/readFile.ts +0 -15
- package/src/lib/writeFile.ts +0 -15
package/build/Dictionaries.js
CHANGED
|
@@ -1,119 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
4
|
};
|
|
41
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
6
|
+
const logger_1 = __importDefault(require("@scrabble-solver/logger"));
|
|
7
|
+
const types_1 = require("@scrabble-solver/types");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
const lib_1 = require("./lib");
|
|
11
|
+
class Dictionaries {
|
|
12
|
+
constructor() {
|
|
49
13
|
this.cache = new lib_1.LayeredCache();
|
|
50
|
-
this.downloadDictionaryProxies = Object.fromEntries(Object.values(types_1.Locale).map(
|
|
14
|
+
this.downloadDictionaryProxies = Object.fromEntries(Object.values(types_1.Locale).map((locale) => [locale, (0, lib_1.createAsyncProxy)(() => (0, lib_1.downloadDictionary)(locale))]));
|
|
15
|
+
}
|
|
16
|
+
async get(locale) {
|
|
17
|
+
if (this.cache.has(locale)) {
|
|
18
|
+
const trie = await this.cache.get(locale);
|
|
19
|
+
if (trie) {
|
|
20
|
+
return trie;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
logger_1.default.info('Dictionaries - cache miss', { locale });
|
|
24
|
+
return this.updateDictionary(locale);
|
|
51
25
|
}
|
|
52
|
-
|
|
53
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
54
|
-
var trie;
|
|
55
|
-
return __generator(this, function (_a) {
|
|
56
|
-
switch (_a.label) {
|
|
57
|
-
case 0:
|
|
58
|
-
if (!this.cache.has(locale)) return [3 /*break*/, 2];
|
|
59
|
-
return [4 /*yield*/, this.cache.get(locale)];
|
|
60
|
-
case 1:
|
|
61
|
-
trie = _a.sent();
|
|
62
|
-
if (trie) {
|
|
63
|
-
return [2 /*return*/, trie];
|
|
64
|
-
}
|
|
65
|
-
_a.label = 2;
|
|
66
|
-
case 2:
|
|
67
|
-
logger_1.default.info('Dictionaries - cache miss', { locale: locale });
|
|
68
|
-
return [2 /*return*/, this.updateDictionary(locale)];
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
Dictionaries.prototype.remove = function () {
|
|
26
|
+
remove() {
|
|
74
27
|
fs_1.default.rmdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Dictionaries.prototype.getLocalesToUpdate = function () {
|
|
94
|
-
var _this = this;
|
|
95
|
-
return Object.values(types_1.Locale).filter(function (locale) { return _this.cache.isStale(locale) !== false; });
|
|
96
|
-
};
|
|
97
|
-
Dictionaries.prototype.updateDictionary = function (locale) {
|
|
98
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
99
|
-
var downloadDictionaryProxy, trie;
|
|
100
|
-
return __generator(this, function (_a) {
|
|
101
|
-
switch (_a.label) {
|
|
102
|
-
case 0:
|
|
103
|
-
logger_1.default.info('Dictionaries - updateDictionary', { locale: locale });
|
|
104
|
-
fs_1.default.mkdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
|
|
105
|
-
downloadDictionaryProxy = this.downloadDictionaryProxies[locale];
|
|
106
|
-
return [4 /*yield*/, downloadDictionaryProxy()];
|
|
107
|
-
case 1:
|
|
108
|
-
trie = _a.sent();
|
|
109
|
-
return [4 /*yield*/, this.cache.set(locale, trie)];
|
|
110
|
-
case 2:
|
|
111
|
-
_a.sent();
|
|
112
|
-
return [2 /*return*/, trie];
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
return Dictionaries;
|
|
118
|
-
}());
|
|
28
|
+
}
|
|
29
|
+
async update(force) {
|
|
30
|
+
const locales = force ? Object.values(types_1.Locale) : this.getLocalesToUpdate();
|
|
31
|
+
logger_1.default.info('Dictionaries - update', { force, locales });
|
|
32
|
+
await Promise.all(locales.map((locale) => this.updateDictionary(locale)));
|
|
33
|
+
}
|
|
34
|
+
getLocalesToUpdate() {
|
|
35
|
+
return Object.values(types_1.Locale).filter((locale) => this.cache.isStale(locale) !== false);
|
|
36
|
+
}
|
|
37
|
+
async updateDictionary(locale) {
|
|
38
|
+
logger_1.default.info('Dictionaries - updateDictionary', { locale });
|
|
39
|
+
fs_1.default.mkdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
|
|
40
|
+
const downloadDictionaryProxy = this.downloadDictionaryProxies[locale];
|
|
41
|
+
const trie = await downloadDictionaryProxy();
|
|
42
|
+
await this.cache.set(locale, trie);
|
|
43
|
+
return trie;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
119
46
|
exports.default = Dictionaries;
|
package/build/constants/index.js
CHANGED
|
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.OUTPUT_DIRECTORY = exports.CACHE_STALE_THRESHOLD = exports.DAY = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const os_1 = __importDefault(require("os"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
9
|
exports.DAY = 24 * 60 * 60 * 1000;
|
|
10
10
|
exports.CACHE_STALE_THRESHOLD = 30 * exports.DAY;
|
|
11
11
|
exports.OUTPUT_DIRECTORY = path_1.default.resolve(os_1.default.homedir(), '.scrabble-solver', 'dictionaries');
|
package/build/index.js
CHANGED
|
@@ -18,6 +18,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
20
|
exports.dictionaries = void 0;
|
|
21
|
-
|
|
21
|
+
const Dictionaries_1 = __importDefault(require("./Dictionaries"));
|
|
22
22
|
__exportStar(require("./lib"), exports);
|
|
23
23
|
exports.dictionaries = new Dictionaries_1.default();
|
package/build/lib/DiskCache.js
CHANGED
|
@@ -1,110 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
4
|
};
|
|
41
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
6
|
+
const trie_1 = require("@kamilmielnik/trie");
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const getDictionaryFilepath_1 = __importDefault(require("./getDictionaryFilepath"));
|
|
10
|
+
class DiskCache {
|
|
11
|
+
async get(locale) {
|
|
12
|
+
if (!this.has(locale)) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
16
|
+
const serialized = await fs_1.default.promises.readFile(filepath, 'utf-8');
|
|
17
|
+
const trie = trie_1.Trie.deserialize(serialized);
|
|
18
|
+
return trie;
|
|
50
19
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
var filepath, serialized, trie;
|
|
54
|
-
return __generator(this, function (_a) {
|
|
55
|
-
switch (_a.label) {
|
|
56
|
-
case 0:
|
|
57
|
-
if (!this.has(locale)) {
|
|
58
|
-
return [2 /*return*/, undefined];
|
|
59
|
-
}
|
|
60
|
-
filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
61
|
-
return [4 /*yield*/, (0, readFile_1.default)(filepath)];
|
|
62
|
-
case 1:
|
|
63
|
-
serialized = _a.sent();
|
|
64
|
-
trie = trie_1.Trie.deserialize(serialized);
|
|
65
|
-
return [2 /*return*/, trie];
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
DiskCache.prototype.getLastModifiedTimestamp = function (locale) {
|
|
71
|
-
var filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
20
|
+
getLastModifiedTimestamp(locale) {
|
|
21
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
72
22
|
if (!fs_1.default.existsSync(filepath)) {
|
|
73
23
|
return undefined;
|
|
74
24
|
}
|
|
75
|
-
|
|
25
|
+
const stats = fs_1.default.statSync(filepath);
|
|
76
26
|
return stats.mtimeMs;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
27
|
+
}
|
|
28
|
+
has(locale) {
|
|
29
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
80
30
|
return fs_1.default.existsSync(filepath);
|
|
81
|
-
}
|
|
82
|
-
|
|
31
|
+
}
|
|
32
|
+
isStale(locale) {
|
|
83
33
|
if (!this.has(locale)) {
|
|
84
34
|
return undefined;
|
|
85
35
|
}
|
|
86
|
-
|
|
36
|
+
const lastModifiedTimestamp = this.getLastModifiedTimestamp(locale);
|
|
87
37
|
if (typeof lastModifiedTimestamp === 'undefined') {
|
|
88
38
|
return undefined;
|
|
89
39
|
}
|
|
90
|
-
|
|
40
|
+
const timeSinceModification = Math.abs(lastModifiedTimestamp - Date.now());
|
|
91
41
|
return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
case 0:
|
|
99
|
-
filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
100
|
-
return [4 /*yield*/, (0, writeFile_1.default)(filepath, trie.serialize())];
|
|
101
|
-
case 1:
|
|
102
|
-
_a.sent();
|
|
103
|
-
return [2 /*return*/];
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
return DiskCache;
|
|
109
|
-
}());
|
|
42
|
+
}
|
|
43
|
+
async set(locale, trie) {
|
|
44
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
45
|
+
await fs_1.default.promises.writeFile(filepath, trie.serialize());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
110
48
|
exports.default = DiskCache;
|
|
@@ -1,119 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
39
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
40
|
-
if (!m) return o;
|
|
41
|
-
var i = m.call(o), r, ar = [], e;
|
|
42
|
-
try {
|
|
43
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
44
|
-
}
|
|
45
|
-
catch (error) { e = { error: error }; }
|
|
46
|
-
finally {
|
|
47
|
-
try {
|
|
48
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
49
|
-
}
|
|
50
|
-
finally { if (e) throw e.error; }
|
|
51
|
-
}
|
|
52
|
-
return ar;
|
|
53
|
-
};
|
|
54
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
55
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
56
|
-
if (ar || !(i in from)) {
|
|
57
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
58
|
-
ar[i] = from[i];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
62
|
-
};
|
|
63
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
64
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
65
4
|
};
|
|
66
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
6
|
+
const createCacheTimestampComparator_1 = __importDefault(require("./createCacheTimestampComparator"));
|
|
7
|
+
const DiskCache_1 = __importDefault(require("./DiskCache"));
|
|
8
|
+
const MemoryCache_1 = __importDefault(require("./MemoryCache"));
|
|
9
|
+
class LayeredCache {
|
|
10
|
+
constructor() {
|
|
72
11
|
this.layers = [new MemoryCache_1.default(), new DiskCache_1.default()];
|
|
73
12
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (!
|
|
13
|
+
async get(locale) {
|
|
14
|
+
const cache = this.getLastModifiedLayer(locale);
|
|
15
|
+
if (!cache) {
|
|
77
16
|
return Promise.resolve(undefined);
|
|
78
17
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
18
|
+
const [memoryCache, diskCache] = this.layers;
|
|
19
|
+
const value = await cache.get(locale);
|
|
20
|
+
if (cache === diskCache && typeof value !== 'undefined') {
|
|
21
|
+
await memoryCache.set(locale, value);
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
getLastModifiedTimestamp(locale) {
|
|
26
|
+
const cache = this.getLastModifiedLayer(locale);
|
|
27
|
+
if (!cache) {
|
|
84
28
|
return undefined;
|
|
85
29
|
}
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return this.layers.some(
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (this.layers.some(
|
|
30
|
+
return cache.getLastModifiedTimestamp(locale);
|
|
31
|
+
}
|
|
32
|
+
has(locale) {
|
|
33
|
+
return this.layers.some((cache) => cache.has(locale));
|
|
34
|
+
}
|
|
35
|
+
isStale(locale) {
|
|
36
|
+
if (this.layers.some((cache) => cache.isStale(locale))) {
|
|
93
37
|
return true;
|
|
94
38
|
}
|
|
95
|
-
if (this.layers.every(
|
|
39
|
+
if (this.layers.every((cache) => typeof cache.isStale(locale) === 'undefined')) {
|
|
96
40
|
return undefined;
|
|
97
41
|
}
|
|
98
42
|
return false;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
LayeredCache.prototype.getLastModifiedLayer = function (locale) {
|
|
113
|
-
var layers = this.layers.filter(function (cache) { return cache.has(locale); });
|
|
114
|
-
var _a = __read(__spreadArray([], __read(layers), false).sort((0, createCacheTimestampComparator_1.default)(locale)), 1), cached = _a[0];
|
|
43
|
+
}
|
|
44
|
+
async set(locale, trie) {
|
|
45
|
+
const [memoryCache, diskCache] = this.layers;
|
|
46
|
+
await diskCache.set(locale, trie);
|
|
47
|
+
await memoryCache.set(locale, trie);
|
|
48
|
+
}
|
|
49
|
+
getLastModifiedLayer(locale) {
|
|
50
|
+
const layers = this.layers.filter((cache) => cache.has(locale));
|
|
51
|
+
const [cached] = [...layers].sort((0, createCacheTimestampComparator_1.default)(locale));
|
|
115
52
|
return cached;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
}());
|
|
53
|
+
}
|
|
54
|
+
}
|
|
119
55
|
exports.default = LayeredCache;
|
package/build/lib/MemoryCache.js
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const constants_1 = require("../constants");
|
|
4
|
+
class MemoryCache {
|
|
5
|
+
constructor() {
|
|
6
6
|
this.cache = {};
|
|
7
7
|
this.cacheTimestamps = {};
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
get(locale) {
|
|
10
10
|
return Promise.resolve(this.cache[locale]);
|
|
11
|
-
}
|
|
12
|
-
|
|
11
|
+
}
|
|
12
|
+
getLastModifiedTimestamp(locale) {
|
|
13
13
|
return this.cacheTimestamps[locale];
|
|
14
|
-
}
|
|
15
|
-
|
|
14
|
+
}
|
|
15
|
+
has(locale) {
|
|
16
16
|
return typeof this.cache[locale] !== 'undefined';
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
}
|
|
18
|
+
isStale(locale) {
|
|
19
|
+
const timestamp = this.getLastModifiedTimestamp(locale);
|
|
20
20
|
if (!this.has(locale) || typeof timestamp === 'undefined') {
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const timeSinceModification = Math.abs(timestamp - Date.now());
|
|
24
24
|
return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
|
|
25
|
-
}
|
|
26
|
-
|
|
25
|
+
}
|
|
26
|
+
set(locale, trie) {
|
|
27
27
|
this.cacheTimestamps[locale] = Date.now();
|
|
28
28
|
this.cache[locale] = trie;
|
|
29
29
|
return Promise.resolve();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
}());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
33
32
|
exports.default = MemoryCache;
|
|
@@ -1,62 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
case 2: return [2 /*return*/, _a.sent()];
|
|
54
|
-
case 3:
|
|
55
|
-
promise = null;
|
|
56
|
-
return [7 /*endfinally*/];
|
|
57
|
-
case 4: return [2 /*return*/];
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}); };
|
|
3
|
+
const createAsyncProxy = (asyncCallback) => {
|
|
4
|
+
let promise = null;
|
|
5
|
+
return async () => {
|
|
6
|
+
if (promise) {
|
|
7
|
+
return promise;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
promise = asyncCallback();
|
|
11
|
+
return await promise;
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
promise = null;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
61
17
|
};
|
|
62
18
|
exports.default = createAsyncProxy;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
return
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const createCacheTimestampComparator = (locale) => {
|
|
4
|
+
return (a, b) => {
|
|
5
|
+
const aTimestamp = a.getLastModifiedTimestamp(locale);
|
|
6
|
+
const bTimestamp = b.getLastModifiedTimestamp(locale);
|
|
7
7
|
if (aTimestamp === bTimestamp) {
|
|
8
8
|
return 0;
|
|
9
9
|
}
|
|
@@ -1,60 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
4
|
};
|
|
41
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
case 1:
|
|
53
|
-
words = _a.sent();
|
|
54
|
-
logger_1.default.info('downloadDictionary - success', { locale: locale });
|
|
55
|
-
trie = trie_1.Trie.fromArray(words);
|
|
56
|
-
return [2 /*return*/, trie];
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}); };
|
|
6
|
+
const trie_1 = require("@kamilmielnik/trie");
|
|
7
|
+
const logger_1 = __importDefault(require("@scrabble-solver/logger"));
|
|
8
|
+
const word_lists_1 = require("@scrabble-solver/word-lists");
|
|
9
|
+
const downloadDictionary = async (locale) => {
|
|
10
|
+
logger_1.default.info('downloadDictionary', { locale });
|
|
11
|
+
const words = await (0, word_lists_1.getWordList)(locale);
|
|
12
|
+
logger_1.default.info('downloadDictionary - success', { locale });
|
|
13
|
+
const trie = trie_1.Trie.fromArray(words);
|
|
14
|
+
return trie;
|
|
15
|
+
};
|
|
60
16
|
exports.default = downloadDictionary;
|
|
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return path_1.default.resolve(constants_1.OUTPUT_DIRECTORY,
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const constants_1 = require("../constants");
|
|
8
|
+
const getDictionaryFilepath = (locale) => {
|
|
9
|
+
return path_1.default.resolve(constants_1.OUTPUT_DIRECTORY, `${locale}.txt`);
|
|
10
10
|
};
|
|
11
11
|
exports.default = getDictionaryFilepath;
|
package/build/lib/index.d.ts
CHANGED
|
@@ -5,5 +5,3 @@ export { default as downloadDictionary } from './downloadDictionary';
|
|
|
5
5
|
export { default as getDictionaryFilepath } from './getDictionaryFilepath';
|
|
6
6
|
export { default as LayeredCache } from './LayeredCache';
|
|
7
7
|
export { default as MemoryCache } from './MemoryCache';
|
|
8
|
-
export { default as readFile } from './readFile';
|
|
9
|
-
export { default as writeFile } from './writeFile';
|
package/build/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.MemoryCache = exports.LayeredCache = exports.getDictionaryFilepath = exports.downloadDictionary = exports.DiskCache = exports.createCacheTimestampComparator = exports.createAsyncProxy = void 0;
|
|
7
7
|
var createAsyncProxy_1 = require("./createAsyncProxy");
|
|
8
8
|
Object.defineProperty(exports, "createAsyncProxy", { enumerable: true, get: function () { return __importDefault(createAsyncProxy_1).default; } });
|
|
9
9
|
var createCacheTimestampComparator_1 = require("./createCacheTimestampComparator");
|
|
@@ -18,7 +18,3 @@ var LayeredCache_1 = require("./LayeredCache");
|
|
|
18
18
|
Object.defineProperty(exports, "LayeredCache", { enumerable: true, get: function () { return __importDefault(LayeredCache_1).default; } });
|
|
19
19
|
var MemoryCache_1 = require("./MemoryCache");
|
|
20
20
|
Object.defineProperty(exports, "MemoryCache", { enumerable: true, get: function () { return __importDefault(MemoryCache_1).default; } });
|
|
21
|
-
var readFile_1 = require("./readFile");
|
|
22
|
-
Object.defineProperty(exports, "readFile", { enumerable: true, get: function () { return __importDefault(readFile_1).default; } });
|
|
23
|
-
var writeFile_1 = require("./writeFile");
|
|
24
|
-
Object.defineProperty(exports, "writeFile", { enumerable: true, get: function () { return __importDefault(writeFile_1).default; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/dictionaries",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.4",
|
|
4
4
|
"description": "Scrabble Solver 2 - Dictionaries",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"postbuild": "node ./bin/update-dictionaries.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@kamilmielnik/trie": "^
|
|
34
|
-
"@scrabble-solver/logger": "^2.8.
|
|
35
|
-
"@scrabble-solver/types": "^2.8.
|
|
36
|
-
"@scrabble-solver/word-lists": "^2.8.
|
|
33
|
+
"@kamilmielnik/trie": "^2.0.0",
|
|
34
|
+
"@scrabble-solver/logger": "^2.8.4",
|
|
35
|
+
"@scrabble-solver/types": "^2.8.4",
|
|
36
|
+
"@scrabble-solver/word-lists": "^2.8.4"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "3b0c4c9d7987e456f34f7e2918931b0024b8a393"
|
|
39
39
|
}
|
package/src/lib/DiskCache.ts
CHANGED
|
@@ -6,8 +6,6 @@ import { CACHE_STALE_THRESHOLD } from '../constants';
|
|
|
6
6
|
import { Cache } from '../types';
|
|
7
7
|
|
|
8
8
|
import getDictionaryFilepath from './getDictionaryFilepath';
|
|
9
|
-
import readFile from './readFile';
|
|
10
|
-
import writeFile from './writeFile';
|
|
11
9
|
|
|
12
10
|
class DiskCache implements Cache<Locale, Trie> {
|
|
13
11
|
public async get(locale: Locale): Promise<Trie | undefined> {
|
|
@@ -16,7 +14,7 @@ class DiskCache implements Cache<Locale, Trie> {
|
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
const filepath = getDictionaryFilepath(locale);
|
|
19
|
-
const serialized = await readFile(filepath);
|
|
17
|
+
const serialized = await fs.promises.readFile(filepath, 'utf-8');
|
|
20
18
|
const trie = Trie.deserialize(serialized);
|
|
21
19
|
return trie;
|
|
22
20
|
}
|
|
@@ -54,7 +52,7 @@ class DiskCache implements Cache<Locale, Trie> {
|
|
|
54
52
|
|
|
55
53
|
public async set(locale: Locale, trie: Trie): Promise<void> {
|
|
56
54
|
const filepath = getDictionaryFilepath(locale);
|
|
57
|
-
await writeFile(filepath, trie.serialize());
|
|
55
|
+
await fs.promises.writeFile(filepath, trie.serialize());
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
58
|
|
package/src/lib/LayeredCache.ts
CHANGED
|
@@ -10,24 +10,31 @@ import MemoryCache from './MemoryCache';
|
|
|
10
10
|
class LayeredCache implements Cache<Locale, Trie> {
|
|
11
11
|
private readonly layers = [new MemoryCache(), new DiskCache()];
|
|
12
12
|
|
|
13
|
-
public get(locale: Locale): Promise<Trie | undefined> {
|
|
14
|
-
const
|
|
13
|
+
public async get(locale: Locale): Promise<Trie | undefined> {
|
|
14
|
+
const cache = this.getLastModifiedLayer(locale);
|
|
15
15
|
|
|
16
|
-
if (!
|
|
16
|
+
if (!cache) {
|
|
17
17
|
return Promise.resolve(undefined);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const [memoryCache, diskCache] = this.layers;
|
|
21
|
+
const value = await cache.get(locale);
|
|
22
|
+
|
|
23
|
+
if (cache === diskCache && typeof value !== 'undefined') {
|
|
24
|
+
await memoryCache.set(locale, value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return value;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
public getLastModifiedTimestamp(locale: Locale): number | undefined {
|
|
24
|
-
const
|
|
31
|
+
const cache = this.getLastModifiedLayer(locale);
|
|
25
32
|
|
|
26
|
-
if (!
|
|
33
|
+
if (!cache) {
|
|
27
34
|
return undefined;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
return
|
|
37
|
+
return cache.getLastModifiedTimestamp(locale);
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
public has(locale: Locale): boolean {
|
|
@@ -47,7 +54,9 @@ class LayeredCache implements Cache<Locale, Trie> {
|
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
public async set(locale: Locale, trie: Trie): Promise<void> {
|
|
50
|
-
|
|
57
|
+
const [memoryCache, diskCache] = this.layers;
|
|
58
|
+
await diskCache.set(locale, trie);
|
|
59
|
+
await memoryCache.set(locale, trie);
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
private getLastModifiedLayer(locale: Locale): Cache<Locale, Trie> | undefined {
|
package/src/lib/index.ts
CHANGED
|
@@ -5,5 +5,3 @@ export { default as downloadDictionary } from './downloadDictionary';
|
|
|
5
5
|
export { default as getDictionaryFilepath } from './getDictionaryFilepath';
|
|
6
6
|
export { default as LayeredCache } from './LayeredCache';
|
|
7
7
|
export { default as MemoryCache } from './MemoryCache';
|
|
8
|
-
export { default as readFile } from './readFile';
|
|
9
|
-
export { default as writeFile } from './writeFile';
|
package/build/lib/readFile.d.ts
DELETED
package/build/lib/readFile.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
-
};
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
var fs_1 = __importDefault(require("fs"));
|
|
43
|
-
var readFile = function (filepath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
44
|
-
return __generator(this, function (_a) {
|
|
45
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
46
|
-
fs_1.default.readFile(filepath, { encoding: 'utf-8' }, function (error, data) {
|
|
47
|
-
if (error) {
|
|
48
|
-
reject();
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
resolve(data.toString());
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
})];
|
|
55
|
-
});
|
|
56
|
-
}); };
|
|
57
|
-
exports.default = readFile;
|
package/build/lib/writeFile.d.ts
DELETED
package/build/lib/writeFile.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
-
};
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
var fs_1 = __importDefault(require("fs"));
|
|
43
|
-
var writeFile = function (filepath, data) { return __awaiter(void 0, void 0, void 0, function () {
|
|
44
|
-
return __generator(this, function (_a) {
|
|
45
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
46
|
-
fs_1.default.writeFile(filepath, data, function (error) {
|
|
47
|
-
if (error) {
|
|
48
|
-
reject();
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
resolve();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
})];
|
|
55
|
-
});
|
|
56
|
-
}); };
|
|
57
|
-
exports.default = writeFile;
|
package/src/lib/readFile.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
|
|
3
|
-
const readFile = async (filepath: string): Promise<string> => {
|
|
4
|
-
return new Promise((resolve, reject) => {
|
|
5
|
-
fs.readFile(filepath, { encoding: 'utf-8' }, (error, data) => {
|
|
6
|
-
if (error) {
|
|
7
|
-
reject();
|
|
8
|
-
} else {
|
|
9
|
-
resolve(data.toString());
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default readFile;
|
package/src/lib/writeFile.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
|
|
3
|
-
const writeFile = async (filepath: string, data: string): Promise<void> => {
|
|
4
|
-
return new Promise((resolve, reject) => {
|
|
5
|
-
fs.writeFile(filepath, data, (error) => {
|
|
6
|
-
if (error) {
|
|
7
|
-
reject();
|
|
8
|
-
} else {
|
|
9
|
-
resolve();
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default writeFile;
|