Skip to content

Commit 4af3650

Browse files
authored
🤖 Merge PR DefinitelyTyped#74615 [hotwired__turbo] Introduce Adapter interface by @myabc
1 parent 8a4c291 commit 4af3650

File tree

2 files changed

+104
-12
lines changed

2 files changed

+104
-12
lines changed

‎types/hotwired__turbo/hotwired__turbo-tests.ts‎

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import {
2+
Adapter,
3+
BrowserAdapter,
24
cache,
35
config,
46
connectStreamSource,
57
disconnectStreamSource,
68
navigator,
9+
NavigatorDelegate,
10+
ProgressBar,
11+
registerAdapter,
712
renderStreamMessage,
813
session,
914
start,
1015
StreamActions,
1116
StreamMessage,
1217
StreamSource,
18+
Visit,
1319
visit,
20+
VisitOptions,
1421
} from "@hotwired/turbo";
1522

1623
const turboFrame = document.querySelector("turbo-frame")!;
@@ -145,15 +152,29 @@ document.addEventListener("turbo:submit-end", function(event) {
145152

146153
// Test start() function
147154
start();
155+
156+
const customAdapter: Adapter = {
157+
visitProposedToLocation(_location: URL, _options?: VisitOptions): void {},
158+
visitStarted(_visit: Visit): void {},
159+
visitCompleted(_visit: Visit): void {},
160+
visitFailed(_visit: Visit): void {},
161+
visitRequestStarted(_visit: Visit): void {},
162+
visitRequestCompleted(_visit: Visit): void {},
163+
visitRequestFailedWithStatusCode(_visit: Visit, _statusCode: number): void {},
164+
visitRequestFinished(_visit: Visit): void {},
165+
visitRendered(_visit: Visit): void {},
166+
pageInvalidated(_reason: { reason: string }): void {},
167+
};
168+
registerAdapter(customAdapter);
169+
Turbo.registerAdapter(customAdapter);
170+
148171
Turbo.start();
149172

150173
// Test session.adapter
151-
// $ExpectType BrowserAdapter
174+
// $ExpectType Adapter
152175
session.adapter;
153-
session.adapter.formSubmissionStarted();
154-
session.adapter.formSubmissionFinished();
155-
Turbo.session.adapter.formSubmissionStarted();
156-
Turbo.session.adapter.formSubmissionFinished();
176+
// $ExpectType Adapter
177+
Turbo.session.adapter;
157178

158179
// Test navigator.submitForm
159180
const form = document.querySelector("form")!;
@@ -162,6 +183,26 @@ navigator.submitForm(form, document.querySelector("button")!);
162183
Turbo.navigator.submitForm(form);
163184
Turbo.navigator.submitForm(form, document.querySelector("button")!);
164185

186+
// Test navigator.delegate
187+
// $ExpectType NavigatorDelegate
188+
navigator.delegate;
189+
// $ExpectType Adapter
190+
navigator.delegate.adapter;
191+
192+
// Test ProgressBar via BrowserAdapter cast
193+
const browserAdapter = navigator.delegate.adapter as BrowserAdapter;
194+
// $ExpectType ProgressBar
195+
browserAdapter.progressBar;
196+
browserAdapter.progressBar.setValue(0);
197+
browserAdapter.progressBar.show();
198+
browserAdapter.progressBar.hide();
199+
// $ExpectType number
200+
browserAdapter.progressBar.value;
201+
// $ExpectType boolean
202+
browserAdapter.progressBar.visible;
203+
// $ExpectType boolean
204+
browserAdapter.progressBar.hiding;
205+
165206
// Test cache methods
166207
cache.clear();
167208
cache.resetCacheControl();

‎types/hotwired__turbo/index.d.ts‎

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,71 @@ export class FetchResponse {
109109
succeeded: boolean;
110110
}
111111

112+
export interface Visit {
113+
readonly action: Action;
114+
readonly location: URL;
115+
hasCachedSnapshot(): boolean;
116+
complete(): void;
117+
cancel(): void;
118+
}
119+
120+
export interface Adapter {
121+
visitProposedToLocation(location: URL, options?: VisitOptions): void;
122+
visitStarted(visit: Visit): void;
123+
visitCompleted(visit: Visit): void;
124+
visitFailed(visit: Visit): void;
125+
visitRequestStarted(visit: Visit): void;
126+
visitRequestCompleted(visit: Visit): void;
127+
visitRequestFailedWithStatusCode(visit: Visit, statusCode: number): void;
128+
visitRequestFinished(visit: Visit): void;
129+
visitRendered(visit: Visit): void;
130+
pageInvalidated(reason: { reason: string }): void;
131+
formSubmissionStarted?(formSubmission: FormSubmission): void;
132+
formSubmissionFinished?(formSubmission: FormSubmission): void;
133+
linkPrefetchingIsEnabledForLocation?(location: URL): boolean;
134+
}
135+
136+
export class BrowserAdapter implements Adapter {
137+
progressBar: ProgressBar;
138+
visitProposedToLocation(location: URL, options?: VisitOptions): void;
139+
visitStarted(visit: Visit): void;
140+
visitCompleted(visit: Visit): void;
141+
visitFailed(visit: Visit): void;
142+
visitRequestStarted(visit: Visit): void;
143+
visitRequestCompleted(visit: Visit): void;
144+
visitRequestFailedWithStatusCode(visit: Visit, statusCode: number): void;
145+
visitRequestFinished(visit: Visit): void;
146+
visitRendered(visit: Visit): void;
147+
pageInvalidated(reason: { reason: string }): void;
148+
formSubmissionStarted(formSubmission: FormSubmission): void;
149+
formSubmissionFinished(formSubmission: FormSubmission): void;
150+
linkPrefetchingIsEnabledForLocation(location: URL): boolean;
151+
}
152+
153+
export interface ProgressBar {
154+
hiding: boolean;
155+
value: number;
156+
visible: boolean;
157+
show(): void;
158+
hide(): void;
159+
setValue(value: number): void;
160+
}
161+
112162
/**
113-
* Interface for accessing the browser adapter.
114-
* The adapter handles form submission lifecycle events.
163+
* The delegate for the Turbo navigator — in practice, the active session.
164+
* Provides access to the current adapter.
115165
*/
116-
export interface BrowserAdapter {
117-
formSubmissionStarted(formSubmission?: FormSubmission): void;
118-
formSubmissionFinished(formSubmission?: FormSubmission): void;
166+
export interface NavigatorDelegate {
167+
adapter: Adapter;
119168
}
120169

121170
/**
122171
* Interface for the Turbo navigator.
123172
* Provides methods for programmatic navigation and form submission.
124173
*/
125174
export interface Navigator {
175+
/** The delegate for this navigator (the active Turbo session). */
176+
delegate: NavigatorDelegate;
126177
/**
127178
* Submits a form programmatically through Turbo Drive.
128179
*
@@ -231,7 +282,7 @@ export interface TurboSession {
231282
disconnectStreamSource(source: StreamSource): void;
232283
renderStreamMessage(message: StreamMessage | string): void;
233284
drive: boolean;
234-
adapter: BrowserAdapter;
285+
adapter: Adapter;
235286
}
236287

237288
export const StreamActions: {
@@ -256,7 +307,7 @@ export function start(): void;
256307
*
257308
* @param adapter Adapter to register
258309
*/
259-
export function registerAdapter(adapter: unknown): void;
310+
export function registerAdapter(adapter: Adapter): void;
260311

261312
/**
262313
* Sets the form mode for Turbo Drive.

0 commit comments

Comments
 (0)