chore: establish learning module baseline
This commit is contained in:
commit
2d04197f3f
2409 files changed
+533050
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import type { PPTElement } from '@openmaic/dsl';
|
||||
|
||||
/**
|
||||
* Extract the semantic payload for each element type.
|
||||
* Used by elementFingerprint to detect content-only changes
|
||||
* (same id/position but different text, chart data, media src, etc.).
|
||||
*/
|
||||
function semanticPart(e: PPTElement): unknown {
|
||||
switch (e.type) {
|
||||
case 'text':
|
||||
return { content: e.content };
|
||||
case 'image':
|
||||
return { src: e.src };
|
||||
case 'shape':
|
||||
return {
|
||||
path: e.path,
|
||||
fill: e.fill,
|
||||
text: e.text?.content ?? '',
|
||||
gradient: e.gradient ?? null,
|
||||
pattern: e.pattern ?? null,
|
||||
};
|
||||
case 'line':
|
||||
return {
|
||||
start: e.start,
|
||||
end: e.end,
|
||||
color: e.color,
|
||||
style: e.style,
|
||||
points: e.points,
|
||||
};
|
||||
case 'chart':
|
||||
return {
|
||||
chartType: e.chartType,
|
||||
data: e.data,
|
||||
themeColors: e.themeColors,
|
||||
};
|
||||
case 'table':
|
||||
return {
|
||||
data: e.data.map((row) => row.map((c) => c.text)),
|
||||
colWidths: e.colWidths,
|
||||
theme: e.theme ?? null,
|
||||
};
|
||||
case 'latex':
|
||||
return { latex: e.latex };
|
||||
case 'video':
|
||||
return { src: e.src, poster: e.poster ?? '' };
|
||||
case 'audio':
|
||||
return { src: e.src };
|
||||
case 'code':
|
||||
return { language: e.language, lines: e.lines, fileName: e.fileName ?? '' };
|
||||
default: {
|
||||
const exhaustiveCheck: never = e;
|
||||
return exhaustiveCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a fingerprint string for a list of whiteboard elements.
|
||||
* Used for change detection and deduplication in history snapshots.
|
||||
*
|
||||
* Covers both geometry (id, position, size) AND semantic content
|
||||
* via structured JSON.stringify — avoids delimiter-collision issues
|
||||
* that hand-concatenated strings would have with rich-text HTML content.
|
||||
*/
|
||||
export function elementFingerprint(els: PPTElement[]): string {
|
||||
return JSON.stringify(
|
||||
els.map((e) => ({
|
||||
id: e.id,
|
||||
left: e.left ?? 0,
|
||||
top: e.top ?? 0,
|
||||
width: 'width' in e ? e.width : 0,
|
||||
height: 'height' in e && e.height != null ? e.height : 0,
|
||||
sem: semanticPart(e),
|
||||
})),
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user