@effect-agent/platform-cloudflare 0.1.0-beta.120 → 0.1.0-beta.122

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.
@@ -1,7 +1,7 @@
1
- import { C as reportBrowserCause, S as inheritBrowserReport, b as BrowserRunFailure, c as BrowserRunLiveViewResult, r as BrowserRunHandoffState, s as BrowserRunLiveViewRequest, t as BrowserRunHandoffRequest, v as BrowserRunSessionLifecycle, w as reportedBrowserError, x as browserFailure, y as BrowserRunBinding } from "./InteractiveBrowser-CBUFAECo.mjs";
1
+ import { C as reportBrowserCause, S as inheritBrowserReport, b as BrowserRunFailure, c as BrowserRunLiveViewResult, r as BrowserRunHandoffState, s as BrowserRunLiveViewRequest, t as BrowserRunHandoffRequest, v as BrowserRunSessionLifecycle, w as reportedBrowserError, x as browserFailure, y as BrowserRunBinding } from "./InteractiveBrowser-DXwmvWdA.mjs";
2
2
  import { Cause, Clock, Context, Crypto, Effect, Layer, Redacted, Schema, Semaphore } from "effect";
3
- import "@cloudflare/puppeteer";
4
3
  import { InteractiveBrowserPolicy } from "effect-agent/interactive-browser";
4
+ import "puppeteer-core/lib/esm/puppeteer/puppeteer-core-browser.js";
5
5
  import { BrowserCredentialAccess, CardCredential, CredentialObservationDecision, CredentialOffer, CredentialOfferMetadata, CredentialOrigin, CredentialTarget, CredentialUseResult, ListCredentialOffers, LoginCredential, ProtectedBrowser, ProtectedBrowserCheckpoint, ProtectedBrowserClick, ProtectedBrowserControl, ProtectedBrowserError, ProtectedBrowserFill, ProtectedBrowserNavigate, ProtectedBrowserObservation, UseCredential } from "effect-agent/protected-browser";
6
6
  //#region src/protected-browser/policy.ts
7
7
  var ProtectedTransportError = class extends Schema.TaggedError()("ProtectedTransportError", { reason: Schema.Literals([
@@ -885,169 +885,209 @@ const protectedBindingLayer = (options) => Layer.effect(BrowserRunProtectedBindi
885
885
  const lifecycle = yield* BrowserRunSessionLifecycle;
886
886
  const binding = yield* BrowserRunBinding;
887
887
  const crypto = yield* Crypto.Crypto;
888
- return { open: Effect.fn("BrowserRunProtectedTransport.open")(function* (policy, identity) {
889
- const failure = () => new ProtectedBrowserError({
890
- reason: "provider",
891
- dispatch: "not-dispatched",
892
- milestone: "none",
893
- observation: "closed",
894
- cleanup: "unconfirmed"
895
- });
896
- let sessionId = identity?.sessionId;
897
- let detached = false;
898
- let control;
899
- let providerIdentity;
900
- let browser;
901
- let driver;
902
- let invalid = false;
903
- const runCleanup = Effect.runPromiseWith(yield* Effect.context());
904
- const terminate = Effect.gen(function* () {
905
- invalid = true;
906
- driver?.invalidate();
907
- if (sessionId === void 0) return "unconfirmed";
908
- const cleanup = yield* lifecycle.close(sessionId).pipe(Effect.as("confirmed"), Effect.catchCause((cause) => reportBrowserCause("protected.close", cause).pipe(Effect.as("unconfirmed"))), Effect.interruptible, Effect.timeoutOrElse({
909
- duration: "10 seconds",
910
- orElse: () => reportBrowserCause("protected.close", Cause.fail(new BrowserRunFailure({
911
- operation: "protected.close",
912
- reason: "timeout"
913
- }))).pipe(Effect.as("unconfirmed"))
914
- }));
915
- const connected = browser;
916
- if (connected !== void 0) yield* Effect.promise(() => connected.disconnect()).pipe(Effect.catchCause((cause) => reportBrowserCause("protected.disconnect", cause)), Effect.interruptible, Effect.timeoutOrElse({
917
- duration: "1 second",
918
- orElse: () => reportBrowserCause("protected.disconnect", Cause.fail(new BrowserRunFailure({
919
- operation: "protected.disconnect",
920
- reason: "timeout"
921
- })))
922
- }));
923
- return cleanup;
924
- });
925
- const close = yield* Effect.cached(terminate);
926
- yield* Effect.addFinalizer(() => detached ? Effect.void : close);
927
- let stage = identity === void 0 ? "protected.acquire" : "protected.connect";
928
- const acquired = yield* Effect.tryPromise({
929
- try: async (signal) => {
930
- try {
931
- sessionId = identity === void 0 ? Redacted.make(await binding.acquire(Math.min(6e5, Math.max(1e4, policy.maxElapsedMillis)), "protected.acquire")) : identity.sessionId;
932
- if (signal.aborted || invalid) {
933
- await runCleanup(terminate);
934
- throw new ProtectedTransportError({ reason: "stale-reference" });
935
- }
936
- stage = "protected.connect";
937
- browser = await binding.connect(Redacted.value(sessionId), stage);
938
- if (signal.aborted || invalid) {
939
- await runCleanup(terminate);
940
- throw new ProtectedTransportError({ reason: "stale-reference" });
941
- }
942
- let page;
943
- if (identity === void 0) {
944
- stage = "protected.context";
945
- const context = await browser.createBrowserContext();
946
- stage = "protected.page";
947
- page = await context.newPage();
948
- } else {
949
- stage = "protected.resume";
950
- const context = browser.browserContexts().find((candidate) => candidate.id === Redacted.value(identity.contextId));
951
- if (context === void 0) throw new ProtectedTransportError({ reason: "stale-reference" });
952
- const pages = await context.pages();
953
- let found;
954
- for (const candidate of pages) {
955
- const client = await candidate.createCDPSession();
956
- const info = await client.send("Target.getTargetInfo");
957
- await client.detach();
958
- if (info.targetInfo.targetId === Redacted.value(identity.targetId)) found = candidate;
888
+ return {
889
+ open: Effect.fn("BrowserRunProtectedTransport.open")(function* (policy, identity) {
890
+ const failure = () => new ProtectedBrowserError({
891
+ reason: "provider",
892
+ dispatch: "not-dispatched",
893
+ milestone: "none",
894
+ observation: "closed",
895
+ cleanup: "unconfirmed"
896
+ });
897
+ let sessionId = identity?.sessionId;
898
+ let detached = false;
899
+ let control;
900
+ let providerIdentity;
901
+ let browser;
902
+ let attachment;
903
+ let driver;
904
+ let invalid = false;
905
+ const runCleanup = Effect.runPromiseWith(yield* Effect.context());
906
+ const terminate = Effect.gen(function* () {
907
+ invalid = true;
908
+ driver?.invalidate();
909
+ if (sessionId === void 0) return "unconfirmed";
910
+ if (identity !== void 0 && driver === void 0) {
911
+ if (attachment !== void 0) yield* attachment.retire.pipe(Effect.interruptible, Effect.timeoutOrElse({
912
+ duration: "1 second",
913
+ orElse: () => Effect.fail(new BrowserRunFailure({
914
+ operation: "protected.disconnect",
915
+ reason: "timeout"
916
+ }))
917
+ }), Effect.catch((error) => reportBrowserCause("protected.disconnect", Cause.fail(error)).pipe(Effect.andThen(() => Effect.die(reportedBrowserError(error))))));
918
+ return "unconfirmed";
919
+ }
920
+ const cleanup = yield* lifecycle.close(sessionId).pipe(Effect.as("confirmed"), Effect.catchCause((cause) => reportBrowserCause("protected.close", cause).pipe(Effect.as("unconfirmed"))), Effect.interruptible, Effect.timeoutOrElse({
921
+ duration: "10 seconds",
922
+ orElse: () => reportBrowserCause("protected.close", Cause.fail(new BrowserRunFailure({
923
+ operation: "protected.close",
924
+ reason: "timeout"
925
+ }))).pipe(Effect.as("unconfirmed"))
926
+ }));
927
+ const connected = browser;
928
+ if (connected !== void 0) yield* Effect.promise(() => connected.disconnect()).pipe(Effect.catchCause((cause) => reportBrowserCause("protected.disconnect", cause)), Effect.interruptible, Effect.timeoutOrElse({
929
+ duration: "1 second",
930
+ orElse: () => reportBrowserCause("protected.disconnect", Cause.fail(new BrowserRunFailure({
931
+ operation: "protected.disconnect",
932
+ reason: "timeout"
933
+ })))
934
+ }));
935
+ return cleanup;
936
+ });
937
+ const close = yield* Effect.cached(terminate);
938
+ yield* Effect.addFinalizer(() => detached ? Effect.void : close);
939
+ let stage = identity === void 0 ? "protected.acquire" : "protected.connect";
940
+ const acquired = yield* Effect.tryPromise({
941
+ try: async (signal) => {
942
+ try {
943
+ sessionId = identity === void 0 ? Redacted.make(await binding.acquire(Math.min(6e5, Math.max(1e4, policy.maxElapsedMillis)), "protected.acquire")) : identity.sessionId;
944
+ if (signal.aborted || invalid) {
945
+ await runCleanup(terminate);
946
+ throw new ProtectedTransportError({ reason: "stale-reference" });
959
947
  }
960
- if (found === void 0 || pages.length !== 1) throw new ProtectedTransportError({ reason: "stale-reference" });
961
- page = found;
962
- }
963
- stage = "protected.control";
964
- control = await page.createCDPSession();
965
- const info = await control.send("Target.getTargetInfo");
966
- stage = "protected.identity";
967
- providerIdentity = Schema.decodeSync(ProtectedProviderIdentity)({
968
- sessionId,
969
- contextId: Redacted.make(page.browserContext().id ?? ""),
970
- targetId: Redacted.make(info.targetInfo.targetId)
971
- });
972
- stage = "protected.interception";
973
- await page.setBypassServiceWorker(true);
974
- await page.setRequestInterception(true);
975
- page.on("request", (request) => {
976
- let allowed = policy.network._tag === "Unrestricted";
977
- try {
978
- const url = new URL(request.url());
979
- allowed ||= policy.network._tag === "ExactHosts" && url.protocol === "https:" && !url.username && !url.password && policy.network.allowedHosts.includes(url.host);
980
- } catch {}
981
- (allowed && !invalid ? request.continue() : request.abort("blockedbyclient")).catch(async (cause) => {
982
- invalid = true;
983
- driver?.invalidate();
984
- await runCleanup(reportBrowserCause("protected.interception", Cause.fail(cause)));
948
+ stage = "protected.connect";
949
+ attachment = binding.connect(Redacted.value(sessionId), stage, signal);
950
+ browser = await attachment.browser;
951
+ if (signal.aborted || invalid) {
952
+ await runCleanup(terminate);
953
+ throw new ProtectedTransportError({ reason: "stale-reference" });
954
+ }
955
+ let page;
956
+ if (identity === void 0) {
957
+ stage = "protected.context";
958
+ const context = await browser.createBrowserContext();
959
+ stage = "protected.page";
960
+ page = await context.newPage();
961
+ } else {
962
+ stage = "protected.resume";
963
+ const context = browser.browserContexts().find((candidate) => candidate.id === Redacted.value(identity.contextId));
964
+ if (context === void 0) throw new ProtectedTransportError({ reason: "stale-reference" });
965
+ const pages = await context.pages();
966
+ let found;
967
+ for (const candidate of pages) {
968
+ const client = await candidate.createCDPSession();
969
+ const info = await client.send("Target.getTargetInfo");
970
+ await client.detach();
971
+ if (info.targetInfo.targetId === Redacted.value(identity.targetId)) found = candidate;
972
+ }
973
+ if (found === void 0 || pages.length !== 1) throw new ProtectedTransportError({ reason: "stale-reference" });
974
+ page = found;
975
+ }
976
+ stage = "protected.control";
977
+ control = await page.createCDPSession();
978
+ const info = await control.send("Target.getTargetInfo");
979
+ stage = "protected.identity";
980
+ providerIdentity = Schema.decodeSync(ProtectedProviderIdentity)({
981
+ sessionId,
982
+ contextId: Redacted.make(page.browserContext().id ?? ""),
983
+ targetId: Redacted.make(info.targetInfo.targetId)
985
984
  });
986
- });
987
- if (signal.aborted || invalid) {
988
- await runCleanup(terminate);
989
- throw new ProtectedTransportError({ reason: "stale-reference" });
985
+ if (policy.network._tag !== "Unrestricted") {
986
+ stage = "protected.interception";
987
+ await page.setBypassServiceWorker(true);
988
+ await page.setRequestInterception(true);
989
+ page.on("request", (request) => {
990
+ let allowed = false;
991
+ try {
992
+ const url = new URL(request.url());
993
+ allowed = policy.network._tag === "ExactHosts" && url.protocol === "https:" && !url.username && !url.password && policy.network.allowedHosts.includes(url.host);
994
+ } catch {}
995
+ (allowed && !invalid ? request.continue() : request.abort("blockedbyclient")).catch(async (cause) => {
996
+ invalid = true;
997
+ driver?.invalidate();
998
+ await runCleanup(reportBrowserCause("protected.interception", Cause.fail(cause)));
999
+ });
1000
+ });
1001
+ }
1002
+ if (signal.aborted || invalid) {
1003
+ await runCleanup(terminate);
1004
+ throw new ProtectedTransportError({ reason: "stale-reference" });
1005
+ }
1006
+ return ProtectedNativeSession.of({
1007
+ browser,
1008
+ page,
1009
+ close,
1010
+ release: Effect.suspend(() => detached ? Effect.void : close.pipe(Effect.asVoid))
1011
+ });
1012
+ } catch (cause) {
1013
+ if (signal.aborted && !(cause instanceof ProtectedTransportError)) await runCleanup(reportBrowserCause(stage, Cause.fail(cause)));
1014
+ throw cause;
990
1015
  }
991
- return ProtectedNativeSession.of({
992
- browser,
993
- page,
994
- close,
995
- release: Effect.suspend(() => detached ? Effect.void : close.pipe(Effect.asVoid))
996
- });
997
- } catch (cause) {
998
- if (signal.aborted && !(cause instanceof ProtectedTransportError)) await runCleanup(reportBrowserCause(stage, Cause.fail(cause)));
999
- throw cause;
1000
- }
1001
- },
1002
- catch: (cause) => browserFailure(stage, cause)
1003
- }).pipe(Effect.timeoutOrElse({
1004
- duration: Math.min(policy.maxElapsedMillis, 3e4),
1005
- orElse: () => Effect.fail(new BrowserRunFailure({
1006
- operation: stage,
1007
- reason: "timeout"
1008
- }))
1009
- }), Effect.catch((error) => reportBrowserCause(stage, Cause.fail(error)).pipe(Effect.andThen(close), Effect.flatMap((cleanup) => Effect.fail(reportedBrowserError(new ProtectedBrowserError({
1010
- ...failure(),
1011
- reason: error.reason === "timeout" ? "timeout" : "provider",
1012
- cleanup
1013
- })))))));
1014
- driver = yield* makeProtectedNativeTransport(policy).pipe(Effect.provideService(ProtectedNativeSession, acquired), Effect.provideService(Crypto.Crypto, crypto));
1015
- const exact = providerIdentity;
1016
- if (exact === void 0) return yield* failure();
1017
- return {
1018
- identity: exact,
1019
- driver,
1020
- command: (method, parameters) => Effect.tryPromise({
1021
- try: async () => {
1022
- if (invalid || detached || control === void 0) throw void 0;
1023
- const send = Reflect.get(control, "send");
1024
- return await Reflect.apply(send, control, [method, parameters]);
1025
1016
  },
1026
- catch: (cause) => browserFailure("protected.command", cause)
1017
+ catch: (cause) => browserFailure(stage, cause)
1027
1018
  }).pipe(Effect.timeoutOrElse({
1028
- duration: "10 seconds",
1019
+ duration: Math.min(policy.maxElapsedMillis, 3e4),
1029
1020
  orElse: () => Effect.fail(new BrowserRunFailure({
1030
- operation: "protected.command",
1021
+ operation: stage,
1031
1022
  reason: "timeout"
1032
1023
  }))
1033
- }), Effect.catch((error) => reportBrowserCause("protected.command", Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(failure())))))),
1034
- detach: Effect.tryPromise({
1035
- try: async () => {
1036
- if (invalid || detached || browser === void 0) throw void 0;
1037
- await browser.disconnect();
1038
- detached = true;
1039
- driver?.invalidate();
1040
- },
1041
- catch: (cause) => browserFailure("protected.detach", cause)
1042
- }).pipe(Effect.timeoutOrElse({
1024
+ }), Effect.catch((error) => {
1025
+ if (identity !== void 0 && driver === void 0) return reportBrowserCause(stage, Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(new ProtectedBrowserError({
1026
+ ...failure(),
1027
+ reason: error.reason === "timeout" ? "timeout" : "provider",
1028
+ cleanup: "not-requested"
1029
+ })))), Effect.ensuring(close));
1030
+ return reportBrowserCause(stage, Cause.fail(error)).pipe(Effect.andThen(close), Effect.flatMap((cleanup) => Effect.fail(reportedBrowserError(new ProtectedBrowserError({
1031
+ ...failure(),
1032
+ reason: error.reason === "timeout" ? "timeout" : "provider",
1033
+ cleanup
1034
+ })))));
1035
+ }));
1036
+ driver = yield* makeProtectedNativeTransport(policy).pipe(Effect.provideService(ProtectedNativeSession, acquired), Effect.provideService(Crypto.Crypto, crypto));
1037
+ const exact = providerIdentity;
1038
+ if (exact === void 0) return yield* failure();
1039
+ return {
1040
+ identity: exact,
1041
+ driver,
1042
+ command: (method, parameters) => Effect.tryPromise({
1043
+ try: async () => {
1044
+ if (invalid || detached || control === void 0) throw void 0;
1045
+ const send = Reflect.get(control, "send");
1046
+ return await Reflect.apply(send, control, [method, parameters]);
1047
+ },
1048
+ catch: (cause) => browserFailure("protected.command", cause)
1049
+ }).pipe(Effect.timeoutOrElse({
1050
+ duration: "10 seconds",
1051
+ orElse: () => Effect.fail(new BrowserRunFailure({
1052
+ operation: "protected.command",
1053
+ reason: "timeout"
1054
+ }))
1055
+ }), Effect.catch((error) => reportBrowserCause("protected.command", Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(failure())))))),
1056
+ detach: Effect.tryPromise({
1057
+ try: async () => {
1058
+ if (invalid || detached || browser === void 0) throw void 0;
1059
+ await browser.disconnect();
1060
+ detached = true;
1061
+ driver?.invalidate();
1062
+ },
1063
+ catch: (cause) => browserFailure("protected.detach", cause)
1064
+ }).pipe(Effect.timeoutOrElse({
1065
+ duration: "10 seconds",
1066
+ orElse: () => Effect.fail(new BrowserRunFailure({
1067
+ operation: "protected.detach",
1068
+ reason: "timeout"
1069
+ }))
1070
+ }), Effect.catch((error) => reportBrowserCause("protected.detach", Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(failure()))))))
1071
+ };
1072
+ }, Effect.withTracerEnabled(false)),
1073
+ keepAlive: Effect.fn("BrowserRunProtectedBinding.keepAlive")(function* (sessionId) {
1074
+ const failure = (reason) => new ProtectedBrowserError({
1075
+ reason,
1076
+ dispatch: "not-dispatched",
1077
+ milestone: "none",
1078
+ observation: "protected",
1079
+ cleanup: "not-requested"
1080
+ });
1081
+ const id = yield* Schema.decodeEffect(ProtectedProviderIdentity.fields.sessionId)(sessionId).pipe(Effect.mapError(() => failure("denied")));
1082
+ yield* binding.keepAlive(Redacted.value(id)).pipe(Effect.timeoutOrElse({
1043
1083
  duration: "10 seconds",
1044
1084
  orElse: () => Effect.fail(new BrowserRunFailure({
1045
- operation: "protected.detach",
1085
+ operation: "protected.keepAlive",
1046
1086
  reason: "timeout"
1047
1087
  }))
1048
- }), Effect.catch((error) => reportBrowserCause("protected.detach", Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(failure()))))))
1049
- };
1050
- }, Effect.withTracerEnabled(false)) };
1088
+ }), Effect.tapError((error) => reportBrowserCause("protected.keepAlive", Cause.fail(error))), Effect.mapError((error) => reportedBrowserError(failure(error.reason === "timeout" ? "timeout" : "provider"))));
1089
+ }, Effect.withTracerEnabled(false))
1090
+ };
1051
1091
  })).pipe(Layer.provide(BrowserRunBinding.layer(options.browser)));
1052
1092
  /** One binding implementation serves scoped tools and host-managed protected handoffs. */
1053
1093
  const browserRunProtectedBindingLayer = (options) => Layer.effect(BrowserRunProtectedTransport)(Effect.gen(function* () {
@@ -1190,6 +1230,7 @@ const browserRunProtectedHostLayer = () => Layer.effect(BrowserRunProtectedHost)
1190
1230
  };
1191
1231
  }, Effect.withTracerEnabled(false));
1192
1232
  return {
1233
+ keepAlive: binding.keepAlive,
1193
1234
  open: (policy) => open(policy),
1194
1235
  resume: (checkpoint) => Schema.decodeEffect(BrowserRunProtectedCheckpoint)(checkpoint).pipe(Effect.mapError(() => failure("denied")), Effect.flatMap((decoded) => open(decoded.protected.policy, decoded))),
1195
1236
  closeSession: (id) => lifecycle.close(id).pipe(Effect.as("confirmed"), Effect.catchCause((cause) => reportBrowserCause("protected.closeSession", cause).pipe(Effect.as("unconfirmed"))))