@picked/svelte 0.0.1-dev.1793923852884 → 0.0.1-dev.1793933802654
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/dist/.tsbuildinfo +1 -1
- package/dist/plugins/devtools/DevToolsExperience.svelte +32 -2
- package/dist/plugins/devtools/derive/guide-sections/guide-sections.d.ts +1 -1
- package/dist/plugins/devtools/derive/guide-sections/guide-sections.js +1 -1
- package/dist/plugins/devtools/derive/index.d.ts +3 -1
- package/dist/plugins/devtools/derive/index.js +1 -1
- package/dist/plugins/devtools/derive/issue-report/index.d.ts +3 -0
- package/dist/plugins/devtools/derive/issue-report/index.js +1 -0
- package/dist/plugins/devtools/derive/issue-report/issue-report.d.ts +255 -0
- package/dist/plugins/devtools/derive/issue-report/issue-report.js +2 -0
- package/dist/plugins/devtools/derive/plain-language/index.d.ts +1 -1
- package/dist/plugins/devtools/derive/plain-language/index.js +1 -1
- package/dist/plugins/devtools/derive/plain-language/plain-language.d.ts +6 -0
- package/dist/plugins/devtools/derive/plain-language/plain-language.js +1 -1
- package/dist/plugins/devtools/index.d.ts +4 -1
- package/dist/plugins/devtools/index.js +1 -1
- package/dist/plugins/devtools/options.d.ts +30 -1
- package/dist/plugins/devtools/options.js +1 -1
- package/dist/plugins/devtools/review/index.d.ts +3 -2
- package/dist/plugins/devtools/review/index.js +1 -1
- package/dist/plugins/devtools/review/issues/ReportIssuePanel.svelte +805 -0
- package/dist/plugins/devtools/review/issues/capture-screenshot.d.ts +38 -0
- package/dist/plugins/devtools/review/issues/capture-screenshot.js +1 -0
- package/dist/plugins/devtools/review/issues/read-attachment.d.ts +27 -0
- package/dist/plugins/devtools/review/issues/read-attachment.js +1 -0
- package/dist/plugins/devtools/review/issues/site-endpoint.d.ts +17 -0
- package/dist/plugins/devtools/review/issues/site-endpoint.js +1 -0
- package/dist/plugins/devtools/sidebar/nav.d.ts +6 -3
- package/dist/plugins/devtools/sidebar/nav.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Takes a screenshot of the page for a report, through the browser's screen-share prompt.
|
|
3
|
+
*
|
|
4
|
+
* The panel hides BEFORE the prompt opens, so neither the panel nor the prompt is in the shot, and
|
|
5
|
+
* shows again however the capture ends.
|
|
6
|
+
*/
|
|
7
|
+
import type { IssueAttachment } from '../../derive/issue-report';
|
|
8
|
+
/** The largest screenshot a report carries. */
|
|
9
|
+
export declare const MAX_SCREENSHOT_BYTES: number;
|
|
10
|
+
/** Why a screenshot was not taken. */
|
|
11
|
+
export declare class ScreenshotError extends Error {
|
|
12
|
+
/** `unsupported`: the browser cannot share a screen. `cancelled`: the reviewer said no. */
|
|
13
|
+
readonly reason: 'unsupported' | 'cancelled' | 'failed';
|
|
14
|
+
/**
|
|
15
|
+
* A refused or failed screenshot.
|
|
16
|
+
*
|
|
17
|
+
* @param {'unsupported' | 'cancelled' | 'failed'} reason - Why.
|
|
18
|
+
* @param {string} message - What the reviewer reads.
|
|
19
|
+
* @example new ScreenshotError('cancelled', 'No screenshot was taken.')
|
|
20
|
+
*/
|
|
21
|
+
constructor(reason: 'unsupported' | 'cancelled' | 'failed', message: string);
|
|
22
|
+
}
|
|
23
|
+
/** What a capture hides and shows around the prompt. */
|
|
24
|
+
export interface CaptureHooks {
|
|
25
|
+
hide: () => void;
|
|
26
|
+
show: () => void;
|
|
27
|
+
}
|
|
28
|
+
/** The part of the browser's media devices a capture uses. */
|
|
29
|
+
export type ScreenShare = Pick<MediaDevices, 'getDisplayMedia'>;
|
|
30
|
+
/**
|
|
31
|
+
* Takes a screenshot of what the reviewer shares, as a JPEG attachment.
|
|
32
|
+
*
|
|
33
|
+
* @param {CaptureHooks} hooks - Hides the panel before the prompt, and shows it after.
|
|
34
|
+
* @param {ScreenShare | null} [media] - The screen sharing to use; `null` for none.
|
|
35
|
+
* @returns {Promise<IssueAttachment>} The screenshot.
|
|
36
|
+
* @example await captureScreenshot({ hide, show })
|
|
37
|
+
*/
|
|
38
|
+
export declare function captureScreenshot(hooks: CaptureHooks, media?: ScreenShare | null): Promise<IssueAttachment>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readAttachment as e}from"./read-attachment.js";var t=1572864,n=1920,r=[.85,.7,.55,.4],i=class extends Error{reason;constructor(e,t){super(t),this.name=`ScreenshotError`,this.reason=e}};function a(){return new Promise(e=>{requestAnimationFrame(()=>requestAnimationFrame(()=>e()))})}async function o(e){let t=document.createElement(`video`);t.muted=!0,t.playsInline=!0,t.srcObject=e,await t.play(),t.videoWidth===0&&await new Promise(e=>{t.addEventListener(`loadeddata`,e,{once:!0})});let r=Math.min(1,n/t.videoWidth),i=document.createElement(`canvas`);return i.width=Math.round(t.videoWidth*r),i.height=Math.round(t.videoHeight*r),i.getContext(`2d`)?.drawImage(t,0,0,i.width,i.height),t.srcObject=null,i}async function s(e){let t=null;for(let n of r){let r=await new Promise(t=>{e.toBlob(t,`image/jpeg`,n)});if(r===null)break;if(t=r,r.size<=1572864)return r}if(t===null||t.size>1572864)throw new i(`failed`,`The screenshot is too large to send. Attach a smaller one.`);return t}function c(){return typeof navigator<`u`&&`mediaDevices`in navigator?navigator.mediaDevices:null}async function l(t,n=c()){if(typeof n?.getDisplayMedia!=`function`)throw new i(`unsupported`,`This browser cannot take a screenshot. Attach one instead.`);t.hide();try{await a();let t={video:!0,audio:!1,preferCurrentTab:!0},r;try{r=await n.getDisplayMedia(t)}catch{throw new i(`cancelled`,`No screenshot was taken.`)}try{let t=await s(await o(r)),n=new Date().toISOString().replaceAll(/[:.]/g,`-`);return await e(t,`screenshot-${n}.jpg`)}finally{for(let e of r.getTracks())e.stop()}}finally{t.show()}}export{t as MAX_SCREENSHOT_BYTES,i as ScreenshotError,l as captureScreenshot};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @file Reads a file, or a captured image, into an attachment a report carries. */
|
|
2
|
+
import type { IssueAttachment } from '../../derive/issue-report';
|
|
3
|
+
/**
|
|
4
|
+
* A blob's bytes as base64, with no `data:` prefix.
|
|
5
|
+
*
|
|
6
|
+
* @param {Blob} blob - The bytes.
|
|
7
|
+
* @returns {Promise<string>} The base64 text.
|
|
8
|
+
* @example await readAsBase64(new Blob(['hi'])) // 'aGk='
|
|
9
|
+
*/
|
|
10
|
+
export declare function readAsBase64(blob: Blob): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* A blob as an attachment.
|
|
13
|
+
*
|
|
14
|
+
* @param {Blob} blob - The bytes.
|
|
15
|
+
* @param {string} filename - The name it goes by.
|
|
16
|
+
* @returns {Promise<IssueAttachment>} The attachment.
|
|
17
|
+
* @example await readAttachment(file, file.name)
|
|
18
|
+
*/
|
|
19
|
+
export declare function readAttachment(blob: Blob, filename: string): Promise<IssueAttachment>;
|
|
20
|
+
/**
|
|
21
|
+
* An image attachment as a `data:` URL an `<img>` can show.
|
|
22
|
+
*
|
|
23
|
+
* @param {IssueAttachment} attachment - The attachment.
|
|
24
|
+
* @returns {string | null} The URL, or `null` for a file that is not an image.
|
|
25
|
+
* @example previewUrl({ contentType: 'image/png', data: 'iVBO…', filename: 'a.png', size: 9 })
|
|
26
|
+
*/
|
|
27
|
+
export declare function previewUrl(attachment: IssueAttachment): string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){return new Promise((t,n)=>{let r=new FileReader;r.addEventListener(`load`,()=>{let{result:e}=r;t(typeof e==`string`?e.slice(e.indexOf(`,`)+1):``)}),r.addEventListener(`error`,()=>n(r.error??Error(`The file could not be read.`))),r.readAsDataURL(e)})}async function t(t,n){return{filename:n,contentType:t.type,data:await e(t),size:t.size}}function n(e){return e.contentType.startsWith(`image/`)?`data:${e.contentType};base64,${e.data}`:null}export{n as previewUrl,e as readAsBase64,t as readAttachment};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @file A sink that posts each report to an endpoint on the site's own server. */
|
|
2
|
+
import { type IssueSink } from '../../derive/issue-report';
|
|
3
|
+
/** How {@link siteEndpoint} calls the endpoint. */
|
|
4
|
+
export interface SiteEndpointOptions {
|
|
5
|
+
/** Headers sent with each report, over `content-type: application/json`. */
|
|
6
|
+
headers?: Readonly<Record<string, string>>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A sink that posts each report as JSON to an endpoint the site runs, which files it in the site's
|
|
10
|
+
* tracker. The endpoint answers with the issue's `reference` (or `identifier`, or `id`) and `url`.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} url - The endpoint, absolute or relative to the page.
|
|
13
|
+
* @param {SiteEndpointOptions} [options] - How to call it.
|
|
14
|
+
* @returns {IssueSink} The sink, for the devtools' `issues.sink` option.
|
|
15
|
+
* @example svelteDevtoolsPlugin({ issues: { sink: siteEndpoint('/api/report-issue') } })
|
|
16
|
+
*/
|
|
17
|
+
export declare function siteEndpoint(url: string, options?: SiteEndpointOptions): IssueSink;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readReceipt as e}from"../../derive/issue-report/issue-report.js";function t(t,n={}){return async r=>{let i=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`,...n.headers},body:JSON.stringify(r)});if(!i.ok)throw Error(`The report was not sent: the server answered ${i.status}.`);let a=await i.json().catch(()=>null);return e(a)}}export{t as siteEndpoint};
|
|
@@ -3,9 +3,9 @@ import type { CustomToolIcon } from '../customTools';
|
|
|
3
3
|
import type { StorageGetter } from '../launcher/launcher';
|
|
4
4
|
/**
|
|
5
5
|
* What a sidebar entry opens: a review tab, a custom tool, the Custom Tools page listed while no
|
|
6
|
-
* unplaced tool is registered,
|
|
6
|
+
* unplaced tool is registered, one of the SDK's own screens, or Report an issue.
|
|
7
7
|
*/
|
|
8
|
-
export type NavKind = 'review' | 'tool' | 'custom-tools' | 'screen';
|
|
8
|
+
export type NavKind = 'review' | 'tool' | 'custom-tools' | 'screen' | 'report';
|
|
9
9
|
/** One entry of the sidebar: a row, or an icon at its foot. */
|
|
10
10
|
export interface NavItem {
|
|
11
11
|
/** Unique across the whole sidebar. */
|
|
@@ -15,7 +15,10 @@ export interface NavItem {
|
|
|
15
15
|
/** The glyph of an icon at the sidebar's foot. */
|
|
16
16
|
icon?: CustomToolIcon;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* The sidebar's entries: the top-level tabs, the Advanced group's screens, and the foot's icons,
|
|
20
|
+
* Report an issue's bug first.
|
|
21
|
+
*/
|
|
19
22
|
export interface NavModel {
|
|
20
23
|
primary: readonly NavItem[];
|
|
21
24
|
advanced: readonly NavItem[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TAB_LABELS as
|
|
1
|
+
import{REPORT_ISSUE_LABEL as e,REPORT_ISSUE_TAB as t,TAB_LABELS as n}from"../derive/plain-language/plain-language.js";var r=`picked-devtools-tab`,i=`picked-devtools-advanced-open`,a=`Custom Tools`,o=`guide`,s=`custom-tools`,c=[{id:`components`,label:`Components`},{id:`config`,label:`Config`},{id:`content`,label:`Content`},{id:`events`,label:`Events`},{id:`fields`,label:`Fields`},{id:`frameworks`,label:`Frameworks`},{id:`history`,label:`History`},{id:`identity`,label:`Identity`},{id:`predicates`,label:`Predicates`},{id:`project`,label:`Project`}];function l(e){return`tool:${e}`}function u(e){return`screen:${e}`}function d(r){let i=[{id:`guide`,label:n.guide,kind:`review`},{id:`session`,label:n.session,kind:`review`},{id:`answers`,label:n.answers,kind:`review`},{id:`journey`,label:n.journey,kind:`review`},{id:`personas`,label:n.personas,kind:`review`}];r.variations&&i.push({id:`variations`,label:n.variations,kind:`review`});let o=e=>({id:l(e.id),label:e.label,kind:`tool`}),d=r.tools.map(o),f=r.customTools.map(o),p=c.map(e=>({id:u(e.id),label:e.label,kind:`screen`})),m=f.length===0?[{id:s,label:a,kind:`custom-tools`}]:[],h=[{id:t,label:e,kind:`report`,icon:`bug`},...r.footerTools.map(e=>({id:l(e.id),label:e.label,kind:`tool`,icon:e.icon??`wrench`}))];return{primary:[...i,...d,...f,...m],advanced:p,footer:h}}function f(e,t){return e===null?o:[...t.primary,...t.advanced,...t.footer].some(t=>t.id===e)?e:o}function p(e,t){return t.advanced.some(t=>t.id===e)}function m(e,t,n){let r=Math.max(0,n-1);switch(e){case`ArrowDown`:return Math.min(t+1,r);case`ArrowUp`:return Math.max(t-1,0);case`Home`:return 0;case`End`:return r;default:return null}}function h(e,t){try{return e().getItem(t)}catch{return null}}function g(e,t,n){try{e().setItem(t,n)}catch{}}export{i as ADVANCED_OPEN_STORAGE_KEY,a as CUSTOM_TOOLS_LABEL,s as CUSTOM_TOOLS_TAB,o as DEFAULT_TAB,c as SCREENS,r as TAB_STORAGE_KEY,d as buildNav,p as isInAdvanced,m as nextFocusIndex,h as readStored,f as resolveTab,u as screenTabId,l as toolTabId,g as writeStored};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/svelte",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.1793933802654",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"d3": "^7.9.0"
|
|
6
6
|
},
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"license": "SEE LICENSE IN LICENSE",
|
|
114
114
|
"module": "./dist/index.js",
|
|
115
115
|
"peerDependencies": {
|
|
116
|
-
"@picked/client": "0.0.1-dev.
|
|
116
|
+
"@picked/client": "0.0.1-dev.1793933802654",
|
|
117
117
|
"effector": "^23.4.4",
|
|
118
118
|
"svelte": "^5.55.7"
|
|
119
119
|
},
|