@aftership/ads-core
v0.4.1
Published
Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.
Readme
@aftership/ads-core
自渲染 Ads 界面的 headless TypeScript 基础包。没有 runtime dependency,也不访问 DOM。
职责
- 导出标准化 decision、offer、theme、token context 和 host event 类型;
- 接受注入的 decision fetcher,不自行选择 endpoint 或认证方式;
- 把不可信 decision 响应清理为稳定的 nullable/array 结构;
- 丢弃缺少必填
id或target_url的 offer; - 把 timeout、transport failure 和畸形响应降级为空 decision;
- 为测试和 renderer demo 提供确定性 mock 场景。
它不直接调用 Ads backend、不渲染 UI、不存储 decision,也不向 POST /v1/events 转发 event。
公开 API
import {
createAdsClient,
createMockFetcher,
mockDecision,
type Decision,
type DecisionFetcher,
} from "@aftership/ads-core";Host 必须提供 DecisionFetcher。Browser host 应调用有授权的 BFF 或使用服务端注入数据;不得把内部 Ads decision endpoint 直接暴露给 browser。
createAdsClient 默认使用 2.5 秒 host timeout,并始终 resolve。失败时返回:
{ decision_id: "", offers: [], attribution: null }契约来源
- HTTP schema:OpenAPI
- Decision 行为:Decision 架构
- Event 行为:Event 架构
公开类型与事件模型
Placement 为 tracking_page、order_confirmation_page、tracking_update_email,与 backend decision contract 一致。Decision(widget 级)与 Offer(offer 级)暴露 backend 签发的 report_token。
AdsEvent 是 host callback(AdsEventSink)结构,不是 POST /v1/events 请求体。事件类型为 widget_load、widget_display、offer_display、offer_click 与 host-local 的 no_fill,并携带对应 report_token。host 负责把有 token 的事件经自身 BFF 转发到 POST /v1/events;no_fill 与无 report_token 的事件不转发。以 OpenAPI 为契约事实来源。
开发
pnpm --filter @aftership/ads-core build
pnpm --filter @aftership/ads-core typecheck
pnpm --filter @aftership/ads-core testsrc/types.ts:公开类型;src/client.ts:fail-safe 注入 client;src/sanitize.ts:runtime 响应清理;src/mock.ts:mock decision。
