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
9 changes: 9 additions & 0 deletions .changeset/profile-safety-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@lynx-js/react': patch
---

Add safety checks for compilation macros to prevent runtime errors when they are undefined.

Replaces direct usage of `__PROFILE__`, `__MAIN_THREAD__`, `__BACKGROUND__` with `typeof` checks.

This improves robustness by checking variable existence before access, preventing runtime errors in environments where compilation macros are not defined.
6 changes: 4 additions & 2 deletions packages/react/components/src/DeferredListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export interface DeferredListItemProps {
}

export const DeferredListItem: FC<DeferredListItemProps> = ({ defer, renderListItem, renderChildren }) => {
const __cloneElement = __MAIN_THREAD__ ? _cloneElementMainThread : _cloneElement;
const __cloneElement = typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__
? _cloneElementMainThread
: _cloneElement;

const initialDeferRef = useRef(defer);
const prevDeferRef = useRef(defer);
Expand All @@ -42,7 +44,7 @@ export const DeferredListItem: FC<DeferredListItemProps> = ({ defer, renderListI
};
}, []);

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
if (prevDeferRef.current && !defer) {
setIsReady(true);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/alog/elementPAPICall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ export function initElementPAPICallAlog(globalWithIndex: Record<string, unknown>
const oldFiberElementPAPI = globalWithIndex[fiberElementPAPIName];
if (typeof oldFiberElementPAPI === 'function') {
globalWithIndex[fiberElementPAPIName] = (...args: unknown[]): unknown => {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart(`FiberElementPAPI: ${fiberElementPAPIName}`, {
args: {
args: JSON.stringify(args),
},
});
}
const result = (oldFiberElementPAPI as (...args: unknown[]) => unknown)(...args);
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}

Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/alog/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export function initRenderAlog(): void {
const threadName = __MAIN_THREAD__ ? 'MainThread' : 'BackgroundThread';
const displayName = getDisplayName(vnode.type as ComponentClass);
// log the component render into Alog
if (__MAIN_THREAD__) {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
console.alog?.(
`[${threadName} Component Render] name: ${displayName}`,
);
} else if (__BACKGROUND__) {
} else if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
const dom = vnode[DOM];
console.alog?.(
`[${threadName} Component Render] name: ${displayName}, uniqID: ${dom?.type}, __id: ${dom?.__id}`,
Expand Down
6 changes: 3 additions & 3 deletions packages/react/runtime/src/backgroundSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class BackgroundSnapshotInstance {
}

setAttribute(key: string | number, value: unknown): void {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::BSI::setAttribute');
}
if (key === 'values') {
Expand Down Expand Up @@ -286,7 +286,7 @@ export class BackgroundSnapshotInstance {
});
}
this.__values = value as unknown[];
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
return;
Expand All @@ -305,7 +305,7 @@ export class BackgroundSnapshotInstance {
key,
value,
);
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/react/runtime/src/debug/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function initProfileHook(): void {
const sFlowID = Symbol('FLOW_ID');
type PatchedComponent = Component & { [sFlowID]?: number };

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
function buildSetStateProfileMarkArgs(
currentState: Record<string, unknown>,
nextState: Record<string, unknown>,
Expand Down Expand Up @@ -84,7 +84,7 @@ export function initProfileHook(): void {
if (typeof vnode.type === 'function') {
const profileOptions: TraceOption = {};

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
const c: PatchedComponent = oldVNode[COMPONENT]!;
if (c) {
const flowId = c[sFlowID];
Expand Down Expand Up @@ -112,7 +112,7 @@ export function initProfileHook(): void {
old?.(vnode);
});

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
hook(options, COMMIT, (old, vnode, commitQueue) => {
profileStart('ReactLynx::commit', {
...globalPatchOptions.flowIds
Expand Down Expand Up @@ -144,7 +144,7 @@ export function initProfileHook(): void {
old?.(vnode);
});

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
const sPatchLength = Symbol('PATCH_LENGTH');

type PatchedVNode = VNode & { [sPatchLength]?: number };
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export function hydrate(before: SnapshotInstance, after: SnapshotInstance, optio
updateAction,
};

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::listHydrate::updateListInfo', {
args: {
'list id': String(listID),
Expand All @@ -403,7 +403,7 @@ export function hydrate(before: SnapshotInstance, after: SnapshotInstance, optio
// avoid the newly created list's (behind snapshot instance `after`) "update-list-info" being recorded.
__pendingListUpdates.clear(after.__id);

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/lifecycle/destroy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { globalCommitTaskMap } from './patch/commit.js';
import { profileEnd, profileStart } from '../debug/utils.js';

function destroyBackground(): void {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::destroyBackground');
}

Expand All @@ -27,7 +27,7 @@ function destroyBackground(): void {
if (delayedEvents) {
delayedEvents.length = 0;
}
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/react/runtime/src/lifecycle/event/jsReady.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ let jsReadyEventIdSwap: Record<string | number, number>;
function jsReady(): void {
isJSReady = true;

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::transferRoot');
profileStart('ReactLynx::serializeRoot');
}
const root = JSON.stringify(__root);
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
__OnLifecycleEvent([
Expand All @@ -26,7 +26,7 @@ function jsReady(): void {
jsReadyEventIdSwap,
},
]);
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
jsReadyEventIdSwap = {};
Expand Down
6 changes: 3 additions & 3 deletions packages/react/runtime/src/lifecycle/patch/commit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function replaceCommitHook(): void {
commitQueue,
) => {
// Skip commit phase for MT runtime
if (__MAIN_THREAD__) {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
// for testing only
commitQueue.length = 0;
return;
Expand Down Expand Up @@ -193,7 +193,7 @@ function commitPatchUpdate(patchList: PatchList, patchOptions: GlobalPatchOption
// );
// console.debug('commitPatchUpdate:', prettyFormatSnapshotPatch(patchList.patchList[0]?.snapshotPatch));

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::commitChanges');
}
markTiming('packChangesStart');
Expand All @@ -212,7 +212,7 @@ function commitPatchUpdate(patchList: PatchList, patchOptions: GlobalPatchOption
obj.patchOptions.pipelineOptions = globalPipelineOptions;
setPipeline(undefined);
}
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}

Expand Down
8 changes: 4 additions & 4 deletions packages/react/runtime/src/lifecycle/reload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { renderMainThread } from './render.js';
import { profileEnd, profileStart } from '../debug/utils.js';

function reloadMainThread(data: unknown, options: UpdatePageOption): void {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::reloadMainThread');
}

Expand Down Expand Up @@ -62,14 +62,14 @@ function reloadMainThread(data: unknown, options: UpdatePageOption): void {

__FlushElementTree(__page, options);

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
return;
}

function reloadBackground(updateData: Record<string, any>): void {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::reloadBackground');
}

Expand All @@ -86,7 +86,7 @@ function reloadBackground(updateData: Record<string, any>): void {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
render(__root.__jsx, __root as any);

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/react/runtime/src/lifecycle/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import { SnapshotInstance } from '../snapshot.js';
function renderMainThread(): void {
let opcodes;
try {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::renderMainThread');
}
opcodes = renderToString(__root.__jsx, undefined);
} catch (e) {
lynx.reportError(e as Error);
opcodes = [];
} finally {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand All @@ -40,15 +40,15 @@ function renderMainThread(): void {
});
}

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::renderOpcodes');
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
renderOpcodesInto(opcodes, __root as any);
if (__ENABLE_SSR__) {
__root.__opcodes = opcodes;
}
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/listUpdateInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class ListUpdateInfoRecording implements ListUpdateInfo {
// });
const updateListInfo = this.__toAttribute();

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
const listID = __GetElementUniqueID(listElement);
profileStart(`ReactLynx::listFlush::updateListInfo`, {
args: {
Expand All @@ -104,7 +104,7 @@ export class ListUpdateInfoRecording implements ListUpdateInfo {
componentAtIndexes,
);

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
return this.list.__id;
Expand Down
6 changes: 3 additions & 3 deletions packages/react/runtime/src/lynx-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,16 @@ export interface Root {
export const root: Root = {
render: (jsx: ReactNode): void => {
/* v8 ignore next 2 */
if (__MAIN_THREAD__) {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
__root.__jsx = jsx;
} else {
__root.__jsx = jsx;
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('ReactLynx::renderBackground');
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
render(jsx, __root as any);
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}
if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {
Expand Down
8 changes: 4 additions & 4 deletions packages/react/runtime/src/lynx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import { injectUpdateMTRefInitValue } from './worklet/ref/updateInitValue.js';
export { runWithForce } from './lynx/runWithForce.js';

// @ts-expect-error Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature
if (__MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
// @ts-expect-error Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature
globalThis.processEvalResult = <T>(result: ((schema: string) => T) | undefined, schema: string) => {
return result?.(schema);
};
}

if (__MAIN_THREAD__) {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
injectCalledByNative();
injectUpdateMainThread();
injectUpdateMTRefInitValue();
Expand All @@ -44,7 +44,7 @@ if (__DEV__) {
}

// We are profiling both main-thread and background.
if (__MAIN_THREAD__ && __PROFILE__) {
if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
initProfileHook();
}

Expand All @@ -53,7 +53,7 @@ if (typeof __ALOG__ !== 'undefined' && __ALOG__) {
initAlog();
}

if (__BACKGROUND__) {
if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
// Trick Preact and TypeScript to accept our custom document adapter.
options.document = document as unknown as Document;
options.requestAnimationFrame = lynxQueueMicrotask;
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/lynx/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function setupLynxEnv(): void {
) {
let hasDefaultDataProcessorExecuted = false;
globalThis.processData = (data, processorName) => {
if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileStart('processData');
}

Expand All @@ -70,7 +70,7 @@ export function setupLynxEnv(): void {
r = {};
}

if (__PROFILE__) {
if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
profileEnd();
}

Expand Down
Loading
Loading