Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion common/config/rush/pnpm-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@
"playwright-core": "^1.55.1",
"glob@^10.0.0": "^10.5.0",
"node-forge": "^1.3.3",
"qs": "^6.14.1"
"qs": "^6.14.1",
"@griffel/core@1.21.1": "^1.21.2",
"@griffel/react@1.7.3": "^1.7.4"
},

/**
Expand Down
2,630 changes: 1,331 additions & 1,299 deletions common/config/rush/pnpm-lock.yaml

Large diffs are not rendered by default.

2,630 changes: 1,331 additions & 1,299 deletions common/config/rush/variants/stable/pnpm-lock.yaml

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions packages/acs-ui-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
"@azure/logger": "^1.0.4"
},
"peerDependencies": {
"react": ">=16.8.0 <19.0.0",
"@types/react": ">=16.8.0 <19.0.0"
"react": ">=16.8.0 <20.0.0",
"@types/react": ">=16.8.0 <20.0.0"
},
"devDependencies": {
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"copyfiles": "^2.4.1",
Expand All @@ -60,7 +60,7 @@
"globals": "~16.2.0",
"jest": "29.7.0",
"prettier": "3.5.3",
"react": "18.3.1",
"react": "19.2.6",
"rimraf": "^2.6.2",
"rollup": "^4.40.2",
"ts-jest": "^29.3.3",
Expand Down
22 changes: 22 additions & 0 deletions packages/acs-ui-common/src/react-jsx-global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// React 19's @types/react scopes the JSX namespace under `React.JSX` and no longer
// declares a global `JSX` namespace. This restores the global namespace so existing
// `JSX.Element` references throughout the codebase continue to resolve.
import 'react';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
type ElementType = React.JSX.ElementType;
type Element = React.JSX.Element;
type ElementClass = React.JSX.ElementClass;
type ElementAttributesProperty = React.JSX.ElementAttributesProperty;
type ElementChildrenAttribute = React.JSX.ElementChildrenAttribute;
type LibraryManagedAttributes<C, P> = React.JSX.LibraryManagedAttributes<C, P>;
type IntrinsicAttributes = React.JSX.IntrinsicAttributes;
type IntrinsicClassAttributes<T> = React.JSX.IntrinsicClassAttributes<T>;
type IntrinsicElements = React.JSX.IntrinsicElements;
}
}
16 changes: 9 additions & 7 deletions packages/acs-ui-javascript-loaders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,21 @@
"@azure/communication-common": "^2.3.2-beta.1 || ^2.4.0",
"@internal/acs-ui-common": "1.32.0-beta.1",
"@internal/react-composites": "1.32.0-beta.1",
"@fluentui/react": "^8.123.0",
"@fluentui/react": "^8.125.6",
"@azure/logger": "^1.0.4"
},
"peerDependencies": {
"react": ">=16.8.0 <19.0.0",
"@types/react": ">=16.8.0 <19.0.0",
"@types/react-dom": ">=16.8.0 <19.0.0",
"react-dom": ">=16.8.0 <19.0.0"
"react": ">=16.8.0 <20.0.0",
"@types/react": ">=16.8.0 <20.0.0",
"@types/react-dom": ">=16.8.0 <20.0.0",
"react-dom": ">=16.8.0 <20.0.0"
},
"devDependencies": {
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@types/react-dom": "19.2.3",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"copyfiles": "^2.4.1",
Expand All @@ -65,7 +66,8 @@
"if-env": "^1.0.4",
"jest": "29.7.0",
"prettier": "3.5.3",
"react": "18.3.1",
"react": "19.2.6",
"react-dom": "19.2.6",
"rimraf": "^2.6.2",
"rollup": "^4.40.2",
"ts-jest": "^29.3.3",
Expand Down
8 changes: 4 additions & 4 deletions packages/calling-component-bindings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@
"peerDependencies": {
"@azure/communication-calling-effects": "^1.3.2",
"@azure/communication-calling": "1.41.1-beta.1 || ^1.40.1",
"@types/react": ">=16.8.0 <19.0.0",
"react": ">=16.8.0 <19.0.0"
"@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0"
},
"devDependencies": {
"@azure/communication-calling": "1.41.1-beta.1 || ^1.40.1",
"@azure/communication-calling-effects": "^1.3.2",
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"copyfiles": "^2.4.1",
Expand All @@ -66,7 +66,7 @@
"jest": "29.7.0",
"jiti": "~2.4.2",
"prettier": "3.5.3",
"react": "18.3.1",
"react": "19.2.6",
"rimraf": "^2.6.2",
"rollup": "^4.40.2",
"ts-jest": "^29.3.3",
Expand Down
22 changes: 22 additions & 0 deletions packages/calling-component-bindings/src/react-jsx-global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// React 19's @types/react scopes the JSX namespace under `React.JSX` and no longer
// declares a global `JSX` namespace. This restores the global namespace so existing
// `JSX.Element` references throughout the codebase continue to resolve.
import 'react';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
type ElementType = React.JSX.ElementType;
type Element = React.JSX.Element;
type ElementClass = React.JSX.ElementClass;
type ElementAttributesProperty = React.JSX.ElementAttributesProperty;
type ElementChildrenAttribute = React.JSX.ElementChildrenAttribute;
type LibraryManagedAttributes<C, P> = React.JSX.LibraryManagedAttributes<C, P>;
type IntrinsicAttributes = React.JSX.IntrinsicAttributes;
type IntrinsicClassAttributes<T> = React.JSX.IntrinsicClassAttributes<T>;
type IntrinsicElements = React.JSX.IntrinsicElements;
}
}
2 changes: 1 addition & 1 deletion packages/calling-stateful-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"copyfiles": "^2.4.1",
Expand Down
47 changes: 47 additions & 0 deletions packages/calling-stateful-client/src/DeviceManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,53 @@ describe('errors should be reported correctly from DeviceManger when', () => {
});
});

describe('device manager isSpeakerSelectionAvailable error handling', () => {
let consoleWarnSpy: jest.SpyInstance;

beforeEach(() => {
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined);
});

afterEach(() => {
consoleWarnSpy.mockRestore();
});

test('returns false through the proxy when the SDK getter throws', async () => {
const base = createMockDeviceManagerWithMicrophones([microphoneWithName('mic')]);
const manager = { ...base } as MockDeviceManager;
Object.defineProperty(manager, 'isSpeakerSelectionAvailable', {
get(): boolean {
throw new Error('injected SDK error');
}
});
const client = createStatefulCallClientWithDeviceManager(manager);
const proxied = await client.getDeviceManager();

expect(proxied.isSpeakerSelectionAvailable).toBe(false);
expect(consoleWarnSpy).toHaveBeenCalled();
});

test('audioDevicesUpdated does not throw when the SDK getter throws', async () => {
const base = createMockDeviceManagerWithSpeakers([speakerWithName('speaker')]);
const manager = {
...base,
async getMicrophones(): Promise<AudioDeviceInfo[]> {
return [];
}
} as MockDeviceManager;
Object.defineProperty(manager, 'isSpeakerSelectionAvailable', {
get(): boolean {
throw new Error('injected SDK error');
}
});
const client = createStatefulCallClientWithDeviceManager(manager);
await client.getDeviceManager();

expect(() => manager.emit('audioDevicesUpdated', {})).not.toThrow();
expect(await waitWithBreakCondition(() => consoleWarnSpy.mock.calls.length > 0)).toBe(true);
});
});

const createStatefulCallClientWithDeviceManager = (deviceManager: MockDeviceManager): StatefulCallClient => {
const agent = createMockCallAgent('defaultDisplayName');
return createStatefulCallClientWithDeps(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,15 @@ class ProxyDeviceManager implements ProxyHandler<DeviceManager> {
// isSpeakerSelectionAvailable, selectedMicrophone, and selectedSpeaker are properties on DeviceManager. Since they
// are not functions we can't proxy them so we'll update whenever we think they may need updating such as at
// construction time or when certain events happen.
this._context.setDeviceManagerIsSpeakerSelectionAvailable(this._deviceManager.isSpeakerSelectionAvailable);
// The isSpeakerSelectionAvailable getter can throw a CallingCommunicationError when the device manager is not
// yet ready (e.g. during a Permissions API change event). Default to false in that case.
let isSpeakerSelectionAvailable = false;
try {
isSpeakerSelectionAvailable = this._deviceManager.isSpeakerSelectionAvailable;
} catch (e) {
console.warn('DeviceManager.isSpeakerSelectionAvailable threw an error', e);
}
this._context.setDeviceManagerIsSpeakerSelectionAvailable(isSpeakerSelectionAvailable);
this._context.setDeviceManagerSelectedMicrophone(this._deviceManager.selectedMicrophone);
this._context.setDeviceManagerSelectedSpeaker(this._deviceManager.selectedSpeaker);
};
Expand Down Expand Up @@ -149,7 +157,13 @@ class ProxyDeviceManager implements ProxyHandler<DeviceManager> {

private audioDevicesUpdated = async (): Promise<void> => {
this._context.setDeviceManagerMicrophones(dedupeById(await this._deviceManager.getMicrophones()));
if (this._deviceManager.isSpeakerSelectionAvailable) {
let isSpeakerSelectionAvailable = false;
try {
isSpeakerSelectionAvailable = this._deviceManager.isSpeakerSelectionAvailable;
} catch (e) {
console.warn('DeviceManager.isSpeakerSelectionAvailable threw an error', e);
}
if (isSpeakerSelectionAvailable) {
this._context.setDeviceManagerSpeakers(dedupeById(await this._deviceManager.getSpeakers()));
}
};
Expand Down Expand Up @@ -257,6 +271,16 @@ class ProxyDeviceManager implements ProxyHandler<DeviceManager> {
'DeviceManager.askDevicePermission'
);
}
case 'isSpeakerSelectionAvailable': {
// The SDK's isSpeakerSelectionAvailable getter can throw a CallingCommunicationError when the device manager
// is not yet ready. Default to false in that case so consumers never see an unhandled exception.
try {
return target.isSpeakerSelectionAvailable;
} catch (e) {
console.warn('DeviceManager.isSpeakerSelectionAvailable threw an error', e);
return false;
}
}
default:
return Reflect.get(target, prop);
}
Expand Down
8 changes: 4 additions & 4 deletions packages/chat-component-bindings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@
},
"peerDependencies": {
"@azure/communication-chat": "1.6.0-beta.7 || >=1.6.0",
"@types/react": ">=16.8.0 <19.0.0",
"react": ">=16.8.0 <19.0.0"
"@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0"
},
"devDependencies": {
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@testing-library/react": "^16.3.0",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@types/uuid": "^9.0.8",
"copyfiles": "^2.4.1",
"cpy-cli": "^5.0.0",
Expand All @@ -62,7 +62,7 @@
"if-env": "^1.0.4",
"jest": "29.7.0",
"prettier": "3.5.3",
"react": "18.3.1",
"react": "19.2.6",
"rimraf": "^2.6.2",
"rollup": "^4.40.2",
"typescript": "5.4.5",
Expand Down
22 changes: 22 additions & 0 deletions packages/chat-component-bindings/src/react-jsx-global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// React 19's @types/react scopes the JSX namespace under `React.JSX` and no longer
// declares a global `JSX` namespace. This restores the global namespace so existing
// `JSX.Element` references throughout the codebase continue to resolve.
import 'react';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
type ElementType = React.JSX.ElementType;
type Element = React.JSX.Element;
type ElementClass = React.JSX.ElementClass;
type ElementAttributesProperty = React.JSX.ElementAttributesProperty;
type ElementChildrenAttribute = React.JSX.ElementChildrenAttribute;
type LibraryManagedAttributes<C, P> = React.JSX.LibraryManagedAttributes<C, P>;
type IntrinsicAttributes = React.JSX.IntrinsicAttributes;
type IntrinsicClassAttributes<T> = React.JSX.IntrinsicClassAttributes<T>;
type IntrinsicElements = React.JSX.IntrinsicElements;
}
}
2 changes: 1 addition & 1 deletion packages/chat-stateful-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@types/jest": "^29.5.14",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"@types/node": "^22.15.18",
Expand Down
32 changes: 16 additions & 16 deletions packages/communication-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
"@azure/communication-common": "^2.3.2-beta.1 || ^2.4.0",
"@azure/core-paging": "^1.5.0",
"@azure/logger": "^1.0.4",
"@fluentui/react-components": "9.62.0",
"@fluentui/react": "^8.123.0",
"@fluentui/react-file-type-icons": "8.13.2",
"@fluentui/react-hooks": "^8.8.18",
"@fluentui/react-icons": "^2.0.302",
"@fluentui/react-window-provider": "^2.2.30",
"@fluentui-contrib/react-chat": "0.1.11",
"@fluentui/react-components": "9.73.8",
"@fluentui/react": "^8.125.6",
"@fluentui/react-file-type-icons": "8.18.0",
"@fluentui/react-hooks": "^8.10.2",
"@fluentui/react-icons": "^2.0.327",
"@fluentui/react-window-provider": "^2.3.2",
"@fluentui-contrib/react-chat": "0.2.2",
"@griffel/react": "^1.5.30",
"@types/events": "^3.0.3",
"copy-to-clipboard": "^3.3.1",
Expand All @@ -58,10 +58,10 @@
"@azure/communication-calling-effects": "^1.3.2",
"@azure/communication-calling": "1.41.1-beta.1 || ^1.40.1",
"@azure/communication-chat": "1.6.0-beta.7 || >=1.6.0",
"@types/react": ">=16.8.0 <19.0.0",
"@types/react-dom": ">=16.8.0 <19.0.0",
"react": ">=16.8.0 <19.0.0",
"react-dom": ">=16.8.0 <19.0.0"
"@types/react": ">=16.8.0 <20.0.0",
"@types/react-dom": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0",
"react-dom": ">=16.8.0 <20.0.0"
},
"main": "./dist/dist-cjs/communication-react/index.js",
"module": "./dist/dist-esm/communication-react/src/index.js",
Expand Down Expand Up @@ -133,9 +133,9 @@
"@types/jest": "^29.5.14",
"@types/json-stringify-safe": "^5.0.3",
"@types/node": "^22.15.18",
"@types/react-dom": "18.3.1",
"@types/react-dom": "19.2.3",
"@types/react-linkify": "^1.0.4",
"@types/react": "18.3.12",
"@types/react": "19.2.15",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
Expand All @@ -157,9 +157,9 @@
"node-forge": ">=1.3.3",
"prettier": "3.5.3",
"pretty-quick": "^4.2.2",
"react-dom": "18.3.1",
"react-is": "^18.3.1",
"react": "18.3.1",
"react-dom": "19.2.6",
"react-is": "^19.2.6",
"react": "19.2.6",
"regenerator-runtime": "^0.14.0",
"renamer": "^4.0.0",
"rimraf": "^2.6.2",
Expand Down
Loading