camox 0.60.2 → 0.62.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.
@@ -139,7 +139,7 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
139
139
  [attribute: `data-camox-${string}`]: string | boolean | undefined;
140
140
  }, data: FileValue) => React.ReactNode;
141
141
  }) => React.ReactNode;
142
- Repeater: <K extends never>({ name, children }: {
142
+ Repeater: <K extends never>(props: {
143
143
  name: K;
144
144
  children: (item: {
145
145
  Field: <F extends keyof { [F_1 in keyof ({}[K] extends (infer U)[] ? U : never) as ({}[K] extends (infer U)[] ? U : never)[F_1] extends IconValue | ArtifactSource ? never : ({}[K] extends (infer U)[] ? U : never)[F_1] extends string ? F_1 : never]: ({}[K] extends (infer U)[] ? U : never)[F_1]; }>(props: InlineTextStyles & {
@@ -402,12 +402,12 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
402
402
  }) => React.ReactNode;
403
403
  useSetting: <F extends string>(name: F) => never;
404
404
  }, index: number) => React.ReactNode;
405
- }) => import("react").JSX.Element;
406
- Reference: <K extends never>({ name, children }: {
405
+ }) => React.ReactNode;
406
+ Reference: <K extends never>(props: {
407
407
  name: K;
408
408
  children: (scope: ReferenceScope<never>) => React.ReactNode;
409
409
  }) => React.ReactNode;
410
- ReferenceList: <K extends never>({ name, children }: {
410
+ ReferenceList: <K extends never>(props: {
411
411
  name: K;
412
412
  children: (scope: ReferenceScope<never>) => React.ReactNode;
413
413
  }) => React.ReactNode;
@@ -581,7 +581,7 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
581
581
  [attribute: `data-camox-${string}`]: string | boolean | undefined;
582
582
  }, data: FileValue) => React.ReactNode;
583
583
  }) => React.ReactNode;
584
- Repeater: <K extends never>({ name, children }: {
584
+ Repeater: <K extends never>(props: {
585
585
  name: K;
586
586
  children: (item: {
587
587
  Field: <F extends keyof { [F_1 in keyof ({}[K] extends (infer U)[] ? U : never) as ({}[K] extends (infer U)[] ? U : never)[F_1] extends IconValue | ArtifactSource ? never : ({}[K] extends (infer U)[] ? U : never)[F_1] extends string ? F_1 : never]: ({}[K] extends (infer U)[] ? U : never)[F_1]; }>(props: InlineTextStyles & {
@@ -844,12 +844,12 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
844
844
  }) => React.ReactNode;
845
845
  useSetting: <F extends string>(name: F) => never;
846
846
  }, index: number) => React.ReactNode;
847
- }) => import("react").JSX.Element;
848
- Reference: <K extends never>({ name, children }: {
847
+ }) => React.ReactNode;
848
+ Reference: <K extends never>(props: {
849
849
  name: K;
850
850
  children: (scope: ReferenceScope<never>) => React.ReactNode;
851
851
  }) => React.ReactNode;
852
- ReferenceList: <K extends never>({ name, children }: {
852
+ ReferenceList: <K extends never>(props: {
853
853
  name: K;
854
854
  children: (scope: ReferenceScope<never>) => React.ReactNode;
855
855
  }) => React.ReactNode;
@@ -3,8 +3,7 @@ import "./lib/lexicalReact.js";
3
3
  import { ContentFieldBuilder, SettingBuilder } from "./lib/contentType.js";
4
4
  import { BlockComponentProps, PeekItem, RepeatableItemSeed, createEditableBlock } from "./editing/createEditableBlock.js";
5
5
  //#region src/core/createBlock.d.ts
6
- type EditableCreateBlock = typeof createEditableBlock;
7
- export declare const createBlock: EditableCreateBlock;
6
+ export declare const createBlock: typeof createEditableBlock;
8
7
  export type Block = ReturnType<typeof createBlock>;
9
8
  //#endregion
10
9
  export type { BlockComponentProps, ContentFieldBuilder, InlineStyle, InlineTextStyles, PeekItem, RepeatableItemSeed, SettingBuilder, TextLinkStyleData, TextStyleData };
@@ -211,8 +211,16 @@ type CreateLayoutOptions<TBefore extends readonly LayoutBlock[], TAfter extends
211
211
  } & LayoutOutputs<LoadedContext<LoaderData<Result>, Record<string, string>, RecordFields<Result>>, {
212
212
  children: React.ReactNode;
213
213
  }, Declared>;
214
- /** Every option a layout may define, as the implementation reads them. */
215
- type AnyLayoutOptions = LayoutBaseOptions<any, any, any> & {
214
+ /**
215
+ * Every option a layout may define, as the implementation reads them. The public signatures
216
+ * validated which slot each block may go in.
217
+ */
218
+ type AnyLayoutOptions = Omit<LayoutBaseOptions<any, any, any>, "blocks"> & {
219
+ blocks: {
220
+ before: readonly LayoutBlock<true>[];
221
+ after: readonly LayoutBlock<true>[];
222
+ initial?: readonly InitialBlockImport[];
223
+ };
216
224
  kind?: "curated" | "derived" | "singleton";
217
225
  loader?: (context: LayoutLoaderContext) => LoaderReturn;
218
226
  routes?: (context: LayoutRoutesContext) => RoutesReturn<Record<string, string>>;
@@ -16,9 +16,7 @@ function createLayoutDefinition(options) {
16
16
  if (options.routes && options.kind !== "derived") throw new Error(`Only derived layouts can define routes: ${options.id}`);
17
17
  if (options.toMarkdown && (options.kind ?? "curated") === "curated") throw new Error(`Curated layouts cannot define toMarkdown: ${options.id}`);
18
18
  const LayoutContext = React.createContext(null);
19
- const beforeBlocks = options.blocks.before;
20
- const afterBlocks = options.blocks.after;
21
- const initialBlocks = options.blocks.initial;
19
+ const { before: beforeBlocks, after: afterBlocks, initial: initialBlocks } = options.blocks;
22
20
  const BeforeBlocks = () => {
23
21
  const $ = c(4);
24
22
  const ctx = React.use(LayoutContext);
@@ -1,5 +1,6 @@
1
1
  import { LoadedRecord } from "../requestContext.js";
2
2
  import { Collection } from "../createCollection.js";
3
+ import "./createEditableBlock.js";
3
4
  import * as React from "react";
4
5
  //#region src/core/editing/BlockEditingRuntime.d.ts
5
6
  /** A record page's record, as `layout.Item` hands it to the editing runtime. */
@@ -13,6 +13,10 @@ function getEditableDefinition(options) {
13
13
  editableDefinitions.set(options, definition);
14
14
  return definition;
15
15
  }
16
+ /** A primitive of the editable definition, rendered with the props the view block received. */
17
+ function editingPrimitive(definition, primitive) {
18
+ return definition[primitive];
19
+ }
16
20
  function EditableBlock(t0) {
17
21
  const $ = c(5);
18
22
  const { options, props } = t0;
@@ -23,15 +27,14 @@ function EditableBlock(t0) {
23
27
  $[1] = t1;
24
28
  } else t1 = $[1];
25
29
  const Component = t1._internal.Component;
26
- const t2 = props;
27
- let t3;
28
- if ($[2] !== Component || $[3] !== t2) {
29
- t3 = /* @__PURE__ */ jsx(Component, { ...t2 });
30
+ let t2;
31
+ if ($[2] !== Component || $[3] !== props) {
32
+ t2 = /* @__PURE__ */ jsx(Component, { ...props });
30
33
  $[2] = Component;
31
- $[3] = t2;
32
- $[4] = t3;
33
- } else t3 = $[4];
34
- return t3;
34
+ $[3] = props;
35
+ $[4] = t2;
36
+ } else t2 = $[4];
37
+ return t2;
35
38
  }
36
39
  /** Record pages' records render through the record scope of a block without fields. */
37
40
  const layoutItemOptions = {
@@ -58,7 +61,7 @@ const completeEditingRuntime = {
58
61
  });
59
62
  },
60
63
  renderPrimitive(options, primitive, props) {
61
- const Primitive = getEditableDefinition(options)[primitive];
64
+ const Primitive = editingPrimitive(getEditableDefinition(options), primitive);
62
65
  if (!Primitive) throw new Error(`Unknown Camox editing primitive: ${primitive}`);
63
66
  return /* @__PURE__ */ jsx(Primitive, { ...props });
64
67
  }
@@ -527,7 +527,7 @@ export declare function createEditableBlock<TSchemaShape extends Record<string,
527
527
  params: unknown[] & [];
528
528
  })["static"]; }, { [K_4 in keyof TSchemaShape]: TSchemaShape[K_4] extends import("@sinclair/typebox").TOptional<TSchema> ? TSchemaShape[K_4] extends import("@sinclair/typebox").TReadonly<TSchemaShape[K_4]> ? never : K_4 : never; }[keyof TSchemaShape]>> & Required<Pick<{ [K_1 in keyof TSchemaShape]: (TSchemaShape[K_1] & {
529
529
  params: unknown[] & [];
530
- })["static"]; }, Exclude<keyof TSchemaShape, { [K_2 in keyof TSchemaShape]: TSchemaShape[K_2] extends import("@sinclair/typebox").TReadonly<TSchema> ? TSchemaShape[K_2] extends import("@sinclair/typebox").TOptional<TSchemaShape[K_2]> ? K_2 : never : never; }[keyof TSchemaShape] | { [K_3 in keyof TSchemaShape]: TSchemaShape[K_3] extends import("@sinclair/typebox").TReadonly<TSchema> ? TSchemaShape[K_3] extends import("@sinclair/typebox").TOptional<TSchemaShape[K_3]> ? never : K_3 : never; }[keyof TSchemaShape] | { [K_4 in keyof TSchemaShape]: TSchemaShape[K_4] extends import("@sinclair/typebox").TOptional<TSchema> ? TSchemaShape[K_4] extends import("@sinclair/typebox").TReadonly<TSchemaShape[K_4]> ? never : K_4 : never; }[keyof TSchemaShape]>>>>[K_5]; }>({ name, children }: {
530
+ })["static"]; }, Exclude<keyof TSchemaShape, { [K_2 in keyof TSchemaShape]: TSchemaShape[K_2] extends import("@sinclair/typebox").TReadonly<TSchema> ? TSchemaShape[K_2] extends import("@sinclair/typebox").TOptional<TSchemaShape[K_2]> ? K_2 : never : never; }[keyof TSchemaShape] | { [K_3 in keyof TSchemaShape]: TSchemaShape[K_3] extends import("@sinclair/typebox").TReadonly<TSchema> ? TSchemaShape[K_3] extends import("@sinclair/typebox").TOptional<TSchemaShape[K_3]> ? never : K_3 : never; }[keyof TSchemaShape] | { [K_4 in keyof TSchemaShape]: TSchemaShape[K_4] extends import("@sinclair/typebox").TOptional<TSchema> ? TSchemaShape[K_4] extends import("@sinclair/typebox").TReadonly<TSchemaShape[K_4]> ? never : K_4 : never; }[keyof TSchemaShape]>>>>[K_5]; }>(props: {
531
531
  name: K;
532
532
  children: (item: {
533
533
  Field: <F extends keyof { [F_1 in keyof ({ [K_5 in keyof import("@sinclair/typebox").Evaluate<Readonly<Partial<Pick<{ [K_1 in keyof TSchemaShape]: (TSchemaShape[K_1] & {
@@ -1652,12 +1652,12 @@ export declare function createEditableBlock<TSchemaShape extends Record<string,
1652
1652
  params: unknown[] & [];
1653
1653
  })["static"]; }, Exclude<keyof S, { [K_7 in keyof S]: S[K_7] extends import("@sinclair/typebox").TReadonly<TSchema> ? S[K_7] extends import("@sinclair/typebox").TOptional<S[K_7]> ? K_7 : never : never; }[keyof S] | { [K_8 in keyof S]: S[K_8] extends import("@sinclair/typebox").TReadonly<TSchema> ? S[K_8] extends import("@sinclair/typebox").TOptional<S[K_8]> ? never : K_8 : never; }[keyof S] | { [K_9 in keyof S]: S[K_9] extends import("@sinclair/typebox").TOptional<TSchema> ? S[K_9] extends import("@sinclair/typebox").TReadonly<S[K_9]> ? never : K_9 : never; }[keyof S]>>>> : Record<string, never> : Record<string, never>)[F];
1654
1654
  }, index: number) => React.ReactNode;
1655
- }) => React.JSX.Element;
1656
- Reference: <K extends ReferenceKeys<TSchemaShape>>({ name, children }: {
1655
+ }) => React.ReactNode;
1656
+ Reference: <K extends ReferenceKeys<TSchemaShape>>(props: {
1657
1657
  name: K;
1658
1658
  children: (scope: ReferenceScope<ReferenceContent<TSchemaShape[K]>>) => React.ReactNode;
1659
1659
  }) => React.ReactNode;
1660
- ReferenceList: <K extends ReferenceListKeys<TSchemaShape>>({ name, children }: {
1660
+ ReferenceList: <K extends ReferenceListKeys<TSchemaShape>>(props: {
1661
1661
  name: K;
1662
1662
  children: (scope: ReferenceScope<ReferenceContent<TSchemaShape[K]>>) => React.ReactNode;
1663
1663
  }) => React.ReactNode;
@@ -1455,7 +1455,7 @@ function createEditableBlock(options) {
1455
1455
  } else t4 = $[5];
1456
1456
  return t4;
1457
1457
  };
1458
- const Repeater = (t0) => {
1458
+ const RepeaterImpl = (t0) => {
1459
1459
  const $ = c(29);
1460
1460
  const { name, children } = t0;
1461
1461
  const blockContext = React.use(Context);
@@ -1463,16 +1463,7 @@ function createEditableBlock(options) {
1463
1463
  const { blockId, content, mode } = blockContext;
1464
1464
  const parentRepeaterContext = React.use(RepeatableItemContext);
1465
1465
  const fieldName = String(name);
1466
- const ItemField = Field;
1467
- const ItemLink = Link;
1468
- const ItemEmbed = Embed;
1469
- const ItemArtifact = Artifact;
1470
- const ItemImage = Image;
1471
- const ItemImageList = _AssetList;
1472
- const ItemFileList = _AssetList;
1473
- const ItemFile = File;
1474
- const ItemRepeater = Repeater;
1475
- const source = parentRepeaterContext ? parentRepeaterContext.itemContent[name] : content[name];
1466
+ const source = parentRepeaterContext ? parentRepeaterContext.itemContent[fieldName] : content[fieldName];
1476
1467
  const { itemsMap } = useNormalizedData();
1477
1468
  let t1;
1478
1469
  if ($[0] !== source) {
@@ -1481,7 +1472,7 @@ function createEditableBlock(options) {
1481
1472
  $[1] = t1;
1482
1473
  } else t1 = $[1];
1483
1474
  const storedValue = t1;
1484
- if (!Array.isArray(storedValue)) throw new Error(`Field "${String(name)}" is not an array`);
1475
+ if (!Array.isArray(storedValue)) throw new Error(`Field "${fieldName}" is not an array`);
1485
1476
  let T0;
1486
1477
  let t2;
1487
1478
  let t3;
@@ -1518,18 +1509,18 @@ function createEditableBlock(options) {
1518
1509
  const itemId = isDbItem ? item_0.id : void 0;
1519
1510
  const useItemSetting = (settingName) => itemSettings[settingName];
1520
1511
  const itemApi = {
1521
- Field: ItemField,
1522
- Link: ItemLink,
1512
+ Field,
1513
+ Link,
1523
1514
  Icon,
1524
- Embed: ItemEmbed,
1525
- Artifact: ItemArtifact,
1526
- Image: ItemImage,
1527
- File: ItemFile,
1528
- ImageList: ItemImageList,
1529
- FileList: ItemFileList,
1530
- Repeater: ItemRepeater,
1531
- Reference,
1532
- ReferenceList,
1515
+ Embed,
1516
+ Artifact,
1517
+ Image,
1518
+ File,
1519
+ ImageList: _AssetList,
1520
+ FileList: _AssetList,
1521
+ Repeater: RepeaterImpl,
1522
+ Reference: ReferenceImpl,
1523
+ ReferenceList: ReferenceListImpl,
1533
1524
  useSetting: useItemSetting
1534
1525
  };
1535
1526
  return /* @__PURE__ */ jsx(RepeatableItemContext.Provider, {
@@ -1595,6 +1586,7 @@ function createEditableBlock(options) {
1595
1586
  } else t5 = $[28];
1596
1587
  return t5;
1597
1588
  };
1589
+ const Repeater = RepeaterImpl;
1598
1590
  const BlockComponent = (t0) => {
1599
1591
  const $ = c(63);
1600
1592
  const { blockData, mode, isFirstBlock, showAddBlockTop, showAddBlockBottom, addBlockAfterPosition } = t0;
@@ -2313,7 +2305,7 @@ function createEditableBlock(options) {
2313
2305
  } else t4 = $[9];
2314
2306
  return t4;
2315
2307
  };
2316
- const Reference = (t0) => {
2308
+ const ReferenceImpl = (t0) => {
2317
2309
  const $ = c(21);
2318
2310
  const { name, children } = t0;
2319
2311
  const block = React.use(Context);
@@ -2386,6 +2378,7 @@ function createEditableBlock(options) {
2386
2378
  } else t4 = $[20];
2387
2379
  return t4;
2388
2380
  };
2381
+ const Reference = ReferenceImpl;
2389
2382
  const ListedRecord = (t0) => {
2390
2383
  const $ = c(14);
2391
2384
  const { block, owner, field, fieldName, record, listHovered, children } = t0;
@@ -2565,7 +2558,7 @@ function createEditableBlock(options) {
2565
2558
  } else t3 = $[8];
2566
2559
  return t3;
2567
2560
  };
2568
- const ReferenceList = (t0) => {
2561
+ const ReferenceListImpl = (t0) => {
2569
2562
  const $ = c(44);
2570
2563
  const { name, children } = t0;
2571
2564
  const block = React.use(Context);
@@ -2698,6 +2691,7 @@ function createEditableBlock(options) {
2698
2691
  if (t5 !== Symbol.for("react.early_return_sentinel")) return t5;
2699
2692
  return t4;
2700
2693
  };
2694
+ const ReferenceList = ReferenceListImpl;
2701
2695
  const Detached = (t0) => {
2702
2696
  const $ = c(30);
2703
2697
  const { children } = t0;
@@ -87,7 +87,7 @@ function attachArtifactData(content, settings, owner) {
87
87
  sources[name] = source;
88
88
  }
89
89
  field.dataSchema = objectSchema(Object.fromEntries(Object.entries(sources).map(([name, s]) => [name, valueSchema(s.schema)])));
90
- Reflect.set(field, DATA_SOURCES, sources);
90
+ field[DATA_SOURCES] = sources;
91
91
  }
92
92
  }
93
93
  function normalizeAsset(fieldType, file) {
@@ -122,7 +122,7 @@ function normalizeValue(schema, value, resolve) {
122
122
  * to hrefs and assets to URLs. Artifacts without `data` receive an empty object.
123
123
  */
124
124
  function artifactData(field, owner, resolve) {
125
- const sources = field && Reflect.get(field, DATA_SOURCES);
125
+ const sources = field?.[DATA_SOURCES];
126
126
  if (!sources) return {};
127
127
  return Object.fromEntries(Object.entries(sources).map(([name, { scope, schema }]) => [name, normalizeValue(schema, owner[scope][name], resolve)]));
128
128
  }
@@ -43,6 +43,7 @@ var Conditional = class {
43
43
  return "{{/if}}";
44
44
  }
45
45
  };
46
+ /** Reads each field as its token. `TProxy` is how the template reads the fields. */
46
47
  function createContentProxy(shape, prefix = "") {
47
48
  return new Proxy({}, { get(_target, prop) {
48
49
  if (typeof prop !== "string") return void 0;
@@ -58,8 +59,8 @@ function createContentProxy(shape, prefix = "") {
58
59
  */
59
60
  function referenceToken(shape, path) {
60
61
  const fields = createContentProxy(shape, path);
61
- return new Proxy(new FieldToken(path), { get(target, prop, receiver) {
62
- if (typeof prop !== "string" || prop in target) return Reflect.get(target, prop, receiver);
62
+ return new Proxy(new FieldToken(path), { get(target, prop) {
63
+ if (typeof prop !== "string" || prop in target) return target[prop];
63
64
  return fields[prop];
64
65
  } });
65
66
  }
@@ -156,10 +157,10 @@ function resolveRecordStructuredData(builder, contentShape) {
156
157
  const ARTIFACT_MAX_LENGTH = 262144;
157
158
  const IMAGE_PLACEHOLDER = Symbol("camox.imagePlaceholder");
158
159
  function isImagePlaceholder(value) {
159
- return typeof Reflect.get(value, IMAGE_PLACEHOLDER) === "string" && !value._fileId;
160
+ return typeof value[IMAGE_PLACEHOLDER] === "string" && !value._fileId;
160
161
  }
161
162
  function getImagePlaceholderTitle(value) {
162
- return Reflect.get(value, IMAGE_PLACEHOLDER);
163
+ return value[IMAGE_PLACEHOLDER];
163
164
  }
164
165
  function _imageSingle(options) {
165
166
  return Type.Unsafe({
@@ -13,54 +13,62 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
13
 
14
14
  //#region src/features/content/CamoxContent.tsx
15
15
  const CamoxContent = () => {
16
- const $ = c(7);
16
+ const $ = c(9);
17
+ const projectUuid = useProjectUuid();
18
+ let t0;
19
+ if ($[0] !== projectUuid) {
20
+ t0 = reads.project({ projectUuid });
21
+ $[0] = projectUuid;
22
+ $[1] = t0;
23
+ } else t0 = $[1];
24
+ const { data: project } = useReadQuery(t0);
17
25
  const pathname = useLocalePath();
18
26
  const localized = useLocalizedPath();
19
27
  if (pathname === "/camox/content" || pathname === `${"/camox/content"}/`) {
20
- let t0;
21
- if ($[0] !== localized) {
22
- t0 = localized(STUDIO_ASSETS_PATH);
23
- $[0] = localized;
24
- $[1] = t0;
25
- } else t0 = $[1];
26
28
  let t1;
27
- if ($[2] !== t0) {
28
- t1 = /* @__PURE__ */ jsx(Navigate, {
29
- to: t0,
30
- replace: true
31
- });
32
- $[2] = t0;
29
+ if ($[2] !== localized) {
30
+ t1 = localized(STUDIO_ASSETS_PATH);
31
+ $[2] = localized;
33
32
  $[3] = t1;
34
33
  } else t1 = $[3];
35
- return t1;
34
+ let t2;
35
+ if ($[4] !== t1) {
36
+ t2 = /* @__PURE__ */ jsx(Navigate, {
37
+ to: t1,
38
+ replace: true
39
+ });
40
+ $[4] = t1;
41
+ $[5] = t2;
42
+ } else t2 = $[5];
43
+ return t2;
36
44
  }
37
- if (typeof __CAMOX_ENABLE_EXPERIMENTAL_FEATURES__ !== "undefined" && __CAMOX_ENABLE_EXPERIMENTAL_FEATURES__) {
38
- let t0;
39
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
40
- t0 = /* @__PURE__ */ jsx(ExperimentalContent, {});
41
- $[4] = t0;
42
- } else t0 = $[4];
43
- return t0;
45
+ if (project?.experimentalFeatures) {
46
+ let t1;
47
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
48
+ t1 = /* @__PURE__ */ jsx(ExperimentalContent, {});
49
+ $[6] = t1;
50
+ } else t1 = $[6];
51
+ return t1;
44
52
  }
45
- let t0;
46
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
47
- t0 = [];
48
- $[5] = t0;
49
- } else t0 = $[5];
50
53
  let t1;
51
- if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
52
- t1 = /* @__PURE__ */ jsxs("div", {
54
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
55
+ t1 = [];
56
+ $[7] = t1;
57
+ } else t1 = $[7];
58
+ let t2;
59
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
60
+ t2 = /* @__PURE__ */ jsxs("div", {
53
61
  className: "flex min-h-0 flex-1 flex-row",
54
62
  children: [/* @__PURE__ */ jsx(ContentSidebar, {
55
- collections: t0,
63
+ collections: t1,
56
64
  selectedCollectionId: null,
57
65
  collectionsError: false,
58
66
  children: /* @__PURE__ */ jsx(MissingFromLocaleGroup, { collections: [] })
59
67
  }), /* @__PURE__ */ jsx(ContentAssets, {})]
60
68
  });
61
- $[6] = t1;
62
- } else t1 = $[6];
63
- return t1;
69
+ $[8] = t2;
70
+ } else t2 = $[8];
71
+ return t2;
64
72
  };
65
73
  const ExperimentalContent = () => {
66
74
  const $ = c(38);
@@ -6,14 +6,30 @@ import { createContentEditor } from "../../core/editing/contentEdits.js";
6
6
  import { LIVE_KEY_SCOPE, scopeOfKey } from "@camox/api-contract/query-keys";
7
7
 
8
8
  //#region src/features/renderer/rendererHost.ts
9
- const mirrored = {
10
- preview: previewStore,
11
- canvas: canvasStore
9
+ /** The studio's state of each store the renderer mirrors. */
10
+ const storeMessages = {
11
+ preview: () => ({
12
+ type: "store",
13
+ store: "preview",
14
+ context: previewStore.getSnapshot().context
15
+ }),
16
+ canvas: () => ({
17
+ type: "store",
18
+ store: "canvas",
19
+ context: canvasStore.getSnapshot().context
20
+ })
12
21
  };
22
+ /** The stores the renderer forwards its events to, as the host applies them. */
13
23
  const forwarded = {
14
24
  preview: previewStore,
15
25
  referencePickerFocus
16
26
  };
27
+ /** Applies an event the renderer forwarded to the studio's store. */
28
+ const applyStoreEvent = (message) => {
29
+ const store = forwarded[message.store];
30
+ if (!store) return;
31
+ store.send(message.event);
32
+ };
17
33
  /**
18
34
  * The host of the studio whose cache is `studioCache`, viewing the draft `draftScope` names, which
19
35
  * the renderer shows too. Without them, the renderer hears nothing of the studio's cache.
@@ -45,12 +61,8 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
45
61
  const post = (message) => {
46
62
  if (welcomed) renderer?.(message);
47
63
  };
48
- const postStore = (store) => post({
49
- type: "store",
50
- store,
51
- context: mirrored[store].getSnapshot().context
52
- });
53
- const subscriptions = Object.keys(mirrored).map((store) => mirrored[store].subscribe(() => postStore(store)));
64
+ const postStore = (store) => post(storeMessages[store]());
65
+ const subscriptions = [previewStore.subscribe(() => postStore("preview")), canvasStore.subscribe(() => postStore("canvas"))];
54
66
  const shownScope = () => draftScope?.current() ?? LIVE_KEY_SCOPE;
55
67
  const shown = (queryKey) => scopeOfKey(queryKey) === shownScope();
56
68
  /** Whether a project room invalidation reaches the reads of the draft the renderer shows. */
@@ -103,7 +115,7 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
103
115
  if (message.sdkVersion !== SDK_VERSION) return setStatus("updating");
104
116
  welcomed = true;
105
117
  setStatus("connected");
106
- for (const store of Object.keys(mirrored)) postStore(store);
118
+ for (const store of Object.keys(storeMessages)) postStore(store);
107
119
  for (const [frameId, { slot, target }] of frames) post({
108
120
  type: "frame",
109
121
  frameId,
@@ -123,12 +135,7 @@ function createRendererHost({ studioCache, draftScope, queryClient, notify } = {
123
135
  });
124
136
  for (const listener of connectionListeners) listener();
125
137
  return;
126
- case "storeEvent": {
127
- const store = forwarded[message.store];
128
- if (!store) return;
129
- store.send(message.event);
130
- return;
131
- }
138
+ case "storeEvent": return applyStoreEvent(message);
132
139
  case "rendered": return frames.get(message.frameId)?.hears.rendered?.();
133
140
  case "error": return frames.get(message.frameId)?.hears.failed?.(message.message);
134
141
  case "navigate": return frames.get(message.frameId)?.hears.navigate?.(message.to);
@@ -5,14 +5,21 @@ import { SDK_VERSION, deferredInbox } from "./protocol.js";
5
5
  import { answerFromCode } from "./definitionAnswers.js";
6
6
 
7
7
  //#region src/features/renderer/studioConnection.ts
8
+ /** The stores of this document that take the studio's state as it is (`mirror`). */
8
9
  const mirrors = {
9
10
  preview: previewStore,
10
11
  canvas: canvasStore
11
12
  };
13
+ /** The stores of this document whose events are forwarded to the studio's. */
12
14
  const forwards = {
13
15
  preview: previewStore,
14
16
  referencePickerFocus
15
17
  };
18
+ /** Has this document's copy of a mirrored store take the studio's state. */
19
+ const mirror = (message) => mirrors[message.store]?.send({
20
+ type: "mirror",
21
+ context: message.context
22
+ });
16
23
  /**
17
24
  * Connects the renderer document to the studio through its handle. This document's stores then
18
25
  * mirror the studio's, its own events are forwarded to the studio, which owns their truth, and
@@ -64,10 +71,7 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
64
71
  setFrames(frames.filter(({ frameId }) => frameId !== message.frameId));
65
72
  return;
66
73
  case "store":
67
- mirrors[message.store]?.send({
68
- type: "mirror",
69
- context: message.context
70
- });
74
+ mirror(message);
71
75
  return;
72
76
  case "draftStarted":
73
77
  draftScope.enterStarted(message.draftId);
@@ -106,7 +106,6 @@ async function buildTarget({ root, dir, target, specifiers, names, settings }) {
106
106
  define: {
107
107
  __CAMOX_ICON_IDS__: JSON.stringify(settings.iconIds),
108
108
  __CAMOX_TELEMETRY_DISABLED__: JSON.stringify(settings.telemetryDisabled),
109
- __CAMOX_ENABLE_EXPERIMENTAL_FEATURES__: JSON.stringify(settings.experimentalFeatures),
110
109
  __CAMOX_API_URL__: JSON.stringify(settings.apiUrl),
111
110
  "process.env.NODE_ENV": JSON.stringify("production")
112
111
  },
@@ -13,8 +13,8 @@ import { cp, mkdir, mkdtemp, readFile, rename, rm } from "node:fs/promises";
13
13
  */
14
14
  /** Turns building against an SDK Bundle on (`1`) or off (`0`) for `vite build`. */
15
15
  const SDK_BUNDLE_SWITCH_ENV = "CAMOX_INTERNAL_SDK_BUNDLE";
16
- /** Off until websites build against an SDK Bundle by default (#670). */
17
- const SDK_BUNDLE_SWITCH_DEFAULT = false;
16
+ /** On: websites build against an SDK Bundle by default (#670, ADR 0029). */
17
+ const SDK_BUNDLE_SWITCH_DEFAULT = true;
18
18
  /** The folder SDK Bundles are cached in, when not the website's own. */
19
19
  const SDK_BUNDLE_CACHE_ENV = "CAMOX_INTERNAL_SDK_BUNDLE_CACHE";
20
20
  /** Whether `vite build` builds against an SDK Bundle. */
@@ -28,7 +28,6 @@ export interface SdkBundleSettings {
28
28
  /** The icon ids of the collection the website picked. */
29
29
  iconIds: readonly string[];
30
30
  telemetryDisabled: boolean;
31
- experimentalFeatures: boolean;
32
31
  apiUrl: string;
33
32
  }
34
33
  export interface SdkBundleNameInputs {
@@ -67,7 +67,6 @@ async function sdkBundleName({ lockfile, importer = ".", target, settings, build
67
67
  settings: {
68
68
  iconIds: settings.iconIds,
69
69
  telemetryDisabled: settings.telemetryDisabled,
70
- experimentalFeatures: settings.experimentalFeatures,
71
70
  apiUrl: settings.apiUrl
72
71
  },
73
72
  packages: resolutions
@@ -1,6 +1,7 @@
1
1
  import { useProjectUuid } from "../../lib/auth.js";
2
2
  import { reads, useReadQuery } from "../../lib/studio-reads.js";
3
3
  import { AnalyticsSettings } from "./AnalyticsSettings.js";
4
+ import { ExperimentalFeaturesSettings } from "./ExperimentalFeaturesSettings.js";
4
5
  import { FaviconSettings } from "./FaviconSettings.js";
5
6
  import { ProjectNameSettings } from "./ProjectNameSettings.js";
6
7
  import { SocialProfilesSettings } from "./SocialProfilesSettings.js";
@@ -30,6 +31,10 @@ const parts = [
30
31
  {
31
32
  id: "analytics",
32
33
  Part: AnalyticsSettings
34
+ },
35
+ {
36
+ id: "experimental-features",
37
+ Part: ExperimentalFeaturesSettings
33
38
  }
34
39
  ];
35
40
  /**