@plitzi/sdk-shared 0.33.2 → 0.34.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.
Files changed (204) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/actions/cron.d.ts +34 -0
  3. package/dist/actions/cron.mjs +72 -0
  4. package/dist/actions/index.d.ts +6 -0
  5. package/dist/actions/index.mjs +5 -0
  6. package/dist/actions/triggerParams.d.ts +41 -0
  7. package/dist/actions/triggerParams.mjs +40 -0
  8. package/dist/actions/triggers.d.ts +29 -0
  9. package/dist/actions/triggers.mjs +4 -0
  10. package/dist/actions/validateDocument.d.ts +23 -0
  11. package/dist/actions/validateDocument.mjs +267 -0
  12. package/dist/auth/failureChannel.d.ts +9 -4
  13. package/dist/auth/failureChannel.mjs +3 -2
  14. package/dist/authoring/builder.d.ts +51 -0
  15. package/dist/authoring/builder.mjs +29 -0
  16. package/dist/authoring/declare.d.ts +64 -0
  17. package/dist/authoring/declare.mjs +4 -0
  18. package/dist/authoring/elementCallbacks.d.ts +13 -0
  19. package/dist/authoring/elementCallbacks.mjs +71 -0
  20. package/dist/authoring/index.d.ts +21 -0
  21. package/dist/authoring/index.mjs +6 -0
  22. package/dist/authoring/paramSpec.d.ts +51 -0
  23. package/dist/authoring/paramSpec.mjs +40 -0
  24. package/dist/authoring/spaceCallbacks.d.ts +10 -0
  25. package/dist/authoring/spaceCallbacks.mjs +51 -0
  26. package/dist/builder/contexts/BuilderContext.d.ts +2 -4
  27. package/dist/dataSource/getBindingsDetails.mjs +1 -1
  28. package/dist/dataSource/helpers/getSourceName.d.ts +1 -3
  29. package/dist/dataSource/helpers/getSourceName.mjs +1 -1
  30. package/dist/dataSource/index.d.ts +2 -0
  31. package/dist/dataSource/index.mjs +6 -5
  32. package/dist/dataSource/resolveVariables.d.ts +22 -0
  33. package/dist/dataSource/resolveVariables.mjs +16 -0
  34. package/dist/dataSource/utility/index.mjs +15 -13
  35. package/dist/dataSource/utility/not.d.ts +11 -0
  36. package/dist/dataSource/utility/not.mjs +15 -0
  37. package/dist/devTools/debugCookie.d.ts +16 -0
  38. package/dist/devTools/debugCookie.mjs +7 -0
  39. package/dist/devTools/index.d.ts +6 -2
  40. package/dist/devTools/index.mjs +4 -2
  41. package/dist/devTools/interactionLog.d.ts +14 -0
  42. package/dist/devTools/interactionLog.mjs +4 -0
  43. package/dist/helpers/index.d.ts +2 -0
  44. package/dist/helpers/index.mjs +11 -9
  45. package/dist/helpers/reducerOrigin.d.ts +15 -0
  46. package/dist/helpers/reducerOrigin.mjs +4 -0
  47. package/dist/helpers/ruleEvaluator.d.ts +14 -0
  48. package/dist/helpers/ruleEvaluator.mjs +5 -0
  49. package/dist/helpers/twigWrapper/AST.d.ts +12 -1
  50. package/dist/helpers/twigWrapper/AST.mjs +0 -0
  51. package/dist/helpers/twigWrapper/Evaluator/Evaluator.mjs +7 -0
  52. package/dist/helpers/twigWrapper/Parser/Cursor.d.ts +7 -0
  53. package/dist/helpers/twigWrapper/Parser/Cursor.mjs +5 -0
  54. package/dist/helpers/twigWrapper/Parser/ExpressionParser.mjs +46 -8
  55. package/dist/helpers/twigWrapper/Parser/types.mjs +0 -0
  56. package/dist/helpers/twigWrapper/charClass.d.ts +7 -0
  57. package/dist/helpers/twigWrapper/charClass.mjs +16 -12
  58. package/dist/helpers/twigWrapper/tokens/tokenPatterns.mjs +2 -2
  59. package/dist/helpers/utils.d.ts +0 -2
  60. package/dist/helpers/utils.mjs +16 -19
  61. package/dist/hooks/index.d.ts +2 -1
  62. package/dist/hooks/index.mjs +4 -3
  63. package/dist/hooks/useFontHead.d.ts +3 -0
  64. package/dist/hooks/useFontHead.mjs +23 -0
  65. package/dist/hooks/usePlitziServiceContext.d.ts +3 -2
  66. package/dist/index.mjs +61 -45
  67. package/dist/navigation/index.d.ts +1 -1
  68. package/dist/navigation/index.mjs +2 -2
  69. package/dist/navigation/routes.d.ts +8 -0
  70. package/dist/navigation/routes.mjs +39 -39
  71. package/dist/network/graphql/builder/Mutations/Segment/SegmentAddMutation.mjs +0 -1
  72. package/dist/network/graphql/builder/Mutations/Segment/SegmentAddTemplateMutation.mjs +0 -1
  73. package/dist/network/graphql/builder/Mutations/Segment/SegmentUpdateMutation.mjs +0 -1
  74. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentAddElementMutation.mjs +0 -1
  75. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentCloneElementMutation.mjs +0 -1
  76. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentMoveElementMutation.mjs +0 -1
  77. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRemoveElementMutation.mjs +0 -1
  78. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRenameElementMutation.d.ts +3 -0
  79. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRenameElementMutation.mjs +9 -0
  80. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentUpdateElementMutation.mjs +0 -1
  81. package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentUpdateElementsMutation.mjs +0 -1
  82. package/dist/network/graphql/builder/Mutations/Space/SpaceAddElementMutation.mjs +0 -1
  83. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.mjs +0 -1
  84. package/dist/network/graphql/builder/Mutations/Space/SpaceCloneElementMutation.mjs +0 -1
  85. package/dist/network/graphql/builder/Mutations/Space/SpaceMoveElementMutation.mjs +0 -1
  86. package/dist/network/graphql/builder/Mutations/Space/SpaceRemoveElementMutation.mjs +0 -1
  87. package/dist/network/graphql/builder/Mutations/Space/SpaceRenameElementMutation.d.ts +5 -0
  88. package/dist/network/graphql/builder/Mutations/Space/SpaceRenameElementMutation.mjs +9 -0
  89. package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateElementMutation.mjs +0 -1
  90. package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateElementsMutation.mjs +0 -1
  91. package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateMutation.mjs +0 -1
  92. package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateSchemaMutation.mjs +0 -1
  93. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceAddActionMutation.d.ts +8 -0
  94. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceAddActionMutation.mjs +16 -0
  95. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRemoveActionMutation.d.ts +4 -0
  96. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRemoveActionMutation.mjs +16 -0
  97. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.d.ts +4 -0
  98. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.mjs +14 -0
  99. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceUpdateActionMutation.d.ts +4 -0
  100. package/dist/network/graphql/builder/Mutations/Space/actions/SpaceUpdateActionMutation.mjs +16 -0
  101. package/dist/network/graphql/builder/Mutations/Space/pages/SpaceAddPageMutation.mjs +2 -3
  102. package/dist/network/graphql/builder/Mutations/Space/pages/SpaceUpdatePageMutation.mjs +0 -1
  103. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleAddFontMutation.d.ts +2 -0
  104. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleAddFontMutation.mjs +11 -0
  105. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleRemoveFontMutation.d.ts +2 -0
  106. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleRemoveFontMutation.mjs +11 -0
  107. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleUpdateFontMutation.d.ts +2 -0
  108. package/dist/network/graphql/builder/Mutations/Style/fonts/StyleUpdateFontMutation.mjs +11 -0
  109. package/dist/network/graphql/builder/Mutations/index.d.ts +24 -0
  110. package/dist/network/graphql/builder/Mutations/index.mjs +150 -132
  111. package/dist/network/graphql/builder/Queries/InitQuery.mjs +1 -2
  112. package/dist/network/graphql/builder/Queries/Segment/SegmentQuery.mjs +0 -1
  113. package/dist/network/graphql/builder/Queries/Segment/SegmentsQuery.mjs +0 -1
  114. package/dist/network/graphql/builder/Queries/Space/SpaceActionEventsQuery.d.ts +9 -0
  115. package/dist/network/graphql/builder/Queries/Space/SpaceActionEventsQuery.mjs +30 -0
  116. package/dist/network/graphql/builder/Queries/Space/SpaceActionTasksQuery.d.ts +6 -0
  117. package/dist/network/graphql/builder/Queries/Space/SpaceActionTasksQuery.mjs +16 -0
  118. package/dist/network/graphql/builder/Queries/Space/SpaceActionsQuery.d.ts +9 -0
  119. package/dist/network/graphql/builder/Queries/Space/SpaceActionsQuery.mjs +25 -0
  120. package/dist/network/graphql/builder/Queries/Space/SpaceCheckActionQuery.d.ts +6 -0
  121. package/dist/network/graphql/builder/Queries/Space/SpaceCheckActionQuery.mjs +17 -0
  122. package/dist/network/graphql/builder/Queries/Space/SpaceQuotaQuery.d.ts +30 -0
  123. package/dist/network/graphql/builder/Queries/Space/SpaceQuotaQuery.mjs +40 -0
  124. package/dist/network/graphql/builder/Queries/index.d.ts +16 -0
  125. package/dist/network/graphql/builder/Queries/index.mjs +24 -14
  126. package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +4 -0
  127. package/dist/network/graphql/sdk/Queries/InitQuery.mjs +5 -2
  128. package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.mjs +0 -1
  129. package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.mjs +0 -1
  130. package/dist/network/spaceEvents.d.ts +20 -1
  131. package/dist/network/spaceEvents.mjs +89 -74
  132. package/dist/schema/index.d.ts +1 -0
  133. package/dist/schema/index.mjs +2 -1
  134. package/dist/schema/serverElements.d.ts +16 -0
  135. package/dist/schema/serverElements.mjs +18 -0
  136. package/dist/server/actions/useActionsSync.d.ts +10 -0
  137. package/dist/server/actions/useActionsSync.mjs +7 -0
  138. package/dist/server/index.d.ts +2 -1
  139. package/dist/server/index.mjs +5 -4
  140. package/dist/server/rsc/refreshRsc.d.ts +11 -1
  141. package/dist/server/rsc/refreshRsc.mjs +30 -12
  142. package/dist/server/rsc/useRscSync.mjs +20 -13
  143. package/dist/state/runtimeStatePersist.mjs +4 -3
  144. package/dist/store/actionRuns/actionRunsRecorder.d.ts +36 -0
  145. package/dist/store/actionRuns/actionRunsRecorder.mjs +39 -0
  146. package/dist/store/actionRuns/actionRunsStore.d.ts +16 -0
  147. package/dist/store/actionRuns/actionRunsStore.mjs +5 -0
  148. package/dist/store/actionRuns/index.d.ts +6 -0
  149. package/dist/store/actionRuns/index.mjs +4 -0
  150. package/dist/store/actionRuns/useActionRuns.d.ts +13 -0
  151. package/dist/store/actionRuns/useActionRuns.mjs +10 -0
  152. package/dist/store/index.d.ts +46 -45
  153. package/dist/store/index.mjs +6 -3
  154. package/dist/store/renderSettings.d.ts +3 -0
  155. package/dist/store/renderSettings.mjs +17 -5
  156. package/dist/store/tracing/tracingCollector.d.ts +1 -1
  157. package/dist/store/tracing/tracingCollector.mjs +37 -35
  158. package/dist/store/tracing/tracingStore.d.ts +13 -0
  159. package/dist/store/tracing/tracingStore.mjs +3 -3
  160. package/dist/style/fontAssets.d.ts +12 -0
  161. package/dist/style/fontAssets.mjs +18 -0
  162. package/dist/style/fontValidation.d.ts +8 -0
  163. package/dist/style/fontValidation.mjs +107 -0
  164. package/dist/style/fonts.d.ts +74 -0
  165. package/dist/style/fonts.mjs +198 -0
  166. package/dist/style/fontsFromCss.d.ts +27 -0
  167. package/dist/style/fontsFromCss.mjs +43 -0
  168. package/dist/style/index.d.ts +4 -0
  169. package/dist/style/index.mjs +5 -1
  170. package/dist/style/styleConstants.d.ts +2 -2
  171. package/dist/style/styleConstants.mjs +1 -0
  172. package/dist/theme/ThemeProvider.d.ts +36 -6
  173. package/dist/theme/ThemeProvider.mjs +49 -35
  174. package/dist/theme/ThemeScope.d.ts +16 -0
  175. package/dist/theme/ThemeScope.mjs +6 -0
  176. package/dist/theme/index.d.ts +7 -1
  177. package/dist/theme/index.mjs +6 -2
  178. package/dist/theme/themeCookie.d.ts +30 -0
  179. package/dist/theme/themeCookie.mjs +24 -0
  180. package/dist/theme/themeStore.d.ts +40 -0
  181. package/dist/theme/themeStore.mjs +17 -0
  182. package/dist/theme/useTheme.d.ts +29 -0
  183. package/dist/theme/useTheme.mjs +20 -0
  184. package/dist/types/ActionTypes.d.ts +396 -0
  185. package/dist/types/ActionTypes.mjs +0 -0
  186. package/dist/types/AuthTypes.d.ts +23 -2
  187. package/dist/types/BuilderTypes.d.ts +0 -12
  188. package/dist/types/CommonTypes.d.ts +13 -0
  189. package/dist/types/DevToolsTypes.d.ts +57 -14
  190. package/dist/types/EventBridgeTypes.d.ts +1 -1
  191. package/dist/types/InteractionTypes.d.ts +23 -3
  192. package/dist/types/PluginTypes.d.ts +0 -3
  193. package/dist/types/SchemaTypes.d.ts +29 -4
  194. package/dist/types/ServerTypes.d.ts +390 -46
  195. package/dist/types/SpaceTypes.d.ts +16 -0
  196. package/dist/types/StoreTypes.d.ts +181 -3
  197. package/dist/types/StyleTypes.d.ts +83 -4
  198. package/dist/types/TemplateTypes.d.ts +20 -0
  199. package/dist/types/TemplateTypes.mjs +0 -0
  200. package/dist/types/ThemeTypes.d.ts +28 -1
  201. package/dist/types/index.d.ts +2 -0
  202. package/eslint.config.mjs +2 -0
  203. package/package.json +244 -29
  204. package/vite.config.ts +27 -7
@@ -1,3 +1,4 @@
1
+ import { ActionField } from './ActionTypes';
1
2
  import { SubscriptionCollaborator, SubscriptionCollaboratorPointer } from './BuilderTypes';
2
3
  import { Environment, RenderMode } from './CommonTypes';
3
4
  import { Source } from './DataSourceTypes';
@@ -6,6 +7,7 @@ import { Schema, Element } from './SchemaTypes';
6
7
  import { Segment } from './SegmentTypes';
7
8
  import { SpaceConnector } from './SpaceTypes';
8
9
  import { DisplayMode, Style, StyleState } from './StyleTypes';
10
+ import { ColorScheme, Theme } from './ThemeTypes';
9
11
  export type RuntimeSourceValues = {
10
12
  variables?: Record<string, unknown>;
11
13
  navigation?: {
@@ -14,9 +16,7 @@ export type RuntimeSourceValues = {
14
16
  };
15
17
  auth?: Record<string, unknown>;
16
18
  state?: Record<string, unknown>;
17
- /** @deprecated Use the `state` source (mirrors `runtime.state`). Kept as an alias so existing `page.*` bindings keep
18
- * working; it still carries the runtime state plus `currentPageId`. */
19
- page?: Record<string, unknown>;
19
+ host?: Record<string, unknown>;
20
20
  };
21
21
  export type CommonState = {
22
22
  prevSchema?: Schema;
@@ -27,16 +27,45 @@ export type CommonState = {
27
27
  runtime?: {
28
28
  sources: RuntimeSourceValues & Record<string, unknown>;
29
29
  state?: Record<string, unknown>;
30
+ /**
31
+ * What the embedding application handed this space — its screens, who is signed in to IT, whatever a shell
32
+ * needs to render. Written by whoever mounts the SDK and mirrored to `runtime.sources.host`.
33
+ *
34
+ * The counterpart of the `hostAction` step: without it that step is a one-way shout, because a shell cannot
35
+ * list the host's screens unless the host can give it the list.
36
+ */
37
+ host?: Record<string, unknown>;
30
38
  elements?: Record<string, unknown>;
31
39
  };
32
40
  sources?: Record<string, Source>;
33
41
  rsc?: RscState;
42
+ actions?: ActionsState;
34
43
  render?: RenderSettings;
44
+ /**
45
+ * The theme, mirrored from `themeStore` so it reads like everything else: `{{ theme.resolved }}` in a binding, a
46
+ * `when` rule that switches on it, and one line in the devtools store viewer that answers "which theme is this".
47
+ *
48
+ * A MIRROR and never the source. The theme has to be readable by things that are not under any provider — the
49
+ * dev-tools panel in its shadow root, an editor in a portal — which no app store can serve, so `themeStore` owns
50
+ * it and `ThemeProvider` publishes it here. Write through `useTheme`/`setThemeMode`; writing this copy changes
51
+ * the value nobody reads. Same contract `navigation` has below, for the same reason.
52
+ *
53
+ * Ephemeral: excluded from history (a toggle is not an edit) and not persisted here — `ThemeProvider` keeps it
54
+ * in a cookie, which is the one place a server can read it back from.
55
+ */
56
+ theme?: {
57
+ mode: Theme;
58
+ resolved: ColorScheme;
59
+ areas: Record<string, Theme>;
60
+ };
35
61
  navigation: {
36
62
  urlSearchParams?: URLSearchParams;
37
63
  routeParams: RouteParams;
38
64
  queryParams: QueryParams;
39
65
  hostname: string;
66
+ /** Scheme, host AND port — what a link needs to name this page absolutely. `hostname` has no port, which is why
67
+ * it answers `when` rules and cannot answer this. */
68
+ origin: string;
40
69
  currentPageId: string;
41
70
  navigate: (url: string, isExternal?: boolean) => void;
42
71
  };
@@ -50,12 +79,94 @@ export type RenderSettings = {
50
79
  renderMode?: RenderMode;
51
80
  environment?: Environment;
52
81
  isHydrating?: boolean;
82
+ /**
83
+ * Whether React has finished hydrating this render — false during the pass that has to match the server's markup,
84
+ * true from the commit after it. Only ever true on a render that was hydrating in the first place; a client-only
85
+ * render has no markup to match and never sets either flag.
86
+ *
87
+ * It exists because "this render came from SSR" and "the SSR markup has been reconciled" are different questions,
88
+ * and everything that must not run until the second one has happened had no way to ask it. Restoring persisted
89
+ * state is the case that forced it: what a browser kept from last time is, by definition, something the server
90
+ * could not know, so applying it during the hydrating pass is a guaranteed mismatch — and React answers a mismatch
91
+ * by throwing away the whole tree it happened in, not the one node.
92
+ */
93
+ hydrated?: boolean;
94
+ /**
95
+ * This space is over its plan's quota, as the SERVER decided when it metered the render.
96
+ *
97
+ * Not the visitor's business and not the page's either — it is a fact about the account behind the site, which is
98
+ * why it rides the render surface rather than the schema: nothing an author writes can set it, and nothing in the
99
+ * space's settings can turn it off. `branding` is forced on by the same state; this is what says WHY.
100
+ */
101
+ overQuota?: boolean;
102
+ /**
103
+ * Whether every element carries `data-plitzi-el="<its id>"`, which is what an end-to-end test addresses it by.
104
+ *
105
+ * On unless a deployment says otherwise, and that default is the point: a consumer's own suite has to work
106
+ * against their own build without configuring anything, and the ids are already in the page — the schema the
107
+ * browser hydrates from carries every one of them, so the attribute publishes nothing new.
108
+ *
109
+ * `authorSpace` returns the matching handles, so a spec names `handles.hero.cta` rather than a string somebody
110
+ * has to keep in step with the document by hand.
111
+ */
112
+ testAttributes?: boolean;
113
+ };
114
+ /** Absent `endpoint` is the whole feature switch: a render with no server tier leaves every `serverAction` step
115
+ * inert instead of letting each click discover a 404. */
116
+ export type ActionsState = {
117
+ endpoint?: string;
118
+ /**
119
+ * What this space can run, for the editor that offers it.
120
+ *
121
+ * Authoring data, seeded by the builder from the space's own actions and empty everywhere else — a published
122
+ * page names one action and has no business holding a directory of the others. It is here rather than in
123
+ * `BuilderState` because the step that reads it is registered by the SDK runtime, in the same place a
124
+ * `navigate` step reads the page list: one vocabulary, and the options come from whoever knows them.
125
+ *
126
+ * A deployment answers it through `listActions`, so a self-hoster's own actions show up in their editor for the
127
+ * same reason their own tasks do.
128
+ */
129
+ catalog?: ActionCatalogEntry[];
130
+ /**
131
+ * Whether the target this space publishes to can run actions AT ALL.
132
+ *
133
+ * Seeded by the builder from the space's deployments, and absent everywhere else — a rendered page does not need
134
+ * to be told, it has an `endpoint` or it does not. It exists so a step can say "this space deploys nowhere that
135
+ * runs server code" while it is being authored, rather than at the first click in production.
136
+ */
137
+ available?: boolean;
138
+ };
139
+ /** One action as a picker needs it: what to store, what to show, and what it takes. Never the flow itself. */
140
+ export type ActionCatalogEntry = {
141
+ identifier: string;
142
+ name: string;
143
+ /** The fields the `call` trigger declares, so an editor can say what an action expects before it is called. */
144
+ input: Record<string, ActionField>;
53
145
  };
54
146
  export type RscState = {
55
147
  enabled?: boolean;
56
148
  endpoint?: string;
57
149
  loaded?: boolean;
58
150
  data?: Record<string, unknown>;
151
+ /**
152
+ * True when the last refresh could not reach the server, so what every server element is showing is from before
153
+ * that.
154
+ *
155
+ * A refresh failing is not an error — the payload is supplemental, and dropping it keeps the page working — but
156
+ * silently keeping the old data is a page that looks current and is not. Published so an author can bind it and
157
+ * say so; cleared by the first refresh that gets through.
158
+ */
159
+ stale?: boolean;
160
+ /**
161
+ * The location the payload in `data` was resolved for — `pathname + search`, as the request carried it.
162
+ *
163
+ * A route change in the browser renders the new page immediately, while the answer for it is still in flight.
164
+ * Without this the payload sitting in the store is indistinguishable from one belonging to the page being
165
+ * shown, and every element on it reads "no slice for me": a binding with no value leaves the element as it was
166
+ * authored, so a visibility binding paints *visible* and an empty section is drawn and then corrected. Elements
167
+ * compare this against where the visitor actually is, and a mismatch means "not mine yet" rather than "gone".
168
+ */
169
+ location?: string;
59
170
  };
60
171
  export type BuilderState = CommonState & {
61
172
  collaboration: {
@@ -64,6 +175,22 @@ export type BuilderState = CommonState & {
64
175
  };
65
176
  connectors: Record<string, SpaceConnector>;
66
177
  hasServerRendering: boolean;
178
+ /**
179
+ * A URL the author is trying the page ON, instead of the one the editor itself is open at.
180
+ *
181
+ * The builder's own address is `/spaces/12/builder`, so a page whose route takes a `:slug`, a variable that
182
+ * switches on `?plan=pro`, or a binding that reads the hostname has nothing real to resolve against — the author
183
+ * had to publish to find out what any of it does. What is set here is laid over what the browser gives, in the
184
+ * one place that publishes `navigation.*`, so everything downstream of it — variable `when` rules, bindings,
185
+ * server-driven elements, an action's input — sees the URL being tested and not the editor's own.
186
+ *
187
+ * Editor-only and never published: `navigation` still holds the resolved values, which is what the page reads.
188
+ */
189
+ urlTest?: {
190
+ routeParams: RouteParams;
191
+ queryParams: QueryParams;
192
+ hostname: string;
193
+ };
67
194
  displayMode: DisplayMode;
68
195
  selector?: string;
69
196
  styleSelector?: string;
@@ -83,7 +210,17 @@ export type PropChange = {
83
210
  ref?: boolean;
84
211
  };
85
212
  export type CommitElementRender = {
213
+ /**
214
+ * This INSTANCE, not this element.
215
+ *
216
+ * A controlled list renders the same element once per row, and the element's id is the same string every time. Keyed
217
+ * by that, a hundred rows collapsed into one node: the flamegraph drew a single row carrying the last instance's
218
+ * timing, and the ninety-nine renders that made the commit expensive were nowhere in it. This is the identity React
219
+ * itself uses — one key per mounted component — so the tree the panel draws is the tree that rendered.
220
+ */
86
221
  id: string;
222
+ /** Which element this instance is, for the label, the schema lookup and the outline on the page. */
223
+ elementId: string;
87
224
  parentId?: string;
88
225
  phase: RenderPhase;
89
226
  actualDuration: number;
@@ -105,8 +242,49 @@ export type CommitEntry = {
105
242
  export type TracingTreeNode = {
106
243
  parentId?: string;
107
244
  baseDuration: number;
245
+ /** Which element this instance is — see `CommitElementRender.id`. */
246
+ elementId: string;
108
247
  };
109
248
  export type TracingTree = Record<string, TracingTreeNode>;
249
+ /**
250
+ * One server action this page started, as the dev-tools show it back.
251
+ *
252
+ * Recorded by the `runServerAction` step itself, so it covers what no network tab makes legible: which action was
253
+ * named, in which mode, what the server answered, and — when the deployment is a dev one, which is the only time
254
+ * the server sends it — the STEPS the flow ran on the other side. A `detached` run has no answer to await and a
255
+ * `stream` returns before its frames arrive, so both are invisible without a record of their own.
256
+ */
257
+ export type ActionRunEntry = {
258
+ /** Local to this page: assigned when the run is SENT, which is before any server run id exists. */
259
+ id: string;
260
+ actionId: string;
261
+ mode: 'await' | 'detached' | 'stream';
262
+ /** The server's own id, once it answers. Absent for a run that never reached one. */
263
+ runId?: string;
264
+ status: 'running' | 'completed' | 'failed' | 'accepted' | 'streaming' | 'skipped' | 'aborted';
265
+ /** The server's vocabulary when it refused: `duplicate`, `over_capacity`, `recursion`, `forbidden`… */
266
+ reason?: string;
267
+ /** What went wrong, when anything says so. Never a credential — the server redacts before answering. */
268
+ error?: string;
269
+ input?: Record<string, unknown>;
270
+ output?: Record<string, unknown>;
271
+ /** Chunks a streaming run emitted, in order. */
272
+ progress: unknown[];
273
+ /** The server-side steps, when the deployment sent them: authoring requests and dev servers only. */
274
+ trace?: Record<string, unknown>[];
275
+ /**
276
+ * Whether this run can still be stopped from the panel.
277
+ *
278
+ * True while it is in flight and the step that started it is still holding the handle. It is what lets the
279
+ * dev-tools offer a Cancel on a run that is happening rather than on one that already ended.
280
+ */
281
+ cancellable?: boolean;
282
+ startedAt: number;
283
+ endedAt?: number;
284
+ };
285
+ export type ActionRunsState = {
286
+ runs: ActionRunEntry[];
287
+ };
110
288
  export type TracingState = {
111
289
  enabled: boolean;
112
290
  hydrated: boolean;
@@ -1,10 +1,10 @@
1
+ import { ColorScheme, Theme } from './ThemeTypes';
1
2
  import { default as styleConstants } from '../style/styleConstants';
2
3
  export type TagType = 'class' | 'element' | 'id';
3
4
  export type DisplayMode = 'desktop' | 'tablet' | 'mobile';
4
5
  export type StyleMode = 'mobile-first' | 'desktop-first';
5
6
  export type StyleState = 'hover' | 'active' | 'focus' | 'disabled' | 'checked' | 'visited';
6
7
  export type StyleValue = number | string;
7
- export type StyleThemeMode = 'system' | 'light' | 'dark';
8
8
  export type StyleCategory = (typeof styleConstants)[keyof typeof styleConstants];
9
9
  export declare enum StyleVariableCategory {
10
10
  COLOR = "color",
@@ -12,7 +12,7 @@ export declare enum StyleVariableCategory {
12
12
  SHADOW = "shadow",
13
13
  CUSTOM = "custom"
14
14
  }
15
- export type StyleThemeValue = Partial<Record<Exclude<StyleThemeMode, 'system'> | 'default', string>>;
15
+ export type StyleThemeValue = Partial<Record<ColorScheme | 'default', string>>;
16
16
  export type StyleVariableValue = string | number | StyleThemeValue;
17
17
  export type StyleVariableGroup = Record<string, StyleVariableValue>;
18
18
  export type StyleVariables = Record<StyleVariableCategory, StyleVariableGroup>;
@@ -33,14 +33,90 @@ export type StyleItem = {
33
33
  cache: string;
34
34
  componentType?: string;
35
35
  };
36
+ export type FontSource = 'system' | 'google' | 'remote' | 'hosted';
37
+ export type FontStyle = 'normal' | 'italic';
38
+ export type FontDisplay = 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
39
+ /** One face of a family: the file carrying a given weight and slant. */
40
+ export type FontFace = {
41
+ weight: number;
42
+ style: FontStyle;
43
+ format: 'woff2' | 'woff';
44
+ /** Limits the face to the code points it covers, so the browser fetches it only when needed. */
45
+ unicodeRange?: string;
46
+ };
47
+ export type FontBase = {
48
+ /** What `font-family` names. Unique within a space. */
49
+ family: string;
50
+ /** Appended to the stack — `'Lato', sans-serif` — and what renders while the face loads. */
51
+ fallback: string;
52
+ /** The weights the family really provides: what the picker offers, and what it disables against. */
53
+ weights: number[];
54
+ styles: FontStyle[];
55
+ display?: FontDisplay;
56
+ /** Worth a `<link rel="preload">`. The body family, and at most one more: preloading everything
57
+ * is the same as preloading nothing. */
58
+ preload?: boolean;
59
+ };
60
+ /** Installed nowhere: a stack the visitor's system already has. Costs no bytes. */
61
+ export type SystemFont = FontBase & {
62
+ source: 'system';
63
+ };
64
+ /** Google Fonts, reached through the single aggregated `css2` request the resolver builds. */
65
+ export type GoogleFont = FontBase & {
66
+ source: 'google';
67
+ subsets?: string[];
68
+ };
69
+ /** Someone else's origin — Adobe Fonts, Bunny, Fontshare, the customer's own CDN. Either a
70
+ * stylesheet that declares the faces, or the files themselves. */
71
+ export type RemoteFont = FontBase & {
72
+ source: 'remote';
73
+ stylesheet?: string;
74
+ files?: (FontFace & {
75
+ url: string;
76
+ })[];
77
+ };
78
+ /** Uploaded to this deployment's font store. `path` is store-relative and never absolute: a
79
+ * manifest that carried `https://cdn.plitzi.com/...` would follow a space onto a server that is
80
+ * not ours and keep asking Plitzi for its fonts. The URL is made at render time. */
81
+ export type HostedFont = FontBase & {
82
+ source: 'hosted';
83
+ files: (FontFace & {
84
+ path: string;
85
+ })[];
86
+ };
87
+ export type SpaceFont = SystemFont | GoogleFont | RemoteFont | HostedFont;
88
+ /** What a surface needs to put in its `<head>` for a manifest — see `fontsToHead`. */
89
+ export type FontHead = {
90
+ /** `crossorigin` where the origin serves the FILES: a font is fetched in CORS mode, and a preconnect that
91
+ * omits it warms a connection the font fetch then cannot use. A stylesheet origin takes it off. */
92
+ preconnect: {
93
+ href: string;
94
+ crossorigin?: boolean;
95
+ }[];
96
+ links: {
97
+ href: string;
98
+ rel: 'stylesheet' | 'preload';
99
+ as?: 'style' | 'font';
100
+ type?: string;
101
+ crossorigin?: boolean;
102
+ }[];
103
+ /** `@font-face` blocks, as CSS text. Empty when every family is system or linked. */
104
+ faces: string;
105
+ /** Every origin the manifest reaches for, for a CSP that has to name them. */
106
+ origins: string[];
107
+ };
36
108
  export type Style = {
37
109
  platform: Record<DisplayMode, Record<string, StyleItem>>;
38
110
  mode?: StyleMode;
39
111
  theme: {
40
- default: StyleThemeMode;
41
- schemes: StyleThemeMode[];
112
+ default: Theme;
113
+ schemes: Theme[];
42
114
  };
43
115
  variables: Partial<StyleVariables>;
116
+ /** The families this space declares. A `font-family` naming anything absent from here renders in a fallback,
117
+ * because nothing else in the system loads a face. Optional because a document written before the manifest
118
+ * existed has none, and that is a real state every reader has to survive rather than a bug. */
119
+ fonts?: SpaceFont[];
44
120
  cache: string;
45
121
  };
46
122
  export type StyleContextValue = {
@@ -55,6 +131,9 @@ export type StyleContextValue = {
55
131
  styleAddVariable?: unknown;
56
132
  styleUpdateVariable?: unknown;
57
133
  styleRemoveVariable?: unknown;
134
+ styleAddFont?: unknown;
135
+ styleUpdateFont?: unknown;
136
+ styleRemoveFont?: unknown;
58
137
  styleAddTemplate?: unknown;
59
138
  styleUpdateSettings?: unknown;
60
139
  };
@@ -0,0 +1,20 @@
1
+ import { Element, Schema } from './SchemaTypes';
2
+ import { Style } from './StyleTypes';
3
+ /**
4
+ * A published template: 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 Template = {
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
+ schema: Schema;
19
+ style: Style;
20
+ };
File without changes
@@ -1,5 +1,32 @@
1
1
  export type Theme = 'dark' | 'light' | 'system';
2
- export type ThemeContextValue = {
2
+ /**
3
+ * The answer, once `system` has been put to the machine: what is actually on screen.
4
+ *
5
+ * Every consumer that paints something wants this one — a code editor, a chart, the dev-tools panel. `theme` is
6
+ * the CHOICE and can be `system`, which is not a colour and cannot be compared against one.
7
+ */
8
+ export type ColorScheme = Exclude<Theme, 'system'>;
9
+ /**
10
+ * The whole of what anybody knows about the theme, in one store.
11
+ *
12
+ * `scheme` is the machine's own answer, kept live by {@link ThemeProvider} — the only place that talks to
13
+ * `matchMedia`, so no two components can disagree about it during the frame after the visitor changes their system
14
+ * setting.
15
+ *
16
+ * `areas` is for a surface that paints more than one thing: the builder's canvas and its preview pane each get to
17
+ * be dark while the editor around them is light. An area with no entry FOLLOWS `mode`, and choosing a surface theme
18
+ * empties the map — an area's choice is an override of the current one, never a permanent divorce from it.
19
+ */
20
+ export type ThemeState = {
21
+ mode: Theme;
22
+ scheme: ColorScheme;
23
+ areas: Record<string, Theme>;
24
+ };
25
+ export type ThemeValue = {
3
26
  theme: Theme;
27
+ /** `theme` with `system` already resolved, and kept in step when the machine changes its mind. */
28
+ resolvedTheme: ColorScheme;
29
+ /** `system` gives the machine back the decision; the other two are the visitor overruling it. */
30
+ setTheme: (theme: Theme) => void;
4
31
  toggleTheme: () => void;
5
32
  };
@@ -1,5 +1,6 @@
1
1
  export * from './SchemaTypes';
2
2
  export * from './StyleTypes';
3
+ export * from './TemplateTypes';
3
4
  export * from './InteractionTypes';
4
5
  export * from './PluginTypes';
5
6
  export * from './ElementTypes';
@@ -10,6 +11,7 @@ export * from './BuilderTypes';
10
11
  export * from './NavigationTypes';
11
12
  export * from './CollectionTypes';
12
13
  export * from './ConnectorTypes';
14
+ export * from './ActionTypes';
13
15
  export * from './ComponentTypes';
14
16
  export * from './StateTypes';
15
17
  export * from './CommonTypes';
package/eslint.config.mjs CHANGED
@@ -64,6 +64,8 @@ export default tsEslint.config({
64
64
  'react-hooks/preserve-manual-memoization': 'off', // @todo: review later
65
65
  'prettier/prettier': ['warn', { trailingComma: 'none' }],
66
66
  '@typescript-eslint/restrict-template-expressions': ['error', { allowNumber: true }],
67
+ // Destructuring a key out so the rest carries everything else is how a field is dropped from an object here.
68
+ '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
67
69
  'import/order': [
68
70
  'error',
69
71
  {