<T extends PipeableTag>(strategy: HandoffStrategy): (tag: T) => T
<Self, S extends Spec, HSelf>(
tag: NodeBoundTag<Self, S, HSelf>,
strategy: HandoffStrategy
): NodeBoundTag<Self, S, HSelf>
<Self, S extends Spec>(
tag: HyperlinkTag<Self, S>,
strategy: HandoffStrategy
): HyperlinkTag<Self, S>Attach an opt-in cutover strategy to a HyperService tag (Locked #33). Default is off —
absent stamp ⇒ Track C does not migrate this HyperService (#29). Dual (data-first or .pipe):
class Jobs extends WorkPool.Tag<Jobs>()("app/Jobs", { payload: Item }).pipe(
Hyperlink.withHandoff("drainOnly"),
) {}Strategies:
"drainOnly"— WorkPoolshutdown+ waitphase === "off""workPoolRelease"— localreleaseEncoded/releasethen shutdown (peer enqueue = #34)
Run during Node.shutdown after drain and before Lookup leave. Non-WorkPool kinds log and no-op.
export const const withHandoff: {
<T extends PipeableTag>(
strategy: HandoffStrategy
): (tag: T) => T
<Self, S extends Spec, HSelf>(
tag: NodeBoundTag<Self, S, HSelf>,
strategy: HandoffStrategy
): NodeBoundTag<Self, S, HSelf>
<Self, S extends Spec>(
tag: HyperlinkTag<Self, S>,
strategy: HandoffStrategy
): HyperlinkTag<Self, S>
}
Attach an opt-in cutover strategy to a HyperService tag (Locked #33). Default is off —
absent stamp ⇒ Track C does not migrate this HyperService (#29). Dual (data-first or .pipe):
class Jobs extends WorkPool.Tag<Jobs>()("app/Jobs", { payload: Item }).pipe(
Hyperlink.withHandoff("drainOnly"),
) {}
Strategies:
"drainOnly" — WorkPool shutdown + wait phase === "off"
"workPoolRelease" — local releaseEncoded/release then shutdown (peer enqueue = #34)
Run during
Node.shutdown
after drain and before Lookup leave. Non-WorkPool kinds log and no-op.
withHandoff: {
<function (type parameter) T in <T extends PipeableTag>(strategy: HandoffStrategy): (tag: T) => TT extends type PipeableTag = {
readonly [specSym]: FlatSpec
}
PipeableTag>(strategy: HandoffStrategystrategy: type HandoffStrategy =
| "drainOnly"
| "workPoolRelease"
Opt-in cutover strategy for
withHandoff
(Locked #33).
camelCase option strings — same family as OnConflict / WorkPool shutdownMode
(PascalCase is reserved for _tag discriminants).
HandoffStrategy): (tag: T extends PipeableTagtag: function (type parameter) T in <T extends PipeableTag>(strategy: HandoffStrategy): (tag: T) => TT) => function (type parameter) T in <T extends PipeableTag>(strategy: HandoffStrategy): (tag: T) => TT;
<function (type parameter) Self in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>Self, function (type parameter) S in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>S extends Spec, function (type parameter) HSelf in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>HSelf>(
tag: NodeBoundTag<Self, S, HSelf>(parameter) tag: {
description: string | undefined;
key: Identifier;
of: (this: void, self: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends …;
context: (self: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { readonly _…;
use: (f: (service: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { rea…;
useSync: (f: (service: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { rea…;
Identifier: Identifier;
Service: Shape;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
tag: interface NodeBoundTag<Self, S extends Spec, HSelf, Svc = Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<...> : S[K] extends DefaultMethod<...> ? F : S[K] extends { ...; } ? SuccessOf<...> : S[K] extends { ...; } ? Subscribable<...> : S[K] extends { ...; } ? ClientMethod<...> : S[K] extends Spec ? Simplify<...> : never; }>>A
HyperlinkTag
bound to a concrete
Node
— its [nodeSym] narrowed to that node's
NodeKey<HSelf>, which is how
Hyperlink.client
discriminates the node-aware path. Returned
by the node-bearing tag constructors. It's a named type (not an inline & { [nodeSym] }) so a
consumer can export a node-bearing tag without leaking the internal symbol (TS4020).
NodeBoundTag<function (type parameter) Self in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>Self, function (type parameter) S in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>S, function (type parameter) HSelf in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>HSelf>,
strategy: HandoffStrategystrategy: type HandoffStrategy =
| "drainOnly"
| "workPoolRelease"
Opt-in cutover strategy for
withHandoff
(Locked #33).
camelCase option strings — same family as OnConflict / WorkPool shutdownMode
(PascalCase is reserved for _tag discriminants).
HandoffStrategy,
): interface NodeBoundTag<Self, S extends Spec, HSelf, Svc = Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<...> : S[K] extends DefaultMethod<...> ? F : S[K] extends { ...; } ? SuccessOf<...> : S[K] extends { ...; } ? Subscribable<...> : S[K] extends { ...; } ? ClientMethod<...> : S[K] extends Spec ? Simplify<...> : never; }>>A
HyperlinkTag
bound to a concrete
Node
— its [nodeSym] narrowed to that node's
NodeKey<HSelf>, which is how
Hyperlink.client
discriminates the node-aware path. Returned
by the node-bearing tag constructors. It's a named type (not an inline & { [nodeSym] }) so a
consumer can export a node-bearing tag without leaking the internal symbol (TS4020).
NodeBoundTag<function (type parameter) Self in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>Self, function (type parameter) S in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>S, function (type parameter) HSelf in <Self, S extends Spec, HSelf>(tag: NodeBoundTag<Self, S, HSelf>, strategy: HandoffStrategy): NodeBoundTag<Self, S, HSelf>HSelf>;
<function (type parameter) Self in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>Self, function (type parameter) S in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>S extends Spec>(
tag: HyperlinkTag<Self, S>(parameter) tag: {
description: string | undefined;
key: Identifier;
of: (this: void, self: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends …;
context: (self: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { readonly _…;
use: (f: (service: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { rea…;
useSync: (f: (service: Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<T, never, Self> : S[K] extends DefaultMethod<infer F> ? F : S[K] extends { rea…;
Identifier: Identifier;
Service: Shape;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
tag: interface HyperlinkTag<Self, S extends Spec, Svc = Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<...> : S[K] extends DefaultMethod<...> ? F : S[K] extends { ...; } ? SuccessOf<...> : S[K] extends { ...; } ? Subscribable<...> : S[K] extends { ...; } ? ClientMethod<...> : S[K] extends Spec ? Simplify<...> : never; }>>The type of a HyperService tag carrying spec S — what
Hyperlink.Tag
produces
(and what you extend). Lets a consumer write
<S extends Spec>(tag: HyperlinkTag<Self, S>) and read the spec through named types
(
specOf
/
groupOf
) instead of a Parameters<typeof specOf> workaround.
HyperlinkTag<function (type parameter) Self in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>Self, function (type parameter) S in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>S>,
strategy: HandoffStrategystrategy: type HandoffStrategy =
| "drainOnly"
| "workPoolRelease"
Opt-in cutover strategy for
withHandoff
(Locked #33).
camelCase option strings — same family as OnConflict / WorkPool shutdownMode
(PascalCase is reserved for _tag discriminants).
HandoffStrategy,
): interface HyperlinkTag<Self, S extends Spec, Svc = Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<...> : S[K] extends DefaultMethod<...> ? F : S[K] extends { ...; } ? SuccessOf<...> : S[K] extends { ...; } ? Subscribable<...> : S[K] extends { ...; } ? ClientMethod<...> : S[K] extends Spec ? Simplify<...> : never; }>>The type of a HyperService tag carrying spec S — what
Hyperlink.Tag
produces
(and what you extend). Lets a consumer write
<S extends Spec>(tag: HyperlinkTag<Self, S>) and read the spec through named types
(
specOf
/
groupOf
) instead of a Parameters<typeof specOf> workaround.
HyperlinkTag<function (type parameter) Self in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>Self, function (type parameter) S in <Self, S extends Spec>(tag: HyperlinkTag<Self, S>, strategy: HandoffStrategy): HyperlinkTag<Self, S>S>;
} = import FnFn.const dual: <(...args: Array<any>) => any, <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy) => T>(arity: 2, body: <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy) => T) => ((...args: Array<any>) => any) & (<T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy) => T) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) T in <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy): TT extends interface HyperlinkTag<Self, S extends Spec, Svc = Simplify<{ readonly [K in keyof S]: S[K] extends FromLocalMethod<infer M> ? InjectLocal<M, Self> : S[K] extends LocalMethod<infer T> ? LocalEffect<...> : S[K] extends DefaultMethod<...> ? F : S[K] extends { ...; } ? SuccessOf<...> : S[K] extends { ...; } ? Subscribable<...> : S[K] extends { ...; } ? ClientMethod<...> : S[K] extends Spec ? Simplify<...> : never; }>>The type of a HyperService tag carrying spec S — what
Hyperlink.Tag
produces
(and what you extend). Lets a consumer write
<S extends Spec>(tag: HyperlinkTag<Self, S>) and read the spec through named types
(
specOf
/
groupOf
) instead of a Parameters<typeof specOf> workaround.
HyperlinkTag<any, any, any>>(tag: T extends HyperlinkTag<any, any, any>tag: function (type parameter) T in <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy): TT, strategy: HandoffStrategystrategy: type HandoffStrategy =
| "drainOnly"
| "workPoolRelease"
Opt-in cutover strategy for
withHandoff
(Locked #33).
camelCase option strings — same family as OnConflict / WorkPool shutdownMode
(PascalCase is reserved for _tag discriminants).
HandoffStrategy): function (type parameter) T in <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy): TT =>
// SAFE: same stamp pattern as withReadiness — Object.assign mutates the tag identity; T is preserved.
var Object: ObjectConstructorProvides functionality common to all JavaScript objects.
Object.ObjectConstructor.assign<T, {
[handoffSym]: HyperlinkHandoffStrategy;
}>(target: T, source: {
[handoffSym]: HyperlinkHandoffStrategy;
}): T & {
[handoffSym]: HyperlinkHandoffStrategy;
} (+3 overloads)
Copy the values of all of the enumerable own properties from one or more source objects to a
target object. Returns the target object.
assign(tag: T extends HyperlinkTag<any, any, any>tag, { [const handoffSym: typeof handoffSymWhere a HyperService's opt-in cutover strategy is stowed — applied by
withHandoff
.
Absent ⇒ not migrated by Track C (#29).
handoffSym]: strategy: HandoffStrategystrategy }) as function (type parameter) T in <T extends HyperlinkTag<any, any, any>>(tag: T, strategy: HandoffStrategy): TT,
);