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