docs: add package introductions and the @robonen/crdt guide
An intro.vue landing for all 12 packages, plus a multi-section crdt guide (Concepts, Primitives, Replication & Sync, and an interactive convergence Playground).
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
<script setup lang="ts">
|
||||
const usageExample = `import { compose, base, typescript, vue, vitest, imports } from '@robonen/eslint';
|
||||
|
||||
// eslint.config.ts
|
||||
export default compose(base, typescript, vue, vitest, imports);`;
|
||||
|
||||
const overrideExample = `import { compose, base, typescript } from '@robonen/eslint';
|
||||
|
||||
export default compose(base, typescript, {
|
||||
// later entries override earlier ones
|
||||
rules: { 'no-console': 'off' },
|
||||
});`;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="docs-section">
|
||||
<div class="prose-docs">
|
||||
<h1>@robonen/eslint</h1>
|
||||
<p class="text-lg text-(--fg-muted)">
|
||||
Composable ESLint flat-config presets — assemble a linting setup from
|
||||
small, focused building blocks instead of one monolithic config.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Modern ESLint flat config is just an ordered array of config objects, but
|
||||
wiring up plugins, parsers, and rule sets by hand is repetitive and easy
|
||||
to get wrong. <code>@robonen/eslint</code> ships a curated set of presets
|
||||
— <code>base</code>, <code>typescript</code>, <code>vue</code>,
|
||||
<code>vitest</code>, <code>imports</code>, <code>node</code>,
|
||||
<code>regexp</code>, and <code>stylistic</code> — and a single
|
||||
<code>compose()</code> helper that flattens them into one config array.
|
||||
Pick the presets your project needs, layer your own overrides on top, and
|
||||
you have a consistent, type-safe lint setup in a few lines.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Composable presets</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
Mix and match focused presets per language and tool. Each preset is a
|
||||
plain flat-config array — no magic, no hidden state.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Override-friendly</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
Append inline config objects after presets. Later entries win, exactly
|
||||
as ESLint flat-config semantics intend.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Conditional by design</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>compose()</code> skips <code>false</code>/<code>null</code>/<code>undefined</code>
|
||||
entries, so feature flags and conditional spreads just work.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Typed flat config</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
Exported <code>FlatConfig</code> and <code>Rules</code> types give you
|
||||
editor autocomplete and type-checked overrides in
|
||||
<code>eslint.config.ts</code>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Install</h2>
|
||||
<p>
|
||||
Install the package alongside ESLint and <code>jiti</code> (so ESLint can
|
||||
load a TypeScript <code>eslint.config.ts</code>).
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="`pnpm add -D @robonen/eslint eslint jiti`" lang="bash" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Usage</h2>
|
||||
<p>
|
||||
Create <code>eslint.config.ts</code> in your project root and compose the
|
||||
presets you want:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="usageExample" lang="ts" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Add inline config objects after the presets to tweak rules — later
|
||||
entries override earlier ones:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="overrideExample" lang="ts" />
|
||||
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-elevated) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-2">Where to next</h3>
|
||||
<ul class="text-sm text-(--fg-muted) space-y-1.5 list-disc pl-5 m-0">
|
||||
<li>
|
||||
<NuxtLink to="/eslint/overview" class="text-(--accent-text) hover:underline">compose</NuxtLink>
|
||||
— flatten presets and overrides into one config array.
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/eslint/base" class="text-(--accent-text) hover:underline">base</NuxtLink>
|
||||
— core ESLint, unicorn, regexp rules and global ignores.
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/eslint/typescript" class="text-(--accent-text) hover:underline">typescript</NuxtLink>
|
||||
and
|
||||
<NuxtLink to="/eslint/vue" class="text-(--accent-text) hover:underline">vue</NuxtLink>
|
||||
— language presets for TS and Vue 3 SFCs.
|
||||
</li>
|
||||
<li>
|
||||
Read the guide sections below for the full preset table and migration
|
||||
notes from <code>@robonen/oxlint</code>.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,154 @@
|
||||
<script setup lang="ts">
|
||||
const nodeExample = `// Node / isomorphic library
|
||||
{ "extends": "@robonen/tsconfig/tsconfig.base.json" }`;
|
||||
|
||||
const vueExample = `// Vue package, with path aliases
|
||||
{
|
||||
"extends": "@robonen/tsconfig/tsconfig.vue.json",
|
||||
"compilerOptions": {
|
||||
"paths": { "@/*": ["./src/*"] }
|
||||
}
|
||||
}`;
|
||||
|
||||
const splitExample = `// tsconfig.json — solution root
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.src.json" }, // extends tsconfig.dom.json
|
||||
{ "path": "./tsconfig.node.json" } // *.config.ts, types: ["node"]
|
||||
]
|
||||
}`;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="docs-section">
|
||||
<div class="prose-docs">
|
||||
<h1>@robonen/tsconfig</h1>
|
||||
<p class="text-lg text-(--fg-muted)">
|
||||
Shared, strict TypeScript configurations — a small set of layered
|
||||
presets you extend instead of copying compiler options between packages.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Every package in a monorepo wants the same modern, strict TypeScript
|
||||
baseline, but keeping a dozen <code>tsconfig.json</code> files in sync by
|
||||
hand drifts almost immediately. <code>@robonen/tsconfig</code> ships one
|
||||
carefully tuned <code>base</code> config and three environment layers
|
||||
— <code>dom</code>, <code>vue</code>, and <code>node</code> — that extend
|
||||
it. Point your package's <code>extends</code> at the right preset and you
|
||||
inherit a consistent, bundler-first, type-check-only setup with no local
|
||||
compiler options to maintain.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Layered presets</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>base</code> → <code>dom</code> → <code>vue</code>, plus
|
||||
a sibling <code>node</code> layer. Extend the one that matches the
|
||||
environment; everything else is inherited.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Strict by default</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>strict</code> plus <code>noUncheckedIndexedAccess</code>,
|
||||
<code>noImplicitOverride</code>, <code>noImplicitReturns</code> and
|
||||
<code>noFallthroughCasesInSwitch</code> are on out of the box.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Bundler-first</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>module: Preserve</code> with <code>Bundler</code> resolution,
|
||||
<code>verbatimModuleSyntax</code> and <code>isolatedModules</code>.
|
||||
Emit is <code>noEmit</code> — declarations come from
|
||||
<code>tsdown</code>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Env isolation</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
Browser <code>src</code> (DOM, no Node globals) and tooling files
|
||||
(<code>node</code> types, no DOM) split into separate projects wired
|
||||
with project references.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Install</h2>
|
||||
<p>
|
||||
Add the package as a dev dependency. It ships only JSON presets — no
|
||||
runtime code.
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="`pnpm add -D @robonen/tsconfig`" lang="bash" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Usage</h2>
|
||||
<p>
|
||||
Pick the preset that matches the package and extend it from your
|
||||
<code>tsconfig.json</code>:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="nodeExample" lang="json" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Vue SFC packages extend the <code>vue</code> layer (adds
|
||||
<code>jsx: preserve</code> and strict
|
||||
<code>vueCompilerOptions</code>) and can declare path aliases inline:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="vueExample" lang="json" />
|
||||
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-inset) p-4">
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<strong class="text-(--fg)">Note:</strong> path aliases resolve relative
|
||||
to the <code class="text-(--fg)">tsconfig.json</code> location —
|
||||
<code class="text-(--fg)">baseUrl</code> is intentionally omitted
|
||||
(deprecated, removed in TypeScript 7.0).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>DOM + Node split</h2>
|
||||
<p>
|
||||
Most packages mix browser <code>src</code> with Node tooling files
|
||||
(<code>vite.config.ts</code>, <code>vitest.config.ts</code>,
|
||||
<code>tsdown.config.ts</code>). Split them into two projects wired with
|
||||
references so <code>src</code> never sees Node globals and config files
|
||||
never see <code>DOM</code>, then type-check the whole package with
|
||||
<code>tsc -b</code> / <code>vue-tsc -b</code>:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="splitExample" lang="json" />
|
||||
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-elevated) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-2">Where to next</h3>
|
||||
<ul class="text-sm text-(--fg-muted) space-y-1.5 list-disc pl-5 m-0">
|
||||
<li>
|
||||
<strong class="text-(--fg)">Presets</strong> — the full table of
|
||||
<code>base</code>, <code>dom</code>, <code>vue</code> and
|
||||
<code>node</code>, with what each layer adds.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="text-(--fg)">Project references</strong> — the complete
|
||||
DOM + Node split with <code>composite</code> and
|
||||
<code>tsBuildInfoFile</code> wiring.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="text-(--fg)">What's included</strong> — the exact
|
||||
compiler options the <code>base</code> preset turns on.
|
||||
</li>
|
||||
<li>
|
||||
See the guide sections in the sidebar for each of the above.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,121 @@
|
||||
<script setup lang="ts">
|
||||
const usageExample = `import { defineConfig } from 'tsdown';
|
||||
import { sharedConfig } from '@robonen/tsdown';
|
||||
|
||||
export default defineConfig({
|
||||
...sharedConfig,
|
||||
tsconfig: './tsconfig.src.json',
|
||||
entry: ['src/index.ts'],
|
||||
});`;
|
||||
|
||||
const overrideExample = `import { defineConfig } from 'tsdown';
|
||||
import { sharedConfig } from '@robonen/tsdown';
|
||||
import Vue from 'unplugin-vue/rolldown';
|
||||
|
||||
export default defineConfig({
|
||||
...sharedConfig,
|
||||
entry: ['src/index.ts', 'src/*/index.ts'],
|
||||
plugins: [Vue({ isProduction: true })],
|
||||
// layer on top of the shared defaults
|
||||
dts: { vue: true },
|
||||
});`;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="docs-section">
|
||||
<div class="prose-docs">
|
||||
<h1>@robonen/tsdown</h1>
|
||||
<p class="text-lg text-(--fg-muted)">
|
||||
Shared tsdown build configuration for every <code>@robonen</code>
|
||||
package — one source of truth for output formats, declarations, and
|
||||
bundle hygiene.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Every library in this monorepo ships dual ESM/CJS builds with type
|
||||
declarations, a clean <code>dist</code>, and a consistent license
|
||||
banner. Re-declaring that in each package's
|
||||
<code>tsdown.config.ts</code> is repetitive and drifts over time.
|
||||
<code>@robonen/tsdown</code> exports a single
|
||||
<code>sharedConfig</code> object you spread into
|
||||
<code>defineConfig</code>, then add only what is package-specific —
|
||||
usually just <code>entry</code> and <code>tsconfig</code>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Dual ESM + CJS</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
Emits both <code>esm</code> and <code>cjs</code> formats so packages
|
||||
work in modern bundlers and legacy <code>require</code> setups alike.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Types included</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>dts: true</code> generates <code>.d.ts</code> declarations on
|
||||
every build — no separate type pipeline to maintain.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Clean, stable output</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
<code>clean: true</code> wipes <code>dist</code> first and
|
||||
<code>hash: false</code> keeps file names deterministic for
|
||||
predictable publishing.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-subtle) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-1.5">Spread & override</h3>
|
||||
<p class="text-sm text-(--fg-muted) m-0">
|
||||
It is a plain object typed as <code>InlineConfig</code> — spread it,
|
||||
override any field, and let editor autocomplete guide you.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Install</h2>
|
||||
<p>
|
||||
Add the config package and <code>tsdown</code> itself as dev
|
||||
dependencies:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="`pnpm add -D @robonen/tsdown tsdown`" lang="bash" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<h2>Usage</h2>
|
||||
<p>
|
||||
Create <code>tsdown.config.ts</code> in your package, spread
|
||||
<code>sharedConfig</code>, and supply your entry points:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="usageExample" lang="ts" />
|
||||
|
||||
<div class="prose-docs">
|
||||
<p>
|
||||
Because <code>sharedConfig</code> is a normal object, you can override
|
||||
or extend any field after spreading — add plugins, extra entries, or
|
||||
tweak the declaration options:
|
||||
</p>
|
||||
</div>
|
||||
<DocsCode :code="overrideExample" lang="ts" />
|
||||
|
||||
<div class="rounded-lg border border-(--border) bg-(--bg-elevated) p-5">
|
||||
<h3 class="font-medium text-(--fg) mb-2">Where to next</h3>
|
||||
<ul class="text-sm text-(--fg-muted) space-y-1.5 list-disc pl-5 m-0">
|
||||
<li>
|
||||
<NuxtLink to="/tsdown/overview" class="text-(--accent-text) hover:underline">sharedConfig</NuxtLink>
|
||||
— the full list of defaults and their exact values.
|
||||
</li>
|
||||
<li>
|
||||
Read the guide sections below for the conventions baked into the
|
||||
shared build and tips for package-specific overrides.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user