| ... | ... | @@ -26,6 +26,7 @@ import * as Layer from "effect/Layer"; |
| 26 | 26 | import * as Option from "effect/Option"; |
| 27 | 27 | import * as PlatformError from "effect/PlatformError"; |
| 28 | 28 | import * as Path from "effect/Path"; |
| 29 | import * as Queue from "effect/Queue"; |
| 29 | 30 | import * as Ref from "effect/Ref"; |
| 30 | 31 | import * as Schedule from "effect/Schedule"; |
| 31 | 32 | import * as Schema from "effect/Schema"; |
| ... | ... | @@ -1400,6 +1401,50 @@ it.layer( |
| 1400 | 1401 | }), |
| 1401 | 1402 | ); |
| 1402 | 1403 | |
| 1404 | it.effect("coalesces live history writes while retaining the latest output on close", () => |
| 1405 | Effect.gen(function* () { |
| 1406 | const fs = yield* FileSystem.FileSystem; |
| 1407 | const writes = yield* Queue.unbounded<string>(); |
| 1408 | const output = yield* Queue.unbounded<string>(); |
| 1409 | const trackedFileSystem = FileSystem.FileSystem.of({ |
| 1410 | ...fs, |
| 1411 | writeFileString: (filePath, contents, options) => |
| 1412 | fs |
| 1413 | .writeFileString(filePath, contents, options) |
| 1414 | .pipe( |
| 1415 | Effect.tap(() => (contents.length > 0 ? Queue.offer(writes, contents) : Effect.void)), |
| 1416 | ), |
| 1417 | }); |
| 1418 | const { manager, ptyAdapter } = yield* createManager(5, { processKillGraceMs: 0 }).pipe( |
| 1419 | Effect.provideService(FileSystem.FileSystem, trackedFileSystem), |
| 1420 | ); |
| 1421 | yield* manager.open(openInput()); |
| 1422 | const unsubscribe = yield* manager.subscribe((event) => |
| 1423 | event.type === "output" ? Queue.offer(output, event.data).pipe(Effect.asVoid) : Effect.void, |
| 1424 | ); |
| 1425 | yield* Effect.addFinalizer(() => Effect.sync(unsubscribe)); |
| 1426 | const process = ptyAdapter.processes[0]!; |
| 1427 | |
| 1428 | process.emitData("first"); |
| 1429 | yield* Queue.take(output); |
| 1430 | yield* TestClock.adjust("200 millis"); |
| 1431 | expect(yield* Queue.size(writes)).toBe(0); |
| 1432 | |
| 1433 | process.emitData(" second"); |
| 1434 | yield* Queue.take(output); |
| 1435 | yield* TestClock.adjust("50 millis"); |
| 1436 | expect(yield* Queue.take(writes)).toBe("first second"); |
| 1437 | |
| 1438 | process.emitData(" third"); |
| 1439 | yield* Queue.take(output); |
| 1440 | const close = yield* manager.close({ threadId: "thread-1" }).pipe(Effect.forkScoped); |
| 1441 | yield* Effect.yieldNow; |
| 1442 | yield* TestClock.adjust("250 millis"); |
| 1443 | yield* Fiber.join(close); |
| 1444 | expect((yield* manager.open(openInput())).history).toBe("first second third"); |
| 1445 | }).pipe(Effect.provide(TestClock.layer())), |
| 1446 | ); |
| 1447 | |
| 1403 | 1448 | it.effect("caps persisted history to configured line limit", () => |
| 1404 | 1449 | Effect.gen(function* () { |
| 1405 | 1450 | const { manager, ptyAdapter } = yield* createManager(3); |