diff --git a/package-lock.json b/package-lock.json index 5b8e6033..8adc094e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@file-services/node": "^9.4.1", "@file-services/path": "^9.4.1", "@file-services/resolve": "^9.4.1", - "@playwright/browser-chromium": "^1.48.0", + "@playwright/browser-chromium": "^1.48.1", "@types/chai": "^4.3.20", "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^10.0.9", @@ -28,7 +28,7 @@ "chai": "^4.5.0", "chai-as-promised": "^7.1.2", "esbuild": "^0.24.0", - "eslint": "^9.12.0", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-react": "^7.37.1", @@ -42,7 +42,7 @@ "rimraf": "^6.0.1", "sinon": "^19.0.2", "typescript": "~5.6.3", - "typescript-eslint": "^8.9.0" + "typescript-eslint": "^8.10.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -508,9 +508,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -542,9 +542,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true, "license": "MIT", "engines": { @@ -562,9 +562,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", + "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -841,14 +841,14 @@ } }, "node_modules/@playwright/browser-chromium": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/@playwright/browser-chromium/-/browser-chromium-1.48.0.tgz", - "integrity": "sha512-933FDk719os4Z6iUoXaoO/mxTGSnaXCXHqLgttfGFmNElB+7LVO4jhJ/gnRnQFjhrB3YKFXP86pnMepjaEykcw==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@playwright/browser-chromium/-/browser-chromium-1.48.1.tgz", + "integrity": "sha512-WNpIE+CpO4XNhdNTC/mVE8m/1gYR/hPswL8dnIZzElqxsOPm7qxIBdAChWm/7q1kkMiQ+gEGAaXXQfqL0vR28w==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.48.0" + "playwright-core": "1.48.1" }, "engines": { "node": ">=18" @@ -1060,9 +1060,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", - "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.3.tgz", + "integrity": "sha512-golm/Sc4CqLV/ZalIP14Nre7zPgd8xG/S3nHULMTBHMX0llyTNhE1O6nrgbfvLX2o0y849CnLKdu8OE05Ztiiw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1133,9 +1133,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.16.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", - "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", + "version": "20.16.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.12.tgz", + "integrity": "sha512-LfPFB0zOeCeCNQV3i+67rcoVvoN5n0NVuR2vLG0O5ySQMgchuZlC4lgz546ZOJyDtj5KIgOxy+lacOimfqZAIA==", "dev": true, "license": "MIT", "dependencies": { @@ -1188,17 +1188,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.9.0.tgz", - "integrity": "sha512-Y1n621OCy4m7/vTXNlCbMVp87zSd7NH0L9cXD8aIpOaNlzeWxIK4+Q19A68gSmTNRZn92UjocVUWDthGxtqHFg==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.10.0.tgz", + "integrity": "sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.9.0", - "@typescript-eslint/type-utils": "8.9.0", - "@typescript-eslint/utils": "8.9.0", - "@typescript-eslint/visitor-keys": "8.9.0", + "@typescript-eslint/scope-manager": "8.10.0", + "@typescript-eslint/type-utils": "8.10.0", + "@typescript-eslint/utils": "8.10.0", + "@typescript-eslint/visitor-keys": "8.10.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1222,16 +1222,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.9.0.tgz", - "integrity": "sha512-U+BLn2rqTTHnc4FL3FJjxaXptTxmf9sNftJK62XLz4+GxG3hLHm/SUNaaXP5Y4uTiuYoL5YLy4JBCJe3+t8awQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.10.0.tgz", + "integrity": "sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.9.0", - "@typescript-eslint/types": "8.9.0", - "@typescript-eslint/typescript-estree": "8.9.0", - "@typescript-eslint/visitor-keys": "8.9.0", + "@typescript-eslint/scope-manager": "8.10.0", + "@typescript-eslint/types": "8.10.0", + "@typescript-eslint/typescript-estree": "8.10.0", + "@typescript-eslint/visitor-keys": "8.10.0", "debug": "^4.3.4" }, "engines": { @@ -1251,14 +1251,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.9.0.tgz", - "integrity": "sha512-bZu9bUud9ym1cabmOYH9S6TnbWRzpklVmwqICeOulTCZ9ue2/pczWzQvt/cGj2r2o1RdKoZbuEMalJJSYw3pHQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.10.0.tgz", + "integrity": "sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.9.0", - "@typescript-eslint/visitor-keys": "8.9.0" + "@typescript-eslint/types": "8.10.0", + "@typescript-eslint/visitor-keys": "8.10.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1269,14 +1269,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.9.0.tgz", - "integrity": "sha512-JD+/pCqlKqAk5961vxCluK+clkppHY07IbV3vett97KOV+8C6l+CPEPwpUuiMwgbOz/qrN3Ke4zzjqbT+ls+1Q==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.10.0.tgz", + "integrity": "sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.9.0", - "@typescript-eslint/utils": "8.9.0", + "@typescript-eslint/typescript-estree": "8.10.0", + "@typescript-eslint/utils": "8.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1294,9 +1294,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.9.0.tgz", - "integrity": "sha512-SjgkvdYyt1FAPhU9c6FiYCXrldwYYlIQLkuc+LfAhCna6ggp96ACncdtlbn8FmnG72tUkXclrDExOpEYf1nfJQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.10.0.tgz", + "integrity": "sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w==", "dev": true, "license": "MIT", "engines": { @@ -1308,14 +1308,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.9.0.tgz", - "integrity": "sha512-9iJYTgKLDG6+iqegehc5+EqE6sqaee7kb8vWpmHZ86EqwDjmlqNNHeqDVqb9duh+BY6WCNHfIGvuVU3Tf9Db0g==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.10.0.tgz", + "integrity": "sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.9.0", - "@typescript-eslint/visitor-keys": "8.9.0", + "@typescript-eslint/types": "8.10.0", + "@typescript-eslint/visitor-keys": "8.10.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1376,16 +1376,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.9.0.tgz", - "integrity": "sha512-PKgMmaSo/Yg/F7kIZvrgrWa1+Vwn036CdNUvYFEkYbPwOH4i8xvkaRlu148W3vtheWK9ckKRIz7PBP5oUlkrvQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.10.0.tgz", + "integrity": "sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.9.0", - "@typescript-eslint/types": "8.9.0", - "@typescript-eslint/typescript-estree": "8.9.0" + "@typescript-eslint/scope-manager": "8.10.0", + "@typescript-eslint/types": "8.10.0", + "@typescript-eslint/typescript-estree": "8.10.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1399,13 +1399,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.9.0.tgz", - "integrity": "sha512-Ht4y38ubk4L5/U8xKUBfKNYGmvKvA1CANoxiTRMM+tOLk3lbF3DvzZCxJCRSE+2GdCMSh6zq9VZJc3asc1XuAA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.10.0.tgz", + "integrity": "sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.9.0", + "@typescript-eslint/types": "8.10.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1532,9 +1532,9 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, "license": "MIT", "bin": { @@ -2638,18 +2638,18 @@ } }, "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", + "@eslint/js": "9.13.0", "@eslint/plugin-kit": "^0.2.0", "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", @@ -4925,9 +4925,9 @@ } }, "node_modules/playwright-core": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.0.tgz", - "integrity": "sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", + "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6079,15 +6079,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.9.0.tgz", - "integrity": "sha512-AuD/FXGYRQyqyOBCpNLldMlsCGvmDNxptQ3Dp58/NXeB+FqyvTfXmMyba3PYa0Vi9ybnj7G8S/yd/4Cw8y47eA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.10.0.tgz", + "integrity": "sha512-YIu230PeN7z9zpu/EtqCIuRVHPs4iSlqW6TEvjbyDAE3MZsSl2RXBo+5ag+lbABCG8sFM1WVKEXhlQ8Ml8A3Fw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.9.0", - "@typescript-eslint/parser": "8.9.0", - "@typescript-eslint/utils": "8.9.0" + "@typescript-eslint/eslint-plugin": "8.10.0", + "@typescript-eslint/parser": "8.10.0", + "@typescript-eslint/utils": "8.10.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index 2bb9ce9f..b1a2ff20 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@file-services/node": "^9.4.1", "@file-services/path": "^9.4.1", "@file-services/resolve": "^9.4.1", - "@playwright/browser-chromium": "^1.48.0", + "@playwright/browser-chromium": "^1.48.1", "@types/chai": "^4.3.20", "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^10.0.9", @@ -31,7 +31,7 @@ "chai": "^4.5.0", "chai-as-promised": "^7.1.2", "esbuild": "^0.24.0", - "eslint": "^9.12.0", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-react": "^7.37.1", @@ -45,7 +45,7 @@ "rimraf": "^6.0.1", "sinon": "^19.0.2", "typescript": "~5.6.3", - "typescript-eslint": "^8.9.0" + "typescript-eslint": "^8.10.0" }, "license": "MIT", "private": true diff --git a/packages/app-core/test-kit/index.ts b/packages/app-core/test-kit/index.ts index fc43f5d9..dc85abb0 100644 --- a/packages/app-core/test-kit/index.ts +++ b/packages/app-core/test-kit/index.ts @@ -134,7 +134,10 @@ export class AppDefDriver { void rerender({ uri: lastUri }); }; - this.addManifestListener(manifestListener); + if (testAutoRerenderOnManifestUpdate !== false) { + this.addManifestListener(manifestListener); + } return { dispose: () => { unmount(); diff --git a/packages/define-remix-app/src/manifest-to-router.tsx b/packages/define-remix-app/src/manifest-to-router.tsx index a5e873d6..eed2f24e 100644 --- a/packages/define-remix-app/src/manifest-to-router.tsx +++ b/packages/define-remix-app/src/manifest-to-router.tsx @@ -7,10 +7,10 @@ import { serializeRequest, } from './remix-app-utils'; import { createRemixStub } from '@remix-run/testing'; -import { lazy, Suspense, useEffect, useState } from 'react'; +import { lazy, Suspense, useCallback, useEffect, useState } from 'react'; import type { ActionFunctionArgs, LinksFunction, LoaderFunction } from '@remix-run/node'; import React from 'react'; -import { ClientActionFunction, ClientLoaderFunction, useLocation, useNavigate } from '@remix-run/react'; +import { ClientActionFunction, ClientLoaderFunction, useLocation, useNavigate, useRevalidator } from '@remix-run/react'; import { navigation } from './navigation'; import { createHandleProxy } from './handle-proxy'; import { createLinksProxy } from './links-proxy'; @@ -122,7 +122,14 @@ function RootComp({ setUri: (uri: string) => void; prevUri: { current: string }; }) { - const currentModule = useDispatcher(module); + const revalidator = useRevalidator(); + const currentModule = useDispatcher( + module, + useCallback(() => { + // invalidates loader data + revalidator.revalidate(); + }, [revalidator]), + ); const uri = useLocation().pathname; @@ -157,7 +164,14 @@ function RootComp({ } function PageComp({ module, filePath }: { module: Dispatcher>; filePath: string }) { - const currentModule = useDispatcher(module); + const revalidator = useRevalidator(); + const currentModule = useDispatcher( + module, + useCallback(() => { + // invalidates loader data + revalidator.revalidate(); + }, [revalidator]), + ); const location = useLocation(); if (currentModule.errorMessage) { return
{currentModule.errorMessage}
; @@ -366,11 +380,14 @@ function createDispatcher(value: T): Dispatcher { }, }; } -function useDispatcher(dispatcher: Dispatcher) { +function useDispatcher(dispatcher: Dispatcher, onChange?: (newValue: T) => void) { const [state, setState] = useState(dispatcher.getState()); useEffect(() => { - return dispatcher.subscribe(setState); - }, [dispatcher]); + return dispatcher.subscribe((newValue) => { + setState(newValue); + onChange?.(newValue); + }); + }, [dispatcher, onChange]); return state; } diff --git a/packages/define-remix-app/test/define-remix.spec.ts b/packages/define-remix-app/test/define-remix.spec.ts index a365cfa5..1b02ffa8 100644 --- a/packages/define-remix-app/test/define-remix.spec.ts +++ b/packages/define-remix-app/test/define-remix.spec.ts @@ -22,6 +22,7 @@ import { pageWithLinks, userApiConsumer, userApiPage, + loaderAndClientLoaderRoot, } from './test-cases/roots'; import chai, { expect } from 'chai'; import { IAppManifest, RouteInfo, RoutingPattern } from '@wixc3/app-core'; @@ -1195,6 +1196,58 @@ describe('define-remix', () => { dispose(); }); + it('should re-load data on route source change (root)', async () => { + const { driver } = await getInitialManifest({ + [rootPath]: loaderAndClientLoaderRoot('server initial data', 'client initial data'), + [indexPath]: namedPage('Home'), + }); + + const { dispose, container } = await driver.render({ + uri: '', + testAutoRerenderOnManifestUpdate: false, + }); + + await expect(() => container.textContent) + .retry() + .to.include('App:server initial data!client initial data'); + + driver.addOrUpdateFile( + rootPath, + loaderAndClientLoaderRoot('server modified data', 'client modified data'), + ); + + await expect(() => container.textContent) + .retry() + .to.include('App:server modified data!client modified data'); + + dispose(); + }); + it('should re-load data on route source change (page)', async () => { + const { driver } = await getInitialManifest({ + [rootPath]: rootWithLayout2, + [indexPath]: loaderAndClientLoaderPage('Home', 'server initial data', 'client initial data'), + }); + + const { dispose, container } = await driver.render({ + uri: '', + testAutoRerenderOnManifestUpdate: false, + }); + + await expect(() => container.textContent) + .retry() + .to.include('Layout|App|Home:server initial data!client initial data'); + + driver.addOrUpdateFile( + indexPath, + loaderAndClientLoaderPage('Home', 'server modified data', 'client modified data'), + ); + + await expect(() => container.textContent) + .retry() + .to.include('Layout|App|Home:server modified data!client modified data'); + + dispose(); + }); }); describe('clientLoader', () => { it('should call clientLoader and pass the information into useLoaderData', async () => { diff --git a/packages/define-remix-app/test/test-cases/roots.ts b/packages/define-remix-app/test/test-cases/roots.ts index 32da6e02..1792c560 100644 --- a/packages/define-remix-app/test/test-cases/roots.ts +++ b/packages/define-remix-app/test/test-cases/roots.ts @@ -278,6 +278,45 @@ export const loaderAndClientLoaderPage = (name: string, message: string, clientM } `); +export const loaderAndClientLoaderRoot = (serverLoaderMsg: string, clientLoaderMsg: string) => + transformTsx(` + import React from 'react'; + import { Outlet, Links, useLoaderData, json } from '@remix-run/react'; + + export const clientLoader = async ({serverLoader}) => { + const serverResponse = await serverLoader(); + const serverData = await serverResponse.json(); + return { clientMessage: '${clientLoaderMsg}', ...serverData } + }; + clientLoader.hydrate = true; + export const loader = () => (json({ serverMessage: '${serverLoaderMsg}' })); + + export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + Layout| + {children} + + + ); + } + export default function App() { + const data = useLoaderData(); + return ( +
+ App:{data.serverMessage}!{data.clientMessage}| + +
+ ); + } + + export function ErrorBoundary({ error }: { error: Error }) { + return
Error
; + } +`); + export const clientLoaderWithFallbackPage = (name: string, clientMessage: string) => transformTsx(` import React from 'react';