(
rt: AtomClientRuntime,
self: {
readonly id: string
readonly handler: (i: I) => Stream.Stream<A, E, any>
readonly options?: ClientForOptions
readonly queryKeyProjectionHash?: string
}
)
| 493 | const recordReads = Effect |
| 494 | .gen(function*() { |
| 495 | const readsRef = yield* Ref.make(DataDependencies.empty()) |
| 496 | const writesRef = yield* Ref.make(DataDependencies.empty()) |
| 497 | const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef) |
| 498 | const result = yield* self |
| 499 | .handler(input) |
| 500 | .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder)) |
| 501 | lastReads = yield* Ref.get(readsRef) |
| 502 | setQueryReadDependencies(fullKey, lastReads) |
| 503 | return result |
| 504 | }) |
| 505 | let liveFetch = false |
| 506 | const effect = Effect |
| 507 | .gen(function*() { |
| 508 | liveFetch = yield* Effect.promise(() => beginLiveQueryFetch(fullKey)) |
| 509 | return yield* recordReads.pipe(Effect.retry({ times: 5, while: isRetryable })) |
| 510 | }) |
| 511 | .pipe( |
| 512 | Effect.ensuring(Effect.sync(() => endLiveQueryFetch(liveFetch))), |
| 513 | Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause)), |
| 514 | // On exit, the compute is no longer in-flight. An interrupt (subscriber lost interest / a |
| 515 | // superseding refresh) may leave the result at `waiting`; with `inFlight` back at 0 that |
| 516 | // reads as "stuck", so the next mount recovers it (`recoverStuckWaitingOnMount`). We do not |
| 517 | // re-fire here — the interrupt was intentional; recovery is driven by a genuine (re)mount. |
| 518 | Effect.onExit(() => |
| 519 | Effect.sync(() => { |
| 520 | fetchState.inFlight = Math.max(0, fetchState.inFlight - 1) |
| 521 | }) |
| 522 | ), |
| 523 | Effect.withSpan(`query ${self.id}`, {}, { captureStackTrace: false }) |
| 524 | ) |
| 525 | const parentSpan = takeAtomQueryParentSpan(atom) |
no test coverage detected
searching dependent graphs…