/** * Runtime auto-discovery — walks an `app/` source tree, dynamic-imports every * module it finds, and classifies each export by its `$kind` discriminator. * * Mechanism: Node.js `fs.readdirSync` + ESM `import()`. Works identically * under `nwire dev` (Vite host), `nwire build` / production, and `vitest` — * no codegen step required. * * Caveat: requires Node.js `node:fs` and dynamic import from the local * filesystem. Does NOT work in bundled edge environments (Cloudflare Workers, * Deno Deploy, etc.) where `node:fs` is absent or `import()` resolves only * bundled modules. For edge targets, pass handlers/actors/etc. explicitly. */ import type { Logger } from "@nwire/logger"; /** Discovered primitives grouped by kind. */ export interface DiscoveredPrimitives { /** `defineHandler` + `defineAction` + `defineQuery` exports (any `$kind:"handler"`). */ readonly handlers: any[]; /** `defineActor` exports. */ readonly actors: any[]; /** `defineProjection` exports. */ readonly projections: any[]; /** `defineWorkflow` exports. */ readonly workflows: any[]; /** `defineEvent` exports — typed facts; `.public()` ones feed the app's public surface. */ readonly events: any[]; /** `defineCommand` exports — operator scripts dispatched via `nwire please`. */ readonly commands: any[]; /** `defineExternalCall` exports — typed outbound integration points. */ readonly externalCalls: any[]; } /** * Recursively collect importable source files under `dir`, applying the same * skip rules the runtime scanner uses. Exported so the build-time registry * codegen (`@nwire/scan`) emits imports for exactly the file set the runtime * fs-scan would discover — the two paths can't drift on which files count. */ export declare function collectFiles(dir: string): string[]; /** * Classify the exports of a set of already-imported modules into the four * primitive groups. This is the pure, fs-free core of discovery — the single * source of truth shared by two callers: * * - {@link discoverPrimitives} — imports files off disk, then classifies. * - the build-time generated registry (`@nwire/scan`) — statically imports * every app module, then classifies, so a production bundle registers the * exact same set without any filesystem scan or dynamic import. * * Because both paths run the *same* classifier over the *real* exported * values, the build path and the runtime fs-scan path are equivalent by * construction — there is no second copy of the `$kind` rules to drift. * * `sources` is the optional parallel list of file paths the modules came * from — both callers know it, and passing it stamps every classified * primitive with its defining file (`$source`) so registration errors can * point at real code. Older generated registries omit it; nothing breaks. */ export declare function classifyModules(mods: ReadonlyArray>, sources?: ReadonlyArray): DiscoveredPrimitives; /** * Walk `root`, import every source module, and classify all named exports. * Returns the primitive groups. * * @param root Absolute path to scan (e.g. `path.resolve(process.cwd(), "app")`). * @param logger Optional logger for skipped-file warnings (defaults to silent). */ export declare function discoverPrimitives(root: string, logger?: Logger): Promise; /** * Merge a discovered list with an explicit list, preferring explicit entries * on name collision. Works for handlers (keyed on `.name`) and for actors / * projections / workflows (also keyed on `.name`). */ export declare function mergeByName(discovered: readonly T[], explicit: readonly T[]): T[];