Skip to content

Worker / edge runtime

Import: i18nprune/core/runtime/edge

Workers (Cloudflare Workers, AWS Lambda@Edge-style isolates, Deno Deploy, etc.) impose strict bundle limits, no persistent POSIX filesystem, and no node: modules unless explicitly polyfilled by the platform.

Why runtime/edge exists

ConstraintImpact
Bundle graph auditsPublishable graphs must tree-shake cleanly—accidentally importing runtime/node pulls forbidden node: symbols
Filesystem semanticsReads/writes flow through virtual adapters (KV, R2, ephemeral /tmp, HTTP uploads) rather than raw fs.readFileSync
LifetimeRuns last milliseconds—progress UX differs from CLI

This package targets Tier A workloads first (README.md): validate, review, quality, report ingestion where payloads arrive via HTTP rather than disk scans.

Hosting workers.i18nprune.dev

The apps/workers/i18nprune app packages runtime/edge for Cloudflare Workers. It stores shared project snapshots and shared report documents in a global Durable Object (ProjectStoreDO).

Ingest routes

MethodRouteBodyWho prepares
POST/v1/projectsJSON prepared envelopeHost (CLI share upload, SDK, web)
POST/v1/projects/archivemultipart zip (+ optional configJson)Worker (prepareProjectSnapshotFromArchive, cache OFF)
POST/v1/reports{ document }Host
POST/v1/reports/archivezip (same shape as project)Worker (prepareReportFromArchive)

The worker does not read your repo’s .i18nprune/cache or run long-lived analysis cache on the edge.

Read / delete

MethodRouteReturns
GET/v1/projects/:idMetadata only (timings, localeTags, extraction summary)
GET/v1/projects/:id/snapshotFull cached snapshot (heavy)
DELETE/v1/projects/:idEvict row
GET/v1/reports/:idReport metadata
GET/v1/reports/:id/documentFull ProjectReportDocument
DELETE/v1/reports/:idEvict row

There is no /metadata suffix — the metadata GET is GET /v1/projects/:id (and the report equivalent).

Retention

  • Rows are kept while they receive reads (including metadata GETs).
  • 7 days without reads → idle sweep deletes project:*, report:*, and hash index keys.
  • Missing ids return PROJECT_NOT_FOUND / REPORT_NOT_FOUND with guidance to re-upload (not a separate “expired payload” code).

Upload responses and metadata include expiresAt derived from last access.

Limits and errors

Responses use a structured envelope (success, code, errors[] with code, message, action, optional suggestions).

CodeTypical HTTPaction hint
PAYLOAD_TOO_LARGE / TOO_MANY_FILES / EXTRACTION_LIMIT_EXCEEDED413reduce_payload
PAYLOAD_REJECTED / INVALID_SCHEMA400fix_payload
RATE_LIMITED429retry (per-IP upload quota)
HASH_ALREADY_EXISTS200 + warningReused existing row for same content hash
STORAGE_QUOTA_EXCEEDED507self_host
PROJECT_NOT_FOUND / REPORT_NOT_FOUND404reupload

Force replace: ?force=true or JSON "force": true on ingest skips dedup, deletes the prior row for that content hash, and stores a new id (hash unchanged).

CLI mapping: share command and share issue codes.

Timings on project metadata

GET /v1/projects/:id includes a timing block:

  • preparedAt — payload ready to persist (host prepare or worker zip + extraction finished)
  • requestReceivedAt — worker received the ingest request
  • storedAt — durable object write completed
  • prepare.* — zip parse / analysis / extraction ms (measured or derived)
  • extraction.* — extraction window ISO + duration
  • edge.persistMs — measured DO persist latency

Top-level preparedAt mirrors timing.preparedAt. Older stored rows may still use snapshot uploadedAt; current core reads both.

Privacy

Uploads are prepared snapshots (sanitized zip or JSON envelope) or report JSON — not opaque full-repo uploads. See share for what enters the payload.

API docs and OpenAPI

URLFormatUse
GET /docsSwagger UI (HTML + JS)Interactive exploration in a browser
GET /openapi.jsonOpenAPI 3.0 JSONCrawlers, codegen, CI contract checks without executing Swagger UI
GET /Discovery JSONLists openapi and docs URLs for the deployment

Prefer /openapi.json when you need a machine-readable spec — the /docs shell is JS-rendered and empty to non-browser clients.

Upload access model

Ingest routes (POST /v1/projects, /v1/projects/archive, /v1/reports, /v1/reports/archive) are public with per-IP rate limits (no API key today). Reads and deletes use the returned row id. Prepare payloads locally or via CLI share upload; the worker stores sanitized snapshots only.

Bundle checklist

  1. Run pnpm builds with NODE_OPTIONS=--conditions worker (or host-specific presets) when applicable.
  2. Add CI guards rejecting node: imports on Worker graphs once finalized.

See README.md for tier comparisons and node.md / web.md for sibling adapters.