Wocart

Public API surface

This page is the curated map of @wocart/theme 4.1.0: what each entry point exports, what it is for, and what is not part of the contract. The generated reference has every signature; this page tells you which ones to reach for.

TerminalCode
npm install --save-exact @wocart/theme@4.1.0 @wocart/storefront@3.1.0
ImportRuns inHolds
@wocart/themeBrowser and serverDefinitions, validation, documents, operations, settings, copy, style, manifest, preview protocol — no Astro, no I/O
@wocart/theme/astroServer and buildThe read cache, the manifest and stylesheet endpoints, slot and preview helpers
@wocart/theme/astro/InstanceView.astroServer and buildThe reference renderer
@wocart/theme/astro/Blocks.astro, Block.astroServer and buildA slot's blocks, one fixed block
@wocart/theme/astro/ThemeStyles.astroServer and buildStylesheet link and color-scheme CSS
@wocart/theme/image-serviceBuildmediaImageService for Astro's image.service
@wocart/theme/previewBrowserstartPreviewBridge for a theme's preview page
@wocart/theme/lifecycleBrowserbindEach, onEachPage: browser behaviour that survives page and section swaps
@wocart/theme/messagesBrowserformatMessage and the plural helpers, without the rest of the contract

The root entry imports no Astro module and performs no I/O, so it runs in a unit test or a script. Validation belongs on the server or in the build: a schema in a shopper's page ships Zod to every visitor.

Definitions and validation

ExportWhat it does
defineComponent(definition)Identity helper: keeps field literals, types load from the fields, types the component's props
defineTheme(definition)Identity helper for the catalog
defineCapabilities(capabilities)A shared capabilities constant, typed so defineComponent keeps inferring its fields
componentsOf(theme)A theme's components as definitions, in catalog order — what a test or a tool iterates
validateThemeDefinition(theme, options?)Assembly check: key/type agreement, fields, slots, blocks, presets, documents, content keys, order-form guarantee. [] is the only pass
themeManifest(theme)The serializable manifest; drops component and load
validateThemeManifest(input)Boundary for JSON: serializability, structure, then the same relational rules. { manifest, issues }
manifestCatalog(manifest)A ThemeDefinition with component: null — for editing and validation, never for rendering
diffThemeManifests(previous, next){ breaking, additive } between two releases
THEME_SDK_VERSIONThe package version the manifest records ("4.1.0")
THEME_MANIFEST_CONTRACT_VERSIONVersion of the manifest format (1)
THEME_MANIFEST_PATH/wocart-theme.json
THEME_KEY_PATTERNThe rule a theme key follows: lowercase kebab-case, at most 64 characters

validateThemeDefinition takes one option: contentKeys, the key set every contentKey must exist in. Passing an empty array is meaningful — it enables the check and reports every declared key.

Documents and instances

ExportWhat it does
parsePageData(input)Read a saved document forgivingly: { page, issues }; page is null only for a broken envelope
validatePageData(theme, input, scope?)The same read against a catalog, adding unknown-type and slot gating
resolveInstance(definition, instance, scope?)One instance → { props, children, slots, fixed, issues }; the renderer's core
createInstance(definition, id, props?)Materialize an instance; throws on unknown keys, wrong types and unfillable required fields
checkFieldValue(field, value)Writer check for one value: { ok: true, value } or { ok: false, message }
resolveSurfaceDocument(theme, surface, saved, scope?)Which document renders, completed: { page, source, reason, issues }
completePage(theme, page)Add every fixed and required block; { page, issues }
isFieldVisible(field, values)Evaluate a field's visibleIf against sibling values — editors only
CONDITION_DEPTHHow deep a condition may nest (4)

Document operations

Writers — an editor, a script, an agent — change documents through these. Each returns { ok: true, page } or { ok: false, issue }, and none mutates its input.

ExportWhat it does
insertInstance(theme, page, instance, placement?)Place a new instance at { parent?, slot?, index? } (no parent: a top-level section)
moveInstance(theme, page, id, placement?)Re-place an existing instance
duplicateInstance(theme, page, id, newId)Copy an instance and its tree, taking fresh ids from newId
setInstanceProps(theme, page, id, changes)Merge props, checking each against its field
setInstanceHidden(theme, page, id, hidden)Hide or show, refusing for fixed and required blocks
removeInstance(theme, page, id)Delete an instance and its tree, refusing when composition requires it
findInstance(page, id){ instance, parent, slot, index, depth, fixed? } or null
newInstanceId()cmp_ plus 16 hex digits
checkPageData(theme, input)Every issue a writer must fix before saving: DocumentIssue[]
setAreaHidden(theme, page, key, hidden)Leave an area (the header, the footer) out of this page, or bring it back; only an area the surface lists in hideableAreas

Every operation takes the theme first: without it, a writer could not know a slot's required types or a block that must stay shown.

Composition

ExportWhat it does
instantiatePreset(theme, type, key, newId)Build a preset's instances
isInsertableOn(component, surface)Whether capabilities offer it here — advisory, enforced at insertion
COMPONENT_PLACEMENTS["section", "block", "both"]
COMPONENT_ROLES["order-form"]
THEME_LIMITS{ slotInstances: 50, sections: 50, documentInstances: 1000, depth: 6 }
areaSurface(key)"area:header": the surface an area's document is stored under
landingSurface(id)"lp:<id>": the surface one landing page's own document is stored under
templateSurface(surface)The surface a document follows: "landing" for an lp: surface, else the surface itself
LANDING_TEMPLATE"landing": the surface every landing page's document follows
hideableAreas(theme, surface)The areas a page of that surface may leave out
isAreaShown(theme, page, key)Whether a page shows an area, after its hiddenAreas
fixedBlockId(ownerId, name)The id a fixed block renders with when the document does not store it

Settings and copy

ExportWhat it does
resolveThemeSettings(theme, stored, scope?)Effective settings: { values, issues }, typed by InferSettings
checkThemeSettings(theme, values)Writer check: every key declared, every value accepted, each colorScheme naming a real scheme
resolveThemeContent(theme, locale, overrides, options?)The theme's words for one page: its pack for the language (else the default's), with the merchant's text edits of the pack's own keys for that language only
localize(value, locales)A LocalizedText in the first language that has one
formatMessage(pack, key, values, { locale, formatNumber? })Placeholders and CLDR plurals from a content pack; locale is required
pluralMessageKeys(pack)The base keys of every plural message in a pack
messageForms(pack, key)The CLDR forms a message key defines
pluralFormIssues(pack, locale)Forms the language needs but the pack lacks, or carries unused
PLURAL_CATEGORIESCLDR's six categories

Rich text

ExportWhat it does
richTextToHtml(document, { href?, inline? })Escaped HTML (p, h2–h4, ul/ol, strong, em, u, s, a, br), safe for set:html; unsafe links are dropped
richTextToPlainText(document)The words only, one block per line — for a meta description or an aria-label
RICH_TEXT_FORMATSThe seven formats a richtext field may allow, in editor order

Style

ExportWhat it does
styleClasses(value)The classes for a style value
schemeClass(scheme), SCHEME_MARKER_CLASSwc-scheme wc-scheme-<id>: the shared marker a theme derives its tokens on, and the scheme's own class — "" for no scheme
themeStyleSheet(style)The stylesheet of every class the theme's sizes allow
colorSchemeCss(schemes)Custom properties per scheme
contrastRatio(a, b)WCAG contrast ratio between two hex colors
STYLE_STEPS, STYLE_WIDTHS, STYLE_PANELS, STYLE_BREAKPOINTSThe platform's style vocabulary
COLOR_ROLES, COLOR_SCHEMES_MAXThe seven roles, and 24 schemes per store
THEME_STYLES_PATH/wocart-styles.css

Preview protocol

ExportWhat it does
previewStartMarker(instance), previewEndMarker(instance)The comment markers the renderer brackets an instance with in a preview
parsePreviewMarker(text)Read a marker back
PREVIEW_PROTOCOL_VERSION, THEME_PREVIEW_PATHProtocol version (1) and /wocart-preview

@wocart/theme/astro

ExportWhat it does
createReadCache()One ReadCache per page render: the first call for a key runs the loader, later calls reuse the settled value and its rejection
themeManifestEndpoint(theme)A GET handler for the prerendered manifest; throws at module load when the manifest is invalid
themeStylesEndpoint(theme)A GET handler for the style classes, text/css
hasBlocks(blocks, slot?)Whether a slot holds a block that renders — skip an empty wrapper
isPreview(blocks)Whether this render is an editor's preview; placeholders belong there only
previewTarget(theme, draft, client)What an editor's preview shows: the surface, its page type, the area edited, the route's parameters and the document — null for a surface the theme does not compose
BlocksHandle, RendererIssueThe blocks prop a component receives, and the renderer's issue shape
resolveInstance, THEME_LIMITS, THEME_STYLES_PATH, colorSchemeCss, previewStartMarker, previewEndMarkerRe-exports of the root module, so a co-located import resolves in the source and dist layouts

The four components: InstanceView.astro (the renderer), Blocks.astro (<Blocks of={blocks} slot="info" />), Block.astro (<Block of={blocks} name="gallery" />) and ThemeStyles.astro (<ThemeStyles schemes={settings.colorSchemes} />).

@wocart/theme/image-service and /preview

ExportWhat it does
mediaImageService(delivery)An Astro image service that resizes store images with the store's media delivery (ImageKit or Cloudflare) and passes every other image, and every image of a direct delivery, through; delivery is a function read on every image, answering config.media (or a promise of it)
mediaImageParams(options)The resize parameters the service asks mediaImageUrl for, from an Astro transform
startPreviewBridge({ editorOrigin, token, endpoint?, window? })The browser side of a preview page: markup patches, hover/select messages, re-render requests. Returns { stop() }
PREVIEW_SECTION_LOAD_EVENT"wocart:section-load" — dispatched per section the bridge swapped in

@wocart/theme/lifecycle and /messages

The two browser entries: tiny, Zod-free, and safe on every shopper's page.

ExportWhat it does
bindEach(selector, bind, options?)Binds every matching element once — on load, after Astro's router swaps the page, after an editor's preview swaps a section in. A bind may return a teardown
onEachPage(boot, options?)Runs a page's behaviour once per page, its teardown before the page is swapped out
PREVIEW_SECTION_LOAD_EVENT"wocart:section-load", without the bridge: a theme never names the swap events itself
formatMessage(pack, key, values?, { locale }), messageForms(pack, key), pluralMessageKeys(pack)A message from the copy, its plural form chosen by count (/messages)

Types you will name

GroupTypes
CatalogThemeDefinition, ComponentDefinition, SurfaceSpec, AreaSpec, SurfacePageType, LocalizedText, ThemeStyle, SettingsGroup
FieldsFieldDefinition and its per-kind interfaces, FieldValue, FieldValues, InferProps, InferSettings, MediaReference, ResolvedImage, RichTextValue, StyleValue, ColorScheme
DocumentsPageData, ComponentInstance, PageDataResult, PageDataIssue, PageDataIssueCode, ResolvedInstance, ResolutionScope
RenderingThemeRenderContext, LoadContext, LoadFn, ReadCache, BlocksHandle, RendererIssue
WritingDocumentEdit, DocumentIssue, DocumentIssueCode, InstanceLocation, InstancePlacement
ManifestThemeManifest, ThemeManifestResult, ManifestDiff, ManifestChange
SettingsThemeSettingsResult, ThemeSettingsIssue, ThemeSettingsIssueCode

What is not public

dist/… and src/… deep paths are implementation. ComponentDefinition.component and .load are code and never serialized; manifestCatalog returns definitions without a component, so it is for editing, not rendering. The theme's key is part of the contract: renaming it orphans merchant edits.

Version

THEME_SDK_VERSION must equal the installed package.json version — the package check refuses a release where they differ. A manifest records it, so an editor knows what the theme's renderer reads. See Production and upgrades for the peer ranges and the upgrade checklist.