Skip to content

Commit

Permalink
feat: add beacon request parameters hook
Browse files Browse the repository at this point in the history
This change introduces a new hook called `resolveSendBeaconRequestParameters`. This enables consumers to modify a subset of the RequestInit parameters being used by the fetch request that polyfills the navigator.sendBeacon API in the worker context, e.g. setting keepalive: false
  • Loading branch information
hoebbelsB committed Feb 15, 2024
1 parent 1d2efe0 commit b7fc0a9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
14 changes: 14 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,11 @@ export type SerializedInstance =
*/
export type ResolveUrlType = 'fetch' | 'xhr' | 'script' | 'iframe' | 'image';

/**
* @public
*/
export type SendBeaconParameters = Pick<RequestInit, 'keepalive' | 'mode' | 'headers' | 'signal' | 'cache'>;

/**
* https://partytown.builder.io/configuration
*
Expand All @@ -398,6 +403,15 @@ export interface PartytownConfig {
* @returns The returned value must be a URL interface, otherwise the default resolved URL is used.
*/
resolveUrl?(url: URL, location: Location, type: ResolveUrlType): URL | undefined | null;
/**
* The `resolveSendBeaconRequestParameters()` hook can be used to modify the RequestInit parameters
* being used by the fetch request that polyfills the navigator.sendBeacon API in the worker context.
*
* @param url - The URL to be resolved. This is a URL https://developer.mozilla.org/en-US/docs/Web/API/URL, not a string.
* @param location - The current window location.
* @returns The returned value must be a SendBeaconParameters interface, otherwise the default parameters are used.
*/
resolveSendBeaconRequestParameters?(url: URL, location: Location): SendBeaconParameters | undefined | null;
/**
* When set to `true`, Partytown scripts are not inlined and not minified.
*
Expand Down
34 changes: 26 additions & 8 deletions src/lib/web-worker/worker-exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,7 @@ export const insertIframe = (winId: WinId, iframe: WorkerInstance) => {
callback();
};

export const resolveToUrl = (
env: WebWorkerEnvironment,
url: string,
type: ResolveUrlType | null,
baseLocation?: Location,
resolvedUrl?: URL,
configResolvedUrl?: any
) => {
const resolveBaseLocation = (env: WebWorkerEnvironment, baseLocation?: Location) => {
baseLocation = env.$location$;
while (!baseLocation.host) {
env = environments[env.$parentWinId$];
Expand All @@ -229,7 +222,20 @@ export const resolveToUrl = (
break;
}
}
return baseLocation;
}

export const resolveToUrl = (
env: WebWorkerEnvironment,
url: string,
type: ResolveUrlType | null,
baseLocation?: Location,
resolvedUrl?: URL,
configResolvedUrl?: any
) => {

baseLocation = resolveBaseLocation(env, baseLocation);

resolvedUrl = new URL(url || '', baseLocation as any);
if (type && webWorkerCtx.$config$.resolveUrl) {
configResolvedUrl = webWorkerCtx.$config$.resolveUrl!(resolvedUrl, baseLocation, type!);
Expand All @@ -243,5 +249,17 @@ export const resolveToUrl = (
export const resolveUrl = (env: WebWorkerEnvironment, url: string, type: ResolveUrlType | null) =>
resolveToUrl(env, url, type) + '';

export const resolveSendBeaconRequestParameters = (env: WebWorkerEnvironment, url: string) => {
const baseLocation = resolveBaseLocation(env);
const resolvedUrl = new URL(url || '', baseLocation as any);
if (webWorkerCtx.$config$.resolveSendBeaconRequestParameters) {
const configResolvedParams = webWorkerCtx.$config$.resolveSendBeaconRequestParameters!(resolvedUrl, baseLocation);
if (configResolvedParams) {
return configResolvedParams;
}
}
return {};
}

export const getPartytownScript = () =>
`<script src="${partytownLibUrl('partytown.js?v=' + VERSION)}"></script>`;
3 changes: 2 additions & 1 deletion src/lib/web-worker/worker-navigator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { WebWorkerEnvironment } from '../types';
import { debug } from '../utils';
import { logWorker } from '../log';
import { resolveUrl } from './worker-exec';
import { resolveSendBeaconRequestParameters, resolveUrl } from './worker-exec';
import { webWorkerCtx } from './worker-constants';
import { getter } from './worker-proxy';

Expand All @@ -25,6 +25,7 @@ export const createNavigator = (env: WebWorkerEnvironment) => {
body,
mode: 'no-cors',
keepalive: true,
...(resolveSendBeaconRequestParameters(env, url))
});
return true;
} catch (e) {
Expand Down

0 comments on commit b7fc0a9

Please sign in to comment.