drop-core-serveris the server-side companion to the SDK: it receives the platform's data hooks into a swappable cache, serves reads through a repository with local/remote modes, and renders published store pages from Handlebars templates. The pages in this section are extracted from the package README.
Server-side companion to drop-core-sdk. It turns the data hooks
the backend already emits into a warm local cache, and serves reads from that
cache first — falling back to core (public.content) only when needed.
Three cooperating pieces:
- Hook receiver — accepts the backend's hook POSTs (verifying the
access-seedsignature when configured; the deprecatedaccess_seedspelling is still accepted — nginx drops underscore headers by default) and writes the payload into a cache.WebSite.receiveEventHookis the MULTI-EVENT ingress: one endpoint receives every subscribed kind (data / files / templates / elements / …) and dispatches on thex-drop-eventheader. Anx-drop-updatedordering guard (a{key}#vsidecar in the data cache) drops out-of-order deliveries, so unordered best-effort pushes can never re-warm stale data. Full feed reference: the repo-rootdocs/hooks-and-caching.md. - Cache — a swappable
Cache<T>keyed by${locale}/${collection}/${id}(MemoryCacheby default;RenderCachefor SSR HTML;DiskCache— a Node-only file-per-entry backend for RAM-poor fleets, imported directly fromlib/cache/disk_cache). - Repository — a unified read API with
local/remote/preferLocal/preferRemotemodes over the cache and core.
It re-exports everything from drop-core-sdk (and thus drop-core-lib), so one
import gives you entity types, the SDK, and all server helpers.
Two entity types are owned here rather than by drop-core-lib, because the
core API never types them — they are contracts between this renderer and the
admin UI:
WebTemplateEntity(web/web_template.ts) — the web-builder's HTML/CSS artifact atstore/{sid}/schemas/{schemaId}/templates/{version}, read byWebSiteand listed/edited by the admin Code Studio.TranslationsEntity(web/translations.ts) — one stored translations group document, the input the{{t}}helper's flattener turns into{group}.{leaf}keys; the admin's translations editor writes it.
Both come out of the same drop-core-server import as everything else.
Install & build#
npm install # pulls drop-core-sdk (file:../sdk-js)
npm run build # tsc → lib/Build order in the monorepo: core-lib → sdk-js → sdk-server-js. express
is an optional peer dependency (v4 or v5) — only needed if you use
expressHookRouter.
Unit tests are node:test files beside the sources in src/web/
(compose_module.test.ts, …): npm run build && npm test runs
node --test "lib/web/*.test.js" over the compiled output.
Quick start#
import {
DropCore, getDropCoreInstance,
MemoryCache, HookReceiver, expressHookRouter, DataRepository,
} from 'drop-core-server';
import express from 'express';
// DropCore.start() registers the session; build the instance separately —
// it carries the .public.content facade the repository reads through.
DropCore.start({ store: '*', access_token: TOKEN, target: 'instore' });
const instance = getDropCoreInstance();
const cache = new MemoryCache({ ttlMs: 5 * 60_000 });
const repo = new DataRepository({ cache, instance, mode: 'preferLocal', locale: 'cs_CZ' });
const receiver = new HookReceiver({ cache, privateKey: HOOK_KEY }); // omit privateKey to accept unverified
const app = express();
app.use('/data', expressHookRouter(receiver)); // backend pushes here → cache warms
app.get('/p/:id', async (req, res) => res.json(await repo.get('products', req.params.id)));Configure one store data-hook per locale+collection pointing at
POST /data/:locale/:collection (the receiver recovers the id from
body.id / body.ref), or POST /data/:locale/:collection/:id if your hook
URL includes the id. x-drop-locale / x-drop-collection / x-drop-id headers
override the route params when present — and the router also mounts a
header-driven POST / (the multi-event form: context from headers alone;
non-data kinds no-op-accept there). Consumers wanting the FULL event feed
(files/templates/elements evictions and app-level orders/invoices/forms)
route the store's one multi hook at WebSite.receiveEventHook instead —
see "Multi-event hook ingress" below.