This repository has been archived by the owner on Apr 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Babel.js
153 lines (134 loc) · 4.5 KB
/
Babel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const Promise = require('bluebird');
const PbfSplicer = require('./PbfSplicer');
const LanguagePicker = require('./LanguagePicker');
const Err = require('@kartotherian/err');
const checkType = require('@kartotherian/input-validator');
const uptile = require('tilelive-promise');
const fs = require('fs');
const path = require('path');
let core;
function Babel(uri, callback) {
if (!new.target) {
return new Babel(uri, callback);
}
let self = this;
Promise.try(() => {
self = uptile(self);
const { query } = checkType.normalizeUrl(uri);
checkType(query, 'source', 'string', true);
checkType(query, 'tag', 'string', 'name');
self.nameTag = query.tag;
checkType(query, 'multiTag', 'string', `${self.nameTag}_`);
self.multiTag = query.multiTag;
checkType(query, 'keepUncompressed', 'boolean');
self.keepUncompressed = query.keepUncompressed;
switch (uri.protocol) {
case 'babel:':
checkType(query, 'combineName', 'boolean', false);
self.combineName = query.combineName;
checkType(query, 'defaultLanguage', 'string');
self.defaultLanguage = query.defaultLanguage;
query.languageMap = query.languageMap || path.join(__dirname, 'fallbacks.json');
if (typeof query.languageMap === 'string') {
query.languageMap = JSON.parse(fs.readFileSync(query.languageMap, 'utf8'));
}
if (typeof query.languageMap === 'object' &&
!Array.isArray(query.languageMap)
) {
for (const lang of Object.keys(query.languageMap)) {
const value = { languageMap: query.languageMap[lang] };
checkType(value, 'languageMap', 'string-array', true);
value.languageMap.unshift(lang);
query.languageMap[lang] = value.languageMap;
}
} else {
throw new Err('languageMap must be a dictionary of' +
' langCodes => [list of langs codes]');
}
self.languageMap = query.languageMap;
self.langSplicers = {};
self.pickLanguage = true;
self.splicer = self._createSplicer(query.defaultLanguage);
break;
case 'json2tags:':
if (query.defaultLanguage || query.languageMap) {
throw new Err('defaultLanguage and languageMap params ' +
'are not allowed for "json2tags://" protocol');
}
self.pickLanguage = false;
self.splicer = self._createSplicer();
break;
default:
throw new Error('unknown protocol');
}
return core.loadSource(query.source);
}).then((source) => {
self.source = uptile(source);
return self;
}).nodeify(callback);
}
Babel.prototype.getAsync = function getAsync(opts) {
const self = this;
return self.source.getAsync(opts).then((res) => {
switch (opts.type) {
case undefined:
case 'tile': {
// return tile as-is
if (self.pickLanguage &&
(opts.lang || self.defaultLanguage) === 'local') {
return res;
}
let p = core.uncompressAsync(res.data, res.headers).then((v) => {
res.data = self._getSplicer(opts).processTile(v);
return res;
});
if (!self.keepUncompressed) {
p = p.then(core.compressPbfAsync);
}
return p;
}
default:
return res;
}
});
};
Babel.prototype._getSplicer = function _getSplicer(opts) {
checkType(opts, 'lang', 'string');
if (!this.pickLanguage || !opts.lang) {
return this.splicer;
}
let splicer = this.langSplicers[opts.lang];
if (splicer === undefined) {
splicer = this._createSplicer(opts.lang);
if (Object.keys(this.langSplicers).length > 1000) {
// Safety - ensure we don't consume too much memory
// todo: consider using some LRU cache instead of
// flushing everything when it gets too big
this.langSplicers = {};
}
this.langSplicers[opts.lang] = splicer;
}
return splicer;
};
Babel.prototype._createSplicer = function _createSplicer(langCode) {
let namePicker;
if (this.pickLanguage) {
namePicker = new LanguagePicker(langCode, {
nameTag: this.nameTag,
multiTag: this.multiTag,
languageMap: this.languageMap,
});
}
return new PbfSplicer({
nameTag: this.nameTag,
multiTag: this.multiTag,
namePicker,
combineName: this.combineName,
});
};
Babel.initKartotherian = function initKartotherian(cor) {
core = cor;
core.tilelive.protocols['json2tags:'] = Babel;
core.tilelive.protocols['babel:'] = Babel;
};
module.exports = Babel;