akanjs 3.1.0-rc.3 → 3.1.0-rc.4
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/client/rscNavigation.ts +1 -4
- package/client/transitionTypes.ts +0 -4
- package/package.json +1 -1
- package/server/routeState.ts +0 -6
- package/server/rscClient.tsx +1 -19
- package/server/rscWorker.tsx +0 -7
- package/types/client/rscNavigation.d.ts +0 -1
- package/types/client/transitionTypes.d.ts +0 -2
- package/types/server/routeState.d.ts +1 -4
- package/ui/System/SSR.tsx +2 -35
- package/ui/styles.css +0 -103
- package/client/viewTransition.ts +0 -10
- package/types/client/viewTransition.d.ts +0 -3
package/client/rscNavigation.ts
CHANGED
|
@@ -3,10 +3,7 @@ declare global {
|
|
|
3
3
|
var __AKAN_RSC_IS_FROM_CACHE__: (() => boolean) | undefined;
|
|
4
4
|
var __AKAN_RSC_REFRESH__: ((options?: { buildId?: number }) => Promise<void>) | undefined;
|
|
5
5
|
var __AKAN_RSC_NAVIGATE__:
|
|
6
|
-
| ((
|
|
7
|
-
href: string,
|
|
8
|
-
options?: { replace?: boolean; scrollToTop?: boolean; shallow?: boolean; pop?: boolean },
|
|
9
|
-
) => Promise<void>)
|
|
6
|
+
| ((href: string, options?: { replace?: boolean; scrollToTop?: boolean; shallow?: boolean }) => Promise<void>)
|
|
10
7
|
| undefined;
|
|
11
8
|
var __AKAN_DEV_SYNC_NAVIGATION__: ((href: string, kind: "push" | "replace" | "back" | "pop") => void) | undefined;
|
|
12
9
|
var __AKAN_DEV_SYNC_NAVIGATION_APPLYING__: boolean | undefined;
|
|
@@ -1,6 +1,2 @@
|
|
|
1
1
|
export const transitionTypes = ["none", "fade", "bottomUp", "stack", "scaleOut"] as const;
|
|
2
2
|
export type TransitionType = (typeof transitionTypes)[number];
|
|
3
|
-
|
|
4
|
-
/** The class `ui/styles.css` animates a page by when a navigation plays `transition` forward (push) or back (pop). */
|
|
5
|
-
export const viewTransitionClassOf = (transition: Exclude<TransitionType, "none">, direction: "push" | "pop") =>
|
|
6
|
-
`akan-${transition}-${direction}` as const;
|
package/package.json
CHANGED
package/server/routeState.ts
CHANGED
|
@@ -27,8 +27,6 @@ export interface AkanRouterStateV1 {
|
|
|
27
27
|
href: string;
|
|
28
28
|
routeId: string;
|
|
29
29
|
segments: AkanRouteSegmentState[];
|
|
30
|
-
/** The route's `.config({ transition })`, which the browser plays as a view transition on the way in and out. */
|
|
31
|
-
transition?: string;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
export type AkanHeadSnapshotTag = "title" | "meta" | "link";
|
|
@@ -134,7 +132,6 @@ export function isAkanRouterStateV1(value: unknown): value is AkanRouterStateV1
|
|
|
134
132
|
(state.buildId === undefined || typeof state.buildId === "number") &&
|
|
135
133
|
typeof state.href === "string" &&
|
|
136
134
|
typeof state.routeId === "string" &&
|
|
137
|
-
(state.transition === undefined || typeof state.transition === "string") &&
|
|
138
135
|
Array.isArray(state.segments) &&
|
|
139
136
|
state.segments.every(isSegmentState)
|
|
140
137
|
);
|
|
@@ -210,12 +207,10 @@ export function createAkanRouterState({
|
|
|
210
207
|
pathRoute,
|
|
211
208
|
href,
|
|
212
209
|
buildId,
|
|
213
|
-
transition,
|
|
214
210
|
}: {
|
|
215
211
|
pathRoute: PathRoute;
|
|
216
212
|
href: string;
|
|
217
213
|
buildId?: number;
|
|
218
|
-
transition?: string;
|
|
219
214
|
}): AkanRouterStateV1 {
|
|
220
215
|
return {
|
|
221
216
|
version: AKAN_RSC_STATE_VERSION,
|
|
@@ -223,7 +218,6 @@ export function createAkanRouterState({
|
|
|
223
218
|
href,
|
|
224
219
|
routeId: pathRoute.path,
|
|
225
220
|
segments: createAkanRouteSegments(pathRoute),
|
|
226
|
-
...(transition && transition !== "none" ? { transition } : {}),
|
|
227
221
|
};
|
|
228
222
|
}
|
|
229
223
|
|
package/server/rscClient.tsx
CHANGED
|
@@ -2,8 +2,6 @@ import { createElement, type ReactNode, startTransition, type Usable, use, useLa
|
|
|
2
2
|
import { hydrateRoot } from "react-dom/client";
|
|
3
3
|
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
|
4
4
|
import type {} from "../client/rscNavigation";
|
|
5
|
-
import { transitionTypes, viewTransitionClassOf } from "../client/transitionTypes";
|
|
6
|
-
import { addTransitionType } from "../client/viewTransition";
|
|
7
5
|
import {
|
|
8
6
|
type AkanHeadSnapshotV1,
|
|
9
7
|
type AkanRouterStateV1,
|
|
@@ -209,13 +207,6 @@ function commitHistory(target: string, replace: boolean | undefined) {
|
|
|
209
207
|
renderedHref = target;
|
|
210
208
|
}
|
|
211
209
|
|
|
212
|
-
function viewTransitionTypeOf(transition: string | undefined, push: boolean): string | null {
|
|
213
|
-
const type = transitionTypes.find((candidate) => candidate === transition);
|
|
214
|
-
if (!type || type === "none") return null;
|
|
215
|
-
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return null;
|
|
216
|
-
return viewTransitionClassOf(type, push ? "push" : "pop");
|
|
217
|
-
}
|
|
218
|
-
|
|
219
210
|
/** Writes the entry without asking the server for the page; only a change that keeps the rendered path qualifies. */
|
|
220
211
|
function navigateShallow(target: string, replace: boolean | undefined): boolean {
|
|
221
212
|
if (pathnameOf(target) !== pathnameOf(renderedHref)) return false;
|
|
@@ -516,11 +507,6 @@ function Root(): ReactNode {
|
|
|
516
507
|
});
|
|
517
508
|
|
|
518
509
|
await nextNode.thenable;
|
|
519
|
-
|
|
520
|
-
const viewTransitionType = viewTransitionTypeOf(
|
|
521
|
-
options.pop ? currentRouterState?.transition : nextNode.routerState?.transition,
|
|
522
|
-
!options.pop,
|
|
523
|
-
);
|
|
524
510
|
const committed = commitLatestRscNavigation({
|
|
525
511
|
cache: rscCache,
|
|
526
512
|
href: target,
|
|
@@ -528,10 +514,6 @@ function Root(): ReactNode {
|
|
|
528
514
|
maxEntries: MAX_RSC_CACHE_ENTRIES,
|
|
529
515
|
startTransition,
|
|
530
516
|
commitThenable: (node) => {
|
|
531
|
-
if (viewTransitionType && addTransitionType) {
|
|
532
|
-
addTransitionType("akan-nav");
|
|
533
|
-
addTransitionType(viewTransitionType);
|
|
534
|
-
}
|
|
535
517
|
currentCommitFromCache = servedFromCache;
|
|
536
518
|
resetAkanSegmentOutletPatches();
|
|
537
519
|
setThenable(node.thenable);
|
|
@@ -564,7 +546,7 @@ window.addEventListener("popstate", (event) => {
|
|
|
564
546
|
|
|
565
547
|
if (!keepsPage)
|
|
566
548
|
void globalThis
|
|
567
|
-
.__AKAN_RSC_NAVIGATE__?.(window.location.href, { replace: true, scrollToTop: false
|
|
549
|
+
.__AKAN_RSC_NAVIGATE__?.(window.location.href, { replace: true, scrollToTop: false })
|
|
568
550
|
?.catch((error: unknown) => hardNavigateAfterRscFailure(window.location.href, true, error));
|
|
569
551
|
window.setTimeout(() => {
|
|
570
552
|
if (globalThis.__AKAN_DEV_SYNC_NAVIGATION_APPLYING__) return;
|
package/server/rscWorker.tsx
CHANGED
|
@@ -491,18 +491,11 @@ export class RscRenderer {
|
|
|
491
491
|
const beforeLoadedKeys = RouteTreeBuilder.getCacheStats().loadedModuleKeys;
|
|
492
492
|
const cacheDecision = match ? this.#getResultCacheEntry(request, urlObj) : { entry: null };
|
|
493
493
|
const cacheEntry = cacheDecision.entry;
|
|
494
|
-
const targetFrame = match
|
|
495
|
-
? await RouteElementComposer.resolveSsrFramePathRoute({
|
|
496
|
-
pathRoute: match.pathRoute,
|
|
497
|
-
basePath: this.#getBasePath(urlObj),
|
|
498
|
-
})
|
|
499
|
-
: null;
|
|
500
494
|
const targetRouterState = match
|
|
501
495
|
? createAkanRouterState({
|
|
502
496
|
pathRoute: match.pathRoute,
|
|
503
497
|
href: urlObj.href,
|
|
504
498
|
buildId: this.#pagesBundleBuildId,
|
|
505
|
-
transition: targetFrame?.pageState.transition,
|
|
506
499
|
})
|
|
507
500
|
: null;
|
|
508
501
|
const searchParams = parseSearchParams(urlObj.search);
|
|
@@ -8,7 +8,6 @@ declare global {
|
|
|
8
8
|
replace?: boolean;
|
|
9
9
|
scrollToTop?: boolean;
|
|
10
10
|
shallow?: boolean;
|
|
11
|
-
pop?: boolean;
|
|
12
11
|
}) => Promise<void>) | undefined;
|
|
13
12
|
var __AKAN_DEV_SYNC_NAVIGATION__: ((href: string, kind: "push" | "replace" | "back" | "pop") => void) | undefined;
|
|
14
13
|
var __AKAN_DEV_SYNC_NAVIGATION_APPLYING__: boolean | undefined;
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export declare const transitionTypes: readonly ["none", "fade", "bottomUp", "stack", "scaleOut"];
|
|
2
2
|
export type TransitionType = (typeof transitionTypes)[number];
|
|
3
|
-
/** The class `ui/styles.css` animates a page by when a navigation plays `transition` forward (push) or back (pop). */
|
|
4
|
-
export declare const viewTransitionClassOf: (transition: Exclude<TransitionType, "none">, direction: "push" | "pop") => "akan-stack-pop" | "akan-stack-push" | "akan-fade-pop" | "akan-fade-push" | "akan-bottomUp-pop" | "akan-bottomUp-push" | "akan-scaleOut-pop" | "akan-scaleOut-push";
|
|
@@ -23,8 +23,6 @@ export interface AkanRouterStateV1 {
|
|
|
23
23
|
href: string;
|
|
24
24
|
routeId: string;
|
|
25
25
|
segments: AkanRouteSegmentState[];
|
|
26
|
-
/** The route's `.config({ transition })`, which the browser plays as a view transition on the way in and out. */
|
|
27
|
-
transition?: string;
|
|
28
26
|
}
|
|
29
27
|
export type AkanHeadSnapshotTag = "title" | "meta" | "link";
|
|
30
28
|
export interface AkanHeadSnapshotNode {
|
|
@@ -70,11 +68,10 @@ export declare function readAkanRouterStateResponseHeader(headers: Headers): Aka
|
|
|
70
68
|
export declare function encodeAkanRscPatchSegmentPath(segmentPath: string[]): string;
|
|
71
69
|
export declare function decodeAkanRscPatchSegmentPath(value: string | null | undefined): string[] | null;
|
|
72
70
|
export declare function readAkanRscPatchMetadataResponseHeaders(headers: Headers): AkanRscPatchMetadata | null;
|
|
73
|
-
export declare function createAkanRouterState({ pathRoute, href, buildId,
|
|
71
|
+
export declare function createAkanRouterState({ pathRoute, href, buildId, }: {
|
|
74
72
|
pathRoute: PathRoute;
|
|
75
73
|
href: string;
|
|
76
74
|
buildId?: number;
|
|
77
|
-
transition?: string;
|
|
78
75
|
}): AkanRouterStateV1;
|
|
79
76
|
export declare function createAkanRouteSegments(pathRoute: PathRoute): AkanRouteSegmentState[];
|
|
80
77
|
export declare function createAkanSegmentOutletKey(segmentPath: string[], segmentIndex: number): string | null;
|
package/ui/System/SSR.tsx
CHANGED
|
@@ -7,20 +7,10 @@ import {
|
|
|
7
7
|
type ReactFont,
|
|
8
8
|
router,
|
|
9
9
|
Translator,
|
|
10
|
-
transitionTypes,
|
|
11
10
|
usePage,
|
|
12
|
-
viewTransitionClassOf,
|
|
13
11
|
} from "akanjs/client";
|
|
14
12
|
import { getRequestFrameState, setRequestTheme } from "akanjs/fetch";
|
|
15
|
-
import {
|
|
16
|
-
Children,
|
|
17
|
-
type CSSProperties,
|
|
18
|
-
Fragment,
|
|
19
|
-
type ReactNode,
|
|
20
|
-
Suspense,
|
|
21
|
-
type ViewTransitionClassPerType,
|
|
22
|
-
} from "react";
|
|
23
|
-
import { ViewTransition } from "../../client/viewTransition";
|
|
13
|
+
import { Children, type CSSProperties, Fragment, type ReactNode, Suspense } from "react";
|
|
24
14
|
import { FontCss } from "../fontCss";
|
|
25
15
|
import { frameSlotContainerClassNames, frameSlotContentClassNames, frameSlotStyles } from "../Layout/frameSlot";
|
|
26
16
|
import { Load } from "../Load";
|
|
@@ -124,18 +114,6 @@ const ServerFontFace = ({ fonts }: { fonts: ReactFont[] }) => {
|
|
|
124
114
|
);
|
|
125
115
|
};
|
|
126
116
|
|
|
127
|
-
const pageViewTransition: ViewTransitionClassPerType = Object.fromEntries([
|
|
128
|
-
["default", "none"],
|
|
129
|
-
...transitionTypes.flatMap((transition) =>
|
|
130
|
-
transition === "none"
|
|
131
|
-
? []
|
|
132
|
-
: (["push", "pop"] as const).map((direction) => {
|
|
133
|
-
const type = viewTransitionClassOf(transition, direction);
|
|
134
|
-
return [type, type];
|
|
135
|
-
}),
|
|
136
|
-
),
|
|
137
|
-
]);
|
|
138
|
-
|
|
139
117
|
interface SSRWrapperProps {
|
|
140
118
|
className?: string;
|
|
141
119
|
appName: string;
|
|
@@ -220,18 +198,7 @@ const SSRWrapper = ({
|
|
|
220
198
|
layoutStyle === "mobile" && "left-1/2 h-screen w-full max-w-[600px] -translate-x-1/2",
|
|
221
199
|
)}
|
|
222
200
|
>
|
|
223
|
-
{
|
|
224
|
-
<ViewTransition
|
|
225
|
-
default="none"
|
|
226
|
-
enter={pageViewTransition}
|
|
227
|
-
exit={pageViewTransition}
|
|
228
|
-
update={pageViewTransition}
|
|
229
|
-
>
|
|
230
|
-
{Children.toArray(children)}
|
|
231
|
-
</ViewTransition>
|
|
232
|
-
) : (
|
|
233
|
-
Children.toArray(children)
|
|
234
|
-
)}
|
|
201
|
+
{Children.toArray(children)}
|
|
235
202
|
</div>
|
|
236
203
|
</div>
|
|
237
204
|
</div>
|
package/ui/styles.css
CHANGED
|
@@ -323,109 +323,6 @@ body.akan-mobile-document {
|
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
/* Route transitions on the web: an RSC navigation tags itself `akan-<transition>-<push|pop>` from the route's
|
|
327
|
-
`.config({ transition })`, and the page content's ViewTransition takes that class. The rest of the page holds. */
|
|
328
|
-
:root:active-view-transition-type(akan-nav)::view-transition-old(root),
|
|
329
|
-
:root:active-view-transition-type(akan-nav)::view-transition-new(root) {
|
|
330
|
-
animation: none;
|
|
331
|
-
}
|
|
332
|
-
::view-transition-old(.akan-stack-push) {
|
|
333
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-out-left;
|
|
334
|
-
}
|
|
335
|
-
::view-transition-new(.akan-stack-push) {
|
|
336
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-right;
|
|
337
|
-
}
|
|
338
|
-
::view-transition-old(.akan-stack-pop) {
|
|
339
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-out-right;
|
|
340
|
-
}
|
|
341
|
-
::view-transition-new(.akan-stack-pop) {
|
|
342
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-left;
|
|
343
|
-
}
|
|
344
|
-
::view-transition-old(.akan-bottomUp-push),
|
|
345
|
-
::view-transition-new(.akan-bottomUp-pop) {
|
|
346
|
-
animation: none;
|
|
347
|
-
}
|
|
348
|
-
::view-transition-new(.akan-bottomUp-push) {
|
|
349
|
-
animation: 280ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-up;
|
|
350
|
-
}
|
|
351
|
-
::view-transition-old(.akan-bottomUp-pop) {
|
|
352
|
-
animation: 240ms ease-in both akan-vt-out-down;
|
|
353
|
-
}
|
|
354
|
-
::view-transition-old(.akan-fade-push),
|
|
355
|
-
::view-transition-old(.akan-fade-pop) {
|
|
356
|
-
animation: 180ms ease-in both akan-vt-fade-out;
|
|
357
|
-
}
|
|
358
|
-
::view-transition-new(.akan-fade-push),
|
|
359
|
-
::view-transition-new(.akan-fade-pop) {
|
|
360
|
-
animation: 180ms ease-out both akan-vt-fade-in;
|
|
361
|
-
}
|
|
362
|
-
::view-transition-old(.akan-scaleOut-push) {
|
|
363
|
-
animation: 220ms ease-in both akan-vt-shrink-out;
|
|
364
|
-
}
|
|
365
|
-
::view-transition-new(.akan-scaleOut-push) {
|
|
366
|
-
animation: 220ms ease-out both akan-vt-fade-in;
|
|
367
|
-
}
|
|
368
|
-
::view-transition-old(.akan-scaleOut-pop) {
|
|
369
|
-
animation: 200ms ease-in both akan-vt-fade-out;
|
|
370
|
-
}
|
|
371
|
-
::view-transition-new(.akan-scaleOut-pop) {
|
|
372
|
-
animation: 220ms ease-out both akan-vt-grow-in;
|
|
373
|
-
}
|
|
374
|
-
@keyframes akan-vt-in-right {
|
|
375
|
-
from {
|
|
376
|
-
transform: translateX(100%);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
@keyframes akan-vt-out-left {
|
|
380
|
-
to {
|
|
381
|
-
transform: translateX(-30%);
|
|
382
|
-
opacity: 0.6;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
@keyframes akan-vt-in-left {
|
|
386
|
-
from {
|
|
387
|
-
transform: translateX(-30%);
|
|
388
|
-
opacity: 0.6;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
@keyframes akan-vt-out-right {
|
|
392
|
-
to {
|
|
393
|
-
transform: translateX(100%);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
@keyframes akan-vt-in-up {
|
|
397
|
-
from {
|
|
398
|
-
transform: translateY(100%);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
@keyframes akan-vt-out-down {
|
|
402
|
-
to {
|
|
403
|
-
transform: translateY(100%);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
@keyframes akan-vt-fade-in {
|
|
407
|
-
from {
|
|
408
|
-
opacity: 0;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
@keyframes akan-vt-fade-out {
|
|
412
|
-
to {
|
|
413
|
-
opacity: 0;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
@keyframes akan-vt-shrink-out {
|
|
417
|
-
to {
|
|
418
|
-
transform: scale(0.94);
|
|
419
|
-
opacity: 0;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
@keyframes akan-vt-grow-in {
|
|
423
|
-
from {
|
|
424
|
-
transform: scale(0.94);
|
|
425
|
-
opacity: 0;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
326
|
/* Always-included keyframes (non-theme animations) */
|
|
430
327
|
@keyframes smaller {
|
|
431
328
|
0% {
|
package/client/viewTransition.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ComponentType, ViewTransitionProps } from "react";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
const react = React as {
|
|
5
|
-
ViewTransition?: ComponentType<ViewTransitionProps>;
|
|
6
|
-
addTransitionType?: (type: string) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const ViewTransition = react.ViewTransition;
|
|
10
|
-
export const addTransitionType = react.addTransitionType;
|