@zafuru/primitives-craft
v1.0.0-alpha.0
Published
lowcode-ai Craft.js adapter for @zafuru primitives and json-render specs.
Maintainers
Readme
@zafuru/primitives-craft
Bidirectional adapter between @zafuru/primitives specs and Craft.js-style serialized nodes.
This package is maintained in the lowcode-ai monorepo. It was split from the historical source/json-render/packages/primitives-craft path; lowcode-ai is now the maintenance source for this @zafuru/* package.
This package is the bridge layer for low-code editors that use Craft.js as the editing model while keeping json-render spec as the saved and published source of truth.
Install
Current local consumers still use file: / workspace dependencies. The npm command below describes the intended usage after this package is published.
npm install @zafuru/primitives-craft @zafuru/primitivesInstall your editor's Craft runtime separately when needed; this adapter only reads and writes Craft-style serialized data.
What It Does
- Converts a primitives spec into Craft-compatible serialized nodes
- Converts Craft serialized nodes back into a standard
json-render spec - Reuses
@zafuru/primitivesfor component names, props validation, and child constraints - Preserves element-level fields like
on,visible,repeat, andwatch - Leaves props expressions such as
{ $state },{ $bindState },{ $item }, and{ $index }untouched
What It Does Not Do
- No Craft resolver
- No palette or inspector schema
- No preview runtime
- No non-primitives catalog support
Source of Truth
json-render spec remains the only persisted format.
Craft serialized nodes are treated as an editor work model:
spec -> Craft nodes -> edit -> spec
For full-page editor state, use the document helpers:
spec -> Craft document -> edit -> spec
Exports
specToCraftNodescraftNodesToSpecspecToCraftDocumentcraftDocumentToSpecvalidatePrimitiveSpecForCraftvalidateCraftNodesForPrimitiveSpecvalidatePrimitiveCraftDocumentresolvePrimitiveCraftRootId
Serialized Node Shape
The adapter emits a stable serialized node shape:
{
id: "button-1",
data: {
type: "Button",
name: "Button",
displayName: "Button",
props: { label: "Save" },
custom: {
jsonRender: {
id: "button-1",
on: { press: { action: "saveForm" } },
visible: { $state: "/showSave" }
}
},
parent: "screen",
isCanvas: true,
hidden: false,
nodes: [],
linkedNodes: {}
}
}Example
import {
craftDocumentToSpec,
craftNodesToSpec,
specToCraftDocument,
specToCraftNodes,
} from "@zafuru/primitives-craft";
const nodes = specToCraftNodes(spec);
const nextSpec = craftNodesToSpec(nodes);
const document = specToCraftDocument(spec);
const nextSpecWithState = craftDocumentToSpec(document);Validation Rules
- Unknown primitive component types throw
- Props must pass the matching
@zafuru/primitivesschema - Components with
canHaveChildren: falsecannot carry children - Missing
rootor missing child references throw - A node or element cannot be referenced by multiple parents
- Serialized node
parentpointers must stay consistent withnodeschild links - Cyclic child graphs are rejected during import and export
- Multiple implicit roots in serialized nodes throw unless you pass
rootId linkedNodesare currently rejected because the primitives adapter only supports the default child slot
Notes
- The adapter does not resolve or execute dynamic props. It only preserves them.
stateis not serialized into Craft nodes. Use the document helpers when your editor needs to persist page state together with nodes.
