Skip to content

feat(audience): CDN bundle entry point and tsup build (SDK-115)#2853

Merged
ImmutableJeffrey merged 1 commit into
mainfrom
feat/audience-cdn-bundle
Apr 15, 2026
Merged

feat(audience): CDN bundle entry point and tsup build (SDK-115)#2853
ImmutableJeffrey merged 1 commit into
mainfrom
feat/audience-cdn-bundle

Conversation

@ImmutableJeffrey

@ImmutableJeffrey ImmutableJeffrey commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a single-file IIFE build of @imtbl/audience at dist/cdn/imtbl-audience.global.js so studios can embed via <script> and call ImmutableAudience.Audience.init({...}) — no bundler, no npm install required.

Linear: SDK-115.

@ImmutableJeffrey ImmutableJeffrey requested review from a team as code owners April 14, 2026 05:14
@nx-cloud

nx-cloud Bot commented Apr 14, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 42565f8

Command Status Duration Result
nx run-many -p @imtbl/sdk,@imtbl/checkout-widge... ✅ Succeeded 1s View ↗
nx affected -t build,lint,test ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-15 07:32:22 UTC

@nx-cloud

nx-cloud Bot commented Apr 14, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit c58d1f8

Command Status Duration Result
nx run-many -p @imtbl/sdk,@imtbl/checkout-widge... ✅ Succeeded 6s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-14 05:15:43 UTC

ImmutableJeffrey added a commit that referenced this pull request Apr 15, 2026
…core

Exposes AudienceError to web SDK consumers. The core queue and consent
manager already accept an onError callback and map TransportError to a
public AudienceError via toAudienceError; this commit just forwards
AudienceConfig.onError into both positional slots in the Audience
constructor, which were previously hard-coded to undefined.

Also re-exports AudienceError (runtime) and AudienceErrorCode (type)
from the @imtbl/audience package index so ESM consumers can import
the error type they need for their onError handler. CDN consumers
already have it via window.ImmutableAudience.AudienceError from the
CDN bundle work in #2853.

Two new sdk.test.ts tests cover the wire-through end-to-end: a flush
failure against a mocked backend, and a consent sync failure against
a mocked backend. Both verify the AudienceError shape (name, code,
status, endpoint) rather than just that the callback fires.

Refs SDK-49

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ImmutableJeffrey added a commit that referenced this pull request Apr 15, 2026
…core

Exposes AudienceError to web SDK consumers. The core queue and consent
manager already accept an onError callback and map TransportError to a
public AudienceError via toAudienceError; this commit just forwards
AudienceConfig.onError into both positional slots in the Audience
constructor, which were previously hard-coded to undefined.

Also re-exports AudienceError (runtime) and AudienceErrorCode (type)
from the @imtbl/audience package index so ESM consumers can import
the error type they need for their onError handler. CDN consumers
already have it via window.ImmutableAudience.AudienceError from the
CDN bundle work in #2853.

Two new sdk.test.ts tests cover the wire-through end-to-end: a flush
failure against a mocked backend, and a consent sync failure against
a mocked backend. Both verify the AudienceError shape (name, code,
status, endpoint) rather than just that the callback fires.

Refs SDK-49

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ImmutableJeffrey ImmutableJeffrey force-pushed the feat/audience-cdn-bundle branch from fddbfed to 90add33 Compare April 15, 2026 07:15
Ships @imtbl/audience as a single-file IIFE bundle for <script>-tag
embedding — no npm install, no bundler required.

Public API:
- Studios load dist/cdn/imtbl-audience.global.js, then call
  ImmutableAudience.init({publishableKey: '...'}) to get an instance.
- Global surface: init, AudienceError, AudienceEvents, IdentityType,
  canIdentify, canTrack, version. Flat — no class on the global.
  Every peer is a conscious forever-commitment, nothing leaks by
  default. Adding the class back later is non-breaking additive.
- TypeScript consumers get ImmutableAudienceGlobal re-exported from
  the npm entry for typing window.ImmutableAudience.

Build (new tsup.cdn.js):
- format: iife, globalName: ImmutableAudience, platform: browser,
  target: es2018
- noExternal: [/.*/] — inlines every transitive dep; a "no bundler"
  bundle has to ship self-contained
- treeshake + minify; no source maps (keeps SRI hash stable for
  studios pinning)
- Wired into `pnpm build` alongside the existing ESM/CJS builds
- Watch-mode and production version-fallback strings aligned to
  '0.0.0-local' for local dev builds

Robustness:
- Double-import guard: a second load is ignored, a warning logs the
  already-loaded version and tells the studio to remove the old
  <script> tag to upgrade
- globalThis with a window fallback for Safari < 12.1 (the es2018
  target predates the globalThis baseline)

Tests:
- src/cdn.test.ts: source-level unit tests (global shape, guard)
- test/cdn-artifact.test.ts: reads the built IIFE off disk, evaluates
  it in a jsdom realm, asserts the full global shape, and calls
  init() end-to-end via a mocked fetch. Catches failure modes a
  source-level test cannot — e.g., a broken tsup config that ships
  with the source-level test still passing
- Chained into `pnpm test` so CI's nx affected -t test runs both
@ImmutableJeffrey ImmutableJeffrey force-pushed the feat/audience-cdn-bundle branch from 90add33 to 42565f8 Compare April 15, 2026 07:19
}),
replace({
__SDK_VERSION__: pkg.version === '0.0.0' ? '2.0.0' : pkg.version,
__SDK_VERSION__: pkg.version === '0.0.0' ? '0.0.0-local' : pkg.version,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct — hardcoding '2.0.0' as the local dev fallback was clearly wrong — but it changes the version string reported by all local builds of the existing npm package, not just the new CDN bundle. Worth a quick check that nothing in the codebase compares against '2.0.0' at runtime before the next publish.

ImmutableJeffrey added a commit that referenced this pull request Apr 15, 2026
…core

Exposes AudienceError to web SDK consumers. The core queue and consent
manager already accept an onError callback and map TransportError to a
public AudienceError via toAudienceError; this commit just forwards
AudienceConfig.onError into both positional slots in the Audience
constructor, which were previously hard-coded to undefined.

Also re-exports AudienceError (runtime) and AudienceErrorCode (type)
from the @imtbl/audience package index so ESM consumers can import
the error type they need for their onError handler. CDN consumers
already have it via window.ImmutableAudience.AudienceError from the
CDN bundle work in #2853.

Two new sdk.test.ts tests cover the wire-through end-to-end: a flush
failure against a mocked backend, and a consent sync failure against
a mocked backend. Both verify the AudienceError shape (name, code,
status, endpoint) rather than just that the callback fires.

Refs SDK-49

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ImmutableJeffrey added a commit that referenced this pull request Apr 15, 2026
The sample app and both READMEs were written against the nested
ImmutableAudience.Audience.init(...) shape that the CDN bundle
originally exposed. #2853 has since flattened the global to
ImmutableAudience.init(...) and removed the Audience class from
the CDN surface entirely — so the sample app's destructure
(\`var Audience = window.ImmutableAudience.Audience\`) now resolves
to undefined and every init call throws.

- sample-app.js: destructure \`init\` directly into a local
  \`audienceInit\` var and update all six call sites.
- sdk-sample-app/README.md: update the one remaining code snippet
  that showed Audience.init(...).
- sdk/README.md: update the tagline, rewrite the CDN quickstart to
  destructure \`init\` instead of \`Audience\`, and rephrase the
  "symbols attached to the global" paragraph to match the new
  surface (the CDN no longer exposes the Audience class itself).
@ImmutableJeffrey ImmutableJeffrey added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit 6d6fbc4 Apr 15, 2026
7 checks passed
@ImmutableJeffrey ImmutableJeffrey deleted the feat/audience-cdn-bundle branch April 15, 2026 23:41
ImmutableJeffrey added a commit that referenced this pull request Apr 16, 2026
…core

Exposes AudienceError to web SDK consumers. The core queue and consent
manager already accept an onError callback and map TransportError to a
public AudienceError via toAudienceError; this commit just forwards
AudienceConfig.onError into both positional slots in the Audience
constructor, which were previously hard-coded to undefined.

Also re-exports AudienceError (runtime) and AudienceErrorCode (type)
from the @imtbl/audience package index so ESM consumers can import
the error type they need for their onError handler. CDN consumers
already have it via window.ImmutableAudience.AudienceError from the
CDN bundle work in #2853.

Two new sdk.test.ts tests cover the wire-through end-to-end: a flush
failure against a mocked backend, and a consent sync failure against
a mocked backend. Both verify the AudienceError shape (name, code,
status, endpoint) rather than just that the callback fires.

Refs SDK-49

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants