Skip to content

Commit 06c98fc

Browse files
committed
chore: add types via jsdoc
1 parent 3ce8d46 commit 06c98fc

File tree

2 files changed

+120
-28
lines changed

2 files changed

+120
-28
lines changed

_webi/builds-cacher.js

Lines changed: 119 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,27 @@ var TERMS_META = [
5656
/** @typedef {String} VersionString */
5757
/** @typedef {Object.<VersionString, Array<BuildAsset>>} PackagesByRelease */
5858

59+
/** @typedef {ProjectMeta & ProjectInfoPartial} ProjectInfo */
5960
/**
60-
* @typedef ProjectInfo
61-
* @prop {Array<BuildAsset>} releases
61+
* @typedef ProjectMeta
6262
* @prop {Array<BuildAsset>} packages
6363
* @prop {Object.<TripletString, PackagesByRelease>} releasesByTriplet
6464
* @prop {Array<import('./build-classifier/types.js').ArchString>} arches
6565
* @prop {Array<import('./build-classifier/types.js').OsString>} oses
6666
* @prop {Array<import('./build-classifier/types.js').LibcString>} libcs
67-
* @prop {Array<String>} channels
6867
* @prop {Array<String>} formats
6968
* @prop {Array<String>} triplets
7069
* @prop {Array<String>} versions
7170
* @prop {Array<String>} lexvers
7271
* @prop {Object.<String, String>} lexversMap
7372
*/
7473

74+
/**
75+
* @typedef ProjectInfoPartial
76+
* @prop {Array<BuildAsset>} releases
77+
* @prop {Array<String>} channels
78+
*/
79+
7580
/**
7681
* @typedef BuildAsset
7782
* @prop {String} name
@@ -83,6 +88,8 @@ var TERMS_META = [
8388
* @prop {String} libc
8489
* @prop {String} ext
8590
* @prop {String} download
91+
* @prop {import('./build-classifier/types.js').TargetTriplet} [target]
92+
* @prop {String} [lexver]
8693
*/
8794

8895
/**
@@ -100,6 +107,18 @@ var TERMS_META = [
100107
* @prop {Error} target.error
101108
*/
102109

110+
/**
111+
* @typedef {Error & WebiErrorPartial} WebiError
112+
* @typedef WebiErrorPartial
113+
* @prop {String} code
114+
* @prop {Number} status
115+
*/
116+
117+
/** @typedef {String} PathString */
118+
119+
/**
120+
* @param {PathString} path
121+
*/
103122
async function getPartialHeader(path) {
104123
let readme = `${path}/README.md`;
105124
let head = await readFirstBytes(readme).catch(function (err) {
@@ -112,8 +131,9 @@ async function getPartialHeader(path) {
112131
return head;
113132
}
114133

115-
// let fsOpen = util.promisify(Fs.open);
116-
// let fsRead = util.promisify(Fs.read);
134+
/**
135+
* @param {PathString} path
136+
*/
117137
async function readFirstBytes(path) {
118138
let start = 0;
119139
let n = 1024;
@@ -126,15 +146,29 @@ async function readFirstBytes(path) {
126146
return str;
127147
}
128148

149+
/** @type {Object.<String, Promise<void>>} */
129150
let promises = {};
151+
152+
/**
153+
* @param {import('../_example/releases.js')?} Releases
154+
* @param {PathString} installersDir
155+
* @param {PathString} cacheDir
156+
* @param {PathString} name
157+
* @param {Date?} [date]
158+
*/
130159
async function getLatestBuilds(Releases, installersDir, cacheDir, name, date) {
131160
console.info(`[INFO] getLatestBuilds: ${name}`);
132161

133162
if (!Releases) {
134163
Releases = require(`${installersDir}/${name}/releases.js`);
135164
}
165+
if (!Releases) {
166+
throw new Error('unreachable: narrowing for type checker');
167+
}
168+
136169
// TODO update all releases files with module.exports.xxxx = 'foo';
137170
if (!Releases.latest) {
171+
//@ts-expect-error
138172
Releases.latest = Releases;
139173
}
140174

@@ -150,6 +184,12 @@ async function getLatestBuilds(Releases, installersDir, cacheDir, name, date) {
150184
return await promises[id];
151185
}
152186

187+
/**
188+
* @param {import('../_example/releases.js')} Releases
189+
* @param {PathString} cacheDir
190+
* @param {PathString} name
191+
* @param {Date?} [date]
192+
*/
153193
async function getLatestBuildsInner(Releases, cacheDir, name, date) {
154194
let data = await Releases.latest();
155195

@@ -191,11 +231,14 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
191231
bc.orphanTerms = Object.assign({}, bc.ALL_TERMS);
192232
bc.unknownTerms = {};
193233
bc.usedTerms = {};
234+
/** @type {Array<String>} */
194235
bc.formats = [];
195236
bc._triplets = {};
196237
bc._targetsByBuildIdCache = {};
238+
/** @type {Object.<String, ProjectInfo>} */
197239
bc._caches = {};
198240
bc._staleAge = 15 * 60 * 1000;
241+
/** @type {Object.<String, Array<String>>} */
199242
bc._allFormats = {};
200243
bc._allTriplets = {};
201244

@@ -243,8 +286,8 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
243286
let filepath = Path.join(installersDir, name);
244287
let entry;
245288
try {
246-
entry = await Fs.lstat(filepath);
247-
Object.assign(entry, { name: name });
289+
let stat = await Fs.lstat(filepath);
290+
entry = Object.assign(stat, { name: name });
248291
} catch (e) {
249292
return { type: 'errors', detail: 'not found' };
250293
}
@@ -255,7 +298,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
255298

256299
/**
257300
* Get project type and detail - alias, selfhosted, valid (and the invalids)
258-
* @param {fs.Stats|fs.Dirent} entry
301+
* @param {Omit<import('fs').Dirent, "path"|"parentPath">} entry
259302
*/
260303
bc.getProjectTypeByEntry = async function (entry) {
261304
let path = Path.join(installersDir, entry.name);
@@ -300,7 +343,9 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
300343
let releasesPath = Path.join(path, 'releases.js');
301344
try {
302345
void require(releasesPath);
303-
} catch (err) {
346+
} catch (_err) {
347+
/** @type {WebiError} */ // @ts-expect-error
348+
let err = _err;
304349
if (err.code !== 'MODULE_NOT_FOUND') {
305350
return { type: 'errors', detail: err };
306351
}
@@ -315,9 +360,16 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
315360
return { type: 'valid', detail: true };
316361
};
317362

318-
// Typically a package is organized by release (ex: go has 1.20, 1.21, etc),
319-
// but we will organize by the build (ex: go1.20-darwin-arm64.tar.gz, etc).
320-
bc.getPackages = async function ({ Releases, name, date }) {
363+
/**
364+
* Typically a package is organized by release (ex: go has 1.20, 1.21, etc),
365+
* but we will organize by the build (ex: go1.20-darwin-arm64.tar.gz, etc).
366+
*
367+
* @param {Object} opts
368+
* @param {import('../_example/releases.js')?} [opts.Releases]
369+
* @param {PathString} opts.name
370+
* @param {Date} opts.date
371+
*/
372+
bc.getPackages = async function ({ Releases = null, name, date }) {
321373
if (!date) {
322374
date = new Date();
323375
}
@@ -342,6 +394,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
342394

343395
let projInfo = bc._caches[name];
344396

397+
/** @type {ProjectMeta} */
345398
let meta = {
346399
// version info
347400
versions: projInfo?.versions || [],
@@ -360,20 +413,23 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
360413
};
361414

362415
if (!projInfo) {
416+
let NULLSTRING = 'null';
363417
let json = await Fs.readFile(dataFile, 'ascii').catch(
364418
async function (err) {
365419
if (err.code !== 'ENOENT') {
366420
throw err;
367421
}
368422

369-
return null;
423+
return NULLSTRING;
370424
},
371425
);
372426

373427
try {
374428
projInfo = JSON.parse(json);
375-
} catch (e) {
376-
console.error(`error: ${dataFile}:\n\t${e.message}`);
429+
} catch (_err) {
430+
/** @type {WebiError} */ // @ts-expect-error
431+
let err = _err;
432+
console.error(`error: ${dataFile}:\n\t${err.message}`);
377433
projInfo = null;
378434
}
379435
}
@@ -419,8 +475,13 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
419475
};
420476

421477
// Makes sure that packages are updated once an hour, on average
478+
/** @type {Array<String>} */
422479
bc._staleNames = [];
480+
/** @type {ReturnType<typeof setTimeout>?} */
423481
bc._freshenTimeout = null;
482+
/**
483+
* @param {Number?} [minDelay]
484+
*/
424485
bc.freshenRandomPackage = async function (minDelay) {
425486
if (!minDelay) {
426487
minDelay = 15 * 1000;
@@ -437,7 +498,7 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
437498
let name = bc._staleNames.pop();
438499
void (await bc.getPackages({
439500
//Releases: Releases,
440-
name: name,
501+
name: name || '',
441502
date: new Date(),
442503
}));
443504
console.info(`[INFO] freshenRandomPackage: ${name}`);
@@ -448,7 +509,9 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
448509
let seed = Math.random();
449510
delay += seed * spread;
450511

451-
clearTimeout(bc._freshenTimeout);
512+
if (bc._freshenTimeout) {
513+
clearTimeout(bc._freshenTimeout);
514+
}
452515
bc._freshenTimeout = setTimeout(bc.freshenRandomPackage, delay);
453516
bc._freshenTimeout.unref();
454517
};
@@ -471,6 +534,8 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
471534
* .tar.xz
472535
* .xz
473536
* .zip
537+
*
538+
* @param {Array<String>} formats
474539
*/
475540
bc.getSortedFormats = function (formats) {
476541
/* jshint maxcomplexity: 25 */
@@ -579,6 +644,10 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
579644
return exts;
580645
};
581646

647+
/**
648+
* @param {Array<BuildAsset>} packages
649+
* @param {Array<String>} formats
650+
*/
582651
bc.selectPackage = function (packages, formats) {
583652
if (packages.length === 1) {
584653
return packages[0];
@@ -767,6 +836,11 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
767836
return bc;
768837
};
769838

839+
/**
840+
* @param {ReturnType<typeof BuildsCacher.create>} bc
841+
* @param {ProjectInfo} projInfo
842+
* @param {BuildAsset} build
843+
*/
770844
BuildsCacher._classify = function (bc, projInfo, build) {
771845
/* jshint maxcomplexity: 25 */
772846
let maybeInstallable = Triplet.maybeInstallable(projInfo, build);
@@ -947,7 +1021,11 @@ BuildsCacher.transformAndUpdate = function (name, projInfo, meta, date, bc) {
9471021
};
9481022

9491023
// TODO
950-
// - tag channels
1024+
// - tag channels
1025+
/**
1026+
* @param {ProjectInfo} projInfo
1027+
* @param {ProjectMeta} meta
1028+
*/
9511029
BuildsCacher.updateAndSortVersions = function (projInfo, meta) {
9521030
for (let build of projInfo.packages) {
9531031
let hasVersion = meta.versions.includes(build.version);
@@ -967,17 +1045,31 @@ BuildsCacher.updateAndSortVersions = function (projInfo, meta) {
9671045
meta.versions.push(version);
9681046
}
9691047

970-
projInfo.packages.sort(function (a, b) {
971-
if (a.lexver > b.lexver) {
972-
return -1;
973-
}
974-
if (a.lexver < b.lexver) {
975-
return 1;
976-
}
977-
return 0;
978-
});
1048+
projInfo.packages.sort(BuildsCacher.sortByLexver);
1049+
};
1050+
1051+
/**
1052+
* @typedef HasLexver
1053+
* @prop {String} lexver
1054+
*/
1055+
1056+
/**
1057+
* @param {HasLexver} a
1058+
* @param {HasLexver} b
1059+
*/
1060+
BuildsCacher.sortByLexver = function (a, b) {
1061+
if (a.lexver > b.lexver) {
1062+
return -1;
1063+
}
1064+
if (a.lexver < b.lexver) {
1065+
return 1;
1066+
}
1067+
return 0;
9791068
};
9801069

1070+
/**
1071+
* @param {ProjectMeta} meta
1072+
*/
9811073
BuildsCacher.updateReleasesByTriplet = function (meta) {
9821074
for (let build of meta.packages) {
9831075
let target = build.target;

0 commit comments

Comments
 (0)