bippy 0.7.2-dev.23cd194 → 0.7.2-dev.e113600
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 +0 -68
- package/dist/core.cjs +1 -1
- package/dist/core.js +1 -1
- package/dist/errors.d.cts +56 -9
- package/dist/errors.d.ts +56 -9
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +8 -35
- package/dist/index.d.ts +8 -35
- package/dist/index.js +1 -1
- package/dist/install-hook-only.cjs +1 -1
- package/dist/install-hook-only.js +1 -1
- package/dist/rdt-hook.cjs +1 -1
- package/dist/rdt-hook.js +1 -1
- package/dist/source.cjs +10 -9
- package/dist/source.d.cts +36 -9
- package/dist/source.d.ts +36 -9
- package/dist/source.js +13 -12
- package/package.json +7 -7
- package/src/core.ts +134 -55
- package/src/rdt-hook.ts +126 -70
- package/src/react-internals/types.ts +33 -6
- package/src/react.ts +1 -0
- package/src/source/constants.ts +1 -3
- package/src/source/get-display-name-from-source.ts +10 -3
- package/src/source/get-source.ts +39 -19
- package/src/source/index.ts +17 -3
- package/src/source/inspect-hooks.ts +169 -28
- package/src/source/owner-stack.ts +43 -35
- package/src/source/parse-hook-names.ts +15 -8
- package/src/source/parse-stack.ts +3 -1
- package/src/source/renderer-dispatchers.ts +9 -4
- package/src/source/symbolication.ts +53 -32
|
@@ -39,6 +39,7 @@ export interface SourceFetch {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export interface SourceMapRequestOptions {
|
|
42
|
+
allowCrossOriginSourceMap?: boolean;
|
|
42
43
|
allowUnsafeServerFetch?: boolean;
|
|
43
44
|
maxBundleSizeBytes?: number;
|
|
44
45
|
maxSourceMapSizeBytes?: number;
|
|
@@ -49,6 +50,7 @@ export interface SourceMapRequestOptions {
|
|
|
49
50
|
export interface SourceMap {
|
|
50
51
|
file?: string;
|
|
51
52
|
ignoredSourceIndices?: Set<number>;
|
|
53
|
+
sourceMapUrl?: string;
|
|
52
54
|
mappings: SourceMapSegment[][];
|
|
53
55
|
names?: string[];
|
|
54
56
|
sections?: DecodedSourceMapSection[];
|
|
@@ -298,10 +300,14 @@ const resolveUrl = (reference: string, baseUrl: string): string | null => {
|
|
|
298
300
|
return new URL(reference, baseUrl).toString();
|
|
299
301
|
} catch {
|
|
300
302
|
try {
|
|
301
|
-
|
|
302
|
-
return `${resolvedUrl.pathname}${resolvedUrl.search}${resolvedUrl.hash}`;
|
|
303
|
+
return new URL(reference).toString();
|
|
303
304
|
} catch {
|
|
304
|
-
|
|
305
|
+
try {
|
|
306
|
+
const resolvedUrl = new URL(reference, new URL(baseUrl, "https://bippy.invalid/"));
|
|
307
|
+
return `${resolvedUrl.pathname}${resolvedUrl.search}${resolvedUrl.hash}`;
|
|
308
|
+
} catch {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
305
311
|
}
|
|
306
312
|
}
|
|
307
313
|
};
|
|
@@ -460,6 +466,11 @@ const resolveSourceMapSources = (rawSourceMap: StandardSourceMap, sourceMapUrl:
|
|
|
460
466
|
resolveSourceRoot(rawSourceMap.sourceRoot, source, sourceMapUrl),
|
|
461
467
|
);
|
|
462
468
|
|
|
469
|
+
// An inline URL carries the whole encoded map, so retaining it in the cache would
|
|
470
|
+
// double the memory held per source map for the lifetime of the process.
|
|
471
|
+
const getRetainableSourceMapUrl = (sourceMapUrl: string): string | undefined =>
|
|
472
|
+
INLINE_SOURCEMAP_REGEX.test(sourceMapUrl) ? undefined : sourceMapUrl;
|
|
473
|
+
|
|
463
474
|
const decodeStandardSourceMap = (
|
|
464
475
|
rawSourceMap: StandardSourceMap,
|
|
465
476
|
sourceMapUrl: string,
|
|
@@ -470,6 +481,7 @@ const decodeStandardSourceMap = (
|
|
|
470
481
|
ignoredSourceIndices: getIgnoredSourceIndices(rawSourceMap),
|
|
471
482
|
mappings: decode(rawSourceMap.mappings),
|
|
472
483
|
names: rawSourceMap.names,
|
|
484
|
+
sourceMapUrl: getRetainableSourceMapUrl(sourceMapUrl),
|
|
473
485
|
sourceRoot: rawSourceMap.sourceRoot,
|
|
474
486
|
sources: resolveSourceMapSources(rawSourceMap, sourceMapUrl),
|
|
475
487
|
sourcesContent: rawSourceMap.sourcesContent,
|
|
@@ -532,6 +544,7 @@ const decodeIndexSourceMap = async (
|
|
|
532
544
|
mappings: [],
|
|
533
545
|
names: [],
|
|
534
546
|
sections: decodedSections,
|
|
547
|
+
sourceMapUrl: getRetainableSourceMapUrl(sourceMapUrl),
|
|
535
548
|
sourceRoot: undefined,
|
|
536
549
|
sources: Array.from(allSources),
|
|
537
550
|
sourcesContent: undefined,
|
|
@@ -782,22 +795,23 @@ const readSourceMapDocument = async (
|
|
|
782
795
|
|
|
783
796
|
const getSourceMapUncachedInternal = async (
|
|
784
797
|
bundleUrl: string,
|
|
785
|
-
|
|
798
|
+
sourceFetchOverride?: SourceFetch,
|
|
786
799
|
options: SourceMapRequestOptions = {},
|
|
787
800
|
): Promise<null | SourceMap> => {
|
|
788
|
-
const shouldAllowCustomProtocol =
|
|
801
|
+
const shouldAllowCustomProtocol = sourceFetchOverride !== undefined;
|
|
789
802
|
if (!isFetchableUrl(bundleUrl, shouldAllowCustomProtocol)) {
|
|
790
803
|
return null;
|
|
791
804
|
}
|
|
792
805
|
|
|
793
806
|
const isServer = isServerRuntime();
|
|
794
|
-
const shouldRejectRedirects =
|
|
795
|
-
|
|
807
|
+
const shouldRejectRedirects =
|
|
808
|
+
(isServer || isExtensionUrl(bundleUrl)) && !options.allowCrossOriginSourceMap;
|
|
809
|
+
if (isServer && !sourceFetchOverride) {
|
|
796
810
|
if (!options.allowUnsafeServerFetch || !isAbsoluteHttpUrl(bundleUrl)) return null;
|
|
797
811
|
}
|
|
798
812
|
|
|
799
813
|
const sourceFetch =
|
|
800
|
-
|
|
814
|
+
sourceFetchOverride ??
|
|
801
815
|
(typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : undefined);
|
|
802
816
|
if (!sourceFetch) return null;
|
|
803
817
|
const maxBundleSizeBytes = options.maxBundleSizeBytes ?? defaultMaxBundleSizeBytes;
|
|
@@ -864,11 +878,11 @@ const getSourceMapUncachedInternal = async (
|
|
|
864
878
|
|
|
865
879
|
export const getSourceMapUncached = async (
|
|
866
880
|
bundleUrl: string,
|
|
867
|
-
|
|
881
|
+
sourceFetch?: SourceFetch,
|
|
868
882
|
options: SourceMapRequestOptions = {},
|
|
869
883
|
): Promise<null | SourceMap> => {
|
|
870
884
|
try {
|
|
871
|
-
return await getSourceMapUncachedInternal(bundleUrl,
|
|
885
|
+
return await getSourceMapUncachedInternal(bundleUrl, sourceFetch, options);
|
|
872
886
|
} catch (error) {
|
|
873
887
|
if (error instanceof TransientSourceMapError) return null;
|
|
874
888
|
throw error;
|
|
@@ -878,66 +892,67 @@ export const getSourceMapUncached = async (
|
|
|
878
892
|
const getPerFetchMap = <Value>(
|
|
879
893
|
mapsByFetch: WeakMap<SourceFetch, Map<string, Value>>,
|
|
880
894
|
globalMap: Map<string, Value>,
|
|
881
|
-
|
|
895
|
+
sourceFetch: SourceFetch | undefined,
|
|
882
896
|
): Map<string, Value> => {
|
|
883
|
-
if (!
|
|
884
|
-
let map = mapsByFetch.get(
|
|
897
|
+
if (!sourceFetch) return globalMap;
|
|
898
|
+
let map = mapsByFetch.get(sourceFetch);
|
|
885
899
|
if (!map) {
|
|
886
900
|
map = new Map();
|
|
887
|
-
mapsByFetch.set(
|
|
901
|
+
mapsByFetch.set(sourceFetch, map);
|
|
888
902
|
}
|
|
889
903
|
return map;
|
|
890
904
|
};
|
|
891
905
|
|
|
892
|
-
const getSourceMapCache = (
|
|
893
|
-
getPerFetchMap(sourceMapCachesByFetch, sourceMapCache,
|
|
906
|
+
const getSourceMapCache = (sourceFetch: SourceFetch | undefined): Map<string, null | SourceMap> =>
|
|
907
|
+
getPerFetchMap(sourceMapCachesByFetch, sourceMapCache, sourceFetch);
|
|
894
908
|
|
|
895
909
|
const getPendingSourceMapRequests = (
|
|
896
|
-
|
|
910
|
+
sourceFetch: SourceFetch | undefined,
|
|
897
911
|
): Map<string, Promise<SourceMapResult>> =>
|
|
898
|
-
getPerFetchMap(pendingSourceMapRequestsByFetch, pendingSourceMapRequests,
|
|
912
|
+
getPerFetchMap(pendingSourceMapRequestsByFetch, pendingSourceMapRequests, sourceFetch);
|
|
899
913
|
|
|
900
914
|
const getSourceMapCacheKey = (file: string, options: SourceMapRequestOptions): string =>
|
|
915
|
+
options.allowCrossOriginSourceMap === undefined &&
|
|
901
916
|
options.allowUnsafeServerFetch === undefined &&
|
|
902
917
|
options.maxBundleSizeBytes === undefined &&
|
|
903
918
|
options.maxSourceMapSizeBytes === undefined &&
|
|
904
919
|
options.timeoutMs === undefined
|
|
905
920
|
? file
|
|
906
|
-
: `${file}\0${options.allowUnsafeServerFetch ?? ""}\0${options.maxBundleSizeBytes ?? ""}\0${options.maxSourceMapSizeBytes ?? ""}\0${options.timeoutMs ?? ""}`;
|
|
921
|
+
: `${file}\0${options.allowCrossOriginSourceMap ?? ""}\0${options.allowUnsafeServerFetch ?? ""}\0${options.maxBundleSizeBytes ?? ""}\0${options.maxSourceMapSizeBytes ?? ""}\0${options.timeoutMs ?? ""}`;
|
|
907
922
|
|
|
908
923
|
export const getSourceMap = async (
|
|
909
924
|
file: string,
|
|
910
|
-
|
|
911
|
-
|
|
925
|
+
shouldUseCache = true,
|
|
926
|
+
sourceFetch?: SourceFetch,
|
|
912
927
|
options: SourceMapRequestOptions = {},
|
|
913
928
|
): Promise<null | SourceMap> => {
|
|
914
|
-
const
|
|
915
|
-
const cache = getSourceMapCache(
|
|
916
|
-
const pendingRequests = getPendingSourceMapRequests(
|
|
929
|
+
const canUseCache = shouldUseCache && options.signal === undefined;
|
|
930
|
+
const cache = getSourceMapCache(sourceFetch);
|
|
931
|
+
const pendingRequests = getPendingSourceMapRequests(sourceFetch);
|
|
917
932
|
const cacheKey = getSourceMapCacheKey(file, options);
|
|
918
|
-
if (
|
|
933
|
+
if (canUseCache && cache.has(cacheKey)) {
|
|
919
934
|
return cache.get(cacheKey) ?? null;
|
|
920
935
|
}
|
|
921
936
|
|
|
922
|
-
const pendingRequest =
|
|
937
|
+
const pendingRequest = canUseCache ? pendingRequests.get(cacheKey) : undefined;
|
|
923
938
|
if (pendingRequest) {
|
|
924
939
|
return (await pendingRequest).sourceMap;
|
|
925
940
|
}
|
|
926
941
|
|
|
927
942
|
const fetchPromise: Promise<SourceMapResult> = getSourceMapUncachedInternal(
|
|
928
943
|
file,
|
|
929
|
-
|
|
944
|
+
sourceFetch,
|
|
930
945
|
options,
|
|
931
946
|
).then(
|
|
932
947
|
(sourceMap) => ({ sourceMap, isTransientFailure: false }),
|
|
933
948
|
() => ({ sourceMap: null, isTransientFailure: true }),
|
|
934
949
|
);
|
|
935
|
-
if (
|
|
950
|
+
if (canUseCache) {
|
|
936
951
|
pendingRequests.set(cacheKey, fetchPromise);
|
|
937
952
|
}
|
|
938
953
|
|
|
939
954
|
const { sourceMap, isTransientFailure } = await fetchPromise;
|
|
940
|
-
if (
|
|
955
|
+
if (canUseCache) {
|
|
941
956
|
pendingRequests.delete(cacheKey);
|
|
942
957
|
if (!isTransientFailure) {
|
|
943
958
|
cache.set(cacheKey, sourceMap);
|
|
@@ -949,13 +964,19 @@ export const getSourceMap = async (
|
|
|
949
964
|
|
|
950
965
|
export const symbolicateStack = async (
|
|
951
966
|
stack: StackFrame[],
|
|
952
|
-
|
|
953
|
-
|
|
967
|
+
shouldUseCache = true,
|
|
968
|
+
sourceFetch?: SourceFetch,
|
|
969
|
+
requestOptions: SourceMapRequestOptions = {},
|
|
954
970
|
): Promise<StackFrame[]> => {
|
|
955
971
|
return Promise.all(
|
|
956
972
|
stack.map(async (stackFrame) => {
|
|
957
973
|
if (!stackFrame.fileName) return stackFrame;
|
|
958
|
-
const sourceMap = await getSourceMap(
|
|
974
|
+
const sourceMap = await getSourceMap(
|
|
975
|
+
stackFrame.fileName,
|
|
976
|
+
shouldUseCache,
|
|
977
|
+
sourceFetch,
|
|
978
|
+
requestOptions,
|
|
979
|
+
);
|
|
959
980
|
if (
|
|
960
981
|
!sourceMap ||
|
|
961
982
|
typeof stackFrame.lineNumber !== "number" ||
|