inital upload
This commit is contained in:
21
node_modules/rehackt/LICENSE.md
generated
vendored
Normal file
21
node_modules/rehackt/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Lenz Weber-Tronic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
100
node_modules/rehackt/README.md
generated
vendored
Normal file
100
node_modules/rehackt/README.md
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
# Rehackt
|
||||
|
||||
> This package is fairly advanced and is only intended for library developers that want to maintain high interop with Next.js server actions.
|
||||
|
||||
Rehackt invisibly wraps `react` so that you're able to use shared imports with `react` in server-side Next.js code without throwing an error to your users.
|
||||
|
||||
## Explainer
|
||||
|
||||
Assume you have the following code in a Next.js codebase:
|
||||
|
||||
```tsx
|
||||
"use client"
|
||||
|
||||
import { useFormState } from "react-dom"
|
||||
import someAction from "./action";
|
||||
|
||||
export const ClientComp = () => {
|
||||
const [data, action] = useFormState(someAction, "Hello client");
|
||||
|
||||
return <form action={action}>
|
||||
<p>{data}</p>
|
||||
<button type={"submit"}>Update data</button>
|
||||
</form>
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
"use server"
|
||||
// action.ts
|
||||
|
||||
import {data} from "./shared-code";
|
||||
|
||||
export default async function someAction() {
|
||||
return "Hello " + data.name;
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// shared-code.ts
|
||||
import {useState} from "react";
|
||||
|
||||
export const data = {
|
||||
useForm: <T>(val: T) => {
|
||||
useState(val)
|
||||
},
|
||||
name: "server"
|
||||
}
|
||||
```
|
||||
|
||||
While you're not intending to use `data.useForm` in your `action.ts` server-only file, you'll still receive the following error from Next.js' build process when trying to use this code:
|
||||
|
||||
```shell
|
||||
./src/app/shared-code.ts
|
||||
ReactServerComponentsError:
|
||||
|
||||
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
|
||||
Learn more: https://nextjs.org/docs/getting-started/react-essentials
|
||||
|
||||
╭─[/src/app/shared-code.ts:1:1]
|
||||
1 │ import {useState} from "react";
|
||||
· ────────
|
||||
2 │
|
||||
3 │ export const data = {
|
||||
3 │ useForm: <T>(val: T) => {
|
||||
╰────
|
||||
|
||||
Maybe one of these should be marked as a client entry with "use client":
|
||||
./src/app/shared-code.ts
|
||||
./src/app/action.ts
|
||||
```
|
||||
|
||||
This is because Next.js statically analyzes usage of `useState` to ensure it's not being utilized in server-only code.
|
||||
|
||||
By replacing the import from `react` to `rehackt`:
|
||||
|
||||
```tsx
|
||||
// shared-code.ts
|
||||
import {useState} from "rehackt";
|
||||
|
||||
export const data = {
|
||||
useForm: <T>(val: T) => {
|
||||
useState(val)
|
||||
},
|
||||
name: "server"
|
||||
}
|
||||
```
|
||||
|
||||
You'll no longer see this error.
|
||||
|
||||
> Keep in mind, this does not enable usage of `useState` in server-only code, this just removes the error described above.
|
||||
|
||||
## Further Reading
|
||||
|
||||
The following is a list of reading resources that pertain to this package:
|
||||
|
||||
- [My take on the current React & Server Components controversy - Lenz Weber-Tronic](https://phryneas.de/react-server-components-controversy)
|
||||
|
||||
- [apollographql/apollo-client#10974](https://github.com/apollographql/apollo-client/issues/10974)
|
||||
|
||||
- [TanStack/form#480](https://github.com/TanStack/form/issues/480#issuecomment-1793576645)
|
||||
3
node_modules/rehackt/index.d.ts
generated
vendored
Normal file
3
node_modules/rehackt/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/// <reference types="react" />
|
||||
import * as React from "react";
|
||||
export = React;
|
||||
24
node_modules/rehackt/index.js
generated
vendored
Normal file
24
node_modules/rehackt/index.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
if (0) {
|
||||
// Trick cjs-module-lexer into adding named exports for all React exports.
|
||||
// (if imported with `import()`, they will appear in `.default` as well.)
|
||||
// This way, cjs-module-lexer will let all of react's (named) exports through unchanged.
|
||||
module.exports = require("react");
|
||||
}
|
||||
// We don't want bundlers to error when they encounter usage of any of these exports.
|
||||
// It's up to the package author to ensure that if they access React internals,
|
||||
// they do so in a safe way that won't break if React changes how they use these internals.
|
||||
// (e.g. only access them in development, and only in an optional way that won't
|
||||
// break if internals are not there or do not have the expected structure)
|
||||
// @ts-ignore
|
||||
module.exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = undefined;
|
||||
// @ts-ignore
|
||||
module.exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = undefined;
|
||||
// @ts-ignore
|
||||
module.exports.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = undefined;
|
||||
// Here we actually pull in the React library and add everything
|
||||
// it exports to our own `module.exports`.
|
||||
// If React suddenly were to add one of the above "polyfilled" exports,
|
||||
// the React version would overwrite our version, so this should be
|
||||
// future-proof.
|
||||
Object.assign(module.exports, require("react"));
|
||||
48
node_modules/rehackt/package.json
generated
vendored
Normal file
48
node_modules/rehackt/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "rehackt",
|
||||
"version": "0.1.0",
|
||||
"description": "A wrapper around React that will hide hooks from the React Server Component compiler",
|
||||
"author": "Lenz Weber-Tronic",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/phryneas/rehackt.git"
|
||||
},
|
||||
"homepage": "https://github.com/phryneas/rehackt",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"react-server": "./rsc.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"rsc.js",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE.md"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.5.7",
|
||||
"react": "^19.0.0-canary-33a32441e9-20240418"
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 120
|
||||
}
|
||||
}
|
||||
89
node_modules/rehackt/rsc.js
generated
vendored
Normal file
89
node_modules/rehackt/rsc.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// @ts-check
|
||||
|
||||
if (0) {
|
||||
// Trick cjs-module-lexer into adding named exports for all React exports.
|
||||
// (if imported with `import()`, they will appear in `.default` as well.)
|
||||
// This way, cjs-module-lexer will let all of react's (named) exports through unchanged.
|
||||
module.exports = require("react");
|
||||
}
|
||||
|
||||
// missing functions
|
||||
module.exports.createContext = polyfillMissingFn("createContext");
|
||||
// @ts-ignore
|
||||
module.exports.createFactory = polyfillMissingFn("createFactory");
|
||||
module.exports.act = polyfillMissingFn("act");
|
||||
// @ts-ignore
|
||||
module.exports.unstable_act = polyfillMissingFn("unstable_act");
|
||||
module.exports.unstable_useCacheRefresh = polyfillMissingFn("unstable_useCacheRefresh");
|
||||
module.exports.useContext = polyfillMissingFn("useContext");
|
||||
module.exports.useDeferredValue = polyfillMissingFn("useDeferredValue");
|
||||
module.exports.useEffect = polyfillMissingFn("useEffect");
|
||||
module.exports.useImperativeHandle = polyfillMissingFn("useImperativeHandle");
|
||||
module.exports.useInsertionEffect = polyfillMissingFn("useInsertionEffect");
|
||||
module.exports.useLayoutEffect = polyfillMissingFn("useLayoutEffect");
|
||||
module.exports.useReducer = polyfillMissingFn("useReducer");
|
||||
module.exports.useRef = polyfillMissingFn("useRef");
|
||||
module.exports.useState = polyfillMissingFn("useState");
|
||||
module.exports.useSyncExternalStore = polyfillMissingFn("useSyncExternalStore");
|
||||
module.exports.useTransition = polyfillMissingFn("useTransition");
|
||||
module.exports.useOptimistic = polyfillMissingFn("useOptimistic");
|
||||
// We don't want bundlers to error when they encounter usage of any of these exports.
|
||||
// It's up to the package author to ensure that if they access React internals,
|
||||
// they do so in a safe way that won't break if React changes how they use these internals.
|
||||
// (e.g. only access them in development, and only in an optional way that won't
|
||||
// break if internals are not there or do not have the expected structure)
|
||||
// @ts-ignore
|
||||
module.exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = undefined;
|
||||
// @ts-ignore
|
||||
module.exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = undefined;
|
||||
// @ts-ignore
|
||||
module.exports.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = undefined;
|
||||
|
||||
// missing classes
|
||||
module.exports.Component = polyfillMissingClass("Component");
|
||||
module.exports.PureComponent = polyfillMissingClass("PureComponent");
|
||||
|
||||
module.exports.createContext = function unsupportedCreateContext() {
|
||||
return {
|
||||
Provider: function throwNoContext() {
|
||||
throw new Error("Context is not available in this environment.");
|
||||
},
|
||||
Consumer: function throwNoContext() {
|
||||
throw new Error("Context is not available in this environment.");
|
||||
},
|
||||
};
|
||||
};
|
||||
// @ts-ignore
|
||||
module.exports.createFactory = function unsupportedCreateFactory() {
|
||||
return function throwNoCreateFactory() {
|
||||
throw new Error("createFactory is not available in this environment.");
|
||||
};
|
||||
};
|
||||
|
||||
// Here we actually pull in the React library and add everything
|
||||
// it exports to our own `module.exports`.
|
||||
// If React suddenly were to add one of the above "polyfilled" exports,
|
||||
// the React version would overwrite our version, so this should be
|
||||
// future-proof.
|
||||
Object.assign(module.exports, require("react"));
|
||||
|
||||
function polyfillMissingFn(exportName) {
|
||||
const name = "nonExistingExport__" + exportName;
|
||||
return /** @type {any} */ (
|
||||
{
|
||||
[name]() {
|
||||
throw new Error(`React functionality '${exportName}' is not available in this environment.`);
|
||||
},
|
||||
}[name]
|
||||
);
|
||||
}
|
||||
|
||||
function polyfillMissingClass(exportName) {
|
||||
return /** @type {any} */ (
|
||||
class NonExistentClass {
|
||||
constructor() {
|
||||
throw new Error(`React class '${exportName}' is not available in this environment.`);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user