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.
- package/README.md +51 -0
- package/dist/LinkPicker-W2Rtxetz.d.ts +111 -0
- package/dist/autosave/index.d.ts +6 -3
- package/dist/autosave/index.js +1 -1
- package/dist/chrome/index.d.ts +3 -2
- package/dist/chrome/index.js +1 -25
- package/dist/chunk-26OOWIJJ.js +1 -0
- package/dist/chunk-2LK54I4E.js +1 -0
- package/dist/chunk-3M3A3DN2.js +4 -0
- package/dist/chunk-3QVB4AG2.js +3 -0
- package/dist/chunk-3WSPDAK2.js +1 -0
- package/dist/chunk-4ES5JGGX.js +1 -0
- package/dist/chunk-4MXFKJUY.js +1 -0
- package/dist/chunk-57DJOKXT.js +1 -0
- package/dist/chunk-5MZ3RNQQ.js +13 -0
- package/dist/chunk-5ZBY24K7.js +1 -0
- package/dist/chunk-66ICOE3I.js +8 -0
- package/dist/chunk-6DJHRLCU.js +25 -0
- package/dist/chunk-6FY3PZS3.js +1 -0
- package/dist/chunk-6TZTKAB5.js +1 -0
- package/dist/chunk-6UJ3Y6FC.js +1 -0
- package/dist/chunk-6W7WLPZH.js +1 -0
- package/dist/chunk-7F52SZOI.js +2 -0
- package/dist/chunk-7MU3RJ6S.js +1 -0
- package/dist/chunk-A7ZJII7O.js +1 -0
- package/dist/chunk-AJBJ74ME.js +1 -0
- package/dist/chunk-AKFJK65Z.js +1 -0
- package/dist/chunk-AKZWUV5Z.js +1 -0
- package/dist/chunk-BDTITTMW.js +1 -0
- package/dist/chunk-BSPCSC45.js +1 -0
- package/dist/chunk-BXZ6WLHC.js +22 -0
- package/dist/chunk-DUVRZ456.js +1 -0
- package/dist/chunk-F6CCTEIX.js +1 -0
- package/dist/chunk-FGNR22NY.js +1 -0
- package/dist/chunk-FUDHI5I4.js +1 -0
- package/dist/chunk-GENAF3P6.js +1 -0
- package/dist/chunk-GOTN2KY4.js +2 -0
- package/dist/chunk-GXN65JMA.js +1 -0
- package/dist/chunk-GXQCZJOP.js +1 -0
- package/dist/chunk-GZO72N3Q.js +0 -0
- package/dist/chunk-HDKTR5TZ.js +62 -0
- package/dist/chunk-HMX55DYT.js +1 -0
- package/dist/chunk-HQ4VVRIC.js +1 -0
- package/dist/chunk-HWW4XJOH.js +1 -0
- package/dist/chunk-I54UCYOU.js +1 -0
- package/dist/chunk-IQ5TA7AM.js +1 -0
- package/dist/chunk-IWAPPEL4.js +6 -0
- package/dist/chunk-IYT6NN2J.js +1 -0
- package/dist/chunk-KCBEE2MC.js +2 -0
- package/dist/chunk-KDYIMJTZ.js +1 -0
- package/dist/chunk-KQMML6JM.js +4 -0
- package/dist/chunk-LG436UTD.js +1 -0
- package/dist/chunk-MSBF7IW3.js +2 -0
- package/dist/chunk-NBJ2YY6Y.js +4 -0
- package/dist/chunk-OM67AJQC.js +1 -0
- package/dist/chunk-OORDMLL4.js +5 -0
- package/dist/chunk-OYX47SL7.js +1 -0
- package/dist/chunk-P67FP7PG.js +9 -0
- package/dist/chunk-PWZOS45R.js +2 -0
- package/dist/chunk-Q2HPBMG5.js +1 -0
- package/dist/chunk-Q3SQBNJB.js +1 -0
- package/dist/chunk-R2HLPNQF.js +1 -0
- package/dist/chunk-R5L2E7JX.js +1 -0
- package/dist/chunk-R5ZVNJLJ.js +2 -0
- package/dist/chunk-RLBXE4EU.js +1 -0
- package/dist/chunk-RW4XBUUW.js +1 -0
- package/dist/chunk-SERF2FAU.js +1 -0
- package/dist/chunk-TTJ54QGG.js +18 -0
- package/dist/chunk-VV5ADNBR.js +1 -0
- package/dist/chunk-YJXEHK6I.js +2 -0
- package/dist/chunk-Z3KBLIEH.js +10 -0
- package/dist/chunk-ZE7I3PLX.js +1 -0
- package/dist/chunk-ZWK3CBRU.js +1 -0
- package/dist/chunk-ZZ7VLIHQ.js +1 -0
- package/dist/drag/index.d.ts +3 -41
- package/dist/drag/index.js +1 -18
- package/dist/easel/index.js +1 -9
- package/dist/{words-BMzV04b1.d.ts → engine-DBxp_v6B.d.ts} +1 -58
- package/dist/fields/index.d.ts +2 -109
- package/dist/fields/index.js +1 -22
- package/dist/gold/index.d.ts +4 -2
- package/dist/host-DJ8Gzsx7.d.ts +552 -0
- package/dist/menu/index.js +1 -1
- package/dist/node-ops/index.js +1 -1
- package/dist/panelWidths-D9hTLR25.d.ts +66 -0
- package/dist/screen/components/AddBlockRow.d.ts +14 -0
- package/dist/screen/components/AddBlockRow.js +1 -0
- package/dist/screen/components/AddChildRow.d.ts +39 -0
- package/dist/screen/components/AddChildRow.js +1 -0
- package/dist/screen/components/AddSidePanel.d.ts +54 -0
- package/dist/screen/components/AddSidePanel.js +1 -0
- package/dist/screen/components/MediaSidePanel.d.ts +47 -0
- package/dist/screen/components/MediaSidePanel.js +1 -0
- package/dist/screen/components/NodeContextMenu.d.ts +364 -0
- package/dist/screen/components/NodeContextMenu.js +1 -0
- package/dist/screen/components/PageEditGuardNotices.d.ts +5 -0
- package/dist/screen/components/PageEditGuardNotices.js +1 -0
- package/dist/screen/components/PanelToggleIcon.d.ts +14 -0
- package/dist/screen/components/PanelToggleIcon.js +1 -0
- package/dist/screen/components/PreviewDeviceContext.d.ts +28 -0
- package/dist/screen/components/PreviewDeviceContext.js +1 -0
- package/dist/screen/components/PreviewPartsContext.d.ts +33 -0
- package/dist/screen/components/PreviewPartsContext.js +1 -0
- package/dist/screen/components/ScreenChrome.d.ts +5 -0
- package/dist/screen/components/ScreenChrome.js +1 -0
- package/dist/screen/components/ScreenDocumentContext.d.ts +20 -0
- package/dist/screen/components/ScreenDocumentContext.js +1 -0
- package/dist/screen/components/ScreenMount.d.ts +76 -0
- package/dist/screen/components/ScreenMount.js +1 -0
- package/dist/screen/components/ScreenStoreProvider.d.ts +63 -0
- package/dist/screen/components/ScreenStoreProvider.js +1 -0
- package/dist/screen/components/SectionScreenShell.d.ts +5 -0
- package/dist/screen/components/SectionScreenShell.js +16 -0
- package/dist/screen/components/SidePanelHead.d.ts +81 -0
- package/dist/screen/components/SidePanelHead.js +1 -0
- package/dist/screen/components/SlotChildActionsContext.d.ts +41 -0
- package/dist/screen/components/SlotChildActionsContext.js +1 -0
- package/dist/screen/components/UiIcon.d.ts +52 -0
- package/dist/screen/components/UiIcon.js +1 -0
- package/dist/screen/components/panel-widths.d.ts +37 -0
- package/dist/screen/components/panel-widths.js +1 -0
- package/dist/screen/components/usePartBridge.d.ts +66 -0
- package/dist/screen/components/usePartBridge.js +1 -0
- package/dist/screen/index.d.ts +31 -0
- package/dist/screen/index.js +1 -0
- package/dist/screen/lib/admin-bridge.d.ts +105 -0
- package/dist/screen/lib/admin-bridge.js +1 -0
- package/dist/screen/lib/backend-error.d.ts +106 -0
- package/dist/screen/lib/backend-error.js +1 -0
- package/dist/screen/lib/chrome-theme.d.ts +21 -0
- package/dist/screen/lib/chrome-theme.js +1 -0
- package/dist/screen/lib/client-only.d.ts +24 -0
- package/dist/screen/lib/client-only.js +1 -0
- package/dist/screen/lib/content/view-tiers.d.ts +25 -0
- package/dist/screen/lib/content/view-tiers.js +1 -0
- package/dist/screen/lib/document-addressing.d.ts +20 -0
- package/dist/screen/lib/document-addressing.js +1 -0
- package/dist/screen/lib/document-contract.d.ts +237 -0
- package/dist/screen/lib/document-contract.js +1 -0
- package/dist/screen/lib/document-hooks.d.ts +71 -0
- package/dist/screen/lib/document-hooks.js +0 -0
- package/dist/screen/lib/document-switch.d.ts +74 -0
- package/dist/screen/lib/document-switch.js +1 -0
- package/dist/screen/lib/failure.d.ts +54 -0
- package/dist/screen/lib/failure.js +1 -0
- package/dist/screen/lib/host-chrome.d.ts +181 -0
- package/dist/screen/lib/host-chrome.js +1 -0
- package/dist/screen/lib/host-inbound.d.ts +20 -0
- package/dist/screen/lib/host-inbound.js +1 -0
- package/dist/screen/lib/host.d.ts +20 -0
- package/dist/screen/lib/host.js +1 -0
- package/dist/screen/lib/key-scope.d.ts +23 -0
- package/dist/screen/lib/key-scope.js +1 -0
- package/dist/screen/lib/links/link-filters.d.ts +41 -0
- package/dist/screen/lib/links/link-filters.js +0 -0
- package/dist/screen/lib/load-error.d.ts +29 -0
- package/dist/screen/lib/load-error.js +1 -0
- package/dist/screen/lib/media-panel.d.ts +94 -0
- package/dist/screen/lib/media-panel.js +1 -0
- package/dist/screen/lib/media-picker.d.ts +68 -0
- package/dist/screen/lib/media-picker.js +1 -0
- package/dist/screen/lib/page-lock.d.ts +5 -0
- package/dist/screen/lib/page-lock.js +1 -0
- package/dist/screen/lib/puck/add-target-types.d.ts +55 -0
- package/dist/screen/lib/puck/add-target-types.js +0 -0
- package/dist/screen/lib/puck/block-choice.d.ts +52 -0
- package/dist/screen/lib/puck/block-choice.js +1 -0
- package/dist/screen/lib/puck/block-types-in.d.ts +39 -0
- package/dist/screen/lib/puck/block-types-in.js +1 -0
- package/dist/screen/lib/puck/content-tree.d.ts +196 -0
- package/dist/screen/lib/puck/content-tree.js +1 -0
- package/dist/screen/lib/puck/device-fields.d.ts +128 -0
- package/dist/screen/lib/puck/device-fields.js +1 -0
- package/dist/screen/lib/puck/field-buckets.d.ts +22 -0
- package/dist/screen/lib/puck/field-buckets.js +1 -0
- package/dist/screen/lib/puck/field-markers.d.ts +205 -0
- package/dist/screen/lib/puck/field-markers.js +1 -0
- package/dist/screen/lib/puck/hidable.d.ts +44 -0
- package/dist/screen/lib/puck/hidable.js +1 -0
- package/dist/screen/lib/puck/palette-sections.d.ts +96 -0
- package/dist/screen/lib/puck/palette-sections.js +1 -0
- package/dist/screen/lib/puck/panel-fields.d.ts +47 -0
- package/dist/screen/lib/puck/panel-fields.js +1 -0
- package/dist/screen/lib/puck/panel-no-control-mark.d.ts +74 -0
- package/dist/screen/lib/puck/panel-no-control-mark.js +1 -0
- package/dist/screen/lib/puck/part-id.d.ts +23 -0
- package/dist/screen/lib/puck/part-id.js +1 -0
- package/dist/screen/lib/puck/preview-click.d.ts +49 -0
- package/dist/screen/lib/puck/preview-click.js +1 -0
- package/dist/screen/lib/puck/preview-dom.d.ts +8 -0
- package/dist/screen/lib/puck/preview-dom.js +1 -0
- package/dist/screen/lib/puck/preview-events.d.ts +25 -0
- package/dist/screen/lib/puck/preview-events.js +1 -0
- package/dist/screen/lib/puck/preview-selection-context.d.ts +72 -0
- package/dist/screen/lib/puck/preview-selection-context.js +1 -0
- package/dist/screen/lib/puck/section-doc.d.ts +20 -0
- package/dist/screen/lib/puck/section-doc.js +1 -0
- package/dist/screen/lib/puck/slot-child-name.d.ts +186 -0
- package/dist/screen/lib/puck/slot-child-name.js +1 -0
- package/dist/screen/lib/puck/slot-heal.d.ts +5 -0
- package/dist/screen/lib/puck/slot-heal.js +1 -0
- package/dist/screen/lib/puck/slot-section-spec.d.ts +96 -0
- package/dist/screen/lib/puck/slot-section-spec.js +0 -0
- package/dist/screen/lib/puck/style-clipboard.d.ts +78 -0
- package/dist/screen/lib/puck/style-clipboard.js +1 -0
- package/dist/screen/lib/puck/text-control-kinds.d.ts +71 -0
- package/dist/screen/lib/puck/text-control-kinds.js +1 -0
- package/dist/screen/lib/puck/tree-reveal.d.ts +62 -0
- package/dist/screen/lib/puck/tree-reveal.js +1 -0
- package/dist/screen/lib/puck/use-section-ops.d.ts +86 -0
- package/dist/screen/lib/puck/use-section-ops.js +1 -0
- package/dist/screen/lib/screen-parts.d.ts +748 -0
- package/dist/screen/lib/screen-parts.js +1 -0
- package/dist/screen/lib/section-template-types.d.ts +49 -0
- package/dist/screen/lib/section-template-types.js +0 -0
- package/dist/screen/lib/section-templates.d.ts +23 -0
- package/dist/screen/lib/section-templates.js +1 -0
- package/dist/screen/lib/session-context.d.ts +30 -0
- package/dist/screen/lib/session-context.js +1 -0
- package/dist/screen/lib/session.d.ts +255 -0
- package/dist/screen/lib/session.js +1 -0
- package/dist/screen/screen.css +1102 -0
- package/dist/screen/words.d.ts +42 -0
- package/dist/screen/words.js +1 -0
- package/dist/session-DSQFmIvx.d.ts +43 -0
- package/dist/strings/catalogue.d.ts +13 -4
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +5 -2
- package/dist/strings/index.js +1 -1
- package/dist/style-clipboard/index.js +1 -1
- package/dist/{types-DGcCsxs8.d.ts → types-CqY85foL.d.ts} +3 -65
- package/dist/words-D_Lnw1Gr.d.ts +59 -0
- package/package.json +348 -2
- 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
|