@dcl/ecs 7.1.1-4387338275.commit-167a7e2 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { ISchema } from '../schemas';
2
+ import { ByteBuffer } from '../serialization/ByteBuffer';
2
3
  import { CrdtMessageBody, DeleteComponentMessageBody, PutComponentMessageBody } from '../serialization/crdt';
3
4
  import { Entity } from './entity';
4
5
  import { DeepReadonly, DeepReadonlySet } from './readonly';
@@ -38,6 +39,11 @@ export interface BaseComponent<T> {
38
39
  * @public
39
40
  */
40
41
  getCrdtUpdates(): Iterable<CrdtMessageBody>;
42
+ /**
43
+ * This function writes the whole state of the component into a ByteBuffer
44
+ * @public
45
+ */
46
+ dumpCrdtState(buffer: ByteBuffer): void;
41
47
  /**
42
48
  * @public
43
49
  * Marks the entity as deleted and signals it cannot be used ever again. It must
@@ -1,5 +1,5 @@
1
1
  import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
2
- import { CrdtMessageType } from '../serialization/crdt';
2
+ import { AppendValueOperation, CrdtMessageType } from '../serialization/crdt';
3
3
  import { __DEV__ } from '../runtime/invariant';
4
4
  const emptyReadonlySet = freezeSet(new Set());
5
5
  function frozenError() {
@@ -126,6 +126,15 @@ export function createValueSetComponentDefinitionFromSchema(componentName, compo
126
126
  append(_body.entityId, schema.deserialize(buf));
127
127
  }
128
128
  return [null, undefined];
129
+ },
130
+ dumpCrdtState: function (buffer) {
131
+ for (const [entity, { raw }] of data) {
132
+ for (const it of raw) {
133
+ const buf = new ReadWriteByteBuffer();
134
+ schema.serialize(it.value, buf);
135
+ AppendValueOperation.write(entity, 0, componentId, buf.toBinary(), buffer);
136
+ }
137
+ }
129
138
  }
130
139
  };
131
140
  return ret;
@@ -2,7 +2,14 @@ import { ByteBuffer } from '../serialization/ByteBuffer';
2
2
  import { OnChangeFunction } from '../systems/crdt';
3
3
  import { Entity } from './entity';
4
4
  import { SystemItem } from './systems';
5
+ import type { IEngine, IEngineOptions } from './types';
5
6
  export * from './input';
6
7
  export * from './readonly';
7
8
  export * from './types';
8
9
  export { Entity, ByteBuffer, SystemItem, OnChangeFunction };
10
+ /**
11
+ * Internal constructor of new engines, this is an internal API
12
+ * @public
13
+ * @deprecated Prevent manual usage prefer "engine" for scene development
14
+ */
15
+ export declare function Engine(options?: IEngineOptions): IEngine;
@@ -187,7 +187,9 @@ function preEngine() {
187
187
  };
188
188
  }
189
189
  /**
190
- * @internal
190
+ * Internal constructor of new engines, this is an internal API
191
+ * @public
192
+ * @deprecated Prevent manual usage prefer "engine" for scene development
191
193
  */
192
194
  export function Engine(options) {
193
195
  const partialEngine = preEngine();
@@ -1,6 +1,8 @@
1
1
  import { ISchema } from '../schemas';
2
+ import { ByteBuffer } from '../serialization/ByteBuffer';
2
3
  import { PutComponentMessageBody, DeleteComponentMessageBody, CrdtMessageBody } from '../serialization/crdt';
3
4
  import { Entity } from './entity';
4
5
  export declare function incrementTimestamp(entity: Entity, timestamps: Map<Entity, number>): number;
6
+ export declare function createDumpLwwFunctionFromCrdt(componentId: number, timestamps: Map<Entity, number>, schema: Pick<ISchema<any>, 'serialize' | 'deserialize'>, data: Map<Entity, unknown>): (buffer: ByteBuffer) => void;
5
7
  export declare function createUpdateLwwFromCrdt(componentId: number, timestamps: Map<Entity, number>, schema: Pick<ISchema<any>, 'serialize' | 'deserialize'>, data: Map<Entity, unknown>): (msg: CrdtMessageBody) => [null | PutComponentMessageBody | DeleteComponentMessageBody, any];
6
8
  export declare function createGetCrdtMessagesForLww(componentId: number, timestamps: Map<Entity, number>, dirtyIterator: Set<Entity>, schema: Pick<ISchema<any>, 'serialize'>, data: Map<Entity, unknown>): () => Generator<PutComponentMessageBody | DeleteComponentMessageBody, void, unknown>;
@@ -1,5 +1,5 @@
1
1
  import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
2
- import { ProcessMessageResultType, CrdtMessageType } from '../serialization/crdt';
2
+ import { ProcessMessageResultType, CrdtMessageType, PutComponentOperation, DeleteComponent } from '../serialization/crdt';
3
3
  import { dataCompare } from '../systems/crdt/utils';
4
4
  import { deepReadonly } from './readonly';
5
5
  export function incrementTimestamp(entity, timestamps) {
@@ -7,6 +7,22 @@ export function incrementTimestamp(entity, timestamps) {
7
7
  timestamps.set(entity, newTimestamp);
8
8
  return newTimestamp;
9
9
  }
10
+ export function createDumpLwwFunctionFromCrdt(componentId, timestamps, schema, data) {
11
+ return function dumpCrdtState(buffer) {
12
+ for (const [entity, timestamp] of timestamps) {
13
+ /* istanbul ignore else */
14
+ if (data.has(entity)) {
15
+ const it = data.get(entity);
16
+ const buf = new ReadWriteByteBuffer();
17
+ schema.serialize(it, buf);
18
+ PutComponentOperation.write(entity, timestamp, componentId, buf.toBinary(), buffer);
19
+ }
20
+ else {
21
+ DeleteComponent.write(entity, componentId, timestamp, buffer);
22
+ }
23
+ }
24
+ };
25
+ }
10
26
  export function createUpdateLwwFromCrdt(componentId, timestamps, schema, data) {
11
27
  /**
12
28
  * Process the received message only if the lamport number recieved is higher
@@ -224,6 +240,7 @@ export function createComponentDefinitionFromSchema(componentName, componentId,
224
240
  }
225
241
  },
226
242
  getCrdtUpdates: createGetCrdtMessagesForLww(componentId, timestamps, dirtyIterator, schema, data),
227
- updateFromCrdt: createUpdateLwwFromCrdt(componentId, timestamps, schema, data)
243
+ updateFromCrdt: createUpdateLwwFromCrdt(componentId, timestamps, schema, data),
244
+ dumpCrdtState: createDumpLwwFunctionFromCrdt(componentId, timestamps, schema, data)
228
245
  };
229
246
  }
@@ -1,5 +1,6 @@
1
1
  import type { ISchema } from '../schemas/ISchema';
2
2
  import { MapResult, Spec } from '../schemas/Map';
3
+ import { OnChangeFunction } from '../systems/crdt';
3
4
  import { Transport } from '../systems/crdt/types';
4
5
  import { ComponentDefinition, GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition } from './component';
5
6
  import { Entity, EntityState } from './entity';
@@ -32,6 +33,12 @@ export interface MapComponentDefinition<T> extends LastWriteWinElementSetCompone
32
33
  */
33
34
  createOrReplace(entity: Entity, val?: Partial<T>): T;
34
35
  }
36
+ /**
37
+ * @public
38
+ */
39
+ export interface IEngineOptions {
40
+ onChangeFunction: OnChangeFunction;
41
+ }
35
42
  /**
36
43
  * @public
37
44
  */
@@ -1 +1,15 @@
1
- export {};
1
+ import { Entity } from '../../engine/entity';
2
+ import { ByteBuffer } from '../ByteBuffer';
3
+ import { AppendValueMessage } from './types';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare namespace AppendValueOperation {
8
+ const MESSAGE_HEADER_LENGTH = 16;
9
+ /**
10
+ * Call this function for an optimal writing data passing the ByteBuffer
11
+ * already allocated
12
+ */
13
+ function write(entity: Entity, timestamp: number, componentId: number, data: Uint8Array, buf: ByteBuffer): void;
14
+ function read(buf: ByteBuffer): AppendValueMessage | null;
15
+ }
@@ -1,7 +1,7 @@
1
1
  import { CrdtMessageProtocol } from './crdtMessageProtocol';
2
2
  import { CrdtMessageType, CRDT_MESSAGE_HEADER_LENGTH } from './types';
3
3
  /**
4
- * @internal
4
+ * @public
5
5
  */
6
6
  export var AppendValueOperation;
7
7
  (function (AppendValueOperation) {
@@ -1 +1,30 @@
1
- export {};
1
+ import { ByteBuffer } from '../ByteBuffer';
2
+ import { CrdtMessageHeader } from './types';
3
+ /**
4
+ * @public
5
+ */
6
+ export declare namespace CrdtMessageProtocol {
7
+ /**
8
+ * Validate if the message incoming is completed
9
+ * @param buf - ByteBuffer
10
+ */
11
+ function validate(buf: ByteBuffer): boolean;
12
+ /**
13
+ * Get the current header, consuming the bytes involved.
14
+ * @param buf - ByteBuffer
15
+ * @returns header or null if there is no validated message
16
+ */
17
+ function readHeader(buf: ByteBuffer): CrdtMessageHeader | null;
18
+ /**
19
+ * Get the current header, without consuming the bytes involved.
20
+ * @param buf - ByteBuffer
21
+ * @returns header or null if there is no validated message
22
+ */
23
+ function getHeader(buf: ByteBuffer): CrdtMessageHeader | null;
24
+ /**
25
+ * Consume the incoming message without processing it.
26
+ * @param buf - ByteBuffer
27
+ * @returns true in case of success or false if there is no valid message.
28
+ */
29
+ function consumeMessage(buf: ByteBuffer): boolean;
30
+ }
@@ -1,6 +1,6 @@
1
1
  import { CRDT_MESSAGE_HEADER_LENGTH } from './types';
2
2
  /**
3
- * @internal
3
+ * @public
4
4
  */
5
5
  export var CrdtMessageProtocol;
6
6
  (function (CrdtMessageProtocol) {
@@ -1 +1,14 @@
1
- export {};
1
+ import { Entity } from '../../engine/entity';
2
+ import { ByteBuffer } from '../ByteBuffer';
3
+ import { DeleteComponentMessage } from './types';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare namespace DeleteComponent {
8
+ const MESSAGE_HEADER_LENGTH = 12;
9
+ /**
10
+ * Write DeleteComponent message
11
+ */
12
+ function write(entity: Entity, componentId: number, timestamp: number, buf: ByteBuffer): void;
13
+ function read(buf: ByteBuffer): DeleteComponentMessage | null;
14
+ }
@@ -1,7 +1,7 @@
1
1
  import { CrdtMessageProtocol } from './crdtMessageProtocol';
2
2
  import { CrdtMessageType, CRDT_MESSAGE_HEADER_LENGTH } from './types';
3
3
  /**
4
- * @internal
4
+ * @public
5
5
  */
6
6
  export var DeleteComponent;
7
7
  (function (DeleteComponent) {
@@ -1 +1,11 @@
1
- export {};
1
+ import { Entity } from '../../engine/entity';
2
+ import { ByteBuffer } from '../ByteBuffer';
3
+ import { DeleteEntityMessage } from './types';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare namespace DeleteEntity {
8
+ const MESSAGE_HEADER_LENGTH = 4;
9
+ function write(entity: Entity, buf: ByteBuffer): void;
10
+ function read(buf: ByteBuffer): DeleteEntityMessage | null;
11
+ }
@@ -1,7 +1,7 @@
1
1
  import { CrdtMessageProtocol } from './crdtMessageProtocol';
2
2
  import { CrdtMessageType, CRDT_MESSAGE_HEADER_LENGTH } from './types';
3
3
  /**
4
- * @internal
4
+ * @public
5
5
  */
6
6
  export var DeleteEntity;
7
7
  (function (DeleteEntity) {
@@ -1 +1,15 @@
1
- export {};
1
+ import { Entity } from '../../engine/entity';
2
+ import { ByteBuffer } from '../ByteBuffer';
3
+ import { PutComponentMessage } from './types';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare namespace PutComponentOperation {
8
+ const MESSAGE_HEADER_LENGTH = 16;
9
+ /**
10
+ * Call this function for an optimal writing data passing the ByteBuffer
11
+ * already allocated
12
+ */
13
+ function write(entity: Entity, timestamp: number, componentId: number, data: Uint8Array, buf: ByteBuffer): void;
14
+ function read(buf: ByteBuffer): PutComponentMessage | null;
15
+ }
@@ -1,7 +1,7 @@
1
1
  import { CrdtMessageProtocol } from './crdtMessageProtocol';
2
2
  import { CrdtMessageType, CRDT_MESSAGE_HEADER_LENGTH } from './types';
3
3
  /**
4
- * @internal
4
+ * @public
5
5
  */
6
6
  export var PutComponentOperation;
7
7
  (function (PutComponentOperation) {
@@ -103,6 +103,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
103
103
  engine.entityContainer.updateUsedEntity(msg.entityId);
104
104
  }
105
105
  const component = engine.getComponentOrNull(msg.componentId);
106
+ /* istanbul ignore else */
106
107
  if (component) {
107
108
  const [conflictMessage, value] = component.updateFromCrdt(msg);
108
109
  if (conflictMessage) {
@@ -124,6 +125,10 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
124
125
  onProcessEntityComponentChange && onProcessEntityComponentChange(msg.entityId, msg.type, component, value);
125
126
  }
126
127
  }
128
+ else {
129
+ // TODO: test this line, it is fundammental to make the editor work
130
+ broadcastMessages.push(msg);
131
+ }
127
132
  }
128
133
  }
129
134
  // the last stage of the syncrhonization is to delete the entities
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcl/ecs",
3
- "version": "7.1.1-4387338275.commit-167a7e2",
3
+ "version": "7.1.1",
4
4
  "description": "Decentraland ECS",
5
5
  "main": "./dist/index.js",
6
6
  "typings": "./dist/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "ts-proto": "^1.112.0"
28
28
  },
29
29
  "dependencies": {
30
- "@dcl/js-runtime": "7.1.1-4387338275.commit-167a7e2",
30
+ "@dcl/js-runtime": "7.1.1",
31
31
  "@dcl/protocol": "1.0.0-4177500465.commit-247c87f"
32
32
  },
33
33
  "files": [
@@ -40,5 +40,5 @@
40
40
  "displayName": "ECS",
41
41
  "tsconfig": "./tsconfig.json"
42
42
  },
43
- "commit": "167a7e2cdf2b8ba2832595085fadf48f9f6c5bed"
43
+ "commit": "d41e42b3708afee075cd36ec8ab5649b119f88ad"
44
44
  }