@webiny/app 6.1.0 → 6.2.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/exports/admin.d.ts +1 -0
- package/exports/admin.js +1 -0
- package/exports/admin.js.map +1 -1
- package/features/eventPublisher/feature.d.ts +3 -1
- package/features/eventPublisher/feature.js +5 -0
- package/features/eventPublisher/feature.js.map +1 -1
- package/features/graphqlClient/BatchingGraphQLClient.d.ts +1 -3
- package/features/graphqlClient/BatchingGraphQLClient.js +13 -14
- package/features/graphqlClient/BatchingGraphQLClient.js.map +1 -1
- package/features/graphqlClient/FetchGraphQLClient.d.ts +0 -3
- package/features/graphqlClient/FetchGraphQLClient.js +4 -8
- package/features/graphqlClient/FetchGraphQLClient.js.map +1 -1
- package/features/graphqlClient/RequestValue.d.ts +1 -0
- package/features/graphqlClient/RequestValue.js +3 -0
- package/features/graphqlClient/RequestValue.js.map +1 -1
- package/features/graphqlClient/__tests__/GraphQLClient.test.js +20 -0
- package/features/graphqlClient/__tests__/GraphQLClient.test.js.map +1 -1
- package/features/graphqlClient/abstractions.d.ts +1 -0
- package/features/graphqlClient/abstractions.js.map +1 -1
- package/features/mainGraphQLClient/MainGraphQLClient.d.ts +11 -0
- package/features/mainGraphQLClient/MainGraphQLClient.js +23 -0
- package/features/mainGraphQLClient/MainGraphQLClient.js.map +1 -0
- package/features/mainGraphQLClient/abstractions.d.ts +17 -0
- package/features/mainGraphQLClient/abstractions.js +4 -0
- package/features/mainGraphQLClient/abstractions.js.map +1 -0
- package/features/mainGraphQLClient/feature.d.ts +3 -0
- package/features/mainGraphQLClient/feature.js +16 -0
- package/features/mainGraphQLClient/feature.js.map +1 -0
- package/features/mainGraphQLClient/index.d.ts +1 -0
- package/features/mainGraphQLClient/index.js +3 -0
- package/features/mainGraphQLClient/index.js.map +1 -0
- package/features/router/HistoryRouterGateway.d.ts +5 -3
- package/features/router/HistoryRouterGateway.js +49 -32
- package/features/router/HistoryRouterGateway.js.map +1 -1
- package/features/router/RouterRepository.d.ts +4 -4
- package/features/router/RouterRepository.js +22 -34
- package/features/router/RouterRepository.js.map +1 -1
- package/features/router/abstractions.d.ts +3 -6
- package/features/router/abstractions.js.map +1 -1
- package/features/router/index.d.ts +1 -1
- package/features/router/index.js.map +1 -1
- package/package.json +15 -15
- package/shared/di/useFeature.js +2 -12
- package/shared/di/useFeature.js.map +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createImplementation } from "@webiny/di";
|
|
2
|
+
import { MainGraphQLClient } from "./abstractions.js";
|
|
3
|
+
import { GraphQLClient } from "../graphqlClient/abstractions.js";
|
|
4
|
+
import { EnvConfig } from "../envConfig/index.js";
|
|
5
|
+
class MainGraphQLClientImpl {
|
|
6
|
+
constructor(envConfig, client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
this.endpoint = envConfig.get("graphqlApiUrl");
|
|
9
|
+
}
|
|
10
|
+
async execute(params) {
|
|
11
|
+
return this.client.execute({
|
|
12
|
+
endpoint: this.endpoint,
|
|
13
|
+
...params
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export const DefaultMainGraphQLClient = createImplementation({
|
|
18
|
+
abstraction: MainGraphQLClient,
|
|
19
|
+
implementation: MainGraphQLClientImpl,
|
|
20
|
+
dependencies: [EnvConfig, GraphQLClient]
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=MainGraphQLClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createImplementation","MainGraphQLClient","GraphQLClient","EnvConfig","MainGraphQLClientImpl","constructor","envConfig","client","endpoint","get","execute","params","DefaultMainGraphQLClient","abstraction","implementation","dependencies"],"sources":["MainGraphQLClient.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/di\";\nimport { MainGraphQLClient } from \"./abstractions.js\";\nimport { GraphQLClient } from \"~/features/graphqlClient/abstractions.js\";\nimport { EnvConfig } from \"~/features/envConfig/index.js\";\n\nclass MainGraphQLClientImpl implements MainGraphQLClient.Interface {\n private readonly endpoint: string;\n\n constructor(\n envConfig: EnvConfig.Interface,\n private client: GraphQLClient.Interface\n ) {\n this.endpoint = envConfig.get(\"graphqlApiUrl\");\n }\n\n async execute<TResult = any, TVariables = any>(\n params: MainGraphQLClient.Request<TVariables>\n ): Promise<TResult> {\n return this.client.execute({ endpoint: this.endpoint, ...params });\n }\n}\n\nexport const DefaultMainGraphQLClient = createImplementation({\n abstraction: MainGraphQLClient,\n implementation: MainGraphQLClientImpl,\n dependencies: [EnvConfig, GraphQLClient]\n});\n"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,YAAY;AACjD,SAASC,iBAAiB;AAC1B,SAASC,aAAa;AACtB,SAASC,SAAS;AAElB,MAAMC,qBAAqB,CAAwC;EAG/DC,WAAWA,CACPC,SAA8B,EACtBC,MAA+B,EACzC;IAAA,KADUA,MAA+B,GAA/BA,MAA+B;IAEvC,IAAI,CAACC,QAAQ,GAAGF,SAAS,CAACG,GAAG,CAAC,eAAe,CAAC;EAClD;EAEA,MAAMC,OAAOA,CACTC,MAA6C,EAC7B;IAChB,OAAO,IAAI,CAACJ,MAAM,CAACG,OAAO,CAAC;MAAEF,QAAQ,EAAE,IAAI,CAACA,QAAQ;MAAE,GAAGG;IAAO,CAAC,CAAC;EACtE;AACJ;AAEA,OAAO,MAAMC,wBAAwB,GAAGZ,oBAAoB,CAAC;EACzDa,WAAW,EAAEZ,iBAAiB;EAC9Ba,cAAc,EAAEV,qBAAqB;EACrCW,YAAY,EAAE,CAACZ,SAAS,EAAED,aAAa;AAC3C,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DocumentNode } from "graphql";
|
|
2
|
+
type IHeaders = Record<string, string | number | undefined>;
|
|
3
|
+
type MainGraphQLRequest<TVariables = any> = {
|
|
4
|
+
query: DocumentNode | string;
|
|
5
|
+
variables?: TVariables;
|
|
6
|
+
headers?: IHeaders;
|
|
7
|
+
};
|
|
8
|
+
export interface IMainGraphQLClient {
|
|
9
|
+
execute<TResult = any, TVariables = any>(params: MainGraphQLRequest<TVariables>): Promise<TResult>;
|
|
10
|
+
}
|
|
11
|
+
export declare const MainGraphQLClient: import("@webiny/di").Abstraction<IMainGraphQLClient>;
|
|
12
|
+
export declare namespace MainGraphQLClient {
|
|
13
|
+
type Headers = IHeaders;
|
|
14
|
+
type Interface = IMainGraphQLClient;
|
|
15
|
+
type Request<TVariables = any> = MainGraphQLRequest<TVariables>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAbstraction","MainGraphQLClient"],"sources":["abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { DocumentNode } from \"graphql\";\n\ntype IHeaders = Record<string, string | number | undefined>;\n\ntype MainGraphQLRequest<TVariables = any> = {\n query: DocumentNode | string;\n variables?: TVariables;\n headers?: IHeaders;\n};\n\nexport interface IMainGraphQLClient {\n execute<TResult = any, TVariables = any>(\n params: MainGraphQLRequest<TVariables>\n ): Promise<TResult>;\n}\n\nexport const MainGraphQLClient = createAbstraction<IMainGraphQLClient>(\"MainGraphQLClient\");\n\nexport namespace MainGraphQLClient {\n export type Headers = IHeaders;\n export type Interface = IMainGraphQLClient;\n export type Request<TVariables = any> = MainGraphQLRequest<TVariables>;\n}\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,uBAAuB;AAiBzD,OAAO,MAAMC,iBAAiB,GAAGD,iBAAiB,CAAqB,mBAAmB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MainGraphQLClient } from "./abstractions.js";
|
|
2
|
+
import { DefaultMainGraphQLClient } from "./MainGraphQLClient.js";
|
|
3
|
+
import { createFeature } from "../../shared/di/createFeature.js";
|
|
4
|
+
export const MainGraphQLClientFeature = createFeature({
|
|
5
|
+
name: "MainGraphQLClient",
|
|
6
|
+
register(container) {
|
|
7
|
+
container.register(DefaultMainGraphQLClient).inSingletonScope();
|
|
8
|
+
},
|
|
9
|
+
resolve(container) {
|
|
10
|
+
return {
|
|
11
|
+
client: container.resolve(MainGraphQLClient)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MainGraphQLClient","DefaultMainGraphQLClient","createFeature","MainGraphQLClientFeature","name","register","container","inSingletonScope","resolve","client"],"sources":["feature.ts"],"sourcesContent":["import { MainGraphQLClient } from \"./abstractions.js\";\nimport { DefaultMainGraphQLClient } from \"./MainGraphQLClient.js\";\nimport { createFeature } from \"~/shared/di/createFeature.js\";\n\nexport const MainGraphQLClientFeature = createFeature({\n name: \"MainGraphQLClient\",\n register(container) {\n container.register(DefaultMainGraphQLClient).inSingletonScope();\n },\n resolve(container) {\n return {\n client: container.resolve(MainGraphQLClient)\n };\n }\n});\n"],"mappings":"AAAA,SAASA,iBAAiB;AAC1B,SAASC,wBAAwB;AACjC,SAASC,aAAa;AAEtB,OAAO,MAAMC,wBAAwB,GAAGD,aAAa,CAAC;EAClDE,IAAI,EAAE,mBAAmB;EACzBC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACD,QAAQ,CAACJ,wBAAwB,CAAC,CAACM,gBAAgB,CAAC,CAAC;EACnE,CAAC;EACDC,OAAOA,CAACF,SAAS,EAAE;IACf,OAAO;MACHG,MAAM,EAAEH,SAAS,CAACE,OAAO,CAACR,iBAAiB;IAC/C,CAAC;EACL;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MainGraphQLClient } from "./abstractions.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MainGraphQLClient"],"sources":["index.ts"],"sourcesContent":["export { MainGraphQLClient } from \"./abstractions.js\";\n"],"mappings":"AAAA,SAASA,iBAAiB","ignoreList":[]}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
2
|
import type { History } from "history";
|
|
3
|
-
import type { RouteDefinition,
|
|
3
|
+
import type { RouteDefinition, RouteTransitionGuardConfig, GuardDisposer } from "./abstractions.js";
|
|
4
4
|
import { RouterGateway } from "./abstractions.js";
|
|
5
5
|
export declare class HistoryRouterGateway implements RouterGateway.Interface {
|
|
6
6
|
private readonly history;
|
|
7
7
|
private readonly router;
|
|
8
8
|
private stopListening;
|
|
9
9
|
private unblock;
|
|
10
|
-
private
|
|
10
|
+
private guards;
|
|
11
11
|
constructor(history: History, baseUrl: string);
|
|
12
|
-
|
|
12
|
+
addGuard(config: RouteTransitionGuardConfig): GuardDisposer;
|
|
13
13
|
goToRoute(name: string, params: z.ZodTypeAny): void;
|
|
14
14
|
setRoutes(routes: RouteDefinition[]): void;
|
|
15
15
|
destroy(): void;
|
|
16
16
|
pushState(url: string): void;
|
|
17
17
|
private resolvePathname;
|
|
18
|
+
private findBlockingGuard;
|
|
18
19
|
private installBlocker;
|
|
20
|
+
private removeBlocker;
|
|
19
21
|
private removeBlockerAndRetry;
|
|
20
22
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RouteUrl } from "./RouteUrl.js";
|
|
2
2
|
import { Router } from "./Router.js";
|
|
3
3
|
export class HistoryRouterGateway {
|
|
4
|
+
guards = new Set();
|
|
4
5
|
constructor(history, baseUrl) {
|
|
5
6
|
this.history = history;
|
|
6
7
|
this.router = new Router(baseUrl);
|
|
@@ -11,9 +12,18 @@ export class HistoryRouterGateway {
|
|
|
11
12
|
this.resolvePathname(location.pathname, queryParams);
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
15
|
+
addGuard(config) {
|
|
16
|
+
const hadGuards = this.guards.size > 0;
|
|
17
|
+
this.guards.add(config);
|
|
18
|
+
if (!hadGuards) {
|
|
19
|
+
this.installBlocker();
|
|
20
|
+
}
|
|
21
|
+
return () => {
|
|
22
|
+
this.guards.delete(config);
|
|
23
|
+
if (this.guards.size === 0) {
|
|
24
|
+
this.removeBlocker();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
17
27
|
}
|
|
18
28
|
goToRoute(name, params) {
|
|
19
29
|
const route = this.router.findRoute(name);
|
|
@@ -32,11 +42,8 @@ export class HistoryRouterGateway {
|
|
|
32
42
|
}
|
|
33
43
|
destroy() {
|
|
34
44
|
this.stopListening();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.unblock = undefined;
|
|
38
|
-
}
|
|
39
|
-
this.onRouteExitCb = undefined;
|
|
45
|
+
this.removeBlocker();
|
|
46
|
+
this.guards.clear();
|
|
40
47
|
}
|
|
41
48
|
pushState(url) {
|
|
42
49
|
this.history.push(url);
|
|
@@ -52,47 +59,57 @@ export class HistoryRouterGateway {
|
|
|
52
59
|
} = result;
|
|
53
60
|
onMatch(matchedRoute);
|
|
54
61
|
}
|
|
62
|
+
findBlockingGuard() {
|
|
63
|
+
for (const config of this.guards) {
|
|
64
|
+
if (config.guard()) {
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
55
70
|
installBlocker() {
|
|
56
71
|
if (this.unblock) {
|
|
57
72
|
this.unblock();
|
|
58
73
|
}
|
|
59
74
|
this.unblock = this.history.block(tx => {
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
const blockingGuard = this.findBlockingGuard();
|
|
76
|
+
if (blockingGuard) {
|
|
77
|
+
let resolved = false;
|
|
78
|
+
blockingGuard.onBlocked({
|
|
79
|
+
continue: () => {
|
|
80
|
+
if (!resolved) {
|
|
81
|
+
resolved = true;
|
|
82
|
+
this.removeBlockerAndRetry(tx);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
cancel: () => {
|
|
69
86
|
resolved = true;
|
|
70
|
-
|
|
87
|
+
// Do nothing — history v5 already reverted the URL.
|
|
71
88
|
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
});
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
this.removeBlockerAndRetry(tx);
|
|
92
|
+
}
|
|
78
93
|
});
|
|
79
94
|
}
|
|
80
|
-
|
|
81
|
-
// We must remove the blocker before retrying because history v5's
|
|
82
|
-
// allowTx() always returns false when any blocker is registered.
|
|
95
|
+
removeBlocker() {
|
|
83
96
|
if (this.unblock) {
|
|
84
97
|
this.unblock();
|
|
85
98
|
this.unblock = undefined;
|
|
86
99
|
}
|
|
100
|
+
}
|
|
101
|
+
removeBlockerAndRetry(tx) {
|
|
102
|
+
// We must remove the blocker before retrying because history v5's
|
|
103
|
+
// allowTx() always returns false when any blocker is registered.
|
|
104
|
+
this.removeBlocker();
|
|
87
105
|
|
|
88
106
|
// Listen for the next navigation to complete, then reinstall the
|
|
89
|
-
// blocker
|
|
90
|
-
// reinstallation fires before an async popstate (back/forward)
|
|
91
|
-
// has settled, causing the blocker to catch its own retried
|
|
92
|
-
// navigation in an infinite loop.
|
|
107
|
+
// blocker only if guards are still active.
|
|
93
108
|
const unlisten = this.history.listen(() => {
|
|
94
109
|
unlisten();
|
|
95
|
-
this.
|
|
110
|
+
if (this.guards.size > 0) {
|
|
111
|
+
this.installBlocker();
|
|
112
|
+
}
|
|
96
113
|
});
|
|
97
114
|
tx.retry();
|
|
98
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RouteUrl","Router","HistoryRouterGateway","constructor","history","baseUrl","router","stopListening","listen","location","queryParams","Object","fromEntries","URLSearchParams","search","entries","resolvePathname","pathname","
|
|
1
|
+
{"version":3,"names":["RouteUrl","Router","HistoryRouterGateway","guards","Set","constructor","history","baseUrl","router","stopListening","listen","location","queryParams","Object","fromEntries","URLSearchParams","search","entries","resolvePathname","pathname","addGuard","config","hadGuards","size","add","installBlocker","delete","removeBlocker","goToRoute","name","params","route","findRoute","console","warn","getBaseUrl","push","fromPattern","path","setRoutes","routes","currentPathname","destroy","clear","pushState","url","result","resolve","matchedRoute","onMatch","findBlockingGuard","guard","undefined","unblock","block","tx","blockingGuard","resolved","onBlocked","continue","removeBlockerAndRetry","cancel","unlisten","retry"],"sources":["HistoryRouterGateway.ts"],"sourcesContent":["import type { z } from \"zod\";\nimport type { History } from \"history\";\nimport type { RouteDefinition, RouteTransitionGuardConfig, GuardDisposer } from \"./abstractions.js\";\nimport { RouterGateway } from \"./abstractions.js\";\nimport { RouteUrl } from \"./RouteUrl.js\";\nimport { Router } from \"./Router.js\";\n\nexport class HistoryRouterGateway implements RouterGateway.Interface {\n private readonly history: History;\n private readonly router: Router;\n private stopListening: () => void;\n private unblock: (() => void) | undefined;\n private guards = new Set<RouteTransitionGuardConfig>();\n\n constructor(history: History, baseUrl: string) {\n this.history = history;\n this.router = new Router(baseUrl);\n\n this.stopListening = history.listen(async ({ location }) => {\n const queryParams = Object.fromEntries(new URLSearchParams(location.search).entries());\n this.resolvePathname(location.pathname, queryParams);\n });\n }\n\n addGuard(config: RouteTransitionGuardConfig): GuardDisposer {\n const hadGuards = this.guards.size > 0;\n this.guards.add(config);\n if (!hadGuards) {\n this.installBlocker();\n }\n return () => {\n this.guards.delete(config);\n if (this.guards.size === 0) {\n this.removeBlocker();\n }\n };\n }\n\n goToRoute(name: string, params: z.ZodTypeAny): void {\n const route = this.router.findRoute(name);\n if (!route) {\n console.warn(`Route \"${name}\" not found.`);\n return;\n }\n\n const baseUrl = this.router.getBaseUrl();\n this.history.push(RouteUrl.fromPattern(route.path, params, baseUrl));\n }\n\n setRoutes(routes: RouteDefinition[]) {\n this.router.setRoutes(routes);\n\n const queryParams = Object.fromEntries(\n new URLSearchParams(this.history.location.search).entries()\n );\n const currentPathname = this.history.location.pathname;\n this.resolvePathname(currentPathname, queryParams);\n }\n\n destroy(): void {\n this.stopListening();\n this.removeBlocker();\n this.guards.clear();\n }\n\n pushState(url: string): void {\n this.history.push(url);\n }\n\n private async resolvePathname(pathname: string, queryParams?: Record<string, unknown>) {\n const result = this.router.resolve(pathname, queryParams);\n if (!result) {\n return;\n }\n\n const { matchedRoute, onMatch } = result;\n\n onMatch(matchedRoute);\n }\n\n private findBlockingGuard(): RouteTransitionGuardConfig | undefined {\n for (const config of this.guards) {\n if (config.guard()) {\n return config;\n }\n }\n return undefined;\n }\n\n private installBlocker(): void {\n if (this.unblock) {\n this.unblock();\n }\n\n this.unblock = this.history.block(tx => {\n const blockingGuard = this.findBlockingGuard();\n if (blockingGuard) {\n let resolved = false;\n\n blockingGuard.onBlocked({\n continue: () => {\n if (!resolved) {\n resolved = true;\n this.removeBlockerAndRetry(tx);\n }\n },\n cancel: () => {\n resolved = true;\n // Do nothing — history v5 already reverted the URL.\n }\n });\n } else {\n this.removeBlockerAndRetry(tx);\n }\n });\n }\n\n private removeBlocker(): void {\n if (this.unblock) {\n this.unblock();\n this.unblock = undefined;\n }\n }\n\n private removeBlockerAndRetry(tx: { retry: () => void }): void {\n // We must remove the blocker before retrying because history v5's\n // allowTx() always returns false when any blocker is registered.\n this.removeBlocker();\n\n // Listen for the next navigation to complete, then reinstall the\n // blocker only if guards are still active.\n const unlisten = this.history.listen(() => {\n unlisten();\n if (this.guards.size > 0) {\n this.installBlocker();\n }\n });\n\n tx.retry();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,9 +5,9 @@ declare class RouterRepositoryImpl implements Abstractions.RouterRepository.Inte
|
|
|
5
5
|
private gateway;
|
|
6
6
|
private currentRoute;
|
|
7
7
|
private routes;
|
|
8
|
-
private guards;
|
|
9
8
|
private pendingTransition;
|
|
10
9
|
private forceUnblocked;
|
|
10
|
+
private guardDisposers;
|
|
11
11
|
constructor(gateway: Abstractions.RouterGateway.Interface);
|
|
12
12
|
getMatchedRoute(): MatchedRoute<Record<string, any>> | undefined;
|
|
13
13
|
getCurrentRoute(): Route<any> | undefined;
|
|
@@ -20,11 +20,11 @@ declare class RouterRepositoryImpl implements Abstractions.RouterRepository.Inte
|
|
|
20
20
|
confirmTransition(): void;
|
|
21
21
|
cancelTransition(): void;
|
|
22
22
|
destroy(): void;
|
|
23
|
-
private installBlocker;
|
|
24
|
-
private findBlockingGuard;
|
|
25
23
|
private routeWithAction;
|
|
26
24
|
private transitionToRoute;
|
|
27
25
|
private getRouteByName;
|
|
28
26
|
}
|
|
29
|
-
export declare const RouterRepository:
|
|
27
|
+
export declare const RouterRepository: typeof RouterRepositoryImpl & {
|
|
28
|
+
__abstraction: import("@webiny/di").Abstraction<Abstractions.IRouterRepository>;
|
|
29
|
+
};
|
|
30
30
|
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { makeAutoObservable, runInAction } from "mobx";
|
|
2
2
|
import * as Abstractions from "./abstractions.js";
|
|
3
|
-
import { createImplementation } from "@webiny/di";
|
|
4
3
|
import { RouteUrl } from "./RouteUrl.js";
|
|
5
4
|
const INIT_ROUTE = {
|
|
6
5
|
name: "__init__",
|
|
@@ -11,13 +10,11 @@ const INIT_ROUTE = {
|
|
|
11
10
|
class RouterRepositoryImpl {
|
|
12
11
|
currentRoute = INIT_ROUTE;
|
|
13
12
|
routes = [];
|
|
14
|
-
guards = new Set();
|
|
15
13
|
forceUnblocked = false;
|
|
14
|
+
guardDisposers = new Map();
|
|
16
15
|
constructor(gateway) {
|
|
17
16
|
this.gateway = gateway;
|
|
18
|
-
this.installBlocker();
|
|
19
17
|
makeAutoObservable(this, {
|
|
20
|
-
guards: false,
|
|
21
18
|
pendingTransition: false,
|
|
22
19
|
forceUnblocked: false
|
|
23
20
|
});
|
|
@@ -40,13 +37,29 @@ class RouterRepositoryImpl {
|
|
|
40
37
|
this.gateway.goToRoute(route.name, params);
|
|
41
38
|
}
|
|
42
39
|
addGuard(config) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
const gatewayGuard = {
|
|
41
|
+
guard: () => {
|
|
42
|
+
if (this.forceUnblocked) {
|
|
43
|
+
this.forceUnblocked = false;
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return config.guard();
|
|
47
|
+
},
|
|
48
|
+
onBlocked: controller => {
|
|
49
|
+
this.pendingTransition = controller;
|
|
50
|
+
config.onBlocked(controller);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const disposeGatewayGuard = this.gateway.addGuard(gatewayGuard);
|
|
54
|
+
const dispose = () => {
|
|
55
|
+
this.guardDisposers.delete(config);
|
|
56
|
+
disposeGatewayGuard();
|
|
46
57
|
};
|
|
58
|
+
this.guardDisposers.set(config, dispose);
|
|
59
|
+
return dispose;
|
|
47
60
|
}
|
|
48
61
|
isBlocked() {
|
|
49
|
-
return this.
|
|
62
|
+
return this.pendingTransition !== undefined;
|
|
50
63
|
}
|
|
51
64
|
unblock() {
|
|
52
65
|
this.forceUnblocked = true;
|
|
@@ -80,30 +93,6 @@ class RouterRepositoryImpl {
|
|
|
80
93
|
destroy() {
|
|
81
94
|
this.gateway.destroy();
|
|
82
95
|
}
|
|
83
|
-
installBlocker() {
|
|
84
|
-
this.gateway.onRouteExit(controller => {
|
|
85
|
-
if (this.forceUnblocked) {
|
|
86
|
-
this.forceUnblocked = false;
|
|
87
|
-
controller.continue();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const blockingGuard = this.findBlockingGuard();
|
|
91
|
-
if (blockingGuard) {
|
|
92
|
-
this.pendingTransition = controller;
|
|
93
|
-
blockingGuard.onBlocked();
|
|
94
|
-
} else {
|
|
95
|
-
controller.continue();
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
findBlockingGuard() {
|
|
100
|
-
for (const config of this.guards) {
|
|
101
|
-
if (config.guard()) {
|
|
102
|
-
return config;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
96
|
routeWithAction = route => {
|
|
108
97
|
return {
|
|
109
98
|
name: route.name,
|
|
@@ -128,9 +117,8 @@ class RouterRepositoryImpl {
|
|
|
128
117
|
return this.routes.find(existingRoute => existingRoute.name === name);
|
|
129
118
|
}
|
|
130
119
|
}
|
|
131
|
-
export const RouterRepository = createImplementation({
|
|
120
|
+
export const RouterRepository = Abstractions.RouterRepository.createImplementation({
|
|
132
121
|
implementation: RouterRepositoryImpl,
|
|
133
|
-
abstraction: Abstractions.RouterRepository,
|
|
134
122
|
dependencies: [Abstractions.RouterGateway]
|
|
135
123
|
});
|
|
136
124
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["makeAutoObservable","runInAction","Abstractions","createImplementation","RouteUrl","INIT_ROUTE","name","path","pathname","params","RouterRepositoryImpl","currentRoute","routes","guards","Set","forceUnblocked","constructor","gateway","installBlocker","pendingTransition","getMatchedRoute","undefined","getCurrentRoute","find","route","registerRoutes","routesWithAction","map","routeWithAction","setRoutes","getLink","fromPattern","goToRoute","addGuard","config","add","delete","isBlocked","findBlockingGuard","unblock","tx","continue","setTimeout","confirmTransition","cancelTransition","cancel","destroy","onRouteExit","controller","blockingGuard","onBlocked","guard","onMatch","transitionToRoute","bind","matchedRoute","getRouteByName","parse","Object","assign","existingRoute","RouterRepository","implementation","abstraction","dependencies","RouterGateway"],"sources":["RouterRepository.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from \"mobx\";\nimport type {\n MatchedRoute,\n RouteDefinition,\n RouteTransitionGuardConfig,\n GuardDisposer,\n TransitionController\n} from \"./abstractions.js\";\nimport * as Abstractions from \"./abstractions.js\";\nimport { Route, RouteParamsDefinition, RouteParamsInfer } from \"./Route.js\";\nimport { createImplementation } from \"@webiny/di\";\nimport { RouteUrl } from \"./RouteUrl.js\";\n\nconst INIT_ROUTE = { name: \"__init__\", path: \"\", pathname: \"\", params: {} };\n\nclass RouterRepositoryImpl implements Abstractions.RouterRepository.Interface {\n private gateway: Abstractions.RouterGateway.Interface;\n private currentRoute: MatchedRoute = INIT_ROUTE;\n private routes: Route<any>[] = [];\n private guards = new Set<RouteTransitionGuardConfig>();\n private pendingTransition: TransitionController | undefined;\n private forceUnblocked = false;\n\n constructor(gateway: Abstractions.RouterGateway.Interface) {\n this.gateway = gateway;\n this.installBlocker();\n\n makeAutoObservable(this, {\n guards: false,\n pendingTransition: false,\n forceUnblocked: false\n } as any);\n }\n\n getMatchedRoute() {\n return this.currentRoute.name !== INIT_ROUTE.name ? this.currentRoute : undefined;\n }\n\n getCurrentRoute(): Route<any> | undefined {\n return this.routes.find(route => route.name === this.currentRoute.name);\n }\n\n registerRoutes = (routes: Route[]) => {\n this.routes = routes;\n const routesWithAction = routes.map<RouteDefinition>(this.routeWithAction);\n\n this.gateway.setRoutes(routesWithAction);\n };\n\n getLink<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params?: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): string {\n return RouteUrl.fromPattern(route.path, params);\n }\n\n goToRoute<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): void {\n this.gateway.goToRoute(route.name, params);\n }\n\n addGuard(config: RouteTransitionGuardConfig): GuardDisposer {\n this.guards.add(config);\n return () => {\n this.guards.delete(config);\n };\n }\n\n isBlocked(): boolean {\n return this.findBlockingGuard() !== undefined;\n }\n\n unblock(): void {\n this.forceUnblocked = true;\n if (this.pendingTransition) {\n this.forceUnblocked = false;\n const tx = this.pendingTransition;\n this.pendingTransition = undefined;\n tx.continue();\n } else {\n // No pending transition — expire the flag after the current\n // call stack so it only covers synchronous navigations that\n // follow immediately (e.g. router.goToRoute on the next line).\n setTimeout(() => {\n this.forceUnblocked = false;\n }, 0);\n }\n }\n\n confirmTransition(): void {\n const tx = this.pendingTransition;\n this.pendingTransition = undefined;\n if (tx) {\n tx.continue();\n }\n }\n\n cancelTransition(): void {\n if (this.pendingTransition) {\n this.pendingTransition.cancel();\n this.pendingTransition = undefined;\n }\n }\n\n destroy() {\n this.gateway.destroy();\n }\n\n private installBlocker(): void {\n this.gateway.onRouteExit(controller => {\n if (this.forceUnblocked) {\n this.forceUnblocked = false;\n controller.continue();\n return;\n }\n\n const blockingGuard = this.findBlockingGuard();\n if (blockingGuard) {\n this.pendingTransition = controller;\n blockingGuard.onBlocked();\n } else {\n controller.continue();\n }\n });\n }\n\n private findBlockingGuard(): RouteTransitionGuardConfig | undefined {\n for (const config of this.guards) {\n if (config.guard()) {\n return config;\n }\n }\n return undefined;\n }\n\n private routeWithAction = (route: Route<any>) => {\n return {\n name: route.name,\n path: route.path,\n onMatch: this.transitionToRoute.bind(this)\n };\n };\n\n private async transitionToRoute(matchedRoute: MatchedRoute) {\n const route = this.getRouteByName(matchedRoute.name);\n if (!route) {\n return;\n }\n\n const params =\n typeof route.params?.parse === \"function\"\n ? route.params.parse(matchedRoute.params)\n : matchedRoute.params;\n\n runInAction(() => {\n Object.assign(this.currentRoute, {\n ...matchedRoute,\n params\n });\n });\n }\n\n private getRouteByName(name: string) {\n return this.routes.find(existingRoute => existingRoute.name === name);\n }\n}\n\nexport const RouterRepository = createImplementation({\n implementation: RouterRepositoryImpl,\n abstraction: Abstractions.RouterRepository,\n dependencies: [Abstractions.RouterGateway]\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["makeAutoObservable","runInAction","Abstractions","RouteUrl","INIT_ROUTE","name","path","pathname","params","RouterRepositoryImpl","currentRoute","routes","forceUnblocked","guardDisposers","Map","constructor","gateway","pendingTransition","getMatchedRoute","undefined","getCurrentRoute","find","route","registerRoutes","routesWithAction","map","routeWithAction","setRoutes","getLink","fromPattern","goToRoute","addGuard","config","gatewayGuard","guard","onBlocked","controller","disposeGatewayGuard","dispose","delete","set","isBlocked","unblock","tx","continue","setTimeout","confirmTransition","cancelTransition","cancel","destroy","onMatch","transitionToRoute","bind","matchedRoute","getRouteByName","parse","Object","assign","existingRoute","RouterRepository","createImplementation","implementation","dependencies","RouterGateway"],"sources":["RouterRepository.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from \"mobx\";\nimport type {\n MatchedRoute,\n RouteDefinition,\n RouteTransitionGuardConfig,\n GuardDisposer,\n TransitionController\n} from \"./abstractions.js\";\nimport * as Abstractions from \"./abstractions.js\";\nimport { Route, RouteParamsDefinition, RouteParamsInfer } from \"./Route.js\";\nimport { RouteUrl } from \"./RouteUrl.js\";\n\nconst INIT_ROUTE = { name: \"__init__\", path: \"\", pathname: \"\", params: {} };\n\nclass RouterRepositoryImpl implements Abstractions.RouterRepository.Interface {\n private gateway: Abstractions.RouterGateway.Interface;\n private currentRoute: MatchedRoute = INIT_ROUTE;\n private routes: Route<any>[] = [];\n private pendingTransition: TransitionController | undefined;\n private forceUnblocked = false;\n private guardDisposers = new Map<RouteTransitionGuardConfig, GuardDisposer>();\n\n constructor(gateway: Abstractions.RouterGateway.Interface) {\n this.gateway = gateway;\n\n makeAutoObservable(this, {\n pendingTransition: false,\n forceUnblocked: false\n } as any);\n }\n\n getMatchedRoute() {\n return this.currentRoute.name !== INIT_ROUTE.name ? this.currentRoute : undefined;\n }\n\n getCurrentRoute(): Route<any> | undefined {\n return this.routes.find(route => route.name === this.currentRoute.name);\n }\n\n registerRoutes = (routes: Route[]) => {\n this.routes = routes;\n const routesWithAction = routes.map<RouteDefinition>(this.routeWithAction);\n\n this.gateway.setRoutes(routesWithAction);\n };\n\n getLink<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params?: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): string {\n return RouteUrl.fromPattern(route.path, params);\n }\n\n goToRoute<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): void {\n this.gateway.goToRoute(route.name, params);\n }\n\n addGuard(config: RouteTransitionGuardConfig): GuardDisposer {\n const gatewayGuard: RouteTransitionGuardConfig = {\n guard: () => {\n if (this.forceUnblocked) {\n this.forceUnblocked = false;\n return false;\n }\n return config.guard();\n },\n onBlocked: (controller: TransitionController) => {\n this.pendingTransition = controller;\n config.onBlocked(controller);\n }\n };\n\n const disposeGatewayGuard = this.gateway.addGuard(gatewayGuard);\n\n const dispose = () => {\n this.guardDisposers.delete(config);\n disposeGatewayGuard();\n };\n\n this.guardDisposers.set(config, dispose);\n return dispose;\n }\n\n isBlocked(): boolean {\n return this.pendingTransition !== undefined;\n }\n\n unblock(): void {\n this.forceUnblocked = true;\n if (this.pendingTransition) {\n this.forceUnblocked = false;\n const tx = this.pendingTransition;\n this.pendingTransition = undefined;\n tx.continue();\n } else {\n // No pending transition — expire the flag after the current\n // call stack so it only covers synchronous navigations that\n // follow immediately (e.g. router.goToRoute on the next line).\n setTimeout(() => {\n this.forceUnblocked = false;\n }, 0);\n }\n }\n\n confirmTransition(): void {\n const tx = this.pendingTransition;\n this.pendingTransition = undefined;\n if (tx) {\n tx.continue();\n }\n }\n\n cancelTransition(): void {\n if (this.pendingTransition) {\n this.pendingTransition.cancel();\n this.pendingTransition = undefined;\n }\n }\n\n destroy() {\n this.gateway.destroy();\n }\n\n private routeWithAction = (route: Route<any>) => {\n return {\n name: route.name,\n path: route.path,\n onMatch: this.transitionToRoute.bind(this)\n };\n };\n\n private async transitionToRoute(matchedRoute: MatchedRoute) {\n const route = this.getRouteByName(matchedRoute.name);\n if (!route) {\n return;\n }\n\n const params =\n typeof route.params?.parse === \"function\"\n ? route.params.parse(matchedRoute.params)\n : matchedRoute.params;\n\n runInAction(() => {\n Object.assign(this.currentRoute, {\n ...matchedRoute,\n params\n });\n });\n }\n\n private getRouteByName(name: string) {\n return this.routes.find(existingRoute => existingRoute.name === name);\n }\n}\n\nexport const RouterRepository = Abstractions.RouterRepository.createImplementation({\n implementation: RouterRepositoryImpl,\n dependencies: [Abstractions.RouterGateway]\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -30,7 +30,7 @@ export interface MatchedRoute<TParams = Record<string, any>> {
|
|
|
30
30
|
path: string;
|
|
31
31
|
params: TParams;
|
|
32
32
|
}
|
|
33
|
-
interface IRouterRepository {
|
|
33
|
+
export interface IRouterRepository {
|
|
34
34
|
getMatchedRoute(): MatchedRoute | undefined;
|
|
35
35
|
getCurrentRoute(): Route<any> | undefined;
|
|
36
36
|
goToRoute<TParams extends RouteParamsDefinition | undefined>(route: Route<TParams>, params: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined): void;
|
|
@@ -57,16 +57,13 @@ export type TransitionController = {
|
|
|
57
57
|
continue: () => void;
|
|
58
58
|
cancel: () => void;
|
|
59
59
|
};
|
|
60
|
-
export interface OnRouteExit {
|
|
61
|
-
(controller: TransitionController): void;
|
|
62
|
-
}
|
|
63
60
|
interface IRouterGateway {
|
|
64
61
|
setRoutes(routes: RouteDefinition[]): void;
|
|
65
62
|
goToRoute(name: string, params?: {
|
|
66
63
|
[k: string]: any;
|
|
67
64
|
}): void;
|
|
68
65
|
pushState(url: string): void;
|
|
69
|
-
|
|
66
|
+
addGuard(config: RouteTransitionGuardConfig): GuardDisposer;
|
|
70
67
|
destroy(): void;
|
|
71
68
|
}
|
|
72
69
|
export declare const RouterGateway: Abstraction<IRouterGateway>;
|
|
@@ -79,6 +76,6 @@ export interface RouteTransitionGuardConfig {
|
|
|
79
76
|
/** Return true to block the transition. */
|
|
80
77
|
guard: () => boolean;
|
|
81
78
|
/** Called when this guard blocks a transition. Show a confirmation dialog here. */
|
|
82
|
-
onBlocked: () => void;
|
|
79
|
+
onBlocked: (controller: TransitionController) => void;
|
|
83
80
|
}
|
|
84
81
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Abstraction","RouterPresenter","RouterRepository","RouterGateway"],"sources":["abstractions.ts"],"sourcesContent":["import { Abstraction } from \"@webiny/di\";\nimport type { Route, RouteParamsDefinition, RouteParamsInfer } from \"./Route.js\";\nimport type { RequiredKeysOf } from \"type-fest\";\n\n/***** Presenter *****/\n\nexport type RouteParamsArgs<TParams extends RouteParamsDefinition | undefined> =\n TParams extends RouteParamsDefinition\n ? RequiredKeysOf<RouteParamsInfer<TParams>> extends never\n ? [params?: RouteParamsInfer<TParams>] // all optional → param optional\n : [params: RouteParamsInfer<TParams>] // some required → param required\n : [];\n\ninterface RouterViewModel {\n currentRoute: MatchedRoute | undefined;\n}\n\nexport interface IRouterPresenter {\n vm: RouterViewModel;\n bootstrap(routes: Route[]): void;\n goToRoute<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n ...args: RouteParamsArgs<TParams>\n ): void;\n getLink<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n ...args: RouteParamsArgs<TParams>\n ): string;\n setRouteParams<T extends Record<string, any>>(cb: (params: T) => T): void;\n addTransitionGuard(config: RouteTransitionGuardConfig): GuardDisposer;\n isTransitionBlocked(): boolean;\n unblockTransition(): void;\n confirmTransition(): void;\n cancelTransition(): void;\n destroy(): void;\n}\nexport const RouterPresenter = new Abstraction<IRouterPresenter>(\"RouterPresenter\");\n\nexport namespace RouterPresenter {\n export type Interface = IRouterPresenter;\n}\n\n/***** Repository *****/\n\nexport interface MatchedRoute<TParams = Record<string, any>> {\n // Name of the matched route.\n name: string;\n // Pathname that was used to match the route.\n pathname: string;\n // Path pattern that matched this route.\n path: string;\n // Route params extracted from the pathname.\n params: TParams;\n}\n\
|
|
1
|
+
{"version":3,"names":["Abstraction","RouterPresenter","RouterRepository","RouterGateway"],"sources":["abstractions.ts"],"sourcesContent":["import { Abstraction } from \"@webiny/di\";\nimport type { Route, RouteParamsDefinition, RouteParamsInfer } from \"./Route.js\";\nimport type { RequiredKeysOf } from \"type-fest\";\n\n/***** Presenter *****/\n\nexport type RouteParamsArgs<TParams extends RouteParamsDefinition | undefined> =\n TParams extends RouteParamsDefinition\n ? RequiredKeysOf<RouteParamsInfer<TParams>> extends never\n ? [params?: RouteParamsInfer<TParams>] // all optional → param optional\n : [params: RouteParamsInfer<TParams>] // some required → param required\n : [];\n\ninterface RouterViewModel {\n currentRoute: MatchedRoute | undefined;\n}\n\nexport interface IRouterPresenter {\n vm: RouterViewModel;\n bootstrap(routes: Route[]): void;\n goToRoute<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n ...args: RouteParamsArgs<TParams>\n ): void;\n getLink<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n ...args: RouteParamsArgs<TParams>\n ): string;\n setRouteParams<T extends Record<string, any>>(cb: (params: T) => T): void;\n addTransitionGuard(config: RouteTransitionGuardConfig): GuardDisposer;\n isTransitionBlocked(): boolean;\n unblockTransition(): void;\n confirmTransition(): void;\n cancelTransition(): void;\n destroy(): void;\n}\nexport const RouterPresenter = new Abstraction<IRouterPresenter>(\"RouterPresenter\");\n\nexport namespace RouterPresenter {\n export type Interface = IRouterPresenter;\n}\n\n/***** Repository *****/\n\nexport interface MatchedRoute<TParams = Record<string, any>> {\n // Name of the matched route.\n name: string;\n // Pathname that was used to match the route.\n pathname: string;\n // Path pattern that matched this route.\n path: string;\n // Route params extracted from the pathname.\n params: TParams;\n}\n\nexport interface IRouterRepository {\n getMatchedRoute(): MatchedRoute | undefined;\n\n getCurrentRoute(): Route<any> | undefined;\n\n goToRoute<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): void;\n\n getLink<TParams extends RouteParamsDefinition | undefined>(\n route: Route<TParams>,\n params: TParams extends RouteParamsDefinition ? RouteParamsInfer<TParams> : undefined\n ): string;\n\n registerRoutes(routes: Route[]): void;\n\n addGuard(config: RouteTransitionGuardConfig): GuardDisposer;\n isBlocked(): boolean;\n unblock(): void;\n confirmTransition(): void;\n cancelTransition(): void;\n\n destroy(): void;\n}\n\nexport const RouterRepository = new Abstraction<IRouterRepository>(\"RouterRepository\");\n\nexport namespace RouterRepository {\n export type Interface = IRouterRepository;\n}\n\n/***** Gateway *****/\n\nexport interface RouteDefinition {\n name: string;\n path: string;\n onMatch(route: MatchedRoute): void;\n}\n\nexport type TransitionController = {\n continue: () => void;\n cancel: () => void;\n};\n\ninterface IRouterGateway {\n setRoutes(routes: RouteDefinition[]): void;\n goToRoute(name: string, params?: { [k: string]: any }): void;\n pushState(url: string): void;\n addGuard(config: RouteTransitionGuardConfig): GuardDisposer;\n destroy(): void;\n}\n\nexport const RouterGateway = new Abstraction<IRouterGateway>(\"RouterGateway\");\n\nexport namespace RouterGateway {\n export type Interface = IRouterGateway;\n}\n\n/***** Route Transition *****/\n\nexport type GuardDisposer = () => void;\n\nexport interface RouteTransitionGuardConfig {\n /** Return true to block the transition. */\n guard: () => boolean;\n /** Called when this guard blocks a transition. Show a confirmation dialog here. */\n onBlocked: (controller: TransitionController) => void;\n}\n"],"mappings":"AAAA,SAASA,WAAW,QAAQ,YAAY;;AAIxC;;AAgCA,OAAO,MAAMC,eAAe,GAAG,IAAID,WAAW,CAAmB,iBAAiB,CAAC;;AAMnF;;AAuCA,OAAO,MAAME,gBAAgB,GAAG,IAAIF,WAAW,CAAoB,kBAAkB,CAAC;;AAMtF;;AAqBA,OAAO,MAAMG,aAAa,GAAG,IAAIH,WAAW,CAAiB,eAAe,CAAC;;AAM7E","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { RouterPresenter, RouterGateway } from "./abstractions.js";
|
|
2
|
-
export type { RouteTransitionGuardConfig, GuardDisposer } from "./abstractions.js";
|
|
2
|
+
export type { RouteTransitionGuardConfig, GuardDisposer, TransitionController } from "./abstractions.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RouterPresenter","RouterGateway"],"sources":["index.ts"],"sourcesContent":["export { RouterPresenter, RouterGateway } from \"./abstractions.js\";\nexport type {
|
|
1
|
+
{"version":3,"names":["RouterPresenter","RouterGateway"],"sources":["index.ts"],"sourcesContent":["export { RouterPresenter, RouterGateway } from \"./abstractions.js\";\nexport type {\n RouteTransitionGuardConfig,\n GuardDisposer,\n TransitionController\n} from \"./abstractions.js\";\n"],"mappings":"AAAA,SAASA,eAAe,EAAEC,aAAa","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/app",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@apollo/react-hooks": "3.1.5",
|
|
19
19
|
"@emotion/styled": "11.14.1",
|
|
20
|
-
"@types/react": "18.
|
|
20
|
+
"@types/react": "18.3.28",
|
|
21
21
|
"@webiny/di": "0.2.3",
|
|
22
|
-
"@webiny/feature": "6.
|
|
23
|
-
"@webiny/i18n": "6.
|
|
24
|
-
"@webiny/i18n-react": "6.
|
|
25
|
-
"@webiny/plugins": "6.
|
|
26
|
-
"@webiny/react-composition": "6.
|
|
27
|
-
"@webiny/react-properties": "6.
|
|
22
|
+
"@webiny/feature": "6.2.0",
|
|
23
|
+
"@webiny/i18n": "6.2.0",
|
|
24
|
+
"@webiny/i18n-react": "6.2.0",
|
|
25
|
+
"@webiny/plugins": "6.2.0",
|
|
26
|
+
"@webiny/react-composition": "6.2.0",
|
|
27
|
+
"@webiny/react-properties": "6.2.0",
|
|
28
28
|
"apollo-cache": "1.3.5",
|
|
29
29
|
"apollo-cache-inmemory": "1.6.6",
|
|
30
30
|
"apollo-client": "2.6.10",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"graphql": "16.13.2",
|
|
39
39
|
"history": "5.3.0",
|
|
40
40
|
"invariant": "2.2.4",
|
|
41
|
-
"lodash": "4.
|
|
42
|
-
"minimatch": "10.2.
|
|
41
|
+
"lodash": "4.18.1",
|
|
42
|
+
"minimatch": "10.2.5",
|
|
43
43
|
"mobx": "6.15.0",
|
|
44
44
|
"nanoid": "5.1.7",
|
|
45
|
-
"react": "18.
|
|
46
|
-
"react-dom": "18.
|
|
45
|
+
"react": "18.3.1",
|
|
46
|
+
"react-dom": "18.3.1",
|
|
47
47
|
"ts-invariant": "0.10.3",
|
|
48
48
|
"warning": "4.0.3",
|
|
49
49
|
"zod": "4.3.6"
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/lodash": "4.17.24",
|
|
53
53
|
"@types/warning": "3.0.4",
|
|
54
|
-
"@webiny/build-tools": "6.
|
|
54
|
+
"@webiny/build-tools": "6.2.0",
|
|
55
55
|
"rimraf": "6.1.3",
|
|
56
56
|
"type-fest": "5.5.0",
|
|
57
57
|
"typescript": "5.9.3",
|
|
58
|
-
"vitest": "4.1.
|
|
58
|
+
"vitest": "4.1.4"
|
|
59
59
|
},
|
|
60
60
|
"publishConfig": {
|
|
61
61
|
"access": "public",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
]
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "3d3148358b6febbc857371930871743bec3b3939"
|
|
72
72
|
}
|
package/shared/di/useFeature.js
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
1
2
|
import { useContainer } from "./DiContainerProvider.js";
|
|
2
|
-
const featureCache = new WeakMap();
|
|
3
3
|
export function useFeature(feature) {
|
|
4
4
|
const container = useContainer();
|
|
5
|
-
|
|
6
|
-
if (!featureMap) {
|
|
7
|
-
featureMap = new Map();
|
|
8
|
-
featureCache.set(container, featureMap);
|
|
9
|
-
}
|
|
10
|
-
if (featureMap.has(feature.name)) {
|
|
11
|
-
return featureMap.get(feature.name);
|
|
12
|
-
}
|
|
13
|
-
const exports = feature.resolve(container);
|
|
14
|
-
featureMap.set(feature.name, exports);
|
|
15
|
-
return exports;
|
|
5
|
+
return useMemo(() => feature.resolve(container), [container, feature]);
|
|
16
6
|
}
|
|
17
7
|
|
|
18
8
|
//# sourceMappingURL=useFeature.js.map
|