Skip to content

Commit

Permalink
feat(plugin-history-sync, link): If no path is given, the default pat…
Browse files Browse the repository at this point in the history
…h is used
  • Loading branch information
tonyfromundefined committed Jan 20, 2025
1 parent dbd9e6d commit 447022b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 37 deletions.
5 changes: 4 additions & 1 deletion extensions/link/src/future/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export function Link<K extends RegisteredActivityName>(props: LinkProps<K>) {
const { path } = match;
const { makeTemplate, urlPatternOptions } = config.historySync;

const template = makeTemplate({ path }, urlPatternOptions);
const template = makeTemplate(
{ activityName: props.activityName, path },
urlPatternOptions,
);

return template.fill(props.activityParams);
}, [config, props.activityName, props.activityParams]);
Expand Down
40 changes: 15 additions & 25 deletions extensions/plugin-history-sync/src/historySyncPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ export function historySyncPlugin<

const activityRoutes = sortActivityRoutes(normalizeActivityRouteMap(routes));

function matchActivityRoute(activityName: string) {
return (
activityRoutes.find((r) => r.activityName === activityName) ?? {
activityName,
}
);
}

return () => {
let pushFlag = 0;
let silentFlag = false;
Expand Down Expand Up @@ -193,9 +201,7 @@ export function historySyncPlugin<
onInit({ actions: { getStack, dispatchEvent, push, stepPush } }) {
const rootActivity = getStack().activities[0];

const match = activityRoutes.find(
(r) => r.activityName === rootActivity.name,
)!;
const match = matchActivityRoute(rootActivity.name);
const template = makeTemplate(match, options.urlPatternOptions);

const lastStep = last(rootActivity.steps);
Expand Down Expand Up @@ -347,10 +353,7 @@ export function historySyncPlugin<
return;
}

const match = activityRoutes.find(
(r) => r.activityName === activity.name,
)!;

const match = matchActivityRoute(activity.name);
const template = makeTemplate(match, options.urlPatternOptions);

requestHistoryTick(() => {
Expand All @@ -371,10 +374,7 @@ export function historySyncPlugin<
return;
}

const match = activityRoutes.find(
(r) => r.activityName === activity.name,
)!;

const match = matchActivityRoute(activity.name);
const template = makeTemplate(match, options.urlPatternOptions);

requestHistoryTick(() => {
Expand All @@ -395,10 +395,7 @@ export function historySyncPlugin<
return;
}

const match = activityRoutes.find(
(r) => r.activityName === activity.name,
)!;

const match = matchActivityRoute(activity.name);
const template = makeTemplate(match, options.urlPatternOptions);

requestHistoryTick(() => {
Expand All @@ -418,10 +415,7 @@ export function historySyncPlugin<
return;
}

const match = activityRoutes.find(
(r) => r.activityName === activity.name,
)!;

const match = matchActivityRoute(activity.name);
const template = makeTemplate(match, options.urlPatternOptions);

requestHistoryTick(() => {
Expand All @@ -438,9 +432,7 @@ export function historySyncPlugin<
});
},
onBeforePush({ actionParams, actions: { overrideActionParams } }) {
const match = activityRoutes.find(
(r) => r.activityName === actionParams.activityName,
)!;
const match = matchActivityRoute(actionParams.activityName);
const template = makeTemplate(match, options.urlPatternOptions);
const path = template.fill(actionParams.activityParams);

Expand All @@ -456,9 +448,7 @@ export function historySyncPlugin<
actionParams,
actions: { overrideActionParams, getStack },
}) {
const match = activityRoutes.find(
(r) => r.activityName === actionParams.activityName,
)!;
const match = matchActivityRoute(actionParams.activityName);
const template = makeTemplate(match, options.urlPatternOptions);
const path = template.fill(actionParams.activityParams);

Expand Down
53 changes: 46 additions & 7 deletions extensions/plugin-history-sync/src/makeTemplate.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { makeTemplate } from "./makeTemplate";

test("makeTemplate - 패스 파라미터만 있을 때는 패스 파라미터로 붙입니다", () => {
const template = makeTemplate({ path: "/articles/:articleId" });
const template = makeTemplate({
activityName: "Article",
path: "/articles/:articleId",
});

expect(
template.fill({
Expand All @@ -11,7 +14,10 @@ test("makeTemplate - 패스 파라미터만 있을 때는 패스 파라미터로
});

test("makeTemplate - 패스 파라미터에 추가 파라미터가 주어질 때는 쿼리 파라미터로 붙입니다", () => {
const template = makeTemplate({ path: "/articles/:articleId" });
const template = makeTemplate({
activityName: "Article",
path: "/articles/:articleId",
});

expect(
template.fill({
Expand All @@ -22,7 +28,10 @@ test("makeTemplate - 패스 파라미터에 추가 파라미터가 주어질 때
});

test("makeTemplate - 추가 파라미터만 있을 때는 모두 쿼리 파라미터로 붙입니다", () => {
const template = makeTemplate({ path: "/home/" });
const template = makeTemplate({
activityName: "Article",
path: "/home/",
});

expect(
template.fill({
Expand All @@ -33,19 +42,28 @@ test("makeTemplate - 추가 파라미터만 있을 때는 모두 쿼리 파라
});

test("makeTemplate - 패스가 같으면 빈 객체를 내려줍니다", () => {
const template = makeTemplate({ path: "/articles/" });
const template = makeTemplate({
activityName: "Article",
path: "/articles/",
});

expect(template.parse("/articles/")).toStrictEqual({});
});

test("makeTemplate - 패스가 다르면 null을 내려줍니다", () => {
const template = makeTemplate({ path: "/articles/" });
const template = makeTemplate({
activityName: "Article",
path: "/articles/",
});

expect(template.parse("/not-articles/")).toEqual(null);
});

test("makeTemplate - 패스 파라미터와 쿼리 파라미터를 적절하게 파싱합니다", () => {
const template = makeTemplate({ path: "/articles/:articleId" });
const template = makeTemplate({
activityName: "Article",
path: "/articles/:articleId",
});

expect(template.parse("/articles/1234/?title=hello")).toStrictEqual({
articleId: "1234",
Expand All @@ -54,7 +72,10 @@ test("makeTemplate - 패스 파라미터와 쿼리 파라미터를 적절하게
});

test("makeTemplate - 패스 파라미터에 `undefined` 값이 포함된 경우 삭제합니다", () => {
const template = makeTemplate({ path: "/articles" });
const template = makeTemplate({
activityName: "Article",
path: "/articles",
});

expect(
template.fill({
Expand All @@ -66,6 +87,7 @@ test("makeTemplate - 패스 파라미터에 `undefined` 값이 포함된 경우

test("makeTemplate - parse with given decode function", () => {
const template = makeTemplate({
activityName: "Article",
path: "/articles/:articleId",
decode: ({ articleId }) => ({
articleId: Number(articleId),
Expand All @@ -76,3 +98,20 @@ test("makeTemplate - parse with given decode function", () => {
articleId: 1234,
});
});

test("makeTemplate - If no path is given, the default path is `/.activities/*`.", () => {
const template = makeTemplate({
activityName: "Article",
path: undefined as any,
decode: ({ articleId }) => ({
articleId: Number(articleId),
}),
});

expect(
template.fill({
articleId: "1234",
title: "hello",
}),
).toEqual("/.activities/Article/?articleId=1234&title=hello");
});
9 changes: 5 additions & 4 deletions extensions/plugin-history-sync/src/makeTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import UrlPattern from "url-pattern";

import type { Route } from "./RouteLike";
import type { ActivityRoute } from "./ActivityRoute";

export function pathToUrl(path: string) {
return new URL(path, "file://");
Expand Down Expand Up @@ -46,9 +45,11 @@ export interface UrlPatternOptions {
}

export function makeTemplate<T>(
{ path, decode }: Route<T>,
route: { activityName: string } & Partial<ActivityRoute<T>>,
urlPatternOptions?: UrlPatternOptions,
) {
const path =
route.path ?? `/.activities/${encodeURIComponent(route.activityName)}`;
const pattern = new UrlPattern(`${path}(/)`, urlPatternOptions);

const onlyAsterisk = path === "*" || path === "/*";
Expand Down Expand Up @@ -103,7 +104,7 @@ export function makeTemplate<T>(
...pathParams,
};

return decode ? decode(params) : params;
return route.decode ? route.decode(params) : params;
},
variableCount,
};
Expand Down

0 comments on commit 447022b

Please sign in to comment.