@adobe/ecs 0.2.0 → 0.2.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.
- package/dist/implementation/world/create.js.map +1 -1
- package/dist/implementation/world/finalizers.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.js.map +1 -1
- package/dist/interface/component/component.d.ts +7 -1
- package/dist/interface/component/component.js +0 -1
- package/dist/interface/component/component.js.map +1 -1
- package/dist/interface/component/index.d.ts +1 -1
- package/dist/interface/component/value.d.ts +5 -5
- package/dist/interface/component/values.d.ts +2 -2
- package/dist/interface/finalizer/body.d.ts +5 -5
- package/dist/interface/resource/condition.d.ts +3 -3
- package/dist/interface/resource/index.d.ts +0 -1
- package/dist/interface/resource/resource.d.ts +4 -1
- package/dist/interface/resource/resource.js +0 -1
- package/dist/interface/resource/resource.js.map +1 -1
- package/dist/interface/resource/value.d.ts +5 -5
- package/dist/interface/resources/cadence.d.ts +1 -1
- package/dist/interface/system/access.d.ts +1 -1
- package/dist/interface/system/body.d.ts +2 -2
- package/dist/interface/system/commands.d.ts +4 -4
- package/dist/interface/system/struct.d.ts +2 -2
- package/dist/interface/system/values-of.d.ts +4 -4
- package/dist/interface/system/values.d.ts +5 -5
- package/dist/interface/trait/types.d.ts +4 -4
- package/dist/interface/world/create.d.ts +3 -7
- package/dist/interface/world/declarations.d.ts +2 -2
- package/dist/interface/world/join.d.ts +2 -10
- package/package.json +1 -1
- package/src/exports.test.ts +2 -2
- package/src/guide/03-systems.out +1 -1
- package/src/guide/11-traits.type-test.ts +1 -1
- package/src/guide/18-identity.out +1 -1
- package/src/implementation/world/create.ts +3 -3
- package/src/implementation/world/finalizers.ts +3 -3
- package/src/implementation/world/pool-size.cases.ts +3 -1
- package/src/implementation/world/reads.test-helper.ts +6 -6
- package/src/index.ts +24 -1
- package/src/interface/component/component.ts +7 -1
- package/src/interface/component/index.ts +1 -1
- package/src/interface/component/value.ts +5 -5
- package/src/interface/component/values.ts +2 -2
- package/src/interface/finalizer/body.ts +5 -5
- package/src/interface/index.type-test.ts +1 -1
- package/src/interface/resource/condition.ts +3 -3
- package/src/interface/resource/index.ts +0 -1
- package/src/interface/resource/resource.ts +4 -1
- package/src/interface/resource/value.ts +5 -5
- package/src/interface/resources/cadence.ts +1 -1
- package/src/interface/system/access.ts +1 -1
- package/src/interface/system/body.ts +2 -2
- package/src/interface/system/commands.ts +4 -4
- package/src/interface/system/struct.ts +2 -2
- package/src/interface/system/values-of.ts +4 -4
- package/src/interface/system/values.ts +5 -5
- package/src/interface/thread/thread.type-test.ts +1 -1
- package/src/interface/trait/trait.type-test.ts +4 -4
- package/src/interface/trait/types.ts +4 -4
- package/src/interface/world/create.ts +3 -7
- package/src/interface/world/declarations.ts +2 -2
- package/src/interface/world/join.ts +2 -10
- package/src/interface/world/loop.type-test.ts +6 -6
- package/src/observe/members.ts +3 -3
- package/src/observe/query.ts +1 -1
- package/src/observe/select.ts +1 -1
- package/src/observe/values.ts +2 -2
|
@@ -16,7 +16,7 @@ const gpuOnly = Symbol("traitTest/gpuOnly");
|
|
|
16
16
|
const nonPersistent = Symbol("traitTest/nonPersistent");
|
|
17
17
|
declare module '@adobe/ecs' {
|
|
18
18
|
export interface Traits<N> {
|
|
19
|
-
readonly [gpuOnly]: N extends Component.Key ? (IsStruct<Component
|
|
19
|
+
readonly [gpuOnly]: N extends Component.Key ? (IsStruct<Component<N>> extends true ? true : never) : never;
|
|
20
20
|
readonly [nonPersistent]: N extends Component.Key ? (Components[N] extends { readonly derived: true } ? never : true) : true;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -53,15 +53,15 @@ declare module '@adobe/ecs' {
|
|
|
53
53
|
|
|
54
54
|
// Types filter components by their traits and value types.
|
|
55
55
|
type Ours = typeof parent | typeof follows | typeof slot | typeof ready | typeof score | typeof link | typeof pair | typeof cache;
|
|
56
|
-
check<Equal<Component
|
|
57
|
-
check<Equal<Component
|
|
56
|
+
check<Equal<Component<typeof parent>, Entity>>();
|
|
57
|
+
check<Equal<Component<typeof link>, { readonly to: Entity; readonly weight: number }>>();
|
|
58
58
|
check<Equal<Extract<Component.With<"reference">, Ours>, typeof parent | typeof follows>>();
|
|
59
59
|
check<Equal<Extract<Component.With<"reference", "owner">, Ours>, typeof parent>>();
|
|
60
60
|
check<Equal<Extract<Derived, Ours>, typeof slot>>();
|
|
61
61
|
check<Equal<Extract<Component.With<typeof gpuOnly>, Ours>, typeof pair>>();
|
|
62
62
|
type Persisted = Exclude<Essential, Component.With<typeof nonPersistent>>;
|
|
63
63
|
check<Equal<Extract<Persisted, Ours>, Exclude<Ours, typeof slot | typeof cache>>>();
|
|
64
|
-
check<Equal<Resource
|
|
64
|
+
check<Equal<Resource<typeof time>, number>>();
|
|
65
65
|
|
|
66
66
|
// Commands add and remove only essential components.
|
|
67
67
|
export const issue = (commands: Commands, entity: Entity): void => {
|
|
@@ -9,7 +9,7 @@ import type { IsComparable, IsString, IsStruct } from '../schema/is-struct.js';
|
|
|
9
9
|
import type { Thread } from '../thread/thread.js';
|
|
10
10
|
|
|
11
11
|
/** The value type of the component or resource `N`. */
|
|
12
|
-
type ValueOf<N> = N extends Component.Key ? Component
|
|
12
|
+
type ValueOf<N> = N extends Component.Key ? Component<N> : N extends Resource.Key ? Resource<N> : never;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Whether each component's and resource's value is a struct, `"string"` for a string, computed once so a check is a
|
|
@@ -39,14 +39,14 @@ export interface Traits<N extends Component.Key | Resource.Key> {
|
|
|
39
39
|
* component. Not on a derived component, whose target only a command could set.
|
|
40
40
|
*/
|
|
41
41
|
readonly reference: N extends Component.Key
|
|
42
|
-
? Components[N] extends { readonly derived: true } | { readonly shared: true } ? never : [Component
|
|
42
|
+
? Components[N] extends { readonly derived: true } | { readonly shared: true } ? never : [Component<N>] extends [Entity] ? "owner" | "weak" : never
|
|
43
43
|
: never;
|
|
44
44
|
/**
|
|
45
45
|
* On a resource, the operator systems reduce into it with: each run that a contributor runs in starts it at the
|
|
46
46
|
* operator's identity and leaves it holding the fold of every contribution. Booleans fold bitwise.
|
|
47
47
|
*/
|
|
48
48
|
readonly reduce: N extends Resource.Key
|
|
49
|
-
? [Resource
|
|
49
|
+
? [Resource<N>] extends [boolean] ? "&" | "|" | "^" : Structs[N] extends true ? Reduction : never
|
|
50
50
|
: never;
|
|
51
51
|
/**
|
|
52
52
|
* The logical thread an object lives on, `"world"` without it. Not on a struct or a string, which live in shared
|
|
@@ -64,6 +64,6 @@ export interface Traits<N extends Component.Key | Resource.Key> {
|
|
|
64
64
|
* reference, and it has no thread: every thread reads it.
|
|
65
65
|
*/
|
|
66
66
|
readonly shared: N extends Component.Key
|
|
67
|
-
? Components[N] extends { readonly derived: true } | { readonly reference: unknown } ? never : IsComparable<Component
|
|
67
|
+
? Components[N] extends { readonly derived: true } | { readonly reference: unknown } ? never : IsComparable<Component<N>> extends true ? true : never
|
|
68
68
|
: never;
|
|
69
69
|
}
|
|
@@ -5,15 +5,11 @@ import type { InvalidDeclarations } from './declarations.js';
|
|
|
5
5
|
import type { World } from './world.js';
|
|
6
6
|
|
|
7
7
|
/** Values resources start at in place of their defaults: any but those only the world writes. */
|
|
8
|
-
export type InitialResources = { readonly [K in Exclude<Resource.Key, WorldWritten>]?: Resource
|
|
8
|
+
export type InitialResources = { readonly [K in Exclude<Resource.Key, WorldWritten>]?: Resource<K> };
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* device, and fills every logical thread no joined thread claims. Keys are the resources' symbols, built-in ones
|
|
14
|
-
* included (`{ [workers]: 0 }`); string keys are never a resource's, so they're ignored. Throws for a symbol that isn't
|
|
15
|
-
* a resource, or is one only the world writes. While a declaration's trait or default doesn't hold, each call fails to
|
|
16
|
-
* compile, once, naming each such key, its members and what's wrong with them.
|
|
11
|
+
* The type of `World.create`.
|
|
12
|
+
* @inline
|
|
17
13
|
*/
|
|
18
14
|
export type Create = (
|
|
19
15
|
// Unknown while every declaration holds; else what a call's `this` can't be, so the call reports it, printed whole.
|
|
@@ -30,5 +30,5 @@ type Reported<K, Members extends PropertyKey> = [Members] extends [never] ? neve
|
|
|
30
30
|
* `World.create` reports these.
|
|
31
31
|
*/
|
|
32
32
|
export type InvalidDeclarations =
|
|
33
|
-
| { readonly [K in Component.Key]: Reported<K, Invalid<K, Components[K], Component
|
|
34
|
-
| { readonly [K in Resource.Key]: Reported<K, Invalid<K, Resources[K], Resource
|
|
33
|
+
| { readonly [K in Component.Key]: Reported<K, Invalid<K, Components[K], Component<K>>> }[Component.Key]
|
|
34
|
+
| { readonly [K in Resource.Key]: Reported<K, Invalid<K, Resources[K], Resource<K>>> }[Resource.Key];
|
|
@@ -3,15 +3,7 @@ import type { Thread } from '../thread/thread.js';
|
|
|
3
3
|
import type { World } from './world.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* once the world accepted the claim, to the same world: its `run` runs systems there, and its `add` and `remove` take
|
|
9
|
-
* observer systems, which run here after the world's sync points. Add them before awaiting anything else, so the
|
|
10
|
-
* world's `share` resolves with them in place. Its `dispose` disconnects this thread. Rejects with an `Error` saying
|
|
11
|
-
* why it didn't join: the world refused the claim, was disposed, or its thread ended first, as the platform reports it:
|
|
12
|
-
* the world's `Worker` failing to start or throwing first, a port closed, as in node, or, in a browser, the world's
|
|
13
|
-
* thread ending once it was shared through a port this thread listened on. A browser world's worker that the page ended
|
|
14
|
-
* before this thread heard from it isn't reported, so the join stays pending. Rejects too where memory can't be shared,
|
|
15
|
-
* as without cross-origin isolation.
|
|
6
|
+
* The type of `World.join`.
|
|
7
|
+
* @inline
|
|
16
8
|
*/
|
|
17
9
|
export type Join = (port: Parameters<World["share"]>[0], options?: { readonly threads?: readonly Exclude<Thread, "world">[] }) => Promise<World>;
|
|
@@ -25,14 +25,14 @@ world.remove(move);
|
|
|
25
25
|
void removed;
|
|
26
26
|
|
|
27
27
|
// Built-in resources.
|
|
28
|
-
check<Equal<Resource
|
|
29
|
-
check<Equal<Resource
|
|
28
|
+
check<Equal<Resource<typeof gpuDevice>, GPUDevice | null>>();
|
|
29
|
+
check<Equal<Resource<typeof workers>, number | null>>();
|
|
30
30
|
// null is the platform's choice of pool size.
|
|
31
31
|
export const platformPool: World = create({ [workers]: null });
|
|
32
|
-
check<Equal<Resource
|
|
33
|
-
check<Equal<Resource
|
|
34
|
-
check<Equal<Resource
|
|
35
|
-
check<Equal<Resource
|
|
32
|
+
check<Equal<Resource<typeof always>, boolean>>();
|
|
33
|
+
check<Equal<Resource<typeof wake>, number>>();
|
|
34
|
+
check<Equal<Resource<typeof clock>, { readonly now: number; readonly delta: number; readonly tick: number }>>();
|
|
35
|
+
check<Equal<Resource<typeof cadence>, { readonly kind: "frame" } | { readonly kind: "fixed"; readonly step: number; readonly maxSteps?: number }>>();
|
|
36
36
|
// Built-in resources are symbols, so worlds start them at other values through their imported keys.
|
|
37
37
|
check<Equal<[typeof gpuDevice, typeof workers, typeof cadence, typeof always, typeof wake, typeof clock] extends readonly symbol[] ? true : false, true>>();
|
|
38
38
|
// @ts-expect-error a resource key is its imported symbol, never its description
|
package/src/observe/members.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Observe } from './observe.js';
|
|
|
5
5
|
import { observeCount, observeSelect } from './select.js';
|
|
6
6
|
import type { Query } from './query.js';
|
|
7
7
|
import { observeResource } from './resource.js';
|
|
8
|
-
import type {
|
|
8
|
+
import type { ReadonlyResourceType, ReadonlyType } from './values.js';
|
|
9
9
|
|
|
10
10
|
export { toPromise } from './to-promise.js';
|
|
11
11
|
export type { Query } from './query.js';
|
|
@@ -14,7 +14,7 @@ export type { Query } from './query.js';
|
|
|
14
14
|
* A resource's value, then a new one after each run or tick that changed it: one whose sync point stamped it, even with
|
|
15
15
|
* the same value, a reduced resource when its fold differs.
|
|
16
16
|
*/
|
|
17
|
-
export const resource = <R extends Resource.Key>(world: World, resource: R): Observe<
|
|
17
|
+
export const resource = <R extends Resource.Key>(world: World, resource: R): Observe<ReadonlyResourceType<R>> =>
|
|
18
18
|
observeResource(world, resource);
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -27,7 +27,7 @@ export const entity = <const R extends readonly Component.Key[] = [], const O ex
|
|
|
27
27
|
world: World,
|
|
28
28
|
entity: Entity,
|
|
29
29
|
components: { readonly required?: R; readonly optional?: O },
|
|
30
|
-
): Observe<({ readonly [K in keyof Pick<Components, R[number]>]:
|
|
30
|
+
): Observe<({ readonly [K in keyof Pick<Components, R[number]>]: ReadonlyType<K> } & { readonly [K in keyof Pick<Components, O[number]>]?: ReadonlyType<K> }) | null> =>
|
|
31
31
|
observeEntity(world, entity, components);
|
|
32
32
|
|
|
33
33
|
/**
|
package/src/observe/query.ts
CHANGED
|
@@ -10,7 +10,7 @@ type Comparison<T> = {
|
|
|
10
10
|
readonly ">="?: T;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
type ValuesOf<C extends readonly Component.Key[]> = { readonly [K in C[number]]: Component
|
|
13
|
+
type ValuesOf<C extends readonly Component.Key[]> = { readonly [K in C[number]]: Component<K> };
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Entities that have every component in `required`, every entity but the resource entity without it, and none in
|
package/src/observe/select.ts
CHANGED
|
@@ -161,7 +161,7 @@ const rangeOf = (condition: unknown): Range => {
|
|
|
161
161
|
return bounds.length === 0 ? unbounded : { range, bounds, exact };
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
-
type Value = Component
|
|
164
|
+
type Value = Component<Component.Key>;
|
|
165
165
|
|
|
166
166
|
/** A value or comparison a sorted index on one key part looks up by. */
|
|
167
167
|
type Bound = Value | { readonly "<="?: Value; readonly ">="?: Value; readonly "=="?: Value };
|
package/src/observe/values.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Component, Resource } from '../interface/index.js';
|
|
|
4
4
|
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
5
5
|
|
|
6
6
|
/** Component `K`'s value as observers give it: read-only, with branded primitives such as `Entity` as they are. */
|
|
7
|
-
export type
|
|
7
|
+
export type ReadonlyType<K extends Component.Key> = Component<K> extends Primitive ? Component<K> : Readonly<Component<K>>;
|
|
8
8
|
|
|
9
9
|
/** Resource `K`'s value as observers give it. */
|
|
10
|
-
export type
|
|
10
|
+
export type ReadonlyResourceType<K extends Resource.Key> = Resource<K> extends Primitive ? Resource<K> : Readonly<Resource<K>>;
|