create-koppajs 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +12 -10
- package/bin/create-koppajs.js +0 -14
- package/package.json +4 -4
- package/template/README.md +19 -206
- package/template/_gitignore +0 -3
- package/template/index.html +1 -1
- package/template/package.json +9 -46
- package/template/public/favicon.png +0 -0
- package/template/public/koppajs-logo.png +0 -0
- package/template/src/app-view.kpa +1 -3
- package/template/tsconfig.json +2 -9
- package/template-overlays/router/README.md +25 -200
- package/template-overlays/router/index.html +1 -1
- package/template-overlays/router/package.json +10 -47
- package/template-overlays/router/src/app-view.kpa +21 -78
- package/template-overlays/router/src/home-page.kpa +23 -60
- package/template-overlays/router/src/main.ts +0 -9
- package/template-overlays/router/src/not-found-page.kpa +16 -48
- package/template-overlays/router/src/router-page.kpa +34 -69
- package/template-overlays/router/src/style.css +5 -29
- package/template/AI_CONSTITUTION.md +0 -50
- package/template/ARCHITECTURE.md +0 -84
- package/template/CHANGELOG.md +0 -35
- package/template/CONTRIBUTING.md +0 -89
- package/template/DECISION_HIERARCHY.md +0 -32
- package/template/DEVELOPMENT_RULES.md +0 -57
- package/template/LICENSE +0 -201
- package/template/RELEASE.md +0 -227
- package/template/ROADMAP.md +0 -34
- package/template/TESTING_STRATEGY.md +0 -96
- package/template/_editorconfig +0 -12
- package/template/_github/instructions/ai-workflow.md +0 -33
- package/template/_github/workflows/ci.yml +0 -41
- package/template/_github/workflows/release.yml +0 -58
- package/template/_husky/commit-msg +0 -8
- package/template/_husky/pre-commit +0 -1
- package/template/_prettierignore +0 -7
- package/template/commitlint.config.mjs +0 -6
- package/template/docs/adr/0001-keep-the-starter-minimal.md +0 -32
- package/template/docs/adr/0002-adopt-a-living-meta-layer.md +0 -30
- package/template/docs/adr/0003-rely-on-upstream-kpa-es-module-output.md +0 -32
- package/template/docs/adr/0004-adopt-an-automated-quality-baseline.md +0 -31
- package/template/docs/adr/0005-adopt-a-tag-driven-release-baseline.md +0 -45
- package/template/docs/adr/0006-adopt-commit-message-conventions.md +0 -39
- package/template/docs/adr/README.md +0 -37
- package/template/docs/adr/TEMPLATE.md +0 -18
- package/template/docs/architecture/module-boundaries.md +0 -47
- package/template/docs/meta/maintenance.md +0 -40
- package/template/docs/quality/quality-gates.md +0 -39
- package/template/docs/specs/README.md +0 -36
- package/template/docs/specs/TEMPLATE.md +0 -34
- package/template/docs/specs/app-bootstrap.md +0 -46
- package/template/docs/specs/counter-component.md +0 -48
- package/template/docs/specs/quality-workflow.md +0 -62
- package/template/eslint.config.mjs +0 -54
- package/template/playwright.config.ts +0 -31
- package/template/pnpm-lock.yaml +0 -3777
- package/template/prettier.config.mjs +0 -6
- package/template/public/favicon.svg +0 -15
- package/template/tests/e2e/app.spec.ts +0 -18
- package/template/tests/integration/main-bootstrap.test.ts +0 -33
- package/template/vite.config.d.mts +0 -5
- package/template/vitest.config.mjs +0 -19
- package/template-overlays/router/ARCHITECTURE.md +0 -86
- package/template-overlays/router/CHANGELOG.md +0 -50
- package/template-overlays/router/DEVELOPMENT_RULES.md +0 -57
- package/template-overlays/router/ROADMAP.md +0 -34
- package/template-overlays/router/TESTING_STRATEGY.md +0 -67
- package/template-overlays/router/docs/adr/0001-keep-the-starter-minimal.md +0 -32
- package/template-overlays/router/docs/architecture/module-boundaries.md +0 -39
- package/template-overlays/router/docs/meta/maintenance.md +0 -38
- package/template-overlays/router/docs/specs/README.md +0 -19
- package/template-overlays/router/docs/specs/app-bootstrap.md +0 -42
- package/template-overlays/router/docs/specs/router-navigation.md +0 -41
- package/template-overlays/router/pnpm-lock.yaml +0 -3786
- package/template-overlays/router/tests/e2e/app.spec.ts +0 -38
- package/template-overlays/router/tests/integration/main-bootstrap.test.ts +0 -150
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<svg width="410" height="404" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)"/>
|
|
3
|
-
<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)"/>
|
|
4
|
-
<defs>
|
|
5
|
-
<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
|
|
6
|
-
<stop stop-color="#41D1FF"/>
|
|
7
|
-
<stop offset="1" stop-color="#BD34FE"/>
|
|
8
|
-
</linearGradient>
|
|
9
|
-
<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
|
|
10
|
-
<stop stop-color="#FFEA83"/>
|
|
11
|
-
<stop offset="0.0833333" stop-color="#FFDD35"/>
|
|
12
|
-
<stop offset="1" stop-color="#FFA800"/>
|
|
13
|
-
</linearGradient>
|
|
14
|
-
</defs>
|
|
15
|
-
</svg>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "@playwright/test";
|
|
2
|
-
|
|
3
|
-
test("renders the starter and updates the counter", async ({ page }) => {
|
|
4
|
-
await page.goto("/");
|
|
5
|
-
|
|
6
|
-
await expect(page.getByText("Minimal Starter")).toBeVisible();
|
|
7
|
-
|
|
8
|
-
const counterValue = page.getByRole("status");
|
|
9
|
-
|
|
10
|
-
await expect(counterValue).toHaveText("0");
|
|
11
|
-
|
|
12
|
-
await page.getByRole("button", { name: "Increment counter" }).click();
|
|
13
|
-
await expect(counterValue).toHaveText("1");
|
|
14
|
-
|
|
15
|
-
await page.getByRole("button", { name: "Decrement counter" }).click();
|
|
16
|
-
await page.getByRole("button", { name: "Decrement counter" }).click();
|
|
17
|
-
await expect(counterValue).toHaveText("-1");
|
|
18
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const { core, take } = vi.hoisted(() => {
|
|
4
|
-
const take = vi.fn();
|
|
5
|
-
const core = Object.assign(vi.fn(), { take });
|
|
6
|
-
|
|
7
|
-
return { core, take };
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
vi.mock("@koppajs/koppajs-core", () => ({
|
|
11
|
-
Core: core,
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
describe("main bootstrap", () => {
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
core.mockClear();
|
|
17
|
-
take.mockClear();
|
|
18
|
-
vi.resetModules();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("registers the root components and boots the app once", async () => {
|
|
22
|
-
await import("../../src/main");
|
|
23
|
-
|
|
24
|
-
expect(take).toHaveBeenCalledTimes(2);
|
|
25
|
-
expect(take).toHaveBeenNthCalledWith(1, expect.anything(), "app-view");
|
|
26
|
-
expect(take).toHaveBeenNthCalledWith(
|
|
27
|
-
2,
|
|
28
|
-
expect.anything(),
|
|
29
|
-
"counter-component",
|
|
30
|
-
);
|
|
31
|
-
expect(core).toHaveBeenCalledTimes(1);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineConfig, mergeConfig } from "vitest/config";
|
|
2
|
-
|
|
3
|
-
import viteConfig from "./vite.config.mjs";
|
|
4
|
-
|
|
5
|
-
export default mergeConfig(
|
|
6
|
-
viteConfig,
|
|
7
|
-
defineConfig({
|
|
8
|
-
test: {
|
|
9
|
-
include: ["tests/**/*.test.ts"],
|
|
10
|
-
coverage: {
|
|
11
|
-
provider: "v8",
|
|
12
|
-
reporter: ["text", "html"],
|
|
13
|
-
reportsDirectory: "./coverage",
|
|
14
|
-
include: ["src/**/*.ts"],
|
|
15
|
-
exclude: ["playwright.config.ts", "tests/**/*.ts", "vitest.config.mjs"],
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
}),
|
|
19
|
-
);
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
This repository is a small KoppaJS router starter. It demonstrates a clear
|
|
4
|
-
bootstrap path: HTML shell, TypeScript entrypoint, one root app shell
|
|
5
|
-
component, one router instance, two primary routes, and one explicit not-found
|
|
6
|
-
route. The repository also carries the same quality and release automation
|
|
7
|
-
baseline as the minimal starter so the example remains production-like.
|
|
8
|
-
|
|
9
|
-
## System overview
|
|
10
|
-
|
|
11
|
-
- `index.html` provides the document shell, loads global CSS, declares the
|
|
12
|
-
`<app-view>` root element, and imports the TypeScript entrypoint.
|
|
13
|
-
- `src/main.ts` registers local components with `Core.take(...)`, calls
|
|
14
|
-
`Core()` once, waits for the route outlet to exist, and initializes one
|
|
15
|
-
`KoppajsRouter` instance.
|
|
16
|
-
- `src/app-view.kpa` is the root shell. It renders the hero area, the primary
|
|
17
|
-
navigation, and the `#app-outlet` container that receives route content.
|
|
18
|
-
- `src/home-page.kpa` is the default route and composes `counter-component`.
|
|
19
|
-
- `src/router-page.kpa` is the second route and explains the router wiring.
|
|
20
|
-
- `src/not-found-page.kpa` is the explicit catch-all route.
|
|
21
|
-
- `src/counter-component.kpa` remains the example local-state component.
|
|
22
|
-
- `src/style.css` defines global tokens, base layout, and the background.
|
|
23
|
-
- `tests/integration/` verifies bootstrap wiring and router startup.
|
|
24
|
-
- `tests/e2e/` verifies the user-visible route flow and counter behavior.
|
|
25
|
-
|
|
26
|
-
More detailed boundaries live in [docs/architecture/module-boundaries.md](./docs/architecture/module-boundaries.md).
|
|
27
|
-
|
|
28
|
-
## Runtime flow
|
|
29
|
-
|
|
30
|
-
1. The browser loads [`index.html`](./index.html).
|
|
31
|
-
2. The document loads [`src/style.css`](./src/style.css) and [`src/main.ts`](./src/main.ts).
|
|
32
|
-
3. [`src/main.ts`](./src/main.ts) registers `app-view`, `home-page`,
|
|
33
|
-
`router-page`, `not-found-page`, and `counter-component`, then calls
|
|
34
|
-
`Core()`.
|
|
35
|
-
4. KoppaJS instantiates `<app-view>`.
|
|
36
|
-
5. [`src/app-view.kpa`](./src/app-view.kpa) renders the app shell, navigation,
|
|
37
|
-
and `#app-outlet`.
|
|
38
|
-
6. `src/main.ts` initializes `KoppajsRouter` with the route table and outlet.
|
|
39
|
-
7. The router renders the matching route component into `#app-outlet`,
|
|
40
|
-
synchronizes active links, and updates the current browser URL.
|
|
41
|
-
|
|
42
|
-
## Quality automation layer
|
|
43
|
-
|
|
44
|
-
- `eslint.config.mjs` lint-checks TypeScript source plus tooling files.
|
|
45
|
-
- `prettier.config.mjs` and `.editorconfig` keep supported text files consistent.
|
|
46
|
-
- `.npmrc` enforces the declared engine floor during installs.
|
|
47
|
-
- `.husky/pre-commit` runs `lint-staged`.
|
|
48
|
-
- `.husky/commit-msg` validates commit headers with `commitlint`.
|
|
49
|
-
- `.github/workflows/ci.yml` runs the full repository validation flow on GitHub.
|
|
50
|
-
- `.github/workflows/release.yml` runs tagged release validation and creates GitHub Releases.
|
|
51
|
-
|
|
52
|
-
## Module responsibilities
|
|
53
|
-
|
|
54
|
-
| Module | Responsibility | Must not do |
|
|
55
|
-
| --------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------ |
|
|
56
|
-
| `index.html` | Declare the root tag and static assets | Hold feature logic or router setup |
|
|
57
|
-
| `src/main.ts` | Bootstrap the app, register components, and start one router | Accumulate page copy or unrelated UI state |
|
|
58
|
-
| `src/app-view.kpa` | Render the shared shell, nav, and router outlet | Own route resolution or register components |
|
|
59
|
-
| `src/home-page.kpa` | Render the landing route and compose the counter example | Reach into router internals or mutate global DOM state |
|
|
60
|
-
| `src/router-page.kpa` | Render the second route and explain the router baseline | Own bootstrap logic or global navigation state |
|
|
61
|
-
| `src/not-found-page.kpa` | Render the explicit fallback route | Replace route matching or bootstrap responsibilities |
|
|
62
|
-
| `src/counter-component.kpa` | Demonstrate local interactive state | Reach into route orchestration or app-shell concerns |
|
|
63
|
-
| `src/style.css` | Hold global tokens and truly global base styles | Duplicate component-local visuals |
|
|
64
|
-
| `tests/integration/` | Verify bootstrap and router-start boundaries | Duplicate full browser smoke expectations |
|
|
65
|
-
| `tests/e2e/` | Verify visible navigation and counter behavior in a real browser | Assert brittle implementation details |
|
|
66
|
-
|
|
67
|
-
## Invariants
|
|
68
|
-
|
|
69
|
-
- There is exactly one bootstrap entrypoint.
|
|
70
|
-
- The root tag in `index.html` must match a component registered in `src/main.ts`.
|
|
71
|
-
- `Core()` is called once from `src/main.ts`.
|
|
72
|
-
- The starter owns exactly one router instance.
|
|
73
|
-
- The route table contains an explicit `*` fallback route.
|
|
74
|
-
- Route rendering happens through `#app-outlet`.
|
|
75
|
-
- Official releases require matching versions across `package.json`,
|
|
76
|
-
`CHANGELOG.md`, and `vX.Y.Z` tags.
|
|
77
|
-
|
|
78
|
-
## Extension guidance
|
|
79
|
-
|
|
80
|
-
- Add new route components under `src/` and register them from `src/main.ts`.
|
|
81
|
-
- Keep route definitions in one obvious place.
|
|
82
|
-
- Extract reusable route helpers into `.ts` modules only when logic becomes
|
|
83
|
-
shared or branch-heavy.
|
|
84
|
-
- Add a spec before changing visible navigation behavior.
|
|
85
|
-
- Add an ADR before changing the routing model, adding data fetching,
|
|
86
|
-
persistence, or another major subsystem.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to **__PROJECT_NAME__** are documented in this file.
|
|
4
|
-
|
|
5
|
-
This project uses a **manual, tag-driven release process**.
|
|
6
|
-
Only tagged versions represent official releases.
|
|
7
|
-
|
|
8
|
-
This changelog documents **intentional milestones and guarantees**,
|
|
9
|
-
not every internal refactor.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## [Unreleased]
|
|
14
|
-
|
|
15
|
-
### Changed
|
|
16
|
-
|
|
17
|
-
- raised the minimum Node.js version to `>=22` and expanded CI coverage to
|
|
18
|
-
Node 24
|
|
19
|
-
- refreshed the router starter dependency baseline to the current
|
|
20
|
-
`@koppajs/koppajs-core`, `@koppajs/koppajs-vite-plugin`, and
|
|
21
|
-
`@koppajs/koppajs-router` releases
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## [1.0.0] — Initial Starter Baseline
|
|
26
|
-
|
|
27
|
-
**2026-03-17**
|
|
28
|
-
|
|
29
|
-
### Added
|
|
30
|
-
|
|
31
|
-
- a small KoppaJS router app shell with `app-view`, `home-page`,
|
|
32
|
-
`router-page`, `not-found-page`, and `counter-component`
|
|
33
|
-
- route-based rendering through `@koppajs/koppajs-router`
|
|
34
|
-
- ESLint, Prettier, Vitest, Playwright, Husky, lint-staged, and commitlint
|
|
35
|
-
- starter governance docs, ADRs, specs, and release workflow files
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Versioning Policy
|
|
40
|
-
|
|
41
|
-
- Semantic Versioning (SemVer) is followed pragmatically
|
|
42
|
-
- **Breaking changes** include:
|
|
43
|
-
- public runtime behavior changes
|
|
44
|
-
- route structure changes
|
|
45
|
-
- release workflow changes
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
_This changelog documents intent.
|
|
50
|
-
If something is not written here, it is not guaranteed._
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Development Rules
|
|
2
|
-
|
|
3
|
-
## Scope
|
|
4
|
-
|
|
5
|
-
These rules describe how code and documentation are expected to evolve in this repository.
|
|
6
|
-
|
|
7
|
-
## Source layout rules
|
|
8
|
-
|
|
9
|
-
- Keep `index.html` as a static shell with asset references and the single root element.
|
|
10
|
-
- Keep `src/main.ts` limited to bootstrap concerns: imports, `Core.take(...)`
|
|
11
|
-
registrations, route definitions, and initialization of the single router instance.
|
|
12
|
-
- Use `.kpa` files for UI composition, local component state, and component-scoped CSS.
|
|
13
|
-
- Keep the route outlet inside `app-view.kpa` and keep route rendering consumer-owned.
|
|
14
|
-
- If logic becomes reusable, asynchronous, or branch-heavy, move it into `.ts` modules under `src/`.
|
|
15
|
-
- Keep `public/` for static assets only.
|
|
16
|
-
|
|
17
|
-
## Naming conventions
|
|
18
|
-
|
|
19
|
-
- Custom element names must be kebab-case.
|
|
20
|
-
- Root-level application components should use `app-` prefixes when they represent app shells or app-wide structure.
|
|
21
|
-
- Route component filenames should match their registered component tags or route purpose.
|
|
22
|
-
- New files and folders should use descriptive names over abbreviations.
|
|
23
|
-
|
|
24
|
-
## Dependency rules
|
|
25
|
-
|
|
26
|
-
- Runtime dependencies must be justified by a concrete need in a spec or ADR.
|
|
27
|
-
- Prefer browser APIs and KoppaJS primitives before adding helper libraries.
|
|
28
|
-
- Keep this repository wired to published npm packages unless there is an explicit ADR stating otherwise.
|
|
29
|
-
- Build tooling changes must update contributor docs and architecture docs in the same change.
|
|
30
|
-
- Quality tooling must stay proportionate to the starter.
|
|
31
|
-
|
|
32
|
-
## Coding patterns
|
|
33
|
-
|
|
34
|
-
- Favor simple, local state over premature abstraction.
|
|
35
|
-
- Keep route definitions obvious and close to router initialization.
|
|
36
|
-
- Avoid hidden side effects during import.
|
|
37
|
-
- Keep CSS local to components unless the style truly applies application-wide.
|
|
38
|
-
- Preserve strict TypeScript settings; do not weaken `tsconfig.json` to work around errors.
|
|
39
|
-
- Give interactive controls stable accessible names so smoke tests can target public semantics instead of brittle selectors.
|
|
40
|
-
|
|
41
|
-
## Forbidden without a spec and ADR
|
|
42
|
-
|
|
43
|
-
- Replacing the starter's single-router model with a second navigation system
|
|
44
|
-
- Adding global state containers
|
|
45
|
-
- Adding network or persistence layers
|
|
46
|
-
- Introducing SSR, multi-page bootstraps, or multiple root entries
|
|
47
|
-
- Switching dependency sourcing from npm packages to local monorepo links
|
|
48
|
-
- Expanding the starter into a feature-rich demo application
|
|
49
|
-
- Adding heavyweight hooks that run the entire suite on every commit
|
|
50
|
-
|
|
51
|
-
## Documentation obligations
|
|
52
|
-
|
|
53
|
-
- Update [ARCHITECTURE.md](./ARCHITECTURE.md) when source layout or runtime flow changes.
|
|
54
|
-
- Update [TESTING_STRATEGY.md](./TESTING_STRATEGY.md) when quality gates or tooling change.
|
|
55
|
-
- Update or create a spec in [docs/specs](./docs/specs) for user-visible changes.
|
|
56
|
-
- Add an ADR in [docs/adr](./docs/adr) for durable technical decisions.
|
|
57
|
-
- Update [docs/quality/quality-gates.md](./docs/quality/quality-gates.md) when scripts, hooks, CI checks, or browser-smoke expectations change.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# Roadmap
|
|
2
|
-
|
|
3
|
-
This roadmap describes intended directions, not guaranteed delivery dates.
|
|
4
|
-
|
|
5
|
-
## Current priorities
|
|
6
|
-
|
|
7
|
-
- Keep the router starter focused and production-like.
|
|
8
|
-
- Preserve a clear bootstrap path for new KoppaJS users.
|
|
9
|
-
- Keep the meta layer synchronized with the actual repository.
|
|
10
|
-
|
|
11
|
-
## Near-term opportunities
|
|
12
|
-
|
|
13
|
-
- Add route-level examples only when they demonstrate a real starter need.
|
|
14
|
-
- Strengthen route-related tests if the starter gains redirects, params, or nested routes.
|
|
15
|
-
- Keep documentation aligned with the actual router wiring.
|
|
16
|
-
|
|
17
|
-
## Longer-term expansion triggers
|
|
18
|
-
|
|
19
|
-
These should happen only with a spec and ADR:
|
|
20
|
-
|
|
21
|
-
- async data fetching
|
|
22
|
-
- persistence
|
|
23
|
-
- richer route hierarchies
|
|
24
|
-
- shared state beyond local component state
|
|
25
|
-
- CI automation changes
|
|
26
|
-
|
|
27
|
-
## Meta-layer maintenance
|
|
28
|
-
|
|
29
|
-
Every release or architecture-changing change should answer:
|
|
30
|
-
|
|
31
|
-
- Does the architecture document still match the code?
|
|
32
|
-
- Did any new decision deserve an ADR?
|
|
33
|
-
- Did testing expectations change?
|
|
34
|
-
- Did contributor instructions stay accurate?
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Testing Strategy
|
|
2
|
-
|
|
3
|
-
## Current state
|
|
4
|
-
|
|
5
|
-
This repository carries a small automated testing stack aligned with the router starter's actual risk profile:
|
|
6
|
-
|
|
7
|
-
- `pnpm test:run` for unit and integration tests in Vitest
|
|
8
|
-
- `pnpm test:coverage` for local coverage reporting
|
|
9
|
-
- `pnpm test:e2e` for a Playwright smoke test against `vite preview`
|
|
10
|
-
- `pnpm check` for the fast repository baseline
|
|
11
|
-
- `pnpm validate` for the full local and CI validation path
|
|
12
|
-
- `pnpm release:check` for tagged release candidates
|
|
13
|
-
- `commitlint` through `.husky/commit-msg` for commit message validation
|
|
14
|
-
|
|
15
|
-
## Philosophy
|
|
16
|
-
|
|
17
|
-
- Test the smallest meaningful unit that gives confidence.
|
|
18
|
-
- Prefer extracting logic into `.ts` modules when it becomes complex enough to warrant focused unit tests.
|
|
19
|
-
- Avoid brittle tests that mirror implementation details instead of observable behavior.
|
|
20
|
-
- Reuse the real Vite loading path in automated tests whenever `.kpa` handling is part of the risk surface.
|
|
21
|
-
|
|
22
|
-
## Test pyramid for this repository
|
|
23
|
-
|
|
24
|
-
### Unit tests
|
|
25
|
-
|
|
26
|
-
Use unit tests for isolated logic that can fail independently of the browser runtime.
|
|
27
|
-
|
|
28
|
-
### Integration or component tests
|
|
29
|
-
|
|
30
|
-
Use integration tests when bootstrap, component registration, and router startup
|
|
31
|
-
must be verified together but a full browser run would be disproportionate.
|
|
32
|
-
|
|
33
|
-
Typical triggers:
|
|
34
|
-
|
|
35
|
-
- bootstrap registration in `src/main.ts`
|
|
36
|
-
- router startup wiring and route table shape
|
|
37
|
-
- build-time behavior that depends on the Vite plugin
|
|
38
|
-
|
|
39
|
-
### End-to-end tests
|
|
40
|
-
|
|
41
|
-
Keep Playwright intentionally user-facing and smoke-level.
|
|
42
|
-
|
|
43
|
-
Typical triggers:
|
|
44
|
-
|
|
45
|
-
- root UI rendering
|
|
46
|
-
- route navigation between starter pages
|
|
47
|
-
- critical starter interactions such as the counter behavior
|
|
48
|
-
- preview/build regressions that would not be caught by Vitest alone
|
|
49
|
-
|
|
50
|
-
## Coverage expectations
|
|
51
|
-
|
|
52
|
-
- There is no blanket repository percentage target right now.
|
|
53
|
-
- New non-trivial logic should come with focused tests.
|
|
54
|
-
- When a subsystem introduces more branching logic, async behavior, or shared state, test automation stops being optional.
|
|
55
|
-
|
|
56
|
-
## Quality gates by change size
|
|
57
|
-
|
|
58
|
-
- Documentation-only change: verify links and document consistency.
|
|
59
|
-
- Small style or copy change: run `pnpm check`.
|
|
60
|
-
- Source or config change: run `pnpm check`.
|
|
61
|
-
- UI, bootstrap, or browser-sensitive change: run `pnpm validate`.
|
|
62
|
-
- Version, changelog, or release workflow change: run `pnpm release:check`.
|
|
63
|
-
|
|
64
|
-
## Maintenance rule
|
|
65
|
-
|
|
66
|
-
Whenever test tooling, quality gates, or expected confidence levels change,
|
|
67
|
-
update this file and [docs/quality/quality-gates.md](./docs/quality/quality-gates.md) in the same change.
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# ADR 0001: Keep the router starter focused
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
This repository starts from the maintained KoppaJS router starter baseline.
|
|
6
|
-
Its audience needs a runnable reference that demonstrates routing without
|
|
7
|
-
turning into a broad showcase application.
|
|
8
|
-
|
|
9
|
-
## Decision
|
|
10
|
-
|
|
11
|
-
The router starter remains intentionally small:
|
|
12
|
-
|
|
13
|
-
- one HTML shell,
|
|
14
|
-
- one TypeScript bootstrap file,
|
|
15
|
-
- one root KoppaJS view,
|
|
16
|
-
- one router instance,
|
|
17
|
-
- two primary routes plus one explicit fallback route,
|
|
18
|
-
- one stateful child component,
|
|
19
|
-
- published npm packages instead of local monorepo `file:` dependencies.
|
|
20
|
-
|
|
21
|
-
Any expansion beyond that baseline requires a spec and ADR.
|
|
22
|
-
|
|
23
|
-
## Consequences
|
|
24
|
-
|
|
25
|
-
- New users get a fast example of routing without a lot of incidental complexity.
|
|
26
|
-
- The repository stays easy to audit and maintain.
|
|
27
|
-
- More advanced route features must be introduced deliberately rather than accumulating ad hoc.
|
|
28
|
-
|
|
29
|
-
## Alternatives considered
|
|
30
|
-
|
|
31
|
-
- A feature-rich demo app that showcases many KoppaJS patterns at once
|
|
32
|
-
- A monorepo-linked starter that depends on local sibling packages
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Module Boundaries
|
|
2
|
-
|
|
3
|
-
## Repository boundary model
|
|
4
|
-
|
|
5
|
-
This repository is intentionally shallow. Its boundaries keep the starter easy to inspect.
|
|
6
|
-
|
|
7
|
-
| Path | Responsibility | Allowed dependencies | Must not depend on |
|
|
8
|
-
| --------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------- |
|
|
9
|
-
| `index.html` | Document shell, root element, asset references | Static assets, `src/main.ts`, `src/style.css` | Feature logic, router setup, extra scripts |
|
|
10
|
-
| `src/main.ts` | Application bootstrap, component registration, and router startup | `@koppajs/koppajs-core`, `@koppajs/koppajs-router`, local `.kpa` modules | Page copy, route component visuals, unrelated state |
|
|
11
|
-
| `src/app-view.kpa` | Shared shell, primary navigation, and route outlet | Local markup, local CSS | Route matching, component registration |
|
|
12
|
-
| `src/home-page.kpa` | Landing-route content and counter composition | Local markup, local CSS, `counter-component` | Router setup or global shell orchestration |
|
|
13
|
-
| `src/router-page.kpa` | Second-route content | Local markup and local CSS | Bootstrap or route resolution concerns |
|
|
14
|
-
| `src/not-found-page.kpa` | Explicit fallback-route content | Local markup and local CSS | Route matching rules or global state |
|
|
15
|
-
| `src/counter-component.kpa` | Example local state and interaction | Local markup, local methods, local CSS | Route orchestration or app-shell concerns |
|
|
16
|
-
| `src/style.css` | Global tokens and truly global base rules | Standard CSS | Route-specific or component-specific visual rules |
|
|
17
|
-
| `tests/integration/` | Bootstrap and router boundary verification | Vitest, local modules, selective mocks | Browser-only smoke assertions |
|
|
18
|
-
| `tests/e2e/` | Real-browser smoke coverage | Playwright, preview server | Implementation-detail assertions |
|
|
19
|
-
| `vite.config.mjs` | Build and dev server integration | Vite and the KoppaJS Vite plugin | Application runtime logic |
|
|
20
|
-
|
|
21
|
-
## Boundary rules
|
|
22
|
-
|
|
23
|
-
- Registration and route configuration happen in `src/main.ts`.
|
|
24
|
-
- `app-view.kpa` may compose navigation and the outlet but must not become a second router.
|
|
25
|
-
- Route components own their own copy and layout.
|
|
26
|
-
- Shared logic belongs in dedicated `.ts` modules once reuse or complexity justifies it.
|
|
27
|
-
- Vitest owns helper-level and bootstrap-level confidence; Playwright owns browser smoke confidence.
|
|
28
|
-
|
|
29
|
-
## Escalation rules
|
|
30
|
-
|
|
31
|
-
Before crossing existing boundaries, add a spec and ADR if the change introduces:
|
|
32
|
-
|
|
33
|
-
- nested or parameterized routing beyond the current baseline,
|
|
34
|
-
- shared state,
|
|
35
|
-
- async workflows,
|
|
36
|
-
- persistence,
|
|
37
|
-
- more than one root entrypoint,
|
|
38
|
-
- npm publishing or deployment automation,
|
|
39
|
-
- new top-level source folders.
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Meta-Layer Maintenance
|
|
2
|
-
|
|
3
|
-
The meta layer is a living system. Any change that alters the real system must update the corresponding governance document in the same change.
|
|
4
|
-
|
|
5
|
-
## Update matrix
|
|
6
|
-
|
|
7
|
-
| Change | Required updates |
|
|
8
|
-
| ------------------------------------------ | ---------------------------------------------------------------------------------------------- |
|
|
9
|
-
| New feature or behavior | Add or update a spec in `docs/specs/`; update `README.md` if setup or visible behavior changes |
|
|
10
|
-
| New enduring technical decision | Add or update an ADR in `docs/adr/` |
|
|
11
|
-
| New module, folder, or data flow | Update `ARCHITECTURE.md` and `docs/architecture/module-boundaries.md` |
|
|
12
|
-
| New coding pattern or dependency rule | Update `DEVELOPMENT_RULES.md` |
|
|
13
|
-
| New test tooling or quality gate | Update `TESTING_STRATEGY.md` and `docs/quality/quality-gates.md` |
|
|
14
|
-
| New hook, CI step, or contributor workflow | Update `CONTRIBUTING.md` and `.github/instructions/ai-workflow.md` |
|
|
15
|
-
| Version, changelog, or release workflow | Update `CHANGELOG.md`, `RELEASE.md`, `package.json`, and affected GitHub workflow files |
|
|
16
|
-
|
|
17
|
-
## Review triggers
|
|
18
|
-
|
|
19
|
-
Perform a meta-layer review when:
|
|
20
|
-
|
|
21
|
-
- a pull request changes the repo structure,
|
|
22
|
-
- a new dependency is added,
|
|
23
|
-
- a public component tag changes,
|
|
24
|
-
- a build or test command changes,
|
|
25
|
-
- a hook or CI workflow changes,
|
|
26
|
-
- the routing model or route surface changes,
|
|
27
|
-
- a README section no longer matches the actual code.
|
|
28
|
-
|
|
29
|
-
## Periodic review checklist
|
|
30
|
-
|
|
31
|
-
- Does [ARCHITECTURE.md](../../ARCHITECTURE.md) still match the runtime flow?
|
|
32
|
-
- Do current specs cover the user-visible behaviors in the repo?
|
|
33
|
-
- Do ADRs still represent active decisions?
|
|
34
|
-
- Do contributor instructions still match the actual toolchain?
|
|
35
|
-
- Did a recent change deserve a new quality gate?
|
|
36
|
-
- Do `CHANGELOG.md`, `RELEASE.md`, and the release workflow still match actual branch and tag practice?
|
|
37
|
-
|
|
38
|
-
If any answer is "no", update the meta layer before considering the repository aligned.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Specifications
|
|
2
|
-
|
|
3
|
-
Specs define expected behavior before or alongside implementation. They are the highest-precedence project documents.
|
|
4
|
-
|
|
5
|
-
## When a spec is required
|
|
6
|
-
|
|
7
|
-
Create or update a spec when a change:
|
|
8
|
-
|
|
9
|
-
- introduces or changes user-visible behavior,
|
|
10
|
-
- adds a subsystem,
|
|
11
|
-
- changes public setup or bootstrap behavior,
|
|
12
|
-
- changes a feature in a way that needs explicit acceptance criteria.
|
|
13
|
-
|
|
14
|
-
## Current specs
|
|
15
|
-
|
|
16
|
-
- [`app-bootstrap.md`](./app-bootstrap.md)
|
|
17
|
-
- [`counter-component.md`](./counter-component.md)
|
|
18
|
-
- [`router-navigation.md`](./router-navigation.md)
|
|
19
|
-
- [`quality-workflow.md`](./quality-workflow.md)
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Spec: App bootstrap
|
|
2
|
-
|
|
3
|
-
## Status
|
|
4
|
-
|
|
5
|
-
Approved
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Provide a predictable startup path for a KoppaJS application that includes the official router runtime.
|
|
10
|
-
|
|
11
|
-
## Behavior
|
|
12
|
-
|
|
13
|
-
- The application starts from `index.html`.
|
|
14
|
-
- The HTML shell loads one global stylesheet and one module entrypoint.
|
|
15
|
-
- The document declares exactly one root custom element: `<app-view>`.
|
|
16
|
-
- `src/main.ts` registers `app-view`, `home-page`, `router-page`, `not-found-page`, and `counter-component` with KoppaJS Core.
|
|
17
|
-
- `src/main.ts` invokes `Core()` once and starts one `KoppajsRouter` instance.
|
|
18
|
-
|
|
19
|
-
## Inputs
|
|
20
|
-
|
|
21
|
-
- Browser loading `index.html`
|
|
22
|
-
- Static asset and source file paths resolved by Vite
|
|
23
|
-
|
|
24
|
-
## Outputs
|
|
25
|
-
|
|
26
|
-
- A rendered `<app-view>` application shell
|
|
27
|
-
- A rendered route component inside `#app-outlet`
|
|
28
|
-
- A registered `<counter-component>` available to the home route
|
|
29
|
-
|
|
30
|
-
## Constraints
|
|
31
|
-
|
|
32
|
-
- There must be a single bootstrap entrypoint.
|
|
33
|
-
- The root tag in `index.html` must stay aligned with the component registered in `src/main.ts`.
|
|
34
|
-
- `Core()` must remain the only KoppaJS bootstrap call.
|
|
35
|
-
- Router initialization must happen after the route outlet exists.
|
|
36
|
-
- No extra runtime dependencies are required beyond the declared npm packages.
|
|
37
|
-
|
|
38
|
-
## Acceptance criteria
|
|
39
|
-
|
|
40
|
-
- Opening the app through Vite renders the root view without manual DOM scripting.
|
|
41
|
-
- `src/main.ts` remains the only location that calls `Core()`.
|
|
42
|
-
- The route outlet is initialized by the router and can render the home route immediately after bootstrap.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Spec: Router navigation
|
|
2
|
-
|
|
3
|
-
## Status
|
|
4
|
-
|
|
5
|
-
Approved
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Define the starter's router baseline so the generated project demonstrates a small but real navigation flow.
|
|
10
|
-
|
|
11
|
-
## Behavior
|
|
12
|
-
|
|
13
|
-
- The starter initializes one `KoppajsRouter` instance from `src/main.ts`.
|
|
14
|
-
- The router renders matched route components into `#app-outlet`.
|
|
15
|
-
- Primary navigation links use `data-route` and participate in active-link state updates.
|
|
16
|
-
- The starter includes a home route, a second content route, and an explicit `*` fallback route.
|
|
17
|
-
|
|
18
|
-
## Inputs
|
|
19
|
-
|
|
20
|
-
- Route definitions declared in `src/main.ts`
|
|
21
|
-
- Browser URL and History API state
|
|
22
|
-
- User clicks on matching `data-route` links
|
|
23
|
-
|
|
24
|
-
## Outputs
|
|
25
|
-
|
|
26
|
-
- URL changes that stay aligned with the rendered route component
|
|
27
|
-
- Active navigation state on the current route link
|
|
28
|
-
- A predictable not-found page for unmatched paths
|
|
29
|
-
|
|
30
|
-
## Constraints
|
|
31
|
-
|
|
32
|
-
- The route table must stay small and inspectable.
|
|
33
|
-
- The fallback route must be explicit rather than implicit.
|
|
34
|
-
- Route content stays in consumer-owned `.kpa` files, not inside the router package.
|
|
35
|
-
|
|
36
|
-
## Acceptance criteria
|
|
37
|
-
|
|
38
|
-
- Visiting `/` renders the home route.
|
|
39
|
-
- Visiting `/router` renders the second route.
|
|
40
|
-
- Visiting an unmatched path renders the fallback route.
|
|
41
|
-
- The active navigation link exposes `aria-current="page"` for the current route.
|