Skip to content

Instantly share code, notes, and snippets.

@i-hardy
Last active March 12, 2019 16:40
Show Gist options
  • Save i-hardy/239cccaa56b02ffcc7fc3fc370539899 to your computer and use it in GitHub Desktop.
Save i-hardy/239cccaa56b02ffcc7fc3fc370539899 to your computer and use it in GitHub Desktop.
Streaming data from the GitHub GraphQL API with an async generator
function githubStream(delayTime = 2) {
const delay = () => new Promise(resolve => setTimeout(resolve, delayTime * 1000))
let repos = [];
let maxIterations = 100;
function getCursor() {
if (repos.length) {
return repos[repos.length - 1].cursor;
}
return '';
}
async function getRepos(variables, cursor = '') {
const query = `query($q: String!) {
search(type: REPOSITORY, query: $q, first: 100${cursor ? `, after: "${cursor}"` : ''}) {
repositoryCount
edges {
node {
... on Repository {
id
createdAt
updatedAt
name
nameWithOwner
stargazers {
totalCount
}
}
}
cursor
}
}
}`
return fetch('https://api.github.com/graphql', {
method: 'POST',
body: JSON.stringify({
query,
variables
}),
headers: {
Authorization: `bearer ${API_KEY}`,
'Content-Type': 'application/json',
Accept: 'application/vnd.github.machine-man-preview+json'
}
})
.then(res => res.json())
.then(json => {
const { repositoryCount, edges } = json.data.search;
maxIterations = repositoryCount;
repos = [...repos, ...edges]
})
}
return {
[Symbol.asyncIterator]: async function*() {
let iterationCount = 0;
while (iterationCount <= maxIterations) {
if (repos.length < 20) {
await getRepos({ q: 'javascript' }, getCursor());
}
await delay();
yield repos.shift();
iterationCount += 1;
}
}
}
}
(async () => {
const stream = githubStream();
for await (let repo of stream) {
console.log(repo.node.nameWithOwner);
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment