ds-markdown 0.0.10 → 0.0.11-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md ADDED
@@ -0,0 +1,491 @@
1
+ # ds-markdown
2
+
3
+ > 🚀 高性能 React Markdown タイピングアニメーションコンポーネント、DeepSeek チャットインターフェース効果を完璧に再現
4
+
5
+ **[🇨🇳 中文](./README.md) | [🇺🇸 English](./README.en.md) | 🇯🇵 日本語 | [🇰🇷 한국어](./README.ko.md)**
6
+
7
+ 現代の AI アプリケーション向けに特別に設計された React コンポーネントで、滑らかなリアルタイムタイピングアニメーションと完全な Markdown レンダリング機能を提供します。
8
+
9
+ [![npm version](https://img.shields.io/npm/v/ds-markdown)](https://www.npmjs.com/package/ds-markdown)
10
+ [![npm downloads](https://img.shields.io/npm/dm/ds-markdown.svg)](https://www.npmjs.com/package/ds-markdown)
11
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/ds-markdown)](https://bundlephobia.com/package/ds-markdown)
12
+ [![React](https://img.shields.io/badge/React-16.8+-blue)](https://react.dev)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
14
+
15
+ [📖 ライブデモ](https://onshinpei.github.io/ds-markdown/) | [🔧 StackBlitz 体験](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
16
+
17
+ ---
18
+
19
+ ## ✨ コア機能
20
+
21
+ ### 🎯 **完璧な再現**
22
+
23
+ - [DeepSeek ウェブサイト](https://chat.deepseek.com/) チャット応答効果の 1:1 再現
24
+ - 思考プロセス(`thinking`)と回答コンテンツ(`answer`)の両モードをサポート
25
+ - コードハイライト、テーブル、リストなどを含むネイティブ Markdown 構文サポート
26
+
27
+ ### ⚡ **究極のパフォーマンス**
28
+
29
+ - スマートバッチ処理により、大容量ドキュメントでもラグゼロレンダリング
30
+ - デュアルタイマーモード:`requestAnimationFrame` + `setTimeout`
31
+ - 内蔵ストリーミング構文バッファリングで、不完全な Markdown レンダリングエラーを回避
32
+
33
+ ### 🎬 **滑らかなアニメーション**
34
+
35
+ - 高頻度タイピングサポート(`requestAnimationFrame` モードでは `0ms` に近いタイピング間隔をサポート)
36
+ - フレーム同期レンダリング、ブラウザの 60fps と完璧にマッチ
37
+ - スマート文字バッチ処理により、より自然な視覚効果
38
+
39
+ ### 🔧 **柔軟で使いやすい**
40
+
41
+ - **宣言的 API**:シンプルなシナリオに適し、React スタイル
42
+ - **命令的 API**:ストリーミングデータに適し、より良いパフォーマンス
43
+ - **ネイティブ TypeScript サポート**:完全な型ヒント
44
+
45
+ ---
46
+
47
+ ## 📦 クイックインストール
48
+
49
+ ```bash
50
+ # npm
51
+ npm install ds-markdown
52
+
53
+ # yarn
54
+ yarn add ds-markdown
55
+
56
+ # pnpm
57
+ pnpm add ds-markdown
58
+ ```
59
+
60
+ ### ESM CDN での使用
61
+
62
+ インストール不要、ブラウザで直接使用できます:
63
+
64
+ ```html
65
+ <!-- スタイルのインポート -->
66
+ <link rel="stylesheet" href="https://esm.sh/ds-markdown/style.css" />
67
+
68
+ <!-- コンポーネントのインポート -->
69
+ <script type="importmap">
70
+ {
71
+ "imports": {
72
+ "react": "https://esm.sh/react@19.1.0",
73
+ "react-dom/client": "https://esm.sh/react-dom@19.1.0/client",
74
+ "ds-markdown": "https://esm.sh/ds-markdown@0.0.10"
75
+ }
76
+ }
77
+ </script>
78
+ <script type="module" src="https://esm.sh/tsx"></script>
79
+
80
+ <script type="text/babel">
81
+ import { createRoot } from 'react-dom/client';
82
+ import DsMarkdown from 'ds-markdown';
83
+
84
+ const markdown = `
85
+ # Hello ds-markdown
86
+
87
+ これは**高性能**なタイピングアニメーションコンポーネントです!
88
+
89
+ ## 特徴
90
+ - ⚡ 遅延ゼロのストリーミング
91
+ - 🎬 スムーズなタイピングアニメーション
92
+ - 🎯 完璧なシンタックスサポート
93
+ `;
94
+
95
+ const root = createRoot(document.getElementById('root'));
96
+ root.render(<DsMarkdown interval={20}>{markdown}</DsMarkdown>);
97
+ </script>
98
+ ```
99
+
100
+ ## 🚀 5分クイックスタート
101
+
102
+ ### 基本的な使用法
103
+
104
+ ```tsx
105
+ import DsMarkdown from 'ds-markdown';
106
+ import 'ds-markdown/style.css';
107
+
108
+ function App() {
109
+ return (
110
+ <DsMarkdown interval={20} answerType="answer">
111
+ # Hello ds-markdown これは**高性能**なタイピングアニメーションコンポーネントです! ## 機能 - ⚡ ゼロ遅延ストリーミング処理 - 🎬 滑らかなタイピングアニメーション - 🎯 完璧な構文サポート
112
+ </DsMarkdown>
113
+ );
114
+ }
115
+ ```
116
+
117
+ ### AI 会話シナリオ
118
+
119
+ ```tsx
120
+ function ChatDemo() {
121
+ const [thinking, setThinking] = useState('');
122
+ const [answer, setAnswer] = useState('');
123
+
124
+ const handleAsk = () => {
125
+ setThinking('🤔 あなたの質問について考えています...');
126
+
127
+ setTimeout(() => {
128
+ setAnswer(`# React 19 について
129
+
130
+ React 19 は多くのエキサイティングな新機能をもたらします:
131
+
132
+ ## 🚀 主要アップデート
133
+ 1. **React Compiler** - 自動パフォーマンス最適化
134
+ 2. **Actions** - フォーム処理の簡素化
135
+ 3. **Document Metadata** - 内蔵 SEO サポート
136
+
137
+ これらの新機能を一緒に探求しましょう!`);
138
+ }, 2000);
139
+ };
140
+
141
+ return (
142
+ <div>
143
+ <button onClick={handleAsk}>AI に質問</button>
144
+
145
+ {thinking && (
146
+ <DsMarkdown answerType="thinking" interval={30}>
147
+ {thinking}
148
+ </DsMarkdown>
149
+ )}
150
+
151
+ {answer && (
152
+ <DsMarkdown answerType="answer" interval={15}>
153
+ {answer}
154
+ </DsMarkdown>
155
+ )}
156
+ </div>
157
+ );
158
+ }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 📚 完全 API ドキュメント
164
+
165
+ ### 宣言的 API(初心者におすすめ)
166
+
167
+ | プロパティ | 型 | 説明 | デフォルト |
168
+ | ------------- | ------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
169
+ | `interval` | `number` | タイピング間隔(ミリ秒) | `30` |
170
+ | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | タイマー型 | 現在のデフォルトは `setTimeout`、後で `requestAnimationFrame` に変更予定 |
171
+ | `answerType` | `'thinking'` \| `'answer'` | コンテンツタイプ(スタイルテーマに影響) | `'answer'` |
172
+ | `onEnd` | `(data: EndData) => void` | タイピング完了コールバック | - |
173
+ | `onStart` | `(data: StartData) => void` | タイピング開始コールバック | - |
174
+ | `onTypedChar` | `(data: CharData) => void` | 文字単位タイピングコールバック | - |
175
+
176
+ ### 命令的 API(ストリーミングシナリオにおすすめ)
177
+
178
+ ```typescript
179
+ import { MarkdownCMD, MarkdownRef } from 'ds-markdown';
180
+
181
+ interface MarkdownRef {
182
+ push: (content: string, answerType: AnswerType) => void;
183
+ clear: () => void;
184
+ triggerWholeEnd: () => void;
185
+ flushBuffer: (answerType?: AnswerType) => void;
186
+ }
187
+ ```
188
+
189
+ | メソッド | パラメータ | 説明 |
190
+ | ----------------- | ------------------------------------------- | ------------------------------------ |
191
+ | `push` | `(content: string, answerType: AnswerType)` | コンテンツを追加してタイピングを開始 |
192
+ | `clear` | - | すべてのコンテンツと状態をクリア |
193
+ | `triggerWholeEnd` | - | 手動で完了コールバックをトリガー |
194
+ | `flushBuffer` | `answerType?: AnswerType` | バッファーコンテンツを強制フラッシュ |
195
+
196
+ ---
197
+
198
+ ## 🎛️ タイマーモード詳細説明
199
+
200
+ ### `requestAnimationFrame` モード 🌟(推奨)
201
+
202
+ ```typescript
203
+ // 🎯 特徴
204
+ - 時間駆動:実際の経過時間に基づいて文字数を計算
205
+ - バッチ処理:単一フレーム内で複数文字を処理可能
206
+ - フレーム同期:ブラウザ 60fps リフレッシュレートと同期
207
+ - 高頻度最適化:interval < 16ms の高速タイピングを完璧サポート
208
+
209
+ // 🎯 適用シナリオ
210
+ - 現代 Web アプリケーションのデフォルト選択
211
+ - 滑らかなアニメーション効果を追求
212
+ - 高頻度タイピング(interval > 0 で十分)
213
+ - AI リアルタイム会話シナリオ
214
+ ```
215
+
216
+ ### `setTimeout` モード 📟(互換性)
217
+
218
+ ```typescript
219
+ // 🎯 特徴
220
+ - 単一文字:一度に正確に一文字を処理
221
+ - 固定間隔:設定時間に従って厳密に実行
222
+ - リズム感:クラシックタイプライターのリズム
223
+ - 精密制御:特定のタイミング要件に適用
224
+
225
+ // 🎯 適用シナリオ
226
+ - 精密時間制御が必要
227
+ - レトロタイプライター効果の作成
228
+ - 互換性要件の高いシナリオ
229
+ ```
230
+
231
+ ### 📊 パフォーマンス比較
232
+
233
+ | 機能 | requestAnimationFrame | setTimeout |
234
+ | -------------------------------- | ------------------------------------- | --------------------- |
235
+ | **文字処理** | フレームあたり複数文字を処理可能 | 一度に一文字を処理 |
236
+ | **高頻度間隔** | ✅ 優秀(5ms → フレームあたり3文字) | ❌ ラグの可能性 |
237
+ | **低頻度間隔** | ✅ 通常(100ms → 6フレーム後に1文字) | ✅ 精密 |
238
+ | **視覚効果** | 🎬 滑らかなアニメーション感 | ⚡ 精密なリズム感 |
239
+ | **パフォーマンスオーバーヘッド** | 🟢 低(フレーム同期) | 🟡 中程度(タイマー) |
240
+
241
+ 高頻度では `requestAnimationFrame`、低頻度では `setTimeout` を推奨
242
+
243
+ ---
244
+
245
+ ## 💡 実践例
246
+
247
+ ### 📝 AI ストリーミング会話
248
+
249
+ ````tsx
250
+ import { useRef } from 'react';
251
+ import { MarkdownCMD, MarkdownRef } from 'ds-markdown';
252
+
253
+ function StreamingChat() {
254
+ const markdownRef = useRef<MarkdownRef>(null);
255
+
256
+ // AI ストリーミング応答をシミュレート
257
+ const simulateAIResponse = async () => {
258
+ markdownRef.current?.clear();
259
+
260
+ // 思考段階
261
+ markdownRef.current?.push('🤔 あなたの質問を分析しています...', 'thinking');
262
+ await delay(1000);
263
+ markdownRef.current?.push('\n\n✅ 分析完了、回答を開始します', 'thinking');
264
+
265
+ // ストリーミング回答
266
+ const chunks = [
267
+ '# React 19 新機能分析\n\n',
268
+ '## 🚀 React Compiler\n',
269
+ 'React 19 の最大のハイライトは **React Compiler** の導入です:\n\n',
270
+ '- 🎯 **自動最適化**:手動の memo と useMemo が不要\n',
271
+ '- ⚡ **パフォーマンス向上**:コンパイル時最適化、ランタイムオーバーヘッドゼロ\n',
272
+ '- 🔧 **後方互換**:既存コードの修正不要\n\n',
273
+ '## 📝 Actions がフォームを簡素化\n',
274
+ '新しい Actions API により、フォーム処理がより簡単になります:\n\n',
275
+ '```tsx\n',
276
+ 'function ContactForm({ action }) {\n',
277
+ ' const [state, formAction] = useActionState(action, null);\n',
278
+ ' return (\n',
279
+ ' <form action={formAction}>\n',
280
+ ' <input name="email" type="email" />\n',
281
+ ' <button>送信</button>\n',
282
+ ' </form>\n',
283
+ ' );\n',
284
+ '}\n',
285
+ '```\n\n',
286
+ 'この回答がお役に立てれば幸いです!🎉',
287
+ ];
288
+
289
+ for (const chunk of chunks) {
290
+ await delay(100);
291
+ markdownRef.current?.push(chunk, 'answer');
292
+ }
293
+ };
294
+
295
+ return (
296
+ <div className="chat-container">
297
+ <button onClick={simulateAIResponse}>🤖 React 19 機能について質問</button>
298
+
299
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('段落完了:', data)} />
300
+ </div>
301
+ );
302
+ }
303
+
304
+ const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
305
+ ````
306
+
307
+ ### 🔄 ストリーミング Markdown 構文処理
308
+
309
+ **核心問題**:ストリーミング出力時、不完全な Markdown 構文がレンダリングエラーを引き起こす可能性
310
+
311
+ ```tsx
312
+ // 🚨 問題シナリオ
313
+ push('#'); // "# "
314
+ push(' '); // "# "
315
+ push('タイトル'); // "# タイトル"
316
+ push('\n'); // "# タイトル\n"
317
+ push('1'); // "# タイトル\n1" ← これは段落として誤解釈される
318
+ push('.'); // "# タイトル\n1." ← 正しいリストを形成
319
+ push(' 項目'); // "# タイトル\n1. 項目"
320
+ ```
321
+
322
+ **✅ スマートソリューション**:コンポーネント内蔵同期バッファリングメカニズム
323
+
324
+ ```tsx
325
+ // コンポーネントが構文境界を知的に処理
326
+ const handleStreamingMarkdown = () => {
327
+ const chunks = ['#', ' ', '使用', 'スキル', '\n', '1', '.', ' ', 'スキル1', '\n', '2', '.', ' スキル2'];
328
+
329
+ chunks.forEach((chunk) => {
330
+ markdownRef.current?.push(chunk, 'answer');
331
+ // 遅延不要、コンポーネント内部で知的バッファリング
332
+ });
333
+
334
+ // オプション:残りのバッファーコンテンツを手動でフラッシュ
335
+ markdownRef.current?.flushBuffer();
336
+ };
337
+
338
+ // 🧠 スマート処理フロー:
339
+ // 1. "# 使用スキル\n1" 構文不完全をリアルタイム検出
340
+ // 2. スマートバッファリング、より多くの文字を待機
341
+ // 3. "." を受信して "1." を形成後、即座に処理
342
+ // 4. ゼロ遅延、純粋同期処理
343
+ ```
344
+
345
+ **バッファーメカニズム特徴**:
346
+
347
+ - ⚡ **ゼロ遅延**:setTimeout なし、純粋同期リアルタイム処理
348
+ - 🧠 **スマート境界**:Markdown 構文ルールに基づく境界検出
349
+ - 🔄 **リアルタイム分割**:完全構文に遭遇時即座に処理、不完全時はスマートバッファリング
350
+ - 🛡️ **安全保証**:残りコンテンツを処理する `flushBuffer()` メソッドを提供
351
+
352
+ **サポートされる構文検出**:
353
+
354
+ ````typescript
355
+ // ✅ 完全構文(即座に処理)
356
+ '## タイトル'; // 完全タイトル
357
+ '1. リスト項目'; // 完全リスト項目
358
+ '- 項目'; // 完全無順序リスト
359
+ '> 引用コンテンツ'; // 完全引用
360
+ '```javascript'; // コードブロック開始
361
+ '```'; // コードブロック終了
362
+ '改行で終わるコンテンツ\n'; // 改行境界
363
+
364
+ // 🔄 不完全構文(スマートバッファリング)
365
+ '##'; // タイトル記号のみ
366
+ '1'; // 数字のみ
367
+ '```java'; // 可能なコードブロック開始
368
+ ````
369
+
370
+ ---
371
+
372
+ ## 🔧 ベストプラクティス
373
+
374
+ ### 1. パフォーマンス最適化
375
+
376
+ ```tsx
377
+ // ✅ 推奨設定
378
+ <DsMarkdown
379
+ timerType="requestAnimationFrame"
380
+ interval={15} // 15-30ms が最適体験
381
+ />
382
+
383
+ // ❌ 過小間隔を避ける
384
+ <DsMarkdown interval={1} /> // パフォーマンス問題を引き起こす可能性
385
+ ```
386
+
387
+ ### 2. ストリーミングデータ処理
388
+
389
+ ```tsx
390
+ // ✅ 推奨:命令的 API
391
+ const ref = useRef<MarkdownRef>(null);
392
+ useEffect(() => {
393
+ ref.current?.push(newChunk, 'answer');
394
+ }, [newChunk]);
395
+
396
+ // ❌ 避ける:頻繁な children 更新
397
+ const [content, setContent] = useState('');
398
+ // 各更新で全体コンテンツを再解析
399
+ ```
400
+
401
+ ### 3. 型安全
402
+
403
+ ```tsx
404
+ import { MarkdownRef } from 'ds-markdown';
405
+
406
+ const ref = useRef<MarkdownRef>(null);
407
+ // 完全な TypeScript 型ヒント
408
+ ```
409
+
410
+ ### 4. スタイルカスタマイズ
411
+
412
+ ```css
413
+ /* 思考エリアスタイル */
414
+ .ds-markdown-thinking {
415
+ background: rgba(255, 193, 7, 0.1);
416
+ border-left: 3px solid #ffc107;
417
+ padding: 12px;
418
+ border-radius: 6px;
419
+ margin: 8px 0;
420
+ }
421
+
422
+ /* 回答エリアスタイル */
423
+ .ds-markdown-answer {
424
+ color: #333;
425
+ line-height: 1.6;
426
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
427
+ }
428
+
429
+ /* コードブロックスタイル */
430
+ .ds-markdown pre {
431
+ background: #f8f9fa;
432
+ border-radius: 8px;
433
+ padding: 16px;
434
+ overflow-x: auto;
435
+ }
436
+
437
+ /* テーブルスタイル */
438
+ .ds-markdown-table {
439
+ border-collapse: collapse;
440
+ width: 100%;
441
+ margin: 16px 0;
442
+ }
443
+
444
+ .ds-markdown-table th,
445
+ .ds-markdown-table td {
446
+ border: 1px solid #ddd;
447
+ padding: 8px 12px;
448
+ text-align: left;
449
+ }
450
+ ```
451
+
452
+ ---
453
+
454
+ ## 🌐 互換性
455
+
456
+ | 環境 | バージョン要件 | 説明 |
457
+ | -------------- | ----------------------------------- | ---------------------- |
458
+ | **React** | 16.8.0+ | Hooks サポートが必要 |
459
+ | **TypeScript** | 4.0+ | オプション、ただし推奨 |
460
+ | **ブラウザ** | Chrome 60+, Firefox 55+, Safari 12+ | モダンブラウザ |
461
+ | **Node.js** | 14.0+ | ビルド環境 |
462
+
463
+ ---
464
+
465
+ ## 🤝 貢献ガイド
466
+
467
+ Issue と Pull Request の提出を歓迎します!
468
+
469
+ 1. このリポジトリをフォーク
470
+ 2. 機能ブランチを作成:`git checkout -b feature/amazing-feature`
471
+ 3. 変更をコミット:`git commit -m 'Add amazing feature'`
472
+ 4. ブランチをプッシュ:`git push origin feature/amazing-feature`
473
+ 5. Pull Request を提出
474
+
475
+ ---
476
+
477
+ ## 📄 ライセンス
478
+
479
+ MIT © [onshinpei](https://github.com/onshinpei)
480
+
481
+ ---
482
+
483
+ <div align="center">
484
+ <strong>このプロジェクトがお役に立てば、⭐️ Star でサポートしてください!</strong>
485
+
486
+ <br><br>
487
+
488
+ [🐛 問題報告](https://github.com/onshinpei/ds-markdown/issues) |
489
+ [💡 機能提案](https://github.com/onshinpei/ds-markdown/issues) |
490
+ [📖 ドキュメント参照](https://onshinpei.github.io/ds-markdown/)
491
+ </div>