@farm.js/plugin 0.1.0-beta.10 → 0.1.0-beta.13
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/dist/api/index.d.ts +42 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +493 -0
- package/dist/context/index.d.ts +61 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +75 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/middleware/index.d.ts +97 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +469 -0
- package/dist/observability/index.d.ts +190 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +399 -0
- package/dist/rsc/automatic-optimized-boundary.d.ts +11 -0
- package/dist/rsc/automatic-optimized-boundary.d.ts.map +1 -0
- package/dist/rsc/automatic-optimized-boundary.js +162 -0
- package/dist/rsc/build-paths.d.ts +3 -0
- package/dist/rsc/build-paths.d.ts.map +1 -0
- package/dist/rsc/build-paths.js +8 -0
- package/dist/rsc/compatibility.d.ts +8 -0
- package/dist/rsc/compatibility.d.ts.map +1 -0
- package/dist/rsc/compatibility.js +46 -0
- package/dist/rsc/entries/client.d.ts +14 -0
- package/dist/rsc/entries/client.d.ts.map +1 -0
- package/dist/rsc/entries/client.js +283 -0
- package/dist/rsc/entries/rsc.d.ts +13 -0
- package/dist/rsc/entries/rsc.d.ts.map +1 -0
- package/dist/rsc/entries/rsc.js +932 -0
- package/dist/rsc/entries/ssr.d.ts +13 -0
- package/dist/rsc/entries/ssr.d.ts.map +1 -0
- package/dist/rsc/entries/ssr.js +245 -0
- package/dist/rsc/index.d.ts +87 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +1389 -0
- package/dist/rsc/nitro-build.d.ts +36 -0
- package/dist/rsc/nitro-build.d.ts.map +1 -0
- package/dist/rsc/nitro-build.js +396 -0
- package/dist/rsc/optimized-boundary.d.ts +29 -0
- package/dist/rsc/optimized-boundary.d.ts.map +1 -0
- package/dist/rsc/optimized-boundary.js +243 -0
- package/dist/rsc/server-fn-transform.d.ts +6 -0
- package/dist/rsc/server-fn-transform.d.ts.map +1 -0
- package/dist/rsc/server-fn-transform.js +152 -0
- package/dist/rsc/types.d.ts +123 -0
- package/dist/rsc/types.d.ts.map +1 -0
- package/dist/rsc/types.js +1 -0
- package/dist/rsc/vite-plugin-nitro.d.ts +33 -0
- package/dist/rsc/vite-plugin-nitro.d.ts.map +1 -0
- package/dist/rsc/vite-plugin-nitro.js +163 -0
- package/package.json +3 -3
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
export type IncidentSeverity = "low" | "medium" | "high" | "critical";
|
|
3
|
+
export type ObservabilitySignalKind = "request.completed" | "api.response" | "render.completed" | "runtime.error" | "build.result" | "nitro.build";
|
|
4
|
+
export interface ObservabilitySignal {
|
|
5
|
+
id: string;
|
|
6
|
+
kind: ObservabilitySignalKind;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
service: string;
|
|
9
|
+
environment: string;
|
|
10
|
+
tags: Record<string, string>;
|
|
11
|
+
request?: {
|
|
12
|
+
method: string;
|
|
13
|
+
pathname: string;
|
|
14
|
+
statusCode: number;
|
|
15
|
+
durationMs: number;
|
|
16
|
+
requestId: string;
|
|
17
|
+
};
|
|
18
|
+
api?: {
|
|
19
|
+
method: string;
|
|
20
|
+
pathname: string;
|
|
21
|
+
status: number;
|
|
22
|
+
};
|
|
23
|
+
render?: {
|
|
24
|
+
pathname: string;
|
|
25
|
+
routePattern: string | null;
|
|
26
|
+
};
|
|
27
|
+
error?: {
|
|
28
|
+
phase: string;
|
|
29
|
+
message: string;
|
|
30
|
+
name?: string;
|
|
31
|
+
};
|
|
32
|
+
build?: {
|
|
33
|
+
success: boolean;
|
|
34
|
+
preset: string;
|
|
35
|
+
root: string;
|
|
36
|
+
outputDir?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface ObservabilityIncident {
|
|
40
|
+
id: string;
|
|
41
|
+
kind: string;
|
|
42
|
+
title: string;
|
|
43
|
+
severity: IncidentSeverity;
|
|
44
|
+
fingerprint: string;
|
|
45
|
+
detectedAt: number;
|
|
46
|
+
signalId: string;
|
|
47
|
+
summary?: string;
|
|
48
|
+
metadata?: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
export interface ObservabilityDetectionContext {
|
|
51
|
+
now: () => number;
|
|
52
|
+
}
|
|
53
|
+
export interface ObservabilityRule {
|
|
54
|
+
id: string;
|
|
55
|
+
severity?: IncidentSeverity;
|
|
56
|
+
when: (signal: ObservabilitySignal, context: ObservabilityDetectionContext) => boolean | Promise<boolean>;
|
|
57
|
+
buildIncident?: (signal: ObservabilitySignal, context: ObservabilityDetectionContext) => Partial<Omit<ObservabilityIncident, "id" | "detectedAt" | "signalId">> | null | undefined | Promise<Partial<Omit<ObservabilityIncident, "id" | "detectedAt" | "signalId">> | null | undefined>;
|
|
58
|
+
}
|
|
59
|
+
export interface ObservabilityFixResult {
|
|
60
|
+
summary: string;
|
|
61
|
+
branch?: string;
|
|
62
|
+
commitSha?: string;
|
|
63
|
+
metadata?: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
export interface ObservabilityPipelineContext {
|
|
66
|
+
signal: ObservabilitySignal;
|
|
67
|
+
incident: ObservabilityIncident;
|
|
68
|
+
/**
|
|
69
|
+
* @deprecated Use state["fix"] or step result values in `state`.
|
|
70
|
+
*/
|
|
71
|
+
fixResult?: ObservabilityFixResult | null;
|
|
72
|
+
state: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
export type ObservabilityAction = (context: ObservabilityPipelineContext) => unknown | Promise<unknown>;
|
|
75
|
+
export type ObservabilityPipelineStepName = string;
|
|
76
|
+
export interface ObservabilityWorkflowStepEvent {
|
|
77
|
+
step: string;
|
|
78
|
+
context: ObservabilityPipelineContext;
|
|
79
|
+
}
|
|
80
|
+
export interface ObservabilityWorkflowStepCompleteEvent extends ObservabilityWorkflowStepEvent {
|
|
81
|
+
result: unknown;
|
|
82
|
+
}
|
|
83
|
+
export interface ObservabilityWorkflowStepErrorEvent extends ObservabilityWorkflowStepEvent {
|
|
84
|
+
error: unknown;
|
|
85
|
+
}
|
|
86
|
+
export interface ObservabilityWorkflowErrorEvent {
|
|
87
|
+
error: unknown;
|
|
88
|
+
context: ObservabilityPipelineContext;
|
|
89
|
+
}
|
|
90
|
+
export interface ObservabilityWorkflowCallbacks {
|
|
91
|
+
onIncident?: (context: ObservabilityPipelineContext) => void | Promise<void>;
|
|
92
|
+
onPipelineStart?: (context: ObservabilityPipelineContext) => void | Promise<void>;
|
|
93
|
+
onPipelineComplete?: (context: ObservabilityPipelineContext) => void | Promise<void>;
|
|
94
|
+
onPipelineError?: (event: ObservabilityWorkflowErrorEvent) => void | Promise<void>;
|
|
95
|
+
onStepStart?: (event: ObservabilityWorkflowStepEvent) => void | Promise<void>;
|
|
96
|
+
onStepComplete?: (event: ObservabilityWorkflowStepCompleteEvent) => void | Promise<void>;
|
|
97
|
+
onStepError?: (event: ObservabilityWorkflowStepErrorEvent) => void | Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
export interface ObservabilityWorkflowOptions {
|
|
100
|
+
pipeline?: ObservabilityPipelineStepName[];
|
|
101
|
+
actions?: Record<string, ObservabilityAction>;
|
|
102
|
+
/**
|
|
103
|
+
* Callback lifecycle for side effects around pipeline execution.
|
|
104
|
+
*/
|
|
105
|
+
callbacks?: ObservabilityWorkflowCallbacks;
|
|
106
|
+
/**
|
|
107
|
+
* Continue pipeline execution when a step fails.
|
|
108
|
+
* Defaults to true to avoid affecting request handling.
|
|
109
|
+
*/
|
|
110
|
+
continueOnStepError?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* @deprecated Use `callbacks.onIncident`.
|
|
113
|
+
*/
|
|
114
|
+
onIncident?: (context: ObservabilityPipelineContext) => void | Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* @deprecated Use `actions.fix` and include "fix" in `pipeline`.
|
|
117
|
+
*/
|
|
118
|
+
runFix?: (context: ObservabilityPipelineContext) => ObservabilityFixResult | null | undefined | Promise<ObservabilityFixResult | null | undefined>;
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Use `actions.pullRequest` and include "pullRequest" in `pipeline`.
|
|
121
|
+
*/
|
|
122
|
+
openPullRequest?: (context: ObservabilityPipelineContext) => void | Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
export interface ObservabilityDetectionOptions {
|
|
125
|
+
enabled?: boolean;
|
|
126
|
+
dedupeWindowMs?: number;
|
|
127
|
+
rules?: ObservabilityRule[];
|
|
128
|
+
mapSignalToIncident?: (signal: ObservabilitySignal, context: ObservabilityDetectionContext) => ObservabilityIncident | null | undefined | Promise<ObservabilityIncident | null | undefined>;
|
|
129
|
+
}
|
|
130
|
+
export interface ObservabilityTelemetryOptions {
|
|
131
|
+
slowRequestMs?: number;
|
|
132
|
+
logLifecycle?: boolean;
|
|
133
|
+
annotateHtml?: boolean;
|
|
134
|
+
}
|
|
135
|
+
export interface ObservabilityPluginOptions {
|
|
136
|
+
service?: string;
|
|
137
|
+
environment?: string;
|
|
138
|
+
tags?: Record<string, string>;
|
|
139
|
+
telemetry?: ObservabilityTelemetryOptions;
|
|
140
|
+
detection?: ObservabilityDetectionOptions;
|
|
141
|
+
workflow?: ObservabilityWorkflowOptions;
|
|
142
|
+
/**
|
|
143
|
+
* @deprecated Use telemetry.slowRequestMs instead.
|
|
144
|
+
*/
|
|
145
|
+
slowRequestMs?: number;
|
|
146
|
+
/**
|
|
147
|
+
* @deprecated Use telemetry.logLifecycle instead.
|
|
148
|
+
*/
|
|
149
|
+
logLifecycle?: boolean;
|
|
150
|
+
}
|
|
151
|
+
interface ObservabilityPlugin {
|
|
152
|
+
name: string;
|
|
153
|
+
enforce?: "pre" | "post";
|
|
154
|
+
init?: () => void;
|
|
155
|
+
ready?: () => void;
|
|
156
|
+
beforeRequest?: (req: IncomingMessage, res: ServerResponse, context?: unknown) => void;
|
|
157
|
+
afterResponse?: (req: IncomingMessage, res: ServerResponse, context?: unknown) => void | Promise<void>;
|
|
158
|
+
afterApiHandler?: (response: Response, api: {
|
|
159
|
+
method: string;
|
|
160
|
+
pathname: string;
|
|
161
|
+
}, context?: unknown) => Response | Promise<Response>;
|
|
162
|
+
afterRender?: (html: string, render: {
|
|
163
|
+
pathname: string;
|
|
164
|
+
routePattern: string | null;
|
|
165
|
+
}, context?: unknown) => string;
|
|
166
|
+
onError?: (error: {
|
|
167
|
+
phase: string;
|
|
168
|
+
error: unknown;
|
|
169
|
+
}, context?: unknown) => void | Promise<void>;
|
|
170
|
+
hmrUpdate?: (update: {
|
|
171
|
+
file: string;
|
|
172
|
+
modules: string[];
|
|
173
|
+
}, context?: unknown) => void;
|
|
174
|
+
afterBundle?: (result: {
|
|
175
|
+
success: boolean;
|
|
176
|
+
preset: string;
|
|
177
|
+
root: string;
|
|
178
|
+
}, context?: unknown) => void | Promise<void>;
|
|
179
|
+
afterNitroBuild?: (payload: {
|
|
180
|
+
preset: string;
|
|
181
|
+
outputDir: string;
|
|
182
|
+
root?: string;
|
|
183
|
+
}, context?: unknown) => void | Promise<void>;
|
|
184
|
+
shutdown?: (payload: {
|
|
185
|
+
reason: string;
|
|
186
|
+
}, context?: unknown) => void;
|
|
187
|
+
}
|
|
188
|
+
export declare function observabilityPlugin(options?: ObservabilityPluginOptions): ObservabilityPlugin;
|
|
189
|
+
export {};
|
|
190
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
function errorMessage(error) {
|
|
2
|
+
if (error instanceof Error)
|
|
3
|
+
return error.message;
|
|
4
|
+
return String(error);
|
|
5
|
+
}
|
|
6
|
+
function stableFingerprint(parts) {
|
|
7
|
+
return parts
|
|
8
|
+
.map((part) => (part === undefined || part === null ? "na" : String(part).trim()))
|
|
9
|
+
.join(":");
|
|
10
|
+
}
|
|
11
|
+
function toPositiveInt(value, fallback) {
|
|
12
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
13
|
+
return fallback;
|
|
14
|
+
return Math.max(1, Math.floor(value));
|
|
15
|
+
}
|
|
16
|
+
export function observabilityPlugin(options = {}) {
|
|
17
|
+
const now = () => Date.now();
|
|
18
|
+
const service = options.service || process.env.FARM_SERVICE || "farm-app";
|
|
19
|
+
const environment = options.environment || process.env.NODE_ENV || "development";
|
|
20
|
+
const tags = options.tags || {};
|
|
21
|
+
const telemetry = options.telemetry || {};
|
|
22
|
+
const detection = options.detection || {};
|
|
23
|
+
const workflow = options.workflow || {};
|
|
24
|
+
const slowRequestMs = toPositiveInt(telemetry.slowRequestMs ?? options.slowRequestMs, 300);
|
|
25
|
+
const dedupeWindowMs = toPositiveInt(detection.dedupeWindowMs, 60_000);
|
|
26
|
+
const logLifecycle = telemetry.logLifecycle ?? options.logLifecycle ?? true;
|
|
27
|
+
const annotateHtml = telemetry.annotateHtml ?? true;
|
|
28
|
+
const detectionEnabled = detection.enabled ?? true;
|
|
29
|
+
const continueOnStepError = workflow.continueOnStepError ?? true;
|
|
30
|
+
const requestStarts = new WeakMap();
|
|
31
|
+
const recentIncidentsByFingerprint = new Map();
|
|
32
|
+
let signalCounter = 0;
|
|
33
|
+
let incidentCounter = 0;
|
|
34
|
+
const nextSignalId = () => `sig_${now()}_${(signalCounter++).toString(36)}`;
|
|
35
|
+
const nextIncidentId = () => `inc_${now()}_${(incidentCounter++).toString(36)}`;
|
|
36
|
+
const detectionContext = { now };
|
|
37
|
+
const createDefaultIncident = (signal) => {
|
|
38
|
+
if (signal.kind === "runtime.error" && signal.error) {
|
|
39
|
+
return {
|
|
40
|
+
kind: "runtime-error",
|
|
41
|
+
title: `Runtime error in ${signal.error.phase}`,
|
|
42
|
+
severity: "critical",
|
|
43
|
+
fingerprint: stableFingerprint(["runtime-error", signal.error.phase, signal.error.message]),
|
|
44
|
+
summary: signal.error.message,
|
|
45
|
+
metadata: { phase: signal.error.phase, name: signal.error.name },
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (signal.kind === "request.completed" && signal.request) {
|
|
49
|
+
if (signal.request.statusCode >= 500) {
|
|
50
|
+
return {
|
|
51
|
+
kind: "request-failure",
|
|
52
|
+
title: `Request failure ${signal.request.method} ${signal.request.pathname}`,
|
|
53
|
+
severity: "high",
|
|
54
|
+
fingerprint: stableFingerprint([
|
|
55
|
+
"request-failure",
|
|
56
|
+
signal.request.method,
|
|
57
|
+
signal.request.pathname,
|
|
58
|
+
signal.request.statusCode,
|
|
59
|
+
]),
|
|
60
|
+
summary: `Request returned ${signal.request.statusCode}`,
|
|
61
|
+
metadata: {
|
|
62
|
+
method: signal.request.method,
|
|
63
|
+
pathname: signal.request.pathname,
|
|
64
|
+
statusCode: signal.request.statusCode,
|
|
65
|
+
durationMs: signal.request.durationMs,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (signal.request.durationMs >= slowRequestMs) {
|
|
70
|
+
return {
|
|
71
|
+
kind: "slow-request",
|
|
72
|
+
title: `Slow request ${signal.request.method} ${signal.request.pathname}`,
|
|
73
|
+
severity: "medium",
|
|
74
|
+
fingerprint: stableFingerprint([
|
|
75
|
+
"slow-request",
|
|
76
|
+
signal.request.method,
|
|
77
|
+
signal.request.pathname,
|
|
78
|
+
]),
|
|
79
|
+
summary: `Request took ${signal.request.durationMs}ms`,
|
|
80
|
+
metadata: {
|
|
81
|
+
method: signal.request.method,
|
|
82
|
+
pathname: signal.request.pathname,
|
|
83
|
+
statusCode: signal.request.statusCode,
|
|
84
|
+
durationMs: signal.request.durationMs,
|
|
85
|
+
thresholdMs: slowRequestMs,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (signal.kind === "api.response" && signal.api && signal.api.status >= 500) {
|
|
91
|
+
return {
|
|
92
|
+
kind: "api-failure",
|
|
93
|
+
title: `API failure ${signal.api.method} ${signal.api.pathname}`,
|
|
94
|
+
severity: "high",
|
|
95
|
+
fingerprint: stableFingerprint([
|
|
96
|
+
"api-failure",
|
|
97
|
+
signal.api.method,
|
|
98
|
+
signal.api.pathname,
|
|
99
|
+
signal.api.status,
|
|
100
|
+
]),
|
|
101
|
+
summary: `API returned ${signal.api.status}`,
|
|
102
|
+
metadata: {
|
|
103
|
+
method: signal.api.method,
|
|
104
|
+
pathname: signal.api.pathname,
|
|
105
|
+
status: signal.api.status,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
};
|
|
111
|
+
const shouldDedupe = (fingerprint) => {
|
|
112
|
+
const seenAt = recentIncidentsByFingerprint.get(fingerprint);
|
|
113
|
+
if (seenAt && now() - seenAt < dedupeWindowMs) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
recentIncidentsByFingerprint.set(fingerprint, now());
|
|
117
|
+
return false;
|
|
118
|
+
};
|
|
119
|
+
const applyRules = async (signal) => {
|
|
120
|
+
const rules = detection.rules || [];
|
|
121
|
+
for (const rule of rules) {
|
|
122
|
+
const matched = await rule.when(signal, detectionContext);
|
|
123
|
+
if (!matched)
|
|
124
|
+
continue;
|
|
125
|
+
const partial = (await rule.buildIncident?.(signal, detectionContext)) || {};
|
|
126
|
+
const defaultIncident = createDefaultIncident(signal);
|
|
127
|
+
return {
|
|
128
|
+
kind: partial.kind || defaultIncident?.kind || `rule:${rule.id}`,
|
|
129
|
+
title: partial.title || defaultIncident?.title || `Incident from rule ${rule.id}`,
|
|
130
|
+
severity: partial.severity || rule.severity || defaultIncident?.severity || "high",
|
|
131
|
+
fingerprint: partial.fingerprint ||
|
|
132
|
+
defaultIncident?.fingerprint ||
|
|
133
|
+
stableFingerprint(["rule", rule.id, signal.kind]),
|
|
134
|
+
summary: partial.summary || defaultIncident?.summary,
|
|
135
|
+
metadata: {
|
|
136
|
+
...defaultIncident?.metadata,
|
|
137
|
+
...partial.metadata,
|
|
138
|
+
ruleId: rule.id,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
};
|
|
144
|
+
const resolveIncident = async (signal) => {
|
|
145
|
+
const mapped = await detection.mapSignalToIncident?.(signal, detectionContext);
|
|
146
|
+
if (mapped) {
|
|
147
|
+
return {
|
|
148
|
+
id: mapped.id || nextIncidentId(),
|
|
149
|
+
kind: mapped.kind || "mapped-incident",
|
|
150
|
+
title: mapped.title || "Mapped incident",
|
|
151
|
+
severity: mapped.severity || "high",
|
|
152
|
+
fingerprint: mapped.fingerprint || stableFingerprint(["mapped-incident", mapped.kind, signal.kind]),
|
|
153
|
+
detectedAt: mapped.detectedAt || now(),
|
|
154
|
+
signalId: mapped.signalId || signal.id,
|
|
155
|
+
summary: mapped.summary,
|
|
156
|
+
metadata: mapped.metadata,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const byRule = await applyRules(signal);
|
|
160
|
+
const chosen = byRule || createDefaultIncident(signal);
|
|
161
|
+
if (!chosen)
|
|
162
|
+
return null;
|
|
163
|
+
return {
|
|
164
|
+
id: nextIncidentId(),
|
|
165
|
+
kind: chosen.kind,
|
|
166
|
+
title: chosen.title,
|
|
167
|
+
severity: chosen.severity,
|
|
168
|
+
fingerprint: chosen.fingerprint,
|
|
169
|
+
detectedAt: now(),
|
|
170
|
+
signalId: signal.id,
|
|
171
|
+
summary: chosen.summary,
|
|
172
|
+
metadata: chosen.metadata,
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
const runWorkflow = async (signal, incident) => {
|
|
176
|
+
const context = {
|
|
177
|
+
signal,
|
|
178
|
+
incident,
|
|
179
|
+
state: {},
|
|
180
|
+
fixResult: null,
|
|
181
|
+
};
|
|
182
|
+
const callbacks = workflow.callbacks || {};
|
|
183
|
+
const userActions = workflow.actions || {};
|
|
184
|
+
const legacyOnIncident = workflow.onIncident;
|
|
185
|
+
const builtInActions = {
|
|
186
|
+
notify: async (ctx) => {
|
|
187
|
+
const onIncident = callbacks.onIncident || legacyOnIncident;
|
|
188
|
+
if (onIncident) {
|
|
189
|
+
await onIncident(ctx);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
console.warn(`[obs] incident detected kind=${ctx.incident.kind} severity=${ctx.incident.severity} id=${ctx.incident.id} title="${ctx.incident.title}"`);
|
|
193
|
+
},
|
|
194
|
+
log: async (ctx) => {
|
|
195
|
+
console.log(`[obs] pipeline incident=${ctx.incident.id} kind=${ctx.incident.kind} severity=${ctx.incident.severity}`);
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
// Backward-compatibility shims. Prefer defining these steps via workflow.actions.
|
|
199
|
+
const legacyActions = {};
|
|
200
|
+
if (workflow.runFix) {
|
|
201
|
+
legacyActions.fix = async (ctx) => {
|
|
202
|
+
const result = (await workflow.runFix?.(ctx)) || null;
|
|
203
|
+
ctx.fixResult = result;
|
|
204
|
+
return result;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (workflow.openPullRequest) {
|
|
208
|
+
legacyActions.pullRequest = async (ctx) => {
|
|
209
|
+
if (!ctx.fixResult)
|
|
210
|
+
return null;
|
|
211
|
+
await workflow.openPullRequest?.(ctx);
|
|
212
|
+
return ctx.fixResult;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const actionRegistry = {
|
|
216
|
+
...builtInActions,
|
|
217
|
+
...legacyActions,
|
|
218
|
+
...userActions,
|
|
219
|
+
};
|
|
220
|
+
const hasFixPath = typeof workflow.runFix === "function";
|
|
221
|
+
const hasPrPath = typeof workflow.openPullRequest === "function";
|
|
222
|
+
const pipeline = workflow.pipeline && workflow.pipeline.length > 0
|
|
223
|
+
? workflow.pipeline
|
|
224
|
+
: hasFixPath
|
|
225
|
+
? hasPrPath
|
|
226
|
+
? ["notify", "fix", "pullRequest"]
|
|
227
|
+
: ["notify", "fix"]
|
|
228
|
+
: ["notify"];
|
|
229
|
+
try {
|
|
230
|
+
await callbacks.onPipelineStart?.(context);
|
|
231
|
+
for (const step of pipeline) {
|
|
232
|
+
const action = actionRegistry[step];
|
|
233
|
+
if (!action) {
|
|
234
|
+
const message = `[obs] pipeline step "${step}" is not registered`;
|
|
235
|
+
if (!continueOnStepError)
|
|
236
|
+
throw new Error(message);
|
|
237
|
+
console.warn(message);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
await callbacks.onStepStart?.({ step, context });
|
|
242
|
+
const result = await action(context);
|
|
243
|
+
if (result !== undefined) {
|
|
244
|
+
context.state[step] = result;
|
|
245
|
+
if (step === "fix") {
|
|
246
|
+
context.fixResult = result;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
await callbacks.onStepComplete?.({ step, context, result });
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
await callbacks.onStepError?.({ step, context, error });
|
|
253
|
+
const message = `[obs] pipeline step "${step}" failed: ${errorMessage(error)}`;
|
|
254
|
+
if (!continueOnStepError)
|
|
255
|
+
throw new Error(message);
|
|
256
|
+
console.error(message);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
await callbacks.onPipelineComplete?.(context);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
await callbacks.onPipelineError?.({ error, context });
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
const processSignal = async (signal) => {
|
|
267
|
+
if (!detectionEnabled)
|
|
268
|
+
return;
|
|
269
|
+
const incident = await resolveIncident(signal);
|
|
270
|
+
if (!incident)
|
|
271
|
+
return;
|
|
272
|
+
if (shouldDedupe(incident.fingerprint))
|
|
273
|
+
return;
|
|
274
|
+
try {
|
|
275
|
+
await runWorkflow(signal, incident);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
console.error(`[obs] workflow failed incident=${incident.id} error=${errorMessage(error)}`);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
const createSignal = (kind, payload) => {
|
|
282
|
+
return {
|
|
283
|
+
id: nextSignalId(),
|
|
284
|
+
kind,
|
|
285
|
+
timestamp: now(),
|
|
286
|
+
service,
|
|
287
|
+
environment,
|
|
288
|
+
tags,
|
|
289
|
+
...payload,
|
|
290
|
+
};
|
|
291
|
+
};
|
|
292
|
+
return {
|
|
293
|
+
name: "@farm.js/plugin-observability",
|
|
294
|
+
enforce: "post",
|
|
295
|
+
init() {
|
|
296
|
+
if (logLifecycle)
|
|
297
|
+
console.log("[obs] init");
|
|
298
|
+
},
|
|
299
|
+
ready() {
|
|
300
|
+
if (logLifecycle)
|
|
301
|
+
console.log("[obs] ready");
|
|
302
|
+
},
|
|
303
|
+
beforeRequest(req) {
|
|
304
|
+
const pathname = req.url || "/";
|
|
305
|
+
const method = req.method || "GET";
|
|
306
|
+
const requestId = `req_${now()}_${(signalCounter++).toString(36)}`;
|
|
307
|
+
requestStarts.set(req, {
|
|
308
|
+
startedAt: now(),
|
|
309
|
+
method,
|
|
310
|
+
pathname,
|
|
311
|
+
requestId,
|
|
312
|
+
});
|
|
313
|
+
},
|
|
314
|
+
async afterResponse(req, res) {
|
|
315
|
+
const started = requestStarts.get(req);
|
|
316
|
+
if (!started)
|
|
317
|
+
return;
|
|
318
|
+
requestStarts.delete(req);
|
|
319
|
+
const signal = createSignal("request.completed", {
|
|
320
|
+
request: {
|
|
321
|
+
method: started.method,
|
|
322
|
+
pathname: started.pathname,
|
|
323
|
+
statusCode: res.statusCode || 200,
|
|
324
|
+
durationMs: now() - started.startedAt,
|
|
325
|
+
requestId: started.requestId,
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
await processSignal(signal);
|
|
329
|
+
},
|
|
330
|
+
async afterApiHandler(response, api) {
|
|
331
|
+
const signal = createSignal("api.response", {
|
|
332
|
+
api: {
|
|
333
|
+
method: api.method,
|
|
334
|
+
pathname: api.pathname,
|
|
335
|
+
status: response.status,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
await processSignal(signal);
|
|
339
|
+
return response;
|
|
340
|
+
},
|
|
341
|
+
afterRender(html, render) {
|
|
342
|
+
if (!annotateHtml)
|
|
343
|
+
return html;
|
|
344
|
+
const marker = `<!-- observability:path=${render.pathname} route=${render.routePattern ?? "unmatched"} -->`;
|
|
345
|
+
return html.includes("</body>")
|
|
346
|
+
? html.replace("</body>", `${marker}\n</body>`)
|
|
347
|
+
: `${html}\n${marker}`;
|
|
348
|
+
},
|
|
349
|
+
async onError(error) {
|
|
350
|
+
const message = errorMessage(error.error);
|
|
351
|
+
const signal = createSignal("runtime.error", {
|
|
352
|
+
error: {
|
|
353
|
+
phase: error.phase,
|
|
354
|
+
message,
|
|
355
|
+
name: error.error instanceof Error ? error.error.name : undefined,
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
await processSignal(signal);
|
|
359
|
+
},
|
|
360
|
+
hmrUpdate(update) {
|
|
361
|
+
if (!logLifecycle)
|
|
362
|
+
return;
|
|
363
|
+
console.log(`[obs] hmr file=${update.file} modules=${update.modules.length}`);
|
|
364
|
+
},
|
|
365
|
+
async afterBundle(result) {
|
|
366
|
+
if (logLifecycle) {
|
|
367
|
+
const state = result.success ? "success" : "failed";
|
|
368
|
+
console.log(`[obs] bundle ${state} preset=${result.preset} root=${result.root}`);
|
|
369
|
+
}
|
|
370
|
+
const signal = createSignal("build.result", {
|
|
371
|
+
build: {
|
|
372
|
+
success: result.success,
|
|
373
|
+
preset: result.preset,
|
|
374
|
+
root: result.root,
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
await processSignal(signal);
|
|
378
|
+
},
|
|
379
|
+
async afterNitroBuild(payload) {
|
|
380
|
+
if (logLifecycle) {
|
|
381
|
+
console.log(`[obs] nitro preset=${payload.preset} output=${payload.outputDir}`);
|
|
382
|
+
}
|
|
383
|
+
const signal = createSignal("nitro.build", {
|
|
384
|
+
build: {
|
|
385
|
+
success: true,
|
|
386
|
+
preset: payload.preset,
|
|
387
|
+
root: payload.root || process.cwd(),
|
|
388
|
+
outputDir: payload.outputDir,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
await processSignal(signal);
|
|
392
|
+
},
|
|
393
|
+
shutdown(payload) {
|
|
394
|
+
if (logLifecycle)
|
|
395
|
+
console.log(`[obs] shutdown reason=${payload.reason}`);
|
|
396
|
+
recentIncidentsByFingerprint.clear();
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AutomaticOptimizedBoundaryTransform {
|
|
2
|
+
code: string;
|
|
3
|
+
boundaryCount: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Wrap React JSX-runtime calls for native host boundaries with Farm's
|
|
7
|
+
* server-only optimizer. Eligibility is decided against the fully evaluated
|
|
8
|
+
* React element at runtime, so unsupported trees retain normal React behavior.
|
|
9
|
+
*/
|
|
10
|
+
export declare function transformAutomaticOptimizedBoundaries(code: string, id: string): AutomaticOptimizedBoundaryTransform | null;
|
|
11
|
+
//# sourceMappingURL=automatic-optimized-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-optimized-boundary.d.ts","sourceRoot":"","sources":["../../src/rsc/automatic-optimized-boundary.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mCAAmC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAiGD;;;;GAIG;AACH,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,mCAAmC,GAAG,IAAI,CA8C5C"}
|