@thunderkiller/video-clipper 1.5.6 → 1.6.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.
Files changed (49) hide show
  1. package/dist/config/env.d.ts +4 -0
  2. package/dist/config/env.d.ts.map +1 -1
  3. package/dist/pipeline/runner.d.ts.map +1 -1
  4. package/dist/pipeline/runner.js +79 -72
  5. package/dist/pipeline/runner.js.map +1 -1
  6. package/dist/pipeline/stages/segmentAnalyzer.d.ts +1 -1
  7. package/dist/pipeline/stages/segmentAnalyzer.d.ts.map +1 -1
  8. package/dist/pipeline/stages/segmentAnalyzer.js +2 -2
  9. package/dist/pipeline/stages/segmentAnalyzer.js.map +1 -1
  10. package/dist/services/clipRefiner/index.d.ts +2 -1
  11. package/dist/services/clipRefiner/index.d.ts.map +1 -1
  12. package/dist/services/clipRefiner/index.js +3 -5
  13. package/dist/services/clipRefiner/index.js.map +1 -1
  14. package/dist/services/llmAnalyzer/LLMAnalyzer.d.ts +2 -2
  15. package/dist/services/llmAnalyzer/LLMAnalyzer.d.ts.map +1 -1
  16. package/dist/services/llmAnalyzer/LLMAnalyzer.js +2 -2
  17. package/dist/services/llmAnalyzer/LLMAnalyzer.js.map +1 -1
  18. package/dist/services/llmAnalyzer/index.d.ts +3 -2
  19. package/dist/services/llmAnalyzer/index.d.ts.map +1 -1
  20. package/dist/services/llmAnalyzer/index.js +5 -7
  21. package/dist/services/llmAnalyzer/index.js.map +1 -1
  22. package/dist/services/transcriptDetector/index.d.ts +2 -2
  23. package/dist/services/transcriptDetector/index.d.ts.map +1 -1
  24. package/dist/services/transcriptDetector/index.js.map +1 -1
  25. package/dist/types/config.d.ts +7 -0
  26. package/dist/types/config.d.ts.map +1 -1
  27. package/dist/types/config.js +12 -0
  28. package/dist/types/config.js.map +1 -1
  29. package/dist/utils/cache.d.ts +14 -18
  30. package/dist/utils/cache.d.ts.map +1 -1
  31. package/dist/utils/cache.js +32 -112
  32. package/dist/utils/cache.js.map +1 -1
  33. package/dist/utils/cacheBackend.d.ts +40 -0
  34. package/dist/utils/cacheBackend.d.ts.map +1 -0
  35. package/dist/utils/cacheBackend.js +28 -0
  36. package/dist/utils/cacheBackend.js.map +1 -0
  37. package/dist/utils/cacheFactory.d.ts +14 -0
  38. package/dist/utils/cacheFactory.d.ts.map +1 -0
  39. package/dist/utils/cacheFactory.js +31 -0
  40. package/dist/utils/cacheFactory.js.map +1 -0
  41. package/dist/utils/fileCacheBackend.d.ts +33 -0
  42. package/dist/utils/fileCacheBackend.d.ts.map +1 -0
  43. package/dist/utils/fileCacheBackend.js +123 -0
  44. package/dist/utils/fileCacheBackend.js.map +1 -0
  45. package/dist/utils/mongoCacheBackend.d.ts +51 -0
  46. package/dist/utils/mongoCacheBackend.d.ts.map +1 -0
  47. package/dist/utils/mongoCacheBackend.js +176 -0
  48. package/dist/utils/mongoCacheBackend.js.map +1 -0
  49. package/package.json +2 -1
@@ -0,0 +1,176 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { log } from './logger.js';
4
+ import { TranscriptLineSchema, ChunkEvaluationSchema, AudioEventSchema, SegmentRefinementSchema, } from '../types/index.js';
5
+ // ---------------------------------------------------------------------------
6
+ // Internal helpers
7
+ // ---------------------------------------------------------------------------
8
+ function hashContent(input) {
9
+ return createHash('sha256').update(input).digest('hex');
10
+ }
11
+ /**
12
+ * Serializes audio events into a stable string for cache keying.
13
+ * Events are sorted by time so the key is order-independent.
14
+ */
15
+ function audioEventsKey(events) {
16
+ if (events.length === 0)
17
+ return '';
18
+ const sorted = [...events].sort((a, b) => a.time - b.time);
19
+ return JSON.stringify(sorted);
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // MongoCacheBackend
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * MongoDB-backed cache backend.
26
+ *
27
+ * Each cache category maps to one collection. Documents have the shape:
28
+ * { cacheKey: string, data: <payload>, createdAt: Date }
29
+ *
30
+ * Indexes created on first use (idempotent):
31
+ * - Unique index on `cacheKey` for O(1) lookups
32
+ * - TTL index on `createdAt` when `ttlSeconds > 0`
33
+ *
34
+ * All reads validate the stored payload through the same zod schemas used by
35
+ * the file backend, giving identical runtime safety guarantees.
36
+ *
37
+ * Pass `ttlSeconds = 0` (or omit) to disable TTL expiration.
38
+ */
39
+ export class MongoCacheBackend {
40
+ client;
41
+ db;
42
+ ttlSeconds;
43
+ /** Track which collections already have their indexes created this session. */
44
+ indexedCollections = new Set();
45
+ constructor(client, databaseName, ttlSeconds = 0) {
46
+ this.client = client;
47
+ this.db = client.db(databaseName);
48
+ this.ttlSeconds = ttlSeconds;
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // Index management
52
+ // ---------------------------------------------------------------------------
53
+ /**
54
+ * Ensures indexes exist for a collection. Called lazily on first access per
55
+ * collection name. `createIndex` is idempotent so concurrent calls are safe.
56
+ */
57
+ async ensureIndexes(collectionName) {
58
+ if (this.indexedCollections.has(collectionName))
59
+ return;
60
+ try {
61
+ const col = this.db.collection(collectionName);
62
+ // Unique index for O(1) cache key lookups
63
+ await col.createIndex({ cacheKey: 1 }, { unique: true });
64
+ // TTL index — only when a positive TTL is configured
65
+ if (this.ttlSeconds > 0) {
66
+ await col.createIndex({ createdAt: 1 }, { expireAfterSeconds: this.ttlSeconds });
67
+ }
68
+ this.indexedCollections.add(collectionName);
69
+ }
70
+ catch (err) {
71
+ // Non-fatal — pipeline should not crash if indexes can't be created
72
+ log.warn(`[mongo-cache] Failed to ensure indexes on "${collectionName}": ${err instanceof Error ? err.message : String(err)}`);
73
+ }
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Low-level read / write helpers
77
+ // ---------------------------------------------------------------------------
78
+ async readDoc(collectionName, cacheKey, schema) {
79
+ try {
80
+ await this.ensureIndexes(collectionName);
81
+ const col = this.db.collection(collectionName);
82
+ const doc = await col.findOne({ cacheKey });
83
+ if (!doc)
84
+ return null;
85
+ const parsed = schema.safeParse(doc.data);
86
+ if (!parsed.success) {
87
+ log.warn(`[mongo-cache] Corrupt entry in "${collectionName}" (key=${cacheKey}) — ignoring`);
88
+ return null;
89
+ }
90
+ return parsed.data;
91
+ }
92
+ catch (err) {
93
+ log.warn(`[mongo-cache] Read failed in "${collectionName}": ${err instanceof Error ? err.message : String(err)}`);
94
+ return null;
95
+ }
96
+ }
97
+ async writeDoc(collectionName, cacheKey, data) {
98
+ try {
99
+ await this.ensureIndexes(collectionName);
100
+ const col = this.db.collection(collectionName);
101
+ await col.updateOne({ cacheKey }, { $set: { cacheKey, data, createdAt: new Date() } }, { upsert: true });
102
+ }
103
+ catch (err) {
104
+ log.warn(`[mongo-cache] Write failed in "${collectionName}": ${err instanceof Error ? err.message : String(err)}`);
105
+ }
106
+ }
107
+ // ---------------------------------------------------------------------------
108
+ // Transcript
109
+ // ---------------------------------------------------------------------------
110
+ static TRANSCRIPTS = 'transcripts';
111
+ async readTranscript(videoId) {
112
+ return this.readDoc(MongoCacheBackend.TRANSCRIPTS, hashContent(videoId), z.array(TranscriptLineSchema));
113
+ }
114
+ async writeTranscript(videoId, lines) {
115
+ await this.writeDoc(MongoCacheBackend.TRANSCRIPTS, hashContent(videoId), lines);
116
+ }
117
+ // ---------------------------------------------------------------------------
118
+ // LLM chunk results
119
+ // ---------------------------------------------------------------------------
120
+ static CHUNKS = 'chunkEvaluations';
121
+ chunkKey(chunk, chunkAudioEvents = []) {
122
+ const audioKey = audioEventsKey(chunkAudioEvents);
123
+ return hashContent(`${chunk.start}|${chunk.end}|${chunk.text}|${audioKey}`);
124
+ }
125
+ async readChunk(chunk, chunkAudioEvents = []) {
126
+ return this.readDoc(MongoCacheBackend.CHUNKS, this.chunkKey(chunk, chunkAudioEvents), ChunkEvaluationSchema);
127
+ }
128
+ async writeChunk(chunk, evaluation, chunkAudioEvents = []) {
129
+ // Only cache successful evaluations — mirrors the file backend behaviour
130
+ if (evaluation.status !== 'success')
131
+ return;
132
+ await this.writeDoc(MongoCacheBackend.CHUNKS, this.chunkKey(chunk, chunkAudioEvents), evaluation);
133
+ }
134
+ // ---------------------------------------------------------------------------
135
+ // Segment refinement
136
+ // ---------------------------------------------------------------------------
137
+ static SEGMENTS = 'segmentRefinements';
138
+ async readSegmentRefinement(start, end, reason) {
139
+ return this.readDoc(MongoCacheBackend.SEGMENTS, hashContent(`${start}|${end}|${reason}`), SegmentRefinementSchema);
140
+ }
141
+ async writeSegmentRefinement(start, end, reason, refined) {
142
+ await this.writeDoc(MongoCacheBackend.SEGMENTS, hashContent(`${start}|${end}|${reason}`), refined);
143
+ }
144
+ // ---------------------------------------------------------------------------
145
+ // Audio events (whole-video)
146
+ // ---------------------------------------------------------------------------
147
+ static AUDIO_EVENTS = 'audioEvents';
148
+ async readAudioEvents(videoId, gameProfile, provider) {
149
+ return this.readDoc(MongoCacheBackend.AUDIO_EVENTS, hashContent(`${videoId}|${gameProfile}|${provider}`), z.array(AudioEventSchema));
150
+ }
151
+ async writeAudioEvents(videoId, gameProfile, provider, events) {
152
+ await this.writeDoc(MongoCacheBackend.AUDIO_EVENTS, hashContent(`${videoId}|${gameProfile}|${provider}`), events);
153
+ }
154
+ // ---------------------------------------------------------------------------
155
+ // Audio events (per-chunk)
156
+ // ---------------------------------------------------------------------------
157
+ static AUDIO_CHUNKS = 'audioChunks';
158
+ async readAudioChunk(videoId, gameProfile, provider, windowStart, windowEnd) {
159
+ return this.readDoc(MongoCacheBackend.AUDIO_CHUNKS, hashContent(`${videoId}|${gameProfile}|${provider}|${windowStart}|${windowEnd}`), z.array(AudioEventSchema));
160
+ }
161
+ async writeAudioChunk(videoId, gameProfile, provider, windowStart, windowEnd, events) {
162
+ await this.writeDoc(MongoCacheBackend.AUDIO_CHUNKS, hashContent(`${videoId}|${gameProfile}|${provider}|${windowStart}|${windowEnd}`), events);
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // Lifecycle
166
+ // ---------------------------------------------------------------------------
167
+ async close() {
168
+ try {
169
+ await this.client.close();
170
+ }
171
+ catch (err) {
172
+ log.warn(`[mongo-cache] Failed to close MongoDB connection: ${err instanceof Error ? err.message : String(err)}`);
173
+ }
174
+ }
175
+ }
176
+ //# sourceMappingURL=mongoCacheBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongoCacheBackend.js","sourceRoot":"","sources":["../../src/utils/mongoCacheBackend.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thunderkiller/video-clipper",
3
- "version": "1.5.6",
3
+ "version": "1.6.0",
4
4
  "description": "CLI that analyzes YouTube transcripts with an LLM to find interesting moments and cut clips",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -73,6 +73,7 @@
73
73
  "dotenv": "^16.4.7",
74
74
  "execa": "^9.5.2",
75
75
  "fluent-ffmpeg": "^2.1.3",
76
+ "mongodb": "^7.1.0",
76
77
  "p-limit": "^7.3.0",
77
78
  "zod": "^4.3.6"
78
79
  },