Skip to content

Commit 416b65d

Browse files
fix(plugin-history-sync): revert activity params string coercion (#705) (#717)
1 parent 78e7b84 commit 416b65d

17 files changed

Lines changed: 116 additions & 3531 deletions
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@stackflow/core": patch
3+
---
4+
5+
Remove the internal optional `stepContext` event fields and `ActivityStep.context`
6+
storage that were added for plugin-history-sync URL preservation.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@stackflow/plugin-history-sync": patch
3+
---
4+
5+
Withdraw the activity and step param string coercion introduced in `1.11.0`.
6+
Internal navigation now preserves non-string param values at runtime again, while
7+
URL arrivals continue to use decoded URL params as before.

β€Žcore/src/Stack.tsβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { BaseDomainEvent } from "event-types/_base";
12
import type {
23
DomainEvent,
34
PoppedEvent,
@@ -18,7 +19,6 @@ export type ActivityStep = {
1819
params: {
1920
[key: string]: string | undefined;
2021
};
21-
context?: {};
2222
enteredBy: PushedEvent | ReplacedEvent | StepPushedEvent | StepReplacedEvent;
2323
exitedBy?: ReplacedEvent | PoppedEvent | StepReplacedEvent | StepPoppedEvent;
2424
zIndex: number;

β€Žcore/src/activity-utils/makeActivityReducer.tsβ€Ž

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ export function makeActivityReducer(context: {
6868
const newRoute = {
6969
id: event.stepId,
7070
params: event.stepParams,
71-
...(event.stepContext ? { context: event.stepContext } : null),
7271
enteredBy: event,
7372
zIndex: activity.zIndex,
7473
hasZIndex: event.hasZIndex ?? false,
@@ -89,7 +88,6 @@ export function makeActivityReducer(context: {
8988
const newRoute = {
9089
id: event.stepId,
9190
params: event.stepParams,
92-
...(event.stepContext ? { context: event.stepContext } : null),
9391
enteredBy: event,
9492
zIndex: activity.zIndex,
9593
hasZIndex: event.hasZIndex ?? false,
@@ -109,7 +107,7 @@ export function makeActivityReducer(context: {
109107
* Pop the last step
110108
* If there are params in the previous step, set them as the new params
111109
*/
112-
StepPopped: (activity: Activity, _event: StepPoppedEvent): Activity => {
110+
StepPopped: (activity: Activity, event: StepPoppedEvent): Activity => {
113111
activity.steps.pop();
114112

115113
const beforeActivityParams = last(activity.steps)?.params;

β€Žcore/src/aggregate.tsβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ export function aggregate(inputEvents: DomainEvent[], now: number): Stack {
7575
{
7676
...step,
7777
zIndex: lastStepZIndex + (step.hasZIndex ? 1 : 0),
78-
...(step.context ? { context: step.context } : null),
7978
},
8079
];
8180
}, []);

β€Žcore/src/event-types/StepPushedEvent.tsβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export type StepPushedEvent = BaseDomainEvent<
77
stepParams: {
88
[key: string]: string | undefined;
99
};
10-
stepContext?: {};
1110
targetActivityId?: string;
1211
hasZIndex?: boolean;
1312
}

β€Žcore/src/event-types/StepReplacedEvent.tsβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export type StepReplacedEvent = BaseDomainEvent<
77
stepParams: {
88
[key: string]: string | undefined;
99
};
10-
stepContext?: {};
1110
targetActivityId?: string;
1211
hasZIndex?: boolean;
1312
}

β€Ždocs/pages/docs/advanced/history-sync.en.mdxβ€Ž

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,6 @@ The `historySyncPlugin` accepts two options: `config` and `fallbackActivity`.
7272
**Warning** - When mapping activity parameters to path parameters, ensure that the parameter values are URL-safe. If special characters that are not URL-safe are used, query parameters may appear duplicated.
7373
</Callout>
7474

75-
## Runtime Coercion of Activity Params
76-
77-
Regardless of how an activity is entered, including `push()`, `replace()`, `pushStep()`, `replaceStep()`, or URL arrival with or without a `decode` hook, the params you receive from `useActivityParams()` are always `string | undefined` at runtime.
78-
79-
```tsx
80-
// These two paths used to produce different runtime types. They don't anymore.
81-
push("ArticleActivity", { visible: true }) // store: { visible: "true" }
82-
// URL arrival: /articles/1?visible=true // store: { visible: "true" }
83-
```
84-
85-
The `encode` hook on a route still receives the original typed params, so you can use `encode: ({ visible }) => ({ visible: visible ? "y" : "n" })` exactly as before. Coercion happens at the `@stackflow/plugin-history-sync` boundary, after `encode` has consumed the typed values to build the URL.
86-
87-
<Callout emoji="⚠️">
88-
**Migration note for `decode` users**: if you previously relied on `decode` to inject typed values, such as `decode: (p) => ({ count: Number(p.count) })`, and read them back via `useActivityParams().count` as a number, that value is now a string in the store. Perform the type coercion at the usage site instead: `Number(params.count)`.
89-
</Callout>
90-
9175
<Callout emoji="⚑️">
9276
In a server-side rendering environment, the `window.location` value is not available, so the initial activity cannot be determined. To set the initial activity, add the path value to the `req.path` field in the `initialContext` of the Stack as follows:
9377

β€Ždocs/pages/docs/advanced/history-sync.ko.mdxβ€Ž

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,6 @@ const { Stack } = stackflow({
7575
특수문자λ₯Ό μ‚¬μš©ν•˜λŠ” 경우 query parameterκ°€ μ€‘λ³΅ν•΄μ„œ λ‚˜νƒ€λ‚  수 μžˆμ–΄μš”.
7676
</Callout>
7777

78-
## μ•‘ν‹°λΉ„ν‹° νŒŒλΌλ―Έν„°μ˜ λŸ°νƒ€μž„ κ°•μ œ λ³€ν™˜
79-
80-
앑티비티에 μ–΄λ–»κ²Œ μ§„μž…ν–ˆλŠ”μ§€μ™€ 관계없이, `push()`, `replace()`, `pushStep()`, `replaceStep()`, λ˜λŠ” `decode` ν›… μœ λ¬΄μ™€ λ¬΄κ΄€ν•œ URL 직접 μ§„μž… λͺ¨λ‘μ—μ„œ `useActivityParams()`둜 λ°›λŠ” νŒŒλΌλ―Έν„°λŠ” λŸ°νƒ€μž„μ— 항상 `string | undefined`μ˜ˆμš”.
81-
82-
```tsx
83-
// μ΄μ „μ—λŠ” 두 κ²½λ‘œκ°€ λŸ°νƒ€μž„μ— μ„œλ‘œ λ‹€λ₯Έ νƒ€μž…μ„ λ°˜ν™˜ν–ˆμ§€λ§Œ, μ΄μ œλŠ” λ™μΌν•΄μš”.
84-
push("ArticleActivity", { visible: true }) // μŠ€ν† μ–΄: { visible: "true" }
85-
// URL μ§„μž…: /articles/1?visible=true // μŠ€ν† μ–΄: { visible: "true" }
86-
```
87-
88-
라우트의 `encode` 훅은 μ—¬μ „νžˆ μ›λ³Έμ˜ νƒ€μž…μ΄ 적용된 νŒŒλΌλ―Έν„°λ₯Ό λ°›μ•„μš”. 예λ₯Ό λ“€μ–΄ `encode: ({ visible }) => ({ visible: visible ? "y" : "n" })`λŠ” 이전과 λ™μΌν•˜κ²Œ λ™μž‘ν•΄μš”. λ¬Έμžμ—΄ν™”λŠ” `encode`κ°€ URL 생성을 μœ„ν•΄ νƒ€μž…μ΄ 적용된 값을 μ†ŒλΉ„ν•œ 이후에, `@stackflow/plugin-history-sync` κ²½κ³„μ—μ„œ μ΄λ€„μ Έμš”.
89-
90-
<Callout emoji="⚠️">
91-
**`decode` μ‚¬μš©μžλ₯Ό μœ„ν•œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ•ˆλ‚΄**: 이전에 `decode`둜 νƒ€μž…μ΄ 적용된 값을 μ£Όμž…ν•΄μ„œ, 예λ₯Ό λ“€μ–΄ `decode: (p) => ({ count: Number(p.count) })`, `useActivityParams().count`λ₯Ό 숫자둜 μ‚¬μš©ν•˜μ…¨λ‹€λ©΄, 이제 ν•΄λ‹Ή 값은 μŠ€ν† μ–΄μ—μ„œ λ¬Έμžμ—΄μ΄μ—μš”. μ‚¬μš© μ§€μ μ—μ„œ νƒ€μž… λ³€ν™˜μ„ ν•΄μ£Όμ„Έμš”: `Number(params.count)`.
92-
</Callout>
93-
9478
<Callout emoji="⚑️">
9579
μ„œλ²„μ‚¬μ΄λ“œ λ Œλ”λ§ ν™˜κ²½μ—μ„œλŠ” `window.location` 값이 μ—†μœΌλ―€λ‘œ 초기 μ•‘ν‹°λΉ„ν‹°λ₯Ό κ²°μ •ν•  수 μ—†μ–΄μš”.
9680
초기 μ•‘ν‹°λΉ„ν‹°λ₯Ό κ²°μ •ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같이 Stack의 `initialContext`에 `req.path` ν•„λ“œμ— path 값을 λ„£μ–΄μ£Όμ„Έμš”.

β€Žextensions/plugin-history-sync/INTENT.mdβ€Ž

Lines changed: 0 additions & 71 deletions
This file was deleted.

0 commit comments

Comments
Β (0)