pi-supernova 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,17 @@ export const isFunction = (v) => toStr.call(v) === "[object Function]" || v inst
8
8
 
9
9
  export const isNumber = (v) => toStr.call(v) === "[object Number]" && Number.isFinite(v);
10
10
 
11
+ /** Path-shaped if it has a slash, is relative, or has a file extension. Identifiers are not paths. */
12
+ export function looksLikePath(target) {
13
+ return (
14
+ isString(target) &&
15
+ (target.includes("/") ||
16
+ target.includes("\\") ||
17
+ target.startsWith(".") ||
18
+ (!/\s/.test(target) && /\.[A-Za-z0-9]+$/.test(target)))
19
+ );
20
+ }
21
+
11
22
  const MAX_DEPTH = 64;
12
23
 
13
24
  const MAX_TYPED_ARRAY = 4096;
@@ -54,7 +65,9 @@ export function toPlain(value, seen = new Set(), depth = 0) {
54
65
  if (value === null || value === undefined) return value;
55
66
  const tag = toStr.call(value);
56
67
 
57
- if (tag === "[object String]" || tag === "[object Number]" || tag === "[object Boolean]") return value.valueOf();
68
+ if (tag === "[object String]") return value.valueOf();
69
+
70
+ if (tag === "[object Number]" || tag === "[object Boolean]") return value.valueOf();
58
71
 
59
72
  if (tag === "[object BigInt]") return value.toString() + "n";
60
73
 
@@ -73,7 +86,12 @@ export function toPlain(value, seen = new Set(), depth = 0) {
73
86
  if (value instanceof Error) {
74
87
  const out = { name: value.name, message: value.message };
75
88
 
76
- if (value.cause !== undefined) out.cause = toPlain(value.cause, seen, depth + 1);
89
+ if (value.cause !== undefined) {
90
+ seen.add(value);
91
+
92
+ try { out.cause = toPlain(value.cause, seen, depth + 1); }
93
+ finally { seen.delete(value); }
94
+ }
77
95
 
78
96
  return out;
79
97
  }
@@ -82,7 +100,12 @@ export function toPlain(value, seen = new Set(), depth = 0) {
82
100
 
83
101
  if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return plainFromBinary(value);
84
102
 
85
- if (isFunction(value.toJSON)) return toPlain(value.toJSON(), seen, depth + 1);
103
+ if (isFunction(value.toJSON)) {
104
+ seen.add(value);
105
+
106
+ try { return toPlain(value.toJSON(), seen, depth + 1); }
107
+ finally { seen.delete(value); }
108
+ }
86
109
  seen.add(value);
87
110
 
88
111
  try {
@@ -38,7 +38,10 @@ function borderPaint(theme, state, borderColor) {
38
38
 
39
39
  if (theme && isFunction(theme.fg)) {
40
40
  try {
41
- return (text) => theme.fg(key, text);
41
+ return (text) => {
42
+ try { return theme.fg(key, text); }
43
+ catch { return text; }
44
+ };
42
45
  } catch {
43
46
  /* fall through */
44
47
  }
@@ -51,10 +54,14 @@ const STATUS_PREFIX = { error: ["error", "✗ "], running: ["dim", "… "] };
51
54
 
52
55
  function statusHeader(theme, { title, description, state, icon }) {
53
56
  const resolved = icon ?? (state === "error" ? "error" : undefined);
57
+ const fg = (key, text) => {
58
+ try { return isFunction(theme?.fg) ? theme.fg(key, text) : text; }
59
+ catch { return text; }
60
+ };
54
61
  const prefixSpec = STATUS_PREFIX[resolved];
55
- const prefix = prefixSpec ? (theme?.fg ? theme.fg(prefixSpec[0], prefixSpec[1]) : prefixSpec[1]) : "";
56
- const titleText = theme?.fg ? theme.fg("accent", title) : title;
57
- const descText = description ? (theme?.fg ? theme.fg("muted", description) : description) : "";
62
+ const prefix = prefixSpec ? fg(prefixSpec[0], prefixSpec[1]) : "";
63
+ const titleText = fg("accent", title);
64
+ const descText = description ? fg("muted", description) : "";
58
65
 
59
66
  return descText ? `${prefix}${titleText}: ${descText}` : `${prefix}${titleText}`;
60
67
  }
package/src/ui/render.js CHANGED
@@ -363,9 +363,9 @@ function opDuration(op, isPartial) {
363
363
  */
364
364
  function formatOpRow(theme, op, width, isPartial, isError) {
365
365
  const marker = opMarker(theme, op, isPartial, isError);
366
- const toolText = op.tool.padEnd(TOOL_COL);
366
+ const toolText = op.tool.slice(0, TOOL_COL).padEnd(TOOL_COL);
367
367
  const tool = theme.fg("syntaxFunction", toolText);
368
- const durationText = opDuration(op, isPartial);
368
+ const durationText = opDuration(op, isPartial).slice(-DURATION_COL);
369
369
  const duration = theme.fg("dim", durationText.padStart(DURATION_COL));
370
370
  let prefix = `${marker} ${tool} ${duration} `;
371
371
  let used = 2 + toolText.length + 1 + DURATION_COL + 2;