wasl-flow
v1.0.1
Published
Wasl Flow: a framework-agnostic, schema-validated renderer for dynamic content models
Maintainers
Readme
wasl-flow (core)
The core package of Wasl Flow. It provides the abstract renderer, shared types, and base content type definition used by all renderers.
Install
npm install wasl-flow
# or
pnpm add wasl-flowWhat This Package Provides
AbstractRenderer: the framework-agnostic renderer and type dispatcher.AbstractContentTypeDefinition: a reusable bundle oftype,parse, andfactory.- Core types:
ContentModel,ContentModelParser,ComponentFactory,RenderError, andRendererConfiguration.
Quick Start
Use the core directly when you are building your own renderer or rendering layer.
import {
AbstractContentTypeDefinition,
AbstractRenderer,
type ContentModelParser,
type ComponentFactory,
type RenderError,
} from 'wasl-flow';
type HeroModel = {
type: 'hero';
title: string;
subtitle?: string;
};
type ButtonModel = {
type: 'button';
label: string;
};
class HeroDefinition extends AbstractContentTypeDefinition<HeroModel> {
constructor() {
super('hero');
}
parse: ContentModelParser<HeroModel> = model => ({ data: model as HeroModel });
factory: ComponentFactory<HeroModel> = ({ model, renderContent }) => {
const cta = renderContent({ type: 'button', label: 'Get started' }) as string;
return `<section class="hero"><h1>${model.title}</h1><p>${model.subtitle ?? ''}</p>${cta}</section>`;
};
}
class ButtonDefinition extends AbstractContentTypeDefinition<ButtonModel> {
constructor() {
super('button');
}
parse: ContentModelParser<ButtonModel> = model => ({ data: model as ButtonModel });
factory: ComponentFactory<ButtonModel> = ({ model }) => {
return `<button class="btn">${model.label}</button>`;
};
}
class HtmlStringRenderer extends AbstractRenderer {
protected aggregateArrayOutputs(outputs: unknown[]): string {
return outputs.filter(Boolean).join('');
}
protected renderValidationError(error: RenderError): string {
return `<pre class="error">${error.type}: ${error.message}</pre>`;
}
}
const renderer = new HtmlStringRenderer({
showValidationErrors: true,
onRenderError: error => {
console.error('Renderer error', error);
},
});
renderer.register(new HeroDefinition());
renderer.register(new ButtonDefinition());
const html = renderer.render({
type: 'hero',
title: 'Welcome',
subtitle: 'Build once, render anywhere.',
});How Rendering Works
- The renderer uses
typeField(defaulttype) to find the matching registration. parsevalidates and normalizes the model. Return{ data, error }to signal validation failure.factoryreceives the validatedmodeland arenderContenthelper for nested content.- Errors are either rendered (when
showValidationErrorsis true) or replaced withnullValue. - Default rendered error payloads are sanitized and do not include raw models or internal error objects.
Configuration
You can configure rendering and safety behavior through RendererConfiguration:
typeField(defaulttype): field name used to identify a model type.nullValue(defaultnull): value returned when rendering fails or model is null/undefined.showValidationErrors(defaultfalse): render error details instead ofnullValue.allowDuplicateRegistrations(defaultfalse): allow overrides of existing registrations.maxRenderDepth(default50): maximum recursive render depth.maxRenderNodes(default1000): maximum number of nodes per render traversal.onRenderError(defaultnull): optional callback for reporting/logging full internal error details.
Errors And Safety Limits
Possible render error types are:
MISSING_TYPE_FIELDUNREGISTERED_TYPEVALIDATION_ERRORFACTORY_ERRORRENDER_LIMIT_EXCEEDED
Safety limits guard against infinite recursion and large trees. Cycles are detected by object reference.
When To Use The Core Directly
Use wasl-flow directly when you need to build a new framework renderer or you want a custom renderer. Otherwise, use a renderer from @wasl-flow/*.
Related Packages
@wasl-flow/react@wasl-flow/vue@wasl-flow/vanilla@wasl-flow/jquery
