Skip to content

bump to 2.2.6 and variable support - #49

Merged
diegopeixoto merged 4 commits into
mainfrom
bump-2.2.6
Jul 9, 2026
Merged

diegopeixoto merged 4 commits into
mainfrom
bump-2.2.6

Conversation

@GeorgeHastings

@GeorgeHastings GeorgeHastings commented Jul 8, 2026 •

Copy link
Copy Markdown
Collaborator

Gave this one to Fable:

What the integration looks like

Three new declarative props, available on both the React and Next.js components:

<UnicornScene
  projectId="YOUR_PROJECT_EMBED_ID"
  preset="Dark Theme"
  variables={{ brandColor: "#7c3aed", intensity: 0.65 }}
  onVariableChange={(name, value, values) => console.log(name, value)}
/>

The design deliberately mirrors the existing paused prop pattern rather than inventing anything new:

  • variables is passed as initialVariables when the scene is created (so there's no flash of authored defaults), then synced via scene.setVariables() whenever the values change — the scene is never re-initialized for a value change. Since users will typically pass inline object literals, the sync effect keys off a serialized snapshot of the values, so a new object with identical values doesn't trigger a redundant setVariables() call.
  • preset works the same way: initialPreset on creation, scene.setPreset() on change. It accepts an ID or a name (I verified the SDK resolves both).
  • onVariableChange subscribes through scene.onVariableChange() after init and unsubscribes on destroy. It's held in a ref like onLoad/onError, so a new callback identity never re-initializes the scene.

For everything beyond that (GSAP-driven variables, building control panels from the manifest, direct layer control), the existing sceneRef prop is now the typed escape hatch — UnicornStudioScene gained the full 2.2 runtime surface: setVariable, getVariableManifest, getPresets, setProp, setTexture, getLayers, getLayer, getMouse, etc. All new methods are optional on the interface so a custom sdkUrl pointing at an older SDK degrades gracefully instead of throwing.

Summary by CodeRabbit

  • New Features

    • Added declarative scene variables and preset support, including initial application, live syncing, and onVariableChange callbacks.
    • Expanded the scene API with typed variable/preset getters/setters and additional runtime access.
    • Exported additional TypeScript types for variables, presets, manifests, and Vec2/Vec3.
  • Documentation

    • Updated README usage and prop references with variables/presets behavior and examples.
  • Tests

    • Added coverage for synchronization, pending initialization, and safe behavior when variable APIs are unavailable.
  • Chores

    • Released version 2.2.6 (including SDK update).

@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@diegopeixoto, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7dcd8023-60a2-40c6-975f-a718a90cd93c

📥 Commits

Reviewing files that changed from the base of the PR and between 777bb38 and b938152.

📒 Files selected for processing (1)
  • src/shared/hooks.ts
📝 Walkthrough

Walkthrough

This PR adds declarative scene variables and preset support to unicornstudio-react. It expands public types, updates useUnicornScene to sync scene state and variable-change callbacks, forwards the new props through React and Next entry points, and updates tests, docs, changelog, and version numbers.

Changes

Variables and Presets Feature

Layer / File(s) Summary
Variable/preset type contracts
src/shared/types.ts
Adds exported types for variable values, definitions, manifests, presets, layers, callback signature, and extends UnicornSceneProps, UnicornStudioScene, and UnicornSceneConfig.
useUnicornScene variable/preset synchronization
src/shared/hooks.ts
useUnicornScene gains variables/preset/onVariableChange params, applies initialVariables/initialPreset on load, subscribes to variable changes, syncs updates via setVariables/setPreset, and unsubscribes on teardown.
React/Next component and export wiring
src/react/index.tsx, src/next/index.tsx, src/index.tsx
UnicornScene components forward new props to the hook; type re-exports expand across entry points to include the new variable/preset types.
Hook variable/preset tests
src/__tests__/useUnicornScene.test.ts
New tests validate initial config forwarding, update synchronization, change subscription/unsubscription, pending-creation reconciliation, and graceful handling when the scene lacks the variables API.
Docs, changelog, and version bump
README.md, CHANGELOG.md, package.json, src/shared/constants.ts
Adds a "Variables and Presets" README section and props table entries, a 2.2.6 changelog entry, and bumps the package and SDK version to 2.2.6.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Component
  participant useUnicornScene
  participant Scene
  Component->>useUnicornScene: pass variables, preset, onVariableChange
  useUnicornScene->>Scene: addScene(initialVariables, initialPreset)
  Scene-->>useUnicornScene: onVariableChange unsubscribe
  Component->>useUnicornScene: update variables or preset
  useUnicornScene->>Scene: setVariables() / setPreset()
  Scene-->>useUnicornScene: variable change event
  useUnicornScene-->>Component: onVariableChange callback
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: diegopeixoto

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main changes: version bump to 2.2.6 and added variable support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bump-2.2.6

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/__tests__/useUnicornScene.test.ts (1)

470-493: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider asserting no re-initialization in the graceful-handling test.

The test verifies that rerendering with new variables/preset/onVariableChange doesn't throw when the scene lacks the variables API, but it doesn't verify that addSceneMock was called only once. Adding this assertion would confirm the hook correctly avoids scene re-creation in this edge case, matching the pattern used in the other sync tests.

🧪 Suggested addition
     await act(async () => {});
 
+    expect(addSceneMock).toHaveBeenCalledTimes(1);
+
     expect(() => {
       rerender({
         ...defaultProps(elementRef),
         variables: { intensity: 0.9 },
         preset: "Light Theme",
         onVariableChange: vi.fn(),
       });
     }).not.toThrow();
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/useUnicornScene.test.ts` around lines 470 - 493, In the
“handles scenes without the variables API gracefully” test, also assert that the
scene is not re-initialized on rerender. After the existing no-throw check in
useUnicornScene, verify addSceneMock was called only once so the hook’s graceful
path still avoids recreating the scene when variables/preset/onVariableChange
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 334-336: The README table entry for the `variables` prop uses a
placeholder type and should be updated to the exported public type. Replace the
`Record<string, value>` description with `UnicornVariables` in the documentation
section that lists `variables`, `preset`, and `onVariableChange`, so it matches
the actual API surface.

In `@src/shared/hooks.ts`:
- Around line 405-406: The sync path for `variables` and `preset` can fire
before `internalSceneRef.current` is ready during `addScene()`, so the latest
values are never applied to the newly created scene. Update the logic around the
`variablesRef`/`presetRef` sync effects in `hooks.ts` so they re-run or replay
once `internalSceneRef.current` becomes available after async scene creation,
ensuring the final scene gets the latest `variables` and `preset` instead of
stale initial values.

---

Nitpick comments:
In `@src/__tests__/useUnicornScene.test.ts`:
- Around line 470-493: In the “handles scenes without the variables API
gracefully” test, also assert that the scene is not re-initialized on rerender.
After the existing no-throw check in useUnicornScene, verify addSceneMock was
called only once so the hook’s graceful path still avoids recreating the scene
when variables/preset/onVariableChange change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 571d301f-61ef-4ed1-accb-bc083fa10168

📥 Commits

Reviewing files that changed from the base of the PR and between 9805dde and 1a77b4e.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • README.md
  • package.json
  • src/__tests__/useUnicornScene.test.ts
  • src/index.tsx
  • src/next/index.tsx
  • src/react/index.tsx
  • src/shared/constants.ts
  • src/shared/hooks.ts
  • src/shared/sdk-bundle.ts
  • src/shared/types.ts
  • vendor/unicornstudio/unicornStudio.umd.js

Comment thread README.md Outdated
Comment thread src/shared/hooks.ts Outdated
buildSceneConfig snapshots variablesRef/presetRef before awaiting
addScene(). If either prop changed while creation was in flight, the
sync effects ran against a still-null scene ref and no-op'd, leaving
the scene with stale initial values and no replay.

Capture what the scene was created with, then apply any drift once
addScene() resolves.

Also sync package-lock version to 2.2.6 and correct the README
variables type to the exported UnicornVariables.
Conflicts were version-only:
- package.json / package-lock.json: keep 2.2.6
- src/shared/sdk-bundle.ts: generated file, regenerated from vendor/

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/__tests__/useUnicornScene.test.ts (1)

470-504: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider asserting exact call counts for the replay path.

The test correctly verifies that changed variables/preset are replayed via setVariables/setPreset after pending scene creation resolves. However, toHaveBeenCalledWith only checks that the function was called with the given args at least once — it would still pass if the sync effects also fired and double-called these methods. Adding toHaveBeenCalledTimes(1) would lock down the replay path and catch potential double-call regressions.

🧪 Suggested additions
     expect(setVariables).toHaveBeenCalledWith({ intensity: 0.9 });
     expect(setPreset).toHaveBeenCalledWith("Light Theme");
+    expect(setVariables).toHaveBeenCalledTimes(1);
+    expect(setPreset).toHaveBeenCalledTimes(1);
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/useUnicornScene.test.ts` around lines 470 - 504, The
replay-path test in useUnicornScene is only checking arguments, so it could
still pass if setVariables or setPreset are called multiple times by both the
replay logic and the normal sync effects. Update the assertion block in this
test to also verify exact call counts for setVariables and setPreset, keeping
the focus on the pending addScene resolution path and guarding against
double-call regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/__tests__/useUnicornScene.test.ts`:
- Around line 470-504: The replay-path test in useUnicornScene is only checking
arguments, so it could still pass if setVariables or setPreset are called
multiple times by both the replay logic and the normal sync effects. Update the
assertion block in this test to also verify exact call counts for setVariables
and setPreset, keeping the focus on the pending addScene resolution path and
guarding against double-call regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ee83063c-1c18-482d-ac6e-50a4a1c4cb50

📥 Commits

Reviewing files that changed from the base of the PR and between 1a77b4e and 777bb38.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • README.md
  • src/__tests__/useUnicornScene.test.ts
  • src/shared/constants.ts
  • src/shared/hooks.ts
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/shared/constants.ts
  • src/shared/hooks.ts

The replay branches pushed initializeScene's cognitive complexity to 21,
over the 15 allowed. Move the snapshot and the replay into helpers.

No behavior change.
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@diegopeixoto
diegopeixoto merged commit 587e692 into main Jul 9, 2026
4 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