chore(template): clean-slate template snapshot from bb4a0c7
Curated, product-agnostic snapshot of the post-story-04 tree: demo content deleted, auth-only reference feature, web-next shell, all gates green. Product-specific docs, ADRs 027-029, PRDs/epics/archive, editor library traces, and product naming are curated out; generic template repairs (coverage provider devDeps, root test:coverage script, live lint fixes, root-only release-please) are kept. See TEMPLATE.md for provenance, curation list, and usage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
35
packages/core-analytics/src/with-analytics.ts
Normal file
35
packages/core-analytics/src/with-analytics.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { IAnalytics } from "./analytics.interface";
|
||||
import { attachBrand } from "@repo/core-shared/conformance";
|
||||
|
||||
/**
|
||||
* Phantom-type brand attached at wrap time by `withAnalytics`. The conformance
|
||||
* system uses this as the type-level seam for use cases that declare
|
||||
* `analyticsEvents: [...]` in their manifest — without `__analyzed`, the
|
||||
* binding is not assignable to `ProductionUseCase<I, O, M>` when M demands it.
|
||||
* At runtime the brand is a non-enumerable property attached by `attachBrand`
|
||||
* from `@repo/core-shared/conformance`, so the boot-time assertion can verify
|
||||
* the binding went through the analytics-aware path.
|
||||
*/
|
||||
export type Analyzed<F> = F & { readonly __analyzed: true };
|
||||
|
||||
/**
|
||||
* Use-case wrapper applied at DI bind time. The wrapper is a thin closure
|
||||
* that forwards to `fn` unchanged and carries the `__analyzed` brand. The
|
||||
* forward closure (instead of returning `fn` directly) keeps the brand on
|
||||
* a fresh function so the caller's original `fn` is not mutated — important
|
||||
* when the same factory output is used elsewhere unwrapped (dev-seed paths,
|
||||
* tests).
|
||||
*/
|
||||
export function withAnalytics<Args extends unknown[], R>(
|
||||
// The wrapper attaches the brand and ensures the analytics dependency is
|
||||
// available at bind time. Actual `analytics.track()` calls live in the
|
||||
// use case body — only the use case knows which properties to extract
|
||||
// from its input/output for the analytics event.
|
||||
analytics: IAnalytics,
|
||||
fn: (...args: Args) => Promise<R>,
|
||||
): Analyzed<(...args: Args) => Promise<R>> {
|
||||
void analytics;
|
||||
const wrapped: (...args: Args) => Promise<R> = (...args) => fn(...args);
|
||||
attachBrand(wrapped, "__analyzed");
|
||||
return wrapped as Analyzed<(...args: Args) => Promise<R>>;
|
||||
}
|
||||
Reference in New Issue
Block a user