mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
refactor(main): extract jellyfin and anilist runtime composers
This commit is contained in:
40
src/main/runtime/composers/anilist-setup-composer.test.ts
Normal file
40
src/main/runtime/composers/anilist-setup-composer.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { composeAnilistSetupHandlers } from './anilist-setup-composer';
|
||||
|
||||
test('composeAnilistSetupHandlers returns callable setup handlers', () => {
|
||||
const composed = composeAnilistSetupHandlers({
|
||||
notifyDeps: {
|
||||
hasMpvClient: () => false,
|
||||
showMpvOsd: () => {},
|
||||
showDesktopNotification: () => {},
|
||||
logInfo: () => {},
|
||||
},
|
||||
consumeTokenDeps: {
|
||||
consumeAnilistSetupCallbackUrl: () => false,
|
||||
saveToken: () => {},
|
||||
setCachedToken: () => {},
|
||||
setResolvedState: () => {},
|
||||
setSetupPageOpened: () => {},
|
||||
onSuccess: () => {},
|
||||
closeWindow: () => {},
|
||||
},
|
||||
handleProtocolDeps: {
|
||||
consumeAnilistSetupTokenFromUrl: () => false,
|
||||
logWarn: () => {},
|
||||
},
|
||||
registerProtocolClientDeps: {
|
||||
isDefaultApp: () => false,
|
||||
getArgv: () => [],
|
||||
execPath: process.execPath,
|
||||
resolvePath: (value) => value,
|
||||
setAsDefaultProtocolClient: () => true,
|
||||
logWarn: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(typeof composed.notifyAnilistSetup, 'function');
|
||||
assert.equal(typeof composed.consumeAnilistSetupTokenFromUrl, 'function');
|
||||
assert.equal(typeof composed.handleAnilistSetupProtocolUrl, 'function');
|
||||
assert.equal(typeof composed.registerSubminerProtocolClient, 'function');
|
||||
});
|
||||
55
src/main/runtime/composers/anilist-setup-composer.ts
Normal file
55
src/main/runtime/composers/anilist-setup-composer.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
createBuildConsumeAnilistSetupTokenFromUrlMainDepsHandler,
|
||||
createBuildHandleAnilistSetupProtocolUrlMainDepsHandler,
|
||||
createBuildNotifyAnilistSetupMainDepsHandler,
|
||||
createBuildRegisterSubminerProtocolClientMainDepsHandler,
|
||||
createConsumeAnilistSetupTokenFromUrlHandler,
|
||||
createHandleAnilistSetupProtocolUrlHandler,
|
||||
createNotifyAnilistSetupHandler,
|
||||
createRegisterSubminerProtocolClientHandler,
|
||||
} from '../domains/anilist';
|
||||
|
||||
type NotifyHandler = ReturnType<typeof createNotifyAnilistSetupHandler>;
|
||||
type ConsumeHandler = ReturnType<typeof createConsumeAnilistSetupTokenFromUrlHandler>;
|
||||
type HandleProtocolHandler = ReturnType<typeof createHandleAnilistSetupProtocolUrlHandler>;
|
||||
type RegisterClientHandler = ReturnType<typeof createRegisterSubminerProtocolClientHandler>;
|
||||
|
||||
export type AnilistSetupComposerOptions = {
|
||||
notifyDeps: Parameters<typeof createBuildNotifyAnilistSetupMainDepsHandler>[0];
|
||||
consumeTokenDeps: Parameters<typeof createBuildConsumeAnilistSetupTokenFromUrlMainDepsHandler>[0];
|
||||
handleProtocolDeps: Parameters<typeof createBuildHandleAnilistSetupProtocolUrlMainDepsHandler>[0];
|
||||
registerProtocolClientDeps: Parameters<
|
||||
typeof createBuildRegisterSubminerProtocolClientMainDepsHandler
|
||||
>[0];
|
||||
};
|
||||
|
||||
export type AnilistSetupComposerResult = {
|
||||
notifyAnilistSetup: NotifyHandler;
|
||||
consumeAnilistSetupTokenFromUrl: ConsumeHandler;
|
||||
handleAnilistSetupProtocolUrl: HandleProtocolHandler;
|
||||
registerSubminerProtocolClient: RegisterClientHandler;
|
||||
};
|
||||
|
||||
export function composeAnilistSetupHandlers(
|
||||
options: AnilistSetupComposerOptions,
|
||||
): AnilistSetupComposerResult {
|
||||
const notifyAnilistSetup = createNotifyAnilistSetupHandler(
|
||||
createBuildNotifyAnilistSetupMainDepsHandler(options.notifyDeps)(),
|
||||
);
|
||||
const consumeAnilistSetupTokenFromUrl = createConsumeAnilistSetupTokenFromUrlHandler(
|
||||
createBuildConsumeAnilistSetupTokenFromUrlMainDepsHandler(options.consumeTokenDeps)(),
|
||||
);
|
||||
const handleAnilistSetupProtocolUrl = createHandleAnilistSetupProtocolUrlHandler(
|
||||
createBuildHandleAnilistSetupProtocolUrlMainDepsHandler(options.handleProtocolDeps)(),
|
||||
);
|
||||
const registerSubminerProtocolClient = createRegisterSubminerProtocolClientHandler(
|
||||
createBuildRegisterSubminerProtocolClientMainDepsHandler(options.registerProtocolClientDeps)(),
|
||||
);
|
||||
|
||||
return {
|
||||
notifyAnilistSetup,
|
||||
consumeAnilistSetupTokenFromUrl,
|
||||
handleAnilistSetupProtocolUrl,
|
||||
registerSubminerProtocolClient,
|
||||
};
|
||||
}
|
||||
34
src/main/runtime/composers/jellyfin-remote-composer.test.ts
Normal file
34
src/main/runtime/composers/jellyfin-remote-composer.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { composeJellyfinRemoteHandlers } from './jellyfin-remote-composer';
|
||||
|
||||
test('composeJellyfinRemoteHandlers returns callable jellyfin remote handlers', () => {
|
||||
let lastProgressAt = 0;
|
||||
const composed = composeJellyfinRemoteHandlers({
|
||||
getConfiguredSession: () => null,
|
||||
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: 'test', deviceId: 'dev' }) as never,
|
||||
getJellyfinConfig: () => ({ enabled: false }) as never,
|
||||
playJellyfinItem: async () => {},
|
||||
logWarn: () => {},
|
||||
getMpvClient: () => null,
|
||||
sendMpvCommand: () => {},
|
||||
jellyfinTicksToSeconds: () => 0,
|
||||
getActivePlayback: () => null,
|
||||
clearActivePlayback: () => {},
|
||||
getSession: () => null,
|
||||
getNow: () => 0,
|
||||
getLastProgressAtMs: () => lastProgressAt,
|
||||
setLastProgressAtMs: (next) => {
|
||||
lastProgressAt = next;
|
||||
},
|
||||
progressIntervalMs: 3000,
|
||||
ticksPerSecond: 10_000_000,
|
||||
logDebug: () => {},
|
||||
});
|
||||
|
||||
assert.equal(typeof composed.reportJellyfinRemoteProgress, 'function');
|
||||
assert.equal(typeof composed.reportJellyfinRemoteStopped, 'function');
|
||||
assert.equal(typeof composed.handleJellyfinRemotePlay, 'function');
|
||||
assert.equal(typeof composed.handleJellyfinRemotePlaystate, 'function');
|
||||
assert.equal(typeof composed.handleJellyfinRemoteGeneralCommand, 'function');
|
||||
});
|
||||
124
src/main/runtime/composers/jellyfin-remote-composer.ts
Normal file
124
src/main/runtime/composers/jellyfin-remote-composer.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
createBuildHandleJellyfinRemoteGeneralCommandMainDepsHandler,
|
||||
createBuildHandleJellyfinRemotePlayMainDepsHandler,
|
||||
createBuildHandleJellyfinRemotePlaystateMainDepsHandler,
|
||||
createBuildReportJellyfinRemoteProgressMainDepsHandler,
|
||||
createBuildReportJellyfinRemoteStoppedMainDepsHandler,
|
||||
createHandleJellyfinRemoteGeneralCommand,
|
||||
createHandleJellyfinRemotePlay,
|
||||
createHandleJellyfinRemotePlaystate,
|
||||
createReportJellyfinRemoteProgressHandler,
|
||||
createReportJellyfinRemoteStoppedHandler,
|
||||
} from '../domains/jellyfin';
|
||||
|
||||
type RemotePlayPayload = Parameters<ReturnType<typeof createHandleJellyfinRemotePlay>>[0];
|
||||
type RemotePlaystatePayload = Parameters<ReturnType<typeof createHandleJellyfinRemotePlaystate>>[0];
|
||||
type RemoteGeneralPayload = Parameters<ReturnType<typeof createHandleJellyfinRemoteGeneralCommand>>[0];
|
||||
|
||||
export type JellyfinRemoteComposerOptions = {
|
||||
getConfiguredSession: Parameters<typeof createBuildHandleJellyfinRemotePlayMainDepsHandler>[0]['getConfiguredSession'];
|
||||
getClientInfo: Parameters<typeof createBuildHandleJellyfinRemotePlayMainDepsHandler>[0]['getClientInfo'];
|
||||
getJellyfinConfig: Parameters<typeof createBuildHandleJellyfinRemotePlayMainDepsHandler>[0]['getJellyfinConfig'];
|
||||
playJellyfinItem: Parameters<typeof createBuildHandleJellyfinRemotePlayMainDepsHandler>[0]['playJellyfinItem'];
|
||||
logWarn: Parameters<typeof createBuildHandleJellyfinRemotePlayMainDepsHandler>[0]['logWarn'];
|
||||
getMpvClient: Parameters<typeof createBuildReportJellyfinRemoteProgressMainDepsHandler>[0]['getMpvClient'];
|
||||
sendMpvCommand: Parameters<typeof createBuildHandleJellyfinRemotePlaystateMainDepsHandler>[0]['sendMpvCommand'];
|
||||
jellyfinTicksToSeconds: Parameters<
|
||||
typeof createBuildHandleJellyfinRemotePlaystateMainDepsHandler
|
||||
>[0]['jellyfinTicksToSeconds'];
|
||||
getActivePlayback: Parameters<typeof createBuildHandleJellyfinRemoteGeneralCommandMainDepsHandler>[0]['getActivePlayback'];
|
||||
clearActivePlayback: Parameters<typeof createBuildReportJellyfinRemoteProgressMainDepsHandler>[0]['clearActivePlayback'];
|
||||
getSession: Parameters<typeof createBuildReportJellyfinRemoteProgressMainDepsHandler>[0]['getSession'];
|
||||
getNow: Parameters<typeof createBuildReportJellyfinRemoteProgressMainDepsHandler>[0]['getNow'];
|
||||
getLastProgressAtMs: Parameters<
|
||||
typeof createBuildReportJellyfinRemoteProgressMainDepsHandler
|
||||
>[0]['getLastProgressAtMs'];
|
||||
setLastProgressAtMs: Parameters<
|
||||
typeof createBuildReportJellyfinRemoteProgressMainDepsHandler
|
||||
>[0]['setLastProgressAtMs'];
|
||||
progressIntervalMs: number;
|
||||
ticksPerSecond: number;
|
||||
logDebug: Parameters<typeof createBuildReportJellyfinRemoteProgressMainDepsHandler>[0]['logDebug'];
|
||||
};
|
||||
|
||||
export type JellyfinRemoteComposerResult = {
|
||||
reportJellyfinRemoteProgress: ReturnType<typeof createReportJellyfinRemoteProgressHandler>;
|
||||
reportJellyfinRemoteStopped: ReturnType<typeof createReportJellyfinRemoteStoppedHandler>;
|
||||
handleJellyfinRemotePlay: (payload: RemotePlayPayload) => Promise<void>;
|
||||
handleJellyfinRemotePlaystate: (payload: RemotePlaystatePayload) => Promise<void>;
|
||||
handleJellyfinRemoteGeneralCommand: (payload: RemoteGeneralPayload) => Promise<void>;
|
||||
};
|
||||
|
||||
export function composeJellyfinRemoteHandlers(
|
||||
options: JellyfinRemoteComposerOptions,
|
||||
): JellyfinRemoteComposerResult {
|
||||
const buildReportJellyfinRemoteProgressMainDepsHandler =
|
||||
createBuildReportJellyfinRemoteProgressMainDepsHandler({
|
||||
getActivePlayback: options.getActivePlayback,
|
||||
clearActivePlayback: options.clearActivePlayback,
|
||||
getSession: options.getSession,
|
||||
getMpvClient: options.getMpvClient,
|
||||
getNow: options.getNow,
|
||||
getLastProgressAtMs: options.getLastProgressAtMs,
|
||||
setLastProgressAtMs: options.setLastProgressAtMs,
|
||||
progressIntervalMs: options.progressIntervalMs,
|
||||
ticksPerSecond: options.ticksPerSecond,
|
||||
logDebug: options.logDebug,
|
||||
});
|
||||
const buildReportJellyfinRemoteStoppedMainDepsHandler =
|
||||
createBuildReportJellyfinRemoteStoppedMainDepsHandler({
|
||||
getActivePlayback: options.getActivePlayback,
|
||||
clearActivePlayback: options.clearActivePlayback,
|
||||
getSession: options.getSession,
|
||||
logDebug: options.logDebug,
|
||||
});
|
||||
const reportJellyfinRemoteProgress = createReportJellyfinRemoteProgressHandler(
|
||||
buildReportJellyfinRemoteProgressMainDepsHandler(),
|
||||
);
|
||||
const reportJellyfinRemoteStopped = createReportJellyfinRemoteStoppedHandler(
|
||||
buildReportJellyfinRemoteStoppedMainDepsHandler(),
|
||||
);
|
||||
|
||||
const buildHandleJellyfinRemotePlayMainDepsHandler =
|
||||
createBuildHandleJellyfinRemotePlayMainDepsHandler({
|
||||
getConfiguredSession: options.getConfiguredSession,
|
||||
getClientInfo: options.getClientInfo,
|
||||
getJellyfinConfig: options.getJellyfinConfig,
|
||||
playJellyfinItem: options.playJellyfinItem,
|
||||
logWarn: options.logWarn,
|
||||
});
|
||||
const buildHandleJellyfinRemotePlaystateMainDepsHandler =
|
||||
createBuildHandleJellyfinRemotePlaystateMainDepsHandler({
|
||||
getMpvClient: options.getMpvClient as Parameters<
|
||||
typeof createBuildHandleJellyfinRemotePlaystateMainDepsHandler
|
||||
>[0]['getMpvClient'],
|
||||
sendMpvCommand: options.sendMpvCommand,
|
||||
reportJellyfinRemoteProgress: (force) => reportJellyfinRemoteProgress(force),
|
||||
reportJellyfinRemoteStopped: () => reportJellyfinRemoteStopped(),
|
||||
jellyfinTicksToSeconds: options.jellyfinTicksToSeconds,
|
||||
});
|
||||
const buildHandleJellyfinRemoteGeneralCommandMainDepsHandler =
|
||||
createBuildHandleJellyfinRemoteGeneralCommandMainDepsHandler({
|
||||
getMpvClient: options.getMpvClient as Parameters<
|
||||
typeof createBuildHandleJellyfinRemoteGeneralCommandMainDepsHandler
|
||||
>[0]['getMpvClient'],
|
||||
sendMpvCommand: options.sendMpvCommand,
|
||||
getActivePlayback: options.getActivePlayback,
|
||||
reportJellyfinRemoteProgress: (force) => reportJellyfinRemoteProgress(force),
|
||||
logDebug: (message) => options.logDebug(message, undefined),
|
||||
});
|
||||
|
||||
return {
|
||||
reportJellyfinRemoteProgress,
|
||||
reportJellyfinRemoteStopped,
|
||||
handleJellyfinRemotePlay: createHandleJellyfinRemotePlay(
|
||||
buildHandleJellyfinRemotePlayMainDepsHandler(),
|
||||
),
|
||||
handleJellyfinRemotePlaystate: createHandleJellyfinRemotePlaystate(
|
||||
buildHandleJellyfinRemotePlaystateMainDepsHandler(),
|
||||
),
|
||||
handleJellyfinRemoteGeneralCommand: createHandleJellyfinRemoteGeneralCommand(
|
||||
buildHandleJellyfinRemoteGeneralCommandMainDepsHandler(),
|
||||
),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user