microsoft / microsoft/FluidFramework
Duplicate Code: Devtools messaging message scaffold
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 586
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 146
Description
🔍 Duplicate Code Detected: Devtools message scaffold boilerplate
Analysis of commit 92bb9570be8d1ff42628f2e025467a8462857e29
Assignee: @copilot
Summary
The devtools-core messaging layer repeats the same message “scaffold” (namespace wrapper, MessageType, MessageData, Message extends IDevtoolsMessage, and createMessage) across many message definition files.
This is a high-frequency, structurally-identical pattern that is a good candidate for extraction into a shared helper (or generation), reducing maintenance overhead and risk of inconsistent tweaks across message types.
Duplication Details
Pattern: MessageType + typed Message + createMessage repeated across message types
-
Severity: Medium
-
Occurrences: 23 files under
packages/tools/devtools/devtools-core/src/messaging/**match the full scaffold (MessageType+Message extends IDevtoolsMessage+createMessage). -
Representative locations (all show the same scaffold structure with only message-specific data/docs varying):
packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/CloseContainer.ts(lines 9-52)packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/ConnectContainer.ts(lines 9-52)packages/tools/devtools/devtools-core/src/messaging/devtools-messages/ContainerList.ts(lines 9-59)packages/tools/devtools/devtools-core/src/messaging/telemetry-messages/TelemetryEvent.ts(lines 9-58)
-
Code sample (duplicated scaffold excerpt):
export namespace CloseContainer { export const MessageType = "CLOSE_CONTAINER"; export type MessageData = HasContainerKey; export interface Message extends IDevtoolsMessage(MessageData) { type: typeof MessageType; } export function createMessage(data: MessageData): Message { return { data, type: MessageType, }; } }
Impact Analysis
- Maintainability: Any future change to the message envelope (e.g., adding common fields, changing creation semantics, updating typing/docs patterns) must be replicated across 20+ files.
- Bug Risk: Small divergences are easy to introduce (e.g., inconsistent typing of
type, different return shape, differing docs/behavior). - Code Bloat: The scaffold itself is ~20–40 lines per message, contributing a few hundred lines of repetitive code.
Refactoring Recommendations
-
Extract a shared typed helper in the messaging layer
- Suggested location:
packages/tools/devtools/devtools-core/src/messaging/messageUtils.ts(or colocate inMessages.tsif appropriate) - Example API:
export type TypedDevtoolsMessage(TType extends string, TData) = IDevtoolsMessage(TData) & { type: TType }; export function createDevtoolsMessage(TType extends string, TData)( type: TType, data: TData, ): TypedDevtoolsMessage(TType, TData) { return { type, data }; } - Then each message file can reduce to:
export type Message = TypedDevtoolsMessage(typeof MessageType, MessageData)export const createMessage = (data: MessageData): Message => createDevtoolsMessage(MessageType, data)
- Estimated effort: Medium (mechanical refactor across ~23 files)
- Benefits: Centralized typing + creation logic; reduces duplication substantially.
- Suggested location:
-
(Optional) Consider code generation for message definitions
- If the project already uses generation elsewhere, a small generator could emit these message files from a declarative list (message type string + data shape reference).
- Estimated effort: Higher; best if many more message types are expected.
Implementation Checklist
- Confirm desired public/internal API surface for the helper type/function
- Add helper in messaging layer
- Refactor message definition files to use helper
- Ensure any API Extractor / docs tooling still produces desired docs
- Run build + typecheck + relevant devtools tests
Analysis Metadata
- Analyzed Files: 2804 (non-test
.ts/.cjs/.mjs, excluding workflows) - Detection Method: Serena semantic inspection + structural pattern scan
- Commit: 92bb9570be8d1ff42628f2e025467a8462857e29
- Analysis Date: 2026-03-14T07:57:22.835Z
AI generated by Duplicate Code Detector
To add this workflow in your repository, run
gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4. See usage guide.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the scaffold in CloseContainer.ts, ConnectContainer.ts, ContainerList.ts, and TelemetryEvent.ts under packages/tools/devtools/devtools-core/src/messaging/. Review the proposed helper API and its public/internal surface before refactoring the 23 matching message files. Done means the repeated definitions use a consistent helper and build, typecheck, API Extractor/docs tooling, and relevant devtools tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100