@burdenoff/fe-libs

中文文档
2026.1108.3发布于 2026/11/08TypeScriptES Module近 30 天下载 4.9万

Burdenoff frontend primitives and domain libraries

原始使用文档
文档目录16 节
  1. Architecture
  2. Package Structure
  3. Usage
  4. Development
  5. Components
  6. Workflow Primitives
  7. Button
  8. Shared
  9. shell-native (app shells only)
  10. Native preview flag
  11. Build-time config generators
  12. Raw colours, canvas tokens and the shared ESLint guard
  13. Explicit product analytics and withdrawal
  14. Tech Stack
  15. Export migration (BOFF-9417)
  16. Captured workspace actions

@burdenoff/fe-libs

Frontend primitives and domain libraries for all Burdenoff products.

Architecture

This is a Layer 1 package - a monolithic package with subpath exports for all primitives.

Package Structure

@burdenoff/fe-libs/
├── /workflow    - Workflow primitives (Node, Canvas, Edge)
├── /tag         - Tag components
├── /form        - Form components
├── /button      - Button primitives
└── /shared      - Shared utilities (cn, types)

Usage

import { Button } from '@burdenoff/fe-libs/button';
import { mockProducts } from '@burdenoff/fe-libs/shared/utils/mockData';
import { cn } from '@burdenoff/fe-libs/shared';

Development

# Install dependencies
bun install

# Build library
bun run build

# Type check
bun run type:check

# Run all checks
bun run sanity

Components

Workflow Primitives

  • WorkflowNode - Renders a workflow node with status indicators
  • WorkflowCanvas - Canvas component for workflow builder with grid background

Button

  • Button - Versatile button component with variants (default, destructive, outline, secondary, ghost, link)

Shared

  • cn - Utility for merging Tailwind classes

shell-native (app shells only)

@burdenoff/fe-libs/shell-native is the shell-side native runtime: Capacitor (iOS/Android), Electron desktop and PWA wiring in one entry point. App shells import it; microfrontends never do — MFEs talk to the shell through window.__burdenoffNativeBridge (@burdenoff/fe-libs/shared/native).

Boot it once in main.tsx, before React mounts:

import { bootNativeShell, registerDeepLinkNavigator } from '@burdenoff/fe-libs/shell-native';

const shell = bootNativeShell({
  product: 'vibecontrols',
  appName: 'VibeControls',
  // Optional plugins are loaded ONLY through these loaders, so web-only shells
  // never bundle them.
  plugins: {
    updater: () => import('@capgo/capacitor-updater'),
    pushNotifications: () => import('@capacitor/push-notifications'),
  },
  push: { enabled: true, onToken: (token) => void registerDevice(token) },
  runtimeHooks: { syncPendingOperations: refetchAll, saveState: flushDrafts },
});

// Inside the router:
registerDeepLinkNavigator((path) => navigate(path));
// After the first meaningful paint:
void shell.markAppReady();

Boot order (each step is individually try/caught — boot never throws): preview → OTA notifyAppReady → auth-redirect intercept → external URL opener → native bridge + platform classes → device info → status-bar theme listener → keyboard → Android back button → deep links → network → app-state hooks → push listeners → splash safety timer (native) → PWA service worker (web) → desktop shell boot.

Contracts the shells and MFEs can rely on:

  • Window globals — __burdenoffNativeBridge, __burdenoffDeviceInfo, __burdenoffOpenExternal(url), __burdenoffPushToken, __burdenoffPwaInstallPrompt.
  • Body classes — platform-ios | platform-android | platform-web, platform-native, platform-preview, keyboard-open. <html> carries data-platform and (in preview) data-native-preview.
  • CSS var — --keyboard-height (0px when closed).
  • Window events — burdenoff:appReady, burdenoff:appStateChange, burdenoff:networkStatusChange, burdenoff:keyboardWillShow|DidShow|WillHide|DidHide, burdenoff:pushToken, burdenoff:pwaUpdateReady, burdenoff:pwaInstalled, burdenoff:pwaInstallAvailable. The shell listens for burdenoff:statusBarTheme.

Native preview flag

?__nativePreview=ios|android|pwa|desktop renders the installed-app chrome in a plain browser (persisted in sessionStorage, cleared with off). It is presentation only — real plugin calls stay gated on Capacitor.isPluginAvailable, and the flag is ignored inside a real native app.

Build-time config generators

defineCapacitorConfig(nativeConfig), defineWebManifest(nativeConfig) and renderServiceWorker(nativeConfig, version) are pure functions (no @capacitor/* imports) that emit each product's capacitor.config.ts, public/manifest.json and public/sw.js from its native.config.json (NativeConfig).

Raw colours, canvas tokens and the shared ESLint guard

UI code uses semantic tokens only. createEslintConfig() from @burdenoff/fe-libs/shared/config/eslint.config.mjs reports, as an error, hex / rgb() / hsl() / oklch() literals and Tailwind palette classes (bg-red-500, text-white, border-t-gray-200, …) in string literals and template strings. Comments and test files are not checked.

  • A repo that still carries raw-colour debt can pass rawColors: 'warn' while it sweeps; treat that as a tracked, temporary opt-out.
  • A repo with a standalone ESLint config applies the same guard with 'no-restricted-syntax': ['error', ...rawColorRestrictedSyntax()].

Workflow builders, graphs and mappers use the canvas tokens in tokens.css. Each one aliases an existing chart-* / status-* / surface token, so it follows light/dark mode, the brand and the expressive themes:

GroupTokens
Canvas--color-canvas-{bg,grid,selection,minimap-bg,minimap-node,minimap-mask,control-bg}
Node surface--color-node-{bg,bg-hover,border,border-hover,border-selected,text,text-muted,handle,handle-connected}
Node category--color-node-{trigger,action,logic,loop,data,integration,ai,human,utility,end,default} plus -subtle
Node state--color-node-state-{idle,queued,running,success,warning,error,skipped}
Edge--color-edge-{default,hover,selected,active,success,error,compatible,incompatible,label-bg,label-text}
Data type--color-datatype-{string,number,boolean,object,array,date,binary,any}

app-shell.css maps them to Tailwind utilities (bg-node-trigger, stroke-edge-default, ring-node-state-running, …). A shell with its own @theme imports @burdenoff/fe-libs/shared/styles/canvas-theme.css instead. For React Flow props, SVG attributes and inline styles, use the helpers in @burdenoff/fe-libs/shared/utils (nodeCategoryColor, edgeColor, nodeStateColor, dataTypeColor, chartSeriesColor(chartSeriesIndex(key))) and the literal class records (nodeCategoryClasses, nodeStateRingClasses, dataTypeTextClasses).

Explicit product analytics and withdrawal

ComradeCircle's default observability configuration uses the shared Rybbit sink's explicit event transport rather than the provider script's automatic capture. It sends only the five reviewed comradecircle.* funnel facts, resolves known route templates, and never includes resource IDs, query strings, fragments, page titles, referrers, cookies or bearer headers. The public ingestion endpoint requires a public site ID, not a client-side API key.

The host must set privacyConsent: true and privacyConsentReopen: true. The latter keeps a Privacy choices control visible after a decision so people can withdraw or change their choice. Consent, GPC and DNT are checked before every event. Withdrawal and unmount abort outstanding requests; the sink has no replay/retry queue. Alpha has no default site and does not reuse the production site. MFEs still emit typed events through useEventBus() only.

eventEndpoint and routeTemplates are opt-in AppShellObservabilityConfig.rybbit options. Unmatched routes fail closed in explicit mode. Other products keep their existing script mode; this product adoption is not a claim that the legacy provider's automatic listeners support revocation. The original script-loading criterion is replaced by explicit-ingestion verification because removing a loaded third-party script does not remove the listeners it installed.

Tech Stack

  • React 19
  • TypeScript 5.9+
  • TailwindCSS v4
  • Radix UI (for accessible primitives)
  • Vite 7 (for building)

Export migration (BOFF-9417)

Beginning with the first CalVer release containing BOFF-9417, the already nonfunctional @burdenoff/fe-libs/workflow export metadata is explicitly retired. Both advertised targets (dist/workflow.js and dist/workflow.d.ts) are absent from the verified published 2026.1016.3 package. The former WorkflowCanvas/WorkflowNode implementation was deliberately removed in source commit f0920f9a on 2026-01-15; this change does not remove a working runtime implementation or restore that obsolete UI. Existing published releases are unchanged. Usage outside the bounded local repository inventory is unknown; this is not a claim that external consumers do not exist.

Current workflow-builder functionality belongs to @burdenoff/fluidgrids-fe-sdk (WorkflowBuilder and WorkflowBuilderCore), not another microfrontend import. Those APIs differ from the deleted generic canvas/node props and require an explicit consumer migration; they are not a drop-in compatibility adapter. Consumers should review their intended workflow behavior before choosing that API.

The existing @burdenoff/fe-libs/shared/utils/mockData subpath is retained. Its five fixture arrays now have an explicit runtime build entry alongside their declarations. The archive verifier checks literal export/bin targets in the actual npm tar before publication; wildcard export patterns and universal consumer compatibility are not certified by that existence check. Normal release automation assigns the concrete CalVer version; this source note does not claim publication or host adoption.

Captured workspace actions

Use graphqlFetchPinned when a request belongs to a captured actor or workspace. Its named export also makes an incompatible host-library pin fail during the build. It refuses a missing or expired captured bearer before dispatch and never substitutes the account bearer from profile storage, refreshes the account session, or replays a response. Specify authority and context through the typed request options; pinned mode refuses alternate workspace/context overrides in extraHeaders. The caller supplies the current credential after normal session renewal and reviews a failed or ambiguous mutation before attempting it again.

For workspace authority, reuse the shared preparation guard:

const prepared = await prepareWorkspaceRequest({
  url: resolveGatewayUrl('workspace', baseUrl),
  authToken,
  actorId,
  workspaceId,
  tenantId,
  currentQuery: query,
  signal,
});
prepared.assertCurrent();
const response = await graphqlFetchPinned({
  gateway: 'workspace',
  baseUrl,
  query,
  variables,
  authToken,
  workspaceId,
  workspaceToken: prepared.workspaceToken,
  signal,
});

prepareWorkspaceRequest binds profile, actor and workspace authority and checks concurrent changes during token issuance. Pass the captured request context and cancel obsolete reads when the surrounding identity changes. Partition and remount UI query observers by actor/context as well; a response-cache key alone does not bind a request's credentials. The default refreshable mode retains profile-based session recovery. Existing explicit-token consumers need an individual authority/refresh review before adopting pinned behavior; this additive API does not retroactively repair those callers.

版本与发布记录

@burdenoff/fe-libs 共发布 613 个版本,首次发布于 2026/05/11;过去 12 个月发布了 613 个版本。

版本发布日期距今
2026.1108.3latest2026/11/08今天
2026.1108.22026/11/08今天
2026.1108.12026/11/08今天
2026.1107.62026/11/081 天前
2026.1107.52026/11/081 天前
2026.1107.42026/11/071 天前

关于 @burdenoff/fe-libs 的常见问题

@burdenoff/fe-libs 是什么?

Burdenoff frontend primitives and domain libraries

如何安装 @burdenoff/fe-libs?

在项目目录运行 npm install @burdenoff/fe-libs,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)、graphql(^16.12.0)、zustand(^5.0.5)、react-dom(^19.0.0)、react-router(^8.3.0)、@apollo/client(^4.0.9)、@tanstack/react-query(^5.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 a11y-audit、burdenoff-i18n、graphql-schema-drift,可以用 npx a11y-audit 直接运行。

@burdenoff/fe-libs 支持 TypeScript 吗?

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

@burdenoff/fe-libs 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@burdenoff/fe-libs 可以商用吗?

@burdenoff/fe-libs 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@burdenoff/fe-libs 的下载量有多少?

根据 npm 官方下载统计,@burdenoff/fe-libs 在 2026/10/09 – 2026/11/07 这 30 天内被下载 49,100 次,日均约 1,637 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@burdenoff/fe-libs 还在维护吗?

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