Skip to content

Commit

Permalink
✨ 🔀 new options.wrap property that's more powerful with auto, `si…
Browse files Browse the repository at this point in the history
…ngle-line`, `multi-line` or `number` for line breaking + old `options.lineLength` is now removed in favor of `options.wrap` + `consoleTable()` now shows as much of the object inline as it can + removed `consoleGroup()` usage when object is at root level
  • Loading branch information
astoilkov committed Feb 8, 2024
1 parent e115aa9 commit 4a964b2
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 93 deletions.
4 changes: 2 additions & 2 deletions src/extras/consoleTable.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ConsoleText } from "../core/consoleText";
import hasOnlyPrimitives from "../utils/hasOnlyPrimitives";
import consolePrint from "../core/consolePrint";
import defaultLineLength from "../utils/defaultLineLength";
import guessAvailableLength from "../utils/guessAvailableLength";
import arrayOfObjectsTable from "./consoleTable/arrayOfObjectsTable";
import flatObjectOrArrayTable from "./consoleTable/flatObjectOrArrayTable";

Expand All @@ -19,7 +19,7 @@ export default function consoleTable(
Array.isArray(object) && !hasOnlyPrimitives(object);
const optionsRequired = {
print: true,
lineLength: defaultLineLength(),
lineLength: guessAvailableLength(),
theme: matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light",
Expand Down
84 changes: 56 additions & 28 deletions src/extras/consoleTable/consoleTableCell.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,66 @@
import consoleInline from "../../utils/consoleInline";
import inspectInline from "../../inspect/inspectors/inspectInline";
import inspectAny from "../../inspect/inspectors/inspectAny";
import { ConsoleText, consoleText } from "../../core/consoleText";
import createTableCell, { ConsoleTableCell } from "./createTableCell";
import spansLength from "../../utils/spansLength";

export default function consoleTableCell(
value: unknown,
theme: "light" | "dark",
maxCellLength: number,
): ConsoleTableCell {
const spans = inspectAny(
value,
{
theme,
lineLength: maxCellLength,
print: false,
line: false,
indent: 0,
depth: 2,
},
{
depth: 1,
indent: 0,
},
).map((span) => {
return typeof span === "string"
? consoleText(span)
: span.type === "object"
? consoleInline(span, theme)
: span;
});
return spans.every(
(span): span is ConsoleText =>
span.type === "text" && !span.text.includes("\n"),
)
? createTableCell(spans)
: createTableCell(consoleInline(value, theme));
const spans = findOptimalExpansion(value, theme, maxCellLength);
return spans === undefined
? createTableCell(inspectInline(value, theme))
: createTableCell(spans);
}

function findOptimalExpansion(
value: unknown,
theme: "light" | "dark",
maxCellLength: number,
): ConsoleText[] | undefined {
let optimal: ConsoleText[] | undefined;
let depth = 1;
while (true) {
let hasObject = false;
const spans = inspectAny(
value,
{
theme,
wrap: "single-line",
print: false,
line: false,
indent: 0,
depth: depth + 1,
},
{
depth: depth,
indent: 0,
wrap: Number.MAX_SAFE_INTEGER,
},
).map((span) => {
return typeof span === "string"
? consoleText(span)
: span.type === "object"
? ((hasObject = true), inspectInline(span, theme))
: span;
});
if (
spans.every((span): span is ConsoleText => span.type === "text") &&
spansLength(spans) <= maxCellLength
) {
depth += 1;
optimal = spans;
if (!hasObject) {
break;
}
if (depth > 6) {
break;
}
} else {
break;
}
}
return optimal;
}
2 changes: 1 addition & 1 deletion src/extras/consoleTable/flatObjectOrArrayTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function flatObjectOrArrayTable(
const spans: ConsoleText[] = [];
const isArray = Array.isArray(object);
const keys = Object.keys(object);
const lengthPerColumn = Math.floor(options.lineLength / keys.length);
const lengthPerColumn = Math.floor(options.lineLength / 2);
const rows = keys.map((key) => {
return [
createTableCell(
Expand Down
46 changes: 26 additions & 20 deletions src/inspect/consoleInspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import consolePrint from "../core/consolePrint";
import inspectAny from "./inspectors/inspectAny";
import consoleApply from "../core/consoleApply";
import ConsoleSpan from "../core/ConsoleSpan";
import defaultLineLength from "../utils/defaultLineLength";
import guessAvailableLength from "../utils/guessAvailableLength";

export interface ConsoleInspectOptions {
line?: boolean;
indent?: number;
print?: boolean;
depth?: number;
lineLength?: number;
theme?: "light" | "dark";
wrap?: "auto" | "single-line" | "multi-line" | 100;
// preferMultiLine?: boolean;
// preferSingleLine?: boolean;
// preferTables?: boolean;
Expand All @@ -19,31 +19,37 @@ export interface ConsoleInspectOptions {
export interface ConsoleInspectContext {
indent: number;
depth: number;
wrap: number;
}

export default function consoleInspect(
value: unknown,
options?: ConsoleInspectOptions,
): ConsoleSpan[] {
const requiredOptions: Required<ConsoleInspectOptions> = {
depth: 2,
indent: 4,
line: false,
wrap: "auto",
theme: matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light",
print: true,
...options,
};
const spans = consoleApply(
inspectAny(
value,
{
depth: 2,
indent: 4,
line: false,
lineLength: defaultLineLength(),
theme: matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light",
print: true,
...options,
},
{
depth: 0,
indent: 0,
},
),
inspectAny(value, requiredOptions, {
depth: 0,
indent: 0,
wrap:
requiredOptions.wrap === "auto"
? guessAvailableLength()
: requiredOptions.wrap === "single-line"
? Number.MAX_SAFE_INTEGER
: requiredOptions.wrap === "multi-line"
? 0
: requiredOptions.wrap,
}),
{
lineHeight: "1.6",
},
Expand Down
7 changes: 3 additions & 4 deletions src/inspect/inspectors/inspectAny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import inspectObject from "./inspectObject";
import isIterable from "../../utils/isIterable";
import isPrimitive from "../../utils/isPrimitive";
import inspectPrimitive from "./inspectPrimitive";
import { consoleText } from "../../core/consoleText";
import ConsoleSpan from "../../core/ConsoleSpan";
import { consoleObject } from "../../core/consoleObject";
import { ConsoleText, consoleText } from "../../core/consoleText";
import { ConsoleObject, consoleObject } from "../../core/consoleObject";
import { ConsoleInspectContext, ConsoleInspectOptions } from "../consoleInspect";

export default function inspectAny(
value: unknown,
options: Required<ConsoleInspectOptions>,
context: ConsoleInspectContext,
): ConsoleSpan[] {
): (ConsoleText | ConsoleObject)[] {
if (isPrimitive(value)) {
return [inspectPrimitive(value, options.theme)];
} else if (Array.isArray(value) || isIterable(value)) {
Expand Down
38 changes: 19 additions & 19 deletions src/inspect/inspectors/inspectArray.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Primitive } from "type-fest";
import { ConsoleText, consoleText } from "../../core/consoleText";
import inspectPrimitive from "./inspectPrimitive";
import ConsoleSpan from "../../core/ConsoleSpan";
import isPrimitive from "../../utils/isPrimitive";
import inspectAny from "./inspectAny";
import consoleStyles from "../utils/consoleStyles";
Expand All @@ -10,29 +8,29 @@ import {
ConsoleInspectOptions,
} from "../consoleInspect";
import hasOnlyPrimitives from "../../utils/hasOnlyPrimitives";
import { consoleObject } from "../../core/consoleObject";
import { ConsoleObject, consoleObject } from "../../core/consoleObject";
import createIndent from "../utils/createIndent";
import spansLength from "../../utils/spansLength";
import { consoleGroup } from "../../core/consoleGroup";
import inspectInline from "./inspectInline";

export default function inspectArray(
array: unknown[],
options: Required<ConsoleInspectOptions>,
context: ConsoleInspectContext,
): ConsoleSpan[] {
if (array.every(isPrimitive)) {
): (ConsoleText | ConsoleObject)[] {
if (options.wrap !== "auto" || array.every(isPrimitive)) {
const singleLine = singleLineArray(array as Primitive[], options);
if (spansLength(singleLine) + context.indent <= options.lineLength) {
if (spansLength(singleLine) + context.indent <= context.wrap) {
// special case: top-level array
// we otherwise can't use groups because they call `consoleFlush()`
if (context.depth === 0) {
return [
consoleGroup({
header: singleLine,
body: multiLineArray(array, options, context),
}),
];
}
// if (context.depth === 0) {
// return [
// consoleGroup({
// header: singleLine,
// body: multiLineArray(array, options, context),
// }),
// ];
// }
return singleLine;
}
}
Expand All @@ -47,13 +45,13 @@ export default function inspectArray(
function singleLineArray(
array: Primitive[],
options: Required<ConsoleInspectOptions>,
): ConsoleText[] {
): (ConsoleText | ConsoleObject)[] {
return [
consoleText("["),
...array.flatMap((value, i) => {
return i === 0
? [inspectPrimitive(value, options.theme)]
: [consoleText(", "), inspectPrimitive(value, options.theme)];
? [inspectInline(value, options.theme)]
: [consoleText(", "), inspectInline(value, options.theme)];
}),
consoleText("]"),
consoleText(` (${array.length})`, consoleStyles[options.theme].dimmed),
Expand All @@ -64,7 +62,7 @@ function multiLineArray(
array: unknown[],
options: Required<ConsoleInspectOptions>,
context: ConsoleInspectContext,
): ConsoleSpan[] {
): (ConsoleText | ConsoleObject)[] {
return array.flatMap((value, i) => {
const indexText = `[${i}]: `;
const valueSpans =
Expand All @@ -73,11 +71,13 @@ function multiLineArray(
context.depth + 1 >= options.depth
? inspectAny(value, options, {
indent: 0,
wrap: context.wrap,
depth: context.depth + 1,
})
: [
consoleText("\n"),
...inspectAny(value, options, {
wrap: context.wrap,
indent: context.indent + options.indent,
depth: context.depth + 1,
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { consoleText, ConsoleText } from "../core/consoleText";
import isPrimitive from "./isPrimitive";
import inspectPrimitive from "../inspect/inspectors/inspectPrimitive";
import isIterable from "./isIterable";
import { consoleText, ConsoleText } from "../../core/consoleText";
import isPrimitive from "../../utils/isPrimitive";
import inspectPrimitive from "./inspectPrimitive";
import isIterable from "../../utils/isIterable";

export default function consoleInline(
export default function inspectInline(
value: unknown,
theme: "light" | "dark",
): ConsoleText {
Expand Down
Loading

0 comments on commit 4a964b2

Please sign in to comment.