@openinary/core 1.1.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 (242) hide show
  1. package/LICENSE +661 -0
  2. package/dist/config/deps.d.ts +14 -0
  3. package/dist/config/deps.d.ts.map +1 -0
  4. package/dist/config/deps.js +2 -0
  5. package/dist/config/deps.js.map +1 -0
  6. package/dist/index.d.ts +27 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +28 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/routes/authenticated.d.ts +4 -0
  11. package/dist/routes/authenticated.d.ts.map +1 -0
  12. package/dist/routes/authenticated.js +130 -0
  13. package/dist/routes/authenticated.js.map +1 -0
  14. package/dist/routes/download-folder.d.ts +4 -0
  15. package/dist/routes/download-folder.d.ts.map +1 -0
  16. package/dist/routes/download-folder.js +101 -0
  17. package/dist/routes/download-folder.js.map +1 -0
  18. package/dist/routes/download-zip.d.ts +15 -0
  19. package/dist/routes/download-zip.d.ts.map +1 -0
  20. package/dist/routes/download-zip.js +147 -0
  21. package/dist/routes/download-zip.js.map +1 -0
  22. package/dist/routes/download.d.ts +4 -0
  23. package/dist/routes/download.d.ts.map +1 -0
  24. package/dist/routes/download.js +83 -0
  25. package/dist/routes/download.js.map +1 -0
  26. package/dist/routes/invalidate.d.ts +4 -0
  27. package/dist/routes/invalidate.d.ts.map +1 -0
  28. package/dist/routes/invalidate.js +114 -0
  29. package/dist/routes/invalidate.js.map +1 -0
  30. package/dist/routes/queue-events.d.ts +4 -0
  31. package/dist/routes/queue-events.d.ts.map +1 -0
  32. package/dist/routes/queue-events.js +125 -0
  33. package/dist/routes/queue-events.js.map +1 -0
  34. package/dist/routes/queue.d.ts +4 -0
  35. package/dist/routes/queue.d.ts.map +1 -0
  36. package/dist/routes/queue.js +130 -0
  37. package/dist/routes/queue.js.map +1 -0
  38. package/dist/routes/storage.d.ts +4 -0
  39. package/dist/routes/storage.d.ts.map +1 -0
  40. package/dist/routes/storage.js +694 -0
  41. package/dist/routes/storage.js.map +1 -0
  42. package/dist/routes/transform-helpers.d.ts +62 -0
  43. package/dist/routes/transform-helpers.d.ts.map +1 -0
  44. package/dist/routes/transform-helpers.js +372 -0
  45. package/dist/routes/transform-helpers.js.map +1 -0
  46. package/dist/routes/transform.d.ts +4 -0
  47. package/dist/routes/transform.d.ts.map +1 -0
  48. package/dist/routes/transform.js +65 -0
  49. package/dist/routes/transform.js.map +1 -0
  50. package/dist/routes/video-status.d.ts +4 -0
  51. package/dist/routes/video-status.d.ts.map +1 -0
  52. package/dist/routes/video-status.js +208 -0
  53. package/dist/routes/video-status.js.map +1 -0
  54. package/dist/services/transform.service.d.ts +71 -0
  55. package/dist/services/transform.service.d.ts.map +1 -0
  56. package/dist/services/transform.service.js +362 -0
  57. package/dist/services/transform.service.js.map +1 -0
  58. package/dist/types.d.ts +82 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +2 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils/asset-deletion.d.ts +16 -0
  63. package/dist/utils/asset-deletion.d.ts.map +1 -0
  64. package/dist/utils/asset-deletion.js +131 -0
  65. package/dist/utils/asset-deletion.js.map +1 -0
  66. package/dist/utils/cache.d.ts +44 -0
  67. package/dist/utils/cache.d.ts.map +1 -0
  68. package/dist/utils/cache.js +248 -0
  69. package/dist/utils/cache.js.map +1 -0
  70. package/dist/utils/get-unique-file-path.d.ts +8 -0
  71. package/dist/utils/get-unique-file-path.d.ts.map +1 -0
  72. package/dist/utils/get-unique-file-path.js +26 -0
  73. package/dist/utils/get-unique-file-path.js.map +1 -0
  74. package/dist/utils/image/aspect-ratio.d.ts +7 -0
  75. package/dist/utils/image/aspect-ratio.d.ts.map +1 -0
  76. package/dist/utils/image/aspect-ratio.js +40 -0
  77. package/dist/utils/image/aspect-ratio.js.map +1 -0
  78. package/dist/utils/image/background.d.ts +6 -0
  79. package/dist/utils/image/background.d.ts.map +1 -0
  80. package/dist/utils/image/background.js +22 -0
  81. package/dist/utils/image/background.js.map +1 -0
  82. package/dist/utils/image/compression.d.ts +44 -0
  83. package/dist/utils/image/compression.d.ts.map +1 -0
  84. package/dist/utils/image/compression.js +345 -0
  85. package/dist/utils/image/compression.js.map +1 -0
  86. package/dist/utils/image/gravity.d.ts +6 -0
  87. package/dist/utils/image/gravity.d.ts.map +1 -0
  88. package/dist/utils/image/gravity.js +24 -0
  89. package/dist/utils/image/gravity.js.map +1 -0
  90. package/dist/utils/image/index.d.ts +8 -0
  91. package/dist/utils/image/index.d.ts.map +1 -0
  92. package/dist/utils/image/index.js +77 -0
  93. package/dist/utils/image/index.js.map +1 -0
  94. package/dist/utils/image/param-registry.d.ts +63 -0
  95. package/dist/utils/image/param-registry.d.ts.map +1 -0
  96. package/dist/utils/image/param-registry.js +196 -0
  97. package/dist/utils/image/param-registry.js.map +1 -0
  98. package/dist/utils/image/quality.d.ts +8 -0
  99. package/dist/utils/image/quality.d.ts.map +1 -0
  100. package/dist/utils/image/quality.js +9 -0
  101. package/dist/utils/image/quality.js.map +1 -0
  102. package/dist/utils/image/resize.d.ts +7 -0
  103. package/dist/utils/image/resize.d.ts.map +1 -0
  104. package/dist/utils/image/resize.js +62 -0
  105. package/dist/utils/image/resize.js.map +1 -0
  106. package/dist/utils/image/rotation.d.ts +6 -0
  107. package/dist/utils/image/rotation.d.ts.map +1 -0
  108. package/dist/utils/image/rotation.js +20 -0
  109. package/dist/utils/image/rotation.js.map +1 -0
  110. package/dist/utils/image/round-corners.d.ts +12 -0
  111. package/dist/utils/image/round-corners.d.ts.map +1 -0
  112. package/dist/utils/image/round-corners.js +102 -0
  113. package/dist/utils/image/round-corners.js.map +1 -0
  114. package/dist/utils/image/types.d.ts +2 -0
  115. package/dist/utils/image/types.d.ts.map +1 -0
  116. package/dist/utils/image/types.js +2 -0
  117. package/dist/utils/image/types.js.map +1 -0
  118. package/dist/utils/logger.d.ts +21 -0
  119. package/dist/utils/logger.d.ts.map +1 -0
  120. package/dist/utils/logger.js +82 -0
  121. package/dist/utils/logger.js.map +1 -0
  122. package/dist/utils/parser.d.ts +8 -0
  123. package/dist/utils/parser.d.ts.map +1 -0
  124. package/dist/utils/parser.js +226 -0
  125. package/dist/utils/parser.js.map +1 -0
  126. package/dist/utils/signature.d.ts +35 -0
  127. package/dist/utils/signature.d.ts.map +1 -0
  128. package/dist/utils/signature.js +100 -0
  129. package/dist/utils/signature.js.map +1 -0
  130. package/dist/utils/storage/cache.d.ts +41 -0
  131. package/dist/utils/storage/cache.d.ts.map +1 -0
  132. package/dist/utils/storage/cache.js +90 -0
  133. package/dist/utils/storage/cache.js.map +1 -0
  134. package/dist/utils/storage/cloud-storage.d.ts +188 -0
  135. package/dist/utils/storage/cloud-storage.d.ts.map +1 -0
  136. package/dist/utils/storage/cloud-storage.js +514 -0
  137. package/dist/utils/storage/cloud-storage.js.map +1 -0
  138. package/dist/utils/storage/factory.d.ts +10 -0
  139. package/dist/utils/storage/factory.d.ts.map +1 -0
  140. package/dist/utils/storage/factory.js +17 -0
  141. package/dist/utils/storage/factory.js.map +1 -0
  142. package/dist/utils/storage/index.d.ts +7 -0
  143. package/dist/utils/storage/index.d.ts.map +1 -0
  144. package/dist/utils/storage/index.js +8 -0
  145. package/dist/utils/storage/index.js.map +1 -0
  146. package/dist/utils/storage/key-generator.d.ts +11 -0
  147. package/dist/utils/storage/key-generator.d.ts.map +1 -0
  148. package/dist/utils/storage/key-generator.js +23 -0
  149. package/dist/utils/storage/key-generator.js.map +1 -0
  150. package/dist/utils/storage/listing-cache.d.ts +14 -0
  151. package/dist/utils/storage/listing-cache.d.ts.map +1 -0
  152. package/dist/utils/storage/listing-cache.js +29 -0
  153. package/dist/utils/storage/listing-cache.js.map +1 -0
  154. package/dist/utils/storage/s3-client.d.ts +97 -0
  155. package/dist/utils/storage/s3-client.d.ts.map +1 -0
  156. package/dist/utils/storage/s3-client.js +297 -0
  157. package/dist/utils/storage/s3-client.js.map +1 -0
  158. package/dist/utils/storage/stats-tracker.d.ts +45 -0
  159. package/dist/utils/storage/stats-tracker.d.ts.map +1 -0
  160. package/dist/utils/storage/stats-tracker.js +97 -0
  161. package/dist/utils/storage/stats-tracker.js.map +1 -0
  162. package/dist/utils/storage/types.d.ts +2 -0
  163. package/dist/utils/storage/types.d.ts.map +1 -0
  164. package/dist/utils/storage/types.js +2 -0
  165. package/dist/utils/storage/types.js.map +1 -0
  166. package/dist/utils/storage-level.d.ts +66 -0
  167. package/dist/utils/storage-level.d.ts.map +1 -0
  168. package/dist/utils/storage-level.js +106 -0
  169. package/dist/utils/storage-level.js.map +1 -0
  170. package/dist/utils/storage-tree.d.ts +30 -0
  171. package/dist/utils/storage-tree.d.ts.map +1 -0
  172. package/dist/utils/storage-tree.js +81 -0
  173. package/dist/utils/storage-tree.js.map +1 -0
  174. package/dist/utils/upload-signature.d.ts +25 -0
  175. package/dist/utils/upload-signature.d.ts.map +1 -0
  176. package/dist/utils/upload-signature.js +56 -0
  177. package/dist/utils/upload-signature.js.map +1 -0
  178. package/dist/utils/video/auto-downscale.d.ts +12 -0
  179. package/dist/utils/video/auto-downscale.d.ts.map +1 -0
  180. package/dist/utils/video/auto-downscale.js +29 -0
  181. package/dist/utils/video/auto-downscale.js.map +1 -0
  182. package/dist/utils/video/command-builder.d.ts +22 -0
  183. package/dist/utils/video/command-builder.d.ts.map +1 -0
  184. package/dist/utils/video/command-builder.js +79 -0
  185. package/dist/utils/video/command-builder.js.map +1 -0
  186. package/dist/utils/video/config.d.ts +51 -0
  187. package/dist/utils/video/config.d.ts.map +1 -0
  188. package/dist/utils/video/config.js +170 -0
  189. package/dist/utils/video/config.js.map +1 -0
  190. package/dist/utils/video/format.d.ts +22 -0
  191. package/dist/utils/video/format.d.ts.map +1 -0
  192. package/dist/utils/video/format.js +64 -0
  193. package/dist/utils/video/format.js.map +1 -0
  194. package/dist/utils/video/index.d.ts +25 -0
  195. package/dist/utils/video/index.d.ts.map +1 -0
  196. package/dist/utils/video/index.js +104 -0
  197. package/dist/utils/video/index.js.map +1 -0
  198. package/dist/utils/video/param-registry.d.ts +64 -0
  199. package/dist/utils/video/param-registry.d.ts.map +1 -0
  200. package/dist/utils/video/param-registry.js +201 -0
  201. package/dist/utils/video/param-registry.js.map +1 -0
  202. package/dist/utils/video/quality.d.ts +12 -0
  203. package/dist/utils/video/quality.d.ts.map +1 -0
  204. package/dist/utils/video/quality.js +45 -0
  205. package/dist/utils/video/quality.js.map +1 -0
  206. package/dist/utils/video/queue-store.d.ts +51 -0
  207. package/dist/utils/video/queue-store.d.ts.map +1 -0
  208. package/dist/utils/video/queue-store.js +2 -0
  209. package/dist/utils/video/queue-store.js.map +1 -0
  210. package/dist/utils/video/resize.d.ts +7 -0
  211. package/dist/utils/video/resize.d.ts.map +1 -0
  212. package/dist/utils/video/resize.js +40 -0
  213. package/dist/utils/video/resize.js.map +1 -0
  214. package/dist/utils/video/sqlite-video-job-store.d.ts +29 -0
  215. package/dist/utils/video/sqlite-video-job-store.d.ts.map +1 -0
  216. package/dist/utils/video/sqlite-video-job-store.js +320 -0
  217. package/dist/utils/video/sqlite-video-job-store.js.map +1 -0
  218. package/dist/utils/video/thumbnail.d.ts +7 -0
  219. package/dist/utils/video/thumbnail.d.ts.map +1 -0
  220. package/dist/utils/video/thumbnail.js +22 -0
  221. package/dist/utils/video/thumbnail.js.map +1 -0
  222. package/dist/utils/video/trim.d.ts +7 -0
  223. package/dist/utils/video/trim.d.ts.map +1 -0
  224. package/dist/utils/video/trim.js +36 -0
  225. package/dist/utils/video/trim.js.map +1 -0
  226. package/dist/utils/video/types.d.ts +19 -0
  227. package/dist/utils/video/types.d.ts.map +1 -0
  228. package/dist/utils/video/types.js +2 -0
  229. package/dist/utils/video/types.js.map +1 -0
  230. package/dist/utils/video/video-info.d.ts +25 -0
  231. package/dist/utils/video/video-info.d.ts.map +1 -0
  232. package/dist/utils/video/video-info.js +58 -0
  233. package/dist/utils/video/video-info.js.map +1 -0
  234. package/dist/utils/video/video-worker.d.ts +52 -0
  235. package/dist/utils/video/video-worker.d.ts.map +1 -0
  236. package/dist/utils/video/video-worker.js +192 -0
  237. package/dist/utils/video/video-worker.js.map +1 -0
  238. package/dist/utils/video-job-queue.d.ts +62 -0
  239. package/dist/utils/video-job-queue.d.ts.map +1 -0
  240. package/dist/utils/video-job-queue.js +122 -0
  241. package/dist/utils/video-job-queue.js.map +1 -0
  242. package/package.json +51 -0
@@ -0,0 +1,192 @@
1
+ import { EventEmitter } from "events";
2
+ import { transformVideo } from "./index.js";
3
+ import { saveToCache } from "../cache.js";
4
+ import logger, { serializeError } from "../logger.js";
5
+ import { MAX_CONCURRENT_JOBS, WORKER_POLL_INTERVAL_MS } from "./config.js";
6
+ import { contentTypeForFormat, determineOutputFormat } from "./format.js";
7
+ /**
8
+ * Background worker for processing video jobs
9
+ */
10
+ export class VideoWorker extends EventEmitter {
11
+ intervalId = null;
12
+ maxConcurrent;
13
+ pollInterval;
14
+ storage;
15
+ store;
16
+ isAcquiring = false;
17
+ constructor(storage, store) {
18
+ super();
19
+ this.storage = storage;
20
+ this.store = store;
21
+ this.maxConcurrent = MAX_CONCURRENT_JOBS;
22
+ this.pollInterval = WORKER_POLL_INTERVAL_MS;
23
+ }
24
+ /**
25
+ * Start the worker
26
+ */
27
+ start() {
28
+ if (this.intervalId) {
29
+ logger.warn("Worker already started");
30
+ return;
31
+ }
32
+ logger.info({
33
+ maxConcurrent: this.maxConcurrent,
34
+ pollInterval: this.pollInterval,
35
+ }, "Starting video worker");
36
+ // Reset any orphaned "processing" jobs from previous crashes/restarts
37
+ // These are jobs marked as "processing" but not actually being processed
38
+ const resetCount = this.store.resetOrphanedProcessingJobs();
39
+ if (resetCount > 0) {
40
+ logger.info({ resetCount }, "Reset orphaned processing jobs on worker start");
41
+ }
42
+ // Start polling for jobs
43
+ this.intervalId = setInterval(() => {
44
+ this.fillAvailableSlots().catch((error) => {
45
+ logger.error({ error: serializeError(error) }, "Error in worker polling loop");
46
+ });
47
+ }, this.pollInterval);
48
+ // Also process immediately on start
49
+ this.fillAvailableSlots().catch((error) => {
50
+ logger.error({ error: serializeError(error) }, "Error in initial job processing");
51
+ });
52
+ }
53
+ /**
54
+ * Stop the worker
55
+ */
56
+ stop() {
57
+ if (this.intervalId) {
58
+ clearInterval(this.intervalId);
59
+ this.intervalId = null;
60
+ logger.info("Video worker stopped");
61
+ }
62
+ }
63
+ /**
64
+ * Set maximum concurrent jobs
65
+ */
66
+ setMaxConcurrent(n) {
67
+ this.maxConcurrent = n;
68
+ logger.info({ maxConcurrent: n }, "Updated max concurrent jobs");
69
+ }
70
+ /**
71
+ * Fill every free concurrency slot with pending jobs (runs on each poll tick)
72
+ */
73
+ async fillAvailableSlots() {
74
+ // Serialize acquisition so overlapping ticks don't grab the same job
75
+ if (this.isAcquiring) {
76
+ return;
77
+ }
78
+ try {
79
+ this.isAcquiring = true;
80
+ while (true) {
81
+ const processingCount = this.store.countProcessingJobs();
82
+ if (processingCount >= this.maxConcurrent) {
83
+ logger.debug({ processingCount, maxConcurrent: this.maxConcurrent }, "Max concurrent jobs reached, waiting...");
84
+ break;
85
+ }
86
+ // Get next pending job (atomically marks it as processing)
87
+ const job = this.store.getNextPendingJob();
88
+ if (!job) {
89
+ break; // No more pending jobs
90
+ }
91
+ logger.info({
92
+ jobId: job.id,
93
+ filePath: job.file_path,
94
+ priority: job.priority,
95
+ processingCount: processingCount + 1,
96
+ maxConcurrent: this.maxConcurrent,
97
+ }, "Dispatching video job");
98
+ // Fire and forget; errors are handled inside processJob
99
+ this.processJob(job).catch((error) => {
100
+ logger.error({ error: serializeError(error), jobId: job.id }, "Unhandled error in job processing");
101
+ });
102
+ }
103
+ }
104
+ finally {
105
+ this.isAcquiring = false;
106
+ }
107
+ }
108
+ /**
109
+ * Process a single video job (runs concurrently with other jobs)
110
+ */
111
+ async processJob(job) {
112
+ // Emit started event
113
+ this.emit("job:started", job);
114
+ try {
115
+ // Parse params from JSON
116
+ const params = JSON.parse(job.params_json);
117
+ // Download source file if using cloud storage
118
+ let sourcePath = `./public/${job.file_path}`;
119
+ if (this.storage) {
120
+ try {
121
+ const fs = await import("fs/promises");
122
+ const path = await import("path");
123
+ // Download to temp directory
124
+ const buffer = await this.storage.downloadOriginal(job.file_path);
125
+ const tempDir = "./temp";
126
+ sourcePath = path.join(tempDir, path.basename(job.file_path));
127
+ await fs.writeFile(sourcePath, buffer);
128
+ }
129
+ catch (error) {
130
+ logger.error({ error: serializeError(error), filePath: job.file_path }, "Failed to download source file from cloud storage");
131
+ throw error;
132
+ }
133
+ }
134
+ // Process video
135
+ const buffer = await transformVideo(sourcePath, params);
136
+ // Save to cache
137
+ await saveToCache(job.cache_path, buffer);
138
+ // Upload to cloud storage if configured
139
+ if (this.storage) {
140
+ const sourceExt = job.file_path.split(".").pop()?.toLowerCase();
141
+ const { format } = determineOutputFormat(sourceExt, params.format);
142
+ const contentType = contentTypeForFormat(format);
143
+ await this.storage.upload(job.file_path, params, buffer, contentType);
144
+ }
145
+ // Mark as completed
146
+ this.store.updateJobStatus(job.id, "completed", 100);
147
+ logger.info({ jobId: job.id, filePath: job.file_path }, "Video job completed successfully");
148
+ // Emit completion event
149
+ this.emit("job:completed", {
150
+ ...job,
151
+ status: "completed",
152
+ progress: 100,
153
+ });
154
+ }
155
+ catch (error) {
156
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
157
+ logger.error({
158
+ error: serializeError(error),
159
+ jobId: job.id,
160
+ filePath: job.file_path,
161
+ }, "Video job processing failed");
162
+ // Check if we should retry
163
+ if (job.retry_count < job.max_retries) {
164
+ logger.info({
165
+ jobId: job.id,
166
+ retryCount: job.retry_count + 1,
167
+ maxRetries: job.max_retries,
168
+ }, "Scheduling job for retry");
169
+ // IMPORTANT: Mark as error first, then retry will reset it to pending
170
+ this.store.updateJobStatus(job.id, "error", job.progress, errorMessage);
171
+ this.store.retryFailedJob(job.id);
172
+ }
173
+ else {
174
+ // Mark as error if max retries reached
175
+ this.store.updateJobStatus(job.id, "error", job.progress, errorMessage);
176
+ this.emit("job:error", { ...job, status: "error", error: errorMessage }, error);
177
+ }
178
+ }
179
+ }
180
+ /**
181
+ * Get worker statistics
182
+ */
183
+ getStats() {
184
+ return {
185
+ maxConcurrent: this.maxConcurrent,
186
+ pollInterval: this.pollInterval,
187
+ isRunning: !!this.intervalId,
188
+ processingCount: this.store.countProcessingJobs(),
189
+ };
190
+ }
191
+ }
192
+ //# sourceMappingURL=video-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-worker.js","sourceRoot":"","sources":["../../../src/utils/video/video-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { EventEmitter } from "events";
2
+ import { parseParams } from "./parser";
3
+ import { CloudStorage } from "./storage/index";
4
+ import { VideoWorker } from "./video/video-worker";
5
+ import type { JobStatus, VideoJobStore } from "./video/queue-store";
6
+ export type { JobStatus };
7
+ export interface VideoJob {
8
+ id: string;
9
+ filePath: string;
10
+ params: ReturnType<typeof parseParams>;
11
+ cachePath: string;
12
+ status: JobStatus;
13
+ progress?: number;
14
+ error?: string;
15
+ startedAt?: Date;
16
+ completedAt?: Date;
17
+ }
18
+ export declare class VideoJobQueue extends EventEmitter {
19
+ private worker;
20
+ private storage;
21
+ private store;
22
+ private cleanupInterval;
23
+ constructor(store: VideoJobStore);
24
+ /**
25
+ * Initialize the queue with storage client
26
+ */
27
+ initialize(storage: CloudStorage | null): void;
28
+ /**
29
+ * Add a video to the processing queue
30
+ */
31
+ addJob(filePath: string, params: ReturnType<typeof parseParams>, cachePath: string, sourcePath: string, storage: CloudStorage | null, priority?: number): Promise<string>;
32
+ /**
33
+ * Get job status
34
+ */
35
+ getJob(jobId: string): VideoJob | null;
36
+ /**
37
+ * Get job by file path and params
38
+ */
39
+ getJobByPath(filePath: string, params: ReturnType<typeof parseParams>): VideoJob | null;
40
+ /**
41
+ * Clean up old completed/error jobs
42
+ */
43
+ cleanup(): void;
44
+ /**
45
+ * Get queue stats
46
+ */
47
+ getStats(): import("..").JobStats;
48
+ /**
49
+ * Get the underlying job store (for admin/CRUD operations not exposed
50
+ * directly by this queue facade, e.g. listing or cancelling jobs).
51
+ */
52
+ getStore(): VideoJobStore;
53
+ /**
54
+ * Get worker instance (for advanced usage)
55
+ */
56
+ getWorker(): VideoWorker;
57
+ /**
58
+ * Stop the worker (for graceful shutdown)
59
+ */
60
+ stop(): void;
61
+ }
62
+ //# sourceMappingURL=video-job-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-job-queue.d.ts","sourceRoot":"","sources":["../../src/utils/video-job-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAEV,SAAS,EACT,aAAa,EACd,MAAM,qBAAqB,CAAC;AAI7B,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAmBD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,eAAe,CAA+C;gBAE1D,KAAK,EAAE,aAAa;IAwBhC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;IAiC9C;;OAEG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GAAG,IAAI,EAC5B,QAAQ,GAAE,MAAgC,GACzC,OAAO,CAAC,MAAM,CAAC;IAalB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAKtC;;OAEG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GACrC,QAAQ,GAAG,IAAI;IAKlB;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,QAAQ;IAIR;;;OAGG;IACH,QAAQ,IAAI,aAAa;IAIzB;;OAEG;IACH,SAAS,IAAI,WAAW;IAIxB;;OAEG;IACH,IAAI,IAAI,IAAI;CAOb"}
@@ -0,0 +1,122 @@
1
+ import { EventEmitter } from "events";
2
+ import logger from "./logger.js";
3
+ import { VideoWorker } from "./video/video-worker.js";
4
+ import { JOB_CLEANUP_HOURS, TRANSFORMATION_PRIORITY } from "./video/config.js";
5
+ /**
6
+ * Convert database job to legacy format for backward compatibility
7
+ */
8
+ function convertDBJob(dbJob) {
9
+ return {
10
+ id: dbJob.id,
11
+ filePath: dbJob.file_path,
12
+ params: JSON.parse(dbJob.params_json),
13
+ cachePath: dbJob.cache_path,
14
+ status: dbJob.status,
15
+ progress: dbJob.progress,
16
+ error: dbJob.error || undefined,
17
+ startedAt: dbJob.started_at ? new Date(dbJob.started_at) : undefined,
18
+ completedAt: dbJob.completed_at ? new Date(dbJob.completed_at) : undefined,
19
+ };
20
+ }
21
+ export class VideoJobQueue extends EventEmitter {
22
+ worker;
23
+ storage = null;
24
+ store;
25
+ cleanupInterval = null;
26
+ constructor(store) {
27
+ super();
28
+ this.store = store;
29
+ // Worker will be re-created with real storage once initialize() runs
30
+ this.worker = new VideoWorker(null, store);
31
+ // Forward worker events
32
+ this.worker.on("job:created", (job) => this.emit("job:created", convertDBJob(job)));
33
+ this.worker.on("job:started", (job) => this.emit("job:started", convertDBJob(job)));
34
+ this.worker.on("job:progress", (job, progress) => this.emit("job:progress", convertDBJob(job), progress));
35
+ this.worker.on("job:completed", (job) => this.emit("job:completed", convertDBJob(job)));
36
+ this.worker.on("job:error", (job, error) => this.emit("job:error", convertDBJob(job), error));
37
+ }
38
+ /**
39
+ * Initialize the queue with storage client
40
+ */
41
+ initialize(storage) {
42
+ this.storage = storage;
43
+ this.worker = new VideoWorker(storage, this.store);
44
+ // Forward worker events
45
+ this.worker.on("job:created", (job) => this.emit("job:created", convertDBJob(job)));
46
+ this.worker.on("job:started", (job) => this.emit("job:started", convertDBJob(job)));
47
+ this.worker.on("job:progress", (job, progress) => this.emit("job:progress", convertDBJob(job), progress));
48
+ this.worker.on("job:completed", (job) => this.emit("job:completed", convertDBJob(job)));
49
+ this.worker.on("job:error", (job, error) => this.emit("job:error", convertDBJob(job), error));
50
+ // Start the worker
51
+ this.worker.start();
52
+ // Periodic cleanup (every 10 minutes). Started here rather than at
53
+ // module load so it never runs against a not-yet-initialized worker.
54
+ if (!this.cleanupInterval) {
55
+ this.cleanupInterval = setInterval(() => this.cleanup(), 10 * 60 * 1000);
56
+ }
57
+ logger.info("Video job queue initialized with background worker");
58
+ }
59
+ /**
60
+ * Add a video to the processing queue
61
+ */
62
+ async addJob(filePath, params, cachePath, sourcePath, storage, priority = TRANSFORMATION_PRIORITY) {
63
+ // Create job in database
64
+ const jobId = this.store.createJob(filePath, params, cachePath, priority);
65
+ // Emit created event
66
+ const job = this.store.getJobById(jobId);
67
+ if (job) {
68
+ this.emit("job:created", convertDBJob(job));
69
+ }
70
+ return jobId;
71
+ }
72
+ /**
73
+ * Get job status
74
+ */
75
+ getJob(jobId) {
76
+ const dbJob = this.store.getJobById(jobId);
77
+ return dbJob ? convertDBJob(dbJob) : null;
78
+ }
79
+ /**
80
+ * Get job by file path and params
81
+ */
82
+ getJobByPath(filePath, params) {
83
+ const dbJob = this.store.getJobByFileAndParams(filePath, params);
84
+ return dbJob ? convertDBJob(dbJob) : null;
85
+ }
86
+ /**
87
+ * Clean up old completed/error jobs
88
+ */
89
+ cleanup() {
90
+ this.store.cleanupOldJobs(JOB_CLEANUP_HOURS);
91
+ }
92
+ /**
93
+ * Get queue stats
94
+ */
95
+ getStats() {
96
+ return this.store.getJobStats();
97
+ }
98
+ /**
99
+ * Get the underlying job store (for admin/CRUD operations not exposed
100
+ * directly by this queue facade, e.g. listing or cancelling jobs).
101
+ */
102
+ getStore() {
103
+ return this.store;
104
+ }
105
+ /**
106
+ * Get worker instance (for advanced usage)
107
+ */
108
+ getWorker() {
109
+ return this.worker;
110
+ }
111
+ /**
112
+ * Stop the worker (for graceful shutdown)
113
+ */
114
+ stop() {
115
+ this.worker.stop();
116
+ if (this.cleanupInterval) {
117
+ clearInterval(this.cleanupInterval);
118
+ this.cleanupInterval = null;
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=video-job-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-job-queue.js","sourceRoot":"","sources":["../../src/utils/video-job-queue.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@openinary/core",
3
+ "version": "1.1.0",
4
+ "description": "Openinary's media transformation engine and route handlers (image/video processing, storage, job queue) as a standalone, embeddable package.",
5
+ "type": "module",
6
+ "license": "AGPL-3.0-only",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/openinary/openinary",
10
+ "directory": "packages/core"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "dependencies": {
28
+ "@aws-sdk/client-s3": "^3.855.0",
29
+ "@aws-sdk/s3-request-presigner": "^3.855.0",
30
+ "@webtoon/psd": "^0.4.0",
31
+ "better-sqlite3": "^11.8.1",
32
+ "fflate": "^0.8.3",
33
+ "fluent-ffmpeg": "^2.1.2",
34
+ "hono": "^4.12.30",
35
+ "pino": "^10.1.0",
36
+ "pino-pretty": "^13.1.2",
37
+ "sharp": "^0.33.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/better-sqlite3": "^7.6.12",
41
+ "@types/fluent-ffmpeg": "^2.1.27",
42
+ "@types/node": "^24.2.0",
43
+ "tsx": "^4.7.0",
44
+ "typescript": "^5.9.2"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc && node scripts/add-js-extensions.cjs",
48
+ "type-check": "tsc --noEmit",
49
+ "test": "node --import tsx --test $(find src -name '*.test.ts')"
50
+ }
51
+ }