@dcl/ecs 7.0.6-4177592674.commit-39cdc99 → 7.0.6-4183962432.commit-2fbe270
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/extended/Animator.d.ts +3 -2
- package/dist/components/extended/Material.d.ts +2 -2
- package/dist/components/extended/MeshCollider.d.ts +2 -2
- package/dist/components/extended/MeshRenderer.d.ts +2 -2
- package/dist/components/generated/Animator.gen.js +6 -0
- package/dist/components/generated/AudioSource.gen.js +6 -0
- package/dist/components/generated/AudioStream.gen.js +6 -0
- package/dist/components/generated/AvatarAttach.gen.js +6 -0
- package/dist/components/generated/AvatarModifierArea.gen.js +6 -0
- package/dist/components/generated/AvatarShape.gen.js +6 -0
- package/dist/components/generated/Billboard.gen.js +6 -0
- package/dist/components/generated/CameraMode.gen.js +6 -0
- package/dist/components/generated/CameraModeArea.gen.js +6 -0
- package/dist/components/generated/GltfContainer.gen.js +6 -0
- package/dist/components/generated/Material.gen.js +6 -0
- package/dist/components/generated/MeshCollider.gen.js +6 -0
- package/dist/components/generated/MeshRenderer.gen.js +6 -0
- package/dist/components/generated/NftShape.gen.js +6 -0
- package/dist/components/generated/PointerEvents.gen.js +6 -0
- package/dist/components/generated/PointerEventsResult.gen.js +6 -0
- package/dist/components/generated/PointerLock.gen.js +6 -0
- package/dist/components/generated/Raycast.gen.js +6 -0
- package/dist/components/generated/RaycastResult.gen.js +6 -0
- package/dist/components/generated/TextShape.gen.js +6 -0
- package/dist/components/generated/UiBackground.gen.js +6 -0
- package/dist/components/generated/UiDropdown.gen.js +6 -0
- package/dist/components/generated/UiDropdownResult.gen.js +6 -0
- package/dist/components/generated/UiInput.gen.js +6 -0
- package/dist/components/generated/UiInputResult.gen.js +6 -0
- package/dist/components/generated/UiText.gen.js +6 -0
- package/dist/components/generated/UiTransform.gen.js +6 -0
- package/dist/components/generated/VideoPlayer.gen.js +6 -0
- package/dist/components/generated/VisibilityComponent.gen.js +6 -0
- package/dist/components/generated/global.gen.d.ts +26 -26
- package/dist/components/generated/index.gen.d.ts +32 -31
- package/dist/components/generated/index.gen.js +4 -1
- package/dist/components/generated/pb/decentraland/sdk/components/pointer_events_result.gen.d.ts +1 -9
- package/dist/components/generated/pb/decentraland/sdk/components/pointer_events_result.gen.js +2 -36
- package/dist/components/index.d.ts +9 -9
- package/dist/components/index.js +1 -1
- package/dist/components/{legacy → manual}/Transform.d.ts +2 -2
- package/dist/components/{legacy → manual}/Transform.js +32 -0
- package/dist/components/types.d.ts +1 -1
- package/dist/engine/component.d.ts +74 -27
- package/dist/engine/component.js +7 -240
- package/dist/engine/grow-only-value-set-component-definition.d.ts +8 -0
- package/dist/engine/grow-only-value-set-component-definition.js +132 -0
- package/dist/engine/index.d.ts +1 -2
- package/dist/engine/index.js +18 -1
- package/dist/engine/input.d.ts +3 -3
- package/dist/engine/input.js +75 -68
- package/dist/engine/lww-element-set-component-definition.d.ts +6 -0
- package/dist/engine/lww-element-set-component-definition.js +229 -0
- package/dist/engine/readonly.d.ts +2 -2
- package/dist/engine/types.d.ts +20 -9
- package/dist/engine/types.js +1 -1
- package/dist/runtime/invariant.d.ts +1 -0
- package/dist/runtime/invariant.js +6 -1
- package/dist/runtime/types.d.ts +1 -2
- package/dist/runtime/types.js +0 -1
- package/dist/schemas/Array.js +5 -0
- package/dist/schemas/ISchema.d.ts +27 -2
- package/dist/schemas/Map.d.ts +0 -1
- package/dist/schemas/Map.js +9 -0
- package/dist/schemas/Optional.js +5 -0
- package/dist/schemas/basic/Boolean.js +4 -0
- package/dist/schemas/basic/Enum.js +27 -0
- package/dist/schemas/basic/Float.js +8 -0
- package/dist/schemas/basic/Integer.js +16 -0
- package/dist/schemas/basic/String.js +4 -0
- package/dist/schemas/buildSchema.d.ts +7 -0
- package/dist/schemas/buildSchema.js +63 -0
- package/dist/schemas/custom/Color3.js +9 -0
- package/dist/schemas/custom/Color4.js +10 -0
- package/dist/schemas/custom/Entity.js +4 -0
- package/dist/schemas/custom/Quaternion.js +10 -0
- package/dist/schemas/custom/Vector3.js +10 -0
- package/dist/schemas/index.d.ts +2 -2
- package/dist/serialization/crdt/appendValue.d.ts +1 -0
- package/dist/serialization/crdt/appendValue.js +49 -0
- package/dist/serialization/crdt/index.d.ts +1 -0
- package/dist/serialization/crdt/index.js +1 -0
- package/dist/serialization/crdt/message.js +4 -0
- package/dist/serialization/crdt/types.d.ts +24 -3
- package/dist/serialization/crdt/types.js +2 -1
- package/dist/systems/crdt/index.d.ts +1 -1
- package/dist/systems/crdt/index.js +21 -8
- package/dist/systems/events.d.ts +2 -2
- package/package.json +3 -3
package/dist/components/generated/pb/decentraland/sdk/components/pointer_events_result.gen.js
CHANGED
|
@@ -3,40 +3,6 @@ import _m0 from "protobufjs/minimal";
|
|
|
3
3
|
import { RaycastHit } from "./raycast_result.gen";
|
|
4
4
|
const protobufPackageSarasa = "decentraland.sdk.components";
|
|
5
5
|
function createBasePBPointerEventsResult() {
|
|
6
|
-
return { commands: [] };
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
export const PBPointerEventsResult = {
|
|
15
|
-
encode(message, writer = _m0.Writer.create()) {
|
|
16
|
-
for (const v of message.commands) {
|
|
17
|
-
PBPointerEventsResult_PointerCommand.encode(v, writer.uint32(10).fork()).ldelim();
|
|
18
|
-
}
|
|
19
|
-
return writer;
|
|
20
|
-
},
|
|
21
|
-
decode(input, length) {
|
|
22
|
-
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
23
|
-
let end = length === undefined ? reader.len : reader.pos + length;
|
|
24
|
-
const message = createBasePBPointerEventsResult();
|
|
25
|
-
while (reader.pos < end) {
|
|
26
|
-
const tag = reader.uint32();
|
|
27
|
-
switch (tag >>> 3) {
|
|
28
|
-
case 1:
|
|
29
|
-
message.commands.push(PBPointerEventsResult_PointerCommand.decode(reader, reader.uint32()));
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
reader.skipType(tag & 7);
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return message;
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
function createBasePBPointerEventsResult_PointerCommand() {
|
|
40
6
|
return { button: 0, hit: undefined, state: 0, timestamp: 0, analog: undefined };
|
|
41
7
|
}
|
|
42
8
|
/**
|
|
@@ -45,7 +11,7 @@ function createBasePBPointerEventsResult_PointerCommand() {
|
|
|
45
11
|
/**
|
|
46
12
|
* @internal
|
|
47
13
|
*/
|
|
48
|
-
export const
|
|
14
|
+
export const PBPointerEventsResult = {
|
|
49
15
|
encode(message, writer = _m0.Writer.create()) {
|
|
50
16
|
if (message.button !== 0) {
|
|
51
17
|
writer.uint32(8).int32(message.button);
|
|
@@ -67,7 +33,7 @@ export const PBPointerEventsResult_PointerCommand = {
|
|
|
67
33
|
decode(input, length) {
|
|
68
34
|
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
69
35
|
let end = length === undefined ? reader.len : reader.pos + length;
|
|
70
|
-
const message =
|
|
36
|
+
const message = createBasePBPointerEventsResult();
|
|
71
37
|
while (reader.pos < end) {
|
|
72
38
|
const tag = reader.uint32();
|
|
73
39
|
switch (tag >>> 3) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition } from '../engine/component';
|
|
2
2
|
import { AnimatorComponentDefinitionExtended } from './extended/Animator';
|
|
3
3
|
import { MaterialComponentDefinitionExtended } from './extended/Material';
|
|
4
4
|
import { MeshColliderComponentDefinitionExtended } from './extended/MeshCollider';
|
|
5
5
|
import { MeshRendererComponentDefinitionExtended } from './extended/MeshRenderer';
|
|
6
|
-
import {
|
|
7
|
-
import { TransformComponentExtended } from './
|
|
6
|
+
import { LwwComponentGetter, GSetComponentGetter } from './generated/index.gen';
|
|
7
|
+
import { TransformComponentExtended } from './manual/Transform';
|
|
8
8
|
export * from './generated/index.gen';
|
|
9
|
-
export type {
|
|
10
|
-
export declare const Transform:
|
|
11
|
-
export declare const Material:
|
|
12
|
-
export declare const Animator:
|
|
13
|
-
export declare const MeshRenderer:
|
|
14
|
-
export declare const MeshCollider:
|
|
9
|
+
export type { GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition, LwwComponentGetter, GSetComponentGetter };
|
|
10
|
+
export declare const Transform: LwwComponentGetter<TransformComponentExtended>;
|
|
11
|
+
export declare const Material: LwwComponentGetter<MaterialComponentDefinitionExtended>;
|
|
12
|
+
export declare const Animator: LwwComponentGetter<AnimatorComponentDefinitionExtended>;
|
|
13
|
+
export declare const MeshRenderer: LwwComponentGetter<MeshRendererComponentDefinitionExtended>;
|
|
14
|
+
export declare const MeshCollider: LwwComponentGetter<MeshColliderComponentDefinitionExtended>;
|
package/dist/components/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { defineAnimatorComponent } from './extended/Animator';
|
|
|
2
2
|
import { defineMaterialComponent } from './extended/Material';
|
|
3
3
|
import { defineMeshColliderComponent } from './extended/MeshCollider';
|
|
4
4
|
import { defineMeshRendererComponent } from './extended/MeshRenderer';
|
|
5
|
-
import { defineTransformComponent } from './
|
|
5
|
+
import { defineTransformComponent } from './manual/Transform';
|
|
6
6
|
export * from './generated/index.gen';
|
|
7
7
|
/*#__PURE__*/
|
|
8
8
|
export const Transform = (engine) => defineTransformComponent(engine);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LastWriteWinElementSetComponentDefinition, IEngine } from '../../engine';
|
|
2
2
|
import { Entity } from '../../engine/entity';
|
|
3
3
|
/**
|
|
4
4
|
* @public
|
|
5
5
|
*/
|
|
6
|
-
export type TransformComponent =
|
|
6
|
+
export type TransformComponent = LastWriteWinElementSetComponentDefinition<TransformType>;
|
|
7
7
|
/**
|
|
8
8
|
* @public
|
|
9
9
|
*/
|
|
@@ -58,6 +58,38 @@ export const TransformSchema = {
|
|
|
58
58
|
parent: 0,
|
|
59
59
|
...value
|
|
60
60
|
};
|
|
61
|
+
},
|
|
62
|
+
jsonSchema: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
position: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {
|
|
68
|
+
x: { type: 'number' },
|
|
69
|
+
y: { type: 'number' },
|
|
70
|
+
z: { type: 'number' }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
scale: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
x: { type: 'number' },
|
|
77
|
+
y: { type: 'number' },
|
|
78
|
+
z: { type: 'number' }
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
rotation: {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
x: { type: 'number' },
|
|
85
|
+
y: { type: 'number' },
|
|
86
|
+
z: { type: 'number' },
|
|
87
|
+
w: { type: 'number' }
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
parent: { type: 'integer' }
|
|
91
|
+
},
|
|
92
|
+
serializationType: 'transform'
|
|
61
93
|
}
|
|
62
94
|
};
|
|
63
95
|
export function defineTransformComponent(engine) {
|
|
@@ -2,4 +2,4 @@ export type { AnimatorComponentDefinitionExtended } from './extended/Animator';
|
|
|
2
2
|
export type { MeshRendererComponentDefinitionExtended } from './extended/MeshRenderer';
|
|
3
3
|
export type { MeshColliderComponentDefinitionExtended } from './extended/MeshCollider';
|
|
4
4
|
export type { TextureHelper, MaterialComponentDefinitionExtended } from './extended/Material';
|
|
5
|
-
export type { TransformComponentExtended, TransformTypeWithOptionals } from './
|
|
5
|
+
export type { TransformComponentExtended, TransformTypeWithOptionals } from './manual/Transform';
|
|
@@ -1,24 +1,72 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ISchema } from '../schemas';
|
|
2
2
|
import { CrdtMessageBody, DeleteComponentMessageBody, PutComponentMessageBody } from '../serialization/crdt';
|
|
3
3
|
import { Entity } from './entity';
|
|
4
|
-
import { DeepReadonly } from './readonly';
|
|
4
|
+
import { DeepReadonly, DeepReadonlySet } from './readonly';
|
|
5
5
|
/**
|
|
6
|
+
* Component types are used to pick the wire protocol and the conflict resolution algorithm
|
|
6
7
|
* @public
|
|
7
8
|
*/
|
|
8
|
-
export
|
|
9
|
+
export declare const enum ComponentType {
|
|
10
|
+
LastWriteWinElementSet = 0,
|
|
11
|
+
GrowOnlyValueSet = 1
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A conflict resolution message is the response to an outdated or invalid state
|
|
15
|
+
* in the CRDT.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export type ConflictResolutionMessage = PutComponentMessageBody | DeleteComponentMessageBody;
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export interface BaseComponent<T> {
|
|
9
23
|
readonly componentId: number;
|
|
10
24
|
readonly componentName: string;
|
|
25
|
+
readonly componentType: ComponentType;
|
|
26
|
+
readonly schema: ISchema<T>;
|
|
27
|
+
/**
|
|
28
|
+
* This function receives a CRDT update and returns a touple with a "conflict
|
|
29
|
+
* resoluton" message, in case of the sender being updated or null in case of noop/accepted
|
|
30
|
+
* change. The second element of the touple is the modified/changed/deleted value.
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
updateFromCrdt(body: CrdtMessageBody): [null | ConflictResolutionMessage, T | undefined];
|
|
34
|
+
/**
|
|
35
|
+
* This function returns an iterable with all the CRDT updates that need to be
|
|
36
|
+
* broadcasted to other actors in the system. After returning, this function
|
|
37
|
+
* clears the internal dirty state. Updates are produced only once.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
getCrdtUpdates(): Iterable<CrdtMessageBody>;
|
|
11
41
|
/**
|
|
12
|
-
*
|
|
42
|
+
* @public
|
|
43
|
+
* Marks the entity as deleted and signals it cannot be used ever again. It must
|
|
44
|
+
* clear the component internal state, produces a synchronization message to remove
|
|
45
|
+
* the component from the entity.
|
|
46
|
+
* @param entity - Entity ID that was deleted.
|
|
13
47
|
*/
|
|
14
|
-
|
|
48
|
+
entityDeleted(entity: Entity, markAsDirty: boolean): void;
|
|
15
49
|
/**
|
|
16
50
|
* Get if the entity has this component
|
|
17
51
|
* @param entity - entity to test
|
|
18
52
|
*/
|
|
19
53
|
has(entity: Entity): boolean;
|
|
20
54
|
/**
|
|
21
|
-
* Get the readonly component of the entity (to mutate it, use getMutable instead),
|
|
55
|
+
* Get the readonly component of the entity (to mutate it, use getMutable instead),
|
|
56
|
+
* throws an error if the entity doesn't have the component.
|
|
57
|
+
* @param entity - Entity that will be used to get the component
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
get(entity: Entity): any;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export interface LastWriteWinElementSetComponentDefinition<T> extends BaseComponent<T> {
|
|
66
|
+
readonly componentType: ComponentType.LastWriteWinElementSet;
|
|
67
|
+
/**
|
|
68
|
+
* Get the readonly component of the entity (to mutate it, use getMutable instead),
|
|
69
|
+
* throws an error if the entity doesn't have the component.
|
|
22
70
|
* @param entity - Entity that will be used to get the component
|
|
23
71
|
* @returns
|
|
24
72
|
*/
|
|
@@ -49,14 +97,6 @@ export interface ComponentDefinition<T> {
|
|
|
49
97
|
* @param entity - Entity to delete the component from
|
|
50
98
|
*/
|
|
51
99
|
deleteFrom(entity: Entity): T | null;
|
|
52
|
-
/**
|
|
53
|
-
* @public
|
|
54
|
-
* Marks the entity as deleted and signals it cannot be used ever again. It must
|
|
55
|
-
* clear the component internal state, produces a synchronization message to remove
|
|
56
|
-
* the component from the entity.
|
|
57
|
-
* @param entity - Entity to delete the component from
|
|
58
|
-
*/
|
|
59
|
-
entityDeleted(entity: Entity, markAsDirty: boolean): void;
|
|
60
100
|
/**
|
|
61
101
|
* Get the mutable component of the entity, throw an error if the entity doesn't have the component.
|
|
62
102
|
* - Internal comment: This method adds the <entity,component> to the list to be reviewed next frame
|
|
@@ -69,21 +109,28 @@ export interface ComponentDefinition<T> {
|
|
|
69
109
|
* @param entity - Entity to get the component from
|
|
70
110
|
*/
|
|
71
111
|
getMutableOrNull(entity: Entity): T | null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
export interface GrowOnlyValueSetComponentDefinition<T> extends BaseComponent<T> {
|
|
117
|
+
readonly componentType: ComponentType.GrowOnlyValueSet;
|
|
72
118
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
119
|
+
* Appends an element to the set.
|
|
120
|
+
* @param entity - Entity that will host the value
|
|
121
|
+
* @param val - The final value. The Set will freeze the value, it won't be editable from
|
|
122
|
+
* the script.
|
|
77
123
|
*/
|
|
78
|
-
|
|
124
|
+
addValue(entity: Entity, val: DeepReadonly<T>): DeepReadonlySet<T>;
|
|
79
125
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* @
|
|
126
|
+
* Get the readonly component of the entity (to mutate it, use getMutable instead),
|
|
127
|
+
* throws an error if the entity doesn't have the component.
|
|
128
|
+
* @param entity - Entity that will be used to get the component
|
|
129
|
+
* @returns
|
|
84
130
|
*/
|
|
85
|
-
|
|
131
|
+
get(entity: Entity): DeepReadonlySet<T>;
|
|
86
132
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
133
|
+
/**
|
|
134
|
+
* @public
|
|
135
|
+
*/
|
|
136
|
+
export type ComponentDefinition<T> = LastWriteWinElementSetComponentDefinition<T> | GrowOnlyValueSetComponentDefinition<T>;
|
package/dist/engine/component.js
CHANGED
|
@@ -1,242 +1,9 @@
|
|
|
1
|
-
import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
|
|
2
|
-
import { CrdtMessageType, ProcessMessageResultType } from '../serialization/crdt';
|
|
3
|
-
import { dataCompare } from '../systems/crdt/utils';
|
|
4
|
-
import { deepReadonly } from './readonly';
|
|
5
|
-
export function incrementTimestamp(entity, timestamps) {
|
|
6
|
-
const newTimestamp = (timestamps.get(entity) || 0) + 1;
|
|
7
|
-
timestamps.set(entity, newTimestamp);
|
|
8
|
-
return newTimestamp;
|
|
9
|
-
}
|
|
10
|
-
export function createUpdateFromCrdt(componentId, timestamps, schema, data) {
|
|
11
|
-
/**
|
|
12
|
-
* Process the received message only if the lamport number recieved is higher
|
|
13
|
-
* than the stored one. If its lower, we spread it to the network to correct the peer.
|
|
14
|
-
* If they are equal, the bigger raw data wins.
|
|
15
|
-
|
|
16
|
-
* Returns the recieved data if the lamport number was bigger than ours.
|
|
17
|
-
* If it was an outdated message, then we return void
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
function crdtRuleForCurrentState(message) {
|
|
21
|
-
const { entityId, timestamp } = message;
|
|
22
|
-
const currentTimestamp = timestamps.get(entityId);
|
|
23
|
-
// The received message is > than our current value, update our state.components.
|
|
24
|
-
if (currentTimestamp === undefined || currentTimestamp < timestamp) {
|
|
25
|
-
return ProcessMessageResultType.StateUpdatedTimestamp;
|
|
26
|
-
}
|
|
27
|
-
// Outdated Message. Resend our state message through the wire.
|
|
28
|
-
if (currentTimestamp > timestamp) {
|
|
29
|
-
// console.log('2', currentTimestamp, timestamp)
|
|
30
|
-
return ProcessMessageResultType.StateOutdatedTimestamp;
|
|
31
|
-
}
|
|
32
|
-
// Deletes are idempotent
|
|
33
|
-
if (message.type === CrdtMessageType.DELETE_COMPONENT && !data.has(entityId)) {
|
|
34
|
-
return ProcessMessageResultType.NoChanges;
|
|
35
|
-
}
|
|
36
|
-
let currentDataGreater = 0;
|
|
37
|
-
if (data.has(entityId)) {
|
|
38
|
-
const writeBuffer = new ReadWriteByteBuffer();
|
|
39
|
-
schema.serialize(data.get(entityId), writeBuffer);
|
|
40
|
-
currentDataGreater = dataCompare(writeBuffer.toBinary(), message.data || null);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
currentDataGreater = dataCompare(null, message.data);
|
|
44
|
-
}
|
|
45
|
-
// Same data, same timestamp. Weirdo echo message.
|
|
46
|
-
// console.log('3', currentDataGreater, writeBuffer.toBinary(), (message as any).data || null)
|
|
47
|
-
if (currentDataGreater === 0) {
|
|
48
|
-
return ProcessMessageResultType.NoChanges;
|
|
49
|
-
}
|
|
50
|
-
else if (currentDataGreater > 0) {
|
|
51
|
-
// Current data is greater
|
|
52
|
-
return ProcessMessageResultType.StateOutdatedData;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// Curent data is lower
|
|
56
|
-
return ProcessMessageResultType.StateUpdatedData;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return (msg) => {
|
|
60
|
-
/* istanbul ignore next */
|
|
61
|
-
if (msg.type !== CrdtMessageType.PUT_COMPONENT && msg.type !== CrdtMessageType.DELETE_COMPONENT)
|
|
62
|
-
/* istanbul ignore next */
|
|
63
|
-
return [null, data.get(msg.entityId)];
|
|
64
|
-
const action = crdtRuleForCurrentState(msg);
|
|
65
|
-
const entity = msg.entityId;
|
|
66
|
-
switch (action) {
|
|
67
|
-
case ProcessMessageResultType.StateUpdatedData:
|
|
68
|
-
case ProcessMessageResultType.StateUpdatedTimestamp: {
|
|
69
|
-
timestamps.set(entity, msg.timestamp);
|
|
70
|
-
if (msg.type === CrdtMessageType.PUT_COMPONENT) {
|
|
71
|
-
const buf = new ReadWriteByteBuffer(msg.data);
|
|
72
|
-
data.set(entity, schema.deserialize(buf));
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
data.delete(entity);
|
|
76
|
-
}
|
|
77
|
-
return [null, data.get(entity)];
|
|
78
|
-
}
|
|
79
|
-
case ProcessMessageResultType.StateOutdatedTimestamp:
|
|
80
|
-
case ProcessMessageResultType.StateOutdatedData: {
|
|
81
|
-
if (data.has(entity)) {
|
|
82
|
-
const writeBuffer = new ReadWriteByteBuffer();
|
|
83
|
-
schema.serialize(data.get(entity), writeBuffer);
|
|
84
|
-
return [
|
|
85
|
-
{
|
|
86
|
-
type: CrdtMessageType.PUT_COMPONENT,
|
|
87
|
-
componentId,
|
|
88
|
-
data: writeBuffer.toBinary(),
|
|
89
|
-
entityId: entity,
|
|
90
|
-
timestamp: timestamps.get(entity)
|
|
91
|
-
},
|
|
92
|
-
data.get(entity)
|
|
93
|
-
];
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
return [
|
|
97
|
-
{
|
|
98
|
-
type: CrdtMessageType.DELETE_COMPONENT,
|
|
99
|
-
componentId,
|
|
100
|
-
entityId: entity,
|
|
101
|
-
timestamp: timestamps.get(entity)
|
|
102
|
-
},
|
|
103
|
-
undefined
|
|
104
|
-
];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return [null, data.get(entity)];
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
export function createGetCrdtMessages(componentId, timestamps, dirtyIterator, schema, data) {
|
|
112
|
-
return function* () {
|
|
113
|
-
for (const entity of dirtyIterator) {
|
|
114
|
-
const newTimestamp = incrementTimestamp(entity, timestamps);
|
|
115
|
-
if (data.has(entity)) {
|
|
116
|
-
const writeBuffer = new ReadWriteByteBuffer();
|
|
117
|
-
schema.serialize(data.get(entity), writeBuffer);
|
|
118
|
-
const msg = {
|
|
119
|
-
type: CrdtMessageType.PUT_COMPONENT,
|
|
120
|
-
componentId,
|
|
121
|
-
entityId: entity,
|
|
122
|
-
data: writeBuffer.toBinary(),
|
|
123
|
-
timestamp: newTimestamp
|
|
124
|
-
};
|
|
125
|
-
yield msg;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
const msg = {
|
|
129
|
-
type: CrdtMessageType.DELETE_COMPONENT,
|
|
130
|
-
componentId,
|
|
131
|
-
entityId: entity,
|
|
132
|
-
timestamp: newTimestamp
|
|
133
|
-
};
|
|
134
|
-
yield msg;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
dirtyIterator.clear();
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
1
|
/**
|
|
141
|
-
*
|
|
2
|
+
* Component types are used to pick the wire protocol and the conflict resolution algorithm
|
|
3
|
+
* @public
|
|
142
4
|
*/
|
|
143
|
-
export
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
get componentId() {
|
|
149
|
-
return componentId;
|
|
150
|
-
},
|
|
151
|
-
get componentName() {
|
|
152
|
-
return componentName;
|
|
153
|
-
},
|
|
154
|
-
default() {
|
|
155
|
-
return schema.create();
|
|
156
|
-
},
|
|
157
|
-
isDirty(entity) {
|
|
158
|
-
return dirtyIterator.has(entity);
|
|
159
|
-
},
|
|
160
|
-
has(entity) {
|
|
161
|
-
return data.has(entity);
|
|
162
|
-
},
|
|
163
|
-
deleteFrom(entity, markAsDirty = true) {
|
|
164
|
-
const component = data.get(entity);
|
|
165
|
-
if (data.delete(entity) && markAsDirty) {
|
|
166
|
-
dirtyIterator.add(entity);
|
|
167
|
-
}
|
|
168
|
-
return component || null;
|
|
169
|
-
},
|
|
170
|
-
entityDeleted(entity, markAsDirty) {
|
|
171
|
-
if (data.delete(entity) && markAsDirty) {
|
|
172
|
-
dirtyIterator.add(entity);
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
getOrNull(entity) {
|
|
176
|
-
const component = data.get(entity);
|
|
177
|
-
return component ? deepReadonly(component) : null;
|
|
178
|
-
},
|
|
179
|
-
get(entity) {
|
|
180
|
-
const component = data.get(entity);
|
|
181
|
-
if (!component) {
|
|
182
|
-
throw new Error(`[getFrom] Component ${componentName} for entity #${entity} not found`);
|
|
183
|
-
}
|
|
184
|
-
return deepReadonly(component);
|
|
185
|
-
},
|
|
186
|
-
create(entity, value) {
|
|
187
|
-
const component = data.get(entity);
|
|
188
|
-
if (component) {
|
|
189
|
-
throw new Error(`[create] Component ${componentName} for ${entity} already exists`);
|
|
190
|
-
}
|
|
191
|
-
const usedValue = value === undefined ? schema.create() : schema.extend ? schema.extend(value) : value;
|
|
192
|
-
data.set(entity, usedValue);
|
|
193
|
-
dirtyIterator.add(entity);
|
|
194
|
-
return usedValue;
|
|
195
|
-
},
|
|
196
|
-
createOrReplace(entity, value) {
|
|
197
|
-
const usedValue = value === undefined ? schema.create() : schema.extend ? schema.extend(value) : value;
|
|
198
|
-
data.set(entity, usedValue);
|
|
199
|
-
dirtyIterator.add(entity);
|
|
200
|
-
return usedValue;
|
|
201
|
-
},
|
|
202
|
-
getMutableOrNull(entity) {
|
|
203
|
-
const component = data.get(entity);
|
|
204
|
-
if (!component) {
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
dirtyIterator.add(entity);
|
|
208
|
-
return component;
|
|
209
|
-
},
|
|
210
|
-
getMutable(entity) {
|
|
211
|
-
const component = this.getMutableOrNull(entity);
|
|
212
|
-
if (component === null) {
|
|
213
|
-
throw new Error(`[mutable] Component ${componentName} for ${entity} not found`);
|
|
214
|
-
}
|
|
215
|
-
return component;
|
|
216
|
-
},
|
|
217
|
-
*iterator() {
|
|
218
|
-
for (const [entity, component] of data) {
|
|
219
|
-
yield [entity, component];
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
*dirtyIterator() {
|
|
223
|
-
for (const entity of dirtyIterator) {
|
|
224
|
-
yield entity;
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
getCrdtUpdates: createGetCrdtMessages(componentId, timestamps, dirtyIterator, schema, data),
|
|
228
|
-
toBinary(entity) {
|
|
229
|
-
const component = data.get(entity);
|
|
230
|
-
if (!component) {
|
|
231
|
-
throw new Error(`[toBinary] Component ${componentName} for ${entity} not found`);
|
|
232
|
-
}
|
|
233
|
-
const writeBuffer = new ReadWriteByteBuffer();
|
|
234
|
-
schema.serialize(component, writeBuffer);
|
|
235
|
-
return writeBuffer;
|
|
236
|
-
},
|
|
237
|
-
updateFromCrdt: createUpdateFromCrdt(componentId, timestamps, schema, data),
|
|
238
|
-
deserialize(buffer) {
|
|
239
|
-
return schema.deserialize(buffer);
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
}
|
|
5
|
+
export var ComponentType;
|
|
6
|
+
(function (ComponentType) {
|
|
7
|
+
ComponentType[ComponentType["LastWriteWinElementSet"] = 0] = "LastWriteWinElementSet";
|
|
8
|
+
ComponentType[ComponentType["GrowOnlyValueSet"] = 1] = "GrowOnlyValueSet";
|
|
9
|
+
})(ComponentType || (ComponentType = {}));
|