pixivflow 2.19.4 → 2.20.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.
- package/dist/commands/SchedulerCommand.js +36 -0
- package/dist/commands/SchedulerRunOnceCommand.d.ts +2 -3
- package/dist/commands/SchedulerRunOnceCommand.js +2 -3
- package/dist/commands/scheduler-runtime.js +17 -1
- package/dist/config/defaults.d.ts +1 -0
- package/dist/config/defaults.js +4 -0
- package/dist/config/environment.js +19 -0
- package/dist/config/types.d.ts +28 -0
- package/dist/config/validation.js +25 -0
- package/dist/delivery/DeliveryService.d.ts +30 -1
- package/dist/delivery/DeliveryService.js +13 -2
- package/dist/delivery/HttpMultipartDelivery.js +29 -8
- package/dist/delivery/OutboxWorker.d.ts +2 -0
- package/dist/delivery/OutboxWorker.js +3 -0
- package/dist/delivery/types.d.ts +18 -0
- package/dist/download/DownloadManager.js +12 -1
- package/dist/download/handlers/IllustrationTargetHandler.d.ts +42 -2
- package/dist/download/handlers/IllustrationTargetHandler.js +240 -50
- package/dist/download/handlers/NovelTargetHandler.d.ts +47 -0
- package/dist/download/handlers/NovelTargetHandler.js +213 -27
- package/dist/download/handlers/deliveryContext.d.ts +16 -0
- package/dist/download/handlers/deliveryContext.js +32 -0
- package/dist/download/pipeline/DownloadPipeline.d.ts +22 -3
- package/dist/download/pipeline/DownloadPipeline.js +109 -92
- package/dist/download/plan/DownloadPlanner.d.ts +47 -1
- package/dist/download/plan/DownloadPlanner.js +105 -15
- package/dist/notification/NotificationPolicy.d.ts +12 -0
- package/dist/notification/NotificationPolicy.js +86 -0
- package/dist/package.json +1 -1
- package/dist/scheduler/MultiScheduleManager.js +2 -0
- package/dist/scheduler/ScheduleTriggerServer.d.ts +58 -1
- package/dist/scheduler/ScheduleTriggerServer.js +207 -40
- package/dist/scheduler/SlotCoordinator.d.ts +80 -2
- package/dist/scheduler/SlotCoordinator.js +145 -3
- package/dist/scheduler/TargetOutcome.d.ts +195 -2
- package/dist/scheduler/TargetOutcome.js +202 -3
- package/dist/storage/DatabaseMigration.js +11 -0
- package/dist/storage/repositories/DeliveryRepository.d.ts +12 -0
- package/dist/storage/repositories/DeliveryRepository.js +18 -1
- package/dist/storage/repositories/SlotRepository.d.ts +8 -0
- package/dist/storage/repositories/SlotRepository.js +6 -2
- package/dist/version.js +1 -1
- package/dist/webui/package.json +1 -1
- package/package.json +1 -1
|
@@ -99,6 +99,15 @@ class DatabaseMigration {
|
|
|
99
99
|
lease_owner TEXT,
|
|
100
100
|
lease_until INTEGER,
|
|
101
101
|
heartbeat_at INTEGER,
|
|
102
|
+
-- Request UUID of a remote manual replacement ("重抓"). NULL for a
|
|
103
|
+
-- scheduled occurrence. Persisted in the SAME transaction that
|
|
104
|
+
-- opens the manual slot, so the acceptance ACK and the caller's
|
|
105
|
+
-- retry converge on one row instead of racing a second slot.
|
|
106
|
+
manual_request_id TEXT,
|
|
107
|
+
-- Opaque caller correlation (review chain / review id). Recorded so
|
|
108
|
+
-- the terminal outcome can be reported back to the requester
|
|
109
|
+
-- without this service learning anything about the review.
|
|
110
|
+
correlation_id TEXT,
|
|
102
111
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
103
112
|
started_at DATETIME,
|
|
104
113
|
completed_at DATETIME,
|
|
@@ -227,6 +236,8 @@ class DatabaseMigration {
|
|
|
227
236
|
lease_owner: 'ALTER TABLE schedule_slots ADD COLUMN lease_owner TEXT',
|
|
228
237
|
lease_until: 'ALTER TABLE schedule_slots ADD COLUMN lease_until INTEGER',
|
|
229
238
|
heartbeat_at: 'ALTER TABLE schedule_slots ADD COLUMN heartbeat_at INTEGER',
|
|
239
|
+
manual_request_id: 'ALTER TABLE schedule_slots ADD COLUMN manual_request_id TEXT',
|
|
240
|
+
correlation_id: 'ALTER TABLE schedule_slots ADD COLUMN correlation_id TEXT',
|
|
230
241
|
};
|
|
231
242
|
const columnAlters = [];
|
|
232
243
|
for (const [col, sql] of Object.entries(slotColumnMigrations)) {
|
|
@@ -60,6 +60,18 @@ export declare class DeliveryRepository extends BaseRepository {
|
|
|
60
60
|
isDelivered(deliveryTarget: string, workType: string, pixivId: string): boolean;
|
|
61
61
|
/** Batch form for candidate-pipeline pre-lock dedupe. */
|
|
62
62
|
deliveredIds(deliveryTarget: string, workType: string, pixivIds: string[]): Set<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Batch pre-lock dedupe for CANDIDATE SELECTION: works already delivered, or
|
|
65
|
+
* whose review submission is still PENDING.
|
|
66
|
+
*
|
|
67
|
+
* Deliberately broader than `deliveredIds`: a pending intent is a work already
|
|
68
|
+
* submitted for human review that has not been answered yet. Re-selecting it
|
|
69
|
+
* would submit the same work a second time, which is the user-visible defect
|
|
70
|
+
* this scan exists to prevent. Within-slot RESUME keeps using `isDelivered`:
|
|
71
|
+
* a cell resuming its OWN pending work is continuing it, not duplicating it.
|
|
72
|
+
*/
|
|
73
|
+
submittedIds(deliveryTarget: string, workType: string, pixivIds: string[]): Set<string>;
|
|
74
|
+
private idsByStatus;
|
|
63
75
|
recordAck(id: string, ack: {
|
|
64
76
|
status: DeliveryStatus;
|
|
65
77
|
remoteId?: string;
|
|
@@ -71,16 +71,33 @@ class DeliveryRepository extends BaseRepository_1.BaseRepository {
|
|
|
71
71
|
}
|
|
72
72
|
/** Batch form for candidate-pipeline pre-lock dedupe. */
|
|
73
73
|
deliveredIds(deliveryTarget, workType, pixivIds) {
|
|
74
|
+
return this.idsByStatus(deliveryTarget, workType, pixivIds, ['delivered', 'duplicate']);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Batch pre-lock dedupe for CANDIDATE SELECTION: works already delivered, or
|
|
78
|
+
* whose review submission is still PENDING.
|
|
79
|
+
*
|
|
80
|
+
* Deliberately broader than `deliveredIds`: a pending intent is a work already
|
|
81
|
+
* submitted for human review that has not been answered yet. Re-selecting it
|
|
82
|
+
* would submit the same work a second time, which is the user-visible defect
|
|
83
|
+
* this scan exists to prevent. Within-slot RESUME keeps using `isDelivered`:
|
|
84
|
+
* a cell resuming its OWN pending work is continuing it, not duplicating it.
|
|
85
|
+
*/
|
|
86
|
+
submittedIds(deliveryTarget, workType, pixivIds) {
|
|
87
|
+
return this.idsByStatus(deliveryTarget, workType, pixivIds, ['pending', 'delivered', 'duplicate']);
|
|
88
|
+
}
|
|
89
|
+
idsByStatus(deliveryTarget, workType, pixivIds, statuses) {
|
|
74
90
|
const out = new Set();
|
|
75
91
|
if (pixivIds.length === 0)
|
|
76
92
|
return out;
|
|
93
|
+
const statusList = statuses.map((status) => `'${status}'`).join(',');
|
|
77
94
|
const CHUNK = 400;
|
|
78
95
|
for (let i = 0; i < pixivIds.length; i += CHUNK) {
|
|
79
96
|
const slice = pixivIds.slice(i, i + CHUNK);
|
|
80
97
|
const placeholders = slice.map(() => '?').join(',');
|
|
81
98
|
const rows = this.db
|
|
82
99
|
.prepare(`SELECT DISTINCT pixiv_id FROM deliveries
|
|
83
|
-
WHERE delivery_target = ? AND work_type = ? AND status IN (
|
|
100
|
+
WHERE delivery_target = ? AND work_type = ? AND status IN (${statusList})
|
|
84
101
|
AND pixiv_id IN (${placeholders})`)
|
|
85
102
|
.all(deliveryTarget, workType, ...slice);
|
|
86
103
|
for (const r of rows)
|
|
@@ -25,6 +25,10 @@ export interface SlotRecord {
|
|
|
25
25
|
leaseOwner: string | null;
|
|
26
26
|
leaseUntil: number | null;
|
|
27
27
|
heartbeatAt: number | null;
|
|
28
|
+
/** Request UUID of a remote manual replacement; null for scheduled slots. */
|
|
29
|
+
manualRequestId: string | null;
|
|
30
|
+
/** Opaque caller correlation (review chain / review id); null unless manual. */
|
|
31
|
+
correlationId: string | null;
|
|
28
32
|
}
|
|
29
33
|
export interface SlotItemRecord {
|
|
30
34
|
id: number;
|
|
@@ -65,6 +69,10 @@ export declare class SlotRepository extends BaseRepository {
|
|
|
65
69
|
triggerSource?: string;
|
|
66
70
|
slotDate?: string;
|
|
67
71
|
slotName?: string;
|
|
72
|
+
/** Remote manual replacement request UUID (opens a `manual-` slot). */
|
|
73
|
+
manualRequestId?: string | null;
|
|
74
|
+
/** Opaque caller correlation recorded with a manual slot. */
|
|
75
|
+
correlationId?: string | null;
|
|
68
76
|
}): {
|
|
69
77
|
slot: SlotRecord;
|
|
70
78
|
created: boolean;
|
|
@@ -21,10 +21,10 @@ class SlotRepository extends BaseRepository_1.BaseRepository {
|
|
|
21
21
|
getOrCreateSlot(id, data) {
|
|
22
22
|
const insert = this.db.prepare(`INSERT INTO schedule_slots
|
|
23
23
|
(id, schedule_id, occurrence_at, occurrence_date, occurrence_label, timezone, target_ids,
|
|
24
|
-
status, trigger_source, slot_date, slot_name)
|
|
24
|
+
status, trigger_source, slot_date, slot_name, manual_request_id, correlation_id)
|
|
25
25
|
VALUES
|
|
26
26
|
(@id, @scheduleId, @occurrenceAt, @occurrenceDate, @occurrenceLabel, @timezone, @targetIds,
|
|
27
|
-
'pending', @triggerSource, @slotDate, @slotName)
|
|
27
|
+
'pending', @triggerSource, @slotDate, @slotName, @manualRequestId, @correlationId)
|
|
28
28
|
ON CONFLICT(id) DO NOTHING`);
|
|
29
29
|
const info = insert.run({
|
|
30
30
|
id,
|
|
@@ -37,6 +37,8 @@ class SlotRepository extends BaseRepository_1.BaseRepository {
|
|
|
37
37
|
triggerSource: data.triggerSource ?? null,
|
|
38
38
|
slotDate: data.slotDate ?? data.occurrenceDate ?? '',
|
|
39
39
|
slotName: data.slotName ?? '',
|
|
40
|
+
manualRequestId: data.manualRequestId ?? null,
|
|
41
|
+
correlationId: data.correlationId ?? null,
|
|
40
42
|
});
|
|
41
43
|
const created = info.changes > 0;
|
|
42
44
|
return { slot: this.getSlot(id), created };
|
|
@@ -359,6 +361,8 @@ class SlotRepository extends BaseRepository_1.BaseRepository {
|
|
|
359
361
|
leaseOwner: row.lease_owner ?? null,
|
|
360
362
|
leaseUntil: row.lease_until ?? null,
|
|
361
363
|
heartbeatAt: row.heartbeat_at ?? null,
|
|
364
|
+
manualRequestId: row.manual_request_id ?? null,
|
|
365
|
+
correlationId: row.correlation_id ?? null,
|
|
362
366
|
};
|
|
363
367
|
}
|
|
364
368
|
toItem(row) {
|
package/dist/version.js
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BUILD = void 0;
|
|
4
4
|
// GENERATED by scripts/write-version.js — do not edit manually.
|
|
5
|
-
exports.BUILD = { version: '2.
|
|
5
|
+
exports.BUILD = { version: '2.20.0', commit: '2229fb7b45a6' };
|
|
6
6
|
//# sourceMappingURL=version.js.map
|
package/dist/webui/package.json
CHANGED
package/package.json
CHANGED