Skip to content

feat: cap page-view storage by byte budget instead of fixed count - #114

Open
alexs-mparticle wants to merge 8 commits into
developmentfrom
feat/page-view-byte-budget
Open

feat: cap page-view storage by byte budget instead of fixed count#114
alexs-mparticle wants to merge 8 commits into
developmentfrom
feat/page-view-byte-budget

Conversation

@alexs-mparticle

@alexs-mparticle alexs-mparticle commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

What & why

Persisted page-view history was capped at a fixed 25 records. This replaces that cap with a byte budget (~100 KB): we keep more history when there's room to spare — which improves targeting — while staying a considerate tenant in the customer's shared-origin localStorage instead of assuming the space is ours.

Behaviour

  • Oldest page views are evicted first to keep our footprint under the budget.
  • If the browser reports its own storage quota is full, we drop oldest and retry so the write never fails outright — always keeping at least the most recent page view.
  • If even the newest page view can't be stored, we log at INFO and carry on. Nothing is ever thrown into the host page.

The selectPlacements send path is unchanged — it's now naturally bounded by what's in storage.

Tests

Byte-budget eviction (oldest-first, stays under budget), newest always retained, quota-exceeded → evict-and-retry, and the give-up path logs at INFO without throwing. Full suite, lint, and build pass.

Replace the fixed PAGE_VIEWS_MAX_COUNT = 25 cap on persisted page views
with a byte budget (PAGE_VIEWS_MAX_BYTES = 100 * 1024, measured as JSON
string length). writePageViewsStorage now trims oldest-first to the
budget so the kit stays a polite tenant in the shared origin
localStorage regardless of free space, and wraps the write in a
QuotaExceededError evict-and-retry loop that always keeps at least the
newest record. If the write still fails, the error propagates to the
existing capturePageView catch and reports PAGE_VIEW_CAPTURE_FAILED at
INFO, so nothing is thrown into the host page.

The selectPlacements send path (buildPageEvents) is intentionally
unchanged; it is now naturally bounded by the storage budget.
@alexs-mparticle
alexs-mparticle force-pushed the feat/page-view-byte-budget branch from cc7f462 to f9557ea Compare August 12, 2026 18:36
Comment thread test/src/pageViewStorage.spec.ts Outdated
@alexs-mparticle
alexs-mparticle force-pushed the feat/page-view-byte-budget branch from 88aa62b to 023be7d Compare August 12, 2026 20:13
Move page-view persistence (load/write/clear + legacy-key migration)
out of Rokt-Kit.ts into src/pageViewStorage.ts, and generalize the
byte-budget eviction loop into a reusable storage helper. Keeps
Rokt-Kit.ts focused on kit lifecycle.

Also drop the hand-maintained file manifest from AGENTS.md — it drifts
as modules are added; the source tree is the source of truth.
@alexs-mparticle
alexs-mparticle force-pushed the feat/page-view-byte-budget branch from 023be7d to 2c6a42d Compare August 12, 2026 20:53
Unify the duplicated isObject/isPlainObject guards and move isString and
isEmpty into src/utils.ts with co-located tests. Share an evictOldest helper
across the budget-shrink and write-retry loops in writeNamespacedFieldWithinBudget.
@alexs-mparticle
alexs-mparticle marked this pull request as ready for review August 13, 2026 14:00
Arrays are typeof 'object', so they were already handled by the
object branch; the Array.isArray check was dead code.
Comment thread test/src/pageViewStorage.spec.ts
Comment thread src/storage.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants