Repository: dotnet/aspnetcore
File: src/Components/Web.JS/src/Rendering/JSRootComponents.ts (TypeScript)

Code before:
  }

  manager = managerInstance;
  jsComponentParametersByIdentifier = jsComponentParameters;

  // Call the registered initializers. This is an arbitrary subset of the JS component types that are registered
  // on the .NET side - just those of them that require some JS-side initialization (e.g., to register them
  // as custom elements).
  for (const [initializerIdentifier, componentIdentifiers] of Object.entries(jsComponentInitializers)) {
    const initializerFunc = DotNet.findJSFunction(initializerIdentifier, 0) as JSComponentInitializerCallback;
    for (const componentIdentifier of componentIdentifiers) {
      const parameters = jsComponentParameters[componentIdentifier];
      initializerFunc(componentIdentifier, parameters);
    }
  }
}

function getRequiredManager(): DotNet.DotNetObject {
  if (!manager) {
    throw new Error('Dynamic root components have not been enabled in this application.');
  }

  return manager;
}

// Keep in sync with equivalent in JSComponentConfigurationStore.cs
// These are an internal implementation detail not exposed in the registration APIs.
export type JSComponentParametersByIdentifier = { [identifier: string]: JSComponentParameter[] };
export type JSComponentIdentifiersByInitializer = { [initializer: string]: string[] };

// The following is public API
export interface JSComponentInitializerCallback {
  (identifier: string, parameters: JSComponentParameter[]): void;
}

export interface JSComponentParameter {
  name: string;
  type: JSComponentParameterType;
}

// JSON-primitive types, plus for those whose .NET equivalent isn't nullable, a '?' to indicate nullability
// This allows custom element authors to coerce attribute strings into the appropriate type
export type JSComponentParameterType = 'string' | 'boolean' | 'boolean?' | 'number' | 'number?' | 'object' | 'eventcallback';


Review comment (bug):
I think there is potentially more to this than just fixing this error. Try and trigger a `pause` and a `resume` operation manually. There are likely other things that fail? (happy to be wrong through)

Code after:
    // A different renderer type (e.g., Server vs WebAssembly) is trying to enable JS root components.
    // This is a multi-host scenario which is not supported for dynamic root components.
    throw new Error('Dynamic root components have already been enabled.');
  }

  // When the same renderer type re-enables (e.g., circuit restart or new circuit on same page),
  // accept the new manager. The old manager's DotNetObjectReference is no longer valid anyway
  // because the old circuit is gone. We don't dispose the old manager - doing so would cause
  // JSDisconnectedException because the circuit that created it no longer exists.
  currentRendererId = rendererId;
  manager = managerInstance;
  jsComponentParametersByIdentifier = jsComponentParameters;

  if (!hasInitializedJsComponents) {
    // Call the registered initializers. This is an arbitrary subset of the JS component types that are registered
    // on the .NET side - just those of them that require some JS-side initialization (e.g., to register them
    // as custom elements).
    for (const [initializerIdentifier, componentIdentifiers] of Object.entries(jsComponentInitializers)) {
      const initializerFunc = DotNet.findJSFunction(initializerIdentifier, 0) as JSComponentInitializerCallback;
      for (const componentIdentifier of componentIdentifiers) {
        const parameters = jsComponentParameters[componentIdentifier];
        initializerFunc(componentIdentifier, parameters);
      }
    }

    hasInitializedJsComponents = true;
  }
}

function getRequiredManager(): DotNet.DotNetObject {
  if (!manager) {
    throw new Error('Dynamic root components have not been enabled in this application.');
  }

  return manager;
}

// Keep in sync with equivalent in JSComponentConfigurationStore.cs
// These are an internal implementation detail not exposed in the registration APIs.
export type JSComponentParametersByIdentifier = { [identifier: string]: JSComponentParameter[] };
export type JSComponentIdentifiersByInitializer = { [initializer: string]: string[] };

// The following is public API
export interface JSComponentInitializerCallback {
  (identifier: string, parameters: JSComponentParameter[]): void;
}

export interface JSComponentParameter {
  name: string;
  type: JSComponentParameterType;
}