bippy
Version:
hack into react internals
120 lines (118 loc) • 3.91 kB
JavaScript
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { getRDTHook$1 as getRDTHook, hasRDTHook$1 as hasRDTHook } from "./rdt-hook-D8LwQB-4.js";
//#region src/override.ts
let _overrideProps = null;
let _overrideHookState = null;
let _overrideContext = null;
const injectOverrideMethods = () => {
if (!hasRDTHook()) return null;
const rdtHook = getRDTHook();
if (!rdtHook?.renderers) return null;
if (_overrideProps || _overrideHookState || _overrideContext) return {
overrideProps: _overrideProps,
overrideHookState: _overrideHookState,
overrideContext: _overrideContext
};
for (const [_, renderer] of Array.from(rdtHook.renderers)) try {
if (_overrideHookState) {
const prevOverrideHookState = _overrideHookState;
_overrideHookState = (fiber, id, path, value) => {
let current = fiber.memoizedState;
for (let i = 0; i < Number(id); i++) {
if (!current?.next) break;
current = current.next;
}
if (current?.queue) {
const queue = current.queue;
if (isPOJO(queue) && "dispatch" in queue) {
const dispatch = queue.dispatch;
dispatch(value);
return;
}
}
prevOverrideHookState(fiber, id, path, value);
renderer.overrideHookState?.(fiber, id, path, value);
};
} else if (renderer.overrideHookState) _overrideHookState = renderer.overrideHookState;
if (_overrideProps) {
const prevOverrideProps = _overrideProps;
_overrideProps = (fiber, path, value) => {
prevOverrideProps(fiber, path, value);
renderer.overrideProps?.(fiber, path, value);
};
} else if (renderer.overrideProps) _overrideProps = renderer.overrideProps;
_overrideContext = (fiber, contextType, path, value) => {
let current = fiber;
while (current) {
const type = current.type;
if (type === contextType || type?.Provider === contextType) {
if (_overrideProps) {
_overrideProps(current, ["value", ...path], value);
if (current.alternate) _overrideProps(current.alternate, ["value", ...path], value);
}
break;
}
current = current.return;
}
};
} catch {}
};
const isPOJO = (maybePOJO) => {
return Object.prototype.toString.call(maybePOJO) === "[object Object]" && (Object.getPrototypeOf(maybePOJO) === Object.prototype || Object.getPrototypeOf(maybePOJO) === null);
};
const buildPathsFromValue = (maybePOJO, basePath = []) => {
if (!isPOJO(maybePOJO)) return [{
path: basePath,
value: maybePOJO
}];
const paths = [];
for (const key in maybePOJO) {
const value = maybePOJO[key];
const path = basePath.concat(key);
if (isPOJO(value)) paths.push(...buildPathsFromValue(value, path));
else paths.push({
path,
value
});
}
return paths;
};
const overrideProps = (fiber, partialValue) => {
injectOverrideMethods();
const paths = buildPathsFromValue(partialValue);
for (const { path, value } of paths) try {
_overrideProps?.(fiber, path, value);
} catch {}
};
const overrideHookState = (fiber, id, partialValue) => {
injectOverrideMethods();
const hookId = String(id);
if (isPOJO(partialValue)) {
const paths = buildPathsFromValue(partialValue);
for (const { path, value } of paths) try {
_overrideHookState?.(fiber, hookId, path, value);
} catch {}
} else try {
_overrideHookState?.(fiber, hookId, [], partialValue);
} catch {}
};
const overrideContext = (fiber, contextType, partialValue) => {
injectOverrideMethods();
if (isPOJO(partialValue)) {
const paths = buildPathsFromValue(partialValue);
for (const { path, value } of paths) try {
_overrideContext?.(fiber, contextType, path, value);
} catch {}
} else try {
_overrideContext?.(fiber, contextType, [], partialValue);
} catch {}
};
//#endregion
export { injectOverrideMethods, overrideContext, overrideHookState, overrideProps };