@interfere/next 11.1.1 → 12.0.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.
- package/README.md +25 -25
- package/dist/config.d.mts +7 -8
- package/dist/config.mjs +1 -1
- package/dist/instrument-client.d.mts +5 -5
- package/dist/instrument-client.mjs +1 -1
- package/dist/instrumentation.d.mts +11 -8
- package/dist/instrumentation.edge.d.mts +5 -5
- package/dist/instrumentation.edge.mjs +1 -1
- package/dist/instrumentation.mjs +1 -1
- package/dist/internal/build/configure-build.d.mts +21 -15
- package/dist/internal/build/configure-build.mjs +1 -1
- package/dist/internal/build/detect-bundler.d.mts +3 -4
- package/dist/internal/build/pipeline.d.mts +40 -27
- package/dist/internal/build/pipeline.mjs +1 -1
- package/dist/internal/build/release/git.d.mts +2 -3
- package/dist/internal/build/release/index.d.mts +51 -5
- package/dist/internal/build/release/index.mjs +1 -1
- package/dist/internal/build/source-maps/discover-turbopack.d.mts +2 -3
- package/dist/internal/build/source-maps/discover-turbopack.mjs +1 -1
- package/dist/internal/build/source-maps/discover-webpack.d.mts +3 -4
- package/dist/internal/build/source-maps/discover-webpack.mjs +1 -1
- package/dist/internal/build/source-maps/discover.d.mts +9 -5
- package/dist/internal/build/source-maps/discover.mjs +1 -1
- package/dist/internal/build/source-maps/guard.d.mts +2 -3
- package/dist/internal/build/source-maps/guard.mjs +1 -1
- package/dist/internal/build/source-maps/paths.d.mts +5 -6
- package/dist/internal/build/source-maps/paths.mjs +1 -1
- package/dist/internal/build/telemetry.d.mts +5 -0
- package/dist/internal/build/telemetry.mjs +1 -0
- package/dist/internal/build/value-injection-loader.d.mts +5 -8
- package/dist/internal/build/value-injection-loader.mjs +2 -2
- package/dist/internal/build-marker-guard.d.mts +5 -6
- package/dist/internal/build-marker-guard.mjs +1 -1
- package/dist/internal/env.d.mts +13 -15
- package/dist/internal/env.mjs +1 -1
- package/dist/internal/logger.d.mts +5 -6
- package/dist/internal/logger.mjs +1 -1
- package/dist/internal/release-slug.d.mts +4 -5
- package/dist/internal/release-slug.mjs +1 -1
- package/dist/internal/server/cache-safe-trace-context.d.mts +24 -0
- package/dist/internal/server/cache-safe-trace-context.mjs +1 -0
- package/dist/internal/server/capture.d.mts +3 -4
- package/dist/internal/server/capture.mjs +1 -1
- package/dist/internal/server/console-bridge.d.mts +7 -3
- package/dist/internal/server/console-bridge.mjs +1 -1
- package/dist/internal/server/edge-exporter.d.mts +5 -6
- package/dist/internal/server/edge-exporter.mjs +1 -1
- package/dist/internal/server/freshness-propagator.d.mts +41 -0
- package/dist/internal/server/freshness-propagator.mjs +1 -0
- package/dist/internal/server/global-handlers.d.mts +4 -5
- package/dist/internal/server/global-handlers.mjs +1 -1
- package/dist/internal/server/id-generator.d.mts +2 -3
- package/dist/internal/server/instrumentation-options.d.mts +3 -4
- package/dist/internal/server/remote-config.d.mts +3 -4
- package/dist/internal/server/remote-config.mjs +1 -1
- package/dist/internal/server/server-action-marker.d.mts +10 -5
- package/dist/internal/server/server-action-marker.mjs +1 -1
- package/dist/internal/server/server-flush.d.mts +3 -4
- package/dist/internal/server/server-flush.mjs +1 -1
- package/dist/internal/server/static-generation.d.mts +17 -0
- package/dist/internal/server/static-generation.mjs +1 -0
- package/dist/internal/server/trace-meta.d.mts +13 -26
- package/dist/internal/server/trace-meta.mjs +1 -1
- package/dist/internal/server/traceparent.d.mts +2 -3
- package/dist/internal/server/traceparent.mjs +1 -1
- package/dist/internal/server/types.d.mts +5 -8
- package/dist/internal/server/wrap-proxy.d.mts +3 -4
- package/dist/internal/server/wrap-proxy.mjs +1 -1
- package/dist/internal/server/wrap-server-action.d.mts +2 -3
- package/dist/internal/server/wrap-server-action.mjs +1 -1
- package/dist/internal/setup-warnings.d.mts +3 -4
- package/dist/internal/setup-warnings.mjs +1 -1
- package/dist/internal/version.d.mts +2 -3
- package/dist/package.mjs +1 -1
- package/dist/provider.d.mts +3 -3
- package/dist/provider.mjs +1 -1
- package/package.json +49 -42
- package/dist/internal/build/release/destinations/cli.d.mts +0 -6
- package/dist/internal/build/release/destinations/cli.mjs +0 -1
- package/dist/internal/build/release/destinations/cloudflare.d.mts +0 -5
- package/dist/internal/build/release/destinations/cloudflare.mjs +0 -1
- package/dist/internal/build/release/destinations/index.d.mts +0 -14
- package/dist/internal/build/release/destinations/index.mjs +0 -1
- package/dist/internal/build/release/destinations/vercel.d.mts +0 -5
- package/dist/internal/build/release/destinations/vercel.mjs +0 -1
- package/dist/internal/build/release/sources/github.d.mts +0 -8
- package/dist/internal/build/release/sources/github.mjs +0 -1
- package/dist/internal/build/release/sources/index.d.mts +0 -20
- package/dist/internal/build/release/sources/index.mjs +0 -1
- package/dist/internal/build/source-maps/index.d.mts +0 -6
- package/dist/internal/build/source-maps/index.mjs +0 -1
- package/dist/internal/build/source-maps/upload.d.mts +0 -39
- package/dist/internal/build/source-maps/upload.mjs +0 -1
- package/dist/internal/url.d.mts +0 -4
- package/dist/internal/url.mjs +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
const MARKER=`__interfere_server_action__`;function markServerAction(error,info){typeof error
|
|
1
|
+
const MARKER=`__interfere_server_action__`;function markServerAction(error,info){typeof error==`object`&&error&&Object.defineProperty(error,MARKER,{configurable:!0,enumerable:!1,value:info,writable:!0})}function readServerAction(error){if(typeof error!=`object`||!error||!(MARKER in error))return;let marker=error[MARKER];if(typeof marker==`object`&&marker&&`name`in marker&&typeof marker.name==`string`){if(!(`argsShape`in marker)||marker.argsShape===void 0)return{name:marker.name};if(typeof marker.argsShape==`string`)return{name:marker.name,argsShape:marker.argsShape}}}export{markServerAction,readServerAction};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
//#region src/internal/server/server-flush.d.ts
|
|
2
|
-
declare function setServerFlush(fn: () => Promise<void>): void;
|
|
3
|
-
declare function flushServerTelemetry(): Promise<void>;
|
|
4
|
-
//#endregion
|
|
5
|
-
export { flushServerTelemetry, setServerFlush };
|
|
2
|
+
export declare function setServerFlush(fn: () => Promise<void>): void;
|
|
3
|
+
export declare function flushServerTelemetry(): Promise<void>;
|
|
4
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
let flushFn=null;function setServerFlush(fn){flushFn=fn}function flushServerTelemetry(){return flushFn?flushFn():Promise.resolve()}export{flushServerTelemetry,setServerFlush};
|
|
1
|
+
let flushFn=null;function setServerFlush(fn){flushFn=fn}async function flushServerTelemetry(){return flushFn?flushFn():Promise.resolve()}export{flushServerTelemetry,setServerFlush};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/internal/server/static-generation.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Whether the current render is a static-generation render — a build-time
|
|
4
|
+
* prerender or a runtime ISR revalidation. Trace context injected into such
|
|
5
|
+
* a render is baked into cached HTML and served to every visitor in the
|
|
6
|
+
* cache window, so injection paths that feed `clientTraceMetadata` must
|
|
7
|
+
* skip it, mirroring what Next itself produces for build-time prerenders
|
|
8
|
+
* (no meta at all).
|
|
9
|
+
*
|
|
10
|
+
* Reads Next's `workAsyncStorage` external — the same store Next consults
|
|
11
|
+
* for its own static/dynamic decisions, importable on both the Node.js and
|
|
12
|
+
* Edge runtimes. Outside any render (no store) this returns `false`; the
|
|
13
|
+
* client-side `tracestate` freshness guard remains the backstop for
|
|
14
|
+
* caching the server cannot see (CDN full-page caches).
|
|
15
|
+
*/
|
|
16
|
+
export declare function isStaticGenerationRender(): boolean;
|
|
17
|
+
//#endregion
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{workAsyncStorage}from"next/dist/server/app-render/work-async-storage.external.js";function isStaticGenerationRender(){try{return workAsyncStorage.getStore()?.isStaticGeneration===!0}catch{return!1}}export{isStaticGenerationRender};
|
|
@@ -1,32 +1,19 @@
|
|
|
1
1
|
//#region src/internal/server/trace-meta.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* Server Component that emits a `<meta name="traceparent">` tag so the
|
|
4
|
-
* client SDK can stitch
|
|
4
|
+
* client SDK can stitch browser spans onto the server-side trace.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* @deprecated `withInterfere()` enables Next's native trace-meta injection
|
|
7
|
+
* (`experimental.clientTraceMetadata`), which also carries the `tracestate`
|
|
8
|
+
* freshness stamp that guards cached HTML — this component does not.
|
|
9
|
+
* Remove `<TraceMeta />` from your layout; with `withInterfere()` in your
|
|
10
|
+
* Next config the meta tags are injected for you. This export will be
|
|
11
|
+
* removed in the next major version.
|
|
7
12
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* return (
|
|
13
|
-
* <html>
|
|
14
|
-
* <head>
|
|
15
|
-
* <TraceMeta />
|
|
16
|
-
* </head>
|
|
17
|
-
* <body>{children}</body>
|
|
18
|
-
* </html>
|
|
19
|
-
* );
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* Renders nothing when no OTel span is active (dev without OTel
|
|
24
|
-
* registered, edge runtime where `@interfere/next/instrumentation`'s
|
|
25
|
-
* async `register()` hasn't completed before the layout renders, or
|
|
26
|
-
* unsampled traces). The client SDK's propagation reader handles a
|
|
27
|
-
* missing meta tag the same as no parent — every browser span starts a
|
|
28
|
-
* fresh root, which is at least internally consistent.
|
|
13
|
+
* Renders nothing when no sampled OTel span is active, and nothing during
|
|
14
|
+
* static-generation renders (build prerender, runtime ISR revalidation) —
|
|
15
|
+
* trace context baked into cached HTML would stitch every visitor in the
|
|
16
|
+
* cache window onto one stale trace.
|
|
29
17
|
*/
|
|
30
|
-
declare function TraceMeta(): import("react").JSX.Element | null;
|
|
31
|
-
//#endregion
|
|
32
|
-
export { TraceMeta };
|
|
18
|
+
export declare function TraceMeta(): import("react").JSX.Element | null;
|
|
19
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{activeTraceparent}from"./traceparent.mjs";import{jsx}from"react/jsx-runtime";function TraceMeta(){let traceparent=activeTraceparent();return traceparent?jsx(`meta`,{content:traceparent,name:`traceparent`}):null}export{TraceMeta};
|
|
1
|
+
import{isStaticGenerationRender}from"./static-generation.mjs";import{activeTraceparent}from"./traceparent.mjs";import{jsx}from"react/jsx-runtime";function TraceMeta(){if(isStaticGenerationRender())return null;let traceparent=activeTraceparent();return traceparent?jsx(`meta`,{content:traceparent,name:`traceparent`}):null}export{TraceMeta};
|
|
@@ -11,6 +11,5 @@
|
|
|
11
11
|
* recorded server segments. Returning null lets the browser fall back
|
|
12
12
|
* to its own root, which is at least internally consistent.
|
|
13
13
|
*/
|
|
14
|
-
declare function activeTraceparent(): string | null;
|
|
15
|
-
//#endregion
|
|
16
|
-
export { activeTraceparent };
|
|
14
|
+
export declare function activeTraceparent(): string | null;
|
|
15
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TraceFlags,trace}from"@opentelemetry/api";const SAMPLED_BIT=TraceFlags.SAMPLED;function activeTraceparent(){let span=trace.getActiveSpan();if(!span)return null;let ctx=span.spanContext();if((ctx.traceFlags&SAMPLED_BIT)
|
|
1
|
+
import{TraceFlags,trace}from"@opentelemetry/api";const SAMPLED_BIT=TraceFlags.SAMPLED;function activeTraceparent(){let span=trace.getActiveSpan();if(!span)return null;let ctx=span.spanContext();if((ctx.traceFlags&SAMPLED_BIT)===0)return null;let flags=ctx.traceFlags.toString(16).padStart(2,`0`);return`00-${ctx.traceId}-${ctx.spanId}-${flags}`}export{activeTraceparent};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
+
import { ServerActionMarker } from "./server-action-marker.mjs";
|
|
1
2
|
import { NextjsContext } from "@interfere/types/sdk/plugins/context/next";
|
|
2
3
|
import { ErrorMechanism } from "@interfere/types/sdk/plugins/payload/errors";
|
|
3
4
|
//#region src/internal/server/types.d.ts
|
|
4
|
-
type OnRequestErrorContext = Omit<NextjsContext, "errorDigest" | "requestMethod" | "requestPath" | "runtime">;
|
|
5
|
-
interface CaptureErrorContext {
|
|
5
|
+
export type OnRequestErrorContext = Omit<NextjsContext, "errorDigest" | "requestMethod" | "requestPath" | "runtime">;
|
|
6
|
+
export interface CaptureErrorContext {
|
|
6
7
|
readonly mechanism?: ErrorMechanism;
|
|
7
8
|
readonly nextjs?: Omit<NextjsContext, "runtime">;
|
|
8
9
|
readonly requestHeaders?: Readonly<Record<string, string>>;
|
|
9
|
-
readonly serverAction?:
|
|
10
|
-
readonly name: string;
|
|
11
|
-
readonly argsShape?: string;
|
|
12
|
-
};
|
|
10
|
+
readonly serverAction?: ServerActionMarker;
|
|
13
11
|
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { CaptureErrorContext, OnRequestErrorContext };
|
|
12
|
+
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NextMiddleware } from "next/server
|
|
1
|
+
import { NextMiddleware, NextRequest } from "next/server";
|
|
2
2
|
//#region src/internal/server/wrap-proxy.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Wraps a Next.js proxy (formerly `middleware`) so thrown errors are captured
|
|
@@ -16,6 +16,5 @@ import { NextMiddleware } from "next/server.js";
|
|
|
16
16
|
* });
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
declare function withInterfereProxy(proxy: NextMiddleware):
|
|
20
|
-
//#endregion
|
|
21
|
-
export { withInterfereProxy };
|
|
19
|
+
export declare function withInterfereProxy(proxy: NextMiddleware): (request: NextRequest, event: import("next/server.js").NextFetchEvent) => void | Promise<import("next/dist/server/web/types.js").NextMiddlewareResult> | Response | null;
|
|
20
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{captureError}from"./capture.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";function withInterfereProxy(proxy){return(request,event)=>{try{let result=proxy(request,event);return result instanceof Promise?result.catch(error=>{throw reportProxyError(error,request),error}):result}catch(error){throw reportProxyError(error,request),error}}}function reportProxyError(error,request){captureError(error,request,{mechanism:{type:MECHANISM_TYPE.nextjs.proxy
|
|
1
|
+
import{captureError}from"./capture.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";function withInterfereProxy(proxy){return((request,event)=>{try{let result=proxy(request,event);return result instanceof Promise?result.catch(error=>{throw reportProxyError(error,request),error}):result}catch(error){throw reportProxyError(error,request),error}})}function reportProxyError(error,request){captureError(error,request,{mechanism:{handled:!1,type:MECHANISM_TYPE.nextjs.proxy},nextjs:{requestMethod:request.method,requestPath:request.nextUrl.pathname}})}export{withInterfereProxy};
|
|
@@ -29,6 +29,5 @@ interface ServerActionOptions {
|
|
|
29
29
|
* }
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
declare function withInterfereServerAction<T>(name: string, action: () => T | Promise<T>, options?: ServerActionOptions): Promise<T>;
|
|
33
|
-
//#endregion
|
|
34
|
-
export { withInterfereServerAction };
|
|
32
|
+
export declare function withInterfereServerAction<T>(name: string, action: () => T | Promise<T>, options?: ServerActionOptions): Promise<T>;
|
|
33
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{markServerAction}from"./server-action-marker.mjs";import{SpanStatusCode,trace}from"@opentelemetry/api";function withInterfereServerAction(name,action,options){return trace.getTracer(`@interfere/next/server`).startActiveSpan(`serverAction ${name}`,async span=>{span.setAttribute(`interfere.server_action.name`,name);let argsShape=options?.args?describeArgsShape(options.args):null;argsShape&&span.setAttribute(`interfere.server_action.args_shape`,argsShape);try{let result=await action();return span.setAttribute(`interfere.server_action.outcome`,`success`),result}catch(error){throw span.setAttribute(`interfere.server_action.outcome`,`error`),span.setStatus({code:SpanStatusCode.ERROR}),markServerAction(error,{name
|
|
1
|
+
import{markServerAction}from"./server-action-marker.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{SpanStatusCode,trace}from"@opentelemetry/api";async function withInterfereServerAction(name,action,options){return trace.getTracer(`@interfere/next/server`).startActiveSpan(`serverAction ${name}`,async span=>{span.setAttribute(`interfere.server_action.name`,name);let argsShape=options?.args?describeArgsShape(options.args):null;argsShape&&span.setAttribute(`interfere.server_action.args_shape`,argsShape);try{let result=await action();return span.setAttribute(`interfere.server_action.outcome`,`success`),result}catch(error){throw span.setAttribute(`interfere.server_action.outcome`,`error`),span.setStatus({code:SpanStatusCode.ERROR}),markServerAction(error,omitUndefined({name,argsShape:argsShape||void 0})),error}finally{span.end()}})}function describeArgsShape(args){return args.map(arg=>arg===null?`null`:arg===void 0?`undefined`:typeof arg==`object`?arg.constructor?.name??`object`:typeof arg).join(`,`)}export{withInterfereServerAction};
|
|
@@ -6,12 +6,11 @@
|
|
|
6
6
|
* them. Never blocks the build: some customers genuinely don't want
|
|
7
7
|
* server-side tracing.
|
|
8
8
|
*/
|
|
9
|
-
declare function warnIfServerInstrumentationMissing(projectDir: string): void;
|
|
9
|
+
export declare function warnIfServerInstrumentationMissing(projectDir: string): void;
|
|
10
10
|
/**
|
|
11
11
|
* Reads the customer's installed `next` package version. Returns `null` if
|
|
12
12
|
* Next isn't resolvable from `projectDir` (e.g. running outside a Next app),
|
|
13
13
|
* in which case callers should skip version-conditional behaviour.
|
|
14
14
|
*/
|
|
15
|
-
declare function readNextMajorVersion(projectDir: string): number | null;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { readNextMajorVersion, warnIfServerInstrumentationMissing };
|
|
15
|
+
export declare function readNextMajorVersion(projectDir: string): number | null;
|
|
16
|
+
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{log}from"./logger.mjs";import{createRequire}from"node:module";import{existsSync}from"node:fs";import path from"node:path";const SERVER_INSTRUMENTATION_FILES=[`instrumentation.ts`,`instrumentation.tsx`,`instrumentation.js`,`instrumentation.jsx`,`src/instrumentation.ts`,`src/instrumentation.tsx`,`src/instrumentation.js`,`src/instrumentation.jsx`];function hasServerInstrumentation(projectDir){return SERVER_INSTRUMENTATION_FILES.some(c=>existsSync(path.resolve(projectDir,c)))}function warnIfServerInstrumentationMissing(projectDir){hasServerInstrumentation(projectDir)||log.warn(`No instrumentation.ts found`,[`Server-side traces will be skipped. To enable, create instrumentation.ts at the project root with:`,` export { register } from '@interfere/next/instrumentation';`])}function readNextMajorVersion(projectDir){try{let pkg=createRequire(`${projectDir}/_`)(`next/package.json`)
|
|
1
|
+
import{log}from"./logger.mjs";import{createRequire}from"node:module";import{existsSync}from"node:fs";import path from"node:path";const SERVER_INSTRUMENTATION_FILES=[`instrumentation.ts`,`instrumentation.tsx`,`instrumentation.js`,`instrumentation.jsx`,`src/instrumentation.ts`,`src/instrumentation.tsx`,`src/instrumentation.js`,`src/instrumentation.jsx`];function hasServerInstrumentation(projectDir){return SERVER_INSTRUMENTATION_FILES.some(c=>existsSync(path.resolve(projectDir,c)))}function warnIfServerInstrumentationMissing(projectDir){hasServerInstrumentation(projectDir)||log.warn(`No instrumentation.ts found`,[`Server-side traces will be skipped. To enable, create instrumentation.ts at the project root with:`,` export { register } from '@interfere/next/instrumentation';`])}function readNextMajorVersion(projectDir){try{let pkg=createRequire(`${projectDir}/_`)(`next/package.json`);if(typeof pkg!=`object`||!pkg||!(`version`in pkg)||typeof pkg.version!=`string`)return null;let major=Number.parseInt(pkg.version.split(`.`)[0]??``,10);return Number.isFinite(major)?major:null}catch{return null}}export{readNextMajorVersion,warnIfServerInstrumentationMissing};
|
package/dist/package.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var name=`@interfere/next`,version=`
|
|
1
|
+
var name=`@interfere/next`,version=`12.0.0`;export{name,version};
|
package/dist/provider.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PluginOverrides, useInterfere, useSession } from "@interfere/react/provider";
|
|
2
|
-
import { PropsWithChildren
|
|
2
|
+
import { PropsWithChildren } from "react";
|
|
3
3
|
import { ConsentCategory, ConsentState, ConsentState as ConsentState$1, GateableCategory } from "@interfere/types/sdk/plugins/manifest";
|
|
4
4
|
//#region src/provider.d.ts
|
|
5
5
|
interface InterfereProviderProps extends PropsWithChildren {
|
|
@@ -15,6 +15,6 @@ interface InterfereProviderProps extends PropsWithChildren {
|
|
|
15
15
|
* (`init()` is client-only); the core provider mounts with null-safe
|
|
16
16
|
* accessors and switches to the real kernel on client hydration.
|
|
17
17
|
*/
|
|
18
|
-
declare function InterfereProvider({ children, consent, plugins, errorBoundary }: InterfereProviderProps):
|
|
18
|
+
export declare function InterfereProvider({ children, consent, plugins, errorBoundary }: InterfereProviderProps): import("react").JSX.Element;
|
|
19
19
|
//#endregion
|
|
20
|
-
export { type ConsentCategory, type ConsentState, type GateableCategory,
|
|
20
|
+
export { type ConsentCategory, type ConsentState, type GateableCategory, useInterfere, useSession };
|
package/dist/provider.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{getKernelOrNull,subscribeToKernel}from"./instrument-client.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereProvider as InterfereProvider$1,useInterfere,useSession}from"@interfere/react/provider";import{useSyncExternalStore}from"react";import{jsx}from"react/jsx-runtime";const nullSnapshot=()=>null;function InterfereProvider({children,consent,plugins,errorBoundary}){let kernel=useSyncExternalStore(subscribeToKernel,getKernelOrNull,nullSnapshot);return jsx(InterfereProvider$1,{kernel,...omitUndefined({consent,plugins
|
|
1
|
+
"use client";import{getKernelOrNull,subscribeToKernel}from"./instrument-client.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereProvider as InterfereProvider$1,useInterfere,useSession}from"@interfere/react/provider";import{useSyncExternalStore}from"react";import{jsx}from"react/jsx-runtime";const nullSnapshot=()=>null;function InterfereProvider({children,consent,plugins,errorBoundary}){let kernel=useSyncExternalStore(subscribeToKernel,getKernelOrNull,nullSnapshot);return jsx(InterfereProvider$1,{kernel,...omitUndefined({consent,errorBoundary,plugins}),children})}export{InterfereProvider,useInterfere,useSession};
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interfere/next",
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "MIT",
|
|
3
|
+
"version": "12.0.0",
|
|
5
4
|
"description": "Build software that never breaks.",
|
|
6
5
|
"keywords": [
|
|
6
|
+
"error-tracking",
|
|
7
|
+
"nextjs",
|
|
7
8
|
"observability",
|
|
8
|
-
"typescript",
|
|
9
9
|
"react",
|
|
10
|
-
"
|
|
11
|
-
"error-tracking"
|
|
10
|
+
"typescript"
|
|
12
11
|
],
|
|
13
12
|
"homepage": "https://interfere.com",
|
|
14
13
|
"bugs": {
|
|
15
14
|
"url": "mailto:support@interfere.com"
|
|
16
15
|
},
|
|
16
|
+
"license": "MIT",
|
|
17
17
|
"author": "Interfere <support@interfere.com> (https://interfere.com)",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"type": "module",
|
|
27
|
+
"sideEffects": false,
|
|
27
28
|
"exports": {
|
|
28
29
|
"./config": {
|
|
29
30
|
"monorepo": "./src/config.ts",
|
|
@@ -83,36 +84,60 @@
|
|
|
83
84
|
"default": "./dist/server.mjs"
|
|
84
85
|
}
|
|
85
86
|
},
|
|
86
|
-
"sideEffects": false,
|
|
87
87
|
"publishConfig": {
|
|
88
88
|
"access": "public"
|
|
89
89
|
},
|
|
90
90
|
"scripts": {
|
|
91
91
|
"build": "tsdown",
|
|
92
92
|
"test": "vitest run",
|
|
93
|
+
"test:e2e": "playwright test",
|
|
93
94
|
"typecheck": "tsc --noEmit"
|
|
94
95
|
},
|
|
95
96
|
"dependencies": {
|
|
96
|
-
"@interfere/
|
|
97
|
-
"@interfere/
|
|
98
|
-
"@interfere/
|
|
99
|
-
"@interfere/
|
|
100
|
-
"@interfere/
|
|
97
|
+
"@interfere/build": "^0.2.0",
|
|
98
|
+
"@interfere/constants": "^9.1.0",
|
|
99
|
+
"@interfere/helpers": "^9.2.0",
|
|
100
|
+
"@interfere/javascript": "^0.2.0",
|
|
101
|
+
"@interfere/react": "^12.0.0",
|
|
102
|
+
"@interfere/types": "^10.2.0",
|
|
101
103
|
"@opentelemetry/api": "^1.9.1",
|
|
102
|
-
"@opentelemetry/api-logs": "^0.
|
|
104
|
+
"@opentelemetry/api-logs": "^0.222.0",
|
|
103
105
|
"@opentelemetry/baggage-span-processor": "^0.5.0",
|
|
104
|
-
"@opentelemetry/context-async-hooks": "^2.
|
|
105
|
-
"@opentelemetry/core": "^2.
|
|
106
|
-
"@opentelemetry/exporter-logs-otlp-http": "^0.
|
|
107
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
108
|
-
"@opentelemetry/instrumentation": "^0.
|
|
109
|
-
"@opentelemetry/otlp-exporter-base": "^0.
|
|
110
|
-
"@opentelemetry/otlp-transformer": "^0.
|
|
111
|
-
"@opentelemetry/resources": "^2.
|
|
112
|
-
"@opentelemetry/sdk-logs": "^0.
|
|
113
|
-
"@opentelemetry/sdk-trace-base": "^2.
|
|
114
|
-
"@opentelemetry/sdk-trace-node": "^2.
|
|
115
|
-
"chalk": "^6.0.0"
|
|
106
|
+
"@opentelemetry/context-async-hooks": "^2.11.0",
|
|
107
|
+
"@opentelemetry/core": "^2.11.0",
|
|
108
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.222.0",
|
|
109
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
|
|
110
|
+
"@opentelemetry/instrumentation": "^0.222.0",
|
|
111
|
+
"@opentelemetry/otlp-exporter-base": "^0.222.0",
|
|
112
|
+
"@opentelemetry/otlp-transformer": "^0.222.0",
|
|
113
|
+
"@opentelemetry/resources": "^2.11.0",
|
|
114
|
+
"@opentelemetry/sdk-logs": "^0.222.0",
|
|
115
|
+
"@opentelemetry/sdk-trace-base": "^2.11.0",
|
|
116
|
+
"@opentelemetry/sdk-trace-node": "^2.11.0",
|
|
117
|
+
"chalk": "^6.0.0",
|
|
118
|
+
"zod": "^4.5.4"
|
|
119
|
+
},
|
|
120
|
+
"devDependencies": {
|
|
121
|
+
"@interfere/typescript-config": "^9.0.2",
|
|
122
|
+
"@interfere/vitest-config": "0.0.0",
|
|
123
|
+
"@playwright/test": "^1.63.0",
|
|
124
|
+
"@types/node": "^26.4.1",
|
|
125
|
+
"@types/react": "19.2.18",
|
|
126
|
+
"@types/react-dom": "19.2.7",
|
|
127
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
128
|
+
"@vitest/browser": "5.0.1",
|
|
129
|
+
"@vitest/browser-playwright": "5.0.1",
|
|
130
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
131
|
+
"msw": "^2.14.6",
|
|
132
|
+
"next": "^16.3.8",
|
|
133
|
+
"playwright": "^1.63.0",
|
|
134
|
+
"react": "19.3.0",
|
|
135
|
+
"react-dom": "19.3.0",
|
|
136
|
+
"tsdown": "^0.23.0",
|
|
137
|
+
"typescript": "^7.0.2",
|
|
138
|
+
"vitest": "5.0.1",
|
|
139
|
+
"vitest-browser-react": "2.3.0",
|
|
140
|
+
"webpack": "^5.111.1"
|
|
116
141
|
},
|
|
117
142
|
"peerDependencies": {
|
|
118
143
|
"next": "^15.3.0 || ^16.0.0",
|
|
@@ -129,23 +154,5 @@
|
|
|
129
154
|
"react-dom": {
|
|
130
155
|
"optional": true
|
|
131
156
|
}
|
|
132
|
-
},
|
|
133
|
-
"devDependencies": {
|
|
134
|
-
"@interfere/test-utils": "^9.1.1",
|
|
135
|
-
"@interfere/typescript-config": "^9.0.2",
|
|
136
|
-
"@types/node": "^26.2.0",
|
|
137
|
-
"@types/react": "19.2.18",
|
|
138
|
-
"@types/react-dom": "19.2.4",
|
|
139
|
-
"@vitest/browser": "4.1.10",
|
|
140
|
-
"@vitest/browser-playwright": "4.1.10",
|
|
141
|
-
"@vitest/coverage-v8": "4.1.10",
|
|
142
|
-
"next": "^16.3.0",
|
|
143
|
-
"playwright": "^1.62.1",
|
|
144
|
-
"react": "^19.2.6",
|
|
145
|
-
"react-dom": "19.2.8",
|
|
146
|
-
"tsdown": "^0.22.2",
|
|
147
|
-
"typescript": "^7.0.2",
|
|
148
|
-
"vitest": "4.1.10",
|
|
149
|
-
"vitest-browser-react": "2.2.0"
|
|
150
157
|
}
|
|
151
158
|
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { ReleaseSlug } from "@interfere/types/releases/slug";
|
|
2
|
-
import { ReleaseDestinationMetadata } from "@interfere/types/integrations";
|
|
3
|
-
//#region src/internal/build/release/destinations/cli.d.ts
|
|
4
|
-
declare function resolve(releaseSlug: ReleaseSlug): ReleaseDestinationMetadata;
|
|
5
|
-
//#endregion
|
|
6
|
-
export { resolve };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{resolveCliReleaseDestination}from"@interfere/types/sdk/cli-destination";function resolve(releaseSlug){return resolveCliReleaseDestination(process.env,releaseSlug)}export{resolve};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{parseEnvValue}from"@interfere/types/sdk/env";function parseVersionMetadata(){let raw=parseEnvValue(process.env.CF_VERSION_METADATA);if(!raw)return null;try{return JSON.parse(raw)}catch{return null}}function resolveDeploymentUrl(){let candidate=parseEnvValue(process.env.CF_PAGES_URL)??parseEnvValue(process.env.WORKERS_CI_DEPLOY_URL);return candidate===null?null:candidate.startsWith(`https://`)||candidate.startsWith(`http://`)?candidate:`https://${candidate}`}function resolve(){let versionMetadata=parseVersionMetadata(),versionId=parseEnvValue(process.env.CF_VERSION_ID)??versionMetadata?.id??parseEnvValue(process.env.WORKERS_CI_BUILD_UUID)??null,scriptName=parseEnvValue(process.env.CF_WORKER_NAME)??parseEnvValue(process.env.WORKERS_CI_SCRIPT_NAME)??null,accountId=parseEnvValue(process.env.CF_ACCOUNT_ID)??parseEnvValue(process.env.CLOUDFLARE_ACCOUNT_ID)??null,environment=parseEnvValue(process.env.WORKERS_CI_BRANCH)??versionMetadata?.tag??null;return{provider:`cloudflare`,destinationReleaseId:versionId,environment,versionId,scriptName,accountId,deploymentUrl:resolveDeploymentUrl(),environmentName:environment,environmentTarget:environment}}export{resolve};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { ReleaseSlug } from "@interfere/types/releases/slug";
|
|
2
|
-
import { ReleaseDestinationMetadata, ReleaseDestinationProvider } from "@interfere/types/integrations";
|
|
3
|
-
//#region src/internal/build/release/destinations/index.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Per-provider destination metadata resolvers. Mirrors `sources/` —
|
|
6
|
-
* each entry knows how to read its platform's deployment env vars and
|
|
7
|
-
* returns a `ReleaseDestinationMetadata` blob.
|
|
8
|
-
*
|
|
9
|
-
* Adding a new destination (fly, render, …) is one new file under this
|
|
10
|
-
* directory + one entry here.
|
|
11
|
-
*/
|
|
12
|
-
declare const destinations: Record<ReleaseDestinationProvider, (releaseSlug: ReleaseSlug) => ReleaseDestinationMetadata>;
|
|
13
|
-
//#endregion
|
|
14
|
-
export { destinations };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{resolve}from"./cli.mjs";import{resolve as resolve$1}from"./cloudflare.mjs";import{resolve as resolve$2}from"./vercel.mjs";const destinations={vercel:resolve$2,cloudflare:resolve$1,cli:resolve};export{destinations};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{parseEnvValue}from"@interfere/types/sdk/env";function resolve(){let environment=parseEnvValue(process.env.VERCEL_ENV??process.env.VERCEL_TARGET_ENV),deploymentId=parseEnvValue(process.env.VERCEL_DEPLOYMENT_ID);return{provider:`vercel`,destinationReleaseId:deploymentId,environment,deploymentId,deploymentUrl:resolveDeploymentUrl(),environmentName:environment,environmentTarget:environment}}function resolveDeploymentUrl(){let deploymentUrl=parseEnvValue(process.env.VERCEL_URL);return deploymentUrl===null?null:deploymentUrl.startsWith(`https://`)||deploymentUrl.startsWith(`http://`)?deploymentUrl:`https://${deploymentUrl}`}export{resolve};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ReleaseSourceMetadata } from "@interfere/types/integrations";
|
|
2
|
-
//#region src/internal/build/release/sources/github.d.ts
|
|
3
|
-
type GithubReleaseSource = Extract<ReleaseSourceMetadata, {
|
|
4
|
-
provider: "github";
|
|
5
|
-
}>;
|
|
6
|
-
declare function resolve(): GithubReleaseSource;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { resolve };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{runGitCommand}from"../git.mjs";import{resolveGithubReleaseSource}from"@interfere/types/sdk/github-source";function resolve(){return resolveGithubReleaseSource(process.env,runGitCommand)}export{resolve};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ReleaseSourceMetadata, SourceProvider } from "@interfere/types/integrations";
|
|
2
|
-
//#region src/internal/build/release/sources/index.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Per-provider source metadata resolvers. Each entry knows how to read
|
|
5
|
-
* its platform's env vars (and falls back to local git where applicable)
|
|
6
|
-
* and returns a `ReleaseSourceMetadata` blob keyed to the provider.
|
|
7
|
-
*
|
|
8
|
-
* Adding a new provider (gitlab, bitbucket, …) is one new file under
|
|
9
|
-
* this directory + one entry here. Every consumer that walks this
|
|
10
|
-
* registry — release-create payload assembly in the build pipeline —
|
|
11
|
-
* picks up the new provider for free.
|
|
12
|
-
*
|
|
13
|
-
* Lives under `internal/build/` because resolvers shell out to git via
|
|
14
|
-
* `runGitCommand`, which depends on `node:child_process` (not Edge-safe).
|
|
15
|
-
* Anything imported from `instrumentation.ts` must stay edge-safe; this
|
|
16
|
-
* tree is build-only.
|
|
17
|
-
*/
|
|
18
|
-
declare const sources: Record<SourceProvider, () => ReleaseSourceMetadata>;
|
|
19
|
-
//#endregion
|
|
20
|
-
export { sources };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{resolve}from"./github.mjs";const sources={github:resolve,ghe_cloud:resolve,ghe_server:resolve};export{sources};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { SourceMapFile } from "./discover.mjs";
|
|
2
|
-
import { uploadSourceMaps } from "./upload.mjs";
|
|
3
|
-
//#region src/internal/build/source-maps/index.d.ts
|
|
4
|
-
declare function cleanupSourceMaps(files: SourceMapFile[]): Promise<void>;
|
|
5
|
-
//#endregion
|
|
6
|
-
export { cleanupSourceMaps, uploadSourceMaps };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{log}from"../../logger.mjs";import{uploadSourceMaps}from"./upload.mjs";import{unlink}from"node:fs/promises";async function cleanupSourceMaps(files){let results=await Promise.allSettled(files.map(f=>unlink(f.absolute))),failures=[];for(let[i,r]of results.entries()){if(r.status!==`rejected`)continue;let err=r.reason;if(err.code===`ENOENT`)continue;let file=files[i];failures.push(`${file?.absolute??`<unknown>`}: ${err.code??err.message??String(err)}`)}failures.length>0&&log.warn(`Source-map cleanup left files on disk`,failures)}export{cleanupSourceMaps,uploadSourceMaps};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { DiscoveryResult } from "./discover.mjs";
|
|
2
|
-
import { ReleaseSlug } from "@interfere/types/releases/slug";
|
|
3
|
-
import { HTTPClient } from "@interfere/sdk";
|
|
4
|
-
import { ManifestBundler } from "@interfere/types/data/source-maps";
|
|
5
|
-
//#region src/internal/build/source-maps/upload.d.ts
|
|
6
|
-
interface UploadResult {
|
|
7
|
-
fileCount: number;
|
|
8
|
-
totalBytes: number;
|
|
9
|
-
}
|
|
10
|
-
interface UploadParams {
|
|
11
|
-
apiUrl: string;
|
|
12
|
-
bundler: ManifestBundler;
|
|
13
|
-
discovered: DiscoveryResult;
|
|
14
|
-
httpClient: HTTPClient;
|
|
15
|
-
releaseSlug: ReleaseSlug;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Drives the three-step presigned-URL flow:
|
|
19
|
-
*
|
|
20
|
-
* 1. POST `/v1/releases/:slug/source-maps/sign` with per-file metadata.
|
|
21
|
-
* 2. PUT each file's content directly to R2 in parallel (concurrency
|
|
22
|
-
* bounded so a build with 1000+ chunks doesn't open 1000 sockets).
|
|
23
|
-
* 3. POST `/v1/releases/:slug/source-maps/complete` to materialize the
|
|
24
|
-
* manifest and update the release row.
|
|
25
|
-
*
|
|
26
|
-
* The collector never sees source-map bytes — uploads scale with R2
|
|
27
|
-
* limits, not Cloudflare worker / load-balancer body-size caps. The
|
|
28
|
-
* legacy multipart endpoint is still wired for older SDKs.
|
|
29
|
-
*/
|
|
30
|
-
declare function uploadSourceMaps({ apiUrl, bundler, discovered, httpClient, releaseSlug }: UploadParams): Promise<UploadResult>;
|
|
31
|
-
interface SourceMapRichness {
|
|
32
|
-
hasSourcesContent: boolean;
|
|
33
|
-
hasNames: boolean;
|
|
34
|
-
hasFile: boolean;
|
|
35
|
-
mappingsPresent: boolean;
|
|
36
|
-
}
|
|
37
|
-
declare function extractRichness(content: string): SourceMapRichness;
|
|
38
|
-
//#endregion
|
|
39
|
-
export { UploadResult, extractRichness, uploadSourceMaps };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
async function uploadSourceMaps({apiUrl,bundler,discovered,httpClient,releaseSlug}){let filesByPath=new Map(discovered.files.map(f=>[f.path,f])),signRequest={files:discovered.files.map(file=>({path:file.path,sizeBytes:byteLengthOf(file.content),...extractRichness(file.content)}))},signResponse=await postJson(httpClient,new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/sign`,apiUrl),signRequest),totalBytes=0;await mapWithConcurrency(signResponse.uploads,32,async upload=>{let file=filesByPath.get(upload.path);if(!file)throw Error(`Sign response referenced unknown path "${upload.path}"`);totalBytes+=byteLengthOf(file.content),await putToR2(upload.presignedUrl,file.content)});let completeRequest={files:discovered.files.map(file=>({path:file.path,hash:file.hash,debugId:file.debugId,chunkUrl:file.chunkUrl})),sourceFileCount:discovered.sourceFileCount,bundler};return{fileCount:(await postJson(httpClient,new URL(`/v1/releases/${encodeURIComponent(releaseSlug)}/source-maps/complete`,apiUrl),completeRequest)).fileCount,totalBytes}}function byteLengthOf(content){return new TextEncoder().encode(content).byteLength}const EMPTY_RICHNESS={hasSourcesContent:!1,hasNames:!1,hasFile:!1,mappingsPresent:!1};function leafRichness(map){let sourcesContent=map.sourcesContent,names=map.names,file=map.file,mappings=map.mappings;return{hasSourcesContent:Array.isArray(sourcesContent)&&sourcesContent.length>0,hasNames:Array.isArray(names)&&names.length>0,hasFile:typeof file==`string`&&file.length>0,mappingsPresent:typeof mappings==`string`&&mappings.length>0}}function extractRichness(content){let parsed;try{parsed=JSON.parse(content)}catch{return EMPTY_RICHNESS}if(!(parsed&&typeof parsed==`object`))return EMPTY_RICHNESS;let top=parsed,sections=top.sections;if(!Array.isArray(sections))return leafRichness(top);let merged={hasSourcesContent:!1,hasNames:!1,hasFile:typeof top.file==`string`&&top.file.length>0,mappingsPresent:!1};for(let section of sections){let inner=section?.map;if(!(inner&&typeof inner==`object`))continue;let r=leafRichness(inner);merged.hasSourcesContent||=r.hasSourcesContent,merged.hasNames||=r.hasNames,merged.mappingsPresent||=r.mappingsPresent}return merged}async function postJson(httpClient,url,body){let response=await httpClient.request(new Request(url,{method:`POST`,headers:{"content-type":`application/json`,accept:`application/json`},body:JSON.stringify(body)}));if(!response.ok){let detail=await response.text().catch(()=>``);throw Error(`Source-map API request failed: POST ${url.pathname} -> ${response.status} ${detail}`)}return await response.json()}async function putToR2(presignedUrl,content){let response=await fetch(presignedUrl,{method:`PUT`,headers:{"content-type":`application/json`},body:content});if(!response.ok){let detail=await response.text().catch(()=>``);throw Error(`Release metadata file upload failed: ${response.status} ${detail}`)}}async function mapWithConcurrency(items,concurrency,fn){let cursor=0;async function worker(){for(;;){let i=cursor++;if(i>=items.length)return;let item=items[i];if(item===void 0)return;await fn(item,i)}}await Promise.all(Array.from({length:Math.min(concurrency,items.length)},()=>worker()))}export{extractRichness,uploadSourceMaps};
|
package/dist/internal/url.d.mts
DELETED
package/dist/internal/url.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function withPublicKey(url,publicKey){let next=new URL(url);return next.searchParams.set(`pk`,publicKey),next.toString()}export{withPublicKey};
|