@autobusal/providers 1.42.0 → 1.43.1
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/Errors/ErrorBoundary.tsx +21 -0
- package/Setup/staleChunk.ts +32 -0
- package/package.json +1 -1
- package/types/users.ts +6 -0
package/Errors/ErrorBoundary.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Message from './Message';
|
|
3
|
+
import { isRecoveringFromStaleChunk } from '../Setup/staleChunk';
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
children: JSX.Element[] | JSX.Element
|
|
@@ -36,6 +37,26 @@ class ErrorBoundary extends React.Component<Props, { hasError: boolean; missing:
|
|
|
36
37
|
|
|
37
38
|
render() {
|
|
38
39
|
if (this.state.hasError) {
|
|
40
|
+
/*
|
|
41
|
+
* Claude - 2026-08-31: say nothing while a stale-chunk reload is on its
|
|
42
|
+
* way.
|
|
43
|
+
*
|
|
44
|
+
* A build replaces every hashed chunk, so a tab left open overnight
|
|
45
|
+
* asks for files that no longer exist the moment somebody clicks a
|
|
46
|
+
* link. Setup/staleChunk catches that and reloads - which works, and
|
|
47
|
+
* which the visitor experienced as a flash of "something went wrong"
|
|
48
|
+
* first, because a synchronous re-render beats a navigation the browser
|
|
49
|
+
* has merely been asked to perform.
|
|
50
|
+
*
|
|
51
|
+
* Nothing at all rather than a spinner: the reload is a few hundred
|
|
52
|
+
* milliseconds away and the document is about to be replaced wholesale.
|
|
53
|
+
* A spinner appearing and vanishing in that window is the same flicker
|
|
54
|
+
* in a friendlier colour.
|
|
55
|
+
*/
|
|
56
|
+
if (isRecoveringFromStaleChunk()) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
39
60
|
return <Message type={ this.state.missing ? 'not_found' : 'error' } />;
|
|
40
61
|
}
|
|
41
62
|
|
package/Setup/staleChunk.ts
CHANGED
|
@@ -93,6 +93,30 @@ const remember = (path: string): boolean => {
|
|
|
93
93
|
* sites. Calling preventDefault stops Vite rethrowing, since we are handling
|
|
94
94
|
* it by replacing the document.
|
|
95
95
|
*/
|
|
96
|
+
/*
|
|
97
|
+
* Whether a recovery reload is already on its way.
|
|
98
|
+
*
|
|
99
|
+
* Claude - 2026-08-31. Ferjolt: "When the page is left open for some time and
|
|
100
|
+
* then click on any link on it, firstly it displays an error page for a
|
|
101
|
+
* extremely short moment and after that renders the right page."
|
|
102
|
+
*
|
|
103
|
+
* That flash is the ERROR BOUNDARY, and it is a race we were always going to
|
|
104
|
+
* lose. A failed dynamic import produces two things at once: this event, and
|
|
105
|
+
* a rejected lazy component that React hands to the nearest boundary. The
|
|
106
|
+
* boundary re-renders synchronously; window.location.reload() only asks the
|
|
107
|
+
* browser to navigate, and the browser is free to paint the frame it already
|
|
108
|
+
* has work for first. So the visitor sees "something went wrong" for one
|
|
109
|
+
* frame of a recovery that is working perfectly.
|
|
110
|
+
*
|
|
111
|
+
* A module-level flag rather than state: the boundary that needs to read this
|
|
112
|
+
* is a class component reacting to a throw, with no chance to subscribe to
|
|
113
|
+
* anything, and the answer has to be available synchronously inside
|
|
114
|
+
* getDerivedStateFromError.
|
|
115
|
+
*/
|
|
116
|
+
let recovering = false;
|
|
117
|
+
|
|
118
|
+
export const isRecoveringFromStaleChunk = (): boolean => recovering;
|
|
119
|
+
|
|
96
120
|
const registerStaleChunkRecovery = (): void => {
|
|
97
121
|
window.addEventListener('vite:preloadError', (event) => {
|
|
98
122
|
if (!remember(budgetKey())) {
|
|
@@ -103,6 +127,14 @@ const registerStaleChunkRecovery = (): void => {
|
|
|
103
127
|
|
|
104
128
|
event.preventDefault();
|
|
105
129
|
|
|
130
|
+
/*
|
|
131
|
+
* Set BEFORE the reload is requested, so the error boundary can already
|
|
132
|
+
* see it on the render that the failed import is about to trigger. Never
|
|
133
|
+
* cleared: the only thing that follows is a fresh document, which starts
|
|
134
|
+
* with a fresh module and the flag back to false.
|
|
135
|
+
*/
|
|
136
|
+
recovering = true;
|
|
137
|
+
|
|
106
138
|
// reload() and not assign(): the URL is already the destination - React
|
|
107
139
|
// Router changes it before rendering the route whose chunk just failed -
|
|
108
140
|
// so this fetches a fresh index.html and lands on the page that was asked
|
package/package.json
CHANGED
package/types/users.ts
CHANGED
|
@@ -19,6 +19,12 @@ export interface UserData {
|
|
|
19
19
|
// operator/employee accounts - whether the company's Shipments module is
|
|
20
20
|
// on, so menus can hide the link instead of advertising a 403.
|
|
21
21
|
shipping_enabled?: boolean | null
|
|
22
|
+
// Claude - 2026-08-31: whether this admin belongs to the MAIN label. Same
|
|
23
|
+
// job as shipping_enabled above - the platform-wide screens (database
|
|
24
|
+
// backups) answer a 404 to a whitelabel admin, and a menu should hide the
|
|
25
|
+
// link rather than advertise a door that does not open. Null for every
|
|
26
|
+
// non-admin type.
|
|
27
|
+
is_main_label?: boolean | null
|
|
22
28
|
comissions: ComissionData
|
|
23
29
|
subscription: SubscribedData
|
|
24
30
|
api: ApiData
|