@sjcx/vorma 0.0.0-pre.3 → 0.0.0-pre.4

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/build/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as projectBrowserContracts, S as getClientViewEntries, _ as createCssPublicAssets, a as acquireOutputOwnership, b as toContentDigest, c as writeAndCheckApplicationGeneration, d as readTypescriptProjectRoots, f as runTypescriptOperation, g as containsRelativePath, h as resolveVormaConfig, i as publishApplicationArtifacts, l as collectPublicAssets, m as getGeneratedSourceDirectories, n as loadApplicationSourceLayout, o as checkOutputPath, p as withTypescriptProjects, r as preparePublicOutput, s as assembleApplicationGeneration, t as buildApplication, u as inspectProjects, v as createClientPublicUrlPlugin, x as CLIENT_SHARED_PACKAGES, y as encodeCanonicalJson } from "../build-sHSh5zaX.js";
2
+ import { C as projectBrowserContracts, S as getClientViewEntries, _ as createCssPublicAssets, a as acquireOutputOwnership, b as toContentDigest, c as writeAndCheckApplicationGeneration, d as readTypescriptProjectRoots, f as runTypescriptOperation, g as containsRelativePath, h as resolveVormaConfig, i as publishApplicationArtifacts, l as collectPublicAssets, m as getGeneratedSourceDirectories, n as loadApplicationSourceLayout, o as checkOutputPath, p as withTypescriptProjects, r as preparePublicOutput, s as assembleApplicationGeneration, t as buildApplication, u as inspectProjects, v as createClientPublicUrlPlugin, x as CLIENT_SHARED_PACKAGES, y as encodeCanonicalJson } from "../build-BeUTL6eX.js";
3
3
  import { t as VORMA_BUILD_PLUGIN_NAME } from "../build-invocation-D7Fu8gBK.js";
4
4
  import { NodeChildProcessSpawner, NodeCrypto, NodeFileSystem, NodePath, NodeRuntime, NodeSocketServer, NodeStdio, NodeTerminal } from "@effect/platform-node-shared";
5
5
  import { Cause, Console, Deferred, Effect, Exit, Fiber, FileSystem, Layer, Path, Queue, Result, Schedule, Schema, ScopedRef, Stream } from "effect";
@@ -310,7 +310,10 @@ function startDevelopmentClient(inputs, port, recordChangeFn) {
310
310
  return new RegExp(`^${normalizePath(file).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:\\?.*)?$`);
311
311
  })]
312
312
  },
313
- optimizeDeps: { entries: [inputs.clientEntryFilePath, ...inputs.clientViewModules] },
313
+ optimizeDeps: {
314
+ exclude: [FRAMEWORK_IDENTITY_PROTOCOL.moduleSpecifiers.clientTransportTypes],
315
+ entries: [inputs.clientEntryFilePath, ...inputs.clientViewModules]
316
+ },
314
317
  server: {
315
318
  middlewareMode: true,
316
319
  origin: listener.origin,
@@ -572,7 +575,10 @@ function prepareDevelopmentGeneration(input) {
572
575
  inspection: prepared.sources.inspection,
573
576
  publicAssets: prepared.publicAssets
574
577
  });
575
- if (previous === void 0 || previous.work.inspectSources || previous.work.capturePublicAssets) yield* writeAndCheckApplicationGeneration(application);
578
+ if (previous === void 0 || previous.work.inspectSources || previous.work.capturePublicAssets) yield* writeAndCheckApplicationGeneration(application, previous === void 0 || previous.work.inspectSources ? {
579
+ server: prepared.sources.inputs.serverRootFiles,
580
+ client: prepared.sources.inputs.clientRootFiles
581
+ } : void 0);
576
582
  return {
577
583
  application,
578
584
  sources: prepared.sources.inputs
@@ -630,10 +636,12 @@ function getDevelopmentServerPort() {
630
636
  return address.port;
631
637
  }));
632
638
  }
633
- /** Runs the authored server entry; its Effect scope owns process termination. */
639
+ /** Runs the configured server command; its Effect scope owns process termination. */
634
640
  function startDevelopmentServerProcess(input) {
635
641
  return Effect.gen(function* () {
636
- const process = yield* ChildProcess.make(globalThis.process.execPath, ["--enable-source-maps", input.layout.serverEntryFilePath], {
642
+ const [executable, ...args] = input.command;
643
+ const process = yield* ChildProcess.make(executable, args, {
644
+ cwd: input.configDirectory,
637
645
  env: { [DEVELOPMENT_PROTOCOL.serverPortEnvironmentVariable]: String(input.port) },
638
646
  extendEnv: true,
639
647
  stdin: "ignore",
@@ -818,6 +826,7 @@ function classifyDevelopmentChanges(input) {
818
826
  let restartConfiguration = false;
819
827
  let inspectSources = false;
820
828
  let restartServer = false;
829
+ let restartVite = false;
821
830
  let capturePublicAssets = false;
822
831
  let prepareCriticalCss = false;
823
832
  let revalidateClient = false;
@@ -830,6 +839,7 @@ function classifyDevelopmentChanges(input) {
830
839
  const resolutionSource = inputs.sources.resolutionFiles.has(filePath);
831
840
  inspectSources ||= serverSource || clientSource || resolutionSource;
832
841
  restartServer ||= serverSource || resolutionSource;
842
+ restartVite ||= resolutionSource;
833
843
  capturePublicAssets ||= containsFilePath({
834
844
  path,
835
845
  directory: layout.publicAssetsSourceDirectory,
@@ -855,6 +865,7 @@ function classifyDevelopmentChanges(input) {
855
865
  restartConfiguration,
856
866
  inspectSources,
857
867
  restartServer,
868
+ restartVite,
858
869
  capturePublicAssets,
859
870
  prepareCriticalCss: layout.criticalCssEntryFilePath !== void 0 && (prepareCriticalCss || capturePublicAssets),
860
871
  revalidateClient
@@ -890,8 +901,16 @@ function loadDevelopmentConfig(configPath) {
890
901
  };
891
902
  }
892
903
  });
904
+ const config = yield* Schema.decodeUnknownEffect(VormaConfigSchema)(loaded?.config);
905
+ if (config.dev === void 0) return yield* Effect.fail({
906
+ _tag: "ConfigLoadError",
907
+ message: "vorma dev requires dev.serverCommand in the Vorma configuration"
908
+ });
893
909
  return {
894
- config: yield* Schema.decodeUnknownEffect(VormaConfigSchema)(loaded?.config),
910
+ config: {
911
+ ...config,
912
+ dev: config.dev
913
+ },
895
914
  configFilePath,
896
915
  dependencies: loaded?.dependencies ?? []
897
916
  };
@@ -984,7 +1003,6 @@ function runDevelopmentSession(input) {
984
1003
  yield* input.watcher.watchPathsFn({
985
1004
  paths: [
986
1005
  ...input.loaded.dependencies,
987
- path.dirname(resolved.serverEntryFilePath),
988
1006
  path.dirname(resolved.clientEntryFilePath),
989
1007
  path.dirname(resolved.serverTsconfigFilePath),
990
1008
  path.dirname(resolved.clientTsconfigFilePath),
@@ -1056,7 +1074,8 @@ function runDevelopmentSession(input) {
1056
1074
  };
1057
1075
  const fiber = yield* Effect.scoped(Effect.gen(function* () {
1058
1076
  const server = yield* startDevelopmentServerProcess({
1059
- layout,
1077
+ command: input.loaded.config.dev.serverCommand,
1078
+ configDirectory: layout.configDirectory,
1060
1079
  port: input.port
1061
1080
  });
1062
1081
  announced = true;
@@ -1173,8 +1192,8 @@ function runDevelopmentSession(input) {
1173
1192
  client,
1174
1193
  developmentHeadHtml: head
1175
1194
  });
1176
- const restartVite = work.restartServer || JSON.stringify(previousArtifacts.metadata.clientViews) !== JSON.stringify(nextArtifacts.metadata.clientViews);
1177
- const reload = restartVite || previousArtifacts.metadata.clientBuildId !== nextArtifacts.metadata.clientBuildId;
1195
+ const restartVite = work.restartVite || JSON.stringify(previousArtifacts.metadata.clientViews) !== JSON.stringify(nextArtifacts.metadata.clientViews);
1196
+ const reload = work.restartServer || restartVite || previousArtifacts.metadata.clientBuildId !== nextArtifacts.metadata.clientBuildId;
1178
1197
  yield* publishApplicationArtifacts({
1179
1198
  generation: next.generation.application,
1180
1199
  artifacts: nextArtifacts
@@ -1,5 +1,4 @@
1
1
  import { Effect } from "effect";
2
- import type { ApplicationSourceLayout } from "./source-layout.ts";
3
2
  export type DevelopmentServerExit = {
4
3
  readonly _tag: "DevelopmentServerExit";
5
4
  readonly exitCode: number;
@@ -10,9 +9,10 @@ export type DevelopmentServerReadinessIssue = {
10
9
  };
11
10
  /** Reserves a port until the enclosing allocation scope closes. */
12
11
  export declare function getDevelopmentServerPort(): Effect.Effect<number, import("effect/unstable/socket/SocketServer").SocketServerError, import("effect/Scope").Scope>;
13
- /** Runs the authored server entry; its Effect scope owns process termination. */
12
+ /** Runs the configured server command; its Effect scope owns process termination. */
14
13
  export declare function startDevelopmentServerProcess(input: {
15
- readonly layout: ApplicationSourceLayout;
14
+ readonly command: readonly [string, ...Array<string>];
15
+ readonly configDirectory: string;
16
16
  readonly port: number;
17
17
  }): Effect.Effect<{
18
18
  process: import("effect/unstable/process/ChildProcessSpawner").ChildProcessHandle;
@@ -6,6 +6,7 @@ export type DevelopmentWork = {
6
6
  readonly restartConfiguration: boolean;
7
7
  readonly inspectSources: boolean;
8
8
  readonly restartServer: boolean;
9
+ readonly restartVite: boolean;
9
10
  readonly capturePublicAssets: boolean;
10
11
  readonly prepareCriticalCss: boolean;
11
12
  readonly revalidateClient: boolean;
@@ -25,6 +26,7 @@ export declare function classifyDevelopmentChanges(input: {
25
26
  restartConfiguration: boolean;
26
27
  inspectSources: boolean;
27
28
  restartServer: boolean;
29
+ restartVite: boolean;
28
30
  capturePublicAssets: boolean;
29
31
  prepareCriticalCss: boolean;
30
32
  revalidateClient: boolean;
@@ -7,7 +7,7 @@ import { type PublicAssetIssue, type PublicAssetProjection } from "./public-asse
7
7
  import type { GeneratedSource } from "./render-source-text.ts";
8
8
  import type { ConfigResolutionError } from "./resolve-config.ts";
9
9
  import type { ApplicationSourceLayout, ApplicationSourceLayoutIssues } from "./source-layout.ts";
10
- import { type TypescriptProjectError } from "./typescript-projects.ts";
10
+ import { type TypescriptProjectRoots, type TypescriptProjectError } from "./typescript-projects.ts";
11
11
  export type ApplicationModelIssues = {
12
12
  readonly _tag: "ApplicationModelIssues";
13
13
  readonly issues: ReadonlyArray<ApplicationModelIssue>;
@@ -36,7 +36,7 @@ export type ApplicationGeneration = {
36
36
  readonly publicAssets: PublicAssetProjection;
37
37
  };
38
38
  /** Writes correlated generated sources and verifies their native TypeScript inclusion. */
39
- export declare function writeAndCheckApplicationGeneration(generation: ApplicationGeneration): Effect.Effect<void, GeneratedApplicationWriteError | TypescriptProjectError, FileSystem.FileSystem | Path.Path>;
39
+ export declare function writeAndCheckApplicationGeneration(generation: ApplicationGeneration, knownRootFiles?: TypescriptProjectRoots): Effect.Effect<void, GeneratedApplicationWriteError | TypescriptProjectError, FileSystem.FileSystem | Path.Path>;
40
40
  /** Reads both projects through the checker, captures public assets, and prepares generated build inputs without publishing them. */
41
41
  export declare function prepareApplicationGeneration(sourceLayout: ApplicationSourceLayout): Effect.Effect<ApplicationGeneration, ApplicationGenerationError, FileSystem.FileSystem | Path.Path>;
42
42
  /** Reads declarations and public URL call sites independently of public asset hashing. */
@@ -1,2 +1,2 @@
1
- import { t as buildApplication } from "../build-sHSh5zaX.js";
1
+ import { t as buildApplication } from "../build-BeUTL6eX.js";
2
2
  export { buildApplication };
@@ -2,30 +2,33 @@ import { Effect, Path, Schema } from "effect";
2
2
  type ConfigLoadError = {
3
3
  readonly _tag: "ConfigLoadError";
4
4
  readonly message: string;
5
- readonly cause: unknown;
5
+ readonly cause?: unknown;
6
6
  };
7
7
  /** Vite's configuration loader recompiles configuration dependencies on each development restart. */
8
8
  export declare function loadDevelopmentConfig(configPath: string): Effect.Effect<{
9
9
  config: {
10
- readonly importMeta: {
10
+ importMeta: {
11
11
  readonly url: string;
12
12
  };
13
- readonly serverEntry: string;
14
- readonly serverTsconfigFile: string;
15
- readonly clientEntry: string;
16
- readonly clientTsconfigFile: string;
17
- readonly publicAssetsDir: string;
18
- readonly viteConfigFile: string;
19
- readonly criticalCssEntry?: string;
20
- readonly publicAssetsBasePath: string;
21
- readonly bodySsr?: boolean;
22
- readonly dev?: {
13
+ serverTsconfigFile: string;
14
+ clientEntry: string;
15
+ clientTsconfigFile: string;
16
+ publicAssetsDir: string;
17
+ viteConfigFile: string;
18
+ criticalCssEntry?: string;
19
+ publicAssetsBasePath: string;
20
+ bodySsr?: boolean;
21
+ dev: {
22
+ readonly serverCommand: readonly [string, ...string[]];
23
23
  readonly revalidateClientOnChange?: readonly string[];
24
24
  };
25
25
  };
26
26
  configFilePath: string;
27
27
  dependencies: string[];
28
- }, ConfigLoadError | Schema.SchemaError, Path.Path>;
28
+ }, ConfigLoadError | Schema.SchemaError | {
29
+ _tag: "ConfigLoadError";
30
+ message: string;
31
+ }, Path.Path>;
29
32
  /**
30
33
  * Imports the explicitly selected configuration using the CLI host's module
31
34
  * loader and reports the absolute path of the file it was loaded from,
@@ -36,7 +39,6 @@ export declare function loadVormaConfig(configPath: string): Effect.Effect<{
36
39
  readonly importMeta: {
37
40
  readonly url: string;
38
41
  };
39
- readonly serverEntry: string;
40
42
  readonly serverTsconfigFile: string;
41
43
  readonly clientEntry: string;
42
44
  readonly clientTsconfigFile: string;
@@ -46,6 +48,7 @@ export declare function loadVormaConfig(configPath: string): Effect.Effect<{
46
48
  readonly publicAssetsBasePath: string;
47
49
  readonly bodySsr?: boolean;
48
50
  readonly dev?: {
51
+ readonly serverCommand: readonly [string, ...string[]];
49
52
  readonly revalidateClientOnChange?: readonly string[];
50
53
  };
51
54
  };
@@ -6,7 +6,6 @@ export type ResolvedVormaConfig = {
6
6
  readonly configFilePath: string;
7
7
  /** The directory of the configuration file; every configured path is relative to it. */
8
8
  readonly configDirectory: string;
9
- readonly serverEntryFilePath: string;
10
9
  readonly serverTsconfigFilePath: string;
11
10
  /** The directory containing the server tsconfig, used as the compiler's working directory. */
12
11
  readonly serverProjectDirectory: string;
@@ -27,13 +26,13 @@ export type VormaOwnedPaths = {
27
26
  readonly generatedRegistrationFilePath: string;
28
27
  readonly generatedServerContractsFilePath: string;
29
28
  };
30
- /** The build reads no Vorma directory, in either entry directory, as application source. */
29
+ /** The build excludes both projects' generated directories from application source. */
31
30
  export declare function getGeneratedSourceDirectories(config: VormaOwnedPaths): ReadonlyArray<string>;
32
- /** Derives generated source, public assets, and build coordination from the entry directories. */
31
+ /** Derives generated source, public assets, and build coordination from the tsconfig directories. */
33
32
  export declare function getVormaOwnedPaths(input: {
34
33
  readonly path: Path.Path;
35
- readonly serverEntryDirectory: string;
36
- readonly clientEntryDirectory: string;
34
+ readonly serverProjectDirectory: string;
35
+ readonly clientProjectDirectory: string;
37
36
  }): VormaOwnedPaths;
38
37
  export type ConfigResolutionError = {
39
38
  readonly _tag: "ConfigResolutionError";
@@ -6,7 +6,7 @@ declare const APPLICATION_SOURCE_LAYOUT_BRAND: unique symbol;
6
6
  export type ApplicationSourceLayout = ResolvedVormaConfig & {
7
7
  readonly [APPLICATION_SOURCE_LAYOUT_BRAND]: true;
8
8
  };
9
- export type ApplicationSourcePathField = "serverEntry" | "serverTsconfigFile" | "clientEntry" | "clientTsconfigFile" | "publicAssetsDir" | "viteConfigFile" | "criticalCssEntry";
9
+ export type ApplicationSourcePathField = "serverTsconfigFile" | "clientEntry" | "clientTsconfigFile" | "publicAssetsDir" | "viteConfigFile" | "criticalCssEntry";
10
10
  export type ApplicationSourceLayoutIssue = {
11
11
  readonly field: ApplicationSourcePathField;
12
12
  readonly path: string;
@@ -9,6 +9,10 @@ export type TypescriptProjects = {
9
9
  readonly server: Project;
10
10
  readonly client: Project;
11
11
  };
12
+ export type TypescriptProjectRoots = {
13
+ readonly server: ReadonlySet<string>;
14
+ readonly client: ReadonlySet<string>;
15
+ };
12
16
  /** Reads native project membership without loading programs or declaration types. */
13
17
  export declare function readTypescriptProjectRoots(input: {
14
18
  readonly configDirectory: string;
@@ -25,6 +29,7 @@ export declare function checkGeneratedTypeInclusion(input: {
25
29
  readonly clientTsconfigFilePath: string;
26
30
  readonly serverFiles: ReadonlyArray<string>;
27
31
  readonly clientFiles: ReadonlyArray<string>;
32
+ readonly knownRootFiles?: TypescriptProjectRoots;
28
33
  }): Effect.Effect<void, TypescriptProjectError>;
29
34
  /** Opens the two configured TypeScript projects for the duration of `useFn`, then closes the checker session. */
30
35
  export declare function withTypescriptProjects<A, E, R>(input: {
@@ -1,6 +1,6 @@
1
1
  import { t as VORMA_BUILD_PLUGIN_NAME } from "./build-invocation-D7Fu8gBK.js";
2
2
  import { Effect, FileSystem, Option, Record, Result, Schema } from "effect";
3
- import { build } from "vite";
3
+ import { build, normalizePath } from "vite";
4
4
  import { blake3 } from "@noble/hashes/blake3.js";
5
5
  import { utf8ToBytes } from "@noble/hashes/utils.js";
6
6
  import { base32nopad } from "@scure/base";
@@ -686,16 +686,16 @@ async function createTypeRenderer(input) {
686
686
  }
687
687
  //#endregion
688
688
  //#region src/build/resolve-config.ts
689
- /** The build reads no Vorma directory, in either entry directory, as application source. */
689
+ /** The build excludes both projects' generated directories from application source. */
690
690
  function getGeneratedSourceDirectories(config) {
691
691
  return [config.serverGeneratedDirectory, config.clientGeneratedDirectory];
692
692
  }
693
- /** Derives generated source, public assets, and build coordination from the entry directories. */
693
+ /** Derives generated source, public assets, and build coordination from the tsconfig directories. */
694
694
  function getVormaOwnedPaths(input) {
695
695
  const { path } = input;
696
696
  const name = ARTIFACT_PROTOCOL.vormaDirectoryName;
697
- const clientGeneratedDirectory = path.join(input.clientEntryDirectory, name);
698
- const serverGeneratedDirectory = path.join(input.serverEntryDirectory, name);
697
+ const clientGeneratedDirectory = path.join(input.clientProjectDirectory, name);
698
+ const serverGeneratedDirectory = path.join(input.serverProjectDirectory, name);
699
699
  return {
700
700
  publicDirectory: path.join(clientGeneratedDirectory, ARTIFACT_PROTOCOL.publicDirectoryName),
701
701
  ignoreFilePaths: [.../* @__PURE__ */ new Set([serverGeneratedDirectory, clientGeneratedDirectory])].map((directory) => path.join(directory, ARTIFACT_PROTOCOL.ignoreFileName)),
@@ -728,14 +728,12 @@ function resolveVormaConfig(input) {
728
728
  message: `configFilePath must be absolute, got ${JSON.stringify(input.configFilePath)}`
729
729
  });
730
730
  const configDirectory = path.dirname(path.normalize(input.configFilePath));
731
- const serverEntryFilePath = path.resolve(configDirectory, config.serverEntry);
732
731
  const serverTsconfigFilePath = path.resolve(configDirectory, config.serverTsconfigFile);
733
732
  const clientEntryFilePath = path.resolve(configDirectory, config.clientEntry);
734
733
  const clientTsconfigFilePath = path.resolve(configDirectory, config.clientTsconfigFile);
735
734
  return {
736
735
  configFilePath: path.normalize(input.configFilePath),
737
736
  configDirectory,
738
- serverEntryFilePath,
739
737
  serverTsconfigFilePath,
740
738
  serverProjectDirectory: path.dirname(serverTsconfigFilePath),
741
739
  clientEntryFilePath,
@@ -748,8 +746,8 @@ function resolveVormaConfig(input) {
748
746
  dev: config.dev,
749
747
  ...getVormaOwnedPaths({
750
748
  path,
751
- serverEntryDirectory: path.dirname(serverEntryFilePath),
752
- clientEntryDirectory: path.dirname(clientEntryFilePath)
749
+ serverProjectDirectory: path.dirname(serverTsconfigFilePath),
750
+ clientProjectDirectory: path.dirname(clientTsconfigFilePath)
753
751
  })
754
752
  };
755
753
  });
@@ -790,6 +788,9 @@ function readTypescriptProjectRoots(input) {
790
788
  }
791
789
  /** Checks actual compiler membership after generation, including restrictive files/include/exclude settings. */
792
790
  function checkGeneratedTypeInclusion(input) {
791
+ const serverFiles = input.serverFiles.filter((file) => !input.knownRootFiles?.server.has(normalizePath(file)));
792
+ const clientFiles = input.clientFiles.filter((file) => !input.knownRootFiles?.client.has(normalizePath(file)));
793
+ if (serverFiles.length === 0 && clientFiles.length === 0) return Effect.void;
793
794
  return withTypescriptProjects({
794
795
  ...input,
795
796
  useFn: (projects) => {
@@ -798,11 +799,11 @@ function checkGeneratedTypeInclusion(input) {
798
799
  const missing = [];
799
800
  for (const [project, files, config] of [[
800
801
  projects.server,
801
- input.serverFiles,
802
+ serverFiles,
802
803
  input.serverTsconfigFilePath
803
804
  ], [
804
805
  projects.client,
805
- input.clientFiles,
806
+ clientFiles,
806
807
  input.clientTsconfigFilePath
807
808
  ]]) for (const file of files) if (await project.program.getSourceFileMetadata(file) === void 0) missing.push({
808
809
  project: config,
@@ -812,7 +813,7 @@ function checkGeneratedTypeInclusion(input) {
812
813
  });
813
814
  return yield* missing.length === 0 ? Effect.void : Effect.fail({
814
815
  _tag: "TypescriptProjectError",
815
- message: missing.map(({ project, file }) => `${project} does not include generated type file ${file}. Include the entry's _vorma directory in that TypeScript project.`).join("\n")
816
+ message: missing.map(({ project, file }) => `${project} does not include generated type file ${file}. Include the _vorma directory beside that tsconfig in its TypeScript project.`).join("\n")
816
817
  });
817
818
  });
818
819
  }
@@ -2024,7 +2025,9 @@ function renderGeneratedClientTransport(input) {
2024
2025
  ...entries.length === 0 ? [] : [`import { ${entries.join(", ")} } from ${moduleSpecifier};`],
2025
2026
  `import type { TransportTypeEntry } from ${moduleSpecifier};`,
2026
2027
  "",
2027
- `export const transportTypeEntries = [${entries.join(", ")}] satisfies ReadonlyArray<TransportTypeEntry>;`,
2028
+ "export function getTransportTypeEntries(): ReadonlyArray<TransportTypeEntry> {",
2029
+ ` return [${entries.join(", ")}];`,
2030
+ "}",
2028
2031
  ""
2029
2032
  ].join("\n")
2030
2033
  };
@@ -2032,7 +2035,7 @@ function renderGeneratedClientTransport(input) {
2032
2035
  //#endregion
2033
2036
  //#region src/build/generate-application.ts
2034
2037
  /** Writes correlated generated sources and verifies their native TypeScript inclusion. */
2035
- function writeAndCheckApplicationGeneration(generation) {
2038
+ function writeAndCheckApplicationGeneration(generation, knownRootFiles) {
2036
2039
  return Effect.gen(function* () {
2037
2040
  yield* Effect.all([writeApplicationGeneration(generation), writeGeneratedServerApplication({ generation })], {
2038
2041
  concurrency: 2,
@@ -2040,6 +2043,7 @@ function writeAndCheckApplicationGeneration(generation) {
2040
2043
  });
2041
2044
  yield* checkGeneratedTypeInclusion({
2042
2045
  ...generation.config,
2046
+ ...knownRootFiles === void 0 ? {} : { knownRootFiles },
2043
2047
  serverFiles: [generation.config.generatedServerContractsFilePath],
2044
2048
  clientFiles: [generation.clientContracts.filePath, generation.publicAssets.types.filePath]
2045
2049
  });
@@ -2354,10 +2358,15 @@ function loadApplicationSourceLayout(config) {
2354
2358
  const fileSystem = yield* FileSystem$1.FileSystem;
2355
2359
  const path = yield* Path$1.Path;
2356
2360
  const requiredPaths = {
2357
- serverEntryFilePath: {
2358
- field: "serverEntry",
2359
- path: config.serverEntryFilePath,
2360
- expectedType: "File"
2361
+ serverRootDirectory: {
2362
+ field: "serverTsconfigFile",
2363
+ path: path.dirname(config.serverTsconfigFilePath),
2364
+ expectedType: "Directory"
2365
+ },
2366
+ clientRootDirectory: {
2367
+ field: "clientTsconfigFile",
2368
+ path: path.dirname(config.clientTsconfigFilePath),
2369
+ expectedType: "Directory"
2361
2370
  },
2362
2371
  serverTsconfigFilePath: {
2363
2372
  field: "serverTsconfigFile",
@@ -2422,7 +2431,16 @@ function loadApplicationSourceLayout(config) {
2422
2431
  _tag: "ApplicationSourceLayoutIssues",
2423
2432
  issues
2424
2433
  });
2425
- const { criticalCssEntryFilePath, ...canonical } = canonicalPaths.success;
2434
+ const { serverRootDirectory, clientRootDirectory, criticalCssEntryFilePath, ...canonical } = canonicalPaths.success;
2435
+ if (serverRootDirectory === clientRootDirectory) return yield* Effect.fail({
2436
+ _tag: "ApplicationSourceLayoutIssues",
2437
+ issues: [{
2438
+ field: "clientTsconfigFile",
2439
+ path: config.clientTsconfigFilePath,
2440
+ expectedType: "File",
2441
+ message: `serverTsconfigFile and clientTsconfigFile must be in different directories. Both project roots resolve to ${serverRootDirectory} and would share the same _vorma output.`
2442
+ }]
2443
+ });
2426
2444
  const canonicalConfig = {
2427
2445
  ...config,
2428
2446
  ...canonical,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcx/vorma",
3
- "version": "0.0.0-pre.3",
3
+ "version": "0.0.0-pre.4",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -22,8 +22,8 @@
22
22
  "@effect/platform-node-shared": "^4.0.0-rc.115",
23
23
  "@noble/hashes": "^2.4.0",
24
24
  "@scure/base": "^2.4.0",
25
- "@vorma/primitives": "npm:@sjcx/vorma-primitives@0.0.0-pre.3",
26
- "@vorma/protocol": "npm:@sjcx/vorma-protocol@0.0.0-pre.3",
25
+ "@vorma/primitives": "npm:@sjcx/vorma-primitives@0.0.0-pre.4",
26
+ "@vorma/protocol": "npm:@sjcx/vorma-protocol@0.0.0-pre.4",
27
27
  "chokidar": "^5.0.0",
28
28
  "lightningcss": "^1.33.0",
29
29
  "rolldown": "^1.2.6",