@edv4h/usketch-plugin-timter

中文文档
0.3.22发布于 2026/11/10MITTypeScriptES Module构建来源已验证近 30 天下载 2380
原始使用文档
文档目录5 节
  1. Install
  2. Customizing the shape's look — renderShape
  3. Extend, don't replace
  4. Adding a timer type — registerTimerKind
  5. Model exports

@edv4h/usketch-plugin-timter

Shared timers as canvas shapes (single source of truth). A timer shape is placeable/movable and syncs through the normal shapes map; timing runs against a shared ServerClock so every user agrees on "now". The plugin also surfaces every timer in the Debug HUD's Controls dock (group "Timter").

The domain model (timer-model) is pure, framework-free, and time-source agnostic — every function takes an explicit serverNow.

Install

import { createTimterPlugin } from "@edv4h/usketch-plugin-timter";

const timter = createTimterPlugin({
  serverClock, // your shared ServerClock
  userId,      // optional, attribution (reserved)
});

Customizing the shape's look — renderShape

By default the timer renders with a built-in visual. To match your own design (hand-drawn theme, design tokens, custom controls), pass a renderShape render-prop. It receives the shape, its live TimerCore, a fresh serverNow (recomputed on every self-tick while running), and the timer actions. The plugin owns the tick and the store writes — your renderer only draws and calls actions.

import {
  createTimterPlugin,
  displayMs,
  formatDuration,
  isDone,
} from "@edv4h/usketch-plugin-timter";

createTimterPlugin({
  serverClock,
  renderShape: ({ shape, core, serverNow, actions }) => (
    <div className="my-timer" data-done={isDone(core, serverNow)}>
      <span className="my-timer__time">
        {formatDuration(displayMs(core, serverNow))}
      </span>
      <button type="button" onClick={actions.toggle}>
        {shape.running ? "pause" : "start"}
      </button>
      <button type="button" onClick={actions.reset}>reset</button>
    </div>
  ),
});

actions:

actioneffect
toggle()start if paused, pause if running
reset()back to the configured, stopped state
switchType()advance to the next registered kind (paused only)
adjust(deltaMs)change the configured duration by deltaMs (duration-based kinds, paused only)

Buttons should call e.stopPropagation() on onPointerDown so the click doesn't start a canvas drag — see defaultRenderTimerShape for the pattern.

Extend, don't replace

defaultRenderTimerShape is exported, so you can wrap the built-in visual instead of rewriting it:

import { defaultRenderTimerShape } from "@edv4h/usketch-plugin-timter";

createTimterPlugin({
  serverClock,
  renderShape: (ctx) => (
    <div className="my-frame">{defaultRenderTimerShape(ctx)}</div>
  ),
});

Adding a timer type — registerTimerKind

countdown and stopwatch are built in. Register your own kind (e.g. pomodoro) once at startup; the model transitions, the shape renderer, and the Controls dock all treat it like a built-in. switchType() cycles through every registered kind.

import { registerTimerKind, TIMER_KINDS } from "@edv4h/usketch-plugin-timter";

registerTimerKind("pomodoro", {
  ...TIMER_KINDS.countdown, // reuse countdown transitions
  icon: "🍅",
  // always a 25-minute work block
  initial: () => ({ anchorAt: null, accumMs: 25 * 60_000, durationMs: 25 * 60_000 }),
});

A TimerKind defines pure transitions over TimerCore:

interface TimerKind {
  icon?: string; // glyph used by the built-in renderer / Controls dock
  displayMs(c, serverNow): number;
  isDone(c, serverNow): boolean;
  onStart(c, serverNow): Pick<TimerCore, "anchorAt" | "accumMs">;
  onPause(c, serverNow): Pick<TimerCore, "anchorAt" | "accumMs">;
  initial(durationMs): Pick<TimerCore, "anchorAt" | "accumMs" | "durationMs">;
}

Model exports

start · pause · reset · initialCore · displayMs · isDone · formatDuration · getTimerKind · timerTypes · registerTimerKind · TIMER_KINDS — plus types TimerCore · TimerType · TimerKind.

Shape exports: TIMER_SHAPE_TYPE · TimerShapeData · defaultRenderTimerShape · makeTimerShape · dispatchTimerShapeAction — plus types TimerShapeRenderer · TimerRenderContext · TimerShapeActions.

版本与发布记录

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

版本发布日期距今
0.3.22latest2026/11/103 天前
0.3.212026/11/103 天前
0.3.202026/11/067 天前
0.3.182026/11/0310 天前
0.3.172026/11/0211 天前
0.3.162026/10/2519 天前

关于 @edv4h/usketch-plugin-timter 的常见问题

如何安装 @edv4h/usketch-plugin-timter?

在项目目录运行 npm install @edv4h/usketch-plugin-timter,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=19)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@edv4h/usketch-plugin-timter 支持 TypeScript 吗?

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

@edv4h/usketch-plugin-timter 支持 ESM 还是 CommonJS?

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

@edv4h/usketch-plugin-timter 可以商用吗?

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

@edv4h/usketch-plugin-timter 的下载量有多少?

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

@edv4h/usketch-plugin-timter 还在维护吗?

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