@burdenoff/microfe-movethewheels 2026.1011.2 → 2026.1011.4
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
|
|
2
2
|
import { useCallback as t, useEffect as n, useMemo as r, useRef as i, useState as a } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { clearGraphqlFetchResponseCache as o, graphqlFetch as s } from "@burdenoff/fe-libs/shared/graphql";
|
|
4
|
+
import { print as c } from "graphql";
|
|
5
5
|
//#region src/movethewheels/hooks/useShipmentStatusAuthority.ts
|
|
6
6
|
var l = new Set([
|
|
7
7
|
"STATUS_REVISION_CONFLICT",
|
|
@@ -16,23 +16,23 @@ var l = new Set([
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
function d() {
|
|
19
|
-
let { apiGatewayUrl: n, authToken: i, workspaceToken: a, workspaceId:
|
|
19
|
+
let { apiGatewayUrl: n, authToken: i, workspaceToken: a, workspaceId: o, tenantId: l } = e(), d = r(() => ({
|
|
20
20
|
apiGatewayUrl: n,
|
|
21
21
|
authToken: i,
|
|
22
22
|
workspaceToken: a,
|
|
23
|
-
workspaceId:
|
|
23
|
+
workspaceId: o,
|
|
24
24
|
tenantId: l
|
|
25
25
|
}), [
|
|
26
26
|
n,
|
|
27
27
|
i,
|
|
28
28
|
a,
|
|
29
|
-
|
|
29
|
+
o,
|
|
30
30
|
l
|
|
31
31
|
]);
|
|
32
32
|
return t(async (e, t, n = !1, r) => {
|
|
33
|
-
let i = await
|
|
33
|
+
let i = await s({
|
|
34
34
|
gateway: "workspace",
|
|
35
|
-
query:
|
|
35
|
+
query: c(e),
|
|
36
36
|
variables: t,
|
|
37
37
|
baseUrl: d.apiGatewayUrl,
|
|
38
38
|
authToken: d.authToken,
|
|
@@ -52,19 +52,19 @@ function d() {
|
|
|
52
52
|
}, [d]);
|
|
53
53
|
}
|
|
54
54
|
function f(e, t, r = 0) {
|
|
55
|
-
let i = d(),
|
|
55
|
+
let i = d(), s = JSON.stringify(t), [c, l] = a(null);
|
|
56
56
|
n(() => {
|
|
57
57
|
let t = new AbortController(), n = {
|
|
58
58
|
request: i,
|
|
59
|
-
key:
|
|
59
|
+
key: s,
|
|
60
60
|
revision: r
|
|
61
61
|
};
|
|
62
62
|
if (l({
|
|
63
63
|
...n,
|
|
64
64
|
data: null,
|
|
65
65
|
error: null,
|
|
66
|
-
loading:
|
|
67
|
-
}),
|
|
66
|
+
loading: s !== "null"
|
|
67
|
+
}), s !== "null") return r > 0 && o(), i(e, JSON.parse(s), !1, t.signal).then((e) => {
|
|
68
68
|
t.signal.aborted || l({
|
|
69
69
|
...n,
|
|
70
70
|
data: e,
|
|
@@ -82,14 +82,14 @@ function f(e, t, r = 0) {
|
|
|
82
82
|
}, [
|
|
83
83
|
e,
|
|
84
84
|
i,
|
|
85
|
-
|
|
85
|
+
s,
|
|
86
86
|
r
|
|
87
87
|
]);
|
|
88
|
-
let u = c?.request === i && c.key ===
|
|
88
|
+
let u = c?.request === i && c.key === s && c.revision === r;
|
|
89
89
|
return {
|
|
90
90
|
data: u ? c.data : null,
|
|
91
91
|
error: u ? c.error : null,
|
|
92
|
-
loading: u ? c.loading :
|
|
92
|
+
loading: u ? c.loading : s !== "null"
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
function p() {
|
|
@@ -1,48 +1,58 @@
|
|
|
1
|
+
import { prepareWorkspaceRequest as e } from "@burdenoff/fe-libs/shared/graphql";
|
|
1
2
|
//#region src/movethewheels/utils/graphqlClient.ts
|
|
2
|
-
function
|
|
3
|
+
function t(e) {
|
|
3
4
|
return e ? e.endsWith("/graphql") ? e : `${e}/workspaces/graphql` : "/workspaces/graphql";
|
|
4
5
|
}
|
|
5
|
-
var
|
|
6
|
-
function
|
|
6
|
+
var n = 3, r = 12e3;
|
|
7
|
+
function i(e) {
|
|
7
8
|
return e ? /upstream connect|connection refused|reset before headers|delayed connect|econnrefused|econnreset|socket hang up|service unavailable|bad gateway|gateway timeout|temporarily unavailable|please try again|failed to fetch|networkerror|load failed/i.test(e) : !1;
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
+
function a(e) {
|
|
10
11
|
return e === 429 || e === 502 || e === 503 || e === 504;
|
|
11
12
|
}
|
|
12
|
-
function
|
|
13
|
+
function o(e) {
|
|
13
14
|
return typeof e == "object" && !!e && "name" in e && e.name === "AbortError";
|
|
14
15
|
}
|
|
15
|
-
var
|
|
16
|
-
function
|
|
16
|
+
var s = (e) => new Promise((t) => setTimeout(t, e)), c = 4, l = 0, u = [];
|
|
17
|
+
function d() {
|
|
17
18
|
return new Promise((e) => {
|
|
18
|
-
|
|
19
|
+
l < c ? (l += 1, e()) : u.push(e);
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
|
-
function
|
|
22
|
-
let e =
|
|
23
|
-
e ? e() : --
|
|
22
|
+
function f() {
|
|
23
|
+
let e = u.shift();
|
|
24
|
+
e ? e() : --l;
|
|
24
25
|
}
|
|
25
|
-
async function
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
...n.tenantId ? { "x-tenant-id": n.tenantId } : {},
|
|
32
|
-
...n.actorId ? { "x-actor-id": n.actorId } : {},
|
|
33
|
-
...n.actorId ? { "x-actor-type": "user" } : {}
|
|
34
|
-
}, c = JSON.stringify({
|
|
35
|
-
query: r,
|
|
36
|
-
variables: i
|
|
37
|
-
});
|
|
38
|
-
await u();
|
|
26
|
+
async function p(r, i, a, o = "RETRY_TRANSIENT") {
|
|
27
|
+
let s = { ...r }, c = JSON.stringify({
|
|
28
|
+
query: i,
|
|
29
|
+
variables: a
|
|
30
|
+
}), l = t(s.apiGatewayUrl);
|
|
31
|
+
await d();
|
|
39
32
|
try {
|
|
40
|
-
|
|
33
|
+
let t = typeof window < "u" ? await e({
|
|
34
|
+
url: new URL(l, typeof document < "u" && document.baseURI || window.location.href).toString(),
|
|
35
|
+
authToken: s.authToken ?? "",
|
|
36
|
+
actorId: s.actorId ?? "",
|
|
37
|
+
workspaceId: s.workspaceId ?? "",
|
|
38
|
+
tenantId: s.tenantId,
|
|
39
|
+
workspaceToken: s.workspaceToken,
|
|
40
|
+
currentQuery: i
|
|
41
|
+
}) : null, r = t?.workspaceToken ?? s.workspaceToken;
|
|
42
|
+
return await h(l, {
|
|
43
|
+
"content-type": "application/json",
|
|
44
|
+
...s.authToken ? { Authorization: `Bearer ${s.authToken}` } : {},
|
|
45
|
+
...r ? { "X-Workspace-Authorization": `Bearer ${r}` } : {},
|
|
46
|
+
...s.workspaceId ? { "x-workspace-id": s.workspaceId } : {},
|
|
47
|
+
...s.tenantId ? { "x-tenant-id": s.tenantId } : {},
|
|
48
|
+
...s.actorId ? { "x-actor-id": s.actorId } : {},
|
|
49
|
+
...s.actorId ? { "x-actor-type": "user" } : {}
|
|
50
|
+
}, c, o === "SINGLE_ATTEMPT" ? 0 : n, t?.assertCurrent ?? (() => {}));
|
|
41
51
|
} finally {
|
|
42
|
-
|
|
52
|
+
f();
|
|
43
53
|
}
|
|
44
54
|
}
|
|
45
|
-
async function
|
|
55
|
+
async function m(e) {
|
|
46
56
|
try {
|
|
47
57
|
let t = ((await e.json()).errors ?? []).map((e) => e.message).filter((e) => typeof e == "string" && e.length > 0);
|
|
48
58
|
return t.length > 0 ? t.join("; ") : null;
|
|
@@ -50,44 +60,44 @@ async function p(e) {
|
|
|
50
60
|
return null;
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
|
-
async function
|
|
54
|
-
let
|
|
55
|
-
for (let
|
|
56
|
-
let
|
|
57
|
-
|
|
58
|
-
let
|
|
63
|
+
async function h(e, t, n, c, l) {
|
|
64
|
+
let u = /* @__PURE__ */ Error("GraphQL request failed");
|
|
65
|
+
for (let d = 0; d <= c; d += 1) {
|
|
66
|
+
let f = d < c;
|
|
67
|
+
d > 0 && await s(Math.min(250 * 2 ** (d - 1), 2e3) + Math.floor(Math.random() * 150)), l();
|
|
68
|
+
let p = new AbortController(), h = setTimeout(() => p.abort(), r);
|
|
59
69
|
try {
|
|
60
|
-
let
|
|
70
|
+
let r = await fetch(e, {
|
|
61
71
|
method: "POST",
|
|
62
72
|
headers: t,
|
|
63
|
-
body:
|
|
64
|
-
signal:
|
|
73
|
+
body: n,
|
|
74
|
+
signal: p.signal
|
|
65
75
|
});
|
|
66
|
-
if (!
|
|
67
|
-
let e =
|
|
68
|
-
if (
|
|
69
|
-
throw
|
|
76
|
+
if (!r.ok) {
|
|
77
|
+
let e = a(r.status) ? null : await m(r);
|
|
78
|
+
if (u = Error(e ?? `GraphQL request failed with status ${r.status}`), f && a(r.status)) continue;
|
|
79
|
+
throw u;
|
|
70
80
|
}
|
|
71
|
-
let
|
|
72
|
-
if (
|
|
73
|
-
let e =
|
|
74
|
-
if (
|
|
75
|
-
throw
|
|
81
|
+
let o = await r.json();
|
|
82
|
+
if (o.errors?.length) {
|
|
83
|
+
let e = o.errors.map((e) => e.message ?? "Unknown GraphQL error").join("; ");
|
|
84
|
+
if (u = Error(e), f && o.errors.some((e) => i(e.message))) continue;
|
|
85
|
+
throw u;
|
|
76
86
|
}
|
|
77
|
-
if (!
|
|
78
|
-
if (
|
|
79
|
-
throw
|
|
87
|
+
if (!o.data) {
|
|
88
|
+
if (u = /* @__PURE__ */ Error("GraphQL response did not include data"), f) continue;
|
|
89
|
+
throw u;
|
|
80
90
|
}
|
|
81
|
-
return
|
|
91
|
+
return o.data;
|
|
82
92
|
} catch (e) {
|
|
83
|
-
let t =
|
|
84
|
-
if (
|
|
85
|
-
throw
|
|
93
|
+
let t = o(e), n = t ? `GraphQL request timed out after ${r}ms` : e instanceof Error ? e.message : String(e);
|
|
94
|
+
if (u = !t && e instanceof Error ? e : Error(n), f && (t || i(n) || e instanceof TypeError)) continue;
|
|
95
|
+
throw u;
|
|
86
96
|
} finally {
|
|
87
|
-
clearTimeout(
|
|
97
|
+
clearTimeout(h);
|
|
88
98
|
}
|
|
89
99
|
}
|
|
90
|
-
throw
|
|
100
|
+
throw u;
|
|
91
101
|
}
|
|
92
102
|
//#endregion
|
|
93
|
-
export {
|
|
103
|
+
export { p as executeGraphQL, t as resolveGraphqlUrl };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-movethewheels",
|
|
3
|
-
"version": "2026.1011.
|
|
3
|
+
"version": "2026.1011.4",
|
|
4
4
|
"description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"main": "./dist/index.js",
|
|
27
27
|
"types": "./dist/index.d.ts",
|
|
28
28
|
"scripts": {
|
|
29
|
+
"verify:workspace-predispatch": "bun test scripts/verify-workspace-predispatch.test.ts",
|
|
29
30
|
"verify:multimodal-single-attempt": "bun scripts/verify-multimodal-single-attempt.mjs",
|
|
30
31
|
"verify:live-logistics-contract": "bun test scripts/check-logistics-live-contract.test.mjs scripts/fetch-logistics-live-schema.test.mjs",
|
|
31
32
|
"dev": "vite --port 5191",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
36
37
|
"type:check": "bash scripts/build-limits.sh tsc --noEmit",
|
|
37
38
|
"validate:schema-drift": "graphql-schema-drift",
|
|
38
|
-
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:braces-depth && bun run build && bun run build-storybook'",
|
|
39
|
+
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:workspace-predispatch && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:braces-depth && bun run build && bun run build-storybook'",
|
|
39
40
|
"storybook": "storybook dev -p 6006",
|
|
40
41
|
"build-storybook": "storybook build",
|
|
41
42
|
"test:storybook": "test-storybook",
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
},
|
|
68
69
|
"dependencies": {
|
|
69
70
|
"@apollo/client": "^4.0.11",
|
|
70
|
-
"@burdenoff/fe-libs": "2026.
|
|
71
|
+
"@burdenoff/fe-libs": "2026.1011.2",
|
|
71
72
|
"@react-leaflet/core": "^3.0.0",
|
|
72
73
|
"@tanstack/react-query": "^5.90.16",
|
|
73
74
|
"clsx": "^2.1.1",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { prepareWorkspaceRequest } from '@burdenoff/fe-libs/shared/graphql';
|
|
2
|
+
|
|
1
3
|
export type GraphQLAttemptPolicy = 'RETRY_TRANSIENT' | 'SINGLE_ATTEMPT';
|
|
2
4
|
|
|
3
5
|
interface GraphQLRequestOptions {
|
|
@@ -111,29 +113,46 @@ export async function executeGraphQL<TData>(
|
|
|
111
113
|
variables?: Record<string, unknown>,
|
|
112
114
|
attemptPolicy: GraphQLAttemptPolicy = 'RETRY_TRANSIENT'
|
|
113
115
|
): Promise<TData> {
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
'content-type': 'application/json',
|
|
117
|
-
...(options.authToken ? { Authorization: `Bearer ${options.authToken}` } : {}),
|
|
118
|
-
...(options.workspaceToken
|
|
119
|
-
? { 'X-Workspace-Authorization': `Bearer ${options.workspaceToken}` }
|
|
120
|
-
: {}),
|
|
121
|
-
...(options.workspaceId ? { 'x-workspace-id': options.workspaceId } : {}),
|
|
122
|
-
...(options.tenantId ? { 'x-tenant-id': options.tenantId } : {}),
|
|
123
|
-
...(options.actorId ? { 'x-actor-id': options.actorId } : {}),
|
|
124
|
-
...(options.actorId ? { 'x-actor-type': 'user' } : {}),
|
|
125
|
-
};
|
|
116
|
+
// Capture the original intent before queueing or asynchronously renewing authority.
|
|
117
|
+
const request = { ...options };
|
|
126
118
|
const body = JSON.stringify({ query, variables });
|
|
127
|
-
|
|
128
|
-
// Serialize past the global concurrency cap before doing any network work,
|
|
129
|
-
// and always release the slot when this call settles (success or failure).
|
|
119
|
+
const url = resolveGraphqlUrl(request.apiGatewayUrl);
|
|
130
120
|
await acquireSlot();
|
|
131
121
|
try {
|
|
122
|
+
// Server-side callers retain explicit-token behavior; active browser requests
|
|
123
|
+
// use the shared owning profile/context lifecycle before product dispatch.
|
|
124
|
+
const authority =
|
|
125
|
+
typeof window !== 'undefined'
|
|
126
|
+
? await prepareWorkspaceRequest({
|
|
127
|
+
// Match fetch's document-relative URL resolution without changing its input.
|
|
128
|
+
url: new URL(
|
|
129
|
+
url,
|
|
130
|
+
(typeof document !== 'undefined' && document.baseURI) || window.location.href
|
|
131
|
+
).toString(),
|
|
132
|
+
authToken: request.authToken ?? '',
|
|
133
|
+
actorId: request.actorId ?? '',
|
|
134
|
+
workspaceId: request.workspaceId ?? '',
|
|
135
|
+
tenantId: request.tenantId,
|
|
136
|
+
workspaceToken: request.workspaceToken,
|
|
137
|
+
currentQuery: query,
|
|
138
|
+
})
|
|
139
|
+
: null;
|
|
140
|
+
const workspaceToken = authority?.workspaceToken ?? request.workspaceToken;
|
|
141
|
+
const headers: Record<string, string> = {
|
|
142
|
+
'content-type': 'application/json',
|
|
143
|
+
...(request.authToken ? { Authorization: `Bearer ${request.authToken}` } : {}),
|
|
144
|
+
...(workspaceToken ? { 'X-Workspace-Authorization': `Bearer ${workspaceToken}` } : {}),
|
|
145
|
+
...(request.workspaceId ? { 'x-workspace-id': request.workspaceId } : {}),
|
|
146
|
+
...(request.tenantId ? { 'x-tenant-id': request.tenantId } : {}),
|
|
147
|
+
...(request.actorId ? { 'x-actor-id': request.actorId } : {}),
|
|
148
|
+
...(request.actorId ? { 'x-actor-type': 'user' } : {}),
|
|
149
|
+
};
|
|
132
150
|
return await runWithRetries<TData>(
|
|
133
151
|
url,
|
|
134
152
|
headers,
|
|
135
153
|
body,
|
|
136
|
-
attemptPolicy === 'SINGLE_ATTEMPT' ? 0 : MAX_RETRIES
|
|
154
|
+
attemptPolicy === 'SINGLE_ATTEMPT' ? 0 : MAX_RETRIES,
|
|
155
|
+
authority?.assertCurrent ?? (() => {})
|
|
137
156
|
);
|
|
138
157
|
} finally {
|
|
139
158
|
releaseSlot();
|
|
@@ -157,7 +176,8 @@ async function runWithRetries<TData>(
|
|
|
157
176
|
url: string,
|
|
158
177
|
headers: Record<string, string>,
|
|
159
178
|
body: string,
|
|
160
|
-
retries: number
|
|
179
|
+
retries: number,
|
|
180
|
+
assertCurrent: () => void
|
|
161
181
|
): Promise<TData> {
|
|
162
182
|
let lastError: Error = new Error('GraphQL request failed');
|
|
163
183
|
|
|
@@ -167,6 +187,7 @@ async function runWithRetries<TData>(
|
|
|
167
187
|
if (attempt > 0)
|
|
168
188
|
await sleep(Math.min(250 * 2 ** (attempt - 1), 2000) + Math.floor(Math.random() * 150));
|
|
169
189
|
|
|
190
|
+
assertCurrent();
|
|
170
191
|
const controller = new AbortController();
|
|
171
192
|
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
172
193
|
try {
|