Skip to content

Conversation

@venky-mediboina
Copy link
Contributor

@venky-mediboina venky-mediboina commented May 28, 2025

COMPLETES #SPARK-610518

This pull request addresses

Saving the subnet ip details and sending to web-client

by making the following changes

Saved the subnet ip details in reachability results and sending to web-client

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

Tested manually whether we are getting the subnets in the response or not in webex-web-client.

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Please Specify
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

I certified that

  • I have read and followed contributing guidelines
  • I discussed changes with code owners prior to submitting this pull request
  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the documentation accordingly

Make sure to have followed the contributing guidelines before submitting.

@venky-mediboina venky-mediboina requested review from a team as code owners May 28, 2025 13:49
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 28, 2025

📝 Walkthrough

Walkthrough

This change modifies the subnet reachability tracking in the ClusterReachability class by changing the reachedSubnets property from a set of strings to a set of objects containing protocol, server IP, reachability status, latency, transmission statistics, and an optional port. The constructor initializes cluster information and minimum latency tracking per protocol. The saveResult method is updated to accept an optional port parameter and to add or update detailed subnet objects, preventing duplicates based on server IP, protocol, and port. ICE candidate listeners extract and pass port information to saveResult. The start method prepopulates reachedSubnets with all cluster subnets for UDP, TCP, and XTLS protocols. A new private method updateMinLatency computes minimum latency per protocol. The isSubnetReachable method and reachability results processing are updated to handle the new subnet object structure, enriching results with protocol-specific subnet details.

Possibly related PRs

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.38.1)
packages/@webex/plugin-meetings/test/unit/spec/locus-info/index.js
🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

yarn install v1.22.22
[1/4] Resolving packages...
(node:19808) [DEP0169] DeprecationWarning: url.parse() behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for url.parse() vulnerabilities.
(Use node --trace-deprecation ... to show where the warning was created)
warning [email protected]: This version is no longer supported. Please see https://eslint.org/version-support for other options.
warning eslint > @humanwhocodes/[email protected]: Use @eslint/config-array instead
warning eslint > @humanwhocodes/config-array > @humanwhocodes/[email protected]: Use @eslint/object-schema instead
warning eslint > file-entry-cache > flat-cache > [email protected]: Rimraf versions prior to v4 are no longer supported
warning eslint > file-entry-cache > flat-cache > rimraf > [email protected]: Glob versions prior to v9 are no longer supported
warning eslint > file-entry-cache > flat-cache > rimraf > glob > [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning eslint-import-resolver-typescript > [email protected]: Glob versions prior to v9 are no longer supported
warning [email protected]: Glob versions prior to v9 are no longer supported
warning intern > [email protected]: Glob versions prior to v9 are no longer supported
warning intern > glob > [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning jasmine > [email protected]: Glob versions prior to v9 are no longer supported
warning jest > @jest/core > jest-config > [email protected]: Glob versions prior to v9 are no longer supported
warning jest > @jest/core > @jest/reporters > [email protected]: Glob versions prior to v9 are no longer supported
warning jest > @jest/core > jest-runtime > [email protected]: Glob versions prior to v9 are no longer supported
warning jest > @jest/core > @jest/transform > babel-plugin-istanbul > test-exclude > [email protected]: Glob versions prior to v9 are no longer supported
warning mocha > [email protected]: Glob versions prior to v9 are no longer supported
warning mocha > glob > [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning [email protected]: 16.1.1
warning sinon > @sinonjs/samsam > [email protected]: This package is deprecated. Use the optional chaining (?.) operator instead.
warning wd > [email protected]: request has been deprecated, see request/request#3142
warning wd > [email protected]: You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.

(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
warning wd > archiver > [email protected]: Glob versions prior to v9 are no longer supported
warning wd > request > [email protected]: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
warning wd > archiver > archiver-utils > [email protected]: Glob versions prior to v9 are no longer supported
warning wd > request > [email protected]: this library is no longer supported
warning @babel/cli > [email protected]: Glob versions prior to v9 are no longer supported
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
warning @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
warning @babel/[email protected]: 🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.
warning @babel/polyfill > [email protected]: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning @babel/runtime-corejs2 > [email protected]: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning babel-plugin-lodash > [email protected]: Glob versions prior to v9 are no longer supported
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > [email protected]: This version is no longer supported. Please see https://eslint.org/version-support for other options.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > [email protected]: Glob versions prior to v9 are no longer supported
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > [email protected]: 16.1.1
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
warning workspace-aggregator-73e9ad79-9b85-456d-ba12-c9440adf61b1 > @babel/[email protected]: 🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.
[2/4] Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version "^14 || ^16 || ^17 || ^18 || ^19". Got "24.2.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
packages/@webex/plugin-meetings/src/reachability/index.ts (1)

166-179: ⚠️ Potential issue

Fix logging of subnet objects to avoid "[object Object]" output.

The subnet is now an object, but line 174 still logs it directly which will result in "[object Object]" being displayed. Consider logging the subnet details properly.

Apply this diff to fix the logging:

-          logMessage += `${subnet}`;
+          logMessage += `${subnet.serverIp}:${subnet.port || 'default'} (${subnet.protocol})`;
🧹 Nitpick comments (3)
packages/@webex/plugin-meetings/src/reachability/index.ts (1)

463-489: Consider simplifying the null-safe access pattern.

The current implementation correctly handles undefined clusterReachability, but the code could be more concise.

Apply this diff for a cleaner implementation:

-        const clusterReachability = this.clusterReachability[clusterKey];
-        const subnets = clusterReachability
-          ? Array.from(clusterReachability.reachedSubnets || [])
-          : [];
+        const subnets = Array.from(
+          this.clusterReachability[clusterKey]?.reachedSubnets || []
+        );
packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (2)

52-58: Consider removing the redundant reachable field or making it a boolean.

The reachable field is always set to 'true' (as a string) in the code. Since items are only added to reachedSubnets when they are reachable, this field appears redundant.

Either remove the field entirely:

  public readonly reachedSubnets: Set<{
    protocol: string;
    serverIp: string;
-   reachable: string;
    latency: number;
    port?: number;
  }> = new Set();

Or make it a boolean for type safety:

  public readonly reachedSubnets: Set<{
    protocol: string;
    serverIp: string;
-   reachable: string;
+   reachable: boolean;
    latency: number;
    port?: number;
  }> = new Set();

300-315: Good implementation of duplicate prevention!

The duplicate checking logic correctly prevents adding multiple entries with the same serverIp, protocol, and port combination.

Consider renaming the latency field to latencyInMilliseconds for consistency with the rest of the codebase.

        this.reachedSubnets.add({
          protocol,
          serverIp,
          reachable: 'true',
-         latency,
+         latencyInMilliseconds: latency,
          port,
        });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09a0bf6 and 9c51785.

📒 Files selected for processing (2)
  • packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (4 hunks)
  • packages/@webex/plugin-meetings/src/reachability/index.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: AWS Amplify Console Web Preview

@aws-amplify-us-east-2
Copy link

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-4300.d3m3l2kee0btzx.amplifyapp.com

Copy link
Collaborator

@marcin-bazyl marcin-bazyl left a comment

Choose a reason for hiding this comment

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

This is not the right approach, we should be storing the reached server IP and port in reachability results that we store in boundedStorage as REACHABILITY.localStorageResult and make sure that getReachabilityResults() returns them in the format as described on Orpheus wiki. We will need to also take into account that server IPs might be IPV6.

public readonly reachedSubnets: Set<{
protocol: string;
serverIp: string;
reachable: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need reachable here? the name of this set is reachedSubnets so they're all always reachable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is subnet level reachability result. There might be chance in the cluster, one subnet fails and other(s) success. This reachedSubnets is list of all subnets in the cluster. Subnet level details include individual subnet IP(serverIp), its result, time for this subnet, etc.

protocol: string;
serverIp: string;
reachable: string;
latency: number;
Copy link
Collaborator

Choose a reason for hiding this comment

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

latency is already stored in reachability results, why do we need it here?

if (serverIp) {
this.reachedSubnets.add(serverIp);
// Checking if the serverIp and port combination already exists in the reachedSubnets
const isDuplicate = Array.from(this.reachedSubnets).some(
Copy link
Collaborator

Choose a reason for hiding this comment

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

this feels wrong... we have reachedSubnets defined as a Set so that it's fast and efficient to look up entries in it and check for duplicates, converting it to an array to search for entries doesn't feel right.... I guess you've done this because you only want to check the ip, port and protocol and not latency, best I see no reason why we have latency in this set in the first place...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This Latency is for individual subnet. And I'll try to avoid using array as Rabbit scan suggesting, I'll use Map.

results = mapValues(allClusterResults, (clusterResult, clusterKey) => {
const clusterReachability = this.clusterReachability[clusterKey];
const subnets = clusterReachability
? Array.from(clusterReachability.reachedSubnets || [])
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is not ideal, because reachability results are stored in localStorage, but reachedSubnets is not, so in theory we might want to use getReachabilityResults() without doing reachability and relying on the results from localStorage. We should be storing the reached server ips/ports in reachability results themselves, not using the ones from allClusterResults[..].reachedSubnets - Kacper added them there because he only needed it for sending the metric at the end of reachability, but you guys need to send this to Orpheus together with reachabiltiy results, so it needs to be stored with reachability results.

Also, the returned data from getReachabilityResults() doesn't match now what it was supposed to match - described in this wiki and once you make it match, you need to update the ReachabilityResultsForBackend type definition too.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 22

🔭 Outside diff range comments (1)
packages/@webex/plugin-meetings/src/locus-info/index.ts (1)

366-370: ⚠️ Potential issue

Fix potential null reference and clarify self parameter handling.

There are two issues in this code segment:

  1. The method signature shows self: any as a required parameter, but lines 367-368 have a conditional check if (self && !isEqual(this.self, self)), suggesting self could be null/undefined. If self can be null, update the signature to self?: any.

  2. Line 370 uses this.self as the previous state reference instead of this.parsedLocus.self. This could cause issues if this.self is not properly initialized or synchronized. Consider using this.parsedLocus.self for consistency with other parts of the codebase.

-  updateSelf(self: any, participants: Array<any>) {
+  updateSelf(self?: any, participants: Array<any>) {
     // @ts-ignore - check where this.self come from
     if (self && !isEqual(this.self, self)) {
       // @ts-ignore
-      const parsedSelves = SelfUtils.getSelves(this.self, self, this.webex.internal.device.url);
+      const parsedSelves = SelfUtils.getSelves(this.parsedLocus.self || this.self, self, this.webex.internal.device.url);
♻️ Duplicate comments (1)
packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (1)

309-338: ⚠️ Potential issue

Optimize subnet lookup by using a Map instead of converting Set to Array

Converting a Set to an Array for searching defeats the purpose of using a Set. This operation has O(n) complexity for each lookup.

Consider using a Map with a composite key or a more efficient data structure:

-public reachedSubnets: Set<{
+public reachedSubnets: Map<string, {
   serverIps: string;
   port: number;
   protocol?: string;
   reachable?: string;
   'answered-tx'?: number;
   'lost-tx'?: number;
   latencies: number[];
-}> = new Set();
+}> = new Map();

// In saveResult method:
-const subnetIndex = Array.from(this.reachedSubnets).findIndex(
-  (subnet) =>
-    subnet.serverIps === serverIp && subnet.protocol === protocol && subnet.port === port
-);
-
-if (subnetIndex !== -1) {
-  const subnet = Array.from(this.reachedSubnets)[subnetIndex];
+const key = `${serverIp}:${port}:${protocol}`;
+const subnet = this.reachedSubnets.get(key);
+
+if (subnet) {
   subnet.reachable = 'true';
   // ... rest of the update logic
} else {
-  this.reachedSubnets.add({
+  this.reachedSubnets.set(key, {
     serverIps: serverIp,
     // ... rest of the object
   });
}
🧹 Nitpick comments (17)
cspell.json (1)

227-255: Suggest sorting and deduplicating the words list
The new block at the end of the words array is currently unsorted and may include duplicates (e.g., multiple variants of "messageid"). Alphabetical ordering and removal of duplicate entries will make this list easier to manage and review in the future.

packages/@webex/plugin-meetings/src/member/util.ts (3)

111-131: Refactor to use optional chaining and enforce boolean.

Simplify patterns like participant && participant.prop to !!participant?.prop, improving readability:

-MemberUtil.isUser = (participant: any) => participant && participant.type === _USER_;
+MemberUtil.isUser = (participant: any): boolean =>
+  participant?.type === _USER_;

Apply similar changes to isModerator, isGuest, isDevice, isModeratorAssignmentProhibited, and isPresenterAssignmentProhibited.

🧰 Tools
🪛 Biome (1.9.4)

[error] 113-113: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 119-119: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 128-128: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 131-131: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


150-156: Consider optional chaining for nested checks.

You can simplify and guard against missing arrays:

-MemberUtil.isAssociatedSame = (participant: any, id: string) =>
-  participant &&
-  participant.associatedUsers &&
-  participant.associatedUsers.some(
-    (user) => user.id === id || (user.person && user.person.id === id)
-  );
+MemberUtil.isAssociatedSame = (participant: any, id: string): boolean =>
+  participant?.associatedUsers?.some(
+    (user) => user.id === id || user.person?.id === id
+  ) || false;
🧰 Tools
🪛 Biome (1.9.4)

[error] 151-155: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


259-276: Ensure isMuted returns a boolean.

The current implementation may return undefined. Consider normalizing:

 MemberUtil.isMuted = (participant: any, statusAccessor: string, controlsAccessor: string): boolean => {
-  const remoteMute = participant?.controls?.[controlsAccessor]?.muted;
+  const remoteMute = !!participant?.controls?.[controlsAccessor]?.muted;
   if (remoteMute) {
     return true;
   }
 
-  const localStatus = participant?.status?.[statusAccessor];
+  const localStatus = participant?.status?.[statusAccessor];
   if (localStatus === _RECEIVE_ONLY_) {
     return true;
   }
   if (localStatus === _SEND_RECEIVE_) {
     return false;
   }
 
-  return remoteMute;
+  return remoteMute;
 };

This ensures consistency in boolean returns.

packages/@webex/plugin-cc/src/services/core/Utils.ts (1)

51-51: Potential redundant fallback in error handling.

The error object creation now includes a fallback (?? \Error while performing ${methodName}`), but reason` already has the same fallback on line 37. This creates redundant logic that might be unnecessary.

Consider simplifying to avoid redundancy:

-    error: new Error(reason ?? `Error while performing ${methodName}`),
+    error: new Error(reason),

Since reason already has the fallback logic, the additional nullish coalescing is redundant.

packages/@webex/plugin-cc/typedoc.md (1)

78-78: Fix style and grammar issues in documentation.

Static analysis identified two issues in this line:

  1. "Agent based operations" should be hyphenated as "Agent-based operations"
  2. Consider using stronger wording than "if you want to"
-- [`Contact Center`](./classes/ContactCenter.html) - Click here if you want to learn more about `Agent based operations` such as station login, user state management, outdial, and related functionalities.
+- [`Contact Center`](./classes/ContactCenter.html) - Click here to learn more about `Agent-based operations` such as station login, user state management, outdial, and related functionalities.
🧰 Tools
🪛 LanguageTool

[style] ~78-~78: Consider using an alternative to strengthen your wording.
Context: ...ContactCenter.html) - Click here if you want to learn more about `Agent based operat...

(WANT_KEEN)


[uncategorized] ~78-~78: This expression is usually spelled with a hyphen.
Context: ...ck here if you want to learn more about Agent based operations such as station login, user...

(BASED_HYPHEN)

packages/@webex/plugin-meetings/src/reachability/reachability.types.ts (1)

12-21: Comprehensive subnet details type definition.

The SubnetDetails type provides thorough tracking of per-subnet reachability metrics including protocol, transmission statistics, latency arrays, and port information. This supports granular analysis of network connectivity.

Consider adding JSDoc comments to document the purpose of transmission count properties (answered-tx, lost-tx) for better developer understanding.

+/**
+ * Detailed reachability information for a specific subnet IP address
+ */
 export type SubnetDetails = {
   protocol?: 'udp' | 'tcp' | 'xtls'; // Protocol used for the test
   serverIps: string; // IP address of the subnet being tested
   reachable: true | false; // Result for this specific address
-  'answered-tx'?: number; // 1 if reachable, 0 otherwise
-  'lost-tx'?: number; // 1 if unreachable, 0 otherwise
+  'answered-tx'?: number; // Number of successful transmissions (1 if reachable, 0 otherwise)
+  'lost-tx'?: number; // Number of failed transmissions (1 if unreachable, 0 otherwise)
   port: number; // Port used for the test
   latencies?: number[];
 };
packages/@webex/plugin-meetings/src/locus-info/index.ts (1)

367-370: Consider addressing TypeScript type issues in a follow-up.

There are multiple @ts-ignore comments in this code that suggest unresolved TypeScript type issues. While not critical for this PR, consider creating a follow-up task to properly type these properties and remove the need for these suppressions.

Would you like me to help create proper TypeScript interfaces for the self and participant objects to eliminate these type suppressions?

Also applies to: 1627-1627

packages/@webex/plugin-meetings/test/unit/spec/locus-info/index.js (1)

859-859: Consider using a consistent approach for setting self state in tests

Throughout the test file, there's inconsistent usage between direct assignment (locusInfo.self = ...) and calling updateSelf. While both approaches work for testing, using a consistent pattern would improve test readability and maintainability.

Consider standardizing on one approach, preferably using updateSelf to better simulate actual usage:

-locusInfo.self = selfWithBrbChanged;
+locusInfo.updateSelf(selfWithBrbChanged, []);

Also applies to: 883-883, 997-997, 1032-1033, 1039-1039, 1050-1050, 1094-1094, 1126-1126, 1148-1148, 1187-1187, 1228-1228, 1253-1253, 1294-1294, 1415-1415, 1434-1434, 1453-1453, 1475-1475, 1497-1497, 1950-1950

packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (2)

321-324: Document the XTLS domain name replacement logic

The special handling for XTLS where domain names are replaced with resolved IPs could be confusing and prone to bugs. Consider adding a comment explaining why this is necessary.

// Replacing domain name with resolved IP for XTLS
if (protocol === 'xtls' && subnet.serverIps.includes('.public.')) {
+  // XTLS initially uses domain names in serverIps, but we need to store the resolved IP
+  // for accurate tracking and comparison
  subnet.serverIps = serverIp;
}

536-545: Add null check for edge cases in updateMinLatency

The method should handle the edge case where this.result[protocol] might be undefined.

private updateMinLatency(protocol: 'udp' | 'tcp' | 'xtls') {
-  if (this.reachedSubnets) {
+  if (this.reachedSubnets && this.result[protocol]) {
    const latencies = Array.from(this.reachedSubnets)
      .filter((subnet) => subnet.protocol === protocol && subnet.latencies.length > 0)
      .flatMap((subnet) => subnet.latencies);
    if (latencies.length > 0) {
      this.result[protocol].minLatency = Math.min(...latencies);
    }
  }
}
packages/@webex/webex-core/test/unit/spec/services-v2/service-url.js (1)

71-71: Fix typo in test description.

-    describe('#defautUrl', () => {
+    describe('#defaultUrl', () => {
packages/@webex/webex-core/test/unit/spec/services-v2/service-registry.js (1)

641-641: Fix typo in comment.

-      it('should reset all hosts when called withour a filter', () => {
+      it('should reset all hosts when called without a filter', () => {
packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/service.js (1)

8-8: Remove unused CONFIG import.

The CONFIG import is not used anywhere in this test file.

 import {ServiceInterceptor} from '@webex/webex-core';
-import CONFIG from '../../../../../src/config';
packages/@webex/webex-core/test/integration/spec/services-v2/services-v2.js (1)

237-237: Remove or fix commented assertion

Commented code should be removed or fixed if it's meant to be active.

-// assert.equal(serviceFound.url, catalog.get('exampleValid', true));
packages/@webex/webex-core/src/lib/services-v2/service-registry.js (1)

446-446: Inconsistent error message prefix

The error message uses "service-catalogs:" prefix but this is the ServiceRegistry class.

-throw new Error(`service-catalogs: '${catalog}' is not a valid catalog`);
+throw new Error(`service-registry: '${catalog}' is not a valid catalog`);
packages/@webex/webex-core/src/lib/services-v2/services-v2.js (1)

710-714: Consider more explicit error handling.

The try-catch block silently returns from the forEach iteration when URL parsing fails. Consider logging a warning to help with debugging.

 let host;
 try {
   host = new URL(serviceUrl).host;
 } catch (e) {
+  this.logger.warn(`services: invalid service URL for ${serviceName}: ${serviceUrl}`);
   return;
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b7a8cd and 1b4baf8.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (83)
  • cspell.json (2 hunks)
  • docs/assets/css/main.css (0 hunks)
  • docs/index.html (5 hunks)
  • docs/labs/contact-center/README.md (0 hunks)
  • docs/labs/contact-center/auth.js (0 hunks)
  • docs/labs/contact-center/cleanup.js (0 hunks)
  • docs/labs/contact-center/index.html (0 hunks)
  • docs/labs/contact-center/index.js (0 hunks)
  • docs/labs/contact-center/registration.js (0 hunks)
  • docs/labs/contact-center/state-change.js (0 hunks)
  • docs/labs/contact-center/station-login.js (0 hunks)
  • docs/labs/contact-center/styles.css (0 hunks)
  • docs/labs/contact-center/task-consult.js (0 hunks)
  • docs/labs/contact-center/task-manager.js (0 hunks)
  • docs/samples/contact-center/app.js (0 hunks)
  • docs/samples/contact-center/index.html (0 hunks)
  • packages/@webex/http-core/src/interceptors/http-status.js (0 hunks)
  • packages/@webex/http-core/test/unit/spec/interceptors/http-status.js (0 hunks)
  • packages/@webex/internal-plugin-encryption/package.json (1 hunks)
  • packages/@webex/media-helpers/package.json (1 hunks)
  • packages/@webex/plugin-cc/src/cc.ts (14 hunks)
  • packages/@webex/plugin-cc/src/services/core/Utils.ts (2 hunks)
  • packages/@webex/plugin-cc/src/services/task/index.ts (15 hunks)
  • packages/@webex/plugin-cc/src/types.ts (7 hunks)
  • packages/@webex/plugin-cc/test/unit/spec/cc.ts (49 hunks)
  • packages/@webex/plugin-cc/test/unit/spec/services/core/Utils.ts (10 hunks)
  • packages/@webex/plugin-cc/typedoc.md (1 hunks)
  • packages/@webex/plugin-meetings/package.json (1 hunks)
  • packages/@webex/plugin-meetings/src/breakouts/index.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/config.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/constants.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/locus-info/index.ts (7 hunks)
  • packages/@webex/plugin-meetings/src/locus-info/selfUtils.ts (6 hunks)
  • packages/@webex/plugin-meetings/src/media/index.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts (2 hunks)
  • packages/@webex/plugin-meetings/src/meeting-info/utilv2.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/meeting/index.ts (1 hunks)
  • packages/@webex/plugin-meetings/src/meetings/index.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/member/index.ts (2 hunks)
  • packages/@webex/plugin-meetings/src/member/util.ts (1 hunks)
  • packages/@webex/plugin-meetings/src/members/index.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/members/request.ts (0 hunks)
  • packages/@webex/plugin-meetings/src/members/util.ts (1 hunks)
  • packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (9 hunks)
  • packages/@webex/plugin-meetings/src/reachability/index.ts (2 hunks)
  • packages/@webex/plugin-meetings/src/reachability/reachability.types.ts (1 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/breakouts/index.ts (19 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/locus-info/index.js (35 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/locus-info/selfUtils.js (8 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/media/index.ts (3 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/meeting-info/utilv2.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/meetings/index.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/members/index.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/members/request.js (0 hunks)
  • packages/@webex/plugin-meetings/test/unit/spec/members/utils.js (0 hunks)
  • packages/@webex/webex-core/src/index.js (1 hunks)
  • packages/@webex/webex-core/src/interceptors/redirect.js (0 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/index.js (1 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-catalog.js (16 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-detail.ts (0 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-host.js (1 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-registry.js (1 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-state.js (1 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/service-url.js (1 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/services-v2.js (10 hunks)
  • packages/@webex/webex-core/src/lib/services-v2/types.ts (0 hunks)
  • packages/@webex/webex-core/test/fixtures/host-catalog-v2.js (1 hunks)
  • packages/@webex/webex-core/test/integration/spec/services-v2/service-catalog.js (1 hunks)
  • packages/@webex/webex-core/test/integration/spec/services-v2/services-v2.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/interceptors/redirect.js (0 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/hostmap.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/server-error.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/service.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-catalog.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-detail.ts (0 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-host.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-registry.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-state.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-url.js (1 hunks)
  • packages/@webex/webex-core/test/unit/spec/services-v2/services-v2.js (3 hunks)
  • packages/calling/package.json (1 hunks)
💤 Files with no reviewable changes (36)
  • packages/@webex/http-core/test/unit/spec/interceptors/http-status.js
  • packages/@webex/plugin-meetings/test/unit/spec/members/request.js
  • packages/@webex/http-core/src/interceptors/http-status.js
  • packages/@webex/plugin-meetings/src/config.ts
  • packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js
  • packages/@webex/plugin-meetings/src/members/index.ts
  • packages/@webex/plugin-meetings/src/media/index.ts
  • packages/@webex/plugin-meetings/test/unit/spec/meeting-info/utilv2.js
  • docs/samples/contact-center/index.html
  • packages/@webex/plugin-meetings/test/unit/spec/members/utils.js
  • packages/@webex/webex-core/src/interceptors/redirect.js
  • packages/@webex/plugin-meetings/src/meeting-info/utilv2.ts
  • packages/@webex/plugin-meetings/test/unit/spec/members/index.js
  • packages/@webex/plugin-meetings/src/meetings/index.ts
  • packages/@webex/webex-core/src/lib/services-v2/types.ts
  • docs/labs/contact-center/auth.js
  • packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js
  • packages/@webex/webex-core/test/unit/spec/interceptors/redirect.js
  • packages/@webex/plugin-meetings/src/breakouts/index.ts
  • docs/labs/contact-center/styles.css
  • docs/labs/contact-center/cleanup.js
  • packages/@webex/webex-core/src/lib/services-v2/service-detail.ts
  • packages/@webex/plugin-meetings/test/unit/spec/meetings/index.js
  • packages/@webex/plugin-meetings/src/constants.ts
  • docs/assets/css/main.css
  • docs/labs/contact-center/station-login.js
  • docs/labs/contact-center/state-change.js
  • packages/@webex/plugin-meetings/src/members/request.ts
  • docs/labs/contact-center/index.js
  • docs/labs/contact-center/index.html
  • docs/labs/contact-center/task-consult.js
  • packages/@webex/webex-core/test/unit/spec/services-v2/service-detail.ts
  • docs/labs/contact-center/task-manager.js
  • docs/labs/contact-center/README.md
  • docs/samples/contact-center/app.js
  • docs/labs/contact-center/registration.js
✅ Files skipped from review due to trivial changes (12)
  • packages/@webex/plugin-meetings/package.json
  • packages/@webex/plugin-meetings/src/member/index.ts
  • packages/@webex/internal-plugin-encryption/package.json
  • packages/calling/package.json
  • packages/@webex/media-helpers/package.json
  • packages/@webex/webex-core/src/lib/services-v2/index.js
  • packages/@webex/webex-core/test/fixtures/host-catalog-v2.js
  • docs/index.html
  • packages/@webex/plugin-meetings/test/unit/spec/media/index.ts
  • packages/@webex/plugin-cc/src/services/task/index.ts
  • packages/@webex/plugin-cc/src/types.ts
  • packages/@webex/plugin-meetings/test/unit/spec/breakouts/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/@webex/plugin-meetings/src/reachability/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (11)
packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/hostmap.js (2)
packages/@webex/test-helper-mock-webex/src/index.js (1)
  • MockWebex (126-222)
packages/@webex/webex-core/src/lib/services-v2/interceptors/hostmap.js (1)
  • HostMapInterceptor (12-36)
packages/@webex/plugin-meetings/src/members/util.ts (1)
packages/@webex/plugin-meetings/src/constants.ts (1)
  • VALID_EMAIL_ADDRESS (225-226)
packages/@webex/webex-core/test/unit/spec/services-v2/service-state.js (1)
packages/@webex/webex-core/src/lib/services-v2/service-state.js (1)
  • ServiceState (15-78)
packages/@webex/webex-core/src/lib/services-v2/service-state.js (1)
packages/@webex/webex-core/src/lib/services-v2/constants.js (1)
  • SERVICE_CATALOGS (2-2)
packages/@webex/webex-core/test/unit/spec/services-v2/service-host.js (1)
packages/@webex/webex-core/src/lib/services-v2/service-host.js (1)
  • ServiceHost (30-267)
packages/@webex/webex-core/test/unit/spec/services-v2/service-url.js (2)
packages/@webex/test-helper-mock-webex/src/index.js (1)
  • MockWebex (126-222)
packages/@webex/webex-core/src/lib/services-v2/service-url.js (3)
  • ServiceUrl (9-121)
  • foundHost (97-97)
  • url (25-25)
packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/server-error.js (3)
packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/service.js (1)
  • chai (10-10)
packages/@webex/webex-core/src/lib/services-v2/interceptors/server-error.js (1)
  • ServerErrorInterceptor (10-48)
packages/@webex/webex-core/src/lib/webex-http-error.js (1)
  • WebexHttpError (10-60)
packages/@webex/webex-core/test/unit/spec/services-v2/service-registry.js (4)
packages/@webex/webex-core/src/lib/services-v2/service-registry.js (1)
  • ServiceRegistry (35-465)
packages/@webex/webex-core/src/lib/services-v2/constants.js (1)
  • SERVICE_CATALOGS (2-2)
packages/@webex/webex-core/src/lib/services-v2/services-v2.js (2)
  • hostCatalog (672-672)
  • host (678-678)
packages/@webex/webex-core/src/lib/services-v2/service-url.js (2)
  • filteredHosts (59-61)
  • foundHost (97-97)
packages/@webex/webex-core/src/lib/services-v2/service-registry.js (2)
packages/@webex/webex-core/src/lib/services-v2/constants.js (2)
  • SERVICE_CATALOGS_ENUM_TYPES (4-7)
  • SERVICE_CATALOGS (2-2)
packages/@webex/webex-core/src/lib/services-v2/service-host.js (1)
  • ServiceHost (30-267)
packages/@webex/plugin-meetings/src/meeting/index.ts (1)
packages/@webex/plugin-meetings/src/reachability/reachability.types.ts (1)
  • ReachabilityMetrics (35-49)
packages/@webex/plugin-meetings/src/reachability/clusterReachability.ts (1)
packages/@webex/plugin-meetings/src/reachability/request.ts (1)
  • ClusterNode (5-10)
🪛 Biome (1.9.4)
packages/@webex/webex-core/test/unit/spec/services-v2/service-host.js

[error] 198-198: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 203-203: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 208-208: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 213-213: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 218-218: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 223-223: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/server-error.js

[error] 182-182: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/@webex/webex-core/test/integration/spec/services-v2/services-v2.js

[error] 1061-1085: Excessive describe() nesting detected.

Excessive nesting of describe() calls can hinder test readability.
Consider refactoring and reduce the level of nested describe to improve code clarity.

(lint/complexity/noExcessiveNestedTestSuites)


[error] 1087-1109: Excessive describe() nesting detected.

Excessive nesting of describe() calls can hinder test readability.
Consider refactoring and reduce the level of nested describe to improve code clarity.

(lint/complexity/noExcessiveNestedTestSuites)


[error] 1192-1203: Disallow duplicate setup and teardown hooks.

Disallow before duplicacy inside the describe function.

(lint/suspicious/noDuplicateTestHooks)

packages/@webex/webex-core/src/lib/services-v2/service-registry.js

[error] 77-77: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

packages/@webex/plugin-meetings/src/member/util.ts

[error] 113-113: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 119-119: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 128-128: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 131-131: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 151-155: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 164-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 166-168: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 287-287: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 302-302: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 345-345: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 403-403: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 LanguageTool
packages/@webex/plugin-cc/typedoc.md

[style] ~78-~78: Consider using an alternative to strengthen your wording.
Context: ...ContactCenter.html) - Click here if you want to learn more about `Agent based operat...

(WANT_KEEN)


[uncategorized] ~78-~78: This expression is usually spelled with a hyphen.
Context: ...ck here if you want to learn more about Agent based operations such as station login, user...

(BASED_HYPHEN)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: AWS Amplify Console Web Preview
🔇 Additional comments (61)
cspell.json (1)

271-271: ignoreWords formatting is concise and clear
Consolidating the ignore list into a single line improves readability without sacrificing clarity.

packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts (2)

636-636: Formatting change looks good.

The registrationId parameter declaration appears to be a minor formatting or consistency update.


687-692:

✅ Verification successful

Verify the URI handling simplification doesn't break existing functionality.

The logic has been simplified from presumably more complex URI handling (involving fullSiteUrl) to a basic directURI check. While this simplification is good for maintainability, ensure that any edge cases or fallback behavior previously handled by the removed logic are still properly addressed.


🏁 Script executed:

#!/bin/bash
# Description: Check for any references to fullSiteUrl in the codebase to understand the scope of this change
# Expected: Find references that might indicate where fullSiteUrl was used and if there are other places that need updating

echo "Searching for fullSiteUrl references in the codebase..."
rg -i "fullsiteurl" --type ts --type js -A 3 -B 3

echo "Searching for disableWebRedirect references..."
rg -i "disablewebredirect" --type ts --type js -A 3 -B 3

echo "Searching for usage of fetchMeetingInfo method to check parameter compatibility..."
rg "fetchMeetingInfo\(" --type ts --type js -A 5

Length of output: 66053


✅ No legacy URI fallback logic detected

I searched the codebase for fullSiteUrl and disableWebRedirect references and found none. All calls to fetchMeetingInfo now correctly branch on directURI versus the WBXAPPAPI_SERVICE/meetingInfo fallback, and existing unit tests in meeting-info-v2.js and related specs cover:

  • Direct-URI paths
  • Service/resource fallback
  • Error and edge-case scenarios

No further action is needed.

packages/@webex/plugin-meetings/src/member/util.ts (17)

59-61: LGTM.

The implementation is concise and defaults to false when BRB status is not present.


76-92: LGTM.

The specialized role checks (hasCohost, hasModerator, hasPresenter) correctly delegate to hasRole with a false fallback.


97-105: LGTM.

extractControlRoles neatly aggregates specific role flags into an external shape.


140-142: LGTM.

isSame correctly handles both direct and nested person.id comparisons.


180-198: LGTM.

Audio/video mute checks correctly guard against missing participants and delegate to isMuted.


204-210: LGTM.

Properly throws when participant is undefined and safely returns the raised status.


216-222: LGTM.

Correctly validates breakout support and covers undefined participant.


228-236: LGTM.

Interpretation support flag is handled consistently with error guarding.


242-250: LGTM.

Live annotation support logic is clear and safe.


283-292: LGTM.

The method safely checks nested properties and returns recording member or null.

🧰 Tools
🪛 Biome (1.9.4)

[error] 287-287: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


298-307: LGTM.

Recording detection correctly throws on undefined participants and returns a boolean.

🧰 Tools
🪛 Biome (1.9.4)

[error] 302-302: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


309-321: LGTM.

Removal logic is straightforward and covers all edge cases.


323-338: LGTM.

Mutability rules are clearly implemented with proper condition ordering.


344-368: LGTM.

Status extraction handles all device and state combinations consistently.

🧰 Tools
🪛 Biome (1.9.4)

[error] 345-345: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


374-380: LGTM.

Simple and correct ID extraction with null fallback.


387-396: LGTM.

Media status extraction is safe and uses JSDoc for type assurance.


402-408: LGTM.

Name extraction is correctly guarded and returns null when absent.

🧰 Tools
🪛 Biome (1.9.4)

[error] 403-403: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/@webex/plugin-cc/test/unit/spec/services/core/Utils.ts (3)

4-4: LGTM - Import addition.

The addition of WebexRequestPayload import aligns with its usage in the test code.


37-37: LGTM - Formatting improvements.

The formatting changes improve code readability by adding consistent spacing in object literals and improving alignment.

Also applies to: 71-71, 123-123, 195-197, 204-205


1-220:

❓ Verification inconclusive

Inconsistency between PR objectives and files under review.

The PR objectives mention fixing subnet IP details in plugin-meetings, but all files under review are from plugin-cc (Contact Center plugin). Please verify that the correct files are being reviewed for this PR.


🏁 Script executed:

#!/bin/bash
# Check if this PR contains any plugin-meetings files
echo "=== Searching for plugin-meetings files in the repository ==="
fd -t f . | rg "plugin-meetings" | head -20

echo -e "\n=== Searching for ClusterReachability class mentioned in AI summary ==="
ast-grep --pattern 'class ClusterReachability {
  $$$
}'

echo -e "\n=== Searching for reachability-related changes ==="
rg -i "reachability|subnet" --type ts -A 3 -B 3

Length of output: 83335


🏁 Script executed:

#!/bin/bash
# Fetch main to compare against PR branch
git fetch origin main --quiet

echo "=== plugin-meetings files modified in this PR ==="
git diff --name-only origin/main..HEAD | grep "packages/@webex/plugin-meetings" || echo "none"

echo -e "\n=== plugin-cc files modified in this PR ==="
git diff --name-only origin/main..HEAD | grep "packages/@webex/plugin-cc" || echo "none"

Length of output: 864


🏁 Script executed:

#!/bin/bash
# Fetch master to compare against PR branch
git fetch origin master --quiet

echo "=== plugin-meetings files modified in this PR ==="
git diff --name-only origin/master...HEAD | grep "packages/@webex/plugin-meetings" || echo "none"

echo -e "\n=== plugin-cc files modified in this PR ==="
git diff --name-only origin/master...HEAD | grep "packages/@webex/plugin-cc" || echo "none"

Length of output: 841


Inconsistent PR scope: plugin-meetings vs. plugin-cc
The PR description refers to updating subnet IPs in plugin-meetings, but the only changed files are under packages/@webex/plugin-cc (e.g. test/unit/spec/services/core/Utils.ts).

Please verify that:

  • The intended plugin-meetings files are included in this PR.
  • You’re reviewing the correct set of changes against the PR objectives.
packages/@webex/plugin-cc/test/unit/spec/cc.ts (1)

33-33: LGTM - Consistent formatting improvements.

The formatting changes improve code readability through consistent spacing, proper object literal formatting, and better alignment of multi-line constructs. The test logic and assertions remain unchanged.

Also applies to: 79-79, 281-284, 568-568, 728-732

packages/@webex/plugin-cc/src/services/core/Utils.ts (1)

2-2: LGTM - Import addition.

The import of WebexRequestPayload type is appropriate for the function signatures in this file.

packages/@webex/plugin-cc/typedoc.md (1)

3-85: LGTM - Excellent documentation improvements.

The documentation rewrite significantly improves the developer experience by:

  • Providing clear, concise installation and initialization examples
  • Adding a comprehensive configuration reference table
  • Focusing on practical usage rather than verbose explanations
  • Maintaining a professional, reference-style format
🧰 Tools
🪛 LanguageTool

[style] ~78-~78: Consider using an alternative to strengthen your wording.
Context: ...ContactCenter.html) - Click here if you want to learn more about `Agent based operat...

(WANT_KEEN)


[uncategorized] ~78-~78: This expression is usually spelled with a hyphen.
Context: ...ck here if you want to learn more about Agent based operations such as station login, user...

(BASED_HYPHEN)

packages/@webex/plugin-cc/src/cc.ts (8)

46-46: LGTM! Import looks correct.

The getErrorDetails import is properly maintained and used throughout the file for error handling.


67-78: Excellent documentation simplification!

The streamlined class documentation is much cleaner and focuses on the core capabilities without unnecessary verbosity. The bullet point structure makes it easy to understand the main features.


83-86: Well-structured example code.

The simplified example clearly demonstrates the basic workflow (register → stationLogin → setAgentState) which is exactly what developers need to understand the core usage pattern.


91-122: Clean and consistent property documentation.

The simplified property comments are much more readable and maintain consistent formatting. Each property's purpose is clearly stated without unnecessary verbosity.


197-206: Good documentation streamlining for register method.

The documentation maintains all critical information (return type, throws, usage) while being more concise and focused. The example demonstrates proper usage.


259-272: Clear and improved deregister documentation.

The simplified documentation clearly explains the method's purpose while preserving the important note about not performing station signout. The example shows the proper sequence of operations.


524-524: Verify consistency with the AI summary.

The AI summary mentions removal of this.webCallingService.setLoginOption calls, but I can see this call still exists at line 524 in the stationLogin method. Please verify if the summary accurately reflects the changes made to this specific file.

Likely an incorrect or invalid review comment.


347-347: Consistent documentation improvements across all methods.

The documentation simplification is well-executed across all methods:

  • Examples are more focused and demonstrate core functionality
  • Parameter descriptions are concise but complete
  • Essential information is preserved while removing verbosity
  • Consistent formatting and style throughout

These changes significantly improve the API documentation's readability and usability.

Also applies to: 472-478, 566-566, 638-654, 985-998, 1059-1072, 1120-1125, 1133-1151

packages/@webex/plugin-meetings/src/members/util.ts (1)

113-113: LGTM: Email validation simplified correctly.

The change removes SIP address format validation and now only validates email addresses using the VALID_EMAIL_ADDRESS regex pattern, which aligns with the removal of SIP functionality mentioned in the PR objectives.

packages/@webex/plugin-meetings/src/reachability/reachability.types.ts (1)

8-10: LGTM: Well-designed type enhancements for detailed reachability tracking.

The addition of minLatency and details properties to TransportResult effectively supports the PR objective of saving subnet IP details. The optional nature of these properties ensures backward compatibility.

packages/@webex/plugin-meetings/src/meeting/index.ts (1)

265-265: LGTM! Clean type simplification.

The intersection type syntax is correct and the simplification aligns well with the architectural improvements described in the PR summary. Moving detailed subnet handling to the reachability subsystem while keeping the essential boolean flag here makes the code more maintainable.

packages/@webex/plugin-meetings/test/unit/spec/locus-info/selfUtils.js (3)

7-7: Import looks good.

The addition of _IDLE_ and _WAIT_ constants is appropriate for the updated test cases that check device intent states.


278-349: Verify the inconsistent getSelves method signatures.

Most calls to SelfUtils.getSelves have been updated to use 2 parameters (removing the participants parameter), but line 349 uses 3 parameters with self.devices[0].url as the third parameter. This inconsistency suggests either:

  • The method has different behaviors based on the number of parameters
  • There's a missing update in other test cases

Please verify that this is intentional and consider adding a comment to clarify why this specific test uses a different signature.


343-391: Test refactoring looks good.

The renaming from hasUserEnteredLobby to isUserUnadmitted and the corresponding helper function updates improve semantic clarity. The test cases properly cover the different state transitions for user admission status.

packages/@webex/plugin-meetings/src/locus-info/index.ts (3)

384-384: Good improvement for data consistency.

Using the passed participants parameter instead of this.participants ensures the method works with the most current data, preventing potential issues with stale participant information.


267-267: Call sites properly updated.

The updateSelf method calls have been correctly updated to include the participants parameter, maintaining consistency with the new method signature.

Also applies to: 452-452


1530-1540: Event naming improvements look good.

The renaming from hasUserEnteredLobby/hasUserBeenAdmitted to isUserUnadmitted/isUserAdmitted improves clarity and follows boolean naming conventions.

packages/@webex/plugin-meetings/src/locus-info/selfUtils.ts (2)

29-74: LGTM! Good simplification of the parse method

The removal of the participants parameter and the simplification of isUserUnadmitted logic makes the code cleaner and more maintainable. The direct calculation of isUserUnadmitted based on state and intent type is more straightforward.


97-140: LGTM! Clean refactoring of getSelves method

The removal of participant dependency and the simplified parsing logic improves code clarity. The renamed flags (isUserUnadmitted and isUserAdmitted) are more descriptive than the previous naming.

packages/@webex/webex-core/src/index.js (1)

34-40: LGTM! Export additions support the services-v2 refactor.

The new exports for ServiceRegistryV2, ServiceStateV2, ServiceHostV2, and ServiceUrlV2 are properly structured and follow the established naming conventions. These additions correctly support the architectural shift from ServiceDetail to the new modular service management classes.

packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/hostmap.js (1)

1-79: LGTM! Comprehensive test coverage for HostMapInterceptor.

The test suite properly validates the HostMapInterceptor functionality:

  • URI replacement when options.uri is defined
  • No action when options.uri is undefined
  • Error handling when replaceHostFromHostmap throws exceptions

The mocking approach using sinon stubs is appropriate and the test structure follows established patterns in the codebase.

packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/server-error.js (1)

1-204: Excellent test coverage for ServerErrorInterceptor.

The test suite comprehensively validates the interceptor's behavior across multiple scenarios:

  • Feature flag checking and conditional logic
  • Metrics submission when web-high-availability is enabled
  • URL marking as failed for different HTTP error codes (500, 503)
  • Proper error propagation when feature is disabled
  • Edge cases like missing URI

The test structure is well-organized and follows established patterns.

🧰 Tools
🪛 Biome (1.9.4)

[error] 182-182: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/@webex/webex-core/src/lib/services-v2/service-state.js (1)

1-78: LGTM! Well-designed ServiceState class implementation.

The ServiceState class is cleanly implemented with:

  • Comprehensive JSDoc documentation including proper typedef for CatalogState
  • Constructor that properly initializes state for all catalog types from SERVICE_CATALOGS
  • Validation checks in setCollecting and setReady methods to prevent errors on invalid catalogs
  • Static factory method for generating default catalog states
  • Clear separation of concerns for managing service catalog states

The implementation follows established patterns and best practices for the Webex core SDK.

packages/@webex/webex-core/src/lib/services-v2/service-url.js (4)

1-16: Class structure and props definition look good.

The use of AmpState and the props configuration with appropriate types and defaults is well implemented.


24-32: URL generation logic is correctly implemented.

Good handling of the port preservation and the explanatory comment about the url.hostname limitation is helpful.


91-104: Clarify the defaultUrl special case behavior.

The method returns true when the defaultUrl is passed without actually marking anything as failed. This behavior is counterintuitive and could lead to confusion.

Consider either:

  1. Documenting why defaultUrl is treated specially
  2. Returning false for defaultUrl since no host is actually marked as failed
  3. Throwing an error if defaultUrl is passed
   failHost(url) {
     if (url === this.defaultUrl) {
-      return true;
+      // Default URL doesn't have a specific host to mark as failed
+      return false;
     }

114-120: Clean implementation of the get method.

Good separation of concerns by delegating complex logic to _getPriorityHostUrl.

packages/@webex/webex-core/test/unit/spec/services-v2/service-host.js (1)

130-177: Comprehensive setStatus method testing.

Excellent coverage of all property combinations and edge cases.

packages/@webex/webex-core/test/unit/spec/services-v2/service-url.js (1)

97-258: Excellent test coverage for ServiceUrl class.

The tests thoroughly cover all methods including edge cases, error conditions, and the clusterId filtering logic.

packages/@webex/webex-core/test/unit/spec/services-v2/service-registry.js (1)

1-747: Outstanding test coverage for ServiceRegistry.

This test suite provides comprehensive coverage of all ServiceRegistry methods including filtering, state management, and static utilities. The test organization and use of fixtures is exemplary.

packages/@webex/webex-core/test/unit/spec/services-v2/interceptors/service.js (1)

15-194: Well-structured interceptor tests with good async handling.

Excellent use of stubs and spies to test the asynchronous behavior of the interceptor. The test coverage for all methods is comprehensive.

packages/@webex/webex-core/test/unit/spec/services-v2/services-v2.js (1)

318-335: Test correctly reflects the API change to updateServiceUrls.

The test has been properly updated to use catalog.updateServiceUrls instead of the deprecated updateServiceGroups, aligning with the refactored service catalog implementation.

packages/@webex/webex-core/src/lib/services-v2/service-catalog.js (2)

115-115: Good addition of method chaining support.

Returning this enables fluent API usage, which is a nice improvement to the interface.


391-419: Excellent refactoring of the service update logic.

The method now properly updates existing services in place (lines 404-405) rather than replacing the entire list, which is more efficient. The addition of method chaining support (line 418) also improves the API usability.

packages/@webex/webex-core/src/lib/services-v2/services-v2.js (1)

27-29: Important notice about v2 implementation.

The comment clearly indicates this is for DNSSec enabled users and may not be backwards compatible. Ensure this is well-documented in release notes and migration guides.

Comment on lines +30 to +31
const MemberUtil: any = {};

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Prefer a strongly typed interface over any for MemberUtil.

Using any erases type safety for the entire utility. Define an interface that describes the shape of MemberUtil or use Record<string, Function> to retain type checking.

🤖 Prompt for AI Agents
In packages/@webex/plugin-meetings/src/member/util.ts at lines 30 to 31, the
MemberUtil object is typed as any, which removes type safety. Replace the any
type with a strongly typed interface that defines the expected properties and
methods of MemberUtil, or use Record<string, Function> if the shape is dynamic,
to ensure proper type checking and maintain code safety.

Comment on lines +36 to +44
MemberUtil.canReclaimHost = (participant) => {
if (!participant) {
throw new ParameterError(
'canReclaimHostRole could not be processed, participant is undefined.'
);
}

return participant.canReclaimHostRole || false;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix error message to match method name.

The thrown ParameterError references canReclaimHostRole but the method is canReclaimHost. Update the message for clarity:

-  throw new ParameterError(
-    'canReclaimHostRole could not be processed, participant is undefined.'
-  );
+  throw new ParameterError(
+    'canReclaimHost could not be processed, participant is undefined.'
+  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MemberUtil.canReclaimHost = (participant) => {
if (!participant) {
throw new ParameterError(
'canReclaimHostRole could not be processed, participant is undefined.'
);
}
return participant.canReclaimHostRole || false;
};
MemberUtil.canReclaimHost = (participant) => {
if (!participant) {
throw new ParameterError(
'canReclaimHost could not be processed, participant is undefined.'
);
}
return participant.canReclaimHostRole || false;
};
🤖 Prompt for AI Agents
In packages/@webex/plugin-meetings/src/member/util.ts around lines 36 to 44, the
error message thrown in the ParameterError references 'canReclaimHostRole'
instead of the correct method name 'canReclaimHost'. Update the error message
string to accurately reflect the method name 'canReclaimHost' for clarity and
correctness.

Comment on lines +50 to +52
MemberUtil.getControlsRoles = (participant: ParticipantWithRoles): Array<ServerRoleShape> =>
participant?.controls?.role?.roles;

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure getControlsRoles always returns an array.

participant?.controls?.role?.roles can be undefined, leading to downstream errors. Provide a default empty array:

-MemberUtil.getControlsRoles = (participant: ParticipantWithRoles): Array<ServerRoleShape> =>
-  participant?.controls?.role?.roles;
+MemberUtil.getControlsRoles = (
+  participant: ParticipantWithRoles
+): Array<ServerRoleShape> =>
+  participant?.controls?.role?.roles || [];
🤖 Prompt for AI Agents
In packages/@webex/plugin-meetings/src/member/util.ts around lines 50 to 52, the
getControlsRoles method may return undefined if participant.controls.role.roles
is undefined, causing downstream errors. Modify the return statement to provide
a default empty array when roles is undefined, ensuring the method always
returns an array.

Comment on lines +67 to +71
MemberUtil.hasRole = (participant: any, controlRole: ServerRoles): boolean =>
MemberUtil.getControlsRoles(participant)?.some(
(role) => role.type === controlRole && role.hasRole
);

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure hasRole always returns a boolean.

Currently .some(...) may return undefined if roles are undefined. Add a fallback:

-MemberUtil.hasRole = (participant: any, controlRole: ServerRoles): boolean =>
-  MemberUtil.getControlsRoles(participant)?.some(
-    (role) => role.type === controlRole && role.hasRole
-  );
+MemberUtil.hasRole = (
+  participant: any,
+  controlRole: ServerRoles
+): boolean =>
+  MemberUtil.getControlsRoles(participant)?.some(
+    (role) => role.type === controlRole && role.hasRole
+  ) || false;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MemberUtil.hasRole = (participant: any, controlRole: ServerRoles): boolean =>
MemberUtil.getControlsRoles(participant)?.some(
(role) => role.type === controlRole && role.hasRole
);
MemberUtil.hasRole = (
participant: any,
controlRole: ServerRoles
): boolean =>
MemberUtil.getControlsRoles(participant)?.some(
(role) => role.type === controlRole && role.hasRole
) || false;
🤖 Prompt for AI Agents
In packages/@webex/plugin-meetings/src/member/util.ts at lines 67 to 71, the
hasRole function uses .some(...) which can return undefined if getControlsRoles
returns undefined. To fix this, ensure hasRole always returns a boolean by
adding a fallback to false when getControlsRoles(participant) is undefined
before calling .some(...).

Comment on lines +163 to +174
MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string): boolean =>
participant &&
participant.guest &&
((participant.devices &&
participant.devices[0] &&
participant.devices[0].intent &&
participant.devices[0].intent.type === _WAIT_ &&
// @ts-ignore
isGuest &&
status === _IN_LOBBY_) ||
// @ts-ignore
!status === _IN_MEETING_);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix logical error in admission check.

The expression !status === _IN_MEETING_ is incorrect (negating status instead of comparing inequality). Update to status !== _IN_MEETING_ and use optional chaining:

-MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string): boolean =>
-  participant &&
-  participant.guest &&
-  ((participant.devices &&
-    participant.devices[0] &&
-    participant.devices[0].intent &&
-    participant.devices[0].intent.type === _WAIT_ &&
-    // @ts-ignore
-    isGuest &&
-    status === _IN_LOBBY_) ||
-    // @ts-ignore
-    !status === _IN_MEETING_);
+MemberUtil.isNotAdmitted = (
+  participant: any,
+  isGuest: boolean,
+  status: string
+): boolean =>
+  !!participant &&
+  participant.guest &&
+  ((participant.devices?.[0]?.intent?.type === _WAIT_ && isGuest && status === _IN_LOBBY_) ||
+    status !== _IN_MEETING_);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string): boolean =>
participant &&
participant.guest &&
((participant.devices &&
participant.devices[0] &&
participant.devices[0].intent &&
participant.devices[0].intent.type === _WAIT_ &&
// @ts-ignore
isGuest &&
status === _IN_LOBBY_) ||
// @ts-ignore
!status === _IN_MEETING_);
MemberUtil.isNotAdmitted = (
participant: any,
isGuest: boolean,
status: string
): boolean =>
!!participant &&
participant.guest &&
((participant.devices?.[0]?.intent?.type === _WAIT_ && isGuest && status === _IN_LOBBY_) ||
status !== _IN_MEETING_);
🧰 Tools
🪛 Biome (1.9.4)

[error] 164-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 166-168: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🤖 Prompt for AI Agents
In packages/@webex/plugin-meetings/src/member/util.ts lines 163 to 174, the
condition uses '!status === _IN_MEETING_' which incorrectly negates status
instead of checking inequality. Replace '!status === _IN_MEETING_' with 'status
!== _IN_MEETING_' and apply optional chaining to safely access nested properties
like participant.devices[0].intent.type to avoid runtime errors.

Comment on lines +1192 to +1203
before('collect remote catalogs', () =>
Promise.all([
services._fetchNewServiceHostmap(),
services._fetchNewServiceHostmap({
from: 'limited',
query: {userId: webexUser.id},
}),
]).then(([fRHM, lRHM]) => {
fullRemoteHM = fRHM;
limitedRemoteHM = lRHM;
})
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Duplicate before hook will cause test failures

Having duplicate before hooks in the same describe block is not allowed and will cause test failures.

Remove the duplicate before hook since the remote catalogs are already collected in the parent describe block's before hook:

-before('collect remote catalogs', () =>
-  Promise.all([
-    services._fetchNewServiceHostmap(),
-    services._fetchNewServiceHostmap({
-      from: 'limited',
-      query: {userId: webexUser.id},
-    }),
-  ]).then(([fRHM, lRHM]) => {
-    fullRemoteHM = fRHM;
-    limitedRemoteHM = lRHM;
-  })
-);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
before('collect remote catalogs', () =>
Promise.all([
services._fetchNewServiceHostmap(),
services._fetchNewServiceHostmap({
from: 'limited',
query: {userId: webexUser.id},
}),
]).then(([fRHM, lRHM]) => {
fullRemoteHM = fRHM;
limitedRemoteHM = lRHM;
})
);
🧰 Tools
🪛 Biome (1.9.4)

[error] 1192-1203: Disallow duplicate setup and teardown hooks.

Disallow before duplicacy inside the describe function.

(lint/suspicious/noDuplicateTestHooks)

🤖 Prompt for AI Agents
In packages/@webex/webex-core/test/integration/spec/services-v2/services-v2.js
around lines 1192 to 1203, there is a duplicate before hook that collects remote
catalogs, which will cause test failures. Remove this duplicate before hook
entirely since the remote catalogs are already collected in the parent describe
block's before hook to avoid conflicts and test failures.

Comment on lines +42 to +48
new Promise((resolve) => {
setTimeout(() => {
webexUser = user;
webexUserEU = userEU;
resolve();
}, 1000);
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Arbitrary setTimeout could cause test flakiness

Similar to the previous file, the 1-second setTimeout appears arbitrary.

-new Promise((resolve) => {
-  setTimeout(() => {
-    webexUser = user;
-    webexUserEU = userEU;
-    resolve();
-  }, 1000);
-})
+Promise.resolve().then(() => {
+  webexUser = user;
+  webexUserEU = userEU;
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
new Promise((resolve) => {
setTimeout(() => {
webexUser = user;
webexUserEU = userEU;
resolve();
}, 1000);
})
Promise.resolve().then(() => {
webexUser = user;
webexUserEU = userEU;
})
🤖 Prompt for AI Agents
In packages/@webex/webex-core/test/integration/spec/services-v2/services-v2.js
between lines 42 and 48, replace the arbitrary 1-second setTimeout with a more
reliable synchronization method. Instead of waiting a fixed time, modify the
code to wait for a specific event, promise resolution, or condition that
confirms webexUser and webexUserEU are ready. This will prevent test flakiness
caused by timing assumptions.

foundHostCatalogPriority < currentHostCatalogPriority ||
foundHost.priority < currentHost.priority
) {
filteredHosts.splice(filteredHosts.indexOf(foundHost, 1));
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Syntax error in splice call - missing comma between arguments

The splice call has incorrect syntax with the second argument inside the indexOf call.

-filteredHosts.splice(filteredHosts.indexOf(foundHost, 1));
+filteredHosts.splice(filteredHosts.indexOf(foundHost), 1);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
filteredHosts.splice(filteredHosts.indexOf(foundHost, 1));
filteredHosts.splice(filteredHosts.indexOf(foundHost), 1);
🤖 Prompt for AI Agents
In packages/@webex/webex-core/src/lib/services-v2/service-registry.js at line
245, the splice method call has a syntax error because the second argument is
incorrectly placed inside the indexOf call. Fix this by closing the indexOf call
after foundHost, then add a comma, and pass 1 as the second argument to splice
to correctly remove one element at the found index.

Comment on lines +63 to +79
get map() {
// Get a list of active, local, and priority-mapped hosts.
return this.find({
active: true,
local: true,
priority: true,
}).reduce((map, host) => {
// Generate a new object to assign the existing map.
const hostReference = {};

// Assign the key:value pair for the service and url.
hostReference[host.service] = host.url;

// Assign the reference to the map and return.
return {...map, ...hostReference};
}, {});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Performance issue: O(n²) complexity due to spread in reduce

Using spread syntax in a reduce accumulator creates a new object on each iteration, resulting in O(n²) time complexity.

Use Object.assign or build the object after reduction:

 get map() {
   // Get a list of active, local, and priority-mapped hosts.
-  return this.find({
+  const hosts = this.find({
     active: true,
     local: true,
     priority: true,
-  }).reduce((map, host) => {
-    // Generate a new object to assign the existing map.
-    const hostReference = {};
-
-    // Assign the key:value pair for the service and url.
-    hostReference[host.service] = host.url;
-
-    // Assign the reference to the map and return.
-    return {...map, ...hostReference};
-  }, {});
+  });
+  
+  const map = {};
+  hosts.forEach(host => {
+    map[host.service] = host.url;
+  });
+  
+  return map;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
get map() {
// Get a list of active, local, and priority-mapped hosts.
return this.find({
active: true,
local: true,
priority: true,
}).reduce((map, host) => {
// Generate a new object to assign the existing map.
const hostReference = {};
// Assign the key:value pair for the service and url.
hostReference[host.service] = host.url;
// Assign the reference to the map and return.
return {...map, ...hostReference};
}, {});
}
get map() {
// Get a list of active, local, and priority-mapped hosts.
const hosts = this.find({
active: true,
local: true,
priority: true,
});
const map = {};
hosts.forEach((host) => {
map[host.service] = host.url;
});
return map;
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 77-77: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🤖 Prompt for AI Agents
In packages/@webex/webex-core/src/lib/services-v2/service-registry.js between
lines 63 and 79, the reduce function uses spread syntax to merge objects on each
iteration, causing O(n²) complexity. To fix this, replace the spread syntax with
Object.assign to mutate the accumulator object directly or build the map object
after the reduce completes to avoid creating a new object every iteration,
improving performance.

Comment on lines +699 to +700
this._updateHostCatalog(serviceHostmap.hostCatalog);

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Redundant host catalog updates.

The _hostCatalog is updated twice with the same data - once at the beginning (line 699) and again at the end (line 773). Consider removing one of these calls to avoid redundancy.

 _formatReceivedHostmap(serviceHostmap) {
   this._updateHostCatalog(serviceHostmap.hostCatalog);

   // ... rest of the method ...

   // update all the service urls in the host catalog

   this._updateServiceUrls(serviceHostmap.serviceLinks);
-  this._updateHostCatalog(serviceHostmap.hostCatalog);

   return formattedHostmap;
 }

Also applies to: 772-773

🤖 Prompt for AI Agents
In packages/@webex/webex-core/src/lib/services-v2/services-v2.js between lines
699 and 700, the method _updateHostCatalog is called redundantly with the same
hostCatalog data again at lines 772-773. Remove the earlier call at line 699 to
avoid updating _hostCatalog twice unnecessarily, keeping only the update at the
end to ensure a single, consolidated update.

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