autotel
Version:
Write Once, Observe Anywhere
59 lines (52 loc) • 1.39 kB
text/typescript
import { track } from './track';
import { hashJson } from './stable-hash';
import type { EventSchemaMetadata } from './event-subscriber';
type SafeParseResult<T> =
| { success: true; data: T }
| { success: false; error: unknown };
export interface SchemaLike<T> {
safeParse(input: unknown): SafeParseResult<T>;
}
export interface DefineEventOptions<S> {
toJsonSchema?: (schema: S) => unknown;
}
export interface DefinedEvent<Name extends string, Payload> {
readonly name: Name;
readonly schemaMetadata?: EventSchemaMetadata;
track(payload: Payload): void;
}
export function defineEvent<
Name extends string,
Payload,
S extends SchemaLike<Payload>,
>(
name: Name,
schema: S,
options: DefineEventOptions<S> = {},
): DefinedEvent<Name, Payload> {
const jsonSchema = options.toJsonSchema?.(schema);
const schemaMetadata = jsonSchema
? {
source: 'zod' as const,
jsonSchema,
hash: hashJson(jsonSchema),
}
: undefined;
return {
name,
schemaMetadata,
track(payload: Payload) {
const parsed = schema.safeParse(payload);
if (!parsed.success) {
throw new Error(
`Invalid payload for event "${name}". Schema validation failed.`,
);
}
track(
name,
parsed.data,
schemaMetadata ? { schema: schemaMetadata } : undefined,
);
},
};
}