Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions packages/extendify-api/src/esperanto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const { context, logger } = registerContext({
registerPatch(context, {
find: "EsperantoTransport",
replacement: {
match: /(\i\.executeEsperantoCall),(\i\.cancelEsperantoCall),!1/,
replace: "$1,$2,true"
match: /(\i\.executeEsperantoCall),(\i\.cancelEsperantoCall),/,
replace: "$1,$2,true||"
}
});

Expand All @@ -55,10 +55,12 @@ registerEventListener(context, "platformLoaded", async () => {
const transport = await findModuleExport<{
subscribeToTraffic(
callback: (e: {
type: "request" | "response";
type: "request" | "response" | "stream_response" | "error" | "cancel";
id: string;
payload: Uint8Array;
timestamp: number;
code?: number;
message?: string;
payload?: Uint8Array;
method?: string;
service?: string;
isStreaming?: boolean;
Expand All @@ -67,14 +69,20 @@ registerEventListener(context, "platformLoaded", async () => {
}>(exportFilters.byProps("subscribeToTraffic"));

transport.subscribeToTraffic(e => {
const payload = e.payload.length === 0 ? "Empty payload" : e.payload.join(" ");
const payload = !e.payload?.length ? "Empty payload" : e.payload.join(" ");

if (e.type === "response") {
if (e.type === "response" || e.type === "stream_response") {
logger.debug(`Response to ${e.id}:\n${payload}`);
} else if (e.type === "request") {
logger.debug(
`Sending request from ${e.service ?? "UnknownService"}#${e.method ?? "UnknownMethod"} (${e.id}):\n${payload}`
);
} else if (e.type === "error") {
logger.debug(
`${e.message}: ${e.service ?? "UnknownService"}#${e.method ?? "UnknownMethod"} has encountered an error (${e.id}):\n${payload}`
);
} else if (e.type === "cancel") {
logger.debug(`Request with id ${e.id} was cancelled.`);
} else {
logger.warn(`Unknown traffic type ${e.type} (${e.id}):\n${payload}`);
}
Expand Down
8 changes: 3 additions & 5 deletions packages/extendify-entrypoint/src/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ declare global {
export const PLATFORM: TargetPlatform;
/** The urls of the possible entrypoint bundles */
export const ENTRYPOINTS: string[];
/** The name of the webpack chunk in the global window object */
export const WEBPACK_CHUNK: string;

interface Window {
[WEBPACK_CHUNK]?: WebpackChunkGlobal;
/** The name of the webpack chunks in the global window object */
export const WEBPACK_CHUNKS: string[];

interface Window extends Record<WEBPACK_CHUNKS, WebpackChunkGlobal | undefined> {
ExtendifyFragment: symbol;
ExtendifyCreateElement: typeof React.createElement | (() => any);

Expand Down
6 changes: 3 additions & 3 deletions packages/extendify-scripts/src/build/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const entrypoints: Record<TargetPlatform, string[]> = {
desktop: ["xpui-snapshot.js", "xpui.js"]
};

export const webpackChunkName: Record<TargetPlatform, string> = {
browser: "webpackChunkclient_web",
desktop: "webpackChunkclient_web"
export const webpackChunkNames: Record<TargetPlatform, string[]> = {
browser: ["webpackChunkclient_web", "rspackChunkclient_web"],
desktop: ["webpackChunkclient_web", "rspackChunkclient_web"]
};
4 changes: 2 additions & 2 deletions packages/extendify-scripts/src/build/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getKwarg, hasArg } from "@extendify/scripts/args";
import { entrypoints, webpackChunkName } from "@extendify/scripts/build/config";
import { entrypoints, webpackChunkNames } from "@extendify/scripts/build/config";
import { globPlugins } from "@extendify/scripts/build/plugins";
import { getTimeDifference, stringify } from "@extendify/scripts/utils";
import type { TargetPlatform } from "@extendify/shared/types";
Expand Down Expand Up @@ -40,7 +40,7 @@ await Bun.build({
DEVELOPMENT: DEVELOPMENT,
ENTRYPOINTS: entrypoints[PLATFORM],
PLATFORM: PLATFORM,
WEBPACK_CHUNK: webpackChunkName[PLATFORM]
WEBPACK_CHUNKS: webpackChunkNames[PLATFORM]
}),
entrypoints: [ENTRYPOINT],
format: "iife",
Expand Down
17 changes: 0 additions & 17 deletions packages/extendify-webpack/src/exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,6 @@ const { context, logger } = registerContext({
registerPatch(context, {
all: true,
replacement: [
{
/**
* Turn every module into a function instead of an arrow function:
* 1111: (a, b, c) => {} -> 1111: function(a, b, c) {}
* 2222: (a, b) => {} -> 2222: function(a, b) {}
* 3333: a => {} -> 3333: function(a) {}
* 4444: module => {} -> 4444: function(module) {}
* 5555(a, b, c) {} -> 5555: function(a, b, c) {}
* ^ there's one of these that exists where there is only one argument which has a full name (module)
* If the module is already a function, which there is at least one example of, this patch will not apply
*/
match: /(function)?(?:\((.*?)\)(?:=>)?|(.|module)=>){/,
noWarn: true,
replace(match, func, args1, args2) {
return func ? match : `function(${args1 ?? args2}){`;
}
},
{
// Inject the exporter at the very end of the function
match: /}$/,
Expand Down
30 changes: 16 additions & 14 deletions packages/extendify-webpack/src/interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ const logger = createLogger({ name: "WebpackInterceptor" });

let webpackChunk: any[] | undefined;

Object.defineProperty(window, WEBPACK_CHUNK, {
configurable: true,
get: () => webpackChunk,
set(chunk) {
if (chunk?.push && !chunk.push.$$) {
patchPush(chunk);
logger.info(`Patched ${WEBPACK_CHUNK}.push`);

delete window[WEBPACK_CHUNK];
window[WEBPACK_CHUNK] = chunk;
}
for (const chunkName of WEBPACK_CHUNKS) {
Object.defineProperty(window, chunkName, {
configurable: true,
get: () => webpackChunk,
set(chunk) {
if (chunk?.push && !chunk.push.$$) {
patchPush(chunk);
logger.info(`Patched ${chunkName}.push`);

delete window[chunkName];
window[chunkName] = chunk;
}

webpackChunk = chunk;
}
});
webpackChunk = chunk;
}
});
}

Object.defineProperty(Function.prototype, "m", {
configurable: true,
Expand Down
7 changes: 6 additions & 1 deletion packages/extendify-webpack/src/patcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,17 @@ export function patchFactories(factories: Record<number, WebpackModule> | Webpac
}
}

// Spotify only uses modules with deterministic or natural module ids and a modern ES target,
// removing the need for manually converting each factory function type separately in a patch.
// This simple text replacement already handles both cases:
// { 96879(e,t,i){...} } -> function(e,t,i){...}
// [ function(e,t,i){...} ] -> function(e,t,i){...} (unchanged)
function sanitizeSrc(src: string) {
const firstBlock = src.indexOf("{");
const firstParenth = src.indexOf("(");

if (firstParenth < firstBlock && firstParenth !== 0) {
src = src.substring(firstParenth);
src = `function${src.substring(firstParenth)}`;
}

return src.replaceAll("\n", "");
Expand Down
Loading