Join Server

Release: `svelte-standard` 0.0.21 - Svelte sidebar apps refinement (final?)

Greets @Developer. This update provides what should be the final refinement for FVTTSidebarControl. Given some initial feedback a few more features have been added. Usually there isn't this much incremental additions so quickly w/ svelte-standard, but this update really should finalize FVTTSidebarControl.

The add, remove, replace methods now take an optional condition field that can be a boolean or function that returns a truthy value to conditionally run the sidebar action. This allows you to add condition: () => game.user.isGM for instance to only add / replace, etc. the sidebar for GM users.

Another useful new field particularly for replacing core Foundry sidebars is mergeAppImpl. This allows you to provide the control / model code that implements whatever API the core sidebar app may provide directly in the add / replace data. Instead of augmenting the globalThis.ui.<SIDEBAR ID> field via FVTTSidebarControl.wait().then() you can directly include a custom implementation to merge directly in add / replace.

Other small changes include:
- remove / replace methods data fields removeId / replaceId is now just id. This makes for a little nicer data defined API.

- Enhanced error handling where an error in loading one sidebar will not affect other sidebar actions.

This should provide a final API that meets the needs currently known for Svelte sidebar addition / replacement.
A more complete example for replacing the combat tracker is the following:

import { FVTTSidebarControl }  from '@typhonjs-fvtt/svelte-standard/application';

import { CombatControl }       from './CombatControl.js'
import CombatTab               from './CombatTab.svelte';

Hooks.once('setup', () =>
   const combatControl = new CombatControl();

   // Replaces the core combat sidebar w/ new Svelte implementation.
      id: 'combat',                // Replaces core combat sidebar app.
      icon: 'fas fa-swords',       // FontAwesome icon.
      mergeAppImpl: combatControl, // Loads into `ui.combat`
      title: 'COMBAT.SidebarTitle',// Title of popout sidebar app; can be language string.
      tooltip: 'DOCUMENT.Combats', // Tooltip for sidebar tab.
      svelte: {            // Svelte configuration object...
         class: CombatTab  // A Svelte component.
         context: {
            combatControl  // Pass `combatControl` to component.

Implement API from the core CombatTracker sidebar app as necessary. Also provide Svelte stores that are updated with combat related data for the Svelte sidebar component. All your control / model code for combats goes here.

export class CombatControl
   constructor() { ... }

   * Return an array of Combat encounters which occur within the current Scene.
   * @type {Combat[]}
   get combats() {
      return game.combats.combats;

   initialize({combat=null, render=true}={}) { ... }
   // All other relevant methods in `CombatTracker` core app, etc.