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
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "<your-scope>/<name>" }],
"changelog": ["@changesets/changelog-github", { "repo": "@oopsstudio/system" }],
"commit": false,
"fixed": [],
"linked": [],
Expand Down
256 changes: 29 additions & 227 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,250 +1,52 @@
# Monorepo Template
# Ooops System — Monorepo

Opinionated TypeScript + pnpm workspace monorepo template. It ships with Vitest (V8 coverage), ESLint (flat config), tsup builds, Husky + Commitlint, Changesets, dependency-cruiser, publint, are-the-types-wrong, and size-limit. Batteries included; vendor lock-in not included.

## Requirements

- Node 20.x or 22.x
- pnpm 9.x

## Quick start

1. Use this repository as a **Template** on GitHub.
2. Clone your new repository and install:
- `pnpm install`
3. Validate everything:
- `pnpm -w validate`
(runs typecheck, lint, build, tests, size-limit, dep-cruise, publint, attw)

## What’s inside

- **TypeScript**: strict, ESM, project references ready
- **Vitest**: node environment, V8 coverage, per-package opt-in config
- **ESLint (flat)**: tabs, single quotes, no semicolons, max line length 100
- **tsup**: ESM output, d.ts, sourcemaps, tree-shakeable
- **Husky + Commitlint**: Git hooks, Conventional Commits
- **Changesets**: versioning and publishing flow
- **dependency-cruiser**: no cycles, no unresolved, no importing other packages’ internals
- **publint & are-the-types-wrong**: package publishing sanity checks
- **size-limit**: per-entry bundle budgets

## Workspace layout

```
.
├─ packages/
│ └─ demo/ # example package (you can delete or replace)
├─ .github/workflows/ci.yml # CI pipeline (calls pnpm -w validate)
├─ .github/workflows/release.yml # Auto-release (Changesets)
├─ tsconfig.base.json # shared TS config
├─ eslint.config.js # flat ESLint config
├─ .dependency-cruiser.cjs # graph rules (no cycles, no cross-internals)
├─ package.json # workspace scripts
├─ README.md # README file
└─ vitest.config.ts # vitest config
```

## Common scripts (root)

- `pnpm -w typecheck` — TypeScript type check for the workspace
- `pnpm -w lint` — ESLint across the workspace
- `pnpm -w build` — build all packages with tsup
- `pnpm -w test` — run Vitest across packages
- `pnpm -w size` — run size-limit across packages
- `pnpm -w depcruise` — dependency-cruiser checks
- `pnpm -w publint` — publint checks on built packages
- `pnpm -w attw` — are-the-types-wrong checks
- `pnpm -w validate` — runs the full validation pipeline above

Filter by package: `pnpm -w -F @your-scope/<pkg> <script>`
A modular, framework-agnostic infrastructure suite for building production-grade web applications.
Unifies runtime logic, SDK utilities, and framework integrations under a single, deterministic monorepo.

---

## Auto-release (Changesets + GitHub Actions)

Two supported ways to authenticate with npm:

### Option A: Classic npm token (fastest)

1) Create npm token
- On npmjs.com → Access Tokens → Generate new token (automation).
- Copy the token.

2) Add repo secret
- GitHub → your repo → Settings → Secrets and variables → Actions → **New repository secret**
- Name: `NPM_TOKEN`
- Value: your npm token

3) Ensure packages are publishable
Inside each `packages/<name>/package.json`:
- `"name": "@your-scope/<name>"` (or unscoped if you prefer)
- `"version": "0.0.0"` (or whatever you start with)
- `"publishConfig": { "access": "public" }` for scoped public packages
- `"files": ["dist"]` and your build emits to `dist/`
- `repository`, `author`, `license` filled in
## Overview

4) Release workflow
This template includes `.github/workflows/release.yml` that:
- installs Node + pnpm
- runs `pnpm -w validate`
- runs `changesets/action@v1` to open a **Version Packages** PR and to publish after it’s merged
The **Ooops System** is structured for clarity, composability, and reproducible builds.
It provides three main public packages and supporting developer tooling.

If GitHub blocks PR creation by Actions in your org, add a **Personal Access Token (classic)** with `repo` scope as a secret named `RELEASE_TOKEN` and set the action to use it:
- In `release.yml`, set `GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}` for the Changesets step.
### Packages

### Option B: npm Trusted Publishing (OIDC; no long-lived token)

1) Link repo to npm
- On npmjs.com → your org or package → **Trusted publishers** → Add GitHub repository/workflow as a trusted publisher (follow the UI steps).

2) Enable provenance
- In `release.yml`, ensure:
- `permissions: id-token: write`
- `NPM_CONFIG_PROVENANCE: true` env
- Remove `NPM_TOKEN` usage.

3) First publish
If the package doesn’t exist on npm yet, you can still publish via trusted publishing once configured. If the UI blocks linking until the package exists, do a one-time manual publish locally with `npm publish --access public`, then switch to trusted publishing.
| Package | Description |
|----------|--------------|
| [`@ooopsstudio/core`](./packages/core) | Deterministic runtime, ports, engines, and services |
| [`@ooopsstudio/sdk`](./packages/sdk) | Developer utilities and platform integrations |
| [`@ooopsstudio/frameworks`](./packages/frameworks) | Framework adapters for Svelte and React |

---

## Release flow (TL;DR)

1) Create a feature branch
2) Do your changes
3) Create a changeset: `pnpm -w changeset`
- choose affected packages and bump type (patch/minor/major)
4) Commit and push your branch
5) Open PR → merge PR
6) The release workflow will open a **Version Packages** PR (bumps versions, writes changelogs)
7) Merge the **Version Packages** PR into `main`
8) The release workflow publishes to npm

> No changeset = no version bump = no publish.
## Installation

### Manual publish (optional)

- `pnpm -w changeset version`
- `pnpm install`
- `pnpm -w build`
- `pnpm -w changeset publish`

---

## Adding a new package

Create `packages/<name>/` with:

```
packages/<name>/
├─ package.json
├─ tsconfig.json
├─ tsup.config.ts
├─ size-limit.json
├─ src/
│ └─ index.ts
└─ test/
└─ index.test.ts
```

**package.json (example):**
```json
{
"name": "@your-scope/<name>",
"version": "0.0.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" }
},
"publishConfig": { "access": "public" },
"scripts": {
"build": "tsup",
"test": "vitest run",
"typecheck": "tsc -p tsconfig.json --noEmit",
"lint": "eslint ."
}
}
```

**tsconfig.json:**
```json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"rootDir": "src",
"outDir": "dist",
"types": ["node"]
},
"include": ["src"],
"exclude": ["dist", "coverage", "node_modules"]
}
```

**tsup.config.ts:**
```ts
import {defineConfig} from 'tsup'

export default defineConfig({
entry: { index: 'src/index.ts' },
format: ['esm'],
platform: 'neutral',
target: 'es2022',
dts: true,
sourcemap: true,
clean: true,
splitting: false,
treeshake: true,
minify: false
})
```

**size-limit.json:**
```json
[
{ "name": "<name>", "path": ["dist/index.js"], "limit": "6 KB" }
]
```bash
pnpm install
pnpm -r build
```

---

## Linting & style

- Tabs, single quotes, no semicolons, max line length 100
- No `any` in TypeScript (enforced)
- Don’t import another package’s `/src/**` (use published exports)
- Don’t use test helpers in runtime code

## Testing
## Development Standards

- Put tests under `test/` or `**/*.test.ts`
- Node environment by default
- Coverage via V8; adjust thresholds per package if needed
- Root Vitest config supports `passWithNoTests: true` so empty packages don’t fail CI
- Node 22+
- TypeScript strict mode
- pnpm 9+
- Vitest + V8 coverage
- ESLint Stylistic
- Deterministic builds with tsup

## CI

The GitHub Actions workflow calls `pnpm -w validate` so checks live in code, not YAML. It runs on push and pull requests for Node 20.x and 22.x.

## Troubleshooting

- **“GitHub Actions is not permitted to create or approve pull requests.”**
Use a PAT (classic) with `repo` scope as `RELEASE_TOKEN` and set `GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}` in the release job.
---

- **“No publish happened.”**
Ensure a changeset exists and that the **Version Packages** PR was merged into `main`.
## CI and Publishing

- **“npm auth failed.”**
Check `NPM_TOKEN` secret (for token auth) or your npm “Trusted publishers” configuration (for OIDC).
The repository includes reusable workflows for CI, validation, and releases via **Changesets**.
Each package is published under the `@ooopsstudio` scope on npm.

- **“Package not found / 403 on first publish.”**
For scoped public packages, ensure `"publishConfig": { "access": "public" }`. For OIDC, you may need a one-time manual publish before switching fully to trusted publishing, depending on your npm org settings.
---

## License

MIT (change as needed).
[MIT](./LICENSE) © Ooops Studio
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@<your-scope>/<name>",
"name": "@oopsstudio/system",
"version": "0.0.0",
"description": "TypeScript + pnpm monorepo template with Vitest, ESLint (flat), tsup, Husky/Commitlint, Changesets, dependency-cruiser, publint, ATTW, size-limit, and GitHub Actions CI — strict, fast, and ready to publish.",
"description": "Modular, framework-agnostic infrastructure system unifying runtime logic, SDK utilities, and framework adapters for deterministic, composable web development.",
"private": true,
"type": "module",
"license": "MIT",
Expand All @@ -11,7 +11,7 @@
"packageManager": "pnpm@10.20.0",
"repository": {
"type": "git",
"url": "https://github.com/Ooops-Studio/repo-name.git"
"url": "https://github.com/Ooops-Studio/ooops-system.git"
},
"scripts": {
"typecheck": "tsc -p tsconfig.base.json --noEmit",
Expand Down Expand Up @@ -52,4 +52,4 @@
"typescript": "^5.9.3",
"vitest": "^3.2.4"
}
}
}
3 changes: 3 additions & 0 deletions packages/core/.size-limit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
{ "name": "<core>", "path": ["dist/index.js"], "limit": "6 KB" }
]
3 changes: 3 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @ooopsstudio/core

## 0.0.0
61 changes: 61 additions & 0 deletions packages/core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# @ooopsstudio/core

Deterministic, framework-agnostic runtime for building production-grade web systems.
Includes typed ports, pure engines, and modular services for logging, cache, resilience, and observability — all composable, side-effect-free, and designed for Node 22+.

---

## Installation

```bash
pnpm add @ooopsstudio/core
# or
npm install @ooopsstudio/core
```

---

## Usage

```ts
import { createLogger } from '@ooopsstudio/core/logging'
import { createResiliencePolicy } from '@ooopsstudio/core/resilience'

const logger = createLogger({ level: 'info' })
const policy = createResiliencePolicy({ retries: 3 })

logger.info('System initialized')
```

Each module is tree-shakeable and adheres to strict import fences enforced by CI.
For example:
- **L0 Root** → contracts, tokens, ports
- **L1 Engines** → deterministic, DI-free factories
- **L2 Edges** → safe defaults and bridges
- **L3 Services** → runtime features (logging, cache, metrics, etc.)

---

## Architecture Overview

`@ooopsstudio/core` is part of the **Ooops System** monorepo — a modular infrastructure suite for reproducible web applications.

| Layer | Package | Purpose |
|-------|----------|----------|
| Core | `@ooopsstudio/core` | Runtime logic and services |
| SDK | `@ooopsstudio/sdk` | Developer utilities |
| Frameworks | `@ooopsstudio/frameworks` | Framework adapters (Svelte, React) |

---

## Requirements

- **Node:** 22.x or later
- **TypeScript:** Strict mode
- **Package Manager:** pnpm ≥ 9

---

## License

[MIT](./LICENSE) © Ooops Studio
Loading