@plitzi/sdk-shared 0.37.9 → 0.38.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.
Files changed (135) hide show
  1. package/CHANGELOG.md +601 -0
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.mjs +3 -3
  4. package/dist/actions/triggerParams.mjs +7 -6
  5. package/dist/actions/validateDocument.d.ts +3 -0
  6. package/dist/actions/validateDocument.mjs +89 -88
  7. package/dist/authoring/elementCallbacks.d.ts +65 -0
  8. package/dist/authoring/elementCallbacks.mjs +72 -8
  9. package/dist/authoring/index.mjs +3 -3
  10. package/dist/builder/contexts/BuilderContext.d.ts +18 -7
  11. package/dist/connectors/index.d.ts +1 -1
  12. package/dist/connectors/index.mjs +2 -2
  13. package/dist/connectors/validateManifest.d.ts +3 -0
  14. package/dist/connectors/validateManifest.mjs +77 -76
  15. package/dist/dataSource/computed.mjs +25 -29
  16. package/dist/dataSource/globalSources.d.ts +15 -0
  17. package/dist/dataSource/globalSources.mjs +13 -0
  18. package/dist/dataSource/index.d.ts +2 -0
  19. package/dist/dataSource/index.mjs +8 -7
  20. package/dist/devTools/utils/PlitziConsole.d.ts +9 -0
  21. package/dist/devTools/utils/PlitziConsole.mjs +27 -7
  22. package/dist/flags/flagsCookie.d.ts +26 -0
  23. package/dist/flags/flagsCookie.mjs +20 -0
  24. package/dist/flags/index.d.ts +3 -0
  25. package/dist/flags/index.mjs +4 -0
  26. package/dist/flags/resolveFlags.d.ts +60 -0
  27. package/dist/flags/resolveFlags.mjs +38 -0
  28. package/dist/flags/schemaFlag.d.ts +11 -0
  29. package/dist/flags/schemaFlag.mjs +9 -0
  30. package/dist/flags/useFlagResolution.d.ts +13 -0
  31. package/dist/flags/useFlagResolution.mjs +43 -0
  32. package/dist/helpers/eventTarget.d.ts +10 -0
  33. package/dist/helpers/eventTarget.mjs +4 -0
  34. package/dist/helpers/images.d.ts +18 -0
  35. package/dist/helpers/images.mjs +13 -0
  36. package/dist/helpers/index.d.ts +3 -0
  37. package/dist/helpers/index.mjs +21 -18
  38. package/dist/helpers/interval.d.ts +18 -0
  39. package/dist/helpers/interval.mjs +7 -0
  40. package/dist/helpers/isRecord.d.ts +2 -0
  41. package/dist/helpers/isRecord.mjs +4 -0
  42. package/dist/helpers/scroll.d.ts +42 -0
  43. package/dist/helpers/scroll.mjs +30 -0
  44. package/dist/helpers/twigWrapper/TemplateCache/TemplateCache.mjs +1 -1
  45. package/dist/helpers/twigWrapper/filters/filters.mjs +38 -2
  46. package/dist/history/describe.mjs +3 -1
  47. package/dist/history/diff.d.ts +1 -1
  48. package/dist/history/diff.mjs +1 -0
  49. package/dist/history/types.d.ts +1 -1
  50. package/dist/hooks/index.mjs +5 -5
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.mjs +90 -76
  53. package/dist/navigation/routes.mjs +6 -4
  54. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.d.ts +2 -0
  55. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.mjs +4 -0
  56. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.d.ts +12 -0
  57. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.mjs +4 -0
  58. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.d.ts +2 -0
  59. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.mjs +4 -0
  60. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.d.ts +3 -0
  61. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.mjs +4 -0
  62. package/dist/network/graphql/builder/Mutations/index.d.ts +5 -1
  63. package/dist/network/graphql/builder/Mutations/index.mjs +122 -116
  64. package/dist/network/graphql/builder/Queries/InitQuery.d.ts +3 -1
  65. package/dist/network/graphql/builder/Queries/InitQuery.mjs +1 -1
  66. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.d.ts +16 -2
  67. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.mjs +1 -1
  68. package/dist/network/graphql/builder/Queries/index.d.ts +1 -1
  69. package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +1 -1
  70. package/dist/network/graphql/sdk/Queries/InitQuery.mjs +1 -1
  71. package/dist/network/index.mjs +8 -7
  72. package/dist/network/spaceEvents.d.ts +12 -6
  73. package/dist/network/spaceEvents.mjs +153 -154
  74. package/dist/realtime/client.mjs +123 -95
  75. package/dist/realtime/topics.mjs +18 -17
  76. package/dist/schema/anchor.d.ts +8 -0
  77. package/dist/schema/anchor.mjs +4 -0
  78. package/dist/schema/index.d.ts +2 -0
  79. package/dist/schema/index.mjs +6 -4
  80. package/dist/schema/serverElements.d.ts +6 -2
  81. package/dist/schema/serverElements.mjs +17 -16
  82. package/dist/schema/snippet.d.ts +7 -0
  83. package/dist/schema/snippet.mjs +9 -0
  84. package/dist/schema/wire.d.ts +11 -0
  85. package/dist/schema/wire.mjs +27 -0
  86. package/dist/server/actions/useImagesSync.d.ts +9 -0
  87. package/dist/server/actions/useImagesSync.mjs +7 -0
  88. package/dist/server/rsc/refreshRsc.mjs +8 -8
  89. package/dist/source/snapshot.mjs +23 -22
  90. package/dist/state/paintedState.mjs +13 -12
  91. package/dist/state/runtimeStatePersist.mjs +50 -49
  92. package/dist/store/index.d.ts +45 -45
  93. package/dist/style/breakpoints.d.ts +11 -0
  94. package/dist/style/breakpoints.mjs +8 -0
  95. package/dist/style/displayModes.d.ts +5 -0
  96. package/dist/style/displayModes.mjs +8 -0
  97. package/dist/style/fontValidation.mjs +52 -51
  98. package/dist/style/fonts.d.ts +0 -12
  99. package/dist/style/fonts.mjs +11 -11
  100. package/dist/style/index.d.ts +4 -0
  101. package/dist/style/index.mjs +11 -7
  102. package/dist/style/layoutGrid.d.ts +30 -0
  103. package/dist/style/layoutGrid.mjs +33 -0
  104. package/dist/style/notifications.d.ts +52 -0
  105. package/dist/style/notifications.mjs +55 -0
  106. package/dist/style/snippetStyle.d.ts +23 -0
  107. package/dist/style/snippetStyle.mjs +32 -0
  108. package/dist/style/styleConstants.d.ts +7 -2
  109. package/dist/style/styleConstants.mjs +10 -0
  110. package/dist/style/styleStates.d.ts +11 -2
  111. package/dist/style/styleStates.mjs +12 -9
  112. package/dist/theme/ThemeProvider.mjs +20 -20
  113. package/dist/types/CommonTypes.d.ts +3 -0
  114. package/dist/types/DevToolsTypes.d.ts +29 -4
  115. package/dist/types/EventBridgeTypes.d.ts +2 -2
  116. package/dist/types/PluginTypes.d.ts +1 -1
  117. package/dist/types/ResourceTypes.d.ts +2 -2
  118. package/dist/types/SchemaTypes.d.ts +62 -3
  119. package/dist/types/ServerTypes.d.ts +47 -0
  120. package/dist/types/SnippetTypes.d.ts +28 -0
  121. package/dist/types/StoreTypes.d.ts +25 -0
  122. package/dist/types/StyleTypes.d.ts +2 -1
  123. package/dist/types/StyleTypes.mjs +2 -2
  124. package/dist/types/index.d.ts +1 -1
  125. package/dist/types/index.mjs +2 -2
  126. package/dist/websockets/RTCodec.d.ts +1 -0
  127. package/dist/websockets/RTCodec.mjs +14 -12
  128. package/dist/websockets/index.mjs +2 -2
  129. package/package.json +115 -19
  130. package/tailwind.config.js +1 -6
  131. package/vite.config.ts +16 -4
  132. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.d.ts +0 -2
  133. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.mjs +0 -4
  134. package/dist/types/TemplateTypes.d.ts +0 -20
  135. /package/dist/types/{TemplateTypes.mjs → SnippetTypes.mjs} +0 -0
@@ -102,6 +102,11 @@ declare const styleConstants: {
102
102
  readonly APPEARANCE: "appearance";
103
103
  readonly SCROLL_BEHAVIOR: "scroll-behavior";
104
104
  readonly OVERSCROLL_BEHAVIOR: "overscroll-behavior";
105
+ readonly SCROLL_SNAP_TYPE: "scroll-snap-type";
106
+ readonly SCROLL_SNAP_ALIGN: "scroll-snap-align";
107
+ readonly SCROLL_SNAP_STOP: "scroll-snap-stop";
108
+ readonly SCROLL_PADDING_TOP: "scroll-padding-top";
109
+ readonly SCROLL_MARGIN_TOP: "scroll-margin-top";
105
110
  readonly ACCENT_COLOR: "accent-color";
106
111
  readonly CARET_COLOR: "caret-color";
107
112
  readonly COLOR_SCHEME: "color-scheme";
@@ -177,8 +182,8 @@ declare const styleConstants: {
177
182
  };
178
183
  export declare const inheritableAttributesBase: StyleCategory[];
179
184
  export declare const StyleBindingsAllowed: {
180
- path: "color" | "cursor" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "filter" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "perspective" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "fill" | "stroke" | "stroke-width";
181
- label: "color" | "cursor" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "filter" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "perspective" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "fill" | "stroke" | "stroke-width";
185
+ path: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "perspective" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "stroke" | "stroke-width";
186
+ label: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "perspective" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "stroke" | "stroke-width";
182
187
  }[];
183
188
  export declare const baseDefaultValue: Record<StyleCategory, StyleValue>;
184
189
  export default styleConstants;
@@ -115,6 +115,11 @@ var e = {
115
115
  APPEARANCE: "appearance",
116
116
  SCROLL_BEHAVIOR: "scroll-behavior",
117
117
  OVERSCROLL_BEHAVIOR: "overscroll-behavior",
118
+ SCROLL_SNAP_TYPE: "scroll-snap-type",
119
+ SCROLL_SNAP_ALIGN: "scroll-snap-align",
120
+ SCROLL_SNAP_STOP: "scroll-snap-stop",
121
+ SCROLL_PADDING_TOP: "scroll-padding-top",
122
+ SCROLL_MARGIN_TOP: "scroll-margin-top",
118
123
  ACCENT_COLOR: "accent-color",
119
124
  CARET_COLOR: "caret-color",
120
125
  COLOR_SCHEME: "color-scheme",
@@ -315,6 +320,11 @@ var e = {
315
320
  [t.APPEARANCE]: "none",
316
321
  [t.SCROLL_BEHAVIOR]: "auto",
317
322
  [t.OVERSCROLL_BEHAVIOR]: "auto",
323
+ [t.SCROLL_SNAP_TYPE]: "none",
324
+ [t.SCROLL_SNAP_ALIGN]: "none",
325
+ [t.SCROLL_SNAP_STOP]: "normal",
326
+ [t.SCROLL_PADDING_TOP]: "auto",
327
+ [t.SCROLL_MARGIN_TOP]: "0px",
318
328
  [t.ACCENT_COLOR]: "auto",
319
329
  [t.CARET_COLOR]: "auto",
320
330
  [t.COLOR_SCHEME]: "normal",
@@ -7,11 +7,15 @@
7
7
  * `focus-visible` is the focus ring a keyboard user needs and a mouse user does not; `focus-within` dresses a
8
8
  * container while anything inside it has focus — a field wrapper around its input.
9
9
  *
10
+ * `current` is the link to the page being shown — the navigation item of where the visitor is. The link says so itself
11
+ * (`aria-current="page"`, what a screen reader announces too), so a header written once in a layout marks the right item
12
+ * on every page, which a class chosen per page could not.
13
+ *
10
14
  * `hidden` is not a pseudo-class: it is how an element looks while its `visible` says no — where it goes as it hides,
11
15
  * and where it comes from as it shows. With a transition on the class (`display` among what it transitions, and
12
16
  * `transition-behavior: allow-discrete`), a panel fades or slides in and out instead of blinking.
13
17
  */
14
- export declare const STYLE_STATES: readonly ["hover", "focus", "focus-visible", "focus-within", "active", "disabled", "checked", "visited", "hidden"];
18
+ export declare const STYLE_STATES: readonly ["hover", "focus", "focus-visible", "focus-within", "active", "disabled", "checked", "visited", "current", "hidden"];
15
19
  /** What the SDK puts on an element whose `visible` says no: `display: none`, and what the `hidden` state selects. */
16
20
  export declare const HIDDEN_CLASS = "plitzi-component--hidden";
17
21
  export declare const STYLE_STATE_LABELS: Record<(typeof STYLE_STATES)[number], string>;
@@ -21,7 +25,12 @@ export declare const isKnownState: (state: string) => state is (typeof STYLE_STA
21
25
  * A state outside the list keeps its place after the known ones.
22
26
  */
23
27
  export declare const inCascadeOrder: <T>(states: Record<string, T>) => [string, T][];
24
- /** How a state is written after the selector it modifies: its pseudo-class, or for `hidden` the class that hides. */
28
+ /** What a link to the page being shown carries, and what the `current` state selects. */
29
+ export declare const CURRENT_PAGE_SELECTOR = "[aria-current=\"page\"]";
30
+ /**
31
+ * How a state is written after the selector it modifies: its pseudo-class — or, for `hidden`, the class that hides, and
32
+ * for `current`, the attribute a link to this page carries.
33
+ */
25
34
  export declare const stateSuffix: (state: string) => string;
26
35
  /**
27
36
  * Whether a state is also where an element starts from as it appears (`@starting-style`): `hidden` is — a panel that
@@ -8,6 +8,7 @@ var e = [
8
8
  "disabled",
9
9
  "checked",
10
10
  "visited",
11
+ "current",
11
12
  "hidden"
12
13
  ], t = "plitzi-component--hidden", n = {
13
14
  hover: "Hover",
@@ -18,17 +19,19 @@ var e = [
18
19
  disabled: "Disabled",
19
20
  checked: "Checked",
20
21
  visited: "Visited",
22
+ current: "Current page",
21
23
  hidden: "Hidden"
22
24
  }, r = {
23
25
  visited: 0,
24
26
  checked: 1,
25
- "focus-within": 2,
26
- hover: 3,
27
- focus: 4,
28
- "focus-visible": 5,
29
- active: 6,
30
- disabled: 7,
31
- hidden: 8
32
- }, i = (e) => Object.hasOwn(r, e), a = (t) => i(t) ? r[t] : e.length, o = (e) => Object.entries(e).sort(([e], [t]) => a(e) - a(t)), s = (e) => e === "hidden" ? `.${t}` : `:${e}`, c = (e) => e === "hidden";
27
+ current: 2,
28
+ "focus-within": 3,
29
+ hover: 4,
30
+ focus: 5,
31
+ "focus-visible": 6,
32
+ active: 7,
33
+ disabled: 8,
34
+ hidden: 9
35
+ }, i = (e) => Object.hasOwn(r, e), a = (t) => i(t) ? r[t] : e.length, o = (e) => Object.entries(e).sort(([e], [t]) => a(e) - a(t)), s = "[aria-current=\"page\"]", c = (e) => e === "hidden" ? `.${t}` : e === "current" ? s : `:${e}`, l = (e) => e === "hidden";
33
36
  //#endregion
34
- export { t as HIDDEN_CLASS, e as STYLE_STATES, n as STYLE_STATE_LABELS, o as inCascadeOrder, i as isKnownState, c as isStartingState, s as stateSuffix };
37
+ export { s as CURRENT_PAGE_SELECTOR, t as HIDDEN_CLASS, e as STYLE_STATES, n as STYLE_STATE_LABELS, o as inCascadeOrder, i as isKnownState, l as isStartingState, c as stateSuffix };
@@ -1,48 +1,48 @@
1
- import { THEME_COOKIE_NAME as e, applyThemeClass as t, readThemeCookie as n, writeThemeCookie as r } from "./themeCookie.mjs";
2
- import i, { createThemeStore as a, resolveScheme as o, setMachineScheme as s, setThemeMode as c } from "./themeStore.mjs";
3
- import l from "./ThemeScope.mjs";
4
- import { useCommonStoreSync as u } from "../store/index.mjs";
1
+ import { useCommonStoreSync as e } from "../store/index.mjs";
2
+ import { THEME_COOKIE_NAME as t, applyThemeClass as n, readThemeCookie as r, writeThemeCookie as i } from "./themeCookie.mjs";
3
+ import a, { createThemeStore as o, resolveScheme as s, setMachineScheme as c, setThemeMode as l } from "./themeStore.mjs";
4
+ import u from "./ThemeScope.mjs";
5
5
  import { use as d, useEffect as f, useId as p, useRef as m, useState as h, useSyncExternalStore as g } from "react";
6
6
  import { StoreContext as _, useIsomorphicLayoutEffect as v } from "@plitzi/nexus/react";
7
7
  import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
8
8
  //#region src/theme/ThemeProvider.tsx
9
- var S = "(prefers-color-scheme: dark)", C = () => window.matchMedia(S).matches ? "dark" : "light", w = ({ state: e }) => (u([
9
+ var S = "(prefers-color-scheme: dark)", C = () => window.matchMedia(S).matches ? "dark" : "light", w = ({ state: t }) => (e([
10
10
  "theme.mode",
11
11
  "theme.resolved",
12
12
  "theme.areas"
13
13
  ], [
14
- e.mode,
15
- o(e.mode, e.scheme),
16
- e.areas
17
- ]), null), T = ({ defaultTheme: o = "system", theme: u, scope: T = "document", cookieName: E = e, children: D }) => {
18
- let O = T === "container", k = p(), [A] = h(() => O ? a(`theme${k}`) : void 0), j = A ?? i, M = m({
19
- mode: o,
14
+ t.mode,
15
+ s(t.mode, t.scheme),
16
+ t.areas
17
+ ]), null), T = ({ defaultTheme: e = "system", theme: s, scope: T = "document", cookieName: E = t, children: D }) => {
18
+ let O = T === "container", k = p(), [A] = h(() => O ? o(`theme${k}`) : void 0), j = A ?? a, M = m({
19
+ mode: e,
20
20
  remembered: !1
21
21
  });
22
22
  v(() => {
23
- let e = O ? void 0 : n(E), t = u ?? e ?? o;
23
+ let t = O ? void 0 : r(E), n = s ?? t ?? e;
24
24
  M.current = {
25
- mode: t,
26
- remembered: e !== void 0
25
+ mode: n,
26
+ remembered: t !== void 0
27
27
  }, j.batch(() => {
28
- s(C(), j), c(t, j);
28
+ c(C(), j), l(n, j);
29
29
  });
30
30
  }, [
31
- o,
32
- u,
31
+ e,
32
+ s,
33
33
  E,
34
34
  O,
35
35
  j
36
36
  ]);
37
37
  let N = g(j.subscribe, j.getState, j.getState), P = d(_) !== void 0;
38
38
  f(() => {
39
- let e = window.matchMedia(S), t = () => s(e.matches ? "dark" : "light", j);
39
+ let e = window.matchMedia(S), t = () => c(e.matches ? "dark" : "light", j);
40
40
  return e.addEventListener("change", t), t(), () => e.removeEventListener("change", t);
41
41
  }, [j]), f(() => {
42
42
  if (O) return;
43
43
  let e = () => {
44
44
  let { mode: e } = j.getState();
45
- (M.current.remembered || e !== M.current.mode) && (r(e, E), M.current.remembered = !0), t(e, document.documentElement);
45
+ (M.current.remembered || e !== M.current.mode) && (i(e, E), M.current.remembered = !0), n(e, document.documentElement);
46
46
  };
47
47
  return e(), j.subscribe(e);
48
48
  }, [
@@ -51,7 +51,7 @@ var S = "(prefers-color-scheme: dark)", C = () => window.matchMedia(S).matches ?
51
51
  j
52
52
  ]);
53
53
  let F = P ? /* @__PURE__ */ b(w, { state: N }) : null;
54
- return O ? /* @__PURE__ */ x(l, {
54
+ return O ? /* @__PURE__ */ x(u, {
55
55
  value: A,
56
56
  children: [F, D]
57
57
  }) : /* @__PURE__ */ x(y, { children: [F, D] });
@@ -50,6 +50,9 @@ export type ServerSSR = {
50
50
  realtimePath?: string;
51
51
  /** How pages connect to them — a stream (`sse`, when absent) or a socket (`websocket`). */
52
52
  realtimeTransport?: RealtimeTransport;
53
+ /** Path where this origin resizes remote pictures. Published only by a server that mounts the endpoint: its absence
54
+ * is what keeps an image on its own `src` in the builder, an embed or a project with no page server. */
55
+ imagePath?: string;
53
56
  /** Channel the SSR render writes its response into (status, redirect). Server-side only and by reference: it never
54
57
  * crosses to the browser, and nothing subscribes to it. */
55
58
  renderResult?: SSRRenderResult;
@@ -1,9 +1,11 @@
1
1
  import { InteractionNode, InteractionStatus } from './InteractionTypes';
2
2
  import { NavigationStatus } from './NavigationTypes';
3
+ import { RealtimeMessage, RealtimeTransport } from './RealtimeTypes';
3
4
  import { ElementInteraction } from './SchemaTypes';
5
+ import { RealtimeStatus } from '../realtime/client';
4
6
  import { ReactNode } from 'react';
5
7
  export type LogType = 'info' | 'warning' | 'danger' | 'success' | 'custom';
6
- export type LogCategory = 'navigation' | 'interactions' | 'store' | 'network' | 'actions';
8
+ export type LogCategory = 'navigation' | 'interactions' | 'store' | 'network' | 'actions' | 'realtime';
7
9
  export type LogNavigation = {
8
10
  category: 'navigation';
9
11
  params: {
@@ -93,10 +95,33 @@ export type LogNetwork = {
93
95
  payload?: unknown;
94
96
  };
95
97
  };
96
- export type LogParams = LogNavigation['params'] | LogInteraction['params'] | LogEventBridge['params'] | LogStore['params'] | LogNetwork['params'] | LogAction['params'];
98
+ /** What the page's realtime connection did: opened or dropped, a message in or out, a topic the server refused. */
99
+ export type LogRealtime = {
100
+ category: 'realtime';
101
+ params: {
102
+ event: 'status';
103
+ status: RealtimeStatus;
104
+ topics: string[];
105
+ transport: RealtimeTransport;
106
+ } | {
107
+ event: 'received';
108
+ message: RealtimeMessage;
109
+ } | {
110
+ event: 'published';
111
+ topic: string;
112
+ type: string;
113
+ data: unknown;
114
+ delivered: boolean;
115
+ } | {
116
+ event: 'refused';
117
+ topic: string;
118
+ reason: string;
119
+ };
120
+ };
121
+ export type LogParams = LogNavigation['params'] | LogInteraction['params'] | LogEventBridge['params'] | LogStore['params'] | LogNetwork['params'] | LogAction['params'] | LogRealtime['params'];
97
122
  export type Log = {
98
- logType: string;
123
+ logType: LogType;
99
124
  message: ReactNode;
100
125
  time?: string;
101
- } & (LogInteraction | LogNavigation | LogEventBridge | LogStore | LogNetwork | LogAction);
126
+ } & (LogInteraction | LogNavigation | LogEventBridge | LogStore | LogNetwork | LogAction | LogRealtime);
102
127
  export type ProviderCallback = (...args: unknown[]) => Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
  export type EventBridgeContextValue<T = any> = {
2
2
  eventBridge: T;
3
3
  };
4
- export type EventBridgeModule = 'main' | 'builder' | 'template' | 'interaction' | 'element';
5
- export type EventBridgeEvent = 'schemaAddPage' | 'schemaHomePage' | 'schemaUpdatePage' | 'schemaRemovePage' | 'schemaAddPageFolder' | 'schemaUpdatePageFolder' | 'schemaRemovePageFolder' | 'schemaUpdateSettings' | 'schemaUpdate' | 'schemaAddElement' | 'schemaUpdateElement' | 'schemaRenameElement' | 'schemaUpdateElements' | 'schemaRemoveElement' | 'schemaMoveElement' | 'schemaCloneElement' | 'schemaAddVariable' | 'schemaUpdateVariable' | 'schemaRemoveVariable' | 'schemaAddTemplate' | 'schemaAddComponent' | 'schemaUpdateComponent' | 'schemaRemoveComponent' | 'schemaDetachInstance' | 'styleUpdate' | 'styleAddSelector' | 'styleUpdateSelector' | 'styleRemoveSelector' | 'styleRemoveSelectors' | 'styleAddSelectorVariable' | 'styleUpdateSelectorVariable' | 'styleRemoveSelectorVariable' | 'styleAddVariable' | 'styleUpdateVariable' | 'styleRemoveVariable' | 'styleAddFont' | 'styleUpdateFont' | 'styleRemoveFont' | 'styleAddTemplate' | 'styleUpdateSettings' | 'builderSetBaseContext' | 'builderSetSelected' | 'builderSetHovered';
4
+ export type EventBridgeModule = 'main' | 'builder' | 'snippet' | 'interaction' | 'element';
5
+ export type EventBridgeEvent = 'schemaAddPage' | 'schemaHomePage' | 'schemaUpdatePage' | 'schemaRemovePage' | 'schemaAddPageFolder' | 'schemaUpdatePageFolder' | 'schemaRemovePageFolder' | 'schemaUpdateSettings' | 'schemaUpdate' | 'schemaAddElement' | 'schemaUpdateElement' | 'schemaRenameElement' | 'schemaUpdateElements' | 'schemaRemoveElement' | 'schemaMoveElement' | 'schemaCloneElement' | 'schemaAddVariable' | 'schemaUpdateVariable' | 'schemaRemoveVariable' | 'schemaSetFlag' | 'schemaRemoveFlag' | 'schemaAddSnippet' | 'schemaAddComponent' | 'schemaUpdateComponent' | 'schemaRemoveComponent' | 'schemaDetachInstance' | 'styleUpdate' | 'styleAddSelector' | 'styleUpdateSelector' | 'styleRemoveSelector' | 'styleRemoveSelectors' | 'styleAddSelectorVariable' | 'styleUpdateSelectorVariable' | 'styleRemoveSelectorVariable' | 'styleAddVariable' | 'styleUpdateVariable' | 'styleRemoveVariable' | 'styleAddFont' | 'styleUpdateFont' | 'styleRemoveFont' | 'styleAddSnippet' | 'styleUpdateSettings' | 'builderSetBaseContext' | 'builderSetSelected' | 'builderSetHovered';
@@ -61,7 +61,7 @@ export type PluginBuilder = {
61
61
  canDragDrop?: boolean;
62
62
  canSelect?: boolean;
63
63
  canMove?: boolean;
64
- canTemplate?: boolean;
64
+ canSnippet?: boolean;
65
65
  itemsAllowed?: string[];
66
66
  itemsNotAllowed?: string[];
67
67
  };
@@ -1,7 +1,7 @@
1
1
  import { PluginManifest } from './PluginTypes';
2
2
  import { SpaceCredential } from './SpaceTypes';
3
3
  /** `server`: a file of the space's server code — its functions or runtime — in a private bucket. */
4
- export type ResourceType = 'image' | 'video' | 'document' | 'application' | 'plugin' | 'template' | 'server';
4
+ export type ResourceType = 'image' | 'video' | 'document' | 'application' | 'plugin' | 'snippet' | 'server';
5
5
  export type Resource = {
6
6
  id: string;
7
7
  cdnIdentifier: string;
@@ -33,7 +33,7 @@ export type ResourceFile = File & {
33
33
  metadata?: PluginManifest;
34
34
  };
35
35
  /**
36
- * Who may read a bucket's files. `public`: anybody, at its domain — plugins, images, templates. `private`: only the
36
+ * Who may read a bucket's files. `public`: anybody, at its domain — plugins, images, snippets. `private`: only the
37
37
  * platform, with its CDN's credential — the space's server code. A private bucket has no domain.
38
38
  */
39
39
  export type CdnVisibility = 'public' | 'private';
@@ -1,6 +1,6 @@
1
1
  import { InteractionCallbackParamValues, InteractionCallbackType } from './InteractionTypes';
2
2
  import { ChannelDeclarations } from './RealtimeTypes';
3
- import { Style } from './StyleTypes';
3
+ import { SnippetStyle } from './SnippetTypes';
4
4
  import { BuiltinParam } from '../authoring/paramSpec';
5
5
  import { RuleGroup } from '@plitzi/plitzi-ui/QueryBuilder';
6
6
  export type ElementRuntime = 'server' | 'client' | 'shared';
@@ -71,6 +71,20 @@ export type ElementInteraction<T extends Record<string, unknown> = Record<string
71
71
  /** On a trigger only: what a firing does while this flow is still running. `skip` when absent. */
72
72
  whileRunning?: WhileRunning;
73
73
  };
74
+ /**
75
+ * What a feature flag gates an element on: it exists only while the flag `name` resolves to `is`.
76
+ *
77
+ * Not a visibility. A hidden element is still rendered, its markup still in the page; a gated one whose flag says no
78
+ * is not rendered at all — not on the server, not in the browser, not its subtree — and the data of its server
79
+ * elements is not resolved. Its declaration still travels with the space's document, as every element's does, so a
80
+ * flag switches a feature off; it does not keep it secret. `is: false` is the other half of a rollout: the old
81
+ * version, shown until the flag turns on.
82
+ * On a page, a flag that says no makes the page not found.
83
+ */
84
+ export type ElementFlagGate = {
85
+ name: string;
86
+ is: boolean;
87
+ };
74
88
  export type ElementDefinition = {
75
89
  rootId: Element['id'];
76
90
  label: string;
@@ -93,6 +107,13 @@ export type ElementDefinition = {
93
107
  runtime?: ElementRuntime;
94
108
  /** When this element's items are mounted, relative to its `visibility`. See {@link ElementLoadStrategy}. */
95
109
  loadStrategy?: ElementLoadStrategy;
110
+ /** The feature flag this element exists under. See {@link ElementFlagGate}. */
111
+ flag?: ElementFlagGate;
112
+ /**
113
+ * The `id` this element carries in the DOM, so a link to `/page#anchor` lands on it — `data-id` names the element
114
+ * for the platform, this names it for the URL. One per rendered page, layouts included (`isAnchor`).
115
+ */
116
+ anchor?: string;
96
117
  };
97
118
  /**
98
119
  * An element, keyed by the one name it answers to.
@@ -120,6 +141,28 @@ type SchemaVariableBase<TType extends string, TValue> = {
120
141
  }[];
121
142
  };
122
143
  export type SchemaVariable = SchemaVariableBase<'number', number> | SchemaVariableBase<'checkbox' | 'switch', boolean> | SchemaVariableBase<'text' | 'email' | 'password' | 'select' | 'select2' | 'textarea' | 'color', string>;
144
+ /** A value a flag takes where its `when` matches. The first rule that matches decides. */
145
+ export type SchemaFlagRule = {
146
+ when: RuleGroup;
147
+ value: boolean;
148
+ };
149
+ /**
150
+ * A feature flag the space declares, under the name it is read by: `{{ flags.newCheckout }}`.
151
+ *
152
+ * Read with the document, stored apart from it: each environment has one set, shared by every revision it serves, so a
153
+ * flag is turned without a new revision and a rollback keeps the flags as they are. A revision keeps a copy of the flags
154
+ * it was published with, read only when the environment's own cannot be. The draft (`main`) applies whatever it says
155
+ * now; a published environment, what was last published to it. Its rules see the environment, the host, the URL and
156
+ * who is visiting (`user.authenticated`, `user.email`, `user.username`, `user.roles`). Whoever runs the space may
157
+ * override the answer — the server it is rendered by, then the SDK embedding it, then a tester with the dev tools —
158
+ * but only for flags declared here.
159
+ */
160
+ export type SchemaFlag = {
161
+ description?: string;
162
+ /** The answer when no rule matches. */
163
+ value: boolean;
164
+ rules: SchemaFlagRule[];
165
+ };
123
166
  export type PageFolder = {
124
167
  id: string;
125
168
  name: string;
@@ -161,6 +204,8 @@ export type Schema = {
161
204
  permanentUrl: string;
162
205
  };
163
206
  variables: SchemaVariable[];
207
+ /** Keyed by the name each is read by. A space that declares none has none — documents written before flags too. */
208
+ flags?: Record<string, SchemaFlag>;
164
209
  settings: {
165
210
  keepState?: boolean;
166
211
  stateStorage?: 'localStorage' | 'sessionStorage';
@@ -286,13 +331,27 @@ export type SchemaContextValue = {
286
331
  schemaAddVariable?: (variable: SchemaVariable, fromSubscriptions?: boolean) => void;
287
332
  schemaUpdateVariable?: (variable: SchemaVariable, fromSubscriptions?: boolean) => void;
288
333
  schemaRemoveVariable?: (name: string, fromSubscriptions?: boolean) => void;
289
- schemaAddTemplate?: (to: string, data: Element, dropPosition?: DropPosition, initialItems?: Record<string, Element>, templatePlatform?: Style, variables?: SchemaVariable[], fromSubscriptions?: boolean) => void;
334
+ schemaSetFlag?: (name: string, flag: SchemaFlag, fromSubscriptions?: boolean) => void;
335
+ schemaRemoveFlag?: (name: string, fromSubscriptions?: boolean) => void;
336
+ schemaAddSnippet?: (to: string, data: Element, dropPosition?: DropPosition, initialItems?: Record<string, Element>, style?: SnippetStyle, variables?: SchemaVariable[], fromSubscriptions?: boolean) => void;
290
337
  schemaUpdateSettings?: (value: string | number | boolean, path?: string, fromSubscriptions?: boolean) => void;
291
338
  };
339
+ /** The fields of a definition an element may go without — absent in a document, `null` from GraphQL. */
340
+ type OptionalDefinitionKey = 'parentId' | 'items' | 'bindings' | 'interactions' | 'initialState' | 'runtime' | 'loadStrategy' | 'flag' | 'anchor';
341
+ /**
342
+ * An element as it arrives on the wire. GraphQL answers every field a query names, so one the element does not have
343
+ * comes back `null` — where the element itself has nothing. `schemaFromWire` drops them on arrival.
344
+ */
345
+ export type WireElement = Omit<Element, 'definition'> & {
346
+ definition: Omit<ElementDefinition, OptionalDefinitionKey> & {
347
+ [K in OptionalDefinitionKey]?: ElementDefinition[K] | null;
348
+ };
349
+ };
292
350
  export type SchemaRaw = {
293
351
  definition: Schema['definition'];
294
- flat: Element[];
352
+ flat: WireElement[];
295
353
  variables: SchemaVariable[];
354
+ flags?: Schema['flags'];
296
355
  settings: Schema['settings'];
297
356
  rsc?: Schema['rsc'];
298
357
  pages: Element['id'][];
@@ -6,6 +6,7 @@ import { SSRRealtimeConfig } from './RealtimeTypes';
6
6
  import { Schema } from './SchemaTypes';
7
7
  import { AnalyticsConfig, OfflineDataRaw } from './SdkTypes';
8
8
  import { FontHead, Style } from './StyleTypes';
9
+ import { FlagOverrides } from '../flags/resolveFlags';
9
10
  import { SpaceChange } from '../history/types';
10
11
  import { IncomingHttpHeaders } from 'node:http';
11
12
  import { FC } from 'react';
@@ -153,6 +154,24 @@ export type SSRTemplateProps = {
153
154
  */
154
155
  fonts?: FontHead;
155
156
  };
157
+ /**
158
+ * Remote pictures this server fetches, resizes and keeps, at `/_plitzi/img`.
159
+ *
160
+ * A picture from a dozen other sites, some 1500 px wide for a 360 px card, is the heaviest part of most pages; with
161
+ * this on, an `image` whose `src` is another site's offers the browser a `srcset` of sizes this server makes — in
162
+ * AVIF or WebP when the browser takes them, and with `sharp` installed (without it the picture is passed through,
163
+ * still cached).
164
+ */
165
+ export type SSRImagesConfig = {
166
+ /**
167
+ * The hosts a picture may come from: `images.example.com`, or `*.example.com` for every subdomain. Nothing else is
168
+ * fetched — the endpoint is otherwise a way to make this server download anything — and each address is also held
169
+ * to the rule every outbound request is (no private network, every redirect judged).
170
+ */
171
+ domains: readonly string[];
172
+ /** Where the resized files are kept. Default: `.plitzi/images` under the working directory. */
173
+ cacheDir?: string;
174
+ };
156
175
  /**
157
176
  * How a store-relative font path becomes a URL a browser can fetch.
158
177
  *
@@ -256,6 +275,13 @@ export type SSRSpaceDeployment = {
256
275
  credential?: SSRCredential;
257
276
  spaceId?: number | null;
258
277
  revision?: number;
278
+ /**
279
+ * What this space's feature flags are at, for a deployment that keeps them apart from its revisions — a hash that
280
+ * changes exactly when they do. Part of every cache key a render is kept under (the page, its server data, the space
281
+ * read for it), so a flag turned in production reaches the next request while the revision stays the same. Absent,
282
+ * the flags change only with the revision, and the revision alone keys the caches.
283
+ */
284
+ flagsVersion?: string;
259
285
  /**
260
286
  * This render is an author looking at their own work — the builder's preview — rather than a visitor being
261
287
  * served. Metering skips it: nobody should be billed for editing.
@@ -489,6 +515,12 @@ export interface SSRRscContext {
489
515
  * doing so. Awaiting this joins the read already under way; it never starts a second one.
490
516
  */
491
517
  loadOfflineData: () => Promise<OfflineDataRaw | undefined>;
518
+ /**
519
+ * What the layers above the space decide about its flags for this request: the server's own and, on a page allowed
520
+ * to debug, a tester's. An element gated off by a flag is not resolved — `resolveRscData` resolves the flags
521
+ * against the page it matched and skips it — so a feature that is off puts nothing in the payload.
522
+ */
523
+ flagOverrides?: FlagOverrides;
492
524
  }
493
525
  /**
494
526
  * Which published version of a space is asking.
@@ -520,6 +552,8 @@ export type ActionLookupsConfig = {
520
552
  getConnector?: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<unknown>;
521
553
  /** The space's own functions as of that revision — `SpaceFunctions` in `@plitzi/sdk-server/functions`. */
522
554
  getFunctions?: (spaceId: number, at?: SpaceRevision) => Promise<unknown>;
555
+ /** The feature flags the space declares as of that revision — what a flow reads as `{{ flags.<name> }}`. */
556
+ getFlags?: (spaceId: number, at?: SpaceRevision) => Promise<Schema['flags']>;
523
557
  };
524
558
  export type SSRActionConfig = {
525
559
  /** URL path for the write endpoint, and the base for the action-addressed routes. Defaults to '/_action'. */
@@ -876,6 +910,17 @@ export type SSRServerConfig = {
876
910
  * so does a space whose settings switched `devTools` on. Set, it decides for every space: `false` is a refusal
877
911
  * no space can turn around. */
878
912
  debugMode?: boolean;
913
+ /**
914
+ * The feature flags this deployment decides, by name — the `server` layer: above what each space declares, below
915
+ * the SDK embedding a page and a tester with the dev tools. Only for flags a space declares; an override of one it
916
+ * does not is ignored, and the page says so in its console.
917
+ *
918
+ * A function when one server renders several spaces and they do not share their flags: it is asked per render.
919
+ */
920
+ flags?: Record<string, boolean> | ((space: {
921
+ spaceId: number;
922
+ environment: Environment;
923
+ }) => Record<string, boolean>);
879
924
  cacheTtlMs?: number;
880
925
  loginPath?: string | false;
881
926
  middlewares?: SSRMiddleware[];
@@ -905,6 +950,8 @@ export type SSRServerConfig = {
905
950
  allowPrivatePluginHosts?: boolean;
906
951
  /** Where this deployment serves the font files a space uploaded — see {@link SSRFontsConfig}. */
907
952
  fonts?: SSRFontsConfig;
953
+ /** Remote pictures resized by this server — see {@link SSRImagesConfig}. Absent, images keep their own `src`. */
954
+ images?: SSRImagesConfig;
908
955
  /** Omit client-side JS from the rendered page — useful for verifying SSR HTML without hydration. Default: false. */
909
956
  ssrOnly?: boolean;
910
957
  /** Stream HTML to the client as React renders, reducing TTFB. Default: false. */
@@ -0,0 +1,28 @@
1
+ import { Element, Schema } from './SchemaTypes';
2
+ import { Style, StyleVariables } from './StyleTypes';
3
+ /**
4
+ * A published snippet: a subtree, the style that dresses it, and the element a builder instantiates.
5
+ *
6
+ * The artefact someone hosts when they are not building a space — fetched by URL, shown in the Resources panel,
7
+ * dragged onto a canvas — which is why it lives beside the schema and the style rather than with the builder's own
8
+ * types: it is a document, produced and consumed by processes that never open a builder.
9
+ */
10
+ export type Snippet = {
11
+ id?: string;
12
+ definition: {
13
+ name: string;
14
+ description: string;
15
+ /** Root of what travels. Its subtree is the whole of `schema.flat`, and it answers to no parent. */
16
+ baseElementId: Element['id'];
17
+ };
18
+ /**
19
+ * Only what travels: the subtree and the variables its rules read. Nothing else of the space it was cut from — its
20
+ * pages, settings or components — comes along, and a builder showing or dropping it reads nothing else.
21
+ */
22
+ schema: Pick<Schema, 'flat' | 'variables'>;
23
+ style: Style;
24
+ };
25
+ /** The part of a style a snippet brings into a space: its rules, by display mode, and the tokens they read. */
26
+ export type SnippetStyle = Pick<Style, 'platform'> & {
27
+ variables?: Partial<StyleVariables>;
28
+ };
@@ -8,6 +8,7 @@ import { Schema, Element } from './SchemaTypes';
8
8
  import { SpaceConnector } from './SpaceTypes';
9
9
  import { DisplayMode, Style, StyleState } from './StyleTypes';
10
10
  import { ColorScheme, Theme } from './ThemeTypes';
11
+ import { FlagOverrides, FlagResolution } from '../flags/resolveFlags';
11
12
  export type RuntimeSourceValues = {
12
13
  variables?: Record<string, unknown>;
13
14
  navigation?: {
@@ -21,6 +22,19 @@ export type RuntimeSourceValues = {
21
22
  mode: Theme;
22
23
  resolved: ColorScheme;
23
24
  };
25
+ flags?: Record<string, boolean>;
26
+ };
27
+ /**
28
+ * The feature flags of this render: what each layer above the space says, and how every flag resolved.
29
+ *
30
+ * Top-level for the reason `rsc` is: the overrides are written at the root — by whoever mounts the SDK, by the builder
31
+ * forcing one — and an element scope owning `runtime` would keep a write from any depth to itself.
32
+ */
33
+ export type FlagsState = {
34
+ overrides?: FlagOverrides;
35
+ /** Each declared flag's answer and the layer that gave it — what the dev tools show. The values alone are the
36
+ * `flags` source. */
37
+ resolved?: Record<string, FlagResolution>;
24
38
  };
25
39
  export type CommonState = {
26
40
  schema: Schema;
@@ -41,12 +55,17 @@ export type CommonState = {
41
55
  };
42
56
  sources?: Record<string, Source>;
43
57
  rsc?: RscState;
58
+ flags?: FlagsState;
44
59
  actions?: ActionsState;
45
60
  /** Where this origin's realtime channels answer — absent in a render with no server, where no channel opens. */
46
61
  realtime?: {
47
62
  endpoint?: string;
48
63
  transport?: RealtimeTransport;
49
64
  };
65
+ /** Where this origin resizes remote pictures — absent in a render with no server, where an image keeps its `src`. */
66
+ images?: {
67
+ endpoint?: string;
68
+ };
50
69
  render?: RenderSettings;
51
70
  /**
52
71
  * The theme, mirrored from `themeStore` so the devtools store viewer answers "which theme is this" in one line.
@@ -214,6 +233,12 @@ export type BuilderState = CommonState & {
214
233
  queryParams: QueryParams;
215
234
  hostname: string;
216
235
  };
236
+ /**
237
+ * The builder's OWN feature flags — Plitzi's, not the space's: which parts of the editor this person is shown, as the
238
+ * platform resolved them for them when the editor opened (`PlatformFlags` in the builder's first query). Never
239
+ * authored, never published.
240
+ */
241
+ platformFlags?: Record<string, boolean>;
217
242
  displayMode: DisplayMode;
218
243
  selector?: string;
219
244
  styleSelector?: string;