@scrabble-solver/dictionaries 2.8.2 → 2.8.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/build/Dictionaries.js +37 -110
- package/build/constants/index.js +2 -2
- package/build/index.js +1 -1
- package/build/lib/DiskCache.js +31 -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/readFile.js +12 -50
- package/build/lib/writeFile.js +12 -50
- package/package.json +5 -5
- package/src/lib/LayeredCache.ts +17 -8
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,50 @@
|
|
|
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
|
+
const readFile_1 = __importDefault(require("./readFile"));
|
|
11
|
+
const writeFile_1 = __importDefault(require("./writeFile"));
|
|
12
|
+
class DiskCache {
|
|
13
|
+
async get(locale) {
|
|
14
|
+
if (!this.has(locale)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
18
|
+
const serialized = await (0, readFile_1.default)(filepath);
|
|
19
|
+
const trie = trie_1.Trie.deserialize(serialized);
|
|
20
|
+
return trie;
|
|
50
21
|
}
|
|
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);
|
|
22
|
+
getLastModifiedTimestamp(locale) {
|
|
23
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
72
24
|
if (!fs_1.default.existsSync(filepath)) {
|
|
73
25
|
return undefined;
|
|
74
26
|
}
|
|
75
|
-
|
|
27
|
+
const stats = fs_1.default.statSync(filepath);
|
|
76
28
|
return stats.mtimeMs;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
29
|
+
}
|
|
30
|
+
has(locale) {
|
|
31
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
80
32
|
return fs_1.default.existsSync(filepath);
|
|
81
|
-
}
|
|
82
|
-
|
|
33
|
+
}
|
|
34
|
+
isStale(locale) {
|
|
83
35
|
if (!this.has(locale)) {
|
|
84
36
|
return undefined;
|
|
85
37
|
}
|
|
86
|
-
|
|
38
|
+
const lastModifiedTimestamp = this.getLastModifiedTimestamp(locale);
|
|
87
39
|
if (typeof lastModifiedTimestamp === 'undefined') {
|
|
88
40
|
return undefined;
|
|
89
41
|
}
|
|
90
|
-
|
|
42
|
+
const timeSinceModification = Math.abs(lastModifiedTimestamp - Date.now());
|
|
91
43
|
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
|
-
}());
|
|
44
|
+
}
|
|
45
|
+
async set(locale, trie) {
|
|
46
|
+
const filepath = (0, getDictionaryFilepath_1.default)(locale);
|
|
47
|
+
await (0, writeFile_1.default)(filepath, trie.serialize());
|
|
48
|
+
}
|
|
49
|
+
}
|
|
110
50
|
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/readFile.js
CHANGED
|
@@ -1,57 +1,19 @@
|
|
|
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
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
})];
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const readFile = async (filepath) => {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
fs_1.default.readFile(filepath, { encoding: 'utf-8' }, (error, data) => {
|
|
10
|
+
if (error) {
|
|
11
|
+
reject();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
resolve(data.toString());
|
|
15
|
+
}
|
|
16
|
+
});
|
|
55
17
|
});
|
|
56
|
-
}
|
|
18
|
+
};
|
|
57
19
|
exports.default = readFile;
|
package/build/lib/writeFile.js
CHANGED
|
@@ -1,57 +1,19 @@
|
|
|
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
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
})];
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const writeFile = async (filepath, data) => {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
fs_1.default.writeFile(filepath, data, (error) => {
|
|
10
|
+
if (error) {
|
|
11
|
+
reject();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
resolve();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
55
17
|
});
|
|
56
|
-
}
|
|
18
|
+
};
|
|
57
19
|
exports.default = writeFile;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/dictionaries",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.3",
|
|
4
4
|
"description": "Scrabble Solver 2 - Dictionaries",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@kamilmielnik/trie": "^1.0.3",
|
|
34
|
-
"@scrabble-solver/logger": "^2.8.
|
|
35
|
-
"@scrabble-solver/types": "^2.8.
|
|
36
|
-
"@scrabble-solver/word-lists": "^2.8.
|
|
34
|
+
"@scrabble-solver/logger": "^2.8.3",
|
|
35
|
+
"@scrabble-solver/types": "^2.8.3",
|
|
36
|
+
"@scrabble-solver/word-lists": "^2.8.3"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "116f214733e7ad071044f556bcf67e867da3d9ca"
|
|
39
39
|
}
|
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 {
|