@particle-academy/fancy-slides 0.9.0 → 0.11.0

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/index.cjs CHANGED
@@ -1793,6 +1793,7 @@ function useDeckState({ value, onChange, onOp }) {
1793
1793
  apply,
1794
1794
  setTitle: (title) => apply({ kind: "deck_set_title", title }),
1795
1795
  applyTheme: (theme) => apply({ kind: "deck_apply_theme", theme }),
1796
+ setDeck: (deck) => apply({ kind: "deck_set", deck }),
1796
1797
  addSlide: (index, partial) => {
1797
1798
  const id = partial?.id ?? slideId();
1798
1799
  const slide = {
@@ -1847,6 +1848,8 @@ function reduce(deck, op) {
1847
1848
  return { ...deck, title: op.title };
1848
1849
  case "deck_apply_theme":
1849
1850
  return { ...deck, theme: op.theme };
1851
+ case "deck_set":
1852
+ return op.deck;
1850
1853
  case "slide_add": {
1851
1854
  const slides = [...deck.slides];
1852
1855
  slides.splice(Math.max(0, Math.min(slides.length, op.index)), 0, op.slide);
@@ -3357,6 +3360,74 @@ function DeckEditor({
3357
3360
  // src/types.ts
3358
3361
  var SCHEMA_VERSION = 1;
3359
3362
 
3363
+ // src/utils/serialize.ts
3364
+ var ELEMENT_TYPES = ["text", "image", "chart", "code", "table", "shape", "embed"];
3365
+ function validateDeck(deck) {
3366
+ const errors = [];
3367
+ const d = deck;
3368
+ if (!d || typeof d !== "object") {
3369
+ return { ok: false, errors: ["deck is not an object"] };
3370
+ }
3371
+ if (typeof d.id !== "string" || !d.id) errors.push("deck.id must be a non-empty string");
3372
+ if (typeof d.title !== "string") errors.push("deck.title must be a string");
3373
+ if (!d.theme || typeof d.theme !== "object") errors.push("deck.theme must be an object");
3374
+ if (!Array.isArray(d.slides)) {
3375
+ errors.push("deck.slides must be an array");
3376
+ return { ok: errors.length === 0, errors };
3377
+ }
3378
+ d.slides.forEach((slide, si) => {
3379
+ if (!slide || typeof slide !== "object") {
3380
+ errors.push(`slides[${si}] is not an object`);
3381
+ return;
3382
+ }
3383
+ if (typeof slide.id !== "string" || !slide.id) errors.push(`slides[${si}].id must be a non-empty string`);
3384
+ if (!Array.isArray(slide.elements)) {
3385
+ errors.push(`slides[${si}].elements must be an array`);
3386
+ return;
3387
+ }
3388
+ slide.elements.forEach((el, ei) => {
3389
+ const where = `slides[${si}].elements[${ei}]`;
3390
+ if (!el || typeof el !== "object") {
3391
+ errors.push(`${where} is not an object`);
3392
+ return;
3393
+ }
3394
+ if (typeof el.id !== "string" || !el.id) errors.push(`${where}.id must be a non-empty string`);
3395
+ if (!ELEMENT_TYPES.includes(el.type)) errors.push(`${where}.type "${el.type}" is not a known element type`);
3396
+ for (const k of ["x", "y", "w", "h"]) {
3397
+ const v = el[k];
3398
+ if (typeof v !== "number" || v < 0 || v > 1) errors.push(`${where}.${k} must be a number in 0..1`);
3399
+ }
3400
+ });
3401
+ });
3402
+ return { ok: errors.length === 0, errors };
3403
+ }
3404
+ function migrateDeck(deck) {
3405
+ let d = deck;
3406
+ d.version ?? 1;
3407
+ return d.version === SCHEMA_VERSION ? d : { ...d, version: SCHEMA_VERSION };
3408
+ }
3409
+ function serializeDeck(deck, pretty = false) {
3410
+ const stamped = deck.version === SCHEMA_VERSION ? deck : { ...deck, version: SCHEMA_VERSION };
3411
+ return JSON.stringify(stamped, null, pretty ? 2 : void 0);
3412
+ }
3413
+ function parseDeck(input) {
3414
+ let raw;
3415
+ if (typeof input === "string") {
3416
+ try {
3417
+ raw = JSON.parse(input);
3418
+ } catch (e) {
3419
+ throw new Error(`parseDeck: invalid JSON \u2014 ${e.message}`);
3420
+ }
3421
+ } else {
3422
+ raw = input;
3423
+ }
3424
+ const result = validateDeck(raw);
3425
+ if (!result.ok) {
3426
+ throw new Error(`parseDeck: invalid deck \u2014 ${result.errors.join("; ")}`);
3427
+ }
3428
+ return migrateDeck(raw);
3429
+ }
3430
+
3360
3431
  exports.DeckEditor = DeckEditor;
3361
3432
  exports.EditorToolbar = EditorToolbar;
3362
3433
  exports.ElementInspector = ElementInspector;
@@ -3382,11 +3453,14 @@ exports.defaultTheme = defaultTheme;
3382
3453
  exports.defineTheme = defineTheme;
3383
3454
  exports.elementId = elementId;
3384
3455
  exports.isByParagraph = isByParagraph;
3456
+ exports.migrateDeck = migrateDeck;
3385
3457
  exports.nextId = nextId;
3386
3458
  exports.normalizeSlideMarkdown = normalizeSlideMarkdown;
3387
3459
  exports.paragraphReveals = paragraphReveals;
3460
+ exports.parseDeck = parseDeck;
3388
3461
  exports.reduceDeck = reduce;
3389
3462
  exports.resolveTheme = resolveTheme;
3463
+ exports.serializeDeck = serializeDeck;
3390
3464
  exports.slideId = slideId;
3391
3465
  exports.splitParagraphs = splitParagraphs;
3392
3466
  exports.stepDelays = stepDelays;
@@ -3396,6 +3470,7 @@ exports.useIsDarkSlide = useIsDarkSlide;
3396
3470
  exports.useSlideContext = useSlideContext;
3397
3471
  exports.useSlideKeyboard = useSlideKeyboard;
3398
3472
  exports.useSlideTheme = useSlideTheme;
3473
+ exports.validateDeck = validateDeck;
3399
3474
  exports.visibleElementIds = visibleElementIds;
3400
3475
  exports.vividTheme = vividTheme;
3401
3476
  //# sourceMappingURL=index.cjs.map