@shuji-bonji/rfcxml-mcp 0.1.2 → 0.1.3

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.
@@ -0,0 +1,100 @@
1
+ /**
2
+ * 並列フェッチユーティリティ
3
+ * 複数ソースから最速で成功したレスポンスを返す
4
+ */
5
+ import { HTTP_CONFIG } from '../config.js';
6
+ /**
7
+ * 複数ソースから並列でフェッチし、最初に成功したものを返す
8
+ * 成功後は他のリクエストをキャンセル
9
+ */
10
+ export async function fetchFromMultipleSources(sources, options = {}) {
11
+ const { headers = {}, timeout = HTTP_CONFIG.timeout, validate = () => true } = options;
12
+ // 全リクエストをキャンセルするための AbortController
13
+ const controller = new AbortController();
14
+ const { signal } = controller;
15
+ // 各ソースのフェッチを Promise に変換
16
+ const fetchPromises = sources.map(async ({ name, url }) => {
17
+ try {
18
+ const response = await fetchWithTimeout(url, {
19
+ headers: {
20
+ 'User-Agent': HTTP_CONFIG.userAgent,
21
+ ...headers,
22
+ },
23
+ signal,
24
+ timeout,
25
+ });
26
+ if (!response.ok) {
27
+ throw new Error(`HTTP ${response.status}`);
28
+ }
29
+ const text = await response.text();
30
+ // バリデーション
31
+ if (!validate(text)) {
32
+ throw new Error('Validation failed');
33
+ }
34
+ return { text, source: name };
35
+ }
36
+ catch (error) {
37
+ // AbortError は無視(他のソースが成功したため)
38
+ if (error instanceof Error && error.name === 'AbortError') {
39
+ throw error;
40
+ }
41
+ // それ以外のエラーは詳細を付けて再スロー
42
+ throw new Error(`[${name}] ${error instanceof Error ? error.message : String(error)}`);
43
+ }
44
+ });
45
+ try {
46
+ // Promise.any: 最初に成功したものを返す
47
+ const result = await Promise.any(fetchPromises);
48
+ // 成功したら他のリクエストをキャンセル
49
+ controller.abort();
50
+ return result;
51
+ }
52
+ catch (error) {
53
+ // すべて失敗した場合
54
+ controller.abort();
55
+ if (error instanceof AggregateError) {
56
+ const messages = error.errors.map((e) => e.message).join('; ');
57
+ throw new Error(`All sources failed: ${messages}`);
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ /**
63
+ * タイムアウト付きフェッチ
64
+ */
65
+ async function fetchWithTimeout(url, options) {
66
+ const { timeout = HTTP_CONFIG.timeout, ...fetchOptions } = options;
67
+ // タイムアウト用の AbortController
68
+ const timeoutController = new AbortController();
69
+ const timeoutId = setTimeout(() => timeoutController.abort(), timeout);
70
+ // 外部からの signal と タイムアウト signal を組み合わせる
71
+ const combinedSignal = options.signal
72
+ ? combineAbortSignals(options.signal, timeoutController.signal)
73
+ : timeoutController.signal;
74
+ try {
75
+ const response = await fetch(url, {
76
+ ...fetchOptions,
77
+ signal: combinedSignal,
78
+ });
79
+ return response;
80
+ }
81
+ finally {
82
+ clearTimeout(timeoutId);
83
+ }
84
+ }
85
+ /**
86
+ * 複数の AbortSignal を組み合わせる
87
+ * どちらかが abort されたら結合シグナルも abort
88
+ */
89
+ function combineAbortSignals(...signals) {
90
+ const controller = new AbortController();
91
+ for (const signal of signals) {
92
+ if (signal.aborted) {
93
+ controller.abort(signal.reason);
94
+ return controller.signal;
95
+ }
96
+ signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });
97
+ }
98
+ return controller.signal;
99
+ }
100
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * テキスト処理ユーティリティ
3
+ * RFC パーサー共通のテキスト抽出・解析関数
4
+ */
5
+ import type { CrossReference } from '../types/index.js';
6
+ /**
7
+ * 指定位置を含む文を抽出
8
+ * @param text - 対象テキスト
9
+ * @param position - キーワードの位置
10
+ * @returns 文全体
11
+ */
12
+ export declare function extractSentence(text: string, position: number): string;
13
+ /**
14
+ * クロスリファレンスの抽出
15
+ * RFC参照(RFC 1234)とセクション参照(Section 1.2)を検出
16
+ * @param text - 対象テキスト
17
+ * @returns クロスリファレンスの配列
18
+ */
19
+ export declare function extractCrossReferences(text: string): CrossReference[];
20
+ /**
21
+ * 配列に正規化
22
+ * @param value - 単一値または配列
23
+ * @returns 配列
24
+ */
25
+ export declare function toArray<T>(value: T | T[] | undefined): T[];
26
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CActE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAwBrE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,GAAG,CAAC,EAAE,CAG1D"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * テキスト処理ユーティリティ
3
+ * RFC パーサー共通のテキスト抽出・解析関数
4
+ */
5
+ /**
6
+ * 指定位置を含む文を抽出
7
+ * @param text - 対象テキスト
8
+ * @param position - キーワードの位置
9
+ * @returns 文全体
10
+ */
11
+ export function extractSentence(text, position) {
12
+ // 文の開始を探す
13
+ let start = position;
14
+ while (start > 0 && !/[.!?]\s/.test(text.substring(start - 1, start + 1))) {
15
+ start--;
16
+ }
17
+ // 文の終了を探す
18
+ let end = position;
19
+ while (end < text.length && !/[.!?]/.test(text[end])) {
20
+ end++;
21
+ }
22
+ return text.substring(start, end + 1).trim();
23
+ }
24
+ /**
25
+ * クロスリファレンスの抽出
26
+ * RFC参照(RFC 1234)とセクション参照(Section 1.2)を検出
27
+ * @param text - 対象テキスト
28
+ * @returns クロスリファレンスの配列
29
+ */
30
+ export function extractCrossReferences(text) {
31
+ const refs = [];
32
+ // RFC参照パターン
33
+ const rfcPattern = /RFC\s*(\d+)/gi;
34
+ let match;
35
+ while ((match = rfcPattern.exec(text)) !== null) {
36
+ refs.push({
37
+ target: `RFC${match[1]}`,
38
+ type: 'rfc',
39
+ });
40
+ }
41
+ // セクション参照パターン
42
+ const sectionPattern = /[Ss]ection\s+([\d.]+)/g;
43
+ while ((match = sectionPattern.exec(text)) !== null) {
44
+ refs.push({
45
+ target: match[1],
46
+ type: 'section',
47
+ section: match[1],
48
+ });
49
+ }
50
+ return refs;
51
+ }
52
+ /**
53
+ * 配列に正規化
54
+ * @param value - 単一値または配列
55
+ * @returns 配列
56
+ */
57
+ export function toArray(value) {
58
+ if (!value)
59
+ return [];
60
+ return Array.isArray(value) ? value : [value];
61
+ }
62
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC5D,UAAU;IACV,IAAI,KAAK,GAAG,QAAQ,CAAC;IACrB,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,KAAK,EAAE,CAAC;IACV,CAAC;IAED,UAAU;IACV,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,EAAE,CAAC;IACR,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,IAAI,GAAqB,EAAE,CAAC;IAElC,YAAY;IACZ,MAAM,UAAU,GAAG,eAAe,CAAC;IACnC,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC;YACR,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE;YACxB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED,cAAc;IACd,MAAM,cAAc,GAAG,wBAAwB,CAAC;IAChD,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC;YACR,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YAChB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;SAClB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAI,KAA0B;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuji-bonji/rfcxml-mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "MCP server for structured understanding of RFC documents via RFCXML",
5
5
  "keywords": [
6
6
  "mcp",