import type { ComponentId, FieldDescriptor, FieldToken, FieldValue, ScalarToken, ScalarValue, Schema, TokenOf, VecToken } from '@ecsia/schema'; /** * A typed inter-system message queue ("this happened"), as opposed to an observer ("this component * changed"). Define once at module scope with `defineTopic`; systems declare interest with the * `publish:` / `consume:` keys on `defineSystem`, and code outside systems publishes between frames * via `world.publish`. `id` is the topic's virtual ComponentId, minted when a world registers it. */ export interface TopicDef { readonly name: N; readonly schema: S; readonly fields: readonly FieldDescriptor[]; /** The dense virtual ComponentId once registered with a world; -1 (UNREGISTERED) before. */ id: ComponentId; readonly __ecsiaTopic: true; } /** * The value an event field decodes to on the consume side. Scalars decode like component reads; * `vec` fields decode to a plain readonly number array (events are copied rows, not live views). */ export type TopicFieldValue = TokenOf extends VecToken ? readonly ScalarValue[] : FieldValue>; /** One delivered event: a typed read view over the payload schema. Pooled — never store it. */ export type TopicEvent = { readonly [K in keyof S]: TopicFieldValue; }; /** The payload accepted by `publish` — missing fields take their schema defaults. */ export type TopicEventInit = { readonly [K in keyof S]?: TokenOf extends VecToken ? ArrayLike : FieldValue>; }; /** * Define a typed event queue. `schema` uses the component field tokens (`'f32'`, `'eid'`, `vec`, * `staticString`, ...); `object` and `'string'` fields are rejected — event rows are fixed-width * u32 words so the stream is shareable, byte-deterministic, and serializable. * * `eid` payload fields carry the full generational handle with NO liveness validation on delivery: * an event is a fact about the past, and the referenced entity may legitimately be dead by the time * a consumer reads it (especially on next-frame delivery). Check `world.isAlive(ev.target)` if the * consumer needs the entity. * * Like a `defineComponent` def, a topic def binds to ONE world: registration writes the minted id * into the def, so a second world (another test, an HMR cycle) must call `defineTopic` afresh * rather than reuse the module-scope def — reuse throws "already registered with another world". */ export declare function defineTopic(name: N, schema: S): TopicDef; //# sourceMappingURL=define.d.ts.map