@rsc-kit/mcp 0.26.0 → 0.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/recipes.js +92 -0
- package/dist/recipes.js.map +1 -1
- package/guides/api-routes.md +4 -2
- package/guides/deployment.md +69 -0
- package/guides/go.md +4 -2
- package/guides/laravel.md +25 -1
- package/guides/sections.md +444 -40
- package/guides/your-own-backend.md +1 -1
- package/package.json +1 -1
package/dist/recipes.js
CHANGED
|
@@ -1730,6 +1730,39 @@ validates at runtime), move info/servers/security to the option, move a
|
|
|
1730
1730
|
route's summary/tags/responses to its openapi export.
|
|
1731
1731
|
|
|
1732
1732
|
Full guide: read_guide({ slug: 'openapi' }).`,
|
|
1733
|
+
},
|
|
1734
|
+
{
|
|
1735
|
+
topic: 'secrets',
|
|
1736
|
+
summary: 'The secrets rsc-kit reads - RSC_HOST_CALL_SECRET, RSC_SIGNING_SECRET, RSC_ACTION_ENCRYPTION_KEY - what each protects, how to generate them, where they go in production, and what rotating one does',
|
|
1737
|
+
body: `Three, each its own key for its own job. Never reuse one as another.
|
|
1738
|
+
|
|
1739
|
+
RSC_HOST_CALL_SECRET renderer <-> Go/Laravel backend calls. Required with a
|
|
1740
|
+
backend; read by the renderer AND the backend.
|
|
1741
|
+
RSC_SIGNING_SECRET signs refreshOn names a page hands the tab. Required in
|
|
1742
|
+
production when any page/section uses refreshOn (the
|
|
1743
|
+
server refuses to serve without it). Renderer only.
|
|
1744
|
+
Never falls back to the host-call secret.
|
|
1745
|
+
RSC_ACTION_ENCRYPTION_KEY optional: pins the key server actions encrypt with, so
|
|
1746
|
+
actions survive a deploy. Set at BUILD time too.
|
|
1747
|
+
|
|
1748
|
+
GENERATE - once each, a different value each:
|
|
1749
|
+
openssl rand -base64 32
|
|
1750
|
+
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
|
|
1751
|
+
php -r "echo base64_encode(random_bytes(32)), PHP_EOL;"
|
|
1752
|
+
Development: create-rsc-kit / rsc-kit init (with a backend) and
|
|
1753
|
+
php artisan rsc:install write the first two into .env already.
|
|
1754
|
+
|
|
1755
|
+
PRODUCTION - in the platform's environment settings, never in git:
|
|
1756
|
+
- the SAME value on every instance (a tab served by one renderer is checked by
|
|
1757
|
+
another; a call may land on any backend replica);
|
|
1758
|
+
- read at runtime, so one build deploys anywhere (except the action key).
|
|
1759
|
+
|
|
1760
|
+
ROTATING is a deploy:
|
|
1761
|
+
- host-call: change renderer and backend together; between them every rpc() is refused.
|
|
1762
|
+
- signing: open pages stop refreshing until reloaded; nothing else breaks.
|
|
1763
|
+
- action key: actions from pages loaded before the change fail.
|
|
1764
|
+
|
|
1765
|
+
Docs: /hosts/deployment#secrets.`,
|
|
1733
1766
|
},
|
|
1734
1767
|
{
|
|
1735
1768
|
topic: 'env',
|
|
@@ -1792,6 +1825,65 @@ SAY IT CHANGED - wherever the change happens, not only in an action:
|
|
|
1792
1825
|
Go: reg.Changed(ctx, "team:"+teamID+":repos") // the webhook handler, a job
|
|
1793
1826
|
Laravel: Rsc::changed("team:$teamId:repos"); // a controller, a job, a listener
|
|
1794
1827
|
JS only: import { changed } from '@rsc-kit/core/changed'; await changed(\`team:\${team}:repos\`)
|
|
1828
|
+
ANY DATABASE - rsc-kit ships no driver; hand it yours. Postgres:
|
|
1829
|
+
postgresVersions(sql) (postgres.js/Bun.sql). MySQL/MariaDB: sqlVersions({
|
|
1830
|
+
query: async (t, p) => (await pool.query(t, p))[0] }) (mysql2). SQLite:
|
|
1831
|
+
sqlVersions({ query: async (t, p) => db.query(t).all(...p) }). libSQL/Turso:
|
|
1832
|
+
sqlVersions({ query: async (sql, args) => (await client.execute({ sql, args })).rows }).
|
|
1833
|
+
Redis/ORM query builders: createVersions({ read, bump, listen?, notify? }).
|
|
1834
|
+
Instant across instances: postgres.js LISTEN, Redis pub/sub; others within ~1s.
|
|
1835
|
+
NO BACKEND (JS only) - changed() works as-is on one server. With more than
|
|
1836
|
+
one instance, or a worker process that finishes jobs, keep versions in a
|
|
1837
|
+
table they all share: installVersionSource(postgresVersions(sql)) in
|
|
1838
|
+
instrumentation.ts register() AND in the worker (postgres.js LISTENs, so
|
|
1839
|
+
cross-instance changes are instant; Bun.sql polls once a second; any SQL
|
|
1840
|
+
driver/ORM: sqlVersions({ query }) - Prisma: query: (t, p) =>
|
|
1841
|
+
prisma.$queryRawUnsafe(t, ...p); anything else (Drizzle query builder, Redis,
|
|
1842
|
+
KV): createVersions({ read(names), bump(names), listen?, notify? }) and
|
|
1843
|
+
rsc-kit does the waiting/waking). An app-installed store always wins over a
|
|
1844
|
+
backend's. In-memory versions fail with 2+ instances; in production rsc-kit logs a
|
|
1845
|
+
warning once when it falls back to them - installVersionSource(memoryVersions())
|
|
1846
|
+
says "one instance on purpose" and silences it.
|
|
1847
|
+
Table: rsc_versions(name TEXT PRIMARY KEY, version BIGINT NOT NULL) - same as
|
|
1848
|
+
Go's SQLVersions. ANY process can bump without rsc-kit: upsert version + 1
|
|
1849
|
+
(Postgres: ON CONFLICT (name) DO UPDATE SET version = rsc_versions.version + 1;
|
|
1850
|
+
then NOTIFY rsc_versions).
|
|
1851
|
+
TABLE - the app owns rsc_versions (rsc-kit never creates/alters it at
|
|
1852
|
+
runtime): name TEXT PRIMARY KEY (MySQL: VARCHAR(255)), version BIGINT NOT
|
|
1853
|
+
NULL. Extra columns fine if they have defaults. Drizzle: a pgTable in your
|
|
1854
|
+
schema + createVersions with the query builder (not raw SQL).
|
|
1855
|
+
BUN / no LISTEN - keep Bun.sql (or Drizzle over it) for read/bump and open one
|
|
1856
|
+
postgres.js connection ({ max: 1 }) only for listen/notify in createVersions:
|
|
1857
|
+
instant across instances.
|
|
1858
|
+
AFTER COMMIT - call changed() AFTER the transaction resolves, never inside
|
|
1859
|
+
it: a tab refreshes at once and would read the old data, then sit at the new
|
|
1860
|
+
version. Laravel: DB::afterCommit(fn () => Rsc::changed(...)).
|
|
1861
|
+
SAME NAME - many sections/pages may refresh on one name; one changed() moves
|
|
1862
|
+
it once and every tab refreshes what it shows. Section names are per page.
|
|
1863
|
+
STARTUP - assertSigningSecret() from @rsc-kit/core/changed in
|
|
1864
|
+
instrumentation.ts register() makes a deploy without the secret fail before
|
|
1865
|
+
taking traffic (Kubernetes readiness); otherwise it is refused on the first
|
|
1866
|
+
request.
|
|
1867
|
+
SECRET - set RSC_SIGNING_SECRET, the same on every instance, with or without
|
|
1868
|
+
a backend (NOT the host-call secret). In production an app using refreshOn
|
|
1869
|
+
refuses to serve without it. Names are signed per request, never at build.
|
|
1870
|
+
REQUEST - a refreshOn function runs per request: cookies()/headers() work,
|
|
1871
|
+
e.g. a name for the signed-in user.
|
|
1872
|
+
SHARED - section(name, C, { refreshOn, shared: true }) for a section that
|
|
1873
|
+
renders the same for everyone allowed to see the page: tabs refreshing
|
|
1874
|
+
because of the same change share ONE render (guards still run per tab).
|
|
1875
|
+
Never on per-visitor content - rpc() runs with the first visitor's session.
|
|
1876
|
+
LARAVEL AT SCALE - RSC_VERSIONS=database (publish rsc-migrations) and
|
|
1877
|
+
installVersionSource(postgresVersions(sql)) in the renderer: watching costs
|
|
1878
|
+
PHP zero requests; Postgres NOTIFY makes it instant.
|
|
1879
|
+
DEBUG - dev console lists what each region watches; a region missing there
|
|
1880
|
+
rendered no names (server log says why). Hidden tabs stop watching and catch
|
|
1881
|
+
up when shown.
|
|
1882
|
+
COST - per visible tab one SSE connection (keepalive every 8s - set
|
|
1883
|
+
RSC_STREAM_KEEPALIVE_MS lower if a server/proxy drops idle connections sooner;
|
|
1884
|
+
~40 bytes
|
|
1885
|
+
per change); per change one refresh of just the sections showing the name;
|
|
1886
|
+
per server one versions read covering all its tabs.
|
|
1795
1887
|
HOW - a name has a version, a number that moves when it is said to have
|
|
1796
1888
|
changed; nothing else travels. The page learns versions at render, one SSE
|
|
1797
1889
|
stream per tab (only on a page with names) watches them, and a moved version
|