@merkur/plugin-router 0.36.0 → 0.37.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/lib/index.cjs CHANGED
@@ -15,10 +15,31 @@ const ENV =
15
15
  : DEV;
16
16
 
17
17
  function createRouter(widget, routes, options) {
18
- widget.$dependencies.router = new UniversalRouter(routes, options);
18
+ let wrappedRoutes = routes.reduce((result, route) => {
19
+ const clonedRoute = { ...route };
20
+
21
+ if (core.isFunction(clonedRoute.action)) {
22
+ const originAction = clonedRoute.action;
23
+ clonedRoute.action = (...rest) => {
24
+ // @TODO UniversalRouter don't parse query from url so context.params are only named route parameters
25
+ // For some application can be helpful to have named route parameters and query parameters merged
26
+ // because link method support both named parameters and query parameters
27
+ widget.$in.router.context = rest[0];
28
+
29
+ return originAction(...rest);
30
+ };
31
+ }
32
+
33
+ result.push(clonedRoute);
34
+
35
+ return result;
36
+ }, []);
37
+
38
+ widget.$dependencies.router = new UniversalRouter(wrappedRoutes, options);
19
39
  widget.$dependencies.link = generateUrls(widget.$dependencies.router, {
20
40
  stringifyQueryParams: (params) => new URLSearchParams(params).toString(),
21
41
  });
42
+ widget.$in.router.options = options;
22
43
  }
23
44
 
24
45
  function routerPlugin() {
@@ -28,6 +49,8 @@ function routerPlugin() {
28
49
 
29
50
  widget.$in.router = {
30
51
  route: null,
52
+ context: null,
53
+ options: {},
31
54
  pathname: null,
32
55
  isMounting: false,
33
56
  isRouteActivated: false,
@@ -69,6 +92,20 @@ function routerPlugin() {
69
92
  };
70
93
  }
71
94
 
95
+ function getOrigin(widget) {
96
+ const { protocol, host } = widget.$in.router.options;
97
+
98
+ if (!host) {
99
+ return '';
100
+ }
101
+
102
+ if (!protocol) {
103
+ return `//${host}`;
104
+ }
105
+
106
+ return `${protocol.replace(':', '').trim()}://${host.trim()}`;
107
+ }
108
+
72
109
  function routerAPI() {
73
110
  return {
74
111
  router: {
@@ -76,11 +113,21 @@ function routerAPI() {
76
113
  widget.emit(RouterEvents.REDIRECT, { url, ...data });
77
114
  },
78
115
  link(widget, routeName, data = {}) {
79
- return widget.$dependencies.link(routeName, data);
116
+ const origin = getOrigin(widget);
117
+ const path = widget.$dependencies.link(routeName, data);
118
+
119
+ if (origin && path === '/') {
120
+ return origin;
121
+ }
122
+
123
+ return `${origin}${path}`;
80
124
  },
81
125
  getCurrentRoute(widget) {
82
126
  return widget.$in.router.route;
83
127
  },
128
+ getCurrentContext(widget) {
129
+ return widget.$in.router.context;
130
+ },
84
131
  },
85
132
  };
86
133
  }
@@ -114,6 +161,7 @@ async function loadHook(widget, originalLoad, ...rest) {
114
161
  : Promise.resolve({});
115
162
  const routeStatePromise = plugin.route.load(widget, {
116
163
  route: plugin.route,
164
+ context: plugin.context,
117
165
  args: rest,
118
166
  globalState: globalStatePromise,
119
167
  });
@@ -139,7 +187,11 @@ async function mountHook(widget, originalMount, ...rest) {
139
187
  const result = await originalMount(...rest);
140
188
 
141
189
  if (plugin.isMounting && core.isFunction(plugin.route.init)) {
142
- await plugin.route.init(widget, { route: plugin.route, args: rest });
190
+ await plugin.route.init(widget, {
191
+ route: plugin.route,
192
+ context: plugin.context,
193
+ args: rest,
194
+ });
143
195
  }
144
196
 
145
197
  if (
@@ -148,7 +200,11 @@ async function mountHook(widget, originalMount, ...rest) {
148
200
  !plugin.isRouteActivated
149
201
  ) {
150
202
  plugin.isRouteActivated = true;
151
- plugin.route.activate(widget, { route: plugin.route, args: rest });
203
+ plugin.route.activate(widget, {
204
+ route: plugin.route,
205
+ context: plugin.context,
206
+ args: rest,
207
+ });
152
208
  }
153
209
 
154
210
  plugin.isMounting = false;
@@ -168,7 +224,11 @@ async function updateHook(widget, originalUpdate, ...rest) {
168
224
  !plugin.isRouteActivated
169
225
  ) {
170
226
  plugin.isRouteActivated = true;
171
- plugin.route.activate(widget, { route: plugin.route, args: rest });
227
+ plugin.route.activate(widget, {
228
+ route: plugin.route,
229
+ context: plugin.context,
230
+ args: rest,
231
+ });
172
232
  }
173
233
 
174
234
  return result;
@@ -209,9 +269,10 @@ async function resolveRoute(widget) {
209
269
 
210
270
  async function setupRouterCycle(widget, ...rest) {
211
271
  const route = await resolveRoute(widget);
272
+ const plugin = widget.$in.router;
212
273
 
213
274
  if (core.isFunction(route.init)) {
214
- await route.init(widget, { route, args: rest });
275
+ await route.init(widget, { route, context: plugin.context, args: rest });
215
276
  }
216
277
  }
217
278
 
@@ -222,11 +283,19 @@ async function tearDownRouterCycle(widget, ...rest) {
222
283
 
223
284
  if (route) {
224
285
  if (core.isFunction(route.deactivate) && isRouteActivated === true) {
225
- await route.deactivate(widget, { route, args: rest });
286
+ await route.deactivate(widget, {
287
+ route,
288
+ context: plugin.context,
289
+ args: rest,
290
+ });
226
291
  }
227
292
 
228
293
  if (core.isFunction(route.destroy)) {
229
- await route.destroy(widget, { route, args: rest });
294
+ await route.destroy(widget, {
295
+ route,
296
+ context: plugin.context,
297
+ args: rest,
298
+ });
230
299
  }
231
300
  }
232
301
 
package/lib/index.es9.cjs CHANGED
@@ -9,10 +9,28 @@ var RouterEvents = Object.freeze({
9
9
  const DEV = 'development';
10
10
  const ENV = typeof process !== 'undefined' && process && process.env ? process.env.NODE_ENV : DEV;
11
11
  function createRouter(widget, routes, options) {
12
- widget.$dependencies.router = new UniversalRouter(routes, options);
12
+ let wrappedRoutes = routes.reduce((result, route) => {
13
+ const clonedRoute = {
14
+ ...route
15
+ };
16
+ if (core.isFunction(clonedRoute.action)) {
17
+ const originAction = clonedRoute.action;
18
+ clonedRoute.action = (...rest) => {
19
+ // @TODO UniversalRouter don't parse query from url so context.params are only named route parameters
20
+ // For some application can be helpful to have named route parameters and query parameters merged
21
+ // because link method support both named parameters and query parameters
22
+ widget.$in.router.context = rest[0];
23
+ return originAction(...rest);
24
+ };
25
+ }
26
+ result.push(clonedRoute);
27
+ return result;
28
+ }, []);
29
+ widget.$dependencies.router = new UniversalRouter(wrappedRoutes, options);
13
30
  widget.$dependencies.link = generateUrls(widget.$dependencies.router, {
14
31
  stringifyQueryParams: params => new URLSearchParams(params).toString()
15
32
  });
33
+ widget.$in.router.options = options;
16
34
  }
17
35
  function routerPlugin() {
18
36
  return {
@@ -20,6 +38,8 @@ function routerPlugin() {
20
38
  core.assignMissingKeys(widget, routerAPI());
21
39
  widget.$in.router = {
22
40
  route: null,
41
+ context: null,
42
+ options: {},
23
43
  pathname: null,
24
44
  isMounting: false,
25
45
  isRouteActivated: false,
@@ -47,6 +67,19 @@ function routerPlugin() {
47
67
  }
48
68
  };
49
69
  }
70
+ function getOrigin(widget) {
71
+ const {
72
+ protocol,
73
+ host
74
+ } = widget.$in.router.options;
75
+ if (!host) {
76
+ return '';
77
+ }
78
+ if (!protocol) {
79
+ return `//${host}`;
80
+ }
81
+ return `${protocol.replace(':', '').trim()}://${host.trim()}`;
82
+ }
50
83
  function routerAPI() {
51
84
  return {
52
85
  router: {
@@ -57,10 +90,18 @@ function routerAPI() {
57
90
  });
58
91
  },
59
92
  link(widget, routeName, data = {}) {
60
- return widget.$dependencies.link(routeName, data);
93
+ const origin = getOrigin(widget);
94
+ const path = widget.$dependencies.link(routeName, data);
95
+ if (origin && path === '/') {
96
+ return origin;
97
+ }
98
+ return `${origin}${path}`;
61
99
  },
62
100
  getCurrentRoute(widget) {
63
101
  return widget.$in.router.route;
102
+ },
103
+ getCurrentContext(widget) {
104
+ return widget.$in.router.context;
64
105
  }
65
106
  }
66
107
  };
@@ -86,6 +127,7 @@ async function loadHook(widget, originalLoad, ...rest) {
86
127
  const globalStatePromise = core.isFunction(originalLoad) ? originalLoad(widget, ...rest) : Promise.resolve({});
87
128
  const routeStatePromise = plugin.route.load(widget, {
88
129
  route: plugin.route,
130
+ context: plugin.context,
89
131
  args: rest,
90
132
  globalState: globalStatePromise
91
133
  });
@@ -108,6 +150,7 @@ async function mountHook(widget, originalMount, ...rest) {
108
150
  if (plugin.isMounting && core.isFunction(plugin.route.init)) {
109
151
  await plugin.route.init(widget, {
110
152
  route: plugin.route,
153
+ context: plugin.context,
111
154
  args: rest
112
155
  });
113
156
  }
@@ -115,6 +158,7 @@ async function mountHook(widget, originalMount, ...rest) {
115
158
  plugin.isRouteActivated = true;
116
159
  plugin.route.activate(widget, {
117
160
  route: plugin.route,
161
+ context: plugin.context,
118
162
  args: rest
119
163
  });
120
164
  }
@@ -130,6 +174,7 @@ async function updateHook(widget, originalUpdate, ...rest) {
130
174
  plugin.isRouteActivated = true;
131
175
  plugin.route.activate(widget, {
132
176
  route: plugin.route,
177
+ context: plugin.context,
133
178
  args: rest
134
179
  });
135
180
  }
@@ -161,9 +206,11 @@ async function resolveRoute(widget) {
161
206
  }
162
207
  async function setupRouterCycle(widget, ...rest) {
163
208
  const route = await resolveRoute(widget);
209
+ const plugin = widget.$in.router;
164
210
  if (core.isFunction(route.init)) {
165
211
  await route.init(widget, {
166
212
  route,
213
+ context: plugin.context,
167
214
  args: rest
168
215
  });
169
216
  }
@@ -178,12 +225,14 @@ async function tearDownRouterCycle(widget, ...rest) {
178
225
  if (core.isFunction(route.deactivate) && isRouteActivated === true) {
179
226
  await route.deactivate(widget, {
180
227
  route,
228
+ context: plugin.context,
181
229
  args: rest
182
230
  });
183
231
  }
184
232
  if (core.isFunction(route.destroy)) {
185
233
  await route.destroy(widget, {
186
234
  route,
235
+ context: plugin.context,
187
236
  args: rest
188
237
  });
189
238
  }
package/lib/index.es9.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { assignMissingKeys, bindWidgetToFunctions, setDefaultValueForUndefined, hookMethod, isFunction } from '@merkur/core';
1
+ import { isFunction, assignMissingKeys, bindWidgetToFunctions, setDefaultValueForUndefined, hookMethod } from '@merkur/core';
2
2
  import UniversalRouter from 'universal-router';
3
3
  import generateUrls from 'universal-router/generateUrls';
4
4
  var RouterEvents = Object.freeze({
@@ -7,10 +7,28 @@ var RouterEvents = Object.freeze({
7
7
  const DEV = 'development';
8
8
  const ENV = typeof process !== 'undefined' && process && process.env ? process.env.NODE_ENV : DEV;
9
9
  function createRouter(widget, routes, options) {
10
- widget.$dependencies.router = new UniversalRouter(routes, options);
10
+ let wrappedRoutes = routes.reduce((result, route) => {
11
+ const clonedRoute = {
12
+ ...route
13
+ };
14
+ if (isFunction(clonedRoute.action)) {
15
+ const originAction = clonedRoute.action;
16
+ clonedRoute.action = (...rest) => {
17
+ // @TODO UniversalRouter don't parse query from url so context.params are only named route parameters
18
+ // For some application can be helpful to have named route parameters and query parameters merged
19
+ // because link method support both named parameters and query parameters
20
+ widget.$in.router.context = rest[0];
21
+ return originAction(...rest);
22
+ };
23
+ }
24
+ result.push(clonedRoute);
25
+ return result;
26
+ }, []);
27
+ widget.$dependencies.router = new UniversalRouter(wrappedRoutes, options);
11
28
  widget.$dependencies.link = generateUrls(widget.$dependencies.router, {
12
29
  stringifyQueryParams: params => new URLSearchParams(params).toString()
13
30
  });
31
+ widget.$in.router.options = options;
14
32
  }
15
33
  function routerPlugin() {
16
34
  return {
@@ -18,6 +36,8 @@ function routerPlugin() {
18
36
  assignMissingKeys(widget, routerAPI());
19
37
  widget.$in.router = {
20
38
  route: null,
39
+ context: null,
40
+ options: {},
21
41
  pathname: null,
22
42
  isMounting: false,
23
43
  isRouteActivated: false,
@@ -45,6 +65,19 @@ function routerPlugin() {
45
65
  }
46
66
  };
47
67
  }
68
+ function getOrigin(widget) {
69
+ const {
70
+ protocol,
71
+ host
72
+ } = widget.$in.router.options;
73
+ if (!host) {
74
+ return '';
75
+ }
76
+ if (!protocol) {
77
+ return `//${host}`;
78
+ }
79
+ return `${protocol.replace(':', '').trim()}://${host.trim()}`;
80
+ }
48
81
  function routerAPI() {
49
82
  return {
50
83
  router: {
@@ -55,10 +88,18 @@ function routerAPI() {
55
88
  });
56
89
  },
57
90
  link(widget, routeName, data = {}) {
58
- return widget.$dependencies.link(routeName, data);
91
+ const origin = getOrigin(widget);
92
+ const path = widget.$dependencies.link(routeName, data);
93
+ if (origin && path === '/') {
94
+ return origin;
95
+ }
96
+ return `${origin}${path}`;
59
97
  },
60
98
  getCurrentRoute(widget) {
61
99
  return widget.$in.router.route;
100
+ },
101
+ getCurrentContext(widget) {
102
+ return widget.$in.router.context;
62
103
  }
63
104
  }
64
105
  };
@@ -84,6 +125,7 @@ async function loadHook(widget, originalLoad, ...rest) {
84
125
  const globalStatePromise = isFunction(originalLoad) ? originalLoad(widget, ...rest) : Promise.resolve({});
85
126
  const routeStatePromise = plugin.route.load(widget, {
86
127
  route: plugin.route,
128
+ context: plugin.context,
87
129
  args: rest,
88
130
  globalState: globalStatePromise
89
131
  });
@@ -106,6 +148,7 @@ async function mountHook(widget, originalMount, ...rest) {
106
148
  if (plugin.isMounting && isFunction(plugin.route.init)) {
107
149
  await plugin.route.init(widget, {
108
150
  route: plugin.route,
151
+ context: plugin.context,
109
152
  args: rest
110
153
  });
111
154
  }
@@ -113,6 +156,7 @@ async function mountHook(widget, originalMount, ...rest) {
113
156
  plugin.isRouteActivated = true;
114
157
  plugin.route.activate(widget, {
115
158
  route: plugin.route,
159
+ context: plugin.context,
116
160
  args: rest
117
161
  });
118
162
  }
@@ -128,6 +172,7 @@ async function updateHook(widget, originalUpdate, ...rest) {
128
172
  plugin.isRouteActivated = true;
129
173
  plugin.route.activate(widget, {
130
174
  route: plugin.route,
175
+ context: plugin.context,
131
176
  args: rest
132
177
  });
133
178
  }
@@ -159,9 +204,11 @@ async function resolveRoute(widget) {
159
204
  }
160
205
  async function setupRouterCycle(widget, ...rest) {
161
206
  const route = await resolveRoute(widget);
207
+ const plugin = widget.$in.router;
162
208
  if (isFunction(route.init)) {
163
209
  await route.init(widget, {
164
210
  route,
211
+ context: plugin.context,
165
212
  args: rest
166
213
  });
167
214
  }
@@ -176,12 +223,14 @@ async function tearDownRouterCycle(widget, ...rest) {
176
223
  if (isFunction(route.deactivate) && isRouteActivated === true) {
177
224
  await route.deactivate(widget, {
178
225
  route,
226
+ context: plugin.context,
179
227
  args: rest
180
228
  });
181
229
  }
182
230
  if (isFunction(route.destroy)) {
183
231
  await route.destroy(widget, {
184
232
  route,
233
+ context: plugin.context,
185
234
  args: rest
186
235
  });
187
236
  }
package/lib/index.js CHANGED
@@ -15,10 +15,31 @@ const ENV =
15
15
  : DEV;
16
16
 
17
17
  function createRouter(widget, routes, options) {
18
- widget.$dependencies.router = new UniversalRouter(routes, options);
18
+ let wrappedRoutes = routes.reduce((result, route) => {
19
+ const clonedRoute = { ...route };
20
+
21
+ if (core.isFunction(clonedRoute.action)) {
22
+ const originAction = clonedRoute.action;
23
+ clonedRoute.action = (...rest) => {
24
+ // @TODO UniversalRouter don't parse query from url so context.params are only named route parameters
25
+ // For some application can be helpful to have named route parameters and query parameters merged
26
+ // because link method support both named parameters and query parameters
27
+ widget.$in.router.context = rest[0];
28
+
29
+ return originAction(...rest);
30
+ };
31
+ }
32
+
33
+ result.push(clonedRoute);
34
+
35
+ return result;
36
+ }, []);
37
+
38
+ widget.$dependencies.router = new UniversalRouter(wrappedRoutes, options);
19
39
  widget.$dependencies.link = generateUrls(widget.$dependencies.router, {
20
40
  stringifyQueryParams: (params) => new URLSearchParams(params).toString(),
21
41
  });
42
+ widget.$in.router.options = options;
22
43
  }
23
44
 
24
45
  function routerPlugin() {
@@ -28,6 +49,8 @@ function routerPlugin() {
28
49
 
29
50
  widget.$in.router = {
30
51
  route: null,
52
+ context: null,
53
+ options: {},
31
54
  pathname: null,
32
55
  isMounting: false,
33
56
  isRouteActivated: false,
@@ -69,6 +92,20 @@ function routerPlugin() {
69
92
  };
70
93
  }
71
94
 
95
+ function getOrigin(widget) {
96
+ const { protocol, host } = widget.$in.router.options;
97
+
98
+ if (!host) {
99
+ return '';
100
+ }
101
+
102
+ if (!protocol) {
103
+ return `//${host}`;
104
+ }
105
+
106
+ return `${protocol.replace(':', '').trim()}://${host.trim()}`;
107
+ }
108
+
72
109
  function routerAPI() {
73
110
  return {
74
111
  router: {
@@ -76,11 +113,21 @@ function routerAPI() {
76
113
  widget.emit(RouterEvents.REDIRECT, { url, ...data });
77
114
  },
78
115
  link(widget, routeName, data = {}) {
79
- return widget.$dependencies.link(routeName, data);
116
+ const origin = getOrigin(widget);
117
+ const path = widget.$dependencies.link(routeName, data);
118
+
119
+ if (origin && path === '/') {
120
+ return origin;
121
+ }
122
+
123
+ return `${origin}${path}`;
80
124
  },
81
125
  getCurrentRoute(widget) {
82
126
  return widget.$in.router.route;
83
127
  },
128
+ getCurrentContext(widget) {
129
+ return widget.$in.router.context;
130
+ },
84
131
  },
85
132
  };
86
133
  }
@@ -114,6 +161,7 @@ async function loadHook(widget, originalLoad, ...rest) {
114
161
  : Promise.resolve({});
115
162
  const routeStatePromise = plugin.route.load(widget, {
116
163
  route: plugin.route,
164
+ context: plugin.context,
117
165
  args: rest,
118
166
  globalState: globalStatePromise,
119
167
  });
@@ -139,7 +187,11 @@ async function mountHook(widget, originalMount, ...rest) {
139
187
  const result = await originalMount(...rest);
140
188
 
141
189
  if (plugin.isMounting && core.isFunction(plugin.route.init)) {
142
- await plugin.route.init(widget, { route: plugin.route, args: rest });
190
+ await plugin.route.init(widget, {
191
+ route: plugin.route,
192
+ context: plugin.context,
193
+ args: rest,
194
+ });
143
195
  }
144
196
 
145
197
  if (
@@ -148,7 +200,11 @@ async function mountHook(widget, originalMount, ...rest) {
148
200
  !plugin.isRouteActivated
149
201
  ) {
150
202
  plugin.isRouteActivated = true;
151
- plugin.route.activate(widget, { route: plugin.route, args: rest });
203
+ plugin.route.activate(widget, {
204
+ route: plugin.route,
205
+ context: plugin.context,
206
+ args: rest,
207
+ });
152
208
  }
153
209
 
154
210
  plugin.isMounting = false;
@@ -168,7 +224,11 @@ async function updateHook(widget, originalUpdate, ...rest) {
168
224
  !plugin.isRouteActivated
169
225
  ) {
170
226
  plugin.isRouteActivated = true;
171
- plugin.route.activate(widget, { route: plugin.route, args: rest });
227
+ plugin.route.activate(widget, {
228
+ route: plugin.route,
229
+ context: plugin.context,
230
+ args: rest,
231
+ });
172
232
  }
173
233
 
174
234
  return result;
@@ -209,9 +269,10 @@ async function resolveRoute(widget) {
209
269
 
210
270
  async function setupRouterCycle(widget, ...rest) {
211
271
  const route = await resolveRoute(widget);
272
+ const plugin = widget.$in.router;
212
273
 
213
274
  if (core.isFunction(route.init)) {
214
- await route.init(widget, { route, args: rest });
275
+ await route.init(widget, { route, context: plugin.context, args: rest });
215
276
  }
216
277
  }
217
278
 
@@ -222,11 +283,19 @@ async function tearDownRouterCycle(widget, ...rest) {
222
283
 
223
284
  if (route) {
224
285
  if (core.isFunction(route.deactivate) && isRouteActivated === true) {
225
- await route.deactivate(widget, { route, args: rest });
286
+ await route.deactivate(widget, {
287
+ route,
288
+ context: plugin.context,
289
+ args: rest,
290
+ });
226
291
  }
227
292
 
228
293
  if (core.isFunction(route.destroy)) {
229
- await route.destroy(widget, { route, args: rest });
294
+ await route.destroy(widget, {
295
+ route,
296
+ context: plugin.context,
297
+ args: rest,
298
+ });
230
299
  }
231
300
  }
232
301
 
package/lib/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { assignMissingKeys, bindWidgetToFunctions, setDefaultValueForUndefined, hookMethod, isFunction } from '@merkur/core';
1
+ import { isFunction, assignMissingKeys, bindWidgetToFunctions, setDefaultValueForUndefined, hookMethod } from '@merkur/core';
2
2
  import UniversalRouter from 'universal-router';
3
3
  import generateUrls from 'universal-router/generateUrls';
4
4
 
@@ -13,10 +13,31 @@ const ENV =
13
13
  : DEV;
14
14
 
15
15
  function createRouter(widget, routes, options) {
16
- widget.$dependencies.router = new UniversalRouter(routes, options);
16
+ let wrappedRoutes = routes.reduce((result, route) => {
17
+ const clonedRoute = { ...route };
18
+
19
+ if (isFunction(clonedRoute.action)) {
20
+ const originAction = clonedRoute.action;
21
+ clonedRoute.action = (...rest) => {
22
+ // @TODO UniversalRouter don't parse query from url so context.params are only named route parameters
23
+ // For some application can be helpful to have named route parameters and query parameters merged
24
+ // because link method support both named parameters and query parameters
25
+ widget.$in.router.context = rest[0];
26
+
27
+ return originAction(...rest);
28
+ };
29
+ }
30
+
31
+ result.push(clonedRoute);
32
+
33
+ return result;
34
+ }, []);
35
+
36
+ widget.$dependencies.router = new UniversalRouter(wrappedRoutes, options);
17
37
  widget.$dependencies.link = generateUrls(widget.$dependencies.router, {
18
38
  stringifyQueryParams: (params) => new URLSearchParams(params).toString(),
19
39
  });
40
+ widget.$in.router.options = options;
20
41
  }
21
42
 
22
43
  function routerPlugin() {
@@ -26,6 +47,8 @@ function routerPlugin() {
26
47
 
27
48
  widget.$in.router = {
28
49
  route: null,
50
+ context: null,
51
+ options: {},
29
52
  pathname: null,
30
53
  isMounting: false,
31
54
  isRouteActivated: false,
@@ -67,6 +90,20 @@ function routerPlugin() {
67
90
  };
68
91
  }
69
92
 
93
+ function getOrigin(widget) {
94
+ const { protocol, host } = widget.$in.router.options;
95
+
96
+ if (!host) {
97
+ return '';
98
+ }
99
+
100
+ if (!protocol) {
101
+ return `//${host}`;
102
+ }
103
+
104
+ return `${protocol.replace(':', '').trim()}://${host.trim()}`;
105
+ }
106
+
70
107
  function routerAPI() {
71
108
  return {
72
109
  router: {
@@ -74,11 +111,21 @@ function routerAPI() {
74
111
  widget.emit(RouterEvents.REDIRECT, { url, ...data });
75
112
  },
76
113
  link(widget, routeName, data = {}) {
77
- return widget.$dependencies.link(routeName, data);
114
+ const origin = getOrigin(widget);
115
+ const path = widget.$dependencies.link(routeName, data);
116
+
117
+ if (origin && path === '/') {
118
+ return origin;
119
+ }
120
+
121
+ return `${origin}${path}`;
78
122
  },
79
123
  getCurrentRoute(widget) {
80
124
  return widget.$in.router.route;
81
125
  },
126
+ getCurrentContext(widget) {
127
+ return widget.$in.router.context;
128
+ },
82
129
  },
83
130
  };
84
131
  }
@@ -112,6 +159,7 @@ async function loadHook(widget, originalLoad, ...rest) {
112
159
  : Promise.resolve({});
113
160
  const routeStatePromise = plugin.route.load(widget, {
114
161
  route: plugin.route,
162
+ context: plugin.context,
115
163
  args: rest,
116
164
  globalState: globalStatePromise,
117
165
  });
@@ -137,7 +185,11 @@ async function mountHook(widget, originalMount, ...rest) {
137
185
  const result = await originalMount(...rest);
138
186
 
139
187
  if (plugin.isMounting && isFunction(plugin.route.init)) {
140
- await plugin.route.init(widget, { route: plugin.route, args: rest });
188
+ await plugin.route.init(widget, {
189
+ route: plugin.route,
190
+ context: plugin.context,
191
+ args: rest,
192
+ });
141
193
  }
142
194
 
143
195
  if (
@@ -146,7 +198,11 @@ async function mountHook(widget, originalMount, ...rest) {
146
198
  !plugin.isRouteActivated
147
199
  ) {
148
200
  plugin.isRouteActivated = true;
149
- plugin.route.activate(widget, { route: plugin.route, args: rest });
201
+ plugin.route.activate(widget, {
202
+ route: plugin.route,
203
+ context: plugin.context,
204
+ args: rest,
205
+ });
150
206
  }
151
207
 
152
208
  plugin.isMounting = false;
@@ -166,7 +222,11 @@ async function updateHook(widget, originalUpdate, ...rest) {
166
222
  !plugin.isRouteActivated
167
223
  ) {
168
224
  plugin.isRouteActivated = true;
169
- plugin.route.activate(widget, { route: plugin.route, args: rest });
225
+ plugin.route.activate(widget, {
226
+ route: plugin.route,
227
+ context: plugin.context,
228
+ args: rest,
229
+ });
170
230
  }
171
231
 
172
232
  return result;
@@ -207,9 +267,10 @@ async function resolveRoute(widget) {
207
267
 
208
268
  async function setupRouterCycle(widget, ...rest) {
209
269
  const route = await resolveRoute(widget);
270
+ const plugin = widget.$in.router;
210
271
 
211
272
  if (isFunction(route.init)) {
212
- await route.init(widget, { route, args: rest });
273
+ await route.init(widget, { route, context: plugin.context, args: rest });
213
274
  }
214
275
  }
215
276
 
@@ -220,11 +281,19 @@ async function tearDownRouterCycle(widget, ...rest) {
220
281
 
221
282
  if (route) {
222
283
  if (isFunction(route.deactivate) && isRouteActivated === true) {
223
- await route.deactivate(widget, { route, args: rest });
284
+ await route.deactivate(widget, {
285
+ route,
286
+ context: plugin.context,
287
+ args: rest,
288
+ });
224
289
  }
225
290
 
226
291
  if (isFunction(route.destroy)) {
227
- await route.destroy(widget, { route, args: rest });
292
+ await route.destroy(widget, {
293
+ route,
294
+ context: plugin.context,
295
+ args: rest,
296
+ });
228
297
  }
229
298
  }
230
299
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@merkur/plugin-router",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "description": "Merkur router plugin.",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -56,9 +56,9 @@
56
56
  },
57
57
  "homepage": "https://merkur.js.org/",
58
58
  "devDependencies": {
59
- "@merkur/core": "^0.36.0",
60
- "@merkur/plugin-component": "^0.36.0",
61
- "@merkur/plugin-event-emitter": "^0.36.0"
59
+ "@merkur/core": "^0.37.0",
60
+ "@merkur/plugin-component": "^0.37.0",
61
+ "@merkur/plugin-event-emitter": "^0.37.0"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "@merkur/core": "*",
@@ -68,5 +68,5 @@
68
68
  "dependencies": {
69
69
  "universal-router": "^9.1.0"
70
70
  },
71
- "gitHead": "2471f91d8249ae75e49b2a0da8d0deb93062f014"
71
+ "gitHead": "af826493e5ed4b37602dd43ce89a59baeeb1bada"
72
72
  }