@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.
Files changed (89) hide show
  1. package/dist/components/extended/Animator.d.ts +3 -2
  2. package/dist/components/extended/Material.d.ts +2 -2
  3. package/dist/components/extended/MeshCollider.d.ts +2 -2
  4. package/dist/components/extended/MeshRenderer.d.ts +2 -2
  5. package/dist/components/generated/Animator.gen.js +6 -0
  6. package/dist/components/generated/AudioSource.gen.js +6 -0
  7. package/dist/components/generated/AudioStream.gen.js +6 -0
  8. package/dist/components/generated/AvatarAttach.gen.js +6 -0
  9. package/dist/components/generated/AvatarModifierArea.gen.js +6 -0
  10. package/dist/components/generated/AvatarShape.gen.js +6 -0
  11. package/dist/components/generated/Billboard.gen.js +6 -0
  12. package/dist/components/generated/CameraMode.gen.js +6 -0
  13. package/dist/components/generated/CameraModeArea.gen.js +6 -0
  14. package/dist/components/generated/GltfContainer.gen.js +6 -0
  15. package/dist/components/generated/Material.gen.js +6 -0
  16. package/dist/components/generated/MeshCollider.gen.js +6 -0
  17. package/dist/components/generated/MeshRenderer.gen.js +6 -0
  18. package/dist/components/generated/NftShape.gen.js +6 -0
  19. package/dist/components/generated/PointerEvents.gen.js +6 -0
  20. package/dist/components/generated/PointerEventsResult.gen.js +6 -0
  21. package/dist/components/generated/PointerLock.gen.js +6 -0
  22. package/dist/components/generated/Raycast.gen.js +6 -0
  23. package/dist/components/generated/RaycastResult.gen.js +6 -0
  24. package/dist/components/generated/TextShape.gen.js +6 -0
  25. package/dist/components/generated/UiBackground.gen.js +6 -0
  26. package/dist/components/generated/UiDropdown.gen.js +6 -0
  27. package/dist/components/generated/UiDropdownResult.gen.js +6 -0
  28. package/dist/components/generated/UiInput.gen.js +6 -0
  29. package/dist/components/generated/UiInputResult.gen.js +6 -0
  30. package/dist/components/generated/UiText.gen.js +6 -0
  31. package/dist/components/generated/UiTransform.gen.js +6 -0
  32. package/dist/components/generated/VideoPlayer.gen.js +6 -0
  33. package/dist/components/generated/VisibilityComponent.gen.js +6 -0
  34. package/dist/components/generated/global.gen.d.ts +26 -26
  35. package/dist/components/generated/index.gen.d.ts +32 -31
  36. package/dist/components/generated/index.gen.js +4 -1
  37. package/dist/components/generated/pb/decentraland/sdk/components/pointer_events_result.gen.d.ts +1 -9
  38. package/dist/components/generated/pb/decentraland/sdk/components/pointer_events_result.gen.js +2 -36
  39. package/dist/components/index.d.ts +9 -9
  40. package/dist/components/index.js +1 -1
  41. package/dist/components/{legacy → manual}/Transform.d.ts +2 -2
  42. package/dist/components/{legacy → manual}/Transform.js +32 -0
  43. package/dist/components/types.d.ts +1 -1
  44. package/dist/engine/component.d.ts +74 -27
  45. package/dist/engine/component.js +7 -240
  46. package/dist/engine/grow-only-value-set-component-definition.d.ts +8 -0
  47. package/dist/engine/grow-only-value-set-component-definition.js +132 -0
  48. package/dist/engine/index.d.ts +1 -2
  49. package/dist/engine/index.js +18 -1
  50. package/dist/engine/input.d.ts +3 -3
  51. package/dist/engine/input.js +75 -68
  52. package/dist/engine/lww-element-set-component-definition.d.ts +6 -0
  53. package/dist/engine/lww-element-set-component-definition.js +229 -0
  54. package/dist/engine/readonly.d.ts +2 -2
  55. package/dist/engine/types.d.ts +20 -9
  56. package/dist/engine/types.js +1 -1
  57. package/dist/runtime/invariant.d.ts +1 -0
  58. package/dist/runtime/invariant.js +6 -1
  59. package/dist/runtime/types.d.ts +1 -2
  60. package/dist/runtime/types.js +0 -1
  61. package/dist/schemas/Array.js +5 -0
  62. package/dist/schemas/ISchema.d.ts +27 -2
  63. package/dist/schemas/Map.d.ts +0 -1
  64. package/dist/schemas/Map.js +9 -0
  65. package/dist/schemas/Optional.js +5 -0
  66. package/dist/schemas/basic/Boolean.js +4 -0
  67. package/dist/schemas/basic/Enum.js +27 -0
  68. package/dist/schemas/basic/Float.js +8 -0
  69. package/dist/schemas/basic/Integer.js +16 -0
  70. package/dist/schemas/basic/String.js +4 -0
  71. package/dist/schemas/buildSchema.d.ts +7 -0
  72. package/dist/schemas/buildSchema.js +63 -0
  73. package/dist/schemas/custom/Color3.js +9 -0
  74. package/dist/schemas/custom/Color4.js +10 -0
  75. package/dist/schemas/custom/Entity.js +4 -0
  76. package/dist/schemas/custom/Quaternion.js +10 -0
  77. package/dist/schemas/custom/Vector3.js +10 -0
  78. package/dist/schemas/index.d.ts +2 -2
  79. package/dist/serialization/crdt/appendValue.d.ts +1 -0
  80. package/dist/serialization/crdt/appendValue.js +49 -0
  81. package/dist/serialization/crdt/index.d.ts +1 -0
  82. package/dist/serialization/crdt/index.js +1 -0
  83. package/dist/serialization/crdt/message.js +4 -0
  84. package/dist/serialization/crdt/types.d.ts +24 -3
  85. package/dist/serialization/crdt/types.js +2 -1
  86. package/dist/systems/crdt/index.d.ts +1 -1
  87. package/dist/systems/crdt/index.js +21 -8
  88. package/dist/systems/events.d.ts +2 -2
  89. package/package.json +3 -3
@@ -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 PBPointerEventsResult_PointerCommand = {
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 = createBasePBPointerEventsResult_PointerCommand();
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 { ComponentDefinition } from '../engine/component';
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 { ComponentGetter } from './generated/index.gen';
7
- import { TransformComponentExtended } from './legacy/Transform';
6
+ import { LwwComponentGetter, GSetComponentGetter } from './generated/index.gen';
7
+ import { TransformComponentExtended } from './manual/Transform';
8
8
  export * from './generated/index.gen';
9
- export type { ComponentDefinition, ComponentGetter };
10
- export declare const Transform: ComponentGetter<TransformComponentExtended>;
11
- export declare const Material: ComponentGetter<MaterialComponentDefinitionExtended>;
12
- export declare const Animator: ComponentGetter<AnimatorComponentDefinitionExtended>;
13
- export declare const MeshRenderer: ComponentGetter<MeshRendererComponentDefinitionExtended>;
14
- export declare const MeshCollider: ComponentGetter<MeshColliderComponentDefinitionExtended>;
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>;
@@ -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 './legacy/Transform';
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 { ComponentDefinition, IEngine } from '../../engine';
1
+ import { LastWriteWinElementSetComponentDefinition, IEngine } from '../../engine';
2
2
  import { Entity } from '../../engine/entity';
3
3
  /**
4
4
  * @public
5
5
  */
6
- export type TransformComponent = ComponentDefinition<TransformType>;
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 './legacy/Transform';
5
+ export type { TransformComponentExtended, TransformTypeWithOptionals } from './manual/Transform';
@@ -1,24 +1,72 @@
1
- import type { ISchema } from '../schemas/ISchema';
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 interface ComponentDefinition<T> {
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
- * Return the default value of the current component
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
- default(): DeepReadonly<T>;
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), throw an error if the entity doesn't have the component.
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 &lt;entity,component&gt; 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
- * This function receives a CRDT update and returns a touple with a "conflict
74
- * resoluton" message, in case of the sender being updated or null in case of noop/accepted
75
- * change. The second element of the touple is the modified/changed/deleted value.
76
- * @public
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
- updateFromCrdt(body: CrdtMessageBody): [null | PutComponentMessageBody | DeleteComponentMessageBody, T | null];
124
+ addValue(entity: Entity, val: DeepReadonly<T>): DeepReadonlySet<T>;
79
125
  /**
80
- * This function returns an iterable with all the CRDT updates that need to be
81
- * broadcasted to other actors in the system. After returning, this function
82
- * clears the internal dirty state. Updates are produced only once.
83
- * @public
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
- getCrdtUpdates(): Iterable<CrdtMessageBody>;
131
+ get(entity: Entity): DeepReadonlySet<T>;
86
132
  }
87
- export declare function incrementTimestamp(entity: Entity, timestamps: Map<Entity, number>): number;
88
- export declare function createUpdateFromCrdt(componentId: number, timestamps: Map<Entity, number>, schema: Pick<ISchema<any>, 'serialize' | 'deserialize'>, data: Map<Entity, unknown>): (msg: CrdtMessageBody) => [null | PutComponentMessageBody | DeleteComponentMessageBody, any];
89
- export declare function createGetCrdtMessages(componentId: number, timestamps: Map<Entity, number>, dirtyIterator: Set<Entity>, schema: Pick<ISchema<any>, 'serialize'>, data: Map<Entity, unknown>): () => Generator<PutComponentMessageBody | DeleteComponentMessageBody, void, unknown>;
133
+ /**
134
+ * @public
135
+ */
136
+ export type ComponentDefinition<T> = LastWriteWinElementSetComponentDefinition<T> | GrowOnlyValueSetComponentDefinition<T>;
@@ -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
- * @internal
2
+ * Component types are used to pick the wire protocol and the conflict resolution algorithm
3
+ * @public
142
4
  */
143
- export function createComponentDefinitionFromSchema(componentName, componentId, schema) {
144
- const data = new Map();
145
- const dirtyIterator = new Set();
146
- const timestamps = new Map();
147
- return {
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 = {}));
@@ -0,0 +1,8 @@
1
+ import { DeepReadonly } from './readonly';
2
+ /**
3
+ * @public
4
+ */
5
+ export type ValueSetOptions<T> = {
6
+ timestampFunction: (value: DeepReadonly<T>) => number;
7
+ maxElements: number;
8
+ };