async function init()

in packages/runtime/src/dataLoader.ts [208:275]


async function init(loaders: Loaders, options: Options) {
  const {
    fetcher,
    decorator,
    runtimeModules,
    appExport,
  } = options;

  const runtimeApi = {
    appContext: {
      appExport,
    },
  };

  if (runtimeModules) {
    await Promise.all(runtimeModules.map(module => {
      const runtimeModule = ((module as CommonJsRuntime).default || module) as StaticRuntimePlugin;
      return runtimeModule(runtimeApi);
    }).filter(Boolean));
  }

  if (fetcher) {
    setFetcher(fetcher);
  }

  if (decorator) {
    setDecorator(decorator);
  }

  try {
    loadInitialDataInClient(loaders);
  } catch (error) {
    console.error('Load initial data error: ', error);
  }

  (window as any).__ICE_DATA_LOADER__ = {
    getLoader: (id) => {
      return loaders[id];
    },
    getData: (id, options: LoadRoutesDataOptions) => {
      let result;

      // First render for ssg use data from build time, second render for ssg will use data from data loader.
      const cacheKey = `${id}${options?.renderMode === 'SSG' ? '_ssg' : ''}`;

      // In CSR, all dataLoader is called by global data loader to avoid bundle dataLoader in page bundle duplicate.
      result = cache.get(cacheKey);
      // Always fetch new data after cache is been used.
      cache.delete(cacheKey);

      // Already send data request.
      if (result) {
        return result.value;
      }

      const dataLoaderConfig = loaders[id];

      // No data loader.
      if (!dataLoaderConfig) {
        return null;
      }

      // Call dataLoader.
      const { loader } = dataLoaderConfig;
      return callDataLoader(loader, options?.requestContext || getRequestContext(window.location));
    },
  };
}