application.ts 1.0.0
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/LICENSE +21 -0
- package/README.md +358 -0
- package/dist/app/App.d.ts +124 -0
- package/dist/app/App.js +326 -0
- package/dist/app/App.js.map +1 -0
- package/dist/app/AppView.d.ts +143 -0
- package/dist/app/AppView.js +264 -0
- package/dist/app/AppView.js.map +1 -0
- package/dist/app/types.d.ts +67 -0
- package/dist/app/types.js +2 -0
- package/dist/app/types.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/route.d.ts +34 -0
- package/dist/navigation/route.js +68 -0
- package/dist/navigation/route.js.map +1 -0
- package/dist/navigation/router.d.ts +92 -0
- package/dist/navigation/router.js +246 -0
- package/dist/navigation/router.js.map +1 -0
- package/dist/navigation/types.d.ts +63 -0
- package/dist/navigation/types.js +9 -0
- package/dist/navigation/types.js.map +1 -0
- package/package.json +68 -0
- package/src/app/App.ts +391 -0
- package/src/app/AppView.ts +333 -0
- package/src/app/types.ts +78 -0
- package/src/index.ts +28 -0
- package/src/navigation/route.ts +87 -0
- package/src/navigation/router.ts +284 -0
- package/src/navigation/types.ts +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Xoboto Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# Application.Ts
|
|
2
|
+
|
|
3
|
+
A lightweight, dependency-free except template.ts and stackview.ts TypeScript framework for building single-page applications (SPAs) with pure vanilla JavaScript and CSS. No build tools required, just modern web standards.
|
|
4
|
+
|
|
5
|
+
## What is Application.Ts?
|
|
6
|
+
|
|
7
|
+
Application.Ts is a minimalist SPA framework that combines:
|
|
8
|
+
- **Routing**: URL-based navigation with parameters and guards
|
|
9
|
+
- **Templating**: Reactive data binding with Template.Ts
|
|
10
|
+
- **View Management**: Stack-based view transitions with StackView.Ts
|
|
11
|
+
- **Component Model**: Web Components for reusable UI elements
|
|
12
|
+
|
|
13
|
+
Built on web standards, Application.Ts provides a simple yet powerful foundation for creating modern web applications without the complexity of larger frameworks.
|
|
14
|
+
|
|
15
|
+
## Quick Setup
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install application.ts
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { App } from 'application.ts';
|
|
23
|
+
import { HomeView } from './views/home.view';
|
|
24
|
+
|
|
25
|
+
const app = new App('#root');
|
|
26
|
+
|
|
27
|
+
app.router
|
|
28
|
+
.map('/', HomeView)
|
|
29
|
+
.notFound(NotFoundView);
|
|
30
|
+
|
|
31
|
+
app.start();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<!doctype html>
|
|
36
|
+
<html lang="en">
|
|
37
|
+
<head>
|
|
38
|
+
<meta charset="UTF-8" />
|
|
39
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
40
|
+
<title>My App</title>
|
|
41
|
+
</head>
|
|
42
|
+
<body>
|
|
43
|
+
<div id="root"></div>
|
|
44
|
+
<script type="module" src="/main.ts"></script>
|
|
45
|
+
</body>
|
|
46
|
+
</html>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
### 🚀 Routing
|
|
52
|
+
- Pattern-based routing with URL parameters
|
|
53
|
+
- Navigation guards (canEnter)
|
|
54
|
+
- Programmatic navigation
|
|
55
|
+
- Browser history support
|
|
56
|
+
- Query string handling
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
app.router
|
|
60
|
+
.map('/', HomeView)
|
|
61
|
+
.map('/user/:id', UserView)
|
|
62
|
+
.map('/dashboard', DashboardView, {
|
|
63
|
+
canEnter: () => AuthService.isLoggedIn()
|
|
64
|
+
})
|
|
65
|
+
.notFound(NotFoundView);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Route Guards with canEnter
|
|
69
|
+
|
|
70
|
+
Protect routes with navigation guards. The `canEnter` function can:
|
|
71
|
+
- Return `true` to allow navigation
|
|
72
|
+
- Return `false` to block navigation
|
|
73
|
+
- Return a string path to redirect
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Simple authentication check
|
|
77
|
+
app.router.map('/dashboard', DashboardView, {
|
|
78
|
+
canEnter: () => {
|
|
79
|
+
return AuthService.isLoggedIn();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Redirect to login if not authenticated
|
|
84
|
+
app.router.map('/profile', ProfileView, {
|
|
85
|
+
canEnter: () => {
|
|
86
|
+
if (!AuthService.isLoggedIn()) {
|
|
87
|
+
return '/login'; // Redirect to login page
|
|
88
|
+
}
|
|
89
|
+
return true; // Allow access
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Access route parameters in guard
|
|
94
|
+
app.router.map('/admin/:section', AdminView, {
|
|
95
|
+
canEnter: (params) => {
|
|
96
|
+
if (!AuthService.isAdmin()) {
|
|
97
|
+
return '/'; // Redirect to home
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Async guards for API checks
|
|
104
|
+
app.router.map('/document/:id', DocumentView, {
|
|
105
|
+
canEnter: async (params) => {
|
|
106
|
+
const hasAccess = await checkDocumentPermission(params.id);
|
|
107
|
+
return hasAccess ? true : '/unauthorized';
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 🎨 Reactive Templates
|
|
113
|
+
Data binding with Template.Ts v2:
|
|
114
|
+
- `@on:` - Event handlers
|
|
115
|
+
- `@prop:` - Property binding
|
|
116
|
+
- `@att` - Attribute binding
|
|
117
|
+
- `@batt` - Boolean attribute binding
|
|
118
|
+
- `@if` - Conditional rendering
|
|
119
|
+
- `@for` - List rendering
|
|
120
|
+
- `{{ }}` - Expression interpolation
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const template = `
|
|
124
|
+
<div>
|
|
125
|
+
<h1>{{ title }}</h1>
|
|
126
|
+
<button @on:click="increment">Count: {{ count }}</button>
|
|
127
|
+
<ul>
|
|
128
|
+
<li @for="items">{{ item.name }}</li>
|
|
129
|
+
</ul>
|
|
130
|
+
</div>`;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 🧩 Component System
|
|
134
|
+
Build reusable components with AppView base class:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { AppView, Register } from 'application.ts';
|
|
138
|
+
|
|
139
|
+
@Register
|
|
140
|
+
export class MyComponent extends AppView {
|
|
141
|
+
template() {
|
|
142
|
+
return `<div>{{ message }}</div>`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
state() {
|
|
146
|
+
return { message: 'Hello World' };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 📐 Layouts
|
|
152
|
+
Wrap views with shared layouts:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
app.router
|
|
156
|
+
.map('/', HomeView)
|
|
157
|
+
.map('/about', AboutView)
|
|
158
|
+
.setLayout(DefaultLayout);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 🎯 View Lifecycle
|
|
162
|
+
Hook into view lifecycle events:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
export class MyView extends AppView {
|
|
166
|
+
async onMounted() {
|
|
167
|
+
// View mounted to DOM
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async stackViewShown() {
|
|
171
|
+
// View became visible
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async stackViewHidden() {
|
|
175
|
+
// View hidden
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## How to Use
|
|
181
|
+
|
|
182
|
+
### 1. Create a View
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// views/home.view.ts
|
|
186
|
+
import { AppView, Register } from 'application.ts';
|
|
187
|
+
|
|
188
|
+
const template = `
|
|
189
|
+
<div class="home">
|
|
190
|
+
<h1>{{ title }}</h1>
|
|
191
|
+
<p>Counter: {{ count }}</p>
|
|
192
|
+
<button @on:click="increment">Increment</button>
|
|
193
|
+
</div>`;
|
|
194
|
+
|
|
195
|
+
class State {
|
|
196
|
+
title: string = 'Home Page';
|
|
197
|
+
count: number = 0;
|
|
198
|
+
|
|
199
|
+
increment: () => void = () => {
|
|
200
|
+
this.count++;
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@Register
|
|
205
|
+
export class HomeView extends AppView {
|
|
206
|
+
template() {
|
|
207
|
+
return template;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
state() {
|
|
211
|
+
return new State();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 2. Set Up Routes
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// main.ts
|
|
220
|
+
import { App } from 'application.ts';
|
|
221
|
+
import { HomeView } from './views/home.view';
|
|
222
|
+
import { AboutView } from './views/about.view';
|
|
223
|
+
import { UserView } from './views/user.view';
|
|
224
|
+
|
|
225
|
+
const app = new App('#root');
|
|
226
|
+
|
|
227
|
+
app.router
|
|
228
|
+
.map('/', HomeView)
|
|
229
|
+
.map('/about', AboutView)
|
|
230
|
+
.map('/user/:id', UserView);
|
|
231
|
+
|
|
232
|
+
app.start();
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 3. Navigate Between Views
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// Programmatic navigation
|
|
239
|
+
this.navigate('/about');
|
|
240
|
+
this.navigate('/user/123');
|
|
241
|
+
|
|
242
|
+
// In templates with links
|
|
243
|
+
<a href="/about">About</a>
|
|
244
|
+
<a href="/user/42">User Profile</a>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 4. Access Route Parameters
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
export class UserView extends AppView {
|
|
251
|
+
async onMounted() {
|
|
252
|
+
const userId = this.params?.id;
|
|
253
|
+
console.log('User ID:', userId);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 5. Create Components
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// components/button.component.ts
|
|
262
|
+
import { AppView, Register } from 'application.ts';
|
|
263
|
+
|
|
264
|
+
const template = `
|
|
265
|
+
<button @on:click="handleClick" class="btn">
|
|
266
|
+
{{ label }}
|
|
267
|
+
</button>`;
|
|
268
|
+
|
|
269
|
+
@Register
|
|
270
|
+
export class AppButton extends AppView {
|
|
271
|
+
template() { return template; }
|
|
272
|
+
|
|
273
|
+
state() {
|
|
274
|
+
return {
|
|
275
|
+
label: 'Click me',
|
|
276
|
+
handleClick: () => {
|
|
277
|
+
this.dispatchEvent(new CustomEvent('buttonclick', {
|
|
278
|
+
bubbles: true
|
|
279
|
+
}));
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get label() { return this.viewState.label; }
|
|
285
|
+
set label(value: string) { this.setState('label', value); }
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Use in templates:
|
|
290
|
+
```html
|
|
291
|
+
<app-button @prop:label="'Save'" @on:buttonclick="handleSave"></app-button>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Examples
|
|
295
|
+
|
|
296
|
+
Explore the `/examples` folder for complete working examples:
|
|
297
|
+
|
|
298
|
+
- **Minimal** - The simplest possible app
|
|
299
|
+
- **Basic** - Routing, layouts, and components
|
|
300
|
+
- **Advanced** - Full-featured SPA with services, state management, and more
|
|
301
|
+
|
|
302
|
+
## API Reference
|
|
303
|
+
|
|
304
|
+
### App
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
const app = new App(selector: string, options?: AppOptions);
|
|
308
|
+
app.router // Access router
|
|
309
|
+
app.start() // Start the application
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Router
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
router.map(path: string, view: typeof AppView, options?: RouteOptions)
|
|
316
|
+
router.setLayout(layout: typeof AppView)
|
|
317
|
+
router.notFound(view: typeof AppView)
|
|
318
|
+
router.navigate(path: string)
|
|
319
|
+
router.start()
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### AppView
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
abstract class AppView {
|
|
326
|
+
template(): string // Define HTML template
|
|
327
|
+
state() // Define reactive state
|
|
328
|
+
|
|
329
|
+
// Lifecycle hooks
|
|
330
|
+
onBeforeMount()
|
|
331
|
+
onMounted()
|
|
332
|
+
onBeforeUnmount()
|
|
333
|
+
onUnmounted()
|
|
334
|
+
onStateChanged()
|
|
335
|
+
onParamsChanged()
|
|
336
|
+
|
|
337
|
+
// Navigation
|
|
338
|
+
navigate(path: string)
|
|
339
|
+
|
|
340
|
+
// State management
|
|
341
|
+
setState(key: string, value: any)
|
|
342
|
+
setStates(updates: Record<string, any>)
|
|
343
|
+
update() // Force re-render
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
MIT
|
|
350
|
+
|
|
351
|
+
## Contributing
|
|
352
|
+
|
|
353
|
+
Contributions are welcome! Please feel free to submit issues or pull requests.
|
|
354
|
+
|
|
355
|
+
## Links
|
|
356
|
+
|
|
357
|
+
- [Template.Ts Documentation](https://www.npmjs.com/package/template.ts)
|
|
358
|
+
- [StackView.Ts Documentation](https://www.npmjs.com/package/stackview.ts)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Router } from '../navigation/router';
|
|
2
|
+
import type { AppView } from './AppView';
|
|
3
|
+
/**
|
|
4
|
+
* View constructor type
|
|
5
|
+
*/
|
|
6
|
+
type ViewConstructor = new () => AppView<any>;
|
|
7
|
+
/**
|
|
8
|
+
* Main App class that manages routing and view rendering
|
|
9
|
+
* Integrates Router with StackView.Ts for navigation
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { App } from 'application.ts';
|
|
14
|
+
* import { HomeView, AboutView, NotFoundView } from './views';
|
|
15
|
+
*
|
|
16
|
+
* const app = new App('#root');
|
|
17
|
+
*
|
|
18
|
+
* app.router
|
|
19
|
+
* .map('/', HomeView)
|
|
20
|
+
* .map('/about', AboutView)
|
|
21
|
+
* .notFound(NotFoundView);
|
|
22
|
+
*
|
|
23
|
+
* app.start();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class App {
|
|
27
|
+
readonly router: Router;
|
|
28
|
+
private stackView;
|
|
29
|
+
private rootElement;
|
|
30
|
+
private viewRegistry;
|
|
31
|
+
private layoutRegistry;
|
|
32
|
+
private currentViewInstance;
|
|
33
|
+
private currentLayoutInstance;
|
|
34
|
+
private currentRoutePath;
|
|
35
|
+
private defaultLayout;
|
|
36
|
+
/**
|
|
37
|
+
* Get the App instance from any element by traversing up the DOM tree
|
|
38
|
+
* @param element - Any HTMLElement in the app
|
|
39
|
+
* @returns App instance or null if not found
|
|
40
|
+
*/
|
|
41
|
+
static fromElement(element: HTMLElement | null): App | null;
|
|
42
|
+
constructor(rootSelector?: string);
|
|
43
|
+
/**
|
|
44
|
+
* Register a view class with a handler name
|
|
45
|
+
* @param handler - The view handler/identifier used in router.map()
|
|
46
|
+
* @param viewClass - The AppView class constructor
|
|
47
|
+
*/
|
|
48
|
+
registerView(handler: string, viewClass: ViewConstructor): this;
|
|
49
|
+
/**
|
|
50
|
+
* Register multiple views at once
|
|
51
|
+
* @param views - Object mapping handler names to view classes
|
|
52
|
+
*/
|
|
53
|
+
registerViews(views: Record<string, ViewConstructor>): this;
|
|
54
|
+
/**
|
|
55
|
+
* Register a layout class with a handler name
|
|
56
|
+
* @param handler - The layout handler/identifier
|
|
57
|
+
* @param layoutClass - The AppView layout class constructor
|
|
58
|
+
*/
|
|
59
|
+
registerLayout(handler: string, layoutClass: ViewConstructor): this;
|
|
60
|
+
/**
|
|
61
|
+
* Register multiple layouts at once
|
|
62
|
+
* @param layouts - Object mapping handler names to layout classes
|
|
63
|
+
*/
|
|
64
|
+
registerLayouts(layouts: Record<string, ViewConstructor>): this;
|
|
65
|
+
/**
|
|
66
|
+
* Set the default layout for all routes
|
|
67
|
+
* @param handler - The layout handler name, or null for no layout
|
|
68
|
+
*/
|
|
69
|
+
setDefaultLayout(handler: string | null): this;
|
|
70
|
+
/**
|
|
71
|
+
* Initialize the root element and StackView
|
|
72
|
+
* @param selector - CSS selector for the root element
|
|
73
|
+
*/
|
|
74
|
+
private initializeRoot;
|
|
75
|
+
/**
|
|
76
|
+
* Start the application
|
|
77
|
+
* @param rootSelector - Optional root selector if not provided in constructor
|
|
78
|
+
*/
|
|
79
|
+
start(rootSelector?: string): void;
|
|
80
|
+
/**
|
|
81
|
+
* Resolve view class from handler (supports both class constructor and string lookup)
|
|
82
|
+
* @param handler - View class constructor or string identifier
|
|
83
|
+
* @returns View class constructor or null
|
|
84
|
+
*/
|
|
85
|
+
private resolveViewClass;
|
|
86
|
+
/**
|
|
87
|
+
* Handle navigation event from router
|
|
88
|
+
*/
|
|
89
|
+
private handleNavigation;
|
|
90
|
+
/**
|
|
91
|
+
* Render view wrapped in a layout
|
|
92
|
+
*/
|
|
93
|
+
private renderWithLayout;
|
|
94
|
+
/**
|
|
95
|
+
* Render view without layout
|
|
96
|
+
*/
|
|
97
|
+
private renderWithoutLayout;
|
|
98
|
+
/**
|
|
99
|
+
* Handle not found event from router
|
|
100
|
+
*/
|
|
101
|
+
private handleNotFound;
|
|
102
|
+
/**
|
|
103
|
+
* Get the route pattern that matches the given path
|
|
104
|
+
*/
|
|
105
|
+
getRoutePattern(path: string): string | null;
|
|
106
|
+
/**
|
|
107
|
+
* Get the current view instance
|
|
108
|
+
*/
|
|
109
|
+
get currentView(): AppView<any> | null;
|
|
110
|
+
/**
|
|
111
|
+
* Get the current route pattern (e.g., '/user/:id')
|
|
112
|
+
*/
|
|
113
|
+
get currentRoute(): string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Navigate to a specific path
|
|
116
|
+
* @param path - The path to navigate to
|
|
117
|
+
*/
|
|
118
|
+
navigate(path: string): void;
|
|
119
|
+
/**
|
|
120
|
+
* Go back in navigation history
|
|
121
|
+
*/
|
|
122
|
+
goBack(): Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
export {};
|