@cmssy/react 9.10.0 → 10.1.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.
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ var internal = require('@cmssy/core/internal');
4
+
5
+ // src/components/resolve-block-data.ts
6
+
7
+ // src/registry.ts
8
+ function buildLoaderMap(blocks) {
9
+ const map = /* @__PURE__ */ Object.create(null);
10
+ for (const block of blocks) {
11
+ if (block.loader) map[block.type] = block.loader;
12
+ }
13
+ return map;
14
+ }
15
+ function blocksToSchemas(blocks) {
16
+ const out = /* @__PURE__ */ Object.create(null);
17
+ for (const block of blocks) {
18
+ const schema = {};
19
+ for (const [key, def] of Object.entries(block.props)) {
20
+ schema[key] = { ...def, label: def.label || key };
21
+ }
22
+ out[block.type] = schema;
23
+ }
24
+ return out;
25
+ }
26
+
27
+ // src/components/block-error.ts
28
+ var BLOCK_ERROR_KEY = "__cmssyBlockError";
29
+ function blockErrorMessage(err) {
30
+ return err instanceof Error ? err.message : String(err);
31
+ }
32
+ function markBlockError(error) {
33
+ return { [BLOCK_ERROR_KEY]: error };
34
+ }
35
+ async function resolveBlocks(blocks, loaderMap, locale, defaultLocale, context, enabledLocales, options) {
36
+ const contents = blocks.map(
37
+ (block) => internal.getBlockContentForLanguage(
38
+ block.content,
39
+ locale,
40
+ defaultLocale,
41
+ enabledLocales?.length ? enabledLocales : void 0
42
+ )
43
+ );
44
+ if (options?.config && options.schemas) {
45
+ await internal.resolveRelationContent(
46
+ options.config,
47
+ blocks.map((block, i) => ({ type: block.type, content: contents[i] })),
48
+ options.schemas,
49
+ locale,
50
+ options.workspaceId ? { workspaceId: options.workspaceId } : {}
51
+ );
52
+ }
53
+ return Promise.all(
54
+ blocks.map(async (block, i) => {
55
+ const content = contents[i];
56
+ const loader = loaderMap[block.type];
57
+ let data;
58
+ let error;
59
+ if (loader) {
60
+ try {
61
+ data = await loader({ content, context });
62
+ } catch (err) {
63
+ if (typeof console !== "undefined") {
64
+ console.error(
65
+ `[cmssy] loader for block "${block.type}" (${block.id}) failed`,
66
+ err
67
+ );
68
+ }
69
+ error = { message: blockErrorMessage(err), source: "loader" };
70
+ }
71
+ }
72
+ return { content, data, error };
73
+ })
74
+ );
75
+ }
76
+
77
+ // src/components/resolve-block-data.ts
78
+ function collectBlockData(blocks, resolved, isPreview) {
79
+ const data = {};
80
+ const content = {};
81
+ blocks.forEach((block, index) => {
82
+ const entry = resolved[index];
83
+ if (!entry) return;
84
+ content[block.id] = entry.content;
85
+ if (entry.error && isPreview) {
86
+ data[block.id] = markBlockError(entry.error);
87
+ } else if (entry.data !== void 0) {
88
+ data[block.id] = entry.data;
89
+ }
90
+ });
91
+ return { data, content };
92
+ }
93
+ async function resolveEditorBlockData({
94
+ page,
95
+ blocks,
96
+ locale,
97
+ defaultLocale,
98
+ enabledLocales,
99
+ forms,
100
+ isPreview = false,
101
+ config
102
+ }) {
103
+ if (!page) return { data: {}, content: {} };
104
+ const loaderMap = buildLoaderMap(blocks);
105
+ const context = internal.buildBlockContext(
106
+ locale,
107
+ defaultLocale,
108
+ enabledLocales,
109
+ isPreview,
110
+ forms
111
+ );
112
+ const resolved = await resolveBlocks(
113
+ page.blocks,
114
+ loaderMap,
115
+ locale,
116
+ defaultLocale,
117
+ context,
118
+ enabledLocales,
119
+ { schemas: blocksToSchemas(blocks), config }
120
+ );
121
+ return collectBlockData(page.blocks, resolved, isPreview);
122
+ }
123
+ async function resolveBlockData(options) {
124
+ return (await resolveEditorBlockData(options)).data;
125
+ }
126
+ async function resolveEditorLayoutBlockData({
127
+ groups,
128
+ blocks,
129
+ position,
130
+ locale,
131
+ defaultLocale,
132
+ enabledLocales,
133
+ forms,
134
+ isPreview = false,
135
+ config
136
+ }) {
137
+ const group = groups.find((g) => g.position === position);
138
+ const layoutBlocks = group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
139
+ if (layoutBlocks.length === 0) return { data: {}, content: {} };
140
+ const loaderMap = buildLoaderMap(blocks);
141
+ const context = internal.buildBlockContext(
142
+ locale,
143
+ defaultLocale,
144
+ enabledLocales,
145
+ isPreview,
146
+ forms
147
+ );
148
+ const resolved = await resolveBlocks(
149
+ layoutBlocks,
150
+ loaderMap,
151
+ locale,
152
+ defaultLocale,
153
+ context,
154
+ enabledLocales,
155
+ { schemas: blocksToSchemas(blocks), config }
156
+ );
157
+ return collectBlockData(layoutBlocks, resolved, isPreview);
158
+ }
159
+ async function resolveLayoutBlockData(options) {
160
+ return (await resolveEditorLayoutBlockData(options)).data;
161
+ }
162
+
163
+ exports.resolveBlockData = resolveBlockData;
164
+ exports.resolveEditorBlockData = resolveEditorBlockData;
165
+ exports.resolveEditorLayoutBlockData = resolveEditorLayoutBlockData;
166
+ exports.resolveLayoutBlockData = resolveLayoutBlockData;
@@ -0,0 +1,37 @@
1
+ import { CmssyPageData, CmssyFormDefinition, CmssyClientConfig, CmssyLayoutGroup } from '@cmssy/core';
2
+ import { B as BlockDefinition } from './registry-zeNh3t6y.cjs';
3
+ import 'react';
4
+
5
+ interface EditorBlockData {
6
+ data: Record<string, unknown>;
7
+ content: Record<string, Record<string, unknown>>;
8
+ }
9
+ interface ResolveBlockDataOptions {
10
+ page: CmssyPageData | null;
11
+ blocks: BlockDefinition[];
12
+ locale: string;
13
+ defaultLocale: string;
14
+ enabledLocales?: string[];
15
+ forms?: Record<string, CmssyFormDefinition>;
16
+ isPreview?: boolean;
17
+ /** Workspace the relation records are read from. No config, no resolution. */
18
+ config?: CmssyClientConfig;
19
+ }
20
+ declare function resolveEditorBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<EditorBlockData>;
21
+ declare function resolveBlockData(options: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
22
+ interface ResolveLayoutBlockDataOptions {
23
+ groups: CmssyLayoutGroup[];
24
+ blocks: BlockDefinition[];
25
+ position: string;
26
+ locale: string;
27
+ defaultLocale: string;
28
+ enabledLocales?: string[];
29
+ forms?: Record<string, CmssyFormDefinition>;
30
+ isPreview?: boolean;
31
+ /** Workspace the relation records are read from. No config, no resolution. */
32
+ config?: CmssyClientConfig;
33
+ }
34
+ declare function resolveEditorLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<EditorBlockData>;
35
+ declare function resolveLayoutBlockData(options: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
36
+
37
+ export { type EditorBlockData, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
@@ -0,0 +1,37 @@
1
+ import { CmssyPageData, CmssyFormDefinition, CmssyClientConfig, CmssyLayoutGroup } from '@cmssy/core';
2
+ import { B as BlockDefinition } from './registry-zeNh3t6y.js';
3
+ import 'react';
4
+
5
+ interface EditorBlockData {
6
+ data: Record<string, unknown>;
7
+ content: Record<string, Record<string, unknown>>;
8
+ }
9
+ interface ResolveBlockDataOptions {
10
+ page: CmssyPageData | null;
11
+ blocks: BlockDefinition[];
12
+ locale: string;
13
+ defaultLocale: string;
14
+ enabledLocales?: string[];
15
+ forms?: Record<string, CmssyFormDefinition>;
16
+ isPreview?: boolean;
17
+ /** Workspace the relation records are read from. No config, no resolution. */
18
+ config?: CmssyClientConfig;
19
+ }
20
+ declare function resolveEditorBlockData({ page, blocks, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveBlockDataOptions): Promise<EditorBlockData>;
21
+ declare function resolveBlockData(options: ResolveBlockDataOptions): Promise<Record<string, unknown>>;
22
+ interface ResolveLayoutBlockDataOptions {
23
+ groups: CmssyLayoutGroup[];
24
+ blocks: BlockDefinition[];
25
+ position: string;
26
+ locale: string;
27
+ defaultLocale: string;
28
+ enabledLocales?: string[];
29
+ forms?: Record<string, CmssyFormDefinition>;
30
+ isPreview?: boolean;
31
+ /** Workspace the relation records are read from. No config, no resolution. */
32
+ config?: CmssyClientConfig;
33
+ }
34
+ declare function resolveEditorLayoutBlockData({ groups, blocks, position, locale, defaultLocale, enabledLocales, forms, isPreview, config, }: ResolveLayoutBlockDataOptions): Promise<EditorBlockData>;
35
+ declare function resolveLayoutBlockData(options: ResolveLayoutBlockDataOptions): Promise<Record<string, unknown>>;
36
+
37
+ export { type EditorBlockData, type ResolveBlockDataOptions, type ResolveLayoutBlockDataOptions, resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
@@ -0,0 +1,161 @@
1
+ import { buildBlockContext, getBlockContentForLanguage, resolveRelationContent } from '@cmssy/core/internal';
2
+
3
+ // src/components/resolve-block-data.ts
4
+
5
+ // src/registry.ts
6
+ function buildLoaderMap(blocks) {
7
+ const map = /* @__PURE__ */ Object.create(null);
8
+ for (const block of blocks) {
9
+ if (block.loader) map[block.type] = block.loader;
10
+ }
11
+ return map;
12
+ }
13
+ function blocksToSchemas(blocks) {
14
+ const out = /* @__PURE__ */ Object.create(null);
15
+ for (const block of blocks) {
16
+ const schema = {};
17
+ for (const [key, def] of Object.entries(block.props)) {
18
+ schema[key] = { ...def, label: def.label || key };
19
+ }
20
+ out[block.type] = schema;
21
+ }
22
+ return out;
23
+ }
24
+
25
+ // src/components/block-error.ts
26
+ var BLOCK_ERROR_KEY = "__cmssyBlockError";
27
+ function blockErrorMessage(err) {
28
+ return err instanceof Error ? err.message : String(err);
29
+ }
30
+ function markBlockError(error) {
31
+ return { [BLOCK_ERROR_KEY]: error };
32
+ }
33
+ async function resolveBlocks(blocks, loaderMap, locale, defaultLocale, context, enabledLocales, options) {
34
+ const contents = blocks.map(
35
+ (block) => getBlockContentForLanguage(
36
+ block.content,
37
+ locale,
38
+ defaultLocale,
39
+ enabledLocales?.length ? enabledLocales : void 0
40
+ )
41
+ );
42
+ if (options?.config && options.schemas) {
43
+ await resolveRelationContent(
44
+ options.config,
45
+ blocks.map((block, i) => ({ type: block.type, content: contents[i] })),
46
+ options.schemas,
47
+ locale,
48
+ options.workspaceId ? { workspaceId: options.workspaceId } : {}
49
+ );
50
+ }
51
+ return Promise.all(
52
+ blocks.map(async (block, i) => {
53
+ const content = contents[i];
54
+ const loader = loaderMap[block.type];
55
+ let data;
56
+ let error;
57
+ if (loader) {
58
+ try {
59
+ data = await loader({ content, context });
60
+ } catch (err) {
61
+ if (typeof console !== "undefined") {
62
+ console.error(
63
+ `[cmssy] loader for block "${block.type}" (${block.id}) failed`,
64
+ err
65
+ );
66
+ }
67
+ error = { message: blockErrorMessage(err), source: "loader" };
68
+ }
69
+ }
70
+ return { content, data, error };
71
+ })
72
+ );
73
+ }
74
+
75
+ // src/components/resolve-block-data.ts
76
+ function collectBlockData(blocks, resolved, isPreview) {
77
+ const data = {};
78
+ const content = {};
79
+ blocks.forEach((block, index) => {
80
+ const entry = resolved[index];
81
+ if (!entry) return;
82
+ content[block.id] = entry.content;
83
+ if (entry.error && isPreview) {
84
+ data[block.id] = markBlockError(entry.error);
85
+ } else if (entry.data !== void 0) {
86
+ data[block.id] = entry.data;
87
+ }
88
+ });
89
+ return { data, content };
90
+ }
91
+ async function resolveEditorBlockData({
92
+ page,
93
+ blocks,
94
+ locale,
95
+ defaultLocale,
96
+ enabledLocales,
97
+ forms,
98
+ isPreview = false,
99
+ config
100
+ }) {
101
+ if (!page) return { data: {}, content: {} };
102
+ const loaderMap = buildLoaderMap(blocks);
103
+ const context = buildBlockContext(
104
+ locale,
105
+ defaultLocale,
106
+ enabledLocales,
107
+ isPreview,
108
+ forms
109
+ );
110
+ const resolved = await resolveBlocks(
111
+ page.blocks,
112
+ loaderMap,
113
+ locale,
114
+ defaultLocale,
115
+ context,
116
+ enabledLocales,
117
+ { schemas: blocksToSchemas(blocks), config }
118
+ );
119
+ return collectBlockData(page.blocks, resolved, isPreview);
120
+ }
121
+ async function resolveBlockData(options) {
122
+ return (await resolveEditorBlockData(options)).data;
123
+ }
124
+ async function resolveEditorLayoutBlockData({
125
+ groups,
126
+ blocks,
127
+ position,
128
+ locale,
129
+ defaultLocale,
130
+ enabledLocales,
131
+ forms,
132
+ isPreview = false,
133
+ config
134
+ }) {
135
+ const group = groups.find((g) => g.position === position);
136
+ const layoutBlocks = group ? group.blocks.filter((b) => b.isActive).slice().sort((a, b) => a.order - b.order) : [];
137
+ if (layoutBlocks.length === 0) return { data: {}, content: {} };
138
+ const loaderMap = buildLoaderMap(blocks);
139
+ const context = buildBlockContext(
140
+ locale,
141
+ defaultLocale,
142
+ enabledLocales,
143
+ isPreview,
144
+ forms
145
+ );
146
+ const resolved = await resolveBlocks(
147
+ layoutBlocks,
148
+ loaderMap,
149
+ locale,
150
+ defaultLocale,
151
+ context,
152
+ enabledLocales,
153
+ { schemas: blocksToSchemas(blocks), config }
154
+ );
155
+ return collectBlockData(layoutBlocks, resolved, isPreview);
156
+ }
157
+ async function resolveLayoutBlockData(options) {
158
+ return (await resolveEditorLayoutBlockData(options)).data;
159
+ }
160
+
161
+ export { resolveBlockData, resolveEditorBlockData, resolveEditorLayoutBlockData, resolveLayoutBlockData };
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ var LocaleContext = react.createContext(null);
8
+ function CmssyLocaleProvider({
9
+ value,
10
+ children
11
+ }) {
12
+ return /* @__PURE__ */ jsxRuntime.jsx(LocaleContext.Provider, { value, children });
13
+ }
14
+ function useCmssyLocale() {
15
+ return react.useContext(LocaleContext);
16
+ }
17
+
18
+ exports.CmssyLocaleProvider = CmssyLocaleProvider;
19
+ exports.useCmssyLocale = useCmssyLocale;
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { CmssyLocaleContext } from '@cmssy/core';
4
+
5
+ interface CmssyLocaleProviderProps {
6
+ value: CmssyLocaleContext;
7
+ children: ReactNode;
8
+ }
9
+ /**
10
+ * Exposes the active locale ({@link CmssyLocaleContext}) to client components
11
+ * below it (e.g. `CmssyLink`) so they can build locale-aware hrefs without
12
+ * prop-drilling. Wrap your root layout body with it.
13
+ */
14
+ declare function CmssyLocaleProvider({ value, children, }: CmssyLocaleProviderProps): react_jsx_runtime.JSX.Element;
15
+ /** Reads the active locale; returns null when no provider is mounted. */
16
+ declare function useCmssyLocale(): CmssyLocaleContext | null;
17
+
18
+ export { CmssyLocaleProvider, type CmssyLocaleProviderProps, useCmssyLocale };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { CmssyLocaleContext } from '@cmssy/core';
4
+
5
+ interface CmssyLocaleProviderProps {
6
+ value: CmssyLocaleContext;
7
+ children: ReactNode;
8
+ }
9
+ /**
10
+ * Exposes the active locale ({@link CmssyLocaleContext}) to client components
11
+ * below it (e.g. `CmssyLink`) so they can build locale-aware hrefs without
12
+ * prop-drilling. Wrap your root layout body with it.
13
+ */
14
+ declare function CmssyLocaleProvider({ value, children, }: CmssyLocaleProviderProps): react_jsx_runtime.JSX.Element;
15
+ /** Reads the active locale; returns null when no provider is mounted. */
16
+ declare function useCmssyLocale(): CmssyLocaleContext | null;
17
+
18
+ export { CmssyLocaleProvider, type CmssyLocaleProviderProps, useCmssyLocale };
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { createContext, useContext } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ var LocaleContext = createContext(null);
6
+ function CmssyLocaleProvider({
7
+ value,
8
+ children
9
+ }) {
10
+ return /* @__PURE__ */ jsx(LocaleContext.Provider, { value, children });
11
+ }
12
+ function useCmssyLocale() {
13
+ return useContext(LocaleContext);
14
+ }
15
+
16
+ export { CmssyLocaleProvider, useCmssyLocale };
@@ -1,5 +1,5 @@
1
1
  import { ComponentType } from 'react';
2
- import { FieldDefinition, CmssyBlockContext, BlockPropsSchema, InferBlockContent, BlockMeta, BlockSchema } from '@cmssy/core';
2
+ import { FieldDefinition, CmssyBlockContext, BlockPropsSchema, InferBlockContent } from '@cmssy/core';
3
3
 
4
4
  /**
5
5
  * The props a block component receives, derived from the fields it declares:
@@ -99,9 +99,5 @@ type BlockMap = Record<string, ComponentType<{
99
99
  data?: unknown;
100
100
  }>>;
101
101
  declare function buildBlockMap(blocks: BlockDefinition[]): BlockMap;
102
- declare function blocksToSchemas(blocks: BlockDefinition[]): Record<string, BlockSchema>;
103
- declare function blocksToMeta(blocks: BlockDefinition[], defaults?: {
104
- category?: string;
105
- }): Record<string, BlockMeta>;
106
102
 
107
- export { type BlockDefinition as B, type BlockMap as a, type BlockProps as b, blocksToMeta as c, blocksToSchemas as d, buildBlockMap as e, defineBlock as f };
103
+ export { type BlockDefinition as B, type BlockMap as a, type BlockProps as b, buildBlockMap as c, defineBlock as d };
@@ -1,5 +1,5 @@
1
1
  import { ComponentType } from 'react';
2
- import { FieldDefinition, CmssyBlockContext, BlockPropsSchema, InferBlockContent, BlockMeta, BlockSchema } from '@cmssy/core';
2
+ import { FieldDefinition, CmssyBlockContext, BlockPropsSchema, InferBlockContent } from '@cmssy/core';
3
3
 
4
4
  /**
5
5
  * The props a block component receives, derived from the fields it declares:
@@ -99,9 +99,5 @@ type BlockMap = Record<string, ComponentType<{
99
99
  data?: unknown;
100
100
  }>>;
101
101
  declare function buildBlockMap(blocks: BlockDefinition[]): BlockMap;
102
- declare function blocksToSchemas(blocks: BlockDefinition[]): Record<string, BlockSchema>;
103
- declare function blocksToMeta(blocks: BlockDefinition[], defaults?: {
104
- category?: string;
105
- }): Record<string, BlockMeta>;
106
102
 
107
- export { type BlockDefinition as B, type BlockMap as a, type BlockProps as b, blocksToMeta as c, blocksToSchemas as d, buildBlockMap as e, defineBlock as f };
103
+ export { type BlockDefinition as B, type BlockMap as a, type BlockProps as b, buildBlockMap as c, defineBlock as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "9.10.0",
3
+ "version": "10.1.0",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -33,6 +33,16 @@
33
33
  "import": "./dist/client.js",
34
34
  "require": "./dist/client.cjs"
35
35
  },
36
+ "./internal": {
37
+ "types": "./dist/internal.d.ts",
38
+ "import": "./dist/internal.js",
39
+ "require": "./dist/internal.cjs"
40
+ },
41
+ "./internal-server": {
42
+ "types": "./dist/internal-server.d.ts",
43
+ "import": "./dist/internal-server.js",
44
+ "require": "./dist/internal-server.cjs"
45
+ },
36
46
  "./block-error-boundary": {
37
47
  "types": "./dist/block-error-boundary.d.ts",
38
48
  "import": "./dist/block-error-boundary.js",
@@ -62,7 +72,7 @@
62
72
  },
63
73
  "dependencies": {
64
74
  "@cmssy/types": "0.29.0",
65
- "@cmssy/core": "9.10.0"
75
+ "@cmssy/core": "10.1.0"
66
76
  },
67
77
  "scripts": {
68
78
  "build": "tsup",