Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
TidaLuna
https://luna-wiki.jxnxsdev.de/
Admin
TidaLuna enhances the TIDAL desktop app with plugin support and extended functionality.
Tokens:
11,738
Snippets:
163
Trust Score:
2.1
Update:
6 months ago
Context
Chat
Benchmark
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Run Installer in CLI Mode Source: https://luna-wiki.jxnxsdev.de/install/mac.html Execute the installer in headless mode to list versions, install, or uninstall the application. ```bash ./installer-macOS-x86_64-vX.X.X --headless --list-versions ./installer-macOS-x86_64-vX.X.X --headless --install ./installer-macOS-x86_64-vX.X.X --headless --uninstall ``` -------------------------------- ### Practical Settings Pattern Example Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html Example demonstrating a common pattern for settings pages using @luna/ui components and @luna/core's ReactiveStore. ```APIDOC ## Practical Settings Pattern ### Description This example demonstrates a common pattern for settings pages, integrating UI components with persistent storage. ### Code Example (tsx) ```tsx import React from "react"; import { ReactiveStore } from "@luna/core"; import { LunaSettings, LunaSwitchSetting, LunaNumberSetting, LunaButtonSetting } from "@luna/ui"; export const settings = await ReactiveStore.getPluginStorage("MyPlugin", { enabled: true, speed: 25, }); export const Settings = () => { const [enabled, setEnabled] = React.useState(settings.enabled); const [speed, setSpeed] = React.useState(settings.speed); return ( <LunaSettings> <LunaSwitchSetting title="Enabled" checked={enabled} onChange={(_, checked) => setEnabled((settings.enabled = checked))} /> <LunaNumberSetting title="Speed" value={speed} min={1} max={100} onNumber={(value) => setSpeed((settings.speed = value))} /> <LunaButtonSetting title="Reset" onClick={() => setSpeed((settings.speed = 25))} /> </LunaSettings> ); }; ``` ### Notes - Prefer `Luna*Setting` components for a consistent Luna look and feel. - Ensure both local React state and persistent plugin storage are updated simultaneously. - Encapsulate complex asynchronous actions within `LunaButtonSetting` for explicit user triggers. - Utilize the `confirm(...)` helper for advanced user experience flows. ``` -------------------------------- ### Run Installer with Elevated Privileges Source: https://luna-wiki.jxnxsdev.de/install/mac.html Use sudo to execute the installer if standard permission settings fail. ```bash sudo ./installer-macOS-x86_64-vX.X.X ``` -------------------------------- ### Check Node.js Installation Source: https://luna-wiki.jxnxsdev.de/development/getting-started.html Verify that Node.js is installed and accessible in your system's PATH. ```bash node -v ``` -------------------------------- ### Run AppImage Installer Source: https://luna-wiki.jxnxsdev.de/install/linux.html Execute the TidaLuna installer using the AppImage format after making it executable. ```bash ./installer-linux-x86_64-vX.X.X.AppImage ``` -------------------------------- ### Run Portable Binary Installer Source: https://luna-wiki.jxnxsdev.de/install/linux.html Execute the TidaLuna installer using the portable binary format after making it executable. ```bash ./installer-linux-x86_64-vX.X.X ``` -------------------------------- ### Run TidaLuna Installer in CLI Mode (PowerShell) Source: https://luna-wiki.jxnxsdev.de/install/windows.html Use these commands to interact with the TidaLuna installer via PowerShell for advanced operations like listing versions, installing, or uninstalling. Specify a custom installation path using the --path argument. ```powershell ./installer-windows-x86_64-vX.X.X.exe --headless --list-versions ``` ```powershell ./installer-windows-x86_64-vX.X.X.exe --headless --install ``` ```powershell ./installer-windows-x86_64-vX.X.X.exe --headless --uninstall ``` -------------------------------- ### Practical Example: Context Menu + Media Item Interaction Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Demonstrates a common plugin pattern for adding a context menu button that interacts with a selected media item. ```APIDOC ## Practical example (context menu + media) Pattern used by plugins like QR/share tools and exporters: ```ts import type { LunaUnload } from "@luna/core"; import { ContextMenu, MediaItem } from "@luna/lib"; export const unloads = new Set<LunaUnload>(); const button = ContextMenu.addButton(unloads); button.text = "Run Action"; ContextMenu.onMediaItem(unloads, async ({ mediaCollection, contextMenu }) => { const first = (await mediaCollection.mediaItems().next()).value as MediaItem | undefined; if (!first) return; await button.show(contextMenu); button.onClick(async () => { const title = await first.title(); console.log("Selected:", title); }); }); ``` ``` -------------------------------- ### Run TidaLuna Installer in CLI Mode Source: https://luna-wiki.jxnxsdev.de/install/linux.html Commands for running the TidaLuna installer in headless (CLI) mode for listing versions, installing, or uninstalling. ```bash ./installer-linux-x86_64-vX.X.X --headless --list-versions ``` ```bash ./installer-linux-x86_64-vX.X.X --headless --install ``` ```bash ./installer-linux-x86_64-vX.X.X --headless --uninstall ``` -------------------------------- ### Example Usage of @luna/lib.native Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib-native.html Demonstrates how to use functions from the @luna/lib.native module for opening files and displaying messages. ```APIDOC ## Example Usage of @luna/lib.native ### Description This example shows how to use `showOpenDialog`, `openExternal`, and `showMessageBox` from the `@luna/lib.native` module. ### Code Example ```typescript import { showOpenDialog, openExternal, showMessageBox } from "@luna/lib.native"; const result = await showOpenDialog({ properties: ["openFile", "openDirectory"], }); if (!result.canceled && result.filePaths[0]) { await openExternal(`file://${result.filePaths[0]}`); } else { await showMessageBox({ type: "info", message: "No file selected", }); } ``` ``` -------------------------------- ### Prepare and Run Raw Binary on macOS Source: https://luna-wiki.jxnxsdev.de/install/mac.html Commands to remove quarantine attributes, sign the binary, and set executable permissions before running the installer. ```bash xattr -d com.apple.quarantine installer-macOS-x86_64-vX.X.X ``` ```bash codesign -s - -f --deep installer-macOS-x86_64-vX.X.X ``` ```bash chmod +x installer-macOS-x86_64-vX.X.X ``` ```bash ./installer-macOS-x86_64-vX.X.X ``` -------------------------------- ### Install Project Dependencies Source: https://luna-wiki.jxnxsdev.de/development/getting-started.html Install all necessary dependencies for your TidaLuna plugin project. Ensure this command is run in the root directory of your cloned repository. ```bash pnpm install ``` -------------------------------- ### Execute TidaLuna CLI commands Source: https://luna-wiki.jxnxsdev.de/install/installing.html Use these commands for headless installation, version listing, and uninstallation. Ensure --headless is the first argument. ```bash # List available channels/versions ./tidaluna-installer --headless --list-versions # Install latest stable ./tidaluna-installer --headless --install # Install specific version ./tidaluna-installer --headless --install --version 2.1.17 # Install to custom TIDAL resources path ./tidaluna-installer --headless --install --path "/path/to/tidal/resources" # Uninstall ./tidaluna-installer --headless --uninstall ``` -------------------------------- ### Check pnpm Installation Source: https://luna-wiki.jxnxsdev.de/development/getting-started.html Verify that pnpm is installed and accessible in your system's PATH. pnpm is recommended over npm for efficiency. ```bash pnpm -v ``` -------------------------------- ### Example Plugin package.json Configuration Source: https://luna-wiki.jxnxsdev.de/development/getting-started.html This JSON object shows the essential fields for a TidaLuna plugin's package.json file, including name, description, author details, main entry point, and module type. ```json "name": "My Awesome First Plugin", "description": "A plugin that does something awesome", "author": { "name": "coolUsername", "url": "https://github.com/coolUsername", "avatarUrl": "your avatar url" }, "main": "./src/index.ts", "type": "module" ``` -------------------------------- ### Build and Watch Plugin Changes Source: https://luna-wiki.jxnxsdev.de/development/getting-started.html Start the development server to automatically build your plugin and watch for file changes. This allows for live testing in the TIDAL desktop app. ```bash pnpm run watch ``` -------------------------------- ### Log Redux actions with @luna/dev Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-dev.html Demonstrates how to start and stop Redux action logging using a regex filter and a custom handler for trace logging. ```typescript import { startReduxLog, stopReduxLog, trace } from "@luna/dev"; await startReduxLog(/router\/.*/, (payload, type) => { trace.log("Redux", type, payload); }); // later await stopReduxLog(); ``` -------------------------------- ### Log Redux actions Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/logging.html Starts and stops logging for specific Redux actions using a regex filter. ```ts import { startReduxLog, stopReduxLog } from "@luna/dev"; await startReduxLog(/router\/.*/, (payload, type) => { trace.log("Redux", type, payload); }); // later await stopReduxLog(); ``` -------------------------------- ### showSettings() Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-linux.html Opens the tidal-hifi settings window on Linux platforms. ```APIDOC ## showSettings() ### Description Opens the tidal-hifi settings window. ### Request Example ```typescript import { showSettings } from "@luna/linux"; showSettings(); ``` ``` -------------------------------- ### Implement a minimal context menu action Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/context-menu.html Use ContextMenu.addButton to create a button and ContextMenu.onMediaItem to display it within media item menus. Ensure all resources are tracked via the unloads set for proper cleanup. ```ts import type { LunaUnload } from "@luna/core"; import { ContextMenu } from "@luna/lib"; export const unloads = new Set<LunaUnload>(); const actionButton = ContextMenu.addButton(unloads); actionButton.text = "My Action"; ContextMenu.onMediaItem(unloads, async ({ mediaCollection, contextMenu }) => { await actionButton.show(contextMenu); actionButton.onClick(async () => { const first = await mediaCollection.mediaItems().next(); if (first.value) { console.log("Selected media item", first.value.id); } }); }); ``` -------------------------------- ### Make Portable Binary Executable Source: https://luna-wiki.jxnxsdev.de/install/linux.html Grant execute permissions to the portable binary file before running it. ```bash chmod +x installer-linux-x86_64-vX.X.X ``` -------------------------------- ### Implement Plugin Settings Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html Standard pattern for creating a settings page using ReactiveStore and Luna UI components. Ensure both local React state and persistent storage are updated within the change handlers. ```tsx import React from "react"; import { ReactiveStore } from "@luna/core"; import { LunaSettings, LunaSwitchSetting, LunaNumberSetting, LunaButtonSetting } from "@luna/ui"; export const settings = await ReactiveStore.getPluginStorage("MyPlugin", { enabled: true, speed: 25, }); export const Settings = () => { const [enabled, setEnabled] = React.useState(settings.enabled); const [speed, setSpeed] = React.useState(settings.speed); return ( <LunaSettings> <LunaSwitchSetting title="Enabled" checked={enabled} onChange={(_, checked) => setEnabled((settings.enabled = checked))} /> <LunaNumberSetting title="Speed" value={speed} min={1} max={100} onNumber={(value) => setSpeed((settings.speed = value))} /> <LunaButtonSetting title="Reset" onClick={() => setSpeed((settings.speed = 25))} /> </LunaSettings> ); }; ``` -------------------------------- ### Implement Context Menu Action Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Demonstrates how to add a custom button to the context menu and interact with selected media items using the @luna/lib API. ```typescript import type { LunaUnload } from "@luna/core"; import { ContextMenu, MediaItem } from "@luna/lib"; export const unloads = new Set<LunaUnload>(); const button = ContextMenu.addButton(unloads); button.text = "Run Action"; ContextMenu.onMediaItem(unloads, async ({ mediaCollection, contextMenu }) => { const first = (await mediaCollection.mediaItems().next()).value as MediaItem | undefined; if (!first) return; await button.show(contextMenu); button.onClick(async () => { const title = await first.title(); console.log("Selected:", title); }); }); ``` -------------------------------- ### Make AppImage Executable Source: https://luna-wiki.jxnxsdev.de/install/linux.html Use this command to grant execute permissions to the AppImage file before running it. ```bash chmod +x installer-linux-x86_64-vX.X.X.AppImage ``` -------------------------------- ### Show and Hide Settings Window Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-linux.html Use `showSettings` to open the tidal-hifi settings window and `hideSettings` to close it. Ensure this plugin is only used on Linux platforms. ```typescript import { showSettings, hideSettings } from "@luna/linux"; showSettings(); // ...later hideSettings(); ``` -------------------------------- ### Initialize Tracer for plugins Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/logging.html Sets up the Tracer instance with a plugin identifier and initializes the unload set. ```ts import { Tracer, type LunaUnload } from "@luna/core"; export const unloads = new Set<LunaUnload>(); export const { trace, errSignal } = Tracer("[MyPlugin]"); ``` -------------------------------- ### Open file dialog and external URL Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib-native.html Demonstrates using native dialogs to select a file and opening the resulting path in an external application. ```typescript import { showOpenDialog, openExternal, showMessageBox } from "@luna/lib.native"; const result = await showOpenDialog({ properties: ["openFile", "openDirectory"], }); if (!result.canceled && result.filePaths[0]) { await openExternal(`file://${result.filePaths[0]}`); } else { await showMessageBox({ type: "info", message: "No file selected", }); } ``` -------------------------------- ### Safety Notes for @luna/lib.native Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib-native.html Important considerations for using native functionalities securely. ```APIDOC ## Safety Notes for @luna/lib.native ### Description Guidelines to ensure secure and responsible usage of native Electron capabilities. ### Notes - Keep native actions user-driven and explicit. - Avoid exposing raw privileged functions to arbitrary plugin UI callbacks. - Validate paths/inputs before passing to native APIs. ``` -------------------------------- ### hideSettings() Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-linux.html Closes the tidal-hifi settings window on Linux platforms. ```APIDOC ## hideSettings() ### Description Closes the tidal-hifi settings window. ### Request Example ```typescript import { hideSettings } from "@luna/linux"; hideSettings(); ``` ``` -------------------------------- ### Settings Components Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html Wrapper components for creating settings interfaces in TidaLuna plugins. ```APIDOC ## Settings Components (`components/settings/*`) ### Description Wrapper components for creating settings interfaces in TidaLuna plugins. ### Components - **`LunaSettings(props)`**: The main container for settings. - **`LunaSwitchSetting(props)`**: A control for boolean settings. - **`LunaTextSetting(props)`**: A text input control for string settings. - **`LunaNumberSetting(props)`**: A numeric input control with min/max validation and an `onNumber` handler. - **`LunaSelectSetting<T>(props)` and `LunaSelectItem`**: Components for dropdown or multi-select settings. - **`LunaButtonSetting(props)`**: A component for action buttons within settings. ``` -------------------------------- ### @luna/lib.native API Reference Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib-native.html This section details the functions available within the @luna/lib.native module, categorized by their functionality. ```APIDOC ## @luna/lib.native API Reference ### Description Provides access to native Electron capabilities for privileged operations and stream/file work. ### App + Updater Functions - **pkg()** - Returns current app/package metadata. - **update(...)** - Triggers the update flow. - **relaunch()** - Restarts the client. - **needsElevation()** - Detects if an elevated install path is required. - **runElevatedInstall(...)** - Executes an elevated install operation. ### Native Messaging / Shell Functions - **sendToRender(channel, ...args)** - **openExternal(url)** - **clipboardWriteText(text)** ### Dialog Helper Functions - **showOpenDialog(options)** - Displays an open file/directory dialog. - **showSaveDialog(options)** - Displays a save file dialog. - **showMessageBox(options)** - Displays a message box. - **showErrorBox(title, content)** - Displays an error box. ### Streaming Helper Functions - **fetchMediaItemStream(playbackInfo, options?)** - Creates a Node `Readable` from TIDAL playback manifests. - Supports FLAC tagging via `options.tags` and init-only DASH reads via `initSegmentOnly`. - **fetchStream(urls, options?)** - Low-level async stream fetch generator used by `fetchMediaItemStream`. ``` -------------------------------- ### Create Persistent Settings Storage Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/plugin-settings.html Use ReactiveStore to create persistent storage for plugin settings. Define default values close to the settings definition. ```typescript import { ReactiveStore } from "@luna/core"; export const settings = await ReactiveStore.getPluginStorage("MyPlugin", { enabled: true, speed: 25, mode: "default", }); ``` -------------------------------- ### Common Controls Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html Reusable UI controls provided by the @luna/ui toolkit. ```APIDOC ## Common Controls ### Description Reusable UI controls provided by the @luna/ui toolkit. ### Components - `LunaButton(props)` - `LunaSwitch(props)` - `LunaNumber(props)` - `LunaStack(props)` - `LunaTitle(props)` - `LunaTrashButton(props)` - `SpinningButton(props)` ``` -------------------------------- ### PlayState Module Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Provides access to playback state and controls for managing audio playback, including play, pause, seek, and event listeners. ```APIDOC ## PlayState ### Read state: * `PlayState.state`, `desiredState`, `playing` * `PlayState.currentTime`, `playTime` * `PlayState.playQueue`, `shuffle`, `repeatMode` ### Control playback: * `PlayState.play(mediaItemId?)`, `pause()`, `next()`, `previous()` * `PlayState.moveTo(index)`, `playNext(mediaItemId | mediaItemIds)` * `PlayState.seek(seconds)` * `PlayState.setShuffle(enabled, shuffleItems?)` * `PlayState.setRepeatMode(mode)` ### Events: * `PlayState.onState(unloads, callback)` * `PlayState.onScrobble(unloads, callback)` ``` -------------------------------- ### Build Settings Component with Luna UI Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/plugin-settings.html Construct a settings UI using Luna's provided components like LunaSwitchSetting, LunaNumberSetting, LunaSelectSetting, and LunaButtonSetting. Ensure local React state is synchronized with the persistent settings. ```typescript import React from "react"; import { LunaSettings, LunaSwitchSetting, LunaNumberSetting, LunaSelectSetting, LunaSelectItem, LunaButtonSetting, } from "@luna/ui"; export const Settings = () => { const [enabled, setEnabled] = React.useState(settings.enabled); const [speed, setSpeed] = React.useState(settings.speed); const [mode, setMode] = React.useState(settings.mode); return ( <LunaSettings> <LunaSwitchSetting title="Enabled" desc="Enable or disable this feature." checked={enabled} onChange={(_, checked) => setEnabled((settings.enabled = checked))} /> <LunaNumberSetting title="Speed" desc="Controls update speed." min={1} max={100} value={speed} onNumber={(value) => setSpeed((settings.speed = value))} /> <LunaSelectSetting title="Mode" value={mode} onChange={(event: any) => setMode((settings.mode = event.target.value))} > <LunaSelectItem value="default">Default</LunaSelectItem> <LunaSelectItem value="advanced">Advanced</LunaSelectItem> </LunaSelectSetting> <LunaButtonSetting title="Reset" desc="Restore default values" onClick={() => { setEnabled((settings.enabled = true)); setSpeed((settings.speed = 25)); setMode((settings.mode = "default")); }} /> </LunaSettings> ); }; ``` -------------------------------- ### Helper Function Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html Global confirm helper for modal-like confirmation flows. ```APIDOC ## Helper Function ### Description Global confirm helper for modal-like confirmation flows. ### Function - **`confirm(options)`** from `@luna/ui/helpers/confirm`: Presents an asynchronous confirmation prompt to the user. ``` -------------------------------- ### StyleTag Module Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Allows for dynamic creation and management of CSS style tags within the application. ```APIDOC ## StyleTag ### `new StyleTag(id, unloads, css?)` ### `styleTag.css = "..." ### `styleTag.add()` / `styleTag.remove()` ``` -------------------------------- ### Luna Linux Bridge Settings API Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/function-reference.html APIs for managing the Linux bridge settings window within the `@luna/linux` package. ```APIDOC ## `@luna/linux` API ### Show Settings Window #### Description Opens the Linux bridge settings window. #### Method `showSettings()` ### Hide Settings Window #### Description Closes the Linux bridge settings window. #### Method `hideSettings()` ``` -------------------------------- ### Helper Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Utility functions for DOM observation, safe timeouts/intervals, and retrieving credentials. ```APIDOC ### Helpers * `observe(unloads, selector, callback)` * `observePromise(unloads, selector, timeoutMs?)` * `safeTimeout(unloads, callback, delay?)` * `safeInterval(unloads, callback, delay?)` * `getCredentials()` ``` -------------------------------- ### ContextMenu Module Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Functions for managing and interacting with the context menu, including adding buttons and responding to menu events. ```APIDOC ## ContextMenu ### `ContextMenu.addButton(unloads)` Creates a reusable context menu button controller. ### `ContextMenu.getCurrent()` Resolves the currently open menu element (or `null`). ### `ContextMenu.onOpen(unloads, ({ event, contextMenu }) => ...)` Runs whenever a context menu opens. ### `ContextMenu.onMediaItem(unloads, ({ mediaCollection, contextMenu }) => ...)` Runs for track/album/playlist style context menus. ``` -------------------------------- ### MediaItem Module Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Represents a media item (track, album, playlist) and provides methods for fetching information, controlling playback, and managing downloads. ```APIDOC ## MediaItem ### Static construction/listeners: * `MediaItem.fromId(id, contentType?)` * `MediaItem.fromPlaybackContext(ctx?)` * `MediaItem.fromIsrc(isrc)` * `MediaItem.fromIds(ids)` / `fromTMediaItems(items)` * `MediaItem.onMediaTransition(unloads, callback)` * `MediaItem.onPreload(unloads, callback)` ### Common instance methods: * `play()` * `title()`, `artists()`, `album()`, `coverUrl(opts?)`, `lyrics()` * `playbackInfo(audioQuality?)`, `fetchBestQuality()` * `download(path, audioQuality?)`, `downloadProgress()`, `fileExtension(audioQuality?)` * `withFormat(unloads, audioQuality, listener)`, `updateFormat(audioQuality?, force?)` ``` -------------------------------- ### Export Settings UI from Plugin Entry Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/plugin-settings.html Export the Settings component from your plugin's main entry file (e.g., src/index.ts) to make it visible in the Luna Settings interface. Failure to export will prevent the settings page from appearing. ```typescript export { Settings } from "./Settings"; ``` -------------------------------- ### Implement and consume native modules Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/native-modules.html Define native logic in a .native.ts file and import it into renderer code. Ensure all exported functions are asynchronous. ```typescript // src/feature.native.ts export async function readStuff() { // native context work return "ok"; } // src/index.ts import { readStuff } from "./feature.native"; const value = await readStuff(); ``` -------------------------------- ### Implement resource cleanup pattern Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/plugin-unloading.html Register cleanup logic within the unloads set to remove DOM elements, styles, and timers when the plugin is unloaded. ```typescript const style = document.createElement("style"); document.head.appendChild(style); const node = document.createElement("div"); node.id = "my-plugin-root"; document.body.appendChild(node); const timer = setInterval(() => { // work }, 1000); unloads.add(() => { clearInterval(timer); style.remove(); node.remove(); document.documentElement.style.removeProperty("--my-plugin-var"); }); ``` -------------------------------- ### Luna Dev Logging and Debugging APIs Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/function-reference.html APIs for controlling Redux logging, IPC logging, and native debugging within the `@luna/dev` package. ```APIDOC ## `@luna/dev` API ### Start Redux Logging #### Description Starts Redux action logging with a specified regex filter. #### Method `startReduxLog(regex, handler)` #### Parameters - **regex** (string) - Required - The regular expression to filter Redux actions. - **handler** (function) - Required - The function to handle logged actions. ### Stop Redux Logging #### Description Stops the current Redux logging session. #### Method `stopReduxLog()` ### Toggle Native IPC Logging #### Description Toggles the logging for Native to Render Inter-Process Communication (IPC) events. #### Method `startNativeIPCLog()` / `stopNativeIPCLog()` ### Toggle Render IPC Logging #### Description Toggles the logging for Render to Native Inter-Process Communication (IPC) events. #### Method `startRenderIpcLog()` / `stopRenderIpcLog()` ### Get IPC Event Maps #### Description Retrieves the event maps used by the IPC loggers for both Native and Render processes. #### Method `getNativeIPCEvents()` / `getRenderIPCEvents()` ### Enable Native Debugging #### Description Enables the native debug attach flow for debugging. #### Method `startNativeDebugging()` ``` -------------------------------- ### Native Debugger Helper Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-dev.html Helper function to trigger the native debug attach flow. ```APIDOC ## Native Debugger Helper ### Description Triggers the native debug attach flow, typically used by the built-in development settings page. ### Methods - `startNativeDebugging()`: Initiates the native debug attach flow. ``` -------------------------------- ### Define standard unload set Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/plugin-unloading.html Initialize a Set to track cleanup functions using the LunaUnload type. ```typescript import type { LunaUnload } from "@luna/core"; export const unloads = new Set<LunaUnload>(); ``` -------------------------------- ### Page API Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-ui.html API for registering and managing pages within TidaLuna plugins. ```APIDOC ## Page API (`classes/Page`) ### Description API for registering and managing pages within TidaLuna plugins. ### Methods - **`Page.register(name, unloads, component?)`** Registers or reuses a page by name and ties its lifecycle to the provided `unloads` array. - **`page.open()`** Navigates to and opens the specific page within the Luna flow. - **`page.render()`** Renders the page component if it has not been rendered yet. ``` -------------------------------- ### IPC Renderer Module Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Functions for interacting with the Electron IPC renderer process, including sending and receiving messages, and handling deep link events. ```APIDOC ## IPC Module (`ipcRenderer`) ### `ipcRenderer.invoke(channel, ...args)` ### `ipcRenderer.send(channel, ...args)` ### `ipcRenderer.on(unloads, channel, listener)` ### `ipcRenderer.once(unloads, channel, listener)` ### `ipcRenderer.onOpenUrl(unloads, listener)` Helper for `tidaluna:` deep link events. ``` -------------------------------- ### Logging Controls API Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-dev.html Functions to manage real-time logging for Redux actions and IPC communication channels. ```APIDOC ## Logging Controls ### Description Functions to start and stop logging for Redux actions and IPC traffic between Native and Render processes. ### Methods - `startReduxLog(regex, handler)`: Starts logging Redux actions matching the provided regex. - `stopReduxLog()`: Stops Redux action logging. - `startNativeIPCLog()`: Starts logging Native to Render IPC traffic. - `stopNativeIPCLog()`: Stops Native to Render IPC logging. - `startRenderIpcLog()`: Starts logging Render to Native IPC traffic. - `stopRenderIpcLog()`: Stops Render to Native IPC logging. ``` -------------------------------- ### Redux Module Functions Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-lib.html Functions for intercepting and dispatching Redux actions, accessing the store, and handling promise-based actions. ```APIDOC ## Redux Module (`redux`) ### `redux.intercept(actionType | actionType[], unloads, callback, once?)` Listen for one or many Redux action types. Return `true` from callback to cancel dispatch. ### `redux.interceptPromise(actionType, unloads, cancel?)` Wait for the next matching action as a promise. ### `redux.interceptActionResp(trigger, unloads, resolveTypes, rejectTypes?, options?)` Trigger an action and wait for success or fail response actions. ### `redux.actions[...]` Dispatch typed TIDAL/Luna actions (playback, router, queue, etc.). ### `redux.store` Typed Redux store access for reads. ``` -------------------------------- ### IPC Event Map Helpers Source: https://luna-wiki.jxnxsdev.de/development/documentation/plugins/luna-dev.html Functions to retrieve current IPC event mappings. ```APIDOC ## IPC Event Map Helpers ### Description Retrieve the current event maps for IPC communication. ### Methods - `getNativeIPCEvents()`: Returns the current Native IPC event map. - `getRenderIPCEvents()`: Returns the current Render IPC event map. ``` -------------------------------- ### Handle Request/Response Action Flow Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/redux-store.html Manages a request-response pattern for Redux actions, including success and failure states. Requires specifying success and failure action types. ```typescript const result = await redux.interceptActionResp( () => redux.actions["content/LOAD_SINGLE_MEDIA_ITEM"]({ id: 123, itemType: "track" }), unloads, ["content/LOAD_SINGLE_MEDIA_ITEM_SUCCESS"], ["content/LOAD_SINGLE_MEDIA_ITEM_FAIL"], ); ``` -------------------------------- ### Observe a Single Action as a Promise Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/redux-store.html Waits for a specific Redux action to be dispatched and returns its payload. The 'unloads' Set should be managed. ```typescript const payload = await redux.interceptPromise("contextMenu/OPEN", unloads); ``` -------------------------------- ### Observe Redux Actions Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/redux-store.html Intercepts and logs specific Redux actions. Ensure the 'unloads' Set is managed to prevent memory leaks. ```typescript import { redux } from "@luna/lib"; import type { LunaUnload } from "@luna/core"; const unloads = new Set<LunaUnload>(); redux.intercept("router/NAVIGATED", unloads, (payload) => { console.log("Route:", payload.pathname); }); ``` -------------------------------- ### Log IPC traffic Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/logging.html Enables and disables logging for native and render IPC traffic. ```ts import { startNativeIPCLog, stopNativeIPCLog, startRenderIpcLog, stopRenderIpcLog } from "@luna/dev"; await startNativeIPCLog(); await startRenderIpcLog(); // cleanup await stopNativeIPCLog(); await stopRenderIpcLog(); ``` -------------------------------- ### Dispatch Redux Actions Source: https://luna-wiki.jxnxsdev.de/development/documentation/guides/redux-store.html Directly dispatches Redux actions to modify the application state. Use sparingly for simple state changes. ```typescript redux.actions["playbackControls/PLAY"](); redux.actions["playQueue/MOVE_NEXT"](); ```