melony 0.3.6 → 0.3.7
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/dist/index.d.ts +10 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -129,13 +129,21 @@ declare class MelonyBuilder<TState = any, TEvent = any> {
|
|
|
129
129
|
* Add an event handler for a specific event type. Supports method chaining.
|
|
130
130
|
* The handler receives the narrowed event type based on the eventType string.
|
|
131
131
|
*/
|
|
132
|
-
on
|
|
132
|
+
on<K extends (TEvent extends {
|
|
133
|
+
type: string;
|
|
134
|
+
} ? TEvent["type"] : string) | "*">(eventType: K, handler: (event: K extends "*" ? TEvent : Extract<TEvent, {
|
|
135
|
+
type: K;
|
|
136
|
+
}>, context: RuntimeContext<TState, TEvent>) => AsyncGenerator<TEvent, void, unknown> | void): this;
|
|
133
137
|
/**
|
|
134
138
|
* Register an interceptor that runs before any handlers.
|
|
135
139
|
* Useful for logging, validation, or suspending for approval.
|
|
136
140
|
*/
|
|
137
141
|
intercept(interceptor: EventInterceptor<TState, TEvent>): this;
|
|
138
|
-
intercept
|
|
142
|
+
intercept<K extends (TEvent extends {
|
|
143
|
+
type: string;
|
|
144
|
+
} ? TEvent["type"] : string)>(eventType: K, interceptor: (event: Extract<TEvent, {
|
|
145
|
+
type: K;
|
|
146
|
+
}>, context: RuntimeContext<TState, TEvent>) => Promise<TEvent | void> | TEvent | void): this;
|
|
139
147
|
/**
|
|
140
148
|
* Use a plugin to extend the builder.
|
|
141
149
|
* This is ideal for modularizing common handlers.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/generate-id.ts","../src/runtime.ts","../src/utils/create-json-response.ts","../src/utils/create-stream-response.ts","../src/utils/handle-request.ts","../src/melony.ts"],"names":["event","origin","pnr"],"mappings":"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","file":"index.js","sourcesContent":["export const generateId = () => {\n return typeof crypto !== \"undefined\" && crypto.randomUUID\n ? crypto.randomUUID()\n : Math.random().toString(36).substring(7);\n};\n","import {\n RuntimeContext,\n Config,\n RunOptions,\n} from \"./types\";\nimport { generateId } from \"./utils/generate-id\";\n\n/**\n * The Melony Runtime.\n * Fully unopinionated - processes events through handlers.\n */\nexport class Runtime<TState = any, TEvent = any> {\n public readonly config: Config<TState, TEvent>;\n\n constructor(config: Config<TState, TEvent>) {\n this.config = config;\n }\n\n /**\n * Helper to get the event type from an event object based on configuration.\n */\n private getEventType(event: TEvent): string {\n const key = this.config.eventKey || \"type\";\n return (event as any)[key] || \"*\";\n }\n\n /**\n * Helper to check if a value is a Melony Event.\n */\n private isEvent(val: any): val is TEvent {\n const key = this.config.eventKey || \"type\";\n return val && typeof val === \"object\" && typeof (val as any)[key] === \"string\";\n }\n\n /**\n * Process an incoming event through the runtime.\n * All event processing is handled by user-defined event handlers.\n */\n public async *run(\n event: TEvent,\n options?: RunOptions<TState>\n ): AsyncGenerator<TEvent> {\n const runId = options?.runId ?? generateId();\n const eventKey = this.config.eventKey || \"type\";\n\n // Resolve initial state: options.state > config.initialState > {}\n let state: TState;\n if (options?.state) {\n state = options.state;\n } else if (typeof this.config.initialState === \"function\") {\n state = await (this.config.initialState as any)();\n } else if (this.config.initialState) {\n // Use structuredClone if available, otherwise fallback to simple spread for safety\n state = typeof (globalThis as any).structuredClone === \"function\"\n ? (globalThis as any).structuredClone(this.config.initialState)\n : { ...this.config.initialState };\n } else {\n state = {} as TState;\n }\n\n const context: RuntimeContext<TState, TEvent> = {\n state,\n runtime: this,\n runId,\n suspend: (event?: TEvent) => {\n throw event || { [eventKey]: \"run-suspended\", data: {} };\n },\n };\n\n try {\n // 1. Call onStart hook\n if (this.config.onStart) {\n const startEvents = await this.config.onStart(context, event);\n if (startEvents) {\n for await (const lifecycleEvent of startEvents) {\n yield* this.runEventHandlers(lifecycleEvent, context);\n }\n }\n }\n\n // 2. Process the incoming event through handlers\n yield* this.runEventHandlers(event, context);\n } catch (error) {\n let eventToEmit: TEvent | undefined;\n\n if (this.isEvent(error)) {\n eventToEmit = error as TEvent;\n } else {\n eventToEmit = {\n [eventKey]: \"error\",\n data: {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n },\n } as unknown as TEvent;\n }\n\n if (eventToEmit) {\n yield* this.runEventHandlers(eventToEmit, context);\n }\n } finally {\n // 3. Call onEnd hook\n if (this.config.onEnd) {\n const endEvents = await this.config.onEnd(context);\n if (endEvents) {\n for await (const lifecycleEvent of endEvents) {\n yield* this.runEventHandlers(lifecycleEvent, context);\n }\n }\n }\n }\n }\n\n\n /**\n * Run all event handlers that match the given event type.\n */\n private async *runEventHandlers(\n event: TEvent,\n context: RuntimeContext<TState, TEvent>,\n ): AsyncGenerator<TEvent> {\n let currentEvent = event;\n const eventKey = this.config.eventKey || \"type\";\n\n // 1. Run global interceptors first\n const globalInterceptors = this.config.interceptors.get(\"*\") || [];\n for (const interceptor of globalInterceptors) {\n const result = await interceptor(currentEvent, context);\n if (result && typeof result === \"object\" && eventKey in (result as any)) {\n currentEvent = result as TEvent;\n }\n }\n\n // 2. Run specific interceptors for the (possibly new) event type\n // If currentEvent type is \"*\", it's already been handled by the global interceptors\n let eventType = this.getEventType(currentEvent);\n if (eventType !== \"*\") {\n const specificInterceptors = this.config.interceptors.get(eventType) || [];\n for (const interceptor of specificInterceptors) {\n const result = await interceptor(currentEvent, context);\n if (result && typeof result === \"object\" && eventKey in (result as any)) {\n currentEvent = result as TEvent;\n }\n }\n }\n\n eventType = this.getEventType(currentEvent);\n const wildcardHandlers = this.config.handlers.get(\"*\") || [];\n const specificHandlers = this.config.handlers.get(eventType) || [];\n // When type is missing, getEventType is \"*\"; do not register wildcard handlers twice.\n const handlers =\n eventType === \"*\"\n ? [...wildcardHandlers]\n : [...wildcardHandlers, ...specificHandlers];\n\n // First emit the event itself\n yield* this.emit(currentEvent, context);\n\n for (const handler of handlers) {\n const result = handler(currentEvent, context);\n if (result) {\n for await (const yieldedEvent of result) {\n // Recursively process yielded events through their handlers\n yield* this.runEventHandlers(yieldedEvent, context);\n }\n }\n }\n }\n\n /**\n * Internal helper to yield an event with metadata and trigger hooks.\n */\n private async *emit(\n event: TEvent,\n context: RuntimeContext<TState, TEvent>\n ): AsyncGenerator<TEvent> {\n if (this.config.onEvent) {\n await this.config.onEvent(context, event);\n }\n yield event;\n }\n}\n","import type { RunOptions } from \"../types\";\n\nexport interface CreateJsonResponseDeps<TState, TEvent> {\n run: (\n event: TEvent,\n options?: RunOptions<TState>\n ) => AsyncIterable<TEvent>;\n}\n\n/**\n * Run the agent to completion and return all emitted events as a JSON Response.\n * Useful for initialization or non-streaming requests.\n */\nexport async function createJsonResponse<TState, TEvent>(\n event: TEvent,\n options: RunOptions<TState> | undefined,\n deps: CreateJsonResponseDeps<TState, TEvent>\n): Promise<Response> {\n const events: TEvent[] = [];\n for await (const e of deps.run(event, options)) {\n events.push(e);\n }\n\n return new Response(JSON.stringify({ events }), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n","/**\n * Convert an async generator of events to an HTTP streaming response\n * Exported for backward compatibility and standalone usage\n */\nexport function createStreamResponse<TEvent = any>(\n generator: AsyncGenerator<TEvent>,\n): Response {\n const encoder = new TextEncoder();\n const stream = new ReadableStream({\n async start(controller) {\n try {\n for await (const message of generator) {\n // Format as SSE: data: {...}\\n\\n\n const chunk = `data: ${JSON.stringify(message)}\\n\\n`;\n controller.enqueue(encoder.encode(chunk));\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n","import { generateId } from \"./generate-id\";\n\nexport interface HandleMelonyRequestOptions<TState> {\n state?: (req: Request) => Promise<TState> | TState;\n}\n\nexport interface HandleMelonyRequestDeps<TState, TEvent> {\n eventKey: string;\n initialState?: TState | (() => TState | Promise<TState>);\n streamResponse: (\n event: TEvent,\n options?: { state?: TState; runId?: string }\n ) => Promise<Response>;\n}\n\n/**\n * Unified Web-Standard Request handler: parses Request and returns a streaming Response.\n */\nexport async function handleMelonyRequest<TState, TEvent>(\n request: Request,\n options: HandleMelonyRequestOptions<TState> | undefined,\n deps: HandleMelonyRequestDeps<TState, TEvent>\n): Promise<Response> {\n if (request.method === \"OPTIONS\") {\n const requested = request.headers.get(\"access-control-request-headers\");\n const defaultAllowHeaders =\n \"Content-Type, x-melony-thread-id, x-melony-run-id, x-melony-session-id, Authorization, Last-Event-ID\";\n const origin = request.headers.get(\"origin\");\n const allowOrigin = origin ?? \"*\";\n const headers: Record<string, string> = {\n \"Access-Control-Allow-Origin\": allowOrigin,\n \"Access-Control-Allow-Methods\": \"POST, GET, OPTIONS\",\n \"Access-Control-Allow-Headers\": requested ?? defaultAllowHeaders,\n };\n if (origin) {\n headers.Vary = \"Origin\";\n headers[\"Access-Control-Allow-Credentials\"] = \"true\";\n }\n const pnr = request.headers.get(\"access-control-request-private-network\");\n if (pnr?.toLowerCase() === \"true\") {\n headers[\"Access-Control-Allow-Private-Network\"] = \"true\";\n }\n return new Response(null, { status: 204, headers });\n }\n\n let event: TEvent;\n try {\n if (request.method === \"POST\") {\n event = await request.json();\n } else {\n const url = new URL(request.url);\n // Avoid defaulting GET to \"run\": browsers, probes, and EventSource use GET; reconnects\n // would re-trigger full runs. Use ?type=run when you intend orchestration via GET.\n event = {\n [deps.eventKey]: url.searchParams.get(\"type\") || \"http-get\",\n data: Object.fromEntries(url.searchParams.entries()),\n } as unknown as TEvent;\n }\n } catch {\n return new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n },\n });\n }\n\n const threadId =\n request.headers.get(\"x-melony-thread-id\") ||\n (event as { threadId?: string }).threadId ||\n generateId();\n const runId = request.headers.get(\"x-melony-run-id\") || generateId();\n const sessionId =\n request.headers.get(\"x-melony-session-id\") ||\n (event as { sessionId?: string }).sessionId ||\n generateId();\n\n let state: TState;\n if (options?.state) {\n state = await options.state(request);\n } else if (typeof deps.initialState === \"function\") {\n state = await (deps.initialState as () => TState | Promise<TState>)();\n } else if (deps.initialState) {\n state =\n typeof (globalThis as any).structuredClone === \"function\"\n ? (globalThis as any).structuredClone(deps.initialState)\n : { ...(deps.initialState as object) };\n } else {\n state = { threadId, runId, sessionId } as unknown as TState;\n }\n\n const response = await deps.streamResponse(event, { state, runId });\n const origin = request.headers.get(\"origin\");\n response.headers.set(\"Access-Control-Allow-Origin\", origin ?? \"*\");\n if (origin) {\n response.headers.set(\"Vary\", \"Origin\");\n response.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n const pnr = request.headers.get(\"access-control-request-private-network\");\n if (pnr?.toLowerCase() === \"true\") {\n response.headers.set(\"Access-Control-Allow-Private-Network\", \"true\");\n }\n return response;\n}\n","import { Runtime } from \"./runtime\";\nimport {\n EventHandler,\n Config,\n RuntimeContext,\n EventInterceptor,\n RunOptions,\n LifecycleHookResult,\n} from \"./types\";\nimport { createJsonResponse } from \"./utils/create-json-response\";\nimport { createStreamResponse } from \"./utils/create-stream-response\";\nimport { handleMelonyRequest } from \"./utils/handle-request\";\n\n/**\n * The Melony Runtime class.\n * This is the core class that powers the Melony framework.\n */\nexport const MelonyRuntime = Runtime;\n\n/**\n * A Melony plugin is a function that receives the builder and extends it.\n * This allows for modularizing common handlers.\n */\nexport type MelonyPlugin<TState = any, TEvent = any> = (\n builder: MelonyBuilder<TState, TEvent>\n) => void;\n\n/**\n * Fluent builder for creating Melony agents with excellent developer experience.\n * Provides method chaining for handlers and plugins with full TypeScript support.\n */\nexport class MelonyBuilder<\n TState = any,\n TEvent = any\n> {\n private config: Config<TState, TEvent>;\n\n constructor(initialConfig?: Partial<Config<TState, TEvent>>) {\n this.config = {\n handlers: initialConfig?.handlers ?? new Map(),\n interceptors: initialConfig?.interceptors ?? new Map(),\n eventKey: initialConfig?.eventKey ?? \"type\",\n initialState: initialConfig?.initialState,\n onStart: initialConfig?.onStart,\n onEnd: initialConfig?.onEnd,\n onEvent: initialConfig?.onEvent,\n };\n }\n\n /**\n * Configure the key in the event object that defines its type.\n * Defaults to \"type\".\n */\n eventKey(key: string): this {\n this.config.eventKey = key;\n return this;\n }\n\n /**\n * Configure the initial state for the runtime.\n * Supports a static object or a factory function.\n */\n initialState(state: TState | (() => TState | Promise<TState>)): this {\n this.config.initialState = state;\n return this;\n }\n\n /**\n * Register a hook called before the runtime starts processing events.\n */\n onStart(\n hook: (\n context: RuntimeContext<TState, TEvent>,\n initialEvent: TEvent\n ) => Promise<LifecycleHookResult<TEvent>> | LifecycleHookResult<TEvent>\n ): this {\n this.config.onStart = hook;\n return this;\n }\n\n /**\n * Register a hook called after the runtime has finished processing events.\n */\n onEnd(\n hook: (\n context: RuntimeContext<TState, TEvent>\n ) => Promise<LifecycleHookResult<TEvent>> | LifecycleHookResult<TEvent>\n ): this {\n this.config.onEnd = hook;\n return this;\n }\n\n /**\n * Register a hook called for every event emitted by the runtime.\n */\n onEvent(\n hook: (\n context: RuntimeContext<TState, TEvent>,\n event: TEvent\n ) => Promise<void> | void\n ): this {\n this.config.onEvent = hook;\n return this;\n }\n\n /**\n * Add an event handler for a specific event type. Supports method chaining.\n * The handler receives the narrowed event type based on the eventType string.\n */\n on(\n eventType: string | \"*\",\n handler: (\n event: TEvent,\n context: RuntimeContext<TState, TEvent>\n ) => AsyncGenerator<TEvent, void, unknown> | void\n ): this {\n if (!this.config.handlers.has(eventType)) {\n this.config.handlers.set(eventType, []);\n }\n // Cast is safe because runtime only calls this handler for matching event types\n this.config.handlers.get(eventType)!.push(handler as EventHandler<TState, TEvent>);\n return this;\n }\n\n /**\n * Register an interceptor that runs before any handlers.\n * Useful for logging, validation, or suspending for approval.\n */\n intercept(interceptor: EventInterceptor<TState, TEvent>): this;\n intercept(\n eventType: string,\n interceptor: (\n event: TEvent,\n context: RuntimeContext<TState, TEvent>\n ) => Promise<TEvent | void> | TEvent | void\n ): this;\n intercept(\n arg1: string | EventInterceptor<TState, TEvent>,\n arg2?: any\n ): this {\n if (typeof arg1 === \"string\") {\n const type = arg1;\n const interceptor = arg2!;\n if (!this.config.interceptors.has(type)) {\n this.config.interceptors.set(type, []);\n }\n this.config.interceptors.get(type)!.push(interceptor as EventInterceptor<TState, TEvent>);\n } else {\n const interceptor = arg1;\n if (!this.config.interceptors.has(\"*\")) {\n this.config.interceptors.set(\"*\", []);\n }\n this.config.interceptors.get(\"*\")!.push(interceptor);\n }\n return this;\n }\n\n /**\n * Use a plugin to extend the builder.\n * This is ideal for modularizing common handlers.\n */\n use(plugin: MelonyPlugin<TState, TEvent>): this {\n plugin(this);\n return this;\n }\n\n /**\n * Build and return the Melony runtime instance.\n * This is the final method in the fluent chain.\n */\n build(): Runtime<TState, TEvent> {\n return new Runtime(this.config);\n }\n\n /**\n * Execute the runtime for a specific event.\n */\n async run(\n event: TEvent,\n options?: RunOptions<TState>\n ): Promise<AsyncGenerator<TEvent>> {\n const runtime = this.build();\n return runtime.run(event, options);\n }\n\n /**\n * Execute and stream the response for an event.\n * This is a convenience method that builds the runtime and calls run().\n */\n async streamResponse(\n event: TEvent,\n options?: { state?: TState; runId?: string }\n ): Promise<Response> {\n const runtime = this.build();\n const generator = runtime.run(event, options);\n return createStreamResponse(generator);\n }\n\n /**\n * Execute the agent and return the data from the last event of a specific type as a JSON response.\n * Ideal for initialization or non-streaming requests where you only need the final UI state.\n */\n async jsonResponse(\n event: TEvent,\n options?: RunOptions<TState>\n ): Promise<Response> {\n return createJsonResponse(event, options, {\n run: (e, opts) => this.build().run(e, opts),\n });\n }\n\n /**\n * A unified Web-Standard Request Handler.\n * Automatically parses a Request and returns a streaming Response.\n */\n async handle(\n request: Request,\n options?: { state?: (req: Request) => Promise<TState> | TState }\n ): Promise<Response> {\n return handleMelonyRequest(request, options, {\n eventKey: this.config.eventKey || \"type\",\n initialState: this.config.initialState,\n streamResponse: (event: TEvent, opts) => this.streamResponse(event, opts),\n });\n }\n\n /**\n * Get the current configuration (useful for debugging or serialization).\n */\n getConfig(): Config<TState, TEvent> {\n return { ...this.config };\n }\n}\n\n/**\n * Factory function to create a new Melony builder instance.\n * This is the entry point for the fluent API.\n */\nexport function melony<\n TState = any,\n TEvent = any\n>(initialConfig?: Partial<Config<TState, TEvent>>): MelonyBuilder<TState, TEvent> {\n return new MelonyBuilder<TState, TEvent>(initialConfig);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/generate-id.ts","../src/runtime.ts","../src/utils/create-json-response.ts","../src/utils/create-stream-response.ts","../src/utils/handle-request.ts","../src/melony.ts"],"names":["event","origin","pnr"],"mappings":"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","file":"index.js","sourcesContent":["export const generateId = () => {\n return typeof crypto !== \"undefined\" && crypto.randomUUID\n ? crypto.randomUUID()\n : Math.random().toString(36).substring(7);\n};\n","import {\n RuntimeContext,\n Config,\n RunOptions,\n} from \"./types\";\nimport { generateId } from \"./utils/generate-id\";\n\n/**\n * The Melony Runtime.\n * Fully unopinionated - processes events through handlers.\n */\nexport class Runtime<TState = any, TEvent = any> {\n public readonly config: Config<TState, TEvent>;\n\n constructor(config: Config<TState, TEvent>) {\n this.config = config;\n }\n\n /**\n * Helper to get the event type from an event object based on configuration.\n */\n private getEventType(event: TEvent): string {\n const key = this.config.eventKey || \"type\";\n return (event as any)[key] || \"*\";\n }\n\n /**\n * Helper to check if a value is a Melony Event.\n */\n private isEvent(val: any): val is TEvent {\n const key = this.config.eventKey || \"type\";\n return val && typeof val === \"object\" && typeof (val as any)[key] === \"string\";\n }\n\n /**\n * Process an incoming event through the runtime.\n * All event processing is handled by user-defined event handlers.\n */\n public async *run(\n event: TEvent,\n options?: RunOptions<TState>\n ): AsyncGenerator<TEvent> {\n const runId = options?.runId ?? generateId();\n const eventKey = this.config.eventKey || \"type\";\n\n // Resolve initial state: options.state > config.initialState > {}\n let state: TState;\n if (options?.state) {\n state = options.state;\n } else if (typeof this.config.initialState === \"function\") {\n state = await (this.config.initialState as any)();\n } else if (this.config.initialState) {\n // Use structuredClone if available, otherwise fallback to simple spread for safety\n state = typeof (globalThis as any).structuredClone === \"function\"\n ? (globalThis as any).structuredClone(this.config.initialState)\n : { ...this.config.initialState };\n } else {\n state = {} as TState;\n }\n\n const context: RuntimeContext<TState, TEvent> = {\n state,\n runtime: this,\n runId,\n suspend: (event?: TEvent) => {\n throw event || { [eventKey]: \"run-suspended\", data: {} };\n },\n };\n\n try {\n // 1. Call onStart hook\n if (this.config.onStart) {\n const startEvents = await this.config.onStart(context, event);\n if (startEvents) {\n for await (const lifecycleEvent of startEvents) {\n yield* this.runEventHandlers(lifecycleEvent, context);\n }\n }\n }\n\n // 2. Process the incoming event through handlers\n yield* this.runEventHandlers(event, context);\n } catch (error) {\n let eventToEmit: TEvent | undefined;\n\n if (this.isEvent(error)) {\n eventToEmit = error as TEvent;\n } else {\n eventToEmit = {\n [eventKey]: \"error\",\n data: {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n },\n } as unknown as TEvent;\n }\n\n if (eventToEmit) {\n yield* this.runEventHandlers(eventToEmit, context);\n }\n } finally {\n // 3. Call onEnd hook\n if (this.config.onEnd) {\n const endEvents = await this.config.onEnd(context);\n if (endEvents) {\n for await (const lifecycleEvent of endEvents) {\n yield* this.runEventHandlers(lifecycleEvent, context);\n }\n }\n }\n }\n }\n\n\n /**\n * Run all event handlers that match the given event type.\n */\n private async *runEventHandlers(\n event: TEvent,\n context: RuntimeContext<TState, TEvent>,\n ): AsyncGenerator<TEvent> {\n let currentEvent = event;\n const eventKey = this.config.eventKey || \"type\";\n\n // 1. Run global interceptors first\n const globalInterceptors = this.config.interceptors.get(\"*\") || [];\n for (const interceptor of globalInterceptors) {\n const result = await interceptor(currentEvent, context);\n if (result && typeof result === \"object\" && eventKey in (result as any)) {\n currentEvent = result as TEvent;\n }\n }\n\n // 2. Run specific interceptors for the (possibly new) event type\n // If currentEvent type is \"*\", it's already been handled by the global interceptors\n let eventType = this.getEventType(currentEvent);\n if (eventType !== \"*\") {\n const specificInterceptors = this.config.interceptors.get(eventType) || [];\n for (const interceptor of specificInterceptors) {\n const result = await interceptor(currentEvent, context);\n if (result && typeof result === \"object\" && eventKey in (result as any)) {\n currentEvent = result as TEvent;\n }\n }\n }\n\n eventType = this.getEventType(currentEvent);\n const wildcardHandlers = this.config.handlers.get(\"*\") || [];\n const specificHandlers = this.config.handlers.get(eventType) || [];\n // When type is missing, getEventType is \"*\"; do not register wildcard handlers twice.\n const handlers =\n eventType === \"*\"\n ? [...wildcardHandlers]\n : [...wildcardHandlers, ...specificHandlers];\n\n // First emit the event itself\n yield* this.emit(currentEvent, context);\n\n for (const handler of handlers) {\n const result = handler(currentEvent, context);\n if (result) {\n for await (const yieldedEvent of result) {\n // Recursively process yielded events through their handlers\n yield* this.runEventHandlers(yieldedEvent, context);\n }\n }\n }\n }\n\n /**\n * Internal helper to yield an event with metadata and trigger hooks.\n */\n private async *emit(\n event: TEvent,\n context: RuntimeContext<TState, TEvent>\n ): AsyncGenerator<TEvent> {\n if (this.config.onEvent) {\n await this.config.onEvent(context, event);\n }\n yield event;\n }\n}\n","import type { RunOptions } from \"../types\";\n\nexport interface CreateJsonResponseDeps<TState, TEvent> {\n run: (\n event: TEvent,\n options?: RunOptions<TState>\n ) => AsyncIterable<TEvent>;\n}\n\n/**\n * Run the agent to completion and return all emitted events as a JSON Response.\n * Useful for initialization or non-streaming requests.\n */\nexport async function createJsonResponse<TState, TEvent>(\n event: TEvent,\n options: RunOptions<TState> | undefined,\n deps: CreateJsonResponseDeps<TState, TEvent>\n): Promise<Response> {\n const events: TEvent[] = [];\n for await (const e of deps.run(event, options)) {\n events.push(e);\n }\n\n return new Response(JSON.stringify({ events }), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n","/**\n * Convert an async generator of events to an HTTP streaming response\n * Exported for backward compatibility and standalone usage\n */\nexport function createStreamResponse<TEvent = any>(\n generator: AsyncGenerator<TEvent>,\n): Response {\n const encoder = new TextEncoder();\n const stream = new ReadableStream({\n async start(controller) {\n try {\n for await (const message of generator) {\n // Format as SSE: data: {...}\\n\\n\n const chunk = `data: ${JSON.stringify(message)}\\n\\n`;\n controller.enqueue(encoder.encode(chunk));\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n","import { generateId } from \"./generate-id\";\n\nexport interface HandleMelonyRequestOptions<TState> {\n state?: (req: Request) => Promise<TState> | TState;\n}\n\nexport interface HandleMelonyRequestDeps<TState, TEvent> {\n eventKey: string;\n initialState?: TState | (() => TState | Promise<TState>);\n streamResponse: (\n event: TEvent,\n options?: { state?: TState; runId?: string }\n ) => Promise<Response>;\n}\n\n/**\n * Unified Web-Standard Request handler: parses Request and returns a streaming Response.\n */\nexport async function handleMelonyRequest<TState, TEvent>(\n request: Request,\n options: HandleMelonyRequestOptions<TState> | undefined,\n deps: HandleMelonyRequestDeps<TState, TEvent>\n): Promise<Response> {\n if (request.method === \"OPTIONS\") {\n const requested = request.headers.get(\"access-control-request-headers\");\n const defaultAllowHeaders =\n \"Content-Type, x-melony-thread-id, x-melony-run-id, x-melony-session-id, Authorization, Last-Event-ID\";\n const origin = request.headers.get(\"origin\");\n const allowOrigin = origin ?? \"*\";\n const headers: Record<string, string> = {\n \"Access-Control-Allow-Origin\": allowOrigin,\n \"Access-Control-Allow-Methods\": \"POST, GET, OPTIONS\",\n \"Access-Control-Allow-Headers\": requested ?? defaultAllowHeaders,\n };\n if (origin) {\n headers.Vary = \"Origin\";\n headers[\"Access-Control-Allow-Credentials\"] = \"true\";\n }\n const pnr = request.headers.get(\"access-control-request-private-network\");\n if (pnr?.toLowerCase() === \"true\") {\n headers[\"Access-Control-Allow-Private-Network\"] = \"true\";\n }\n return new Response(null, { status: 204, headers });\n }\n\n let event: TEvent;\n try {\n if (request.method === \"POST\") {\n event = await request.json();\n } else {\n const url = new URL(request.url);\n // Avoid defaulting GET to \"run\": browsers, probes, and EventSource use GET; reconnects\n // would re-trigger full runs. Use ?type=run when you intend orchestration via GET.\n event = {\n [deps.eventKey]: url.searchParams.get(\"type\") || \"http-get\",\n data: Object.fromEntries(url.searchParams.entries()),\n } as unknown as TEvent;\n }\n } catch {\n return new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n },\n });\n }\n\n const threadId =\n request.headers.get(\"x-melony-thread-id\") ||\n (event as { threadId?: string }).threadId ||\n generateId();\n const runId = request.headers.get(\"x-melony-run-id\") || generateId();\n const sessionId =\n request.headers.get(\"x-melony-session-id\") ||\n (event as { sessionId?: string }).sessionId ||\n generateId();\n\n let state: TState;\n if (options?.state) {\n state = await options.state(request);\n } else if (typeof deps.initialState === \"function\") {\n state = await (deps.initialState as () => TState | Promise<TState>)();\n } else if (deps.initialState) {\n state =\n typeof (globalThis as any).structuredClone === \"function\"\n ? (globalThis as any).structuredClone(deps.initialState)\n : { ...(deps.initialState as object) };\n } else {\n state = { threadId, runId, sessionId } as unknown as TState;\n }\n\n const response = await deps.streamResponse(event, { state, runId });\n const origin = request.headers.get(\"origin\");\n response.headers.set(\"Access-Control-Allow-Origin\", origin ?? \"*\");\n if (origin) {\n response.headers.set(\"Vary\", \"Origin\");\n response.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n const pnr = request.headers.get(\"access-control-request-private-network\");\n if (pnr?.toLowerCase() === \"true\") {\n response.headers.set(\"Access-Control-Allow-Private-Network\", \"true\");\n }\n return response;\n}\n","import { Runtime } from \"./runtime\";\nimport {\n Config,\n RuntimeContext,\n EventInterceptor,\n RunOptions,\n LifecycleHookResult,\n} from \"./types\";\nimport { createJsonResponse } from \"./utils/create-json-response\";\nimport { createStreamResponse } from \"./utils/create-stream-response\";\nimport { handleMelonyRequest } from \"./utils/handle-request\";\n\n/**\n * The Melony Runtime class.\n * This is the core class that powers the Melony framework.\n */\nexport const MelonyRuntime = Runtime;\n\n/**\n * A Melony plugin is a function that receives the builder and extends it.\n * This allows for modularizing common handlers.\n */\nexport type MelonyPlugin<TState = any, TEvent = any> = (\n builder: MelonyBuilder<TState, TEvent>\n) => void;\n\n/**\n * Fluent builder for creating Melony agents with excellent developer experience.\n * Provides method chaining for handlers and plugins with full TypeScript support.\n */\nexport class MelonyBuilder<\n TState = any,\n TEvent = any\n> {\n private config: Config<TState, TEvent>;\n\n constructor(initialConfig?: Partial<Config<TState, TEvent>>) {\n this.config = {\n handlers: initialConfig?.handlers ?? new Map(),\n interceptors: initialConfig?.interceptors ?? new Map(),\n eventKey: initialConfig?.eventKey ?? \"type\",\n initialState: initialConfig?.initialState,\n onStart: initialConfig?.onStart,\n onEnd: initialConfig?.onEnd,\n onEvent: initialConfig?.onEvent,\n };\n }\n\n /**\n * Configure the key in the event object that defines its type.\n * Defaults to \"type\".\n */\n eventKey(key: string): this {\n this.config.eventKey = key;\n return this;\n }\n\n /**\n * Configure the initial state for the runtime.\n * Supports a static object or a factory function.\n */\n initialState(state: TState | (() => TState | Promise<TState>)): this {\n this.config.initialState = state;\n return this;\n }\n\n /**\n * Register a hook called before the runtime starts processing events.\n */\n onStart(\n hook: (\n context: RuntimeContext<TState, TEvent>,\n initialEvent: TEvent\n ) => Promise<LifecycleHookResult<TEvent>> | LifecycleHookResult<TEvent>\n ): this {\n this.config.onStart = hook;\n return this;\n }\n\n /**\n * Register a hook called after the runtime has finished processing events.\n */\n onEnd(\n hook: (\n context: RuntimeContext<TState, TEvent>\n ) => Promise<LifecycleHookResult<TEvent>> | LifecycleHookResult<TEvent>\n ): this {\n this.config.onEnd = hook;\n return this;\n }\n\n /**\n * Register a hook called for every event emitted by the runtime.\n */\n onEvent(\n hook: (\n context: RuntimeContext<TState, TEvent>,\n event: TEvent\n ) => Promise<void> | void\n ): this {\n this.config.onEvent = hook;\n return this;\n }\n\n /**\n * Add an event handler for a specific event type. Supports method chaining.\n * The handler receives the narrowed event type based on the eventType string.\n */\n on<K extends (TEvent extends { type: string } ? TEvent[\"type\"] : string) | \"*\">(\n eventType: K,\n handler: (\n event: K extends \"*\" ? TEvent : Extract<TEvent, { type: K }>,\n context: RuntimeContext<TState, TEvent>\n ) => AsyncGenerator<TEvent, void, unknown> | void\n ): this {\n if (!this.config.handlers.has(eventType)) {\n this.config.handlers.set(eventType, []);\n }\n // Cast is safe because runtime only calls this handler for matching event types\n this.config.handlers.get(eventType)!.push(handler as any);\n return this;\n }\n\n /**\n * Register an interceptor that runs before any handlers.\n * Useful for logging, validation, or suspending for approval.\n */\n intercept(interceptor: EventInterceptor<TState, TEvent>): this;\n intercept<K extends (TEvent extends { type: string } ? TEvent[\"type\"] : string)>(\n eventType: K,\n interceptor: (\n event: Extract<TEvent, { type: K }>,\n context: RuntimeContext<TState, TEvent>\n ) => Promise<TEvent | void> | TEvent | void\n ): this;\n intercept(\n arg1: string | EventInterceptor<TState, TEvent>,\n arg2?: any\n ): this {\n if (typeof arg1 === \"string\") {\n const type = arg1;\n const interceptor = arg2!;\n if (!this.config.interceptors.has(type)) {\n this.config.interceptors.set(type, []);\n }\n this.config.interceptors.get(type)!.push(interceptor as any);\n } else {\n const interceptor = arg1;\n if (!this.config.interceptors.has(\"*\")) {\n this.config.interceptors.set(\"*\", []);\n }\n this.config.interceptors.get(\"*\")!.push(interceptor);\n }\n return this;\n }\n\n /**\n * Use a plugin to extend the builder.\n * This is ideal for modularizing common handlers.\n */\n use(plugin: MelonyPlugin<TState, TEvent>): this {\n plugin(this);\n return this;\n }\n\n /**\n * Build and return the Melony runtime instance.\n * This is the final method in the fluent chain.\n */\n build(): Runtime<TState, TEvent> {\n return new Runtime(this.config);\n }\n\n /**\n * Execute the runtime for a specific event.\n */\n async run(\n event: TEvent,\n options?: RunOptions<TState>\n ): Promise<AsyncGenerator<TEvent>> {\n const runtime = this.build();\n return runtime.run(event, options);\n }\n\n /**\n * Execute and stream the response for an event.\n * This is a convenience method that builds the runtime and calls run().\n */\n async streamResponse(\n event: TEvent,\n options?: { state?: TState; runId?: string }\n ): Promise<Response> {\n const runtime = this.build();\n const generator = runtime.run(event, options);\n return createStreamResponse(generator);\n }\n\n /**\n * Execute the agent and return the data from the last event of a specific type as a JSON response.\n * Ideal for initialization or non-streaming requests where you only need the final UI state.\n */\n async jsonResponse(\n event: TEvent,\n options?: RunOptions<TState>\n ): Promise<Response> {\n return createJsonResponse(event, options, {\n run: (e, opts) => this.build().run(e, opts),\n });\n }\n\n /**\n * A unified Web-Standard Request Handler.\n * Automatically parses a Request and returns a streaming Response.\n */\n async handle(\n request: Request,\n options?: { state?: (req: Request) => Promise<TState> | TState }\n ): Promise<Response> {\n return handleMelonyRequest(request, options, {\n eventKey: this.config.eventKey || \"type\",\n initialState: this.config.initialState,\n streamResponse: (event: TEvent, opts) => this.streamResponse(event, opts),\n });\n }\n\n /**\n * Get the current configuration (useful for debugging or serialization).\n */\n getConfig(): Config<TState, TEvent> {\n return { ...this.config };\n }\n}\n\n/**\n * Factory function to create a new Melony builder instance.\n * This is the entry point for the fluent API.\n */\nexport function melony<\n TState = any,\n TEvent = any\n>(initialConfig?: Partial<Config<TState, TEvent>>): MelonyBuilder<TState, TEvent> {\n return new MelonyBuilder<TState, TEvent>(initialConfig);\n}\n"]}
|