@dev-pi2pie/word-counter 0.1.5-canary.4 → 0.1.5
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.md +60 -5
- package/dist/esm/bin.mjs +1010 -136
- package/dist/esm/bin.mjs.map +1 -1
- package/dist/esm/worker/count-worker.mjs +1 -1
- package/dist/esm/worker/count-worker.mjs.map +1 -1
- package/dist/esm/worker-pool.mjs +1 -0
- package/dist/esm/worker-pool.mjs.map +1 -1
- package/dist/wasm-language-detector/language_detector_bg.wasm +0 -0
- package/package.json +7 -7
package/dist/esm/worker-pool.mjs
CHANGED
|
@@ -117,6 +117,7 @@ async function countBatchInputsWithWorkerPool(options) {
|
|
|
117
117
|
section: options.section,
|
|
118
118
|
detectorMode: options.detectorMode,
|
|
119
119
|
wcOptions: options.wcOptions,
|
|
120
|
+
detectBinary: options.detectBinary,
|
|
120
121
|
preserveCollectorSegments: options.preserveCollectorSegments,
|
|
121
122
|
detectorEvidence: options.detectorEvidence,
|
|
122
123
|
debugVerbosity: options.debugVerbosity,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-pool.mjs","names":[],"sources":["../../src/cli/batch/jobs/worker-pool.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport type { SectionMode } from \"../../../markdown\";\nimport type { DetectorMode } from \"../../../detector\";\nimport type { DetectorDebugVerbosity } from \"../../../detector/debug\";\nimport type wordCounter from \"../../../wc\";\nimport type { BatchProgressSnapshot } from \"../../progress/reporter\";\nimport type { BatchFileResult, BatchSkip } from \"../../types\";\nimport type {\n WorkerRequestMessage,\n WorkerResponseMessage,\n WorkerTaskMessage,\n} from \"./worker/protocol\";\n\ntype CountBatchInputsWithWorkerPoolOptions = {\n filePaths: string[];\n jobs: number;\n section: SectionMode;\n detectorMode: DetectorMode;\n wcOptions: Parameters<typeof wordCounter>[1];\n preserveCollectorSegments: boolean;\n detectorEvidence?: boolean;\n debugVerbosity?: DetectorDebugVerbosity;\n onFileProcessed?: (snapshot: BatchProgressSnapshot) => void;\n onDetectorDebugEvent?: (\n event: string,\n details?: Record<string, unknown>,\n options?: { verbosity?: \"compact\" | \"verbose\" },\n ) => void;\n debugEnabled?: boolean;\n};\n\nexport class WorkerPoolUnavailableError extends Error {}\nexport class WorkerPoolTaskFatalError extends Error {\n path: string;\n code?: string;\n\n constructor(path: string, code: string | undefined, message: string) {\n super(message);\n this.path = path;\n this.code = code;\n }\n}\n\ntype CompletedEntry =\n | {\n kind: \"file\";\n file: BatchFileResult;\n }\n | {\n kind: \"skip\";\n skip: BatchSkip;\n };\n\ntype PendingTask = {\n index: number;\n path: string;\n workerIndex: number;\n};\n\nexport function resolveWorkerEntryUrl(): URL | null {\n const candidates = [\n new URL(\"./worker/count-worker.mjs\", import.meta.url),\n new URL(\"./worker/count-worker.js\", import.meta.url),\n new URL(\"./worker/count-worker.ts\", import.meta.url),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(fileURLToPath(candidate))) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport function isWorkerThreadsAvailable(): boolean {\n return typeof Worker === \"function\";\n}\n\nfunction isWorkerResponseMessage(value: unknown): value is WorkerResponseMessage {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n if (!(\"type\" in value)) {\n return false;\n }\n\n const type = (value as { type?: unknown }).type;\n return type === \"result\" || type === \"fatal\" || type === \"debug-event\";\n}\n\nexport async function countBatchInputsWithWorkerPool(\n options: CountBatchInputsWithWorkerPoolOptions,\n): Promise<{ files: BatchFileResult[]; skipped: BatchSkip[] }> {\n if (options.filePaths.length === 0) {\n return { files: [], skipped: [] };\n }\n\n const workerEntryUrl = resolveWorkerEntryUrl();\n if (!workerEntryUrl) {\n throw new WorkerPoolUnavailableError(\n \"Worker pool unavailable: count-worker entry file was not found.\",\n );\n }\n\n const safeRequestedJobs = Number.isFinite(options.jobs) ? Math.floor(options.jobs) : 1;\n const workerCount = Math.max(1, Math.min(options.filePaths.length, safeRequestedJobs));\n const workers: Worker[] = [];\n const completedEntries: Array<CompletedEntry | undefined> = Array.from({\n length: options.filePaths.length,\n });\n const pendingTasks = new Map<number, PendingTask>();\n const requestedShutdownWorkers = new Set<number>();\n let nextIndex = 0;\n let nextTaskId = 1;\n let completed = 0;\n let settled = false;\n\n const teardownWorkers = async (): Promise<void> => {\n await Promise.allSettled(workers.map((worker) => worker.terminate()));\n };\n\n return new Promise((resolve, reject) => {\n const fail = async (error: Error): Promise<void> => {\n if (settled) {\n return;\n }\n settled = true;\n await teardownWorkers();\n reject(error);\n };\n\n const complete = async (): Promise<void> => {\n if (settled) {\n return;\n }\n settled = true;\n await teardownWorkers();\n\n const files: BatchFileResult[] = [];\n const skipped: BatchSkip[] = [];\n for (const entry of completedEntries) {\n if (!entry) {\n reject(new Error(\"Worker pool finalize failed: missing completed entry.\"));\n return;\n }\n if (entry.kind === \"file\") {\n files.push(entry.file);\n continue;\n }\n skipped.push(entry.skip);\n }\n\n resolve({ files, skipped });\n };\n\n const assignNextTask = (worker: Worker, workerIndex: number): void => {\n if (settled) {\n return;\n }\n\n if (nextIndex >= options.filePaths.length) {\n requestedShutdownWorkers.add(workerIndex);\n const shutdown: WorkerRequestMessage = { type: \"shutdown\" };\n worker.postMessage(shutdown);\n return;\n }\n\n const index = nextIndex;\n nextIndex += 1;\n const path = options.filePaths[index];\n if (!path) {\n void fail(new Error(`Worker pool dispatch failed: missing path at index ${index}.`));\n return;\n }\n\n const taskId = nextTaskId;\n nextTaskId += 1;\n pendingTasks.set(taskId, { index, path, workerIndex });\n\n const message: WorkerTaskMessage = {\n type: \"task\",\n taskId,\n index,\n path,\n };\n worker.postMessage(message);\n };\n\n for (let workerIndex = 0; workerIndex < workerCount; workerIndex += 1) {\n let worker: Worker;\n try {\n worker = new Worker(workerEntryUrl, {\n workerData: {\n section: options.section,\n detectorMode: options.detectorMode,\n wcOptions: options.wcOptions,\n preserveCollectorSegments: options.preserveCollectorSegments,\n detectorEvidence: options.detectorEvidence,\n debugVerbosity: options.debugVerbosity,\n debugEnabled: options.debugEnabled,\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n void fail(new WorkerPoolUnavailableError(`Worker pool initialization failed: ${message}`));\n return;\n }\n\n workers.push(worker);\n\n worker.on(\"message\", (value: unknown) => {\n if (!isWorkerResponseMessage(value)) {\n void fail(new Error(\"Worker protocol mismatch: received unknown response payload.\"));\n return;\n }\n\n const pending = pendingTasks.get(value.taskId);\n if (!pending) {\n void fail(new Error(`Worker protocol mismatch: unknown task id ${value.taskId}.`));\n return;\n }\n\n if (value.type === \"debug-event\") {\n if (value.index !== pending.index) {\n void fail(\n new Error(\n `Worker protocol mismatch: task index mismatch for ${value.taskId} (expected ${pending.index}, got ${value.index}).`,\n ),\n );\n return;\n }\n options.onDetectorDebugEvent?.(\n value.event,\n {\n path: pending.path,\n ...value.details,\n },\n {\n verbosity: value.verbosity,\n },\n );\n return;\n }\n\n pendingTasks.delete(value.taskId);\n if (value.index !== pending.index) {\n void fail(\n new Error(\n `Worker protocol mismatch: task index mismatch for ${value.taskId} (expected ${pending.index}, got ${value.index}).`,\n ),\n );\n return;\n }\n\n if (value.type === \"fatal\") {\n void fail(\n new WorkerPoolTaskFatalError(\n value.path,\n value.code,\n `Worker task failed for ${value.path} (${value.code ?? \"UNKNOWN\"}): ${value.message}`,\n ),\n );\n return;\n }\n\n if (value.payload.kind === \"file\") {\n completedEntries[pending.index] = {\n kind: \"file\",\n file: value.payload.file,\n };\n } else {\n completedEntries[pending.index] = {\n kind: \"skip\",\n skip: value.payload.skip,\n };\n }\n\n completed += 1;\n options.onFileProcessed?.({\n completed,\n total: options.filePaths.length,\n });\n\n if (completed >= options.filePaths.length) {\n void complete();\n return;\n }\n\n assignNextTask(worker, workerIndex);\n });\n\n worker.on(\"error\", (error) => {\n const message = error instanceof Error ? error.message : String(error);\n void fail(new Error(`Worker runtime failed: ${message}`));\n });\n\n worker.on(\"exit\", (code) => {\n if (settled) {\n return;\n }\n\n const hasPendingTask = [...pendingTasks.values()].some(\n (task) => task.workerIndex === workerIndex,\n );\n const requestedShutdown = requestedShutdownWorkers.has(workerIndex);\n\n if (hasPendingTask) {\n void fail(new Error(`Worker exited before completing assigned tasks (code ${code}).`));\n return;\n }\n\n if (code !== 0) {\n void fail(new Error(`Worker exited unexpectedly with code ${code}.`));\n return;\n }\n\n if (!requestedShutdown && completed < options.filePaths.length) {\n void fail(new Error(\"Worker exited unexpectedly before completion.\"));\n }\n });\n\n assignNextTask(worker, workerIndex);\n }\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"worker-pool.mjs","names":[],"sources":["../../src/cli/batch/jobs/worker-pool.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport type { SectionMode } from \"../../../markdown\";\nimport type { DetectorMode } from \"../../../detector\";\nimport type { DetectorDebugVerbosity } from \"../../../detector/debug\";\nimport type wordCounter from \"../../../wc\";\nimport type { BatchProgressSnapshot } from \"../../progress/reporter\";\nimport type { BatchFileResult, BatchSkip } from \"../../types\";\nimport type {\n WorkerRequestMessage,\n WorkerResponseMessage,\n WorkerTaskMessage,\n} from \"./worker/protocol\";\n\ntype CountBatchInputsWithWorkerPoolOptions = {\n filePaths: string[];\n jobs: number;\n section: SectionMode;\n detectorMode: DetectorMode;\n wcOptions: Parameters<typeof wordCounter>[1];\n detectBinary: boolean;\n preserveCollectorSegments: boolean;\n detectorEvidence?: boolean;\n debugVerbosity?: DetectorDebugVerbosity;\n onFileProcessed?: (snapshot: BatchProgressSnapshot) => void;\n onDetectorDebugEvent?: (\n event: string,\n details?: Record<string, unknown>,\n options?: { verbosity?: \"compact\" | \"verbose\" },\n ) => void;\n debugEnabled?: boolean;\n};\n\nexport class WorkerPoolUnavailableError extends Error {}\nexport class WorkerPoolTaskFatalError extends Error {\n path: string;\n code?: string;\n\n constructor(path: string, code: string | undefined, message: string) {\n super(message);\n this.path = path;\n this.code = code;\n }\n}\n\ntype CompletedEntry =\n | {\n kind: \"file\";\n file: BatchFileResult;\n }\n | {\n kind: \"skip\";\n skip: BatchSkip;\n };\n\ntype PendingTask = {\n index: number;\n path: string;\n workerIndex: number;\n};\n\nexport function resolveWorkerEntryUrl(): URL | null {\n const candidates = [\n new URL(\"./worker/count-worker.mjs\", import.meta.url),\n new URL(\"./worker/count-worker.js\", import.meta.url),\n new URL(\"./worker/count-worker.ts\", import.meta.url),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(fileURLToPath(candidate))) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport function isWorkerThreadsAvailable(): boolean {\n return typeof Worker === \"function\";\n}\n\nfunction isWorkerResponseMessage(value: unknown): value is WorkerResponseMessage {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n if (!(\"type\" in value)) {\n return false;\n }\n\n const type = (value as { type?: unknown }).type;\n return type === \"result\" || type === \"fatal\" || type === \"debug-event\";\n}\n\nexport async function countBatchInputsWithWorkerPool(\n options: CountBatchInputsWithWorkerPoolOptions,\n): Promise<{ files: BatchFileResult[]; skipped: BatchSkip[] }> {\n if (options.filePaths.length === 0) {\n return { files: [], skipped: [] };\n }\n\n const workerEntryUrl = resolveWorkerEntryUrl();\n if (!workerEntryUrl) {\n throw new WorkerPoolUnavailableError(\n \"Worker pool unavailable: count-worker entry file was not found.\",\n );\n }\n\n const safeRequestedJobs = Number.isFinite(options.jobs) ? Math.floor(options.jobs) : 1;\n const workerCount = Math.max(1, Math.min(options.filePaths.length, safeRequestedJobs));\n const workers: Worker[] = [];\n const completedEntries: Array<CompletedEntry | undefined> = Array.from({\n length: options.filePaths.length,\n });\n const pendingTasks = new Map<number, PendingTask>();\n const requestedShutdownWorkers = new Set<number>();\n let nextIndex = 0;\n let nextTaskId = 1;\n let completed = 0;\n let settled = false;\n\n const teardownWorkers = async (): Promise<void> => {\n await Promise.allSettled(workers.map((worker) => worker.terminate()));\n };\n\n return new Promise((resolve, reject) => {\n const fail = async (error: Error): Promise<void> => {\n if (settled) {\n return;\n }\n settled = true;\n await teardownWorkers();\n reject(error);\n };\n\n const complete = async (): Promise<void> => {\n if (settled) {\n return;\n }\n settled = true;\n await teardownWorkers();\n\n const files: BatchFileResult[] = [];\n const skipped: BatchSkip[] = [];\n for (const entry of completedEntries) {\n if (!entry) {\n reject(new Error(\"Worker pool finalize failed: missing completed entry.\"));\n return;\n }\n if (entry.kind === \"file\") {\n files.push(entry.file);\n continue;\n }\n skipped.push(entry.skip);\n }\n\n resolve({ files, skipped });\n };\n\n const assignNextTask = (worker: Worker, workerIndex: number): void => {\n if (settled) {\n return;\n }\n\n if (nextIndex >= options.filePaths.length) {\n requestedShutdownWorkers.add(workerIndex);\n const shutdown: WorkerRequestMessage = { type: \"shutdown\" };\n worker.postMessage(shutdown);\n return;\n }\n\n const index = nextIndex;\n nextIndex += 1;\n const path = options.filePaths[index];\n if (!path) {\n void fail(new Error(`Worker pool dispatch failed: missing path at index ${index}.`));\n return;\n }\n\n const taskId = nextTaskId;\n nextTaskId += 1;\n pendingTasks.set(taskId, { index, path, workerIndex });\n\n const message: WorkerTaskMessage = {\n type: \"task\",\n taskId,\n index,\n path,\n };\n worker.postMessage(message);\n };\n\n for (let workerIndex = 0; workerIndex < workerCount; workerIndex += 1) {\n let worker: Worker;\n try {\n worker = new Worker(workerEntryUrl, {\n workerData: {\n section: options.section,\n detectorMode: options.detectorMode,\n wcOptions: options.wcOptions,\n detectBinary: options.detectBinary,\n preserveCollectorSegments: options.preserveCollectorSegments,\n detectorEvidence: options.detectorEvidence,\n debugVerbosity: options.debugVerbosity,\n debugEnabled: options.debugEnabled,\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n void fail(new WorkerPoolUnavailableError(`Worker pool initialization failed: ${message}`));\n return;\n }\n\n workers.push(worker);\n\n worker.on(\"message\", (value: unknown) => {\n if (!isWorkerResponseMessage(value)) {\n void fail(new Error(\"Worker protocol mismatch: received unknown response payload.\"));\n return;\n }\n\n const pending = pendingTasks.get(value.taskId);\n if (!pending) {\n void fail(new Error(`Worker protocol mismatch: unknown task id ${value.taskId}.`));\n return;\n }\n\n if (value.type === \"debug-event\") {\n if (value.index !== pending.index) {\n void fail(\n new Error(\n `Worker protocol mismatch: task index mismatch for ${value.taskId} (expected ${pending.index}, got ${value.index}).`,\n ),\n );\n return;\n }\n options.onDetectorDebugEvent?.(\n value.event,\n {\n path: pending.path,\n ...value.details,\n },\n {\n verbosity: value.verbosity,\n },\n );\n return;\n }\n\n pendingTasks.delete(value.taskId);\n if (value.index !== pending.index) {\n void fail(\n new Error(\n `Worker protocol mismatch: task index mismatch for ${value.taskId} (expected ${pending.index}, got ${value.index}).`,\n ),\n );\n return;\n }\n\n if (value.type === \"fatal\") {\n void fail(\n new WorkerPoolTaskFatalError(\n value.path,\n value.code,\n `Worker task failed for ${value.path} (${value.code ?? \"UNKNOWN\"}): ${value.message}`,\n ),\n );\n return;\n }\n\n if (value.payload.kind === \"file\") {\n completedEntries[pending.index] = {\n kind: \"file\",\n file: value.payload.file,\n };\n } else {\n completedEntries[pending.index] = {\n kind: \"skip\",\n skip: value.payload.skip,\n };\n }\n\n completed += 1;\n options.onFileProcessed?.({\n completed,\n total: options.filePaths.length,\n });\n\n if (completed >= options.filePaths.length) {\n void complete();\n return;\n }\n\n assignNextTask(worker, workerIndex);\n });\n\n worker.on(\"error\", (error) => {\n const message = error instanceof Error ? error.message : String(error);\n void fail(new Error(`Worker runtime failed: ${message}`));\n });\n\n worker.on(\"exit\", (code) => {\n if (settled) {\n return;\n }\n\n const hasPendingTask = [...pendingTasks.values()].some(\n (task) => task.workerIndex === workerIndex,\n );\n const requestedShutdown = requestedShutdownWorkers.has(workerIndex);\n\n if (hasPendingTask) {\n void fail(new Error(`Worker exited before completing assigned tasks (code ${code}).`));\n return;\n }\n\n if (code !== 0) {\n void fail(new Error(`Worker exited unexpectedly with code ${code}.`));\n return;\n }\n\n if (!requestedShutdown && completed < options.filePaths.length) {\n void fail(new Error(\"Worker exited unexpectedly before completion.\"));\n }\n });\n\n assignNextTask(worker, workerIndex);\n }\n });\n}\n"],"mappings":"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"}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev-pi2pie/word-counter",
|
|
3
|
-
"version": "0.1.5
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"cli",
|
|
6
6
|
"intl-segmenter",
|
|
@@ -62,16 +62,16 @@
|
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/bun": "^1.3.11",
|
|
64
64
|
"@types/node": "^25.5.0",
|
|
65
|
-
"oxfmt": "^0.
|
|
66
|
-
"oxlint": "^1.
|
|
65
|
+
"oxfmt": "^0.42.0",
|
|
66
|
+
"oxlint": "^1.57.0",
|
|
67
67
|
"picocolors": "^1.1.1",
|
|
68
|
-
"tsdown": "^0.21.
|
|
69
|
-
"typescript": "^
|
|
68
|
+
"tsdown": "^0.21.6",
|
|
69
|
+
"typescript": "^6.0.2"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"typescript": "^5"
|
|
72
|
+
"typescript": "^5 || ^6"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
|
75
|
-
"node": ">=
|
|
75
|
+
"node": ">=22.18.0"
|
|
76
76
|
}
|
|
77
77
|
}
|