veffect
Version:
powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha
232 lines (230 loc) • 7.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.unsafeAdd = exports.size = exports.runtime = exports.run = exports.makeRuntime = exports.make = exports.join = exports.isFiberSet = exports.clear = exports.add = exports.TypeId = void 0;
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Effect"));
var Cause = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Cause.js"));
var Deferred = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Deferred.js"));
var Exit = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Exit.js"));
var Fiber = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Fiber.js"));
var FiberRef = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./FiberRef.js"));
var _Function = /*#__PURE__*/require("./Function.js");
var Inspectable = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Inspectable.js"));
var Option = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Option.js"));
var _Pipeable = /*#__PURE__*/require("./Pipeable.js");
var Predicate = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Predicate.js"));
var Runtime = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Runtime.js"));
function _getRequireWildcardCache(e) {
if ("function" != typeof WeakMap) return null;
var r = new WeakMap(),
t = new WeakMap();
return (_getRequireWildcardCache = function (e) {
return e ? t : r;
})(e);
}
function _interopRequireWildcard(e, r) {
if (!r && e && e.__esModule) return e;
if (null === e || "object" != typeof e && "function" != typeof e) return {
default: e
};
var t = _getRequireWildcardCache(r);
if (t && t.has(e)) return t.get(e);
var n = {
__proto__: null
},
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];
}
return n.default = e, t && t.set(e, n), n;
}
/**
* @since 2.0.0
*/
/**
* @since 2.0.0
* @categories type ids
*/
const TypeId = exports.TypeId = /*#__PURE__*/Symbol.for("effect/FiberSet");
/**
* @since 2.0.0
* @categories refinements
*/
const isFiberSet = u => Predicate.hasProperty(u, TypeId);
exports.isFiberSet = isFiberSet;
const Proto = {
[TypeId]: TypeId,
[Symbol.iterator]() {
return this.backing[Symbol.iterator]();
},
toString() {
return Inspectable.format(this.toJSON());
},
toJSON() {
return {
_id: "FiberMap",
backing: Inspectable.toJSON(Array.from(this.backing))
};
},
[Inspectable.NodeInspectSymbol]() {
return this.toJSON();
},
pipe() {
return (0, _Pipeable.pipeArguments)(this, arguments);
}
};
const unsafeMake = (backing, deferred) => {
const self = Object.create(Proto);
self.backing = backing;
self.deferred = deferred;
return self;
};
/**
* A FiberSet can be used to store a collection of fibers.
* When the associated Scope is closed, all fibers in the set will be interrupted.
*
* You can add fibers to the set using `FiberSet.add` or `FiberSet.run`, and the fibers will
* be automatically removed from the FiberSet when they complete.
*
* @example
* import { Effect, FiberSet } from "effect"
*
* Effect.gen(function*(_) {
* const set = yield* _(FiberSet.make())
*
* // run some effects and add the fibers to the set
* yield* _(FiberSet.run(set, Effect.never))
* yield* _(FiberSet.run(set, Effect.never))
*
* yield* _(Effect.sleep(1000))
* }).pipe(
* Effect.scoped // The fibers will be interrupted when the scope is closed
* )
*
* @since 2.0.0
* @categories constructors
*/
const make = () => Effect.acquireRelease(Effect.map(Deferred.make(), deferred => unsafeMake(new Set(), deferred)), clear);
/**
* Create an Effect run function that is backed by a FiberSet.
*
* @since 2.0.0
* @categories constructors
*/
exports.make = make;
const makeRuntime = () => Effect.flatMap(make(), self => runtime(self)());
/**
* Add a fiber to the FiberSet. When the fiber completes, it will be removed.
*
* @since 2.0.0
* @categories combinators
*/
exports.makeRuntime = makeRuntime;
const unsafeAdd = exports.unsafeAdd = /*#__PURE__*/(0, _Function.dual)(2, (self, fiber) => {
if (self.backing.has(fiber)) {
return;
}
;
fiber.setFiberRef(FiberRef.unhandledErrorLogLevel, Option.none());
self.backing.add(fiber);
fiber.addObserver(exit => {
self.backing.delete(fiber);
if (Exit.isFailure(exit) && !Cause.isInterruptedOnly(exit.cause)) {
Deferred.unsafeDone(self.deferred, exit);
}
});
});
/**
* Add a fiber to the FiberSet. When the fiber completes, it will be removed.
*
* @since 2.0.0
* @categories combinators
*/
const add = exports.add = /*#__PURE__*/(0, _Function.dual)(2, (self, fiber) => Effect.sync(() => unsafeAdd(self, fiber)));
/**
* @since 2.0.0
* @categories combinators
*/
const clear = self => Effect.zipRight(Effect.forEach(self.backing, fiber => Fiber.interrupt(fiber)), Effect.sync(() => {
self.backing.clear();
}));
/**
* Fork an Effect and add the forked fiber to the FiberSet.
* When the fiber completes, it will be removed from the FiberSet.
*
* @since 2.0.0
* @categories combinators
*/
exports.clear = clear;
const run = function () {
const self = arguments[0];
if (arguments.length === 1) {
return effect => Effect.tap(Effect.forkDaemon(effect), fiber => add(self, fiber));
}
const effect = arguments[1];
return Effect.tap(Effect.forkDaemon(effect), fiber => add(self, fiber));
};
/**
* Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberSet.
*
* @example
* import { Context, Effect, FiberSet } from "effect"
*
* interface Users {
* readonly _: unique symbol
* }
* const Users = Context.GenericTag<Users, {
* getAll: Effect.Effect<Array<unknown>>
* }>("Users")
*
* Effect.gen(function*(_) {
* const set = yield* _(FiberSet.make())
* const run = yield* _(FiberSet.runtime(set)<Users>())
*
* // run some effects and add the fibers to the set
* run(Effect.andThen(Users, _ => _.getAll))
* }).pipe(
* Effect.scoped // The fibers will be interrupted when the scope is closed
* )
*
* @since 2.0.0
* @categories combinators
*/
exports.run = run;
const runtime = self => () => Effect.map(Effect.runtime(), runtime => {
const runFork = Runtime.runFork(runtime);
return (effect, options) => {
const fiber = runFork(effect, options);
unsafeAdd(self, fiber);
return fiber;
};
});
/**
* @since 2.0.0
* @categories combinators
*/
exports.runtime = runtime;
const size = self => Effect.sync(() => self.backing.size);
/**
* Join all fibers in the FiberSet. If any of the Fiber's in the set terminate with a failure,
* the returned Effect will terminate with the first failure that occurred.
*
* @since 2.0.0
* @categories combinators
* @example
* import { Effect, FiberSet } from "effect";
*
* Effect.gen(function* (_) {
* const set = yield* _(FiberSet.make());
* yield* _(FiberSet.add(set, Effect.runFork(Effect.fail("error"))));
*
* // parent fiber will fail with "error"
* yield* _(FiberSet.join(set));
* });
*/
exports.size = size;
const join = self => Deferred.await(self.deferred);
exports.join = join;
//# sourceMappingURL=FiberSet.js.map