effect-start 0.21.0 → 0.22.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/README.md +1 -4
- package/dist/Cookies.js +392 -0
- package/dist/FileSystem.js +131 -0
- package/dist/Socket.js +37 -0
- package/package.json +35 -36
- package/src/Commander.ts +73 -130
- package/src/ContentNegotiation.ts +64 -95
- package/src/Cookies.ts +36 -57
- package/src/Development.ts +47 -62
- package/src/Effectify.ts +222 -206
- package/src/Entity.ts +59 -86
- package/src/FilePathPattern.ts +5 -5
- package/src/FileRouter.ts +37 -62
- package/src/FileRouterCodegen.ts +63 -55
- package/src/FileSystem.ts +46 -59
- package/src/Http.ts +17 -50
- package/src/PathPattern.ts +33 -41
- package/src/PlatformError.ts +29 -50
- package/src/PlatformRuntime.ts +39 -47
- package/src/Route.ts +68 -187
- package/src/RouteBody.ts +45 -161
- package/src/RouteHook.ts +22 -45
- package/src/RouteHttp.ts +88 -142
- package/src/RouteHttpTracer.ts +25 -26
- package/src/RouteMount.ts +100 -238
- package/src/RouteSchema.ts +67 -201
- package/src/RouteSse.ts +28 -82
- package/src/RouteTree.ts +31 -79
- package/src/RouteTrie.ts +13 -32
- package/src/SchemaExtra.ts +3 -5
- package/src/Socket.ts +5 -2
- package/src/Start.ts +20 -21
- package/src/StreamExtra.ts +93 -96
- package/src/TuplePathPattern.ts +54 -43
- package/src/Unique.ts +9 -15
- package/src/Values.ts +26 -30
- package/src/bun/BunBundle.ts +27 -73
- package/src/bun/BunImportTrackerPlugin.ts +67 -65
- package/src/bun/BunRoute.ts +12 -31
- package/src/bun/BunRuntime.ts +3 -10
- package/src/bun/BunServer.ts +55 -91
- package/src/bun/BunVirtualFilesPlugin.ts +1 -4
- package/src/bun/_BunEnhancedResolve.ts +17 -42
- package/src/bun/_empty.html +0 -1
- package/src/bundler/Bundle.ts +20 -36
- package/src/bundler/BundleFiles.ts +35 -55
- package/src/client/Overlay.ts +1 -2
- package/src/client/ScrollState.ts +5 -9
- package/src/client/index.ts +10 -13
- package/src/datastar/actions/fetch.ts +29 -48
- package/src/datastar/actions/peek.ts +1 -5
- package/src/datastar/actions/setAll.ts +2 -2
- package/src/datastar/actions/toggleAll.ts +2 -2
- package/src/datastar/attributes/attr.ts +17 -18
- package/src/datastar/attributes/bind.ts +41 -61
- package/src/datastar/attributes/class.ts +2 -5
- package/src/datastar/attributes/computed.ts +2 -10
- package/src/datastar/attributes/effect.ts +1 -2
- package/src/datastar/attributes/indicator.ts +2 -8
- package/src/datastar/attributes/init.ts +2 -10
- package/src/datastar/attributes/jsonSignals.ts +1 -6
- package/src/datastar/attributes/on.ts +4 -13
- package/src/datastar/attributes/onIntersect.ts +10 -22
- package/src/datastar/attributes/onInterval.ts +2 -10
- package/src/datastar/attributes/onSignalPatch.ts +18 -28
- package/src/datastar/attributes/ref.ts +1 -2
- package/src/datastar/attributes/show.ts +1 -2
- package/src/datastar/attributes/signals.ts +1 -5
- package/src/datastar/attributes/style.ts +6 -12
- package/src/datastar/attributes/text.ts +1 -2
- package/src/datastar/engine.ts +102 -158
- package/src/datastar/index.ts +2 -2
- package/src/datastar/utils.ts +16 -51
- package/src/datastar/watchers/patchElements.ts +35 -93
- package/src/datastar/watchers/patchSignals.ts +1 -2
- package/src/experimental/EncryptedCookies.ts +79 -142
- package/src/hyper/Hyper.ts +14 -33
- package/src/hyper/HyperHtml.ts +9 -10
- package/src/hyper/HyperNode.ts +2 -7
- package/src/hyper/HyperRoute.ts +2 -5
- package/src/hyper/jsx-runtime.ts +2 -10
- package/src/hyper/jsx.d.ts +171 -440
- package/src/lint/plugin.js +276 -0
- package/src/node/NodeFileSystem.ts +138 -186
- package/src/node/NodeUtils.ts +1 -3
- package/src/testing/TestLogger.ts +9 -22
- package/src/testing/utils.ts +30 -31
- package/src/x/cloudflare/CloudflareTunnel.ts +37 -54
- package/src/x/datastar/Datastar.ts +3 -10
- package/src/x/datastar/index.ts +1 -3
- package/src/x/datastar/jsx-datastar.d.ts +1 -4
- package/src/x/tailwind/TailwindPlugin.ts +119 -112
- package/src/x/tailwind/compile.ts +10 -33
- package/src/x/tailwind/plugin.ts +2 -2
package/src/TuplePathPattern.ts
CHANGED
|
@@ -1,64 +1,75 @@
|
|
|
1
|
-
export type PathTuple = ReadonlyArray<
|
|
2
|
-
string | [string, string?, string?] | [[string]]
|
|
3
|
-
>
|
|
1
|
+
export type PathTuple = ReadonlyArray<string | [string, string?, string?] | [[string]]>
|
|
4
2
|
|
|
5
3
|
export function format(tuple: PathTuple): `/${string}` {
|
|
6
|
-
return "/" +
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
return ("/" +
|
|
5
|
+
tuple
|
|
6
|
+
.map((el) => {
|
|
7
|
+
if (typeof el === "string") return el
|
|
8
|
+
if (Array.isArray(el[0])) return "[[" + el[0][0] + "]]"
|
|
9
|
+
const [name, suffix, prefix] = el
|
|
10
|
+
return (prefix ?? "") + "[" + name + "]" + (suffix ?? "")
|
|
11
|
+
})
|
|
12
|
+
.join("/")) as `/${string}`
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export function toColon(tuple: PathTuple): string {
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
return (
|
|
17
|
+
"/" +
|
|
18
|
+
tuple
|
|
19
|
+
.map((el) => {
|
|
20
|
+
if (typeof el === "string") return el
|
|
21
|
+
if (Array.isArray(el[0])) return "*"
|
|
22
|
+
const [name, suffix, prefix] = el
|
|
23
|
+
return (prefix ?? "") + ":" + name + (suffix ?? "")
|
|
24
|
+
})
|
|
25
|
+
.join("/")
|
|
26
|
+
)
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export const toHono = toColon
|
|
28
30
|
|
|
29
31
|
export function toExpress(tuple: PathTuple): string {
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
return (
|
|
33
|
+
"/" +
|
|
34
|
+
tuple
|
|
35
|
+
.map((el) => {
|
|
36
|
+
if (typeof el === "string") return el
|
|
37
|
+
if (Array.isArray(el[0])) return "*" + el[0][0]
|
|
38
|
+
const [name, suffix, prefix] = el
|
|
39
|
+
return (prefix ?? "") + ":" + name + (suffix ?? "")
|
|
40
|
+
})
|
|
41
|
+
.join("/")
|
|
42
|
+
)
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
export const toEffect = toColon
|
|
41
46
|
|
|
42
47
|
export function toURLPattern(tuple: PathTuple): string {
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
return (
|
|
49
|
+
"/" +
|
|
50
|
+
tuple
|
|
51
|
+
.map((el) => {
|
|
52
|
+
if (typeof el === "string") return el
|
|
53
|
+
if (Array.isArray(el[0])) return ":" + el[0][0] + "+"
|
|
54
|
+
const [name, suffix, prefix] = el
|
|
55
|
+
return (prefix ?? "") + ":" + name + (suffix ?? "")
|
|
56
|
+
})
|
|
57
|
+
.join("/")
|
|
58
|
+
)
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
export function toRemix(tuple: PathTuple): string {
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
return (
|
|
63
|
+
"/" +
|
|
64
|
+
tuple
|
|
65
|
+
.map((el) => {
|
|
66
|
+
if (typeof el === "string") return el
|
|
67
|
+
if (Array.isArray(el[0])) return "$"
|
|
68
|
+
const [name, suffix, prefix] = el
|
|
69
|
+
return (prefix ?? "") + "$" + name + (suffix ?? "")
|
|
70
|
+
})
|
|
71
|
+
.join("/")
|
|
72
|
+
)
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
export const toBun = toColon
|
package/src/Unique.ts
CHANGED
|
@@ -66,12 +66,12 @@ export function toTimestamp(bytes: Uint8Array): number {
|
|
|
66
66
|
if (bytes.length < 6) return 0
|
|
67
67
|
|
|
68
68
|
return (
|
|
69
|
-
bytes[0] * 0x10000000000
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
bytes[0] * 0x10000000000 +
|
|
70
|
+
bytes[1] * 0x100000000 +
|
|
71
|
+
bytes[2] * 0x1000000 +
|
|
72
|
+
bytes[3] * 0x10000 +
|
|
73
|
+
bytes[4] * 0x100 +
|
|
74
|
+
bytes[5]
|
|
75
75
|
)
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -153,7 +153,7 @@ function formatUlid(bytes: Uint8Array): string {
|
|
|
153
153
|
|
|
154
154
|
function encodeUlidTime(time: number): string {
|
|
155
155
|
let value = BigInt(time)
|
|
156
|
-
const result =
|
|
156
|
+
const result = Array.from<string>({ length: 10 })
|
|
157
157
|
|
|
158
158
|
for (let i = 9; i >= 0; i--) {
|
|
159
159
|
result[i] = ALPHABET_BASE32_CROCKFORD[Number(value & 31n)]
|
|
@@ -178,10 +178,7 @@ function toSafeTime(time: number): number {
|
|
|
178
178
|
* It's qt lil opt from the times where web developers
|
|
179
179
|
* were competing to have the smallest possible bundle size.
|
|
180
180
|
*/
|
|
181
|
-
export function nanoid(
|
|
182
|
-
size = 21,
|
|
183
|
-
alphabet = ALPHABET_BASE64_URL,
|
|
184
|
-
): string {
|
|
181
|
+
export function nanoid(size = 21, alphabet = ALPHABET_BASE64_URL): string {
|
|
185
182
|
if (size <= 0 || alphabet.length === 0) return ""
|
|
186
183
|
|
|
187
184
|
const length = alphabet.length
|
|
@@ -201,10 +198,7 @@ export function nanoid(
|
|
|
201
198
|
return id
|
|
202
199
|
}
|
|
203
200
|
|
|
204
|
-
function toBase32(
|
|
205
|
-
bytes: Uint8Array,
|
|
206
|
-
alphabet = ALPHABET_BASE32_CROCKFORD,
|
|
207
|
-
): string {
|
|
201
|
+
function toBase32(bytes: Uint8Array, alphabet = ALPHABET_BASE32_CROCKFORD): string {
|
|
208
202
|
if (bytes.length === 0) return ""
|
|
209
203
|
|
|
210
204
|
let result = ""
|
package/src/Values.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
type JsonPrimitives =
|
|
2
|
-
| string
|
|
3
|
-
| number
|
|
4
|
-
| boolean
|
|
5
|
-
| null
|
|
1
|
+
type JsonPrimitives = string | number | boolean | null
|
|
6
2
|
|
|
7
3
|
export type JsonObject = {
|
|
8
4
|
[key: string]:
|
|
@@ -12,33 +8,28 @@ export type JsonObject = {
|
|
|
12
8
|
| undefined
|
|
13
9
|
}
|
|
14
10
|
|
|
15
|
-
export type Json =
|
|
16
|
-
| JsonPrimitives
|
|
17
|
-
| Json[]
|
|
18
|
-
| JsonObject
|
|
11
|
+
export type Json = JsonPrimitives | Json[] | JsonObject
|
|
19
12
|
|
|
20
|
-
export function isPlainObject(
|
|
21
|
-
value: unknown,
|
|
22
|
-
): value is Record<string, unknown> {
|
|
13
|
+
export function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
23
14
|
if (value === null || typeof value !== "object") {
|
|
24
15
|
return false
|
|
25
16
|
}
|
|
26
17
|
|
|
27
18
|
// Check for built-in types and web APIs
|
|
28
19
|
if (
|
|
29
|
-
ArrayBuffer.isView(value)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
20
|
+
ArrayBuffer.isView(value) ||
|
|
21
|
+
value instanceof ArrayBuffer ||
|
|
22
|
+
value instanceof Blob ||
|
|
23
|
+
value instanceof FormData ||
|
|
24
|
+
value instanceof URLSearchParams ||
|
|
25
|
+
value instanceof ReadableStream ||
|
|
26
|
+
value instanceof Date ||
|
|
27
|
+
value instanceof Map ||
|
|
28
|
+
value instanceof Set ||
|
|
29
|
+
value instanceof RegExp ||
|
|
30
|
+
value instanceof Error ||
|
|
31
|
+
value instanceof Promise ||
|
|
32
|
+
Array.isArray(value)
|
|
42
33
|
) {
|
|
43
34
|
return false
|
|
44
35
|
}
|
|
@@ -56,19 +47,24 @@ export function isPlainObject(
|
|
|
56
47
|
* class instances or objects with methods.
|
|
57
48
|
*/
|
|
58
49
|
type HasMethod<T> = {
|
|
59
|
-
[K in keyof T]: T[K] extends (...args: any
|
|
50
|
+
[K in keyof T]: T[K] extends (...args: Array<any>) => any ? true : never
|
|
60
51
|
}[keyof T]
|
|
61
52
|
|
|
62
|
-
export type IsPlainObject<T> = T extends object
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
export type IsPlainObject<T> = T extends object
|
|
54
|
+
? T extends Function
|
|
55
|
+
? false
|
|
56
|
+
: HasMethod<T> extends never
|
|
57
|
+
? true
|
|
58
|
+
: false
|
|
65
59
|
: false
|
|
66
60
|
|
|
67
61
|
export type Simplify<T> = {
|
|
68
62
|
-readonly [K in keyof T]: IsPlainObject<T[K]> extends true
|
|
69
63
|
? { -readonly [P in keyof T[K]]: T[K][P] }
|
|
70
64
|
: T[K]
|
|
71
|
-
} extends infer U
|
|
65
|
+
} extends infer U
|
|
66
|
+
? { [K in keyof U]: U[K] }
|
|
67
|
+
: never
|
|
72
68
|
|
|
73
69
|
export const concatBytes = (a: Uint8Array, b: Uint8Array): Uint8Array => {
|
|
74
70
|
const result = new Uint8Array(a.byteLength + b.byteLength)
|
package/src/bun/BunBundle.ts
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
BuildOutput,
|
|
4
|
-
} from "bun"
|
|
5
|
-
import {
|
|
6
|
-
Array,
|
|
7
|
-
Context,
|
|
8
|
-
Effect,
|
|
9
|
-
Iterable,
|
|
10
|
-
Layer,
|
|
11
|
-
pipe,
|
|
12
|
-
Record,
|
|
13
|
-
} from "effect"
|
|
1
|
+
import type { BuildConfig, BuildOutput } from "bun"
|
|
2
|
+
import { Array, type Context, Effect, Iterable, Layer, pipe, Record } from "effect"
|
|
14
3
|
import * as NPath from "node:path"
|
|
15
|
-
import type {
|
|
16
|
-
BundleContext,
|
|
17
|
-
BundleManifest,
|
|
18
|
-
} from "../bundler/Bundle.ts"
|
|
19
4
|
import * as Bundle from "../bundler/Bundle.ts"
|
|
20
|
-
import { BunImportTrackerPlugin } from "./index.ts"
|
|
5
|
+
import type { BunImportTrackerPlugin } from "./index.ts"
|
|
21
6
|
|
|
22
|
-
export type BuildOptions = Omit<
|
|
23
|
-
BuildConfig,
|
|
24
|
-
"outdir"
|
|
25
|
-
>
|
|
7
|
+
export type BuildOptions = Omit<BuildConfig, "outdir">
|
|
26
8
|
|
|
27
|
-
export const buildClient = (
|
|
28
|
-
config: BuildOptions | string,
|
|
29
|
-
) => {
|
|
9
|
+
export const buildClient = (config: BuildOptions | string) => {
|
|
30
10
|
if (typeof config === "string") {
|
|
31
11
|
config = {
|
|
32
12
|
entrypoints: [config],
|
|
@@ -52,9 +32,7 @@ export const buildClient = (
|
|
|
52
32
|
return build(resolvedConfig)
|
|
53
33
|
}
|
|
54
34
|
|
|
55
|
-
export const buildServer = (
|
|
56
|
-
config: BuildOptions | string,
|
|
57
|
-
) => {
|
|
35
|
+
export const buildServer = (config: BuildOptions | string) => {
|
|
58
36
|
if (typeof config === "string") {
|
|
59
37
|
config = {
|
|
60
38
|
entrypoints: [config],
|
|
@@ -84,26 +62,18 @@ export const buildServer = (
|
|
|
84
62
|
*/
|
|
85
63
|
export function build(
|
|
86
64
|
config: BuildOptions,
|
|
87
|
-
): Effect.Effect<BundleContext, Bundle.BundleError> {
|
|
88
|
-
return Effect.gen(function*() {
|
|
65
|
+
): Effect.Effect<Bundle.BundleContext, Bundle.BundleError> {
|
|
66
|
+
return Effect.gen(function* () {
|
|
89
67
|
const output = yield* buildBun(config)
|
|
90
|
-
const manifest = generateManifestfromBunBundle(
|
|
91
|
-
|
|
92
|
-
output,
|
|
93
|
-
)
|
|
94
|
-
const artifactsMap = Record.fromIterableBy(
|
|
95
|
-
output.outputs,
|
|
96
|
-
(v) => v.path.replace(/^\.\//, ""),
|
|
97
|
-
)
|
|
68
|
+
const manifest = generateManifestfromBunBundle(config, output)
|
|
69
|
+
const artifactsMap = Record.fromIterableBy(output.outputs, (v) => v.path.replace(/^\.\//, ""))
|
|
98
70
|
|
|
99
71
|
const resolve = (path: string) => {
|
|
100
72
|
return manifest.entrypoints[path] ?? null
|
|
101
73
|
}
|
|
102
74
|
|
|
103
75
|
const getArtifact = (path: string): Blob | null => {
|
|
104
|
-
return artifactsMap[resolve(path)]
|
|
105
|
-
?? artifactsMap[path]
|
|
106
|
-
?? null
|
|
76
|
+
return artifactsMap[resolve(path)] ?? artifactsMap[path] ?? null
|
|
107
77
|
}
|
|
108
78
|
|
|
109
79
|
return {
|
|
@@ -114,37 +84,31 @@ export function build(
|
|
|
114
84
|
})
|
|
115
85
|
}
|
|
116
86
|
|
|
117
|
-
export function layer<T>(
|
|
118
|
-
tag: Context.Tag<T, BundleContext>,
|
|
119
|
-
config: BuildOptions,
|
|
120
|
-
) {
|
|
87
|
+
export function layer<T>(tag: Context.Tag<T, Bundle.BundleContext>, config: BuildOptions) {
|
|
121
88
|
return Layer.effect(tag, build(config))
|
|
122
89
|
}
|
|
123
90
|
|
|
124
91
|
/**
|
|
125
92
|
* Finds common path prefix across provided paths.
|
|
126
93
|
*/
|
|
127
|
-
function getBaseDir(paths: string
|
|
94
|
+
function getBaseDir(paths: Array<string>) {
|
|
128
95
|
if (paths.length === 0) return ""
|
|
129
96
|
if (paths.length === 1) return NPath.dirname(paths[0])
|
|
130
97
|
|
|
131
|
-
const segmentsList = paths.map((path) =>
|
|
132
|
-
NPath.dirname(path).split("/").filter(Boolean)
|
|
133
|
-
)
|
|
98
|
+
const segmentsList = paths.map((path) => NPath.dirname(path).split("/").filter(Boolean))
|
|
134
99
|
|
|
135
|
-
return
|
|
136
|
-
|
|
137
|
-
|
|
100
|
+
return (
|
|
101
|
+
segmentsList[0]
|
|
102
|
+
.filter((segment, i) => segmentsList.every((segs) => segs[i] === segment))
|
|
103
|
+
.reduce((path, seg) => `${path}/${seg}`, "") ?? ""
|
|
104
|
+
)
|
|
138
105
|
}
|
|
139
106
|
|
|
140
107
|
/**
|
|
141
108
|
* Maps entrypoints to their respective build artifacts.
|
|
142
109
|
* Entrypoint key is trimmed to remove common path prefix.
|
|
143
110
|
*/
|
|
144
|
-
function joinBuildEntrypoints(
|
|
145
|
-
options: BuildOptions,
|
|
146
|
-
output: BuildOutput,
|
|
147
|
-
) {
|
|
111
|
+
function joinBuildEntrypoints(options: BuildOptions, output: BuildOutput) {
|
|
148
112
|
const commonPathPrefix = getBaseDir(options.entrypoints) + "/"
|
|
149
113
|
|
|
150
114
|
return pipe(
|
|
@@ -153,9 +117,8 @@ function joinBuildEntrypoints(
|
|
|
153
117
|
pipe(
|
|
154
118
|
output.outputs,
|
|
155
119
|
// Filter out source maps to properly map artifacts to entrypoints.
|
|
156
|
-
Iterable.filter(
|
|
157
|
-
v.kind !== "sourcemap"
|
|
158
|
-
&& !(v.loader === "html" && v.path.endsWith(".js"))
|
|
120
|
+
Iterable.filter(
|
|
121
|
+
(v) => v.kind !== "sourcemap" && !(v.loader === "html" && v.path.endsWith(".js")),
|
|
159
122
|
),
|
|
160
123
|
),
|
|
161
124
|
),
|
|
@@ -177,18 +140,13 @@ function generateManifestfromBunBundle(
|
|
|
177
140
|
options: BuildOptions,
|
|
178
141
|
output: BuildOutput,
|
|
179
142
|
imports?: BunImportTrackerPlugin.ImportMap,
|
|
180
|
-
): BundleManifest {
|
|
143
|
+
): Bundle.BundleManifest {
|
|
181
144
|
const entrypointArtifacts = joinBuildEntrypoints(options, output)
|
|
182
145
|
|
|
183
146
|
return {
|
|
184
147
|
entrypoints: pipe(
|
|
185
148
|
entrypointArtifacts,
|
|
186
|
-
Iterable.map((v) =>
|
|
187
|
-
[
|
|
188
|
-
v.shortPath,
|
|
189
|
-
v.artifact.path.replace(/^\.\//, ""),
|
|
190
|
-
] as const
|
|
191
|
-
),
|
|
149
|
+
Iterable.map((v) => [v.shortPath, v.artifact.path.replace(/^\.\//, "")] as const),
|
|
192
150
|
Record.fromEntries,
|
|
193
151
|
),
|
|
194
152
|
|
|
@@ -211,17 +169,13 @@ function generateManifestfromBunBundle(
|
|
|
211
169
|
}
|
|
212
170
|
}
|
|
213
171
|
|
|
214
|
-
function buildBun(
|
|
215
|
-
config: BuildOptions,
|
|
216
|
-
): Effect.Effect<BuildOutput, Bundle.BundleError, never> {
|
|
172
|
+
function buildBun(config: BuildOptions): Effect.Effect<BuildOutput, Bundle.BundleError, never> {
|
|
217
173
|
return Object.assign(
|
|
218
|
-
Effect.gen(function*() {
|
|
174
|
+
Effect.gen(function* () {
|
|
219
175
|
const buildOutput: BuildOutput = yield* Effect.tryPromise({
|
|
220
176
|
try: () => Bun.build(config),
|
|
221
177
|
catch: (err: AggregateError | unknown) => {
|
|
222
|
-
const cause = err instanceof AggregateError
|
|
223
|
-
? err.errors?.[0] ?? err
|
|
224
|
-
: err
|
|
178
|
+
const cause = err instanceof AggregateError ? (err.errors?.[0] ?? err) : err
|
|
225
179
|
|
|
226
180
|
return new Bundle.BundleError({
|
|
227
181
|
message: "Failed to Bun.build: " + cause,
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type BunPlugin,
|
|
3
|
-
type Import,
|
|
4
|
-
} from "bun"
|
|
1
|
+
import { type BunPlugin, type Import } from "bun"
|
|
5
2
|
import * as NPath from "node:path"
|
|
6
3
|
|
|
7
|
-
export type ImportMap = ReadonlyMap<string, Import
|
|
4
|
+
export type ImportMap = ReadonlyMap<string, Array<Import>>
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* Tracks all imported modules.
|
|
11
8
|
* State can be accessed via 'virtual:import-tracker' module within a bundle
|
|
12
9
|
* or through `state` property returned by this function.
|
|
13
10
|
*/
|
|
14
|
-
export const make = (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
export const make = (
|
|
12
|
+
opts: {
|
|
13
|
+
includeNodeModules?: false
|
|
14
|
+
baseDir?: string
|
|
15
|
+
} = {},
|
|
16
|
+
): BunPlugin & {
|
|
18
17
|
state: ImportMap
|
|
19
18
|
} => {
|
|
20
|
-
const foundImports: Map<string, Import
|
|
19
|
+
const foundImports: Map<string, Array<Import>> = new Map()
|
|
21
20
|
const baseDir = opts.baseDir ?? process.cwd()
|
|
22
21
|
|
|
23
22
|
return {
|
|
@@ -29,67 +28,70 @@ export const make = (opts: {
|
|
|
29
28
|
|
|
30
29
|
// Each module that goes through this onLoad callback
|
|
31
30
|
// will record its imports in `trackedImports`
|
|
32
|
-
build.onLoad(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
&& args.path.includes("/node_modules/")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
31
|
+
build.onLoad(
|
|
32
|
+
{
|
|
33
|
+
filter: /\.(ts|js)x?$/,
|
|
34
|
+
},
|
|
35
|
+
async (args) => {
|
|
36
|
+
if (!opts.includeNodeModules && args.path.includes("/node_modules/")) {
|
|
37
|
+
return undefined
|
|
38
|
+
}
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
const contents = await Bun.file(args.path).arrayBuffer()
|
|
41
|
+
try {
|
|
42
|
+
const fileImport = transpiler.scanImports(contents)
|
|
43
|
+
const resolvedImports = fileImport.map((imp) => {
|
|
44
|
+
const absoluteImportPath = NPath.resolve(
|
|
45
|
+
NPath.dirname(args.path),
|
|
46
|
+
// 'file' is a default namespace, trim it
|
|
47
|
+
imp.path.replace(/^file:/, ""),
|
|
48
|
+
)
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
50
|
+
return {
|
|
51
|
+
...imp,
|
|
52
|
+
// keep all module identifiers with namespace intact
|
|
53
|
+
path: /(\w+):/.test(imp.path)
|
|
54
|
+
? imp.path
|
|
55
|
+
: NPath.relative(baseDir, absoluteImportPath),
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
foundImports.set(NPath.relative(baseDir, args.path), resolvedImports)
|
|
59
|
+
} catch (e) {}
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
return undefined
|
|
62
|
+
},
|
|
63
|
+
)
|
|
66
64
|
|
|
67
|
-
build.onResolve(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
build.onResolve(
|
|
66
|
+
{
|
|
67
|
+
filter: /^virtual:import-tracker$/,
|
|
68
|
+
},
|
|
69
|
+
() => {
|
|
70
|
+
return {
|
|
71
|
+
namespace: "effect-start",
|
|
72
|
+
path: "virtual:import-tracker",
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
)
|
|
75
76
|
|
|
76
|
-
build.onLoad(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
build.onLoad(
|
|
78
|
+
{
|
|
79
|
+
filter: /^virtual:import-tracker$/,
|
|
80
|
+
namespace: "effect-start",
|
|
81
|
+
},
|
|
82
|
+
async (args) => {
|
|
83
|
+
// Wait for all files to be loaded, ensuring
|
|
84
|
+
// that every file goes through the above `onLoad()` function
|
|
85
|
+
// and their imports tracked
|
|
86
|
+
await args.defer()
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
})
|
|
88
|
+
// Emit JSON containing the stats of each import
|
|
89
|
+
return {
|
|
90
|
+
contents: JSON.stringify(Object.fromEntries(foundImports.entries())),
|
|
91
|
+
loader: "json",
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
)
|
|
93
95
|
},
|
|
94
96
|
|
|
95
97
|
state: foundImports,
|