loadPlugin method

Future<void> loadPlugin(
  1. JsPlugin plugin, {
  2. Map<String, Object?> initialProps = const <String, Object?>{},
  3. List<JsFeatures> features = const <JsFeatures>[],
  4. Iterable<String> grantedPermissions = const <String>[],
  5. JsUiPermissionPolicy? permissionPolicy,
})

Loads plugin, validates permissions, and commits its initial schema.

Implementation

Future<void> loadPlugin(
  JsPlugin plugin, {
  Map<String, Object?> initialProps = const <String, Object?>{},
  List<JsFeatures> features = const <JsFeatures>[],
  Iterable<String> grantedPermissions = const <String>[],
  JsUiPermissionPolicy? permissionPolicy,
}) async {
  return _enqueue(() async {
    final total = Stopwatch()..start();
    final stages = <String, Duration>{};
    var lap = Duration.zero;
    void record(String name) {
      final elapsed = total.elapsed;
      stages[name] = elapsed - lap;
      lap = elapsed;
    }

    _ensureActive();
    permissionPolicy?.validate(
      plugin: plugin,
      grantedPermissions: grantedPermissions,
    );
    final requestedFeatures = List<JsFeatures>.unmodifiable(features);
    final hostBinding = await _hostForPage(requestedFeatures, plugin);
    final host = hostBinding.host;
    record('runtimeAcquire');
    if (_disposed) {
      if (_engineBinding?.ownsEngine == true) {
        unawaited(_disposeHost(host));
      }
      return;
    }
    await _closeCurrentPage();
    record('pageCleanup');
    if (_disposed) {
      return;
    }
    if (!hostBinding.pagePluginInstalled) {
      await _loadPagePlugin(host, plugin);
    }
    record('pluginLoad');
    if (_disposed) {
      return;
    }
    _disposeLifecycleSent = false;
    final page = _JsUiPageBinding(
      plugin: plugin,
      client: JsPluginClient(host, plugin),
      props: Map<String, Object?>.unmodifiable(initialProps),
      features: requestedFeatures,
      grantedPermissions: Set<String>.unmodifiable(grantedPermissions),
      permissionPolicy: permissionPolicy,
    );
    _pageBinding = page;
    try {
      if (plugin.manifest.exports.contains('bootstrap')) {
        _validateRuntimeManifest(plugin);
        final bootstrap = await _resolveMutationResult(
          await _clientCall('bootstrap', <Object?>[page.props]),
        );
        record('bootstrap');
        if (_disposed) return;
        _applyBootstrapResult(page, bootstrap);
      } else {
        await page.client.validate();
        record('validate');
        page.lifecycleTypes = await _loadLegacyLifecycleTypes(
          page.client,
          plugin,
        );
        record('capabilities');
        final initialSnapshot = await _clientCall('mount', <Object?>[
          page.props,
        ]);
        record('stateMount');
        if (_disposed) return;
        _applySnapshot(initialSnapshot);
        await _refreshImpl();
        record('firstCommit');
      }
      inspector?.recordLifecycle('widget', 'load');
      _lastLoadMetrics = JsUiLoadMetrics(
        stages: Map<String, Duration>.unmodifiable(stages),
        totalToSchema: total.elapsed,
      );
    } catch (_) {
      if (identical(_pageBinding, page)) {
        _clearPageBinding();
      }
      rethrow;
    }
  });
}