@jsenv/navi 0.29.53 → 0.29.54
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.
- package/dist/jsenv_navi.js +99 -14
- package/dist/jsenv_navi.js.map +5 -4
- package/docs/error_handling.md +44 -14
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -13091,8 +13091,7 @@ const setActionPrivateProperties = (action, properties) => {
|
|
|
13091
13091
|
* the screen that will is often not even mounted — a route action runs before
|
|
13092
13092
|
* its page renders, which is precisely the case a guess made at failure time
|
|
13093
13093
|
* gets wrong. So nothing is guessed. The error is let go, and whoever displays
|
|
13094
|
-
* it SAYS so by marking it; what
|
|
13095
|
-
* chance was displayed by nobody, and only that is reported as unhandled.
|
|
13094
|
+
* it SAYS so by marking it; what nobody ever took is reported as unhandled.
|
|
13096
13095
|
*
|
|
13097
13096
|
* The mark is `__handled_by__`, the same one the jsenv supervisor reads to stay
|
|
13098
13097
|
* out of the way of an error the app is already showing — one mark, one meaning:
|
|
@@ -13112,22 +13111,58 @@ const errorIsDisplayed = (error) => {
|
|
|
13112
13111
|
};
|
|
13113
13112
|
|
|
13114
13113
|
/**
|
|
13115
|
-
*
|
|
13116
|
-
*
|
|
13117
|
-
*
|
|
13118
|
-
*
|
|
13119
|
-
* (
|
|
13120
|
-
*
|
|
13121
|
-
*
|
|
13122
|
-
*
|
|
13123
|
-
*
|
|
13114
|
+
* A render has read this error — it is now the render tree's business, not this
|
|
13115
|
+
* module's, and there is nothing left to report.
|
|
13116
|
+
*
|
|
13117
|
+
* Whatever the reader does with it is already covered without any deadline: it
|
|
13118
|
+
* displays it (and marks it), or it throws it, and a thrown error either finds a
|
|
13119
|
+
* boundary that displays it or reaches window on its own — `preact/debug`
|
|
13120
|
+
* re-throws every error a boundary caught, and an unbounded one aborts the
|
|
13121
|
+
* render loudly. Reporting it here as well would be a second voice saying the
|
|
13122
|
+
* same thing, always the wrong one, since this module cannot see which of those
|
|
13123
|
+
* happened.
|
|
13124
|
+
*/
|
|
13125
|
+
const errorTakenByRenderSet = new WeakSet();
|
|
13126
|
+
const markErrorAsTakenByRender = (error) => {
|
|
13127
|
+
if (error && typeof error === "object") {
|
|
13128
|
+
errorTakenByRenderSet.add(error);
|
|
13129
|
+
}
|
|
13130
|
+
};
|
|
13131
|
+
|
|
13132
|
+
/**
|
|
13133
|
+
* When the answer "nobody took it" is final.
|
|
13134
|
+
*
|
|
13135
|
+
* The floor is one macrotask: every render that could take the error — Preact's
|
|
13136
|
+
* queue, a Suspense boundary settling on the failure, the boundary above it —
|
|
13137
|
+
* happens in microtasks.
|
|
13138
|
+
*
|
|
13139
|
+
* That floor is enough for an action failing under a page that is already on
|
|
13140
|
+
* screen, and far too early for a route action: it fails ON the url change,
|
|
13141
|
+
* before its page exists, and that page cannot render until the routing that
|
|
13142
|
+
* asked for the data is over. Measured on an offline navigation, the screen
|
|
13143
|
+
* displaying the error arrived ~12ms after this deadline — so the app was told
|
|
13144
|
+
* it had displayed nothing while it was displaying it.
|
|
13145
|
+
*
|
|
13146
|
+
* The browser integration knows when the document has stopped moving and hands
|
|
13147
|
+
* that over here (see installReportDeadlineExtension); nothing else does, and
|
|
13148
|
+
* this module stays free of the DOM. Waiting longer costs nothing now that a
|
|
13149
|
+
* read is enough to call this off: what still reaches the report was read by no
|
|
13150
|
+
* render at all, and a late report about that is as good as a prompt one.
|
|
13151
|
+
*/
|
|
13152
|
+
let waitForDocumentSettled = null;
|
|
13153
|
+
const installReportDeadlineExtension = (fn) => {
|
|
13154
|
+
waitForDocumentSettled = fn;
|
|
13155
|
+
};
|
|
13156
|
+
|
|
13157
|
+
/**
|
|
13158
|
+
* Rethrown rather than logged: an error nobody took is an unhandled error, and
|
|
13124
13159
|
* the runtime already knows what to do with those (window "error" event, jsenv
|
|
13125
13160
|
* overlay in dev). Same trick preact/debug uses for the same reason.
|
|
13126
13161
|
*/
|
|
13127
13162
|
const errorReportedSet = new WeakSet();
|
|
13128
13163
|
const reportErrorIfNobodyDisplaysIt = (error, { action } = {}) => {
|
|
13129
|
-
|
|
13130
|
-
if (errorIsDisplayed(error)) {
|
|
13164
|
+
const decide = () => {
|
|
13165
|
+
if (errorIsDisplayed(error) || errorTakenByRenderSet.has(error)) {
|
|
13131
13166
|
return;
|
|
13132
13167
|
}
|
|
13133
13168
|
if (error && typeof error === "object") {
|
|
@@ -13143,6 +13178,19 @@ const reportErrorIfNobodyDisplaysIt = (error, { action } = {}) => {
|
|
|
13143
13178
|
error.action = action;
|
|
13144
13179
|
}
|
|
13145
13180
|
throw error;
|
|
13181
|
+
};
|
|
13182
|
+
|
|
13183
|
+
setTimeout(() => {
|
|
13184
|
+
if (errorIsDisplayed(error) || errorTakenByRenderSet.has(error)) {
|
|
13185
|
+
// Already taken within the microtasks that followed the failure: the
|
|
13186
|
+
// common case, and there is nothing to wait for.
|
|
13187
|
+
return;
|
|
13188
|
+
}
|
|
13189
|
+
if (waitForDocumentSettled) {
|
|
13190
|
+
waitForDocumentSettled(decide);
|
|
13191
|
+
return;
|
|
13192
|
+
}
|
|
13193
|
+
decide();
|
|
13146
13194
|
});
|
|
13147
13195
|
};
|
|
13148
13196
|
|
|
@@ -22102,6 +22150,39 @@ const browserIntegration = setupBrowserIntegrationViaHistory({
|
|
|
22102
22150
|
isRouting: () => Boolean(updateRoutes),
|
|
22103
22151
|
});
|
|
22104
22152
|
|
|
22153
|
+
/**
|
|
22154
|
+
* How long an error that nothing displayed is given before it is called
|
|
22155
|
+
* unhandled (see action_error_report.js, which knows the rule but not the DOM).
|
|
22156
|
+
*
|
|
22157
|
+
* A route action fails ON the url change, before its page exists: it is the
|
|
22158
|
+
* routing itself that will bring what displays the error, so the answer is only
|
|
22159
|
+
* final once the document has stopped moving AND the frame that paints what it
|
|
22160
|
+
* brought has been through. Anything faster tells an app displaying "you are
|
|
22161
|
+
* offline" that it displayed nothing.
|
|
22162
|
+
*/
|
|
22163
|
+
installReportDeadlineExtension((decide) => {
|
|
22164
|
+
const whenPainted = () => {
|
|
22165
|
+
// The frame that paints what routing brought, then the microtasks after it:
|
|
22166
|
+
// a render claiming the error is on either side of that paint, never later.
|
|
22167
|
+
requestAnimationFrame(() => {
|
|
22168
|
+
setTimeout(decide);
|
|
22169
|
+
});
|
|
22170
|
+
};
|
|
22171
|
+
if (!documentIsBusySignal.peek()) {
|
|
22172
|
+
whenPainted();
|
|
22173
|
+
return;
|
|
22174
|
+
}
|
|
22175
|
+
// Busy right now, so the synchronous first callback of subscribe() says
|
|
22176
|
+
// "busy" and is skipped; what unsubscribes below is a later one.
|
|
22177
|
+
const unsubscribe = documentIsBusySignal.subscribe((documentIsBusy) => {
|
|
22178
|
+
if (documentIsBusy) {
|
|
22179
|
+
return;
|
|
22180
|
+
}
|
|
22181
|
+
unsubscribe();
|
|
22182
|
+
whenPainted();
|
|
22183
|
+
});
|
|
22184
|
+
});
|
|
22185
|
+
|
|
22105
22186
|
setOnAllRouteReady((v) => {
|
|
22106
22187
|
updateRoutes = v;
|
|
22107
22188
|
browserIntegration.init();
|
|
@@ -35861,6 +35942,10 @@ const useActionAsyncData = (action, {
|
|
|
35861
35942
|
throw dismissedPromise;
|
|
35862
35943
|
}
|
|
35863
35944
|
const actionError = action.errorSignal.peek();
|
|
35945
|
+
// A render has it now, whichever way it goes from here (see
|
|
35946
|
+
// action_error_report.js): displayed below, or thrown to a boundary that
|
|
35947
|
+
// displays it — and if none does, the throw reaches window on its own.
|
|
35948
|
+
markErrorAsTakenByRender(actionError);
|
|
35864
35949
|
if (errorEffect === "use") {
|
|
35865
35950
|
// Handed to the component, which is what displays it from here on
|
|
35866
35951
|
// (see action_error_report.js)
|
|
@@ -71839,5 +71924,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
71839
71924
|
})
|
|
71840
71925
|
});
|
|
71841
71926
|
|
|
71842
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
71927
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
71843
71928
|
//# sourceMappingURL=jsenv_navi.js.map
|