EdgeAIG's picture
download
raw
3.98 kB
import * as Context from "../Context.js";
import * as Duration from "../Duration.js";
import * as Effect from "../Effect.js";
import * as Exit from "../Exit.js";
import * as Fiber from "../Fiber.js";
import { identity } from "../Function.js";
import { pipeArguments } from "../Pipeable.js";
import * as Scope from "../Scope.js";
import * as Semaphore from "../Semaphore.js";
const TypeId = "~effect/RcRef";
const stateEmpty = {
_tag: "Empty"
};
const stateClosed = {
_tag: "Closed"
};
const variance = {
_A: identity,
_E: identity
};
class RcRefImpl {
[TypeId] = variance;
pipe() {
return pipeArguments(this, arguments);
}
state = stateEmpty;
semaphore = /*#__PURE__*/Semaphore.makeUnsafe(1);
acquire;
context;
scope;
idleTimeToLive;
constructor(acquire, context, scope, idleTimeToLive) {
this.acquire = acquire;
this.context = context;
this.scope = scope;
this.idleTimeToLive = idleTimeToLive;
}
}
/** @internal */
export const make = options => Effect.withFiber(fiber => {
const context = fiber.context;
const scope = Context.get(context, Scope.Scope);
const ref = new RcRefImpl(options.acquire, context, scope, options.idleTimeToLive ? Duration.fromInputUnsafe(options.idleTimeToLive) : undefined);
return Effect.as(Scope.addFinalizerExit(scope, () => {
const close = ref.state._tag === "Acquired" ? Scope.close(ref.state.scope, Exit.void) : Effect.void;
ref.state = stateClosed;
return close;
}), ref);
});
const getState = self => Effect.uninterruptibleMask(restore => {
switch (self.state._tag) {
case "Closed":
{
return Effect.interrupt;
}
case "Acquired":
{
self.state.refCount++;
return self.state.fiber ? Effect.as(Fiber.interrupt(self.state.fiber), self.state) : Effect.succeed(self.state);
}
case "Empty":
{
const scope = Scope.makeUnsafe();
return self.semaphore.withPermits(1)(restore(Effect.provideContext(self.acquire, Context.add(self.context, Scope.Scope, scope))).pipe(Effect.map(value => {
const state = {
_tag: "Acquired",
value,
scope,
fiber: undefined,
refCount: 1,
invalidated: false
};
self.state = state;
return state;
})));
}
}
});
/** @internal */
export const get = /*#__PURE__*/Effect.fnUntraced(function* (self_) {
const self = self_;
const state = yield* getState(self);
const scope = yield* Effect.scope;
const isFinite = self.idleTimeToLive !== undefined && Duration.isFinite(self.idleTimeToLive);
yield* Scope.addFinalizerExit(scope, () => {
state.refCount--;
if (state.refCount > 0) {
return Effect.void;
}
if (self.idleTimeToLive === undefined) {
self.state = stateEmpty;
return Scope.close(state.scope, Exit.void);
} else if (state.invalidated) {
return Scope.close(state.scope, Exit.void);
} else if (!isFinite) {
return Effect.void;
}
state.fiber = Effect.sleep(self.idleTimeToLive).pipe(Effect.flatMap(() => {
if (self.state._tag === "Acquired" && self.state.refCount === 0) {
self.state = stateEmpty;
return Scope.close(state.scope, Exit.void);
}
return Effect.void;
}), Effect.ensuring(Effect.sync(() => {
state.fiber = undefined;
})), Effect.runForkWith(self.context), Fiber.runIn(self.scope));
return Effect.void;
});
return state.value;
});
/** @internal */
export const invalidate = self_ => {
const self = self_;
return Effect.uninterruptible(Effect.suspend(() => {
if (self.state._tag !== "Acquired") {
return Effect.void;
}
const state = self.state;
self.state = stateEmpty;
state.invalidated = true;
if (state.refCount > 0) {
return Effect.void;
}
state.fiber?.interruptUnsafe();
return Scope.close(state.scope, Exit.void);
}));
};
//# sourceMappingURL=rcRef.js.map

Xet Storage Details

Size:
3.98 kB
·
Xet hash:
d2a2332750ed0b4e5643279258442f495c24b08d9f8cdd9e6a424de1bfa9e378

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.