[pull] main from tldraw:main#606
Merged
Merged
Conversation
In order to keep the public MCP worker (`tldraw-mcp-app`) on the same commit and SDK build as production dotcom without a manual step, this PR makes `deploy-mcp-app.yml` auto-deploy on every push to the `production` branch, mirroring how the VS Code extension auto-publishes via its `push` trigger. Previously the workflow was `workflow_dispatch`-only, so it never ran automatically (despite #8587's description, the auto-trigger was never wired up). This adds a `push` trigger scoped to `production` and keeps the manual `workflow_dispatch`. `TARGET` now falls back to `github.ref_name` so the checkout ref resolves for both event types. Production only: the MCP app is a single Cloudflare worker with no staging environment, so a push to `main` must not overwrite the shared `tldraw-mcp-app` worker. (This is why it does not also trigger on `main` like the VS Code extension, which has a separate staging pre-release channel.) ### Change type - [x] `other` ### Test plan 1. Confirm `MCP_APP_TLDRAW_LICENSE_KEY` and the Cloudflare secrets are available to the `deploy-production` environment. 2. After merge, push to `production` (or wait for a production release) and confirm the **Deploy MCP app** workflow runs automatically and the worker serves the new bundle. 3. Confirm the manual **Deploy MCP app** workflow_dispatch still works. ### Code changes | Section | LOC change | | -------------- | ---------- | | Config/tooling | +8 / -1 |
### The problem
The workspace sidebar can crash the whole app on the proper-Zero
backend:
```
TypeError: Cannot read properties of undefined (reading 'owningGroupId')
at getWorkspaceFilesSorted (TldrawApp.ts)
```
`getWorkspaceFilesSorted` reads `f.file.owningGroupId` for every
`group_file` row, assuming the `file` is always there. The
`workspaceMemberships` query joins `file` as a Zero `.one()`
relationship, which resolves to `undefined` when the referenced `file`
row isn't in the client's synced data. A `group_file` row can be present
without its `file` when:
- the file was deleted, leaving a dangling join row,
- the join row synced before its file row, or
- the file is filtered out server-side because the user can no longer
read it.
Any of these throws inside the sidebar's reactive derive and takes down
the component tree. The declared type `groupFiles: Array<TlaGroupFile &
{ file: TlaFile }>` asserted `file` was always present, so the compiler
never flagged the access.
This only affects the proper-Zero path. The legacy `ZeroPolyfill`
already drops orphan rows at the source (`compact()` + `if (!file)
return null`), so the guard was effectively lost when proper Zero took
over the same shape. Introduced in #9270.
### The change
- Make the type honest: `file: TlaFile | undefined`.
- Drop orphan rows in `getWorkspaceFilesSorted` via a type-guard
predicate, so the non-undefined narrowing flows into `pinned`/`unpinned`
and the rest of the function with no scattered `!` assertions.
- Guard the `canCreateNewFile` file-limit count the same way.
### Testing
Added `getWorkspaceFilesSorted.test.ts`, which drives the real method
against a membership whose first row is an orphan (`file: undefined`).
Without the guard it reproduces the exact production crash; with it, the
orphan is excluded and the owned file is returned. `yarn typecheck`
passes (the honest type surfaced two more access sites, fixed by the
type guard).
In order to keep dotcom styling aligned with the SDK token set, this PR replaces near-match app-shell CSS variable references with existing `--tl-*` package variables and removes now-dead dotcom token metadata. It folds the dotcom `--tla-color-overlay` token onto the package `--tl-color-overlay`, drops the radius and shadow-highlight leftovers from `tla.css`, and deletes the `TLA_COLOR_KEYS_TO_OMIT` set in `ui-themes.ts` (and its filter), which had become a no-op once the color migration landed — none of the keys it listed appear in any theme block anymore. ### Change type - [x] `other` ### Test plan 1. Run `git diff --check`. 2. Confirm no removed `--tla-*` token reads remain in `apps/dotcom/client/src/tla` (every `var(--tla-color-*)` still read resolves to a definition in `tla.css`). 3. Confirm no undefined `--color-warn`, `--tl-color-hover`, or `--tla-shadow-primary-highlight` reads remain. 4. Run `yarn format-current` and `yarn lint-current`. 5. Run `yarn dev-app` and visually inspect the dotcom app shell, sidebar, dialogs, share menu, buttons, drag/drop zones, and admin page in both themes. Note: the collapsed-sidebar scrim now uses `--tl-color-overlay`, which is lighter than the old `--tla-color-overlay` in dark mode (50% vs 81% black). Worth confirming the dark-mode scrim still reads acceptably on a narrow viewport. - [ ] Unit tests - [ ] End to end tests ### Code changes | Section | LOC change | | ------- | ---------- | | Apps | +17 / -90 |
) In order to keep the CI/build runtime current with the [June 2026 Node.js security releases](https://nodejs.org/en/blog/vulnerability/june-2026-security-releases), this bumps the Node version used by the shared `setup` action from `24.13.1` to `24.17.0` — the patched 24.x release (dated 2026-06-17, flagged `security`) — and updates the two cache-key references that pin the version alongside it. Scope notes: - **Build/CI runtime only.** The published `engines` field is unaffected (that's a separate concern — see #9098, which sets it to the `require(esm)` feature floor). `engines` is advisory and isn't the right place to chase security patch levels. - **Not a fix for an exposure in tldraw.** The CVEs in this release are in Node's TLS/hostname-verification, HTTP/HTTP2/proxy, WebCrypto, and `--permission` subsystems. The SDK is browser code, tldraw.com's server side runs on Cloudflare workerd (not Node), and Node only runs at build/CI time here — so we don't believe tldraw is impacted. This is just keeping the build runtime patched. ### Change type - [x] `other` ### Test plan - CI runs green on Node 24.17.0. - [ ] Unit tests - [ ] End to end tests ### Code changes | Section | LOC change | | -------------- | ---------- | | Config/tooling | +3 / -3 |
## Problem After the pattern-tile cache (#9320), profiling a tldraw.com file open on the iOS Simulator showed the next-biggest cost was `findOrCreateFontFace` — ~385 ms, attributed to `next@native` iterating the document's `FontFaceSet`. Crucially this was on a *warm* open (the pattern `toBlob` was already ~0), so it's a per-mount cost, not first-load. Root cause: `findOrCreateFontFace` deduplicates font faces with an O(n) scan of `document.fonts` on every lookup. It runs for each font on every editor mount, and a fresh editor (e.g. switching documents on tldraw.com, which remounts the editor) gets a fresh `FontManager` with no memory of the previous one — so the scan re-runs every mount. The trace ruled out recreation: the `FontFace` constructor was ~11 ms, `load()` ~0 ms, and there were zero font-file network requests — faces are *reused*, just found via a slow scan. ## Fix Cache resolved font faces in a per-document `Map` (keyed by family + descriptors), shared across `FontManager` instances, so repeated lookups and remounts are O(1). On a cache miss the existing `document.fonts` scan still runs once, so faces added outside the manager (preloaded fonts) are still reused rather than duplicated. Keyed per document for cross-window embedding; faces are never removed from `document.fonts`, so the cache stays valid for the document's lifetime. ## Tests `FontManager.test.ts`: a fresh manager on the same document reuses the existing face instead of recreating it (the remount regression), and fonts with different descriptors get distinct faces. The cross-document cache has a test-only reset. All 22 tests pass; typecheck clean; no public-API change (the reset helper is `@internal` and not re-exported). ## Verification Re-trace a file open on the simulator: `findOrCreateFontFace`'s scan cost should be present on the first open and ~0 on subsequent opens. ## Context This is a sibling to #9320 (pattern-tile cache) — same symptom (per-mount cost on tldraw.com file switches), different root cause: patterns had the wrong lifetime (per-instance state); fonts had the wrong data structure (O(n) scan vs O(1) lookup).
…loy (#9327) In order to make deployed tldraw.com builds debuggable in browser devtools and stop the source-map 404s, this PR stops stripping `.js.map` files from the client deploy and serves them publicly. Closes #9322. The client build generated source maps, uploaded them to Sentry, then deleted the `.js.map` files from the deployed assets — while leaving the `//# sourceMappingURL` comments in the shipped JS. That produced a 404 for every map and left browser devtools unable to symbolicate deployed builds. The usual reason to hide source maps is to keep source private, which does not apply here since the client source is public in this repo. Sentry upload is unaffected: it reads from `dist/assets` before the strip step. ### Change type - [x] `bugfix` ### Test plan 1. From the preview deploy, open devtools → Network, reload, and confirm `*.js.map` requests return 200 rather than 404. 2. Open a minified stack frame in devtools and confirm it symbolicates to real names and lines. ### Code changes | Section | LOC change | | -------------- | ---------- | | Config/tooling | +7 / -3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )