npm.io
2.1.0 • Published 3d ago

@signap/signals-angular

Licence
Apache-2.0
Version
2.1.0
Deps
1
Size
49 kB
Vulns
0
Weekly
0

@signap/signals-angular

Angular (standalone) wrapper for @signap/signals-web — a provideSignals() provider plus an injectVisitorData() helper that mirror the React hook and Vue composable.

Install

pnpm add @signap/signals-angular
# @angular/core and @angular/common are peerDependencies (>=17 <21)

Usage

Register the agent once with provideSignals() at bootstrap, then call injectVisitorData() in any component below it.

Provider (app bootstrap)
// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { provideSignals } from "@signap/signals-angular";
import { AppComponent } from "./app.component";

bootstrapApplication(AppComponent, {
  providers: [
    provideSignals({
      apiKey: "pk_live_...",
      endpoint: "https://ingest.signap.example",
    }),
  ],
});
Consume (injectVisitorData)
// visitor-badge.component.ts
import { Component } from "@angular/core";
import { injectVisitorData } from "@signap/signals-angular";

@Component({
  selector: "visitor-badge",
  standalone: true,
  template: `
    @if (visitor.isLoading()) {
      <p>Identifying…</p>
    } @else if (visitor.error()) {
      <p>Failed: {{ visitor.error()?.message }}</p>
    } @else {
      <p>visitor: {{ visitor.data()?.visitorId }}</p>
      <p>confidence: {{ visitor.data()?.confidence }}</p>
      <button (click)="visitor.refetch()">Re-identify</button>
    }
  `,
})
export class VisitorBadgeComponent {
  // Field initializers run in the injection context, so injectVisitorData() is valid here.
  readonly visitor = injectVisitorData({ tag: "page-view" });
}

Helper shape (v2)

injectVisitorData() runs agent.identify() once when the agent is ready and exposes the resolved visitor as Angular signals. ADR §A2 means one round-trip — no separate ack/lookup transition.

field type when populated
data Signal<IdentifyResult | undefined> once agent.identify() resolves
isLoading Signal<boolean> true between call time and data
error Signal<Error | null> last failure (load / identify)
refetch () => Promise<void> re-run agent.identify()

Read each signal by calling it (visitor.data()), in a template or a computed/effect.

SSR-safe: provideSignals() gates SignalsAgent.load() behind isPlatformBrowser(PLATFORM_ID), so it never runs during Angular Universal / prerender server rendering.

Endpoint (required)

provideSignals() takes the underlying AgentLoadOptions. endpoint is required — the published SDK ships no baked default host (the region→host map is empty in this alpha), so pass an explicit endpoint (a string or a callback). See the @signap/signals-web README (Endpoint section).

opts is snapshotted at bootstrap (later changes are ignored — re-bootstrap to swap apiKey/endpoint), the same contract as the React/Vue wrappers.

Why decorator-free

The package ships a functional provider, an inject() helper, and a plain class wired through a DI factory — no @Injectable/@Component decorators. That keeps it AOT-safe under a plain tsup build (no ng-packagr / partial-Ivy step needed) and importable from any Angular 17+ app.