@cloud-ru/ds-context-kit

中文文档
1.0.0发布于 2026/08/18Apache-2.0TypeScriptESM + CJS零依赖近 30 天下载 2万

Основа всех сквозных провайдеров дизайн-системы — версионно-устойчивый React-контекст-синглтон поверх useSyncExternalStore, безопасный для SSR и микрофронтов.

原始使用文档
文档目录8 节
  1. Когда использовать
  2. Установка
  3. Примеры использования
  4. Статический провайдер — createSharedContext
  5. Реактивный провайдер — createSharedStoreContext
  6. Статичное значение в стор — staticStore
  7. Ключ контекста — providerKey
  8. Как это работает

Context Kit

@cloud-ru/ds-context-kit — Основа всех сквозных провайдеров дизайн-системы — версионно-устойчивый React-контекст-синглтон поверх useSyncExternalStore, безопасный для SSR и микрофронтов.

@cloud-ru/ds-context-kit — низкоуровневый примитив, на котором построены все сквозные провайдеры дизайн-системы (@cloud-ru/ds-theme, @cloud-ru/ds-adaptive, @cloud-ru/ds-locale, @cloud-ru/ds-portal-context). Он решает три задачи, общие для всех контекстов в монорепо:

  • Синглтон контекста — объект React-контекста хранится в реестре по ключу Symbol.for, поэтому остаётся единым даже при нескольких копиях пакета в дереве (частый случай в микрофронтах).
  • Реактивное значение через useSyncExternalStore — статичный проп оборачивается в стор, внешний реактивный источник (стор хост-приложения) передаётся напрямую; изменение доходит до подписчиков без перерендера провайдера.
  • SSR-безопасность — getServerSnapshot отдаёт request-scoped значение; на globalThis хранится только иммутабельный объект контекста, не значение, поэтому между запросами ничего не утекает.

Прикладной код обычно потребляет не этот примитив напрямую, а готовые провайдеры. @cloud-ru/ds-context-kit нужен для создания нового сквозного провайдера.

Когда использовать

  • Нужен новый провайдер уровня приложения, значение которого должны читать компоненты из разных пакетов/микрофронтов.
  • Провайдер обязан быть устойчивым к нескольким версиям пакета в одном бандле (MFE).
  • Значение приходит либо пропом (статично, SSR), либо из внешнего реактивного стора (observable / redux / zustand).

Полная модель и рецепты подключения готовых провайдеров — в паттерне Провайдеры — быстрый старт.

Установка

pnpm add @cloud-ru/ds-context-kit
import { createSharedContext, createSharedStoreContext, providerKey, staticStore } from '@cloud-ru/ds-context-kit'

Примеры использования

Статический провайдер — createSharedContext

Для провайдеров, у которых значение приходит пропом (тема, локаль, portal-root). Обёртка заворачивает value в staticStore и мемоизирует его по ссылке.

import { createSharedContext, providerKey } from '@cloud-ru/ds-context-kit';

type Lang = { lang: string; fallbackLang: string };

const DEFAULT_LANG: Lang = { lang: 'en-GB', fallbackLang: 'en-GB' };

// Ключ собирается через providerKey('<домен>', <контракт-версия>).
const { Provider, useValue } = createSharedContext<Lang>({
  key: providerKey('locale', 1),
  defaultValue: DEFAULT_LANG,
});

// Провайдер в корне приложения:
<Provider value={{ lang: 'ru-RU', fallbackLang: 'en-GB' }}>{app}</Provider>;

// Чтение в любом компоненте ниже по дереву:
function Consumer() {
  const { lang } = useValue();
  return <span>{lang}</span>;
}

Реактивный провайдер — createSharedStoreContext

Когда значение приходит из внешнего реактивного источника (стор хост-приложения). Обновление стора доходит до всех подписчиков во всех микрофронтах без перерендера провайдера.

import { createSharedStoreContext, ExternalStore, providerKey } from '@cloud-ru/ds-context-kit';

type LayoutType = 'mobile' | 'tablet' | 'desktopSmall' | 'desktop';

const fallbackStore: ExternalStore<LayoutType> = {
  subscribe: () => () => {},
  getSnapshot: () => 'desktop',
  getServerSnapshot: () => 'desktop', // детерминированный SSR-baseline
};

const { StoreProvider, useStoreValue } = createSharedStoreContext<LayoutType>(
  providerKey('adaptive-context', 1),
  fallbackStore,
);

// Адаптер внешнего реактивного источника в ExternalStore:
const store: ExternalStore<LayoutType> = {
  subscribe: onChange => layoutSource.subscribe(onChange),
  getSnapshot: () => layoutSource.get(),
};

<StoreProvider store={store}>{mfe}</StoreProvider>;

function Consumer() {
  const layoutType = useStoreValue();
  return <span>{layoutType}</span>;
}

Статичное значение в стор — staticStore

Превращает фиксированное значение в ExternalStore: подписка — no-op, snapshot стабилен по ссылке. Используется внутри createSharedContext и как SSR-baseline.

import { staticStore } from '@cloud-ru/ds-context-kit';

const store = staticStore({ colorScheme: 'light' });
store.getSnapshot(); // → { colorScheme: 'light' } (та же ссылка)

Ключ контекста — providerKey

Строит стабильный ключ реестра @cloud-ru/ds:<домен>:v<контракт-версия>. Контракт-версия — версия формы значения контекста, ортогональная мажору пакета; повышается только при несовместимой смене значения. В dev-режиме выводит предупреждение, если в одном JS-контексте (один globalThis) зарегистрированы две разные контракт-версии одного домена (ранний сигнал о смешанных мажорах в MFE).

import { providerKey } from '@cloud-ru/ds-context-kit';

providerKey('theme-appearance', 1); // → '@cloud-ru/ds:theme-appearance:v1'

Как это работает

  • Синглтон. createSharedStoreContext хранит объект React-контекста в globalThis[Symbol.for(registryKey)]. Любая копия пакета — любой версии, при любом неполном dedupe — резолвится в один и тот же объект контекста в пределах одного globalThis, поэтому провайдер из одной копии виден консьюмеру из другой.
  • Реактивность. Консьюмеры читают значение через useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot). Статичное значение оборачивается в staticStore, реактивный источник передаётся напрямую.
  • Контракт-версия. providerKey('<домен>', N) отделяет версию формы значения от мажора пакета: пока изменения значения аддитивны, ключ остаётся прежним, и разные мажоры пакета продолжают разделять контекст. Несовместимая смена формы → повышение N → изолированные контексты (fail-safe: значение по умолчанию, без сбоя).

版本与发布记录

@cloud-ru/ds-context-kit 共发布 1 个版本,首次发布于 2026/08/18;过去 12 个月发布了 1 个版本。

版本发布日期距今
1.0.0latest2026/08/182 个月前

关于 @cloud-ru/ds-context-kit 的常见问题

@cloud-ru/ds-context-kit 是什么?

Основа всех сквозных провайдеров дизайн-системы — версионно-устойчивый React-контекст-синглтон поверх useSyncExternalStore, безопасный для SSR и микрофронтов.

如何安装 @cloud-ru/ds-context-kit?

在项目目录运行 npm install @cloud-ru/ds-context-kit,或使用 pnpm add / yarn add / bun add。

@cloud-ru/ds-context-kit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cloud-ru/ds-context-kit 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cloud-ru/ds-context-kit 可以商用吗?

@cloud-ru/ds-context-kit 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@cloud-ru/ds-context-kit 的下载量有多少?

根据 npm 官方下载统计,@cloud-ru/ds-context-kit 在 2026/10/10 – 2026/11/08 这 30 天内被下载 20,430 次,日均约 681 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cloud-ru/ds-context-kit 还在维护吗?

最新版本 1.0.0 发布于 2026/08/18(2 个月前);至今共发布 1 个版本,其中过去 12 个月发布了 1 个;首次发布于 2026/08/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。