chore(lib/react)!: remove jsx-runtime
This has been made because no developer will likely ever require this API. The current API assumes you already have an instance of the component, which means you can likely already patch that component instance itself. The API can be made more powerful by taking any string names, and comparing it to the component's type name, type displayName, name, displayName, etc., but it will introduce performance bottlenecks.
This commit is contained in:
parent
f824778519
commit
8347e24e54
7 changed files with 1 additions and 165 deletions
|
|
@ -1,14 +1,11 @@
|
|||
import * as PluginApiReact_ from '@revenge-mod/react'
|
||||
import * as PluginApiReactJsxRuntime from '@revenge-mod/react/jsx-runtime'
|
||||
import * as PluginApiReactNative from '@revenge-mod/react/native'
|
||||
|
||||
export type PluginApiReact = typeof PluginApiReact_ & {
|
||||
jsxRuntime: typeof PluginApiReactJsxRuntime
|
||||
native: typeof PluginApiReactNative
|
||||
}
|
||||
|
||||
export const react: PluginApiReact = {
|
||||
...PluginApiReact_,
|
||||
jsxRuntime: PluginApiReactJsxRuntime,
|
||||
native: PluginApiReactNative,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,18 +6,12 @@
|
|||
".": {
|
||||
"default": "./src/index.ts"
|
||||
},
|
||||
"./jsx-runtime": {
|
||||
"default": "./src/jsx-runtime/index.ts"
|
||||
},
|
||||
"./native": {
|
||||
"default": "./src/native/index.ts"
|
||||
},
|
||||
"./preinit": {
|
||||
"default": "./src/preinit.ts"
|
||||
},
|
||||
"./init": {
|
||||
"default": "./src/init.ts"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./src/types.ts"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
import './jsx-runtime/patches'
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import type { ElementType } from 'react'
|
||||
import type { AfterJSXCallback, BeforeJSXCallback, InsteadJSXCallback } from '.'
|
||||
|
||||
export const jPatches = new Map<
|
||||
ElementType | string,
|
||||
[
|
||||
before?: Set<BeforeJSXCallback>,
|
||||
after?: Set<AfterJSXCallback>,
|
||||
instead?: Set<InsteadJSXCallback>,
|
||||
]
|
||||
>()
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
import { jPatches } from './_internal'
|
||||
import type { ComponentProps, ElementType, Key, ReactElement } from 'react'
|
||||
import type { ReactJSXRuntime } from '..'
|
||||
|
||||
export type AnyJSXFactoryFunction = (typeof ReactJSXRuntime)['jsx' | 'jsxs']
|
||||
|
||||
export type BeforeJSXCallback<
|
||||
E extends ElementType = ElementType,
|
||||
P = ComponentProps<E>,
|
||||
> = (
|
||||
args: [element: E, props: P, key?: Key | undefined],
|
||||
) => Parameters<AnyJSXFactoryFunction>
|
||||
|
||||
export type InsteadJSXCallback<
|
||||
E extends ElementType = ElementType,
|
||||
P = ComponentProps<E>,
|
||||
> = (
|
||||
args: [element: E, props: P, key?: Key | undefined],
|
||||
jsx: AnyJSXFactoryFunction,
|
||||
) => ReturnType<AnyJSXFactoryFunction> | null
|
||||
|
||||
export type AfterJSXCallback = (
|
||||
fiber: ReactElement,
|
||||
) => ReturnType<AnyJSXFactoryFunction> | null
|
||||
|
||||
/**
|
||||
* Registers a hook to be called after a JSX element with the specified type is created.
|
||||
*
|
||||
* @param type The type of the element.
|
||||
* @param patch The hook.
|
||||
* @returns A function to unpatch.
|
||||
*/
|
||||
export function afterJSX(type: ElementType, patch: AfterJSXCallback) {
|
||||
let patches = jPatches.get(type)
|
||||
if (!patches) {
|
||||
patches = [undefined, new Set(), undefined]
|
||||
jPatches.set(type, patches)
|
||||
}
|
||||
|
||||
const set = patches[1]!
|
||||
|
||||
set.add(patch as AfterJSXCallback)
|
||||
return () => {
|
||||
const res = set.delete(patch as AfterJSXCallback)
|
||||
if (res) attemptCleanup(type)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a hook to be called before a JSX element with the specified type is created.
|
||||
*
|
||||
* @param type The type of the element.
|
||||
* @param patch The hook.
|
||||
* @returns A function to unpatch.
|
||||
*/
|
||||
export function beforeJSX<
|
||||
E extends ElementType = ElementType,
|
||||
P = ComponentProps<E>,
|
||||
>(type: E, patch: BeforeJSXCallback<E, P>) {
|
||||
let patches = jPatches.get(type)
|
||||
if (!patches) {
|
||||
patches = [new Set(), undefined, undefined]
|
||||
jPatches.set(type, patches)
|
||||
}
|
||||
|
||||
const set = patches[0]!
|
||||
|
||||
set.add(patch as BeforeJSXCallback)
|
||||
return () => {
|
||||
const res = set.delete(patch as BeforeJSXCallback)
|
||||
if (res) attemptCleanup(type)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback to run instead when a JSX element with the specified type is created.
|
||||
*
|
||||
* @param type The type of the element.
|
||||
* @param patch The hook.
|
||||
* @returns A function to unpatch.
|
||||
*/
|
||||
export function insteadJSX<
|
||||
E extends ElementType = ElementType,
|
||||
P = ComponentProps<E>,
|
||||
>(type: E, patch: InsteadJSXCallback<E, P>) {
|
||||
let patches = jPatches.get(type)
|
||||
if (!patches) {
|
||||
patches = [undefined, undefined, new Set()]
|
||||
jPatches.set(type, patches)
|
||||
}
|
||||
|
||||
const set = patches[2]!
|
||||
|
||||
set.add(patch as InsteadJSXCallback)
|
||||
return () => {
|
||||
const res = set.delete(patch as InsteadJSXCallback)
|
||||
if (res) attemptCleanup(type)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
function attemptCleanup(type: ElementType) {
|
||||
const patches = jPatches.get(type)!
|
||||
if (patches[0]?.size || patches[1]?.size || patches[2]?.size) return
|
||||
jPatches.delete(type)
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
import { instead } from '@revenge-mod/patcher'
|
||||
import { ReactJSXRuntime } from '..'
|
||||
import { jPatches } from './_internal'
|
||||
import type { ReactElement } from 'react'
|
||||
import type { AnyJSXFactoryFunction } from '.'
|
||||
|
||||
const jsx = ReactJSXRuntime.jsx
|
||||
|
||||
const patch = (
|
||||
args: Parameters<AnyJSXFactoryFunction>,
|
||||
orig: AnyJSXFactoryFunction,
|
||||
) => {
|
||||
const [type] = args
|
||||
const patches = jPatches.get(type)
|
||||
if (!patches) return Reflect.apply(orig, ReactJSXRuntime, args)
|
||||
|
||||
const [before, after, instead] = patches
|
||||
|
||||
if (before) for (const cb of before) args = cb(args)
|
||||
|
||||
let fiber: ReactElement | null | undefined
|
||||
|
||||
// If there are instead patches, fiber will always be set by the instead patches
|
||||
if (instead) for (const cb of instead) fiber = cb(args, jsx)
|
||||
// If there aren't any instead patches, we compute the fiber normally, and it will be set
|
||||
else fiber = Reflect.apply(orig, ReactJSXRuntime, args)
|
||||
|
||||
if (after) for (const cb of after) fiber = cb(fiber!)
|
||||
|
||||
return fiber!
|
||||
}
|
||||
|
||||
instead(ReactJSXRuntime, 'jsx', patch)
|
||||
instead(ReactJSXRuntime, 'jsxs', patch)
|
||||
|
|
@ -37,11 +37,10 @@ onModuleFirstRequired(IndexModuleId, function onIndexRequired() {
|
|||
)
|
||||
|
||||
// Initialize init libraries
|
||||
require('@revenge-mod/react/init')
|
||||
require('@revenge-mod/storage/init')
|
||||
require('@revenge-mod/externals/init')
|
||||
require('@revenge-mod/discord/init')
|
||||
require('@revenge-mod/components/init')
|
||||
require('@revenge-mod/externals/init')
|
||||
|
||||
// Run all init plugins
|
||||
require('~/plugins/init')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue