Skip to content

refactor(sdk): replace TypeScript enums with const objects for strip-types compatibility#8084

Merged
steveruizok merged 8 commits intomainfrom
steveruizok/replace-enums-with-const-objects
Feb 25, 2026
Merged

refactor(sdk): replace TypeScript enums with const objects for strip-types compatibility#8084
steveruizok merged 8 commits intomainfrom
steveruizok/replace-enums-with-const-objects

Conversation

@steveruizok
Copy link
Copy Markdown
Collaborator

@steveruizok steveruizok commented Feb 25, 2026

Closes #8083

In order to support Node's built-in TypeScript strip-types feature (which does not support enums), this PR converts all 13 TypeScript enums in the repo to the const object + type alias pattern.

Changes

Public API (@public):

  • MigrationFailureReason in packages/store/src/lib/migrate.ts
  • PORTRAIT_BREAKPOINT in packages/tldraw/src/lib/ui/constants.ts

Internal (SDK packages):

  • ArrowHandles in packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx
  • HistoryRecorderState in packages/editor/src/lib/editor/managers/HistoryManager/HistoryManager.ts

Internal (V1 migration compat, @internal):

  • TLV1ShapeType, TLV1ColorStyle, TLV1SizeStyle, TLV1DashStyle, TLV1AlignStyle, TLV1FontStyle, TLV1Decoration, TLV1AssetType in packages/tldraw/src/lib/utils/tldr/buildFromV1Document.ts

Docs app:

  • ArticleStatus, APIGroup in apps/docs/types/content-types.ts

Enum members used in type position (e.g. type: TLV1ShapeType.Draw in discriminated unions) have been updated to use typeof (e.g. type: typeof TLV1ShapeType.Draw).

Change type

  • improvement

Test plan

The const object pattern produces identical runtime values and the same usage patterns as enums. All value-position usages (MigrationFailureReason.MigrationError, PORTRAIT_BREAKPOINT.MOBILE, etc.) work unchanged. Type-position usages have been updated to use typeof.

  • Unit tests
  • End to end tests

Release notes

  • Replace all TypeScript enums with const object + type alias pattern for compatibility with Node's built-in TypeScript support (strip-types).

API changes

  • MigrationFailureReason changed from enum to const object with type alias (runtime-compatible, same values)
  • PORTRAIT_BREAKPOINT changed from enum to const object with type alias (runtime-compatible, same values)

Note

Medium Risk
Moderate risk because it changes exported runtime symbols from enum objects to plain const objects, which can break consumers relying on enum-specific runtime behavior (e.g. reverse mappings) despite identical values.

Overview
Refactors the codebase to eliminate TypeScript enums in favor of as const objects plus union type aliases, improving compatibility with Node’s strip-types type-stripping.

This includes public API surface changes for @tldraw/store (MigrationFailureReason) and @tldraw/tldraw (PORTRAIT_BREAKPOINT), with generated API reports updated accordingly and declare namespace shims added where needed for backward-compat type usage.

Internal enums in the editor, tldraw arrow util, V1 document migration types, and docs content types are similarly converted, and enum-member type positions are updated to typeof SomeConst.Member. Separately, the image-pipeline worker adds explicit ArrayBuffer casts for bytes.buffer return/usage to satisfy typing.

Written by Cursor Bugbot for commit 92edbe7. This will update automatically on new commits. Configure here.

…types compatibility

Convert all 13 TypeScript enums to the `const object + type alias` pattern
to support Node's built-in TypeScript strip-types feature, which does not
support enums.
@huppy-bot huppy-bot bot added the improvement Product improvement label Feb 25, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples Ready Ready Preview Feb 25, 2026 7:27pm
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
analytics Ignored Ignored Preview Feb 25, 2026 7:27pm
chat-template Ignored Ignored Preview Feb 25, 2026 7:27pm
tldraw-docs Ignored Ignored Preview Feb 25, 2026 7:27pm
tldraw-shader Ignored Ignored Preview Feb 25, 2026 7:27pm
workflow-template Ignored Ignored Preview Feb 25, 2026 7:27pm

Request Review

Copy link
Copy Markdown
Collaborator

@ds300 ds300 left a comment

Choose a reason for hiding this comment

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

there's a few very minor backcompat issues here that could be easily worked around, which i'd prefer us to do. but no biggie either way.

steveruizok and others added 3 commits February 25, 2026 15:53
…conversions

Adds `declare namespace` type aliases for `MigrationFailureReason` and
`PORTRAIT_BREAKPOINT` so that consumers using enum members in type
position (e.g. `MigrationFailureReason.IncompatibleSubtype` as a type)
continue to work after the enum-to-const-object refactor.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@steveruizok
Copy link
Copy Markdown
Collaborator Author

@claude fix

@claude
Copy link
Copy Markdown

claude bot commented Feb 25, 2026

Claude finished @steveruizok's task in 2m 59s —— View job


Backward compat fix for MigrationFailureReason and PORTRAIT_BREAKPOINT

  • Read changed files to understand current state
  • Apply export declare namespace pattern to MigrationFailureReason in migrate.ts
  • Apply export declare namespace pattern to PORTRAIT_BREAKPOINT in constants.ts
  • Update API reports
  • Push changes (blocked: write access denied for this bot on the tldraw repo)

I've prepared the changes locally but couldn't push due to repository permissions. Here's what needs to be applied to address ds300's suggestion:

Changes made

packages/store/src/lib/migrate.ts — Added declare namespace for backward compat + fixed indentation (spaces → tabs):

// Backward compat: allows `MigrationFailureReason.MigrationError` to be used as a type
export declare namespace MigrationFailureReason {
	export type IncompatibleSubtype = typeof MigrationFailureReason.IncompatibleSubtype
	export type UnknownType = typeof MigrationFailureReason.UnknownType
	export type TargetVersionTooNew = typeof MigrationFailureReason.TargetVersionTooNew
	export type TargetVersionTooOld = typeof MigrationFailureReason.TargetVersionTooOld
	export type MigrationError = typeof MigrationFailureReason.MigrationError
	export type UnrecognizedSubtype = typeof MigrationFailureReason.UnrecognizedSubtype
}

packages/tldraw/src/lib/ui/constants.ts — Added declare namespace for PORTRAIT_BREAKPOINT + fixed stale "enum" comment:

// Backward compat: allows `PORTRAIT_BREAKPOINT.MOBILE` to be used as a type
/** @public */
export declare namespace PORTRAIT_BREAKPOINT {
	export type ZERO = typeof PORTRAIT_BREAKPOINT.ZERO
	export type MOBILE_XXS = typeof PORTRAIT_BREAKPOINT.MOBILE_XXS
	export type MOBILE_XS = typeof PORTRAIT_BREAKPOINT.MOBILE_XS
	export type MOBILE_SM = typeof PORTRAIT_BREAKPOINT.MOBILE_SM
	export type MOBILE = typeof PORTRAIT_BREAKPOINT.MOBILE
	export type TABLET_SM = typeof PORTRAIT_BREAKPOINT.TABLET_SM
	export type TABLET = typeof PORTRAIT_BREAKPOINT.TABLET
	export type DESKTOP = typeof PORTRAIT_BREAKPOINT.DESKTOP
}

packages/store/api-report.api.md and packages/tldraw/api-report.api.md — Added the resolved namespace type declarations.

Note: The commit is ready locally but push was blocked by repository permissions. You can apply these changes manually or grant the bot write access.

Add explicit @public annotations for MigrationFailureReason, its type alias, and namespace in migrate.ts while removing the long JSDoc block. Update the API report to reflect the symbol as public (undocumented). These changes standardize visibility annotations and simplify the documentation comment.
Add explicit `as ArrayBuffer` type assertions in worker template functions to satisfy TypeScript typings. The changes are limited to templates/image-pipeline/worker/providers/types.ts and templates/image-pipeline/worker/routes/generate.ts and do not alter runtime behavior; they prevent type errors when accessing ArrayBuffer properties.
@vercel vercel bot temporarily deployed to Preview – workflow-template February 25, 2026 18:38 Inactive
@vercel vercel bot temporarily deployed to Preview – chat-template February 25, 2026 18:38 Inactive
@vercel vercel bot temporarily deployed to Preview – tldraw-shader February 25, 2026 18:38 Inactive
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Feb 25, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
image-pipeline-template e2cc538 Commit Preview URL

Branch Preview URL
Feb 25 2026, 06:41 PM

@steveruizok steveruizok added this pull request to the merge queue Feb 25, 2026
Merged via the queue into main with commit 2879b2c Feb 25, 2026
19 checks passed
@steveruizok steveruizok deleted the steveruizok/replace-enums-with-const-objects branch February 25, 2026 20:43
steveruizok added a commit that referenced this pull request Feb 27, 2026
Add 12 new entries from PRs merged since v4.4.0:
- Featured: click-through on transparent image pixels (#7942)
- API: enum-to-const-object refactor (#8084)
- Improvements: SVG sanitizer (#7896), save-on-blur (#8037)
- Bug fixes: cross-origin download (#8090), zero-size draw (#8067),
  rich text toolbar cleanup (#8050), zoom threshold (#8040),
  selection foreground fallback (#8011), sticky note SVG shadow (#7934),
  arrow frame clamping (#7932), zero pressure draw (#5693)
github-merge-queue bot pushed a commit that referenced this pull request Mar 4, 2026
Update `next.mdx` release notes to cover all SDK-relevant PRs merged to
main since v4.4.0.

Highlights:
- Display values system (#8121) with breaking changes and migration
guide
- Click-through on transparent image pixels (#7942)
- `Editor.resizeToBounds()` (#8120)
- SVG sanitization (#7896)
- TypeScript enum-to-const refactoring (#8084)
- 14 bug fixes and 4 improvements

### Change type

- [x] `other`

### Test plan

1. Verify the release notes render correctly on the docs site

### Release notes

- Update next release notes with changes since v4.4.0.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: documentation-only changes updating release notes content
and date, with no runtime/code behavior impact.
> 
> **Overview**
> Updates `apps/docs/content/releases/next.mdx` for the upcoming release
by refreshing the date and replacing the brief blurb with expanded
release notes.
> 
> Documents new SDK surface area (`Geometry2d.ignoreHit`,
`Editor.resizeToBounds`, `sanitizeSvg`), highlights click-through on
transparent image pixels, and adds a list of recent improvements and bug
fixes (paste parenting, link/alt-text persistence, SVG sanitization
behavior, circular-dependency cleanup, and several crash/export/sync
fixes).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5f7dc0a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
github-merge-queue bot pushed a commit that referenced this pull request Mar 18, 2026
In order to publish the v4.5.0 release notes and record the v4.4.1
patch, this PR archives release notes and resets `next.mdx` for the next
cycle.

**v4.5.0.mdx** (new file):
- Archived from `next.mdx` with full frontmatter, keywords, and GitHub
release link
- Featured sections: click-through on transparent image pixels (#7942),
breaking `EmbedShapeUtil.configure()` change (#8034)
- API changes: `Editor.getResizeScaleFactor()` (#8042),
`TLImageAsset.pixelRatio` (#8163), `sanitizeSvg` (#7896),
`experimental__onDropOnCanvas` (#7911), enum-to-const refactoring
(#8084)
- 6 improvements and 20 bug fixes from production

**v4.4.0.mdx:**
- Add v4.4.1 patch release section with tooltip positioning fix (#8171)
- Add v4.4.1 to keywords

**next.mdx:**
- Reset with `last_version: v4.5.0` and empty content

### Change type

- [x] `other`

### Code changes

| Section       | LOC change    |
| ------------- | ------------- |
| Documentation | +128 / -107   |
huppy-bot bot pushed a commit that referenced this pull request Mar 18, 2026
In order to publish the v4.5.0 release notes and record the v4.4.1
patch, this PR archives release notes and resets `next.mdx` for the next
cycle.

**v4.5.0.mdx** (new file):
- Archived from `next.mdx` with full frontmatter, keywords, and GitHub
release link
- Featured sections: click-through on transparent image pixels (#7942),
breaking `EmbedShapeUtil.configure()` change (#8034)
- API changes: `Editor.getResizeScaleFactor()` (#8042),
`TLImageAsset.pixelRatio` (#8163), `sanitizeSvg` (#7896),
`experimental__onDropOnCanvas` (#7911), enum-to-const refactoring
(#8084)
- 6 improvements and 20 bug fixes from production

**v4.4.0.mdx:**
- Add v4.4.1 patch release section with tooltip positioning fix (#8171)
- Add v4.4.1 to keywords

**next.mdx:**
- Reset with `last_version: v4.5.0` and empty content

### Change type

- [x] `other`

### Code changes

| Section       | LOC change    |
| ------------- | ------------- |
| Documentation | +128 / -107   |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Product improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace TypeScript enums with const objects for strip-types compatibility

2 participants