@effect/platform-node 4.0.0-beta.98 → 4.0.0-rc.108

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 (137) hide show
  1. package/AGENTS.md +381 -0
  2. package/CLAUDE.md +381 -0
  3. package/README.md +10 -3
  4. package/ai-docs/README.md +44 -0
  5. package/ai-docs/package.json +36 -0
  6. package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
  7. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
  8. package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
  9. package/ai-docs/src/01_effect/01_basics/index.md +5 -0
  10. package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
  11. package/ai-docs/src/01_effect/02_schema/index.md +7 -0
  12. package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
  13. package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
  14. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
  15. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
  16. package/ai-docs/src/01_effect/03_services/index.md +5 -0
  17. package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
  18. package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
  19. package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
  20. package/ai-docs/src/01_effect/04_errors/index.md +1 -0
  21. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
  22. package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
  23. package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
  24. package/ai-docs/src/01_effect/05_resources/index.md +3 -0
  25. package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
  26. package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
  27. package/ai-docs/src/01_effect/06_running/index.md +1 -0
  28. package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
  29. package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
  30. package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
  31. package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
  32. package/ai-docs/src/03_stream/30_encoding.ts +165 -0
  33. package/ai-docs/src/03_stream/index.md +4 -0
  34. package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
  35. package/ai-docs/src/04_integration/index.md +5 -0
  36. package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
  37. package/ai-docs/src/05_batching/index.md +3 -0
  38. package/ai-docs/src/06_schedule/10_schedules.ts +110 -0
  39. package/ai-docs/src/06_schedule/index.md +3 -0
  40. package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
  41. package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
  42. package/ai-docs/src/07_datetime/index.md +5 -0
  43. package/ai-docs/src/08_observability/10_logging.ts +66 -0
  44. package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
  45. package/ai-docs/src/08_observability/index.md +7 -0
  46. package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
  47. package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
  48. package/ai-docs/src/09_testing/index.md +1 -0
  49. package/ai-docs/src/10_predicate/01_basics.ts +14 -0
  50. package/ai-docs/src/10_predicate/index.md +9 -0
  51. package/ai-docs/src/50_http-client/10_basics.ts +102 -0
  52. package/ai-docs/src/50_http-client/index.md +3 -0
  53. package/ai-docs/src/51_http-server/10_basics.ts +116 -0
  54. package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
  55. package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
  56. package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
  57. package/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
  58. package/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
  59. package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
  60. package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
  61. package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
  62. package/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
  63. package/ai-docs/src/51_http-server/index.md +3 -0
  64. package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
  65. package/ai-docs/src/60_child-process/index.md +3 -0
  66. package/ai-docs/src/70_cli/10_basics.ts +136 -0
  67. package/ai-docs/src/70_cli/index.md +5 -0
  68. package/ai-docs/src/71_ai/10_language-model.ts +156 -0
  69. package/ai-docs/src/71_ai/20_tools.ts +226 -0
  70. package/ai-docs/src/71_ai/30_chat.ts +158 -0
  71. package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
  72. package/ai-docs/src/71_ai/index.md +5 -0
  73. package/ai-docs/src/80_cluster/10_entities.ts +97 -0
  74. package/ai-docs/src/80_cluster/index.md +4 -0
  75. package/ai-docs/src/index.md +10 -0
  76. package/ai-docs/tsconfig.json +24 -0
  77. package/dist/Mime.js.map +1 -1
  78. package/dist/NodeClusterHttp.d.ts +1 -0
  79. package/dist/NodeClusterHttp.d.ts.map +1 -1
  80. package/dist/NodeClusterHttp.js +6 -1
  81. package/dist/NodeClusterHttp.js.map +1 -1
  82. package/dist/NodeClusterSocket.d.ts +1 -0
  83. package/dist/NodeClusterSocket.d.ts.map +1 -1
  84. package/dist/NodeClusterSocket.js +10 -2
  85. package/dist/NodeClusterSocket.js.map +1 -1
  86. package/dist/NodeCrypto.js.map +1 -1
  87. package/dist/NodeFileSystem.js.map +1 -1
  88. package/dist/NodeHttpClient.d.ts +18 -18
  89. package/dist/NodeHttpClient.d.ts.map +1 -1
  90. package/dist/NodeHttpClient.js +26 -20
  91. package/dist/NodeHttpClient.js.map +1 -1
  92. package/dist/NodeHttpIncomingMessage.js.map +1 -1
  93. package/dist/NodeHttpPlatform.d.ts +8 -4
  94. package/dist/NodeHttpPlatform.d.ts.map +1 -1
  95. package/dist/NodeHttpPlatform.js +38 -0
  96. package/dist/NodeHttpPlatform.js.map +1 -1
  97. package/dist/NodeHttpServer.d.ts +21 -16
  98. package/dist/NodeHttpServer.d.ts.map +1 -1
  99. package/dist/NodeHttpServer.js +29 -21
  100. package/dist/NodeHttpServer.js.map +1 -1
  101. package/dist/NodeHttpServerRequest.js.map +1 -1
  102. package/dist/NodeMultipart.d.ts.map +1 -1
  103. package/dist/NodeMultipart.js +3 -2
  104. package/dist/NodeMultipart.js.map +1 -1
  105. package/dist/NodeMultipartParser.d.ts +97 -0
  106. package/dist/NodeMultipartParser.d.ts.map +1 -0
  107. package/dist/NodeMultipartParser.js +108 -0
  108. package/dist/NodeMultipartParser.js.map +1 -0
  109. package/dist/NodePath.js.map +1 -1
  110. package/dist/NodeRedis.js.map +1 -1
  111. package/dist/NodeRuntime.js.map +1 -1
  112. package/dist/NodeServices.js.map +1 -1
  113. package/dist/NodeSocket.js.map +1 -1
  114. package/dist/NodeStdio.js.map +1 -1
  115. package/dist/NodeTerminal.js.map +1 -1
  116. package/dist/NodeWorker.js.map +1 -1
  117. package/dist/NodeWorkerRunner.d.ts.map +1 -1
  118. package/dist/NodeWorkerRunner.js +30 -18
  119. package/dist/NodeWorkerRunner.js.map +1 -1
  120. package/dist/Undici.d.ts +2 -2
  121. package/dist/Undici.js +2 -2
  122. package/dist/Undici.js.map +1 -1
  123. package/dist/index.d.ts +4 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +4 -0
  126. package/dist/index.js.map +1 -1
  127. package/package.json +18 -16
  128. package/src/NodeClusterHttp.ts +6 -2
  129. package/src/NodeClusterSocket.ts +8 -2
  130. package/src/NodeHttpClient.ts +27 -20
  131. package/src/NodeHttpPlatform.ts +49 -0
  132. package/src/NodeHttpServer.ts +61 -40
  133. package/src/NodeMultipart.ts +5 -4
  134. package/src/NodeMultipartParser.ts +184 -0
  135. package/src/NodeWorkerRunner.ts +39 -23
  136. package/src/Undici.ts +2 -2
  137. package/src/index.ts +5 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Node.js streams adapter for the low-level multipart parser.
3
+ *
4
+ * @since 4.0.0
5
+ */
6
+ // oxlint-disable typescript/no-unsafe-declaration-merging
7
+ /// <reference types="node" />
8
+ import type { BaseConfig, MultipartError, Parser, PartInfo } from "effect/unstable/http/MultipartParser"
9
+ import { make as makeParser } from "effect/unstable/http/MultipartParser"
10
+ import type { IncomingHttpHeaders } from "node:http"
11
+ import { Duplex, Readable } from "node:stream"
12
+
13
+ /**
14
+ * A part emitted by the Node.js multipart parser.
15
+ *
16
+ * @category models
17
+ * @since 4.0.0
18
+ */
19
+ export type Part = Field | FileStream
20
+
21
+ /**
22
+ * A parsed multipart field.
23
+ *
24
+ * @category models
25
+ * @since 4.0.0
26
+ */
27
+ export interface Field {
28
+ readonly _tag: "Field"
29
+ readonly info: PartInfo
30
+ readonly value: Uint8Array
31
+ }
32
+
33
+ /**
34
+ * A Node.js duplex stream that emits parsed multipart parts.
35
+ *
36
+ * @category models
37
+ * @since 4.0.0
38
+ */
39
+ export interface MultipartStream extends Duplex {
40
+ [Symbol.asyncIterator](): NodeJS.AsyncIterator<Part>
41
+
42
+ on(event: "field", listener: (field: Field) => void): this
43
+ on(event: "file", listener: (file: FileStream) => void): this
44
+ on(event: "close", listener: () => void): this
45
+ on(event: "data", listener: (part: Part) => void): this
46
+ on(event: "drain", listener: () => void): this
47
+ on(event: "end", listener: () => void): this
48
+ on(event: "error", listener: (err: MultipartError) => void): this
49
+ on(event: "finish", listener: () => void): this
50
+ on(event: "pause", listener: () => void): this
51
+ on(event: "pipe", listener: (src: Readable) => void): this
52
+ on(event: "readable", listener: () => void): this
53
+ on(event: "resume", listener: () => void): this
54
+ on(event: "unpipe", listener: (src: Readable) => void): this
55
+ on(event: string | symbol, listener: (...args: Array<any>) => void): this
56
+
57
+ read(size?: number): Part | null
58
+ }
59
+
60
+ /**
61
+ * Configuration for the Node.js multipart parser.
62
+ *
63
+ * @category models
64
+ * @since 4.0.0
65
+ */
66
+ export type NodeConfig = Omit<BaseConfig, "headers"> & {
67
+ readonly headers: IncomingHttpHeaders
68
+ }
69
+
70
+ /**
71
+ * A Node.js duplex stream that parses multipart input.
72
+ *
73
+ * @category models
74
+ * @since 4.0.0
75
+ */
76
+ export class MultipartStream extends Duplex {
77
+ private _parser: Parser
78
+ _canWrite = true
79
+ private _writeCallback: (() => void) | undefined
80
+
81
+ constructor(config: NodeConfig) {
82
+ super({ readableObjectMode: true })
83
+ let currentError: MultipartError | undefined
84
+ let currentFile: FileStream | undefined
85
+ this._parser = makeParser({
86
+ ...(config as any),
87
+ onField: (info, value) => {
88
+ if (currentError !== undefined) return
89
+ const field: Field = { _tag: "Field", info, value }
90
+ this.push(field)
91
+ this.emit("field", field)
92
+ },
93
+ onFile: (info) => {
94
+ if (currentError !== undefined) return (_) => {}
95
+ const file = new FileStream(info, this)
96
+ currentFile = file
97
+ this.push(file)
98
+ this.emit("file", file)
99
+ return (chunk) => {
100
+ if (currentError !== undefined) return
101
+ this._canWrite = file.push(chunk)
102
+ if (chunk === null && !this._canWrite) {
103
+ currentFile = undefined
104
+ this._resume()
105
+ }
106
+ }
107
+ },
108
+ onError: (error) => {
109
+ this.emit("error", error)
110
+ currentFile?.emit("error", error)
111
+ currentError = error
112
+ },
113
+ onDone: () => {
114
+ this.push(null)
115
+ }
116
+ })
117
+ }
118
+
119
+ _resume() {
120
+ this._canWrite = true
121
+ if (this._writeCallback !== undefined) {
122
+ const callback = this._writeCallback
123
+ this._writeCallback = undefined
124
+ callback()
125
+ }
126
+ }
127
+
128
+ override _read(_size: number) {}
129
+
130
+ override _write(
131
+ chunk: any,
132
+ encoding: BufferEncoding,
133
+ callback: (error?: Error | null | undefined) => void
134
+ ): void {
135
+ this._parser.write(
136
+ chunk instanceof Uint8Array ? chunk : Buffer.from(chunk, encoding)
137
+ )
138
+ if (this._canWrite) {
139
+ callback()
140
+ } else {
141
+ this._writeCallback = callback
142
+ }
143
+ }
144
+
145
+ override _final(callback: (error?: Error | null | undefined) => void): void {
146
+ this._parser.end()
147
+ callback()
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Creates a Node.js multipart parser stream.
153
+ *
154
+ * @category constructors
155
+ * @since 4.0.0
156
+ */
157
+ export const make = (config: NodeConfig): MultipartStream => new MultipartStream(config)
158
+
159
+ /**
160
+ * A readable stream containing a parsed multipart file.
161
+ *
162
+ * @category models
163
+ * @since 4.0.0
164
+ */
165
+ export class FileStream extends Readable {
166
+ readonly _tag = "File"
167
+ readonly filename: string | undefined
168
+ readonly info: PartInfo
169
+ private _parent: MultipartStream
170
+ constructor(
171
+ info: PartInfo,
172
+ parent: MultipartStream
173
+ ) {
174
+ super()
175
+ this.info = info
176
+ this._parent = parent
177
+ this.filename = info.filename
178
+ }
179
+ override _read(_size: number) {
180
+ if (this._parent._canWrite === false) {
181
+ this._parent._resume()
182
+ }
183
+ }
184
+ }
@@ -16,6 +16,7 @@ import * as Effect from "effect/Effect"
16
16
  import * as Exit from "effect/Exit"
17
17
  import * as Fiber from "effect/Fiber"
18
18
  import * as Layer from "effect/Layer"
19
+ import * as Scope from "effect/Scope"
19
20
  import { WorkerError, WorkerReceiveError, WorkerSpawnError } from "effect/unstable/workers/WorkerError"
20
21
  import * as WorkerRunner from "effect/unstable/workers/WorkerRunner"
21
22
  import * as WorkerThreads from "node:worker_threads"
@@ -56,7 +57,8 @@ export const layer: Layer.Layer<WorkerRunner.WorkerRunnerPlatform> = Layer.succe
56
57
  runFork(Effect.logError("unhandled error in worker", exit.cause))
57
58
  }
58
59
  }
59
- ;(WorkerThreads.parentPort ?? process).on("message", (message: WorkerRunner.PlatformMessage<I>) => {
60
+ const port = WorkerThreads.parentPort ?? process
61
+ function onMessage(message: WorkerRunner.PlatformMessage<I>) {
60
62
  if (message[0] === 0) {
61
63
  const result = handler(0, message[1])
62
64
  if (Effect.isEffect(result)) {
@@ -72,32 +74,46 @@ export const layer: Layer.Layer<WorkerRunner.WorkerRunnerPlatform> = Layer.succe
72
74
  }
73
75
  Deferred.doneUnsafe(closeLatch, Exit.void)
74
76
  }
75
- })
77
+ }
78
+ port.on("message", onMessage)
76
79
 
77
- if (WorkerThreads.parentPort) {
78
- WorkerThreads.parentPort.on("messageerror", (cause) => {
79
- Deferred.doneUnsafe(
80
- closeLatch,
81
- new WorkerError({
82
- reason: new WorkerReceiveError({
83
- message: "received messageerror event",
84
- cause
85
- })
80
+ function onMessageError(cause: unknown) {
81
+ Deferred.doneUnsafe(
82
+ closeLatch,
83
+ new WorkerError({
84
+ reason: new WorkerReceiveError({
85
+ message: "received messageerror event",
86
+ cause
86
87
  })
87
- )
88
- })
89
- WorkerThreads.parentPort.on("error", (cause) => {
90
- Deferred.doneUnsafe(
91
- closeLatch,
92
- new WorkerError({
93
- reason: new WorkerReceiveError({
94
- message: "received messageerror event",
95
- cause
96
- })
88
+ })
89
+ )
90
+ }
91
+ function onError(cause: unknown) {
92
+ Deferred.doneUnsafe(
93
+ closeLatch,
94
+ new WorkerError({
95
+ reason: new WorkerReceiveError({
96
+ message: "received error event",
97
+ cause
97
98
  })
98
- )
99
- })
99
+ })
100
+ )
100
101
  }
102
+ if (WorkerThreads.parentPort) {
103
+ WorkerThreads.parentPort.on("messageerror", onMessageError)
104
+ WorkerThreads.parentPort.on("error", onError)
105
+ }
106
+
107
+ yield* Scope.addFinalizer(
108
+ scope,
109
+ Effect.sync(() => {
110
+ port.off("message", onMessage)
111
+ if (WorkerThreads.parentPort) {
112
+ WorkerThreads.parentPort.off("messageerror", onMessageError)
113
+ WorkerThreads.parentPort.off("error", onError)
114
+ }
115
+ })
116
+ )
101
117
 
102
118
  sendUnsafe(0, [0])
103
119
 
package/src/Undici.ts CHANGED
@@ -17,13 +17,13 @@
17
17
  import Undici from "undici"
18
18
 
19
19
  /**
20
- * @category Undici
20
+ * @category re-exports
21
21
  * @since 4.0.0
22
22
  */
23
23
  export * from "undici"
24
24
 
25
25
  /**
26
- * @category Undici
26
+ * @category re-exports
27
27
  * @since 4.0.0
28
28
  */
29
29
  export default Undici
package/src/index.ts CHANGED
@@ -64,6 +64,11 @@ export * as NodeHttpServerRequest from "./NodeHttpServerRequest.ts"
64
64
  */
65
65
  export * as NodeMultipart from "./NodeMultipart.ts"
66
66
 
67
+ /**
68
+ * @since 4.0.0
69
+ */
70
+ export * as NodeMultipartParser from "./NodeMultipartParser.ts"
71
+
67
72
  /**
68
73
  * @since 4.0.0
69
74
  */