@jbrowse/capture 5.0.0-beta.11 → 5.0.0-beta.14
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/README.md +83 -2
- package/esm/annotationOverlay.d.ts +77 -0
- package/esm/annotationOverlay.js +766 -0
- package/esm/annotationSpec.d.ts +7 -0
- package/esm/annotationSpec.js +70 -0
- package/esm/annotations.d.ts +14 -0
- package/esm/annotations.js +68 -0
- package/esm/args.d.ts +5 -3
- package/esm/args.js +28 -13
- package/esm/bin.js +95 -22
- package/esm/capture.d.ts +31 -2
- package/esm/capture.js +162 -40
- package/esm/catalog.d.ts +11 -6
- package/esm/catalog.js +37 -14
- package/esm/dotplotAnchor.d.ts +4 -0
- package/esm/dotplotAnchor.js +104 -0
- package/esm/graphAnchor.d.ts +47 -0
- package/esm/graphAnchor.js +120 -0
- package/esm/index.d.ts +5 -2
- package/esm/index.js +2 -1
- package/esm/jsonArgs.d.ts +23 -0
- package/esm/jsonArgs.js +46 -0
- package/esm/poll.d.ts +9 -0
- package/esm/poll.js +23 -0
- package/esm/ready.d.ts +4 -4
- package/esm/ready.js +6 -2
- package/esm/sessionGate.d.ts +9 -3
- package/esm/sessionGate.js +15 -5
- package/esm/url.d.ts +6 -5
- package/esm/url.js +20 -5
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/esm/waits.d.ts +5 -4
- package/esm/waits.js +3 -5
- package/package.json +6 -4
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Annotation } from './annotationOverlay.ts';
|
|
2
|
+
export declare function readJson(flag: string, value: string): object;
|
|
3
|
+
export declare function readAnnotations(value: string): Annotation[];
|
|
4
|
+
export declare function readSpec(value: string): object;
|
|
5
|
+
export interface BatchEntry {
|
|
6
|
+
out: string;
|
|
7
|
+
hub?: string;
|
|
8
|
+
config?: string;
|
|
9
|
+
assembly?: string;
|
|
10
|
+
loc?: string;
|
|
11
|
+
tracks?: string[];
|
|
12
|
+
/** A session spec inline, or a path to one. */
|
|
13
|
+
spec?: object | string;
|
|
14
|
+
/** A session saved with File → Export session inline, or a path to one. */
|
|
15
|
+
session?: object | string;
|
|
16
|
+
width?: number;
|
|
17
|
+
height?: number;
|
|
18
|
+
dpr?: number;
|
|
19
|
+
fullPage?: boolean;
|
|
20
|
+
/** Callouts inline, or a path to them. */
|
|
21
|
+
annotations?: Annotation[] | string;
|
|
22
|
+
}
|
|
23
|
+
export declare function readBatch(value: string): BatchEntry[];
|
package/esm/jsonArgs.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
// inline JSON, `-` for stdin, or a path
|
|
3
|
+
function parseJson(flag, value) {
|
|
4
|
+
try {
|
|
5
|
+
const inline = /^\s*[[{]/.test(value);
|
|
6
|
+
return JSON.parse(value === '-'
|
|
7
|
+
? readFileSync(0, 'utf8')
|
|
8
|
+
: inline
|
|
9
|
+
? value
|
|
10
|
+
: readFileSync(value, 'utf8'));
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
throw new Error(`${flag.includes(' ') ? flag : `--${flag}`}: ${error instanceof Error ? error.message : error}`, { cause: error });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function readJson(flag, value) {
|
|
17
|
+
const parsed = parseJson(flag, value);
|
|
18
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
19
|
+
throw new Error(`--${flag} must be a JSON object`);
|
|
20
|
+
}
|
|
21
|
+
return parsed;
|
|
22
|
+
}
|
|
23
|
+
export function readAnnotations(value) {
|
|
24
|
+
const parsed = parseJson('annotations', value);
|
|
25
|
+
if (!Array.isArray(parsed)) {
|
|
26
|
+
throw new Error('--annotations must be a JSON array of callouts');
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
// a bare view object is the one-view spec it would be wrapped in
|
|
31
|
+
export function readSpec(value) {
|
|
32
|
+
const spec = readJson('spec', value);
|
|
33
|
+
return 'type' in spec && !('views' in spec) ? { views: [spec] } : spec;
|
|
34
|
+
}
|
|
35
|
+
export function readBatch(value) {
|
|
36
|
+
const parsed = parseJson('batch manifest', value);
|
|
37
|
+
if (!Array.isArray(parsed)) {
|
|
38
|
+
throw new Error('the batch manifest must be a JSON array of captures');
|
|
39
|
+
}
|
|
40
|
+
for (const [i, entry] of parsed.entries()) {
|
|
41
|
+
if (typeof entry?.out !== 'string') {
|
|
42
|
+
throw new Error(`batch capture ${i} has no "out" image path`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
package/esm/poll.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { Frame, Page } from 'puppeteer';
|
|
2
|
+
/** A page, or a frame inside one such as an embedded JBrowse's iframe. */
|
|
3
|
+
export type PageOrFrame = Page | Frame;
|
|
1
4
|
/** The budget each stage of the ready chain gets unless told otherwise. */
|
|
2
5
|
export declare const DEFAULT_TIMEOUT = 60000;
|
|
3
6
|
export declare const delay: (ms: number) => Promise<void>;
|
|
@@ -12,3 +15,9 @@ export declare function holdTrue(read: () => Promise<boolean>, { holdMs, timeout
|
|
|
12
15
|
timeout: number;
|
|
13
16
|
pollMs: number;
|
|
14
17
|
}): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Await a page query, answering `fallback` when it failed for a reason a later
|
|
20
|
+
* poll can outlive, such as a navigation destroying the execution context. A
|
|
21
|
+
* closed or crashed page throws, since no poll will recover it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function queryWhileOpen<T, F>(target: PageOrFrame, query: Promise<T>, fallback: F): Promise<T | F>;
|
package/esm/poll.js
CHANGED
|
@@ -28,3 +28,26 @@ export async function holdTrue(read, { holdMs, timeout, pollMs, }) {
|
|
|
28
28
|
}
|
|
29
29
|
return false;
|
|
30
30
|
}
|
|
31
|
+
function isGone(target) {
|
|
32
|
+
return 'page' in target
|
|
33
|
+
? target.detached || isGone(target.page())
|
|
34
|
+
: target.isClosed() || !target.browser().connected;
|
|
35
|
+
}
|
|
36
|
+
const PAGE_GONE = /crashed|Target closed|Session closed|Connection closed/i;
|
|
37
|
+
/**
|
|
38
|
+
* Await a page query, answering `fallback` when it failed for a reason a later
|
|
39
|
+
* poll can outlive, such as a navigation destroying the execution context. A
|
|
40
|
+
* closed or crashed page throws, since no poll will recover it.
|
|
41
|
+
*/
|
|
42
|
+
export async function queryWhileOpen(target, query, fallback) {
|
|
43
|
+
try {
|
|
44
|
+
return await query;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
48
|
+
if (PAGE_GONE.test(message) || isGone(target)) {
|
|
49
|
+
throw new Error(`the page closed or crashed before it finished rendering (${message})`, { cause: error });
|
|
50
|
+
}
|
|
51
|
+
return fallback;
|
|
52
|
+
}
|
|
53
|
+
}
|
package/esm/ready.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { PageOrFrame } from './poll.ts';
|
|
1
2
|
import type { DisplayState, SessionExpectations } from './sessionGate.ts';
|
|
2
|
-
import type { Page } from 'puppeteer';
|
|
3
3
|
export interface ReadyOptions extends SessionExpectations {
|
|
4
4
|
/** Budget for each wait stage. */
|
|
5
5
|
timeout?: number;
|
|
@@ -19,11 +19,11 @@ export interface ReadyReport {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Wait until the session holds the assembly and tracks asked for, the app has
|
|
22
|
-
* held itself ready,
|
|
22
|
+
* held itself ready, every display has painted, and no error is on screen.
|
|
23
23
|
*/
|
|
24
|
-
export declare function waitForJBrowseReady(page:
|
|
24
|
+
export declare function waitForJBrowseReady(page: PageOrFrame, options?: ReadyOptions): Promise<ReadyReport>;
|
|
25
25
|
/**
|
|
26
26
|
* `waitForJBrowseReady` without the session gate, for a frame that changed
|
|
27
27
|
* while the session did not, such as after a viewport resize.
|
|
28
28
|
*/
|
|
29
|
-
export declare function waitForFrame(page:
|
|
29
|
+
export declare function waitForFrame(page: PageOrFrame, { timeout, allowUnsettled, }?: Omit<ReadyOptions, keyof SessionExpectations>): Promise<ReadyReport>;
|
package/esm/ready.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DEFAULT_TIMEOUT } from './poll.js';
|
|
2
|
-
import { describeDisplays, displayCensusInPage, waitForSession, } from './sessionGate.js';
|
|
2
|
+
import { describeDisplays, displayCensusInPage, errorsShownInPage, waitForSession, } from './sessionGate.js';
|
|
3
3
|
import { appSettledBlocker } from './waits.js';
|
|
4
4
|
/**
|
|
5
5
|
* Wait until the session holds the assembly and tracks asked for, the app has
|
|
6
|
-
* held itself ready,
|
|
6
|
+
* held itself ready, every display has painted, and no error is on screen.
|
|
7
7
|
*/
|
|
8
8
|
export async function waitForJBrowseReady(page, options = {}) {
|
|
9
9
|
await waitForSession(page, options);
|
|
@@ -33,6 +33,10 @@ export async function waitForFrame(page, { timeout = DEFAULT_TIMEOUT, allowUnset
|
|
|
33
33
|
if (canceled.length > 0) {
|
|
34
34
|
unsettled.push(`display(s) canceled, which lasts until Retry: ${describeDisplays(canceled)}`);
|
|
35
35
|
}
|
|
36
|
+
const errors = await page.evaluate(errorsShownInPage);
|
|
37
|
+
if (errors.length > 0) {
|
|
38
|
+
unsettled.push(`error(s) on screen: ${errors.join('; ')}`);
|
|
39
|
+
}
|
|
36
40
|
if (!allowUnsettled && unsettled.length > 0) {
|
|
37
41
|
const stillLoading = pending.some(d => d.phase === undefined || d.phase === 'loading');
|
|
38
42
|
const advice = timedOut || stillLoading
|
package/esm/sessionGate.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PageOrFrame } from './poll.ts';
|
|
2
2
|
export interface SessionExpectations {
|
|
3
3
|
/** Assembly that must be open on some view. */
|
|
4
4
|
assembly?: string;
|
|
@@ -8,7 +8,7 @@ export interface SessionExpectations {
|
|
|
8
8
|
*/
|
|
9
9
|
trackIds?: string[];
|
|
10
10
|
/** The fewest open views that count. Default 1; 0 accepts none. */
|
|
11
|
-
|
|
11
|
+
minViews?: number;
|
|
12
12
|
}
|
|
13
13
|
export interface SessionCensus {
|
|
14
14
|
views: number;
|
|
@@ -30,7 +30,7 @@ export declare function readSessionInPage(): {
|
|
|
30
30
|
* Throws at once with the app's message if it could not load, and on timeout
|
|
31
31
|
* with what the census held instead.
|
|
32
32
|
*/
|
|
33
|
-
export declare function waitForSession(page:
|
|
33
|
+
export declare function waitForSession(page: PageOrFrame, { assembly, trackIds, minViews, timeout, }?: SessionExpectations & {
|
|
34
34
|
timeout?: number;
|
|
35
35
|
}): Promise<void>;
|
|
36
36
|
/** One display and the phase it publishes. */
|
|
@@ -55,5 +55,11 @@ export declare function displayCensusInPage(): {
|
|
|
55
55
|
pending: DisplayState[];
|
|
56
56
|
tooLarge: DisplayState[];
|
|
57
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* The error surfaces no display carries: the toast `notifyError` raises, as a
|
|
60
|
+
* track whose config fails to load does, and the box `ErrorMessage` renders.
|
|
61
|
+
* A track that never opened leaves nothing in {@link displayCensusInPage}.
|
|
62
|
+
*/
|
|
63
|
+
export declare function errorsShownInPage(): string[];
|
|
58
64
|
/** Displays as one clause for a message. */
|
|
59
65
|
export declare function describeDisplays(displays: DisplayState[]): string;
|
package/esm/sessionGate.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_TIMEOUT, holdTrue } from './poll.js';
|
|
1
|
+
import { DEFAULT_TIMEOUT, holdTrue, queryWhileOpen } from './poll.js';
|
|
2
2
|
/**
|
|
3
3
|
* The load failure the app shows in place of itself, the census
|
|
4
4
|
* `AppReadyMarker` publishes beside its phase, and any snackbar up — which is
|
|
@@ -33,11 +33,11 @@ export function readSessionInPage() {
|
|
|
33
33
|
* Throws at once with the app's message if it could not load, and on timeout
|
|
34
34
|
* with what the census held instead.
|
|
35
35
|
*/
|
|
36
|
-
export async function waitForSession(page, { assembly, trackIds = [],
|
|
36
|
+
export async function waitForSession(page, { assembly, trackIds = [], minViews = 1, timeout = DEFAULT_TIMEOUT, } = {}) {
|
|
37
37
|
let last;
|
|
38
38
|
const notices = new Set();
|
|
39
39
|
const reached = await holdTrue(async () => {
|
|
40
|
-
const read = await page.evaluate(readSessionInPage)
|
|
40
|
+
const read = await queryWhileOpen(page, page.evaluate(readSessionInPage), undefined);
|
|
41
41
|
if (read?.failure) {
|
|
42
42
|
throw new Error(`JBrowse could not load: ${read.failure}`);
|
|
43
43
|
}
|
|
@@ -47,7 +47,7 @@ export async function waitForSession(page, { assembly, trackIds = [], views = 1,
|
|
|
47
47
|
const census = read?.census;
|
|
48
48
|
last = census;
|
|
49
49
|
return (!!census &&
|
|
50
|
-
census.views >=
|
|
50
|
+
census.views >= minViews &&
|
|
51
51
|
(assembly === undefined || census.assemblies.includes(assembly)) &&
|
|
52
52
|
trackIds.every(id => census.trackIds.includes(id)));
|
|
53
53
|
}, { holdMs: 0, timeout, pollMs: 250 });
|
|
@@ -67,7 +67,7 @@ export async function waitForSession(page, { assembly, trackIds = [], views = 1,
|
|
|
67
67
|
const said = notices.size
|
|
68
68
|
? `The app said: ${[...notices].join(' | ')}.`
|
|
69
69
|
: 'A trackId the config does not define, or an assembly name that does not match the config, looks like this.';
|
|
70
|
-
throw new Error(`the session never reached the requested state after ${timeout}ms. Wanted ${wanted || (
|
|
70
|
+
throw new Error(`the session never reached the requested state after ${timeout}ms. Wanted ${wanted || (minViews > 0 ? 'an open view' : 'a session')}; found ${found}. ${said}`);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
@@ -94,6 +94,16 @@ export function displayCensusInPage() {
|
|
|
94
94
|
}
|
|
95
95
|
return { pending, tooLarge };
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* The error surfaces no display carries: the toast `notifyError` raises, as a
|
|
99
|
+
* track whose config fails to load does, and the box `ErrorMessage` renders.
|
|
100
|
+
* A track that never opened leaves nothing in {@link displayCensusInPage}.
|
|
101
|
+
*/
|
|
102
|
+
export function errorsShownInPage() {
|
|
103
|
+
return [
|
|
104
|
+
...document.querySelectorAll('[data-testid="snackbar-error"], [data-testid="error-message-box"]'),
|
|
105
|
+
].map(el => (el.innerText || el.textContent || '').trim().slice(0, 300));
|
|
106
|
+
}
|
|
97
107
|
/** Displays as one clause for a message. */
|
|
98
108
|
export function describeDisplays(displays) {
|
|
99
109
|
return displays
|
package/esm/url.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const PUBLIC_INSTANCE = "https://jbrowse.org/code/jb2/v5.0.0-beta.
|
|
1
|
+
export declare const PUBLIC_INSTANCE = "https://jbrowse.org/code/jb2/v5.0.0-beta.14/";
|
|
2
2
|
/**
|
|
3
3
|
* The instance as the page that loads it sees it: a directory given without
|
|
4
4
|
* its slash, which the host redirects, resolves relative URLs one level up.
|
|
@@ -7,7 +7,7 @@ export declare function instanceUrl(instance?: string): URL;
|
|
|
7
7
|
export interface JBrowseUrlOptions {
|
|
8
8
|
/** A genomes.jbrowse.org assembly: a UCSC db name (`hg38`) or GenArk accession. */
|
|
9
9
|
hub?: string;
|
|
10
|
-
/** A config.json URL, for data that is not on genomes.jbrowse.org.
|
|
10
|
+
/** A config.json URL, for data that is not on genomes.jbrowse.org. Not combined with `hub`. */
|
|
11
11
|
config?: string;
|
|
12
12
|
/** Assembly to open. Defaults to `hub`, whose config names its assembly after it. */
|
|
13
13
|
assembly?: string;
|
|
@@ -32,10 +32,11 @@ export interface JBrowseUrlOptions {
|
|
|
32
32
|
instance?: string;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* One source for the config, never a hub and a config URL. A spec or a saved
|
|
36
|
+
* session says which assembly, locations and tracks to open, so the URL carries
|
|
37
|
+
* one of the three ways of saying so, never two.
|
|
37
38
|
*/
|
|
38
|
-
export declare function
|
|
39
|
+
export declare function assertCoherentOptions({ hub, config, spec, session, assembly, loc, tracks, }: JBrowseUrlOptions): void;
|
|
39
40
|
/**
|
|
40
41
|
* The URL that opens a JBrowse Web instance onto a described view, for a
|
|
41
42
|
* person to follow without launching a browser here.
|
package/esm/url.js
CHANGED
|
@@ -9,17 +9,24 @@ export const PUBLIC_INSTANCE = `https://jbrowse.org/code/jb2/v${version}/`;
|
|
|
9
9
|
* its slash, which the host redirects, resolves relative URLs one level up.
|
|
10
10
|
*/
|
|
11
11
|
export function instanceUrl(instance = PUBLIC_INSTANCE) {
|
|
12
|
-
const url =
|
|
12
|
+
const url = URL.parse(instance);
|
|
13
|
+
if (!url || !['http:', 'https:', 'file:'].includes(url.protocol)) {
|
|
14
|
+
throw new Error(`instance "${instance}" is not an http(s) or file URL`);
|
|
15
|
+
}
|
|
13
16
|
if (!url.pathname.endsWith('/') && !/\.html?$/.test(url.pathname)) {
|
|
14
17
|
url.pathname += '/';
|
|
15
18
|
}
|
|
16
19
|
return url;
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
22
|
+
* One source for the config, never a hub and a config URL. A spec or a saved
|
|
23
|
+
* session says which assembly, locations and tracks to open, so the URL carries
|
|
24
|
+
* one of the three ways of saying so, never two.
|
|
21
25
|
*/
|
|
22
|
-
export function
|
|
26
|
+
export function assertCoherentOptions({ hub, config, spec, session, assembly, loc, tracks, }) {
|
|
27
|
+
if (hub && config) {
|
|
28
|
+
throw new Error('pass a hosted hub or a config URL, not both (--hub, --config); name the assembly with --assembly');
|
|
29
|
+
}
|
|
23
30
|
if (spec && session) {
|
|
24
31
|
throw new Error('pass a session spec or a saved session, not both');
|
|
25
32
|
}
|
|
@@ -41,7 +48,15 @@ export function assertSessionStandsAlone({ spec, session, assembly, loc, tracks,
|
|
|
41
48
|
* takes a locstring only. `session` opens a saved session as exported.
|
|
42
49
|
*/
|
|
43
50
|
export function jbrowseUrl({ hub, config, assembly, loc, tracks, spec, session, sessionName, instance, }) {
|
|
44
|
-
|
|
51
|
+
assertCoherentOptions({
|
|
52
|
+
hub,
|
|
53
|
+
config,
|
|
54
|
+
spec,
|
|
55
|
+
session,
|
|
56
|
+
assembly,
|
|
57
|
+
loc,
|
|
58
|
+
tracks,
|
|
59
|
+
});
|
|
45
60
|
const params = new URLSearchParams();
|
|
46
61
|
const set = (key, value) => {
|
|
47
62
|
if (value) {
|
package/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.0.0-beta.
|
|
1
|
+
export declare const version = "5.0.0-beta.14";
|
package/esm/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.0.0-beta.
|
|
1
|
+
export const version = '5.0.0-beta.14';
|
package/esm/waits.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PageOrFrame } from './poll.ts';
|
|
2
|
+
import type { ElementHandle } from 'puppeteer';
|
|
2
3
|
interface WaitOptions {
|
|
3
4
|
timeout?: number;
|
|
4
5
|
}
|
|
@@ -14,7 +15,7 @@ export declare const displaySettled: (testid: string) => string;
|
|
|
14
15
|
* `page.waitForSelector`, whose timeout names each display that had not
|
|
15
16
|
* painted and the phase it was in.
|
|
16
17
|
*/
|
|
17
|
-
export declare function waitForSelectorAttributed(page:
|
|
18
|
+
export declare function waitForSelectorAttributed(page: PageOrFrame, selector: string, { timeout }?: WaitOptions): Promise<ElementHandle>;
|
|
18
19
|
type SettleOptions = WaitOptions & {
|
|
19
20
|
holdMs?: number;
|
|
20
21
|
pollMs?: number;
|
|
@@ -23,7 +24,7 @@ type SettleOptions = WaitOptions & {
|
|
|
23
24
|
* `waitForAppSettled`, answering with what was still blocking at the timeout,
|
|
24
25
|
* or undefined once the hold passed.
|
|
25
26
|
*/
|
|
26
|
-
export declare function appSettledBlocker(page:
|
|
27
|
+
export declare function appSettledBlocker(page: PageOrFrame, { timeout, holdMs, pollMs, }?: SettleOptions): Promise<string | undefined>;
|
|
27
28
|
/**
|
|
28
29
|
* Wait until every app on the page has read ready, with nothing loading or
|
|
29
30
|
* animating, for an unbroken `holdMs`. False on timeout. Right after a
|
|
@@ -31,5 +32,5 @@ export declare function appSettledBlocker(page: Page, { timeout, holdMs, pollMs,
|
|
|
31
32
|
* publishes `[data-app-phase]` throws, since nothing positive exists to wait
|
|
32
33
|
* for.
|
|
33
34
|
*/
|
|
34
|
-
export declare function waitForAppSettled(page:
|
|
35
|
+
export declare function waitForAppSettled(page: PageOrFrame, options?: SettleOptions): Promise<boolean>;
|
|
35
36
|
export {};
|
package/esm/waits.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_TIMEOUT, holdTrue } from './poll.js';
|
|
1
|
+
import { DEFAULT_TIMEOUT, holdTrue, queryWhileOpen } from './poll.js';
|
|
2
2
|
import { describeDisplays, displayCensusInPage } from './sessionGate.js';
|
|
3
3
|
/** The app's own verdict: no view is resolving an assembly, no display is fetching. */
|
|
4
4
|
export const APP_READY = '[data-app-phase="ready"]';
|
|
@@ -64,14 +64,12 @@ const NO_MARKER = 'no [data-app-phase] on the page';
|
|
|
64
64
|
* or undefined once the hold passed.
|
|
65
65
|
*/
|
|
66
66
|
export async function appSettledBlocker(page, { timeout = DEFAULT_TIMEOUT, holdMs = APP_SETTLED_HOLD_MS, pollMs = 250, } = {}) {
|
|
67
|
-
const blocker = () => page
|
|
68
|
-
.evaluate((ready, blockers, noMarker) => document.querySelector('[data-app-phase]') === null
|
|
67
|
+
const blocker = () => queryWhileOpen(page, page.evaluate((ready, blockers, noMarker) => document.querySelector('[data-app-phase]') === null
|
|
69
68
|
? noMarker
|
|
70
69
|
: (blockers.find(([selector]) => document.querySelector(selector))?.[1] ??
|
|
71
70
|
(document.querySelector(ready) === null
|
|
72
71
|
? 'the marker not reading ready'
|
|
73
|
-
: undefined)), APP_READY, SETTLE_BLOCKERS, NO_MARKER)
|
|
74
|
-
.catch(() => 'the page could not be queried');
|
|
72
|
+
: undefined)), APP_READY, SETTLE_BLOCKERS, NO_MARKER), 'the page could not be queried');
|
|
75
73
|
const held = await holdTrue(async () => (await blocker()) === undefined, {
|
|
76
74
|
holdMs,
|
|
77
75
|
timeout,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/capture",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.14",
|
|
4
4
|
"description": "Drive a JBrowse 2 instance with Puppeteer and screenshot it once it has actually finished rendering",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
"type": "module",
|
|
17
17
|
"main": "esm/index.js",
|
|
18
18
|
"exports": {
|
|
19
|
-
".": "./esm/index.js"
|
|
19
|
+
".": "./esm/index.js",
|
|
20
|
+
"./annotationOverlay": "./esm/annotationOverlay.js",
|
|
21
|
+
"./graphAnchor": "./esm/graphAnchor.js"
|
|
20
22
|
},
|
|
21
23
|
"author": "JBrowse Team",
|
|
22
24
|
"license": "Apache-2.0",
|
|
@@ -31,10 +33,10 @@
|
|
|
31
33
|
],
|
|
32
34
|
"sideEffects": false,
|
|
33
35
|
"dependencies": {
|
|
34
|
-
"puppeteer": "^25.
|
|
36
|
+
"puppeteer": "^25.14.0"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@jbrowse/core": "^5.0.0-beta.
|
|
39
|
+
"@jbrowse/core": "^5.0.0-beta.14"
|
|
38
40
|
},
|
|
39
41
|
"publishConfig": {
|
|
40
42
|
"access": "public"
|