-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
147 lines (130 loc) · 4.3 KB
/
index.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
/* eslint-disable no-console */
// const ChangesStream = require('changes-stream');
const https = require('https');
const changes = require('concurrent-couch-follower');
const { createPackage, getNpmSyncSeq, updateNpmSyncSeq } = require('./db.js');
const dbUrl = 'https://replicate.npmjs.com';
const endless = true;
const patchSize = 100; // only applied if endless = false
const customElementsFile = 'custom-elements.json';
const aRequest = url =>
new Promise((resolve, reject) => {
https
.get(url, resp => {
let data = '';
resp.on('data', chunk => {
data += chunk;
});
resp.on('end', () => {
resolve(data);
});
})
.on('error', err => {
reject(err.message);
});
});
function aTimeout(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function getNpmLastDbSeq() {
const body = await aRequest(dbUrl);
return JSON.parse(body).update_seq;
}
async function main() {
const startSeq = await getNpmSyncSeq();
const npmLastDbSeq = await getNpmLastDbSeq();
const potentialEndSeq = startSeq + patchSize;
const endSeq = potentialEndSeq < npmLastDbSeq ? potentialEndSeq : npmLastDbSeq;
let active = true;
async function syncWc(change) {
if (active === false) {
return;
}
console.log(`${change.seq}... processing`);
if (change.deleted) {
// TODO: handle deletion of packages
return;
}
const pkg = change.doc;
const version = Object.keys(pkg.versions)[Object.keys(pkg.versions).length - 1];
const nameAtVersion = `${pkg.name}@${version}`;
const url = `https://unpkg.com/${nameAtVersion}/${customElementsFile}`;
let customElementsJsonString;
// if unpkg does not have the package yet then wait/fetch with increasing intervales
try {
customElementsJsonString = await aRequest(url);
if (customElementsJsonString === `Cannot find package ${nameAtVersion}`) {
console.log('Starting to wait for unpkg');
await aTimeout(10);
customElementsJsonString = await aRequest(url);
}
if (customElementsJsonString === `Cannot find package ${nameAtVersion}`) {
console.log('...more waiting for unpkg');
await aTimeout(100);
customElementsJsonString = await aRequest(url);
}
if (customElementsJsonString === `Cannot find package ${nameAtVersion}`) {
console.log('... ... extreme waiting for unpkg');
await aTimeout(1000);
customElementsJsonString = await aRequest(url);
}
if (customElementsJsonString === `Cannot find package ${nameAtVersion}`) {
console.log('!!! unpkg could not provide the package');
return;
}
} catch (err) {
console.log('!!! unpkg host unreachable');
console.log(err);
}
if (customElementsJsonString === `Cannot find "/${customElementsFile}" in ${nameAtVersion}`) {
console.log(` ${pkg.name}@${version} !== Web Component // ignore`);
}
if (customElementsJsonString[0] === '{') {
console.log(`----------------- ${pkg.name}@${version} === Web Component -----------------`);
await createPackage(pkg, version, JSON.parse(customElementsJsonString));
}
}
const dataHandler = (data, done) => {
syncWc(data).then(() => {
done();
});
};
let stream;
// for a new index the sequence to start/since from is 2877390 as this marks roughtly
// the time/change the first `custom-element.json` got published to npm
// second update after 2899795
const configOptions = {
db: dbUrl,
include_docs: true,
sequence: (seq, cb) => {
if (endless === false && seq >= endSeq) {
active = false;
}
updateNpmSyncSeq(seq)
.then(() => {
cb();
console.log(`= ${seq} // start seq in case of failure`);
if (endless === false && seq >= endSeq) {
if (endSeq === npmLastDbSeq) {
console.log('===> Up to date with latest npm changes');
}
stream.end();
process.exit(0);
}
})
.catch(err => {
console.log('## Could not update npmlas', err);
});
},
since: startSeq,
concurrency: 5,
};
stream = changes(dataHandler, configOptions);
}
main()
.then()
.catch(err => {
console.error(err);
});