apps 0.0.1-beta.17 → 0.0.1-beta.19
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/framework-reference.json +1 -1
- package/js/ui/serving.js +62 -210
- package/package.json +1 -1
- package/runtime.json +1 -1
- package/types/apps/src/contracts/ui.d.ts +18 -0
- package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
- package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
- package/types/apps/src/implementation/ui-errors.d.ts +1 -1
- package/types/apps/src/implementation/ui-serving.d.ts +6 -2
- package/types/apps/src/implementation/ui-watch.d.ts +1 -1
package/js/ui/serving.js
CHANGED
|
@@ -19,186 +19,58 @@ import {
|
|
|
19
19
|
} from "../chunk-CDL5PM2Q.js";
|
|
20
20
|
import "../chunk-CZ7CSFO4.js";
|
|
21
21
|
|
|
22
|
-
// src/implementation/
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const recent = /* @__PURE__ */ new Map();
|
|
27
|
-
const extension = /^(?:chrome|moz|safari-web)-extension:/;
|
|
28
|
-
const errorTypes = /* @__PURE__ */ new Set([
|
|
29
|
-
"Error",
|
|
30
|
-
"TypeError",
|
|
31
|
-
"ReferenceError",
|
|
32
|
-
"SyntaxError",
|
|
33
|
-
"RangeError",
|
|
34
|
-
"URIError",
|
|
35
|
-
"EvalError",
|
|
36
|
-
"AggregateError"
|
|
37
|
-
]);
|
|
38
|
-
const sourceAttributes = (filename, line = 0, column = 0) => {
|
|
39
|
-
const attributes = [];
|
|
40
|
-
if (!URL.canParse(filename)) return attributes;
|
|
41
|
-
const url = new URL(filename);
|
|
42
|
-
if (url.origin !== location.origin || !url.pathname.startsWith("/_executor/assets/") || !url.pathname.endsWith(".js"))
|
|
43
|
-
return attributes;
|
|
44
|
-
attributes.push({ key: "code.file.path", value: { stringValue: url.pathname } });
|
|
45
|
-
if (Number.isSafeInteger(line) && line > 0)
|
|
46
|
-
attributes.push({ key: "code.line.number", value: { intValue: String(line) } });
|
|
47
|
-
if (Number.isSafeInteger(column) && column > 0)
|
|
48
|
-
attributes.push({ key: "code.column.number", value: { intValue: String(column) } });
|
|
49
|
-
return attributes;
|
|
50
|
-
};
|
|
51
|
-
const fail = (kind, details, attributes = []) => {
|
|
52
|
-
const now = Date.now();
|
|
53
|
-
if (now - windowStart >= 6e4) {
|
|
54
|
-
windowStart = now;
|
|
55
|
-
reports = 0;
|
|
56
|
-
recent.clear();
|
|
57
|
-
}
|
|
58
|
-
const signature = `${kind}:${details.slice(0, 2e3)}`;
|
|
59
|
-
const previous = recent.get(signature);
|
|
60
|
-
if (previous !== void 0 && now - previous < 1e3 || reports >= 20) {
|
|
61
|
-
dropped++;
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
recent.set(signature, now);
|
|
65
|
-
reports++;
|
|
66
|
-
attributes.push({
|
|
67
|
-
key: "executor.ui.failure.suppressed",
|
|
68
|
-
value: { intValue: String(dropped) }
|
|
69
|
-
});
|
|
70
|
-
dropped = 0;
|
|
71
|
-
const traceId = Array.from(
|
|
72
|
-
crypto.getRandomValues(new Uint8Array(16)),
|
|
73
|
-
(byte) => byte.toString(16).padStart(2, "0")
|
|
74
|
-
).join("");
|
|
75
|
-
const time = `${Date.now()}000000`;
|
|
76
|
-
let status;
|
|
77
|
-
let deliveryMessage = "Sending error report\u2026";
|
|
78
|
-
const show = () => {
|
|
79
|
-
if (activeDialog?.open) return;
|
|
80
|
-
const host = document.createElement("div");
|
|
81
|
-
const root = host.attachShadow({ mode: "open" });
|
|
82
|
-
const dialog = document.createElement("dialog");
|
|
83
|
-
activeDialog = dialog;
|
|
84
|
-
dialog.setAttribute("aria-labelledby", "executor-failure-title");
|
|
85
|
-
const title = document.createElement("h2");
|
|
86
|
-
title.id = "executor-failure-title";
|
|
87
|
-
title.textContent = kind === "script" ? "This app could not load" : "This app stopped working";
|
|
88
|
-
const message = document.createElement("p");
|
|
89
|
-
message.textContent = kind === "script" ? "A file needed by this page did not load. Reload the page to try again." : "The app encountered an unexpected error. Reload the page to try again.";
|
|
90
|
-
const warning = document.createElement("p");
|
|
91
|
-
warning.textContent = "Copy any unsaved work before reloading.";
|
|
92
|
-
const disclosure = document.createElement("details");
|
|
93
|
-
const summary = document.createElement("summary");
|
|
94
|
-
summary.textContent = "Error details";
|
|
95
|
-
const report = document.createElement("textarea");
|
|
96
|
-
report.readOnly = true;
|
|
97
|
-
report.rows = 10;
|
|
98
|
-
report.cols = 36;
|
|
99
|
-
report.setAttribute("aria-label", "Error details");
|
|
100
|
-
report.value = `${details.slice(0, 12e3)}
|
|
22
|
+
// src/implementation/browser-scripts.gen.ts
|
|
23
|
+
var appWatchSource = '"use strict";(()=>{var s=()=>{let i=document.getElementById("executor-context")?.textContent;if(!i)return;let n=JSON.parse(i);if(typeof n!="object"||n===null||!("deployment"in n))return;let r=n.deployment;if(typeof r!="string"||r.length===0)return;let t=new EventSource("/_executor/version"),l=!1,o=()=>{l||(l=!0,t.close(),location.reload())};t.addEventListener("version",d=>{let e=JSON.parse(d.data);typeof e=="object"&&e!==null&&"deployment"in e&&(e.deployment===null||typeof e.deployment=="string")&&e.deployment!==r&&o()}),t.addEventListener("revoked",o),window.addEventListener("executor:deployment-changed",o),window.addEventListener("pagehide",()=>t.close(),{once:!0}),window.addEventListener("pageshow",d=>{d.persisted&&o()})};s();})();';
|
|
24
|
+
var appFailureSource = '"use strict";(()=>{var D=()=>{let d,w=Date.now(),m=0,g=0,f=new Map,A=/^(?:chrome|moz|safari-web)-extension:/,R=new Set(["Error","TypeError","ReferenceError","SyntaxError","RangeError","URIError","EvalError","AggregateError"]),x=(e,t=0,i=0)=>{let r=[];if(!URL.canParse(e))return r;let a=new URL(e);return a.origin!==location.origin||!a.pathname.startsWith("/_executor/assets/")||!a.pathname.endsWith(".js")||(r.push({key:"code.file.path",value:{stringValue:a.pathname}}),Number.isSafeInteger(t)&&t>0&&r.push({key:"code.line.number",value:{intValue:String(t)}}),Number.isSafeInteger(i)&&i>0&&r.push({key:"code.column.number",value:{intValue:String(i)}})),r},E=(e,t,i=[])=>{let r=Date.now();r-w>=6e4&&(w=r,m=0,f.clear());let a=`${e}:${t.slice(0,2e3)}`,b=f.get(a);if(b!==void 0&&r-b<1e3||m>=20){g++;return}f.set(a,r),m++,i.push({key:"executor.ui.failure.suppressed",value:{intValue:String(g)}}),g=0;let h=Array.from(crypto.getRandomValues(new Uint8Array(16)),s=>s.toString(16).padStart(2,"0")).join(""),S=`${Date.now()}000000`,n,u="Sending error report\\u2026",k=()=>{if(d?.open)return;let s=document.createElement("div"),V=s.attachShadow({mode:"open"}),o=document.createElement("dialog");d=o,o.setAttribute("aria-labelledby","executor-failure-title");let y=document.createElement("h2");y.id="executor-failure-title",y.textContent=e==="script"?"This app could not load":"This app stopped working";let C=document.createElement("p");C.textContent=e==="script"?"A file needed by this page did not load. Reload the page to try again.":"The app encountered an unexpected error. Reload the page to try again.";let L=document.createElement("p");L.textContent="Copy any unsaved work before reloading.";let T=document.createElement("details"),v=document.createElement("summary");v.textContent="Error details";let c=document.createElement("textarea");c.readOnly=!0,c.rows=10,c.cols=36,c.setAttribute("aria-label","Error details"),c.value=`${t.slice(0,12e3)}\n\nDiagnostic ID: ${h}`,T.append(v,c),n=document.createElement("p"),n.setAttribute("role","status"),n.textContent=u;let l=document.createElement("button");l.type="button",l.textContent="Reload page",l.addEventListener("click",()=>location.reload());let p=document.createElement("button");p.type="button",p.textContent="Close",p.addEventListener("click",()=>o.close()),o.addEventListener("close",()=>{d===o&&(d=void 0),s.remove()}),o.append(y,C,L,T,n,l,p),V.append(o),document.documentElement.append(s),o.showModal()};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",k,{once:!0}):k(),fetch("/_executor/api/telemetry/traces",{method:"POST",headers:{"content-type":"application/json"},credentials:"same-origin",keepalive:!0,body:JSON.stringify({resourceSpans:[{scopeSpans:[{spans:[{traceId:h,spanId:h.slice(0,16),name:"ui.app.failure",kind:1,startTimeUnixNano:S,endTimeUnixNano:S,status:{code:2},attributes:[{key:"executor.ui.failure.kind",value:{stringValue:e}},...i]}]}]}]})}).then(s=>{u=s.ok?"Error report sent.":"Could not send the error report. You can copy the error details.",n&&(n.textContent=u)},()=>{u="Could not send the error report. You can copy the error details.",n&&(n.textContent=u)})};window.addEventListener("error",e=>{if(e instanceof ErrorEvent){if(A.test(e.filename))return;let t=x(e.filename,e.lineno,e.colno);e.error instanceof Error&&R.has(e.error.name)&&t.push({key:"exception.type",value:{stringValue:e.error.name}}),E("runtime",e.error instanceof Error?e.error.stack??e.message:e.message,t)}else e.target instanceof HTMLScriptElement&&E("script",`Could not load script: ${e.target.src}`,x(e.target.src))},!0),window.addEventListener("unhandledrejection",e=>{let t=e.reason;E("rejection",t instanceof Error?t.stack??t.message:"An app operation failed without handling its error.")})};D();})();';
|
|
25
|
+
var accountNoticeSource = '"use strict";(()=>{var g=()=>{let r=document.getElementById("executor-account-notice")?.textContent;if(!r)return;let t=JSON.parse(r);if(typeof t!="object"||t===null||!("items"in t)||!("fix"in t))return;let c=t.items,s=t.fix;if(!Array.isArray(c)||typeof s!="string")return;let a=()=>{let i=document.createElement("div"),x=i.attachShadow({mode:"open"}),d=document.createElement("style");d.textContent="aside{position:fixed;right:16px;bottom:16px;z-index:2147483647;max-width:360px;box-sizing:border-box;padding:14px 16px;border-radius:10px;border:1px solid #fcd34d;background:#fffbeb;color:#451a03;font:14px/1.45 ui-sans-serif,system-ui,sans-serif;box-shadow:0 8px 24px rgb(0 0 0/.12)}strong{display:block;margin-bottom:4px}ul{margin:0 0 10px;padding-left:18px}div{display:flex;gap:12px;align-items:center}a{color:inherit;font-weight:600}button{margin-left:auto;font:inherit;background:none;border:0;padding:0;color:inherit;text-decoration:underline;cursor:pointer}";let e=document.createElement("aside");e.setAttribute("role","status"),e.setAttribute("aria-label","Account warning");let l=document.createElement("strong");l.textContent="Some things might not work";let m=document.createElement("ul");for(let f of c){let p=document.createElement("li");p.textContent=String(f),m.append(p)}let u=document.createElement("div"),n=document.createElement("a");n.href=s,n.target="_top",n.textContent="Review accounts";let o=document.createElement("button");o.type="button",o.textContent="Dismiss",o.addEventListener("click",()=>i.remove()),u.append(n,o),e.append(l,m,u),x.append(d,e),document.documentElement.append(i)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",a,{once:!0}):a()};g();})();';
|
|
101
26
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
traceId,
|
|
142
|
-
spanId: traceId.slice(0, 16),
|
|
143
|
-
name: "ui.app.failure",
|
|
144
|
-
kind: 1,
|
|
145
|
-
startTimeUnixNano: time,
|
|
146
|
-
endTimeUnixNano: time,
|
|
147
|
-
status: { code: 2 },
|
|
148
|
-
attributes: [
|
|
149
|
-
{ key: "executor.ui.failure.kind", value: { stringValue: kind } },
|
|
150
|
-
...attributes
|
|
151
|
-
]
|
|
152
|
-
}
|
|
153
|
-
]
|
|
154
|
-
}
|
|
155
|
-
]
|
|
156
|
-
}
|
|
157
|
-
]
|
|
158
|
-
})
|
|
159
|
-
}).then(
|
|
160
|
-
(response) => {
|
|
161
|
-
deliveryMessage = response.ok ? "Error report sent." : "Could not send the error report. You can copy the error details.";
|
|
162
|
-
if (status) status.textContent = deliveryMessage;
|
|
163
|
-
},
|
|
164
|
-
() => {
|
|
165
|
-
deliveryMessage = "Could not send the error report. You can copy the error details.";
|
|
166
|
-
if (status) status.textContent = deliveryMessage;
|
|
167
|
-
}
|
|
168
|
-
);
|
|
169
|
-
};
|
|
170
|
-
window.addEventListener(
|
|
171
|
-
"error",
|
|
172
|
-
(event) => {
|
|
173
|
-
if (event instanceof ErrorEvent) {
|
|
174
|
-
if (extension.test(event.filename)) return;
|
|
175
|
-
const attributes = sourceAttributes(event.filename, event.lineno, event.colno);
|
|
176
|
-
if (event.error instanceof Error && errorTypes.has(event.error.name))
|
|
177
|
-
attributes.push({ key: "exception.type", value: { stringValue: event.error.name } });
|
|
178
|
-
fail(
|
|
179
|
-
"runtime",
|
|
180
|
-
event.error instanceof Error ? event.error.stack ?? event.message : event.message,
|
|
181
|
-
attributes
|
|
182
|
-
);
|
|
183
|
-
} else if (event.target instanceof HTMLScriptElement) {
|
|
184
|
-
fail(
|
|
185
|
-
"script",
|
|
186
|
-
`Could not load script: ${event.target.src}`,
|
|
187
|
-
sourceAttributes(event.target.src)
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
true
|
|
192
|
-
);
|
|
193
|
-
window.addEventListener("unhandledrejection", (event) => {
|
|
194
|
-
const reason = event.reason;
|
|
195
|
-
fail(
|
|
196
|
-
"rejection",
|
|
197
|
-
reason instanceof Error ? reason.stack ?? reason.message : "An app operation failed without handling its error."
|
|
198
|
-
);
|
|
199
|
-
});
|
|
27
|
+
// src/implementation/ui-account-notice.ts
|
|
28
|
+
var escape = (text) => text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
29
|
+
var accountProblemBlocks = (problem) => problem.reason === "missing" || problem.reason === "removed" || problem.reason === "incompatible" || problem.reason === "credentials_rejected";
|
|
30
|
+
var accountProblemText = (problem) => {
|
|
31
|
+
switch (problem.reason) {
|
|
32
|
+
case "missing":
|
|
33
|
+
return `No ${problem.provider} account chosen`;
|
|
34
|
+
case "removed":
|
|
35
|
+
return `${problem.provider} account was removed or is no longer shared`;
|
|
36
|
+
case "incompatible":
|
|
37
|
+
return `Chosen account can't be used as the ${problem.provider} account`;
|
|
38
|
+
case "credentials_rejected":
|
|
39
|
+
return `${problem.account} (${problem.provider}): sign-in rejected at last check`;
|
|
40
|
+
case "forbidden":
|
|
41
|
+
return `${problem.account} (${problem.provider}): missing permission at last check`;
|
|
42
|
+
case "upstream_unavailable":
|
|
43
|
+
return `${problem.account} (${problem.provider}): service unavailable at last check`;
|
|
44
|
+
case "check_failed":
|
|
45
|
+
return `${problem.account} (${problem.provider}): last check failed`;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var accountBlockedPage = (notice) => {
|
|
49
|
+
const title = `${escape(notice.app)} can't open`;
|
|
50
|
+
const items = notice.problems.map(
|
|
51
|
+
(problem) => `<li class="${accountProblemBlocks(problem) ? "bad" : "warn"}">${escape(accountProblemText(problem))}</li>`
|
|
52
|
+
).join("");
|
|
53
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${title}</title><style>
|
|
54
|
+
:root{color-scheme:light dark;font-family:ui-sans-serif,system-ui,sans-serif;color:#18181b;background:#fafafa}
|
|
55
|
+
@media (prefers-color-scheme:dark){:root{color:#f4f4f5;background:#18181b}main{background:#27272a!important;border-color:#3f3f46!important}a{color:inherit!important;border-color:#52525b!important}a.primary{background:#f4f4f5!important;color:#18181b!important}p{color:#a1a1aa!important}}
|
|
56
|
+
body{margin:0;min-height:100vh;display:grid;place-items:center;padding:24px;box-sizing:border-box}
|
|
57
|
+
main{max-width:480px;width:100%;background:#fff;border:1px solid #e4e4e7;border-radius:12px;padding:28px}
|
|
58
|
+
h1{margin:0 0 8px;font-size:20px}p{margin:0 0 16px;color:#52525b;line-height:1.5}
|
|
59
|
+
ul{margin:0 0 24px;padding:0;list-style:none;display:grid;gap:8px}
|
|
60
|
+
li{display:flex;gap:10px;align-items:baseline;line-height:1.4}li::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;transform:translateY(-1px)}
|
|
61
|
+
li.bad::before{background:#dc2626}li.warn::before{background:#f59e0b}
|
|
62
|
+
.actions{display:flex;flex-wrap:wrap;gap:8px}
|
|
63
|
+
a{padding:8px 14px;border-radius:8px;border:1px solid #d4d4d8;color:#18181b;text-decoration:none;font-weight:500}
|
|
64
|
+
a.primary{background:#18181b;border-color:#18181b;color:#fff}
|
|
65
|
+
</style></head><body><main><h1>${title}</h1><p>This profile's accounts need attention before the app can work.</p><ul>${items}</ul><div class="actions"><a class="primary" href="${escape(notice.fix)}">Fix accounts</a><a href="${escape(notice.choose)}">Open with another profile</a></div></main></body></html>`;
|
|
200
66
|
};
|
|
201
|
-
var
|
|
67
|
+
var accountNoticeBootstrap = (notice) => `<script type="application/json" id="executor-account-notice">${JSON.stringify({
|
|
68
|
+
items: notice.problems.map(accountProblemText),
|
|
69
|
+
fix: notice.fix
|
|
70
|
+
}).replaceAll("<", "\\u003c")}</script><script>${accountNoticeSource}</script>`;
|
|
71
|
+
|
|
72
|
+
// src/implementation/ui-errors.ts
|
|
73
|
+
var appFailureBootstrap = `<script>${appFailureSource}</script>`;
|
|
202
74
|
|
|
203
75
|
// src/implementation/ui-serving.ts
|
|
204
76
|
var appDocument = (options) => Effect_exports.gen(function* () {
|
|
@@ -214,8 +86,15 @@ var appDocument = (options) => Effect_exports.gen(function* () {
|
|
|
214
86
|
});
|
|
215
87
|
if (pathname.includes(".") && pathname !== "/index.html")
|
|
216
88
|
return HttpServerResponse_exports.empty({ status: 404 });
|
|
217
|
-
const
|
|
218
|
-
if (
|
|
89
|
+
const notice = options.accounts;
|
|
90
|
+
if (notice?.problems.some(accountProblemBlocks))
|
|
91
|
+
return HttpServerResponse_exports.text(accountBlockedPage(notice), {
|
|
92
|
+
status: 409,
|
|
93
|
+
contentType: "text/html",
|
|
94
|
+
headers: appPrivateHeaders
|
|
95
|
+
});
|
|
96
|
+
const document = yield* options.asset("index.html");
|
|
97
|
+
if (document === void 0)
|
|
219
98
|
return HttpServerResponse_exports.text("This app has no UI.", {
|
|
220
99
|
status: 404,
|
|
221
100
|
headers: appPrivateHeaders
|
|
@@ -228,9 +107,9 @@ var appDocument = (options) => Effect_exports.gen(function* () {
|
|
|
228
107
|
const telemetry = yield* CurrentTelemetryConfig;
|
|
229
108
|
const attribute = (text) => text.replaceAll("&", "&").replaceAll('"', """).replaceAll("<", "<");
|
|
230
109
|
const metadata = telemetry === void 0 ? "" : `<meta name="executor-build" content="${attribute(telemetry.version)}"><meta name="executor-environment" content="${attribute(telemetry.environment)}">`;
|
|
231
|
-
const boot = `${metadata}<base href="/_executor/assets/${attribute(options.deployment)}/"><script type="application/json" id="executor-context">${context}</script>${appFailureBootstrap}<script src="/_executor/watch.js" defer></script>`;
|
|
110
|
+
const boot = `${metadata}<base href="/_executor/assets/${attribute(options.deployment)}/"><script type="application/json" id="executor-context">${context}</script>${appFailureBootstrap}${notice === void 0 || notice.problems.length === 0 ? "" : accountNoticeBootstrap(notice)}<script src="/_executor/watch.js" defer></script>`;
|
|
232
111
|
return HttpServerResponse_exports.text(
|
|
233
|
-
new TextDecoder().decode(
|
|
112
|
+
new TextDecoder().decode(document.body).replace("<!--executor-ui-->", boot),
|
|
234
113
|
{ contentType: "text/html", headers: appPrivateHeaders }
|
|
235
114
|
);
|
|
236
115
|
});
|
|
@@ -252,34 +131,7 @@ var appAsset = (asset, build, path) => Effect_exports.gen(function* () {
|
|
|
252
131
|
});
|
|
253
132
|
|
|
254
133
|
// src/implementation/ui-watch.ts
|
|
255
|
-
var
|
|
256
|
-
const context = document.getElementById("executor-context")?.textContent;
|
|
257
|
-
if (!context) return;
|
|
258
|
-
const pinned = JSON.parse(context);
|
|
259
|
-
if (typeof pinned !== "object" || pinned === null || !("deployment" in pinned)) return;
|
|
260
|
-
const deployment = pinned.deployment;
|
|
261
|
-
if (typeof deployment !== "string" || deployment.length === 0) return;
|
|
262
|
-
const stream = new EventSource("/_executor/version");
|
|
263
|
-
let reloading = false;
|
|
264
|
-
const reload = () => {
|
|
265
|
-
if (reloading) return;
|
|
266
|
-
reloading = true;
|
|
267
|
-
stream.close();
|
|
268
|
-
location.reload();
|
|
269
|
-
};
|
|
270
|
-
stream.addEventListener("version", (event) => {
|
|
271
|
-
const current = JSON.parse(event.data);
|
|
272
|
-
if (typeof current === "object" && current !== null && "deployment" in current && (current.deployment === null || typeof current.deployment === "string") && current.deployment !== deployment)
|
|
273
|
-
reload();
|
|
274
|
-
});
|
|
275
|
-
stream.addEventListener("revoked", reload);
|
|
276
|
-
window.addEventListener("executor:deployment-changed", reload);
|
|
277
|
-
window.addEventListener("pagehide", () => stream.close(), { once: true });
|
|
278
|
-
window.addEventListener("pageshow", (event) => {
|
|
279
|
-
if (event.persisted) reload();
|
|
280
|
-
});
|
|
281
|
-
};
|
|
282
|
-
var appWatchScript = `(${installAppWatch.toString()})()`;
|
|
134
|
+
var appWatchScript = appWatchSource;
|
|
283
135
|
export {
|
|
284
136
|
appAsset,
|
|
285
137
|
appDocument,
|