@critical-path/svelte

中文文档
0.19.11发布于 2026/11/05MITTypeScriptES Module构建来源已验证近 30 天下载 3974

Svelte 5 Runes state and reactive integrations for Critical Path headless project management framework

原始使用文档
文档目录8 节
  1. 📦 Installation
  2. 💡 Usage Examples (Svelte 5 Runes)
  3. 1. Projects & Tasks
  4. 2. Reactive Kanban Board ( KanbanState )
  5. 3. Unified Task Activity & Threaded Discussions ( TaskActiv…
  6. 4. Ladder of Abstraction ( TimelineLadderState )
  7. 🧹 Stale Requests & Cleanup
  8. 📄 License

@critical-path/svelte

Svelte 5 Runes Reactive Integrations for Critical Path.

Upgrading? Upgrade every @critical-path/* package together. Coding agents: follow UPGRADING.md; breaking changes are marked BREAKING in this package's CHANGELOG.md.

@critical-path/svelte provides Svelte 5 Runes reactive state classes and factories (ProjectState, TaskState, KanbanState, TaskTransitionsState, WorkflowState, CommentState, AttachmentState, TaskActivityState, DeliverableState, DeliverableSummaryState, WebMcpState) for building project management UIs in Svelte 5 and SvelteKit applications.


📦 Installation

npm install @critical-path/svelte svelte@^5.0.0
# or
pnpm add @critical-path/svelte svelte@^5.0.0

💡 Usage Examples (Svelte 5 Runes)

1. Projects & Tasks

<script lang="ts">
  import { onMount } from 'svelte';
  import {
    createCriticalPathClient,
    createProjectState,
    createTaskState
  } from '@critical-path/svelte';

  const client = createCriticalPathClient({ baseUrl: '/api/critical-path' });
  const projectState = createProjectState(client);
  const taskState = createTaskState(client, 'proj_1');

  onMount(() => {
    projectState.fetch();
    taskState.fetch();
  });
</script>

{#if taskState.loading || projectState.loading}
  <p>Loading tasks...</p>
{:else if taskState.error}
  <p style="color: red;">Error: {taskState.error.message}</p>
{:else}
  <ul>
    {#each taskState.data as task}
      <li><strong>{task.title}</strong> - {task.status}</li>
    {/each}
  </ul>
{/if}

2. Reactive Kanban Board (KanbanState)

Buckets tasks reactively into workflow columns (backlog, todo, in_progress, etc.) or semantic columns (not_started, in_progress, completed, canceled):

<script lang="ts">
  import { onMount } from 'svelte';
  import { createCriticalPathClient, createKanbanState } from '@critical-path/svelte';

  const client = createCriticalPathClient({ baseUrl: '/api/critical-path' });
  const kanban = createKanbanState(client, 'proj_1');

  onMount(() => {
    kanban.fetch();
  });
</script>

<div class="board" style="display: flex; gap: 16px;">
  {#each Object.entries(kanban.columns) as [status, tasks]}
    <div class="column">
      <h3>{status} ({tasks.length})</h3>
      {#each tasks as task}
        <div class="card">
          <h4>{task.title}</h4>
          <button on:click={() => kanban.moveTask(task.id, 'done')}>Mark Done</button>
        </div>
      {/each}
    </div>
  {/each}
</div>

3. Unified Task Activity & Threaded Discussions (TaskActivityState)

Combines threaded comments with inline attachments (attachment.commentId === comment.id) and standalone attachments in a single reactive store:

<script lang="ts">
  import { onMount } from 'svelte';
  import { createCriticalPathClient, createTaskActivityState } from '@critical-path/svelte';

  const client = createCriticalPathClient({ baseUrl: '/api/critical-path' });
  const activityState = createTaskActivityState(client, 'task_1');

  onMount(() => {
    activityState.fetch();
  });

  async function handleSend(text: string, fileUrl?: string) {
    await activityState.addComment(
      { content: text },
      fileUrl ? [{ filename: 'upload.png', url: fileUrl, mimeType: 'image/png', sizeBytes: 1024 }] : []
    );
  }
</script>

{#each activityState.threads as thread}
  <div class="comment">
    <p><strong>{thread.authorId}</strong>: {thread.content}</p>
    
    <!-- Inline comment attachments -->
    {#if thread.attachments.length > 0}
      <div class="attachments">
        {#each thread.attachments as att}
          <a href={att.url} target="_blank">{att.filename}</a>
        {/each}
      </div>
    {/if}

    <!-- Emoji Reactions -->
    <div class="reactions">
      <button on:click={() => activityState.addReaction(thread.id, '👍')}>👍</button>
      <button on:click={() => activityState.addReaction(thread.id, '🚀')}>🚀</button>
      <span>{thread.reactions?.length || 0} reactions</span>
    </div>

    <!-- Threaded replies -->
    {#each thread.replies as reply}
      <div class="reply">
        <p>↪ {reply.authorId}: {reply.content}</p>
      </div>
    {/each}
  </div>
{/each}

4. Ladder of Abstraction (TimelineLadderState)

Fluidly traverse between Macro phase health, Standard Gantt tasks with CPM critical paths, and Concrete deliverables/effort using Svelte 5 Runes:

<script lang="ts">
  import { onMount } from 'svelte';
  import { createCriticalPathClient, createTimelineLadderState, createCriticalPathState } from '@critical-path/svelte';

  const client = createCriticalPathClient({ baseUrl: '/api/critical-path' });
  const ladderState = createTimelineLadderState(client, 'proj_1', { level: 'all' });
  const cpmState = createCriticalPathState(client, 'proj_1');

  onMount(() => {
    ladderState.fetch();
    cpmState.fetch();
  });
</script>

<!-- Level Switcher -->
<div class="flex gap-2">
  <button on:click={() => ladderState.setLevel('macro')}>Macro</button>
  <button on:click={() => ladderState.setLevel('standard')}>Standard Gantt</button>
  <button on:click={() => ladderState.setLevel('concrete')}>Concrete</button>
  <button on:click={() => ladderState.setLevel('all')}>All Rungs</button>
</div>

{#if ladderState.loading}
  <p>Loading timeline ladder...</p>
{:else}
  <!-- Macro Rung -->
  {#if ladderState.macro}
    <div class="macro-banner">
      <h3>Phase Health: {ladderState.macro.health} ({ladderState.macro.overallProgressPercentage}% Complete)</h3>
      <p>Total Duration: {ladderState.macro.totalDurationHours}h | Critical Path: {ladderState.macro.criticalPathDurationHours}h</p>
    </div>
  {/if}

  <!-- Standard Rung -->
  {#if ladderState.standard}
    <div class="standard-gantt">
      <h4>Gantt Schedule</h4>
      {#each ladderState.standard.tasks as item}
        <div class:is-critical={item.isCritical}>
          {item.task.title} (Early Start: {item.schedule.earlyStart}h, Total Slack: {item.schedule.totalSlack}h)
        </div>
      {/each}
    </div>
  {/if}

  <!-- Concrete Rung -->
  {#if ladderState.concrete}
    <div class="concrete-grounding">
      <h4>Concrete Ground Truth</h4>
      {#each Object.entries(ladderState.concrete) as [taskId, evidence]}
        <div>Task {taskId}: {evidence.deliverables.length} deliverables, {evidence.attachments.length} files</div>
      {/each}
    </div>
  {/if}
{/if}

🧹 Stale Requests & Cleanup

Each state class aborts its previous request when fetch() (or fetchMetrics(), ...) is called again, so the newest call always wins. Call destroy() when a component goes away to cancel anything still in flight:

<script lang="ts">
  import { onDestroy } from 'svelte';
  const tasks = createTaskState(client, projectId);
  onDestroy(() => tasks.destroy());
</script>

📄 License

MIT © Critical Path

版本与发布记录

@critical-path/svelte 共发布 95 个版本,首次发布于 2026/08/24;过去 12 个月发布了 95 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.19.11latest2026/11/055 天前
0.19.102026/11/037 天前
0.19.92026/11/038 天前
0.19.82026/10/2813 天前
0.19.72026/10/2813 天前
0.19.62026/10/2813 天前

关于 @critical-path/svelte 的常见问题

@critical-path/svelte 是什么?

Svelte 5 Runes state and reactive integrations for Critical Path headless project management framework

如何安装 @critical-path/svelte?

在项目目录运行 npm install @critical-path/svelte,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:svelte(^5.57.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@critical-path/svelte 支持 TypeScript 吗?

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

@critical-path/svelte 支持 ESM 还是 CommonJS?

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

@critical-path/svelte 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@critical-path/svelte 可以商用吗?

@critical-path/svelte 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@critical-path/svelte 的下载量有多少?

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

@critical-path/svelte 还在维护吗?

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