@effect-ts/system
Version:
Effect-TS is a zero dependency set of libraries to write highly productive, purely functional TypeScript at scale.
636 lines (494 loc) • 16.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MemoMap = exports.LayerZipWithSeq = exports.LayerZipWithPar = exports.LayerSuspend = exports.LayerMap = exports.LayerManaged = exports.LayerFresh = exports.LayerFold = exports.LayerChain = exports.LayerAllSeq = exports.LayerAllPar = exports.Layer = exports.Empty = void 0;
exports.and = and;
exports.and_ = and_;
exports.build = build;
exports.compose = compose;
exports.compose_ = compose_;
exports.fold = fold;
exports.fromRawEffect = fromRawEffect;
exports.fromRawFunction = fromRawFunction;
exports.fromRawFunctionM = fromRawFunctionM;
exports.fromRawManaged = fromRawManaged;
exports.hashSym = void 0;
exports.identity = identity;
exports.makeMemoMap = makeMemoMap;
exports.provideLayer = provideLayer;
exports.provideLayer_ = provideLayer_;
exports.provideSomeLayer = provideSomeLayer;
exports.provideSomeLayer_ = provideSomeLayer_;
exports.scope = scope;
exports.using = using;
exports.usingAnd = usingAnd;
var _reduce = /*#__PURE__*/require("../Collections/Immutable/Chunk/api/reduce.js");
var _index = /*#__PURE__*/require("../Collections/Immutable/Map/index.js");
var Tp = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Collections/Immutable/Tuple/index.js"));
var _commons = /*#__PURE__*/require("../Effect/commons.js");
var _ExecutionStrategy = /*#__PURE__*/require("../Effect/ExecutionStrategy.js");
var _index3 = /*#__PURE__*/require("../Function/index.js");
var _core = /*#__PURE__*/require("../Managed/core.js");
var _do = /*#__PURE__*/require("../Managed/do.js");
var _forEach = /*#__PURE__*/require("../Managed/forEach.js");
var _fromEffect = /*#__PURE__*/require("../Managed/fromEffect.js");
var _managed = /*#__PURE__*/require("../Managed/managed.js");
var _environment = /*#__PURE__*/require("../Managed/methods/environment.js");
var add = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Managed/ReleaseMap/add.js"));
var Finalizer = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Managed/ReleaseMap/finalizer.js"));
var makeReleaseMap = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Managed/ReleaseMap/makeReleaseMap.js"));
var releaseAll = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Managed/ReleaseMap/releaseAll.js"));
var _succeed = /*#__PURE__*/require("../Managed/succeed.js");
var _use = /*#__PURE__*/require("../Managed/use.js");
var _await = /*#__PURE__*/require("../Promise/await.js");
var _halt = /*#__PURE__*/require("../Promise/halt.js");
var _make = /*#__PURE__*/require("../Promise/make.js");
var _succeed2 = /*#__PURE__*/require("../Promise/succeed.js");
var R = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Ref/index.js"));
var RM = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../RefM/index.js"));
var _index6 = /*#__PURE__*/require("../Support/AtomicReference/index.js");
var T = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./deps-effect.js"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var _a;
/**
* Creates a layer from an effect
*/
function fromRawEffect(resource) {
return new LayerManaged((0, _fromEffect.fromEffect)(resource));
}
/**
* Creates a layer from a function
*/
function fromRawFunction(f) {
return fromRawEffect(T.access(f));
}
/**
* Creates a layer from an effectful function
*/
function fromRawFunctionM(f) {
return fromRawEffect(T.accessM(f));
}
/**
* Creates a layer from a managed environment
*/
function fromRawManaged(resource) {
return new LayerManaged(resource);
}
/**
* Constructs a layer that passes along the specified environment as an
* output.
*/
function identity() {
return fromRawManaged((0, _environment.environment)());
}
/**
* Merge two Layers in parallel without providing any data to each other
*
* @param self - first Layer to combine
* @param that - second Layer to combine
*/
function and_(self, that) {
return new LayerZipWithPar(self, that, (l, r) => ({ ...l,
...r
}));
}
/**
* Merge two Layers in parallel without providing any data to each other
*
* @param that - second Layer to combine
* @param self - first Layer to combine
*/
function and(that) {
return self => new LayerZipWithPar(self, that, (l, r) => ({ ...l,
...r
}));
}
/**
* Feeds the error or output services of this layer into the input of either
* the specified `failure` or `success` layers, resulting in a new layer with
* the inputs of this layer, and the error or outputs of the specified layer.
*/
function fold(self) {
return failure => success => new LayerFold(self, failure, success);
}
/**
* Use `from` to partially provide environment into `to`
*/
function using(from) {
return to => compose_(from["+++"](identity()), to);
}
/**
* Use `from` to partially provide environment into `to` and merge both
*/
function usingAnd(from) {
return to => compose_(from["+++"](identity()), to["+++"](identity()));
}
/**
* Compose layers
*/
function compose_(from, to) {
return fold(from)(fromRawFunctionM(_ => T.halt(_.get(1))))(to);
}
/**
* Compose layers
*/
function compose(to) {
return from => compose_(from, to);
}
const hashSym = /*#__PURE__*/Symbol();
exports.hashSym = hashSym;
class Layer {
constructor() {
this[_a] = new _index6.AtomicReference(Symbol());
}
/**
* Set the hash key for memoization
*/
setKey(hash) {
this[hashSym].set(hash);
return this;
}
[(_a = hashSym, "_I")]() {
return this;
}
/**
* Use that Layer to provide data to this
*/
["<=<"](that) {
return that[">=>"](this);
}
/**
* Use this Layer to provide data to that
*/
[">=>"](that) {
return compose_(this, that);
}
/**
* Use that Layer to partially provide data to this
*/
["<<<"](that) {
return that[">>>"](this);
}
[">>>"](that) {
return this["+++"](identity())[">=>"](that);
}
/**
* Create a Layer with the data from both Layers, while providing the data from this to that
*/
[">+>"](that) {
return this[">>>"](that["+++"](identity()));
}
/**
* Create a Layer with the data from both Layers, while providing the data from that to this
*/
["<+<"](that) {
return that[">+>"](this);
}
/**
* Combine both layers in parallel
*/
["+++"](from) {
return and_(from, this);
}
/**
* Use the layer to provide partial environment to an effect
*/
use(effect) {
return provideSomeLayer(this)(effect);
}
/**
* Use the layer to provide the full environment to an effect
*/
useAll(effect) {
return provideLayer(this)(effect);
}
/**
* Use the layer to provide the full environment to an effect
*/
get useForever() {
return provideLayer(this)(T.never);
}
}
/**
* Provides a layer to the given effect
*/
exports.Layer = Layer;
function provideSomeLayer(layer) {
return self => provideLayer_(self, layer["+++"](identity()));
}
/**
* Provides a layer to the given effect
*/
function provideSomeLayer_(self, layer) {
return provideLayer_(self, layer["+++"](identity()));
}
/**
* Provides a layer to the given effect
*/
function provideLayer_(self, layer) {
return (0, _use.use_)(build(layer), p => T.provideAll_(self, p));
}
/**
* Provides a layer to the given effect
*/
function provideLayer(layer) {
return self => provideLayer_(self, layer);
}
class LayerFold extends Layer {
constructor(self, failure, success) {
super();
this.self = self;
this.failure = failure;
this.success = success;
this._tag = "LayerFold";
}
}
exports.LayerFold = LayerFold;
class LayerMap extends Layer {
constructor(self, f) {
super();
this.self = self;
this.f = f;
this._tag = "LayerMap";
}
}
exports.LayerMap = LayerMap;
class LayerChain extends Layer {
constructor(self, f) {
super();
this.self = self;
this.f = f;
this._tag = "LayerChain";
}
}
exports.LayerChain = LayerChain;
class LayerFresh extends Layer {
constructor(self) {
super();
this.self = self;
this._tag = "LayerFresh";
}
}
exports.LayerFresh = LayerFresh;
class LayerManaged extends Layer {
constructor(self) {
super();
this.self = self;
this._tag = "LayerManaged";
}
}
exports.LayerManaged = LayerManaged;
class LayerSuspend extends Layer {
constructor(self) {
super();
this.self = self;
this._tag = "LayerSuspend";
}
}
exports.LayerSuspend = LayerSuspend;
class LayerZipWithPar extends Layer {
constructor(self, that, f) {
super();
this.self = self;
this.that = that;
this.f = f;
this._tag = "LayerZipWithPar";
}
}
exports.LayerZipWithPar = LayerZipWithPar;
class LayerAllPar extends Layer {
constructor(layers) {
super();
this.layers = layers;
this._tag = "LayerAllPar";
}
}
exports.LayerAllPar = LayerAllPar;
class LayerAllSeq extends Layer {
constructor(layers) {
super();
this.layers = layers;
this._tag = "LayerAllSeq";
}
}
exports.LayerAllSeq = LayerAllSeq;
class LayerZipWithSeq extends Layer {
constructor(self, that, f) {
super();
this.self = self;
this.that = that;
this.f = f;
this._tag = "LayerZipWithSeq";
}
}
exports.LayerZipWithSeq = LayerZipWithSeq;
function scope(_) {
const I = _._I();
switch (I._tag) {
case "LayerFresh":
{
return (0, _succeed.succeed)(() => build(I.self));
}
case "LayerManaged":
{
return (0, _succeed.succeed)(() => I.self);
}
case "LayerSuspend":
{
return (0, _succeed.succeed)(memo => memo.getOrElseMemoize(I.self()));
}
case "LayerMap":
{
return (0, _succeed.succeed)(memo => (0, _core.map_)(memo.getOrElseMemoize(I.self), I.f));
}
case "LayerChain":
{
return (0, _succeed.succeed)(memo => (0, _core.chain_)(memo.getOrElseMemoize(I.self), a => memo.getOrElseMemoize(I.f(a))));
}
case "LayerZipWithPar":
{
return (0, _succeed.succeed)(memo => (0, _core.zipWithPar_)(memo.getOrElseMemoize(I.self), memo.getOrElseMemoize(I.that), I.f));
}
case "LayerZipWithSeq":
{
return (0, _succeed.succeed)(memo => (0, _core.zipWith_)(memo.getOrElseMemoize(I.self), memo.getOrElseMemoize(I.that), I.f));
}
case "LayerAllPar":
{
return (0, _succeed.succeed)(memo => {
return (0, _core.map)((0, _reduce.reduce)({}, (b, a) => ({ ...b,
...a
})))((0, _forEach.forEachPar_)(I.layers, memo.getOrElseMemoize));
});
}
case "LayerAllSeq":
{
return (0, _succeed.succeed)(memo => {
return (0, _core.map)((0, _reduce.reduce)({}, (b, a) => ({ ...b,
...a
})))((0, _forEach.forEach_)(I.layers, memo.getOrElseMemoize));
});
}
case "LayerFold":
{
return (0, _succeed.succeed)(memo => (0, _core.foldCauseM_)(memo.getOrElseMemoize(I.self), e => (0, _core.chain)(r => (0, _core.provideSome_)(memo.getOrElseMemoize(I.failure), () => Tp.tuple(r, e)))((0, _fromEffect.fromEffect)(T.environment())), r => (0, _core.provideAll_)(memo.getOrElseMemoize(I.success), r)));
}
}
}
/**
* Builds a layer into a managed value.
*/
function build(_) {
return (0, _core.map)(({
value
}) => value)((0, _do.bind)("value", ({
memoMap,
run
}) => run(memoMap))((0, _do.bind)("run", () => scope(_))((0, _do.bind)("memoMap", () => (0, _fromEffect.fromEffect)(makeMemoMap()))(_do.do))));
}
/**
* Creates a MemoMap
*/
function makeMemoMap() {
return T.chain_(RM.makeRefM(new Map()), r => T.succeedWith(() => new MemoMap(r)));
}
/**
* A `MemoMap` memoizes dependencies.
*/
class MemoMap {
constructor(ref) {
this.ref = ref;
/**
* Checks the memo map to see if a dependency exists. If it is, immediately
* returns it. Otherwise, obtains the dependency, stores it in the memo map,
* and adds a finalizer to the outer `Managed`.
*/
this.getOrElseMemoize = layer => {
return (0, _managed.managedApply)(T.flatten(RM.modify(m => {
const inMap = m.get(layer[hashSym].get);
if (inMap) {
const {
tuple: [acquire, release]
} = inMap;
const cached = T.accessM(({
tuple: [_, rm]
}) => T.map_(T.onExit_(acquire, ex => {
switch (ex._tag) {
case "Success":
{
return add.add(release)(rm);
}
case "Failure":
{
return T.unit;
}
}
}), x => Tp.tuple(release, x)));
return T.succeed(Tp.tuple(cached, m));
} else {
return T.map_(T.let_(T.let_(T.bind_(T.bind_(T.bind_(T.do, "observers", () => R.makeRef(0)), "promise", () => (0, _make.make)()), "finalizerRef", () => R.makeRef(Finalizer.noopFinalizer)), "resource", ({
finalizerRef,
observers,
promise
}) => T.uninterruptibleMask(({
restore
}) => T.map_(T.bind_(T.bind_(T.let_(T.let_(T.bind_(T.do, "env", () => T.environment()), "a", ({
env: {
tuple: [a]
}
}) => a), "outerReleaseMap", ({
env: {
tuple: [_, outerReleaseMap]
}
}) => outerReleaseMap), "innerReleaseMap", () => makeReleaseMap.makeReleaseMap), "tp", ({
a,
innerReleaseMap,
outerReleaseMap
}) => restore(T.chain_(T.result(T.provideAll_((0, _core.chain)(_ => _(this))(scope(layer)).effect, Tp.tuple(a, innerReleaseMap))), e => {
switch (e._tag) {
case "Failure":
{
return T.chain_(T.chain_((0, _halt.halt)(e.cause)(promise), () => releaseAll.releaseAll(e, _ExecutionStrategy.sequential)(innerReleaseMap)), () => T.halt(e.cause));
}
case "Success":
{
return T.map_(T.tap_(T.bind_(T.tap_(T.tap_(T.do, () => finalizerRef.set(e => T.whenM_(releaseAll.releaseAll(e, _ExecutionStrategy.sequential)(innerReleaseMap), R.modify_(observers, n => Tp.tuple(n === 1, n - 1))))), () => R.update_(observers, n => n + 1)), "outerFinalizer", () => add.add(e => T.chain_(finalizerRef.get, f => f(e)))(outerReleaseMap)), () => (0, _succeed2.succeed)(e.value.get(1))(promise)), ({
outerFinalizer
}) => Tp.tuple(outerFinalizer, e.value.get(1)));
}
}
}))), ({
tp
}) => tp))), "memoized", ({
finalizerRef,
observers,
promise
}) => Tp.tuple(T.onExit_((0, _await.await)(promise), e => {
switch (e._tag) {
case "Failure":
{
return T.unit;
}
case "Success":
{
return R.update_(observers, n => n + 1);
}
}
}), e => T.chain_(finalizerRef.get, f => f(e)))), ({
memoized,
resource
}) => Tp.tuple(resource, (0, _index.insert)(layer[hashSym].get, memoized)(m)));
}
})(this.ref)));
};
}
}
/**
* Empty layer, useful for init cases
*/
exports.MemoMap = MemoMap;
const Empty = /*#__PURE__*/new LayerSuspend(() => identity());
exports.Empty = Empty;
//# sourceMappingURL=definitions.js.map