@merkur/plugin-router 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +56 -0
- package/jest.config.js +5 -0
- package/lib/RouterEvents.cjs +9 -0
- package/lib/RouterEvents.es5.js +1 -0
- package/lib/RouterEvents.es9.cjs +9 -0
- package/lib/RouterEvents.es9.mjs +4 -0
- package/lib/RouterEvents.js +9 -0
- package/lib/RouterEvents.mjs +5 -0
- package/lib/index.cjs +249 -0
- package/lib/index.es5.js +1 -0
- package/lib/index.es9.cjs +246 -0
- package/lib/index.es9.mjs +226 -0
- package/lib/index.js +249 -0
- package/lib/index.mjs +239 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<center>
|
|
2
|
+
<h1 style="font-family: Helvetica, Arial, sans-serif; font-size:60px;">Merkur</h1>
|
|
3
|
+
</center>
|
|
4
|
+
|
|
5
|
+
[](https://travis-ci.com/mjancarik/merkur)
|
|
6
|
+
[](https://www.npmjs.com/package/@merkur/core)
|
|
7
|
+

|
|
8
|
+
[](https://github.com/prettier/prettier)
|
|
9
|
+
|
|
10
|
+
# Merkur
|
|
11
|
+
|
|
12
|
+
The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices. It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of four predefined template's library [React](https://reactjs.org/), [Preact](https://preactjs.com/), [hyperHTML](https://viperhtml.js.org/hyper.html) and [µhtml](https://github.com/WebReflection/uhtml#readme) but you can easily extend for others.
|
|
13
|
+
|
|
14
|
+
## Getting started
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @merkur/create-widget <name>
|
|
18
|
+
|
|
19
|
+
cd name
|
|
20
|
+
|
|
21
|
+
npm run dev // Point your browser at http://localhost:4444/
|
|
22
|
+
```
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img alt="Merkur example, hello widget" src="https://raw.githubusercontent.com/mjancarik/merkur/master/images/hello-widget.png" />
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
You can see live [demo](https://merkur.js.org/demo).
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
Point your browser at `http://localhost:4444/widget`.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"name":"my-widget",
|
|
36
|
+
"version":"0.0.1",
|
|
37
|
+
"props":{},
|
|
38
|
+
"state":{"counter":0},
|
|
39
|
+
"assets":[
|
|
40
|
+
{
|
|
41
|
+
"name": "widget.js",
|
|
42
|
+
"type": "script",
|
|
43
|
+
"source": {
|
|
44
|
+
"es9": "http://localhost:4444/static/es9/widget.6961af42bfa3596bb147.js",
|
|
45
|
+
"es5": "http://localhost:4444/static/es5/widget.31c5090d8c961e43fade.js"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "widget.css",
|
|
50
|
+
"type": "stylesheet",
|
|
51
|
+
"source": "http://localhost:4444/static/es9/widget.814e0cb568c7ddc0725d.css"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"html":"\n <div class=\"merkur__page\">\n <div class=\"merkur__headline\">\n <div class=\"merkur__view\">\n \n <div class=\"merkur__icon\">\n <img src=\"http://localhost:4444/static/merkur-icon.png\" alt=\"Merkur\">\n </div>\n \n \n <h1>Welcome to <a href=\"https://github.com/mjancarik/merkur\">MERKUR</a>,<br> a javascript library for front-end microservices.</h1>\n \n \n <p>The widget's name is <strong>my-widget@0.0.1</strong>.</p>\n \n </div>\n </div>\n <div class=\"merkur__view\">\n \n <div>\n <h2>Counter widget:</h2>\n <p>Count: 0</p>\n <button onclick=\"return ((...rest) => {\n return originalFunction(widget, ...rest);\n }).call(this, event)\">\n increase counter\n </button>\n <button onclick=\"return ((...rest) => {\n return originalFunction(widget, ...rest);\n }).call(this, event)\">\n reset counter\n </button>\n </div>\n \n </div>\n </div>\n "
|
|
55
|
+
}
|
|
56
|
+
```
|
package/jest.config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/es.object.define-property.js"),require("core-js/modules/es.object.freeze.js"),Object.defineProperty(exports,"__esModule",{value:!0});var e=Object.freeze({REDIRECT:"@merkur/plugin-router.redirect"});exports.default=e;
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var core = require('@merkur/core');
|
|
6
|
+
var UniversalRouter = require('universal-router');
|
|
7
|
+
var generateUrls = require('universal-router/generateUrls');
|
|
8
|
+
|
|
9
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
|
+
|
|
11
|
+
var UniversalRouter__default = /*#__PURE__*/_interopDefaultLegacy(UniversalRouter);
|
|
12
|
+
var generateUrls__default = /*#__PURE__*/_interopDefaultLegacy(generateUrls);
|
|
13
|
+
|
|
14
|
+
var RouterEvents = Object.freeze({
|
|
15
|
+
REDIRECT: '@merkur/plugin-router.redirect',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const DEV = 'development';
|
|
19
|
+
const ENV =
|
|
20
|
+
typeof process !== 'undefined' && process && process.env
|
|
21
|
+
? process.env.NODE_ENV
|
|
22
|
+
: DEV;
|
|
23
|
+
|
|
24
|
+
function createRouter(widget, routes, options) {
|
|
25
|
+
widget.$dependencies.router = new UniversalRouter__default['default'](routes, options);
|
|
26
|
+
widget.$dependencies.link = generateUrls__default['default'](widget.$dependencies.router);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function routerPlugin() {
|
|
30
|
+
return {
|
|
31
|
+
async setup(widget) {
|
|
32
|
+
widget = {
|
|
33
|
+
...routerAPI(),
|
|
34
|
+
...widget,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
widget.$in.router = {
|
|
38
|
+
route: null,
|
|
39
|
+
pathname: null,
|
|
40
|
+
isMounting: false,
|
|
41
|
+
isRouteActivated: false,
|
|
42
|
+
isBootstrapCalled: false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
core.bindWidgetToFunctions(widget, widget.router);
|
|
46
|
+
|
|
47
|
+
return widget;
|
|
48
|
+
},
|
|
49
|
+
async create(widget) {
|
|
50
|
+
if (ENV === DEV) {
|
|
51
|
+
if (!widget.$in.component) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
'You must install missing plugin: npm i @merkur/plugin-component'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!widget.$in.eventEmitter) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
'You must install missing plugin: npm i @merkur/plugin-event-emitter'
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
widget.$in.component.lifeCycle = core.setDefaultValueForUndefined(
|
|
65
|
+
widget.$in.component.lifeCycle,
|
|
66
|
+
['load'],
|
|
67
|
+
() => {}
|
|
68
|
+
);
|
|
69
|
+
core.hookMethod(widget, '$in.component.lifeCycle.load', loadHook);
|
|
70
|
+
core.hookMethod(widget, 'bootstrap', bootstrapHook);
|
|
71
|
+
core.hookMethod(widget, 'mount', mountHook);
|
|
72
|
+
core.hookMethod(widget, 'unmount', unmountHook);
|
|
73
|
+
core.hookMethod(widget, 'update', updateHook);
|
|
74
|
+
|
|
75
|
+
return widget;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function routerAPI() {
|
|
81
|
+
return {
|
|
82
|
+
router: {
|
|
83
|
+
redirect(widget, url, data = {}) {
|
|
84
|
+
widget.emit(RouterEvents.REDIRECT, { url, ...data });
|
|
85
|
+
},
|
|
86
|
+
link(widget, routeName, data = {}) {
|
|
87
|
+
return widget.$dependencies.link(routeName, data);
|
|
88
|
+
},
|
|
89
|
+
getCurrentRoute(widget) {
|
|
90
|
+
return widget.$in.router.route;
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function bootstrapHook(widget, originalBootstrap, ...rest) {
|
|
97
|
+
if (widget.$in.router.isBootstrapCalled) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
widget.$in.router.isBootstrapCalled = true;
|
|
102
|
+
|
|
103
|
+
return originalBootstrap(...rest);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// hook Component
|
|
107
|
+
async function loadHook(widget, originalLoad, ...rest) {
|
|
108
|
+
const plugin = widget.$in.router;
|
|
109
|
+
|
|
110
|
+
if (!plugin.isMounting && widget.props.pathname !== plugin.pathname) {
|
|
111
|
+
await tearDownRouterCycle(widget, ...rest);
|
|
112
|
+
|
|
113
|
+
await setupRouterCycle(widget, ...rest);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!core.isFunction(plugin.route.load)) {
|
|
117
|
+
throw new Error('The load method is mandatory.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const globalStatePromise = core.isFunction(originalLoad)
|
|
121
|
+
? originalLoad(widget, ...rest)
|
|
122
|
+
: Promise.resolve({});
|
|
123
|
+
const routeStatePromise = plugin.route.load(widget, {
|
|
124
|
+
route: plugin.route,
|
|
125
|
+
args: rest,
|
|
126
|
+
globalState: globalStatePromise,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const [globalState, routeState] = await Promise.all([
|
|
130
|
+
globalStatePromise,
|
|
131
|
+
routeStatePromise,
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
return { ...globalState, ...routeState };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// hook Component
|
|
138
|
+
async function mountHook(widget, originalMount, ...rest) {
|
|
139
|
+
await widget.bootstrap(...rest);
|
|
140
|
+
|
|
141
|
+
const plugin = widget.$in.router;
|
|
142
|
+
if (!plugin.route) {
|
|
143
|
+
await resolveRoute(widget);
|
|
144
|
+
plugin.isMounting = true;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const result = await originalMount(...rest);
|
|
148
|
+
|
|
149
|
+
if (plugin.isMounting && core.isFunction(plugin.route.init)) {
|
|
150
|
+
await plugin.route.init(widget, { route: plugin.route, args: rest });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
core.isFunction(plugin.route.activate) &&
|
|
155
|
+
isClient() &&
|
|
156
|
+
!plugin.isRouteActivated
|
|
157
|
+
) {
|
|
158
|
+
plugin.isRouteActivated = true;
|
|
159
|
+
plugin.route.activate(widget, { route: plugin.route, args: rest });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
plugin.isMounting = false;
|
|
163
|
+
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// hook Component
|
|
168
|
+
async function updateHook(widget, originalUpdate, ...rest) {
|
|
169
|
+
const result = await originalUpdate(...rest);
|
|
170
|
+
|
|
171
|
+
const plugin = widget.$in.router;
|
|
172
|
+
|
|
173
|
+
if (
|
|
174
|
+
core.isFunction(plugin.route.activate) &&
|
|
175
|
+
isClient() &&
|
|
176
|
+
!plugin.isRouteActivated
|
|
177
|
+
) {
|
|
178
|
+
plugin.isRouteActivated = true;
|
|
179
|
+
plugin.route.activate(widget, { route: plugin.route, args: rest });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// hook Component
|
|
186
|
+
async function unmountHook(widget, originalUnmount, ...rest) {
|
|
187
|
+
const result = await originalUnmount(...rest);
|
|
188
|
+
|
|
189
|
+
await tearDownRouterCycle(widget, ...rest);
|
|
190
|
+
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async function resolveRoute(widget) {
|
|
195
|
+
if (ENV === DEV) {
|
|
196
|
+
if (!widget.props.pathname) {
|
|
197
|
+
throw new Error('The props pathname is not defined.');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!widget.$dependencies.router) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
'You must add calling of createRouter(widget, routes, options) to widget.setup method.'
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const route = await widget.$dependencies.router.resolve({
|
|
208
|
+
pathname: widget.props.pathname,
|
|
209
|
+
widget,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
widget.$in.router.route = route;
|
|
213
|
+
widget.$in.router.pathname = widget.props.pathname;
|
|
214
|
+
|
|
215
|
+
return route;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function setupRouterCycle(widget, ...rest) {
|
|
219
|
+
const route = await resolveRoute(widget);
|
|
220
|
+
|
|
221
|
+
if (core.isFunction(route.init)) {
|
|
222
|
+
await route.init(widget, { route, args: rest });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function tearDownRouterCycle(widget, ...rest) {
|
|
227
|
+
const plugin = widget.$in.router;
|
|
228
|
+
|
|
229
|
+
const { route, isRouteActivated } = plugin;
|
|
230
|
+
|
|
231
|
+
if (route) {
|
|
232
|
+
if (core.isFunction(route.deactivate) && isRouteActivated === true) {
|
|
233
|
+
await route.deactivate(widget, { route, args: rest });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (core.isFunction(route.destroy)) {
|
|
237
|
+
await route.destroy(widget, { route, args: rest });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
plugin.isRouteActivated = false;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function isClient() {
|
|
245
|
+
return typeof window !== 'undefined';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
exports.createRouter = createRouter;
|
|
249
|
+
exports.routerPlugin = routerPlugin;
|
package/lib/index.es5.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function e(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,r){var t=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==t)return;var n,o,u=[],i=!0,a=!1;try{for(t=t.call(e);!(i=(n=t.next()).done)&&(u.push(n.value),!r||u.length!==r);i=!0);}catch(e){a=!0,o=e}finally{try{i||null==t.return||t.return()}finally{if(a)throw o}}return u}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=new Array(r);t<r;t++)n[t]=e[t];return n}function t(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function n(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?t(Object(n),!0).forEach((function(r){o(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):t(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function u(e,r,t,n,o,u,i){try{var a=e[u](i),s=a.value}catch(e){return void t(e)}a.done?r(s):Promise.resolve(s).then(n,o)}function i(e){return function(){var r=this,t=arguments;return new Promise((function(n,o){var i=e.apply(r,t);function a(e){u(i,n,o,a,s,"next",e)}function s(e){u(i,n,o,a,s,"throw",e)}a(void 0)}))}}function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}require("regenerator-runtime/runtime.js"),require("core-js/modules/es.object.define-property.js"),require("core-js/modules/es.object.freeze.js"),require("core-js/modules/es.string.link.js"),require("core-js/modules/es.array.concat.js"),require("core-js/modules/es.object.to-string.js"),require("core-js/modules/es.promise.js"),require("core-js/modules/es.array.iterator.js"),require("core-js/modules/es.string.iterator.js"),require("core-js/modules/web.dom-collections.iterator.js"),require("core-js/modules/es.symbol.js"),require("core-js/modules/es.symbol.description.js"),require("core-js/modules/es.symbol.iterator.js"),require("core-js/modules/es.object.keys.js"),require("core-js/modules/es.array.filter.js"),require("core-js/modules/es.object.get-own-property-descriptor.js"),require("core-js/modules/es.array.for-each.js"),require("core-js/modules/web.dom-collections.for-each.js"),require("core-js/modules/es.object.get-own-property-descriptors.js"),require("core-js/modules/es.object.define-properties.js"),require("core-js/modules/es.array.is-array.js"),require("core-js/modules/es.array.slice.js"),require("core-js/modules/es.function.name.js"),require("core-js/modules/es.array.from.js"),Object.defineProperty(exports,"__esModule",{value:!0});var s=require("@merkur/core"),c=require("universal-router"),p=require("universal-router/generateUrls");function l(e){return e&&"object"===a(e)&&"default"in e?e:{default:e}}var f=l(c),d=l(p),m=Object.freeze({REDIRECT:"@merkur/plugin-router.redirect"}),y="development",h="undefined"!=typeof process&&process&&process.env?process.env.NODE_ENV:y;function b(e,r){return g.apply(this,arguments)}function g(){return g=i(regeneratorRuntime.mark((function e(r,t){var n,o,u,i=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!r.$in.router.isBootstrapCalled){e.next=2;break}return e.abrupt("return");case 2:for(r.$in.router.isBootstrapCalled=!0,n=i.length,o=new Array(n>2?n-2:0),u=2;u<n;u++)o[u-2]=i[u];return e.abrupt("return",t.apply(void 0,o));case 5:case"end":return e.stop()}}),e)}))),g.apply(this,arguments)}function v(e,r){return j.apply(this,arguments)}function j(){return j=i(regeneratorRuntime.mark((function r(t,o){var u,i,a,c,p,l,f,d,m,y,h=arguments;return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:for(u=t.$in.router,i=h.length,a=new Array(i>2?i-2:0),c=2;c<i;c++)a[c-2]=h[c];if(u.isMounting||t.props.pathname===u.pathname){r.next=7;break}return r.next=5,S.apply(void 0,[t].concat(a));case 5:return r.next=7,E.apply(void 0,[t].concat(a));case 7:if(s.isFunction(u.route.load)){r.next=9;break}throw new Error("The load method is mandatory.");case 9:return p=s.isFunction(o)?o.apply(void 0,[t].concat(a)):Promise.resolve({}),l=u.route.load(t,{route:u.route,args:a,globalState:p}),r.next=13,Promise.all([p,l]);case 13:return f=r.sent,d=e(f,2),m=d[0],y=d[1],r.abrupt("return",n(n({},m),y));case 18:case"end":return r.stop()}}),r)}))),j.apply(this,arguments)}function w(e,r){return x.apply(this,arguments)}function x(){return x=i(regeneratorRuntime.mark((function e(r,t){var n,o,u,i,a,c=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:for(n=c.length,o=new Array(n>2?n-2:0),u=2;u<n;u++)o[u-2]=c[u];return e.next=3,r.bootstrap.apply(r,o);case 3:if((i=r.$in.router).route){e.next=8;break}return e.next=7,$(r);case 7:i.isMounting=!0;case 8:return e.next=10,t.apply(void 0,o);case 10:if(a=e.sent,!i.isMounting||!s.isFunction(i.route.init)){e.next=14;break}return e.next=14,i.route.init(r,{route:i.route,args:o});case 14:return s.isFunction(i.route.activate)&&C()&&!i.isRouteActivated&&(i.isRouteActivated=!0,i.route.activate(r,{route:i.route,args:o})),i.isMounting=!1,e.abrupt("return",a);case 17:case"end":return e.stop()}}),e)}))),x.apply(this,arguments)}function k(e,r){return R.apply(this,arguments)}function R(){return R=i(regeneratorRuntime.mark((function e(r,t){var n,o,u,i,a,c=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:for(n=c.length,o=new Array(n>2?n-2:0),u=2;u<n;u++)o[u-2]=c[u];return e.next=3,t.apply(void 0,o);case 3:return i=e.sent,a=r.$in.router,s.isFunction(a.route.activate)&&C()&&!a.isRouteActivated&&(a.isRouteActivated=!0,a.route.activate(r,{route:a.route,args:o})),e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)}))),R.apply(this,arguments)}function q(e,r){return O.apply(this,arguments)}function O(){return O=i(regeneratorRuntime.mark((function e(r,t){var n,o,u,i,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:for(n=a.length,o=new Array(n>2?n-2:0),u=2;u<n;u++)o[u-2]=a[u];return e.next=3,t.apply(void 0,o);case 3:return i=e.sent,e.next=6,S.apply(void 0,[r].concat(o));case 6:return e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)}))),O.apply(this,arguments)}function $(e){return A.apply(this,arguments)}function A(){return(A=i(regeneratorRuntime.mark((function e(r){var t;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(h!==y){e.next=5;break}if(r.props.pathname){e.next=3;break}throw new Error("The props pathname is not defined.");case 3:if(r.$dependencies.router){e.next=5;break}throw new Error("You must add calling of createRouter(widget, routes, options) to widget.setup method.");case 5:return e.next=7,r.$dependencies.router.resolve({pathname:r.props.pathname,widget:r});case 7:return t=e.sent,r.$in.router.route=t,r.$in.router.pathname=r.props.pathname,e.abrupt("return",t);case 11:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function E(e){return P.apply(this,arguments)}function P(){return P=i(regeneratorRuntime.mark((function e(r){var t,n,o,u,i=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,$(r);case 2:if(t=e.sent,!s.isFunction(t.init)){e.next=7;break}for(n=i.length,o=new Array(n>1?n-1:0),u=1;u<n;u++)o[u-1]=i[u];return e.next=7,t.init(r,{route:t,args:o});case 7:case"end":return e.stop()}}),e)}))),P.apply(this,arguments)}function S(e){return M.apply(this,arguments)}function M(){return M=i(regeneratorRuntime.mark((function e(r){var t,n,o,u,i,a,c=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=r.$in.router,n=t.route,o=t.isRouteActivated,!n){e.next=10;break}for(u=c.length,i=new Array(u>1?u-1:0),a=1;a<u;a++)i[a-1]=c[a];if(!s.isFunction(n.deactivate)||!0!==o){e.next=7;break}return e.next=7,n.deactivate(r,{route:n,args:i});case 7:if(!s.isFunction(n.destroy)){e.next=10;break}return e.next=10,n.destroy(r,{route:n,args:i});case 10:t.isRouteActivated=!1;case 11:case"end":return e.stop()}}),e)}))),M.apply(this,arguments)}function C(){return"undefined"!=typeof window}exports.createRouter=function(e,r,t){e.$dependencies.router=new f.default(r,t),e.$dependencies.link=d.default(e.$dependencies.router)},exports.routerPlugin=function(){return{setup:function(e){return i(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return e=n(n({},{router:{redirect:function(e,r){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};e.emit(m.REDIRECT,n({url:r},t))},link:function(e,r){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return e.$dependencies.link(r,t)},getCurrentRoute:function(e){return e.$in.router.route}}}),e),e.$in.router={route:null,pathname:null,isMounting:!1,isRouteActivated:!1,isBootstrapCalled:!1},s.bindWidgetToFunctions(e,e.router),r.abrupt("return",e);case 4:case"end":return r.stop()}}),r)})))()},create:function(e){return i(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(h!==y){r.next=5;break}if(e.$in.component){r.next=3;break}throw new Error("You must install missing plugin: npm i @merkur/plugin-component");case 3:if(e.$in.eventEmitter){r.next=5;break}throw new Error("You must install missing plugin: npm i @merkur/plugin-event-emitter");case 5:return e.$in.component.lifeCycle=s.setDefaultValueForUndefined(e.$in.component.lifeCycle,["load"],(function(){})),s.hookMethod(e,"$in.component.lifeCycle.load",v),s.hookMethod(e,"bootstrap",b),s.hookMethod(e,"mount",w),s.hookMethod(e,"unmount",q),s.hookMethod(e,"update",k),r.abrupt("return",e);case 12:case"end":return r.stop()}}),r)})))()}}};
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var core = require('@merkur/core');
|
|
8
|
+
|
|
9
|
+
var UniversalRouter = require('universal-router');
|
|
10
|
+
|
|
11
|
+
var generateUrls = require('universal-router/generateUrls');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultLegacy(e) {
|
|
14
|
+
return e && typeof e === 'object' && 'default' in e ? e : {
|
|
15
|
+
'default': e
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var UniversalRouter__default = /*#__PURE__*/_interopDefaultLegacy(UniversalRouter);
|
|
20
|
+
|
|
21
|
+
var generateUrls__default = /*#__PURE__*/_interopDefaultLegacy(generateUrls);
|
|
22
|
+
|
|
23
|
+
var RouterEvents = Object.freeze({
|
|
24
|
+
REDIRECT: '@merkur/plugin-router.redirect'
|
|
25
|
+
});
|
|
26
|
+
const DEV = 'development';
|
|
27
|
+
const ENV = typeof process !== 'undefined' && process && process.env ? process.env.NODE_ENV : DEV;
|
|
28
|
+
|
|
29
|
+
function createRouter(widget, routes, options) {
|
|
30
|
+
widget.$dependencies.router = new UniversalRouter__default['default'](routes, options);
|
|
31
|
+
widget.$dependencies.link = generateUrls__default['default'](widget.$dependencies.router);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function routerPlugin() {
|
|
35
|
+
return {
|
|
36
|
+
async setup(widget) {
|
|
37
|
+
widget = { ...routerAPI(),
|
|
38
|
+
...widget
|
|
39
|
+
};
|
|
40
|
+
widget.$in.router = {
|
|
41
|
+
route: null,
|
|
42
|
+
pathname: null,
|
|
43
|
+
isMounting: false,
|
|
44
|
+
isRouteActivated: false,
|
|
45
|
+
isBootstrapCalled: false
|
|
46
|
+
};
|
|
47
|
+
core.bindWidgetToFunctions(widget, widget.router);
|
|
48
|
+
return widget;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async create(widget) {
|
|
52
|
+
if (ENV === DEV) {
|
|
53
|
+
if (!widget.$in.component) {
|
|
54
|
+
throw new Error('You must install missing plugin: npm i @merkur/plugin-component');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!widget.$in.eventEmitter) {
|
|
58
|
+
throw new Error('You must install missing plugin: npm i @merkur/plugin-event-emitter');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
widget.$in.component.lifeCycle = core.setDefaultValueForUndefined(widget.$in.component.lifeCycle, ['load'], () => {});
|
|
63
|
+
core.hookMethod(widget, '$in.component.lifeCycle.load', loadHook);
|
|
64
|
+
core.hookMethod(widget, 'bootstrap', bootstrapHook);
|
|
65
|
+
core.hookMethod(widget, 'mount', mountHook);
|
|
66
|
+
core.hookMethod(widget, 'unmount', unmountHook);
|
|
67
|
+
core.hookMethod(widget, 'update', updateHook);
|
|
68
|
+
return widget;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function routerAPI() {
|
|
75
|
+
return {
|
|
76
|
+
router: {
|
|
77
|
+
redirect(widget, url, data = {}) {
|
|
78
|
+
widget.emit(RouterEvents.REDIRECT, {
|
|
79
|
+
url,
|
|
80
|
+
...data
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
link(widget, routeName, data = {}) {
|
|
85
|
+
return widget.$dependencies.link(routeName, data);
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
getCurrentRoute(widget) {
|
|
89
|
+
return widget.$in.router.route;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function bootstrapHook(widget, originalBootstrap, ...rest) {
|
|
97
|
+
if (widget.$in.router.isBootstrapCalled) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
widget.$in.router.isBootstrapCalled = true;
|
|
102
|
+
return originalBootstrap(...rest);
|
|
103
|
+
} // hook Component
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async function loadHook(widget, originalLoad, ...rest) {
|
|
107
|
+
const plugin = widget.$in.router;
|
|
108
|
+
|
|
109
|
+
if (!plugin.isMounting && widget.props.pathname !== plugin.pathname) {
|
|
110
|
+
await tearDownRouterCycle(widget, ...rest);
|
|
111
|
+
await setupRouterCycle(widget, ...rest);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!core.isFunction(plugin.route.load)) {
|
|
115
|
+
throw new Error('The load method is mandatory.');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const globalStatePromise = core.isFunction(originalLoad) ? originalLoad(widget, ...rest) : Promise.resolve({});
|
|
119
|
+
const routeStatePromise = plugin.route.load(widget, {
|
|
120
|
+
route: plugin.route,
|
|
121
|
+
args: rest,
|
|
122
|
+
globalState: globalStatePromise
|
|
123
|
+
});
|
|
124
|
+
const [globalState, routeState] = await Promise.all([globalStatePromise, routeStatePromise]);
|
|
125
|
+
return { ...globalState,
|
|
126
|
+
...routeState
|
|
127
|
+
};
|
|
128
|
+
} // hook Component
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
async function mountHook(widget, originalMount, ...rest) {
|
|
132
|
+
await widget.bootstrap(...rest);
|
|
133
|
+
const plugin = widget.$in.router;
|
|
134
|
+
|
|
135
|
+
if (!plugin.route) {
|
|
136
|
+
await resolveRoute(widget);
|
|
137
|
+
plugin.isMounting = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const result = await originalMount(...rest);
|
|
141
|
+
|
|
142
|
+
if (plugin.isMounting && core.isFunction(plugin.route.init)) {
|
|
143
|
+
await plugin.route.init(widget, {
|
|
144
|
+
route: plugin.route,
|
|
145
|
+
args: rest
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (core.isFunction(plugin.route.activate) && isClient() && !plugin.isRouteActivated) {
|
|
150
|
+
plugin.isRouteActivated = true;
|
|
151
|
+
plugin.route.activate(widget, {
|
|
152
|
+
route: plugin.route,
|
|
153
|
+
args: rest
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
plugin.isMounting = false;
|
|
158
|
+
return result;
|
|
159
|
+
} // hook Component
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
async function updateHook(widget, originalUpdate, ...rest) {
|
|
163
|
+
const result = await originalUpdate(...rest);
|
|
164
|
+
const plugin = widget.$in.router;
|
|
165
|
+
|
|
166
|
+
if (core.isFunction(plugin.route.activate) && isClient() && !plugin.isRouteActivated) {
|
|
167
|
+
plugin.isRouteActivated = true;
|
|
168
|
+
plugin.route.activate(widget, {
|
|
169
|
+
route: plugin.route,
|
|
170
|
+
args: rest
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return result;
|
|
175
|
+
} // hook Component
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
async function unmountHook(widget, originalUnmount, ...rest) {
|
|
179
|
+
const result = await originalUnmount(...rest);
|
|
180
|
+
await tearDownRouterCycle(widget, ...rest);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function resolveRoute(widget) {
|
|
185
|
+
if (ENV === DEV) {
|
|
186
|
+
if (!widget.props.pathname) {
|
|
187
|
+
throw new Error('The props pathname is not defined.');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!widget.$dependencies.router) {
|
|
191
|
+
throw new Error('You must add calling of createRouter(widget, routes, options) to widget.setup method.');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const route = await widget.$dependencies.router.resolve({
|
|
196
|
+
pathname: widget.props.pathname,
|
|
197
|
+
widget
|
|
198
|
+
});
|
|
199
|
+
widget.$in.router.route = route;
|
|
200
|
+
widget.$in.router.pathname = widget.props.pathname;
|
|
201
|
+
return route;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function setupRouterCycle(widget, ...rest) {
|
|
205
|
+
const route = await resolveRoute(widget);
|
|
206
|
+
|
|
207
|
+
if (core.isFunction(route.init)) {
|
|
208
|
+
await route.init(widget, {
|
|
209
|
+
route,
|
|
210
|
+
args: rest
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function tearDownRouterCycle(widget, ...rest) {
|
|
216
|
+
const plugin = widget.$in.router;
|
|
217
|
+
const {
|
|
218
|
+
route,
|
|
219
|
+
isRouteActivated
|
|
220
|
+
} = plugin;
|
|
221
|
+
|
|
222
|
+
if (route) {
|
|
223
|
+
if (core.isFunction(route.deactivate) && isRouteActivated === true) {
|
|
224
|
+
await route.deactivate(widget, {
|
|
225
|
+
route,
|
|
226
|
+
args: rest
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (core.isFunction(route.destroy)) {
|
|
231
|
+
await route.destroy(widget, {
|
|
232
|
+
route,
|
|
233
|
+
args: rest
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
plugin.isRouteActivated = false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function isClient() {
|
|
242
|
+
return typeof window !== 'undefined';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
exports.createRouter = createRouter;
|
|
246
|
+
exports.routerPlugin = routerPlugin;
|