API reference / @jsprismarine/content
@jsprismarine/content
The runtime every content domain is built on. Blocks, items and entities each get their own package; this one holds the parts they all need and knows nothing about any of them.
That split is the whole point. Nothing here names a block, an item or a hook. A domain supplies its own hook map, its own component factories and its own reader for the shape of its JSON, and gets registries, tags, component resolution, hook dispatch and load-time flattening back.
The three layers
Content moves through three layers, in this order, and the code uses these names.
A definition is parsed, validated, immutable JSON for one identifier. @jsprismarine/packs produces them from a pack stack and its Definition is assignable to the one declared here. The shape is accepted structurally rather than imported, because a domain can also build types from data that never passed through a pack, such as the Java Edition jar dump behind the block property table.
A type is a definition resolved once at load. resolveTypes parses each component's value through its factory's schema, binds the handlers, attaches the behaviors registered for that identifier, builds the dispatch table and computes the flags the domain asked for. After that a type answers questions without parsing anything.
An instance is one live thing of a type: an item stack or an entity, holding a reference to its type plus whatever state the domain keeps per instance. A block in chunk storage is deliberately not an instance. It is a runtime id, and the hot path reads a flattened array instead.
Registries and holders
A Registry<T> is a named table keyed by namespaced identifier, with a dense numeric id per entry. Ids run from 0 in insertion order. They are positional, not persistent: rebuilding with the same keys in the same order reproduces every id, and rebuilding with a different order renumbers from 0. So persist keys rather than ids.
To keep a reference across a content reload, take a Holder<T> instead. A holder resolves by key every time, so after a reload it reads the new value and the new id, and a holder whose key the reload dropped reports that rather than going stale. registry.holder(key) returns the same object for the same key, including for a key no build has introduced yet.
import { Registry } from '@jsprismarine/content';
const blocks = new Registry<BlockType>('blocks');
blocks.rebuild(types); // a ReadonlyMap, an array of pairs, anything iterable
const stone = blocks.holder('minecraft:stone');
stone.id; // 0
stone.value(); // throws while unboundTags
Tags<T> holds the tag files of a whole pack stack for one registry. Merging follows Java Edition's rule: a later file appends to the tag unless it sets replace, which drops everything earlier packs contributed. A #namespace:tag member expands to that tag's own members, transitively.
A reference that closes a cycle is dropped and reported as a tag.cycle diagnostic rather than thrown, so one bad pack cannot stop a load. Build the registry before the tags, because resolution reports a required member the registry does not have. Members are holders, so the resolved sets follow a later registry rebuild on their own.
Components and behaviors
A component is one documented component name bound to a parameter schema and a set of hooks. The schema is a plain function, so a domain can inject whatever checking it already has. It runs once per type at load, and the factory turns the parsed parameters into handlers.
import { accepted, type ComponentFactory, ComponentRegistry, rejected } from '@jsprismarine/content';
interface BlockHooks {
onPlace: (position: Vector3) => void;
onInteract: (player: Player) => boolean | undefined;
}
const friction: ComponentFactory<BlockHooks, number> = {
name: 'minecraft:friction',
hooks: [],
schema: (value) => (typeof value === 'number' ? accepted(value) : rejected('expected a number')),
create: () => ({})
};
const components = new ComponentRegistry<BlockHooks>();
components.register(friction);A factory's hooks list is an upper bound. The parsed parameters may leave a hook out, which is how a non-looping tick component implements nothing, but returning a hook the factory never declared is a registration error. Domains read the list to decide which types can ever reach a hook.
A behavior is the same idea attached from the other side. It is registered by name and attached to identifiers, which is how one door behavior covers every door. The selector is an identifier, a list of them, or a predicate. A predicate receives the identifier and the loaded definition, so it can select behavior from a component as well as from a closed-over tag index. Identifier-only predicates remain valid.
Mojang's minecraft:custom_components is read as one more way to name a behavior rather than the binding mechanism, because that hook is marked deprecated in Mojang's own documentation while its version 2 still needs two experimental toggles.
Hook dispatch
A domain declares its own hook map, so this package never knows a hook name:
interface BlockHooks {
onPlace: (position: Vector3) => void;
}Declare it as an interface or a type, whichever you prefer. The generic parameter is written H extends HookSignatures<H> for that reason: a plain index-signature constraint would reject an interface, because TypeScript gives an implicit index signature to a type alias and not to one.
Each type gets a HookTable built once at load, which turns every hook into a frozen array of handlers. Dispatch is an array lookup and a loop, with no map lookup and no allocation per call. Order is the definition's component order first, then behaviors in attachment order, so the server's own code has the last word over what a pack declared.
Either side can set override, which replaces every handler collected so far for the hooks that contribution implements and leaves the others alone. That is Bedrock's permutation rule, and a domain's ComponentReader sets it per entry when it emits a permutation's component list.
Flattening
flatten is the Dragonfly Finalize idea: precompute the hot properties at load so the tick loop reads an array slot instead of calling through a type.
import { flatten } from '@jsprismarine/content';
const table = flatten(types.values(), {
id: (type) => runtimeIdOf(type.identifier),
length: paletteSize,
columns: {
friction: { kind: 'f32', read: (type) => type.params(friction) },
lightEmission: { kind: 'u8', read: (type) => type.params(light), default: 0 }
},
exceptions: [{ id: 0, column: 'friction', value: 0.6, reason: 'minecraft:unknown has no Java row' }]
});
table.friction[runtimeId]; // a Float32Array readThe column's kind picks the typed array, and the return type carries it, so table.friction is a Float32Array and table.lightEmission is a Uint8Array.
An id with no source value falls back to the column's default and then to a reviewed exception. An id with neither fails the build, and so does an exception that matched nothing. That second rule is what keeps the list honest: every gap is a row with a reason, and a row outlives the gap it covers for exactly one build.
Values are range checked against the column kind, so 300 in a u8 column and 0.5 in any integer column fail the build instead of being silently truncated.
Plugging in a domain
A domain package does five things, in this order.
- Declare its hook map and register a
ComponentFactoryfor every component name it implements. - Register its behaviors and attach them to identifiers or tags.
- Write a
ComponentReaderthat pulls the component list out of its own JSON shape, includingcomponent_groupsand permutations if it has them. - Call
resolveTypeson the definitions@jsprismarine/packsloaded, thenregistry.rebuild(result.types). - Call
flattenfor the properties its tick loop reads, and hand outInstancehandles or dense ids, whichever fits.
Diagnostics come back as a list rather than through a logger, with the same Diagnostic shape @jsprismarine/packs uses, so you can concatenate a load report and a resolve report. An unknown component name resolves the type anyway and is reported once per pack, which turns "component not implemented" into a log line instead of a missing class. Pass strict: true to turn any diagnostic into a ContentLoadError, which is what the test suites do.
Classes
- BehaviorRegistry
- ComponentRegistry
- ContentError
- ContentLoadError
- FlattenError
- HookTable
- Instance
- Registry
- Tags
Interfaces
Behavior
Defined in: packages/content/src/behaviors.ts:16
A named set of handlers attached to types by identifier instead of declared in a definition.
Behaviors carry the code a family of content shares, the way one door behavior covers every door. Mojang's minecraft:custom_components key is one way to name a behavior, not the binding mechanism, because Mojang marked that hook deprecated while its version 2 still needs two experimental toggles.
Type Parameters
H
H extends HookSignatures<H>
Properties
hooks
readonlyhooks: readonly (keyofH&string)[]
Defined in: packages/content/src/behaviors.ts:24
Every hook the behavior may implement. As with a component factory this is an upper bound, and returning a hook that is not on the list is a registration error.
name
readonlyname:string
Defined in: packages/content/src/behaviors.ts:18
The behavior's name, in the server's or a plugin's own namespace.
override?
readonlyoptionaloverride?:boolean
Defined in: packages/content/src/behaviors.ts:26
Replace the handlers every earlier contribution bound for the hooks this one implements.
Methods
create()
create(
context):Partial<H>
Defined in: packages/content/src/behaviors.ts:28
Builds the handlers for one type. Runs once per attached type at load.
Parameters
context
Returns
Partial<H>
BindContext
Defined in: packages/content/src/components.ts:31
What a component factory or a behavior can see about the type it binds to.
Properties
definition
readonlydefinition:Definition
Defined in: packages/content/src/components.ts:35
The definition the type is resolved from.
identifier
readonlyidentifier:string
Defined in: packages/content/src/components.ts:33
The identifier of the type being resolved.
BoundBehavior
Defined in: packages/content/src/behaviors.ts:42
One behavior after its handlers are built for a type.
Type Parameters
H
H extends HookSignatures<H>
Properties
handlers
readonlyhandlers:Partial<H>
Defined in: packages/content/src/behaviors.ts:44
name
readonlyname:string
Defined in: packages/content/src/behaviors.ts:43
override
readonlyoverride:boolean
Defined in: packages/content/src/behaviors.ts:46
Whether the behavior replaces earlier handlers for the hooks it implements.
BoundComponent
Defined in: packages/content/src/components.ts:61
One component after its value parsed and its handlers bound.
Type Parameters
H
H extends HookSignatures<H>
Properties
handlers
readonlyhandlers:Partial<H>
Defined in: packages/content/src/components.ts:71
The handlers the factory returned.
name
readonlyname:string
Defined in: packages/content/src/components.ts:63
The component name, which is also its key in the definition.
params
readonlyparams:unknown
Defined in: packages/content/src/components.ts:69
What the factory's schema produced. The parameter type is erased here; read it back through the resolved type, which narrows it against the factory that produced it.
ColumnSpec
Defined in: packages/content/src/flatten.ts:27
One column of a flattened table.
Type Parameters
T
T
K
K extends ColumnKind = ColumnKind
Properties
default?
readonlyoptionaldefault?:number
Defined in: packages/content/src/flatten.ts:38
Stored for any id the sources leave without a value.
kind
readonlykind:K
Defined in: packages/content/src/flatten.ts:29
The typed array the column stores.
Methods
read()
read(
source):number|undefined
Defined in: packages/content/src/flatten.ts:36
Reads the column's value for one source.
Parameters
source
T
Returns
number | undefined
The value, or undefined when the source has none, which then needs the column's default or a reviewed exception.
ComponentEntry
Defined in: packages/content/src/types.ts:10
One component a definition declares, as the domain's reader found it.
Properties
name
name:
string
Defined in: packages/content/src/types.ts:12
The component name, which must match a registered factory.
override?
optionaloverride?:boolean
Defined in: packages/content/src/types.ts:20
Replace the handlers every earlier entry bound for the hooks this one implements. A block domain sets it for a permutation's component list, which is how Bedrock's permutations override a base component.
value
value:
unknown
Defined in: packages/content/src/types.ts:14
The component's raw JSON value, passed to the factory's schema.
ComponentFactory
Defined in: packages/content/src/components.ts:44
One documented component name bound to a schema and a set of hooks.
A domain registers one factory per component name it implements. The server fills the registry with the vanilla components and plugins add their own.
Extended by
Type Parameters
H
H extends HookSignatures<H>
P
P = unknown
Properties
hooks
readonlyhooks: readonly (keyofH&string)[]
Defined in: packages/content/src/components.ts:53
Every hook the component may implement. This is an upper bound: the parsed parameters may leave one out, and returning a hook that is not on the list is a registration error. Domains read the list to decide which types can ever reach a hook.
name
readonlyname:string
Defined in: packages/content/src/components.ts:46
The component name as a definition writes it, such as minecraft:destructible_by_mining.
schema
readonlyschema:ComponentSchema<P>
Defined in: packages/content/src/components.ts:55
Runs once per type at load, before ComponentFactory.create.
Methods
create()
create(
params,context):Partial<H>
Defined in: packages/content/src/components.ts:57
Turns parsed parameters into the handlers this component contributes.
Parameters
params
P
context
Returns
Partial<H>
Definition
Defined in: packages/content/src/definitions.ts:11
The first of the three content layers: parsed, validated, immutable JSON for one identifier.
@jsprismarine/packs produces this shape from a pack stack, and its Definition is assignable here. The content runtime accepts the shape structurally instead of importing it, so a domain can also build types from data that never passed through a pack, such as the Java Edition jar dump behind the block property table.
Properties
data
data:
unknown
Defined in: packages/content/src/definitions.ts:21
The parsed definition, replaced whole by a later pack, never merged.
identifier
identifier:
string
Defined in: packages/content/src/definitions.ts:13
The identifier the definition is registered under, such as minecraft:stone.
pack
pack:
string
Defined in: packages/content/src/definitions.ts:17
The name of the pack the winning definition came from; diagnostics name it.
path
path:
string
Defined in: packages/content/src/definitions.ts:19
The pack-relative path of the file.
registry
registry:
string
Defined in: packages/content/src/definitions.ts:15
The registry the definition belongs to, such as blocks.
Diagnostic
Defined in: packages/content/src/diagnostics.ts:18
One finding reported while resolving content.
Properties
code
code:
string
Defined in: packages/content/src/diagnostics.ts:21
A stable machine-readable code, such as component.unknown or tag.cycle.
message
message:
string
Defined in: packages/content/src/diagnostics.ts:26
pack
pack:
string
Defined in: packages/content/src/diagnostics.ts:23
The name of the pack the finding belongs to.
path?
optionalpath?:string
Defined in: packages/content/src/diagnostics.ts:25
The file within the pack, when the finding concerns one file; the first file when several share the finding.
severity
severity:
DiagnosticSeverity
Defined in: packages/content/src/diagnostics.ts:19
FlattenException
Defined in: packages/content/src/flatten.ts:51
One id a column has no source value for, reviewed and written down.
The list works like the mapping package's loss list: every gap is a row with a reason, and a row that matches nothing fails the build, so the list cannot outlive the gap it covers.
Properties
column?
optionalcolumn?:string
Defined in: packages/content/src/flatten.ts:55
The column name, or omitted to cover every column of that id.
id
id:
number
Defined in: packages/content/src/flatten.ts:53
The dense id with no source value.
reason
reason:
string
Defined in: packages/content/src/flatten.ts:59
Why the id has no source value. The failure message quotes it when the row matches nothing.
value
value:
number
Defined in: packages/content/src/flatten.ts:57
The value to store instead.
FlattenSpec
Defined in: packages/content/src/flatten.ts:63
What to flatten and how, including the reviewed exceptions.
Type Parameters
T
T
C
C extends Columns<T>
Properties
columns
columns:
C
Defined in: packages/content/src/flatten.ts:68
exceptions?
optionalexceptions?: readonlyFlattenException[]
Defined in: packages/content/src/flatten.ts:69
id
id: (
source) =>number
Defined in: packages/content/src/flatten.ts:65
The dense id of one source. Ids run from 0 to length - 1 with no repeats.
Parameters
source
T
Returns
number
length
length:
number
Defined in: packages/content/src/flatten.ts:67
How many ids the arrays cover.
Holder
Defined in: packages/content/src/registry.ts:11
A stable reference to one registry entry by key.
A holder outlives the build it came from. Reloading content replaces a registry's entries and renumbers them, and every holder for a surviving key then reads the new value and the new id. A holder for a key the new build drops goes unbound instead of going stale.
Type Parameters
T
T
Properties
bound
readonlybound:boolean
Defined in: packages/content/src/registry.ts:17
Whether the current build has an entry under the key.
id
readonlyid:number|undefined
Defined in: packages/content/src/registry.ts:19
The entry's id in the current build, or undefined while unbound.
key
readonlykey:string
Defined in: packages/content/src/registry.ts:15
The key, normally a namespaced identifier such as minecraft:stone.
registry
readonlyregistry:string
Defined in: packages/content/src/registry.ts:13
The name of the registry the key belongs to.
Methods
get()
get():
T|undefined
Defined in: packages/content/src/registry.ts:21
The current value, or undefined while unbound.
Returns
T | undefined
value()
value():
T
Defined in: packages/content/src/registry.ts:27
The current value.
Returns
T
Throws
While the holder is unbound.
HolderSet
Defined in: packages/content/src/tags.ts:35
The resolved members of one tag, as holders, so the set survives a registry rebuild the same way a single Holder does.
Extends
Iterable<Holder<T>>
Type Parameters
T
T
Properties
members
readonlymembers: readonlyHolder<T>[]
Defined in: packages/content/src/tags.ts:39
Members in merge order, with tag references expanded and keys deduplicated.
tag
readonlytag:string
Defined in: packages/content/src/tags.ts:37
The tag's namespaced id, without a #.
Methods
has()
has(
key):boolean
Defined in: packages/content/src/tags.ts:41
Whether the set contains a registry key.
Parameters
key
string
Returns
boolean
values()
values(): readonly
T[]
Defined in: packages/content/src/tags.ts:43
The values of the members the registry currently has, in merge order.
Returns
readonly T[]
HookContribution
Defined in: packages/content/src/hooks.ts:25
One contributor's handlers, from a component or an attached behavior.
Type Parameters
H
H extends HookSignatures<H>
Properties
handlers
readonlyhandlers:Partial<H>
Defined in: packages/content/src/hooks.ts:29
The handlers it implements. A hook it leaves out is simply absent.
override?
readonlyoptionaloverride?:boolean
Defined in: packages/content/src/hooks.ts:36
Replace every earlier handler for each hook this contribution implements instead of running after them. This is Bedrock's permutation rule: a permutation's component overrides the base component for the same hook and leaves the hooks it does not implement alone.
source
readonlysource:string
Defined in: packages/content/src/hooks.ts:27
The component or behavior name, so diagnostics and dispatch order can name it.
ResolveOptions
Defined in: packages/content/src/types.ts:113
Options for resolveTypes.
Type Parameters
H
H extends HookSignatures<H>
F
F extends object
Properties
behaviors?
optionalbehaviors?:BehaviorRegistry<H>
Defined in: packages/content/src/types.ts:117
The behaviors the server and its plugins attach by identifier.
components
components:
ComponentRegistry<H>
Defined in: packages/content/src/types.ts:115
The component names the domain implements.
flags?
optionalflags?:FlagSpec<H,F>
Defined in: packages/content/src/types.ts:125
The flags to compute per type. Written as a mapped type over F so a spec passed inline both infers its own flag names and gives each computer a typed TypeView parameter.
read
read:
ComponentReader
Defined in: packages/content/src/types.ts:119
Pulls the component list out of each definition.
strict?
optionalstrict?:boolean
Defined in: packages/content/src/types.ts:127
Fail the resolve when any diagnostic is reported, instead of reporting and continuing.
ResolveResult
Defined in: packages/content/src/types.ts:131
What resolveTypes returns: the resolved types plus the full report.
Type Parameters
H
H extends HookSignatures<H>
F
F extends string
Properties
diagnostics
diagnostics: readonly
Diagnostic[]
Defined in: packages/content/src/types.ts:134
types
types:
ReadonlyMap<string,Type<H,F>>
Defined in: packages/content/src/types.ts:133
Identifier to type, in definition order, ready for Registry.rebuild.
TagSource
Defined in: packages/content/src/tags.ts:16
One tag file contributed by one pack.
Properties
pack
pack:
string
Defined in: packages/content/src/tags.ts:20
The name of the pack the file came from.
path?
optionalpath?:string
Defined in: packages/content/src/tags.ts:22
The file's path within the pack, for diagnostics.
replace?
optionalreplace?:boolean
Defined in: packages/content/src/tags.ts:27
Drop everything earlier packs put in this tag before adding values. This is Java Edition's rule: a tag file appends unless it sets replace.
tag
tag:
string
Defined in: packages/content/src/tags.ts:18
The tag's namespaced id, written without the # a reference carries.
values
values: readonly
TagMember[]
Defined in: packages/content/src/tags.ts:28
Type
Defined in: packages/content/src/types.ts:61
The second of the three content layers: a definition resolved against the component registries once at load, with components bound, behaviors attached, the dispatch table built and the domain's flags computed.
Extends
TypeView<H>
Extended by
Type Parameters
H
H extends HookSignatures<H>
F
F extends string = never
Properties
behaviors
readonlybehaviors: readonlyBoundBehavior<H>[]
Defined in: packages/content/src/types.ts:42
The behaviors that attached, in attachment order.
Inherited from
components
readonlycomponents: readonlyBoundComponent<H>[]
Defined in: packages/content/src/types.ts:40
The components that bound, in declaration order; a rejected one is absent.
Inherited from
definition
readonlydefinition:Definition
Defined in: packages/content/src/types.ts:38
The definition the type came from.
Inherited from
flags
readonlyflags:Readonly<Record<F,boolean>>
Defined in: packages/content/src/types.ts:63
The flags the domain's FlagSpec computed, one pass at load.
hooks
readonlyhooks:HookTable<H>
Defined in: packages/content/src/types.ts:44
The dispatch table, built once here rather than per call.
Inherited from
identifier
readonlyidentifier:string
Defined in: packages/content/src/types.ts:36
The identifier the type is registered under.
Inherited from
Methods
hasComponent()
hasComponent(
name):boolean
Defined in: packages/content/src/types.ts:53
Whether the type bound a component under the name.
Parameters
name
string
Returns
boolean
Inherited from
params()
params<
P>(factory):P|undefined
Defined in: packages/content/src/types.ts:51
The parsed parameters of one component, narrowed against the factory whose schema produced them.
Type Parameters
P
P
Parameters
factory
ComponentFactory<H, P>
Returns
P | undefined
The parameters, or undefined when the type has no such component.
Inherited from
TypeView
Defined in: packages/content/src/types.ts:34
A resolved type before its flags are computed, which is what a flag computer reads.
Extended by
Type Parameters
H
H extends HookSignatures<H>
Properties
behaviors
readonlybehaviors: readonlyBoundBehavior<H>[]
Defined in: packages/content/src/types.ts:42
The behaviors that attached, in attachment order.
components
readonlycomponents: readonlyBoundComponent<H>[]
Defined in: packages/content/src/types.ts:40
The components that bound, in declaration order; a rejected one is absent.
definition
readonlydefinition:Definition
Defined in: packages/content/src/types.ts:38
The definition the type came from.
hooks
readonlyhooks:HookTable<H>
Defined in: packages/content/src/types.ts:44
The dispatch table, built once here rather than per call.
identifier
readonlyidentifier:string
Defined in: packages/content/src/types.ts:36
The identifier the type is registered under.
Methods
hasComponent()
hasComponent(
name):boolean
Defined in: packages/content/src/types.ts:53
Whether the type bound a component under the name.
Parameters
name
string
Returns
boolean
params()
params<
P>(factory):P|undefined
Defined in: packages/content/src/types.ts:51
The parsed parameters of one component, narrowed against the factory whose schema produced them.
Type Parameters
P
P
Parameters
factory
ComponentFactory<H, P>
Returns
P | undefined
The parameters, or undefined when the type has no such component.
Type Aliases
BehaviorSelector
BehaviorSelector =
string| readonlystring[] | ((identifier,definition?) =>boolean)
Defined in: packages/content/src/behaviors.ts:39
Picks the type identifiers a behavior attaches to: one identifier, a list of them, or a predicate. Predicates receive the identifier and its loaded definition, which lets a domain select behavior from component data or attach by tag through a closed-over Tags instance. The definition argument is optional when a caller invokes the predicate directly; the registry supplies it when matching.
ColumnArray
ColumnArray<
K> =InstanceType<typeofCOLUMN_KINDS[K]["array"]>
Defined in: packages/content/src/flatten.ts:24
The typed array one column kind produces.
Type Parameters
K
K extends ColumnKind
ColumnKind
ColumnKind = keyof typeof
COLUMN_KINDS
Defined in: packages/content/src/flatten.ts:21
One of COLUMN_KINDS.
Columns
Columns<
T> =Readonly<Record<string,ColumnSpec<T>>>
Defined in: packages/content/src/flatten.ts:42
The columns a flattened table holds, keyed by the name the caller indexes them under.
Type Parameters
T
T
ComponentReader
ComponentReader = (
definition) =>Iterable<ComponentEntry>
Defined in: packages/content/src/types.ts:31
Reads the component list out of a definition's JSON, in declaration order.
This is the seam that keeps the content runtime domain-neutral: the block, item and entity packages each know their own wrapper key, their own component_groups and their own permutation rules, and the runtime only sees the flat list that comes out.
Parameters
definition
Returns
Iterable<ComponentEntry>
ComponentSchema
ComponentSchema<
P> = (value) =>ParseResult<P>
Defined in: packages/content/src/components.ts:25
Validates and parses one component's JSON value, once per type at load.
A schema is a plain function so a domain can inject whatever it already has: a hand-written check, a Bedrock sample schema, or a vanilla-mcdoc checker.
Type Parameters
P
P
Parameters
value
unknown
Returns
ParseResult<P>
DiagnosticSeverity
DiagnosticSeverity =
"error"|"warning"
Defined in: packages/content/src/diagnostics.ts:15
How much a finding matters. An error means content was dropped; a warning means it loaded with something unhandled. A strict resolve fails on either, which is what @jsprismarine/packs does too.
FlagComputer
FlagComputer<
H> = (type) =>boolean
Defined in: packages/content/src/types.ts:67
Computes one load-time flag from a resolved type.
Type Parameters
H
H extends HookSignatures<H>
Parameters
type
TypeView<H>
Returns
boolean
FlagSpec
FlagSpec<
H,F> ={ readonly [K in keyof F]: FlagComputer<H> }
Defined in: packages/content/src/types.ts:74
The flags a domain computes once per type, such as whether a block is solid or takes random ticks. Flattening a flag into a typed array is flatten's job; this is for the handful a type is asked for by name.
Type Parameters
H
H extends HookSignatures<H>
F
F
FlatTable
FlatTable<
C> ={ readonly [K in keyof C]: ColumnArray<C[K]["kind"]> }
Defined in: packages/content/src/flatten.ts:73
The flattened table: one typed array per column, indexed by the dense id.
Type Parameters
C
C extends Columns<never>
HookSignatures
HookSignatures<
H> ={ [K in keyof H]: (args: never[]) => unknown }
Defined in: packages/content/src/hooks.ts:19
The hook map a domain declares: hook name to handler signature. The content runtime never names a hook, so the block, item and entity packages each declare their own map and pass it as the H parameter.
The parameter is self-referential (H extends HookSignatures<H>) so a domain can declare its map as an interface. A plain index-signature constraint would reject one, because TypeScript gives an implicit index signature to a type alias and not to an interface.
Type Parameters
H
H
Example
interface BlockHooks {
onPlace: (position: number) => void;
onInteract: (player: string) => boolean | undefined;
}ParseResult
ParseResult<
P> = {ok:true;value:P; } | {message:string;ok:false; }
Defined in: packages/content/src/components.ts:6
What a ComponentSchema made of a JSON value.
Type Parameters
P
P
TagMember
TagMember =
string| {id:string;required?:boolean; }
Defined in: packages/content/src/tags.ts:13
One entry in a tag file. A bare string is a required member; the object form carries Java's required flag, and a member that is not required and has no registry entry is dropped without a report.
An id that starts with # names another tag, whose members are expanded in place.
Variables
COLUMN_KINDS
constCOLUMN_KINDS:object
Defined in: packages/content/src/flatten.ts:9
The typed arrays a flattened column can use, with whether the kind holds whole numbers and whether it holds negative ones. The value ranges come out of each constructor's BYTES_PER_ELEMENT, so this table is the only place a kind is declared.
Type Declaration
f32
readonlyf32:object
f32.array
readonlyarray:Float32ArrayConstructor=Float32Array
f32.integer
readonlyinteger:false=false
f32.signed
readonlysigned:true=true
f64
readonlyf64:object
f64.array
readonlyarray:Float64ArrayConstructor=Float64Array
f64.integer
readonlyinteger:false=false
f64.signed
readonlysigned:true=true
i16
readonlyi16:object
i16.array
readonlyarray:Int16ArrayConstructor=Int16Array
i16.integer
readonlyinteger:true=true
i16.signed
readonlysigned:true=true
i32
readonlyi32:object
i32.array
readonlyarray:Int32ArrayConstructor=Int32Array
i32.integer
readonlyinteger:true=true
i32.signed
readonlysigned:true=true
i8
readonlyi8:object
i8.array
readonlyarray:Int8ArrayConstructor=Int8Array
i8.integer
readonlyinteger:true=true
i8.signed
readonlysigned:true=true
u16
readonlyu16:object
u16.array
readonlyarray:Uint16ArrayConstructor=Uint16Array
u16.integer
readonlyinteger:true=true
u16.signed
readonlysigned:false=false
u32
readonlyu32:object
u32.array
readonlyarray:Uint32ArrayConstructor=Uint32Array
u32.integer
readonlyinteger:true=true
u32.signed
readonlysigned:false=false
u8
readonlyu8:object
u8.array
readonlyarray:Uint8ArrayConstructor=Uint8Array
u8.integer
readonlyinteger:true=true
u8.signed
readonlysigned:false=false
anyValue
constanyValue:ComponentSchema<unknown>
Defined in: packages/content/src/components.ts:28
Accepts any JSON value unchanged, for a component with no schema yet.
Functions
accepted()
accepted<
P>(value):ParseResult<P>
Defined in: packages/content/src/components.ts:10
Wraps a parsed value as a successful ParseResult.
Type Parameters
P
P
Parameters
value
P
Returns
ParseResult<P>
flatten()
flatten<
T,C>(sources,spec):FlatTable<C>
Defined in: packages/content/src/flatten.ts:117
Flattens resolved types into one typed array per column, indexed by a dense numeric id, so a hot path reads an array slot instead of calling through a type. This is Dragonfly's Finalize idea: precompute at load, so lighting and tick selection never ask a type anything.
A column with no value for an id falls back to the column's default, then to a reviewed exception. An id with neither fails the build, and so does an exception that matched nothing.
Type Parameters
T
T
C
C extends Readonly<Record<string, ColumnSpec<T, "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64">>>
Parameters
sources
Iterable<T>
The resolved types, in any order; spec.id places each one.
spec
FlattenSpec<T, C>
Returns
FlatTable<C>
Throws
On a duplicate or out-of-range id, a value the column kind cannot hold, an id with no value and no exception, or an unused exception.
rejected()
rejected(
message):ParseResult<never>
Defined in: packages/content/src/components.ts:17
Wraps a failure as a ParseResult.
Parameters
message
string
What the value should have been; the resolver puts it in a diagnostic.
Returns
ParseResult<never>
resolveTypes()
resolveTypes<
H,F>(definitions,options):ResolveResult<H,Extract<keyofF,string>>
Defined in: packages/content/src/types.ts:161
Resolves definitions into types.
Each definition's components bind in declaration order, then the behaviors attached to its identifier bind in attachment order, so the server's own code has the last word over what a pack declared and a behavior marked override can replace a component's handler. An unknown component name loads the type anyway and is reported once per pack, naming the first file that declared it, which turns "component not implemented" into a log line instead of a missing class.
Type Parameters
H
H extends HookSignatures<H>
F
F extends object = Record<never, never>
Parameters
definitions
Iterable<Definition>
options
ResolveOptions<H, F>
Returns
ResolveResult<H, Extract<keyof F, string>>
Throws
In strict mode, when any diagnostic is reported.