@lvce-editor/iframe-worker 1.4.0 → 2.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 (2) hide show
  1. package/dist/iframeWorkerMain.js +765 -642
  2. package/package.json +10 -4
@@ -1,11 +1,6 @@
1
1
  const commands = Object.create(null);
2
- const registerCommand = (key, fn) => {
3
- commands[key] = fn;
4
- };
5
2
  const register = commandMap => {
6
- for (const [key, value] of Object.entries(commandMap)) {
7
- registerCommand(key, value);
8
- }
3
+ Object.assign(commands, commandMap);
9
4
  };
10
5
  const getCommand = key => {
11
6
  return commands[key];
@@ -18,449 +13,224 @@ const execute = (command, ...args) => {
18
13
  return fn(...args);
19
14
  };
20
15
 
21
- const createUrl = (protocol, host) => {
22
- return protocol + '//' + host;
16
+ const Two = '2.0';
17
+ const state = {
18
+ callbacks: Object.create(null)
23
19
  };
24
-
25
- const createLocalHostUrl = (locationProtocol, locationHost, isGitpod, webViewPort) => {
26
- if (isGitpod) {
27
- return createUrl(locationProtocol, locationHost.replace('3000', `${webViewPort}`));
28
- }
29
- return `http://localhost:${webViewPort}`;
20
+ const set = (id, fn) => {
21
+ state.callbacks[id] = fn;
30
22
  };
31
-
32
- const Web = 1;
33
- const Electron = 2;
34
- const Remote = 3;
35
- const Test = 4;
36
-
37
- /* istanbul ignore file */
38
-
39
- // TODO this should always be completely tree shaken out during build, maybe need to be marked as @__Pure for terser to work
40
-
41
- // TODO treeshake this function out when targeting electron
42
-
43
- /**
44
- * @returns {number}
45
- */
46
- const getPlatform = () => {
47
- // @ts-ignore
48
- if (typeof PLATFORM !== 'undefined') {
49
- // @ts-ignore
50
- return PLATFORM;
23
+ const get = id => {
24
+ return state.callbacks[id];
25
+ };
26
+ const remove = id => {
27
+ delete state.callbacks[id];
28
+ };
29
+ let id = 0;
30
+ const create$3 = () => {
31
+ return ++id;
32
+ };
33
+ const warn = (...args) => {
34
+ console.warn(...args);
35
+ };
36
+ const registerPromise = () => {
37
+ const id = create$3();
38
+ const {
39
+ resolve,
40
+ promise
41
+ } = Promise.withResolvers();
42
+ set(id, resolve);
43
+ return {
44
+ id,
45
+ promise
46
+ };
47
+ };
48
+ const resolve = (id, response) => {
49
+ const fn = get(id);
50
+ if (!fn) {
51
+ console.log(response);
52
+ warn(`callback ${id} may already be disposed`);
53
+ return;
51
54
  }
52
- // @ts-ignore
53
- if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
54
- return Test;
55
+ fn(response);
56
+ remove(id);
57
+ };
58
+ const create$2 = (method, params) => {
59
+ const {
60
+ id,
61
+ promise
62
+ } = registerPromise();
63
+ const message = {
64
+ jsonrpc: Two,
65
+ method,
66
+ params,
67
+ id
68
+ };
69
+ return {
70
+ message,
71
+ promise
72
+ };
73
+ };
74
+ class JsonRpcError extends Error {
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = 'JsonRpcError';
55
78
  }
56
- // TODO find a better way to pass runtime environment
57
- if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
58
- return Electron;
79
+ }
80
+ const NewLine$3 = '\n';
81
+ const DomException = 'DOMException';
82
+ const ReferenceError$1 = 'ReferenceError';
83
+ const SyntaxError$1 = 'SyntaxError';
84
+ const TypeError$1 = 'TypeError';
85
+ const getErrorConstructor = (message, type) => {
86
+ if (type) {
87
+ switch (type) {
88
+ case DomException:
89
+ return DOMException;
90
+ case TypeError$1:
91
+ return TypeError;
92
+ case SyntaxError$1:
93
+ return SyntaxError;
94
+ case ReferenceError$1:
95
+ return ReferenceError;
96
+ default:
97
+ return Error;
98
+ }
59
99
  }
60
- if (typeof name !== 'undefined' && name.endsWith('(Web)')) {
61
- return Web;
100
+ if (message.startsWith('TypeError: ')) {
101
+ return TypeError;
62
102
  }
63
- return Remote;
64
- };
65
- const platform = getPlatform();
66
-
67
- const getAssetDir = () => {
68
- // @ts-ignore
69
- if (typeof ASSET_DIR !== 'undefined') {
70
- // @ts-ignore
71
- return ASSET_DIR;
103
+ if (message.startsWith('SyntaxError: ')) {
104
+ return SyntaxError;
72
105
  }
73
- if (platform === Electron) {
74
- return '';
106
+ if (message.startsWith('ReferenceError: ')) {
107
+ return ReferenceError;
75
108
  }
76
- return '';
109
+ return Error;
77
110
  };
78
- const assetDir = getAssetDir();
79
-
80
- const getWebViewHtml = (baseUrl, locationOrigin, elements) => {
81
- if (!elements) {
82
- return '';
111
+ const constructError = (message, type, name) => {
112
+ const ErrorConstructor = getErrorConstructor(message, type);
113
+ if (ErrorConstructor === DOMException && name) {
114
+ return new ErrorConstructor(message, name);
83
115
  }
84
- const middle = [];
85
- middle.push('<meta charset="utf-8">');
86
- for (const element of elements) {
87
- if (element.type === 'title') {
88
- middle.push(`<title>${element.value}</title>`);
89
- } else if (element.type === 'script') {
90
- middle.push(`<script type="module" src="${locationOrigin}${assetDir}/js/preview-injected.js"></script>`);
91
- middle.push(`<script type="module" src="${locationOrigin}${baseUrl}/${element.path}"></script>`);
92
- } else if (element.type === 'css') {
93
- middle.push(`<link rel="stylesheet" href="${locationOrigin}${baseUrl}/${element.path}" />`);
116
+ if (ErrorConstructor === Error) {
117
+ const error = new Error(message);
118
+ if (name && name !== 'VError') {
119
+ error.name = name;
94
120
  }
121
+ return error;
95
122
  }
96
- const middleHtml = middle.join('\n ');
97
- let html = `<!DOCTYPE html>
98
- <html>
99
- <head>
100
- ${middleHtml}
101
- </head>
102
- </html>
103
- `;
104
- return html;
123
+ return new ErrorConstructor(message);
105
124
  };
106
-
107
- const WebView = 'lvce-oss-webview';
108
-
109
- const getWebView$1 = (webViews, webViewId) => {
110
- for (const webView of webViews) {
111
- if (webView.id === webViewId) {
112
- return webView;
113
- }
114
- }
115
- return undefined;
125
+ const getNewLineIndex$2 = (string, startIndex = undefined) => {
126
+ return string.indexOf(NewLine$3, startIndex);
116
127
  };
117
- const getWebViewPath = (webViews, webViewId) => {
118
- const webView = getWebView$1(webViews, webViewId);
119
- if (!webView) {
120
- return '';
128
+ const getParentStack = error => {
129
+ let parentStack = error.stack || error.data || error.message || '';
130
+ if (parentStack.startsWith(' at')) {
131
+ parentStack = error.message + NewLine$3 + parentStack;
121
132
  }
122
- return webView.path;
133
+ return parentStack;
123
134
  };
124
- const getWebViewUri = (webViews, webViewId) => {
125
- const webViewPath = getWebViewPath(webViews, webViewId);
126
- if (!webViewPath) {
127
- return '';
128
- }
129
- if (webViewPath.startsWith('/')) {
130
- // TODO make it work on windows also
131
- return `file://${webViewPath}`;
132
- }
133
- return webViewPath;
135
+ const joinLines$1 = lines => {
136
+ return lines.join(NewLine$3);
134
137
  };
135
- const getIframeSrcRemote = (webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root) => {
136
- const webView = getWebView$1(webViews, webViewId);
137
- const webViewUri = getWebViewUri(webViews, webViewId);
138
- if (!webViewUri) {
139
- return undefined;
140
- }
141
- let iframeSrc = webViewUri;
142
- let webViewRoot = webViewUri;
143
- if (platform === Electron) {
144
- const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
145
- iframeSrc = `${WebView}://-${relativePath}/`;
146
- // TODO
147
- } else if (platform === Remote) {
148
- const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
149
- if (webViewUri.startsWith('file://')) {
150
- // ignore
151
- webViewRoot = webViewUri.slice('file://'.length).replace('/index.html', '');
138
+ const MethodNotFound = -32601;
139
+ const Custom = -32001;
140
+ const splitLines$1 = lines => {
141
+ return lines.split(NewLine$3);
142
+ };
143
+ const restoreJsonRpcError = error => {
144
+ if (error && error instanceof Error) {
145
+ return error;
146
+ }
147
+ const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(1));
148
+ if (error && error.code && error.code === MethodNotFound) {
149
+ const restoredError = new JsonRpcError(error.message);
150
+ const parentStack = getParentStack(error);
151
+ restoredError.stack = parentStack + NewLine$3 + currentStack;
152
+ return restoredError;
153
+ }
154
+ if (error && error.message) {
155
+ const restoredError = constructError(error.message, error.type, error.name);
156
+ if (error.data) {
157
+ if (error.data.stack && error.data.type && error.message) {
158
+ restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
159
+ } else if (error.data.stack) {
160
+ restoredError.stack = error.data.stack;
161
+ }
162
+ if (error.data.codeFrame) {
163
+ // @ts-ignore
164
+ restoredError.codeFrame = error.data.codeFrame;
165
+ }
166
+ if (error.data.code) {
167
+ // @ts-ignore
168
+ restoredError.code = error.data.code;
169
+ }
170
+ if (error.data.type) {
171
+ // @ts-ignore
172
+ restoredError.name = error.data.type;
173
+ }
152
174
  } else {
153
- webViewRoot = root + relativePath;
175
+ if (error.stack) {
176
+ const lowerStack = restoredError.stack || '';
177
+ // @ts-ignore
178
+ const indexNewLine = getNewLineIndex$2(lowerStack);
179
+ const parentStack = getParentStack(error);
180
+ // @ts-ignore
181
+ restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
182
+ }
183
+ if (error.codeFrame) {
184
+ // @ts-ignore
185
+ restoredError.codeFrame = error.codeFrame;
186
+ }
154
187
  }
155
- iframeSrc = createLocalHostUrl(locationProtocol, locationHost, isGitpod, webViewPort);
188
+ return restoredError;
156
189
  }
157
- let iframeContent = getWebViewHtml('', '', webView.elements);
158
- // TODO either
159
- // - load webviews the same as in web using blob urls
160
- // - load webviews from a pattern like /webviews/:id/:fileName
161
- iframeContent = iframeContent.replaceAll('/media/', '/').replaceAll('//', '/');
162
- return {
163
- srcDoc: '',
164
- iframeSrc,
165
- webViewRoot,
166
- iframeContent
167
- };
168
- };
169
-
170
- const getBlobUrl = (content, contentType) => {
171
- const blob = new Blob([content], {
172
- type: contentType
173
- });
174
- const url = URL.createObjectURL(blob); // TODO dispose
175
- return url;
190
+ if (typeof error === 'string') {
191
+ return new Error(`JsonRpc Error: ${error}`);
192
+ }
193
+ return new Error(`JsonRpc Error: ${error}`);
176
194
  };
177
-
178
- const getDefaultBaseUrl = webView => {
179
- const {
180
- remotePath,
181
- path
182
- } = webView;
183
- if (remotePath) {
184
- if (remotePath.endsWith('/index.html')) {
185
- return remotePath.slice(0, -'/index.html'.length);
186
- }
187
- return remotePath;
195
+ const unwrapJsonRpcResult = responseMessage => {
196
+ if ('error' in responseMessage) {
197
+ const restoredError = restoreJsonRpcError(responseMessage.error);
198
+ throw restoredError;
188
199
  }
189
- if (path) {
190
- if (path.endsWith('/index.html')) {
191
- return path.slice(0, -'/index.html'.length);
192
- }
193
- return path;
200
+ if ('result' in responseMessage) {
201
+ return responseMessage.result;
194
202
  }
195
- return '';
196
- };
197
- const getWebViewBaseUrl = webView => {
198
- const defaultBaseUrl = getDefaultBaseUrl(webView);
199
- return defaultBaseUrl;
203
+ throw new JsonRpcError('unexpected response message');
200
204
  };
201
-
202
- const getIframeSrc$1 = (webView, locationOrigin) => {
203
- const baseUrl = getWebViewBaseUrl(webView);
204
- const srcHtml = getWebViewHtml(baseUrl, locationOrigin, webView.elements);
205
- if (srcHtml) {
206
- const blobUrl = getBlobUrl(srcHtml, 'text/html');
207
- return {
208
- srcDoc: '',
209
- iframeSrc: blobUrl,
210
- webViewRoot: '',
211
- iframeContent: ''
212
- };
205
+ const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
206
+ const getErrorType = prettyError => {
207
+ if (prettyError && prettyError.type) {
208
+ return prettyError.type;
213
209
  }
214
- return undefined;
215
- };
216
-
217
- const getWebView = (webViews, webViewId) => {
218
- for (const webView of webViews) {
219
- if (webView.id === webViewId) {
220
- return webView;
221
- }
210
+ if (prettyError && prettyError.constructor && prettyError.constructor.name) {
211
+ return prettyError.constructor.name;
222
212
  }
223
213
  return undefined;
224
214
  };
225
-
226
- const normalizeLine$1 = line => {
227
- if (line.startsWith('Error: ')) {
228
- return line.slice(`Error: `.length);
229
- }
230
- if (line.startsWith('VError: ')) {
231
- return line.slice(`VError: `.length);
215
+ const getErrorProperty = (error, prettyError) => {
216
+ if (error && error.code === E_COMMAND_NOT_FOUND) {
217
+ return {
218
+ code: MethodNotFound,
219
+ message: error.message,
220
+ data: error.stack
221
+ };
232
222
  }
233
- return line;
234
- };
235
- const getCombinedMessage$1 = (error, message) => {
236
- const stringifiedError = normalizeLine$1(`${error}`);
237
- if (message) {
238
- return `${message}: ${stringifiedError}`;
239
- }
240
- return stringifiedError;
241
- };
242
- const NewLine$2 = '\n';
243
- const getNewLineIndex$1 = (string, startIndex = undefined) => {
244
- return string.indexOf(NewLine$2, startIndex);
245
- };
246
- const mergeStacks$1 = (parent, child) => {
247
- if (!child) {
248
- return parent;
249
- }
250
- const parentNewLineIndex = getNewLineIndex$1(parent);
251
- const childNewLineIndex = getNewLineIndex$1(child);
252
- if (childNewLineIndex === -1) {
253
- return parent;
254
- }
255
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
256
- const childRest = child.slice(childNewLineIndex);
257
- const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
258
- if (parentFirstLine.includes(childFirstLine)) {
259
- return parentFirstLine + childRest;
260
- }
261
- return child;
262
- };
263
- let VError$1 = class VError extends Error {
264
- constructor(error, message) {
265
- const combinedMessage = getCombinedMessage$1(error, message);
266
- super(combinedMessage);
267
- this.name = 'VError';
268
- if (error instanceof Error) {
269
- this.stack = mergeStacks$1(this.stack, error.stack);
270
- }
271
- if (error.codeFrame) {
272
- // @ts-ignore
273
- this.codeFrame = error.codeFrame;
274
- }
275
- if (error.code) {
276
- // @ts-ignore
277
- this.code = error.code;
278
- }
279
- }
280
- };
281
-
282
- const getIframeSrc = (webViews, webViewId, webViewPort, root, isGitpod, locationProtocol, locationHost, locationOrigin) => {
283
- try {
284
- const webView = getWebView(webViews, webViewId);
285
- if (platform === Web) {
286
- return getIframeSrc$1(webView, locationOrigin);
287
- }
288
- return getIframeSrcRemote(webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root);
289
- } catch (error) {
290
- throw new VError$1(error, `Failed to construct webview iframe src`);
291
- }
292
- };
293
-
294
- const SemiColon = ';';
295
- const Space = ' ';
296
-
297
- const addSemicolon = line => {
298
- return line + SemiColon;
299
- };
300
-
301
- const getContentSecurityPolicy = items => {
302
- return items.map(addSemicolon).join(Space);
303
- };
304
-
305
- const getWebViewCsp = webView => {
306
- if (webView && webView.contentSecurityPolicy) {
307
- return getContentSecurityPolicy(webView.contentSecurityPolicy);
308
- }
309
- const csp = getContentSecurityPolicy([`default-src 'none'`, `script-src 'self'`, `style-src 'self'`, `img-src 'self'`, `media-src 'self'`]);
310
- return csp;
311
- };
312
-
313
- const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
314
- const frameAncestors = createUrl(locationProtocol, locationHost);
315
- return frameAncestors;
316
- };
317
-
318
- const getWebViewOrigin = webViewPort => {
319
- // TODO don't hardcode protocol
320
- let origin = '';
321
- if (platform === Electron) {
322
- origin = `${WebView}://-/`;
323
- } else if (platform === Remote) {
324
- origin = `http://localhost:${webViewPort}`;
325
- } else {
326
- origin = '*'; // TODO
327
- }
328
- return origin;
329
- };
330
-
331
- const AllowScripts = 'allow-scripts';
332
- const AllowSameOrigin = 'allow-same-origin';
333
-
334
- const getIframeSandbox = (webView, platform) => {
335
- const extensionSandbox = webView.sandbox || [];
336
- if (platform === Remote) {
337
- return [AllowScripts, AllowSameOrigin, ...extensionSandbox]; // TODO maybe disallow same origin
338
- }
339
- if (platform === Web) {
340
- return [AllowScripts, ...extensionSandbox];
341
- }
342
- // TODO set something for electron
343
- return [...extensionSandbox];
344
- };
345
-
346
- const getOrigin = () => {
347
- return location.origin;
348
- };
349
- const getHost = () => {
350
- return location.host;
351
- };
352
- const getProtocol = () => {
353
- return location.protocol;
354
- };
355
-
356
- const commandMap = {
357
- 'Location.getHost': getHost,
358
- 'Location.getOrigin': getOrigin,
359
- 'Location.getProtocol': getProtocol,
360
- 'WebView.getBaseUrl': getWebViewBaseUrl,
361
- 'WebView.getFrameAncestors': getWebViewFrameAncestors,
362
- 'WebView.getHtml': getWebViewHtml,
363
- 'WebView.getIframeSrc': getIframeSrc,
364
- 'WebView.getOrigin': getWebViewOrigin,
365
- 'WebView.getSandbox': getIframeSandbox,
366
- 'WebView.getWebViewCsp': getWebViewCsp
367
- };
368
-
369
- const Two = '2.0';
370
- class AssertionError extends Error {
371
- constructor(message) {
372
- super(message);
373
- this.name = 'AssertionError';
374
- }
375
- }
376
- const getType$1 = value => {
377
- switch (typeof value) {
378
- case 'number':
379
- return 'number';
380
- case 'function':
381
- return 'function';
382
- case 'string':
383
- return 'string';
384
- case 'object':
385
- if (value === null) {
386
- return 'null';
387
- }
388
- if (Array.isArray(value)) {
389
- return 'array';
390
- }
391
- return 'object';
392
- case 'boolean':
393
- return 'boolean';
394
- default:
395
- return 'unknown';
396
- }
397
- };
398
- const number = value => {
399
- const type = getType$1(value);
400
- if (type !== 'number') {
401
- throw new AssertionError('expected value to be of type number');
402
- }
403
- };
404
- const state$1 = {
405
- callbacks: Object.create(null)
406
- };
407
- const get = id => {
408
- return state$1.callbacks[id];
409
- };
410
- const remove = id => {
411
- delete state$1.callbacks[id];
412
- };
413
- const warn = (...args) => {
414
- console.warn(...args);
415
- };
416
- const resolve = (id, args) => {
417
- number(id);
418
- const fn = get(id);
419
- if (!fn) {
420
- console.log(args);
421
- warn(`callback ${id} may already be disposed`);
422
- return;
423
- }
424
- fn(args);
425
- remove(id);
426
- };
427
- class JsonRpcError extends Error {
428
- constructor(message) {
429
- super(message);
430
- this.name = 'JsonRpcError';
431
- }
432
- }
433
- const MethodNotFound = -32601;
434
- const Custom = -32001;
435
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
436
- const getType = prettyError => {
437
- if (prettyError && prettyError.type) {
438
- return prettyError.type;
439
- }
440
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
441
- return prettyError.constructor.name;
442
- }
443
- return undefined;
444
- };
445
- const getErrorProperty = (error, prettyError) => {
446
- if (error && error.code === E_COMMAND_NOT_FOUND) {
447
- return {
448
- code: MethodNotFound,
449
- message: error.message,
450
- data: error.stack
451
- };
452
- }
453
- return {
454
- code: Custom,
455
- message: prettyError.message,
456
- data: {
457
- stack: prettyError.stack,
458
- codeFrame: prettyError.codeFrame,
459
- type: getType(prettyError),
460
- code: prettyError.code,
461
- name: prettyError.name
462
- }
463
- };
223
+ return {
224
+ code: Custom,
225
+ message: prettyError.message,
226
+ data: {
227
+ stack: prettyError.stack,
228
+ codeFrame: prettyError.codeFrame,
229
+ type: getErrorType(prettyError),
230
+ code: prettyError.code,
231
+ name: prettyError.name
232
+ }
233
+ };
464
234
  };
465
235
  const create$1 = (message, error) => {
466
236
  return {
@@ -475,7 +245,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
475
245
  const errorProperty = getErrorProperty(error, prettyError);
476
246
  return create$1(message, errorProperty);
477
247
  };
478
- const create = (message, result) => {
248
+ const create$4 = (message, result) => {
479
249
  return {
480
250
  jsonrpc: Two,
481
251
  id: message.id,
@@ -484,7 +254,7 @@ const create = (message, result) => {
484
254
  };
485
255
  const getSuccessResponse = (message, result) => {
486
256
  const resultProperty = result ?? null;
487
- return create(message, resultProperty);
257
+ return create$4(message, resultProperty);
488
258
  };
489
259
  const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
490
260
  try {
@@ -504,32 +274,42 @@ const defaultRequiresSocket = () => {
504
274
  return false;
505
275
  };
506
276
  const defaultResolve = resolve;
507
- const handleJsonRpcMessage = async (...args) => {
508
- let message;
509
- let ipc;
510
- let execute;
511
- let preparePrettyError;
512
- let logError;
513
- let resolve;
514
- let requiresSocket;
277
+
278
+ // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
279
+ const normalizeParams = args => {
515
280
  if (args.length === 1) {
516
- const arg = args[0];
517
- message = arg.message;
518
- ipc = arg.ipc;
519
- execute = arg.execute;
520
- preparePrettyError = arg.preparePrettyError || defaultPreparePrettyError;
521
- logError = arg.logError || defaultLogError;
522
- requiresSocket = arg.requiresSocket || defaultRequiresSocket;
523
- resolve = arg.resolve || defaultResolve;
524
- } else {
525
- ipc = args[0];
526
- message = args[1];
527
- execute = args[2];
528
- resolve = args[3];
529
- preparePrettyError = args[4];
530
- logError = args[5];
531
- requiresSocket = args[6];
281
+ const options = args[0];
282
+ return {
283
+ ipc: options.ipc,
284
+ message: options.message,
285
+ execute: options.execute,
286
+ resolve: options.resolve || defaultResolve,
287
+ preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
288
+ logError: options.logError || defaultLogError,
289
+ requiresSocket: options.requiresSocket || defaultRequiresSocket
290
+ };
532
291
  }
292
+ return {
293
+ ipc: args[0],
294
+ message: args[1],
295
+ execute: args[2],
296
+ resolve: args[3],
297
+ preparePrettyError: args[4],
298
+ logError: args[5],
299
+ requiresSocket: args[6]
300
+ };
301
+ };
302
+ const handleJsonRpcMessage = async (...args) => {
303
+ const options = normalizeParams(args);
304
+ const {
305
+ message,
306
+ ipc,
307
+ execute,
308
+ resolve,
309
+ preparePrettyError,
310
+ logError,
311
+ requiresSocket
312
+ } = options;
533
313
  if ('id' in message) {
534
314
  if ('method' in message) {
535
315
  const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
@@ -550,38 +330,19 @@ const handleJsonRpcMessage = async (...args) => {
550
330
  }
551
331
  throw new JsonRpcError('unexpected message');
552
332
  };
553
-
554
- const requiresSocket = () => {
555
- return false;
556
- };
557
- const preparePrettyError = error => {
558
- return error;
559
- };
560
- const logError = error => {
561
- console.error(error);
562
- };
563
- const handleMessage = event => {
564
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
565
- };
566
-
567
- const handleIpc = ipc => {
568
- ipc.addEventListener('message', handleMessage);
569
- };
570
-
571
- const MessagePort$1 = 1;
572
- const ModuleWorker = 2;
573
- const ReferencePort = 3;
574
- const ModuleWorkerAndMessagePort = 8;
575
- const Auto = () => {
576
- // @ts-ignore
577
- if (globalThis.acceptPort) {
578
- return MessagePort$1;
579
- }
580
- // @ts-ignore
581
- if (globalThis.acceptReferencePort) {
582
- return ReferencePort;
333
+ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
334
+ const {
335
+ message,
336
+ promise
337
+ } = create$2(method, params);
338
+ {
339
+ ipc.send(message);
583
340
  }
584
- return ModuleWorkerAndMessagePort;
341
+ const responseMessage = await promise;
342
+ return unwrapJsonRpcResult(responseMessage);
343
+ };
344
+ const invoke = (ipc, method, ...params) => {
345
+ return invokeHelper(ipc, method, params);
585
346
  };
586
347
 
587
348
  const getData$1 = event => {
@@ -694,12 +455,6 @@ class IpcChildWithModuleWorker extends Ipc {
694
455
  const wrap$6 = global => {
695
456
  return new IpcChildWithModuleWorker(global);
696
457
  };
697
- const IpcChildWithModuleWorker$1 = {
698
- __proto__: null,
699
- listen: listen$4,
700
- signal: signal$3,
701
- wrap: wrap$6
702
- };
703
458
  const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
704
459
  const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
705
460
  const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
@@ -764,61 +519,472 @@ const getModuleSyntaxError = () => {
764
519
  code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
765
520
  };
766
521
  };
767
- const isModuleNotFoundError = stderr => {
768
- if (!stderr) {
769
- return false;
522
+ const isModuleNotFoundError = stderr => {
523
+ if (!stderr) {
524
+ return false;
525
+ }
526
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
527
+ };
528
+ const isNormalStackLine = line => {
529
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
530
+ };
531
+ const getDetails = lines => {
532
+ const index = lines.findIndex(isNormalStackLine);
533
+ if (index === -1) {
534
+ return {
535
+ actualMessage: joinLines(lines),
536
+ rest: []
537
+ };
538
+ }
539
+ let lastIndex = index - 1;
540
+ while (++lastIndex < lines.length) {
541
+ if (!isNormalStackLine(lines[lastIndex])) {
542
+ break;
543
+ }
544
+ }
545
+ return {
546
+ actualMessage: lines[index - 1],
547
+ rest: lines.slice(index, lastIndex)
548
+ };
549
+ };
550
+ const getHelpfulChildProcessError = (stdout, stderr) => {
551
+ if (isUnhelpfulNativeModuleError(stderr)) {
552
+ return getNativeModuleErrorMessage(stderr);
553
+ }
554
+ if (isModulesSyntaxError(stderr)) {
555
+ return getModuleSyntaxError();
556
+ }
557
+ if (isModuleNotFoundError(stderr)) {
558
+ return getModuleNotFoundError(stderr);
559
+ }
560
+ const lines = splitLines(stderr);
561
+ const {
562
+ actualMessage,
563
+ rest
564
+ } = getDetails(lines);
565
+ return {
566
+ message: `${actualMessage}`,
567
+ code: '',
568
+ stack: rest
569
+ };
570
+ };
571
+ const normalizeLine$1 = line => {
572
+ if (line.startsWith('Error: ')) {
573
+ return line.slice(`Error: `.length);
574
+ }
575
+ if (line.startsWith('VError: ')) {
576
+ return line.slice(`VError: `.length);
577
+ }
578
+ return line;
579
+ };
580
+ const getCombinedMessage$1 = (error, message) => {
581
+ const stringifiedError = normalizeLine$1(`${error}`);
582
+ if (message) {
583
+ return `${message}: ${stringifiedError}`;
584
+ }
585
+ return stringifiedError;
586
+ };
587
+ const NewLine$2 = '\n';
588
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
589
+ return string.indexOf(NewLine$2, startIndex);
590
+ };
591
+ const mergeStacks$1 = (parent, child) => {
592
+ if (!child) {
593
+ return parent;
594
+ }
595
+ const parentNewLineIndex = getNewLineIndex$1(parent);
596
+ const childNewLineIndex = getNewLineIndex$1(child);
597
+ if (childNewLineIndex === -1) {
598
+ return parent;
599
+ }
600
+ const parentFirstLine = parent.slice(0, parentNewLineIndex);
601
+ const childRest = child.slice(childNewLineIndex);
602
+ const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
603
+ if (parentFirstLine.includes(childFirstLine)) {
604
+ return parentFirstLine + childRest;
605
+ }
606
+ return child;
607
+ };
608
+ let VError$1 = class VError extends Error {
609
+ constructor(error, message) {
610
+ const combinedMessage = getCombinedMessage$1(error, message);
611
+ super(combinedMessage);
612
+ this.name = 'VError';
613
+ if (error instanceof Error) {
614
+ this.stack = mergeStacks$1(this.stack, error.stack);
615
+ }
616
+ if (error.codeFrame) {
617
+ // @ts-ignore
618
+ this.codeFrame = error.codeFrame;
619
+ }
620
+ if (error.code) {
621
+ // @ts-ignore
622
+ this.code = error.code;
623
+ }
624
+ }
625
+ };
626
+ class IpcError extends VError$1 {
627
+ // @ts-ignore
628
+ constructor(betterMessage, stdout = '', stderr = '') {
629
+ if (stdout || stderr) {
630
+ // @ts-ignore
631
+ const {
632
+ message,
633
+ code,
634
+ stack
635
+ } = getHelpfulChildProcessError(stdout, stderr);
636
+ const cause = new Error(message);
637
+ // @ts-ignore
638
+ cause.code = code;
639
+ cause.stack = stack;
640
+ super(cause, betterMessage);
641
+ } else {
642
+ super(betterMessage);
643
+ }
644
+ // @ts-ignore
645
+ this.name = 'IpcError';
646
+ // @ts-ignore
647
+ this.stdout = stdout;
648
+ // @ts-ignore
649
+ this.stderr = stderr;
650
+ }
651
+ }
652
+ const withResolvers = () => {
653
+ let _resolve;
654
+ const promise = new Promise(resolve => {
655
+ _resolve = resolve;
656
+ });
657
+ return {
658
+ resolve: _resolve,
659
+ promise
660
+ };
661
+ };
662
+ const waitForFirstMessage = async port => {
663
+ const {
664
+ resolve,
665
+ promise
666
+ } = withResolvers();
667
+ port.addEventListener('message', resolve, {
668
+ once: true
669
+ });
670
+ const event = await promise;
671
+ // @ts-ignore
672
+ return event.data;
673
+ };
674
+ const listen$3 = async () => {
675
+ const parentIpcRaw = listen$4();
676
+ signal$3(parentIpcRaw);
677
+ const parentIpc = wrap$6(parentIpcRaw);
678
+ const firstMessage = await waitForFirstMessage(parentIpc);
679
+ if (firstMessage.method !== 'initialize') {
680
+ throw new IpcError('unexpected first message');
681
+ }
682
+ const type = firstMessage.params[0];
683
+ if (type === 'message-port') {
684
+ parentIpc.send({
685
+ jsonrpc: '2.0',
686
+ id: firstMessage.id,
687
+ result: null
688
+ });
689
+ parentIpc.dispose();
690
+ const port = firstMessage.params[1];
691
+ return port;
692
+ }
693
+ return globalThis;
694
+ };
695
+ class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
696
+ constructor(port) {
697
+ super(port);
698
+ }
699
+ getData(event) {
700
+ return getData$1(event);
701
+ }
702
+ send(message) {
703
+ this._rawIpc.postMessage(message);
704
+ }
705
+ sendAndTransfer(message) {
706
+ const transfer = getTransferrables(message);
707
+ this._rawIpc.postMessage(message, transfer);
708
+ }
709
+ dispose() {
710
+ if (this._rawIpc.close) {
711
+ this._rawIpc.close();
712
+ }
713
+ }
714
+ onClose(callback) {
715
+ // ignore
716
+ }
717
+ onMessage(callback) {
718
+ this._rawIpc.addEventListener('message', callback);
719
+ this._rawIpc.start();
720
+ }
721
+ }
722
+ const wrap$5 = port => {
723
+ return new IpcChildWithModuleWorkerAndMessagePort(port);
724
+ };
725
+ const IpcChildWithModuleWorkerAndMessagePort$1 = {
726
+ __proto__: null,
727
+ listen: listen$3,
728
+ wrap: wrap$5
729
+ };
730
+
731
+ const createRpc = ipc => {
732
+ const rpc = {
733
+ invoke(method, ...params) {
734
+ return invoke(ipc, method, ...params);
735
+ }
736
+ };
737
+ return rpc;
738
+ };
739
+ const requiresSocket = () => {
740
+ return false;
741
+ };
742
+ const preparePrettyError = error => {
743
+ return error;
744
+ };
745
+ const logError = () => {
746
+ // handled by renderer worker
747
+ };
748
+ const handleMessage = event => {
749
+ return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
750
+ };
751
+ const handleIpc = ipc => {
752
+ ipc.addEventListener('message', handleMessage);
753
+ };
754
+
755
+ // @ts-ignore
756
+ const listen$1 = async () => {
757
+ const module = IpcChildWithModuleWorkerAndMessagePort$1;
758
+ const rawIpc = await module.listen();
759
+ const ipc = module.wrap(rawIpc);
760
+ return ipc;
761
+ };
762
+ const create = async ({
763
+ commandMap
764
+ }) => {
765
+ // TODO create a commandMap per rpc instance
766
+ register(commandMap);
767
+ const ipc = await listen$1();
768
+ handleIpc(ipc);
769
+ const rpc = createRpc(ipc);
770
+ return rpc;
771
+ };
772
+ const WebWorkerRpcClient = {
773
+ __proto__: null,
774
+ create
775
+ };
776
+
777
+ const createUrl = (protocol, host) => {
778
+ return protocol + '//' + host;
779
+ };
780
+
781
+ const createLocalHostUrl = (locationProtocol, locationHost, isGitpod, webViewPort) => {
782
+ if (isGitpod) {
783
+ return createUrl(locationProtocol, locationHost.replace('3000', `${webViewPort}`));
784
+ }
785
+ return `http://localhost:${webViewPort}`;
786
+ };
787
+
788
+ const Web = 1;
789
+ const Electron = 2;
790
+ const Remote = 3;
791
+ const Test = 4;
792
+
793
+ /* istanbul ignore file */
794
+
795
+ // TODO this should always be completely tree shaken out during build, maybe need to be marked as @__Pure for terser to work
796
+
797
+ // TODO treeshake this function out when targeting electron
798
+
799
+ /**
800
+ * @returns {number}
801
+ */
802
+ const getPlatform = () => {
803
+ // @ts-ignore
804
+ if (typeof PLATFORM !== 'undefined') {
805
+ // @ts-ignore
806
+ return PLATFORM;
807
+ }
808
+ // @ts-ignore
809
+ if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
810
+ return Test;
811
+ }
812
+ // TODO find a better way to pass runtime environment
813
+ if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
814
+ return Electron;
815
+ }
816
+ if (typeof name !== 'undefined' && name.endsWith('(Web)')) {
817
+ return Web;
818
+ }
819
+ return Remote;
820
+ };
821
+ const platform = getPlatform();
822
+
823
+ const getAssetDir = () => {
824
+ // @ts-ignore
825
+ if (typeof ASSET_DIR !== 'undefined') {
826
+ // @ts-ignore
827
+ return ASSET_DIR;
828
+ }
829
+ if (platform === Electron) {
830
+ return '';
831
+ }
832
+ return '';
833
+ };
834
+ const assetDir = getAssetDir();
835
+
836
+ const getWebViewHtml = (baseUrl, locationOrigin, elements) => {
837
+ if (!elements) {
838
+ return '';
839
+ }
840
+ const middle = [];
841
+ middle.push('<meta charset="utf-8">');
842
+ for (const element of elements) {
843
+ if (element.type === 'title') {
844
+ middle.push(`<title>${element.value}</title>`);
845
+ } else if (element.type === 'script') {
846
+ middle.push(`<script type="module" src="${locationOrigin}${assetDir}/js/preview-injected.js"></script>`);
847
+ middle.push(`<script type="module" src="${locationOrigin}${baseUrl}/${element.path}"></script>`);
848
+ } else if (element.type === 'css') {
849
+ middle.push(`<link rel="stylesheet" href="${locationOrigin}${baseUrl}/${element.path}" />`);
850
+ }
851
+ }
852
+ const middleHtml = middle.join('\n ');
853
+ let html = `<!DOCTYPE html>
854
+ <html>
855
+ <head>
856
+ ${middleHtml}
857
+ </head>
858
+ </html>
859
+ `;
860
+ return html;
861
+ };
862
+
863
+ const WebView = 'lvce-oss-webview';
864
+
865
+ const getWebView$1 = (webViews, webViewId) => {
866
+ for (const webView of webViews) {
867
+ if (webView.id === webViewId) {
868
+ return webView;
869
+ }
870
+ }
871
+ return undefined;
872
+ };
873
+ const getWebViewPath = (webViews, webViewId) => {
874
+ const webView = getWebView$1(webViews, webViewId);
875
+ if (!webView) {
876
+ return '';
877
+ }
878
+ return webView.path;
879
+ };
880
+ const getWebViewUri = (webViews, webViewId) => {
881
+ const webViewPath = getWebViewPath(webViews, webViewId);
882
+ if (!webViewPath) {
883
+ return '';
884
+ }
885
+ if (webViewPath.startsWith('/')) {
886
+ // TODO make it work on windows also
887
+ return `file://${webViewPath}`;
888
+ }
889
+ return webViewPath;
890
+ };
891
+ const getIframeSrcRemote = (webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root) => {
892
+ const webView = getWebView$1(webViews, webViewId);
893
+ const webViewUri = getWebViewUri(webViews, webViewId);
894
+ if (!webViewUri) {
895
+ return undefined;
896
+ }
897
+ let iframeSrc = webViewUri;
898
+ let webViewRoot = webViewUri;
899
+ if (platform === Electron) {
900
+ const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
901
+ iframeSrc = `${WebView}://-${relativePath}/`;
902
+ // TODO
903
+ } else if (platform === Remote) {
904
+ const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
905
+ if (webViewUri.startsWith('file://')) {
906
+ // ignore
907
+ webViewRoot = webViewUri.slice('file://'.length).replace('/index.html', '');
908
+ } else {
909
+ webViewRoot = root + relativePath;
910
+ }
911
+ iframeSrc = createLocalHostUrl(locationProtocol, locationHost, isGitpod, webViewPort);
912
+ }
913
+ let iframeContent = getWebViewHtml('', '', webView.elements);
914
+ // TODO either
915
+ // - load webviews the same as in web using blob urls
916
+ // - load webviews from a pattern like /webviews/:id/:fileName
917
+ iframeContent = iframeContent.replaceAll('/media/', '/').replaceAll('//', '/');
918
+ return {
919
+ srcDoc: '',
920
+ iframeSrc,
921
+ webViewRoot,
922
+ iframeContent
923
+ };
924
+ };
925
+
926
+ const getBlobUrl = (content, contentType) => {
927
+ const blob = new Blob([content], {
928
+ type: contentType
929
+ });
930
+ const url = URL.createObjectURL(blob); // TODO dispose
931
+ return url;
932
+ };
933
+
934
+ const getDefaultBaseUrl = webView => {
935
+ const {
936
+ remotePath,
937
+ path
938
+ } = webView;
939
+ if (remotePath) {
940
+ if (remotePath.endsWith('/index.html')) {
941
+ return remotePath.slice(0, -'/index.html'.length);
942
+ }
943
+ return remotePath;
770
944
  }
771
- return stderr.includes('ERR_MODULE_NOT_FOUND');
945
+ if (path) {
946
+ if (path.endsWith('/index.html')) {
947
+ return path.slice(0, -'/index.html'.length);
948
+ }
949
+ return path;
950
+ }
951
+ return '';
772
952
  };
773
- const isNormalStackLine = line => {
774
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
953
+ const getWebViewBaseUrl = webView => {
954
+ const defaultBaseUrl = getDefaultBaseUrl(webView);
955
+ return defaultBaseUrl;
775
956
  };
776
- const getDetails = lines => {
777
- const index = lines.findIndex(isNormalStackLine);
778
- if (index === -1) {
957
+
958
+ const getIframeSrc$1 = (webView, locationOrigin) => {
959
+ const baseUrl = getWebViewBaseUrl(webView);
960
+ const srcHtml = getWebViewHtml(baseUrl, locationOrigin, webView.elements);
961
+ if (srcHtml) {
962
+ const blobUrl = getBlobUrl(srcHtml, 'text/html');
779
963
  return {
780
- actualMessage: joinLines(lines),
781
- rest: []
964
+ srcDoc: '',
965
+ iframeSrc: blobUrl,
966
+ webViewRoot: '',
967
+ iframeContent: ''
782
968
  };
783
969
  }
784
- let lastIndex = index - 1;
785
- while (++lastIndex < lines.length) {
786
- if (!isNormalStackLine(lines[lastIndex])) {
787
- break;
788
- }
789
- }
790
- return {
791
- actualMessage: lines[index - 1],
792
- rest: lines.slice(index, lastIndex)
793
- };
970
+ return undefined;
794
971
  };
795
- const getHelpfulChildProcessError = (stdout, stderr) => {
796
- if (isUnhelpfulNativeModuleError(stderr)) {
797
- return getNativeModuleErrorMessage(stderr);
798
- }
799
- if (isModulesSyntaxError(stderr)) {
800
- return getModuleSyntaxError();
801
- }
802
- if (isModuleNotFoundError(stderr)) {
803
- return getModuleNotFoundError(stderr);
972
+
973
+ const getWebView = (webViews, webViewId) => {
974
+ for (const webView of webViews) {
975
+ if (webView.id === webViewId) {
976
+ return webView;
977
+ }
804
978
  }
805
- const lines = splitLines(stderr);
806
- const {
807
- actualMessage,
808
- rest
809
- } = getDetails(lines);
810
- return {
811
- message: `${actualMessage}`,
812
- code: '',
813
- stack: rest
814
- };
979
+ return undefined;
815
980
  };
981
+
816
982
  const normalizeLine = line => {
817
983
  if (line.startsWith('Error: ')) {
818
- return line.slice(`Error: `.length);
984
+ return line.slice('Error: '.length);
819
985
  }
820
986
  if (line.startsWith('VError: ')) {
821
- return line.slice(`VError: `.length);
987
+ return line.slice('VError: '.length);
822
988
  }
823
989
  return line;
824
990
  };
@@ -868,140 +1034,97 @@ class VError extends Error {
868
1034
  }
869
1035
  }
870
1036
  }
871
- class IpcError extends VError {
872
- // @ts-ignore
873
- constructor(betterMessage, stdout = '', stderr = '') {
874
- if (stdout || stderr) {
875
- // @ts-ignore
876
- const {
877
- message,
878
- code,
879
- stack
880
- } = getHelpfulChildProcessError(stdout, stderr);
881
- const cause = new Error(message);
882
- // @ts-ignore
883
- cause.code = code;
884
- cause.stack = stack;
885
- super(cause, betterMessage);
886
- } else {
887
- super(betterMessage);
1037
+
1038
+ const getIframeSrc = (webViews, webViewId, webViewPort, root, isGitpod, locationProtocol, locationHost, locationOrigin) => {
1039
+ try {
1040
+ const webView = getWebView(webViews, webViewId);
1041
+ if (platform === Web) {
1042
+ return getIframeSrc$1(webView, locationOrigin);
888
1043
  }
889
- // @ts-ignore
890
- this.name = 'IpcError';
891
- // @ts-ignore
892
- this.stdout = stdout;
893
- // @ts-ignore
894
- this.stderr = stderr;
1044
+ return getIframeSrcRemote(webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root);
1045
+ } catch (error) {
1046
+ throw new VError(error, `Failed to construct webview iframe src`);
895
1047
  }
896
- }
897
- const withResolvers = () => {
898
- let _resolve;
899
- const promise = new Promise(resolve => {
900
- _resolve = resolve;
901
- });
902
- return {
903
- resolve: _resolve,
904
- promise
905
- };
906
1048
  };
907
- const waitForFirstMessage = async port => {
908
- const {
909
- resolve,
910
- promise
911
- } = withResolvers();
912
- port.addEventListener('message', resolve, {
913
- once: true
914
- });
915
- const event = await promise;
916
- // @ts-ignore
917
- return event.data;
1049
+
1050
+ const SemiColon = ';';
1051
+ const Space = ' ';
1052
+
1053
+ const addSemicolon = line => {
1054
+ return line + SemiColon;
918
1055
  };
919
- const listen$3 = async () => {
920
- const parentIpcRaw = listen$4();
921
- signal$3(parentIpcRaw);
922
- const parentIpc = wrap$6(parentIpcRaw);
923
- const firstMessage = await waitForFirstMessage(parentIpc);
924
- if (firstMessage.method !== 'initialize') {
925
- throw new IpcError('unexpected first message');
926
- }
927
- const type = firstMessage.params[0];
928
- if (type === 'message-port') {
929
- parentIpc.send({
930
- jsonrpc: '2.0',
931
- id: firstMessage.id,
932
- result: null
933
- });
934
- parentIpc.dispose();
935
- const port = firstMessage.params[1];
936
- return port;
937
- }
938
- return globalThis;
1056
+
1057
+ const getContentSecurityPolicy = items => {
1058
+ return items.map(addSemicolon).join(Space);
939
1059
  };
940
- class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
941
- constructor(port) {
942
- super(port);
943
- }
944
- getData(event) {
945
- return getData$1(event);
946
- }
947
- send(message) {
948
- this._rawIpc.postMessage(message);
949
- }
950
- sendAndTransfer(message) {
951
- const transfer = getTransferrables(message);
952
- this._rawIpc.postMessage(message, transfer);
953
- }
954
- dispose() {
955
- if (this._rawIpc.close) {
956
- this._rawIpc.close();
957
- }
958
- }
959
- onClose(callback) {
960
- // ignore
961
- }
962
- onMessage(callback) {
963
- this._rawIpc.addEventListener('message', callback);
964
- this._rawIpc.start();
1060
+
1061
+ const getWebViewCsp = webView => {
1062
+ if (webView && webView.contentSecurityPolicy) {
1063
+ return getContentSecurityPolicy(webView.contentSecurityPolicy);
965
1064
  }
966
- }
967
- const wrap$5 = port => {
968
- return new IpcChildWithModuleWorkerAndMessagePort(port);
1065
+ const csp = getContentSecurityPolicy([`default-src 'none'`, `script-src 'self'`, `style-src 'self'`, `img-src 'self'`, `media-src 'self'`]);
1066
+ return csp;
969
1067
  };
970
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
971
- __proto__: null,
972
- listen: listen$3,
973
- wrap: wrap$5
1068
+
1069
+ const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
1070
+ const frameAncestors = createUrl(locationProtocol, locationHost);
1071
+ return frameAncestors;
974
1072
  };
975
1073
 
976
- const getModule = method => {
977
- switch (method) {
978
- case ModuleWorker:
979
- return IpcChildWithModuleWorker$1;
980
- case ModuleWorkerAndMessagePort:
981
- return IpcChildWithModuleWorkerAndMessagePort$1;
982
- default:
983
- throw new Error('unexpected ipc type');
1074
+ const getWebViewOrigin = webViewPort => {
1075
+ // TODO don't hardcode protocol
1076
+ let origin = '';
1077
+ if (platform === Electron) {
1078
+ origin = `${WebView}://-/`;
1079
+ } else if (platform === Remote) {
1080
+ origin = `http://localhost:${webViewPort}`;
1081
+ } else {
1082
+ origin = '*'; // TODO
984
1083
  }
1084
+ return origin;
985
1085
  };
986
1086
 
987
- const listen$1 = async ({
988
- method
989
- }) => {
990
- const module = await getModule(method);
991
- const rawIpc = await module.listen();
992
- if (module.signal) {
993
- module.signal(rawIpc);
1087
+ const AllowScripts = 'allow-scripts';
1088
+ const AllowSameOrigin = 'allow-same-origin';
1089
+
1090
+ const getIframeSandbox = (webView, platform) => {
1091
+ const extensionSandbox = webView.sandbox || [];
1092
+ if (platform === Remote) {
1093
+ return [AllowScripts, AllowSameOrigin, ...extensionSandbox]; // TODO maybe disallow same origin
994
1094
  }
995
- const ipc = module.wrap(rawIpc);
996
- return ipc;
1095
+ if (platform === Web) {
1096
+ return [AllowScripts, ...extensionSandbox];
1097
+ }
1098
+ return [AllowScripts, AllowSameOrigin, ...extensionSandbox];
1099
+ };
1100
+
1101
+ const getOrigin = () => {
1102
+ return location.origin;
1103
+ };
1104
+ const getHost = () => {
1105
+ return location.host;
1106
+ };
1107
+ const getProtocol = () => {
1108
+ return location.protocol;
1109
+ };
1110
+
1111
+ const commandMap = {
1112
+ 'Location.getHost': getHost,
1113
+ 'Location.getOrigin': getOrigin,
1114
+ 'Location.getProtocol': getProtocol,
1115
+ 'WebView.getBaseUrl': getWebViewBaseUrl,
1116
+ 'WebView.getFrameAncestors': getWebViewFrameAncestors,
1117
+ 'WebView.getHtml': getWebViewHtml,
1118
+ 'WebView.getIframeSrc': getIframeSrc,
1119
+ 'WebView.getOrigin': getWebViewOrigin,
1120
+ 'WebView.getSandbox': getIframeSandbox,
1121
+ 'WebView.getWebViewCsp': getWebViewCsp
997
1122
  };
998
1123
 
999
1124
  const listen = async () => {
1000
- register(commandMap);
1001
- const ipc = await listen$1({
1002
- method: Auto()
1125
+ await WebWorkerRpcClient.create({
1126
+ commandMap: commandMap
1003
1127
  });
1004
- handleIpc(ipc);
1005
1128
  };
1006
1129
 
1007
1130
  const main = async () => {