@jk2908/solas 0.5.4 → 0.6.0
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 +24 -0
- package/README.md +81 -85
- package/dist/config.d.ts +25 -0
- package/dist/config.js +152 -0
- package/dist/events.d.ts +4 -0
- package/dist/events.js +5 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +59 -37
- package/dist/internal/boundary-error.d.ts +4 -0
- package/dist/internal/boundary-error.js +8 -0
- package/dist/internal/browser-router/history.d.ts +1 -1
- package/dist/internal/browser-router/link.d.ts +1 -1
- package/dist/internal/browser-router/link.js +1 -1
- package/dist/internal/browser-router/router.d.ts +2 -2
- package/dist/internal/browser-router/router.js +5 -5
- package/dist/internal/browser-router/shared.d.ts +182 -184
- package/dist/internal/browser-router/shared.js +49 -56
- package/dist/internal/browser-router/use-router.d.ts +1 -1
- package/dist/internal/browser-router/use-search-params.js +3 -3
- package/dist/internal/build.d.ts +108 -110
- package/dist/internal/build.js +569 -581
- package/dist/internal/codegen/config.js +3 -3
- package/dist/internal/codegen/environments.js +5 -6
- package/dist/internal/codegen/format.d.ts +6 -0
- package/dist/internal/codegen/format.js +24 -0
- package/dist/internal/codegen/manifest.js +2 -2
- package/dist/internal/codegen/maps.d.ts +1 -1
- package/dist/internal/codegen/maps.js +2 -2
- package/dist/internal/codegen/types.js +4 -4
- package/dist/internal/codegen/utils.js +2 -2
- package/dist/internal/env/request-context.js +1 -1
- package/dist/internal/env/rsc.d.ts +3 -2
- package/dist/internal/env/rsc.js +26 -25
- package/dist/internal/env/ssr.js +4 -4
- package/dist/internal/http-router/router.js +8 -8
- package/dist/internal/metadata.d.ts +1 -1
- package/dist/internal/metadata.js +1 -1
- package/dist/internal/navigation/http-exception-boundary.d.ts +1 -1
- package/dist/internal/navigation/redirect-boundary.d.ts +1 -1
- package/dist/internal/navigation/redirect.js +6 -6
- package/dist/internal/postbuild.js +18 -17
- package/dist/internal/prerender.d.ts +130 -138
- package/dist/internal/prerender.js +326 -354
- package/dist/internal/public-files.js +2 -4
- package/dist/internal/render/head.js +2 -2
- package/dist/internal/resolver.js +1 -1
- package/dist/internal/server/actions.js +2 -2
- package/dist/internal/ui/error-boundary.d.ts +1 -1
- package/dist/manifest.d.ts +7 -0
- package/dist/manifest.js +85 -0
- package/dist/prerender.d.ts +1 -1
- package/dist/prerender.js +1 -1
- package/dist/solas.d.ts +2 -46
- package/dist/solas.js +6 -266
- package/dist/types.d.ts +14 -21
- package/dist/types.js +1 -1
- package/dist/utils/base-path.d.ts +12 -14
- package/dist/utils/base-path.js +75 -82
- package/dist/utils/compress.d.ts +9 -11
- package/dist/utils/compress.js +59 -64
- package/dist/utils/context.d.ts +4 -6
- package/dist/utils/context.js +17 -22
- package/dist/utils/logger.js +2 -2
- package/dist/utils/time.d.ts +2 -4
- package/dist/utils/time.js +23 -29
- package/package.json +18 -8
package/dist/index.js
CHANGED
|
@@ -5,10 +5,12 @@ import { createServer, loadConfigFromFile, } from 'vite';
|
|
|
5
5
|
import rsc from '@vitejs/plugin-rsc';
|
|
6
6
|
import { ExportReader } from './utils/export-reader.js';
|
|
7
7
|
import { Logger } from './utils/logger.js';
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
8
|
+
import { debounce } from './utils/time.js';
|
|
9
|
+
import * as Config from './config.js';
|
|
10
|
+
import * as Build from './internal/build.js';
|
|
10
11
|
import { writeConfig } from './internal/codegen/config.js';
|
|
11
12
|
import { writeBrowserEntry, writeRSCEntry, writeSSREntry, } from './internal/codegen/environments.js';
|
|
13
|
+
import { format as formatSource } from './internal/codegen/format.js';
|
|
12
14
|
import { writeManifest } from './internal/codegen/manifest.js';
|
|
13
15
|
import { writeMaps } from './internal/codegen/maps.js';
|
|
14
16
|
import { writeTypes } from './internal/codegen/types.js';
|
|
@@ -16,7 +18,6 @@ import { postbuild } from './internal/postbuild.js';
|
|
|
16
18
|
import { collect as collectPublicFiles } from './internal/public-files.js';
|
|
17
19
|
import { createRuntime } from './internal/runtimes/create.js';
|
|
18
20
|
import { Runtime } from './internal/runtimes/runtime.js';
|
|
19
|
-
import { Solas } from './solas.js';
|
|
20
21
|
const DEFAULT_CONFIG = {
|
|
21
22
|
runtime: 'auto',
|
|
22
23
|
precompress: false,
|
|
@@ -25,15 +26,14 @@ const DEFAULT_CONFIG = {
|
|
|
25
26
|
trailingSlash: 'never',
|
|
26
27
|
};
|
|
27
28
|
function solas(c) {
|
|
28
|
-
const validatedConfig =
|
|
29
|
-
...c,
|
|
30
|
-
url: c?.url ?? process.env.VITE_APP_URL?.toString(),
|
|
31
|
-
});
|
|
29
|
+
const validatedConfig = Config.validate(c);
|
|
32
30
|
const config = {
|
|
33
31
|
...DEFAULT_CONFIG,
|
|
34
32
|
...validatedConfig,
|
|
35
33
|
runtime: validatedConfig.runtime ?? DEFAULT_CONFIG.runtime,
|
|
36
34
|
};
|
|
35
|
+
const envUrl = process.env.VITE_APP_URL?.toString();
|
|
36
|
+
let resolvedUrl = c?.url ?? (envUrl && envUrl.length > 0 ? envUrl : undefined);
|
|
37
37
|
Runtime.runtime = createRuntime(config.runtime);
|
|
38
38
|
if (config.logger?.level)
|
|
39
39
|
Logger.defaultLevel = config.logger.level;
|
|
@@ -93,8 +93,8 @@ function solas(c) {
|
|
|
93
93
|
}
|
|
94
94
|
async function build() {
|
|
95
95
|
const cwd = process.cwd();
|
|
96
|
-
const routesDir = path.join(cwd,
|
|
97
|
-
const generatedDir = path.join(cwd,
|
|
96
|
+
const routesDir = path.join(cwd, Config.APP_DIR);
|
|
97
|
+
const generatedDir = path.join(cwd, Config.GENERATED_DIR);
|
|
98
98
|
await Promise.all([
|
|
99
99
|
fs.mkdir(routesDir, { recursive: true }),
|
|
100
100
|
fs.mkdir(generatedDir, { recursive: true }),
|
|
@@ -107,12 +107,27 @@ function solas(c) {
|
|
|
107
107
|
['config.ts', writeConfig(config)],
|
|
108
108
|
['manifest.ts', writeManifest(manifest)],
|
|
109
109
|
['maps.ts', writeMaps(imports, modules)],
|
|
110
|
-
[`${
|
|
111
|
-
[
|
|
112
|
-
[
|
|
113
|
-
[
|
|
110
|
+
[`${Config.SLUG}.d.ts`, writeTypes(manifest)],
|
|
111
|
+
[Config.ENTRY_RSC, writeRSCEntry(config)],
|
|
112
|
+
[Config.ENTRY_SSR, writeSSREntry()],
|
|
113
|
+
[Config.ENTRY_BROWSER, writeBrowserEntry()],
|
|
114
114
|
];
|
|
115
|
-
|
|
115
|
+
// remove generated files no longer emitted by the current codegen, so
|
|
116
|
+
// old artifacts don't linger and break module resolution. keep
|
|
117
|
+
// closeBundle's build.json, which lives in the same directory
|
|
118
|
+
const currentFiles = new Set(files.map(([file]) => file));
|
|
119
|
+
const existing = await fs
|
|
120
|
+
.readdir(generatedDir, { withFileTypes: true })
|
|
121
|
+
.catch(() => []);
|
|
122
|
+
await Promise.all(existing
|
|
123
|
+
.filter(entry => entry.isFile() &&
|
|
124
|
+
entry.name !== 'build.json' &&
|
|
125
|
+
!currentFiles.has(entry.name))
|
|
126
|
+
.map(entry => fs.rm(path.join(generatedDir, entry.name), { force: true })));
|
|
127
|
+
const writes = await Promise.all(files.map(async ([file, content]) => {
|
|
128
|
+
const formatted = await formatSource(file, content);
|
|
129
|
+
return maybeWrite(path.join(generatedDir, file), formatted);
|
|
130
|
+
}));
|
|
116
131
|
const changed = writes.filter(n => n !== null);
|
|
117
132
|
// early return if nothing has changed
|
|
118
133
|
if (!changed.length)
|
|
@@ -125,7 +140,7 @@ function solas(c) {
|
|
|
125
140
|
// normalise all watcher paths to forward slashes so path checks behave the
|
|
126
141
|
// same on Windows and POSIX
|
|
127
142
|
const WATCH_CWD = process.cwd().replace(/\\/g, '/');
|
|
128
|
-
const WATCH_APP_ROOT = `${WATCH_CWD}/${
|
|
143
|
+
const WATCH_APP_ROOT = `${WATCH_CWD}/${Config.APP_DIR}/`;
|
|
129
144
|
// convert watcher paths to a consistent slash format before comparing them
|
|
130
145
|
const normaliseWatchPath = (p) => p.replace(/\\/g, '/');
|
|
131
146
|
// resolve relative watcher paths against the project root so prefix checks are reliable
|
|
@@ -136,7 +151,7 @@ function solas(c) {
|
|
|
136
151
|
// edits needing special treatment because verb exports can change in-place
|
|
137
152
|
const routeFile = /\/\+(layout|page|401|403|404|500|loading|middleware|endpoint)\.(t|j)sx?$/;
|
|
138
153
|
const endpointFile = /\/\+endpoint\.(t|j)sx?$/;
|
|
139
|
-
const rebuild =
|
|
154
|
+
const rebuild = debounce((event, p) => {
|
|
140
155
|
const queue = () => {
|
|
141
156
|
void (async () => {
|
|
142
157
|
// collapse bursts of file events into one active rebuild plus a single
|
|
@@ -197,9 +212,7 @@ function solas(c) {
|
|
|
197
212
|
return [];
|
|
198
213
|
if (Array.isArray(plugin))
|
|
199
214
|
return plugin.flatMap(flatten);
|
|
200
|
-
if (typeof plugin === 'object' &&
|
|
201
|
-
'name' in plugin &&
|
|
202
|
-
plugin.name === Solas.Config.NAME) {
|
|
215
|
+
if (typeof plugin === 'object' && 'name' in plugin && plugin.name === Config.NAME) {
|
|
203
216
|
return [];
|
|
204
217
|
}
|
|
205
218
|
return [plugin];
|
|
@@ -219,26 +232,35 @@ function solas(c) {
|
|
|
219
232
|
return utilityServer;
|
|
220
233
|
}
|
|
221
234
|
const plugin = {
|
|
222
|
-
name:
|
|
235
|
+
name: Config.NAME,
|
|
223
236
|
async config(viteConfig) {
|
|
224
237
|
const pkg = JSON.parse(fsSync.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
225
238
|
if (typeof pkg.name !== 'string' || pkg.name.length === 0) {
|
|
226
|
-
throw new Error(`Missing ${
|
|
239
|
+
throw new Error(`Missing ${Config.NAME} package name`);
|
|
227
240
|
}
|
|
228
241
|
if (typeof pkg.version !== 'string' || pkg.version.length === 0) {
|
|
229
|
-
throw new Error(`Missing ${
|
|
242
|
+
throw new Error(`Missing ${Config.NAME} package version`);
|
|
230
243
|
}
|
|
231
244
|
viteConfig.build ??= {};
|
|
232
|
-
viteConfig.build.outDir =
|
|
245
|
+
viteConfig.build.outDir = Config.OUT_DIR;
|
|
233
246
|
// keep framework files under one reserved url prefix
|
|
234
|
-
viteConfig.build.assetsDir =
|
|
247
|
+
viteConfig.build.assetsDir = Config.ASSETS_DIR;
|
|
235
248
|
viteConfig.build.emptyOutDir = true;
|
|
236
249
|
// let users move the source public folder if they want
|
|
237
|
-
viteConfig.publicDir ??=
|
|
250
|
+
viteConfig.publicDir ??= Config.PUBLIC_DIR;
|
|
238
251
|
viteConfig.server ??= {};
|
|
239
|
-
viteConfig.server.port
|
|
252
|
+
viteConfig.server.port ??= 8787;
|
|
253
|
+
// derive the public url from vite's dev server settings when no
|
|
254
|
+
// origin was set explicitly via the url option or VITE_APP_URL
|
|
255
|
+
if (resolvedUrl === undefined) {
|
|
256
|
+
const { host, port } = viteConfig.server;
|
|
257
|
+
const hostname = typeof host === 'string' && host.length > 0 && host !== '0.0.0.0'
|
|
258
|
+
? host
|
|
259
|
+
: 'localhost';
|
|
260
|
+
resolvedUrl = `http://${hostname}:${port}`;
|
|
261
|
+
}
|
|
240
262
|
viteConfig.define ??= {};
|
|
241
|
-
viteConfig.define['import.meta.env.VITE_APP_URL'] = JSON.stringify(
|
|
263
|
+
viteConfig.define['import.meta.env.VITE_APP_URL'] = JSON.stringify(resolvedUrl);
|
|
242
264
|
viteConfig.define['import.meta.env.SOLAS_VERSION'] = JSON.stringify(pkg.version);
|
|
243
265
|
viteConfig.optimizeDeps ??= {};
|
|
244
266
|
viteConfig.optimizeDeps.exclude = [
|
|
@@ -255,12 +277,12 @@ function solas(c) {
|
|
|
255
277
|
...viteConfig.resolve.alias,
|
|
256
278
|
{
|
|
257
279
|
find: '.solas',
|
|
258
|
-
replacement: path.resolve(process.cwd(),
|
|
280
|
+
replacement: path.resolve(process.cwd(), Config.GENERATED_DIR),
|
|
259
281
|
},
|
|
260
282
|
]
|
|
261
283
|
: {
|
|
262
284
|
...viteConfig.resolve.alias,
|
|
263
|
-
'.solas': path.resolve(process.cwd(),
|
|
285
|
+
'.solas': path.resolve(process.cwd(), Config.GENERATED_DIR),
|
|
264
286
|
};
|
|
265
287
|
},
|
|
266
288
|
configResolved(resolvedConfig) {
|
|
@@ -268,7 +290,7 @@ function solas(c) {
|
|
|
268
290
|
buildContext.command = resolvedConfig.command;
|
|
269
291
|
},
|
|
270
292
|
configureServer(server) {
|
|
271
|
-
logger.info('[configureServer]', `Watching for changes in ./${
|
|
293
|
+
logger.info('[configureServer]', `Watching for changes in ./${Config.APP_DIR}...`);
|
|
272
294
|
server.watcher
|
|
273
295
|
.on('add', (p) => rebuild('add', p))
|
|
274
296
|
.on('change', (p) => rebuild('change', p))
|
|
@@ -294,7 +316,7 @@ function solas(c) {
|
|
|
294
316
|
}
|
|
295
317
|
// resolve sitemap routes
|
|
296
318
|
let sitemapRoutes = [];
|
|
297
|
-
if (config.sitemap &&
|
|
319
|
+
if (config.sitemap && resolvedUrl) {
|
|
298
320
|
const auto = [
|
|
299
321
|
...new Set([...buildContext.knownRoutes, ...buildContext.prerenderRoutes]),
|
|
300
322
|
];
|
|
@@ -306,7 +328,7 @@ function solas(c) {
|
|
|
306
328
|
}
|
|
307
329
|
}
|
|
308
330
|
// write build manifest
|
|
309
|
-
const generatedDir = path.join(process.cwd(),
|
|
331
|
+
const generatedDir = path.join(process.cwd(), Config.GENERATED_DIR);
|
|
310
332
|
await Runtime.write(path.join(generatedDir, 'build.json'), JSON.stringify({
|
|
311
333
|
base: resolvedViteConfig?.base ?? '/',
|
|
312
334
|
publicFiles: await collectPublicFiles(resolvedViteConfig?.publicDir),
|
|
@@ -314,7 +336,7 @@ function solas(c) {
|
|
|
314
336
|
sitemapRoutes,
|
|
315
337
|
precompress: config.precompress,
|
|
316
338
|
trailingSlash: config.trailingSlash,
|
|
317
|
-
url:
|
|
339
|
+
url: resolvedUrl,
|
|
318
340
|
}));
|
|
319
341
|
},
|
|
320
342
|
buildApp: {
|
|
@@ -328,12 +350,12 @@ function solas(c) {
|
|
|
328
350
|
plugin,
|
|
329
351
|
rsc({
|
|
330
352
|
entries: {
|
|
331
|
-
rsc: `./${
|
|
332
|
-
ssr: `./${
|
|
333
|
-
client: `./${
|
|
353
|
+
rsc: `./${Config.GENERATED_DIR}/${Config.ENTRY_RSC}`,
|
|
354
|
+
ssr: `./${Config.GENERATED_DIR}/${Config.ENTRY_SSR}`,
|
|
355
|
+
client: `./${Config.GENERATED_DIR}/${Config.ENTRY_BROWSER}`,
|
|
334
356
|
},
|
|
335
357
|
}),
|
|
336
358
|
];
|
|
337
359
|
}
|
|
338
360
|
export default solas;
|
|
339
|
-
export
|
|
361
|
+
export * as Solas from './solas.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef } from 'react';
|
|
4
|
-
import
|
|
4
|
+
import * as BrowserRouter from './shared.js';
|
|
5
5
|
import { useRouter } from './use-router.js';
|
|
6
6
|
function guard(path, prefetcher) {
|
|
7
7
|
const connection = window.navigator.connection;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RscPayload } from '../env/rsc.js';
|
|
2
|
-
import
|
|
3
|
-
export
|
|
2
|
+
import * as BrowserRouter from './shared.js';
|
|
3
|
+
export * as BrowserRouter from './shared.js';
|
|
4
4
|
export declare const BrowserRouterContext: import("react").Context<BrowserRouter.Context>;
|
|
5
5
|
export declare function BrowserRouterProvider({ children, setPayload, isNavigating, url }: {
|
|
6
6
|
children: React.ReactNode;
|
|
@@ -3,11 +3,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { createContext, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { createFromFetch } from '@vitejs/plugin-rsc/browser';
|
|
5
5
|
import { Logger } from '../../utils/logger.js';
|
|
6
|
-
import
|
|
6
|
+
import * as Events from '../../events.js';
|
|
7
7
|
import { BrowserRouterHistory } from './history.js';
|
|
8
8
|
import { ResponseCache } from './response-cache.js';
|
|
9
|
-
import
|
|
10
|
-
export
|
|
9
|
+
import * as BrowserRouter from './shared.js';
|
|
10
|
+
export * as BrowserRouter from './shared.js';
|
|
11
11
|
export const BrowserRouterContext = createContext({
|
|
12
12
|
go: async () => '',
|
|
13
13
|
prefetch: () => { },
|
|
@@ -98,7 +98,7 @@ export function BrowserRouterProvider({ children, setPayload, isNavigating = fal
|
|
|
98
98
|
history.current.replaceState(resolvedPath);
|
|
99
99
|
}
|
|
100
100
|
setPayload?.(payload);
|
|
101
|
-
window.dispatchEvent(new CustomEvent(
|
|
101
|
+
window.dispatchEvent(new CustomEvent(Events.names.NAVIGATION, {
|
|
102
102
|
detail: { path: resolvedPath },
|
|
103
103
|
}));
|
|
104
104
|
return resolvedPath;
|
|
@@ -107,7 +107,7 @@ export function BrowserRouterProvider({ children, setPayload, isNavigating = fal
|
|
|
107
107
|
if (err instanceof Error && err.name === 'AbortError') {
|
|
108
108
|
return path;
|
|
109
109
|
}
|
|
110
|
-
window.dispatchEvent(new CustomEvent(
|
|
110
|
+
window.dispatchEvent(new CustomEvent(Events.names.NAVIGATION_ERROR, {
|
|
111
111
|
detail: {
|
|
112
112
|
path,
|
|
113
113
|
error: err instanceof Error ? err.message : Logger.print(err),
|