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
8 changes: 3 additions & 5 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,8 @@ export default tseslint.config(
'packages/react/runtime/src/backgroundSnapshot.ts',
'packages/react/runtime/src/compat/**',
'packages/react/runtime/src/debug/**',
'packages/react/runtime/src/hydrate.ts',
'packages/react/runtime/src/list.ts',
'packages/react/runtime/src/lynx-api.ts',
'packages/react/runtime/src/lynx.ts',
'packages/react/runtime/src/opcodes.ts',
'packages/react/runtime/src/snapshot.ts',
'packages/react/runtime/src/utils.ts',

// TODO: enable eslint for tools
// tools
Expand Down Expand Up @@ -275,6 +270,9 @@ export default tseslint.config(
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/consistent-generic-constructors': 'off',
},
},
// JavaScript-related
{
Expand Down
2 changes: 1 addition & 1 deletion packages/react/runtime/src/hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export function hydrate(before: SnapshotInstance, after: SnapshotInstance, optio
}

let swap;
if (swap = options?.swap) {
if ((swap = options?.swap)) {
swap[before.__id] = after.__id;
}

Expand Down
9 changes: 5 additions & 4 deletions packages/react/runtime/src/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function componentAtIndexFactory(
throw new Error('childCtx not found');
}

const platformInfo = childCtx.__listItemPlatformInfo || {};
const platformInfo = childCtx.__listItemPlatformInfo ?? {};

const uniqID = childCtx.type + (platformInfo['reuse-identifier'] ?? '');
const recycleSignMap = recycleMap.get(uniqID);
Expand Down Expand Up @@ -97,7 +97,7 @@ export function componentAtIndexFactory(
if (enableReuseNotification) {
flushOptions.listReuseNotification = {
listElement: list,
itemKey: platformInfo['item-key'],
itemKey: platformInfo['item-key']!,
};
}
__FlushElementTree(root, flushOptions);
Expand All @@ -108,7 +108,7 @@ export function componentAtIndexFactory(
if (enableReuseNotification) {
flushOptions.listReuseNotification = {
listElement: list,
itemKey: platformInfo['item-key'],
itemKey: platformInfo['item-key']!,
};
}
__FlushElementTree(root, flushOptions);
Expand Down Expand Up @@ -161,6 +161,7 @@ export function componentAtIndexFactory(
}

export function enqueueComponentFactory(): EnqueueComponentCallback {
// eslint-disable-next-line unicorn/consistent-function-scoping
const enqueueComponent = (_: FiberElement, listID: number, sign: number) => {
const signMap = gSignMap[listID];
const recycleMap = gRecycleMap[listID];
Expand All @@ -173,7 +174,7 @@ export function enqueueComponentFactory(): EnqueueComponentCallback {
return;
}

const platformInfo = childCtx.__listItemPlatformInfo || {};
const platformInfo = childCtx.__listItemPlatformInfo ?? {};

const uniqID = childCtx.type + (platformInfo['reuse-identifier'] ?? '');
if (!recycleMap.has(uniqID)) {
Expand Down
1 change: 1 addition & 0 deletions packages/react/runtime/src/lynx-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const root: Root = {
__root.__jsx = jsx;
} else {
__root.__jsx = jsx;
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
render(jsx, __root as any);
if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {
// This is for cases where `root.render()` is called asynchronously,
Expand Down
1 change: 1 addition & 0 deletions packages/react/runtime/src/lynx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ if (__PROFILE__) {

if (__BACKGROUND__) {
// Trick Preact and TypeScript to accept our custom document adapter.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
options.document = document as any;
setupBackgroundDocument();
injectTt();
Expand Down
34 changes: 18 additions & 16 deletions packages/react/runtime/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ListUpdateInfoRecording } from './listUpdateInfo.js';
import { __pendingListUpdates } from './pendingListUpdates.js';
import { DynamicPartType } from './snapshot/dynamicPartType.js';
import { snapshotDestroyList } from './snapshot/list.js';
import type { PlatformInfo } from './snapshot/platformInfo.js';
import { unref } from './snapshot/ref.js';
import { isDirectOrDeepEqual } from './utils.js';

Expand Down Expand Up @@ -165,7 +166,7 @@ export const backgroundSnapshotInstanceManager: {
}
const spreadKey = res[2];
if (spreadKey) {
return ctx.__values![expIndex][spreadKey];
return (ctx.__values![expIndex] as { [spreadKey]: unknown })[spreadKey];
} else {
return ctx.__values![expIndex];
}
Expand Down Expand Up @@ -261,7 +262,7 @@ export class SnapshotInstance {
__values?: unknown[] | undefined;
__current_slot_index = 0;
__worklet_ref_set?: Set<WorkletRefImpl<any> | Worklet>;
__listItemPlatformInfo?: any;
__listItemPlatformInfo?: PlatformInfo;

constructor(public type: string, id?: number) {
this.__snapshot_def = snapshotManager.values.get(type)!;
Expand All @@ -270,7 +271,7 @@ export class SnapshotInstance {
throw new Error('Snapshot not found: ' + type);
}

id ||= snapshotInstanceManager.nextId -= 1;
id ??= snapshotInstanceManager.nextId -= 1;
this.__id = id;
snapshotInstanceManager.values.set(id, this);
}
Expand Down Expand Up @@ -579,31 +580,25 @@ export class SnapshotInstance {
}

setAttribute(key: string | number, value: any): void {
const helper = (index: number, oldValue: any, newValue: any) => {
if (isDirectOrDeepEqual(oldValue, newValue)) {}
else {
this.__snapshot_def.update![index]!(this, index, oldValue);
}
};

if (key === 'values') {
const oldValues = this.__values;
this.__values = value;
const values = value as unknown[];
this.__values = values;
if (oldValues) {
for (let index = 0; index < value.length; index++) {
helper(index, oldValues[index], value[index]);
for (let index = 0; index < values.length; index++) {
this.callUpdateIfNotDirectOrDeepEqual(index, oldValues[index], values[index]);
}
} else {
for (let index = 0; index < value.length; index++) {
helper(index, undefined, value[index]);
for (let index = 0; index < values.length; index++) {
this.callUpdateIfNotDirectOrDeepEqual(index, undefined, values[index]);
}
}
return;
}

const index = typeof key === 'string' ? Number(key.slice(2)) : key;
this.__values ??= [];
helper(index, this.__values[index], this.__values[index] = value);
this.callUpdateIfNotDirectOrDeepEqual(index, this.__values[index], this.__values[index] = value);
}

toJSON(): Omit<SerializedSnapshotInstance, 'children'> & { children: SnapshotInstance[] | undefined } {
Expand All @@ -614,4 +609,11 @@ export class SnapshotInstance {
children: this.__firstChild ? this.childNodes : undefined,
};
}

callUpdateIfNotDirectOrDeepEqual(index: number, oldValue: any, newValue: any): void {
if (isDirectOrDeepEqual(oldValue, newValue)) {}
else {
this.__snapshot_def.update![index]!(this, index, oldValue);
}
}
}
13 changes: 12 additions & 1 deletion packages/react/runtime/src/snapshot/platformInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@ const platformInfoAttributes: Set<string> = /* @__PURE__ */ new Set<string>([
'estimated-main-axis-size-px',
]);

export interface PlatformInfo {
'reuse-identifier'?: string;
'full-span'?: boolean;
'item-key'?: string;
'sticky-top'?: boolean;
'sticky-bottom'?: boolean;
'estimated-height'?: number;
'estimated-height-px'?: number;
'estimated-main-axis-size-px'?: number;
}

function updateListItemPlatformInfo(
ctx: SnapshotInstance,
index: number,
oldValue: any,
elementIndex: number,
): void {
const newValue = ctx.__listItemPlatformInfo = ctx.__values![index];
const newValue = ctx.__listItemPlatformInfo = ctx.__values![index] as PlatformInfo;

const list = ctx.parentNode;
if (list?.__snapshot_def.isListHolder) {
Expand Down
4 changes: 2 additions & 2 deletions packages/react/runtime/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export function isSdkVersionGt(major: number, minor: number): boolean {
}

export function pick<T extends object, K extends keyof T>(obj: T, keys: Iterable<K>): Pick<T, K> {
const result: any = {};
const result: Partial<Pick<T, K>> = {};
for (const key of keys) {
if (key in obj) {
result[key] = obj[key];
}
}
return result;
return result as Pick<T, K>;
}
Loading