"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MemoMap = void 0;
exports.build = build;
exports.isFresh = exports.buildWithScope = void 0;
exports.makeMemoMap = makeMemoMap;
exports.withScope = void 0;

var tsplus_module_1 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@tsplus/stdlib/data/Maybe/fromNullable"));

var tsplus_module_2 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/unit"));

var tsplus_module_3 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Scope/operations/addFinalizerExit"));

var tsplus_module_4 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Exit/operations/fold"));

var tsplus_module_5 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/onExit"));

var tsplus_module_6 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@tsplus/stdlib/data/Tuple/make"));

var tsplus_module_7 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/succeed"));

var tsplus_module_8 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/flatMap"));

var tsplus_module_9 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Scope/operations/close"));

var tsplus_module_10 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/zipRight"));

var tsplus_module_11 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/failCause"));

var tsplus_module_12 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/whenEffect"));

var tsplus_module_13 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/as"));

var tsplus_module_14 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/exit"));

var tsplus_module_15 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Scope/operations/make"));

var tsplus_module_16 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/do"));

var tsplus_module_17 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/interruption"));

var tsplus_module_18 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Ref/operations/make"));

var tsplus_module_19 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Deferred/operations/make"));

var tsplus_module_20 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/map"));

var tsplus_module_21 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/flatten"));

var tsplus_module_22 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Scope/definition"));

var tsplus_module_23 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/serviceWithEffect"));

var tsplus_module_24 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/scopeWith"));

var tsplus_module_25 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/foldCauseEffect"));

var tsplus_module_26 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Scope/operations/extend"));

var tsplus_module_27 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/provideEnvironment"));

var tsplus_module_28 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/zipWithPar"));

var tsplus_module_29 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@tsplus/stdlib/data/Match"));

var _definition2 = /*#__PURE__*/require("@effect/core/io/Layer/definition");

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; }

const fileName_1 = "(@effect/core) _src/io/Layer/memoMap.ts";
const buildWithScope = buildWithScope_1;
exports.buildWithScope = buildWithScope;
const withScope = withScope_1;
exports.withScope = withScope;
const isFresh = isFresh_1;
exports.isFresh = isFresh;

/**
 * A `MemoMap` memoizes layers.
 */
class MemoMap {
  constructor(ref) {
    this.ref = ref;
  }
  /**
   * Checks the memo map to see if a layer exists. If it is, immediately
   * returns it. Otherwise, obtains the layer, stores it in the memo map,
   * and adds a finalizer to the `Scope`.
   */


  getOrElseMemoize(layer, scope) {
    return tsplus_module_8.flatMap_(tsplus_module_7.succeed(scope, fileName_1 + ":22:26"), scope => tsplus_module_21.flattenNow(this.ref.modifyEffect(map => {
      const inMap = tsplus_module_1.fromNullable(map.get(layer));

      switch (inMap._tag) {
        case "Some":
          {
            const {
              tuple: [acquire, release]
            } = inMap.value;
            const cached = tsplus_module_5.onExit_(acquire, exit => tsplus_module_4.fold_(exit, () => tsplus_module_2.unit, () => tsplus_module_3.addFinalizerExit_(scope, release)), fileName_1 + ":32:71");
            return tsplus_module_7.succeed(() => tsplus_module_6.make(cached, map), fileName_1 + ":39:34");
          }

        case "None":
          {
            return tsplus_module_20.map_(tsplus_module_16.bindValue_(tsplus_module_16.bindValue_(tsplus_module_16.bind_(tsplus_module_16.bind_(tsplus_module_16.bind_(tsplus_module_16.Do(), "observers", () => tsplus_module_18.makeSynchronized(() => 0, fileName_1 + ":43:61"), fileName_1 + ":43:20"), "deferred", () => tsplus_module_19.make(fileName_1 + ":44:52"), fileName_1 + ":44:20"), "finalizerRef", () => tsplus_module_18.makeSynchronized(() => () => tsplus_module_2.unit, fileName_1 + ":45:64"), fileName_1 + ":45:20"), "resource", ({
              deferred,
              finalizerRef,
              observers
            }) => tsplus_module_17.uninterruptibleMask(({
              restore
            }) => tsplus_module_8.flatMap_(tsplus_module_16.bind_(tsplus_module_16.bindValue_(tsplus_module_16.Do(), "outerScope", () => scope, fileName_1 + ":49:31"), "innerScope", () => tsplus_module_15.make, fileName_1 + ":51:26"), ({
              innerScope,
              outerScope
            }) => tsplus_module_8.flatMap_(tsplus_module_14.exit(restore(() => tsplus_module_8.flatMap_(withScope_1(layer, () => innerScope, fileName_1 + ":53:46"), f => f(this), fileName_1 + ":53:66"), fileName_1 + ":53:30"), fileName_1 + ":54:30"), exit => {
              switch (exit._tag) {
                case "Failure":
                  {
                    return tsplus_module_10.zipRight_(tsplus_module_10.zipRight_(deferred.failCause(() => exit.cause, fileName_1 + ":59:51"), () => tsplus_module_9.close_(innerScope, () => exit), fileName_1 + ":59:65"), () => tsplus_module_11.failCause(() => exit.cause, fileName_1 + ":61:51"), fileName_1 + ":60:59");
                  }

                case "Success":
                  {
                    return tsplus_module_13.as_(tsplus_module_10.zipRight_(tsplus_module_10.zipRight_(tsplus_module_10.zipRight_(finalizerRef.set(exit => tsplus_module_12.whenEffect(() => observers.modify(n => tsplus_module_6.make(n === 1, n - 1), fileName_1 + ":67:51"), () => tsplus_module_9.close_(innerScope, () => exit), fileName_1 + ":66:50"), fileName_1 + ":65:54"), () => observers.update(n => n + 1, fileName_1 + ":71:59"), fileName_1 + ":71:42"), () => tsplus_module_3.addFinalizerExit_(outerScope, e => tsplus_module_8.flatMap_(finalizerRef.get(fileName_1 + ":73:86"), fin => fin(e), fileName_1 + ":73:96")), fileName_1 + ":72:42"), () => deferred.succeed(() => exit.value, fileName_1 + ":75:59"), fileName_1 + ":75:42"), () => exit.value, fileName_1 + ":76:36");
                  }
              }
            }, fileName_1 + ":55:33"), fileName_1 + ":52:29"), fileName_1 + ":47:43"), fileName_1 + ":46:25"), "memoized", ({
              deferred,
              finalizerRef,
              observers
            }) => tsplus_module_6.make(tsplus_module_5.onExit_(deferred.await(fileName_1 + ":84:33"), exit => tsplus_module_4.fold_(exit, () => tsplus_module_2.unit, () => observers.update(n => n + 1, fileName_1 + ":89:47")), fileName_1 + ":85:28"), e => tsplus_module_8.flatMap_(finalizerRef.get(fileName_1 + ":92:66"), fin => fin(e), fileName_1 + ":92:76")), fileName_1 + ":82:25"), ({
              memoized,
              resource
            }) => tsplus_module_6.make(resource, isFresh_1(layer) ? map : map.set(layer, memoized)), fileName_1 + ":94:19");
          }
      }
    }, fileName_1 + ":23:28"), fileName_1 + ":97:17"), fileName_1 + ":22:41");
  }

}
/**
 * Creates an empty `MemoMap`.
 */


exports.MemoMap = MemoMap;

function makeMemoMap() {
  return tsplus_module_8.flatMap_(tsplus_module_18.makeSynchronized(() => new Map(), fileName_1 + ":106:31"), r => tsplus_module_7.succeed(() => new MemoMap(r), fileName_1 + ":108:45"), fileName_1 + ":108:23");
}
/**
 * Builds a layer into a scoped value.
 *
 * @tsplus fluent ets/Layer build
 */


function build(self, __tsplusTrace) {
  return tsplus_module_23.serviceWithEffect(tsplus_module_22.Scope.Tag, scope => buildWithScope_1(self, () => scope, __tsplusTrace), __tsplusTrace);
}
/**
 * Builds a layer into an Effect value. Any resources associated with this layer
 * will be released when the specified scope is closed unless their scope has
 * been extended. This allows building layers where the lifetime of some of
 * the services output by the layer exceed the lifetime of the effect the
 * layer is provided to.
 *
 * @tsplus fluent ets/Layer buildWithScope
 */


function buildWithScope_1(self, scope, __tsplusTrace) {
  return tsplus_module_8.flatMap_(tsplus_module_16.bind_(tsplus_module_16.bind_(tsplus_module_16.Do(), "memoMap", () => makeMemoMap(), __tsplusTrace), "run", () => withScope_1(self, scope, __tsplusTrace), __tsplusTrace), ({
    memoMap,
    run
  }) => run(memoMap), __tsplusTrace);
}
/**
 * @tsplus fluent ets/Layer withScope
 */


function withScope_1(self, scope, __tsplusTrace) {
  return tsplus_module_29.matchTag_(self, {
    LayerApply: _ => tsplus_module_7.succeed(() => memoMap => _.self, __tsplusTrace),
    LayerExtendScope: _ => tsplus_module_7.succeed(() => memoMap => tsplus_module_24.scopeWith(scope => memoMap.getOrElseMemoize(_.self, () => scope), __tsplusTrace), __tsplusTrace),
    LayerFold: _ => tsplus_module_7.succeed(() => memoMap => tsplus_module_25.foldCauseEffect_(memoMap.getOrElseMemoize(_.self, scope), e => memoMap.getOrElseMemoize(_.failure(e), scope), r => memoMap.getOrElseMemoize(_.success(r), scope), __tsplusTrace), __tsplusTrace),
    LayerFresh: _ => tsplus_module_7.succeed(() => __ => buildWithScope_1(_.self, scope, __tsplusTrace), __tsplusTrace),
    LayerScoped: _ => tsplus_module_7.succeed(() => __ => tsplus_module_26.extend_(scope(), () => _.self), __tsplusTrace),
    LayerSuspend: _ => tsplus_module_7.succeed(() => memoMap => memoMap.getOrElseMemoize(_.self(), scope), __tsplusTrace),
    LayerTo: _ => tsplus_module_7.succeed(() => memoMap => tsplus_module_8.flatMap_(memoMap.getOrElseMemoize(_.self, scope), r => tsplus_module_27.provideEnvironment_(memoMap.getOrElseMemoize(_.that, scope), () => r, __tsplusTrace), __tsplusTrace), __tsplusTrace),
    LayerZipWithPar: _ => tsplus_module_7.succeed(() => memoMap => tsplus_module_28.zipWithPar_(memoMap.getOrElseMemoize(_.self, scope), () => memoMap.getOrElseMemoize(_.that, scope), _.f, __tsplusTrace), __tsplusTrace)
  });
}
/**
 * Returns whether this layer is a fresh version that will not be shared.
 *
 * @tsplus getter ets/Layer isFresh
 */


function isFresh_1(self) {
  return self._tag === "LayerFresh";
}
//# sourceMappingURL=memoMap.js.map