markpdfdown 0.4.5 → 0.4.7

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.
@@ -71129,11 +71129,14 @@ function mapCloudTasksToTasks(cloudTasks) {
71129
71129
  }
71130
71130
  const { Text: Text$4 } = Typography;
71131
71131
  const CLOUD_MODEL_TIERS$1 = ["lite", "pro", "ultra"];
71132
+ const cloudProgressCache = /* @__PURE__ */ new Map();
71132
71133
  const List = () => {
71133
71134
  const { message: message2, modal } = App$1.useApp();
71134
71135
  const { t: t2 } = useTranslation("list");
71135
71136
  const { t: tCommon } = useTranslation("common");
71136
71137
  const cloudContext = reactExports.useContext(CloudContext);
71138
+ const cloudIsAuthenticated = cloudContext?.isAuthenticated ?? false;
71139
+ const cloudGetTasks = cloudContext?.getTasks;
71137
71140
  const [loading, setLoading] = reactExports.useState(false);
71138
71141
  const [data, setData] = reactExports.useState([]);
71139
71142
  const [pagination, setPagination] = reactExports.useState({
@@ -71146,6 +71149,10 @@ const List = () => {
71146
71149
  const pollTimerRef = reactExports.useRef(null);
71147
71150
  const paginationRef = reactExports.useRef(pagination);
71148
71151
  paginationRef.current = pagination;
71152
+ const pendingRefreshRef = reactExports.useRef(false);
71153
+ const refreshTimerRef = reactExports.useRef(null);
71154
+ const dataRef = reactExports.useRef(data);
71155
+ dataRef.current = data;
71149
71156
  const MAX_FETCH_ITEMS = 100;
71150
71157
  const buildLocalModelValue = (modelId, providerId) => `${modelId}@${providerId}`;
71151
71158
  const parseLocalModelValue = (value) => {
@@ -71192,8 +71199,8 @@ const List = () => {
71192
71199
  const promises = [
71193
71200
  window.api.task.getAll({ page: 1, pageSize: MAX_FETCH_ITEMS })
71194
71201
  ];
71195
- if (cloudContext?.isAuthenticated) {
71196
- promises.push(cloudContext.getTasks(1, MAX_FETCH_ITEMS));
71202
+ if (cloudIsAuthenticated && cloudGetTasks) {
71203
+ promises.push(cloudGetTasks(1, MAX_FETCH_ITEMS));
71197
71204
  }
71198
71205
  const results = await Promise.all(promises);
71199
71206
  const localResult = results[0];
@@ -71228,7 +71235,50 @@ const List = () => {
71228
71235
  combinedList.sort((a2, b) => getTimestamp(b) - getTimestamp(a2));
71229
71236
  const startIndex = (page - 1) * pageSize;
71230
71237
  const paginatedList = combinedList.slice(startIndex, startIndex + pageSize);
71231
- setData(paginatedList);
71238
+ setData((prevData) => {
71239
+ const existingMap = /* @__PURE__ */ new Map();
71240
+ for (const item of prevData) {
71241
+ if (item.isCloud && item.id) {
71242
+ existingMap.set(item.id, item);
71243
+ }
71244
+ }
71245
+ return paginatedList.map((task) => {
71246
+ if (task.isCloud && task.id) {
71247
+ const fromState = existingMap.get(task.id);
71248
+ const fromCache = cloudProgressCache.get(task.id);
71249
+ const maxProgress = Math.max(
71250
+ task.progress || 0,
71251
+ fromState?.progress || 0,
71252
+ fromCache?.progress || 0
71253
+ );
71254
+ const maxCompleted = Math.max(
71255
+ task.completed_count || 0,
71256
+ fromState?.completed_count || 0,
71257
+ fromCache?.completed_count || 0
71258
+ );
71259
+ const maxFailed = Math.max(
71260
+ task.failed_count || 0,
71261
+ fromState?.failed_count || 0,
71262
+ fromCache?.failed_count || 0
71263
+ );
71264
+ cloudProgressCache.set(task.id, {
71265
+ progress: maxProgress,
71266
+ completed_count: maxCompleted,
71267
+ failed_count: maxFailed,
71268
+ status: task.status ?? fromCache?.status ?? 0
71269
+ });
71270
+ if (maxProgress > (task.progress || 0) || maxCompleted > (task.completed_count || 0)) {
71271
+ return {
71272
+ ...task,
71273
+ progress: maxProgress,
71274
+ completed_count: maxCompleted,
71275
+ failed_count: maxFailed
71276
+ };
71277
+ }
71278
+ }
71279
+ return task;
71280
+ });
71281
+ });
71232
71282
  setPagination((prev2) => ({
71233
71283
  ...prev2,
71234
71284
  current: page,
@@ -71241,7 +71291,7 @@ const List = () => {
71241
71291
  } finally {
71242
71292
  setLoading(false);
71243
71293
  }
71244
- }, [message2, t2, cloudContext]);
71294
+ }, [message2, t2, cloudIsAuthenticated, cloudGetTasks]);
71245
71295
  const handleTaskEvent = reactExports.useCallback((event) => {
71246
71296
  const { type: type4, taskId, task } = event;
71247
71297
  console.log(`[List] Received task event: ${type4}`, { taskId, task });
@@ -71291,27 +71341,33 @@ const List = () => {
71291
71341
  reactExports.useEffect(() => {
71292
71342
  if (!window.api?.events?.onCloudTaskEvent) return;
71293
71343
  console.log("[List] Registering cloud SSE event listener");
71294
- let pendingRefresh = false;
71295
71344
  const handleCloudEvent = (event) => {
71296
- const { type: type4, data: data2 } = event;
71345
+ const { type: type4, data: eventData } = event;
71297
71346
  if (type4 === "heartbeat" || type4 === "connected") return;
71298
- const taskId = data2.task_id;
71347
+ const taskId = eventData.task_id;
71299
71348
  if (!taskId) return;
71300
71349
  console.log(`[List] Cloud SSE event: type=${type4}, task_id=${taskId}`);
71301
- setData((prevData) => {
71302
- const index2 = prevData.findIndex((t22) => t22.id === taskId);
71303
- if (index2 === -1) {
71304
- if (!pendingRefresh) {
71305
- pendingRefresh = true;
71306
- queueMicrotask(() => {
71307
- pendingRefresh = false;
71308
- fetchTasks(paginationRef.current.current, paginationRef.current.pageSize);
71309
- });
71310
- }
71311
- return prevData;
71350
+ const currentData = dataRef.current;
71351
+ const index2 = currentData.findIndex((t22) => t22.id === taskId);
71352
+ if (index2 === -1) {
71353
+ if (!pendingRefreshRef.current) {
71354
+ pendingRefreshRef.current = true;
71355
+ refreshTimerRef.current = setTimeout(async () => {
71356
+ try {
71357
+ await fetchTasks(paginationRef.current.current, paginationRef.current.pageSize);
71358
+ } finally {
71359
+ pendingRefreshRef.current = false;
71360
+ refreshTimerRef.current = null;
71361
+ }
71362
+ }, 500);
71312
71363
  }
71364
+ return;
71365
+ }
71366
+ setData((prevData) => {
71367
+ const idx = prevData.findIndex((t22) => t22.id === taskId);
71368
+ if (idx === -1) return prevData;
71313
71369
  const newData = [...prevData];
71314
- const task = { ...newData[index2] };
71370
+ const task = { ...newData[idx] };
71315
71371
  switch (type4) {
71316
71372
  case "page_started":
71317
71373
  case "page_retry_started": {
@@ -71319,11 +71375,15 @@ const List = () => {
71319
71375
  break;
71320
71376
  }
71321
71377
  case "page_completed": {
71322
- const pageNumber = data2.page;
71323
- const totalPages = data2.total_pages || task.pages || 1;
71324
- const completed = Math.max(task.completed_count || 0, pageNumber || 0);
71325
- task.completed_count = completed;
71326
- task.progress = Math.round(completed / totalPages * 100);
71378
+ const pageNumber = eventData.page;
71379
+ const totalPages = eventData.total_pages || task.pages || 1;
71380
+ if (task.status === 8) {
71381
+ task.completed_count = (task.completed_count || 0) + 1;
71382
+ task.failed_count = Math.max(0, (task.failed_count || 0) - 1);
71383
+ } else {
71384
+ task.completed_count = Math.max(task.completed_count || 0, pageNumber || 0);
71385
+ }
71386
+ task.progress = Math.round((task.completed_count || 0) / totalPages * 100);
71327
71387
  task.status = 3;
71328
71388
  break;
71329
71389
  }
@@ -71332,15 +71392,15 @@ const List = () => {
71332
71392
  break;
71333
71393
  }
71334
71394
  case "completed": {
71335
- task.status = data2.status || 6;
71395
+ task.status = eventData.status || 6;
71336
71396
  task.progress = 100;
71337
- task.completed_count = data2.pages_completed;
71338
- task.failed_count = data2.pages_failed;
71397
+ task.completed_count = eventData.pages_completed;
71398
+ task.failed_count = eventData.pages_failed;
71339
71399
  break;
71340
71400
  }
71341
71401
  case "error": {
71342
71402
  task.status = 0;
71343
- task.error = data2.error;
71403
+ task.error = eventData.error;
71344
71404
  break;
71345
71405
  }
71346
71406
  case "cancelled": {
@@ -71349,13 +71409,26 @@ const List = () => {
71349
71409
  }
71350
71410
  case "pdf_ready": {
71351
71411
  task.status = 3;
71352
- task.pages = data2.page_count;
71412
+ task.pages = eventData.page_count;
71353
71413
  break;
71354
71414
  }
71355
71415
  default:
71356
71416
  return prevData;
71357
71417
  }
71358
- newData[index2] = task;
71418
+ newData[idx] = task;
71419
+ if (task.id) {
71420
+ const terminalStatuses = [0, 6, 7, 8];
71421
+ if (terminalStatuses.includes(task.status ?? -1)) {
71422
+ cloudProgressCache.delete(task.id);
71423
+ } else {
71424
+ cloudProgressCache.set(task.id, {
71425
+ progress: task.progress || 0,
71426
+ completed_count: task.completed_count || 0,
71427
+ failed_count: task.failed_count || 0,
71428
+ status: task.status ?? 0
71429
+ });
71430
+ }
71431
+ }
71359
71432
  return newData;
71360
71433
  });
71361
71434
  };
@@ -71363,6 +71436,11 @@ const List = () => {
71363
71436
  return () => {
71364
71437
  console.log("[List] Cleaning up cloud SSE event listener");
71365
71438
  cleanup2();
71439
+ if (refreshTimerRef.current) {
71440
+ clearTimeout(refreshTimerRef.current);
71441
+ refreshTimerRef.current = null;
71442
+ pendingRefreshRef.current = false;
71443
+ }
71366
71444
  };
71367
71445
  }, [fetchTasks]);
71368
71446
  reactExports.useEffect(() => {
@@ -126300,13 +126378,20 @@ const CloudPreview = () => {
126300
126378
  }
126301
126379
  return [...prev2, { page, status: 2, status_name: "COMPLETED", markdown: markdown2, width_mm: 210, height_mm: 297 }];
126302
126380
  });
126303
- setTask((prev2) => prev2 ? {
126304
- ...prev2,
126305
- pages_completed: (prev2.pages_completed || 0) + 1
126306
- } : null);
126381
+ setTask((prev2) => {
126382
+ if (!prev2) return null;
126383
+ const updates = {
126384
+ pages_completed: (prev2.pages_completed || 0) + 1
126385
+ };
126386
+ if (prev2.status === 8) {
126387
+ updates.pages_failed = Math.max(0, (prev2.pages_failed || 0) - 1);
126388
+ }
126389
+ return { ...prev2, ...updates };
126390
+ });
126307
126391
  break;
126308
126392
  }
126309
- case "page_started": {
126393
+ case "page_started":
126394
+ case "page_retry_started": {
126310
126395
  const { page } = event.data;
126311
126396
  setPages((prev2) => {
126312
126397
  const idx = prev2.findIndex((p2) => p2.page === page);
@@ -126344,6 +126429,9 @@ const CloudPreview = () => {
126344
126429
  pages_completed: data.pages_completed,
126345
126430
  pages_failed: data.pages_failed
126346
126431
  } : null);
126432
+ if (data.pages_failed === 0) {
126433
+ setPages((prev2) => prev2.map((p2) => p2.status !== 2 ? { ...p2, status: 2, status_name: "COMPLETED" } : p2));
126434
+ }
126347
126435
  break;
126348
126436
  }
126349
126437
  case "error": {
@@ -130469,41 +130557,64 @@ const CloudProvider = ({ children }) => {
130469
130557
  });
130470
130558
  return cleanup2;
130471
130559
  }, [isAuthenticated, refreshCredits]);
130472
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
130473
- CloudContext.Provider,
130474
- {
130475
- value: {
130476
- user,
130477
- credits,
130478
- isAuthenticated,
130479
- isLoading,
130480
- deviceFlowStatus,
130481
- userCode,
130482
- verificationUrl,
130483
- authError,
130484
- login,
130485
- logout,
130486
- cancelLogin,
130487
- refreshCredits,
130488
- convertFile,
130489
- getTasks,
130490
- getTaskById,
130491
- getTaskPages,
130492
- cancelTask,
130493
- retryTask,
130494
- deleteTask,
130495
- retryPage,
130496
- getTaskResult,
130497
- downloadResult,
130498
- createCheckout,
130499
- getCheckoutStatus,
130500
- reconcileCheckout,
130501
- getCreditHistory,
130502
- getPaymentHistory
130503
- },
130504
- children
130505
- }
130506
- );
130560
+ const contextValue = reactExports.useMemo(() => ({
130561
+ user,
130562
+ credits,
130563
+ isAuthenticated,
130564
+ isLoading,
130565
+ deviceFlowStatus,
130566
+ userCode,
130567
+ verificationUrl,
130568
+ authError,
130569
+ login,
130570
+ logout,
130571
+ cancelLogin,
130572
+ refreshCredits,
130573
+ convertFile,
130574
+ getTasks,
130575
+ getTaskById,
130576
+ getTaskPages,
130577
+ cancelTask,
130578
+ retryTask,
130579
+ deleteTask,
130580
+ retryPage,
130581
+ getTaskResult,
130582
+ downloadResult,
130583
+ createCheckout,
130584
+ getCheckoutStatus,
130585
+ reconcileCheckout,
130586
+ getCreditHistory,
130587
+ getPaymentHistory
130588
+ }), [
130589
+ user,
130590
+ credits,
130591
+ isAuthenticated,
130592
+ isLoading,
130593
+ deviceFlowStatus,
130594
+ userCode,
130595
+ verificationUrl,
130596
+ authError,
130597
+ login,
130598
+ logout,
130599
+ cancelLogin,
130600
+ refreshCredits,
130601
+ convertFile,
130602
+ getTasks,
130603
+ getTaskById,
130604
+ getTaskPages,
130605
+ cancelTask,
130606
+ retryTask,
130607
+ deleteTask,
130608
+ retryPage,
130609
+ getTaskResult,
130610
+ downloadResult,
130611
+ createCheckout,
130612
+ getCheckoutStatus,
130613
+ reconcileCheckout,
130614
+ getCreditHistory,
130615
+ getPaymentHistory
130616
+ ]);
130617
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CloudContext.Provider, { value: contextValue, children });
130507
130618
  };
130508
130619
  clientExports.createRoot(document.getElementById("root")).render(
130509
130620
  /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CloudProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) }) })
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>MarkPDFdown</title>
8
- <script type="module" crossorigin src="./assets/index-BDl2RVlc.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-CG2nvY4Z.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-DXcyx2Q8.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markpdfdown",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "A high-quality PDF to Markdown tool based on large language model visual recognition.",
5
5
  "author": "MarkPDFdown",
6
6
  "main": "dist/main/index.js",