Skip to content

Conversation

jpsantosbh
Copy link
Collaborator

Description

The usage of Brand Types was causing issues to use the SDK. Plus the solution only "renamed" the declared type, all other types used by the inner properties continue to have Room and Fabric references.

This PR replaces the Brand and Prettify types with Compute from the ts-toolbelt library, fixing the issue

Type of change

  • Internal refactoring
  • Bug fix (bugfix - non-breaking)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Code snippets

In case of new feature or breaking changes, please include code snippets.

jpsantosbh and others added 4 commits July 17, 2025 14:30
- Created typeUtils.ts with ShallowCompute utility for types that need flat computation
- Applied ShallowCompute to complex types with generics and function signatures
- Kept deep computation for simpler types
- Build now passes successfully without TypeScript errors

Types using ShallowCompute:
- EmitterContract and other contract types
- PaginatedResponse/Result generics
- Callback and handler types
- SignalWireClient and SignalWireContract

This approach prevents TypeScript from hitting complexity limits while
maintaining type safety through selective computation strategies.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

changeset-bot bot commented Jul 18, 2025

⚠️ No Changeset found

Latest commit: f113e96

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@jpsantosbh jpsantosbh marked this pull request as draft July 18, 2025 12:40
@jpsantosbh jpsantosbh requested a review from Copilot July 18, 2025 14:04
@jpsantosbh jpsantosbh marked this pull request as ready for review July 18, 2025 14:05
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes TypeScript type issues in the @signalwire/client SDK by replacing Brand and Prettify types with Compute from the ts-toolbelt library. The change resolves SDK usage issues while providing better type computation for complex generic types.

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/client/src/utils/typeUtils.ts Introduces new type utilities using ts-toolbelt's Compute with different computation depths
packages/client/src/utils/interfaces/fabric.ts Replaces Brand types with DeepCompute/ShallowCompute wrappers
packages/client/src/index.ts Refactors type exports from Prettify to Compute-based approach with aliased imports
packages/client/src/fabric/workers/fabricWorker.ts Updates worker types to use ShallowCompute and adds type assertions
packages/client/src/fabric/workers/callSegmentWorker.ts Adds type assertions for MapToPubSubShape compatibility
packages/client/snippets/CLIENT_SDK_OVERVIEW.md Adds comprehensive SDK documentation
packages/client/package.json Adds ts-toolbelt dependency

Comment on lines +93 to +101
action: action as unknown as MapToPubSubShape<
CallMemberJoinedEvent | CallMemberLeftEvent
>,
})
const videoAction =
mapFabricMemberActionToVideoMemberJoinAndLeftAction(action)
const videoAction = mapFabricMemberActionToVideoMemberJoinAndLeftAction(
// TS is complaining {[x: string]: {}} in assignable to Record<string, unknown>
action as unknown as MapToPubSubShape<
CallMemberJoinedEvent | CallMemberLeftEvent
>
Copy link
Preview

Copilot AI Jul 18, 2025

Choose a reason for hiding this comment

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

The type assertion with 'unknown' and the comment suggest a deeper type compatibility issue. Consider creating a proper type mapping function or updating the MapToPubSubShape type definition to handle these cases more elegantly.

Copilot uses AI. Check for mistakes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The problem is how Compute resolve Record<string, unknown> to {[x: string], {}}
{} is not equal to unknown, but is safe to cast {} to unknown

@@ -41,7 +41,8 @@
"dependencies": {
"@signalwire/core": "4.3.0",
"@signalwire/webrtc": "3.14.0",
"jwt-decode": "^3.1.2"
"jwt-decode": "^3.1.2",
"ts-toolbelt": "^9.6.0"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we please not do this? We always try not to install any packages on the SDK.

Also, even with this lib addition, I see in this PR copilot has highlighted issues with the TS usage. Maybe we need to stop adding these quick fixes and think hard and understand the root cause?

We can take @LittorWired's help as well and understand the TS problems that you have been facing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was from a @LittorWired suggestion already :-)
#1257 (comment)

Since we're heavily relying on Prettify/Compute on this SDK package, I agree that using a well-tested library is better in this case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If it solves one problem but causes two new ones, is it really worth it?

Also, the dependency should be a devDependency?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was trying to point out in that comment that Prettify/Compute might require a more well-battle-tested utility type if we really want to improve the DX without type "bugs".

Maybe the prettify/compute is not needed at the moment, but to be honest I don't yet fully understand the full context around the root of the issue. I gather it is around type aliases?

@@ -83,16 +89,25 @@ export const callSegmentWorker = function* (
case 'member.left': {
yield sagaEffects.fork(fabricMemberWorker, {
...options,
action,
// TS is complaining {[x: string]: {}} in assignable to Record<string, unknown>
Copy link
Collaborator

@iAmmar7 iAmmar7 Jul 21, 2025

Choose a reason for hiding this comment

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

We need to double-check these deeper type compatibility issues. It could happen anywhere in the SDK.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this markdown file supposed to be part of this PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes

Comment on lines 41 to +43
member: action.payload.room_session.members.find(
(m) => m.member_id === action.payload.member_id
)!,
)! as InternalCallMemberEntityUpdated,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the error be correctly handled if the member is not found?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe if (!cfRoomSession.selfMember) covers that already

Copy link
Contributor

Choose a reason for hiding this comment

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

If that is already covered is it possible then for a simple refactor to remove the ! as InternalCallMemberEntityUpdated type casting to make it safer?

@@ -41,7 +41,8 @@
"dependencies": {
"@signalwire/core": "4.3.0",
"@signalwire/webrtc": "3.14.0",
"jwt-decode": "^3.1.2"
"jwt-decode": "^3.1.2",
"ts-toolbelt": "^9.6.0"
Copy link
Contributor

Choose a reason for hiding this comment

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

Should ts-toolbelt be a dev dependency?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@LittorWired actually, it's imported in the code, so it's not just a dev dependency.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK thanks just wanted to double check

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.

3 participants