EdgeAIG's picture
download
raw
4.42 kB
/**
* Connects typed `HttpApi` clients to atoms.
*
* The service created here exposes the generated HTTP API client plus
* atom-based query and mutation helpers. Query atoms call endpoints and track
* their asynchronous result, while mutations run endpoint calls that can
* invalidate reactivity keys after a successful request. Query atoms can also be
* cached, serialized for hydration, and kept alive with a time-to-live.
*
* @since 4.0.0
*/
import * as Context from "../../Context.js";
import * as Duration from "../../Duration.js";
import * as Effect from "../../Effect.js";
import * as Layer from "../../Layer.js";
import * as Schema from "../../Schema.js";
import * as HttpClientError from "../http/HttpClientError.js";
import * as HttpApiClient from "../httpapi/HttpApiClient.js";
import * as HttpApiEndpoint from "../httpapi/HttpApiEndpoint.js";
import * as AsyncResult from "./AsyncResult.js";
import * as Atom from "./Atom.js";
import * as Reactivity from "./Reactivity.js";
/**
* Creates a `Context.Service` class for an HTTP API client backed by an atom
* runtime.
*
* **Details**
*
* The options provide the API definition, HTTP client layer, optional client and
* response transforms, base URL, and runtime factory used by the query and
* mutation helpers.
*
* @category constructors
* @since 4.0.0
*/
export const Service = () => (id, options) => {
const self = Context.Service()(id);
const layer = Layer.effect(self, HttpApiClient.make(options.api, options));
const runtimeFactory = options.runtime ?? Atom.runtime;
self.runtime = runtimeFactory(typeof options.httpClient === "function" ? get => Layer.provide(layer, options.httpClient(get)) : Layer.provide(layer, options.httpClient));
const catchErrors = Effect.catch(e => Schema.isSchemaError(e) || HttpClientError.isHttpClientError(e) ? Effect.die(e) : Effect.fail(e));
const mutationFamily = Atom.family(({
endpoint,
group,
responseMode
}) => {
const atom = self.runtime.fn()(Effect.fnUntraced(function* (opts) {
const client = yield* self;
const effect = catchErrors(client[group][endpoint]({
...opts,
responseMode
}));
return yield* opts.reactivityKeys ? Reactivity.mutation(effect, opts.reactivityKeys) : effect;
}));
if (responseMode === "decoded-only") {
const definition = options.api.groups[group].endpoints[endpoint];
return Atom.serializable(atom, {
key: `AtomHttpApi:mutation:${group}:${endpoint}`,
schema: AsyncResult.Schema({
success: Schema.Union(HttpApiEndpoint.getSuccessSchemas(definition)),
error: Schema.Union(HttpApiEndpoint.getErrorSchemas(definition))
})
});
}
return atom;
});
self.mutation = (group, endpoint, options) => mutationFamily({
group,
endpoint,
responseMode: options?.responseMode ?? "decoded-only"
});
const queryFamily = Atom.family(opts => {
let atom = self.runtime.atom(self.use(client_ => {
const client = client_;
return catchErrors(client[opts.group][opts.endpoint](opts));
}));
if (opts.responseMode === "decoded-only" && opts.serializationKey) {
const endpoint = options.api.groups[opts.group].endpoints[opts.endpoint];
atom = Atom.serializable(atom, {
key: `AtomHttpApi:${opts.group}:${opts.endpoint}:${opts.serializationKey}`,
schema: AsyncResult.Schema({
success: Schema.Union(HttpApiEndpoint.getSuccessSchemas(endpoint)),
error: Schema.Union(HttpApiEndpoint.getErrorSchemas(endpoint))
})
});
}
if (opts.timeToLive) {
atom = Duration.isFinite(opts.timeToLive) ? Atom.setIdleTTL(atom, opts.timeToLive) : Atom.keepAlive(atom);
}
return opts.reactivityKeys ? self.runtime.factory.withReactivity(opts.reactivityKeys)(atom) : atom;
});
self.query = (group, endpoint, request) => {
const key = {
group,
endpoint,
params: request.params,
query: request.query,
payload: request.payload,
headers: request.headers,
responseMode: request.responseMode ?? "decoded-only",
reactivityKeys: request.reactivityKeys,
timeToLive: request.timeToLive ? Duration.fromInputUnsafe(request.timeToLive) : undefined,
serializationKey: request.serializationKey
};
return queryFamily(key);
};
return self;
};
//# sourceMappingURL=AtomHttpApi.js.map

Xet Storage Details

Size:
4.42 kB
·
Xet hash:
1d5c7cac977ede77a86c6d9e77dcbf291326878d55f77c33aaa5e22e8549e1cb

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.