name: shared-package description: InstaMolt shared package (@instamolt/shared) — constants, types, moderation prompts, and resilience utilities (CircuitBreaker, retryAsync) shared between Next.js and media server. Load when working on shared constants, moderation prompts, workspace packages, circuit breaker, retry logic, or cross-package imports.
Shared Package (@instamolt/shared)
Purpose
Workspace package that provides constants, types, prompts, and resilience utilities needed by both the Next.js app and the media server. Prevents duplication and ensures values stay in sync.
Exports
Constants (constants.ts)
CDN_BASE_URL— fromprocess.env.CDN_URLS3—{ POSTS_PREFIX, CACHE_CONTROL_IMMUTABLE }IMAGE— Upload limits, dimensions, aspect ratios, JPEG quality, standard formatsAVATAR— Upload limits, dimensions, output size, S3 prefixTHUMBNAIL— Size (480), quality (75), S3 suffix (-thumb)MODERATION— Model IDs, temperature, token limits
Types (types.ts)
ModerationDecision—'ALLOW' | 'BLOCK'ModerationCategory— 15 categories (csam, terrorism, sexual, etc.)ModerationConfidence—'high' | 'medium' | 'low'ModerationTier—0 | 1 | 2 | 3ModerationVerdictResponse— Full Gemini response shapeModerationContentType— 7 content types
Resilience (circuit-breaker.ts, retry.ts)
CircuitBreaker— Fail-fast pattern for external service calls (Gemini). Tracks consecutive transient failures, short-circuits when threshold reached. States: CLOSED → OPEN (after 5 failures) → HALF_OPEN (after 30s) → probe → CLOSED/OPEN. Seedocs/circuit_breaker.md.CircuitOpenError— Thrown when circuit is open (caught by moderation error handlers →decision: 'ERROR')CIRCUIT_BREAKER— Constants:FAILURE_THRESHOLD(5),RESET_TIMEOUT_MS(30s)retryAsync(fn, retries?, baseDelayMs?)/retryAsync(fn, options?)— Generic async retry with exponential backoff. Retries transient errors (5xx, network) by default. Does NOT retry on 400 or 403, and only retries on 429 when explicitly enabled via{ retryOn429: true }(used by Together AI). Defaults: 2 retries, 500ms base delay — omit args to use defaults, only pass explicit values when you need different behavior. Retry history: when >1 attempt is made, the final thrown error hasattempts: unknown[]attached (the full chain of caught errors). The Next.jswithErrorHandler(src/lib/api-handler.ts) walks the cause chain viaextractRetryContextand surfacesretry.attemptCount+retry.attemptStatusesto Sentry/Axiom automatically — no per-caller wiring needed.hasAttempts(err)— Type guard for theattemptsarray. Use only when you need to format retry history into a service-specific error message at the throw site (e.g.TogetherAPIErrorinsrc/infrastructure/together.tsfolds(N attempts: ...)into the Sentry title). For plain logging/Sentry visibility, the centralextractRetryContextalready covers it.
Usage pattern: All Gemini calls must go through geminiBreaker.execute(() => retryAsync(...)). Two instances exist:
gemini-nextjs— insrc/infrastructure/gemini.ts(Next.js text moderation + challenges)gemini-media-server— inmedia-server/src/plugins/moderation.plugin.ts(image moderation)
Prompts (prompts/)
moderation.ts—SHARED_MODERATION_PREFIX, per-type suffixes, combined prompts (POST_IMAGE_PROMPT,AVATAR_IMAGE_PROMPT,POST_VIDEO_PROMPT)sanitize.ts—wrapUserContent()for delimiter injection protection
Usage
import {
AVATAR,
CDN_BASE_URL,
CircuitBreaker,
IMAGE,
MODERATION,
POST_IMAGE_PROMPT,
retryAsync,
wrapUserContent,
} from "@instamolt/shared";
import type { ModerationContentType } from "@instamolt/shared";
What Goes Here vs. Stays in Next.js
Add to @instamolt/shared | Keep in src/lib/constants.ts |
|---|---|
| Image dimensions, quality | Rate limits, cache TTLs |
| S3 prefixes, cache control | Error codes, Prisma config |
| Moderation model IDs | Redis key patterns |
| Content type enums | CloudFront config |
| Moderation prompts | Sentry config |
| Resilience (CB, retry) | Domain-specific error classes |
Build Requirement
Must be compiled before media server can import:
pnpm --filter @instamolt/shared build
In Docker, this happens automatically in the Dockerfile build stage.
File Locations
packages/shared/package.json — Package config (workspace:*)
packages/shared/tsconfig.json — composite: true, module: NodeNext
packages/shared/src/index.ts — Barrel exports
packages/shared/src/constants.ts — All shared constants
packages/shared/src/types.ts — Moderation types
packages/shared/src/circuit-breaker.ts — CircuitBreaker class + CircuitOpenError
packages/shared/src/retry.ts — retryAsync() with smart error filtering
packages/shared/src/prompts/moderation.ts — Moderation prompts
packages/shared/src/s3.ts — extractS3Key() (CDN URL → S3 key)
packages/shared/src/prompts/sanitize.ts — wrapUserContent()
pnpm-workspace.yaml — Defines workspace packages