camox 0.58.1 → 0.60.2

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 (102) hide show
  1. package/dist/core/createBlock.js +1 -1
  2. package/dist/core/editing/createEditableBlock.js +2 -2
  3. package/dist/core/lib/recordScope.js +1 -1
  4. package/dist/features/canvas/CamoxCanvas.js +2 -2
  5. package/dist/features/canvas/CanvasOverlays.js +1 -1
  6. package/dist/features/canvas/sidebar/LayoutPageSeo.js +1 -1
  7. package/dist/features/canvas/sidebar/PageInspector.js +1 -1
  8. package/dist/features/content/CamoxContent.js +1 -1
  9. package/dist/features/content/components/MissingFromLocale.js +1 -1
  10. package/dist/features/page/CuratedPageContent.js +1 -1
  11. package/dist/features/preview/CamoxPreview.js +3 -3
  12. package/dist/features/preview/components/AddBlockSheet.js +1 -1
  13. package/dist/features/preview/components/AssetLightbox.js +1 -1
  14. package/dist/features/preview/components/BlockActionsPopover.js +1 -1
  15. package/dist/features/preview/components/CreatePageModal.js +2 -2
  16. package/dist/features/preview/components/FieldOverlayStyles.js +1 -1
  17. package/dist/features/preview/components/MobilePreviewDrawer.js +1 -1
  18. package/dist/features/preview/components/Overlays.js +1 -1
  19. package/dist/features/preview/components/PageInfo.js +1 -1
  20. package/dist/features/preview/components/PagePicker.js +1 -1
  21. package/dist/features/preview/components/PageTree.js +1 -1
  22. package/dist/features/preview/components/PreviewPanel.js +1 -1
  23. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  24. package/dist/features/preview/components/SelectionEditor.js +2 -2
  25. package/dist/features/preview/components/StudioEditingFallback.js +1 -1
  26. package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
  27. package/dist/features/provider/CamoxProvider.js +1 -1
  28. package/dist/features/provider/CoreCamoxProvider.js +3 -3
  29. package/dist/features/provider/components/CommandPalette.js +1 -1
  30. package/dist/features/renderer/RendererApp.js +187 -103
  31. package/dist/features/renderer/rendererHost.js +3 -7
  32. package/dist/features/routes/pageRuntime.d.ts +2 -5
  33. package/dist/features/routes/pageRuntime.js +1 -2
  34. package/dist/features/runtime/RuntimeChrome.js +1 -1
  35. package/dist/features/runtime/loopbackFetch.d.ts +8 -0
  36. package/dist/features/runtime/navigationTarget.js +1 -2
  37. package/dist/features/runtime/pageApp.js +1 -1
  38. package/dist/features/runtime/publicCache.d.ts +21 -0
  39. package/dist/features/runtime/publishingDraft.d.ts +4 -0
  40. package/dist/features/runtime/rendererClient.js +1 -1
  41. package/dist/features/runtime/runtime.d.ts +0 -5
  42. package/dist/features/runtime/runtime.js +80 -33
  43. package/dist/features/runtime/worker.js +4 -7
  44. package/dist/features/runtime/workerRequest.d.ts +8 -0
  45. package/dist/features/runtime/workerRuntime.d.ts +5 -0
  46. package/dist/features/runtime/workerRuntime.js +6 -0
  47. package/dist/features/sdkBundle/buildSdkBundle.d.ts +40 -0
  48. package/dist/features/sdkBundle/buildSdkBundle.js +323 -0
  49. package/dist/features/sdkBundle/localSdkBundle.d.ts +44 -0
  50. package/dist/features/sdkBundle/localSdkBundle.js +162 -0
  51. package/dist/features/sdkBundle/sdkBundle.d.ts +3 -0
  52. package/dist/features/sdkBundle/sdkBundle.js +4 -0
  53. package/dist/features/sdkBundle/sdkBundleName.d.ts +59 -0
  54. package/dist/features/sdkBundle/sdkBundleName.js +164 -0
  55. package/dist/features/sdkBundle/specifiers.d.ts +34 -0
  56. package/dist/features/sdkBundle/specifiers.js +146 -0
  57. package/dist/features/settings/FaviconSettings.js +1 -1
  58. package/dist/features/settings/SocialProfilesSettings.js +284 -151
  59. package/dist/features/studio/CamoxStudio.js +1 -1
  60. package/dist/features/studio/FollowAgentProvider.js +72 -13
  61. package/dist/features/studio/components/ChatWidget.js +86 -44
  62. package/dist/features/studio/components/DraftsControl.js +232 -201
  63. package/dist/features/studio/components/LocalePicker.js +2 -2
  64. package/dist/features/studio/components/Navbar.js +3 -3
  65. package/dist/features/studio/components/Patrol.js +312 -209
  66. package/dist/features/studio/components/ProjectMenu.js +2 -2
  67. package/dist/features/studio/components/ReviewDraftSheet.js +9 -15
  68. package/dist/features/studio/components/Squareling.js +164 -66
  69. package/dist/features/studio/components/ThreadComposer.js +139 -69
  70. package/dist/features/studio/components/ThreadMessages.js +216 -64
  71. package/dist/features/studio/components/UserButton.js +2 -2
  72. package/dist/features/studio/draftLabel.js +1 -2
  73. package/dist/features/studio/draftNotice.js +0 -1
  74. package/dist/features/studio/editorWhereContext.js +11 -0
  75. package/dist/features/studio/showInCanvas.js +1 -1
  76. package/dist/features/studio/useEditorSelection.js +135 -0
  77. package/dist/features/vite/definitionsSync.js +14 -60
  78. package/dist/features/vite/devSignIn.js +1 -1
  79. package/dist/features/vite/hostedChecks.js +1 -1
  80. package/dist/features/vite/runtimeDev.js +2 -2
  81. package/dist/features/vite/sdkBundleBuild.js +74 -0
  82. package/dist/features/vite/staticAssetHeaders.js +7 -4
  83. package/dist/features/vite/vite.d.ts +8 -7
  84. package/dist/features/vite/vite.js +67 -28
  85. package/dist/lib/api-client-server.js +25 -8
  86. package/dist/lib/api-client.js +2 -6
  87. package/dist/lib/auth.js +25 -59
  88. package/dist/lib/draft-scope.js +5 -25
  89. package/dist/lib/preview-handoff.js +1 -1
  90. package/dist/lib/server-auth-cookie.js +23 -11
  91. package/dist/lib/stored-auth-cookies.js +76 -0
  92. package/dist/lib/studio-reads.js +1 -1
  93. package/dist/lib/use-thread.js +40 -40
  94. package/dist/package.js +1 -1
  95. package/dist/studio.css +1 -1
  96. package/package.json +17 -4
  97. package/skills/camox/references/block-definitions.md +1 -1
  98. package/dist/features/vite/publishSeededContent.js +0 -30
  99. package/skills/camox-cli/SKILL.md +0 -15
  100. package/skills/camox-cli/references/cli-common.md +0 -58
  101. package/skills/camox-cli/references/cli-content.md +0 -181
  102. package/skills/camox-cli/references/cli-publishing.md +0 -26
@@ -113,9 +113,10 @@ function RendererApp(t0) {
113
113
  }
114
114
  /** A block's thumbnail, rendered by the draft's code into its frame: nothing for a block it lacks. */
115
115
  function RendererThumbnail(t0) {
116
- const $ = c(9);
116
+ const $ = c(17);
117
117
  const { slot, blockType, camoxApp } = t0;
118
118
  const frameWindow = slot.ownerDocument.defaultView;
119
+ const left = useLeftInSlot(slot);
119
120
  const t1 = frameWindow?.frameElement ?? null;
120
121
  let t2;
121
122
  if ($[0] !== frameWindow || $[1] !== t1) {
@@ -130,32 +131,55 @@ function RendererThumbnail(t0) {
130
131
  const frameContext = t2;
131
132
  let t3;
132
133
  if ($[3] !== blockType || $[4] !== camoxApp) {
133
- t3 = /* @__PURE__ */ jsx(ThumbnailErrorBoundary, { children: /* @__PURE__ */ jsx(React.Suspense, {
134
- fallback: null,
135
- children: /* @__PURE__ */ jsx(ThumbnailBlock, {
136
- blockType,
137
- camoxApp
138
- })
139
- }) });
134
+ t3 = /* @__PURE__ */ jsx(ThumbnailBlock, {
135
+ blockType,
136
+ camoxApp
137
+ });
140
138
  $[3] = blockType;
141
139
  $[4] = camoxApp;
142
140
  $[5] = t3;
143
141
  } else t3 = $[5];
144
142
  let t4;
145
- if ($[6] !== frameContext || $[7] !== t3) {
146
- t4 = /* @__PURE__ */ jsx(NavigationProvider, {
143
+ if ($[6] !== left) {
144
+ t4 = /* @__PURE__ */ jsx(RemovesLeft, { nodes: left });
145
+ $[6] = left;
146
+ $[7] = t4;
147
+ } else t4 = $[7];
148
+ let t5;
149
+ if ($[8] !== t3 || $[9] !== t4) {
150
+ t5 = /* @__PURE__ */ jsxs(React.Suspense, {
151
+ fallback: null,
152
+ children: [t3, t4]
153
+ });
154
+ $[8] = t3;
155
+ $[9] = t4;
156
+ $[10] = t5;
157
+ } else t5 = $[10];
158
+ let t6;
159
+ if ($[11] !== left || $[12] !== t5) {
160
+ t6 = /* @__PURE__ */ jsx(ThumbnailErrorBoundary, {
161
+ left,
162
+ children: t5
163
+ });
164
+ $[11] = left;
165
+ $[12] = t5;
166
+ $[13] = t6;
167
+ } else t6 = $[13];
168
+ let t7;
169
+ if ($[14] !== frameContext || $[15] !== t6) {
170
+ t7 = /* @__PURE__ */ jsx(NavigationProvider, {
147
171
  location: THUMBNAIL_LOCATION,
148
172
  navigate: noNavigation,
149
173
  children: /* @__PURE__ */ jsx(FrameContext.Provider, {
150
174
  value: frameContext,
151
- children: t3
175
+ children: t6
152
176
  })
153
177
  });
154
- $[6] = frameContext;
155
- $[7] = t3;
156
- $[8] = t4;
157
- } else t4 = $[8];
158
- return t4;
178
+ $[14] = frameContext;
179
+ $[15] = t6;
180
+ $[16] = t7;
181
+ } else t7 = $[16];
182
+ return t7;
159
183
  }
160
184
  const THUMBNAIL_LOCATION = {
161
185
  href: "",
@@ -173,7 +197,7 @@ var ThumbnailErrorBoundary = class extends React.Component {
173
197
  console.error("Camox: a block's thumbnail failed to render.", error);
174
198
  }
175
199
  render() {
176
- return this.state.failed ? null : this.props.children;
200
+ return this.state.failed ? /* @__PURE__ */ jsx(RemovesLeft, { nodes: this.props.left }) : this.props.children;
177
201
  }
178
202
  };
179
203
  function ThumbnailBlock(t0) {
@@ -188,6 +212,46 @@ function ThumbnailBlock(t0) {
188
212
  } else t1 = $[1];
189
213
  return t1;
190
214
  }
215
+ /**
216
+ * What another renderer document left in `slot`, read before this one renders into it. Each new
217
+ * revision loads another renderer document, and removing the last one's frame never unmounts
218
+ * what it rendered into the studio's frames, so its page stays there.
219
+ */
220
+ function useLeftInSlot(slot) {
221
+ const $ = c(2);
222
+ let t0;
223
+ if ($[0] !== slot) {
224
+ t0 = () => [...slot.childNodes];
225
+ $[0] = slot;
226
+ $[1] = t0;
227
+ } else t0 = $[1];
228
+ const [left] = React.useState(t0);
229
+ return left;
230
+ }
231
+ /**
232
+ * Removes the nodes another renderer left, once what replaces them commits: until then, the
233
+ * frame keeps showing the last page rather than nothing.
234
+ */
235
+ function RemovesLeft(t0) {
236
+ const $ = c(3);
237
+ const { nodes } = t0;
238
+ let t1;
239
+ let t2;
240
+ if ($[0] !== nodes) {
241
+ t1 = () => {
242
+ for (const node of nodes) node.remove();
243
+ };
244
+ t2 = [nodes];
245
+ $[0] = nodes;
246
+ $[1] = t1;
247
+ $[2] = t2;
248
+ } else {
249
+ t1 = $[1];
250
+ t2 = $[2];
251
+ }
252
+ React.useLayoutEffect(t1, t2);
253
+ return null;
254
+ }
191
255
  function locationOf(href) {
192
256
  const url = new URL(href);
193
257
  return {
@@ -199,10 +263,11 @@ function locationOf(href) {
199
263
  }
200
264
  /** One frame's page, with what the studio says of the frame around it. */
201
265
  function RendererFrameContent(t0) {
202
- const $ = c(59);
266
+ const $ = c(65);
203
267
  const { frame: t1, connection, camoxApp, codeLoaded, projectUuid, runtimeBasePath } = t0;
204
268
  const { frameId, slot, target } = t1;
205
269
  const frameWindow = slot.ownerDocument.defaultView;
270
+ const left = useLeftInSlot(slot);
206
271
  const frameElement = frameWindow?.frameElement ?? null;
207
272
  let t2;
208
273
  if ($[0] !== target.href) {
@@ -293,17 +358,14 @@ function RendererFrameContent(t0) {
293
358
  } else t9 = $[18];
294
359
  let t10;
295
360
  if ($[19] !== camoxApp || $[20] !== codeLoaded || $[21] !== projectUuid || $[22] !== rendered || $[23] !== runtimeBasePath || $[24] !== target.derivedLayoutId || $[25] !== target.pathname) {
296
- t10 = /* @__PURE__ */ jsx(React.Suspense, {
297
- fallback: t9,
298
- children: /* @__PURE__ */ jsx(FramePage, {
299
- camoxApp,
300
- codeLoaded,
301
- projectUuid,
302
- runtimeBasePath,
303
- pathname: target.pathname,
304
- derivedLayoutId: target.derivedLayoutId,
305
- onRendered: rendered
306
- })
361
+ t10 = /* @__PURE__ */ jsx(FramePage, {
362
+ camoxApp,
363
+ codeLoaded,
364
+ projectUuid,
365
+ runtimeBasePath,
366
+ pathname: target.pathname,
367
+ derivedLayoutId: target.derivedLayoutId,
368
+ onRendered: rendered
307
369
  });
308
370
  $[19] = camoxApp;
309
371
  $[20] = codeLoaded;
@@ -315,110 +377,128 @@ function RendererFrameContent(t0) {
315
377
  $[26] = t10;
316
378
  } else t10 = $[26];
317
379
  let t11;
318
- if ($[27] !== failed || $[28] !== t10 || $[29] !== target.pathname) {
319
- t11 = /* @__PURE__ */ jsx(FrameErrorBoundary, {
320
- onError: failed,
321
- children: t10
322
- }, target.pathname);
323
- $[27] = failed;
324
- $[28] = t10;
325
- $[29] = target.pathname;
326
- $[30] = t11;
327
- } else t11 = $[30];
380
+ if ($[27] !== left) {
381
+ t11 = /* @__PURE__ */ jsx(RemovesLeft, { nodes: left });
382
+ $[27] = left;
383
+ $[28] = t11;
384
+ } else t11 = $[28];
328
385
  let t12;
329
- if ($[31] !== t11 || $[32] !== t8) {
330
- t12 = /* @__PURE__ */ jsx(React.Activity, {
331
- mode: t8,
332
- children: t11
386
+ if ($[29] !== t10 || $[30] !== t11) {
387
+ t12 = /* @__PURE__ */ jsxs(React.Suspense, {
388
+ fallback: t9,
389
+ children: [t10, t11]
333
390
  });
334
- $[31] = t11;
335
- $[32] = t8;
336
- $[33] = t12;
337
- } else t12 = $[33];
391
+ $[29] = t10;
392
+ $[30] = t11;
393
+ $[31] = t12;
394
+ } else t12 = $[31];
338
395
  let t13;
339
- if ($[34] !== t12 || $[35] !== target.artifactStudio) {
340
- t13 = /* @__PURE__ */ jsx(ArtifactStudioContext, {
341
- value: target.artifactStudio,
396
+ if ($[32] !== failed || $[33] !== left || $[34] !== t12 || $[35] !== target.pathname) {
397
+ t13 = /* @__PURE__ */ jsx(FrameErrorBoundary, {
398
+ onError: failed,
399
+ left,
342
400
  children: t12
343
- });
401
+ }, target.pathname);
402
+ $[32] = failed;
403
+ $[33] = left;
344
404
  $[34] = t12;
345
- $[35] = target.artifactStudio;
405
+ $[35] = target.pathname;
346
406
  $[36] = t13;
347
407
  } else t13 = $[36];
348
408
  let t14;
349
- if ($[37] !== t13 || $[38] !== target.artifactsRun) {
350
- t14 = /* @__PURE__ */ jsx(ArtifactsRunContext, {
351
- value: target.artifactsRun,
409
+ if ($[37] !== t13 || $[38] !== t8) {
410
+ t14 = /* @__PURE__ */ jsx(React.Activity, {
411
+ mode: t8,
352
412
  children: t13
353
413
  });
354
414
  $[37] = t13;
355
- $[38] = target.artifactsRun;
415
+ $[38] = t8;
356
416
  $[39] = t14;
357
417
  } else t14 = $[39];
358
418
  let t15;
359
- if ($[40] !== t14 || $[41] !== target.editable) {
360
- t15 = /* @__PURE__ */ jsx(EditableSurfaceContext, {
361
- value: target.editable,
419
+ if ($[40] !== t14 || $[41] !== target.artifactStudio) {
420
+ t15 = /* @__PURE__ */ jsx(ArtifactStudioContext, {
421
+ value: target.artifactStudio,
362
422
  children: t14
363
423
  });
364
424
  $[40] = t14;
365
- $[41] = target.editable;
425
+ $[41] = target.artifactStudio;
366
426
  $[42] = t15;
367
427
  } else t15 = $[42];
368
428
  let t16;
369
- if ($[43] !== t15 || $[44] !== workspace) {
370
- t16 = /* @__PURE__ */ jsx(CanvasWorkspaceContext, {
371
- value: workspace,
429
+ if ($[43] !== t15 || $[44] !== target.artifactsRun) {
430
+ t16 = /* @__PURE__ */ jsx(ArtifactsRunContext, {
431
+ value: target.artifactsRun,
372
432
  children: t15
373
433
  });
374
434
  $[43] = t15;
375
- $[44] = workspace;
435
+ $[44] = target.artifactsRun;
376
436
  $[45] = t16;
377
437
  } else t16 = $[45];
378
438
  let t17;
379
- if ($[46] !== t16 || $[47] !== target.owner) {
380
- t17 = /* @__PURE__ */ jsx(PreviewEditingOwnerContext, {
381
- value: target.owner,
439
+ if ($[46] !== t16 || $[47] !== target.editable) {
440
+ t17 = /* @__PURE__ */ jsx(EditableSurfaceContext, {
441
+ value: target.editable,
382
442
  children: t16
383
443
  });
384
444
  $[46] = t16;
385
- $[47] = target.owner;
445
+ $[47] = target.editable;
386
446
  $[48] = t17;
387
447
  } else t17 = $[48];
388
448
  let t18;
389
- if ($[49] !== frameContext || $[50] !== t17) {
390
- t18 = /* @__PURE__ */ jsx(FrameContext.Provider, {
391
- value: frameContext,
449
+ if ($[49] !== t17 || $[50] !== workspace) {
450
+ t18 = /* @__PURE__ */ jsx(CanvasWorkspaceContext, {
451
+ value: workspace,
392
452
  children: t17
393
453
  });
394
- $[49] = frameContext;
395
- $[50] = t17;
454
+ $[49] = t17;
455
+ $[50] = workspace;
396
456
  $[51] = t18;
397
457
  } else t18 = $[51];
398
458
  let t19;
399
- if ($[52] !== location || $[53] !== navigate || $[54] !== t18) {
400
- t19 = /* @__PURE__ */ jsx(NavigationProvider, {
401
- location,
402
- navigate,
459
+ if ($[52] !== t18 || $[53] !== target.owner) {
460
+ t19 = /* @__PURE__ */ jsx(PreviewEditingOwnerContext, {
461
+ value: target.owner,
403
462
  children: t18
404
463
  });
405
- $[52] = location;
406
- $[53] = navigate;
407
- $[54] = t18;
408
- $[55] = t19;
409
- } else t19 = $[55];
410
- const content = t19;
464
+ $[52] = t18;
465
+ $[53] = target.owner;
466
+ $[54] = t19;
467
+ } else t19 = $[54];
411
468
  let t20;
412
- if ($[56] !== content || $[57] !== target.locale) {
413
- t20 = target.locale ? /* @__PURE__ */ jsx(ViewLocaleContext, {
469
+ if ($[55] !== frameContext || $[56] !== t19) {
470
+ t20 = /* @__PURE__ */ jsx(FrameContext.Provider, {
471
+ value: frameContext,
472
+ children: t19
473
+ });
474
+ $[55] = frameContext;
475
+ $[56] = t19;
476
+ $[57] = t20;
477
+ } else t20 = $[57];
478
+ let t21;
479
+ if ($[58] !== location || $[59] !== navigate || $[60] !== t20) {
480
+ t21 = /* @__PURE__ */ jsx(NavigationProvider, {
481
+ location,
482
+ navigate,
483
+ children: t20
484
+ });
485
+ $[58] = location;
486
+ $[59] = navigate;
487
+ $[60] = t20;
488
+ $[61] = t21;
489
+ } else t21 = $[61];
490
+ const content = t21;
491
+ let t22;
492
+ if ($[62] !== content || $[63] !== target.locale) {
493
+ t22 = target.locale ? /* @__PURE__ */ jsx(ViewLocaleContext, {
414
494
  value: target.locale,
415
495
  children: content
416
496
  }) : content;
417
- $[56] = content;
418
- $[57] = target.locale;
419
- $[58] = t20;
420
- } else t20 = $[58];
421
- return t20;
497
+ $[62] = content;
498
+ $[63] = target.locale;
499
+ $[64] = t22;
500
+ } else t22 = $[64];
501
+ return t22;
422
502
  }
423
503
  function _temp2() {
424
504
  return _temp;
@@ -539,19 +619,23 @@ var FrameErrorBoundary = class extends React.Component {
539
619
  role: "alert",
540
620
  "data-camox-renderer-error": true,
541
621
  style: ERROR_STYLE,
542
- children: [/* @__PURE__ */ jsx("p", {
543
- style: {
544
- margin: 0,
545
- fontWeight: 600
546
- },
547
- children: "This page couldn’t render."
548
- }), /* @__PURE__ */ jsx("p", {
549
- style: {
550
- margin: "8px 0 0",
551
- fontFamily: "ui-monospace, monospace"
552
- },
553
- children: this.state.error
554
- })]
622
+ children: [
623
+ /* @__PURE__ */ jsx(RemovesLeft, { nodes: this.props.left }),
624
+ /* @__PURE__ */ jsx("p", {
625
+ style: {
626
+ margin: 0,
627
+ fontWeight: 600
628
+ },
629
+ children: "This page couldn’t render."
630
+ }),
631
+ /* @__PURE__ */ jsx("p", {
632
+ style: {
633
+ margin: "8px 0 0",
634
+ fontFamily: "ui-monospace, monospace"
635
+ },
636
+ children: this.state.error
637
+ })
638
+ ]
555
639
  });
556
640
  }
557
641
  };
@@ -54,20 +54,16 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
54
54
  const shownScope = () => draftScope?.current() ?? LIVE_KEY_SCOPE;
55
55
  const shown = (queryKey) => scopeOfKey(queryKey) === shownScope();
56
56
  /** Whether a project room invalidation reaches the reads of the draft the renderer shows. */
57
- const reaches = async (message, projectId) => {
58
- if (message.draftId === null) return true;
59
- if (!draftScope) return false;
60
- return await draftScope.keyScopeOfDraft(message.draftId, projectId) === shownScope();
61
- };
57
+ const reaches = (message) => message.draftId === null || !!draftScope && message.draftId === shownScope();
62
58
  const relayChange = (change) => {
63
59
  switch (change.type) {
64
60
  case "received": {
65
61
  const { message, projectId } = change;
66
- reaches(message, projectId).then((reached) => reached && post({
62
+ if (reaches(message)) post({
67
63
  type: "invalidate",
68
64
  message,
69
65
  projectId
70
- }));
66
+ });
71
67
  return;
72
68
  }
73
69
  case "wrote":
@@ -22,14 +22,11 @@ export type PageStructure = {
22
22
  recordStructuredData?: PageWithBlocks["recordStructuredData"];
23
23
  };
24
24
  /**
25
- * Why a member can't see the draft a URL names: it doesn't exist, it's someone else's
26
- * development draft, or it was published or deleted (ADR 0011). In dev mode, the caller's
27
- * own development draft doesn't exist until the dev server's first sync creates it.
25
+ * Why a member can't see the draft a URL names: it doesn't exist, it isn't open to them, or it
26
+ * was published or deleted (ADR 0011).
28
27
  */
29
28
  export type DraftNotice = {
30
29
  reason: "missing";
31
- } | {
32
- reason: "noDevelopmentDraft";
33
30
  } | {
34
31
  reason: "forbidden";
35
32
  } | ({
@@ -6,7 +6,7 @@ import { PAGE_IMAGE_SIZE, pageImageUrl } from "../og/pageImage.js";
6
6
  import { curatedLayoutContext } from "../../core/layoutContext.js";
7
7
  import { isArticle } from "../../core/structuredData.js";
8
8
  import { publishingDraft } from "../runtime/publishingDraft.js";
9
- import { DRAFT_ENDED_ERROR_CODE, DRAFT_HEADER, NO_DEVELOPMENT_DRAFT_ERROR, PUBLISHING_DRAFT_HEADER } from "@camox/api-contract/drafts";
9
+ import { DRAFT_ENDED_ERROR_CODE, DRAFT_HEADER, PUBLISHING_DRAFT_HEADER } from "@camox/api-contract/drafts";
10
10
  import { createORPCClient } from "@orpc/client";
11
11
  import { RPCLink } from "@orpc/client/fetch";
12
12
 
@@ -83,7 +83,6 @@ function draftRefusalNotice(error, draftId) {
83
83
  reason: "ended",
84
84
  ...data
85
85
  };
86
- if (code === NO_DEVELOPMENT_DRAFT_ERROR) return { reason: "noDevelopmentDraft" };
87
86
  if (isNotFoundError(error) && data?.draftId === draftId) return { reason: "missing" };
88
87
  if (code === "FORBIDDEN" || status === 403) return { reason: "forbidden" };
89
88
  if (code === "UNAUTHORIZED" || status === 401) return null;
@@ -7,8 +7,8 @@ import { PreviewToolbar } from "../preview/components/PreviewToolbar.js";
7
7
  import { AgentSidebar } from "../studio/components/AgentSidebar.js";
8
8
  import { FollowAgentProvider } from "../studio/FollowAgentProvider.js";
9
9
  import { c } from "react/compiler-runtime";
10
- import { useSelector } from "@xstate/store-react";
11
10
  import { jsx, jsxs } from "react/jsx-runtime";
11
+ import { useSelector } from "@xstate/store-react";
12
12
  import studioCssUrl from "virtual:camox-studio-css";
13
13
 
14
14
  //#region src/features/runtime/RuntimeChrome.tsx
@@ -0,0 +1,8 @@
1
+ //#region src/features/runtime/loopbackFetch.d.ts
2
+ /**
3
+ * Browsers resolve any `*.localhost` name to loopback, but the Workers runtime asks the
4
+ * OS, which need not. Local dev servers (like the per-checkout API) use such names, so
5
+ * the dev worker reaches them on 127.0.0.1 instead.
6
+ */
7
+ export declare function fetchLocalhostOnLoopback(fetch: typeof globalThis.fetch): typeof globalThis.fetch;
8
+ //#endregion
@@ -9,8 +9,7 @@ function runtimePath(pathname, basePath) {
9
9
  }
10
10
  /**
11
11
  * Requests one of the runtime's JSON endpoints (`/_camox/data`, `/_camox/routes`) as the editor,
12
- * reading `draft` (null for Live) in `locale` (the default locale without it). Dev mode's runtime
13
- * always reads the development draft. A path the endpoint takes names its own locale by its
12
+ * reading `draft` (null for Live) in `locale` (the default locale without it). A path the endpoint takes names its own locale by its
14
13
  * prefix; route discovery, which takes none, reads the locale the request names.
15
14
  */
16
15
  function fetchRuntimeJson(draftScope, endpoint, runtimeBasePath, params, draft, signal, locale) {
@@ -1,5 +1,5 @@
1
- import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
2
1
  import { DraftScopeContext } from "../../lib/draft-scope.js";
2
+ import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
3
3
  import { useSignInShortcut } from "../provider/signInShortcut.js";
4
4
  import { PreviewDocumentContext } from "./PreviewDocumentContext.js";
5
5
  import { PreviewActivation } from "../preview/components/PreviewActivation.js";
@@ -0,0 +1,21 @@
1
+ //#region src/features/runtime/publicCache.d.ts
2
+ /** Where a website's public renders are kept, and what they're kept under. */
3
+ export interface PublicCache {
4
+ /** Opens Cloudflare's cache in the request's data center: `PUBLIC_CACHE_NAME`. */
5
+ cache: () => Promise<Cache>;
6
+ /** The project's Live cache key, which changes whenever Live does; null when unreadable. */
7
+ liveCacheKey: () => Promise<string | null>;
8
+ /** The website's build, so a release never serves pages naming the last release's assets. */
9
+ build: string;
10
+ waitUntil: (promise: Promise<unknown>) => void;
11
+ }
12
+ /** The named cache public renders are kept in. */
13
+ export declare const PUBLIC_CACHE_NAME = "camox-public-renders";
14
+ /** The project's Live cache key, as the API serves it from its edge cache. */
15
+ export declare function readLiveCacheKey(apiUrl: string, projectUuid: string): Promise<string | null>;
16
+ /**
17
+ * Answers a public request from the cache, or renders it and keeps the render when it may be
18
+ * shared. Without a Live cache key, it renders without the cache: nothing tells when Live changed.
19
+ */
20
+ export declare function respondThroughPublicCache(request: Request, publicCache: PublicCache, render: () => Promise<Response | null>): Promise<Response | null>;
21
+ //#endregion
@@ -0,0 +1,4 @@
1
+ //#region src/features/runtime/publishingDraft.d.ts
2
+ /** Keeps the publishing draft a Worker's environment names, if it names one. */
3
+ export declare function rememberPublishingDraft(env: unknown): void;
4
+ //#endregion
@@ -1,6 +1,6 @@
1
- import { getDraftReadClient } from "../../lib/api-client.js";
2
1
  import { DraftScopeContext, createDraftScope, followUrl } from "../../lib/draft-scope.js";
3
2
  import { StudioCacheContext, createStudioCache } from "../../lib/studio-reads.js";
3
+ import { getDraftReadClient } from "../../lib/api-client.js";
4
4
  import { STUDIO_HANDLE_KEY } from "../renderer/protocol.js";
5
5
  import { CoreCamoxProvider } from "../provider/CoreCamoxProvider.js";
6
6
  import { readHydrationData } from "./hydrationData.js";
@@ -82,11 +82,6 @@ export interface RuntimeOptions {
82
82
  /** The built chunks each block module needs, by module path. `null` in dev. */
83
83
  chunks: Record<string, string[]> | null;
84
84
  };
85
- /**
86
- * Dev mode: every render reads the caller's development draft and ignores the URL's draft
87
- * (ADR 0006).
88
- */
89
- developmentDraft?: boolean;
90
85
  pageClientEntryUrl?: string;
91
86
  studioClientEntryUrl?: string;
92
87
  /** The renderer frame's client entry, which renders the studio's pages (ADR 0023). */