@qzsy/vinext 0.1.82 → 0.1.84

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.
@@ -12,8 +12,103 @@ import { VINEXT_ACTION_LOG_HEADER } from "./headers.js";
12
12
  *
13
13
  * https://github.com/vercel/next.js/pull/88277
14
14
  */
15
+ /** Max characters per string arg in dev action logs. */
16
+ const MAX_ARG_STRING_LENGTH = 80;
17
+ /** Max UTF-8 bytes for the JSON payload before base64 encoding. */
18
+ const MAX_HEADER_JSON_BYTES = 2048;
15
19
  const INLINE_ACTION_PREFIXES = ["$$RSC_SERVER_ACTION_", "$$hoist_"];
16
20
  const USE_CACHE_ACTION_PREFIX = "$$RSC_SERVER_CACHE_";
21
+ function truncateString(value, maxLength = MAX_ARG_STRING_LENGTH) {
22
+ if (value.length <= maxLength) return value;
23
+ return `${value.slice(0, maxLength)}...`;
24
+ }
25
+ const DEFAULT_ARG_SANITIZE_LIMITS = {
26
+ maxStringLength: MAX_ARG_STRING_LENGTH,
27
+ maxArrayItems: 3,
28
+ maxObjectKeys: 3,
29
+ maxDepth: 2
30
+ };
31
+ function sanitizeArgForLog(arg, depth = 0, limits = DEFAULT_ARG_SANITIZE_LIMITS) {
32
+ if (arg === null || arg === void 0) return arg;
33
+ if (typeof arg === "string") return truncateString(arg, limits.maxStringLength);
34
+ if (typeof arg === "number" || typeof arg === "boolean" || typeof arg === "bigint") return arg;
35
+ if (typeof arg === "symbol") return String(arg);
36
+ if (typeof arg === "function") return "[Function]";
37
+ if (depth >= limits.maxDepth) return "[Object]";
38
+ if (Array.isArray(arg)) {
39
+ const items = arg.slice(0, limits.maxArrayItems).map((item) => sanitizeArgForLog(item, depth + 1, limits));
40
+ if (arg.length > limits.maxArrayItems) items.push("...");
41
+ return items;
42
+ }
43
+ if (typeof arg === "object") try {
44
+ const entries = Object.entries(arg).slice(0, limits.maxObjectKeys);
45
+ const sanitized = {};
46
+ for (const [key, value] of entries) sanitized[key] = sanitizeArgForLog(value, depth + 1, limits);
47
+ if (Object.keys(arg).length > limits.maxObjectKeys) sanitized["..."] = "...";
48
+ return sanitized;
49
+ } catch {
50
+ return "[Object]";
51
+ }
52
+ try {
53
+ return truncateString(JSON.stringify(arg), limits.maxStringLength);
54
+ } catch {
55
+ return "[unserializable]";
56
+ }
57
+ }
58
+ function sanitizeArgsForLog(args, limits = DEFAULT_ARG_SANITIZE_LIMITS) {
59
+ return args.map((arg) => sanitizeArgForLog(arg, 0, limits));
60
+ }
61
+ function headerJsonByteLength(info) {
62
+ return Buffer.byteLength(JSON.stringify(info), "utf8");
63
+ }
64
+ /** Keep as much leading arg content as possible while staying under the header budget. */
65
+ function fitLogInfoForHeader(info) {
66
+ const limits = { ...DEFAULT_ARG_SANITIZE_LIMITS };
67
+ let maxArgs = info.args.length;
68
+ while (true) {
69
+ const args = sanitizeArgsForLog(info.args.slice(0, maxArgs), limits);
70
+ if (maxArgs < info.args.length) args.push("...");
71
+ const candidate = {
72
+ functionName: info.functionName,
73
+ args,
74
+ location: info.location,
75
+ duration: info.duration
76
+ };
77
+ if (headerJsonByteLength(candidate) <= MAX_HEADER_JSON_BYTES) return candidate;
78
+ if (limits.maxStringLength > 16) {
79
+ limits.maxStringLength = Math.max(16, Math.floor(limits.maxStringLength / 2));
80
+ continue;
81
+ }
82
+ if (limits.maxArrayItems > 1) {
83
+ limits.maxArrayItems--;
84
+ continue;
85
+ }
86
+ if (limits.maxObjectKeys > 1) {
87
+ limits.maxObjectKeys--;
88
+ continue;
89
+ }
90
+ if (limits.maxDepth > 0) {
91
+ limits.maxDepth--;
92
+ continue;
93
+ }
94
+ if (maxArgs > 1) {
95
+ maxArgs--;
96
+ continue;
97
+ }
98
+ if (limits.maxStringLength > 1) {
99
+ limits.maxStringLength = Math.max(1, Math.floor(limits.maxStringLength / 2));
100
+ continue;
101
+ }
102
+ const firstArg = info.args[0];
103
+ const prefix = typeof firstArg === "string" ? truncateString(firstArg, 1) : truncateString(formatArg(firstArg), 1);
104
+ return {
105
+ functionName: info.functionName,
106
+ args: [prefix, "..."],
107
+ location: info.location,
108
+ duration: info.duration
109
+ };
110
+ }
111
+ }
17
112
  function isDevServerActionLoggingEnabled() {
18
113
  return process.env.NODE_ENV !== "production";
19
114
  }
@@ -48,7 +143,7 @@ function resolveServerActionLogMeta(actionId) {
48
143
  function formatArg(arg, depth = 0) {
49
144
  if (arg === null) return "null";
50
145
  if (arg === void 0) return "undefined";
51
- if (typeof arg === "string") return JSON.stringify(arg);
146
+ if (typeof arg === "string") return JSON.stringify(truncateString(arg));
52
147
  if (typeof arg === "number" || typeof arg === "boolean" || typeof arg === "bigint") return String(arg);
53
148
  if (typeof arg === "symbol") return String(arg);
54
149
  if (typeof arg === "function") return "[Function]";
@@ -75,12 +170,27 @@ function formatArg(arg, depth = 0) {
75
170
  function formatActionArgs(args) {
76
171
  return args.map((arg) => formatArg(arg)).join(", ");
77
172
  }
173
+ function encodeHeaderPayload(json) {
174
+ return Buffer.from(json, "utf8").toString("base64");
175
+ }
176
+ function decodeHeaderPayload(value) {
177
+ if (value.startsWith("{")) return value;
178
+ return Buffer.from(value, "base64").toString("utf8");
179
+ }
180
+ function prepareLogInfoForHeader(info) {
181
+ const prepared = {
182
+ ...info,
183
+ args: sanitizeArgsForLog(info.args)
184
+ };
185
+ if (headerJsonByteLength(prepared) <= MAX_HEADER_JSON_BYTES) return prepared;
186
+ return fitLogInfoForHeader(info);
187
+ }
78
188
  function serializeServerActionLogHeader(info) {
79
- return JSON.stringify(info);
189
+ return encodeHeaderPayload(JSON.stringify(prepareLogInfoForHeader(info)));
80
190
  }
81
191
  function parseServerActionLogHeader(value) {
82
192
  try {
83
- const parsed = JSON.parse(value);
193
+ const parsed = JSON.parse(decodeHeaderPayload(value));
84
194
  if (typeof parsed.functionName === "string" && Array.isArray(parsed.args) && typeof parsed.location === "string" && typeof parsed.duration === "number") return parsed;
85
195
  } catch {}
86
196
  return null;
@@ -96,7 +206,7 @@ function createServerActionLogInfo(options) {
96
206
  const args = Array.isArray(options.args) ? options.args : [options.args];
97
207
  return {
98
208
  ...meta,
99
- args: [...args],
209
+ args: sanitizeArgsForLog([...args]),
100
210
  duration: options.durationMs
101
211
  };
102
212
  }
@@ -582,7 +582,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
582
582
  const Router = window.next?.appDir === true ? void 0 : window.next?.router;
583
583
  await navigatePagesRouterLinkWithFallback({
584
584
  router: Router && "reload" in Router ? Router : void 0,
585
- loadRouter: async () => (await import("D:\\projects\\vinext\\node_modules\\.pnpm\\next@16.2.7_@opentelemetry+_a27effa3fabbfbd07255229e73bfb661\\node_modules\\next\\router.js")).default,
585
+ loadRouter: async () => (await import("./router.js")).default,
586
586
  navigation: {
587
587
  href: pagesHrefForLink,
588
588
  as: pagesAsForLink,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzsy/vinext",
3
- "version": "0.1.82",
3
+ "version": "0.1.84",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {