@jsenv/navi 0.18.25 → 0.18.26

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.
@@ -174,9 +174,6 @@ const ActionRenderer = ({
174
174
  if (errorBoundary) {
175
175
  return renderError(errorBoundary, "ui_error", action);
176
176
  }
177
- if (error) {
178
- return renderError(error, "action_error", action);
179
- }
180
177
  if (aborted) {
181
178
  return renderAborted(action);
182
179
  }
@@ -199,6 +196,9 @@ const ActionRenderer = ({
199
196
  }
200
197
  return renderLoading(action);
201
198
  }
199
+ if (error) {
200
+ return renderError(error, "action_error", action);
201
+ }
202
202
  return renderCompletedSafe(data, action);
203
203
  };
204
204
  const defaultPromise = Promise.resolve();
@@ -1376,7 +1376,6 @@ const createAction = (callback, rootOptions = {}) => {
1376
1376
  completed = false,
1377
1377
  renderLoadedAsync,
1378
1378
  sideEffect = () => {},
1379
- keepOldData = false,
1380
1379
  meta = {},
1381
1380
 
1382
1381
  outputSignal,
@@ -1418,10 +1417,10 @@ const createAction = (callback, rootOptions = {}) => {
1418
1417
  };
1419
1418
  /**
1420
1419
  * Stop the action completely - this will:
1421
- * 1. Abort the action if it's currently running
1422
- * 2. Reset the action to IDLE state
1420
+ * 1. Abort if it's currently running
1421
+ * 2. Reset action running signal to IDLE state
1423
1422
  * 3. Clean up any resources and side effects
1424
- * 4. Reset data to initial value (unless keepOldData is true)
1423
+ * 4. Reset data/error to initial value
1425
1424
  */
1426
1425
  const reset = (options) => {
1427
1426
  return dispatchSingleAction(action, "reset", options);
@@ -1751,7 +1750,6 @@ const createAction = (callback, rootOptions = {}) => {
1751
1750
  actionAbortMap.set(action, abort);
1752
1751
 
1753
1752
  batch(() => {
1754
- errorSignal.value = null;
1755
1753
  runningStateSignal.value = RUNNING;
1756
1754
  if (!isPrerun) {
1757
1755
  isPrerunSignal.value = false;
@@ -1798,6 +1796,7 @@ const createAction = (callback, rootOptions = {}) => {
1798
1796
  const value = resultToValue
1799
1797
  ? resultToValue(runResult, action)
1800
1798
  : runResult;
1799
+ errorSignal.value = undefined;
1801
1800
  valueSignal.value = value;
1802
1801
  runningStateSignal.value = COMPLETED;
1803
1802
  const data = dataSignal.value;
@@ -1916,8 +1915,8 @@ const createAction = (callback, rootOptions = {}) => {
1916
1915
 
1917
1916
  actionPromiseMap.delete(action);
1918
1917
  batch(() => {
1919
- errorSignal.value = null;
1920
- if (!keepOldData && !willRunOrPrerun) {
1918
+ if (!willRunOrPrerun) {
1919
+ errorSignal.value = undefined;
1921
1920
  valueSignal.value = valueInitial;
1922
1921
  if (outputSignal) {
1923
1922
  outputSignal.value = undefined;
@@ -1958,10 +1957,14 @@ const createAction = (callback, rootOptions = {}) => {
1958
1957
  * @param {boolean} options.rerunOnChange - Ensures the action is rerun every time a signal value is modified.
1959
1958
  * This enables live updates - for example, performing an HTTP GET request every time
1960
1959
  * a list of filters changes, providing real-time results without user interaction.
1961
- * @param {boolean} options.transferData - Ensures the new action inherits the data from the current action (if any).
1962
- * This enables "Apply Filters" workflows where users modify filters but results are only
1963
- * updated when they explicitly trigger the action (e.g., clicking an "Apply" button).
1964
- * The old data remains visible until the new action completes.
1960
+ * @param {boolean} options.inheritData - When true, each new target action starts fresh with no inherited state.
1961
+ * By default (false), the proxy carries over the previous target's value and error into the new action.
1962
+ * This keeps the facade in sync with the latest known data: `action.dataSignal.value` only changes when a
1963
+ * new action completes, not when it starts loading. Code that needs to distinguish loading state can still
1964
+ * check `action.runningState`, while code that just reads `action.data` always sees the most recent
1965
+ * available data — even while a newer action is in flight.
1966
+ * This default also enables "Apply Filters" workflows where parameters change but the action only reruns
1967
+ * on an explicit user trigger: the previous results remain visible until the new action completes.
1965
1968
  * @param {function} options.onChange - Optional callback triggered when the target action changes
1966
1969
  */
1967
1970
  const createActionProxyFromSignal = (
@@ -1970,7 +1973,7 @@ const createActionProxyFromSignal = (
1970
1973
  {
1971
1974
  runOnce = false,
1972
1975
  rerunOnChange = false,
1973
- transferData = false,
1976
+ inheritData = true,
1974
1977
  onChange,
1975
1978
  syncParams,
1976
1979
  } = {},
@@ -2001,6 +2004,18 @@ const createActionProxyFromSignal = (
2001
2004
  let currentActionPrivateProperties = getActionPrivateProperties(action);
2002
2005
  let actionTargetPreviousWeakRef = null;
2003
2006
 
2007
+ const createTarget = (params) => {
2008
+ if (inheritData) {
2009
+ const previousActionTarget = actionTargetPreviousWeakRef?.deref();
2010
+ const previousTarget = previousActionTarget || action;
2011
+ return action.bindParams(params, {
2012
+ error: previousTarget.errorSignal.peek(),
2013
+ value: previousTarget.valueSignal.peek(),
2014
+ });
2015
+ }
2016
+ return action.bindParams(params);
2017
+ };
2018
+
2004
2019
  let isUpdatingTarget = false;
2005
2020
  const _updateTarget = (context) => {
2006
2021
  if (isUpdatingTarget) {
@@ -2030,7 +2045,7 @@ const createActionProxyFromSignal = (
2030
2045
  currentAction = action;
2031
2046
  currentActionPrivateProperties = getActionPrivateProperties(action);
2032
2047
  } else {
2033
- actionTarget = action.bindParams(params);
2048
+ actionTarget = createTarget(params);
2034
2049
  if (previousActionTarget === actionTarget) {
2035
2050
  return;
2036
2051
  }
@@ -2073,6 +2088,7 @@ const createActionProxyFromSignal = (
2073
2088
  return nameSignal.value;
2074
2089
  },
2075
2090
  });
2091
+ actionWeakMap.set(actionProxy, actionProxy);
2076
2092
  }
2077
2093
 
2078
2094
  // Create our own signal for params that we control completely
@@ -2215,15 +2231,6 @@ const createActionProxyFromSignal = (
2215
2231
  return true;
2216
2232
  };
2217
2233
 
2218
- if (transferData) {
2219
- onActionTargetChange((actionTarget, actionTargetPrevious) => {
2220
- if (actionTarget && actionTargetPrevious) {
2221
- const targetValueSignal = actionTarget.valueSignal;
2222
- const previousValueSignal = actionTargetPrevious.valueSignal;
2223
- targetValueSignal.value = previousValueSignal.value;
2224
- }
2225
- });
2226
- }
2227
2234
  if (runOnce) {
2228
2235
  onActionTargetChange((actionTarget, actionTargetPrevious) => {
2229
2236
  if (!actionTargetPrevious && actionTarget) {
@@ -2323,9 +2330,11 @@ getActionPrivateProperties(COMPLETED_ACTION).performRun({});
2323
2330
  const actionRunEffect = (
2324
2331
  action,
2325
2332
  deriveActionParamsFromSignals,
2326
- { debounce, actionOptions } = {},
2333
+ { debounce, ...options } = {},
2327
2334
  ) => {
2328
- if (typeof action === "function") action = createAction(action);
2335
+ if (typeof action === "function") {
2336
+ action = createAction(action);
2337
+ }
2329
2338
  let lastTruthyParams;
2330
2339
  let actionParamsSignal = computed(() => {
2331
2340
  const params = deriveActionParamsFromSignals();
@@ -2393,7 +2402,7 @@ const actionRunEffect = (
2393
2402
  }
2394
2403
  }
2395
2404
  },
2396
- ...actionOptions,
2405
+ ...options,
2397
2406
  });
2398
2407
  if (actionParamsSignal.peek()) {
2399
2408
  actionRunnedByThisEffect.run({ reason: "initial truthy params" });