# @zenweb/core - AI Reference

Quick reference for AI agents working with this module.

## Quick Start

```typescript
import { $initCore } from '@zenweb/core';

$initCore()
  .setup(myModule())
  .start();
```

## Module Definition Pattern

```typescript
import { SetupFunction } from '@zenweb/core';

export interface MyModuleOption {
  enabled?: boolean;
}

export default function (opt?: MyModuleOption): SetupFunction {
  return function mymodule(setup) {
    setup.debug('options:', opt);

    setup.defineCoreProperty('myFeature', { value: opt?.enabled ?? true });
    setup.defineContextCacheProperty('user', (ctx) => ctx.header['x-user']);

    setup.middleware(async (ctx, next) => {
      return next();
    });

    setup.after(() => setup.assertModuleExists('router'));
    setup.destroy(async () => { /* cleanup */ });
  };
}

// Type extensions
declare module '@zenweb/core' {
  interface Core { myFeature: boolean; }
  interface Context { user: string | null; }
}
```

## Naming Convention

**`$`-prefixed exports provide global access without explicit passing.**

- `$core` / `$getCore()` - Access Core instance globally (requires `$initCore()` first)
- `$ctx` / `$getContext()` - Access current request context (requires AsyncLocalStorage)
- `$debug` - Debug output with request context info when available

Enable by calling `$initCore()` which auto-enables asyncLocalStorage.

## Key APIs

### Core
- `setup(fn, { name?, order? })` - Install module
- `boot()` - Initialize all modules
- `start(port?)` - Boot + listen + signal handling
- `stop(signal?)` - Graceful shutdown

### SetupHelper
- `defineCoreProperty(prop, descriptor)` - Add property to Core
- `defineContextProperty(prop, descriptor)` - Add property to Koa context
- `defineContextCacheProperty(prop, getter)` - Lazy-cached context property
- `middleware(fn)` - Register Koa middleware
- `after(fn)` - Callback after all modules initialized
- `destroy(fn)` - Cleanup callback (runs in reverse order)
- `assertModuleExists(name)` - Check dependency loaded

## Module Loading Order

- Default: auto-increment by 100 (100, 200, 300...)
- Custom: `setup(module(), { order: 50 })`
- Lower order = earlier initialization
- Destroy runs in reverse order

## Common Mistakes

1. **Forgot `$initCore()` before using `$core`/`$ctx`** - Must call first
2. **Using `$ctx` outside request context** - Only works during request handling; returns undefined with `$getContext(false)`
3. **Wrong module order** - If module A depends on B, A must have higher order
4. **Missing type extension** - Extend `Core`/`Context` interfaces for TypeScript support
5. **Setup function name matters** - The function name (e.g., `mymodule`) is used as module identifier