Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* text=auto eol=lf

*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.woff binary
*.woff2 binary
*.wasm binary
35 changes: 35 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--
Thanks for the PR. Please fill in the sections below.
Delete sections that don't apply.
-->

## What

<!-- One-sentence summary of the change. -->

## Why

<!-- What problem does this solve? Link issues with "Closes #123". -->

## How

<!-- A short walkthrough of the approach. Call out non-obvious decisions. -->

## Course module

<!-- If this PR maps to a course module (M0..M15), reference it here. -->

- Module: <!-- e.g. M3 / PR #4 -->

## Checklist

- [ ] `npm run typecheck` passes
- [ ] `npm run lint` passes (no new warnings)
- [ ] `npm run format:check` passes
- [ ] `npm test` passes
- [ ] PR description explains the **why**, not just the **what**
- [ ] No `console.log`, dead code, or commented-out blocks left behind

## Screenshots / recordings

<!-- For UI changes, please include a before/after. -->
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
verify:
name: Lint / Typecheck / Build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: ['20.19.x', '22.12.x']

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Format check
run: npm run format:check

- name: Lint
run: npm run lint

- name: Typecheck
run: npm run typecheck

- name: Test
run: npm test

- name: Build
run: npm run build
38 changes: 38 additions & 0 deletions .github/workflows/deploy-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Deploy Preview

on:
pull_request:
branches: [main]

concurrency:
group: deploy-preview-${{ github.ref }}
cancel-in-progress: true

jobs:
preview:
runs-on: ubuntu-latest
name: Build for Vercel preview
if: ${{ secrets.VERCEL_TOKEN != '' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22.12.x'
cache: 'npm'
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm test
- run: npm run build
- name: Deploy to Vercel (preview)
run: |
npm i -g vercel@latest
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "Preview URL: $URL"
gh pr comment ${{ github.event.pull_request.number }} --body "Preview deploy: $URL"
env:
GH_TOKEN: ${{ github.token }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ dist-ssr
*.njsproj
*.sln
*.sw?

# Crash dumps
*.stackdump

# Test coverage
coverage

# Build artifacts
.vite
10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
dist
build
coverage
.vite
*.min.js
*.min.css
package-lock.json
pnpm-lock.yaml
yarn.lock
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 100,
"arrowParens": "always",
"endOfLine": "lf"
}
78 changes: 78 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Contributing to Reactisma

Thanks for considering a contribution. Reactisma is the companion repo of the Reactisma course, so a few conventions matter more here than in a typical OSS project:

1. Every change should be educational. If a refactor is "just" cleaner, write a paragraph in the PR explaining the **why**.
2. PRs map 1:1 with course modules where possible. If your change overlaps a planned module, please coordinate first (open an issue).
3. We prefer **boring, readable code**. No clever one-liners that future course readers will trip over.

---

## Workflow

1. Fork the repo and clone your fork.
2. Create a branch off `main`: `git checkout -b feat/short-description`.
3. Make changes, run `npm run typecheck`, `npm run lint`, `npm test`.
4. Commit using **conventional commits** (see below).
5. Push and open a PR against `main`. Fill out the template.

---

## Conventional commits

Format: `<type>(<scope>): <summary>`

Types we use:

| Type | When to use |
| --- | --- |
| `feat` | A new feature or capability |
| `fix` | A bug fix |
| `perf` | A performance improvement |
| `refactor` | Code change that neither fixes a bug nor adds a feature |
| `docs` | Documentation only |
| `test` | Adding/updating tests |
| `chore` | Tooling, build, dependencies |
| `style` | Formatting only (no logic change) |

Scopes are loose but try to be one of: `vdom`, `hooks`, `scheduler`, `reconciler`, `dom`, `styled`, `nn`, `memory`, `ssr`, `worker`, `wasm`, `devtools`, `course`.

Examples:

```
feat(hooks): add useReducer with action discrimination via TS narrowing
fix(reconciler): preserve component instance when reordering keyed children
perf(nn): switch dual hemispheres to Float32Array layout
docs(course): expand module 4 outline with diagram links
```

---

## PR checklist

Before requesting review, please confirm:

- [ ] `npm run typecheck` passes
- [ ] `npm run lint` passes (no new warnings either)
- [ ] `npm run format:check` passes
- [ ] `npm test` passes
- [ ] The PR has a description explaining **why** (not just what)
- [ ] If the change is part of a course module, the module is referenced
- [ ] No leftover `console.log`, commented-out code, or dead imports

---

## Code style

- TypeScript strict mode is non-negotiable. Don't widen types with `any`; use `unknown` + narrowing.
- Functions should fit on a screen. If they don't, split them.
- Prefer pure functions in `utils/`. Side effects belong in components or in clearly-named lifecycle hooks.
- Hooks must follow the rules of hooks. We will land a custom ESLint rule for this in M3.

## Reporting issues

Open an issue with a reproduction case (link to a fork, a CodeSandbox, or a minimal `.tsx` snippet) and the expected vs. actual behavior. Tag with `bug`, `enhancement`, `question`, or `course`.

## License

By contributing, you agree that your contributions will be licensed under the MIT License.
Loading