StorytellerBeta — what storyteller does today
Shared reference for the redesign. We're tearing all of this up; this is just so we agree what "today" means.
Pipeline
Today's load sequence
1. Publisher page loads
core.js (priority 4)2. Loader runs prebid auction for
ocm-storyteller native ad unit3. Loader fetches stories from RSS or AdsQuirrel API
4. Loader filters out URLs the user already visited (7d localStorage TTL)
5. Splices native ad into stories[] at fixed index (default position 2)
6. Builds an iframe with
srcdoc + injects cain.js (the actual player)7. Cain renders carousel inside iframe, reads
OCM.ST globals8. Parent ↔ iframe sync via
postMessage for sticky/intersect/render events
Surface area
apps/story-teller-v2/index.js (this repo)
- 1055-line single class
- Iframe + postMessage shell
- Native ad bridge (prebid → iframe)
- Sticky / floating positioning
- Story sourcing (RSS + AdsQuirrel)
- Visited-URL filter (localStorage)
- Analytics shipper (CF Worker)
deckard-cain-v2.js (separate, on CDN)
- The actual player UI you see
- Story carousel + autoplay
- Ad rendering inside player
- Mute / sound-hack / VC-hack logic
- Branding / custom CSS
- Logs back to parent via postMessage
- Not in this repo. CDN-loaded at runtime.
Coupling
Things that reach into storyteller — or vice versa
- header_bidding — 5 special-cases for
'ocm-storyteller'ad unit (skipped from normal auction; native render bypasses width logic) - aniview — reads
OCM.sws.story_teller_v2&OCM.ST.hasAd; queries storyteller's iframe by id and posts to it - stickies-manager — hardcoded list of 2 sticky services (
aniview,story_teller_v2) - OCM.ST — global object mixing config (publisherId, sticky cfg, branding) and runtime state (stories, hasAd)
↓ Continue in terminal — first question coming there ↓