@effect/platform-node
Advanced tools
Comparing version 0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49 to 0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.NodeWorkerRunner = exports.NodeWorker = exports.NodeTerminal = exports.NodeStream = exports.NodeSink = exports.NodeRuntime = exports.NodePath = exports.NodeKeyValueStore = exports.NodeHttpServer = exports.NodeHttpClient = exports.NodeFileSystem = exports.NodeContext = exports.NodeCommandExecutor = void 0; | ||
exports.NodeWorkerRunner = exports.NodeWorker = exports.NodeTerminal = exports.NodeStream = exports.NodeSocket = exports.NodeSink = exports.NodeRuntime = exports.NodePath = exports.NodeKeyValueStore = exports.NodeHttpServer = exports.NodeHttpClient = exports.NodeFileSystem = exports.NodeContext = exports.NodeCommandExecutor = void 0; | ||
var _NodeCommandExecutor = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./NodeCommandExecutor.js")); | ||
@@ -26,2 +26,4 @@ exports.NodeCommandExecutor = _NodeCommandExecutor; | ||
exports.NodeSink = _NodeSink; | ||
var _NodeSocket = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./NodeSocket.js")); | ||
exports.NodeSocket = _NodeSocket; | ||
var _NodeStream = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./NodeStream.js")); | ||
@@ -54,3 +56,3 @@ exports.NodeStream = _NodeStream; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -57,0 +59,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -10,3 +10,4 @@ "use strict"; | ||
var ClientResponse = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/ClientResponse")); | ||
var UrlParams = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/UrlParams")); | ||
var Cookies = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/Cookies")); | ||
var IncomingMessage = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/IncomingMessage")); | ||
var Context = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Context")); | ||
@@ -42,3 +43,3 @@ var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Effect")); | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -65,8 +66,3 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
const agentLayer = exports.agentLayer = /*#__PURE__*/makeAgentLayer(); | ||
const fromAgent = agent => Client.makeDefault(request => Effect.flatMap(UrlParams.makeUrl(request.url, request.urlParams, _ => Error.RequestError({ | ||
request, | ||
reason: "InvalidUrl", | ||
error: _ | ||
})), url => Effect.suspend(() => { | ||
const controller = new AbortController(); | ||
const fromAgent = agent => Client.makeDefault((request, url, signal) => { | ||
const nodeRequest = url.protocol === "https:" ? Https.request(url, { | ||
@@ -76,3 +72,3 @@ agent: agent.https, | ||
headers: request.headers, | ||
signal: controller.signal | ||
signal | ||
}) : Http.request(url, { | ||
@@ -82,8 +78,8 @@ agent: agent.http, | ||
headers: request.headers, | ||
signal: controller.signal | ||
signal | ||
}); | ||
return (0, _Function.pipe)(Effect.zipRight(sendBody(nodeRequest, request, request.body), waitForResponse(nodeRequest, request), { | ||
concurrent: true | ||
}), Effect.onInterrupt(() => Effect.sync(() => controller.abort())), Effect.map(_ => new ClientResponseImpl(request, _))); | ||
}))); | ||
}), Effect.map(_ => new ClientResponseImpl(request, _))); | ||
}); | ||
const sendBody = (nodeRequest, request, body) => Effect.suspend(() => { | ||
@@ -110,3 +106,3 @@ switch (body._tag) { | ||
try: () => (0, _promises.pipeline)(_nodeStream.Readable.fromWeb(response.body), nodeRequest), | ||
catch: _ => Error.RequestError({ | ||
catch: _ => new Error.RequestError({ | ||
request, | ||
@@ -120,7 +116,7 @@ reason: "Transport", | ||
{ | ||
return Stream.run(Stream.mapError(body.stream, _ => Error.RequestError({ | ||
return Stream.run(Stream.mapError(body.stream, _ => new Error.RequestError({ | ||
request, | ||
reason: "Encode", | ||
error: _ | ||
})), NodeSink.fromWritable(() => nodeRequest, _ => Error.RequestError({ | ||
})), NodeSink.fromWritable(() => nodeRequest, _ => new Error.RequestError({ | ||
request, | ||
@@ -135,3 +131,3 @@ reason: "Transport", | ||
function onError(error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
resume(Effect.fail(new Error.RequestError({ | ||
request, | ||
@@ -157,3 +153,3 @@ reason: "Transport", | ||
function onError(error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
resume(Effect.fail(new Error.RequestError({ | ||
request, | ||
@@ -167,3 +163,3 @@ reason: "Transport", | ||
nodeRequest.off("error", onError); | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
} | ||
@@ -180,3 +176,3 @@ nodeRequest.once("finish", onFinish); | ||
constructor(request, source) { | ||
super(source, _ => Error.ResponseError({ | ||
super(source, _ => new Error.ResponseError({ | ||
request, | ||
@@ -193,2 +189,13 @@ response: this, | ||
} | ||
cachedCookies; | ||
get cookies() { | ||
if (this.cachedCookies !== undefined) { | ||
return this.cachedCookies; | ||
} | ||
const header = this.source.headers["set-cookie"]; | ||
if (Array.isArray(header)) { | ||
return this.cachedCookies = Cookies.fromSetCookie(header); | ||
} | ||
return this.cachedCookies = Cookies.empty; | ||
} | ||
get formData() { | ||
@@ -211,11 +218,8 @@ return Effect.tryPromise({ | ||
} | ||
toString() { | ||
return `ClientResponse(${this.status})`; | ||
} | ||
toJSON() { | ||
return { | ||
_tag: "ClientResponse", | ||
status: this.status, | ||
headers: this.headers | ||
}; | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ClientResponse", | ||
request: this.request.toJSON(), | ||
status: this.status | ||
}); | ||
} | ||
@@ -222,0 +226,0 @@ } |
@@ -12,2 +12,3 @@ "use strict"; | ||
var FiberRef = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/FiberRef")); | ||
var Inspectable = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Inspectable")); | ||
var Option = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Option")); | ||
@@ -34,3 +35,3 @@ var NodeStream = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../NodeStream.js")); | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -42,3 +43,3 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
/** @internal */ | ||
class IncomingMessageImpl { | ||
class IncomingMessageImpl extends Inspectable.Class { | ||
source; | ||
@@ -49,2 +50,3 @@ onError; | ||
constructor(source, onError, remoteAddressOverride) { | ||
super(); | ||
this.source = source; | ||
@@ -72,2 +74,5 @@ this.onError = onError; | ||
} | ||
get unsafeText() { | ||
return Effect.runSync(this.text); | ||
} | ||
get json() { | ||
@@ -79,2 +84,5 @@ return Effect.tryMap(this.text, { | ||
} | ||
get unsafeJson() { | ||
return Effect.runSync(this.json); | ||
} | ||
get urlParamsBody() { | ||
@@ -81,0 +89,0 @@ return Effect.flatMap(this.text, _ => Effect.try({ |
@@ -41,3 +41,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -44,0 +44,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.requestSource = exports.makeHandler = exports.make = exports.layerServer = exports.layerConfig = exports.layer = void 0; | ||
exports.requestSource = exports.makeUpgradeHandler = exports.makeHandler = exports.make = exports.layerServer = exports.layerConfig = exports.layer = void 0; | ||
var Etag = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform-node-shared/Http/Etag")); | ||
@@ -12,16 +12,20 @@ var MultipartNode = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform-node-shared/Http/Multipart")); | ||
var App = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/App")); | ||
var Cookies = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/Cookies")); | ||
var IncomingMessage = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/IncomingMessage")); | ||
var Middleware = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/Middleware")); | ||
var Server = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/Server")); | ||
var Error = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/ServerError")); | ||
var ServerRequest = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Http/ServerRequest")); | ||
var Socket = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Socket")); | ||
var Cause = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Cause")); | ||
var Config = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Config")); | ||
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Effect")); | ||
var FiberSet = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/FiberSet")); | ||
var Layer = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Layer")); | ||
var Option = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Option")); | ||
var Runtime = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Runtime")); | ||
var Scope = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Scope")); | ||
var Stream = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Stream")); | ||
var Http = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("node:http")); | ||
var _nodeStream = /*#__PURE__*/require("node:stream"); | ||
var _promises = /*#__PURE__*/require("node:stream/promises"); | ||
var WS = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("ws")); | ||
var NodeContext = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../NodeContext.js")); | ||
@@ -50,3 +54,3 @@ var NodeSink = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../NodeSink.js")); | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -59,3 +63,7 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
const make = (evaluate, options) => Effect.gen(function* (_) { | ||
const server = yield* _(Effect.acquireRelease(Effect.sync(evaluate), server => Effect.async(resume => { | ||
const scope = yield* Effect.scope; | ||
const server = yield* Effect.acquireRelease(Effect.sync(evaluate), server => Effect.async(resume => { | ||
if (!server.listening) { | ||
return resume(Effect.void); | ||
} | ||
server.close(error => { | ||
@@ -65,17 +73,24 @@ if (error) { | ||
} else { | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
} | ||
}); | ||
}))); | ||
yield* _(Effect.async(resume => { | ||
server.on("error", error => { | ||
resume(Effect.fail(Error.ServeError({ | ||
})); | ||
yield* Effect.async(resume => { | ||
function onError(error) { | ||
resume(Effect.fail(new Error.ServeError({ | ||
error | ||
}))); | ||
}); | ||
} | ||
server.on("error", onError); | ||
server.listen(options, () => { | ||
resume(Effect.unit); | ||
server.off("error", onError); | ||
resume(Effect.void); | ||
}); | ||
})); | ||
}); | ||
const address = server.address(); | ||
const wss = yield* _(Effect.acquireRelease(Effect.sync(() => new WS.WebSocketServer({ | ||
noServer: true | ||
})), wss => Effect.async(resume => { | ||
wss.close(() => resume(Effect.void)); | ||
})), Scope.extend(scope), Effect.cached); | ||
return Server.make({ | ||
@@ -92,6 +107,9 @@ address: typeof address === "string" ? { | ||
const handler = yield* _(makeHandler(httpApp, middleware)); | ||
const upgradeHandler = yield* _(makeUpgradeHandler(wss, httpApp, middleware)); | ||
yield* _(Effect.addFinalizer(() => Effect.sync(() => { | ||
server.off("request", handler); | ||
server.off("upgrade", upgradeHandler); | ||
}))); | ||
server.on("request", handler); | ||
server.on("upgrade", upgradeHandler); | ||
}) | ||
@@ -103,22 +121,58 @@ }); | ||
const makeHandler = (httpApp, middleware) => { | ||
const handledApp = Effect.scoped(middleware ? middleware(App.withDefaultMiddleware(respond(httpApp))) : App.withDefaultMiddleware(respond(httpApp))); | ||
return Effect.map(Effect.runtime(), runtime => { | ||
const runFork = Runtime.runFork(runtime); | ||
return function handler(nodeRequest, nodeResponse) { | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse))); | ||
nodeResponse.on("close", () => { | ||
if (!nodeResponse.writableEnded) { | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(499); | ||
} | ||
nodeResponse.end(); | ||
runFork(fiber.interruptAsFork(Error.clientAbortFiberId)); | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause(handleResponse(request, exit.value), cause => handleCause(request, cause)); | ||
} | ||
return handleCause(request, exit.cause); | ||
}, middleware); | ||
return Effect.map(FiberSet.makeRuntime(), runFork => function handler(nodeRequest, nodeResponse) { | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse))); | ||
nodeResponse.on("close", () => { | ||
if (!nodeResponse.writableEnded) { | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(499); | ||
} | ||
}); | ||
nodeResponse.end(); | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** @internal */ | ||
exports.makeHandler = makeHandler; | ||
const makeUpgradeHandler = (lazyWss, httpApp, middleware) => { | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause(handleResponse(request, exit.value), cause => handleCause(request, cause)); | ||
} | ||
return handleCause(request, exit.cause); | ||
}, middleware); | ||
return Effect.map(FiberSet.makeRuntime(), runFork => function handler(nodeRequest, socket, head) { | ||
let nodeResponse_ = undefined; | ||
const nodeResponse = () => { | ||
if (nodeResponse_ === undefined) { | ||
nodeResponse_ = new Http.ServerResponse(nodeRequest); | ||
nodeResponse_.assignSocket(socket); | ||
} | ||
return nodeResponse_; | ||
}; | ||
const upgradeEffect = Socket.fromWebSocket(Effect.flatMap(lazyWss, wss => Effect.acquireRelease(Effect.async(resume => wss.handleUpgrade(nodeRequest, socket, head, ws => { | ||
resume(Effect.succeed(ws)); | ||
})), ws => Effect.sync(() => ws.close())))); | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect))); | ||
socket.on("close", () => { | ||
const res = nodeResponse(); | ||
if (!socket.writableEnded) { | ||
if (!res.headersSent) { | ||
res.writeHead(499); | ||
} | ||
res.end(); | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId); | ||
} | ||
}); | ||
}); | ||
}; | ||
exports.makeHandler = makeHandler; | ||
const respond = /*#__PURE__*/Middleware.make(httpApp => Effect.uninterruptibleMask(restore => Effect.flatMap(ServerRequest.ServerRequest, request => Effect.tapErrorCause(restore(Effect.tap(Effect.flatMap(httpApp, response => Effect.flatMap(App.preResponseHandler, f => f(request, response))), response => handleResponse(request, response))), cause => Effect.sync(() => { | ||
const nodeResponse = request.response; | ||
exports.makeUpgradeHandler = makeUpgradeHandler; | ||
const handleCause = (request, cause) => Effect.sync(() => { | ||
const nodeResponse = request.resolvedResponse; | ||
if (!nodeResponse.headersSent) { | ||
@@ -130,11 +184,12 @@ nodeResponse.writeHead(Cause.isInterruptedOnly(cause) ? 503 : 500); | ||
} | ||
}))))); | ||
}); | ||
class ServerRequestImpl extends _incomingMessage.IncomingMessageImpl { | ||
source; | ||
response; | ||
upgradeEffect; | ||
url; | ||
headersOverride; | ||
[ServerRequest.TypeId]; | ||
constructor(source, response, url = source.url, headersOverride, remoteAddressOverride) { | ||
super(source, _ => Error.RequestError({ | ||
constructor(source, response, upgradeEffect, url = source.url, headersOverride, remoteAddressOverride) { | ||
super(source, _ => new Error.RequestError({ | ||
request: this, | ||
@@ -146,2 +201,3 @@ reason: "Decode", | ||
this.response = response; | ||
this.upgradeEffect = upgradeEffect; | ||
this.url = url; | ||
@@ -151,4 +207,14 @@ this.headersOverride = headersOverride; | ||
} | ||
cachedCookies; | ||
get cookies() { | ||
if (this.cachedCookies) { | ||
return this.cachedCookies; | ||
} | ||
return this.cachedCookies = Cookies.parseHeader(this.headers.cookie ?? ""); | ||
} | ||
get resolvedResponse() { | ||
return typeof this.response === "function" ? this.response() : this.response; | ||
} | ||
modify(options) { | ||
return new ServerRequestImpl(this.source, this.response, options.url ?? this.url, options.headers ?? this.headersOverride, options.remoteAddress ?? this.remoteAddressOverride); | ||
return new ServerRequestImpl(this.source, this.response, this.upgradeEffect, options.url ?? this.url, options.headers ?? this.headersOverride, options.remoteAddress ?? this.remoteAddressOverride); | ||
} | ||
@@ -176,2 +242,9 @@ get originalUrl() { | ||
} | ||
get upgrade() { | ||
return this.upgradeEffect ?? Effect.fail(new Error.RequestError({ | ||
request: this, | ||
reason: "Decode", | ||
error: "not an upgradeable ServerRequest" | ||
})); | ||
} | ||
toString() { | ||
@@ -181,9 +254,7 @@ return `ServerRequest(${this.method} ${this.url})`; | ||
toJSON() { | ||
return { | ||
_tag: "ServerRequest", | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ServerRequest", | ||
method: this.method, | ||
url: this.url, | ||
originalUrl: this.originalUrl, | ||
headers: this.headers | ||
}; | ||
url: this.originalUrl | ||
}); | ||
} | ||
@@ -201,7 +272,22 @@ } | ||
const handleResponse = (request, response) => Effect.suspend(() => { | ||
const nodeResponse = request.response; | ||
const nodeResponse = request.resolvedResponse; | ||
if (nodeResponse.writableEnded) { | ||
return Effect.void; | ||
} | ||
let headers = response.headers; | ||
if (!Cookies.isEmpty(response.cookies)) { | ||
headers = { | ||
...headers | ||
}; | ||
const toSet = Cookies.toSetCookieHeaders(response.cookies); | ||
if (headers["set-cookie"] !== undefined) { | ||
toSet.push(headers["set-cookie"]); | ||
} | ||
headers["set-cookie"] = toSet; | ||
} | ||
if (request.method === "HEAD") { | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(() => resume(Effect.void)); | ||
}); | ||
} | ||
@@ -212,9 +298,10 @@ const body = response.body; | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(() => resume(Effect.void)); | ||
}); | ||
} | ||
case "Raw": | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.writeHead(response.status, headers); | ||
if (typeof body.body === "object" && body.body !== null && "pipe" in body.body && typeof body.body.pipe === "function") { | ||
@@ -226,3 +313,3 @@ return Effect.tryPromise({ | ||
}), | ||
catch: error => Error.ResponseError({ | ||
catch: error => new Error.ResponseError({ | ||
request, | ||
@@ -235,30 +322,35 @@ response, | ||
} | ||
nodeResponse.end(body.body); | ||
return Effect.unit; | ||
return Effect.async(resume => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)); | ||
}); | ||
} | ||
case "Uint8Array": | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(body.body); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)); | ||
}); | ||
} | ||
case "FormData": | ||
{ | ||
return Effect.async(resume => { | ||
return Effect.suspend(() => { | ||
const r = new Response(body.formData); | ||
const headers = { | ||
...response.headers, | ||
nodeResponse.writeHead(response.status, { | ||
...headers, | ||
...Object.fromEntries(r.headers) | ||
}; | ||
nodeResponse.writeHead(response.status, headers); | ||
_nodeStream.Readable.fromWeb(r.body).pipe(nodeResponse).on("error", error => { | ||
resume(Effect.fail(Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}))); | ||
}).once("finish", () => { | ||
resume(Effect.unit); | ||
}); | ||
return Effect.async((resume, signal) => { | ||
_nodeStream.Readable.fromWeb(r.body, { | ||
signal | ||
}).pipe(nodeResponse).on("error", error => { | ||
resume(Effect.fail(new Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}))); | ||
}).once("finish", () => { | ||
resume(Effect.void); | ||
}); | ||
}).pipe(Effect.interruptible); | ||
}); | ||
@@ -268,4 +360,4 @@ } | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
return Stream.run(Stream.mapError(body.stream, error => Error.ResponseError({ | ||
nodeResponse.writeHead(response.status, headers); | ||
return Stream.run(Stream.mapError(body.stream, error => new Error.ResponseError({ | ||
request, | ||
@@ -275,3 +367,3 @@ response, | ||
error | ||
})), NodeSink.fromWritable(() => nodeResponse, error => Error.ResponseError({ | ||
})), NodeSink.fromWritable(() => nodeResponse, error => new Error.ResponseError({ | ||
request, | ||
@@ -281,3 +373,3 @@ response, | ||
error | ||
}))); | ||
}))).pipe(Effect.interruptible); | ||
} | ||
@@ -284,0 +376,0 @@ } |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.makePoolSerializedLayer = exports.makePoolSerialized = exports.makePoolLayer = exports.makePool = exports.layerWorker = exports.layerManager = void 0; | ||
exports.layerWorker = exports.layerManager = exports.layer = void 0; | ||
var Worker = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/Worker")); | ||
@@ -33,3 +33,3 @@ var _WorkerError = /*#__PURE__*/require("@effect/platform/WorkerError"); | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -47,3 +47,3 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
worker.once("exit", () => { | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
}); | ||
@@ -59,9 +59,18 @@ worker.postMessage([1]); | ||
worker.on("messageerror", error => { | ||
resume(Effect.fail((0, _WorkerError.WorkerError)("decode", error.message, error.stack))); | ||
resume(new _WorkerError.WorkerError({ | ||
reason: "decode", | ||
error | ||
})); | ||
}); | ||
worker.on("error", error => { | ||
resume(Effect.fail((0, _WorkerError.WorkerError)("unknown", error.message, error.stack))); | ||
resume(new _WorkerError.WorkerError({ | ||
reason: "unknown", | ||
error | ||
})); | ||
}); | ||
worker.on("exit", code => { | ||
resume(Effect.fail((0, _WorkerError.WorkerError)("unknown", new Error(`exited with code ${code}`)))); | ||
resume(new _WorkerError.WorkerError({ | ||
reason: "unknown", | ||
error: new Error(`exited with code ${code}`) | ||
})); | ||
}); | ||
@@ -71,3 +80,6 @@ }), Effect.interruptible, Effect.forkScoped); | ||
try: () => worker.postMessage([0, message], transfers), | ||
catch: error => (0, _WorkerError.WorkerError)("send", error.message, error.stack) | ||
catch: error => new _WorkerError.WorkerError({ | ||
reason: "send", | ||
error | ||
}) | ||
}); | ||
@@ -87,9 +99,4 @@ return { | ||
/** @internal */ | ||
const makePool = exports.makePool = /*#__PURE__*/Worker.makePool(); | ||
/** @internal */ | ||
const makePoolLayer = exports.makePoolLayer = /*#__PURE__*/Worker.makePoolLayer(layerManager); | ||
/** @internal */ | ||
const makePoolSerialized = exports.makePoolSerialized = /*#__PURE__*/Worker.makePoolSerialized(); | ||
/** @internal */ | ||
const makePoolSerializedLayer = exports.makePoolSerializedLayer = /*#__PURE__*/Worker.makePoolSerializedLayer(layerManager); | ||
const layer = spawn => Layer.merge(layerManager, Worker.layerSpawner(spawn)); | ||
exports.layer = layer; | ||
//# sourceMappingURL=worker.js.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.layerSerialized = exports.layerPlatform = exports.layer = void 0; | ||
exports.layer = void 0; | ||
var _WorkerError = /*#__PURE__*/require("@effect/platform/WorkerError"); | ||
@@ -35,3 +35,3 @@ var Runner = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/platform/WorkerRunner")); | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -47,3 +47,6 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
if (!WorkerThreads.parentPort) { | ||
return yield* _(Effect.fail((0, _WorkerError.WorkerError)("spawn", "not in worker"))); | ||
return yield* _(new _WorkerError.WorkerError({ | ||
reason: "spawn", | ||
error: new Error("not in worker") | ||
})); | ||
} | ||
@@ -55,3 +58,3 @@ const port = WorkerThreads.parentPort; | ||
if (message[0] === 0) { | ||
queue.unsafeOffer(message[1]); | ||
queue.unsafeOffer([0, message[1]]); | ||
} else { | ||
@@ -62,12 +65,18 @@ Effect.runFork(shutdown); | ||
port.on("messageerror", error => { | ||
resume(Effect.fail((0, _WorkerError.WorkerError)("decode", error.message, error.stack))); | ||
resume(new _WorkerError.WorkerError({ | ||
reason: "decode", | ||
error | ||
})); | ||
}); | ||
port.on("error", error => { | ||
resume(Effect.fail((0, _WorkerError.WorkerError)("unknown", error.message, error.stack))); | ||
resume(new _WorkerError.WorkerError({ | ||
reason: "unknown", | ||
error | ||
})); | ||
}); | ||
}), Effect.tapErrorCause(cause => Cause.isInterruptedOnly(cause) ? Effect.unit : Effect.logDebug(cause)), Effect.retry(Schedule.forever), Effect.annotateLogs({ | ||
}), Effect.tapErrorCause(cause => Cause.isInterruptedOnly(cause) ? Effect.void : Effect.logDebug(cause)), Effect.retry(Schedule.forever), Effect.annotateLogs({ | ||
package: "@effect/platform-node", | ||
module: "WorkerRunner" | ||
}), Effect.interruptible, Effect.forkScoped); | ||
const send = (message, transfers) => Effect.sync(() => port.postMessage([1, message], transfers)); | ||
const send = (_portId, message, transfers) => Effect.sync(() => port.postMessage([1, message], transfers)); | ||
// ready | ||
@@ -83,9 +92,3 @@ port.postMessage([0]); | ||
/** @internal */ | ||
const layerPlatform = exports.layerPlatform = /*#__PURE__*/Layer.succeed(Runner.PlatformRunner, platformRunnerImpl); | ||
/** @internal */ | ||
const layer = (process, options) => Layer.provide(Runner.layer(process, options), layerPlatform); | ||
/** @internal */ | ||
exports.layer = layer; | ||
const layerSerialized = (schema, handlers) => Layer.provide(Runner.layerSerialized(schema, handlers), layerPlatform); | ||
exports.layerSerialized = layerSerialized; | ||
const layer = exports.layer = /*#__PURE__*/Layer.succeed(Runner.PlatformRunner, platformRunnerImpl); | ||
//# sourceMappingURL=workerRunner.js.map |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -33,3 +33,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -36,0 +36,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -6,4 +6,5 @@ "use strict"; | ||
}); | ||
exports.makeAgentLayer = exports.makeAgent = exports.make = exports.layerWithoutAgent = exports.layer = exports.agentLayer = exports.HttpAgentTypeId = exports.HttpAgent = void 0; | ||
exports.withUndiciOptions = exports.makeUndici = exports.makeDispatcher = exports.makeAgentLayer = exports.makeAgent = exports.make = exports.layerWithoutAgent = exports.layerUndiciWithoutDispatcher = exports.layerUndici = exports.layer = exports.dispatcherLayerGlobal = exports.dispatcherLayer = exports.currentUndiciOptions = exports.agentLayer = exports.HttpAgentTypeId = exports.HttpAgent = exports.Dispatcher = void 0; | ||
var internal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/http/client.js")); | ||
var internalUndici = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/http/clientUndici.js")); | ||
function _getRequireWildcardCache(e) { | ||
@@ -28,3 +29,3 @@ if ("function" != typeof WeakMap) return null; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -75,2 +76,47 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
const layerWithoutAgent = exports.layerWithoutAgent = internal.layerWithoutAgent; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const Dispatcher = exports.Dispatcher = internalUndici.Dispatcher; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const makeDispatcher = exports.makeDispatcher = internalUndici.makeDispatcher; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const dispatcherLayer = exports.dispatcherLayer = internalUndici.dispatcherLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const dispatcherLayerGlobal = exports.dispatcherLayerGlobal = internalUndici.dispatcherLayerGlobal; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const currentUndiciOptions = exports.currentUndiciOptions = internalUndici.currentUndiciOptions; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
const withUndiciOptions = exports.withUndiciOptions = internalUndici.withUndiciOptions; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
const makeUndici = exports.makeUndici = internalUndici.make; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
const layerUndici = exports.layerUndici = internalUndici.layer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
const layerUndiciWithoutDispatcher = exports.layerUndiciWithoutDispatcher = internalUndici.layerWithoutDispatcher; | ||
//# sourceMappingURL=NodeHttpClient.js.map |
@@ -34,3 +34,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -37,0 +37,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -27,3 +27,3 @@ "use strict"; | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -30,0 +30,0 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.makePoolSerializedLayer = exports.makePoolSerialized = exports.makePoolLayer = exports.makePool = exports.layerWorker = exports.layerManager = void 0; | ||
exports.layerWorker = exports.layerManager = exports.layer = void 0; | ||
var internal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/worker.js")); | ||
@@ -28,3 +28,3 @@ function _getRequireWildcardCache(e) { | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -37,25 +37,10 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
* @since 1.0.0 | ||
* @category constructors | ||
* @category layers | ||
*/ | ||
const makePool = exports.makePool = internal.makePool; | ||
const layerManager = exports.layerManager = internal.layerManager; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
const makePoolLayer = exports.makePoolLayer = internal.makePoolLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
const makePoolSerialized = exports.makePoolSerialized = internal.makePoolSerialized; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
const makePoolSerializedLayer = exports.makePoolSerializedLayer = internal.makePoolSerializedLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
const layerManager = exports.layerManager = internal.layerManager; | ||
const layerWorker = exports.layerWorker = internal.layerWorker; | ||
/** | ||
@@ -65,3 +50,3 @@ * @since 1.0.0 | ||
*/ | ||
const layerWorker = exports.layerWorker = internal.layerWorker; | ||
const layer = exports.layer = internal.layer; | ||
//# sourceMappingURL=NodeWorker.js.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.layerSerialized = exports.layerPlatform = exports.layer = void 0; | ||
exports.layer = void 0; | ||
var internal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/workerRunner.js")); | ||
@@ -28,3 +28,3 @@ function _getRequireWildcardCache(e) { | ||
a = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { | ||
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { | ||
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; | ||
@@ -39,13 +39,3 @@ i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; | ||
*/ | ||
const layerPlatform = exports.layerPlatform = internal.layerPlatform; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
const layer = exports.layer = internal.layer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
const layerSerialized = exports.layerSerialized = internal.layerSerialized; | ||
//# sourceMappingURL=NodeWorkerRunner.js.map |
@@ -32,4 +32,4 @@ /// <reference types="node" resolution-mode="require"/> | ||
export declare const makeHandler: { | ||
<R, E>(httpApp: App.Default<R, E>): Effect.Effect<Exclude<R, Scope.Scope | ServerRequest.ServerRequest>, never, (nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void>; | ||
<R, E, App extends App.Default<any, any>>(httpApp: App.Default<R, E>, middleware: Middleware.Middleware.Applied<R, E, App>): Effect.Effect<Exclude<Effect.Effect.Context<App>, Scope.Scope | ServerRequest.ServerRequest>, never, (nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void>; | ||
<R, E>(httpApp: App.Default<E, R>): Effect.Effect<(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void, never, Exclude<R, Scope.Scope | ServerRequest.ServerRequest>>; | ||
<R, E, App extends App.Default<any, any>>(httpApp: App.Default<E, R>, middleware: Middleware.Middleware.Applied<App, E, R>): Effect.Effect<(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void, never, Exclude<Effect.Effect.Context<App>, Scope.Scope | ServerRequest.ServerRequest>>; | ||
}; | ||
@@ -45,3 +45,3 @@ /** | ||
*/ | ||
export declare const layer: (evaluate: LazyArg<Http.Server>, options: Net.ListenOptions) => Layer.Layer<Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, ServeError>; | ||
export declare const layer: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Net.ListenOptions) => Layer.Layer<Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, ServeError>; | ||
/** | ||
@@ -51,3 +51,3 @@ * @since 1.0.0 | ||
*/ | ||
export declare const layerConfig: (evaluate: LazyArg<Http.Server>, options: Config.Config.Wrap<Net.ListenOptions>) => Layer.Layer<Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, ServeError | ConfigError.ConfigError>; | ||
export declare const layerConfig: (evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, options: Config.Config.Wrap<Net.ListenOptions>) => Layer.Layer<Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, ConfigError.ConfigError | ServeError>; | ||
//# sourceMappingURL=Server.d.ts.map |
@@ -40,2 +40,6 @@ /** | ||
*/ | ||
export * as NodeSocket from "./NodeSocket.js"; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export * as NodeStream from "./NodeStream.js"; | ||
@@ -42,0 +46,0 @@ /** |
@@ -9,2 +9,3 @@ /// <reference types="node" resolution-mode="require"/> | ||
import type * as Effect from "effect/Effect"; | ||
import type * as FiberRef from "effect/FiberRef"; | ||
import type * as Layer from "effect/Layer"; | ||
@@ -14,2 +15,3 @@ import type * as Scope from "effect/Scope"; | ||
import type * as Https from "node:https"; | ||
import type * as Undici from "undici"; | ||
/** | ||
@@ -69,2 +71,57 @@ * @since 1.0.0 | ||
export declare const layerWithoutAgent: Layer.Layer<Client.Client.Default, never, HttpAgent>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export interface Dispatcher { | ||
readonly _: unique symbol; | ||
} | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const Dispatcher: Context.Tag<Dispatcher, Undici.Dispatcher>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const makeDispatcher: Effect.Effect<Undici.Dispatcher, never, Scope.Scope>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const dispatcherLayer: Layer.Layer<Dispatcher>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const dispatcherLayerGlobal: Layer.Layer<Dispatcher>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const currentUndiciOptions: FiberRef.FiberRef<Partial<Undici.Dispatcher.RequestOptions>>; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export declare const withUndiciOptions: { | ||
(options: Partial<Undici.Dispatcher.RequestOptions>): <R, E, A>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>; | ||
<R, E, A>(effect: Effect.Effect<A, E, R>, options: Partial<Undici.Dispatcher.RequestOptions>): Effect.Effect<A, E, R>; | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export declare const makeUndici: (dispatcher: Undici.Dispatcher) => Client.Client.Default; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export declare const layerUndici: Layer.Layer<Client.Client.Default>; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export declare const layerUndiciWithoutDispatcher: Layer.Layer<Client.Client.Default, never, Dispatcher>; | ||
//# sourceMappingURL=NodeHttpClient.d.ts.map |
@@ -6,33 +6,14 @@ /// <reference types="node" resolution-mode="require"/> | ||
import type * as Worker from "@effect/platform/Worker"; | ||
import type * as Schema from "@effect/schema/Schema"; | ||
import type * as Context from "effect/Context"; | ||
import type * as Effect from "effect/Effect"; | ||
import type * as Layer from "effect/Layer"; | ||
import type * as Scope from "effect/Scope"; | ||
import type * as WorkerThreads from "node:worker_threads"; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
* @category layers | ||
*/ | ||
export declare const makePool: <I, E, O>(options: Worker.WorkerPool.Options<I, WorkerThreads.Worker>) => Effect.Effect<Worker.WorkerPool<I, E, O>, never, Worker.WorkerManager | Scope.Scope>; | ||
export declare const layerManager: Layer.Layer<Worker.WorkerManager>; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export declare const makePoolLayer: <Tag, I, E, O>(tag: Context.Tag<Tag, Worker.WorkerPool<I, E, O>>, options: Worker.WorkerPool.Options<I, WorkerThreads.Worker>) => Layer.Layer<Tag>; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export declare const makePoolSerialized: <I extends Schema.TaggedRequest.Any>(options: Worker.SerializedWorkerPool.Options<I, WorkerThreads.Worker>) => Effect.Effect<Worker.SerializedWorkerPool<I>, never, Worker.WorkerManager | Scope.Scope>; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export declare const makePoolSerializedLayer: <Tag, I extends Schema.TaggedRequest.Any>(tag: Context.Tag<Tag, Worker.SerializedWorkerPool<I>>, options: Worker.SerializedWorkerPool.Options<I, WorkerThreads.Worker>) => Layer.Layer<Tag>; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export declare const layerManager: Layer.Layer<Worker.WorkerManager>; | ||
export declare const layerWorker: Layer.Layer<Worker.PlatformWorker>; | ||
/** | ||
@@ -42,3 +23,3 @@ * @since 1.0.0 | ||
*/ | ||
export declare const layerWorker: Layer.Layer<Worker.PlatformWorker>; | ||
export declare const layer: (spawn: (id: number) => WorkerThreads.Worker) => Layer.Layer<Worker.WorkerManager | Worker.Spawner, never, never>; | ||
//# sourceMappingURL=NodeWorker.d.ts.map |
/** | ||
* @since 1.0.0 | ||
*/ | ||
import type { WorkerError } from "@effect/platform/WorkerError"; | ||
import type * as Runner from "@effect/platform/WorkerRunner"; | ||
import type * as Schema from "@effect/schema/Schema"; | ||
import type * as Layer from "effect/Layer"; | ||
import type * as Stream from "effect/Stream"; | ||
/** | ||
@@ -13,13 +10,3 @@ * @since 1.0.0 | ||
*/ | ||
export declare const layerPlatform: Layer.Layer<Runner.PlatformRunner>; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export declare const layer: <I, R, E, O>(process: (request: I) => Stream.Stream<O, E, R>, options?: Runner.Runner.Options<I, E, O> | undefined) => Layer.Layer<never, WorkerError, R>; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export declare const layerSerialized: <A extends Schema.TaggedRequest.Any, I, R, Handlers extends Runner.SerializedRunner.Handlers<A>>(schema: Schema.Schema<A, I, R>, handlers: Handlers) => Layer.Layer<never, WorkerError, R | Runner.SerializedRunner.HandlersContext<Handlers>>; | ||
export declare const layer: Layer.Layer<Runner.PlatformRunner>; | ||
//# sourceMappingURL=NodeWorkerRunner.d.ts.map |
@@ -40,2 +40,6 @@ /** | ||
*/ | ||
export * as NodeSocket from "./NodeSocket.js"; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export * as NodeStream from "./NodeStream.js"; | ||
@@ -42,0 +46,0 @@ /** |
import * as Client from "@effect/platform/Http/Client"; | ||
import * as Error from "@effect/platform/Http/ClientError"; | ||
import * as ClientResponse from "@effect/platform/Http/ClientResponse"; | ||
import * as UrlParams from "@effect/platform/Http/UrlParams"; | ||
import * as Cookies from "@effect/platform/Http/Cookies"; | ||
import * as IncomingMessage from "@effect/platform/Http/IncomingMessage"; | ||
import * as Context from "effect/Context"; | ||
@@ -30,8 +31,3 @@ import * as Effect from "effect/Effect"; | ||
export const agentLayer = /*#__PURE__*/makeAgentLayer(); | ||
const fromAgent = agent => Client.makeDefault(request => Effect.flatMap(UrlParams.makeUrl(request.url, request.urlParams, _ => Error.RequestError({ | ||
request, | ||
reason: "InvalidUrl", | ||
error: _ | ||
})), url => Effect.suspend(() => { | ||
const controller = new AbortController(); | ||
const fromAgent = agent => Client.makeDefault((request, url, signal) => { | ||
const nodeRequest = url.protocol === "https:" ? Https.request(url, { | ||
@@ -41,3 +37,3 @@ agent: agent.https, | ||
headers: request.headers, | ||
signal: controller.signal | ||
signal | ||
}) : Http.request(url, { | ||
@@ -47,8 +43,8 @@ agent: agent.http, | ||
headers: request.headers, | ||
signal: controller.signal | ||
signal | ||
}); | ||
return pipe(Effect.zipRight(sendBody(nodeRequest, request, request.body), waitForResponse(nodeRequest, request), { | ||
concurrent: true | ||
}), Effect.onInterrupt(() => Effect.sync(() => controller.abort())), Effect.map(_ => new ClientResponseImpl(request, _))); | ||
}))); | ||
}), Effect.map(_ => new ClientResponseImpl(request, _))); | ||
}); | ||
const sendBody = (nodeRequest, request, body) => Effect.suspend(() => { | ||
@@ -75,3 +71,3 @@ switch (body._tag) { | ||
try: () => pipeline(Readable.fromWeb(response.body), nodeRequest), | ||
catch: _ => Error.RequestError({ | ||
catch: _ => new Error.RequestError({ | ||
request, | ||
@@ -85,7 +81,7 @@ reason: "Transport", | ||
{ | ||
return Stream.run(Stream.mapError(body.stream, _ => Error.RequestError({ | ||
return Stream.run(Stream.mapError(body.stream, _ => new Error.RequestError({ | ||
request, | ||
reason: "Encode", | ||
error: _ | ||
})), NodeSink.fromWritable(() => nodeRequest, _ => Error.RequestError({ | ||
})), NodeSink.fromWritable(() => nodeRequest, _ => new Error.RequestError({ | ||
request, | ||
@@ -100,3 +96,3 @@ reason: "Transport", | ||
function onError(error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
resume(Effect.fail(new Error.RequestError({ | ||
request, | ||
@@ -122,3 +118,3 @@ reason: "Transport", | ||
function onError(error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
resume(Effect.fail(new Error.RequestError({ | ||
request, | ||
@@ -132,3 +128,3 @@ reason: "Transport", | ||
nodeRequest.off("error", onError); | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
} | ||
@@ -145,3 +141,3 @@ nodeRequest.once("finish", onFinish); | ||
constructor(request, source) { | ||
super(source, _ => Error.ResponseError({ | ||
super(source, _ => new Error.ResponseError({ | ||
request, | ||
@@ -158,2 +154,13 @@ response: this, | ||
} | ||
cachedCookies; | ||
get cookies() { | ||
if (this.cachedCookies !== undefined) { | ||
return this.cachedCookies; | ||
} | ||
const header = this.source.headers["set-cookie"]; | ||
if (Array.isArray(header)) { | ||
return this.cachedCookies = Cookies.fromSetCookie(header); | ||
} | ||
return this.cachedCookies = Cookies.empty; | ||
} | ||
get formData() { | ||
@@ -176,11 +183,8 @@ return Effect.tryPromise({ | ||
} | ||
toString() { | ||
return `ClientResponse(${this.status})`; | ||
} | ||
toJSON() { | ||
return { | ||
_tag: "ClientResponse", | ||
status: this.status, | ||
headers: this.headers | ||
}; | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ClientResponse", | ||
request: this.request.toJSON(), | ||
status: this.status | ||
}); | ||
} | ||
@@ -187,0 +191,0 @@ } |
@@ -6,6 +6,7 @@ import * as Headers from "@effect/platform/Http/Headers"; | ||
import * as FiberRef from "effect/FiberRef"; | ||
import * as Inspectable from "effect/Inspectable"; | ||
import * as Option from "effect/Option"; | ||
import * as NodeStream from "../../NodeStream.js"; | ||
/** @internal */ | ||
export class IncomingMessageImpl { | ||
export class IncomingMessageImpl extends Inspectable.Class { | ||
source; | ||
@@ -16,2 +17,3 @@ onError; | ||
constructor(source, onError, remoteAddressOverride) { | ||
super(); | ||
this.source = source; | ||
@@ -39,2 +41,5 @@ this.onError = onError; | ||
} | ||
get unsafeText() { | ||
return Effect.runSync(this.text); | ||
} | ||
get json() { | ||
@@ -46,2 +51,5 @@ return Effect.tryMap(this.text, { | ||
} | ||
get unsafeJson() { | ||
return Effect.runSync(this.json); | ||
} | ||
get urlParamsBody() { | ||
@@ -48,0 +56,0 @@ return Effect.flatMap(this.text, _ => Effect.try({ |
@@ -5,16 +5,20 @@ import * as Etag from "@effect/platform-node-shared/Http/Etag"; | ||
import * as App from "@effect/platform/Http/App"; | ||
import * as Cookies from "@effect/platform/Http/Cookies"; | ||
import * as IncomingMessage from "@effect/platform/Http/IncomingMessage"; | ||
import * as Middleware from "@effect/platform/Http/Middleware"; | ||
import * as Server from "@effect/platform/Http/Server"; | ||
import * as Error from "@effect/platform/Http/ServerError"; | ||
import * as ServerRequest from "@effect/platform/Http/ServerRequest"; | ||
import * as Socket from "@effect/platform/Socket"; | ||
import * as Cause from "effect/Cause"; | ||
import * as Config from "effect/Config"; | ||
import * as Effect from "effect/Effect"; | ||
import * as FiberSet from "effect/FiberSet"; | ||
import * as Layer from "effect/Layer"; | ||
import * as Option from "effect/Option"; | ||
import * as Runtime from "effect/Runtime"; | ||
import * as Scope from "effect/Scope"; | ||
import * as Stream from "effect/Stream"; | ||
import * as Http from "node:http"; | ||
import { Readable } from "node:stream"; | ||
import { pipeline } from "node:stream/promises"; | ||
import * as WS from "ws"; | ||
import * as NodeContext from "../../NodeContext.js"; | ||
@@ -26,3 +30,7 @@ import * as NodeSink from "../../NodeSink.js"; | ||
export const make = (evaluate, options) => Effect.gen(function* (_) { | ||
const server = yield* _(Effect.acquireRelease(Effect.sync(evaluate), server => Effect.async(resume => { | ||
const scope = yield* Effect.scope; | ||
const server = yield* Effect.acquireRelease(Effect.sync(evaluate), server => Effect.async(resume => { | ||
if (!server.listening) { | ||
return resume(Effect.void); | ||
} | ||
server.close(error => { | ||
@@ -32,17 +40,24 @@ if (error) { | ||
} else { | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
} | ||
}); | ||
}))); | ||
yield* _(Effect.async(resume => { | ||
server.on("error", error => { | ||
resume(Effect.fail(Error.ServeError({ | ||
})); | ||
yield* Effect.async(resume => { | ||
function onError(error) { | ||
resume(Effect.fail(new Error.ServeError({ | ||
error | ||
}))); | ||
}); | ||
} | ||
server.on("error", onError); | ||
server.listen(options, () => { | ||
resume(Effect.unit); | ||
server.off("error", onError); | ||
resume(Effect.void); | ||
}); | ||
})); | ||
}); | ||
const address = server.address(); | ||
const wss = yield* _(Effect.acquireRelease(Effect.sync(() => new WS.WebSocketServer({ | ||
noServer: true | ||
})), wss => Effect.async(resume => { | ||
wss.close(() => resume(Effect.void)); | ||
})), Scope.extend(scope), Effect.cached); | ||
return Server.make({ | ||
@@ -59,6 +74,9 @@ address: typeof address === "string" ? { | ||
const handler = yield* _(makeHandler(httpApp, middleware)); | ||
const upgradeHandler = yield* _(makeUpgradeHandler(wss, httpApp, middleware)); | ||
yield* _(Effect.addFinalizer(() => Effect.sync(() => { | ||
server.off("request", handler); | ||
server.off("upgrade", upgradeHandler); | ||
}))); | ||
server.on("request", handler); | ||
server.on("upgrade", upgradeHandler); | ||
}) | ||
@@ -69,21 +87,56 @@ }); | ||
export const makeHandler = (httpApp, middleware) => { | ||
const handledApp = Effect.scoped(middleware ? middleware(App.withDefaultMiddleware(respond(httpApp))) : App.withDefaultMiddleware(respond(httpApp))); | ||
return Effect.map(Effect.runtime(), runtime => { | ||
const runFork = Runtime.runFork(runtime); | ||
return function handler(nodeRequest, nodeResponse) { | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse))); | ||
nodeResponse.on("close", () => { | ||
if (!nodeResponse.writableEnded) { | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(499); | ||
} | ||
nodeResponse.end(); | ||
runFork(fiber.interruptAsFork(Error.clientAbortFiberId)); | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause(handleResponse(request, exit.value), cause => handleCause(request, cause)); | ||
} | ||
return handleCause(request, exit.cause); | ||
}, middleware); | ||
return Effect.map(FiberSet.makeRuntime(), runFork => function handler(nodeRequest, nodeResponse) { | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse))); | ||
nodeResponse.on("close", () => { | ||
if (!nodeResponse.writableEnded) { | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(499); | ||
} | ||
}); | ||
nodeResponse.end(); | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** @internal */ | ||
export const makeUpgradeHandler = (lazyWss, httpApp, middleware) => { | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause(handleResponse(request, exit.value), cause => handleCause(request, cause)); | ||
} | ||
return handleCause(request, exit.cause); | ||
}, middleware); | ||
return Effect.map(FiberSet.makeRuntime(), runFork => function handler(nodeRequest, socket, head) { | ||
let nodeResponse_ = undefined; | ||
const nodeResponse = () => { | ||
if (nodeResponse_ === undefined) { | ||
nodeResponse_ = new Http.ServerResponse(nodeRequest); | ||
nodeResponse_.assignSocket(socket); | ||
} | ||
return nodeResponse_; | ||
}; | ||
const upgradeEffect = Socket.fromWebSocket(Effect.flatMap(lazyWss, wss => Effect.acquireRelease(Effect.async(resume => wss.handleUpgrade(nodeRequest, socket, head, ws => { | ||
resume(Effect.succeed(ws)); | ||
})), ws => Effect.sync(() => ws.close())))); | ||
const fiber = runFork(Effect.provideService(handledApp, ServerRequest.ServerRequest, new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect))); | ||
socket.on("close", () => { | ||
const res = nodeResponse(); | ||
if (!socket.writableEnded) { | ||
if (!res.headersSent) { | ||
res.writeHead(499); | ||
} | ||
res.end(); | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId); | ||
} | ||
}); | ||
}); | ||
}; | ||
const respond = /*#__PURE__*/Middleware.make(httpApp => Effect.uninterruptibleMask(restore => Effect.flatMap(ServerRequest.ServerRequest, request => Effect.tapErrorCause(restore(Effect.tap(Effect.flatMap(httpApp, response => Effect.flatMap(App.preResponseHandler, f => f(request, response))), response => handleResponse(request, response))), cause => Effect.sync(() => { | ||
const nodeResponse = request.response; | ||
const handleCause = (request, cause) => Effect.sync(() => { | ||
const nodeResponse = request.resolvedResponse; | ||
if (!nodeResponse.headersSent) { | ||
@@ -95,11 +148,12 @@ nodeResponse.writeHead(Cause.isInterruptedOnly(cause) ? 503 : 500); | ||
} | ||
}))))); | ||
}); | ||
class ServerRequestImpl extends IncomingMessageImpl { | ||
source; | ||
response; | ||
upgradeEffect; | ||
url; | ||
headersOverride; | ||
[ServerRequest.TypeId]; | ||
constructor(source, response, url = source.url, headersOverride, remoteAddressOverride) { | ||
super(source, _ => Error.RequestError({ | ||
constructor(source, response, upgradeEffect, url = source.url, headersOverride, remoteAddressOverride) { | ||
super(source, _ => new Error.RequestError({ | ||
request: this, | ||
@@ -111,2 +165,3 @@ reason: "Decode", | ||
this.response = response; | ||
this.upgradeEffect = upgradeEffect; | ||
this.url = url; | ||
@@ -116,4 +171,14 @@ this.headersOverride = headersOverride; | ||
} | ||
cachedCookies; | ||
get cookies() { | ||
if (this.cachedCookies) { | ||
return this.cachedCookies; | ||
} | ||
return this.cachedCookies = Cookies.parseHeader(this.headers.cookie ?? ""); | ||
} | ||
get resolvedResponse() { | ||
return typeof this.response === "function" ? this.response() : this.response; | ||
} | ||
modify(options) { | ||
return new ServerRequestImpl(this.source, this.response, options.url ?? this.url, options.headers ?? this.headersOverride, options.remoteAddress ?? this.remoteAddressOverride); | ||
return new ServerRequestImpl(this.source, this.response, this.upgradeEffect, options.url ?? this.url, options.headers ?? this.headersOverride, options.remoteAddress ?? this.remoteAddressOverride); | ||
} | ||
@@ -141,2 +206,9 @@ get originalUrl() { | ||
} | ||
get upgrade() { | ||
return this.upgradeEffect ?? Effect.fail(new Error.RequestError({ | ||
request: this, | ||
reason: "Decode", | ||
error: "not an upgradeable ServerRequest" | ||
})); | ||
} | ||
toString() { | ||
@@ -146,9 +218,7 @@ return `ServerRequest(${this.method} ${this.url})`; | ||
toJSON() { | ||
return { | ||
_tag: "ServerRequest", | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ServerRequest", | ||
method: this.method, | ||
url: this.url, | ||
originalUrl: this.originalUrl, | ||
headers: this.headers | ||
}; | ||
url: this.originalUrl | ||
}); | ||
} | ||
@@ -163,7 +233,22 @@ } | ||
const handleResponse = (request, response) => Effect.suspend(() => { | ||
const nodeResponse = request.response; | ||
const nodeResponse = request.resolvedResponse; | ||
if (nodeResponse.writableEnded) { | ||
return Effect.void; | ||
} | ||
let headers = response.headers; | ||
if (!Cookies.isEmpty(response.cookies)) { | ||
headers = { | ||
...headers | ||
}; | ||
const toSet = Cookies.toSetCookieHeaders(response.cookies); | ||
if (headers["set-cookie"] !== undefined) { | ||
toSet.push(headers["set-cookie"]); | ||
} | ||
headers["set-cookie"] = toSet; | ||
} | ||
if (request.method === "HEAD") { | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(() => resume(Effect.void)); | ||
}); | ||
} | ||
@@ -174,9 +259,10 @@ const body = response.body; | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(() => resume(Effect.void)); | ||
}); | ||
} | ||
case "Raw": | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.writeHead(response.status, headers); | ||
if (typeof body.body === "object" && body.body !== null && "pipe" in body.body && typeof body.body.pipe === "function") { | ||
@@ -188,3 +274,3 @@ return Effect.tryPromise({ | ||
}), | ||
catch: error => Error.ResponseError({ | ||
catch: error => new Error.ResponseError({ | ||
request, | ||
@@ -197,30 +283,35 @@ response, | ||
} | ||
nodeResponse.end(body.body); | ||
return Effect.unit; | ||
return Effect.async(resume => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)); | ||
}); | ||
} | ||
case "Uint8Array": | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
nodeResponse.end(body.body); | ||
return Effect.unit; | ||
nodeResponse.writeHead(response.status, headers); | ||
return Effect.async(resume => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)); | ||
}); | ||
} | ||
case "FormData": | ||
{ | ||
return Effect.async(resume => { | ||
return Effect.suspend(() => { | ||
const r = new Response(body.formData); | ||
const headers = { | ||
...response.headers, | ||
nodeResponse.writeHead(response.status, { | ||
...headers, | ||
...Object.fromEntries(r.headers) | ||
}; | ||
nodeResponse.writeHead(response.status, headers); | ||
Readable.fromWeb(r.body).pipe(nodeResponse).on("error", error => { | ||
resume(Effect.fail(Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}))); | ||
}).once("finish", () => { | ||
resume(Effect.unit); | ||
}); | ||
return Effect.async((resume, signal) => { | ||
Readable.fromWeb(r.body, { | ||
signal | ||
}).pipe(nodeResponse).on("error", error => { | ||
resume(Effect.fail(new Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}))); | ||
}).once("finish", () => { | ||
resume(Effect.void); | ||
}); | ||
}).pipe(Effect.interruptible); | ||
}); | ||
@@ -230,4 +321,4 @@ } | ||
{ | ||
nodeResponse.writeHead(response.status, response.headers); | ||
return Stream.run(Stream.mapError(body.stream, error => Error.ResponseError({ | ||
nodeResponse.writeHead(response.status, headers); | ||
return Stream.run(Stream.mapError(body.stream, error => new Error.ResponseError({ | ||
request, | ||
@@ -237,3 +328,3 @@ response, | ||
error | ||
})), NodeSink.fromWritable(() => nodeResponse, error => Error.ResponseError({ | ||
})), NodeSink.fromWritable(() => nodeResponse, error => new Error.ResponseError({ | ||
request, | ||
@@ -243,3 +334,3 @@ response, | ||
error | ||
}))); | ||
}))).pipe(Effect.interruptible); | ||
} | ||
@@ -246,0 +337,0 @@ } |
@@ -14,3 +14,3 @@ import * as Worker from "@effect/platform/Worker"; | ||
worker.once("exit", () => { | ||
resume(Effect.unit); | ||
resume(Effect.void); | ||
}); | ||
@@ -26,9 +26,18 @@ worker.postMessage([1]); | ||
worker.on("messageerror", error => { | ||
resume(Effect.fail(WorkerError("decode", error.message, error.stack))); | ||
resume(new WorkerError({ | ||
reason: "decode", | ||
error | ||
})); | ||
}); | ||
worker.on("error", error => { | ||
resume(Effect.fail(WorkerError("unknown", error.message, error.stack))); | ||
resume(new WorkerError({ | ||
reason: "unknown", | ||
error | ||
})); | ||
}); | ||
worker.on("exit", code => { | ||
resume(Effect.fail(WorkerError("unknown", new Error(`exited with code ${code}`)))); | ||
resume(new WorkerError({ | ||
reason: "unknown", | ||
error: new Error(`exited with code ${code}`) | ||
})); | ||
}); | ||
@@ -38,3 +47,6 @@ }), Effect.interruptible, Effect.forkScoped); | ||
try: () => worker.postMessage([0, message], transfers), | ||
catch: error => WorkerError("send", error.message, error.stack) | ||
catch: error => new WorkerError({ | ||
reason: "send", | ||
error | ||
}) | ||
}); | ||
@@ -54,9 +66,3 @@ return { | ||
/** @internal */ | ||
export const makePool = /*#__PURE__*/Worker.makePool(); | ||
/** @internal */ | ||
export const makePoolLayer = /*#__PURE__*/Worker.makePoolLayer(layerManager); | ||
/** @internal */ | ||
export const makePoolSerialized = /*#__PURE__*/Worker.makePoolSerialized(); | ||
/** @internal */ | ||
export const makePoolSerializedLayer = /*#__PURE__*/Worker.makePoolSerializedLayer(layerManager); | ||
export const layer = spawn => Layer.merge(layerManager, Worker.layerSpawner(spawn)); | ||
//# sourceMappingURL=worker.js.map |
@@ -14,3 +14,6 @@ import { WorkerError } from "@effect/platform/WorkerError"; | ||
if (!WorkerThreads.parentPort) { | ||
return yield* _(Effect.fail(WorkerError("spawn", "not in worker"))); | ||
return yield* _(new WorkerError({ | ||
reason: "spawn", | ||
error: new Error("not in worker") | ||
})); | ||
} | ||
@@ -22,3 +25,3 @@ const port = WorkerThreads.parentPort; | ||
if (message[0] === 0) { | ||
queue.unsafeOffer(message[1]); | ||
queue.unsafeOffer([0, message[1]]); | ||
} else { | ||
@@ -29,12 +32,18 @@ Effect.runFork(shutdown); | ||
port.on("messageerror", error => { | ||
resume(Effect.fail(WorkerError("decode", error.message, error.stack))); | ||
resume(new WorkerError({ | ||
reason: "decode", | ||
error | ||
})); | ||
}); | ||
port.on("error", error => { | ||
resume(Effect.fail(WorkerError("unknown", error.message, error.stack))); | ||
resume(new WorkerError({ | ||
reason: "unknown", | ||
error | ||
})); | ||
}); | ||
}), Effect.tapErrorCause(cause => Cause.isInterruptedOnly(cause) ? Effect.unit : Effect.logDebug(cause)), Effect.retry(Schedule.forever), Effect.annotateLogs({ | ||
}), Effect.tapErrorCause(cause => Cause.isInterruptedOnly(cause) ? Effect.void : Effect.logDebug(cause)), Effect.retry(Schedule.forever), Effect.annotateLogs({ | ||
package: "@effect/platform-node", | ||
module: "WorkerRunner" | ||
}), Effect.interruptible, Effect.forkScoped); | ||
const send = (message, transfers) => Effect.sync(() => port.postMessage([1, message], transfers)); | ||
const send = (_portId, message, transfers) => Effect.sync(() => port.postMessage([1, message], transfers)); | ||
// ready | ||
@@ -50,7 +59,3 @@ port.postMessage([0]); | ||
/** @internal */ | ||
export const layerPlatform = /*#__PURE__*/Layer.succeed(Runner.PlatformRunner, platformRunnerImpl); | ||
/** @internal */ | ||
export const layer = (process, options) => Layer.provide(Runner.layer(process, options), layerPlatform); | ||
/** @internal */ | ||
export const layerSerialized = (schema, handlers) => Layer.provide(Runner.layerSerialized(schema, handlers), layerPlatform); | ||
export const layer = /*#__PURE__*/Layer.succeed(Runner.PlatformRunner, platformRunnerImpl); | ||
//# sourceMappingURL=workerRunner.js.map |
import * as internal from "./internal/http/client.js"; | ||
import * as internalUndici from "./internal/http/clientUndici.js"; | ||
/** | ||
@@ -42,2 +43,47 @@ * @since 1.0.0 | ||
export const layerWithoutAgent = internal.layerWithoutAgent; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const Dispatcher = internalUndici.Dispatcher; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const makeDispatcher = internalUndici.makeDispatcher; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const dispatcherLayer = internalUndici.dispatcherLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const dispatcherLayerGlobal = internalUndici.dispatcherLayerGlobal; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const currentUndiciOptions = internalUndici.currentUndiciOptions; | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const withUndiciOptions = internalUndici.withUndiciOptions; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makeUndici = internalUndici.make; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerUndici = internalUndici.layer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerUndiciWithoutDispatcher = internalUndici.layerWithoutDispatcher; | ||
//# sourceMappingURL=NodeHttpClient.js.map |
import * as internal from "./internal/worker.js"; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
* @category layers | ||
*/ | ||
export const makePool = internal.makePool; | ||
export const layerManager = internal.layerManager; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolLayer = internal.makePoolLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolSerialized = internal.makePoolSerialized; | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolSerializedLayer = internal.makePoolSerializedLayer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerManager = internal.layerManager; | ||
export const layerWorker = internal.layerWorker; | ||
/** | ||
@@ -31,3 +16,3 @@ * @since 1.0.0 | ||
*/ | ||
export const layerWorker = internal.layerWorker; | ||
export const layer = internal.layer; | ||
//# sourceMappingURL=NodeWorker.js.map |
@@ -6,13 +6,3 @@ import * as internal from "./internal/workerRunner.js"; | ||
*/ | ||
export const layerPlatform = internal.layerPlatform; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layer = internal.layer; | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerSerialized = internal.layerSerialized; | ||
//# sourceMappingURL=NodeWorkerRunner.js.map |
{ | ||
"name": "@effect/platform-node", | ||
"version": "0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49", | ||
"description": "Unified interfaces for common platform-specific services", | ||
"version": "0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99", | ||
"description": "Platform specific implementations for the Node.js runtime", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/effect-ts/effect.git" | ||
"url": "https://github.com/Effect-TS/effect.git", | ||
"directory": "packages/platform-node" | ||
}, | ||
@@ -13,8 +14,13 @@ "sideEffects": [], | ||
"mime": "^3.0.0", | ||
"@effect/platform-node-shared": "^0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49" | ||
"undici": "^6.18.0", | ||
"ws": "^8.17.0", | ||
"@effect/platform-node-shared": "^0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99" | ||
}, | ||
"peerDependencies": { | ||
"@effect/platform": "^0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49", | ||
"effect": "^0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49" | ||
"@effect/platform": "^0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99", | ||
"effect": "^0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99" | ||
}, | ||
"publishConfig": { | ||
"provenance": true | ||
}, | ||
"main": "./dist/cjs/index.js", | ||
@@ -90,2 +96,7 @@ "module": "./dist/esm/index.js", | ||
}, | ||
"./NodeSocket": { | ||
"types": "./dist/dts/NodeSocket.d.ts", | ||
"import": "./dist/esm/NodeSocket.js", | ||
"default": "./dist/cjs/NodeSocket.js" | ||
}, | ||
"./NodeStream": { | ||
@@ -150,2 +161,5 @@ "types": "./dist/dts/NodeStream.d.ts", | ||
], | ||
"NodeSocket": [ | ||
"./dist/dts/NodeSocket.d.ts" | ||
], | ||
"NodeStream": [ | ||
@@ -152,0 +166,0 @@ "./dist/dts/NodeStream.d.ts" |
@@ -41,15 +41,15 @@ /** | ||
<R, E>( | ||
httpApp: App.Default<R, E> | ||
httpApp: App.Default<E, R> | ||
): Effect.Effect< | ||
Exclude<R, Scope.Scope | ServerRequest.ServerRequest>, | ||
(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void, | ||
never, | ||
(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void | ||
Exclude<R, Scope.Scope | ServerRequest.ServerRequest> | ||
> | ||
<R, E, App extends App.Default<any, any>>( | ||
httpApp: App.Default<R, E>, | ||
middleware: Middleware.Middleware.Applied<R, E, App> | ||
httpApp: App.Default<E, R>, | ||
middleware: Middleware.Middleware.Applied<App, E, R> | ||
): Effect.Effect< | ||
Exclude<Effect.Effect.Context<App>, Scope.Scope | ServerRequest.ServerRequest>, | ||
(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void, | ||
never, | ||
(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse<Http.IncomingMessage>) => void | ||
Exclude<Effect.Effect.Context<App>, Scope.Scope | ServerRequest.ServerRequest> | ||
> | ||
@@ -72,3 +72,3 @@ } = internal.makeHandler | ||
export const layer: ( | ||
evaluate: LazyArg<Http.Server>, | ||
evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, | ||
options: Net.ListenOptions | ||
@@ -83,7 +83,7 @@ ) => Layer.Layer<Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, ServeError> = | ||
export const layerConfig: ( | ||
evaluate: LazyArg<Http.Server>, | ||
evaluate: LazyArg<Http.Server<typeof Http.IncomingMessage, typeof Http.ServerResponse>>, | ||
options: Config.Config.Wrap<Net.ListenOptions> | ||
) => Layer.Layer< | ||
Platform.Platform | Etag.Generator | NodeContext.NodeContext | Server.Server, | ||
ServeError | ConfigError.ConfigError | ||
ConfigError.ConfigError | ServeError | ||
> = internal.layerConfig |
@@ -49,2 +49,7 @@ /** | ||
*/ | ||
export * as NodeSocket from "./NodeSocket.js" | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export * as NodeStream from "./NodeStream.js" | ||
@@ -51,0 +56,0 @@ |
@@ -6,3 +6,4 @@ import type * as Body from "@effect/platform/Http/Body" | ||
import * as ClientResponse from "@effect/platform/Http/ClientResponse" | ||
import * as UrlParams from "@effect/platform/Http/UrlParams" | ||
import * as Cookies from "@effect/platform/Http/Cookies" | ||
import * as IncomingMessage from "@effect/platform/Http/IncomingMessage" | ||
import * as Context from "effect/Context" | ||
@@ -58,36 +59,23 @@ import * as Effect from "effect/Effect" | ||
const fromAgent = (agent: NodeClient.HttpAgent): Client.Client.Default => | ||
Client.makeDefault((request) => | ||
Effect.flatMap( | ||
UrlParams.makeUrl(request.url, request.urlParams, (_) => | ||
Error.RequestError({ | ||
request, | ||
reason: "InvalidUrl", | ||
error: _ | ||
})), | ||
(url) => | ||
Effect.suspend(() => { | ||
const controller = new AbortController() | ||
const nodeRequest = url.protocol === "https:" ? | ||
Https.request(url, { | ||
agent: agent.https, | ||
method: request.method, | ||
headers: request.headers, | ||
signal: controller.signal | ||
}) : | ||
Http.request(url, { | ||
agent: agent.http, | ||
method: request.method, | ||
headers: request.headers, | ||
signal: controller.signal | ||
}) | ||
return pipe( | ||
Effect.zipRight(sendBody(nodeRequest, request, request.body), waitForResponse(nodeRequest, request), { | ||
concurrent: true | ||
}), | ||
Effect.onInterrupt(() => Effect.sync(() => controller.abort())), | ||
Effect.map((_) => new ClientResponseImpl(request, _)) | ||
) | ||
}) | ||
Client.makeDefault((request, url, signal) => { | ||
const nodeRequest = url.protocol === "https:" ? | ||
Https.request(url, { | ||
agent: agent.https, | ||
method: request.method, | ||
headers: request.headers, | ||
signal | ||
}) : | ||
Http.request(url, { | ||
agent: agent.http, | ||
method: request.method, | ||
headers: request.headers, | ||
signal | ||
}) | ||
return pipe( | ||
Effect.zipRight(sendBody(nodeRequest, request, request.body), waitForResponse(nodeRequest, request), { | ||
concurrent: true | ||
}), | ||
Effect.map((_) => new ClientResponseImpl(request, _)) | ||
) | ||
) | ||
}) | ||
@@ -120,3 +108,3 @@ const sendBody = ( | ||
catch: (_) => | ||
Error.RequestError({ | ||
new Error.RequestError({ | ||
request, | ||
@@ -131,3 +119,3 @@ reason: "Transport", | ||
Stream.mapError(body.stream, (_) => | ||
Error.RequestError({ | ||
new Error.RequestError({ | ||
request, | ||
@@ -138,3 +126,3 @@ reason: "Encode", | ||
NodeSink.fromWritable(() => nodeRequest, (_) => | ||
Error.RequestError({ | ||
new Error.RequestError({ | ||
request, | ||
@@ -150,9 +138,11 @@ reason: "Transport", | ||
const waitForResponse = (nodeRequest: Http.ClientRequest, request: ClientRequest.ClientRequest) => | ||
Effect.async<Http.IncomingMessage, Error.RequestError, never>((resume) => { | ||
Effect.async<Http.IncomingMessage, Error.RequestError>((resume) => { | ||
function onError(error: Error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
request, | ||
reason: "Transport", | ||
error | ||
}))) | ||
resume(Effect.fail( | ||
new Error.RequestError({ | ||
request, | ||
reason: "Transport", | ||
error | ||
}) | ||
)) | ||
} | ||
@@ -176,9 +166,11 @@ nodeRequest.on("error", onError) | ||
const waitForFinish = (nodeRequest: Http.ClientRequest, request: ClientRequest.ClientRequest) => | ||
Effect.async<void, Error.RequestError, never>((resume) => { | ||
Effect.async<void, Error.RequestError>((resume) => { | ||
function onError(error: Error) { | ||
resume(Effect.fail(Error.RequestError({ | ||
request, | ||
reason: "Transport", | ||
error | ||
}))) | ||
resume(Effect.fail( | ||
new Error.RequestError({ | ||
request, | ||
reason: "Transport", | ||
error | ||
}) | ||
)) | ||
} | ||
@@ -189,3 +181,3 @@ nodeRequest.once("error", onError) | ||
nodeRequest.off("error", onError) | ||
resume(Effect.unit) | ||
resume(Effect.void) | ||
} | ||
@@ -208,3 +200,3 @@ nodeRequest.once("finish", onFinish) | ||
super(source, (_) => | ||
Error.ResponseError({ | ||
new Error.ResponseError({ | ||
request, | ||
@@ -222,2 +214,14 @@ response: this, | ||
cachedCookies?: Cookies.Cookies | ||
get cookies(): Cookies.Cookies { | ||
if (this.cachedCookies !== undefined) { | ||
return this.cachedCookies | ||
} | ||
const header = this.source.headers["set-cookie"] | ||
if (Array.isArray(header)) { | ||
return this.cachedCookies = Cookies.fromSetCookie(header) | ||
} | ||
return this.cachedCookies = Cookies.empty | ||
} | ||
get formData(): Effect.Effect<FormData, Error.ResponseError> { | ||
@@ -248,12 +252,8 @@ return Effect.tryPromise({ | ||
toString(): string { | ||
return `ClientResponse(${this.status})` | ||
} | ||
toJSON(): unknown { | ||
return { | ||
_tag: "ClientResponse", | ||
status: this.status, | ||
headers: this.headers | ||
} | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ClientResponse", | ||
request: this.request.toJSON(), | ||
status: this.status | ||
}) | ||
} | ||
@@ -260,0 +260,0 @@ } |
@@ -6,2 +6,3 @@ import * as Headers from "@effect/platform/Http/Headers" | ||
import * as FiberRef from "effect/FiberRef" | ||
import * as Inspectable from "effect/Inspectable" | ||
import * as Option from "effect/Option" | ||
@@ -13,3 +14,3 @@ import type * as Stream from "effect/Stream" | ||
/** @internal */ | ||
export class IncomingMessageImpl<E> implements IncomingMessage.IncomingMessage<E> { | ||
export abstract class IncomingMessageImpl<E> extends Inspectable.Class implements IncomingMessage.IncomingMessage<E> { | ||
readonly [IncomingMessage.TypeId]: IncomingMessage.TypeId | ||
@@ -22,2 +23,3 @@ | ||
) { | ||
super() | ||
this[IncomingMessage.TypeId] = IncomingMessage.TypeId | ||
@@ -52,2 +54,6 @@ } | ||
get unsafeText(): string { | ||
return Effect.runSync(this.text) | ||
} | ||
get json(): Effect.Effect<unknown, E> { | ||
@@ -60,2 +66,6 @@ return Effect.tryMap(this.text, { | ||
get unsafeJson(): unknown { | ||
return Effect.runSync(this.json) | ||
} | ||
get urlParamsBody(): Effect.Effect<UrlParams.UrlParams, E> { | ||
@@ -62,0 +72,0 @@ return Effect.flatMap(this.text, (_) => |
@@ -5,6 +5,7 @@ import * as Etag from "@effect/platform-node-shared/Http/Etag" | ||
import * as App from "@effect/platform/Http/App" | ||
import * as Cookies from "@effect/platform/Http/Cookies" | ||
import type * as Headers from "@effect/platform/Http/Headers" | ||
import * as IncomingMessage from "@effect/platform/Http/IncomingMessage" | ||
import type { Method } from "@effect/platform/Http/Method" | ||
import * as Middleware from "@effect/platform/Http/Middleware" | ||
import type * as Middleware from "@effect/platform/Http/Middleware" | ||
import type * as Multipart from "@effect/platform/Http/Multipart" | ||
@@ -16,15 +17,19 @@ import * as Server from "@effect/platform/Http/Server" | ||
import type * as Path from "@effect/platform/Path" | ||
import * as Socket from "@effect/platform/Socket" | ||
import * as Cause from "effect/Cause" | ||
import * as Config from "effect/Config" | ||
import * as Effect from "effect/Effect" | ||
import * as FiberSet from "effect/FiberSet" | ||
import { type LazyArg } from "effect/Function" | ||
import * as Layer from "effect/Layer" | ||
import * as Option from "effect/Option" | ||
import * as Runtime from "effect/Runtime" | ||
import type * as Scope from "effect/Scope" | ||
import type { ReadonlyRecord } from "effect/Record" | ||
import * as Scope from "effect/Scope" | ||
import * as Stream from "effect/Stream" | ||
import type * as Http from "node:http" | ||
import * as Http from "node:http" | ||
import type * as Net from "node:net" | ||
import type { Duplex } from "node:stream" | ||
import { Readable } from "node:stream" | ||
import { pipeline } from "node:stream/promises" | ||
import * as WS from "ws" | ||
import * as NodeContext from "../../NodeContext.js" | ||
@@ -41,6 +46,10 @@ import * as NodeSink from "../../NodeSink.js" | ||
Effect.gen(function*(_) { | ||
const server = yield* _(Effect.acquireRelease( | ||
const scope = yield* Effect.scope | ||
const server = yield* Effect.acquireRelease( | ||
Effect.sync(evaluate), | ||
(server) => | ||
Effect.async<void, never, never>((resume) => { | ||
Effect.async<void>((resume) => { | ||
if (!server.listening) { | ||
return resume(Effect.void) | ||
} | ||
server.close((error) => { | ||
@@ -50,19 +59,33 @@ if (error) { | ||
} else { | ||
resume(Effect.unit) | ||
resume(Effect.void) | ||
} | ||
}) | ||
}) | ||
)) | ||
) | ||
yield* _(Effect.async<void, Error.ServeError, never>((resume) => { | ||
server.on("error", (error) => { | ||
resume(Effect.fail(Error.ServeError({ error }))) | ||
}) | ||
yield* Effect.async<void, Error.ServeError>((resume) => { | ||
function onError(error: Error) { | ||
resume(Effect.fail(new Error.ServeError({ error }))) | ||
} | ||
server.on("error", onError) | ||
server.listen(options, () => { | ||
resume(Effect.unit) | ||
server.off("error", onError) | ||
resume(Effect.void) | ||
}) | ||
})) | ||
}) | ||
const address = server.address()! | ||
const wss = yield* _( | ||
Effect.acquireRelease( | ||
Effect.sync(() => new WS.WebSocketServer({ noServer: true })), | ||
(wss) => | ||
Effect.async<void>((resume) => { | ||
wss.close(() => resume(Effect.void)) | ||
}) | ||
), | ||
Scope.extend(scope), | ||
Effect.cached | ||
) | ||
return Server.make({ | ||
@@ -82,8 +105,11 @@ address: typeof address === "string" ? | ||
const handler = yield* _(makeHandler(httpApp, middleware!)) | ||
const upgradeHandler = yield* _(makeUpgradeHandler(wss, httpApp, middleware!)) | ||
yield* _(Effect.addFinalizer(() => | ||
Effect.sync(() => { | ||
server.off("request", handler) | ||
server.off("upgrade", upgradeHandler) | ||
}) | ||
)) | ||
server.on("request", handler) | ||
server.on("upgrade", upgradeHandler) | ||
}) | ||
@@ -100,3 +126,3 @@ }) | ||
export const makeHandler: { | ||
<R, E>(httpApp: App.Default<R, E>): Effect.Effect< | ||
<R, E>(httpApp: App.Default<E, R>): Effect.Effect< | ||
(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse) => void, | ||
@@ -107,4 +133,4 @@ never, | ||
<R, E, App extends App.Default<any, any>>( | ||
httpApp: App.Default<R, E>, | ||
middleware: Middleware.Middleware.Applied<R, E, App> | ||
httpApp: App.Default<E, R>, | ||
middleware: Middleware.Middleware.Applied<App, E, R> | ||
): Effect.Effect< | ||
@@ -115,11 +141,17 @@ (nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse) => void, | ||
> | ||
} = <R, E>(httpApp: App.Default<R, E>, middleware?: Middleware.Middleware) => { | ||
const handledApp = Effect.scoped( | ||
middleware | ||
? middleware(App.withDefaultMiddleware(respond(httpApp))) | ||
: App.withDefaultMiddleware(respond(httpApp)) | ||
) | ||
return Effect.map(Effect.runtime<R>(), (runtime) => { | ||
const runFork = Runtime.runFork(runtime) | ||
return function handler(nodeRequest: Http.IncomingMessage, nodeResponse: Http.ServerResponse) { | ||
} = <E, R>(httpApp: App.Default<E, R>, middleware?: Middleware.Middleware) => { | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause( | ||
handleResponse(request, exit.value), | ||
(cause) => handleCause(request, cause) | ||
) | ||
} | ||
return handleCause(request, exit.cause) | ||
}, middleware) | ||
return Effect.map(FiberSet.makeRuntime<R>(), (runFork) => | ||
function handler( | ||
nodeRequest: Http.IncomingMessage, | ||
nodeResponse: Http.ServerResponse | ||
) { | ||
const fiber = runFork( | ||
@@ -138,36 +170,80 @@ Effect.provideService( | ||
nodeResponse.end() | ||
runFork(fiber.interruptAsFork(Error.clientAbortFiberId)) | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId) | ||
} | ||
}) | ||
} | ||
}) | ||
}) | ||
} | ||
const respond = Middleware.make((httpApp) => | ||
Effect.uninterruptibleMask((restore) => | ||
Effect.flatMap(ServerRequest.ServerRequest, (request) => | ||
Effect.tapErrorCause( | ||
restore( | ||
Effect.tap( | ||
Effect.flatMap( | ||
httpApp, | ||
(response) => Effect.flatMap(App.preResponseHandler, (f) => f(request, response)) | ||
/** @internal */ | ||
export const makeUpgradeHandler = <R, E>( | ||
lazyWss: Effect.Effect<WS.WebSocketServer>, | ||
httpApp: App.Default<E, R>, | ||
middleware?: Middleware.Middleware | ||
) => { | ||
const handledApp = App.toHandled(httpApp, (request, exit) => { | ||
if (exit._tag === "Success") { | ||
return Effect.catchAllCause( | ||
handleResponse(request, exit.value), | ||
(cause) => handleCause(request, cause) | ||
) | ||
} | ||
return handleCause(request, exit.cause) | ||
}, middleware) | ||
return Effect.map(FiberSet.makeRuntime<R>(), (runFork) => | ||
function handler( | ||
nodeRequest: Http.IncomingMessage, | ||
socket: Duplex, | ||
head: Buffer | ||
) { | ||
let nodeResponse_: Http.ServerResponse | undefined = undefined | ||
const nodeResponse = () => { | ||
if (nodeResponse_ === undefined) { | ||
nodeResponse_ = new Http.ServerResponse(nodeRequest) | ||
nodeResponse_.assignSocket(socket as any) | ||
} | ||
return nodeResponse_ | ||
} | ||
const upgradeEffect = Socket.fromWebSocket(Effect.flatMap( | ||
lazyWss, | ||
(wss) => | ||
Effect.acquireRelease( | ||
Effect.async<globalThis.WebSocket>((resume) => | ||
wss.handleUpgrade(nodeRequest, socket, head, (ws) => { | ||
resume(Effect.succeed(ws as any)) | ||
}) | ||
), | ||
(response) => handleResponse(request, response) | ||
(ws) => Effect.sync(() => ws.close()) | ||
) | ||
), | ||
(cause) => | ||
Effect.sync(() => { | ||
const nodeResponse = (request as ServerRequestImpl).response | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(Cause.isInterruptedOnly(cause) ? 503 : 500) | ||
} | ||
if (!nodeResponse.writableEnded) { | ||
nodeResponse.end() | ||
} | ||
}) | ||
)) | ||
) | ||
) | ||
const fiber = runFork( | ||
Effect.provideService( | ||
handledApp, | ||
ServerRequest.ServerRequest, | ||
new ServerRequestImpl(nodeRequest, nodeResponse, upgradeEffect) | ||
) | ||
) | ||
socket.on("close", () => { | ||
const res = nodeResponse() | ||
if (!socket.writableEnded) { | ||
if (!res.headersSent) { | ||
res.writeHead(499) | ||
} | ||
res.end() | ||
fiber.unsafeInterruptAsFork(Error.clientAbortFiberId) | ||
} | ||
}) | ||
}) | ||
} | ||
const handleCause = <E>(request: ServerRequest.ServerRequest, cause: Cause.Cause<E>) => | ||
Effect.sync(() => { | ||
const nodeResponse = (request as ServerRequestImpl).resolvedResponse | ||
if (!nodeResponse.headersSent) { | ||
nodeResponse.writeHead(Cause.isInterruptedOnly(cause) ? 503 : 500) | ||
} | ||
if (!nodeResponse.writableEnded) { | ||
nodeResponse.end() | ||
} | ||
}) | ||
class ServerRequestImpl extends IncomingMessageImpl<Error.RequestError> implements ServerRequest.ServerRequest { | ||
@@ -178,3 +254,4 @@ readonly [ServerRequest.TypeId]: ServerRequest.TypeId | ||
readonly source: Http.IncomingMessage, | ||
readonly response: Http.ServerResponse, | ||
readonly response: Http.ServerResponse | LazyArg<Http.ServerResponse>, | ||
private upgradeEffect?: Effect.Effect<Socket.Socket, Error.RequestError>, | ||
readonly url = source.url!, | ||
@@ -185,3 +262,3 @@ private headersOverride?: Headers.Headers, | ||
super(source, (_) => | ||
Error.RequestError({ | ||
new Error.RequestError({ | ||
request: this, | ||
@@ -194,2 +271,14 @@ reason: "Decode", | ||
private cachedCookies: ReadonlyRecord<string, string> | undefined | ||
get cookies() { | ||
if (this.cachedCookies) { | ||
return this.cachedCookies | ||
} | ||
return this.cachedCookies = Cookies.parseHeader(this.headers.cookie ?? "") | ||
} | ||
get resolvedResponse(): Http.ServerResponse { | ||
return typeof this.response === "function" ? this.response() : this.response | ||
} | ||
modify( | ||
@@ -205,2 +294,3 @@ options: { | ||
this.response, | ||
this.upgradeEffect, | ||
options.url ?? this.url, | ||
@@ -250,2 +340,12 @@ options.headers ?? this.headersOverride, | ||
get upgrade(): Effect.Effect<Socket.Socket, Error.RequestError> { | ||
return this.upgradeEffect ?? Effect.fail( | ||
new Error.RequestError({ | ||
request: this, | ||
reason: "Decode", | ||
error: "not an upgradeable ServerRequest" | ||
}) | ||
) | ||
} | ||
toString(): string { | ||
@@ -256,9 +356,7 @@ return `ServerRequest(${this.method} ${this.url})` | ||
toJSON(): unknown { | ||
return { | ||
_tag: "ServerRequest", | ||
return IncomingMessage.inspect(this, { | ||
_id: "@effect/platform/Http/ServerRequest", | ||
method: this.method, | ||
url: this.url, | ||
originalUrl: this.originalUrl, | ||
headers: this.headers | ||
} | ||
url: this.originalUrl | ||
}) | ||
} | ||
@@ -302,7 +400,22 @@ } | ||
Effect.suspend((): Effect.Effect<void, Error.ResponseError> => { | ||
const nodeResponse = (request as ServerRequestImpl).response | ||
const nodeResponse = (request as ServerRequestImpl).resolvedResponse | ||
if (nodeResponse.writableEnded) { | ||
return Effect.void | ||
} | ||
let headers: Record<string, string | Array<string>> = response.headers | ||
if (!Cookies.isEmpty(response.cookies)) { | ||
headers = { ...headers } | ||
const toSet = Cookies.toSetCookieHeaders(response.cookies) | ||
if (headers["set-cookie"] !== undefined) { | ||
toSet.push(headers["set-cookie"] as string) | ||
} | ||
headers["set-cookie"] = toSet | ||
} | ||
if (request.method === "HEAD") { | ||
nodeResponse.writeHead(response.status, response.headers) | ||
nodeResponse.end() | ||
return Effect.unit | ||
nodeResponse.writeHead(response.status, headers) | ||
return Effect.async<void>((resume) => { | ||
nodeResponse.end(() => resume(Effect.void)) | ||
}) | ||
} | ||
@@ -312,8 +425,9 @@ const body = response.body | ||
case "Empty": { | ||
nodeResponse.writeHead(response.status, response.headers) | ||
nodeResponse.end() | ||
return Effect.unit | ||
nodeResponse.writeHead(response.status, headers) | ||
return Effect.async<void>((resume) => { | ||
nodeResponse.end(() => resume(Effect.void)) | ||
}) | ||
} | ||
case "Raw": { | ||
nodeResponse.writeHead(response.status, response.headers) | ||
nodeResponse.writeHead(response.status, headers) | ||
if ( | ||
@@ -326,3 +440,3 @@ typeof body.body === "object" && body.body !== null && "pipe" in body.body && | ||
catch: (error) => | ||
Error.ResponseError({ | ||
new Error.ResponseError({ | ||
request, | ||
@@ -335,35 +449,40 @@ response, | ||
} | ||
nodeResponse.end(body.body) | ||
return Effect.unit | ||
return Effect.async<void>((resume) => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)) | ||
}) | ||
} | ||
case "Uint8Array": { | ||
nodeResponse.writeHead(response.status, response.headers) | ||
nodeResponse.end(body.body) | ||
return Effect.unit | ||
nodeResponse.writeHead(response.status, headers) | ||
return Effect.async<void>((resume) => { | ||
nodeResponse.end(body.body, () => resume(Effect.void)) | ||
}) | ||
} | ||
case "FormData": { | ||
return Effect.async<void, Error.ResponseError, never>((resume) => { | ||
return Effect.suspend(() => { | ||
const r = new Response(body.formData) | ||
const headers = { | ||
...response.headers, | ||
nodeResponse.writeHead(response.status, { | ||
...headers, | ||
...Object.fromEntries(r.headers) | ||
} | ||
nodeResponse.writeHead(response.status, headers) | ||
Readable.fromWeb(r.body as any) | ||
.pipe(nodeResponse) | ||
.on("error", (error) => { | ||
resume(Effect.fail(Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}))) | ||
}) | ||
.once("finish", () => { | ||
resume(Effect.unit) | ||
}) | ||
}) | ||
return Effect.async<void, Error.ResponseError>((resume, signal) => { | ||
Readable.fromWeb(r.body as any, { signal }) | ||
.pipe(nodeResponse) | ||
.on("error", (error) => { | ||
resume(Effect.fail( | ||
new Error.ResponseError({ | ||
request, | ||
response, | ||
reason: "Decode", | ||
error | ||
}) | ||
)) | ||
}) | ||
.once("finish", () => { | ||
resume(Effect.void) | ||
}) | ||
}).pipe(Effect.interruptible) | ||
}) | ||
} | ||
case "Stream": { | ||
nodeResponse.writeHead(response.status, response.headers) | ||
nodeResponse.writeHead(response.status, headers) | ||
return Stream.run( | ||
@@ -373,3 +492,3 @@ Stream.mapError( | ||
(error) => | ||
Error.ResponseError({ | ||
new Error.ResponseError({ | ||
request, | ||
@@ -382,3 +501,3 @@ response, | ||
NodeSink.fromWritable(() => nodeResponse, (error) => | ||
Error.ResponseError({ | ||
new Error.ResponseError({ | ||
request, | ||
@@ -389,3 +508,3 @@ response, | ||
})) | ||
) | ||
).pipe(Effect.interruptible) | ||
} | ||
@@ -392,0 +511,0 @@ } |
@@ -16,5 +16,5 @@ import * as Worker from "@effect/platform/Worker" | ||
pipe( | ||
Effect.async<void, never, never>((resume) => { | ||
Effect.async<void>((resume) => { | ||
worker.once("exit", () => { | ||
resume(Effect.unit) | ||
resume(Effect.void) | ||
}) | ||
@@ -30,3 +30,3 @@ worker.postMessage([1]) | ||
const fiber = yield* _( | ||
Effect.async<never, WorkerError, never>((resume) => { | ||
Effect.async<never, WorkerError>((resume) => { | ||
worker.on("message", (message: Worker.BackingWorker.Message<O>) => { | ||
@@ -36,9 +36,9 @@ queue.unsafeOffer(message) | ||
worker.on("messageerror", (error) => { | ||
resume(Effect.fail(WorkerError("decode", error.message, error.stack))) | ||
resume(new WorkerError({ reason: "decode", error })) | ||
}) | ||
worker.on("error", (error) => { | ||
resume(Effect.fail(WorkerError("unknown", error.message, error.stack))) | ||
resume(new WorkerError({ reason: "unknown", error })) | ||
}) | ||
worker.on("exit", (code) => { | ||
resume(Effect.fail(WorkerError("unknown", new Error(`exited with code ${code}`)))) | ||
resume(new WorkerError({ reason: "unknown", error: new Error(`exited with code ${code}`) })) | ||
}) | ||
@@ -52,3 +52,3 @@ }), | ||
try: () => worker.postMessage([0, message], transfers as any), | ||
catch: (error) => WorkerError("send", (error as any).message, (error as any).stack) | ||
catch: (error) => new WorkerError({ reason: "send", error }) | ||
}) | ||
@@ -67,13 +67,6 @@ return { fiber, queue, send } | ||
/** @internal */ | ||
export const makePool = Worker.makePool<WorkerThreads.Worker>() | ||
/** @internal */ | ||
export const makePoolLayer = Worker.makePoolLayer<WorkerThreads.Worker>(layerManager) | ||
/** @internal */ | ||
export const makePoolSerialized = Worker.makePoolSerialized<WorkerThreads.Worker>() | ||
/** @internal */ | ||
export const makePoolSerializedLayer = Worker.makePoolSerializedLayer<WorkerThreads.Worker>( | ||
layerManager | ||
) | ||
export const layer = (spawn: (id: number) => WorkerThreads.Worker) => | ||
Layer.merge( | ||
layerManager, | ||
Worker.layerSpawner(spawn) | ||
) |
import { WorkerError } from "@effect/platform/WorkerError" | ||
import * as Runner from "@effect/platform/WorkerRunner" | ||
import type * as Schema from "@effect/schema/Schema" | ||
import * as Cause from "effect/Cause" | ||
@@ -9,3 +8,2 @@ import * as Effect from "effect/Effect" | ||
import * as Schedule from "effect/Schedule" | ||
import type * as Stream from "effect/Stream" | ||
import * as WorkerThreads from "node:worker_threads" | ||
@@ -18,11 +16,11 @@ | ||
if (!WorkerThreads.parentPort) { | ||
return yield* _(Effect.fail(WorkerError("spawn", "not in worker"))) | ||
return yield* _(new WorkerError({ reason: "spawn", error: new Error("not in worker") })) | ||
} | ||
const port = WorkerThreads.parentPort | ||
const queue = yield* _(Queue.unbounded<I>()) | ||
const queue = yield* _(Queue.unbounded<readonly [portId: number, message: I]>()) | ||
yield* _( | ||
Effect.async<never, WorkerError, never>((resume) => { | ||
Effect.async<never, WorkerError>((resume) => { | ||
port.on("message", (message: Runner.BackingRunner.Message<I>) => { | ||
if (message[0] === 0) { | ||
queue.unsafeOffer(message[1]) | ||
queue.unsafeOffer([0, message[1]]) | ||
} else { | ||
@@ -33,9 +31,9 @@ Effect.runFork(shutdown) | ||
port.on("messageerror", (error) => { | ||
resume(Effect.fail(WorkerError("decode", error.message, error.stack))) | ||
resume(new WorkerError({ reason: "decode", error })) | ||
}) | ||
port.on("error", (error) => { | ||
resume(Effect.fail(WorkerError("unknown", error.message, error.stack))) | ||
resume(new WorkerError({ reason: "unknown", error })) | ||
}) | ||
}), | ||
Effect.tapErrorCause((cause) => Cause.isInterruptedOnly(cause) ? Effect.unit : Effect.logDebug(cause)), | ||
Effect.tapErrorCause((cause) => Cause.isInterruptedOnly(cause) ? Effect.void : Effect.logDebug(cause)), | ||
Effect.retry(Schedule.forever), | ||
@@ -49,3 +47,3 @@ Effect.annotateLogs({ | ||
) | ||
const send = (message: O, transfers?: ReadonlyArray<unknown>) => | ||
const send = (_portId: number, message: O, transfers?: ReadonlyArray<unknown>) => | ||
Effect.sync(() => port.postMessage([1, message], transfers as any)) | ||
@@ -60,20 +58,2 @@ // ready | ||
/** @internal */ | ||
export const layerPlatform = Layer.succeed(Runner.PlatformRunner, platformRunnerImpl) | ||
/** @internal */ | ||
export const layer = <I, R, E, O>( | ||
process: (request: I) => Stream.Stream<O, E, R>, | ||
options?: Runner.Runner.Options<I, E, O> | ||
): Layer.Layer<never, WorkerError, R> => Layer.provide(Runner.layer(process, options), layerPlatform) | ||
/** @internal */ | ||
export const layerSerialized = < | ||
A extends Schema.TaggedRequest.Any, | ||
I, | ||
R, | ||
Handlers extends Runner.SerializedRunner.Handlers<A> | ||
>( | ||
schema: Schema.Schema<A, I, R>, | ||
handlers: Handlers | ||
): Layer.Layer<never, WorkerError, R | Runner.SerializedRunner.HandlersContext<Handlers>> => | ||
Layer.provide(Runner.layerSerialized(schema, handlers), layerPlatform) | ||
export const layer = Layer.succeed(Runner.PlatformRunner, platformRunnerImpl) |
@@ -7,2 +7,3 @@ /** | ||
import type * as Effect from "effect/Effect" | ||
import type * as FiberRef from "effect/FiberRef" | ||
import type * as Layer from "effect/Layer" | ||
@@ -12,3 +13,5 @@ import type * as Scope from "effect/Scope" | ||
import type * as Https from "node:https" | ||
import type * as Undici from "undici" | ||
import * as internal from "./internal/http/client.js" | ||
import * as internalUndici from "./internal/http/clientUndici.js" | ||
@@ -79,1 +82,70 @@ /** | ||
export const layerWithoutAgent: Layer.Layer<Client.Client.Default, never, HttpAgent> = internal.layerWithoutAgent | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export interface Dispatcher { | ||
readonly _: unique symbol | ||
} | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const Dispatcher: Context.Tag<Dispatcher, Undici.Dispatcher> = internalUndici.Dispatcher | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const makeDispatcher: Effect.Effect<Undici.Dispatcher, never, Scope.Scope> = internalUndici.makeDispatcher | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const dispatcherLayer: Layer.Layer<Dispatcher> = internalUndici.dispatcherLayer | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const dispatcherLayerGlobal: Layer.Layer<Dispatcher> = internalUndici.dispatcherLayerGlobal | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const currentUndiciOptions: FiberRef.FiberRef<Partial<Undici.Dispatcher.RequestOptions>> = | ||
internalUndici.currentUndiciOptions | ||
/** | ||
* @since 1.0.0 | ||
* @category undici | ||
*/ | ||
export const withUndiciOptions: { | ||
( | ||
options: Partial<Undici.Dispatcher.RequestOptions> | ||
): <R, E, A>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> | ||
<R, E, A>(effect: Effect.Effect<A, E, R>, options: Partial<Undici.Dispatcher.RequestOptions>): Effect.Effect<A, E, R> | ||
} = internalUndici.withUndiciOptions | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makeUndici: (dispatcher: Undici.Dispatcher) => Client.Client.Default = internalUndici.make | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerUndici: Layer.Layer<Client.Client.Default> = internalUndici.layer | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerUndiciWithoutDispatcher: Layer.Layer<Client.Client.Default, never, Dispatcher> = | ||
internalUndici.layerWithoutDispatcher |
@@ -5,7 +5,3 @@ /** | ||
import type * as Worker from "@effect/platform/Worker" | ||
import type * as Schema from "@effect/schema/Schema" | ||
import type * as Context from "effect/Context" | ||
import type * as Effect from "effect/Effect" | ||
import type * as Layer from "effect/Layer" | ||
import type * as Scope from "effect/Scope" | ||
import type * as WorkerThreads from "node:worker_threads" | ||
@@ -16,40 +12,11 @@ import * as internal from "./internal/worker.js" | ||
* @since 1.0.0 | ||
* @category constructors | ||
* @category layers | ||
*/ | ||
export const makePool: <I, E, O>( | ||
options: Worker.WorkerPool.Options<I, WorkerThreads.Worker> | ||
) => Effect.Effect<Worker.WorkerPool<I, E, O>, never, Worker.WorkerManager | Scope.Scope> = internal.makePool | ||
export const layerManager: Layer.Layer<Worker.WorkerManager> = internal.layerManager | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolLayer: <Tag, I, E, O>( | ||
tag: Context.Tag<Tag, Worker.WorkerPool<I, E, O>>, | ||
options: Worker.WorkerPool.Options<I, WorkerThreads.Worker> | ||
) => Layer.Layer<Tag> = internal.makePoolLayer | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolSerialized: <I extends Schema.TaggedRequest.Any>( | ||
options: Worker.SerializedWorkerPool.Options<I, WorkerThreads.Worker> | ||
) => Effect.Effect<Worker.SerializedWorkerPool<I>, never, Worker.WorkerManager | Scope.Scope> = | ||
internal.makePoolSerialized | ||
/** | ||
* @since 1.0.0 | ||
* @category constructors | ||
*/ | ||
export const makePoolSerializedLayer: <Tag, I extends Schema.TaggedRequest.Any>( | ||
tag: Context.Tag<Tag, Worker.SerializedWorkerPool<I>>, | ||
options: Worker.SerializedWorkerPool.Options<I, WorkerThreads.Worker> | ||
) => Layer.Layer<Tag> = internal.makePoolSerializedLayer | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerManager: Layer.Layer<Worker.WorkerManager> = internal.layerManager | ||
export const layerWorker: Layer.Layer<Worker.PlatformWorker> = internal.layerWorker | ||
@@ -60,2 +27,4 @@ /** | ||
*/ | ||
export const layerWorker: Layer.Layer<Worker.PlatformWorker> = internal.layerWorker | ||
export const layer: ( | ||
spawn: (id: number) => WorkerThreads.Worker | ||
) => Layer.Layer<Worker.WorkerManager | Worker.Spawner, never, never> = internal.layer |
/** | ||
* @since 1.0.0 | ||
*/ | ||
import type { WorkerError } from "@effect/platform/WorkerError" | ||
import type * as Runner from "@effect/platform/WorkerRunner" | ||
import type * as Schema from "@effect/schema/Schema" | ||
import type * as Layer from "effect/Layer" | ||
import type * as Stream from "effect/Stream" | ||
import * as internal from "./internal/workerRunner.js" | ||
@@ -15,25 +12,2 @@ | ||
*/ | ||
export const layerPlatform: Layer.Layer<Runner.PlatformRunner> = internal.layerPlatform | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layer: <I, R, E, O>( | ||
process: (request: I) => Stream.Stream<O, E, R>, | ||
options?: Runner.Runner.Options<I, E, O> | undefined | ||
) => Layer.Layer<never, WorkerError, R> = internal.layer | ||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layerSerialized: < | ||
A extends Schema.TaggedRequest.Any, | ||
I, | ||
R, | ||
Handlers extends Runner.SerializedRunner.Handlers<A> | ||
>( | ||
schema: Schema.Schema<A, I, R>, | ||
handlers: Handlers | ||
) => Layer.Layer<never, WorkerError, R | Runner.SerializedRunner.HandlersContext<Handlers>> = internal.layerSerialized | ||
export const layer: Layer.Layer<Runner.PlatformRunner> = internal.layer |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
341887
203
5468
6
+ Addedundici@^6.18.0
+ Addedws@^8.17.0
+ Addedundici@6.21.1(transitive)
+ Addedws@8.18.0(transitive)
Updated@effect/platform-node-shared@^0.0.0-snapshot-d173a21c87b057e0151a0df4c89e7b7420ff7a99