@agent-native/toolkit 0.207.0 → 0.207.1-nightly-20261011212936
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/app/onboarding/first-run-startup-gate.d.ts.map +1 -1
- package/dist/app/onboarding/first-run-startup-gate.js +21 -8
- package/dist/app/onboarding/first-run-startup-gate.js.map +1 -1
- package/package.json +4 -4
- package/src/app/onboarding/first-run-startup-gate.spec.tsx +47 -5
- package/src/app/onboarding/first-run-startup-gate.tsx +23 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"first-run-startup-gate.d.ts","sourceRoot":"","sources":["../../../src/app/onboarding/first-run-startup-gate.tsx"],"names":[],"mappings":"AAMA,OAAO,KAON,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"first-run-startup-gate.d.ts","sourceRoot":"","sources":["../../../src/app/onboarding/first-run-startup-gate.tsx"],"names":[],"mappings":"AAMA,OAAO,KAON,MAAM,OAAO,CAAC;AAmCf,wBAAgB,oCAAoC,IAAI,OAAO,CAE9D;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EACR,QAA+B,EAC/B,eAAuB,GACxB,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,qBAsGA"}
|
|
@@ -10,6 +10,8 @@ import { AppShellSkeleton } from "../shared/AppShellSkeleton.js";
|
|
|
10
10
|
const FirstRunOnboarding = lazy(() => import("./FirstRunOnboarding.js").then((module) => ({
|
|
11
11
|
default: module.FirstRunOnboarding,
|
|
12
12
|
})));
|
|
13
|
+
const FIRST_RUN_STATUS_MAX_ATTEMPTS = 2;
|
|
14
|
+
const FIRST_RUN_STATUS_RETRY_DELAY_MS = 500;
|
|
13
15
|
const FirstRunOnboardingGateContext = createContext(false);
|
|
14
16
|
function readFirstRunOnboardingCookieState() {
|
|
15
17
|
if (typeof document === "undefined")
|
|
@@ -55,6 +57,7 @@ export function FirstRunOnboardingStartupGate({ children, fallback = _jsx(AppShe
|
|
|
55
57
|
if (preloading)
|
|
56
58
|
return;
|
|
57
59
|
let cancelled = false;
|
|
60
|
+
let retryTimeout;
|
|
58
61
|
const handleFirstRunCompleted = () => {
|
|
59
62
|
trackOnboardingEvent("onboarding_app_entered", { flow: "first_run" });
|
|
60
63
|
cancelled = true;
|
|
@@ -62,17 +65,27 @@ export function FirstRunOnboardingStartupGate({ children, fallback = _jsx(AppShe
|
|
|
62
65
|
};
|
|
63
66
|
window.addEventListener("agent-native:first-run-completed", handleFirstRunCompleted);
|
|
64
67
|
setDecision("pending");
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
const resolveStatus = (attempt) => {
|
|
69
|
+
void fetchFirstRunOnboardingStatus()
|
|
70
|
+
.then((firstRun) => {
|
|
71
|
+
if (!cancelled)
|
|
72
|
+
setDecision(firstRun ? "eligible" : "ineligible");
|
|
73
|
+
})
|
|
74
|
+
.catch(() => {
|
|
75
|
+
if (cancelled)
|
|
76
|
+
return;
|
|
77
|
+
if (attempt < FIRST_RUN_STATUS_MAX_ATTEMPTS) {
|
|
78
|
+
retryTimeout = window.setTimeout(() => resolveStatus(attempt + 1), FIRST_RUN_STATUS_RETRY_DELAY_MS);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
72
81
|
setDecision("ineligible");
|
|
73
|
-
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
resolveStatus(1);
|
|
74
85
|
return () => {
|
|
75
86
|
cancelled = true;
|
|
87
|
+
if (retryTimeout !== undefined)
|
|
88
|
+
window.clearTimeout(retryTimeout);
|
|
76
89
|
window.removeEventListener("agent-native:first-run-completed", handleFirstRunCompleted);
|
|
77
90
|
};
|
|
78
91
|
}, [shouldResolve, preloading]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"first-run-startup-gate.js","sourceRoot":"","sources":["../../../src/app/onboarding/first-run-startup-gate.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"first-run-startup-gate.js","sourceRoot":"","sources":["../../../src/app/onboarding/first-run-startup-gate.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/toolkit",
|
|
3
|
-
"version": "0.207.
|
|
3
|
+
"version": "0.207.1-nightly-20261011212936",
|
|
4
4
|
"description": "Reusable app-building UI and helpers for Agent-Native apps.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -678,7 +678,7 @@
|
|
|
678
678
|
"y-protocols": "^1.0.7",
|
|
679
679
|
"yjs": "^13.6.33",
|
|
680
680
|
"zod": "^4.3.6",
|
|
681
|
-
"@agent-native/agentkit": "^0.207.
|
|
681
|
+
"@agent-native/agentkit": "^0.207.1-nightly-20261011212936"
|
|
682
682
|
},
|
|
683
683
|
"devDependencies": {
|
|
684
684
|
"@excalidraw/excalidraw": "0.18.1",
|
|
@@ -702,10 +702,10 @@
|
|
|
702
702
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
703
703
|
"vite": "8.1.0",
|
|
704
704
|
"vitest": "^4.1.5",
|
|
705
|
-
"@agent-native/core": "^0.207.
|
|
705
|
+
"@agent-native/core": "^0.207.1-nightly-20261011212936"
|
|
706
706
|
},
|
|
707
707
|
"peerDependencies": {
|
|
708
|
-
"@agent-native/core": "
|
|
708
|
+
"@agent-native/core": "0.207.1-nightly-20261011212936",
|
|
709
709
|
"@excalidraw/excalidraw": ">=0.18",
|
|
710
710
|
"@excalidraw/mermaid-to-excalidraw": ">=2",
|
|
711
711
|
"@tanstack/react-query": "^5.99.2",
|
|
@@ -87,6 +87,7 @@ describe("FirstRunOnboardingStartupGate", () => {
|
|
|
87
87
|
|
|
88
88
|
afterEach(() => {
|
|
89
89
|
act(() => root.unmount());
|
|
90
|
+
vi.useRealTimers();
|
|
90
91
|
container.remove();
|
|
91
92
|
vi.unstubAllGlobals();
|
|
92
93
|
document.cookie = `${FIRST_RUN_ONBOARDING_COOKIE}=; Max-Age=0; path=/`;
|
|
@@ -195,6 +196,45 @@ describe("FirstRunOnboardingStartupGate", () => {
|
|
|
195
196
|
).toBe("true");
|
|
196
197
|
});
|
|
197
198
|
|
|
199
|
+
it("retries a failed status read before revealing a first-run app", async () => {
|
|
200
|
+
vi.useFakeTimers();
|
|
201
|
+
const status = deferred<boolean>();
|
|
202
|
+
mocks.fetchStatus
|
|
203
|
+
.mockRejectedValueOnce(new Error("status timed out"))
|
|
204
|
+
.mockReturnValueOnce(status.promise);
|
|
205
|
+
|
|
206
|
+
act(() => {
|
|
207
|
+
root.render(
|
|
208
|
+
<FirstRunOnboardingStartupGate>
|
|
209
|
+
<div data-testid="app-content">app</div>
|
|
210
|
+
</FirstRunOnboardingStartupGate>,
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
await act(async () => {
|
|
214
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
expect(mocks.fetchStatus).toHaveBeenCalledTimes(2);
|
|
218
|
+
expect(
|
|
219
|
+
container.querySelector("[data-first-run-startup-loading]"),
|
|
220
|
+
).not.toBeNull();
|
|
221
|
+
expect(
|
|
222
|
+
container.querySelector("[data-testid='app-content']"),
|
|
223
|
+
).not.toBeNull();
|
|
224
|
+
expect(
|
|
225
|
+
container.querySelector("[data-first-run-app-hidden]"),
|
|
226
|
+
).not.toBeNull();
|
|
227
|
+
|
|
228
|
+
await act(async () => {
|
|
229
|
+
status.resolve(true);
|
|
230
|
+
await status.promise;
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
expect(
|
|
234
|
+
container.querySelector("[data-testid='first-run-onboarding']"),
|
|
235
|
+
).not.toBeNull();
|
|
236
|
+
});
|
|
237
|
+
|
|
198
238
|
it("reveals an existing-organization member without mounting onboarding", async () => {
|
|
199
239
|
const status = deferred<boolean>();
|
|
200
240
|
mocks.fetchStatus.mockReturnValue(status.promise);
|
|
@@ -463,9 +503,11 @@ describe("FirstRunOnboardingStartupGate", () => {
|
|
|
463
503
|
).toBeNull();
|
|
464
504
|
});
|
|
465
505
|
|
|
466
|
-
it("
|
|
467
|
-
|
|
468
|
-
mocks.fetchStatus
|
|
506
|
+
it("reveals the app if both eligibility checks are unavailable", async () => {
|
|
507
|
+
vi.useFakeTimers();
|
|
508
|
+
mocks.fetchStatus
|
|
509
|
+
.mockRejectedValueOnce(new Error("first status read failed"))
|
|
510
|
+
.mockRejectedValueOnce(new Error("retry failed"));
|
|
469
511
|
|
|
470
512
|
act(() => {
|
|
471
513
|
root.render(
|
|
@@ -476,10 +518,10 @@ describe("FirstRunOnboardingStartupGate", () => {
|
|
|
476
518
|
});
|
|
477
519
|
|
|
478
520
|
await act(async () => {
|
|
479
|
-
|
|
480
|
-
await status.promise.catch(() => undefined);
|
|
521
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
481
522
|
});
|
|
482
523
|
|
|
524
|
+
expect(mocks.fetchStatus).toHaveBeenCalledTimes(2);
|
|
483
525
|
expect(
|
|
484
526
|
container.querySelector("[data-testid='app-content']"),
|
|
485
527
|
).not.toBeNull();
|
|
@@ -24,6 +24,9 @@ const FirstRunOnboarding = lazy(() =>
|
|
|
24
24
|
type FirstRunDecision = "pending" | "eligible" | "ineligible";
|
|
25
25
|
type FirstRunCookieState = "present" | "absent" | "unreadable";
|
|
26
26
|
|
|
27
|
+
const FIRST_RUN_STATUS_MAX_ATTEMPTS = 2;
|
|
28
|
+
const FIRST_RUN_STATUS_RETRY_DELAY_MS = 500;
|
|
29
|
+
|
|
27
30
|
const FirstRunOnboardingGateContext = createContext(false);
|
|
28
31
|
|
|
29
32
|
function readFirstRunOnboardingCookieState(): FirstRunCookieState {
|
|
@@ -84,6 +87,7 @@ export function FirstRunOnboardingStartupGate({
|
|
|
84
87
|
if (preloading) return;
|
|
85
88
|
|
|
86
89
|
let cancelled = false;
|
|
90
|
+
let retryTimeout: number | undefined;
|
|
87
91
|
const handleFirstRunCompleted = () => {
|
|
88
92
|
trackOnboardingEvent("onboarding_app_entered", { flow: "first_run" });
|
|
89
93
|
cancelled = true;
|
|
@@ -94,16 +98,28 @@ export function FirstRunOnboardingStartupGate({
|
|
|
94
98
|
handleFirstRunCompleted,
|
|
95
99
|
);
|
|
96
100
|
setDecision("pending");
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
const resolveStatus = (attempt: number) => {
|
|
102
|
+
void fetchFirstRunOnboardingStatus()
|
|
103
|
+
.then((firstRun) => {
|
|
104
|
+
if (!cancelled) setDecision(firstRun ? "eligible" : "ineligible");
|
|
105
|
+
})
|
|
106
|
+
.catch(() => {
|
|
107
|
+
if (cancelled) return;
|
|
108
|
+
if (attempt < FIRST_RUN_STATUS_MAX_ATTEMPTS) {
|
|
109
|
+
retryTimeout = window.setTimeout(
|
|
110
|
+
() => resolveStatus(attempt + 1),
|
|
111
|
+
FIRST_RUN_STATUS_RETRY_DELAY_MS,
|
|
112
|
+
);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
setDecision("ineligible");
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
resolveStatus(1);
|
|
104
119
|
|
|
105
120
|
return () => {
|
|
106
121
|
cancelled = true;
|
|
122
|
+
if (retryTimeout !== undefined) window.clearTimeout(retryTimeout);
|
|
107
123
|
window.removeEventListener(
|
|
108
124
|
"agent-native:first-run-completed",
|
|
109
125
|
handleFirstRunCompleted,
|