@stackflow/plugin-history-sync
Advanced tools
Comparing version 1.6.0 to 1.6.1
@@ -12,3 +12,3 @@ "use strict"; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; | ||
var __spreadValues = (a, b) => { | ||
@@ -26,5 +26,8 @@ for (var prop in b || (b = {})) | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __commonJS = (cb, mod) => function __require() { | ||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; | ||
}; | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
for (var name2 in all) | ||
__defProp(target, name2, { get: all[name2], enumerable: true }); | ||
}; | ||
@@ -49,2 +52,97 @@ var __copyProps = (to, from, except, desc) => { | ||
// ../../.yarn/cache/json-cycle-npm-1.5.0-4c80b4d041-4ce7594eb8.zip/node_modules/json-cycle/cycle.js | ||
var require_cycle = __commonJS({ | ||
"../../.yarn/cache/json-cycle-npm-1.5.0-4c80b4d041-4ce7594eb8.zip/node_modules/json-cycle/cycle.js"(exports, module) { | ||
"use strict"; | ||
(function(global, factory) { | ||
typeof define === "function" && define.amd ? define(factory) : typeof module === "object" && module.exports ? module.exports = factory : global.json = factory; | ||
})(exports, /* @__PURE__ */ function() { | ||
function decycle(object) { | ||
var objects = [], paths = []; | ||
return function derez(value2, path2) { | ||
var i2, name2, nu; | ||
var _value = value2; | ||
try { | ||
_value = value2.toJSON(); | ||
} catch (error) { | ||
} | ||
if (typeof _value === "object" && _value) { | ||
for (i2 = 0; i2 < objects.length; i2 += 1) { | ||
if (objects[i2] === _value) { | ||
return { $ref: paths[i2] }; | ||
} | ||
} | ||
objects.push(_value); | ||
paths.push(path2); | ||
if (Object.prototype.toString.apply(_value) === "[object Array]") { | ||
nu = []; | ||
for (i2 = 0; i2 < _value.length; i2 += 1) { | ||
nu[i2] = derez(_value[i2], path2 + "[" + i2 + "]"); | ||
} | ||
} else { | ||
nu = {}; | ||
for (name2 in _value) { | ||
if (Object.prototype.hasOwnProperty.call(_value, name2)) { | ||
nu[name2] = derez( | ||
_value[name2], | ||
path2 + "[" + JSON.stringify(name2) + "]" | ||
); | ||
} | ||
} | ||
} | ||
return nu; | ||
} | ||
return _value; | ||
}(object, "$"); | ||
} | ||
function retrocycle($) { | ||
var px = /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; | ||
(function rez(value) { | ||
var i, item, name, path; | ||
if (value && typeof value === "object") { | ||
if (Object.prototype.toString.apply(value) === "[object Array]") { | ||
for (i = 0; i < value.length; i += 1) { | ||
item = value[i]; | ||
if (item && typeof item === "object") { | ||
path = item.$ref; | ||
if (typeof path === "string" && px.test(path)) { | ||
value[i] = eval(path); | ||
} else { | ||
rez(item); | ||
} | ||
} | ||
} | ||
} else { | ||
for (name in value) { | ||
if (typeof value[name] === "object") { | ||
item = value[name]; | ||
if (item) { | ||
path = item.$ref; | ||
if (typeof path === "string" && px.test(path)) { | ||
value[name] = eval(path); | ||
} else { | ||
rez(item); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
})($); | ||
return $; | ||
} | ||
return { | ||
decycle, | ||
retrocycle, | ||
stringify: function(object, replacer, space) { | ||
return JSON.stringify(decycle(object), replacer, space); | ||
}, | ||
parse: function($2, reviver) { | ||
return retrocycle(JSON.parse($2, reviver)); | ||
} | ||
}; | ||
}()); | ||
} | ||
}); | ||
// src/index.ts | ||
@@ -96,18 +194,10 @@ var src_exports = {}; | ||
// src/historyState.ts | ||
var import_json_cycle = __toESM(require_cycle()); | ||
var STATE_TAG = "@stackflow/plugin-history-sync"; | ||
function clone(input) { | ||
return JSON.parse(JSON.stringify(input)); | ||
} | ||
function serializeStep(step) { | ||
return clone(step); | ||
} | ||
function serializeActivity(activity) { | ||
return clone(activity); | ||
} | ||
function serializeState(state) { | ||
return { | ||
return (0, import_json_cycle.decycle)({ | ||
_TAG: STATE_TAG, | ||
activity: serializeActivity(state.activity), | ||
step: state.step ? serializeStep(state.step) : void 0 | ||
}; | ||
activity: state.activity, | ||
step: state.step | ||
}); | ||
} | ||
@@ -117,3 +207,3 @@ function safeParseState(state) { | ||
if (typeof _state === "object" && _state !== null && "_TAG" in _state && typeof _state._TAG === "string" && _state._TAG === STATE_TAG) { | ||
return state; | ||
return (0, import_json_cycle.retrocycle)(state); | ||
} | ||
@@ -171,9 +261,9 @@ return null; | ||
var import_url_pattern = __toESM(require("url-pattern")); | ||
function pathToUrl(path) { | ||
return new URL(path, "file://"); | ||
function pathToUrl(path2) { | ||
return new URL(path2, "file://"); | ||
} | ||
function urlSearchParamsToMap(urlSearchParams) { | ||
const map = {}; | ||
urlSearchParams.forEach((value, key) => { | ||
map[key] = value; | ||
urlSearchParams.forEach((value2, key) => { | ||
map[key] = value2; | ||
}); | ||
@@ -195,5 +285,5 @@ return map; | ||
} | ||
function makeTemplate({ path, decode }, urlPatternOptions) { | ||
const pattern = new import_url_pattern.default(`${path}(/)`, urlPatternOptions); | ||
const onlyAsterisk = path === "*" || path === "/*"; | ||
function makeTemplate({ path: path2, decode }, urlPatternOptions) { | ||
const pattern = new import_url_pattern.default(`${path2}(/)`, urlPatternOptions); | ||
const onlyAsterisk = path2 === "*" || path2 === "/*"; | ||
const variableCount = onlyAsterisk ? Number.POSITIVE_INFINITY : pattern.names.length; | ||
@@ -210,4 +300,4 @@ return { | ||
Object.entries(searchParamsMap).reduce( | ||
(acc, [key, value]) => __spreadValues(__spreadValues({}, acc), value ? { | ||
[key]: value | ||
(acc, [key, value2]) => __spreadValues(__spreadValues({}, acc), value2 ? { | ||
[key]: value2 | ||
} : null), | ||
@@ -219,4 +309,4 @@ {} | ||
}, | ||
parse(path2) { | ||
const url = pathToUrl(path2); | ||
parse(path3) { | ||
const url = pathToUrl(path3); | ||
const pathParams = pattern.match(url.pathname); | ||
@@ -235,4 +325,4 @@ const searchParams = urlSearchParamsToMap(url.searchParams); | ||
// src/normalizeRouteInput.ts | ||
function makeRoute(path) { | ||
return typeof path === "string" ? { path } : path; | ||
function makeRoute(path2) { | ||
return typeof path2 === "string" ? { path: path2 } : path2; | ||
} | ||
@@ -264,4 +354,4 @@ function normalizeRouteInput(route) { | ||
var isSplat = (s) => s === "*"; | ||
function computeScore(path) { | ||
const segments = path.split("/"); | ||
function computeScore(path2) { | ||
const segments = path2.split("/"); | ||
let initialScore = segments.length; | ||
@@ -583,6 +673,6 @@ if (segments.some(isSplat)) { | ||
const template = makeTemplate(match, options.urlPatternOptions); | ||
const path = template.fill(actionParams.activityParams); | ||
const path2 = template.fill(actionParams.activityParams); | ||
overrideActionParams(__spreadProps(__spreadValues({}, actionParams), { | ||
activityContext: __spreadProps(__spreadValues({}, actionParams.activityContext), { | ||
path | ||
path: path2 | ||
}) | ||
@@ -599,6 +689,6 @@ })); | ||
const template = makeTemplate(match, options.urlPatternOptions); | ||
const path = template.fill(actionParams.activityParams); | ||
const path2 = template.fill(actionParams.activityParams); | ||
overrideActionParams(__spreadProps(__spreadValues({}, actionParams), { | ||
activityContext: __spreadProps(__spreadValues({}, actionParams.activityContext), { | ||
path | ||
path: path2 | ||
}) | ||
@@ -612,3 +702,3 @@ })); | ||
if (previousActivity) { | ||
for (let i = 0; i < previousActivity.steps.length - 1; i += 1) { | ||
for (let i2 = 0; i2 < previousActivity.steps.length - 1; i2 += 1) { | ||
requestHistoryTick((resolve) => { | ||
@@ -650,3 +740,3 @@ if (!safeParseState(getCurrentState({ history }))) { | ||
const popCount = isRoot ? 0 : steps.length; | ||
for (let i = 0; i < popCount; i += 1) { | ||
for (let i2 = 0; i2 < popCount; i2 += 1) { | ||
requestHistoryTick((resolve) => { | ||
@@ -653,0 +743,0 @@ if (!safeParseState(getCurrentState({ history }))) { |
{ | ||
"name": "@stackflow/plugin-history-sync", | ||
"version": "1.6.0", | ||
"version": "1.6.1", | ||
"repository": { | ||
@@ -49,3 +49,3 @@ "type": "git", | ||
"@stackflow/config": "^1.1.0", | ||
"@stackflow/core": "^1.0.13", | ||
"@stackflow/core": "^1.0.14", | ||
"@stackflow/esbuild-config": "^1.0.3", | ||
@@ -60,2 +60,3 @@ "@stackflow/react": "^1.2.0", | ||
"jest": "^29.7.0", | ||
"json-cycle": "^1.5.0", | ||
"react": "^18.3.1", | ||
@@ -62,0 +63,0 @@ "rimraf": "^3.0.2", |
import type { Activity, ActivityStep } from "@stackflow/core"; | ||
import type { History } from "history"; | ||
import { decycle, retrocycle } from "json-cycle"; | ||
@@ -15,20 +16,8 @@ const STATE_TAG = "@stackflow/plugin-history-sync"; | ||
function clone<T>(input: T): T { | ||
return JSON.parse(JSON.stringify(input)); | ||
} | ||
function serializeStep(step: ActivityStep): ActivityStep { | ||
return clone(step); | ||
} | ||
function serializeActivity(activity: Activity): Activity { | ||
return clone(activity); | ||
} | ||
function serializeState(state: State): SerializedState { | ||
return { | ||
return decycle({ | ||
_TAG: STATE_TAG, | ||
activity: serializeActivity(state.activity), | ||
step: state.step ? serializeStep(state.step) : undefined, | ||
}; | ||
activity: state.activity, | ||
step: state.step, | ||
}); | ||
} | ||
@@ -46,3 +35,3 @@ | ||
) { | ||
return state as State; | ||
return retrocycle<State>(state); | ||
} | ||
@@ -49,0 +38,0 @@ |
@@ -1327,2 +1327,47 @@ import type { | ||
}); | ||
test("historySyncPlugin - activity.context에 cyclic dependency가 있어도 정상적으로 로드됩니다", async () => { | ||
history = createMemoryHistory({ | ||
initialEntries: ["/home"], | ||
}); | ||
const coreStore = stackflow({ | ||
activityNames: ["Home", "Article"], | ||
plugins: [ | ||
historySyncPlugin({ | ||
history, | ||
routes: { | ||
Home: "/home", | ||
Article: "/articles/:articleId", | ||
}, | ||
fallbackActivity: () => "Home", | ||
}), | ||
], | ||
}); | ||
actions = makeActionsProxy({ | ||
actions: coreStore.actions, | ||
}); | ||
const cyclic: any = {}; | ||
cyclic.self = cyclic; | ||
await actions.push({ | ||
activityId: "a1", | ||
activityName: "Article", | ||
activityParams: { | ||
articleId: "1", | ||
}, | ||
activityContext: { | ||
cyclic, | ||
}, | ||
}); | ||
const stack = await actions.getStack(); | ||
expect( | ||
(stack.activities[1].context as any).cyclic === | ||
(stack.activities[1].context as any).cyclic.self, | ||
).toEqual(true); | ||
}); | ||
}); |
@@ -28,4 +28,4 @@ import type { ActivityRoute } from "./ActivityRoute"; | ||
: segment === "" | ||
? emptySegmentValue | ||
: staticSegmentValue), | ||
? emptySegmentValue | ||
: staticSegmentValue), | ||
initialScore, | ||
@@ -32,0 +32,0 @@ ); |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
218798
67
3715
15
4