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.
Files changed (94) hide show
  1. package/README.md +1 -4
  2. package/dist/Cookies.js +392 -0
  3. package/dist/FileSystem.js +131 -0
  4. package/dist/Socket.js +37 -0
  5. package/package.json +35 -36
  6. package/src/Commander.ts +73 -130
  7. package/src/ContentNegotiation.ts +64 -95
  8. package/src/Cookies.ts +36 -57
  9. package/src/Development.ts +47 -62
  10. package/src/Effectify.ts +222 -206
  11. package/src/Entity.ts +59 -86
  12. package/src/FilePathPattern.ts +5 -5
  13. package/src/FileRouter.ts +37 -62
  14. package/src/FileRouterCodegen.ts +63 -55
  15. package/src/FileSystem.ts +46 -59
  16. package/src/Http.ts +17 -50
  17. package/src/PathPattern.ts +33 -41
  18. package/src/PlatformError.ts +29 -50
  19. package/src/PlatformRuntime.ts +39 -47
  20. package/src/Route.ts +68 -187
  21. package/src/RouteBody.ts +45 -161
  22. package/src/RouteHook.ts +22 -45
  23. package/src/RouteHttp.ts +88 -142
  24. package/src/RouteHttpTracer.ts +25 -26
  25. package/src/RouteMount.ts +100 -238
  26. package/src/RouteSchema.ts +67 -201
  27. package/src/RouteSse.ts +28 -82
  28. package/src/RouteTree.ts +31 -79
  29. package/src/RouteTrie.ts +13 -32
  30. package/src/SchemaExtra.ts +3 -5
  31. package/src/Socket.ts +5 -2
  32. package/src/Start.ts +20 -21
  33. package/src/StreamExtra.ts +93 -96
  34. package/src/TuplePathPattern.ts +54 -43
  35. package/src/Unique.ts +9 -15
  36. package/src/Values.ts +26 -30
  37. package/src/bun/BunBundle.ts +27 -73
  38. package/src/bun/BunImportTrackerPlugin.ts +67 -65
  39. package/src/bun/BunRoute.ts +12 -31
  40. package/src/bun/BunRuntime.ts +3 -10
  41. package/src/bun/BunServer.ts +55 -91
  42. package/src/bun/BunVirtualFilesPlugin.ts +1 -4
  43. package/src/bun/_BunEnhancedResolve.ts +17 -42
  44. package/src/bun/_empty.html +0 -1
  45. package/src/bundler/Bundle.ts +20 -36
  46. package/src/bundler/BundleFiles.ts +35 -55
  47. package/src/client/Overlay.ts +1 -2
  48. package/src/client/ScrollState.ts +5 -9
  49. package/src/client/index.ts +10 -13
  50. package/src/datastar/actions/fetch.ts +29 -48
  51. package/src/datastar/actions/peek.ts +1 -5
  52. package/src/datastar/actions/setAll.ts +2 -2
  53. package/src/datastar/actions/toggleAll.ts +2 -2
  54. package/src/datastar/attributes/attr.ts +17 -18
  55. package/src/datastar/attributes/bind.ts +41 -61
  56. package/src/datastar/attributes/class.ts +2 -5
  57. package/src/datastar/attributes/computed.ts +2 -10
  58. package/src/datastar/attributes/effect.ts +1 -2
  59. package/src/datastar/attributes/indicator.ts +2 -8
  60. package/src/datastar/attributes/init.ts +2 -10
  61. package/src/datastar/attributes/jsonSignals.ts +1 -6
  62. package/src/datastar/attributes/on.ts +4 -13
  63. package/src/datastar/attributes/onIntersect.ts +10 -22
  64. package/src/datastar/attributes/onInterval.ts +2 -10
  65. package/src/datastar/attributes/onSignalPatch.ts +18 -28
  66. package/src/datastar/attributes/ref.ts +1 -2
  67. package/src/datastar/attributes/show.ts +1 -2
  68. package/src/datastar/attributes/signals.ts +1 -5
  69. package/src/datastar/attributes/style.ts +6 -12
  70. package/src/datastar/attributes/text.ts +1 -2
  71. package/src/datastar/engine.ts +102 -158
  72. package/src/datastar/index.ts +2 -2
  73. package/src/datastar/utils.ts +16 -51
  74. package/src/datastar/watchers/patchElements.ts +35 -93
  75. package/src/datastar/watchers/patchSignals.ts +1 -2
  76. package/src/experimental/EncryptedCookies.ts +79 -142
  77. package/src/hyper/Hyper.ts +14 -33
  78. package/src/hyper/HyperHtml.ts +9 -10
  79. package/src/hyper/HyperNode.ts +2 -7
  80. package/src/hyper/HyperRoute.ts +2 -5
  81. package/src/hyper/jsx-runtime.ts +2 -10
  82. package/src/hyper/jsx.d.ts +171 -440
  83. package/src/lint/plugin.js +276 -0
  84. package/src/node/NodeFileSystem.ts +138 -186
  85. package/src/node/NodeUtils.ts +1 -3
  86. package/src/testing/TestLogger.ts +9 -22
  87. package/src/testing/utils.ts +30 -31
  88. package/src/x/cloudflare/CloudflareTunnel.ts +37 -54
  89. package/src/x/datastar/Datastar.ts +3 -10
  90. package/src/x/datastar/index.ts +1 -3
  91. package/src/x/datastar/jsx-datastar.d.ts +1 -4
  92. package/src/x/tailwind/TailwindPlugin.ts +119 -112
  93. package/src/x/tailwind/compile.ts +10 -33
  94. package/src/x/tailwind/plugin.ts +2 -2
@@ -11,9 +11,9 @@ import {
11
11
  String,
12
12
  } from "effect"
13
13
 
14
- export class CloudflareTunnelSpawnError extends Data.TaggedError(
15
- "CloudflareTunnelSpawnError",
16
- )<{ cause: unknown }> {}
14
+ export class CloudflareTunnelSpawnError extends Data.TaggedError("CloudflareTunnelSpawnError")<{
15
+ cause: unknown
16
+ }> {}
17
17
 
18
18
  export const start = (opts: {
19
19
  command?: string
@@ -23,36 +23,28 @@ export const start = (opts: {
23
23
  logLevel?: LogLevel.LogLevel
24
24
  logPrefix?: string
25
25
  }) =>
26
- Effect.gen(function*() {
27
- const logPrefix = String.isString(opts.logPrefix)
28
- ? opts.logPrefix
29
- : "CloudflareTunnel: "
30
- const args: string[] = [
26
+ Effect.gen(function* () {
27
+ const logPrefix = String.isString(opts.logPrefix) ? opts.logPrefix : "CloudflareTunnel: "
28
+ const args: Array<string> = [
31
29
  "tunnel",
32
30
  "run",
33
- opts.tunnelUrl
34
- ? [
35
- "--url",
36
- opts.tunnelUrl,
37
- ]
38
- : [],
31
+ opts.tunnelUrl ? ["--url", opts.tunnelUrl] : [],
39
32
  opts.tunnelName,
40
- ]
41
- .flatMap(v => v)
33
+ ].flatMap((v) => v)
42
34
 
43
35
  const proc = yield* Effect.try({
44
36
  try: () =>
45
- Bun.spawn(
46
- [opts.command ?? "cloudflared", ...args],
47
- { stderr: "pipe", stdout: "pipe" },
48
- ),
37
+ Bun.spawn([opts.command ?? "cloudflared", ...args], {
38
+ stderr: "pipe",
39
+ stdout: "pipe",
40
+ }),
49
41
  catch: (err) => new CloudflareTunnelSpawnError({ cause: err }),
50
42
  })
51
43
 
52
44
  yield* Effect.addFinalizer(() =>
53
45
  Effect.sync(() => {
54
46
  proc.kill()
55
- })
47
+ }),
56
48
  )
57
49
 
58
50
  yield* Effect.logInfo(
@@ -68,48 +60,39 @@ export const start = (opts: {
68
60
  ),
69
61
  Stream.decodeText("utf-8"),
70
62
  Stream.splitLines,
71
- opts.cleanLogs ?? true
72
- ? Stream.map(v =>
73
- v.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\s\w+\s/, "")
74
- )
63
+ (opts.cleanLogs ?? true)
64
+ ? Stream.map((v) => v.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\s\w+\s/, ""))
75
65
  : identity,
76
- logPrefix
77
- ? Stream.map(v => logPrefix + v)
78
- : identity,
79
- Stream.runForEach(v =>
80
- Effect.logWithLevel(opts.logLevel ?? LogLevel.Debug, v)
81
- ),
66
+ logPrefix ? Stream.map((v) => logPrefix + v) : identity,
67
+ Stream.runForEach((v) => Effect.logWithLevel(opts.logLevel ?? LogLevel.Debug, v)),
82
68
  )
83
69
  })
84
70
 
85
71
  export const layer = () =>
86
- Layer.scopedDiscard(Effect.gen(function*() {
87
- const tunnelName = yield* pipe(
88
- Config.string("CLOUDFLARE_TUNNEL_NAME"),
89
- Config.option,
90
- Effect.andThen(Option.getOrUndefined),
91
- )
92
- const tunnelUrl = yield* pipe(
93
- Config.string("CLOUDFLARE_TUNNEL_URL"),
94
- Config.option,
95
- Effect.andThen(Option.getOrUndefined),
96
- )
72
+ Layer.scopedDiscard(
73
+ Effect.gen(function* () {
74
+ const tunnelName = yield* pipe(
75
+ Config.string("CLOUDFLARE_TUNNEL_NAME"),
76
+ Config.option,
77
+ Effect.andThen(Option.getOrUndefined),
78
+ )
79
+ const tunnelUrl = yield* pipe(
80
+ Config.string("CLOUDFLARE_TUNNEL_URL"),
81
+ Config.option,
82
+ Effect.andThen(Option.getOrUndefined),
83
+ )
97
84
 
98
- if (!tunnelName) {
99
- yield* Effect.logWarning("CLOUDFLARE_TUNNEL_NAME not provided. Skipping.")
85
+ if (!tunnelName) {
86
+ yield* Effect.logWarning("CLOUDFLARE_TUNNEL_NAME not provided. Skipping.")
100
87
 
101
- return
102
- }
88
+ return
89
+ }
103
90
 
104
- yield* Effect
105
- .forkScoped(
91
+ yield* Effect.forkScoped(
106
92
  start({
107
93
  tunnelName,
108
94
  tunnelUrl,
109
- }).pipe(
110
- Effect.catchAll(err =>
111
- Effect.logError("Cloudflare tunnel failed", err)
112
- ),
113
- ),
95
+ }).pipe(Effect.catchAll((err) => Effect.logError("Cloudflare tunnel failed", err))),
114
96
  )
115
- }))
97
+ }),
98
+ )
@@ -1,4 +1,4 @@
1
- import * as HyperNode from "../../hyper/HyperNode.ts"
1
+ import type * as HyperNode from "../../hyper/HyperNode.ts"
2
2
 
3
3
  export const HyperHooks = {
4
4
  onNode,
@@ -49,18 +49,11 @@ function onNode(node: HyperNode.HyperNode) {
49
49
 
50
50
  // Handle dynamic attributes with suffixes
51
51
  for (const [key, value] of Object.entries(node.props)) {
52
- if (
53
- key.startsWith("data-signals-")
54
- && typeof value === "object"
55
- && value !== null
56
- ) {
52
+ if (key.startsWith("data-signals-") && typeof value === "object" && value !== null) {
57
53
  node.props[key] = JSON.stringify(value)
58
54
  }
59
55
 
60
- if (
61
- key.startsWith("data-on-")
62
- && typeof value === "function"
63
- ) {
56
+ if (key.startsWith("data-on-") && typeof value === "function") {
64
57
  // @ts-ignore
65
58
  node.props[key] = `(${value.toString()})()`
66
59
  }
@@ -1,4 +1,2 @@
1
1
  export * as Datastar from "./Datastar.ts"
2
- export {
3
- HyperHooks,
4
- } from "./Datastar.ts"
2
+ export { HyperHooks } from "./Datastar.ts"
@@ -2,10 +2,7 @@
2
2
  type DatastarSignalsObject = Record<string, any>
3
3
  type DatastarClassObject = Record<string, boolean | string>
4
4
  type DatastarAttrObject = Record<string, string | boolean | number>
5
- type DatastarStyleObject = Record<
6
- string,
7
- string | number | boolean | null | undefined
8
- >
5
+ type DatastarStyleObject = Record<string, string | number | boolean | null | undefined>
9
6
 
10
7
  /**
11
8
  * Datastar attributes for reactive web applications
@@ -46,12 +46,12 @@ export const make = (opts?: {
46
46
 
47
47
  const prepopulateCandidates = opts?.scanPath
48
48
  ? async () => {
49
- const candidates = await scanFiles(opts.scanPath!)
49
+ const candidates = await scanFiles(opts.scanPath!)
50
50
 
51
- scannedCandidates.clear()
51
+ scannedCandidates.clear()
52
52
 
53
- candidates.forEach(candidate => scannedCandidates.add(candidate))
54
- }
53
+ candidates.forEach((candidate) => scannedCandidates.add(candidate))
54
+ }
55
55
  : null
56
56
 
57
57
  // Track import relationships when dynamically scanning
@@ -60,122 +60,129 @@ export const make = (opts?: {
60
60
  // Better to pass scanPath explicitly.
61
61
  // @see https://github.com/oven-sh/bun/issues/20877
62
62
  if (!prepopulateCandidates) {
63
- builder.onResolve({
64
- filter: /.*/,
65
- }, (args) => {
66
- const fullPath = Bun.resolveSync(args.path, args.resolveDir)
67
- const importer = args.importer
68
-
69
- if (fullPath.includes("/node_modules/")) {
70
- return undefined
71
- }
72
-
73
- /**
74
- * Register every visited module.
75
- */
63
+ builder.onResolve(
76
64
  {
77
- if (!importAncestors.has(fullPath)) {
78
- importAncestors.set(fullPath, new Set())
65
+ filter: /.*/,
66
+ },
67
+ (args) => {
68
+ const fullPath = Bun.resolveSync(args.path, args.resolveDir)
69
+ const importer = args.importer
70
+
71
+ if (fullPath.includes("/node_modules/")) {
72
+ return undefined
79
73
  }
80
74
 
81
- if (!importDescendants.has(fullPath)) {
82
- importDescendants.set(fullPath, new Set())
75
+ /**
76
+ * Register every visited module.
77
+ */
78
+ {
79
+ if (!importAncestors.has(fullPath)) {
80
+ importAncestors.set(fullPath, new Set())
81
+ }
82
+
83
+ if (!importDescendants.has(fullPath)) {
84
+ importDescendants.set(fullPath, new Set())
85
+ }
86
+
87
+ if (!importAncestors.has(importer)) {
88
+ importAncestors.set(args.importer, new Set())
89
+ }
90
+
91
+ if (!importDescendants.has(importer)) {
92
+ importDescendants.set(importer, new Set())
93
+ }
83
94
  }
84
95
 
85
- if (!importAncestors.has(importer)) {
86
- importAncestors.set(args.importer, new Set())
87
- }
96
+ importAncestors.get(fullPath)!.add(importer)
97
+ importDescendants.get(importer)!.add(fullPath)
88
98
 
89
- if (!importDescendants.has(importer)) {
90
- importDescendants.set(importer, new Set())
91
- }
92
- }
93
-
94
- importAncestors.get(fullPath)!.add(importer)
95
- importDescendants.get(importer)!.add(fullPath)
96
-
97
- return undefined
98
- })
99
+ return undefined
100
+ },
101
+ )
99
102
  }
100
103
 
101
104
  /**
102
105
  * Scan for class name candidates in component files.
103
106
  */
104
- builder.onLoad({
105
- filter: filesPattern,
106
- }, async (args) => {
107
- const contents = await Bun.file(args.path).text()
108
- const classNames = extractClassNames(contents)
109
-
110
- if (classNames.size > 0) {
111
- classNameCandidates.set(args.path, classNames)
112
- }
107
+ builder.onLoad(
108
+ {
109
+ filter: filesPattern,
110
+ },
111
+ async (args) => {
112
+ const contents = await Bun.file(args.path).text()
113
+ const classNames = extractClassNames(contents)
114
+
115
+ if (classNames.size > 0) {
116
+ classNameCandidates.set(args.path, classNames)
117
+ }
113
118
 
114
- return undefined
115
- })
119
+ return undefined
120
+ },
121
+ )
116
122
 
117
123
  /**
118
124
  * Compile tailwind entrypoints.
119
125
  */
120
- builder.onLoad({
121
- filter: cssPattern,
122
- }, async (args) => {
123
- const source = await Bun.file(args.path).text()
124
-
125
- if (!hasCssImport(source, "tailwindcss")) {
126
- return undefined
127
- }
126
+ builder.onLoad(
127
+ {
128
+ filter: cssPattern,
129
+ },
130
+ async (args) => {
131
+ const source = await Bun.file(args.path).text()
132
+
133
+ if (!hasCssImport(source, "tailwindcss")) {
134
+ return undefined
135
+ }
128
136
 
129
- const compiler = await Tailwind.compile(source, {
130
- base: NPath.dirname(args.path),
131
- onDependency: (path) => {},
132
- })
137
+ const compiler = await Tailwind.compile(source, {
138
+ base: NPath.dirname(args.path),
139
+ onDependency: (path) => {},
140
+ })
133
141
 
134
- await prepopulateCandidates?.()
142
+ await prepopulateCandidates?.()
135
143
 
136
- // wait for other files to be loaded so we can collect class name candidates
137
- await args.defer()
144
+ // wait for other files to be loaded so we can collect class name candidates
145
+ await args.defer()
138
146
 
139
- const candidates = new Set<string>(scannedCandidates)
147
+ const candidates = new Set<string>(scannedCandidates)
140
148
 
141
- // when we scan a path, we don't need to track candidate tree
142
- if (!prepopulateCandidates) {
143
- const pendingModules = [
144
- // get class name candidates from all modules that import this one
145
- ...(importAncestors.get(args.path) ?? []),
146
- ]
147
- const visitedModules = new Set<string>()
149
+ // when we scan a path, we don't need to track candidate tree
150
+ if (!prepopulateCandidates) {
151
+ const pendingModules = [
152
+ // get class name candidates from all modules that import this one
153
+ ...(importAncestors.get(args.path) ?? []),
154
+ ]
155
+ const visitedModules = new Set<string>()
148
156
 
149
- while (pendingModules.length > 0) {
150
- const currentPath = pendingModules.shift()!
157
+ while (pendingModules.length > 0) {
158
+ const currentPath = pendingModules.shift()!
151
159
 
152
- if (visitedModules.has(currentPath)) {
153
- continue
154
- }
160
+ if (visitedModules.has(currentPath)) {
161
+ continue
162
+ }
155
163
 
156
- const moduleImports = importDescendants.get(currentPath)
164
+ const moduleImports = importDescendants.get(currentPath)
157
165
 
158
- moduleImports?.forEach(moduleImport => {
159
- const moduleCandidates = classNameCandidates.get(moduleImport)
166
+ moduleImports?.forEach((moduleImport) => {
167
+ const moduleCandidates = classNameCandidates.get(moduleImport)
160
168
 
161
- moduleCandidates?.forEach(candidate => candidates.add(candidate))
169
+ moduleCandidates?.forEach((candidate) => candidates.add(candidate))
162
170
 
163
- pendingModules.push(moduleImport)
164
- })
171
+ pendingModules.push(moduleImport)
172
+ })
165
173
 
166
- visitedModules.add(currentPath)
174
+ visitedModules.add(currentPath)
175
+ }
167
176
  }
168
- }
169
177
 
170
- const contents = compiler.build([
171
- ...candidates,
172
- ])
178
+ const contents = compiler.build([...candidates])
173
179
 
174
- return {
175
- contents,
176
- loader: "css",
177
- }
178
- })
180
+ return {
181
+ contents,
182
+ loader: "css",
183
+ }
184
+ },
185
+ )
179
186
  },
180
187
  }
181
188
  }
@@ -186,19 +193,19 @@ const TEMPLATE_EXPRESSION_REGEX = /\$\{[^}]*\}/g
186
193
  const TAILWIND_CLASS_REGEX = /^[a-zA-Z0-9_:-]+(\[[^\]]*\])?$/
187
194
  const CLASS_NAME_PATTERNS = [
188
195
  // HTML class attributes with double quotes: <div class="bg-blue-500 text-white">
189
- "<[^>]*?\\sclass\\s*=\\s*\"([^\"]+)\"",
196
+ '<[^>]*?\\sclass\\s*=\\s*"([^"]+)"',
190
197
 
191
198
  // HTML class attributes with single quotes: <div class='bg-blue-500 text-white'>
192
199
  "<[^>]*?\\sclass\\s*=\\s*'([^']+)'",
193
200
 
194
201
  // JSX className attributes with double quotes: <div className="bg-blue-500 text-white">
195
- "<[^>]*?\\sclassName\\s*=\\s*\"([^\"]+)\"",
202
+ '<[^>]*?\\sclassName\\s*=\\s*"([^"]+)"',
196
203
 
197
204
  // JSX className attributes with single quotes: <div className='bg-blue-500 text-white'>
198
205
  "<[^>]*?\\sclassName\\s*=\\s*'([^']+)'",
199
206
 
200
207
  // JSX className with braces and double quotes: <div className={"bg-blue-500 text-white"}>
201
- "<[^>]*?\\sclassName\\s*=\\s*\\{\\s*\"([^\"]+)\"\\s*\\}",
208
+ '<[^>]*?\\sclassName\\s*=\\s*\\{\\s*"([^"]+)"\\s*\\}',
202
209
 
203
210
  // JSX className with braces and single quotes: <div className={'bg-blue-500 text-white'}>
204
211
  "<[^>]*?\\sclassName\\s*=\\s*\\{\\s*'([^']+)'\\s*\\}",
@@ -210,19 +217,19 @@ const CLASS_NAME_PATTERNS = [
210
217
  "<[^>]*?\\sclass\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
211
218
 
212
219
  // HTML class at start of tag with double quotes: <div class="bg-blue-500">
213
- "<\\w+\\s+class\\s*=\\s*\"([^\"]+)\"",
220
+ '<\\w+\\s+class\\s*=\\s*"([^"]+)"',
214
221
 
215
222
  // HTML class at start of tag with single quotes: <div class='bg-blue-500'>
216
223
  "<\\w+\\s+class\\s*=\\s*'([^']+)'",
217
224
 
218
225
  // JSX className at start of tag with double quotes: <div className="bg-blue-500">
219
- "<\\w+\\s+className\\s*=\\s*\"([^\"]+)\"",
226
+ '<\\w+\\s+className\\s*=\\s*"([^"]+)"',
220
227
 
221
228
  // JSX className at start of tag with single quotes: <div className='bg-blue-500'>
222
229
  "<\\w+\\s+className\\s*=\\s*'([^']+)'",
223
230
 
224
231
  // JSX className at start with braces and double quotes: <div className={"bg-blue-500"}>
225
- "<\\w+\\s+className\\s*=\\s*\\{\\s*\"([^\"]+)\"\\s*\\}",
232
+ '<\\w+\\s+className\\s*=\\s*\\{\\s*"([^"]+)"\\s*\\}',
226
233
 
227
234
  // JSX className at start with braces and single quotes: <div className={'bg-blue-500'}>
228
235
  "<\\w+\\s+className\\s*=\\s*\\{\\s*'([^']+)'\\s*\\}",
@@ -235,7 +242,7 @@ const CLASS_NAME_PATTERNS = [
235
242
  ]
236
243
 
237
244
  const CLASS_NAME_REGEX = new RegExp(
238
- CLASS_NAME_PATTERNS.map(pattern => `(?:${pattern})`).join("|"),
245
+ CLASS_NAME_PATTERNS.map((pattern) => `(?:${pattern})`).join("|"),
239
246
  "g",
240
247
  )
241
248
 
@@ -244,8 +251,7 @@ function hasCssImport(css: string, specifier?: string): boolean {
244
251
 
245
252
  if (!importPath) return false
246
253
 
247
- return specifier === undefined
248
- || importPath.includes(specifier)
254
+ return specifier === undefined || importPath.includes(specifier)
249
255
  }
250
256
 
251
257
  export function extractClassNames(source: string): Set<string> {
@@ -270,17 +276,20 @@ export function extractClassNames(source: string): Set<string> {
270
276
  const staticParts = classString.split(TEMPLATE_EXPRESSION_REGEX)
271
277
 
272
278
  for (const part of staticParts) {
273
- const names = part.trim().split(/\s+/).filter(name => {
274
- if (name.length === 0) return false
275
- if (name.endsWith("-") || name.startsWith("-")) return false
276
- return TAILWIND_CLASS_REGEX.test(name)
277
- })
278
- names.forEach(name => candidates.add(name))
279
+ const names = part
280
+ .trim()
281
+ .split(/\s+/)
282
+ .filter((name) => {
283
+ if (name.length === 0) return false
284
+ if (name.endsWith("-") || name.startsWith("-")) return false
285
+ return TAILWIND_CLASS_REGEX.test(name)
286
+ })
287
+ names.forEach((name) => candidates.add(name))
279
288
  }
280
289
  } else {
281
290
  // Simple case: regular class string without expressions
282
- const names = classString.split(/\s+/).filter(name => name.length > 0)
283
- names.forEach(name => candidates.add(name))
291
+ const names = classString.split(/\s+/).filter((name) => name.length > 0)
292
+ names.forEach((name) => candidates.add(name))
284
293
  }
285
294
  }
286
295
 
@@ -291,12 +300,10 @@ async function scanFiles(dir: string): Promise<Set<string>> {
291
300
  const candidates = new Set<string>()
292
301
  const glob = new Bun.Glob("**/*.{js,jsx,ts,tsx,html,vue,svelte,astro}")
293
302
 
294
- for await (
295
- const filePath of glob.scan({
296
- cwd: dir,
297
- absolute: true,
298
- })
299
- ) {
303
+ for await (const filePath of glob.scan({
304
+ cwd: dir,
305
+ absolute: true,
306
+ })) {
300
307
  if (filePath.includes("/node_modules/")) {
301
308
  continue
302
309
  }
@@ -1,25 +1,14 @@
1
1
  import fsPromises from "node:fs/promises"
2
2
  import path from "node:path"
3
3
  import { pathToFileURL } from "node:url"
4
- import {
5
- compile as _compile,
6
- compileAst as _compileAst,
7
- Features,
8
- Polyfills,
9
- } from "tailwindcss"
4
+ import { compile as _compile, compileAst as _compileAst, Features, Polyfills } from "tailwindcss"
10
5
  import * as BunEnhancedResolve from "../../bun/_BunEnhancedResolve"
11
6
 
12
7
  type AstNode = Parameters<typeof _compileAst>[0][number]
13
8
 
14
- export {
15
- Features,
16
- Polyfills,
17
- }
9
+ export { Features, Polyfills }
18
10
 
19
- export type Resolver = (
20
- id: string,
21
- base: string,
22
- ) => Promise<string | false | undefined>
11
+ export type Resolver = (id: string, base: string) => Promise<string | false | undefined>
23
12
 
24
13
  export interface CompileOptions {
25
14
  base: string
@@ -48,12 +37,7 @@ function createCompileOptions({
48
37
  return loadModule(id, base, onDependency, customJsResolver)
49
38
  },
50
39
  async loadStylesheet(id: string, sheetBase: string) {
51
- let sheet = await loadStylesheet(
52
- id,
53
- sheetBase,
54
- onDependency,
55
- customCssResolver,
56
- )
40
+ let sheet = await loadStylesheet(id, sheetBase, onDependency, customCssResolver)
57
41
 
58
42
  return sheet
59
43
  },
@@ -66,7 +50,7 @@ async function ensureSourceDetectionRootExists(compiler: {
66
50
  // Verify if the `source(…)` path exists (until the glob pattern starts)
67
51
  if (compiler.root && compiler.root !== "none") {
68
52
  let globSymbols = /[*{]/
69
- let basePath: string[] = []
53
+ let basePath: Array<string> = []
70
54
  for (let segment of compiler.root.pattern.split("/")) {
71
55
  if (globSymbols.test(segment)) {
72
56
  break
@@ -89,7 +73,7 @@ async function ensureSourceDetectionRootExists(compiler: {
89
73
  }
90
74
 
91
75
  export async function compileAst(
92
- ast: AstNode[],
76
+ ast: Array<AstNode>,
93
77
  options: CompileOptions,
94
78
  ): ReturnType<typeof _compileAst> {
95
79
  let compiler = await _compileAst(ast, createCompileOptions(options))
@@ -97,10 +81,7 @@ export async function compileAst(
97
81
  return compiler
98
82
  }
99
83
 
100
- export async function compile(
101
- css: string,
102
- options: CompileOptions,
103
- ): ReturnType<typeof _compile> {
84
+ export async function compile(css: string, options: CompileOptions): ReturnType<typeof _compile> {
104
85
  let compiler = await _compile(css, createCompileOptions(options))
105
86
  await ensureSourceDetectionRootExists(compiler)
106
87
  return compiler
@@ -131,9 +112,7 @@ export async function loadModule(
131
112
  throw new Error(`Could not resolve '${id}' from '${base}'`)
132
113
  }
133
114
 
134
- let [module] = await Promise.all([
135
- importModule(pathToFileURL(resolvedPath).href + "?id=" + Date.now()),
136
- ])
115
+ let module = await importModule(pathToFileURL(resolvedPath).href + "?id=" + Date.now())
137
116
 
138
117
  return {
139
118
  path: resolvedPath,
@@ -230,9 +209,7 @@ async function resolveJsId(
230
209
  }
231
210
  }
232
211
 
233
- return runResolver(esmResolver, id, base).catch(() =>
234
- runResolver(cjsResolver, id, base)
235
- )
212
+ return runResolver(esmResolver, id, base).catch(() => runResolver(cjsResolver, id, base))
236
213
  }
237
214
 
238
215
  function runResolver(
@@ -244,6 +221,6 @@ function runResolver(
244
221
  resolver.resolve({}, base, id, {}, (err, result) => {
245
222
  if (err) return reject(err)
246
223
  resolve(result)
247
- })
224
+ }),
248
225
  )
249
226
  }
@@ -8,8 +8,8 @@ const packageJson = await NodeUtils.findClosestPackageJson(process.cwd())
8
8
  const scanPath = dirParam
9
9
  ? NPath.resolve(process.cwd(), dirParam)
10
10
  : packageJson
11
- ? NPath.dirname(packageJson)
12
- : process.cwd()
11
+ ? NPath.dirname(packageJson)
12
+ : process.cwd()
13
13
 
14
14
  // Export as default to be used in bunfig.toml
15
15
  export default TailwindPlugin.make({