@drawnagency/primitives 0.1.75 → 0.1.77

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.
Files changed (83) hide show
  1. package/dist/chunk-2G2S36SY.js +13 -0
  2. package/dist/{chunk-7T2WQSWF.js → chunk-63BQQNZO.js} +9 -9
  3. package/dist/chunk-REM2NH7K.js +44 -0
  4. package/dist/{chunk-U4E6S4PX.js → chunk-RO4E5UJI.js} +53 -39
  5. package/dist/{chunk-NKVZGPR6.js → chunk-YP7IHMC3.js} +1 -1
  6. package/dist/collab/provider-registry.d.ts +4 -0
  7. package/dist/collab/provider-registry.d.ts.map +1 -0
  8. package/dist/collab/provider-registry.js +9 -0
  9. package/dist/collab/rebase.d.ts +37 -0
  10. package/dist/collab/rebase.d.ts.map +1 -0
  11. package/dist/collab/rebase.js +64 -0
  12. package/dist/collab/recovery.d.ts +89 -0
  13. package/dist/collab/recovery.d.ts.map +1 -0
  14. package/dist/collab/types.d.ts +93 -0
  15. package/dist/collab/types.d.ts.map +1 -0
  16. package/dist/collab/types.js +19 -0
  17. package/dist/components/editor/AudienceIndicator.d.ts +3 -1
  18. package/dist/components/editor/AudienceIndicator.d.ts.map +1 -1
  19. package/dist/components/editor/ChildBlockWrapper.d.ts +7 -0
  20. package/dist/components/editor/ChildBlockWrapper.d.ts.map +1 -1
  21. package/dist/components/editor/ConflictDialog.d.ts +14 -0
  22. package/dist/components/editor/ConflictDialog.d.ts.map +1 -0
  23. package/dist/components/editor/IndicatorPill.d.ts +4 -1
  24. package/dist/components/editor/IndicatorPill.d.ts.map +1 -1
  25. package/dist/components/editor/LockBadge.d.ts +7 -0
  26. package/dist/components/editor/LockBadge.d.ts.map +1 -0
  27. package/dist/components/editor/PresenceAvatars.d.ts +9 -0
  28. package/dist/components/editor/PresenceAvatars.d.ts.map +1 -0
  29. package/dist/components/editor/SectionWrapper.d.ts +1 -1
  30. package/dist/components/editor/SectionWrapper.d.ts.map +1 -1
  31. package/dist/components/editor/StatusIndicator.d.ts +3 -1
  32. package/dist/components/editor/StatusIndicator.d.ts.map +1 -1
  33. package/dist/components/editor/index.js +92 -44
  34. package/dist/components/primitives/index.js +3 -3
  35. package/dist/components/sections/Container/Container.d.ts.map +1 -1
  36. package/dist/components/sections/brand-guide.js +3 -3
  37. package/dist/components/sections/register-schemas.js +9 -9
  38. package/dist/components/sections/register.js +9 -9
  39. package/dist/components/shell/EditorShell.d.ts +3 -1
  40. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  41. package/dist/hooks/useCollabSession.d.ts +23 -0
  42. package/dist/hooks/useCollabSession.d.ts.map +1 -0
  43. package/dist/hooks/useEditorPersistence.d.ts +21 -1
  44. package/dist/hooks/useEditorPersistence.d.ts.map +1 -1
  45. package/dist/hooks/useEditorPublish.d.ts +39 -2
  46. package/dist/hooks/useEditorPublish.d.ts.map +1 -1
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +44 -22
  50. package/dist/lib/dexie.d.ts +12 -0
  51. package/dist/lib/dexie.d.ts.map +1 -1
  52. package/dist/lib/dexie.js +27 -0
  53. package/dist/lib/index.js +12 -12
  54. package/dist/lib/registry.d.ts +10 -0
  55. package/dist/lib/registry.d.ts.map +1 -1
  56. package/dist/schemas/index.js +1 -1
  57. package/dist/types/database.d.ts +70 -0
  58. package/dist/types/database.d.ts.map +1 -1
  59. package/package.json +13 -1
  60. package/src/collab/provider-registry.ts +14 -0
  61. package/src/collab/rebase.ts +140 -0
  62. package/src/collab/recovery.ts +149 -0
  63. package/src/collab/types.ts +96 -0
  64. package/src/components/editor/AudienceIndicator.tsx +4 -1
  65. package/src/components/editor/ChildBlockWrapper.tsx +15 -1
  66. package/src/components/editor/ConflictDialog.tsx +61 -0
  67. package/src/components/editor/IndicatorPill.tsx +12 -6
  68. package/src/components/editor/LockBadge.tsx +31 -0
  69. package/src/components/editor/PresenceAvatars.tsx +53 -0
  70. package/src/components/editor/SectionWrapper.tsx +60 -29
  71. package/src/components/editor/StatusIndicator.tsx +4 -0
  72. package/src/components/sections/Container/Container.tsx +6 -4
  73. package/src/components/shell/EditorShell.tsx +561 -18
  74. package/src/hooks/useCollabSession.ts +220 -0
  75. package/src/hooks/useEditorPersistence.ts +104 -1
  76. package/src/hooks/useEditorPublish.ts +205 -63
  77. package/src/index.ts +2 -0
  78. package/src/lib/dexie.ts +44 -0
  79. package/src/lib/registry.ts +8 -0
  80. package/src/types/database.ts +55 -0
  81. package/dist/{chunk-Q3T23HVW.js → chunk-B2DLHZKC.js} +4 -4
  82. package/dist/{chunk-T7MP7ANP.js → chunk-UUCOJL7O.js} +0 -0
  83. package/dist/{chunk-ZRWGV5O6.js → chunk-XFDEUK37.js} +3 -3
@@ -0,0 +1,13 @@
1
+ // src/collab/provider-registry.ts
2
+ var provider = null;
3
+ function setCollabProvider(p) {
4
+ provider = p;
5
+ }
6
+ function getCollabProvider() {
7
+ return provider;
8
+ }
9
+
10
+ export {
11
+ setCollabProvider,
12
+ getCollabProvider
13
+ };
@@ -1,15 +1,15 @@
1
+ import {
2
+ Checkbox,
3
+ FormLabel,
4
+ Input
5
+ } from "./chunk-5THS4K5D.js";
1
6
  import {
2
7
  EditableGrid,
3
8
  EditablePlainText,
4
9
  MediaBlock,
5
10
  containerGridClass,
6
11
  useEditableCollection
7
- } from "./chunk-T7MP7ANP.js";
8
- import {
9
- Checkbox,
10
- FormLabel,
11
- Input
12
- } from "./chunk-5THS4K5D.js";
12
+ } from "./chunk-UUCOJL7O.js";
13
13
  import {
14
14
  AddIcon,
15
15
  DeleteIcon,
@@ -27,13 +27,13 @@ import {
27
27
  import {
28
28
  cn
29
29
  } from "./chunk-7EOSDFS3.js";
30
- import {
31
- defineSection
32
- } from "./chunk-VKAGMEKE.js";
33
30
  import {
34
31
  HexColorSchema,
35
32
  SingleMediaReferenceSchema
36
33
  } from "./chunk-SWIHUIFT.js";
34
+ import {
35
+ defineSection
36
+ } from "./chunk-VKAGMEKE.js";
37
37
 
38
38
  // src/components/sections/Colors/index.tsx
39
39
  import { z as z2 } from "zod";
@@ -0,0 +1,44 @@
1
+ // src/collab/types.ts
2
+ import { z } from "zod";
3
+ var HEARTBEAT_INTERVAL_MS = 15e3;
4
+ var LOCK_STALE_MS = 45e3;
5
+ var CollabPeerSchema = z.object({
6
+ userId: z.string(),
7
+ email: z.string(),
8
+ focusSectionId: z.string().nullable(),
9
+ heldSectionIds: z.array(z.string())
10
+ });
11
+ var SectionUpdateMessageSchema = z.object({
12
+ v: z.literal(1),
13
+ sectionId: z.string(),
14
+ content: z.unknown(),
15
+ userId: z.string()
16
+ });
17
+ var IndexUpdateMessageSchema = z.object({
18
+ v: z.literal(1),
19
+ index: z.unknown(),
20
+ userId: z.string()
21
+ });
22
+ var TakeoverMessageSchema = z.object({
23
+ v: z.literal(1),
24
+ sectionId: z.string(),
25
+ byUserId: z.string(),
26
+ byEmail: z.string()
27
+ });
28
+ var SavedMessageSchema = z.object({
29
+ v: z.literal(1),
30
+ newSha: z.string(),
31
+ changedSectionIds: z.array(z.string()),
32
+ deletedSectionIds: z.array(z.string()),
33
+ source: z.enum(["editor", "api"])
34
+ });
35
+
36
+ export {
37
+ HEARTBEAT_INTERVAL_MS,
38
+ LOCK_STALE_MS,
39
+ CollabPeerSchema,
40
+ SectionUpdateMessageSchema,
41
+ IndexUpdateMessageSchema,
42
+ TakeoverMessageSchema,
43
+ SavedMessageSchema
44
+ };
@@ -1,25 +1,9 @@
1
- import {
2
- EditableRichText,
3
- defineHeadingSection
4
- } from "./chunk-NKVZGPR6.js";
5
- import {
6
- embedUrl
7
- } from "./chunk-Y4JQGO6G.js";
8
1
  import {
9
2
  brandGuideSectionDefs,
10
3
  pluralize,
11
4
  stripHtmlToPlainText,
12
5
  truncate
13
- } from "./chunk-7T2WQSWF.js";
14
- import {
15
- EditablePlainText,
16
- ImageDropZone,
17
- MAX_CONTAINER_COLUMNS,
18
- MediaBlock,
19
- colSpanClass,
20
- containerGridClass,
21
- spacerHiddenClass
22
- } from "./chunk-T7MP7ANP.js";
6
+ } from "./chunk-63BQQNZO.js";
23
7
  import {
24
8
  DeleteButton,
25
9
  DragHandle,
@@ -31,11 +15,27 @@ import {
31
15
  buildBlockDropData,
32
16
  canDropBlock,
33
17
  isBlockDragData
34
- } from "./chunk-Q3T23HVW.js";
18
+ } from "./chunk-B2DLHZKC.js";
19
+ import {
20
+ EditableRichText,
21
+ defineHeadingSection
22
+ } from "./chunk-YP7IHMC3.js";
23
+ import {
24
+ EditablePlainText,
25
+ ImageDropZone,
26
+ MAX_CONTAINER_COLUMNS,
27
+ MediaBlock,
28
+ colSpanClass,
29
+ containerGridClass,
30
+ spacerHiddenClass
31
+ } from "./chunk-UUCOJL7O.js";
35
32
  import {
36
33
  useMediaLibrary,
37
34
  useResolvedMedia
38
35
  } from "./chunk-IFHRHV7S.js";
36
+ import {
37
+ embedUrl
38
+ } from "./chunk-Y4JQGO6G.js";
39
39
  import {
40
40
  DEFAULT_LINK,
41
41
  LinkValueSchema
@@ -49,13 +49,13 @@ import {
49
49
  import {
50
50
  getSectionSchema
51
51
  } from "./chunk-TZQPOR5A.js";
52
+ import {
53
+ SingleMediaReferenceSchema
54
+ } from "./chunk-SWIHUIFT.js";
52
55
  import {
53
56
  defineSection,
54
57
  getSection
55
58
  } from "./chunk-VKAGMEKE.js";
56
- import {
57
- SingleMediaReferenceSchema
58
- } from "./chunk-SWIHUIFT.js";
59
59
 
60
60
  // src/components/sections/LinkHeading/index.tsx
61
61
  import { Heading1 } from "lucide-react";
@@ -536,6 +536,7 @@ var ChildBlockWrapper = forwardRef(
536
536
  onDuplicate,
537
537
  onColSpanChange,
538
538
  onOpenSettings,
539
+ clearSectionChrome,
539
540
  children
540
541
  }, ref) {
541
542
  return /* @__PURE__ */ jsxs4(
@@ -548,23 +549,33 @@ var ChildBlockWrapper = forwardRef(
548
549
  "hover:outline hover:outline-2 hover:outline-primary/30"
549
550
  ),
550
551
  children: [
551
- /* @__PURE__ */ jsxs4("div", { className: "absolute top-0 left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none", children: [
552
- /* @__PURE__ */ jsx12("span", { className: "sr-only", children: label }),
553
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DragHandle, { ref: dragHandleRef }) }),
554
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(ColSpanControl, { colSpan, columns, onChange: onColSpanChange }) }),
555
- hasSettings && onOpenSettings && /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(SettingsButton, { onClick: onOpenSettings }) }),
556
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(
557
- "button",
558
- {
559
- type: "button",
560
- "aria-label": "Duplicate block",
561
- onClick: onDuplicate,
562
- className: "cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary",
563
- children: /* @__PURE__ */ jsx12(CopyPlus, { size: 16 })
564
- }
565
- ) }),
566
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DeleteButton, { onDelete }) })
567
- ] }),
552
+ /* @__PURE__ */ jsxs4(
553
+ "div",
554
+ {
555
+ "data-testid": "child-control-rail",
556
+ className: cn(
557
+ "absolute left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none",
558
+ clearSectionChrome ? "top-8 xl:top-0" : "top-0"
559
+ ),
560
+ children: [
561
+ /* @__PURE__ */ jsx12("span", { className: "sr-only", children: label }),
562
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DragHandle, { ref: dragHandleRef }) }),
563
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(ColSpanControl, { colSpan, columns, onChange: onColSpanChange }) }),
564
+ hasSettings && onOpenSettings && /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(SettingsButton, { onClick: onOpenSettings }) }),
565
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(
566
+ "button",
567
+ {
568
+ type: "button",
569
+ "aria-label": "Duplicate block",
570
+ onClick: onDuplicate,
571
+ className: "cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary",
572
+ children: /* @__PURE__ */ jsx12(CopyPlus, { size: 16 })
573
+ }
574
+ ) }),
575
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DeleteButton, { onDelete }) })
576
+ ]
577
+ }
578
+ ),
568
579
  closestEdge === "left" && /* @__PURE__ */ jsx12(
569
580
  "div",
570
581
  {
@@ -764,6 +775,7 @@ function ContainerChild({
764
775
  hasSettings,
765
776
  mergedOptions,
766
777
  isEditMode,
778
+ clearSectionChrome,
767
779
  ChildComp,
768
780
  onDelete,
769
781
  onDuplicate,
@@ -797,6 +809,7 @@ function ContainerChild({
797
809
  closestEdge,
798
810
  isDragging,
799
811
  hasSettings,
812
+ clearSectionChrome,
800
813
  dragHandleRef: handleRef,
801
814
  onDelete,
802
815
  onDuplicate,
@@ -956,6 +969,7 @@ function Container({ content, isEditMode, onChange, openModal }) {
956
969
  hasSettings,
957
970
  mergedOptions,
958
971
  isEditMode,
972
+ clearSectionChrome: index === 0,
959
973
  ChildComp: def.component,
960
974
  onDelete: () => emit(trimTrailingSpacers(removeChildAt(container, index).container)),
961
975
  onDuplicate: () => emit(duplicateChildAt(container, index, newId)),
@@ -969,7 +983,7 @@ function Container({ content, isEditMode, onChange, openModal }) {
969
983
  }
970
984
  const occupied = occupiedColumns(children, columns);
971
985
  const emptyCols = occupied < columns ? columns - occupied : 0;
972
- return /* @__PURE__ */ jsx13("div", { className: "@container", children: /* @__PURE__ */ jsxs5("div", { className: cn(gridClass, "pt-8 xl:pt-0"), children: [
986
+ return /* @__PURE__ */ jsx13("div", { className: "@container", children: /* @__PURE__ */ jsxs5("div", { className: gridClass, children: [
973
987
  children.map(renderEditChild),
974
988
  Array.from({ length: emptyCols }, (_, i) => /* @__PURE__ */ jsx13(
975
989
  EmptyColumnCell,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EditablePlainText
3
- } from "./chunk-T7MP7ANP.js";
3
+ } from "./chunk-UUCOJL7O.js";
4
4
  import {
5
5
  Button,
6
6
  usePages
@@ -0,0 +1,4 @@
1
+ import type { CollabProvider } from "./types";
2
+ export declare function setCollabProvider(p: CollabProvider | null): void;
3
+ export declare function getCollabProvider(): CollabProvider | null;
4
+ //# sourceMappingURL=provider-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../../src/collab/provider-registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAEhE;AAED,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD"}
@@ -0,0 +1,9 @@
1
+ import {
2
+ getCollabProvider,
3
+ setCollabProvider
4
+ } from "../chunk-2G2S36SY.js";
5
+ import "../chunk-JSBRDJBE.js";
6
+ export {
7
+ getCollabProvider,
8
+ setCollabProvider
9
+ };
@@ -0,0 +1,37 @@
1
+ import type { LoadedSection } from "../lib/loader";
2
+ import type { SiteIndex } from "../schemas/site-config";
3
+ export interface RebaseArgs {
4
+ localSections: LoadedSection[];
5
+ localIndex: SiteIndex;
6
+ localIndexDirty: boolean;
7
+ dirtySectionIds: Set<string>;
8
+ /** Section ids created locally since the last clean baseline (i.e. dirty ids
9
+ * absent from the last-loaded saved-branch index). Callers derive this from
10
+ * the cached clean baseline (Dexie contentCache index), NOT from remoteIndex —
11
+ * remote absence is exactly what this field disambiguates: without it, a
12
+ * locally-added unsaved section is indistinguishable from a section deleted
13
+ * remotely while dirty (both dirty, present locally, absent remotely). */
14
+ locallyAddedIds: Set<string>;
15
+ locallyDeletedIds: Set<string>;
16
+ remoteSections: LoadedSection[];
17
+ remoteIndex: SiteIndex;
18
+ remoteChangedIds: Set<string>;
19
+ }
20
+ export interface RebaseResult {
21
+ sections: LoadedSection[];
22
+ index: SiteIndex;
23
+ conflictIds: string[];
24
+ }
25
+ /** Merge a fresh remote (saved-branch) snapshot under local unsaved work.
26
+ * Remote wins everywhere the local editor has no unsaved edits; dirty local
27
+ * sections are kept verbatim; overlaps are reported as conflicts for the
28
+ * caller's keep-mine/take-theirs dialog. Implements the 5 merge rules from
29
+ * the collaboration spec ("conflict-free by construction under lock
30
+ * discipline").
31
+ *
32
+ * Invariants: inputs are never mutated (the returned index is a fresh
33
+ * structure in both branches), and the result partitions: every section in
34
+ * `sections` is reachable from `index`; a dirty section deleted remotely is
35
+ * kept, re-linked into the index, and reported in `conflictIds`. */
36
+ export declare function rebaseContent(args: RebaseArgs): RebaseResult;
37
+ //# sourceMappingURL=rebase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebase.d.ts","sourceRoot":"","sources":["../../src/collab/rebase.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,aAAa,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B;;;;;+EAK2E;IAC3E,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,WAAW,EAAE,SAAS,CAAC;IAKvB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IAIjB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;qEAUqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CA2F5D"}
@@ -0,0 +1,64 @@
1
+ import "../chunk-JSBRDJBE.js";
2
+
3
+ // src/collab/rebase.ts
4
+ function rebaseContent(args) {
5
+ const localById = new Map(args.localSections.map((s) => [s.section.id, s]));
6
+ const remoteIds = new Set(args.remoteSections.map((s) => s.section.id));
7
+ const merged = args.remoteSections.filter((s) => !args.locallyDeletedIds.has(s.section.id)).map((s) => args.dirtySectionIds.has(s.section.id) ? localById.get(s.section.id) ?? s : s);
8
+ for (const id of args.dirtySectionIds) {
9
+ if (remoteIds.has(id) || args.locallyDeletedIds.has(id)) continue;
10
+ const local = localById.get(id);
11
+ if (local) merged.push(local);
12
+ }
13
+ const conflictSet = /* @__PURE__ */ new Set();
14
+ for (const id of args.dirtySectionIds) {
15
+ if (args.locallyDeletedIds.has(id)) continue;
16
+ if (args.remoteChangedIds.has(id)) {
17
+ conflictSet.add(id);
18
+ } else if (localById.has(id) && !(id in args.remoteIndex.sections) && !args.locallyAddedIds.has(id)) {
19
+ conflictSet.add(id);
20
+ }
21
+ }
22
+ const conflictIds = [...conflictSet].sort();
23
+ let index;
24
+ if (!args.localIndexDirty) {
25
+ index = {
26
+ ...args.remoteIndex,
27
+ pages: args.remoteIndex.pages.map((p) => ({ ...p, order: [...p.order] })),
28
+ sections: { ...args.remoteIndex.sections }
29
+ };
30
+ } else {
31
+ const localOrderIds = new Set(args.localIndex.pages.flatMap((p) => p.order));
32
+ const pages = args.localIndex.pages.map((p) => ({
33
+ ...p,
34
+ order: p.order.filter((id) => id in args.remoteIndex.sections || args.dirtySectionIds.has(id))
35
+ }));
36
+ const sections = {};
37
+ for (const [id, meta] of Object.entries(args.localIndex.sections)) {
38
+ if (id in args.remoteIndex.sections || args.dirtySectionIds.has(id)) sections[id] = meta;
39
+ }
40
+ for (const remotePage of args.remoteIndex.pages) {
41
+ for (const id of remotePage.order) {
42
+ if (localOrderIds.has(id) || args.locallyDeletedIds.has(id)) continue;
43
+ const target = pages.find((p) => p.id === remotePage.id) ?? pages[0];
44
+ if (target && !target.order.includes(id)) target.order.push(id);
45
+ sections[id] = args.remoteIndex.sections[id];
46
+ }
47
+ }
48
+ index = { ...args.localIndex, pages, sections };
49
+ }
50
+ for (const s of merged) {
51
+ const id = s.section.id;
52
+ if (id in index.sections) continue;
53
+ const meta = args.localIndex.sections[id] ?? s.meta;
54
+ const localPage = args.localIndex.pages.find((p) => p.order.includes(id));
55
+ const target = (localPage && index.pages.find((p) => p.id === localPage.id)) ?? index.pages[0];
56
+ if (!target) continue;
57
+ if (!target.order.includes(id)) target.order.push(id);
58
+ index.sections[id] = meta;
59
+ }
60
+ return { sections: merged, index, conflictIds };
61
+ }
62
+ export {
63
+ rebaseContent
64
+ };
@@ -0,0 +1,89 @@
1
+ import type { LoadedSection } from "../lib/loader";
2
+ import type { Section, SectionContent } from "../schemas/sections";
3
+ import type { SiteIndex } from "../schemas/site-config";
4
+ /** The last CLEAN saved-branch snapshot (no local dirty overlays folded in).
5
+ * Lifecycle: primed by loadContent, re-primed with the committed snapshot on
6
+ * every successful save, and re-primed with the fetched remote snapshot on
7
+ * every recovery — so it is always the editor's last agreed-with-server state. */
8
+ export interface RecoveryBaseline {
9
+ sections: LoadedSection[];
10
+ index: SiteIndex;
11
+ }
12
+ /** Derive rebaseContent's remoteChangedIds + locallyAddedIds from a clean
13
+ * baseline and the freshly fetched remote snapshot.
14
+ *
15
+ * - remoteChangedIds: sections whose content differs between the clean baseline
16
+ * and the fresh remote. The baseline MUST be clean — diffing against the dirty
17
+ * in-memory view would flag every locally-edited section as remote-changed,
18
+ * turning every dirty section into a false conflict.
19
+ * - locallyAddedIds: dirty ids absent from the clean baseline INDEX — sections
20
+ * created locally and never saved. This is what lets rebase distinguish a
21
+ * local add from a section deleted remotely while dirty.
22
+ *
23
+ * Degraded mode (baseline === null — should be unreachable, since every load,
24
+ * save, and recovery re-primes the cache): fail SAFE, not silent. Every dirty
25
+ * section that still exists remotely is flagged remote-changed (forcing the
26
+ * keep-mine/take-theirs dialog instead of a silent local-wins merge), and every
27
+ * dirty section absent remotely is treated as locally added (kept — a true
28
+ * remote-deletion-while-dirty resurrects instead of conflicting, which loses
29
+ * nothing). This is deliberately NOT derived from the published mainIndex: a
30
+ * main-based baseline would silently local-win every dirty section that already
31
+ * exists on main — the exact lost-update this path exists to prevent. */
32
+ export declare function deriveRecoveryInputs({ baseline, remote, dirtyRows, deletedIds }: {
33
+ baseline: RecoveryBaseline | null;
34
+ remote: {
35
+ sections: LoadedSection[];
36
+ index: SiteIndex;
37
+ };
38
+ dirtyRows: {
39
+ sectionId: string;
40
+ }[];
41
+ deletedIds: Set<string>;
42
+ }): {
43
+ remoteChangedIds: Set<string>;
44
+ locallyAddedIds: Set<string>;
45
+ };
46
+ /** Apply the user's keep-mine/take-theirs choices to a rebase result.
47
+ * Pure — inputs are never mutated. For every conflict the LOCAL copy is
48
+ * returned in `preserved` (the caller snapshots it via preserveEdit so no
49
+ * choice is destructive). "theirs" swaps in the remote section — or, when the
50
+ * remote side DELETED it, removes the section AND strips its id from the index
51
+ * (pages' order + sections map); leaving the dangling index ref would make the
52
+ * server's dangling-ref gate reject every later save. `droppedDirtyIds` lists
53
+ * the "theirs" ids whose local dirty rows must be deleted so the retry doesn't
54
+ * re-send the overridden local content. */
55
+ export declare function applyConflictChoices({ merged, remoteSections, choices }: {
56
+ merged: {
57
+ sections: LoadedSection[];
58
+ index: SiteIndex;
59
+ };
60
+ remoteSections: LoadedSection[];
61
+ choices: Record<string, "mine" | "theirs">;
62
+ }): {
63
+ sections: LoadedSection[];
64
+ index: SiteIndex;
65
+ droppedDirtyIds: string[];
66
+ preserved: {
67
+ sectionId: string;
68
+ section: Section;
69
+ }[];
70
+ };
71
+ /** Build the COMMITTED post-save snapshot for re-priming the clean baseline.
72
+ * The committed content is exactly what performSave sent (savedRows), NOT the
73
+ * current view state — edits typed while the request was in flight must not
74
+ * leak into the "clean" baseline (they are still dirty rows and would otherwise
75
+ * read as remote changes on the next recovery). Base = the previous clean
76
+ * baseline when available (post-recovery it is the fetched remote snapshot);
77
+ * fallback = the loaded sections captured at save start. Ids absent from the
78
+ * sent index (deleted this save) are dropped; saved ids absent from the base
79
+ * (locally added) are appended with their meta from the sent index. */
80
+ export declare function buildCommittedBaseline({ baselineSections, fallbackSections, savedRows, sentIndex }: {
81
+ baselineSections: LoadedSection[] | null;
82
+ fallbackSections: LoadedSection[];
83
+ savedRows: {
84
+ sectionId: string;
85
+ content: SectionContent;
86
+ }[];
87
+ sentIndex: SiteIndex;
88
+ }): LoadedSection[];
89
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../src/collab/recovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;mFAGmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;0EAmB0E;AAC1E,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;IAChF,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE;QAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IACxD,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB,GAAG;IAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CA0BlE;AAED;;;;;;;;4CAQ4C;AAC5C,wBAAgB,oBAAoB,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE;IACxE,MAAM,EAAE;QAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IACxD,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;CAC5C,GAAG;IACF,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CACtD,CA4BA;AAED;;;;;;;;wEAQwE;AACxE,wBAAgB,sBAAsB,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE;IACnG,gBAAgB,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACzC,gBAAgB,EAAE,aAAa,EAAE,CAAC;IAClC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE,EAAE,CAAC;IAC5D,SAAS,EAAE,SAAS,CAAC;CACtB,GAAG,aAAa,EAAE,CAiBlB"}
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ export declare const HEARTBEAT_INTERVAL_MS = 15000;
3
+ export declare const LOCK_STALE_MS = 45000;
4
+ export declare const CollabPeerSchema: z.ZodObject<{
5
+ userId: z.ZodString;
6
+ email: z.ZodString;
7
+ focusSectionId: z.ZodNullable<z.ZodString>;
8
+ heldSectionIds: z.ZodArray<z.ZodString>;
9
+ }, z.core.$strip>;
10
+ export type CollabPeer = z.infer<typeof CollabPeerSchema>;
11
+ export declare const SectionUpdateMessageSchema: z.ZodObject<{
12
+ v: z.ZodLiteral<1>;
13
+ sectionId: z.ZodString;
14
+ content: z.ZodUnknown;
15
+ userId: z.ZodString;
16
+ }, z.core.$strip>;
17
+ export type SectionUpdateMessage = z.infer<typeof SectionUpdateMessageSchema>;
18
+ export declare const IndexUpdateMessageSchema: z.ZodObject<{
19
+ v: z.ZodLiteral<1>;
20
+ index: z.ZodUnknown;
21
+ userId: z.ZodString;
22
+ }, z.core.$strip>;
23
+ export type IndexUpdateMessage = z.infer<typeof IndexUpdateMessageSchema>;
24
+ export declare const TakeoverMessageSchema: z.ZodObject<{
25
+ v: z.ZodLiteral<1>;
26
+ sectionId: z.ZodString;
27
+ byUserId: z.ZodString;
28
+ byEmail: z.ZodString;
29
+ }, z.core.$strip>;
30
+ export type TakeoverMessage = z.infer<typeof TakeoverMessageSchema>;
31
+ export declare const SavedMessageSchema: z.ZodObject<{
32
+ v: z.ZodLiteral<1>;
33
+ newSha: z.ZodString;
34
+ changedSectionIds: z.ZodArray<z.ZodString>;
35
+ deletedSectionIds: z.ZodArray<z.ZodString>;
36
+ source: z.ZodEnum<{
37
+ editor: "editor";
38
+ api: "api";
39
+ }>;
40
+ }, z.core.$strip>;
41
+ export type SavedMessage = z.infer<typeof SavedMessageSchema>;
42
+ export type CollabStatus = "connecting" | "connected" | "offline";
43
+ /** Opaque server-minted connection blob. Provider-specific keys ride along;
44
+ * primitives only reads the three identity fields. */
45
+ export interface CollabBootstrap {
46
+ siteId: string;
47
+ userId: string;
48
+ email: string;
49
+ [key: string]: unknown;
50
+ }
51
+ export interface CollabEvents {
52
+ onPeers(peers: CollabPeer[]): void;
53
+ onSectionUpdate(msg: SectionUpdateMessage): void;
54
+ onIndexUpdate(msg: IndexUpdateMessage): void;
55
+ onTakeover(msg: TakeoverMessage): void;
56
+ onSaved(msg: SavedMessage): void;
57
+ onStatus(status: CollabStatus): void;
58
+ }
59
+ /** A live connection to one site channel. The session owns the held-lock set
60
+ * (heartbeats them every HEARTBEAT_INTERVAL_MS and includes them in its
61
+ * presence payload). acquireLock({steal:true}) also emits the takeover
62
+ * broadcast on success. */
63
+ export interface CollabSession {
64
+ setFocus(sectionId: string | null): void;
65
+ acquireLock(sectionId: string, opts?: {
66
+ steal?: boolean;
67
+ }): Promise<boolean>;
68
+ releaseLocks(sectionIds: string[]): Promise<void>;
69
+ broadcastSectionUpdate(sectionId: string, content: unknown): void;
70
+ broadcastIndexUpdate(index: unknown): void;
71
+ disconnect(): Promise<void>;
72
+ }
73
+ export interface SavedBroadcast {
74
+ newSha: string;
75
+ changedSectionIds: string[];
76
+ deletedSectionIds: string[];
77
+ source: "editor" | "api";
78
+ }
79
+ export interface CollabProvider {
80
+ /** Browser: join the site channel. Resolves null when collaboration is
81
+ * unavailable (no session, join refused) — caller runs solo-mode. */
82
+ connect(bootstrap: CollabBootstrap, events: CollabEvents): Promise<CollabSession | null>;
83
+ /** Server: mint the browser bootstrap for an authenticated editor session,
84
+ * or null when the provider can't support collab (e.g. missing env). */
85
+ getBootstrap(args: {
86
+ siteId: string;
87
+ userId: string;
88
+ email: string;
89
+ }): CollabBootstrap | null;
90
+ /** Server: post-commit fan-out of a successful save to all connected editors. */
91
+ broadcastSaved(siteId: string, event: SavedBroadcast): Promise<void>;
92
+ }
93
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/collab/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import {
2
+ CollabPeerSchema,
3
+ HEARTBEAT_INTERVAL_MS,
4
+ IndexUpdateMessageSchema,
5
+ LOCK_STALE_MS,
6
+ SavedMessageSchema,
7
+ SectionUpdateMessageSchema,
8
+ TakeoverMessageSchema
9
+ } from "../chunk-REM2NH7K.js";
10
+ import "../chunk-JSBRDJBE.js";
11
+ export {
12
+ CollabPeerSchema,
13
+ HEARTBEAT_INTERVAL_MS,
14
+ IndexUpdateMessageSchema,
15
+ LOCK_STALE_MS,
16
+ SavedMessageSchema,
17
+ SectionUpdateMessageSchema,
18
+ TakeoverMessageSchema
19
+ };
@@ -3,7 +3,9 @@ interface AudienceIndicatorProps {
3
3
  access: string[];
4
4
  audiences: Audience[];
5
5
  onChange: (access: string[]) => void;
6
+ /** Display-only mode — the pill still shows audiences but the picker never opens. */
7
+ disabled?: boolean;
6
8
  }
7
- export declare function AudienceIndicator({ access, audiences, onChange }: AudienceIndicatorProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function AudienceIndicator({ access, audiences, onChange, disabled }: AudienceIndicatorProps): import("react/jsx-runtime").JSX.Element;
8
10
  export {};
9
11
  //# sourceMappingURL=AudienceIndicator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AudienceIndicator.d.ts","sourceRoot":"","sources":["../../../src/components/editor/AudienceIndicator.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,sBAAsB,2CAkExF"}
1
+ {"version":3,"file":"AudienceIndicator.d.ts","sourceRoot":"","sources":["../../../src/components/editor/AudienceIndicator.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,qFAAqF;IACrF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,sBAAsB,2CAmElG"}
@@ -13,6 +13,13 @@ export interface ChildBlockWrapperProps {
13
13
  onDuplicate: () => void;
14
14
  onColSpanChange: (span: number) => void;
15
15
  onOpenSettings?: () => void;
16
+ /**
17
+ * Below xl the parent SECTION's "+" hangs down into the left gutter where this
18
+ * rail starts — set on the container's first cell so the rail (not the cell)
19
+ * shifts down out of the collision. Cells never move: edit-mode layout must
20
+ * match view mode exactly.
21
+ */
22
+ clearSectionChrome?: boolean;
16
23
  children: ReactNode;
17
24
  }
18
25
  export declare const ChildBlockWrapper: import("react").ForwardRefExoticComponent<ChildBlockWrapperProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"ChildBlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/editor/ChildBlockWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uDAAuD,CAAC;AAQlF,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,mHAkF7B,CAAC"}
1
+ {"version":3,"file":"ChildBlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/editor/ChildBlockWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uDAAuD,CAAC;AAQlF,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,mHAyF7B,CAAC"}