Hyperlinkv0.8.0-beta.28

Hyperlink

Hyperlink.tagForfunctionsrc/Hyperlink.ts:3099
<const S extends Spec, HSelf>(
  groupId: string,
  spec: S,
  options: {
    readonly description?: string
    readonly kind?: string
    readonly node: AddressedNode<HSelf>
  }
): {
  <Self>(key: string): NodeBoundTag<Self, S, HSelf> & {
    readonly [nodeSym]: AddressedNode<HSelf>
  }
  readonly groupId: string
  readonly description: string | undefined
  readonly [specSym]: FlatSpec
  readonly [specTypeSym]?: S
  readonly [groupSym]: RpcGroupOf<S>
}
<const S extends Spec, HSelf>(
  groupId: string,
  spec: S,
  options: {
    readonly description?: string
    readonly kind?: string
    readonly node: NodeKey<HSelf>
  }
): NodeTagFactory<S, HSelf>
<const S extends Spec>(
  groupId: string,
  spec: S,
  options?: { readonly description?: string; readonly kind?: string }
): TagFactory<S>

Build a factory tag-maker that bakes a shared Spec once under a groupId: every instance shares the same contract + RPC group, and callers never pass the spec — only an instance key. Use for resource families (many instances, one contract). The groupId (e.g. "queue") is the wire prefix for the family's procedures, so a shared RpcServer can node this family next to other resource types without tag collisions; instances are told apart by the per-call key header.

Pass options.node to bind the whole family to a Node: every instance becomes a node-bearing tag and ships only-the-tag (see Hyperlink.client / Hyperlink.connect).

const Queue = Hyperlink.tagFor("queue", { pause: Hyperlink.effect(Schema.Void) });
class Jobs extends Queue<Jobs>("@app/Jobs") {}  // spec baked in; just the instance key
class Mail extends Queue<Mail>("@app/Mail") {}  // shares contract + group, routed by key
constructorsSpecNodeHyperlink.clientHyperlink.connect
Source src/Hyperlink.ts:309955 lines
function tagFor<const S extends Spec, HSelf>(
  groupId: string,
  spec: S,
  options: {
    readonly description?: string;
    readonly kind?: string;
    readonly node: AddressedNode<HSelf>;
  },
): {
  <Self>(key: string): NodeBoundTag<Self, S, HSelf> & {
    readonly [nodeSym]: AddressedNode<HSelf>;
  };
  readonly groupId: string;
  readonly description: string | undefined;
  readonly [specSym]: FlatSpec;
  readonly [specTypeSym]?: S;
  readonly [groupSym]: RpcGroupOf<S>;
};
function tagFor<const S extends Spec, HSelf>(
  groupId: string,
  spec: S,
  options: { readonly description?: string; readonly kind?: string; readonly node: NodeKey<HSelf> },
): NodeTagFactory<S, HSelf>;
function tagFor<const S extends Spec>(
  groupId: string,
  spec: S,
  options?: { readonly description?: string; readonly kind?: string },
): TagFactory<S>;
function tagFor<const S extends Spec>(
  groupId: string,
  spec: S,
  options?: { readonly description?: string; readonly kind?: string; readonly node?: NodeKey<unknown> },
): TagFactory<S> {
  claimGroupId(groupId);
  const group = buildRpcGroup(groupId, flattenSpec(spec));
  const node = options?.node;
  const factory = <Self>(key: string) =>
    buildInstanceTag<Self, S>(
      groupId,
      key,
      spec,
      group,
      options?.description,
      node,
      options?.kind,
    );
  // Stow the shared groupId/description/spec/group on the factory too, so the family
  // server ({@link serveInstances}) can read the contract + prefix without an instance.
  return Object.assign(factory, {
    groupId,
    description: options?.description,
    [specSym]: flattenSpec(spec),
    [groupSym]: group,
  });
}