├── .gitignore
├── .npmignore
├── README.md
├── package-lock.json
├── package.json
├── src
└── index.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /lib
3 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | tsconfig.json
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Server Only Context
2 |
3 | Tiny wrapper around `cache` to have request-scoped context
4 | for server components. No more prop drilling!
5 |
6 | **Note:** when navigating on the client side the layout is not re-rendered,
7 | so you need to set the context **both in the page and in the layout**.
8 |
9 | ```javascript
10 | import serverContext from "server-only-context";
11 |
12 | export const [getLocale, setLocale] = serverContext("en");
13 | export const [getUserId, setUserId] = serverContext("");
14 | ```
15 |
16 | ```javascript
17 | import { setLocale, setUserId } from "@/context";
18 |
19 | export default function UserPage({ params: { locale, userId } }) {
20 | setLocale(locale);
21 | setUserId(userId);
22 | return ;
23 | }
24 | ```
25 |
26 | ```javascript
27 | import { getLocale, getUserId } from "@/context";
28 |
29 | export default function MyComponent() {
30 | const locale = getLocale();
31 | const userId = getUserId();
32 |
33 | return (
34 |
35 | Hello {userId}! Locale is {locale}.
36 |
37 | );
38 | }
39 | ```
40 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-only-context",
3 | "version": "0.1.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "server-only-context",
9 | "version": "0.1.0",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "typescript": "^4.9.5"
13 | },
14 | "peerDependencies": {
15 | "react": "next"
16 | }
17 | },
18 | "node_modules/js-tokens": {
19 | "version": "4.0.0",
20 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
21 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
22 | "peer": true
23 | },
24 | "node_modules/loose-envify": {
25 | "version": "1.4.0",
26 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
27 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
28 | "peer": true,
29 | "dependencies": {
30 | "js-tokens": "^3.0.0 || ^4.0.0"
31 | },
32 | "bin": {
33 | "loose-envify": "cli.js"
34 | }
35 | },
36 | "node_modules/react": {
37 | "version": "18.3.0-next-fccf3a9fb-20230213",
38 | "resolved": "https://registry.npmjs.org/react/-/react-18.3.0-next-fccf3a9fb-20230213.tgz",
39 | "integrity": "sha512-DPWHyL/tLt70h3CW8So5ul1pnW0muvZFM3B8iwxVj+u4j4Z901wnbwE45CLMSpX8yJiSxO9ioPvkhgiuIji2uw==",
40 | "peer": true,
41 | "dependencies": {
42 | "loose-envify": "^1.1.0"
43 | },
44 | "engines": {
45 | "node": ">=0.10.0"
46 | }
47 | },
48 | "node_modules/typescript": {
49 | "version": "4.9.5",
50 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
51 | "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
52 | "dev": true,
53 | "bin": {
54 | "tsc": "bin/tsc",
55 | "tsserver": "bin/tsserver"
56 | },
57 | "engines": {
58 | "node": ">=4.2.0"
59 | }
60 | }
61 | },
62 | "dependencies": {
63 | "js-tokens": {
64 | "version": "4.0.0",
65 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
66 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
67 | "peer": true
68 | },
69 | "loose-envify": {
70 | "version": "1.4.0",
71 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
72 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
73 | "peer": true,
74 | "requires": {
75 | "js-tokens": "^3.0.0 || ^4.0.0"
76 | }
77 | },
78 | "react": {
79 | "version": "18.3.0-next-fccf3a9fb-20230213",
80 | "resolved": "https://registry.npmjs.org/react/-/react-18.3.0-next-fccf3a9fb-20230213.tgz",
81 | "integrity": "sha512-DPWHyL/tLt70h3CW8So5ul1pnW0muvZFM3B8iwxVj+u4j4Z901wnbwE45CLMSpX8yJiSxO9ioPvkhgiuIji2uw==",
82 | "peer": true,
83 | "requires": {
84 | "loose-envify": "^1.1.0"
85 | }
86 | },
87 | "typescript": {
88 | "version": "4.9.5",
89 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
90 | "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
91 | "dev": true
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-only-context",
3 | "version": "0.1.0",
4 | "description": "Context for your server components",
5 | "main": "lib/index.js",
6 | "files": [
7 | "lib/**/*"
8 | ],
9 | "scripts": {
10 | "prepare": "tsc",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/manvalls/server-only-context.git"
16 | },
17 | "keywords": [],
18 | "author": "",
19 | "license": "ISC",
20 | "bugs": {
21 | "url": "https://github.com/manvalls/server-only-context/issues"
22 | },
23 | "homepage": "https://github.com/manvalls/server-only-context#readme",
24 | "peerDependencies": {
25 | "react": "next"
26 | },
27 | "devDependencies": {
28 | "typescript": "^4.9.5"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import { cache } from "react";
3 |
4 | export default (defaultValue: T): [() => T, (v: T) => void] => {
5 | const getRef = cache(() => ({ current: defaultValue }));
6 |
7 | const getValue = (): T => getRef().current;
8 |
9 | const setValue = (value: T) => {
10 | getRef().current = value;
11 | };
12 |
13 | return [getValue, setValue];
14 | };
15 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "declaration": true,
6 | "outDir": "./lib",
7 | "strict": true
8 | },
9 | "include": ["src"],
10 | "exclude": ["node_modules", "**/__tests__/*"]
11 | }
--------------------------------------------------------------------------------