@latticexyz/recs 2.0.0-transaction-context-324984c5 → 2.0.1-main-4a6b4598

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/CHANGELOG.md CHANGED
@@ -1,10 +1,17 @@
1
1
  # Change Log
2
2
 
3
- ## 2.0.0-transaction-context-324984c5
3
+ ## 2.0.1-main-4a6b4598
4
+
5
+ ### Patch Changes
6
+
7
+ - @latticexyz/schema-type@2.0.1-main-4a6b4598
8
+ - @latticexyz/utils@2.0.1-main-4a6b4598
9
+
10
+ ## 2.0.0
4
11
 
5
12
  ### Minor Changes
6
13
 
7
- - c14f8bf1: - Moved `createActionSystem` from `std-client` to `recs` package and updated it to better support v2 sync stack.
14
+ - c14f8bf1e: - Moved `createActionSystem` from `std-client` to `recs` package and updated it to better support v2 sync stack.
8
15
 
9
16
  If you want to use `createActionSystem` alongside `syncToRecs`, you'll need to pass in arguments like so:
10
17
 
@@ -26,7 +33,6 @@
26
33
  ```
27
34
 
28
35
  - Fixed a bug in `waitForComponentValueIn` that caused the promise to not resolve if the component value was already set when the function was called.
29
-
30
36
  - Fixed a bug in `createActionSystem` that caused optimistic updates to be incorrectly propagated to requirement checks. To fix the bug, you must now pass in the full component object to the action's `updates` instead of just the component name.
31
37
 
32
38
  ```diff
@@ -44,10 +50,10 @@
44
50
 
45
51
  ### Patch Changes
46
52
 
47
- - ce7125a1: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`.
48
- - 1e2ad78e: improve RECS error messages for v2 components
49
- - 59054203: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages.
50
- - 60cfd089: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout.
53
+ - ce7125a1b: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`.
54
+ - 1e2ad78e2: improve RECS error messages for v2 components
55
+ - 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages.
56
+ - 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout.
51
57
 
52
58
  These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys.
53
59
 
@@ -58,7 +64,6 @@
58
64
  As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything.
59
65
 
60
66
  1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors)
61
-
62
67
  2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain.
63
68
 
64
69
  ```diff
@@ -213,7 +218,7 @@
213
218
  .pipe(
214
219
  map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms
215
220
  filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block
216
- filter((blockTimestamp) => blockTimestamp !== clock.currentTime) // Ignore if the current local timestamp is correct
221
+ filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct
217
222
  )
218
223
  .subscribe(clock.update); // Update the local clock
219
224
  ```
@@ -234,7 +239,7 @@
234
239
  }
235
240
  ```
236
241
 
237
- - afdba793: Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values.
242
+ - afdba793f: Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values.
238
243
 
239
244
  This may break if you were previously dependent on `component.id`, `component.metadata.componentId`, or `component.metadata.tableId`:
240
245
 
@@ -244,20 +249,31 @@
244
249
  - `component.metadata.keySchema` is an object with key names and their corresponding ABI types
245
250
  - `component.metadata.valueSchema` is an object with field names and their corresponding ABI types
246
251
 
247
- - Updated dependencies [52182f70]
248
- - Updated dependencies [aabd3076]
249
- - Updated dependencies [f99e8898]
250
- - Updated dependencies [48909d15]
251
- - Updated dependencies [b02f9d0e]
252
- - Updated dependencies [bb91edaa]
253
- - Updated dependencies [59054203]
254
- - Updated dependencies [f03531d9]
255
- - Updated dependencies [b8a6158d]
256
- - Updated dependencies [92de5998]
257
- - Updated dependencies [4e4a3415]
258
- - Updated dependencies [53522998]
259
- - @latticexyz/utils@2.0.0-transaction-context-324984c5
260
- - @latticexyz/schema-type@2.0.0-transaction-context-324984c5
252
+ - Updated dependencies [52182f70d]
253
+ - Updated dependencies [aabd30767]
254
+ - Updated dependencies [b38c096d]
255
+ - Updated dependencies [f99e88987]
256
+ - Updated dependencies [48909d151]
257
+ - Updated dependencies [b02f9d0e4]
258
+ - Updated dependencies [bb91edaa0]
259
+ - Updated dependencies [590542030]
260
+ - Updated dependencies [f03531d97]
261
+ - Updated dependencies [b8a6158d6]
262
+ - Updated dependencies [92de59982]
263
+ - Updated dependencies [4e4a34150]
264
+ - Updated dependencies [535229984]
265
+ - Updated dependencies [d7b1c588a]
266
+ - @latticexyz/utils@2.0.0
267
+ - @latticexyz/schema-type@2.0.0
268
+
269
+ ## 2.0.0-next.18
270
+
271
+ ### Patch Changes
272
+
273
+ - Updated dependencies [b38c096d]
274
+ - Updated dependencies [d7b1c588a]
275
+ - @latticexyz/schema-type@2.0.0-next.18
276
+ - @latticexyz/utils@2.0.0-next.18
261
277
 
262
278
  ## 2.0.0-next.17
263
279
 
@@ -598,7 +614,7 @@
598
614
  .pipe(
599
615
  map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms
600
616
  filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block
601
- filter((blockTimestamp) => blockTimestamp !== clock.currentTime) // Ignore if the current local timestamp is correct
617
+ filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct
602
618
  )
603
619
  .subscribe(clock.update); // Update the local clock
604
620
  ```
@@ -1,2 +1,2 @@
1
1
  var P=(o=>(o[o.Boolean=0]="Boolean",o[o.Number=1]="Number",o[o.OptionalNumber=2]="OptionalNumber",o[o.BigInt=3]="BigInt",o[o.OptionalBigInt=4]="OptionalBigInt",o[o.String=5]="String",o[o.OptionalString=6]="OptionalString",o[o.NumberArray=7]="NumberArray",o[o.OptionalNumberArray=8]="OptionalNumberArray",o[o.BigIntArray=9]="BigIntArray",o[o.OptionalBigIntArray=10]="OptionalBigIntArray",o[o.StringArray=11]="StringArray",o[o.OptionalStringArray=12]="OptionalStringArray",o[o.Entity=13]="Entity",o[o.OptionalEntity=14]="OptionalEntity",o[o.EntityArray=15]="EntityArray",o[o.OptionalEntityArray=16]="OptionalEntityArray",o[o.T=17]="T",o[o.OptionalT=18]="OptionalT",o))(P||{}),k=(i=>(i[i.Enter=0]="Enter",i[i.Exit=1]="Exit",i[i.Update=2]="Update",i[i.Noop=3]="Noop",i))(k||{}),w=[14,16,2,8,4,10,6,12,18];import{transformIterator as j,uuid as F}from"@latticexyz/utils";import{mapObject as N}from"@latticexyz/utils";import{filter as L,map as D,Subject as $}from"rxjs";function M(e){let t=new Map;function n(l){let u=t.get(r(l));return u?new Set([...u].map(v)):new Set}function r(l){return Object.values(l).join("/")}function i(l,u){if(!u)return;let x=r(u),f=t.get(x);f||(f=new Set,t.set(x,f)),f.add(l)}function d(l,u){if(!u)return;let x=r(u),f=t.get(x);f&&f.delete(l)}for(let l of V(e)){let u=g(e,l);i(p(l),u)}let m=e.update$.subscribe(({entity:l,value:u})=>{d(p(l),u[1]),i(p(l),u[0])});return e.world.registerDisposer(()=>m?.unsubscribe()),{...e,getEntitiesWithValue:n}}import{map as W,pipe as B}from"rxjs";function X(e,t){return e.component===t}function U(e,t){let n=g(t,e);return{entity:e,component:t,value:[n,void 0],type:n==null?3:0}}function Y(e){return B(W(t=>U(t,e)))}function I(e){return"getEntitiesWithValue"in e}function T(e,t){return Object.keys(e.schema).every(n=>n in t)}function b(e){return e.metadata?.componentName??e.metadata?.tableName??e.metadata?.tableId??e.metadata?.contractId??e.id}function ie(e,t,n){if(Object.keys(t).length===0)throw new Error("Component schema must have at least one key");let r=n?.id??F(),i=N(t,()=>new Map),d=new $,m=n?.metadata,u={values:i,schema:t,id:r,update$:d,metadata:m,entities:()=>j(Object.values(i)[0].keys(),v),world:e};return n?.indexed&&(u=M(u)),e.registerComponent(u),u}function E(e,t,n,r={}){let i=p(t),d=g(e,t);for(let[m,l]of Object.entries(n))e.values[m]?e.values[m].set(i,l):e.metadata?.tableId&&/^\d+$/.test(m)||console.warn("Component definition for",b(e),"is missing key",m,", ignoring value",l,"for entity",t,". Existing keys: ",Object.keys(e.values));r.skipUpdateStream||e.update$.next({entity:t,value:[n,d],component:e})}function se(e,t,n,r,i={}){let d=g(e,t);if(d===void 0){if(r===void 0)throw new Error(`Can't update component ${b(e)} without a current value or initial value`);E(e,t,{...r,...n},i)}else E(e,t,{...d,...n},i)}function ue(e,t,n={}){let r=p(t),i=g(e,t);for(let d of Object.keys(e.values))e.values[d].delete(r);n.skipUpdateStream||e.update$.next({entity:t,value:[void 0,i],component:e})}function le(e,t){let n=p(t);return Object.values(e.values)[0].has(n)}function g(e,t){let n={},r=p(t),i=Object.keys(e.schema);for(let d of i){let m=e.values[d].get(r);if(m===void 0&&!w.includes(e.schema[d]))return;n[d]=m}return n}function de(e,t){let n=g(e,t);if(!n)throw new Error(`No value for component ${b(e)} on entity ${t}`);return n}function K(e,t){if(!e&&!t)return!0;if(!e||!t)return!1;let n=!0;for(let r of Object.keys(e))if(n=e[r]===t[r],!n)return!1;return n}function me(e,t){return[e,t]}function ce(e,t){if(I(e)&&T(e,t))return e.getEntitiesWithValue(t);let n=new Set;for(let r of V(e)){let i=g(e,r);K(t,i)&&n.add(r)}return n}function V(e){return e.entities()}function Se(e){let t=0,n=new Map,r=new Map,i=new $;function d(s,a){n.set(s,{update:a,nonce:t++}),C(a.entity,a.value)}function m(s){let a=n.get(s)?.update.entity;if(n.delete(s),a==null)return;let S=[...n.values()].filter(c=>c.update.entity===a).sort((c,h)=>c.nonce<h.nonce?-1:1);if(S.length>0){let c=S[S.length-1];C(a,c.update.value)}else C(a,void 0)}function l(s){let a=g(e,s),S=p(s),c=r.get(S);return(a||c)&&c!==null?{...a,...c}:void 0}let u=s=>({get(a,S){return S==="get"?c=>{let h=a.get(c),O=r.get(c);return O&&O[s]!=null?O[s]:h}:S==="has"?c=>a.has(c)||r.has(c):S==="keys"?()=>new Set([...a.keys(),...r.keys()]).values():Reflect.get(a,S,a)}}),x={};for(let s of Object.keys(e.values))x[s]=new Proxy(e.values[s],u(s));let f=x,y=new Proxy(e,{get(s,a){return a==="addOverride"?d:a==="removeOverride"?m:a==="values"?f:a==="update$"?i:a==="entities"?()=>new Set([...j(r.keys(),v),...s.entities()]).values():Reflect.get(s,a)},has(s,a){return a==="addOverride"||a==="removeOverride"?!0:a in s}});function C(s,a){let S=p(s),c=l(s);a!==void 0?r.set(S,a):r.delete(S),i.next({entity:s,value:[l(s),c],component:y})}return e.update$.pipe(L(s=>!r.get(p(s.entity))),D(s=>({...s,component:y}))).subscribe(i),y}function A(e,t){return`localcache-${t}-${e.id}`}function fe(e,t){localStorage.removeItem(A(e,t))}function pe(e,t){let{world:n,update$:r,values:i}=e,d=A(e,t),m=0,l=Date.now(),u=localStorage.getItem(d);if(u){let f=JSON.parse(u),y={};for(let[C,s]of f)for(let[a,S]of s)y[a]=y[a]||{},y[a][C]=S;for(let[C,s]of Object.entries(y)){let a=n.registerEntity({id:C});E(e,a,s)}console.info("Loading component",b(e),"from local cache.")}let x=r.subscribe(()=>{m++;let f=JSON.stringify(Object.entries(N(i,y=>[...y.entries()].map(C=>[v(C[0]),C[1]]))));localStorage.setItem(d,f),m>200&&console.warn("Component",b(e),"was locally cached",m,"times since",new Date(l).toLocaleTimeString(),"- the local cache is in an alpha state and should not be used with components that update frequently yet")});return e.world.registerDisposer(()=>x?.unsubscribe()),e}function ge(e,t,n){let r=e.registerEntity(n??{});if(t)for(let[i,d]of t)E(i,r,d);return r}function p(e){return Symbol.for(e)}function v(e){return Symbol.keyFor(e)}export{P as a,k as b,w as c,ge as d,p as e,v as f,M as g,X as h,U as i,Y as j,I as k,T as l,ie as m,E as n,se as o,ue as p,le as q,g as r,de as s,K as t,me as u,ce as v,V as w,Se as x,fe as y,pe as z};
2
- //# sourceMappingURL=chunk-YDQFEK6R.js.map
2
+ //# sourceMappingURL=chunk-X4WOMEVS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts","../src/Component.ts","../src/Indexer.ts","../src/utils.ts","../src/Entity.ts"],"sourcesContent":["/**\n * Type enum is used to specify value types in {@link ComponentSchema} to be able\n * to access type values in JavaScript in addition to TypeScript type checks.\n */\nexport enum Type {\n Boolean,\n Number,\n OptionalNumber,\n BigInt,\n OptionalBigInt,\n String,\n OptionalString,\n NumberArray,\n OptionalNumberArray,\n BigIntArray,\n OptionalBigIntArray,\n StringArray,\n OptionalStringArray,\n Entity,\n OptionalEntity,\n EntityArray,\n OptionalEntityArray,\n T,\n OptionalT,\n}\n\n/**\n * Used to specify type of {@link ComponentUpdate}.\n * - Enter: Update added a value to an entity that did not have a value before\n * - Exit: Update removed a value from an entity that had a value before\n * - Update: Update changed a value of an entity that already had a value before. Note: the value doesn't need to be different from the previous value.\n * - Noop: Update did nothing (removed a value from an entity that did not have a value)\n */\nexport enum UpdateType {\n Enter,\n Exit,\n Update,\n Noop,\n}\n\n/**\n * Helper constant with all optional {@link Type}s.\n */\nexport const OptionalTypes = [\n Type.OptionalEntity,\n Type.OptionalEntityArray,\n Type.OptionalNumber,\n Type.OptionalNumberArray,\n Type.OptionalBigInt,\n Type.OptionalBigIntArray,\n Type.OptionalString,\n Type.OptionalStringArray,\n Type.OptionalT,\n];\n","import { transformIterator, uuid } from \"@latticexyz/utils\";\nimport { mapObject } from \"@latticexyz/utils\";\nimport { filter, map, Subject } from \"rxjs\";\nimport { OptionalTypes } from \"./constants\";\nimport { createIndexer } from \"./Indexer\";\nimport {\n Component,\n ComponentValue,\n Entity,\n EntitySymbol,\n Indexer,\n Metadata,\n OverridableComponent,\n Override,\n Schema,\n World,\n} from \"./types\";\nimport { isFullComponentValue, isIndexer } from \"./utils\";\nimport { getEntityString, getEntitySymbol } from \"./Entity\";\n\nexport type ComponentMutationOptions = {\n /** Skip publishing this mutation to the component's update stream. Mostly used internally during initial hydration. */\n skipUpdateStream?: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getComponentName(component: Component<any, any, any>) {\n return (\n component.metadata?.componentName ??\n component.metadata?.tableName ??\n component.metadata?.tableId ??\n component.metadata?.contractId ??\n component.id\n );\n}\n\n/**\n * Components contain state indexed by entities and are one of the fundamental building blocks in ECS.\n * Besides containing the state, components expose an rxjs update$ stream, that emits an event any time the value\n * of an entity in this component is updated.\n *\n * @param world {@link World} object this component should be registered onto.\n * @param schema {@link Schema} of component values. Uses Type enum as bridge between typescript types and javascript accessible values.\n * @param options Optional: {\n * id: descriptive id for this component (otherwise an autogenerated id is used),\n * metadata: arbitrary metadata,\n * indexed: if this flag is set, an indexer is applied to this component (see {@link createIndexer})\n * }\n * @returns Component object linked to the provided World\n *\n * @example\n * ```\n * const Position = defineComponent(world, { x: Type.Number, y: Type.Number }, { id: \"Position\" });\n * ```\n */\nexport function defineComponent<S extends Schema, M extends Metadata, T = unknown>(\n world: World,\n schema: S,\n options?: { id?: string; metadata?: M; indexed?: boolean },\n) {\n if (Object.keys(schema).length === 0) throw new Error(\"Component schema must have at least one key\");\n const id = options?.id ?? uuid();\n const values = mapObject(schema, () => new Map());\n const update$ = new Subject();\n const metadata = options?.metadata;\n const entities = () =>\n transformIterator((Object.values(values)[0] as Map<EntitySymbol, unknown>).keys(), getEntityString);\n let component = { values, schema, id, update$, metadata, entities, world } as Component<S, M, T>;\n if (options?.indexed) component = createIndexer(component);\n world.registerComponent(component as Component);\n return component;\n}\n\n/**\n * Set the value for a given entity in a given component.\n *\n * @param component {@link defineComponent Component} to be updated.\n * @param entity {@link Entity} whose value in the given component should be set.\n * @param value Value to set, schema must match the component schema.\n *\n * @example\n * ```\n * setComponent(Position, entity, { x: 1, y: 2 });\n * ```\n */\nexport function setComponent<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n entity: Entity,\n value: ComponentValue<S, T>,\n options: ComponentMutationOptions = {},\n) {\n const entitySymbol = getEntitySymbol(entity);\n const prevValue = getComponentValue(component, entity);\n for (const [key, val] of Object.entries(value)) {\n if (component.values[key]) {\n component.values[key].set(entitySymbol, val);\n } else {\n const isTableFieldIndex = component.metadata?.tableId && /^\\d+$/.test(key);\n if (!isTableFieldIndex) {\n // If this key looks like a field index from `defineStoreComponents`,\n // we can ignore this value without logging anything.\n //\n // Otherwise, we should let the user know we found undefined data.\n console.warn(\n \"Component definition for\",\n getComponentName(component),\n \"is missing key\",\n key,\n \", ignoring value\",\n val,\n \"for entity\",\n entity,\n \". Existing keys: \",\n Object.keys(component.values),\n );\n }\n }\n }\n if (!options.skipUpdateStream) {\n component.update$.next({ entity, value: [value, prevValue], component });\n }\n}\n\n/**\n * Update the value for a given entity in a given component while keeping the old value of keys not included in the update.\n *\n * @param component {@link defineComponent Component} to be updated.\n * @param entity {@link Entity} whose value in the given component should be updated.\n * @param value Partial value to be set, remaining keys will be taken from the existing component value.\n *\n * @remarks\n * This function fails silently during runtime if a partial value is set for an entity that\n * does not have a component value yet, since then a partial value will be set in the component for this entity.\n *\n * @example\n * ```\n * updateComponent(Position, entity, { x: 1 });\n * ```\n */\nexport function updateComponent<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n entity: Entity,\n value: Partial<ComponentValue<S, T>>,\n initialValue?: ComponentValue<S, T>,\n options: ComponentMutationOptions = {},\n) {\n const currentValue = getComponentValue(component, entity);\n if (currentValue === undefined) {\n if (initialValue === undefined) {\n throw new Error(`Can't update component ${getComponentName(component)} without a current value or initial value`);\n }\n setComponent(component, entity, { ...initialValue, ...value }, options);\n } else {\n setComponent(component, entity, { ...currentValue, ...value }, options);\n }\n}\n\n/**\n * Remove a given entity from a given component.\n *\n * @param component {@link defineComponent Component} to be updated.\n * @param entity {@link Entity} whose value should be removed from this component.\n */\nexport function removeComponent<S extends Schema, M extends Metadata, T = unknown>(\n component: Component<S, M, T>,\n entity: Entity,\n options: ComponentMutationOptions = {},\n) {\n const entitySymbol = getEntitySymbol(entity);\n const prevValue = getComponentValue(component, entity);\n for (const key of Object.keys(component.values)) {\n component.values[key].delete(entitySymbol);\n }\n if (!options.skipUpdateStream) {\n component.update$.next({ entity, value: [undefined, prevValue], component });\n }\n}\n\n/**\n * Check whether a component contains a value for a given entity.\n *\n * @param component {@link defineComponent Component} to check whether it has a value for the given entity.\n * @param entity {@link Entity} to check whether it has a value in the given component.\n * @returns true if the component contains a value for the given entity, else false.\n */\nexport function hasComponent<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n entity: Entity,\n): boolean {\n const entitySymbol = getEntitySymbol(entity);\n const map = Object.values(component.values)[0];\n return map.has(entitySymbol);\n}\n\n/**\n * Get the value of a given entity in the given component.\n * Returns undefined if no value or only a partial value is found.\n *\n * @param component {@link defineComponent Component} to get the value from for the given entity.\n * @param entity {@link Entity} to get the value for from the given component.\n * @returns Value of the given entity in the given component or undefined if no value exists.\n */\nexport function getComponentValue<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n entity: Entity,\n): ComponentValue<S, T> | undefined {\n const value: Record<string, unknown> = {};\n const entitySymbol = getEntitySymbol(entity);\n\n // Get the value of each schema key\n const schemaKeys = Object.keys(component.schema);\n for (const key of schemaKeys) {\n const val = component.values[key].get(entitySymbol);\n if (val === undefined && !OptionalTypes.includes(component.schema[key])) return undefined;\n value[key] = val;\n }\n\n return value as ComponentValue<S, T>;\n}\n\n/**\n * Get the value of a given entity in the given component.\n * Throws an error if no value exists for the given entity in the given component.\n *\n * @param component {@link defineComponent Component} to get the value from for the given entity.\n * @param entity {@link Entity} of the entity to get the value for from the given component.\n * @returns Value of the given entity in the given component.\n *\n * @remarks\n * Throws an error if no value exists in the component for the given entity.\n */\nexport function getComponentValueStrict<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n entity: Entity,\n): ComponentValue<S, T> {\n const value = getComponentValue(component, entity);\n if (!value) throw new Error(`No value for component ${getComponentName(component)} on entity ${entity}`);\n return value;\n}\n\n/**\n * Compare two {@link ComponentValue}s.\n * `a` can be a partial component value, in which case only the keys present in `a` are compared to the corresponding keys in `b`.\n *\n * @param a Partial {@link ComponentValue} to compare to `b`\n * @param b Component value to compare `a` to.\n * @returns True if `a` equals `b` in the keys present in a or neither `a` nor `b` are defined, else false.\n *\n * @example\n * ```\n * componentValueEquals({ x: 1, y: 2 }, { x: 1, y: 3 }) // returns false because value of y doesn't match\n * componentValueEquals({ x: 1 }, { x: 1, y: 3 }) // returns true because x is equal and y is not present in a\n * ```\n */\nexport function componentValueEquals<S extends Schema, T = unknown>(\n a?: Partial<ComponentValue<S, T>>,\n b?: ComponentValue<S, T>,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n\n let equals = true;\n for (const key of Object.keys(a)) {\n equals = a[key] === b[key];\n if (!equals) return false;\n }\n return equals;\n}\n\n/**\n * Util to create a tuple of a component and value with matching schema.\n * (Used to enforce Typescript type safety.)\n *\n * @param component {@link defineComponent Component} with {@link ComponentSchema} `S`\n * @param value {@link ComponentValue} with {@link ComponentSchema} `S`\n * @returns Tuple `[component, value]`\n */\nexport function withValue<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n value: ComponentValue<S, T>,\n): [Component<S, Metadata, T>, ComponentValue<S, T>] {\n return [component, value];\n}\n\n/**\n * Get a set of entities that have the given component value in the given component.\n *\n * @param component {@link defineComponent Component} to get entities with the given value from.\n * @param value look for entities with this {@link ComponentValue}.\n * @returns Set with {@link Entity Entities} with the given component value.\n */\nexport function getEntitiesWithValue<S extends Schema>(\n component: Component<S> | Indexer<S>,\n value: Partial<ComponentValue<S>>,\n): Set<Entity> {\n // Shortcut for indexers\n if (isIndexer(component) && isFullComponentValue(component, value)) {\n return component.getEntitiesWithValue(value);\n }\n\n // Trivial implementation for regular components\n const entities = new Set<Entity>();\n for (const entity of getComponentEntities(component)) {\n const val = getComponentValue(component, entity);\n if (componentValueEquals(value, val)) {\n entities.add(entity);\n }\n }\n return entities;\n}\n\n/**\n * Get a set of all entities of the given component.\n *\n * @param component {@link defineComponent Component} to get all entities from\n * @returns Set of all entities in the given component.\n */\nexport function getComponentEntities<S extends Schema, T = unknown>(\n component: Component<S, Metadata, T>,\n): IterableIterator<Entity> {\n return component.entities();\n}\n\n/**\n * An overridable component is a mirror of the source component, with functions to lazily override specific entity values.\n * Lazily override means the values are not actually set to the source component, but the override is only returned if the value is read.\n *\n * - When an override for an entity is added to the component, the override is propagated via the component's `update$` stream.\n * - While an override is set for a specific entity, no updates to the source component for this entity will be propagated to the `update$` stream.\n * - When an override is removed for a specific entity and there are more overrides targeting this entity,\n * the override with the highest nonce will be propagated to the `update$` stream.\n * - When an override is removed for a specific entity and there are no more overrides targeting this entity,\n * the non-overridden underlying component value of this entity will be propagated to the `update$` stream.\n *\n * @param component {@link defineComponent Component} to use as underlying source for the overridable component\n * @returns overridable component\n */\nexport function overridableComponent<S extends Schema, M extends Metadata, T = unknown>(\n component: Component<S, M, T>,\n): OverridableComponent<S, M, T> {\n let nonce = 0;\n\n // Map from OverrideId to Override (to be able to add multiple overrides to the same Entity)\n const overrides = new Map<string, { update: Override<S, T>; nonce: number }>();\n\n // Map from EntitySymbol to current overridden component value\n const overriddenEntityValues = new Map<EntitySymbol, Partial<ComponentValue<S, T>> | null>();\n\n // Update event stream that takes into account overridden entity values\n const update$ = new Subject<{\n entity: Entity;\n value: [ComponentValue<S, T> | undefined, ComponentValue<S, T> | undefined];\n component: Component<S, Metadata, T>;\n }>();\n\n // Add a new override to some entity\n function addOverride(id: string, update: Override<S, T>) {\n overrides.set(id, { update, nonce: nonce++ });\n setOverriddenComponentValue(update.entity, update.value);\n }\n\n // Remove an override from an entity\n function removeOverride(id: string) {\n const affectedEntity = overrides.get(id)?.update.entity;\n overrides.delete(id);\n\n if (affectedEntity == null) return;\n\n // If there are more overries affecting this entity,\n // set the overriddenEntityValue to the last override\n const relevantOverrides = [...overrides.values()]\n .filter((o) => o.update.entity === affectedEntity)\n .sort((a, b) => (a.nonce < b.nonce ? -1 : 1));\n\n if (relevantOverrides.length > 0) {\n const lastOverride = relevantOverrides[relevantOverrides.length - 1];\n setOverriddenComponentValue(affectedEntity, lastOverride.update.value);\n } else {\n setOverriddenComponentValue(affectedEntity, undefined);\n }\n }\n\n // Internal function to get the current overridden value or value of the source component\n function getOverriddenComponentValue(entity: Entity): ComponentValue<S, T> | undefined {\n const originalValue = getComponentValue(component, entity);\n const entitySymbol = getEntitySymbol(entity);\n const overriddenValue = overriddenEntityValues.get(entitySymbol);\n return (originalValue || overriddenValue) && overriddenValue !== null // null is a valid override, in this case return undefined\n ? ({ ...originalValue, ...overriddenValue } as ComponentValue<S, T>)\n : undefined;\n }\n\n const valueProxyHandler: (key: keyof S) => ProxyHandler<(typeof component.values)[typeof key]> = (key: keyof S) => ({\n get(target, prop) {\n // Intercept calls to component.value[key].get(entity)\n if (prop === \"get\") {\n return (entity: EntitySymbol) => {\n const originalValue = target.get(entity);\n const overriddenValue = overriddenEntityValues.get(entity);\n return overriddenValue && overriddenValue[key] != null ? overriddenValue[key] : originalValue;\n };\n }\n\n // Intercept calls to component.value[key].has(entity)\n if (prop === \"has\") {\n return (entity: EntitySymbol) => {\n return target.has(entity) || overriddenEntityValues.has(entity);\n };\n }\n\n // Intercept calls to component.value[key].keys()\n if (prop === \"keys\") {\n return () => new Set([...target.keys(), ...overriddenEntityValues.keys()]).values();\n }\n\n return Reflect.get(target, prop, target);\n },\n });\n\n const partialValues: Partial<Component<S, M, T>[\"values\"]> = {};\n for (const key of Object.keys(component.values) as (keyof S)[]) {\n partialValues[key] = new Proxy(component.values[key], valueProxyHandler(key));\n }\n const valuesProxy = partialValues as Component<S, M, T>[\"values\"];\n\n const overriddenComponent = new Proxy(component, {\n get(target, prop) {\n if (prop === \"addOverride\") return addOverride;\n if (prop === \"removeOverride\") return removeOverride;\n if (prop === \"values\") return valuesProxy;\n if (prop === \"update$\") return update$;\n if (prop === \"entities\")\n return () =>\n new Set([\n ...transformIterator(overriddenEntityValues.keys(), getEntityString),\n ...target.entities(),\n ]).values();\n\n return Reflect.get(target, prop);\n },\n has(target, prop) {\n if (prop === \"addOverride\" || prop === \"removeOverride\") return true;\n return prop in target;\n },\n }) as OverridableComponent<S, M, T>;\n\n // Internal function to set the current overridden component value and emit the update event\n function setOverriddenComponentValue(entity: Entity, value?: Partial<ComponentValue<S, T>> | null) {\n const entitySymbol = getEntitySymbol(entity);\n // Check specifically for undefined - null is a valid override\n const prevValue = getOverriddenComponentValue(entity);\n if (value !== undefined) overriddenEntityValues.set(entitySymbol, value);\n else overriddenEntityValues.delete(entitySymbol);\n update$.next({ entity, value: [getOverriddenComponentValue(entity), prevValue], component: overriddenComponent });\n }\n\n // Channel through update events from the original component if there are no overrides\n component.update$\n .pipe(\n filter((e) => !overriddenEntityValues.get(getEntitySymbol(e.entity))),\n map((update) => ({ ...update, component: overriddenComponent })),\n )\n .subscribe(update$);\n\n return overriddenComponent;\n}\n\nfunction getLocalCacheId(component: Component, uniqueWorldIdentifier?: string): string {\n return `localcache-${uniqueWorldIdentifier}-${component.id}`;\n}\n\nexport function clearLocalCache(component: Component, uniqueWorldIdentifier?: string): void {\n localStorage.removeItem(getLocalCacheId(component, uniqueWorldIdentifier));\n}\n\n// Note: Only proof of concept for now - use this only for component that do not update frequently\nexport function createLocalCache<S extends Schema, M extends Metadata, T = unknown>(\n component: Component<S, M, T>,\n uniqueWorldIdentifier?: string,\n): Component<S, M, T> {\n const { world, update$, values } = component;\n const cacheId = getLocalCacheId(component as Component, uniqueWorldIdentifier);\n let numUpdates = 0;\n const creation = Date.now();\n\n // On creation, check if this component has locally cached values\n const encodedCache = localStorage.getItem(cacheId);\n if (encodedCache) {\n const cache = JSON.parse(encodedCache) as [string, [Entity, unknown][]][];\n const state: { [entity: Entity]: { [key: string]: unknown } } = {};\n\n for (const [key, values] of cache) {\n for (const [entity, value] of values) {\n state[entity] = state[entity] || {};\n state[entity][key] = value;\n }\n }\n\n for (const [entityId, value] of Object.entries(state)) {\n const entity = world.registerEntity({ id: entityId });\n setComponent(component, entity, value as ComponentValue<S, T>);\n }\n\n console.info(\"Loading component\", getComponentName(component), \"from local cache.\");\n }\n\n // Flush the entire component to the local cache every time it updates.\n // Note: this is highly unperformant and should only be used for components that\n // don't update often and don't have many values\n const updateSub = update$.subscribe(() => {\n numUpdates++;\n const encoded = JSON.stringify(\n Object.entries(mapObject(values, (m) => [...m.entries()].map((e) => [getEntityString(e[0]), e[1]]))),\n );\n localStorage.setItem(cacheId, encoded);\n if (numUpdates > 200) {\n console.warn(\n \"Component\",\n getComponentName(component),\n \"was locally cached\",\n numUpdates,\n \"times since\",\n new Date(creation).toLocaleTimeString(),\n \"- the local cache is in an alpha state and should not be used with components that update frequently yet\",\n );\n }\n });\n component.world.registerDisposer(() => updateSub?.unsubscribe());\n\n return component;\n}\n","import { getComponentEntities, getComponentValue } from \"./Component\";\nimport { getEntityString, getEntitySymbol } from \"./Entity\";\nimport { Component, ComponentValue, Entity, EntitySymbol, Indexer, Metadata, Schema } from \"./types\";\n\n/**\n * Create an indexed component from a given component.\n *\n * @remarks\n * An indexed component keeps a \"reverse mapping\" from {@link ComponentValue} to the Set of {@link createEntity Entities} with this value.\n * This adds a performance overhead to modifying component values and a memory overhead since in the worst case there is one\n * Set per entity (if every entity has a different component value).\n * In return the performance for querying for entities with a given component value is close to O(1) (instead of O(#entities) in a regular non-indexed component).\n * As a rule of thumb only components that are added to many entities and are queried with {@link HasValue} a lot should be indexed (eg. the Position component).\n *\n * @dev This could be made more (memory) efficient by using a hash of the component value as key, but would require handling hash collisions.\n *\n * @param component {@link defineComponent Component} to index.\n * @returns Indexed version of the component.\n */\nexport function createIndexer<S extends Schema, M extends Metadata, T = unknown>(\n component: Component<S, M, T>,\n): Indexer<S, M, T> {\n const valueToEntities = new Map<string, Set<EntitySymbol>>();\n\n function getEntitiesWithValue(value: ComponentValue<S, T>) {\n const entities = valueToEntities.get(getValueKey(value));\n return entities ? new Set([...entities].map(getEntityString)) : new Set<Entity>();\n }\n\n function getValueKey(value: ComponentValue<S, T>): string {\n return Object.values(value).join(\"/\");\n }\n\n function add(entity: EntitySymbol, value: ComponentValue<S, T> | undefined) {\n if (!value) return;\n const valueKey = getValueKey(value);\n let entitiesWithValue = valueToEntities.get(valueKey);\n if (!entitiesWithValue) {\n entitiesWithValue = new Set<EntitySymbol>();\n valueToEntities.set(valueKey, entitiesWithValue);\n }\n entitiesWithValue.add(entity);\n }\n\n function remove(entity: EntitySymbol, value: ComponentValue<S, T> | undefined) {\n if (!value) return;\n const valueKey = getValueKey(value);\n const entitiesWithValue = valueToEntities.get(valueKey);\n if (!entitiesWithValue) return;\n entitiesWithValue.delete(entity);\n }\n\n // Initial indexing\n for (const entity of getComponentEntities(component)) {\n const value = getComponentValue(component, entity);\n add(getEntitySymbol(entity), value);\n }\n\n // Keeping index up to date\n const subscription = component.update$.subscribe(({ entity, value }) => {\n // Remove from previous location\n remove(getEntitySymbol(entity), value[1]);\n\n // Add to new location\n add(getEntitySymbol(entity), value[0]);\n });\n\n component.world.registerDisposer(() => subscription?.unsubscribe());\n\n return { ...component, getEntitiesWithValue };\n}\n","import { map, pipe } from \"rxjs\";\nimport { getComponentValue } from \"./Component\";\nimport { UpdateType } from \"./constants\";\nimport { Component, ComponentUpdate, ComponentValue, Entity, Indexer, Schema } from \"./types\";\n\n/**\n * Type guard to infer the TypeScript type of a given component update\n *\n * @param update Component update to infer the type of.\n * @param component {@link defineComponent Component} to check whether the given update corresponds to it.\n * @returns True (+ infered type for `update`) if `update` belongs to `component`. Else false.\n */\nexport function isComponentUpdate<S extends Schema>(\n update: ComponentUpdate,\n component: Component<S>,\n): update is ComponentUpdate<S> {\n return update.component === component;\n}\n\n/**\n * Helper function to create a component update for the current component value of a given entity.\n *\n * @param entity Entity to create the component update for.\n * @param component Component to create the component update for.\n * @returns Component update corresponding to the given entity, the given component and the entity's current component value.\n */\nexport function toUpdate<S extends Schema>(entity: Entity, component: Component<S>) {\n const value = getComponentValue(component, entity);\n return {\n entity,\n component,\n value: [value, undefined],\n type: value == null ? UpdateType.Noop : UpdateType.Enter,\n } as ComponentUpdate<S> & {\n type: UpdateType;\n };\n}\n\n/**\n * Helper function to turn a stream of {@link Entity Entities} into a stream of component updates of the given component.\n * @param component Component to create update stream for.\n * @returns Unary function to be used with RxJS that turns stream of {@link Entity Entities} into stream of component updates.\n */\nexport function toUpdateStream<S extends Schema>(component: Component<S>) {\n return pipe(map((entity: Entity) => toUpdate(entity, component)));\n}\n\n/**\n * Helper function to check whether a given component is indexed.\n * @param c\n * @returns\n */\nexport function isIndexer<S extends Schema>(c: Component<S> | Indexer<S>): c is Indexer<S> {\n return \"getEntitiesWithValue\" in c;\n}\n\n/**\n * Helper function to check whether a given component value is partial or full.\n * @param component\n * @param value\n * @returns\n */\nexport function isFullComponentValue<S extends Schema>(\n component: Component<S>,\n value: Partial<ComponentValue<S>>,\n): value is ComponentValue<S> {\n return Object.keys(component.schema).every((key) => key in value);\n}\n","import { setComponent } from \"./Component\";\nimport { Component, ComponentValue, Entity, EntitySymbol, World } from \"./types\";\n\n/**\n * Register a new entity in the given {@link World} and initialize it with the given {@link ComponentValue}s.\n *\n * @param world World object this entity should be registered in.\n * @param components Array of [{@link defineComponent Component}, {@link ComponentValue}] tuples to be added to this entity.\n * (Use {@link withValue} to generate these tuples with type safety.)\n * @param options Optional: {\n * id: {@link Entity} for this entity. Use this for entities that were created outside of recs.\n * idSuffix: string to be appended to the auto-generated id. Use this for improved readability. Do not use this if the `id` option is provided.\n * }\n * @returns index of this entity in the {@link World}. This {@link Entity} is used to refer to this entity in other recs methods (eg {@link setComponent}).\n * (This is to avoid having to store strings in every component.)\n */\nexport function createEntity(\n world: World,\n components?: [Component, ComponentValue][],\n options?: { id?: string } | { idSuffix?: string },\n): Entity {\n const entity = world.registerEntity(options ?? {});\n\n if (components) {\n for (const [component, value] of components) {\n setComponent(component, entity, value);\n }\n }\n\n return entity;\n}\n\n/*\n * Get the symbol corresponding to an entity's string ID.\n * Entities are represented as symbols internally for memory efficiency.\n */\nexport function getEntitySymbol(entityString: string): EntitySymbol {\n return Symbol.for(entityString) as EntitySymbol;\n}\n\n/**\n * Get the underlying entity string of an entity symbol.\n */\nexport function getEntityString(entity: EntitySymbol): Entity {\n return Symbol.keyFor(entity) as Entity;\n}\n"],"mappings":"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","names":["Type","UpdateType","OptionalTypes","transformIterator","uuid","mapObject","filter","map","Subject","createIndexer","component","valueToEntities","getEntitiesWithValue","value","entities","getValueKey","getEntityString","add","entity","valueKey","entitiesWithValue","remove","getComponentEntities","getComponentValue","getEntitySymbol","subscription","map","pipe","isComponentUpdate","update","component","toUpdate","entity","value","getComponentValue","toUpdateStream","pipe","map","isIndexer","c","isFullComponentValue","key","getComponentName","component","defineComponent","world","schema","options","id","uuid","values","mapObject","update$","Subject","metadata","transformIterator","getEntityString","createIndexer","setComponent","entity","value","entitySymbol","getEntitySymbol","prevValue","getComponentValue","key","val","updateComponent","initialValue","currentValue","removeComponent","hasComponent","schemaKeys","OptionalTypes","getComponentValueStrict","componentValueEquals","a","b","equals","withValue","getEntitiesWithValue","isIndexer","isFullComponentValue","entities","getComponentEntities","overridableComponent","nonce","overrides","overriddenEntityValues","addOverride","update","setOverriddenComponentValue","removeOverride","affectedEntity","relevantOverrides","o","lastOverride","getOverriddenComponentValue","originalValue","overriddenValue","valueProxyHandler","target","prop","partialValues","valuesProxy","overriddenComponent","filter","e","map","getLocalCacheId","uniqueWorldIdentifier","clearLocalCache","createLocalCache","cacheId","numUpdates","creation","encodedCache","cache","state","entityId","updateSub","encoded","m","createEntity","world","components","options","entity","component","value","setComponent","getEntitySymbol","entityString","getEntityString"]}
@@ -1,2 +1,2 @@
1
- import{d as h,m as O,n as T,o as a,r as c,x as v}from"../chunk-YDQFEK6R.js";var b=(s=>(s.Requested="Requested",s.Executing="Executing",s.WaitingForTxEvents="WaitingForTxEvents",s.Complete="Complete",s.Failed="Failed",s.Cancelled="Cancelled",s.TxReduced="TxReduced",s))(b||{});import{merge as S}from"rxjs";import{mapObject as D,awaitStreamValue as F,uuid as R}from"@latticexyz/utils";function A(d){return O(d,{state:5,on:14,metadata:18,overrides:12,txHash:6},{id:"Action"})}function L(d,x,C){let o=A(d),m={},u=new Map,f=new Map;d.registerDisposer(()=>{for(let{dispose:t}of f.values())t()});function s(t){let n=m[t.id]||v(t);return m[t.id]||(m[t.id]=n),n}function E(t){if(d.hasEntity(t.id))return console.warn(`Action with id ${t.id} is already requested.`),t.id;let i=h(d,void 0,{id:t.id});T(o,i,{state:"Requested",on:t.on,metadata:t.metadata,overrides:void 0,txHash:void 0});for(let r of Object.values(t.components))m[r.id]||(m[r.id]=v(r));let e={...t,entity:i,componentsWithOptimisticUpdates:D(t.components,r=>s(r))};u.set(e.id,e);let p=S(...Object.values(e.componentsWithOptimisticUpdates).map(r=>r.update$)).subscribe(()=>g(e));return g(e),f.set(e.id,{dispose:()=>p?.unsubscribe()}),i}function g(t){if(c(o,t.entity)?.state!=="Requested")return;let n=t.requirement(t.componentsWithOptimisticUpdates);n&&w(t,n)}async function w(t,n){if(c(o,t.entity)?.state!=="Requested")return;a(o,t.entity,{state:"Executing"});let i=t.updates(t.componentsWithOptimisticUpdates,n).map(e=>({...e,id:R()}));a(o,t.entity,{overrides:i.map(e=>`${e.id}/${e.component.id}`)});for(let{component:e,value:p,entity:r,id:y}of i)m[e.id].addOverride(y,{entity:r,value:p});try{let e=await t.execute(n);if(e&&(a(o,t.entity,{state:"WaitingForTxEvents",txHash:e}),await F(x,p=>p===e),a(o,t.entity,{state:"TxReduced"}),t.awaitConfirmation))if(C)await C(e);else throw new Error("action has awaitConfirmation but no waitForTransaction specified in createActionSystem");a(o,t.entity,{state:"Complete"})}catch(e){M(e,t)}l(t.id)}function M(t,n){console.error(t),a(o,n.entity,{state:"Failed"}),l(n.id)}function W(t){let n=u.get(t);return!n||c(o,n.entity)?.state!=="Requested"?(console.warn(`Action ${t} was not found or is not in the "Requested" state.`),!1):(a(o,n.entity,{state:"Cancelled"}),l(t),!0)}function l(t){if(!u.get(t)){console.warn(`Trying to remove action ${t} that does not exist.`);return}let i=t,e=i!=null&&c(o,i)?.overrides||[];for(let p of e){let[r,y]=p.split("/");m[y].removeOverride(r)}f.get(t)?.dispose(),f.delete(t),u.delete(t),i!=null&&setTimeout(()=>d.deleteEntity(i),5e3)}return{add:E,cancel:W,withOptimisticUpdates:s,Action:o}}export{b as ActionState,L as createActionSystem};
1
+ import{d as h,m as O,n as T,o as a,r as c,x as v}from"../chunk-X4WOMEVS.js";var b=(s=>(s.Requested="Requested",s.Executing="Executing",s.WaitingForTxEvents="WaitingForTxEvents",s.Complete="Complete",s.Failed="Failed",s.Cancelled="Cancelled",s.TxReduced="TxReduced",s))(b||{});import{merge as S}from"rxjs";import{mapObject as D,awaitStreamValue as F,uuid as R}from"@latticexyz/utils";function A(d){return O(d,{state:5,on:14,metadata:18,overrides:12,txHash:6},{id:"Action"})}function L(d,x,C){let o=A(d),m={},u=new Map,f=new Map;d.registerDisposer(()=>{for(let{dispose:t}of f.values())t()});function s(t){let n=m[t.id]||v(t);return m[t.id]||(m[t.id]=n),n}function E(t){if(d.hasEntity(t.id))return console.warn(`Action with id ${t.id} is already requested.`),t.id;let i=h(d,void 0,{id:t.id});T(o,i,{state:"Requested",on:t.on,metadata:t.metadata,overrides:void 0,txHash:void 0});for(let r of Object.values(t.components))m[r.id]||(m[r.id]=v(r));let e={...t,entity:i,componentsWithOptimisticUpdates:D(t.components,r=>s(r))};u.set(e.id,e);let p=S(...Object.values(e.componentsWithOptimisticUpdates).map(r=>r.update$)).subscribe(()=>g(e));return g(e),f.set(e.id,{dispose:()=>p?.unsubscribe()}),i}function g(t){if(c(o,t.entity)?.state!=="Requested")return;let n=t.requirement(t.componentsWithOptimisticUpdates);n&&w(t,n)}async function w(t,n){if(c(o,t.entity)?.state!=="Requested")return;a(o,t.entity,{state:"Executing"});let i=t.updates(t.componentsWithOptimisticUpdates,n).map(e=>({...e,id:R()}));a(o,t.entity,{overrides:i.map(e=>`${e.id}/${e.component.id}`)});for(let{component:e,value:p,entity:r,id:y}of i)m[e.id].addOverride(y,{entity:r,value:p});try{let e=await t.execute(n);if(e&&(a(o,t.entity,{state:"WaitingForTxEvents",txHash:e}),await F(x,p=>p===e),a(o,t.entity,{state:"TxReduced"}),t.awaitConfirmation))if(C)await C(e);else throw new Error("action has awaitConfirmation but no waitForTransaction specified in createActionSystem");a(o,t.entity,{state:"Complete"})}catch(e){M(e,t)}l(t.id)}function M(t,n){console.error(t),a(o,n.entity,{state:"Failed"}),l(n.id)}function W(t){let n=u.get(t);return!n||c(o,n.entity)?.state!=="Requested"?(console.warn(`Action ${t} was not found or is not in the "Requested" state.`),!1):(a(o,n.entity,{state:"Cancelled"}),l(t),!0)}function l(t){if(!u.get(t)){console.warn(`Trying to remove action ${t} that does not exist.`);return}let i=t,e=i!=null&&c(o,i)?.overrides||[];for(let p of e){let[r,y]=p.split("/");m[y].removeOverride(r)}f.get(t)?.dispose(),f.delete(t),u.delete(t),i!=null&&setTimeout(()=>d.deleteEntity(i),5e3)}return{add:E,cancel:W,withOptimisticUpdates:s,Action:o}}export{b as ActionState,L as createActionSystem};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/deprecated/constants.ts","../../src/deprecated/createActionSystem.ts","../../src/deprecated/defineActionComponent.ts"],"sourcesContent":["export enum ActionState {\n Requested = \"Requested\",\n Executing = \"Executing\",\n WaitingForTxEvents = \"WaitingForTxEvents\",\n Complete = \"Complete\",\n Failed = \"Failed\",\n Cancelled = \"Cancelled\",\n TxReduced = \"TxReduced\",\n}\n","import { merge, Observable } from \"rxjs\";\nimport { mapObject, awaitStreamValue, uuid } from \"@latticexyz/utils\";\nimport { ActionState } from \"./constants\";\nimport { ActionData, ActionRequest } from \"./types\";\nimport { defineActionComponent } from \"./defineActionComponent\";\nimport { overridableComponent, setComponent, getComponentValue, updateComponent } from \"../Component\";\nimport { createEntity } from \"../Entity\";\nimport { World, OverridableComponent, Metadata, Component, Components, Entity, Schema } from \"../types\";\n\nexport type ActionSystem = ReturnType<typeof createActionSystem>;\n\n/**\n * @deprecated For now, we suggest using `overridableComponent(Component)` and `addOverride`/`removeOverride` to manage overrides yourself.\n */\nexport function createActionSystem<M = unknown>(\n world: World,\n txReduced$: Observable<string>,\n waitForTransaction?: (tx: string) => Promise<void>\n) {\n // Action component\n const Action = defineActionComponent<M>(world);\n\n // Components that scheduled actions depend on including pending updates\n const componentsWithOptimisticUpdates: { [id: string]: OverridableComponent<Schema> } = {};\n\n // ActionData contains requirements and execute logic of scheduled actions.\n // We also store the relevant subset of all componentsWithOptimisticUpdates in the action data,\n // to recheck requirements only if relevant components updated.\n const actionData = new Map<string, ActionData>();\n\n // Disposers of requirement check autoruns for all pending actions\n const disposer = new Map<string, { dispose: () => void }>();\n world.registerDisposer(() => {\n for (const { dispose } of disposer.values()) dispose();\n });\n\n /**\n * Maps all components in a given components map to the respective components including pending updates\n * @param component Component to be mapped to components including pending updates\n * @returns Components including pending updates\n */\n function withOptimisticUpdates<S extends Schema, M extends Metadata, T>(\n component: Component<S, M, T>\n ): OverridableComponent<S, M, T> {\n const optimisticComponent = componentsWithOptimisticUpdates[component.id] || overridableComponent(component);\n\n // If the component is not tracked yet, add it to the map of overridable components\n if (!componentsWithOptimisticUpdates[component.id]) {\n componentsWithOptimisticUpdates[component.id] = optimisticComponent;\n }\n\n // Typescript can't know that the optimistic component with this id has the same type as C\n return optimisticComponent as OverridableComponent<S, M, T>;\n }\n\n /**\n * Schedules an action. The action will be executed once its requirement is fulfilled.\n * Note: the requirement will only be rechecked automatically if the requirement is based on components\n * (or other mobx-observable values).\n * @param actionRequest Action to be scheduled\n * @returns index of the entity created for the action\n */\n function add<C extends Components, T>(actionRequest: ActionRequest<C, T, M>): Entity {\n // Prevent the same actions from being scheduled multiple times\n const existingAction = world.hasEntity(actionRequest.id as Entity);\n if (existingAction) {\n console.warn(`Action with id ${actionRequest.id} is already requested.`);\n return actionRequest.id as Entity;\n }\n\n // Set the action component\n const entity = createEntity(world, undefined, {\n id: actionRequest.id,\n });\n\n setComponent(Action, entity, {\n state: ActionState.Requested,\n on: actionRequest.on,\n metadata: actionRequest.metadata,\n overrides: undefined,\n txHash: undefined,\n });\n\n // Add components that are not tracked yet to internal overridable component map.\n // Pending updates will be applied to internal overridable components.\n for (const component of Object.values(actionRequest.components)) {\n if (!componentsWithOptimisticUpdates[component.id])\n componentsWithOptimisticUpdates[component.id] = overridableComponent(component);\n }\n\n // Store relevant components with pending updates along the action's requirement and execution logic\n const action = {\n ...actionRequest,\n entity,\n componentsWithOptimisticUpdates: mapObject(actionRequest.components, (c) => withOptimisticUpdates(c)),\n } as unknown as ActionData;\n actionData.set(action.id, action);\n\n // This subscriotion makes sure the action requirement is checked again every time\n // one of the referenced components changes or the pending updates map changes\n const subscription = merge(\n ...Object.values(action.componentsWithOptimisticUpdates).map((c) => c.update$)\n ).subscribe(() => checkRequirement(action));\n checkRequirement(action);\n disposer.set(action.id, { dispose: () => subscription?.unsubscribe() });\n\n return entity;\n }\n\n /**\n * Checks the requirement of a given action and executes the action if the requirement is fulfilled\n * @param action Action to check the requirement of\n * @returns void\n */\n function checkRequirement(action: ActionData) {\n // Only check requirements of requested actions\n if (getComponentValue(Action, action.entity)?.state !== ActionState.Requested) return;\n\n // Check requirement on components including pending updates\n const requirementResult = action.requirement(action.componentsWithOptimisticUpdates);\n\n // Execute the action if the requirements are met\n if (requirementResult) executeAction(action, requirementResult);\n }\n\n /**\n * Executes the given action and sets the corresponding Action component\n * @param action ActionData of the action to be executed\n * @param requirementResult Result of the action's requirement function\n * @returns void\n */\n async function executeAction<T>(action: ActionData, requirementResult: T) {\n // Only execute actions that were requested before\n if (getComponentValue(Action, action.entity)?.state !== ActionState.Requested) return;\n\n // Update the action state\n updateComponent(Action, action.entity, { state: ActionState.Executing });\n\n // Compute overrides\n const overrides = action\n .updates(action.componentsWithOptimisticUpdates, requirementResult)\n .map((o) => ({ ...o, id: uuid() }));\n\n // Store overrides on Action component to be able to remove when action is done\n updateComponent(Action, action.entity, { overrides: overrides.map((o) => `${o.id}/${o.component.id}`) });\n\n // Set all pending updates of this action\n for (const { component, value, entity, id } of overrides) {\n componentsWithOptimisticUpdates[component.id].addOverride(id, { entity, value });\n }\n\n try {\n // Execute the action\n const tx = await action.execute(requirementResult);\n\n // If the result includes a hash key (single tx) or hashes (multiple tx) key, wait for the transactions to complete before removing the pending actions\n if (tx) {\n // Wait for all tx events to be reduced\n updateComponent(Action, action.entity, { state: ActionState.WaitingForTxEvents, txHash: tx });\n await awaitStreamValue(txReduced$, (v) => v === tx);\n updateComponent(Action, action.entity, { state: ActionState.TxReduced });\n // TODO: extend ActionData type to be aware of whether waitForTransaction is set\n if (action.awaitConfirmation) {\n if (waitForTransaction) {\n await waitForTransaction(tx);\n } else {\n throw new Error(\"action has awaitConfirmation but no waitForTransaction specified in createActionSystem\");\n }\n }\n }\n\n updateComponent(Action, action.entity, { state: ActionState.Complete });\n } catch (e) {\n handleError(e, action);\n }\n\n // After the action is done executing (failed or completed), remove its actionData and remove the Action component\n remove(action.id);\n }\n\n // Set the action's state to ActionState.Failed\n function handleError(e: unknown, action: ActionData) {\n console.error(e);\n updateComponent(Action, action.entity, { state: ActionState.Failed });\n remove(action.id);\n }\n\n /**\n * Cancels the action with the given ID if it is in the \"Requested\" state.\n * @param actionId ID of the action to be cancelled\n * @returns void\n */\n function cancel(actionId: string): boolean {\n const action = actionData.get(actionId);\n if (!action || getComponentValue(Action, action.entity)?.state !== ActionState.Requested) {\n console.warn(`Action ${actionId} was not found or is not in the \"Requested\" state.`);\n return false;\n }\n updateComponent(Action, action.entity, { state: ActionState.Cancelled });\n remove(actionId);\n return true;\n }\n\n /**\n * Removes actionData disposer of the action with the given ID and removes its pending updates.\n * @param actionId ID of the action to be removed\n */\n function remove(actionId: string) {\n const action = actionData.get(actionId);\n if (!action) {\n console.warn(`Trying to remove action ${actionId} that does not exist.`);\n return;\n }\n\n // Remove this action's pending updates\n const actionEntity = actionId as Entity;\n const overrides = (actionEntity != null && getComponentValue(Action, actionEntity)?.overrides) || [];\n for (const override of overrides) {\n const [id, componentId] = override.split(\"/\");\n const component = componentsWithOptimisticUpdates[componentId];\n component.removeOverride(id);\n }\n\n // Remove this action's autorun and corresponding disposer\n disposer.get(actionId)?.dispose();\n disposer.delete(actionId);\n\n // Remove the action data\n actionData.delete(actionId);\n\n // Remove the action entity after some time\n actionEntity != null && setTimeout(() => world.deleteEntity(actionEntity), 5000);\n }\n\n return { add, cancel, withOptimisticUpdates, Action };\n}\n","import { defineComponent } from \"../Component\";\nimport { Type } from \"../constants\";\nimport { World, Component, SchemaOf, Metadata } from \"../types\";\n\nexport function defineActionComponent<T = unknown>(world: World) {\n const Action = defineComponent(\n world,\n {\n state: Type.String,\n on: Type.OptionalEntity,\n metadata: Type.OptionalT,\n overrides: Type.OptionalStringArray,\n txHash: Type.OptionalString,\n },\n { id: \"Action\" }\n );\n return Action as Component<SchemaOf<typeof Action>, Metadata, T>;\n}\n"],"mappings":"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","names":["ActionState","merge","mapObject","awaitStreamValue","uuid","defineActionComponent","world","defineComponent","createActionSystem","world","txReduced$","waitForTransaction","Action","defineActionComponent","componentsWithOptimisticUpdates","actionData","disposer","dispose","withOptimisticUpdates","component","optimisticComponent","overridableComponent","add","actionRequest","entity","createEntity","setComponent","action","mapObject","c","subscription","merge","checkRequirement","getComponentValue","requirementResult","executeAction","updateComponent","overrides","o","uuid","value","id","tx","awaitStreamValue","v","handleError","remove","e","cancel","actionId","actionEntity","override","componentId"]}
1
+ {"version":3,"sources":["../../src/deprecated/constants.ts","../../src/deprecated/createActionSystem.ts","../../src/deprecated/defineActionComponent.ts"],"sourcesContent":["export enum ActionState {\n Requested = \"Requested\",\n Executing = \"Executing\",\n WaitingForTxEvents = \"WaitingForTxEvents\",\n Complete = \"Complete\",\n Failed = \"Failed\",\n Cancelled = \"Cancelled\",\n TxReduced = \"TxReduced\",\n}\n","import { merge, Observable } from \"rxjs\";\nimport { mapObject, awaitStreamValue, uuid } from \"@latticexyz/utils\";\nimport { ActionState } from \"./constants\";\nimport { ActionData, ActionRequest } from \"./types\";\nimport { defineActionComponent } from \"./defineActionComponent\";\nimport { overridableComponent, setComponent, getComponentValue, updateComponent } from \"../Component\";\nimport { createEntity } from \"../Entity\";\nimport { World, OverridableComponent, Metadata, Component, Components, Entity, Schema } from \"../types\";\n\nexport type ActionSystem = ReturnType<typeof createActionSystem>;\n\n/**\n * @deprecated For now, we suggest using `overridableComponent(Component)` and `addOverride`/`removeOverride` to manage overrides yourself.\n */\nexport function createActionSystem<M = unknown>(\n world: World,\n txReduced$: Observable<string>,\n waitForTransaction?: (tx: string) => Promise<void>,\n) {\n // Action component\n const Action = defineActionComponent<M>(world);\n\n // Components that scheduled actions depend on including pending updates\n const componentsWithOptimisticUpdates: { [id: string]: OverridableComponent<Schema> } = {};\n\n // ActionData contains requirements and execute logic of scheduled actions.\n // We also store the relevant subset of all componentsWithOptimisticUpdates in the action data,\n // to recheck requirements only if relevant components updated.\n const actionData = new Map<string, ActionData>();\n\n // Disposers of requirement check autoruns for all pending actions\n const disposer = new Map<string, { dispose: () => void }>();\n world.registerDisposer(() => {\n for (const { dispose } of disposer.values()) dispose();\n });\n\n /**\n * Maps all components in a given components map to the respective components including pending updates\n * @param component Component to be mapped to components including pending updates\n * @returns Components including pending updates\n */\n function withOptimisticUpdates<S extends Schema, M extends Metadata, T>(\n component: Component<S, M, T>,\n ): OverridableComponent<S, M, T> {\n const optimisticComponent = componentsWithOptimisticUpdates[component.id] || overridableComponent(component);\n\n // If the component is not tracked yet, add it to the map of overridable components\n if (!componentsWithOptimisticUpdates[component.id]) {\n componentsWithOptimisticUpdates[component.id] = optimisticComponent;\n }\n\n // Typescript can't know that the optimistic component with this id has the same type as C\n return optimisticComponent as OverridableComponent<S, M, T>;\n }\n\n /**\n * Schedules an action. The action will be executed once its requirement is fulfilled.\n * Note: the requirement will only be rechecked automatically if the requirement is based on components\n * (or other mobx-observable values).\n * @param actionRequest Action to be scheduled\n * @returns index of the entity created for the action\n */\n function add<C extends Components, T>(actionRequest: ActionRequest<C, T, M>): Entity {\n // Prevent the same actions from being scheduled multiple times\n const existingAction = world.hasEntity(actionRequest.id as Entity);\n if (existingAction) {\n console.warn(`Action with id ${actionRequest.id} is already requested.`);\n return actionRequest.id as Entity;\n }\n\n // Set the action component\n const entity = createEntity(world, undefined, {\n id: actionRequest.id,\n });\n\n setComponent(Action, entity, {\n state: ActionState.Requested,\n on: actionRequest.on,\n metadata: actionRequest.metadata,\n overrides: undefined,\n txHash: undefined,\n });\n\n // Add components that are not tracked yet to internal overridable component map.\n // Pending updates will be applied to internal overridable components.\n for (const component of Object.values(actionRequest.components)) {\n if (!componentsWithOptimisticUpdates[component.id])\n componentsWithOptimisticUpdates[component.id] = overridableComponent(component);\n }\n\n // Store relevant components with pending updates along the action's requirement and execution logic\n const action = {\n ...actionRequest,\n entity,\n componentsWithOptimisticUpdates: mapObject(actionRequest.components, (c) => withOptimisticUpdates(c)),\n } as unknown as ActionData;\n actionData.set(action.id, action);\n\n // This subscriotion makes sure the action requirement is checked again every time\n // one of the referenced components changes or the pending updates map changes\n const subscription = merge(\n ...Object.values(action.componentsWithOptimisticUpdates).map((c) => c.update$),\n ).subscribe(() => checkRequirement(action));\n checkRequirement(action);\n disposer.set(action.id, { dispose: () => subscription?.unsubscribe() });\n\n return entity;\n }\n\n /**\n * Checks the requirement of a given action and executes the action if the requirement is fulfilled\n * @param action Action to check the requirement of\n * @returns void\n */\n function checkRequirement(action: ActionData) {\n // Only check requirements of requested actions\n if (getComponentValue(Action, action.entity)?.state !== ActionState.Requested) return;\n\n // Check requirement on components including pending updates\n const requirementResult = action.requirement(action.componentsWithOptimisticUpdates);\n\n // Execute the action if the requirements are met\n if (requirementResult) executeAction(action, requirementResult);\n }\n\n /**\n * Executes the given action and sets the corresponding Action component\n * @param action ActionData of the action to be executed\n * @param requirementResult Result of the action's requirement function\n * @returns void\n */\n async function executeAction<T>(action: ActionData, requirementResult: T) {\n // Only execute actions that were requested before\n if (getComponentValue(Action, action.entity)?.state !== ActionState.Requested) return;\n\n // Update the action state\n updateComponent(Action, action.entity, { state: ActionState.Executing });\n\n // Compute overrides\n const overrides = action\n .updates(action.componentsWithOptimisticUpdates, requirementResult)\n .map((o) => ({ ...o, id: uuid() }));\n\n // Store overrides on Action component to be able to remove when action is done\n updateComponent(Action, action.entity, { overrides: overrides.map((o) => `${o.id}/${o.component.id}`) });\n\n // Set all pending updates of this action\n for (const { component, value, entity, id } of overrides) {\n componentsWithOptimisticUpdates[component.id].addOverride(id, { entity, value });\n }\n\n try {\n // Execute the action\n const tx = await action.execute(requirementResult);\n\n // If the result includes a hash key (single tx) or hashes (multiple tx) key, wait for the transactions to complete before removing the pending actions\n if (tx) {\n // Wait for all tx events to be reduced\n updateComponent(Action, action.entity, { state: ActionState.WaitingForTxEvents, txHash: tx });\n await awaitStreamValue(txReduced$, (v) => v === tx);\n updateComponent(Action, action.entity, { state: ActionState.TxReduced });\n // TODO: extend ActionData type to be aware of whether waitForTransaction is set\n if (action.awaitConfirmation) {\n if (waitForTransaction) {\n await waitForTransaction(tx);\n } else {\n throw new Error(\"action has awaitConfirmation but no waitForTransaction specified in createActionSystem\");\n }\n }\n }\n\n updateComponent(Action, action.entity, { state: ActionState.Complete });\n } catch (e) {\n handleError(e, action);\n }\n\n // After the action is done executing (failed or completed), remove its actionData and remove the Action component\n remove(action.id);\n }\n\n // Set the action's state to ActionState.Failed\n function handleError(e: unknown, action: ActionData) {\n console.error(e);\n updateComponent(Action, action.entity, { state: ActionState.Failed });\n remove(action.id);\n }\n\n /**\n * Cancels the action with the given ID if it is in the \"Requested\" state.\n * @param actionId ID of the action to be cancelled\n * @returns void\n */\n function cancel(actionId: string): boolean {\n const action = actionData.get(actionId);\n if (!action || getComponentValue(Action, action.entity)?.state !== ActionState.Requested) {\n console.warn(`Action ${actionId} was not found or is not in the \"Requested\" state.`);\n return false;\n }\n updateComponent(Action, action.entity, { state: ActionState.Cancelled });\n remove(actionId);\n return true;\n }\n\n /**\n * Removes actionData disposer of the action with the given ID and removes its pending updates.\n * @param actionId ID of the action to be removed\n */\n function remove(actionId: string) {\n const action = actionData.get(actionId);\n if (!action) {\n console.warn(`Trying to remove action ${actionId} that does not exist.`);\n return;\n }\n\n // Remove this action's pending updates\n const actionEntity = actionId as Entity;\n const overrides = (actionEntity != null && getComponentValue(Action, actionEntity)?.overrides) || [];\n for (const override of overrides) {\n const [id, componentId] = override.split(\"/\");\n const component = componentsWithOptimisticUpdates[componentId];\n component.removeOverride(id);\n }\n\n // Remove this action's autorun and corresponding disposer\n disposer.get(actionId)?.dispose();\n disposer.delete(actionId);\n\n // Remove the action data\n actionData.delete(actionId);\n\n // Remove the action entity after some time\n actionEntity != null && setTimeout(() => world.deleteEntity(actionEntity), 5000);\n }\n\n return { add, cancel, withOptimisticUpdates, Action };\n}\n","import { defineComponent } from \"../Component\";\nimport { Type } from \"../constants\";\nimport { World, Component, SchemaOf, Metadata } from \"../types\";\n\nexport function defineActionComponent<T = unknown>(world: World) {\n const Action = defineComponent(\n world,\n {\n state: Type.String,\n on: Type.OptionalEntity,\n metadata: Type.OptionalT,\n overrides: Type.OptionalStringArray,\n txHash: Type.OptionalString,\n },\n { id: \"Action\" },\n );\n return Action as Component<SchemaOf<typeof Action>, Metadata, T>;\n}\n"],"mappings":"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","names":["ActionState","merge","mapObject","awaitStreamValue","uuid","defineActionComponent","world","defineComponent","createActionSystem","world","txReduced$","waitForTransaction","Action","defineActionComponent","componentsWithOptimisticUpdates","actionData","disposer","dispose","withOptimisticUpdates","component","optimisticComponent","overridableComponent","add","actionRequest","entity","createEntity","setComponent","action","mapObject","c","subscription","merge","checkRequirement","getComponentValue","requirementResult","executeAction","updateComponent","overrides","o","uuid","value","id","tx","awaitStreamValue","v","handleError","remove","e","cancel","actionId","actionEntity","override","componentId"]}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as W,b as v,c as te,d as ne,e as S,f as V,g as re,h as oe,i as ie,j as g,k as pe,l as ae,m as ye,n as C,o as ue,p as E,q as s,r as l,s as me,t as h,u as de,v as O,w as b,x as se,y as le,z as ce}from"./chunk-YDQFEK6R.js";import{concat as K,EMPTY as X,from as Z}from"rxjs";import{filterNullish as R}from"@latticexyz/utils";import{observable as B}from"mobx";import{concat as $,concatMap as q,filter as F,from as D,map as j,merge as L,of as z,share as Y}from"rxjs";var N=(o=>(o[o.Has=0]="Has",o[o.HasValue=1]="HasValue",o[o.Not=2]="Not",o[o.NotValue=3]="NotValue",o[o.ProxyRead=4]="ProxyRead",o[o.ProxyExpand=5]="ProxyExpand",o))(N||{});function xe(e){return[2,4,6,14,16,8,10,12].includes(e)}function Te(e){return[7,8,9,10,11,12,15,16].includes(e)}function Se(e){return[1,2].includes(e)}function ge(e){return[13,14].includes(e)}function Ye(e){return{type:0,component:e}}function Ge(e){return{type:2,component:e}}function Je(e,t){return{type:1,component:e,value:t}}function Ke(e,t){return{type:3,component:e,value:t}}function Xe(e,t){return{type:4,component:e,depth:t}}function Ze(e,t){return{type:5,component:e,depth:t}}function c(e,t){if(t.type===0)return s(t.component,e);if(t.type===1)return h(t.value,l(t.component,e));if(t.type===2)return!s(t.component,e);if(t.type===3)return!h(t.value,l(t.component,e));throw new Error("Unknown query fragment")}function G(e){return e.type===0||e.type==1}function P(e){return e.type===2||e.type==3}function J(e){return e.type===5||e.type==4}function U(e,t){return e&&G(t)||!e&&P(t)}function I(e,t,n){let r=e,a=!1;for(let y=0;y<n.depth;y++){let o=l(n.component,r);if(!o)return null;let p=o.value;if(!p)return null;if(r=p,a=c(r,t),U(a,t))return a}return a}function Q(e,t,n){if(n===0)return new Set;let r=O(t,{value:e});if(n===1)return r;let a=[...r].map(y=>[...Q(y,t,n-1)]).flat();return new Set([...r,...a])}function A(e,t){let n=t?new Set([...t]):void 0,r,a;for(let y=0;y<e.length;y++){let o=e[y];if(J(o))o.type===4&&(r=o),o.type===5&&(a=o);else if(n)for(let p of[...n]){let m=c(p,o);if(r&&r.depth>0&&!U(m,o)&&(m=I(p,o,r)??m),m||n.delete(p),a&&a.depth>0){let d=Q(p,a.component,a.depth);for(let i of d)(c(i,o)||r&&r.depth>0&&I(i,o,r))&&n.add(i)}}else{if(P(o))throw new Error("First EntityQueryFragment must be Has or HasValue");if(n=o.type===0?new Set([...b(o.component)]):O(o.component,o.value),a&&a.depth>0)for(let p of[...n])for(let m of Q(p,a.component,a.depth))n.add(m)}}return n??new Set}function f(e,t){let n=t?.runOnInit||t?.initialSet?A(e,t.initialSet):new Set,r=B(n),a=D(r).pipe(g(e[0].component)),y=e.findIndex(p=>[5,4].includes(p.type))!==-1,o=L(...e.map(p=>p.component.update$)).pipe(y?q(p=>{let m=A(e,t?.initialSet),d=[];for(let i of r)m.has(i)||(r.delete(i),d.push({entity:i,type:1,component:p.component,value:[void 0,void 0]}));for(let i of m)r.has(i)?d.push({entity:i,type:2,component:p.component,value:[l(p.component,i),void 0]}):(r.add(i),d.push({entity:i,type:0,component:p.component,value:[l(p.component,i),void 0]}));return z(...d)}):j(p=>{if(r.has(p.entity))return e.filter(u=>u.component.id===p.component.id).every(u=>c(p.entity,u))?{...p,type:2}:(r.delete(p.entity),{...p,type:1});if(e.every(d=>c(p.entity,d)))return r.add(p.entity),{...p,type:0}}),R());return{matching:r,update$:$(a,o).pipe(Y())}}function H(e,t){return f(e,t).update$.pipe(F(n=>n.type===2))}function w(e,t){return f(e,t).update$.pipe(F(n=>n.type===0))}function k(e,t){return f(e,t).update$.pipe(F(n=>n.type===1))}function x(e,t,n){let r=t.subscribe(n);e.registerDisposer(()=>r?.unsubscribe())}function pt(e,t,n,r={runOnInit:!0}){x(e,H(t,r),n)}function at(e,t,n,r={runOnInit:!0}){x(e,w(t,r),n)}function yt(e,t,n,r={runOnInit:!0}){x(e,k(t,r),n)}function _(e,t,n,r={runOnInit:!0}){x(e,f(t,r).update$,n)}function ut(e,t,n,r={runOnInit:!0}){let a=r?.runOnInit?Z(b(t)).pipe(g(t)):X;x(e,K(a,t.update$),n)}function mt(e,t,n,r,a={update:!1,runOnInit:!0}){_(e,t,({entity:y,type:o})=>{o===0&&C(n(y),y,r(y)),o===1&&E(n(y),y),a?.update&&o===2&&C(n(y),y,r(y))},a)}import{transformIterator as ee}from"@latticexyz/utils";function ft(){let e=new Set,t=[],n=[];function r({id:i,idSuffix:u}={}){let T=i||e.size+(u?"-"+u:""),M=S(T);return e.add(M),T}function a(){return ee(e.values(),V)}function y(i){t.push(i)}function o(i){for(let[,u]of n.filter(T=>!i||T[0]===i))u();n=n.filter(u=>i&&u[0]!==i)}function p(i,u=""){n.push([u,i])}function m(i){let u=S(i);return e.has(u)}function d(i){for(let u of t)s(u,i)&&E(u,i);e.delete(S(i))}return{registerEntity:r,components:t,registerComponent:y,dispose:o,registerDisposer:p,hasEntity:m,getEntities:a,entitySymbols:e,deleteEntity:d}}function xt(e,t){return{...e,registerDisposer:n=>e.registerDisposer(n,t),dispose:()=>e.dispose(t)}}function Tt(e,t){return e.components.filter(n=>s(n,t))}export{Ye as Has,Je as HasValue,Ge as Not,Ke as NotValue,te as OptionalTypes,Ze as ProxyExpand,Xe as ProxyRead,N as QueryFragmentType,W as Type,v as UpdateType,le as clearLocalCache,h as componentValueEquals,ne as createEntity,re as createIndexer,ce as createLocalCache,ft as createWorld,ye as defineComponent,ut as defineComponentSystem,w as defineEnterQuery,at as defineEnterSystem,k as defineExitQuery,yt as defineExitSystem,f as defineQuery,x as defineRxSystem,mt as defineSyncSystem,_ as defineSystem,H as defineUpdateQuery,pt as defineUpdateSystem,Q as getChildEntities,b as getComponentEntities,l as getComponentValue,me as getComponentValueStrict,O as getEntitiesWithValue,Tt as getEntityComponents,V as getEntityString,S as getEntitySymbol,s as hasComponent,Te as isArrayType,oe as isComponentUpdate,ge as isEntityType,ae as isFullComponentValue,pe as isIndexer,Se as isNumberType,xe as isOptionalType,xt as namespaceWorld,se as overridableComponent,E as removeComponent,A as runQuery,C as setComponent,ie as toUpdate,g as toUpdateStream,ue as updateComponent,de as withValue};
1
+ import{a as W,b as v,c as te,d as ne,e as g,f as V,g as re,h as oe,i as ie,j as S,k as pe,l as ae,m as ye,n as C,o as ue,p as E,q as s,r as l,s as me,t as h,u as de,v as O,w as b,x as se,y as le,z as ce}from"./chunk-X4WOMEVS.js";import{concat as K,EMPTY as X,from as Z}from"rxjs";import{filterNullish as R}from"@latticexyz/utils";import{observable as B}from"mobx";import{concat as $,concatMap as q,filter as F,from as D,map as j,merge as L,of as z,share as Y}from"rxjs";var N=(o=>(o[o.Has=0]="Has",o[o.HasValue=1]="HasValue",o[o.Not=2]="Not",o[o.NotValue=3]="NotValue",o[o.ProxyRead=4]="ProxyRead",o[o.ProxyExpand=5]="ProxyExpand",o))(N||{});function xe(e){return[2,4,6,14,16,8,10,12].includes(e)}function Te(e){return[7,8,9,10,11,12,15,16].includes(e)}function ge(e){return[1,2].includes(e)}function Se(e){return[13,14].includes(e)}function Le(e){return{type:0,component:e}}function ze(e){return{type:2,component:e}}function Ye(e,t){return{type:1,component:e,value:t}}function Ge(e,t){return{type:3,component:e,value:t}}function Je(e,t){return{type:4,component:e,depth:t}}function Ke(e,t){return{type:5,component:e,depth:t}}function c(e,t){if(t.type===0)return s(t.component,e);if(t.type===1)return h(t.value,l(t.component,e));if(t.type===2)return!s(t.component,e);if(t.type===3)return!h(t.value,l(t.component,e));throw new Error("Unknown query fragment")}function G(e){return e.type===0||e.type==1}function P(e){return e.type===2||e.type==3}function J(e){return e.type===5||e.type==4}function U(e,t){return e&&G(t)||!e&&P(t)}function I(e,t,n){let r=e,a=!1;for(let y=0;y<n.depth;y++){let o=l(n.component,r);if(!o)return null;let p=o.value;if(!p)return null;if(r=p,a=c(r,t),U(a,t))return a}return a}function Q(e,t,n){if(n===0)return new Set;let r=O(t,{value:e});if(n===1)return r;let a=[...r].map(y=>[...Q(y,t,n-1)]).flat();return new Set([...r,...a])}function A(e,t){let n=t?new Set([...t]):void 0,r,a;for(let y=0;y<e.length;y++){let o=e[y];if(J(o))o.type===4&&(r=o),o.type===5&&(a=o);else if(n)for(let p of[...n]){let m=c(p,o);if(r&&r.depth>0&&!U(m,o)&&(m=I(p,o,r)??m),m||n.delete(p),a&&a.depth>0){let d=Q(p,a.component,a.depth);for(let i of d)(c(i,o)||r&&r.depth>0&&I(i,o,r))&&n.add(i)}}else{if(P(o))throw new Error("First EntityQueryFragment must be Has or HasValue");if(n=o.type===0?new Set([...b(o.component)]):O(o.component,o.value),a&&a.depth>0)for(let p of[...n])for(let m of Q(p,a.component,a.depth))n.add(m)}}return n??new Set}function f(e,t){let n=t?.runOnInit||t?.initialSet?A(e,t.initialSet):new Set,r=B(n),a=D(r).pipe(S(e[0].component)),y=e.findIndex(p=>[5,4].includes(p.type))!==-1,o=L(...e.map(p=>p.component.update$)).pipe(y?q(p=>{let m=A(e,t?.initialSet),d=[];for(let i of r)m.has(i)||(r.delete(i),d.push({entity:i,type:1,component:p.component,value:[void 0,void 0]}));for(let i of m)r.has(i)?d.push({entity:i,type:2,component:p.component,value:[l(p.component,i),void 0]}):(r.add(i),d.push({entity:i,type:0,component:p.component,value:[l(p.component,i),void 0]}));return z(...d)}):j(p=>{if(r.has(p.entity))return e.filter(u=>u.component.id===p.component.id).every(u=>c(p.entity,u))?{...p,type:2}:(r.delete(p.entity),{...p,type:1});if(e.every(d=>c(p.entity,d)))return r.add(p.entity),{...p,type:0}}),R());return{matching:r,update$:$(a,o).pipe(Y())}}function H(e,t){return f(e,t).update$.pipe(F(n=>n.type===2))}function w(e,t){return f(e,t).update$.pipe(F(n=>n.type===0))}function k(e,t){return f(e,t).update$.pipe(F(n=>n.type===1))}function x(e,t,n){let r=t.subscribe(n);e.registerDisposer(()=>r?.unsubscribe())}function ot(e,t,n,r={runOnInit:!0}){x(e,H(t,r),n)}function it(e,t,n,r={runOnInit:!0}){x(e,w(t,r),n)}function pt(e,t,n,r={runOnInit:!0}){x(e,k(t,r),n)}function _(e,t,n,r={runOnInit:!0}){x(e,f(t,r).update$,n)}function at(e,t,n,r={runOnInit:!0}){let a=r?.runOnInit?Z(b(t)).pipe(S(t)):X;x(e,K(a,t.update$),n)}function yt(e,t,n,r,a={update:!1,runOnInit:!0}){_(e,t,({entity:y,type:o})=>{o===0&&C(n(y),y,r(y)),o===1&&E(n(y),y),a?.update&&o===2&&C(n(y),y,r(y))},a)}import{transformIterator as ee}from"@latticexyz/utils";function lt(){let e=new Set,t=[],n=[];function r({id:i,idSuffix:u}={}){let T=i||e.size+(u?"-"+u:""),M=g(T);return e.add(M),T}function a(){return ee(e.values(),V)}function y(i){t.push(i)}function o(i){for(let[,u]of n.filter(T=>!i||T[0]===i))u();n=n.filter(u=>i&&u[0]!==i)}function p(i,u=""){n.push([u,i])}function m(i){let u=g(i);return e.has(u)}function d(i){for(let u of t)s(u,i)&&E(u,i);e.delete(g(i))}return{registerEntity:r,components:t,registerComponent:y,dispose:o,registerDisposer:p,hasEntity:m,getEntities:a,entitySymbols:e,deleteEntity:d}}function ct(e,t){return{...e,registerDisposer:n=>e.registerDisposer(n,t),dispose:()=>e.dispose(t)}}function ft(e,t){return e.components.filter(n=>s(n,t))}export{Le as Has,Ye as HasValue,ze as Not,Ge as NotValue,te as OptionalTypes,Ke as ProxyExpand,Je as ProxyRead,N as QueryFragmentType,W as Type,v as UpdateType,le as clearLocalCache,h as componentValueEquals,ne as createEntity,re as createIndexer,ce as createLocalCache,lt as createWorld,ye as defineComponent,at as defineComponentSystem,w as defineEnterQuery,it as defineEnterSystem,k as defineExitQuery,pt as defineExitSystem,f as defineQuery,x as defineRxSystem,yt as defineSyncSystem,_ as defineSystem,H as defineUpdateQuery,ot as defineUpdateSystem,Q as getChildEntities,b as getComponentEntities,l as getComponentValue,me as getComponentValueStrict,O as getEntitiesWithValue,ft as getEntityComponents,V as getEntityString,g as getEntitySymbol,s as hasComponent,Te as isArrayType,oe as isComponentUpdate,Se as isEntityType,ae as isFullComponentValue,pe as isIndexer,ge as isNumberType,xe as isOptionalType,ct as namespaceWorld,se as overridableComponent,E as removeComponent,A as runQuery,C as setComponent,ie as toUpdate,S as toUpdateStream,ue as updateComponent,de as withValue};
2
2
  //# sourceMappingURL=index.js.map