Skip to content

Conversation

@johallar
Copy link
Contributor

@johallar johallar commented Nov 10, 2025

Description

This removes flow, and replaces it with typescript, and is the next step in the plan laid out in #25716 (comment)

Motivation and Context

Typescript has better tooling, and has a bigger community around it so this will be another QOL improvement for developers.

Big # line changes is mostly yarn-lock changes, the code diff relatively small

Impact

Test Plan

CI passes, there should be no user facing changes

Contributor checklist

  • Please make sure your submission complies with our contributing guide, in particular code style and commit standards.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.
  • If adding new dependencies, verified they have an OpenSSF Scorecard score of 5.0 or higher (or obtained explicit TSC approval for lower scores).

Release Notes

Please follow release notes guidelines and fill in the release notes below.

== NO RELEASE NOTE ==

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 10, 2025

Reviewer's Guide

This PR fully replaces Flow with TypeScript by converting all Flow type annotations to TS, renaming source files to .ts/.tsx, refactoring components for TS compatibility, and updating the build, lint, and packaging configurations to integrate TypeScript support.

Class diagram for updated QueryOverview types (Flow to TypeScript)

classDiagram
    class TaskStatus {
        self: string
        state: string
    }
    class TaskStats {
        createTimeInMillis: number
        elapsedTimeInNanos: number
        totalCpuTimeInNanos: number
        fullyBlocked: boolean
        queuedDrivers: number
        runningDrivers: number
        blockedDrivers: number
        totalDrivers: number
        completedDrivers: number
        queuedNewDrivers: number
        runningNewDrivers: number
        totalNewDrivers: number
        completedNewDrivers: number
        queuedSplits: number
        runningSplits: number
        totalSplits: number
        completedSplits: number
        rawInputPositions: number
        rawInputDataSizeInBytes: number
        totalScheduledTimeInNanos: number
    }
    class TaskOutputBuffers {
        type: string
        state: string
        totalBufferedBytes: number
    }
    class Task {
        taskId: string
        taskStatus: TaskStatus
        stats: TaskStats
        nodeId: string
        outputBuffers: TaskOutputBuffers
    }
    class RuntimeStat {
        name: string
        unit: string
        sum: number
        count: number
        max: number
        min: number
    }
    class RuntimeStats {
        key_string: RuntimeStat
    }
    class OutputStage {
        stageId: string
        self: string
        plan: unknown
        latestAttemptExecutionInfo: StageExecutionInfo
        previousAttemptsExecutionInfos: StageExecutionInfo[]
        subStages: OutputStage[]
        isRuntimeOptimized: boolean
    }
    class StageExecutionInfo {
        state: string
        stats: QueryStats
        tasks: Task[]
        failureCause: string
    }
    class QueryStats {
        totalScheduledTime: string
        totalBlockedTime: string
        totalCpuTime: string
        cumulativeUserMemory: number
        cumulativeTotalMemory: number
        userMemoryReservation: string
        peakUserMemoryReservation: string
        runtimeStats: RuntimeStats
        elapsedTime: string
        createTime: string
        endTime: string
        waitingForPrerequisitesTime: string
        queuedTime: string
        totalPlanningTime: string
        executionTime: string
        processedInputPositions: number
        processedInputDataSize: string
        rawInputPositions: number
        rawInputDataSize: string
        shuffledPositions: number
        shuffledDataSize: string
        peakTotalMemoryReservation: string
        outputPositions: number
        outputDataSize: string
        writtenOutputPositions: number
        writtenOutputLogicalDataSize: string
        writtenOutputPhysicalDataSize: string
        spilledDataSize: string
    }
    class FailureInfo {
        type: string
        message: string
        cause: FailureInfo
        suppressed: FailureInfo[]
        stack: string[]
        errorCode: string
        errorCause: string
    }
    class ResourceEstimates {
        executionTime: string
        cpuTime: string
        peakMemory: string
        peakTaskMemory: string
        key_string: string
    }
    class SessionRepresentation {
        systemProperties: string
        catalogProperties: string
        resourceEstimates: ResourceEstimates
        user: string
        principal: string
        source: string
        catalog: string
        schema: string
        traceToken: string
        timeZoneKey: number
        locale: string
        remoteUserAddress: string
        userAgent: string
        clientInfo: string
        clientTags: string[]
        startTime: number
    }
    class PrestoWarning {
        warningCode: string
        message: string
    }
    class ErrorCode {
        code: number
        name: string
        type: string
        retriable: boolean
    }
    class QueryData {
        outputStage: OutputStage
        queryId: string
        session: SessionRepresentation
        preparedQuery: string
        warnings: PrestoWarning[]
        queryStats: QueryStats
        failureInfo: FailureInfo
        errorType: string
        errorCode: ErrorCode
        resourceGroupId: string[]
        self: string
        memoryPool: string
        query: string
    }
    Task --> TaskStatus
    Task --> TaskStats
    Task --> TaskOutputBuffers
    StageExecutionInfo --> QueryStats
    StageExecutionInfo --> Task
    OutputStage --> StageExecutionInfo
    OutputStage --> OutputStage
    QueryStats --> RuntimeStats
    RuntimeStats --> RuntimeStat
    QueryData --> OutputStage
    QueryData --> SessionRepresentation
    QueryData --> PrestoWarning
    QueryData --> QueryStats
    QueryData --> FailureInfo
    QueryData --> ErrorCode
    SessionRepresentation --> ResourceEstimates
Loading

Class diagram for updated PageTitle component types (Flow to TypeScript)

classDiagram
    class Props {
        titles: string[]
        urls: string[]
        current: number
        path: string
    }
    class State {
        noConnection: boolean
        lightShown: boolean
        info: any | null | undefined
        lastSuccess: number
        modalShown: boolean
        errorText: string | null | undefined
    }
    Props --> State
Loading

Class diagram for updated LivePlan component types (Flow to TypeScript)

classDiagram
    class StageStatisticsProps {
        stage: any
    }
    class StageNodeInfo {
        stageId: string
        id: string
        root: string
        distribution: any
        stageStats: any
        state: string
        nodes: Map<string, any>
    }
    class OutputStage {
        subStages: any
        stageId: string
        latestAttemptExecutionInfo: any
        plan: any
    }
    class QueryInfo {
        outputStage: OutputStage
    }
    class PlanNodeProps {
        id: string
        name: string
        identifier: string
        details: string
        sources: string[]
        remoteSources: string[]
    }
    class LivePlanProps {
        queryId: string
        isEmbedded: boolean
    }
    class LivePlanState {
        initialized: boolean
        ended: boolean
        query: any | null | undefined
    }
    OutputStage --> StageNodeInfo
    QueryInfo --> OutputStage
Loading

Class diagram for updated Split component types (Flow to TypeScript)

classDiagram
    class QueryState {
        query: any | null
        failed: boolean
        ended: boolean
    }
Loading

Class diagram for updated SQLInput types (Flow to TypeScript)

classDiagram
    class PrestoClientConfig {
        host: string
        port: number
        user: string
        catalog: string
        schema: string
        sessions: string
    }
    class PrestoClient {}
    PrestoClientConfig --> PrestoClient
Loading

Class diagram for updated SQLClient types (Flow to TypeScript)

classDiagram
    class SessionValues {
        "[key: string]": string
    }
Loading

Class diagram for updated utility function types (Flow to TypeScript)

classDiagram
    class UtilityFunctions {
        getHumanReadableState(queryState: string, scheduled: boolean, fullyBlocked: boolean, blockedReasons: Array<unknown>, memoryPool: string, errorType: string, errorCodeName: string): string
        parseDataSize(value: string): number | null | undefined
        parseDuration(value: string): number | null | undefined
    }
Loading

File-Level Changes

Change Details Files
Remove Flow and enable TypeScript across the codebase
  • Removed all Flow annotations, directives, and dependencies
  • Converted type definitions from Flow syntax to TS (semicolons, explicit types, unknown instead of mixed)
  • Renamed source files from .js/.jsx to .ts/.tsx
  • Replaced Flow ignore comments with @ts-expect-error
src/components/QueryOverview.tsx
src/components/LivePlan.tsx
src/components/PageTitle.tsx
src/router/PageTitle.tsx
src/components/Splits.tsx
src/components/SQLInput.tsx
src/components/SQLClient.tsx
src/components/SessionProps.tsx
src/components/QueryPlanView.tsx
src/components/QuerySplitsView.tsx
src/utils.ts
Refactor React components for TypeScript compatibility
  • Updated function return types from React.Node to React.ReactElement
  • Re-typed event handlers (e.g. React.MouseEvent) and useRef timers as number
  • Adjusted property checks to use Object.prototype.hasOwnProperty.call or Object.keys
  • Casted customStyles and added explicit HTML element refs
  • Replaced setTimeout calls with window.setTimeout and added ts-expect-error for untyped plugins
src/components/QueryOverview.tsx
src/components/LivePlan.tsx
src/components/PageTitle.tsx
src/components/Splits.tsx
src/components/SQLInput.tsx
src/components/SQLClient.tsx
src/components/QueryPlanView.tsx
src/components/QuerySplitsView.tsx
Update build and lint configurations for TypeScript
  • Added tsconfig.json and configured ts-loader in webpack.config.js
  • Extended webpack resolve to include .ts/.tsx
  • Revised ESLint config to use @typescript-eslint parser/plugin and removed Flow plugin
  • Updated package.json: removed Flow deps, added TS deps, added typecheck script, expanded lint/format scripts
  • Modified CI script to run tsc typecheck instead of Flow
tsconfig.json
webpack.config.js
eslint.config.mjs
package.json
bin/check_webui.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@johallar johallar marked this pull request as ready for review November 12, 2025 16:37
@johallar johallar requested review from a team and yhwang as code owners November 12, 2025 16:37
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Consider enabling stricter TypeScript compiler options (e.g. strictNullChecks, noImplicitAny) in tsconfig to catch more issues early and improve overall type safety.
  • There’s still a lot of any usage and @ts-expect-error shims for third-party libs—adding or sourcing proper type declarations for sparkline, hljs, and jQuery plugins would eliminate many of these ignores and tighten your typings.
  • You have many inline prop/state types across components—extracting shared interfaces (or using React.FC) could reduce duplication and improve readability/maintainability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider enabling stricter TypeScript compiler options (e.g. strictNullChecks, noImplicitAny) in tsconfig to catch more issues early and improve overall type safety.
- There’s still a lot of `any` usage and `@ts-expect-error` shims for third-party libs—adding or sourcing proper type declarations for sparkline, hljs, and jQuery plugins would eliminate many of these ignores and tighten your typings.
- You have many inline prop/state types across components—extracting shared interfaces (or using React.FC<Props>) could reduce duplication and improve readability/maintainability.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Member

@yhwang yhwang left a comment

Choose a reason for hiding this comment

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

Went through the changes and don't see any issue. I will try the changes locally soon and update you.

Great effort! Thanks.

@yhwang
Copy link
Member

yhwang commented Nov 17, 2025

@johallar, since you updated the utils, would you mind also updating d3utils to ts? And my local testing is doing well!

@yhwang
Copy link
Member

yhwang commented Nov 17, 2025

@johallar one last comment (sorry that I didn't put all comments at once):

How do you think about the @typescript-eslint/no-unused-vars rule?
I am thinking of turning on error for this one, and maybe have the ignore pattern option, something like:

            "@typescript-eslint/no-unused-vars": [
                "error",
                {
                    argsIgnorePattern: "^_",
                    varsIgnorePattern: "^_",
                },
            ],

How do you think? And I know this would lead to one error in the QueryOverview.tsx, but that could be fixed by either removing the arg or using _.

And that's all I have!! Again, thanks for the effort.

@johallar
Copy link
Contributor Author

@yhwang Yes, definitely think this should be a rule, i'll add and fix the errors!

Copy link
Member

@yhwang yhwang left a comment

Choose a reason for hiding this comment

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

Great work!
/LGTM

@yhwang yhwang merged commit 9297555 into prestodb:master Nov 18, 2025
82 of 85 checks passed
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.

2 participants