diff --git a/static/capabilities.js b/static/capabilities.js index 750fd27..bbe0d72 100644 --- a/static/capabilities.js +++ b/static/capabilities.js @@ -86,6 +86,7 @@ // operation is still completing through the provider. const COMMAND_TIMEOUTS_MS = { 'audio-mix': { 'get-fader-value': 2100, 'set-fader-value': 2100 }, + 'library': { 'refresh-providers': 15000, 'sync-song': 15000 }, 'midi-input': { 'discover': 15000, 'open-source': 15000 }, }; function _commandTimeoutFor(capability, commandName) { diff --git a/tests/js/capabilities_lifecycle.test.js b/tests/js/capabilities_lifecycle.test.js index 93485eb..0b49195 100644 --- a/tests/js/capabilities_lifecycle.test.js +++ b/tests/js/capabilities_lifecycle.test.js @@ -77,4 +77,34 @@ test('failed no-op registrations do not block reload and rehydrate replacement', assert.equal(participants.length, 1); assert.equal(result.status, 'applied'); assert.equal(result.payload.generation, 2); -}); \ No newline at end of file +}); + +test('library long-running commands override the default handler timeout', async () => { + const window = loadCapabilities(); + const api = window.feedBack.capabilities; + const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + + api.registerParticipant('stems', { + stems: { + roles: ['owner'], + commands: ['slow-probe'], + handlers: { 'slow-probe': async () => { await delay(300); return { outcome: 'handled' }; } }, + runtime: true, + }, + }); + const timedOut = await api.dispatch({ capability: 'stems', command: 'slow-probe', source: 'test' }); + assert.equal(timedOut.outcome, 'failed'); + assert.match(timedOut.reason, /timed out after 250 ms/); + + api.registerParticipant('core.library', { + library: { + roles: ['owner'], + commands: ['sync-song'], + handlers: { 'sync-song': async () => { await delay(300); return { outcome: 'handled', payload: { ok: true } }; } }, + runtime: true, + }, + }); + const synced = await api.dispatch({ capability: 'library', command: 'sync-song', source: 'test' }); + assert.equal(synced.status, 'applied'); + assert.equal(synced.payload.ok, true); +});