v0.15.0 post-correction: @amplitude/unified + session replay + overlay binding
Mid-Session-L correction to the v0.15.0 release that the dispatched
subagent (Session ξ) shipped. ξ was working from a pre-vendor brief
that specified @amplitude/analytics-browser and treated the API key
as a secret via `flotilla secret set`. Operator subsequently
provisioned the Amplitude project, surfaced the vendor's
recommended installation prompt, and confirmed the key value.
Three downstream changes:
- Package: swap @amplitude/analytics-browser → @amplitude/unified
(analytics + session replay in one install; vendor-recommended).
- Init call: `amplitude.init(KEY, undefined, { defaultTracking: false })`
becomes `amplitude.initAll(KEY, { analytics: { autocapture: true },
sessionReplay: { sampleRate: 1 } })`. Vendor's exact installation-
wizard shape; gates remain on the v0.13.0 consent banner.
- Binding: Amplitude browser keys are bundle-embedded by design
(same nature as VITE_TURNSTILE_SITE_KEY from v0.12.0), so the key
is public, not secret. CHANGELOG MUST step rewritten to bind via
`flotilla overlay set <deployment> VITE_AMPLITUDE_API_KEY=<key>`
rather than `flotilla secret set`. The roadmap row #13's
"new secret: AMPLITUDE_API_KEY" wording predated vendor
consultation; the roadmap will be updated when this ships.
§19.2 candidate captured in CHANGELOG: split the analytics consent
toggle into a separate session-replay category (recording has a
larger privacy footprint than event counters), follow-up release.
Wrapper structural shape (track/identify/anonymize, queue + drain,
consent-flip → setOptOut, lazy import) is unchanged from ξ's work.
Event taxonomy and Login.jsx / App.jsx / Admin.jsx / etc. instrument
sites are unchanged. Frontend build verified green
(VITE_APP_NAME=… npm run build).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+58
-33
@@ -26,21 +26,24 @@ that.
|
||||
## 0.15.0 — 2026-05-28
|
||||
|
||||
**Minor — no schema migration; one new build-time env var bound via
|
||||
`flotilla secret set`.** This release ships Amplitude analytics
|
||||
instrumentation (roadmap item #13). The frontend gains a small
|
||||
wrapper around `@amplitude/analytics-browser` that gates SDK
|
||||
`flotilla overlay set`.** This release ships Amplitude Analytics +
|
||||
Session Replay instrumentation (roadmap item #13). The frontend
|
||||
gains a small wrapper around `@amplitude/unified` that gates SDK
|
||||
initialization on the v0.13.0 cookie/privacy consent — the SDK is
|
||||
never loaded for visitors who have not granted analytics consent, and
|
||||
a later consent flip to `denied` calls `setOptOut(true)` so events
|
||||
stop firing immediately. The wrapper exposes a stable taxonomy of
|
||||
never loaded for visitors who have not granted analytics consent,
|
||||
no session is recorded, no network request fires; a later consent
|
||||
flip to `denied` calls `setOptOut(true)` so events and session
|
||||
replay stop immediately. The wrapper exposes a stable taxonomy of
|
||||
nine events (Page Viewed, RFC Viewed, User Signed In / Signed Out,
|
||||
RFC Proposed, PR Opened, Comment Posted, Beta Access Requested, Admin
|
||||
Permission Decision) wired into the existing routes, the Login flow,
|
||||
the propose / open-PR / discussion / PR-review surfaces, and the
|
||||
admin grant/revoke action. Event bodies carry only ids and enums; no
|
||||
free-text fields (titles, comment bodies, names, emails) are ever
|
||||
sent. The Amplitude API key is read from `VITE_AMPLITUDE_API_KEY` at
|
||||
build time; when unset, the wrapper logs one console warning and
|
||||
sent. **Session replay** records sessions at `sampleRate: 1` (100%)
|
||||
— vendor-recommended default; gated by the same v0.13.0 analytics
|
||||
consent. The Amplitude API key is read from `VITE_AMPLITUDE_API_KEY`
|
||||
at build time; when unset, the wrapper logs one console warning and
|
||||
no-ops so dev environments without analytics keep working. No backend
|
||||
events ship in this release — Amplitude SaaS holds the events,
|
||||
nothing lands in our DB, no migration.
|
||||
@@ -51,12 +54,13 @@ nothing lands in our DB, no migration.
|
||||
surface: `track(name, props)`, `identify({ user_id })`,
|
||||
`anonymize()`, the `EVENTS` taxonomy constant, and a
|
||||
`__resetForTests` helper. Internally lazy-imports
|
||||
`@amplitude/analytics-browser` and calls `amplitude.init(API_KEY,
|
||||
undefined, { defaultTracking: false })` only after consent is
|
||||
granted; queues pre-init calls and drains them on init resolve;
|
||||
flips `setOptOut(true)` on a granted→denied consent change. The
|
||||
wrapper subscribes to `onConsentChange()` so a freshly-banner-clicked
|
||||
"analytics on" flips the SDK live without a page reload.
|
||||
`@amplitude/unified` and calls `amplitude.initAll(API_KEY,
|
||||
{ analytics: { autocapture: true }, sessionReplay: { sampleRate: 1 } })`
|
||||
only after consent is granted; queues pre-init calls and drains
|
||||
them on init resolve; flips `setOptOut(true)` on a granted→denied
|
||||
consent change (stops both analytics events and session replay).
|
||||
The wrapper subscribes to `onConsentChange()` so a freshly-banner-
|
||||
clicked "analytics on" flips the SDK live without a page reload.
|
||||
- **Event taxonomy** wired into the app:
|
||||
- `Page Viewed` — fires from `App.jsx` on every route change with
|
||||
`path` (`location.pathname`); the location hook owns the firing
|
||||
@@ -86,8 +90,9 @@ nothing lands in our DB, no migration.
|
||||
called with `String(viewer.id)`. The sign-out gesture calls
|
||||
`anonymize()` before the nav. No email, display name, or other PII
|
||||
is passed through the SDK.
|
||||
- **`@amplitude/analytics-browser`** dependency added to
|
||||
`frontend/package.json`. Lockfile updated.
|
||||
- **`@amplitude/unified`** dependency added to
|
||||
`frontend/package.json` (analytics + session replay in one
|
||||
install). Lockfile updated.
|
||||
- **`VITE_AMPLITUDE_API_KEY`** documented in `frontend/.env.example`
|
||||
with the secret-vs-overlay binding caveat (see below).
|
||||
|
||||
@@ -124,40 +129,60 @@ nothing lands in our DB, no migration.
|
||||
this release and remains available for the next minor that needs a
|
||||
schema bump.
|
||||
|
||||
### Caveat — secret-vs-overlay binding for `AMPLITUDE_API_KEY`
|
||||
### Caveat — overlay binding for `VITE_AMPLITUDE_API_KEY`
|
||||
|
||||
Amplitude browser API keys are embedded in the frontend bundle at
|
||||
build time and visible to anyone with browser dev tools. They are
|
||||
conventionally treated as semi-sensitive (not truly secret) and would
|
||||
in principle fit `flotilla overlay set` rather than `flotilla secret
|
||||
set`. The roadmap calls for `secret set` to keep
|
||||
all-keys-in-Secret-Manager regularity for the deployment — that's the
|
||||
choice this release follows. The matching CloudFlare Turnstile pair
|
||||
(public site key via overlay, secret key via Secret Manager) is the
|
||||
contrast; Amplitude only has one key so the "is it public?" question
|
||||
has no separating answer at provisioning time, and the operator runs
|
||||
the secret-set gesture rather than the overlay-set one.
|
||||
public by design — same nature as the v0.12.0
|
||||
`VITE_TURNSTILE_SITE_KEY` (also public, also bundle-embedded,
|
||||
explicitly contrasted with `CLOUDFLARE_TURNSTILE_SECRET` which is
|
||||
the real secret-half of that pair). The Amplitude installation
|
||||
guidance from the vendor shows the key inline as a literal string
|
||||
argument to `initAll(…)`, confirming the public framing. This
|
||||
release accordingly binds the value via `flotilla overlay set`,
|
||||
not `flotilla secret set` — the env-var name is `VITE_AMPLITUDE_API_KEY`
|
||||
(Vite-prefix convention, so the build picks it up directly without
|
||||
an alias step).
|
||||
|
||||
(Roadmap row #13 originally said "new secret: AMPLITUDE_API_KEY";
|
||||
that wording predated vendor consultation. Mid-Session-L the
|
||||
operator provisioned the Amplitude project, surfaced the vendor's
|
||||
recommended init prompt, and the binding settled as overlay. The
|
||||
roadmap row will be updated to match when #13 ships.)
|
||||
|
||||
### Caveat — session replay scope and consent
|
||||
|
||||
This release enables Amplitude Session Replay at `sampleRate: 1`
|
||||
(100% of sessions recorded for full-DOM playback). The vendor's
|
||||
installation wizard recommends this default for new deployments —
|
||||
maximum learning during the early phase. The v0.13.0 single
|
||||
"analytics" consent toggle gates session replay together with
|
||||
events, so no recording happens without explicit opt-in. A future
|
||||
release **MAY** split this into a separate consent category for
|
||||
session replay specifically (recording has a meaningfully larger
|
||||
privacy footprint than event counters); §19.2 candidate.
|
||||
|
||||
### Upgrade steps (from 0.14.0)
|
||||
|
||||
- You **MUST** install the new frontend dependency before building:
|
||||
`cd frontend && npm install` picks up `@amplitude/analytics-browser`
|
||||
from the updated `frontend/package.json` and the refreshed
|
||||
`cd frontend && npm install` picks up `@amplitude/unified` from
|
||||
the updated `frontend/package.json` and the refreshed
|
||||
`package-lock.json`. The lockfile change is committed.
|
||||
- You **MUST** rebuild the frontend after upgrading so the analytics
|
||||
wrapper and its consent gate ship to viewers. `frontend/package.json#version`
|
||||
and `VERSION` both move to `0.15.0`. No schema migration; the
|
||||
backend is unchanged for this release.
|
||||
- **MUST**: before deploying, the operator runs `pbpaste | /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/.venv/bin/ohm-rfc-app-flotilla secret set ohm-rfc-app AMPLITUDE_API_KEY` (with the Amplitude project's API key in the clipboard) to bind the new `AMPLITUDE_API_KEY` secret. The deploy MUST NOT proceed before this binding exists. If the binding is absent, the frontend's analytics wrapper no-ops with a console warning and the rest of the app continues to function — but no events are sent.
|
||||
- **MUST**: before deploying, the operator runs `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/.venv/bin/ohm-rfc-app-flotilla overlay set ohm-rfc-app VITE_AMPLITUDE_API_KEY=<key>` to bind the Amplitude project's public API key. (Receiving the value in the conversation is fine — it's bundle-embedded by design, same as `VITE_TURNSTILE_SITE_KEY`.) The deploy **SHOULD NOT** proceed before this binding exists; if the binding is absent, the frontend's analytics wrapper no-ops with a console warning and the rest of the app continues to function — but no events or session replays are sent.
|
||||
- You **MAY** leave `VITE_AMPLITUDE_API_KEY` unset in dev environments
|
||||
— the wrapper detects the empty value and no-ops with a single
|
||||
console warning. The app, the consent banner, and every other
|
||||
surface keep working unchanged.
|
||||
- You **SHOULD** verify after deploy that the Amplitude dashboard
|
||||
receives events when a consenting browser exercises one of the
|
||||
taxonomy events (the easiest probe: open the deployed site in an
|
||||
Incognito window, accept analytics on the consent banner, navigate
|
||||
to an RFC, and watch the project's live event stream).
|
||||
receives events and a session replay when a consenting browser
|
||||
exercises one of the taxonomy events (the easiest probe: open the
|
||||
deployed site in an Incognito window, accept analytics on the
|
||||
consent banner, navigate to an RFC, and watch the project's live
|
||||
event stream + replay panel).
|
||||
|
||||
## 0.14.0 — 2026-05-28
|
||||
|
||||
|
||||
+17
-12
@@ -63,19 +63,24 @@ VITE_COOKIES_POLICY_URL=
|
||||
# VITE_TURNSTILE_SITE_KEY=0x4AAAAAAA...
|
||||
VITE_TURNSTILE_SITE_KEY=
|
||||
|
||||
# v0.15.0 / roadmap item #13: Amplitude project API key. Embedded in
|
||||
# the frontend bundle at build time and used by the analytics wrapper
|
||||
# (`frontend/src/lib/analytics.js`) when the user has granted analytics
|
||||
# consent (v0.13.0 cookie banner). Provision an Amplitude project at
|
||||
# app.amplitude.com → Projects → New, copy the API key.
|
||||
# v0.15.0 / roadmap item #13: Amplitude project API key (public).
|
||||
# Embedded in the frontend bundle at build time and used by the
|
||||
# analytics wrapper (`frontend/src/lib/analytics.js`) — which loads
|
||||
# `@amplitude/unified` (Analytics + Session Replay) when the user
|
||||
# has granted analytics consent (v0.13.0 cookie banner). Provision
|
||||
# an Amplitude project at app.amplitude.com → Projects → New, copy
|
||||
# the API key.
|
||||
#
|
||||
# Caveat — secret-vs-overlay binding choice: Amplitude browser API
|
||||
# keys are visible to anyone with browser dev tools (they ride in the
|
||||
# shipped bundle). They are conventionally treated as semi-sensitive,
|
||||
# not truly secret. The roadmap binds the value through flotilla's
|
||||
# `secret set` verb anyway, to keep all-keys-in-Secret-Manager
|
||||
# regularity for the OHM deployment. Leave unset in dev; the wrapper
|
||||
# logs one console warning and no-ops (the app continues to work).
|
||||
# Public by design: Amplitude browser keys are bundle-embedded
|
||||
# (visible in dev tools), same nature as VITE_TURNSTILE_SITE_KEY
|
||||
# (also public; the truly-secret half of that Turnstile pair is
|
||||
# CLOUDFLARE_TURNSTILE_SECRET on the backend). For deployments
|
||||
# behind flotilla, bind via `flotilla overlay set <deployment>
|
||||
# VITE_AMPLITUDE_API_KEY=<key>` — NOT `flotilla secret set`. The
|
||||
# vendor's installation wizard shows the key inline as a literal
|
||||
# string in the init call, confirming the public framing. Leave
|
||||
# unset in dev; the wrapper logs one console warning and no-ops
|
||||
# (the app continues to work).
|
||||
#
|
||||
# Examples:
|
||||
# VITE_AMPLITUDE_API_KEY=01234567890abcdef01234567890abcd
|
||||
|
||||
Generated
+395
-6
@@ -8,7 +8,7 @@
|
||||
"name": "rfc-app-frontend",
|
||||
"version": "0.15.0",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "^2.42.4",
|
||||
"@amplitude/unified": "^1.1.9",
|
||||
"@codemirror/commands": "^6.10.3",
|
||||
"@codemirror/lang-markdown": "^6.5.0",
|
||||
"@codemirror/language": "^6.12.3",
|
||||
@@ -48,6 +48,18 @@
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/analytics-client-common": {
|
||||
"version": "2.4.48",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.4.48.tgz",
|
||||
"integrity": "sha512-jdRvu8ux3aIf74FvTDZuSFR1mutzdrIg1ebXYqpKizs9upXz1AJnHClkldSw9i4yu924AJ2wudxq6dccHWlNiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-connector": "^1.4.8",
|
||||
"@amplitude/analytics-core": "2.48.2",
|
||||
"@amplitude/analytics-types": "2.11.1",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/analytics-connector": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-connector/-/analytics-connector-1.6.4.tgz",
|
||||
@@ -67,6 +79,43 @@
|
||||
"zen-observable": "0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/analytics-types": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.11.1.tgz",
|
||||
"integrity": "sha512-wFEgb0t99ly2uJKm5oZ28Lti0Kh5RecR5XBkwfUpDzn84IoCIZ8GJTsMw/nThu8FZFc7xFDA4UAt76zhZKrs9A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/engagement-browser": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/engagement-browser/-/engagement-browser-1.0.9.tgz",
|
||||
"integrity": "sha512-zvPr0L5aLlOS3nG8scIkEEDMVK2y3MaMbgjYhMfYruhMpfsC/U0apov22nEc1RRrTwve2awEXruPRKf1TysqrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-types": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/experiment-core": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/experiment-core/-/experiment-core-0.13.1.tgz",
|
||||
"integrity": "sha512-ZHvR0dxTltasp8MiMcQ6qKsY20mWnODoy3oebGad6qaRR1ywpUi8IuLf5AwLTM35ZwgzEUTn9TEIWKLHpDwHMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-base64": "^3.7.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/experiment-js-client": {
|
||||
"version": "1.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/experiment-js-client/-/experiment-js-client-1.21.1.tgz",
|
||||
"integrity": "sha512-chE/4qQG/5Cgl93Wqj1NEdgOL5LkqySLlfk1EN0f+7bJa52HpkGFALA2FeCNYf31Z5CglEeKX6dUMgL7y33SIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-connector": "^1.6.4",
|
||||
"@amplitude/experiment-core": "^0.13.1",
|
||||
"@amplitude/ua-parser-js": "^0.7.31",
|
||||
"base64-js": "1.5.1",
|
||||
"unfetch": "4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-autocapture-browser": {
|
||||
"version": "1.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.27.2.tgz",
|
||||
@@ -97,6 +146,16 @@
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-experiment-browser": {
|
||||
"version": "1.0.0-beta.28",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-experiment-browser/-/plugin-experiment-browser-1.0.0-beta.28.tgz",
|
||||
"integrity": "sha512-NQz267zLi7vl2G2lx10yUrEoGOCe5K9iqcPSIjbTavGu/XGvsmqLDqBHhg+EkdEMAPwypoXnmtPEs3RMhX+1MA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.48.2",
|
||||
"@amplitude/experiment-js-client": "^1.15.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-network-capture-browser": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.10.1.tgz",
|
||||
@@ -127,6 +186,22 @@
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-session-replay-browser": {
|
||||
"version": "1.31.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-session-replay-browser/-/plugin-session-replay-browser-1.31.0.tgz",
|
||||
"integrity": "sha512-b7kyYVEdW3EMR6cPXCfld+h8nQsuAR5o6vum8Glu+ofhFDfG4wj/mTJ0ITEaNbsJCfXniKQ3kFgTe6hTtxSFGQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-client-common": "2.4.48",
|
||||
"@amplitude/analytics-core": "2.48.2",
|
||||
"@amplitude/analytics-types": "2.11.1",
|
||||
"@amplitude/rrweb-plugin-console-record": "2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-record": "2.0.0-alpha.40",
|
||||
"@amplitude/session-replay-browser": "1.44.0",
|
||||
"idb-keyval": "^6.2.1",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-web-vitals-browser": {
|
||||
"version": "1.1.33",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-web-vitals-browser/-/plugin-web-vitals-browser-1.1.33.tgz",
|
||||
@@ -138,6 +213,178 @@
|
||||
"web-vitals": "5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrdom": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrdom/-/rrdom-2.1.0.tgz",
|
||||
"integrity": "sha512-2dAtxXL02usBV2CSOnScLd3WoVqWaeiGpxN8LuXJ0r/NpLJkW1k876v2tRKAz5NrxPwSdjihsMmwCIXHpJhHfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/rrweb-snapshot": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb/-/rrweb-2.1.1.tgz",
|
||||
"integrity": "sha512-6uA+5VE/VHumaXPXTTLGRogd/K9MDwd01jGteppeLzsX0PvqlDyY5aIi35yh9+q1iS6ciPBn/2NRg0lg4cFIlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/rrdom": "^2.1.0",
|
||||
"@amplitude/rrweb-snapshot": "^2.1.0",
|
||||
"@amplitude/rrweb-types": "^2.1.0",
|
||||
"@amplitude/rrweb-utils": "^2.1.0",
|
||||
"@types/css-font-loading-module": "0.0.7",
|
||||
"@xstate/fsm": "^1.4.0",
|
||||
"base64-arraybuffer": "^1.0.1",
|
||||
"mitt": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-packer": {
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-packer/-/rrweb-packer-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-Btb6b9pS1IvDMbvyYxpUdTk9NRJugSoJjRCl7R6jP/iSlPWXoveJIwHaNFAS9ZmWUEK7HhyBJ8bKGFN3giUsDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/rrweb-types": "^2.0.0-alpha.40",
|
||||
"fflate": "^0.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-plugin-console-record": {
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-plugin-console-record/-/rrweb-plugin-console-record-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-vtY7T/kGFl62nC1u7ZUXQvU7ulB70cZGVHPRN/SO9fzVfsY7y6rCmBfoc2jS5KmISdlgkVzMjY2r/EE2Gk9AQA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@amplitude/rrweb": "^2.0.0-alpha.40"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-record": {
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-record/-/rrweb-record-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-5cJhQwzhymJWX5/XOtpWK0h2NLq9+t2YiO6ub0cdZ9F5AZizaRbsVH88int07DfX0YiXTKWbISezVuduCLqgSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/rrweb": "^2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-types": "^2.0.0-alpha.40"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-snapshot": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-snapshot/-/rrweb-snapshot-2.1.0.tgz",
|
||||
"integrity": "sha512-xYQvOW73ig+5M7caqilA8j0S6MHWUULLeJNK+2VVvUqv8mr4FMT2DUAQiVBGCImNlb9Gu2rLUfCScMnVxn+EDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss": "^8.4.38"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-types": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-types/-/rrweb-types-2.1.0.tgz",
|
||||
"integrity": "sha512-S73tBI/04A6HCHgnrUNeeVOvnDTEoQnNrmZGyrZncJwRlTIX+6BQSYtBFofMag8GnAy9gA+NtC0TL0CnluOWBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/rrweb-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-utils/-/rrweb-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-dTCDnSiMMHZ10utYHJ8dSd/xkjFgdF67y74PkOzAPcCKW1rLxyJYcFOA3uPL2b7cIVVmoel/5NTp5eflaUaJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/session-replay-browser": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/session-replay-browser/-/session-replay-browser-1.44.0.tgz",
|
||||
"integrity": "sha512-8Ruep2TTDMcfVMKurSpBbVclBK/v8Lb3aSHFsYd/xOQ1E3CaKoAu39pplli28NWoUcW7unyVE7khkOa2zzn0Lw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-client-common": "2.4.48",
|
||||
"@amplitude/analytics-core": "2.48.2",
|
||||
"@amplitude/analytics-types": "2.11.1",
|
||||
"@amplitude/experiment-core": "0.7.2",
|
||||
"@amplitude/rrweb-packer": "2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-plugin-console-record": "2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-record": "2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-types": "2.0.0-alpha.40",
|
||||
"@amplitude/rrweb-utils": "2.0.0-alpha.40",
|
||||
"@amplitude/targeting": "0.2.0",
|
||||
"@rollup/plugin-replace": "^6.0.1",
|
||||
"idb": "8.0.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/session-replay-browser/node_modules/@amplitude/experiment-core": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/experiment-core/-/experiment-core-0.7.2.tgz",
|
||||
"integrity": "sha512-Wc2NWvgQ+bLJLeF0A9wBSPIaw0XuqqgkPKsoNFQrmS7r5Djd56um75In05tqmVntPJZRvGKU46pAp8o5tdf4mA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-base64": "^3.7.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/session-replay-browser/node_modules/@amplitude/rrweb-types": {
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-types/-/rrweb-types-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-rP7CBDkzXupxOA7ukvC+zDYLuCtsz54TuJKC4+5O72Jsz4YdokLznKZRG34P6zXozfhGU0261qckk87lLY6mKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/session-replay-browser/node_modules/@amplitude/rrweb-utils": {
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/rrweb-utils/-/rrweb-utils-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-i1CCt6MCjlqoeNc+1Hse5bz+ZbASaWaIJ0WdJZvnQjUCHH29Xy/QFouyOuor73RZ+UWX4s2tYSrUIdmBepXk3w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/targeting": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/targeting/-/targeting-0.2.0.tgz",
|
||||
"integrity": "sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-client-common": ">=1 <3",
|
||||
"@amplitude/analytics-core": ">=1 <3",
|
||||
"@amplitude/analytics-types": ">=1 <3",
|
||||
"@amplitude/experiment-core": "0.7.2",
|
||||
"idb": "^8.0.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/targeting/node_modules/@amplitude/experiment-core": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/experiment-core/-/experiment-core-0.7.2.tgz",
|
||||
"integrity": "sha512-Wc2NWvgQ+bLJLeF0A9wBSPIaw0XuqqgkPKsoNFQrmS7r5Djd56um75In05tqmVntPJZRvGKU46pAp8o5tdf4mA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-base64": "^3.7.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/ua-parser-js": {
|
||||
"version": "0.7.33",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
|
||||
"integrity": "sha512-wKEtVR4vXuPT9cVEIJkYWnlF++Gx3BdLatPBM+SZ1ztVIvnhdGBZR/mn9x/PzyrMcRlZmyi6L56I2J3doVBnjA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ua-parser-js"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/faisalman"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/unified": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/unified/-/unified-1.1.9.tgz",
|
||||
"integrity": "sha512-YPgQbp/vDQ92GshHs2hfUxoeRnR3rRBWCoQ6wXgFjXQ1uiJf2tP0CBZWdrCStSDuhcpo2rsCz/Ek2LGq5J6SIQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "2.42.4",
|
||||
"@amplitude/analytics-core": "2.48.2",
|
||||
"@amplitude/engagement-browser": "^1.0.3",
|
||||
"@amplitude/plugin-experiment-browser": "1.0.0-beta.28",
|
||||
"@amplitude/plugin-session-replay-browser": "1.31.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/install-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
|
||||
@@ -372,6 +619,12 @@
|
||||
"import-meta-resolve": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz",
|
||||
@@ -765,6 +1018,49 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/plugin-replace": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.3.tgz",
|
||||
"integrity": "sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"magic-string": "^0.30.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
|
||||
"integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "3.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.23.6.tgz",
|
||||
@@ -1217,6 +1513,12 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/css-font-loading-module": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz",
|
||||
"integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
|
||||
@@ -1470,6 +1772,12 @@
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
||||
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
|
||||
@@ -1549,6 +1857,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@xstate/fsm": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz",
|
||||
"integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
@@ -2135,6 +2478,12 @@
|
||||
"benchmarks"
|
||||
]
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-equals": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz",
|
||||
@@ -2162,6 +2511,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.4.8",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
|
||||
"integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@@ -2195,6 +2550,18 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/idb": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/idb/-/idb-8.0.0.tgz",
|
||||
"integrity": "sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/idb-keyval": {
|
||||
"version": "6.2.4",
|
||||
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.4.tgz",
|
||||
"integrity": "sha512-D/NzHWUmYJGXi++z67aMSrnisb9A3621CyRK5G89JyTlN13C8xf0g04DLxUKMufPem3e3L2JAXR6Z00OWy183Q==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/import-meta-resolve": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
|
||||
@@ -2214,6 +2581,12 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/js-base64": {
|
||||
"version": "3.7.8",
|
||||
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz",
|
||||
"integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/katex": {
|
||||
"version": "0.16.47",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz",
|
||||
@@ -2535,6 +2908,15 @@
|
||||
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "18.0.4",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-18.0.4.tgz",
|
||||
@@ -2588,11 +2970,16 @@
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
||||
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2629,14 +3016,12 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -2665,7 +3050,6 @@
|
||||
"version": "8.5.15",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
|
||||
"integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -2970,7 +3354,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -3029,6 +3412,12 @@
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/unfetch": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.1.0.tgz",
|
||||
"integrity": "sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "^2.42.4",
|
||||
"@amplitude/unified": "^1.1.9",
|
||||
"@codemirror/commands": "^6.10.3",
|
||||
"@codemirror/lang-markdown": "^6.5.0",
|
||||
"@codemirror/language": "^6.12.3",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// analytics.js — v0.15.0 / roadmap item #13.
|
||||
//
|
||||
// Wrapper around `@amplitude/analytics-browser` that gates SDK
|
||||
// initialization on the user's cookie/privacy consent (v0.13.0,
|
||||
// `frontend/src/lib/consent.js`, SPEC §14.5). The wrapper presents
|
||||
// a stable surface to the rest of the app:
|
||||
// Wrapper around `@amplitude/unified` (Amplitude Analytics +
|
||||
// Session Replay) that gates SDK initialization on the user's
|
||||
// cookie/privacy consent (v0.13.0, `frontend/src/lib/consent.js`,
|
||||
// SPEC §14.5). The wrapper presents a stable surface to the rest
|
||||
// of the app:
|
||||
//
|
||||
// import { track, identify, anonymize } from './lib/analytics'
|
||||
//
|
||||
@@ -15,17 +16,20 @@
|
||||
// 1. Calls `bootstrap()` once, which reads `getConsent()` and
|
||||
// subscribes to `onConsentChange()`. If consent.analytics is
|
||||
// true, it lazily imports the Amplitude SDK and calls
|
||||
// `amplitude.init(API_KEY, { defaultTracking: false })`.
|
||||
// `amplitude.initAll(API_KEY, { analytics: { autocapture: true },
|
||||
// sessionReplay: { sampleRate: 1 } })`.
|
||||
// If consent.analytics is false (or undecided), the SDK is
|
||||
// not loaded — no network request, no cookies. A later
|
||||
// consent change to `true` triggers init at that moment.
|
||||
// not loaded — no network request, no cookies, no session
|
||||
// replay recording. A later consent change to `true` triggers
|
||||
// init at that moment.
|
||||
// 2. The wrapper queues `track()` and `identify()` calls made
|
||||
// before init finishes (lazy import + consent grant), and
|
||||
// drains the queue when init completes.
|
||||
// 3. If the user later flips consent from granted → denied, the
|
||||
// wrapper calls `amplitude.setOptOut(true)` so subsequent
|
||||
// events are dropped client-side (the SDK is still loaded —
|
||||
// we cannot unload a script — but it stops firing).
|
||||
// events are dropped client-side and session replay stops
|
||||
// recording (the SDK is still loaded — we cannot unload a
|
||||
// script — but it stops firing).
|
||||
//
|
||||
// Consent precedence ladder:
|
||||
//
|
||||
@@ -35,6 +39,14 @@
|
||||
// consent.recorded_at === null → treat as denied (banner is up;
|
||||
// the user has not yet chosen)
|
||||
//
|
||||
// Session replay scope: this release ships session replay at
|
||||
// `sampleRate: 1` (100% of sessions are recorded for full-DOM
|
||||
// playback). That is the vendor-recommended default for new
|
||||
// Amplitude deployments. The v0.13.0 consent banner's single
|
||||
// "analytics" toggle gates both events and session replay together —
|
||||
// a separate consent category for session-replay specifically is a
|
||||
// §19.2 follow-up.
|
||||
//
|
||||
// API key resolution:
|
||||
//
|
||||
// The build-time env var `VITE_AMPLITUDE_API_KEY` carries the
|
||||
@@ -43,15 +55,11 @@
|
||||
// function becomes a deterministic no-op so dev environments
|
||||
// (and deployments that intentionally don't ship analytics)
|
||||
// keep working. The deploy gesture wires the key via flotilla's
|
||||
// `secret set` verb (see CHANGELOG for the operator gesture).
|
||||
//
|
||||
// Note on bundle visibility: Amplitude browser API keys are embedded
|
||||
// in the frontend bundle and visible via dev tools — they are
|
||||
// conventionally treated as semi-sensitive, not truly secret. The
|
||||
// roadmap binds the value through `flotilla secret set` rather than
|
||||
// `flotilla overlay set` to keep all-keys-in-Secret-Manager
|
||||
// regularity for the deployment. See CHANGELOG 0.15.0 for the
|
||||
// caveat write-up.
|
||||
// `overlay set` verb (see CHANGELOG for the operator gesture):
|
||||
// Amplitude browser keys are bundle-embedded by design (visible
|
||||
// to anyone with dev tools, same nature as the v0.12.0
|
||||
// `VITE_TURNSTILE_SITE_KEY`), so the binding is overlay, not
|
||||
// secret.
|
||||
//
|
||||
// PII discipline:
|
||||
//
|
||||
@@ -100,9 +108,9 @@ function warnNoKey() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'[analytics] VITE_AMPLITUDE_API_KEY is unset; analytics events ' +
|
||||
'will not be sent. This is expected in dev; in production it ' +
|
||||
'means the operator has not yet run `flotilla secret set ' +
|
||||
'ohm-rfc-app AMPLITUDE_API_KEY`.',
|
||||
'and session replay will not be sent. This is expected in dev; ' +
|
||||
'in production it means the operator has not yet run ' +
|
||||
'`flotilla overlay set <deployment> VITE_AMPLITUDE_API_KEY=<key>`.',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -148,19 +156,31 @@ async function initSdk() {
|
||||
}
|
||||
_initPromise = (async () => {
|
||||
try {
|
||||
const mod = await import('@amplitude/analytics-browser')
|
||||
// The SDK exports `init`, `track`, `setUserId`, `reset`,
|
||||
// `setOptOut` as named functions. We hold the module so the
|
||||
// queue drainer can call them by name.
|
||||
const mod = await import('@amplitude/unified')
|
||||
// The unified package exposes `initAll`, `track`,
|
||||
// `setUserId`, `reset`, `setOptOut` as named functions.
|
||||
// We hold the module so the queue drainer can call them
|
||||
// by name.
|
||||
_amplitude = mod
|
||||
// defaultTracking: false — we choose what to send, and we
|
||||
// already gate on consent here. The SDK's own "default
|
||||
// tracking" would otherwise capture page-views, sessions,
|
||||
// and form interactions automatically; we want explicit
|
||||
// `track('Page Viewed', …)` calls from the app instead.
|
||||
await mod.init(API_KEY, undefined, {
|
||||
defaultTracking: false,
|
||||
}).promise
|
||||
// initAll wires up both Analytics and Session Replay in one
|
||||
// call. Vendor-recommended init shape from the Amplitude
|
||||
// installation wizard:
|
||||
// - analytics.autocapture: true — auto-instruments page
|
||||
// views, session start/end, clicks, and form interactions.
|
||||
// Our explicit `track('Page Viewed', …)` etc. layer on top
|
||||
// for app-specific names that survive renames.
|
||||
// - sessionReplay.sampleRate: 1 — record 100% of sessions
|
||||
// for full-DOM playback. Gated by the v0.13.0 consent
|
||||
// banner just like the rest of the SDK; never starts
|
||||
// recording without explicit analytics opt-in.
|
||||
const ret = mod.initAll(API_KEY, {
|
||||
analytics: { autocapture: true },
|
||||
sessionReplay: { sampleRate: 1 },
|
||||
})
|
||||
// initAll returns an AmplitudeReturn with a `.promise` accessor
|
||||
// (consistent with the legacy `init`). Some unified builds
|
||||
// resolve synchronously; await defensively.
|
||||
if (ret && ret.promise) await ret.promise
|
||||
_initialized = true
|
||||
drainQueue()
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user