Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 2x 2x 2x 2x 2x 2x 2x 2x 3356x 130x 130x 130x 2x 3350x 3350x 2x 115x 115x 115x 115x 115x 115x 115x 130x 130x 105x 104x 104x 2x 225x 225x | /**
* Dev features: on `main`, invisible unless the page asked for them (§29).
*
* A dev feature is built, specified and tested like any other, and a reader
* who has not asked for it sees **nothing** of it — no row, no task, no
* command, no example, no clause in a sentence. Not greyed, not listed with an
* instruction: §8.5's corrected form would list a control the reader could make
* work, and this is the one case where there is something they could do and
* they are deliberately not told.
*
* **The registry is the list below**, one line each with the reason it is not
* public yet. Making a feature public is deleting its line — and then the
* compiler names every gate it leaves behind, because {@link DevFeature} is the
* registry's keys: a `devFeature('metacool')` whose key no longer exists is a
* type error rather than a gate that quietly always opens.
*
* **The switch is the page's address**, read once per page, so nothing about
* it is kept in the browser. The answer must not change under a page that was
* built with the other one: every surface is built once with it, so no card,
* task list, worker or cached command list can disagree with it.
*
* **Never in an embed** (§21): a host page is not a developer's browser.
* **Always on where there is no page** — the command line has no switch and
* shows everything (§29.5), and it shares the task registry and the examples
* that ask this.
*/
import { embedded } from '../embed'
/** What is dev today, and why. Delete a line to make that feature public. */
export const DEV_FEATURES = {
/**
* Both containers, the genome layer, its views and tasks, and every sentence naming them —
* and the DNA Bacterial Zoo's store, which is published with them (§24.3).
*/
metacool: 'The multi-genome format, and the bacterial zoo made beside it, are not published yet.',
/** The reference editor (§27): the stage, its task, its keys and the lens. */
edit: 'Editing the reference is not validated yet.',
/** Two sequences on two axes (§28). */
dotplot: 'The dot plot is not validated yet.',
} as const
export type DevFeature = keyof typeof DEV_FEATURES
let cached: boolean | null = null
/**
* Whether the dev features are on in this page.
*
* Read once and remembered: the answer must not change under a page that was
* built with the other one. `false` always in an embed.
*/
export function devFeaturesOn(): boolean {
if (cached !== null) return cached
cached = read()
return cached
}
/**
* Whether one dev feature is to be shown.
*
* Every registered feature answers to the one switch; the name is taken so that
* each gate says which feature it is, and so that deleting a registry line turns
* that feature's gates into compile errors (see the header).
*/
export function devFeature(feature: DevFeature): boolean {
return DEV_FEATURES[feature] !== undefined && devFeaturesOn()
}
/**
* Whether a query string asks for the dev features.
*
* Pure, so the whole contract is testable without a `location`. On for a key
* that is present, off for the three spellings of "no" — the same reading as
* `embed` (`embed.ts`).
*/
export function readDevFeatures(search: string): boolean {
let params: URLSearchParams
try {
params = new URLSearchParams(search)
} catch {
return false
}
const flag = params.get('dev')
return flag !== null && flag !== '0' && flag !== 'false' && flag !== 'off'
}
function read(): boolean {
// No page, no switch: the command line — which imports the same task
// registry and the same examples — sees everything, as §29.5 says it does. A
// worker has no `window` either, and is told the page's answer on each open
// instead of asking this.
if (typeof window === 'undefined') return true
if (embedded()) return false
return readDevFeatures(window.location.search)
}
/**
* Forget the remembered answer, or state one. For tests, and for the files the
* site build writes for language models (`llms/render.ts`): a page reads it
* once, and a test or a build under `node` has no address to put an answer in.
*/
export function resetDevFeatures(on: boolean | null = null): void {
cached = on
}
|