Skip to content

Commit a7eff39

Browse files
authored
refactor: manually namespace meta (webstudio-is#5073)
Here got rid from auto namespacing meta.constraints and meta.indexWithinAncestor to unlock using components from other sdk packages. Now package prefixes should be explicitly specified in meta though with the help of proxy. Though exports are still need to prefix automatically when install package.
1 parent 3f5041a commit a7eff39

23 files changed

Lines changed: 163 additions & 227 deletions

apps/builder/app/shared/matcher.test.tsx

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
expression,
55
renderTemplate,
66
renderData,
7+
createProxy,
78
} from "@webstudio-is/template";
89
import { coreMetas } from "@webstudio-is/sdk";
910
import * as baseMetas from "@webstudio-is/sdk-components-react/metas";
@@ -788,21 +789,25 @@ describe("is tree matching", () => {
788789
});
789790

790791
describe("is instance detachable", () => {
791-
const metas = new Map(Object.entries({ ...baseMetas, ...radixMetas }));
792+
const metas = new Map(Object.entries(baseMetas));
793+
const radix = createProxy("@webstudio-is/sdk-components-react-radix:");
794+
for (const [component, meta] of Object.entries(radixMetas)) {
795+
metas.set(`@webstudio-is/sdk-components-react-radix:${component}`, meta);
796+
}
792797

793798
test("allow deleting one of matching instances", () => {
794799
expect(
795800
isInstanceDetachable({
796801
...renderData(
797802
<$.Body ws:id="body">
798-
<$.Tabs ws:id="tabs">
799-
<$.TabsList ws:id="list">
800-
<$.TabsTrigger ws:id="trigger1"></$.TabsTrigger>
801-
<$.TabsTrigger ws:id="trigger2"></$.TabsTrigger>
802-
</$.TabsList>
803-
<$.TabsContent ws:id="content1"></$.TabsContent>
804-
<$.TabsContent ws:id="content2"></$.TabsContent>
805-
</$.Tabs>
803+
<radix.Tabs ws:id="tabs">
804+
<radix.TabsList ws:id="list">
805+
<radix.TabsTrigger ws:id="trigger1"></radix.TabsTrigger>
806+
<radix.TabsTrigger ws:id="trigger2"></radix.TabsTrigger>
807+
</radix.TabsList>
808+
<radix.TabsContent ws:id="content1"></radix.TabsContent>
809+
<radix.TabsContent ws:id="content2"></radix.TabsContent>
810+
</radix.Tabs>
806811
</$.Body>
807812
),
808813
metas,
@@ -816,12 +821,12 @@ describe("is instance detachable", () => {
816821
isInstanceDetachable({
817822
...renderData(
818823
<$.Body ws:id="body">
819-
<$.Tabs ws:id="tabs">
820-
<$.TabsList ws:id="list">
821-
<$.TabsTrigger ws:id="trigger1"></$.TabsTrigger>
822-
</$.TabsList>
823-
<$.TabsContent ws:id="content1"></$.TabsContent>
824-
</$.Tabs>
824+
<radix.Tabs ws:id="tabs">
825+
<radix.TabsList ws:id="list">
826+
<radix.TabsTrigger ws:id="trigger1"></radix.TabsTrigger>
827+
</radix.TabsList>
828+
<radix.TabsContent ws:id="content1"></radix.TabsContent>
829+
</radix.Tabs>
825830
</$.Body>
826831
),
827832
metas,
@@ -835,7 +840,7 @@ describe("is instance detachable", () => {
835840
isInstanceDetachable({
836841
...renderData(
837842
<$.Body ws:id="body">
838-
<$.Tabs ws:id="tabs"></$.Tabs>
843+
<radix.Tabs ws:id="tabs"></radix.Tabs>
839844
<$.Box ws:id="box"></$.Box>
840845
</$.Body>
841846
),

apps/builder/app/shared/nano-states/components.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import { nanoid } from "nanoid";
22
import { shallowEqual } from "shallow-equal";
33
import type { ExoticComponent } from "react";
44
import { atom, computed } from "nanostores";
5-
import {
6-
type AnyComponent,
7-
type Hook,
8-
type HookContext,
9-
namespaceMeta,
10-
type InstanceData,
5+
import type {
6+
AnyComponent,
7+
Hook,
8+
HookContext,
9+
InstanceData,
1110
} from "@webstudio-is/react-sdk";
1211
import {
1312
getIndexesWithinAncestors,
@@ -210,12 +209,7 @@ export const registerComponentLibrary = ({
210209
const prevMetas = $registeredComponentMetas.get();
211210
const nextMetas = new Map(prevMetas);
212211
for (const [componentName, meta] of Object.entries(metas)) {
213-
nextMetas.set(
214-
`${prefix}${componentName}`,
215-
namespace === undefined
216-
? meta
217-
: namespaceMeta(meta, namespace, new Set(Object.keys(metas)))
218-
);
212+
nextMetas.set(`${prefix}${componentName}`, meta);
219213
}
220214
$registeredComponentMetas.set(nextMetas);
221215

packages/cli/src/framework-react-router.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { join } from "node:path";
22
import { readFile, rm } from "node:fs/promises";
33
import type { WsComponentMeta } from "@webstudio-is/sdk";
4-
import { generateRemixRoute, namespaceMeta } from "@webstudio-is/react-sdk";
4+
import { generateRemixRoute } from "@webstudio-is/react-sdk";
55
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
66
import * as animationComponentMetas from "@webstudio-is/sdk-components-animation/metas";
77
import * as reactRouterComponentMetas from "@webstudio-is/sdk-components-react-router/metas";
@@ -34,21 +34,13 @@ export const createFramework = async (): Promise<Framework> => {
3434
const radixComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
3535
for (const [name, meta] of Object.entries(radixComponentMetas)) {
3636
const namespace = "@webstudio-is/sdk-components-react-radix";
37-
radixComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
38-
meta,
39-
namespace,
40-
new Set(Object.keys(radixComponentMetas))
41-
);
37+
radixComponentNamespacedMetas[`${namespace}:${name}`] = meta;
4238
}
4339

4440
const animationComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
4541
for (const [name, meta] of Object.entries(animationComponentMetas)) {
4642
const namespace = "@webstudio-is/sdk-components-animation";
47-
animationComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
48-
meta as WsComponentMeta,
49-
namespace,
50-
new Set(Object.keys(animationComponentMetas))
51-
);
43+
animationComponentNamespacedMetas[`${namespace}:${name}`] = meta;
5244
}
5345

5446
return {

packages/cli/src/framework-remix.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { join } from "node:path";
22
import { readFile, rm } from "node:fs/promises";
33
import type { WsComponentMeta } from "@webstudio-is/sdk";
4-
import { generateRemixRoute, namespaceMeta } from "@webstudio-is/react-sdk";
4+
import { generateRemixRoute } from "@webstudio-is/react-sdk";
55
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
66
import * as animationComponentMetas from "@webstudio-is/sdk-components-animation/metas";
77
import * as remixComponentMetas from "@webstudio-is/sdk-components-react-remix/metas";
@@ -34,21 +34,13 @@ export const createFramework = async (): Promise<Framework> => {
3434
const radixComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
3535
for (const [name, meta] of Object.entries(radixComponentMetas)) {
3636
const namespace = "@webstudio-is/sdk-components-react-radix";
37-
radixComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
38-
meta,
39-
namespace,
40-
new Set(Object.keys(radixComponentMetas))
41-
);
37+
radixComponentNamespacedMetas[`${namespace}:${name}`] = meta;
4238
}
4339

4440
const animationComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
4541
for (const [name, meta] of Object.entries(animationComponentMetas)) {
4642
const namespace = "@webstudio-is/sdk-components-animation";
47-
animationComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
48-
meta as WsComponentMeta,
49-
namespace,
50-
new Set(Object.keys(animationComponentMetas))
51-
);
43+
animationComponentNamespacedMetas[`${namespace}:${name}`] = meta;
5244
}
5345

5446
return {

packages/cli/src/framework-vike-ssg.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { join } from "node:path";
22
import { readFile, rm } from "node:fs/promises";
33
import type { WsComponentMeta } from "@webstudio-is/sdk";
4-
import { namespaceMeta } from "@webstudio-is/react-sdk";
54
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
65
import * as animationComponentMetas from "@webstudio-is/sdk-components-animation/metas";
76
import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas";
@@ -36,21 +35,13 @@ export const createFramework = async (): Promise<Framework> => {
3635
const radixComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
3736
for (const [name, meta] of Object.entries(radixComponentMetas)) {
3837
const namespace = "@webstudio-is/sdk-components-react-radix";
39-
radixComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
40-
meta,
41-
namespace,
42-
new Set(Object.keys(radixComponentMetas))
43-
);
38+
radixComponentNamespacedMetas[`${namespace}:${name}`] = meta;
4439
}
4540

4641
const animationComponentNamespacedMetas: Record<string, WsComponentMeta> = {};
4742
for (const [name, meta] of Object.entries(animationComponentMetas)) {
4843
const namespace = "@webstudio-is/sdk-components-animation";
49-
animationComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
50-
meta as WsComponentMeta,
51-
namespace,
52-
new Set(Object.keys(animationComponentMetas))
53-
);
44+
animationComponentNamespacedMetas[`${namespace}:${name}`] = meta;
5445
}
5546

5647
return {

packages/react-sdk/src/embed-template.test.tsx

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from "vitest";
2-
import { generateDataFromEmbedTemplate, namespaceMeta } from "./embed-template";
2+
import { generateDataFromEmbedTemplate } from "./embed-template";
33
import { showAttribute } from "./props";
44

55
const expectString = expect.any(String);
@@ -664,31 +664,3 @@ test("generate data for embedding from instance child bound to variables", () =>
664664
resources: [],
665665
});
666666
});
667-
668-
test("add namespace to constants and indexWithinAncestor", () => {
669-
expect(
670-
namespaceMeta(
671-
{
672-
type: "container",
673-
label: "",
674-
icon: "",
675-
constraints: {
676-
relation: "ancestor",
677-
component: { $nin: ["Button", "Box"] },
678-
},
679-
indexWithinAncestor: "Tooltip",
680-
},
681-
"my-namespace",
682-
new Set(["Tooltip", "Button"])
683-
)
684-
).toEqual({
685-
type: "container",
686-
label: "",
687-
icon: "",
688-
constraints: {
689-
relation: "ancestor",
690-
component: { $nin: ["my-namespace:Button", "my-namespace:Box"] },
691-
},
692-
indexWithinAncestor: "my-namespace:Tooltip",
693-
});
694-
});

packages/react-sdk/src/embed-template.ts

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ import type {
88
Breakpoint,
99
DataSource,
1010
WebstudioFragment,
11-
Matcher,
1211
EmbedTemplateVariable,
1312
WsEmbedTemplate,
14-
EmbedTemplateInstance,
1513
WsComponentMeta,
1614
} from "@webstudio-is/sdk";
1715
import {
@@ -275,47 +273,3 @@ export const generateDataFromEmbedTemplate = (
275273
resources: [],
276274
};
277275
};
278-
279-
const namespaceMatcher = (namespace: string, matcher: Matcher) => {
280-
const newMatcher = structuredClone(matcher);
281-
if (newMatcher.component?.$eq) {
282-
newMatcher.component.$eq = `${namespace}:${newMatcher.component.$eq}`;
283-
}
284-
if (newMatcher.component?.$neq) {
285-
newMatcher.component.$neq = `${namespace}:${newMatcher.component.$neq}`;
286-
}
287-
if (newMatcher.component?.$in) {
288-
newMatcher.component.$in = newMatcher.component.$in.map(
289-
(component) => `${namespace}:${component}`
290-
);
291-
}
292-
if (newMatcher.component?.$nin) {
293-
newMatcher.component.$nin = newMatcher.component.$nin.map(
294-
(component) => `${namespace}:${component}`
295-
);
296-
}
297-
return newMatcher;
298-
};
299-
300-
export const namespaceMeta = (
301-
meta: WsComponentMeta,
302-
namespace: string,
303-
components: Set<EmbedTemplateInstance["component"]>
304-
) => {
305-
const newMeta = { ...meta };
306-
if (newMeta.constraints) {
307-
if (Array.isArray(newMeta.constraints)) {
308-
newMeta.constraints = newMeta.constraints.map((matcher) =>
309-
namespaceMatcher(namespace, matcher)
310-
);
311-
} else {
312-
newMeta.constraints = namespaceMatcher(namespace, newMeta.constraints);
313-
}
314-
}
315-
if (newMeta.indexWithinAncestor) {
316-
newMeta.indexWithinAncestor = components.has(newMeta.indexWithinAncestor)
317-
? `${namespace}:${newMeta.indexWithinAncestor}`
318-
: newMeta.indexWithinAncestor;
319-
}
320-
return newMeta;
321-
};

packages/sdk-cli/src/generate-stories.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ import {
1313
coreMetas,
1414
generateCss,
1515
} from "@webstudio-is/sdk";
16-
import {
17-
generateWebstudioComponent,
18-
namespaceMeta,
19-
} from "@webstudio-is/react-sdk";
16+
import { generateWebstudioComponent } from "@webstudio-is/react-sdk";
2017
import { renderTemplate, type TemplateMeta } from "@webstudio-is/template";
2118

2219
const WS_NAMESPACE = "ws";
@@ -150,17 +147,13 @@ export const generateStories = async () => {
150147
);
151148
namespaceMetas = new Map(Object.entries(await import(metasUrl)));
152149
}
153-
for (let [name, meta] of namespaceMetas) {
150+
for (const [name, meta] of namespaceMetas) {
151+
let prefixedName = name;
154152
if (namespace !== BASE_NAMESPACE && namespace !== WS_NAMESPACE) {
155-
name = `${namespace}:${name}`;
156-
meta = namespaceMeta(
157-
meta as WsComponentMeta,
158-
namespace,
159-
new Set(metas.keys())
160-
);
153+
prefixedName = `${namespace}:${name}`;
161154
}
162-
if (components.has(name)) {
163-
usedMetas.set(name, meta as WsComponentMeta);
155+
if (components.has(prefixedName)) {
156+
usedMetas.set(prefixedName, meta as WsComponentMeta);
164157
}
165158
}
166159
}

packages/sdk-components-animation/src/animate-text.ws.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { TextAnimationIcon } from "@webstudio-is/icons/svg";
22
import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk";
3+
import { animation } from "./shared/meta";
34
import { props } from "./__generated__/animate-text.props";
45

56
export const meta: WsComponentMeta = {
@@ -11,7 +12,7 @@ export const meta: WsComponentMeta = {
1112
order: 6,
1213
label: "Text Animation",
1314
constraints: [
14-
{ relation: "parent", component: { $eq: "AnimateChildren" } },
15+
{ relation: "parent", component: { $eq: animation.AnimateChildren } },
1516
{
1617
relation: "child",
1718
text: false,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const createMetaProxy = (prefix: string): Record<string, string> => {
2+
return new Proxy(
3+
{},
4+
{
5+
get(_target, prop) {
6+
return `${prefix}${prop as string}`;
7+
},
8+
}
9+
);
10+
};
11+
12+
export const animation = createMetaProxy(
13+
"@webstudio-is/sdk-components-animation:"
14+
);

0 commit comments

Comments
 (0)