Files
scrap/node_modules/next/dist/shared/lib/router/action-queue.js
2024-09-24 03:52:46 +00:00

162 lines
6.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ActionQueueContext: null,
createMutableActionQueue: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ActionQueueContext: function() {
return ActionQueueContext;
},
createMutableActionQueue: function() {
return createMutableActionQueue;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _routerreducertypes = require("../../../client/components/router-reducer/router-reducer-types");
const _routerreducer = require("../../../client/components/router-reducer/router-reducer");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const ActionQueueContext = _react.default.createContext(null);
function runRemainingActions(actionQueue, setState) {
if (actionQueue.pending !== null) {
actionQueue.pending = actionQueue.pending.next;
if (actionQueue.pending !== null) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
runAction({
actionQueue,
action: actionQueue.pending,
setState
});
} else {
// No more actions are pending, check if a refresh is needed
if (actionQueue.needsRefresh) {
actionQueue.needsRefresh = false;
actionQueue.dispatch({
type: _routerreducertypes.ACTION_REFRESH,
origin: window.location.origin
}, setState);
}
}
}
}
async function runAction(param) {
let { actionQueue, action, setState } = param;
const prevState = actionQueue.state;
if (!prevState) {
// This shouldn't happen as the state is initialized in the dispatcher if it's not set
throw new Error("Invariant: Router state not initialized");
}
actionQueue.pending = action;
const payload = action.payload;
const actionResult = actionQueue.action(prevState, payload);
function handleResult(nextState) {
// if we discarded this action, the state should also be discarded
if (action.discarded) {
return;
}
actionQueue.state = nextState;
if (actionQueue.devToolsInstance) {
actionQueue.devToolsInstance.send(payload, nextState);
}
runRemainingActions(actionQueue, setState);
action.resolve(nextState);
}
// if the action is a promise, set up a callback to resolve it
if ((0, _routerreducertypes.isThenable)(actionResult)) {
actionResult.then(handleResult, (err)=>{
runRemainingActions(actionQueue, setState);
action.reject(err);
});
} else {
handleResult(actionResult);
}
}
function dispatchAction(actionQueue, payload, setState) {
let resolvers = {
resolve: setState,
reject: ()=>{}
};
// most of the action types are async with the exception of restore
// it's important that restore is handled quickly since it's fired on the popstate event
// and we don't want to add any delay on a back/forward nav
// this only creates a promise for the async actions
if (payload.type !== _routerreducertypes.ACTION_RESTORE) {
// Create the promise and assign the resolvers to the object.
const deferredPromise = new Promise((resolve, reject)=>{
resolvers = {
resolve,
reject
};
});
(0, _react.startTransition)(()=>{
// we immediately notify React of the pending promise -- the resolver is attached to the action node
// and will be called when the associated action promise resolves
setState(deferredPromise);
});
}
const newAction = {
payload,
next: null,
resolve: resolvers.resolve,
reject: resolvers.reject
};
// Check if the queue is empty
if (actionQueue.pending === null) {
// The queue is empty, so add the action and start it immediately
// Mark this action as the last in the queue
actionQueue.last = newAction;
runAction({
actionQueue,
action: newAction,
setState
});
} else if (payload.type === _routerreducertypes.ACTION_NAVIGATE || payload.type === _routerreducertypes.ACTION_RESTORE) {
// Navigations (including back/forward) take priority over any pending actions.
// Mark the pending action as discarded (so the state is never applied) and start the navigation action immediately.
actionQueue.pending.discarded = true;
// Mark this action as the last in the queue
actionQueue.last = newAction;
// if the pending action was a server action, mark the queue as needing a refresh once events are processed
if (actionQueue.pending.payload.type === _routerreducertypes.ACTION_SERVER_ACTION) {
actionQueue.needsRefresh = true;
}
runAction({
actionQueue,
action: newAction,
setState
});
} else {
// The queue is not empty, so add the action to the end of the queue
// It will be started by runRemainingActions after the previous action finishes
if (actionQueue.last !== null) {
actionQueue.last.next = newAction;
}
actionQueue.last = newAction;
}
}
function createMutableActionQueue() {
const actionQueue = {
state: null,
dispatch: (payload, setState)=>dispatchAction(actionQueue, payload, setState),
action: async (state, action)=>{
if (state === null) {
throw new Error("Invariant: Router state not initialized");
}
const result = (0, _routerreducer.reducer)(state, action);
return result;
},
pending: null,
last: null
};
return actionQueue;
}
//# sourceMappingURL=action-queue.js.map