Skip to content

refactor(headless): import coveo.analytics modules instead of vendoring them - #8169

Open
alexprudhomme wants to merge 3 commits into
mainfrom
KIT-5959-headless-cajs-esm
Open

refactor(headless): import coveo.analytics modules instead of vendoring them#8169
alexprudhomme wants to merge 3 commits into
mainfrom
KIT-5959-headless-cajs-esm

Conversation

@alexprudhomme

@alexprudhomme alexprudhomme commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

KIT-5959

Draft — stacked on #8157. Base is KIT-5959-cajs-exports-esm, so this diff shows only the Headless-side change.

Problem

Headless vendors four coveo.analytics modules under packages/headless/src/api/analytics/coveo.analytics/cookie.ts, detector.ts, storage.ts, history-store.ts plus their tests. They were copied in #5346 because coveo.analytics shipped only bundled artifacts, so importing HistoryStore would have pulled a whole bundle into every consumer.

That copy has drifted: the Secure cookie fix landed only in Headless (ported back in #8156), and the Headless copy also gained IPv4/IPv6 host handling that coveo.analytics still lacks.

#8157 publishes real per-module ESM, so the copy is no longer necessary.

Solution

Delete the vendored modules and import from coveo.analytics/dist/esm/*.mjs.

Only history-store was imported outside the vendored folder (12 call sites); cookie, detector and storage existed purely to serve it, so they delete outright. history-store.ts shrinks from 187 lines to a subclass that keeps the shared-instance behavior Headless relies on:

export default class HistoryStore extends CoveoAnalyticsHistoryStore {
  private static instance: HistoryStore | null = null;
  public static getInstance(store?: WebStorage): HistoryStore { ... }
}

Subclassing keeps HistoryStore usable as both a value and a type, so all 12 call sites and the existing history-store.test.ts are untouched.

Net: -1033 / +40 lines.

esbuild alias (required, not cosmetic)

The first build silently emitted this into dist/cjs/headless.cjs:

require("coveo.analytics/dist/esm/history.mjs")

require() of an ESM file. It happens to work on Node 22.20, but throws ERR_REQUIRE_ESM on older Node, and this package declares engines.node: ^20.9.0 || ^22.11.0 || ^24.11.0require(ESM) only arrived in 20.19 / 22.12, so the bottom of the supported range would break.

Cause: esbuild.mjs uses packages: 'external' together with an alias that maps bare coveo.analytics to an absolute path via resolveEsm. Absolute paths are not externalized, so coveo.analytics is bundled today. A deep specifier is not covered by that alias, so it stayed external. Fixed by aliasing the deep path the same way. Verified afterwards: zero require("coveo.analytics...") across every CJS use-case bundle, and HistoryStore is inlined again.

Any future deep import into coveo.analytics needs the same treatment.

Bundle size

Measured from clean full rebuilds of packages/headless/dist on each side:

before after delta
esm/ 5456 KB 5440 KB -16 KB
cjs/ 8296 KB 8296 KB 0
definitions/ 5204 KB 5192 KB -12 KB
esm/api/analytics/ 64 KB 48 KB -16 KB
cjs/headless.cjs 767.7 KB 767.0 KB -0.7 KB
esm/ file count 1201 1198 -3

Essentially flat, and that is the expected result. The CJS bundle inlines the modules either way, so this is a swap rather than a removal. The value here is deleting ~1000 lines of duplicated source and the drift risk that comes with it — not bytes. Framing it as a size optimization would be wrong.

Dropped IP-host cookie branch (local dev only)

The vendored cookie.ts omits the cookie domain attribute for bare-IP hosts; coveo.analytics/src/cookieutils.ts has no equivalent, so this PR drops it (#8174, closed).

It only matters when a page is served from a bare IPv4 host (http://192.168.1.1:3000, not a hostname) and localStorage is unavailable — the only case where the vendored Cookie is reachable at all. There, actions history stops working. No deployment on a real domain is affected, and visitorId never used this path.

It was authored in the vendored copy in #5346 (80d43f02c9) while adding review-requested tests, not to fix a bug — a local divergence being retired, not a fix being lost.

Verification

  • tsc --noEmit clean.
  • 5535 tests pass across 429 files, including history-store.test.ts unchanged against the subclass.
  • @coveo/headless#build passes; no ESM require in any CJS output.
  • lint:check clean.

@changeset-bot

changeset-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7aeeb49

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@coveo/headless Patch
@coveo/quantic Patch
@coveo/headless-react Patch
@coveo/atomic-hosted-page Patch
@coveo/atomic Patch
@coveo/atomic-legacy Patch
@coveo/shopify Patch
@coveo/ui-kit-sample-atomic-commerce-react Patch
@coveo/ui-kit-sample-atomic-commerce-vite Patch
@coveo/ui-kit-sample-atomic-search-react Patch
@coveo/ui-kit-sample-atomic-search-vite Patch
@coveo/ui-kit-sample-headless-commerce-react Patch
@coveo/ui-kit-sample-headless-commerce-vite Patch
@coveo/ui-kit-sample-headless-search-react Patch
@coveo/ui-kit-sample-headless-search-vite Patch
@coveo/ui-kit-sample-headless-ssr-commerce-express Patch
@coveo/ui-kit-sample-headless-ssr-commerce-nextjs Patch
@coveo/atomic-react Patch
@coveo/atomic-angular Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svcsnykcoveo

svcsnykcoveo commented Aug 4, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@pkg-pr-new

pkg-pr-new Bot commented Aug 4, 2026

Copy link
Copy Markdown
@coveo/atomic

npm i https://pkg.pr.new/@coveo/atomic@8169

@coveo/atomic-hosted-page

npm i https://pkg.pr.new/@coveo/atomic-hosted-page@8169

@coveo/atomic-legacy

npm i https://pkg.pr.new/@coveo/atomic-legacy@8169

@coveo/atomic-react

npm i https://pkg.pr.new/@coveo/atomic-react@8169

@coveo/auth

npm i https://pkg.pr.new/@coveo/auth@8169

@coveo/bueno

npm i https://pkg.pr.new/@coveo/bueno@8169

@coveo/create-atomic

npm i https://pkg.pr.new/@coveo/create-atomic@8169

@coveo/create-atomic-component

npm i https://pkg.pr.new/@coveo/create-atomic-component@8169

@coveo/create-atomic-component-project

npm i https://pkg.pr.new/@coveo/create-atomic-component-project@8169

@coveo/create-atomic-result-component

npm i https://pkg.pr.new/@coveo/create-atomic-result-component@8169

@coveo/create-atomic-rollup-plugin

npm i https://pkg.pr.new/@coveo/create-atomic-rollup-plugin@8169

@coveo/create-ui

npm i https://pkg.pr.new/@coveo/create-ui@8169

@coveo/headless

npm i https://pkg.pr.new/@coveo/headless@8169

@coveo/headless-react

npm i https://pkg.pr.new/@coveo/headless-react@8169

@coveo/relay

npm i https://pkg.pr.new/@coveo/relay@8169

@coveo/shopify

npm i https://pkg.pr.new/@coveo/shopify@8169

commit: 7aeeb49

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🔗 Scratch Orgs ready to test this PR:

@chromatic-com

chromatic-com Bot commented Aug 4, 2026

Copy link
Copy Markdown

Tip

All tests passed and all changes approved!

🟢 UI Tests: 465 tests unchanged
🟢 UI Review: 465 stories published -- no changes
Storybook icon Storybook Publish: 465 stories published

@alexprudhomme
alexprudhomme force-pushed the KIT-5959-cajs-exports-esm branch from 1e66ed0 to ae9bfe9 Compare August 4, 2026 18:04
@alexprudhomme
alexprudhomme force-pushed the KIT-5959-headless-cajs-esm branch from 382d4f6 to 791814a Compare August 4, 2026 18:04
@alexprudhomme
alexprudhomme force-pushed the KIT-5959-headless-cajs-esm branch from 791814a to 4aea200 Compare August 4, 2026 18:14
@alexprudhomme
alexprudhomme force-pushed the KIT-5959-cajs-exports-esm branch from ae9bfe9 to 9b8e91e Compare August 12, 2026 16:59
Base automatically changed from KIT-5959-cajs-exports-esm to main August 12, 2026 19:19
@alexprudhomme
alexprudhomme force-pushed the KIT-5959-headless-cajs-esm branch from 4aea200 to 6a61ff2 Compare August 12, 2026 19:28

Copilot AI left a comment

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.

Pull request overview

Refactors @coveo/headless to stop vendoring several coveo.analytics internals (cookie/detector/storage/history-store) and instead consume the newly published per-module ESM output, keeping Headless’s singleton HistoryStore behavior via a thin subclass wrapper.

Changes:

  • Deleted the vendored cookie, detector, and storage modules (and their unit tests) from Headless.
  • Replaced the vendored history-store implementation with a subclass of coveo.analytics/dist/esm/history.mjs that preserves the shared-instance (getInstance) behavior.
  • Updated Headless’ esbuild aliasing to ensure deep coveo.analytics/dist/esm/history.mjs imports are bundled (avoiding require() of ESM in CJS output), and added a changeset.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/headless/src/api/analytics/coveo.analytics/storage.ts Deleted vendored storage implementation (now sourced transitively from coveo.analytics history module).
packages/headless/src/api/analytics/coveo.analytics/storage.test.ts Deleted Headless storage unit tests (coverage now expected upstream).
packages/headless/src/api/analytics/coveo.analytics/history-store.ts Replaced vendored HistoryStore with a subclass wrapper around coveo.analytics’ per-module ESM HistoryStore and re-exported HistoryElement type.
packages/headless/src/api/analytics/coveo.analytics/history-store.test.ts Updated tests to import constants/types from coveo.analytics/dist/esm/* while continuing to test the Headless wrapper.
packages/headless/src/api/analytics/coveo.analytics/detector.ts Deleted vendored detector implementation.
packages/headless/src/api/analytics/coveo.analytics/detector.test.ts Deleted Headless detector unit tests (coverage now expected upstream).
packages/headless/src/api/analytics/coveo.analytics/cookie.ts Deleted vendored cookie implementation.
packages/headless/src/api/analytics/coveo.analytics/cookie.test.ts Deleted Headless cookie unit tests (coverage now expected upstream).
packages/headless/esbuild.mjs Added deep-path aliasing for coveo.analytics/dist/esm/history.mjs to keep it bundled and avoid require(ESM) in generated CJS output.
.changeset/headless-cajs-per-module-esm.md Added changeset documenting the refactor.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread .changeset/headless-cajs-per-module-esm.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread packages/headless/esbuild.mjs Outdated
…e cajs aliases

Keeps `new HistoryStore()` unreachable from outside the class, as the vendored
copy did, and extracts the duplicated coveo.analytics alias map so the browser
and node esbuild configs cannot drift.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants