Last active
July 8, 2021 16:07
-
-
Save velut/6d0335c3ede885e11ce7c5768107d103 to your computer and use it in GitHub Desktop.
🦕 Running your first Deno script (From: https://www.edoardoscibona.com/running-your-first-deno-script)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Follow along with the article at: | |
// https://www.edoardoscibona.com/running-your-first-deno-script | |
// | |
// This script is licensed under the MIT license (https://opensource.org/licenses/MIT). | |
// | |
// Import the `sleep` function from a remote module | |
import { sleep } from "https://deno.land/x/sleep/mod.ts"; | |
/** Base URL for all calls to the Hacker News API */ | |
const baseURL = "https://hacker-news.firebaseio.com/v0"; | |
/** Item represents an item fetched from the HN API */ | |
interface Item { | |
/** Unique item ID; the only required property */ | |
readonly id: number; | |
/** Item type (`job`, `story`, `comment`, `poll`, or `pollopt`) */ | |
readonly type?: string; | |
/** Username of the user who submitted the item */ | |
readonly by?: string; | |
/** Title text for a story, poll or job */ | |
readonly title?: string; | |
/** URL for a story or job */ | |
readonly url?: string; | |
/** Text for a story, comment, poll, poll option or job */ | |
readonly text?: string; | |
/** Unix timestamp for when the item was created */ | |
readonly time?: number; | |
/** Score for a story, job or poll; votes for a poll option */ | |
readonly score?: number; | |
/** Number of total comments for a story or poll */ | |
readonly descendants?: number; | |
/** Set to `true` if the item is deleted */ | |
readonly deleted?: boolean; | |
/** Set to `true` if the item is dead */ | |
readonly dead?: boolean; | |
/** ID of the parent item of a comment (a story or another comment) */ | |
readonly parent?: number; | |
/** List of IDs of the item's comments, in display order */ | |
readonly kids?: number[]; | |
/** ID of the poll associated to a poll option */ | |
readonly poll?: number; | |
/** List of IDs of related poll options, in display order */ | |
readonly parts?: number[]; | |
} | |
/** getMaxItemID returns the ID of the most recent item published on HN */ | |
async function getMaxItemID(): Promise<number> { | |
const endpoint = `${baseURL}/maxitem.json`; | |
const res = await fetch(endpoint); | |
const id = await res.json(); | |
return id; | |
} | |
/** getItemByID fetches an item from the HN API given its ID */ | |
async function getItemByID(id: number): Promise<Item | undefined> { | |
const endpoint = `${baseURL}/item/${id}.json`; | |
const res = await fetch(endpoint); | |
const item = await res.json(); | |
return item ?? undefined; | |
} | |
/** streamComments continuously fetches and displays the most recent comments published on HN */ | |
async function streamComments() { | |
// Get the ID of the most recent item | |
let id = await getMaxItemID(); | |
// Keep running forever | |
while (true) { | |
// Get the item | |
const item = await getItemByID(id); | |
// If the item does not exist, wait 5 seconds and try again | |
if (!item) { | |
await sleep(5); | |
continue; | |
} | |
// Print only items that are visible comments | |
const { type, deleted, dead } = item; | |
const removed = deleted || dead || false; | |
if (type === "comment" && !removed) { | |
// Get the comment's author, if any | |
const author = item.by ?? "unknown author"; | |
// Get the comment's URL on HN website | |
const hnURL = `https://news.ycombinator.com/item?id=${id}`; | |
// Print the comment | |
console.log(`\nRead new comment by ${author} on ${hnURL}`); | |
console.log(item); | |
} | |
// Increment the ID for the next item | |
id += 1; | |
} | |
} | |
await streamComments(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment