Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/rename-client-react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"stack-effect": patch
---

rename `client` target kind to `client-react` and prefix client module IDs with `react`

- `http-api-client` becomes `http-api-react-client`
- `http-rpc-client` becomes `http-rpc-react-client`
- `ws-presence-client` becomes `ws-presence-react-client`
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ bun run start -- init smoke-app --yes --root "$TMP_REPO"
bun run start -- add --yes --root "$TMP_REPO" --target package/domain --modules domain-api --dry-run

# 3) Optional negative test: cross-target implication should fail in non-interactive mode
bun run start -- add --yes --root "$TMP_REPO" --target client/web --modules http-api-client --dry-run
bun run start -- add --yes --root "$TMP_REPO" --target client-react/web --modules http-api-react-client --dry-run
```

Notes:
Expand Down
8 changes: 4 additions & 4 deletions apps/cli/e2e/add.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ describe("add", () => {
"--root",
root,
"--target",
"client/web",
"client-react/web",
"--modules",
"http-api-client",
"http-api-react-client",
);
yield* cli.expectExitCode(1);
yield* cli.expectOutputContaining("implies");
Expand Down Expand Up @@ -140,9 +140,9 @@ describe("add", () => {
"--root",
root,
"--target",
"client/web",
"client-react/web",
"--modules",
"http-api-client",
"http-api-react-client",
"--dry-run",
);
yield* cli.expectExitCode(0);
Expand Down
10 changes: 5 additions & 5 deletions apps/cli/e2e/matrix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface MatrixEntry {
*/
const defaultTargetNames = new Map([
["server", "api"],
["client", "web"],
["client-react", "web"],
["cli", "app"],
["package", "domain"], // fallback; overridden by identity modules
]);
Expand Down Expand Up @@ -105,7 +105,7 @@ const matrix = Effect.runSync(

// Separate entries that have cross-target implications (client modules)
const singleTargetEntries = matrix.filter(
(e) => !e.target.startsWith("client"),
(e) => !e.target.startsWith("client-react"),
);

// ---------------------------------------------------------------------------
Expand All @@ -116,7 +116,7 @@ const buildFullStackMatrix = Effect.gen(function* () {
const catalog = yield* CatalogService;

const clientModules = yield* catalog.getSupportedModules(
TargetKind.make("client"),
TargetKind.make("client-react"),
);

return Arr.map(clientModules, (clientMod) => {
Expand All @@ -132,7 +132,7 @@ const buildFullStackMatrix = Effect.gen(function* () {
label: `full-stack: ${clientMod.id} → server [${serverModuleIds.join(", ")}]`,
serverTarget: `server/${defaultTargetNames.get("server")}`,
serverModules: serverModuleIds,
clientTarget: `client/${defaultTargetNames.get("client")}`,
clientTarget: `client-react/${defaultTargetNames.get("client-react")}`,
clientModules: [clientMod.id],
};
}
Expand Down Expand Up @@ -279,7 +279,7 @@ describe("matrix", () => {
"--root",
root,
"--target",
`client/${defaultTargetNames.get("client")}`,
`client-react/${defaultTargetNames.get("client-react")}`,
"--modules",
allClientModules.join(","),
);
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/commands/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface CollectedTarget {
const targetFlag = Flag.string("target").pipe(
Flag.optional,
Flag.withDescription(
"Target identity as <targetKind>/<targetName>, e.g. client/web",
"Target identity as <targetKind>/<targetName>, e.g. client-react/web",
),
);

Expand Down
16 changes: 8 additions & 8 deletions packages/catalog/src/registry/modules/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ import {
*/
export const clientModules: ReadonlyArray<typeof ModuleDefinition.Type> = [
{
id: ModuleId.make("http-api-client"),
id: ModuleId.make("http-api-react-client"),
title: "HTTP API Client",
description: "REST API client with Effect Atom and typed HttpApiClient",
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client") }],
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client-react") }],
dependencies: [
{
_tag: "required-module",
Expand Down Expand Up @@ -89,10 +89,10 @@ export const clientModules: ReadonlyArray<typeof ModuleDefinition.Type> = [
],
},
{
id: ModuleId.make("http-rpc-client"),
id: ModuleId.make("http-rpc-react-client"),
title: "HTTP RPC Client",
description: "RPC streaming client with tick atom and UI",
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client") }],
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client-react") }],
dependencies: [
{
_tag: "required-module",
Expand Down Expand Up @@ -155,10 +155,10 @@ export const clientModules: ReadonlyArray<typeof ModuleDefinition.Type> = [
],
},
{
id: ModuleId.make("chat-client"),
id: ModuleId.make("chat-react-client"),
title: "Chat Client",
description: "AI chat UI with streaming, tool calls, and state machine",
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client") }],
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client-react") }],
dependencies: [
{
_tag: "required-module",
Expand Down Expand Up @@ -225,10 +225,10 @@ export const clientModules: ReadonlyArray<typeof ModuleDefinition.Type> = [
],
},
{
id: ModuleId.make("ws-presence-client"),
id: ModuleId.make("ws-presence-react-client"),
title: "WebSocket Presence Client",
description: "Real-time presence UI with WebSocket RPC",
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client") }],
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client-react") }],
dependencies: [
{
_tag: "required-module",
Expand Down
4 changes: 2 additions & 2 deletions packages/catalog/src/registry/modules/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { configTypescriptViteContents } from "../content/client";
*/
export const configModules: ReadonlyArray<typeof ModuleDefinition.Type> = [
{
id: ModuleId.make("config-typescript-vite"),
id: ModuleId.make("config-typescript-react-vite"),
title: "Config TypeScript Vite",
description: "Vite TypeScript preset for client applications",
visibility: "internal",
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client") }],
supportedOn: [{ _tag: "kind", kind: TargetKind.make("client-react") }],
dependencies: [],
contributions: [
{
Expand Down
8 changes: 4 additions & 4 deletions packages/catalog/src/registry/targetRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ export const targetRegistry: ReadonlyArray<typeof TargetDefinition.Type> = [
},

{
kind: TargetKind.make("client"),
title: "Client Application",
description: "A frontend application, such as one built with React or Vue",
requiredModules: [ModuleId.make("config-typescript-vite")],
kind: TargetKind.make("client-react"),
title: "Client React Application",
description: "A frontend application built with React",
requiredModules: [ModuleId.make("config-typescript-react-vite")],
contributions: [
// Files
{
Expand Down
2 changes: 1 addition & 1 deletion packages/domain/src/Blueprint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe("@repo/domain Blueprint", () => {
identity.matches({
_tag: "identity",
identity: new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "api",
}),
}),
Expand Down
18 changes: 9 additions & 9 deletions packages/domain/src/Scaffold.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ describe("@repo/domain Scaffold", () => {
name: "api",
});
const clientIdentity = Schema.decodeUnknownSync(TargetIdentity)({
kind: "client",
kind: "client-react",
name: "admin-ui",
});

expect(packageIdentity.toKey()).toBe("packages/domain");
expect(packageIdentity.toPath()).toBe("packages/domain");
expect(serverIdentity.toKey()).toBe("apps/server-api");
expect(clientIdentity.toPath()).toBe("apps/client-admin-ui");
expect(clientIdentity.toPath()).toBe("apps/client-react-admin-ui");
});

it("accepts empty target names for apps (uses kind only)", () => {
Expand Down Expand Up @@ -66,12 +66,12 @@ describe("@repo/domain Scaffold", () => {

it("slugifies names with underscores into canonical keys and paths", () => {
const identity = Schema.decodeUnknownSync(TargetIdentity)({
kind: "client",
kind: "client-react",
name: "admin_ui",
});

expect(identity.toKey()).toBe("apps/client-admin-ui");
expect(identity.toPath()).toBe("apps/client-admin-ui");
expect(identity.toKey()).toBe("apps/client-react-admin-ui");
expect(identity.toPath()).toBe("apps/client-react-admin-ui");
});

it("normalizes surrounding whitespace before deriving canonical keys and paths", () => {
Expand Down Expand Up @@ -99,12 +99,12 @@ describe("@repo/domain Scaffold", () => {
name: "api",
});
const clientIdentity = Schema.decodeUnknownSync(TargetIdentity)({
kind: "client",
kind: "client-react",
name: "web",
});

expect(serverIdentity.toPackageName()).toBe("server-api");
expect(clientIdentity.toPackageName()).toBe("client-web");
expect(clientIdentity.toPackageName()).toBe("client-react-web");
});

it("returns just kind for apps without names", () => {
Expand All @@ -113,12 +113,12 @@ describe("@repo/domain Scaffold", () => {
name: "",
});
const clientIdentity = Schema.decodeUnknownSync(TargetIdentity)({
kind: "client",
kind: "client-react",
name: "",
});

expect(serverIdentity.toPackageName()).toBe("server");
expect(clientIdentity.toPackageName()).toBe("client");
expect(clientIdentity.toPackageName()).toBe("client-react");
});

it("slugifies package names", () => {
Expand Down
26 changes: 14 additions & 12 deletions packages/scaffold/src/service/blueprint/BlueprintService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ describe("BlueprintService", () => {
},
{
identity: new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "api",
}),
modules: [],
Expand All @@ -258,7 +258,7 @@ describe("BlueprintService", () => {
.filter((node) => node._tag === "target")
.map((node) => node.id),
).toEqual([
"apps/client-api",
"apps/client-react-api",
"apps/server-api",
"packages/domain",
]);
Expand All @@ -274,10 +274,12 @@ describe("BlueprintService", () => {
targets: [
{
identity: new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "app",
}),
modules: [{ id: ModuleId.make("config-typescript-vite") }],
modules: [
{ id: ModuleId.make("config-typescript-react-vite") },
],
},
],
});
Expand All @@ -287,16 +289,16 @@ describe("BlueprintService", () => {
blueprint,
toAttachedModuleNodeId(
new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "app",
}).toKey(),
ModuleId.make("config-typescript-vite"),
ModuleId.make("config-typescript-react-vite"),
),
),
).toMatchObject({
_tag: "attached-module",
targetId: "apps/client-app",
moduleId: "config-typescript-vite",
targetId: "apps/client-react-app",
moduleId: "config-typescript-react-vite",
});
}),
);
Expand All @@ -307,7 +309,7 @@ describe("BlueprintService", () => {
Effect.gen(function* () {
const blueprintService = yield* BlueprintService;
const identity = new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "required",
});
const blueprint = yield* blueprintService.resolve({
Expand All @@ -319,13 +321,13 @@ describe("BlueprintService", () => {
blueprint,
toAttachedModuleNodeId(
identity.toKey(),
ModuleId.make("config-typescript-vite"),
ModuleId.make("config-typescript-react-vite"),
),
),
).toMatchObject({
_tag: "attached-module",
targetId: "apps/client-required",
moduleId: "config-typescript-vite",
targetId: "apps/client-react-required",
moduleId: "config-typescript-react-vite",
});
}),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const serverIdentity = new TargetIdentity({
});

const clientIdentity = new TargetIdentity({
kind: TargetKind.make("client"),
kind: TargetKind.make("client-react"),
name: "web",
});

Expand Down
Loading