koota 0.1.12 → 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/README.md +13 -4
- package/dist/{chunk-FAWXK4QV.js → chunk-4QEK6BHY.js} +10 -5
- package/dist/index.cjs +13 -8
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/react.cjs +50 -35
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +20 -24
- package/dist/{world-CIrtrsKj.d.cts → world-DQXl4lI8.d.cts} +4 -6
- package/dist/{world-CIrtrsKj.d.ts → world-DQXl4lI8.d.ts} +4 -6
- package/package.json +15 -16
- package/react/index.cjs +50 -35
- package/react/index.d.cts +1 -1
- package/react/index.d.ts +1 -1
- package/react/index.js +20 -24
package/README.md
CHANGED
|
@@ -283,6 +283,15 @@ const movedEntities = world.query(Changed(Position));
|
|
|
283
283
|
// After running the query, the Changed modifier is reset
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
+
### Query all entities
|
|
287
|
+
|
|
288
|
+
To get al queryable entities you simply query with not paramerters. Note, that not all entities are queryable. Any entity that has `IsExcluded` will not be able to be queried. This is used in Koota to exclude world entities, for example, but maybe used for other system level entities in the future. To get all entities regardless, use `world.entities`.
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
// Returns all queryable entities
|
|
292
|
+
const allQueryableEntities = world.query()
|
|
293
|
+
```
|
|
294
|
+
|
|
286
295
|
### Add, remove and change events
|
|
287
296
|
|
|
288
297
|
Koota allows you to subscribe to add, remove, and change events for specific traits.
|
|
@@ -309,7 +318,7 @@ entity.set(Position, { x: 10, y: 20 });
|
|
|
309
318
|
entity.remove(Position);
|
|
310
319
|
```
|
|
311
320
|
|
|
312
|
-
### Change detection with `
|
|
321
|
+
### Change detection with `updateEach`
|
|
313
322
|
|
|
314
323
|
By default, `updateEach` will automatically turn on change detection for traits that are being tracked via `onChange` or the `Changed` modifier. If you want to silence change detection for a loop or force it to always run, you can do so with an options config.
|
|
315
324
|
|
|
@@ -320,7 +329,7 @@ world.query(Position, Velocity).updateEach(([position, velocity]) => {
|
|
|
320
329
|
|
|
321
330
|
// Setting changeDetection to 'always' will ignore selective tracking and always emit change events for all traits that are mutated
|
|
322
331
|
world.query(Position, Velocity).updateEach(([position, velocity]) => {
|
|
323
|
-
}, { changeDetection: '
|
|
332
|
+
}, { changeDetection: 'always' });
|
|
324
333
|
```
|
|
325
334
|
|
|
326
335
|
### World traits
|
|
@@ -427,7 +436,7 @@ const unsub = world.onAdd([Position], (entity) => {})
|
|
|
427
436
|
const unsub = world.onRemove([Position], (entity) => {})
|
|
428
437
|
const unsub = world.onChange([Position], (entity) => {})
|
|
429
438
|
|
|
430
|
-
// An array of all entities alive in the world
|
|
439
|
+
// An array of all entities alive in the world, including non-queryable entities
|
|
431
440
|
// This is a copy so editing it won't do anything!
|
|
432
441
|
// Entity[]
|
|
433
442
|
world.entities
|
|
@@ -754,4 +763,4 @@ useEffect(() => {
|
|
|
754
763
|
spawnPlayer()
|
|
755
764
|
return () => destroyAllPlayers()
|
|
756
765
|
}, [])
|
|
757
|
-
```
|
|
766
|
+
```
|
|
@@ -330,7 +330,12 @@ function defineRelation(definition) {
|
|
|
330
330
|
function relationFn(target) {
|
|
331
331
|
if (target === void 0) throw Error("Relation target is undefined");
|
|
332
332
|
if (target === "*") target = Wildcard;
|
|
333
|
-
return getRelationTrait(
|
|
333
|
+
return getRelationTrait(
|
|
334
|
+
relationFn,
|
|
335
|
+
traitFactory,
|
|
336
|
+
pairsMap,
|
|
337
|
+
target
|
|
338
|
+
);
|
|
334
339
|
}
|
|
335
340
|
return Object.assign(relationFn, {
|
|
336
341
|
[$internal]: {
|
|
@@ -570,9 +575,7 @@ Number.prototype.set = function(trait2, value, triggerChanged = true) {
|
|
|
570
575
|
const index = this & ENTITY_ID_MASK;
|
|
571
576
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
572
577
|
const store = ctx.stores[worldId];
|
|
573
|
-
|
|
574
|
-
value = value(ctx.get(index, store));
|
|
575
|
-
}
|
|
578
|
+
value instanceof Function && (value = value(ctx.get(index, store)));
|
|
576
579
|
ctx.set(index, store, value);
|
|
577
580
|
triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
|
|
578
581
|
};
|
|
@@ -791,6 +794,7 @@ var createQueryHash = (parameters) => {
|
|
|
791
794
|
var IsExcluded = trait();
|
|
792
795
|
var Query = class {
|
|
793
796
|
constructor(world, parameters = []) {
|
|
797
|
+
__publicField(this, "version", 0);
|
|
794
798
|
__publicField(this, "world");
|
|
795
799
|
__publicField(this, "parameters");
|
|
796
800
|
__publicField(this, "hash");
|
|
@@ -876,6 +880,7 @@ var Query = class {
|
|
|
876
880
|
this.traits.push(trait2);
|
|
877
881
|
}
|
|
878
882
|
}
|
|
883
|
+
this.traitData.forbidden.push(ctx.traitData.get(IsExcluded));
|
|
879
884
|
this.traitData.all = [
|
|
880
885
|
...this.traitData.required,
|
|
881
886
|
...this.traitData.forbidden,
|
|
@@ -957,7 +962,6 @@ var Query = class {
|
|
|
957
962
|
const entities = ctx.entityIndex.dense;
|
|
958
963
|
for (let i = 0; i < entities.length; i++) {
|
|
959
964
|
const entity = entities[i];
|
|
960
|
-
if (entity.has(IsExcluded)) continue;
|
|
961
965
|
const match = this.check(world, entity);
|
|
962
966
|
if (match) this.add(entity);
|
|
963
967
|
}
|
|
@@ -976,6 +980,7 @@ var Query = class {
|
|
|
976
980
|
for (const sub of this.addSubscriptions) {
|
|
977
981
|
sub(entity);
|
|
978
982
|
}
|
|
983
|
+
this.version++;
|
|
979
984
|
}
|
|
980
985
|
remove(world, entity) {
|
|
981
986
|
if (!this.entities.has(entity) || this.toRemove.has(entity)) return;
|
package/dist/index.cjs
CHANGED
|
@@ -35,8 +35,8 @@ var __privateWrapper = (obj, member, setter, getter) => ({
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
// src/index.ts
|
|
38
|
-
var
|
|
39
|
-
__export(
|
|
38
|
+
var index_exports = {};
|
|
39
|
+
__export(index_exports, {
|
|
40
40
|
$internal: () => $internal,
|
|
41
41
|
Not: () => Not,
|
|
42
42
|
Or: () => Or,
|
|
@@ -52,7 +52,7 @@ __export(src_exports, {
|
|
|
52
52
|
trait: () => trait,
|
|
53
53
|
universe: () => universe
|
|
54
54
|
});
|
|
55
|
-
module.exports = __toCommonJS(
|
|
55
|
+
module.exports = __toCommonJS(index_exports);
|
|
56
56
|
|
|
57
57
|
// ../core/src/common.ts
|
|
58
58
|
var $internal = Symbol("internal");
|
|
@@ -82,7 +82,12 @@ function defineRelation(definition) {
|
|
|
82
82
|
function relationFn(target) {
|
|
83
83
|
if (target === void 0) throw Error("Relation target is undefined");
|
|
84
84
|
if (target === "*") target = Wildcard;
|
|
85
|
-
return getRelationTrait(
|
|
85
|
+
return getRelationTrait(
|
|
86
|
+
relationFn,
|
|
87
|
+
traitFactory,
|
|
88
|
+
pairsMap,
|
|
89
|
+
target
|
|
90
|
+
);
|
|
86
91
|
}
|
|
87
92
|
return Object.assign(relationFn, {
|
|
88
93
|
[$internal]: {
|
|
@@ -607,9 +612,7 @@ Number.prototype.set = function(trait2, value, triggerChanged = true) {
|
|
|
607
612
|
const index = this & ENTITY_ID_MASK;
|
|
608
613
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
609
614
|
const store = ctx.stores[worldId];
|
|
610
|
-
|
|
611
|
-
value = value(ctx.get(index, store));
|
|
612
|
-
}
|
|
615
|
+
value instanceof Function && (value = value(ctx.get(index, store)));
|
|
613
616
|
ctx.set(index, store, value);
|
|
614
617
|
triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
|
|
615
618
|
};
|
|
@@ -769,6 +772,7 @@ var createQueryHash = (parameters) => {
|
|
|
769
772
|
var IsExcluded = trait();
|
|
770
773
|
var Query = class {
|
|
771
774
|
constructor(world, parameters = []) {
|
|
775
|
+
__publicField(this, "version", 0);
|
|
772
776
|
__publicField(this, "world");
|
|
773
777
|
__publicField(this, "parameters");
|
|
774
778
|
__publicField(this, "hash");
|
|
@@ -854,6 +858,7 @@ var Query = class {
|
|
|
854
858
|
this.traits.push(trait2);
|
|
855
859
|
}
|
|
856
860
|
}
|
|
861
|
+
this.traitData.forbidden.push(ctx.traitData.get(IsExcluded));
|
|
857
862
|
this.traitData.all = [
|
|
858
863
|
...this.traitData.required,
|
|
859
864
|
...this.traitData.forbidden,
|
|
@@ -935,7 +940,6 @@ var Query = class {
|
|
|
935
940
|
const entities = ctx.entityIndex.dense;
|
|
936
941
|
for (let i = 0; i < entities.length; i++) {
|
|
937
942
|
const entity = entities[i];
|
|
938
|
-
if (entity.has(IsExcluded)) continue;
|
|
939
943
|
const match = this.check(world, entity);
|
|
940
944
|
if (match) this.add(entity);
|
|
941
945
|
}
|
|
@@ -954,6 +958,7 @@ var Query = class {
|
|
|
954
958
|
for (const sub of this.addSubscriptions) {
|
|
955
959
|
sub(entity);
|
|
956
960
|
}
|
|
961
|
+
this.version++;
|
|
957
962
|
}
|
|
958
963
|
remove(world, entity) {
|
|
959
964
|
if (!this.entities.has(entity) || this.toRemove.has(entity)) return;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-
|
|
2
|
-
export { $ as $internal, A as AoSFactory, C as ConfigurableTrait,
|
|
1
|
+
import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-DQXl4lI8.cjs';
|
|
2
|
+
export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-DQXl4lI8.cjs';
|
|
3
3
|
|
|
4
4
|
declare function defineTrait<S extends Schema = {}>(schema?: S): Trait<Norm<S>>;
|
|
5
5
|
declare const trait: typeof defineTrait;
|
|
@@ -29,11 +29,11 @@ declare const universe: {
|
|
|
29
29
|
|
|
30
30
|
declare function cacheQuery(...parameters: QueryParameter[]): string;
|
|
31
31
|
|
|
32
|
-
declare function defineRelation<S extends Schema = any
|
|
32
|
+
declare function defineRelation<S extends Schema = any>(definition?: {
|
|
33
33
|
exclusive?: boolean;
|
|
34
34
|
autoRemoveTarget?: boolean;
|
|
35
35
|
store?: S;
|
|
36
|
-
}): Relation<
|
|
36
|
+
}): Relation<Trait<S>>;
|
|
37
37
|
declare const relation: typeof defineRelation;
|
|
38
38
|
declare const Pair: <T extends Trait>(relation: Relation<T>, target: RelationTarget) => T;
|
|
39
39
|
declare const Wildcard: WildcardRelation;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-
|
|
2
|
-
export { $ as $internal, A as AoSFactory, C as ConfigurableTrait,
|
|
1
|
+
import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-DQXl4lI8.js';
|
|
2
|
+
export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-DQXl4lI8.js';
|
|
3
3
|
|
|
4
4
|
declare function defineTrait<S extends Schema = {}>(schema?: S): Trait<Norm<S>>;
|
|
5
5
|
declare const trait: typeof defineTrait;
|
|
@@ -29,11 +29,11 @@ declare const universe: {
|
|
|
29
29
|
|
|
30
30
|
declare function cacheQuery(...parameters: QueryParameter[]): string;
|
|
31
31
|
|
|
32
|
-
declare function defineRelation<S extends Schema = any
|
|
32
|
+
declare function defineRelation<S extends Schema = any>(definition?: {
|
|
33
33
|
exclusive?: boolean;
|
|
34
34
|
autoRemoveTarget?: boolean;
|
|
35
35
|
store?: S;
|
|
36
|
-
}): Relation<
|
|
36
|
+
}): Relation<Trait<S>>;
|
|
37
37
|
declare const relation: typeof defineRelation;
|
|
38
38
|
declare const Pair: <T extends Trait>(relation: Relation<T>, target: RelationTarget) => T;
|
|
39
39
|
declare const Wildcard: WildcardRelation;
|
package/dist/index.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -48,16 +48,6 @@ __export(react_exports, {
|
|
|
48
48
|
});
|
|
49
49
|
module.exports = __toCommonJS(react_exports);
|
|
50
50
|
|
|
51
|
-
// ../react/src/hooks/use-query.ts
|
|
52
|
-
var import_react3 = require("react");
|
|
53
|
-
|
|
54
|
-
// ../react/src/world/use-world.ts
|
|
55
|
-
var import_react2 = require("react");
|
|
56
|
-
|
|
57
|
-
// ../react/src/world/world-context.ts
|
|
58
|
-
var import_react = require("react");
|
|
59
|
-
var WorldContext = (0, import_react.createContext)(null);
|
|
60
|
-
|
|
61
51
|
// ../core/src/common.ts
|
|
62
52
|
var $internal = Symbol("internal");
|
|
63
53
|
|
|
@@ -86,7 +76,12 @@ function defineRelation(definition) {
|
|
|
86
76
|
function relationFn(target) {
|
|
87
77
|
if (target === void 0) throw Error("Relation target is undefined");
|
|
88
78
|
if (target === "*") target = Wildcard;
|
|
89
|
-
return getRelationTrait(
|
|
79
|
+
return getRelationTrait(
|
|
80
|
+
relationFn,
|
|
81
|
+
traitFactory,
|
|
82
|
+
pairsMap,
|
|
83
|
+
target
|
|
84
|
+
);
|
|
90
85
|
}
|
|
91
86
|
return Object.assign(relationFn, {
|
|
92
87
|
[$internal]: {
|
|
@@ -599,9 +594,7 @@ Number.prototype.set = function(trait2, value, triggerChanged = true) {
|
|
|
599
594
|
const index = this & ENTITY_ID_MASK;
|
|
600
595
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
601
596
|
const store = ctx.stores[worldId];
|
|
602
|
-
|
|
603
|
-
value = value(ctx.get(index, store));
|
|
604
|
-
}
|
|
597
|
+
value instanceof Function && (value = value(ctx.get(index, store)));
|
|
605
598
|
ctx.set(index, store, value);
|
|
606
599
|
triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
|
|
607
600
|
};
|
|
@@ -761,6 +754,7 @@ var createQueryHash = (parameters) => {
|
|
|
761
754
|
var IsExcluded = trait();
|
|
762
755
|
var Query = class {
|
|
763
756
|
constructor(world, parameters = []) {
|
|
757
|
+
__publicField(this, "version", 0);
|
|
764
758
|
__publicField(this, "world");
|
|
765
759
|
__publicField(this, "parameters");
|
|
766
760
|
__publicField(this, "hash");
|
|
@@ -846,6 +840,7 @@ var Query = class {
|
|
|
846
840
|
this.traits.push(trait2);
|
|
847
841
|
}
|
|
848
842
|
}
|
|
843
|
+
this.traitData.forbidden.push(ctx.traitData.get(IsExcluded));
|
|
849
844
|
this.traitData.all = [
|
|
850
845
|
...this.traitData.required,
|
|
851
846
|
...this.traitData.forbidden,
|
|
@@ -927,7 +922,6 @@ var Query = class {
|
|
|
927
922
|
const entities = ctx.entityIndex.dense;
|
|
928
923
|
for (let i = 0; i < entities.length; i++) {
|
|
929
924
|
const entity = entities[i];
|
|
930
|
-
if (entity.has(IsExcluded)) continue;
|
|
931
925
|
const match = this.check(world, entity);
|
|
932
926
|
if (match) this.add(entity);
|
|
933
927
|
}
|
|
@@ -946,6 +940,7 @@ var Query = class {
|
|
|
946
940
|
for (const sub of this.addSubscriptions) {
|
|
947
941
|
sub(entity);
|
|
948
942
|
}
|
|
943
|
+
this.version++;
|
|
949
944
|
}
|
|
950
945
|
remove(world, entity) {
|
|
951
946
|
if (!this.entities.has(entity) || this.toRemove.has(entity)) return;
|
|
@@ -1362,6 +1357,31 @@ function createWorld(...traits) {
|
|
|
1362
1357
|
return new World(...traits);
|
|
1363
1358
|
}
|
|
1364
1359
|
|
|
1360
|
+
// ../core/src/query/utils/cache-query.ts
|
|
1361
|
+
function cacheQuery(...parameters) {
|
|
1362
|
+
const hash = createQueryHash(parameters);
|
|
1363
|
+
for (const world of universe.worlds) {
|
|
1364
|
+
if (!world) continue;
|
|
1365
|
+
const ctx = world[$internal];
|
|
1366
|
+
if (!ctx.queriesHashMap.has(hash)) {
|
|
1367
|
+
const query = new Query(world, parameters);
|
|
1368
|
+
ctx.queriesHashMap.set(hash, query);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
universe.cachedQueries.set(hash, parameters);
|
|
1372
|
+
return hash;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
// ../react/src/hooks/use-query.ts
|
|
1376
|
+
var import_react3 = require("react");
|
|
1377
|
+
|
|
1378
|
+
// ../react/src/world/use-world.ts
|
|
1379
|
+
var import_react2 = require("react");
|
|
1380
|
+
|
|
1381
|
+
// ../react/src/world/world-context.ts
|
|
1382
|
+
var import_react = require("react");
|
|
1383
|
+
var WorldContext = (0, import_react.createContext)(null);
|
|
1384
|
+
|
|
1365
1385
|
// ../react/src/world/default-world.ts
|
|
1366
1386
|
var defaultWorld = createWorld();
|
|
1367
1387
|
var getDefaultWorld = () => defaultWorld;
|
|
@@ -1374,34 +1394,29 @@ function useWorld() {
|
|
|
1374
1394
|
|
|
1375
1395
|
// ../react/src/hooks/use-query.ts
|
|
1376
1396
|
function useQuery(...parameters) {
|
|
1377
|
-
const memoizedParameters = (0, import_react3.useMemo)(() => parameters, [parameters]);
|
|
1378
1397
|
const world = useWorld();
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
forceUpdate();
|
|
1386
|
-
}, [world]);
|
|
1398
|
+
const [hash, initialVersion] = (0, import_react3.useMemo)(() => {
|
|
1399
|
+
const hash2 = cacheQuery(...parameters);
|
|
1400
|
+
const query = world[$internal].queriesHashMap.get(hash2);
|
|
1401
|
+
return [hash2, query.version];
|
|
1402
|
+
}, [parameters]);
|
|
1403
|
+
const [entities, setEntities] = (0, import_react3.useState)(() => world.query(hash));
|
|
1387
1404
|
(0, import_react3.useEffect)(() => {
|
|
1388
|
-
const unsubAdd = world.onAdd(
|
|
1389
|
-
|
|
1390
|
-
mutableEntities.push(entity);
|
|
1391
|
-
forceUpdate();
|
|
1405
|
+
const unsubAdd = world.onAdd(parameters, () => {
|
|
1406
|
+
setEntities(world.query(hash));
|
|
1392
1407
|
});
|
|
1393
|
-
const unsubRemove = world.onRemove(
|
|
1394
|
-
|
|
1395
|
-
const index = mutableEntities.indexOf(entity);
|
|
1396
|
-
mutableEntities[index] = mutableEntities[mutableEntities.length - 1];
|
|
1397
|
-
mutableEntities.pop();
|
|
1398
|
-
forceUpdate();
|
|
1408
|
+
const unsubRemove = world.onRemove(parameters, () => {
|
|
1409
|
+
setEntities(world.query(hash));
|
|
1399
1410
|
});
|
|
1411
|
+
const query = world[$internal].queriesHashMap.get(hash);
|
|
1412
|
+
if (query.version !== initialVersion) {
|
|
1413
|
+
setEntities(world.query(hash));
|
|
1414
|
+
}
|
|
1400
1415
|
return () => {
|
|
1401
1416
|
unsubAdd();
|
|
1402
1417
|
unsubRemove();
|
|
1403
1418
|
};
|
|
1404
|
-
}, [world]);
|
|
1419
|
+
}, [world, hash]);
|
|
1405
1420
|
return entities;
|
|
1406
1421
|
}
|
|
1407
1422
|
|
package/dist/react.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Q as QueryParameter,
|
|
1
|
+
import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from './world-DQXl4lI8.cjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Q as QueryParameter,
|
|
1
|
+
import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from './world-DQXl4lI8.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
package/dist/react.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
$internal,
|
|
3
|
+
cacheQuery,
|
|
3
4
|
createWorld
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4QEK6BHY.js";
|
|
5
6
|
|
|
6
7
|
// ../react/src/hooks/use-query.ts
|
|
7
|
-
import { useEffect, useMemo,
|
|
8
|
+
import { useEffect, useMemo, useState } from "react";
|
|
8
9
|
|
|
9
10
|
// ../react/src/world/use-world.ts
|
|
10
11
|
import { useContext } from "react";
|
|
@@ -25,34 +26,29 @@ function useWorld() {
|
|
|
25
26
|
|
|
26
27
|
// ../react/src/hooks/use-query.ts
|
|
27
28
|
function useQuery(...parameters) {
|
|
28
|
-
const memoizedParameters = useMemo(() => parameters, [parameters]);
|
|
29
29
|
const world = useWorld();
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
const [hash, initialVersion] = useMemo(() => {
|
|
31
|
+
const hash2 = cacheQuery(...parameters);
|
|
32
|
+
const query = world[$internal].queriesHashMap.get(hash2);
|
|
33
|
+
return [hash2, query.version];
|
|
34
|
+
}, [parameters]);
|
|
35
|
+
const [entities, setEntities] = useState(() => world.query(hash));
|
|
32
36
|
useEffect(() => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
mutableEntities.push(...world.query(...memoizedParameters));
|
|
36
|
-
forceUpdate();
|
|
37
|
-
}, [world]);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
const unsubAdd = world.onAdd(memoizedParameters, (entity) => {
|
|
40
|
-
const mutableEntities = entities;
|
|
41
|
-
mutableEntities.push(entity);
|
|
42
|
-
forceUpdate();
|
|
37
|
+
const unsubAdd = world.onAdd(parameters, () => {
|
|
38
|
+
setEntities(world.query(hash));
|
|
43
39
|
});
|
|
44
|
-
const unsubRemove = world.onRemove(
|
|
45
|
-
|
|
46
|
-
const index = mutableEntities.indexOf(entity);
|
|
47
|
-
mutableEntities[index] = mutableEntities[mutableEntities.length - 1];
|
|
48
|
-
mutableEntities.pop();
|
|
49
|
-
forceUpdate();
|
|
40
|
+
const unsubRemove = world.onRemove(parameters, () => {
|
|
41
|
+
setEntities(world.query(hash));
|
|
50
42
|
});
|
|
43
|
+
const query = world[$internal].queriesHashMap.get(hash);
|
|
44
|
+
if (query.version !== initialVersion) {
|
|
45
|
+
setEntities(world.query(hash));
|
|
46
|
+
}
|
|
51
47
|
return () => {
|
|
52
48
|
unsubAdd();
|
|
53
49
|
unsubRemove();
|
|
54
50
|
};
|
|
55
|
-
}, [world]);
|
|
51
|
+
}, [world, hash]);
|
|
56
52
|
return entities;
|
|
57
53
|
}
|
|
58
54
|
|
|
@@ -69,7 +65,7 @@ function useActions(actions) {
|
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
// ../react/src/hooks/use-trait.ts
|
|
72
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
|
|
68
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
73
69
|
|
|
74
70
|
// ../react/src/utils/is-world.ts
|
|
75
71
|
function isWorld(target) {
|
|
@@ -83,7 +79,7 @@ function useTrait(target, trait) {
|
|
|
83
79
|
() => target ? createSubscriptions(target, trait, contextWorld) : void 0,
|
|
84
80
|
[target, trait, contextWorld]
|
|
85
81
|
);
|
|
86
|
-
const [value, setValue] =
|
|
82
|
+
const [value, setValue] = useState2(() => {
|
|
87
83
|
return memo?.entity.has(trait) ? memo?.entity.get(trait) : void 0;
|
|
88
84
|
});
|
|
89
85
|
useEffect2(() => {
|
|
@@ -43,12 +43,9 @@ type Store<T extends Schema = any> = T extends AoSFactory ? ReturnType<T>[] : {
|
|
|
43
43
|
type Norm<T extends Schema> = T extends AoSFactory ? () => ReturnType<T> extends number ? number : ReturnType<T> extends boolean ? boolean : ReturnType<T> extends string ? string : ReturnType<T> : {
|
|
44
44
|
[K in keyof T]: T[K] extends boolean ? boolean : T[K];
|
|
45
45
|
};
|
|
46
|
-
type ExtractSchema<T extends Trait
|
|
46
|
+
type ExtractSchema<T extends Trait | Relation<Trait>> = T extends Relation<infer R> ? ExtractSchema<R> : T extends Trait<infer S> ? S : never;
|
|
47
47
|
type ExtractStore<T extends Trait> = T extends Trait<any, infer S> ? S : never;
|
|
48
48
|
type ExtractIsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
49
|
-
type ExtractStores<T extends [Trait, ...Trait[]]> = T extends [infer C] ? C extends Trait<any, Store<any>> ? ExtractStore<C> : never : {
|
|
50
|
-
[K in keyof T]: ExtractStore<T[K]>;
|
|
51
|
-
};
|
|
52
49
|
type IsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
53
50
|
|
|
54
51
|
type RelationTarget = Entity | '*' | WildcardRelation;
|
|
@@ -79,7 +76,7 @@ type Entity = number & {
|
|
|
79
76
|
destroy: () => void;
|
|
80
77
|
changed: (trait: Trait) => void;
|
|
81
78
|
set: <T extends Trait>(trait: T, value: TraitValue<ExtractSchema<T>> | ((prev: TraitInstance<ExtractSchema<T>>) => TraitValue<ExtractSchema<T>>), flagChanged?: boolean) => void;
|
|
82
|
-
get: <T extends Trait
|
|
79
|
+
get: <T extends Trait | Relation<Trait>>(trait: T) => TraitInstance<ExtractSchema<T>> | undefined;
|
|
83
80
|
targetFor: <T extends Trait>(relation: Relation<T>) => Entity | undefined;
|
|
84
81
|
targetsFor: <T extends Trait>(relation: Relation<T>) => Entity[];
|
|
85
82
|
id: () => number;
|
|
@@ -156,6 +153,7 @@ type InstancesFromParameters<T extends QueryParameter[]> = T extends [
|
|
|
156
153
|
type IsNotModifier<T> = T extends ModifierData<any, infer TType> ? TType extends 'not' ? true : false : false;
|
|
157
154
|
|
|
158
155
|
declare class Query {
|
|
156
|
+
version: number;
|
|
159
157
|
world: World;
|
|
160
158
|
parameters: QueryParameter[];
|
|
161
159
|
hash: string;
|
|
@@ -244,4 +242,4 @@ declare class World {
|
|
|
244
242
|
}
|
|
245
243
|
declare function createWorld(...traits: ConfigurableTrait[]): World;
|
|
246
244
|
|
|
247
|
-
export { $internal as $, type AoSFactory as A, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type WildcardRelation as b, createWorld as c, type TraitType as d, type TraitValue as e, type TraitTuple as f, type TraitInstance as g, type Store as h, type ExtractStore as i, type ExtractIsTag as j, type
|
|
245
|
+
export { $internal as $, type AoSFactory as A, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type WildcardRelation as b, createWorld as c, type TraitType as d, type TraitValue as e, type TraitTuple as f, type TraitInstance as g, type Store as h, type ExtractStore as i, type ExtractIsTag as j, type Entity as k, type QueryModifier as l, type QuerySubscriber as m, type QueryResultOptions as n, type QueryResult as o, type StoresFromParameters as p, type InstancesFromParameters as q, type IsNotModifier as r };
|
|
@@ -43,12 +43,9 @@ type Store<T extends Schema = any> = T extends AoSFactory ? ReturnType<T>[] : {
|
|
|
43
43
|
type Norm<T extends Schema> = T extends AoSFactory ? () => ReturnType<T> extends number ? number : ReturnType<T> extends boolean ? boolean : ReturnType<T> extends string ? string : ReturnType<T> : {
|
|
44
44
|
[K in keyof T]: T[K] extends boolean ? boolean : T[K];
|
|
45
45
|
};
|
|
46
|
-
type ExtractSchema<T extends Trait
|
|
46
|
+
type ExtractSchema<T extends Trait | Relation<Trait>> = T extends Relation<infer R> ? ExtractSchema<R> : T extends Trait<infer S> ? S : never;
|
|
47
47
|
type ExtractStore<T extends Trait> = T extends Trait<any, infer S> ? S : never;
|
|
48
48
|
type ExtractIsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
49
|
-
type ExtractStores<T extends [Trait, ...Trait[]]> = T extends [infer C] ? C extends Trait<any, Store<any>> ? ExtractStore<C> : never : {
|
|
50
|
-
[K in keyof T]: ExtractStore<T[K]>;
|
|
51
|
-
};
|
|
52
49
|
type IsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
53
50
|
|
|
54
51
|
type RelationTarget = Entity | '*' | WildcardRelation;
|
|
@@ -79,7 +76,7 @@ type Entity = number & {
|
|
|
79
76
|
destroy: () => void;
|
|
80
77
|
changed: (trait: Trait) => void;
|
|
81
78
|
set: <T extends Trait>(trait: T, value: TraitValue<ExtractSchema<T>> | ((prev: TraitInstance<ExtractSchema<T>>) => TraitValue<ExtractSchema<T>>), flagChanged?: boolean) => void;
|
|
82
|
-
get: <T extends Trait
|
|
79
|
+
get: <T extends Trait | Relation<Trait>>(trait: T) => TraitInstance<ExtractSchema<T>> | undefined;
|
|
83
80
|
targetFor: <T extends Trait>(relation: Relation<T>) => Entity | undefined;
|
|
84
81
|
targetsFor: <T extends Trait>(relation: Relation<T>) => Entity[];
|
|
85
82
|
id: () => number;
|
|
@@ -156,6 +153,7 @@ type InstancesFromParameters<T extends QueryParameter[]> = T extends [
|
|
|
156
153
|
type IsNotModifier<T> = T extends ModifierData<any, infer TType> ? TType extends 'not' ? true : false : false;
|
|
157
154
|
|
|
158
155
|
declare class Query {
|
|
156
|
+
version: number;
|
|
159
157
|
world: World;
|
|
160
158
|
parameters: QueryParameter[];
|
|
161
159
|
hash: string;
|
|
@@ -244,4 +242,4 @@ declare class World {
|
|
|
244
242
|
}
|
|
245
243
|
declare function createWorld(...traits: ConfigurableTrait[]): World;
|
|
246
244
|
|
|
247
|
-
export { $internal as $, type AoSFactory as A, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type WildcardRelation as b, createWorld as c, type TraitType as d, type TraitValue as e, type TraitTuple as f, type TraitInstance as g, type Store as h, type ExtractStore as i, type ExtractIsTag as j, type
|
|
245
|
+
export { $internal as $, type AoSFactory as A, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type WildcardRelation as b, createWorld as c, type TraitType as d, type TraitValue as e, type TraitTuple as f, type TraitInstance as g, type Store as h, type ExtractStore as i, type ExtractIsTag as j, type Entity as k, type QueryModifier as l, type QuerySubscriber as m, type QueryResultOptions as n, type QueryResult as o, type StoresFromParameters as p, type InstancesFromParameters as q, type IsNotModifier as r };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koota",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "🌎 Performant real-time state management for React and TypeScript",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"type": "module",
|
|
@@ -32,36 +32,35 @@
|
|
|
32
32
|
"LICENSE"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"@types/three": "^0.162.0",
|
|
38
|
-
"react": "^18.3.1",
|
|
39
|
-
"react-dom": "^18.3.1",
|
|
40
|
-
"rimraf": "^6.0.1",
|
|
35
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
36
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
41
37
|
"tsup": "^8.3.0",
|
|
42
38
|
"@koota/core": "0.0.1",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
39
|
+
"tsconfig": "0.1.0",
|
|
40
|
+
"@koota/react": "0.0.1"
|
|
45
41
|
},
|
|
46
42
|
"peerDependencies": {
|
|
47
|
-
"@react
|
|
48
|
-
"react": "^18.
|
|
49
|
-
"react
|
|
50
|
-
"
|
|
43
|
+
"@types/react": "^18.0.0 || ^19.0.0",
|
|
44
|
+
"@types/react-dom": "^18.0.0 || ^19.0.0",
|
|
45
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
46
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
51
47
|
},
|
|
52
48
|
"peerDependenciesMeta": {
|
|
53
|
-
"@react
|
|
49
|
+
"@types/react": {
|
|
54
50
|
"optional": true
|
|
55
51
|
},
|
|
56
|
-
"
|
|
52
|
+
"@types/react-dom": {
|
|
57
53
|
"optional": true
|
|
58
54
|
},
|
|
59
55
|
"react-dom": {
|
|
60
56
|
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"react": {
|
|
59
|
+
"optional": true
|
|
61
60
|
}
|
|
62
61
|
},
|
|
63
62
|
"scripts": {
|
|
64
|
-
"build": "
|
|
63
|
+
"build": "tsup && tsx scripts/copy-readme.ts && tsx scripts/copy-react-files.ts",
|
|
65
64
|
"test": "vitest --environment=jsdom"
|
|
66
65
|
}
|
|
67
66
|
}
|
package/react/index.cjs
CHANGED
|
@@ -48,16 +48,6 @@ __export(react_exports, {
|
|
|
48
48
|
});
|
|
49
49
|
module.exports = __toCommonJS(react_exports);
|
|
50
50
|
|
|
51
|
-
// ../react/src/hooks/use-query.ts
|
|
52
|
-
var import_react3 = require("react");
|
|
53
|
-
|
|
54
|
-
// ../react/src/world/use-world.ts
|
|
55
|
-
var import_react2 = require("react");
|
|
56
|
-
|
|
57
|
-
// ../react/src/world/world-context.ts
|
|
58
|
-
var import_react = require("react");
|
|
59
|
-
var WorldContext = (0, import_react.createContext)(null);
|
|
60
|
-
|
|
61
51
|
// ../core/src/common.ts
|
|
62
52
|
var $internal = Symbol("internal");
|
|
63
53
|
|
|
@@ -86,7 +76,12 @@ function defineRelation(definition) {
|
|
|
86
76
|
function relationFn(target) {
|
|
87
77
|
if (target === void 0) throw Error("Relation target is undefined");
|
|
88
78
|
if (target === "*") target = Wildcard;
|
|
89
|
-
return getRelationTrait(
|
|
79
|
+
return getRelationTrait(
|
|
80
|
+
relationFn,
|
|
81
|
+
traitFactory,
|
|
82
|
+
pairsMap,
|
|
83
|
+
target
|
|
84
|
+
);
|
|
90
85
|
}
|
|
91
86
|
return Object.assign(relationFn, {
|
|
92
87
|
[$internal]: {
|
|
@@ -599,9 +594,7 @@ Number.prototype.set = function(trait2, value, triggerChanged = true) {
|
|
|
599
594
|
const index = this & ENTITY_ID_MASK;
|
|
600
595
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
601
596
|
const store = ctx.stores[worldId];
|
|
602
|
-
|
|
603
|
-
value = value(ctx.get(index, store));
|
|
604
|
-
}
|
|
597
|
+
value instanceof Function && (value = value(ctx.get(index, store)));
|
|
605
598
|
ctx.set(index, store, value);
|
|
606
599
|
triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
|
|
607
600
|
};
|
|
@@ -761,6 +754,7 @@ var createQueryHash = (parameters) => {
|
|
|
761
754
|
var IsExcluded = trait();
|
|
762
755
|
var Query = class {
|
|
763
756
|
constructor(world, parameters = []) {
|
|
757
|
+
__publicField(this, "version", 0);
|
|
764
758
|
__publicField(this, "world");
|
|
765
759
|
__publicField(this, "parameters");
|
|
766
760
|
__publicField(this, "hash");
|
|
@@ -846,6 +840,7 @@ var Query = class {
|
|
|
846
840
|
this.traits.push(trait2);
|
|
847
841
|
}
|
|
848
842
|
}
|
|
843
|
+
this.traitData.forbidden.push(ctx.traitData.get(IsExcluded));
|
|
849
844
|
this.traitData.all = [
|
|
850
845
|
...this.traitData.required,
|
|
851
846
|
...this.traitData.forbidden,
|
|
@@ -927,7 +922,6 @@ var Query = class {
|
|
|
927
922
|
const entities = ctx.entityIndex.dense;
|
|
928
923
|
for (let i = 0; i < entities.length; i++) {
|
|
929
924
|
const entity = entities[i];
|
|
930
|
-
if (entity.has(IsExcluded)) continue;
|
|
931
925
|
const match = this.check(world, entity);
|
|
932
926
|
if (match) this.add(entity);
|
|
933
927
|
}
|
|
@@ -946,6 +940,7 @@ var Query = class {
|
|
|
946
940
|
for (const sub of this.addSubscriptions) {
|
|
947
941
|
sub(entity);
|
|
948
942
|
}
|
|
943
|
+
this.version++;
|
|
949
944
|
}
|
|
950
945
|
remove(world, entity) {
|
|
951
946
|
if (!this.entities.has(entity) || this.toRemove.has(entity)) return;
|
|
@@ -1362,6 +1357,31 @@ function createWorld(...traits) {
|
|
|
1362
1357
|
return new World(...traits);
|
|
1363
1358
|
}
|
|
1364
1359
|
|
|
1360
|
+
// ../core/src/query/utils/cache-query.ts
|
|
1361
|
+
function cacheQuery(...parameters) {
|
|
1362
|
+
const hash = createQueryHash(parameters);
|
|
1363
|
+
for (const world of universe.worlds) {
|
|
1364
|
+
if (!world) continue;
|
|
1365
|
+
const ctx = world[$internal];
|
|
1366
|
+
if (!ctx.queriesHashMap.has(hash)) {
|
|
1367
|
+
const query = new Query(world, parameters);
|
|
1368
|
+
ctx.queriesHashMap.set(hash, query);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
universe.cachedQueries.set(hash, parameters);
|
|
1372
|
+
return hash;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
// ../react/src/hooks/use-query.ts
|
|
1376
|
+
var import_react3 = require("react");
|
|
1377
|
+
|
|
1378
|
+
// ../react/src/world/use-world.ts
|
|
1379
|
+
var import_react2 = require("react");
|
|
1380
|
+
|
|
1381
|
+
// ../react/src/world/world-context.ts
|
|
1382
|
+
var import_react = require("react");
|
|
1383
|
+
var WorldContext = (0, import_react.createContext)(null);
|
|
1384
|
+
|
|
1365
1385
|
// ../react/src/world/default-world.ts
|
|
1366
1386
|
var defaultWorld = createWorld();
|
|
1367
1387
|
var getDefaultWorld = () => defaultWorld;
|
|
@@ -1374,34 +1394,29 @@ function useWorld() {
|
|
|
1374
1394
|
|
|
1375
1395
|
// ../react/src/hooks/use-query.ts
|
|
1376
1396
|
function useQuery(...parameters) {
|
|
1377
|
-
const memoizedParameters = (0, import_react3.useMemo)(() => parameters, [parameters]);
|
|
1378
1397
|
const world = useWorld();
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
forceUpdate();
|
|
1386
|
-
}, [world]);
|
|
1398
|
+
const [hash, initialVersion] = (0, import_react3.useMemo)(() => {
|
|
1399
|
+
const hash2 = cacheQuery(...parameters);
|
|
1400
|
+
const query = world[$internal].queriesHashMap.get(hash2);
|
|
1401
|
+
return [hash2, query.version];
|
|
1402
|
+
}, [parameters]);
|
|
1403
|
+
const [entities, setEntities] = (0, import_react3.useState)(() => world.query(hash));
|
|
1387
1404
|
(0, import_react3.useEffect)(() => {
|
|
1388
|
-
const unsubAdd = world.onAdd(
|
|
1389
|
-
|
|
1390
|
-
mutableEntities.push(entity);
|
|
1391
|
-
forceUpdate();
|
|
1405
|
+
const unsubAdd = world.onAdd(parameters, () => {
|
|
1406
|
+
setEntities(world.query(hash));
|
|
1392
1407
|
});
|
|
1393
|
-
const unsubRemove = world.onRemove(
|
|
1394
|
-
|
|
1395
|
-
const index = mutableEntities.indexOf(entity);
|
|
1396
|
-
mutableEntities[index] = mutableEntities[mutableEntities.length - 1];
|
|
1397
|
-
mutableEntities.pop();
|
|
1398
|
-
forceUpdate();
|
|
1408
|
+
const unsubRemove = world.onRemove(parameters, () => {
|
|
1409
|
+
setEntities(world.query(hash));
|
|
1399
1410
|
});
|
|
1411
|
+
const query = world[$internal].queriesHashMap.get(hash);
|
|
1412
|
+
if (query.version !== initialVersion) {
|
|
1413
|
+
setEntities(world.query(hash));
|
|
1414
|
+
}
|
|
1400
1415
|
return () => {
|
|
1401
1416
|
unsubAdd();
|
|
1402
1417
|
unsubRemove();
|
|
1403
1418
|
};
|
|
1404
|
-
}, [world]);
|
|
1419
|
+
}, [world, hash]);
|
|
1405
1420
|
return entities;
|
|
1406
1421
|
}
|
|
1407
1422
|
|
package/react/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Q as QueryParameter,
|
|
1
|
+
import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-DQXl4lI8.cjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
package/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Q as QueryParameter,
|
|
1
|
+
import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-DQXl4lI8.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
package/react/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
$internal,
|
|
3
|
+
cacheQuery,
|
|
3
4
|
createWorld
|
|
4
|
-
} from "../dist/chunk-
|
|
5
|
+
} from "../dist/chunk-4QEK6BHY.js";
|
|
5
6
|
|
|
6
7
|
// ../react/src/hooks/use-query.ts
|
|
7
|
-
import { useEffect, useMemo,
|
|
8
|
+
import { useEffect, useMemo, useState } from "react";
|
|
8
9
|
|
|
9
10
|
// ../react/src/world/use-world.ts
|
|
10
11
|
import { useContext } from "react";
|
|
@@ -25,34 +26,29 @@ function useWorld() {
|
|
|
25
26
|
|
|
26
27
|
// ../react/src/hooks/use-query.ts
|
|
27
28
|
function useQuery(...parameters) {
|
|
28
|
-
const memoizedParameters = useMemo(() => parameters, [parameters]);
|
|
29
29
|
const world = useWorld();
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
const [hash, initialVersion] = useMemo(() => {
|
|
31
|
+
const hash2 = cacheQuery(...parameters);
|
|
32
|
+
const query = world[$internal].queriesHashMap.get(hash2);
|
|
33
|
+
return [hash2, query.version];
|
|
34
|
+
}, [parameters]);
|
|
35
|
+
const [entities, setEntities] = useState(() => world.query(hash));
|
|
32
36
|
useEffect(() => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
mutableEntities.push(...world.query(...memoizedParameters));
|
|
36
|
-
forceUpdate();
|
|
37
|
-
}, [world]);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
const unsubAdd = world.onAdd(memoizedParameters, (entity) => {
|
|
40
|
-
const mutableEntities = entities;
|
|
41
|
-
mutableEntities.push(entity);
|
|
42
|
-
forceUpdate();
|
|
37
|
+
const unsubAdd = world.onAdd(parameters, () => {
|
|
38
|
+
setEntities(world.query(hash));
|
|
43
39
|
});
|
|
44
|
-
const unsubRemove = world.onRemove(
|
|
45
|
-
|
|
46
|
-
const index = mutableEntities.indexOf(entity);
|
|
47
|
-
mutableEntities[index] = mutableEntities[mutableEntities.length - 1];
|
|
48
|
-
mutableEntities.pop();
|
|
49
|
-
forceUpdate();
|
|
40
|
+
const unsubRemove = world.onRemove(parameters, () => {
|
|
41
|
+
setEntities(world.query(hash));
|
|
50
42
|
});
|
|
43
|
+
const query = world[$internal].queriesHashMap.get(hash);
|
|
44
|
+
if (query.version !== initialVersion) {
|
|
45
|
+
setEntities(world.query(hash));
|
|
46
|
+
}
|
|
51
47
|
return () => {
|
|
52
48
|
unsubAdd();
|
|
53
49
|
unsubRemove();
|
|
54
50
|
};
|
|
55
|
-
}, [world]);
|
|
51
|
+
}, [world, hash]);
|
|
56
52
|
return entities;
|
|
57
53
|
}
|
|
58
54
|
|
|
@@ -69,7 +65,7 @@ function useActions(actions) {
|
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
// ../react/src/hooks/use-trait.ts
|
|
72
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
|
|
68
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
73
69
|
|
|
74
70
|
// ../react/src/utils/is-world.ts
|
|
75
71
|
function isWorld(target) {
|
|
@@ -83,7 +79,7 @@ function useTrait(target, trait) {
|
|
|
83
79
|
() => target ? createSubscriptions(target, trait, contextWorld) : void 0,
|
|
84
80
|
[target, trait, contextWorld]
|
|
85
81
|
);
|
|
86
|
-
const [value, setValue] =
|
|
82
|
+
const [value, setValue] = useState2(() => {
|
|
87
83
|
return memo?.entity.has(trait) ? memo?.entity.get(trait) : void 0;
|
|
88
84
|
});
|
|
89
85
|
useEffect2(() => {
|