piral-blazor 1.0.0-pre.2217 → 1.0.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.
Files changed (236) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +55 -12
  3. package/convert.d.ts +13 -10
  4. package/convert.js +17 -12
  5. package/esm/converter.d.ts +10 -6
  6. package/esm/converter.js +164 -48
  7. package/esm/converter.js.map +1 -1
  8. package/esm/create.d.ts +21 -1
  9. package/esm/create.js +29 -15
  10. package/esm/create.js.map +1 -1
  11. package/esm/dependencies.d.ts +6 -3
  12. package/esm/dependencies.js +104 -14
  13. package/esm/dependencies.js.map +1 -1
  14. package/esm/events.d.ts +6 -0
  15. package/esm/events.js +145 -0
  16. package/esm/events.js.map +1 -0
  17. package/esm/interop.d.ts +29 -0
  18. package/esm/interop.js +205 -0
  19. package/esm/interop.js.map +1 -0
  20. package/esm/navigation.d.ts +2 -0
  21. package/esm/navigation.js +30 -0
  22. package/esm/navigation.js.map +1 -0
  23. package/esm/types.d.ts +97 -4
  24. package/infra.codegen +53 -68
  25. package/lib/converter.d.ts +10 -6
  26. package/lib/converter.js +164 -48
  27. package/lib/converter.js.map +1 -1
  28. package/lib/create.d.ts +21 -1
  29. package/lib/create.js +31 -17
  30. package/lib/create.js.map +1 -1
  31. package/lib/dependencies.d.ts +6 -3
  32. package/lib/dependencies.js +104 -14
  33. package/lib/dependencies.js.map +1 -1
  34. package/lib/events.d.ts +6 -0
  35. package/lib/events.js +154 -0
  36. package/lib/events.js.map +1 -0
  37. package/lib/index.js +1 -1
  38. package/lib/interop.d.ts +29 -0
  39. package/lib/interop.js +226 -0
  40. package/lib/interop.js.map +1 -0
  41. package/lib/navigation.d.ts +2 -0
  42. package/lib/navigation.js +35 -0
  43. package/lib/navigation.js.map +1 -0
  44. package/lib/types.d.ts +97 -4
  45. package/package.json +26 -13
  46. package/src/converter.ts +237 -57
  47. package/src/create.ts +53 -9
  48. package/src/dependencies.ts +122 -14
  49. package/src/events.ts +174 -0
  50. package/src/interop.ts +273 -0
  51. package/src/navigation.ts +36 -0
  52. package/src/types.ts +115 -4
  53. package/convert.ts +0 -17
  54. package/esm/internal/Environment.d.ts +0 -3
  55. package/esm/internal/Environment.js +0 -6
  56. package/esm/internal/Environment.js.map +0 -1
  57. package/esm/internal/Platform/BootConfig.d.ts +0 -20
  58. package/esm/internal/Platform/BootConfig.js +0 -10
  59. package/esm/internal/Platform/BootConfig.js.map +0 -1
  60. package/esm/internal/Platform/Mono/MonoDebugger.d.ts +0 -3
  61. package/esm/internal/Platform/Mono/MonoDebugger.js +0 -43
  62. package/esm/internal/Platform/Mono/MonoDebugger.js.map +0 -1
  63. package/esm/internal/Platform/Mono/MonoPlatform.d.ts +0 -2
  64. package/esm/internal/Platform/Mono/MonoPlatform.js +0 -403
  65. package/esm/internal/Platform/Mono/MonoPlatform.js.map +0 -1
  66. package/esm/internal/Platform/Mono/TimezoneDataFile.d.ts +0 -1
  67. package/esm/internal/Platform/Mono/TimezoneDataFile.js +0 -51
  68. package/esm/internal/Platform/Mono/TimezoneDataFile.js.map +0 -1
  69. package/esm/internal/Platform/Platform.d.ts +0 -31
  70. package/esm/internal/Platform/Platform.js +0 -2
  71. package/esm/internal/Platform/Platform.js.map +0 -1
  72. package/esm/internal/Platform/Url.d.ts +0 -2
  73. package/esm/internal/Platform/Url.js +0 -11
  74. package/esm/internal/Platform/Url.js.map +0 -1
  75. package/esm/internal/Platform/WebAssemblyConfigLoader.d.ts +0 -4
  76. package/esm/internal/Platform/WebAssemblyConfigLoader.js +0 -64
  77. package/esm/internal/Platform/WebAssemblyConfigLoader.js.map +0 -1
  78. package/esm/internal/Platform/WebAssemblyResourceLoader.d.ts +0 -24
  79. package/esm/internal/Platform/WebAssemblyResourceLoader.js +0 -223
  80. package/esm/internal/Platform/WebAssemblyResourceLoader.js.map +0 -1
  81. package/esm/internal/Platform/WebAssemblyStartOptions.d.ts +0 -13
  82. package/esm/internal/Platform/WebAssemblyStartOptions.js +0 -2
  83. package/esm/internal/Platform/WebAssemblyStartOptions.js.map +0 -1
  84. package/esm/internal/Rendering/BrowserRenderer.d.ts +0 -38
  85. package/esm/internal/Rendering/BrowserRenderer.js +0 -458
  86. package/esm/internal/Rendering/BrowserRenderer.js.map +0 -1
  87. package/esm/internal/Rendering/ElementReferenceCapture.d.ts +0 -1
  88. package/esm/internal/Rendering/ElementReferenceCapture.js +0 -24
  89. package/esm/internal/Rendering/ElementReferenceCapture.js.map +0 -1
  90. package/esm/internal/Rendering/EventDelegator.d.ts +0 -20
  91. package/esm/internal/Rendering/EventDelegator.js +0 -236
  92. package/esm/internal/Rendering/EventDelegator.js.map +0 -1
  93. package/esm/internal/Rendering/EventFieldInfo.d.ts +0 -6
  94. package/esm/internal/Rendering/EventFieldInfo.js +0 -32
  95. package/esm/internal/Rendering/EventFieldInfo.js.map +0 -1
  96. package/esm/internal/Rendering/EventForDotNet.d.ts +0 -10
  97. package/esm/internal/Rendering/EventForDotNet.js +0 -194
  98. package/esm/internal/Rendering/EventForDotNet.js.map +0 -1
  99. package/esm/internal/Rendering/LogicalElements.d.ts +0 -19
  100. package/esm/internal/Rendering/LogicalElements.js +0 -250
  101. package/esm/internal/Rendering/LogicalElements.js.map +0 -1
  102. package/esm/internal/Rendering/RenderBatch/BinaryDecoder.d.ts +0 -5
  103. package/esm/internal/Rendering/RenderBatch/BinaryDecoder.js +0 -34
  104. package/esm/internal/Rendering/RenderBatch/BinaryDecoder.js.map +0 -1
  105. package/esm/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.d.ts +0 -18
  106. package/esm/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.js +0 -190
  107. package/esm/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.js.map +0 -1
  108. package/esm/internal/Rendering/RenderBatch/RenderBatch.d.ts +0 -87
  109. package/esm/internal/Rendering/RenderBatch/RenderBatch.js +0 -26
  110. package/esm/internal/Rendering/RenderBatch/RenderBatch.js.map +0 -1
  111. package/esm/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.d.ts +0 -52
  112. package/esm/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.js +0 -103
  113. package/esm/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.js.map +0 -1
  114. package/esm/internal/Rendering/RenderBatch/Utf8Decoder.d.ts +0 -1
  115. package/esm/internal/Rendering/RenderBatch/Utf8Decoder.js +0 -63
  116. package/esm/internal/Rendering/RenderBatch/Utf8Decoder.js.map +0 -1
  117. package/esm/internal/Rendering/Renderer.d.ts +0 -8
  118. package/esm/internal/Rendering/Renderer.js +0 -69
  119. package/esm/internal/Rendering/Renderer.js.map +0 -1
  120. package/esm/internal/Rendering/RendererEventDispatcher.d.ts +0 -4
  121. package/esm/internal/Rendering/RendererEventDispatcher.js +0 -11
  122. package/esm/internal/Rendering/RendererEventDispatcher.js.map +0 -1
  123. package/esm/internal/Services/NavigationManager.d.ts +0 -16
  124. package/esm/internal/Services/NavigationManager.js +0 -138
  125. package/esm/internal/Services/NavigationManager.js.map +0 -1
  126. package/esm/internal/globals.d.ts +0 -1
  127. package/esm/internal/globals.js +0 -5
  128. package/esm/internal/globals.js.map +0 -1
  129. package/esm/internal/index.d.ts +0 -15
  130. package/esm/internal/index.js +0 -152
  131. package/esm/internal/index.js.map +0 -1
  132. package/lib/internal/Environment.d.ts +0 -3
  133. package/lib/internal/Environment.js +0 -9
  134. package/lib/internal/Environment.js.map +0 -1
  135. package/lib/internal/Platform/BootConfig.d.ts +0 -20
  136. package/lib/internal/Platform/BootConfig.js +0 -13
  137. package/lib/internal/Platform/BootConfig.js.map +0 -1
  138. package/lib/internal/Platform/Mono/MonoDebugger.d.ts +0 -3
  139. package/lib/internal/Platform/Mono/MonoDebugger.js +0 -48
  140. package/lib/internal/Platform/Mono/MonoDebugger.js.map +0 -1
  141. package/lib/internal/Platform/Mono/MonoPlatform.d.ts +0 -2
  142. package/lib/internal/Platform/Mono/MonoPlatform.js +0 -406
  143. package/lib/internal/Platform/Mono/MonoPlatform.js.map +0 -1
  144. package/lib/internal/Platform/Mono/TimezoneDataFile.d.ts +0 -1
  145. package/lib/internal/Platform/Mono/TimezoneDataFile.js +0 -55
  146. package/lib/internal/Platform/Mono/TimezoneDataFile.js.map +0 -1
  147. package/lib/internal/Platform/Platform.d.ts +0 -31
  148. package/lib/internal/Platform/Platform.js +0 -3
  149. package/lib/internal/Platform/Platform.js.map +0 -1
  150. package/lib/internal/Platform/Url.d.ts +0 -2
  151. package/lib/internal/Platform/Url.js +0 -16
  152. package/lib/internal/Platform/Url.js.map +0 -1
  153. package/lib/internal/Platform/WebAssemblyConfigLoader.d.ts +0 -4
  154. package/lib/internal/Platform/WebAssemblyConfigLoader.js +0 -67
  155. package/lib/internal/Platform/WebAssemblyConfigLoader.js.map +0 -1
  156. package/lib/internal/Platform/WebAssemblyResourceLoader.d.ts +0 -24
  157. package/lib/internal/Platform/WebAssemblyResourceLoader.js +0 -226
  158. package/lib/internal/Platform/WebAssemblyResourceLoader.js.map +0 -1
  159. package/lib/internal/Platform/WebAssemblyStartOptions.d.ts +0 -13
  160. package/lib/internal/Platform/WebAssemblyStartOptions.js +0 -3
  161. package/lib/internal/Platform/WebAssemblyStartOptions.js.map +0 -1
  162. package/lib/internal/Rendering/BrowserRenderer.d.ts +0 -38
  163. package/lib/internal/Rendering/BrowserRenderer.js +0 -461
  164. package/lib/internal/Rendering/BrowserRenderer.js.map +0 -1
  165. package/lib/internal/Rendering/ElementReferenceCapture.d.ts +0 -1
  166. package/lib/internal/Rendering/ElementReferenceCapture.js +0 -28
  167. package/lib/internal/Rendering/ElementReferenceCapture.js.map +0 -1
  168. package/lib/internal/Rendering/EventDelegator.d.ts +0 -20
  169. package/lib/internal/Rendering/EventDelegator.js +0 -239
  170. package/lib/internal/Rendering/EventDelegator.js.map +0 -1
  171. package/lib/internal/Rendering/EventFieldInfo.d.ts +0 -6
  172. package/lib/internal/Rendering/EventFieldInfo.js +0 -35
  173. package/lib/internal/Rendering/EventFieldInfo.js.map +0 -1
  174. package/lib/internal/Rendering/EventForDotNet.d.ts +0 -10
  175. package/lib/internal/Rendering/EventForDotNet.js +0 -197
  176. package/lib/internal/Rendering/EventForDotNet.js.map +0 -1
  177. package/lib/internal/Rendering/LogicalElements.d.ts +0 -19
  178. package/lib/internal/Rendering/LogicalElements.js +0 -265
  179. package/lib/internal/Rendering/LogicalElements.js.map +0 -1
  180. package/lib/internal/Rendering/RenderBatch/BinaryDecoder.d.ts +0 -5
  181. package/lib/internal/Rendering/RenderBatch/BinaryDecoder.js +0 -42
  182. package/lib/internal/Rendering/RenderBatch/BinaryDecoder.js.map +0 -1
  183. package/lib/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.d.ts +0 -18
  184. package/lib/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.js +0 -193
  185. package/lib/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.js.map +0 -1
  186. package/lib/internal/Rendering/RenderBatch/RenderBatch.d.ts +0 -87
  187. package/lib/internal/Rendering/RenderBatch/RenderBatch.js +0 -29
  188. package/lib/internal/Rendering/RenderBatch/RenderBatch.js.map +0 -1
  189. package/lib/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.d.ts +0 -52
  190. package/lib/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.js +0 -106
  191. package/lib/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.js.map +0 -1
  192. package/lib/internal/Rendering/RenderBatch/Utf8Decoder.d.ts +0 -1
  193. package/lib/internal/Rendering/RenderBatch/Utf8Decoder.js +0 -66
  194. package/lib/internal/Rendering/RenderBatch/Utf8Decoder.js.map +0 -1
  195. package/lib/internal/Rendering/Renderer.d.ts +0 -8
  196. package/lib/internal/Rendering/Renderer.js +0 -76
  197. package/lib/internal/Rendering/Renderer.js.map +0 -1
  198. package/lib/internal/Rendering/RendererEventDispatcher.d.ts +0 -4
  199. package/lib/internal/Rendering/RendererEventDispatcher.js +0 -16
  200. package/lib/internal/Rendering/RendererEventDispatcher.js.map +0 -1
  201. package/lib/internal/Services/NavigationManager.d.ts +0 -16
  202. package/lib/internal/Services/NavigationManager.js +0 -144
  203. package/lib/internal/Services/NavigationManager.js.map +0 -1
  204. package/lib/internal/globals.d.ts +0 -1
  205. package/lib/internal/globals.js +0 -7
  206. package/lib/internal/globals.js.map +0 -1
  207. package/lib/internal/index.d.ts +0 -15
  208. package/lib/internal/index.js +0 -161
  209. package/lib/internal/index.js.map +0 -1
  210. package/src/internal/Environment.ts +0 -11
  211. package/src/internal/Platform/BootConfig.ts +0 -21
  212. package/src/internal/Platform/Mono/MonoDebugger.ts +0 -48
  213. package/src/internal/Platform/Mono/MonoPlatform.ts +0 -494
  214. package/src/internal/Platform/Mono/MonoTypes.d.ts +0 -27
  215. package/src/internal/Platform/Mono/TimezoneDataFile.ts +0 -46
  216. package/src/internal/Platform/Platform.ts +0 -40
  217. package/src/internal/Platform/Url.ts +0 -11
  218. package/src/internal/Platform/WebAssemblyConfigLoader.ts +0 -34
  219. package/src/internal/Platform/WebAssemblyResourceLoader.ts +0 -234
  220. package/src/internal/Platform/WebAssemblyStartOptions.ts +0 -22
  221. package/src/internal/Rendering/BrowserRenderer.ts +0 -616
  222. package/src/internal/Rendering/ElementReferenceCapture.ts +0 -27
  223. package/src/internal/Rendering/EventDelegator.ts +0 -293
  224. package/src/internal/Rendering/EventFieldInfo.ts +0 -31
  225. package/src/internal/Rendering/EventForDotNet.ts +0 -370
  226. package/src/internal/Rendering/LogicalElements.ts +0 -289
  227. package/src/internal/Rendering/RenderBatch/BinaryDecoder.ts +0 -43
  228. package/src/internal/Rendering/RenderBatch/OutOfProcessRenderBatch.ts +0 -244
  229. package/src/internal/Rendering/RenderBatch/RenderBatch.ts +0 -100
  230. package/src/internal/Rendering/RenderBatch/SharedMemoryRenderBatch.ts +0 -137
  231. package/src/internal/Rendering/RenderBatch/Utf8Decoder.ts +0 -66
  232. package/src/internal/Rendering/Renderer.ts +0 -98
  233. package/src/internal/Rendering/RendererEventDispatcher.ts +0 -20
  234. package/src/internal/Services/NavigationManager.ts +0 -157
  235. package/src/internal/globals.ts +0 -5
  236. package/src/internal/index.ts +0 -170
@@ -1,24 +1,132 @@
1
- import { addReference } from './internal';
1
+ import type { PiletMetadata } from 'piral-core';
2
+ import { loadBlazorPilet, loadResource, loadResourceWithSymbol, unloadBlazorPilet, unloadResource } from './interop';
2
3
  import type { createConverter } from './converter';
4
+ import type { BlazorDependencyLoader, BlazorRootConfig } from './types';
3
5
 
4
- export function createDependencyLoader(convert: ReturnType<typeof createConverter>, lazy = true) {
5
- let dependency: () => Promise<any>;
6
+ const loadedDependencies = (window.$blazorDependencies ??= []);
7
+ const depsWithPrios = (window.$blazorDependencyPrios ??= []);
8
+
9
+ export function createDependencyLoader(convert: ReturnType<typeof createConverter>) {
10
+ const definedBlazorReferences: Array<string> = [];
11
+ const loadedBlazorPilets: Array<string> = [];
12
+ let dependency: BlazorDependencyLoader;
6
13
 
7
14
  return {
8
15
  getDependency() {
9
16
  return dependency;
10
17
  },
11
- defineBlazorReferences(references) {
12
- const load = () =>
13
- Promise.all(
14
- references.map((reference) =>
15
- fetch(reference)
16
- .then((res) => res.blob())
17
- .then(addReference),
18
- ),
19
- );
20
- let result = !lazy && convert.loader.then(load);
21
- dependency = () => result || (result = load());
18
+ defineBlazorReferences(references: Array<string>, meta: Partial<PiletMetadata> = {}, satellites = {}, prio = 0) {
19
+ prio = Math.max(prio, 0);
20
+
21
+ const depWithPrio = {
22
+ prio,
23
+ load() {
24
+ return Promise.resolve();
25
+ },
26
+ };
27
+
28
+ let result: false | Promise<void> = false;
29
+ const load = async ([_, capabilities]: BlazorRootConfig) => {
30
+ // let others finish first
31
+ await Promise.all(depsWithPrios.filter((m) => m.prio > prio).map((m) => m.load()));
32
+
33
+ window.dispatchEvent(new CustomEvent('loading-blazor-pilet', { detail: meta }));
34
+
35
+ if (capabilities.includes('load')) {
36
+ // new loading mechanism
37
+
38
+ if (!capabilities.includes('language')) {
39
+ satellites = undefined;
40
+ }
41
+
42
+ const dependencies = references.filter((m) => m.endsWith('.dll'));
43
+ const dllUrl = dependencies.pop();
44
+ const piletName = dllUrl.substring(0, dllUrl.length - 4);
45
+ const piletPdb = `${piletName}.pdb`;
46
+ const pdbUrl = references.find((m) => m === piletPdb);
47
+ const id = Math.random().toString(26).substring(2);
48
+
49
+ await loadBlazorPilet(id, {
50
+ name: meta.name || '(unknown)',
51
+ version: meta.version || '0.0.0',
52
+ config: JSON.stringify(meta.config || {}),
53
+ baseUrl: meta.basePath || dllUrl.substring(0, dllUrl.lastIndexOf('/')).replace('/_framework/', '/'),
54
+ dependencies,
55
+ satellites,
56
+ dllUrl,
57
+ pdbUrl,
58
+ });
59
+
60
+ loadedBlazorPilets.push(id);
61
+ } else {
62
+ // old loading mechanism
63
+
64
+ for (const dllUrl of references) {
65
+ const dllName = dllUrl.substring(dllUrl.lastIndexOf('/') + 1);
66
+
67
+ if (dllUrl.endsWith('.dll')) {
68
+ const entry = loadedDependencies.find((m) => m.name === dllName);
69
+
70
+ if (entry) {
71
+ entry.count++;
72
+ await entry.promise;
73
+ } else {
74
+ const urlWithoutExtension = dllUrl.substring(0, dllUrl.length - 4);
75
+ const pdbName = `${urlWithoutExtension}.pdb`;
76
+ const pdbUrl = references.find((m) => m === pdbName);
77
+ const promise = pdbUrl ? loadResourceWithSymbol(dllUrl, pdbUrl) : loadResource(dllUrl);
78
+
79
+ loadedDependencies.push({
80
+ name: dllName,
81
+ url: dllUrl,
82
+ count: 1,
83
+ promise,
84
+ });
85
+
86
+ await promise;
87
+ }
88
+
89
+ definedBlazorReferences.push(dllName);
90
+ }
91
+ }
92
+ }
93
+
94
+ // inform remaining that this one finished
95
+ window.dispatchEvent(new CustomEvent('loaded-blazor-pilet', { detail: meta }));
96
+ };
97
+
98
+ depWithPrio.load = () => {
99
+ if (!result) {
100
+ result = convert.loader.then(load);
101
+ }
102
+
103
+ return result;
104
+ };
105
+ result = !convert.lazy && convert.loader.then(load);
106
+ dependency = (config) => result || (result = load(config));
107
+
108
+ if (prio) {
109
+ depsWithPrios.push(depWithPrio);
110
+ }
111
+ },
112
+ async releaseBlazorReferences() {
113
+ const references = definedBlazorReferences.splice(0, definedBlazorReferences.length);
114
+ const ids = loadedBlazorPilets.splice(0, loadedBlazorPilets.length);
115
+
116
+ // old way of loading
117
+ for (const reference of references) {
118
+ const entry = loadedDependencies.find((m) => m.name === reference);
119
+
120
+ if (--entry.count === 0) {
121
+ loadedDependencies.splice(loadedDependencies.indexOf(entry), 1);
122
+ await unloadResource(entry.url);
123
+ }
124
+ }
125
+
126
+ // new way of loading
127
+ for (const id of ids) {
128
+ await unloadBlazorPilet(id);
129
+ }
22
130
  },
23
131
  };
24
132
  }
package/src/events.ts ADDED
@@ -0,0 +1,174 @@
1
+ import type { ExtensionRegistration } from 'piral-core';
2
+ import { isInternalNavigation, performInternalNavigation } from './navigation';
3
+
4
+ const blazorRootId = 'blazor-root';
5
+ const eventParents: Array<HTMLElement> = [];
6
+
7
+ const globalEventNames = [
8
+ 'abort',
9
+ 'blur',
10
+ 'change',
11
+ 'error',
12
+ 'focus',
13
+ 'load',
14
+ 'loadend',
15
+ 'loadstart',
16
+ 'mouseenter',
17
+ 'mouseleave',
18
+ 'progress',
19
+ 'reset',
20
+ 'scroll',
21
+ 'submit',
22
+ 'unload',
23
+ 'DOMNodeInsertedIntoDocument',
24
+ 'DOMNodeRemovedFromDocument',
25
+ 'click',
26
+ 'dblclick',
27
+ 'mousedown',
28
+ 'mousemove',
29
+ 'mouseup',
30
+ ];
31
+
32
+ const eventNames = {
33
+ render: 'render-blazor-extension',
34
+ navigate: 'navigate-blazor',
35
+ piral: 'piral-blazor',
36
+ };
37
+
38
+ function isRooted(target: HTMLElement) {
39
+ let parent = target.parentElement;
40
+
41
+ while (parent) {
42
+ if (parent.id === blazorRootId) {
43
+ return true;
44
+ }
45
+
46
+ parent = parent.parentElement;
47
+ }
48
+
49
+ return false;
50
+ }
51
+
52
+ function findTarget(target: HTMLElement = document.body) {
53
+ if (eventParents.length === 0) {
54
+ return target;
55
+ } else if (target === document.body) {
56
+ return eventParents[0];
57
+ } else {
58
+ return target;
59
+ }
60
+ }
61
+
62
+ function dispatchToRoot(event: any) {
63
+ isInternalNavigation(event) && performInternalNavigation(event);
64
+
65
+ // the mutation event cannot be cloned (at least in Webkit-based browsers)
66
+ if (!(event instanceof MutationEvent) && !event.processed) {
67
+ const eventClone = new event.constructor(event.type, event);
68
+ document.getElementById(blazorRootId)?.dispatchEvent(eventClone);
69
+ // make sure to only process every event once; even though multiple boundaries might be active
70
+ event.processed = true;
71
+ }
72
+ }
73
+
74
+ export function emitRenderEvent(
75
+ source: HTMLElement,
76
+ name: string,
77
+ params: any,
78
+ sourceRef: any,
79
+ fallbackComponent: string | null,
80
+ ) {
81
+ const target = findTarget(source);
82
+ const empty = typeof fallbackComponent === 'string' ? () => {} : undefined;
83
+ const order =
84
+ typeof sourceRef !== 'undefined'
85
+ ? (elements: Array<ExtensionRegistration>) => {
86
+ const oldItems = elements.map((el, id) => ({
87
+ id,
88
+ pilet: el.pilet,
89
+ defaults: el.defaults ?? {},
90
+ }));
91
+ const newItems: Array<{ id: number }> = sourceRef.invokeMethod('Order', oldItems);
92
+ return newItems.map(({ id }) => elements[id]).filter(Boolean);
93
+ }
94
+ : undefined;
95
+ const eventInit = {
96
+ bubbles: true,
97
+ detail: {
98
+ target,
99
+ props: {
100
+ name,
101
+ params,
102
+ empty,
103
+ order,
104
+ },
105
+ },
106
+ };
107
+ const delayEmit = () =>
108
+ requestAnimationFrame(() => {
109
+ if (!isRooted(target)) {
110
+ target.dispatchEvent(new CustomEvent(eventNames.render, eventInit));
111
+ } else {
112
+ delayEmit();
113
+ }
114
+ });
115
+ delayEmit();
116
+ }
117
+
118
+ export function emitPiralEvent(type: string, args: any) {
119
+ document.body.dispatchEvent(
120
+ new CustomEvent(eventNames.piral, {
121
+ bubbles: false,
122
+ detail: {
123
+ type,
124
+ args,
125
+ },
126
+ }),
127
+ );
128
+ }
129
+
130
+ export function emitNavigateEvent(source: HTMLElement, to: string, replace = false, state?: any) {
131
+ findTarget(source).dispatchEvent(
132
+ new CustomEvent(eventNames.navigate, {
133
+ bubbles: true,
134
+ detail: {
135
+ to,
136
+ replace,
137
+ state,
138
+ },
139
+ }),
140
+ );
141
+ }
142
+
143
+ export function attachEvents(
144
+ host: HTMLElement,
145
+ render: (ev: CustomEvent) => void,
146
+ navigate: (ev: CustomEvent) => void,
147
+ forward: (ev: CustomEvent) => void,
148
+ ) {
149
+ eventParents.push(host);
150
+ host.addEventListener(eventNames.render, render, false);
151
+ host.addEventListener(eventNames.navigate, navigate, false);
152
+
153
+ if (eventParents.length === 1) {
154
+ document.body.addEventListener(eventNames.piral, forward, false);
155
+ }
156
+
157
+ return () => {
158
+ eventParents.splice(eventParents.indexOf(host), 1);
159
+ host.removeEventListener(eventNames.render, render, false);
160
+ host.removeEventListener(eventNames.navigate, navigate, false);
161
+
162
+ if (eventParents.length === 0) {
163
+ document.body.removeEventListener(eventNames.piral, forward, false);
164
+ }
165
+ };
166
+ }
167
+
168
+ export function addGlobalEventListeners(el: HTMLElement) {
169
+ globalEventNames.forEach((eventName) => el.addEventListener(eventName, dispatchToRoot));
170
+ }
171
+
172
+ export function removeGlobalEventListeners(el: HTMLElement) {
173
+ globalEventNames.forEach((eventName) => el.removeEventListener(eventName, dispatchToRoot));
174
+ }
package/src/interop.ts ADDED
@@ -0,0 +1,273 @@
1
+ import { PiletApi } from 'piral-core';
2
+ import { emitRenderEvent, emitNavigateEvent, emitPiralEvent } from './events';
3
+ import type { BlazorLogLevel, BlazorRootConfig, WebAssemblyStartOptions } from './types';
4
+
5
+ const wasmLib = 'Microsoft.AspNetCore.Components.WebAssembly';
6
+ const coreLib = 'Piral.Blazor.Core';
7
+
8
+ function isDotNet6OrBelow() {
9
+ return typeof window.Blazor._internal.NavigationLock === 'undefined';
10
+ }
11
+
12
+ function createBase() {
13
+ // Nothing found, we need to guess
14
+ const el = document.createElement('base');
15
+ let baseUrl = el.href;
16
+
17
+ // The main app is served by a script - but we don't know which one
18
+ // hence we just iterate over all the local ones and use the script
19
+ // that is served from the "shortest" route - should work almost
20
+ // always and if not - one can always explicitely set a <base> node
21
+ for (let i = document.scripts.length; i--; ) {
22
+ const s = document.scripts[i];
23
+ const src = s.getAttribute('src');
24
+
25
+ if (src && src.startsWith('/')) {
26
+ const segEnd = src.lastIndexOf('/');
27
+ const newUrl = src.substring(0, segEnd + 1);
28
+
29
+ if (baseUrl.split('/').length > newUrl.split('/').length) {
30
+ baseUrl = newUrl;
31
+ }
32
+ }
33
+ }
34
+
35
+ el.href = baseUrl;
36
+ return document.head.appendChild(el);
37
+ }
38
+
39
+ function prepareForStartup() {
40
+ const originalApplyHotReload = window.Blazor._internal.applyHotReload;
41
+ const queue = [];
42
+
43
+ const applyChanges = (api: PiletApi) => {
44
+ const pilet = api.meta;
45
+
46
+ if (pilet.config && pilet.config.blazorHotReload) {
47
+ for (const item of queue.splice(0, queue.length)) {
48
+ item();
49
+ }
50
+
51
+ window.Blazor._internal.applyHotReload = originalApplyHotReload;
52
+ }
53
+ };
54
+
55
+ window.Blazor._internal.applyHotReload = function (...args) {
56
+ queue.push(() => originalApplyHotReload.apply(this, args));
57
+ };
58
+
59
+ return getCapabilities().then((capabilities) => ({
60
+ capabilities,
61
+ applyChanges,
62
+ }));
63
+ }
64
+
65
+ function createBlazorStarter(publicPath: string): (opts: WebAssemblyStartOptions) => Promise<BlazorRootConfig> {
66
+ const root = document.body.appendChild(document.createElement('div'));
67
+
68
+ root.style.display = 'none';
69
+ root.id = 'blazor-root';
70
+
71
+ if (publicPath) {
72
+ const baseElement = document.head.querySelector('base') || createBase();
73
+ const originalBase = baseElement.href;
74
+ baseElement.href = publicPath;
75
+
76
+ return (opts) => {
77
+ const navManager = window.Blazor._internal.navigationManager;
78
+
79
+ //Overwrite to get NavigationManager in Blazor working, see https://github.com/smapiot/Piral.Blazor/issues/89
80
+ navManager.navigateTo = (
81
+ route: string,
82
+ opts: { forceLoad: boolean; replaceHistoryEntry: boolean; historyEntryState: any },
83
+ ) => {
84
+ if (opts.forceLoad) {
85
+ location.href = route;
86
+ return;
87
+ }
88
+
89
+ if (route.startsWith(location.origin) && '') {
90
+ // normalize "local" absolute URLs
91
+ route = route.substring(location.origin.length);
92
+ } else if (/^https?:\/\//.test(route)) {
93
+ // prevent absolute URLs to be a standard navigation
94
+ location.href = route;
95
+ return;
96
+ }
97
+
98
+ window.Blazor.emitNavigateEvent(undefined, route, opts.replaceHistoryEntry, opts.historyEntryState);
99
+ };
100
+
101
+ navManager.getBaseURI = () => originalBase;
102
+
103
+ return window.Blazor.start(opts)
104
+ .then(prepareForStartup)
105
+ .then(({ capabilities, applyChanges }) => {
106
+ baseElement.href = originalBase;
107
+ return [root, capabilities, applyChanges];
108
+ });
109
+ };
110
+ }
111
+
112
+ return (opts) =>
113
+ window.Blazor.start(opts)
114
+ .then(prepareForStartup)
115
+ .then(({ capabilities, applyChanges }) => [root, capabilities, applyChanges]);
116
+ }
117
+
118
+ function computePath() {
119
+ try {
120
+ throw new Error();
121
+ } catch (t) {
122
+ const e = ('' + t.stack).match(/(https?|file|ftp|chrome-extension|moz-extension):\/\/[^)\n]+/g);
123
+ if (e) {
124
+ return e[0].replace(/^((?:https?|file|ftp|chrome-extension|moz-extension):\/\/.+)\/[^\/]+$/, '$1') + '/';
125
+ }
126
+ }
127
+
128
+ return '/';
129
+ }
130
+
131
+ function addScript(url: string) {
132
+ return new Promise<void>((resolve, reject) => {
133
+ const script = document.createElement('script');
134
+ script.src = url;
135
+ script.onerror = () => reject();
136
+ script.onload = () => resolve();
137
+ document.body.appendChild(script);
138
+ });
139
+ }
140
+
141
+ export function processEvent(type: string, args: any) {
142
+ return window.DotNet.invokeMethodAsync(coreLib, 'ProcessEvent', type, args);
143
+ }
144
+
145
+ export function setLogLevel(logLevel: BlazorLogLevel) {
146
+ return window.DotNet.invokeMethodAsync(coreLib, 'SetLogLevel', logLevel);
147
+ }
148
+
149
+ export function createElement(moduleName: string, props: any): Promise<string> {
150
+ return window.DotNet.invokeMethodAsync(coreLib, 'CreateElement', moduleName, props);
151
+ }
152
+
153
+ export function updateElement(referenceId: string, props: any): Promise<string> {
154
+ return window.DotNet.invokeMethodAsync(coreLib, 'UpdateElement', referenceId, props);
155
+ }
156
+
157
+ export function destroyElement(referenceId: string): Promise<string> {
158
+ return window.DotNet.invokeMethodAsync(coreLib, 'DestroyElement', referenceId);
159
+ }
160
+
161
+ export function activate(moduleName: string, props: any): Promise<string> {
162
+ return window.DotNet.invokeMethodAsync(coreLib, 'Activate', moduleName, props);
163
+ }
164
+
165
+ export function reactivate(moduleName: string, referenceId: string, props: any): Promise<void> {
166
+ return window.DotNet.invokeMethodAsync(coreLib, 'Reactivate', moduleName, referenceId, props).catch(() => {
167
+ // Apparently an older version of Piral.Blazor, which does not support this
168
+ // discard this error silently (in the future we may print warnings here)
169
+ });
170
+ }
171
+
172
+ export function deactivate(moduleName: string, referenceId: string): Promise<void> {
173
+ return window.DotNet.invokeMethodAsync(coreLib, 'Deactivate', moduleName, referenceId);
174
+ }
175
+
176
+ export function callNotifyLocationChanged(url: string, replace: boolean, state: any): Promise<void> {
177
+ if (isDotNet6OrBelow()) {
178
+ return window.DotNet.invokeMethodAsync(wasmLib, 'NotifyLocationChanged', url, replace);
179
+ } else {
180
+ if (state !== undefined && typeof state !== 'string') {
181
+ state = JSON.stringify(state);
182
+ }
183
+
184
+ return window.DotNet.invokeMethodAsync(wasmLib, 'NotifyLocationChanged', url, state, replace);
185
+ }
186
+ }
187
+
188
+ export function setLanguage(language: string): Promise<void> {
189
+ return window.DotNet.invokeMethodAsync(coreLib, 'SetLanguage', language);
190
+ }
191
+
192
+ export function getCapabilities(): Promise<Array<string>> {
193
+ return window.DotNet.invokeMethodAsync(coreLib, 'GetCapabilities').catch(() => {
194
+ // Apparently an older version of Piral.Blazor, which does not support this
195
+ // discard this error silently (in the future we may print warnings here)
196
+ return [];
197
+ });
198
+ }
199
+
200
+ export function loadResource(url: string): Promise<void> {
201
+ return window.DotNet.invokeMethodAsync(coreLib, 'LoadComponentsFromLibrary', url);
202
+ }
203
+
204
+ export function loadResourceWithSymbol(dllUrl: string, pdbUrl: string): Promise<void> {
205
+ return window.DotNet.invokeMethodAsync(coreLib, 'LoadComponentsWithSymbolsFromLibrary', dllUrl, pdbUrl);
206
+ }
207
+
208
+ export function unloadResource(url: string): Promise<void> {
209
+ return window.DotNet.invokeMethodAsync(coreLib, 'UnloadComponentsFromLibrary', url);
210
+ }
211
+
212
+ export interface PiletData {
213
+ dllUrl: string;
214
+ pdbUrl?: string;
215
+ name: string;
216
+ version: string;
217
+ config: string;
218
+ baseUrl: string;
219
+ satellites?: Record<string, Array<string>>;
220
+ dependencies: Array<string>;
221
+ }
222
+
223
+ export function loadBlazorPilet(id: string, data: PiletData) {
224
+ return window.DotNet.invokeMethodAsync(coreLib, 'LoadPilet', id, data);
225
+ }
226
+
227
+ export function unloadBlazorPilet(id: string) {
228
+ return window.DotNet.invokeMethodAsync(coreLib, 'UnloadPilet', id);
229
+ }
230
+
231
+ export function initialize(scriptUrl: string, publicPath: string, opts: WebAssemblyStartOptions = {}) {
232
+ if (typeof opts.loadBootResource !== 'function') {
233
+ opts.loadBootResource = (type, name, url) =>
234
+ type === 'dotnetjs' ? url : fetch(url, { method: 'GET', cache: 'no-cache' });
235
+ }
236
+
237
+ return new Promise<BlazorRootConfig>((resolve, reject) => {
238
+ const startBlazor = createBlazorStarter(publicPath);
239
+ const script = document.createElement('script');
240
+ script.src = scriptUrl;
241
+ script.setAttribute('autostart', 'false');
242
+
243
+ script.onerror = () => reject();
244
+ script.onload = () => {
245
+ Object.assign(window.Blazor, {
246
+ emitRenderEvent,
247
+ emitNavigateEvent,
248
+ emitPiralEvent,
249
+ });
250
+
251
+ startBlazor(opts).then(resolve);
252
+ };
253
+
254
+ document.body.appendChild(script);
255
+ });
256
+ }
257
+
258
+ export function createBootLoader(scriptUrl: string, extraScriptUrls: Array<string>) {
259
+ const publicPath = computePath();
260
+
261
+ return (opts?: WebAssemblyStartOptions) => {
262
+ if (typeof window.$blazorLoader === 'undefined') {
263
+ window.dispatchEvent(new CustomEvent('loading-blazor-core'));
264
+
265
+ // we load all satellite scripts before we initialize blazor
266
+ window.$blazorLoader = Promise.all(extraScriptUrls.map(addScript)).then(() =>
267
+ initialize(scriptUrl, publicPath, opts),
268
+ );
269
+ }
270
+
271
+ return window.$blazorLoader;
272
+ };
273
+ }
@@ -0,0 +1,36 @@
1
+ function findClosestAncestor(element: Element | null, tagName: string) {
2
+ // tslint:disable-next-line:no-null-keyword
3
+ return !element ? null : element.tagName === tagName ? element : findClosestAncestor(element.parentElement, tagName);
4
+ }
5
+
6
+ function getAnchorTarget(event: MouseEvent) {
7
+ return findClosestAncestor(event.target as Element | null, 'A') as HTMLAnchorElement | null;
8
+ }
9
+
10
+ function isWithinBaseUriSpace(href: string) {
11
+ const baseURI = document.baseURI;
12
+ const baseUriUntilLastSlash = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);
13
+ return href.startsWith(baseUriUntilLastSlash);
14
+ }
15
+
16
+ function eventHasSpecialKey(event: MouseEvent) {
17
+ return event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
18
+ }
19
+
20
+ export function isInternalNavigation(event: MouseEvent) {
21
+ const anchorTarget = getAnchorTarget(event);
22
+ return (
23
+ event.type === 'click' &&
24
+ event.button === 0 &&
25
+ !eventHasSpecialKey(event) &&
26
+ anchorTarget?.hasAttribute('href') &&
27
+ isWithinBaseUriSpace(anchorTarget.href)
28
+ );
29
+ }
30
+
31
+ export function performInternalNavigation(event: MouseEvent) {
32
+ const anchorTarget = getAnchorTarget(event);
33
+ event.preventDefault();
34
+ const to = anchorTarget.getAttribute('href');
35
+ window.Blazor.emitNavigateEvent(anchorTarget, to);
36
+ }