Newer
Older
TelosDB / src / frontend / js / shared.js
/**
 * フロントエンド共通: API・設定読み書き・ユーティリティ
 */

const DEFAULT_EXTENSIONS = ['txt', 'md', 'json', 'html', 'css', 'js', 'mjs', 'ts', 'rs'];

export const SETTINGS_KEY = 'telosdb_settings';

export const DEFAULTS = {
  min_score: 0.3,
  limit: 5,
  run_on_login: false,
  standard_folders_enabled: false,
  monitor_paths: [],
  watch_extensions: DEFAULT_EXTENSIONS,
};

export function getApiBase() {
  return (typeof window !== 'undefined' && window.API_BASE) ? window.API_BASE : 'http://127.0.0.1:3001';
}

export function escapeHtml(s) {
  const div = document.createElement('div');
  div.textContent = s;
  return div.innerHTML;
}

export async function callMcp(method, params = {}) {
  const res = await fetch(`${getApiBase()}/messages`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method,
      params,
      id: Date.now(),
    }),
  });
  const data = await res.json();
  if (data.error) throw new Error(data.error.message || JSON.stringify(data.error));
  return data.result;
}

export function parseResultText(result) {
  const content = result?.content;
  if (!content || !Array.isArray(content) || content.length === 0) return null;
  if (content[0].type === 'text' && content[0].text) {
    try {
      return JSON.parse(content[0].text);
    } catch (_) {
      return content[0].text;
    }
  }
  return null;
}

export async function loadSettingsFromFile() {
  try {
    const { invoke } = await import('@tauri-apps/api/core');
    const fileSettings = await invoke('get_app_settings');
    if (fileSettings && typeof fileSettings === 'object') {
      return {
        min_score: fileSettings.min_score ?? DEFAULTS.min_score,
        limit: fileSettings.limit ?? DEFAULTS.limit,
        run_on_login: Boolean(fileSettings.run_on_login),
        standard_folders_enabled: Boolean(fileSettings.standard_folders_enabled),
        monitor_paths: Array.isArray(fileSettings.monitor_paths) ? fileSettings.monitor_paths : DEFAULTS.monitor_paths,
        watch_extensions: Array.isArray(fileSettings.watch_extensions) ? fileSettings.watch_extensions : DEFAULTS.watch_extensions,
      };
    }
  } catch (_) {
    try {
      const res = await fetch(`${getApiBase()}/settings`);
      if (!res.ok) return null;
      const fileSettings = await res.json();
      if (fileSettings && typeof fileSettings === 'object') {
        return {
          min_score: fileSettings.min_score ?? DEFAULTS.min_score,
          limit: fileSettings.limit ?? DEFAULTS.limit,
          run_on_login: Boolean(fileSettings.run_on_login),
          standard_folders_enabled: Boolean(fileSettings.standard_folders_enabled),
          monitor_paths: Array.isArray(fileSettings.monitor_paths) ? fileSettings.monitor_paths : DEFAULTS.monitor_paths,
          watch_extensions: Array.isArray(fileSettings.watch_extensions) ? fileSettings.watch_extensions : DEFAULTS.watch_extensions,
        };
      }
    } catch (_) {}
  }
  return null;
}

export async function saveSettingsToFile(payload) {
  const toPersist = {
    min_score: payload.min_score,
    limit: payload.limit,
    run_on_login: payload.run_on_login,
    standard_folders_enabled: payload.standard_folders_enabled,
    monitor_paths: payload.monitor_paths,
    watch_extensions: payload.watch_extensions,
  };
  const hasRemovals = Array.isArray(payload.remove_from_index_paths) && payload.remove_from_index_paths.length > 0;
  if (hasRemovals) {
    try {
      const res = await fetch(`${getApiBase()}/settings`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...toPersist, remove_from_index_paths: payload.remove_from_index_paths }),
      });
      return res.ok;
    } catch (_) {
      return false;
    }
  }
  try {
    const { invoke } = await import('@tauri-apps/api/core');
    await invoke('set_app_settings', { settings: toPersist });
    return true;
  } catch (_) {
    try {
      const res = await fetch(`${getApiBase()}/settings`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(toPersist),
      });
      return res.ok;
    } catch (_) {
      return false;
    }
  }
}