Enforces @adobe/data/ecs best practices. Use this whenever @adobe/data/ecs is imported, when creating or modifying Database.Plugin definitions, or when working with ECS components, resources, transactions, actions, systems, or services.
Enforces @adobe/data/ecs best practices. Use this whenever @adobe/data/ecs is imported, when creating or modifying Database.Plugin definitions, or when working with ECS components, resources, transactions, actions, systems, or services.
Database.Plugin authoring
Plugins are created with Database.Plugin.create() from @adobe/data/ecs.
Property order (enforced at runtime)
Properties must appear in this exact order. All are optional.
PluginPropertyOrder [
"extends — Plugin, base plugin to extend"
"services — (db) => ServiceInstance, singleton service factories"
"components — schema object, ECS component schemas"
"resources — { default: value as Type }, global resource schemas"
"archetypes — ['comp1', 'comp2'], standard ECS archetypes; storage tables for efficient insertions"
"computed — (db) => Observe<T>, computed observables"
"transactions — (store, payload) => void, synchronous deterministic atomic mutations"
"actions — (db, payload) => T, general functions"
"systems — { create: (db) => fn | void }, per-frame (60fps) or init-only"
]
Constraints {
Properties must appear in this exact order; wrong order throws at runtime
}
Non-persistable values (e.g. HTML elements, DOM refs) must use transient: true — excluded from serialization.
resources
Global state not tied to entities. Use as Type to provide the compile-time type — without it the value is treated as a const literal. See data-modeling.md for patterns.
Factory returning Observe<T> or (...args) => Observe<T>. Receives full db.
computed: {
max: db =>Observe.withFilter(
Observe.fromProperties({
a: db.observe.resources.a,
b: db.observe.resources.b,
}),
({ a, b }) =>Math.max(a, b)
),
},
transactions
Synchronous, deterministic atomic mutations. Receive store and a payload. Store allows direct, immediate mutation of all entities, components, and resources.
General functions with access to the full db. Can return anything or nothing.
UI components that call actions MUST never consume returned values — call for side effects only. Consuming return values violates unidirectional flow (data down via Observe, actions up as void).
Call at most one transaction per action; multiple transactions corrupt the undo/redo stack.
create receives db and may optionally return a per-frame function (60fps) or just initialize values. Always called synchronously when database.extend(plugin) runs.
fn whenCreatingOrModifyingPlugin() {
Constraints {
Verify property order matches (extends, services, components, resources, archetypes, computed, transactions, actions, systems)
Use extends for single-parent; Database.Plugin.combine() for multiple peers
Ensure services only access db.services from extended plugins (not forward references)
Export type *Database = Database.Plugin.ToDatabase<typeof *Plugin> when consumers need typed db access
Follow naming conventions for files, exports, and systems
}
}
Additional resources
data-modeling.md — Components, resources, and archetypes (particle simulation example)