pixivflow 2.12.3 → 2.13.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 (131) hide show
  1. package/README.md +12 -4
  2. package/dist/commands/DoctorCommand.d.ts +20 -0
  3. package/dist/commands/DoctorCommand.d.ts.map +1 -0
  4. package/dist/commands/DoctorCommand.js +107 -0
  5. package/dist/commands/DoctorCommand.js.map +1 -0
  6. package/dist/commands/ReconcileCommand.d.ts +24 -0
  7. package/dist/commands/ReconcileCommand.d.ts.map +1 -0
  8. package/dist/commands/ReconcileCommand.js +70 -0
  9. package/dist/commands/ReconcileCommand.js.map +1 -0
  10. package/dist/commands/SchedulerCommand.d.ts.map +1 -1
  11. package/dist/commands/SchedulerCommand.js +5 -0
  12. package/dist/commands/SchedulerCommand.js.map +1 -1
  13. package/dist/commands/SchedulerRunOnceCommand.d.ts.map +1 -1
  14. package/dist/commands/SchedulerRunOnceCommand.js +6 -0
  15. package/dist/commands/SchedulerRunOnceCommand.js.map +1 -1
  16. package/dist/commands/index.d.ts +3 -1
  17. package/dist/commands/index.d.ts.map +1 -1
  18. package/dist/commands/index.js +7 -1
  19. package/dist/commands/index.js.map +1 -1
  20. package/dist/commands/scheduler-runtime.d.ts +10 -1
  21. package/dist/commands/scheduler-runtime.d.ts.map +1 -1
  22. package/dist/commands/scheduler-runtime.js +157 -47
  23. package/dist/commands/scheduler-runtime.js.map +1 -1
  24. package/dist/config/types.d.ts +10 -1
  25. package/dist/config/types.d.ts.map +1 -1
  26. package/dist/delivery/DeliveryAck.d.ts +70 -0
  27. package/dist/delivery/DeliveryAck.d.ts.map +1 -0
  28. package/dist/delivery/DeliveryAck.js +72 -0
  29. package/dist/delivery/DeliveryAck.js.map +1 -0
  30. package/dist/delivery/DeliveryDispatcher.js +1 -1
  31. package/dist/delivery/DeliveryDispatcher.js.map +1 -1
  32. package/dist/delivery/DeliveryService.d.ts +74 -0
  33. package/dist/delivery/DeliveryService.d.ts.map +1 -0
  34. package/dist/delivery/DeliveryService.js +207 -0
  35. package/dist/delivery/DeliveryService.js.map +1 -0
  36. package/dist/delivery/HttpMultipartDelivery.d.ts +10 -1
  37. package/dist/delivery/HttpMultipartDelivery.d.ts.map +1 -1
  38. package/dist/delivery/HttpMultipartDelivery.js +40 -65
  39. package/dist/delivery/HttpMultipartDelivery.js.map +1 -1
  40. package/dist/delivery/LegacyOutboxMigration.d.ts +21 -0
  41. package/dist/delivery/LegacyOutboxMigration.d.ts.map +1 -0
  42. package/dist/delivery/LegacyOutboxMigration.js +125 -0
  43. package/dist/delivery/LegacyOutboxMigration.js.map +1 -0
  44. package/dist/delivery/OutboxWorker.d.ts +69 -0
  45. package/dist/delivery/OutboxWorker.d.ts.map +1 -0
  46. package/dist/delivery/OutboxWorker.js +194 -0
  47. package/dist/delivery/OutboxWorker.js.map +1 -0
  48. package/dist/delivery/types.d.ts +11 -0
  49. package/dist/delivery/types.d.ts.map +1 -1
  50. package/dist/download/DownloadManager.d.ts +17 -12
  51. package/dist/download/DownloadManager.d.ts.map +1 -1
  52. package/dist/download/DownloadManager.js +31 -53
  53. package/dist/download/DownloadManager.js.map +1 -1
  54. package/dist/download/NovelDownloader.d.ts +3 -1
  55. package/dist/download/NovelDownloader.d.ts.map +1 -1
  56. package/dist/download/NovelDownloader.js +30 -2
  57. package/dist/download/NovelDownloader.js.map +1 -1
  58. package/dist/download/handlers/IllustrationTargetHandler.d.ts +18 -8
  59. package/dist/download/handlers/IllustrationTargetHandler.d.ts.map +1 -1
  60. package/dist/download/handlers/IllustrationTargetHandler.js +100 -74
  61. package/dist/download/handlers/IllustrationTargetHandler.js.map +1 -1
  62. package/dist/download/handlers/NovelTargetHandler.d.ts +8 -8
  63. package/dist/download/handlers/NovelTargetHandler.d.ts.map +1 -1
  64. package/dist/download/handlers/NovelTargetHandler.js +64 -83
  65. package/dist/download/handlers/NovelTargetHandler.js.map +1 -1
  66. package/dist/download/plan/DownloadPlanner.d.ts +6 -1
  67. package/dist/download/plan/DownloadPlanner.d.ts.map +1 -1
  68. package/dist/download/plan/DownloadPlanner.js +28 -5
  69. package/dist/download/plan/DownloadPlanner.js.map +1 -1
  70. package/dist/notification/NotificationPolicy.d.ts +38 -0
  71. package/dist/notification/NotificationPolicy.d.ts.map +1 -0
  72. package/dist/notification/NotificationPolicy.js +89 -0
  73. package/dist/notification/NotificationPolicy.js.map +1 -0
  74. package/dist/package.json +1 -1
  75. package/dist/pixiv/PixivClient.d.ts +4 -0
  76. package/dist/pixiv/PixivClient.d.ts.map +1 -1
  77. package/dist/pixiv/PixivClient.js +15 -2
  78. package/dist/pixiv/PixivClient.js.map +1 -1
  79. package/dist/pixiv/RateLimitCoordinator.d.ts +30 -0
  80. package/dist/pixiv/RateLimitCoordinator.d.ts.map +1 -0
  81. package/dist/pixiv/RateLimitCoordinator.js +66 -0
  82. package/dist/pixiv/RateLimitCoordinator.js.map +1 -0
  83. package/dist/pixiv/client/PixivApiCore.d.ts +5 -0
  84. package/dist/pixiv/client/PixivApiCore.d.ts.map +1 -1
  85. package/dist/pixiv/client/PixivApiCore.js +31 -9
  86. package/dist/pixiv/client/PixivApiCore.js.map +1 -1
  87. package/dist/scheduler/ScheduleTriggerServer.d.ts +7 -0
  88. package/dist/scheduler/ScheduleTriggerServer.d.ts.map +1 -1
  89. package/dist/scheduler/ScheduleTriggerServer.js +17 -0
  90. package/dist/scheduler/ScheduleTriggerServer.js.map +1 -1
  91. package/dist/scheduler/SlotCoordinator.d.ts +15 -0
  92. package/dist/scheduler/SlotCoordinator.d.ts.map +1 -1
  93. package/dist/scheduler/SlotCoordinator.js +74 -0
  94. package/dist/scheduler/SlotCoordinator.js.map +1 -1
  95. package/dist/scheduler/SlotStateMachine.d.ts +32 -0
  96. package/dist/scheduler/SlotStateMachine.d.ts.map +1 -0
  97. package/dist/scheduler/SlotStateMachine.js +65 -0
  98. package/dist/scheduler/SlotStateMachine.js.map +1 -0
  99. package/dist/scheduler/TargetOutcome.d.ts +63 -0
  100. package/dist/scheduler/TargetOutcome.d.ts.map +1 -0
  101. package/dist/scheduler/TargetOutcome.js +28 -0
  102. package/dist/scheduler/TargetOutcome.js.map +1 -0
  103. package/dist/storage/Database.d.ts +16 -0
  104. package/dist/storage/Database.d.ts.map +1 -1
  105. package/dist/storage/Database.js +29 -0
  106. package/dist/storage/Database.js.map +1 -1
  107. package/dist/storage/DatabaseMigration.d.ts.map +1 -1
  108. package/dist/storage/DatabaseMigration.js +66 -0
  109. package/dist/storage/DatabaseMigration.js.map +1 -1
  110. package/dist/storage/repositories/DeliveryRepository.d.ts +73 -0
  111. package/dist/storage/repositories/DeliveryRepository.d.ts.map +1 -0
  112. package/dist/storage/repositories/DeliveryRepository.js +148 -0
  113. package/dist/storage/repositories/DeliveryRepository.js.map +1 -0
  114. package/dist/storage/repositories/MetadataRepository.d.ts +27 -0
  115. package/dist/storage/repositories/MetadataRepository.d.ts.map +1 -0
  116. package/dist/storage/repositories/MetadataRepository.js +58 -0
  117. package/dist/storage/repositories/MetadataRepository.js.map +1 -0
  118. package/dist/storage/repositories/OutboxRepository.d.ts +70 -0
  119. package/dist/storage/repositories/OutboxRepository.d.ts.map +1 -0
  120. package/dist/storage/repositories/OutboxRepository.js +187 -0
  121. package/dist/storage/repositories/OutboxRepository.js.map +1 -0
  122. package/dist/storage/repositories/SlotRepository.d.ts +26 -1
  123. package/dist/storage/repositories/SlotRepository.d.ts.map +1 -1
  124. package/dist/storage/repositories/SlotRepository.js +76 -2
  125. package/dist/storage/repositories/SlotRepository.js.map +1 -1
  126. package/dist/webui/package.json +1 -1
  127. package/package.json +1 -1
  128. package/dist/delivery/DeliveryOutbox.d.ts +0 -43
  129. package/dist/delivery/DeliveryOutbox.d.ts.map +0 -1
  130. package/dist/delivery/DeliveryOutbox.js +0 -293
  131. package/dist/delivery/DeliveryOutbox.js.map +0 -1
@@ -11,9 +11,7 @@ const DownloadExecutor_1 = require("./exec/DownloadExecutor");
11
11
  const ErrorRecovery_1 = require("./recovery/ErrorRecovery");
12
12
  const DownloadPipeline_1 = require("./pipeline/DownloadPipeline");
13
13
  const errors_1 = require("../utils/errors");
14
- const DeliveryDispatcher_1 = require("../delivery/DeliveryDispatcher");
15
- const DeliveryOutbox_1 = require("../delivery/DeliveryOutbox");
16
- const node_path_1 = require("node:path");
14
+ const DeliveryService_1 = require("../delivery/DeliveryService");
17
15
  const IllustrationTargetHandler_1 = require("./handlers/IllustrationTargetHandler");
18
16
  const NovelTargetHandler_1 = require("./handlers/NovelTargetHandler");
19
17
  const createTopicPipeline_1 = require("../topic/createTopicPipeline");
@@ -56,19 +54,19 @@ class DownloadManager {
56
54
  // Cooperative cancellation state (see cancel())
57
55
  cancelled = false;
58
56
  cancelReason = '';
59
- deliveryOutbox;
60
- /** Per-target outcome hook (used by the Slot ledger to record cell results). */
57
+ deliveryService;
58
+ /** Per-target TYPED outcome hook (the Slot ledger maps it to cell transitions). */
61
59
  onTargetOutcome = null;
62
- /** Fired when a work is locked for delivery (fresh or outbox replay). */
63
- onWorkLocked = null;
64
- /** Register a callback fired after each target with the error if it failed. */
60
+ /** Register a callback fired after each target with its explicit business outcome. */
65
61
  setTargetOutcomeHook(fn) {
66
62
  this.onTargetOutcome = fn;
67
63
  }
68
- /** Register a callback fired when a Pixiv work is selected and locked for a target. */
69
- setWorkLockedHook(fn) {
70
- this.onWorkLocked = fn;
64
+ /** Expose delivery service for handlers (preflight + intent creation). */
65
+ get deliveries() {
66
+ return this.deliveryService;
71
67
  }
68
+ /** Slot context propagated to delivery templates/outcomes for scheduled runs. */
69
+ slotContext;
72
70
  /**
73
71
  * Request cooperative cancellation of the current run. In-flight item
74
72
  * finishes; no further targets/items are started. runAllTargets() will
@@ -92,8 +90,10 @@ class DownloadManager {
92
90
  const downloadConcurrency = config.download?.concurrency || 3;
93
91
  const storagePath = config.storage?.illustrationDirectory ?? config.storage?.downloadDirectory ?? './downloads';
94
92
  this.illustrationDownloader = new IllustrationDownloader_1.IllustrationDownloader(client, database, fileService, downloadConcurrency, storagePath);
95
- this.novelDownloader = new NovelDownloader_1.NovelDownloader(client, database, fileService);
96
- this.planner = new DownloadPlanner_1.DownloadPlanner(database);
93
+ this.novelDownloader = new NovelDownloader_1.NovelDownloader(client, database, fileService, database);
94
+ this.planner = new DownloadPlanner_1.DownloadPlanner(database, {
95
+ deliveredIds: (target, type, ids) => this.deliveryService.deliveredIds(target, type, ids),
96
+ });
97
97
  this.executor = new DownloadExecutor_1.DownloadExecutor();
98
98
  const downloadConfig = config.download ?? {};
99
99
  const maxRetries = downloadConfig.maxRetries ?? 3;
@@ -112,19 +112,16 @@ class DownloadManager {
112
112
  recovery: this.errorRecovery,
113
113
  isCancelled: () => this.cancelled,
114
114
  });
115
- const databasePath = config.storage?.databasePath ?? './data/pixiv-downloader.db';
116
- const deliveryDispatcher = new DeliveryDispatcher_1.DeliveryDispatcher(config.delivery, this.buildProxyUrl(config.network));
117
- this.deliveryOutbox = new DeliveryOutbox_1.DeliveryOutbox((0, node_path_1.join)((0, node_path_1.dirname)(databasePath), 'delivery-outbox'), deliveryDispatcher, config.delivery?.deleteAfterDelivery !== false, {
118
- retryBaseDelayMs: config.delivery?.outboxRetryBaseMs,
119
- retryMaxDelayMs: config.delivery?.outboxRetryMaxMs,
120
- onDeliver: (artifact, target) => this.onWorkLocked?.(artifact, target),
121
- });
115
+ // Delivery ledger + SQLite outbox. Requires the concrete Database (with the
116
+ // deliveries/outbox repositories). Unit tests pass plain mock databases; in
117
+ // that case delivery dedupe/enqueue is simply inactive.
118
+ this.deliveryService = new DeliveryService_1.DeliveryService(database);
122
119
  // One lazily-created topic pipeline (shared resolver/cache) for this run.
123
120
  const topicFactory = (0, createTopicPipeline_1.createTopicPipelineFactory)(client, typeof database.getDatabasePath === 'function'
124
121
  ? database
125
122
  : config.storage?.databasePath, config.download?.requestDelay ?? 500);
126
- this.illustrationHandler = new IllustrationTargetHandler_1.IllustrationTargetHandler(client, database, this.rankingService, this.illustrationDownloader, this.pipeline, this.deliveryOutbox, topicFactory);
127
- this.novelHandler = new NovelTargetHandler_1.NovelTargetHandler(client, database, this.rankingService, this.pipeline, this.novelDownloader, this.deliveryOutbox, topicFactory);
123
+ this.illustrationHandler = new IllustrationTargetHandler_1.IllustrationTargetHandler(client, database, this.rankingService, this.illustrationDownloader, this.pipeline, topicFactory, this.deliveryService);
124
+ this.novelHandler = new NovelTargetHandler_1.NovelTargetHandler(client, database, this.rankingService, this.pipeline, this.novelDownloader, topicFactory, this.deliveryService);
128
125
  }
129
126
  setProgressCallback(callback) {
130
127
  this.progressReporter.setCallback(callback);
@@ -133,13 +130,8 @@ class DownloadManager {
133
130
  await this.fileService.initialise();
134
131
  }
135
132
  async runAllTargets() {
136
- const pending = await this.deliveryOutbox.retryPending();
137
- if (pending.succeeded > 0 || pending.failed > 0) {
138
- logger_1.logger.info('Processed pending deliveries', { ...pending });
139
- }
140
- else if (pending.deferred > 0) {
141
- logger_1.logger.debug('Pending deliveries remain in backoff', { ...pending });
142
- }
133
+ // NOTE: pending deliveries are pumped independently by the OutboxWorker,
134
+ // not piggy-backed onto the next download run. No retryPending() here.
143
135
  const totalTargets = this.config.targets.length;
144
136
  if (totalTargets === 0) {
145
137
  this.progressReporter.complete(0, '所有目标处理完成');
@@ -156,14 +148,18 @@ class DownloadManager {
156
148
  const targetName = target.filterTag || target.tag || 'unknown';
157
149
  this.updateProgress(currentTarget, totalTargets, `处理目标: ${targetName} (${target.type})`);
158
150
  try {
159
- await this.dispatchTarget(target);
160
- this.onTargetOutcome?.(target);
151
+ const outcome = await this.dispatchTarget(target);
152
+ this.onTargetOutcome?.(target, outcome);
153
+ if (outcome.kind === 'failed' && !outcome.retryable) {
154
+ errors.push({ target: `${targetName} (${target.type})`, error: outcome.error });
155
+ }
161
156
  }
162
157
  catch (error) {
158
+ // A raw escape means an unexpected/retryable infrastructure failure.
163
159
  const errorMessage = error instanceof Error ? error.message : String(error);
164
160
  errors.push({ target: `${targetName} (${target.type})`, error: errorMessage });
165
161
  logger_1.logger.error(`Target ${targetName} (${target.type}) failed, continuing with next target`, { error: errorMessage });
166
- this.onTargetOutcome?.(target, errorMessage);
162
+ this.onTargetOutcome?.(target, { kind: 'failed', retryable: true, error: errorMessage });
167
163
  }
168
164
  }
169
165
  if (this.cancelled) {
@@ -184,35 +180,17 @@ class DownloadManager {
184
180
  async dispatchTarget(target) {
185
181
  switch (target.type) {
186
182
  case 'illustration':
187
- await this.illustrationHandler.handle(target);
188
- break;
183
+ return await this.illustrationHandler.handle(target);
189
184
  case 'novel':
190
- await this.novelHandler.handle(target);
191
- break;
185
+ return await this.novelHandler.handle(target);
192
186
  default:
193
187
  logger_1.logger.warn(`Unsupported target type ${target.type}`);
188
+ return { kind: 'failed', retryable: false, error: `unsupported target type ${target.type}` };
194
189
  }
195
190
  }
196
191
  updateProgress(current, total, message) {
197
192
  this.progressReporter.update(current, total, message);
198
193
  }
199
- buildProxyUrl(network) {
200
- const proxy = network?.proxy;
201
- if (!proxy?.enabled) {
202
- return undefined;
203
- }
204
- const protocol = proxy.protocol ?? 'http';
205
- if (protocol !== 'http' && protocol !== 'https') {
206
- logger_1.logger.warn(`HTTP multipart delivery does not support ${protocol} proxy through undici; delivering directly`);
207
- return undefined;
208
- }
209
- const url = new URL(`${protocol}://${proxy.host}:${proxy.port}`);
210
- if (proxy.username)
211
- url.username = proxy.username;
212
- if (proxy.password)
213
- url.password = proxy.password;
214
- return url.toString();
215
- }
216
194
  }
217
195
  exports.DownloadManager = DownloadManager;
218
196
  //# sourceMappingURL=DownloadManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DownloadManager.js","sourceRoot":"","sources":["../../src/download/DownloadManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DownloadManager.js","sourceRoot":"","sources":["../../src/download/DownloadManager.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,13 @@ import { IDatabase } from '../interfaces/IDatabase';
4
4
  import { IFileService } from '../interfaces/IFileService';
5
5
  import { PixivNovel } from '../pixiv/PixivClient';
6
6
  import { DownloadedArtifact } from '../delivery/types';
7
+ import type { Database } from '../storage/Database';
7
8
  export declare class NovelDownloader {
8
9
  private readonly client;
9
10
  private readonly database;
10
11
  private readonly fileService;
11
- constructor(client: IPixivClient, database: IDatabase, fileService: IFileService);
12
+ private readonly metadataDb?;
13
+ constructor(client: IPixivClient, database: IDatabase, fileService: IFileService, metadataDb?: Database | undefined);
12
14
  download(novel: PixivNovel, tag: string, target: TargetConfig): Promise<DownloadedArtifact | undefined>;
13
15
  }
14
16
  //# sourceMappingURL=NovelDownloader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NovelDownloader.d.ts","sourceRoot":"","sources":["../../src/download/NovelDownloader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,SAAS,EACnB,WAAW,EAAE,YAAY;IAGtC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;CA0K9G"}
1
+ {"version":3,"file":"NovelDownloader.d.ts","sourceRoot":"","sources":["../../src/download/NovelDownloader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAHX,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,SAAS,EACnB,WAAW,EAAE,YAAY,EACzB,UAAU,CAAC,EAAE,QAAQ,YAAA;IAGlC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;CAuM9G"}
@@ -36,16 +36,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.NovelDownloader = void 0;
37
37
  const logger_1 = require("../logger");
38
38
  const language_detection_1 = require("../utils/language-detection");
39
+ const LANGUAGE_CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
39
40
  class NovelDownloader {
40
41
  client;
41
42
  database;
42
43
  fileService;
43
- constructor(client, database, fileService) {
44
+ metadataDb;
45
+ constructor(client, database, fileService, metadataDb) {
44
46
  this.client = client;
45
47
  this.database = database;
46
48
  this.fileService = fileService;
49
+ this.metadataDb = metadataDb;
47
50
  }
48
51
  async download(novel, tag, target) {
52
+ // Metadata cache: language filtering otherwise pulls FULL text per candidate
53
+ // on every fallback run. A cached classification short-circuits to the same
54
+ // skip decision without any Pixiv request (bounded detail/text fetch volume).
55
+ if (target.languageFilter && this.metadataDb) {
56
+ const cached = this.metadataDb?.metadata?.fresh?.(String(novel.id), 'novel', LANGUAGE_CACHE_TTL_MS);
57
+ if (cached?.language) {
58
+ const isChinese = cached.language.includes('Chinese') || cached.language.startsWith('zh');
59
+ const wanted = (target.languageFilter === 'chinese' && isChinese) ||
60
+ (target.languageFilter === 'non-chinese' && !isChinese);
61
+ if (!wanted) {
62
+ const reason = target.languageFilter === 'chinese' ? 'not Chinese' : 'is Chinese';
63
+ logger_1.logger.info(`Novel ${novel.id} language filter from cache (${cached.language}): ${reason}`, {
64
+ novelId: novel.id, filter: target.languageFilter, cached: true,
65
+ });
66
+ throw new Error(`Novel ${novel.id} skipped: language filter mismatch (cached: ${cached.language}, required: ${target.languageFilter})`);
67
+ }
68
+ // Cached match: still need full text to deliver; fall through to fetch.
69
+ }
70
+ }
49
71
  const { novel: detail, tags } = await this.client.getNovelDetailWithTags(novel.id);
50
72
  // getNovelText resolves to the API envelope { novel_text }; unwrap it here,
51
73
  // otherwise the object gets stringified to "[object Object]" and the
@@ -65,7 +87,7 @@ class NovelDownloader {
65
87
  let detectedLang = null;
66
88
  if (enableDetection) {
67
89
  const fullContent = `${detail.title}\n${text}`;
68
- detectedLang = (0, language_detection_1.detectLanguage)(fullContent);
90
+ detectedLang = await (0, language_detection_1.detectLanguage)(fullContent);
69
91
  if (detectedLang) {
70
92
  logger_1.logger.info(`Detected language for novel ${detail.id}: ${detectedLang.name} (${detectedLang.code})`, {
71
93
  novelId: detail.id,
@@ -73,6 +95,12 @@ class NovelDownloader {
73
95
  code: detectedLang.code,
74
96
  isChinese: detectedLang.isChinese,
75
97
  });
98
+ this.metadataDb?.metadata?.put?.(String(detail.id), 'novel', {
99
+ language: detectedLang.name,
100
+ xRestrict: detail.x_restrict ?? novel.x_restrict ?? null,
101
+ publishedAt: detail.create_date ?? novel.create_date ?? null,
102
+ title: detail.title,
103
+ });
76
104
  }
77
105
  else {
78
106
  logger_1.logger.debug(`Language detection inconclusive for novel ${detail.id} (text may be too short)`);
@@ -1 +1 @@
1
- {"version":3,"file":"NovelDownloader.js","sourceRoot":"","sources":["../../src/download/NovelDownloader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NovelDownloader.js","sourceRoot":"","sources":["../../src/download/NovelDownloader.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,8 @@ import { IDatabase } from '../../interfaces/IDatabase';
4
4
  import { RankingService } from '../RankingService';
5
5
  import { IllustrationDownloader } from '../IllustrationDownloader';
6
6
  import { DownloadPipeline } from '../pipeline/DownloadPipeline';
7
- import { DeliveryOutbox } from '../../delivery/DeliveryOutbox';
7
+ import { DeliveryService } from '../../delivery/DeliveryService';
8
+ import { TargetOutcome } from '../../scheduler/TargetOutcome';
8
9
  import type { TopicPipelineFactory } from '../../topic/createTopicPipeline';
9
10
  export declare class IllustrationTargetHandler {
10
11
  private readonly client;
@@ -12,10 +13,15 @@ export declare class IllustrationTargetHandler {
12
13
  private readonly rankingService;
13
14
  private readonly illustrationDownloader;
14
15
  private readonly pipeline;
15
- private readonly deliveryOutbox?;
16
16
  private readonly topicPipelineFactory?;
17
- constructor(client: IPixivClient, database: IDatabase, rankingService: RankingService, illustrationDownloader: IllustrationDownloader, pipeline: DownloadPipeline, deliveryOutbox?: DeliveryOutbox | undefined, topicPipelineFactory?: TopicPipelineFactory | undefined);
18
- handle(target: TargetConfig): Promise<void>;
17
+ private readonly deliveryService?;
18
+ /** Outcomes produced during this handle() call (deliveries + terminal non-matches). */
19
+ private outcomes;
20
+ constructor(client: IPixivClient, database: IDatabase, rankingService: RankingService, illustrationDownloader: IllustrationDownloader, pipeline: DownloadPipeline, topicPipelineFactory?: TopicPipelineFactory | undefined, deliveryService?: DeliveryService | undefined);
21
+ handle(target: TargetConfig): Promise<TargetOutcome>;
22
+ /** Reduce the outcomes collected while processing one target to one cell result. */
23
+ private summarize;
24
+ private classifyError;
19
25
  private fetchIllustrations;
20
26
  private fetchTopicIllustrations;
21
27
  private handleTopicWithLookback;
@@ -25,14 +31,18 @@ export declare class IllustrationTargetHandler {
25
31
  private fetchSearchIllustrations;
26
32
  private handleDownloadResult;
27
33
  private handleZeroDownloads;
28
- private handleError;
29
- /** Notify the review group when a target's download hard-fails (not just a no-match). */
30
- private notifyDownloadFailure;
31
- private notifyNoMatch;
32
34
  private handleSingleIllustration;
33
35
  private handleUserIllustrations;
34
36
  private sortByPopularityAndLog;
35
37
  private logError;
36
38
  private downloadAndDeliver;
39
+ /**
40
+ * Turn a downloaded artifact into the target's business outcome. In cache
41
+ * delivery mode the DeliveryService creates the durable intent atomically and
42
+ * the result is 'delivery_pending' (NOT submitted — the OutboxWorker confirms
43
+ * the ACK). Persistent/download-only runs are 'stored'.
44
+ */
45
+ private recordArtifactOutcome;
46
+ private executionContextFields;
37
47
  }
38
48
  //# sourceMappingURL=IllustrationTargetHandler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IllustrationTargetHandler.d.ts","sourceRoot":"","sources":["../../../src/download/handlers/IllustrationTargetHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBANrB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,SAAS,EACnB,cAAc,EAAE,cAAc,EAC9B,sBAAsB,EAAE,sBAAsB,EAC9C,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,cAAc,YAAA,EAC/B,oBAAoB,CAAC,EAAE,oBAAoB,YAAA;IAGxD,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;YAoCnC,kBAAkB;YAWlB,uBAAuB;YA2BvB,uBAAuB;IAqCrC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,QAAQ;YAMF,yBAAyB;YA4CzB,wBAAwB;IAwBtC,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,mBAAmB;YA2Cb,WAAW;IAwBzB,yFAAyF;YAC3E,qBAAqB;YAqBrB,aAAa;YAgBb,wBAAwB;YAuBxB,uBAAuB;IAiCrC,OAAO,CAAC,sBAAsB;IAgC9B,OAAO,CAAC,QAAQ;YAmBF,kBAAkB;CAiBjC"}
1
+ {"version":3,"file":"IllustrationTargetHandler.d.ts","sourceRoot":"","sources":["../../../src/download/handlers/IllustrationTargetHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,qBAAa,yBAAyB;IAKlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAVnC,uFAAuF;IACvF,OAAO,CAAC,QAAQ,CAAuB;gBAGpB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,SAAS,EACnB,cAAc,EAAE,cAAc,EAC9B,sBAAsB,EAAE,sBAAsB,EAC9C,QAAQ,EAAE,gBAAgB,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,YAAA,EAC3C,eAAe,CAAC,EAAE,eAAe,YAAA;IAG9C,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAmC1D,oFAAoF;IACpF,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,aAAa;YAgBP,kBAAkB;YAWlB,uBAAuB;YA2BvB,uBAAuB;IAoCrC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,QAAQ;YAMF,yBAAyB;YA4CzB,wBAAwB;IAwBtC,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,mBAAmB;YAmDb,wBAAwB;YAuBxB,uBAAuB;IAiCrC,OAAO,CAAC,sBAAsB;IAgC9B,OAAO,CAAC,QAAQ;YAmBF,kBAAkB;IAiBhC;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,sBAAsB;CAY/B"}
@@ -12,25 +12,28 @@ class IllustrationTargetHandler {
12
12
  rankingService;
13
13
  illustrationDownloader;
14
14
  pipeline;
15
- deliveryOutbox;
16
15
  topicPipelineFactory;
17
- constructor(client, database, rankingService, illustrationDownloader, pipeline, deliveryOutbox, topicPipelineFactory) {
16
+ deliveryService;
17
+ /** Outcomes produced during this handle() call (deliveries + terminal non-matches). */
18
+ outcomes = [];
19
+ constructor(client, database, rankingService, illustrationDownloader, pipeline, topicPipelineFactory, deliveryService) {
18
20
  this.client = client;
19
21
  this.database = database;
20
22
  this.rankingService = rankingService;
21
23
  this.illustrationDownloader = illustrationDownloader;
22
24
  this.pipeline = pipeline;
23
- this.deliveryOutbox = deliveryOutbox;
24
25
  this.topicPipelineFactory = topicPipelineFactory;
26
+ this.deliveryService = deliveryService;
25
27
  }
26
28
  async handle(target) {
29
+ this.outcomes = [];
27
30
  if (target.illustId) {
28
31
  await this.handleSingleIllustration(target);
29
- return;
32
+ return this.summarize(target);
30
33
  }
31
34
  if (target.userId) {
32
35
  await this.handleUserIllustrations(target);
33
- return;
36
+ return this.summarize(target);
34
37
  }
35
38
  const mode = target.mode || 'search';
36
39
  const displayTag = (0, target_label_1.getTargetLabel)(target);
@@ -38,18 +41,50 @@ class IllustrationTargetHandler {
38
41
  try {
39
42
  if (mode === 'topic') {
40
43
  await this.handleTopicWithLookback(target, displayTag);
41
- return;
44
+ return this.summarize(target);
42
45
  }
43
46
  const illusts = await this.fetchIllustrations(target, mode);
44
47
  const result = await this.pipeline.run(illusts, target, 'illustration', (illust, tag) => this.downloadAndDeliver(illust, tag, target));
45
48
  this.handleDownloadResult(result, target, mode, illusts.length);
49
+ return this.summarize(target);
46
50
  }
47
51
  catch (error) {
48
- if (error instanceof Error && error.message.startsWith('No matching illustrations found after checking')) {
49
- throw error;
50
- }
51
- await this.handleError(error, displayTag, mode, target);
52
+ return this.classifyError(error, displayTag, mode, target);
53
+ }
54
+ }
55
+ /** Reduce the outcomes collected while processing one target to one cell result. */
56
+ summarize(target) {
57
+ const submitted = this.outcomes.find((o) => o.kind === 'submitted');
58
+ if (submitted)
59
+ return submitted;
60
+ const stored = this.outcomes.find((o) => o.kind === 'stored');
61
+ if (stored)
62
+ return stored;
63
+ const pending = this.outcomes.find((o) => o.kind === 'delivery_pending');
64
+ if (pending)
65
+ return pending;
66
+ const duplicate = this.outcomes.find((o) => o.kind === 'duplicate');
67
+ if (duplicate)
68
+ return duplicate;
69
+ const failed = this.outcomes.find((o) => o.kind === 'failed');
70
+ if (failed)
71
+ return failed;
72
+ return { kind: 'no_candidate', reason: 'no matching illustration after filtering/dedupe' };
73
+ }
74
+ classifyError(error, displayTag, mode, target) {
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ this.database.logExecution(displayTag, 'illustration', 'failed', message);
77
+ logger_1.logger.error(`Illustration ${mode === 'ranking' ? 'ranking' : 'tag'} ${displayTag} failed`, {
78
+ error: message,
79
+ errorType: error instanceof Error ? error.constructor.name : typeof error,
80
+ });
81
+ // Explicit no-candidate signals are business outcomes, not failures.
82
+ if (/no matching|all .*filtered|no_candidate/i.test(message)) {
83
+ return { kind: 'no_candidate', reason: message };
52
84
  }
85
+ // Network/transient => retryable so the SAME work resumes on next trigger.
86
+ const retryable = error instanceof errors_1.NetworkError || /timeout|econn|enotfound|etimed|429|5dd/i.test(message);
87
+ return { kind: 'failed', retryable, error: message };
53
88
  }
54
89
  async fetchIllustrations(target, mode) {
55
90
  if (mode === 'topic') {
@@ -106,8 +141,7 @@ class IllustrationTargetHandler {
106
141
  const message = `No matching illustrations found after checking ${checkedDays.length} day(s): ${checkedDays.join(', ')}`;
107
142
  this.database.logExecution(displayTag, 'illustration', 'success', message);
108
143
  logger_1.logger.warn(`Illustration topic ${displayTag} produced no matching result`, { checkedDays });
109
- await this.notifyNoMatch(target, displayTag, checkedDays);
110
- throw new Error(message);
144
+ this.outcomes.push({ kind: 'no_candidate', reason: message });
111
145
  }
112
146
  resolveTopicDay(target) {
113
147
  return target.date === 'TODAY'
@@ -224,68 +258,17 @@ class IllustrationTargetHandler {
224
258
  `多为网络/Pixiv 瞬时错误,下次计划会自动重试;同一作品持续失败请查日志(可能为已删除/私密/R-18 权限)。`
225
259
  : `No new illustrations for ${tagForLog}: requested ${targetLimit}, but no matching illustrations were found.`;
226
260
  this.database.logExecution(tagForLog, 'illustration', 'failed', errorMessage);
227
- logger_1.logger.error(`Illustration ${mode === 'ranking' ? 'ranking' : 'tag'} ${tagForLog} failed: ${errorMessage}`);
228
- throw new Error(errorMessage);
229
- }
230
- }
231
- async handleError(error, displayTag, mode, target) {
232
- let errorMessage = error instanceof Error ? error.message : String(error);
233
- if (error instanceof errors_1.NetworkError && error.cause) {
234
- const causeMsg = error.cause instanceof Error ? error.cause.message : String(error.cause);
235
- errorMessage = `${errorMessage} (原因: ${causeMsg})`;
236
- }
237
- if (error instanceof errors_1.NetworkError && error.url) {
238
- errorMessage = `${errorMessage} [URL: ${error.url}]`;
239
- }
240
- this.database.logExecution(displayTag, 'illustration', 'failed', errorMessage);
241
- logger_1.logger.error(`Illustration ${mode === 'ranking' ? 'ranking' : 'tag'} ${displayTag} failed`, {
242
- error: errorMessage,
243
- errorType: error instanceof Error ? error.constructor.name : typeof error,
244
- stack: error instanceof Error ? error.stack : undefined,
245
- });
246
- await this.notifyDownloadFailure(target, displayTag, errorMessage);
247
- throw error;
248
- }
249
- /** Notify the review group when a target's download hard-fails (not just a no-match). */
250
- async notifyDownloadFailure(target, label, errorMessage) {
251
- if (!target?.delivery?.target?.trim())
252
- return;
253
- if (!this.deliveryOutbox) {
254
- logger_1.logger.warn('Download-failure notification requested but delivery outbox is unavailable');
255
- return;
256
- }
257
- const truncated = errorMessage.length > 200 ? `${errorMessage.slice(0, 200)}…` : errorMessage;
258
- const text = [
259
- '❌ PixivFlow 本次下载失败',
260
- `目标:${target.id || label}(${label} · 插画)`,
261
- `错误:${truncated}`,
262
- '处理结果:本次未投递;可点击「🔄 重抓/换一张」重试,或等待下次定时任务。',
263
- ].join('\n');
264
- const key = `pixivflow:hard-fail:${target.id || label}:illustration:${(0, pixiv_date_utils_1.getTodayDate)()}`;
265
- try {
266
- await this.deliveryOutbox.notifyNoMatch(target, text, key);
267
- }
268
- catch (notifyError) {
269
- logger_1.logger.warn('Failed to send download-failure notification', { label, errorMessage, notifyError });
270
- }
271
- }
272
- async notifyNoMatch(target, label, checkedDays) {
273
- if (target.noMatchPolicy?.notify !== true || !this.deliveryOutbox)
274
- return;
275
- const text = [
276
- '⚠️ PixivFlow 本次没有可投稿内容',
277
- `目标:${target.id || label}(${label} · 插画)`,
278
- `检查日期:${checkedDays.join('、')}`,
279
- '处理结果:未创建空投稿;下次定时任务会继续正常执行。',
280
- ].join('\n');
281
- const key = `pixivflow:no-match:${target.id || label}:illustration:${checkedDays[0]}:${checkedDays.at(-1)}`;
282
- try {
283
- await this.deliveryOutbox.notifyNoMatch(target, text, key);
284
- }
285
- catch (error) {
286
- logger_1.logger.warn('Failed to send no-match notification', { label, error });
261
+ logger_1.logger.warn(`Illustration ${mode === 'ranking' ? 'ranking' : 'tag'} ${tagForLog}: ${errorMessage}`);
262
+ // Skipped due to transient errors => no terminal submitted; caller retries.
263
+ this.outcomes.push({
264
+ kind: 'failed',
265
+ retryable: skipped > 0,
266
+ error: errorMessage,
267
+ });
287
268
  }
288
269
  }
270
+ // Notifications are produced centrally by NotificationPolicy (slot-scoped
271
+ // keys), not per-handler with date-based keys. See noteOutcome/sendSlotSummary.
289
272
  async handleSingleIllustration(target) {
290
273
  const illustId = Number(target.illustId);
291
274
  if (!Number.isFinite(illustId)) {
@@ -376,9 +359,52 @@ class IllustrationTargetHandler {
376
359
  aiMetadataCheck: target.aiMetadataCheck === true,
377
360
  maxPageCount: target.maxPageCount,
378
361
  });
379
- if (artifact && this.deliveryOutbox) {
380
- await this.deliveryOutbox.deliver(artifact, target);
362
+ if (!artifact)
363
+ return;
364
+ this.recordArtifactOutcome(artifact, target);
365
+ }
366
+ /**
367
+ * Turn a downloaded artifact into the target's business outcome. In cache
368
+ * delivery mode the DeliveryService creates the durable intent atomically and
369
+ * the result is 'delivery_pending' (NOT submitted — the OutboxWorker confirms
370
+ * the ACK). Persistent/download-only runs are 'stored'.
371
+ */
372
+ recordArtifactOutcome(artifact, target) {
373
+ const isDelivery = target.storageMode === 'cache' && target.delivery?.target?.trim();
374
+ if (!isDelivery || !this.deliveryService) {
375
+ this.outcomes.push({ kind: 'stored', workId: artifact.pixivId, workType: artifact.type });
376
+ return;
377
+ }
378
+ // Pre-lock delivery dedupe (after selection): if the ledger already knows it,
379
+ // that is a confirmed fact, not a new submission.
380
+ const slotId = target.delivery?.executionContext?.slotId;
381
+ if (this.deliveryService.isAlreadyDelivered(target.delivery.target, artifact.type, artifact.pixivId)) {
382
+ this.outcomes.push({ kind: 'duplicate', workId: artifact.pixivId, reason: 'already delivered to target (ledger)' });
383
+ return;
384
+ }
385
+ const res = this.deliveryService.enqueue(artifact, target, {
386
+ slotId,
387
+ fields: target.delivery?.fields,
388
+ extraContext: this.executionContextFields(target),
389
+ });
390
+ if (res.duplicate) {
391
+ this.outcomes.push({ kind: 'duplicate', workId: artifact.pixivId, reason: 'already delivered to target (ledger)' });
381
392
  }
393
+ else {
394
+ this.outcomes.push({ kind: 'delivery_pending', workId: artifact.pixivId, workType: artifact.type, deliveryId: res.deliveryId });
395
+ }
396
+ }
397
+ executionContextFields(target) {
398
+ const ec = target.delivery;
399
+ return {
400
+ scheduleId: ec?.executionContext?.scheduleId,
401
+ executionId: ec?.executionContext?.slotId,
402
+ occurrenceAt: ec?.executionContext?.occurrenceAtIso,
403
+ triggerSource: ec?.executionContext?.triggerSource,
404
+ slotId: ec?.slotContext?.slotId ?? ec?.executionContext?.slotId,
405
+ slotName: ec?.slotContext?.slotName ?? ec?.executionContext?.slotName,
406
+ slotDate: ec?.slotContext?.slotDate ?? ec?.executionContext?.slotDate,
407
+ };
382
408
  }
383
409
  }
384
410
  exports.IllustrationTargetHandler = IllustrationTargetHandler;