Back to Black Site Map Editor
SOURCE / PINNED RELEASE

Made of little things.

Black Site Map Editor

Release
32a57733b7e9…
Author-recorded commit
3f54890f542f…
License
LICENSE
Author’s source reference
nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.shakespeare.diy%2F/black-site-map-editor

Archive hash verified: 7a4b1abbac7db5b0…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/state/editor-state.ts
import type { NostrEvent } from '@napplet/sdk';
import { createMap, type BlackSiteMap, type Selection } from '../model';
import type { MapRecord } from '../map-host';
import { Store } from './store';

export type WorkspaceTab = 'map' | 'tools' | 'details';
export type CacheKind = '' | 'start' | 'weapons';

/** Everything the editor UI renders. Fast pointer/view state stays inside the canvas. */
export interface EditorState {
    map: BlackSiteMap;
    canUndo: boolean;
    canRedo: boolean;
    selection?: Selection;
    tool: string;
    placeOptions: { color: string; patrol: boolean; cacheKind: CacheKind };
    viewer: string;
    identityLabel: string;
    base?: MapRecord;
    remixOf?: NostrEvent;
    remixRelay?: string;
    content: string;
    hashtags: string[];
    image?: string;
    dirty: boolean;
    busy: boolean;
    showGrid: boolean;
    workspaceTab: WorkspaceTab;
    status: { message: string; kind: string };
    validation: string;
    publication: {
        phase: 'idle' | 'working' | 'success' | 'error';
        message: string;
        stage: number;
        error?: string;
        warnings: string[];
    };
    publishDetails: string;
    exportFallback: string;
    library: {
        view: 'none' | 'records' | 'templates';
        records: MapRecord[];
        status: string;
        loadMore: boolean;
    };
    /** Bumped whenever shortcut bindings change so key hints re-render. */
    shortcutsRev: number;
}

export function initialState(): EditorState {
    return {
        map: createMap(`map-${Date.now().toString(36)}`),
        canUndo: false,
        canRedo: false,
        tool: 'select',
        placeOptions: { color: '#2f5a7a', patrol: false, cacheKind: '' },
        viewer: '',
        identityLabel: 'Checking account…',
        content: '',
        hashtags: [],
        dirty: false,
        busy: false,
        showGrid: true,
        workspaceTab: 'map',
        status: { message: 'Ready. Create a map or open Maps to browse published maps.', kind: '' },
        validation: 'Check the walkable route before publishing.',
        publication: { phase: 'idle', message: '', stage: 0, warnings: [] },
        publishDetails: '',
        exportFallback: '',
        library: { view: 'none', records: [], status: '', loadMore: false },
        shortcutsRev: 0,
    };
}

export const store = new Store<EditorState>(initialState());