@aiquants/duckdb-helper 1.4.1 → 1.5.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.
@@ -0,0 +1,188 @@
1
+ # Logger 仕様書
2
+
3
+ > ソースファイル: `src/utils/simple-logger.ts`
4
+
5
+ ## 1. 概要
6
+
7
+ ライブラリ内部で使用するログ出力ユーティリティ。ログレベルによるフィルタリング、プレフィックス付与、カスタムロガー実装の差し替えが可能。
8
+
9
+ ## 2. ログレベル(`LogLevel` enum)
10
+
11
+ ```typescript
12
+ export enum LogLevel {
13
+ DEBUG = 0, // 最も詳細(開発中のデバッグ情報)
14
+ INFO = 1, // 一般的な情報(初期化ステップなど)
15
+ WARN = 2, // 警告(処理は継続するが注意が必要)
16
+ ERROR = 3, // エラー(処理が失敗)
17
+ NONE = 4, // ログ出力なし
18
+ }
19
+ ```
20
+
21
+ | レベル | 数値 | 出力対象 | 用途例 |
22
+ |--------|------|---------|--------|
23
+ | `DEBUG` | 0 | debug, info, warn, error すべて出力 | 開発中のデバッグ |
24
+ | `INFO` | 1 | info, warn, error を出力 | 初期化ステップの確認 |
25
+ | `WARN` | 2 | warn, error のみ出力 | **デフォルト** |
26
+ | `ERROR` | 3 | error のみ出力 | 本番環境での最小ログ |
27
+ | `NONE` | 4 | 何も出力しない | テスト時のログ抑制 |
28
+
29
+ **判定ルール**: `設定レベル <= メソッドのレベル` の場合にログが出力される。
30
+
31
+ ## 3. `ILogger` インターフェース
32
+
33
+ ```typescript
34
+ export interface ILogger {
35
+ debug(message?: unknown, ...optionalParams: unknown[]): void
36
+ info(message?: unknown, ...optionalParams: unknown[]): void
37
+ warn(message?: unknown, ...optionalParams: unknown[]): void
38
+ error(message?: unknown, ...optionalParams: unknown[]): void
39
+ }
40
+ ```
41
+
42
+ `console` オブジェクトと互換のインターフェース。カスタムロガーを作る場合はこれを実装する。
43
+
44
+ ## 4. `Logger` クラス
45
+
46
+ ### 4.1 二重のAPI: インスタンスメソッドと静的メソッド
47
+
48
+ `Logger` は2つの使い方ができる。
49
+
50
+ | 使い方 | 対象 | 用途 |
51
+ |--------|------|------|
52
+ | **静的メソッド** | 内部のデフォルトインスタンス | ライブラリ内部での標準的な使用 |
53
+ | **インスタンスメソッド** | 個別のインスタンス | カスタム設定が必要な場合 |
54
+
55
+ ```typescript
56
+ // 静的メソッド(ライブラリ内部で使用)
57
+ Logger.info("初期化開始")
58
+ Logger.error("クエリ失敗:", error)
59
+
60
+ // インスタンスメソッド(カスタム用途)
61
+ const myLogger = new Logger(LogLevel.DEBUG, "[my-app]")
62
+ myLogger.debug("デバッグ情報")
63
+ ```
64
+
65
+ ### 4.2 コンストラクタ
66
+
67
+ ```typescript
68
+ constructor(
69
+ level: LogLevel = LogLevel.WARN,
70
+ prefix: string = "[duckdb-helper]",
71
+ impl: ILogger = console
72
+ )
73
+ ```
74
+
75
+ | 引数 | デフォルト | 説明 |
76
+ |------|-----------|------|
77
+ | `level` | `LogLevel.WARN` | 最小出力レベル |
78
+ | `prefix` | `"[duckdb-helper]"` | ログメッセージの先頭に付与する文字列 |
79
+ | `impl` | `console` | 実際のログ出力を行うオブジェクト |
80
+
81
+ ### 4.3 デフォルトインスタンス(static)
82
+
83
+ ```typescript
84
+ private static instance: Logger = new Logger(LogLevel.WARN, "[duckdb-helper]")
85
+ ```
86
+
87
+ - 静的メソッド(`Logger.info()` など)はこのインスタンスを使用する
88
+ - デフォルトレベルは `WARN` なので、`info` や `debug` のログは出力されない
89
+ - `DuckDBService` 内の初期化ログ(`Logger.info("🔧 Starting...")` など)はデフォルトでは非表示
90
+
91
+ ### 4.4 静的メソッド一覧
92
+
93
+ #### ログ出力
94
+
95
+ | メソッド | 出力条件 |
96
+ |---------|---------|
97
+ | `Logger.debug(message, ...params)` | `level <= DEBUG (0)` |
98
+ | `Logger.info(message, ...params)` | `level <= INFO (1)` |
99
+ | `Logger.warn(message, ...params)` | `level <= WARN (2)` |
100
+ | `Logger.error(message, ...params)` | `level <= ERROR (3)` |
101
+
102
+ #### 設定変更
103
+
104
+ | メソッド | 説明 |
105
+ |---------|------|
106
+ | `Logger.setLevel(level)` | デフォルトインスタンスのログレベルを変更 |
107
+ | `Logger.setImplementation(impl)` | デフォルトインスタンスのロガー実装を差し替え |
108
+ | `Logger.setPrefix(prefix)` | デフォルトインスタンスのプレフィックスを変更 |
109
+
110
+ ### 4.5 メッセージフォーマット
111
+
112
+ ```typescript
113
+ private formatMessage(message: unknown): unknown[] {
114
+ if (typeof message === "string") {
115
+ return [`${this.prefix} ${message}`]
116
+ }
117
+ return [this.prefix, message]
118
+ }
119
+ ```
120
+
121
+ | 入力 | 出力 |
122
+ |------|------|
123
+ | `"初期化中..."` | `["[duckdb-helper] 初期化中..."]` |
124
+ | `{ key: "value" }` | `["[duckdb-helper]", { key: "value" }]` |
125
+
126
+ 文字列の場合はプレフィックスを結合し、オブジェクトの場合はプレフィックスを別引数として渡す(console の展開表示を活用)。
127
+
128
+ ## 5. ライブラリ内での使用箇所
129
+
130
+ | ファイル | 使用メソッド | 内容 |
131
+ |---------|------------|------|
132
+ | `services/duckdb.ts` | `Logger.info` | Worker 初期化の各ステップのログ |
133
+ | `services/duckdb.ts` | `Logger.warn` | splink_udfs ロード失敗時の警告 |
134
+ | `services/duckdb.ts` | `Logger.error` | 初期化失敗・クエリ失敗のエラーログ |
135
+ | `hooks/useDuckDB.ts` | `Logger.info` | ステータス変更・自動初期化のログ |
136
+ | `hooks/useDuckDB.ts` | `Logger.error` | 初期化失敗のエラーログ |
137
+
138
+ ## 6. 利用側でのログレベル制御
139
+
140
+ ### 開発中(すべてのログを表示)
141
+
142
+ > **重要**: `Logger` と `LogLevel` は `index.ts` から公開エクスポートされておらず、`package.json` の `exports` にもサブパスが定義されていないため、**現状では利用側から直接インポートできない**。ログレベルを変更するには、パッケージ側で `index.ts` にエクスポートを追加する必要がある(追加方法は[開発ガイド](../guides/2026.04.11%20%5BAI%5D%20development.md)の「Q: Logger を公開 API にしたい」を参照)。
143
+
144
+ パッケージ側でエクスポートが追加された場合の使用例:
145
+
146
+ ```typescript
147
+ import { Logger, LogLevel } from '@aiquants/duckdb-helper'
148
+
149
+ Logger.setLevel(LogLevel.DEBUG)
150
+ ```
151
+
152
+ ### 本番環境(エラーのみ表示)
153
+
154
+ ```typescript
155
+ Logger.setLevel(LogLevel.ERROR)
156
+ ```
157
+
158
+ ### テスト(ログを完全に抑制)
159
+
160
+ ```typescript
161
+ Logger.setLevel(LogLevel.NONE)
162
+ ```
163
+
164
+ ### カスタムロガーに差し替え
165
+
166
+ ```typescript
167
+ const customLogger: ILogger = {
168
+ debug: (...args) => myLoggingService.log('debug', ...args),
169
+ info: (...args) => myLoggingService.log('info', ...args),
170
+ warn: (...args) => myLoggingService.log('warn', ...args),
171
+ error: (...args) => myLoggingService.log('error', ...args),
172
+ }
173
+
174
+ Logger.setImplementation(customLogger)
175
+ ```
176
+
177
+ ## 7. 注意事項
178
+
179
+ 1. **Logger / LogLevel は `index.ts` から公開エクスポートされていない**。ライブラリ内部用の位置づけ。`package.json` の `exports` にもサブパスが未定義のため、`@aiquants/duckdb-helper/utils/simple-logger` のような直接パスインポートも動作しない。利用側からログレベルを変更するにはパッケージのエクスポートを拡張する必要がある。
180
+ 2. **デフォルトレベルは `WARN`**。つまり `DuckDBService` 内の `Logger.info(...)` による初期化ログは通常表示されない。デバッグ時にログを見たい場合は `Logger.setLevel(LogLevel.DEBUG)` を設定する。
181
+ 3. **リスナーでの例外はキャッチされる**。`DuckDBService.notifyListeners()` 内でリスナーが例外を投げた場合、`Logger.error` でログに出力されるが、他のリスナーへの通知は続行される。
182
+
183
+ ## 8. 新人向けポイント
184
+
185
+ 1. **普段は Logger を意識しなくてOK**。ライブラリ内部で勝手にログを出す仕組み。
186
+ 2. **デバッグしたい時は `Logger.setLevel(LogLevel.DEBUG)` するだけ**。初期化の各ステップが詳細に表示される。
187
+ 3. **テストで邪魔なログを消すには `Logger.setLevel(LogLevel.NONE)`**。
188
+ 4. **プレフィックス `[duckdb-helper]` でログをフィルタリング**できる。ブラウザの DevTools で検索すると便利。
@@ -0,0 +1,170 @@
1
+ # ビルド設定仕様書
2
+
3
+ > ソースファイル: `tsup.config.ts`, `tsconfig.json`, `package.json`
4
+
5
+ ## 1. 概要
6
+
7
+ このパッケージは **tsup**(esbuild ベースのバンドラー)を使ってビルドされ、CommonJS と ESM の両形式で配布される。
8
+
9
+ ## 2. tsup 設定(`tsup.config.ts`)
10
+
11
+ ```typescript
12
+ import { defineConfig } from 'tsup'
13
+
14
+ export default defineConfig({
15
+ entry: ['src/index.ts'], // エントリーポイント
16
+ format: ['cjs', 'esm'], // 出力形式(CommonJS + ESM)
17
+ dts: true, // 型定義ファイル (.d.ts) を生成
18
+ clean: true, // ビルド前に dist/ をクリーン
19
+ sourcemap: true, // ソースマップを生成
20
+ external: ['react', 'react-dom', '@duckdb/duckdb-wasm'], // バンドルに含めない
21
+ outDir: 'dist', // 出力先
22
+ target: 'es2020', // ターゲット環境
23
+ splitting: false, // コード分割なし
24
+ minify: true // ミニファイ有効
25
+ })
26
+ ```
27
+
28
+ ### 各設定の意味
29
+
30
+ | 設定 | 値 | 説明 |
31
+ |------|------|------|
32
+ | `entry` | `['src/index.ts']` | ビルドのエントリーポイント。`index.ts` の公開 API のみがバンドルされる |
33
+ | `format` | `['cjs', 'esm']` | CommonJS(`.js`)と ESM(`.mjs`)の両形式を生成 |
34
+ | `dts` | `true` | TypeScript 型定義ファイル(`.d.ts`)を自動生成 |
35
+ | `clean` | `true` | ビルド前に `dist/` を削除してクリーンビルド |
36
+ | `sourcemap` | `true` | デバッグ用のソースマップを生成 |
37
+ | `external` | 3パッケージ | これらはバンドルに含めず、利用側でインストールしてもらう |
38
+ | `outDir` | `'dist'` | ビルド成果物の出力先 |
39
+ | `target` | `'es2020'` | ES2020 の構文までを使用。Optional chaining, nullish coalescing 等が使える |
40
+ | `splitting` | `false` | チャンク分割を無効化。1ファイルにまとめる |
41
+ | `minify` | `true` | 配布サイズ削減のためミニファイ |
42
+
43
+ ### external の意味
44
+
45
+ | パッケージ | 理由 |
46
+ |-----------|------|
47
+ | `react` | ピア依存。利用側が提供する |
48
+ | `react-dom` | ピア依存。利用側が提供する |
49
+ | `@duckdb/duckdb-wasm` | 本番依存だがサイズが大きいため、利用側のバンドラーに委ねる |
50
+
51
+ ## 3. TypeScript 設定(`tsconfig.json`)
52
+
53
+ ### 主要設定
54
+
55
+ | 設定 | 値 | 説明 |
56
+ |------|------|------|
57
+ | `target` | `ES2020` | 出力する JavaScript のバージョン |
58
+ | `module` | `ES2020` | モジュールシステム |
59
+ | `lib` | `["ES2020", "DOM", "DOM.Iterable"]` | 利用可能な型定義。DOM はブラウザ API 用 |
60
+ | `strict` | `true` | すべての strict チェックを有効化 |
61
+ | `jsx` | `react-jsx` | React 17+ の JSX トランスフォーム |
62
+ | `moduleResolution` | `node` | Node.js スタイルのモジュール解決 |
63
+ | `noEmit` | `true` | tsc は型チェックのみ。ビルドは tsup が担当 |
64
+ | `isolatedModules` | `true` | 各ファイルを独立してトランスパイル可能にする(tsup 互換) |
65
+
66
+ ### パスエイリアス
67
+
68
+ ```json
69
+ "paths": {
70
+ "@/*": ["./src/*"]
71
+ }
72
+ ```
73
+
74
+ `@/services/duckdb` のように `src/` からの相対パスを `@/` で参照できる。ただし現在のソースコードでは使用されていない。
75
+
76
+ ### 除外設定
77
+
78
+ ```json
79
+ "exclude": [
80
+ "node_modules",
81
+ "dist",
82
+ "**/*.test.*",
83
+ "**/*.spec.*"
84
+ ]
85
+ ```
86
+
87
+ テストファイルはビルド・型チェックの対象外。
88
+
89
+ ## 4. package.json のビルド関連設定
90
+
91
+ ### 出力形式のマッピング
92
+
93
+ ```json
94
+ {
95
+ "main": "dist/index.js", // CommonJS (require)
96
+ "module": "dist/index.mjs", // ESM (import)
97
+ "types": "dist/index.d.ts", // 型定義
98
+ "exports": {
99
+ ".": {
100
+ "types": "./dist/index.d.ts",
101
+ "import": "./dist/index.mjs",
102
+ "require": "./dist/index.js",
103
+ "default": "./dist/index.mjs"
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ | フィールド | 用途 |
110
+ |-----------|------|
111
+ | `main` | Node.js / 古いバンドラーが参照(CommonJS) |
112
+ | `module` | Webpack / Rollup 等が参照(ESM) |
113
+ | `types` | TypeScript の型定義 |
114
+ | `exports` | Node.js 12+ のモジュール解決。条件付きエクスポート |
115
+
116
+ ### npm スクリプト
117
+
118
+ | スクリプト | コマンド | 説明 |
119
+ |-----------|---------|------|
120
+ | `build` | `tsup` | ビルド実行 |
121
+ | `build:watch` | `tsup --watch` | ファイル変更時に自動リビルド |
122
+ | `dev` | `tsup --watch` | 開発用(build:watch と同一) |
123
+ | `watch` | `tsup --watch` | ウォッチモード |
124
+ | `type-check` | `tsc --noEmit` | 型チェックのみ実行 |
125
+ | `clean` | `rimraf dist` | ビルド成果物を削除 |
126
+ | `prepare` | `pnpm run build` | パッケージインストール後に自動ビルド |
127
+ | `prepublishOnly` | clean → typecheck → test(`--if-present`) → build | 公開前の品質チェック |
128
+ | `lint` | `biome lint src/` | Biome による Lint |
129
+ | `lint:fix` | `biome lint --write src/` | Biome による Lint 自動修正 |
130
+ | `format` | `biome format src/` | Biome によるフォーマット |
131
+ | `format:fix` | `biome format --write src/` | Biome によるフォーマット自動修正 |
132
+ | `check` | `biome check src/` | Lint + フォーマットの同時チェック |
133
+ | `check:fix` | `biome check --write src/` | Lint + フォーマットの同時自動修正 |
134
+ | `typecheck` | `npm run type-check` | `type-check` のエイリアス |
135
+ | `test` | `vitest run` | テスト実行 |
136
+ | `test:coverage` | `vitest run --coverage` | カバレッジ付きテスト |
137
+ | `license-check` | `pnpm dlx license-checker ...` | 許可ライセンスのチェック |
138
+ | `license-check:json` | `pnpm dlx license-checker ... --json` | ライセンスチェック(JSON 出力) |
139
+ | `publish:patch` | version patch → publish | パッチバージョン公開 |
140
+ | `publish:minor` | version minor → publish | マイナーバージョン公開 |
141
+ | `publish:major` | version major → publish | メジャーバージョン公開 |
142
+
143
+ ### 配布ファイル
144
+
145
+ ```json
146
+ "files": ["dist", "README.md", "LICENSE", "docs"]
147
+ ```
148
+
149
+ npm に公開されるファイル。`src/` はパッケージに含まれない。
150
+
151
+ ## 5. ビルド成果物の構成
152
+
153
+ ```
154
+ dist/
155
+ ├── index.js # CommonJS バンドル(require() 用)
156
+ ├── index.mjs # ESM バンドル(import 用)
157
+ ├── index.d.ts # TypeScript 型定義
158
+ ├── index.d.mts # ESM 用 TypeScript 型定義
159
+ ├── index.js.map # CommonJS ソースマップ
160
+ └── index.mjs.map # ESM ソースマップ
161
+ ```
162
+
163
+ ## 6. 新人向けポイント
164
+
165
+ 1. **`pnpm run build` でビルド**。`dist/` にファイルが生成される。
166
+ 2. **`pnpm run dev` で開発中はウォッチモード**を使うと、ソース変更が自動で反映される。
167
+ 3. **`pnpm run type-check` で型エラーだけ確認**できる。ビルドせずに素早くチェック。
168
+ 4. **`external` に指定されたパッケージはバンドルに含まれない**。利用側でインストールが必要。
169
+ 5. **ビルドは tsup(esbuild ベース)が行い、tsc は型チェック専用**。この分業により高速ビルドと厳密な型チェックを両立。
170
+ 6. **`src/` は npm パッケージに含まれない**。利用者が見るのは `dist/` のビルド済みコードのみ。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiquants/duckdb-helper",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "DuckDB helper utilities with React hooks, worker initialization, and typed query helpers",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -36,18 +36,18 @@
36
36
  "@duckdb/duckdb-wasm": "^1.30.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/react": "^18.3.27",
40
- "@types/react-dom": "^18.3.7",
41
- "react": "^18.3.1",
42
- "react-dom": "^18.3.1",
39
+ "@types/react": "^19.2.7",
40
+ "@types/react-dom": "^19.2.3",
41
+ "react": "^19.2.7",
42
+ "react-dom": "^19.2.7",
43
43
  "rimraf": "^6.1.2",
44
44
  "tsup": "^8.5.1",
45
45
  "typescript": "^5.9.3",
46
46
  "vitest": "^3.2.4"
47
47
  },
48
48
  "peerDependencies": {
49
- "react": ">=18.0.0",
50
- "react-dom": ">=18.0.0"
49
+ "react": "^19.2.7",
50
+ "react-dom": "^19.2.7"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "react": {
@@ -69,8 +69,7 @@
69
69
  "build:watch": "tsup --watch",
70
70
  "dev": "tsup --watch",
71
71
  "watch": "tsup --watch",
72
- "type-check": "tsc --noEmit",
73
- "typecheck": "npm run type-check",
72
+ "typecheck": "tsc --noEmit",
74
73
  "clean": "rimraf dist",
75
74
  "publish:patch": "npm version patch && pnpm publish --no-git-checks",
76
75
  "publish:minor": "npm version minor && pnpm publish --no-git-checks",