diff --git a/documentation/api.md b/documentation/api.md index a0efe0ad9..7a2a79642 100644 --- a/documentation/api.md +++ b/documentation/api.md @@ -590,6 +590,8 @@ export function CounterProvider(props) { } ``` +The value passed to provider is passed to `useContext` as is. That means wrapping as a reactive expression will not work. You should pass in Signals and State directly instead of accessing them in the JSX. + ## `useContext` ```ts diff --git a/documentation/guides/server.md b/documentation/guides/server.md index ce0723eb3..a95adaa5b 100644 --- a/documentation/guides/server.md +++ b/documentation/guides/server.md @@ -70,24 +70,36 @@ const html = ` ${app} -` +`; ``` ```jsx import { HydrationScript } from "solid-js/web"; const App = () => { - return - - 🔥 Solid SSR 🔥 - - - - - - {/*... rest of App*/} - -} + return ( + + + 🔥 Solid SSR 🔥 + + + + + + {/*... rest of App*/} + + ); +}; +``` + +When hydrating from the document inserting assets that aren't available in the client run also can mess things up. Solid provides a `` component whose children will work as normal on the server, but not hydrate in the browser. + +```jsx + + {manifest.map(m => ( + + ))} + ``` ## Async and Streaming SSR diff --git a/package-lock.json b/package-lock.json index dff6849dc..39e0b31fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,15 +27,15 @@ "@types/jest": "^26.0.23", "@types/shelljs": "^0.8.8", "babel-jest": "^26.6.3", - "babel-plugin-jsx-dom-expressions": "^0.28.5", + "babel-plugin-jsx-dom-expressions": "^0.28.7", "coveralls": "^3.1.0", - "dom-expressions": "0.28.6", + "dom-expressions": "0.28.7", "gitly": "^2.1.0", - "hyper-dom-expressions": "0.28.6", + "hyper-dom-expressions": "0.28.7", "jest": "~26.6.3", "jest-ts-webcompat-resolver": "^1.0.0", "lerna": "^3.22.1", - "lit-dom-expressions": "0.28.6", + "lit-dom-expressions": "0.28.7", "ncp": "2.0.0", "npm-run-all": "^4.1.5", "rimraf": "^3.0.2", @@ -4942,11 +4942,10 @@ } }, "node_modules/babel-plugin-jsx-dom-expressions": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.28.5.tgz", - "integrity": "sha512-7zM3SSA7qhvg6TDaTfbN4fR4FCdMAc+2wj711BCiOg6rPY9bK2ZIZw8dQlDhxH2LLnAqN35CcYuoJx7OBxW3aw==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.28.7.tgz", + "integrity": "sha512-j13F2tMbjZyoejlBc0jYmvBkmsgJIR9Wx79p9XF8Li+LokBc/AkyQHE95n1KIfjzSuWKpFr6Ak+fgnST+PGVIw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@babel/plugin-syntax-jsx": "^7.10.4", @@ -7106,11 +7105,10 @@ } }, "node_modules/dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.28.6.tgz", - "integrity": "sha512-4pvENjcSJg06E/U5IUmUg2sMOskhazCvdGM+lvYGLAU4ZZ0e3VJKBjuV4mUVbbd7iNCECNesAvKzGwsmFzkGqg==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.28.7.tgz", + "integrity": "sha512-ibZ4Wol3ihdJA+w9eGbx/0aVIXcBIDwGm9n+Qbcc46JstbWkKwde3qE/k3XV0J+lmSf4qd32AiwwsWILDdrmKQ==", "dev": true, - "license": "MIT", "dependencies": { "babel-plugin-transform-rename-import": "^2.3.0", "devalue": "^2.0.1" @@ -9310,9 +9308,9 @@ } }, "node_modules/goober": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.0.37.tgz", - "integrity": "sha512-wgj5C7IJX2+MyHZ4TgOA+hLL1mCDW+jGorQ5KCMLF1ofE9gQkfbo1s8txIrzIsAX65XRTm0qaipolId2KMYUkw==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.0.38.tgz", + "integrity": "sha512-oGrP8xMB3k6EEcEAuKstd05r0JRFs8L9ouPCTKxupu85PdDJ443LTCXvxRVMeYN6pVhV6htVb7FaKTk5JlFzCQ==", "peerDependencies": { "csstype": "^2.6.2" } @@ -9605,9 +9603,9 @@ } }, "node_modules/hyper-dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.28.6.tgz", - "integrity": "sha512-cWuHrQWkgFU/HVtlRSGjOQPMY4rwrrJfWmAbhw1PaCKAoDGQmKpT+NKDrnD1dg7f4CZO/Zsrm0aquap9VWOrgg==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.28.7.tgz", + "integrity": "sha512-KrYvguxtelfOtRCBloyvzGBwASYZJFb0cuTLg4NVyGIUJujFh+dEsL1u//gFv1yoP+9dDg0CQupS/9HjlrPYdQ==", "dev": true }, "node_modules/iconv-lite": { @@ -12696,9 +12694,9 @@ "dev": true }, "node_modules/lit-dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.28.6.tgz", - "integrity": "sha512-obJdAT1eE/DqWA1Mz+5sVQPDlsAjYSsYGVbYfFo9sds3b4RoL/Wb9AjZO4H/xoPBXe0cZdjMrxNgsBrRiKCtzA==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.28.7.tgz", + "integrity": "sha512-tr3MNCkP+cR715uScFk4YVK+6LY2mKHWCQnyheC/yIUfwDOCncBt8TEkQV5EwoJ0JhdAlAk7ciTgNzVp+cdHPg==", "dev": true }, "node_modules/load-json-file": { @@ -21814,9 +21812,9 @@ } }, "babel-plugin-jsx-dom-expressions": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.28.5.tgz", - "integrity": "sha512-7zM3SSA7qhvg6TDaTfbN4fR4FCdMAc+2wj711BCiOg6rPY9bK2ZIZw8dQlDhxH2LLnAqN35CcYuoJx7OBxW3aw==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.28.7.tgz", + "integrity": "sha512-j13F2tMbjZyoejlBc0jYmvBkmsgJIR9Wx79p9XF8Li+LokBc/AkyQHE95n1KIfjzSuWKpFr6Ak+fgnST+PGVIw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", @@ -23578,9 +23576,9 @@ } }, "dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.28.6.tgz", - "integrity": "sha512-4pvENjcSJg06E/U5IUmUg2sMOskhazCvdGM+lvYGLAU4ZZ0e3VJKBjuV4mUVbbd7iNCECNesAvKzGwsmFzkGqg==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.28.7.tgz", + "integrity": "sha512-ibZ4Wol3ihdJA+w9eGbx/0aVIXcBIDwGm9n+Qbcc46JstbWkKwde3qE/k3XV0J+lmSf4qd32AiwwsWILDdrmKQ==", "dev": true, "requires": { "babel-plugin-transform-rename-import": "^2.3.0", @@ -25339,9 +25337,9 @@ } }, "goober": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.0.37.tgz", - "integrity": "sha512-wgj5C7IJX2+MyHZ4TgOA+hLL1mCDW+jGorQ5KCMLF1ofE9gQkfbo1s8txIrzIsAX65XRTm0qaipolId2KMYUkw==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.0.38.tgz", + "integrity": "sha512-oGrP8xMB3k6EEcEAuKstd05r0JRFs8L9ouPCTKxupu85PdDJ443LTCXvxRVMeYN6pVhV6htVb7FaKTk5JlFzCQ==", "requires": {} }, "graceful-fs": { @@ -25585,9 +25583,9 @@ } }, "hyper-dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.28.6.tgz", - "integrity": "sha512-cWuHrQWkgFU/HVtlRSGjOQPMY4rwrrJfWmAbhw1PaCKAoDGQmKpT+NKDrnD1dg7f4CZO/Zsrm0aquap9VWOrgg==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.28.7.tgz", + "integrity": "sha512-KrYvguxtelfOtRCBloyvzGBwASYZJFb0cuTLg4NVyGIUJujFh+dEsL1u//gFv1yoP+9dDg0CQupS/9HjlrPYdQ==", "dev": true }, "iconv-lite": { @@ -28027,9 +28025,9 @@ "dev": true }, "lit-dom-expressions": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.28.6.tgz", - "integrity": "sha512-obJdAT1eE/DqWA1Mz+5sVQPDlsAjYSsYGVbYfFo9sds3b4RoL/Wb9AjZO4H/xoPBXe0cZdjMrxNgsBrRiKCtzA==", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.28.7.tgz", + "integrity": "sha512-tr3MNCkP+cR715uScFk4YVK+6LY2mKHWCQnyheC/yIUfwDOCncBt8TEkQV5EwoJ0JhdAlAk7ciTgNzVp+cdHPg==", "dev": true }, "load-json-file": { diff --git a/package.json b/package.json index f242e0c5b..ff9065219 100644 --- a/package.json +++ b/package.json @@ -33,15 +33,15 @@ "@types/jest": "^26.0.23", "@types/shelljs": "^0.8.8", "babel-jest": "^26.6.3", - "babel-plugin-jsx-dom-expressions": "^0.28.5", + "babel-plugin-jsx-dom-expressions": "^0.28.7", "coveralls": "^3.1.0", - "dom-expressions": "0.28.6", + "dom-expressions": "0.28.7", "gitly": "^2.1.0", - "hyper-dom-expressions": "0.28.6", + "hyper-dom-expressions": "0.28.7", "jest": "~26.6.3", "jest-ts-webcompat-resolver": "^1.0.0", "lerna": "^3.22.1", - "lit-dom-expressions": "0.28.6", + "lit-dom-expressions": "0.28.7", "ncp": "2.0.0", "npm-run-all": "^4.1.5", "rimraf": "^3.0.2", diff --git a/packages/babel-preset-solid/package.json b/packages/babel-preset-solid/package.json index 65249b3a6..da4c8fbd2 100644 --- a/packages/babel-preset-solid/package.json +++ b/packages/babel-preset-solid/package.json @@ -14,6 +14,6 @@ "test": "node test.js" }, "dependencies": { - "babel-plugin-jsx-dom-expressions": "^0.28.5" + "babel-plugin-jsx-dom-expressions": "^0.28.7" } } diff --git a/packages/solid/src/index.ts b/packages/solid/src/index.ts index f34d37a7d..40b333cbb 100644 --- a/packages/solid/src/index.ts +++ b/packages/solid/src/index.ts @@ -35,7 +35,9 @@ export type { StatePathRange, ArrayFilterFn, Part, - Next + Next, + Readonly, + DeepReadonly } from "./reactive/state"; export * from "./reactive/mutable"; export * from "./reactive/observable"; diff --git a/packages/solid/src/reactive/signal.ts b/packages/solid/src/reactive/signal.ts index 1bd63b34e..2b1616236 100644 --- a/packages/solid/src/reactive/signal.ts +++ b/packages/solid/src/reactive/signal.ts @@ -1019,10 +1019,14 @@ function resolveChildren(children: any): unknown { function createProvider(id: symbol) { return function provider(props: { value: unknown; children: any }) { - return createMemo(() => { - Owner!.context = { [id]: props.value }; - return children(() => props.children); - }) as unknown as JSX.Element; + let res; + createComputed(() => + res = untrack(() => { + Owner!.context = { [id]: props.value }; + return children(() => props.children); + }) + ); + return res as JSX.Element; }; } diff --git a/packages/solid/src/reactive/state.ts b/packages/solid/src/reactive/state.ts index 239e6573b..5a3ab76d4 100644 --- a/packages/solid/src/reactive/state.ts +++ b/packages/solid/src/reactive/state.ts @@ -228,8 +228,8 @@ export function updatePath(current: StateNode, path: any[], traversed: (number | } else setProperty(current, part, value); } -export declare type Readonly = { readonly [K in keyof T]: DeepReadonly }; -export declare type DeepReadonly = T extends [infer A] +export type Readonly = { readonly [K in keyof T]: DeepReadonly }; +export type DeepReadonly = T extends [infer A] ? Readonly<[A]> : T extends [infer A, infer B] ? Readonly<[A, B]> diff --git a/packages/solid/web/src/server-mock.ts b/packages/solid/web/src/server-mock.ts index 50525a080..59a1be1b8 100644 --- a/packages/solid/web/src/server-mock.ts +++ b/packages/solid/web/src/server-mock.ts @@ -46,5 +46,6 @@ export function ssrClassList(value: { [k: string]: boolean }): string {} export function ssrStyle(value: { [k: string]: string }): string {} export function ssrSpread(accessor: any): () => string {} export function ssrBoolean(key: string, value: boolean): string {} +export function ssrHydrationKey(): string {} export function escape(html: string): string {} export function generateHydrationScript(): string {}