Skip to content

♻️ move batching transport stack to @datadog/js-core - #4856

Draft
BenoitZugmeyer wants to merge 13 commits into
mainfrom
benoit/move-transport
Draft

♻️ move batching transport stack to @datadog/js-core#4856
BenoitZugmeyer wants to merge 13 commits into
mainfrom
benoit/move-transport

Conversation

@BenoitZugmeyer

Copy link
Copy Markdown
Member

Motivation

The @datadog/js-core package is meant to hold runtime-agnostic SDK utilities
shared across all Datadog JS SDKs. However, the entire batching transport stack
(createBatch, createHttpRequest, createFlushController, and all their
dependencies) lived exclusively in @datadog/browser-core, making it
unavailable to non-browser consumers such as the Worker or future server-side
SDK targets.

This PR moves the complete transport stack into @datadog/js-core, with
browser-specific concerns (fetch, sendBeacon, DOM events) remaining in
browser-core as injectable strategies.

Changes

  • Pure utilities (byteUtils, jsonStringify, context, objectValues,
    isServerError) moved to @datadog/js-core/util; browser-core re-exports.
  • mockable moved to @datadog/js-core/util.
  • Observable, BufferedObservable, mergeObservables, queueMicrotask
    moved to @datadog/js-core/util; queueMicrotask drops the monitor()
    wrapper (callers handle error wrapping at their own layer).
  • Encoder / createIdentityEncoder moved to @datadog/js-core/transport.
  • timer / getZoneJsOriginalValue moved to @datadog/js-core/util;
    js-core timer has no monitor() wrapping; browser-core keeps monitored wrappers.
  • sendWithRetryStrategy and Payload types moved to
    @datadog/js-core/transport; navigator.onLine access goes through
    globalObject.
  • flushController moved to @datadog/js-core/transport; PageExitReason
    and PageMayExitEvent move with it as pure types; pageMayExitObservable
    is injected as a parameter.
  • createHttpRequest moved to @datadog/js-core/transport with injectable
    sendStrategy / sendOnExitStrategy; browser-core keeps fetchStrategy and
    sendBeaconStrategy and wraps the js-core factory.
  • createBatch moved to @datadog/js-core/transport; request and
    pageMayExitObservable are injected parameters; display.warn becomes an
    injected warn function; browser-core wrapper preserves the existing call
    signature for all current callers.
  • API cleanup: sendWithRetryStrategy, newRetryState, RetryState,
    internal constants, createFlushController, and FlushController are
    removed from js-core's public transport entry — they are internal details.
    Their specs move to js-core alongside the implementation.

Test instructions

This is a pure refactor with no observable behaviour change. All existing unit
tests cover the moved code. To sanity-check the SDK still initialises and
sends data correctly:

  1. Run yarn dev and open http://localhost:8080.
  2. Check the Network tab — RUM and Logs requests should still be sent to the
    intake endpoints on the configured interval.
  3. Navigate away from the page and confirm a flush request is sent on
    beforeunload/visibilitychange.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 8, 2026

Copy link
Copy Markdown

Pipelines  Tests

Unblock PR with BitsAI

⚠️ Warnings

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 1 Pipeline job failed

DataDog/browser-sdk | build-and-lint — 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 82.92%
Overall Coverage: 77.16% (+0.20%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 4e48c7a | Docs | View more details | Give us feedback!

@BenoitZugmeyer
BenoitZugmeyer force-pushed the benoit/move-transport branch from fa999e3 to db9e0f1 Compare July 8, 2026 15:17
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jul 8, 2026

Copy link
Copy Markdown

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 181.52 KiB 181.80 KiB +291 B +0.16%
Rum Profiler 8.43 KiB 8.43 KiB -1 B -0.01%
Rum Recorder 22.31 KiB 22.31 KiB -2 B -0.01%
Logs 57.63 KiB 57.97 KiB +349 B +0.59%
Rum Salesforce N/A 139.94 KiB N/A N/A N/A
Rum Slim 139.59 KiB 139.93 KiB +352 B +0.25%
Worker 22.96 KiB 22.96 KiB 0 B 0.00%
Rum Shopify N/A 202.63 KiB N/A N/A N/A
Rum-shopify Profiler N/A 8.43 KiB N/A N/A N/A
Rum-shopify Recorder N/A 3.72 KiB N/A N/A N/A

Move byteUtils, context types, jsonStringify, objectValues and isServerError
to js-core — they have no browser-specific dependencies and are needed by the
transport modules that will follow in subsequent commits.

Browser-core files become thin re-exports so all existing relative imports
keep working without touching every consumer.
… public API

These were exported as stepping stones during the migration but have no
legitimate external consumers:

- sendWithRetryStrategy, newRetryState, RetryState, and the bandwidth /
  retry constants are internal machinery of createHttpRequest; remove
  them from @datadog/js-core/transport
- FlushController is the internal return type of createFlushController;
  callers that needed the type can use ReturnType<typeof createFlushController>
- browser-core's dead sendWithRetryStrategy.ts re-export shim is deleted
  (nothing ever imported from it)
- sendWithRetryStrategy.spec.ts moves from browser-core to js-core so it
  can use internal imports; a minimal test/ helper (registerCleanupTask,
  mockClock, mockNavigator) is added to js-core for this
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.

1 participant