@trailstash/ultra 5.0.1 → 5.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ultra-map.js +9 -1
- package/lib/queryParams.js +13 -0
- package/lib/sandbox.js +81 -22
- package/package.json +1 -1
package/components/ultra-map.js
CHANGED
|
@@ -357,7 +357,15 @@ export class UltraMap extends HTMLElement {
|
|
|
357
357
|
});
|
|
358
358
|
if (this.transform) {
|
|
359
359
|
if (sandbox) {
|
|
360
|
-
source.data = await
|
|
360
|
+
source.data = await Promise.race([
|
|
361
|
+
sandbox(this.transform, source.data),
|
|
362
|
+
new Promise((resolve, reject) => {
|
|
363
|
+
controller.signal.onabort = () => {
|
|
364
|
+
this.#cachedTransform = null;
|
|
365
|
+
reject(new DOMException("", "AbortError"));
|
|
366
|
+
};
|
|
367
|
+
}),
|
|
368
|
+
]);
|
|
361
369
|
} else {
|
|
362
370
|
throw new Error("sandbox could not be initialized");
|
|
363
371
|
}
|
package/lib/queryParams.js
CHANGED
|
@@ -62,6 +62,9 @@ export const getQueryFromQueryParams = () => {
|
|
|
62
62
|
// query
|
|
63
63
|
if (params.has("q")) {
|
|
64
64
|
query = decompressFromEncodedURIComponent(params.get("q"));
|
|
65
|
+
if (!query) {
|
|
66
|
+
alert("Invalid compressed query specified in URL");
|
|
67
|
+
}
|
|
65
68
|
} else if (params.has("query")) {
|
|
66
69
|
query = params.get("query");
|
|
67
70
|
if (query.startsWith("gist:")) {
|
|
@@ -111,6 +114,16 @@ export const getOptionsFromQueryParams = () => {
|
|
|
111
114
|
};
|
|
112
115
|
|
|
113
116
|
export const getAutoRunFromQueryParams = () => {
|
|
117
|
+
// Don't autorun if provided query can't be decompressed
|
|
118
|
+
// TODO: other query load errors?
|
|
119
|
+
const params = new URLSearchParams(window.location.hash.slice(1));
|
|
120
|
+
if (params.has("q")) {
|
|
121
|
+
const query = decompressFromEncodedURIComponent(params.get("q"));
|
|
122
|
+
if (!query) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
114
127
|
return new URLSearchParams(window.location.hash.slice(1)).has("run");
|
|
115
128
|
};
|
|
116
129
|
|
package/lib/sandbox.js
CHANGED
|
@@ -1,46 +1,104 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
iframe.style.display = "none";
|
|
5
|
-
iframe.src =
|
|
6
|
-
"data:text/html;base64," +
|
|
7
|
-
btoa(`<!DOCTYPE html>
|
|
8
|
-
<script type="module">
|
|
9
|
-
const p = "${window.location.origin}"
|
|
10
|
-
|
|
11
|
-
window.addEventListener(
|
|
1
|
+
const sandboxInit = async (sandboxId, p) => {
|
|
2
|
+
const workerInit = (workerId) => {
|
|
3
|
+
self.addEventListener(
|
|
12
4
|
"message",
|
|
13
5
|
async (event) => {
|
|
14
|
-
console.debug(event);
|
|
15
|
-
|
|
16
|
-
if (event.origin !== p) return;
|
|
6
|
+
console.debug("worker recived msg from sandbox", event);
|
|
17
7
|
|
|
18
8
|
let id;
|
|
19
9
|
try {
|
|
20
10
|
const msg = JSON.parse(event.data);
|
|
21
11
|
id = msg.id;
|
|
22
|
-
console.debug(msg)
|
|
12
|
+
console.debug("parsed message", msg);
|
|
23
13
|
|
|
24
14
|
const { default: transform } = await import(msg.transform);
|
|
25
15
|
|
|
26
16
|
const o = await Promise.resolve(transform(msg.data));
|
|
27
|
-
|
|
17
|
+
self.postMessage(JSON.stringify({ id: msg.id, data: o }));
|
|
28
18
|
} catch (e) {
|
|
29
|
-
|
|
19
|
+
self.postMessage(JSON.stringify({ id: id, error: e.toString() }));
|
|
30
20
|
}
|
|
31
21
|
},
|
|
32
22
|
false,
|
|
33
23
|
);
|
|
34
24
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
self.postMessage(JSON.stringify({ id: workerId }));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const workerBlob = new Blob([`(${workerInit.toString()})("${sandboxId}");`], {
|
|
29
|
+
type: "module",
|
|
30
|
+
});
|
|
31
|
+
const worker = new Worker(URL.createObjectURL(workerBlob));
|
|
32
|
+
|
|
33
|
+
const waitForWorkerReady = () =>
|
|
34
|
+
new Promise((resolve, reject) => {
|
|
35
|
+
const listener = (event) => {
|
|
36
|
+
worker.removeEventListener("message", listener, false);
|
|
37
|
+
console.debug("sandbox recived msg from worker", event);
|
|
38
|
+
try {
|
|
39
|
+
const msg = JSON.parse(event.data);
|
|
40
|
+
if (msg.id === sandboxId) {
|
|
41
|
+
resolve();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.warn("unexpected msg!");
|
|
45
|
+
} catch (e) {
|
|
46
|
+
reject(e);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
worker.addEventListener("message", listener, false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// wait for ready msg from worker
|
|
54
|
+
await waitForWorkerReady();
|
|
55
|
+
console.log("worker ready");
|
|
56
|
+
|
|
57
|
+
// Relay messages from parent to worker
|
|
58
|
+
window.addEventListener(
|
|
59
|
+
"message",
|
|
60
|
+
(event) => {
|
|
61
|
+
console.debug("sandbox recieved msg from parent", event);
|
|
62
|
+
worker.postMessage(event.data);
|
|
63
|
+
},
|
|
64
|
+
false,
|
|
65
|
+
);
|
|
66
|
+
// Relay messages from worker to parent
|
|
67
|
+
worker.addEventListener(
|
|
68
|
+
"message",
|
|
69
|
+
(event) => {
|
|
70
|
+
console.debug("sandbox recieved msg from worker", event);
|
|
71
|
+
window.parent.postMessage(event.data, p);
|
|
72
|
+
},
|
|
73
|
+
false,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
window.parent.postMessage(JSON.stringify({ id: sandboxId }), p);
|
|
77
|
+
};
|
|
78
|
+
const makeSandbox = () => {
|
|
79
|
+
const iframe = window.document.createElement("iframe");
|
|
80
|
+
const sandboxId = crypto.randomUUID();
|
|
81
|
+
iframe.style.display = "none";
|
|
82
|
+
const sandboxBlob = new Blob(
|
|
83
|
+
[
|
|
84
|
+
`
|
|
85
|
+
<!DOCTYPE html>
|
|
86
|
+
<script type="module">
|
|
87
|
+
(${sandboxInit.toString()})("${sandboxId}", "${window.location.origin}");
|
|
88
|
+
</script>
|
|
89
|
+
`,
|
|
90
|
+
],
|
|
91
|
+
{
|
|
92
|
+
type: "text/html",
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
iframe.src = URL.createObjectURL(sandboxBlob);
|
|
38
96
|
|
|
39
97
|
const run = (transform, data) => {
|
|
40
98
|
const messageID = crypto.randomUUID();
|
|
41
99
|
return new Promise((resolve, reject) => {
|
|
42
100
|
const listener = (event) => {
|
|
43
|
-
console.debug(event);
|
|
101
|
+
console.debug("parent recieved msg from sandbox", event);
|
|
44
102
|
try {
|
|
45
103
|
const msg = JSON.parse(event.data);
|
|
46
104
|
if (msg.id === messageID) {
|
|
@@ -73,10 +131,11 @@ const makeSandbox = () => {
|
|
|
73
131
|
return new Promise((resolve) => {
|
|
74
132
|
const listener = (event) => {
|
|
75
133
|
window.removeEventListener("message", listener, false);
|
|
76
|
-
console.debug(event);
|
|
134
|
+
console.debug("parent recieved msg from sandbox", event);
|
|
77
135
|
try {
|
|
78
136
|
const msg = JSON.parse(event.data);
|
|
79
137
|
if (msg.id === sandboxId) {
|
|
138
|
+
console.log("sandbox ready");
|
|
80
139
|
resolve(run);
|
|
81
140
|
return;
|
|
82
141
|
}
|
package/package.json
CHANGED