Skip to content

Commit

Permalink
feat: make replicated data types generic
Browse files Browse the repository at this point in the history
  • Loading branch information
pvlugter committed May 11, 2022
1 parent fad233b commit 1339db7
Show file tree
Hide file tree
Showing 16 changed files with 268 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type RemoveShoppingCart = proto.com.example.shoppingcart.RemoveShoppingCart;

type Context = replicatedentity.ReplicatedEntityCommandContext;

type Product = proto.com.example.shoppingcart.domain.IProduct & protobuf.Message;

// end::types[]
// tag::class[]
const entity = new replicatedentity.ReplicatedEntity( // <1>
Expand All @@ -45,7 +47,7 @@ const entity = new replicatedentity.ReplicatedEntity( // <1>
// end::class[]

// tag::defaultValue[]
entity.defaultValue = () => new replicatedentity.ReplicatedCounterMap(); // <1>
entity.defaultValue = () => new replicatedentity.ReplicatedCounterMap<Product>(); // <1>
// end::defaultValue[]

// tag::types[]
Expand All @@ -69,7 +71,7 @@ function addItem(addLineItem: AddLineItem, context: Context) {
return replies.failure(`Quantity for item ${addLineItem.productId} must be greater than zero`); // <1>
}

const cart = context.state as replicatedentity.ReplicatedCounterMap; // <2>
const cart = context.state as replicatedentity.ReplicatedCounterMap<Product>; // <2>

const product = Product.create({
id: addLineItem.productId, // <3>
Expand All @@ -83,7 +85,7 @@ function addItem(addLineItem: AddLineItem, context: Context) {
// end::addItem[]

function removeItem(removeLineItem: RemoveLineItem, context: Context) {
const cart = context.state as replicatedentity.ReplicatedCounterMap;
const cart = context.state as replicatedentity.ReplicatedCounterMap<Product>;

const product = Product.create({
id: removeLineItem.productId,
Expand All @@ -101,7 +103,7 @@ function removeItem(removeLineItem: RemoveLineItem, context: Context) {

// tag::getCart[]
function getCart(getShoppingCart: GetShoppingCart, context: Context) {
const cart = context.state as replicatedentity.ReplicatedCounterMap; // <1>
const cart = context.state as replicatedentity.ReplicatedCounterMap<Product>; // <1>

const items = Array.from(cart.keys()) // <2>
.map(product => ({
Expand Down
18 changes: 18 additions & 0 deletions sdk/bin/compile-protobuf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ $PROTOC \
rm -rf test/proto
cp -r proto test/

pbjs -t static-module -w commonjs \
-o ./test/proto/test-protobuf-bundle.js \
-p ./proto -p ./protoc/include \
./proto/kalix/*.proto \
./proto/kalix/protocol/*.proto \
./proto/kalix/component/*.proto \
./proto/kalix/component/*/*.proto \
./test/*.proto

pbjs -t static-module \
-p ./proto -p ./protoc/include \
./proto/kalix/*.proto \
./proto/kalix/protocol/*.proto \
./proto/kalix/component/*.proto \
./proto/kalix/component/*/*.proto \
./test/*.proto \
| pbts -o ./test/proto/test-protobuf-bundle.d.ts -

OUT_DIR="${PWD}/test/proto"
TS_OUT_DIR="${PWD}/test/proto"

Expand Down
36 changes: 20 additions & 16 deletions sdk/src/replicated-data/counter-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,23 @@ namespace protocol {
proto.kalix.component.replicatedentity.IReplicatedCounterMapEntryDelta;
}

interface Entry {
key: Serializable;
interface Entry<Key extends Serializable> {
key: Key;
counter: ReplicatedCounter;
}

/**
* A replicated map of counters.
*
* @typeParam Key - Type of keys for the Replicated Counter Map
*
* @public
*/
export class ReplicatedCounterMap implements ReplicatedData {
private counters = new Map<Comparable, Entry>();
private removed = new Map<Comparable, Serializable>();
export class ReplicatedCounterMap<Key extends Serializable = Serializable>
implements ReplicatedData
{
private counters = new Map<Comparable, Entry<Key>>();
private removed = new Map<Comparable, Key>();
private cleared = false;

/**
Expand All @@ -55,7 +59,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @param key - The key to get
* @returns The counter value, or undefined if no value is defined at that key
*/
get = (key: Serializable): number | undefined => {
get = (key: Key): number | undefined => {
const entry = this.counters.get(AnySupport.toComparable(key));
return entry !== undefined ? entry.counter.value : undefined;
};
Expand All @@ -66,7 +70,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @param key - The key to get
* @returns The counter value as a long, or undefined if no value is defined at that key
*/
getLong = (key: Serializable): Long.Long | undefined => {
getLong = (key: Key): Long.Long | undefined => {
const entry = this.counters.get(AnySupport.toComparable(key));
return entry !== undefined ? entry.counter.longValue : undefined;
};
Expand All @@ -79,9 +83,9 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @returns This counter map
*/
increment = (
key: Serializable,
key: Key,
increment: Long.Long | number,
): ReplicatedCounterMap => {
): ReplicatedCounterMap<Key> => {
this.getOrCreateCounter(key).increment(increment);
return this;
};
Expand All @@ -94,9 +98,9 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @returns This counter map
*/
decrement = (
key: Serializable,
key: Key,
decrement: Long.Long | number,
): ReplicatedCounterMap => {
): ReplicatedCounterMap<Key> => {
this.getOrCreateCounter(key).decrement(decrement);
return this;
};
Expand All @@ -107,7 +111,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @param key - The key to check
* @returns True if this counter map contains a value for the given key
*/
has = (key: Serializable): boolean => {
has = (key: Key): boolean => {
return this.counters.has(AnySupport.toComparable(key));
};

Expand All @@ -121,7 +125,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
/**
* Return an (iterable) iterator of the keys of this counter map.
*/
keys = (): IterableIterator<Serializable> => {
keys = (): IterableIterator<Key> => {
return iterators.map(this.counters.values(), (entry) => entry.key);
};

Expand All @@ -132,7 +136,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
* @returns This counter map
*/

delete = (key: Serializable): ReplicatedCounterMap => {
delete = (key: Key): ReplicatedCounterMap<Key> => {
const comparableKey = AnySupport.toComparable(key);
if (this.counters.has(comparableKey)) {
this.counters.delete(comparableKey);
Expand All @@ -146,7 +150,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
*
* @returns This counter map
*/
clear = (): ReplicatedCounterMap => {
clear = (): ReplicatedCounterMap<Key> => {
if (this.counters.size > 0) {
this.cleared = true;
this.counters.clear();
Expand All @@ -155,7 +159,7 @@ export class ReplicatedCounterMap implements ReplicatedData {
return this;
};

private getOrCreateCounter(key: Serializable): ReplicatedCounter {
private getOrCreateCounter(key: Key): ReplicatedCounter {
const comparableKey = AnySupport.toComparable(key);
const entry = this.counters.get(comparableKey);
if (entry) {
Expand Down
Loading

0 comments on commit 1339db7

Please sign in to comment.