@hybridly/core 0.0.1-dev.2
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/dist/index.cjs +642 -0
- package/dist/index.d.ts +367 -0
- package/dist/index.mjs +624 -0
- package/package.json +50 -0
- package/properties.d.ts +6 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { RequestData } from '@hybridly/utils';
|
|
2
|
+
import { AxiosResponse, AxiosProgressEvent } from 'axios';
|
|
3
|
+
|
|
4
|
+
declare type MaybePromise<T> = T | Promise<T>;
|
|
5
|
+
|
|
6
|
+
interface Hooks {
|
|
7
|
+
/**
|
|
8
|
+
* Called before anything when a visit is going to happen.
|
|
9
|
+
*/
|
|
10
|
+
before: (options: VisitOptions) => MaybePromise<any | boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Called before the request of a visit is going to happen.
|
|
13
|
+
*/
|
|
14
|
+
start: (context: InternalRouterContext) => MaybePromise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Called when progress on the request is being made.
|
|
17
|
+
*/
|
|
18
|
+
progress: (progress: Progress) => MaybePromise<any>;
|
|
19
|
+
/**
|
|
20
|
+
* Called when data is received after a request for a visit.
|
|
21
|
+
*/
|
|
22
|
+
data: (response: AxiosResponse) => MaybePromise<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Called when a request is successful and there is no error.
|
|
25
|
+
*/
|
|
26
|
+
success: (payload: VisitPayload) => MaybePromise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* Called when a request is successful but there were errors.
|
|
29
|
+
*/
|
|
30
|
+
error: (errors: Errors) => MaybePromise<any>;
|
|
31
|
+
/**
|
|
32
|
+
* Called when a request has been aborted.
|
|
33
|
+
*/
|
|
34
|
+
abort: (context: InternalRouterContext) => MaybePromise<any>;
|
|
35
|
+
/**
|
|
36
|
+
* Called when a response to a request is not a valid Hybridly response.
|
|
37
|
+
*/
|
|
38
|
+
invalid: (response: AxiosResponse) => MaybePromise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Called when an unknowne exception was triggered.
|
|
41
|
+
*/
|
|
42
|
+
exception: (error: Error) => MaybePromise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Called whenever the request failed, for any reason, in addition to other hooks.
|
|
45
|
+
*/
|
|
46
|
+
fail: (context: InternalRouterContext) => MaybePromise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Called after a request has been made, even if it didn't succeed.
|
|
49
|
+
*/
|
|
50
|
+
after: (context: InternalRouterContext) => MaybePromise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Called when a visit has been made and a page component has been navigated to.
|
|
53
|
+
*/
|
|
54
|
+
navigate: (options: NavigationOptions) => MaybePromise<void>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Registers a global hook.
|
|
58
|
+
*/
|
|
59
|
+
declare function registerHook<T extends keyof Hooks>(hook: T, fn: Hooks[T]): () => void;
|
|
60
|
+
/**
|
|
61
|
+
* Registers a global hook that will run only once.
|
|
62
|
+
*/
|
|
63
|
+
declare function registerHookOnce<T extends keyof Hooks>(hook: T, fn: Hooks[T]): void;
|
|
64
|
+
|
|
65
|
+
interface Plugin {
|
|
66
|
+
name: string;
|
|
67
|
+
initialized: (context: InternalRouterContext) => MaybePromise<void>;
|
|
68
|
+
hooks: Partial<Hooks>;
|
|
69
|
+
}
|
|
70
|
+
declare function definePlugin(plugin: Plugin): Plugin;
|
|
71
|
+
|
|
72
|
+
/** Options for creating a router context. */
|
|
73
|
+
interface RouterContextOptions {
|
|
74
|
+
/** The initial payload served by the browser. */
|
|
75
|
+
payload: VisitPayload;
|
|
76
|
+
/** Adapter-specific functions. */
|
|
77
|
+
adapter: Adapter;
|
|
78
|
+
/** History state serializer. */
|
|
79
|
+
serializer?: Serializer;
|
|
80
|
+
/** List of plugins. */
|
|
81
|
+
plugins?: Plugin[];
|
|
82
|
+
}
|
|
83
|
+
/** Router context. */
|
|
84
|
+
interface InternalRouterContext {
|
|
85
|
+
/** The current, normalized URL. */
|
|
86
|
+
url: string;
|
|
87
|
+
/** The current view. */
|
|
88
|
+
view: View;
|
|
89
|
+
/** The current, optional dialog. */
|
|
90
|
+
dialog?: View;
|
|
91
|
+
/** The current local asset version. */
|
|
92
|
+
version: string;
|
|
93
|
+
/** The current adapter's functions. */
|
|
94
|
+
adapter: Adapter;
|
|
95
|
+
/** Scroll positions of the current page's DOM elements. */
|
|
96
|
+
scrollRegions: ScrollRegion[];
|
|
97
|
+
/** Arbitrary state. */
|
|
98
|
+
state: Record<string, any>;
|
|
99
|
+
/** Currently pending visit. */
|
|
100
|
+
activeVisit?: PendingVisit;
|
|
101
|
+
/** History state serializer. */
|
|
102
|
+
serializer: Serializer;
|
|
103
|
+
/** List of plugins. */
|
|
104
|
+
plugins: Plugin[];
|
|
105
|
+
/** Global hooks. */
|
|
106
|
+
hooks: Partial<Record<keyof Hooks, Array<Function>>>;
|
|
107
|
+
}
|
|
108
|
+
/** Router context. */
|
|
109
|
+
declare type RouterContext = Readonly<InternalRouterContext>;
|
|
110
|
+
/** Adapter-specific functions. */
|
|
111
|
+
interface Adapter {
|
|
112
|
+
/** Resolves a component from the given name. */
|
|
113
|
+
resolveComponent: ResolveComponent;
|
|
114
|
+
/** Swaps to the given view. */
|
|
115
|
+
swapView: SwapView;
|
|
116
|
+
/** Swaps to the given dialog. */
|
|
117
|
+
swapDialog: SwapDialog;
|
|
118
|
+
/** Called when the context is updated. */
|
|
119
|
+
update?: (context: InternalRouterContext) => void;
|
|
120
|
+
}
|
|
121
|
+
interface ScrollRegion {
|
|
122
|
+
top: number;
|
|
123
|
+
left: number;
|
|
124
|
+
}
|
|
125
|
+
/** Provides methods to serialize the state into the history state. */
|
|
126
|
+
interface Serializer {
|
|
127
|
+
serialize: <T>(view: T) => any;
|
|
128
|
+
unserialize: <T>(state: any) => T;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Gets the current context. */
|
|
132
|
+
declare function getRouterContext(): RouterContext;
|
|
133
|
+
|
|
134
|
+
declare type UrlResolvable = string | URL | Location;
|
|
135
|
+
declare type UrlTransformable = Partial<Omit<URL, 'searchParams' | 'toJSON' | 'toString'>>;
|
|
136
|
+
/**
|
|
137
|
+
* Converts an input to an URL, optionally changing its properties after initialization.
|
|
138
|
+
*/
|
|
139
|
+
declare function makeUrl(href: UrlResolvable, transformations?: UrlTransformable): URL;
|
|
140
|
+
/**
|
|
141
|
+
* Checks if the given URLs have the same origin and path.
|
|
142
|
+
*/
|
|
143
|
+
declare function sameUrls(...hrefs: UrlResolvable[]): boolean;
|
|
144
|
+
|
|
145
|
+
declare type ConditionalNavigationOption = boolean | ((payload: VisitPayload) => boolean);
|
|
146
|
+
interface LocalVisitOptions {
|
|
147
|
+
/** Name of the component to use. */
|
|
148
|
+
component?: string;
|
|
149
|
+
/** Properties to apply to the component. */
|
|
150
|
+
properties: Properties;
|
|
151
|
+
/**
|
|
152
|
+
* Whether to replace the current history state instead of adding
|
|
153
|
+
* one. This affects the browser's "back" and "forward" features.
|
|
154
|
+
*/
|
|
155
|
+
replace?: ConditionalNavigationOption;
|
|
156
|
+
/** Whether to preserve the current scrollbar position. */
|
|
157
|
+
preserveScroll?: ConditionalNavigationOption;
|
|
158
|
+
/** Whether to preserve the current page component state. */
|
|
159
|
+
preserveState?: ConditionalNavigationOption;
|
|
160
|
+
}
|
|
161
|
+
interface NavigationOptions {
|
|
162
|
+
/** View to navigate to. */
|
|
163
|
+
payload?: VisitPayload;
|
|
164
|
+
/**
|
|
165
|
+
* Whether to replace the current history state instead of adding
|
|
166
|
+
* one. This affects the browser's "back" and "forward" features.
|
|
167
|
+
*/
|
|
168
|
+
replace?: ConditionalNavigationOption;
|
|
169
|
+
/** Whether to preserve the current scrollbar position. */
|
|
170
|
+
preserveScroll?: ConditionalNavigationOption;
|
|
171
|
+
/** Whether to preserve the current page component's state. */
|
|
172
|
+
preserveState?: ConditionalNavigationOption;
|
|
173
|
+
/** Whether to preserve the current URL. */
|
|
174
|
+
preserveUrl?: ConditionalNavigationOption;
|
|
175
|
+
/**
|
|
176
|
+
* Properties of the given URL to override.
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* router.get('/login?redirect=/', {
|
|
180
|
+
* transformUrl: { search: '' }
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
transformUrl?: UrlTransformable;
|
|
185
|
+
/**
|
|
186
|
+
* Defines whether the history state should be updated.
|
|
187
|
+
* @internal This is an advanced property meant to be used internally.
|
|
188
|
+
*/
|
|
189
|
+
updateHistoryState?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Defines whether this navigation is a back/forward visit from the popstate event.
|
|
192
|
+
* @internal This is an advanced property meant to be used internally.
|
|
193
|
+
*/
|
|
194
|
+
isBackForward?: boolean;
|
|
195
|
+
}
|
|
196
|
+
declare type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
197
|
+
interface VisitOptions extends Omit<NavigationOptions, 'request'> {
|
|
198
|
+
/** The URL to visit. */
|
|
199
|
+
url?: UrlResolvable;
|
|
200
|
+
/** HTTP verb to use for the request. */
|
|
201
|
+
method?: Method;
|
|
202
|
+
/** Body of the request. */
|
|
203
|
+
data?: RequestData;
|
|
204
|
+
/** Which properties to update for this visit. Other properties will be ignored. */
|
|
205
|
+
only?: string | string[];
|
|
206
|
+
/** Which properties not to update for this visit. Other properties will be updated. */
|
|
207
|
+
except?: string | string[];
|
|
208
|
+
/** Specific headers to add to the request. */
|
|
209
|
+
headers?: Record<string, string>;
|
|
210
|
+
/** The bag in which to put potential errors. */
|
|
211
|
+
errorBag?: string;
|
|
212
|
+
/** Hooks for this visit. */
|
|
213
|
+
hooks?: Partial<Hooks>;
|
|
214
|
+
/** If `true`, force the usage of a `FormData` object. */
|
|
215
|
+
useFormData?: boolean;
|
|
216
|
+
}
|
|
217
|
+
interface VisitResponse {
|
|
218
|
+
response?: AxiosResponse;
|
|
219
|
+
error?: {
|
|
220
|
+
type: string;
|
|
221
|
+
actual: Error;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
interface Router {
|
|
225
|
+
/** Aborts the currently pending visit, if any. */
|
|
226
|
+
abort: () => Promise<void>;
|
|
227
|
+
/** Checks if there is an active request. */
|
|
228
|
+
active: () => boolean;
|
|
229
|
+
/** Makes a visit with the given options. */
|
|
230
|
+
visit: (options: VisitOptions) => Promise<VisitResponse>;
|
|
231
|
+
/** Reloads the current page. */
|
|
232
|
+
reload: (options?: VisitOptions) => Promise<VisitResponse>;
|
|
233
|
+
/** Makes a GET request to the given URL. */
|
|
234
|
+
get: (url: UrlResolvable, options?: Omit<VisitOptions, 'method' | 'url'>) => Promise<VisitResponse>;
|
|
235
|
+
/** Makes a POST request to the given URL. */
|
|
236
|
+
post: (url: UrlResolvable, options?: Omit<VisitOptions, 'method' | 'url'>) => Promise<VisitResponse>;
|
|
237
|
+
/** Makes a PUT request to the given URL. */
|
|
238
|
+
put: (url: UrlResolvable, options?: Omit<VisitOptions, 'method' | 'url'>) => Promise<VisitResponse>;
|
|
239
|
+
/** Makes a PATCH request to the given URL. */
|
|
240
|
+
patch: (url: UrlResolvable, options?: Omit<VisitOptions, 'method' | 'url'>) => Promise<VisitResponse>;
|
|
241
|
+
/** Makes a DELETE request to the given URL. */
|
|
242
|
+
delete: (url: UrlResolvable, options?: Omit<VisitOptions, 'method' | 'url'>) => Promise<VisitResponse>;
|
|
243
|
+
/** Navigates to the given external URL. Alias for `document.location.href`. */
|
|
244
|
+
external: (url: UrlResolvable, data?: VisitOptions['data']) => void;
|
|
245
|
+
/** Navigates to the given URL without a server round-trip. */
|
|
246
|
+
local: (url: UrlResolvable, options: LocalVisitOptions) => Promise<void>;
|
|
247
|
+
/** Access the history state. */
|
|
248
|
+
history: {
|
|
249
|
+
/** Remembers a value for the given route. */
|
|
250
|
+
remember: (key: string, value: any) => void;
|
|
251
|
+
/** Gets a remembered value. */
|
|
252
|
+
get: <T = any>(key: string) => T | undefined;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/** An axios visit being made. */
|
|
256
|
+
interface PendingVisit {
|
|
257
|
+
/** The URL to which the request is being made. */
|
|
258
|
+
url: URL;
|
|
259
|
+
/** Abort controller associated to this request. */
|
|
260
|
+
controller: AbortController;
|
|
261
|
+
/** Options for the associated visit. */
|
|
262
|
+
options: VisitOptions;
|
|
263
|
+
/** Visit identifier. */
|
|
264
|
+
id: string;
|
|
265
|
+
}
|
|
266
|
+
/** A page or dialog component. */
|
|
267
|
+
interface View {
|
|
268
|
+
/** Name of the component to use. */
|
|
269
|
+
name: string;
|
|
270
|
+
/** Properties to apply to the component. */
|
|
271
|
+
properties: Properties;
|
|
272
|
+
}
|
|
273
|
+
declare type Property = null | string | number | boolean | Property[] | {
|
|
274
|
+
[name: string]: Property;
|
|
275
|
+
};
|
|
276
|
+
declare type Properties = Record<string | number, Property>;
|
|
277
|
+
interface SwapOptions<T> {
|
|
278
|
+
/** The new component. */
|
|
279
|
+
component: T;
|
|
280
|
+
/** Whether to preserve the state of the component. */
|
|
281
|
+
preserveState?: boolean;
|
|
282
|
+
}
|
|
283
|
+
declare type ViewComponent = any;
|
|
284
|
+
declare type DialogComponent = any;
|
|
285
|
+
declare type ResolveComponent = (name: string) => Promise<ViewComponent>;
|
|
286
|
+
declare type SwapView = (options: SwapOptions<ViewComponent>) => Promise<void>;
|
|
287
|
+
declare type SwapDialog = (options: SwapOptions<DialogComponent>) => Promise<void>;
|
|
288
|
+
/** The payload of a visit request from the server. */
|
|
289
|
+
interface VisitPayload {
|
|
290
|
+
/** The view to use in this request. */
|
|
291
|
+
view: View;
|
|
292
|
+
/** An optional dialog. */
|
|
293
|
+
dialog?: View;
|
|
294
|
+
/** The current page URL. */
|
|
295
|
+
url: string;
|
|
296
|
+
/** The current asset version. */
|
|
297
|
+
version: string;
|
|
298
|
+
}
|
|
299
|
+
interface Progress {
|
|
300
|
+
/** Base event. */
|
|
301
|
+
event: AxiosProgressEvent;
|
|
302
|
+
/** Computed percentage. */
|
|
303
|
+
percentage: Readonly<number>;
|
|
304
|
+
}
|
|
305
|
+
interface Errors {
|
|
306
|
+
[key: string]: string;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* The hybridly router.
|
|
311
|
+
* This is the core function that you can use to navigate in
|
|
312
|
+
* your application. Make sure the routes you call return a
|
|
313
|
+
* hybridly response, otherwise you need to call `external`.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* router.get('/posts/edit', { post })
|
|
317
|
+
*/
|
|
318
|
+
declare const router: Router;
|
|
319
|
+
/** Creates the hybridly router. */
|
|
320
|
+
declare function createRouter(options: RouterContextOptions): Promise<InternalRouterContext>;
|
|
321
|
+
|
|
322
|
+
interface Authorizable<Authorizations extends Record<string, boolean>> {
|
|
323
|
+
authorization: Authorizations;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Checks whether the given data has the authorization for the given action.
|
|
327
|
+
* If the data object has no authorization definition corresponding to the given action, this method will return `false`.
|
|
328
|
+
*/
|
|
329
|
+
declare function can<Authorizations extends Record<string, boolean>, Data extends Authorizable<Authorizations>, Action extends keyof Data['authorization']>(resource: Data, action: Action): Authorizations[Action];
|
|
330
|
+
|
|
331
|
+
declare const STORAGE_EXTERNAL_KEY = "hybridly:external";
|
|
332
|
+
declare const HYBRIDLY_HEADER = "x-hybridly";
|
|
333
|
+
declare const EXTERNAL_VISIT_HEADER: string;
|
|
334
|
+
declare const PARTIAL_COMPONENT_HEADER: string;
|
|
335
|
+
declare const ONLY_DATA_HEADER: string;
|
|
336
|
+
declare const EXCEPT_DATA_HEADER: string;
|
|
337
|
+
declare const CONTEXT_HEADER: string;
|
|
338
|
+
declare const VERSION_HEADER: string;
|
|
339
|
+
declare const ERROR_BAG_HEADER: string;
|
|
340
|
+
declare const SCROLL_REGION_ATTRIBUTE = "scroll-region";
|
|
341
|
+
|
|
342
|
+
declare const constants_STORAGE_EXTERNAL_KEY: typeof STORAGE_EXTERNAL_KEY;
|
|
343
|
+
declare const constants_HYBRIDLY_HEADER: typeof HYBRIDLY_HEADER;
|
|
344
|
+
declare const constants_EXTERNAL_VISIT_HEADER: typeof EXTERNAL_VISIT_HEADER;
|
|
345
|
+
declare const constants_PARTIAL_COMPONENT_HEADER: typeof PARTIAL_COMPONENT_HEADER;
|
|
346
|
+
declare const constants_ONLY_DATA_HEADER: typeof ONLY_DATA_HEADER;
|
|
347
|
+
declare const constants_EXCEPT_DATA_HEADER: typeof EXCEPT_DATA_HEADER;
|
|
348
|
+
declare const constants_CONTEXT_HEADER: typeof CONTEXT_HEADER;
|
|
349
|
+
declare const constants_VERSION_HEADER: typeof VERSION_HEADER;
|
|
350
|
+
declare const constants_ERROR_BAG_HEADER: typeof ERROR_BAG_HEADER;
|
|
351
|
+
declare const constants_SCROLL_REGION_ATTRIBUTE: typeof SCROLL_REGION_ATTRIBUTE;
|
|
352
|
+
declare namespace constants {
|
|
353
|
+
export {
|
|
354
|
+
constants_STORAGE_EXTERNAL_KEY as STORAGE_EXTERNAL_KEY,
|
|
355
|
+
constants_HYBRIDLY_HEADER as HYBRIDLY_HEADER,
|
|
356
|
+
constants_EXTERNAL_VISIT_HEADER as EXTERNAL_VISIT_HEADER,
|
|
357
|
+
constants_PARTIAL_COMPONENT_HEADER as PARTIAL_COMPONENT_HEADER,
|
|
358
|
+
constants_ONLY_DATA_HEADER as ONLY_DATA_HEADER,
|
|
359
|
+
constants_EXCEPT_DATA_HEADER as EXCEPT_DATA_HEADER,
|
|
360
|
+
constants_CONTEXT_HEADER as CONTEXT_HEADER,
|
|
361
|
+
constants_VERSION_HEADER as VERSION_HEADER,
|
|
362
|
+
constants_ERROR_BAG_HEADER as ERROR_BAG_HEADER,
|
|
363
|
+
constants_SCROLL_REGION_ATTRIBUTE as SCROLL_REGION_ATTRIBUTE,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export { Authorizable, MaybePromise, Method, Plugin, ResolveComponent, Router, RouterContext, RouterContextOptions, UrlResolvable, VisitOptions, VisitPayload, VisitResponse, can, constants, createRouter, definePlugin, getRouterContext, makeUrl, registerHook, registerHookOnce, router, sameUrls };
|