@sjcx/vorma 0.0.0-pre.6 → 0.0.0-pre.8

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.
Files changed (110) hide show
  1. package/LICENSE +197 -1
  2. package/dist/build/assets/css-static-public-assets.d.ts +22 -0
  3. package/dist/build/assets/static-public-asset-plugin.d.ts +20 -0
  4. package/dist/build/assets/static-public-assets.d.ts +44 -0
  5. package/dist/build/build-application.d.ts +18 -0
  6. package/dist/build/{bundle-client.d.ts → bundling/bundle-client.d.ts} +16 -5
  7. package/dist/build/{client-output-hashing.d.ts → bundling/client-output-hashing.d.ts} +1 -1
  8. package/dist/build/bundling/critical-css.d.ts +19 -0
  9. package/dist/build/cli.js +4773 -849
  10. package/dist/build/config/load-config.d.ts +142 -0
  11. package/dist/build/config/resolve-config.d.ts +63 -0
  12. package/dist/build/{source-layout.d.ts → config/source-layout.d.ts} +4 -6
  13. package/dist/build/config/url-pathname.d.ts +13 -0
  14. package/dist/build/config/vite-options.d.ts +80 -0
  15. package/dist/build/dev/application-process.d.ts +18 -0
  16. package/dist/build/dev/artifacts.d.ts +37 -0
  17. package/dist/build/dev/browser-source.d.ts +25 -0
  18. package/dist/build/dev/build.d.ts +33 -0
  19. package/dist/build/dev/cargo-metadata.d.ts +28 -0
  20. package/dist/build/dev/changes.d.ts +11 -0
  21. package/dist/build/dev/client-inputs.d.ts +25 -0
  22. package/dist/build/dev/client.d.ts +39 -0
  23. package/dist/build/dev/dev-protocol.d.ts +23 -0
  24. package/dist/build/dev/generated-paths.d.ts +27 -0
  25. package/dist/build/dev/generation.d.ts +31 -0
  26. package/dist/build/dev/index-html.d.ts +28 -0
  27. package/dist/build/dev/module-server.d.ts +24 -0
  28. package/dist/build/dev/patterns.d.ts +26 -0
  29. package/dist/build/dev/ports.d.ts +25 -0
  30. package/dist/build/dev/server-process.d.ts +34 -0
  31. package/dist/build/dev/server-sources.d.ts +19 -0
  32. package/dist/build/dev/session.d.ts +28 -0
  33. package/dist/build/dev/sources.d.ts +46 -0
  34. package/dist/build/{development-stylesheet.d.ts → dev/stylesheet.d.ts} +4 -4
  35. package/dist/build/dev/watcher.d.ts +30 -0
  36. package/dist/build/dev/work.d.ts +67 -0
  37. package/dist/build/{client-inputs.d.ts → generation/client-view-entries.d.ts} +1 -3
  38. package/dist/build/generation/compile-application.d.ts +28 -0
  39. package/dist/build/generation/generate-application.d.ts +52 -0
  40. package/dist/build/generation/render-client-contracts.d.ts +15 -0
  41. package/dist/build/{render-source-text.d.ts → generation/render-source-text.d.ts} +3 -7
  42. package/dist/build/inspection/http-method.d.ts +4 -0
  43. package/dist/build/inspection/inspect-application.d.ts +25 -0
  44. package/dist/build/inspection/inspect-projects.d.ts +85 -0
  45. package/dist/build/inspection/rust-server.d.ts +57 -0
  46. package/dist/build/inspection/type-declarations.d.ts +20 -0
  47. package/dist/build/inspection/typescript-projects.d.ts +31 -0
  48. package/dist/build/issues.d.ts +25 -0
  49. package/dist/build/{contained-path.d.ts → output/contained-path.d.ts} +3 -13
  50. package/dist/build/output/content-hash.d.ts +9 -0
  51. package/dist/build/output/dist-dir.d.ts +34 -0
  52. package/dist/build/output/output-files.d.ts +23 -0
  53. package/dist/build/output/output-ownership.d.ts +44 -0
  54. package/dist/build/output/published-file-url.d.ts +6 -0
  55. package/dist/build/patterns/nested-route-chains.d.ts +12 -0
  56. package/dist/build/patterns/pattern-language.d.ts +3 -0
  57. package/dist/build/patterns/route-patterns.d.ts +12 -0
  58. package/dist/build/publication/assemble-artifacts.d.ts +37 -0
  59. package/dist/build/{browser-contracts.d.ts → publication/browser-contracts.d.ts} +1 -1
  60. package/dist/build/publication/build-metadata.d.ts +45 -0
  61. package/dist/build/publication/publish-artifacts.d.ts +17 -0
  62. package/dist/config-FbabCxBO.js +56 -0
  63. package/dist/config.d.ts +106 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +2 -0
  66. package/dist/plugin-api-Btb0teGk.js +36 -0
  67. package/dist/vite/index.d.ts +14 -3
  68. package/dist/vite/index.js +25 -9
  69. package/dist/vite/plugin-api.d.ts +18 -0
  70. package/package.json +12 -16
  71. package/dist/build/assemble-artifacts.d.ts +0 -23
  72. package/dist/build/client-public-urls.d.ts +0 -20
  73. package/dist/build/compare-text.d.ts +0 -5
  74. package/dist/build/compile-application.d.ts +0 -43
  75. package/dist/build/content-digest.d.ts +0 -7
  76. package/dist/build/critical-css.d.ts +0 -7
  77. package/dist/build/css-public-assets.d.ts +0 -15
  78. package/dist/build/development-artifacts.d.ts +0 -36
  79. package/dist/build/development-browser-source.d.ts +0 -3
  80. package/dist/build/development-build.d.ts +0 -27
  81. package/dist/build/development-changes.d.ts +0 -14
  82. package/dist/build/development-client.d.ts +0 -21
  83. package/dist/build/development-generation.d.ts +0 -20
  84. package/dist/build/development-listener.d.ts +0 -14
  85. package/dist/build/development-patterns.d.ts +0 -5
  86. package/dist/build/development-protocol.d.ts +0 -20
  87. package/dist/build/development-server-process.d.ts +0 -30
  88. package/dist/build/development-sources.d.ts +0 -22
  89. package/dist/build/development-watcher.d.ts +0 -15
  90. package/dist/build/development-work.d.ts +0 -33
  91. package/dist/build/development.d.ts +0 -3
  92. package/dist/build/generate-application.d.ts +0 -62
  93. package/dist/build/index.d.ts +0 -14
  94. package/dist/build/index.js +0 -2
  95. package/dist/build/inspect-css-artifacts.d.ts +0 -11
  96. package/dist/build/inspect-projects.d.ts +0 -68
  97. package/dist/build/load-config.d.ts +0 -57
  98. package/dist/build/output-files.d.ts +0 -8
  99. package/dist/build/output-ownership.d.ts +0 -21
  100. package/dist/build/public-assets.d.ts +0 -32
  101. package/dist/build/publish-artifacts.d.ts +0 -20
  102. package/dist/build/render-client-contracts.d.ts +0 -10
  103. package/dist/build/render-client-transport.d.ts +0 -11
  104. package/dist/build/render-server-generated.d.ts +0 -22
  105. package/dist/build/render-types.d.ts +0 -31
  106. package/dist/build/resolve-config.d.ts +0 -47
  107. package/dist/build/typescript-projects.d.ts +0 -43
  108. package/dist/build-Dy9VE6xO.js +0 -3013
  109. package/dist/build-invocation-D7Fu8gBK.js +0 -4
  110. package/dist/vite/build-invocation.d.ts +0 -4
@@ -0,0 +1,57 @@
1
+ import { Effect, FileSystem } from "effect";
2
+ import * as Path from "effect/Path";
3
+ import type { InspectionIssues, ServerInspection } from "./inspect-projects.ts";
4
+ /** An executable and its arguments, run without a shell. */
5
+ type Cmd = readonly [string, ...Array<string>];
6
+ /** A Rust server's declarations and the executable that described them. */
7
+ export type CompiledRustServer = {
8
+ readonly inspection: ServerInspection;
9
+ /** The compiled binary; development reads its Cargo dependency file beside it and runs it. */
10
+ readonly executable: string;
11
+ };
12
+ /**
13
+ * Runs `cmd` so that the server it starts writes its declaration
14
+ * contract, and reads the declarations. `vorma build` runs
15
+ * `build.serverStartCmd` this way.
16
+ */
17
+ export declare function inspectStartedRustServer(input: {
18
+ readonly cmd: Cmd;
19
+ readonly configDir: string;
20
+ }): Effect.Effect<{
21
+ inspection: ServerInspection;
22
+ }, InspectionIssues, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
23
+ /**
24
+ * Compiles the server binary with Cargo and runs it with `binArgs` to read the
25
+ * declaration contract. `vorma dev` inspects the server this way and then runs
26
+ * the same executable.
27
+ */
28
+ export declare function inspectCompiledRustServer(input: {
29
+ readonly cargoManifestFilePath: string;
30
+ readonly cargoBin: string;
31
+ readonly cargoArgs: ReadonlyArray<string>;
32
+ readonly binArgs: ReadonlyArray<string>;
33
+ readonly configDir: string;
34
+ }): Effect.Effect<{
35
+ inspection: ServerInspection;
36
+ executable: string;
37
+ }, InspectionIssues, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
38
+ /**
39
+ * Runs `cmd` so that the server it starts loads the build directory
40
+ * `buildDir`, runs its startup checks, and exits. `vorma build` runs
41
+ * `build.serverStartCmd` this way after it writes the build directory.
42
+ */
43
+ export declare function checkStartedRustServer(input: {
44
+ readonly cmd: Cmd;
45
+ readonly configDir: string;
46
+ readonly buildDir: string;
47
+ }): Effect.Effect<undefined, InspectionIssues, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/Scope").Scope>;
48
+ /**
49
+ * Decodes the declaration contract that the Rust server `serverLabel` wrote. The
50
+ * contract's version is checked before the rest, so a contract of another
51
+ * version fails with the version message.
52
+ */
53
+ export declare function decodeDeclarationContract(input: {
54
+ readonly text: string;
55
+ readonly serverLabel: string;
56
+ }): Effect.Effect<ServerInspection, InspectionIssues>;
57
+ export {};
@@ -0,0 +1,20 @@
1
+ /** The named type declarations of a server's contract, and the names that each declaration and each type text references directly. */
2
+ export type TypeDeclarations = {
3
+ /** In name order; each declaration is a complete module-local `type` statement at depth zero. */
4
+ readonly declarations: ReadonlyArray<{
5
+ readonly name: string;
6
+ readonly declaration: string;
7
+ readonly referencedTypeNames: ReadonlySet<string>;
8
+ }>;
9
+ readonly typeTexts: ReadonlyMap<string, ReadonlySet<string>>;
10
+ };
11
+ /**
12
+ * The declarations that the given type texts need, including every
13
+ * declaration that a needed declaration names, in declaration order. A
14
+ * generated file declares only these, so that it has no unused declaration
15
+ * under the application's compiler options.
16
+ */
17
+ export declare function selectTypeDeclarations(input: {
18
+ readonly typeDeclarations: TypeDeclarations;
19
+ readonly typeTexts: Iterable<string>;
20
+ }): ReadonlyArray<string>;
@@ -0,0 +1,31 @@
1
+ import { Effect } from "effect";
2
+ import { type APIOptions, type Project } from "typescript/unstable/async";
3
+ export type TsProjectIssue = {
4
+ readonly _tag: "TsProjectIssue";
5
+ readonly msg: string;
6
+ readonly cause?: unknown;
7
+ };
8
+ /** Reads the client project's root files without loading its program or declaration types. */
9
+ export declare function readClientProjectRoots(input: {
10
+ readonly configDir: string;
11
+ readonly clientTsConfigFilePath: string;
12
+ }): Effect.Effect<string[], TsProjectIssue, never>;
13
+ /** Opens the configured client project for the duration of `useFn`, then closes the checker session. */
14
+ export declare function withClientProject<A, E, R>(input: {
15
+ readonly configDir: string;
16
+ readonly clientTsConfigFilePath: string;
17
+ /**
18
+ * Files that the checker reads as empty. Inspection empties the generated
19
+ * types file, so it reads every build as the first build does and never
20
+ * depends on a previous build's output.
21
+ */
22
+ readonly emptiedFiles: ReadonlyArray<string>;
23
+ readonly fileSystem?: APIOptions["fs"];
24
+ readonly useFn: (client: Project) => Effect.Effect<A, E, R>;
25
+ }): Effect.Effect<A, E | TsProjectIssue, R>;
26
+ /**
27
+ * One request to the compiler. The compiler has no cancellation API, so an
28
+ * interrupted request stays pending, and the session's release ends the
29
+ * compiler process.
30
+ */
31
+ export declare function runTsOperation<Value>(fn: () => Promise<Value>): Effect.Effect<Value, TsProjectIssue, never>;
@@ -0,0 +1,25 @@
1
+ import { Effect } from "effect";
2
+ /** One problem that the build found, described by its message alone. */
3
+ export type VormaBuildIssue = {
4
+ readonly msg: string;
5
+ };
6
+ /** Every issue that a build found. */
7
+ export type VormaBuildIssues = {
8
+ readonly _tag: "VormaBuildIssues";
9
+ readonly issues: ReadonlyArray<VormaBuildIssue>;
10
+ };
11
+ /** A failure that reports one issue, or one that reports several. */
12
+ export type BuildIssueSource = {
13
+ readonly msg: string;
14
+ } | {
15
+ readonly issues: ReadonlyArray<{
16
+ readonly msg: string;
17
+ }>;
18
+ };
19
+ export declare function toBuildIssues(failure: BuildIssueSource): VormaBuildIssues;
20
+ /** Prints each issue's message on standard error. */
21
+ export declare function printBuildIssues(issues: VormaBuildIssues): Effect.Effect<void>;
22
+ /** A failure of unknown type as build issues, when it is a failure that reports issues. */
23
+ export declare function readBuildIssues(failure: unknown): VormaBuildIssues | undefined;
24
+ /** An underlying failure's own message, for an issue that explains what it prevented. */
25
+ export declare function describeCause(cause: unknown): string;
@@ -1,29 +1,19 @@
1
1
  import type * as Path from "effect/Path";
2
2
  /** True when a `path.relative` result names the root or a descendant of it. */
3
- export declare function containsRelativePath(input: {
3
+ export declare function testRelativePathContained(input: {
4
4
  readonly relativePath: string;
5
5
  readonly separator: string;
6
6
  readonly absolute: boolean;
7
7
  }): boolean;
8
- /**
9
- * True when a module specifier names a package or one of its subpaths.
10
- * Relative, absolute, builtin, scheme, drive-letter, and virtual-module
11
- * specifiers never match; only the caller decides which of those to exclude
12
- * first.
13
- */
14
- export declare function matchesPackageSpecifier(input: {
15
- readonly source: string;
16
- readonly packageName: string;
17
- }): boolean;
18
8
  /** The path operations a relative POSIX conversion needs. */
19
- export type PosixRelativePath = Pick<Path.Path, "sep" | "relative">;
9
+ export type PosixRelativePathOperations = Pick<Path.Path, "sep" | "relative">;
20
10
  /**
21
11
  * A `path.relative` result with platform separators converted to POSIX
22
12
  * separators, for generated module specifiers, output keys, and build
23
13
  * identities, which are POSIX even when the build runs on Windows.
24
14
  */
25
15
  export declare function toPosixRelativePath(input: {
26
- readonly path: PosixRelativePath;
16
+ readonly path: PosixRelativePathOperations;
27
17
  readonly from: string;
28
18
  readonly to: string;
29
19
  }): string;
@@ -0,0 +1,9 @@
1
+ import { type Schema } from "effect";
2
+ /** BLAKE3 content identity, encoded as lowercase base32 without padding. */
3
+ export declare function toContentHash(source: string | Uint8Array): string;
4
+ /** Encodes an already computed BLAKE3 hash. */
5
+ export declare function encodeContentHash(hash: Uint8Array): string;
6
+ /** The leading 24 characters of the content hash of a client build's canonical identity. */
7
+ export declare function toClientBuildId(identity: Schema.Json): string;
8
+ /** Canonical object ordering; array order carries framework semantics. */
9
+ export declare function encodeCanonicalJson(value: Schema.Json): string;
@@ -0,0 +1,34 @@
1
+ import type * as Path from "effect/Path";
2
+ /** The layout of the dist directory and of a build directory, and the stable names of published files. */
3
+ export declare const ARTIFACT_PROTOCOL: {
4
+ /** Inside the dist directory: the build directory that `vorma build` writes and that the server reads in production. */
5
+ readonly prodBuildDirName: "prod";
6
+ /** Inside the dist directory: the build directory that `vorma dev` writes and that the development server reads. */
7
+ readonly devBuildDirName: "dev";
8
+ /** Inside the build directory: the build metadata that the server reads at startup. */
9
+ readonly buildMetadataFileName: "metadata.json";
10
+ /** Inside the build directory: the published static public assets. */
11
+ readonly publicDirName: "public";
12
+ /** Inside the build directory: the lock that a running build or development session holds. */
13
+ readonly lockDirName: "build.lock";
14
+ /** Inside the build directory: the directory in which a running build stages its output. */
15
+ readonly stagingDirName: "staging";
16
+ readonly publicOutputFileNamePrefix: "vorma_out_";
17
+ readonly publicModuleFileNamePattern: "vorma_out_[name]-[hash].js";
18
+ readonly staticPublicAssetFileNamePattern: "vorma_out_[name]-[hash][extname]";
19
+ };
20
+ export type BuildDirPaths = {
21
+ /** The one directory that the build writes. */
22
+ readonly buildDir: string;
23
+ /** The published static public assets. */
24
+ readonly publicDir: string;
25
+ /** The build metadata that the server reads. */
26
+ readonly buildMetadataFilePath: string;
27
+ };
28
+ /** The path operations that the derivation needs; both Effect Path and `node:path` provide them. */
29
+ export type BuildDirPathOperations = Pick<Path.Path, "join">;
30
+ export declare function getBuildDirPaths(input: {
31
+ readonly path: BuildDirPathOperations;
32
+ /** The absolute path of the build directory. */
33
+ readonly buildDir: string;
34
+ }): BuildDirPaths;
@@ -0,0 +1,23 @@
1
+ import { Effect } from "effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Path from "effect/Path";
4
+ export type GeneratedSourceConflictIssue = {
5
+ readonly _tag: "GeneratedSourceConflictIssue";
6
+ readonly filePath: string;
7
+ readonly msg: string;
8
+ };
9
+ /** Names the temporary directory that `writeOutputFile` writes through, beside the output file. */
10
+ export declare const TEMPORARY_OUTPUT_DIR_PREFIX = "_vorma-write-";
11
+ /**
12
+ * Atomically replaces generated source that TypeScript and build tools can
13
+ * read. Existing files must have Vorma's generated-source header. A file that
14
+ * already holds the source is left untouched, so editors and watchers see no change.
15
+ */
16
+ export declare function writeOutputFile(input: {
17
+ readonly filePath: string;
18
+ readonly source: string;
19
+ }): Effect.Effect<undefined, import("effect/PlatformError").PlatformError | {
20
+ _tag: "GeneratedSourceConflictIssue";
21
+ filePath: string;
22
+ msg: string;
23
+ }, FileSystem.FileSystem | Path.Path>;
@@ -0,0 +1,44 @@
1
+ import { Effect, FileSystem, type Scope } from "effect";
2
+ import * as Path from "effect/Path";
3
+ export type OutputOwnershipIssue = {
4
+ readonly _tag: "OutputOwnershipIssue";
5
+ readonly dir: string;
6
+ readonly msg: string;
7
+ readonly cause?: unknown;
8
+ };
9
+ /** Resolves aliases even when the output directory has not been created. */
10
+ export declare function canonicalizeOutputPath(filePath: string): Effect.Effect<string, OutputOwnershipIssue, FileSystem.FileSystem | Path.Path>;
11
+ /** Checks canonical containment before removing or replacing generated output. */
12
+ export declare function checkOutputPath(input: {
13
+ readonly filePath: string;
14
+ readonly rootDir: string;
15
+ }): Effect.Effect<void, OutputOwnershipIssue, FileSystem.FileSystem | Path.Path>;
16
+ /**
17
+ * A production build's output, staged inside the build directory. Publication
18
+ * moves the staged files of `public` into the build directory's `public`,
19
+ * replaces the build metadata in one rename, and then removes the published
20
+ * files that the staged build does not have. Every file name in `public`
21
+ * carries a content hash, so a published file with a staged file's name has the
22
+ * same bytes. The build directory therefore always holds one complete build: the
23
+ * previous build until the metadata is replaced, and the staged build after
24
+ * that. A failed build leaves the previous build intact. Closing the scope
25
+ * removes the staging directory.
26
+ */
27
+ export type StagedBuildDir = {
28
+ /** The staging directory, where the build writes. */
29
+ readonly stagingDir: string;
30
+ readonly publish: Effect.Effect<void, OutputOwnershipIssue>;
31
+ };
32
+ export declare function createStagedBuildDir(input: {
33
+ readonly buildDir: string;
34
+ }): Effect.Effect<StagedBuildDir, OutputOwnershipIssue, Scope.Scope | FileSystem.FileSystem | Path.Path>;
35
+ /** The build directory paths of a staged build, inside its staging directory. */
36
+ export declare function getStagedBuildDirPaths(input: {
37
+ readonly path: Path.Path;
38
+ readonly staged: StagedBuildDir;
39
+ }): import("./dist-dir.ts").BuildDirPaths;
40
+ /** Owns the build directory until the build or development scope closes. */
41
+ export declare function acquireOutputOwnership(input: {
42
+ readonly buildDir: string;
43
+ readonly kind: "build" | "dev";
44
+ }): Effect.Effect<void, OutputOwnershipIssue, Scope.Scope | FileSystem.FileSystem | Path.Path>;
@@ -0,0 +1,6 @@
1
+ import type { StaticPublicAssetsServeUrlPathPrefix } from "../config/resolve-config.ts";
2
+ /** The browser URL of a published file: the static public assets base path, then each path segment of the file name, URL-encoded. */
3
+ export declare function toPublishedFileUrl(input: {
4
+ readonly staticPublicAssetsServeUrlPathPrefix: StaticPublicAssetsServeUrlPathPrefix;
5
+ readonly fileName: string;
6
+ }): string;
@@ -0,0 +1,12 @@
1
+ import type { CompiledNestedPattern } from "primitives-ts/matcher";
2
+ type NestedRouteNode = {
3
+ readonly compiledPattern: CompiledNestedPattern;
4
+ };
5
+ /** Builds each unique target's outer-to-inner chain by looking up its compiled path prefixes. */
6
+ export declare function createNestedRouteChains<Node extends NestedRouteNode>(input: {
7
+ readonly nodes: ReadonlyArray<Node>;
8
+ }): ReadonlyArray<{
9
+ readonly target: Node;
10
+ readonly chain: ReadonlyArray<Node>;
11
+ }>;
12
+ export {};
@@ -0,0 +1,3 @@
1
+ import type * as Matcher from "primitives-ts/matcher";
2
+ /** The view pattern language, with the markers that the client and the server use. */
3
+ export declare const NESTED_PATTERN_LANGUAGE: Matcher.NestedPatternLanguage;
@@ -0,0 +1,12 @@
1
+ import { type PathWireError } from "@sjcx/vorma-client/unstable";
2
+ import { Result } from "effect";
3
+ import { type CompiledNestedPattern, type PatternCompileError } from "primitives-ts/matcher";
4
+ export type RoutePatternError = PathWireError | PatternCompileError;
5
+ /**
6
+ * Compiles an authored view route pattern: wire encoding first, then the
7
+ * nested pattern language. Every view pattern enters the matcher through this
8
+ * function.
9
+ */
10
+ export declare function compileViewPattern(pattern: string): Result.Result<CompiledNestedPattern, RoutePatternError>;
11
+ /** A route pattern's compile error as a sentence fragment. */
12
+ export declare function formatRoutePatternError(error: RoutePatternError): string;
@@ -0,0 +1,37 @@
1
+ import { Effect } from "effect";
2
+ import type { ClientBundle } from "../bundling/bundle-client.ts";
3
+ import type { ApplicationGeneration } from "../generation/generate-application.ts";
4
+ import { type BuildMetadata } from "./build-metadata.ts";
5
+ export type ApplicationArtifact = {
6
+ /** Relative to the published public directory, with decoded filenames. */
7
+ readonly fileName: string;
8
+ readonly url: string;
9
+ readonly hash: string;
10
+ };
11
+ /** The build metadata that the Rust server reads: the browser build's metadata and the hash of the declarations that the build directory is built for. */
12
+ export type ServerBuildMetadata = BuildMetadata & {
13
+ /** The format of the metadata file, which the server checks. */
14
+ readonly formatVersion: number;
15
+ readonly declarationsHash: string;
16
+ /** The development session's values for the server's Content-Security-Policy sources; absent from production metadata. */
17
+ readonly devCsp?: {
18
+ /** Where pages load browser modules, styles, images, and fonts. */
19
+ readonly moduleServerOrigin: string;
20
+ /** The module server's WebSocket origin. */
21
+ readonly webSocketOrigin: string;
22
+ /** The value of Vite's `html.cspNonce`, which `vorma dev` chooses unless the application sets it. */
23
+ readonly nonce?: string;
24
+ };
25
+ };
26
+ export type ApplicationArtifacts = {
27
+ readonly metadata: ServerBuildMetadata;
28
+ };
29
+ export type ArtifactAssemblyIssue = {
30
+ readonly _tag: "ArtifactAssemblyIssue";
31
+ readonly msg: string;
32
+ };
33
+ /** Joins published file metadata and checks paths, collisions, and module projections. */
34
+ export declare function assembleApplicationArtifacts(input: {
35
+ readonly generation: ApplicationGeneration;
36
+ readonly client: ClientBundle;
37
+ }): Effect.Effect<ApplicationArtifacts, ArtifactAssemblyIssue>;
@@ -1,5 +1,5 @@
1
1
  import type { Schema } from "effect";
2
- import type { InspectedProjects } from "./inspect-projects.ts";
2
+ import type { InspectedProjects } from "../inspection/inspect-projects.ts";
3
3
  /**
4
4
  * The static contracts on which browser code and learned routing depend.
5
5
  * Source locations, export names, and runtime implementations are not inputs.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The format of `metadata.json`. The Rust server checks it when it reads the
3
+ * file and refuses a file of another format. It changes with any change to the
4
+ * file's shape that an older reader or writer would misread, and the `vorma`
5
+ * crate's `BUILD_METADATA_FORMAT_VERSION` has the same value.
6
+ */
7
+ export declare const BUILD_METADATA_FORMAT_VERSION = 1;
8
+ /** One browser module's build-to-runtime projection. A view module's default export is its view. The metadata leaves out a list that is empty. */
9
+ export type ClientModule = {
10
+ readonly importUrl: string;
11
+ readonly depUrls?: ReadonlyArray<string>;
12
+ readonly cssBundleUrls?: ReadonlyArray<string>;
13
+ /** The URLs of the static public assets that the module's JavaScript references, not those that only its stylesheets reference. The server preloads the images and fonts among them. */
14
+ readonly referencedStaticPublicAssetUrls?: ReadonlyArray<string>;
15
+ };
16
+ /** Makes a module's metadata, which leaves out each list that is empty. */
17
+ export declare function createClientModule(input: {
18
+ readonly importUrl: string;
19
+ readonly depUrls: ReadonlyArray<string>;
20
+ readonly cssBundleUrls: ReadonlyArray<string>;
21
+ readonly referencedStaticPublicAssetUrls: ReadonlyArray<string>;
22
+ }): ClientModule;
23
+ /** Whether the application runs as a production deployment or under the development program. */
24
+ export type RuntimeMode = "prod" | "dev";
25
+ /** Everything one build determines about its own output. The server reads it from the build directory. */
26
+ export type BuildMetadata = {
27
+ readonly clientBuildId: string;
28
+ readonly runtimeMode: RuntimeMode;
29
+ /** The URL path under which the server serves the files of the public output directory, such as `/` or `/static/`. */
30
+ readonly staticPublicAssetsServeUrlPathPrefix: string;
31
+ /** The names of exactly the files that the build wrote to the public output directory. The server serves each at the prefix followed by the name, URL-encoded. Every file is content-hashed, so the server serves each as immutable. This inventory stays on the server. */
32
+ readonly staticPublicAssetFileNames: ReadonlyArray<string>;
33
+ /** Each static public asset's source key and its published URL path. */
34
+ readonly staticPublicAssetUrls: Readonly<Record<string, string>>;
35
+ readonly criticalCss: string;
36
+ /** The development HTML that Vite's plugins add to the head; absent from production metadata. */
37
+ readonly devHeadHtml?: string;
38
+ /** The development HTML that Vite's plugins add to the start of the body; absent from production metadata. */
39
+ readonly devBodyPrependHtml?: string;
40
+ /** The development HTML that Vite's plugins add to the end of the body; absent from production metadata. */
41
+ readonly devBodyHtml?: string;
42
+ readonly clientEntry: ClientModule;
43
+ /** Each view's module, by the pattern that the view states. */
44
+ readonly clientViews: Readonly<Record<string, ClientModule>>;
45
+ };
@@ -0,0 +1,17 @@
1
+ import { Effect } from "effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import type { ApplicationSourceLayout } from "../config/source-layout.ts";
4
+ import type { ApplicationGeneration } from "../generation/generate-application.ts";
5
+ import type { ApplicationArtifacts } from "./assemble-artifacts.ts";
6
+ export type ArtifactPublicationIssue = {
7
+ readonly _tag: "ArtifactPublicationIssue";
8
+ readonly msg: string;
9
+ readonly cause: unknown;
10
+ };
11
+ /** Empties the public directory before the build adds its files. */
12
+ export declare function preparePublicOutput(sourceLayout: Pick<ApplicationSourceLayout, "publicDir" | "buildDir">): Effect.Effect<void, ArtifactPublicationIssue | import("../output/output-ownership.ts").OutputOwnershipIssue, FileSystem.FileSystem | import("effect/Path").Path>;
13
+ /** Writes the build metadata, which the server reads, for the completed browser build. */
14
+ export declare function writeBuildMetadata(input: {
15
+ readonly artifacts: ApplicationArtifacts;
16
+ readonly generation: ApplicationGeneration;
17
+ }): Effect.Effect<void, ArtifactPublicationIssue, FileSystem.FileSystem>;
@@ -0,0 +1,56 @@
1
+ import { Schema } from "effect";
2
+ //#region src/config.ts
3
+ /** The work that a `dev.onChange` rule requests. */
4
+ const DEV_ACTIONS = [
5
+ "revalidate-client-data",
6
+ "hard-browser-reload",
7
+ "restart-server"
8
+ ];
9
+ /** An executable followed by its arguments, run without a shell. */
10
+ const Cmd = Schema.TupleWithRest(Schema.Tuple([Schema.NonEmptyString]), [Schema.String]);
11
+ const WrapCmdSchema = Schema.declare((value) => {
12
+ return typeof value === "function";
13
+ });
14
+ const DevOnChangeRule = Schema.Struct({
15
+ triggers: Schema.NonEmptyArray(Schema.NonEmptyString),
16
+ actions: Schema.NonEmptyArray(Schema.Literals(DEV_ACTIONS))
17
+ });
18
+ const VormaConfigSchema = Schema.Struct({
19
+ core: Schema.Struct({
20
+ importMetaUrl: Schema.NonEmptyString,
21
+ distDir: Schema.NonEmptyString,
22
+ staticPublicAssets: Schema.Struct({
23
+ srcDir: Schema.NonEmptyString,
24
+ serveUrlPathPrefix: Schema.String
25
+ })
26
+ }),
27
+ build: Schema.Struct({ serverStartCmd: Cmd }),
28
+ client: Schema.Struct({
29
+ tsConfigFile: Schema.NonEmptyString,
30
+ viteConfigFile: Schema.NonEmptyString,
31
+ tsGenOutFile: Schema.NonEmptyString,
32
+ criticalCssFile: Schema.optionalKey(Schema.NonEmptyString),
33
+ entryFile: Schema.NonEmptyString,
34
+ viewFilePattern: Schema.NonEmptyString
35
+ }),
36
+ dev: Schema.optionalKey(Schema.Struct({
37
+ server: Schema.Struct({
38
+ cargoManifestFile: Schema.NonEmptyString,
39
+ cargoBin: Schema.NonEmptyString,
40
+ cargoArgs: Schema.optionalKey(Schema.Array(Schema.String)),
41
+ binArgs: Schema.optionalKey(Schema.Array(Schema.String)),
42
+ wrapCmdFn: Schema.optionalKey(WrapCmdSchema),
43
+ preferredPort: Schema.optionalKey(Schema.Int.check(Schema.isBetween({
44
+ minimum: 1,
45
+ maximum: 65535
46
+ })))
47
+ }),
48
+ onChange: Schema.optionalKey(Schema.Array(DevOnChangeRule))
49
+ }))
50
+ });
51
+ /** Types a configuration object where it is written. */
52
+ function defineConfig(config) {
53
+ return config;
54
+ }
55
+ //#endregion
56
+ export { defineConfig as n, VormaConfigSchema as t };
@@ -0,0 +1,106 @@
1
+ import { Schema } from "effect";
2
+ /** The work that a `dev.onChange` rule requests. */
3
+ declare const DEV_ACTIONS: readonly ["revalidate-client-data", "hard-browser-reload", "restart-server"];
4
+ export type DevAction = (typeof DEV_ACTIONS)[number];
5
+ /** An executable followed by its arguments, run without a shell. */
6
+ declare const Cmd: Schema.TupleWithRest<Schema.Tuple<readonly [Schema.NonEmptyString]>, readonly [Schema.String]>;
7
+ /**
8
+ * The command that `dev.server.wrapCmdFn` returns for the compiled executable
9
+ * and the arguments that Vorma would pass to it.
10
+ */
11
+ type WrapCmd = (input: {
12
+ readonly executable: string;
13
+ readonly args: ReadonlyArray<string>;
14
+ }) => typeof Cmd.Type;
15
+ export declare const VormaConfigSchema: Schema.Struct<{
16
+ readonly core: Schema.Struct<{
17
+ readonly importMetaUrl: Schema.NonEmptyString;
18
+ readonly distDir: Schema.NonEmptyString;
19
+ readonly staticPublicAssets: Schema.Struct<{
20
+ readonly srcDir: Schema.NonEmptyString;
21
+ readonly serveUrlPathPrefix: Schema.String;
22
+ }>;
23
+ }>;
24
+ readonly build: Schema.Struct<{
25
+ readonly serverStartCmd: Schema.TupleWithRest<Schema.Tuple<readonly [Schema.NonEmptyString]>, readonly [Schema.String]>;
26
+ }>;
27
+ readonly client: Schema.Struct<{
28
+ readonly tsConfigFile: Schema.NonEmptyString;
29
+ readonly viteConfigFile: Schema.NonEmptyString;
30
+ readonly tsGenOutFile: Schema.NonEmptyString;
31
+ readonly criticalCssFile: Schema.optionalKey<Schema.NonEmptyString>;
32
+ readonly entryFile: Schema.NonEmptyString;
33
+ readonly viewFilePattern: Schema.NonEmptyString;
34
+ }>;
35
+ readonly dev: Schema.optionalKey<Schema.Struct<{
36
+ readonly server: Schema.Struct<{
37
+ readonly cargoManifestFile: Schema.NonEmptyString;
38
+ readonly cargoBin: Schema.NonEmptyString;
39
+ readonly cargoArgs: Schema.optionalKey<Schema.$Array<Schema.String>>;
40
+ readonly binArgs: Schema.optionalKey<Schema.$Array<Schema.String>>;
41
+ readonly wrapCmdFn: Schema.optionalKey<Schema.declare<WrapCmd, WrapCmd>>;
42
+ readonly preferredPort: Schema.optionalKey<Schema.Int>;
43
+ }>;
44
+ readonly onChange: Schema.optionalKey<Schema.$Array<Schema.Struct<{
45
+ readonly triggers: Schema.NonEmptyArray<Schema.NonEmptyString>;
46
+ readonly actions: Schema.NonEmptyArray<Schema.Literals<readonly ["revalidate-client-data", "hard-browser-reload", "restart-server"]>>;
47
+ }>>>;
48
+ }>>;
49
+ }>;
50
+ /**
51
+ * The input of `vorma build` and `vorma dev`, which take the configuration
52
+ * file as their argument.
53
+ *
54
+ * `core.importMetaUrl` is the configuration file's own `import.meta.url`, and
55
+ * every configured path is relative to that file's directory. `core.distDir`
56
+ * is the directory that holds Vorma's build output: `vorma build` writes the
57
+ * production build to `prod` in it, and `vorma dev` writes the development
58
+ * build to `dev` in it. Vorma owns those two directories and writes nothing
59
+ * else in `core.distDir`.
60
+ * `core.staticPublicAssets.srcDir` holds the static public asset sources, and
61
+ * `serveUrlPathPrefix` is the URL path at which their hashed files are served. The build
62
+ * skips every entry in `srcDir`, at any depth, that is named `.DS_Store` or
63
+ * `.env`, or whose name starts with `.env.`, because env files hold secrets by
64
+ * convention and everything in the public output is public. A skipped file is
65
+ * not hashed, not published, not a `staticPublicAssets` key, not an input of
66
+ * the build ID, not watched by `vorma dev`, and not served. It publishes every
67
+ * other file, dotfiles included.
68
+ *
69
+ * `client` names the client project's tsconfig file, the file where the build
70
+ * writes its generated types, the Vite configuration, the browser entry, the
71
+ * view files as one glob pattern, and, optionally, the critical CSS file.
72
+ *
73
+ * `build.serverStartCmd` is the executable and arguments that `vorma build`
74
+ * runs without a shell from the configuration directory, with the
75
+ * declaration-read variable set, so that the application's server writes its
76
+ * declarations and ends. The application builds that server before it runs
77
+ * `vorma build`, or names a command that compiles and runs it. `vorma build`
78
+ * compiles nothing.
79
+ *
80
+ * `dev.server` configures the server that `vorma dev` compiles and runs.
81
+ * `cargoManifestFile` and `cargoBin` name the Cargo target that `vorma dev`
82
+ * compiles after each server change, and `cargoArgs` are added to that Cargo
83
+ * command. `vorma dev` reads the declarations by running the compiled
84
+ * executable with `binArgs`, then runs the same executable with `binArgs` as
85
+ * the development server, passing the application's port in `PORT`. When
86
+ * `wrapCmdFn` is set, the development server runs the command that `wrapCmdFn`
87
+ * returns for the executable and its arguments, for example to run it in a
88
+ * profiler. `wrapCmdFn` does not wrap the declaration reads.
89
+ * `preferredPort` is where the search for a free port starts. Each
90
+ * `dev.onChange` rule pairs file patterns with the actions that a change to a
91
+ * matching file requests. A pattern is relative to the configuration
92
+ * directory; a leading `!` excludes the files that it matches from the
93
+ * patterns before it. The configuration is invalid when a pattern is empty or
94
+ * when all of a rule's patterns are exclusions. `"restart-server"` rebuilds
95
+ * and restarts the application's server as a change to a source that Cargo
96
+ * tracks does, for a file that the server reads at run time and that Cargo
97
+ * does not track, such as a configuration file or a template.
98
+ *
99
+ * `vorma dev` never writes `prod` in `core.distDir`, and `vorma build` never
100
+ * writes `dev` in it, so a production build stays as it is while `vorma dev`
101
+ * runs.
102
+ */
103
+ export type VormaConfig = typeof VormaConfigSchema.Type;
104
+ /** Types a configuration object where it is written. */
105
+ export declare function defineConfig(config: VormaConfig): VormaConfig;
106
+ export {};
@@ -0,0 +1 @@
1
+ export { defineConfig, type DevAction, type VormaConfig } from "./config.ts";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { n as defineConfig } from "./config-FbabCxBO.js";
2
+ export { defineConfig };
@@ -0,0 +1,36 @@
1
+ import { Result } from "effect";
2
+ import { normalize } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ //#region src/vite/plugin-api.ts
5
+ /** The name by which Vorma's commands find the application's plugin in a resolved Vite configuration. */
6
+ const VORMA_PLUGIN_NAME = "vorma";
7
+ /** Runtime peers that must have one browser identity in every Vite invocation. */
8
+ const CLIENT_SHARED_PACKAGES = [
9
+ "@vorma/client",
10
+ "react",
11
+ "react-dom",
12
+ "preact",
13
+ "solid-js"
14
+ ];
15
+ /** The path of the configuration file that a configuration's `core.importMetaUrl` identifies. */
16
+ function readConfigFilePath(importMetaUrl) {
17
+ return Result.try({
18
+ try: () => fileURLToPath(importMetaUrl),
19
+ catch: () => {
20
+ return `core.importMetaUrl must be the configuration file's import.meta.url, got ${JSON.stringify(importMetaUrl)}`;
21
+ }
22
+ });
23
+ }
24
+ function findVormaPlugin(plugins) {
25
+ return plugins.find((plugin) => plugin.name === VORMA_PLUGIN_NAME);
26
+ }
27
+ /** Checks that a resolved Vite configuration's plugin carries the Vorma configuration file that a command loaded. */
28
+ function checkVormaPlugin(input) {
29
+ const plugin = findVormaPlugin(input.plugins);
30
+ if (plugin?.api === void 0) return Result.fail("Vorma requires vorma({ config }) from vorma/vite in the configured Vite plugins list.");
31
+ const { importMetaUrl } = plugin.api.config.core;
32
+ const pluginConfigFilePath = readConfigFilePath(importMetaUrl);
33
+ return Result.isSuccess(pluginConfigFilePath) && normalize(pluginConfigFilePath.success) === normalize(input.configFilePath) ? Result.succeed(void 0) : Result.fail(`The Vite configuration's vorma({ config }) received the configuration of ${importMetaUrl}, but Vorma loaded ${input.configFilePath}.`);
34
+ }
35
+ //#endregion
36
+ export { readConfigFilePath as i, VORMA_PLUGIN_NAME as n, checkVormaPlugin as r, CLIENT_SHARED_PACKAGES as t };