koota-kit 0.1.1

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/CONTRIBUTING.md +51 -0
  3. package/LICENSE +21 -0
  4. package/README.md +215 -0
  5. package/SECURITY.md +25 -0
  6. package/dist/cjs/eventLog.cjs +81 -0
  7. package/dist/cjs/eventLog.d.cts +49 -0
  8. package/dist/cjs/eventLog.d.cts.map +1 -0
  9. package/dist/cjs/index.cjs +36 -0
  10. package/dist/cjs/index.d.cts +9 -0
  11. package/dist/cjs/index.d.cts.map +1 -0
  12. package/dist/cjs/package.json +3 -0
  13. package/dist/cjs/rng.cjs +168 -0
  14. package/dist/cjs/rng.d.cts +86 -0
  15. package/dist/cjs/rng.d.cts.map +1 -0
  16. package/dist/cjs/traits/index.cjs +54 -0
  17. package/dist/cjs/traits/index.d.cts +48 -0
  18. package/dist/cjs/traits/index.d.cts.map +1 -0
  19. package/dist/cjs/world.cjs +111 -0
  20. package/dist/cjs/world.d.cts +83 -0
  21. package/dist/cjs/world.d.cts.map +1 -0
  22. package/dist/esm/eventLog.d.ts +49 -0
  23. package/dist/esm/eventLog.d.ts.map +1 -0
  24. package/dist/esm/eventLog.js +78 -0
  25. package/dist/esm/index.d.ts +9 -0
  26. package/dist/esm/index.d.ts.map +1 -0
  27. package/dist/esm/index.js +14 -0
  28. package/dist/esm/rng.d.ts +86 -0
  29. package/dist/esm/rng.d.ts.map +1 -0
  30. package/dist/esm/rng.js +154 -0
  31. package/dist/esm/traits/index.d.ts +48 -0
  32. package/dist/esm/traits/index.d.ts.map +1 -0
  33. package/dist/esm/traits/index.js +51 -0
  34. package/dist/esm/world.d.ts +83 -0
  35. package/dist/esm/world.d.ts.map +1 -0
  36. package/dist/esm/world.js +101 -0
  37. package/docs/API.md +119 -0
  38. package/docs/ARCHITECTURE.md +57 -0
  39. package/docs/assets/favicon.svg +1 -0
  40. package/docs/assets/koota-kit-hero.webp +0 -0
  41. package/docs/changelog.md +13 -0
  42. package/docs/contributing.md +28 -0
  43. package/examples/basic.mjs +27 -0
  44. package/examples/commonjs.cjs +8 -0
  45. package/package.json +173 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. This project follows
4
+ [Semantic Versioning](https://semver.org/) and uses
5
+ [Conventional Commits](https://www.conventionalcommits.org/) to drive releases.
6
+
7
+ ## Unreleased
8
+
9
+ ### Added
10
+
11
+ - Release-ready `@jbdevprimary/koota-kit` package with ESM and CommonJS entry
12
+ points.
13
+ - Idempotent world teardown and validated, atomic snapshot restoration.
14
+ - Independent deterministic `gen` and `events` random streams.
15
+ - Compile-time and runtime guards for object-valued Koota traits.
16
+ - World-scoped event logs with consuming and observational read paths.
17
+ - Runnable examples, package-consumer checks, API/architecture documentation,
18
+ and Node 22/24 Linux plus Node 24 Windows CI coverage.
19
+ - Repository-level LF normalization so formatter checks behave identically on
20
+ Windows, macOS, and Linux checkouts.
21
+
22
+ ### Changed
23
+
24
+ - `WorldHandle.world`, `WorldHandle.seeds`, and `WorldHandle.scratch` are
25
+ readonly references; seed values are copied and frozen at creation.
26
+ - Invalid RNG bounds, probabilities, clock values, event-log keys, and
27
+ persisted headers now fail with `TypeError` or `RangeError` instead of
28
+ producing invalid state.
@@ -0,0 +1,51 @@
1
+ # Contributing
2
+
3
+ Thanks for taking the time to contribute.
4
+
5
+ ## Getting set up
6
+
7
+ With [mise](https://mise.jdx.dev) (recommended — installs the Node and pnpm
8
+ versions pinned in `mise.toml`):
9
+
10
+ ```sh
11
+ mise install
12
+ pnpm install
13
+ pnpm verify # lint, typecheck, test, build — the same gate CI runs
14
+ ```
15
+
16
+ Without mise, use `corepack` so pnpm matches the version pinned in
17
+ `package.json#packageManager`, on any Node release in the `engines.node`
18
+ range (`>=22`; CI verifies 22, 24, and 26 with the official
19
+ `actions/setup-node` + `pnpm/action-setup`):
20
+
21
+ ```sh
22
+ corepack enable
23
+ pnpm install
24
+ pnpm verify
25
+ ```
26
+
27
+ ## Making a change
28
+
29
+ 1. Branch off `main`.
30
+ 2. Write the test first. A bug fix should come with a test that fails without it.
31
+ 3. Run `pnpm verify`. A change is not ready while any part of that is red.
32
+ 4. Commit with [Conventional Commits](https://www.conventionalcommits.org):
33
+ `fix:`, `feat:`, `docs:`, `refactor:`, `test:`, `chore:`. Release Please uses
34
+ these commits to drive the changelog and next version number.
35
+ 5. Open a pull request describing what changed and why.
36
+
37
+ ## What gets reviewed
38
+
39
+ - Does it do what it says, and is there a test proving it?
40
+ - Does it keep the public API honest? A breaking change needs a `!` or a
41
+ `BREAKING CHANGE:` footer.
42
+ - Are the types right for consumers? CI runs `publint` and
43
+ `arethetypeswrong` because broken types only surface at integration time.
44
+ - Do invalid inputs fail before changing clock, RNG, or restored state?
45
+ - Does the change keep Koota-facing behavior aligned with the supported peer?
46
+
47
+ ## Releases
48
+
49
+ Releases are automated. Merging a conventional commit to `main` opens a
50
+ release pull request; merging that publishes to npm with provenance. Do not
51
+ hand-edit versions or the changelog.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jon Bogaty
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # koota-kit
2
+
3
+ ![Two deterministic streams—world generation and runtime events—flow through a simulation clock into modular ECS components.](./docs/assets/koota-kit-hero.webp)
4
+
5
+ [![CI](https://github.com/jbcom/koota-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/jbcom/koota-kit/actions/workflows/ci.yml)
6
+ [![MIT license](https://img.shields.io/badge/license-MIT-17324d.svg)](./LICENSE)
7
+
8
+ Small, production-derived conventions for deterministic simulations built with
9
+ [Koota](https://github.com/pmndrs/koota). koota-kit gives a simulation one
10
+ lifecycle boundary, two independent seeded random streams, safe object-valued
11
+ traits, and world-scoped event logs.
12
+
13
+ It is deliberately **not a game engine**. It is the narrow layer that prevents
14
+ recurring classes of simulation bug without hiding Koota's queries,
15
+ entities, relations, or actions.
16
+
17
+ Full documentation: **[jonbogaty.com/koota-kit](https://jonbogaty.com/koota-kit/)**
18
+
19
+ ## Why use it?
20
+
21
+ | Problem | koota-kit convention |
22
+ | --- | --- |
23
+ | World generation changes after unrelated gameplay draws | Separate `gen` and `events` RNG streams |
24
+ | A loaded save no longer reproduces the next random result | Byte-exact, JSON-safe RNG snapshots |
25
+ | Object state leaks between entities | `defineTrait` requires per-entity factories |
26
+ | A HUD or test consumes an event before its real system sees it | Single-consumer `drain`, non-consuming `peek` |
27
+ | Replaced worlds retain caches or process-global Koota IDs | `createSimWorld` / idempotent `destroySimWorld` lifecycle |
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ pnpm add koota-kit koota
33
+ ```
34
+
35
+ Requirements:
36
+
37
+ - Node.js 22 or newer (CI covers Node 22/24/26 on Linux and Node 24 on Windows)
38
+ - Koota `^0.6.6`, installed by the application as a peer dependency
39
+
40
+ The package ships native ESM and CommonJS entry points with format-correct
41
+ TypeScript declarations.
42
+
43
+ ## Quick start
44
+
45
+ ```ts
46
+ import {
47
+ advanceClock,
48
+ createSimWorld,
49
+ defineEventLog,
50
+ defineTrait,
51
+ destroySimWorld,
52
+ nextInt,
53
+ snapshotWorld,
54
+ } from "koota-kit";
55
+
56
+ const Position = defineTrait({ x: 0, y: 0 });
57
+ const Inventory = defineTrait({ items: () => [] as string[] });
58
+ const moved = defineEventLog<{ entity: number; distance: number }>("movement:completed");
59
+
60
+ const sim = createSimWorld({ gen: "map-42", events: "run-1" });
61
+
62
+ try {
63
+ const scout = sim.world.spawn(Position({ x: 4, y: 9 }), Inventory());
64
+
65
+ advanceClock(sim, 1 / 60);
66
+ const distance = nextInt(sim.rng.events, 1, 5);
67
+ const position = scout.get(Position);
68
+ if (position) scout.set(Position, { ...position, x: position.x + distance });
69
+ moved.push(sim, { entity: Number(scout), distance });
70
+
71
+ // The owning system consumes each event once.
72
+ for (const event of moved.drain(sim)) {
73
+ console.log(event);
74
+ }
75
+
76
+ // Save this beside your own serialized entity/trait state.
77
+ const header = snapshotWorld(sim);
78
+ const serializedHeader = JSON.stringify(header);
79
+ console.log(serializedHeader);
80
+ } finally {
81
+ destroySimWorld(sim);
82
+ }
83
+ ```
84
+
85
+ Runnable ESM and CommonJS versions live in [`examples/`](./examples).
86
+
87
+ ## Core concepts
88
+
89
+ ### One handle owns one simulation
90
+
91
+ `createSimWorld` creates a Koota world, immutable seed values, independent RNG
92
+ streams, a fixed-step clock, and a scratch map. `destroySimWorld` clears the
93
+ scratch map and releases Koota's world ID; it is safe to call more than once.
94
+
95
+ The scratch map is for derived, non-serializable caches and short-lived
96
+ coordination state. Namespace keys by system, for example `pathfinding:grid`
97
+ or `combat:hits`.
98
+
99
+ ### Randomness has two jobs
100
+
101
+ - `rng.gen` defines stable world content: terrain, layouts, initial spawns.
102
+ - `rng.events` defines play history: combat rolls, weather, runtime events.
103
+
104
+ Never key per-entity randomness on packed Koota entity IDs or consume a shared
105
+ stream in query iteration order. Entity IDs contain process-global world and
106
+ generation bits. Derive a local stream from a stable domain key instead:
107
+
108
+ ```ts
109
+ import { createRng, nextU32 } from "koota-kit/rng";
110
+
111
+ const tileRng = createRng({
112
+ gen: `${String(sim.seeds.gen)}/tile:12,8`,
113
+ events: 0,
114
+ });
115
+ const terrainVariant = nextU32(tileRng.gen);
116
+ ```
117
+
118
+ ### Object-valued traits need factories
119
+
120
+ Koota's structure-of-arrays layout can alias a bare object literal across
121
+ entities. koota-kit rejects that form at compile time and runtime:
122
+
123
+ ```ts
124
+ defineTrait({ storage: () => ({ logs: 0 }) }); // correct: one object per entity
125
+ defineTrait({ storage: { logs: 0 } }); // TypeError: shared object footgun
126
+ ```
127
+
128
+ Declare traits once in a leaf module and export each trait from one location.
129
+ Koota identifies traits by reference, not by a string name.
130
+
131
+ ### Event logs have one consuming owner
132
+
133
+ `push` appends, `drain` returns every pending event and empties the log, and
134
+ `peek` returns a copy without consuming. A devtool, HUD, or test should peek;
135
+ the system responsible for acting on the event should drain.
136
+
137
+ ## Persistence boundary
138
+
139
+ `snapshotWorld` stores the clock and both RNG states. It intentionally does not
140
+ serialize entities or traits: those are application data with application-
141
+ specific schemas and migrations. `restoreWorldHeader` validates a parsed save
142
+ before changing the handle and restores atomically.
143
+
144
+ Persist a version beside the header and your ECS state so the application can
145
+ migrate its own schema.
146
+
147
+ ## API and architecture
148
+
149
+ The root package exports the full API. Focused entry points are also available:
150
+
151
+ | Entry point | Purpose |
152
+ | --- | --- |
153
+ | `koota-kit/world` | World lifecycle, clock, Koota facade, world snapshots |
154
+ | `koota-kit/rng` | Seeded streams, bounded draws, snapshots |
155
+ | `koota-kit/traits` | Safe trait declaration |
156
+ | `koota-kit/eventLog` | World-scoped publish/drain logs |
157
+
158
+ See the [API reference](./docs/API.md) for signatures and validation behavior,
159
+ and [architecture notes](./docs/ARCHITECTURE.md) for module boundaries and
160
+ invariants.
161
+
162
+ ## Errors and edge cases
163
+
164
+ - Seeds must be strings or finite numbers.
165
+ - `advanceClock` accepts finite, non-negative `dt`; `0` is a valid paused tick.
166
+ - `nextInt` requires safe-integer bounds with `maxExclusive > minInclusive` and
167
+ a range no larger than `2**32`.
168
+ - `chance` accepts only finite probabilities in `[0, 1]`.
169
+ - Restores reject malformed RNG or clock state before mutating the handle.
170
+ - Event-log keys must be non-empty and cannot reuse a scratch key holding a
171
+ non-array cache.
172
+
173
+ Invalid caller input raises `TypeError` or `RangeError` with the API name in the
174
+ message. No validation failure consumes RNG state or partially restores a
175
+ world header.
176
+
177
+ ## Development
178
+
179
+ ```sh
180
+ mise install # or: corepack enable
181
+ pnpm install --frozen-lockfile
182
+ pnpm verify
183
+ ```
184
+
185
+ Node and pnpm versions live in `mise.toml`; CI verifies against the full
186
+ supported Node range (22, 24, 26).
187
+
188
+ `pnpm verify` runs formatting/lint checks, strict TypeScript, the full test
189
+ suite with 100% coverage thresholds, dual-format builds, both runnable
190
+ examples, `publint`, Are The Types Wrong, and package-content/runtime checks.
191
+
192
+ Useful individual commands:
193
+
194
+ ```sh
195
+ pnpm test # fast behavior suite
196
+ pnpm test:watch # local watch mode
197
+ pnpm coverage # tests plus enforced coverage thresholds
198
+ pnpm build # dist/esm and dist/cjs
199
+ pnpm package:check # exports, declarations, packed files, ESM/CJS parity
200
+ pnpm audit --prod # registry-backed production dependency audit
201
+ ```
202
+
203
+ ## Releases and support
204
+
205
+ Release Please maintains versions and `CHANGELOG.md` from Conventional
206
+ Commits. A release tag triggers a clean verification and npm publication with
207
+ provenance. The latest `0.x` release receives fixes; pre-1.0 APIs may evolve,
208
+ with breaking changes called out in the changelog.
209
+
210
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) before opening a pull request. Report
211
+ security issues privately according to [SECURITY.md](./SECURITY.md).
212
+
213
+ ## License
214
+
215
+ [MIT](./LICENSE) © Jon Bogaty.
package/SECURITY.md ADDED
@@ -0,0 +1,25 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ Please do not open a public issue for a security problem.
6
+
7
+ Report it privately through
8
+ [GitHub Security Advisories](https://github.com/jbcom/koota-kit/security/advisories/new),
9
+ which lets us discuss and fix the issue before it is disclosed.
10
+
11
+ You can expect an acknowledgement within a few days. If a fix is warranted, we
12
+ will prepare it privately, publish a patched release, and credit you in the
13
+ advisory unless you would rather remain anonymous.
14
+
15
+ ## Supported versions
16
+
17
+ The latest `0.x` release receives security fixes. Older pre-1.0 releases are
18
+ not patched unless a coordinated disclosure requires an exceptional backport.
19
+
20
+ ## In scope
21
+
22
+ Examples include malicious persisted snapshot handling, package supply-chain
23
+ issues, unexpected code execution during install/build, and vulnerabilities in
24
+ the package's runtime dependencies. Application authorization and game logic
25
+ built on top of koota-kit are outside this repository's security boundary.
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ // Scratch-backed event logs — the publish/drain seam between sim systems.
3
+ //
4
+ // A fixed-timestep sim needs one system to tell another that something HAPPENED,
5
+ // not merely that some state now differs. The distinction is load-bearing: a
6
+ // system cannot infer an event from state a lower priority band has already
7
+ // consumed, so "a demon was struck this tick" has to be published as a fact
8
+ // rather than reconstructed from health that has already changed.
9
+ //
10
+ // Every such log is the same shape: an array under a well-known scratch key,
11
+ // appended by the owner, drained by exactly one consumer. Consuming systems
12
+ // drain (the log must empty, or a cue plays twice); OBSERVERS — a dev harness, a
13
+ // test, a HUD — must peek instead, because a reader that consumes what a consumer
14
+ // needs is a race, and whichever runs first wins.
15
+ //
16
+ // That distinction is why this is a package module rather than a snippet. It was
17
+ // re-derived ELEVEN times in one consuming game, and three of those sites had no
18
+ // peek at all until an observer silently stole records from the audio bridge and
19
+ // the missing sound was misdiagnosed as a missing swing. The pattern is not hard;
20
+ // getting it wrong is quiet, and it costs a debugging session every time.
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.defineEventLog = defineEventLog;
23
+ /**
24
+ * Declare an event log under `key`.
25
+ *
26
+ * The array is created lazily on first use and lives in `handle.scratch`, so it
27
+ * lifecycles with the world: a new run starts with empty logs and cannot inherit
28
+ * the last one's events. That is not a detail — a log at module scope survives
29
+ * the world that produced it, and stale events replay into a fresh run.
30
+ *
31
+ * Keys should be namespaced by system (`"combat:hits"`, `"voices:events"`) for
32
+ * the same reason trait names are: scratch is one flat map shared by every
33
+ * system in the world. Empty keys are rejected, as is a collision with an
34
+ * existing non-array scratch value.
35
+ */
36
+ function defineEventLog(key) {
37
+ if (typeof key !== "string" || key.trim().length === 0) {
38
+ throw new TypeError("defineEventLog: key must be a non-empty string.");
39
+ }
40
+ const existingFor = (handle) => {
41
+ const existing = handle.scratch.get(key);
42
+ if (existing === undefined)
43
+ return undefined;
44
+ if (!Array.isArray(existing)) {
45
+ throw new TypeError(`Event log "${key}" cannot use its scratch key because it already holds a non-array value.`);
46
+ }
47
+ return existing;
48
+ };
49
+ const arrayFor = (handle) => {
50
+ const existing = existingFor(handle);
51
+ if (existing)
52
+ return existing;
53
+ const log = [];
54
+ handle.scratch.set(key, log);
55
+ return log;
56
+ };
57
+ return {
58
+ key,
59
+ push: (handle, event) => {
60
+ arrayFor(handle).push(event);
61
+ },
62
+ drain: (handle) => {
63
+ const log = existingFor(handle);
64
+ if (!log)
65
+ return [];
66
+ // Copy, then truncate IN PLACE rather than replacing the array: another
67
+ // system may already hold this reference, and swapping in a new array
68
+ // would leave that holder appending into an orphan nobody drains.
69
+ const out = log.slice();
70
+ log.length = 0;
71
+ return out;
72
+ },
73
+ peek: (handle) => existingFor(handle)?.slice() ?? [],
74
+ clear: (handle) => {
75
+ const log = existingFor(handle);
76
+ if (log)
77
+ log.length = 0;
78
+ },
79
+ size: (handle) => existingFor(handle)?.length ?? 0,
80
+ };
81
+ }
@@ -0,0 +1,49 @@
1
+ import type { WorldHandle } from "./world.cjs";
2
+ /**
3
+ * A published event log: append here, drain or peek from the other side.
4
+ *
5
+ * Returned as an object rather than loose functions so a system declares its log
6
+ * ONCE at module scope and the key is written in exactly one place. Two string
7
+ * literals for the same log is the typo that produces an event stream nobody
8
+ * receives, and no type checker can catch it.
9
+ */
10
+ export type EventLog<T> = {
11
+ /** The scratch key, exposed for debugging and for snapshot tooling. */
12
+ readonly key: string;
13
+ /** Append an event. Called by the system that owns the fact. */
14
+ push: (handle: WorldHandle, event: T) => void;
15
+ /**
16
+ * Take every event and EMPTY the log — for the single consuming system.
17
+ *
18
+ * If two systems both need the same events, that is a design question and not
19
+ * a reason to drain twice: publish two logs, or have the second peek. A log
20
+ * drained by two consumers delivers each event to whichever ran first.
21
+ */
22
+ drain: (handle: WorldHandle) => T[];
23
+ /**
24
+ * Read every event WITHOUT emptying — for observers: harnesses, tests, HUDs.
25
+ *
26
+ * Returns a readonly copy, so a caller cannot mutate the live array and
27
+ * cannot hold a reference that changes underneath them.
28
+ */
29
+ peek: (handle: WorldHandle) => readonly T[];
30
+ /** Drop everything without reading. For run teardown and test setup. */
31
+ clear: (handle: WorldHandle) => void;
32
+ /** How many events are pending, without allocating a copy. */
33
+ size: (handle: WorldHandle) => number;
34
+ };
35
+ /**
36
+ * Declare an event log under `key`.
37
+ *
38
+ * The array is created lazily on first use and lives in `handle.scratch`, so it
39
+ * lifecycles with the world: a new run starts with empty logs and cannot inherit
40
+ * the last one's events. That is not a detail — a log at module scope survives
41
+ * the world that produced it, and stale events replay into a fresh run.
42
+ *
43
+ * Keys should be namespaced by system (`"combat:hits"`, `"voices:events"`) for
44
+ * the same reason trait names are: scratch is one flat map shared by every
45
+ * system in the world. Empty keys are rejected, as is a collision with an
46
+ * existing non-array scratch value.
47
+ */
48
+ export declare function defineEventLog<T>(key: string): EventLog<T>;
49
+ //# sourceMappingURL=eventLog.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventLog.d.ts","sourceRoot":"","sources":["../../src/eventLog.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,EAAE,CAAC;IACpC;;;;;OAKG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAC,EAAE,CAAC;IAC5C,wEAAwE;IACxE,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC,8DAA8D;IAC9D,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC;CACvC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CA6C1D"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ // koota-kit — thin koota ECS conventions layer.
3
+ //
4
+ // Four modules, also importable as subpaths:
5
+ // ./world — WorldHandle lifecycle (world + dual-stream rng + clock + scratch)
6
+ // ./rng — dual-layer deterministic seedrandom PRNG with byte-exact
7
+ // snapshot/restore
8
+ // ./traits — defineTrait AoS-aliasing guard (leaf module, zero sibling
9
+ // imports)
10
+ // ./eventLog — scratch-backed publish/drain event logs with a peek seam for
11
+ // observers (harnesses, tests, HUDs)
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.defineTrait = exports.defineEventLog = exports.snapshotStream = exports.snapshotLayers = exports.restoreStream = exports.restoreLayers = exports.nextU32 = exports.nextInt = exports.nextFloat = exports.createRng = exports.chance = exports.trait = exports.snapshotWorld = exports.restoreWorldHeader = exports.relation = exports.destroySimWorld = exports.createSimWorld = exports.createActions = exports.advanceClock = void 0;
14
+ var world_js_1 = require("./world.cjs");
15
+ Object.defineProperty(exports, "advanceClock", { enumerable: true, get: function () { return world_js_1.advanceClock; } });
16
+ Object.defineProperty(exports, "createActions", { enumerable: true, get: function () { return world_js_1.createActions; } });
17
+ Object.defineProperty(exports, "createSimWorld", { enumerable: true, get: function () { return world_js_1.createSimWorld; } });
18
+ Object.defineProperty(exports, "destroySimWorld", { enumerable: true, get: function () { return world_js_1.destroySimWorld; } });
19
+ Object.defineProperty(exports, "relation", { enumerable: true, get: function () { return world_js_1.relation; } });
20
+ Object.defineProperty(exports, "restoreWorldHeader", { enumerable: true, get: function () { return world_js_1.restoreWorldHeader; } });
21
+ Object.defineProperty(exports, "snapshotWorld", { enumerable: true, get: function () { return world_js_1.snapshotWorld; } });
22
+ Object.defineProperty(exports, "trait", { enumerable: true, get: function () { return world_js_1.trait; } });
23
+ var rng_js_1 = require("./rng.cjs");
24
+ Object.defineProperty(exports, "chance", { enumerable: true, get: function () { return rng_js_1.chance; } });
25
+ Object.defineProperty(exports, "createRng", { enumerable: true, get: function () { return rng_js_1.createRng; } });
26
+ Object.defineProperty(exports, "nextFloat", { enumerable: true, get: function () { return rng_js_1.nextFloat; } });
27
+ Object.defineProperty(exports, "nextInt", { enumerable: true, get: function () { return rng_js_1.nextInt; } });
28
+ Object.defineProperty(exports, "nextU32", { enumerable: true, get: function () { return rng_js_1.nextU32; } });
29
+ Object.defineProperty(exports, "restoreLayers", { enumerable: true, get: function () { return rng_js_1.restoreLayers; } });
30
+ Object.defineProperty(exports, "restoreStream", { enumerable: true, get: function () { return rng_js_1.restoreStream; } });
31
+ Object.defineProperty(exports, "snapshotLayers", { enumerable: true, get: function () { return rng_js_1.snapshotLayers; } });
32
+ Object.defineProperty(exports, "snapshotStream", { enumerable: true, get: function () { return rng_js_1.snapshotStream; } });
33
+ var eventLog_js_1 = require("./eventLog.cjs");
34
+ Object.defineProperty(exports, "defineEventLog", { enumerable: true, get: function () { return eventLog_js_1.defineEventLog; } });
35
+ var index_js_1 = require("./traits/index.cjs");
36
+ Object.defineProperty(exports, "defineTrait", { enumerable: true, get: function () { return index_js_1.defineTrait; } });
@@ -0,0 +1,9 @@
1
+ export { advanceClock, createActions, createSimWorld, destroySimWorld, relation, restoreWorldHeader, snapshotWorld, trait, } from "./world.cjs";
2
+ export type { Entity, World, WorldHandle, WorldSnapshot } from "./world.cjs";
3
+ export { chance, createRng, nextFloat, nextInt, nextU32, restoreLayers, restoreStream, snapshotLayers, snapshotStream, } from "./rng.cjs";
4
+ export type { RngLayers, RngLayersSnapshot, RngSeeds, RngStream, RngStreamSnapshot, } from "./rng.cjs";
5
+ export { defineEventLog } from "./eventLog.cjs";
6
+ export type { EventLog } from "./eventLog.cjs";
7
+ export { defineTrait } from "./traits/index.cjs";
8
+ export type { SafeSchema } from "./traits/index.cjs";
9
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,KAAK,GACN,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EACL,MAAM,EACN,SAAS,EACT,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }