@swissjs/swite 0.4.1 → 0.4.2
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/CHANGELOG.md +7 -0
- package/__tests__/import-rewriter-bug.test.ts +122 -122
- package/__tests__/security-r001-r002.test.ts +190 -190
- package/dist/cli.js +0 -0
- package/dist/dev-engine/hmr/hmr-client-template.js +111 -111
- package/dist/dev-engine/middleware/middleware-setup.js +4 -3
- package/docs/architecture/build-pipeline.md +97 -97
- package/docs/architecture/dev-server.md +87 -87
- package/docs/architecture/hmr.md +78 -78
- package/docs/architecture/import-rewriting.md +101 -101
- package/docs/architecture/index.md +16 -16
- package/docs/architecture/python-integration.md +93 -93
- package/docs/architecture/resolution.md +92 -92
- package/docs/cli/build.md +78 -78
- package/docs/cli/dev.md +90 -90
- package/docs/cli/index.md +15 -15
- package/docs/cli/start.md +45 -45
- package/docs/development/contributing.md +74 -74
- package/docs/development/index.md +12 -12
- package/docs/development/internals.md +101 -101
- package/docs/guide/configuration.md +89 -89
- package/docs/guide/index.md +13 -13
- package/docs/guide/project-structure.md +75 -75
- package/docs/guide/quickstart.md +113 -113
- package/docs/index.md +16 -16
- package/package.json +10 -9
- package/src/config/env.ts +98 -98
- package/src/dev-engine/handlers/ui-handler.ts +30 -30
- package/src/dev-engine/handlers/uix-handler.ts +21 -21
- package/src/dev-engine/hmr/hmr-client-template.ts +122 -122
- package/src/dev-engine/middleware/middleware-setup.ts +354 -354
- package/src/dev-engine/middleware/static-files.ts +813 -813
- package/src/resolution/cdn/cdn-fallback.ts +40 -40
- package/src/resolution/path/path-fixup.ts +27 -27
- package/src/resolution/rewriting/import-rewriter.ts +237 -237
- package/src/resolution/symlink-registry.ts +114 -114
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Copyright (c) 2024 Themba Mzumara
|
|
3
|
-
SWITE - SWISS Development Server
|
|
4
|
-
Licensed under the MIT License.
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
# Contributing
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Build
|
|
12
|
-
|
|
13
|
-
SWITE is compiled from TypeScript to `dist/` using the TypeScript compiler:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pnpm build # single build
|
|
17
|
-
pnpm dev # watch mode (tsc -b --watch)
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
The `bin.swite` field in `package.json` points to `dist/cli.js`. After a build, the CLI is runnable as `node dist/cli.js dev` from the package root, or via the `swite` binary when the package is installed.
|
|
21
|
-
|
|
22
|
-
To clean build artifacts and `node_modules`:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pnpm clean
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Running tests
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
pnpm test
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Tests run via Node's built-in test runner (`node --import tsx --test`). Test files live in `__tests__/`. Add new test files with a `.test.ts` extension.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Generating an import map
|
|
41
|
-
|
|
42
|
-
The import map generation CLI is separate from the main build:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
pnpm generate-import-map
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This runs `src/internal/generate-import-map-cli.ts` via `tsx` and writes `.swite/import-map.json` in the current directory. Run this from the project root of an application, not from the SWITE package root.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Changesets and releases
|
|
53
|
-
|
|
54
|
-
SWITE uses `@changesets/cli` for versioning.
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
pnpm changeset # create a changeset for your changes
|
|
58
|
-
pnpm release:version # bump versions from pending changesets
|
|
59
|
-
pnpm release:publish # publish to npm
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Branch conventions
|
|
65
|
-
|
|
66
|
-
- Work in feature branches named `feat/<topic>` or `fix/<topic>`.
|
|
67
|
-
- Do not push directly to the default branch.
|
|
68
|
-
- Each PR should include a changeset unless the change is documentation-only.
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## Package scope
|
|
73
|
-
|
|
74
|
-
SWITE is published as `@swissjs/swite`. The npm registry is `registry.npmjs.org` with `access: public`. The repository is part of the `kibologic/alpine-erp-core` GitHub repo.
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2024 Themba Mzumara
|
|
3
|
+
SWITE - SWISS Development Server
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Contributing
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Build
|
|
12
|
+
|
|
13
|
+
SWITE is compiled from TypeScript to `dist/` using the TypeScript compiler:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm build # single build
|
|
17
|
+
pnpm dev # watch mode (tsc -b --watch)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The `bin.swite` field in `package.json` points to `dist/cli.js`. After a build, the CLI is runnable as `node dist/cli.js dev` from the package root, or via the `swite` binary when the package is installed.
|
|
21
|
+
|
|
22
|
+
To clean build artifacts and `node_modules`:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm clean
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Running tests
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm test
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Tests run via Node's built-in test runner (`node --import tsx --test`). Test files live in `__tests__/`. Add new test files with a `.test.ts` extension.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Generating an import map
|
|
41
|
+
|
|
42
|
+
The import map generation CLI is separate from the main build:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm generate-import-map
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This runs `src/internal/generate-import-map-cli.ts` via `tsx` and writes `.swite/import-map.json` in the current directory. Run this from the project root of an application, not from the SWITE package root.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Changesets and releases
|
|
53
|
+
|
|
54
|
+
SWITE uses `@changesets/cli` for versioning.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pnpm changeset # create a changeset for your changes
|
|
58
|
+
pnpm release:version # bump versions from pending changesets
|
|
59
|
+
pnpm release:publish # publish to npm
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Branch conventions
|
|
65
|
+
|
|
66
|
+
- Work in feature branches named `feat/<topic>` or `fix/<topic>`.
|
|
67
|
+
- Do not push directly to the default branch.
|
|
68
|
+
- Each PR should include a changeset unless the change is documentation-only.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Package scope
|
|
73
|
+
|
|
74
|
+
SWITE is published as `@swissjs/swite`. The npm registry is `registry.npmjs.org` with `access: public`. The repository is part of the `kibologic/alpine-erp-core` GitHub repo.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Copyright (c) 2024 Themba Mzumara
|
|
3
|
-
SWITE - SWISS Development Server
|
|
4
|
-
Licensed under the MIT License.
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
# Development
|
|
8
|
-
|
|
9
|
-
Notes for contributors and maintainers working on SWITE itself.
|
|
10
|
-
|
|
11
|
-
- [Contributing](./contributing.md) — local build, running tests, branch conventions
|
|
12
|
-
- [Internals](./internals.md) — workspace root detection algorithm, import map generation, symlink registry, package registry
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2024 Themba Mzumara
|
|
3
|
+
SWITE - SWISS Development Server
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Development
|
|
8
|
+
|
|
9
|
+
Notes for contributors and maintainers working on SWITE itself.
|
|
10
|
+
|
|
11
|
+
- [Contributing](./contributing.md) — local build, running tests, branch conventions
|
|
12
|
+
- [Internals](./internals.md) — workspace root detection algorithm, import map generation, symlink registry, package registry
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Copyright (c) 2024 Themba Mzumara
|
|
3
|
-
SWITE - SWISS Development Server
|
|
4
|
-
Licensed under the MIT License.
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
# Internals
|
|
8
|
-
|
|
9
|
-
Implementation notes for the non-obvious parts of SWITE.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Workspace root detection algorithm
|
|
14
|
-
|
|
15
|
-
Two separate implementations exist: one in `SwiteServer` (used at server startup) and one in `src/kernel/workspace.ts` (used by handlers and resolution code at request time). They are slightly different.
|
|
16
|
-
|
|
17
|
-
### SwiteServer.findWorkspaceRoot
|
|
18
|
-
|
|
19
|
-
Walks up to six directory levels from `startDir`. At each level it looks for:
|
|
20
|
-
1. A `pnpm-workspace.yaml` file, or
|
|
21
|
-
2. A `package.json` with a `workspaces` field
|
|
22
|
-
|
|
23
|
-
The first directory matching either condition is returned. `SwiteConfig.rootDir` short-circuits this search if set.
|
|
24
|
-
|
|
25
|
-
### kernel/workspace.findWorkspaceRoot
|
|
26
|
-
|
|
27
|
-
Walks up to ten directory levels from `root`. At each level it additionally requires the candidate directory to have either a `lib/` or `packages/` subdirectory alongside the workspace marker file. This stricter check ensures the resolved workspace root is the SWS root (the monorepo that owns the `lib/` directory with compiled packages), not an intermediate workspace.
|
|
28
|
-
|
|
29
|
-
If a directory has `pnpm-workspace.yaml` but no `lib/` or `packages/`, the walk continues upward. This handles nested monorepo layouts where an inner workspace exists inside an outer SWS root.
|
|
30
|
-
|
|
31
|
-
### file-path-resolver /lib/ path resolution
|
|
32
|
-
|
|
33
|
-
For `/lib/` URLs specifically, `resolveFilePath` walks from the app root upward looking for a directory that has both `pnpm-workspace.yaml` and a `lib/` subdirectory present simultaneously. This is the most precise check and handles the case where `findWorkspaceRoot` returns an intermediate directory.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Import map generation
|
|
38
|
-
|
|
39
|
-
`generateImportMap` (`src/internal/generate-import-map.ts`) runs at the request of the CLI or the `generate-import-map` script, not automatically at dev server startup.
|
|
40
|
-
|
|
41
|
-
The generated file format:
|
|
42
|
-
|
|
43
|
-
```json
|
|
44
|
-
{
|
|
45
|
-
"version": "1.0",
|
|
46
|
-
"generated": 1716211234567,
|
|
47
|
-
"imports": {
|
|
48
|
-
"@scope/pkg": "/swiss-packages/pkg/src/index.ts",
|
|
49
|
-
"@scope/pkg/components": "/swiss-packages/pkg/src/components/index.ts"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
At dev server startup, `setupMiddleware` calls `loadImportMap` to read this file. If found, it is passed to `ModuleResolver.setImportMap()` and becomes the fast path for all bare import resolutions. A cache miss falls through to the full `resolveBareImport` pipeline.
|
|
55
|
-
|
|
56
|
-
The SPA fallback handler also reads this file directly and merges it into the HTML importmap.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Symlink registry
|
|
61
|
-
|
|
62
|
-
`buildSymlinkRegistry` (`src/resolution/symlink-registry.ts`) is called once during server startup. It scans up to four `node_modules` directories:
|
|
63
|
-
|
|
64
|
-
1. `<appRoot>/node_modules`
|
|
65
|
-
2. `<parentOfAppRoot>/node_modules`
|
|
66
|
-
3. `<workspaceRoot>/node_modules`
|
|
67
|
-
4. `<frameworkMonorepoRoot>/node_modules`
|
|
68
|
-
|
|
69
|
-
For each directory, it reads all entries. For scoped entries (starting with `@`), it recurses one level and registers each symlink found there. For unscoped entries, it registers each symlink directly.
|
|
70
|
-
|
|
71
|
-
Registration: `fs.realpath(symlinkPath)` is resolved and stored in a `Map<string, string>` as `realpath → /node_modules/<pkgName>`.
|
|
72
|
-
|
|
73
|
-
`lookupInSymlinkRegistry(absolutePath)` iterates the map and returns the browser URL if the path starts with any registered realpath. This is called by `toUrl` as the very first step when an absolute path is received.
|
|
74
|
-
|
|
75
|
-
The registry is consulted before any other logic in `toUrl` because `fs.realpath()` is called throughout the handler chain (in `resolveFilePath` for `/node_modules/` URLs, in `NodeModuleHandler`, and elsewhere) and the resulting absolute paths would otherwise bypass all the workspace-relative URL conversion logic.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Package registry
|
|
80
|
-
|
|
81
|
-
`PackageRegistry` (`src/kernel/package-registry.ts`) is a process-wide singleton. It is first populated when `resolveWorkspacePackage` is called and the registry is empty. After that, it serves as a cache for the workspace scan.
|
|
82
|
-
|
|
83
|
-
The scan is recursive up to 15 levels deep and skips: `node_modules`, `dist`, `.git`, `.swite`, and hidden directories. Any directory containing a `package.json` with a `name` field is registered. Duplicates keep the first-found entry.
|
|
84
|
-
|
|
85
|
-
`rescan()` clears the cache and re-scans from the same root directories. It is called when a package is not found after the initial scan, in case new packages were added since the server started.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Compilation cache
|
|
90
|
-
|
|
91
|
-
`compilationCache` (`src/internal/cache/compilation-cache.ts`) is an in-memory cache keyed by absolute file path. Each entry stores the compiled source output and tracks the set of dependency URLs. Handlers call `compilationCache.get(filePath, getDependencies)` before compiling; if the file's mtime has not changed since the last compile, the cached output is returned.
|
|
92
|
-
|
|
93
|
-
Cache writes happen after every successful compilation via `compilationCache.set(filePath, rawCompiled, finalCode, getDependencies)`.
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## path-fixup rationale
|
|
98
|
-
|
|
99
|
-
`fixSwissLibPaths` exists because `@swissjs/compiler` was originally written when the framework packages directory was named `swiss-lib/packages/`. When the directory was renamed to be served under `/swiss-packages/`, the compiler was not updated at the same time. Rather than forking every handler to patch its own output, a single central fixup is applied once per compilation.
|
|
100
|
-
|
|
101
|
-
The fixup replaces `/swiss-lib/packages/` before `/swiss-lib/` to avoid double-substitution if the function were called more than once on already-patched output.
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2024 Themba Mzumara
|
|
3
|
+
SWITE - SWISS Development Server
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Internals
|
|
8
|
+
|
|
9
|
+
Implementation notes for the non-obvious parts of SWITE.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Workspace root detection algorithm
|
|
14
|
+
|
|
15
|
+
Two separate implementations exist: one in `SwiteServer` (used at server startup) and one in `src/kernel/workspace.ts` (used by handlers and resolution code at request time). They are slightly different.
|
|
16
|
+
|
|
17
|
+
### SwiteServer.findWorkspaceRoot
|
|
18
|
+
|
|
19
|
+
Walks up to six directory levels from `startDir`. At each level it looks for:
|
|
20
|
+
1. A `pnpm-workspace.yaml` file, or
|
|
21
|
+
2. A `package.json` with a `workspaces` field
|
|
22
|
+
|
|
23
|
+
The first directory matching either condition is returned. `SwiteConfig.rootDir` short-circuits this search if set.
|
|
24
|
+
|
|
25
|
+
### kernel/workspace.findWorkspaceRoot
|
|
26
|
+
|
|
27
|
+
Walks up to ten directory levels from `root`. At each level it additionally requires the candidate directory to have either a `lib/` or `packages/` subdirectory alongside the workspace marker file. This stricter check ensures the resolved workspace root is the SWS root (the monorepo that owns the `lib/` directory with compiled packages), not an intermediate workspace.
|
|
28
|
+
|
|
29
|
+
If a directory has `pnpm-workspace.yaml` but no `lib/` or `packages/`, the walk continues upward. This handles nested monorepo layouts where an inner workspace exists inside an outer SWS root.
|
|
30
|
+
|
|
31
|
+
### file-path-resolver /lib/ path resolution
|
|
32
|
+
|
|
33
|
+
For `/lib/` URLs specifically, `resolveFilePath` walks from the app root upward looking for a directory that has both `pnpm-workspace.yaml` and a `lib/` subdirectory present simultaneously. This is the most precise check and handles the case where `findWorkspaceRoot` returns an intermediate directory.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Import map generation
|
|
38
|
+
|
|
39
|
+
`generateImportMap` (`src/internal/generate-import-map.ts`) runs at the request of the CLI or the `generate-import-map` script, not automatically at dev server startup.
|
|
40
|
+
|
|
41
|
+
The generated file format:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"version": "1.0",
|
|
46
|
+
"generated": 1716211234567,
|
|
47
|
+
"imports": {
|
|
48
|
+
"@scope/pkg": "/swiss-packages/pkg/src/index.ts",
|
|
49
|
+
"@scope/pkg/components": "/swiss-packages/pkg/src/components/index.ts"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
At dev server startup, `setupMiddleware` calls `loadImportMap` to read this file. If found, it is passed to `ModuleResolver.setImportMap()` and becomes the fast path for all bare import resolutions. A cache miss falls through to the full `resolveBareImport` pipeline.
|
|
55
|
+
|
|
56
|
+
The SPA fallback handler also reads this file directly and merges it into the HTML importmap.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Symlink registry
|
|
61
|
+
|
|
62
|
+
`buildSymlinkRegistry` (`src/resolution/symlink-registry.ts`) is called once during server startup. It scans up to four `node_modules` directories:
|
|
63
|
+
|
|
64
|
+
1. `<appRoot>/node_modules`
|
|
65
|
+
2. `<parentOfAppRoot>/node_modules`
|
|
66
|
+
3. `<workspaceRoot>/node_modules`
|
|
67
|
+
4. `<frameworkMonorepoRoot>/node_modules`
|
|
68
|
+
|
|
69
|
+
For each directory, it reads all entries. For scoped entries (starting with `@`), it recurses one level and registers each symlink found there. For unscoped entries, it registers each symlink directly.
|
|
70
|
+
|
|
71
|
+
Registration: `fs.realpath(symlinkPath)` is resolved and stored in a `Map<string, string>` as `realpath → /node_modules/<pkgName>`.
|
|
72
|
+
|
|
73
|
+
`lookupInSymlinkRegistry(absolutePath)` iterates the map and returns the browser URL if the path starts with any registered realpath. This is called by `toUrl` as the very first step when an absolute path is received.
|
|
74
|
+
|
|
75
|
+
The registry is consulted before any other logic in `toUrl` because `fs.realpath()` is called throughout the handler chain (in `resolveFilePath` for `/node_modules/` URLs, in `NodeModuleHandler`, and elsewhere) and the resulting absolute paths would otherwise bypass all the workspace-relative URL conversion logic.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Package registry
|
|
80
|
+
|
|
81
|
+
`PackageRegistry` (`src/kernel/package-registry.ts`) is a process-wide singleton. It is first populated when `resolveWorkspacePackage` is called and the registry is empty. After that, it serves as a cache for the workspace scan.
|
|
82
|
+
|
|
83
|
+
The scan is recursive up to 15 levels deep and skips: `node_modules`, `dist`, `.git`, `.swite`, and hidden directories. Any directory containing a `package.json` with a `name` field is registered. Duplicates keep the first-found entry.
|
|
84
|
+
|
|
85
|
+
`rescan()` clears the cache and re-scans from the same root directories. It is called when a package is not found after the initial scan, in case new packages were added since the server started.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Compilation cache
|
|
90
|
+
|
|
91
|
+
`compilationCache` (`src/internal/cache/compilation-cache.ts`) is an in-memory cache keyed by absolute file path. Each entry stores the compiled source output and tracks the set of dependency URLs. Handlers call `compilationCache.get(filePath, getDependencies)` before compiling; if the file's mtime has not changed since the last compile, the cached output is returned.
|
|
92
|
+
|
|
93
|
+
Cache writes happen after every successful compilation via `compilationCache.set(filePath, rawCompiled, finalCode, getDependencies)`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## path-fixup rationale
|
|
98
|
+
|
|
99
|
+
`fixSwissLibPaths` exists because `@swissjs/compiler` was originally written when the framework packages directory was named `swiss-lib/packages/`. When the directory was renamed to be served under `/swiss-packages/`, the compiler was not updated at the same time. Rather than forking every handler to patch its own output, a single central fixup is applied once per compilation.
|
|
100
|
+
|
|
101
|
+
The fixup replaces `/swiss-lib/packages/` before `/swiss-lib/` to avoid double-substitution if the function were called more than once on already-patched output.
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Copyright (c) 2024 Themba Mzumara
|
|
3
|
-
SWITE - SWISS Development Server
|
|
4
|
-
Licensed under the MIT License.
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
# Configuration
|
|
8
|
-
|
|
9
|
-
SWITE reads `swiss.config.ts` (or `swiss.config.js`) from the project root. The file must export a `SwiteUserConfig` object as its default export, typically via the `defineConfig` helper.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
// swiss.config.ts
|
|
13
|
-
import { defineConfig } from '@swissjs/swite';
|
|
14
|
-
|
|
15
|
-
export default defineConfig({
|
|
16
|
-
server: {
|
|
17
|
-
port: 3000,
|
|
18
|
-
host: 'localhost',
|
|
19
|
-
},
|
|
20
|
-
services: {
|
|
21
|
-
python: {
|
|
22
|
-
entry: 'server/main.py',
|
|
23
|
-
port: 8000,
|
|
24
|
-
autoStart: true,
|
|
25
|
-
healthCheck: '/health',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The config file is transpiled to ESM by esbuild at startup (bundling disabled, `platform: node`). The temporary output file is cleaned up before the server starts.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## SwiteUserConfig
|
|
36
|
-
|
|
37
|
-
| Field | Type | Default | Description |
|
|
38
|
-
|-------|------|---------|-------------|
|
|
39
|
-
| `server` | `ServerConfig` | `{}` | HTTP server options |
|
|
40
|
-
| `services` | `ServicesConfig` | `{}` | External service options |
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## ServerConfig
|
|
45
|
-
|
|
46
|
-
| Field | Type | Default | Description |
|
|
47
|
-
|-------|------|---------|-------------|
|
|
48
|
-
| `port` | `number` | `3000` | Port for the HTTP server |
|
|
49
|
-
| `host` | `string` | `"localhost"` | Host to bind. When `"localhost"`, SWITE binds to `0.0.0.0` internally so both IPv4 and IPv6 loopback addresses work |
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## ServicesConfig
|
|
54
|
-
|
|
55
|
-
| Field | Type | Default | Description |
|
|
56
|
-
|-------|------|---------|-------------|
|
|
57
|
-
| `python` | `PythonServiceConfig` | — | Python service definition. Omit if you have no Python backend |
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## PythonServiceConfig
|
|
62
|
-
|
|
63
|
-
| Field | Type | Required | Description |
|
|
64
|
-
|-------|------|----------|-------------|
|
|
65
|
-
| `entry` | `string` | Yes | Path to the Python entry file, relative to the project root (e.g. `"server/main.py"`) |
|
|
66
|
-
| `port` | `number` | Yes | Port the Python service listens on |
|
|
67
|
-
| `autoStart` | `boolean` | Yes | When `true`, `swite dev` spawns the Python process automatically before starting the Node server |
|
|
68
|
-
| `healthCheck` | `string` | Yes | URL path polled to determine when the Python service is ready (e.g. `"/health"`). SWITE polls `http://localhost:{port}{healthCheck}` every 500 ms, with exponential back-off after five attempts, timing out after 15 seconds |
|
|
69
|
-
| `env` | `Record<string, string>` | No | Additional environment variables merged into the Python process environment alongside `PORT={port}` |
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## defineConfig
|
|
74
|
-
|
|
75
|
-
`defineConfig(config: SwiteUserConfig): SwiteUserConfig` is a pass-through identity function that provides TypeScript type checking at the call site. Unknown fields are rejected at compile time.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Environment variables
|
|
80
|
-
|
|
81
|
-
In addition to `swiss.config.ts`, SWITE reads `.env` files at the project root for `import.meta.env` inlining. Variables are inlined at compile time into each compiled module; they are not available at runtime via a global object. SWITE loads both a base `.env` and a mode-specific `.env.development` or `.env.production` depending on whether the server is running in dev or production mode.
|
|
82
|
-
|
|
83
|
-
The following environment variables affect SWITE's own runtime behavior:
|
|
84
|
-
|
|
85
|
-
| Variable | Description |
|
|
86
|
-
|----------|-------------|
|
|
87
|
-
| `PYTHON_SERVICE_URL` | Base URL of the Python service in production. Required when running `swite start` with a Python service configured. Overrides the localhost fallback used in dev. |
|
|
88
|
-
| `INTERNAL_API_TOKEN` | Value injected as the `X-Internal-Token` header on every `proxyToPython` call |
|
|
89
|
-
| `SWITE_CDN_FALLBACK_SCOPES` | Comma-separated list of scoped package prefixes (e.g. `@types,@tanstack`) that are allowed to fall back to jsDelivr when not found locally. Unscoped packages always fall back. Scoped packages do not fall back by default. |
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2024 Themba Mzumara
|
|
3
|
+
SWITE - SWISS Development Server
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Configuration
|
|
8
|
+
|
|
9
|
+
SWITE reads `swiss.config.ts` (or `swiss.config.js`) from the project root. The file must export a `SwiteUserConfig` object as its default export, typically via the `defineConfig` helper.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// swiss.config.ts
|
|
13
|
+
import { defineConfig } from '@swissjs/swite';
|
|
14
|
+
|
|
15
|
+
export default defineConfig({
|
|
16
|
+
server: {
|
|
17
|
+
port: 3000,
|
|
18
|
+
host: 'localhost',
|
|
19
|
+
},
|
|
20
|
+
services: {
|
|
21
|
+
python: {
|
|
22
|
+
entry: 'server/main.py',
|
|
23
|
+
port: 8000,
|
|
24
|
+
autoStart: true,
|
|
25
|
+
healthCheck: '/health',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The config file is transpiled to ESM by esbuild at startup (bundling disabled, `platform: node`). The temporary output file is cleaned up before the server starts.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## SwiteUserConfig
|
|
36
|
+
|
|
37
|
+
| Field | Type | Default | Description |
|
|
38
|
+
|-------|------|---------|-------------|
|
|
39
|
+
| `server` | `ServerConfig` | `{}` | HTTP server options |
|
|
40
|
+
| `services` | `ServicesConfig` | `{}` | External service options |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## ServerConfig
|
|
45
|
+
|
|
46
|
+
| Field | Type | Default | Description |
|
|
47
|
+
|-------|------|---------|-------------|
|
|
48
|
+
| `port` | `number` | `3000` | Port for the HTTP server |
|
|
49
|
+
| `host` | `string` | `"localhost"` | Host to bind. When `"localhost"`, SWITE binds to `0.0.0.0` internally so both IPv4 and IPv6 loopback addresses work |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## ServicesConfig
|
|
54
|
+
|
|
55
|
+
| Field | Type | Default | Description |
|
|
56
|
+
|-------|------|---------|-------------|
|
|
57
|
+
| `python` | `PythonServiceConfig` | — | Python service definition. Omit if you have no Python backend |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## PythonServiceConfig
|
|
62
|
+
|
|
63
|
+
| Field | Type | Required | Description |
|
|
64
|
+
|-------|------|----------|-------------|
|
|
65
|
+
| `entry` | `string` | Yes | Path to the Python entry file, relative to the project root (e.g. `"server/main.py"`) |
|
|
66
|
+
| `port` | `number` | Yes | Port the Python service listens on |
|
|
67
|
+
| `autoStart` | `boolean` | Yes | When `true`, `swite dev` spawns the Python process automatically before starting the Node server |
|
|
68
|
+
| `healthCheck` | `string` | Yes | URL path polled to determine when the Python service is ready (e.g. `"/health"`). SWITE polls `http://localhost:{port}{healthCheck}` every 500 ms, with exponential back-off after five attempts, timing out after 15 seconds |
|
|
69
|
+
| `env` | `Record<string, string>` | No | Additional environment variables merged into the Python process environment alongside `PORT={port}` |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## defineConfig
|
|
74
|
+
|
|
75
|
+
`defineConfig(config: SwiteUserConfig): SwiteUserConfig` is a pass-through identity function that provides TypeScript type checking at the call site. Unknown fields are rejected at compile time.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Environment variables
|
|
80
|
+
|
|
81
|
+
In addition to `swiss.config.ts`, SWITE reads `.env` files at the project root for `import.meta.env` inlining. Variables are inlined at compile time into each compiled module; they are not available at runtime via a global object. SWITE loads both a base `.env` and a mode-specific `.env.development` or `.env.production` depending on whether the server is running in dev or production mode.
|
|
82
|
+
|
|
83
|
+
The following environment variables affect SWITE's own runtime behavior:
|
|
84
|
+
|
|
85
|
+
| Variable | Description |
|
|
86
|
+
|----------|-------------|
|
|
87
|
+
| `PYTHON_SERVICE_URL` | Base URL of the Python service in production. Required when running `swite start` with a Python service configured. Overrides the localhost fallback used in dev. |
|
|
88
|
+
| `INTERNAL_API_TOKEN` | Value injected as the `X-Internal-Token` header on every `proxyToPython` call |
|
|
89
|
+
| `SWITE_CDN_FALLBACK_SCOPES` | Comma-separated list of scoped package prefixes (e.g. `@types,@tanstack`) that are allowed to fall back to jsDelivr when not found locally. Unscoped packages always fall back. Scoped packages do not fall back by default. |
|
package/docs/guide/index.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Copyright (c) 2024 Themba Mzumara
|
|
3
|
-
SWITE - SWISS Development Server
|
|
4
|
-
Licensed under the MIT License.
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
# Guide
|
|
8
|
-
|
|
9
|
-
Start here. This guide covers installing SWITE, laying out a project, configuring it, and building for production.
|
|
10
|
-
|
|
11
|
-
- [Quickstart](./quickstart.md) — install, run `swite dev`, write your first component, build
|
|
12
|
-
- [Project structure](./project-structure.md) — recommended directory layout, public dir, config file location
|
|
13
|
-
- [Configuration](./configuration.md) — full `SwiteUserConfig` and `PythonServiceConfig` reference
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2024 Themba Mzumara
|
|
3
|
+
SWITE - SWISS Development Server
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Guide
|
|
8
|
+
|
|
9
|
+
Start here. This guide covers installing SWITE, laying out a project, configuring it, and building for production.
|
|
10
|
+
|
|
11
|
+
- [Quickstart](./quickstart.md) — install, run `swite dev`, write your first component, build
|
|
12
|
+
- [Project structure](./project-structure.md) — recommended directory layout, public dir, config file location
|
|
13
|
+
- [Configuration](./configuration.md) — full `SwiteUserConfig` and `PythonServiceConfig` reference
|