akanjs 2.3.9-rc.4 → 2.3.9-rc.6
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.
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/common/Logger.ts +1 -81
- package/common/index.ts +1 -8
- package/package.json +1 -1
- package/server/rscWorker.tsx +26 -115
- package/server/rscWorkerHost.ts +12 -56
- package/server/ssrFromRscRenderer.tsx +5 -22
- package/server/ssrTypes.ts +0 -1
- package/server/webRouter.ts +12 -130
- package/types/common/Logger.d.ts +0 -20
- package/types/common/index.d.ts +1 -1
- package/types/server/rscWorkerHost.d.ts +2 -17
- package/types/server/ssrTypes.d.ts +0 -4
package/README.ko.md
CHANGED
|
@@ -220,7 +220,7 @@ akan update
|
|
|
220
220
|
|
|
221
221
|
주요 영역:
|
|
222
222
|
|
|
223
|
-
- **Workspace**: workspace 생성,
|
|
223
|
+
- **Workspace**: workspace 생성, lint, sync.
|
|
224
224
|
- **Application**: app start, build, typecheck, package, release.
|
|
225
225
|
- **Library**: shared library 생성, 설치, sync, push, pull.
|
|
226
226
|
- **Module and scalar**: domain module, model, view, unit, template, store 생성.
|
package/README.md
CHANGED
|
@@ -218,7 +218,7 @@ akan update
|
|
|
218
218
|
|
|
219
219
|
Common areas:
|
|
220
220
|
|
|
221
|
-
- **Workspace**: create workspaces,
|
|
221
|
+
- **Workspace**: create workspaces, lint and sync projects.
|
|
222
222
|
- **Application**: start, build, typecheck, package, and release apps.
|
|
223
223
|
- **Library**: create, install, sync, push, and pull shared libraries.
|
|
224
224
|
- **Module and scalar**: generate domain modules, models, views, units, templates, and stores.
|
package/common/Logger.ts
CHANGED
|
@@ -2,24 +2,12 @@ import dayjs from "dayjs";
|
|
|
2
2
|
|
|
3
3
|
const logLevels = ["trace", "verbose", "debug", "log", "info", "warn", "error"] as const;
|
|
4
4
|
export type LogLevel = (typeof logLevels)[number];
|
|
5
|
-
export type LoggerMeta = Record<string, unknown>;
|
|
6
|
-
|
|
7
|
-
export interface LoggerSerializedError {
|
|
8
|
-
name?: string;
|
|
9
|
-
message: string;
|
|
10
|
-
stack?: string;
|
|
11
|
-
cause?: LoggerSerializedError | string;
|
|
12
|
-
digest?: string;
|
|
13
|
-
code?: string | number;
|
|
14
|
-
status?: number;
|
|
15
|
-
}
|
|
16
5
|
|
|
17
6
|
export interface LoggerSinkEntry {
|
|
18
7
|
stream: "stdout" | "stderr";
|
|
19
8
|
level?: LogLevel;
|
|
20
9
|
message: string;
|
|
21
10
|
plainMessage: string;
|
|
22
|
-
meta?: LoggerMeta;
|
|
23
11
|
}
|
|
24
12
|
|
|
25
13
|
export type LoggerSink = (entry: LoggerSinkEntry) => void | Promise<void>;
|
|
@@ -45,11 +33,6 @@ const colorizeMap: { [key in LogLevel]: (text: string) => string } = {
|
|
|
45
33
|
|
|
46
34
|
const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
47
35
|
|
|
48
|
-
function readErrorProp(error: unknown, key: string): unknown {
|
|
49
|
-
if (typeof error !== "object" || error === null || !(key in error)) return undefined;
|
|
50
|
-
return (error as Record<string, unknown>)[key];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
36
|
/** Log-level aware logger used by Akan runtime, CLI, and application services. */
|
|
54
37
|
export class Logger {
|
|
55
38
|
static level: LogLevel = (process.env?.AKAN_PUBLIC_LOG_LEVEL as LogLevel | undefined) ?? "log";
|
|
@@ -103,9 +86,6 @@ export class Logger {
|
|
|
103
86
|
error(msg: string, context = "", name = this.name ?? "App") {
|
|
104
87
|
if (Logger.#shouldLog("error")) Logger.#printMessages(name, msg, context, "error");
|
|
105
88
|
}
|
|
106
|
-
errorObject(msg: string, error: unknown, meta: LoggerMeta = {}, context = "", name = this.name ?? "App") {
|
|
107
|
-
if (Logger.#shouldLog("error")) Logger.#printError(name, msg, error, meta, context);
|
|
108
|
-
}
|
|
109
89
|
raw(msg: string, method?: "console" | "process") {
|
|
110
90
|
Logger.rawLog(msg, method);
|
|
111
91
|
}
|
|
@@ -134,60 +114,6 @@ export class Logger {
|
|
|
134
114
|
static error(msg: string, context = "", name = "App") {
|
|
135
115
|
if (Logger.#shouldLog("error")) Logger.#printMessages(name, msg, context, "error");
|
|
136
116
|
}
|
|
137
|
-
static errorObject(msg: string, error: unknown, meta: LoggerMeta = {}, context = "", name = "App") {
|
|
138
|
-
if (Logger.#shouldLog("error")) Logger.#printError(name, msg, error, meta, context);
|
|
139
|
-
}
|
|
140
|
-
static createErrorId(input: { requestId?: string; scope?: string; sequence?: string | number } = {}) {
|
|
141
|
-
const parts = ["akanerr", input.requestId, input.scope, input.sequence, Date.now().toString(36)]
|
|
142
|
-
.filter((part): part is string | number => part !== undefined && part !== "")
|
|
143
|
-
.map((part) => String(part).replace(/[^a-zA-Z0-9_-]/g, "-"));
|
|
144
|
-
return parts.join("-");
|
|
145
|
-
}
|
|
146
|
-
static serializeError(error: unknown): LoggerSerializedError {
|
|
147
|
-
if (error instanceof Error) {
|
|
148
|
-
const digest = readErrorProp(error, "digest");
|
|
149
|
-
const code = readErrorProp(error, "code");
|
|
150
|
-
const status = readErrorProp(error, "status") ?? readErrorProp(error, "statusCode");
|
|
151
|
-
return {
|
|
152
|
-
name: error.name,
|
|
153
|
-
message: error.message,
|
|
154
|
-
...(error.stack ? { stack: error.stack } : {}),
|
|
155
|
-
...(error.cause !== undefined ? { cause: Logger.serializeError(error.cause) } : {}),
|
|
156
|
-
...(typeof digest === "string" ? { digest } : {}),
|
|
157
|
-
...(typeof code === "string" || typeof code === "number" ? { code } : {}),
|
|
158
|
-
...(typeof status === "number" ? { status } : {}),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (typeof error === "object" && error !== null) {
|
|
162
|
-
const message = readErrorProp(error, "message");
|
|
163
|
-
const name = readErrorProp(error, "name");
|
|
164
|
-
const stack = readErrorProp(error, "stack");
|
|
165
|
-
const cause = readErrorProp(error, "cause");
|
|
166
|
-
const digest = readErrorProp(error, "digest");
|
|
167
|
-
const code = readErrorProp(error, "code");
|
|
168
|
-
const status = readErrorProp(error, "status") ?? readErrorProp(error, "statusCode");
|
|
169
|
-
return {
|
|
170
|
-
...(typeof name === "string" ? { name } : {}),
|
|
171
|
-
message: typeof message === "string" ? message : String(error),
|
|
172
|
-
...(typeof stack === "string" ? { stack } : {}),
|
|
173
|
-
...(cause !== undefined ? { cause: Logger.serializeError(cause) } : {}),
|
|
174
|
-
...(typeof digest === "string" ? { digest } : {}),
|
|
175
|
-
...(typeof code === "string" || typeof code === "number" ? { code } : {}),
|
|
176
|
-
...(typeof status === "number" ? { status } : {}),
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
return { message: String(error) };
|
|
180
|
-
}
|
|
181
|
-
static formatError(error: unknown) {
|
|
182
|
-
const serialized = Logger.serializeError(error);
|
|
183
|
-
const details = serialized.stack ?? serialized.message;
|
|
184
|
-
if (!serialized.cause) return details;
|
|
185
|
-
const cause =
|
|
186
|
-
typeof serialized.cause === "string"
|
|
187
|
-
? serialized.cause
|
|
188
|
-
: (serialized.cause.stack ?? serialized.cause.message);
|
|
189
|
-
return `${details}\nCaused by: ${cause}`;
|
|
190
|
-
}
|
|
191
117
|
static #colorize(msg: string, logLevel: LogLevel) {
|
|
192
118
|
return colorizeMap[logLevel](msg);
|
|
193
119
|
}
|
|
@@ -211,18 +137,12 @@ export class Logger {
|
|
|
211
137
|
}
|
|
212
138
|
}
|
|
213
139
|
}
|
|
214
|
-
static #printError(name: string | undefined, msg: string, error: unknown, meta: LoggerMeta, context: string) {
|
|
215
|
-
const serializedError = Logger.serializeError(error);
|
|
216
|
-
const message = `${msg}: ${Logger.formatError(error)}`;
|
|
217
|
-
Logger.#printMessages(name, message, context, "error", "stderr", { ...meta, error: serializedError });
|
|
218
|
-
}
|
|
219
140
|
static #printMessages(
|
|
220
141
|
name: string | undefined,
|
|
221
142
|
content: string,
|
|
222
143
|
context: string,
|
|
223
144
|
logLevel: LogLevel,
|
|
224
145
|
writeStreamType: "stdout" | "stderr" = logLevel === "error" ? "stderr" : "stdout",
|
|
225
|
-
meta?: LoggerMeta,
|
|
226
146
|
) {
|
|
227
147
|
const now = dayjs();
|
|
228
148
|
const replicaIdx = (process as unknown as NodeJS.Process | undefined)?.env?.AKAN_REPLICA_IDX;
|
|
@@ -238,7 +158,7 @@ export class Logger {
|
|
|
238
158
|
const timeDiffMsg = clc.yellow(`+${now.diff(Logger.#startAt, "ms")}ms`);
|
|
239
159
|
const message = `${processMsg} ${timestampMsg} ${logLevelMsg} ${contextMsg} ${contentMsg} ${timeDiffMsg}\n`;
|
|
240
160
|
if (Logger.#shouldEmitSink(logLevel))
|
|
241
|
-
Logger.#emit({ stream: writeStreamType, level: logLevel, message, plainMessage: Logger.#stripAnsi(message)
|
|
161
|
+
Logger.#emit({ stream: writeStreamType, level: logLevel, message, plainMessage: Logger.#stripAnsi(message) });
|
|
242
162
|
if (!Logger.#shouldWriteConsole(logLevel)) return;
|
|
243
163
|
if (typeof window === "undefined")
|
|
244
164
|
(process[writeStreamType] as unknown as NodeJS.WriteStream | undefined)?.write(message);
|
package/common/index.ts
CHANGED
|
@@ -17,14 +17,7 @@ export { isPhoneNumber } from "./isPhoneNumber";
|
|
|
17
17
|
export { isQueryEqual } from "./isQueryEqual";
|
|
18
18
|
export { isValidDate } from "./isValidDate";
|
|
19
19
|
export { decodeJwtPayload } from "./jwtDecode";
|
|
20
|
-
export {
|
|
21
|
-
Logger,
|
|
22
|
-
type LoggerMeta,
|
|
23
|
-
type LoggerSerializedError,
|
|
24
|
-
type LoggerSink,
|
|
25
|
-
type LoggerSinkEntry,
|
|
26
|
-
type LogLevel,
|
|
27
|
-
} from "./Logger";
|
|
20
|
+
export { Logger, type LoggerSink, type LoggerSinkEntry, type LogLevel } from "./Logger";
|
|
28
21
|
export {
|
|
29
22
|
type AkanI18nConfig,
|
|
30
23
|
type AkanI18nConfigInput,
|
package/package.json
CHANGED
package/server/rscWorker.tsx
CHANGED
|
@@ -110,7 +110,7 @@ type InMsg = InitMsg | RenderMsg | CancelMsg | ReloadMsg | UpdateCssAssetsMsg |
|
|
|
110
110
|
type RenderControl =
|
|
111
111
|
| { type: "redirect"; location: string; method: "replace" | "push"; status: RedirectStatus }
|
|
112
112
|
| { type: "not-found" }
|
|
113
|
-
| { type: "error"; error: unknown
|
|
113
|
+
| { type: "error"; error: unknown };
|
|
114
114
|
interface FlightRenderResult {
|
|
115
115
|
chunks: Uint8Array[];
|
|
116
116
|
bytes: number;
|
|
@@ -206,7 +206,6 @@ export class RscRenderer {
|
|
|
206
206
|
#resultCacheHits = 0;
|
|
207
207
|
#resultCacheMisses = 0;
|
|
208
208
|
#resultCacheBypass = 0;
|
|
209
|
-
#renderErrorSequence = 0;
|
|
210
209
|
readonly #send: (message: unknown) => void;
|
|
211
210
|
|
|
212
211
|
constructor() {
|
|
@@ -224,74 +223,6 @@ export class RscRenderer {
|
|
|
224
223
|
this.#send({ type: "hello" });
|
|
225
224
|
}
|
|
226
225
|
|
|
227
|
-
#nextRenderErrorId(requestId: string | undefined, scope: string): string {
|
|
228
|
-
this.#renderErrorSequence += 1;
|
|
229
|
-
return Logger.createErrorId({ requestId, scope, sequence: this.#renderErrorSequence });
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
#createRenderErrorPayload(
|
|
233
|
-
error: unknown,
|
|
234
|
-
input: {
|
|
235
|
-
requestId?: string;
|
|
236
|
-
scope: string;
|
|
237
|
-
errorId?: string;
|
|
238
|
-
url?: URL | string;
|
|
239
|
-
pathname?: string;
|
|
240
|
-
routeId?: string;
|
|
241
|
-
trace?: RscTraceMetadata;
|
|
242
|
-
},
|
|
243
|
-
) {
|
|
244
|
-
const errorId = input.errorId ?? this.#nextRenderErrorId(input.requestId, input.scope);
|
|
245
|
-
const serialized = Logger.serializeError(error);
|
|
246
|
-
const pathname = input.pathname ?? input.trace?.pathname;
|
|
247
|
-
const routeId = input.routeId ?? input.trace?.routeId;
|
|
248
|
-
const url = typeof input.url === "string" ? input.url : input.url?.href;
|
|
249
|
-
const meta = {
|
|
250
|
-
errorId,
|
|
251
|
-
requestId: input.requestId,
|
|
252
|
-
scope: input.scope,
|
|
253
|
-
url,
|
|
254
|
-
pathname,
|
|
255
|
-
routeId,
|
|
256
|
-
digest: errorId,
|
|
257
|
-
originalDigest: serialized.digest,
|
|
258
|
-
};
|
|
259
|
-
return {
|
|
260
|
-
message: serialized.message,
|
|
261
|
-
name: serialized.name,
|
|
262
|
-
stack: serialized.stack,
|
|
263
|
-
errorId,
|
|
264
|
-
digest: errorId,
|
|
265
|
-
requestId: input.requestId,
|
|
266
|
-
scope: input.scope,
|
|
267
|
-
pathname,
|
|
268
|
-
routeId,
|
|
269
|
-
meta,
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
#logRenderError(
|
|
274
|
-
message: string,
|
|
275
|
-
error: unknown,
|
|
276
|
-
input: {
|
|
277
|
-
requestId?: string;
|
|
278
|
-
scope: string;
|
|
279
|
-
errorId?: string;
|
|
280
|
-
url?: URL | string;
|
|
281
|
-
pathname?: string;
|
|
282
|
-
routeId?: string;
|
|
283
|
-
trace?: RscTraceMetadata;
|
|
284
|
-
},
|
|
285
|
-
) {
|
|
286
|
-
const payload = this.#createRenderErrorPayload(error, input);
|
|
287
|
-
this.#logger.errorObject(
|
|
288
|
-
`${message} requestId=${input.requestId ?? "(none)"} scope=${input.scope} errorId=${payload.errorId}`,
|
|
289
|
-
error,
|
|
290
|
-
payload.meta,
|
|
291
|
-
);
|
|
292
|
-
return payload;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
226
|
#handleMessage(msg: InMsg): void {
|
|
296
227
|
switch (msg.type) {
|
|
297
228
|
case "init":
|
|
@@ -356,11 +287,11 @@ export class RscRenderer {
|
|
|
356
287
|
this.#logger.verbose(`init complete in ${Date.now() - startedAt}ms`);
|
|
357
288
|
this.#send({ type: "ready" });
|
|
358
289
|
} catch (error) {
|
|
359
|
-
|
|
290
|
+
this.#logger.error(`init failed: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`);
|
|
360
291
|
this.#send({
|
|
361
292
|
type: "error",
|
|
362
|
-
...payload,
|
|
363
293
|
requestId: "__init__",
|
|
294
|
+
message: error instanceof Error ? error.message : String(error),
|
|
364
295
|
});
|
|
365
296
|
}
|
|
366
297
|
}
|
|
@@ -395,15 +326,14 @@ export class RscRenderer {
|
|
|
395
326
|
this.#logger.verbose(`reload complete buildId=${msg.buildId} in ${Date.now() - startedAt}ms`);
|
|
396
327
|
this.#send({ type: "reloaded", buildId: msg.buildId });
|
|
397
328
|
} catch (error) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
});
|
|
329
|
+
this.#logger.error(
|
|
330
|
+
`reload failed buildId=${msg.buildId}: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`,
|
|
331
|
+
);
|
|
402
332
|
this.#send({
|
|
403
333
|
type: "error",
|
|
404
|
-
...payload,
|
|
405
334
|
requestId: "__reload__",
|
|
406
335
|
buildId: msg.buildId,
|
|
336
|
+
message: error instanceof Error ? error.message : String(error),
|
|
407
337
|
});
|
|
408
338
|
}
|
|
409
339
|
}
|
|
@@ -808,13 +738,9 @@ export class RscRenderer {
|
|
|
808
738
|
this.#send({ type: "not-found", requestId });
|
|
809
739
|
return;
|
|
810
740
|
}
|
|
811
|
-
|
|
812
|
-
requestId
|
|
813
|
-
|
|
814
|
-
url,
|
|
815
|
-
pathname: activeRoute.url?.pathname,
|
|
816
|
-
routeId: activeRoute.match?.pathRoute.path,
|
|
817
|
-
});
|
|
741
|
+
this.#logger.error(
|
|
742
|
+
`render[${requestId}] failed url=${url}: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`,
|
|
743
|
+
);
|
|
818
744
|
const fallbackUrl = activeRoute.url;
|
|
819
745
|
const fallbackMatch = activeRoute.match;
|
|
820
746
|
if (
|
|
@@ -836,8 +762,8 @@ export class RscRenderer {
|
|
|
836
762
|
}
|
|
837
763
|
this.#send({
|
|
838
764
|
type: "error",
|
|
839
|
-
...payload,
|
|
840
765
|
requestId,
|
|
766
|
+
message: error instanceof Error ? error.message : String(error),
|
|
841
767
|
});
|
|
842
768
|
} finally {
|
|
843
769
|
this.#activeRenderReaders.delete(requestId);
|
|
@@ -908,7 +834,6 @@ export class RscRenderer {
|
|
|
908
834
|
const controlRef: { current: RenderControl | null } = { current: null };
|
|
909
835
|
const stream = await renderToReadableStream(element, clientManifest, {
|
|
910
836
|
onError: (error) => {
|
|
911
|
-
if (controlRef.current?.type === "error") return controlRef.current.digest;
|
|
912
837
|
if (isAkanRedirectError(error)) {
|
|
913
838
|
controlRef.current = {
|
|
914
839
|
type: "redirect",
|
|
@@ -926,13 +851,8 @@ export class RscRenderer {
|
|
|
926
851
|
controlRef.current = { type: "not-found" };
|
|
927
852
|
return error.digest;
|
|
928
853
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
scope: "rsc-stream",
|
|
932
|
-
trace: options.trace,
|
|
933
|
-
});
|
|
934
|
-
controlRef.current = { type: "error", error, errorId: payload.errorId, digest: payload.digest };
|
|
935
|
-
return payload.digest;
|
|
854
|
+
controlRef.current = { type: "error", error };
|
|
855
|
+
return error instanceof Error ? error.message : String(error);
|
|
936
856
|
},
|
|
937
857
|
});
|
|
938
858
|
const reader = stream.getReader();
|
|
@@ -1071,14 +991,11 @@ export class RscRenderer {
|
|
|
1071
991
|
this.#stats.totalFlightChunks += result.chunksCount;
|
|
1072
992
|
return true;
|
|
1073
993
|
} catch (fallbackError) {
|
|
1074
|
-
this.#
|
|
1075
|
-
requestId
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
routeId: route.path,
|
|
1080
|
-
trace,
|
|
1081
|
-
});
|
|
994
|
+
this.#logger.error(
|
|
995
|
+
`render[${requestId}] custom ${kind} fallback failed: ${
|
|
996
|
+
fallbackError instanceof Error ? (fallbackError.stack ?? fallbackError.message) : String(fallbackError)
|
|
997
|
+
}`,
|
|
998
|
+
);
|
|
1082
999
|
return false;
|
|
1083
1000
|
}
|
|
1084
1001
|
}
|
|
@@ -1108,13 +1025,11 @@ export class RscRenderer {
|
|
|
1108
1025
|
this.#stats.totalFlightChunks += result.chunksCount;
|
|
1109
1026
|
return true;
|
|
1110
1027
|
} catch (error) {
|
|
1111
|
-
this.#
|
|
1112
|
-
requestId
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
trace,
|
|
1117
|
-
});
|
|
1028
|
+
this.#logger.error(
|
|
1029
|
+
`render[${requestId}] system not-found fallback failed: ${
|
|
1030
|
+
error instanceof Error ? (error.stack ?? error.message) : String(error)
|
|
1031
|
+
}`,
|
|
1032
|
+
);
|
|
1118
1033
|
return false;
|
|
1119
1034
|
}
|
|
1120
1035
|
}
|
|
@@ -1132,13 +1047,9 @@ export class RscRenderer {
|
|
|
1132
1047
|
return;
|
|
1133
1048
|
}
|
|
1134
1049
|
if (control.type === "error") {
|
|
1135
|
-
const
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
errorId: control.errorId,
|
|
1139
|
-
});
|
|
1140
|
-
this.#logger.verbose(`render[${requestId}] error errorId=${payload.errorId}`);
|
|
1141
|
-
this.#send({ type: "error", ...payload, requestId });
|
|
1050
|
+
const message = control.error instanceof Error ? control.error.message : String(control.error);
|
|
1051
|
+
this.#logger.verbose(`render[${requestId}] error`);
|
|
1052
|
+
this.#send({ type: "error", requestId, message });
|
|
1142
1053
|
return;
|
|
1143
1054
|
}
|
|
1144
1055
|
this.#logger.verbose(`render[${requestId}] not-found`);
|
package/server/rscWorkerHost.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { type AkanI18nConfig, DEFAULT_AKAN_I18N, Logger
|
|
4
|
+
import { type AkanI18nConfig, DEFAULT_AKAN_I18N, Logger } from "akanjs/common";
|
|
5
5
|
import type { AkanTheme } from "akanjs/fetch";
|
|
6
6
|
import type { AkanMetricsReport } from "akanjs/service";
|
|
7
7
|
import type { ClientManifest } from "./artifact";
|
|
@@ -14,7 +14,7 @@ const DEFAULT_RSC_HOST_MAX_PENDING_CHUNKS = 256;
|
|
|
14
14
|
export interface RscPending {
|
|
15
15
|
onChunk: (data: Uint8Array) => void;
|
|
16
16
|
onEnd: () => void;
|
|
17
|
-
onError: (
|
|
17
|
+
onError: (message: string) => void;
|
|
18
18
|
onMeta?: (meta: { theme?: AkanTheme; status?: number; trace?: RscTraceMetadata }) => void;
|
|
19
19
|
onCacheState?: (state: RouteCacheRenderState) => void;
|
|
20
20
|
onRedirect?: (location: string, method: RscRedirectMethod, status: RscRedirectStatus) => void;
|
|
@@ -25,19 +25,6 @@ export interface RscPending {
|
|
|
25
25
|
export type RscRedirectMethod = "replace" | "push";
|
|
26
26
|
export type RscRedirectStatus = 303 | 307 | 308;
|
|
27
27
|
|
|
28
|
-
export interface RscWorkerErrorPayload {
|
|
29
|
-
message: string;
|
|
30
|
-
name?: string;
|
|
31
|
-
stack?: string;
|
|
32
|
-
errorId?: string;
|
|
33
|
-
digest?: string;
|
|
34
|
-
requestId?: string;
|
|
35
|
-
scope?: string;
|
|
36
|
-
pathname?: string;
|
|
37
|
-
routeId?: string;
|
|
38
|
-
meta?: LoggerMeta;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
28
|
export interface RscWorkerInvalidateCacheMessage {
|
|
42
29
|
type: "invalidate-cache";
|
|
43
30
|
reason?: string;
|
|
@@ -48,7 +35,6 @@ export interface RscWorkerInvalidateCacheMessage {
|
|
|
48
35
|
export type RscRenderResult =
|
|
49
36
|
| {
|
|
50
37
|
type: "stream";
|
|
51
|
-
requestId?: string;
|
|
52
38
|
stream: ReadableStream<Uint8Array>;
|
|
53
39
|
theme?: AkanTheme;
|
|
54
40
|
status?: number;
|
|
@@ -80,23 +66,6 @@ function createRscRenderAbortError(reason?: unknown): Error {
|
|
|
80
66
|
return error;
|
|
81
67
|
}
|
|
82
68
|
|
|
83
|
-
export function createRscWorkerError(input: string | RscWorkerErrorPayload): Error {
|
|
84
|
-
if (typeof input === "string") return new Error(input);
|
|
85
|
-
const error = new Error(input.message);
|
|
86
|
-
if (input.name) error.name = input.name;
|
|
87
|
-
if (input.stack) error.stack = input.stack;
|
|
88
|
-
Object.assign(error, {
|
|
89
|
-
errorId: input.errorId,
|
|
90
|
-
digest: input.digest ?? input.errorId,
|
|
91
|
-
requestId: input.requestId,
|
|
92
|
-
scope: input.scope,
|
|
93
|
-
pathname: input.pathname,
|
|
94
|
-
routeId: input.routeId,
|
|
95
|
-
meta: input.meta,
|
|
96
|
-
});
|
|
97
|
-
return error;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
69
|
export function createIdempotentRscRenderCancel(onCancel: (reason?: unknown) => void): (reason?: unknown) => void {
|
|
101
70
|
let cancelled = false;
|
|
102
71
|
return (reason?: unknown) => {
|
|
@@ -120,7 +89,6 @@ export function createRscWorkerInvalidateCacheMessage(
|
|
|
120
89
|
}
|
|
121
90
|
|
|
122
91
|
export function createRscHostRenderStream(input: {
|
|
123
|
-
requestId?: string;
|
|
124
92
|
setPending: (pending: RscPending) => void;
|
|
125
93
|
deletePending: () => void;
|
|
126
94
|
sendRenderOrQueue: () => void;
|
|
@@ -185,17 +153,7 @@ export function createRscHostRenderStream(input: {
|
|
|
185
153
|
const settleStream = () => {
|
|
186
154
|
if (settled) return;
|
|
187
155
|
settled = true;
|
|
188
|
-
|
|
189
|
-
type: "stream",
|
|
190
|
-
requestId: input.requestId,
|
|
191
|
-
stream,
|
|
192
|
-
theme,
|
|
193
|
-
status,
|
|
194
|
-
trace,
|
|
195
|
-
lateControl,
|
|
196
|
-
cacheState,
|
|
197
|
-
cancel: cancelRender,
|
|
198
|
-
});
|
|
156
|
+
resolve({ type: "stream", stream, theme, status, trace, lateControl, cacheState, cancel: cancelRender });
|
|
199
157
|
};
|
|
200
158
|
input.setPending({
|
|
201
159
|
onMeta: (meta) => {
|
|
@@ -224,17 +182,16 @@ export function createRscHostRenderStream(input: {
|
|
|
224
182
|
settleStream();
|
|
225
183
|
controller.close();
|
|
226
184
|
},
|
|
227
|
-
onError: (
|
|
228
|
-
const error = createRscWorkerError(payload);
|
|
185
|
+
onError: (msg) => {
|
|
229
186
|
settleLateControl(null);
|
|
230
187
|
settleCacheState({ cacheable: false, reason: "error" });
|
|
231
188
|
cleanupAbortListener();
|
|
232
189
|
if (!settled) {
|
|
233
190
|
settled = true;
|
|
234
|
-
reject(
|
|
191
|
+
reject(new Error(msg));
|
|
235
192
|
return;
|
|
236
193
|
}
|
|
237
|
-
controller.error(
|
|
194
|
+
controller.error(new Error(msg));
|
|
238
195
|
},
|
|
239
196
|
onRedirect: (location, method, status) => {
|
|
240
197
|
settleLateControl(null);
|
|
@@ -305,7 +262,7 @@ type RscInMsg =
|
|
|
305
262
|
}
|
|
306
263
|
| { type: "not-found"; requestId: string }
|
|
307
264
|
| { type: "metrics"; metrics: AkanMetricsReport }
|
|
308
|
-
|
|
|
265
|
+
| { type: "error"; requestId: string; message: string; buildId?: number };
|
|
309
266
|
|
|
310
267
|
export interface RscWorkerReloadInput {
|
|
311
268
|
clientManifest: ClientManifest;
|
|
@@ -422,7 +379,7 @@ export class RscWorker {
|
|
|
422
379
|
this.#pending.set(requestId, {
|
|
423
380
|
onChunk: (data) => controller.enqueue(data),
|
|
424
381
|
onEnd: () => controller.close(),
|
|
425
|
-
onError: (
|
|
382
|
+
onError: (msg) => controller.error(new Error(msg)),
|
|
426
383
|
});
|
|
427
384
|
const send = () => {
|
|
428
385
|
|
|
@@ -455,7 +412,6 @@ export class RscWorker {
|
|
|
455
412
|
): Promise<RscRenderResult> {
|
|
456
413
|
const requestId = crypto.randomUUID();
|
|
457
414
|
return createRscHostRenderStream({
|
|
458
|
-
requestId,
|
|
459
415
|
setPending: (pending) => {
|
|
460
416
|
this.#pending.set(requestId, pending);
|
|
461
417
|
},
|
|
@@ -700,8 +656,8 @@ export class RscWorker {
|
|
|
700
656
|
case "error":
|
|
701
657
|
if (message.requestId === "__init__") {
|
|
702
658
|
|
|
703
|
-
if (!this.#readyResolved) this.#rejectReady(
|
|
704
|
-
else this.#logger.
|
|
659
|
+
if (!this.#readyResolved) this.#rejectReady(new Error(String(message.message)));
|
|
660
|
+
else this.#logger.error(`[rsc] worker init error on restart: ${message.message}`);
|
|
705
661
|
return;
|
|
706
662
|
}
|
|
707
663
|
if (message.requestId === "__reload__") {
|
|
@@ -709,12 +665,12 @@ export class RscWorker {
|
|
|
709
665
|
this.#pendingReload &&
|
|
710
666
|
(message.buildId === undefined || this.#pendingReload.targetBuildId === message.buildId)
|
|
711
667
|
) {
|
|
712
|
-
this.#pendingReload.reject(
|
|
668
|
+
this.#pendingReload.reject(new Error(String(message.message)));
|
|
713
669
|
this.#pendingReload = null;
|
|
714
670
|
}
|
|
715
671
|
return;
|
|
716
672
|
}
|
|
717
|
-
this.#resolvePending(message.requestId, (p) => p.onError(message));
|
|
673
|
+
this.#resolvePending(message.requestId, (p) => p.onError(String(message.message)));
|
|
718
674
|
return;
|
|
719
675
|
}
|
|
720
676
|
}
|
|
@@ -595,28 +595,11 @@ export class SsrFromRscRenderer {
|
|
|
595
595
|
: SsrFromRscRenderer.#clientBootstrap;
|
|
596
596
|
|
|
597
597
|
const renderHtml = async () => {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
throw error;
|
|
604
|
-
}
|
|
605
|
-
let stream: ReadableStream<Uint8Array> & { allReady: Promise<void> };
|
|
606
|
-
try {
|
|
607
|
-
stream = await renderToReadableStream(root, {
|
|
608
|
-
bootstrapScriptContent: bootstrap,
|
|
609
|
-
});
|
|
610
|
-
} catch (error) {
|
|
611
|
-
input.onError?.({ scope: "html-render", error });
|
|
612
|
-
throw error;
|
|
613
|
-
}
|
|
614
|
-
try {
|
|
615
|
-
await stream.allReady;
|
|
616
|
-
} catch (error) {
|
|
617
|
-
input.onError?.({ scope: "html-all-ready", error });
|
|
618
|
-
throw error;
|
|
619
|
-
}
|
|
598
|
+
const root = await thenable;
|
|
599
|
+
const stream = await renderToReadableStream(root, {
|
|
600
|
+
bootstrapScriptContent: bootstrap,
|
|
601
|
+
});
|
|
602
|
+
await stream.allReady;
|
|
620
603
|
return stream;
|
|
621
604
|
};
|
|
622
605
|
const requestContext = input.requestStore ?? input.request;
|
package/server/ssrTypes.ts
CHANGED
|
@@ -73,5 +73,4 @@ export interface SsrFromRscInput {
|
|
|
73
73
|
injectThemeInitScript?: boolean;
|
|
74
74
|
lateControl?: Promise<SsrLateRedirect | null>;
|
|
75
75
|
onCancel?: (reason?: unknown) => void;
|
|
76
|
-
onError?: (event: { scope: "flight-decode" | "html-render" | "html-all-ready"; error: unknown }) => void;
|
|
77
76
|
}
|
package/server/webRouter.ts
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
DEFAULT_AKAN_I18N,
|
|
7
7
|
getBasePathFromPathname,
|
|
8
8
|
Logger,
|
|
9
|
-
type LoggerMeta,
|
|
10
9
|
parseAkanI18nEnv,
|
|
11
10
|
} from "akanjs/common";
|
|
12
11
|
import { type AkanRequestStore, createRequestStore, parseCookieHeader } from "akanjs/fetch";
|
|
@@ -58,15 +57,6 @@ const RESERVED_BASE_PATHS = new Set(["admin"]);
|
|
|
58
57
|
const CLIENT_CLOSED_REQUEST_STATUS = 499;
|
|
59
58
|
export const DEFAULT_HTML_RESULT_CACHE_MAX_BODY_BYTES = 2 * 1024 * 1024;
|
|
60
59
|
|
|
61
|
-
interface SsrErrorLogMeta extends LoggerMeta {
|
|
62
|
-
errorId: string;
|
|
63
|
-
requestId?: string;
|
|
64
|
-
scope: string;
|
|
65
|
-
pathname?: string;
|
|
66
|
-
routeId?: string;
|
|
67
|
-
url?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
60
|
export function createRscRedirectResponse(
|
|
71
61
|
location: string,
|
|
72
62
|
method: RscRedirectMethod,
|
|
@@ -459,16 +449,10 @@ export class WebRouter {
|
|
|
459
449
|
return createRscRedirectResponse(result.location, result.method, result.status);
|
|
460
450
|
if (result.type === "not-found") return WebRouter.#rscNotFoundResponse();
|
|
461
451
|
if (result.status && result.status >= 500)
|
|
462
|
-
return this.#renderRscErrorResponse(
|
|
463
|
-
"__rsc",
|
|
464
|
-
new Error("RSC render returned an error status"),
|
|
465
|
-
req,
|
|
466
|
-
result.trace,
|
|
467
|
-
result.requestId,
|
|
468
|
-
);
|
|
452
|
+
return this.#renderRscErrorResponse("__rsc", "Internal Server Error");
|
|
469
453
|
return createRscNavigationStreamResponse(result);
|
|
470
454
|
} catch (err) {
|
|
471
|
-
return this.#renderRscErrorResponse("__rsc", err
|
|
455
|
+
return this.#renderRscErrorResponse("__rsc", err);
|
|
472
456
|
}
|
|
473
457
|
},
|
|
474
458
|
"/__rsc/manifest": () =>
|
|
@@ -546,8 +530,6 @@ export class WebRouter {
|
|
|
546
530
|
);
|
|
547
531
|
}
|
|
548
532
|
|
|
549
|
-
let activeRscRequestId: string | undefined;
|
|
550
|
-
let activeRscTrace: RscTraceMetadata | undefined;
|
|
551
533
|
try {
|
|
552
534
|
this.#requestStats.fullSsr += 1;
|
|
553
535
|
const manifest = await this.#ensureRoute(url);
|
|
@@ -566,10 +548,6 @@ export class WebRouter {
|
|
|
566
548
|
clientManifest: manifest.clientManifest,
|
|
567
549
|
signal: req.signal,
|
|
568
550
|
});
|
|
569
|
-
if (rscResult.type === "stream") {
|
|
570
|
-
activeRscRequestId = rscResult.requestId ?? rscResult.trace?.navId;
|
|
571
|
-
activeRscTrace = rscResult.trace;
|
|
572
|
-
}
|
|
573
551
|
if (rscResult.type === "redirect")
|
|
574
552
|
return Response.redirect(new URL(rscResult.location, url.origin), rscResult.status);
|
|
575
553
|
if (rscResult.type === "not-found") return this.#renderSystemNotFoundFallbackResponse(req, url);
|
|
@@ -596,22 +574,6 @@ export class WebRouter {
|
|
|
596
574
|
onCancel: (reason: unknown) => {
|
|
597
575
|
rscResult.cancel(reason);
|
|
598
576
|
},
|
|
599
|
-
onError: ({ scope, error }) => {
|
|
600
|
-
const meta = WebRouter.#createSsrErrorLogMeta(error, {
|
|
601
|
-
scope,
|
|
602
|
-
requestId: rscResult.requestId ?? rscResult.trace?.navId,
|
|
603
|
-
pathname: url.pathname,
|
|
604
|
-
routeId: rscResult.trace?.routeId,
|
|
605
|
-
url: url.href,
|
|
606
|
-
});
|
|
607
|
-
this.#logger.errorObject(
|
|
608
|
-
`[SSR] ${scope} failed requestId=${meta.requestId ?? "(none)"} pathname=${
|
|
609
|
-
meta.pathname ?? "(unknown)"
|
|
610
|
-
} route=${meta.routeId ?? "(unknown)"} errorId=${meta.errorId}`,
|
|
611
|
-
error,
|
|
612
|
-
meta,
|
|
613
|
-
);
|
|
614
|
-
},
|
|
615
577
|
});
|
|
616
578
|
const responseStatus = rscResult.status ?? 200;
|
|
617
579
|
const responseHeaders = WebRouter.#htmlResponseHeaders(responseStatus);
|
|
@@ -680,11 +642,7 @@ export class WebRouter {
|
|
|
680
642
|
headers,
|
|
681
643
|
});
|
|
682
644
|
} catch (err) {
|
|
683
|
-
return this.#renderErrorResponse(req,
|
|
684
|
-
requestId: activeRscRequestId,
|
|
685
|
-
routeId: activeRscTrace?.routeId,
|
|
686
|
-
pathname: activeRscTrace?.pathname ?? url.pathname,
|
|
687
|
-
});
|
|
645
|
+
return this.#renderErrorResponse(req, url.pathname, err);
|
|
688
646
|
}
|
|
689
647
|
},
|
|
690
648
|
};
|
|
@@ -839,110 +797,34 @@ export class WebRouter {
|
|
|
839
797
|
});
|
|
840
798
|
}
|
|
841
799
|
|
|
842
|
-
#renderErrorResponse(
|
|
843
|
-
req: Request,
|
|
844
|
-
scope: string,
|
|
845
|
-
err: unknown,
|
|
846
|
-
input: { requestId?: string; pathname?: string; routeId?: string } = {},
|
|
847
|
-
): Promise<Response> {
|
|
800
|
+
#renderErrorResponse(req: Request, scope: string, err: unknown): Promise<Response> {
|
|
848
801
|
if (WebRouter.#isExpectedRequestAbort(err)) return Promise.resolve(WebRouter.#clientClosedResponse());
|
|
849
802
|
const message = err instanceof Error ? err.message : String(err);
|
|
850
|
-
|
|
851
|
-
const meta = WebRouter.#createSsrErrorLogMeta(err, {
|
|
852
|
-
scope,
|
|
853
|
-
requestId: input.requestId,
|
|
854
|
-
pathname: input.pathname ?? url.pathname,
|
|
855
|
-
routeId: input.routeId,
|
|
856
|
-
url: url.href,
|
|
857
|
-
});
|
|
858
|
-
this.#logger.errorObject(
|
|
859
|
-
`[SSR] render failed requestId=${meta.requestId ?? "(none)"} scope=${meta.scope} pathname=${
|
|
860
|
-
meta.pathname ?? "(unknown)"
|
|
861
|
-
} route=${meta.routeId ?? "(unknown)"} errorId=${meta.errorId}`,
|
|
862
|
-
err,
|
|
863
|
-
meta,
|
|
864
|
-
);
|
|
803
|
+
this.#logger.error(`[SSR] render failed scope=${scope}: ${message}`);
|
|
865
804
|
this.#hub?.broadcast({ type: "error", message });
|
|
866
805
|
return createSystemPageResponse({
|
|
867
806
|
kind: "error",
|
|
868
807
|
method: req.method,
|
|
869
|
-
pathname:
|
|
870
|
-
lang: WebRouter.#getLocale(url.pathname, this.#artifact.i18n),
|
|
871
|
-
homeHref: this.#getSystemPageHomeHref(req, url.pathname),
|
|
872
|
-
stylesheetHref: this.#getStylesheetHref(req, url.pathname),
|
|
808
|
+
pathname: scope,
|
|
809
|
+
lang: WebRouter.#getLocale(new URL(req.url).pathname, this.#artifact.i18n),
|
|
810
|
+
homeHref: this.#getSystemPageHomeHref(req, new URL(req.url).pathname),
|
|
811
|
+
stylesheetHref: this.#getStylesheetHref(req, new URL(req.url).pathname),
|
|
873
812
|
showDetails: !this.#prodMode,
|
|
874
813
|
error: err,
|
|
875
|
-
}).then((response) => {
|
|
876
|
-
response.headers.set("X-Akan-Error-Id", meta.errorId);
|
|
877
|
-
if (meta.requestId) response.headers.set("X-Akan-Rsc-Nav-Id", meta.requestId);
|
|
878
|
-
return response;
|
|
879
814
|
});
|
|
880
815
|
}
|
|
881
816
|
|
|
882
|
-
#renderRscErrorResponse(
|
|
883
|
-
scope: string,
|
|
884
|
-
err: unknown,
|
|
885
|
-
req?: Request,
|
|
886
|
-
trace?: RscTraceMetadata,
|
|
887
|
-
requestId?: string,
|
|
888
|
-
): Response {
|
|
817
|
+
#renderRscErrorResponse(scope: string, err: unknown): Response {
|
|
889
818
|
if (WebRouter.#isExpectedRequestAbort(err)) return WebRouter.#clientClosedResponse();
|
|
890
819
|
const message = err instanceof Error ? err.message : String(err);
|
|
891
|
-
|
|
892
|
-
const meta = WebRouter.#createSsrErrorLogMeta(err, {
|
|
893
|
-
scope,
|
|
894
|
-
pathname: trace?.pathname ?? url?.pathname,
|
|
895
|
-
routeId: trace?.routeId,
|
|
896
|
-
requestId: trace?.navId ?? requestId,
|
|
897
|
-
url: url?.href,
|
|
898
|
-
});
|
|
899
|
-
this.#logger.errorObject(
|
|
900
|
-
`[SSR] render failed requestId=${meta.requestId ?? "(none)"} scope=${meta.scope} pathname=${
|
|
901
|
-
meta.pathname ?? "(unknown)"
|
|
902
|
-
} route=${meta.routeId ?? "(unknown)"} errorId=${meta.errorId}`,
|
|
903
|
-
err,
|
|
904
|
-
meta,
|
|
905
|
-
);
|
|
820
|
+
this.#logger.error(`[SSR] render failed scope=${scope}: ${message}`);
|
|
906
821
|
this.#hub?.broadcast({ type: "error", message });
|
|
907
822
|
return new Response("Internal Server Error", {
|
|
908
823
|
status: 500,
|
|
909
|
-
headers: {
|
|
910
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
911
|
-
"Cache-Control": "no-store",
|
|
912
|
-
"X-Akan-Error-Id": meta.errorId,
|
|
913
|
-
...(meta.requestId ? { "X-Akan-Rsc-Nav-Id": meta.requestId } : {}),
|
|
914
|
-
},
|
|
824
|
+
headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store" },
|
|
915
825
|
});
|
|
916
826
|
}
|
|
917
827
|
|
|
918
|
-
static #createSsrErrorLogMeta(
|
|
919
|
-
error: unknown,
|
|
920
|
-
input: { scope: string; requestId?: string; pathname?: string; routeId?: string; url?: string },
|
|
921
|
-
): SsrErrorLogMeta {
|
|
922
|
-
const requestId = WebRouter.#stringErrorProp(error, "requestId") ?? input.requestId;
|
|
923
|
-
const scope = WebRouter.#stringErrorProp(error, "scope") ?? input.scope;
|
|
924
|
-
const pathname = WebRouter.#stringErrorProp(error, "pathname") ?? input.pathname;
|
|
925
|
-
const routeId = WebRouter.#stringErrorProp(error, "routeId") ?? input.routeId;
|
|
926
|
-
const errorId =
|
|
927
|
-
WebRouter.#stringErrorProp(error, "errorId") ??
|
|
928
|
-
WebRouter.#stringErrorProp(error, "digest") ??
|
|
929
|
-
Logger.createErrorId({ requestId, scope });
|
|
930
|
-
return {
|
|
931
|
-
errorId,
|
|
932
|
-
requestId,
|
|
933
|
-
scope,
|
|
934
|
-
pathname,
|
|
935
|
-
routeId,
|
|
936
|
-
url: input.url,
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
static #stringErrorProp(error: unknown, key: string): string | undefined {
|
|
941
|
-
if (typeof error !== "object" || error === null || !(key in error)) return undefined;
|
|
942
|
-
const value = (error as Record<string, unknown>)[key];
|
|
943
|
-
return typeof value === "string" && value ? value : undefined;
|
|
944
|
-
}
|
|
945
|
-
|
|
946
828
|
static #clientClosedResponse(): Response {
|
|
947
829
|
return new Response(null, {
|
|
948
830
|
status: CLIENT_CLOSED_REQUEST_STATUS,
|
package/types/common/Logger.d.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
declare const logLevels: readonly ["trace", "verbose", "debug", "log", "info", "warn", "error"];
|
|
2
2
|
export type LogLevel = (typeof logLevels)[number];
|
|
3
|
-
export type LoggerMeta = Record<string, unknown>;
|
|
4
|
-
export interface LoggerSerializedError {
|
|
5
|
-
name?: string;
|
|
6
|
-
message: string;
|
|
7
|
-
stack?: string;
|
|
8
|
-
cause?: LoggerSerializedError | string;
|
|
9
|
-
digest?: string;
|
|
10
|
-
code?: string | number;
|
|
11
|
-
status?: number;
|
|
12
|
-
}
|
|
13
3
|
export interface LoggerSinkEntry {
|
|
14
4
|
stream: "stdout" | "stderr";
|
|
15
5
|
level?: LogLevel;
|
|
16
6
|
message: string;
|
|
17
7
|
plainMessage: string;
|
|
18
|
-
meta?: LoggerMeta;
|
|
19
8
|
}
|
|
20
9
|
export type LoggerSink = (entry: LoggerSinkEntry) => void | Promise<void>;
|
|
21
10
|
/** Log-level aware logger used by Akan runtime, CLI, and application services. */
|
|
@@ -37,7 +26,6 @@ export declare class Logger {
|
|
|
37
26
|
info(msg: string, context?: string, name?: string): void;
|
|
38
27
|
warn(msg: string, context?: string, name?: string): void;
|
|
39
28
|
error(msg: string, context?: string, name?: string): void;
|
|
40
|
-
errorObject(msg: string, error: unknown, meta?: LoggerMeta, context?: string, name?: string): void;
|
|
41
29
|
raw(msg: string, method?: "console" | "process"): void;
|
|
42
30
|
rawLog(msg: string, method?: "console" | "process"): void;
|
|
43
31
|
static trace(msg: string, context?: string, name?: string): void;
|
|
@@ -47,14 +35,6 @@ export declare class Logger {
|
|
|
47
35
|
static info(msg: string, context?: string, name?: string): void;
|
|
48
36
|
static warn(msg: string, context?: string, name?: string): void;
|
|
49
37
|
static error(msg: string, context?: string, name?: string): void;
|
|
50
|
-
static errorObject(msg: string, error: unknown, meta?: LoggerMeta, context?: string, name?: string): void;
|
|
51
|
-
static createErrorId(input?: {
|
|
52
|
-
requestId?: string;
|
|
53
|
-
scope?: string;
|
|
54
|
-
sequence?: string | number;
|
|
55
|
-
}): string;
|
|
56
|
-
static serializeError(error: unknown): LoggerSerializedError;
|
|
57
|
-
static formatError(error: unknown): string;
|
|
58
38
|
static rawLog(msg?: string, method?: "console" | "process", outputStream?: "log" | "error"): void;
|
|
59
39
|
static raw(msg?: string, method?: "console" | "process", outputStream?: "log" | "error"): void;
|
|
60
40
|
}
|
package/types/common/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { isPhoneNumber } from "./isPhoneNumber.d.ts";
|
|
|
13
13
|
export { isQueryEqual } from "./isQueryEqual.d.ts";
|
|
14
14
|
export { isValidDate } from "./isValidDate.d.ts";
|
|
15
15
|
export { decodeJwtPayload } from "./jwtDecode.d.ts";
|
|
16
|
-
export { Logger, type
|
|
16
|
+
export { Logger, type LoggerSink, type LoggerSinkEntry, type LogLevel } from "./Logger.d.ts";
|
|
17
17
|
export { type AkanI18nConfig, type AkanI18nConfigInput, DEFAULT_AKAN_I18N, parseAkanI18nEnv, resolveAkanI18nConfig, } from "./localeConfig.d.ts";
|
|
18
18
|
export { lowerlize } from "./lowerlize.d.ts";
|
|
19
19
|
export { mergeVersion } from "./mergeVersion.d.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AkanI18nConfig
|
|
1
|
+
import { type AkanI18nConfig } from "akanjs/common";
|
|
2
2
|
import type { AkanTheme } from "akanjs/fetch";
|
|
3
3
|
import type { AkanMetricsReport } from "akanjs/service";
|
|
4
4
|
import type { ClientManifest } from "./artifact.d.ts";
|
|
@@ -8,7 +8,7 @@ import type { BaseBuildArtifact, CssAsset } from "./types.d.ts";
|
|
|
8
8
|
export interface RscPending {
|
|
9
9
|
onChunk: (data: Uint8Array) => void;
|
|
10
10
|
onEnd: () => void;
|
|
11
|
-
onError: (
|
|
11
|
+
onError: (message: string) => void;
|
|
12
12
|
onMeta?: (meta: {
|
|
13
13
|
theme?: AkanTheme;
|
|
14
14
|
status?: number;
|
|
@@ -21,18 +21,6 @@ export interface RscPending {
|
|
|
21
21
|
}
|
|
22
22
|
export type RscRedirectMethod = "replace" | "push";
|
|
23
23
|
export type RscRedirectStatus = 303 | 307 | 308;
|
|
24
|
-
export interface RscWorkerErrorPayload {
|
|
25
|
-
message: string;
|
|
26
|
-
name?: string;
|
|
27
|
-
stack?: string;
|
|
28
|
-
errorId?: string;
|
|
29
|
-
digest?: string;
|
|
30
|
-
requestId?: string;
|
|
31
|
-
scope?: string;
|
|
32
|
-
pathname?: string;
|
|
33
|
-
routeId?: string;
|
|
34
|
-
meta?: LoggerMeta;
|
|
35
|
-
}
|
|
36
24
|
export interface RscWorkerInvalidateCacheMessage {
|
|
37
25
|
type: "invalidate-cache";
|
|
38
26
|
reason?: string;
|
|
@@ -41,7 +29,6 @@ export interface RscWorkerInvalidateCacheMessage {
|
|
|
41
29
|
}
|
|
42
30
|
export type RscRenderResult = {
|
|
43
31
|
type: "stream";
|
|
44
|
-
requestId?: string;
|
|
45
32
|
stream: ReadableStream<Uint8Array>;
|
|
46
33
|
theme?: AkanTheme;
|
|
47
34
|
status?: number;
|
|
@@ -60,11 +47,9 @@ export type RscRenderResult = {
|
|
|
60
47
|
export declare function getRscHostMaxPendingChunks(value?: string | undefined): number;
|
|
61
48
|
export declare function nextRscHostPendingChunkCount(currentPendingChunks: number, desiredSize: number | null): number;
|
|
62
49
|
export declare function isRscHostPendingChunkOverflow(pendingChunks: number, maxPendingChunks: number): boolean;
|
|
63
|
-
export declare function createRscWorkerError(input: string | RscWorkerErrorPayload): Error;
|
|
64
50
|
export declare function createIdempotentRscRenderCancel(onCancel: (reason?: unknown) => void): (reason?: unknown) => void;
|
|
65
51
|
export declare function createRscWorkerInvalidateCacheMessage(invalidation?: string | RouteCacheInvalidation): RscWorkerInvalidateCacheMessage;
|
|
66
52
|
export declare function createRscHostRenderStream(input: {
|
|
67
|
-
requestId?: string;
|
|
68
53
|
setPending: (pending: RscPending) => void;
|
|
69
54
|
deletePending: () => void;
|
|
70
55
|
sendRenderOrQueue: () => void;
|
|
@@ -70,8 +70,4 @@ export interface SsrFromRscInput {
|
|
|
70
70
|
injectThemeInitScript?: boolean;
|
|
71
71
|
lateControl?: Promise<SsrLateRedirect | null>;
|
|
72
72
|
onCancel?: (reason?: unknown) => void;
|
|
73
|
-
onError?: (event: {
|
|
74
|
-
scope: "flight-decode" | "html-render" | "html-all-ready";
|
|
75
|
-
error: unknown;
|
|
76
|
-
}) => void;
|
|
77
73
|
}
|