AbsoluteJS

@absolutejs/sync-pack-mentions

@absolutejs/sync-pack-mentionsv0.1.4betaData & Sync

@mention parser pack for @absolutejs/sync — extracts @usernames from a body, writes per-actor mention rows, fires an onMention hook that composes with the notifications pack

#Installation

BASH
bun add @absolutejs/sync-pack-mentions

#Capabilities

Overview

@username parser pack for @absolutejs/sync. Owns a mentions table, parses bodies for @usernames, writes per-actor mention rows, and fires an onMention hook the host wires into other packs.

The onMention hook is the seam. Packs in @absolutejs/sync-packs never call each other's mutations directly; the host wires them together. This pack provides the parser + the collection; you decide whether mentions fire notifications, emails, Slack pings, or anything else.

Surface

ownsTables — mentions

Collections — mentions (per-actor view, filterable by sourceKind / unresolvedOnly)

Mutations — mentions:record { sourceKind, sourceId, body, authorId? }, mentions:resolve { id }, mentions:dismiss { id }

Show 1 more

Permissions — only the mentioned actor reads, updates, deletes their rows; insert is host-trusted (the pack itself writes on the author's behalf)

Composition pattern

The host calls mentions:record right after its own post mutation succeeds, then onMention fires once per parsed mention. From inside the hook, the host can engine.runMutation('notifications:notify', …) to compose with @absolutejs/sync-pack-notifications.

Mention rows are idempotent ((sourceKind, sourceId, mentionedActorId) is the primary key), so re-calling mentions:record on an edit of the same source body does not re-fire onMention for the same target. Self-mentions are skipped automatically.

Outcomes

What you can build

Build on the supported package contract

Use @absolutejs/sync-pack-mentions through its supported public entry points.

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/sync-pack-mentions version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/sync-pack-mentions example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#@absolutejs/sync-pack-mentions quick start

Partial snippet

# @absolutejs/sync-pack-mentions

TS
import { createSyncEngine } from '@absolutejs/sync/engine';
import { createMentionsPack } from '@absolutejs/sync-pack-mentions';

const engine = createSyncEngine();

engine.registerPack(
  createMentionsPack({
    getActorId: (ctx) => ctx.session.userId,
    resolveActorId: async (username) => userIdByUsername(username),
    onMention: async ({ mention }, ctx) => {
      await engine.runMutation(
        'notifications:notify',
        {
          targetActorId: mention.mentionedActorId,
          kind: 'mention',
          title: 'You were mentioned',
          body: mention.snippet,
          href: `/comments/${mention.sourceId}`,
        },
        ctx,
      );
    },
  }),
);

#Public entry points

Supported entry points declared by this package manifest.

Package entry point declared in package.json.

@absolutejs/sync-pack-mentions@absolutejs/sync-pack-mentions/manifest@absolutejs/sync-pack-mentions/manifest.json

#Package commands

Scripts declared by this package manifest.

bun run buildrm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit
bun run formatprettier --write "./**/*.{ts,json,md}"
bun run testbun test
bun run typechecktsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

8 symbols
MentionRowtypePermalinkSource

One row per (sourceKind, sourceId, mentionedActorId).

TS
type MentionRow = {
    /** `${sourceKind}:${sourceId}:${mentionedActorId}` — deterministic so re-recording is idempotent. */
    id: string;
    /** Host-level category for the row that originated the mention ("comment", "doc", "task", …). */
    sourceKind: string;
    /** Host-level id of the row that originated the mention. */
    sourceId: string;
    /** Who wrote the body containing the mention. `null` for system-generated content. */
    authorId: string | null;
    /** The actor id the `@username` resolved to. */
    mentionedActorId: string;
    /** The raw username text (without the `@`). */
    username: string;
    /** A short excerpt of the body around the mention — useful for inbox previews. */
    snippet: string;
    createdAt: number;
    /** Stamped by `mentions:resolve` (host's onMention hook is free to call it). */
    resolvedAt: number | null;
};
Exported from @absolutejs/sync-pack-mentions