npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jolibox/ads

v1.4.16

Published

This project is for integrating Jolibox ads providers

Readme

@jolibox/ads

1. 背景

@jolibox/ads 是 Jolibox JSSDK 的核心包之一,主要负责业务层面的广告调用与聚合。它为不同类型的接入方提供了统一的广告接入规范:

  • 游戏接入方:对外暴露 AdSense for Game (AFG) 接口,支持激励视频、插屏广告及 Preroll 等格式。
  • 短剧接入方:对外暴露特定的 AFV (AdSense for Video) 接口,主要用于视频流中的广告插入。

为了最大化广告收益并保证填充率,该包实现了一套高效的广告聚合逻辑,支持从多个广告源 (Provider) 进行瀑布流式的广告加载。

2. 目的

  • 统一接口:为前端业务屏蔽底层不同广告供应商(如 Google AdSense, OKSpin, AppsRockets 等)的 API 差异。
  • 聚合下发:通过后端下发的配置,动态决定广告供应商的优先级和调用顺序。
  • 高填充率:通过“瀑布流” (Waterfall) 机制,在一间供应商失败时自动尝试下一间,确保广告展示机会。
  • 解耦业务:将复杂的广告加载、超检测、埋点监控等逻辑封装内部,业务方只需关注简单的 adBreakrequestAd 调用。

3. 技术选型

  • TypeScript: 核心逻辑编写,提供强类型定义。
  • Preact & @preact/signals: 部分 native 广告 UI 组件的渲染与状态管理。
  • Vite & Esbuild: 高性能的构建工具链,支持 ESM/CJS/IIFE 多种输出格式。
  • Async/Await Hooks: 利用 Promise 封装异步回调,简化瀑布流逻辑。

4. 架构

项目采用 Provider 模式 结合 Orchestrator (协调者) 的架构:

  • Providers: 每个广告平台(如 Google, OKSpin)都被实现为一个独立的 Provider 子类,遵循统一的接口契约 (IAbstractAFGProvider / IAbstractAFVProvider)。
  • Async Proxies: AdBreakAsyncProxyAdRequestAsyncProxy 作为中间件,负责包装 Provider 的回调函数,并将异步回调转化为 Promise 状态,从而支持在循环中按序等待。
  • Orchestrator: JoliboxAdsForGameJoliboxAdsForVideo 作为入口类,负责初始化各 Provider,并根据后端下发的序列执行循环调用。
graph TD
    User([业务方调用]) --> Main[JoliboxAdsForGame / Video]
    Main --> FetchConfig[AdsRequest: 获取广告策略]
    FetchConfig --> Loop{瀑布流循环}
    Loop --> Proxy[Async Proxy: 包装回调]
    Proxy --> Provider[Concrete Provider: Google/OKSpin...]
    Provider -- 失败/超时 --> Loop
    Provider -- 成功渲染 --> Done([流程结束])

5. 目录结构

src/
├── afg/                # AdSense for Game 相关实现
│   ├── adsense/        # Google AdSense Provider
│   ├── okspin/         # OKSpin Provider
│   ├── native/         # Native 广告逻辑
│   ├── adbreak-async-proxy.ts # AFG 异步代理逻辑
│   └── index.ts        # AFG 入口及瀑布流编排
├── afv/                # AdSense for Video 相关实现
│   ├── ima/            # Google IMA Provider
│   ├── adrequest-async-proxy.ts # AFV 异步代理逻辑
│   └── index.ts        # AFV 入口
├── components/         # 公共组件(如 AdsRequest 请求封装)
├── type/               # 公共类型定义
└── utils/              # 工具函数

6. 业务分层

  • 接入层 (Access Layer)JoliboxAdsForGame / JoliboxAdsForVideo 类,负责面向接入方提供标准的、归一化的 API 接口(如 adBreak, requestAd)。
  • 调度与代理层 (Orchestration & Proxy Layer):通过 AsyncProxy 将异步回调模式转化为同步 await 语义,并实现核心的瀑布流调度逻辑。
  • 委派与适配层 (Delegation & Adaptation Layer)
    • 二级委派机制:这是实现的核心。外露接口不直接参与具体的广告加载逻辑,而是将其委派给具体的 Provider
    • 某些复杂的 Provider(如 GoogleGPTNative)会进行二次委派给专有的 AdManager,从而实现统一外露接口不同广告源具体实现细节的彻底分离。
  • 基础层 (Base Layer)AdsContext 提供埋点、请求、环境感知的底层支撑。

7. 一些实现细节

Async-Proxy 的实现

为了让分布在不同回调函数(如 beforeAd, adBreakDone 等)中的逻辑能像同步代码一样在一个循环中执行,我们使用了 AsyncProxy 模式:

  1. callAdBreakAndContinue 返回一个 Promise
  2. 内部通过 wrapAdBreakDone 等闭包捕获原始回调。
  3. 当广告完成、出错或超时时,调用 resolve 并返回一个 continueLoop 标志。

超时处理

AdBreakAsyncProxy 中内置了 5 秒的保护性超时。如果 Provider 在规定时间内没有触发任何有效回调(如 beforeAd),代理层会自动触发 timeout 并让瀑布流进入下一个节点。

Native 广告集成

对于 Native 环境,通过 NativeProvider 与客户端通信。在 Web 端,则通过 AppsRocketsGoogleGPT 渲染特定的 UI 组件。

8. Provider 重组逻辑 (Reorganization)

init 和获取广告策略 (getAFGAdsInfo/getAFVAdsInfo) 阶段,SDK 会对后端下发的 Provider 列表进行重组。其核心目的是将所有 Native 类型的 Provider 虚拟化为一个统一的 INTERNAL_NATIVE 节点

为什么需要重组?

  1. 统一调度语义:在 JS 层的瀑布流逻辑中,不需要感知 Native 侧具体包含多少个三方 SDK(如 Mintegral, AppLovin 等)。通过重组,JS 侧只需与一个 NativeProvider 交互。
  2. 职责分离:JS 侧负责处理 Web 端的多个渠道(Google, OKSpin 等)与 Native 整体之间的优先级;而 Native 侧则利用原生 SDK 的优势,在 NativeProvider 内部处理其子级的广告竞价与切换。
  3. 简化序列管理:后端下发的 seq(优先级)可以在重组后被重新映射。所有 Native 广告通常被视为一个高优先级的整体块(Block),这保证了在原生 APP 环境下,原生广告始终能被优先调用。

9. 广告源实现详情

针对各个广告源的具体实现细节,请参阅以下文档:

10. 开发者深度指南 (AI/Developer Onboarding)

如果你需要在此包上进行二次开发或接入新的广告源,请务必阅读以下规范文档: