effect-cf 0.41.0 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Sandbox.ts CHANGED
@@ -44,6 +44,8 @@ import * as Binding from "./Binding";
44
44
  import type { ContainerStartOptions, ContainerStopSignal } from "./ContainerNamespace";
45
45
  import { WorkerEnvironment } from "./Environment";
46
46
  import * as ErrorMessage from "./internal/ErrorMessage";
47
+ import { CurrentTargets } from "./internal/RpcTargets";
48
+ import * as RpcTargets from "./RpcTargets";
47
49
 
48
50
  export type {
49
51
  BackupOptions,
@@ -370,6 +372,7 @@ const trySandboxPromise = <A>(
370
372
  instance: string,
371
373
  operation: string,
372
374
  evaluate: (signal: AbortSignal) => PromiseLike<A>,
375
+ target?: SandboxClientResource | SandboxNamespaceResource,
373
376
  ): Effect.Effect<A, SandboxOperationError> =>
374
377
  Effect.tryPromise({
375
378
  try: evaluate,
@@ -380,16 +383,19 @@ const trySandboxPromise = <A>(
380
383
  operation,
381
384
  cause,
382
385
  }),
383
- });
386
+ }).pipe(
387
+ Effect.tapCause(() => (target === undefined ? Effect.void : RpcTargets.invalidate(target))),
388
+ );
384
389
 
385
390
  const sandboxStream = <A>(
386
391
  definition: SandboxDefinition,
387
392
  instance: string,
388
393
  operation: string,
389
394
  acquire: (signal: AbortSignal) => PromiseLike<ReadableStream<A>>,
395
+ target: SandboxClientResource | SandboxNamespaceResource,
390
396
  ): Stream.Stream<A, SandboxOperationError> =>
391
397
  Stream.unwrap(
392
- Effect.map(trySandboxPromise(definition, instance, operation, acquire), (readable) =>
398
+ Effect.map(trySandboxPromise(definition, instance, operation, acquire, target), (readable) =>
393
399
  Stream.fromReadableStream({
394
400
  evaluate: () => readable,
395
401
  onError: (cause) =>
@@ -401,7 +407,7 @@ const sandboxStream = <A>(
401
407
  }),
402
408
  }),
403
409
  ),
404
- );
410
+ ).pipe(Stream.tapCause(() => RpcTargets.invalidate(target)));
405
411
 
406
412
  const decodeSseData = <A>(payload: string): ReadonlyArray<A> => {
407
413
  if (payload === "[DONE]" || payload.trim() === "") {
@@ -451,7 +457,14 @@ const makeProcessHandle = (
451
457
  definition: SandboxDefinition,
452
458
  instance: string,
453
459
  process: SandboxProcess,
460
+ target: SandboxClientResource | SandboxNamespaceResource,
454
461
  ): SandboxProcessHandle => {
462
+ const attempt = <A>(operation: string, evaluate: (signal: AbortSignal) => PromiseLike<A>) =>
463
+ trySandboxPromise(definition, instance, operation, evaluate, target);
464
+ const stream = <A>(
465
+ operation: string,
466
+ acquire: (signal: AbortSignal) => PromiseLike<ReadableStream<A>>,
467
+ ) => sandboxStream(definition, instance, operation, acquire, target);
455
468
  const spanOptions = (operation: string) => ({
456
469
  attributes: {
457
470
  binding: definition.binding,
@@ -465,24 +478,19 @@ const makeProcessHandle = (
465
478
  id: process.id,
466
479
  pid: process.pid,
467
480
  rawUnsafe: Effect.succeed(process),
468
- status: trySandboxPromise(definition, instance, "process.status", () => process.status()).pipe(
481
+ status: attempt("process.status", () => process.status()).pipe(
469
482
  Effect.withSpan("Sandbox.process.status", spanOptions("process.status")),
470
483
  ),
471
- exitCode: trySandboxPromise(
472
- definition,
473
- instance,
474
- "process.exitCode",
475
- () => process.exitCode,
476
- ).pipe(Effect.withSpan("Sandbox.process.exitCode", spanOptions("process.exitCode"))),
484
+ exitCode: attempt("process.exitCode", () => process.exitCode).pipe(
485
+ Effect.withSpan("Sandbox.process.exitCode", spanOptions("process.exitCode")),
486
+ ),
477
487
  logs: (options?: Omit<ProcessLogsOptions, "signal">) =>
478
- sandboxStream(definition, instance, "process.logs", (signal) =>
479
- process.logs({ ...options, signal }),
480
- ),
488
+ stream("process.logs", (signal) => process.logs({ ...options, signal })),
481
489
  waitForLog: Effect.fn(
482
490
  "Sandbox.process.waitForLog",
483
491
  spanOptions("process.waitForLog"),
484
492
  )(function* (pattern: string | RegExp, options?: Omit<WaitForLogOptions, "signal">) {
485
- return yield* trySandboxPromise(definition, instance, "process.waitForLog", (signal) =>
493
+ return yield* attempt("process.waitForLog", (signal) =>
486
494
  process.waitForLog(pattern, { ...options, signal }),
487
495
  );
488
496
  }),
@@ -490,7 +498,7 @@ const makeProcessHandle = (
490
498
  "Sandbox.process.waitForExit",
491
499
  spanOptions("process.waitForExit"),
492
500
  )(function* (options?: Omit<WaitForExitOptions, "signal">) {
493
- return yield* trySandboxPromise(definition, instance, "process.waitForExit", (signal) =>
501
+ return yield* attempt("process.waitForExit", (signal) =>
494
502
  process.waitForExit({ ...options, signal }),
495
503
  );
496
504
  }),
@@ -498,15 +506,13 @@ const makeProcessHandle = (
498
506
  "Sandbox.process.output",
499
507
  spanOptions("process.output"),
500
508
  )(function* (options?: Omit<ProcessOutputOptions, "signal">) {
501
- return yield* trySandboxPromise(definition, instance, "process.output", (signal) =>
502
- process.output({ ...options, signal }),
503
- );
509
+ return yield* attempt("process.output", (signal) => process.output({ ...options, signal }));
504
510
  }),
505
511
  outputText: Effect.fn(
506
512
  "Sandbox.process.outputText",
507
513
  spanOptions("process.outputText"),
508
514
  )(function* (options?: Omit<ProcessOutputOptions, "signal">) {
509
- return yield* trySandboxPromise(definition, instance, "process.outputText", (signal) =>
515
+ return yield* attempt("process.outputText", (signal) =>
510
516
  process.output({ ...options, encoding: "utf8", signal }),
511
517
  );
512
518
  }),
@@ -514,7 +520,7 @@ const makeProcessHandle = (
514
520
  "Sandbox.process.waitForPort",
515
521
  spanOptions("process.waitForPort"),
516
522
  )(function* (port: number, options?: Omit<WaitForPortOptions, "signal">) {
517
- return yield* trySandboxPromise(definition, instance, "process.waitForPort", (signal) =>
523
+ return yield* attempt("process.waitForPort", (signal) =>
518
524
  process.waitForPort(port, { ...options, signal }),
519
525
  );
520
526
  }),
@@ -522,9 +528,7 @@ const makeProcessHandle = (
522
528
  "Sandbox.process.kill",
523
529
  spanOptions("process.kill"),
524
530
  )(function* (signal?: number) {
525
- return yield* trySandboxPromise(definition, instance, "process.kill", () =>
526
- process.kill(signal),
527
- );
531
+ return yield* attempt("process.kill", () => process.kill(signal));
528
532
  }),
529
533
  };
530
534
  };
@@ -533,7 +537,14 @@ const makeTerminalHandle = (
533
537
  definition: SandboxDefinition,
534
538
  instance: string,
535
539
  terminal: Terminal,
540
+ target: SandboxClientResource | SandboxNamespaceResource,
536
541
  ): SandboxTerminalHandle => {
542
+ const attempt = <A>(operation: string, evaluate: (signal: AbortSignal) => PromiseLike<A>) =>
543
+ trySandboxPromise(definition, instance, operation, evaluate, target);
544
+ const stream = <A>(
545
+ operation: string,
546
+ acquire: (signal: AbortSignal) => PromiseLike<ReadableStream<A>>,
547
+ ) => sandboxStream(definition, instance, operation, acquire, target);
537
548
  const spanOptions = (operation: string) => ({
538
549
  attributes: {
539
550
  binding: definition.binding,
@@ -546,43 +557,37 @@ const makeTerminalHandle = (
546
557
  return {
547
558
  id: terminal.id,
548
559
  rawUnsafe: Effect.succeed(terminal),
549
- snapshot: trySandboxPromise(definition, instance, "terminal.snapshot", () =>
550
- terminal.getSnapshot(),
551
- ).pipe(Effect.withSpan("Sandbox.terminal.snapshot", spanOptions("terminal.snapshot"))),
560
+ snapshot: attempt("terminal.snapshot", () => terminal.getSnapshot()).pipe(
561
+ Effect.withSpan("Sandbox.terminal.snapshot", spanOptions("terminal.snapshot")),
562
+ ),
552
563
  write: Effect.fn(
553
564
  "Sandbox.terminal.write",
554
565
  spanOptions("terminal.write"),
555
566
  )(function* (data: Uint8Array) {
556
- return yield* trySandboxPromise(definition, instance, "terminal.write", () =>
557
- terminal.write(data),
558
- );
567
+ return yield* attempt("terminal.write", () => terminal.write(data));
559
568
  }),
560
569
  resize: Effect.fn(
561
570
  "Sandbox.terminal.resize",
562
571
  spanOptions("terminal.resize"),
563
572
  )(function* (cols: number, rows: number) {
564
- return yield* trySandboxPromise(definition, instance, "terminal.resize", () =>
565
- terminal.resize(cols, rows),
566
- );
573
+ return yield* attempt("terminal.resize", () => terminal.resize(cols, rows));
567
574
  }),
568
575
  output: (options?: Omit<TerminalOutputOptions, "signal">) =>
569
- sandboxStream(definition, instance, "terminal.output", (signal) =>
570
- terminal.output({ ...options, signal }),
571
- ),
576
+ stream("terminal.output", (signal) => terminal.output({ ...options, signal })),
572
577
  waitForExit: Effect.fn(
573
578
  "Sandbox.terminal.waitForExit",
574
579
  spanOptions("terminal.waitForExit"),
575
580
  )(function* (options?: Omit<WaitForExitOptions, "signal">) {
576
- return yield* trySandboxPromise(definition, instance, "terminal.waitForExit", (signal) =>
581
+ return yield* attempt("terminal.waitForExit", (signal) =>
577
582
  terminal.waitForExit({ ...options, signal }),
578
583
  );
579
584
  }),
580
- interrupt: trySandboxPromise(definition, instance, "terminal.interrupt", () =>
581
- terminal.interrupt(),
582
- ).pipe(Effect.withSpan("Sandbox.terminal.interrupt", spanOptions("terminal.interrupt"))),
583
- terminate: trySandboxPromise(definition, instance, "terminal.terminate", () =>
584
- terminal.terminate(),
585
- ).pipe(Effect.withSpan("Sandbox.terminal.terminate", spanOptions("terminal.terminate"))),
585
+ interrupt: attempt("terminal.interrupt", () => terminal.interrupt()).pipe(
586
+ Effect.withSpan("Sandbox.terminal.interrupt", spanOptions("terminal.interrupt")),
587
+ ),
588
+ terminate: attempt("terminal.terminate", () => terminal.terminate()).pipe(
589
+ Effect.withSpan("Sandbox.terminal.terminate", spanOptions("terminal.terminate")),
590
+ ),
586
591
  connect: Effect.fn(
587
592
  "Sandbox.terminal.connect",
588
593
  spanOptions("terminal.connect"),
@@ -594,9 +599,7 @@ const makeTerminalHandle = (
594
599
  readonly rows?: number;
595
600
  },
596
601
  ) {
597
- return yield* trySandboxPromise(definition, instance, "terminal.connect", () =>
598
- terminal.connect(request, options),
599
- );
602
+ return yield* attempt("terminal.connect", () => terminal.connect(request, options));
600
603
  }),
601
604
  };
602
605
  };
@@ -605,7 +608,20 @@ export const fromSandboxClient = (
605
608
  client: SandboxClientResource,
606
609
  definition: SandboxDefinition,
607
610
  instance: string,
611
+ ): SandboxInstanceClient => makeSandboxClient(client, definition, instance, client);
612
+
613
+ const makeSandboxClient = (
614
+ client: SandboxClientResource,
615
+ definition: SandboxDefinition,
616
+ instance: string,
617
+ target: SandboxClientResource | SandboxNamespaceResource,
608
618
  ): SandboxInstanceClient => {
619
+ const attempt = <A>(operation: string, evaluate: (signal: AbortSignal) => PromiseLike<A>) =>
620
+ trySandboxPromise(definition, instance, operation, evaluate, target);
621
+ const stream = <A>(
622
+ operation: string,
623
+ acquire: (signal: AbortSignal) => PromiseLike<ReadableStream<A>>,
624
+ ) => sandboxStream(definition, instance, operation, acquire, target);
609
625
  const spanOptions = (operation: string) => ({
610
626
  attributes: { binding: definition.binding, instance, operation },
611
627
  });
@@ -616,27 +632,23 @@ export const fromSandboxClient = (
616
632
  "Sandbox.exec",
617
633
  spanOptions("exec"),
618
634
  )(function* (command: SandboxCommand, options?: ExecOptions) {
619
- const process = yield* trySandboxPromise(definition, instance, "exec", () =>
620
- client.exec(command, options),
621
- );
635
+ const process = yield* attempt("exec", () => client.exec(command, options));
622
636
 
623
- return makeProcessHandle(definition, instance, process);
637
+ return makeProcessHandle(definition, instance, process, target);
624
638
  }),
625
639
  getProcess: Effect.fn(
626
640
  "Sandbox.getProcess",
627
641
  spanOptions("getProcess"),
628
642
  )(function* (id: string) {
629
- const process = yield* trySandboxPromise(definition, instance, "getProcess", () =>
630
- client.getProcess(id),
631
- );
643
+ const process = yield* attempt("getProcess", () => client.getProcess(id));
632
644
 
633
645
  return Option.map(Option.fromNullishOr(process), (found) =>
634
- makeProcessHandle(definition, instance, found),
646
+ makeProcessHandle(definition, instance, found, target),
635
647
  );
636
648
  }),
637
- listProcesses: trySandboxPromise(definition, instance, "listProcesses", () =>
638
- client.listProcesses(),
639
- ).pipe(Effect.withSpan("Sandbox.listProcesses", spanOptions("listProcesses"))),
649
+ listProcesses: attempt("listProcesses", () => client.listProcesses()).pipe(
650
+ Effect.withSpan("Sandbox.listProcesses", spanOptions("listProcesses")),
651
+ ),
640
652
  writeFile: Effect.fn(
641
653
  "Sandbox.writeFile",
642
654
  spanOptions("writeFile"),
@@ -647,9 +659,7 @@ export const fromSandboxClient = (
647
659
  ) {
648
660
  yield* Effect.annotateCurrentSpan("path", path);
649
661
 
650
- return yield* trySandboxPromise(definition, instance, "writeFile", () =>
651
- client.writeFile(path, content, options),
652
- );
662
+ return yield* attempt("writeFile", () => client.writeFile(path, content, options));
653
663
  }),
654
664
  readFile: Effect.fn(
655
665
  "Sandbox.readFile",
@@ -657,21 +667,16 @@ export const fromSandboxClient = (
657
667
  )(function* (path: string, options?: { readonly encoding?: ReadFileEncoding }) {
658
668
  yield* Effect.annotateCurrentSpan("path", path);
659
669
 
660
- return yield* trySandboxPromise(definition, instance, "readFile", () =>
661
- client.readFile(path, options),
662
- );
670
+ return yield* attempt("readFile", () => client.readFile(path, options));
663
671
  }),
664
- readFileStream: (path: string) =>
665
- sandboxStream(definition, instance, "readFileStream", () => client.readFileStream(path)),
672
+ readFileStream: (path: string) => stream("readFileStream", () => client.readFileStream(path)),
666
673
  mkdir: Effect.fn(
667
674
  "Sandbox.mkdir",
668
675
  spanOptions("mkdir"),
669
676
  )(function* (path: string, options?: { readonly recursive?: boolean }) {
670
677
  yield* Effect.annotateCurrentSpan("path", path);
671
678
 
672
- return yield* trySandboxPromise(definition, instance, "mkdir", () =>
673
- client.mkdir(path, options),
674
- );
679
+ return yield* attempt("mkdir", () => client.mkdir(path, options));
675
680
  }),
676
681
  deleteFile: Effect.fn(
677
682
  "Sandbox.deleteFile",
@@ -679,9 +684,7 @@ export const fromSandboxClient = (
679
684
  )(function* (path: string) {
680
685
  yield* Effect.annotateCurrentSpan("path", path);
681
686
 
682
- return yield* trySandboxPromise(definition, instance, "deleteFile", () =>
683
- client.deleteFile(path),
684
- );
687
+ return yield* attempt("deleteFile", () => client.deleteFile(path));
685
688
  }),
686
689
  renameFile: Effect.fn(
687
690
  "Sandbox.renameFile",
@@ -689,9 +692,7 @@ export const fromSandboxClient = (
689
692
  )(function* (oldPath: string, newPath: string) {
690
693
  yield* Effect.annotateCurrentSpan({ oldPath, newPath });
691
694
 
692
- return yield* trySandboxPromise(definition, instance, "renameFile", () =>
693
- client.renameFile(oldPath, newPath),
694
- );
695
+ return yield* attempt("renameFile", () => client.renameFile(oldPath, newPath));
695
696
  }),
696
697
  moveFile: Effect.fn(
697
698
  "Sandbox.moveFile",
@@ -699,9 +700,7 @@ export const fromSandboxClient = (
699
700
  )(function* (sourcePath: string, destinationPath: string) {
700
701
  yield* Effect.annotateCurrentSpan({ sourcePath, destinationPath });
701
702
 
702
- return yield* trySandboxPromise(definition, instance, "moveFile", () =>
703
- client.moveFile(sourcePath, destinationPath),
704
- );
703
+ return yield* attempt("moveFile", () => client.moveFile(sourcePath, destinationPath));
705
704
  }),
706
705
  listFiles: Effect.fn(
707
706
  "Sandbox.listFiles",
@@ -709,9 +708,7 @@ export const fromSandboxClient = (
709
708
  )(function* (path: string, options?: ListFilesOptions) {
710
709
  yield* Effect.annotateCurrentSpan("path", path);
711
710
 
712
- return yield* trySandboxPromise(definition, instance, "listFiles", () =>
713
- client.listFiles(path, options),
714
- );
711
+ return yield* attempt("listFiles", () => client.listFiles(path, options));
715
712
  }),
716
713
  exists: Effect.fn(
717
714
  "Sandbox.exists",
@@ -719,11 +716,11 @@ export const fromSandboxClient = (
719
716
  )(function* (path: string) {
720
717
  yield* Effect.annotateCurrentSpan("path", path);
721
718
 
722
- return yield* trySandboxPromise(definition, instance, "exists", () => client.exists(path));
719
+ return yield* attempt("exists", () => client.exists(path));
723
720
  }),
724
721
  watch: (path: string, options?: WatchOptions) =>
725
722
  decodeSseEvents<FileWatchSSEEvent, SandboxOperationError, never>(
726
- sandboxStream(definition, instance, "watch", () => client.watch(path, options)),
723
+ stream("watch", () => client.watch(path, options)),
727
724
  ),
728
725
  checkChanges: Effect.fn(
729
726
  "Sandbox.checkChanges",
@@ -731,17 +728,13 @@ export const fromSandboxClient = (
731
728
  )(function* (path: string, options?: CheckChangesOptions) {
732
729
  yield* Effect.annotateCurrentSpan("path", path);
733
730
 
734
- return yield* trySandboxPromise(definition, instance, "checkChanges", () =>
735
- client.checkChanges(path, options),
736
- );
731
+ return yield* attempt("checkChanges", () => client.checkChanges(path, options));
737
732
  }),
738
733
  setEnvVars: Effect.fn(
739
734
  "Sandbox.setEnvVars",
740
735
  spanOptions("setEnvVars"),
741
736
  )(function* (envVars: Record<string, string | undefined>) {
742
- return yield* trySandboxPromise(definition, instance, "setEnvVars", () =>
743
- client.setEnvVars(envVars),
744
- );
737
+ return yield* attempt("setEnvVars", () => client.setEnvVars(envVars));
745
738
  }),
746
739
  exposePort: Effect.fn(
747
740
  "Sandbox.exposePort",
@@ -749,9 +742,7 @@ export const fromSandboxClient = (
749
742
  )(function* (port: number, options: ExposePortOptions) {
750
743
  yield* Effect.annotateCurrentSpan("port", port);
751
744
 
752
- return yield* trySandboxPromise(definition, instance, "exposePort", () =>
753
- client.exposePort(port, options),
754
- );
745
+ return yield* attempt("exposePort", () => client.exposePort(port, options));
755
746
  }),
756
747
  unexposePort: Effect.fn(
757
748
  "Sandbox.unexposePort",
@@ -759,17 +750,13 @@ export const fromSandboxClient = (
759
750
  )(function* (port: number) {
760
751
  yield* Effect.annotateCurrentSpan("port", port);
761
752
 
762
- return yield* trySandboxPromise(definition, instance, "unexposePort", () =>
763
- client.unexposePort(port),
764
- );
753
+ return yield* attempt("unexposePort", () => client.unexposePort(port));
765
754
  }),
766
755
  getExposedPorts: Effect.fn(
767
756
  "Sandbox.getExposedPorts",
768
757
  spanOptions("getExposedPorts"),
769
758
  )(function* (hostname: string) {
770
- return yield* trySandboxPromise(definition, instance, "getExposedPorts", () =>
771
- client.getExposedPorts(hostname),
772
- );
759
+ return yield* attempt("getExposedPorts", () => client.getExposedPorts(hostname));
773
760
  }),
774
761
  isPortExposed: Effect.fn(
775
762
  "Sandbox.isPortExposed",
@@ -777,9 +764,7 @@ export const fromSandboxClient = (
777
764
  )(function* (port: number) {
778
765
  yield* Effect.annotateCurrentSpan("port", port);
779
766
 
780
- return yield* trySandboxPromise(definition, instance, "isPortExposed", () =>
781
- client.isPortExposed(port),
782
- );
767
+ return yield* attempt("isPortExposed", () => client.isPortExposed(port));
783
768
  }),
784
769
  validatePortToken: Effect.fn(
785
770
  "Sandbox.validatePortToken",
@@ -787,17 +772,13 @@ export const fromSandboxClient = (
787
772
  )(function* (port: number, token: string) {
788
773
  yield* Effect.annotateCurrentSpan("port", port);
789
774
 
790
- return yield* trySandboxPromise(definition, instance, "validatePortToken", () =>
791
- client.validatePortToken(port, token),
792
- );
775
+ return yield* attempt("validatePortToken", () => client.validatePortToken(port, token));
793
776
  }),
794
777
  containerFetch: Effect.fn(
795
778
  "Sandbox.containerFetch",
796
779
  spanOptions("containerFetch"),
797
780
  )(function* (requestOrUrl: Request | string | URL, port?: number) {
798
- return yield* trySandboxPromise(definition, instance, "containerFetch", () =>
799
- client.containerFetch(requestOrUrl, port),
800
- );
781
+ return yield* attempt("containerFetch", () => client.containerFetch(requestOrUrl, port));
801
782
  }),
802
783
  wsConnect: Effect.fn(
803
784
  "Sandbox.wsConnect",
@@ -805,9 +786,7 @@ export const fromSandboxClient = (
805
786
  )(function* (request: Request, port: number) {
806
787
  yield* Effect.annotateCurrentSpan("port", port);
807
788
 
808
- return yield* trySandboxPromise(definition, instance, "wsConnect", () =>
809
- client.wsConnect(request, port),
810
- );
789
+ return yield* attempt("wsConnect", () => client.wsConnect(request, port));
811
790
  }),
812
791
  mountBucket: Effect.fn(
813
792
  "Sandbox.mountBucket",
@@ -815,9 +794,7 @@ export const fromSandboxClient = (
815
794
  )(function* (bucket: string, mountPath: string, options: MountBucketOptions) {
816
795
  yield* Effect.annotateCurrentSpan({ bucket, mountPath });
817
796
 
818
- return yield* trySandboxPromise(definition, instance, "mountBucket", () =>
819
- client.mountBucket(bucket, mountPath, options),
820
- );
797
+ return yield* attempt("mountBucket", () => client.mountBucket(bucket, mountPath, options));
821
798
  }),
822
799
  unmountBucket: Effect.fn(
823
800
  "Sandbox.unmountBucket",
@@ -825,9 +802,7 @@ export const fromSandboxClient = (
825
802
  )(function* (mountPath: string) {
826
803
  yield* Effect.annotateCurrentSpan("mountPath", mountPath);
827
804
 
828
- return yield* trySandboxPromise(definition, instance, "unmountBucket", () =>
829
- client.unmountBucket(mountPath),
830
- );
805
+ return yield* attempt("unmountBucket", () => client.unmountBucket(mountPath));
831
806
  }),
832
807
  createBackup: Effect.fn(
833
808
  "Sandbox.createBackup",
@@ -835,9 +810,7 @@ export const fromSandboxClient = (
835
810
  )(function* (options: BackupOptions) {
836
811
  yield* Effect.annotateCurrentSpan("dir", options.dir);
837
812
 
838
- return yield* trySandboxPromise(definition, instance, "createBackup", () =>
839
- client.createBackup(options),
840
- );
813
+ return yield* attempt("createBackup", () => client.createBackup(options));
841
814
  }),
842
815
  restoreBackup: Effect.fn(
843
816
  "Sandbox.restoreBackup",
@@ -845,37 +818,29 @@ export const fromSandboxClient = (
845
818
  )(function* (backup: DirectoryBackup) {
846
819
  yield* Effect.annotateCurrentSpan({ backupId: backup.id, dir: backup.dir });
847
820
 
848
- return yield* trySandboxPromise(definition, instance, "restoreBackup", () =>
849
- client.restoreBackup(backup),
850
- );
821
+ return yield* attempt("restoreBackup", () => client.restoreBackup(backup));
851
822
  }),
852
823
  createTerminal: Effect.fn(
853
824
  "Sandbox.createTerminal",
854
825
  spanOptions("createTerminal"),
855
826
  )(function* (options: CreateTerminalOptions) {
856
- const terminal = yield* trySandboxPromise(definition, instance, "createTerminal", () =>
857
- client.createTerminal(options),
858
- );
827
+ const terminal = yield* attempt("createTerminal", () => client.createTerminal(options));
859
828
 
860
- return makeTerminalHandle(definition, instance, terminal);
829
+ return makeTerminalHandle(definition, instance, terminal, target);
861
830
  }),
862
831
  getTerminal: Effect.fn(
863
832
  "Sandbox.getTerminal",
864
833
  spanOptions("getTerminal"),
865
834
  )(function* (id: string) {
866
- const terminal = yield* trySandboxPromise(definition, instance, "getTerminal", () =>
867
- client.getTerminal(id),
868
- );
835
+ const terminal = yield* attempt("getTerminal", () => client.getTerminal(id));
869
836
 
870
837
  return Option.map(Option.fromNullishOr(terminal), (found) =>
871
- makeTerminalHandle(definition, instance, found),
838
+ makeTerminalHandle(definition, instance, found, target),
872
839
  );
873
840
  }),
874
- listTerminals: trySandboxPromise(definition, instance, "listTerminals", () =>
875
- client.listTerminals(),
876
- ).pipe(
841
+ listTerminals: attempt("listTerminals", () => client.listTerminals()).pipe(
877
842
  Effect.map((terminals) =>
878
- terminals.map((terminal) => makeTerminalHandle(definition, instance, terminal)),
843
+ terminals.map((terminal) => makeTerminalHandle(definition, instance, terminal, target)),
879
844
  ),
880
845
  Effect.withSpan("Sandbox.listTerminals", spanOptions("listTerminals")),
881
846
  ),
@@ -886,35 +851,31 @@ export const fromSandboxClient = (
886
851
  )(function* (port: number, options?: TunnelOptions) {
887
852
  yield* Effect.annotateCurrentSpan("port", port);
888
853
 
889
- return yield* trySandboxPromise(definition, instance, "tunnels.get", () =>
890
- client.tunnels.get(port, options),
891
- );
854
+ return yield* attempt("tunnels.get", () => client.tunnels.get(port, options));
892
855
  }),
893
- list: trySandboxPromise(definition, instance, "tunnels.list", () =>
894
- client.tunnels.list(),
895
- ).pipe(Effect.withSpan("Sandbox.tunnels.list", spanOptions("tunnels.list"))),
856
+ list: attempt("tunnels.list", () => client.tunnels.list()).pipe(
857
+ Effect.withSpan("Sandbox.tunnels.list", spanOptions("tunnels.list")),
858
+ ),
896
859
  destroy: Effect.fn(
897
860
  "Sandbox.tunnels.destroy",
898
861
  spanOptions("tunnels.destroy"),
899
862
  )(function* (portOrInfo: number | TunnelInfo) {
900
- return yield* trySandboxPromise(definition, instance, "tunnels.destroy", () =>
901
- client.tunnels.destroy(portOrInfo),
902
- );
863
+ return yield* attempt("tunnels.destroy", () => client.tunnels.destroy(portOrInfo));
903
864
  }),
904
865
  },
905
866
  start: Effect.fn(
906
867
  "Sandbox.start",
907
868
  spanOptions("start"),
908
869
  )(function* (options?: ContainerStartOptions) {
909
- return yield* trySandboxPromise(definition, instance, "start", () => client.start(options));
870
+ return yield* attempt("start", () => client.start(options));
910
871
  }),
911
872
  stop: Effect.fn(
912
873
  "Sandbox.stop",
913
874
  spanOptions("stop"),
914
875
  )(function* (signal?: ContainerStopSignal) {
915
- return yield* trySandboxPromise(definition, instance, "stop", () => client.stop(signal));
876
+ return yield* attempt("stop", () => client.stop(signal));
916
877
  }),
917
- destroy: trySandboxPromise(definition, instance, "destroy", () => client.destroy()).pipe(
878
+ destroy: attempt("destroy", () => client.destroy()).pipe(
918
879
  Effect.withSpan("Sandbox.destroy", spanOptions("destroy")),
919
880
  ),
920
881
  };
@@ -958,7 +919,31 @@ export const makeClient =
958
919
  yield* Effect.annotateCurrentSpan("instance", name);
959
920
 
960
921
  const sandboxModule = yield* importSandboxModule(definition, name);
961
- const nativeNamespace: unknown = namespace;
922
+ const targets = yield* Effect.serviceOption(CurrentTargets);
923
+ const scopedNamespace = yield* RpcTargets.get(namespace, "sandbox-namespace", () => {
924
+ const adapter: SandboxNamespaceResource = {
925
+ idFromName: (name) => namespace.idFromName(name),
926
+ get: (id, options) =>
927
+ Option.isSome(targets)
928
+ ? targets.value.get(adapter, JSON.stringify([id.toString(), options]), () =>
929
+ namespace.get(id, options),
930
+ )
931
+ : namespace.get(id, options),
932
+ };
933
+
934
+ return adapter;
935
+ }).pipe(
936
+ Effect.mapError(
937
+ (error) =>
938
+ new SandboxOperationError({
939
+ binding: definition.binding,
940
+ instance: name,
941
+ operation: "get",
942
+ cause: error.cause,
943
+ }),
944
+ ),
945
+ );
946
+ const nativeNamespace: unknown = scopedNamespace;
962
947
  const client = yield* Effect.try({
963
948
  try: () =>
964
949
  sandboxModule.getSandbox(
@@ -979,7 +964,7 @@ export const makeClient =
979
964
  }),
980
965
  });
981
966
 
982
- return fromSandboxClient(client, definition, name);
967
+ return makeSandboxClient(client, definition, name, scopedNamespace);
983
968
  });
984
969
 
985
970
  return {
@@ -0,0 +1,10 @@
1
+ import * as Context from "effect/Context";
2
+
3
+ export interface Targets {
4
+ get<A extends object, Owner extends object>(owner: Owner, address: string, create: () => A): A;
5
+ invalidate<Target extends object>(target: Target): void;
6
+ }
7
+
8
+ export class CurrentTargets extends Context.Service<CurrentTargets, Targets>()(
9
+ "effect-cf/RpcTargets",
10
+ ) {}