npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teriusu/rich-editor

v0.7.12

Published

TipTap 기반 Notion-style 리치 텍스트 에디터 (Svelte)

Readme

@teriusu/rich-editor

TipTap v3 기반 리치 텍스트 에디터. Svelte 5 컴포넌트 라이브러리.

설치

npm install @teriusu/rich-editor

Tailwind CSS v4 사용 시 @source 추가:

@import "@teriusu/rich-editor/styles";
@source "../node_modules/@teriusu/rich-editor/dist";

기본 사용법

<script>
  import { TipTapEditor } from '@teriusu/rich-editor';
  import '@teriusu/rich-editor/styles';

  let html = $state('');
</script>

<TipTapEditor
  content={html}
  onChange={(h) => html = h}
  onUploadFile={async (file) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: form });
    const { url } = await res.json();
    return url;
  }}
/>

Props

| Prop | 타입 | 기본값 | 설명 | |------|------|--------|------| | content | string | "" | HTML 콘텐츠 | | onChange | (html: string) => void | 필수 | 콘텐츠 변경 콜백 | | placeholder | string | "'/'를 눌러..." | 플레이스홀더 | | onUploadFile | (file: File) => Promise<string> | - | 파일 업로드 핸들러 (URL 반환) | | onResolveFile | (fileId: string) => Promise<{src, name?, size?}> | - | 파일 ID → URL 변환 | | extensions | AnyExtension[] | [] | 추가 TipTap 확장 주입 | | editable | boolean | true | 읽기 전용 모드 |

파일 저장 방식

URL 직접 (기본)

onUploadFile만 제공하면 파일 URL이 HTML에 직접 저장됩니다.

<div data-file-src="/files/report.pdf" data-file-name="report.pdf" data-file-size="204800"></div>

ID 기반 (하이브리드)

onResolveFile을 추가하면 파일 ID + 캐시 URL이 함께 저장됩니다.

<TipTapEditor
  content={html}
  onChange={(h) => html = h}
  onUploadFile={async (file) => {
    const res = await fetch('/api/upload', { method: 'POST', body: file });
    return await res.json(); // { id, url, name, size }
  }}
  onResolveFile={async (fileId) => {
    const res = await fetch(`/api/files/${fileId}`);
    return await res.json(); // { src, name, size }
  }}
/>
<div data-file-id="abc123" data-file-src="/files/report.pdf" data-file-name="report.pdf"></div>

ID 기반은 URL이 변경되어도 대응 가능하고, 권한 제어(signed URL)에 활용할 수 있습니다.

기능

텍스트 서식

Bold, Italic, Underline, Strikethrough, Highlight, Superscript, Subscript, 텍스트 색상

구조

제목 (H1~H3), 글머리/번호 목록, 체크리스트, 인용문, 구분선, 접기/펼치기 (Details), 들여쓰기 (Tab/Shift-Tab)

미디어

이미지, PDF (PDF.js 캔버스 렌더링), 영상 파일 (mp4/webm), YouTube, 파일 첨부, 드래그 앤 드롭 업로드

레이아웃

2단/3단 컬럼, 텍스트 정렬 (좌/중/우)

테이블

삽입, 행/열 추가/삭제, 헤더 토글, 셀 병합/분할, 셀 배경색, 열 리사이즈

입력

/ 슬래시 커맨드, 고정 툴바, 테이블 버블 메뉴, Undo/Redo

레거시 HTML 호환

TipTap v2 커스텀 태그를 자동 변환합니다. 에디터 로드 시 transformLegacyHtml이 자동 호출됩니다.

| 레거시 태그 | 변환 결과 | |---|---| | <tiptap-file id="X"> | <div data-file-id="X"> | | <tiptap-midibus id="X"> | iframe (play.mbus.tv) | | <tiptap-collapsable title="X"> | <details><summary> | | <lite-youtube videoid="X"> | YouTube iframe | | <embed type="application/pdf"> | <div data-pdf-src> | | <div class="tiptap-columns"> | <div data-type="columns"> | | margin-left: 40px | indent level 1 (em 출력) |

게시물 조회 페이지(읽기 전용)에서도 적용:

import { transformLegacyHtml } from '@teriusu/rich-editor';

const html = transformLegacyHtml(post.content);

커스텀 확장 주입

extensions prop으로 호스트 앱 전용 확장을 주입할 수 있습니다.

<script>
  import { TipTapEditor } from '@teriusu/rich-editor';
  import { Node } from '@tiptap/core';

  const MyExtension = Node.create({ /* ... */ });
</script>

<TipTapEditor
  content={html}
  onChange={handleChange}
  extensions={[MyExtension]}
/>

Exports

컴포넌트

TipTapEditor, FixedToolbar, BubbleToolbar, SlashCommandMenu, TableBubbleMenu, InputModal, PdfViewer

확장

PdfBlock, FileAttachment, VideoBlock, Columns, Column, Indent, FixedDetails

유틸리티

transformLegacyHtml, sanitizeHtml, stripHtmlToExcerpt, configurePdfJs, getPdfJs, cn

타입

UploadHandler, FileResolver, FileResolveResult, TipTapEditorProps, SlashMenuItem

빌드 / 배포

npm run build          # svelte-package → dist/
npm test               # vitest

배포는 main 브랜치 push 시 GitHub Actions가 자동 수행 (.github/workflows/publish.yml). 수동 npm publish는 사용하지 않음.

버전 정책 (SemVer)

| 단계 | 조건 | 커밋 타입 | |------|------|-----------| | patch (0.0.x) | 버그 수정, 내부 리팩토링, 스타일 조정, 의존성 patch | fix:, chore:, refactor:, style: | | minor (0.x.0) | 하위 호환 기능 추가 (새 prop, 새 extension, 새 toolbar feature) | feat: | | major (x.0.0) | 깨는 변경 (prop 제거·rename, peer dep major bump, export 경로 변경) | feat!: / BREAKING CHANGE: |

0.x대에서는 관행상 minor도 breaking일 수 있음. 호스트 앱은 ^0.5.3 대신 ~0.5.3 사용을 권장.

릴리스 플로우

  1. patch만 필요한 변경: 소스 수정 후 main에 push → CI가 package.json의 버전이 이미 publish된 최신과 같으면 자동 patch bump 후 publish
  2. minor / major 변경: push 전에 수동 bump
    npm version minor --no-git-tag-version   # 또는 major
    git add package.json package-lock.json
    git commit -m "chore: v$(node -p 'require(\"./package.json\").version')"
    git push
    CI가 "이미 bump됨"을 감지하고 그 버전으로 publish.

자동 전파

publish 성공 시 repository_dispatch (rich-editor-published) 이벤트가 다음 repo로 전송되고, 각 repo의 update-* 워크플로우가 package.json을 새 버전으로 업데이트 + 커밋:

  • teriusu-ko/hancomac@teriusu/rich-editor
  • HancomAC/trinityapps/jungol, apps/codepass@teriusu/rich-editor

teriusu-ko/teriusu는 현재 수동 업데이트 (hook 미설정 — GH_PAT secret 추가 시 연결 가능).

기술 스택

| 구분 | 기술 | |------|------| | 에디터 엔진 | TipTap v3 | | UI | Svelte 5 (runes) | | 언어 | TypeScript | | 빌드 | svelte-package | | 아이콘 | lucide-svelte | | 스타일 | Tailwind CSS + CSS 변수 |