All files utils.js

100% Statements 72/72
97.95% Branches 48/49
100% Functions 9/9
100% Lines 72/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 731x 2x 2x 2x 2x 2x 1x 1x 8x 8x 1x 1x 197x 197x 197x 197x 1x 1x 52x 52x 1x 1x 1x 1x 1x 1x 189x 189x 1x 1x 21x 21x 18x 18x 21x 12x 12x 21x 21x 21x 21x 21x 18x 21x 1x 1x 18x 18x 12x 12x 18x 18x 18x 18x 18x 18x 18x 1x 1x 8x 8x 7x 8x 4x 4x 8x 8x 8x 8x 8x 7x 8x  
export function formatTimestamp(timestamp) {
    return new Date(timestamp).toLocaleString(undefined, {
        year: 'numeric', month: 'short', day: 'numeric',
        hour: '2-digit', minute: '2-digit', second: '2-digit'
    });
}
 
export function isNonEmptyString(val) {
    return typeof val === 'string' && val.trim().length > 0;
}
 
export function deepClone(obj) {
    return typeof structuredClone === 'function'
        ? structuredClone(obj)
        : JSON.parse(JSON.stringify(obj));
}
 
export function createId() {
    return Date.now() + '-' + Math.random().toString(36).slice(2);
}
 
export function isNodeEnvironment() {
    return typeof window === 'undefined';
}
 
export function randomLetter() {
    return String.fromCharCode(65 + Math.floor(Math.random() * 26));
}
 
export function parseStateFromUrl(urlString) {
    const qIndex = urlString.indexOf('?');
    if (qIndex === -1) return {};
    const params = new URLSearchParams(urlString.slice(qIndex));
    const state = {};
    if (params.has('words')) {
        state.words = params.get('words').split(',');
    }
    if (params.has('width')) state.grid_width = Number(params.get('width'));
    if (params.has('height')) state.grid_height = Number(params.get('height'));
    if (params.has('all_cross')) state.all_cross = params.get('all_cross') === 'true';
    if (params.has('allow_diagonals')) state.allow_diagonals = params.get('allow_diagonals') === 'true';
    if (params.has('allow_reverse')) state.allow_reverse = params.get('allow_reverse') === 'true';
    return state;
}
 
export function serializeStateToUrl(state) {
    const params = new URLSearchParams();
    if (state.words && state.words.length > 0) {
        params.set('words', state.words.map(w => w.value).join(','));
    }
    if (state.grid_width !== undefined) params.set('width', String(state.grid_width));
    if (state.grid_height !== undefined) params.set('height', String(state.grid_height));
    if (state.all_cross !== undefined) params.set('all_cross', String(state.all_cross));
    if (state.allow_diagonals !== undefined) params.set('allow_diagonals', String(state.allow_diagonals));
    if (state.allow_reverse !== undefined) params.set('allow_reverse', String(state.allow_reverse));
    return params.toString();
}
 
export function buildInitialStateFromUrl(urlString) {
    const parsed = parseStateFromUrl(urlString);
    if (Object.keys(parsed).length === 0) return {};
    const state = {};
    if (parsed.words) {
        state.words = parsed.words.map(w => ({ id: createId(), value: w }));
    }
    if (parsed.grid_width !== undefined) state.grid_width = parsed.grid_width;
    if (parsed.grid_height !== undefined) state.grid_height = parsed.grid_height;
    if (parsed.all_cross !== undefined) state.all_cross = parsed.all_cross;
    if (parsed.allow_diagonals !== undefined) state.allow_diagonals = parsed.allow_diagonals;
    if (parsed.allow_reverse !== undefined) state.allow_reverse = parsed.allow_reverse;
    return state;
}