effect-start 0.32.0 → 0.34.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/dist/Entity.d.ts +6 -1
- package/dist/Entity.d.ts.map +1 -1
- package/dist/Entity.js +43 -5
- package/dist/Entity.js.map +1 -1
- package/dist/Fetch.js.map +1 -1
- package/dist/FileRouterCodegen.js +2 -2
- package/dist/FileRouterCodegen.js.map +1 -1
- package/dist/Html.d.ts +5 -11
- package/dist/Html.d.ts.map +1 -1
- package/dist/Html.js +21 -1
- package/dist/Html.js.map +1 -1
- package/dist/KeyValueStore.d.ts +37 -0
- package/dist/KeyValueStore.d.ts.map +1 -0
- package/dist/KeyValueStore.js +99 -0
- package/dist/KeyValueStore.js.map +1 -0
- package/dist/Route.d.ts +2 -2
- package/dist/Route.d.ts.map +1 -1
- package/dist/Route.js +1 -1
- package/dist/Route.js.map +1 -1
- package/dist/RouteBody.d.ts +2 -2
- package/dist/RouteBody.d.ts.map +1 -1
- package/dist/RouteHttp.d.ts.map +1 -1
- package/dist/RouteHttp.js +45 -35
- package/dist/RouteHttp.js.map +1 -1
- package/dist/RouteMount.d.ts +20 -31
- package/dist/RouteMount.d.ts.map +1 -1
- package/dist/RouteMount.js +0 -15
- package/dist/RouteMount.js.map +1 -1
- package/dist/Start.d.ts.map +1 -1
- package/dist/Start.js +4 -0
- package/dist/Start.js.map +1 -1
- package/dist/StaticFiles.d.ts +2 -2
- package/dist/StaticFiles.d.ts.map +1 -1
- package/dist/StaticFiles.js +7 -8
- package/dist/StaticFiles.js.map +1 -1
- package/dist/bun/BunRoute.d.ts.map +1 -1
- package/dist/bun/BunRoute.js +90 -78
- package/dist/bun/BunRoute.js.map +1 -1
- package/dist/bun/BunServer.d.ts +1 -1
- package/dist/bun/BunServer.d.ts.map +1 -1
- package/dist/bun/BunServer.js +8 -1
- package/dist/bun/BunServer.js.map +1 -1
- package/dist/bundler/BundleRoute.d.ts +4 -4
- package/dist/bundler/BundleRoute.d.ts.map +1 -1
- package/dist/datastar/attributes/computed.js +3 -3
- package/dist/datastar/attributes/computed.js.map +1 -1
- package/dist/datastar/attributes/on.js +11 -36
- package/dist/datastar/attributes/on.js.map +1 -1
- package/dist/datastar/engine.d.ts +9 -7
- package/dist/datastar/engine.d.ts.map +1 -1
- package/dist/datastar/engine.js +45 -29
- package/dist/datastar/engine.js.map +1 -1
- package/dist/datastar/jsx.d.ts +70 -0
- package/dist/datastar/jsx.d.ts.map +1 -0
- package/dist/datastar/jsx.js +2 -0
- package/dist/datastar/jsx.js.map +1 -0
- package/dist/datastar/window.d.ts +8 -0
- package/dist/datastar/window.d.ts.map +1 -0
- package/dist/datastar/window.js +4 -0
- package/dist/datastar/window.js.map +1 -0
- package/dist/experimental/KeyValueStore.d.ts +37 -0
- package/dist/experimental/KeyValueStore.d.ts.map +1 -0
- package/dist/experimental/KeyValueStore.js +99 -0
- package/dist/experimental/KeyValueStore.js.map +1 -0
- package/dist/experimental/SqlCache.d.ts +19 -0
- package/dist/experimental/SqlCache.d.ts.map +1 -0
- package/dist/experimental/SqlCache.js +35 -0
- package/dist/experimental/SqlCache.js.map +1 -0
- package/dist/experimental/SqlIntrospect.d.ts +92 -0
- package/dist/experimental/SqlIntrospect.d.ts.map +1 -0
- package/dist/experimental/SqlIntrospect.js +478 -0
- package/dist/experimental/SqlIntrospect.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.d.ts +2 -2
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx.d.ts +3216 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/jsx.js +6 -0
- package/dist/jsx.js.map +1 -0
- package/dist/lint/plugin.d.ts +4 -3
- package/dist/lint/plugin.js +56 -17
- package/dist/lint/plugin.js.map +1 -1
- package/dist/sql/index.d.ts +0 -2
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js +0 -2
- package/dist/sql/index.js.map +1 -1
- package/dist/studio/StudioLogger.d.ts.map +1 -1
- package/dist/studio/StudioLogger.js +2 -1
- package/dist/studio/StudioLogger.js.map +1 -1
- package/dist/studio/StudioStore.d.ts +3 -0
- package/dist/studio/StudioStore.d.ts.map +1 -1
- package/dist/studio/StudioStore.js +13 -0
- package/dist/studio/StudioStore.js.map +1 -1
- package/dist/studio/_Pretty.d.ts +4 -0
- package/dist/studio/_Pretty.d.ts.map +1 -0
- package/dist/studio/_Pretty.js +56 -0
- package/dist/studio/_Pretty.js.map +1 -0
- package/dist/studio/routes/errors/route.d.ts +2 -2
- package/dist/studio/routes/fiberDetail.d.ts +2 -2
- package/dist/studio/routes/fibers/route.d.ts +2 -2
- package/dist/studio/routes/layout.d.ts +2 -0
- package/dist/studio/routes/layout.d.ts.map +1 -1
- package/dist/studio/routes/layout.html +3 -12
- package/dist/studio/routes/layout.js +6 -1
- package/dist/studio/routes/layout.js.map +1 -1
- package/dist/studio/routes/logs/route.d.ts +2 -2
- package/dist/studio/routes/metrics/route.d.ts +2 -2
- package/dist/studio/routes/route.d.ts +2 -2
- package/dist/studio/routes/routes/route.d.ts +2 -2
- package/dist/studio/routes/services/route.d.ts +2 -2
- package/dist/studio/routes/system/route.d.ts +2 -2
- package/dist/studio/routes/traceDetail.d.ts +2 -2
- package/dist/studio/routes/traces/route.d.ts +2 -2
- package/dist/studio/routes/traces/route.d.ts.map +1 -1
- package/dist/studio/routes/traces/route.js +5 -2
- package/dist/studio/routes/traces/route.js.map +1 -1
- package/dist/studio/routes/tree.d.ts +22 -0
- package/dist/studio/routes/tree.d.ts.map +1 -1
- package/dist/studio/ui/Errors.d.ts +1 -1
- package/dist/studio/ui/Errors.js +1 -1
- package/dist/studio/ui/Errors.js.map +1 -1
- package/dist/studio/ui/Fibers.d.ts +2 -2
- package/dist/studio/ui/Fibers.d.ts.map +1 -1
- package/dist/studio/ui/Fibers.js +4 -3
- package/dist/studio/ui/Fibers.js.map +1 -1
- package/dist/studio/ui/Logs.d.ts +1 -1
- package/dist/studio/ui/Logs.d.ts.map +1 -1
- package/dist/studio/ui/Logs.js +2 -1
- package/dist/studio/ui/Logs.js.map +1 -1
- package/dist/studio/ui/Metrics.d.ts +1 -1
- package/dist/studio/ui/Routes.d.ts +1 -1
- package/dist/studio/ui/Routes.d.ts.map +1 -1
- package/dist/studio/ui/Services.d.ts +1 -1
- package/dist/studio/ui/Services.d.ts.map +1 -1
- package/dist/studio/ui/Shell.d.ts +2 -2
- package/dist/studio/ui/Shell.d.ts.map +1 -1
- package/dist/studio/ui/System.d.ts +1 -1
- package/dist/studio/ui/Traces.d.ts +3 -3
- package/dist/studio/ui/Traces.d.ts.map +1 -1
- package/dist/studio/ui/Traces.js +5 -11
- package/dist/studio/ui/Traces.js.map +1 -1
- package/dist/studio/ui/_PrettyValue.d.ts +10 -0
- package/dist/studio/ui/_PrettyValue.d.ts.map +1 -0
- package/dist/studio/ui/_PrettyValue.js +27 -0
- package/dist/studio/ui/_PrettyValue.js.map +1 -0
- package/dist/tailwind/TailwindPlugin.d.ts.map +1 -1
- package/dist/tailwind/TailwindPlugin.js +89 -62
- package/dist/tailwind/TailwindPlugin.js.map +1 -1
- package/dist/ts/import-plugin.cjs +388 -0
- package/dist/ts/import-plugin.cjs.map +1 -0
- package/dist/ts/import-plugin.d.cts +87 -0
- package/dist/ts/import-plugin.d.cts.map +1 -0
- package/dist/ts/import-plugin.d.ts +87 -0
- package/dist/ts/import-plugin.d.ts.map +1 -0
- package/dist/ts/import-plugin.js +390 -0
- package/dist/ts/import-plugin.js.map +1 -0
- package/package.json +109 -8
- package/src/Entity.ts +62 -8
- package/src/Fetch.ts +1 -1
- package/src/FileRouterCodegen.ts +2 -2
- package/src/Html.ts +28 -21
- package/src/Route.ts +2 -2
- package/src/RouteBody.ts +2 -2
- package/src/RouteHttp.ts +45 -47
- package/src/RouteMount.ts +23 -65
- package/src/Start.ts +4 -0
- package/src/StaticFiles.ts +7 -10
- package/src/bun/BunRoute.ts +117 -95
- package/src/bun/BunServer.ts +9 -2
- package/src/datastar/README.md +24 -8
- package/src/datastar/attributes/computed.ts +3 -3
- package/src/datastar/attributes/on.ts +11 -37
- package/src/datastar/engine.ts +61 -37
- package/src/datastar/jsx.d.ts +12 -26
- package/src/datastar/types.d.ts +8 -0
- package/src/experimental/KeyValueStore.ts +161 -0
- package/src/{sql → experimental}/SqlCache.ts +1 -1
- package/src/{sql → experimental}/SqlIntrospect.ts +1 -1
- package/src/index.ts +1 -0
- package/src/jsx-runtime.ts +1 -1
- package/src/jsx.d.ts +17 -2
- package/src/lint/plugin.js +54 -19
- package/src/sql/index.ts +0 -2
- package/src/studio/StudioLogger.ts +2 -1
- package/src/studio/StudioStore.ts +18 -0
- package/src/studio/_Pretty.ts +59 -0
- package/src/studio/routes/layout.html +3 -12
- package/src/studio/routes/layout.tsx +9 -1
- package/src/studio/routes/traces/route.tsx +5 -1
- package/src/studio/ui/Errors.tsx +1 -1
- package/src/studio/ui/Fibers.tsx +14 -10
- package/src/studio/ui/Logs.tsx +15 -10
- package/src/studio/ui/Traces.tsx +40 -68
- package/src/studio/ui/_PrettyValue.tsx +34 -0
- package/src/tailwind/TailwindPlugin.ts +102 -75
- package/src/RouteTrie.ts +0 -205
- package/src/experimental/index.ts +0 -1
package/src/bun/BunRoute.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as Bun from "bun"
|
|
2
|
-
import * as NPath from "node:path"
|
|
3
2
|
import * as Data from "effect/Data"
|
|
4
3
|
import * as Either from "effect/Either"
|
|
5
4
|
import * as Effect from "effect/Effect"
|
|
@@ -87,54 +86,21 @@ export function htmlBundle(load: () => HTMLBundleModule | Promise<HTMLBundleModu
|
|
|
87
86
|
let status = 200
|
|
88
87
|
let contentType = "text/html;charset=utf-8"
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const response = yield* Effect.tryPromise({
|
|
106
|
-
try: () => fetch(proxyRequest),
|
|
107
|
-
catch: (error) =>
|
|
108
|
-
new BunRouteError({
|
|
109
|
-
reason: "ProxyError",
|
|
110
|
-
pattern: internalPath,
|
|
111
|
-
message: `Failed to fetch internal HTML bundle: ${String(error)}`,
|
|
112
|
-
}),
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
html = yield* Effect.tryPromise({
|
|
116
|
-
try: () => response.text(),
|
|
117
|
-
catch: (error) =>
|
|
118
|
-
new BunRouteError({
|
|
119
|
-
reason: "ProxyError",
|
|
120
|
-
pattern: internalPath,
|
|
121
|
-
message: String(error),
|
|
122
|
-
}),
|
|
123
|
-
})
|
|
124
|
-
status = response.status
|
|
125
|
-
contentType = response.headers.get("content-type") ?? contentType
|
|
126
|
-
} else {
|
|
127
|
-
html = yield* readBundleHtml(bunLoad).pipe(
|
|
128
|
-
Effect.mapError(
|
|
129
|
-
(error) =>
|
|
130
|
-
new BunRouteError({
|
|
131
|
-
reason: "ProxyError",
|
|
132
|
-
pattern: bunPrefix,
|
|
133
|
-
message: `Failed to load nested HTML bundle: ${String(error)}`,
|
|
134
|
-
}),
|
|
135
|
-
),
|
|
136
|
-
)
|
|
137
|
-
}
|
|
89
|
+
const response = yield* fetchBundleResponse(
|
|
90
|
+
bunPrefix,
|
|
91
|
+
originalRequest,
|
|
92
|
+
)
|
|
93
|
+
html = yield* Effect.tryPromise({
|
|
94
|
+
try: () => response.text(),
|
|
95
|
+
catch: (error) =>
|
|
96
|
+
new BunRouteError({
|
|
97
|
+
reason: "ProxyError",
|
|
98
|
+
pattern: bunPrefix,
|
|
99
|
+
message: String(error),
|
|
100
|
+
}),
|
|
101
|
+
})
|
|
102
|
+
status = response.status
|
|
103
|
+
contentType = response.headers.get("content-type") ?? contentType
|
|
138
104
|
|
|
139
105
|
const childEntity = yield* next(context).pipe(
|
|
140
106
|
Effect.locally(bundleDepthRef, bundleDepth + 1),
|
|
@@ -162,7 +128,7 @@ export function htmlBundle(load: () => HTMLBundleModule | Promise<HTMLBundleModu
|
|
|
162
128
|
}
|
|
163
129
|
}
|
|
164
130
|
|
|
165
|
-
childrenHtml = yield*
|
|
131
|
+
childrenHtml = yield* stripDuplicateBunScripts(html, childrenHtml)
|
|
166
132
|
|
|
167
133
|
html = html.replaceAll("%children%", childrenHtml)
|
|
168
134
|
|
|
@@ -186,60 +152,82 @@ export function htmlBundle(load: () => HTMLBundleModule | Promise<HTMLBundleModu
|
|
|
186
152
|
}
|
|
187
153
|
}
|
|
188
154
|
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
155
|
+
function fetchBundleResponse(
|
|
156
|
+
bunPrefix: string,
|
|
157
|
+
originalRequest: Request,
|
|
158
|
+
) {
|
|
159
|
+
return Effect.gen(function* () {
|
|
160
|
+
const bunServer = yield* BunServer.BunServer
|
|
161
|
+
const url = new URL(originalRequest.url)
|
|
162
|
+
const internalUrl = new URL(bunServer.server.url)
|
|
163
|
+
|
|
164
|
+
internalUrl.pathname = `${bunPrefix}${url.pathname}`
|
|
165
|
+
internalUrl.search = url.search
|
|
166
|
+
|
|
167
|
+
const headers = new Headers(originalRequest.headers)
|
|
168
|
+
headers.set(INTERNAL_FETCH_HEADER, "true")
|
|
169
|
+
|
|
170
|
+
const proxyRequest = new Request(internalUrl, {
|
|
171
|
+
method: originalRequest.method,
|
|
172
|
+
headers,
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
return yield* Effect.tryPromise({
|
|
176
|
+
try: () => fetch(proxyRequest),
|
|
177
|
+
catch: (error) =>
|
|
178
|
+
new BunRouteError({
|
|
179
|
+
reason: "ProxyError",
|
|
180
|
+
pattern: internalUrl.pathname,
|
|
181
|
+
message: `Failed to fetch internal HTML bundle: ${String(error)}`,
|
|
182
|
+
}),
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
}
|
|
201
186
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
187
|
+
function stripDuplicateBunScripts(parentHtml: string, childHtml: string) {
|
|
188
|
+
return getInjectedBunScriptSrcs(parentHtml).pipe(
|
|
189
|
+
Effect.flatMap((parentScriptSrcs) => {
|
|
190
|
+
if (parentScriptSrcs.size === 0) {
|
|
191
|
+
return Effect.succeed(childHtml)
|
|
206
192
|
}
|
|
207
193
|
|
|
208
|
-
removeNextInlineScript = false
|
|
209
|
-
|
|
210
|
-
|
|
194
|
+
let removeNextInlineScript = false
|
|
195
|
+
const rewriter = new HTMLRewriter().on("script", {
|
|
196
|
+
element(element) {
|
|
197
|
+
const src = element.getAttribute("src")
|
|
198
|
+
const hasDevAttribute = element.hasAttribute("data-bun-dev-server-script")
|
|
211
199
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
200
|
+
if (src !== null && hasDevAttribute && parentScriptSrcs.has(src)) {
|
|
201
|
+
element.remove()
|
|
202
|
+
removeNextInlineScript = true
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (removeNextInlineScript && src === null) {
|
|
207
|
+
element.remove()
|
|
208
|
+
removeNextInlineScript = false
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
removeNextInlineScript = false
|
|
213
|
+
},
|
|
214
|
+
})
|
|
222
215
|
|
|
223
|
-
function readBundleHtml(bunLoad: () => Promise<Bun.HTMLBundle>) {
|
|
224
|
-
return Effect.tryPromise({
|
|
225
|
-
try: () => bunLoad(),
|
|
226
|
-
catch: (error) =>
|
|
227
|
-
new BunRouteError({
|
|
228
|
-
reason: "ProxyError",
|
|
229
|
-
pattern: "readBundleHtml",
|
|
230
|
-
message: String(error),
|
|
231
|
-
}),
|
|
232
|
-
}).pipe(
|
|
233
|
-
Effect.andThen((bundle) => {
|
|
234
|
-
const indexPath = NPath.isAbsolute(bundle.index)
|
|
235
|
-
? bundle.index
|
|
236
|
-
: NPath.resolve(NPath.dirname(Bun.main), bundle.index)
|
|
237
216
|
return Effect.tryPromise({
|
|
238
|
-
try: () =>
|
|
217
|
+
try: () =>
|
|
218
|
+
rewriter
|
|
219
|
+
.transform(
|
|
220
|
+
new Response(childHtml, {
|
|
221
|
+
headers: {
|
|
222
|
+
"content-type": "text/html;charset=utf-8",
|
|
223
|
+
},
|
|
224
|
+
}),
|
|
225
|
+
)
|
|
226
|
+
.text(),
|
|
239
227
|
catch: (error) =>
|
|
240
228
|
new BunRouteError({
|
|
241
229
|
reason: "ProxyError",
|
|
242
|
-
pattern:
|
|
230
|
+
pattern: "stripDuplicateBunScripts",
|
|
243
231
|
message: String(error),
|
|
244
232
|
}),
|
|
245
233
|
})
|
|
@@ -247,6 +235,40 @@ function readBundleHtml(bunLoad: () => Promise<Bun.HTMLBundle>) {
|
|
|
247
235
|
)
|
|
248
236
|
}
|
|
249
237
|
|
|
238
|
+
function getInjectedBunScriptSrcs(html: string) {
|
|
239
|
+
return Effect.tryPromise({
|
|
240
|
+
try: async () => {
|
|
241
|
+
const srcs = new Set<string>()
|
|
242
|
+
const rewriter = new HTMLRewriter().on("script", {
|
|
243
|
+
element(element) {
|
|
244
|
+
const src = element.getAttribute("src")
|
|
245
|
+
if (src !== null && element.hasAttribute("data-bun-dev-server-script")) {
|
|
246
|
+
srcs.add(src)
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
await rewriter
|
|
252
|
+
.transform(
|
|
253
|
+
new Response(html, {
|
|
254
|
+
headers: {
|
|
255
|
+
"content-type": "text/html;charset=utf-8",
|
|
256
|
+
},
|
|
257
|
+
}),
|
|
258
|
+
)
|
|
259
|
+
.text()
|
|
260
|
+
|
|
261
|
+
return srcs
|
|
262
|
+
},
|
|
263
|
+
catch: (error) =>
|
|
264
|
+
new BunRouteError({
|
|
265
|
+
reason: "ProxyError",
|
|
266
|
+
pattern: "getInjectedBunScriptSrcs",
|
|
267
|
+
message: String(error),
|
|
268
|
+
}),
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
|
|
250
272
|
type BunServerFetchHandler = (
|
|
251
273
|
request: Request,
|
|
252
274
|
server: Bun.Server<unknown>,
|
package/src/bun/BunServer.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as Deferred from "effect/Deferred"
|
|
|
6
6
|
import * as Effect from "effect/Effect"
|
|
7
7
|
import * as Exit from "effect/Exit"
|
|
8
8
|
import * as Layer from "effect/Layer"
|
|
9
|
+
import * as MutableRef from "effect/MutableRef"
|
|
9
10
|
import * as Option from "effect/Option"
|
|
10
11
|
import * as Runtime from "effect/Runtime"
|
|
11
12
|
import type * as Scope from "effect/Scope"
|
|
@@ -43,7 +44,7 @@ interface BunServeOptions {
|
|
|
43
44
|
readonly reusePort?: boolean
|
|
44
45
|
readonly ipv6Only?: boolean
|
|
45
46
|
readonly idleTimeout?: number
|
|
46
|
-
readonly development?:
|
|
47
|
+
readonly development?: Bun.Serve.Development
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
export type BunServer = {
|
|
@@ -145,9 +146,15 @@ export const make = (
|
|
|
145
146
|
// @ts-expect-error
|
|
146
147
|
service.server = server
|
|
147
148
|
|
|
149
|
+
const myFiber = MutableRef.get(PlatformRuntime.mainFiber)
|
|
148
150
|
yield* Effect.addFinalizer(() =>
|
|
149
151
|
Effect.sync(() => {
|
|
150
|
-
server
|
|
152
|
+
// Only stop the server on real shutdown; and not on hot reloads
|
|
153
|
+
// when Bun.serve automatically swaps routes without restarting the server
|
|
154
|
+
const currentMain = MutableRef.get(PlatformRuntime.mainFiber)
|
|
155
|
+
if (currentMain === myFiber) {
|
|
156
|
+
server.stop()
|
|
157
|
+
}
|
|
151
158
|
}),
|
|
152
159
|
)
|
|
153
160
|
|
package/src/datastar/README.md
CHANGED
|
@@ -9,15 +9,31 @@ We can probably cut it down by another ~10kb if we remove DataStar expression an
|
|
|
9
9
|
We made following changes:
|
|
10
10
|
|
|
11
11
|
- Path aliases converted to relative imports: `@engine/*` → `./engine/*`, etc.
|
|
12
|
-
- Flattened
|
|
13
|
-
-
|
|
14
|
-
|
|
12
|
+
- Flattened and merged the source tree:
|
|
13
|
+
- `plugins/actions|attributes|watchers` → `actions|attributes|watchers`
|
|
14
|
+
- `engine/{consts,types,signals,engine}.ts` → `engine.ts`
|
|
15
|
+
- `utils/{dom,math,paths,polyfills,tags,text,timing,view-transitions}.ts` → `utils.ts`
|
|
16
|
+
- Replaced upstream `bundles/` entrypoints with local `index.ts`:
|
|
17
|
+
- Registers all plugins as side effects
|
|
18
|
+
- Re-exports all of `engine.ts` instead of upstream's narrower bundle export surface
|
|
19
|
+
- Removed alias build support:
|
|
20
|
+
- Deleted `globals.d.ts`
|
|
21
|
+
- `aliasify()` always produces `data-${name}`
|
|
22
|
+
- `applyAttributePlugin` no longer accepts aliased `data-${ALIAS}-*` attributes
|
|
15
23
|
- Removed plugin header comments.
|
|
16
24
|
- Updated type declaration to conform to `erasableSyntaxOnly`:
|
|
17
25
|
- Converted `enum ReactiveFlags` and `enum EffectFlags` to `const` objects with `as const`
|
|
18
26
|
- Added type aliases `ReactiveFlags_X` to replace `ReactiveFlags.X` namespace types
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- Function
|
|
22
|
-
-
|
|
23
|
-
-
|
|
27
|
+
- Extended expressions with function form handled by `genRx`:
|
|
28
|
+
- Function expressions are evaluated directly instead of compiled through Datastar's string-expression transform
|
|
29
|
+
- Function expressions receive a `DataEvent` object with `signals`, `actions`, `target`, and `window`
|
|
30
|
+
- Shared expression-event setup is centralized in `createDataEvent()` and reused by both `genRx` and `data-computed`
|
|
31
|
+
- Value-returning object literals are compiled as `return ({...});` so block-bodied arrow functions inside object expressions still parse
|
|
32
|
+
- `data-computed` supports object values with function leaves:
|
|
33
|
+
- String/object-literal form still works: `data-computed="{statusText: (e) => e.signals.state}"`
|
|
34
|
+
- JSX object form also works: `data-computed={{ statusText: (e) => e.signals.state }}`
|
|
35
|
+
- Object values only accept functions at the leaves
|
|
36
|
+
- JSX typing allows `data-computed` object values
|
|
37
|
+
- `data-on` supports function form:
|
|
38
|
+
- Function form: `data-on:click="(e) => { e.signals.count = e.signals.count + 1 }"`
|
|
39
|
+
- Event names are used literally from the attribute key; upstream `modifyCasing(..., "kebab")` normalization is no longer applied
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attribute, computed, mergePatch, mergePaths } from "../engine.ts"
|
|
1
|
+
import { attribute, computed, createDataEvent, mergePatch, mergePaths } from "../engine.ts"
|
|
2
2
|
import { modifyCasing, updateLeaves } from "../utils.ts"
|
|
3
3
|
|
|
4
4
|
attribute({
|
|
@@ -7,14 +7,14 @@ attribute({
|
|
|
7
7
|
value: "must",
|
|
8
8
|
},
|
|
9
9
|
returnsValue: true,
|
|
10
|
-
apply({ key, mods, rx, error }) {
|
|
10
|
+
apply({ el, key, mods, rx, error }) {
|
|
11
11
|
if (key) {
|
|
12
12
|
mergePaths([[modifyCasing(key, mods), computed(rx)]])
|
|
13
13
|
} else {
|
|
14
14
|
const patch = Object.assign({}, rx() as Record<string, () => any>)
|
|
15
15
|
updateLeaves(patch, (old) => {
|
|
16
16
|
if (typeof old === "function") {
|
|
17
|
-
return computed(old)
|
|
17
|
+
return computed(() => old(createDataEvent({ el, cleanups: new Map(), error: () => error })))
|
|
18
18
|
} else {
|
|
19
19
|
throw error("ComputedExpectedFunction")
|
|
20
20
|
}
|
|
@@ -4,59 +4,33 @@ import {
|
|
|
4
4
|
DATASTAR_FETCH_EVENT,
|
|
5
5
|
DATASTAR_SIGNAL_PATCH_EVENT,
|
|
6
6
|
endBatch,
|
|
7
|
-
type Modifiers,
|
|
8
7
|
} from "../engine.ts"
|
|
9
8
|
import { modifyTiming, modifyViewTransition } from "../utils.ts"
|
|
10
9
|
|
|
11
|
-
// TODO: support leading/trailing options for debounce/throttle
|
|
12
|
-
// e.g. { debounce: { ms: 500, leading: true, noTrailing: true } }
|
|
13
|
-
const configToMods = (config: Record<string, any>): Modifiers => {
|
|
14
|
-
const mods: Modifiers = new Map()
|
|
15
|
-
for (const [k, v] of Object.entries(config)) {
|
|
16
|
-
if (v === true) {
|
|
17
|
-
mods.set(k, new Set())
|
|
18
|
-
} else if (typeof v === "number") {
|
|
19
|
-
mods.set(k, new Set([`${v}ms`]))
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return mods
|
|
23
|
-
}
|
|
24
|
-
|
|
25
10
|
attribute({
|
|
26
11
|
name: "on",
|
|
27
12
|
requirement: "must",
|
|
28
13
|
argNames: ["evt"],
|
|
29
|
-
apply({ el, key, mods, rx
|
|
30
|
-
let userFn: Function | undefined
|
|
31
|
-
let effectiveMods = mods
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
const parts = Function(`return [${value}]`)()
|
|
35
|
-
if (typeof parts[0] === "function") {
|
|
36
|
-
userFn = parts[0]
|
|
37
|
-
if (parts[1]) effectiveMods = configToMods(parts[1])
|
|
38
|
-
}
|
|
39
|
-
} catch {}
|
|
40
|
-
|
|
14
|
+
apply({ el, key, mods, rx }) {
|
|
41
15
|
let target: Element | Window | Document = el
|
|
42
|
-
if (
|
|
16
|
+
if (mods.has("window")) target = window
|
|
43
17
|
let callback = (evt?: Event) => {
|
|
44
18
|
if (evt) {
|
|
45
|
-
if (
|
|
46
|
-
if (
|
|
19
|
+
if (mods.has("prevent")) evt.preventDefault()
|
|
20
|
+
if (mods.has("stop")) evt.stopPropagation()
|
|
47
21
|
}
|
|
48
22
|
beginBatch()
|
|
49
|
-
|
|
23
|
+
rx(evt)
|
|
50
24
|
endBatch()
|
|
51
25
|
}
|
|
52
|
-
callback = modifyViewTransition(callback,
|
|
53
|
-
callback = modifyTiming(callback,
|
|
26
|
+
callback = modifyViewTransition(callback, mods)
|
|
27
|
+
callback = modifyTiming(callback, mods)
|
|
54
28
|
const evtListOpts: AddEventListenerOptions = {
|
|
55
|
-
capture:
|
|
56
|
-
passive:
|
|
57
|
-
once:
|
|
29
|
+
capture: mods.has("capture"),
|
|
30
|
+
passive: mods.has("passive"),
|
|
31
|
+
once: mods.has("once"),
|
|
58
32
|
}
|
|
59
|
-
if (
|
|
33
|
+
if (mods.has("outside")) {
|
|
60
34
|
target = document
|
|
61
35
|
const cb = callback
|
|
62
36
|
callback = (evt?: Event) => {
|
package/src/datastar/engine.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DataEvent as _DataEvent, HTMLOrSVG as _HTMLOrSVG } from "./types.d.ts"
|
|
1
2
|
import { aliasify, hasOwn, isHTMLOrSVG, isPojo, pathToObj, snake } from "./utils.ts"
|
|
2
3
|
|
|
3
4
|
/*********
|
|
@@ -115,13 +116,42 @@ export type MergePatchArgs = {
|
|
|
115
116
|
ifMissing?: boolean
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
export type HTMLOrSVG =
|
|
119
|
+
export type HTMLOrSVG = _HTMLOrSVG
|
|
120
|
+
export type DataEvent = _DataEvent
|
|
119
121
|
|
|
120
|
-
export
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
export const createDataEvent = ({
|
|
123
|
+
el,
|
|
124
|
+
evt,
|
|
125
|
+
cleanups,
|
|
126
|
+
error,
|
|
127
|
+
}: {
|
|
128
|
+
el: HTMLOrSVG
|
|
129
|
+
evt?: Event
|
|
130
|
+
cleanups: Map<string, () => void>
|
|
131
|
+
error: (actionName: string) => ErrorFn
|
|
132
|
+
}): DataEvent => {
|
|
133
|
+
const actionsProxy = new Proxy({} as Record<string, any>, {
|
|
134
|
+
get:
|
|
135
|
+
(_, name: string) =>
|
|
136
|
+
(...actionArgs: Array<any>) => {
|
|
137
|
+
const err = error(name)
|
|
138
|
+
const fn = actions[name]
|
|
139
|
+
if (fn) {
|
|
140
|
+
return fn({ el, evt: undefined, error: err, cleanups }, ...actionArgs)
|
|
141
|
+
}
|
|
142
|
+
throw err("UndefinedAction")
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
const dataEvt = (evt instanceof Event ? evt : new Event("datastar:expression")) as DataEvent
|
|
147
|
+
Object.defineProperties(dataEvt, {
|
|
148
|
+
target: { value: el },
|
|
149
|
+
signals: { value: root },
|
|
150
|
+
actions: { value: actionsProxy },
|
|
151
|
+
window: { value: window },
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
return dataEvt
|
|
125
155
|
}
|
|
126
156
|
|
|
127
157
|
export type Modifiers = Map<string, Set<string>>
|
|
@@ -1092,6 +1122,7 @@ const applyAttributePlugin = (
|
|
|
1092
1122
|
const { pluginName, key, mods } = parseAttributeKey(rawKey)
|
|
1093
1123
|
const plugin = attributePlugins.get(pluginName)
|
|
1094
1124
|
if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {
|
|
1125
|
+
const cleanups = new Map<string, () => void>()
|
|
1095
1126
|
const ctx = {
|
|
1096
1127
|
el,
|
|
1097
1128
|
rawKey,
|
|
@@ -1147,7 +1178,6 @@ const applyAttributePlugin = (
|
|
|
1147
1178
|
}
|
|
1148
1179
|
}
|
|
1149
1180
|
|
|
1150
|
-
const cleanups = new Map<string, () => void>()
|
|
1151
1181
|
if (valueProvided) {
|
|
1152
1182
|
let cachedRx: GenRxFn
|
|
1153
1183
|
ctx.rx = (...args: Array<any>) => {
|
|
@@ -1199,27 +1229,16 @@ const genRx = (
|
|
|
1199
1229
|
const userFn = Function(`return (${value.trim()})`)()
|
|
1200
1230
|
|
|
1201
1231
|
return (el: HTMLOrSVG, ...args: Array<any>) => {
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
if (fn) return fn({ el, evt: undefined, error: err, cleanups }, ...actionArgs)
|
|
1213
|
-
throw err("UndefinedAction")
|
|
1214
|
-
},
|
|
1215
|
-
})
|
|
1216
|
-
|
|
1217
|
-
const dataEvt = args[0] instanceof Event ? args[0] : new Event("datastar:expression")
|
|
1218
|
-
Object.defineProperties(dataEvt, {
|
|
1219
|
-
target: { value: el },
|
|
1220
|
-
signals: { value: root },
|
|
1221
|
-
actions: { value: actionsProxy },
|
|
1222
|
-
window: { value: window },
|
|
1232
|
+
const dataEvt = createDataEvent({
|
|
1233
|
+
el,
|
|
1234
|
+
evt: args[0],
|
|
1235
|
+
cleanups,
|
|
1236
|
+
error: (name) =>
|
|
1237
|
+
error.bind(0, {
|
|
1238
|
+
plugin: { type: "action", name },
|
|
1239
|
+
element: { id: el.id, tag: el.tagName },
|
|
1240
|
+
expression: { fnContent: value, value },
|
|
1241
|
+
}),
|
|
1223
1242
|
})
|
|
1224
1243
|
|
|
1225
1244
|
try {
|
|
@@ -1240,16 +1259,21 @@ const genRx = (
|
|
|
1240
1259
|
|
|
1241
1260
|
let expr = ""
|
|
1242
1261
|
if (returnsValue) {
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1262
|
+
const trimmed = value.trim()
|
|
1263
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
1264
|
+
expr = `return (${trimmed});`
|
|
1265
|
+
} else {
|
|
1266
|
+
const statementRe =
|
|
1267
|
+
/(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm
|
|
1268
|
+
const statements = trimmed.match(statementRe)
|
|
1269
|
+
if (statements) {
|
|
1270
|
+
const lastIdx = statements.length - 1
|
|
1271
|
+
const last = statements[lastIdx].trim()
|
|
1272
|
+
if (!last.startsWith("return")) {
|
|
1273
|
+
statements[lastIdx] = `return (${last});`
|
|
1274
|
+
}
|
|
1275
|
+
expr = statements.join(";\n")
|
|
1251
1276
|
}
|
|
1252
|
-
expr = statements.join(";\n")
|
|
1253
1277
|
}
|
|
1254
1278
|
} else {
|
|
1255
1279
|
expr = value.trim()
|
package/src/datastar/jsx.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataEvent } from "./
|
|
1
|
+
import type { DataEvent } from "./types.d.ts"
|
|
2
2
|
|
|
3
3
|
// Datastar object types for specific attributes
|
|
4
4
|
type DatastarSignalsObject = Record<string, any>
|
|
@@ -8,21 +8,6 @@ type DatastarStyleObject = Record<string, string | number | boolean | null | und
|
|
|
8
8
|
|
|
9
9
|
type DatastarFn = (e: DataEvent) => any
|
|
10
10
|
|
|
11
|
-
// TODO: support leading/trailing options
|
|
12
|
-
// e.g. { debounce: { ms: 500, leading: true, noTrailing: true } }
|
|
13
|
-
type DatastarOnConfig = {
|
|
14
|
-
prevent?: boolean
|
|
15
|
-
stop?: boolean
|
|
16
|
-
capture?: boolean
|
|
17
|
-
passive?: boolean
|
|
18
|
-
once?: boolean
|
|
19
|
-
outside?: boolean
|
|
20
|
-
window?: boolean
|
|
21
|
-
viewTransition?: boolean
|
|
22
|
-
} & ({ debounce?: number; throttle?: never } | { debounce?: never; throttle?: number })
|
|
23
|
-
|
|
24
|
-
type DatastarOnFn = DatastarFn | [handler: DatastarFn, config: DatastarOnConfig]
|
|
25
|
-
|
|
26
11
|
/**
|
|
27
12
|
* Datastar attributes for reactive web applications
|
|
28
13
|
* @see https://data-star.dev/reference/attributes
|
|
@@ -41,15 +26,16 @@ export interface DatastarAttributes {
|
|
|
41
26
|
|
|
42
27
|
// Attributes that accept function expressions
|
|
43
28
|
"data-bind"?: string | undefined
|
|
44
|
-
"data-computed"?: string | DatastarFn | undefined
|
|
29
|
+
"data-computed"?: string | DatastarFn | Record<string, DatastarFn | Record<string, DatastarFn>> | undefined
|
|
45
30
|
"data-effect"?: string | DatastarFn | undefined
|
|
31
|
+
"data-init"?: string | DatastarFn | undefined
|
|
46
32
|
"data-indicator"?: string | undefined
|
|
47
|
-
"data-json-signals"?: string | undefined
|
|
48
|
-
"data-on"?: string |
|
|
49
|
-
"data-on-intersect"?: string |
|
|
50
|
-
"data-on-interval"?: string |
|
|
51
|
-
"data-on-load"?: string |
|
|
52
|
-
"data-on-signal-patch"?: string |
|
|
33
|
+
"data-json-signals"?: true | string | undefined
|
|
34
|
+
"data-on"?: string | DatastarFn | undefined
|
|
35
|
+
"data-on-intersect"?: string | DatastarFn | undefined
|
|
36
|
+
"data-on-interval"?: string | DatastarFn | undefined
|
|
37
|
+
"data-on-load"?: string | DatastarFn | undefined
|
|
38
|
+
"data-on-signal-patch"?: string | DatastarFn | undefined
|
|
53
39
|
"data-on-signal-patch-filter"?: string | undefined
|
|
54
40
|
"data-preserve-attr"?: string | undefined
|
|
55
41
|
"data-ref"?: string | undefined
|
|
@@ -58,8 +44,8 @@ export interface DatastarAttributes {
|
|
|
58
44
|
// Pro attributes
|
|
59
45
|
"data-animate"?: string | undefined
|
|
60
46
|
"data-custom-validity"?: string | DatastarFn | undefined
|
|
61
|
-
"data-on-raf"?: string |
|
|
62
|
-
"data-on-resize"?: string |
|
|
47
|
+
"data-on-raf"?: string | DatastarFn | undefined
|
|
48
|
+
"data-on-resize"?: string | DatastarFn | undefined
|
|
63
49
|
"data-persist"?: string | undefined
|
|
64
50
|
"data-query-string"?: string | undefined
|
|
65
51
|
"data-replace-url"?: string | undefined
|
|
@@ -75,5 +61,5 @@ export interface DatastarAttributes {
|
|
|
75
61
|
[key: `data-computed:${string}`]: string | DatastarFn | undefined
|
|
76
62
|
[key: `data-indicator:${string}`]: string | undefined
|
|
77
63
|
[key: `data-ref:${string}`]: string | undefined
|
|
78
|
-
[key: `data-on:${string}`]: string |
|
|
64
|
+
[key: `data-on:${string}`]: string | DatastarFn | undefined
|
|
79
65
|
}
|