Skip to content

Commit

Permalink
enhance: Correctly log throttlable fetch actions in devtool
Browse files Browse the repository at this point in the history
  • Loading branch information
ntucker committed Jul 18, 2024
1 parent 06df291 commit 597a1b2
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changeset/hip-donkeys-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@data-client/core': patch
'@data-client/react': patch
---

Disable devtools dispatch feature as it is not usable
10 changes: 10 additions & 0 deletions .changeset/rude-donuts-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@data-client/core': patch
'@data-client/react': patch
---

fix: Devtools correctly logs fetch actions

We inspect fetches against inflight to see if they are throttled;
However, we previously did this after we sent the action to NetworkManager, which
meant it would also skip logging any throttlable fetches - even if they were not throttled.
6 changes: 6 additions & 0 deletions .changeset/wild-rabbits-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@data-client/core': patch
'@data-client/react': patch
---

Improve typing for devtools options
15 changes: 14 additions & 1 deletion packages/core/src/manager/DevtoolsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ if (process.env.NODE_ENV !== 'production') {
DEFAULT_CONFIG = {
name: `Data Client: ${globalThis.document?.title}`,
autoPause: true,
features: {
pause: true, // start/pause recording of dispatched actions
lock: true, // lock/unlock dispatching actions and side effects
persist: false, // persist states on page reloading
export: true, // export history of actions in a file
import: 'custom', // import history of actions from a file
jump: true, // jump back and forth (time travelling)
skip: true, // skip (cancel) actions
reorder: true, // drag and drop actions in the history list
dispatch: false, // dispatch custom actions or action creators
test: false, // generate tests for the selected actions
},
actionSanitizer: (action: ActionTypes) => {
if (!('endpoint' in action)) return action;
return {
Expand Down Expand Up @@ -131,6 +143,7 @@ export default class DevToolsManager implements Manager {
const reducer = createReducer(controller as any);
let state = controller.getState();
return next => action => {
const shouldSkip = skipLogging?.(action);
const ret = next(action);
if (this.started) {
// we track state changes here since getState() will only update after a batch commit
Expand All @@ -139,7 +152,7 @@ export default class DevToolsManager implements Manager {
state = controller.getState();
}
ret.then(() => {
if (skipLogging?.(action)) return;
if (shouldSkip) return;
this.handleAction(action, state.optimistic.reduce(reducer, state));
});
return ret;
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/manager/devtoolsTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
type Action = any;
import { ActionTypes } from '../actions.js';
import { State } from '../types.js';

type Action = ActionTypes;
type ActionCreator<T> = any;

// taken from https://github.com/reduxjs/redux-devtools/blob/main/packages/redux-devtools-extension/src/index.ts
Expand Down Expand Up @@ -78,7 +81,7 @@ export interface EnhancerOptions {
/**
* function which takes `state` object and index as arguments, and should return `state` object back.
*/
stateSanitizer?: <S>(state: S, index: number) => S;
stateSanitizer?: <S extends State<unknown>>(state: S, index: number) => S;
/**
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
Expand All @@ -105,7 +108,10 @@ export interface EnhancerOptions {
* called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
* Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
*/
predicate?: <S, A extends Action>(state: S, action: A) => boolean;
predicate?: <S extends State<unknown>, A extends Action>(
state: S,
action: A,
) => boolean;
/**
* if specified as `false`, it will not record the changes till clicking on `Start recording` button.
* Available only for Redux enhancer, for others use `autoPause`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ declare class PollingSubscription implements Subscription {
protected lastFetchTime(): number;
}

type Action = any;
type Action = ActionTypes;
type ActionCreator<T> = any;
interface EnhancerOptions {
/**
Expand Down Expand Up @@ -950,7 +950,7 @@ interface EnhancerOptions {
/**
* function which takes `state` object and index as arguments, and should return `state` object back.
*/
stateSanitizer?: <S>(state: S, index: number) => S;
stateSanitizer?: <S extends State<unknown>>(state: S, index: number) => S;
/**
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
Expand All @@ -977,7 +977,7 @@ interface EnhancerOptions {
* called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
* Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
*/
predicate?: <S, A extends Action>(state: S, action: A) => boolean;
predicate?: <S extends State<unknown>, A extends Action>(state: S, action: A) => boolean;
/**
* if specified as `false`, it will not record the changes till clicking on `Start recording` button.
* Available only for Redux enhancer, for others use `autoPause`.
Expand Down

0 comments on commit 597a1b2

Please sign in to comment.