efficient-easel 0.101.1 → 0.103.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 (234) hide show
  1. package/README.md +51 -0
  2. package/dist/LinkPicker-W2Rtxetz.d.ts +111 -0
  3. package/dist/autosave/index.d.ts +6 -3
  4. package/dist/autosave/index.js +1 -1
  5. package/dist/chrome/index.d.ts +3 -2
  6. package/dist/chrome/index.js +1 -25
  7. package/dist/chunk-26OOWIJJ.js +1 -0
  8. package/dist/chunk-2LK54I4E.js +1 -0
  9. package/dist/chunk-3M3A3DN2.js +4 -0
  10. package/dist/chunk-3QVB4AG2.js +3 -0
  11. package/dist/chunk-3WSPDAK2.js +1 -0
  12. package/dist/chunk-4ES5JGGX.js +1 -0
  13. package/dist/chunk-4MXFKJUY.js +1 -0
  14. package/dist/chunk-57DJOKXT.js +1 -0
  15. package/dist/chunk-5MZ3RNQQ.js +13 -0
  16. package/dist/chunk-5ZBY24K7.js +1 -0
  17. package/dist/chunk-66ICOE3I.js +8 -0
  18. package/dist/chunk-6DJHRLCU.js +25 -0
  19. package/dist/chunk-6FY3PZS3.js +1 -0
  20. package/dist/chunk-6TZTKAB5.js +1 -0
  21. package/dist/chunk-6UJ3Y6FC.js +1 -0
  22. package/dist/chunk-6W7WLPZH.js +1 -0
  23. package/dist/chunk-7F52SZOI.js +2 -0
  24. package/dist/chunk-7MU3RJ6S.js +1 -0
  25. package/dist/chunk-A7ZJII7O.js +1 -0
  26. package/dist/chunk-AJBJ74ME.js +1 -0
  27. package/dist/chunk-AKFJK65Z.js +1 -0
  28. package/dist/chunk-AKZWUV5Z.js +1 -0
  29. package/dist/chunk-BDTITTMW.js +1 -0
  30. package/dist/chunk-BSPCSC45.js +1 -0
  31. package/dist/chunk-BXZ6WLHC.js +22 -0
  32. package/dist/chunk-DUVRZ456.js +1 -0
  33. package/dist/chunk-F6CCTEIX.js +1 -0
  34. package/dist/chunk-FGNR22NY.js +1 -0
  35. package/dist/chunk-FUDHI5I4.js +1 -0
  36. package/dist/chunk-GENAF3P6.js +1 -0
  37. package/dist/chunk-GOTN2KY4.js +2 -0
  38. package/dist/chunk-GXN65JMA.js +1 -0
  39. package/dist/chunk-GXQCZJOP.js +1 -0
  40. package/dist/chunk-GZO72N3Q.js +0 -0
  41. package/dist/chunk-HDKTR5TZ.js +62 -0
  42. package/dist/chunk-HMX55DYT.js +1 -0
  43. package/dist/chunk-HQ4VVRIC.js +1 -0
  44. package/dist/chunk-HWW4XJOH.js +1 -0
  45. package/dist/chunk-I54UCYOU.js +1 -0
  46. package/dist/chunk-IQ5TA7AM.js +1 -0
  47. package/dist/chunk-IWAPPEL4.js +6 -0
  48. package/dist/chunk-IYT6NN2J.js +1 -0
  49. package/dist/chunk-KCBEE2MC.js +2 -0
  50. package/dist/chunk-KDYIMJTZ.js +1 -0
  51. package/dist/chunk-KQMML6JM.js +4 -0
  52. package/dist/chunk-LG436UTD.js +1 -0
  53. package/dist/chunk-MSBF7IW3.js +2 -0
  54. package/dist/chunk-NBJ2YY6Y.js +4 -0
  55. package/dist/chunk-OM67AJQC.js +1 -0
  56. package/dist/chunk-OORDMLL4.js +5 -0
  57. package/dist/chunk-OYX47SL7.js +1 -0
  58. package/dist/chunk-P67FP7PG.js +9 -0
  59. package/dist/chunk-PWZOS45R.js +2 -0
  60. package/dist/chunk-Q2HPBMG5.js +1 -0
  61. package/dist/chunk-Q3SQBNJB.js +1 -0
  62. package/dist/chunk-R2HLPNQF.js +1 -0
  63. package/dist/chunk-R5L2E7JX.js +1 -0
  64. package/dist/chunk-R5ZVNJLJ.js +2 -0
  65. package/dist/chunk-RLBXE4EU.js +1 -0
  66. package/dist/chunk-RW4XBUUW.js +1 -0
  67. package/dist/chunk-SERF2FAU.js +1 -0
  68. package/dist/chunk-TTJ54QGG.js +18 -0
  69. package/dist/chunk-VV5ADNBR.js +1 -0
  70. package/dist/chunk-YJXEHK6I.js +2 -0
  71. package/dist/chunk-Z3KBLIEH.js +10 -0
  72. package/dist/chunk-ZE7I3PLX.js +1 -0
  73. package/dist/chunk-ZWK3CBRU.js +1 -0
  74. package/dist/chunk-ZZ7VLIHQ.js +1 -0
  75. package/dist/drag/index.d.ts +3 -41
  76. package/dist/drag/index.js +1 -18
  77. package/dist/easel/index.js +1 -9
  78. package/dist/{words-BMzV04b1.d.ts → engine-DBxp_v6B.d.ts} +1 -58
  79. package/dist/fields/index.d.ts +2 -109
  80. package/dist/fields/index.js +1 -22
  81. package/dist/gold/index.d.ts +4 -2
  82. package/dist/host-DJ8Gzsx7.d.ts +552 -0
  83. package/dist/menu/index.js +1 -1
  84. package/dist/node-ops/index.js +1 -1
  85. package/dist/panelWidths-D9hTLR25.d.ts +66 -0
  86. package/dist/screen/components/AddBlockRow.d.ts +14 -0
  87. package/dist/screen/components/AddBlockRow.js +1 -0
  88. package/dist/screen/components/AddChildRow.d.ts +39 -0
  89. package/dist/screen/components/AddChildRow.js +1 -0
  90. package/dist/screen/components/AddSidePanel.d.ts +54 -0
  91. package/dist/screen/components/AddSidePanel.js +1 -0
  92. package/dist/screen/components/MediaSidePanel.d.ts +47 -0
  93. package/dist/screen/components/MediaSidePanel.js +1 -0
  94. package/dist/screen/components/NodeContextMenu.d.ts +364 -0
  95. package/dist/screen/components/NodeContextMenu.js +1 -0
  96. package/dist/screen/components/PageEditGuardNotices.d.ts +5 -0
  97. package/dist/screen/components/PageEditGuardNotices.js +1 -0
  98. package/dist/screen/components/PanelToggleIcon.d.ts +14 -0
  99. package/dist/screen/components/PanelToggleIcon.js +1 -0
  100. package/dist/screen/components/PreviewDeviceContext.d.ts +28 -0
  101. package/dist/screen/components/PreviewDeviceContext.js +1 -0
  102. package/dist/screen/components/PreviewPartsContext.d.ts +33 -0
  103. package/dist/screen/components/PreviewPartsContext.js +1 -0
  104. package/dist/screen/components/ScreenChrome.d.ts +5 -0
  105. package/dist/screen/components/ScreenChrome.js +1 -0
  106. package/dist/screen/components/ScreenDocumentContext.d.ts +20 -0
  107. package/dist/screen/components/ScreenDocumentContext.js +1 -0
  108. package/dist/screen/components/ScreenMount.d.ts +76 -0
  109. package/dist/screen/components/ScreenMount.js +1 -0
  110. package/dist/screen/components/ScreenStoreProvider.d.ts +63 -0
  111. package/dist/screen/components/ScreenStoreProvider.js +1 -0
  112. package/dist/screen/components/SectionScreenShell.d.ts +5 -0
  113. package/dist/screen/components/SectionScreenShell.js +16 -0
  114. package/dist/screen/components/SidePanelHead.d.ts +81 -0
  115. package/dist/screen/components/SidePanelHead.js +1 -0
  116. package/dist/screen/components/SlotChildActionsContext.d.ts +41 -0
  117. package/dist/screen/components/SlotChildActionsContext.js +1 -0
  118. package/dist/screen/components/UiIcon.d.ts +52 -0
  119. package/dist/screen/components/UiIcon.js +1 -0
  120. package/dist/screen/components/panel-widths.d.ts +37 -0
  121. package/dist/screen/components/panel-widths.js +1 -0
  122. package/dist/screen/components/usePartBridge.d.ts +66 -0
  123. package/dist/screen/components/usePartBridge.js +1 -0
  124. package/dist/screen/index.d.ts +31 -0
  125. package/dist/screen/index.js +1 -0
  126. package/dist/screen/lib/admin-bridge.d.ts +105 -0
  127. package/dist/screen/lib/admin-bridge.js +1 -0
  128. package/dist/screen/lib/backend-error.d.ts +106 -0
  129. package/dist/screen/lib/backend-error.js +1 -0
  130. package/dist/screen/lib/chrome-theme.d.ts +21 -0
  131. package/dist/screen/lib/chrome-theme.js +1 -0
  132. package/dist/screen/lib/client-only.d.ts +24 -0
  133. package/dist/screen/lib/client-only.js +1 -0
  134. package/dist/screen/lib/content/view-tiers.d.ts +25 -0
  135. package/dist/screen/lib/content/view-tiers.js +1 -0
  136. package/dist/screen/lib/document-addressing.d.ts +20 -0
  137. package/dist/screen/lib/document-addressing.js +1 -0
  138. package/dist/screen/lib/document-contract.d.ts +237 -0
  139. package/dist/screen/lib/document-contract.js +1 -0
  140. package/dist/screen/lib/document-hooks.d.ts +71 -0
  141. package/dist/screen/lib/document-hooks.js +0 -0
  142. package/dist/screen/lib/document-switch.d.ts +74 -0
  143. package/dist/screen/lib/document-switch.js +1 -0
  144. package/dist/screen/lib/failure.d.ts +54 -0
  145. package/dist/screen/lib/failure.js +1 -0
  146. package/dist/screen/lib/host-chrome.d.ts +181 -0
  147. package/dist/screen/lib/host-chrome.js +1 -0
  148. package/dist/screen/lib/host-inbound.d.ts +20 -0
  149. package/dist/screen/lib/host-inbound.js +1 -0
  150. package/dist/screen/lib/host.d.ts +20 -0
  151. package/dist/screen/lib/host.js +1 -0
  152. package/dist/screen/lib/key-scope.d.ts +23 -0
  153. package/dist/screen/lib/key-scope.js +1 -0
  154. package/dist/screen/lib/links/link-filters.d.ts +41 -0
  155. package/dist/screen/lib/links/link-filters.js +0 -0
  156. package/dist/screen/lib/load-error.d.ts +29 -0
  157. package/dist/screen/lib/load-error.js +1 -0
  158. package/dist/screen/lib/media-panel.d.ts +94 -0
  159. package/dist/screen/lib/media-panel.js +1 -0
  160. package/dist/screen/lib/media-picker.d.ts +68 -0
  161. package/dist/screen/lib/media-picker.js +1 -0
  162. package/dist/screen/lib/page-lock.d.ts +5 -0
  163. package/dist/screen/lib/page-lock.js +1 -0
  164. package/dist/screen/lib/puck/add-target-types.d.ts +55 -0
  165. package/dist/screen/lib/puck/add-target-types.js +0 -0
  166. package/dist/screen/lib/puck/block-choice.d.ts +52 -0
  167. package/dist/screen/lib/puck/block-choice.js +1 -0
  168. package/dist/screen/lib/puck/block-types-in.d.ts +39 -0
  169. package/dist/screen/lib/puck/block-types-in.js +1 -0
  170. package/dist/screen/lib/puck/content-tree.d.ts +196 -0
  171. package/dist/screen/lib/puck/content-tree.js +1 -0
  172. package/dist/screen/lib/puck/device-fields.d.ts +128 -0
  173. package/dist/screen/lib/puck/device-fields.js +1 -0
  174. package/dist/screen/lib/puck/field-buckets.d.ts +22 -0
  175. package/dist/screen/lib/puck/field-buckets.js +1 -0
  176. package/dist/screen/lib/puck/field-markers.d.ts +205 -0
  177. package/dist/screen/lib/puck/field-markers.js +1 -0
  178. package/dist/screen/lib/puck/hidable.d.ts +44 -0
  179. package/dist/screen/lib/puck/hidable.js +1 -0
  180. package/dist/screen/lib/puck/palette-sections.d.ts +96 -0
  181. package/dist/screen/lib/puck/palette-sections.js +1 -0
  182. package/dist/screen/lib/puck/panel-fields.d.ts +47 -0
  183. package/dist/screen/lib/puck/panel-fields.js +1 -0
  184. package/dist/screen/lib/puck/panel-no-control-mark.d.ts +74 -0
  185. package/dist/screen/lib/puck/panel-no-control-mark.js +1 -0
  186. package/dist/screen/lib/puck/part-id.d.ts +23 -0
  187. package/dist/screen/lib/puck/part-id.js +1 -0
  188. package/dist/screen/lib/puck/preview-click.d.ts +49 -0
  189. package/dist/screen/lib/puck/preview-click.js +1 -0
  190. package/dist/screen/lib/puck/preview-dom.d.ts +8 -0
  191. package/dist/screen/lib/puck/preview-dom.js +1 -0
  192. package/dist/screen/lib/puck/preview-events.d.ts +25 -0
  193. package/dist/screen/lib/puck/preview-events.js +1 -0
  194. package/dist/screen/lib/puck/preview-selection-context.d.ts +72 -0
  195. package/dist/screen/lib/puck/preview-selection-context.js +1 -0
  196. package/dist/screen/lib/puck/section-doc.d.ts +20 -0
  197. package/dist/screen/lib/puck/section-doc.js +1 -0
  198. package/dist/screen/lib/puck/slot-child-name.d.ts +186 -0
  199. package/dist/screen/lib/puck/slot-child-name.js +1 -0
  200. package/dist/screen/lib/puck/slot-heal.d.ts +5 -0
  201. package/dist/screen/lib/puck/slot-heal.js +1 -0
  202. package/dist/screen/lib/puck/slot-section-spec.d.ts +96 -0
  203. package/dist/screen/lib/puck/slot-section-spec.js +0 -0
  204. package/dist/screen/lib/puck/style-clipboard.d.ts +78 -0
  205. package/dist/screen/lib/puck/style-clipboard.js +1 -0
  206. package/dist/screen/lib/puck/text-control-kinds.d.ts +71 -0
  207. package/dist/screen/lib/puck/text-control-kinds.js +1 -0
  208. package/dist/screen/lib/puck/tree-reveal.d.ts +62 -0
  209. package/dist/screen/lib/puck/tree-reveal.js +1 -0
  210. package/dist/screen/lib/puck/use-section-ops.d.ts +86 -0
  211. package/dist/screen/lib/puck/use-section-ops.js +1 -0
  212. package/dist/screen/lib/screen-parts.d.ts +748 -0
  213. package/dist/screen/lib/screen-parts.js +1 -0
  214. package/dist/screen/lib/section-template-types.d.ts +49 -0
  215. package/dist/screen/lib/section-template-types.js +0 -0
  216. package/dist/screen/lib/section-templates.d.ts +23 -0
  217. package/dist/screen/lib/section-templates.js +1 -0
  218. package/dist/screen/lib/session-context.d.ts +30 -0
  219. package/dist/screen/lib/session-context.js +1 -0
  220. package/dist/screen/lib/session.d.ts +255 -0
  221. package/dist/screen/lib/session.js +1 -0
  222. package/dist/screen/screen.css +1102 -0
  223. package/dist/screen/words.d.ts +42 -0
  224. package/dist/screen/words.js +1 -0
  225. package/dist/session-DSQFmIvx.d.ts +43 -0
  226. package/dist/strings/catalogue.d.ts +13 -4
  227. package/dist/strings/catalogue.js +1 -1
  228. package/dist/strings/index.d.ts +5 -2
  229. package/dist/strings/index.js +1 -1
  230. package/dist/style-clipboard/index.js +1 -1
  231. package/dist/{types-DGcCsxs8.d.ts → types-CqY85foL.d.ts} +3 -65
  232. package/dist/words-D_Lnw1Gr.d.ts +59 -0
  233. package/package.json +348 -2
  234. package/dist/chunk-IG3U5NWJ.js +0 -1
@@ -0,0 +1,105 @@
1
+ import { RefObject } from 'react';
2
+ import { EaselSession } from './session.js';
3
+ import '../../blocks/index.js';
4
+ import '../../types-E3HrTPg2.js';
5
+ import '../../data/index.js';
6
+ import '../../types-41704JE4.js';
7
+ import '../../resolve-D68pb3Bx.js';
8
+ import '../../plan-DChbUXdS.js';
9
+ import './host-chrome.js';
10
+ import './links/link-filters.js';
11
+ import '../../LinkPicker-W2Rtxetz.js';
12
+ import './document-contract.js';
13
+ import './document-hooks.js';
14
+ import './section-template-types.js';
15
+ import './puck/content-tree.js';
16
+
17
+ /** The `storefront-editor:auth` payload the admin portal bridges in. */
18
+ interface AuthMessage {
19
+ type?: string;
20
+ token?: string;
21
+ /**
22
+ * The WEBSITE this editor is working on, as a real `StorefrontSite` id — the
23
+ * admin's answer to "where does an upload from this editor belong?" (its own
24
+ * page target's site, else the website the operator has open). OPTIONAL by
25
+ * design: an admin build that predates it sends nothing, and "the admin cannot
26
+ * tell you" is a real answer that must not be turned into a default.
27
+ *
28
+ * A SEPARATE IDENTITY FROM `brandId` — a brand is a wheel manufacturer, a site
29
+ * is a storefront. They are never interchangeable, so neither is ever used as a
30
+ * fallback for the other.
31
+ */
32
+ siteId?: string;
33
+ /**
34
+ * The BRAND being edited, the legacy upload scope. Kept exactly as it was:
35
+ * still read, still stored, still the only thing that can produce a `?brand=`
36
+ * upload. Untouched by the site bridge above.
37
+ */
38
+ brandId?: string;
39
+ theme?: string;
40
+ /** Operator capabilities the CONSOLE has resolved. See {@link BridgedCapabilities}. */
41
+ can?: unknown;
42
+ }
43
+ /**
44
+ * Capabilities the editor may not decide for itself.
45
+ *
46
+ * `canCreatePlatformTemplate` is the operator bar for "Save site as platform
47
+ * template". The editor CANNOT derive it: being on localhost, holding a token,
48
+ * having no tenant info, a URL parameter, something in localStorage and the mere
49
+ * presence of a siteId are all things a page can arrange for itself. Only the
50
+ * authenticated Admin Console knows whether this user is a platform operator, so
51
+ * it says so explicitly on the already origin-gated auth message.
52
+ *
53
+ * This is a UI affordance ONLY. The backend re-checks `IsPlatformOperator` on
54
+ * every call, so a forged flag buys a hidden button and a 403.
55
+ *
56
+ * Optional with a safe default of `false`: the shop and admin images deploy
57
+ * independently, so an editor build that REQUIRED this field would break against
58
+ * any console still on the previous build.
59
+ */
60
+ type BridgedCapabilities = {
61
+ canCreatePlatformTemplate: boolean;
62
+ };
63
+ declare const NO_BRIDGED_CAPABILITIES: BridgedCapabilities;
64
+ /**
65
+ * Apply one accepted auth grant — the whole effect of a trusted
66
+ * `storefront-editor:auth`, minus the React state the hook owns.
67
+ *
68
+ * Split out of the listener so the grant's CONTRACT can be exercised without a
69
+ * DOM and a mounted editor (see scripts/test-editor-site-bridge.ts): the listener
70
+ * decides whether to trust a message, this decides what a trusted one does.
71
+ *
72
+ * The two things it writes are deliberately separate concerns, both kept on the
73
+ * editor SESSION (lib/session — the one the grant was delivered to):
74
+ * • the JWT + the legacy brand (read through lib/editor-auth) — the existing
75
+ * contract, set with exactly the values it always was;
76
+ * • the website scope (read through lib/editor-site), which the document
77
+ * context also writes to. See that module for why they don't share a slot.
78
+ *
79
+ * Unconditional in both cases: a grant with no `siteId` CLEARS the bridged scope
80
+ * rather than leaving the last website standing, so a refresh after the operator
81
+ * moved on can't file the next upload against where they used to be.
82
+ */
83
+ declare function applyAuthGrant(d: AuthMessage & {
84
+ token: string;
85
+ }, opts?: {
86
+ stampChromeTheme?: boolean;
87
+ session?: EaselSession;
88
+ }): void;
89
+ interface AdminBridge {
90
+ /** The bridged admin JWT — null until the handshake completes. */
91
+ token: string | null;
92
+ /** Live ref to the same token, for stable callbacks that must not re-bind. */
93
+ tokenRef: RefObject<string | null>;
94
+ /** What the CONSOLE says this operator may do. All false until it says so. */
95
+ capabilities: BridgedCapabilities;
96
+ }
97
+ declare function useAdminBridge(handlers?: {
98
+ /** Called after each auth grant is applied. `hadToken` distinguishes a
99
+ * refresh (e.g. after an auth-expired save — retry it) from the first grant. */
100
+ onAuth?: (hadToken: boolean) => void;
101
+ /** Every OTHER message from a trusted admin origin (already origin-gated). */
102
+ onMessage?: (data: unknown) => void;
103
+ }): AdminBridge;
104
+
105
+ export { type AdminBridge, type AuthMessage, type BridgedCapabilities, NO_BRIDGED_CAPABILITIES, applyAuthGrant, useAdminBridge };
@@ -0,0 +1 @@
1
+ export{NO_BRIDGED_CAPABILITIES,applyAuthGrant,useAdminBridge}from"../../chunk-Q3SQBNJB.js";import"../../chunk-3WSPDAK2.js";import"../../chunk-R5ZVNJLJ.js";import"../../chunk-6TZTKAB5.js";import"../../chunk-AJBJ74ME.js";
@@ -0,0 +1,106 @@
1
+ import { SaveConflict, LockHolder } from '../../edit-lock/index.js';
2
+
3
+ /**
4
+ * lib/backend-error.ts — why an editor's backend call failed, in the
5
+ * editor's own terms, and how the host says what its own failures mean.
6
+ *
7
+ * Moved from lib/web-backend (which re-exports all of it) so the editor's screen
8
+ * can classify a failure — a document that would not load, a save refused —
9
+ * without importing the website's backend interfaces, and can move into
10
+ * efficient-easel with the screen (doc/adr/0004). Nothing here names a page or
11
+ * a site.
12
+ */
13
+
14
+ /** Why a backend call failed, in the editor's own terms. */
15
+ type WebsiteBackendErrorKind =
16
+ /** The session is not (or no longer) authorised. The editor tells its host
17
+ * (`storefront-editor:auth-expired`) and treats the call as failed. */
18
+ "unauthorized"
19
+ /** A save was refused: the stored page moved on since this copy was loaded.
20
+ * Carries `conflict`. */
21
+ | "changed-elsewhere"
22
+ /** Somebody else holds the page (a claim), or took it from this tab (a save).
23
+ * Carries `holder`. */
24
+ | "lock-taken"
25
+ /** There is no such page, site or template. */
26
+ | "not-found"
27
+ /** The backend understood the request and refused it as wrong. */
28
+ | "invalid"
29
+ /** No answer: offline, timed out, the backend itself failing. */
30
+ | "unavailable";
31
+ /**
32
+ * The one error a backend rejects with.
33
+ *
34
+ * `message` is shown to the operator where the editor has nowhere better to
35
+ * read from (a document that would not load), so write it for a person.
36
+ */
37
+ declare class WebsiteBackendError extends Error {
38
+ readonly kind: WebsiteBackendErrorKind;
39
+ /** `changed-elsewhere`: who saved, and whether it was this person's own tab. */
40
+ readonly conflict?: SaveConflict;
41
+ /** `lock-taken`: who holds the page. */
42
+ readonly holder?: LockHolder;
43
+ /** `invalid`: the inputs that were refused, by name, each with the reason —
44
+ * when the backend can say which. The editor shows it beside that input. */
45
+ readonly fields?: Readonly<Record<string, string>>;
46
+ constructor(kind: WebsiteBackendErrorKind, message?: string, detail?: {
47
+ conflict?: SaveConflict;
48
+ holder?: LockHolder;
49
+ fields?: Readonly<Record<string, string>>;
50
+ cause?: unknown;
51
+ });
52
+ }
53
+ /**
54
+ * Whether `err` is a backend failure — optionally of one kind.
55
+ *
56
+ * By NAME and shape, not `instanceof`: an embedder's bundle and this package
57
+ * may each carry their own copy of the class (two module graphs), and an error
58
+ * thrown by one must still be read by the other.
59
+ */
60
+ declare function isBackendError(err: unknown, kind?: WebsiteBackendErrorKind): err is WebsiteBackendError;
61
+ /** The status the editor gives a call that got no answer at all. */
62
+ declare const STATUS_UNREACHABLE = 0;
63
+ /**
64
+ * A failure of the HOST'S OWN HTTP client, as the two things the editor's
65
+ * shared rules read off one: a status and the response body.
66
+ *
67
+ * Not every call goes through a `WebsiteBackend` yet (doc/adr/0002: the groups
68
+ * that have not crossed), and a call that does not rejects with the host's own
69
+ * error class — EFFICIENT's `ApiError`. The edit lock, the refused-save notice
70
+ * and the "could not open this page" message all have to read such an error,
71
+ * and until this they imported that class to do it. The host tells the editor
72
+ * how to read its errors instead ({@link provideHostFailures}); the editor
73
+ * imports none of them.
74
+ */
75
+ interface HostFailure {
76
+ /** HTTP-style: 401, 404, 409, 5xx — or {@link STATUS_UNREACHABLE}. */
77
+ status: number;
78
+ /** The response body, or null. */
79
+ data: unknown;
80
+ message: string;
81
+ }
82
+ interface HostFailures {
83
+ /** A host client error as a {@link HostFailure}; null for anything else. */
84
+ read(err: unknown): HostFailure | null;
85
+ /** What the host says when its server cannot be reached at all. */
86
+ unreachableMessage: string;
87
+ /** The host's whole sentence for a document it REFUSED to open — a correct
88
+ * outcome of its own, not a failed call; null for everything else. */
89
+ loadRefusal?(err: unknown, document: {
90
+ slug: string;
91
+ }): string | null;
92
+ }
93
+ /** Tell the editor how to read the host client's own errors. Called once, by
94
+ * the host's backend module as it loads (EFFICIENT's: `lib/efficient-backend`). */
95
+ declare function provideHostFailures(failures: HostFailures): void;
96
+ /** `err` as the host's client failure it is, or null when it is not one (or no
97
+ * host has said how to read its errors). */
98
+ declare function readHostFailure(err: unknown): HostFailure | null;
99
+ /** The host's sentence for a document it refused to open, or null. */
100
+ declare function hostLoadRefusalOf(err: unknown, document: {
101
+ slug: string;
102
+ }): string | null;
103
+ /** The host's own "server cannot be reached" sentence, or a plain one. */
104
+ declare function hostUnreachableMessage(): string;
105
+
106
+ export { type HostFailure, STATUS_UNREACHABLE, WebsiteBackendError, type WebsiteBackendErrorKind, hostLoadRefusalOf, hostUnreachableMessage, isBackendError, provideHostFailures, readHostFailure };
@@ -0,0 +1 @@
1
+ export{STATUS_UNREACHABLE,WebsiteBackendError,hostLoadRefusalOf,hostUnreachableMessage,isBackendError,provideHostFailures,readHostFailure}from"../../chunk-KDYIMJTZ.js";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Editor chrome theme bridge — the embedded editor is deliberately LIGHT-ONLY.
3
+ *
4
+ * The admin portal bridges its resolved efficient-shell theme in the
5
+ * `storefront-editor:auth` message (see efficient-admin-portal's
6
+ * PageBlockEditor). Every editor entry point — the page/template editor AND the
7
+ * standalone section editor — still hands that value here so the call site stays
8
+ * uniform, but the editor no longer mirrors the admin's dark palette: per owner
9
+ * directive the storefront editor renders in the light base regardless of the
10
+ * bridged theme. This function stamps `data-editor-theme="light"` unconditionally;
11
+ * the CSS (components/storefront-editor.css) carries only the light `--sf-*` base,
12
+ * so the editor chrome is always light.
13
+ */
14
+ /**
15
+ * Reflect the (light-only) editor chrome theme onto the editor document.
16
+ * The bridged admin theme is intentionally ignored — the editor is always light.
17
+ * No-op server-side.
18
+ */
19
+ declare function applyEaselChromeTheme(theme: string | null | undefined): void;
20
+
21
+ export { applyEaselChromeTheme };
@@ -0,0 +1 @@
1
+ export{applyEaselChromeTheme}from"../../chunk-3WSPDAK2.js";
@@ -0,0 +1,24 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ /**
4
+ * lib/client-only.tsx — a component that is drawn in the browser only: what
5
+ * `next/dynamic` with `{ ssr: false }` did for the editor's screen.
6
+ *
7
+ * The editor never needs a server render: it draws only after a client-side
8
+ * sign-in. The screen used `next/dynamic` for that, which is a Next.js import,
9
+ * and the screen moved into efficient-easel, whose only peers are react and
10
+ * react-dom (efficient-web-builder doc/adr/0004). This is the same thing in
11
+ * React's own terms: nothing on the server, nothing on the client's first
12
+ * render (so hydration matches), then the component.
13
+ *
14
+ * The component is IMPORTED, not loaded with `import()`. Every module of the
15
+ * screen imports with no DOM (tests/screen-one-graph.test.ts), so nothing here
16
+ * needs keeping out of a server's module graph; and a dynamic `import()` of a
17
+ * file of this package is a second instance of it in a host that loads the
18
+ * package through `require` (a CommonJS test runner), with a second copy of
19
+ * every context the screen provides, so the provider above it and the chrome
20
+ * below it would not meet.
21
+ */
22
+ declare function clientOnly<P extends object>(Component: ComponentType<P>): ComponentType<P>;
23
+
24
+ export { clientOnly };
@@ -0,0 +1 @@
1
+ export{clientOnly}from"../../chunk-GXQCZJOP.js";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * View tiers — the desktop / tablet / mobile split that every PER-VIEW section
3
+ * setting is authored against.
4
+ *
5
+ * A merchant does not set one number for all screens: they pick a view in the
6
+ * editor chrome's top bar and set THAT view. Three separate places have to agree
7
+ * on what "tablet" means for that to work — the top-bar switcher
8
+ * (PreviewDeviceContext), the field the merchant edits, and the live grid that
9
+ * renders the result — so the tier vocabulary lives here, once, rather than
10
+ * being restated by each feature that grows a per-view control.
11
+ *
12
+ * The Footer's columns-per-line and logo-fill toggles were the first callers;
13
+ * the Alloy Wheels Listing's wheels-per-row (lib/wheels/plp-grid) is the second.
14
+ */
15
+ type ViewTier = "desktop" | "tablet" | "mobile";
16
+ /** Order the tiers surface in the UI (widest → narrowest). */
17
+ declare const VIEW_TIERS: ViewTier[];
18
+ /** Human label per tier (control hints, a11y). */
19
+ declare const VIEW_TIER_LABEL: Record<ViewTier, string>;
20
+ declare const VIEW_TABLET_MIN = 720;
21
+ declare const VIEW_DESKTOP_MIN = 1100;
22
+ /** Which tier a viewport width falls in. */
23
+ declare function viewTierForWidth(width: number): ViewTier;
24
+
25
+ export { VIEW_DESKTOP_MIN, VIEW_TABLET_MIN, VIEW_TIERS, VIEW_TIER_LABEL, type ViewTier, viewTierForWidth };
@@ -0,0 +1 @@
1
+ var e=["desktop","tablet","mobile"],t={desktop:"Desktop",tablet:"Tablet",mobile:"Mobile"},o=720,b=1100;function l(e){return e>=1100?"desktop":e>=720?"tablet":"mobile"}export{b as VIEW_DESKTOP_MIN,o as VIEW_TABLET_MIN,e as VIEW_TIERS,t as VIEW_TIER_LABEL,l as viewTierForWidth};
@@ -0,0 +1,20 @@
1
+ export { A as AnyDocumentAddressing, a as DocumentAddressing, N as NO_DOCUMENT_ADDRESSING } from '../../host-DJ8Gzsx7.js';
2
+ import './document-contract.js';
3
+ import './session.js';
4
+ import 'react';
5
+ import '../../blocks/index.js';
6
+ import '../../types-E3HrTPg2.js';
7
+ import '../../data/index.js';
8
+ import '../../types-41704JE4.js';
9
+ import '../../resolve-D68pb3Bx.js';
10
+ import '../../plan-DChbUXdS.js';
11
+ import './document-switch.js';
12
+ import '../../engine-DBxp_v6B.js';
13
+ import '../../edit-lock/index.js';
14
+ import './admin-bridge.js';
15
+ import './host-chrome.js';
16
+ import './links/link-filters.js';
17
+ import '../../LinkPicker-W2Rtxetz.js';
18
+ import './document-hooks.js';
19
+ import './section-template-types.js';
20
+ import './puck/content-tree.js';
@@ -0,0 +1 @@
1
+ export{NO_DOCUMENT_ADDRESSING}from"../../chunk-RLBXE4EU.js";
@@ -0,0 +1,237 @@
1
+ /**
2
+ * lib/document-contract.ts — WHAT STORES A DOCUMENT, as the provider
3
+ * that loads and saves one asks it (components/ScreenDocumentContext): a
4
+ * resolved document, the adapter that reads and writes it, and the
5
+ * capabilities the one chrome consults.
6
+ *
7
+ * The contract and nothing that keeps it. The two adapters there are — a
8
+ * website's pages, a website template's pages — are the website's, and stand
9
+ * where they always have (lib/editor-document-adapter, whose account of why
10
+ * the capabilities exist is the one to read, and which still hands these
11
+ * types on). They are here because the provider is a file of the editor's
12
+ * screen, which imports no website (doc/adr/0003, seam W5): it is handed its
13
+ * adapter (lib/document-addressing) and needs only the shape of one.
14
+ *
15
+ * The capabilities keep the names the chrome and the panels have always read,
16
+ * most of them in a website's words. Which of them any editor has, and under
17
+ * what name, is settled when the screen moves to efficient-easel.
18
+ *
19
+ * So do the four shapes an adapter hands back besides a document — a row of the
20
+ * page list, the edit lock, the site record and what is written of it. They are
21
+ * declared HERE and not with the backend's contract (lib/web-backend, which
22
+ * names them in its own groups and hands them on): this module moves into
23
+ * efficient-easel with the screen (doc/adr/0004), and the website's backend
24
+ * does not. The record and its patch are a website's, as most capabilities'
25
+ * names are: the screen reads neither and hands them through to the layer's
26
+ * own chrome, and whether the contract keeps them is settled with the names.
27
+ */
28
+ /** One row of the editor's page list. Rows arrive in display order. */
29
+ type EaselPageRow = {
30
+ id: string;
31
+ slug: string;
32
+ /** What the list calls the page. */
33
+ label: string;
34
+ /** Header text of the row's group (null / absent = top level). */
35
+ group?: string | null;
36
+ /** Stable key of that group — two groups may share a header text. */
37
+ groupKey?: string;
38
+ /** Not published yet (drives the "draft" tag). False where pages never publish. */
39
+ draft: boolean;
40
+ /** Page kind, where the backend has kinds (`dynamic`, `lightbox`, …). */
41
+ kind?: string | null;
42
+ };
43
+ /** The advisory "somebody is editing this page" lock. */
44
+ interface WebsiteEditLock {
45
+ /**
46
+ * Claim the page, refresh the claim (the heartbeat) or — `takeover` — take it
47
+ * from whoever holds it. Resolves once this tab holds the page; rejects
48
+ * `lock-taken` (with `holder`) while somebody else does.
49
+ */
50
+ claim(id: string, clientId: string, takeover: boolean): Promise<{
51
+ heartbeatSeconds: number;
52
+ }>;
53
+ /** Hand the page back. Best-effort: a lock expires by itself. */
54
+ release(id: string, clientId: string): Promise<void>;
55
+ }
56
+ /** What the editor reads of the website itself. */
57
+ interface SiteRecord {
58
+ /** The website's display name. */
59
+ name: string;
60
+ /** Its public slug, where it has one. */
61
+ slug?: string | null;
62
+ /** The site-wide Google Maps browser key the canvas's map blocks draw with. */
63
+ mapsApiKey?: string | null;
64
+ /** The site-wide Google Maps cloud style. */
65
+ mapsMapId?: string | null;
66
+ }
67
+ /** The part of the site record the editor writes. */
68
+ type SiteRecordPatch = {
69
+ mapsApiKey?: string;
70
+ };
71
+ /** What the pointed-at document supports — its record type, and the backend
72
+ * behind it. The editor renders ONE chrome and consults these to include the
73
+ * few genuinely mode-specific controls. */
74
+ type EaselCapabilities = {
75
+ /** Publish/unpublish + draft state exist (site pages on a backend that
76
+ * publishes). A template page has no public URL — its documents save, never
77
+ * publish — and neither does a page whose backend has no `pages.publish`. */
78
+ canPublish: boolean;
79
+ /** Site-wide panels apply: SEO/sitemap, site settings, maps keys, chat,
80
+ * favicon — anything that reads or writes the WEBSITE, not the document.
81
+ * These rows are EFFICIENT's (`/api/storefront/*`, still read by their own
82
+ * callers), so this is false for a template AND for a page on an embedder's
83
+ * own backend. */
84
+ hasSiteSettings: boolean;
85
+ /** The styles tab (site theme/fonts) reads StorefrontThemeSettings; a
86
+ * template's theme rides inside its own document instead. */
87
+ hasSiteTheme: boolean;
88
+ /** Placeholder frames are on: the canvas renders every MEDIA slot as its
89
+ * built-in placeholder hint (template authoring — a template never previews
90
+ * media; its text and structure always render as authored). */
91
+ placeholderFrames: boolean;
92
+ /** Media may be picked/uploaded onto this document. False for templates —
93
+ * a template never owns, stores or selects media (the backend strips it on
94
+ * every template write), so every upload/picker affordance is hidden. */
95
+ mediaEditing: boolean;
96
+ /** Pages are created through the HOST's New Page form (the admin console's —
97
+ * title, URL handle, SEO and the template-library picker live there). When
98
+ * false — the backend has `pages.create` — the switcher offers its own
99
+ * lightweight inline "Add page". */
100
+ pageCreationInAdminForm: boolean;
101
+ /** Pages may be deleted inline from the switcher (the backend has
102
+ * `pages.remove`; an EFFICIENT site page's delete lives in the admin Pages
103
+ * list with its guards). */
104
+ canDeletePagesInline: boolean;
105
+ /** An advisory "somebody is editing this" lock exists for the document
106
+ * (`WebsiteBackend.lock`, site pages). Without one the editor is writable
107
+ * from the start and the version check alone guards a save. */
108
+ hasEditLock: boolean;
109
+ /** The "somebody else is editing" and "your save was refused" notices apply:
110
+ * a website's page, whose saves are versioned and may be locked. A template
111
+ * page is neither, so the notices have nothing to say there. */
112
+ hasEditGuard: boolean;
113
+ /** The document carries the storefront's PINNED chrome — the Header marker
114
+ * and the Footer the chrome seeds and heals. EFFICIENT's own furniture: a
115
+ * page on an embedder's backend is its sections and nothing else. The Header
116
+ * is a commerce block and the Footer a service one, so it also needs both of
117
+ * those sets offered — seeding either would write a withheld block. */
118
+ hasPinnedChrome: boolean;
119
+ /** Website-scoped controls (Appearance, Header, Live chat) stay in view as
120
+ * explained placeholders — a website TEMPLATE, where each website made from
121
+ * it sets its own. False where they exist for real (a site page) and where
122
+ * the backend has none of them at all (an embedder's own): there the chrome
123
+ * offers no entry to a panel that could only apologise. */
124
+ explainsSiteSettings: boolean;
125
+ /** The website's own record can be read (`site.get`): its name, its Maps
126
+ * key. False for a template, and for an EFFICIENT page opened without a
127
+ * site id — a site row IS its id. */
128
+ hasSiteRecord: boolean;
129
+ /** …and its Maps key written (`site.update`). */
130
+ canEditSiteRecord: boolean;
131
+ /** The top bar's Preview link has an address: `preview.href`, or the
132
+ * storefront's own rule under the EFFICIENT backend. */
133
+ hasPreviewLink: boolean;
134
+ /** The product catalog is read into the canvas (the wheels page's seed, the
135
+ * listing's live rows). EFFICIENT's, until the catalog joins the backend
136
+ * contract — and only where the commerce blocks it fills are offered. */
137
+ hasCatalog: boolean;
138
+ /** The website's forms can be listed, built and edited (the Form section's
139
+ * picker, and the host's form builder behind it). EFFICIENT's, until forms
140
+ * join the backend contract: under any other backend — or where the service
141
+ * blocks are not offered — the picker offers nothing to choose, build or
142
+ * retry. */
143
+ hasForms: boolean;
144
+ /** The website's blog can be listed (`backend.blog`): a section's optional
145
+ * "Blog post source" offers its posts, and a link has a "Blog post" target.
146
+ * Needs the backend's blog AND the service blocks offered — EFFICIENT's
147
+ * backend always has one, so there it is `offersService` exactly. Without
148
+ * it a block that is already linked to a post says so and can only be
149
+ * unlinked, and the link picker lists no post. */
150
+ hasBlog: boolean;
151
+ /** The COMMERCE set of blocks is offered (lib/editor-blocks). Without it a
152
+ * link has no "Product" target and no product-type row: nothing on the page
153
+ * could be a product listing. True unless the host chose its sets. */
154
+ offersCommerce: boolean;
155
+ /** The SERVICE set of blocks is offered. Without it a link has no "Blog post"
156
+ * target, and a section's optional "Blog post source" is not drawn. True
157
+ * unless the host chose its sets. */
158
+ offersService: boolean;
159
+ };
160
+ /** A resolved, editable document. */
161
+ type EaselDocument = {
162
+ id: string;
163
+ layout: unknown;
164
+ /** Page kind (`dynamic` drives product binding) — site pages only. */
165
+ kind?: string | null;
166
+ /** VERSION of the document as loaded — what a save says it is replacing, so a
167
+ * second editor's autosave is refused instead of erasing this one's work.
168
+ * `null` for a record type with no version check (a template page). */
169
+ version?: string | null;
170
+ /** Why this document may NEVER be written, in words for the operator — "Read-only
171
+ * — this campaign is sent": a record that is the account of something that
172
+ * already happened (0.103.0). Carried, the editor holds the document
173
+ * read-only for good: its saves are refused, its edit lock is never claimed,
174
+ * and the save pill's place says this. Absent (every website document), it
175
+ * is writable as it always was. */
176
+ readOnlyReason?: string;
177
+ };
178
+ interface EaselDocumentAdapter {
179
+ capabilities: EaselCapabilities;
180
+ /** Resolve the document for `slug`, or null when it doesn't exist. Template
181
+ * mode may CREATE the missing home page (a fresh template opens on
182
+ * something, mirroring backend migration 0021). */
183
+ resolve(slug: string): Promise<EaselDocument | null>;
184
+ /** Persist a document's working layout; answers with the version it now has.
185
+ *
186
+ * `version` is what `resolve` returned (refreshed from each save's answer):
187
+ * the version this write replaces. A record type with a version check REFUSES
188
+ * a null — writing a document blind is the bug this parameter exists for, so
189
+ * it fails loudly rather than quietly saving unguarded. A record type without
190
+ * one ignores it.
191
+ *
192
+ * `clientId` is this editor tab, the id its edit-lock claim sends. A record
193
+ * type with a lock sends it, and the backend then refuses the write as
194
+ * `lock-taken` once somebody else has taken the document from this tab.
195
+ * A record type without a lock ignores it. */
196
+ saveLayout(id: string, layout: Record<string, unknown>, version: string | null, clientId?: string): Promise<{
197
+ version: string | null;
198
+ }>;
199
+ /** Re-read the CURRENT stored version of one document, without its layout.
200
+ *
201
+ * Only a record type with a version check has one. It exists for the single
202
+ * case where this editor is refused by its own earlier save from another
203
+ * session: the operator asked for one editor, not a question, so the write is
204
+ * re-based on what is stored and sent again — see
205
+ * `ScreenDocumentContext.persistLayout`. A record type without a version
206
+ * check never conflicts, so it does not implement this. */
207
+ rereadVersion?(id: string): Promise<string | null>;
208
+ /** Make the stored working copy the public one (`capabilities.canPublish`). */
209
+ publish?(id: string, version?: string): Promise<{
210
+ version: string | null;
211
+ }>;
212
+ /** The document's advisory edit lock (`capabilities.hasEditLock`). */
213
+ lock?: WebsiteEditLock;
214
+ /** The rows the page switcher navigates between. */
215
+ listPages(): Promise<EaselPageRow[]>;
216
+ /** Inline page creation (absent when the host's form owns it). */
217
+ createPage?(input: {
218
+ slug: string;
219
+ title: string;
220
+ layout: Record<string, unknown>;
221
+ }): Promise<EaselPageRow>;
222
+ /** Inline page deletion. */
223
+ deletePage?(id: string): Promise<void>;
224
+ /** The website's record (`capabilities.hasSiteRecord`). */
225
+ site?(): Promise<SiteRecord>;
226
+ /** Save the website's Maps key (`capabilities.canEditSiteRecord`). */
227
+ updateSite?(patch: SiteRecordPatch): Promise<SiteRecord>;
228
+ /** The name of the template this document is a page of (template mode) —
229
+ * the canvas header's wordmark while it is edited. */
230
+ templateName?(): Promise<string>;
231
+ /** The top bar's Preview link for a page, when the BACKEND names it
232
+ * (`preview.href`). Absent under the EFFICIENT backend, whose link is the
233
+ * storefront's own rule (components/usePreviewHref). */
234
+ previewHref?(slug: string): string;
235
+ }
236
+
237
+ export type { EaselCapabilities, EaselDocument, EaselDocumentAdapter, EaselPageRow, SiteRecord, SiteRecordPatch, WebsiteEditLock };
@@ -0,0 +1 @@
1
+ import"../../chunk-GZO72N3Q.js";
@@ -0,0 +1,71 @@
1
+ import { Data } from '../../blocks/index.js';
2
+ import { EaselCapabilities } from './document-contract.js';
3
+ import 'react';
4
+ import '../../types-E3HrTPg2.js';
5
+ import '../../data/index.js';
6
+ import '../../types-41704JE4.js';
7
+ import '../../resolve-D68pb3Bx.js';
8
+ import '../../plan-DChbUXdS.js';
9
+
10
+ /**
11
+ * WHAT A HOST DOES TO A DOCUMENT AS IT OPENS AND AS IT IS STORED.
12
+ *
13
+ * The editor loads a page's layout and hands it to the canvas; every edit goes
14
+ * back through the autosave. Between those two a HOST may have work of its own
15
+ * that is not the editor's to know (doc/adr/0002, doc/adr/0004): the storefront
16
+ * seeds a fresh wheels page with its catalogue sections and gives the canvas
17
+ * the live catalogue a listing block draws on a published page — and takes
18
+ * that catalogue back out of every edit, so it is never saved.
19
+ *
20
+ * That used to be written into the editor's document context, which therefore
21
+ * imported the shop's catalogue. It is the host's now, handed over on the
22
+ * editor's session beside its registry and its chrome (`documentHooks`,
23
+ * lib/session; the storefront's: lib/storefront-document). An editor
24
+ * given none opens a document as it is stored and stores it as it is edited.
25
+ *
26
+ * The hooks are the host's; their SHAPE is the session's, so this module moves
27
+ * into efficient-easel with the screen (doc/adr/0004), and it reads the
28
+ * capabilities off the document's contract (lib/document-contract)
29
+ * rather than off the website's adapters that hand them on.
30
+ */
31
+
32
+ /** What the editor knows of the document it is about to open. */
33
+ interface OpeningDocument {
34
+ /** The page's slug (a template's page too). */
35
+ slug: string;
36
+ /** Whether it is a page of a template, which has no website of its own. */
37
+ isTemplate: boolean;
38
+ /** What the backend in force supports — a host's hooks gate on these, as the
39
+ * editor's own panels do. */
40
+ capabilities: EaselCapabilities;
41
+ }
42
+ interface EaselDocumentHooks {
43
+ /**
44
+ * Called as a document's load STARTS, so a host can fetch what it needs
45
+ * while the layout is still on its way. The function it answers with is
46
+ * handed the stored layout and resolves to the layout the canvas opens on.
47
+ *
48
+ * INITIAL data only — the canvas reads it once — and best effort: it must
49
+ * resolve (to the layout it was given, when the host's own read failed), for
50
+ * a rejection here is a document that does not open.
51
+ */
52
+ opening?(document: OpeningDocument): (layout: Data) => Promise<Data>;
53
+ /**
54
+ * Every edit on its way to the autosave, and the layout Publish sends: take
55
+ * back out whatever {@link opening} put in for display only. Synchronous,
56
+ * and the SAME object back when there is nothing to take out.
57
+ */
58
+ stored?(layout: Data): Data;
59
+ /**
60
+ * The same taking-out for ONE node that is leaving this document for
61
+ * another — a section copied onto another page is saved there directly, and
62
+ * never passes through {@link stored}. The same node back when there is
63
+ * nothing to take out.
64
+ */
65
+ storedNode?<T extends {
66
+ type: string;
67
+ props?: Record<string, unknown>;
68
+ }>(node: T): T;
69
+ }
70
+
71
+ export type { EaselDocumentHooks, OpeningDocument };
File without changes