Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
# @suaveplan/i18n-backend-memory - Universal in-memory translation backend for the @suaveplan/i18n family. Backed by Map<locale, Map<namespace, TranslationRecord>> plus a modification ledger; implements the full Backend contract (read, readMulti, save, lastModified). Designed for tests, seeded defaults, and the cache layer of a ChainedBackend. Zero runtime dependencies on @suaveplan/i18n core.
|
||||
|
||||
## Summary
|
||||
|
||||
Universal in-memory translation backend for the
|
||||
`@suaveplan/i18n` family. Backed by `Map<locale, Map<namespace,
|
||||
TranslationRecord>>` plus a modification ledger; implements the full
|
||||
`Backend` contract (`read`, `readMulti`, `save`, `lastModified`).
|
||||
Designed for tests, seeded defaults, and the cache layer of a
|
||||
`ChainedBackend`. Zero runtime dependencies on `@suaveplan/i18n`
|
||||
core.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
<!-- end:auto-docs --> - [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_- [backend](./src/backend/backend.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ - [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_ - [observability](./src/observability/observability.md) — <!-- begin:auto-docs --> _(no submodules)_
|
||||
## Why this exists
|
||||
|
||||
The Wave 5 modular split lifts each backend out of the
|
||||
`@suaveplan/i18n` monolith into its own sibling so consumers can
|
||||
install only the backends they need (matching the `crypto-*` /
|
||||
`drive-*` / `network-plugin-*` granularity established elsewhere in
|
||||
the project). The in-memory backend is the simplest and most
|
||||
universal of the five — it has zero external runtime deps, runs
|
||||
identically in browser and server, and is the canonical seed source
|
||||
for every other backend's tests.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/i18n-backend-memory
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```ts
|
||||
import { memoryBackend } from "@suaveplan/i18n-backend-memory";
|
||||
|
||||
const backend = memoryBackend({
|
||||
seed: {
|
||||
en: { common: { hello: "Hello" } },
|
||||
fr: { common: { hello: "Bonjour" } },
|
||||
},
|
||||
});
|
||||
|
||||
const enCommon = await backend.read("en", "common");
|
||||
// { hello: "Hello" }
|
||||
|
||||
await backend.save("en", "auth", { login: { title: "Sign in" } });
|
||||
const t = await backend.lastModified("en", "auth"); // number (ms)
|
||||
```
|
||||
|
||||
## Modules
|
||||
|
||||
| Subpath | Description |
|
||||
|---|---|
|
||||
| `@suaveplan/i18n-backend-memory` | Root barrel — class + factory + types + schemas + observability |
|
||||
| `@suaveplan/i18n-backend-memory/backend` | `MemoryBackend` class only |
|
||||
| `@suaveplan/i18n-backend-memory/factory` | `memoryBackend` factory function only |
|
||||
| `@suaveplan/i18n-backend-memory/schemas` | Zod boundary schemas |
|
||||
| `@suaveplan/i18n-backend-memory/observability` | OTel instruments + in-memory state ring |
|
||||
|
||||
## Modules Documentation
|
||||
|
||||
- [backend.md](src/backend/backend.md) — `MemoryBackend` class + capability matrix
|
||||
- [factory.md](src/factory/factory.md) — `memoryBackend` factory function
|
||||
- [observability.md](src/observability/observability.md) — OTel instruments + metric names + cardinality
|
||||
|
||||
## Capabilities
|
||||
|
||||
| Flag | Value | Notes |
|
||||
|---|---|---|
|
||||
| `canRead` | `true` | always — every backend reads |
|
||||
| `canReadMulti` | `true` | bulk-load O(N) over the namespace map |
|
||||
| `canSave` | `true` | persists into the in-memory store |
|
||||
| `canTrackModification` | `true` | injectable `now()` clock |
|
||||
| `canWatch` | `false` | no reactive `loaded` events |
|
||||
|
||||
## Testing
|
||||
|
||||
The package's own tests use the shared `runBackendConformance`
|
||||
harness from `@suaveplan/i18n-shared/testing` so the universal
|
||||
`Backend` contract is exercised against a fresh in-memory backend
|
||||
per assertion:
|
||||
|
||||
```ts
|
||||
import { runBackendConformance } from "@suaveplan/i18n-shared/testing";
|
||||
import { MemoryBackend } from "@suaveplan/i18n-backend-memory";
|
||||
|
||||
runBackendConformance("MemoryBackend", async () => {
|
||||
const backend = new MemoryBackend();
|
||||
return {
|
||||
backend,
|
||||
async seed(locale, namespace, record) {
|
||||
await backend.save(locale, namespace, record as never);
|
||||
},
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
This package is part of the i18n modular-split rollout. Stays at
|
||||
`0.1.0` until the slim core (Wave 6) cuts the family `1.0.0`
|
||||
release. The metric names under `i18n.backend.memory.*` are part of
|
||||
the public API contract and will not change without a major bump.
|
||||
|
||||
## Wave 5 Scope
|
||||
|
||||
This package is Wave 5a of the 14-package i18n modular split. It
|
||||
ships pure additions only — `packages/i18n/i18n/src/core/backend/memory/`
|
||||
retains its copy of the backend until Wave 6 deletes it. Both copies
|
||||
coexist during Wave 5; downstream consumers continue to import from
|
||||
the monolith and observe no behaviour change.
|
||||
|
||||
Reference in New Issue
Block a user