Skip to content

Commit 905dca7

Browse files
committed
fix: skip PDF companion locks when opening EPUBs
1 parent 65f6954 commit 905dca7

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎electron/main.mjs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { createAppIcon } from './main/services/app-icon.mjs';
3838
import { createCompanionServer } from './main/services/companion-server.mjs';
3939
import {
4040
configureEPUBSupport,
41+
isEPUBPath,
4142
readSystemPDF,
4243
validateSystemPDF,
4344
pdfLaunchPaths,
@@ -323,6 +324,8 @@ else {
323324
return error;
324325
};
325326
const claimCompanionID = async (id, target, notificationTarget = target, options = {}) => {
327+
// Companion transfer and revision locks operate on source PDF files only.
328+
if (isEPUBPath(recents?.path(id))) return { available: false };
326329
if (!id || !companion?.claimDesktopDocument) return { available: false };
327330
const state = registry.stateFor(target);
328331
if (state?.companionDocumentId === id && state.companionSessionID)
@@ -422,6 +425,7 @@ else {
422425
};
423426
const claimCompanionPath = async (path, target, notificationTarget = target, options = {}) => {
424427
if (typeof path !== 'string' || !path) return { available: false };
428+
if (isEPUBPath(path)) return { available: false };
425429
let id = recentIDForPath(path);
426430
let prepared;
427431
if (!id && companion?.claimDesktopDocument && recents?.prepare) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert/strict';
3+
import { readFile } from 'node:fs/promises';
4+
import { isEPUBPath } from '../../../electron/main/services/documents.mjs';
5+
6+
// Exercise the composition root's real claim entry points without starting Electron.
7+
const source = await readFile(new URL('../../../electron/main.mjs', import.meta.url), 'utf8');
8+
const claims = source.slice(
9+
source.indexOf(' const claimCompanionID ='),
10+
source.indexOf(' const companionOwnership ='),
11+
);
12+
const createClaims = new Function(
13+
'isEPUBPath',
14+
'recents',
15+
'companion',
16+
`
17+
const windows = new Map(), desktopClaimsInFlight = new Map();
18+
const registry = { stateFor: () => undefined };
19+
const desktopSessionID = () => 'session';
20+
const handoffLockWaitMs = 30000;
21+
const recentIDForPath = path => recents.path('recent') === path ? 'recent' : undefined;
22+
const notifyCompanionLock = () => {};
23+
${claims}
24+
return { byID: claimCompanionID, byPath: claimCompanionPath };
25+
`,
26+
);
27+
28+
test('EPUB launch and recent opens bypass PDF-only companion claims', async () => {
29+
for (const path of ['/books/new.epub', '/books/RECENT.EPUB']) {
30+
const recents = { path: () => path, prepare: () => assert.fail('prepared EPUB for companion') };
31+
const companion = { claimDesktopDocument: () => assert.fail('claimed EPUB as PDF') };
32+
const claim = createClaims(isEPUBPath, recents, companion);
33+
assert.deepEqual(await claim.byPath(path, {}), { available: false });
34+
assert.deepEqual(await claim.byID('recent', {}), { available: false });
35+
}
36+
});
37+
38+
test('PDF opens still claim companion ownership', async () => {
39+
const calls = [];
40+
const claim = createClaims(
41+
isEPUBPath,
42+
{ path: () => '/books/book.pdf' },
43+
{
44+
claimDesktopDocument: async (...args) => {
45+
calls.push(args);
46+
return { claimed: true };
47+
},
48+
},
49+
);
50+
assert.deepEqual(await claim.byPath('/books/book.pdf', {}), { claimed: true });
51+
assert.equal(calls.length, 1);
52+
assert.deepEqual(calls[0], ['recent', 'session', 'This Mac']);
53+
});

0 commit comments

Comments
 (0)