@maravilla-labs/platform 0.2.2 → 0.2.5
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/events.d.ts +16 -1
- package/dist/events.js.map +1 -1
- package/package.json +1 -1
- package/src/events.ts +14 -2
package/dist/events.d.ts
CHANGED
|
@@ -127,11 +127,26 @@ interface DeployEvent {
|
|
|
127
127
|
interface EventCtx {
|
|
128
128
|
/** Per-tenant env vars. */
|
|
129
129
|
env: Record<string, string>;
|
|
130
|
+
/** KV store — same shape as `getPlatform().env.KV` / `platform.kv`. */
|
|
131
|
+
kv?: unknown;
|
|
132
|
+
/** MongoDB-style database — same shape as `getPlatform().env.DB`. */
|
|
133
|
+
database?: unknown;
|
|
134
|
+
/** Object storage. */
|
|
135
|
+
storage?: unknown;
|
|
136
|
+
/** Durable queue producer (`.send(name, payload, opts?)`). */
|
|
137
|
+
queue?: {
|
|
138
|
+
send: (name: string, payload: unknown, opts?: unknown) => Promise<string>;
|
|
139
|
+
};
|
|
140
|
+
/** Auth service — register/login/logout/user CRUD/etc. */
|
|
141
|
+
auth?: unknown;
|
|
142
|
+
/** Web Push service. */
|
|
143
|
+
push?: unknown;
|
|
144
|
+
/** Full platform object — escape hatch for services not surfaced above. */
|
|
145
|
+
platform?: unknown;
|
|
130
146
|
/** Trace correlation id — propagate through logs. */
|
|
131
147
|
traceId: string;
|
|
132
148
|
tenant: string;
|
|
133
149
|
handlerId: string;
|
|
134
|
-
[extra: string]: unknown;
|
|
135
150
|
}
|
|
136
151
|
declare const TRIGGER_SYMBOL: "__maravilla_trigger";
|
|
137
152
|
interface RegisteredHandler<Event = unknown, Ctx = EventCtx> {
|
package/dist/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/events.ts"],"sourcesContent":["/**\n * @fileoverview Event handler registration helpers for Maravilla.\n *\n * User apps declare event handlers in `events.ts` or `events/*.ts`:\n *\n * ```ts\n * import { onKvChange, defineEvent } from '@maravilla-labs/platform/events';\n *\n * export const invalidateCache = onKvChange(\n * { namespace: 'config', keyPattern: 'feature:*' },\n * async (event, ctx) => { await ctx.kv.delete('cache', event.key!); },\n * );\n * ```\n *\n * These helpers are pure factories. They produce a `RegisteredHandler`\n * marker object that the build pipeline (`@maravilla-labs/functions`\n * `discoverEvents`) detects by its `__maravilla_trigger` property.\n * The Rust event dispatcher uses the trigger config from the manifest\n * and invokes the bundled handler via `globalThis.handleEvent(id, event)`.\n */\n\nimport type { RenEvent } from './ren.js';\n\n// ============ Trigger descriptors ============\n// Kept structurally identical to adapter-core's `EventTrigger` — duplicated\n// here so the runtime SDK has no build-time dep on adapter-core. Keep in sync.\n\nexport type EventTrigger =\n | EventTriggerKv\n | EventTriggerDb\n | EventTriggerAuth\n | EventTriggerSchedule\n | EventTriggerQueue\n | EventTriggerChannel\n | EventTriggerDeploy\n | EventTriggerRen;\n\nexport interface EventTriggerKv {\n kind: 'kv';\n namespace?: string;\n keyPattern?: string;\n op?: 'put' | 'delete' | 'expired';\n}\n\nexport interface EventTriggerDb {\n kind: 'db';\n collection: string;\n op?: 'insert' | 'update' | 'delete';\n}\n\nexport type AuthOp =\n | 'registered'\n | 'logged_in'\n | 'logged_out'\n | 'logged_out_all'\n | 'deleted'\n | 'updated';\n\nexport interface EventTriggerAuth {\n kind: 'auth';\n op?: AuthOp;\n}\n\nexport interface EventTriggerSchedule {\n kind: 'schedule';\n cron: string;\n}\n\nexport interface EventTriggerQueue {\n kind: 'queue';\n name: string;\n batch?: number;\n maxAttempts?: number;\n}\n\nexport interface EventTriggerChannel {\n kind: 'channel';\n channel: string;\n type?: string;\n}\n\nexport interface EventTriggerDeploy {\n kind: 'deploy';\n phase: 'ready' | 'draining' | 'stopped';\n}\n\nexport interface EventTriggerRen {\n kind: 'ren';\n match: { r?: string; t?: string; ns?: string };\n}\n\n// ============ Event payload shapes ============\n\nexport interface KvChangeEvent {\n op: 'put' | 'delete' | 'expired';\n namespace: string;\n key: string;\n /** Present on `put`. */\n value?: unknown;\n ts: number;\n}\n\nexport interface DbChangeEvent {\n op: 'insert' | 'update' | 'delete';\n collection: string;\n id: string;\n doc?: unknown;\n before?: unknown;\n after?: unknown;\n ts: number;\n}\n\nexport interface AuthEvent {\n op: AuthOp;\n userId: string;\n /**\n * Op-specific payload:\n * - `registered` → `{ email, provider, profile }` where `profile` is the\n * app's custom fields passed to `platform.auth.register({ profile: {...} })`.\n * - `logged_in` → `{ email }`\n * - `logged_out` → `{ sessionId }`\n * - `logged_out_all` / `deleted` / `updated` → null or empty.\n */\n data?: {\n email?: string;\n provider?: string;\n profile?: Record<string, unknown> | null;\n sessionId?: string;\n [k: string]: unknown;\n };\n ts: number;\n}\n\nexport interface ScheduleEvent {\n cron: string;\n scheduledAt: number;\n firedAt: number;\n}\n\nexport interface QueueMessage<T = unknown> {\n id: string;\n payload: T;\n attempt: number;\n enqueuedAt: number;\n}\n\nexport interface ChannelEvent<T = unknown> {\n channel: string;\n type: string;\n data?: T;\n uid?: string;\n ts: number;\n}\n\nexport interface DeployEvent {\n phase: 'ready' | 'draining' | 'stopped';\n ts: number;\n}\n\n// ============ Handler context ============\n\nexport interface EventCtx {\n /** Per-tenant env vars. */\n env: Record<string, string>;\n /**
|
|
1
|
+
{"version":3,"sources":["../src/events.ts"],"sourcesContent":["/**\n * @fileoverview Event handler registration helpers for Maravilla.\n *\n * User apps declare event handlers in `events.ts` or `events/*.ts`:\n *\n * ```ts\n * import { onKvChange, defineEvent } from '@maravilla-labs/platform/events';\n *\n * export const invalidateCache = onKvChange(\n * { namespace: 'config', keyPattern: 'feature:*' },\n * async (event, ctx) => { await ctx.kv.delete('cache', event.key!); },\n * );\n * ```\n *\n * These helpers are pure factories. They produce a `RegisteredHandler`\n * marker object that the build pipeline (`@maravilla-labs/functions`\n * `discoverEvents`) detects by its `__maravilla_trigger` property.\n * The Rust event dispatcher uses the trigger config from the manifest\n * and invokes the bundled handler via `globalThis.handleEvent(id, event)`.\n */\n\nimport type { RenEvent } from './ren.js';\n\n// ============ Trigger descriptors ============\n// Kept structurally identical to adapter-core's `EventTrigger` — duplicated\n// here so the runtime SDK has no build-time dep on adapter-core. Keep in sync.\n\nexport type EventTrigger =\n | EventTriggerKv\n | EventTriggerDb\n | EventTriggerAuth\n | EventTriggerSchedule\n | EventTriggerQueue\n | EventTriggerChannel\n | EventTriggerDeploy\n | EventTriggerRen;\n\nexport interface EventTriggerKv {\n kind: 'kv';\n namespace?: string;\n keyPattern?: string;\n op?: 'put' | 'delete' | 'expired';\n}\n\nexport interface EventTriggerDb {\n kind: 'db';\n collection: string;\n op?: 'insert' | 'update' | 'delete';\n}\n\nexport type AuthOp =\n | 'registered'\n | 'logged_in'\n | 'logged_out'\n | 'logged_out_all'\n | 'deleted'\n | 'updated';\n\nexport interface EventTriggerAuth {\n kind: 'auth';\n op?: AuthOp;\n}\n\nexport interface EventTriggerSchedule {\n kind: 'schedule';\n cron: string;\n}\n\nexport interface EventTriggerQueue {\n kind: 'queue';\n name: string;\n batch?: number;\n maxAttempts?: number;\n}\n\nexport interface EventTriggerChannel {\n kind: 'channel';\n channel: string;\n type?: string;\n}\n\nexport interface EventTriggerDeploy {\n kind: 'deploy';\n phase: 'ready' | 'draining' | 'stopped';\n}\n\nexport interface EventTriggerRen {\n kind: 'ren';\n match: { r?: string; t?: string; ns?: string };\n}\n\n// ============ Event payload shapes ============\n\nexport interface KvChangeEvent {\n op: 'put' | 'delete' | 'expired';\n namespace: string;\n key: string;\n /** Present on `put`. */\n value?: unknown;\n ts: number;\n}\n\nexport interface DbChangeEvent {\n op: 'insert' | 'update' | 'delete';\n collection: string;\n id: string;\n doc?: unknown;\n before?: unknown;\n after?: unknown;\n ts: number;\n}\n\nexport interface AuthEvent {\n op: AuthOp;\n userId: string;\n /**\n * Op-specific payload:\n * - `registered` → `{ email, provider, profile }` where `profile` is the\n * app's custom fields passed to `platform.auth.register({ profile: {...} })`.\n * - `logged_in` → `{ email }`\n * - `logged_out` → `{ sessionId }`\n * - `logged_out_all` / `deleted` / `updated` → null or empty.\n */\n data?: {\n email?: string;\n provider?: string;\n profile?: Record<string, unknown> | null;\n sessionId?: string;\n [k: string]: unknown;\n };\n ts: number;\n}\n\nexport interface ScheduleEvent {\n cron: string;\n scheduledAt: number;\n firedAt: number;\n}\n\nexport interface QueueMessage<T = unknown> {\n id: string;\n payload: T;\n attempt: number;\n enqueuedAt: number;\n}\n\nexport interface ChannelEvent<T = unknown> {\n channel: string;\n type: string;\n data?: T;\n uid?: string;\n ts: number;\n}\n\nexport interface DeployEvent {\n phase: 'ready' | 'draining' | 'stopped';\n ts: number;\n}\n\n// ============ Handler context ============\n\nexport interface EventCtx {\n /** Per-tenant env vars. */\n env: Record<string, string>;\n /** KV store — same shape as `getPlatform().env.KV` / `platform.kv`. */\n kv?: unknown;\n /** MongoDB-style database — same shape as `getPlatform().env.DB`. */\n database?: unknown;\n /** Object storage. */\n storage?: unknown;\n /** Durable queue producer (`.send(name, payload, opts?)`). */\n queue?: { send: (name: string, payload: unknown, opts?: unknown) => Promise<string> };\n /** Auth service — register/login/logout/user CRUD/etc. */\n auth?: unknown;\n /** Web Push service. */\n push?: unknown;\n /** Full platform object — escape hatch for services not surfaced above. */\n platform?: unknown;\n /** Trace correlation id — propagate through logs. */\n traceId: string;\n tenant: string;\n handlerId: string;\n}\n\n// ============ Registered handler marker ============\n\nexport const TRIGGER_SYMBOL = '__maravilla_trigger' as const;\n\nexport interface RegisteredHandler<Event = unknown, Ctx = EventCtx> {\n readonly [TRIGGER_SYMBOL]: EventTrigger;\n readonly handler: (event: Event, ctx: Ctx) => unknown | Promise<unknown>;\n}\n\nfunction register<Event, Ctx = EventCtx>(\n trigger: EventTrigger,\n handler: (event: Event, ctx: Ctx) => unknown | Promise<unknown>,\n): RegisteredHandler<Event, Ctx> {\n return { [TRIGGER_SYMBOL]: trigger, handler };\n}\n\n// ============ Public factory helpers ============\n\nexport function onKvChange(\n config: Omit<EventTriggerKv, 'kind'>,\n handler: (event: KvChangeEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<KvChangeEvent> {\n return register({ kind: 'kv', ...config }, handler);\n}\n\nexport function onDbChange(\n config: Omit<EventTriggerDb, 'kind'>,\n handler: (event: DbChangeEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<DbChangeEvent> {\n return register({ kind: 'db', ...config }, handler);\n}\n\n/**\n * React to user authentication events: registration, login, logout,\n * deletion, update. Omit `op` to match all auth events; set it to\n * narrow to a specific lifecycle transition.\n *\n * ```ts\n * export const welcomeEmail = onAuth(\n * { op: 'registered' },\n * async (event, ctx) => {\n * await sendWelcomeEmail(event.data?.email);\n * },\n * );\n * ```\n */\nexport function onAuth(\n config: Omit<EventTriggerAuth, 'kind'>,\n handler: (event: AuthEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<AuthEvent> {\n return register({ kind: 'auth', ...config }, handler);\n}\n\nexport function onSchedule(\n cron: string,\n handler: (event: ScheduleEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<ScheduleEvent> {\n return register({ kind: 'schedule', cron }, handler);\n}\n\nexport function onQueue<T = unknown>(\n name: string,\n config: Omit<EventTriggerQueue, 'kind' | 'name'>,\n handler: (messages: QueueMessage<T>[], ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<QueueMessage<T>[]> {\n return register({ kind: 'queue', name, ...config }, handler);\n}\n\nexport function onChannel<T = unknown>(\n config: Omit<EventTriggerChannel, 'kind'>,\n handler: (event: ChannelEvent<T>, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<ChannelEvent<T>> {\n return register({ kind: 'channel', ...config }, handler);\n}\n\nexport function onDeploy(\n phase: EventTriggerDeploy['phase'],\n handler: (event: DeployEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<DeployEvent> {\n return register({ kind: 'deploy', phase }, handler);\n}\n\n/** Escape hatch for arbitrary `RenEvent` matches. */\nexport function defineEvent(\n config: Omit<EventTriggerRen, 'kind'>,\n handler: (event: RenEvent, ctx: EventCtx) => unknown | Promise<unknown>,\n): RegisteredHandler<RenEvent> {\n return register({ kind: 'ren', ...config }, handler);\n}\n\n/** Type guard used by the build-time discoverer and the runtime registry. */\nexport function isRegisteredHandler(value: unknown): value is RegisteredHandler {\n return (\n typeof value === 'object' &&\n value !== null &&\n TRIGGER_SYMBOL in value &&\n typeof (value as Record<string, unknown>).handler === 'function'\n );\n}\n"],"mappings":";AA0LO,IAAM,iBAAiB;AAO9B,SAAS,SACP,SACA,SAC+B;AAC/B,SAAO,EAAE,CAAC,cAAc,GAAG,SAAS,QAAQ;AAC9C;AAIO,SAAS,WACd,QACA,SACkC;AAClC,SAAO,SAAS,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO;AACpD;AAEO,SAAS,WACd,QACA,SACkC;AAClC,SAAO,SAAS,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO;AACpD;AAgBO,SAAS,OACd,QACA,SAC8B;AAC9B,SAAO,SAAS,EAAE,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO;AACtD;AAEO,SAAS,WACd,MACA,SACkC;AAClC,SAAO,SAAS,EAAE,MAAM,YAAY,KAAK,GAAG,OAAO;AACrD;AAEO,SAAS,QACd,MACA,QACA,SACsC;AACtC,SAAO,SAAS,EAAE,MAAM,SAAS,MAAM,GAAG,OAAO,GAAG,OAAO;AAC7D;AAEO,SAAS,UACd,QACA,SACoC;AACpC,SAAO,SAAS,EAAE,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO;AACzD;AAEO,SAAS,SACd,OACA,SACgC;AAChC,SAAO,SAAS,EAAE,MAAM,UAAU,MAAM,GAAG,OAAO;AACpD;AAGO,SAAS,YACd,QACA,SAC6B;AAC7B,SAAO,SAAS,EAAE,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO;AACrD;AAGO,SAAS,oBAAoB,OAA4C;AAC9E,SACE,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SAClB,OAAQ,MAAkC,YAAY;AAE1D;","names":[]}
|
package/package.json
CHANGED
package/src/events.ts
CHANGED
|
@@ -162,12 +162,24 @@ export interface DeployEvent {
|
|
|
162
162
|
export interface EventCtx {
|
|
163
163
|
/** Per-tenant env vars. */
|
|
164
164
|
env: Record<string, string>;
|
|
165
|
+
/** KV store — same shape as `getPlatform().env.KV` / `platform.kv`. */
|
|
166
|
+
kv?: unknown;
|
|
167
|
+
/** MongoDB-style database — same shape as `getPlatform().env.DB`. */
|
|
168
|
+
database?: unknown;
|
|
169
|
+
/** Object storage. */
|
|
170
|
+
storage?: unknown;
|
|
171
|
+
/** Durable queue producer (`.send(name, payload, opts?)`). */
|
|
172
|
+
queue?: { send: (name: string, payload: unknown, opts?: unknown) => Promise<string> };
|
|
173
|
+
/** Auth service — register/login/logout/user CRUD/etc. */
|
|
174
|
+
auth?: unknown;
|
|
175
|
+
/** Web Push service. */
|
|
176
|
+
push?: unknown;
|
|
177
|
+
/** Full platform object — escape hatch for services not surfaced above. */
|
|
178
|
+
platform?: unknown;
|
|
165
179
|
/** Trace correlation id — propagate through logs. */
|
|
166
180
|
traceId: string;
|
|
167
181
|
tenant: string;
|
|
168
182
|
handlerId: string;
|
|
169
|
-
// Platform services are attached by the runtime at invoke time.
|
|
170
|
-
[extra: string]: unknown;
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
// ============ Registered handler marker ============
|