@contentful/experience-design-system-cli 2.7.1-dev-build-02830eb.0 → 2.7.1
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/package.json +1 -1
- package/dist/src/analyze/select/tui/App.js +475 -54
- package/dist/src/analyze/select/tui/components/ComponentDetail.d.ts +5 -3
- package/dist/src/analyze/select/tui/components/ComponentDetail.js +3 -3
- package/dist/src/analyze/select/tui/components/FinalizeDialog.d.ts +1 -1
- package/dist/src/analyze/select/tui/components/FinalizeDialog.js +10 -2
- package/dist/src/analyze/select/tui/components/HelpOverlay.d.ts +1 -1
- package/dist/src/analyze/select/tui/components/HelpOverlay.js +7 -2
- package/dist/src/analyze/select/tui/components/JsonEditor.d.ts +5 -7
- package/dist/src/analyze/select/tui/components/JsonEditor.js +146 -15
- package/dist/src/analyze/select/tui/components/QuitDialog.d.ts +1 -1
- package/dist/src/analyze/select/tui/components/QuitDialog.js +10 -2
- package/dist/src/analyze/select/tui/components/Sidebar.d.ts +2 -0
- package/dist/src/analyze/select/tui/components/StatusBar.d.ts +2 -0
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.d.ts +0 -5
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +4 -7
- package/dist/src/analyze/select/tui/hooks/useKeymap.d.ts +23 -0
- package/dist/src/analyze/select/tui/hooks/useKeymap.js +67 -1
- package/dist/src/analyze/select/tui/hooks/useUndo.js +21 -15
- package/dist/src/analyze/tui/AnalyzeView.js +0 -2
- package/dist/src/import/tui/WizardApp.js +0 -2
- package/dist/src/import/tui/steps/GenerateReviewStep.js +11 -4
- package/dist/src/print/validate/tui/ValidateView.js +0 -2
- package/package.json +2 -2
- package/dist/src/analyze/select/tui/hooks/useRawMode.d.ts +0 -6
- package/dist/src/analyze/select/tui/hooks/useRawMode.js +0 -16
- package/dist/src/analyze/select/tui/hooks/useSideEffects.d.ts +0 -17
- package/dist/src/analyze/select/tui/hooks/useSideEffects.js +0 -226
- package/dist/src/analyze/select/tui/inputToAction.d.ts +0 -13
- package/dist/src/analyze/select/tui/inputToAction.js +0 -68
- package/dist/src/analyze/select/tui/state.d.ts +0 -136
- package/dist/src/analyze/select/tui/state.js +0 -385
- package/dist/src/analyze/select/tui/utils.d.ts +0 -5
- package/dist/src/analyze/select/tui/utils.js +0 -11
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useRef } from 'react';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import { openPipelineDb, storeRawComponents, loadCDFComponents } from '../../../../session/db.js';
|
|
4
|
-
import { ImportApiClient } from '../../../../apply/api-client.js';
|
|
5
|
-
import { readTokensFromPath } from '../../../../apply/manifest.js';
|
|
6
|
-
import { buildManifest } from '@contentful/experience-design-system-types';
|
|
7
|
-
/**
|
|
8
|
-
* All async side effects in one place.
|
|
9
|
-
* Detects transitions by comparing state to prevState — no pending* counter signals needed.
|
|
10
|
-
*/
|
|
11
|
-
export function useSideEffects(state, dispatch, services) {
|
|
12
|
-
const prevRef = useRef(state);
|
|
13
|
-
// Per-instance timer ref — avoids module-level state shared between test instances
|
|
14
|
-
const previewTimerRef = useRef(null);
|
|
15
|
-
// useLayoutEffect: fires synchronously after commit, before next render.
|
|
16
|
-
// This guarantees transitions are detected even if two renders fire in rapid
|
|
17
|
-
// succession — prevRef.current is updated before the next render reads it.
|
|
18
|
-
useLayoutEffect(() => {
|
|
19
|
-
const prev = prevRef.current;
|
|
20
|
-
prevRef.current = state;
|
|
21
|
-
// ── Session persistence: save whenever session components change ──────
|
|
22
|
-
if (state.session && state.paths && prev.session?.components !== state.session.components) {
|
|
23
|
-
void services.saveState(state.session);
|
|
24
|
-
}
|
|
25
|
-
// ── Draft persist: mode left editing (but not via discard — discard clears the draft) ──
|
|
26
|
-
if (prev.mode.type === 'editing' && state.mode.type !== 'editing') {
|
|
27
|
-
const { componentId } = prev.mode;
|
|
28
|
-
const draft = state.draftsByComponentId[componentId]; // undefined if discarded
|
|
29
|
-
if (draft && state.session && state.paths) {
|
|
30
|
-
void persistDraft(componentId, draft, state, dispatch, services);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// ── Finalize: mode just became finalized ──────────────────────────────
|
|
34
|
-
if (prev.mode.type !== 'finalized' && state.mode.type === 'finalized') {
|
|
35
|
-
if (state.session && state.paths) {
|
|
36
|
-
void persistFinalize(state, dispatch, services);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// ── Preview refresh: session components changed ───────────────────────
|
|
40
|
-
if (state.session?.components !== prev.session?.components && state.session) {
|
|
41
|
-
schedulePreviewRefresh(state, dispatch, services.sessionId, previewTimerRef);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
// ── Source code lazy loading ──────────────────────────────────────────────
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (!state.selectedId || !state.session)
|
|
47
|
-
return;
|
|
48
|
-
if (state.sourceCodeById[state.selectedId] !== undefined)
|
|
49
|
-
return;
|
|
50
|
-
const component = state.session.components.find((c) => c.id === state.selectedId);
|
|
51
|
-
if (!component)
|
|
52
|
-
return;
|
|
53
|
-
const id = state.selectedId;
|
|
54
|
-
readFile(component.resolvedSourcePath, 'utf8')
|
|
55
|
-
.then((code) => dispatch({ type: 'SOURCE_LOADED', componentId: id, code }))
|
|
56
|
-
.catch(() => dispatch({ type: 'SOURCE_LOADED', componentId: id, code: '' }));
|
|
57
|
-
}, [state.selectedId]);
|
|
58
|
-
// ── SIGINT ────────────────────────────────────────────────────────────────
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
const handler = () => {
|
|
61
|
-
if (Object.keys(state.draftsByComponentId).length > 0) {
|
|
62
|
-
dispatch({ type: 'OPEN_DIALOG', which: 'quit' });
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
process.on('SIGINT', handler);
|
|
69
|
-
return () => {
|
|
70
|
-
process.off('SIGINT', handler);
|
|
71
|
-
};
|
|
72
|
-
}, [state.draftsByComponentId]);
|
|
73
|
-
// ── Auto-clear errors ─────────────────────────────────────────────────────
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
if (!state.saveError)
|
|
76
|
-
return;
|
|
77
|
-
const t = setTimeout(() => dispatch({ type: 'CLEAR_ERRORS' }), 3000);
|
|
78
|
-
return () => clearTimeout(t);
|
|
79
|
-
}, [state.saveError]);
|
|
80
|
-
// ── Seed preview from env (non-live mode) ─────────────────────────────────
|
|
81
|
-
useEffect(() => {
|
|
82
|
-
if (!state.session || state.previewResponse)
|
|
83
|
-
return;
|
|
84
|
-
const raw = process.env['EDS_PREVIEW_COUNTS'];
|
|
85
|
-
if (!raw)
|
|
86
|
-
return;
|
|
87
|
-
try {
|
|
88
|
-
const counts = JSON.parse(raw);
|
|
89
|
-
const make = (n) => Array(n).fill({});
|
|
90
|
-
dispatch({
|
|
91
|
-
type: 'PREVIEW_SUCCESS',
|
|
92
|
-
response: {
|
|
93
|
-
components: {
|
|
94
|
-
new: make(counts.compNew ?? 0),
|
|
95
|
-
changed: make(counts.compChanged ?? 0),
|
|
96
|
-
removed: make(counts.compRemoved ?? 0),
|
|
97
|
-
unchanged: make(counts.compUnchanged ?? 0),
|
|
98
|
-
},
|
|
99
|
-
tokens: {
|
|
100
|
-
new: make(counts.tokNew ?? 0),
|
|
101
|
-
changed: make(counts.tokChanged ?? 0),
|
|
102
|
-
removed: make(counts.tokRemoved ?? 0),
|
|
103
|
-
unchanged: make(counts.tokUnchanged ?? 0),
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
annotations: {},
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch { }
|
|
110
|
-
}, [state.session]);
|
|
111
|
-
}
|
|
112
|
-
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
113
|
-
async function persistDraft(componentId, draft, state, dispatch, services) {
|
|
114
|
-
try {
|
|
115
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
116
|
-
const parsed = JSON.parse(draft);
|
|
117
|
-
const component = state.session.components.find((c) => c.id === componentId);
|
|
118
|
-
const currentStatus = component?.status;
|
|
119
|
-
const newStatus = currentStatus === 'needs-review' ? 'reviewed' : (currentStatus ?? 'reviewed');
|
|
120
|
-
const updatedComponents = state.session.components.map((c) => c.id === componentId ? { ...c, editedProposal: parsed, status: newStatus } : c);
|
|
121
|
-
await services.saveState({ ...state.session, components: updatedComponents });
|
|
122
|
-
await services.appendEvent({ type: 'draft_saved', payload: { componentId } });
|
|
123
|
-
const db = openPipelineDb();
|
|
124
|
-
try {
|
|
125
|
-
storeRawComponents(db, services.sessionId, updatedComponents.map((c) => c.editedProposal), {
|
|
126
|
-
status: 'generated',
|
|
127
|
-
preserveCDF: true,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
finally {
|
|
131
|
-
db.close();
|
|
132
|
-
}
|
|
133
|
-
dispatch({ type: 'DRAFT_PERSIST_DONE', componentId, updatedComponents });
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
dispatch({ type: 'DRAFT_PERSIST_DONE', componentId, updatedComponents: state.session.components });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async function persistFinalize(state, dispatch, services) {
|
|
140
|
-
if (state.mode.type !== 'finalized')
|
|
141
|
-
return;
|
|
142
|
-
const { accepted, rejected, excluded } = state.mode;
|
|
143
|
-
try {
|
|
144
|
-
await services.appendEvent({ type: 'finalized', payload: { accepted, rejected, excluded } });
|
|
145
|
-
const acceptedNames = new Set(state.session.components.filter((c) => c.status === 'accepted').map((c) => c.name));
|
|
146
|
-
const db = openPipelineDb();
|
|
147
|
-
try {
|
|
148
|
-
storeRawComponents(db, services.sessionId, state.session.components.map((c) => c.editedProposal), { status: 'extracted', preserveCDF: true });
|
|
149
|
-
if (acceptedNames.size > 0) {
|
|
150
|
-
db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${[...acceptedNames].map(() => '?').join(',')})`).run(services.sessionId, ...acceptedNames);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
finally {
|
|
154
|
-
db.close();
|
|
155
|
-
}
|
|
156
|
-
process.stdout.write(JSON.stringify({ status: 'finalized', sessionDir: state.paths.sessionDir, accepted, rejected, excluded }, null, 2) + '\n');
|
|
157
|
-
}
|
|
158
|
-
catch (err) {
|
|
159
|
-
dispatch({ type: 'SAVE_ERROR', message: String(err) });
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function schedulePreviewRefresh(state, dispatch, sessionId, timerRef) {
|
|
163
|
-
if (timerRef.current)
|
|
164
|
-
clearTimeout(timerRef.current);
|
|
165
|
-
timerRef.current = setTimeout(() => {
|
|
166
|
-
timerRef.current = null;
|
|
167
|
-
// Sync session to DB
|
|
168
|
-
const db = openPipelineDb();
|
|
169
|
-
try {
|
|
170
|
-
db.prepare(`UPDATE raw_components SET status = 'extracted' WHERE session_id = ?`).run(sessionId);
|
|
171
|
-
const acceptedNames = state
|
|
172
|
-
.session.components.filter((c) => c.status === 'accepted' || c.status === 'reviewed')
|
|
173
|
-
.map((c) => c.name);
|
|
174
|
-
if (acceptedNames.length > 0) {
|
|
175
|
-
db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${acceptedNames.map(() => '?').join(',')})`).run(sessionId, ...acceptedNames);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
finally {
|
|
179
|
-
db.close();
|
|
180
|
-
}
|
|
181
|
-
const cmaToken = process.env['EDS_CMA_TOKEN'];
|
|
182
|
-
const spaceId = process.env['EDS_SPACE_ID'];
|
|
183
|
-
const environmentId = process.env['EDS_ENVIRONMENT_ID'];
|
|
184
|
-
const tokensPath = process.env['EDS_TOKENS_PATH'];
|
|
185
|
-
if (!cmaToken || !spaceId || !environmentId)
|
|
186
|
-
return;
|
|
187
|
-
dispatch({ type: 'PREVIEW_START' });
|
|
188
|
-
void (async () => {
|
|
189
|
-
try {
|
|
190
|
-
const pdb = openPipelineDb();
|
|
191
|
-
let components = [];
|
|
192
|
-
try {
|
|
193
|
-
components = loadCDFComponents(pdb, sessionId);
|
|
194
|
-
}
|
|
195
|
-
finally {
|
|
196
|
-
pdb.close();
|
|
197
|
-
}
|
|
198
|
-
let tokens = [];
|
|
199
|
-
if (tokensPath)
|
|
200
|
-
tokens = await readTokensFromPath('tokens', tokensPath);
|
|
201
|
-
const manifest = buildManifest(components, tokens);
|
|
202
|
-
if (!manifest.componentsManifest)
|
|
203
|
-
manifest.componentsManifest = {};
|
|
204
|
-
const client = new ImportApiClient({ cmaToken, spaceId, environmentId });
|
|
205
|
-
const preview = await client.previewImport(manifest);
|
|
206
|
-
const annotations = {};
|
|
207
|
-
for (const item of preview.components.new) {
|
|
208
|
-
const name = item.name ?? '';
|
|
209
|
-
if (name)
|
|
210
|
-
annotations[name] = 'new';
|
|
211
|
-
}
|
|
212
|
-
for (const item of preview.components.removed)
|
|
213
|
-
annotations[item.name] = 'removed';
|
|
214
|
-
for (const item of preview.components.changed) {
|
|
215
|
-
annotations[item.current.name] =
|
|
216
|
-
item.changeClassification?.classification === 'breaking' ? 'breaking' : 'changed';
|
|
217
|
-
}
|
|
218
|
-
dispatch({ type: 'PREVIEW_SUCCESS', response: preview, annotations });
|
|
219
|
-
}
|
|
220
|
-
catch (err) {
|
|
221
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
222
|
-
dispatch({ type: 'PREVIEW_ERROR', message: msg.includes('token') ? 'Preview request failed' : msg });
|
|
223
|
-
}
|
|
224
|
-
})();
|
|
225
|
-
}, 500);
|
|
226
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { AppAction, AppState, applyEditorKey } from './state.js';
|
|
2
|
-
export type Key = Parameters<typeof applyEditorKey>[2] & {
|
|
3
|
-
tab: boolean;
|
|
4
|
-
pageUp: boolean;
|
|
5
|
-
pageDown: boolean;
|
|
6
|
-
shift: boolean;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Pure function: maps a keypress to an AppAction (or null).
|
|
10
|
-
* No hooks. No closures over stale React state.
|
|
11
|
-
* Branching is on mode — the committed state from the reducer.
|
|
12
|
-
*/
|
|
13
|
-
export declare function inputToAction(input: string, key: Key, state: AppState, visibleCount: number, terminalWidth: number): AppAction | null;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure function: maps a keypress to an AppAction (or null).
|
|
3
|
-
* No hooks. No closures over stale React state.
|
|
4
|
-
* Branching is on mode — the committed state from the reducer.
|
|
5
|
-
*/
|
|
6
|
-
export function inputToAction(input, key, state, visibleCount, terminalWidth) {
|
|
7
|
-
const { mode } = state;
|
|
8
|
-
// ── Dialog ────────────────────────────────────────────────────────────────
|
|
9
|
-
if (mode.type === 'dialog') {
|
|
10
|
-
if (input === 'y' || key.return) {
|
|
11
|
-
if (mode.which === 'finalize')
|
|
12
|
-
return { type: 'FINALIZE_CONFIRM' };
|
|
13
|
-
if (mode.which === 'quit')
|
|
14
|
-
return { type: 'QUIT_CONFIRM' };
|
|
15
|
-
return { type: 'CLOSE_DIALOG' };
|
|
16
|
-
}
|
|
17
|
-
if (input === 'n' || key.escape)
|
|
18
|
-
return { type: 'CLOSE_DIALOG' };
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
// ── Editing ───────────────────────────────────────────────────────────────
|
|
22
|
-
if (mode.type === 'editing') {
|
|
23
|
-
if (key.ctrl && input === 's')
|
|
24
|
-
return { type: 'EDITOR_VALIDATE' };
|
|
25
|
-
if (key.escape)
|
|
26
|
-
return { type: 'DRAFT_DISCARD' };
|
|
27
|
-
// All other keys go to the editor
|
|
28
|
-
return { type: 'EDITOR_KEY', input, key, visibleHeight: visibleCount - 4 };
|
|
29
|
-
}
|
|
30
|
-
// ── Finalized ─────────────────────────────────────────────────────────────
|
|
31
|
-
if (mode.type === 'finalized') {
|
|
32
|
-
if (key.return || input === 'q' || key.escape)
|
|
33
|
-
process.exit(0);
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
// ── Browsing ──────────────────────────────────────────────────────────────
|
|
37
|
-
if (input === 'q')
|
|
38
|
-
return { type: 'OPEN_DIALOG', which: 'quit' };
|
|
39
|
-
if (input === '?')
|
|
40
|
-
return { type: 'OPEN_DIALOG', which: 'help' };
|
|
41
|
-
if (input === 'F')
|
|
42
|
-
return { type: 'OPEN_DIALOG', which: 'finalize' };
|
|
43
|
-
if (key.tab)
|
|
44
|
-
return { type: 'TOGGLE_FOCUS' };
|
|
45
|
-
if (input === 'a')
|
|
46
|
-
return { type: 'ACCEPT' };
|
|
47
|
-
if (input === 'r')
|
|
48
|
-
return { type: 'REJECT' };
|
|
49
|
-
if (input === 'e')
|
|
50
|
-
return { type: 'ENTER_EDIT' };
|
|
51
|
-
if (input === 's')
|
|
52
|
-
return { type: 'TOGGLE_SOURCE', terminalWidth };
|
|
53
|
-
if (input === 'A')
|
|
54
|
-
return { type: 'APPROVE_ALL' };
|
|
55
|
-
if (mode.sidebarFocused) {
|
|
56
|
-
if (key.upArrow || input === 'k')
|
|
57
|
-
return { type: 'SIDEBAR_UP', visibleCount };
|
|
58
|
-
if (key.downArrow || input === 'j')
|
|
59
|
-
return { type: 'SIDEBAR_DOWN', visibleCount };
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
if (key.upArrow || input === 'k')
|
|
63
|
-
return { type: 'SCROLL_UP' };
|
|
64
|
-
if (key.downArrow || input === 'j')
|
|
65
|
-
return { type: 'SCROLL_DOWN' };
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type { PreviewAnnotation, ReviewComponentRecord, ReviewComponentSummary, ReviewSessionSnapshot } from '../types.js';
|
|
2
|
-
import type { ServerPreviewResponse } from '@contentful/experience-design-system-types';
|
|
3
|
-
export type AppMode = {
|
|
4
|
-
type: 'browsing';
|
|
5
|
-
sidebarFocused: boolean;
|
|
6
|
-
sourceVisible: boolean;
|
|
7
|
-
} | {
|
|
8
|
-
type: 'editing';
|
|
9
|
-
componentId: string;
|
|
10
|
-
} | {
|
|
11
|
-
type: 'dialog';
|
|
12
|
-
which: 'help' | 'finalize' | 'quit';
|
|
13
|
-
} | {
|
|
14
|
-
type: 'finalized';
|
|
15
|
-
accepted: number;
|
|
16
|
-
rejected: number;
|
|
17
|
-
excluded: number;
|
|
18
|
-
};
|
|
19
|
-
export type EditorCursor = {
|
|
20
|
-
lines: string[];
|
|
21
|
-
cursorRow: number;
|
|
22
|
-
cursorCol: number;
|
|
23
|
-
};
|
|
24
|
-
export type EditorState = {
|
|
25
|
-
cursor: EditorCursor;
|
|
26
|
-
undoStack: EditorCursor[];
|
|
27
|
-
scrollRow: number;
|
|
28
|
-
validationError: string | null;
|
|
29
|
-
};
|
|
30
|
-
export declare function applyEditorKey(e: EditorState, input: string, key: {
|
|
31
|
-
ctrl: boolean;
|
|
32
|
-
meta: boolean;
|
|
33
|
-
return: boolean;
|
|
34
|
-
backspace: boolean;
|
|
35
|
-
delete: boolean;
|
|
36
|
-
escape: boolean;
|
|
37
|
-
upArrow: boolean;
|
|
38
|
-
downArrow: boolean;
|
|
39
|
-
leftArrow: boolean;
|
|
40
|
-
rightArrow: boolean;
|
|
41
|
-
}, visibleHeight: number): EditorState | null;
|
|
42
|
-
export type AppState = {
|
|
43
|
-
mode: AppMode;
|
|
44
|
-
session: ReviewSessionSnapshot | null;
|
|
45
|
-
paths: {
|
|
46
|
-
sessionDir: string;
|
|
47
|
-
statePath: string;
|
|
48
|
-
eventsPath: string;
|
|
49
|
-
} | null;
|
|
50
|
-
selectedId: string | null;
|
|
51
|
-
sortedIds: string[];
|
|
52
|
-
sessionSummary: ReviewComponentSummary[];
|
|
53
|
-
sidebarScrollOffset: number;
|
|
54
|
-
jsonScrollOffset: number;
|
|
55
|
-
draftsByComponentId: Record<string, string>;
|
|
56
|
-
editor: EditorState | null;
|
|
57
|
-
sourceCodeById: Record<string, string>;
|
|
58
|
-
previewAnnotations: Record<string, PreviewAnnotation>;
|
|
59
|
-
previewResponse: ServerPreviewResponse | null;
|
|
60
|
-
previewLoading: boolean;
|
|
61
|
-
previewError: string | null;
|
|
62
|
-
saveError: string | null;
|
|
63
|
-
};
|
|
64
|
-
export declare const initialState: AppState;
|
|
65
|
-
export type AppAction = {
|
|
66
|
-
type: 'SESSION_LOADED';
|
|
67
|
-
session: ReviewSessionSnapshot;
|
|
68
|
-
paths: AppState['paths'];
|
|
69
|
-
} | {
|
|
70
|
-
type: 'SELECT';
|
|
71
|
-
id: string;
|
|
72
|
-
} | {
|
|
73
|
-
type: 'SIDEBAR_UP';
|
|
74
|
-
visibleCount: number;
|
|
75
|
-
} | {
|
|
76
|
-
type: 'SIDEBAR_DOWN';
|
|
77
|
-
visibleCount: number;
|
|
78
|
-
} | {
|
|
79
|
-
type: 'ACCEPT';
|
|
80
|
-
} | {
|
|
81
|
-
type: 'REJECT';
|
|
82
|
-
} | {
|
|
83
|
-
type: 'APPROVE_ALL';
|
|
84
|
-
} | {
|
|
85
|
-
type: 'ENTER_EDIT';
|
|
86
|
-
} | {
|
|
87
|
-
type: 'EDITOR_KEY';
|
|
88
|
-
input: string;
|
|
89
|
-
key: Parameters<typeof applyEditorKey>[2];
|
|
90
|
-
visibleHeight: number;
|
|
91
|
-
} | {
|
|
92
|
-
type: 'EDITOR_VALIDATE';
|
|
93
|
-
} | {
|
|
94
|
-
type: 'DRAFT_DISCARD';
|
|
95
|
-
} | {
|
|
96
|
-
type: 'TOGGLE_FOCUS';
|
|
97
|
-
} | {
|
|
98
|
-
type: 'SCROLL_UP';
|
|
99
|
-
} | {
|
|
100
|
-
type: 'SCROLL_DOWN';
|
|
101
|
-
} | {
|
|
102
|
-
type: 'TOGGLE_SOURCE';
|
|
103
|
-
terminalWidth: number;
|
|
104
|
-
} | {
|
|
105
|
-
type: 'OPEN_DIALOG';
|
|
106
|
-
which: 'help' | 'finalize' | 'quit';
|
|
107
|
-
} | {
|
|
108
|
-
type: 'CLOSE_DIALOG';
|
|
109
|
-
} | {
|
|
110
|
-
type: 'FINALIZE_CONFIRM';
|
|
111
|
-
} | {
|
|
112
|
-
type: 'QUIT_CONFIRM';
|
|
113
|
-
} | {
|
|
114
|
-
type: 'SOURCE_LOADED';
|
|
115
|
-
componentId: string;
|
|
116
|
-
code: string;
|
|
117
|
-
} | {
|
|
118
|
-
type: 'PREVIEW_START';
|
|
119
|
-
} | {
|
|
120
|
-
type: 'PREVIEW_SUCCESS';
|
|
121
|
-
response: ServerPreviewResponse;
|
|
122
|
-
annotations: Record<string, PreviewAnnotation>;
|
|
123
|
-
} | {
|
|
124
|
-
type: 'PREVIEW_ERROR';
|
|
125
|
-
message: string;
|
|
126
|
-
} | {
|
|
127
|
-
type: 'SAVE_ERROR';
|
|
128
|
-
message: string;
|
|
129
|
-
} | {
|
|
130
|
-
type: 'CLEAR_ERRORS';
|
|
131
|
-
} | {
|
|
132
|
-
type: 'DRAFT_PERSIST_DONE';
|
|
133
|
-
componentId: string;
|
|
134
|
-
updatedComponents: ReviewComponentRecord[];
|
|
135
|
-
};
|
|
136
|
-
export declare function reducer(state: AppState, action: AppAction): AppState;
|