@hybridly/core 0.4.0 → 0.4.1
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/index.cjs +104 -35
- package/dist/index.d.ts +9 -1
- package/dist/index.mjs +105 -36
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -160,7 +160,7 @@ async function restoreScrollPositions() {
|
|
|
160
160
|
utils.debug.scroll("No region found to restore.");
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
|
-
context.adapter.
|
|
163
|
+
context.adapter.executeOnMounted(() => {
|
|
164
164
|
utils.debug.scroll(`Restoring ${regions.length}/${context.scrollRegions.length} region(s).`);
|
|
165
165
|
regions.forEach((el, i) => el.scrollTo({
|
|
166
166
|
top: context.scrollRegions.at(i)?.top ?? el.scrollTop,
|
|
@@ -500,6 +500,7 @@ async function initializeContext(options) {
|
|
|
500
500
|
plugins: options.plugins ?? [],
|
|
501
501
|
axios: options.axios ?? axios__default.create(),
|
|
502
502
|
routing: options.routing,
|
|
503
|
+
preloadCache: /* @__PURE__ */ new Map(),
|
|
503
504
|
hooks: {},
|
|
504
505
|
memo: {}
|
|
505
506
|
};
|
|
@@ -590,6 +591,52 @@ async function closeDialog(options) {
|
|
|
590
591
|
});
|
|
591
592
|
}
|
|
592
593
|
|
|
594
|
+
function isPreloaded(targetUrl) {
|
|
595
|
+
const context = getInternalRouterContext();
|
|
596
|
+
return context.preloadCache.has(targetUrl.toString()) ?? false;
|
|
597
|
+
}
|
|
598
|
+
function getPreloadedRequest(targetUrl) {
|
|
599
|
+
const context = getInternalRouterContext();
|
|
600
|
+
return context.preloadCache.get(targetUrl.toString());
|
|
601
|
+
}
|
|
602
|
+
function storePreloadRequest(targetUrl, response) {
|
|
603
|
+
const context = getInternalRouterContext();
|
|
604
|
+
context.preloadCache.set(targetUrl.toString(), response);
|
|
605
|
+
}
|
|
606
|
+
function discardPreloadedRequest(targetUrl) {
|
|
607
|
+
const context = getInternalRouterContext();
|
|
608
|
+
return context.preloadCache.delete(targetUrl.toString());
|
|
609
|
+
}
|
|
610
|
+
async function performPreloadRequest(options) {
|
|
611
|
+
const context = getRouterContext();
|
|
612
|
+
const url = makeUrl(options.url ?? context.url);
|
|
613
|
+
if (isPreloaded(url)) {
|
|
614
|
+
utils.debug.router("This request is already preloaded.");
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
if (context.pendingNavigation) {
|
|
618
|
+
utils.debug.router("A navigation is pending, preload aborted.");
|
|
619
|
+
return false;
|
|
620
|
+
}
|
|
621
|
+
if (options.method !== "GET") {
|
|
622
|
+
utils.debug.router("Cannot preload non-GET requests.");
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
utils.debug.router(`Preloading response for [${url.toString()}]`);
|
|
626
|
+
try {
|
|
627
|
+
const response = await performHybridRequest(url, options);
|
|
628
|
+
if (!isHybridResponse(response)) {
|
|
629
|
+
utils.debug.router("Preload result was invalid.");
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
storePreloadRequest(url, response);
|
|
633
|
+
return true;
|
|
634
|
+
} catch (error) {
|
|
635
|
+
utils.debug.router("Preloading failed.");
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
593
640
|
const router = {
|
|
594
641
|
abort: async () => getRouterContext().pendingNavigation?.controller.abort(),
|
|
595
642
|
active: () => !!getRouterContext().pendingNavigation,
|
|
@@ -601,6 +648,7 @@ const router = {
|
|
|
601
648
|
patch: async (url, options = {}) => await performHybridNavigation({ preserveState: true, ...options, url, method: "PATCH" }),
|
|
602
649
|
delete: async (url, options = {}) => await performHybridNavigation({ preserveState: true, ...options, url, method: "DELETE" }),
|
|
603
650
|
local: async (url, options = {}) => await performLocalNavigation(url, options),
|
|
651
|
+
preload: async (url, options = {}) => await performPreloadRequest({ ...options, url, method: "GET" }),
|
|
604
652
|
external: (url, data = {}) => navigateToExternalUrl(url, data),
|
|
605
653
|
to: async (name, parameters, options) => {
|
|
606
654
|
const url = generateRouteFromName(name, parameters);
|
|
@@ -632,11 +680,6 @@ async function performHybridNavigation(options) {
|
|
|
632
680
|
if ((utils.hasFiles(options.data) || options.useFormData) && !(options.data instanceof FormData)) {
|
|
633
681
|
options.data = utils.objectToFormData(options.data);
|
|
634
682
|
utils.debug.router("Converted data to FormData.", options.data);
|
|
635
|
-
if (options.method && ["PUT", "PATCH", "DELETE"].includes(options.method) && options.spoof !== false) {
|
|
636
|
-
utils.debug.router(`Automatically spoofing method ${options.method}.`);
|
|
637
|
-
options.data.append("_method", options.method);
|
|
638
|
-
options.method = "POST";
|
|
639
|
-
}
|
|
640
683
|
}
|
|
641
684
|
if (!(options.data instanceof FormData) && options.method === "GET" && Object.keys(options.data ?? {}).length) {
|
|
642
685
|
utils.debug.router("Transforming data to query parameters.", options.data);
|
|
@@ -645,6 +688,19 @@ async function performHybridNavigation(options) {
|
|
|
645
688
|
});
|
|
646
689
|
options.data = {};
|
|
647
690
|
}
|
|
691
|
+
if (["PUT", "PATCH", "DELETE"].includes(options.method) && options.spoof !== false) {
|
|
692
|
+
utils.debug.router(`Automatically spoofing method ${options.method}.`);
|
|
693
|
+
if (options.data instanceof FormData) {
|
|
694
|
+
options.data.append("_method", options.method);
|
|
695
|
+
} else if (Object.keys(options.data ?? {}).length) {
|
|
696
|
+
Object.assign(options.data, { _method: options.method });
|
|
697
|
+
} else if (typeof options.data === "undefined") {
|
|
698
|
+
options.data = { _method: options.method };
|
|
699
|
+
} else {
|
|
700
|
+
utils.debug.router("Could not spoof method because body type is not supported.", options.data);
|
|
701
|
+
}
|
|
702
|
+
options.method = "POST";
|
|
703
|
+
}
|
|
648
704
|
if (!await runHooks("before", options.hooks, options, context)) {
|
|
649
705
|
utils.debug.router('"before" event returned false, aborting the navigation.');
|
|
650
706
|
throw new NavigationCancelledError('The navigation was cancelled by the "before" event.');
|
|
@@ -670,35 +726,7 @@ async function performHybridNavigation(options) {
|
|
|
670
726
|
});
|
|
671
727
|
await runHooks("start", options.hooks, context);
|
|
672
728
|
utils.debug.router("Making request with axios.");
|
|
673
|
-
const response = await
|
|
674
|
-
url: targetUrl.toString(),
|
|
675
|
-
method: options.method,
|
|
676
|
-
data: options.method === "GET" ? {} : options.data,
|
|
677
|
-
params: options.method === "GET" ? options.data : {},
|
|
678
|
-
signal: abortController.signal,
|
|
679
|
-
headers: {
|
|
680
|
-
...options.headers,
|
|
681
|
-
...context.dialog ? { [DIALOG_KEY_HEADER]: context.dialog.key } : {},
|
|
682
|
-
...context.dialog ? { [DIALOG_REDIRECT_HEADER]: context.dialog.redirectUrl ?? "" } : {},
|
|
683
|
-
...utils.when(options.only !== void 0 || options.except !== void 0, {
|
|
684
|
-
[PARTIAL_COMPONENT_HEADER]: context.view.component,
|
|
685
|
-
...utils.when(options.only, { [ONLY_DATA_HEADER]: JSON.stringify(options.only) }, {}),
|
|
686
|
-
...utils.when(options.except, { [EXCEPT_DATA_HEADER]: JSON.stringify(options.except) }, {})
|
|
687
|
-
}, {}),
|
|
688
|
-
...utils.when(options.errorBag, { [ERROR_BAG_HEADER]: options.errorBag }, {}),
|
|
689
|
-
...utils.when(context.version, { [VERSION_HEADER]: context.version }, {}),
|
|
690
|
-
[HYBRIDLY_HEADER]: true,
|
|
691
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
692
|
-
"Accept": "text/html, application/xhtml+xml"
|
|
693
|
-
},
|
|
694
|
-
validateStatus: () => true,
|
|
695
|
-
onUploadProgress: async (event) => {
|
|
696
|
-
await runHooks("progress", options.hooks, {
|
|
697
|
-
event,
|
|
698
|
-
percentage: Math.round(event.loaded / (event.total ?? 0) * 100)
|
|
699
|
-
}, context);
|
|
700
|
-
}
|
|
701
|
-
});
|
|
729
|
+
const response = await performHybridRequest(targetUrl, options, abortController);
|
|
702
730
|
await runHooks("data", options.hooks, response, context);
|
|
703
731
|
if (isExternalResponse(response)) {
|
|
704
732
|
utils.debug.router("The response is explicitely external.");
|
|
@@ -842,6 +870,47 @@ async function navigate(options) {
|
|
|
842
870
|
resetScrollPositions();
|
|
843
871
|
}
|
|
844
872
|
await runHooks("navigated", {}, options, context);
|
|
873
|
+
context.adapter.executeOnMounted(() => {
|
|
874
|
+
runHooks("mounted", {}, context);
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
async function performHybridRequest(targetUrl, options, abortController) {
|
|
878
|
+
const context = getInternalRouterContext();
|
|
879
|
+
const preloaded = getPreloadedRequest(targetUrl);
|
|
880
|
+
if (preloaded) {
|
|
881
|
+
utils.debug.router(`Found a pre-loaded request for [${targetUrl}]`);
|
|
882
|
+
discardPreloadedRequest(targetUrl);
|
|
883
|
+
return preloaded;
|
|
884
|
+
}
|
|
885
|
+
return await context.axios.request({
|
|
886
|
+
url: targetUrl.toString(),
|
|
887
|
+
method: options.method,
|
|
888
|
+
data: options.method === "GET" ? {} : options.data,
|
|
889
|
+
params: options.method === "GET" ? options.data : {},
|
|
890
|
+
signal: abortController?.signal,
|
|
891
|
+
headers: {
|
|
892
|
+
...options.headers,
|
|
893
|
+
...context.dialog ? { [DIALOG_KEY_HEADER]: context.dialog.key } : {},
|
|
894
|
+
...context.dialog ? { [DIALOG_REDIRECT_HEADER]: context.dialog.redirectUrl ?? "" } : {},
|
|
895
|
+
...utils.when(options.only !== void 0 || options.except !== void 0, {
|
|
896
|
+
[PARTIAL_COMPONENT_HEADER]: context.view.component,
|
|
897
|
+
...utils.when(options.only, { [ONLY_DATA_HEADER]: JSON.stringify(options.only) }, {}),
|
|
898
|
+
...utils.when(options.except, { [EXCEPT_DATA_HEADER]: JSON.stringify(options.except) }, {})
|
|
899
|
+
}, {}),
|
|
900
|
+
...utils.when(options.errorBag, { [ERROR_BAG_HEADER]: options.errorBag }, {}),
|
|
901
|
+
...utils.when(context.version, { [VERSION_HEADER]: context.version }, {}),
|
|
902
|
+
[HYBRIDLY_HEADER]: true,
|
|
903
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
904
|
+
"Accept": "text/html, application/xhtml+xml"
|
|
905
|
+
},
|
|
906
|
+
validateStatus: () => true,
|
|
907
|
+
onUploadProgress: async (event) => {
|
|
908
|
+
await runHooks("progress", options.hooks, {
|
|
909
|
+
event,
|
|
910
|
+
percentage: Math.round(event.loaded / (event.total ?? 0) * 100)
|
|
911
|
+
}, context);
|
|
912
|
+
}
|
|
913
|
+
});
|
|
845
914
|
}
|
|
846
915
|
async function initializeRouter() {
|
|
847
916
|
const context = getRouterContext();
|
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,10 @@ interface Hooks extends RequestHooks {
|
|
|
70
70
|
* Called when a component has been navigated to.
|
|
71
71
|
*/
|
|
72
72
|
navigated: (options: NavigationOptions, context: InternalRouterContext) => MaybePromise<any>;
|
|
73
|
+
/**
|
|
74
|
+
* Called when a component has been navigated to and was mounted by the adapter.
|
|
75
|
+
*/
|
|
76
|
+
mounted: (context: InternalRouterContext) => MaybePromise<any>;
|
|
73
77
|
}
|
|
74
78
|
interface HookOptions {
|
|
75
79
|
/** Executes the hook only once. */
|
|
@@ -228,6 +232,8 @@ interface Router {
|
|
|
228
232
|
external: (url: UrlResolvable, data?: HybridRequestOptions['data']) => void;
|
|
229
233
|
/** Navigates to the given URL without a server round-trip. */
|
|
230
234
|
local: (url: UrlResolvable, options: ComponentNavigationOptions) => Promise<void>;
|
|
235
|
+
/** Preloads the given URL. The next time this URL is navigated to, it will be loaded from the cache. */
|
|
236
|
+
preload: (url: UrlResolvable, options?: Omit<HybridRequestOptions, 'method' | 'url'>) => Promise<boolean>;
|
|
231
237
|
/** Access the dialog router. */
|
|
232
238
|
dialog: DialogRouter;
|
|
233
239
|
/** Access the history state. */
|
|
@@ -368,6 +374,8 @@ interface InternalRouterContext {
|
|
|
368
374
|
routing?: RoutingConfiguration;
|
|
369
375
|
/** Whether to display response error modals. */
|
|
370
376
|
responseErrorModals?: boolean;
|
|
377
|
+
/** Cache of preload requests. */
|
|
378
|
+
preloadCache: Map<string, AxiosResponse>;
|
|
371
379
|
}
|
|
372
380
|
/** Router context. */
|
|
373
381
|
type RouterContext = Readonly<InternalRouterContext>;
|
|
@@ -382,7 +390,7 @@ interface Adapter {
|
|
|
382
390
|
/** Called when a dialog is closed. */
|
|
383
391
|
onDialogClose?: (context: InternalRouterContext) => void;
|
|
384
392
|
/** Called when Hybridly is waiting for a component to be mounted. The given callback should be executed after the view component is mounted. */
|
|
385
|
-
|
|
393
|
+
executeOnMounted: (callback: Function) => void;
|
|
386
394
|
}
|
|
387
395
|
interface ResolvedAdapter extends Adapter {
|
|
388
396
|
updateRoutingConfiguration: (routing?: RoutingConfiguration) => void;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { debug, merge, removeTrailingSlash, debounce, random, hasFiles, objectToFormData,
|
|
1
|
+
import { debug, merge, removeTrailingSlash, debounce, random, hasFiles, objectToFormData, match, showResponseErrorModal, when } from '@hybridly/utils';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { stringify, parse } from 'superjson';
|
|
4
4
|
import qs from 'qs';
|
|
@@ -151,7 +151,7 @@ async function restoreScrollPositions() {
|
|
|
151
151
|
debug.scroll("No region found to restore.");
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
|
-
context.adapter.
|
|
154
|
+
context.adapter.executeOnMounted(() => {
|
|
155
155
|
debug.scroll(`Restoring ${regions.length}/${context.scrollRegions.length} region(s).`);
|
|
156
156
|
regions.forEach((el, i) => el.scrollTo({
|
|
157
157
|
top: context.scrollRegions.at(i)?.top ?? el.scrollTop,
|
|
@@ -491,6 +491,7 @@ async function initializeContext(options) {
|
|
|
491
491
|
plugins: options.plugins ?? [],
|
|
492
492
|
axios: options.axios ?? axios.create(),
|
|
493
493
|
routing: options.routing,
|
|
494
|
+
preloadCache: /* @__PURE__ */ new Map(),
|
|
494
495
|
hooks: {},
|
|
495
496
|
memo: {}
|
|
496
497
|
};
|
|
@@ -581,6 +582,52 @@ async function closeDialog(options) {
|
|
|
581
582
|
});
|
|
582
583
|
}
|
|
583
584
|
|
|
585
|
+
function isPreloaded(targetUrl) {
|
|
586
|
+
const context = getInternalRouterContext();
|
|
587
|
+
return context.preloadCache.has(targetUrl.toString()) ?? false;
|
|
588
|
+
}
|
|
589
|
+
function getPreloadedRequest(targetUrl) {
|
|
590
|
+
const context = getInternalRouterContext();
|
|
591
|
+
return context.preloadCache.get(targetUrl.toString());
|
|
592
|
+
}
|
|
593
|
+
function storePreloadRequest(targetUrl, response) {
|
|
594
|
+
const context = getInternalRouterContext();
|
|
595
|
+
context.preloadCache.set(targetUrl.toString(), response);
|
|
596
|
+
}
|
|
597
|
+
function discardPreloadedRequest(targetUrl) {
|
|
598
|
+
const context = getInternalRouterContext();
|
|
599
|
+
return context.preloadCache.delete(targetUrl.toString());
|
|
600
|
+
}
|
|
601
|
+
async function performPreloadRequest(options) {
|
|
602
|
+
const context = getRouterContext();
|
|
603
|
+
const url = makeUrl(options.url ?? context.url);
|
|
604
|
+
if (isPreloaded(url)) {
|
|
605
|
+
debug.router("This request is already preloaded.");
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
if (context.pendingNavigation) {
|
|
609
|
+
debug.router("A navigation is pending, preload aborted.");
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
if (options.method !== "GET") {
|
|
613
|
+
debug.router("Cannot preload non-GET requests.");
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
debug.router(`Preloading response for [${url.toString()}]`);
|
|
617
|
+
try {
|
|
618
|
+
const response = await performHybridRequest(url, options);
|
|
619
|
+
if (!isHybridResponse(response)) {
|
|
620
|
+
debug.router("Preload result was invalid.");
|
|
621
|
+
return false;
|
|
622
|
+
}
|
|
623
|
+
storePreloadRequest(url, response);
|
|
624
|
+
return true;
|
|
625
|
+
} catch (error) {
|
|
626
|
+
debug.router("Preloading failed.");
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
584
631
|
const router = {
|
|
585
632
|
abort: async () => getRouterContext().pendingNavigation?.controller.abort(),
|
|
586
633
|
active: () => !!getRouterContext().pendingNavigation,
|
|
@@ -592,6 +639,7 @@ const router = {
|
|
|
592
639
|
patch: async (url, options = {}) => await performHybridNavigation({ preserveState: true, ...options, url, method: "PATCH" }),
|
|
593
640
|
delete: async (url, options = {}) => await performHybridNavigation({ preserveState: true, ...options, url, method: "DELETE" }),
|
|
594
641
|
local: async (url, options = {}) => await performLocalNavigation(url, options),
|
|
642
|
+
preload: async (url, options = {}) => await performPreloadRequest({ ...options, url, method: "GET" }),
|
|
595
643
|
external: (url, data = {}) => navigateToExternalUrl(url, data),
|
|
596
644
|
to: async (name, parameters, options) => {
|
|
597
645
|
const url = generateRouteFromName(name, parameters);
|
|
@@ -623,11 +671,6 @@ async function performHybridNavigation(options) {
|
|
|
623
671
|
if ((hasFiles(options.data) || options.useFormData) && !(options.data instanceof FormData)) {
|
|
624
672
|
options.data = objectToFormData(options.data);
|
|
625
673
|
debug.router("Converted data to FormData.", options.data);
|
|
626
|
-
if (options.method && ["PUT", "PATCH", "DELETE"].includes(options.method) && options.spoof !== false) {
|
|
627
|
-
debug.router(`Automatically spoofing method ${options.method}.`);
|
|
628
|
-
options.data.append("_method", options.method);
|
|
629
|
-
options.method = "POST";
|
|
630
|
-
}
|
|
631
674
|
}
|
|
632
675
|
if (!(options.data instanceof FormData) && options.method === "GET" && Object.keys(options.data ?? {}).length) {
|
|
633
676
|
debug.router("Transforming data to query parameters.", options.data);
|
|
@@ -636,6 +679,19 @@ async function performHybridNavigation(options) {
|
|
|
636
679
|
});
|
|
637
680
|
options.data = {};
|
|
638
681
|
}
|
|
682
|
+
if (["PUT", "PATCH", "DELETE"].includes(options.method) && options.spoof !== false) {
|
|
683
|
+
debug.router(`Automatically spoofing method ${options.method}.`);
|
|
684
|
+
if (options.data instanceof FormData) {
|
|
685
|
+
options.data.append("_method", options.method);
|
|
686
|
+
} else if (Object.keys(options.data ?? {}).length) {
|
|
687
|
+
Object.assign(options.data, { _method: options.method });
|
|
688
|
+
} else if (typeof options.data === "undefined") {
|
|
689
|
+
options.data = { _method: options.method };
|
|
690
|
+
} else {
|
|
691
|
+
debug.router("Could not spoof method because body type is not supported.", options.data);
|
|
692
|
+
}
|
|
693
|
+
options.method = "POST";
|
|
694
|
+
}
|
|
639
695
|
if (!await runHooks("before", options.hooks, options, context)) {
|
|
640
696
|
debug.router('"before" event returned false, aborting the navigation.');
|
|
641
697
|
throw new NavigationCancelledError('The navigation was cancelled by the "before" event.');
|
|
@@ -661,35 +717,7 @@ async function performHybridNavigation(options) {
|
|
|
661
717
|
});
|
|
662
718
|
await runHooks("start", options.hooks, context);
|
|
663
719
|
debug.router("Making request with axios.");
|
|
664
|
-
const response = await
|
|
665
|
-
url: targetUrl.toString(),
|
|
666
|
-
method: options.method,
|
|
667
|
-
data: options.method === "GET" ? {} : options.data,
|
|
668
|
-
params: options.method === "GET" ? options.data : {},
|
|
669
|
-
signal: abortController.signal,
|
|
670
|
-
headers: {
|
|
671
|
-
...options.headers,
|
|
672
|
-
...context.dialog ? { [DIALOG_KEY_HEADER]: context.dialog.key } : {},
|
|
673
|
-
...context.dialog ? { [DIALOG_REDIRECT_HEADER]: context.dialog.redirectUrl ?? "" } : {},
|
|
674
|
-
...when(options.only !== void 0 || options.except !== void 0, {
|
|
675
|
-
[PARTIAL_COMPONENT_HEADER]: context.view.component,
|
|
676
|
-
...when(options.only, { [ONLY_DATA_HEADER]: JSON.stringify(options.only) }, {}),
|
|
677
|
-
...when(options.except, { [EXCEPT_DATA_HEADER]: JSON.stringify(options.except) }, {})
|
|
678
|
-
}, {}),
|
|
679
|
-
...when(options.errorBag, { [ERROR_BAG_HEADER]: options.errorBag }, {}),
|
|
680
|
-
...when(context.version, { [VERSION_HEADER]: context.version }, {}),
|
|
681
|
-
[HYBRIDLY_HEADER]: true,
|
|
682
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
683
|
-
"Accept": "text/html, application/xhtml+xml"
|
|
684
|
-
},
|
|
685
|
-
validateStatus: () => true,
|
|
686
|
-
onUploadProgress: async (event) => {
|
|
687
|
-
await runHooks("progress", options.hooks, {
|
|
688
|
-
event,
|
|
689
|
-
percentage: Math.round(event.loaded / (event.total ?? 0) * 100)
|
|
690
|
-
}, context);
|
|
691
|
-
}
|
|
692
|
-
});
|
|
720
|
+
const response = await performHybridRequest(targetUrl, options, abortController);
|
|
693
721
|
await runHooks("data", options.hooks, response, context);
|
|
694
722
|
if (isExternalResponse(response)) {
|
|
695
723
|
debug.router("The response is explicitely external.");
|
|
@@ -833,6 +861,47 @@ async function navigate(options) {
|
|
|
833
861
|
resetScrollPositions();
|
|
834
862
|
}
|
|
835
863
|
await runHooks("navigated", {}, options, context);
|
|
864
|
+
context.adapter.executeOnMounted(() => {
|
|
865
|
+
runHooks("mounted", {}, context);
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
async function performHybridRequest(targetUrl, options, abortController) {
|
|
869
|
+
const context = getInternalRouterContext();
|
|
870
|
+
const preloaded = getPreloadedRequest(targetUrl);
|
|
871
|
+
if (preloaded) {
|
|
872
|
+
debug.router(`Found a pre-loaded request for [${targetUrl}]`);
|
|
873
|
+
discardPreloadedRequest(targetUrl);
|
|
874
|
+
return preloaded;
|
|
875
|
+
}
|
|
876
|
+
return await context.axios.request({
|
|
877
|
+
url: targetUrl.toString(),
|
|
878
|
+
method: options.method,
|
|
879
|
+
data: options.method === "GET" ? {} : options.data,
|
|
880
|
+
params: options.method === "GET" ? options.data : {},
|
|
881
|
+
signal: abortController?.signal,
|
|
882
|
+
headers: {
|
|
883
|
+
...options.headers,
|
|
884
|
+
...context.dialog ? { [DIALOG_KEY_HEADER]: context.dialog.key } : {},
|
|
885
|
+
...context.dialog ? { [DIALOG_REDIRECT_HEADER]: context.dialog.redirectUrl ?? "" } : {},
|
|
886
|
+
...when(options.only !== void 0 || options.except !== void 0, {
|
|
887
|
+
[PARTIAL_COMPONENT_HEADER]: context.view.component,
|
|
888
|
+
...when(options.only, { [ONLY_DATA_HEADER]: JSON.stringify(options.only) }, {}),
|
|
889
|
+
...when(options.except, { [EXCEPT_DATA_HEADER]: JSON.stringify(options.except) }, {})
|
|
890
|
+
}, {}),
|
|
891
|
+
...when(options.errorBag, { [ERROR_BAG_HEADER]: options.errorBag }, {}),
|
|
892
|
+
...when(context.version, { [VERSION_HEADER]: context.version }, {}),
|
|
893
|
+
[HYBRIDLY_HEADER]: true,
|
|
894
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
895
|
+
"Accept": "text/html, application/xhtml+xml"
|
|
896
|
+
},
|
|
897
|
+
validateStatus: () => true,
|
|
898
|
+
onUploadProgress: async (event) => {
|
|
899
|
+
await runHooks("progress", options.hooks, {
|
|
900
|
+
event,
|
|
901
|
+
percentage: Math.round(event.loaded / (event.total ?? 0) * 100)
|
|
902
|
+
}, context);
|
|
903
|
+
}
|
|
904
|
+
});
|
|
836
905
|
}
|
|
837
906
|
async function initializeRouter() {
|
|
838
907
|
const context = getRouterContext();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hybridly/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Core functionality of Hybridly",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hybridly",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"qs": "^6.11.2",
|
|
40
40
|
"superjson": "^1.12.3",
|
|
41
|
-
"@hybridly/utils": "0.4.
|
|
41
|
+
"@hybridly/utils": "0.4.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"defu": "^6.1.2"
|