Server-side render fails with "requestAnimationFrame is not defined" when the room has a video node
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 79/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- node.js, typescript
Research direction
Start with code/packages/sdk/src/stores/store.ts and the tests in code/packages/sdk/src/stores/__tests__/store.setup.test.ts; trace the afterTransaction handler and how it schedules renders. Check how brush-tool.ts handles environments without requestAnimationFrame, then add coverage for both a post-load transaction and a state write during setupRenderer(). Done when both cases avoid the error and the fallback schedules one render.
Written by the indexing model from the issue text.
Description
Describe the bug
On the server, weave.start() rejects with ReferenceError: requestAnimationFrame is not defined when the room contains a video node, so server-side exports (image, PDF) of that room fail. Found in the weavejs-backend export jobs.
Two pieces of code combine:
WeaveStore.setup()(code/packages/sdk/src/stores/store.ts) handles everyafterTransactionafter the first load by scheduling the state events andinstance.render()withrequestAnimationFrame. That global does not exist in Node.js.WeaveVideoNode.onRender()(code/packages/sdk/src/nodes/video/video.ts) callsthis.instance.updateNode(...)whenisServer(), so it writes state during the initial render.
That write starts a second Yjs transaction inside the store's first-load afterTransaction handler. Yjs runs the afterTransaction of the second transaction once the handler has returned, when isRoomLoaded is already true, so the store calls requestAnimationFrame and throws.
Any state change on the server after the room has loaded goes through the same call. The video node is the one that makes it happen during the load.
Steps to reproduce
- On the server, call
await setupSkiaBackend(). - Create a
Weaveinstance withWeaveStoreStandalone,WeaveKonvaBaseRendererandWeaveVideoNode, with room data that has a video node inmainLayer. await weave.start()rejects:
ReferenceError: requestAnimationFrame is not defined
at node_modules/@inditextech/weave-sdk/dist/sdk.js:1512:35
at node_modules/lib0/observable.js:82:90
at Array.forEach (<anonymous>)
at Doc.emit (node_modules/lib0/observable.js:82:77)
at Array.<anonymous> (node_modules/yjs/dist/yjs.mjs:3297:25)
at callAll (node_modules/lib0/function.js:20:12)
at cleanupTransactions (node_modules/yjs/dist/yjs.mjs:3298:7)
at cleanupTransactions (node_modules/yjs/dist/yjs.mjs:3376:9)
at transact (node_modules/yjs/dist/yjs.mjs:3424:9)
at readUpdateV2 (node_modules/yjs/dist/yjs.mjs:1652:3)
The second transaction is started from:
Weave.updateNode
WeaveVideoNode.onRender
createInstance (renderer-konva-base)
WeaveKonvaBaseRenderer.buildSubtree
WeaveKonvaBaseRenderer.render
Weave.setupRenderer
WeaveStore afterTransaction handler (first load)
The same room without the video node loads and renders fine.
Expected behavior
The store works without requestAnimationFrame. Where it is not available, it defers with setTimeout(cb, 0) and still coalesces the updates into one render. brush-tool.ts already checks for requestAnimationFrame before using it.
Tests to add in code/packages/sdk/src/stores/__tests__/store.setup.test.ts:
- Without
requestAnimationFrame, a transaction after the first load does not throw, andrender()runs once the timer fires. - A state write during
setupRenderer()(the video case) does not throw.
Environment
- Seen with
@inditextech/weave-sdk5.9.0-SNAPSHOT; the same code is in 5.8.0 and currentmain. TherequestAnimationFramebatching was added in 5.0.0 (#1093). - Node.js 24, worker threads, Skia backend,
WeaveStoreStandalone.
Additional context
- The trace points to
dist/sdk.js(browser build) because@inditextech/weave-store-standalone/serverimportsWeaveStorefrom@inditextech/weave-sdkinstead of@inditextech/weave-sdk/server. Both builds have the same store code, so it is not the cause, but a server app ends up loading both builds. - Open question: whether
WeaveVideoNodeshould write state fromonRender()on the server at all.
- Dominant language
- TypeScript
- Stars
- 276
- Forks
- 26
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 47
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing 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.
More from InditexTech/weavejs
-
internal
Difficulty 4/5 3-5 days Newbie friendliness 35/100
InditexTech/weavejs#1258 ·
Maintainers usually reply within 1 day
-
Generated create-weave-*-app projects do not install, build or run without manual fixesPossibly taken @txnioh claimed this 9 days ago. Openbug
Difficulty 4/5 3-5 days Newbie friendliness 45/100
InditexTech/weavejs#1257 ·
Maintainers usually reply within 1 day
-
Add sticky note canvas primitive and interactive placement toolPossibly taken @jmcaamanog claimed this 21 days ago. Openenhancement
Difficulty 4/5 3-5 days Newbie friendliness 58/100
InditexTech/weavejs#1232 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 5/5 Over a week Newbie friendliness 35/100
InditexTech/weavejs#1217 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 48/100
InditexTech/weavejs#1163 ·
Maintainers usually reply within 1 day
All issues in InditexTech/weavejs
Similar issues
-
Difficulty 1/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
jupyterlite/jupyterlite#2111 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
karlhorky/electron-app-patcher#241 ·
Maintainers usually reply within 1 day
-
Tab bar scrolls past its last tab in Firefox until no tabs are visiblePossibly taken @daviwil claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
eclipse-theia/theia#18367 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day