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:
2026-07-12 20:40:54 +02:00
commit f77e6ea881
1062 changed files with 105156 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
import { describe, expect, it, vi } from "vitest";
import { render, renderHook } from "@testing-library/react";
import { RecordingAnalytics } from "@repo/core-testing";
import {
AnalyticsContextError,
AnalyticsProvider,
useAnalytics,
} from "@/react/index";
function Tracker() {
const analytics = useAnalytics();
analytics.track("test.event");
return null;
}
describe("AnalyticsProvider", () => {
it("makes analytics available through context and track flows through", () => {
const recording = new RecordingAnalytics();
render(
<AnalyticsProvider value={recording}>
<Tracker />
</AnalyticsProvider>,
);
expect(recording.tracked).toContainEqual({ event: "test.event" });
});
});
describe("useAnalytics", () => {
it("throws AnalyticsContextError when called outside a provider", () => {
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
try {
expect(() => renderHook(() => useAnalytics())).toThrow(
AnalyticsContextError,
);
} finally {
spy.mockRestore();
}
});
});

View File

@@ -0,0 +1,33 @@
import { createContext, useContext, type ReactNode } from "react";
import type { IAnalytics } from "../analytics.interface";
const AnalyticsContext = createContext<IAnalytics | null>(null);
export class AnalyticsContextError extends Error {
constructor() {
super("useAnalytics() must be called within an <AnalyticsProvider>.");
this.name = "AnalyticsContextError";
}
}
export function AnalyticsProvider({
value,
children,
}: {
value: IAnalytics;
children: ReactNode;
}) {
return (
<AnalyticsContext.Provider value={value}>
{children}
</AnalyticsContext.Provider>
);
}
export function useAnalytics(): IAnalytics {
const analytics = useContext(AnalyticsContext);
if (analytics === null) {
throw new AnalyticsContextError();
}
return analytics;
}

View File

@@ -0,0 +1,5 @@
export {
AnalyticsProvider,
useAnalytics,
AnalyticsContextError,
} from "./analytics-provider";