@worktile/planet 12.1.2 → 14.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +422 -0
  2. package/LICENSE +21 -0
  3. package/README.md +348 -0
  4. package/application/planet-application-loader.d.ts +3 -0
  5. package/application/planet-application-loader.d.ts.map +1 -1
  6. package/application/planet-application.service.d.ts +3 -0
  7. package/application/planet-application.service.d.ts.map +1 -1
  8. package/assets-loader.d.ts +3 -0
  9. package/assets-loader.d.ts.map +1 -1
  10. package/component/planet-component-loader.d.ts +3 -0
  11. package/component/planet-component-loader.d.ts.map +1 -1
  12. package/empty/empty.component.d.ts +3 -0
  13. package/empty/empty.component.d.ts.map +1 -1
  14. package/esm2020/application/planet-application-loader.mjs +454 -0
  15. package/esm2020/application/planet-application-ref.mjs +94 -0
  16. package/{esm2015/application/planet-application.service.js → esm2020/application/planet-application.service.mjs} +9 -11
  17. package/{esm2015/application/portal-application.js → esm2020/application/portal-application.mjs} +0 -0
  18. package/{esm2015/assets-loader.js → esm2020/assets-loader.mjs} +9 -10
  19. package/esm2020/component/planet-component-loader.mjs +153 -0
  20. package/{esm2015/component/planet-component-ref.js → esm2020/component/planet-component-ref.mjs} +0 -0
  21. package/{esm2015/component/plant-component.config.js → esm2020/component/plant-component.config.mjs} +0 -0
  22. package/{esm2015/debug.js → esm2020/debug.mjs} +0 -0
  23. package/esm2020/empty/empty.component.mjs +15 -0
  24. package/{esm2015/global-event-dispatcher.js → esm2020/global-event-dispatcher.mjs} +9 -10
  25. package/esm2020/global-planet.mjs +53 -0
  26. package/{esm2015/helpers.js → esm2020/helpers.mjs} +0 -0
  27. package/esm2020/module.mjs +31 -0
  28. package/{esm2015/planet.class.js → esm2020/planet.class.mjs} +0 -0
  29. package/esm2020/planet.mjs +91 -0
  30. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  31. package/{esm2015/sandbox/constants.js → esm2020/sandbox/constants.mjs} +0 -0
  32. package/{esm2015/sandbox/exec.js → esm2020/sandbox/exec.mjs} +0 -0
  33. package/{esm2015/sandbox/index.js → esm2020/sandbox/index.mjs} +0 -0
  34. package/{esm2015/sandbox/proxy/patches/document.js → esm2020/sandbox/proxy/patches/document.mjs} +0 -0
  35. package/{esm2015/sandbox/proxy/patches/eventListener.js → esm2020/sandbox/proxy/patches/eventListener.mjs} +0 -0
  36. package/{esm2015/sandbox/proxy/patches/index.js → esm2020/sandbox/proxy/patches/index.mjs} +0 -0
  37. package/{esm2015/sandbox/proxy/patches/storage.js → esm2020/sandbox/proxy/patches/storage.mjs} +0 -0
  38. package/{esm2015/sandbox/proxy/patches/timer.js → esm2020/sandbox/proxy/patches/timer.mjs} +0 -0
  39. package/{esm2015/sandbox/proxy/proxies/common.js → esm2020/sandbox/proxy/proxies/common.mjs} +2 -2
  40. package/{esm2015/sandbox/proxy/proxies/document.js → esm2020/sandbox/proxy/proxies/document.mjs} +0 -0
  41. package/{esm2015/sandbox/proxy/proxies/window.js → esm2020/sandbox/proxy/proxies/window.mjs} +5 -2
  42. package/{esm2015/sandbox/proxy/proxy-sandbox.js → esm2020/sandbox/proxy/proxy-sandbox.mjs} +2 -2
  43. package/{esm2015/sandbox/proxy/types.js → esm2020/sandbox/proxy/types.mjs} +0 -0
  44. package/{esm2015/sandbox/sandbox.js → esm2020/sandbox/sandbox.mjs} +0 -0
  45. package/{esm2015/sandbox/snapshot/snapshot-sandbox.js → esm2020/sandbox/snapshot/snapshot-sandbox.mjs} +0 -0
  46. package/{esm2015/sandbox/types.js → esm2020/sandbox/types.mjs} +0 -0
  47. package/esm2020/worktile-planet.mjs +5 -0
  48. package/fesm2015/{worktile-planet.js → worktile-planet.mjs} +231 -230
  49. package/fesm2015/worktile-planet.mjs.map +1 -0
  50. package/fesm2020/worktile-planet.mjs +2046 -0
  51. package/fesm2020/worktile-planet.mjs.map +1 -0
  52. package/global-event-dispatcher.d.ts +3 -0
  53. package/global-event-dispatcher.d.ts.map +1 -1
  54. package/index.d.ts +6 -0
  55. package/module.d.ts +6 -0
  56. package/module.d.ts.map +1 -1
  57. package/package.json +24 -12
  58. package/planet.d.ts +3 -0
  59. package/planet.d.ts.map +1 -1
  60. package/worktile-planet.d.ts.map +1 -1
  61. package/application/planet-application-loader.ngfactory.d.ts.map +0 -1
  62. package/application/planet-application.service.ngfactory.d.ts.map +0 -1
  63. package/assets-loader.ngfactory.d.ts.map +0 -1
  64. package/bundles/worktile-planet.umd.js +0 -2564
  65. package/bundles/worktile-planet.umd.js.map +0 -1
  66. package/component/planet-component-loader.ngfactory.d.ts.map +0 -1
  67. package/empty/empty.component.ngfactory.d.ts.map +0 -1
  68. package/esm2015/application/planet-application-loader.js +0 -457
  69. package/esm2015/application/planet-application-ref.js +0 -97
  70. package/esm2015/component/planet-component-loader.js +0 -155
  71. package/esm2015/empty/empty.component.js +0 -10
  72. package/esm2015/global-planet.js +0 -54
  73. package/esm2015/module.js +0 -27
  74. package/esm2015/planet.js +0 -91
  75. package/esm2015/worktile-planet.js +0 -6
  76. package/fesm2015/worktile-planet.js.map +0 -1
  77. package/global-event-dispatcher.ngfactory.d.ts.map +0 -1
  78. package/module.ngfactory.d.ts.map +0 -1
  79. package/planet.ngfactory.d.ts.map +0 -1
  80. package/worktile-planet.d.ts +0 -6
  81. package/worktile-planet.metadata.json +0 -1
@@ -0,0 +1,2046 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Injectable, NgZone, Inject, Optional, Component, NgModule } from '@angular/core';
3
+ import * as i3 from '@angular/router';
4
+ import { Router, NavigationEnd } from '@angular/router';
5
+ import * as i1 from '@angular/common/http';
6
+ import { HttpClientModule } from '@angular/common/http';
7
+ import { map, concatAll, switchMap, take, shareReplay, filter, distinctUntilChanged, catchError, tap, share, startWith, delayWhen } from 'rxjs/operators';
8
+ import { Observable, of, concat, forkJoin, from, Subject, timer } from 'rxjs';
9
+ import { PortalInjector, DomPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
10
+ import { DOCUMENT } from '@angular/common';
11
+
12
+ var SwitchModes;
13
+ (function (SwitchModes) {
14
+ SwitchModes["default"] = "default";
15
+ SwitchModes["coexist"] = "coexist";
16
+ })(SwitchModes || (SwitchModes = {}));
17
+ const PLANET_APPLICATIONS = new InjectionToken('PLANET_APPLICATIONS');
18
+
19
+ const ELEMENT_NODE_TYPE = 1;
20
+ function hashCode(str) {
21
+ let hash = 0;
22
+ let chr;
23
+ if (str.length === 0) {
24
+ return hash;
25
+ }
26
+ for (let i = 0; i < str.length; i++) {
27
+ chr = str.charCodeAt(i);
28
+ hash = (hash << 5) - hash + chr;
29
+ hash |= 0; // Convert to 32bit integer
30
+ }
31
+ return hash;
32
+ }
33
+ function getHTMLElement(selector) {
34
+ if (selector instanceof HTMLElement) {
35
+ return selector;
36
+ }
37
+ else {
38
+ return document.querySelector(selector);
39
+ }
40
+ }
41
+ function getTagNameByTemplate(template) {
42
+ const element = createElementByTemplate(template);
43
+ return element ? element.nodeName : '';
44
+ }
45
+ function createElementByTemplate(template) {
46
+ if (!template) {
47
+ return null;
48
+ }
49
+ const element = document.createRange().createContextualFragment(template).firstChild;
50
+ if (element && element.nodeType === ELEMENT_NODE_TYPE) {
51
+ return element;
52
+ }
53
+ else {
54
+ throw new Error(`invalid template '${template}'`);
55
+ }
56
+ }
57
+ function coerceArray(value) {
58
+ return Array.isArray(value) ? value : [value];
59
+ }
60
+ function isEmpty(value) {
61
+ if (!value || value.length === 0) {
62
+ return true;
63
+ }
64
+ else {
65
+ return false;
66
+ }
67
+ }
68
+ function isFunction(value) {
69
+ const type = typeof value;
70
+ return !!value && type === 'function';
71
+ }
72
+ function isObject(val) {
73
+ return val && typeof val === 'object';
74
+ }
75
+ /**
76
+ * Get file name from path
77
+ * 1. "main.js" => "main.js"
78
+ * 2. "assets/scripts/main.js" => "main.js"
79
+ * @param path path
80
+ */
81
+ function getResourceFileName(path) {
82
+ const lastSlashIndex = path.lastIndexOf('/');
83
+ if (lastSlashIndex >= 0) {
84
+ return path.slice(lastSlashIndex + 1);
85
+ }
86
+ else {
87
+ return path;
88
+ }
89
+ }
90
+ /**
91
+ * Build resource path by manifest
92
+ * if manifest is { "main.js": "main.h2sh23abee.js"}
93
+ * 1. "main.js" => "main.h2sh23abee.js"
94
+ * 2. "assets/scripts/main.js" =>"assets/scripts/main.h2sh23abee.js"
95
+ * @param resourceFilePath Resource File Path
96
+ * @param manifestResult manifest
97
+ */
98
+ function buildResourceFilePath(resourceFilePath, manifestResult) {
99
+ const fileName = getResourceFileName(resourceFilePath);
100
+ if (manifestResult[fileName]) {
101
+ return resourceFilePath.replace(fileName, manifestResult[fileName]);
102
+ }
103
+ else {
104
+ return resourceFilePath;
105
+ }
106
+ }
107
+ /**
108
+ * Get static resource full path
109
+ * @param app PlanetApplication
110
+ * @param manifestResult manifest
111
+ */
112
+ function getScriptsAndStylesFullPaths(app, manifestResult) {
113
+ let scripts = app.scripts || [];
114
+ let styles = app.styles || [];
115
+ // combine resource path by manifest
116
+ if (manifestResult) {
117
+ scripts = scripts.map(script => {
118
+ return buildResourceFilePath(script, manifestResult);
119
+ });
120
+ styles = styles.map(style => {
121
+ return buildResourceFilePath(style, manifestResult);
122
+ });
123
+ }
124
+ if (app.resourcePathPrefix) {
125
+ scripts = scripts.map(script => {
126
+ return `${app.resourcePathPrefix}${script}`;
127
+ });
128
+ styles = styles.map(style => {
129
+ return `${app.resourcePathPrefix}${style}`;
130
+ });
131
+ }
132
+ return {
133
+ scripts: scripts,
134
+ styles: styles
135
+ };
136
+ }
137
+
138
+ const PLANET_SANDBOX_WINDOW_WHITELIST = window['___PLANET_SANDBOX_WINDOW_WHITELIST___'];
139
+ const PLANET_SANDBOX_DOCUMENT_WHITELIST = window['___PLANET_SANDBOX_DOCUMENT_WHITELIST___'];
140
+ const SANDBOX_INSTANCE = Symbol.for('PLANET_SANDBOX_INSTANCE');
141
+ const RAW_NODE = Symbol.for('PLANET_RAW_NODE');
142
+ const WINDOW_BIND_FN = Symbol.for('PLANET_WINDOW_BIND_FN');
143
+ const DOCUMENT_BIND_FN = Symbol.for('PLANET_DOCUMENT_BIND_FN');
144
+
145
+ const rawHasOwnProperty = Object.prototype.hasOwnProperty;
146
+ function hasOwnProp(obj, key) {
147
+ return rawHasOwnProperty.call(obj, key);
148
+ }
149
+ function isValueDescriptor(desc) {
150
+ if (desc === undefined) {
151
+ return false;
152
+ }
153
+ return 'value' in desc || 'writable' in desc;
154
+ }
155
+ function isAccessorDescriptor(desc) {
156
+ if (desc === undefined) {
157
+ return false;
158
+ }
159
+ return 'get' in desc || 'set' in desc;
160
+ }
161
+ function isNonWriteableValue(desc) {
162
+ return desc && desc.configurable === false && 'value' in desc && desc.writable === false;
163
+ }
164
+ function isInvalidSetAccessor(desc) {
165
+ if (desc && desc.configurable === false && 'set' in desc && desc.set === undefined) {
166
+ return true;
167
+ }
168
+ else {
169
+ return false;
170
+ }
171
+ }
172
+ function isInvalidGetAccessor(desc) {
173
+ if (desc && desc.configurable === false && 'get' in desc && desc.get === undefined) {
174
+ return true;
175
+ }
176
+ else {
177
+ return false;
178
+ }
179
+ }
180
+ function transferParams(args) {
181
+ args = Array.isArray(args) ? args : Array.from(args);
182
+ return args.map(arg => {
183
+ return arg[RAW_NODE] ? arg[RAW_NODE] : arg;
184
+ });
185
+ }
186
+ const buildInProps = ['length', 'caller', 'callee', 'arguments', 'prototype', Symbol.hasInstance];
187
+ function transferProps(o, n) {
188
+ for (const key of Reflect.ownKeys(o)) {
189
+ if (buildInProps.includes(key)) {
190
+ continue;
191
+ }
192
+ const desc = Object.getOwnPropertyDescriptor(n, key);
193
+ if (desc && desc.writable) {
194
+ n[key] = o[key];
195
+ }
196
+ }
197
+ }
198
+ function bind(fn, context) {
199
+ const fNOP = function () { };
200
+ function bound() {
201
+ const args = transferParams(arguments);
202
+ if (this instanceof bound) {
203
+ const obj = new fn(...args);
204
+ Object.setPrototypeOf(obj, bound.prototype);
205
+ return obj;
206
+ }
207
+ else {
208
+ return fn.apply(context, args);
209
+ }
210
+ }
211
+ bound.$native = fn;
212
+ transferProps(fn, bound);
213
+ if (fn.prototype) {
214
+ fNOP.prototype = fn.prototype;
215
+ }
216
+ bound.prototype = new fNOP();
217
+ if (Symbol.hasInstance) {
218
+ Object.defineProperty(bound, Symbol.hasInstance, {
219
+ configurable: true,
220
+ value(instance) {
221
+ const op = fn.prototype;
222
+ return isObject(op) || typeof op === 'function' ? instance instanceof fn : false;
223
+ }
224
+ });
225
+ }
226
+ return bound;
227
+ }
228
+ function createFakeObject(target, writableKeys) {
229
+ const fakeObject = {};
230
+ const propertyMap = {};
231
+ const storageBox = Object.create(null);
232
+ const propertyNames = Object.getOwnPropertyNames(target);
233
+ const def = (p) => {
234
+ const descriptor = Object.getOwnPropertyDescriptor(target, p);
235
+ if (descriptor?.configurable) {
236
+ const hasGetter = hasOwnProp(descriptor, 'get');
237
+ const hasSetter = hasOwnProp(descriptor, 'set');
238
+ const canWritable = writableKeys && writableKeys.length > 0 && writableKeys.includes(p);
239
+ if (hasGetter) {
240
+ descriptor.get = () => (hasOwnProp(storageBox, p) ? storageBox[p] : target[p]);
241
+ }
242
+ if (hasSetter) {
243
+ descriptor.set = val => {
244
+ storageBox[p] = val;
245
+ return true;
246
+ };
247
+ }
248
+ if (canWritable) {
249
+ if (descriptor.writable === false) {
250
+ descriptor.writable = true;
251
+ }
252
+ else if (hasGetter) {
253
+ descriptor.set = val => {
254
+ storageBox[p] = val;
255
+ return true;
256
+ };
257
+ }
258
+ }
259
+ Object.defineProperty(fakeObject, p, Object.freeze(descriptor));
260
+ }
261
+ };
262
+ propertyNames.forEach(p => {
263
+ propertyMap[p] = true;
264
+ def(p);
265
+ });
266
+ // 再次循环是为了处理原型链中的属性
267
+ for (const prop in target) {
268
+ if (!propertyMap[prop]) {
269
+ def(prop);
270
+ }
271
+ }
272
+ return fakeObject;
273
+ }
274
+
275
+ const esGlobalFunctions = ('eval,isFinite,isNaN,parseFloat,parseInt,' +
276
+ // URL handling functions
277
+ 'decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
278
+ // Constructor properties of the global object
279
+ 'Array,ArrayBuffer,BigInt,BigInt64Array,BigUint64Array,Boolean,DataView,Date,Error,EvalError,' +
280
+ 'FinalizationRegistry,Float32Array,Float64Array,Function,Int8Array,Int16Array,Int32Array,Map,Number,' +
281
+ 'Object,Promise,Proxy,RangeError,ReferenceError,RegExp,Set,SharedArrayBuffer,String,Symbol,SyntaxError,' +
282
+ 'TypeError,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array,URIError,WeakMap,WeakRef,WeakSet,' +
283
+ // Other Properties of the Global Object
284
+ 'Atomics,JSON,Math,Reflect').split(',');
285
+ const whitelistVariables = PLANET_SANDBOX_WINDOW_WHITELIST || [];
286
+ function isConstructor(fn) {
287
+ const fp = fn.prototype;
288
+ const hasConstructor = fp && fp.constructor === fn && Object.getOwnPropertyNames(fp).length > 1;
289
+ const functionStr = !hasConstructor && fn.toString();
290
+ return hasConstructor || /^function\s+[A-Z]/.test(functionStr) || /^class\b/.test(functionStr);
291
+ }
292
+ const unscopables = {
293
+ undefined: true,
294
+ Array: true,
295
+ Object: true,
296
+ String: true,
297
+ Boolean: true,
298
+ Math: true,
299
+ Number: true,
300
+ Symbol: true,
301
+ parseFloat: true,
302
+ Float32Array: true
303
+ };
304
+ class ProxyWindow {
305
+ constructor(sandbox) {
306
+ this.sandbox = sandbox;
307
+ this.definedVariables = new Set();
308
+ }
309
+ createGetter() {
310
+ return (target, key, receiver) => {
311
+ if (key === Symbol.unscopables) {
312
+ return unscopables;
313
+ }
314
+ if (key === SANDBOX_INSTANCE) {
315
+ return this.sandbox;
316
+ }
317
+ let value = null;
318
+ if (whitelistVariables.includes(key)) {
319
+ return Reflect.get(window, key);
320
+ }
321
+ else {
322
+ value = hasOwnProp(target, key) ? Reflect.get(target, key, receiver) : Reflect.get(window, key);
323
+ }
324
+ if (isFunction(value)) {
325
+ if (esGlobalFunctions.includes(key) ||
326
+ whitelistVariables.includes(key) ||
327
+ this.sandbox.rewriteVariables.includes(key) ||
328
+ this.definedVariables.has(key) ||
329
+ isConstructor(value)) {
330
+ return value;
331
+ }
332
+ else {
333
+ const newValue = hasOwnProp(value, WINDOW_BIND_FN) ? value[WINDOW_BIND_FN] : bind(value, window);
334
+ const desc = Object.getOwnPropertyDescriptor(target, key);
335
+ if (isNonWriteableValue(desc)) {
336
+ return value;
337
+ }
338
+ if (isInvalidGetAccessor(desc)) {
339
+ return undefined;
340
+ }
341
+ value[WINDOW_BIND_FN] = newValue;
342
+ return newValue;
343
+ }
344
+ }
345
+ else {
346
+ return value;
347
+ }
348
+ };
349
+ }
350
+ createSetter() {
351
+ return (target, key, value, receiver) => {
352
+ const desc = Object.getOwnPropertyDescriptor(whitelistVariables.includes(key) ? window : receiver ? receiver : target, key);
353
+ if (desc && isNonWriteableValue(desc)) {
354
+ if (!Object.is(value, desc.value)) {
355
+ return false;
356
+ }
357
+ else {
358
+ return true;
359
+ }
360
+ }
361
+ if (isInvalidSetAccessor(desc)) {
362
+ return false;
363
+ }
364
+ if (whitelistVariables.includes(key)) {
365
+ return Reflect.set(window, key, value);
366
+ }
367
+ else {
368
+ const success = Reflect.set(target, key, value, receiver);
369
+ if (success) {
370
+ if (this.sandbox.running) {
371
+ this.definedVariables.add(key);
372
+ }
373
+ }
374
+ return success;
375
+ }
376
+ };
377
+ }
378
+ createDefineProperty() {
379
+ return (target, p, descriptor) => {
380
+ if (whitelistVariables.includes(p)) {
381
+ return Reflect.defineProperty(window, p, descriptor);
382
+ }
383
+ else {
384
+ const success = Reflect.defineProperty(target, p, descriptor);
385
+ if (this.sandbox.running && success) {
386
+ this.definedVariables.add(p);
387
+ }
388
+ return success;
389
+ }
390
+ };
391
+ }
392
+ createDeleteProperty() {
393
+ return (target, p) => {
394
+ if (hasOwnProp(target, p)) {
395
+ delete target[p];
396
+ if (this.sandbox.running && this.definedVariables.has(p)) {
397
+ this.definedVariables.delete(p);
398
+ }
399
+ }
400
+ return true;
401
+ };
402
+ }
403
+ createHas() {
404
+ return (_target, key) => {
405
+ return !whitelistVariables.includes(key);
406
+ };
407
+ }
408
+ create() {
409
+ const fakeWindow = createFakeObject(window, this.sandbox.rewriteVariables);
410
+ const baseHandlers = {
411
+ get: this.createGetter(),
412
+ set: this.createSetter(),
413
+ defineProperty: this.createDefineProperty(),
414
+ deleteProperty: this.createDeleteProperty()
415
+ };
416
+ const proxy = new Proxy(fakeWindow, {
417
+ ...baseHandlers,
418
+ has: this.createHas()
419
+ });
420
+ const subProxy = new Proxy(fakeWindow, baseHandlers);
421
+ proxy.self = subProxy;
422
+ proxy.window = subProxy;
423
+ proxy.globalThis = subProxy;
424
+ proxy.top = window.top === window ? subProxy : window.top;
425
+ proxy.parent = window.parent === window ? subProxy : window.top;
426
+ return proxy;
427
+ }
428
+ }
429
+
430
+ function eventListenerPatch(sandbox) {
431
+ const rawAddEventListener = window.addEventListener;
432
+ const rawRemoveEventListener = window.removeEventListener;
433
+ const listenerSubscriptions = new Map();
434
+ function addEventListener(type, listener, options) {
435
+ const observable = new Observable(() => {
436
+ rawAddEventListener.call(this, type, listener, options);
437
+ return () => {
438
+ rawRemoveEventListener.call(this, type, listener, options);
439
+ };
440
+ });
441
+ const subscription = observable.subscribe(() => { });
442
+ listenerSubscriptions.set(listener, subscription);
443
+ }
444
+ function removeEventListener(type, listener) {
445
+ const subscription = listenerSubscriptions.get(listener);
446
+ if (subscription) {
447
+ subscription.unsubscribe();
448
+ listenerSubscriptions.delete(listener);
449
+ }
450
+ }
451
+ return {
452
+ rewrite: {
453
+ addEventListener: addEventListener.bind(window),
454
+ removeEventListener: removeEventListener.bind(window)
455
+ },
456
+ init() {
457
+ const fakeDocument = sandbox.global.document;
458
+ if (fakeDocument) {
459
+ fakeDocument.addEventListener = addEventListener.bind(document);
460
+ fakeDocument.removeEventListener = removeEventListener.bind(document);
461
+ }
462
+ },
463
+ destroy() {
464
+ listenerSubscriptions.forEach(subscription => subscription.unsubscribe());
465
+ listenerSubscriptions.clear();
466
+ }
467
+ };
468
+ }
469
+
470
+ const rawDocument = Document;
471
+ const whitelist = ['cookie', 'title', 'location', ...(PLANET_SANDBOX_DOCUMENT_WHITELIST || [])];
472
+ class ProxyDocument {
473
+ constructor() { }
474
+ createGetter() {
475
+ return (target, p, receiver) => {
476
+ const value = hasOwnProp(target, p) ? Reflect.get(target, p, receiver) : Reflect.get(document, p);
477
+ if (p === 'activeElement') {
478
+ return Reflect.get(document, p);
479
+ }
480
+ // TODO: 处理动态节点
481
+ // if (p === 'createElement') {
482
+ // return function(tagName: string, options: ElementCreationOptions) {
483
+ // const created = value.call(document, tagName, options);
484
+ // if (isObject(created)) {
485
+ // created[SANDBOX_INSTANCE] = sandbox;
486
+ // }
487
+ // return created;
488
+ // };
489
+ // }
490
+ if (isFunction(value)) {
491
+ let newValue = hasOwnProp(value, DOCUMENT_BIND_FN) ? value[DOCUMENT_BIND_FN] : null;
492
+ if (!newValue) {
493
+ newValue = bind(value, document);
494
+ }
495
+ const desc = Object.getOwnPropertyDescriptor(target, p);
496
+ if (desc && isNonWriteableValue(desc)) {
497
+ if (!Object.is(newValue, desc.value)) {
498
+ return value;
499
+ }
500
+ }
501
+ if (isInvalidGetAccessor(desc)) {
502
+ return undefined;
503
+ }
504
+ value[DOCUMENT_BIND_FN] = newValue;
505
+ return newValue;
506
+ }
507
+ return value;
508
+ };
509
+ }
510
+ createSetter() {
511
+ return (target, p, value, receiver) => {
512
+ const desc = Object.getOwnPropertyDescriptor(whitelist.includes(p) ? document : receiver || target, p);
513
+ if (desc && isNonWriteableValue(desc)) {
514
+ if (Object.is(value, desc.value)) {
515
+ return true;
516
+ }
517
+ else {
518
+ return false;
519
+ }
520
+ }
521
+ if (isInvalidSetAccessor(desc)) {
522
+ return false;
523
+ }
524
+ return whitelist.includes(p) ? Reflect.set(document, p, value) : Reflect.set(target, p, value, receiver);
525
+ };
526
+ }
527
+ createDefineProperty() {
528
+ return (target, p, descriptor) => {
529
+ return whitelist.includes(p)
530
+ ? Reflect.defineProperty(document, p, descriptor)
531
+ : Reflect.defineProperty(target, p, descriptor);
532
+ };
533
+ }
534
+ create() {
535
+ let proxyDocument = null;
536
+ const fakeDocument = createFakeObject(document);
537
+ const getter = this.createGetter();
538
+ const fakeDocumentProto = new Proxy(fakeDocument, {
539
+ get: (...args) => {
540
+ return getter(...args);
541
+ }
542
+ });
543
+ const fakeDocumentCtor = function Document() {
544
+ if (!(this instanceof fakeDocumentCtor)) {
545
+ throw new TypeError(`Failed to construct 'Document': Please use the 'new' operator.`);
546
+ }
547
+ const docInstance = new rawDocument();
548
+ Object.setPrototypeOf(docInstance, fakeDocument);
549
+ return docInstance;
550
+ };
551
+ fakeDocumentCtor.prototype = fakeDocumentProto;
552
+ fakeDocumentCtor.prototype.constructor = fakeDocumentCtor;
553
+ if (Symbol.hasInstance) {
554
+ Object.defineProperty(fakeDocumentCtor, Symbol.hasInstance, {
555
+ configurable: true,
556
+ value(value) {
557
+ let proto = value;
558
+ if (proto === document) {
559
+ return true;
560
+ }
561
+ while ((proto = Object.getPrototypeOf(proto))) {
562
+ if (proto === fakeDocumentProto) {
563
+ return true;
564
+ }
565
+ }
566
+ const cloned = function () { };
567
+ cloned.prototype = fakeDocument;
568
+ return value instanceof cloned;
569
+ }
570
+ });
571
+ }
572
+ proxyDocument = new Proxy(Object.create(fakeDocumentProto, {
573
+ currentScript: {
574
+ value: null,
575
+ writable: true
576
+ },
577
+ [RAW_NODE]: {
578
+ writable: false,
579
+ configurable: false,
580
+ value: document
581
+ }
582
+ }), {
583
+ set: this.createSetter(),
584
+ defineProperty: this.createDefineProperty()
585
+ });
586
+ return {
587
+ document: proxyDocument,
588
+ Document: fakeDocumentCtor
589
+ };
590
+ }
591
+ }
592
+
593
+ function documentPatch() {
594
+ const proxyDocument = new ProxyDocument();
595
+ const { document, Document } = proxyDocument.create();
596
+ return {
597
+ rewrite: {
598
+ document,
599
+ Document
600
+ }
601
+ };
602
+ }
603
+
604
+ const rawSetTimeout = window.setTimeout;
605
+ const rawClearTimeout = window.clearTimeout;
606
+ const rawSetInterval = window.setInterval;
607
+ const rawClearInterval = window.clearInterval;
608
+ function timerPatch() {
609
+ const timeout = new Set();
610
+ const interval = new Set();
611
+ function rewriteSetTimeout(handler, ms, ...args) {
612
+ const timeoutId = rawSetTimeout(handler, ms, ...args);
613
+ timeout.add(timeoutId);
614
+ return timeoutId;
615
+ }
616
+ function rewriteClearTimeout(timeoutId) {
617
+ timeout.delete(timeoutId);
618
+ rawClearTimeout(timeoutId);
619
+ }
620
+ function rewriteSetInterval(handler, ms, ...args) {
621
+ const intervalId = rawSetInterval(handler, ms, ...args);
622
+ interval.add(intervalId);
623
+ return intervalId;
624
+ }
625
+ function rewriteClearInterval(intervalId) {
626
+ interval.delete(intervalId);
627
+ rawClearInterval(intervalId);
628
+ }
629
+ return {
630
+ rewrite: {
631
+ setTimeout: rewriteSetTimeout,
632
+ clearTimeout: rewriteClearTimeout,
633
+ setInterval: rewriteSetInterval,
634
+ clearInterval: rewriteClearInterval
635
+ },
636
+ destroy: () => {
637
+ timeout.forEach(timeoutId => {
638
+ rawClearTimeout(timeoutId);
639
+ });
640
+ interval.forEach(intervalId => {
641
+ rawClearInterval(intervalId);
642
+ });
643
+ }
644
+ };
645
+ }
646
+
647
+ const PLANET_STORAGE_PREFIX = '__planet-storage-';
648
+ class RewriteStorage {
649
+ constructor(app, rawStorage) {
650
+ this.rawStorage = rawStorage;
651
+ this.prefix = `${PLANET_STORAGE_PREFIX}${app}__:`;
652
+ }
653
+ get length() {
654
+ return this.getKeys().length;
655
+ }
656
+ getKeys() {
657
+ return Object.keys(this.rawStorage).filter(key => key.startsWith(this.prefix));
658
+ }
659
+ key(n) {
660
+ const key = this.getKeys()[n];
661
+ return key ? key.substring(this.prefix.length) : null;
662
+ }
663
+ getItem(key) {
664
+ return this.rawStorage.getItem(`${this.prefix + key}`);
665
+ }
666
+ setItem(key, value) {
667
+ this.rawStorage.setItem(`${this.prefix + key}`, value);
668
+ }
669
+ removeItem(key) {
670
+ this.rawStorage.removeItem(`${this.prefix + key}`);
671
+ }
672
+ clear() {
673
+ this.getKeys().forEach(key => {
674
+ this.rawStorage.removeItem(key);
675
+ });
676
+ }
677
+ }
678
+ function storagePatch(sandbox) {
679
+ return {
680
+ rewrite: {
681
+ localStorage: new RewriteStorage(sandbox.app, localStorage),
682
+ sessionStorage: new RewriteStorage(sandbox.app, sessionStorage)
683
+ }
684
+ };
685
+ }
686
+
687
+ const sandboxPatches = [documentPatch, eventListenerPatch, timerPatch, storagePatch];
688
+ function getSandboxPatchHandlers(sandbox) {
689
+ return sandboxPatches.map(patch => {
690
+ return patch(sandbox);
691
+ });
692
+ }
693
+
694
+ function execScript(code, url, global, strictGlobal) {
695
+ const sourceUrl = '//# sourceURL='.concat(url, '\n');
696
+ const window = (0, eval)('window');
697
+ window.tempGlobal = global;
698
+ code = strictGlobal
699
+ ? ';(function(window, self, globalThis){with(window){;'
700
+ .concat(code, '\n')
701
+ .concat(sourceUrl, '}}).bind(window.tempGlobal)(window.tempGlobal, window.tempGlobal, window.tempGlobal);')
702
+ : ';(function(window, self, globalThis){;'
703
+ .concat(code, '\n')
704
+ .concat(sourceUrl, '}).bind(window.tempGlobal)(window.tempGlobal, window.tempGlobal, window.tempGlobal);');
705
+ (0, eval)(code);
706
+ delete window.tempGlobal;
707
+ }
708
+
709
+ class Sandbox {
710
+ execScript(code, url = '') {
711
+ execScript(code, url, this.global, !!this.options.strictGlobal);
712
+ }
713
+ }
714
+
715
+ class ProxySandbox extends Sandbox {
716
+ constructor(app, options) {
717
+ super();
718
+ this.app = app;
719
+ this.options = options;
720
+ this.running = false;
721
+ this.patchHandlers = [];
722
+ this.patchHandlers = getSandboxPatchHandlers(this);
723
+ this.start();
724
+ }
725
+ start() {
726
+ this.running = true;
727
+ this.rewriteVariables = this.getPatchRewriteVariables();
728
+ const proxyWindow = new ProxyWindow(this);
729
+ this.global = proxyWindow.create();
730
+ this.execPatchHandlers();
731
+ }
732
+ destroy() {
733
+ this.running = false;
734
+ this.patchHandlers.forEach(handler => {
735
+ if (handler.destroy) {
736
+ handler.destroy();
737
+ }
738
+ });
739
+ }
740
+ getPatchRewriteVariables() {
741
+ return this.patchHandlers.reduce((pre, cur) => {
742
+ return [...pre, ...(cur.rewrite ? Object.keys(cur.rewrite) : [])];
743
+ }, []);
744
+ }
745
+ execPatchHandlers() {
746
+ this.patchHandlers.forEach(handler => {
747
+ if (handler.rewrite) {
748
+ for (const key in handler.rewrite) {
749
+ if (handler.rewrite[key]) {
750
+ this.global[key] = handler.rewrite[key];
751
+ }
752
+ }
753
+ }
754
+ if (handler.init) {
755
+ handler?.init();
756
+ }
757
+ });
758
+ }
759
+ }
760
+
761
+ class SnapshotSandbox extends Sandbox {
762
+ constructor(app, options) {
763
+ super();
764
+ this.app = app;
765
+ this.options = options;
766
+ this.start();
767
+ }
768
+ start() { }
769
+ destroy() { }
770
+ }
771
+
772
+ const defaultOptions = {
773
+ strictGlobal: false
774
+ };
775
+ function createSandbox(app, options) {
776
+ options = Object.assign({}, defaultOptions, options || {});
777
+ if (window.Proxy) {
778
+ return new ProxySandbox(app, options);
779
+ }
780
+ else {
781
+ return new SnapshotSandbox(app, options);
782
+ }
783
+ }
784
+ function getSandboxInstance() {
785
+ return window[SANDBOX_INSTANCE];
786
+ }
787
+
788
+ class AssetsLoader {
789
+ constructor(http) {
790
+ this.http = http;
791
+ this.loadedSources = [];
792
+ }
793
+ loadScript(src) {
794
+ const id = hashCode(src);
795
+ if (this.loadedSources.includes(id)) {
796
+ return of({
797
+ src: src,
798
+ hashCode: id,
799
+ loaded: true,
800
+ status: 'Loaded'
801
+ });
802
+ }
803
+ return new Observable((observer) => {
804
+ const script = document.createElement('script');
805
+ script.type = 'text/javascript';
806
+ script.src = src;
807
+ script.async = true;
808
+ if (script['readyState']) {
809
+ // IE
810
+ script['onreadystatechange'] = () => {
811
+ if (script['readyState'] === 'loaded' || script['readyState'] === 'complete') {
812
+ script['onreadystatechange'] = null;
813
+ observer.next({
814
+ src: src,
815
+ hashCode: id,
816
+ loaded: true,
817
+ status: 'Loaded'
818
+ });
819
+ observer.complete();
820
+ this.loadedSources.push(id);
821
+ }
822
+ };
823
+ }
824
+ else {
825
+ // Others
826
+ script.onload = () => {
827
+ observer.next({
828
+ src: src,
829
+ hashCode: id,
830
+ loaded: true,
831
+ status: 'Loaded'
832
+ });
833
+ observer.complete();
834
+ this.loadedSources.push(id);
835
+ };
836
+ }
837
+ script.onerror = error => {
838
+ observer.error({
839
+ src: src,
840
+ hashCode: id,
841
+ loaded: false,
842
+ status: 'Error',
843
+ error: error
844
+ });
845
+ observer.complete();
846
+ };
847
+ document.body.appendChild(script);
848
+ });
849
+ }
850
+ loadScriptWithSandbox(app, src) {
851
+ const id = hashCode(src);
852
+ if (this.loadedSources.includes(id)) {
853
+ return of({
854
+ src: src,
855
+ hashCode: id,
856
+ loaded: true,
857
+ status: 'Loaded'
858
+ });
859
+ }
860
+ return new Observable((observer) => {
861
+ this.http.get(src, { responseType: 'text' }).subscribe((code) => {
862
+ this.loadedSources.push(id);
863
+ const sandbox = createSandbox(app);
864
+ sandbox.execScript(code, src);
865
+ observer.next({
866
+ src: src,
867
+ hashCode: id,
868
+ loaded: true,
869
+ status: 'Loaded'
870
+ });
871
+ observer.complete();
872
+ }, error => {
873
+ observer.error({
874
+ src: src,
875
+ hashCode: id,
876
+ loaded: false,
877
+ status: 'Error',
878
+ error: error
879
+ });
880
+ observer.complete();
881
+ });
882
+ });
883
+ }
884
+ loadStyle(src) {
885
+ const id = hashCode(src);
886
+ if (this.loadedSources.includes(id)) {
887
+ return of({
888
+ src: src,
889
+ hashCode: id,
890
+ loaded: true,
891
+ status: 'Loaded'
892
+ });
893
+ }
894
+ return new Observable((observer) => {
895
+ const head = document.getElementsByTagName('head')[0];
896
+ const link = document.createElement('link');
897
+ link.rel = 'stylesheet';
898
+ link.type = 'text/css';
899
+ link.href = src;
900
+ link.media = 'all';
901
+ link.onload = () => {
902
+ observer.next({
903
+ src: src,
904
+ hashCode: id,
905
+ loaded: true,
906
+ status: 'Loaded'
907
+ });
908
+ observer.complete();
909
+ this.loadedSources.push(id);
910
+ };
911
+ link.onerror = error => {
912
+ observer.error({
913
+ src: src,
914
+ hashCode: id,
915
+ loaded: true,
916
+ status: 'Loaded',
917
+ error: error
918
+ });
919
+ observer.complete();
920
+ };
921
+ head.appendChild(link);
922
+ });
923
+ }
924
+ loadScripts(sources, options = {
925
+ serial: false,
926
+ sandbox: false
927
+ }) {
928
+ if (isEmpty(sources)) {
929
+ return of(null);
930
+ }
931
+ const observables = sources.map(src => {
932
+ // TODO: 暂时只支持Proxy沙箱
933
+ if (options.sandbox && window.Proxy) {
934
+ return this.loadScriptWithSandbox(options.app, src);
935
+ }
936
+ else {
937
+ return this.loadScript(src);
938
+ }
939
+ });
940
+ if (options.serial) {
941
+ const a = concat(...observables).pipe(map(item => {
942
+ return of([item]);
943
+ }), concatAll());
944
+ return a;
945
+ }
946
+ else {
947
+ return forkJoin(observables).pipe();
948
+ }
949
+ }
950
+ loadStyles(sources) {
951
+ if (isEmpty(sources)) {
952
+ return of(null);
953
+ }
954
+ return forkJoin(sources.map(src => {
955
+ return this.loadStyle(src);
956
+ }));
957
+ }
958
+ loadScriptsAndStyles(scripts = [], styles = [], options) {
959
+ return forkJoin([this.loadScripts(scripts, options), this.loadStyles(styles)]);
960
+ }
961
+ loadAppAssets(app) {
962
+ if (app.manifest) {
963
+ return this.loadManifest(`${app.manifest}?t=${new Date().getTime()}`).pipe(switchMap(manifestResult => {
964
+ const { scripts, styles } = getScriptsAndStylesFullPaths(app, manifestResult);
965
+ return this.loadScriptsAndStyles(scripts, styles, {
966
+ app: app.name,
967
+ sandbox: app.sandbox,
968
+ serial: app.loadSerial
969
+ });
970
+ }));
971
+ }
972
+ else {
973
+ const { scripts, styles } = getScriptsAndStylesFullPaths(app);
974
+ return this.loadScriptsAndStyles(scripts, styles, {
975
+ app: app.name,
976
+ sandbox: app.sandbox,
977
+ serial: app.loadSerial
978
+ });
979
+ }
980
+ }
981
+ loadManifest(url) {
982
+ return this.http.get(url).pipe(map((response) => {
983
+ return response;
984
+ }));
985
+ }
986
+ }
987
+ AssetsLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: AssetsLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
988
+ AssetsLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: AssetsLoader, providedIn: 'root' });
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: AssetsLoader, decorators: [{
990
+ type: Injectable,
991
+ args: [{
992
+ providedIn: 'root'
993
+ }]
994
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
995
+
996
+ class PlanetApplicationRef {
997
+ constructor(name, options) {
998
+ this.name = name;
999
+ if (options) {
1000
+ this.template = options.template;
1001
+ this.innerSelector = this.template ? getTagNameByTemplate(this.template) : '';
1002
+ this.appModuleBootstrap = options.bootstrap;
1003
+ }
1004
+ // This is a hack, since NgZone doesn't allow you to configure the property that identifies your zone.
1005
+ // See https://github.com/PlaceMe-SAS/single-spa-angular-cli/issues/33,
1006
+ NgZone.isInAngularZone = () => {
1007
+ // @ts-ignore
1008
+ return window.Zone.current._properties[`ngx-planet-${name}`] === true;
1009
+ };
1010
+ }
1011
+ get selector() {
1012
+ return this.innerSelector;
1013
+ }
1014
+ get bootstrapped() {
1015
+ return !!this.appModuleRef;
1016
+ }
1017
+ get ngZone() {
1018
+ return this.appModuleRef?.injector.get(NgZone);
1019
+ }
1020
+ get sandbox() {
1021
+ return getSandboxInstance();
1022
+ }
1023
+ // 子应用路由变化后同步修改 portal 的 Route
1024
+ syncPortalRouteWhenNavigationEnd() {
1025
+ const router = this.appModuleRef?.injector.get(Router);
1026
+ if (router) {
1027
+ router.events.subscribe(event => {
1028
+ if (event instanceof NavigationEnd) {
1029
+ this.ngZone?.onStable
1030
+ .asObservable()
1031
+ .pipe(take(1))
1032
+ .subscribe(() => {
1033
+ this.portalApp.router.navigateByUrl(event.url);
1034
+ });
1035
+ }
1036
+ });
1037
+ }
1038
+ }
1039
+ bootstrap(app) {
1040
+ if (!this.appModuleBootstrap) {
1041
+ throw new Error(`app(${this.name}) is not defined`);
1042
+ }
1043
+ this.portalApp = app;
1044
+ return from(this.appModuleBootstrap(app).then(appModuleRef => {
1045
+ this.appModuleRef = appModuleRef;
1046
+ this.appModuleRef.instance.appName = this.name;
1047
+ this.syncPortalRouteWhenNavigationEnd();
1048
+ return this;
1049
+ }));
1050
+ }
1051
+ getRouter() {
1052
+ return this.appModuleRef?.injector.get(Router);
1053
+ }
1054
+ getCurrentRouterStateUrl() {
1055
+ return this.getRouter()?.routerState.snapshot.url;
1056
+ }
1057
+ navigateByUrl(url) {
1058
+ const router = this.getRouter();
1059
+ this.ngZone?.run(() => {
1060
+ router?.navigateByUrl(url);
1061
+ });
1062
+ }
1063
+ getComponentFactory() {
1064
+ return this.componentFactory;
1065
+ }
1066
+ registerComponentFactory(componentFactory) {
1067
+ this.componentFactory = componentFactory;
1068
+ }
1069
+ destroy() {
1070
+ if (this.appModuleRef) {
1071
+ const router = this.appModuleRef.injector.get(Router);
1072
+ if (router) {
1073
+ router.dispose();
1074
+ }
1075
+ if (this.sandbox) {
1076
+ this.sandbox.destroy();
1077
+ }
1078
+ this.appModuleRef.destroy();
1079
+ this.appModuleRef = undefined;
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+ const globalPlanet = (window.planet = window.planet || {
1085
+ apps: {}
1086
+ });
1087
+ function defineApplication(name, options) {
1088
+ if (globalPlanet.apps[name]) {
1089
+ throw new Error(`${name} application has exist.`);
1090
+ }
1091
+ if (isFunction(options)) {
1092
+ options = {
1093
+ template: '',
1094
+ bootstrap: options
1095
+ };
1096
+ }
1097
+ const appRef = new PlanetApplicationRef(name, options);
1098
+ globalPlanet.apps[name] = appRef;
1099
+ }
1100
+ function getPlanetApplicationRef(appName) {
1101
+ if (globalPlanet && globalPlanet.apps && globalPlanet.apps[appName]) {
1102
+ return globalPlanet.apps[appName];
1103
+ }
1104
+ else {
1105
+ return null;
1106
+ }
1107
+ }
1108
+ function setPortalApplicationData(data) {
1109
+ if (globalPlanet.portalApplication) {
1110
+ globalPlanet.portalApplication.data = data;
1111
+ }
1112
+ }
1113
+ function getPortalApplicationData() {
1114
+ return globalPlanet.portalApplication?.data;
1115
+ }
1116
+ function setApplicationLoader(loader) {
1117
+ globalPlanet.applicationLoader = loader;
1118
+ }
1119
+ function getApplicationLoader() {
1120
+ return globalPlanet.applicationLoader;
1121
+ }
1122
+ function setApplicationService(service) {
1123
+ globalPlanet.applicationService = service;
1124
+ }
1125
+ function getApplicationService() {
1126
+ return globalPlanet.applicationService;
1127
+ }
1128
+ function clearGlobalPlanet() {
1129
+ window.planet.apps = {};
1130
+ window.planet.portalApplication = null;
1131
+ window.planet.applicationLoader = null;
1132
+ window.planet.applicationService = null;
1133
+ }
1134
+
1135
+ class PlanetApplicationService {
1136
+ constructor(http, assetsLoader) {
1137
+ this.http = http;
1138
+ this.assetsLoader = assetsLoader;
1139
+ this.apps = [];
1140
+ this.appsMap = {};
1141
+ if (getApplicationService()) {
1142
+ throw new Error('PlanetApplicationService has been injected in the portal, repeated injection is not allowed');
1143
+ }
1144
+ }
1145
+ register(appOrApps) {
1146
+ const apps = coerceArray(appOrApps);
1147
+ apps.forEach(app => {
1148
+ if (this.appsMap[app.name]) {
1149
+ throw new Error(`${app.name} has be registered.`);
1150
+ }
1151
+ this.apps.push(app);
1152
+ this.appsMap[app.name] = app;
1153
+ });
1154
+ }
1155
+ registerByUrl(url) {
1156
+ const result = this.http.get(`${url}`).pipe(map(apps => {
1157
+ if (apps && Array.isArray(apps)) {
1158
+ this.register(apps);
1159
+ }
1160
+ else {
1161
+ this.register(apps);
1162
+ }
1163
+ }), shareReplay());
1164
+ result.subscribe();
1165
+ return result;
1166
+ }
1167
+ unregister(name) {
1168
+ if (this.appsMap[name]) {
1169
+ delete this.appsMap[name];
1170
+ this.apps = this.apps.filter(app => {
1171
+ return app.name !== name;
1172
+ });
1173
+ }
1174
+ }
1175
+ getAppsByMatchedUrl(url) {
1176
+ return this.getApps().filter(app => {
1177
+ if (app.routerPathPrefix instanceof RegExp) {
1178
+ return app.routerPathPrefix.test(url);
1179
+ }
1180
+ else {
1181
+ return url.startsWith(app.routerPathPrefix);
1182
+ }
1183
+ });
1184
+ }
1185
+ getAppByName(name) {
1186
+ return this.appsMap[name];
1187
+ }
1188
+ getAppsToPreload(excludeAppNames) {
1189
+ return this.getApps().filter(app => {
1190
+ if (excludeAppNames) {
1191
+ return app.preload && !excludeAppNames.includes(app.name);
1192
+ }
1193
+ else {
1194
+ return app.preload;
1195
+ }
1196
+ });
1197
+ }
1198
+ getApps() {
1199
+ return this.apps;
1200
+ }
1201
+ }
1202
+ PlanetApplicationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationService, deps: [{ token: i1.HttpClient }, { token: AssetsLoader }], target: i0.ɵɵFactoryTarget.Injectable });
1203
+ PlanetApplicationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationService, providedIn: 'root' });
1204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationService, decorators: [{
1205
+ type: Injectable,
1206
+ args: [{
1207
+ providedIn: 'root'
1208
+ }]
1209
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: AssetsLoader }]; } });
1210
+
1211
+ class PlanetPortalApplication {
1212
+ navigateByUrl(url, extras) {
1213
+ return this.ngZone.run(() => {
1214
+ return this.router.navigateByUrl(url, extras);
1215
+ });
1216
+ }
1217
+ run(fn) {
1218
+ return this.ngZone.run(() => {
1219
+ return fn();
1220
+ });
1221
+ }
1222
+ tick() {
1223
+ this.applicationRef.tick();
1224
+ }
1225
+ }
1226
+
1227
+ const CUSTOM_EVENT_NAME = 'PLANET_GLOBAL_EVENT_DISPATCHER';
1228
+ class GlobalEventDispatcher {
1229
+ constructor(ngZone) {
1230
+ this.ngZone = ngZone;
1231
+ this.subject$ = new Subject();
1232
+ this.hasAddGlobalEventListener = false;
1233
+ this.subscriptionCount = 0;
1234
+ this.globalEventListener = (event) => {
1235
+ this.subject$.next(event.detail);
1236
+ };
1237
+ }
1238
+ addGlobalEventListener() {
1239
+ this.hasAddGlobalEventListener = true;
1240
+ window.addEventListener(CUSTOM_EVENT_NAME, this.globalEventListener);
1241
+ }
1242
+ removeGlobalEventListener() {
1243
+ this.hasAddGlobalEventListener = false;
1244
+ window.removeEventListener(CUSTOM_EVENT_NAME, this.globalEventListener);
1245
+ }
1246
+ dispatch(name, payload) {
1247
+ window.dispatchEvent(new CustomEvent(CUSTOM_EVENT_NAME, {
1248
+ detail: {
1249
+ name: name,
1250
+ payload: payload
1251
+ }
1252
+ }));
1253
+ }
1254
+ register(eventName) {
1255
+ return new Observable(observer => {
1256
+ if (!this.hasAddGlobalEventListener) {
1257
+ this.addGlobalEventListener();
1258
+ }
1259
+ this.subscriptionCount++;
1260
+ const subscription = this.subject$
1261
+ .pipe(filter(event => {
1262
+ return event.name === eventName;
1263
+ }), map(event => {
1264
+ return event.payload;
1265
+ }))
1266
+ .subscribe(payload => {
1267
+ this.ngZone.run(() => {
1268
+ observer.next(payload);
1269
+ });
1270
+ });
1271
+ return () => {
1272
+ this.subscriptionCount--;
1273
+ subscription.unsubscribe();
1274
+ if (!this.subscriptionCount) {
1275
+ this.removeGlobalEventListener();
1276
+ }
1277
+ };
1278
+ });
1279
+ }
1280
+ getSubscriptionCount() {
1281
+ return this.subscriptionCount;
1282
+ }
1283
+ }
1284
+ GlobalEventDispatcher.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: GlobalEventDispatcher, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
1285
+ GlobalEventDispatcher.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: GlobalEventDispatcher, providedIn: 'root' });
1286
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: GlobalEventDispatcher, decorators: [{
1287
+ type: Injectable,
1288
+ args: [{
1289
+ providedIn: 'root'
1290
+ }]
1291
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
1292
+
1293
+ /**
1294
+ * Debug factory for debug module
1295
+ */
1296
+ let _debugFactory;
1297
+ let _debuggerMap = {};
1298
+ function createDebug(namespace) {
1299
+ const key = `planet:${namespace}`;
1300
+ return function (formatter, ...args) {
1301
+ if (_debugFactory) {
1302
+ let debugDebugger = _debuggerMap[key];
1303
+ if (!debugDebugger) {
1304
+ debugDebugger = _debugFactory(key);
1305
+ _debuggerMap[key] = debugDebugger;
1306
+ }
1307
+ debugDebugger(formatter, args);
1308
+ }
1309
+ };
1310
+ }
1311
+ function setDebugFactory(debug) {
1312
+ if (debug && !isFunction(debug)) {
1313
+ throw new Error('debug factory type is invalid, must be function');
1314
+ }
1315
+ _debugFactory = debug;
1316
+ }
1317
+ function clearDebugFactory() {
1318
+ _debugFactory = undefined;
1319
+ _debuggerMap = {};
1320
+ }
1321
+ function getDebugFactory() {
1322
+ return _debugFactory;
1323
+ }
1324
+
1325
+ const debug = createDebug('app-loader');
1326
+ var ApplicationStatus;
1327
+ (function (ApplicationStatus) {
1328
+ ApplicationStatus[ApplicationStatus["assetsLoading"] = 1] = "assetsLoading";
1329
+ ApplicationStatus[ApplicationStatus["assetsLoaded"] = 2] = "assetsLoaded";
1330
+ ApplicationStatus[ApplicationStatus["bootstrapping"] = 3] = "bootstrapping";
1331
+ ApplicationStatus[ApplicationStatus["bootstrapped"] = 4] = "bootstrapped";
1332
+ ApplicationStatus[ApplicationStatus["active"] = 5] = "active";
1333
+ ApplicationStatus[ApplicationStatus["loadError"] = 10] = "loadError";
1334
+ })(ApplicationStatus || (ApplicationStatus = {}));
1335
+ class PlanetApplicationLoader {
1336
+ constructor(assetsLoader, planetApplicationService, ngZone, router, injector, applicationRef) {
1337
+ this.assetsLoader = assetsLoader;
1338
+ this.planetApplicationService = planetApplicationService;
1339
+ this.ngZone = ngZone;
1340
+ this.firstLoad = true;
1341
+ this.inProgressAppAssetsLoads = new Map();
1342
+ this.appsStatus = new Map();
1343
+ this.portalApp = new PlanetPortalApplication();
1344
+ this.routeChange$ = new Subject();
1345
+ this.appStatusChange$ = new Subject();
1346
+ this.appsLoadingStart$ = new Subject();
1347
+ this.loadingDone = false;
1348
+ if (getApplicationLoader()) {
1349
+ throw new Error('PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed');
1350
+ }
1351
+ this.options = {
1352
+ switchMode: SwitchModes.default,
1353
+ errorHandler: (error) => {
1354
+ console.error(error);
1355
+ }
1356
+ };
1357
+ this.portalApp.ngZone = ngZone;
1358
+ this.portalApp.applicationRef = applicationRef;
1359
+ this.portalApp.router = router;
1360
+ this.portalApp.injector = injector;
1361
+ this.portalApp.globalEventDispatcher = injector.get(GlobalEventDispatcher);
1362
+ globalPlanet.portalApplication = this.portalApp;
1363
+ this.setupRouteChange();
1364
+ }
1365
+ get appStatusChange() {
1366
+ return this.appStatusChange$.asObservable();
1367
+ }
1368
+ get appsLoadingStart() {
1369
+ return this.appsLoadingStart$.asObservable();
1370
+ }
1371
+ setAppStatus(app, status) {
1372
+ this.ngZone.run(() => {
1373
+ const fromStatus = this.appsStatus.get(app);
1374
+ debug(`app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${ApplicationStatus[status]}`);
1375
+ this.appsStatus.set(app, status);
1376
+ this.appStatusChange$.next({
1377
+ app: app,
1378
+ status: status
1379
+ });
1380
+ });
1381
+ }
1382
+ getAppStatusChange$(app, status = ApplicationStatus.bootstrapped) {
1383
+ return this.appStatusChange.pipe(filter(event => {
1384
+ return event.app === app && event.status === status;
1385
+ }), map(() => {
1386
+ return app;
1387
+ }));
1388
+ }
1389
+ switchModeIsCoexist(app) {
1390
+ if (app && app.switchMode) {
1391
+ return app.switchMode === SwitchModes.coexist;
1392
+ }
1393
+ else {
1394
+ return this.options.switchMode === SwitchModes.coexist;
1395
+ }
1396
+ }
1397
+ errorHandler(error) {
1398
+ this.ngZone.run(() => {
1399
+ this.options.errorHandler(error);
1400
+ });
1401
+ }
1402
+ setLoadingDone() {
1403
+ this.ngZone.run(() => {
1404
+ this.loadingDone = true;
1405
+ });
1406
+ }
1407
+ getAppNames(apps) {
1408
+ return apps.length === 0
1409
+ ? `[]`
1410
+ : apps.map(item => {
1411
+ return item.name;
1412
+ });
1413
+ }
1414
+ setupRouteChange() {
1415
+ this.routeChange$
1416
+ .pipe(distinctUntilChanged((x, y) => {
1417
+ return (x && x.url) === (y && y.url);
1418
+ }),
1419
+ // Using switchMap so we cancel executing loading when a new one comes in
1420
+ switchMap(event => {
1421
+ // Return new observable use of and catchError,
1422
+ // in order to prevent routeChange$ completed which never trigger new route change
1423
+ return of(event).pipe(
1424
+ // unload apps and return should load apps
1425
+ map(() => {
1426
+ debug(`route change, url is: ${event.url}`);
1427
+ this.startRouteChangeEvent = event;
1428
+ const shouldLoadApps = this.planetApplicationService.getAppsByMatchedUrl(event.url);
1429
+ debug(`should load apps: ${this.getAppNames(shouldLoadApps)}`);
1430
+ const shouldUnloadApps = this.getUnloadApps(shouldLoadApps);
1431
+ this.appsLoadingStart$.next({
1432
+ shouldLoadApps,
1433
+ shouldUnloadApps
1434
+ });
1435
+ this.unloadApps(shouldUnloadApps, event);
1436
+ debug(`unload apps: ${this.getAppNames(shouldUnloadApps)}`);
1437
+ return shouldLoadApps;
1438
+ }),
1439
+ // Load app assets (static resources)
1440
+ switchMap(shouldLoadApps => {
1441
+ let hasAppsNeedLoadingAssets = false;
1442
+ const loadApps$ = shouldLoadApps.map(app => {
1443
+ const appStatus = this.appsStatus.get(app);
1444
+ if (!appStatus ||
1445
+ appStatus === ApplicationStatus.assetsLoading ||
1446
+ appStatus === ApplicationStatus.loadError) {
1447
+ debug(`app(${app.name}) status is ${ApplicationStatus[appStatus]}, start load assets`);
1448
+ hasAppsNeedLoadingAssets = true;
1449
+ return this.ngZone.runOutsideAngular(() => {
1450
+ return this.startLoadAppAssets(app);
1451
+ });
1452
+ }
1453
+ else {
1454
+ return of(app);
1455
+ }
1456
+ });
1457
+ if (hasAppsNeedLoadingAssets) {
1458
+ this.loadingDone = false;
1459
+ }
1460
+ return loadApps$.length > 0 ? forkJoin(loadApps$) : of([]);
1461
+ }),
1462
+ // Bootstrap or show apps
1463
+ map(apps => {
1464
+ const apps$ = apps.map(app => {
1465
+ return of(app).pipe(switchMap(app => {
1466
+ const appStatus = this.appsStatus.get(app);
1467
+ if (appStatus === ApplicationStatus.bootstrapped) {
1468
+ debug(`[routeChange] app(${app.name}) status is bootstrapped, show app and active`);
1469
+ this.showApp(app);
1470
+ const appRef = getPlanetApplicationRef(app.name);
1471
+ appRef?.navigateByUrl(event.url);
1472
+ this.setAppStatus(app, ApplicationStatus.active);
1473
+ this.setLoadingDone();
1474
+ return of(app);
1475
+ }
1476
+ else if (appStatus === ApplicationStatus.assetsLoaded) {
1477
+ debug(`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`);
1478
+ return this.bootstrapApp(app).pipe(map(() => {
1479
+ debug(`app(${app.name}) bootstrapped success, active it`);
1480
+ this.setAppStatus(app, ApplicationStatus.active);
1481
+ this.setLoadingDone();
1482
+ return app;
1483
+ }));
1484
+ }
1485
+ else if (appStatus === ApplicationStatus.active) {
1486
+ debug(`[routeChange] app(${app.name}) is active, do nothings`);
1487
+ const appRef = getPlanetApplicationRef(app.name);
1488
+ // Backwards compatibility sub app use old version which has not getCurrentRouterStateUrl
1489
+ const currentUrl = appRef?.getCurrentRouterStateUrl
1490
+ ? appRef.getCurrentRouterStateUrl()
1491
+ : '';
1492
+ if (currentUrl !== event.url) {
1493
+ appRef?.navigateByUrl(event.url);
1494
+ }
1495
+ return of(app);
1496
+ }
1497
+ else {
1498
+ debug(`[routeChange] app(${app.name}) status is ${ApplicationStatus[appStatus]}`);
1499
+ return this.getAppStatusChange$(app).pipe(take(1), map(() => {
1500
+ debug(`app(${app.name}) status is bootstrapped by subscribe status change, active it`);
1501
+ this.setAppStatus(app, ApplicationStatus.active);
1502
+ this.showApp(app);
1503
+ return app;
1504
+ }));
1505
+ }
1506
+ }));
1507
+ });
1508
+ if (apps$.length > 0) {
1509
+ debug(`start load and active apps: ${this.getAppNames(apps)}`);
1510
+ // 切换到应用后会有闪烁现象,所以使用 setTimeout 后启动应用
1511
+ // example: redirect to app1's dashboard from portal's about page
1512
+ // If app's route has redirect, it doesn't work, it ok just in setTimeout, I don't know why.
1513
+ // TODO:: remove it, it is ok in version Angular 9.x
1514
+ setTimeout(() => {
1515
+ // 此处判断是因为如果静态资源加载完毕还未启动被取消,还是会启动之前的应用,虽然可能性比较小,但是无法排除这种可能性,所以只有当 Event 是最后一个才会启动
1516
+ if (this.startRouteChangeEvent === event) {
1517
+ // runOutsideAngular for fix error: `Expected to not be in Angular Zone, but it is!`
1518
+ this.ngZone.runOutsideAngular(() => {
1519
+ forkJoin(apps$).subscribe(() => {
1520
+ this.setLoadingDone();
1521
+ this.ensurePreloadApps(apps);
1522
+ });
1523
+ });
1524
+ }
1525
+ });
1526
+ }
1527
+ else {
1528
+ debug(`no apps need to be loaded, ensure preload apps`);
1529
+ this.ensurePreloadApps(apps);
1530
+ this.setLoadingDone();
1531
+ }
1532
+ }),
1533
+ // Error handler
1534
+ catchError(error => {
1535
+ debug(`apps loader error: ${error}`);
1536
+ this.errorHandler(error);
1537
+ return [];
1538
+ }));
1539
+ }))
1540
+ .subscribe();
1541
+ }
1542
+ startLoadAppAssets(app) {
1543
+ if (this.inProgressAppAssetsLoads.get(app.name)) {
1544
+ return this.inProgressAppAssetsLoads.get(app.name);
1545
+ }
1546
+ else {
1547
+ const loadApp$ = this.assetsLoader.loadAppAssets(app).pipe(tap(() => {
1548
+ this.inProgressAppAssetsLoads.delete(app.name);
1549
+ this.setAppStatus(app, ApplicationStatus.assetsLoaded);
1550
+ }), map(() => {
1551
+ return app;
1552
+ }), catchError(error => {
1553
+ this.inProgressAppAssetsLoads.delete(app.name);
1554
+ this.setAppStatus(app, ApplicationStatus.loadError);
1555
+ throw error;
1556
+ }), share());
1557
+ this.inProgressAppAssetsLoads.set(app.name, loadApp$);
1558
+ this.setAppStatus(app, ApplicationStatus.assetsLoading);
1559
+ return loadApp$;
1560
+ }
1561
+ }
1562
+ hideApp(planetApp) {
1563
+ const appRef = getPlanetApplicationRef(planetApp.name);
1564
+ const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
1565
+ if (appRootElement) {
1566
+ appRootElement.setAttribute('style', 'display:none;');
1567
+ }
1568
+ }
1569
+ showApp(planetApp) {
1570
+ const appRef = getPlanetApplicationRef(planetApp.name);
1571
+ const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
1572
+ if (appRootElement) {
1573
+ appRootElement.setAttribute('style', '');
1574
+ }
1575
+ }
1576
+ destroyApp(planetApp) {
1577
+ const appRef = getPlanetApplicationRef(planetApp.name);
1578
+ if (appRef) {
1579
+ appRef.destroy();
1580
+ }
1581
+ const container = getHTMLElement(planetApp.hostParent);
1582
+ const appRootElement = container?.querySelector((appRef && appRef.selector) || planetApp.selector);
1583
+ if (appRootElement) {
1584
+ container?.removeChild(appRootElement);
1585
+ }
1586
+ }
1587
+ bootstrapApp(app, defaultStatus = 'display') {
1588
+ debug(`app(${app.name}) start bootstrapping`);
1589
+ this.setAppStatus(app, ApplicationStatus.bootstrapping);
1590
+ const appRef = getPlanetApplicationRef(app.name);
1591
+ if (appRef && appRef.bootstrap) {
1592
+ const container = getHTMLElement(app.hostParent);
1593
+ let appRootElement;
1594
+ if (container) {
1595
+ appRootElement = container.querySelector(appRef.selector || app.selector);
1596
+ if (!appRootElement) {
1597
+ if (appRef.template) {
1598
+ appRootElement = createElementByTemplate(appRef.template);
1599
+ }
1600
+ else {
1601
+ appRootElement = document.createElement(app.selector);
1602
+ }
1603
+ appRootElement.setAttribute('style', 'display:none;');
1604
+ if (app.hostClass) {
1605
+ appRootElement.classList.add(...coerceArray(app.hostClass));
1606
+ }
1607
+ if (app.stylePrefix) {
1608
+ appRootElement.classList.add(...coerceArray(app.stylePrefix));
1609
+ }
1610
+ container.appendChild(appRootElement);
1611
+ }
1612
+ }
1613
+ let result = appRef.bootstrap(this.portalApp);
1614
+ // Backwards compatibility promise for bootstrap
1615
+ if (result['then']) {
1616
+ result = from(result);
1617
+ }
1618
+ return result.pipe(tap(() => {
1619
+ debug(`app(${app.name}) bootstrapped success for ${defaultStatus}`);
1620
+ this.setAppStatus(app, ApplicationStatus.bootstrapped);
1621
+ if (defaultStatus === 'display' && appRootElement) {
1622
+ appRootElement.removeAttribute('style');
1623
+ }
1624
+ }), map(() => {
1625
+ return appRef;
1626
+ }));
1627
+ }
1628
+ else {
1629
+ throw new Error(`[${app.name}] not found, make sure that the app has the correct name defined use defineApplication(${app.name}) and runtimeChunk and vendorChunk are set to true, details see https://github.com/worktile/ngx-planet#throw-error-cannot-read-property-call-of-undefined-at-__webpack_require__-bootstrap79`);
1630
+ }
1631
+ }
1632
+ getUnloadApps(activeApps) {
1633
+ const unloadApps = [];
1634
+ this.appsStatus.forEach((value, app) => {
1635
+ if (value === ApplicationStatus.active && !activeApps.find(item => item.name === app.name)) {
1636
+ unloadApps.push(app);
1637
+ }
1638
+ });
1639
+ return unloadApps;
1640
+ }
1641
+ unloadApps(shouldUnloadApps, event) {
1642
+ const hideApps = [];
1643
+ const destroyApps = [];
1644
+ shouldUnloadApps.forEach(app => {
1645
+ if (this.switchModeIsCoexist(app)) {
1646
+ debug(`hide app(${app.name}) for coexist mode`);
1647
+ hideApps.push(app);
1648
+ this.hideApp(app);
1649
+ this.setAppStatus(app, ApplicationStatus.bootstrapped);
1650
+ }
1651
+ else {
1652
+ destroyApps.push(app);
1653
+ // 销毁之前先隐藏,否则会出现闪烁,因为 destroy 是延迟执行的
1654
+ // 如果销毁不延迟执行,会出现切换到主应用的时候会有视图卡顿现象
1655
+ this.hideApp(app);
1656
+ this.setAppStatus(app, ApplicationStatus.assetsLoaded);
1657
+ }
1658
+ });
1659
+ if (hideApps.length > 0 || destroyApps.length > 0) {
1660
+ // 从其他应用切换到主应用的时候会有视图卡顿现象,所以先等主应用渲染完毕后再加载其他应用
1661
+ // 此处尝试使用 this.ngZone.onStable.pipe(take(1)) 应用之间的切换会出现闪烁
1662
+ setTimeout(() => {
1663
+ hideApps.forEach(app => {
1664
+ const appRef = getPlanetApplicationRef(app.name);
1665
+ if (appRef) {
1666
+ appRef.navigateByUrl(event.url);
1667
+ }
1668
+ });
1669
+ destroyApps.forEach(app => {
1670
+ debug(`destroy app(${app.name})`);
1671
+ this.destroyApp(app);
1672
+ });
1673
+ });
1674
+ }
1675
+ }
1676
+ preloadApps(activeApps) {
1677
+ setTimeout(() => {
1678
+ const toPreloadApps = this.planetApplicationService.getAppsToPreload(activeApps ? activeApps.map(item => item.name) : undefined);
1679
+ debug(`start preload apps: ${this.getAppNames(toPreloadApps)}`);
1680
+ const loadApps$ = toPreloadApps.map(preloadApp => {
1681
+ return this.preloadInternal(preloadApp);
1682
+ });
1683
+ forkJoin(loadApps$).subscribe({
1684
+ error: error => {
1685
+ this.errorHandler(error);
1686
+ }
1687
+ });
1688
+ });
1689
+ }
1690
+ ensurePreloadApps(activeApps) {
1691
+ // Start preload apps
1692
+ // Start preload when first time app loaded
1693
+ if (this.firstLoad) {
1694
+ this.preloadApps(activeApps);
1695
+ this.firstLoad = false;
1696
+ }
1697
+ }
1698
+ setOptions(options) {
1699
+ this.options = {
1700
+ ...this.options,
1701
+ ...options
1702
+ };
1703
+ }
1704
+ /**
1705
+ * reset route by current router
1706
+ */
1707
+ reroute(event) {
1708
+ this.routeChange$.next(event);
1709
+ }
1710
+ preloadInternal(app, immediate) {
1711
+ const status = this.appsStatus.get(app);
1712
+ if (!status || status === ApplicationStatus.loadError) {
1713
+ debug(`preload app(${app.name}), status is empty, start to load assets`);
1714
+ return this.startLoadAppAssets(app).pipe(switchMap(() => {
1715
+ debug(`preload app(${app.name}), assets loaded, start bootstrap app, immediate: ${!!immediate}`);
1716
+ if (immediate) {
1717
+ return this.bootstrapApp(app, 'hidden');
1718
+ }
1719
+ else {
1720
+ return this.ngZone.runOutsideAngular(() => {
1721
+ return this.bootstrapApp(app, 'hidden');
1722
+ });
1723
+ }
1724
+ }), catchError(error => {
1725
+ this.errorHandler(error);
1726
+ return of(null);
1727
+ }), map(() => {
1728
+ return getPlanetApplicationRef(app.name);
1729
+ }));
1730
+ }
1731
+ else if ([ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(status)) {
1732
+ debug(`preload app(${app.name}), status is ${ApplicationStatus[status]}, return until bootstrapped`);
1733
+ return this.getAppStatusChange$(app).pipe(take(1), map(() => {
1734
+ return getPlanetApplicationRef(app.name);
1735
+ }));
1736
+ }
1737
+ else {
1738
+ const appRef = getPlanetApplicationRef(app.name);
1739
+ if (!appRef) {
1740
+ throw new Error(`${app.name}'s status is ${ApplicationStatus[status]}, planetApplicationRef is null.`);
1741
+ }
1742
+ return of(appRef);
1743
+ }
1744
+ }
1745
+ /**
1746
+ * Preload planet application
1747
+ * @param app app
1748
+ * @param immediate bootstrap on stable by default, setting immediate is true, it will bootstrap immediate
1749
+ */
1750
+ preload(app, immediate) {
1751
+ return this.preloadInternal(app, immediate);
1752
+ }
1753
+ }
1754
+ PlanetApplicationLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, deps: [{ token: AssetsLoader }, { token: PlanetApplicationService }, { token: i0.NgZone }, { token: i3.Router }, { token: i0.Injector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
1755
+ PlanetApplicationLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, providedIn: 'root' });
1756
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, decorators: [{
1757
+ type: Injectable,
1758
+ args: [{
1759
+ providedIn: 'root'
1760
+ }]
1761
+ }], ctorParameters: function () { return [{ type: AssetsLoader }, { type: PlanetApplicationService }, { type: i0.NgZone }, { type: i3.Router }, { type: i0.Injector }, { type: i0.ApplicationRef }]; } });
1762
+
1763
+ class Planet {
1764
+ constructor(injector, router, planetApplications) {
1765
+ this.injector = injector;
1766
+ this.router = router;
1767
+ if (!this.planetApplicationLoader) {
1768
+ setApplicationLoader(this.injector.get(PlanetApplicationLoader));
1769
+ }
1770
+ if (!this.planetApplicationService) {
1771
+ setApplicationService(this.injector.get(PlanetApplicationService));
1772
+ }
1773
+ if (planetApplications) {
1774
+ this.registerApps(planetApplications);
1775
+ }
1776
+ }
1777
+ get planetApplicationLoader() {
1778
+ return getApplicationLoader();
1779
+ }
1780
+ get planetApplicationService() {
1781
+ return getApplicationService();
1782
+ }
1783
+ get loadingDone() {
1784
+ return this.planetApplicationLoader.loadingDone;
1785
+ }
1786
+ get appStatusChange() {
1787
+ return this.planetApplicationLoader.appStatusChange;
1788
+ }
1789
+ get appsLoadingStart() {
1790
+ return this.planetApplicationLoader.appsLoadingStart;
1791
+ }
1792
+ setOptions(options) {
1793
+ this.planetApplicationLoader.setOptions(options);
1794
+ if (options.debugFactory) {
1795
+ setDebugFactory(options.debugFactory);
1796
+ }
1797
+ }
1798
+ setPortalAppData(data) {
1799
+ setPortalApplicationData(data);
1800
+ }
1801
+ registerApp(app) {
1802
+ this.planetApplicationService.register(app);
1803
+ }
1804
+ registerApps(apps) {
1805
+ this.planetApplicationService.register(apps);
1806
+ }
1807
+ unregisterApp(name) {
1808
+ this.planetApplicationService.unregister(name);
1809
+ }
1810
+ getApps() {
1811
+ return this.planetApplicationService.getApps();
1812
+ }
1813
+ start() {
1814
+ this.subscription = this.router.events
1815
+ .pipe(filter(event => {
1816
+ return event instanceof NavigationEnd;
1817
+ }), map(event => {
1818
+ return event.urlAfterRedirects || event.url;
1819
+ }), startWith(location.pathname), distinctUntilChanged())
1820
+ .subscribe((url) => {
1821
+ this.planetApplicationLoader.reroute({
1822
+ url: url
1823
+ });
1824
+ });
1825
+ }
1826
+ stop() {
1827
+ this.subscription?.unsubscribe();
1828
+ }
1829
+ }
1830
+ Planet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: Planet, deps: [{ token: i0.Injector }, { token: i3.Router }, { token: PLANET_APPLICATIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1831
+ Planet.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: Planet, providedIn: 'root' });
1832
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: Planet, decorators: [{
1833
+ type: Injectable,
1834
+ args: [{
1835
+ providedIn: 'root'
1836
+ }]
1837
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i3.Router }, { type: undefined, decorators: [{
1838
+ type: Inject,
1839
+ args: [PLANET_APPLICATIONS]
1840
+ }, {
1841
+ type: Optional
1842
+ }] }]; } });
1843
+
1844
+ class EmptyComponent {
1845
+ }
1846
+ EmptyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: EmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1847
+ EmptyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.2", type: EmptyComponent, selector: "empty-component", ngImport: i0, template: ``, isInline: true });
1848
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: EmptyComponent, decorators: [{
1849
+ type: Component,
1850
+ args: [{
1851
+ // eslint-disable-next-line @angular-eslint/component-selector
1852
+ selector: 'empty-component',
1853
+ template: ``
1854
+ }]
1855
+ }] });
1856
+
1857
+ class NgxPlanetModule {
1858
+ static forRoot(apps) {
1859
+ return {
1860
+ ngModule: NgxPlanetModule,
1861
+ providers: [
1862
+ {
1863
+ provide: PLANET_APPLICATIONS,
1864
+ useValue: apps
1865
+ }
1866
+ ]
1867
+ };
1868
+ }
1869
+ }
1870
+ NgxPlanetModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: NgxPlanetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1871
+ NgxPlanetModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.2", ngImport: i0, type: NgxPlanetModule, declarations: [EmptyComponent], imports: [HttpClientModule], exports: [HttpClientModule, EmptyComponent] });
1872
+ NgxPlanetModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: NgxPlanetModule, imports: [HttpClientModule, HttpClientModule] });
1873
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: NgxPlanetModule, decorators: [{
1874
+ type: NgModule,
1875
+ args: [{
1876
+ declarations: [EmptyComponent],
1877
+ imports: [HttpClientModule],
1878
+ providers: [],
1879
+ exports: [HttpClientModule, EmptyComponent]
1880
+ }]
1881
+ }] });
1882
+
1883
+ class PlanetComponentRef {
1884
+ }
1885
+
1886
+ const componentWrapperClass = 'planet-component-wrapper';
1887
+ class PlanetComponentLoader {
1888
+ constructor(applicationRef, ngModuleRef, ngZone, document) {
1889
+ this.applicationRef = applicationRef;
1890
+ this.ngModuleRef = ngModuleRef;
1891
+ this.ngZone = ngZone;
1892
+ this.document = document;
1893
+ this.domPortalOutletCache = new WeakMap();
1894
+ }
1895
+ get applicationLoader() {
1896
+ return getApplicationLoader();
1897
+ }
1898
+ get applicationService() {
1899
+ return getApplicationService();
1900
+ }
1901
+ getPlantAppRef(name) {
1902
+ if (globalPlanet.apps[name] && globalPlanet.apps[name].appModuleRef) {
1903
+ return of(globalPlanet.apps[name]);
1904
+ }
1905
+ else {
1906
+ const app = this.applicationService.getAppByName(name);
1907
+ return this.applicationLoader.preload(app, true).pipe(map(() => {
1908
+ return globalPlanet.apps[name];
1909
+ }));
1910
+ }
1911
+ }
1912
+ createInjector(appModuleRef, componentRef) {
1913
+ const injectionTokens = new WeakMap([[PlanetComponentRef, componentRef]]);
1914
+ const defaultInjector = appModuleRef.injector;
1915
+ return new PortalInjector(defaultInjector, injectionTokens);
1916
+ }
1917
+ getContainerElement(config) {
1918
+ if (!config.container) {
1919
+ throw new Error(`config 'container' cannot be null`);
1920
+ }
1921
+ else {
1922
+ if (config.container.nativeElement) {
1923
+ return config.container.nativeElement;
1924
+ }
1925
+ else {
1926
+ return config.container;
1927
+ }
1928
+ }
1929
+ }
1930
+ createWrapperElement(config) {
1931
+ const container = this.getContainerElement(config);
1932
+ const element = this.document.createElement('div');
1933
+ const subApp = this.applicationService.getAppByName(this.ngModuleRef.instance.appName);
1934
+ element.classList.add(componentWrapperClass);
1935
+ element.setAttribute('planet-inline', '');
1936
+ if (config.wrapperClass) {
1937
+ element.classList.add(config.wrapperClass);
1938
+ }
1939
+ if (subApp && subApp.stylePrefix) {
1940
+ element.classList.add(subApp.stylePrefix);
1941
+ }
1942
+ container.appendChild(element);
1943
+ return element;
1944
+ }
1945
+ attachComponent(plantComponent, appModuleRef, config) {
1946
+ const plantComponentRef = new PlanetComponentRef();
1947
+ const componentFactoryResolver = appModuleRef.componentFactoryResolver;
1948
+ const appRef = this.applicationRef;
1949
+ const injector = this.createInjector(appModuleRef, plantComponentRef);
1950
+ const wrapper = this.createWrapperElement(config);
1951
+ let portalOutlet = this.domPortalOutletCache.get(wrapper);
1952
+ if (portalOutlet) {
1953
+ portalOutlet.detach();
1954
+ }
1955
+ else {
1956
+ portalOutlet = new DomPortalOutlet(wrapper, componentFactoryResolver, appRef, injector);
1957
+ this.domPortalOutletCache.set(wrapper, portalOutlet);
1958
+ }
1959
+ const componentPortal = new ComponentPortal(plantComponent.component, null);
1960
+ const componentRef = portalOutlet.attachComponentPortal(componentPortal);
1961
+ if (config.initialState) {
1962
+ Object.assign(componentRef.instance, config.initialState);
1963
+ }
1964
+ plantComponentRef.componentInstance = componentRef.instance;
1965
+ plantComponentRef.componentRef = componentRef;
1966
+ plantComponentRef.wrapperElement = wrapper;
1967
+ plantComponentRef.dispose = () => {
1968
+ this.domPortalOutletCache.delete(wrapper);
1969
+ portalOutlet.dispose();
1970
+ };
1971
+ return plantComponentRef;
1972
+ }
1973
+ registerComponentFactory(componentOrComponents) {
1974
+ const app = this.ngModuleRef.instance.appName;
1975
+ this.getPlantAppRef(app).subscribe(appRef => {
1976
+ appRef.registerComponentFactory((componentName, config) => {
1977
+ const components = coerceArray(componentOrComponents);
1978
+ const component = components.find(item => item.name === componentName);
1979
+ if (component) {
1980
+ return this.ngZone.run(() => {
1981
+ const componentRef = this.attachComponent(component, appRef.appModuleRef, config);
1982
+ return componentRef;
1983
+ });
1984
+ }
1985
+ else {
1986
+ throw Error(`unregistered component ${componentName} in app ${app}`);
1987
+ }
1988
+ });
1989
+ });
1990
+ }
1991
+ register(components) {
1992
+ setTimeout(() => {
1993
+ this.registerComponentFactory(components);
1994
+ });
1995
+ }
1996
+ load(app, componentName, config) {
1997
+ const result = this.getPlantAppRef(app).pipe(delayWhen(appRef => {
1998
+ if (appRef.getComponentFactory()) {
1999
+ return of('');
2000
+ }
2001
+ else {
2002
+ // Because register use 'setTimeout',so timer 20
2003
+ return timer(20);
2004
+ }
2005
+ }), map(appRef => {
2006
+ const componentFactory = appRef.getComponentFactory();
2007
+ if (componentFactory) {
2008
+ return componentFactory(componentName, config);
2009
+ }
2010
+ else {
2011
+ throw new Error(`${app}'s component(${componentName}) is not registered`);
2012
+ }
2013
+ }), shareReplay());
2014
+ result.subscribe();
2015
+ return result;
2016
+ }
2017
+ }
2018
+ PlanetComponentLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetComponentLoader, deps: [{ token: i0.ApplicationRef }, { token: i0.NgModuleRef }, { token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
2019
+ PlanetComponentLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetComponentLoader, providedIn: 'root' });
2020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetComponentLoader, decorators: [{
2021
+ type: Injectable,
2022
+ args: [{
2023
+ providedIn: 'root'
2024
+ }]
2025
+ }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.NgModuleRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
2026
+ type: Inject,
2027
+ args: [DOCUMENT]
2028
+ }] }]; } });
2029
+
2030
+ class PlantComponentConfig {
2031
+ constructor() {
2032
+ /** Data being injected into the child component. */
2033
+ this.initialState = null;
2034
+ }
2035
+ }
2036
+
2037
+ /*
2038
+ * Public API Surface of core
2039
+ */
2040
+
2041
+ /**
2042
+ * Generated bundle index. Do not edit.
2043
+ */
2044
+
2045
+ export { ApplicationStatus, AssetsLoader, EmptyComponent, GlobalEventDispatcher, NgxPlanetModule, PLANET_APPLICATIONS, Planet, PlanetApplicationLoader, PlanetApplicationRef, PlanetApplicationService, PlanetComponentLoader, PlanetComponentRef, PlanetPortalApplication, PlantComponentConfig, SwitchModes, defineApplication, getPlanetApplicationRef, getPortalApplicationData };
2046
+ //# sourceMappingURL=worktile-planet.mjs.map