diff options
Diffstat (limited to 'client/src/app/core/plugins/plugin.service.ts')
-rw-r--r-- | client/src/app/core/plugins/plugin.service.ts | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts index 7f751f479..4abe9ee8d 100644 --- a/client/src/app/core/plugins/plugin.service.ts +++ b/client/src/app/core/plugins/plugin.service.ts | |||
@@ -7,7 +7,7 @@ import { PluginScope } from '@shared/models/plugins/plugin-scope.type' | |||
7 | import { environment } from '../../../environments/environment' | 7 | import { environment } from '../../../environments/environment' |
8 | import { RegisterHookOptions } from '@shared/models/plugins/register.model' | 8 | import { RegisterHookOptions } from '@shared/models/plugins/register.model' |
9 | import { ReplaySubject } from 'rxjs' | 9 | import { ReplaySubject } from 'rxjs' |
10 | import { first } from 'rxjs/operators' | 10 | import { first, shareReplay } from 'rxjs/operators' |
11 | 11 | ||
12 | interface HookStructValue extends RegisterHookOptions { | 12 | interface HookStructValue extends RegisterHookOptions { |
13 | plugin: ServerConfigPlugin | 13 | plugin: ServerConfigPlugin |
@@ -21,6 +21,7 @@ export class PluginService { | |||
21 | private plugins: ServerConfigPlugin[] = [] | 21 | private plugins: ServerConfigPlugin[] = [] |
22 | private scopes: { [ scopeName: string ]: { plugin: ServerConfigPlugin, clientScript: ClientScript }[] } = {} | 22 | private scopes: { [ scopeName: string ]: { plugin: ServerConfigPlugin, clientScript: ClientScript }[] } = {} |
23 | private loadedScripts: { [ script: string ]: boolean } = {} | 23 | private loadedScripts: { [ script: string ]: boolean } = {} |
24 | private loadedScopes: PluginScope[] = [] | ||
24 | 25 | ||
25 | private hooks: { [ name: string ]: HookStructValue[] } = {} | 26 | private hooks: { [ name: string ]: HookStructValue[] } = {} |
26 | 27 | ||
@@ -43,14 +44,48 @@ export class PluginService { | |||
43 | 44 | ||
44 | ensurePluginsAreLoaded () { | 45 | ensurePluginsAreLoaded () { |
45 | return this.pluginsLoaded.asObservable() | 46 | return this.pluginsLoaded.asObservable() |
46 | .pipe(first()) | 47 | .pipe(first(), shareReplay()) |
47 | .toPromise() | 48 | .toPromise() |
48 | } | 49 | } |
49 | 50 | ||
51 | addPlugin (plugin: ServerConfigPlugin) { | ||
52 | for (const key of Object.keys(plugin.clientScripts)) { | ||
53 | const clientScript = plugin.clientScripts[key] | ||
54 | |||
55 | for (const scope of clientScript.scopes) { | ||
56 | if (!this.scopes[scope]) this.scopes[scope] = [] | ||
57 | |||
58 | this.scopes[scope].push({ | ||
59 | plugin, | ||
60 | clientScript: { | ||
61 | script: environment.apiUrl + `/plugins/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`, | ||
62 | scopes: clientScript.scopes | ||
63 | } | ||
64 | }) | ||
65 | |||
66 | this.loadedScripts[clientScript.script] = false | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | removePlugin (plugin: ServerConfigPlugin) { | ||
72 | for (const key of Object.keys(this.scopes)) { | ||
73 | this.scopes[key] = this.scopes[key].filter(o => o.plugin.name !== plugin.name) | ||
74 | } | ||
75 | } | ||
76 | |||
77 | async reloadLoadedScopes () { | ||
78 | for (const scope of this.loadedScopes) { | ||
79 | await this.loadPluginsByScope(scope) | ||
80 | } | ||
81 | } | ||
82 | |||
50 | async loadPluginsByScope (scope: PluginScope) { | 83 | async loadPluginsByScope (scope: PluginScope) { |
51 | try { | 84 | try { |
52 | await this.ensurePluginsAreLoaded() | 85 | await this.ensurePluginsAreLoaded() |
53 | 86 | ||
87 | this.loadedScopes.push(scope) | ||
88 | |||
54 | const toLoad = this.scopes[ scope ] | 89 | const toLoad = this.scopes[ scope ] |
55 | if (!Array.isArray(toLoad)) return | 90 | if (!Array.isArray(toLoad)) return |
56 | 91 | ||
@@ -63,7 +98,7 @@ export class PluginService { | |||
63 | this.loadedScripts[ clientScript.script ] = true | 98 | this.loadedScripts[ clientScript.script ] = true |
64 | } | 99 | } |
65 | 100 | ||
66 | return Promise.all(promises) | 101 | await Promise.all(promises) |
67 | } catch (err) { | 102 | } catch (err) { |
68 | console.error('Cannot load plugins by scope %s.', scope, err) | 103 | console.error('Cannot load plugins by scope %s.', scope, err) |
69 | } | 104 | } |
@@ -101,29 +136,14 @@ export class PluginService { | |||
101 | 136 | ||
102 | console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name) | 137 | console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name) |
103 | 138 | ||
104 | const url = environment.apiUrl + `/plugins/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}` | 139 | return import(/* webpackIgnore: true */ clientScript.script) |
105 | |||
106 | return import(/* webpackIgnore: true */ url) | ||
107 | .then(script => script.register({ registerHook })) | 140 | .then(script => script.register({ registerHook })) |
108 | .then(() => this.sortHooksByPriority()) | 141 | .then(() => this.sortHooksByPriority()) |
109 | } | 142 | } |
110 | 143 | ||
111 | private buildScopeStruct () { | 144 | private buildScopeStruct () { |
112 | for (const plugin of this.plugins) { | 145 | for (const plugin of this.plugins) { |
113 | for (const key of Object.keys(plugin.clientScripts)) { | 146 | this.addPlugin(plugin) |
114 | const clientScript = plugin.clientScripts[key] | ||
115 | |||
116 | for (const scope of clientScript.scopes) { | ||
117 | if (!this.scopes[scope]) this.scopes[scope] = [] | ||
118 | |||
119 | this.scopes[scope].push({ | ||
120 | plugin, | ||
121 | clientScript | ||
122 | }) | ||
123 | |||
124 | this.loadedScripts[clientScript.script] = false | ||
125 | } | ||
126 | } | ||
127 | } | 147 | } |
128 | } | 148 | } |
129 | 149 | ||