Skip to content

Commit

Permalink
refactor: resolve promise after response
Browse files Browse the repository at this point in the history
  • Loading branch information
boywithkeyboard committed Apr 4, 2024
1 parent 7875190 commit fe46e34
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 51 deletions.
41 changes: 26 additions & 15 deletions registry/file_map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export async function createFileMap(user: string, repo: string, tag: string): Pr
return map
}

export async function getFileMap(user: string, repo: string, tag: string): Promise<FileMap | null> {
export async function getFileMap(user: string, repo: string, tag: string): Promise<{
fileMap: FileMap | null
resolve?: Promise<unknown>
}> {
await ensureDir('./cache')

const mapName = user + '/' + repo + '/' + tag
Expand All @@ -55,7 +58,9 @@ export async function getFileMap(user: string, repo: string, tag: string): Promi
// check if file map is in local cache
str = await readFile('./cache/' + encodedMapName, 'utf-8')

return JSON.parse(str)
return {
fileMap: JSON.parse(str)
}
} catch (err) {
// check if file map is in remote cache
const res = await fetch(`https://${process.env.R2_HOSTNAME}/${mapName}`)
Expand All @@ -67,26 +72,32 @@ export async function getFileMap(user: string, repo: string, tag: string): Promi

await writeFile('./cache/' + encodedMapName, buf)

return JSON.parse(buf.toString('utf-8'))
return {
fileMap: JSON.parse(buf.toString('utf-8'))
}
} else {
await res.body?.cancel()
}

// generate file map
const map = await createFileMap(user, repo, tag)
const fileMap = await createFileMap(user, repo, tag)

if (!map) {
return null
if (!fileMap) {
return {
fileMap: null
}
}

await writeFile('./cache/' + encodedMapName, JSON.stringify(map))

await s3.putObject({
Bucket: process.env.S3_BUCKET,
Key: mapName,
Body: await compress(JSON.stringify(map))
})

return map
return {
fileMap,
resolve: Promise.all([
writeFile('./cache/' + encodedMapName, JSON.stringify(fileMap)),
s3.putObject({
Bucket: process.env.S3_BUCKET,
Key: mapName,
Body: await compress(JSON.stringify(fileMap))
})
])
}
}
}
104 changes: 68 additions & 36 deletions registry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,39 @@ app.get('/favicon.svg', (_, res) => {

app.get('/ready', () => 'READY')

function respondWith(res: FastifyReply, statusCode: number, body: string | Buffer | null, headers?: Record<string, string>) {
if (headers) {
for (const [key, value] of Object.entries(headers)) {
async function respondWith(res: FastifyReply, statusCode: number, body: string | Buffer | null, options: {
headers?: Record<string, string>
resolve?: Promise<unknown>
} = {}) {
if (options.headers) {
for (const [key, value] of Object.entries(options.headers)) {
res.header(key, value)
}
}

res.code(statusCode)

if (body !== null) {
res.send(body)
res.send(body)

if (options.resolve) {
await options.resolve
}
}

app.setNotFoundHandler(async (req, res) => {
try {
if (req.method.toUpperCase() !== 'GET') {
return respondWith(res, 404, 'BAD METHOD')
return await respondWith(res, 404, 'BAD METHOD')
}

let url = req.url

if (
/^\/(std|(([a-zA-Z0-9\-]+)\/([a-zA-Z0-9._\-]+)))(@[a-zA-Z0-9.*]+)?(\/([a-zA-Z0-9._\-]+))*$/.test(url) === false
) {
return respondWith(res, 404, 'BAD URL', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'BAD URL', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
}
})
}

Expand All @@ -72,23 +78,29 @@ app.setNotFoundHandler(async (req, res) => {
const latestTag = await getLatestTag(user, repo)

if (!latestTag) {
return respondWith(res, 404, 'REPOSITORY NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'REPOSITORY NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
}
})
}

arr[2] = arr[2] + '@' + latestTag

return respondWith(res, 307, null, {
Location: 'https://deno.re' + arr.join('/')
return await respondWith(res, 307, null, {
headers: {
Location: 'https://deno.re' + arr.join('/')
}
})
}

const fileMap = await getFileMap(user, repo, tag)
const { fileMap, resolve } = await getFileMap(user, repo, tag)

if (!fileMap) {
return respondWith(res, 500, 'REPOSITORY OR TAG NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 500, 'REPOSITORY OR TAG NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
}
})
}

Expand All @@ -107,8 +119,11 @@ app.setNotFoundHandler(async (req, res) => {
const ext = arr.pop()

if (!ext) {
return respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
},
resolve
})
}

Expand All @@ -119,8 +134,11 @@ app.setNotFoundHandler(async (req, res) => {
entryPoint = arr.join('.')

if (!originalContent) {
return respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
},
resolve
})
}

Expand All @@ -131,14 +149,20 @@ app.setNotFoundHandler(async (req, res) => {
} else if (entryPoint) {
content = fileMap[entryPoint]
} else {
return respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'ENTRY POINT NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
},
resolve
})
}

if (!content) {
return respondWith(res, 404, 'FILE NOT FOUND', {
'Cache-Control': 's-max-age=60, max-age=0'
return await respondWith(res, 404, 'FILE NOT FOUND', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
},
resolve
})
}

Expand All @@ -160,27 +184,35 @@ app.setNotFoundHandler(async (req, res) => {
const typeHeader = resolveTypeHeader(fileMap, entryPoint)

if (previousEtag === checksum) {
return respondWith(res, 304, null, {
return await respondWith(res, 304, null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'public, max-age=2592000, immutable', // a month
'Content-Type': contentType + '; charset=utf-8',
'ETag': checksum,
...(typeHeader && { 'X-TypeScript-Types': 'https://deno.re/' + user + '/' + repo + '@' + tag + typeHeader })
},
resolve
})
}

await respondWith(res, 200, content, {
headers: {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'public, max-age=2592000, immutable', // a month
'Content-Type': contentType + '; charset=utf-8',
'ETag': checksum,
...(typeHeader && { 'X-TypeScript-Types': 'https://deno.re/' + user + '/' + repo + '@' + tag + typeHeader })
})
}

respondWith(res, 200, content, {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'public, max-age=2592000, immutable', // a month
'Content-Type': contentType + '; charset=utf-8',
'ETag': checksum,
...(typeHeader && { 'X-TypeScript-Types': 'https://deno.re/' + user + '/' + repo + '@' + tag + typeHeader })
},
resolve
})
} catch (err) {
console.error(err)

respondWith(res, 500, 'SOMETHING WENT WRONG', {
'Cache-Control': 's-max-age=60, max-age=0'
await respondWith(res, 500, 'SOMETHING WENT WRONG', {
headers: {
'Cache-Control': 's-max-age=60, max-age=0'
}
})
}
})
Expand Down

0 comments on commit fe46e34

Please sign in to comment.