UNPKG

lacona-api

Version:

Cross-platform API for use with lacona commands

955 lines (799 loc) 27.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchMusic = exports.checkVolume = exports.checkDoNotDisturb = exports.setDoNotDisturb = exports.checkWifi = exports.setWifi = exports.checkDarkMode = exports.fetchBrowserTabs = exports.fetchOpenWindows = exports.fetchFiles = undefined; /* Files */ let fetchFiles = exports.fetchFiles = (() => { var ref = _asyncToGenerator(function* ({ query }) { if (isDemo()) { return Promise.resolve(demoData.spotlightFiles); } if (isOSX()) { const escapedQuery = _lodash2.default.chain(query.split('')).map(function (char) { return char.replace('*', '\\*').replace('\\', '\\\\').replace('"', '\\"'); // .replace("'", "\\'") }).join('*').value(); const data = yield fetchSpotlight({ query: `kMDItemFSName LIKE[cd] "*${ escapedQuery }*" AND ` + 'kMDItemSupportFileType != "MDSystemFile" AND ' + 'kMDItemContentTypeTree != "com.apple.application" AND ' + 'kMDItemContentTypeTree != "com.apple.application-bundle" AND ' + 'kMDItemContentTypeTree != "com.apple.safari.bookmark" AND ' + 'kMDItemContentTypeTree != "public.contact" AND ' + 'kMDItemContentTypeTree != "com.apple.addressbook.group" AND ' + 'kMDItemContentTypeTree != "com.apple.safari.history" AND ' + 'kMDItemContentTypeTree != "public.calendar-event" AND ' + 'kMDItemContentTypeTree != "com.apple.ichat.transcript"', attributes: ['kMDItemPath', 'kMDItemContentType'], limit: 10 }); return _lodash2.default.map(data, function ({ kMDItemPath, kMDItemContentType }) { return { path: kMDItemPath, contentType: kMDItemContentType }; }); } }); return function fetchFiles(_x) { return ref.apply(this, arguments); }; })(); let fetchOpenWindows = exports.fetchOpenWindows = (() => { var ref = _asyncToGenerator(function* () { if (isDemo()) { return []; } if (isOSX()) { const data = yield runApplescript({ script: openWindowFetchScript }); return _lodash2.default.map(data, _lodash2.default.partial(_lodash2.default.zipObject, ['id', 'name', 'closeable'], _lodash2.default)); } }); return function fetchOpenWindows() { return ref.apply(this, arguments); }; })(); let fetchBrowserTabs = exports.fetchBrowserTabs = (() => { var ref = _asyncToGenerator(function* () { if (isDemo()) { return []; } if (isOSX()) { const data = yield runApplescript({ script: browserFetchScript }); return _lodash2.default.map(data, _lodash2.default.partial(_lodash2.default.zipObject, ['appName', 'id', 'name'], _lodash2.default)); } }); return function fetchBrowserTabs() { return ref.apply(this, arguments); }; })(); let checkDarkMode = exports.checkDarkMode = (() => { var ref = _asyncToGenerator(function* () { if (isOSX()) { const enabled = yield runApplescript({ script: CHECK_DARK_MODE_SCRIPT }); return { enabled }; } }); return function checkDarkMode() { return ref.apply(this, arguments); }; })(); let setWifi = exports.setWifi = (() => { var ref = _asyncToGenerator(function* ({ enabled }) { if (isOSX()) { yield callSystem(`/usr/sbin/networksetup -setairportpower en0 ${ enabled ? 'on' : 'off' }`); return; } }); return function setWifi(_x2) { return ref.apply(this, arguments); }; })(); let checkWifi = exports.checkWifi = (() => { var ref = _asyncToGenerator(function* () { if (isOSX()) { const stdout = yield callSystem('/usr/sbin/networksetup -getairportpower en0'); return { enabled: _lodash2.default.includes(stdout, 'On') }; } }); return function checkWifi() { return ref.apply(this, arguments); }; })(); let setDoNotDisturb = exports.setDoNotDisturb = (() => { var ref = _asyncToGenerator(function* ({ enabled }) { if (isOSX()) { if (enabled) { yield callSystem('defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean true; defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturbDate -date "`date -u +\\"%Y-%m-%d %H:%M:%S +000\\"`"; killall NotificationCenter'); } else { yield callSystem('defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean false; killall NotificationCenter'); } return; } }); return function setDoNotDisturb(_x3) { return ref.apply(this, arguments); }; })(); let checkDoNotDisturb = exports.checkDoNotDisturb = (() => { var ref = _asyncToGenerator(function* () { if (isOSX()) { const stdout = yield callSystem(`/usr/bin/defaults -currentHost read ${ userHome() }/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb`); return { enabled: _lodash2.default.includes(stdout, '1') }; } }); return function checkDoNotDisturb() { return ref.apply(this, arguments); }; })(); let checkVolume = exports.checkVolume = (() => { var ref = _asyncToGenerator(function* () { if (isOSX()) { const script = `output muted of (get volume settings)`; const output = yield runApplescript({ script }); return { mute: output }; } }); return function checkVolume() { return ref.apply(this, arguments); }; })(); let fetchMusic = exports.fetchMusic = (() => { var ref = _asyncToGenerator(function* () { if (isDemo()) { return global.demoData.music; } if (isOSX()) { const script = 'tell application "iTunes" to get {name, album, artist, album artist, composer, genre, year, disc number, track number, database ID} of every track of first library playlist'; const arrays = yield runApplescript({ script }); return arrangeOSXMusic(arrays); } }); return function fetchMusic() { return ref.apply(this, arguments); }; })(); exports.__set_send = __set_send; exports.isOSX = isOSX; exports.isDemo = isDemo; exports.openURL = openURL; exports.openFile = openFile; exports.canAccessEvents = canAccessEvents; exports.canAccessReminders = canAccessReminders; exports.createEvent = createEvent; exports.createReminder = createReminder; exports.fetchReminderLists = fetchReminderLists; exports.fetchCalendars = fetchCalendars; exports.showNotification = showNotification; exports.fetchUserDefaults = fetchUserDefaults; exports.fetchClipboard = fetchClipboard; exports.setClipboard = setClipboard; exports.watchApplications = watchApplications; exports.openURLInApplication = openURLInApplication; exports.openFileInApplication = openFileInApplication; exports.fetchApplication = fetchApplication; exports.watchBookmarks = watchBookmarks; exports.canAccessContacts = canAccessContacts; exports.fetchUserContact = fetchUserContact; exports.fetchContacts = fetchContacts; exports.userHome = userHome; exports.fetchRunningApplications = fetchRunningApplications; exports.activateApplication = activateApplication; exports.hideApplication = hideApplication; exports.closeApplicationWindows = closeApplicationWindows; exports.quitApplication = quitApplication; exports.closeOpenWindow = closeOpenWindow; exports.activateOpenWindow = activateOpenWindow; exports.activateBrowserTab = activateBrowserTab; exports.closeBrowserTab = closeBrowserTab; exports.watchPreferencePanes = watchPreferencePanes; exports.fetchDictionaryDefinitions = fetchDictionaryDefinitions; exports.setBluetooth = setBluetooth; exports.checkBluetooth = checkBluetooth; exports.setDarkMode = setDarkMode; exports.setVolume = setVolume; exports.shutdown = shutdown; exports.restart = restart; exports.logOut = logOut; exports.sleep = sleep; exports.lock = lock; exports.hibernate = hibernate; exports.turnOffDisplay = turnOffDisplay; exports.turnOnScreensaver = turnOnScreensaver; exports.emptyTrash = emptyTrash; exports.fetchMountedVolumes = fetchMountedVolumes; exports.unmountVolume = unmountVolume; exports.unmountAllVolumes = unmountAllVolumes; exports.playSongIds = playSongIds; exports.musicPlay = musicPlay; exports.musicPause = musicPause; exports.musicNext = musicNext; exports.musicPrevious = musicPrevious; exports.musicStop = musicStop; exports.runApplescript = runApplescript; exports.fetchSpotlight = fetchSpotlight; exports.watchSpotlight = watchSpotlight; exports.reloadAddons = reloadAddons; exports.openLaconaPreferences = openLaconaPreferences; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _map = require('rxjs/operator/map'); var _Observable = require('rxjs/Observable'); var _nodeUuid = require('node-uuid'); var _child_process = require('child_process'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; } /** @jsx createElement */ const demoConfig = { webSearch: { searchEngines: [{ name: 'Google', url: 'https://www.google.com/search?q=${query}' }, { name: 'Google Images', url: 'https://www.google.com/search?q=${query}&tbm=isch' }, { name: 'Google Maps', url: 'https://www.google.com/maps?q=${query}' }, { name: 'Gmail', url: 'https://www.google.com/search?q=${query}' }, { name: 'Google Mail', url: 'http://mail.google.com/mail/u/0/#search/${query}' }, { name: 'Google Inbox', url: 'https://inbox.google.com/search/${query}' }, { name: 'Google Drive', url: 'https://drive.google.com/drive/u/0/#search?q=${query}' }, { name: 'Maps', url: 'http://maps.apple.com/?q=${query}' }, { name: 'Twitter', url: 'https://twitter.com/search?q=${query}' }, { name: 'Facebook', url: 'https://www.facebook.com/search/results.php?q=${query}' }, { name: 'LinkedIn', url: 'https://www.linkedin.com/vsearch/p?keywords=${query}' }, { name: 'Youtube', url: 'https://www.youtube.com/results?search_query=${query}' }, { name: 'Wikipedia', url: 'https://wikipedia.org/wiki/Special:Search/${query}' }, { name: 'Amazon', url: 'http://www.amazon.com/s?url=search-alias=aps&field-keywords=${query}&tag=lacona-20' }, { name: 'eBay', url: 'http://shop.ebay.com/?_nkw=${query}' }, { name: 'IMDb', url: 'http://www.imdb.com/find?s=all&q=${query}' }, { name: 'Rotten Tomatoes', url: 'http://www.rottentomatoes.com/search/?search=${query}' }, { name: 'Bing', url: 'http://www.bing.com/search?q=${query}' }, { name: 'Yahoo', url: 'https://search.yahoo.com/search?p=${query}' }, { name: 'Ask', url: 'http://www.ask.com/web?q=${query}' }, { name: 'Flickr', url: 'https://www.flickr.com/search/?q=${query}&w=all' }, { name: 'Wolfram|Alpha', url: 'http://www.wolframalpha.com/input/?i=${query}' }, { name: 'Yubnub', url: 'http://www.yubnub.org/parser/parse?command=${query}' }, { name: 'DuckDuckGo', url: 'https://duckduckgo.com/?q=${query}' }] }, applications: { searchDirectories: [], applications: [] } }; const SEND_KEY = Symbol.for("io.lacona.lacona.api.send"); function __set_send(send) { global[SEND_KEY] = send; } function send(type, data = {}) { return new Promise((resolve, reject) => { global[SEND_KEY](type, data, (err, res) => { if (err) { reject(err); } else { resolve(res); } }); }); } function isOSX() { return process.platform === 'darwin' || !isDemo(); } function isDemo() { return process.env.LACONA_ENV === 'demo'; } /* Open */ function open({ url, path, applicationPath }) { if (isOSX()) { return send('OPEN', { url, path, applicationPath }); } } function openURL({ url }) { return open({ url }); } function openFile({ path }) { return open({ path }); } /* Events */ function canAccessEvents() { if (isOSX()) { return send('CAN_ACCESS_EVENTS'); } } function canAccessReminders() { if (isOSX()) { return send('CAN_ACCESS_REMINDERS'); } } function createEvent({ title, start, end, allDay, calendar, location }) { if (isOSX()) { return send('CREATE_EVENT', { title, start, end, allDay, calendar, location }); } } function createReminder({ title, date, reminderList }) { if (isOSX()) { return send('CREATE_REMINDER', { title, date, reminderList }); } } function fetchReminderLists() { if (isOSX()) { return send('FETCH_REMINDER_LISTS'); } } function fetchCalendars() { if (isOSX()) { return send('FETCH_CALENDARS'); } } /* Notifications */ function showNotification({ title, subtitle, content }) { if (isOSX()) { return send('SHOW_NOTIFICATION', { title, subtitle, content }); } } /* User Defaults */ // FIRST AVAILABLE IN 1.0.3 function fetchUserDefaults({ domain, key }) { if (isOSX()) { return send('FETCH_USER_DEFAULTS', { domain, key }); } } /* Clipboard */ function fetchClipboard() { if (isOSX()) { return send('FETCH_CLIPBOARD'); } } function setClipboard({ text }) { if (isOSX()) { return send('SET_CLIPBOARD', { text }); } } /* Applications */ function watchApplications({ directories, appPaths }) { if (isDemo()) { return new _Observable.Observable(observer => { observer.next(demoData.applications); }); } if (isOSX()) { var _context; const tilde = userHome(); const trueDirectories = _lodash2.default.map(directories, dir => dir.replace(/^~/, tilde)); const truePaths = _lodash2.default.map(appPaths, path => path.replace(/^~/, tilde)); return (_context = watchSpotlight({ directories: trueDirectories, query: "kMDItemContentTypeTree == 'com.apple.application'", attributes: ['kMDItemDisplayName', 'kMDItemCFBundleIdentifier', 'kMDItemAlternateNames', 'kMDItemPath'] }), _map.map).call(_context, data => { return _lodash2.default.map(data, item => { let alternativeNames = item.kMDItemAlternateNames || []; if (item.kMDItemCFBundleIdentifier === 'com.google.Chrome') { alternativeNames = ['Chrome']; } if (item.kMDItemCFBundleIdentifier === 'com.apple.iChat') { alternativeNames = ['iMessage', 'iChat']; } return { name: item.kMDItemDisplayName, bundleId: item.kMDItemCFBundleIdentifier, path: item.kMDItemPath, alternativeNames }; }); }); } } function openURLInApplication({ url, applicationPath }) { return open({ url, applicationPath }); } function openFileInApplication({ path, applicationPath }) { return open({ path, applicationPath }); } function fetchApplication({ name }) { return send('FETCH_APPLICATION_INFO', { name }); } /* Bookmarks */ function watchBookmarks() { if (isDemo()) { return new _Observable.Observable(observer => { observer.next(demoData.bookmarks); }); } if (isOSX()) { var _context2; return (_context2 = watchSpotlight({ query: "kMDItemContentTypeTree = 'com.apple.safari.bookmark'", attributes: ['kMDItemDisplayName', 'kMDItemURL', 'kMDItemPath'] }), _map.map).call(_context2, data => { return _lodash2.default.map(data, ({ kMDItemDisplayName, kMDItemURL, kMDItemPath }) => ({ name: kMDItemDisplayName, url: kMDItemURL, path: kMDItemPath })); }); } } /* Contacts */ function canAccessContacts() { if (isOSX()) { return send('CAN_ACCESS_CONTACTS'); } } function fetchUserContact() { if (isDemo()) { return Promise.resolve(global.demoData.userContact); } if (isOSX()) { return send('FETCH_USER_CONTACT'); } } function fetchContacts() { if (isDemo()) { return Promise.resolve(global.demoData.contacts); } if (isOSX()) { return send('FETCH_ALL_CONTACTS'); } }function userHome() { if (isDemo()) { return '/Users/LaconaUser'; } return process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME']; } /* Running Apps */ function fetchRunningApplications() { if (isDemo()) { return Promise.resolve(global.demoData.applications); } if (isOSX()) { return send('FETCH_RUNNING_APPLICATIONS'); } } function activateApplication({ path }) { if (isOSX()) { return open({ path }); } } function hideApplication({ path }) { if (isOSX()) { return send('HIDE', { path }); } } function closeApplicationWindows({ bundleId }) { if (isOSX()) { const script = ` tell application "System Events" set proc to first process whose background only is false and bundle identifier is "${ bundleId }" repeat with win in proc's windows set butt to (win's first button whose subrole is "AXCloseButton") click butt end repeat end tell `; return runApplescript({ script }); } } function quitApplication({ path }) { if (isOSX()) { return send('QUIT', { path }); } } /* Open Windows */ const openWindowFetchScript = ` on run tell application "System Events" set allWindows to {} repeat with proc in (processes where background only is false) repeat with win in proc's windows if win's subrole is "AXStandardWindow" then set end of allWindows to {{proc's id, win's name}, win's title, my hasCloseButton(win)} end if end repeat end repeat end tell return allWindows end run on hasCloseButton(win) tell application "System Events" if win's subrole is "AXStandardWindow" then repeat with butt in win's buttons if butt's subrole is "AXCloseButton" then return true end if end repeat end if return false end tell end hasCloseButton `; function closeOpenWindow({ id }) { if (isOSX()) { //NOT IMPLEMENTED } } function activateOpenWindow({ id }) { if (isOSX()) { const [procId, name] = id; const script = ` tell application "System Events" set proc to first process whose background only is false and id is ${ procId } set win to proc's first window whose name is "${ name }" perform action "AXRaise" of win set proc's frontmost to true end tell `; return runApplescript({ script }); } } /* Browser Tabs */ const browserFetchScript = ` -- set chromeTabs to {} set safariTabs to {} -- if is_running("Google Chrome") then -- set chromeTabs to run script " -- set allTabs to {} -- tell application \\"Google Chrome\\" -- repeat with win in every window -- repeat with t in win's tabs -- set end of allTabs to {\\"Google Chrome\\", {\\"Google Chrome\\", t's id}, title of t} -- end repeat -- end repeat -- end tell -- return allTabs -- " -- end if if is_running("Safari") then set safariTabs to run script " set allTabs to {} tell application \\"Safari\\" repeat with win in (windows where visible is true) repeat with t in win's tabs set end of allTabs to {\\"Safari\\", {\\"Safari\\", {win's index, t's index}}, t's name} end repeat end repeat end tell return allTabs " end if on is_running(appName) tell application "System Events" to (name of processes) contains appName end is_running -- return chromeTabs & safariTabs return safariTabs `; function activateBrowserTab(id) { if (isOSX()) { const [appName, id] = id; if (appName === 'Google Chrome') { script = ` tell application "Google Chrome" repeat with wi from 1 to count windows repeat with ti from 1 to count (window wi's tabs) if id of window wi's tab ti is ${ id } then set theTab to ti set theWin to wi end if end repeat end repeat set window theWin's active tab index to theTab set window theWin's index to 1 activate end tell `; return runApplescript({ script }); } else if (appName === 'Safari') { // TODO THIS DOES NOT WORK const [winId, tabId] = id; script = ` tell application "Safari" activate set win to window ${ winId } set win's current tab to win's tab ${ tabId } set win's index to 1 end tell `; return runApplescript({ script }); } } } function closeBrowserTab({ id }) { if (isOSX()) { //not yet implemented } } /* Preference Panes */ function watchPreferencePanes() { if (isDemo()) { return new _Observable.Observable(observer => { observer.next(demoData.preferencePanes); }); } if (isOSX()) { var _context3; return (_context3 = watchSpotlight({ query: "kMDItemContentType == 'com.apple.systempreference.prefpane'", attributes: ['kMDItemDisplayName', 'kMDItemPath'] }), _map.map).call(_context3, data => { return _lodash2.default.map(data, ({ kMDItemDisplayName, kMDItemPath }) => ({ name: kMDItemDisplayName, path: kMDItemPath })); }); } } /* Dictionary */ function fetchDictionaryDefinitions({ word }) { if (isOSX()) { return send('FETCH_DICTIONARY_DEFINITIONS', { word }); } } /* Settings */ function setBluetooth({ enabled }) { if (isOSX()) { return send('SET_BLUETOOTH', { enabled }); } } function checkBluetooth() { if (isOSX()) { return send('CHECK_BLUETOOTH'); } } function setDarkMode({ enabled }) { if (isOSX()) { const script = ` tell application "System Events" tell appearance preferences set dark mode to ${ enabled ? 'true' : 'false' } end tell end tell `; return runApplescript({ script }); } } const CHECK_DARK_MODE_SCRIPT = ` tell application "System Events" tell appearance preferences return dark mode end tell end tell `; function callSystem(command) { return new Promise((resolve, reject) => { (0, _child_process.exec)(command, (err, stdout, stderr) => { if (err) { reject(err); } else { resolve(stdout); } }); }); } function setVolume({ mute }) { if (isOSX()) { const script = `set volume ${ mute ? 'with' : 'without' } output muted`; return runApplescript({ script }); } } function shutdown() { if (isOSX()) { return runApplescript({ script: 'tell application "System Events" to shut down' }); } } function restart() { if (isOSX()) { return runApplescript({ script: 'tell application "System Events" to restart' }); } } function logOut() { if (isOSX()) { return runApplescript({ script: 'tell application "System Events" to log out' }); } } function sleep() { if (isOSX()) { return runApplescript({ script: 'tell application "System Events" to sleep' }); } } function lock() { if (isOSX()) { return callSystem('/System/Library/CoreServices/Menu\\ Extras/User.menu/Contents/Resources/CGSession -suspend'); } } function hibernate() {} function turnOffDisplay() { if (isOSX()) { return callSystem('/usr/bin/pmset displaysleepnow'); } } function turnOnScreensaver() { if (isOSX()) { return runApplescript({ script: 'tell application "System Events" to start current screen saver' }); } } function emptyTrash() { if (isOSX()) { return runApplescript({ script: 'tell application "Finder" to empty the trash' }); } } /* Mounted Volumes */ function fetchMountedVolumes() { if (isDemo()) { return Promise.resolve(global.demoData.volumes); } if (isOSX()) { return send('FETCH_MOUNTED_VOLUMES'); } } function unmountVolume({ id }) { if (isOSX()) { const script = `tell application "Finder" to eject "${ id }"`; return runApplescript({ script }); } } function unmountAllVolumes() { if (isOSX()) { const script = 'tell application "Finder" to eject the disks'; return runApplescript({ script }); } } /* Music */ function simplifyArtist(item) { const { albumArtist, artist } = item; item.artist = albumArtist || artist; delete item.albumArtist; } function sortStringAsInteger(key) { return item => parseInt(item[key], 10); } function arrangeOSXMusic(arrays) { return _lodash2.default.chain(arrays).thru(_lodash2.default.spread(_lodash2.default.zip)).map(_lodash2.default.partial(_lodash2.default.zipObject, ['name', 'album', 'artist', 'albumArtist', 'composer', 'genre', 'year', 'discNumber', 'trackNumber', 'id'])).tap(items => _lodash2.default.forEach(items, simplifyArtist)).sortBy([simplifyArtist, sortStringAsInteger('year'), 'album', sortStringAsInteger('discNumber'), sortStringAsInteger('trackNumber'), sortStringAsInteger('id')]).value(); } function playSongIds({ ids }) { const script = ` tell application "iTunes" if user playlist "Lacona Playlist" exists then try delete user playlist "Lacona Playlist" end try end if make new user playlist with properties {name:"Lacona Playlist", shuffle: false} repeat with tid in {${ ids.join(',') }} set trk to (some track of first user playlist whose database ID is tid) duplicate trk to end of user playlist "Lacona Playlist" end repeat play user playlist "Lacona Playlist" end tell `; return runApplescript({ script }); } function musicPlay() { if (isOSX()) { return runApplescript({ script: 'tell application "iTunes" to play' }); } } function musicPause() { if (isOSX()) { return runApplescript({ script: 'tell application "iTunes" to pause' }); } } function musicNext() { if (isOSX()) { return runApplescript({ script: 'tell application "iTunes" to next track' }); } } function musicPrevious() { if (isOSX()) { return runApplescript({ script: 'tell application "iTunes" to previous track' }); } } function musicStop() { if (isOSX()) { return runApplescript({ script: 'tell application "iTunes" to stop' }); } } /* OSX specific */ function runApplescript({ script }) { if (isOSX()) { return send('RUN_APPLESCRIPT', { script }); } } function fetchSpotlight({ query = '', attributes = [], directories = [], limit = 0 }) { const queryId = (0, _nodeUuid.v4)(); return send('QUERY_SPOTLIGHT', { query, queryId, attributes, directories, limit, liveUpdate: false }); } function watchSpotlight({ query = '', attributes = [], directories = [], limit = 0 }) { return new _Observable.Observable(observer => { observer.next([]); const queryId = (0, _nodeUuid.v4)(); global[SEND_KEY]('QUERY_SPOTLIGHT', { query, queryId, attributes, directories, limit, liveUpdate: true }, (err, data) => { if (err) { console.error(err); } else { observer.next(data); } }); return () => global[SEND_KEY]('CANCEL_SPOTLIGHT_QUERY', { queryId }); }); } function reloadAddons() { return send('RELOAD_ADDONS'); } /* Config and Context */ function openLaconaPreferences() { return send('OPEN_LACONA_PREFERENCES'); }