mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 10:12:34 +00:00
Eng-council sweep: export hygiene, dead code, helper dedup, declare vega-expression
This commit is contained in:
@@ -12,7 +12,7 @@ import type { VisualizationSpec } from 'vega-embed';
|
||||
import type { Config } from 'vega-lite';
|
||||
|
||||
/** Options for `RenderHandle.toImageURL` (spec §08 → Per-chart export). */
|
||||
export interface ImageExportOptions {
|
||||
interface ImageExportOptions {
|
||||
/**
|
||||
* Pixel-density multiplier for the **PNG** raster, **relative to the device**.
|
||||
* The image is drawn at `scale × devicePixelRatio` logical-pixel density, so
|
||||
@@ -80,7 +80,7 @@ export interface RenderOptions {
|
||||
* size against this (÷ dpr, since the backing store is dpr× the CSS size) and
|
||||
* throws `ChartTooLargeError` rather than handing back a blank canvas.
|
||||
*/
|
||||
export const MAX_CANVAS_PX = 32767;
|
||||
const MAX_CANVAS_PX = 32767;
|
||||
|
||||
/**
|
||||
* Thrown by `renderSpec` when a **canvas**-backed chart resolves to a height larger
|
||||
|
||||
@@ -110,12 +110,20 @@ export function runMergeChartTheme(editor: monaco.editor.IStandaloneCodeEditor):
|
||||
});
|
||||
}
|
||||
|
||||
/** Remove the draft's `config` block, copying it to the clipboard first. */
|
||||
export async function runExtractConfig(editor: monaco.editor.IStandaloneCodeEditor): Promise<void> {
|
||||
/**
|
||||
* Shared prologue of the two extract actions: the model, the spec parsed off it,
|
||||
* and the config split out — or null (after toasting) when any step has nothing
|
||||
* to work with.
|
||||
*/
|
||||
function extractableConfig(editor: monaco.editor.IStandaloneCodeEditor): {
|
||||
model: monaco.editor.ITextModel;
|
||||
rest: Record<string, unknown>;
|
||||
config: Record<string, unknown>;
|
||||
} | null {
|
||||
const model = editor.getModel();
|
||||
if (!model) return;
|
||||
if (!model) return null;
|
||||
const spec = parseSpecObject(model);
|
||||
if (!spec) return;
|
||||
if (!spec) return null;
|
||||
|
||||
const { spec: rest, config } = extractConfigFromSpec(spec);
|
||||
if (config === null) {
|
||||
@@ -124,8 +132,16 @@ export async function runExtractConfig(editor: monaco.editor.IStandaloneCodeEdit
|
||||
title: 'No config to extract',
|
||||
message: 'This spec has no config block.',
|
||||
});
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
return { model, rest, config };
|
||||
}
|
||||
|
||||
/** Remove the draft's `config` block, copying it to the clipboard first. */
|
||||
export async function runExtractConfig(editor: monaco.editor.IStandaloneCodeEditor): Promise<void> {
|
||||
const extracted = extractableConfig(editor);
|
||||
if (!extracted) return;
|
||||
const { model, rest, config } = extracted;
|
||||
|
||||
// Copy before removing — if the clipboard write fails, the spec keeps its
|
||||
// config and nothing is lost.
|
||||
@@ -157,20 +173,9 @@ export async function runExtractConfig(editor: monaco.editor.IStandaloneCodeEdit
|
||||
* non-overlapping keys stop applying once the new theme replaces it.)
|
||||
*/
|
||||
export function runExtractConfigToTheme(editor: monaco.editor.IStandaloneCodeEditor): void {
|
||||
const model = editor.getModel();
|
||||
if (!model) return;
|
||||
const spec = parseSpecObject(model);
|
||||
if (!spec) return;
|
||||
|
||||
const { spec: rest, config } = extractConfigFromSpec(spec);
|
||||
if (config === null) {
|
||||
notify({
|
||||
kind: 'info',
|
||||
title: 'No config to extract',
|
||||
message: 'This spec has no config block.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const extracted = extractableConfig(editor);
|
||||
if (!extracted) return;
|
||||
const { model, rest, config } = extracted;
|
||||
|
||||
const snippet = selectActiveSnippet(useSnippetStore.getState());
|
||||
const theme = useCustomThemeStore
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
reassignCollidingSnippetIds,
|
||||
} from '@core/import-normalize';
|
||||
import { snippetSizeBytes } from '@core/snippet';
|
||||
import { humanizeBytes } from '@core/storage-estimate';
|
||||
import { downloadJson, readTextFile } from '../infrastructure/file-transfer';
|
||||
import { deleteSnippet, saveSnippet, StorageQuotaError } from '../infrastructure/snippet-store';
|
||||
import { notify } from '../stores/NotificationStore';
|
||||
@@ -36,13 +37,6 @@ import { useSnippetStore } from '../stores/SnippetStore';
|
||||
/** Practical snippet-storage budget (spec §02 storage monitor / §08). */
|
||||
const SNIPPET_BUDGET_BYTES = 5 * 1024 * 1024;
|
||||
|
||||
/** Round bytes to a short KB/MB string for the overage warning. */
|
||||
function formatBytes(bytes: number): string {
|
||||
const kb = bytes / 1024;
|
||||
if (kb < 1024) return `${Math.max(1, Math.round(kb))} KB`;
|
||||
return `${Math.round(kb / 1024)} MB`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the whole workspace to a downloaded JSON file (spec §08 → Export).
|
||||
* Flushes the live editor buffer first so in-progress draft edits are included.
|
||||
@@ -209,7 +203,7 @@ export async function importWorkspace(file: File): Promise<void> {
|
||||
}
|
||||
if (overage > 0) {
|
||||
clauses.push(
|
||||
`This puts snippet storage about ${formatBytes(overage)} over the ~5 MB budget; ` +
|
||||
`This puts snippet storage about ${humanizeBytes(overage)} over the ~5 MB budget; ` +
|
||||
`consider deleting some snippets.`,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user