effect-start 0.13.0 → 0.14.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 +4 -4
- package/package.json +12 -17
- package/src/Bundle.ts +0 -35
- package/src/BundleHttp.test.ts +4 -6
- package/src/BundleHttp.ts +2 -1
- package/src/Effect_HttpRouter.test.ts +2 -3
- package/src/FileHttpRouter.test.ts +2 -2
- package/src/FileRouterCodegen.test.ts +1 -1
- package/src/FileRouter_files.test.ts +1 -1
- package/src/HttpAppExtra.test.ts +1 -1
- package/src/Start.ts +0 -34
- package/src/StartApp.ts +20 -16
- package/src/bun/BunBundle.test.ts +1 -1
- package/src/bun/BunBundle_imports.test.ts +2 -2
- package/src/bun/BunRoute_bundles.test.ts +1 -1
- package/src/bun/_BunEnhancedResolve.ts +201 -0
- package/src/bun/index.ts +0 -1
- package/src/{SseHttpResponse.ts → experimental/SseHttpResponse.ts} +2 -1
- package/src/experimental/index.ts +2 -0
- package/src/index.ts +2 -20
- package/src/middlewares/index.ts +1 -0
- package/src/{TestHttpClient.test.ts → testing/TestHttpClient.test.ts} +1 -1
- package/src/{TestHttpClient.ts → testing/TestHttpClient.ts} +0 -1
- package/src/testing/index.ts +3 -0
- package/src/{bun/BunTailwindPlugin.test.ts → x/tailwind/TailwindPlugin.test.ts} +1 -1
- package/src/{bun/BunTailwindPlugin.ts → x/tailwind/TailwindPlugin.ts} +32 -42
- package/src/x/tailwind/compile.ts +243 -0
- package/src/x/tailwind/plugin.ts +2 -2
- package/src/JsModule.test.ts +0 -14
- package/src/JsModule.ts +0 -116
- package/src/PublicDirectory.test.ts +0 -280
- package/src/PublicDirectory.ts +0 -108
- package/src/StartHttp.ts +0 -42
- /package/src/{EncryptedCookies.test.ts → experimental/EncryptedCookies.test.ts} +0 -0
- /package/src/{EncryptedCookies.ts → experimental/EncryptedCookies.ts} +0 -0
- /package/src/{TestLogger.test.ts → testing/TestLogger.test.ts} +0 -0
- /package/src/{TestLogger.ts → testing/TestLogger.ts} +0 -0
- /package/src/{testing.ts → testing/utils.ts} +0 -0
package/README.md
CHANGED
|
@@ -52,13 +52,13 @@ src/routes
|
|
|
52
52
|
|
|
53
53
|
### Tailwind CSS Support
|
|
54
54
|
|
|
55
|
-
Effect Start comes with
|
|
56
|
-
works with minimal
|
|
55
|
+
Effect Start comes with Tailwind plugin that is lightweight and
|
|
56
|
+
works with minimal configuration.
|
|
57
57
|
|
|
58
|
-
First, install Tailwind package:
|
|
58
|
+
First, install official Tailwind package:
|
|
59
59
|
|
|
60
60
|
```sh
|
|
61
|
-
bun add tailwindcss
|
|
61
|
+
bun add -D tailwindcss
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Then, register a plugin in `bunfig.toml`:
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect-start",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./src/index.ts",
|
|
8
|
+
"./StartApp": "./src/StartApp.ts",
|
|
8
9
|
"./FileRouter": "./src/FileRouter.ts",
|
|
9
10
|
"./Route": "./src/Route.ts",
|
|
10
|
-
"./EncryptedCookies": "./src/EncryptedCookies.ts",
|
|
11
11
|
"./bun": "./src/bun/index.ts",
|
|
12
12
|
"./client": "./src/client/index.ts",
|
|
13
|
-
"./
|
|
14
|
-
"./package.json": "./package.json",
|
|
15
|
-
"./jsx-runtime": "./src/jsx-runtime.ts",
|
|
16
|
-
"./jsx-dev-runtime": "./src/jsx-runtime.ts",
|
|
17
|
-
"./hyper": "./src/hyper/index.ts",
|
|
13
|
+
"./testing": "./src/testing/index.ts",
|
|
18
14
|
"./x/*": "./src/x/*/index.ts",
|
|
19
15
|
"./x/tailwind/plugin": "./src/x/tailwind/plugin.ts",
|
|
20
|
-
"./middlewares
|
|
21
|
-
"./
|
|
16
|
+
"./middlewares": "./src/middlewares/index.ts",
|
|
17
|
+
"./experimental": "./src/experimental/index.ts",
|
|
18
|
+
"./assets.d.ts": "./src/assets.d.ts",
|
|
19
|
+
"./jsx-runtime": "./src/jsx-runtime.ts",
|
|
20
|
+
"./jsx-dev-runtime": "./src/jsx-runtime.ts",
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"format": "bunx dprint fmt",
|
|
@@ -32,23 +32,18 @@
|
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"typescript": "^5.9.3"
|
|
34
34
|
},
|
|
35
|
-
"peerDependenciesMeta": {
|
|
36
|
-
"@tailwindcss/node": {
|
|
37
|
-
"optional": true
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
35
|
"devDependencies": {
|
|
36
|
+
"dprint-cli": "^0.4.1",
|
|
37
|
+
"dprint-markup": "nounder/dprint-markup",
|
|
41
38
|
"@dprint/json": "^0.21.0",
|
|
42
39
|
"@dprint/markdown": "^0.20.0",
|
|
43
40
|
"@dprint/typescript": "^0.95.13",
|
|
44
41
|
"@effect/language-service": "^0.61.0",
|
|
45
|
-
"@tailwindcss/node": "^4.1.17",
|
|
46
42
|
"@types/bun": "^1.3.4",
|
|
47
43
|
"@types/react": "^19.2.7",
|
|
48
44
|
"@types/react-dom": "^19.2.3",
|
|
49
|
-
"dprint-cli": "^0.4.1",
|
|
50
|
-
"dprint-markup": "nounder/dprint-markup",
|
|
51
45
|
"effect-memfs": "^0.8.0",
|
|
46
|
+
"tailwindcss": "^4.1.18",
|
|
52
47
|
"ts-namespace-import": "nounder/ts-namespace-import#140c405"
|
|
53
48
|
},
|
|
54
49
|
"files": [
|
package/src/Bundle.ts
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
PubSub,
|
|
7
7
|
} from "effect"
|
|
8
8
|
import * as Schema from "effect/Schema"
|
|
9
|
-
import { importBlob } from "./JsModule.ts"
|
|
10
9
|
|
|
11
10
|
export const BundleEntrypointMetaKey: unique symbol = Symbol.for(
|
|
12
11
|
"effect-start/BundleEntrypointMetaKey",
|
|
@@ -131,37 +130,3 @@ export type Tag = Context.Tag<
|
|
|
131
130
|
|
|
132
131
|
export class ClientBundle extends Tag("ClientBundle")<ClientBundle>() {}
|
|
133
132
|
export class ServerBundle extends Tag("ServerBundle")<ServerBundle>() {}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Lodas a bundle as a javascript module.
|
|
137
|
-
* Bundle must have only one entrypoint.
|
|
138
|
-
*/
|
|
139
|
-
export function load<M>(
|
|
140
|
-
bundle: Effect.Effect<BundleContext, BundleError>,
|
|
141
|
-
): Effect.Effect<M, BundleError> {
|
|
142
|
-
return Effect.gen(function*() {
|
|
143
|
-
const context = yield* bundle
|
|
144
|
-
const [artifact, ...rest] = Object.values(context.entrypoints)
|
|
145
|
-
|
|
146
|
-
if (rest.length > 0) {
|
|
147
|
-
return yield* Effect.fail(
|
|
148
|
-
new BundleError({
|
|
149
|
-
message: "Multiple entrypoints are not supported in load()",
|
|
150
|
-
}),
|
|
151
|
-
)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return yield* Effect.tryPromise({
|
|
155
|
-
try: () => {
|
|
156
|
-
const blob = context.getArtifact(artifact)
|
|
157
|
-
|
|
158
|
-
return importBlob<M>(blob!)
|
|
159
|
-
},
|
|
160
|
-
catch: (e) =>
|
|
161
|
-
new BundleError({
|
|
162
|
-
message: "Failed to load entrypoint",
|
|
163
|
-
cause: e,
|
|
164
|
-
}),
|
|
165
|
-
})
|
|
166
|
-
})
|
|
167
|
-
}
|
package/src/BundleHttp.test.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import * as HttpRouter from "@effect/platform/HttpRouter"
|
|
2
2
|
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
|
|
3
3
|
import * as t from "bun:test"
|
|
4
|
-
import {
|
|
5
|
-
Bundle,
|
|
6
|
-
BundleHttp,
|
|
7
|
-
effectFn,
|
|
8
|
-
TestHttpClient,
|
|
9
|
-
} from "effect-start"
|
|
10
4
|
import * as Effect from "effect/Effect"
|
|
11
5
|
import * as Layer from "effect/Layer"
|
|
12
6
|
import IndexHtml from "../static/react-dashboard.html" with { type: "file" }
|
|
13
7
|
import * as BunBundle from "./bun/BunBundle.ts"
|
|
8
|
+
import * as Bundle from "./Bundle.ts"
|
|
9
|
+
import * as BundleHttp from "./BundleHttp.ts"
|
|
10
|
+
import { effectFn } from "./testing"
|
|
11
|
+
import * as TestHttpClient from "./testing/TestHttpClient.ts"
|
|
14
12
|
|
|
15
13
|
const effect = effectFn(
|
|
16
14
|
Layer.effect(
|
package/src/BundleHttp.ts
CHANGED
|
@@ -13,7 +13,8 @@ import * as Stream from "effect/Stream"
|
|
|
13
13
|
import * as NPath from "node:path"
|
|
14
14
|
import * as NUrl from "node:url"
|
|
15
15
|
import * as Bundle from "./Bundle.ts"
|
|
16
|
-
import * as SseHttpResponse from "./SseHttpResponse.ts"
|
|
16
|
+
import * as SseHttpResponse from "./experimental/SseHttpResponse.ts"
|
|
17
|
+
|
|
17
18
|
|
|
18
19
|
const DefaultBundleEndpoint = "/_bundle"
|
|
19
20
|
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
import * as HttpRouter from "@effect/platform/HttpRouter"
|
|
8
8
|
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
|
|
9
9
|
import * as t from "bun:test"
|
|
10
|
-
import
|
|
11
|
-
import * as TestHttpClient from "
|
|
12
|
-
import { effectFn } from "../src/testing.ts"
|
|
10
|
+
import { effectFn } from "../src/testing"
|
|
11
|
+
import * as TestHttpClient from "./testing/TestHttpClient.ts"
|
|
13
12
|
|
|
14
13
|
const effect = effectFn()
|
|
15
14
|
|
|
@@ -7,8 +7,8 @@ import * as Effect from "effect/Effect"
|
|
|
7
7
|
import * as FileHttpRouter from "./FileHttpRouter.ts"
|
|
8
8
|
import * as FileRouter from "./FileRouter.ts"
|
|
9
9
|
import * as Route from "./Route.ts"
|
|
10
|
-
import
|
|
11
|
-
import
|
|
10
|
+
import { effectFn } from "./testing"
|
|
11
|
+
import * as TestHttpClient from "./testing/TestHttpClient.ts"
|
|
12
12
|
|
|
13
13
|
class CustomError extends Data.TaggedError("CustomError") {}
|
|
14
14
|
|
|
@@ -12,7 +12,7 @@ import * as FileRouterCodegen from "./FileRouterCodegen.ts"
|
|
|
12
12
|
import * as NodeFileSystem from "./NodeFileSystem.ts"
|
|
13
13
|
import * as Route from "./Route.ts"
|
|
14
14
|
import * as SchemaExtra from "./SchemaExtra.ts"
|
|
15
|
-
import * as TestLogger from "./TestLogger.ts"
|
|
15
|
+
import * as TestLogger from "./testing/TestLogger.ts"
|
|
16
16
|
|
|
17
17
|
function createTempDirWithFiles(
|
|
18
18
|
files: Record<string, string>,
|
|
@@ -2,7 +2,7 @@ import * as t from "bun:test"
|
|
|
2
2
|
import { MemoryFileSystem } from "effect-memfs"
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
4
|
import * as FileRouter from "./FileRouter.ts"
|
|
5
|
-
import { effectFn } from "./testing
|
|
5
|
+
import { effectFn } from "./testing"
|
|
6
6
|
|
|
7
7
|
const Files = {
|
|
8
8
|
"/routes/about/layer.tsx": "",
|
package/src/HttpAppExtra.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "effect"
|
|
8
8
|
import * as Cause from "effect/Cause"
|
|
9
9
|
import * as HttpAppExtra from "./HttpAppExtra.ts"
|
|
10
|
-
import { effectFn } from "./testing
|
|
10
|
+
import { effectFn } from "./testing"
|
|
11
11
|
|
|
12
12
|
const mockRequest = HttpServerRequest.HttpServerRequest.of({
|
|
13
13
|
url: "http://localhost:3000/test",
|
package/src/Start.ts
CHANGED
|
@@ -3,48 +3,14 @@ import * as FileSystem from "@effect/platform/FileSystem"
|
|
|
3
3
|
import * as HttpClient from "@effect/platform/HttpClient"
|
|
4
4
|
import * as HttpRouter from "@effect/platform/HttpRouter"
|
|
5
5
|
import * as HttpServer from "@effect/platform/HttpServer"
|
|
6
|
-
import * as Config from "effect/Config"
|
|
7
6
|
import * as Effect from "effect/Effect"
|
|
8
7
|
import * as Function from "effect/Function"
|
|
9
8
|
import * as Layer from "effect/Layer"
|
|
10
|
-
import * as Option from "effect/Option"
|
|
11
|
-
import * as BunBundle from "./bun/BunBundle.ts"
|
|
12
9
|
import * as BunHttpServer from "./bun/BunHttpServer.ts"
|
|
13
|
-
import * as BunRoute from "./bun/BunRoute.ts"
|
|
14
10
|
import * as BunRuntime from "./bun/BunRuntime.ts"
|
|
15
|
-
import * as Bundle from "./Bundle.ts"
|
|
16
|
-
import * as BundleHttp from "./BundleHttp.ts"
|
|
17
|
-
import * as HttpAppExtra from "./HttpAppExtra.ts"
|
|
18
11
|
import * as NodeFileSystem from "./NodeFileSystem.ts"
|
|
19
|
-
import * as Router from "./Router.ts"
|
|
20
12
|
import * as StartApp from "./StartApp.ts"
|
|
21
13
|
|
|
22
|
-
export function bundleClient(config: BunBundle.BuildOptions | string) {
|
|
23
|
-
const clientLayer = Layer.effect(
|
|
24
|
-
Bundle.ClientBundle,
|
|
25
|
-
Function.pipe(
|
|
26
|
-
BunBundle.buildClient(config),
|
|
27
|
-
Bundle.handleBundleErrorSilently,
|
|
28
|
-
),
|
|
29
|
-
)
|
|
30
|
-
const assetsLayer = Layer.effectDiscard(Effect.gen(function*() {
|
|
31
|
-
const router = yield* HttpRouter.Default
|
|
32
|
-
const app = BundleHttp.toHttpApp(Bundle.ClientBundle)
|
|
33
|
-
|
|
34
|
-
yield* router.mountApp(
|
|
35
|
-
"/_bundle",
|
|
36
|
-
// we need to use as any here because HttpRouter.Default
|
|
37
|
-
// only accepts default services.
|
|
38
|
-
app as any,
|
|
39
|
-
)
|
|
40
|
-
}))
|
|
41
|
-
|
|
42
|
-
return Layer.mergeAll(
|
|
43
|
-
clientLayer,
|
|
44
|
-
assetsLayer,
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
14
|
export function layer<
|
|
49
15
|
Layers extends [
|
|
50
16
|
Layer.Layer<never, any, any>,
|
package/src/StartApp.ts
CHANGED
|
@@ -3,23 +3,22 @@ import * as Context from "effect/Context"
|
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
4
|
import * as Function from "effect/Function"
|
|
5
5
|
import * as Layer from "effect/Layer"
|
|
6
|
+
import * as PubSub from "effect/PubSub"
|
|
6
7
|
import * as Ref from "effect/Ref"
|
|
7
8
|
|
|
8
|
-
type NewType = HttpApp.Default<never, never>
|
|
9
|
-
|
|
10
9
|
type StartMiddleware = <E, R>(
|
|
11
10
|
self: HttpApp.Default<E, R>,
|
|
12
|
-
) =>
|
|
11
|
+
) => HttpApp.Default<never, never>
|
|
13
12
|
|
|
14
13
|
export class StartApp extends Context.Tag("effect-start/StartApp")<
|
|
15
14
|
StartApp,
|
|
16
15
|
{
|
|
17
16
|
readonly env: "development" | "production" | string
|
|
18
|
-
readonly relativeUrlRoot?: string
|
|
19
17
|
readonly addMiddleware: (
|
|
20
18
|
middleware: StartMiddleware,
|
|
21
19
|
) => Effect.Effect<void>
|
|
22
20
|
readonly middleware: Ref.Ref<StartMiddleware>
|
|
21
|
+
readonly events: PubSub.PubSub<any>
|
|
23
22
|
}
|
|
24
23
|
>() {
|
|
25
24
|
}
|
|
@@ -27,17 +26,22 @@ export class StartApp extends Context.Tag("effect-start/StartApp")<
|
|
|
27
26
|
export function layer(options?: {
|
|
28
27
|
env?: string
|
|
29
28
|
}) {
|
|
30
|
-
return Layer.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
return Layer.effect(
|
|
30
|
+
StartApp,
|
|
31
|
+
Effect.gen(function*() {
|
|
32
|
+
const env = options?.env ?? process.env.NODE_ENV ?? "development"
|
|
33
|
+
const middleware = yield* Ref.make(
|
|
34
|
+
Function.identity as StartMiddleware,
|
|
35
|
+
)
|
|
36
|
+
const events = yield* PubSub.unbounded()
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
return StartApp.of({
|
|
39
|
+
env,
|
|
40
|
+
middleware,
|
|
41
|
+
addMiddleware: (f) =>
|
|
42
|
+
Ref.update(middleware, (prev) => (app) => f(prev(app))),
|
|
43
|
+
events,
|
|
44
|
+
})
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
43
47
|
}
|
|
@@ -7,7 +7,7 @@ import * as NOS from "node:os"
|
|
|
7
7
|
import * as NPath from "node:path"
|
|
8
8
|
import * as Bundle from "../Bundle.ts"
|
|
9
9
|
import * as BundleHttp from "../BundleHttp.ts"
|
|
10
|
-
import * as TestHttpClient from "../TestHttpClient.ts"
|
|
10
|
+
import * as TestHttpClient from "../testing/TestHttpClient.ts"
|
|
11
11
|
import * as BunBundle from "./BunBundle.ts"
|
|
12
12
|
|
|
13
13
|
t.describe("BunBundle manifest structure", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "bun:test"
|
|
2
|
-
import { effectFn } from "../testing
|
|
2
|
+
import { effectFn } from "../testing"
|
|
3
3
|
import * as BunBundle from "./BunBundle.ts"
|
|
4
4
|
import * as BunImportTrackerPlugin from "./BunImportTrackerPlugin.ts"
|
|
5
5
|
|
|
@@ -35,7 +35,7 @@ t.it("imports", () =>
|
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
kind: "import-statement",
|
|
38
|
-
path: "src/testing
|
|
38
|
+
path: "src/testing",
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
kind: "import-statement",
|
|
@@ -2,7 +2,7 @@ import * as t from "bun:test"
|
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
3
|
import * as Route from "../Route.ts"
|
|
4
4
|
import * as Router from "../Router.ts"
|
|
5
|
-
import * as TestHttpClient from "../TestHttpClient.ts"
|
|
5
|
+
import * as TestHttpClient from "../testing/TestHttpClient.ts"
|
|
6
6
|
import * as BunHttpServer from "./BunHttpServer.ts"
|
|
7
7
|
import * as BunRoute from "./BunRoute.ts"
|
|
8
8
|
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun adapter for enhanced-resolve
|
|
3
|
+
*
|
|
4
|
+
* This module provides a drop-in replacement for `enhanced-resolve` that uses
|
|
5
|
+
* Bun's built-in resolver. It implements the subset of the enhanced-resolve API
|
|
6
|
+
* used for Tailwind CSS.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "node:fs"
|
|
9
|
+
import path from "node:path"
|
|
10
|
+
|
|
11
|
+
type ErrorWithDetail =
|
|
12
|
+
& Error
|
|
13
|
+
& {
|
|
14
|
+
details?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ResolveRequest {
|
|
18
|
+
path: string | false
|
|
19
|
+
context?: object
|
|
20
|
+
descriptionFilePath?: string
|
|
21
|
+
descriptionFileRoot?: string
|
|
22
|
+
descriptionFileData?: Record<string, unknown>
|
|
23
|
+
relativePath?: string
|
|
24
|
+
ignoreSymlinks?: boolean
|
|
25
|
+
fullySpecified?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface ResolveContext {
|
|
29
|
+
contextDependencies?: { add: (item: string) => void }
|
|
30
|
+
fileDependencies?: { add: (item: string) => void }
|
|
31
|
+
missingDependencies?: { add: (item: string) => void }
|
|
32
|
+
stack?: Set<string>
|
|
33
|
+
log?: (str: string) => void
|
|
34
|
+
yield?: (request: ResolveRequest) => void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface ResolveOptions {
|
|
38
|
+
extensions?: string[]
|
|
39
|
+
mainFields?: (string | string[])[]
|
|
40
|
+
conditionNames?: string[]
|
|
41
|
+
fileSystem?: unknown
|
|
42
|
+
useSyncFileSystemCalls?: boolean
|
|
43
|
+
modules?: string | string[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface Resolver {
|
|
47
|
+
resolve(
|
|
48
|
+
context: object,
|
|
49
|
+
path: string,
|
|
50
|
+
request: string,
|
|
51
|
+
resolveContext: ResolveContext,
|
|
52
|
+
callback: (
|
|
53
|
+
err: null | ErrorWithDetail,
|
|
54
|
+
res?: string | false,
|
|
55
|
+
req?: ResolveRequest,
|
|
56
|
+
) => void,
|
|
57
|
+
): void
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class CachedInputFileSystem {
|
|
61
|
+
constructor(
|
|
62
|
+
_fileSystem: unknown,
|
|
63
|
+
_duration: number,
|
|
64
|
+
) {}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const ResolverFactory = {
|
|
68
|
+
createResolver(options: ResolveOptions): Resolver {
|
|
69
|
+
const extensions = options.extensions ?? []
|
|
70
|
+
const mainFields = (options.mainFields ?? []).flatMap((f) =>
|
|
71
|
+
Array.isArray(f) ? f : [f]
|
|
72
|
+
)
|
|
73
|
+
const conditionNames = options.conditionNames ?? []
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
resolve(
|
|
77
|
+
_context: object,
|
|
78
|
+
basePath: string,
|
|
79
|
+
id: string,
|
|
80
|
+
_resolveContext: ResolveContext,
|
|
81
|
+
callback: (
|
|
82
|
+
err: null | ErrorWithDetail,
|
|
83
|
+
res?: string | false,
|
|
84
|
+
req?: ResolveRequest,
|
|
85
|
+
) => void,
|
|
86
|
+
): void {
|
|
87
|
+
try {
|
|
88
|
+
const result = resolveSync(id, basePath, {
|
|
89
|
+
extensions,
|
|
90
|
+
mainFields,
|
|
91
|
+
conditionNames,
|
|
92
|
+
})
|
|
93
|
+
callback(null, result)
|
|
94
|
+
} catch (err) {
|
|
95
|
+
callback(err instanceof Error ? err : new Error(String(err)))
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface ResolveInternalOptions {
|
|
103
|
+
extensions: string[]
|
|
104
|
+
mainFields: string[]
|
|
105
|
+
conditionNames: string[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function resolveSync(
|
|
109
|
+
id: string,
|
|
110
|
+
base: string,
|
|
111
|
+
options: ResolveInternalOptions,
|
|
112
|
+
): string | undefined {
|
|
113
|
+
if (id.startsWith(".") || id.startsWith("/")) {
|
|
114
|
+
for (const ext of ["", ...options.extensions]) {
|
|
115
|
+
const fullPath = path.resolve(base, id + ext)
|
|
116
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
|
117
|
+
return fullPath
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return undefined
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const packagePath = resolvePackagePath(id, base)
|
|
124
|
+
if (!packagePath) return undefined
|
|
125
|
+
|
|
126
|
+
const packageJsonPath = path.join(packagePath, "package.json")
|
|
127
|
+
if (!fs.existsSync(packageJsonPath)) return undefined
|
|
128
|
+
|
|
129
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"))
|
|
130
|
+
|
|
131
|
+
for (const field of options.mainFields) {
|
|
132
|
+
if (typeof packageJson[field] === "string") {
|
|
133
|
+
const resolved = path.resolve(packagePath, packageJson[field])
|
|
134
|
+
if (fs.existsSync(resolved)) return resolved
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (packageJson.exports) {
|
|
139
|
+
const resolved = resolveExports(
|
|
140
|
+
packageJson.exports,
|
|
141
|
+
packagePath,
|
|
142
|
+
options.conditionNames,
|
|
143
|
+
)
|
|
144
|
+
if (resolved && fs.existsSync(resolved)) return resolved
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
return Bun.resolveSync(id, base)
|
|
149
|
+
} catch {
|
|
150
|
+
return undefined
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function resolvePackagePath(id: string, base: string): string | undefined {
|
|
155
|
+
const parts = id.split("/")
|
|
156
|
+
const packageName = id.startsWith("@")
|
|
157
|
+
? parts.slice(0, 2).join("/")
|
|
158
|
+
: parts[0]
|
|
159
|
+
|
|
160
|
+
let dir = base
|
|
161
|
+
while (dir !== path.dirname(dir)) {
|
|
162
|
+
const candidate = path.join(dir, "node_modules", packageName)
|
|
163
|
+
if (fs.existsSync(candidate)) return candidate
|
|
164
|
+
dir = path.dirname(dir)
|
|
165
|
+
}
|
|
166
|
+
return undefined
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function resolveExports(
|
|
170
|
+
exports: unknown,
|
|
171
|
+
packagePath: string,
|
|
172
|
+
conditionNames: string[],
|
|
173
|
+
): string | undefined {
|
|
174
|
+
if (typeof exports === "string") {
|
|
175
|
+
return path.resolve(packagePath, exports)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (exports && typeof exports === "object" && !Array.isArray(exports)) {
|
|
179
|
+
const exportsObj = exports as Record<string, unknown>
|
|
180
|
+
|
|
181
|
+
if ("." in exportsObj) {
|
|
182
|
+
return resolveExports(exportsObj["."], packagePath, conditionNames)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
for (const condition of conditionNames) {
|
|
186
|
+
if (condition in exportsObj) {
|
|
187
|
+
return resolveExports(
|
|
188
|
+
exportsObj[condition],
|
|
189
|
+
packagePath,
|
|
190
|
+
conditionNames,
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if ("default" in exportsObj) {
|
|
196
|
+
return resolveExports(exportsObj["default"], packagePath, conditionNames)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return undefined
|
|
201
|
+
}
|
package/src/bun/index.ts
CHANGED
|
@@ -4,7 +4,8 @@ import * as Effect from "effect/Effect"
|
|
|
4
4
|
import * as Function from "effect/Function"
|
|
5
5
|
import * as Schedule from "effect/Schedule"
|
|
6
6
|
import * as Stream from "effect/Stream"
|
|
7
|
-
import * as StreamExtra from "
|
|
7
|
+
import * as StreamExtra from "../StreamExtra.ts"
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
const DefaultHeartbeatInterval = Duration.seconds(5)
|
|
10
11
|
|
package/src/index.ts
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
export * as
|
|
2
|
-
export * as BundleHttp from "./BundleHttp.ts"
|
|
3
|
-
|
|
4
|
-
export * as StartHttp from "./StartHttp.ts"
|
|
5
|
-
|
|
6
|
-
export * as HttpAppExtra from "./HttpAppExtra.ts"
|
|
7
|
-
|
|
8
|
-
export * as PublicDirectory from "./PublicDirectory.ts"
|
|
9
|
-
|
|
10
|
-
export * as TestHttpClient from "./TestHttpClient.ts"
|
|
11
|
-
export {
|
|
12
|
-
effectFn,
|
|
13
|
-
} from "./testing.ts"
|
|
1
|
+
export * as Start from "./Start.ts"
|
|
14
2
|
|
|
15
|
-
export * as FileHttpRouter from "./FileHttpRouter.ts"
|
|
16
3
|
export * as FileRouter from "./FileRouter.ts"
|
|
17
|
-
|
|
18
4
|
export * as Route from "./Route.ts"
|
|
19
|
-
export * as Router from "./Router.ts"
|
|
20
5
|
|
|
21
|
-
export * as
|
|
22
|
-
|
|
23
|
-
export * as Hyper from "./Hyper.ts"
|
|
24
|
-
export * as HyperHtml from "./HyperHtml.ts"
|
|
6
|
+
export * as Bundle from "./Bundle.ts"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as BasicAuthMiddleware from "./BasicAuthMiddleware.ts"
|
|
@@ -2,8 +2,8 @@ import * as HttpServerRequest from "@effect/platform/HttpServerRequest"
|
|
|
2
2
|
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
|
|
3
3
|
import * as t from "bun:test"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
|
+
import { effectFn } from "./index.ts"
|
|
5
6
|
import * as TestHttpClient from "./TestHttpClient.ts"
|
|
6
|
-
import { effectFn } from "./testing.ts"
|
|
7
7
|
|
|
8
8
|
const App = Effect.gen(function*() {
|
|
9
9
|
const req = yield* HttpServerRequest.HttpServerRequest
|
|
@@ -10,7 +10,6 @@ import * as UrlParams from "@effect/platform/UrlParams"
|
|
|
10
10
|
import * as Effect from "effect/Effect"
|
|
11
11
|
import * as Either from "effect/Either"
|
|
12
12
|
import * as Function from "effect/Function"
|
|
13
|
-
import * as Scope from "effect/Scope"
|
|
14
13
|
import * as Stream from "effect/Stream"
|
|
15
14
|
|
|
16
15
|
const WebHeaders = globalThis.Headers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as t from "bun:test"
|
|
2
2
|
|
|
3
|
-
import { extractClassNames } from "./
|
|
3
|
+
import { extractClassNames } from "./TailwindPlugin.ts"
|
|
4
4
|
|
|
5
5
|
// Keep the old broad implementation for comparison tests
|
|
6
6
|
function extractClassNamesBroad(source: string): Set<string> {
|