@makeswift/runtime 0.28.9 → 0.28.10-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api/graphql-api-client.js +1 -1
- package/dist/cjs/api/rest-api-client.js +1 -1
- package/dist/cjs/api-handler/handlers/manifest.js +1 -1
- package/dist/cjs/next/components/tests/controls/page-control-prop-rendering.js +24 -2
- package/dist/cjs/next/components/tests/controls/page-control-prop-rendering.js.map +1 -1
- package/dist/cjs/react/server/index.js +45 -0
- package/dist/cjs/react/server/index.js.map +1 -0
- package/dist/cjs/runtimes/react/components/ElementData.js +41 -8
- package/dist/cjs/runtimes/react/components/ElementData.js.map +1 -1
- package/dist/cjs/runtimes/react/components/framework-context.js.map +1 -1
- package/dist/cjs/runtimes/react/controls/rich-text/EditableText/editable-text.js +3 -1
- package/dist/cjs/runtimes/react/controls/rich-text/EditableText/editable-text.js.map +1 -1
- package/dist/cjs/runtimes/react/controls/rich-text-v2/EditableTextV2/editable-text-v2.js +3 -0
- package/dist/cjs/runtimes/react/controls/rich-text-v2/EditableTextV2/editable-text-v2.js.map +1 -1
- package/dist/cjs/runtimes/react/controls/use-slate-reset.js +37 -0
- package/dist/cjs/runtimes/react/controls/use-slate-reset.js.map +1 -0
- package/dist/cjs/runtimes/react/hooks/use-editable-element-stylesheet-factory.js +58 -0
- package/dist/cjs/runtimes/react/hooks/use-editable-element-stylesheet-factory.js.map +1 -0
- package/dist/cjs/runtimes/react/hooks/use-element-data.js +35 -0
- package/dist/cjs/runtimes/react/hooks/use-element-data.js.map +1 -0
- package/dist/cjs/runtimes/react/hooks/use-element.js +40 -0
- package/dist/cjs/runtimes/react/hooks/use-element.js.map +1 -0
- package/dist/cjs/runtimes/react/hooks/use-resolved-props.js.map +1 -1
- package/dist/cjs/runtimes/react/hooks/use-server-element-refresh.js +90 -0
- package/dist/cjs/runtimes/react/hooks/use-server-element-refresh.js.map +1 -0
- package/dist/cjs/runtimes/react/react-runtime-core.js +22 -4
- package/dist/cjs/runtimes/react/react-runtime-core.js.map +1 -1
- package/dist/cjs/runtimes/react/resource-resolver.js.map +1 -1
- package/dist/cjs/runtimes/react/server/collect-server-elements.js +74 -0
- package/dist/cjs/runtimes/react/server/collect-server-elements.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/editable-server-element.js +173 -0
- package/dist/cjs/runtimes/react/server/components/editable-server-element.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/element-data.js +76 -0
- package/dist/cjs/runtimes/react/server/components/element-data.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/element.js +59 -0
- package/dist/cjs/runtimes/react/server/components/element.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/makeswift-component.js +32 -0
- package/dist/cjs/runtimes/react/server/components/makeswift-component.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/renderer.js +54 -0
- package/dist/cjs/runtimes/react/server/components/renderer.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/server-elements-cache.js +70 -0
- package/dist/cjs/runtimes/react/server/components/server-elements-cache.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/slot.js +33 -0
- package/dist/cjs/runtimes/react/server/components/slot.js.map +1 -0
- package/dist/cjs/runtimes/react/server/components/snapshot-renderer.js +50 -0
- package/dist/cjs/runtimes/react/server/components/snapshot-renderer.js.map +1 -0
- package/dist/cjs/runtimes/react/server/css/client-css.js +112 -0
- package/dist/cjs/runtimes/react/server/css/client-css.js.map +1 -0
- package/dist/cjs/runtimes/react/server/css/css-runtime.js +102 -0
- package/dist/cjs/runtimes/react/server/css/css-runtime.js.map +1 -0
- package/dist/cjs/runtimes/react/server/css/server-css.js +71 -0
- package/dist/cjs/runtimes/react/server/css/server-css.js.map +1 -0
- package/dist/cjs/runtimes/react/server/index.js +51 -0
- package/dist/cjs/runtimes/react/server/index.js.map +1 -0
- package/dist/cjs/runtimes/react/server/render-context.js +58 -0
- package/dist/cjs/runtimes/react/server/render-context.js.map +1 -0
- package/dist/cjs/runtimes/react/server/render-element-payload.js +45 -0
- package/dist/cjs/runtimes/react/server/render-element-payload.js.map +1 -0
- package/dist/cjs/runtimes/react/server/resolve-props.js +58 -0
- package/dist/cjs/runtimes/react/server/resolve-props.js.map +1 -0
- package/dist/cjs/runtimes/react/server/resource-resolver.js +40 -0
- package/dist/cjs/runtimes/react/server/resource-resolver.js.map +1 -0
- package/dist/cjs/runtimes/react/server/update-api-resource-cache.js +32 -0
- package/dist/cjs/runtimes/react/server/update-api-resource-cache.js.map +1 -0
- package/dist/cjs/runtimes/react/testing/react-runtime.js +19 -2
- package/dist/cjs/runtimes/react/testing/react-runtime.js.map +1 -1
- package/dist/cjs/state/modules/components-meta.js.map +1 -1
- package/dist/cjs/unstable-framework-support/index.js +3 -0
- package/dist/cjs/unstable-framework-support/index.js.map +1 -1
- package/dist/cjs/utils/prop-by-path.js +35 -0
- package/dist/cjs/utils/prop-by-path.js.map +1 -0
- package/dist/cjs/utils/set.js +32 -0
- package/dist/cjs/utils/set.js.map +1 -0
- package/dist/esm/api/graphql-api-client.js +1 -1
- package/dist/esm/api/rest-api-client.js +1 -1
- package/dist/esm/api-handler/handlers/manifest.js +1 -1
- package/dist/esm/next/components/tests/controls/page-control-prop-rendering.js +24 -2
- package/dist/esm/next/components/tests/controls/page-control-prop-rendering.js.map +1 -1
- package/dist/esm/react/server/index.js +23 -0
- package/dist/esm/react/server/index.js.map +1 -0
- package/dist/esm/runtimes/react/components/ElementData.js +42 -9
- package/dist/esm/runtimes/react/components/ElementData.js.map +1 -1
- package/dist/esm/runtimes/react/components/framework-context.js.map +1 -1
- package/dist/esm/runtimes/react/controls/rich-text/EditableText/editable-text.js +3 -1
- package/dist/esm/runtimes/react/controls/rich-text/EditableText/editable-text.js.map +1 -1
- package/dist/esm/runtimes/react/controls/rich-text-v2/EditableTextV2/editable-text-v2.js +3 -0
- package/dist/esm/runtimes/react/controls/rich-text-v2/EditableTextV2/editable-text-v2.js.map +1 -1
- package/dist/esm/runtimes/react/controls/use-slate-reset.js +13 -0
- package/dist/esm/runtimes/react/controls/use-slate-reset.js.map +1 -0
- package/dist/esm/runtimes/react/hooks/use-editable-element-stylesheet-factory.js +34 -0
- package/dist/esm/runtimes/react/hooks/use-editable-element-stylesheet-factory.js.map +1 -0
- package/dist/esm/runtimes/react/hooks/use-element-data.js +11 -0
- package/dist/esm/runtimes/react/hooks/use-element-data.js.map +1 -0
- package/dist/esm/runtimes/react/hooks/use-element.js +16 -0
- package/dist/esm/runtimes/react/hooks/use-element.js.map +1 -0
- package/dist/esm/runtimes/react/hooks/use-resolved-props.js.map +1 -1
- package/dist/esm/runtimes/react/hooks/use-server-element-refresh.js +66 -0
- package/dist/esm/runtimes/react/hooks/use-server-element-refresh.js.map +1 -0
- package/dist/esm/runtimes/react/react-runtime-core.js +22 -4
- package/dist/esm/runtimes/react/react-runtime-core.js.map +1 -1
- package/dist/esm/runtimes/react/resource-resolver.js.map +1 -1
- package/dist/esm/runtimes/react/server/collect-server-elements.js +50 -0
- package/dist/esm/runtimes/react/server/collect-server-elements.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/editable-server-element.js +152 -0
- package/dist/esm/runtimes/react/server/components/editable-server-element.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/element-data.js +60 -0
- package/dist/esm/runtimes/react/server/components/element-data.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/element.js +38 -0
- package/dist/esm/runtimes/react/server/components/element.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/makeswift-component.js +8 -0
- package/dist/esm/runtimes/react/server/components/makeswift-component.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/renderer.js +29 -0
- package/dist/esm/runtimes/react/server/components/renderer.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/server-elements-cache.js +45 -0
- package/dist/esm/runtimes/react/server/components/server-elements-cache.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/slot.js +9 -0
- package/dist/esm/runtimes/react/server/components/slot.js.map +1 -0
- package/dist/esm/runtimes/react/server/components/snapshot-renderer.js +26 -0
- package/dist/esm/runtimes/react/server/components/snapshot-renderer.js.map +1 -0
- package/dist/esm/runtimes/react/server/css/client-css.js +87 -0
- package/dist/esm/runtimes/react/server/css/client-css.js.map +1 -0
- package/dist/esm/runtimes/react/server/css/css-runtime.js +77 -0
- package/dist/esm/runtimes/react/server/css/css-runtime.js.map +1 -0
- package/dist/esm/runtimes/react/server/css/server-css.js +45 -0
- package/dist/esm/runtimes/react/server/css/server-css.js.map +1 -0
- package/dist/esm/runtimes/react/server/index.js +23 -0
- package/dist/esm/runtimes/react/server/index.js.map +1 -0
- package/dist/esm/runtimes/react/server/render-context.js +31 -0
- package/dist/esm/runtimes/react/server/render-context.js.map +1 -0
- package/dist/esm/runtimes/react/server/render-element-payload.js +21 -0
- package/dist/esm/runtimes/react/server/render-element-payload.js.map +1 -0
- package/dist/esm/runtimes/react/server/resolve-props.js +34 -0
- package/dist/esm/runtimes/react/server/resolve-props.js.map +1 -0
- package/dist/esm/runtimes/react/server/resource-resolver.js +16 -0
- package/dist/esm/runtimes/react/server/resource-resolver.js.map +1 -0
- package/dist/esm/runtimes/react/server/update-api-resource-cache.js +8 -0
- package/dist/esm/runtimes/react/server/update-api-resource-cache.js.map +1 -0
- package/dist/esm/runtimes/react/testing/react-runtime.js +19 -2
- package/dist/esm/runtimes/react/testing/react-runtime.js.map +1 -1
- package/dist/esm/state/modules/components-meta.js.map +1 -1
- package/dist/esm/unstable-framework-support/index.js +2 -0
- package/dist/esm/unstable-framework-support/index.js.map +1 -1
- package/dist/esm/utils/prop-by-path.js +10 -0
- package/dist/esm/utils/prop-by-path.js.map +1 -0
- package/dist/esm/utils/set.js +7 -0
- package/dist/esm/utils/set.js.map +1 -0
- package/dist/types/next/components/tests/controls/page-control-prop-rendering.d.ts +2 -1
- package/dist/types/next/components/tests/controls/page-control-prop-rendering.d.ts.map +1 -1
- package/dist/types/react/server/index.d.ts +2 -0
- package/dist/types/react/server/index.d.ts.map +1 -0
- package/dist/types/runtimes/react/components/ElementData.d.ts +2 -2
- package/dist/types/runtimes/react/components/ElementData.d.ts.map +1 -1
- package/dist/types/runtimes/react/components/framework-context.d.ts +6 -1
- package/dist/types/runtimes/react/components/framework-context.d.ts.map +1 -1
- package/dist/types/runtimes/react/controls/rich-text/EditableText/editable-text.d.ts.map +1 -1
- package/dist/types/runtimes/react/controls/rich-text-v2/EditableTextV2/editable-text-v2.d.ts.map +1 -1
- package/dist/types/runtimes/react/controls/use-slate-reset.d.ts +35 -0
- package/dist/types/runtimes/react/controls/use-slate-reset.d.ts.map +1 -0
- package/dist/types/runtimes/react/hooks/__tests__/use-server-element-refresh.test.d.ts +3 -0
- package/dist/types/runtimes/react/hooks/__tests__/use-server-element-refresh.test.d.ts.map +1 -0
- package/dist/types/runtimes/react/hooks/use-editable-element-stylesheet-factory.d.ts +5 -0
- package/dist/types/runtimes/react/hooks/use-editable-element-stylesheet-factory.d.ts.map +1 -0
- package/dist/types/runtimes/react/hooks/use-element-data.d.ts +5 -0
- package/dist/types/runtimes/react/hooks/use-element-data.d.ts.map +1 -0
- package/dist/types/runtimes/react/hooks/use-element.d.ts +5 -0
- package/dist/types/runtimes/react/hooks/use-element.d.ts.map +1 -0
- package/dist/types/runtimes/react/hooks/use-resolved-props.d.ts +3 -0
- package/dist/types/runtimes/react/hooks/use-resolved-props.d.ts.map +1 -1
- package/dist/types/runtimes/react/hooks/use-server-element-refresh.d.ts +14 -0
- package/dist/types/runtimes/react/hooks/use-server-element-refresh.d.ts.map +1 -0
- package/dist/types/runtimes/react/react-runtime-core.d.ts +3 -1
- package/dist/types/runtimes/react/react-runtime-core.d.ts.map +1 -1
- package/dist/types/runtimes/react/resource-resolver.d.ts +1 -0
- package/dist/types/runtimes/react/resource-resolver.d.ts.map +1 -1
- package/dist/types/runtimes/react/server/collect-server-elements.d.ts +19 -0
- package/dist/types/runtimes/react/server/collect-server-elements.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/__tests__/editable-server-element.test.d.ts +3 -0
- package/dist/types/runtimes/react/server/components/__tests__/editable-server-element.test.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/editable-server-element.d.ts +6 -0
- package/dist/types/runtimes/react/server/components/editable-server-element.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/element-data.d.ts +9 -0
- package/dist/types/runtimes/react/server/components/element-data.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/element.d.ts +9 -0
- package/dist/types/runtimes/react/server/components/element.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/makeswift-component.d.ts +8 -0
- package/dist/types/runtimes/react/server/components/makeswift-component.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/renderer.d.ts +23 -0
- package/dist/types/runtimes/react/server/components/renderer.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/server-elements-cache.d.ts +22 -0
- package/dist/types/runtimes/react/server/components/server-elements-cache.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/slot.d.ts +8 -0
- package/dist/types/runtimes/react/server/components/slot.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/components/snapshot-renderer.d.ts +10 -0
- package/dist/types/runtimes/react/server/components/snapshot-renderer.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/css/client-css.d.ts +10 -0
- package/dist/types/runtimes/react/server/css/client-css.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/css/css-runtime.d.ts +16 -0
- package/dist/types/runtimes/react/server/css/css-runtime.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/css/server-css.d.ts +14 -0
- package/dist/types/runtimes/react/server/css/server-css.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/index.d.ts +8 -0
- package/dist/types/runtimes/react/server/index.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/render-context.d.ts +28 -0
- package/dist/types/runtimes/react/server/render-context.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/render-element-payload.d.ts +215 -0
- package/dist/types/runtimes/react/server/render-element-payload.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/resolve-props.d.ts +7 -0
- package/dist/types/runtimes/react/server/resolve-props.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/resource-resolver.d.ts +6 -0
- package/dist/types/runtimes/react/server/resource-resolver.d.ts.map +1 -0
- package/dist/types/runtimes/react/server/update-api-resource-cache.d.ts +4 -0
- package/dist/types/runtimes/react/server/update-api-resource-cache.d.ts.map +1 -0
- package/dist/types/runtimes/react/testing/react-runtime.d.ts +12 -2
- package/dist/types/runtimes/react/testing/react-runtime.d.ts.map +1 -1
- package/dist/types/state/modules/components-meta.d.ts +1 -0
- package/dist/types/state/modules/components-meta.d.ts.map +1 -1
- package/dist/types/unstable-framework-support/index.d.ts +1 -0
- package/dist/types/unstable-framework-support/index.d.ts.map +1 -1
- package/dist/types/utils/__tests__/prop-by-path.test.d.ts +2 -0
- package/dist/types/utils/__tests__/prop-by-path.test.d.ts.map +1 -0
- package/dist/types/utils/prop-by-path.d.ts +3 -0
- package/dist/types/utils/prop-by-path.d.ts.map +1 -0
- package/dist/types/utils/set.d.ts +3 -0
- package/dist/types/utils/set.d.ts.map +1 -0
- package/package.json +8 -3
- package/react/server/package.json +5 -0
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
} from "../../state/actions/internal/read-only-actions";
|
|
6
6
|
import { ComponentIcon } from "../../state/modules/components-meta";
|
|
7
7
|
import { RuntimeCore } from "./runtime-core";
|
|
8
|
-
function validateComponentType(
|
|
9
|
-
|
|
8
|
+
function validateComponentType({
|
|
9
|
+
type,
|
|
10
|
+
componentName
|
|
11
|
+
}) {
|
|
10
12
|
if (typeof type !== "string" || type === "") {
|
|
11
13
|
throw new Error(
|
|
12
14
|
`${componentName}: A non-empty string \`type\` is required for component registration, got ${type}`
|
|
@@ -22,13 +24,21 @@ class ReactRuntimeCore extends RuntimeCore {
|
|
|
22
24
|
description,
|
|
23
25
|
builtinSuspense,
|
|
24
26
|
unstable_migration,
|
|
27
|
+
server = false,
|
|
25
28
|
props
|
|
26
29
|
}) {
|
|
27
|
-
validateComponentType(
|
|
30
|
+
validateComponentType(
|
|
31
|
+
// make sure we don't access `component?.name` and trigger loading of the server
|
|
32
|
+
// component unless we're running in the RSC environment
|
|
33
|
+
server && !this.isRSCEnv() ? { type, componentName: label || "Unknown server component" } : {
|
|
34
|
+
type,
|
|
35
|
+
componentName: component?.name || label || "Unknown component"
|
|
36
|
+
}
|
|
37
|
+
);
|
|
28
38
|
const unregisterComponent = this.protoStore.dispatch(
|
|
29
39
|
registerComponentEffect(
|
|
30
40
|
type,
|
|
31
|
-
{ label, icon, hidden, description, builtinSuspense, unstable_migration },
|
|
41
|
+
{ label, icon, hidden, description, builtinSuspense, unstable_migration, server },
|
|
32
42
|
props ?? {}
|
|
33
43
|
)
|
|
34
44
|
);
|
|
@@ -37,6 +47,11 @@ class ReactRuntimeCore extends RuntimeCore {
|
|
|
37
47
|
"builtinSuspense is ignored in React >= 19.2; components are always wrapped in <Activity>."
|
|
38
48
|
);
|
|
39
49
|
}
|
|
50
|
+
if (server && !this.isRSCEnv()) {
|
|
51
|
+
return () => {
|
|
52
|
+
unregisterComponent();
|
|
53
|
+
};
|
|
54
|
+
}
|
|
40
55
|
const unregisterReactComponent = this.protoStore.dispatch(
|
|
41
56
|
registerReactComponentEffect(type, component)
|
|
42
57
|
);
|
|
@@ -45,6 +60,9 @@ class ReactRuntimeCore extends RuntimeCore {
|
|
|
45
60
|
unregisterReactComponent();
|
|
46
61
|
};
|
|
47
62
|
}
|
|
63
|
+
isRSCEnv() {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
48
66
|
}
|
|
49
67
|
export {
|
|
50
68
|
ReactRuntimeCore
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/runtimes/react/react-runtime-core.ts"],"sourcesContent":["import { ControlDefinition as UnifiedControlDefinition } from '@makeswift/controls'\n\nimport { type LegacyDescriptor, type DescriptorValueType } from '../../prop-controllers/descriptors'\n\nimport { supportsActivity } from './components/activity-with-fallback'\n\nimport {\n registerComponentEffect,\n registerReactComponentEffect,\n} from '../../state/actions/internal/read-only-actions'\n\nimport { ComponentIcon } from '../../state/modules/components-meta'\nimport type { ComponentType } from '../../state/read-only-state'\n\nimport { RuntimeCore } from './runtime-core'\n\nfunction validateComponentType(type:
|
|
1
|
+
{"version":3,"sources":["../../../../src/runtimes/react/react-runtime-core.ts"],"sourcesContent":["import { ControlDefinition as UnifiedControlDefinition } from '@makeswift/controls'\n\nimport { type LegacyDescriptor, type DescriptorValueType } from '../../prop-controllers/descriptors'\n\nimport { supportsActivity } from './components/activity-with-fallback'\n\nimport {\n registerComponentEffect,\n registerReactComponentEffect,\n} from '../../state/actions/internal/read-only-actions'\n\nimport { ComponentIcon } from '../../state/modules/components-meta'\nimport type { ComponentType } from '../../state/read-only-state'\n\nimport { RuntimeCore } from './runtime-core'\n\nfunction validateComponentType({\n type,\n componentName,\n}: {\n type: string\n componentName: string\n}): void {\n if (typeof type !== 'string' || type === '') {\n throw new Error(\n `${componentName}: A non-empty string \\`type\\` is required for component registration, got ${type}`,\n )\n }\n}\n\nexport class ReactRuntimeCore extends RuntimeCore {\n registerComponent<\n ControlDef extends UnifiedControlDefinition,\n P extends Record<string, LegacyDescriptor | ControlDef>,\n C extends ComponentType<{ [K in keyof P]: DescriptorValueType<P[K]> }>,\n >(\n component: C,\n {\n type,\n label,\n icon = ComponentIcon.Cube,\n hidden = false,\n description,\n builtinSuspense,\n unstable_migration,\n server = false,\n props,\n }: {\n type: string\n label: string\n icon?: ComponentIcon\n hidden?: boolean\n description?: string\n /**\n * In React <= 19.1, controls the default `<Suspense>` boundary.\n * Ignored in React >= 19.2; components are always wrapped in `<Activity>`.\n * Defaults to `true`.\n */\n builtinSuspense?: boolean\n /**\n * Marks this registration as superseded by `replacementType`. When\n * `replacementType` differs from `type`, the builder offers a way to\n * update existing instances.\n */\n unstable_migration?: { replacementType: string }\n server?: boolean\n props?: P\n },\n ): () => void {\n validateComponentType(\n // make sure we don't access `component?.name` and trigger loading of the server\n // component unless we're running in the RSC environment\n server && !this.isRSCEnv()\n ? { type, componentName: label || 'Unknown server component' }\n : {\n type,\n componentName: component?.name || label || 'Unknown component',\n },\n )\n\n const unregisterComponent = this.protoStore.dispatch(\n registerComponentEffect(\n type,\n { label, icon, hidden, description, builtinSuspense, unstable_migration, server },\n props ?? {},\n ),\n )\n\n if (supportsActivity() && builtinSuspense !== undefined) {\n console.warn(\n 'builtinSuspense is ignored in React >= 19.2; components are always wrapped in <Activity>.',\n )\n }\n\n if (server && !this.isRSCEnv()) {\n // we can't load server components code outside of the RSC environment, but we also\n // don't need to: if everything is set up correctly, React has already rendered and\n // streamed the corresponding React elements to the client for us -- see\n // `ServerElementsCache` and `ElementDataServer`\n return () => {\n unregisterComponent()\n }\n }\n\n const unregisterReactComponent = this.protoStore.dispatch(\n registerReactComponentEffect(type, component as unknown as ComponentType),\n )\n\n return () => {\n unregisterComponent()\n unregisterReactComponent()\n }\n }\n\n protected isRSCEnv() {\n return false\n }\n}\n"],"mappings":"AAIA,SAAS,wBAAwB;AAEjC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,qBAAqB;AAG9B,SAAS,mBAAmB;AAE5B,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AACF,GAGS;AACP,MAAI,OAAO,SAAS,YAAY,SAAS,IAAI;AAC3C,UAAM,IAAI;AAAA,MACR,GAAG,aAAa,6EAA6E,IAAI;AAAA,IACnG;AAAA,EACF;AACF;AAEO,MAAM,yBAAyB,YAAY;AAAA,EAChD,kBAKE,WACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,OAAO,cAAc;AAAA,IACrB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,GAqBY;AACZ;AAAA;AAAA;AAAA,MAGE,UAAU,CAAC,KAAK,SAAS,IACrB,EAAE,MAAM,eAAe,SAAS,2BAA2B,IAC3D;AAAA,QACE;AAAA,QACA,eAAe,WAAW,QAAQ,SAAS;AAAA,MAC7C;AAAA,IACN;AAEA,UAAM,sBAAsB,KAAK,WAAW;AAAA,MAC1C;AAAA,QACE;AAAA,QACA,EAAE,OAAO,MAAM,QAAQ,aAAa,iBAAiB,oBAAoB,OAAO;AAAA,QAChF,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,iBAAiB,KAAK,oBAAoB,QAAW;AACvD,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,CAAC,KAAK,SAAS,GAAG;AAK9B,aAAO,MAAM;AACX,4BAAoB;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,2BAA2B,KAAK,WAAW;AAAA,MAC/C,6BAA6B,MAAM,SAAqC;AAAA,IAC1E;AAEA,WAAO,MAAM;AACX,0BAAoB;AACpB,+BAAyB;AAAA,IAC3B;AAAA,EACF;AAAA,EAEU,WAAW;AACnB,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/runtimes/react/resource-resolver.ts"],"sourcesContent":["import { type ResourceResolver } from '@makeswift/controls'\n\nimport { getElementId } from '../../state/read-only-state'\nimport { ApiResourcesClient } from '../../api/api-resources-client'\nimport { Store } from '../../state/store'\n\nexport const createResourceResolver = ({\n store,\n apiClient,\n documentKey,\n locale,\n}: {\n store: Store\n apiClient: ApiResourcesClient\n documentKey: string | null\n locale: string | null\n}): ResourceResolver => ({\n resolveSwatch: swatchId => apiClient.resolveSwatch(swatchId),\n resolveFile: fileId => apiClient.resolveFile(fileId),\n resolveTypography: typographyId => apiClient.resolveTypography(typographyId),\n resolvePagePathnameSlice: pageId => apiClient.resolvePagePathnameSlice({ pageId, locale }),\n resolveElementId: elementKey => {\n const read = () =>\n documentKey == null ? null : getElementId(store.getState(), documentKey, elementKey)\n\n let lastValue: string | null = null\n return {\n name: `element-id:${documentKey}:${elementKey}`,\n readStable: () => (lastValue = read()),\n subscribe: (onUpdate: () => void) =>\n store.subscribe(() => {\n if (read() !== lastValue) onUpdate()\n }),\n }\n },\n})\n"],"mappings":"AAEA,SAAS,oBAAoB;
|
|
1
|
+
{"version":3,"sources":["../../../../src/runtimes/react/resource-resolver.ts"],"sourcesContent":["import { type ResourceResolver } from '@makeswift/controls'\n\nimport { getElementId } from '../../state/read-only-state'\nimport { ApiResourcesClient } from '../../api/api-resources-client'\nimport { Store } from '../../state/store'\n\nexport { type ResourceResolver } from '@makeswift/controls'\n\nexport const createResourceResolver = ({\n store,\n apiClient,\n documentKey,\n locale,\n}: {\n store: Store\n apiClient: ApiResourcesClient\n documentKey: string | null\n locale: string | null\n}): ResourceResolver => ({\n resolveSwatch: swatchId => apiClient.resolveSwatch(swatchId),\n resolveFile: fileId => apiClient.resolveFile(fileId),\n resolveTypography: typographyId => apiClient.resolveTypography(typographyId),\n resolvePagePathnameSlice: pageId => apiClient.resolvePagePathnameSlice({ pageId, locale }),\n resolveElementId: elementKey => {\n const read = () =>\n documentKey == null ? null : getElementId(store.getState(), documentKey, elementKey)\n\n let lastValue: string | null = null\n return {\n name: `element-id:${documentKey}:${elementKey}`,\n readStable: () => (lastValue = read()),\n subscribe: (onUpdate: () => void) =>\n store.subscribe(() => {\n if (read() !== lastValue) onUpdate()\n }),\n }\n },\n})\n"],"mappings":"AAEA,SAAS,oBAAoB;AAMtB,MAAM,yBAAyB,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,OAKyB;AAAA,EACvB,eAAe,cAAY,UAAU,cAAc,QAAQ;AAAA,EAC3D,aAAa,YAAU,UAAU,YAAY,MAAM;AAAA,EACnD,mBAAmB,kBAAgB,UAAU,kBAAkB,YAAY;AAAA,EAC3E,0BAA0B,YAAU,UAAU,yBAAyB,EAAE,QAAQ,OAAO,CAAC;AAAA,EACzF,kBAAkB,gBAAc;AAC9B,UAAM,OAAO,MACX,eAAe,OAAO,OAAO,aAAa,MAAM,SAAS,GAAG,aAAa,UAAU;AAErF,QAAI,YAA2B;AAC/B,WAAO;AAAA,MACL,MAAM,cAAc,WAAW,IAAI,UAAU;AAAA,MAC7C,YAAY,MAAO,YAAY,KAAK;AAAA,MACpC,WAAW,CAAC,aACV,MAAM,UAAU,MAAM;AACpB,YAAI,KAAK,MAAM;AAAW,mBAAS;AAAA,MACrC,CAAC;AAAA,IACL;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { isElementReference } from "@makeswift/controls";
|
|
3
|
+
import { getComponentsMeta } from "../../../state/modules/components-meta";
|
|
4
|
+
import { traverseElementTree } from "../../../state/modules/element-trees";
|
|
5
|
+
import { registerDocument } from "../../../state/shared-api";
|
|
6
|
+
import { getPropControllerDescriptors } from "../../../state/read-only-state";
|
|
7
|
+
import { ServerElement } from "./components/element";
|
|
8
|
+
import { getStore } from "./render-context";
|
|
9
|
+
import { updateApiResourceCache } from "./update-api-resource-cache";
|
|
10
|
+
function collectServerElements(context, document, cacheData) {
|
|
11
|
+
const store = getStore(context);
|
|
12
|
+
updateApiResourceCache(store, cacheData);
|
|
13
|
+
store.dispatch(registerDocument(document));
|
|
14
|
+
const state = store.getState();
|
|
15
|
+
const descriptors = getPropControllerDescriptors(state);
|
|
16
|
+
const result = /* @__PURE__ */ new Map();
|
|
17
|
+
for (const element of traverseElementTree(document.rootElement, descriptors)) {
|
|
18
|
+
if (isElementReference(element)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const meta = getComponentsMeta(state.componentsMeta).get(element.type);
|
|
22
|
+
if (meta == null) {
|
|
23
|
+
console.warn(`collectServerElements: Component meta not found for ${element.type}`);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (result.has(element.key)) {
|
|
27
|
+
console.warn(`collectServerElements: RSC node already exists for ${element.key}`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (meta.server) {
|
|
31
|
+
result.set(
|
|
32
|
+
element.key,
|
|
33
|
+
/* @__PURE__ */ jsx(
|
|
34
|
+
ServerElement,
|
|
35
|
+
{
|
|
36
|
+
context,
|
|
37
|
+
element,
|
|
38
|
+
documentKey: document.key
|
|
39
|
+
},
|
|
40
|
+
element.key
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
collectServerElements
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=collect-server-elements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/runtimes/react/server/collect-server-elements.tsx"],"sourcesContent":["import { type ReactNode } from 'react'\n\nimport { isElementReference } from '@makeswift/controls'\n\nimport { type CacheData } from '../../../api/api-resources-client'\n\nimport { type Document } from '../../../state/modules/read-only-documents'\nimport { getComponentsMeta } from '../../../state/modules/components-meta'\nimport { traverseElementTree } from '../../../state/modules/element-trees'\nimport { registerDocument } from '../../../state/shared-api'\nimport { getPropControllerDescriptors } from '../../../state/read-only-state'\n\nimport { ServerElement } from './components/element'\n\nimport { type ServerRenderContext, getStore } from './render-context'\nimport { updateApiResourceCache } from './update-api-resource-cache'\n\nexport type ElementsMap = Map<string, ReactNode>\n\n/**\n * Collects React nodes for document's server elements into a map keyed by\n * element key.\n *\n * Note that this function only *creates* React elements and associates them\n * with the corresponding Makeswift elements; it does not render anything.\n *\n * The actual render happens when React's server renderer walks the React tree\n * and hits the 'use client' boundary at `<ServerElementsCache />`, at which\n * point it needs to serialize the `value` prop into the flight stream and thus\n * execute `ServerElement` rendering code for each entry in the map.\n */\nexport function collectServerElements(\n context: ServerRenderContext,\n document: Document,\n cacheData: CacheData,\n): ElementsMap {\n const store = getStore(context)\n updateApiResourceCache(store, cacheData)\n\n store.dispatch(registerDocument(document))\n\n const state = store.getState()\n const descriptors = getPropControllerDescriptors(state)\n\n const result: ElementsMap = new Map()\n\n for (const element of traverseElementTree(document.rootElement, descriptors)) {\n if (isElementReference(element)) {\n // TODO: Element reference support\n continue\n }\n\n const meta = getComponentsMeta(state.componentsMeta).get(element.type)\n\n if (meta == null) {\n console.warn(`collectServerElements: Component meta not found for ${element.type}`)\n continue\n }\n\n if (result.has(element.key)) {\n console.warn(`collectServerElements: RSC node already exists for ${element.key}`)\n continue\n }\n\n if (meta.server) {\n result.set(\n element.key,\n <ServerElement\n key={element.key}\n context={context}\n element={element}\n documentKey={document.key}\n />,\n )\n }\n }\n\n return result\n}\n"],"mappings":"AAmEQ;AAjER,SAAS,0BAA0B;AAKnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,oCAAoC;AAE7C,SAAS,qBAAqB;AAE9B,SAAmC,gBAAgB;AACnD,SAAS,8BAA8B;AAgBhC,SAAS,sBACd,SACA,UACA,WACa;AACb,QAAM,QAAQ,SAAS,OAAO;AAC9B,yBAAuB,OAAO,SAAS;AAEvC,QAAM,SAAS,iBAAiB,QAAQ,CAAC;AAEzC,QAAM,QAAQ,MAAM,SAAS;AAC7B,QAAM,cAAc,6BAA6B,KAAK;AAEtD,QAAM,SAAsB,oBAAI,IAAI;AAEpC,aAAW,WAAW,oBAAoB,SAAS,aAAa,WAAW,GAAG;AAC5E,QAAI,mBAAmB,OAAO,GAAG;AAE/B;AAAA,IACF;AAEA,UAAM,OAAO,kBAAkB,MAAM,cAAc,EAAE,IAAI,QAAQ,IAAI;AAErE,QAAI,QAAQ,MAAM;AAChB,cAAQ,KAAK,uDAAuD,QAAQ,IAAI,EAAE;AAClF;AAAA,IACF;AAEA,QAAI,OAAO,IAAI,QAAQ,GAAG,GAAG;AAC3B,cAAQ,KAAK,sDAAsD,QAAQ,GAAG,EAAE;AAChF;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ;AACf,aAAO;AAAA,QACL,QAAQ;AAAA,QACR;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA;AAAA,YACA,aAAa,SAAS;AAAA;AAAA,UAHjB,QAAQ;AAAA,QAIf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, startTransition, useCallback } from "react";
|
|
4
|
+
import {
|
|
5
|
+
setResolvedValueOverride,
|
|
6
|
+
clearResolvedValueOverride
|
|
7
|
+
} from "../../../../state/actions/internal/read-write-actions";
|
|
8
|
+
import { useServerElementRefresh } from "../../hooks/use-server-element-refresh";
|
|
9
|
+
import { useElementData } from "../../hooks/use-element-data";
|
|
10
|
+
import { useControlDefs } from "../../hooks/use-control-defs";
|
|
11
|
+
import { useEditableElementStylesheetFactory } from "../../hooks/use-editable-element-stylesheet-factory";
|
|
12
|
+
import { useResolvedProps } from "../../hooks/use-resolved-props";
|
|
13
|
+
import { useControlInstances } from "../../components/control-instances-context";
|
|
14
|
+
import { useDispatch } from "../../hooks/use-dispatch";
|
|
15
|
+
import { useDocumentKey } from "../../hooks/use-document-context";
|
|
16
|
+
import { getProp } from "../../../../utils/prop-by-path";
|
|
17
|
+
import { setUnion, setDifference } from "../../../../utils/set";
|
|
18
|
+
const EditableServerElement = ({
|
|
19
|
+
initialElementData,
|
|
20
|
+
children
|
|
21
|
+
}) => {
|
|
22
|
+
const elementKey = initialElementData.key;
|
|
23
|
+
const elementData = useElementData({ elementKey });
|
|
24
|
+
if (elementData == null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return /* @__PURE__ */ jsx(EditableServerElementWrapper, { ...{ initialElementData, elementData }, children });
|
|
28
|
+
};
|
|
29
|
+
const EditableServerElementWrapper = ({
|
|
30
|
+
initialElementData,
|
|
31
|
+
elementData,
|
|
32
|
+
children
|
|
33
|
+
}) => {
|
|
34
|
+
const elementKey = initialElementData.key;
|
|
35
|
+
const dispatch = useDispatch();
|
|
36
|
+
const documentKey = useDocumentKey();
|
|
37
|
+
const [_legacyDefs, definitions] = useControlDefs({ elementType: initialElementData.type });
|
|
38
|
+
const stylesheetFactory = useEditableElementStylesheetFactory({ elementKey });
|
|
39
|
+
const controlInstances = useControlInstances(elementKey);
|
|
40
|
+
const resolvedProps = useResolvedProps({
|
|
41
|
+
elementKey,
|
|
42
|
+
propDefs: definitions,
|
|
43
|
+
propData: elementData.props,
|
|
44
|
+
controlInstances,
|
|
45
|
+
stylesheetFactory
|
|
46
|
+
});
|
|
47
|
+
const prevPropsRef = useRef(resolvedProps);
|
|
48
|
+
const prevLeafPropsRef = useRef(
|
|
49
|
+
getLeafPropsAndInstances(resolvedProps, controlInstances).leafProps
|
|
50
|
+
);
|
|
51
|
+
const serverRefresh = useServerElementRefresh({ elementKey });
|
|
52
|
+
const applyServerRefresh = useCallback(
|
|
53
|
+
(elementData2, leafInstances, documentKey2) => startTransition(async () => {
|
|
54
|
+
const applied = await serverRefresh(elementData2);
|
|
55
|
+
if (!applied)
|
|
56
|
+
return;
|
|
57
|
+
startTransition(() => {
|
|
58
|
+
leafInstances.forEach(
|
|
59
|
+
(c) => dispatch(clearResolvedValueOverride({ documentKey: documentKey2, instanceKey: c.instanceKey }))
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
}),
|
|
63
|
+
[serverRefresh, dispatch]
|
|
64
|
+
);
|
|
65
|
+
const applyResolvedValueOverrides = useCallback(
|
|
66
|
+
(instances, props, documentKey2) => instances.forEach(
|
|
67
|
+
(c) => dispatch(
|
|
68
|
+
setResolvedValueOverride({
|
|
69
|
+
documentKey: documentKey2,
|
|
70
|
+
instanceKey: c.instanceKey,
|
|
71
|
+
value: getProp(props, c.propPath)
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
),
|
|
75
|
+
[dispatch]
|
|
76
|
+
);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (documentKey == null)
|
|
79
|
+
return;
|
|
80
|
+
if (children == null) {
|
|
81
|
+
const { leafInstances, leafProps } = getLeafPropsAndInstances(resolvedProps, controlInstances);
|
|
82
|
+
applyServerRefresh(elementData, leafInstances, documentKey);
|
|
83
|
+
prevPropsRef.current = resolvedProps;
|
|
84
|
+
prevLeafPropsRef.current = leafProps;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (resolvedProps !== prevPropsRef.current) {
|
|
88
|
+
const { needsRefresh, leafInstances, leafProps, reactNodeInstances } = needsServerRefresh({
|
|
89
|
+
resolvedProps,
|
|
90
|
+
controlInstances,
|
|
91
|
+
prevProps: prevPropsRef.current,
|
|
92
|
+
prevLeafProps: prevLeafPropsRef.current
|
|
93
|
+
});
|
|
94
|
+
if (needsRefresh) {
|
|
95
|
+
applyServerRefresh(elementData, leafInstances, documentKey);
|
|
96
|
+
} else {
|
|
97
|
+
applyResolvedValueOverrides(reactNodeInstances, resolvedProps, documentKey);
|
|
98
|
+
}
|
|
99
|
+
prevPropsRef.current = resolvedProps;
|
|
100
|
+
prevLeafPropsRef.current = leafProps;
|
|
101
|
+
}
|
|
102
|
+
}, [
|
|
103
|
+
children,
|
|
104
|
+
resolvedProps,
|
|
105
|
+
documentKey,
|
|
106
|
+
elementData,
|
|
107
|
+
controlInstances,
|
|
108
|
+
applyServerRefresh,
|
|
109
|
+
applyResolvedValueOverrides
|
|
110
|
+
]);
|
|
111
|
+
return children;
|
|
112
|
+
};
|
|
113
|
+
const needsServerRefresh = ({
|
|
114
|
+
resolvedProps,
|
|
115
|
+
controlInstances,
|
|
116
|
+
prevProps,
|
|
117
|
+
prevLeafProps
|
|
118
|
+
}) => {
|
|
119
|
+
const { leafInstances, leafProps } = getLeafPropsAndInstances(resolvedProps, controlInstances);
|
|
120
|
+
const combinedLeafProps = setUnion(leafProps, prevLeafProps).values();
|
|
121
|
+
const updatedLeafProps = new Set(
|
|
122
|
+
[...combinedLeafProps].filter(
|
|
123
|
+
(propName) => getProp(resolvedProps, propName) !== getProp(prevProps, propName)
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
const updatedLeafInstances = leafInstances.filter(
|
|
127
|
+
(instance) => updatedLeafProps.has(instance.propPath)
|
|
128
|
+
);
|
|
129
|
+
const reactNodeInstances = updatedLeafInstances.filter((c) => c.resolvesToRenderableNode());
|
|
130
|
+
const reactNodePropKeys = new Set(reactNodeInstances.map((c) => c.propPath));
|
|
131
|
+
const newlyAddedLeafProps = setDifference(leafProps, prevLeafProps);
|
|
132
|
+
const needsRefresh = setDifference(updatedLeafProps, reactNodePropKeys).size > 0 || newlyAddedLeafProps.size > 0;
|
|
133
|
+
return {
|
|
134
|
+
needsRefresh,
|
|
135
|
+
leafInstances,
|
|
136
|
+
leafProps,
|
|
137
|
+
reactNodeInstances
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
const getLeafPropsAndInstances = (props, controlInstances) => {
|
|
141
|
+
const topLevelInstances = Object.keys(props).map((prop) => controlInstances?.[prop]).filter((inst) => inst != null);
|
|
142
|
+
const leafInstances = getLeafInstances(topLevelInstances);
|
|
143
|
+
const leafProps = new Set(leafInstances.map((c) => c.propPath));
|
|
144
|
+
return { leafProps, leafInstances };
|
|
145
|
+
};
|
|
146
|
+
const getLeafInstances = (instances) => instances.flatMap(
|
|
147
|
+
(instance) => instance.isCompositeProp() ? getLeafInstances(instance.children()) : [instance]
|
|
148
|
+
);
|
|
149
|
+
export {
|
|
150
|
+
EditableServerElement
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=editable-server-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/editable-server-element.tsx"],"sourcesContent":["'use client'\n\nimport { type PropsWithChildren, useEffect, useRef, startTransition, useCallback } from 'react'\n\nimport { ControlInstance } from '@makeswift/controls'\n\nimport { type ElementData } from '../../../../state/read-only-state'\nimport {\n setResolvedValueOverride,\n clearResolvedValueOverride,\n} from '../../../../state/actions/internal/read-write-actions'\n\nimport { useServerElementRefresh } from '../../hooks/use-server-element-refresh'\nimport { useElementData } from '../../hooks/use-element-data'\nimport { useControlDefs } from '../../hooks/use-control-defs'\nimport { useEditableElementStylesheetFactory } from '../../hooks/use-editable-element-stylesheet-factory'\nimport { useResolvedProps } from '../../hooks/use-resolved-props'\nimport { useControlInstances } from '../../components/control-instances-context'\nimport { useDispatch } from '../../hooks/use-dispatch'\nimport { useDocumentKey } from '../../hooks/use-document-context'\n\nimport { getProp } from '../../../../utils/prop-by-path'\nimport { setUnion, setDifference } from '../../../../utils/set'\n\nexport const EditableServerElement = ({\n initialElementData,\n children,\n}: PropsWithChildren<{ initialElementData: ElementData }>) => {\n const elementKey = initialElementData.key\n const elementData = useElementData({ elementKey })\n if (elementData == null) {\n // Element has been deleted\n return null\n }\n\n return (\n <EditableServerElementWrapper {...{ initialElementData, elementData }}>\n {children}\n </EditableServerElementWrapper>\n )\n}\n\n/**\n * Reflects edits to `elementData.props` in the server-rendered `children`.\n * Changes limited to existing `ReactNode` props are applied through client-side\n * overrides. Style prop changes are handled by the stylesheet engine during\n * prop resolution. All other prop changes trigger a server refresh.\n */\nconst EditableServerElementWrapper = ({\n initialElementData,\n elementData,\n children,\n}: PropsWithChildren<{ initialElementData: ElementData; elementData: ElementData }>) => {\n const elementKey = initialElementData.key\n const dispatch = useDispatch()\n const documentKey = useDocumentKey()\n\n const [_legacyDefs, definitions] = useControlDefs({ elementType: initialElementData.type })\n const stylesheetFactory = useEditableElementStylesheetFactory({ elementKey })\n\n const controlInstances = useControlInstances(elementKey)\n const resolvedProps = useResolvedProps({\n elementKey,\n propDefs: definitions,\n propData: elementData.props,\n controlInstances,\n stylesheetFactory,\n })\n\n const prevPropsRef = useRef(resolvedProps)\n const prevLeafPropsRef = useRef(\n getLeafPropsAndInstances(resolvedProps, controlInstances).leafProps,\n )\n\n const serverRefresh = useServerElementRefresh({ elementKey })\n const applyServerRefresh = useCallback(\n (elementData: ElementData, leafInstances: ControlInstance[], documentKey: string) =>\n startTransition(async () => {\n const applied = await serverRefresh(elementData)\n if (!applied) return\n\n // need a nested `startTransition` here, see\n // https://react.dev/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition\n startTransition(() => {\n // reset instance overrides, if any\n leafInstances.forEach(c =>\n dispatch(clearResolvedValueOverride({ documentKey, instanceKey: c.instanceKey })),\n )\n })\n }),\n [serverRefresh, dispatch],\n )\n\n const applyResolvedValueOverrides = useCallback(\n (instances: ControlInstance[], props: Record<string, unknown>, documentKey: string) =>\n instances.forEach(c =>\n dispatch(\n setResolvedValueOverride({\n documentKey,\n instanceKey: c.instanceKey,\n value: getProp(props, c.propPath),\n }),\n ),\n ),\n [dispatch],\n )\n\n useEffect(() => {\n if (documentKey == null) return\n\n if (children == null) {\n // If we don't have a server-rendered node (i.e. user just dropped the element to the page),\n // trigger a server re-render\n const { leafInstances, leafProps } = getLeafPropsAndInstances(resolvedProps, controlInstances)\n\n applyServerRefresh(elementData, leafInstances, documentKey)\n\n prevPropsRef.current = resolvedProps\n prevLeafPropsRef.current = leafProps\n return\n }\n\n if (resolvedProps !== prevPropsRef.current) {\n // If there was a change in resolved value, check if any of the changed props necessitate\n // a server refresh.\n //\n // Note that style props have stable class names and updating a style prop will not result\n // in a change to the resolved value, which is what we want. The stylesheet engine takes\n // care of updating the client CSS on style prop updates through the `useResolvedProps` call.\n const { needsRefresh, leafInstances, leafProps, reactNodeInstances } = needsServerRefresh({\n resolvedProps,\n controlInstances,\n prevProps: prevPropsRef.current,\n prevLeafProps: prevLeafPropsRef.current,\n })\n\n if (needsRefresh) {\n applyServerRefresh(elementData, leafInstances, documentKey)\n } else {\n applyResolvedValueOverrides(reactNodeInstances, resolvedProps, documentKey)\n }\n\n prevPropsRef.current = resolvedProps\n prevLeafPropsRef.current = leafProps\n }\n }, [\n children,\n resolvedProps,\n documentKey,\n elementData,\n controlInstances,\n applyServerRefresh,\n applyResolvedValueOverrides,\n ])\n\n return children\n}\n\n/**\n * Determines whether resolved prop changes require a server refresh and returns\n * the control-instance state needed to apply the update.\n */\nconst needsServerRefresh = ({\n resolvedProps,\n controlInstances,\n prevProps,\n prevLeafProps,\n}: {\n resolvedProps: Record<string, unknown>\n controlInstances: Record<string, ControlInstance> | null\n prevProps: Record<string, unknown>\n prevLeafProps: Set<string>\n}): {\n needsRefresh: boolean\n leafInstances: ControlInstance[]\n leafProps: Set<string>\n reactNodeInstances: ControlInstance[]\n} => {\n const { leafInstances, leafProps } = getLeafPropsAndInstances(resolvedProps, controlInstances)\n\n const combinedLeafProps = setUnion(leafProps, prevLeafProps).values()\n const updatedLeafProps = new Set(\n [...combinedLeafProps].filter(\n propName => getProp(resolvedProps, propName) !== getProp(prevProps, propName),\n ),\n )\n\n const updatedLeafInstances = leafInstances.filter(instance =>\n updatedLeafProps.has(instance.propPath),\n )\n\n const reactNodeInstances = updatedLeafInstances.filter(c => c.resolvesToRenderableNode())\n\n const reactNodePropKeys = new Set(reactNodeInstances.map(c => c.propPath))\n const newlyAddedLeafProps = setDifference(leafProps, prevLeafProps)\n\n // A server refresh is needed if some of the updated props are not `ReactNode` props, or we\n // have newly observed props (typically `List` items). Even when newly observed props are\n // `ReactNode` props, we have to first render them on the server to get them in the element\n // tree before they can be updated client-side.\n const needsRefresh =\n setDifference(updatedLeafProps, reactNodePropKeys).size > 0 || newlyAddedLeafProps.size > 0\n\n return {\n needsRefresh,\n leafInstances,\n leafProps,\n reactNodeInstances,\n }\n}\n\n/**\n * Returns terminal prop paths with the corresponding control instances.\n */\nconst getLeafPropsAndInstances = (\n props: Record<string, unknown>,\n controlInstances: Record<string, ControlInstance> | null,\n): {\n leafProps: Set<string>\n leafInstances: ControlInstance[]\n} => {\n const topLevelInstances = Object.keys(props)\n .map(prop => controlInstances?.[prop])\n .filter(inst => inst != null)\n\n const leafInstances = getLeafInstances(topLevelInstances)\n const leafProps = new Set(leafInstances.map(c => c.propPath))\n return { leafProps, leafInstances }\n}\n\n/**\n * Flattens a control instance tree to its leaf (terminal) instances.\n */\nconst getLeafInstances = (instances: ControlInstance[]): ControlInstance[] =>\n instances.flatMap(instance =>\n instance.isCompositeProp() ? getLeafInstances(instance.children()) : [instance],\n )\n"],"mappings":"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","names":["elementData","documentKey"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { partitionRecord } from "../../../../utils/partition";
|
|
3
|
+
import {
|
|
4
|
+
getReactComponent,
|
|
5
|
+
getBreakpoints,
|
|
6
|
+
getComponentPropControllerDescriptors
|
|
7
|
+
} from "../../../../state/read-only-state";
|
|
8
|
+
import { FallbackComponent } from "../../../../components/shared/FallbackComponent";
|
|
9
|
+
import { isLegacyDescriptor } from "../../../../prop-controllers/descriptors";
|
|
10
|
+
import {
|
|
11
|
+
ServerCSSCollector,
|
|
12
|
+
createCollectingServerStylesheet,
|
|
13
|
+
InjectServerCSS
|
|
14
|
+
} from "../css/server-css";
|
|
15
|
+
import { getStore } from "../render-context";
|
|
16
|
+
import { resolveProps } from "../resolve-props";
|
|
17
|
+
async function ServerElementData({
|
|
18
|
+
documentKey,
|
|
19
|
+
context,
|
|
20
|
+
elementData
|
|
21
|
+
}) {
|
|
22
|
+
const state = getStore(context).getState();
|
|
23
|
+
const Component = getReactComponent(state, elementData.type);
|
|
24
|
+
if (Component == null) {
|
|
25
|
+
return /* @__PURE__ */ jsx(
|
|
26
|
+
FallbackComponent,
|
|
27
|
+
{
|
|
28
|
+
text: "Component not found",
|
|
29
|
+
details: `Unknown component '${elementData.type}'`
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const [legacyDescriptors, definitions] = getControlDefs(state, elementData);
|
|
34
|
+
const legacyKeys = Object.keys(legacyDescriptors);
|
|
35
|
+
if (legacyKeys.length > 0) {
|
|
36
|
+
console.warn(`Unexpected legacy control data in server element '${elementData.key}`, {
|
|
37
|
+
elementData,
|
|
38
|
+
legacyKeys
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const cssCollector = new ServerCSSCollector();
|
|
42
|
+
const stylesheet = createCollectingServerStylesheet(
|
|
43
|
+
cssCollector,
|
|
44
|
+
getBreakpoints(state),
|
|
45
|
+
elementData.key
|
|
46
|
+
);
|
|
47
|
+
const props = await resolveProps(context, elementData, documentKey, definitions, stylesheet);
|
|
48
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
|
+
/* @__PURE__ */ jsx(Component, { ...props }, elementData.key),
|
|
50
|
+
/* @__PURE__ */ jsx(InjectServerCSS, { collector: cssCollector, elementKey: elementData.key })
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
const getControlDefs = (state, elementData) => {
|
|
54
|
+
const descriptors = getComponentPropControllerDescriptors(state, elementData.type) ?? {};
|
|
55
|
+
return partitionRecord(descriptors, isLegacyDescriptor);
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
ServerElementData
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=element-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/element-data.tsx"],"sourcesContent":["import { type ReactNode } from 'react'\n\nimport { partitionRecord } from '../../../../utils/partition'\n\nimport {\n type State,\n type ElementData,\n getReactComponent,\n getBreakpoints,\n getComponentPropControllerDescriptors,\n} from '../../../../state/read-only-state'\n\nimport { FallbackComponent } from '../../../../components/shared/FallbackComponent'\nimport { isLegacyDescriptor } from '../../../../prop-controllers/descriptors'\n\nimport {\n ServerCSSCollector,\n createCollectingServerStylesheet,\n InjectServerCSS,\n} from '../css/server-css'\nimport { type ServerRenderContext, getStore } from '../render-context'\nimport { resolveProps } from '../resolve-props'\n\nexport async function ServerElementData({\n documentKey,\n context,\n elementData,\n}: {\n documentKey: string\n context: ServerRenderContext\n elementData: ElementData\n}): Promise<ReactNode> {\n const state = getStore(context).getState()\n\n const Component = getReactComponent(state, elementData.type)\n if (Component == null) {\n return (\n <FallbackComponent\n text=\"Component not found\"\n details={`Unknown component '${elementData.type}'`}\n />\n )\n }\n\n const [legacyDescriptors, definitions] = getControlDefs(state, elementData)\n const legacyKeys = Object.keys(legacyDescriptors)\n if (legacyKeys.length > 0) {\n console.warn(`Unexpected legacy control data in server element '${elementData.key}`, {\n elementData,\n legacyKeys,\n })\n }\n\n const cssCollector = new ServerCSSCollector()\n const stylesheet = createCollectingServerStylesheet(\n cssCollector,\n getBreakpoints(state),\n elementData.key,\n )\n\n const props = await resolveProps(context, elementData, documentKey, definitions, stylesheet)\n\n return (\n <>\n {/* Make the component the first child so that `findDOMNode` resolves to its first\n rendered DOM node (if any) rather than the component's `<style>` element */}\n <Component key={elementData.key} {...props} />\n <InjectServerCSS collector={cssCollector} elementKey={elementData.key} />\n </>\n )\n}\n\nconst getControlDefs = (state: State, elementData: ElementData) => {\n const descriptors = getComponentPropControllerDescriptors(state, elementData.type) ?? {}\n return partitionRecord(descriptors, isLegacyDescriptor)\n}\n"],"mappings":"AAqCM,SA0BF,UA1BE,KA0BF,YA1BE;AAnCN,SAAS,uBAAuB;AAEhC;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AAEnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAmC,gBAAgB;AACnD,SAAS,oBAAoB;AAE7B,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIuB;AACrB,QAAM,QAAQ,SAAS,OAAO,EAAE,SAAS;AAEzC,QAAM,YAAY,kBAAkB,OAAO,YAAY,IAAI;AAC3D,MAAI,aAAa,MAAM;AACrB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,sBAAsB,YAAY,IAAI;AAAA;AAAA,IACjD;AAAA,EAEJ;AAEA,QAAM,CAAC,mBAAmB,WAAW,IAAI,eAAe,OAAO,WAAW;AAC1E,QAAM,aAAa,OAAO,KAAK,iBAAiB;AAChD,MAAI,WAAW,SAAS,GAAG;AACzB,YAAQ,KAAK,qDAAqD,YAAY,GAAG,IAAI;AAAA,MACnF;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,IAAI,mBAAmB;AAC5C,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,eAAe,KAAK;AAAA,IACpB,YAAY;AAAA,EACd;AAEA,QAAM,QAAQ,MAAM,aAAa,SAAS,aAAa,aAAa,aAAa,UAAU;AAE3F,SACE,iCAGE;AAAA,wBAAC,aAAiC,GAAG,SAArB,YAAY,GAAgB;AAAA,IAC5C,oBAAC,mBAAgB,WAAW,cAAc,YAAY,YAAY,KAAK;AAAA,KACzE;AAEJ;AAEA,MAAM,iBAAiB,CAAC,OAAc,gBAA6B;AACjE,QAAM,cAAc,sCAAsC,OAAO,YAAY,IAAI,KAAK,CAAC;AACvF,SAAO,gBAAgB,aAAa,kBAAkB;AACxD;","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
isElementReference,
|
|
4
|
+
getComponentsMeta
|
|
5
|
+
} from "../../../../state/read-only-state";
|
|
6
|
+
import { FallbackComponent } from "../../../../components/shared/FallbackComponent";
|
|
7
|
+
import { Element as ClientElement } from "../../components/Element";
|
|
8
|
+
import { getStore } from "../render-context";
|
|
9
|
+
import { ServerElementData } from "./element-data";
|
|
10
|
+
function ServerElement({
|
|
11
|
+
context,
|
|
12
|
+
element,
|
|
13
|
+
documentKey
|
|
14
|
+
}) {
|
|
15
|
+
if (isElementReference(element)) {
|
|
16
|
+
return /* @__PURE__ */ jsx(FallbackComponent, { text: "Element reference is not supported on server yet" });
|
|
17
|
+
}
|
|
18
|
+
const state = getStore(context).getState();
|
|
19
|
+
const elementMeta = getComponentsMeta(state).get(element.type);
|
|
20
|
+
if (elementMeta == null) {
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
FallbackComponent,
|
|
23
|
+
{
|
|
24
|
+
text: "Component not found",
|
|
25
|
+
details: `Missing component metadata for '${element.type}'`
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
const isRSC = elementMeta.server ?? false;
|
|
30
|
+
if (!isRSC) {
|
|
31
|
+
return /* @__PURE__ */ jsx(ClientElement, { element }, element.key);
|
|
32
|
+
}
|
|
33
|
+
return /* @__PURE__ */ jsx(ServerElementData, { documentKey, context, elementData: element });
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
ServerElement
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/element.tsx"],"sourcesContent":["import { ReactNode } from 'react'\n\nimport {\n isElementReference,\n getComponentsMeta,\n type Element as ElementDataOrRef,\n} from '../../../../state/read-only-state'\n\nimport { FallbackComponent } from '../../../../components/shared/FallbackComponent'\n\nimport { Element as ClientElement } from '../../components/Element'\n\nimport { type ServerRenderContext, getStore } from '../render-context'\n\nimport { ServerElementData } from './element-data'\n\nexport function ServerElement({\n context,\n element,\n documentKey,\n}: {\n context: ServerRenderContext\n element: ElementDataOrRef\n documentKey: string\n}): ReactNode {\n // check for element references first to avoid looking them up as regular components\n if (isElementReference(element)) {\n return <FallbackComponent text=\"Element reference is not supported on server yet\" />\n }\n\n const state = getStore(context).getState()\n const elementMeta = getComponentsMeta(state).get(element.type)\n if (elementMeta == null) {\n return (\n <FallbackComponent\n text=\"Component not found\"\n details={`Missing component metadata for '${element.type}'`}\n />\n )\n }\n\n const isRSC = elementMeta.server ?? false\n if (!isRSC) {\n return <ClientElement key={element.key} element={element} />\n }\n\n return <ServerElementData documentKey={documentKey} context={context} elementData={element} />\n}\n"],"mappings":"AA2BW;AAzBX;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,yBAAyB;AAElC,SAAS,WAAW,qBAAqB;AAEzC,SAAmC,gBAAgB;AAEnD,SAAS,yBAAyB;AAE3B,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIc;AAEZ,MAAI,mBAAmB,OAAO,GAAG;AAC/B,WAAO,oBAAC,qBAAkB,MAAK,oDAAmD;AAAA,EACpF;AAEA,QAAM,QAAQ,SAAS,OAAO,EAAE,SAAS;AACzC,QAAM,cAAc,kBAAkB,KAAK,EAAE,IAAI,QAAQ,IAAI;AAC7D,MAAI,eAAe,MAAM;AACvB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,mCAAmC,QAAQ,IAAI;AAAA;AAAA,IAC1D;AAAA,EAEJ;AAEA,QAAM,QAAQ,YAAY,UAAU;AACpC,MAAI,CAAC,OAAO;AACV,WAAO,oBAAC,iBAAgC,WAAb,QAAQ,GAAuB;AAAA,EAC5D;AAEA,SAAO,oBAAC,qBAAkB,aAA0B,SAAkB,aAAa,SAAS;AAC9F;","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MakeswiftComponent as MakeswiftClientComponent } from "../../components/MakeswiftComponent";
|
|
3
|
+
import { RSCSnapshotRenderer } from "./snapshot-renderer";
|
|
4
|
+
const MakeswiftComponent = (props) => /* @__PURE__ */ jsx(RSCSnapshotRenderer, { ...props, children: /* @__PURE__ */ jsx(MakeswiftClientComponent, { ...props }) });
|
|
5
|
+
export {
|
|
6
|
+
MakeswiftComponent
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=makeswift-component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/makeswift-component.tsx"],"sourcesContent":["import { type ComponentProps } from 'react'\n\nimport { MakeswiftComponent as MakeswiftClientComponent } from '../../components/MakeswiftComponent'\n\nimport { RSCSnapshotRenderer } from './snapshot-renderer'\n\n/**\n * Renders Makeswift component snapshot with server-element support. RSC counterpart of\n * https://docs.makeswift.com/developer/docs/reference/components/makeswift-component#props\n */\nexport const MakeswiftComponent = (props: ComponentProps<typeof MakeswiftClientComponent>) => (\n <RSCSnapshotRenderer {...props}>\n <MakeswiftClientComponent {...props} />\n </RSCSnapshotRenderer>\n)\n"],"mappings":"AAYI;AAVJ,SAAS,sBAAsB,gCAAgC;AAE/D,SAAS,2BAA2B;AAM7B,MAAM,qBAAqB,CAAC,UACjC,oBAAC,uBAAqB,GAAG,OACvB,8BAAC,4BAA0B,GAAG,OAAO,GACvC;","names":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ClientCSSProvider } from "../css/client-css";
|
|
3
|
+
import { getStore } from "../render-context";
|
|
4
|
+
import { collectServerElements } from "../collect-server-elements";
|
|
5
|
+
import { updateApiResourceCache } from "../update-api-resource-cache";
|
|
6
|
+
import { ServerElementsCache } from "./server-elements-cache";
|
|
7
|
+
function RSCRenderer({
|
|
8
|
+
context,
|
|
9
|
+
document,
|
|
10
|
+
cacheData,
|
|
11
|
+
children
|
|
12
|
+
}) {
|
|
13
|
+
const serverElements = collectServerElements(context, document, cacheData);
|
|
14
|
+
return /* @__PURE__ */ jsx(ServerElementsCache, { value: serverElements, children: /* @__PURE__ */ jsx(ClientCSSProvider, { children }) });
|
|
15
|
+
}
|
|
16
|
+
function RSCElementRenderer({
|
|
17
|
+
context,
|
|
18
|
+
cacheData,
|
|
19
|
+
children
|
|
20
|
+
}) {
|
|
21
|
+
const store = getStore(context);
|
|
22
|
+
updateApiResourceCache(store, cacheData);
|
|
23
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
RSCElementRenderer,
|
|
27
|
+
RSCRenderer
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/renderer.tsx"],"sourcesContent":["import { type PropsWithChildren } from 'react'\n\nimport { type CacheData } from '../../../../api/api-resources-client'\nimport { type Document } from '../../../../state/modules/read-only-documents'\n\nimport { ClientCSSProvider } from '../css/client-css'\n\nimport { type ServerRenderContext, getStore } from '../render-context'\nimport { collectServerElements } from '../collect-server-elements'\nimport { updateApiResourceCache } from '../update-api-resource-cache'\n\nimport { ServerElementsCache } from './server-elements-cache'\n\n/**\n * Helper for rendering a Makeswift document containing server elements. Makes\n * the server-rendered nodes available to the client renderer and enables\n * client-side style updates for editable server elements.\n */\nexport function RSCRenderer({\n context,\n document,\n cacheData,\n children,\n}: PropsWithChildren<{ context: ServerRenderContext; document: Document; cacheData: CacheData }>) {\n const serverElements = collectServerElements(context, document, cacheData)\n\n return (\n <ServerElementsCache value={serverElements}>\n <ClientCSSProvider>{children}</ClientCSSProvider>\n </ServerElementsCache>\n )\n}\n\n/**\n * Helper for (re-)rendering an isolated server element. Updates the server\n * state with the context's API resource cache.\n */\nexport function RSCElementRenderer({\n context,\n cacheData,\n children,\n}: PropsWithChildren<{ context: ServerRenderContext; cacheData: CacheData }>) {\n const store = getStore(context)\n\n updateApiResourceCache(store, cacheData)\n return <>{children}</>\n}\n"],"mappings":"AA4BM,SAiBG,UAjBH;AAvBN,SAAS,yBAAyB;AAElC,SAAmC,gBAAgB;AACnD,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AAEvC,SAAS,2BAA2B;AAO7B,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkG;AAChG,QAAM,iBAAiB,sBAAsB,SAAS,UAAU,SAAS;AAEzE,SACE,oBAAC,uBAAoB,OAAO,gBAC1B,8BAAC,qBAAmB,UAAS,GAC/B;AAEJ;AAMO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA8E;AAC5E,QAAM,QAAQ,SAAS,OAAO;AAE9B,yBAAuB,OAAO,SAAS;AACvC,SAAO,gCAAG,UAAS;AACrB;","names":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useState, useMemo } from "react";
|
|
4
|
+
const Context = createContext({
|
|
5
|
+
getElement: () => null,
|
|
6
|
+
updateElement: () => {
|
|
7
|
+
},
|
|
8
|
+
removeElement: () => {
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const ServerElementsCache = ({
|
|
12
|
+
children,
|
|
13
|
+
value
|
|
14
|
+
}) => {
|
|
15
|
+
const [nodes, setNodes] = useState(value);
|
|
16
|
+
const [previousValue, setPreviousValue] = useState(value);
|
|
17
|
+
if (value !== previousValue) {
|
|
18
|
+
setPreviousValue(value);
|
|
19
|
+
setNodes(value);
|
|
20
|
+
}
|
|
21
|
+
const getElement = useCallback((elementKey) => nodes.get(elementKey), [nodes]);
|
|
22
|
+
const updateElement = useCallback(
|
|
23
|
+
(elementKey, node) => setNodes((prev) => new Map(prev).set(elementKey, node)),
|
|
24
|
+
[]
|
|
25
|
+
);
|
|
26
|
+
const removeElement = useCallback(
|
|
27
|
+
(elementKey) => setNodes((prev) => {
|
|
28
|
+
const next = new Map(prev);
|
|
29
|
+
next.delete(elementKey);
|
|
30
|
+
return next;
|
|
31
|
+
}),
|
|
32
|
+
[]
|
|
33
|
+
);
|
|
34
|
+
const cache = useMemo(
|
|
35
|
+
() => ({ getElement, updateElement, removeElement }),
|
|
36
|
+
[getElement, updateElement, removeElement]
|
|
37
|
+
);
|
|
38
|
+
return /* @__PURE__ */ jsx(Context.Provider, { value: cache, children });
|
|
39
|
+
};
|
|
40
|
+
const useServerElementsCache = () => useContext(Context);
|
|
41
|
+
export {
|
|
42
|
+
ServerElementsCache,
|
|
43
|
+
useServerElementsCache
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=server-elements-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/server-elements-cache.tsx"],"sourcesContent":["'use client'\n\nimport { createContext, ReactNode, useCallback, useContext, useState, useMemo } from 'react'\n\nimport { type ElementsMap } from '../collect-server-elements'\n\ntype ContextValue = {\n getElement: (elementKey: string) => ReactNode\n updateElement: (elementKey: string, node: ReactNode) => void\n removeElement: (elementKey: string) => void\n}\n\nconst Context = createContext<ContextValue>({\n getElement: () => null,\n updateElement: () => {},\n removeElement: () => {},\n})\n\n/**\n * Client-side \"cache\" of server-rendered elements; this is one of the key pieces in our RSC\n * implementation, with React doing the majority of the heavy lifting: when `ReactNode`s are\n * passed as props across a 'use client' boundary, React's flight serializer automatically\n * renders and encodes them in the RSC stream and then reconstructs them on the client. All\n * we need to do on the client is to make these React elements available for lookup/\n * manipulation when editing in the builder.\n */\nexport const ServerElementsCache = ({\n children,\n value,\n}: {\n children: ReactNode\n value: ElementsMap\n}) => {\n // An RSC re-render does not inherently remount client components; React can reconcile\n // the new server tree with the existing client tree, so we need to handle the `value`\n // prop updates\n const [nodes, setNodes] = useState(value)\n const [previousValue, setPreviousValue] = useState(value)\n\n // this is okay to do on render, see https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes\n if (value !== previousValue) {\n setPreviousValue(value)\n setNodes(value)\n }\n\n const getElement = useCallback((elementKey: string): ReactNode => nodes.get(elementKey), [nodes])\n\n const updateElement = useCallback(\n (elementKey: string, node: ReactNode) => setNodes(prev => new Map(prev).set(elementKey, node)),\n [],\n )\n\n const removeElement = useCallback(\n (elementKey: string) =>\n setNodes(prev => {\n const next = new Map(prev)\n next.delete(elementKey)\n return next\n }),\n [],\n )\n\n const cache = useMemo(\n () => ({ getElement, updateElement, removeElement }),\n [getElement, updateElement, removeElement],\n )\n\n return <Context.Provider value={cache}>{children}</Context.Provider>\n}\n\nexport const useServerElementsCache = () => useContext(Context)\n"],"mappings":";AAmES;AAjET,SAAS,eAA0B,aAAa,YAAY,UAAU,eAAe;AAUrF,MAAM,UAAU,cAA4B;AAAA,EAC1C,YAAY,MAAM;AAAA,EAClB,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,eAAe,MAAM;AAAA,EAAC;AACxB,CAAC;AAUM,MAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAGM;AAIJ,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,KAAK;AACxC,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AAGxD,MAAI,UAAU,eAAe;AAC3B,qBAAiB,KAAK;AACtB,aAAS,KAAK;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY,CAAC,eAAkC,MAAM,IAAI,UAAU,GAAG,CAAC,KAAK,CAAC;AAEhG,QAAM,gBAAgB;AAAA,IACpB,CAAC,YAAoB,SAAoB,SAAS,UAAQ,IAAI,IAAI,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC;AAAA,IAC7F,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,eACC,SAAS,UAAQ;AACf,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,WAAK,OAAO,UAAU;AACtB,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ;AAAA,IACZ,OAAO,EAAE,YAAY,eAAe,cAAc;AAAA,IAClD,CAAC,YAAY,eAAe,aAAa;AAAA,EAC3C;AAEA,SAAO,oBAAC,QAAQ,UAAR,EAAiB,OAAO,OAAQ,UAAS;AACnD;AAEO,MAAM,yBAAyB,MAAM,WAAW,OAAO;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MakeswiftComponentType } from "../../../../components/builtin/constants";
|
|
3
|
+
import { Slot as ClientSlot } from "../../components/Slot";
|
|
4
|
+
import { RSCSnapshotRenderer } from "./snapshot-renderer";
|
|
5
|
+
const Slot = ({ label, snapshot, fallback }) => /* @__PURE__ */ jsx(RSCSnapshotRenderer, { snapshot, label, type: MakeswiftComponentType.Slot, children: /* @__PURE__ */ jsx(ClientSlot, { ...{ label, snapshot, fallback } }) });
|
|
6
|
+
export {
|
|
7
|
+
Slot
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=slot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/slot.tsx"],"sourcesContent":["import { type ComponentProps } from 'react'\n\nimport { MakeswiftComponentType } from '../../../../components/builtin/constants'\n\nimport { Slot as ClientSlot } from '../../components/Slot'\n\nimport { RSCSnapshotRenderer } from './snapshot-renderer'\n\n/**\n * Renders Makeswift snapshot or its fallback with server-element support. RSC\n * counterpart of https://docs.makeswift.com/developer/docs/reference/components/slot\n */\nexport const Slot = ({ label, snapshot, fallback }: ComponentProps<typeof ClientSlot>) => (\n <RSCSnapshotRenderer snapshot={snapshot} label={label} type={MakeswiftComponentType.Slot}>\n <ClientSlot {...{ label, snapshot, fallback }} />\n </RSCSnapshotRenderer>\n)\n"],"mappings":"AAcI;AAZJ,SAAS,8BAA8B;AAEvC,SAAS,QAAQ,kBAAkB;AAEnC,SAAS,2BAA2B;AAM7B,MAAM,OAAO,CAAC,EAAE,OAAO,UAAU,SAAS,MAC/C,oBAAC,uBAAoB,UAAoB,OAAc,MAAM,uBAAuB,MAClF,8BAAC,cAAY,GAAG,EAAE,OAAO,UAAU,SAAS,GAAG,GACjD;","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { componentDocumentToRootEmbeddedDocument } from "../../../../client/component-snapshot";
|
|
3
|
+
import { getRenderContext } from "../render-context";
|
|
4
|
+
import { RSCRenderer } from "./renderer";
|
|
5
|
+
const RSCSnapshotRenderer = ({
|
|
6
|
+
snapshot,
|
|
7
|
+
label,
|
|
8
|
+
type,
|
|
9
|
+
description,
|
|
10
|
+
children
|
|
11
|
+
}) => {
|
|
12
|
+
const rootDocument = componentDocumentToRootEmbeddedDocument({
|
|
13
|
+
document: snapshot.document,
|
|
14
|
+
documentKey: snapshot.key,
|
|
15
|
+
name: label,
|
|
16
|
+
type,
|
|
17
|
+
description,
|
|
18
|
+
meta: snapshot.meta
|
|
19
|
+
});
|
|
20
|
+
const context = getRenderContext();
|
|
21
|
+
return /* @__PURE__ */ jsx(RSCRenderer, { context, cacheData: snapshot.cacheData, document: rootDocument, children });
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
RSCSnapshotRenderer
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=snapshot-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/runtimes/react/server/components/snapshot-renderer.tsx"],"sourcesContent":["import { type ComponentProps, type PropsWithChildren } from 'react'\n\nimport { componentDocumentToRootEmbeddedDocument } from '../../../../client/component-snapshot'\nimport { MakeswiftComponent } from '../../components/MakeswiftComponent'\n\nimport { getRenderContext } from '../render-context'\n\nimport { RSCRenderer } from './renderer'\n\n/**\n * High-level helper for rendering server versions of snapshot-backed components\n * (`MakeswiftComponent`, `Slot`). Creates a root document from the snapshot\n * and delegates to `RSCRenderer` to render the server elements and make them\n * editable on the client.\n */\nexport const RSCSnapshotRenderer = ({\n snapshot,\n label,\n type,\n description,\n children,\n}: PropsWithChildren<ComponentProps<typeof MakeswiftComponent>>) => {\n const rootDocument = componentDocumentToRootEmbeddedDocument({\n document: snapshot.document,\n documentKey: snapshot.key,\n name: label,\n type,\n description,\n meta: snapshot.meta,\n })\n\n const context = getRenderContext()\n\n return (\n <RSCRenderer context={context} cacheData={snapshot.cacheData} document={rootDocument}>\n {children}\n </RSCRenderer>\n )\n}\n"],"mappings":"AAkCI;AAhCJ,SAAS,+CAA+C;AAGxD,SAAS,wBAAwB;AAEjC,SAAS,mBAAmB;AAQrB,MAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAoE;AAClE,QAAM,eAAe,wCAAwC;AAAA,IAC3D,UAAU,SAAS;AAAA,IACnB,aAAa,SAAS;AAAA,IACtB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM,SAAS;AAAA,EACjB,CAAC;AAED,QAAM,UAAU,iBAAiB;AAEjC,SACE,oBAAC,eAAY,SAAkB,WAAW,SAAS,WAAW,UAAU,cACrE,UACH;AAEJ;","names":[]}
|