@ecsia/core 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -12
- package/dist/component/define.d.ts.map +1 -1
- package/dist/component/define.js +9 -2
- package/dist/component/define.js.map +1 -1
- package/dist/component/descriptors.d.ts +1 -1
- package/dist/component/descriptors.d.ts.map +1 -1
- package/dist/component/descriptors.js +6 -1
- package/dist/component/descriptors.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/query/compile.d.ts.map +1 -1
- package/dist/query/compile.js +12 -1
- package/dist/query/compile.js.map +1 -1
- package/dist/query/engine.js +1 -1
- package/dist/query/engine.js.map +1 -1
- package/dist/query/live-query.d.ts +62 -3
- package/dist/query/live-query.d.ts.map +1 -1
- package/dist/query/live-query.js +190 -2
- package/dist/query/live-query.js.map +1 -1
- package/dist/serialize-surface.d.ts +2 -0
- package/dist/serialize-surface.d.ts.map +1 -1
- package/dist/topics/codec.d.ts +23 -0
- package/dist/topics/codec.d.ts.map +1 -0
- package/dist/topics/codec.js +113 -0
- package/dist/topics/codec.js.map +1 -0
- package/dist/topics/define.d.ts +44 -0
- package/dist/topics/define.d.ts.map +1 -0
- package/dist/topics/define.js +61 -0
- package/dist/topics/define.js.map +1 -0
- package/dist/topics/index.d.ts +7 -0
- package/dist/topics/index.d.ts.map +1 -0
- package/dist/topics/index.js +4 -0
- package/dist/topics/index.js.map +1 -0
- package/dist/topics/store.d.ts +83 -0
- package/dist/topics/store.d.ts.map +1 -0
- package/dist/topics/store.js +416 -0
- package/dist/topics/store.js.map +1 -0
- package/dist/world.d.ts +17 -0
- package/dist/world.d.ts.map +1 -1
- package/dist/world.js +30 -2
- package/dist/world.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/topics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Schema } from '@ecsia/schema';
|
|
2
|
+
import type { Buffers } from '../memory/index.js';
|
|
3
|
+
import type { TopicDef } from './define.js';
|
|
4
|
+
/** Reserved-zero metadata words per event row (future: tick + publishing system; payload-only v1). */
|
|
5
|
+
export declare const TOPIC_HEADER_WORDS = 2;
|
|
6
|
+
export interface TopicsConfig {
|
|
7
|
+
readonly buffers: Buffers;
|
|
8
|
+
/** Mint the next dense ComponentId (the topic's virtual id; same space as relations' synthetics). */
|
|
9
|
+
readonly allocId: () => number;
|
|
10
|
+
readonly phase: () => 'serial' | 'wave';
|
|
11
|
+
readonly dev: boolean;
|
|
12
|
+
readonly warn: (message: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class Topics {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(cfg: TopicsConfig);
|
|
17
|
+
/** Number of topics registered with this world. Zero ⇒ every per-frame hook is a no-op. */
|
|
18
|
+
get count(): number;
|
|
19
|
+
/** Intern a topic with this world (idempotent): mints its virtual ComponentId + canonical ring. */
|
|
20
|
+
register(def: TopicDef<Schema>): void;
|
|
21
|
+
/** The topic's virtual ComponentId, or -1 if not registered. */
|
|
22
|
+
idOf(def: TopicDef<Schema>): number;
|
|
23
|
+
/** `(name, id)` pairs for worker id alignment (the boot manifest). */
|
|
24
|
+
manifest(): readonly {
|
|
25
|
+
name: string;
|
|
26
|
+
id: number;
|
|
27
|
+
}[];
|
|
28
|
+
/** Scheduler frame hooks: world.publish is illegal while an update is in progress. */
|
|
29
|
+
beginUpdate(): void;
|
|
30
|
+
endUpdate(): void;
|
|
31
|
+
/**
|
|
32
|
+
* `world.publish` — the outside-systems path (input/network handlers, between frames). Appends
|
|
33
|
+
* directly to the canonical stream in call order, ahead of wave 0 of the next frame. Registers
|
|
34
|
+
* the topic on first use. Serial phase only; inside a system body use `ctx.publish` instead
|
|
35
|
+
* (direct appends mid-update would bypass the SystemId canonicalization).
|
|
36
|
+
*/
|
|
37
|
+
publishOutside(def: TopicDef<Schema>, init: Record<string, unknown> | undefined): void;
|
|
38
|
+
/** `ctx.publish` (main-thread system) — encode now, stage to the system's segment. */
|
|
39
|
+
stageValues(def: TopicDef<Schema>, systemId: number, init: Record<string, unknown> | undefined): void;
|
|
40
|
+
/** OP_PUBLISH apply (worker publishes replayed at the command flush) — stage raw field words. */
|
|
41
|
+
stageWords(topicId: number, systemId: number, words: ArrayLike<number>, at: number, fieldWords: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* The wave's serial-slot merge: for every topic with staged events, sort the staging segments by
|
|
44
|
+
* publishing SystemId ascending and append each segment FIFO to the canonical stream. Runs once
|
|
45
|
+
* per wave, after the wave's command flush — the single canonicalization point for every
|
|
46
|
+
* execution mode.
|
|
47
|
+
*/
|
|
48
|
+
mergeStaged(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Eagerly position a reader's cursor at plan time. Before the first update has ever run
|
|
51
|
+
* (the FIRST plan), the cursor starts at the oldest retained event so `world.publish` calls made
|
|
52
|
+
* before `createScheduler` are still delivered; once any update has run, a newly-added reader
|
|
53
|
+
* (a late re-plan join) starts at the current head — no replay of stale retained events.
|
|
54
|
+
*/
|
|
55
|
+
initCursor(def: TopicDef<Schema>, readerKey: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Iterate the reader's unseen events up to the current visible head and advance its cursor —
|
|
58
|
+
* exactly-once per (reader, topic), independent cursors per reader (no drain stealing). The
|
|
59
|
+
* yielded view is pooled: read fields inside the loop, never store the view itself.
|
|
60
|
+
*
|
|
61
|
+
* A reader with no cursor starts at the oldest retained event (the manual-consumption default);
|
|
62
|
+
* scheduler consumers are positioned eagerly via `initCursor` at plan time — at the oldest
|
|
63
|
+
* retained event for the first plan (pre-plan `world.publish` events are delivered), at the
|
|
64
|
+
* current head for a re-plan join (no replay).
|
|
65
|
+
*/
|
|
66
|
+
consume(def: TopicDef<Schema>, readerKey: string): IterableIterator<Record<string, unknown>>;
|
|
67
|
+
/**
|
|
68
|
+
* Frame reset (serial, quiescent): drop events two frames old, fold any spill back into the ring
|
|
69
|
+
* (regrowing it to 2x the observed peak), and compact retained rows to the ring front.
|
|
70
|
+
*/
|
|
71
|
+
frameReset(): void;
|
|
72
|
+
/** Oldest retained / next sequence numbers for `def`. */
|
|
73
|
+
bounds(def: TopicDef<Schema>): {
|
|
74
|
+
tail: number;
|
|
75
|
+
head: number;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* A copy of the retained canonical stream `[tail, head)` in sequence order — the byte-identity
|
|
79
|
+
* surface the serial-equivalence suite compares across worker counts and transports.
|
|
80
|
+
*/
|
|
81
|
+
streamWords(def: TopicDef<Schema>): Uint32Array;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/topics/store.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,oBAAoB,CAAA;AAKpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,sGAAsG;AACtG,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAoDnC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,qGAAqG;IACrG,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,QAAQ,GAAG,MAAM,CAAA;IACvC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACzC;AAED,qBAAa,MAAM;;gBAoBL,GAAG,EAAE,YAAY;IAQ7B,2FAA2F;IAC3F,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,mGAAmG;IACnG,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI;IAsErC,gEAAgE;IAChE,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM;IAInC,sEAAsE;IACtE,QAAQ,IAAI,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE;IAInD,sFAAsF;IACtF,WAAW,IAAI,IAAI;IAQnB,SAAS,IAAI,IAAI;IAMjB;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IAYtF,sFAAsF;IACtF,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IAMrG,iGAAiG;IACjG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAyB7G;;;;;OAKG;IACH,WAAW,IAAI,IAAI;IA8CnB;;;;;OAKG;IACH,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAK1D;;;;;;;;;OASG;IACF,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA4B7F;;;OAGG;IACH,UAAU,IAAI,IAAI;IAqFlB,yDAAyD;IACzD,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAK7D;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,WAAW;CAYhD"}
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
// The world-owned topic store: one canonical event stream per topic plus the per-system staging
|
|
2
|
+
// segments and per-(reader, topic) consume cursors.
|
|
3
|
+
//
|
|
4
|
+
// THE DETERMINISM CONTRACT (the reason this module exists): the total order of events within a
|
|
5
|
+
// topic is `(frame, wave, publishing SystemId ascending, per-system FIFO append order)`.
|
|
6
|
+
// `publish()` therefore NEVER appends to the canonical stream directly — it appends to a
|
|
7
|
+
// per-(topic, system) staging segment, and the wave's serial slot performs ONE segment sort by
|
|
8
|
+
// SystemId (`mergeStaged`). Worker publishes arrive in the same staging via OP_PUBLISH records
|
|
9
|
+
// replayed at the command flush; main-thread publishes stage directly. One code path, every
|
|
10
|
+
// execution mode, byte-identical stream — direct append would expose round/worker order, which
|
|
11
|
+
// varies with workerCount and greedy round packing.
|
|
12
|
+
//
|
|
13
|
+
// The canonical stream is mutated ONLY while world.phase === 'serial' (asserted): the merge runs in
|
|
14
|
+
// the wave's serial slot, so a system mid-wave reads a frozen stream with plain loads.
|
|
15
|
+
//
|
|
16
|
+
// Retention is double-buffered by frame (Bevy's model): at the frame reset entering frame N, every
|
|
17
|
+
// event belonging to frame N-2 or earlier is dropped, so every event is visible for at least one
|
|
18
|
+
// complete frame after the frame it was published in. `world.publish` calls between updates are
|
|
19
|
+
// stamped for the UPCOMING frame. Overflow inside one frame spills to a main-thread array and the
|
|
20
|
+
// ring is regrown to 2x the observed peak at the next frame reset — never a hard throw.
|
|
21
|
+
import { isSharedBacking } from '../memory/buffers.js';
|
|
22
|
+
import { UNREGISTERED } from '../component/index.js';
|
|
23
|
+
import { buildTopicCodec } from './codec.js';
|
|
24
|
+
/** Reserved-zero metadata words per event row (future: tick + publishing system; payload-only v1). */
|
|
25
|
+
export const TOPIC_HEADER_WORDS = 2;
|
|
26
|
+
const INITIAL_CAPACITY_ROWS = 256;
|
|
27
|
+
const NO_SPILL = Number.MAX_SAFE_INTEGER;
|
|
28
|
+
function nextPow2(n) {
|
|
29
|
+
let p = 1;
|
|
30
|
+
while (p < n)
|
|
31
|
+
p *= 2;
|
|
32
|
+
return p;
|
|
33
|
+
}
|
|
34
|
+
export class Topics {
|
|
35
|
+
#buffers;
|
|
36
|
+
#allocId;
|
|
37
|
+
#phase;
|
|
38
|
+
#dev;
|
|
39
|
+
#warn;
|
|
40
|
+
#byDef = new Map();
|
|
41
|
+
#byId = new Map();
|
|
42
|
+
#byName = new Map();
|
|
43
|
+
/** Topics with >= 1 staged segment this cycle — the O(1) merge-skip gate, not an event count. */
|
|
44
|
+
#stagedTopics = 0;
|
|
45
|
+
#inUpdate = false;
|
|
46
|
+
/**
|
|
47
|
+
* Has any update (or manual merge) ever run? Discriminates the FIRST plan from a late re-plan:
|
|
48
|
+
* a consumer in the first plan must see `world.publish` events appended before the plan existed
|
|
49
|
+
* (the input-event contract — "every system sees it next update"), while a consumer added by a
|
|
50
|
+
* re-plan after frames have run starts at the head (no replay of stale retained events).
|
|
51
|
+
*/
|
|
52
|
+
#everUpdated = false;
|
|
53
|
+
constructor(cfg) {
|
|
54
|
+
this.#buffers = cfg.buffers;
|
|
55
|
+
this.#allocId = cfg.allocId;
|
|
56
|
+
this.#phase = cfg.phase;
|
|
57
|
+
this.#dev = cfg.dev;
|
|
58
|
+
this.#warn = cfg.warn;
|
|
59
|
+
}
|
|
60
|
+
/** Number of topics registered with this world. Zero ⇒ every per-frame hook is a no-op. */
|
|
61
|
+
get count() {
|
|
62
|
+
return this.#byDef.size;
|
|
63
|
+
}
|
|
64
|
+
/** Intern a topic with this world (idempotent): mints its virtual ComponentId + canonical ring. */
|
|
65
|
+
register(def) {
|
|
66
|
+
if (this.#byDef.has(def))
|
|
67
|
+
return;
|
|
68
|
+
if (def.id !== UNREGISTERED) {
|
|
69
|
+
throw new Error(`topic '${def.name}' is already registered with another world`);
|
|
70
|
+
}
|
|
71
|
+
const collision = this.#byName.get(def.name);
|
|
72
|
+
if (collision !== undefined) {
|
|
73
|
+
throw new Error(`a different topic named '${def.name}' is already registered with this world — topic names must be unique per world`);
|
|
74
|
+
}
|
|
75
|
+
const id = this.#allocId();
|
|
76
|
+
def.id = id;
|
|
77
|
+
const codec = buildTopicCodec(def.fields);
|
|
78
|
+
const rowWords = TOPIC_HEADER_WORDS + codec.fieldWords;
|
|
79
|
+
const capacityWords = INITIAL_CAPACITY_ROWS * rowWords;
|
|
80
|
+
const region = this.#buffers.region(`topic.${def.name}.ring`, 'u32', capacityWords, {
|
|
81
|
+
maxLength: capacityWords * 16,
|
|
82
|
+
});
|
|
83
|
+
const view = {};
|
|
84
|
+
let curWords = region.view;
|
|
85
|
+
let curBase = 0;
|
|
86
|
+
for (const f of codec.fields) {
|
|
87
|
+
Object.defineProperty(view, f.name, {
|
|
88
|
+
enumerable: true,
|
|
89
|
+
get: () => f.decode(curWords, curBase + f.offset),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const rt = {
|
|
93
|
+
def,
|
|
94
|
+
id,
|
|
95
|
+
name: def.name,
|
|
96
|
+
codec,
|
|
97
|
+
rowWords,
|
|
98
|
+
region,
|
|
99
|
+
ring: region.view,
|
|
100
|
+
baseSeq: 0,
|
|
101
|
+
tail: 0,
|
|
102
|
+
head: 0,
|
|
103
|
+
spill: [],
|
|
104
|
+
spillStartSeq: NO_SPILL,
|
|
105
|
+
prevFrameStart: 0,
|
|
106
|
+
frameEndHead: -1,
|
|
107
|
+
peakRows: 0,
|
|
108
|
+
staged: new Map(),
|
|
109
|
+
stagedEvents: 0,
|
|
110
|
+
cursors: new Map(),
|
|
111
|
+
view,
|
|
112
|
+
bind(words, base) {
|
|
113
|
+
curWords = words;
|
|
114
|
+
curBase = base;
|
|
115
|
+
},
|
|
116
|
+
scratchRow: new Uint32Array(Math.max(codec.fieldWords, 1)),
|
|
117
|
+
overflowWarned: false,
|
|
118
|
+
};
|
|
119
|
+
this.#byDef.set(def, rt);
|
|
120
|
+
this.#byId.set(id, rt);
|
|
121
|
+
this.#byName.set(def.name, rt);
|
|
122
|
+
}
|
|
123
|
+
#runtimeOf(def) {
|
|
124
|
+
const rt = this.#byDef.get(def);
|
|
125
|
+
if (rt === undefined) {
|
|
126
|
+
throw new Error(`topic '${def.name}' is not registered with this world — declare it in a system's publish/consume or publish it once via world.publish`);
|
|
127
|
+
}
|
|
128
|
+
return rt;
|
|
129
|
+
}
|
|
130
|
+
/** The topic's virtual ComponentId, or -1 if not registered. */
|
|
131
|
+
idOf(def) {
|
|
132
|
+
return this.#byDef.get(def)?.id ?? -1;
|
|
133
|
+
}
|
|
134
|
+
/** `(name, id)` pairs for worker id alignment (the boot manifest). */
|
|
135
|
+
manifest() {
|
|
136
|
+
return [...this.#byId.values()].map((rt) => ({ name: rt.name, id: rt.id }));
|
|
137
|
+
}
|
|
138
|
+
/** Scheduler frame hooks: world.publish is illegal while an update is in progress. */
|
|
139
|
+
beginUpdate() {
|
|
140
|
+
if (this.#inUpdate) {
|
|
141
|
+
throw new Error('topics: beginUpdate re-entered — a world update is already in progress (nested scheduler.update?)');
|
|
142
|
+
}
|
|
143
|
+
this.#inUpdate = true;
|
|
144
|
+
this.#everUpdated = true;
|
|
145
|
+
}
|
|
146
|
+
endUpdate() {
|
|
147
|
+
this.#inUpdate = false;
|
|
148
|
+
if (this.#byDef.size === 0)
|
|
149
|
+
return;
|
|
150
|
+
for (const rt of this.#byId.values())
|
|
151
|
+
rt.frameEndHead = rt.head;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* `world.publish` — the outside-systems path (input/network handlers, between frames). Appends
|
|
155
|
+
* directly to the canonical stream in call order, ahead of wave 0 of the next frame. Registers
|
|
156
|
+
* the topic on first use. Serial phase only; inside a system body use `ctx.publish` instead
|
|
157
|
+
* (direct appends mid-update would bypass the SystemId canonicalization).
|
|
158
|
+
*/
|
|
159
|
+
publishOutside(def, init) {
|
|
160
|
+
if (this.#inUpdate) {
|
|
161
|
+
throw new Error(`world.publish('${def.name}') called during world update — world.publish is for code outside systems; use the system's ctx.publish so the event enters the canonical (frame, wave, SystemId, FIFO) order`);
|
|
162
|
+
}
|
|
163
|
+
if (!this.#byDef.has(def))
|
|
164
|
+
this.register(def);
|
|
165
|
+
const rt = this.#runtimeOf(def);
|
|
166
|
+
rt.codec.encode(init, rt.scratchRow, 0);
|
|
167
|
+
this.#appendRow(rt, rt.scratchRow, 0);
|
|
168
|
+
}
|
|
169
|
+
/** `ctx.publish` (main-thread system) — encode now, stage to the system's segment. */
|
|
170
|
+
stageValues(def, systemId, init) {
|
|
171
|
+
const rt = this.#runtimeOf(def);
|
|
172
|
+
rt.codec.encode(init, rt.scratchRow, 0);
|
|
173
|
+
this.#stage(rt, systemId, rt.scratchRow, 0);
|
|
174
|
+
}
|
|
175
|
+
/** OP_PUBLISH apply (worker publishes replayed at the command flush) — stage raw field words. */
|
|
176
|
+
stageWords(topicId, systemId, words, at, fieldWords) {
|
|
177
|
+
const rt = this.#byId.get(topicId);
|
|
178
|
+
if (rt === undefined) {
|
|
179
|
+
this.#warn(`OP_PUBLISH names unknown topic id ${topicId}; record dropped`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (fieldWords !== rt.codec.fieldWords) {
|
|
183
|
+
this.#warn(`OP_PUBLISH for topic '${rt.name}' carries ${fieldWords} field words, expected ${rt.codec.fieldWords}; record dropped`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
this.#stage(rt, systemId, words, at);
|
|
187
|
+
}
|
|
188
|
+
#stage(rt, systemId, words, at) {
|
|
189
|
+
let segment = rt.staged.get(systemId);
|
|
190
|
+
if (segment === undefined) {
|
|
191
|
+
segment = { words: [], events: 0 };
|
|
192
|
+
rt.staged.set(systemId, segment);
|
|
193
|
+
if (rt.staged.size === 1)
|
|
194
|
+
this.#stagedTopics += 1;
|
|
195
|
+
}
|
|
196
|
+
for (let i = 0; i < rt.codec.fieldWords; i++)
|
|
197
|
+
segment.words.push(words[at + i] >>> 0);
|
|
198
|
+
segment.events += 1;
|
|
199
|
+
rt.stagedEvents += 1;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The wave's serial-slot merge: for every topic with staged events, sort the staging segments by
|
|
203
|
+
* publishing SystemId ascending and append each segment FIFO to the canonical stream. Runs once
|
|
204
|
+
* per wave, after the wave's command flush — the single canonicalization point for every
|
|
205
|
+
* execution mode.
|
|
206
|
+
*/
|
|
207
|
+
mergeStaged() {
|
|
208
|
+
this.#everUpdated = true;
|
|
209
|
+
if (this.#stagedTopics === 0)
|
|
210
|
+
return;
|
|
211
|
+
if (this.#phase() !== 'serial') {
|
|
212
|
+
throw new Error('topics: canonical stream merge attempted outside the serial phase');
|
|
213
|
+
}
|
|
214
|
+
for (const rt of this.#byId.values()) {
|
|
215
|
+
if (rt.stagedEvents === 0)
|
|
216
|
+
continue;
|
|
217
|
+
const systemIds = [...rt.staged.keys()].sort((a, b) => a - b);
|
|
218
|
+
const f = rt.codec.fieldWords;
|
|
219
|
+
for (const sid of systemIds) {
|
|
220
|
+
const segment = rt.staged.get(sid);
|
|
221
|
+
for (let e = 0; e < segment.events; e++)
|
|
222
|
+
this.#appendRow(rt, segment.words, e * f);
|
|
223
|
+
}
|
|
224
|
+
rt.staged.clear();
|
|
225
|
+
rt.stagedEvents = 0;
|
|
226
|
+
}
|
|
227
|
+
this.#stagedTopics = 0;
|
|
228
|
+
}
|
|
229
|
+
#appendRow(rt, words, at) {
|
|
230
|
+
if (this.#phase() !== 'serial') {
|
|
231
|
+
throw new Error(`topics: canonical stream for '${rt.name}' mutated outside the serial phase`);
|
|
232
|
+
}
|
|
233
|
+
const seq = rt.head;
|
|
234
|
+
const f = rt.codec.fieldWords;
|
|
235
|
+
if (rt.spillStartSeq === NO_SPILL && (seq - rt.baseSeq + 1) * rt.rowWords <= rt.ring.length) {
|
|
236
|
+
const base = (seq - rt.baseSeq) * rt.rowWords;
|
|
237
|
+
for (let i = 0; i < TOPIC_HEADER_WORDS; i++)
|
|
238
|
+
rt.ring[base + i] = 0;
|
|
239
|
+
for (let i = 0; i < f; i++)
|
|
240
|
+
rt.ring[base + TOPIC_HEADER_WORDS + i] = words[at + i] >>> 0;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
if (rt.spillStartSeq === NO_SPILL)
|
|
244
|
+
rt.spillStartSeq = seq;
|
|
245
|
+
for (let i = 0; i < TOPIC_HEADER_WORDS; i++)
|
|
246
|
+
rt.spill.push(0);
|
|
247
|
+
for (let i = 0; i < f; i++)
|
|
248
|
+
rt.spill.push(words[at + i] >>> 0);
|
|
249
|
+
if (this.#dev && !rt.overflowWarned) {
|
|
250
|
+
rt.overflowWarned = true;
|
|
251
|
+
this.#warn(`topic '${rt.name}' ring overflowed (${Math.floor(rt.ring.length / rt.rowWords)} rows); spilling — the ring grows to 2x peak at the next frame reset`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
rt.head = seq + 1;
|
|
255
|
+
const retained = rt.head - rt.tail;
|
|
256
|
+
if (retained > rt.peakRows)
|
|
257
|
+
rt.peakRows = retained;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Eagerly position a reader's cursor at plan time. Before the first update has ever run
|
|
261
|
+
* (the FIRST plan), the cursor starts at the oldest retained event so `world.publish` calls made
|
|
262
|
+
* before `createScheduler` are still delivered; once any update has run, a newly-added reader
|
|
263
|
+
* (a late re-plan join) starts at the current head — no replay of stale retained events.
|
|
264
|
+
*/
|
|
265
|
+
initCursor(def, readerKey) {
|
|
266
|
+
const rt = this.#runtimeOf(def);
|
|
267
|
+
if (!rt.cursors.has(readerKey))
|
|
268
|
+
rt.cursors.set(readerKey, this.#everUpdated ? rt.head : rt.tail);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Iterate the reader's unseen events up to the current visible head and advance its cursor —
|
|
272
|
+
* exactly-once per (reader, topic), independent cursors per reader (no drain stealing). The
|
|
273
|
+
* yielded view is pooled: read fields inside the loop, never store the view itself.
|
|
274
|
+
*
|
|
275
|
+
* A reader with no cursor starts at the oldest retained event (the manual-consumption default);
|
|
276
|
+
* scheduler consumers are positioned eagerly via `initCursor` at plan time — at the oldest
|
|
277
|
+
* retained event for the first plan (pre-plan `world.publish` events are delivered), at the
|
|
278
|
+
* current head for a re-plan join (no replay).
|
|
279
|
+
*/
|
|
280
|
+
*consume(def, readerKey) {
|
|
281
|
+
const rt = this.#runtimeOf(def);
|
|
282
|
+
let cursor = rt.cursors.get(readerKey) ?? rt.tail;
|
|
283
|
+
if (cursor < rt.tail) {
|
|
284
|
+
if (this.#dev) {
|
|
285
|
+
this.#warn(`topic '${rt.name}': reader '${readerKey}' missed ${rt.tail - cursor} event(s) dropped by retention; cursor snapped to the oldest retained event`);
|
|
286
|
+
}
|
|
287
|
+
cursor = rt.tail;
|
|
288
|
+
}
|
|
289
|
+
// The visible head is frozen for the duration of this iteration: merges happen only at serial
|
|
290
|
+
// slots, never while a system body runs, so `end` is the head as of the consumer's wave start.
|
|
291
|
+
const end = rt.head;
|
|
292
|
+
rt.cursors.set(readerKey, cursor);
|
|
293
|
+
for (let seq = cursor; seq < end; seq++) {
|
|
294
|
+
// Advance BEFORE the yield: a consumer that breaks out of the loop has still observed the
|
|
295
|
+
// yielded event, and exactly-once means it must not be redelivered next consume.
|
|
296
|
+
rt.cursors.set(readerKey, seq + 1);
|
|
297
|
+
if (seq >= rt.spillStartSeq) {
|
|
298
|
+
rt.bind(rt.spill, (seq - rt.spillStartSeq) * rt.rowWords + TOPIC_HEADER_WORDS);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
rt.bind(rt.ring, (seq - rt.baseSeq) * rt.rowWords + TOPIC_HEADER_WORDS);
|
|
302
|
+
}
|
|
303
|
+
yield rt.view;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Frame reset (serial, quiescent): drop events two frames old, fold any spill back into the ring
|
|
308
|
+
* (regrowing it to 2x the observed peak), and compact retained rows to the ring front.
|
|
309
|
+
*/
|
|
310
|
+
frameReset() {
|
|
311
|
+
if (this.#byDef.size === 0)
|
|
312
|
+
return;
|
|
313
|
+
for (const rt of this.#byId.values()) {
|
|
314
|
+
// Frame boundary: events appended after the last update ended belong to the UPCOMING frame
|
|
315
|
+
// (the world.publish input-event path). Without a scheduler (no endUpdate), everything
|
|
316
|
+
// appended so far belongs to the frame now ending.
|
|
317
|
+
const boundary = rt.frameEndHead >= 0 ? rt.frameEndHead : rt.head;
|
|
318
|
+
const newTail = Math.max(rt.tail, rt.prevFrameStart);
|
|
319
|
+
rt.prevFrameStart = boundary;
|
|
320
|
+
rt.frameEndHead = -1;
|
|
321
|
+
this.#compact(rt, newTail);
|
|
322
|
+
rt.peakRows = rt.head - rt.tail;
|
|
323
|
+
rt.overflowWarned = false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
#compact(rt, newTail) {
|
|
327
|
+
const retained = rt.head - newTail;
|
|
328
|
+
const needWords = retained * rt.rowWords;
|
|
329
|
+
const hadSpill = rt.spillStartSeq !== NO_SPILL;
|
|
330
|
+
if (hadSpill || needWords > rt.ring.length) {
|
|
331
|
+
// Regrow to 2x the frame's peak (never below what must be retained right now), then re-place
|
|
332
|
+
// every retained row contiguously from the front.
|
|
333
|
+
const targetRows = Math.max(retained, nextPow2(rt.peakRows * 2));
|
|
334
|
+
const rows = [];
|
|
335
|
+
for (let seq = newTail; seq < rt.head; seq++) {
|
|
336
|
+
const src = seq >= rt.spillStartSeq ? rt.spill : rt.ring;
|
|
337
|
+
const base = seq >= rt.spillStartSeq
|
|
338
|
+
? (seq - rt.spillStartSeq) * rt.rowWords
|
|
339
|
+
: (seq - rt.baseSeq) * rt.rowWords;
|
|
340
|
+
const row = [];
|
|
341
|
+
for (let i = 0; i < rt.rowWords; i++)
|
|
342
|
+
row.push(src[base + i]);
|
|
343
|
+
rows.push(row);
|
|
344
|
+
}
|
|
345
|
+
this.#growRing(rt, targetRows * rt.rowWords);
|
|
346
|
+
for (let r = 0; r < rows.length; r++) {
|
|
347
|
+
const base = r * rt.rowWords;
|
|
348
|
+
for (let i = 0; i < rt.rowWords; i++)
|
|
349
|
+
rt.ring[base + i] = rows[r][i];
|
|
350
|
+
}
|
|
351
|
+
rt.spill = [];
|
|
352
|
+
rt.spillStartSeq = NO_SPILL;
|
|
353
|
+
}
|
|
354
|
+
else if (newTail > rt.baseSeq) {
|
|
355
|
+
// Reclaim the dropped prefix in place so appends keep landing inside the ring.
|
|
356
|
+
rt.ring.copyWithin(0, (newTail - rt.baseSeq) * rt.rowWords, (rt.head - rt.baseSeq) * rt.rowWords);
|
|
357
|
+
}
|
|
358
|
+
rt.baseSeq = newTail;
|
|
359
|
+
rt.tail = newTail;
|
|
360
|
+
}
|
|
361
|
+
#growRing(rt, requiredWords) {
|
|
362
|
+
const region = rt.region;
|
|
363
|
+
const requiredBytes = requiredWords * 4;
|
|
364
|
+
if (requiredBytes <= region.backing.byteLength) {
|
|
365
|
+
rt.ring = region.view;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
// The reactivity-ring growth protocol: in-place resizable grow when the reservation allows,
|
|
369
|
+
// else allocate-copy re-back (serial quiescent point; main thread is the only ring reader in
|
|
370
|
+
// v1 — worker-side consume, and with it the TopicRingGrown re-wrap notice, is the deferred leg).
|
|
371
|
+
const growable = region.backing;
|
|
372
|
+
const resizeFn = growable.grow ?? growable.resize;
|
|
373
|
+
const max = growable.maxByteLength;
|
|
374
|
+
if (typeof resizeFn === 'function' && typeof max === 'number' && requiredBytes <= max) {
|
|
375
|
+
try {
|
|
376
|
+
resizeFn.call(growable, requiredBytes);
|
|
377
|
+
region.view = new Uint32Array(region.backing);
|
|
378
|
+
rt.ring = region.view;
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
// fall through to re-back
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const shared = isSharedBacking(region.backing);
|
|
386
|
+
const fresh = shared ? new SharedArrayBuffer(requiredBytes) : new ArrayBuffer(requiredBytes);
|
|
387
|
+
const freshView = new Uint32Array(fresh);
|
|
388
|
+
freshView.set(region.view);
|
|
389
|
+
region.backing = fresh;
|
|
390
|
+
region.view = freshView;
|
|
391
|
+
rt.ring = freshView;
|
|
392
|
+
}
|
|
393
|
+
// ---- introspection (tests, diagnostics) ------------------------------------------------------
|
|
394
|
+
/** Oldest retained / next sequence numbers for `def`. */
|
|
395
|
+
bounds(def) {
|
|
396
|
+
const rt = this.#runtimeOf(def);
|
|
397
|
+
return { tail: rt.tail, head: rt.head };
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* A copy of the retained canonical stream `[tail, head)` in sequence order — the byte-identity
|
|
401
|
+
* surface the serial-equivalence suite compares across worker counts and transports.
|
|
402
|
+
*/
|
|
403
|
+
streamWords(def) {
|
|
404
|
+
const rt = this.#runtimeOf(def);
|
|
405
|
+
const out = new Uint32Array((rt.head - rt.tail) * rt.rowWords);
|
|
406
|
+
let w = 0;
|
|
407
|
+
for (let seq = rt.tail; seq < rt.head; seq++) {
|
|
408
|
+
const src = seq >= rt.spillStartSeq ? rt.spill : rt.ring;
|
|
409
|
+
const base = seq >= rt.spillStartSeq ? (seq - rt.spillStartSeq) * rt.rowWords : (seq - rt.baseSeq) * rt.rowWords;
|
|
410
|
+
for (let i = 0; i < rt.rowWords; i++)
|
|
411
|
+
out[w++] = src[base + i];
|
|
412
|
+
}
|
|
413
|
+
return out;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/topics/store.ts"],"names":[],"mappings":"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"}
|
package/dist/world.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ import type { ObserverHandle, ObserverHandler, ObserverTerm } from './reactivity
|
|
|
10
10
|
import type { WorldQuery } from '@ecsia/schema';
|
|
11
11
|
import type { SerializationSurface, SerializeRelationProvider } from './serialize-surface.js';
|
|
12
12
|
import type { InspectSurface } from './inspect-surface.js';
|
|
13
|
+
import { Topics } from './topics/index.js';
|
|
14
|
+
import type { TopicDef, TopicEventInit } from './topics/index.js';
|
|
13
15
|
/**: 'serial' during the serial slot (and always, single-threaded); 'wave' only while the scheduler dispatches worker waves. */
|
|
14
16
|
export type WorldPhase = 'serial' | 'wave';
|
|
15
17
|
/**
|
|
@@ -156,6 +158,13 @@ export interface World {
|
|
|
156
158
|
* deterministically. Serial-phase only; called ONLY by the scheduler. Not for user code.
|
|
157
159
|
*/
|
|
158
160
|
__mergeWorkerWrites(pairs: Int32Array | Uint32Array, count: number): void;
|
|
161
|
+
/**
|
|
162
|
+
* Topic store seam. The scheduler registers `publish:`/`consume:`-declared topics, stages
|
|
163
|
+
* `ctx.publish` events, drives the per-wave canonical merge, and routes OP_PUBLISH records here.
|
|
164
|
+
* Serial / main-thread; not for user code — the public surfaces are `world.publish` and the
|
|
165
|
+
* system context's `publish`/`consume`.
|
|
166
|
+
*/
|
|
167
|
+
readonly __topics: Topics;
|
|
159
168
|
/** Current frame tick. Advanced by reactivity at frame reset. */
|
|
160
169
|
readonly tick: number;
|
|
161
170
|
/** Alias for `tick`. */
|
|
@@ -223,6 +232,14 @@ export interface World {
|
|
|
223
232
|
* command buffer and apply at the next serial flush ( re-entrancy safety).
|
|
224
233
|
*/
|
|
225
234
|
observe(term: ObserverTerm, handler: ObserverHandler): ObserverHandle;
|
|
235
|
+
/**
|
|
236
|
+
* Publish one event from OUTSIDE systems (input handlers, network code) — main thread, serial
|
|
237
|
+
* phase, between frames. The event orders ahead of wave 0 of the next frame, in call order, and
|
|
238
|
+
* every system sees it next update. Inside a system body use the context's `publish` instead, so
|
|
239
|
+
* the event enters the canonical (frame, wave, SystemId, FIFO) order; calling this mid-update
|
|
240
|
+
* throws. Values are copied at call time; missing fields take their schema defaults.
|
|
241
|
+
*/
|
|
242
|
+
publish<S extends Schema>(topic: TopicDef<S>, init?: TopicEventInit<S>): void;
|
|
226
243
|
/**
|
|
227
244
|
* Did any component on `handle` change strictly after tick `since`?. Driven by
|
|
228
245
|
* the per-row changeVersion stamps, NOT the write log. Lazily enabled the first time a
|
package/dist/world.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQrE,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEtH,OAAO,KAAK,EAAc,oBAAoB,EAAa,MAAM,mBAAmB,CAAA;AAEpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAOzD,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEhF,OAAO,KAAK,EAAwB,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAChH,OAAO,KAAK,EAAkE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC/G,OAAO,KAAK,EACV,oBAAoB,EAKpB,yBAAyB,EAC1B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAkC,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"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"}
|