efficient-easel 0.0.0 → 0.97.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 (119) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +818 -4
  3. package/dist/autosave/index.d.ts +101 -0
  4. package/dist/autosave/index.js +1 -0
  5. package/dist/blocks/index.d.ts +306 -0
  6. package/dist/blocks/index.js +0 -0
  7. package/dist/buckets-1vRlQceY.d.ts +13 -0
  8. package/dist/canvas/index.d.ts +194 -0
  9. package/dist/canvas/index.js +1 -0
  10. package/dist/chrome/chrome.css +570 -0
  11. package/dist/chrome/index.d.ts +219 -0
  12. package/dist/chrome/index.js +21 -0
  13. package/dist/chunk-2LUSK32B.js +1 -0
  14. package/dist/chunk-2OAZYSWJ.js +1 -0
  15. package/dist/chunk-67VZRQLG.js +13 -0
  16. package/dist/chunk-6OPSJGAI.js +1 -0
  17. package/dist/chunk-6PS6STGA.js +1 -0
  18. package/dist/chunk-6WY6ZXJG.js +1 -0
  19. package/dist/chunk-7A7O2JWQ.js +1 -0
  20. package/dist/chunk-BZ5ASXOL.js +1 -0
  21. package/dist/chunk-CERTFXCV.js +13 -0
  22. package/dist/chunk-D2BCHTQR.js +1 -0
  23. package/dist/chunk-FI23ALVJ.js +1 -0
  24. package/dist/chunk-GGTPNGFJ.js +1 -0
  25. package/dist/chunk-H4B72XCJ.js +1 -0
  26. package/dist/chunk-H6DDIBQ4.js +1 -0
  27. package/dist/chunk-KDIVA6WD.js +1 -0
  28. package/dist/chunk-KRXQM65X.js +1 -0
  29. package/dist/chunk-MCLBHENY.js +1 -0
  30. package/dist/chunk-MFIRYGHW.js +1 -0
  31. package/dist/chunk-NKB3KVAB.js +1 -0
  32. package/dist/chunk-O2NLQBFX.js +1 -0
  33. package/dist/chunk-OGZFDJ6G.js +1 -0
  34. package/dist/chunk-OWBO4WKA.js +0 -0
  35. package/dist/chunk-QB3BZIRA.js +5 -0
  36. package/dist/chunk-RE4LP46F.js +1 -0
  37. package/dist/chunk-STFMZJKU.js +14 -0
  38. package/dist/chunk-SUO5627P.js +1 -0
  39. package/dist/chunk-TDA4HH54.js +1 -0
  40. package/dist/chunk-WK3AFPXY.js +1 -0
  41. package/dist/chunk-YIMRTIBN.js +3 -0
  42. package/dist/chunk-YNZZYHA4.js +450 -0
  43. package/dist/chunk-YRLPFZW3.js +1 -0
  44. package/dist/chunk-ZAOM6PFH.js +1 -0
  45. package/dist/chunk-ZNCEOSXO.js +1 -0
  46. package/dist/copy/copy.css +282 -0
  47. package/dist/copy/index.d.ts +336 -0
  48. package/dist/copy/index.js +10 -0
  49. package/dist/data/index.d.ts +375 -0
  50. package/dist/data/index.js +1 -0
  51. package/dist/drag/drag.css +360 -0
  52. package/dist/drag/index.d.ts +379 -0
  53. package/dist/drag/index.js +18 -0
  54. package/dist/edit-lock/index.d.ts +354 -0
  55. package/dist/edit-lock/index.js +1 -0
  56. package/dist/editor/editor.css +58 -0
  57. package/dist/editor/index.d.ts +361 -0
  58. package/dist/editor/index.js +9 -0
  59. package/dist/fields/fields.css +207 -0
  60. package/dist/fields/index.d.ts +273 -0
  61. package/dist/fields/index.js +46 -0
  62. package/dist/gold/gold.css +196 -0
  63. package/dist/gold/index.d.ts +280 -0
  64. package/dist/gold/index.js +1 -0
  65. package/dist/icons/index.d.ts +474 -0
  66. package/dist/icons/index.js +1 -0
  67. package/dist/index.d.ts +6 -0
  68. package/dist/index.js +1 -0
  69. package/dist/markup/index.d.ts +452 -0
  70. package/dist/markup/index.js +1 -0
  71. package/dist/menu/index.d.ts +49 -0
  72. package/dist/menu/index.js +15 -0
  73. package/dist/menu/menu.css +254 -0
  74. package/dist/node-ops/index.d.ts +91 -0
  75. package/dist/node-ops/index.js +1 -0
  76. package/dist/panel/index.d.ts +1088 -0
  77. package/dist/panel/index.js +16 -0
  78. package/dist/panel/panel.css +1460 -0
  79. package/dist/pick/index.d.ts +153 -0
  80. package/dist/pick/index.js +14 -0
  81. package/dist/pick/pick.css +235 -0
  82. package/dist/plan-DChbUXdS.d.ts +88 -0
  83. package/dist/rail/index.d.ts +145 -0
  84. package/dist/rail/index.js +1 -0
  85. package/dist/rail/rail.css +175 -0
  86. package/dist/render/index.d.ts +117 -0
  87. package/dist/render/index.js +5 -0
  88. package/dist/resolve-D68pb3Bx.d.ts +57 -0
  89. package/dist/shell/index.d.ts +159 -0
  90. package/dist/shell/index.js +1 -0
  91. package/dist/shell/shell.css +122 -0
  92. package/dist/strings/catalogue.d.ts +141 -0
  93. package/dist/strings/catalogue.js +1 -0
  94. package/dist/strings/index.d.ts +56 -0
  95. package/dist/strings/index.js +2 -0
  96. package/dist/style-clipboard/index.d.ts +184 -0
  97. package/dist/style-clipboard/index.js +1 -0
  98. package/dist/tree/index.d.ts +173 -0
  99. package/dist/tree/index.js +1 -0
  100. package/dist/tree/tree.css +618 -0
  101. package/dist/types-41704JE4.d.ts +112 -0
  102. package/dist/types-CEqUFH2j.d.ts +129 -0
  103. package/dist/types-CuNiSnX6.d.ts +204 -0
  104. package/dist/types-DNrn_w4V.d.ts +88 -0
  105. package/dist/types-Dy6oR6Z2.d.ts +153 -0
  106. package/dist/types-pGBXevBU.d.ts +131 -0
  107. package/dist/useNodeOps-BF0fQsif.d.ts +68 -0
  108. package/dist/watch-DmasQA61.d.ts +60 -0
  109. package/dist/wordFit-9B9nqyf3.d.ts +35 -0
  110. package/dist/words-B2YLaKEr.d.ts +30 -0
  111. package/dist/words-B87GIFWH.d.ts +86 -0
  112. package/dist/words-BK-npta-.d.ts +27 -0
  113. package/dist/words-CD3WADyb.d.ts +51 -0
  114. package/dist/words-CsRWXkY4.d.ts +129 -0
  115. package/dist/words-D9ChvbNC.d.ts +52 -0
  116. package/dist/words-DOhF-4D4.d.ts +35 -0
  117. package/dist/words-DagJdwIA.d.ts +78 -0
  118. package/dist/words-DfxEp_RH.d.ts +142 -0
  119. package/package.json +202 -3
@@ -0,0 +1,354 @@
1
+ /**
2
+ * The edit lock's own words (`efficient-easel/strings`, 0.95.0): how long ago,
3
+ * and who, when the backend could not say.
4
+ *
5
+ * Plain TypeScript with no import, like the module it belongs to. A count that
6
+ * can be one or many is a function, so a host does its own plural.
7
+ */
8
+ type LockWords = {
9
+ /** Under 45 seconds, or a time that is not a number. */
10
+ justNow: string;
11
+ /** 1 to 59 minutes. */
12
+ minutesAgo: (v: {
13
+ count: number;
14
+ }) => string;
15
+ /** An hour or more. */
16
+ hoursAgo: (v: {
17
+ count: number;
18
+ }) => string;
19
+ /** The person, when the backend sent no name. */
20
+ someone: string;
21
+ };
22
+
23
+ /**
24
+ * Who may WRITE the open document, and what to tell the operator when they may
25
+ * not — for EVERY editor in the house.
26
+ *
27
+ * This module is the merge of two files that had grown side by side and said
28
+ * the same things in two places (card 11161):
29
+ *
30
+ * * `efficient-admin-portal/src/components/email/campaignEditLock.ts` — the
31
+ * campaign designer's copy, which alone had the TAKE-OVER half;
32
+ * * `efficient-shop/lib/editor-page-lock.ts` — the storefront editor's copy,
33
+ * which alone had the claim/heartbeat driver, the auth-rejection rule and
34
+ * the "a template has no lock" rule.
35
+ *
36
+ * Neither was a subset of the other, so this file keeps EVERY capability of
37
+ * both, and both editors now import it instead of carrying a copy.
38
+ *
39
+ * TWO INDEPENDENT PROTECTIONS, and it matters which is which:
40
+ *
41
+ * * the SAVE-TIME version check is what actually protects work. The backend
42
+ * refuses a document write whose base version has moved on, so no amount of
43
+ * client-side confusion can erase a colleague's edits. Nothing here can
44
+ * weaken it — the token travels with the write and the server decides.
45
+ * * this advisory LOCK only stops two people STARTING, and is soft on
46
+ * purpose: it expires, it can always be taken over, and — see
47
+ * `accessAfterClaimFailure` — it FAILS OPEN. A lock that could refuse to
48
+ * let anybody edit would be worse than no lock at all. A save consults it
49
+ * in one case only: a tab somebody TOOK the document from is refused
50
+ * (`EDIT_LOCK_TAKEN`, read by `readLockTaken`), so it stops at its next
51
+ * save instead of its next heartbeat.
52
+ *
53
+ * The backend rule is one rule shared by both (efficient/editlock.py). These
54
+ * are two CONSUMERS of one server-side contract, which is exactly why one
55
+ * client module can serve them.
56
+ *
57
+ * WHAT IS NOT SHARED, and why there is a factory rather than plain functions:
58
+ * the two editors talk to the backend through different HTTP clients, so a
59
+ * failure arrives as an `AxiosError` in one and as an `ApiError` in the other,
60
+ * and the refused-save payload carries a different `code`. Those two facts —
61
+ * and nothing else — are handed in by the consumer through `createEditLock`.
62
+ * The module itself imports no HTTP client and knows about no repo.
63
+ *
64
+ * LEAF DISCIPLINE: pure TypeScript. No React, no `document`/`window`, no
65
+ * dependency at all. `crypto` is touched inside a function, never at module
66
+ * eval, so a Next server component may import this module safely.
67
+ */
68
+
69
+ /** The `edit-lock` body — identical for every editable document. */
70
+ type EditLockBody = {
71
+ held_by_you: boolean;
72
+ holder_name: string;
73
+ client_id: string;
74
+ last_seen_at: string;
75
+ seconds_since_seen: number;
76
+ seconds_since_held: number;
77
+ heartbeat_seconds: number;
78
+ expiry_seconds: number;
79
+ };
80
+ /** The other operator, as the notices need to describe them. */
81
+ type LockHolder = {
82
+ name: string;
83
+ /** Seconds since their last heartbeat, as the SERVER measured it. */
84
+ secondsSinceSeen: number;
85
+ /** Seconds since they TOOK the document, as the SERVER measured it. Not the
86
+ * same number: an active holder's heartbeat keeps `secondsSinceSeen` near
87
+ * zero, so only this one can say "took over 20 seconds ago". */
88
+ secondsSinceHeld: number;
89
+ };
90
+ /**
91
+ * Whether the open document may be written, and why not when it may not.
92
+ *
93
+ * `editing` is the ONLY writable state, and `canWriteDocument` is the only place
94
+ * that says so — so a new state added later is read-only until someone
95
+ * deliberately makes it writable, rather than writable until someone remembers
96
+ * to block it.
97
+ */
98
+ type EditAccess =
99
+ /** The claim is still in flight. Holding writes for the moment it takes is
100
+ * what stops a fast typist's first autosave landing before we know whether
101
+ * somebody else is in here. */
102
+ {
103
+ kind: 'checking';
104
+ }
105
+ /** You hold the document. */
106
+ | {
107
+ kind: 'editing';
108
+ }
109
+ /** Somebody else holds it and you have not chosen yet — view, or take over. */
110
+ | {
111
+ kind: 'blocked';
112
+ holder: LockHolder;
113
+ }
114
+ /** You chose to look without touching. */
115
+ | {
116
+ kind: 'readonly';
117
+ holder: LockHolder;
118
+ }
119
+ /** You HAD it and somebody took it. Your work is still on screen. */
120
+ | {
121
+ kind: 'takenover';
122
+ holder: LockHolder;
123
+ };
124
+ /** The one gate on the document write path. */
125
+ declare const canWriteDocument: (access: EditAccess) => boolean;
126
+ /**
127
+ * The access a freshly opened document starts from.
128
+ *
129
+ * A document WITH a lock starts `checking` and the claim answers within a round
130
+ * trip. One WITHOUT — the storefront's templates — has no claim effect at all,
131
+ * so `checking` there is not a question awaiting an answer, it is a state
132
+ * nothing will ever leave, and every write for the rest of the session is
133
+ * refused: the merchant's edits and, first of all, the pinned Header/Footer seed
134
+ * that runs in the chrome's mount commit. The editor's MOUNT has always known
135
+ * this; a document SWITCH did not, which is what card 1096 found.
136
+ *
137
+ * Not a loosening of `canWriteDocument`: it says which QUESTION a document opens
138
+ * with, and a document with no lock was never asking one.
139
+ */
140
+ declare function accessForNewDocument(hasEditLock: boolean): EditAccess;
141
+ /** The holder named by a state that has one (for the banner / the notices). */
142
+ declare const holderOf: (access: EditAccess) => LockHolder | null;
143
+ /** Read the `edit-lock` body — from a 200 or from a 409's error payload. */
144
+ declare function readLockHolder(data: unknown): LockHolder | null;
145
+ /** The five capabilities Puck's `permissions` prop carries for the canvas. */
146
+ type DocumentPermissions = {
147
+ edit: boolean;
148
+ insert: boolean;
149
+ delete: boolean;
150
+ duplicate: boolean;
151
+ drag: boolean;
152
+ };
153
+ /**
154
+ * The canvas's Puck `permissions`, derived from the write gate.
155
+ *
156
+ * BOTH branches name ALL FIVE keys — and that completeness is the whole point,
157
+ * not tidiness. Puck does not replace this prop when it changes; it MERGES it
158
+ * over the permissions it already holds (store/slices/permissions.ts,
159
+ * `useRegisterPermissionsSlice`: `{ ...existingGlobalPermissions, ...prop }`),
160
+ * and a field's editability is the live `getPermissions().edit`. Puck mounts
161
+ * while the lock claim is still `checking`, so `canEdit` is false and the store
162
+ * latches every key false. A PARTIAL writable value (say `{ drag: false }`)
163
+ * would then merge WITHOUT an `edit` key and leave `edit:false` stuck — every
164
+ * inspector field disabled for good, even after the claim resolves to
165
+ * `editing`. Spelling out edit/insert/delete/duplicate on the writable branch
166
+ * resets them, so the panel comes back the instant `canEdit` flips true.
167
+ *
168
+ * `drag` stays false in EITHER state: both editors move blocks with native DnD
169
+ * rails of their own, so Puck's flaky cross-iframe canvas drag is always off.
170
+ *
171
+ * Write safety is unchanged: the `checking` window is still non-editable here,
172
+ * and the host's own write gate still drops any edit attempted before the claim
173
+ * resolves, so nothing is saved early.
174
+ */
175
+ declare const documentPermissions: (canEdit: boolean) => DocumentPermissions;
176
+
177
+ /**
178
+ * "just now" / "2 minutes ago" — one phrasing, shared by every notice.
179
+ *
180
+ * `words` is the host's language (`useEditorStrings().lock`, 0.95.0); left out,
181
+ * it is the English it always was. The thresholds are not words and do not
182
+ * move: under 45 seconds is "just now", then whole minutes, then whole hours.
183
+ */
184
+ declare function describeAge(seconds: number, words?: LockWords): string;
185
+ /** Names the person, or says so honestly when the backend could not. */
186
+ declare const nameOrSomeone: (name: string, words?: LockWords) => string;
187
+ /**
188
+ * The identity of THIS editor tab.
189
+ *
190
+ * Per-tab, not per-user: it is what lets the backend tell "me, in a second tab"
191
+ * (take my own lock over silently) from "me, here". Deliberately not persisted —
192
+ * a reload IS a new editor session, and a remembered id would let a closed tab's
193
+ * claim look alive.
194
+ */
195
+ declare function newEditorClientId(): string;
196
+ /**
197
+ * The `code` of a document write refused because somebody else TOOK the
198
+ * document from this tab (backend `efficient/editlock.py`,
199
+ * `EDIT_LOCK_TAKEN_CODE`). The write names its tab with the same `client_id`
200
+ * its claim sends; a write that does not is never refused this way.
201
+ *
202
+ * One code for every document type, unlike the version conflict's: the body
203
+ * is the `edit-lock` body, which is already the same everywhere.
204
+ */
205
+ declare const EDIT_LOCK_TAKEN = "edit_lock_taken";
206
+ /** A refused save: the stored document moved on since this editor loaded it. */
207
+ type SaveConflict = {
208
+ /** Who saved over you. Empty when the backend could not attribute the write. */
209
+ savedBy: string;
210
+ /** True when it was YOU, in another tab — never blame a colleague for it. */
211
+ savedByYou: boolean;
212
+ secondsAgo: number;
213
+ };
214
+ /**
215
+ * A write the editor is HOLDING rather than sending, and the two other reasons
216
+ * it might be held. `onChange` never drops a refused write — the operator's
217
+ * screen is the only copy of it — so each hold owes a release.
218
+ */
219
+ type HeldWrite = {
220
+ /** An unpersisted layout is waiting (the host's pending-data ref). */
221
+ pending: boolean;
222
+ /** Autosave paused: the merchant turned writes off, and the pill's resume is
223
+ * the only thing that may flush. */
224
+ autoSaveEnabled: boolean;
225
+ /** A refused save: their work sits behind a banner and only they decide what
226
+ * happens to it. Retrying behind their back is how it gets lost. */
227
+ saveConflict: boolean;
228
+ };
229
+ /** Everything the claim path reads and drives, passed in rather than imported so
230
+ * the path itself can be RUN in a test — a rule that only lives inside a React
231
+ * effect is a rule nothing can check. */
232
+ type ClaimBeatDeps = {
233
+ /** Claim the document (or take it). */
234
+ claim: (takeover: boolean) => Promise<{
235
+ heartbeat_seconds: number;
236
+ }>;
237
+ /** The effect's cleanup ran: a late answer must not grant a document this
238
+ * editor has already left, nor flush one that is no longer open. */
239
+ cancelled: () => boolean;
240
+ currentAccess: () => EditAccess;
241
+ heldWrite: () => HeldWrite;
242
+ setAccess: (access: EditAccess) => void;
243
+ /** Send the held write — the host's one write path, never a second one. */
244
+ releaseHeldWrite: () => void;
245
+ /** Start the heartbeat that KEEPS the document, at the backend's own interval. */
246
+ startHeartbeat: (intervalMs: number) => void;
247
+ /** Stop beating. Called when the SESSION is refused, never when a single
248
+ * request fails — see `isAuthRejection`. The effect re-runs and claims again
249
+ * the moment a fresh token arrives, so this ends a doomed loop rather than
250
+ * ending the editor's hold on the document. */
251
+ stopHeartbeat: () => void;
252
+ /** A take-over was granted and nothing of this editor's is waiting to be
253
+ * written (`shouldReloadAfterTakeover`): load the stored document if it moved
254
+ * since this copy was loaded. Optional — a host without it keeps its copy. */
255
+ reloadIfMoved?: () => void;
256
+ };
257
+ /**
258
+ * Must a write held ONLY because the document was not yet writable go out now?
259
+ *
260
+ * Keyed on the TRANSITION, not on the current state: `beat` also runs on every
261
+ * heartbeat, where access is already `editing`. Releasing on "is writable" would
262
+ * flush the merchant's in-progress edit on every beat and delete the debounce
263
+ * that keeps whole-document writes rare.
264
+ *
265
+ * Exported so the rule has a test of its own, and because it is the one piece of
266
+ * `makeClaimBeat` a caller can reason about without a driver.
267
+ */
268
+ declare function shouldReleaseHeldWrite(previous: EditAccess, next: EditAccess, held: HeldWrite): boolean;
269
+ /**
270
+ * After a take-over was GRANTED, should the host check whether the stored
271
+ * document moved, and load it if so, before the operator edits?
272
+ *
273
+ * The taker's copy is whatever they opened, and the person they took it from
274
+ * may have saved since — in the seconds before learning they were displaced.
275
+ * Editing that copy means the taker's first save is refused as "saved
276
+ * elsewhere". When NOTHING of theirs is waiting to be written, loading the
277
+ * stored copy costs them nothing: from `blocked` / `readonly` the canvas was
278
+ * read-only, so there is nothing to lose.
279
+ *
280
+ * Never when something IS waiting — the edits a displaced tab held, taken
281
+ * back with "Take it back". Reloading would throw them away. They go out
282
+ * instead (`shouldReleaseHeldWrite`), and the version check refuses them if the
283
+ * other person saved in between. Never with a refused save on screen either:
284
+ * that notice has its own Reload, and it is the operator's to press.
285
+ *
286
+ * Only the question. Whether the version moved is the host's to find out: each
287
+ * document keeps its version its own way.
288
+ */
289
+ declare function shouldReloadAfterTakeover(previous: EditAccess, next: EditAccess, held: Pick<HeldWrite, 'pending' | 'saveConflict'>): boolean;
290
+ /**
291
+ * Has the stored document moved on from the version this copy is based on?
292
+ *
293
+ * Both are version tokens exactly as the API served them (`layout_updated_at`,
294
+ * `design_updated_at`), and a version never goes backwards, so any difference
295
+ * is a newer write. The instant comparison only stops a copy that is somehow
296
+ * AHEAD of the stored one from reading as moved. Two writes in the same
297
+ * millisecond still count as moved: `Date` cannot see microseconds, and an
298
+ * unneeded reload of an untouched copy costs nothing.
299
+ */
300
+ declare function documentVersionMoved(stored: string, ours: string): boolean;
301
+ /**
302
+ * The host's half of a reload after a take-over (`shouldReloadAfterTakeover`):
303
+ * read the stored version, and reload only if it moved AND nothing of the
304
+ * operator's is waiting by the time the answer comes back — the canvas opened
305
+ * the moment the take-over landed, so they may have typed during the read, and
306
+ * that edit is theirs. Resolves whether it reloaded. A read that fails, or a
307
+ * version that is not known, keeps the copy: the version check still stands
308
+ * behind the next save.
309
+ */
310
+ declare function reloadIfVersionMoved(d: {
311
+ /** The version this copy is based on. */
312
+ ours: string | null;
313
+ /** The version stored now. */
314
+ stored: () => Promise<string | null>;
315
+ /** An edit is not on the server yet — read live. */
316
+ hasPending: () => boolean;
317
+ reload: () => void;
318
+ }): Promise<boolean>;
319
+ /** A failed request reduced to the only two things any decision here needs. */
320
+ type EditLockFailure = {
321
+ status: number;
322
+ data: unknown;
323
+ };
324
+ /**
325
+ * The two things that genuinely differ between one editor and the next.
326
+ *
327
+ * Kept to two on purpose. Anything a THIRD editor would also have to answer
328
+ * belongs in this module, not in another adapter.
329
+ */
330
+ type EditLockAdapter = {
331
+ /**
332
+ * Pull `{ status, data }` out of whatever this repo's HTTP client threw, or
333
+ * null when the rejection is not a server answer at all (a dropped socket, a
334
+ * programming error). Every "fails open" branch below leans on that null.
335
+ */
336
+ readFailure: (err: unknown) => EditLockFailure | null;
337
+ /** The `code` the backend puts in a refused-save body for THIS document type
338
+ * — `page_changed_elsewhere`, `campaign_changed_elsewhere`. */
339
+ conflictCode: string;
340
+ };
341
+ /** The decisions that need the adapter. Everything else above is plain. */
342
+ type EditLock = {
343
+ accessAfterClaimFailure: (err: unknown) => EditAccess;
344
+ accessAfterTakeoverFailure: (err: unknown, current: EditAccess) => EditAccess;
345
+ accessAfterHeartbeatFailure: (err: unknown, current: EditAccess) => EditAccess;
346
+ isAuthRejection: (err: unknown) => boolean;
347
+ readSaveConflict: (err: unknown) => SaveConflict | null;
348
+ readLockTaken: (err: unknown) => LockHolder | null;
349
+ makeClaimBeat: (deps: ClaimBeatDeps) => (takeover: boolean) => Promise<void>;
350
+ };
351
+ /** Bind the decisions to one editor's HTTP client and document type. */
352
+ declare function createEditLock(adapter: EditLockAdapter): EditLock;
353
+
354
+ export { type ClaimBeatDeps, type DocumentPermissions, EDIT_LOCK_TAKEN, type EditAccess, type EditLock, type EditLockAdapter, type EditLockBody, type EditLockFailure, type HeldWrite, type LockHolder, type LockWords, type SaveConflict, accessForNewDocument, canWriteDocument, createEditLock, describeAge, documentPermissions, documentVersionMoved, holderOf, nameOrSomeone, newEditorClientId, readLockHolder, reloadIfVersionMoved, shouldReleaseHeldWrite, shouldReloadAfterTakeover };
@@ -0,0 +1 @@
1
+ export{EDIT_LOCK_TAKEN,accessForNewDocument,canWriteDocument,createEditLock,describeAge,documentPermissions,documentVersionMoved,holderOf,nameOrSomeone,newEditorClientId,readLockHolder,reloadIfVersionMoved,shouldReleaseHeldWrite,shouldReloadAfterTakeover}from"../chunk-TDA4HH54.js";import"../chunk-RE4LP46F.js";
@@ -0,0 +1,58 @@
1
+ /*
2
+ * efficient-easel/editor — the canvas's own marks (blueprint 5.1): the
3
+ * lists' empty and selected states, and the outlines over the selected and
4
+ * hovered block. Puck's `puck.css` drew these until now; the rules follow it.
5
+ *
6
+ * The canvas is an iframe of its own, so this sheet must reach it: import it
7
+ * once in the host, and `CanvasFrame` copies the host's stylesheets into the
8
+ * frame. Tokens fall back to the shell blue, because the frame's document has
9
+ * no `.es-editor` root to define them.
10
+ */
11
+
12
+ /* The frame's root (CanvasFrame). Puck's `[data-puck-entry]` rule: a stacking
13
+ context of its own, so a block's z-index stays inside the page. */
14
+ [data-puck-entry] {
15
+ position: relative;
16
+ z-index: 0;
17
+ }
18
+ /* A frame that FILLS its parent (`height="fill"`): the page is at least as tall
19
+ as the frame, as Puck's `#frame-root` was, so a short page's background and
20
+ its top list reach the bottom of the canvas. `height: 1px` gives the root a
21
+ height of its own for a list's `height: 100%` to resolve against. Not on an
22
+ `auto` frame, whose height comes FROM the page: there `100vh` is the frame
23
+ itself, and the page could never be shorter than the frame again. */
24
+ #frame-root.es-frame-fill {
25
+ height: 1px;
26
+ min-height: 100vh;
27
+ }
28
+
29
+ .es-zone {
30
+ position: relative;
31
+ height: 100%;
32
+ min-height: var(--min-empty-height);
33
+ width: 100%;
34
+ outline-offset: -2px;
35
+ }
36
+ .es-zone.has-children {
37
+ min-height: 0;
38
+ }
39
+ .es-zone:empty,
40
+ .es-zone.is-area-selected:not(.is-root),
41
+ .es-zone.is-hovering-area:not(.is-root) {
42
+ background: color-mix(in srgb, var(--es-accent, #2563eb) 6%, transparent);
43
+ outline: 2px dashed color-mix(in srgb, var(--es-accent, #2563eb) 35%, transparent);
44
+ }
45
+
46
+ .es-canvas-outline {
47
+ pointer-events: none;
48
+ box-sizing: border-box;
49
+ z-index: 2147483000;
50
+ }
51
+ .es-canvas-outline.is-selected {
52
+ outline: 2px solid var(--es-accent, #2563eb);
53
+ outline-offset: -1px;
54
+ }
55
+ .es-canvas-outline.is-hover {
56
+ outline: 1px solid color-mix(in srgb, var(--es-accent, #2563eb) 60%, transparent);
57
+ outline-offset: -1px;
58
+ }