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.
@@ -7,6 +7,24 @@ export declare const UiContext: Schema.Struct<{
7
7
  readonly profile: Schema.optional<Schema.NonEmptyString>;
8
8
  readonly expectedProfileRevision: Schema.optional<Schema.Int>;
9
9
  }>;
10
+ /** A problem with one of the page profile's accounts, from stored state. Labels are the owner's own names. */
11
+ export type UiAccountProblem = {
12
+ readonly provider: string;
13
+ readonly reason: "missing" | "removed" | "incompatible";
14
+ } | {
15
+ readonly provider: string;
16
+ readonly account: string;
17
+ readonly reason: "credentials_rejected" | "forbidden" | "upstream_unavailable" | "check_failed";
18
+ };
19
+ /** Account problems found when the page opened, with dashboard links that resolve them. */
20
+ export interface UiAccountNotice {
21
+ readonly app: string;
22
+ readonly problems: readonly UiAccountProblem[];
23
+ /** The profile's accounts in the dashboard. */
24
+ readonly fix: string;
25
+ /** The dashboard chooser, returning to this page. */
26
+ readonly choose: string;
27
+ }
10
28
  /** Retained browser bytes. Hosts authorize access before reading or rendering them. */
11
29
  export interface AppUiAsset {
12
30
  readonly body: Uint8Array;
@@ -0,0 +1,6 @@
1
+ /** Compiled from src/browser/app-watch.ts. */
2
+ export declare const 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();})();";
3
+ /** Compiled from src/browser/app-failure.ts. */
4
+ export declare const 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();})();";
5
+ /** Compiled from src/browser/account-notice.ts. */
6
+ export declare const 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();})();";
@@ -0,0 +1,9 @@
1
+ /** Host-rendered account notices; no authored app code or provider responses enter them. */
2
+ import type { UiAccountNotice, UiAccountProblem } from "../contracts/ui.js";
3
+ /** Missing, removed, incompatible, or rejected accounts stop the app; other failed checks are advisory. */
4
+ export declare const accountProblemBlocks: (problem: UiAccountProblem) => boolean;
5
+ export declare const accountProblemText: (problem: UiAccountProblem) => string;
6
+ /** Full page shown instead of the app while an account problem stops it from working. */
7
+ export declare const accountBlockedPage: (notice: UiAccountNotice) => string;
8
+ /** Inline card for advisory problems; the app still loads underneath. */
9
+ export declare const accountNoticeBootstrap: (notice: UiAccountNotice) => string;
@@ -1,2 +1,2 @@
1
1
  /** Inline host script: no app dependencies, credentials, or authored HTML enter its source. */
2
- export declare const appFailureBootstrap: string;
2
+ export declare const appFailureBootstrap = "<script>\"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();})();</script>";
@@ -1,12 +1,16 @@
1
1
  import { Effect } from "effect";
2
2
  import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
3
- import { UiForbidden, type AppUiAsset } from "../contracts/ui.js";
4
- /** Render an authorized deployment with a host-owned deployment watcher. */
3
+ import { UiForbidden, type AppUiAsset, type UiAccountNotice } from "../contracts/ui.js";
4
+ /**
5
+ * Render an authorized deployment with a host-owned deployment watcher. Account problems that stop
6
+ * the app replace its document with a page that links to their fix; others add a dismissible card.
7
+ */
5
8
  export declare const appDocument: <E, R>(options: {
6
9
  readonly deployment: string;
7
10
  readonly profile?: string | undefined;
8
11
  readonly expectedProfileRevision?: number | undefined;
9
12
  readonly origin: string;
13
+ readonly accounts?: UiAccountNotice | undefined;
10
14
  readonly asset: (path: string) => Effect.Effect<AppUiAsset | undefined, E, R>;
11
15
  }) => Effect.Effect<HttpServerResponse.HttpServerResponse, UiForbidden | E, HttpServerRequest.HttpServerRequest | R>;
12
16
  /** Serve an asset only after the host has checked current access and file existence.
@@ -1,2 +1,2 @@
1
1
  /** Dependency-free browser source served by each host after app authorization. */
2
- export declare const appWatchScript: string;
2
+ export declare const appWatchScript = "\"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();})();";