@deslop/workbench 0.0.320 → 0.0.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server.js +180 -43
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -6250,6 +6250,96 @@ function isOutOfBounds(i, as) {
|
|
|
6250
6250
|
}
|
|
6251
6251
|
const clamp = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length));
|
|
6252
6252
|
/**
|
|
6253
|
+
* Reads an element at the given index safely, returning `Option.some` or
|
|
6254
|
+
* `Option.none` if the index is out of bounds.
|
|
6255
|
+
*
|
|
6256
|
+
* **When to use**
|
|
6257
|
+
*
|
|
6258
|
+
* Use when you need to read an array element by index and handle an
|
|
6259
|
+
* out-of-bounds index as `Option.none`.
|
|
6260
|
+
*
|
|
6261
|
+
* **Details**
|
|
6262
|
+
*
|
|
6263
|
+
* - The index is floored to an integer.
|
|
6264
|
+
* - Never throws.
|
|
6265
|
+
*
|
|
6266
|
+
* **Example** (Safe index access)
|
|
6267
|
+
*
|
|
6268
|
+
* ```ts
|
|
6269
|
+
* import { Array } from "effect"
|
|
6270
|
+
*
|
|
6271
|
+
* console.log(Array.get([1, 2, 3], 1)) // Some(2)
|
|
6272
|
+
* console.log(Array.get([1, 2, 3], 10)) // None
|
|
6273
|
+
* ```
|
|
6274
|
+
*
|
|
6275
|
+
* @see {@link getUnsafe} for indexed access that throws when the index is out of bounds
|
|
6276
|
+
* @see {@link head} for reading the first element as an `Option`
|
|
6277
|
+
* @see {@link last} for reading the last element as an `Option`
|
|
6278
|
+
*
|
|
6279
|
+
* @category getters
|
|
6280
|
+
* @since 2.0.0
|
|
6281
|
+
*/
|
|
6282
|
+
const get$10 = /*#__PURE__*/ dual(2, (self, index) => {
|
|
6283
|
+
const i = Math.floor(index);
|
|
6284
|
+
return isOutOfBounds(i, self) ? none() : some$1(self[i]);
|
|
6285
|
+
});
|
|
6286
|
+
/**
|
|
6287
|
+
* Reads an element at the given index, throwing if the index is out of bounds.
|
|
6288
|
+
*
|
|
6289
|
+
* **When to use**
|
|
6290
|
+
*
|
|
6291
|
+
* Use to read an element at a known valid index when out-of-bounds would be a
|
|
6292
|
+
* programming error.
|
|
6293
|
+
*
|
|
6294
|
+
* **Details**
|
|
6295
|
+
*
|
|
6296
|
+
* - Throws an `Error` with the message `"Index out of bounds: <i>"`.
|
|
6297
|
+
* - Prefer {@link get} for safe access.
|
|
6298
|
+
*
|
|
6299
|
+
* **Example** (Unsafe index access)
|
|
6300
|
+
*
|
|
6301
|
+
* ```ts
|
|
6302
|
+
* import { Array } from "effect"
|
|
6303
|
+
*
|
|
6304
|
+
* console.log(Array.getUnsafe([1, 2, 3], 1)) // 2
|
|
6305
|
+
* // Array.getUnsafe([1, 2, 3], 10) // throws Error
|
|
6306
|
+
* ```
|
|
6307
|
+
*
|
|
6308
|
+
* @see {@link get} — safe version returning `Option`
|
|
6309
|
+
*
|
|
6310
|
+
* @category unsafe
|
|
6311
|
+
* @since 4.0.0
|
|
6312
|
+
*/
|
|
6313
|
+
const getUnsafe$1 = /*#__PURE__*/ dual(2, (self, index) => {
|
|
6314
|
+
const i = Math.floor(index);
|
|
6315
|
+
if (isOutOfBounds(i, self)) throw new Error(`Index out of bounds: ${i}`);
|
|
6316
|
+
return self[i];
|
|
6317
|
+
});
|
|
6318
|
+
/**
|
|
6319
|
+
* Returns the first element of an array safely wrapped in `Option.some`, or
|
|
6320
|
+
* `Option.none` if the array is empty.
|
|
6321
|
+
*
|
|
6322
|
+
* **When to use**
|
|
6323
|
+
*
|
|
6324
|
+
* Use to safely get the first element of an array that may be empty.
|
|
6325
|
+
*
|
|
6326
|
+
* **Example** (Getting the first element)
|
|
6327
|
+
*
|
|
6328
|
+
* ```ts
|
|
6329
|
+
* import { Array } from "effect"
|
|
6330
|
+
*
|
|
6331
|
+
* console.log(Array.head([1, 2, 3])) // Some(1)
|
|
6332
|
+
* console.log(Array.head([])) // None
|
|
6333
|
+
* ```
|
|
6334
|
+
*
|
|
6335
|
+
* @see {@link headNonEmpty} — direct access when array is known non-empty
|
|
6336
|
+
* @see {@link last} — get the last element
|
|
6337
|
+
*
|
|
6338
|
+
* @category getters
|
|
6339
|
+
* @since 2.0.0
|
|
6340
|
+
*/
|
|
6341
|
+
const head = /*#__PURE__*/ get$10(0);
|
|
6342
|
+
/**
|
|
6253
6343
|
* Returns the first element of a `NonEmptyReadonlyArray` directly (no `Option`
|
|
6254
6344
|
* wrapper).
|
|
6255
6345
|
*
|
|
@@ -6271,11 +6361,7 @@ const clamp = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length));
|
|
|
6271
6361
|
* @category getters
|
|
6272
6362
|
* @since 2.0.0
|
|
6273
6363
|
*/
|
|
6274
|
-
const headNonEmpty = /*#__PURE__*/ (
|
|
6275
|
-
const i = Math.floor(index);
|
|
6276
|
-
if (isOutOfBounds(i, self)) throw new Error(`Index out of bounds: ${i}`);
|
|
6277
|
-
return self[i];
|
|
6278
|
-
}))(0);
|
|
6364
|
+
const headNonEmpty = /*#__PURE__*/ getUnsafe$1(0);
|
|
6279
6365
|
/**
|
|
6280
6366
|
* Returns the last element of an array safely wrapped in `Option.some`, or
|
|
6281
6367
|
* `Option.none` if the array is empty.
|
|
@@ -32223,6 +32309,28 @@ function decodeUnknownEffect$1(schema, options) {
|
|
|
32223
32309
|
return options === void 0 ? parser : (input, overrideOptions) => parser(input, mergeParseOptions(options, overrideOptions));
|
|
32224
32310
|
}
|
|
32225
32311
|
/**
|
|
32312
|
+
* Creates a decoder for `unknown` input that returns an `Option` safely.
|
|
32313
|
+
*
|
|
32314
|
+
* **When to use**
|
|
32315
|
+
*
|
|
32316
|
+
* Use when you need a synchronous yes/no decode from untyped input and do not
|
|
32317
|
+
* need schema issue details.
|
|
32318
|
+
*
|
|
32319
|
+
* **Details**
|
|
32320
|
+
*
|
|
32321
|
+
* The returned function produces `Option.some` with the decoded `Type` on success
|
|
32322
|
+
* or `Option.none` on failure, discarding issue details.
|
|
32323
|
+
*
|
|
32324
|
+
* @see {@link decodeOption} for input already typed as the schema's `Encoded` type
|
|
32325
|
+
* @see {@link decodeUnknownResult} for retaining schema issues as data
|
|
32326
|
+
*
|
|
32327
|
+
* @category decoding
|
|
32328
|
+
* @since 3.10.0
|
|
32329
|
+
*/
|
|
32330
|
+
function decodeUnknownOption$1(schema, options) {
|
|
32331
|
+
return asOption(decodeUnknownEffect$1(schema, options));
|
|
32332
|
+
}
|
|
32333
|
+
/**
|
|
32226
32334
|
* Creates an effectful encoder for `unknown` input.
|
|
32227
32335
|
*
|
|
32228
32336
|
* **When to use**
|
|
@@ -32306,6 +32414,11 @@ function run(ast) {
|
|
|
32306
32414
|
function asExit(parser) {
|
|
32307
32415
|
return (input, options) => runSyncExit(parser(input, options));
|
|
32308
32416
|
}
|
|
32417
|
+
/** @internal */
|
|
32418
|
+
function asOption(parser) {
|
|
32419
|
+
const parserExit = asExit(parser);
|
|
32420
|
+
return (input, options) => getSuccess(parserExit(input, options));
|
|
32421
|
+
}
|
|
32309
32422
|
function asSync(parser) {
|
|
32310
32423
|
return (input, options) => runSync(mapErrorEager(parser(input, options), (issue) => new Error(issue.toString(), { cause: issue })));
|
|
32311
32424
|
}
|
|
@@ -32597,6 +32710,26 @@ function decodeUnknownEffect(schema, options) {
|
|
|
32597
32710
|
*/
|
|
32598
32711
|
const decodeEffect = decodeUnknownEffect;
|
|
32599
32712
|
/**
|
|
32713
|
+
* Decodes an `unknown` input against a schema, returning an `Option` that is
|
|
32714
|
+
* `Some` with the decoded value on success or `None` on failure.
|
|
32715
|
+
*
|
|
32716
|
+
* **When to use**
|
|
32717
|
+
*
|
|
32718
|
+
* Use when the input type is not statically known and you only need to know
|
|
32719
|
+
* whether decoding succeeded.
|
|
32720
|
+
*
|
|
32721
|
+
* **Details**
|
|
32722
|
+
*
|
|
32723
|
+
* Prefer this over {@link decodeUnknownExit} or {@link decodeUnknownEffect}
|
|
32724
|
+
* when you don't need error details. For typed input use {@link decodeOption}.
|
|
32725
|
+
* Options may be provided either when creating the decoder or when applying it;
|
|
32726
|
+
* application options override creation options.
|
|
32727
|
+
*
|
|
32728
|
+
* @category decoding
|
|
32729
|
+
* @since 3.10.0
|
|
32730
|
+
*/
|
|
32731
|
+
const decodeUnknownOption = decodeUnknownOption$1;
|
|
32732
|
+
/**
|
|
32600
32733
|
* Encodes an `unknown` input against a schema, returning an `Effect` that
|
|
32601
32734
|
* succeeds with the encoded value or fails with a {@link SchemaError}.
|
|
32602
32735
|
*
|
|
@@ -52449,6 +52582,7 @@ var GitWorktree = class extends Service()("@deslop/git/service/GitWorktree", { m
|
|
|
52449
52582
|
};
|
|
52450
52583
|
//#endregion
|
|
52451
52584
|
//#region ../../packages/portless/src/lib/utils.ts
|
|
52585
|
+
const PackageJson = Struct({ scripts: optional(Record(String$1, String$1)) });
|
|
52452
52586
|
function command(script, port) {
|
|
52453
52587
|
return make$40("vp", [
|
|
52454
52588
|
"run",
|
|
@@ -52474,23 +52608,23 @@ const discover = fnUntraced(function* (cwd, input) {
|
|
|
52474
52608
|
"package.json",
|
|
52475
52609
|
"**/package.json"
|
|
52476
52610
|
], { cwd }));
|
|
52477
|
-
return yield* pipe(pipe(split$1("\n")(output), filter$2((path) => path === "package.json" || endsWith("/package.json")(path))), map$7((packagePath) => pipe(
|
|
52478
|
-
|
|
52479
|
-
|
|
52480
|
-
})), catch_$2(() => succeed$3(
|
|
52481
|
-
if (
|
|
52482
|
-
const packageDirectory =
|
|
52611
|
+
return yield* pipe(pipe(split$1("\n")(output), filter$2((path) => path === "package.json" || endsWith("/package.json")(path))), map$7((packagePath) => pipe(fs.readFileString(path.join(cwd, packagePath)), flatMap$2((source) => try_({
|
|
52612
|
+
catch: (error) => error,
|
|
52613
|
+
try: () => pipe(JSON.parse(source), decodeUnknownOption(PackageJson))
|
|
52614
|
+
})), catch_$2(() => succeed$3(none())), flatMap$2((packageJson) => {
|
|
52615
|
+
if (isNone(packageJson)) return succeed$3([]);
|
|
52616
|
+
const packageDirectory = packagePath === "package.json" ? cwd : path.join(cwd, path.dirname(packagePath));
|
|
52483
52617
|
const folder = path.basename(packageDirectory);
|
|
52484
|
-
const scriptEntries = pipe(Object.entries(
|
|
52485
|
-
const packageOrigin =
|
|
52618
|
+
const scriptEntries = pipe(Object.entries(packageJson.value.scripts ?? {}), filter$2((entry) => entry[0] === "dev" || startsWith("dev:")(entry[0])));
|
|
52619
|
+
const packageOrigin = input.origin([
|
|
52486
52620
|
folder,
|
|
52487
52621
|
path.basename(cwd),
|
|
52488
52622
|
"localhost"
|
|
52489
|
-
].join(".")
|
|
52623
|
+
].join("."));
|
|
52490
52624
|
return pipe(scriptEntries, map$7((entry) => {
|
|
52491
52625
|
const name = entry[0];
|
|
52492
52626
|
const scriptCommand = entry[1];
|
|
52493
|
-
return map$4(input.port(`${
|
|
52627
|
+
return map$4(input.port(`${packagePath}:${name}`), (port) => {
|
|
52494
52628
|
const service = /^dev:(.+)$/u.exec(name)?.[1] ?? "dev";
|
|
52495
52629
|
const host = [
|
|
52496
52630
|
service,
|
|
@@ -52498,7 +52632,7 @@ const discover = fnUntraced(function* (cwd, input) {
|
|
|
52498
52632
|
path.basename(cwd),
|
|
52499
52633
|
"localhost"
|
|
52500
52634
|
].join(".");
|
|
52501
|
-
const origin =
|
|
52635
|
+
const origin = input.origin(host);
|
|
52502
52636
|
return {
|
|
52503
52637
|
host,
|
|
52504
52638
|
port,
|
|
@@ -52517,9 +52651,9 @@ const discover = fnUntraced(function* (cwd, input) {
|
|
|
52517
52651
|
name,
|
|
52518
52652
|
origin,
|
|
52519
52653
|
packageFolder: folder,
|
|
52520
|
-
packagePath
|
|
52654
|
+
packagePath,
|
|
52521
52655
|
service,
|
|
52522
|
-
sessionId: `${
|
|
52656
|
+
sessionId: `${packagePath}:${name}:${Date.now()}:${Math.random()}`
|
|
52523
52657
|
}
|
|
52524
52658
|
};
|
|
52525
52659
|
});
|
|
@@ -52587,9 +52721,9 @@ const INJECTED_HEAD = `<script>
|
|
|
52587
52721
|
<\/script>
|
|
52588
52722
|
<script crossorigin="anonymous" src="//unpkg.com/react-scan/dist/auto.global.js" onload="window.reactScan?.({allowInIframe: true, _debug: 'verbose'})"><\/script>
|
|
52589
52723
|
<script src="https://unpkg.com/react-grab/dist/index.global.js"><\/script>`;
|
|
52590
|
-
|
|
52724
|
+
function injectScripts(html) {
|
|
52591
52725
|
return /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (match) => `${match}\n${INJECTED_HEAD}`) : `${INJECTED_HEAD}\n${html}`;
|
|
52592
|
-
}
|
|
52726
|
+
}
|
|
52593
52727
|
const proxy = fnUntraced(function* (request, origin) {
|
|
52594
52728
|
const webRequest = yield* toWeb(request);
|
|
52595
52729
|
const [pathname = "/", search = ""] = request.url.split("?");
|
|
@@ -52613,7 +52747,7 @@ const proxy = fnUntraced(function* (request, origin) {
|
|
|
52613
52747
|
}));
|
|
52614
52748
|
const body = yield* tryPromise(() => upstreamResponse.text());
|
|
52615
52749
|
headers.set("content-type", "text/html; charset=utf-8");
|
|
52616
|
-
return fromWeb(new Response(
|
|
52750
|
+
return fromWeb(new Response(injectScripts(body), {
|
|
52617
52751
|
headers,
|
|
52618
52752
|
status: upstreamResponse.status,
|
|
52619
52753
|
statusText: upstreamResponse.statusText
|
|
@@ -52621,41 +52755,46 @@ const proxy = fnUntraced(function* (request, origin) {
|
|
|
52621
52755
|
});
|
|
52622
52756
|
const proxyWebSocket = fnUntraced(function* (request, origin) {
|
|
52623
52757
|
const [pathname = "/", search = ""] = request.url.split("?");
|
|
52624
|
-
const protocols = request.headers["sec-websocket-protocol"]
|
|
52758
|
+
const protocols = pipe(fromUndefinedOr(request.headers["sec-websocket-protocol"]), map$9((protocols) => pipe(protocols, split$1(","), map$7(trim), filter$2(isNonEmpty$1))));
|
|
52625
52759
|
const inbound = yield* request.upgrade;
|
|
52626
52760
|
const upstreamUrl = new URL(origin);
|
|
52627
52761
|
upstreamUrl.protocol = upstreamUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
52628
52762
|
upstreamUrl.pathname = pathname;
|
|
52629
52763
|
upstreamUrl.search = search;
|
|
52630
|
-
const outbound = yield* makeWebSocket(upstreamUrl.toString(), { protocols }).pipe(provide(layerWebSocketConstructorGlobal));
|
|
52764
|
+
const outbound = yield* makeWebSocket(upstreamUrl.toString(), { protocols: getOrUndefined$1(protocols) }).pipe(provide(layerWebSocketConstructorGlobal));
|
|
52631
52765
|
const writeInbound = yield* inbound.writer;
|
|
52632
52766
|
const writeOutbound = yield* outbound.writer;
|
|
52633
52767
|
yield* outbound.runRaw((message) => writeInbound(message)).pipe(catchReason("SocketError", "SocketCloseError", (reason) => writeInbound(new CloseEvent(reason.code, reason.closeReason)).pipe(catch_$2(() => void_$1))), catch_$2(() => writeInbound(new CloseEvent(1011, "proxy error")).pipe(catch_$2(() => void_$1))), forkScoped);
|
|
52634
|
-
yield* inbound.runRaw((message) => writeOutbound(
|
|
52768
|
+
yield* inbound.runRaw((message) => writeOutbound(isString(message) ? message : message.slice())).pipe(catch_$2(() => void_$1), ensuring$2(writeOutbound(new CloseEvent()).pipe(catch_$2(() => void_$1))));
|
|
52635
52769
|
return empty();
|
|
52636
52770
|
});
|
|
52637
|
-
|
|
52638
|
-
return fromUndefinedOr(host
|
|
52639
|
-
}
|
|
52771
|
+
function requestHostname(host) {
|
|
52772
|
+
return pipe(fromUndefinedOr(host), flatMap$6((host) => pipe(host, split$1(":"), head)));
|
|
52773
|
+
}
|
|
52640
52774
|
function isLocalHostname(hostname) {
|
|
52641
52775
|
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]";
|
|
52642
52776
|
}
|
|
52643
|
-
var Portless = class Portless extends Service()("@deslop/portless/Portless", { make:
|
|
52777
|
+
var Portless = class Portless extends Service()("@deslop/portless/Portless", { make: gen(function* () {
|
|
52778
|
+
const server = yield* HttpServer;
|
|
52779
|
+
const proxyPort = server.address._tag === "TcpAddress" ? server.address.port.toString() : yield* die$1(/* @__PURE__ */ new Error("portless requires a TCP HTTP server address"));
|
|
52644
52780
|
const ports = /* @__PURE__ */ new Map();
|
|
52645
52781
|
const routes = /* @__PURE__ */ new Map();
|
|
52782
|
+
function origin(host) {
|
|
52783
|
+
return `http://${host}:${proxyPort}`;
|
|
52784
|
+
}
|
|
52646
52785
|
const middleware = fnUntraced(function* (app) {
|
|
52647
52786
|
const request = yield* HttpServerRequest;
|
|
52648
|
-
const hostname =
|
|
52787
|
+
const hostname = requestHostname(request.headers["host"]);
|
|
52649
52788
|
if (isNone(hostname) || isLocalHostname(hostname.value)) return yield* app;
|
|
52650
52789
|
if (!hostname.value.endsWith(".localhost")) return yield* app;
|
|
52651
|
-
const route =
|
|
52790
|
+
const route = lookup(request.headers["host"]);
|
|
52652
52791
|
if (isNone(route)) return empty({ status: 404 });
|
|
52653
52792
|
if (request.headers["upgrade"]?.toLowerCase() === "websocket") return yield* proxyWebSocket(request, route.value);
|
|
52654
52793
|
return yield* proxy(request, route.value);
|
|
52655
52794
|
});
|
|
52656
|
-
|
|
52657
|
-
return pipe(
|
|
52658
|
-
}
|
|
52795
|
+
function lookup(host) {
|
|
52796
|
+
return pipe(requestHostname(host), flatMap$6((hostname) => fromUndefinedOr(routes.get(hostname))));
|
|
52797
|
+
}
|
|
52659
52798
|
const port = fnUntraced(function* (key) {
|
|
52660
52799
|
const existing = ports.get(key);
|
|
52661
52800
|
if (existing !== void 0) return existing;
|
|
@@ -52671,15 +52810,13 @@ var Portless = class Portless extends Service()("@deslop/portless/Portless", { m
|
|
|
52671
52810
|
});
|
|
52672
52811
|
return {
|
|
52673
52812
|
middleware,
|
|
52674
|
-
|
|
52675
|
-
register: fnUntraced(function* (host, port) {
|
|
52676
|
-
routes.set(host, `http://127.0.0.1:${port}`);
|
|
52677
|
-
}),
|
|
52678
|
-
scripts: fnUntraced(function* (cwd, input) {
|
|
52813
|
+
scripts: fnUntraced(function* (cwd) {
|
|
52679
52814
|
return yield* pipe(discover(cwd, {
|
|
52680
|
-
|
|
52681
|
-
|
|
52682
|
-
}),
|
|
52815
|
+
origin,
|
|
52816
|
+
port: (sessionId) => port(`${cwd}:${sessionId}`)
|
|
52817
|
+
}), tap((discovered) => sync(() => {
|
|
52818
|
+
for (const route of discovered) routes.set(route.host, `http://127.0.0.1:${route.port}`);
|
|
52819
|
+
})), map$4((routes) => routes.map((route) => ({
|
|
52683
52820
|
host: route.host,
|
|
52684
52821
|
port: route.port,
|
|
52685
52822
|
script: {
|
|
@@ -53055,11 +53192,11 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
|
|
|
53055
53192
|
const portlessWorktrees = yield* make$46({
|
|
53056
53193
|
idleTimeToLive: infinity,
|
|
53057
53194
|
lookup: fnUntraced(function* (cwd) {
|
|
53058
|
-
const scripts = yield* pipe(portless.scripts(cwd
|
|
53195
|
+
const scripts = yield* pipe(portless.scripts(cwd), mapError$2((cause) => new TerminalError({
|
|
53059
53196
|
cause,
|
|
53060
53197
|
message: `failed to discover portless scripts in ${cwd}`
|
|
53061
53198
|
})));
|
|
53062
|
-
yield* all(pipe(scripts, map$7((script) =>
|
|
53199
|
+
yield* all(pipe(scripts, map$7((script) => update$1(portlessScripts, (current) => set$2(current, script.script.sessionId, script.script)))), { discard: true });
|
|
53063
53200
|
return pipe(scripts, map$7((route) => ({
|
|
53064
53201
|
baseOrigin: route.script.baseOrigin,
|
|
53065
53202
|
command: route.script.command,
|