@latticexyz/recs 2.2.18-90aac1d4acce19ac592d47a090732dd11c1c3e7a → 2.2.18-9fa07c8489f1fbf167d0db01cd9aaa645a29c8e2
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/chunk-A6GOEGXN.js +403 -0
- package/dist/{chunk-2YR7WENB.js.map → chunk-A6GOEGXN.js.map} +1 -1
- package/dist/deprecated/index.cjs +412 -0
- package/dist/deprecated/index.cjs.map +1 -0
- package/dist/deprecated/index.d.cts +51 -0
- package/dist/deprecated/index.js +162 -1
- package/dist/deprecated/index.js.map +1 -1
- package/dist/index.cjs +836 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +606 -0
- package/dist/index.js +411 -1
- package/dist/index.js.map +1 -1
- package/dist/types-CAQycjNT.d.cts +224 -0
- package/package.json +23 -5
- package/dist/chunk-2YR7WENB.js +0 -2
package/dist/index.js
CHANGED
@@ -1,2 +1,412 @@
|
|
1
|
-
import
|
1
|
+
import {
|
2
|
+
OptionalTypes,
|
3
|
+
Type,
|
4
|
+
UpdateType,
|
5
|
+
clearLocalCache,
|
6
|
+
componentValueEquals,
|
7
|
+
createEntity,
|
8
|
+
createIndexer,
|
9
|
+
createLocalCache,
|
10
|
+
defineComponent,
|
11
|
+
getComponentEntities,
|
12
|
+
getComponentValue,
|
13
|
+
getComponentValueStrict,
|
14
|
+
getEntitiesWithValue,
|
15
|
+
getEntityString,
|
16
|
+
getEntitySymbol,
|
17
|
+
hasComponent,
|
18
|
+
isComponentUpdate,
|
19
|
+
isFullComponentValue,
|
20
|
+
isIndexer,
|
21
|
+
overridableComponent,
|
22
|
+
removeComponent,
|
23
|
+
setComponent,
|
24
|
+
toUpdate,
|
25
|
+
toUpdateStream,
|
26
|
+
updateComponent,
|
27
|
+
withValue
|
28
|
+
} from "./chunk-A6GOEGXN.js";
|
29
|
+
|
30
|
+
// src/System.ts
|
31
|
+
import { concat as concat2, EMPTY, from as from2 } from "rxjs";
|
32
|
+
|
33
|
+
// src/Query.ts
|
34
|
+
import { filterNullish } from "@latticexyz/utils";
|
35
|
+
import { observable } from "mobx";
|
36
|
+
import { concat, concatMap, filter, from, map, merge, of, share } from "rxjs";
|
37
|
+
|
38
|
+
// src/types.ts
|
39
|
+
var QueryFragmentType = /* @__PURE__ */ ((QueryFragmentType2) => {
|
40
|
+
QueryFragmentType2[QueryFragmentType2["Has"] = 0] = "Has";
|
41
|
+
QueryFragmentType2[QueryFragmentType2["HasValue"] = 1] = "HasValue";
|
42
|
+
QueryFragmentType2[QueryFragmentType2["Not"] = 2] = "Not";
|
43
|
+
QueryFragmentType2[QueryFragmentType2["NotValue"] = 3] = "NotValue";
|
44
|
+
QueryFragmentType2[QueryFragmentType2["ProxyRead"] = 4] = "ProxyRead";
|
45
|
+
QueryFragmentType2[QueryFragmentType2["ProxyExpand"] = 5] = "ProxyExpand";
|
46
|
+
return QueryFragmentType2;
|
47
|
+
})(QueryFragmentType || {});
|
48
|
+
function isOptionalType(t) {
|
49
|
+
return [
|
50
|
+
2 /* OptionalNumber */,
|
51
|
+
4 /* OptionalBigInt */,
|
52
|
+
6 /* OptionalString */,
|
53
|
+
14 /* OptionalEntity */,
|
54
|
+
16 /* OptionalEntityArray */,
|
55
|
+
8 /* OptionalNumberArray */,
|
56
|
+
10 /* OptionalBigIntArray */,
|
57
|
+
12 /* OptionalStringArray */
|
58
|
+
].includes(t);
|
59
|
+
}
|
60
|
+
function isArrayType(t) {
|
61
|
+
return [
|
62
|
+
7 /* NumberArray */,
|
63
|
+
8 /* OptionalNumberArray */,
|
64
|
+
9 /* BigIntArray */,
|
65
|
+
10 /* OptionalBigIntArray */,
|
66
|
+
11 /* StringArray */,
|
67
|
+
12 /* OptionalStringArray */,
|
68
|
+
15 /* EntityArray */,
|
69
|
+
16 /* OptionalEntityArray */
|
70
|
+
].includes(t);
|
71
|
+
}
|
72
|
+
function isNumberType(t) {
|
73
|
+
return [1 /* Number */, 2 /* OptionalNumber */].includes(t);
|
74
|
+
}
|
75
|
+
function isEntityType(t) {
|
76
|
+
return [13 /* Entity */, 14 /* OptionalEntity */].includes(t);
|
77
|
+
}
|
78
|
+
|
79
|
+
// src/Query.ts
|
80
|
+
function Has(component) {
|
81
|
+
return { type: 0 /* Has */, component };
|
82
|
+
}
|
83
|
+
function Not(component) {
|
84
|
+
return { type: 2 /* Not */, component };
|
85
|
+
}
|
86
|
+
function HasValue(component, value) {
|
87
|
+
return { type: 1 /* HasValue */, component, value };
|
88
|
+
}
|
89
|
+
function NotValue(component, value) {
|
90
|
+
return { type: 3 /* NotValue */, component, value };
|
91
|
+
}
|
92
|
+
function ProxyRead(component, depth) {
|
93
|
+
return { type: 4 /* ProxyRead */, component, depth };
|
94
|
+
}
|
95
|
+
function ProxyExpand(component, depth) {
|
96
|
+
return { type: 5 /* ProxyExpand */, component, depth };
|
97
|
+
}
|
98
|
+
function passesQueryFragment(entity, fragment) {
|
99
|
+
if (fragment.type === 0 /* Has */) {
|
100
|
+
return hasComponent(fragment.component, entity);
|
101
|
+
}
|
102
|
+
if (fragment.type === 1 /* HasValue */) {
|
103
|
+
return componentValueEquals(fragment.value, getComponentValue(fragment.component, entity));
|
104
|
+
}
|
105
|
+
if (fragment.type === 2 /* Not */) {
|
106
|
+
return !hasComponent(fragment.component, entity);
|
107
|
+
}
|
108
|
+
if (fragment.type === 3 /* NotValue */) {
|
109
|
+
return !componentValueEquals(fragment.value, getComponentValue(fragment.component, entity));
|
110
|
+
}
|
111
|
+
throw new Error("Unknown query fragment");
|
112
|
+
}
|
113
|
+
function isPositiveFragment(fragment) {
|
114
|
+
return fragment.type === 0 /* Has */ || fragment.type == 1 /* HasValue */;
|
115
|
+
}
|
116
|
+
function isNegativeFragment(fragment) {
|
117
|
+
return fragment.type === 2 /* Not */ || fragment.type == 3 /* NotValue */;
|
118
|
+
}
|
119
|
+
function isSettingFragment(fragment) {
|
120
|
+
return fragment.type === 5 /* ProxyExpand */ || fragment.type == 4 /* ProxyRead */;
|
121
|
+
}
|
122
|
+
function isBreakingPassState(passes, fragment) {
|
123
|
+
return passes && isPositiveFragment(fragment) || !passes && isNegativeFragment(fragment);
|
124
|
+
}
|
125
|
+
function passesQueryFragmentProxy(entity, fragment, proxyRead) {
|
126
|
+
let proxyEntity = entity;
|
127
|
+
let passes = false;
|
128
|
+
for (let i = 0; i < proxyRead.depth; i++) {
|
129
|
+
const value = getComponentValue(proxyRead.component, proxyEntity);
|
130
|
+
if (!value) return null;
|
131
|
+
const entity2 = value.value;
|
132
|
+
if (!entity2) return null;
|
133
|
+
proxyEntity = entity2;
|
134
|
+
passes = passesQueryFragment(proxyEntity, fragment);
|
135
|
+
if (isBreakingPassState(passes, fragment)) {
|
136
|
+
return passes;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
return passes;
|
140
|
+
}
|
141
|
+
function getChildEntities(entity, component, depth) {
|
142
|
+
if (depth === 0) return /* @__PURE__ */ new Set();
|
143
|
+
const directChildEntities = getEntitiesWithValue(component, { value: entity });
|
144
|
+
if (depth === 1) return directChildEntities;
|
145
|
+
const indirectChildEntities = [...directChildEntities].map((childEntity) => [...getChildEntities(childEntity, component, depth - 1)]).flat();
|
146
|
+
return /* @__PURE__ */ new Set([...directChildEntities, ...indirectChildEntities]);
|
147
|
+
}
|
148
|
+
function runQuery(fragments, initialSet) {
|
149
|
+
let entities = initialSet ? /* @__PURE__ */ new Set([...initialSet]) : void 0;
|
150
|
+
let proxyRead = void 0;
|
151
|
+
let proxyExpand = void 0;
|
152
|
+
for (let i = 0; i < fragments.length; i++) {
|
153
|
+
const fragment = fragments[i];
|
154
|
+
if (isSettingFragment(fragment)) {
|
155
|
+
if (fragment.type === 4 /* ProxyRead */) proxyRead = fragment;
|
156
|
+
if (fragment.type === 5 /* ProxyExpand */) proxyExpand = fragment;
|
157
|
+
} else if (!entities) {
|
158
|
+
if (isNegativeFragment(fragment)) {
|
159
|
+
throw new Error("First EntityQueryFragment must be Has or HasValue");
|
160
|
+
}
|
161
|
+
entities = fragment.type === 0 /* Has */ ? /* @__PURE__ */ new Set([...getComponentEntities(fragment.component)]) : getEntitiesWithValue(fragment.component, fragment.value);
|
162
|
+
if (proxyExpand && proxyExpand.depth > 0) {
|
163
|
+
for (const entity of [...entities]) {
|
164
|
+
for (const childEntity of getChildEntities(entity, proxyExpand.component, proxyExpand.depth)) {
|
165
|
+
entities.add(childEntity);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
} else {
|
170
|
+
for (const entity of [...entities]) {
|
171
|
+
let passes = passesQueryFragment(entity, fragment);
|
172
|
+
if (proxyRead && proxyRead.depth > 0 && !isBreakingPassState(passes, fragment)) {
|
173
|
+
passes = passesQueryFragmentProxy(entity, fragment, proxyRead) ?? passes;
|
174
|
+
}
|
175
|
+
if (!passes) entities.delete(entity);
|
176
|
+
if (proxyExpand && proxyExpand.depth > 0) {
|
177
|
+
const childEntities = getChildEntities(entity, proxyExpand.component, proxyExpand.depth);
|
178
|
+
for (const childEntity of childEntities) {
|
179
|
+
if (passesQueryFragment(childEntity, fragment) || proxyRead && proxyRead.depth > 0 && passesQueryFragmentProxy(childEntity, fragment, proxyRead))
|
180
|
+
entities.add(childEntity);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
return entities ?? /* @__PURE__ */ new Set();
|
187
|
+
}
|
188
|
+
function defineQuery(fragments, options) {
|
189
|
+
const initialSet = options?.runOnInit || options?.initialSet ? runQuery(fragments, options.initialSet) : /* @__PURE__ */ new Set();
|
190
|
+
const matching = observable(initialSet);
|
191
|
+
const initial$ = from(matching).pipe(toUpdateStream(fragments[0].component));
|
192
|
+
const containsProxy = fragments.findIndex((v) => [5 /* ProxyExpand */, 4 /* ProxyRead */].includes(v.type)) !== -1;
|
193
|
+
const internal$ = merge(...fragments.map((f) => f.component.update$)).pipe(
|
194
|
+
containsProxy ? concatMap((update) => {
|
195
|
+
const newMatchingSet = runQuery(fragments, options?.initialSet);
|
196
|
+
const updates = [];
|
197
|
+
for (const previouslyMatchingEntity of matching) {
|
198
|
+
if (!newMatchingSet.has(previouslyMatchingEntity)) {
|
199
|
+
matching.delete(previouslyMatchingEntity);
|
200
|
+
updates.push({
|
201
|
+
entity: previouslyMatchingEntity,
|
202
|
+
type: 1 /* Exit */,
|
203
|
+
component: update.component,
|
204
|
+
value: [void 0, void 0]
|
205
|
+
});
|
206
|
+
}
|
207
|
+
}
|
208
|
+
for (const matchingEntity of newMatchingSet) {
|
209
|
+
if (matching.has(matchingEntity)) {
|
210
|
+
updates.push({
|
211
|
+
entity: matchingEntity,
|
212
|
+
type: 2 /* Update */,
|
213
|
+
component: update.component,
|
214
|
+
value: [getComponentValue(update.component, matchingEntity), void 0]
|
215
|
+
});
|
216
|
+
} else {
|
217
|
+
matching.add(matchingEntity);
|
218
|
+
updates.push({
|
219
|
+
entity: matchingEntity,
|
220
|
+
type: 0 /* Enter */,
|
221
|
+
component: update.component,
|
222
|
+
value: [getComponentValue(update.component, matchingEntity), void 0]
|
223
|
+
});
|
224
|
+
}
|
225
|
+
}
|
226
|
+
return of(...updates);
|
227
|
+
}) : (
|
228
|
+
// Query does not contain proxies
|
229
|
+
map((update) => {
|
230
|
+
if (matching.has(update.entity)) {
|
231
|
+
const relevantFragments = fragments.filter((f) => f.component.id === update.component.id);
|
232
|
+
const pass2 = relevantFragments.every((f) => passesQueryFragment(update.entity, f));
|
233
|
+
if (pass2) {
|
234
|
+
return { ...update, type: 2 /* Update */ };
|
235
|
+
} else {
|
236
|
+
matching.delete(update.entity);
|
237
|
+
return { ...update, type: 1 /* Exit */ };
|
238
|
+
}
|
239
|
+
}
|
240
|
+
const pass = fragments.every((f) => passesQueryFragment(update.entity, f));
|
241
|
+
if (pass) {
|
242
|
+
matching.add(update.entity);
|
243
|
+
return { ...update, type: 0 /* Enter */ };
|
244
|
+
}
|
245
|
+
})
|
246
|
+
),
|
247
|
+
filterNullish()
|
248
|
+
);
|
249
|
+
return {
|
250
|
+
matching,
|
251
|
+
update$: concat(initial$, internal$).pipe(share())
|
252
|
+
};
|
253
|
+
}
|
254
|
+
function defineUpdateQuery(fragments, options) {
|
255
|
+
return defineQuery(fragments, options).update$.pipe(filter((e) => e.type === 2 /* Update */));
|
256
|
+
}
|
257
|
+
function defineEnterQuery(fragments, options) {
|
258
|
+
return defineQuery(fragments, options).update$.pipe(filter((e) => e.type === 0 /* Enter */));
|
259
|
+
}
|
260
|
+
function defineExitQuery(fragments, options) {
|
261
|
+
return defineQuery(fragments, options).update$.pipe(filter((e) => e.type === 1 /* Exit */));
|
262
|
+
}
|
263
|
+
|
264
|
+
// src/System.ts
|
265
|
+
function defineRxSystem(world, observable$, system) {
|
266
|
+
const subscription = observable$.subscribe(system);
|
267
|
+
world.registerDisposer(() => subscription?.unsubscribe());
|
268
|
+
}
|
269
|
+
function defineUpdateSystem(world, query, system, options = { runOnInit: true }) {
|
270
|
+
defineRxSystem(world, defineUpdateQuery(query, options), system);
|
271
|
+
}
|
272
|
+
function defineEnterSystem(world, query, system, options = { runOnInit: true }) {
|
273
|
+
defineRxSystem(world, defineEnterQuery(query, options), system);
|
274
|
+
}
|
275
|
+
function defineExitSystem(world, query, system, options = { runOnInit: true }) {
|
276
|
+
defineRxSystem(world, defineExitQuery(query, options), system);
|
277
|
+
}
|
278
|
+
function defineSystem(world, query, system, options = { runOnInit: true }) {
|
279
|
+
defineRxSystem(world, defineQuery(query, options).update$, system);
|
280
|
+
}
|
281
|
+
function defineComponentSystem(world, component, system, options = { runOnInit: true }) {
|
282
|
+
const initial$ = options?.runOnInit ? from2(getComponentEntities(component)).pipe(toUpdateStream(component)) : EMPTY;
|
283
|
+
defineRxSystem(world, concat2(initial$, component.update$), system);
|
284
|
+
}
|
285
|
+
function defineSyncSystem(world, query, component, value, options = { update: false, runOnInit: true }) {
|
286
|
+
defineSystem(
|
287
|
+
world,
|
288
|
+
query,
|
289
|
+
({ entity, type }) => {
|
290
|
+
if (type === 0 /* Enter */) setComponent(component(entity), entity, value(entity));
|
291
|
+
if (type === 1 /* Exit */) removeComponent(component(entity), entity);
|
292
|
+
if (options?.update && type === 2 /* Update */) setComponent(component(entity), entity, value(entity));
|
293
|
+
},
|
294
|
+
options
|
295
|
+
);
|
296
|
+
}
|
297
|
+
|
298
|
+
// src/World.ts
|
299
|
+
import { transformIterator } from "@latticexyz/utils";
|
300
|
+
function createWorld() {
|
301
|
+
const entitySymbols = /* @__PURE__ */ new Set();
|
302
|
+
const components = [];
|
303
|
+
let disposers = [];
|
304
|
+
function registerEntity({ id, idSuffix } = {}) {
|
305
|
+
const entity = id || entitySymbols.size + (idSuffix ? "-" + idSuffix : "");
|
306
|
+
const entitySymbol = getEntitySymbol(entity);
|
307
|
+
entitySymbols.add(entitySymbol);
|
308
|
+
return entity;
|
309
|
+
}
|
310
|
+
function getEntities() {
|
311
|
+
return transformIterator(entitySymbols.values(), getEntityString);
|
312
|
+
}
|
313
|
+
function registerComponent(component) {
|
314
|
+
components.push(component);
|
315
|
+
}
|
316
|
+
function dispose(namespace) {
|
317
|
+
for (const [, disposer] of disposers.filter((d) => !namespace || d[0] === namespace)) {
|
318
|
+
disposer();
|
319
|
+
}
|
320
|
+
disposers = disposers.filter((d) => namespace && d[0] !== namespace);
|
321
|
+
}
|
322
|
+
function registerDisposer(disposer, namespace = "") {
|
323
|
+
disposers.push([namespace, disposer]);
|
324
|
+
}
|
325
|
+
function hasEntity(entity) {
|
326
|
+
const entitySymbol = getEntitySymbol(entity);
|
327
|
+
return entitySymbols.has(entitySymbol);
|
328
|
+
}
|
329
|
+
function deleteEntity(entity) {
|
330
|
+
for (const component of components) {
|
331
|
+
if (hasComponent(component, entity)) removeComponent(component, entity);
|
332
|
+
}
|
333
|
+
entitySymbols.delete(getEntitySymbol(entity));
|
334
|
+
}
|
335
|
+
return {
|
336
|
+
registerEntity,
|
337
|
+
components,
|
338
|
+
registerComponent,
|
339
|
+
dispose,
|
340
|
+
registerDisposer,
|
341
|
+
hasEntity,
|
342
|
+
getEntities,
|
343
|
+
entitySymbols,
|
344
|
+
deleteEntity
|
345
|
+
};
|
346
|
+
}
|
347
|
+
function namespaceWorld(world, namespace) {
|
348
|
+
return {
|
349
|
+
...world,
|
350
|
+
registerDisposer: (disposer) => world.registerDisposer(disposer, namespace),
|
351
|
+
dispose: () => world.dispose(namespace)
|
352
|
+
};
|
353
|
+
}
|
354
|
+
function getEntityComponents(world, entity) {
|
355
|
+
return world.components.filter((component) => hasComponent(component, entity));
|
356
|
+
}
|
357
|
+
export {
|
358
|
+
Has,
|
359
|
+
HasValue,
|
360
|
+
Not,
|
361
|
+
NotValue,
|
362
|
+
OptionalTypes,
|
363
|
+
ProxyExpand,
|
364
|
+
ProxyRead,
|
365
|
+
QueryFragmentType,
|
366
|
+
Type,
|
367
|
+
UpdateType,
|
368
|
+
clearLocalCache,
|
369
|
+
componentValueEquals,
|
370
|
+
createEntity,
|
371
|
+
createIndexer,
|
372
|
+
createLocalCache,
|
373
|
+
createWorld,
|
374
|
+
defineComponent,
|
375
|
+
defineComponentSystem,
|
376
|
+
defineEnterQuery,
|
377
|
+
defineEnterSystem,
|
378
|
+
defineExitQuery,
|
379
|
+
defineExitSystem,
|
380
|
+
defineQuery,
|
381
|
+
defineRxSystem,
|
382
|
+
defineSyncSystem,
|
383
|
+
defineSystem,
|
384
|
+
defineUpdateQuery,
|
385
|
+
defineUpdateSystem,
|
386
|
+
getChildEntities,
|
387
|
+
getComponentEntities,
|
388
|
+
getComponentValue,
|
389
|
+
getComponentValueStrict,
|
390
|
+
getEntitiesWithValue,
|
391
|
+
getEntityComponents,
|
392
|
+
getEntityString,
|
393
|
+
getEntitySymbol,
|
394
|
+
hasComponent,
|
395
|
+
isArrayType,
|
396
|
+
isComponentUpdate,
|
397
|
+
isEntityType,
|
398
|
+
isFullComponentValue,
|
399
|
+
isIndexer,
|
400
|
+
isNumberType,
|
401
|
+
isOptionalType,
|
402
|
+
namespaceWorld,
|
403
|
+
overridableComponent,
|
404
|
+
removeComponent,
|
405
|
+
runQuery,
|
406
|
+
setComponent,
|
407
|
+
toUpdate,
|
408
|
+
toUpdateStream,
|
409
|
+
updateComponent,
|
410
|
+
withValue
|
411
|
+
};
|
2
412
|
//# sourceMappingURL=index.js.map
|