v0.5.0
Minor Changes
-
76025f4: Simplification + declarative-response pass: internals consolidated, the authoring surface extended (source-scoped
defineEvent), and the HTTP reply repositioned to the invocation layer as a self-describing declaration (breaking, pre-adoption).- Removed dead export
NotImplementedError(root and/core). It was a Phase-0 scaffolding relic: no runtime code path ever threw it, so nothing could ever catch it. Migration: delete any import of it — there is no replacement because there was no behavior. - The three Hasura sources (
hasuraEvent,hasuraCron,hasuraAction) now share onecallableSourceassembly helper instead of three copy-pasted factory blocks; their runtime shape (callable + attached authoring helpers + pluginname) is pinned by new tests. handle()anddryRun()share one intake pipeline (extract → normalize → augment), and the response seams share one error-mapping path — the invocation lifecycle now reads in one place.- Consolidated six copies of the
crypto.randomUUIDfallback and two copies ofisJobDefinitioninto single internal helpers; the two Netlify v2 platforms share the Web-Responserejection formatter. webhookfactory now carries the typed authoring helpers (additive):webhook.detector<TBody>(fn)/webhook.prepare<TBody>(fn)work on the bare factory value (uniform with the Hasura family), so an event module can typectx.bodywithout constructing the vendor-configured source that lives in the entry file. NewWebhookAuthoringinterface; runtime behavior unchanged (identity wrappers).- Source-scoped
defineEvent(additive): every source now carries a typed module builder —hasuraEvent.defineEvent<Row>({ … }),webhook.defineEvent<Body>({ … }),hasuraAction.defineEvent<Input>({ … }),hasuraCron.defineEvent<Payload>({ … }). The one type parameter on the outer call types every inline(ctx) => …seam (detector,prepare) with the source's enriched context, so detectors can be authored inline with no per-seam wrapper. At runtime it is coredefineEvent(name branding only). New core typeSourceEventModule(type-only). The generic rootdefineEventis unchanged and remains the full-inference path (ctx.preparedfromprepare, D32). - BREAKING (pre-adoption): the HTTP reply moved to the invocation layer —
kit.handler({ before, after })(ADR-026, re-amended). A module never declares an HTTP reply: modules own detection + jobs; one invocation has ONE wire reply and the handler declares it.aftertakes one of two self-naming modes:{ body }(a constant — data, not code, so it provably cannot wait on or be changed by the work) or{ fromResults: (result) => body }(arbitrary business logic over the PRESCRIBED typed rollup the runtime builds —InvocationResultwith every detector'sEventOutcomeand every job'sJobExecution; throwClientError/ActionErrorfor the error mapping). Optionalstatus/headers(ResponseWire— the web-standardResponseInitfields as data) ride beside the mode; platform adapters map everything (new Response(body, init)on v2,{ statusCode, headers, body }on classic/Lambda).afteris skipped on a framework error (the 500 retry contract) and never clobbers a pre-dispatch client rejection (webhookrejectUnverified).{ fromResults }is rejected under a background/202 platform — "202 first, then work" is a PLATFORM choice (netlifyBackgroundPlatform), not anaftermode. The earlier per-moduleresolve/respond/responsefields are all removed (registering them throws with the migration pointer); an action/webhook's work runs as JOBS and the reply is composed from their outputs.KitEventDescription.response/FlowResponseKindare removed from describe()/flow output (events no longer have response kinds); theexpectFlow(...).respondsWith(...)testing assertion is removed with them. New core typesHandlerResponse/ResponseBody/ResponseWire. registerEvent/registerEventsnow acceptEventModule<any, any, any>(type-level widening): a source-typed module registers without a variance cast under strict compiler flags (e.g.exactOptionalPropertyTypes). Runtime unchanged.docs/guide.html: documentedkit.dryRun()and the Hasura sources' factory/config form (inbound token discovery) in the API reference; replaced the webhook walkthrough with a real Stripepayment_intent.succeededexample (now authored withwebhook.defineEvent<StripePaymentEvent>and the reply declared atkit.handler({ after: { body } })) and thehmacVerifypreset (the previous example called.detectoron the bare factory — which didn't exist before this change — and showed retry semantics that don't match Stripe's redeliver-on-any-non-2xx contract).
- Removed dead export