@arcforge/cognet 2.0.167 → 2.0.168

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcforge/cognet",
3
- "version": "2.0.167",
3
+ "version": "2.0.168",
4
4
  "description": "The cognet authoring surface for Axon — an agent's brain, compiled, versioned and swappable.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -17,8 +17,8 @@
17
17
  "deploy": "echo \"This package is published ONLY by apps/tui/scripts/release.ts, which pins workspace:* deps to concrete versions first. Publishing it directly ships an unresolvable dependency.\" && exit 1"
18
18
  },
19
19
  "dependencies": {
20
- "@arcforge/err": "2.0.167",
21
- "@arcforge/types": "2.0.167",
20
+ "@arcforge/err": "2.0.168",
21
+ "@arcforge/types": "2.0.168",
22
22
  "hookable": "^5.5.3"
23
23
  },
24
24
  "devDependencies": {
package/src/clock.ts CHANGED
@@ -48,7 +48,10 @@ export function Clock(opts: ClockOpts) {
48
48
  get tick() {
49
49
  return tick
50
50
  },
51
- get phase() {
51
+ // Annotated: without it the inferred return collapses to `null` (the
52
+ // initializer's type), so a consumer comparing it to a phase name gets
53
+ // a "no overlap" error for a comparison that is exactly the point.
54
+ get phase(): string | null {
52
55
  return phase
53
56
  },
54
57
  stamp,
@@ -1,5 +1,5 @@
1
1
  import type { StateT } from "./state"
2
- import type { ComponentRegistry, ComponentType, EntityId } from "./types"
2
+ import type { ComponentRegistry, ComponentType, EntityId, ComponentData } from "./types"
3
3
  import type { EcsEmit } from "./ecs"
4
4
 
5
5
  type ComponentOpts = {
@@ -41,11 +41,11 @@ export function Component(opts: ComponentOpts) {
41
41
  }: {
42
42
  entity: EntityId
43
43
  type: K
44
- data: ComponentRegistry[K]
44
+ data: ComponentData<K>
45
45
  }) {
46
46
  let store = state.components.get(type)
47
47
  if (!store) {
48
- store = new Map<EntityId, ComponentRegistry[K]>()
48
+ store = new Map<EntityId, ComponentData<K>>()
49
49
  state.components.set(type, store)
50
50
  }
51
51
 
@@ -79,7 +79,7 @@ export function Component(opts: ComponentOpts) {
79
79
  }: {
80
80
  entity: EntityId
81
81
  type: K
82
- }): ComponentRegistry[K] | undefined {
82
+ }): ComponentData<K> | undefined {
83
83
  return state.components.get(type)?.get(entity)
84
84
  },
85
85
 
package/src/ecs/entity.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ComponentT } from "./component"
2
2
  import type { StateT } from "./state"
3
- import type { ComponentRegistry, ComponentType, EntityId } from "./types"
3
+ import type { ComponentRegistry, ComponentType, EntityId, ComponentData } from "./types"
4
4
  import type { EcsEmit } from "./ecs"
5
5
 
6
6
  type EntityOpts = {
@@ -23,8 +23,8 @@ export function Entity(opts: EntityOpts) {
23
23
  }: {
24
24
  entity: EntityId
25
25
  components?:
26
- | { type: K; data: ComponentRegistry[K] }
27
- | { type: K; data: ComponentRegistry[K] }[]
26
+ | { type: K; data: ComponentData<K> }
27
+ | { type: K; data: ComponentData<K> }[]
28
28
  }) {
29
29
  state.entities.add(entity)
30
30
  void emit("cognet:entity:add", { ...state.stamp(), entity })
package/src/ecs/types.ts CHANGED
@@ -15,7 +15,22 @@ export interface ComponentRegistry {
15
15
  }
16
16
 
17
17
  export type EntityId = string
18
- export type ComponentType = keyof ComponentRegistry
18
+ /**
19
+ * A component's type name.
20
+ *
21
+ * Falls back to `string` when nothing has augmented the registry, for the same
22
+ * reason `AxonPromptName` does: `keyof` an empty interface is `never`, which
23
+ * makes every parameter typed by it accept NO argument. The whole component
24
+ * API — add, get, has, remove — was uncallable for any consumer that had not
25
+ * augmented `ComponentRegistry` first, including every test in this package.
26
+ *
27
+ * A kernel that DOES augment gets the narrow union and its typo-checking back;
28
+ * one that has not gets a usable API instead of an unusable one.
29
+ */
30
+ export type ComponentType = keyof ComponentRegistry extends never ? string : keyof ComponentRegistry
31
+
32
+ /** The data one component type carries — `unknown` when the registry is unaugmented. */
33
+ export type ComponentData<K extends ComponentType> = K extends keyof ComponentRegistry ? ComponentRegistry[K] : unknown
19
34
  export type ComponentStore<T = any> = Map<EntityId, T>
20
35
 
21
36
  /** Fired synchronously after every component write of a watched type. */