Skip to content

Commit 142297e

Browse files
committed
merge dev into main
2 parents 73b3a5d + 63ec856 commit 142297e

82 files changed

Lines changed: 968 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: CI
2+
on:
3+
push:
4+
branches: [main]
5+
pull_request:
6+
jobs:
7+
test:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: actions/setup-node@v4
12+
with:
13+
node-version: 20
14+
- run: npm ci
15+
- run: npm test

topics/async-promises/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Promises & async/await
2+
3+
Promises represent a future value. async/await is sugar over .then chains.
4+
5+
## Key points
6+
7+
- 3 states: pending, fulfilled, rejected
8+
- Promise.all / race / allSettled / any
9+
- always handle rejections
10+
- common pitfall: forgetting `await`
11+
12+
## Examples
13+
14+
See `examples/` for runnable demos.
15+
16+
## Exercise
17+
18+
Convert a callback-based API client to async/await.
19+
20+
See `exercise.js` for the starter.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// promise chaining
2+
function fetchUser(id) {
3+
return new Promise((resolve) => {
4+
setTimeout(() => resolve({ id, name: 'user_' + id }), 20);
5+
});
6+
}
7+
8+
fetchUser(1)
9+
.then((u) => { console.log(u); return fetchUser(u.id + 1); })
10+
.then((u) => console.log(u))
11+
.catch(console.error);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// async/await
2+
async function loadAll(ids) {
3+
const results = [];
4+
for (const id of ids) {
5+
const u = await fetchUser(id);
6+
results.push(u);
7+
}
8+
return results;
9+
}
10+
11+
// parallel
12+
async function loadAllParallel(ids) {
13+
return Promise.all(ids.map(fetchUser));
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// common pitfall: forgetting to await
2+
async function bad() {
3+
const result = fetchUser(1); // missing await -> returns a Promise, not the user
4+
console.log(result.name); // undefined
5+
}
6+
7+
async function good() {
8+
const result = await fetchUser(1);
9+
console.log(result.name);
10+
}

topics/async-promises/exercise.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Exercise: Convert a callback-based API client to async/await.
2+
// TODO: implement
3+
module.exports = {};

topics/best-practices/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Production checklist
2+
3+
What I want students to remember after the course.
4+
5+
## Key points
6+
7+
- validate input at the boundary
8+
- 12-factor config (env vars, logs to stdout)
9+
- graceful shutdown
10+
- structured logging, not `console.log`
11+
- don't block the event loop
12+
13+
## Examples
14+
15+
See `examples/` for runnable demos.
16+
17+
## Exercise
18+
19+
Audit a sample Express app against the checklist.
20+
21+
See `exercise.js` for the starter.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// don't:
2+
// - log secrets, tokens, full request bodies
3+
// - use synchronous fs in hot paths
4+
// - swallow errors silently
5+
// - pass user input to child_process.exec directly
6+
// - block the event loop with CPU work — use worker_threads
7+
8+
// do:
9+
// - validate input at the boundary (zod, joi)
10+
// - 12-factor: config in env, logs to stdout
11+
// - graceful shutdown on SIGTERM
12+
// - prefer async fs APIs
13+
// - use a process manager (pm2, systemd, k8s)

topics/best-practices/exercise.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Exercise: Audit a sample Express app against the checklist.
2+
// TODO: implement
3+
module.exports = {};

0 commit comments

Comments
 (0)