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
28 changes: 28 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone.

## Our Standards

Examples of behavior that contributes to a positive environment include welcoming language, respectful communication, and constructive feedback.

Examples of unacceptable behavior include harassment, trolling, and publishing others' private information.

## Enforcement Responsibilities

Project maintainers are responsible for clarifying and enforcing our standards.

## Scope

This Code of Conduct applies within all community spaces and in public when an individual is officially representing the project.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the maintainers.
The maintainers will review and respond as appropriate.

## Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
42 changes: 42 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Contributing to @sigrea/react

Thank you for contributing! This project uses a PR-based workflow with required CI checks.

## Requirements

Node.js >= 20 and pnpm >= 10.
TypeScript strict mode, Biome for formatting, Vitest for tests.

## Scripts

`pnpm typecheck` — run TypeScript checks
`pnpm test` — run unit tests
`pnpm build` — build the library via unbuild
`pnpm format` — check formatting (no writes)
`pnpm format:fix` — apply formatting

## Commit Convention

Conventional Commits are required. Examples: `feat: ...`, `fix(scope): ...`, `docs: ...`.
The main branch uses squash merges, so the PR title becomes the final commit message.

## Changelog Entries

Changelogen reads Conventional Commits directly, so please keep commit messages descriptive. Any user-facing change (features, fixes, deprecations, breaking updates) should have a clear `feat`, `fix`, or similar commit. Non-user-facing changes can use `chore`, `test`, etc. For PRs that squash multiple commits, summarize the user impact in the PR description so release managers can double-check the changelog entry.

## Pull Requests

Ensure the following before requesting review:
CI passes (test/typecheck/build/format) and the PR title follows Conventional Commits.

## Release Workflow

This repository now uses [changelogen](https://github.com/unjs/changelogen) to infer the next semantic version from Conventional Commits, update `CHANGELOG.md`, and create the release commit plus tag. The workflow is intentionally linear so that a single maintainer can ship safely end to end.

1. Ensure `main` is up to date and clean. Run `pnpm changelog --no-output` if you want to preview the generated notes without touching the tree.
2. Execute `pnpm release`. This script runs `pnpm test`, `pnpm build`, and `changelogen --release` in sequence. The command bumps the version in `package.json`, rewrites `CHANGELOG.md`, and creates a `chore(release): vX.Y.Z` commit alongside the annotated `vX.Y.Z` tag.
- If you want to force a bump level or a specific version, run changelogen directly (recommended): `pnpm exec changelogen --release --minor` or `pnpm exec changelogen --release -r 0.4.0`.
3. Push the commit and tag together: `git push origin main --follow-tags`. If you need to stage multiple release commits, push in chronological order so tags stay in sync.
4. Tag pushes trigger `.github/workflows/publish.yml` automatically. The job runs on the `release` environment, installs dependencies, executes tests/type checks/build, publishes to npm via OIDC trusted publishing, and then calls `pnpm exec changelogen gh release vX.Y.Z --token $GITHUB_TOKEN` to sync the GitHub Release body with the freshly updated `CHANGELOG.md`.

If the publish workflow fails, fix the root cause and re-run the job from the GitHub Actions UI. Avoid creating a new tag unless you intend to cut a new release. If you must roll back, delete the tag locally and remotely, revert the release commit, and start over from step 1.
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [useDeepSignal](#usedeepsignal)
- [useMolcule](#usemolcule)
- [Testing](#testing)
- [Handling Scope Cleanup Errors](#handling-scope-cleanup-errors)
- [Development](#development)
- [License](#license)

Expand Down Expand Up @@ -68,7 +69,7 @@ const CounterMolecule = molecule((props: { initialCount: number }) => {
});

export function Counter(props: { initialCount: number }) {
const counter = useMolcule(CounterMolcule, props);
const counter = useMolcule(CounterMolecule, props);
const value = useSignal(counter.count);

return (
Expand Down Expand Up @@ -160,6 +161,32 @@ it("increments and displays the updated count", () => {
});
```

## Handling Scope Cleanup Errors

For global error handling configuration, see [@sigrea/core - Handling Scope Cleanup Errors](https://github.com/sigrea/core#handling-scope-cleanup-errors).

In React apps, configure the handler in your application entry point before rendering:

```tsx
// index.tsx or main.tsx
import { setScopeCleanupErrorHandler } from "@sigrea/core";
import { createRoot } from "react-dom/client";
import { App } from "./App";

setScopeCleanupErrorHandler((error, context) => {
console.error(`Cleanup failed:`, error);

// Forward to monitoring service
if (typeof Sentry !== "undefined") {
Sentry.captureException(error, {
tags: { scopeId: context.scopeId, phase: context.phase },
});
}
});

createRoot(document.getElementById("root")!).render(<App />);
```

## Development

This repo targets Node.js 20 or later.
Expand All @@ -174,9 +201,14 @@ You can also run pnpm scripts directly:

- `pnpm install` — install dependencies.
- `pnpm test` — run the Vitest suite once (no watch).
- `pnpm typecheck` — run TypeScript type checking.
- `pnpm test:coverage` — collect coverage.
- `pnpm build` — compile via unbuild to produce dual CJS/ESM bundles.
- `pnpm cicheck` — run CI checks locally.
- `pnpm dev` — launch the playground counter demo.

See [CONTRIBUTING.md](./CONTRIBUTING.md) for workflow details.

## License

MIT — see [LICENSE](./LICENSE).
7 changes: 7 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Security Policy

Please report vulnerabilities privately via GitHub Security Advisories.

- Submit a private advisory: https://github.com/sigrea/react/security/advisories/new

Do not open public issues for security reports. We will review and respond as appropriate.
6 changes: 6 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ run = [
description = "Preview changelog notes (no file changes)"
run = "pnpm exec changelogen --no-output"

[tasks.release_patch]
description = "Cut release commit + tag (force patch)"
depends = ["ci"]
confirm = "Create release commit + tag (patch) on main?"
run = 'test "$(git rev-parse --abbrev-ref HEAD)" = "main" && pnpm exec changelogen --clean --release --patch'

[tasks.release_minor]
description = "Cut release commit + tag (force minor)"
depends = ["ci"]
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"test:coverage": "vitest --coverage",
"typecheck": "tsc -p tsconfig.json --noEmit",
"format": "biome check .",
"format:fix": "biome check --write ."
"format:fix": "biome check --write .",
"cicheck": "pnpm test && pnpm typecheck && pnpm format:fix"
},
"peerDependencies": {
"@sigrea/core": "^0.4.0",
Expand Down