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
@@ -1,14 +1,5 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- effect,
4
- getPath,
5
- mergePaths,
6
- } from "../engine.ts"
7
- import type { Paths } from "../engine.ts"
8
- import {
9
- aliasify,
10
- modifyCasing,
11
- } from "../utils.ts"
1
+ import { attribute, effect, getPath, mergePaths, type Paths } from "../engine.ts"
2
+ import { aliasify, modifyCasing } from "../utils.ts"
12
3
 
13
4
  type SignalFile = {
14
5
  name: string
@@ -27,8 +18,7 @@ attribute({
27
18
  apply({ el, key, mods, value, error }) {
28
19
  const signalName = key != null ? modifyCasing(key, mods) : value
29
20
 
30
- let get = (el: any, type: string) =>
31
- type === "number" ? +el.value : el.value
21
+ let get = (el: any, type: string) => (type === "number" ? +el.value : el.value)
32
22
 
33
23
  let set = (value: any) => {
34
24
  ;(el as HTMLInputElement).value = `${value}`
@@ -38,8 +28,7 @@ attribute({
38
28
  switch (el.type) {
39
29
  case "range":
40
30
  case "number":
41
- get = (el: any, type: string) =>
42
- type === "string" ? el.value : +el.value
31
+ get = (el: any, type: string) => (type === "string" ? el.value : +el.value)
43
32
  break
44
33
 
45
34
  case "checkbox":
@@ -71,47 +60,43 @@ attribute({
71
60
  get = (el: HTMLInputElement, type: string) =>
72
61
  el.checked ? (type === "number" ? +el.value : el.value) : empty
73
62
  set = (value: string | number) => {
74
- el.checked = value === (typeof value === "number"
75
- ? +el.value
76
- : el.value)
63
+ el.checked = value === (typeof value === "number" ? +el.value : el.value)
77
64
  }
78
65
  break
79
66
  case "file": {
80
67
  const syncSignal = () => {
81
68
  const files = [...(el.files || [])]
82
- const signalFiles: SignalFile[] = []
83
- Promise
84
- .all(
85
- files.map(
86
- (f) =>
87
- new Promise<void>((resolve) => {
88
- const reader = new FileReader()
89
- reader.onload = () => {
90
- if (typeof reader.result !== "string") {
91
- throw error("InvalidFileResultType", {
92
- resultType: typeof reader.result,
93
- })
94
- }
95
- const match = reader.result.match(dataURIRegex)
96
- if (!match?.groups) {
97
- throw error("InvalidDataUri", {
98
- result: reader.result,
99
- })
100
- }
101
- signalFiles.push({
102
- name: f.name,
103
- contents: match.groups.contents,
104
- mime: match.groups.mime,
69
+ const signalFiles: Array<SignalFile> = []
70
+ Promise.all(
71
+ files.map(
72
+ (f) =>
73
+ new Promise<void>((resolve) => {
74
+ const reader = new FileReader()
75
+ reader.onload = () => {
76
+ if (typeof reader.result !== "string") {
77
+ throw error("InvalidFileResultType", {
78
+ resultType: typeof reader.result,
105
79
  })
106
80
  }
107
- reader.onloadend = () => resolve()
108
- reader.readAsDataURL(f)
109
- }),
110
- ),
111
- )
112
- .then(() => {
113
- mergePaths([[signalName, signalFiles]])
114
- })
81
+ const match = reader.result.match(dataURIRegex)
82
+ if (!match?.groups) {
83
+ throw error("InvalidDataUri", {
84
+ result: reader.result,
85
+ })
86
+ }
87
+ signalFiles.push({
88
+ name: f.name,
89
+ contents: match.groups.contents,
90
+ mime: match.groups.mime,
91
+ })
92
+ }
93
+ reader.onloadend = () => resolve()
94
+ reader.readAsDataURL(f)
95
+ }),
96
+ ),
97
+ ).then(() => {
98
+ mergePaths([[signalName, signalFiles]])
99
+ })
115
100
  }
116
101
 
117
102
  el.addEventListener("change", syncSignal)
@@ -129,12 +114,10 @@ attribute({
129
114
  get = (el: HTMLSelectElement) =>
130
115
  [...el.selectedOptions].map((option) => {
131
116
  const type = typeMap.get(option.value)
132
- return type === "string" || type == null
133
- ? option.value
134
- : +option.value
117
+ return type === "string" || type == null ? option.value : +option.value
135
118
  })
136
119
 
137
- set = (value: (string | number)[]) => {
120
+ set = (value: Array<string | number>) => {
138
121
  for (const option of el.options) {
139
122
  if (value.includes(option.value)) {
140
123
  typeMap.set(option.value, "string")
@@ -152,7 +135,7 @@ attribute({
152
135
  // default case
153
136
  } else {
154
137
  // web component
155
- get = (el: Element) => "value" in el ? el.value : el.getAttribute("value")
138
+ get = (el: Element) => ("value" in el ? el.value : el.getAttribute("value"))
156
139
  set = (value: any) => {
157
140
  if ("value" in el) {
158
141
  el.value = value
@@ -166,15 +149,12 @@ attribute({
166
149
  const type = typeof initialValue
167
150
 
168
151
  let path = signalName
169
- if (
170
- Array.isArray(initialValue)
171
- && !(el instanceof HTMLSelectElement && el.multiple)
172
- ) {
152
+ if (Array.isArray(initialValue) && !(el instanceof HTMLSelectElement && el.multiple)) {
173
153
  const signalNameKebab = key ? key : value!
174
154
  const inputs = document.querySelectorAll(
175
- `[${aliasedBind}\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}="${
176
- CSS.escape(signalNameKebab)
177
- }"]`,
155
+ `[${aliasedBind}\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}="${CSS.escape(
156
+ signalNameKebab,
157
+ )}"]`,
178
158
  ) as NodeListOf<HTMLInputElement>
179
159
 
180
160
  const paths: Paths = []
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { effect } from "../engine.ts"
1
+ import { attribute, effect } from "../engine.ts"
3
2
  import { modifyCasing } from "../utils.ts"
4
3
 
5
4
  attribute({
@@ -15,9 +14,7 @@ attribute({
15
14
  const callback = () => {
16
15
  observer.disconnect()
17
16
 
18
- classes = key
19
- ? { [key]: rx() as boolean }
20
- : (rx() as Record<string, boolean>)
17
+ classes = key ? { [key]: rx() as boolean } : (rx() as Record<string, boolean>)
21
18
 
22
19
  for (const k in classes) {
23
20
  const classNames = k.split(/\s+/).filter((cn) => cn.length > 0)
@@ -1,13 +1,5 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- computed,
4
- mergePatch,
5
- mergePaths,
6
- } from "../engine.ts"
7
- import {
8
- modifyCasing,
9
- updateLeaves,
10
- } from "../utils.ts"
1
+ import { attribute, computed, mergePatch, mergePaths } from "../engine.ts"
2
+ import { modifyCasing, updateLeaves } from "../utils.ts"
11
3
 
12
4
  attribute({
13
5
  name: "computed",
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { effect } from "../engine.ts"
1
+ import { attribute, effect } from "../engine.ts"
3
2
 
4
3
  attribute({
5
4
  name: "effect",
@@ -1,12 +1,6 @@
1
- import { DATASTAR_FETCH_EVENT } from "../engine.ts"
2
- import { attribute } from "../engine.ts"
3
- import { mergePaths } from "../engine.ts"
4
- import type { DatastarFetchEvent } from "../engine.ts"
1
+ import { attribute, DATASTAR_FETCH_EVENT, mergePaths, type DatastarFetchEvent } from "../engine.ts"
5
2
  import { modifyCasing } from "../utils.ts"
6
- import {
7
- FINISHED,
8
- STARTED,
9
- } from "../actions/fetch.ts"
3
+ import { FINISHED, STARTED } from "../actions/fetch.ts"
10
4
 
11
5
  attribute({
12
6
  name: "indicator",
@@ -1,13 +1,5 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- beginBatch,
4
- endBatch,
5
- } from "../engine.ts"
6
- import {
7
- delay,
8
- modifyViewTransition,
9
- tagToMs,
10
- } from "../utils.ts"
1
+ import { attribute, beginBatch, endBatch } from "../engine.ts"
2
+ import { delay, modifyViewTransition, tagToMs } from "../utils.ts"
11
3
 
12
4
  attribute({
13
5
  name: "init",
@@ -1,9 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- effect,
4
- filtered,
5
- } from "../engine.ts"
6
- import type { SignalFilterOptions } from "../engine.ts"
1
+ import { attribute, effect, filtered, type SignalFilterOptions } from "../engine.ts"
7
2
  import { jsStrToObject } from "../utils.ts"
8
3
 
9
4
  attribute({
@@ -1,17 +1,11 @@
1
1
  import {
2
+ attribute,
3
+ beginBatch,
2
4
  DATASTAR_FETCH_EVENT,
3
5
  DATASTAR_SIGNAL_PATCH_EVENT,
4
- } from "../engine.ts"
5
- import { attribute } from "../engine.ts"
6
- import {
7
- beginBatch,
8
6
  endBatch,
9
7
  } from "../engine.ts"
10
- import {
11
- modifyCasing,
12
- modifyTiming,
13
- modifyViewTransition,
14
- } from "../utils.ts"
8
+ import { modifyCasing, modifyTiming, modifyViewTransition } from "../utils.ts"
15
9
 
16
10
  attribute({
17
11
  name: "on",
@@ -50,10 +44,7 @@ attribute({
50
44
  }
51
45
  }
52
46
  const eventName = modifyCasing(key, mods, "kebab")
53
- if (
54
- eventName === DATASTAR_FETCH_EVENT
55
- || eventName === DATASTAR_SIGNAL_PATCH_EVENT
56
- ) {
47
+ if (eventName === DATASTAR_FETCH_EVENT || eventName === DATASTAR_SIGNAL_PATCH_EVENT) {
57
48
  target = document
58
49
  }
59
50
  if (el instanceof HTMLFormElement && eventName === "submit") {
@@ -1,14 +1,5 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- beginBatch,
4
- endBatch,
5
- } from "../engine.ts"
6
- import type { HTMLOrSVG } from "../engine.ts"
7
- import {
8
- clamp,
9
- modifyTiming,
10
- modifyViewTransition,
11
- } from "../utils.ts"
1
+ import { attribute, beginBatch, endBatch, type HTMLOrSVG } from "../engine.ts"
2
+ import { clamp, modifyTiming, modifyViewTransition } from "../utils.ts"
12
3
 
13
4
  const once = new WeakSet<HTMLOrSVG>()
14
5
 
@@ -35,19 +26,16 @@ attribute({
35
26
  options.threshold = clamp(Number(mods.get("threshold")), 0, 100) / 100
36
27
  }
37
28
  const exit = mods.has("exit")
38
- let observer: IntersectionObserver | null = new IntersectionObserver(
39
- (entries) => {
40
- for (const entry of entries) {
41
- if (entry.isIntersecting !== exit) {
42
- callback()
43
- if (observer && once.has(el)) {
44
- observer.disconnect()
45
- }
29
+ let observer: IntersectionObserver | null = new IntersectionObserver((entries) => {
30
+ for (const entry of entries) {
31
+ if (entry.isIntersecting !== exit) {
32
+ callback()
33
+ if (observer && once.has(el)) {
34
+ observer.disconnect()
46
35
  }
47
36
  }
48
- },
49
- options,
50
- )
37
+ }
38
+ }, options)
51
39
  observer.observe(el)
52
40
  if (mods.has("once")) {
53
41
  once.add(el)
@@ -1,13 +1,5 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- beginBatch,
4
- endBatch,
5
- } from "../engine.ts"
6
- import {
7
- modifyViewTransition,
8
- tagHas,
9
- tagToMs,
10
- } from "../utils.ts"
1
+ import { attribute, beginBatch, endBatch } from "../engine.ts"
2
+ import { modifyViewTransition, tagHas, tagToMs } from "../utils.ts"
11
3
 
12
4
  attribute({
13
5
  name: "on-interval",
@@ -1,20 +1,13 @@
1
- import { DATASTAR_SIGNAL_PATCH_EVENT } from "../engine.ts"
2
- import { attribute } from "../engine.ts"
3
1
  import {
2
+ attribute,
4
3
  beginBatch,
4
+ DATASTAR_SIGNAL_PATCH_EVENT,
5
5
  endBatch,
6
6
  filtered,
7
+ type JSONPatch,
8
+ type SignalFilterOptions,
7
9
  } from "../engine.ts"
8
- import type {
9
- JSONPatch,
10
- SignalFilterOptions,
11
- } from "../engine.ts"
12
- import {
13
- aliasify,
14
- isEmpty,
15
- jsStrToObject,
16
- modifyTiming,
17
- } from "../utils.ts"
10
+ import { aliasify, isEmpty, jsStrToObject, modifyTiming } from "../utils.ts"
18
11
 
19
12
  attribute({
20
13
  name: "on-signal-patch",
@@ -37,23 +30,20 @@ attribute({
37
30
 
38
31
  let running = false
39
32
 
40
- const callback: EventListener = modifyTiming(
41
- (evt: CustomEvent<JSONPatch>) => {
42
- if (running) return
43
- const watched = filtered(filters, evt.detail)
44
- if (!isEmpty(watched)) {
45
- running = true
46
- beginBatch()
47
- try {
48
- rx(watched)
49
- } finally {
50
- endBatch()
51
- running = false
52
- }
33
+ const callback: EventListener = modifyTiming((evt: CustomEvent<JSONPatch>) => {
34
+ if (running) return
35
+ const watched = filtered(filters, evt.detail)
36
+ if (!isEmpty(watched)) {
37
+ running = true
38
+ beginBatch()
39
+ try {
40
+ rx(watched)
41
+ } finally {
42
+ endBatch()
43
+ running = false
53
44
  }
54
- },
55
- mods,
56
- )
45
+ }
46
+ }, mods)
57
47
 
58
48
  document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)
59
49
  return () => {
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { mergePaths } from "../engine.ts"
1
+ import { attribute, mergePaths } from "../engine.ts"
3
2
  import { modifyCasing } from "../utils.ts"
4
3
 
5
4
  attribute({
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { effect } from "../engine.ts"
1
+ import { attribute, effect } from "../engine.ts"
3
2
 
4
3
  const NONE = "none"
5
4
  const DISPLAY = "display"
@@ -1,8 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import {
3
- mergePatch,
4
- mergePaths,
5
- } from "../engine.ts"
1
+ import { attribute, mergePatch, mergePaths } from "../engine.ts"
6
2
  import { modifyCasing } from "../utils.ts"
7
3
 
8
4
  attribute({
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { effect } from "../engine.ts"
1
+ import { attribute, effect } from "../engine.ts"
3
2
  import { kebab } from "../utils.ts"
4
3
 
5
4
  attribute({
@@ -15,13 +14,10 @@ attribute({
15
14
  const apply = (prop: string, value: any) => {
16
15
  const initial = initialStyles.get(prop)
17
16
  if (!value && value !== 0) {
18
- initial !== undefined
19
- && (initial
20
- ? style.setProperty(prop, initial)
21
- : style.removeProperty(prop))
17
+ initial !== undefined &&
18
+ (initial ? style.setProperty(prop, initial) : style.removeProperty(prop))
22
19
  } else {
23
- initial === undefined
24
- && initialStyles.set(prop, style.getPropertyValue(prop))
20
+ initial === undefined && initialStyles.set(prop, style.getPropertyValue(prop))
25
21
  style.setProperty(prop, String(value))
26
22
  }
27
23
  }
@@ -35,10 +31,8 @@ attribute({
35
31
  const styles = rx() as Record<string, any>
36
32
 
37
33
  for (const [prop, initial] of initialStyles) {
38
- prop in styles
39
- || (initial
40
- ? style.setProperty(prop, initial)
41
- : style.removeProperty(prop))
34
+ prop in styles ||
35
+ (initial ? style.setProperty(prop, initial) : style.removeProperty(prop))
42
36
  }
43
37
 
44
38
  for (const prop in styles) {
@@ -1,5 +1,4 @@
1
- import { attribute } from "../engine.ts"
2
- import { effect } from "../engine.ts"
1
+ import { attribute, effect } from "../engine.ts"
3
2
 
4
3
  attribute({
5
4
  name: "text",