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
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Based on {@link https://github.com/jshttp/negotiator}
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
interface ParsedSpec {
|
|
8
7
|
value: string
|
|
9
8
|
q: number
|
|
@@ -12,7 +11,7 @@ interface ParsedSpec {
|
|
|
12
11
|
i: number
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
const simpleMediaTypeRegExp = /^\s*([^\s
|
|
14
|
+
const simpleMediaTypeRegExp = /^\s*([^\s/;]+)\/([^;\s]+)\s*(?:;(.*))?$/
|
|
16
15
|
const simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/
|
|
17
16
|
const simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/
|
|
18
17
|
const simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/
|
|
@@ -25,9 +24,10 @@ function parseQuality(params: string | undefined): number {
|
|
|
25
24
|
return isNaN(q) ? 1 : Math.min(Math.max(q, 0), 1)
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
function splitMediaTypeParams(
|
|
29
|
-
params: string,
|
|
30
|
-
|
|
27
|
+
function splitMediaTypeParams(params: string): {
|
|
28
|
+
params: Record<string, string>
|
|
29
|
+
q: number
|
|
30
|
+
} {
|
|
31
31
|
const result: Record<string, string> = {}
|
|
32
32
|
let q = 1
|
|
33
33
|
|
|
@@ -40,7 +40,7 @@ function splitMediaTypeParams(
|
|
|
40
40
|
const key = trimmed.slice(0, eqIndex).trim().toLowerCase()
|
|
41
41
|
let value = trimmed.slice(eqIndex + 1).trim()
|
|
42
42
|
|
|
43
|
-
if (value.startsWith("
|
|
43
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
44
44
|
value = value.slice(1, -1)
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -56,17 +56,13 @@ function splitMediaTypeParams(
|
|
|
56
56
|
return { params: result, q }
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function parseAccept(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
q: number
|
|
67
|
-
o: number
|
|
68
|
-
}
|
|
69
|
-
> {
|
|
59
|
+
function parseAccept(accept: string): Array<{
|
|
60
|
+
type: string
|
|
61
|
+
subtype: string
|
|
62
|
+
params: Record<string, string>
|
|
63
|
+
q: number
|
|
64
|
+
o: number
|
|
65
|
+
}> {
|
|
70
66
|
const specs: Array<{
|
|
71
67
|
type: string
|
|
72
68
|
subtype: string
|
|
@@ -85,9 +81,7 @@ function parseAccept(
|
|
|
85
81
|
|
|
86
82
|
const type = match[1].toLowerCase()
|
|
87
83
|
const subtype = match[2].toLowerCase()
|
|
88
|
-
const { params, q } = match[3]
|
|
89
|
-
? splitMediaTypeParams(match[3])
|
|
90
|
-
: { params: {}, q: 1 }
|
|
84
|
+
const { params, q } = match[3] ? splitMediaTypeParams(match[3]) : { params: {}, q: 1 }
|
|
91
85
|
|
|
92
86
|
if (q > 0) {
|
|
93
87
|
specs.push({ type, subtype, params, q, o })
|
|
@@ -134,8 +128,7 @@ function specifyMediaType(
|
|
|
134
128
|
if (specParams.length > 0) {
|
|
135
129
|
if (
|
|
136
130
|
specParams.every(
|
|
137
|
-
(key) =>
|
|
138
|
-
spec.params[key].toLowerCase() === (params[key] || "").toLowerCase(),
|
|
131
|
+
(key) => spec.params[key].toLowerCase() === (params[key] || "").toLowerCase(),
|
|
139
132
|
)
|
|
140
133
|
) {
|
|
141
134
|
s |= 1
|
|
@@ -149,15 +142,13 @@ function specifyMediaType(
|
|
|
149
142
|
|
|
150
143
|
function getMediaTypePriority(
|
|
151
144
|
mediaType: string,
|
|
152
|
-
accepted: Array<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
>,
|
|
145
|
+
accepted: Array<{
|
|
146
|
+
type: string
|
|
147
|
+
subtype: string
|
|
148
|
+
params: Record<string, string>
|
|
149
|
+
q: number
|
|
150
|
+
o: number
|
|
151
|
+
}>,
|
|
161
152
|
index: number,
|
|
162
153
|
): ParsedSpec {
|
|
163
154
|
let best: { q: number; s: number; o: number } | null = null
|
|
@@ -169,18 +160,16 @@ function getMediaTypePriority(
|
|
|
169
160
|
|
|
170
161
|
const type = match[1].toLowerCase()
|
|
171
162
|
const subtype = match[2].toLowerCase()
|
|
172
|
-
const { params } = match[3]
|
|
173
|
-
? splitMediaTypeParams(match[3])
|
|
174
|
-
: { params: {} }
|
|
163
|
+
const { params } = match[3] ? splitMediaTypeParams(match[3]) : { params: {} }
|
|
175
164
|
|
|
176
165
|
for (const spec of accepted) {
|
|
177
166
|
const result = specifyMediaType(type, subtype, params, spec)
|
|
178
167
|
if (
|
|
179
|
-
result
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
result &&
|
|
169
|
+
(best === null ||
|
|
170
|
+
result.s > best.s ||
|
|
171
|
+
(result.s === best.s && result.q > best.q) ||
|
|
172
|
+
(result.s === best.s && result.q === best.q && result.o < best.o))
|
|
184
173
|
) {
|
|
185
174
|
best = result
|
|
186
175
|
}
|
|
@@ -256,9 +245,12 @@ function specifyLanguage(
|
|
|
256
245
|
|
|
257
246
|
function getLanguagePriority(
|
|
258
247
|
language: string,
|
|
259
|
-
accepted: Array<
|
|
260
|
-
|
|
261
|
-
|
|
248
|
+
accepted: Array<{
|
|
249
|
+
prefix: string
|
|
250
|
+
suffix: string | undefined
|
|
251
|
+
q: number
|
|
252
|
+
o: number
|
|
253
|
+
}>,
|
|
262
254
|
index: number,
|
|
263
255
|
): ParsedSpec {
|
|
264
256
|
let best: { q: number; s: number; o: number } | null = null
|
|
@@ -266,11 +258,11 @@ function getLanguagePriority(
|
|
|
266
258
|
for (const spec of accepted) {
|
|
267
259
|
const result = specifyLanguage(language, spec)
|
|
268
260
|
if (
|
|
269
|
-
result
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
261
|
+
result &&
|
|
262
|
+
(best === null ||
|
|
263
|
+
result.s > best.s ||
|
|
264
|
+
(result.s === best.s && result.q > best.q) ||
|
|
265
|
+
(result.s === best.s && result.q === best.q && result.o < best.o))
|
|
274
266
|
) {
|
|
275
267
|
best = result
|
|
276
268
|
}
|
|
@@ -285,9 +277,7 @@ function getLanguagePriority(
|
|
|
285
277
|
}
|
|
286
278
|
}
|
|
287
279
|
|
|
288
|
-
function parseAcceptEncoding(
|
|
289
|
-
accept: string,
|
|
290
|
-
): Array<{ encoding: string; q: number; o: number }> {
|
|
280
|
+
function parseAcceptEncoding(accept: string): Array<{ encoding: string; q: number; o: number }> {
|
|
291
281
|
const specs: Array<{ encoding: string; q: number; o: number }> = []
|
|
292
282
|
const parts = accept.split(",")
|
|
293
283
|
let hasIdentity = false
|
|
@@ -341,11 +331,11 @@ function getEncodingPriority(
|
|
|
341
331
|
for (const spec of accepted) {
|
|
342
332
|
const result = specifyEncoding(encoding, spec)
|
|
343
333
|
if (
|
|
344
|
-
result
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
334
|
+
result &&
|
|
335
|
+
(best === null ||
|
|
336
|
+
result.s > best.s ||
|
|
337
|
+
(result.s === best.s && result.q > best.q) ||
|
|
338
|
+
(result.s === best.s && result.q === best.q && result.o < best.o))
|
|
349
339
|
) {
|
|
350
340
|
best = result
|
|
351
341
|
}
|
|
@@ -360,9 +350,7 @@ function getEncodingPriority(
|
|
|
360
350
|
}
|
|
361
351
|
}
|
|
362
352
|
|
|
363
|
-
function parseAcceptCharset(
|
|
364
|
-
accept: string,
|
|
365
|
-
): Array<{ charset: string; q: number; o: number }> {
|
|
353
|
+
function parseAcceptCharset(accept: string): Array<{ charset: string; q: number; o: number }> {
|
|
366
354
|
const specs: Array<{ charset: string; q: number; o: number }> = []
|
|
367
355
|
const parts = accept.split(",")
|
|
368
356
|
|
|
@@ -408,11 +396,11 @@ function getCharsetPriority(
|
|
|
408
396
|
for (const spec of accepted) {
|
|
409
397
|
const result = specifyCharset(charset, spec)
|
|
410
398
|
if (
|
|
411
|
-
result
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
399
|
+
result &&
|
|
400
|
+
(best === null ||
|
|
401
|
+
result.s > best.s ||
|
|
402
|
+
(result.s === best.s && result.q > best.q) ||
|
|
403
|
+
(result.s === best.s && result.q === best.q && result.o < best.o))
|
|
416
404
|
) {
|
|
417
405
|
best = result
|
|
418
406
|
}
|
|
@@ -428,24 +416,17 @@ function getCharsetPriority(
|
|
|
428
416
|
}
|
|
429
417
|
|
|
430
418
|
function compareSpecs(a: ParsedSpec, b: ParsedSpec): number {
|
|
431
|
-
return
|
|
432
|
-
b.q - a.q
|
|
433
|
-
|| b.s - a.s
|
|
434
|
-
|| a.o - b.o
|
|
435
|
-
|| a.i - b.i
|
|
436
|
-
)
|
|
419
|
+
return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i
|
|
437
420
|
}
|
|
438
421
|
|
|
439
|
-
export function media(accept: string, available?: string
|
|
422
|
+
export function media(accept: string, available?: Array<string>): Array<string> {
|
|
440
423
|
const parsed = parseAccept(accept)
|
|
441
424
|
if (parsed.length === 0) {
|
|
442
425
|
return []
|
|
443
426
|
}
|
|
444
427
|
|
|
445
428
|
if (!available) {
|
|
446
|
-
return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) =>
|
|
447
|
-
`${p.type}/${p.subtype}`
|
|
448
|
-
)
|
|
429
|
+
return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) => `${p.type}/${p.subtype}`)
|
|
449
430
|
}
|
|
450
431
|
|
|
451
432
|
const priorities = available.map((t, i) => getMediaTypePriority(t, parsed, i))
|
|
@@ -454,16 +435,16 @@ export function media(accept: string, available?: string[]): string[] {
|
|
|
454
435
|
return sorted.map((p) => p.value)
|
|
455
436
|
}
|
|
456
437
|
|
|
457
|
-
export function language(accept: string, available?: string
|
|
438
|
+
export function language(accept: string, available?: Array<string>): Array<string> {
|
|
458
439
|
const parsed = parseAcceptLanguage(accept)
|
|
459
440
|
if (parsed.length === 0) {
|
|
460
441
|
return []
|
|
461
442
|
}
|
|
462
443
|
|
|
463
444
|
if (!available) {
|
|
464
|
-
return parsed
|
|
465
|
-
|
|
466
|
-
|
|
445
|
+
return parsed
|
|
446
|
+
.sort((a, b) => b.q - a.q || a.o - b.o)
|
|
447
|
+
.map((p) => (p.suffix ? `${p.prefix}-${p.suffix}` : p.prefix))
|
|
467
448
|
}
|
|
468
449
|
|
|
469
450
|
const priorities = available.map((l, i) => getLanguagePriority(l, parsed, i))
|
|
@@ -472,7 +453,7 @@ export function language(accept: string, available?: string[]): string[] {
|
|
|
472
453
|
return sorted.map((p) => p.value)
|
|
473
454
|
}
|
|
474
455
|
|
|
475
|
-
export function encoding(accept: string, available?: string
|
|
456
|
+
export function encoding(accept: string, available?: Array<string>): Array<string> {
|
|
476
457
|
const parsed = parseAcceptEncoding(accept)
|
|
477
458
|
if (parsed.length === 0) {
|
|
478
459
|
return []
|
|
@@ -488,7 +469,7 @@ export function encoding(accept: string, available?: string[]): string[] {
|
|
|
488
469
|
return sorted.map((p) => p.value)
|
|
489
470
|
}
|
|
490
471
|
|
|
491
|
-
export function charset(accept: string, available?: string
|
|
472
|
+
export function charset(accept: string, available?: Array<string>): Array<string> {
|
|
492
473
|
const parsed = parseAcceptCharset(accept)
|
|
493
474
|
if (parsed.length === 0) {
|
|
494
475
|
return []
|
|
@@ -504,37 +485,25 @@ export function charset(accept: string, available?: string[]): string[] {
|
|
|
504
485
|
return sorted.map((p) => p.value)
|
|
505
486
|
}
|
|
506
487
|
|
|
507
|
-
export function headerMedia(
|
|
508
|
-
headers: Headers,
|
|
509
|
-
available?: string[],
|
|
510
|
-
): string[] {
|
|
488
|
+
export function headerMedia(headers: Headers, available?: Array<string>): Array<string> {
|
|
511
489
|
const accept = headers.get("accept")
|
|
512
490
|
if (!accept) return []
|
|
513
491
|
return media(accept, available)
|
|
514
492
|
}
|
|
515
493
|
|
|
516
|
-
export function headerLanguage(
|
|
517
|
-
headers: Headers,
|
|
518
|
-
available?: string[],
|
|
519
|
-
): string[] {
|
|
494
|
+
export function headerLanguage(headers: Headers, available?: Array<string>): Array<string> {
|
|
520
495
|
const accept = headers.get("accept-language")
|
|
521
496
|
if (!accept) return []
|
|
522
497
|
return language(accept, available)
|
|
523
498
|
}
|
|
524
499
|
|
|
525
|
-
export function headerEncoding(
|
|
526
|
-
headers: Headers,
|
|
527
|
-
available?: string[],
|
|
528
|
-
): string[] {
|
|
500
|
+
export function headerEncoding(headers: Headers, available?: Array<string>): Array<string> {
|
|
529
501
|
const accept = headers.get("accept-encoding")
|
|
530
502
|
if (!accept) return []
|
|
531
503
|
return encoding(accept, available)
|
|
532
504
|
}
|
|
533
505
|
|
|
534
|
-
export function headerCharset(
|
|
535
|
-
headers: Headers,
|
|
536
|
-
available?: string[],
|
|
537
|
-
): string[] {
|
|
506
|
+
export function headerCharset(headers: Headers, available?: Array<string>): Array<string> {
|
|
538
507
|
const accept = headers.get("accept-charset")
|
|
539
508
|
if (!accept) return []
|
|
540
509
|
return charset(accept, available)
|
package/src/Cookies.ts
CHANGED
|
@@ -9,23 +9,18 @@ import * as Pipeable from "effect/Pipeable"
|
|
|
9
9
|
import * as Predicate from "effect/Predicate"
|
|
10
10
|
import type * as Types from "effect/Types"
|
|
11
11
|
|
|
12
|
-
export const TypeId: unique symbol = Symbol.for(
|
|
13
|
-
"effect-start/Cookies",
|
|
14
|
-
)
|
|
12
|
+
export const TypeId: unique symbol = Symbol.for("effect-start/Cookies")
|
|
15
13
|
|
|
16
14
|
export type TypeId = typeof TypeId
|
|
17
15
|
|
|
18
|
-
export const isCookies = (u: unknown): u is Cookies =>
|
|
19
|
-
Predicate.hasProperty(u, TypeId)
|
|
16
|
+
export const isCookies = (u: unknown): u is Cookies => Predicate.hasProperty(u, TypeId)
|
|
20
17
|
|
|
21
18
|
export interface Cookies extends Pipeable.Pipeable, Inspectable.Inspectable {
|
|
22
19
|
readonly [TypeId]: TypeId
|
|
23
20
|
readonly cookies: Record<string, Cookie>
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
export const CookieTypeId: unique symbol = Symbol.for(
|
|
27
|
-
"effect-start/Cookies/Cookie",
|
|
28
|
-
)
|
|
23
|
+
export const CookieTypeId: unique symbol = Symbol.for("effect-start/Cookies/Cookie")
|
|
29
24
|
|
|
30
25
|
export type CookieTypeId = typeof CookieTypeId
|
|
31
26
|
|
|
@@ -34,24 +29,26 @@ export interface Cookie extends Inspectable.Inspectable {
|
|
|
34
29
|
readonly name: string
|
|
35
30
|
readonly value: string
|
|
36
31
|
readonly valueEncoded: string
|
|
37
|
-
readonly options?:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
32
|
+
readonly options?:
|
|
33
|
+
| {
|
|
34
|
+
readonly domain?: string | undefined
|
|
35
|
+
readonly expires?: Date | undefined
|
|
36
|
+
readonly maxAge?: Duration.DurationInput | undefined
|
|
37
|
+
readonly path?: string | undefined
|
|
38
|
+
readonly priority?: "low" | "medium" | "high" | undefined
|
|
39
|
+
readonly httpOnly?: boolean | undefined
|
|
40
|
+
readonly secure?: boolean | undefined
|
|
41
|
+
readonly partitioned?: boolean | undefined
|
|
42
|
+
readonly sameSite?:
|
|
43
|
+
// send with top-level navigations and GET requests from third-party sites
|
|
44
|
+
| "lax"
|
|
45
|
+
// only send with same-site requests
|
|
46
|
+
| "strict"
|
|
47
|
+
// send with all requests (requires Secure)
|
|
48
|
+
| "none"
|
|
49
|
+
| undefined
|
|
50
|
+
}
|
|
51
|
+
| undefined
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
const CookiesProto: Omit<Cookies, "cookies"> = {
|
|
@@ -60,9 +57,7 @@ const CookiesProto: Omit<Cookies, "cookies"> = {
|
|
|
60
57
|
toJSON(this: Cookies) {
|
|
61
58
|
return {
|
|
62
59
|
_id: "effect-start/Cookies",
|
|
63
|
-
cookies: Object.fromEntries(
|
|
64
|
-
Object.entries(this.cookies).map(([k, v]) => [k, v.toJSON()]),
|
|
65
|
-
),
|
|
60
|
+
cookies: Object.fromEntries(Object.entries(this.cookies).map(([k, v]) => [k, v.toJSON()])),
|
|
66
61
|
}
|
|
67
62
|
},
|
|
68
63
|
pipe() {
|
|
@@ -83,9 +78,7 @@ const CookieProto = {
|
|
|
83
78
|
},
|
|
84
79
|
}
|
|
85
80
|
|
|
86
|
-
const makeCookiesFromRecord = (
|
|
87
|
-
cookies: Record<string, Cookie>,
|
|
88
|
-
): Cookies => {
|
|
81
|
+
const makeCookiesFromRecord = (cookies: Record<string, Cookie>): Cookies => {
|
|
89
82
|
const self = Object.create(CookiesProto)
|
|
90
83
|
self.cookies = cookies
|
|
91
84
|
return self
|
|
@@ -114,9 +107,7 @@ export const fromIterable = (cookies: Iterable<Cookie>): Cookies => {
|
|
|
114
107
|
return makeCookiesFromRecord(record)
|
|
115
108
|
}
|
|
116
109
|
|
|
117
|
-
export const fromSetCookie = (
|
|
118
|
-
headers: Iterable<string> | string,
|
|
119
|
-
): Cookies => {
|
|
110
|
+
export const fromSetCookie = (headers: Iterable<string> | string): Cookies => {
|
|
120
111
|
const arrayHeaders = typeof headers === "string" ? [headers] : headers
|
|
121
112
|
const cookies: Array<Cookie> = []
|
|
122
113
|
for (const header of arrayHeaders) {
|
|
@@ -139,16 +130,10 @@ export const isEmpty = (self: Cookies): boolean => {
|
|
|
139
130
|
return true
|
|
140
131
|
}
|
|
141
132
|
|
|
142
|
-
export const get = (
|
|
143
|
-
self: Cookies,
|
|
144
|
-
name: string,
|
|
145
|
-
): Option.Option<Cookie> =>
|
|
133
|
+
export const get = (self: Cookies, name: string): Option.Option<Cookie> =>
|
|
146
134
|
name in self.cookies ? Option.some(self.cookies[name]) : Option.none()
|
|
147
135
|
|
|
148
|
-
export const getValue = (
|
|
149
|
-
self: Cookies,
|
|
150
|
-
name: string,
|
|
151
|
-
): Option.Option<string> =>
|
|
136
|
+
export const getValue = (self: Cookies, name: string): Option.Option<string> =>
|
|
152
137
|
Option.map(get(self, name), (cookie) => cookie.value)
|
|
153
138
|
|
|
154
139
|
export const setCookie = (self: Cookies, cookie: Cookie): Cookies =>
|
|
@@ -163,9 +148,7 @@ export const unsafeSet = (
|
|
|
163
148
|
|
|
164
149
|
export const unsafeSetAll = (
|
|
165
150
|
self: Cookies,
|
|
166
|
-
cookies: Iterable<
|
|
167
|
-
readonly [name: string, value: string, options?: Cookie["options"]]
|
|
168
|
-
>,
|
|
151
|
+
cookies: Iterable<readonly [name: string, value: string, options?: Cookie["options"]]>,
|
|
169
152
|
): Cookies => {
|
|
170
153
|
const record: Record<string, Cookie> = { ...self.cookies }
|
|
171
154
|
for (const [name, value, options] of cookies) {
|
|
@@ -251,8 +234,7 @@ export function serializeCookie(self: Cookie): string {
|
|
|
251
234
|
}
|
|
252
235
|
|
|
253
236
|
export const toCookieHeader = (self: Cookies): string =>
|
|
254
|
-
Object
|
|
255
|
-
.values(self.cookies)
|
|
237
|
+
Object.values(self.cookies)
|
|
256
238
|
.map((cookie) => `${cookie.name}=${cookie.valueEncoded}`)
|
|
257
239
|
.join("; ")
|
|
258
240
|
|
|
@@ -288,13 +270,12 @@ export function parseHeader(header: string): Record<string, string> {
|
|
|
288
270
|
|
|
289
271
|
const key = header.substring(pos, eqIdx++).trim()
|
|
290
272
|
if (result[key] === undefined) {
|
|
291
|
-
const val =
|
|
292
|
-
|
|
293
|
-
|
|
273
|
+
const val =
|
|
274
|
+
header.charCodeAt(eqIdx) === 0x22
|
|
275
|
+
? header.substring(eqIdx + 1, terminatorPos - 1).trim()
|
|
276
|
+
: header.substring(eqIdx, terminatorPos).trim()
|
|
294
277
|
|
|
295
|
-
result[key] = !(val.indexOf("%") === -1)
|
|
296
|
-
? tryDecodeURIComponent(val)
|
|
297
|
-
: val
|
|
278
|
+
result[key] = !(val.indexOf("%") === -1) ? tryDecodeURIComponent(val) : val
|
|
298
279
|
}
|
|
299
280
|
|
|
300
281
|
pos = terminatorPos + 1
|
|
@@ -337,9 +318,7 @@ function parseSetCookie(header: string): Option.Option<Cookie> {
|
|
|
337
318
|
const part = parts[i]
|
|
338
319
|
const equalIndex = part.indexOf("=")
|
|
339
320
|
const key = equalIndex === -1 ? part : part.slice(0, equalIndex).trim()
|
|
340
|
-
const value = equalIndex === -1
|
|
341
|
-
? undefined
|
|
342
|
-
: part.slice(equalIndex + 1).trim()
|
|
321
|
+
const value = equalIndex === -1 ? undefined : part.slice(equalIndex + 1).trim()
|
|
343
322
|
|
|
344
323
|
switch (key.toLowerCase()) {
|
|
345
324
|
case "domain": {
|
package/src/Development.ts
CHANGED
|
@@ -7,21 +7,18 @@ import * as Layer from "effect/Layer"
|
|
|
7
7
|
import * as Option from "effect/Option"
|
|
8
8
|
import * as PubSub from "effect/PubSub"
|
|
9
9
|
import * as Stream from "effect/Stream"
|
|
10
|
-
import * as PlatformError from "./PlatformError.ts"
|
|
10
|
+
import type * as PlatformError from "./PlatformError.ts"
|
|
11
11
|
|
|
12
12
|
export type DevelopmentEvent =
|
|
13
13
|
| FileSystem.WatchEvent
|
|
14
14
|
| {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
readonly _tag: "Reload"
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
const devState = GlobalValue.globalValue(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
pubsub: null as PubSub.PubSub<DevelopmentEvent> | null,
|
|
23
|
-
}),
|
|
24
|
-
)
|
|
18
|
+
const devState = GlobalValue.globalValue(Symbol.for("effect-start/Development"), () => ({
|
|
19
|
+
count: 0,
|
|
20
|
+
pubsub: null as PubSub.PubSub<DevelopmentEvent> | null,
|
|
21
|
+
}))
|
|
25
22
|
|
|
26
23
|
/** @internal */
|
|
27
24
|
export const _resetForTesting = () => {
|
|
@@ -48,25 +45,18 @@ export const filterDirectory = (event: FileSystem.WatchEvent): boolean => {
|
|
|
48
45
|
return event.path.endsWith("/")
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
export const watchSource = (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
): Stream.Stream<
|
|
58
|
-
FileSystem.WatchEvent,
|
|
59
|
-
PlatformError.PlatformError,
|
|
60
|
-
FileSystem.FileSystem
|
|
61
|
-
> => {
|
|
48
|
+
export const watchSource = (opts?: {
|
|
49
|
+
path?: string
|
|
50
|
+
recursive?: boolean
|
|
51
|
+
filter?: (event: FileSystem.WatchEvent) => boolean
|
|
52
|
+
}): Stream.Stream<FileSystem.WatchEvent, PlatformError.PlatformError, FileSystem.FileSystem> => {
|
|
62
53
|
const baseDir = opts?.path ?? process.cwd()
|
|
63
54
|
const customFilter = opts?.filter
|
|
64
55
|
|
|
65
56
|
return Function.pipe(
|
|
66
57
|
Stream.unwrap(
|
|
67
|
-
Effect.map(
|
|
68
|
-
|
|
69
|
-
fs => fs.watch(baseDir, { recursive: opts?.recursive ?? true }),
|
|
58
|
+
Effect.map(FileSystem.FileSystem, (fs) =>
|
|
59
|
+
fs.watch(baseDir, { recursive: opts?.recursive ?? true }),
|
|
70
60
|
),
|
|
71
61
|
),
|
|
72
62
|
customFilter ? Stream.filter(customFilter) : Function.identity,
|
|
@@ -80,44 +70,39 @@ export const watchSource = (
|
|
|
80
70
|
)
|
|
81
71
|
}
|
|
82
72
|
|
|
83
|
-
export const watch = (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
path?: string
|
|
117
|
-
recursive?: boolean
|
|
118
|
-
filter?: (event: FileSystem.WatchEvent) => boolean
|
|
119
|
-
},
|
|
120
|
-
) => Layer.scoped(Development, watch(opts))
|
|
73
|
+
export const watch = (opts?: {
|
|
74
|
+
path?: string
|
|
75
|
+
recursive?: boolean
|
|
76
|
+
filter?: (event: FileSystem.WatchEvent) => boolean
|
|
77
|
+
}) =>
|
|
78
|
+
Effect.gen(function* () {
|
|
79
|
+
devState.count++
|
|
80
|
+
|
|
81
|
+
if (devState.count === 1) {
|
|
82
|
+
const pubsub = yield* PubSub.unbounded<DevelopmentEvent>()
|
|
83
|
+
devState.pubsub = pubsub
|
|
84
|
+
|
|
85
|
+
yield* Function.pipe(
|
|
86
|
+
watchSource({
|
|
87
|
+
path: opts?.path,
|
|
88
|
+
recursive: opts?.recursive,
|
|
89
|
+
filter: opts?.filter ?? filterSourceFiles,
|
|
90
|
+
}),
|
|
91
|
+
Stream.runForEach((event) => PubSub.publish(pubsub, event)),
|
|
92
|
+
Effect.fork,
|
|
93
|
+
)
|
|
94
|
+
} else {
|
|
95
|
+
yield* PubSub.publish(devState.pubsub!, { _tag: "Reload" })
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { events: devState.pubsub! } satisfies DevelopmentService
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
export const layerWatch = (opts?: {
|
|
102
|
+
path?: string
|
|
103
|
+
recursive?: boolean
|
|
104
|
+
filter?: (event: FileSystem.WatchEvent) => boolean
|
|
105
|
+
}) => Layer.scoped(Development, watch(opts))
|
|
121
106
|
|
|
122
107
|
export const stream = (): Stream.Stream<DevelopmentEvent> =>
|
|
123
108
|
Stream.unwrap(
|