waddling-errors 0.7.3

Structured, secure-by-default diagnostic codes for distributed systems with no_std and role-based documentation
Documentation
/* ============================================
   STATE MANAGEMENT
   Global State, Constants, and DOM References
   ============================================ */

// === Application State ===
const AppState = {
    // Data
    errors: [],
    filteredErrors: [],
    hashLookup: {}, // Hash → Code reverse lookup map (e.g., "Q9MUf" → "E.DB.VALIDATION.003")
    components: {},
    primaries: {},
    sequences: {},
    severities: {},
    
    // Filters
    searchQuery: '',
    activeSeverities: new Set(['critical', 'error', 'warning', 'info', 'debug', 'trace']),
    activeCategory: null,
    activeCategoryType: null, // 'components', 'primaries', or 'sequences'
    activeTag: null,
    
    // Visibility
    documentRole: 'public', // Set by server: 'internal', 'developer', 'public'
    viewingAs: null, // null = native role, or 'developer'/'public' for restricted view
    
    // UI State
    selectedErrorCode: null,
    expandedCards: new Set(),
    openSections: new Map(), // Map of errorCode -> Set of open section IDs
    sequenceFormat: 'numeric', // 'numeric' (001) or 'named' (EXHAUSTED)
    
    // Sidebar
    activeSidebarTab: 'browse', // 'browse' or 'detail'
    expandedTreeNodes: new Set(),
};

// === Severity Order (WDP Part 10 - matches Rust Severity enum) ===
const SEVERITY_ORDER = ['error', 'blocked', 'critical', 'warning', 'help', 'success', 'completed', 'info', 'trace'];

// === Severity Icons (using HTML entities for encoding safety) ===
const SEVERITY_ICONS = {
    error: '\u274C',
    blocked: '\u26D4',
    critical: '\uD83D\uDD25',
    warning: '\u26A0\uFE0F',
    help: '\uD83D\uDCA1',
    success: '\u2705',
    completed: '\u2714\uFE0F',
    info: '\u2139\uFE0F',
    trace: '\uD83D\uDD0D'
};

// === Visibility Levels (higher = more restricted) ===
const VISIBILITY_LEVELS = {
    public: 0,     // Visible to everyone
    developer: 1,  // Visible to developer and above
    internal: 2    // Visible only to internal
};

// === DOM Element References ===
const DOM = {};

// Initialize DOM references after document load
function initDOMReferences() {
    // Search elements (matches template.rs IDs)
    DOM.searchInput = document.getElementById('searchInput');
    DOM.searchClear = document.getElementById('searchClear');
    DOM.activeFilters = document.getElementById('activeFilters');
    DOM.queryBuilderToggle = document.getElementById('queryBuilderToggle');
    DOM.queryBuilder = document.getElementById('queryBuilderDropdown');
    DOM.autocompleteDropdown = document.getElementById('autocompleteDropdown');
    
    // Filter bars
    DOM.severityBar = document.getElementById('severityFilterBar');
    DOM.visibilityRow = document.getElementById('visibilityRow');
    
    // Results
    DOM.resultsContainer = document.getElementById('results');
    DOM.resultsCount = document.getElementById('resultCount');
    
    // Sidebar
    DOM.statsRow = document.getElementById('statsRow');
    DOM.browseList = document.getElementById('browseList');
    DOM.browseTabs = document.getElementById('browseTabs');
    DOM.detailSection = document.getElementById('detailSection');
    DOM.detailPanel = document.getElementById('detailPanel');
    DOM.detailContent = document.getElementById('detailContent');
    
    // Theme
    DOM.themeToggle = document.getElementById('themeToggle');
    DOM.formatToggle = document.getElementById('formatToggle');
    
    // Mobile hamburger menu
    DOM.hamburgerBtn = document.getElementById('hamburgerBtn');
    DOM.sidebar = document.getElementById('sidebar');
    
    // Toast
    DOM.toastContainer = document.getElementById('toastContainer');
    
    // Query builder parts
    DOM.builderPreview = document.getElementById('builderPreview');
    DOM.builderCloseBtn = document.getElementById('builderCloseBtn');
    DOM.builderClearBtn = document.getElementById('builderClearBtn');
    DOM.builderSearchBtn = document.getElementById('builderSearchBtn');
}

// === Utility: Get current effective visibility ===
function getEffectiveVisibility() {
    return AppState.viewingAs || AppState.documentRole;
}

// === Utility: Check if error is visible at current viewing level ===
// An error is visible if its restriction level is <= the viewing level
// e.g., "public" errors (level 0) are visible to all
// "developer" errors (level 1) are visible to developer (1) and internal (2)
// "internal" errors (level 2) are only visible to internal (2)
function isErrorVisible(error) {
    const viewingLevel = VISIBILITY_LEVELS[getEffectiveVisibility()] || 0;
    // Use 'role' field from JSON, default to 'public' if not set
    const errorRole = (error.role || error.visibility || 'public').toLowerCase();
    const errorLevel = VISIBILITY_LEVELS[errorRole] || 0;
    
    // Error is visible if viewing level >= error's restriction level
    return viewingLevel >= errorLevel;
}