@jk2908/solas 0.5.3 → 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 +29 -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 +46 -0
- package/dist/internal/browser-router/history.js +131 -0
- 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 +6 -14
- package/dist/internal/browser-router/router.js +39 -13
- package/dist/internal/browser-router/shared.d.ts +183 -164
- package/dist/internal/browser-router/shared.js +49 -56
- package/dist/internal/browser-router/use-router.d.ts +1 -10
- 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 +6 -4
- package/dist/internal/env/rsc.js +27 -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/runtimes/bun.d.ts +0 -13
- package/dist/runtimes/bun.js +0 -39
package/dist/utils/base-path.js
CHANGED
|
@@ -1,85 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Normalise a base path so every check uses the same shape
|
|
3
|
+
*/
|
|
4
|
+
export function normaliseBasePath(value) {
|
|
5
|
+
// no base means the app lives at the site root
|
|
6
|
+
if (!value)
|
|
7
|
+
return '/';
|
|
8
|
+
if (value === '/' || value === '.' || value === './')
|
|
9
|
+
return '/';
|
|
10
|
+
let pathname = value.trim();
|
|
11
|
+
if (!pathname)
|
|
12
|
+
return '/';
|
|
13
|
+
// plain path bases are the common case, so keep them cheap
|
|
14
|
+
if (!pathname.startsWith('http://') && !pathname.startsWith('https://')) {
|
|
15
|
+
const hashIndex = pathname.indexOf('#');
|
|
16
|
+
const searchIndex = pathname.indexOf('?');
|
|
17
|
+
const end = hashIndex === -1
|
|
18
|
+
? searchIndex
|
|
19
|
+
: searchIndex === -1
|
|
20
|
+
? hashIndex
|
|
21
|
+
: Math.min(hashIndex, searchIndex);
|
|
22
|
+
if (end >= 0)
|
|
23
|
+
pathname = pathname.slice(0, end);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
try {
|
|
27
|
+
// full urls can still show up here, but we only need the path part
|
|
28
|
+
pathname = new URL(pathname).pathname;
|
|
27
29
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// full urls can still show up here, but we only need the path part
|
|
31
|
-
pathname = new URL(pathname).pathname;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// if parsing fails, fall back to the raw value below
|
|
35
|
-
}
|
|
30
|
+
catch {
|
|
31
|
+
// if parsing fails, fall back to the raw value below
|
|
36
32
|
}
|
|
37
|
-
if (!pathname || pathname === '.' || pathname === './')
|
|
38
|
-
return '/';
|
|
39
|
-
// keep one stable shape: leading slash, trailing slash
|
|
40
|
-
if (!pathname.startsWith('/'))
|
|
41
|
-
pathname = `/${pathname}`;
|
|
42
|
-
return pathname.endsWith('/') ? pathname : `${pathname}/`;
|
|
43
|
-
}
|
|
44
|
-
BasePath.normalise = normalise;
|
|
45
|
-
/**
|
|
46
|
-
* Strip the base path from a request path
|
|
47
|
-
*/
|
|
48
|
-
function strip(pathname, base) {
|
|
49
|
-
const normalisedBase = normalise(base);
|
|
50
|
-
// root base means there is nothing to strip
|
|
51
|
-
if (normalisedBase === '/')
|
|
52
|
-
return pathname || '/';
|
|
53
|
-
const basePath = normalisedBase.slice(0, -1);
|
|
54
|
-
// treat both '/docs' and '/docs/' as the app root
|
|
55
|
-
if (pathname === basePath || pathname === normalisedBase)
|
|
56
|
-
return '/';
|
|
57
|
-
// paths outside the base do not belong to this app
|
|
58
|
-
if (!pathname.startsWith(`${basePath}/`))
|
|
59
|
-
return null;
|
|
60
|
-
// return the path as the app should see it
|
|
61
|
-
return pathname.slice(basePath.length) || '/';
|
|
62
|
-
}
|
|
63
|
-
BasePath.strip = strip;
|
|
64
|
-
/**
|
|
65
|
-
* Add the base path to a path when needed
|
|
66
|
-
*/
|
|
67
|
-
function apply(pathname, base) {
|
|
68
|
-
const normalisedBase = normalise(base);
|
|
69
|
-
// always work with a path-like value
|
|
70
|
-
const target = pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
71
|
-
// root base means the path can pass through unchanged
|
|
72
|
-
if (normalisedBase === '/')
|
|
73
|
-
return target;
|
|
74
|
-
const basePath = normalisedBase.slice(0, -1);
|
|
75
|
-
// leave it alone if the base is already there
|
|
76
|
-
if (target === basePath || target.startsWith(`${basePath}/`))
|
|
77
|
-
return target;
|
|
78
|
-
// the app root maps to the base path itself
|
|
79
|
-
if (target === '/')
|
|
80
|
-
return normalisedBase;
|
|
81
|
-
// everything else sits underneath the base path
|
|
82
|
-
return `${basePath}${target}`;
|
|
83
33
|
}
|
|
84
|
-
|
|
85
|
-
|
|
34
|
+
if (!pathname || pathname === '.' || pathname === './')
|
|
35
|
+
return '/';
|
|
36
|
+
// keep one stable shape: leading slash, trailing slash
|
|
37
|
+
if (!pathname.startsWith('/'))
|
|
38
|
+
pathname = `/${pathname}`;
|
|
39
|
+
return pathname.endsWith('/') ? pathname : `${pathname}/`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Strip the base path from a request path
|
|
43
|
+
*/
|
|
44
|
+
export function stripBasePath(pathname, base) {
|
|
45
|
+
const normalisedBase = normaliseBasePath(base);
|
|
46
|
+
// root base means there is nothing to strip
|
|
47
|
+
if (normalisedBase === '/')
|
|
48
|
+
return pathname || '/';
|
|
49
|
+
const basePath = normalisedBase.slice(0, -1);
|
|
50
|
+
// treat both '/docs' and '/docs/' as the app root
|
|
51
|
+
if (pathname === basePath || pathname === normalisedBase)
|
|
52
|
+
return '/';
|
|
53
|
+
// paths outside the base do not belong to this app
|
|
54
|
+
if (!pathname.startsWith(`${basePath}/`))
|
|
55
|
+
return null;
|
|
56
|
+
// return the path as the app should see it
|
|
57
|
+
return pathname.slice(basePath.length) || '/';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Add the base path to a path when needed
|
|
61
|
+
*/
|
|
62
|
+
export function applyBasePath(pathname, base) {
|
|
63
|
+
const normalisedBase = normaliseBasePath(base);
|
|
64
|
+
// always work with a path-like value
|
|
65
|
+
const target = pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
66
|
+
// root base means the path can pass through unchanged
|
|
67
|
+
if (normalisedBase === '/')
|
|
68
|
+
return target;
|
|
69
|
+
const basePath = normalisedBase.slice(0, -1);
|
|
70
|
+
// leave it alone if the base is already there
|
|
71
|
+
if (target === basePath || target.startsWith(`${basePath}/`))
|
|
72
|
+
return target;
|
|
73
|
+
// the app root maps to the base path itself
|
|
74
|
+
if (target === '/')
|
|
75
|
+
return normalisedBase;
|
|
76
|
+
// everything else sits underneath the base path
|
|
77
|
+
return `${basePath}${target}`;
|
|
78
|
+
}
|
package/dist/utils/compress.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}>;
|
|
11
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Compress a file or directory
|
|
3
|
+
*/
|
|
4
|
+
export declare function run(input: string, config?: {
|
|
5
|
+
filter?: (f: string) => boolean;
|
|
6
|
+
}): AsyncGenerator<{
|
|
7
|
+
input: string;
|
|
8
|
+
compressed: Uint8Array;
|
|
9
|
+
}>;
|
package/dist/utils/compress.js
CHANGED
|
@@ -3,74 +3,69 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { brotliCompress } from 'node:zlib';
|
|
5
5
|
import { Runtime } from '../internal/runtimes/runtime.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!stat.isDirectory()) {
|
|
13
|
-
if (filter(input))
|
|
14
|
-
output.push(input);
|
|
15
|
-
return output;
|
|
16
|
-
}
|
|
17
|
-
for (const entry of await fs.readdir(input, { withFileTypes: true })) {
|
|
18
|
-
const next = path.join(input, entry.name);
|
|
19
|
-
if (entry.isDirectory()) {
|
|
20
|
-
await collect(next, filter, output);
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
if (entry.isFile() && filter(next))
|
|
24
|
-
output.push(next);
|
|
25
|
-
}
|
|
6
|
+
const DEFAULT_CONCURRENCY = Math.max(1, Math.min(os.cpus().length, 8));
|
|
7
|
+
async function collect(input, filter, output = []) {
|
|
8
|
+
const stat = await fs.stat(input);
|
|
9
|
+
if (!stat.isDirectory()) {
|
|
10
|
+
if (filter(input))
|
|
11
|
+
output.push(input);
|
|
26
12
|
return output;
|
|
27
13
|
}
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
fulfill(res);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
// return the input path plus a zero-copy Uint8Array view over the
|
|
41
|
-
// compressed Buffer using its exact offset and length
|
|
42
|
-
return {
|
|
43
|
-
input,
|
|
44
|
-
compressed: new Uint8Array(compressed.buffer, compressed.byteOffset, compressed.byteLength),
|
|
45
|
-
};
|
|
14
|
+
for (const entry of await fs.readdir(input, { withFileTypes: true })) {
|
|
15
|
+
const next = path.join(input, entry.name);
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
await collect(next, filter, output);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (entry.isFile() && filter(next))
|
|
21
|
+
output.push(next);
|
|
46
22
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let index = 0;
|
|
56
|
-
const pending = new Map();
|
|
57
|
-
function enqueue() {
|
|
58
|
-
while (index < targets.length && pending.size < DEFAULT_CONCURRENCY) {
|
|
59
|
-
const i = index++;
|
|
60
|
-
const value = targets[i];
|
|
61
|
-
pending.set(i, compress(value).then(compressed => ({
|
|
62
|
-
index: i,
|
|
63
|
-
value: compressed,
|
|
64
|
-
})));
|
|
23
|
+
return output;
|
|
24
|
+
}
|
|
25
|
+
async function compress(input) {
|
|
26
|
+
const buffer = Buffer.from(await Runtime.readBuffer(input));
|
|
27
|
+
const compressed = await new Promise((fulfill, reject) => {
|
|
28
|
+
brotliCompress(buffer, (err, res) => {
|
|
29
|
+
if (err) {
|
|
30
|
+
reject(err);
|
|
65
31
|
}
|
|
32
|
+
else {
|
|
33
|
+
fulfill(res);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
// return the input path plus a zero-copy Uint8Array view over the
|
|
38
|
+
// compressed Buffer using its exact offset and length
|
|
39
|
+
return {
|
|
40
|
+
input,
|
|
41
|
+
compressed: new Uint8Array(compressed.buffer, compressed.byteOffset, compressed.byteLength),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compress a file or directory
|
|
46
|
+
*/
|
|
47
|
+
export async function* run(input, config = {}) {
|
|
48
|
+
const { filter = f => /\.(js|css|html|svg|json|txt)$/.test(f) } = config;
|
|
49
|
+
const targets = await collect(input, filter);
|
|
50
|
+
if (!targets.length)
|
|
51
|
+
return;
|
|
52
|
+
let index = 0;
|
|
53
|
+
const pending = new Map();
|
|
54
|
+
function enqueue() {
|
|
55
|
+
while (index < targets.length && pending.size < DEFAULT_CONCURRENCY) {
|
|
56
|
+
const i = index++;
|
|
57
|
+
const value = targets[i];
|
|
58
|
+
pending.set(i, compress(value).then(compressed => ({
|
|
59
|
+
index: i,
|
|
60
|
+
value: compressed,
|
|
61
|
+
})));
|
|
66
62
|
}
|
|
63
|
+
}
|
|
64
|
+
enqueue();
|
|
65
|
+
while (pending.size > 0) {
|
|
66
|
+
const settled = await Promise.race(pending.values());
|
|
67
|
+
pending.delete(settled.index);
|
|
68
|
+
yield settled.value;
|
|
67
69
|
enqueue();
|
|
68
|
-
while (pending.size > 0) {
|
|
69
|
-
const settled = await Promise.race(pending.values());
|
|
70
|
-
pending.delete(settled.index);
|
|
71
|
-
yield settled.value;
|
|
72
|
-
enqueue();
|
|
73
|
-
}
|
|
74
70
|
}
|
|
75
|
-
|
|
76
|
-
})(Compress || (Compress = {}));
|
|
71
|
+
}
|
package/dist/utils/context.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
}
|
|
1
|
+
export declare function create<T>(name: string): {
|
|
2
|
+
use(): NonNullable<T>;
|
|
3
|
+
write<R>(value: T, fn: () => R | Promise<R>): R | Promise<R>;
|
|
4
|
+
};
|
package/dist/utils/context.js
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { Logger } from './logger.js';
|
|
3
3
|
const logger = new Logger();
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
Context.create = create;
|
|
25
|
-
})(Context || (Context = {}));
|
|
4
|
+
export function create(name) {
|
|
5
|
+
const storage = new AsyncLocalStorage();
|
|
6
|
+
return {
|
|
7
|
+
use() {
|
|
8
|
+
const r = storage.getStore();
|
|
9
|
+
if (!r) {
|
|
10
|
+
const error = new Error(`No ${name} context available`);
|
|
11
|
+
logger.error(`[Context:create] ${error.message}`, error);
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
return r;
|
|
15
|
+
},
|
|
16
|
+
write(value, fn) {
|
|
17
|
+
return storage.run(value, fn);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import * as Config from '../config.js';
|
|
1
2
|
import { HttpException } from '../internal/navigation/http-exception.js';
|
|
2
|
-
import { Solas } from '../solas.js';
|
|
3
3
|
const LEVELS = {
|
|
4
4
|
debug: 0,
|
|
5
5
|
info: 1,
|
|
@@ -69,7 +69,7 @@ export class Logger {
|
|
|
69
69
|
if (level === 'error' || level === 'fatal') {
|
|
70
70
|
entry.error = error ? Logger.toError(error) : new Error(message);
|
|
71
71
|
}
|
|
72
|
-
const line = `[${
|
|
72
|
+
const line = `[${Config.NAME}] [${entry.ts}] [${level.toUpperCase()}] ${message}`;
|
|
73
73
|
const extra = entry.error ? `\n${Logger.print(entry.error)}` : '';
|
|
74
74
|
if (level === 'warn') {
|
|
75
75
|
console.warn(line, extra);
|
package/dist/utils/time.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
|
|
3
|
-
function timeout<T>(task: Promise<T>, timeoutMs: number, label: string): Promise<Awaited<T>>;
|
|
4
|
-
}
|
|
1
|
+
export declare function debounce<T extends unknown[]>(fn: (...args: T) => void, wait: number): (...args: T) => void;
|
|
2
|
+
export declare function timeout<T>(task: Promise<T>, timeoutMs: number, label: string): Promise<Awaited<T>>;
|
package/dist/utils/time.js
CHANGED
|
@@ -1,29 +1,23 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (timer)
|
|
25
|
-
clearTimeout(timer);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
Time.timeout = timeout;
|
|
29
|
-
})(Time || (Time = {}));
|
|
1
|
+
export function debounce(fn, wait) {
|
|
2
|
+
let timeoutId = null;
|
|
3
|
+
return (...args) => {
|
|
4
|
+
if (timeoutId) {
|
|
5
|
+
clearTimeout(timeoutId);
|
|
6
|
+
}
|
|
7
|
+
timeoutId = setTimeout(() => {
|
|
8
|
+
fn.apply(null, args);
|
|
9
|
+
}, wait);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function timeout(task, timeoutMs, label) {
|
|
13
|
+
let timer;
|
|
14
|
+
const timeout = new Promise((_, reject) => {
|
|
15
|
+
timer = setTimeout(() => {
|
|
16
|
+
reject(new Error(`Timed out after ${timeoutMs}ms (${label})`));
|
|
17
|
+
}, timeoutMs);
|
|
18
|
+
});
|
|
19
|
+
return Promise.race([task, timeout]).finally(() => {
|
|
20
|
+
if (timer)
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
});
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jk2908/solas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A Vite + React meta-framework exploring streaming, Server Components, and partial prerendering. Designed for simplicity and lightness",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -33,10 +33,6 @@
|
|
|
33
33
|
"types": "./dist/index.d.ts",
|
|
34
34
|
"import": "./dist/index.js"
|
|
35
35
|
},
|
|
36
|
-
"./$": {
|
|
37
|
-
"types": "./dist/solas.d.ts",
|
|
38
|
-
"import": "./dist/solas.js"
|
|
39
|
-
},
|
|
40
36
|
"./env/rsc": {
|
|
41
37
|
"types": "./dist/internal/env/rsc.d.ts",
|
|
42
38
|
"import": "./dist/internal/env/rsc.js"
|
|
@@ -76,6 +72,10 @@
|
|
|
76
72
|
},
|
|
77
73
|
"scripts": {
|
|
78
74
|
"build": "rm -rf dist && tsgo",
|
|
75
|
+
"postbuild": "node scripts/measure.mjs",
|
|
76
|
+
"test": "vitest run",
|
|
77
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
78
|
+
"test:watch": "vitest",
|
|
79
79
|
"lint": "bunx oxlint .",
|
|
80
80
|
"lint:fix": "bunx oxlint --fix .",
|
|
81
81
|
"format": "bunx oxfmt --write .",
|
|
@@ -85,16 +85,24 @@
|
|
|
85
85
|
"prepublishOnly": "npm run build && npm run pack:dry"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"@vitejs/plugin-rsc": "
|
|
88
|
+
"@vitejs/plugin-rsc": "0.5.34",
|
|
89
89
|
"oxc-parser": "^0.134.0",
|
|
90
|
+
"oxfmt": "^0.35.0",
|
|
90
91
|
"path-to-regexp": "^8.3.0"
|
|
91
92
|
},
|
|
92
93
|
"devDependencies": {
|
|
93
94
|
"@prettier/plugin-oxc": "^0.1.3",
|
|
94
95
|
"@typescript/native-preview": "^7.0.0-dev.20260224.1",
|
|
96
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
97
|
+
"@vitest/browser": "^4.1.8",
|
|
98
|
+
"@vitest/browser-playwright": "^4.1.8",
|
|
99
|
+
"happy-dom": "^20.10.2",
|
|
95
100
|
"network-information-types": "^0.1.1",
|
|
96
101
|
"oxfmt": "^0.35.0",
|
|
97
|
-
"
|
|
102
|
+
"playwright": "^1.58.2",
|
|
103
|
+
"typescript": "^5.9.3",
|
|
104
|
+
"vitest": "^4.1.8",
|
|
105
|
+
"vitest-browser-react": "^2.2.0"
|
|
98
106
|
},
|
|
99
107
|
"peerDependencies": {
|
|
100
108
|
"@types/react": "^19.2.14",
|
|
@@ -109,5 +117,7 @@
|
|
|
109
117
|
"optional": true
|
|
110
118
|
}
|
|
111
119
|
},
|
|
112
|
-
"engines": {
|
|
120
|
+
"engines": {
|
|
121
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
122
|
+
}
|
|
113
123
|
}
|
package/dist/runtimes/bun.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { RuntimeBase } from '../internal/runtimes/runtime.js';
|
|
2
|
-
declare class BunAdapter extends RuntimeBase {
|
|
3
|
-
readonly name: "bun";
|
|
4
|
-
readonly module: string;
|
|
5
|
-
exists(filePath: string): Promise<boolean>;
|
|
6
|
-
readText(filePath: string): Promise<string>;
|
|
7
|
-
readBuffer(filePath: string): Promise<ArrayBuffer>;
|
|
8
|
-
mimeType(filePath: string): string;
|
|
9
|
-
write(filePath: string, content: string | NodeJS.ArrayBufferView): Promise<void>;
|
|
10
|
-
hash(value: string): string;
|
|
11
|
-
}
|
|
12
|
-
export default function bunAdapter(): BunAdapter;
|
|
13
|
-
export {};
|
package/dist/runtimes/bun.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { RuntimeBase } from '../internal/runtimes/runtime.js';
|
|
2
|
-
import { Solas } from '../solas.js';
|
|
3
|
-
class BunAdapter extends RuntimeBase {
|
|
4
|
-
name = 'bun';
|
|
5
|
-
module = `${Solas.Config.PKG_NAME}/runtimes/bun`;
|
|
6
|
-
async exists(filePath) {
|
|
7
|
-
return Bun.file(filePath).exists();
|
|
8
|
-
}
|
|
9
|
-
readText(filePath) {
|
|
10
|
-
return Bun.file(filePath).text();
|
|
11
|
-
}
|
|
12
|
-
readBuffer(filePath) {
|
|
13
|
-
return Bun.file(filePath).arrayBuffer();
|
|
14
|
-
}
|
|
15
|
-
mimeType(filePath) {
|
|
16
|
-
return Bun.file(filePath).type || 'application/octet-stream';
|
|
17
|
-
}
|
|
18
|
-
async write(filePath, content) {
|
|
19
|
-
// normalise wider arraybuffer views into a shape Bun.write accepts directly
|
|
20
|
-
await Bun.write(filePath, typeof content === 'string'
|
|
21
|
-
? content
|
|
22
|
-
: content instanceof Uint8Array
|
|
23
|
-
? content
|
|
24
|
-
: new Uint8Array(content.buffer, content.byteOffset, content.byteLength));
|
|
25
|
-
}
|
|
26
|
-
hash(value) {
|
|
27
|
-
const hash = Bun.hash(value);
|
|
28
|
-
// Bun.hash returns an integer-like value, so keep it in BigInt space and avoid
|
|
29
|
-
// precision loss. Clamp it to an unsigned 64-bit value before hex
|
|
30
|
-
// formatting. Pad to 16 chars to match the Node adapter
|
|
31
|
-
// output shape
|
|
32
|
-
return BigInt.asUintN(64, typeof hash === 'bigint' ? hash : BigInt(hash))
|
|
33
|
-
.toString(16)
|
|
34
|
-
.padStart(16, '0');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export default function bunAdapter() {
|
|
38
|
-
return new BunAdapter();
|
|
39
|
-
}
|