UNPKG

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

344 lines (343 loc) 14.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateRuntimeFlags = exports.updateFiberRefs = exports.updateContext = exports.unsafeRunSyncExitEffect = exports.unsafeRunSyncExit = exports.unsafeRunSyncEffect = exports.unsafeRunSync = exports.unsafeRunPromiseExitEffect = exports.unsafeRunPromiseExit = exports.unsafeRunPromiseEffect = exports.unsafeRunPromise = exports.unsafeRunEffect = exports.unsafeRunCallback = exports.unsafeForkEffect = exports.unsafeFork = exports.setFiberRef = exports.runtime = exports.provideService = exports.make = exports.isFiberFailure = exports.isAsyncFiberException = exports.fiberFailure = exports.enableRuntimeFlag = exports.disableRuntimeFlag = exports.deleteFiberRef = exports.defaultRuntimeFlags = exports.defaultRuntime = exports.asyncEffect = exports.RuntimeImpl = exports.FiberFailureId = exports.FiberFailureCauseId = void 0; var _Equal = /*#__PURE__*/require("effect/Equal"); var Context = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Context.js")); var Exit = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Exit.js")); var Fiber = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Fiber.js")); var FiberId = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../FiberId.js")); var FiberRefs = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../FiberRefs.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 _scheduler = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Scheduler.js")); var _scope = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../Scope.js")); var InternalCause = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./cause.js")); var core = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./core.js")); var executionStrategy = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./executionStrategy.js")); var FiberRuntime = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./fiberRuntime.js")); var fiberScope = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./fiberScope.js")); var OpCodes = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./opCodes/effect.js")); var runtimeFlags = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./runtimeFlags.js")); var _supervisor = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./supervisor.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; } /** @internal */ const unsafeFork = runtime => (self, options) => { const fiberId = FiberId.unsafeMake(); const fiberRefUpdates = [[core.currentContext, [[fiberId, runtime.context]]]]; if (options?.scheduler) { fiberRefUpdates.push([_scheduler.currentScheduler, [[fiberId, options.scheduler]]]); } let fiberRefs = FiberRefs.updateManyAs(runtime.fiberRefs, { entries: fiberRefUpdates, forkAs: fiberId }); if (options?.updateRefs) { fiberRefs = options.updateRefs(fiberRefs, fiberId); } const fiberRuntime = new FiberRuntime.FiberRuntime(fiberId, fiberRefs, runtime.runtimeFlags); let effect = self; if (options?.scope) { effect = core.flatMap(_scope.fork(options.scope, executionStrategy.sequential), closeableScope => core.zipRight(core.scopeAddFinalizer(closeableScope, core.fiberIdWith(id => (0, _Equal.equals)(id, fiberRuntime.id()) ? core.unit : core.interruptAsFiber(fiberRuntime, id))), core.onExit(self, exit => _scope.close(closeableScope, exit)))); } const supervisor = fiberRuntime._supervisor; // we can compare by reference here as _supervisor.none is wrapped with globalValue if (supervisor !== _supervisor.none) { supervisor.onStart(runtime.context, effect, Option.none(), fiberRuntime); fiberRuntime.addObserver(exit => supervisor.onEnd(exit, fiberRuntime)); } fiberScope.globalScope.add(runtime.runtimeFlags, fiberRuntime); // Only an explicit false will prevent immediate execution if (options?.immediate === false) { fiberRuntime.resume(effect); } else { fiberRuntime.start(effect); } return fiberRuntime; }; /** @internal */ exports.unsafeFork = unsafeFork; const unsafeRunCallback = runtime => (effect, options = {}) => { const fiberRuntime = unsafeFork(runtime)(effect, options); if (options.onExit) { fiberRuntime.addObserver(exit => { options.onExit(exit); }); } return (id, cancelOptions) => unsafeRunCallback(runtime)((0, _Function.pipe)(fiberRuntime, Fiber.interruptAs(id ?? FiberId.none)), { ...cancelOptions, onExit: cancelOptions?.onExit ? exit => cancelOptions.onExit(Exit.flatten(exit)) : undefined }); }; /** @internal */ exports.unsafeRunCallback = unsafeRunCallback; const unsafeRunSync = runtime => effect => { const result = unsafeRunSyncExit(runtime)(effect); if (result._tag === "Failure") { throw fiberFailure(result.effect_instruction_i0); } else { return result.effect_instruction_i0; } }; exports.unsafeRunSync = unsafeRunSync; class AsyncFiberExceptionImpl extends Error { fiber; _tag = "AsyncFiberException"; constructor(fiber) { super(`Fiber #${fiber.id().id} cannot be be resolved synchronously, this is caused by using runSync on an effect that performs async work`); this.fiber = fiber; this.name = this._tag; this.stack = this.message; } } const asyncFiberException = fiber => { const limit = Error.stackTraceLimit; Error.stackTraceLimit = 0; const error = new AsyncFiberExceptionImpl(fiber); Error.stackTraceLimit = limit; return error; }; /** @internal */ const isAsyncFiberException = u => Predicate.isTagged(u, "AsyncFiberException") && "fiber" in u; /** @internal */ exports.isAsyncFiberException = isAsyncFiberException; const FiberFailureId = exports.FiberFailureId = /*#__PURE__*/Symbol.for("effect/Runtime/FiberFailure"); /** @internal */ const FiberFailureCauseId = exports.FiberFailureCauseId = /*#__PURE__*/Symbol.for("effect/Runtime/FiberFailure/Cause"); class FiberFailureImpl extends Error { [FiberFailureId]; [FiberFailureCauseId]; constructor(cause) { super(); this[FiberFailureId] = FiberFailureId; this[FiberFailureCauseId] = cause; const prettyErrors = InternalCause.prettyErrors(cause); if (prettyErrors.length > 0) { const head = prettyErrors[0]; this.name = head.message.split(":")[0]; this.message = head.message.substring(this.name.length + 2); this.stack = InternalCause.pretty(cause); } this.name = `(FiberFailure) ${this.name}`; } toJSON() { return { _id: "FiberFailure", cause: this[FiberFailureCauseId].toJSON() }; } toString() { return "(FiberFailure) " + InternalCause.pretty(this[FiberFailureCauseId]); } [Inspectable.NodeInspectSymbol]() { return this.toString(); } } /** @internal */ const fiberFailure = cause => { const limit = Error.stackTraceLimit; Error.stackTraceLimit = 0; const error = new FiberFailureImpl(cause); Error.stackTraceLimit = limit; return error; }; /** @internal */ exports.fiberFailure = fiberFailure; const isFiberFailure = u => Predicate.hasProperty(u, FiberFailureId); exports.isFiberFailure = isFiberFailure; const fastPath = effect => { const op = effect; switch (op._op) { case "Failure": case "Success": { // @ts-expect-error return op; } case "Left": { return core.exitFail(op.left); } case "Right": { return core.exitSucceed(op.right); } case "Some": { return core.exitSucceed(op.value); } case "None": { // @ts-expect-error return core.exitFail(core.NoSuchElementException()); } } }; /** @internal */ const unsafeRunSyncExit = runtime => effect => { const op = fastPath(effect); if (op) { return op; } const scheduler = new _scheduler.SyncScheduler(); const fiberRuntime = unsafeFork(runtime)(effect, { scheduler }); scheduler.flush(); const result = fiberRuntime.unsafePoll(); if (result) { return result; } throw asyncFiberException(fiberRuntime); }; /** @internal */ exports.unsafeRunSyncExit = unsafeRunSyncExit; const unsafeRunPromise = runtime => (effect, options) => unsafeRunPromiseExit(runtime)(effect, options).then(result => { switch (result._tag) { case OpCodes.OP_SUCCESS: { return result.effect_instruction_i0; } case OpCodes.OP_FAILURE: { throw fiberFailure(result.effect_instruction_i0); } } }); /** @internal */ exports.unsafeRunPromise = unsafeRunPromise; const unsafeRunPromiseExit = runtime => (effect, options) => new Promise(resolve => { const op = fastPath(effect); if (op) { resolve(op); } const fiber = unsafeFork(runtime)(effect); fiber.addObserver(exit => { resolve(exit); }); if (options?.signal !== undefined) { if (options.signal.aborted) { fiber.unsafeInterruptAsFork(fiber.id()); } else { options.signal.addEventListener("abort", () => { fiber.unsafeInterruptAsFork(fiber.id()); }); } } }); /** @internal */ exports.unsafeRunPromiseExit = unsafeRunPromiseExit; class RuntimeImpl { context; runtimeFlags; fiberRefs; constructor(context, runtimeFlags, fiberRefs) { this.context = context; this.runtimeFlags = runtimeFlags; this.fiberRefs = fiberRefs; } pipe() { return (0, _Pipeable.pipeArguments)(this, arguments); } } /** @internal */ exports.RuntimeImpl = RuntimeImpl; const make = options => new RuntimeImpl(options.context, options.runtimeFlags, options.fiberRefs); /** @internal */ exports.make = make; const runtime = () => core.withFiberRuntime((state, status) => core.succeed(new RuntimeImpl(state.getFiberRef(core.currentContext), status.runtimeFlags, state.getFiberRefs()))); /** @internal */ exports.runtime = runtime; const defaultRuntimeFlags = exports.defaultRuntimeFlags = /*#__PURE__*/runtimeFlags.make(runtimeFlags.Interruption, runtimeFlags.CooperativeYielding, runtimeFlags.RuntimeMetrics); /** @internal */ const defaultRuntime = exports.defaultRuntime = /*#__PURE__*/make({ context: /*#__PURE__*/Context.empty(), runtimeFlags: defaultRuntimeFlags, fiberRefs: /*#__PURE__*/FiberRefs.empty() }); /** @internal */ const updateRuntimeFlags = exports.updateRuntimeFlags = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make({ context: self.context, runtimeFlags: f(self.runtimeFlags), fiberRefs: self.fiberRefs })); /** @internal */ const disableRuntimeFlag = exports.disableRuntimeFlag = /*#__PURE__*/(0, _Function.dual)(2, (self, flag) => updateRuntimeFlags(self, runtimeFlags.disable(flag))); /** @internal */ const enableRuntimeFlag = exports.enableRuntimeFlag = /*#__PURE__*/(0, _Function.dual)(2, (self, flag) => updateRuntimeFlags(self, runtimeFlags.enable(flag))); /** @internal */ const updateContext = exports.updateContext = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make({ context: f(self.context), runtimeFlags: self.runtimeFlags, fiberRefs: self.fiberRefs })); /** @internal */ const provideService = exports.provideService = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, service) => updateContext(self, Context.add(tag, service))); /** @internal */ const updateFiberRefs = exports.updateFiberRefs = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make({ context: self.context, runtimeFlags: self.runtimeFlags, fiberRefs: f(self.fiberRefs) })); /** @internal */ const setFiberRef = exports.setFiberRef = /*#__PURE__*/(0, _Function.dual)(3, (self, fiberRef, value) => updateFiberRefs(self, FiberRefs.updateAs({ fiberId: FiberId.none, fiberRef, value }))); /** @internal */ const deleteFiberRef = exports.deleteFiberRef = /*#__PURE__*/(0, _Function.dual)(2, (self, fiberRef) => updateFiberRefs(self, FiberRefs.delete(fiberRef))); /** @internal */ const unsafeRunEffect = exports.unsafeRunEffect = /*#__PURE__*/unsafeRunCallback(defaultRuntime); /** @internal */ const unsafeForkEffect = exports.unsafeForkEffect = /*#__PURE__*/unsafeFork(defaultRuntime); /** @internal */ const unsafeRunPromiseEffect = exports.unsafeRunPromiseEffect = /*#__PURE__*/unsafeRunPromise(defaultRuntime); /** @internal */ const unsafeRunPromiseExitEffect = exports.unsafeRunPromiseExitEffect = /*#__PURE__*/unsafeRunPromiseExit(defaultRuntime); /** @internal */ const unsafeRunSyncEffect = exports.unsafeRunSyncEffect = /*#__PURE__*/unsafeRunSync(defaultRuntime); /** @internal */ const unsafeRunSyncExitEffect = exports.unsafeRunSyncExitEffect = /*#__PURE__*/unsafeRunSyncExit(defaultRuntime); // circular with Effect /** @internal */ const asyncEffect = register => core.suspend(() => { let cleanup = undefined; return core.flatMap(core.deferredMake(), deferred => core.flatMap(runtime(), runtime => core.uninterruptibleMask(restore => core.zipRight(FiberRuntime.fork(restore(core.matchCauseEffect(register(cb => unsafeRunCallback(runtime)(core.intoDeferred(cb, deferred))), { onFailure: cause => core.deferredFailCause(deferred, cause), onSuccess: cleanup_ => { cleanup = cleanup_; return core.unit; } }))), restore(core.onInterrupt(core.deferredAwait(deferred), () => cleanup ?? core.unit)))))); }); exports.asyncEffect = asyncEffect; //# sourceMappingURL=runtime.js.map