JSPM

  • Created
  • Published
  • Downloads 216
  • Score
    100M100P100Q96185F
  • License MPL-2.0

Mandu Framework Core - Spec, Generator, Guard, Runtime

Package Exports

  • @mandujs/core
  • @mandujs/core/a11y
  • @mandujs/core/agent
  • @mandujs/core/auth
  • @mandujs/core/auth/login
  • @mandujs/core/auth/password
  • @mandujs/core/auth/reset
  • @mandujs/core/auth/verification
  • @mandujs/core/bundler
  • @mandujs/core/bundler/analyzer
  • @mandujs/core/bundler/budget
  • @mandujs/core/bundler/generate-static-params
  • @mandujs/core/bundler/hmr-types
  • @mandujs/core/bundler/manifest-schema
  • @mandujs/core/bundler/plugins
  • @mandujs/core/bundler/plugins/block-generated-imports
  • @mandujs/core/bundler/prerender
  • @mandujs/core/bundler/safe-build
  • @mandujs/core/bundler/scenario-matrix
  • @mandujs/core/bundler/types
  • @mandujs/core/bundler/vendor-cache-types
  • @mandujs/core/client
  • @mandujs/core/client/hydrate
  • @mandujs/core/client/rpc
  • @mandujs/core/components/Image
  • @mandujs/core/config
  • @mandujs/core/config/mandu
  • @mandujs/core/config/validate
  • @mandujs/core/content
  • @mandujs/core/content/collection
  • @mandujs/core/content/llms-txt
  • @mandujs/core/content/prebuild
  • @mandujs/core/content/schema
  • @mandujs/core/content/sidebar
  • @mandujs/core/content/slug
  • @mandujs/core/contract
  • @mandujs/core/contract/rpc
  • @mandujs/core/db
  • @mandujs/core/db/migrations
  • @mandujs/core/db/migrations/history-table
  • @mandujs/core/db/migrations/runner
  • @mandujs/core/deploy
  • @mandujs/core/design
  • @mandujs/core/desktop
  • @mandujs/core/desktop/worker
  • @mandujs/core/dev-error-overlay
  • @mandujs/core/diagnose
  • @mandujs/core/email
  • @mandujs/core/error
  • @mandujs/core/filling
  • @mandujs/core/filling/cookie-codec
  • @mandujs/core/filling/session-sqlite
  • @mandujs/core/guard
  • @mandujs/core/guard/define-rule
  • @mandujs/core/guard/design-inline-class
  • @mandujs/core/guard/rule-presets
  • @mandujs/core/guard/tsgolint-bridge
  • @mandujs/core/i18n
  • @mandujs/core/id
  • @mandujs/core/kitchen
  • @mandujs/core/logging
  • @mandujs/core/middleware
  • @mandujs/core/middleware/bridge
  • @mandujs/core/middleware/compose
  • @mandujs/core/middleware/csrf
  • @mandujs/core/middleware/define
  • @mandujs/core/middleware/oauth
  • @mandujs/core/middleware/rate-limit
  • @mandujs/core/middleware/secure
  • @mandujs/core/middleware/session
  • @mandujs/core/observability
  • @mandujs/core/openapi/generator
  • @mandujs/core/perf
  • @mandujs/core/perf/hmr-markers
  • @mandujs/core/perf/user-marks
  • @mandujs/core/plugins
  • @mandujs/core/plugins/define
  • @mandujs/core/plugins/runner
  • @mandujs/core/resource
  • @mandujs/core/resource/ddl/diff
  • @mandujs/core/resource/ddl/emit
  • @mandujs/core/resource/ddl/snapshot
  • @mandujs/core/resource/ddl/type-map
  • @mandujs/core/resource/ddl/types
  • @mandujs/core/resource/generator-repo
  • @mandujs/core/resource/parser
  • @mandujs/core/resource/schema
  • @mandujs/core/router
  • @mandujs/core/routes
  • @mandujs/core/runtime
  • @mandujs/core/runtime/cache
  • @mandujs/core/runtime/fast-refresh-types
  • @mandujs/core/runtime/router
  • @mandujs/core/runtime/server
  • @mandujs/core/scheduler
  • @mandujs/core/storage/s3
  • @mandujs/core/testing
  • @mandujs/core/testing/db
  • @mandujs/core/testing/mocks
  • @mandujs/core/testing/reporter
  • @mandujs/core/testing/server
  • @mandujs/core/testing/session
  • @mandujs/core/testing/snapshot

Readme

Mandu

@mandujs/core

Mandu Framework Core
Runtime, FS Routes, Guard, Bundler, Contract, Filling

English | 한국어

Installation

bun add @mandujs/core

Typically used through @mandujs/cli. Direct usage is for advanced use cases.

Quick Start

Basic API Handler (Filling)

import { Mandu } from "@mandujs/core";

export default Mandu.filling()
  .guard((ctx) => {
    if (!ctx.get("user")) return ctx.unauthorized("Login required");
  })
  .get(async (ctx) => {
    const users = await db.users.findMany();
    return ctx.ok({ data: users });
  })
  .post(async (ctx) => {
    const body = await ctx.body<{ name: string }>();
    const user = await db.users.create({ data: body });
    return ctx.created({ data: user });
  });

Type-Safe Contract

import { Mandu } from "@mandujs/core";
import { z } from "zod";

const userContract = Mandu.contract({
  request: {
    GET: { query: z.object({ id: z.string() }) },
    POST: { body: z.object({ name: z.string() }) }
  },
  response: {
    200: z.object({ data: z.any() }),
    400: z.object({ error: z.string() })
  }
});

const handlers = Mandu.handler(userContract, {
  GET: (ctx) => ({ data: fetchUser(ctx.query.id) }),
  POST: (ctx) => ({ data: createUser(ctx.body) })
});

Module Overview

@mandujs/core
├── router/          # FS Routes - file-system based routing
├── guard/           # Mandu Guard - architecture enforcement
│   ├── healing      # Self-Healing Guard with auto-fix
│   ├── decision-memory   # ADR storage (RFC-001)
│   ├── semantic-slots    # Constraint validation (RFC-001)
│   └── negotiation       # AI-Framework dialog (RFC-001)
├── runtime/         # Server, SSR, streaming
├── filling/         # Handler chain API (Mandu.filling())
├── contract/        # Type-safe API contracts
├── content/         # Content Layer - build-time content loading 🆕
│   └── loaders      # file(), glob(), api() loaders
├── bundler/         # Client bundling, HMR
├── client/          # Island hydration, client router
├── brain/           # Doctor, Watcher, Architecture analyzer
├── change/          # Transaction & history
└── spec/            # Manifest schema & validation

FS Routes

File-system based routing system.

import { scanRoutes, generateManifest, watchFSRoutes } from "@mandujs/core/router";

// Scan routes from app/ directory
const result = await scanRoutes("/path/to/project");
console.log(result.routes);

// Generate manifest
const { manifest } = await generateManifest("/path/to/project", {
  outputPath: ".mandu/manifest.json"
});

// Watch for changes
const watcher = await watchFSRoutes("/path/to/project", {
  onChange: (result) => console.log("Routes updated!", result.routes.length)
});

Route Patterns

import { pathToPattern, parseSegments } from "@mandujs/core/router";

// Convert path to URL pattern
pathToPattern("users/[id]/posts");     // → "/users/:id/posts"
pathToPattern("docs/[...slug]");       // → "/docs/:slug*"
pathToPattern("(auth)/login");         // → "/login" (group ignored)

// Parse segments
parseSegments("[id]");                 // → [{ type: "dynamic", name: "id" }]
parseSegments("[...slug]");            // → [{ type: "catch-all", name: "slug" }]

Mandu Guard

Real-time architecture enforcement with preset support.

import {
  createGuardWatcher,
  checkDirectory,
  getPreset,
  listPresets
} from "@mandujs/core/guard";

// One-time check
const report = await checkDirectory(
  { preset: "mandu" },
  process.cwd()
);
console.log(`Violations: ${report.totalViolations}`);

// Real-time watching
const watcher = createGuardWatcher({
  config: { preset: "mandu", srcDir: "src" },
  rootDir: process.cwd(),
  onViolation: (v) => console.log(`${v.filePath}: ${v.ruleDescription}`),
});
watcher.start();

// List available presets
listPresets().forEach(p => console.log(p.name, p.description));

Presets (6)

Preset Layers Use Case
mandu client/, shared/(contracts, types, utils/, schema, env), server/* Fullstack (default)
fsd app, pages, widgets, features, entities, shared Frontend
clean api, application, domain, infra, shared Backend
hexagonal adapters, ports, application, domain DDD
atomic pages, templates, organisms, molecules, atoms UI
cqrs commands, queries, events, dto, application, domain Event-sourced apps

AST-based Analysis

import { extractImportsAST, analyzeModuleAST } from "@mandujs/core/guard";

// Extract imports with AST (more accurate than regex)
const imports = extractImportsAST(code);
// → [{ path: "./utils", type: "static", line: 1, namedImports: ["foo"] }]

// Full module analysis
const analysis = analyzeModuleAST(code, "src/features/user/api.ts");
import {
  createScanRecord,
  addScanRecord,
  analyzeTrend,
  generateGuardMarkdownReport
} from "@mandujs/core/guard";

// Save scan for trend analysis
const record = createScanRecord(report, "mandu");
await addScanRecord(rootDir, record);

// Analyze improvement trend
const trend = analyzeTrend(records, 7); // 7 days
console.log(trend.trend); // "improving" | "stable" | "degrading"

// Generate reports
const markdown = generateGuardMarkdownReport(report, trend);

Self-Healing Guard (RFC-001) 🆕

import { checkWithHealing, healAll, explainRule } from "@mandujs/core/guard";

// Detect violations with fix suggestions
const result = await checkWithHealing({ preset: "mandu" }, process.cwd());

// Auto-fix all fixable violations
if (result.items.length > 0) {
  const healResult = await healAll(result);
  console.log(`Fixed: ${healResult.fixed}, Failed: ${healResult.failed}`);
}

// Explain any rule
const explanation = explainRule("layer-dependency");
console.log(explanation.description, explanation.examples);

Decision Memory (RFC-001) 🆕

import {
  searchDecisions,
  saveDecision,
  checkConsistency,
  getCompactArchitecture
} from "@mandujs/core/guard";

// Search past decisions
const results = await searchDecisions(rootDir, ["auth", "jwt"]);

// Save new decision (ADR)
await saveDecision(rootDir, {
  id: "ADR-002",
  title: "Use PostgreSQL",
  status: "accepted",
  context: "Need relational database",
  decision: "Use PostgreSQL with Drizzle ORM",
  consequences: ["Need to manage migrations"],
  tags: ["database", "orm"]
});

// Check implementation consistency
const consistency = await checkConsistency(rootDir);

Architecture Negotiation (RFC-001) 🆕

import { negotiate, generateScaffold } from "@mandujs/core/guard";

// AI negotiates with framework before implementation
const plan = await negotiate({
  intent: "Add user authentication",
  requirements: ["JWT based", "Refresh tokens"],
  constraints: ["Use existing User model"]
}, projectRoot);

if (plan.approved) {
  // Generate scaffold files
  await generateScaffold(plan.structure, projectRoot);
}

Filling API

Handler chain for business logic.

import { Mandu } from "@mandujs/core";

export default Mandu.filling()
  // Lifecycle hooks
  .onRequest((ctx) => {
    ctx.set("requestId", crypto.randomUUID());
  })

  // Guard (return Response to block)
  .guard((ctx) => {
    if (!ctx.get("user")) return ctx.unauthorized("Login required");
  })

  // Handlers
  .get(async (ctx) => {
    return ctx.ok({ users: await fetchUsers() });
  })

  .post(async (ctx) => {
    const body = await ctx.body();
    return ctx.created({ user: await createUser(body) });
  })

  // After response
  .afterResponse((ctx) => {
    console.log("Request completed:", ctx.get("requestId"));
  });

Middleware (Compose-style)

export default Mandu.filling()
  .middleware(async (ctx, next) => {
    console.log("before");
    await next();
    console.log("after");
  })
  .get((ctx) => ctx.ok({ ok: true }));

Context API

Method Description
ctx.ok(data) 200 OK
ctx.created(data) 201 Created
ctx.noContent() 204 No Content
ctx.error(message) 400 Bad Request
ctx.unauthorized(message) 401 Unauthorized
ctx.forbidden(message) 403 Forbidden
ctx.notFound(message) 404 Not Found
ctx.fail(message) 500 Internal Server Error
ctx.body<T>() Parse request body
ctx.params Route parameters
ctx.query Query parameters
ctx.set(key, value) Store in context
ctx.get<T>(key) Retrieve from context

Contract API

Type-safe API contracts with Zod.

import { Mandu } from "@mandujs/core";
import { z } from "zod";

// Define contract
const userContract = Mandu.contract({
  request: {
    GET: { query: z.object({ id: z.string() }) },
    POST: { body: z.object({ name: z.string() }) }
  },
  response: {
    200: z.object({ data: z.any() }),
    400: z.object({ error: z.string() })
  }
});

// Create typed handlers
const handlers = Mandu.handler(userContract, {
  GET: (ctx) => ({ data: fetchUser(ctx.query.id) }),
  POST: (ctx) => ({ data: createUser(ctx.body) })
});

  // Type-safe client
  const client = Mandu.client(userContract, { baseUrl: "/api/users" });
  const result = await client.GET({ query: { id: "123" } });

Client-safe Contract

Limit schemas exposed to client-side usage (forms/UI validation):

const clientContract = Mandu.clientContract(userContract, {
  request: {
    POST: { body: true },
  },
  response: [201],
  includeErrors: true,
});

const client = Mandu.client(clientContract, { baseUrl: "/api/users" });

Runtime

Server and SSR.

import { startServer, registerApiHandler, registerPageLoader } from "@mandujs/core";

// Register handlers
registerApiHandler("getUsers", async (req) => ({ users: [] }));
registerPageLoader("home", () => import("./pages/Home"));

// Start server
const server = startServer(manifest, { port: 3000 });

Streaming SSR

import { renderToStream } from "@mandujs/core";

const stream = await renderToStream(<App />, {
  bootstrapScripts: ["/client.js"],
  onError: (err) => console.error(err)
});

Client (Islands & Router)

Island Hydration

import { createIsland, partial } from "@mandujs/core/client";

// Define island
const CounterIsland = createIsland({
  name: "counter",
  component: Counter,
  priority: "visible"
});

// Partial (smaller than island)
const ButtonPartial = partial("submit-btn", SubmitButton);

Client Router

import { useRouter, useParams, Link, NavLink } from "@mandujs/core/client";

function Navigation() {
  const router = useRouter();
  const params = useParams();

  return (
    <nav>
      <NavLink href="/users" activeClass="active">Users</NavLink>
      <button onClick={() => router.push("/settings")}>Settings</button>
    </nav>
  );
}

Content Layer 🆕

Astro-inspired build-time content loading system.

// content.config.ts
import { defineContentConfig, glob, file, api } from "@mandujs/core/content";
import { z } from "zod";

const postSchema = z.object({
  title: z.string(),
  date: z.coerce.date(),
  tags: z.array(z.string()).default([]),
});

export default defineContentConfig({
  collections: {
    // Markdown files with frontmatter
    posts: {
      loader: glob({ pattern: "content/posts/**/*.md" }),
      schema: postSchema,
    },
    // Single JSON/YAML file
    settings: {
      loader: file({ path: "data/settings.json" }),
    },
    // External API
    products: {
      loader: api({
        url: "https://api.example.com/products",
        headers: () => ({ Authorization: `Bearer ${process.env.API_KEY}` }),
        cacheTTL: 3600,
      }),
    },
  },
});

Querying Content

import { getCollection, getEntry } from "@mandujs/core/content";

// Get all entries
const posts = await getCollection("posts");
posts.forEach(post => {
  console.log(post.id, post.data.title);
});

// Get single entry
const post = await getEntry("posts", "hello-world");
console.log(post?.data.title, post?.body);

Built-in Loaders

Loader Description Example
file() Single file (JSON, YAML, TOML) file({ path: "data/config.json" })
glob() Pattern matching (Markdown, JSON) glob({ pattern: "content/**/*.md" })
api() HTTP API with caching api({ url: "https://...", cacheTTL: 3600 })

Features

  • Digest-based caching: Only re-parse changed files
  • Zod validation: Type-safe content with schema validation
  • Frontmatter support: YAML frontmatter in Markdown files
  • Dev mode watching: Auto-reload on content changes
  • Incremental updates: Efficient builds with change detection

Brain (AI Assistant)

Doctor and architecture analyzer.

import {
  initializeBrain,
  getBrain,
  analyzeViolations,
  initializeArchitectureAnalyzer
} from "@mandujs/core";

// Initialize
await initializeBrain();
const brain = getBrain();

// Analyze violations with suggestions
const analysis = await analyzeViolations(violations, { useLLM: true });
console.log(analysis.patches); // Suggested fixes

// Architecture analyzer
const analyzer = initializeArchitectureAnalyzer(rootDir);
const locationResult = await analyzer.checkLocation({ path: "src/features/user.ts" });
const importResult = await analyzer.checkImports({
  sourceFile: "src/features/user.ts",
  imports: ["../entities/product"]
});

Bundler

Client bundling with HMR.

import { buildClientBundle, createDevBundler } from "@mandujs/core/bundler";

// Production build
const result = await buildClientBundle(manifest, {
  outDir: ".mandu/client",
  minify: true,
  sourcemap: true
});

// Development with HMR
const devBundler = await createDevBundler(manifest, {
  rootDir: process.cwd(),
  isDev: true
});

Transaction API

Atomic changes with rollback.

import { beginChange, commitChange, rollbackChange } from "@mandujs/core";

// Start transaction
const { changeId, snapshotId } = await beginChange(rootDir, "Add user API");

// Make changes...

// Commit or rollback
await commitChange(rootDir);
// or
await rollbackChange(rootDir);

Types

import type {
  // Spec
  RoutesManifest,
  RouteSpec,

  // Guard
  GuardPreset,
  GuardConfig,
  Violation,
  ViolationReport,

  // Router
  ScanResult,
  FSRouteConfig,

  // Contract
  ContractDefinition,
  ContractHandlers,

  // Filling
  ManduContext,

  // Content Layer
  DataEntry,
  ContentConfig,
  CollectionConfig,
  Loader,
  LoaderContext,
} from "@mandujs/core";

Requirements

  • Bun >= 1.0.0
  • React >= 19.0.0
  • Zod >= 3.0.0

License

MIT