Socket
Socket
Sign inDemoInstall

@stackflow/plugin-history-sync

Package Overview
Dependencies
9
Maintainers
3
Versions
109
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.18 to 1.4.0-canary.0

dist/ActivityRoute.d.ts

7

dist/historySyncPlugin.d.ts
import type { StackflowReactPlugin } from "@stackflow/react";
import type { History } from "history";
import type { UrlPatternOptions } from "./makeTemplate";
declare type HistorySyncPluginOptions<K extends string> = {
import type { RouteLike } from "./RouteLike";
declare type HistorySyncPluginOptions<T, K extends Extract<keyof T, string>> = {
routes: {
[key in K]: string | string[];
[key in keyof T]: RouteLike<T[key]>;
};

@@ -17,3 +18,3 @@ fallbackActivity: (args: {

[activityName: string]: unknown;
}>(options: HistorySyncPluginOptions<Extract<keyof T, string>>): StackflowReactPlugin<T>;
}, K extends Extract<keyof T, string>>(options: HistorySyncPluginOptions<T, K>): StackflowReactPlugin<T>;
export {};
export { useHistoryTick } from "./HistoryQueueContext";
export * from "./historySyncPlugin";
export { makeTemplate, UrlPatternOptions } from "./makeTemplate";
export { normalizeRoute } from "./normalizeRoute";
export { useRoutes } from "./RoutesContext";

@@ -52,3 +52,2 @@ "use strict";

makeTemplate: () => makeTemplate,
normalizeRoute: () => normalizeRoute,
useHistoryTick: () => useHistoryTick,

@@ -143,2 +142,22 @@ useRoutes: () => useRoutes

// src/makeHistoryTaskQueue.ts
var makeHistoryTaskQueue = (history) => {
let previousTask = Promise.resolve();
const requestHistoryTick = (cb) => {
previousTask = previousTask.then(
() => new Promise((resolve) => {
const clean = history.listen(() => {
clean();
resolve();
});
cb(() => {
clean();
resolve();
});
})
);
};
return { requestHistoryTick };
};
// src/makeTemplate.ts

@@ -169,4 +188,4 @@ var import_url_pattern = __toESM(require("url-pattern"));

}
function makeTemplate(templateStr, urlPatternOptions) {
const pattern = new import_url_pattern.default(`${templateStr}(/)`, urlPatternOptions);
function makeTemplate({ path, decode }, urlPatternOptions) {
const pattern = new import_url_pattern.default(`${path}(/)`, urlPatternOptions);
return {

@@ -190,4 +209,4 @@ fill(params) {

},
parse(path) {
const url = pathToUrl(path);
parse(path2) {
const url = pathToUrl(path2);
const pathParams = pattern.match(url.pathname);

@@ -198,31 +217,29 @@ const searchParams = urlSearchParamsToMap(url.searchParams);

}
return __spreadValues(__spreadValues({}, searchParams), pathParams);
}
return __spreadValues(__spreadValues({}, searchParams), decode ? decode(pathParams) : pathParams);
},
variableCount: pattern.names.length
};
}
// src/normalizeRoute.ts
function normalizeRoute(route) {
return typeof route === "string" ? [route] : route;
// src/normalizeRouteInput.ts
function makeRoute(path) {
return typeof path === "string" ? { path } : path;
}
function normalizeRouteInput(route) {
return (Array.isArray(route) ? route : [route]).map(makeRoute);
}
// src/queue.ts
var makeHistoryTaskQueue = (history) => {
let previousTask = Promise.resolve();
const requestHistoryTick = (cb) => {
previousTask = previousTask.then(
() => new Promise((resolve) => {
const clean = history.listen(() => {
clean();
resolve();
});
cb(() => {
clean();
resolve();
});
})
);
};
return { requestHistoryTick };
};
// src/normalizeActivityRouteMap.ts
function normalizeActivityRouteMap(activityRouteMap) {
const routes = Object.keys(activityRouteMap).flatMap((activityName) => {
const routeInput = activityRouteMap[activityName];
if (!routeInput) {
return [];
}
return normalizeRouteInput(routeInput).map((route) => __spreadValues({
activityName
}, route));
});
return routes;
}

@@ -232,3 +249,3 @@ // src/RoutesContext.tsx

var import_jsx_runtime2 = require("react/jsx-runtime");
var RoutesContext = (0, import_react2.createContext)({});
var RoutesContext = (0, import_react2.createContext)([]);
var RoutesProvider = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RoutesContext.Provider, { value: props.routes, children: props.children });

@@ -240,2 +257,9 @@ RoutesProvider.displayName = "RoutesProvider";

// src/sortActivityRoutes.ts
function sortActivityRoutes(routes) {
return [...routes].sort(
(a, b) => makeTemplate(a).variableCount - makeTemplate(b).variableCount
);
}
// src/historySyncPlugin.tsx

@@ -251,2 +275,5 @@ var import_jsx_runtime3 = require("react/jsx-runtime");

const { location } = history;
const activityRoutes = sortActivityRoutes(
normalizeActivityRouteMap(options.routes)
);
return () => {

@@ -259,3 +286,3 @@ let pushFlag = 0;

wrapStack({ stack }) {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HistoryQueueProvider, { requestHistoryTick, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoutesProvider, { routes: options.routes, children: stack.render() }) });
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HistoryQueueProvider, { requestHistoryTick, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoutesProvider, { routes: activityRoutes, children: stack.render() }) });
},

@@ -279,3 +306,3 @@ overrideInitialEvents({ initialContext }) {

}
function resolvePath() {
function resolveCurrentPath() {
var _a3, _b2;

@@ -290,24 +317,23 @@ if (((_a3 = initialContext == null ? void 0 : initialContext.req) == null ? void 0 : _a3.path) && typeof initialContext.req.path === "string") {

}
const path = resolvePath();
const activityNames = Object.keys(options.routes);
if (path) {
for (const activityName of activityNames) {
const routes = normalizeRoute(options.routes[activityName]);
for (const route of routes) {
const template = makeTemplate(route, options.urlPatternOptions);
const activityParams = template.parse(path);
if (activityParams) {
const activityId = (0, import_core.id)();
return [
(0, import_core.makeEvent)("Pushed", {
activityId,
activityName,
activityParams: __spreadValues({}, activityParams),
eventDate: new Date().getTime() - MINUTE,
activityContext: {
path
}
})
];
}
const currentPath = resolveCurrentPath();
if (currentPath) {
for (const activityRoute of activityRoutes) {
const template = makeTemplate(
activityRoute,
options.urlPatternOptions
);
const activityParams = template.parse(currentPath);
if (activityParams) {
const activityId = (0, import_core.id)();
return [
(0, import_core.makeEvent)("Pushed", {
activityId,
activityName: activityRoute.activityName,
activityParams: __spreadValues({}, activityParams),
eventDate: new Date().getTime() - MINUTE,
activityContext: {
path: currentPath
}
})
];
}

@@ -320,6 +346,6 @@ }

});
const fallbackActivityRoutes = normalizeRoute(
options.routes[fallbackActivityName]
const fallbackActivityRoute = activityRoutes.find(
(r) => r.activityName === fallbackActivityName
);
const fallbackActivityPath = fallbackActivityRoutes[0];
const fallbackActivityPath = fallbackActivityRoute == null ? void 0 : fallbackActivityRoute.path;
return [

@@ -339,6 +365,6 @@ (0, import_core.makeEvent)("Pushed", {

const rootActivity = getStack().activities[0];
const template = makeTemplate(
normalizeRoute(options.routes[rootActivity.name])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === rootActivity.name
);
const template = makeTemplate(match, options.urlPatternOptions);
const lastStep = last(rootActivity.steps);

@@ -455,6 +481,6 @@ requestHistoryTick(

}
const template = makeTemplate(
normalizeRoute(options.routes[activity.name])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === activity.name
);
const template = makeTemplate(match, options.urlPatternOptions);
requestHistoryTick(() => {

@@ -477,6 +503,6 @@ silentFlag = true;

}
const template = makeTemplate(
normalizeRoute(options.routes[activity.name])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === activity.name
);
const template = makeTemplate(match, options.urlPatternOptions);
requestHistoryTick(() => {

@@ -499,6 +525,6 @@ silentFlag = true;

}
const template = makeTemplate(
normalizeRoute(options.routes[activity.name])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === activity.name
);
const template = makeTemplate(match, options.urlPatternOptions);
requestHistoryTick(() => {

@@ -520,6 +546,6 @@ silentFlag = true;

}
const template = makeTemplate(
normalizeRoute(options.routes[activity.name])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === activity.name
);
const template = makeTemplate(match, options.urlPatternOptions);
requestHistoryTick(() => {

@@ -539,6 +565,6 @@ silentFlag = true;

onBeforePush({ actionParams, actions: { overrideActionParams } }) {
const template = makeTemplate(
normalizeRoute(options.routes[actionParams.activityName])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === actionParams.activityName
);
const template = makeTemplate(match, options.urlPatternOptions);
const path = template.fill(actionParams.activityParams);

@@ -555,6 +581,6 @@ overrideActionParams(__spreadProps(__spreadValues({}, actionParams), {

}) {
const template = makeTemplate(
normalizeRoute(options.routes[actionParams.activityName])[0],
options.urlPatternOptions
const match = activityRoutes.find(
(r) => r.activityName === actionParams.activityName
);
const template = makeTemplate(match, options.urlPatternOptions);
const path = template.fill(actionParams.activityParams);

@@ -561,0 +587,0 @@ overrideActionParams(__spreadProps(__spreadValues({}, actionParams), {

@@ -0,1 +1,2 @@

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

@@ -13,9 +14,10 @@ * import { UrlPatternOptions } from "url-pattern"

}
export declare function makeTemplate(templateStr: string, urlPatternOptions?: UrlPatternOptions): {
export declare function makeTemplate<T>({ path, decode }: Route<T>, urlPatternOptions?: UrlPatternOptions): {
fill(params: {
[key: string]: string | undefined;
}): string;
parse<T extends {
parse<T_1 extends {
[key: string]: string | undefined;
}>(path: string): T | null;
}>(path: string): T_1 | null;
variableCount: any;
};
/// <reference types="react" />
export declare type RoutesMap = {
[activityName in string]?: string | string[];
};
export declare const RoutesContext: import("react").Context<RoutesMap>;
interface RoutesProviderProps {
routes: RoutesMap;
import type { ActivityRoute } from "./ActivityRoute";
export declare const RoutesContext: import("react").Context<ActivityRoute<unknown>[]>;
interface RoutesProviderProps<T> {
routes: ActivityRoute<T>[];
children: React.ReactNode;
}
export declare const RoutesProvider: React.FC<RoutesProviderProps>;
export declare function useRoutes(): RoutesMap;
export declare const RoutesProvider: {
<T>(props: RoutesProviderProps<T>): JSX.Element;
displayName: string;
};
export declare function useRoutes(): ActivityRoute<unknown>[];
export {};
{
"name": "@stackflow/plugin-history-sync",
"version": "1.3.18",
"version": "1.4.0-canary.0",
"license": "MIT",

@@ -46,3 +46,3 @@ "exports": {

"@stackflow/eslint-config": "^1.0.2",
"@stackflow/react": "^1.1.7",
"@stackflow/react": "^1.1.8-canary.0",
"@swc/core": "^1.3.35",

@@ -72,3 +72,3 @@ "@swc/jest": "^0.2.24",

"@stackflow/core": "^1.0.10",
"@stackflow/react": "^1.1.7",
"@stackflow/react": "^1.1.8-canary.0",
"@types/react": ">=16.8.0",

@@ -75,0 +75,0 @@ "react": ">=16.8.0"

export { useHistoryTick } from "./HistoryQueueContext";
export * from "./historySyncPlugin";
export { makeTemplate, UrlPatternOptions } from "./makeTemplate";
export { normalizeRoute } from "./normalizeRoute";
export { useRoutes } from "./RoutesContext";
import { makeTemplate } from "./makeTemplate";
test("makeTemplate - 패스 파라미터만 있을 때는 패스 파라미터로 붙입니다", () => {
const template = makeTemplate("/articles/:articleId");
const template = makeTemplate({ path: "/articles/:articleId" });

@@ -14,3 +14,3 @@ expect(

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

@@ -26,3 +26,3 @@ expect(

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

@@ -38,3 +38,3 @@ expect(

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

@@ -45,3 +45,3 @@ expect(template.parse("/articles/")).toStrictEqual({});

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

@@ -52,3 +52,3 @@ expect(template.parse("/not-articles/")).toEqual(null);

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

@@ -62,3 +62,3 @@ expect(template.parse("/articles/1234/?title=hello")).toStrictEqual({

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

@@ -72,1 +72,14 @@ expect(

});
test("makeTemplate - parse with given decode function", () => {
const template = makeTemplate({
path: "/articles/:articleId",
decode: ({ articleId }) => ({
articleId: Number(articleId),
}),
});
expect(template.parse("/articles/1234")).toStrictEqual({
articleId: 1234,
});
});
import UrlPattern from "url-pattern";
import type { Route } from "./RouteLike";
function pathToUrl(path: string) {

@@ -46,7 +48,7 @@ return new URL(path, "file://");

export function makeTemplate(
templateStr: string,
export function makeTemplate<T>(
{ path, decode }: Route<T>,
urlPatternOptions?: UrlPatternOptions,
) {
const pattern = new UrlPattern(`${templateStr}(/)`, urlPatternOptions);
const pattern = new UrlPattern(`${path}(/)`, urlPatternOptions);

@@ -96,6 +98,7 @@ return {

...searchParams,
...pathParams,
...(decode ? decode(pathParams) : pathParams),
};
},
variableCount: (pattern as any).names.length,
};
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc