apps 0.0.1-beta.22 → 0.0.1-beta.24

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/js/client.js CHANGED
@@ -46,6 +46,7 @@ import {
46
46
  Logger_exports,
47
47
  ManagedRuntime_exports,
48
48
  Option_exports,
49
+ Queue_exports,
49
50
  Schedule_exports,
50
51
  Schema_exports,
51
52
  Semaphore_exports,
@@ -793,6 +794,33 @@ var makeOptimisticClient = (transport) => {
793
794
  };
794
795
 
795
796
  // src/implementation/ui-client.ts
797
+ var resubscribeDelay = Schedule_exports.min([
798
+ Schedule_exports.exponential("1 second"),
799
+ Schedule_exports.spaced("1 minute")
800
+ ]).pipe(Schedule_exports.jittered);
801
+ var appFailure = (error) => Schema_exports.is(UiFailed)(error) && error.reason === "operation_failed";
802
+ var resubscribes = (error) => HttpClientError_exports.isHttpClientError(error) || Cause_exports.isTimeoutError(error) || Schema_exports.is(UiFailed)(error) && error.reason !== "account_required";
803
+ var Retrying = class {
804
+ constructor(error, previous) {
805
+ this.error = error;
806
+ this.previous = previous;
807
+ }
808
+ error;
809
+ previous;
810
+ };
811
+ var visibleResult = (result) => {
812
+ const current = AsyncResult_exports.value(result);
813
+ if (Option_exports.isNone(current) || !(current.value instanceof Retrying)) {
814
+ return result;
815
+ }
816
+ const previous = Option_exports.map(
817
+ Option_exports.fromUndefinedOr(current.value.previous),
818
+ AsyncResult_exports.success
819
+ );
820
+ return AsyncResult_exports.isSuccess(result) ? AsyncResult_exports.failureWithPrevious(Cause_exports.fail(current.value.error), { previous, waiting: true }) : AsyncResult_exports.failureWithPrevious(AsyncResult_exports.isFailure(result) ? result.cause : Cause_exports.empty, {
821
+ previous
822
+ });
823
+ };
796
824
  var createAppClient = () => {
797
825
  const { runtime, atoms } = makeBrowserTelemetry(
798
826
  browserSettings("/_executor/api/telemetry", "executor-app-web")
@@ -847,7 +875,8 @@ var createAppClient = () => {
847
875
  Stream_exports.suspend(() => {
848
876
  let previous;
849
877
  let attempts = 0;
850
- return Stream_exports.unwrap(
878
+ let latest;
879
+ const subscription = Stream_exports.unwrap(
851
880
  Effect_exports.gen(function* () {
852
881
  const attempt = attempts++;
853
882
  const first = yield* pendingSpan("ui.app.first_result", {
@@ -895,53 +924,55 @@ var createAppClient = () => {
895
924
  Stream_exports.timeout("45 seconds"),
896
925
  Stream_exports.concat(Stream_exports.fail(new UiFailed({ reason: "unavailable" }))),
897
926
  Stream_exports.filter((frame) => frame.type !== "heartbeat"),
898
- Stream_exports.mapEffect((frame) => {
899
- if (frame.type === "failure") return Effect_exports.fail(frame.error);
900
- const server = externalTrace(frame.trace);
901
- return Effect_exports.gen(function* () {
902
- const value = yield* Schema_exports.decodeUnknownEffect(decoderOf(output))(
903
- frame.value
904
- ).pipe(Effect_exports.mapError(() => new UiFailed({ reason: "operation_failed" })));
905
- const received = yield* Effect_exports.currentSpan;
906
- const receivedAt = clock.currentTimeMillisUnsafe();
907
- const currentRevision = revision++;
908
- yield* Effect_exports.annotateCurrentSpan({
909
- "executor.operation.name": name,
910
- "executor.snapshot.revision": currentRevision,
911
- "browser.query.elapsed_ms": receivedAt - started,
912
- "executor.trace.context_valid": Option_exports.isSome(server)
913
- });
914
- yield* first.finish(Exit_exports.void);
915
- let committed = false;
916
- return {
917
- value,
918
- commit: () => {
919
- if (committed) return;
920
- committed = true;
921
- const committedAt = clock.currentTimeMillisUnsafe();
922
- runtime.runFork(
923
- Effect_exports.void.pipe(
924
- Effect_exports.withSpan("ui.app.result.commit", {
925
- parent: received,
926
- attributes: {
927
- "executor.operation.name": name,
928
- "executor.snapshot.revision": currentRevision,
929
- "browser.query.elapsed_ms": committedAt - started,
930
- "browser.query.receive_to_commit_ms": committedAt - receivedAt,
931
- "browser.page.hidden": document.visibilityState === "hidden"
932
- }
933
- })
934
- )
935
- );
936
- }
937
- };
938
- }).pipe(
939
- Effect_exports.withSpan("ui.app.result.receive", {
940
- parent: Option_exports.isSome(server) ? server.value : first.span,
941
- kind: "consumer"
942
- })
943
- );
944
- }),
927
+ Stream_exports.mapEffect(
928
+ (frame) => {
929
+ if (frame.type === "failure") return Effect_exports.fail(frame.error);
930
+ const server = externalTrace(frame.trace);
931
+ return Effect_exports.gen(function* () {
932
+ const value = yield* Schema_exports.decodeUnknownEffect(decoderOf(output))(
933
+ frame.value
934
+ ).pipe(Effect_exports.mapError(() => new AppQueryFailed()));
935
+ const received = yield* Effect_exports.currentSpan;
936
+ const receivedAt = clock.currentTimeMillisUnsafe();
937
+ const currentRevision = revision++;
938
+ yield* Effect_exports.annotateCurrentSpan({
939
+ "executor.operation.name": name,
940
+ "executor.snapshot.revision": currentRevision,
941
+ "browser.query.elapsed_ms": receivedAt - started,
942
+ "executor.trace.context_valid": Option_exports.isSome(server)
943
+ });
944
+ yield* first.finish(Exit_exports.void);
945
+ let committed = false;
946
+ return {
947
+ value,
948
+ commit: () => {
949
+ if (committed) return;
950
+ committed = true;
951
+ const committedAt = clock.currentTimeMillisUnsafe();
952
+ runtime.runFork(
953
+ Effect_exports.void.pipe(
954
+ Effect_exports.withSpan("ui.app.result.commit", {
955
+ parent: received,
956
+ attributes: {
957
+ "executor.operation.name": name,
958
+ "executor.snapshot.revision": currentRevision,
959
+ "browser.query.elapsed_ms": committedAt - started,
960
+ "browser.query.receive_to_commit_ms": committedAt - receivedAt,
961
+ "browser.page.hidden": document.visibilityState === "hidden"
962
+ }
963
+ })
964
+ )
965
+ );
966
+ }
967
+ };
968
+ }).pipe(
969
+ Effect_exports.withSpan("ui.app.result.receive", {
970
+ parent: Option_exports.isSome(server) ? server.value : first.span,
971
+ kind: "consumer"
972
+ })
973
+ );
974
+ }
975
+ ),
945
976
  Stream_exports.onExit(finish),
946
977
  Stream_exports.provideService(Tracer_exports.ParentSpan, first.span)
947
978
  );
@@ -952,16 +983,35 @@ var createAppClient = () => {
952
983
  Stream_exports.catch(
953
984
  (error) => Schema_exports.is(UiDeploymentChanged)(error) ? Stream_exports.unwrap(deploymentChanged.pipe(Effect_exports.as(Stream_exports.never))) : Stream_exports.fail(error)
954
985
  ),
955
- Stream_exports.retry(
956
- Schedule_exports.spaced("1 second").pipe(
957
- Schedule_exports.while(
958
- ({ input: input2 }) => HttpClientError_exports.isHttpClientError(input2) || Cause_exports.isTimeoutError(input2) || Schema_exports.is(UiFailed)(input2)
959
- )
960
- )
986
+ Stream_exports.tap(
987
+ (value) => Effect_exports.sync(() => {
988
+ latest = value;
989
+ })
961
990
  )
962
991
  );
992
+ return Stream_exports.unwrap(
993
+ Effect_exports.gen(function* () {
994
+ const retrying = yield* Queue_exports.unbounded();
995
+ return Stream_exports.merge(
996
+ subscription.pipe(
997
+ Stream_exports.retry(
998
+ resubscribeDelay.pipe(
999
+ Schedule_exports.while(
1000
+ ({ input: input2 }) => !resubscribes(input2) ? false : appFailure(input2) ? Queue_exports.offer(retrying, new Retrying(input2, latest)).pipe(
1001
+ Effect_exports.as(true)
1002
+ ) : true
1003
+ )
1004
+ )
1005
+ )
1006
+ ),
1007
+ // Shown outside the retried stream, so they do not reset its delay.
1008
+ Stream_exports.fromQueue(retrying),
1009
+ { haltStrategy: "left" }
1010
+ );
1011
+ })
1012
+ );
963
1013
  })
964
- ).pipe(Atom_exports.map(queryResult));
1014
+ ).pipe(Atom_exports.map((result) => queryResult(visibleResult(result))));
965
1015
  const optimistic = makeOptimisticClient({
966
1016
  source,
967
1017
  read: (name, input, output) => request("query", name, input, output),