@deslop/workbench 0.0.344 → 0.0.357

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/client/assets/-workbench-terminal-DyfxJcjD.js +145 -0
  2. package/dist/client/assets/agent-CA1IdfRT.js +1 -0
  3. package/dist/client/assets/agent-COvRE6oy.js +2 -0
  4. package/dist/client/assets/button-Dz6Az3h_.js +16 -0
  5. package/dist/client/assets/{diff-BwOj6t_o.js → diff-BqnMP7Ys.js} +44 -44
  6. package/dist/client/assets/{diff-COOvYjfB.js → diff-CLnQZZVT.js} +2 -2
  7. package/dist/client/assets/{external-link-DR7_wu3r.js → external-link-DPI4TAq4.js} +1 -1
  8. package/dist/client/assets/{fallbacks-D-9MltuA.js → fallbacks-uU4M5NOw.js} +1 -1
  9. package/dist/client/assets/{index-DCRiD9Nz.js → index-Mo4bEjHb.js} +3 -3
  10. package/dist/client/assets/input-group-1-P7Y_75.js +153 -0
  11. package/dist/client/assets/loader-circle-BxillczB.js +1 -0
  12. package/dist/client/assets/{portless-nerboxiJ.js → portless-ClPWjTC4.js} +1 -1
  13. package/dist/client/assets/portless-QJD7ZmA9.js +2 -0
  14. package/dist/client/assets/{resizable-ChkQg6Mj.js → resizable-BaJ5ba6-.js} +1 -1
  15. package/dist/client/assets/route-C-L2dkin.js +45 -0
  16. package/dist/client/assets/route-b5JXfzPO.js +2 -0
  17. package/dist/client/assets/run-C0ukWbxF.js +2 -0
  18. package/dist/client/assets/run-cjBxZ3gl.js +1 -0
  19. package/dist/client/assets/state-CVjPP5QG.js +2 -0
  20. package/dist/client/assets/terminal-B5ko1jIG.js +2 -0
  21. package/dist/client/assets/terminal-CA1dMT3m.js +1 -0
  22. package/dist/client/assets/{triangle-alert-CQsOhrGn.js → triangle-alert-CTEZG9zF.js} +1 -1
  23. package/dist/client/index.html +11 -11
  24. package/dist/server.js +519 -1553
  25. package/package.json +2 -4
  26. package/dist/client/assets/agent-BATV5D0O.js +0 -1
  27. package/dist/client/assets/agent-K-v27T1K.js +0 -2
  28. package/dist/client/assets/button-f42ZKq6E.js +0 -16
  29. package/dist/client/assets/input-group-mMwtG03E.js +0 -153
  30. package/dist/client/assets/loader-circle-DEYAvEPU.js +0 -1
  31. package/dist/client/assets/portless-C8dLcQQw.js +0 -2
  32. package/dist/client/assets/route-DAz8IJkt.js +0 -2
  33. package/dist/client/assets/route-GFqYSDK4.js +0 -45
  34. package/dist/client/assets/run-B16WQaws.js +0 -2
  35. package/dist/client/assets/run-BHEbhvk3.js +0 -1
  36. package/dist/client/assets/state-BOj5tZ-Q.js +0 -2
  37. package/dist/client/assets/terminal-B410vkZ0.js +0 -1
  38. package/dist/client/assets/terminal-BQ9AR6VK.js +0 -145
  39. package/dist/client/assets/terminal-Br297Oa8.js +0 -2
package/dist/server.js CHANGED
@@ -21,8 +21,6 @@ import * as NodeStreamP from "node:stream/promises";
21
21
  import { pipeline } from "node:stream/promises";
22
22
  import * as readline from "node:readline";
23
23
  import * as nodePty from "@lydell/node-pty";
24
- import SerializeModule from "@xterm/addon-serialize";
25
- import HeadlessModule from "@xterm/headless";
26
24
  //#region \0rolldown/runtime.js
27
25
  var __create = Object.create;
28
26
  var __defProp = Object.defineProperty;
@@ -6386,7 +6384,7 @@ const clamp = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length));
6386
6384
  * @category getters
6387
6385
  * @since 2.0.0
6388
6386
  */
6389
- const get$10 = /*#__PURE__*/ dual(2, (self, index) => {
6387
+ const get$9 = /*#__PURE__*/ dual(2, (self, index) => {
6390
6388
  const i = Math.floor(index);
6391
6389
  return isOutOfBounds(i, self) ? none() : some(self[i]);
6392
6390
  });
@@ -6445,7 +6443,7 @@ const getUnsafe$1 = /*#__PURE__*/ dual(2, (self, index) => {
6445
6443
  * @category getters
6446
6444
  * @since 2.0.0
6447
6445
  */
6448
- const head = /*#__PURE__*/ get$10(0);
6446
+ const head = /*#__PURE__*/ get$9(0);
6449
6447
  /**
6450
6448
  * Returns the first element of a `NonEmptyReadonlyArray` directly (no `Option`
6451
6449
  * wrapper).
@@ -7200,7 +7198,7 @@ const ServiceProto = {
7200
7198
  .../*#__PURE__*/ Prototype({
7201
7199
  label: "Service",
7202
7200
  evaluate(fiber) {
7203
- return exitSucceed(get$9(fiber.context, this));
7201
+ return exitSucceed(get$8(fiber.context, this));
7204
7202
  }
7205
7203
  }),
7206
7204
  toJSON() {
@@ -7217,10 +7215,10 @@ const ServiceProto = {
7217
7215
  return make$62(this, self);
7218
7216
  },
7219
7217
  use(f) {
7220
- return withFiber$1((fiber) => f(get$9(fiber.context, this)));
7218
+ return withFiber$1((fiber) => f(get$8(fiber.context, this)));
7221
7219
  },
7222
7220
  useSync(f) {
7223
- return withFiber$1((fiber) => exitSucceed(f(get$9(fiber.context, this))));
7221
+ return withFiber$1((fiber) => exitSucceed(f(get$8(fiber.context, this))));
7224
7222
  }
7225
7223
  };
7226
7224
  const ReferenceTypeId = "~effect/Context/Reference";
@@ -7559,7 +7557,7 @@ const getUnsafe = /*#__PURE__*/ dual(2, (self, service) => {
7559
7557
  * @category getters
7560
7558
  * @since 2.0.0
7561
7559
  */
7562
- const get$9 = getUnsafe;
7560
+ const get$8 = getUnsafe;
7563
7561
  /**
7564
7562
  * Gets the value for a `Context.Reference`, returning its cached default when
7565
7563
  * the context does not contain an override.
@@ -10107,7 +10105,7 @@ const scope$1 = scopeTag;
10107
10105
  /** @internal */
10108
10106
  const provideScope = /*#__PURE__*/ provideService$1(scopeTag);
10109
10107
  /** @internal */
10110
- const scoped$4 = (self) => withFiber$1((fiber) => {
10108
+ const scoped$2 = (self) => withFiber$1((fiber) => {
10111
10109
  const prev = fiber.context;
10112
10110
  const scope = scopeMakeUnsafe();
10113
10111
  fiber.setContext(add(fiber.context, scopeTag, scope));
@@ -10597,11 +10595,11 @@ const NoopSpanProto = {
10597
10595
  const noopSpan = (options) => Object.assign(Object.create(NoopSpanProto), options);
10598
10596
  const filterDisablePropagation = (span) => {
10599
10597
  if (!span) return none();
10600
- return get$9(span.annotations, DisablePropagation) ? span._tag === "Span" ? filterDisablePropagation(getOrUndefined$1(span.parent)) : none() : some(span);
10598
+ return get$8(span.annotations, DisablePropagation) ? span._tag === "Span" ? filterDisablePropagation(getOrUndefined$1(span.parent)) : none() : some(span);
10601
10599
  };
10602
10600
  /** @internal */
10603
10601
  const makeSpanUnsafe = (fiber, name, options) => {
10604
- const disablePropagation = !fiber.getRef(TracerEnabled$1) || options?.annotations && get$9(options.annotations, DisablePropagation);
10602
+ const disablePropagation = !fiber.getRef(TracerEnabled$1) || options?.annotations && get$8(options.annotations, DisablePropagation);
10605
10603
  const parent = options?.parent !== void 0 ? some(options.parent) : options?.root ? none() : filterDisablePropagation(fiber.currentSpan);
10606
10604
  let span;
10607
10605
  if (disablePropagation) span = noopSpan({
@@ -12521,7 +12519,7 @@ const effectDiscard = (effect) => effectContext(as$1(effect, empty$12()));
12521
12519
  */
12522
12520
  const unwrap$4 = (self) => {
12523
12521
  const service = Service("effect/Layer/unwrap");
12524
- return flatMap$3(effect(service)(self), get$9(service));
12522
+ return flatMap$3(effect(service)(self), get$8(service));
12525
12523
  };
12526
12524
  const mergeAllEffect = (layers, memoMap, scope) => {
12527
12525
  const parentScope = forkUnsafe(scope, "parallel");
@@ -12870,7 +12868,7 @@ const flatMap$3 = /*#__PURE__*/ dual(2, (self, f) => fromBuild((memoMap, scope)
12870
12868
  * @category converting
12871
12869
  * @since 2.0.0
12872
12870
  */
12873
- const launch = (self) => scoped$4(andThen$1(build(self), never$2));
12871
+ const launch = (self) => scoped$2(andThen$1(build(self), never$2));
12874
12872
  //#endregion
12875
12873
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Cause.js
12876
12874
  /**
@@ -13827,30 +13825,6 @@ const toDateUtc$1 = (self) => new Date(self.epochMilliseconds);
13827
13825
  */
13828
13826
  const Number$4 = globalThis.Number;
13829
13827
  /**
13830
- * Returns the next power of 2 from the given number.
13831
- *
13832
- * **When to use**
13833
- *
13834
- * Use to round a number up to the next power of two.
13835
- *
13836
- * **Example** (Finding the next power of two)
13837
- *
13838
- * ```ts
13839
- * import { Number } from "effect"
13840
- * import * as assert from "node:assert"
13841
- *
13842
- * assert.deepStrictEqual(Number.nextPow2(5), 8)
13843
- * assert.deepStrictEqual(Number.nextPow2(17), 32)
13844
- * ```
13845
- *
13846
- * @category math
13847
- * @since 2.0.0
13848
- */
13849
- const nextPow2 = (n) => {
13850
- const nextPow = Math.ceil(Math.log(n) / Math.log(2));
13851
- return Math.max(Math.pow(2, nextPow), 2);
13852
- };
13853
- /**
13854
13828
  * Parses a `number` from a `string` safely using the `Number()` function.
13855
13829
  * The following special string values are supported: "NaN", "Infinity", "-Infinity".
13856
13830
  *
@@ -14571,7 +14545,7 @@ const MetricRegistry = /*#__PURE__*/ Reference("~effect/observability/Metric/Met
14571
14545
  * @since 4.0.0
14572
14546
  */
14573
14547
  const snapshotUnsafe = (context) => {
14574
- const registry = get$9(context, MetricRegistry);
14548
+ const registry = get$8(context, MetricRegistry);
14575
14549
  return Array.from(registry.values()).map(({ hooks, ...meta }) => ({
14576
14550
  ...meta,
14577
14551
  state: hooks.get(context)
@@ -17046,7 +17020,7 @@ const scope = scope$1;
17046
17020
  * @category resource management
17047
17021
  * @since 2.0.0
17048
17022
  */
17049
- const scoped$3 = scoped$4;
17023
+ const scoped$1 = scoped$2;
17050
17024
  /**
17051
17025
  * Creates a scoped effect by providing access to the scope.
17052
17026
  *
@@ -23356,7 +23330,7 @@ const takeAll$2 = (self) => takeN(self, self.length);
23356
23330
  * @category elements
23357
23331
  * @since 4.0.0
23358
23332
  */
23359
- const take$3 = (self) => {
23333
+ const take$2 = (self) => {
23360
23334
  if (!self.head) return Empty$2;
23361
23335
  const message = self.head.array[self.head.offset];
23362
23336
  if (self.head.mutable) self.head.array[self.head.offset] = void 0;
@@ -23525,39 +23499,6 @@ const make$50 = (value) => {
23525
23499
  return ref;
23526
23500
  };
23527
23501
  /**
23528
- * Gets the current value of the MutableRef.
23529
- *
23530
- * **When to use**
23531
- *
23532
- * Use to read the current value without mutating the reference.
23533
- *
23534
- * **Example** (Reading current values)
23535
- *
23536
- * ```ts
23537
- * import { MutableRef } from "effect"
23538
- *
23539
- * const ref = MutableRef.make("hello")
23540
- * console.log(MutableRef.get(ref)) // "hello"
23541
- *
23542
- * MutableRef.set(ref, "world")
23543
- * console.log(MutableRef.get(ref)) // "world"
23544
- *
23545
- * // Reading complex objects
23546
- * const config = MutableRef.make({ port: 3000, host: "localhost" })
23547
- * const currentConfig = MutableRef.get(config)
23548
- * console.log(currentConfig.port) // 3000
23549
- *
23550
- * // Multiple reads return the same value
23551
- * const value1 = MutableRef.get(ref)
23552
- * const value2 = MutableRef.get(ref)
23553
- * console.log(value1 === value2) // true
23554
- * ```
23555
- *
23556
- * @category general
23557
- * @since 2.0.0
23558
- */
23559
- const get$8 = (self) => self.current;
23560
- /**
23561
23502
  * Sets the MutableRef to a new value and returns the reference.
23562
23503
  *
23563
23504
  * **When to use**
@@ -23694,41 +23635,6 @@ const SubscriptionTypeId = "~effect/PubSub/Subscription";
23694
23635
  */
23695
23636
  const make$49 = (options) => sync(() => makePubSubUnsafe(options.atomicPubSub(), /* @__PURE__ */ new Map(), makeUnsafe$6(), makeUnsafe$4(false), make$50(false), options.strategy()));
23696
23637
  /**
23697
- * Creates a bounded `PubSub` that applies backpressure when it reaches
23698
- * capacity.
23699
- *
23700
- * **Details**
23701
- *
23702
- * Published messages are retained until all current subscribers have taken
23703
- * them. When the capacity is full, publishers suspend until space is available.
23704
- * Pass an options object to configure both `capacity` and an optional replay
23705
- * buffer for late subscribers.
23706
- *
23707
- * **Example** (Creating a bounded PubSub)
23708
- *
23709
- * ```ts
23710
- * import { Effect, PubSub } from "effect"
23711
- *
23712
- * const program = Effect.gen(function*() {
23713
- * // Create bounded PubSub with capacity 100
23714
- * const pubsub = yield* PubSub.bounded<string>(100)
23715
- *
23716
- * // Create with replay buffer for late subscribers
23717
- * const pubsubWithReplay = yield* PubSub.bounded<string>({
23718
- * capacity: 100,
23719
- * replay: 10 // Last 10 messages replayed to new subscribers
23720
- * })
23721
- * })
23722
- * ```
23723
- *
23724
- * @category constructors
23725
- * @since 2.0.0
23726
- */
23727
- const bounded$1 = (capacity) => make$49({
23728
- atomicPubSub: () => makeAtomicBounded(capacity),
23729
- strategy: () => new BackPressureStrategy()
23730
- });
23731
- /**
23732
23638
  * Creates an unbounded `PubSub`.
23733
23639
  *
23734
23640
  * **Example** (Creating an unbounded PubSub)
@@ -23762,47 +23668,11 @@ const bounded$1 = (capacity) => make$49({
23762
23668
  * @category constructors
23763
23669
  * @since 2.0.0
23764
23670
  */
23765
- const unbounded$1 = (options) => make$49({
23671
+ const unbounded = (options) => make$49({
23766
23672
  atomicPubSub: () => makeAtomicUnbounded(options),
23767
23673
  strategy: () => new DroppingStrategy()
23768
23674
  });
23769
23675
  /**
23770
- * Creates a bounded atomic PubSub implementation with optional replay buffer.
23771
- *
23772
- * **When to use**
23773
- *
23774
- * Use to provide bounded message storage when building a custom `PubSub` with
23775
- * `make` and an explicit delivery strategy.
23776
- *
23777
- * **Details**
23778
- *
23779
- * Pass either a capacity number or an options object with `capacity` and
23780
- * optional `replay`. A positive `replay` value enables a replay buffer for late
23781
- * subscribers, and fractional replay sizes are rounded up.
23782
- *
23783
- * **Gotchas**
23784
- *
23785
- * The capacity must be greater than zero; invalid capacities throw
23786
- * synchronously before an atomic implementation is created.
23787
- *
23788
- * @see {@link make} for constructing a `PubSub` from an atomic implementation and delivery strategy
23789
- * @see {@link makeAtomicUnbounded} for an atomic implementation without a bounded capacity
23790
- * @see {@link bounded} for the higher-level backpressure constructor
23791
- * @see {@link dropping} for the higher-level dropping constructor
23792
- * @see {@link sliding} for the higher-level sliding constructor
23793
- *
23794
- * @category constructors
23795
- * @since 4.0.0
23796
- */
23797
- const makeAtomicBounded = (capacity) => {
23798
- const options = typeof capacity === "number" ? { capacity } : capacity;
23799
- ensureCapacity(options.capacity);
23800
- const replayBuffer = options.replay && options.replay > 0 ? new ReplayBuffer(Math.ceil(options.replay)) : void 0;
23801
- if (options.capacity === 1) return new BoundedPubSubSingle(replayBuffer);
23802
- else if (nextPow2(options.capacity) === options.capacity) return new BoundedPubSubPow2(options.capacity, replayBuffer);
23803
- else return new BoundedPubSubArb(options.capacity, replayBuffer);
23804
- };
23805
- /**
23806
23676
  * Creates an unbounded atomic PubSub implementation with optional replay buffer.
23807
23677
  *
23808
23678
  * **When to use**
@@ -23824,93 +23694,6 @@ const makeAtomicBounded = (capacity) => {
23824
23694
  */
23825
23695
  const makeAtomicUnbounded = (options) => new UnboundedPubSub(options?.replay ? new ReplayBuffer(options.replay) : void 0);
23826
23696
  /**
23827
- * Shuts down the `PubSub`, interrupting suspended publishers and subscribers
23828
- * and finalizing active subscriptions.
23829
- *
23830
- * **Details**
23831
- *
23832
- * After shutdown, `publish` and `publishAll` succeed with `false`,
23833
- * `publishUnsafe` returns `false`, and subscription operations such as `take`
23834
- * interrupt.
23835
- *
23836
- * **Example** (Shutting down a PubSub)
23837
- *
23838
- * ```ts
23839
- * import { Effect, PubSub } from "effect"
23840
- *
23841
- * const program = Effect.gen(function*() {
23842
- * const pubsub = yield* PubSub.bounded<string>(1)
23843
- *
23844
- * // Shutdown the PubSub
23845
- * yield* PubSub.shutdown(pubsub)
23846
- *
23847
- * const isShutdown = yield* PubSub.isShutdown(pubsub)
23848
- * console.log("Is shutdown:", isShutdown) // true
23849
- *
23850
- * // Publishing after shutdown returns false
23851
- * const published = yield* PubSub.publish(pubsub, "msg1")
23852
- * console.log("Published after shutdown:", published) // false
23853
- * })
23854
- * ```
23855
- *
23856
- * @category lifecycle
23857
- * @since 2.0.0
23858
- */
23859
- const shutdown$1 = (self) => uninterruptible(withFiber((fiber) => {
23860
- set$6(self.shutdownFlag, true);
23861
- return close(self.scope, interrupt$2(fiber.id)).pipe(andThen(self.strategy.shutdown), when$2(self.shutdownHook.open), asVoid);
23862
- }));
23863
- /**
23864
- * Publishes a message to the `PubSub` as an `Effect`, returning whether the
23865
- * message was accepted.
23866
- *
23867
- * **When to use**
23868
- *
23869
- * Use when publishing from effectful code and the configured PubSub strategy
23870
- * should handle surplus messages.
23871
- *
23872
- * **Details**
23873
- *
23874
- * The effect succeeds with `false` if the `PubSub` is shut down. If the message
23875
- * cannot be accepted immediately, the configured strategy decides how surplus
23876
- * messages are handled.
23877
- *
23878
- * **Example** (Publishing a message)
23879
- *
23880
- * ```ts
23881
- * import { Effect, PubSub } from "effect"
23882
- *
23883
- * const program = Effect.gen(function*() {
23884
- * const pubsub = yield* PubSub.bounded<string>(10)
23885
- *
23886
- * // Publish a message
23887
- * const published = yield* PubSub.publish(pubsub, "Hello World")
23888
- * console.log("Message published:", published) // true
23889
- *
23890
- * yield* Effect.scoped(Effect.gen(function*() {
23891
- * const subscription = yield* PubSub.subscribe(pubsub)
23892
- *
23893
- * yield* PubSub.publish(pubsub, "Hello")
23894
- * const message = yield* PubSub.take(subscription)
23895
- * console.log("Received:", message) // "Hello"
23896
- * }))
23897
- * })
23898
- * ```
23899
- *
23900
- * @see {@link publishUnsafe} for a synchronous non-blocking attempt that does not run effectful surplus handling
23901
- *
23902
- * @category publishing
23903
- * @since 2.0.0
23904
- */
23905
- const publish = /*#__PURE__*/ dual(2, (self, value) => suspend$2(() => {
23906
- if (self.shutdownFlag.current) return succeed$3(false);
23907
- if (self.pubsub.publish(value)) {
23908
- self.strategy.completeSubscribersUnsafe(self.pubsub, self.subscribers);
23909
- return succeed$3(true);
23910
- }
23911
- return self.strategy.handleSurplus(self.pubsub, self.subscribers, [value], self.shutdownFlag);
23912
- }));
23913
- /**
23914
23697
  * Attempts to publish a message synchronously without applying the PubSub
23915
23698
  * strategy's effectful surplus handling.
23916
23699
  *
@@ -24009,7 +23792,7 @@ const publishUnsafe = /*#__PURE__*/ dual(2, (self, value) => {
24009
23792
  * @since 2.0.0
24010
23793
  */
24011
23794
  const subscribe = (self) => uninterruptible(contextWith((services) => {
24012
- const localScope = get$9(services, Scope);
23795
+ const localScope = get$8(services, Scope);
24013
23796
  const scope = forkUnsafe(self.scope);
24014
23797
  const subscription = makeSubscriptionUnsafe(self.pubsub, self.subscribers, self.strategy);
24015
23798
  return addFinalizer$1(scope, unsubscribe(subscription)).pipe(andThen(addFinalizerExit(localScope, (exit) => close(scope, exit))), as(subscription));
@@ -24026,49 +23809,6 @@ const unsubscribe = (self) => uninterruptible(withFiber((state) => {
24026
23809
  })), when$2(self.shutdownHook.open), asVoid);
24027
23810
  }));
24028
23811
  /**
24029
- * Takes a single message from the subscription. If no messages are available,
24030
- * this will suspend until a message becomes available.
24031
- *
24032
- * **Example** (Taking a message)
24033
- *
24034
- * ```ts
24035
- * import { Effect, Fiber, PubSub } from "effect"
24036
- *
24037
- * const program = Effect.gen(function*() {
24038
- * const pubsub = yield* PubSub.bounded<string>(10)
24039
- *
24040
- * yield* Effect.scoped(Effect.gen(function*() {
24041
- * const subscription = yield* PubSub.subscribe(pubsub)
24042
- *
24043
- * // Start a fiber to take a message (will suspend)
24044
- * const takeFiber = yield* Effect.forkChild(
24045
- * PubSub.take(subscription)
24046
- * )
24047
- *
24048
- * // Publish a message
24049
- * yield* PubSub.publish(pubsub, "Hello")
24050
- *
24051
- * // The take will now complete
24052
- * const message = yield* Fiber.join(takeFiber)
24053
- * console.log("Received:", message) // "Hello"
24054
- * }))
24055
- * })
24056
- * ```
24057
- *
24058
- * @category subscriptions
24059
- * @since 4.0.0
24060
- */
24061
- const take$2 = (self) => suspend$2(() => {
24062
- if (self.shutdownFlag.current) return interrupt$1;
24063
- if (self.replayWindow.remaining > 0) return succeed$3(self.replayWindow.take());
24064
- const message = self.pollers.length === 0 ? self.subscription.poll() : Empty$2;
24065
- if (message === Empty$2) return pollForItem(self);
24066
- else {
24067
- self.strategy.onPubSubEmptySpaceUnsafe(self.pubsub, self.subscribers);
24068
- return succeed$3(message);
24069
- }
24070
- });
24071
- /**
24072
23812
  * Takes all available messages from the subscription, suspending if no items
24073
23813
  * are available.
24074
23814
  *
@@ -24120,53 +23860,6 @@ const pollForItem = (self) => {
24120
23860
  return void_$1;
24121
23861
  });
24122
23862
  };
24123
- /**
24124
- * Takes up to the specified number of messages from the subscription without suspending.
24125
- *
24126
- * **Example** (Taking up to a maximum number of messages)
24127
- *
24128
- * ```ts
24129
- * import { Effect, PubSub } from "effect"
24130
- *
24131
- * const program = Effect.gen(function*() {
24132
- * const pubsub = yield* PubSub.bounded<string>(10)
24133
- *
24134
- * yield* Effect.scoped(Effect.gen(function*() {
24135
- * const subscription = yield* PubSub.subscribe(pubsub)
24136
- *
24137
- * // Publish multiple messages
24138
- * yield* PubSub.publishAll(pubsub, ["msg1", "msg2", "msg3", "msg4", "msg5"])
24139
- *
24140
- * // Take up to 3 messages
24141
- * const upTo3 = yield* PubSub.takeUpTo(subscription, 3)
24142
- * console.log("Up to 3:", upTo3) // ["msg1", "msg2", "msg3"]
24143
- *
24144
- * // Take up to 5 more (only 2 remaining)
24145
- * const upTo5 = yield* PubSub.takeUpTo(subscription, 5)
24146
- * console.log("Up to 5:", upTo5) // ["msg4", "msg5"]
24147
- *
24148
- * // No more messages available
24149
- * const noMore = yield* PubSub.takeUpTo(subscription, 10)
24150
- * console.log("No more:", noMore) // []
24151
- * }))
24152
- * })
24153
- * ```
24154
- *
24155
- * @category subscriptions
24156
- * @since 4.0.0
24157
- */
24158
- const takeUpTo = /*#__PURE__*/ dual(2, (self, max) => suspend$2(() => {
24159
- if (self.shutdownFlag.current) return interrupt$1;
24160
- let replay = void 0;
24161
- if (self.replayWindow.remaining >= max) return succeed$3(self.replayWindow.takeN(max));
24162
- else if (self.replayWindow.remaining > 0) {
24163
- replay = self.replayWindow.takeAll();
24164
- max = max - replay.length;
24165
- }
24166
- const as = self.pollers.length === 0 ? self.subscription.pollUpTo(max) : [];
24167
- self.strategy.onPubSubEmptySpaceUnsafe(self.pubsub, self.subscribers);
24168
- return replay ? succeed$3(replay.concat(as)) : succeed$3(as);
24169
- }));
24170
23863
  const AbsentValue = /*#__PURE__*/ Symbol.for("effect/PubSub/AbsentValue");
24171
23864
  const addSubscribers = (subscribers, subscription, pollers) => {
24172
23865
  if (!subscribers.has(subscription)) subscribers.set(subscription, /* @__PURE__ */ new Set());
@@ -24179,395 +23872,6 @@ const removeSubscribers = (subscribers, subscription, pollers) => {
24179
23872
  if (set.size === 0) subscribers.delete(subscription);
24180
23873
  };
24181
23874
  const makeSubscriptionUnsafe = (pubsub, subscribers, strategy) => new SubscriptionImpl(pubsub, subscribers, pubsub.subscribe(), make$51(), makeUnsafe$4(false), make$50(false), strategy, pubsub.replayWindow());
24182
- var BoundedPubSubArb = class {
24183
- array;
24184
- publisherIndex = 0;
24185
- subscribers;
24186
- subscriberCount = 0;
24187
- subscribersIndex = 0;
24188
- capacity;
24189
- replayBuffer;
24190
- constructor(capacity, replayBuffer) {
24191
- this.capacity = capacity;
24192
- this.replayBuffer = replayBuffer;
24193
- this.array = Array.from({ length: capacity });
24194
- this.subscribers = Array.from({ length: capacity });
24195
- }
24196
- replayWindow() {
24197
- return this.replayBuffer ? new ReplayWindowImpl(this.replayBuffer) : emptyReplayWindow;
24198
- }
24199
- isEmpty() {
24200
- return this.publisherIndex === this.subscribersIndex;
24201
- }
24202
- isFull() {
24203
- return this.publisherIndex === this.subscribersIndex + this.capacity;
24204
- }
24205
- size() {
24206
- return this.publisherIndex - this.subscribersIndex;
24207
- }
24208
- publish(value) {
24209
- if (this.isFull()) return false;
24210
- if (this.subscriberCount !== 0) {
24211
- const index = this.publisherIndex % this.capacity;
24212
- this.array[index] = value;
24213
- this.subscribers[index] = this.subscriberCount;
24214
- this.publisherIndex += 1;
24215
- }
24216
- if (this.replayBuffer) this.replayBuffer.offer(value);
24217
- return true;
24218
- }
24219
- publishAll(elements) {
24220
- if (this.subscriberCount === 0) {
24221
- if (this.replayBuffer) this.replayBuffer.offerAll(elements);
24222
- return [];
24223
- }
24224
- const chunk = fromIterable$2(elements);
24225
- const n = chunk.length;
24226
- const size = this.publisherIndex - this.subscribersIndex;
24227
- const available = this.capacity - size;
24228
- const forPubSub = Math.min(n, available);
24229
- if (forPubSub === 0) return chunk;
24230
- let iteratorIndex = 0;
24231
- const publishAllIndex = this.publisherIndex + forPubSub;
24232
- while (this.publisherIndex !== publishAllIndex) {
24233
- const a = chunk[iteratorIndex++];
24234
- const index = this.publisherIndex % this.capacity;
24235
- this.array[index] = a;
24236
- this.subscribers[index] = this.subscriberCount;
24237
- this.publisherIndex += 1;
24238
- if (this.replayBuffer) this.replayBuffer.offer(a);
24239
- }
24240
- return chunk.slice(iteratorIndex);
24241
- }
24242
- slide() {
24243
- if (this.subscribersIndex !== this.publisherIndex) {
24244
- const index = this.subscribersIndex % this.capacity;
24245
- this.array[index] = AbsentValue;
24246
- this.subscribers[index] = 0;
24247
- this.subscribersIndex += 1;
24248
- }
24249
- if (this.replayBuffer) this.replayBuffer.slide();
24250
- }
24251
- subscribe() {
24252
- this.subscriberCount += 1;
24253
- return new BoundedPubSubArbSubscription(this, this.publisherIndex, false);
24254
- }
24255
- };
24256
- var BoundedPubSubArbSubscription = class {
24257
- self;
24258
- subscriberIndex;
24259
- unsubscribed;
24260
- constructor(self, subscriberIndex, unsubscribed) {
24261
- this.self = self;
24262
- this.subscriberIndex = subscriberIndex;
24263
- this.unsubscribed = unsubscribed;
24264
- }
24265
- isEmpty() {
24266
- return this.unsubscribed || this.self.publisherIndex === this.subscriberIndex || this.self.publisherIndex === this.self.subscribersIndex;
24267
- }
24268
- size() {
24269
- if (this.unsubscribed) return 0;
24270
- return this.self.publisherIndex - Math.max(this.subscriberIndex, this.self.subscribersIndex);
24271
- }
24272
- poll() {
24273
- if (this.unsubscribed) return Empty$2;
24274
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24275
- if (this.subscriberIndex !== this.self.publisherIndex) {
24276
- const index = this.subscriberIndex % this.self.capacity;
24277
- const elem = this.self.array[index];
24278
- this.self.subscribers[index] -= 1;
24279
- if (this.self.subscribers[index] === 0) {
24280
- this.self.array[index] = AbsentValue;
24281
- this.self.subscribersIndex += 1;
24282
- }
24283
- this.subscriberIndex += 1;
24284
- return elem;
24285
- }
24286
- return Empty$2;
24287
- }
24288
- pollUpTo(n) {
24289
- if (this.unsubscribed) return [];
24290
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24291
- const size = this.self.publisherIndex - this.subscriberIndex;
24292
- const toPoll = Math.min(n, size);
24293
- if (toPoll <= 0) return [];
24294
- const builder = [];
24295
- const pollUpToIndex = this.subscriberIndex + toPoll;
24296
- while (this.subscriberIndex !== pollUpToIndex) {
24297
- const index = this.subscriberIndex % this.self.capacity;
24298
- const a = this.self.array[index];
24299
- this.self.subscribers[index] -= 1;
24300
- if (this.self.subscribers[index] === 0) {
24301
- this.self.array[index] = AbsentValue;
24302
- this.self.subscribersIndex += 1;
24303
- }
24304
- builder.push(a);
24305
- this.subscriberIndex += 1;
24306
- }
24307
- return builder;
24308
- }
24309
- unsubscribe() {
24310
- if (!this.unsubscribed) {
24311
- this.unsubscribed = true;
24312
- this.self.subscriberCount -= 1;
24313
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24314
- while (this.subscriberIndex !== this.self.publisherIndex) {
24315
- const index = this.subscriberIndex % this.self.capacity;
24316
- this.self.subscribers[index] -= 1;
24317
- if (this.self.subscribers[index] === 0) {
24318
- this.self.array[index] = AbsentValue;
24319
- this.self.subscribersIndex += 1;
24320
- }
24321
- this.subscriberIndex += 1;
24322
- }
24323
- }
24324
- }
24325
- };
24326
- var BoundedPubSubPow2 = class {
24327
- array;
24328
- mask;
24329
- publisherIndex = 0;
24330
- subscribers;
24331
- subscriberCount = 0;
24332
- subscribersIndex = 0;
24333
- capacity;
24334
- replayBuffer;
24335
- constructor(capacity, replayBuffer) {
24336
- this.capacity = capacity;
24337
- this.replayBuffer = replayBuffer;
24338
- this.array = Array.from({ length: capacity });
24339
- this.mask = capacity - 1;
24340
- this.subscribers = Array.from({ length: capacity });
24341
- }
24342
- replayWindow() {
24343
- return this.replayBuffer ? new ReplayWindowImpl(this.replayBuffer) : emptyReplayWindow;
24344
- }
24345
- isEmpty() {
24346
- return this.publisherIndex === this.subscribersIndex;
24347
- }
24348
- isFull() {
24349
- return this.publisherIndex === this.subscribersIndex + this.capacity;
24350
- }
24351
- size() {
24352
- return this.publisherIndex - this.subscribersIndex;
24353
- }
24354
- publish(value) {
24355
- if (this.isFull()) return false;
24356
- if (this.subscriberCount !== 0) {
24357
- const index = this.publisherIndex & this.mask;
24358
- this.array[index] = value;
24359
- this.subscribers[index] = this.subscriberCount;
24360
- this.publisherIndex += 1;
24361
- }
24362
- if (this.replayBuffer) this.replayBuffer.offer(value);
24363
- return true;
24364
- }
24365
- publishAll(elements) {
24366
- if (this.subscriberCount === 0) {
24367
- if (this.replayBuffer) this.replayBuffer.offerAll(elements);
24368
- return [];
24369
- }
24370
- const chunk = fromIterable$2(elements);
24371
- const n = chunk.length;
24372
- const size = this.publisherIndex - this.subscribersIndex;
24373
- const available = this.capacity - size;
24374
- const forPubSub = Math.min(n, available);
24375
- if (forPubSub === 0) return chunk;
24376
- let iteratorIndex = 0;
24377
- const publishAllIndex = this.publisherIndex + forPubSub;
24378
- while (this.publisherIndex !== publishAllIndex) {
24379
- const elem = chunk[iteratorIndex++];
24380
- const index = this.publisherIndex & this.mask;
24381
- this.array[index] = elem;
24382
- this.subscribers[index] = this.subscriberCount;
24383
- this.publisherIndex += 1;
24384
- if (this.replayBuffer) this.replayBuffer.offer(elem);
24385
- }
24386
- return chunk.slice(iteratorIndex);
24387
- }
24388
- slide() {
24389
- if (this.subscribersIndex !== this.publisherIndex) {
24390
- const index = this.subscribersIndex & this.mask;
24391
- this.array[index] = AbsentValue;
24392
- this.subscribers[index] = 0;
24393
- this.subscribersIndex += 1;
24394
- }
24395
- if (this.replayBuffer) this.replayBuffer.slide();
24396
- }
24397
- subscribe() {
24398
- this.subscriberCount += 1;
24399
- return new BoundedPubSubPow2Subscription(this, this.publisherIndex, false);
24400
- }
24401
- };
24402
- var BoundedPubSubPow2Subscription = class {
24403
- self;
24404
- subscriberIndex;
24405
- unsubscribed;
24406
- constructor(self, subscriberIndex, unsubscribed) {
24407
- this.self = self;
24408
- this.subscriberIndex = subscriberIndex;
24409
- this.unsubscribed = unsubscribed;
24410
- }
24411
- isEmpty() {
24412
- return this.unsubscribed || this.self.publisherIndex === this.subscriberIndex || this.self.publisherIndex === this.self.subscribersIndex;
24413
- }
24414
- size() {
24415
- if (this.unsubscribed) return 0;
24416
- return this.self.publisherIndex - Math.max(this.subscriberIndex, this.self.subscribersIndex);
24417
- }
24418
- poll() {
24419
- if (this.unsubscribed) return Empty$2;
24420
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24421
- if (this.subscriberIndex !== this.self.publisherIndex) {
24422
- const index = this.subscriberIndex & this.self.mask;
24423
- const elem = this.self.array[index];
24424
- this.self.subscribers[index] -= 1;
24425
- if (this.self.subscribers[index] === 0) {
24426
- this.self.array[index] = AbsentValue;
24427
- this.self.subscribersIndex += 1;
24428
- }
24429
- this.subscriberIndex += 1;
24430
- return elem;
24431
- }
24432
- return Empty$2;
24433
- }
24434
- pollUpTo(n) {
24435
- if (this.unsubscribed) return [];
24436
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24437
- const size = this.self.publisherIndex - this.subscriberIndex;
24438
- const toPoll = Math.min(n, size);
24439
- if (toPoll <= 0) return [];
24440
- const builder = [];
24441
- const pollUpToIndex = this.subscriberIndex + toPoll;
24442
- while (this.subscriberIndex !== pollUpToIndex) {
24443
- const index = this.subscriberIndex & this.self.mask;
24444
- const elem = this.self.array[index];
24445
- this.self.subscribers[index] -= 1;
24446
- if (this.self.subscribers[index] === 0) {
24447
- this.self.array[index] = AbsentValue;
24448
- this.self.subscribersIndex += 1;
24449
- }
24450
- builder.push(elem);
24451
- this.subscriberIndex += 1;
24452
- }
24453
- return builder;
24454
- }
24455
- unsubscribe() {
24456
- if (!this.unsubscribed) {
24457
- this.unsubscribed = true;
24458
- this.self.subscriberCount -= 1;
24459
- this.subscriberIndex = Math.max(this.subscriberIndex, this.self.subscribersIndex);
24460
- while (this.subscriberIndex !== this.self.publisherIndex) {
24461
- const index = this.subscriberIndex & this.self.mask;
24462
- this.self.subscribers[index] -= 1;
24463
- if (this.self.subscribers[index] === 0) {
24464
- this.self.array[index] = AbsentValue;
24465
- this.self.subscribersIndex += 1;
24466
- }
24467
- this.subscriberIndex += 1;
24468
- }
24469
- }
24470
- }
24471
- };
24472
- var BoundedPubSubSingle = class {
24473
- publisherIndex = 0;
24474
- subscriberCount = 0;
24475
- subscribers = 0;
24476
- value = AbsentValue;
24477
- capacity = 1;
24478
- replayBuffer;
24479
- constructor(replayBuffer) {
24480
- this.replayBuffer = replayBuffer;
24481
- }
24482
- replayWindow() {
24483
- return this.replayBuffer ? new ReplayWindowImpl(this.replayBuffer) : emptyReplayWindow;
24484
- }
24485
- pipe() {
24486
- return pipeArguments(this, arguments);
24487
- }
24488
- isEmpty() {
24489
- return this.subscribers === 0;
24490
- }
24491
- isFull() {
24492
- return !this.isEmpty();
24493
- }
24494
- size() {
24495
- return this.isEmpty() ? 0 : 1;
24496
- }
24497
- publish(value) {
24498
- if (this.isFull()) return false;
24499
- if (this.subscriberCount !== 0) {
24500
- this.value = value;
24501
- this.subscribers = this.subscriberCount;
24502
- this.publisherIndex += 1;
24503
- }
24504
- if (this.replayBuffer) this.replayBuffer.offer(value);
24505
- return true;
24506
- }
24507
- publishAll(elements) {
24508
- if (this.subscriberCount === 0) {
24509
- if (this.replayBuffer) this.replayBuffer.offerAll(elements);
24510
- return [];
24511
- }
24512
- const chunk = fromIterable$2(elements);
24513
- if (chunk.length === 0) return chunk;
24514
- if (this.publish(chunk[0])) return chunk.slice(1);
24515
- else return chunk;
24516
- }
24517
- slide() {
24518
- if (this.isFull()) {
24519
- this.subscribers = 0;
24520
- this.value = AbsentValue;
24521
- }
24522
- if (this.replayBuffer) this.replayBuffer.slide();
24523
- }
24524
- subscribe() {
24525
- this.subscriberCount += 1;
24526
- return new BoundedPubSubSingleSubscription(this, this.publisherIndex, false);
24527
- }
24528
- };
24529
- var BoundedPubSubSingleSubscription = class {
24530
- self;
24531
- subscriberIndex;
24532
- unsubscribed;
24533
- constructor(self, subscriberIndex, unsubscribed) {
24534
- this.self = self;
24535
- this.subscriberIndex = subscriberIndex;
24536
- this.unsubscribed = unsubscribed;
24537
- }
24538
- isEmpty() {
24539
- return this.unsubscribed || this.self.subscribers === 0 || this.subscriberIndex === this.self.publisherIndex;
24540
- }
24541
- size() {
24542
- return this.isEmpty() ? 0 : 1;
24543
- }
24544
- poll() {
24545
- if (this.isEmpty()) return Empty$2;
24546
- const elem = this.self.value;
24547
- this.self.subscribers -= 1;
24548
- if (this.self.subscribers === 0) this.self.value = AbsentValue;
24549
- this.subscriberIndex += 1;
24550
- return elem;
24551
- }
24552
- pollUpTo(n) {
24553
- if (this.isEmpty() || n < 1) return [];
24554
- const a = this.self.value;
24555
- this.self.subscribers -= 1;
24556
- if (this.self.subscribers === 0) this.self.value = AbsentValue;
24557
- this.subscriberIndex += 1;
24558
- return [a];
24559
- }
24560
- unsubscribe() {
24561
- if (!this.unsubscribed) {
24562
- this.unsubscribed = true;
24563
- this.self.subscriberCount -= 1;
24564
- if (this.subscriberIndex !== this.self.publisherIndex) {
24565
- this.self.subscribers -= 1;
24566
- if (this.self.subscribers === 0) this.self.value = AbsentValue;
24567
- }
24568
- }
24569
- }
24570
- };
24571
23875
  var UnboundedPubSub = class {
24572
23876
  publisherHead = {
24573
23877
  value: AbsentValue,
@@ -24753,99 +24057,6 @@ var PubSubImpl = class {
24753
24057
  }
24754
24058
  };
24755
24059
  const makePubSubUnsafe = (pubsub, subscribers, scope, shutdownHook, shutdownFlag, strategy) => new PubSubImpl(pubsub, subscribers, scope, shutdownHook, shutdownFlag, strategy);
24756
- const ensureCapacity = (capacity) => {
24757
- if (capacity <= 0) throw new Error(`Cannot construct PubSub with capacity of ${capacity}`);
24758
- };
24759
- /**
24760
- * Represents the back-pressure strategy for bounded `PubSub` values.
24761
- *
24762
- * **When to use**
24763
- *
24764
- * Use to preserve every message for current subscribers when a bounded custom
24765
- * `PubSub` should make publishers wait for capacity instead of dropping or
24766
- * evicting messages.
24767
- *
24768
- * **Details**
24769
- *
24770
- * Publishers wait when the `PubSub` is at capacity, so all current subscribers
24771
- * can receive every published message.
24772
- *
24773
- * **Gotchas**
24774
- *
24775
- * A slow subscriber can slow down publishers and other subscribers.
24776
- *
24777
- * @see {@link bounded} for creating bounded PubSubs with back pressure by default
24778
- * @see {@link DroppingStrategy} for dropping new messages when capacity is full
24779
- * @see {@link SlidingStrategy} for evicting old messages when capacity is full
24780
- *
24781
- * @category models
24782
- * @since 4.0.0
24783
- */
24784
- var BackPressureStrategy = class {
24785
- publishers = /*#__PURE__*/ make$51();
24786
- get shutdown() {
24787
- return withFiber((fiber) => forEach$1(takeAll$2(this.publishers), ([_, deferred, last]) => last ? interruptWith(deferred, fiber.id) : void_$1, {
24788
- concurrency: "unbounded",
24789
- discard: true
24790
- }));
24791
- }
24792
- handleSurplus(pubsub, subscribers, elements, isShutdown) {
24793
- return suspend$2(() => {
24794
- const deferred = makeUnsafe$7();
24795
- this.offerUnsafe(elements, deferred);
24796
- this.onPubSubEmptySpaceUnsafe(pubsub, subscribers);
24797
- this.completeSubscribersUnsafe(pubsub, subscribers);
24798
- return (get$8(isShutdown) ? interrupt$1 : _await(deferred)).pipe(onInterrupt(() => {
24799
- this.removeUnsafe(deferred);
24800
- return void_$1;
24801
- }));
24802
- });
24803
- }
24804
- onPubSubEmptySpaceUnsafe(pubsub, subscribers) {
24805
- let keepPolling = true;
24806
- while (keepPolling && !pubsub.isFull()) {
24807
- const publisher = take$3(this.publishers);
24808
- if (publisher === Empty$2) keepPolling = false;
24809
- else {
24810
- const [value, deferred] = publisher;
24811
- const published = pubsub.publish(value);
24812
- if (published && publisher[2]) doneUnsafe(deferred, succeed$5(true));
24813
- else if (!published) prepend(this.publishers, publisher);
24814
- this.completeSubscribersUnsafe(pubsub, subscribers);
24815
- }
24816
- }
24817
- }
24818
- completePollersUnsafe(pubsub, subscribers, subscription, pollers) {
24819
- return strategyCompletePollersUnsafe(this, pubsub, subscribers, subscription, pollers);
24820
- }
24821
- completeSubscribersUnsafe(pubsub, subscribers) {
24822
- return strategyCompleteSubscribersUnsafe(this, pubsub, subscribers);
24823
- }
24824
- offerUnsafe(elements, deferred) {
24825
- const iterator = elements[Symbol.iterator]();
24826
- let next = iterator.next();
24827
- if (!next.done) while (1) {
24828
- const value = next.value;
24829
- next = iterator.next();
24830
- if (next.done) {
24831
- append(this.publishers, [
24832
- value,
24833
- deferred,
24834
- true
24835
- ]);
24836
- break;
24837
- }
24838
- append(this.publishers, [
24839
- value,
24840
- deferred,
24841
- false
24842
- ]);
24843
- }
24844
- }
24845
- removeUnsafe(deferred) {
24846
- filter(this.publishers, ([_, d]) => d !== deferred);
24847
- }
24848
- };
24849
24060
  /**
24850
24061
  * Represents the dropping strategy for bounded `PubSub` values.
24851
24062
  *
@@ -24916,7 +24127,7 @@ var DroppingStrategy = class {
24916
24127
  const strategyCompletePollersUnsafe = (strategy, pubsub, subscribers, subscription, pollers) => {
24917
24128
  let keepPolling = true;
24918
24129
  while (keepPolling && !subscription.isEmpty()) {
24919
- const poller = take$3(pollers);
24130
+ const poller = take$2(pollers);
24920
24131
  if (poller === Empty$2) {
24921
24132
  removeSubscribers(subscribers, subscription, pollers);
24922
24133
  if (pollers.length === 0) keepPolling = false;
@@ -25224,41 +24435,43 @@ const sliding = (capacity) => make$48({
25224
24435
  strategy: "sliding"
25225
24436
  });
25226
24437
  /**
25227
- * Creates an unbounded queue that can grow to any size without blocking producers.
24438
+ * Creates a bounded queue with dropping strategy. When the queue reaches capacity,
24439
+ * new elements are dropped and the offer operation returns false.
25228
24440
  *
25229
24441
  * **When to use**
25230
24442
  *
25231
- * Use when producers should never be blocked; unbounded queues never apply backpressure, so producers
25232
- * can always add messages successfully. This is useful when you want to prioritize
25233
- * producer throughput over memory usage control.
24443
+ * Use when producers should not block and existing messages should be preserved,
24444
+ * but new messages may be lost when the queue is full.
25234
24445
  *
25235
- * **Example** (Creating unbounded queues)
24446
+ * **Example** (Creating dropping queues)
25236
24447
  *
25237
24448
  * ```ts
25238
24449
  * import { Effect, Queue } from "effect"
25239
24450
  *
25240
24451
  * const program = Effect.gen(function*() {
25241
- * const queue = yield* Queue.unbounded<string>()
24452
+ * const queue = yield* Queue.dropping<number>(2)
25242
24453
  *
25243
- * // Producers can always add messages without blocking
25244
- * yield* Queue.offer(queue, "message1")
25245
- * yield* Queue.offer(queue, "message2")
25246
- * yield* Queue.offerAll(queue, ["message3", "message4", "message5"])
24454
+ * // Fill the queue to capacity
24455
+ * const success1 = yield* Queue.offer(queue, 1)
24456
+ * const success2 = yield* Queue.offer(queue, 2)
24457
+ * console.log(success1, success2) // true, true
25247
24458
  *
25248
- * // Check current size
25249
- * const size = yield* Queue.size(queue)
25250
- * console.log(size) // 5
24459
+ * // This will be dropped
24460
+ * const success3 = yield* Queue.offer(queue, 3)
24461
+ * console.log(success3) // false
25251
24462
  *
25252
- * // Take all messages
25253
- * const messages = yield* Queue.takeAll(queue)
25254
- * console.log(messages) // ["message1", "message2", "message3", "message4", "message5"]
24463
+ * const all = yield* Queue.takeAll(queue)
24464
+ * console.log(all) // [1, 2] - element 3 was dropped
25255
24465
  * })
25256
24466
  * ```
25257
24467
  *
25258
24468
  * @category constructors
25259
24469
  * @since 2.0.0
25260
24470
  */
25261
- const unbounded = () => make$48();
24471
+ const dropping = (capacity) => make$48({
24472
+ capacity,
24473
+ strategy: "dropping"
24474
+ });
25262
24475
  /**
25263
24476
  * Adds a message to the queue. Returns `false` if the queue is done.
25264
24477
  *
@@ -25302,7 +24515,7 @@ const offer = (self, message) => suspend$3(() => {
25302
24515
  }
25303
24516
  return offerRemainingSingle(self, message);
25304
24517
  case "sliding":
25305
- take$3(self.messages);
24518
+ take$2(self.messages);
25306
24519
  append(self.messages, message);
25307
24520
  return exitTrue;
25308
24521
  }
@@ -25345,7 +24558,7 @@ const offerUnsafe = (self, message) => {
25345
24558
  if (self.state._tag !== "Open") return false;
25346
24559
  else if (self.messages.length >= self.capacity) {
25347
24560
  if (self.strategy === "sliding") {
25348
- take$3(self.messages);
24561
+ take$2(self.messages);
25349
24562
  append(self.messages, message);
25350
24563
  return true;
25351
24564
  } else if (self.capacity <= 0 && self.state.takers.size > 0) {
@@ -25750,14 +24963,14 @@ const take$1 = (self) => suspend$3(() => takeUnsafe(self) ?? andThen$1(awaitTake
25750
24963
  const takeUnsafe = (self) => {
25751
24964
  if (self.state._tag === "Done") return self.state.exit;
25752
24965
  if (self.messages.length > 0) {
25753
- const message = take$3(self.messages);
24966
+ const message = take$2(self.messages);
25754
24967
  releaseCapacity(self);
25755
24968
  return exitSucceed(message);
25756
24969
  } else if (self.capacity <= 0 && self.state.offers.size > 0) {
25757
24970
  self.capacity = 1;
25758
24971
  releaseCapacity(self);
25759
24972
  self.capacity = 0;
25760
- const message = take$3(self.messages);
24973
+ const message = take$2(self.messages);
25761
24974
  releaseCapacity(self);
25762
24975
  return exitSucceed(message);
25763
24976
  }
@@ -25829,7 +25042,7 @@ const takeBetweenUnsafe = (self, min, max) => {
25829
25042
  self.capacity = 1;
25830
25043
  releaseCapacity(self);
25831
25044
  self.capacity = 0;
25832
- const messages = [take$3(self.messages)];
25045
+ const messages = [take$2(self.messages)];
25833
25046
  releaseCapacity(self);
25834
25047
  return exitSucceed(messages);
25835
25048
  }
@@ -26281,21 +25494,6 @@ const fromTransformBracket = (f) => fromTransform$1(fnUntraced(function* (upstre
26281
25494
  * @since 4.0.0
26282
25495
  */
26283
25496
  const toTransform = (channel) => channel.transform;
26284
- /**
26285
- * The default chunk size used by channels for batching operations.
26286
- *
26287
- * **Example** (Reading the default chunk size)
26288
- *
26289
- * ```ts
26290
- * import { Channel } from "effect"
26291
- *
26292
- * console.log(Channel.DefaultChunkSize) // 4096
26293
- * ```
26294
- *
26295
- * @category constants
26296
- * @since 4.0.0
26297
- */
26298
- const DefaultChunkSize = 4096;
26299
25497
  const asyncQueue = (scope, f, options) => make$48({
26300
25498
  capacity: options?.bufferSize,
26301
25499
  strategy: options?.strategy
@@ -26336,87 +25534,6 @@ const callbackArray = (f, options) => fromTransform$1((_, scope) => map$4(asyncQ
26336
25534
  */
26337
25535
  const suspend$1 = (evaluate) => fromTransform$1((upstream, scope) => suspend$2(() => toTransform(evaluate())(upstream, scope)));
26338
25536
  /**
26339
- * Creates a `Channel` from an iterator that emits arrays of elements.
26340
- *
26341
- * **Example** (Batching iterator output)
26342
- *
26343
- * ```ts
26344
- * import { Channel } from "effect"
26345
- *
26346
- * // Create a channel from a simple iterator
26347
- * const numberIterator = (): Iterator<number, string> => {
26348
- * let count = 0
26349
- * return {
26350
- * next: () => {
26351
- * if (count < 3) {
26352
- * return { value: count++, done: false }
26353
- * }
26354
- * return { value: "finished", done: true }
26355
- * }
26356
- * }
26357
- * }
26358
- *
26359
- * const channel = Channel.fromIteratorArray(() => numberIterator(), 2)
26360
- * // This will emit arrays: [0, 1], [2], then complete with "finished"
26361
- * ```
26362
- *
26363
- * **Example** (Batching generator output)
26364
- *
26365
- * ```ts
26366
- * import { Channel } from "effect"
26367
- *
26368
- * // Create channel from a generator function
26369
- * function* fibonacci(): Generator<number, void, unknown> {
26370
- * let a = 0, b = 1
26371
- * for (let i = 0; i < 5; i++) {
26372
- * yield a
26373
- * ;[a, b] = [b, a + b]
26374
- * }
26375
- * }
26376
- *
26377
- * const fibChannel = Channel.fromIteratorArray(() => fibonacci(), 3)
26378
- * // Emits: [0, 1, 1], [2, 3], then completes
26379
- * ```
26380
- *
26381
- * @category constructors
26382
- * @since 4.0.0
26383
- */
26384
- const fromIteratorArray = (iterator, chunkSize = DefaultChunkSize) => fromPull$1(sync(() => {
26385
- const iter = iterator();
26386
- let done$15 = none();
26387
- return suspend$2(() => {
26388
- if (done$15._tag === "Some") return done(done$15.value);
26389
- const buffer = [];
26390
- while (buffer.length < chunkSize) {
26391
- const state = iter.next();
26392
- if (state.done) {
26393
- if (buffer.length === 0) return done(state.value);
26394
- done$15 = some(state.value);
26395
- break;
26396
- }
26397
- buffer.push(state.value);
26398
- }
26399
- return succeed$3(buffer);
26400
- });
26401
- }));
26402
- /**
26403
- * Creates a `Channel` that emits arrays of elements from an iterable.
26404
- *
26405
- * **Example** (Batching iterable output)
26406
- *
26407
- * ```ts
26408
- * import { Channel } from "effect"
26409
- *
26410
- * const numbers = [1, 2, 3, 4, 5]
26411
- * const channel = Channel.fromIterableArray(numbers)
26412
- * // Emits arrays like: [1, 2, 3, 4], [5] (based on chunk size)
26413
- * ```
26414
- *
26415
- * @category constructors
26416
- * @since 4.0.0
26417
- */
26418
- const fromIterableArray = (iterable, chunkSize = DefaultChunkSize) => fromIteratorArray(() => iterable[Symbol.iterator](), chunkSize);
26419
- /**
26420
25537
  * Creates a `Channel` that emits a single value and then ends.
26421
25538
  *
26422
25539
  * **Example** (Creating channels that succeed)
@@ -27493,14 +26610,6 @@ const unwrap$3 = (channel) => fromTransform$1((upstream, scope) => {
27493
26610
  }));
27494
26611
  });
27495
26612
  /**
27496
- * Runs a channel with a scope provided for the duration of the channel
27497
- * execution, removing the channel's `Scope` requirement.
27498
- *
27499
- * @category resource management
27500
- * @since 2.0.0
27501
- */
27502
- const scoped$2 = (self) => fromTransformBracket((upstream, scope, forkedScope) => map$4(provide$3(toTransform(self)(upstream, scope), forkedScope), provide$3(forkedScope)));
27503
- /**
27504
26613
  * Returns a channel with an exit-aware finalizer that is guaranteed to run once
27505
26614
  * the channel begins execution, whether it succeeds or fails.
27506
26615
  *
@@ -28328,7 +27437,7 @@ const makeUnsafe$2 = (options) => ({
28328
27437
  */
28329
27438
  const make$46 = (options) => withFiber((fiber) => {
28330
27439
  const context = fiber.context;
28331
- const scope = get$9(context, Scope);
27440
+ const scope = get$8(context, Scope);
28332
27441
  const self = makeUnsafe$2({
28333
27442
  lookup: options.lookup,
28334
27443
  context,
@@ -28521,7 +27630,7 @@ var RcRefImpl = class {
28521
27630
  /** @internal */
28522
27631
  const make$45 = (options) => withFiber((fiber) => {
28523
27632
  const context = fiber.context;
28524
- const scope = get$9(context, Scope);
27633
+ const scope = get$8(context, Scope);
28525
27634
  const ref = new RcRefImpl(options.acquire, context, scope, options.idleTimeToLive ? fromInputUnsafe(options.idleTimeToLive) : void 0);
28526
27635
  return as(addFinalizerExit(scope, () => {
28527
27636
  const close$1 = ref.state._tag === "Acquired" ? close(ref.state.scope, void_$2) : void_$1;
@@ -28837,30 +27946,6 @@ const fromChannel = fromChannel$2;
28837
27946
  */
28838
27947
  const fromEffect = (effect) => fromChannel(fromEffect$1(map$4(effect, of)));
28839
27948
  /**
28840
- * Creates a stream from an effect producing a value of type `A` which repeats forever.
28841
- *
28842
- * **Example** (Repeating an effect forever)
28843
- *
28844
- * ```ts
28845
- * import { Console, Effect, Random, Stream } from "effect"
28846
- *
28847
- * const program = Effect.gen(function*() {
28848
- * const stream = Stream.fromEffectRepeat(Random.nextInt).pipe(
28849
- * Stream.take(5)
28850
- * )
28851
- * const values = yield* Stream.runCollect(stream)
28852
- * yield* Console.log(values)
28853
- * })
28854
- *
28855
- * Effect.runPromise(program)
28856
- * // Output: [ 3891571149, 4239494205, 2352981603, 2339111046, 1488052210 ]
28857
- * ```
28858
- *
28859
- * @category constructors
28860
- * @since 4.0.0
28861
- */
28862
- const fromEffectRepeat = (effect) => fromPull(succeed$3(map$4(effect, of)));
28863
- /**
28864
27949
  * Creates a stream from a pull effect, such as one produced by `Stream.toPull`.
28865
27950
  *
28866
27951
  * **Details**
@@ -29071,34 +28156,6 @@ const suspend = (stream) => fromChannel(suspend$1(() => stream().channel));
29071
28156
  */
29072
28157
  const fail$1 = (error) => fromChannel(fail$2(error));
29073
28158
  /**
29074
- * Creates a new `Stream` from an iterable collection of values.
29075
- *
29076
- * **Details**
29077
- *
29078
- * - `chunkSize`: Maximum number of values emitted per chunk.
29079
- *
29080
- * **Example** (Creating a stream from an iterable)
29081
- *
29082
- * ```ts
29083
- * import { Console, Effect, Stream } from "effect"
29084
- *
29085
- * const numbers = [1, 2, 3]
29086
- *
29087
- * const program = Effect.gen(function*() {
29088
- * const stream = Stream.fromIterable(numbers)
29089
- * const values = yield* Stream.runCollect(stream)
29090
- * yield* Console.log(values)
29091
- * })
29092
- *
29093
- * Effect.runPromise(program)
29094
- * // Output: [ 1, 2, 3 ]
29095
- * ```
29096
- *
29097
- * @category constructors
29098
- * @since 2.0.0
29099
- */
29100
- const fromIterable$1 = (iterable, options) => Array.isArray(iterable) && options?.chunkSize === void 0 ? fromArray(iterable) : fromChannel(fromIterableArray(iterable, options?.chunkSize));
29101
- /**
29102
28159
  * Creates a stream from an array of values.
29103
28160
  *
29104
28161
  * **Example** (Creating a stream from an array of values)
@@ -29259,34 +28316,6 @@ const fromReadableStream = (options) => fromChannel(fromTransform$1(fnUntraced(f
29259
28316
  */
29260
28317
  const unwrap$1 = (effect) => fromChannel(unwrap$3(map$4(effect, toChannel)));
29261
28318
  /**
29262
- * Runs a stream that requires `Scope` in a managed scope, ensuring its
29263
- * finalizers are run when the stream completes.
29264
- *
29265
- * **Example** (Scoping a stream)
29266
- *
29267
- * ```ts
29268
- * import { Console, Effect, Stream } from "effect"
29269
- *
29270
- * const stream = Stream.scoped(
29271
- * Stream.fromEffect(
29272
- * Effect.acquireRelease(
29273
- * Console.log("acquire").pipe(Effect.as("resource")),
29274
- * () => Console.log("release")
29275
- * )
29276
- * )
29277
- * )
29278
- *
29279
- * Effect.runPromise(Stream.runCollect(stream)).then(console.log)
29280
- * // acquire
29281
- * // release
29282
- * // [ "resource" ]
29283
- * ```
29284
- *
29285
- * @category constructors
29286
- * @since 2.0.0
29287
- */
29288
- const scoped$1 = (self) => fromChannel(scoped$2(self.channel));
29289
- /**
29290
28319
  * Transforms the elements of this stream using the supplied function.
29291
28320
  *
29292
28321
  * **Example** (Mapping stream values)
@@ -29489,53 +28518,6 @@ const catch_ = /*#__PURE__*/ dual(2, (self, f) => fromChannel(catch_$1(self.chan
29489
28518
  */
29490
28519
  const orDie = (self) => fromChannel(orDie$1(self.channel));
29491
28520
  /**
29492
- * Takes elements until the predicate matches.
29493
- *
29494
- * **Details**
29495
- *
29496
- * When `excludeLast` is `true`, the matching element is dropped.
29497
- *
29498
- * **Example** (Taking until a predicate matches)
29499
- *
29500
- * ```ts
29501
- * import { Console, Effect, Stream } from "effect"
29502
- *
29503
- * const stream = Stream.range(1, 5)
29504
- *
29505
- * const program = Effect.gen(function*() {
29506
- * const inclusive = yield* stream.pipe(
29507
- * Stream.takeUntil((n) => n % 3 === 0),
29508
- * Stream.runCollect
29509
- * )
29510
- * yield* Console.log(inclusive)
29511
- * // Output: [ 1, 2, 3 ]
29512
- *
29513
- * const exclusive = yield* stream.pipe(
29514
- * Stream.takeUntil((n) => n % 3 === 0, { excludeLast: true }),
29515
- * Stream.runCollect
29516
- * )
29517
- * yield* Console.log(exclusive)
29518
- * // Output: [ 1, 2 ]
29519
- * })
29520
- * ```
29521
- *
29522
- * @category filtering
29523
- * @since 2.0.0
29524
- */
29525
- const takeUntil = /*#__PURE__*/ dual((args) => isStream(args[0]), (self, predicate, options) => transformPull(self, (pull, _scope) => sync(() => {
29526
- let i = 0;
29527
- let done$9 = false;
29528
- return flatMap$2(suspend$2(() => done$9 ? done() : pull), (chunk) => {
29529
- const index = chunk.findIndex((a) => predicate(a, i++));
29530
- if (index >= 0) {
29531
- done$9 = true;
29532
- const arr = chunk.slice(0, options?.excludeLast ? index : index + 1);
29533
- return isReadonlyArrayNonEmpty(arr) ? succeed$3(arr) : done();
29534
- }
29535
- return succeed$3(chunk);
29536
- });
29537
- })));
29538
- /**
29539
28521
  * Drops the first `n` elements from this stream.
29540
28522
  *
29541
28523
  * **Example** (Dropping values from the left)
@@ -30610,7 +29592,7 @@ const make$41 = (spawn) => {
30610
29592
  const streamLines = (command, options) => splitLines(streamString(command, options));
30611
29593
  return ChildProcessSpawner.of({
30612
29594
  spawn,
30613
- exitCode: (command) => scoped$3(flatMap$2(spawn(command), (handle) => handle.exitCode)),
29595
+ exitCode: (command) => scoped$1(flatMap$2(spawn(command), (handle) => handle.exitCode)),
30614
29596
  streamString,
30615
29597
  streamLines,
30616
29598
  lines: (command, options) => runCollect(streamLines(command, options)),
@@ -31710,6 +30692,64 @@ const get$3 = (self) => sync(() => self.ref.current);
31710
30692
  */
31711
30693
  const set$4 = /*#__PURE__*/ dual(2, (self, value) => sync(() => set$6(self.ref, value)));
31712
30694
  /**
30695
+ * Modifies the value of the Ref atomically using the given function.
30696
+ *
30697
+ * **When to use**
30698
+ *
30699
+ * Use to compute both a separate return value and the next stored value in one
30700
+ * atomic update.
30701
+ *
30702
+ * **Details**
30703
+ *
30704
+ * The function receives the current value and returns a tuple of
30705
+ * `[result, newValue]`. The Ref is updated with `newValue`, and `result` is
30706
+ * returned by the effect.
30707
+ *
30708
+ * **Example** (Modifying a value atomically)
30709
+ *
30710
+ * ```ts
30711
+ * import { Effect, Ref } from "effect"
30712
+ *
30713
+ * const program = Effect.gen(function*() {
30714
+ * const counter = yield* Ref.make(10)
30715
+ *
30716
+ * // Modify the ref and return some computation result
30717
+ * const result = yield* Ref.modify(counter, (n) => [
30718
+ * `Previous value was ${n}`, // Return value
30719
+ * n * 2 // New ref value
30720
+ * ])
30721
+ *
30722
+ * console.log(result) // "Previous value was 10"
30723
+ *
30724
+ * const current = yield* Ref.get(counter)
30725
+ * console.log(current) // 20
30726
+ * })
30727
+ *
30728
+ * // Example with more complex computation
30729
+ * const program2 = Effect.gen(function*() {
30730
+ * const state = yield* Ref.make({ count: 0, total: 0 })
30731
+ *
30732
+ * const incremented = yield* Ref.modify(state, (s) => [
30733
+ * s.count, // Return previous count
30734
+ * { count: s.count + 1, total: s.total + s.count + 1 } // New state
30735
+ * ])
30736
+ *
30737
+ * console.log(incremented) // 0
30738
+ * })
30739
+ * ```
30740
+ *
30741
+ * @see {@link updateAndGet} for returning the new stored value
30742
+ * @see {@link modifySome} for optionally updating while returning a separate result
30743
+ *
30744
+ * @category setters
30745
+ * @since 2.0.0
30746
+ */
30747
+ const modify$2 = /*#__PURE__*/ dual(2, (self, f) => sync(() => {
30748
+ const [b, a] = f(self.ref.current);
30749
+ self.ref.current = a;
30750
+ return b;
30751
+ }));
30752
+ /**
31713
30753
  * Updates the value of the Ref atomically using the given function.
31714
30754
  *
31715
30755
  * **When to use**
@@ -31749,38 +30789,6 @@ const set$4 = /*#__PURE__*/ dual(2, (self, value) => sync(() => set$6(self.ref,
31749
30789
  const update$1 = /*#__PURE__*/ dual(2, (self, f) => sync(() => {
31750
30790
  self.ref.current = f(self.ref.current);
31751
30791
  }));
31752
- /**
31753
- * Updates the value of the Ref atomically using the given function and returns the new value.
31754
- *
31755
- * **When to use**
31756
- *
31757
- * Use to apply a state transition and return the new stored value.
31758
- *
31759
- * **Example** (Updating and returning the new value)
31760
- *
31761
- * ```ts
31762
- * import { Effect, Ref } from "effect"
31763
- *
31764
- * const program = Effect.gen(function*() {
31765
- * const counter = yield* Ref.make(5)
31766
- *
31767
- * // Update and get the new value in one operation
31768
- * const newValue = yield* Ref.updateAndGet(counter, (n) => n * 3)
31769
- * console.log(newValue) // 15
31770
- *
31771
- * // Verify the ref contains the new value
31772
- * const current = yield* Ref.get(counter)
31773
- * console.log(current) // 15
31774
- * })
31775
- * ```
31776
- *
31777
- * @see {@link update} for updating without returning the new value
31778
- * @see {@link getAndUpdate} for returning the previous value instead
31779
- *
31780
- * @category mutations
31781
- * @since 2.0.0
31782
- */
31783
- const updateAndGet = /*#__PURE__*/ dual(2, (self, f) => sync(() => self.ref.current = f(self.ref.current)));
31784
30792
  //#endregion
31785
30793
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/hashMap.js
31786
30794
  /**
@@ -35040,7 +34048,7 @@ const Proto$10 = /*#__PURE__*/ Object.create(null);
35040
34048
  Object.defineProperties(Proto$10, {
35041
34049
  [TypeId$22]: { value: TypeId$22 },
35042
34050
  [symbolRedactable]: { value(context) {
35043
- return redact(this, get$9(context, CurrentRedactedNames));
34051
+ return redact(this, get$8(context, CurrentRedactedNames));
35044
34052
  } },
35045
34053
  toJSON: { value() {
35046
34054
  return redact$1(this);
@@ -39414,7 +38422,7 @@ var MultipartError = class MultipartError extends TaggedError("MultipartError")
39414
38422
  * @since 4.0.0
39415
38423
  */
39416
38424
  const makeConfig = (headers) => withFiber((fiber) => {
39417
- const mimeTypes = get$9(fiber.context, FieldMimeTypes);
38425
+ const mimeTypes = get$8(fiber.context, FieldMimeTypes);
39418
38426
  return succeed$3({
39419
38427
  headers,
39420
38428
  maxParts: fiber.getRef(MaxParts),
@@ -40482,7 +39490,7 @@ var MiddlewareImpl = class MiddlewareImpl {
40482
39490
  const stack = [context.mapUnsafe.get(fnContextKey)];
40483
39491
  if (this.dependencies) {
40484
39492
  const memoMap = yield* CurrentMemoMap;
40485
- const scope = get$9(context, Scope);
39493
+ const scope = get$8(context, Scope);
40486
39494
  const depsContext = yield* buildWithMemoMap(this.dependencies, memoMap, scope);
40487
39495
  stack.push(...getMiddleware(depsContext));
40488
39496
  }
@@ -43534,7 +42542,7 @@ const makeNoSerialization = /*#__PURE__*/ fnUntraced(function* (group, options)
43534
42542
  const concurrency = options.concurrency ?? "unbounded";
43535
42543
  const disableFatalDefects = options.disableFatalDefects ?? false;
43536
42544
  const services = yield* context$1();
43537
- const scope = get$9(services, Scope);
42545
+ const scope = get$8(services, Scope);
43538
42546
  const trackFiber = runIn(forkUnsafe(scope, "parallel"));
43539
42547
  const concurrencySemaphore = concurrency === "unbounded" ? void 0 : yield* make$47(concurrency);
43540
42548
  const clients = /* @__PURE__ */ new Map();
@@ -43731,7 +42739,7 @@ const makeNoSerialization = /*#__PURE__*/ fnUntraced(function* (group, options)
43731
42739
  return flatMap$2(write, () => latch.await);
43732
42740
  })),
43733
42741
  step: constVoid
43734
- })), catchDone(() => void_$1), scoped$3);
42742
+ })), catchDone(() => void_$1), scoped$1);
43735
42743
  return runForEachArray(stream, (values) => {
43736
42744
  const write = options.onFromServer({
43737
42745
  _tag: "Chunk",
@@ -50250,7 +49258,7 @@ const layer$8 = /*#__PURE__*/ effect(Terminal$1, /*#__PURE__*/ (/* @__PURE__ */
50250
49258
  stdin.on("keypress", handleKeypress);
50251
49259
  return queue;
50252
49260
  });
50253
- const readLine = scoped$3(flatMap$2(get$4(rlRef), (readlineInterface) => callback$1((resume) => {
49261
+ const readLine = scoped$1(flatMap$2(get$4(rlRef), (readlineInterface) => callback$1((resume) => {
50254
49262
  const onLine = (line) => resume(succeed$3(line));
50255
49263
  readlineInterface.once("line", onLine);
50256
49264
  return sync(() => readlineInterface.off("line", onLine));
@@ -51752,7 +50760,7 @@ const Proto = {
51752
50760
  * @category constructors
51753
50761
  * @since 2.0.0
51754
50762
  */
51755
- const make$3 = (value) => map$4(unbounded$1({ replay: 1 }), (pubsub) => {
50763
+ const make$3 = (value) => map$4(unbounded({ replay: 1 }), (pubsub) => {
51756
50764
  const self = Object.create(Proto);
51757
50765
  self.semaphore = makeUnsafe$3(1);
51758
50766
  self.value = value;
@@ -51825,6 +50833,49 @@ const setUnsafe = (self, value) => {
51825
50833
  publishUnsafe(self.pubsub, value);
51826
50834
  };
51827
50835
  /**
50836
+ * Retrieves the current value and optionally updates the reference.
50837
+ *
50838
+ * **When to use**
50839
+ *
50840
+ * Use to read the old value while applying a synchronous update only when a
50841
+ * new value is available.
50842
+ *
50843
+ * **Details**
50844
+ *
50845
+ * If the function returns `Option.some`, the new value is set and published. If
50846
+ * it returns `Option.none`, the reference is left unchanged and no update is
50847
+ * published.
50848
+ *
50849
+ * **Example** (Getting and conditionally updating a value)
50850
+ *
50851
+ * ```ts
50852
+ * import { Effect, Option, SubscriptionRef } from "effect"
50853
+ *
50854
+ * const program = Effect.gen(function*() {
50855
+ * const ref = yield* SubscriptionRef.make(10)
50856
+ *
50857
+ * const oldValue = yield* SubscriptionRef.getAndUpdateSome(
50858
+ * ref,
50859
+ * (n) => n > 5 ? Option.some(n * 2) : Option.none()
50860
+ * )
50861
+ * console.log("Old value:", oldValue)
50862
+ *
50863
+ * const newValue = yield* SubscriptionRef.get(ref)
50864
+ * console.log("New value:", newValue)
50865
+ * })
50866
+ * ```
50867
+ *
50868
+ * @category getters
50869
+ * @since 2.0.0
50870
+ */
50871
+ const getAndUpdateSome = /*#__PURE__*/ dual(2, (self, update) => self.semaphore.withPermit(sync(() => {
50872
+ const current = self.value;
50873
+ const option = update(current);
50874
+ if (isNone(option)) return succeed$3(current);
50875
+ setUnsafe(self, option.value);
50876
+ return current;
50877
+ })));
50878
+ /**
51828
50879
  * Modifies the `SubscriptionRef` atomically with a function that computes a
51829
50880
  * return value and a new value, notifying subscribers of the change.
51830
50881
  *
@@ -52362,13 +51413,7 @@ var TerminalError = class extends TaggedErrorClass()("TerminalError", {
52362
51413
  cause: optional(Defect),
52363
51414
  message: optional(String$1)
52364
51415
  }) {};
52365
- const TerminalEvent = Struct({
52366
- data: String$1,
52367
- sequence: Number$1,
52368
- type: Literal("data")
52369
- });
52370
- const TerminalState = Struct({
52371
- runId: Number$1,
51416
+ const TerminalStatus = Struct({
52372
51417
  state: Literals([
52373
51418
  "idle",
52374
51419
  "starting",
@@ -52380,13 +51425,23 @@ const TerminalState = Struct({
52380
51425
  ]),
52381
51426
  title: String$1
52382
51427
  });
52383
- function terminalStateActive(state) {
51428
+ function terminalStatusActive(state) {
52384
51429
  return state === "idle" || state === "starting" || state === "running" || state === "waiting";
52385
51430
  }
52386
- const TerminalUpdate = Union([Struct({
52387
- state: TerminalState,
52388
- type: Literal("state")
52389
- }), TerminalEvent]);
51431
+ const TerminalAttachUpdate = Union([
51432
+ Struct({
51433
+ data: String$1,
51434
+ type: Literal("snapshot")
51435
+ }),
51436
+ Struct({
51437
+ data: String$1,
51438
+ type: Literal("data")
51439
+ }),
51440
+ Struct({
51441
+ status: TerminalStatus,
51442
+ type: Literal("status")
51443
+ })
51444
+ ]);
52390
51445
  //#endregion
52391
51446
  //#region src/rpcs/contracts.ts
52392
51447
  const CreateWorktreeSource = Union([
@@ -52427,7 +51482,7 @@ const AgentSession = Struct({
52427
51482
  "pi"
52428
51483
  ]),
52429
51484
  label: String$1,
52430
- state: TerminalState,
51485
+ state: TerminalStatus,
52431
51486
  uuid: String$1
52432
51487
  });
52433
51488
  var RpcContracts = class extends make$15(make$18("agents.create", {
@@ -52535,6 +51590,9 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52535
51590
  }), make$18("projects.deleteWorktree", {
52536
51591
  error: GitError,
52537
51592
  payload: Struct({ cwd: String$1 })
51593
+ }), make$18("projects.cleanup", {
51594
+ error: GitError,
51595
+ payload: Struct({ cwd: String$1 })
52538
51596
  }), make$18("runs.portless", {
52539
51597
  error: TerminalError,
52540
51598
  payload: Struct({ cwd: String$1 }),
@@ -52563,21 +51621,21 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52563
51621
  }), make$18("terminal.restart", {
52564
51622
  error: TerminalError,
52565
51623
  payload: TerminalPayload,
52566
- success: TerminalState
52567
- }), make$18("terminal.state.watch", {
51624
+ success: TerminalStatus
51625
+ }), make$18("terminal.status.watch", {
52568
51626
  error: TerminalError,
52569
51627
  payload: TerminalPayload,
52570
51628
  stream: true,
52571
- success: TerminalState
51629
+ success: TerminalStatus
52572
51630
  }), make$18("terminal.stop", {
52573
51631
  error: TerminalError,
52574
51632
  payload: TerminalPayload,
52575
- success: TerminalState
52576
- }), make$18("terminal.watch", {
51633
+ success: TerminalStatus
51634
+ }), make$18("terminal.attach", {
52577
51635
  error: TerminalError,
52578
51636
  payload: TerminalPayload,
52579
51637
  stream: true,
52580
- success: TerminalUpdate
51638
+ success: TerminalAttachUpdate
52581
51639
  })) {};
52582
51640
  //#endregion
52583
51641
  //#region ../../packages/git/src/service.ts
@@ -52588,7 +51646,7 @@ var GitCommand = class extends Service()("@deslop/git/service/GitCommand", { mak
52588
51646
  command: args[0] ?? "git",
52589
51647
  cwd
52590
51648
  });
52591
- return yield* scoped$3(gen(function* () {
51649
+ return yield* scoped$1(gen(function* () {
52592
51650
  const handle = yield* pipe(spawner.spawn(make$40("git", args, {
52593
51651
  cwd,
52594
51652
  stderr: "pipe",
@@ -52909,137 +51967,102 @@ var GitWorkspace = class extends Service()("@deslop/git/service/GitWorkspace", {
52909
51967
  }) }) {
52910
51968
  static layer = effect(this, this.make);
52911
51969
  };
52912
- var GitMaintenance = class extends Service()("@deslop/git/service/GitMaintenance", { make: gen(function* () {
51970
+ const cleanupGitProject = fn("Git.cleanupProject")(function* (cwd) {
52913
51971
  const git = yield* GitCommand;
52914
- const fs = yield* FileSystem;
52915
- const path = yield* Path$1;
52916
- const home = yield* pipe(string("HOME"), withDefault(process.cwd()));
52917
- const maintenanceLock = yield* make$47(1);
52918
- const collectRepositoriesFromRoots = fn("GitMaintenance.collectRepositoriesFromRoots")(function* (roots, repositories) {
52919
- yield* annotateCurrentSpan({
52920
- repositoryCount: length(repositories),
52921
- rootCount: length(roots)
52922
- });
52923
- return yield* match$2(roots, {
52924
- onEmpty: () => succeed$3(repositories),
52925
- onNonEmpty: (remainingRoots) => {
52926
- const root = remainingRoots[0];
52927
- return pipe(fs.readDirectory(root), orElseSucceed(() => empty$13()), flatMap$2((entries) => {
52928
- if (contains(entries, ".git")) return pipe(all({
52929
- gitDirectory: pipe(git.string(root, [
52930
- "rev-parse",
52931
- "--path-format=absolute",
52932
- "--git-common-dir"
52933
- ]), map$4(trim)),
52934
- worktrees: pipe(git.string(root, [
52935
- "worktree",
52936
- "list",
52937
- "--porcelain",
52938
- "-z"
52939
- ]), map$4(parseWorktreeRecords))
52940
- }, { concurrency: "unbounded" }), map$4((repository) => new GitRepository({
52941
- gitDirectory: repository.gitDirectory,
52942
- root: repository.worktrees[0]?.root ?? root
52943
- })), option$1, flatMap$2((repository) => collectRepositoriesFromRoots(drop$1(remainingRoots, 1), pipe(repository, match$4({
52944
- onNone: () => repositories,
52945
- onSome: (value) => append$1(repositories, value)
52946
- })))));
52947
- return pipe(entries, filter$1((entry) => !excludedDiscoveryEntries.has(entry) && !(startsWith(".")(entry) && entry !== ".git")), forEach$1((entry) => pipe(fs.stat(path.join(root, entry)), map$4((info) => info.type === "Directory" ? path.join(root, entry) : ""), orElseSucceed(() => ""))), flatMap$2((nextRoots) => collectRepositoriesFromRoots(pipe(nextRoots, filter$1(isNonEmpty$1), appendAll(drop$1(roots, 1))), repositories)));
52948
- }));
51972
+ yield* annotateCurrentSpan({ cwd });
51973
+ const root = yield* sync(() => NFS.realpathSync.native(cwd));
51974
+ yield* pipe(git.string(cwd, [
51975
+ "fetch",
51976
+ "--all",
51977
+ "--prune"
51978
+ ]), asVoid);
51979
+ const defaultBranch = yield* pipe(git.string(cwd, [
51980
+ "symbolic-ref",
51981
+ "--short",
51982
+ "refs/remotes/origin/HEAD"
51983
+ ]), map$4(flow(trim, replace(/^origin\//u, ""))), catchTag("GitError", () => pipe(git.string(cwd, [
51984
+ "rev-parse",
51985
+ "--verify",
51986
+ "main"
51987
+ ]), as("main"), catchTag("GitError", () => succeed$3("master")))));
51988
+ const mergedBranches = new Set(yield* git.lines(cwd, [
51989
+ "branch",
51990
+ "--merged",
51991
+ `origin/${defaultBranch}`,
51992
+ "--format=%(refname:short)"
51993
+ ]));
51994
+ const branchLines = yield* git.lines(cwd, [
51995
+ "for-each-ref",
51996
+ "refs/heads",
51997
+ "--format=%(refname:short)%00%(upstream:short)%00%(upstream:track)%00%(worktreepath)"
51998
+ ]);
51999
+ function cleanupBranch(branchLine) {
52000
+ return gen(function* () {
52001
+ const fields = split$1("\0")(branchLine);
52002
+ const branch = fields[0];
52003
+ const upstream = fields[1] ?? "";
52004
+ const track = fields[2] ?? "";
52005
+ const worktreePath = fields[3] ?? "";
52006
+ const worktreeRoot = isNonEmpty$1(worktreePath) ? yield* sync(() => NFS.existsSync(worktreePath) ? NFS.realpathSync.native(worktreePath) : worktreePath) : "";
52007
+ if (isEmpty$1(branch)) return;
52008
+ if (track === "[gone]") {
52009
+ if (worktreeRoot === root) return;
52010
+ if (isNonEmpty$1(worktreePath)) yield* git.string(cwd, [
52011
+ "worktree",
52012
+ "remove",
52013
+ "--force",
52014
+ worktreePath
52015
+ ]);
52016
+ yield* git.string(cwd, [
52017
+ "branch",
52018
+ "-D",
52019
+ branch
52020
+ ]);
52021
+ return;
52022
+ }
52023
+ if (isEmpty$1(upstream)) {
52024
+ if (branch === defaultBranch) return;
52025
+ if (!mergedBranches.has(branch)) return;
52026
+ if (worktreeRoot === root) return;
52027
+ if (isNonEmpty$1(worktreePath)) {
52028
+ if (!(yield* pipe(git.lines(worktreePath, ["status", "--porcelain"]), map$4(isReadonlyArrayEmpty)))) return;
52029
+ yield* git.string(cwd, [
52030
+ "worktree",
52031
+ "remove",
52032
+ "--force",
52033
+ worktreePath
52034
+ ]);
52035
+ }
52036
+ yield* git.string(cwd, [
52037
+ "branch",
52038
+ "-D",
52039
+ branch
52040
+ ]);
52041
+ return;
52042
+ }
52043
+ if (!includes("behind")(track) || includes("ahead")(track)) return;
52044
+ if (isNonEmpty$1(worktreePath)) {
52045
+ if (!(yield* pipe(git.lines(worktreePath, ["status", "--porcelain"]), map$4(isReadonlyArrayEmpty)))) return;
52046
+ yield* pipe(git.string(worktreePath, [
52047
+ "merge",
52048
+ "--ff-only",
52049
+ upstream
52050
+ ]), asVoid);
52051
+ return;
52949
52052
  }
52053
+ yield* pipe(git.string(cwd, [
52054
+ "branch",
52055
+ "-f",
52056
+ branch,
52057
+ upstream
52058
+ ]), asVoid);
52950
52059
  });
52060
+ }
52061
+ yield* forEach$1(branchLines, cleanupBranch, {
52062
+ concurrency: 16,
52063
+ discard: true
52951
52064
  });
52952
- const listRepositoriesFrom = fn("GitMaintenance.listRepositoriesFrom")(function* (cwd) {
52953
- yield* annotateCurrentSpan({ cwd });
52954
- return yield* pipe(fs.realPath(cwd), orElseSucceed(() => cwd), flatMap$2((root) => collectRepositoriesFromRoots([root], empty$13())), map$4((repositories) => pipe(repositories, dedupeWith((left, right) => left.gitDirectory === right.gitDirectory || left.root === right.root))));
52955
- });
52956
- const maintain = fn("GitMaintenance.maintain")(function* (cwd) {
52957
- yield* annotateCurrentSpan({ cwd });
52958
- yield* pipe(gen(function* () {
52959
- const repositories = yield* listRepositoriesFrom(cwd);
52960
- yield* annotateCurrentSpan({ repositoryCount: length(repositories) });
52961
- yield* forEach$1(repositories, (repository) => gen(function* () {
52962
- yield* pipe(git.string(repository.root, [
52963
- "fetch",
52964
- "--all",
52965
- "--prune"
52966
- ]), asVoid, withSpan("GitMaintenance.fetch", { attributes: { cwd: repository.root } }));
52967
- const worktrees = parseWorktreeRecords(yield* git.string(repository.root, [
52968
- "worktree",
52969
- "list",
52970
- "--porcelain",
52971
- "-z"
52972
- ]));
52973
- yield* forEach$1(yield* git.lines(repository.root, [
52974
- "for-each-ref",
52975
- "refs/heads",
52976
- "--format=%(refname:short)%00%(upstream:short)%00%(upstream:track)%00%(worktreepath)"
52977
- ]), (row) => pipe(gen(function* () {
52978
- const fields = split$1("\0")(row);
52979
- const branch = fields[0];
52980
- const upstream = fields[1] ?? "";
52981
- const track = fields[2] ?? "";
52982
- const worktreePath = fields[3] ?? pipe(worktrees, findFirst$2((worktree) => worktree.branch === branch), map$9((worktree) => worktree.root), getOrElse$1(() => ""));
52983
- yield* annotateCurrentSpan({
52984
- branch,
52985
- cwd: repository.root
52986
- });
52987
- if (isEmpty$1(branch)) return;
52988
- if (track === "[gone]") {
52989
- if (isNonEmpty$1(worktreePath)) yield* pipe(git.string(repository.root, [
52990
- "worktree",
52991
- "remove",
52992
- "--force",
52993
- worktreePath
52994
- ]), asVoid, withSpan("GitMaintenance.deleteWorktree", { attributes: {
52995
- branch,
52996
- cwd: repository.root
52997
- } }));
52998
- yield* pipe(git.string(repository.root, [
52999
- "branch",
53000
- "-D",
53001
- branch
53002
- ]), asVoid, withSpan("GitMaintenance.deleteBranch", { attributes: {
53003
- branch,
53004
- cwd: repository.root
53005
- } }));
53006
- return;
53007
- }
53008
- if (isEmpty$1(upstream) || !includes("behind")(track) || includes("ahead")(track)) return;
53009
- if (isNonEmpty$1(worktreePath)) {
53010
- yield* pipe(git.string(worktreePath, [
53011
- "merge",
53012
- "--ff-only",
53013
- upstream
53014
- ]), ignore$1, withSpan("GitMaintenance.fastForwardWorktree", { attributes: {
53015
- branch,
53016
- cwd: worktreePath
53017
- } }));
53018
- return;
53019
- }
53020
- yield* pipe(git.string(repository.root, [
53021
- "merge-base",
53022
- "--is-ancestor",
53023
- branch,
53024
- upstream
53025
- ]), andThen(git.string(repository.root, [
53026
- "branch",
53027
- "-f",
53028
- branch,
53029
- upstream
53030
- ])), ignore$1, withSpan("GitMaintenance.fastForwardBranch", { attributes: {
53031
- branch,
53032
- cwd: repository.root
53033
- } }));
53034
- }), withSpan("GitMaintenance.classifyBranch", { attributes: { cwd: repository.root } })), { concurrency: "unbounded" });
53035
- }), { concurrency: "unbounded" });
53036
- }), withPermit(maintenanceLock));
53037
- });
53038
- yield* pipe(maintain(home), ignore$1, andThen(sleep(seconds(180))), forever, forkScoped);
53039
- return { maintain };
53040
- }) }) {
53041
- static layer = effect(this, this.make);
53042
- };
52065
+ });
53043
52066
  var GitReview = class extends Service()("@deslop/git/service/GitReview", { make: fn("GitReview.make")(function* (config) {
53044
52067
  const spawner = yield* ChildProcessSpawner;
53045
52068
  const git = yield* GitCommand;
@@ -53178,7 +52201,7 @@ var GitReview = class extends Service()("@deslop/git/service/GitReview", { make:
53178
52201
  command: args[0] ?? "gh",
53179
52202
  cwd: config.cwd
53180
52203
  });
53181
- return yield* scoped$3(gen(function* () {
52204
+ return yield* scoped$1(gen(function* () {
53182
52205
  const handle = yield* pipe(spawner.spawn(make$40("gh", args, {
53183
52206
  cwd: config.cwd,
53184
52207
  stderr: "pipe",
@@ -53439,7 +52462,7 @@ var GitCommitAction = class extends Service()("@deslop/git/service/GitCommitActi
53439
52462
  command: args[0] ?? "gh",
53440
52463
  cwd: config.cwd
53441
52464
  });
53442
- return yield* scoped$3(gen(function* () {
52465
+ return yield* scoped$1(gen(function* () {
53443
52466
  const handle = yield* pipe(spawner.spawn(make$40("gh", args, {
53444
52467
  cwd: config.cwd,
53445
52468
  stderr: "pipe",
@@ -53812,244 +52835,172 @@ var Portless = class Portless extends Service()("@deslop/portless/Portless", { m
53812
52835
  });
53813
52836
  };
53814
52837
  //#endregion
53815
- //#region ../../packages/terminal/src/service.ts
53816
- var import_addon_progress = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
53817
- (function(e, t) {
53818
- "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define([], t) : "object" == typeof exports ? exports.ProgressAddon = t() : e.ProgressAddon = t();
53819
- })(globalThis, (() => (() => {
53820
- "use strict";
53821
- var e = {};
53822
- return (() => {
53823
- var t = e;
53824
- function s(e) {
53825
- let t = 0;
53826
- for (let s = 0; s < e.length; ++s) {
53827
- const r = e.charCodeAt(s);
53828
- if (r < 48 || 57 < r) return -1;
53829
- t = 10 * t + r - 48;
53830
- }
53831
- return t;
53832
- }
53833
- Object.defineProperty(t, "__esModule", { value: !0 }), t.ProgressAddon = void 0, t.ProgressAddon = class {
53834
- constructor() {
53835
- this._st = 0, this._pr = 0;
53836
- }
53837
- dispose() {
53838
- this._seqHandler?.dispose(), this._onChange?.dispose();
53839
- }
53840
- activate(e) {
53841
- this._seqHandler = e.parser.registerOscHandler(9, ((e) => {
53842
- if (!e.startsWith("4;")) return !1;
53843
- const t = e.split(";");
53844
- if (t.length > 3) return !0;
53845
- 2 === t.length && t.push("");
53846
- const r = s(t[1]), o = s(t[2]);
53847
- switch (r) {
53848
- case 0:
53849
- this.progress = {
53850
- state: r,
53851
- value: 0
53852
- };
53853
- break;
53854
- case 1:
53855
- if (o < 0) return !0;
53856
- this.progress = {
53857
- state: r,
53858
- value: o
53859
- };
53860
- break;
53861
- case 2:
53862
- case 4:
53863
- if (o < 0) return !0;
53864
- this.progress = {
53865
- state: r,
53866
- value: o || this._pr
53867
- };
53868
- break;
53869
- case 3: this.progress = {
53870
- state: r,
53871
- value: this._pr
53872
- };
53873
- }
53874
- return !0;
53875
- })), this._onChange = new e._core._onData.constructor(), this.onChange = this._onChange.event;
53876
- }
53877
- get progress() {
53878
- return {
53879
- state: this._st,
53880
- value: this._pr
53881
- };
53882
- }
53883
- set progress(e) {
53884
- e.state < 0 || e.state > 4 ? console.warn("progress state out of bounds, not applied") : (this._st = e.state, this._pr = Math.min(Math.max(e.value, 0), 100), this._onChange?.fire({
53885
- state: this._st,
53886
- value: this._pr
53887
- }));
53888
- }
53889
- };
53890
- })(), e;
53891
- })()));
53892
- })))(), 1);
53893
- const terminalReset = "\x1Bc";
53894
- function parseTitleSignal(title) {
52838
+ //#region ../../packages/terminal/src/model.ts
52839
+ const terminalReplayBytes = 8 * 1024 * 1024;
52840
+ const terminalChunkBytes = 64 * 1024;
52841
+ const terminalOscCarryBytes = 4096;
52842
+ function terminalByteLength(data) {
52843
+ return Buffer.byteLength(data);
52844
+ }
52845
+ function terminalChunks(data, chunkSize = terminalChunkBytes) {
52846
+ if (data === "") return empty$13();
52847
+ return pipe(range(0, Math.floor((data.length - 1) / chunkSize)), map$7((index) => data.slice(index * chunkSize, (index + 1) * chunkSize)));
52848
+ }
52849
+ function terminalReplayPush(ring, data, maxBytes = terminalReplayBytes) {
52850
+ let chunks = [...ring, data];
52851
+ let bytes = chunks.reduce((total, chunk) => total + terminalByteLength(chunk), 0);
52852
+ while (bytes > maxBytes) {
52853
+ const head = chunks[0];
52854
+ if (head === void 0) break;
52855
+ const excess = bytes - maxBytes;
52856
+ const headBytes = terminalByteLength(head);
52857
+ if (headBytes <= excess) {
52858
+ chunks = chunks.slice(1);
52859
+ bytes -= headBytes;
52860
+ continue;
52861
+ }
52862
+ let offset = Math.min(head.length, excess);
52863
+ while (offset < head.length && terminalByteLength(head.slice(offset)) > maxBytes - (bytes - headBytes)) offset += 1;
52864
+ chunks[0] = head.slice(offset);
52865
+ bytes = chunks.reduce((total, chunk) => total + terminalByteLength(chunk), 0);
52866
+ }
52867
+ return chunks;
52868
+ }
52869
+ function terminalTitleStatus(title) {
53895
52870
  const trimmed = title.trim();
53896
- if (/^\[\s*[!.]\s*\]\s*Action Required\b/iu.test(trimmed)) return {
53897
- state: "waiting",
53898
- title: trimmed.replace(/^\[\s*[!.]\s*\]\s*/iu, "") || trimmed
53899
- };
53900
- const spinner = /^(?:[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏|/\\-])(?:\s|\s*\|)/u.test(trimmed);
53901
- const nextTitle = trimmed.replace(/^OC\s*\|\s*/iu, "").replace(/^π\s*-\s*/iu, "").replace(/^\[\s*[^\]]+\s*\]\s*/u, "").replace(/^(?:[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏|/\\-]\s*)+/u, "").replace(/^\|\s*/u, "").trim() || trimmed;
53902
- const segment = /^(Idle|Ready|Starting|Working|Thinking|Waiting)\b/iu.exec(nextTitle)?.[1]?.toLowerCase();
53903
- if (segment === "idle" || segment === "ready") return {
52871
+ if (trimmed === "") return {
53904
52872
  state: "idle",
53905
- title: nextTitle
53906
- };
53907
- if (segment === "starting") return {
53908
- state: "starting",
53909
- title: nextTitle
52873
+ title: ""
53910
52874
  };
53911
- if (segment === "waiting") return {
52875
+ if (/^\[\s*[!.]\s*\]\s*Action Required\b/iu.test(trimmed)) return {
53912
52876
  state: "waiting",
53913
- title: nextTitle
52877
+ title: trimmed.replace(/^\[\s*[!.]\s*\]\s*/iu, "") || trimmed
53914
52878
  };
53915
- if (segment === "working" || segment === "thinking" || spinner) return {
52879
+ return {
53916
52880
  state: "running",
53917
- title: nextTitle
53918
- };
53919
- if (trimmed !== "") return {
53920
- state: "idle",
53921
- title: nextTitle
52881
+ title: trimmed
53922
52882
  };
52883
+ }
52884
+ function terminalProgressStatus(value) {
52885
+ const progressState = Number.parseInt(value, 10);
52886
+ if (progressState === 0) return "idle";
52887
+ if (progressState === 2) return "failed";
52888
+ if (progressState === 4) return "waiting";
52889
+ return "running";
52890
+ }
52891
+ function terminalOscUpdates(data, carry = "") {
52892
+ const input = `${carry}${data}`;
52893
+ const updates = [];
52894
+ let nextCarry = "";
52895
+ for (let index = 0; index < input.length; index += 1) {
52896
+ if (input.charCodeAt(index) !== 27) continue;
52897
+ if (index === input.length - 1) {
52898
+ nextCarry = input.slice(index);
52899
+ break;
52900
+ }
52901
+ if (input[index + 1] !== "]") continue;
52902
+ const start = index + 2;
52903
+ let end = input.indexOf("\x07", start);
52904
+ let skip = 1;
52905
+ const st = input.indexOf("\x1B\\", start);
52906
+ if (end === -1 || st !== -1 && st < end) {
52907
+ end = st;
52908
+ skip = 2;
52909
+ }
52910
+ if (end === -1) {
52911
+ nextCarry = input.slice(index);
52912
+ break;
52913
+ }
52914
+ const payload = input.slice(start, end);
52915
+ const separator = payload.indexOf(";");
52916
+ const command = separator === -1 ? payload : payload.slice(0, separator);
52917
+ const value = separator === -1 ? "" : payload.slice(separator + 1);
52918
+ if (command === "0" || command === "2") updates.push({
52919
+ title: value,
52920
+ type: "title"
52921
+ });
52922
+ if (command === "9" && value.startsWith("4;")) updates.push({
52923
+ state: terminalProgressStatus(value.slice(2)),
52924
+ type: "progress"
52925
+ });
52926
+ index = end + skip - 1;
52927
+ }
53923
52928
  return {
53924
- state: "idle",
53925
- title: ""
52929
+ carry: terminalByteLength(nextCarry) > terminalOscCarryBytes ? "" : nextCarry,
52930
+ updates
53926
52931
  };
53927
52932
  }
53928
- function snapshotEvents(data, sequence) {
53929
- if (data === "") return empty$13();
53930
- return pipe(range(0, Math.floor((data.length - 1) / (256 * 1024))), map$7((index) => ({
53931
- data: data.slice(index * 256 * 1024, (index + 1) * 256 * 1024),
53932
- sequence,
53933
- type: "data"
53934
- })));
53935
- }
53936
- function adjacentGroups(items, sameGroup, merge) {
52933
+ //#endregion
52934
+ //#region ../../packages/terminal/src/service.ts
52935
+ function mergeWrites(items) {
53937
52936
  return pipe(items, reduce(empty$13(), (groups, item) => {
53938
52937
  const previous = groups.at(-1);
53939
- if (previous === void 0 || !sameGroup(previous, item)) return append$1(groups, item);
53940
- return append$1(dropRight(groups, 1), merge(previous, item));
52938
+ if (previous === void 0 || previous.process !== item.process) return append$1(groups, item);
52939
+ return append$1(dropRight(groups, 1), {
52940
+ data: `${previous.data}${item.data}`,
52941
+ process: item.process
52942
+ });
53941
52943
  }));
53942
52944
  }
53943
- function queuedDataGroups(items, merge) {
53944
- return adjacentGroups(items, (previous, item) => previous.generation === item.generation, merge);
52945
+ function pauseProcess(subprocess) {
52946
+ if ("pause" in subprocess && typeof subprocess.pause === "function") subprocess.pause();
53945
52947
  }
53946
- function mergeQueuedData(previous, item) {
53947
- return {
53948
- data: `${previous.data}${item.data}`,
53949
- generation: item.generation
53950
- };
53951
- }
53952
- function queuedWriteGroups(items) {
53953
- return adjacentGroups(items, (previous, item) => previous.process === item.process, (previous, item) => ({
53954
- data: `${previous.data}${item.data}`,
53955
- process: item.process
53956
- }));
52948
+ function resumeProcess(subprocess) {
52949
+ if ("resume" in subprocess && typeof subprocess.resume === "function") subprocess.resume();
53957
52950
  }
53958
52951
  var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { make: fnUntraced(function* (config) {
53959
- const dataQueue = yield* unbounded();
53960
- const writeQueue = yield* unbounded();
52952
+ const dataQueue = yield* bounded(128);
52953
+ const writeQueue = yield* bounded(128);
53961
52954
  const resizeQueue = yield* sliding(1);
53962
- const events = yield* bounded$1(1024);
53963
52955
  const lifecycleLock = yield* make$47(1);
53964
- const screenLock = yield* make$47(1);
53965
- const eventSequenceRef = yield* make$38(0);
53966
- const parsedSequenceRef = yield* make$38(0);
53967
- const screenGenerationRef = yield* make$38(0);
53968
52956
  const processRef = yield* make$38(void 0);
52957
+ const replayProcessRef = yield* make$38(void 0);
53969
52958
  const sizeRef = yield* make$38({
53970
52959
  cols: 120,
53971
52960
  rows: 32
53972
52961
  });
52962
+ const replayRef = yield* make$38(empty$13());
52963
+ const oscRef = yield* make$38("");
52964
+ const attachRef = yield* make$38(void 0);
53973
52965
  const shell = yield* string("SHELL").pipe(orElseSucceed(() => "bash"));
53974
52966
  const processCommand = config.command?.command ?? shell;
53975
52967
  const processArgs = config.command?.args ?? [];
53976
52968
  const processEnv = config.command?.options.env ?? {};
53977
52969
  const autostart = config.command === void 0;
53978
- const stateRef = yield* make$3({
53979
- runId: 0,
52970
+ const statusRef = yield* make$3({
53980
52971
  state: autostart ? "starting" : "idle",
53981
52972
  title: ""
53982
52973
  });
53983
- const screen = new HeadlessModule.Terminal({
53984
- allowProposedApi: true,
53985
- cols: 120,
53986
- rows: 32,
53987
- scrollback: 1e4
53988
- });
53989
- const serialize = new SerializeModule.SerializeAddon();
53990
- const progressAddon = new import_addon_progress.ProgressAddon();
53991
- screen.loadAddon(serialize);
53992
- screen.loadAddon(progressAddon);
53993
- const publish$1 = fnUntraced(function* (data) {
53994
- const sequence = yield* updateAndGet(eventSequenceRef, (current) => current + 1);
53995
- yield* publish(events, {
53996
- data,
53997
- sequence,
53998
- type: "data"
52974
+ const publishStatus = fnUntraced(function* (status) {
52975
+ const previous = yield* getAndUpdateSome(statusRef, (current) => current.state === status.state && current.title === status.title ? none() : some(status));
52976
+ if (previous.state === status.state && previous.title === status.title) return;
52977
+ const attach = yield* get$3(attachRef);
52978
+ if (attach) yield* offer(attach, {
52979
+ status,
52980
+ type: "status"
53999
52981
  });
54000
- return sequence;
54001
52982
  });
54002
- const requestSnapshot = withPermit(screenLock, gen(function* () {
54003
- return {
54004
- data: serialize.serialize({ scrollback: 1e4 }),
54005
- sequence: yield* get$3(parsedSequenceRef)
54006
- };
54007
- }));
54008
- function setState(state) {
54009
- return update(stateRef, (current) => current.state === state ? current : {
52983
+ function setStatus(state) {
52984
+ return get(statusRef).pipe(flatMap$2((current) => publishStatus({
54010
52985
  ...current,
54011
52986
  state
54012
- });
54013
- }
54014
- function setProgressState(progressState) {
54015
- return update(stateRef, (current) => {
54016
- if (current.state === "stopped" || current.state === "exited" || current.state === "failed") return current;
54017
- const state = pipe(progressState.state, value, when(0, () => "idle"), when(2, () => "failed"), when(4, () => "waiting"), orElse(() => "running"));
54018
- if (current.state === state) return current;
54019
- return {
54020
- ...current,
54021
- state
54022
- };
54023
- });
52987
+ })));
54024
52988
  }
54025
52989
  function setTitle(title) {
54026
- return update(stateRef, (current) => {
54027
- if (!terminalStateActive(current.state)) return current;
54028
- const next = parseTitleSignal(title);
54029
- if (current.state === next.state && current.title === next.title) return current;
54030
- return {
52990
+ return get(statusRef).pipe(flatMap$2((current) => {
52991
+ if (!terminalStatusActive(current.state)) return void_$1;
52992
+ return publishStatus({
54031
52993
  ...current,
54032
- ...next
54033
- };
54034
- });
52994
+ ...terminalTitleStatus(title)
52995
+ });
52996
+ }));
52997
+ }
52998
+ function setProgress(state) {
52999
+ return get(statusRef).pipe(flatMap$2((current) => terminalStatusActive(current.state) ? publishStatus({
53000
+ ...current,
53001
+ state
53002
+ }) : void_$1));
54035
53003
  }
54036
- const startRun = pipe(update(stateRef, (state) => ({
54037
- ...state,
54038
- runId: state.runId + 1,
54039
- state: "starting",
54040
- title: ""
54041
- })), andThen(get(stateRef)));
54042
- screen.parser.registerOscHandler(0, (title) => {
54043
- runFork(setTitle(title));
54044
- return false;
54045
- });
54046
- screen.parser.registerOscHandler(2, (title) => {
54047
- runFork(setTitle(title));
54048
- return false;
54049
- });
54050
- progressAddon.onChange((nextProgress) => {
54051
- runFork(setProgressState(nextProgress));
54052
- });
54053
53004
  const interruptProcess = fnUntraced(function* (subprocess, signal) {
54054
53005
  yield* sync(() => {
54055
53006
  try {
@@ -54062,23 +53013,13 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
54062
53013
  yield* sleep("250 millis");
54063
53014
  yield* interruptProcess(subprocess, "SIGKILL");
54064
53015
  });
54065
- const writeScreen = fnUntraced(function* (input) {
54066
- if ((yield* get$3(screenGenerationRef)) !== input.generation) return;
54067
- yield* withPermit(screenLock, pipe(callback$1((resume) => {
54068
- screen.write(input.data, () => {
54069
- resume(succeed$3(void 0));
54070
- });
54071
- }), andThen(gen(function* () {
54072
- if ((yield* get$3(screenGenerationRef)) === input.generation) yield* set$4(parsedSequenceRef, yield* publish$1(input.data));
54073
- }))));
54074
- });
54075
53016
  const clearProcess = fnUntraced(function* (handle) {
54076
53017
  yield* update$1(processRef, (current) => current === handle ? void 0 : current);
54077
53018
  });
54078
53019
  const stopProcess = fnUntraced(function* (state) {
54079
53020
  const handle = yield* get$3(processRef);
54080
53021
  if (!handle) {
54081
- if (state) yield* setState(state);
53022
+ if (state) yield* setStatus(state);
54082
53023
  return;
54083
53024
  }
54084
53025
  yield* sync(() => {
@@ -54087,14 +53028,22 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
54087
53028
  });
54088
53029
  yield* clearProcess(handle);
54089
53030
  yield* pipe(terminateProcess(handle.process), ignore$1);
54090
- if (state) yield* setState(state);
53031
+ if (state) yield* setStatus(state);
54091
53032
  });
54092
53033
  const spawnProcess = fnUntraced(function* () {
54093
- const generation = yield* updateAndGet(screenGenerationRef, (current) => current + 1);
54094
- yield* withPermit(screenLock, pipe(sync(() => {
54095
- screen.reset();
54096
- }), andThen(publish$1(terminalReset)), tap((sequence) => set$4(parsedSequenceRef, sequence))));
54097
- yield* startRun;
53034
+ yield* stopProcess();
53035
+ yield* set$4(replayProcessRef, void 0);
53036
+ yield* set$4(replayRef, ["\x1Bc"]);
53037
+ yield* set$4(oscRef, "");
53038
+ yield* publishStatus({
53039
+ state: "starting",
53040
+ title: ""
53041
+ });
53042
+ const attach = yield* get$3(attachRef);
53043
+ if (attach) yield* offer(attach, {
53044
+ data: "\x1Bc",
53045
+ type: "data"
53046
+ });
54098
53047
  const size = yield* get$3(sizeRef);
54099
53048
  const subprocess = yield* try_({
54100
53049
  catch: (cause) => new TerminalError({
@@ -54115,54 +53064,36 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
54115
53064
  });
54116
53065
  const handle = {
54117
53066
  data: subprocess.onData((chunk) => {
54118
- offerUnsafe(dataQueue, {
53067
+ const output = {
54119
53068
  data: chunk,
54120
- generation
54121
- });
53069
+ process: subprocess
53070
+ };
53071
+ if (offerUnsafe(dataQueue, output)) return;
53072
+ pauseProcess(subprocess);
53073
+ runFork(offer(dataQueue, output).pipe(andThen(sync(() => resumeProcess(subprocess)))));
54122
53074
  }),
54123
53075
  exit: subprocess.onExit((event) => {
54124
53076
  runFork(withPermit(lifecycleLock, gen(function* () {
54125
53077
  if ((yield* get$3(processRef)) !== handle) return;
54126
53078
  yield* clearProcess(handle);
54127
53079
  if (autostart) {
54128
- yield* pipe(sleep("1 second"), andThen(spawnProcess()), catch_$2(() => setState("failed")));
53080
+ yield* pipe(sleep("1 second"), andThen(spawnProcess()), catch_$2(() => setStatus("failed")));
54129
53081
  return;
54130
53082
  }
54131
- yield* setState(event.exitCode === 0 ? "exited" : "failed");
53083
+ yield* setStatus(event.exitCode === 0 ? "exited" : "failed");
54132
53084
  })));
54133
53085
  }),
54134
53086
  process: subprocess
54135
53087
  };
54136
53088
  yield* set$4(processRef, handle);
54137
- yield* setState("running");
54138
- return yield* get(stateRef);
54139
- });
54140
- const startProcess = fnUntraced(function* () {
54141
- yield* stopProcess();
54142
- return yield* spawnProcess();
53089
+ yield* set$4(replayProcessRef, subprocess);
53090
+ yield* setStatus("running");
53091
+ return yield* get(statusRef);
54143
53092
  });
54144
- yield* pipe(fromQueue(dataQueue), groupedWithin(256, millis(16)), runForEach((items) => forEach$1(queuedDataGroups(fromIterable$2(items), mergeQueuedData), writeScreen, { discard: true })), forkScoped);
54145
- yield* addFinalizer(() => all([
54146
- stopProcess(),
54147
- shutdown$1(events),
54148
- shutdown(dataQueue),
54149
- shutdown(writeQueue),
54150
- shutdown(resizeQueue),
54151
- sync(() => {
54152
- screen.dispose();
54153
- })
54154
- ], {
54155
- concurrency: "unbounded",
54156
- discard: true
54157
- }));
54158
- if (autostart) yield* pipe(startProcess(), withPermit(lifecycleLock), catch_$2(() => setState("failed")));
54159
53093
  const resizeProcess = fnUntraced(function* (nextSize) {
54160
53094
  const size = yield* get$3(sizeRef);
54161
53095
  if (size.cols === nextSize.cols && size.rows === nextSize.rows) return;
54162
53096
  yield* set$4(sizeRef, nextSize);
54163
- yield* withPermit(screenLock, sync(() => {
54164
- screen.resize(nextSize.cols, nextSize.rows);
54165
- }));
54166
53097
  const process = yield* get$3(processRef);
54167
53098
  if (!process) return;
54168
53099
  yield* try_({
@@ -54175,10 +53106,6 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
54175
53106
  }
54176
53107
  });
54177
53108
  });
54178
- yield* pipe(fromQueue(resizeQueue), groupedWithin(32, millis(16)), runForEach((items) => pipe(last(fromIterable$2(items)), match$4({
54179
- onNone: () => void_$1,
54180
- onSome: resizeProcess
54181
- }))), forkScoped);
54182
53109
  const writeProcess = fnUntraced(function* (input) {
54183
53110
  if ((yield* get$3(processRef)) !== input.process) return;
54184
53111
  yield* try_({
@@ -54191,42 +53118,77 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
54191
53118
  }
54192
53119
  });
54193
53120
  });
54194
- yield* pipe(fromQueue(writeQueue), groupedWithin(128, millis(4)), runForEach((items) => forEach$1(queuedWriteGroups(fromIterable$2(items)), writeProcess, { discard: true })), forkScoped);
54195
- const eventsStream = scoped$1(unwrap$1(gen(function* () {
54196
- const subscription = yield* subscribe(events);
54197
- const snapshot = yield* requestSnapshot;
54198
- const pending = yield* takeUpTo(subscription, Number.POSITIVE_INFINITY);
54199
- const replay = filter$1(pending, (event) => event.sequence > snapshot.sequence);
54200
- const replaySequence = replay.at(-1)?.sequence ?? snapshot.sequence;
54201
- return pipe(fromIterable$1([
54202
- {
54203
- data: terminalReset,
54204
- sequence: snapshot.sequence,
53121
+ yield* pipe(fromQueue(dataQueue), groupedWithin(128, millis(16)), runForEach((items) => forEach$1(fromIterable$2(items), (output) => gen(function* () {
53122
+ if ((yield* get$3(replayProcessRef)) !== output.process) return;
53123
+ for (const chunk of terminalChunks(output.data)) {
53124
+ yield* update$1(replayRef, (ring) => terminalReplayPush(ring, chunk));
53125
+ const updates = yield* modify$2(oscRef, (carry) => {
53126
+ const parsed = terminalOscUpdates(chunk, carry);
53127
+ return [parsed.updates, parsed.carry];
53128
+ });
53129
+ for (const update of updates) yield* update.type === "title" ? setTitle(update.title) : setProgress(update.state);
53130
+ const attach = yield* get$3(attachRef);
53131
+ if (attach) yield* offer(attach, {
53132
+ data: chunk,
54205
53133
  type: "data"
54206
- },
54207
- ...snapshotEvents(snapshot.data, snapshot.sequence),
54208
- ...replay,
54209
- ...filter$1(pending, (event) => event.sequence > replaySequence)
54210
- ]), concat(fromEffectRepeat(take$2(subscription))));
54211
- })));
54212
- const stateUpdates = unwrap$1(pipe(get(stateRef), map$4((state) => concat(drop(1)(changes(stateRef)))(make$43(state)))));
54213
- const updates = merge$1(stateUpdates.pipe(map$2((state) => ({
54214
- state,
54215
- type: "state"
54216
- }))), eventsStream);
53134
+ });
53135
+ }
53136
+ }), { discard: true })), forkScoped);
53137
+ yield* pipe(fromQueue(resizeQueue), groupedWithin(32, millis(16)), runForEach((items) => pipe(last(fromIterable$2(items)), match$4({
53138
+ onNone: () => void_$1,
53139
+ onSome: resizeProcess
53140
+ }))), forkScoped);
53141
+ yield* pipe(fromQueue(writeQueue), groupedWithin(128, millis(4)), runForEach((items) => forEach$1(mergeWrites(fromIterable$2(items)), writeProcess, { discard: true })), forkScoped);
53142
+ yield* addFinalizer(() => all([
53143
+ stopProcess(),
53144
+ shutdown(dataQueue),
53145
+ shutdown(writeQueue),
53146
+ shutdown(resizeQueue),
53147
+ get$3(attachRef).pipe(flatMap$2((queue) => queue ? end(queue) : void_$1))
53148
+ ], {
53149
+ concurrency: "unbounded",
53150
+ discard: true
53151
+ }));
53152
+ if (autostart) yield* pipe(spawnProcess(), withPermit(lifecycleLock), catch_$2(() => setStatus("failed")));
53153
+ const attachQueue = gen(function* () {
53154
+ const previous = yield* get$3(attachRef);
53155
+ const queue = yield* dropping(16);
53156
+ yield* offer(queue, {
53157
+ status: yield* get(statusRef),
53158
+ type: "status"
53159
+ });
53160
+ yield* offer(queue, {
53161
+ data: pipe(yield* get$3(replayRef), join$2("")),
53162
+ type: "snapshot"
53163
+ });
53164
+ yield* set$4(attachRef, queue);
53165
+ if (previous) yield* end(previous);
53166
+ yield* addFinalizer(() => update$1(attachRef, (current) => current === queue ? void 0 : current).pipe(andThen(end(queue))));
53167
+ return queue;
53168
+ });
53169
+ const statusQueue = gen(function* () {
53170
+ const queue = yield* sliding(1);
53171
+ yield* addFinalizer(() => end(queue));
53172
+ yield* offer(queue, yield* get(statusRef));
53173
+ yield* pipe(changes(statusRef), drop(1), groupedWithin(32, millis(250)), runForEach((items) => pipe(last(fromIterable$2(items)), match$4({
53174
+ onNone: () => void_$1,
53175
+ onSome: (status) => offer(queue, status)
53176
+ }))), forkScoped);
53177
+ return queue;
53178
+ });
54217
53179
  return {
53180
+ attachQueue,
54218
53181
  resize: fnUntraced(function* (size) {
54219
53182
  yield* offer(resizeQueue, size);
54220
53183
  }),
54221
53184
  restart: fnUntraced(function* () {
54222
- return yield* pipe(startProcess(), withPermit(lifecycleLock), catch_$2(() => pipe(setState("failed"), andThen(get(stateRef)))));
53185
+ return yield* pipe(spawnProcess(), withPermit(lifecycleLock), catch_$2(() => pipe(setStatus("failed"), andThen(get(statusRef)))));
54223
53186
  }),
54224
- stateUpdates,
53187
+ statusQueue,
54225
53188
  stop: fnUntraced(function* () {
54226
53189
  yield* pipe(stopProcess("stopped"), withPermit(lifecycleLock));
54227
- return yield* get(stateRef);
53190
+ return yield* get(statusRef);
54228
53191
  }),
54229
- updates,
54230
53192
  write: fnUntraced(function* (data) {
54231
53193
  if (data === "") return;
54232
53194
  const process = yield* get$3(processRef);
@@ -54256,6 +53218,9 @@ const AgentSessionKey = Struct({
54256
53218
  cwd: String$1,
54257
53219
  uuid: String$1
54258
53220
  });
53221
+ function terminalStatusDone(state) {
53222
+ return !terminalStatusActive(state.state);
53223
+ }
54259
53224
  function terminalSessionInput(session) {
54260
53225
  if ("args" in session || "env" in session) return {
54261
53226
  command: session.command === void 0 ? void 0 : make$40(session.command, session.args ?? [], { env: session.env }),
@@ -54276,19 +53241,19 @@ function terminalSessionInput(session) {
54276
53241
  const TerminalSessions = make$46({
54277
53242
  idleTimeToLive: infinity,
54278
53243
  lookup: fnUntraced(function* (config) {
54279
- return get$9(yield* buildWithScope(Terminal.layer(config), yield* scope), Terminal);
53244
+ return get$8(yield* buildWithScope(Terminal.layer(config), yield* scope), Terminal);
54280
53245
  })
54281
53246
  });
54282
53247
  const GitReviewSessions = make$46({
54283
53248
  idleTimeToLive: zero$1,
54284
53249
  lookup: fnUntraced(function* (cwd) {
54285
- return get$9(yield* buildWithScope(pipe(GitReview.layer({ cwd }), provide$2(GitCommand.layer)), yield* scope), GitReview);
53250
+ return get$8(yield* buildWithScope(pipe(GitReview.layer({ cwd }), provide$2(GitCommand.layer)), yield* scope), GitReview);
54286
53251
  })
54287
53252
  });
54288
53253
  const GitCommitSessions = make$46({
54289
53254
  idleTimeToLive: minutes(5),
54290
53255
  lookup: fnUntraced(function* (cwd) {
54291
- return get$9(yield* buildWithScope(pipe(GitCommitAction.layer({ cwd }), provide$2(GitCommand.layer)), yield* scope), GitCommitAction);
53256
+ return get$8(yield* buildWithScope(pipe(GitCommitAction.layer({ cwd }), provide$2(GitCommand.layer)), yield* scope), GitCommitAction);
54292
53257
  })
54293
53258
  });
54294
53259
  const RpcHandlers = RpcContracts.toLayer(gen(function* () {
@@ -54341,7 +53306,7 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
54341
53306
  }) });
54342
53307
  const updateReviewState = fn("RpcHandlers.updateReviewState")(function* (cwd, f) {
54343
53308
  yield* annotateCurrentSpan({ cwd });
54344
- return yield* pipe(scoped$3(gen(function* () {
53309
+ return yield* pipe(scoped$1(gen(function* () {
54345
53310
  yield* modify(yield* get$6(reviewStates, cwd), (current) => {
54346
53311
  const next = f(current);
54347
53312
  return [next, next];
@@ -54372,7 +53337,6 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
54372
53337
  icon: payload.icon,
54373
53338
  label: `${payload.label} ${labelCount + 1}`,
54374
53339
  state: {
54375
- runId: 0,
54376
53340
  state: "starting",
54377
53341
  title: ""
54378
53342
  },
@@ -54382,39 +53346,41 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
54382
53346
  cwd: agentSession.cwd,
54383
53347
  uuid: agentSession.uuid
54384
53348
  }), agentSession));
54385
- const sessionTerminal = yield* terminalSession(TerminalSessionKey.make({
53349
+ const input = yield* terminalSession(TerminalSessionKey.make({
54386
53350
  args: agentSession.args,
54387
53351
  command: agentSession.command,
54388
53352
  cwd: agentSession.cwd,
54389
53353
  sessionId: agentSession.uuid
54390
- })).pipe(map$4(terminalSessionInput), flatMap$2((input) => get$6(terminals, input)));
53354
+ })).pipe(map$4(terminalSessionInput));
53355
+ const sessionTerminal = yield* get$6(terminals, input);
54391
53356
  yield* sessionTerminal.restart();
54392
- yield* pipe(sessionTerminal.stateUpdates, takeUntil((state) => state.state === "exited" || state.state === "failed" || state.state === "stopped"), runForEach((state) => gen(function* () {
54393
- const key = AgentSessionKey.make({
54394
- cwd: agentSession.cwd,
54395
- uuid: agentSession.uuid
53357
+ const key = AgentSessionKey.make({
53358
+ cwd: agentSession.cwd,
53359
+ uuid: agentSession.uuid
53360
+ });
53361
+ yield* pipe(scoped$1(gen(function* () {
53362
+ const states = yield* sessionTerminal.statusQueue;
53363
+ let done = false;
53364
+ yield* whileLoop({
53365
+ body: () => flatMap$2(take$1(states), (state) => pipe(update(agents, (sessions) => modifyAt(sessions, key, match$4({
53366
+ onNone: () => none(),
53367
+ onSome: (session) => some({
53368
+ ...session,
53369
+ state
53370
+ })
53371
+ }))), andThen(terminalStatusDone(state) ? pipe(update(agents, (sessions) => remove$2(sessions, key)), andThen(pipe(invalidate(terminals, input), ignore$1))) : void_$1), as(state))),
53372
+ step(state) {
53373
+ done = terminalStatusDone(state);
53374
+ },
53375
+ while: () => !done
54396
53376
  });
54397
- yield* update(agents, (sessions) => modifyAt(sessions, key, match$4({
54398
- onNone: () => none(),
54399
- onSome: (session) => some({
54400
- ...session,
54401
- state
54402
- })
54403
- })));
54404
- if (state.state !== "exited" && state.state !== "failed" && state.state !== "stopped") return;
54405
- yield* update(agents, (sessions) => remove$2(sessions, key));
54406
- yield* pipe(invalidate(terminals, terminalSessionInput({
54407
- args: agentSession.args,
54408
- command: agentSession.command,
54409
- cwd: agentSession.cwd,
54410
- sessionId: agentSession.uuid
54411
- })), ignore$1);
54412
53377
  })), forkDetach);
54413
53378
  return agentSession;
54414
53379
  }),
54415
53380
  "agents.remove": (payload) => removeAgent(AgentSessionKey.make(payload)),
54416
53381
  "agents.watch": (payload) => unwrap$1(pipe(get(agents), map$4((current) => pipe(make$43(current), concat(drop(1)(changes(agents))), map$2((sessions) => pipe(fromIterable$2(values(sessions)), filter$1((session) => session.cwd === payload.cwd))))))),
54417
53382
  "projects.branches": (payload) => git.branches(payload.cwd),
53383
+ "projects.cleanup": (payload) => pipe(cleanupGitProject(payload.cwd), provide(GitCommand.layer), ensuring$2(pipe(git.refreshProjects(), ignore$1))),
54418
53384
  "projects.createWorktree": (payload) => git.createWorktree(payload),
54419
53385
  "projects.deleteWorktree": (payload) => git.deleteWorktree(payload),
54420
53386
  "projects.watch": () => unwrap$1(map$4(get(git.projects), (projects) => pipe(make$43(projects), concat(drop(1)(changes(git.projects)))))),
@@ -54442,14 +53408,14 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
54442
53408
  } })),
54443
53409
  "review.state.watch": (payload) => unwrap$1(pipe(get$6(reviewStates, payload.cwd), flatMap$2((ref) => pipe(get(ref), map$4((state) => concat(drop(1)(changes(ref)))(make$43(state))))))),
54444
53410
  "runs.portless": (payload) => get$6(portlessWorktrees, payload.cwd),
53411
+ "terminal.attach": (payload) => flatMap$2(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.attachQueue),
54445
53412
  "terminal.resize": (payload) => pipe(getTerminal(TerminalSessionKey.make(payload)), flatMap$2((sessionTerminal) => sessionTerminal.resize({
54446
53413
  cols: payload.cols,
54447
53414
  rows: payload.rows
54448
53415
  }))),
54449
53416
  "terminal.restart": (payload) => flatMap$2(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.restart()),
54450
- "terminal.state.watch": (payload) => unwrap$1(map$4(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.stateUpdates)),
53417
+ "terminal.status.watch": (payload) => flatMap$2(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.statusQueue),
54451
53418
  "terminal.stop": (payload) => flatMap$2(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.stop()),
54452
- "terminal.watch": (payload) => unwrap$1(map$4(getTerminal(TerminalSessionKey.make(payload)), (sessionTerminal) => sessionTerminal.updates)),
54453
53419
  "terminal.write": (payload) => pipe(getTerminal(TerminalSessionKey.make(payload)), flatMap$2((sessionTerminal) => sessionTerminal.write(payload.data)))
54454
53420
  });
54455
53421
  }));
@@ -71233,7 +70199,7 @@ function OtelLayer(serviceName) {
71233
70199
  }
71234
70200
  //#endregion
71235
70201
  //#region src/lib/serverRuntime.ts
71236
- const LiveLayers = pipe(empty$11, provideMerge(RpcHandlers), provideMerge(Portless.layer), provideMerge(pipe(GitWorkspace.layer, provide$2(GitCommand.layer))), provideMerge(pipe(GitMaintenance.layer, provide$2(GitCommand.layer))), provideMerge(unwrap$4(pipe(string("HOME"), withDefault(process.cwd()), map$4((home) => layerFileSystem(path.join(home, ".deslop")))))), provideMerge(OtelLayer("workbench-server")), provideMerge(layer$16), provideMerge(layerMsgPack));
70202
+ const LiveLayers = pipe(empty$11, provideMerge(RpcHandlers), provideMerge(Portless.layer), provideMerge(pipe(GitWorkspace.layer, provide$2(GitCommand.layer))), provideMerge(unwrap$4(pipe(string("HOME"), withDefault(process.cwd()), map$4((home) => layerFileSystem(path.join(home, ".deslop")))))), provideMerge(OtelLayer("workbench-server")), provideMerge(layer$16), provideMerge(layerMsgPack));
71237
70203
  //#endregion
71238
70204
  //#region src/main.server.ts
71239
70205
  runMain(pipe(serve(mergeAll$1(layerHttp({