Last active
August 28, 2024 19:52
-
-
Save bigmistqke/fa473dad0c879bf277b486ce15cceec1 to your computer and use it in GitHub Desktop.
format logs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { type JSX } from "solid-js"; | |
const LOG_SYMBOL = Symbol("log"); | |
type Log = [source: string, ...styles: string[]] & { | |
[LOG_SYMBOL]: true; | |
}; | |
type ValidValue = [string, JSX.CSSProperties?] | Log; | |
function fragment(array: Log[]): Log { | |
const source = array.map(([source]) => source).join(""); | |
const styles = array.flatMap(([_, ...rest]) => rest); | |
return mark([source, ...styles]); | |
} | |
function mark(array: [source: string, ...styles: string[]]): Log { | |
const marked = array as Log; | |
marked[LOG_SYMBOL] = true; | |
return marked; | |
} | |
function format(template: TemplateStringsArray, ...values: ValidValue[]): Log { | |
let source = template.reduce((aggregator, current, index) => { | |
if (index > values.length - 1) { | |
return `${aggregator}${current}`; | |
} | |
return `${aggregator}%c${current}%c${values[index][0]}`; | |
}, ""); | |
const styles = values.flatMap((value) => { | |
if (LOG_SYMBOL in value) { | |
const [_, ...rest] = value; | |
return ["", "", ...rest]; | |
} | |
const [_, css] = value; | |
return ["", css ? stringifyCssProperties(css) : ""]; | |
}); | |
return mark([source, ...styles]); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { type JSX } from "solid-js"; | |
import { fragment, format, type ValidValue } from "./format.ts" | |
type YamlOptions = { | |
indentation?: number; | |
keyStyle?: JSX.CSSProperties; | |
valueStyle?: JSX.CSSProperties; | |
offset?: number; | |
}; | |
function yaml( | |
value: Record<string, any> | any[], | |
options: YamlOptions = {}, | |
layer = 0, | |
): Log { | |
const { | |
indentation = 2, | |
offset = 0, | |
keyStyle = { color: "darkgrey" }, | |
valueStyle = {}, | |
} = options; | |
const space: ValidValue = [ | |
whitespace(layer, indentation) + whitespace(offset, 1), | |
]; | |
if (Array.isArray(value)) { | |
return fragment( | |
value.map((value) => { | |
if (Array.isArray(value)) { | |
const result = yaml(value, options, layer + 1); | |
if (indentation < 2) { | |
return format`${space}-\n${result}`; | |
} | |
result[0] = `${whitespace(1, indentation - 2)}${trim(result[0])}`; | |
return format`${space}- ${result}`; | |
} | |
if (typeof value === "object") { | |
const result = yaml(value, options, layer + 1); | |
result[0] = trim(result[0]); | |
return format`${space}- ${result}`; | |
} | |
value = typeof value == "string" ? `"${value}"` : value; | |
return format`${space}- ${[value, valueStyle]}\n`; | |
}), | |
); | |
} | |
return fragment( | |
Object.entries(value).map(([key, value]) => { | |
if (typeof value === "object") { | |
return format`${space}${[key, keyStyle]}:\n${yaml(value, options, layer + 1)}`; | |
} | |
value = typeof value == "string" ? `"${value}"` : value; | |
return format`${space}${[key, keyStyle]}: ${[value, valueStyle]}\n`; | |
}), | |
); | |
} | |
function whitespace(amount: number, indentation: number) { | |
if (amount * indentation < 0) { | |
return ""; | |
} | |
return " ".repeat(amount * indentation); | |
} | |
function trim(input: string) { | |
// Use a regular expression to match the first sequence of %c placeholders followed by whitespace | |
const regex = /((%c)\s*)+/; | |
// Find the match and then remove all whitespace from that match | |
const result = input.replace(regex, (match) => { | |
return match.replace(/\s+/g, ""); // Remove all whitespace in the matched sequence | |
}); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment