@wular/pnext 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -0
- package/bin/pnext +67 -0
- package/config/lint/base.js +48 -0
- package/config/ts/base.json +26 -0
- package/config/ts/react.json +13 -0
- package/package.json +70 -0
- package/reference/compat.md +63 -0
- package/reference/config.md +120 -0
- package/reference/css.md +58 -0
- package/reference/dev.md +69 -0
- package/reference/env.md +40 -0
- package/reference/metadata.md +86 -0
- package/reference/navigation.md +149 -0
- package/reference/overview.md +35 -0
- package/reference/performance.md +97 -0
- package/reference/rendering.md +127 -0
- package/reference/routing.md +167 -0
- package/reference/typegen.md +64 -0
- package/src/api/cache.ts +80 -0
- package/src/api/client-cache.ts +9 -0
- package/src/api/client-navigation.ts +279 -0
- package/src/api/dynamic.tsx +102 -0
- package/src/api/link.tsx +119 -0
- package/src/api/navigation.ts +198 -0
- package/src/api/router/events.ts +53 -0
- package/src/api/router/history.ts +70 -0
- package/src/api/router/hub.ts +194 -0
- package/src/api/router/policies.ts +107 -0
- package/src/api/router/runtime.ts +5238 -0
- package/src/api/router/types.ts +299 -0
- package/src/api/router.ts +167 -0
- package/src/api/server.ts +323 -0
- package/src/api/suspense.ts +16 -0
- package/src/cache/context.ts +61 -0
- package/src/cli/adapters/vercel-warm.ts +375 -0
- package/src/cli/adapters/vercel.ts +1310 -0
- package/src/cli/analyze-print.ts +181 -0
- package/src/cli/analyze.ts +328 -0
- package/src/cli/boot-trace.ts +29 -0
- package/src/cli/build.ts +3114 -0
- package/src/cli/dev.ts +276 -0
- package/src/cli/index.ts +196 -0
- package/src/cli/named-bin.ts +119 -0
- package/src/cli/serve-ui.ts +160 -0
- package/src/cli/start.ts +1425 -0
- package/src/client/build.ts +2136 -0
- package/src/client/chunk-fold.ts +526 -0
- package/src/client/entry.ts +1525 -0
- package/src/client/paths.ts +22 -0
- package/src/client/prebuilt.ts +621 -0
- package/src/client/profile.ts +75 -0
- package/src/client/react-compiler.ts +94 -0
- package/src/client/reference-stub.ts +145 -0
- package/src/client/reference.ts +47 -0
- package/src/compat/actions/action-client.ts +531 -0
- package/src/compat/actions/action-dispatch.ts +676 -0
- package/src/compat/actions/action-router.ts +40 -0
- package/src/compat/actions/action-shared.ts +95 -0
- package/src/compat/actions/client-plugin.ts +135 -0
- package/src/compat/actions/client-stub.ts +65 -0
- package/src/compat/actions/config.ts +164 -0
- package/src/compat/actions/detect.ts +208 -0
- package/src/compat/actions/discovery.ts +244 -0
- package/src/compat/actions/early-submit.ts +40 -0
- package/src/compat/actions/endpoint.ts +602 -0
- package/src/compat/actions/flight.ts +52 -0
- package/src/compat/actions/form-state.ts +73 -0
- package/src/compat/actions/hoist.ts +485 -0
- package/src/compat/actions/ids.ts +39 -0
- package/src/compat/actions/index.ts +41 -0
- package/src/compat/actions/instances.ts +144 -0
- package/src/compat/actions/origin.ts +109 -0
- package/src/compat/actions/protocol.ts +125 -0
- package/src/compat/actions/registry.ts +74 -0
- package/src/compat/actions/rewrite.ts +282 -0
- package/src/compat/actions/serve.ts +414 -0
- package/src/compat/actions/server-tag.ts +21 -0
- package/src/compat/actions/unrecognized-error.ts +30 -0
- package/src/compat/adapter/build-complete.ts +257 -0
- package/src/compat/bundler/bun-externals.ts +53 -0
- package/src/compat/bundler/cjs-exports.ts +542 -0
- package/src/compat/bundler/config.ts +363 -0
- package/src/compat/bundler/externals.ts +34 -0
- package/src/compat/bundler/import-meta-url.ts +60 -0
- package/src/compat/bundler/modularize-imports.ts +119 -0
- package/src/compat/bundler/new-url-asset.ts +87 -0
- package/src/compat/bundler/optimize-package-imports.ts +273 -0
- package/src/compat/bundler/polyfill.ts +88 -0
- package/src/compat/bundler/react-compiler.ts +61 -0
- package/src/compat/bundler/react-profiler.tsx +25 -0
- package/src/compat/bundler/relay-transform.ts +116 -0
- package/src/compat/bundler/require-context.ts +281 -0
- package/src/compat/bundler/resolve-extensions.ts +75 -0
- package/src/compat/bundler/source-cache.ts +61 -0
- package/src/compat/bundler/static-imports.ts +25 -0
- package/src/compat/bundler/symlink-imports.ts +119 -0
- package/src/compat/bundler/tsconfig-paths.ts +50 -0
- package/src/compat/bundler/wasm.ts +153 -0
- package/src/compat/bundler/webpack-loaders.ts +685 -0
- package/src/compat/bundler/worker.ts +278 -0
- package/src/compat/cache/build-flags.ts +81 -0
- package/src/compat/cache/build-prerender-errors.ts +163 -0
- package/src/compat/cache/custom-handler.ts +159 -0
- package/src/compat/cache/fetch-patch.ts +745 -0
- package/src/compat/cache/handler.ts +100 -0
- package/src/compat/cache/modern-handler.ts +275 -0
- package/src/compat/cache/resume-data-cache.ts +143 -0
- package/src/compat/cache/revalidate.ts +759 -0
- package/src/compat/cache/runtime-error.ts +124 -0
- package/src/compat/cache/use-cache-transform.ts +961 -0
- package/src/compat/cache/use-cache.ts +1695 -0
- package/src/compat/cache-control.ts +269 -0
- package/src/compat/client/base-path.ts +64 -0
- package/src/compat/client/css-order.ts +36 -0
- package/src/compat/client/errors/control-flow.ts +92 -0
- package/src/compat/client/errors/error-boundary.ts +222 -0
- package/src/compat/client/errors/global-error.ts +238 -0
- package/src/compat/client/errors/install.ts +217 -0
- package/src/compat/client/errors/lazy.ts +53 -0
- package/src/compat/client/errors/primitive-throw.ts +126 -0
- package/src/compat/client/errors/soft-refresh.ts +14 -0
- package/src/compat/client/link-status.ts +86 -0
- package/src/compat/client/nav-compat-runtime.ts +57 -0
- package/src/compat/client/nav-compat.ts +42 -0
- package/src/compat/client/navigation-scroll.ts +154 -0
- package/src/compat/client/optimistic-routing.ts +206 -0
- package/src/compat/client/prefetch-cache.ts +111 -0
- package/src/compat/client/route-announcer.ts +72 -0
- package/src/compat/client/segment-cache-policy.ts +159 -0
- package/src/compat/client/segment-cache.ts +1077 -0
- package/src/compat/client/segment-prefetch.ts +375 -0
- package/src/compat/client/trailing-slash.ts +24 -0
- package/src/compat/css/chunking.ts +254 -0
- package/src/compat/css/inline-css.ts +73 -0
- package/src/compat/css/lightningcss.ts +90 -0
- package/src/compat/css/modules.ts +373 -0
- package/src/compat/css/nonce.ts +30 -0
- package/src/compat/css/sass-plugin.ts +65 -0
- package/src/compat/css/sass.ts +392 -0
- package/src/compat/css/styled-jsx-runtime.ts +80 -0
- package/src/compat/css/styled-jsx.ts +49 -0
- package/src/compat/edge-runtime.ts +71 -0
- package/src/compat/export/client.ts +112 -0
- package/src/compat/export/index.ts +272 -0
- package/src/compat/export/standalone.ts +207 -0
- package/src/compat/image-optimizer/cache.ts +119 -0
- package/src/compat/image-optimizer/detect.ts +143 -0
- package/src/compat/image-optimizer/index.ts +601 -0
- package/src/compat/image-optimizer/source.ts +243 -0
- package/src/compat/index.ts +458 -0
- package/src/compat/lifecycle/after-scope.ts +86 -0
- package/src/compat/lifecycle/after.ts +173 -0
- package/src/compat/lifecycle/error-funnel.ts +306 -0
- package/src/compat/lifecycle/error-serialize.ts +87 -0
- package/src/compat/lifecycle/error-ui.ts +167 -0
- package/src/compat/lifecycle/instrumentation-client.ts +138 -0
- package/src/compat/lifecycle/instrumentation.ts +277 -0
- package/src/compat/lifecycle/node-console.ts +19 -0
- package/src/compat/lifecycle/testmode.ts +263 -0
- package/src/compat/mdx/compile.ts +219 -0
- package/src/compat/mdx/next-mdx-stub.ts +46 -0
- package/src/compat/mdx/plugin.ts +37 -0
- package/src/compat/metadata-route-artifacts.ts +458 -0
- package/src/compat/metadata.ts +295 -0
- package/src/compat/middleware/manifest.ts +210 -0
- package/src/compat/misc/action-return.ts +173 -0
- package/src/compat/next/cache.ts +211 -0
- package/src/compat/next/canonical-url.ts +35 -0
- package/src/compat/next/client-cache.ts +57 -0
- package/src/compat/next/client-navigation.ts +313 -0
- package/src/compat/next/client-only.ts +3 -0
- package/src/compat/next/client-script.tsx +215 -0
- package/src/compat/next/client-server.ts +39 -0
- package/src/compat/next/config-loader.ts +569 -0
- package/src/compat/next/config.ts +29 -0
- package/src/compat/next/constants.cjs +6 -0
- package/src/compat/next/constants.ts +6 -0
- package/src/compat/next/custom-server.ts +236 -0
- package/src/compat/next/dist/client/components/app-router-headers.ts +32 -0
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +38 -0
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -0
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -0
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -0
- package/src/compat/next/dynamic.tsx +46 -0
- package/src/compat/next/error.tsx +148 -0
- package/src/compat/next/font/cache.ts +171 -0
- package/src/compat/next/font/google.ts +2 -0
- package/src/compat/next/font/index.ts +8 -0
- package/src/compat/next/font/local.ts +5 -0
- package/src/compat/next/font/runtime-client.ts +71 -0
- package/src/compat/next/font/runtime.ts +974 -0
- package/src/compat/next/font/shared.ts +281 -0
- package/src/compat/next/form.tsx +156 -0
- package/src/compat/next/head.tsx +10 -0
- package/src/compat/next/headers.ts +247 -0
- package/src/compat/next/image/config.ts +196 -0
- package/src/compat/next/image/optimizer.ts +96 -0
- package/src/compat/next/image/patterns.ts +103 -0
- package/src/compat/next/image/shared.ts +141 -0
- package/src/compat/next/image/static-metadata.ts +283 -0
- package/src/compat/next/image/validate.ts +269 -0
- package/src/compat/next/image-client.tsx +215 -0
- package/src/compat/next/image-props.ts +575 -0
- package/src/compat/next/image-usage.ts +102 -0
- package/src/compat/next/image.tsx +56 -0
- package/src/compat/next/index.ts +1 -0
- package/src/compat/next/legacy-image.tsx +97 -0
- package/src/compat/next/link-usage.ts +29 -0
- package/src/compat/next/link-validation-transform.ts +200 -0
- package/src/compat/next/link.tsx +466 -0
- package/src/compat/next/navigation.cjs +21 -0
- package/src/compat/next/navigation.ts +188 -0
- package/src/compat/next/offline.ts +51 -0
- package/src/compat/next/og.ts +324 -0
- package/src/compat/next/optimistic-route-state.ts +188 -0
- package/src/compat/next/preferred-region.ts +39 -0
- package/src/compat/next/redirects.ts +131 -0
- package/src/compat/next/resource-hints.ts +136 -0
- package/src/compat/next/rewrites.ts +350 -0
- package/src/compat/next/root-params.ts +142 -0
- package/src/compat/next/router.cjs +49 -0
- package/src/compat/next/router.ts +143 -0
- package/src/compat/next/script.tsx +355 -0
- package/src/compat/next/server-only.ts +3 -0
- package/src/compat/next/server.ts +28 -0
- package/src/compat/next/svgr.ts +58 -0
- package/src/compat/next/telemetry.ts +77 -0
- package/src/compat/next/user-agent.ts +100 -0
- package/src/compat/next/web-vitals.ts +56 -0
- package/src/compat/otel/api.ts +95 -0
- package/src/compat/otel/client-trace-metadata.ts +71 -0
- package/src/compat/otel/fetch-span.ts +77 -0
- package/src/compat/otel/tracer.ts +944 -0
- package/src/compat/pages/client-plugin.ts +108 -0
- package/src/compat/pages/index.ts +527 -0
- package/src/compat/pages/router-state.ts +94 -0
- package/src/compat/ppr/io.ts +38 -0
- package/src/compat/ppr/missing-root-params.ts +105 -0
- package/src/compat/ppr/root-params-scan.ts +164 -0
- package/src/compat/ppr/root-params-transform.ts +75 -0
- package/src/compat/ppr/root-params.ts +129 -0
- package/src/compat/ppr/segment-config-incompat.ts +34 -0
- package/src/compat/protocol.ts +202 -0
- package/src/compat/react/client.ts +59 -0
- package/src/compat/react/compiler-runtime.ts +60 -0
- package/src/compat/react/dom-client.ts +115 -0
- package/src/compat/react/dom-react-server.ts +20 -0
- package/src/compat/react/dom-server.ts +40 -0
- package/src/compat/react/dom.ts +154 -0
- package/src/compat/react/preact.ts +522 -0
- package/src/compat/react/react-server.ts +84 -0
- package/src/compat/react/router-shim.ts +26 -0
- package/src/compat/react/server-component-use.ts +48 -0
- package/src/compat/react/server-inserted-html.ts +87 -0
- package/src/compat/react/server.ts +156 -0
- package/src/compat/react/view-transition.ts +60 -0
- package/src/compat/register/actions.ts +875 -0
- package/src/compat/register/boot.ts +141 -0
- package/src/compat/register/build-tier.ts +11 -0
- package/src/compat/register/build.ts +182 -0
- package/src/compat/register/bundler.ts +587 -0
- package/src/compat/register/cache.ts +85 -0
- package/src/compat/register/client-errors.ts +18 -0
- package/src/compat/register/config.ts +17 -0
- package/src/compat/register/css-extras.ts +120 -0
- package/src/compat/register/edge-runtime.ts +6 -0
- package/src/compat/register/errors.ts +46 -0
- package/src/compat/register/export.ts +23 -0
- package/src/compat/register/font.ts +36 -0
- package/src/compat/register/hooks.ts +34 -0
- package/src/compat/register/image.ts +133 -0
- package/src/compat/register/index.ts +111 -0
- package/src/compat/register/instrumentation-client.ts +35 -0
- package/src/compat/register/lifecycle.ts +86 -0
- package/src/compat/register/mdx.ts +48 -0
- package/src/compat/register/middleware.ts +36 -0
- package/src/compat/register/misc.ts +44 -0
- package/src/compat/register/otel.ts +288 -0
- package/src/compat/register/pages-api.ts +473 -0
- package/src/compat/register/ppr.ts +56 -0
- package/src/compat/register/protocol.ts +57 -0
- package/src/compat/register/proxy.ts +127 -0
- package/src/compat/register/render.ts +268 -0
- package/src/compat/register/routing.ts +410 -0
- package/src/compat/register/segment.ts +1903 -0
- package/src/compat/register/static-image.ts +21 -0
- package/src/compat/register/typed-routes.ts +35 -0
- package/src/compat/register/usecache.ts +131 -0
- package/src/compat/register/validation.ts +56 -0
- package/src/compat/segment/loading-boundary.ts +113 -0
- package/src/compat/segment/page-slot.ts +200 -0
- package/src/compat/segment/tree.ts +481 -0
- package/src/compat/segment/vary-key.ts +102 -0
- package/src/compat/segment/vary-params.ts +551 -0
- package/src/compat/static-params.ts +33 -0
- package/src/compat/tsconfig-defaults.ts +301 -0
- package/src/compat/typecheck/index.ts +1481 -0
- package/src/compat/typecheck/worker.ts +26 -0
- package/src/compat/typed-routes/index.ts +92 -0
- package/src/compat/typed-routes/manifest.ts +356 -0
- package/src/compat/typed-routes/typegen.ts +566 -0
- package/src/compat/validation/errors.ts +159 -0
- package/src/compat/validation/index.ts +1770 -0
- package/src/compat/validation/prerender-diagnostics.ts +1508 -0
- package/src/compat-bootstrap.ts +67 -0
- package/src/config.ts +218 -0
- package/src/css/build.ts +697 -0
- package/src/css/index.ts +2 -0
- package/src/css/postcss.ts +236 -0
- package/src/css/worker.ts +34 -0
- package/src/dev/client-actions.ts +35 -0
- package/src/dev/client-chunk-store.ts +92 -0
- package/src/dev/client-key-cache.ts +178 -0
- package/src/dev/global-css-cache.ts +212 -0
- package/src/dev/imports.ts +2430 -0
- package/src/dev/module-cache.ts +721 -0
- package/src/dev/module-generations.ts +38 -0
- package/src/dev/module-transform.ts +188 -0
- package/src/dev/node-module-bundle-cache.ts +63 -0
- package/src/dev/restart-cache.ts +10 -0
- package/src/dev/route-bundle-key-cache.ts +154 -0
- package/src/dev/route-facts-cache.ts +223 -0
- package/src/dev/server.ts +1710 -0
- package/src/dynamic/source.ts +307 -0
- package/src/dynamic/tree-shake.ts +262 -0
- package/src/env.ts +92 -0
- package/src/extensions.ts +1898 -0
- package/src/index.ts +34 -0
- package/src/internal.ts +43 -0
- package/src/islands/boundary-error.ts +8 -0
- package/src/islands/static-children.ts +37 -0
- package/src/islands/static-slots.ts +106 -0
- package/src/ppr-postpone.ts +24 -0
- package/src/ppr.ts +784 -0
- package/src/proxy.ts +752 -0
- package/src/render/hooks.ts +384 -0
- package/src/render/index.ts +1 -0
- package/src/render/island-context.ts +47 -0
- package/src/render/metadata.ts +857 -0
- package/src/render/renderer.ts +7391 -0
- package/src/render/resource-hints.ts +44 -0
- package/src/render/slots.tsx +679 -0
- package/src/request/context.ts +396 -0
- package/src/resolve/engine.ts +219 -0
- package/src/resolve/imports.ts +1104 -0
- package/src/resolve/scan-facts.ts +474 -0
- package/src/resolve/source-text.ts +86 -0
- package/src/routing/forwarded.ts +41 -0
- package/src/routing/handler.ts +271 -0
- package/src/routing/href.ts +203 -0
- package/src/routing/metadata.ts +1018 -0
- package/src/routing/request-runtime.ts +43 -0
- package/src/routing/routes.ts +2560 -0
- package/src/routing/slots.ts +432 -0
- package/src/runtime/server.ts +3453 -0
- package/src/runtime/vendor.ts +1160 -0
- package/src/style-modules.d.ts +9 -0
- package/src/typegen.ts +151 -0
- package/src/types.ts +725 -0
- package/src/utils/ansi.ts +9 -0
- package/src/utils/content-type.ts +31 -0
- package/src/utils/decode.ts +7 -0
- package/src/utils/dev-profile.ts +31 -0
- package/src/utils/error-log.ts +29 -0
- package/src/utils/fs-cache.ts +31 -0
- package/src/utils/fs.ts +119 -0
- package/src/utils/html.ts +46 -0
- package/src/utils/serialize.ts +378 -0
- package/src/utils/source.ts +35 -0
- package/src/utils/verbose.ts +39 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
forwardRef,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useLayoutEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'preact/compat';
|
|
11
|
+
import type { Ref } from 'preact/compat';
|
|
12
|
+
import type { JSX } from 'preact';
|
|
13
|
+
import { getImagesConfig, resolveImageProps } from './image-props';
|
|
14
|
+
import type { ImageProps, ResolvedImagesConfig } from './image-props';
|
|
15
|
+
|
|
16
|
+
const useSettleEffect = (!process.browser && typeof window === 'undefined') ? useEffect : useLayoutEffect;
|
|
17
|
+
|
|
18
|
+
// The initial hydration pass, before the entry flips __NEXT_HYDRATED (a
|
|
19
|
+
// microtask after the island mounts). Layout effects run inside it, so an image
|
|
20
|
+
// seen here came from the server document — one rendered by a later client
|
|
21
|
+
// update (a click) did not.
|
|
22
|
+
function hydrating(): boolean {
|
|
23
|
+
return (
|
|
24
|
+
(process.browser || typeof window !== 'undefined') &&
|
|
25
|
+
!(window as { __NEXT_HYDRATED?: boolean }).__NEXT_HYDRATED
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type OnLoad = NonNullable<ImageProps['onLoad']>;
|
|
30
|
+
type OnLoadingComplete = NonNullable<ImageProps['onLoadingComplete']>;
|
|
31
|
+
type ImageClientProps = ImageProps & { __pnextConfig?: ResolvedImagesConfig };
|
|
32
|
+
|
|
33
|
+
function handleLoading(
|
|
34
|
+
img: HTMLImageElement | null,
|
|
35
|
+
placeholder: string,
|
|
36
|
+
onLoadRef: { current: OnLoad | undefined },
|
|
37
|
+
onLoadingCompleteRef: { current: OnLoadingComplete | undefined },
|
|
38
|
+
setBlurComplete: (b: boolean) => void,
|
|
39
|
+
): void {
|
|
40
|
+
if (!img) return;
|
|
41
|
+
const src = img.src;
|
|
42
|
+
const marker = img as HTMLImageElement & { 'data-loaded-src'?: string };
|
|
43
|
+
if (marker['data-loaded-src'] === src) return;
|
|
44
|
+
marker['data-loaded-src'] = src;
|
|
45
|
+
const p = 'decode' in img ? img.decode() : Promise.resolve();
|
|
46
|
+
void p.catch(() => undefined).then(() => {
|
|
47
|
+
if (!img.parentElement || !img.isConnected) return;
|
|
48
|
+
if (placeholder !== 'empty') setBlurComplete(true);
|
|
49
|
+
if (onLoadRef.current) {
|
|
50
|
+
const event = new Event('load');
|
|
51
|
+
Object.defineProperty(event, 'target', { writable: false, value: img });
|
|
52
|
+
let prevented = false;
|
|
53
|
+
let stopped = false;
|
|
54
|
+
onLoadRef.current({
|
|
55
|
+
...(event as unknown as Record<string, unknown>),
|
|
56
|
+
nativeEvent: event,
|
|
57
|
+
currentTarget: img,
|
|
58
|
+
target: img,
|
|
59
|
+
isDefaultPrevented: () => prevented,
|
|
60
|
+
isPropagationStopped: () => stopped,
|
|
61
|
+
persist: () => undefined,
|
|
62
|
+
preventDefault: () => {
|
|
63
|
+
prevented = true;
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
},
|
|
66
|
+
stopPropagation: () => {
|
|
67
|
+
stopped = true;
|
|
68
|
+
event.stopPropagation();
|
|
69
|
+
},
|
|
70
|
+
} as unknown as JSX.TargetedEvent<HTMLImageElement, Event>);
|
|
71
|
+
}
|
|
72
|
+
if (onLoadingCompleteRef.current) onLoadingCompleteRef.current(img);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function useMergedRef<T>(refA: Ref<T> | undefined, refB: Ref<T> | undefined): (el: T | null) => void {
|
|
77
|
+
const cleanupA = useRef<(() => void) | null>(null);
|
|
78
|
+
const cleanupB = useRef<(() => void) | null>(null);
|
|
79
|
+
return useCallback(
|
|
80
|
+
(current: T | null) => {
|
|
81
|
+
if (current === null) {
|
|
82
|
+
cleanupA.current?.();
|
|
83
|
+
cleanupA.current = null;
|
|
84
|
+
cleanupB.current?.();
|
|
85
|
+
cleanupB.current = null;
|
|
86
|
+
} else {
|
|
87
|
+
if (refA) cleanupA.current = applyRef(refA, current);
|
|
88
|
+
if (refB) cleanupB.current = applyRef(refB, current);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
[refA, refB],
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function applyRef<T>(ref: NonNullable<Ref<T>>, current: T): () => void {
|
|
96
|
+
if (typeof ref === 'function') {
|
|
97
|
+
const cleanup = ref(current);
|
|
98
|
+
return typeof cleanup === 'function' ? cleanup : () => (ref as (v: T | null) => void)(null);
|
|
99
|
+
}
|
|
100
|
+
(ref as { current: T | null }).current = current;
|
|
101
|
+
return () => {
|
|
102
|
+
(ref as { current: T | null }).current = null;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const Image = forwardRef<HTMLImageElement, ImageClientProps>(function Image(
|
|
107
|
+
{ __pnextConfig, ...imageProps },
|
|
108
|
+
forwardedRef,
|
|
109
|
+
) {
|
|
110
|
+
const config = __pnextConfig ?? getImagesConfig();
|
|
111
|
+
const [blurComplete, setBlurComplete] = useState(false);
|
|
112
|
+
const [showAltText, setShowAltText] = useState(false);
|
|
113
|
+
const { props, meta } = resolveImageProps(imageProps, config, blurComplete, showAltText);
|
|
114
|
+
|
|
115
|
+
const { onLoad, onError, onLoadingComplete } = imageProps;
|
|
116
|
+
const onLoadRef = useRef(onLoad);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
onLoadRef.current = onLoad;
|
|
119
|
+
}, [onLoad]);
|
|
120
|
+
const onLoadingCompleteRef = useRef(onLoadingComplete);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
onLoadingCompleteRef.current = onLoadingComplete;
|
|
123
|
+
}, [onLoadingComplete]);
|
|
124
|
+
|
|
125
|
+
const placeholder = meta.placeholder;
|
|
126
|
+
const renderedSrc = typeof props.src === 'string' ? props.src : '';
|
|
127
|
+
const insertedImgRef = useRef<HTMLImageElement | null>(null);
|
|
128
|
+
const settledSrcRef = useRef<string | undefined>(undefined);
|
|
129
|
+
// True while an error the app must not see is outstanding: the server-rendered
|
|
130
|
+
// request that was already in flight when this component mounted. See below.
|
|
131
|
+
const swallowErrorRef = useRef(false);
|
|
132
|
+
useSettleEffect(() => {
|
|
133
|
+
const img = insertedImgRef.current;
|
|
134
|
+
if (img === null || settledSrcRef.current === renderedSrc) return;
|
|
135
|
+
settledSrcRef.current = renderedSrc;
|
|
136
|
+
// An error on a server-rendered image happens before onError is attached,
|
|
137
|
+
// so it is lost — Next re-issues the request once at mount to surface it.
|
|
138
|
+
if (onError) {
|
|
139
|
+
if (img.complete) {
|
|
140
|
+
const currentSrc = img.src;
|
|
141
|
+
img.src = currentSrc;
|
|
142
|
+
} else if (hydrating()) {
|
|
143
|
+
// Same situation, mid-flight: the request started with the document,
|
|
144
|
+
// so its outcome still predates this mount. Swallow it and re-issue
|
|
145
|
+
// once it lands, so onError sees an error raised against this mount.
|
|
146
|
+
swallowErrorRef.current = true;
|
|
147
|
+
img.addEventListener(
|
|
148
|
+
'error',
|
|
149
|
+
() => {
|
|
150
|
+
swallowErrorRef.current = false;
|
|
151
|
+
const failedSrc = img.src;
|
|
152
|
+
img.src = failedSrc;
|
|
153
|
+
},
|
|
154
|
+
{ once: true },
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const settle = () =>
|
|
159
|
+
handleLoading(img, placeholder, onLoadRef, onLoadingCompleteRef, setBlurComplete);
|
|
160
|
+
if (img.complete) settle();
|
|
161
|
+
}, [renderedSrc, placeholder, onError]);
|
|
162
|
+
|
|
163
|
+
const ref = useMergedRef<HTMLImageElement>(forwardedRef, insertedImgRef);
|
|
164
|
+
const extra = imageProps as unknown as {
|
|
165
|
+
crossOrigin?: string;
|
|
166
|
+
referrerPolicy?: string;
|
|
167
|
+
fetchPriority?: string;
|
|
168
|
+
};
|
|
169
|
+
const preloadLink =
|
|
170
|
+
meta.preload ? (
|
|
171
|
+
<link
|
|
172
|
+
rel="preload"
|
|
173
|
+
as="image"
|
|
174
|
+
href={meta.imgAttributes.srcSet ? undefined : meta.imgAttributes.src}
|
|
175
|
+
{...({
|
|
176
|
+
imagesrcset: meta.imgAttributes.srcSet,
|
|
177
|
+
imagesizes: meta.imgAttributes.sizes,
|
|
178
|
+
crossOrigin: extra.crossOrigin,
|
|
179
|
+
referrerPolicy: extra.referrerPolicy,
|
|
180
|
+
fetchpriority: extra.fetchPriority,
|
|
181
|
+
} as Record<string, unknown>)}
|
|
182
|
+
/>
|
|
183
|
+
) : null;
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<>
|
|
187
|
+
{preloadLink}
|
|
188
|
+
<img
|
|
189
|
+
{...props}
|
|
190
|
+
data-nimg={meta.fill ? 'fill' : '1'}
|
|
191
|
+
ref={ref}
|
|
192
|
+
onLoad={event => {
|
|
193
|
+
handleLoading(
|
|
194
|
+
event.currentTarget,
|
|
195
|
+
placeholder,
|
|
196
|
+
onLoadRef,
|
|
197
|
+
onLoadingCompleteRef,
|
|
198
|
+
setBlurComplete,
|
|
199
|
+
);
|
|
200
|
+
}}
|
|
201
|
+
onError={event => {
|
|
202
|
+
setShowAltText(true);
|
|
203
|
+
if (placeholder !== 'empty') setBlurComplete(true);
|
|
204
|
+
// The pre-mount failure is re-issued by the settle effect; the app
|
|
205
|
+
// hears about the retry, not the request that predated its handler.
|
|
206
|
+
if (swallowErrorRef.current) return;
|
|
207
|
+
onError?.(event);
|
|
208
|
+
}}
|
|
209
|
+
/>
|
|
210
|
+
</>
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
export default Image;
|
|
215
|
+
export { Image };
|