seedypea-client
seedypea-client is the browser package. It collects events, binds declarative HTML attributes, manages local tactic state, and includes small web components.
import { init, pageView, track } from "seedypea-client";
init({ endpoint: "/sp/events" });
pageView();
track("AddToCart", { item: "pants" });
Modes
Edge Mode
Edge mode sends same-origin requests to your edge collector. The seedypea edge helper owns the first-party HttpOnly anonymous id.
init({ endpoint: "/sp/events" });
If writeKey is omitted, init() defaults to edge mode. When using edge mode, pass a non-default endpoint.
Direct Mode
Direct mode sends straight to Seedy Pea. The browser stores an anonymous id in localStorage.
init({
projectId: "proj_...",
writeKey: "wk_..."
});
Direct mode defaults to https://app.seedy-pea.com/v1/events.
API
init(config)
Initializes the client.
const result = init({
endpoint: "/sp/events",
mode: "edge"
});
result.mode;
result.anonymousId;
In direct mode, projectId and writeKey are required. In edge mode, endpoint is required unless you deliberately override the hosted default.
track(type, detail)
Sends one event.
await track("ProductViewed", {
sku: "sku_123",
path: location.pathname
});
type must be a non-empty string. Public event types accepted by the HTTP API must match ^[A-Za-z][A-Za-z0-9_.]{0,62}$.
pageView(detail)
Sends PageViewed with page metadata.
await pageView({ surface: "homepage" });
The default detail includes path, href, title, and referrer.
identify(ids, traits)
Sends Identify.
await identify(
{ email: "ada@example.com" },
{ plan: "founder" }
);
bind(root, options)
Binds elements with sp-event or sp-tactic.
<button sp-event="PersonaSelected" sp-prop-persona="developer">
Developer
</button>
import { bind } from "seedypea-client";
const cleanup = bind(document, { observe: true });
Attributes:
| Attribute | Description |
|---|---|
sp-event |
Event type to track. |
sp-tactic |
Registered tactic name to run. |
sp-on |
DOM event name. Defaults to click. |
sp-prop-* |
String props passed as event detail or tactic props. |
sp-prevent-default |
true or false. Tactics on forms submit-prevent by default. |
sp-requires-consent |
Suppresses the action locally unless consent for that category is granted. |
When consent suppresses an action, the client sends no event. Trusted
sp.event.suppressed receipts are substrate-emitted only.
tactics
Local tactic registry and profile-aware state.
import { tactics, track } from "seedypea-client";
tactics.register("lead-capture", async ({ props }) => {
await track("LeadCaptureOpened", props);
});
tactics.open("lead-capture");
tactics.dismiss("lead-capture");
const unsubscribe = tactics.subscribe("lead-capture", state => {
console.log(state.open, state.goal_reached);
});
Profile state can be pushed into the tactic layer:
tactics.setProfile({
fold: { known: true },
segments: [{ segment_name: "high_intent" }],
tactics: {
"lead-capture": {
trigger: "ExitIntentDetected",
goal: "LeadEmailCaptured",
once: true,
goal_reached: false
}
}
});
detectExitIntent(callback, options)
Runs a callback when the pointer leaves through the top of the viewport.
const cleanup = detectExitIntent(detail => {
tactics.open("lead-capture");
}, { threshold: 8, once: true });
trackInteractionSignal(options)
Samples local browser interaction for a short window and emits one coarse InteractionSignalObserved fact — a likelihood plus bucketed interaction evidence.
const signal = trackInteractionSignal({ sampleMs: 4000 });
// end the window early if needed:
signal.stop();
await signal.done;
Options: root (target to observe, defaults to the document), sampleMs (sampling window), eventType (override the emitted type), and detail (extra event detail). Returns a controller with stop() and a done promise that resolves to the ingest response.
It is evidence, not a verdict: it sends no raw pointer trails and does not prove personhood — treat the result as weak browser-interaction evidence the profile fold can seed from, not proof.
forget(options)
Deletes the current anonymous profile and clears local client state.
await forget();
In edge mode, the default endpoint is /sp/profile/delete. In direct mode, it is /v1/profile/delete.
consent
Consent starts denied for every category.
await consent.grant("analytics");
consent.allows("analytics");
await consent.revoke("analytics");
consent.state();
Grant and revoke also track sp.consent.granted and sp.consent.revoked.
Utilities
| Function | Description |
|---|---|
getAnonymousId() |
Returns the local anonymous id in direct mode; returns null in edge mode. |
reset() |
Clears local anonymous id, consent cache, and initialization state. |