@devcabs/folio-engine 0.0.0-stage → 0.1.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/App.d.ts +7 -0
- package/dist/components/canvas/CanvasAddBar.d.ts +28 -0
- package/dist/components/canvas/CanvasAddModal.d.ts +38 -0
- package/dist/components/canvas/CanvasChart.d.ts +23 -0
- package/dist/components/canvas/CanvasDeleteConfirmModal.d.ts +21 -0
- package/dist/components/canvas/CanvasGallery.d.ts +20 -0
- package/dist/components/canvas/CanvasItemControls.d.ts +33 -0
- package/dist/components/canvas/CanvasPhoto.d.ts +28 -0
- package/dist/components/canvas/CanvasSection.d.ts +27 -0
- package/dist/components/canvas/CanvasSubsection.d.ts +23 -0
- package/dist/components/canvas/CanvasText.d.ts +23 -0
- package/dist/components/canvas/DocumentCanvas.d.ts +20 -0
- package/dist/components/canvas/HeroPhoto.d.ts +17 -0
- package/dist/components/canvas/NodeCanvas.d.ts +2 -0
- package/dist/components/canvas/index.d.ts +17 -0
- package/dist/components/chart/BarChart.d.ts +23 -0
- package/dist/components/chart/ChartCard.d.ts +33 -0
- package/dist/components/chart/ChartConfigDrawer.d.ts +16 -0
- package/dist/components/chart/ChartGhostWireframe.d.ts +16 -0
- package/dist/components/chart/ChartLegend.d.ts +14 -0
- package/dist/components/chart/ChartRouter.d.ts +8 -0
- package/dist/components/chart/ChartSortingControls.d.ts +15 -0
- package/dist/components/chart/ChartTableModal.d.ts +26 -0
- package/dist/components/chart/ChartTooltip.d.ts +12 -0
- package/dist/components/chart/DataPendingCard.d.ts +28 -0
- package/dist/components/chart/DonutChart.d.ts +16 -0
- package/dist/components/chart/HistogramChart.d.ts +23 -0
- package/dist/components/chart/LineChart.d.ts +22 -0
- package/dist/components/chart/RangePreviewMatrix.d.ts +19 -0
- package/dist/components/chart/ScatterPlot.d.ts +21 -0
- package/dist/components/chart/drawer/controls/BarVisualControls.d.ts +9 -0
- package/dist/components/chart/drawer/controls/ChartTitlesSection.d.ts +15 -0
- package/dist/components/chart/drawer/controls/DonutVisualControls.d.ts +7 -0
- package/dist/components/chart/drawer/controls/HistogramVisualControls.d.ts +13 -0
- package/dist/components/chart/drawer/controls/LineVisualControls.d.ts +14 -0
- package/dist/components/chart/drawer/controls/ScatterDataControls.d.ts +17 -0
- package/dist/components/chart/drawer/controls/ScatterVisualControls.d.ts +23 -0
- package/dist/components/chart/drawer/controls/SortingAndOrderControls.d.ts +18 -0
- package/dist/components/chart/drawer/controls/StandardDataControls.d.ts +31 -0
- package/dist/components/chart/drawer/hooks/useChartConfigForm.d.ts +156 -0
- package/dist/components/chart/drawer/hooks/useLiveMatrixSync.d.ts +21 -0
- package/dist/components/chart/drawer/hooks/useSheetVerification.d.ts +26 -0
- package/dist/components/chart/drawer/index.d.ts +17 -0
- package/dist/components/chart/drawer/panels/Step1Source.d.ts +18 -0
- package/dist/components/chart/drawer/panels/Step1SourceRange.d.ts +32 -0
- package/dist/components/chart/drawer/panels/Step2DataRange.d.ts +15 -0
- package/dist/components/chart/drawer/panels/Step3ChartSetup.d.ts +17 -0
- package/dist/components/chart/drawer/panels/Step4Review.d.ts +11 -0
- package/dist/components/chart/index.d.ts +22 -0
- package/dist/components/dev/DevActionAffordance.d.ts +4 -0
- package/dist/components/dev/DevExitConfirmModal.d.ts +14 -0
- package/dist/components/dev/DevLockBlockedModal.d.ts +3 -0
- package/dist/components/dev/DevModeBadge.d.ts +3 -0
- package/dist/components/dev/DevPinModal.d.ts +3 -0
- package/dist/components/dev/DevPublishModal.d.ts +9 -0
- package/dist/components/dev/UniversalEditModal.d.ts +40 -0
- package/dist/components/dev/index.d.ts +8 -0
- package/dist/components/feedback/EmptyState.d.ts +13 -0
- package/dist/components/feedback/PageNotFound.d.ts +15 -0
- package/dist/components/feedback/Toast.d.ts +25 -0
- package/dist/components/feedback/index.d.ts +2 -0
- package/dist/components/history/HistoryHubModal.d.ts +44 -0
- package/dist/components/history/index.d.ts +1 -0
- package/dist/components/layout/AppFooter.d.ts +10 -0
- package/dist/components/layout/AppHeader.d.ts +22 -0
- package/dist/components/layout/EditorialSection.d.ts +27 -0
- package/dist/components/layout/EditorialSidebar.d.ts +34 -0
- package/dist/components/layout/HeroSection.d.ts +2 -0
- package/dist/components/layout/HeroWelcome.d.ts +11 -0
- package/dist/components/layout/SearchField.d.ts +9 -0
- package/dist/components/layout/StatusPill.d.ts +2 -0
- package/dist/components/layout/index.d.ts +8 -0
- package/dist/components/roadmap/RoadmapNode.d.ts +30 -0
- package/dist/components/roadmap/RoadmapSection.d.ts +27 -0
- package/dist/components/roadmap/RoadmapTrack.d.ts +25 -0
- package/dist/components/roadmap/serpentine-generator.d.ts +60 -0
- package/dist/components/roadmap/use-roadmap-scroll.d.ts +19 -0
- package/dist/components/source/EditPhotoModal.d.ts +22 -0
- package/dist/components/source/LightboxPhotoStrip.d.ts +23 -0
- package/dist/components/source/LinkFolderModal.d.ts +24 -0
- package/dist/components/source/SourceCard.d.ts +31 -0
- package/dist/components/source/SourceFolderAttachment.d.ts +25 -0
- package/dist/components/source/SourceGallery.d.ts +26 -0
- package/dist/components/source/SourceImage.d.ts +26 -0
- package/dist/components/source/SourceLightbox.d.ts +28 -0
- package/dist/components/source/index.d.ts +9 -0
- package/dist/components/ui/AccordionSection.d.ts +21 -0
- package/dist/components/ui/Breadcrumb.d.ts +29 -0
- package/dist/components/ui/Button.d.ts +31 -0
- package/dist/components/ui/ColumnSelect.d.ts +17 -0
- package/dist/components/ui/ColumnTypeBadge.d.ts +6 -0
- package/dist/components/ui/DevHelpTooltip.d.ts +11 -0
- package/dist/components/ui/DraggableRows.d.ts +21 -0
- package/dist/components/ui/Drawer.d.ts +50 -0
- package/dist/components/ui/DrawerTier.d.ts +8 -0
- package/dist/components/ui/EditableText.d.ts +48 -0
- package/dist/components/ui/FAB.d.ts +24 -0
- package/dist/components/ui/Modal.d.ts +24 -0
- package/dist/components/ui/PageTitle.d.ts +33 -0
- package/dist/components/ui/ParametricShape.d.ts +57 -0
- package/dist/components/ui/RevolvingButton.d.ts +5 -0
- package/dist/components/ui/SectionTitle.d.ts +42 -0
- package/dist/components/ui/SeriesSelectToolbar.d.ts +10 -0
- package/dist/components/ui/StatusPill.d.ts +21 -0
- package/dist/components/ui/TieredSlider.d.ts +19 -0
- package/dist/components/ui/Toast.d.ts +1 -0
- package/dist/components/ui/ValueLabelToggle.d.ts +10 -0
- package/dist/components/ui/index.d.ts +21 -0
- package/dist/config/engine.config.d.ts +162 -0
- package/dist/context/DeveloperModeContext.d.ts +11 -0
- package/dist/context/UndoRedoContext.d.ts +20 -0
- package/dist/diagnostics/verifyEngineSetup.d.ts +30 -0
- package/dist/diagnostics-CpGr1hhi.js +126 -0
- package/dist/diagnostics-Dw5PzR78.cjs +5 -0
- package/dist/diagnostics.cjs +1 -0
- package/dist/diagnostics.d.ts +10 -0
- package/dist/diagnostics.js +14 -0
- package/dist/edge-1WCVZ0J7.cjs +1 -0
- package/dist/edge-CSjifIhA.js +2709 -0
- package/dist/edge-Dr41JdrQ.cjs +34 -0
- package/dist/edge-h_ge9f1E.js +512 -0
- package/dist/edge.cjs +1 -0
- package/dist/edge.d.ts +10 -0
- package/dist/edge.js +26 -0
- package/dist/folio.cjs +9 -0
- package/dist/folio.js +21895 -0
- package/dist/hooks/use-auto-toc.d.ts +31 -0
- package/dist/hooks/use-discrete-step-navigation.d.ts +26 -0
- package/dist/hooks/use-dynamic-section-numbers.d.ts +30 -0
- package/dist/hooks/use-hash-route.d.ts +36 -0
- package/dist/hooks/use-scroll.d.ts +22 -0
- package/dist/hooks/use-scrollspy.d.ts +19 -0
- package/dist/hooks/useChartTooltip.d.ts +25 -0
- package/dist/hooks/useContent.d.ts +36 -0
- package/dist/hooks/useDeveloperMode.d.ts +1 -0
- package/dist/hooks/useDocumentCanvas.d.ts +53 -0
- package/dist/hooks/useDrivePhotoSync.d.ts +15 -0
- package/dist/hooks/useImageLoader.d.ts +12 -0
- package/dist/hooks/useLightboxHistory.d.ts +14 -0
- package/dist/hooks/useNodeCanvas.d.ts +2 -0
- package/dist/hooks/useSheetChartData.d.ts +31 -0
- package/dist/hooks/useSourcePoint.d.ts +35 -0
- package/dist/hooks/useSwipeGesture.d.ts +30 -0
- package/dist/hooks/useUndoRedo.d.ts +9 -0
- package/dist/hooks/useUnsavedChangesPrompt.d.ts +18 -0
- package/dist/index.d.ts +53 -0
- package/dist/main.d.ts +1 -0
- package/dist/services/canvasLayoutService.d.ts +158 -0
- package/dist/services/chartSourceService.d.ts +128 -0
- package/dist/services/devLockService.d.ts +76 -0
- package/dist/services/draftService.d.ts +129 -0
- package/dist/services/drivePhotoSyncService.d.ts +60 -0
- package/dist/services/driveVerificationService.d.ts +41 -0
- package/dist/services/edgePreBakeService.d.ts +81 -0
- package/dist/services/historyService.d.ts +215 -0
- package/dist/services/historyStorage.d.ts +17 -0
- package/dist/services/mediaService.d.ts +25 -0
- package/dist/services/sheetsDataService.d.ts +59 -0
- package/dist/services/sheetsVerificationService.d.ts +87 -0
- package/dist/services/sourceService.d.ts +43 -0
- package/dist/services/undoRedoService.d.ts +63 -0
- package/dist/services/unsavedChangesService.d.ts +32 -0
- package/dist/style.css +1 -0
- package/dist/types/canvas.d.ts +115 -0
- package/dist/types/chart.d.ts +117 -0
- package/dist/types/developer.d.ts +144 -0
- package/dist/types/draft.d.ts +21 -0
- package/dist/types/edge.d.ts +232 -0
- package/dist/types/history.d.ts +81 -0
- package/dist/types/media.d.ts +16 -0
- package/dist/types/navigation.d.ts +19 -0
- package/dist/types/node.d.ts +51 -0
- package/dist/types/source.d.ts +88 -0
- package/dist/utils/canvasDefaults.d.ts +43 -0
- package/dist/utils/chartColors.d.ts +48 -0
- package/dist/utils/chartDimensions.d.ts +50 -0
- package/dist/utils/chartMath.d.ts +142 -0
- package/dist/utils/chartSanitizer.d.ts +84 -0
- package/dist/utils/contentDb.d.ts +86 -0
- package/dist/utils/devSecurity.d.ts +84 -0
- package/dist/utils/mediaUrl.d.ts +32 -0
- package/dist/utils/modalActions.d.ts +32 -0
- package/dist/utils/node-sections.d.ts +15 -0
- package/dist/utils/page-sections.d.ts +1 -0
- package/dist/utils/runtime-env.d.ts +21 -0
- package/dist/utils/scrollLock.d.ts +10 -0
- package/dist/utils/smooth-scroll.d.ts +24 -0
- package/dist/utils/source.d.ts +25 -0
- package/dist/utils/storage.d.ts +13 -0
- package/dist/utils/supabase-config.d.ts +29 -0
- package/dist/utils/supabase-write-guard.d.ts +15 -0
- package/package.json +68 -4
- package/README.md +0 -3
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Folio Engine - Dynamic Canvas Type Definitions
|
|
3
|
+
* Location: src/types/canvas.ts
|
|
4
|
+
* Specification: docs/tasks/task8_1_data_models_and_default_factory.md
|
|
5
|
+
*/
|
|
6
|
+
export type CanvasElementType = 'section' | 'subsection' | 'text' | 'photo' | 'gallery' | 'chart';
|
|
7
|
+
export interface CanvasElementBase {
|
|
8
|
+
id: string;
|
|
9
|
+
type: CanvasElementType;
|
|
10
|
+
}
|
|
11
|
+
export interface TextElement extends CanvasElementBase {
|
|
12
|
+
type: 'text';
|
|
13
|
+
pointId: string;
|
|
14
|
+
content: string;
|
|
15
|
+
as?: 'p' | 'blockquote';
|
|
16
|
+
}
|
|
17
|
+
export interface PhotoElement extends CanvasElementBase {
|
|
18
|
+
type: 'photo';
|
|
19
|
+
pointId: string;
|
|
20
|
+
src?: string;
|
|
21
|
+
/** Responsive image candidate string pre-baked for edge proxy delivery */
|
|
22
|
+
srcSet?: string;
|
|
23
|
+
/** Responsive sizes media query string */
|
|
24
|
+
sizes?: string;
|
|
25
|
+
/** Aspect ratio hint (e.g. "16/9", "4/3") */
|
|
26
|
+
aspectRatio?: string;
|
|
27
|
+
/** Original raw Drive URL preserved for fallback resilience */
|
|
28
|
+
rawDriveUrl?: string;
|
|
29
|
+
alt?: string;
|
|
30
|
+
caption?: string;
|
|
31
|
+
/** Optional Google Drive folder or item link */
|
|
32
|
+
driveUrl?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface GalleryElement extends CanvasElementBase {
|
|
35
|
+
type: 'gallery';
|
|
36
|
+
pointId: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
titlePointId?: string;
|
|
39
|
+
subtitle?: string;
|
|
40
|
+
subtitlePointId?: string;
|
|
41
|
+
driveUrl?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ChartElement extends CanvasElementBase {
|
|
44
|
+
type: 'chart';
|
|
45
|
+
chartId: string;
|
|
46
|
+
title: string;
|
|
47
|
+
subtitle?: string;
|
|
48
|
+
}
|
|
49
|
+
export type CanvasLeafElement = TextElement | PhotoElement | GalleryElement | ChartElement;
|
|
50
|
+
export interface SubsectionElement extends CanvasElementBase {
|
|
51
|
+
type: 'subsection';
|
|
52
|
+
title: string;
|
|
53
|
+
titlePointId?: string;
|
|
54
|
+
subtitle?: string;
|
|
55
|
+
subtitlePointId?: string;
|
|
56
|
+
/** Leaf content items within this subsection */
|
|
57
|
+
elements: CanvasLeafElement[];
|
|
58
|
+
}
|
|
59
|
+
export type CanvasChildElement = SubsectionElement | CanvasLeafElement;
|
|
60
|
+
export interface SectionElement extends CanvasElementBase {
|
|
61
|
+
type: 'section';
|
|
62
|
+
/** Two-digit sequential display number, e.g. "01", "02" */
|
|
63
|
+
number?: string;
|
|
64
|
+
/** Whether the section displays a sequential number badge */
|
|
65
|
+
isNumbered?: boolean;
|
|
66
|
+
title: string;
|
|
67
|
+
titlePointId?: string;
|
|
68
|
+
subtitle?: string;
|
|
69
|
+
subtitlePointId?: string;
|
|
70
|
+
/** Child elements and subsections contained within this section */
|
|
71
|
+
elements: CanvasChildElement[];
|
|
72
|
+
}
|
|
73
|
+
export type CanvasElement = SectionElement | CanvasChildElement;
|
|
74
|
+
export interface NodeCanvasDocument {
|
|
75
|
+
nodeId: string;
|
|
76
|
+
version: number;
|
|
77
|
+
sections: SectionElement[];
|
|
78
|
+
updatedAt: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Type Guards for Canvas Elements
|
|
82
|
+
*/
|
|
83
|
+
export declare function isSectionElement(el: CanvasElement): el is SectionElement;
|
|
84
|
+
export declare function isSubsectionElement(el: CanvasElement): el is SubsectionElement;
|
|
85
|
+
export declare function isLeafElement(el: CanvasElement): el is CanvasLeafElement;
|
|
86
|
+
export declare function isTextElement(el: CanvasElement): el is TextElement;
|
|
87
|
+
export declare function isPhotoElement(el: CanvasElement): el is PhotoElement;
|
|
88
|
+
export declare function isGalleryElement(el: CanvasElement): el is GalleryElement;
|
|
89
|
+
export declare function isChartElement(el: CanvasElement): el is ChartElement;
|
|
90
|
+
/**
|
|
91
|
+
* Unified Canvas Add & Edit Modal Contracts
|
|
92
|
+
* Aligned with docs/tasks/task9_8_unified_canvas_add_edit_modal_drawer.md
|
|
93
|
+
*/
|
|
94
|
+
export type CanvasModalMode = 'add' | 'edit';
|
|
95
|
+
export type CanvasModalElementType = 'section' | 'subsection' | 'text' | 'photo' | 'gallery';
|
|
96
|
+
export interface CanvasElementFormData {
|
|
97
|
+
/** For section, subsection, gallery, or text title */
|
|
98
|
+
title?: string;
|
|
99
|
+
/** For section numbering */
|
|
100
|
+
isNumbered?: boolean;
|
|
101
|
+
/** For narrative text content */
|
|
102
|
+
content?: string;
|
|
103
|
+
/** For text typography style */
|
|
104
|
+
as?: 'p' | 'blockquote';
|
|
105
|
+
/** For photo image source (data URL or external URL) */
|
|
106
|
+
src?: string;
|
|
107
|
+
/** For photo image accessibility description */
|
|
108
|
+
alt?: string;
|
|
109
|
+
/** For photo image caption */
|
|
110
|
+
caption?: string;
|
|
111
|
+
/** Whether photo caption is visible below image */
|
|
112
|
+
showCaption?: boolean;
|
|
113
|
+
/** For photo or gallery Google Drive folder URL */
|
|
114
|
+
driveUrl?: string;
|
|
115
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart Contracts & TypeScript Data Models
|
|
3
|
+
* Document Reference: docs/tasks/task7_1_contracts_d3_math_sanitizer.md & docs/04_DATA_MODELS.md
|
|
4
|
+
*
|
|
5
|
+
* Strict contracts for the host application Data Charts.
|
|
6
|
+
* Supports Bar, Line, Donut, Scatter, and Histogram charts with number purity and zero URL leaks.
|
|
7
|
+
*/
|
|
8
|
+
import type { NodeCode } from './node';
|
|
9
|
+
export type ChartType = 'bar' | 'line' | 'donut' | 'scatter' | 'histogram' | 'auto';
|
|
10
|
+
export interface ChartSeries {
|
|
11
|
+
name: string;
|
|
12
|
+
data: (number | null)[];
|
|
13
|
+
color?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ScatterPoint {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
label?: string;
|
|
19
|
+
group?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface HistogramBin {
|
|
22
|
+
x0: number;
|
|
23
|
+
x1: number;
|
|
24
|
+
count: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Contextual visual configuration parameters editable via the Sidebar Drawer
|
|
28
|
+
*/
|
|
29
|
+
export interface ChartVisualConfig {
|
|
30
|
+
xMin?: number;
|
|
31
|
+
xMax?: number;
|
|
32
|
+
yMin?: number;
|
|
33
|
+
yMax?: number;
|
|
34
|
+
xLabel?: string;
|
|
35
|
+
yLabel?: string;
|
|
36
|
+
unit?: string;
|
|
37
|
+
tabName?: string;
|
|
38
|
+
sheetGid?: string;
|
|
39
|
+
range?: string;
|
|
40
|
+
excludeSummaryRows?: boolean;
|
|
41
|
+
transpose?: boolean;
|
|
42
|
+
binStrategy?: 'auto' | 'custom';
|
|
43
|
+
binCount?: number;
|
|
44
|
+
bucketSize?: number;
|
|
45
|
+
histogramYMode?: 'frequency' | 'relative';
|
|
46
|
+
showSummaryStats?: boolean;
|
|
47
|
+
showMedianMode?: boolean;
|
|
48
|
+
showReferenceGuide?: boolean;
|
|
49
|
+
barVariant?: 'standard' | 'progress';
|
|
50
|
+
targetValue?: number;
|
|
51
|
+
targetLabel?: string;
|
|
52
|
+
categoryColIndex?: number;
|
|
53
|
+
includedSeriesIndices?: number[];
|
|
54
|
+
sortBy?: 'none' | 'asc' | 'desc' | 'category-asc' | 'category-desc';
|
|
55
|
+
sortField?: string;
|
|
56
|
+
sortDirection?: 'asc' | 'desc';
|
|
57
|
+
orientation?: 'vertical' | 'horizontal';
|
|
58
|
+
barOrientation?: 'vertical' | 'horizontal';
|
|
59
|
+
stacked?: boolean;
|
|
60
|
+
showValues?: boolean;
|
|
61
|
+
autoScaleY?: boolean;
|
|
62
|
+
autoScaleX?: boolean;
|
|
63
|
+
startAtZero?: boolean;
|
|
64
|
+
startAtZeroX?: boolean;
|
|
65
|
+
curveInterpolation?: 'smooth' | 'straight' | 'none' | 'linear' | 'polynomial';
|
|
66
|
+
loessBandwidth?: number;
|
|
67
|
+
showAreaFill?: boolean;
|
|
68
|
+
markerSize?: 'compact' | 'regular' | 'prominent';
|
|
69
|
+
scatterXColIndex?: number;
|
|
70
|
+
scatterYColIndex?: number;
|
|
71
|
+
scatterLabelColIndex?: number;
|
|
72
|
+
scatterGroupColIndex?: number;
|
|
73
|
+
showCorrelationChip?: boolean;
|
|
74
|
+
donutVariant?: 'donut' | 'pie';
|
|
75
|
+
groupOthers?: boolean;
|
|
76
|
+
lastModifiedTime?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface ChartDataset {
|
|
79
|
+
chartId: string;
|
|
80
|
+
title: string;
|
|
81
|
+
subtitle?: string;
|
|
82
|
+
unit?: string;
|
|
83
|
+
asOfDate: string;
|
|
84
|
+
chartType: ChartType;
|
|
85
|
+
nodeId?: NodeCode;
|
|
86
|
+
visualConfig?: ChartVisualConfig;
|
|
87
|
+
categories?: string[];
|
|
88
|
+
series?: ChartSeries[];
|
|
89
|
+
scatterPoints?: ScatterPoint[];
|
|
90
|
+
rawValues?: (number | null)[];
|
|
91
|
+
bins?: HistogramBin[];
|
|
92
|
+
sanitizedCsvContent: string;
|
|
93
|
+
}
|
|
94
|
+
export interface SheetChartConfig {
|
|
95
|
+
chartId: string;
|
|
96
|
+
sheetUrl: string;
|
|
97
|
+
tabName?: string;
|
|
98
|
+
sheetGid?: string;
|
|
99
|
+
range?: string;
|
|
100
|
+
defaultType?: ChartType;
|
|
101
|
+
titleOverride?: string;
|
|
102
|
+
subtitleOverride?: string;
|
|
103
|
+
unitOverride?: string;
|
|
104
|
+
nodeId: NodeCode;
|
|
105
|
+
visualConfig?: ChartVisualConfig;
|
|
106
|
+
cachedDataset?: (string | number | null)[][] | null;
|
|
107
|
+
updatedAt?: string;
|
|
108
|
+
updatedBy?: string;
|
|
109
|
+
}
|
|
110
|
+
export type ChartSyncStatus = 'idle' | 'syncing' | 'success' | 'pending_data' | 'error';
|
|
111
|
+
export type ChartProblemCategory = 'unlinked' | 'connection_error' | 'data_format' | 'none';
|
|
112
|
+
export interface ChartState {
|
|
113
|
+
dataset: ChartDataset | null;
|
|
114
|
+
status: ChartSyncStatus;
|
|
115
|
+
errorMessage?: string;
|
|
116
|
+
lastSyncedAt?: string;
|
|
117
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CloudDraftSyncStatus } from './draft';
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript Contracts for Developer Mode & Live Administrative Affordances
|
|
5
|
+
* Task 4.5.0: docs/tasks/task4_5_0_developer_mode.md
|
|
6
|
+
*/
|
|
7
|
+
export type PinVerificationState = 'idle' | 'verifying' | 'success' | 'error' | 'locked_out';
|
|
8
|
+
export interface DeveloperSessionInfo {
|
|
9
|
+
unlockedAt: number | null;
|
|
10
|
+
expiresAt: number | null;
|
|
11
|
+
remainingMinutes: number;
|
|
12
|
+
}
|
|
13
|
+
export interface DevSessionLock {
|
|
14
|
+
id: 'active_session';
|
|
15
|
+
isLocked: boolean;
|
|
16
|
+
lockedBySessionId: string;
|
|
17
|
+
coordinatorLabel?: string;
|
|
18
|
+
lockedAt: string;
|
|
19
|
+
lastHeartbeatAt: string;
|
|
20
|
+
expiresAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DevLockStatusResponse {
|
|
23
|
+
canAcquire: boolean;
|
|
24
|
+
currentLock?: DevSessionLock;
|
|
25
|
+
isSelfSession: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface DeveloperModeContextType {
|
|
28
|
+
/** Whether developer mode is currently active and authenticated */
|
|
29
|
+
isDevMode: boolean;
|
|
30
|
+
/** Whether the current client device meets PC/Desktop requirements (>=1024px, fine pointer) */
|
|
31
|
+
isDesktop: boolean;
|
|
32
|
+
/** Whether the PIN entry modal is currently displayed */
|
|
33
|
+
isPinModalOpen: boolean;
|
|
34
|
+
/** Verification lifecycle state */
|
|
35
|
+
pinState: PinVerificationState;
|
|
36
|
+
/** Number of remaining incorrect attempts before 1-minute lockout */
|
|
37
|
+
attemptsRemaining: number;
|
|
38
|
+
/** Lockout countdown remaining in seconds (0 when not locked out) */
|
|
39
|
+
lockoutRemainingSeconds: number;
|
|
40
|
+
/** Remaining session time in minutes */
|
|
41
|
+
sessionRemainingMinutes: number;
|
|
42
|
+
/** Whether the current PIN modal was triggered for session renewal */
|
|
43
|
+
isRenewal: boolean;
|
|
44
|
+
/** Open PIN modal (or renewal prompt) */
|
|
45
|
+
openPinModal: (isRenewal?: boolean, skipLockCheck?: boolean) => void;
|
|
46
|
+
/** Close PIN modal */
|
|
47
|
+
closePinModal: () => void;
|
|
48
|
+
/** Submit 4-digit PIN for cryptographic verification */
|
|
49
|
+
submitPin: (pin: string) => Promise<boolean>;
|
|
50
|
+
/** Exit developer mode immediately, clearing session unlock timestamp */
|
|
51
|
+
exitDevMode: (options?: {
|
|
52
|
+
discard?: boolean;
|
|
53
|
+
}) => void;
|
|
54
|
+
/** Whether the exit confirmation dialog is open */
|
|
55
|
+
isExitConfirmOpen: boolean;
|
|
56
|
+
/** Request exit from developer mode (prompts confirmation modal) */
|
|
57
|
+
requestExitDevMode: () => void;
|
|
58
|
+
/** Confirm exit from developer mode, closing dialog and exiting */
|
|
59
|
+
confirmExitDevMode: (options?: {
|
|
60
|
+
discard?: boolean;
|
|
61
|
+
}) => void;
|
|
62
|
+
/** Dismiss exit confirmation dialog without exiting */
|
|
63
|
+
closeExitConfirmModal: () => void;
|
|
64
|
+
/** Toggle developer mode: opens PIN modal if inactive, prompts exit if active */
|
|
65
|
+
toggleDevMode: () => void;
|
|
66
|
+
/** Unique session ID generated for this browser instance */
|
|
67
|
+
sessionId: string;
|
|
68
|
+
/** Whether Dev Mode entry is blocked because another coordinator holds the lock */
|
|
69
|
+
isLockBlocked: boolean;
|
|
70
|
+
/** Active lock metadata if blocked */
|
|
71
|
+
activeLockInfo: DevSessionLock | null;
|
|
72
|
+
/** Dismiss the blocked coordinator dialog */
|
|
73
|
+
closeLockBlockedModal: () => void;
|
|
74
|
+
/** Force release or refresh lock status */
|
|
75
|
+
refreshLockStatus: () => Promise<void>;
|
|
76
|
+
/** Whether there are unsaved draft changes in the active session */
|
|
77
|
+
hasUnpublishedChanges: boolean;
|
|
78
|
+
/** Update the dirty state of unpublished draft changes */
|
|
79
|
+
setHasUnpublishedChanges: (hasChanges: boolean) => void;
|
|
80
|
+
/** Whether the active version is currently hydrating from cloud storage */
|
|
81
|
+
isCloudHydrating?: boolean;
|
|
82
|
+
/** Current cloud DB-draft synchronization status */
|
|
83
|
+
cloudSyncStatus?: CloudDraftSyncStatus;
|
|
84
|
+
/** Display a floating Toast feedback capsule */
|
|
85
|
+
showToast: (message: string, type?: 'success' | 'error' | 'info') => void;
|
|
86
|
+
}
|
|
87
|
+
export type DevEditType = 'text' | 'link' | 'image' | 'file';
|
|
88
|
+
export type DevAffordanceType = 'text' | 'link' | 'image' | 'file' | 'source' | 'indicator';
|
|
89
|
+
export interface DevLinkData {
|
|
90
|
+
url: string;
|
|
91
|
+
label?: string;
|
|
92
|
+
openInNewTab?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface DevImageData {
|
|
95
|
+
src: string;
|
|
96
|
+
alt: string;
|
|
97
|
+
caption?: string;
|
|
98
|
+
showCaption?: boolean;
|
|
99
|
+
}
|
|
100
|
+
export interface DevFileData {
|
|
101
|
+
name: string;
|
|
102
|
+
url: string;
|
|
103
|
+
reference?: string;
|
|
104
|
+
format?: 'pdf' | 'doc' | 'sheet' | 'other';
|
|
105
|
+
size?: string;
|
|
106
|
+
}
|
|
107
|
+
export interface DevActionAffordanceProps {
|
|
108
|
+
/** Identifier of the milestone or content node (e.g. 'stage-1', 'node-access') */
|
|
109
|
+
pointId?: string;
|
|
110
|
+
/** Type of affordance to render when developer mode is active */
|
|
111
|
+
type?: DevAffordanceType;
|
|
112
|
+
/** Optional custom action label (deprecated under Uniform Edit Standard) */
|
|
113
|
+
label?: string;
|
|
114
|
+
/** Callback when edit action is clicked */
|
|
115
|
+
onEditText?: () => void;
|
|
116
|
+
/** Callback when "Edit Source" action is clicked */
|
|
117
|
+
onEditSource?: () => void;
|
|
118
|
+
/** Optional link to associated Google Drive folder */
|
|
119
|
+
driveUrl?: string;
|
|
120
|
+
/** Current content for dynamic modal editing */
|
|
121
|
+
currentValue?: string | DevLinkData | DevImageData | DevFileData;
|
|
122
|
+
/** Default fallback content for dynamic modal editing */
|
|
123
|
+
defaultValue?: string | DevLinkData | DevImageData | DevFileData;
|
|
124
|
+
/** Direct update handler if bypassing useContent internal dispatch */
|
|
125
|
+
onSave?: (newValue: string) => void;
|
|
126
|
+
/** Direct reset handler if bypassing useContent internal dispatch */
|
|
127
|
+
onReset?: () => void;
|
|
128
|
+
/** Wrapped child component */
|
|
129
|
+
children: React.ReactNode;
|
|
130
|
+
/** Optional container class name */
|
|
131
|
+
className?: string;
|
|
132
|
+
/** Whether to render as an inline container instead of block */
|
|
133
|
+
inline?: boolean;
|
|
134
|
+
/** Whether the target content belongs to a section heading */
|
|
135
|
+
isSection?: boolean;
|
|
136
|
+
/** Whether the section is currently numbered */
|
|
137
|
+
isNumbered?: boolean;
|
|
138
|
+
/** Default numbering fallback */
|
|
139
|
+
defaultNumbered?: boolean;
|
|
140
|
+
/** Callback when section numbering is toggled */
|
|
141
|
+
onNumberedChange?: (isNumbered: boolean) => void;
|
|
142
|
+
/** Optional deterministic trigger identifier for canvas controls targeting */
|
|
143
|
+
editTriggerId?: string;
|
|
144
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Folio Engine - Cloud DB-Draft Contracts
|
|
3
|
+
* Location: src/types/draft.ts
|
|
4
|
+
* Specification: docs/tasks/task11_2g_db_draft_and_blob_storage_pipeline.md
|
|
5
|
+
*/
|
|
6
|
+
import type { NodeCanvasDocument } from './canvas';
|
|
7
|
+
export interface CloudDraftData {
|
|
8
|
+
id: string;
|
|
9
|
+
baseSnapshotId: string;
|
|
10
|
+
canvases: Record<string, NodeCanvasDocument>;
|
|
11
|
+
contentOverrides: Record<string, string>;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
updatedBySession?: string;
|
|
14
|
+
lockedBySession?: string;
|
|
15
|
+
}
|
|
16
|
+
export type CloudDraftSyncStatus = 'saved' | 'saving' | 'error' | 'offline';
|
|
17
|
+
export interface DraftSyncStatusEventDetail {
|
|
18
|
+
status: CloudDraftSyncStatus;
|
|
19
|
+
lastSavedAt?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Folio Engine — Cloudflare Pages Functions & Edge KV Schema Contracts
|
|
3
|
+
* Location: src/types/edge.ts
|
|
4
|
+
* Specification: docs/tasks/task15_1_edge_routing_and_kv_schema_architecture.md
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { NodeCanvasDocument } from './canvas';
|
|
8
|
+
import type { ChartDataset } from './chart';
|
|
9
|
+
import type { SyncedSourceItem } from './source';
|
|
10
|
+
import type { NodeCode } from './node';
|
|
11
|
+
export declare const VALID_NODES: readonly NodeCode[];
|
|
12
|
+
export type ValidNodeId = typeof VALID_NODES[number];
|
|
13
|
+
/**
|
|
14
|
+
* Cloudflare KV Namespace Interface for Edge Bindings
|
|
15
|
+
*/
|
|
16
|
+
export interface KVNamespace {
|
|
17
|
+
get(key: string, options?: {
|
|
18
|
+
type?: 'text' | 'json' | 'arrayBuffer' | 'stream';
|
|
19
|
+
cacheTtl?: number;
|
|
20
|
+
}): Promise<string | null>;
|
|
21
|
+
get<T>(key: string, type: 'json'): Promise<T | null>;
|
|
22
|
+
put(key: string, value: string | ArrayBuffer | ReadableStream, options?: {
|
|
23
|
+
expiration?: number;
|
|
24
|
+
expirationTtl?: number;
|
|
25
|
+
metadata?: unknown;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
delete(key: string): Promise<void>;
|
|
28
|
+
list(options?: {
|
|
29
|
+
prefix?: string;
|
|
30
|
+
limit?: number;
|
|
31
|
+
cursor?: string;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
keys: {
|
|
34
|
+
name: string;
|
|
35
|
+
expiration?: number;
|
|
36
|
+
metadata?: unknown;
|
|
37
|
+
}[];
|
|
38
|
+
list_complete: boolean;
|
|
39
|
+
cursor?: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Cloudflare Pages Functions Environment Bindings
|
|
44
|
+
*/
|
|
45
|
+
export interface EdgeEnv {
|
|
46
|
+
KV_ENGINE_PUBLIC: KVNamespace;
|
|
47
|
+
VITE_SUPABASE_URL?: string;
|
|
48
|
+
VITE_SUPABASE_ANON_KEY?: string;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Cloudflare Pages Functions EventContext Contract
|
|
53
|
+
*/
|
|
54
|
+
export interface PagesFunctionEventContext<Env = EdgeEnv, P extends string = string, Data = unknown> {
|
|
55
|
+
request: Request;
|
|
56
|
+
functionPath: string;
|
|
57
|
+
waitUntil: (promise: Promise<unknown>) => void;
|
|
58
|
+
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
|
59
|
+
env: Env;
|
|
60
|
+
params: Record<P, string | string[]>;
|
|
61
|
+
data: Data;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Cached Indicator Dataset (serialized tabular/D3 data stored in KV)
|
|
65
|
+
*/
|
|
66
|
+
export type CachedIndicatorDataset = ChartDataset;
|
|
67
|
+
/**
|
|
68
|
+
* Synced Evidence Metadata
|
|
69
|
+
*/
|
|
70
|
+
export interface SyncedSourceMetadata {
|
|
71
|
+
pointId: string;
|
|
72
|
+
folderUrl?: string;
|
|
73
|
+
folderTitle?: string;
|
|
74
|
+
description?: string;
|
|
75
|
+
lastSyncedAt?: string;
|
|
76
|
+
items?: SyncedSourceItem[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Route Contract 1: GET /api/public/node/:nodeId
|
|
80
|
+
*/
|
|
81
|
+
export interface PublicNodePayload {
|
|
82
|
+
nodeId: string;
|
|
83
|
+
snapshotId: string;
|
|
84
|
+
version: number;
|
|
85
|
+
updatedAt: string;
|
|
86
|
+
canvas: NodeCanvasDocument;
|
|
87
|
+
chartDatasets: Record<string, CachedIndicatorDataset>;
|
|
88
|
+
sourceMetadata: Record<string, SyncedSourceMetadata>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Route Contract 2: GET /api/public/manifest
|
|
92
|
+
*/
|
|
93
|
+
export interface PublicPortalManifestPayload {
|
|
94
|
+
activeSnapshotId: string;
|
|
95
|
+
publishedAt: string;
|
|
96
|
+
nodeIds: string[];
|
|
97
|
+
schemaVersion: number;
|
|
98
|
+
}
|
|
99
|
+
export declare const PublicPortalManifestPayloadSchema: z.ZodObject<{
|
|
100
|
+
activeSnapshotId: z.ZodString;
|
|
101
|
+
publishedAt: z.ZodString;
|
|
102
|
+
nodeIds: z.ZodArray<z.ZodString, "many">;
|
|
103
|
+
schemaVersion: z.ZodNumber;
|
|
104
|
+
}, "strip", z.ZodTypeAny, {
|
|
105
|
+
activeSnapshotId: string;
|
|
106
|
+
publishedAt: string;
|
|
107
|
+
nodeIds: string[];
|
|
108
|
+
schemaVersion: number;
|
|
109
|
+
}, {
|
|
110
|
+
activeSnapshotId: string;
|
|
111
|
+
publishedAt: string;
|
|
112
|
+
nodeIds: string[];
|
|
113
|
+
schemaVersion: number;
|
|
114
|
+
}>;
|
|
115
|
+
export declare const NodeCanvasDocumentSchema: z.ZodObject<{
|
|
116
|
+
nodeId: z.ZodString;
|
|
117
|
+
version: z.ZodNumber;
|
|
118
|
+
sections: z.ZodArray<z.ZodAny, "many">;
|
|
119
|
+
updatedAt: z.ZodString;
|
|
120
|
+
}, "strip", z.ZodTypeAny, {
|
|
121
|
+
nodeId: string;
|
|
122
|
+
version: number;
|
|
123
|
+
sections: any[];
|
|
124
|
+
updatedAt: string;
|
|
125
|
+
}, {
|
|
126
|
+
nodeId: string;
|
|
127
|
+
version: number;
|
|
128
|
+
sections: any[];
|
|
129
|
+
updatedAt: string;
|
|
130
|
+
}>;
|
|
131
|
+
export declare const CachedIndicatorDatasetSchema: z.ZodObject<{
|
|
132
|
+
chartId: z.ZodString;
|
|
133
|
+
title: z.ZodString;
|
|
134
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
135
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
136
|
+
asOfDate: z.ZodString;
|
|
137
|
+
chartType: z.ZodString;
|
|
138
|
+
sanitizedCsvContent: z.ZodOptional<z.ZodString>;
|
|
139
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
140
|
+
chartId: z.ZodString;
|
|
141
|
+
title: z.ZodString;
|
|
142
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
143
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
144
|
+
asOfDate: z.ZodString;
|
|
145
|
+
chartType: z.ZodString;
|
|
146
|
+
sanitizedCsvContent: z.ZodOptional<z.ZodString>;
|
|
147
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
148
|
+
chartId: z.ZodString;
|
|
149
|
+
title: z.ZodString;
|
|
150
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
151
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
152
|
+
asOfDate: z.ZodString;
|
|
153
|
+
chartType: z.ZodString;
|
|
154
|
+
sanitizedCsvContent: z.ZodOptional<z.ZodString>;
|
|
155
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
156
|
+
export declare const SyncedSourceMetadataSchema: z.ZodObject<{
|
|
157
|
+
pointId: z.ZodString;
|
|
158
|
+
folderUrl: z.ZodOptional<z.ZodString>;
|
|
159
|
+
folderTitle: z.ZodOptional<z.ZodString>;
|
|
160
|
+
description: z.ZodOptional<z.ZodString>;
|
|
161
|
+
lastSyncedAt: z.ZodOptional<z.ZodString>;
|
|
162
|
+
items: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
163
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
164
|
+
pointId: z.ZodString;
|
|
165
|
+
folderUrl: z.ZodOptional<z.ZodString>;
|
|
166
|
+
folderTitle: z.ZodOptional<z.ZodString>;
|
|
167
|
+
description: z.ZodOptional<z.ZodString>;
|
|
168
|
+
lastSyncedAt: z.ZodOptional<z.ZodString>;
|
|
169
|
+
items: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
170
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
171
|
+
pointId: z.ZodString;
|
|
172
|
+
folderUrl: z.ZodOptional<z.ZodString>;
|
|
173
|
+
folderTitle: z.ZodOptional<z.ZodString>;
|
|
174
|
+
description: z.ZodOptional<z.ZodString>;
|
|
175
|
+
lastSyncedAt: z.ZodOptional<z.ZodString>;
|
|
176
|
+
items: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
177
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
178
|
+
export declare const PublicNodePayloadSchema: z.ZodObject<{
|
|
179
|
+
nodeId: z.ZodString;
|
|
180
|
+
snapshotId: z.ZodString;
|
|
181
|
+
version: z.ZodNumber;
|
|
182
|
+
updatedAt: z.ZodString;
|
|
183
|
+
canvas: z.ZodObject<{
|
|
184
|
+
nodeId: z.ZodString;
|
|
185
|
+
version: z.ZodNumber;
|
|
186
|
+
sections: z.ZodArray<z.ZodAny, "many">;
|
|
187
|
+
updatedAt: z.ZodString;
|
|
188
|
+
}, "strip", z.ZodTypeAny, {
|
|
189
|
+
nodeId: string;
|
|
190
|
+
version: number;
|
|
191
|
+
sections: any[];
|
|
192
|
+
updatedAt: string;
|
|
193
|
+
}, {
|
|
194
|
+
nodeId: string;
|
|
195
|
+
version: number;
|
|
196
|
+
sections: any[];
|
|
197
|
+
updatedAt: string;
|
|
198
|
+
}>;
|
|
199
|
+
chartDatasets: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
200
|
+
sourceMetadata: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
201
|
+
}, "strip", z.ZodTypeAny, {
|
|
202
|
+
nodeId: string;
|
|
203
|
+
version: number;
|
|
204
|
+
updatedAt: string;
|
|
205
|
+
snapshotId: string;
|
|
206
|
+
canvas: {
|
|
207
|
+
nodeId: string;
|
|
208
|
+
version: number;
|
|
209
|
+
sections: any[];
|
|
210
|
+
updatedAt: string;
|
|
211
|
+
};
|
|
212
|
+
chartDatasets: Record<string, any>;
|
|
213
|
+
sourceMetadata: Record<string, any>;
|
|
214
|
+
}, {
|
|
215
|
+
nodeId: string;
|
|
216
|
+
version: number;
|
|
217
|
+
updatedAt: string;
|
|
218
|
+
snapshotId: string;
|
|
219
|
+
canvas: {
|
|
220
|
+
nodeId: string;
|
|
221
|
+
version: number;
|
|
222
|
+
sections: any[];
|
|
223
|
+
updatedAt: string;
|
|
224
|
+
};
|
|
225
|
+
chartDatasets: Record<string, any>;
|
|
226
|
+
sourceMetadata: Record<string, any>;
|
|
227
|
+
}>;
|
|
228
|
+
/**
|
|
229
|
+
* Computes a deterministic weak ETag for HTTP cache negotiation (304 Not Modified).
|
|
230
|
+
* Fast, synchronous, zero-dependency, works identically in Workers, Node, and browser.
|
|
231
|
+
*/
|
|
232
|
+
export declare function computeWeakEtag(content: string): string;
|