@growth-labs/product-meter
v0.1.0
Published
Worker-runtime metered product grants for registered users, backed by consumer-owned D1 storage.
Readme
@growth-labs/product-meter
Worker-runtime metered grants for subscription funnels and soft registration walls. A registered user can consume a limited number of premium resource grants per period, and each consumed grant is permanent for that site/user/resource.
Install
pnpm add @growth-labs/product-meterApply the D1 migration from migrations/0001_create_gl_product_meter.sql
to the consumer-owned D1 binding, or call applyProductMeterMigrations(db)
from tests/provisioning.
Use
import { consumeUnlock, getUnlockState } from '@growth-labs/product-meter'
const userId = '000cf60e-b252-4d19-ba4c-660110e31b9f' // raw verified realm id
const resourceKey = 'article:premium-analysis'
const state = await getUnlockState(env.SITE_DB, userId, resourceKey, {
siteId: 'fronts',
period: 'month',
allowance: 1,
})
if (state.alreadyUnlocked || state.remaining > 0) {
await consumeUnlock(env.SITE_DB, userId, resourceKey, {
siteId: 'fronts',
period: 'month',
allowance: 1,
})
}Use a verified raw realm user ID only: derive it from the authenticated
issuer subject after JWT verification. Do not pass emails, local site user
IDs, gl_id analytics hashes, or prefixed user:<id> subjects.
Resource keys are scoped by siteId, so the same content slug on two
sites does not share grants or allowance.
Tables
gl_product_meter_grantsstores permanent site/user/resource grants.gl_product_meter_period_usagestores the resources consumed in each period so the allowance can replenish for new resources at month boundaries without relocking previous grants.
