Skip to content

[APPS] Copy apps-function-query runtime into apps plugin#322

Merged
yoannmoinet merged 6 commits intomasterfrom
sdkennedy2/apps-function-query-migrate-runtime
Apr 22, 2026
Merged

[APPS] Copy apps-function-query runtime into apps plugin#322
yoannmoinet merged 6 commits intomasterfrom
sdkennedy2/apps-function-query-migrate-runtime

Conversation

@sdkennedy2
Copy link
Copy Markdown
Collaborator

@sdkennedy2 sdkennedy2 commented Apr 18, 2026

Motivation

Own the executeBackendFunction runtime inside the apps plugin so it can evolve alongside codegen and drop the @datadog/apps-function-query dep from user bundles. This PR only copies the source; the upstack PR wires it up.

Changes

Copied @datadog/apps-function-query from web-ui into packages/plugins/apps/src/backend/client/. Nothing imports it yet.

Adaptations needed to fit this repo:

  • Swapped Apache-2.0 license headers for MIT (build-plugins is MIT).
  • Renamed *.unit.ts*.test.ts to match Jest's testMatch.
  • Added /// <reference lib="dom" /> + /* eslint-env browser */ on files using browser globals (repo tsconfig is lib: ["es2022"]).
  • Dropped the iframe postMessage test suite (no DOM test env in this repo; coverage stays with the original in web-ui). I plan on adding these back in but I'm going to solve support browser tests in a separate PR.
  • Rewrote one try/catch test as .rejects.toMatchObject(...) to satisfy jest/no-jasmine-globals + jest/no-conditional-expect.

QA Instructions

  • yarn workspace @dd/apps-plugin typecheck — 0 errors in src/backend/client/.
  • yarn workspace @dd/tests test:unit packages/plugins/apps/src/backend/client — 6 tests pass.
  • yarn eslint 'packages/plugins/apps/src/backend/client/**/*.ts' --quiet — clean.

Blast Radius

New files only, unreachable until the upstack PR wires them up. No dependency or public API changes.

Documentation

@sdkennedy2 sdkennedy2 requested a review from yoannmoinet as a code owner April 18, 2026 13:27
Copy link
Copy Markdown
Collaborator Author

sdkennedy2 commented Apr 18, 2026

@sdkennedy2 sdkennedy2 changed the title Copy apps-function-query runtime into apps plugin proxy-codegen folder [APPS] Copy apps-function-query runtime into apps plugin Apr 18, 2026
@sdkennedy2
Copy link
Copy Markdown
Collaborator Author

@codex review
@cursor review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 929592a5a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

);
}

return executeActionResponse.result.data;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return dev-server result directly instead of .result.data

The dev-server transport currently assumes a success body shaped like { success: true, result: { data: ... } }, but the in-repo /__dd/executeAction handler returns { success: true, result } directly (see packages/plugins/apps/src/vite/dev-server.ts and its test assertion in dev-server.test.ts). With this code, non-iframe calls will resolve undefined for normal backend-function outputs (or crash if result is null), so generated proxies will lose return values once this runtime is wired in.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified E2E on the stacked PR #320 (where this transport is actually wired in via globalThis.DD_APPS_RUNTIME). The hypothesized mismatch doesn't reproduce: the Datadog preview-async queries API itself returns outputs: { data: <value> }, so the wire shape is already what devServerTransport.result.data expects. The recommended result: { data: result } wrap would have double-nested it.

Repro on PR #320, dev server running against staging:

curl -sS -X POST http://127.0.0.1:5173/__dd/executeAction \
  -H 'Content-Type: application/json' \
  -d '{"functionName":"<hash>.getGreeting","args":["World"]}'
# {"success":true,"result":{"data":{"message":"Hello, World! ..."}}}

Why static review missed it: dev-server.ts declares its own loose ExecuteActionResponse with result?: unknown, so the satisfies at the response site has no teeth. And dev-server.test.ts mocks Datadog's API as outputs: { result: 'hello' } — without the data layer the real API adds — so the mock has drifted from reality and wouldn't catch a real shape change either.

Smaller real fix, split across the stack:

This PR (#322):

  • Extract canonical ExecuteActionRequest / ExecuteActionResponse<TData> from backend/client/types.ts into a new backend/protocol.ts (single source of truth, neutral location).
  • Update transports/dev-server-transport.ts and transports/post-message-transport/types.ts imports to pull from there.

PR #320:

  • Replace dev-server.ts's local interfaces with imports from ../backend/protocol; type executeScriptViaDatadog as returning { data: unknown } so satisfies ExecuteActionResponse actually checks the wire contract.
  • Update dev-server.test.ts mocks to use the real outputs: { data: ... } shape so future drift IS caught.

No wire-behavior change. Closing this as not-reproduced; the type + mock work above prevents recurrence. Resolving #3105276088 and #3105612205 as duplicates.

@sdkennedy2
Copy link
Copy Markdown
Collaborator Author

@codex review
@cursor review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41540bfc4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

);
}

return executeActionResponse.result.data;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align result parsing with /__dd/executeAction payload

This transport assumes successful responses are shaped as {"success": true, "result": { "data": ... }}, but the current dev-server handler returns {"success": true, "result": ...} (packages/plugins/apps/src/vite/dev-server.ts:302). As written, successful backend calls will resolve to undefined (or throw when result is null) instead of the actual function output once this runtime is wired in, which breaks normal backend-function execution in dev.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Responded in the previous thread.

The backend/client files use browser APIs (window, MessageEvent, fetch)
that need DOM types, but adding them via /// <reference lib="dom" />
polluted the entire workspace compilation — causing Node.js types
(Blob, ReadableStream, Headers) to clash with DOM equivalents across
@dd/core and other packages.

Fix: split into two tsconfigs — the main one excludes backend/client,
and a new tsconfig.client.json includes only those files with
lib: ["es2022", "dom"]. The typecheck script chains both.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sdkennedy2
Copy link
Copy Markdown
Collaborator Author

@codex review
@cursor review

@chatgpt-codex-connector
Copy link
Copy Markdown

Summary

Testing

  • ⚠️ yarn workspace @dd/tests test:unit packages/plugins/apps/src/backend/client/execute-backend-function.test.ts (tests passed, but repo fixture setup logged a network/corepack warning in this environment).
  • ./node_modules/.bin/eslint packages/plugins/apps/src/backend/client/types.ts packages/plugins/apps/src/backend/client/transports/dev-server-transport.ts packages/plugins/apps/src/backend/client/transports/post-message-transport/post-message-transport.ts packages/plugins/apps/src/backend/client/execute-backend-function.test.ts
  • ./node_modules/.bin/jest packages/plugins/apps/src/backend/client/execute-backend-function.test.ts --runInBand (fails in this repo without the workspace Jest harness / TS transform config).

View task →

@sdkennedy2
Copy link
Copy Markdown
Collaborator Author

@codex review
@cursor review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d972daf59d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

);
}

return executeActionResponse.result.data;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return the executeAction result without forcing .data

devServerTransport currently assumes the success payload is { success: true, result: { data: ... } }, but the in-repo /__dd/executeAction handler returns { success: true, result } directly (packages/plugins/apps/src/vite/dev-server.ts, handleExecuteAction) and its tests assert body.result is the final value (packages/plugins/apps/src/vite/dev-server.test.ts). In that common path, executeActionResponse.result.data is undefined, so backend function calls will silently lose their return value in dev mode once this runtime is wired up.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Responded in the previous thread.

Copy link
Copy Markdown
Member

@yoannmoinet yoannmoinet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review makes sense to me, will you follow it?

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.

2 participants