@serialized/serialized-client
Advanced tools
Comparing version 2.2.0 to 3.0.0
@@ -1,23 +0,8 @@ | ||
import { BaseClient } from './BaseClient'; | ||
export interface LoadAggregateOptions { | ||
since?: number; | ||
limit?: number; | ||
} | ||
export interface DomainEvent { | ||
eventType: string; | ||
eventId?: string; | ||
data?: any; | ||
encryptedData?: string; | ||
} | ||
import { BaseClient, DomainEvent, EventEnvelope } from './'; | ||
export interface DeleteAggregateResponse { | ||
deleteToken?: string; | ||
} | ||
export interface StoreEventsPayload { | ||
events: DomainEvent[]; | ||
expectedVersion?: number; | ||
} | ||
declare type AggregateType = string; | ||
declare type AggregateId = string; | ||
export interface AggregateRequest { | ||
aggregateType: AggregateType; | ||
aggregateId: AggregateId; | ||
@@ -27,16 +12,8 @@ } | ||
aggregateVersion: number; | ||
events: DomainEvent[]; | ||
events: EventEnvelope<DomainEvent>[]; | ||
hasMore: false; | ||
} | ||
export interface StoreEventsRequest extends AggregateRequest { | ||
events: DomainEvent[]; | ||
} | ||
export interface StoreEventsOptions { | ||
expectedVersion?: number; | ||
} | ||
export interface StoreEventRequest extends AggregateRequest { | ||
event: DomainEvent; | ||
} | ||
export interface LoadAggregateRequest extends AggregateRequest { | ||
} | ||
export interface CheckAggregateExistsRequest extends AggregateRequest { | ||
@@ -52,13 +29,25 @@ } | ||
} | ||
export declare class AggregatesClient extends BaseClient { | ||
constructor(axiosClient: any, config: any); | ||
export interface AggregateMetadata { | ||
version: number; | ||
} | ||
export interface Commit { | ||
events: DomainEvent[]; | ||
encryptedData?: string; | ||
} | ||
declare class AggregatesClient<A> extends BaseClient { | ||
private aggregateTypeConstructor; | ||
private readonly aggregateType; | ||
private readonly eventHandlers; | ||
private readonly initialState; | ||
constructor(aggregateTypeConstructor: any, config: any); | ||
checkExists(request: CheckAggregateExistsRequest): Promise<any>; | ||
loadAggregate(request: LoadAggregateRequest, options?: LoadAggregateOptions): Promise<LoadAggregateResponse>; | ||
storeEvents(request: StoreEventsRequest, options?: StoreEventsOptions): Promise<void>; | ||
storeEvent(request: StoreEventRequest, options?: StoreEventsOptions): Promise<void>; | ||
update(aggregateId: string, commandHandler: (s: A) => Commit): Promise<void>; | ||
create(aggregateId: string, commandHandler: (s: A) => Commit): Promise<void>; | ||
storeEvent(aggregateId: string, event: DomainEvent, options?: StoreEventsOptions): Promise<void>; | ||
storeEvents(aggregateId: string, commit: Commit, options?: StoreEventsOptions): Promise<void>; | ||
load<T extends A>(aggregateId: string): Promise<T>; | ||
private loadInternal; | ||
deleteAggregate(request: DeleteAggregateRequest, options?: DeleteAggregateOptions): Promise<DeleteAggregateResponse | void>; | ||
deleteAggregateType(request: DeleteAggregateTypeRequest, options?: DeleteAggregateOptions): Promise<DeleteAggregateResponse | void>; | ||
save(aggregateRoot: any, consistencyCheck?: boolean): Promise<any>; | ||
create(aggregateRoot: any): Promise<any>; | ||
load(aggregateRoot: any): Promise<void>; | ||
private saveInternal; | ||
static aggregateEventsUrlPath(aggregateType: string, aggregateId: string): string; | ||
@@ -68,2 +57,2 @@ static aggregateUrlPath(aggregateType: string, aggregateId: string): string; | ||
} | ||
export {}; | ||
export { AggregatesClient }; |
@@ -52,7 +52,13 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var BaseClient_1 = require("./BaseClient"); | ||
var _1 = require("./"); | ||
var AggregatesClient = /** @class */ (function (_super) { | ||
__extends(AggregatesClient, _super); | ||
function AggregatesClient(axiosClient, config) { | ||
return _super.call(this, axiosClient, config) || this; | ||
function AggregatesClient(aggregateTypeConstructor, config) { | ||
var _this = _super.call(this, config) || this; | ||
_this.aggregateTypeConstructor = aggregateTypeConstructor; | ||
var aggregateTypeInstance = new aggregateTypeConstructor.prototype.constructor({}); | ||
_this.aggregateType = aggregateTypeInstance.aggregateType; | ||
_this.initialState = aggregateTypeInstance.initialState; | ||
_this.eventHandlers = aggregateTypeInstance.eventHandlers; | ||
return _this; | ||
} | ||
@@ -65,3 +71,3 @@ AggregatesClient.prototype.checkExists = function (request) { | ||
case 0: | ||
url = AggregatesClient.aggregateUrlPath(request.aggregateType, request.aggregateId); | ||
url = AggregatesClient.aggregateUrlPath(this.aggregateType, request.aggregateId); | ||
return [4 /*yield*/, this.axiosClient.head(url, this.axiosConfig())]; | ||
@@ -73,13 +79,15 @@ case 1: return [2 /*return*/, (_a.sent()).data]; | ||
}; | ||
AggregatesClient.prototype.loadAggregate = function (request, options) { | ||
AggregatesClient.prototype.update = function (aggregateId, commandHandler) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, config; | ||
var response, eventsToSave; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = AggregatesClient.aggregateUrlPath(request.aggregateType, request.aggregateId); | ||
config = this.axiosConfig(); | ||
config.params = options; | ||
return [4 /*yield*/, this.axiosClient.get(url, config)]; | ||
case 1: return [2 /*return*/, (_a.sent()).data]; | ||
case 0: return [4 /*yield*/, this.loadInternal(aggregateId)]; | ||
case 1: | ||
response = _a.sent(); | ||
eventsToSave = commandHandler(response.aggregate); | ||
return [4 /*yield*/, this.saveInternal(aggregateId, eventsToSave, { expectedVersion: response.metadata.version })]; | ||
case 2: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
@@ -89,16 +97,13 @@ }); | ||
}; | ||
AggregatesClient.prototype.storeEvents = function (request, options) { | ||
AggregatesClient.prototype.create = function (aggregateId, commandHandler) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, payload; | ||
var aggregate, eventsToSave; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = "" + AggregatesClient.aggregateEventsUrlPath(request.aggregateType, request.aggregateId); | ||
payload = { | ||
events: request.events, | ||
expectedVersion: options === null || options === void 0 ? void 0 : options.expectedVersion | ||
}; | ||
return [4 /*yield*/, this.axiosClient.post(url, payload, this.axiosConfig())]; | ||
aggregate = new this.aggregateTypeConstructor.prototype.constructor(this.initialState); | ||
eventsToSave = commandHandler(aggregate); | ||
return [4 /*yield*/, this.saveInternal(aggregateId, eventsToSave, { expectedVersion: 0 })]; | ||
case 1: | ||
(_a.sent()).data; | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
@@ -109,16 +114,9 @@ } | ||
}; | ||
AggregatesClient.prototype.storeEvent = function (request, options) { | ||
AggregatesClient.prototype.storeEvent = function (aggregateId, event, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, payload; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = "" + AggregatesClient.aggregateEventsUrlPath(request.aggregateType, request.aggregateId); | ||
payload = { | ||
events: [request.event], | ||
expectedVersion: options === null || options === void 0 ? void 0 : options.expectedVersion | ||
}; | ||
return [4 /*yield*/, this.axiosClient.post(url, payload, this.axiosConfig())]; | ||
case 0: return [4 /*yield*/, this.storeEvents(aggregateId, { events: [event] }, options)]; | ||
case 1: | ||
(_a.sent()).data; | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
@@ -129,2 +127,58 @@ } | ||
}; | ||
AggregatesClient.prototype.storeEvents = function (aggregateId, commit, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.saveInternal(aggregateId, commit, options)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AggregatesClient.prototype.load = function (aggregateId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var response; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.loadInternal(aggregateId)]; | ||
case 1: | ||
response = _a.sent(); | ||
return [2 /*return*/, response.aggregate]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AggregatesClient.prototype.loadInternal = function (aggregateId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, axiosResponse, data, currentState, aggregate, metadata; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = "" + AggregatesClient.aggregateUrlPath(this.aggregateType, aggregateId); | ||
return [4 /*yield*/, this.axiosClient.get(url, this.axiosConfig())]; | ||
case 1: | ||
axiosResponse = _a.sent(); | ||
data = axiosResponse.data; | ||
currentState = this.initialState; | ||
data.events.forEach(function (e) { | ||
var handler = _this.eventHandlers[e.eventType]; | ||
if (handler) { | ||
currentState = handler(currentState, e); | ||
} | ||
else { | ||
return Promise.reject("Failed to call handler. No match for event " + e.eventType); | ||
} | ||
}); | ||
aggregate = new this.aggregateTypeConstructor.prototype.constructor(currentState); | ||
metadata = { version: data.aggregateVersion }; | ||
aggregate._metadata = metadata; | ||
console.log("Loaded aggregate " + this.aggregateType + "@" + aggregateId + ":" + metadata.version); | ||
return [2 /*return*/, { aggregate: aggregate, metadata: metadata }]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AggregatesClient.prototype.deleteAggregate = function (request, options) { | ||
@@ -136,3 +190,3 @@ return __awaiter(this, void 0, void 0, function () { | ||
case 0: | ||
url = "" + AggregatesClient.aggregateUrlPath(request.aggregateType, request.aggregateId); | ||
url = "" + AggregatesClient.aggregateUrlPath(this.aggregateType, request.aggregateId); | ||
config = this.axiosConfig(); | ||
@@ -161,14 +215,15 @@ config.params = options; | ||
}; | ||
AggregatesClient.prototype.save = function (aggregateRoot, consistencyCheck) { | ||
if (consistencyCheck === void 0) { consistencyCheck = true; } | ||
AggregatesClient.prototype.saveInternal = function (aggregateId, commit, options) { | ||
if (options === void 0) { options = { expectedVersion: undefined }; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var uncommittedEvents, payload, url, data; | ||
var eventsToSave, payload, url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
uncommittedEvents = aggregateRoot.getUncommittedEvents(); | ||
if (consistencyCheck) { | ||
eventsToSave = commit.events.map(function (e) { return (_1.EventEnvelope.fromDomainEvent(e)); }); | ||
if (options.expectedVersion) { | ||
payload = { | ||
events: uncommittedEvents, | ||
expectedVersion: aggregateRoot.getCurrentVersion(), | ||
events: eventsToSave, | ||
expectedVersion: options.expectedVersion, | ||
encryptedData: commit.encryptedData | ||
}; | ||
@@ -178,47 +233,10 @@ } | ||
payload = { | ||
events: uncommittedEvents, | ||
events: eventsToSave, | ||
encryptedData: commit.encryptedData | ||
}; | ||
} | ||
url = AggregatesClient.aggregateUrlPath(aggregateRoot.aggregateType, aggregateRoot.aggregateId) + "/events"; | ||
url = AggregatesClient.aggregateUrlPath(this.aggregateType, aggregateId) + "/events"; | ||
return [4 /*yield*/, this.axiosClient.post(url, payload, this.axiosConfig())]; | ||
case 1: | ||
data = (_a.sent()).data; | ||
aggregateRoot.commit(); | ||
if (consistencyCheck) { | ||
aggregateRoot.nextVersion(); | ||
} | ||
return [2 /*return*/, data]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AggregatesClient.prototype.create = function (aggregateRoot) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var uncommittedEvents, payload, url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
uncommittedEvents = aggregateRoot.getUncommittedEvents(); | ||
payload = { | ||
events: uncommittedEvents, | ||
expectedVersion: 0, | ||
}; | ||
url = AggregatesClient.aggregateUrlPath(aggregateRoot.aggregateType, aggregateRoot.aggregateId) + "/events"; | ||
return [4 /*yield*/, this.axiosClient.post(url, payload, this.axiosConfig())]; | ||
case 1: return [2 /*return*/, (_a.sent()).data]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AggregatesClient.prototype.load = function (aggregateRoot) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, response; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = "" + AggregatesClient.aggregateUrlPath(aggregateRoot.aggregateType, aggregateRoot.aggregateId); | ||
return [4 /*yield*/, this.axiosClient.get(url, this.axiosConfig())]; | ||
case 1: | ||
response = (_a.sent()).data; | ||
aggregateRoot.fromEvents(response); | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
@@ -239,3 +257,3 @@ } | ||
return AggregatesClient; | ||
}(BaseClient_1.BaseClient)); | ||
}(_1.BaseClient)); | ||
exports.AggregatesClient = AggregatesClient; |
@@ -5,4 +5,4 @@ import { AxiosInstance, AxiosRequestConfig } from "axios"; | ||
private config; | ||
constructor(axiosClient: any, config: any); | ||
constructor(config: any); | ||
protected axiosConfig(): AxiosRequestConfig; | ||
} |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var axios_1 = __importDefault(require("axios")); | ||
var SERIALIZED_ACCESS_KEY_HEADER = 'Serialized-Access-Key'; | ||
var SERIALIZED_SECRET_ACCESS_KEY_HEADER = 'Serialized-Secret-Access-Key'; | ||
var BaseClient = /** @class */ (function () { | ||
function BaseClient(axiosClient, config) { | ||
function BaseClient(config) { | ||
var axiosClient = axios_1.default.create({ | ||
baseURL: "https://api.serialized.io", | ||
withCredentials: true, | ||
maxRedirects: 0, | ||
headers: { | ||
Accept: 'application/json', | ||
} | ||
}); | ||
axiosClient.interceptors.response.use(function (response) { | ||
return response; | ||
}, function (error) { | ||
if (error.config && error.config.headers) { | ||
if (error.config.headers[SERIALIZED_ACCESS_KEY_HEADER]) { | ||
error.config.headers[SERIALIZED_ACCESS_KEY_HEADER] = '******'; | ||
} | ||
if (error.config.headers[SERIALIZED_SECRET_ACCESS_KEY_HEADER]) { | ||
error.config.headers[SERIALIZED_SECRET_ACCESS_KEY_HEADER] = '******'; | ||
} | ||
} | ||
return Promise.reject(error); | ||
}); | ||
this.axiosClient = axiosClient; | ||
@@ -6,0 +33,0 @@ this.config = config; |
@@ -1,4 +0,2 @@ | ||
import { BaseClient } from "./BaseClient"; | ||
import { AxiosInstance } from "axios"; | ||
import { SerializedConfig } from "./types"; | ||
import { BaseClient } from "./"; | ||
export interface FeedEvent { | ||
@@ -47,3 +45,2 @@ eventType: string; | ||
export declare class FeedsClient extends BaseClient { | ||
constructor(axiosClient: AxiosInstance, config: SerializedConfig); | ||
loadOverview(): Promise<LoadFeedsOverviewResponse>; | ||
@@ -50,0 +47,0 @@ loadFeed(request: LoadFeedRequest, options?: LoadFeedOptions): Promise<LoadFeedResponse>; |
@@ -52,7 +52,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var BaseClient_1 = require("./BaseClient"); | ||
var _1 = require("./"); | ||
var FeedsClient = /** @class */ (function (_super) { | ||
__extends(FeedsClient, _super); | ||
function FeedsClient(axiosClient, config) { | ||
return _super.call(this, axiosClient, config) || this; | ||
function FeedsClient() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
@@ -133,3 +133,3 @@ FeedsClient.prototype.loadOverview = function () { | ||
return FeedsClient; | ||
}(BaseClient_1.BaseClient)); | ||
}(_1.BaseClient)); | ||
exports.FeedsClient = FeedsClient; |
import { SerializedInstance } from "./Serialized"; | ||
import { SerializedConfig } from "./types"; | ||
export * from "./decorators"; | ||
export * from "./types"; | ||
export * from "./Serialized"; | ||
export * from "./AggregateRoot"; | ||
export * from "./BaseClient"; | ||
export * from "./AggregatesClient"; | ||
export * from "./ProjectionsClient"; | ||
@@ -7,0 +9,0 @@ export * from "./ReactionsClient"; |
@@ -5,15 +5,11 @@ "use strict"; | ||
} | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var axios_1 = __importDefault(require("axios")); | ||
var Serialized_1 = require("./Serialized"); | ||
__export(require("./decorators")); | ||
__export(require("./Serialized")); | ||
__export(require("./AggregateRoot")); | ||
__export(require("./BaseClient")); | ||
__export(require("./AggregatesClient")); | ||
__export(require("./ProjectionsClient")); | ||
__export(require("./ReactionsClient")); | ||
__export(require("./FeedsClient")); | ||
var SERIALIZED_ACCESS_KEY_HEADER = 'Serialized-Access-Key'; | ||
var SERIALIZED_SECRET_ACCESS_KEY_HEADER = 'Serialized-Secret-Access-Key'; | ||
var Serialized = /** @class */ (function () { | ||
@@ -37,22 +33,3 @@ function Serialized() { | ||
Serialized.createInstance = function (config) { | ||
var axiosClient = axios_1.default.create({ | ||
baseURL: "https://api.serialized.io", | ||
withCredentials: true, | ||
maxRedirects: 0, | ||
headers: { | ||
Accept: 'application/json', | ||
} | ||
}); | ||
axiosClient.interceptors.response.use(function (response) { | ||
return response; | ||
}, function (error) { | ||
if (error.config.headers[SERIALIZED_ACCESS_KEY_HEADER]) { | ||
error.config.headers[SERIALIZED_ACCESS_KEY_HEADER] = '******'; | ||
} | ||
if (error.config.headers[SERIALIZED_SECRET_ACCESS_KEY_HEADER]) { | ||
error.config.headers[SERIALIZED_SECRET_ACCESS_KEY_HEADER] = '******'; | ||
} | ||
return Promise.reject(error); | ||
}); | ||
return new Serialized_1.SerializedInstance(config, axiosClient); | ||
return new Serialized_1.SerializedInstance(config); | ||
}; | ||
@@ -59,0 +36,0 @@ return Serialized; |
@@ -1,4 +0,2 @@ | ||
import { BaseClient } from "./BaseClient"; | ||
import { AxiosInstance } from "axios"; | ||
import { SerializedConfig } from "./types"; | ||
import { BaseClient } from "./"; | ||
export interface ListSingleProjectionOptions { | ||
@@ -77,3 +75,2 @@ sort?: string; | ||
export declare class ProjectionsClient extends BaseClient { | ||
constructor(axiosClient: AxiosInstance, config: SerializedConfig); | ||
createOrUpdateDefinition(request: CreateProjectionDefinitionRequest): Promise<void>; | ||
@@ -80,0 +77,0 @@ deleteProjectionDefinition(request: DeleteProjectionDefinitionRequest): Promise<void>; |
@@ -52,7 +52,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var BaseClient_1 = require("./BaseClient"); | ||
var _1 = require("./"); | ||
var ProjectionsClient = /** @class */ (function (_super) { | ||
__extends(ProjectionsClient, _super); | ||
function ProjectionsClient(axiosClient, config) { | ||
return _super.call(this, axiosClient, config) || this; | ||
function ProjectionsClient() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
@@ -159,3 +159,3 @@ ProjectionsClient.prototype.createOrUpdateDefinition = function (request) { | ||
return ProjectionsClient; | ||
}(BaseClient_1.BaseClient)); | ||
}(_1.BaseClient)); | ||
exports.ProjectionsClient = ProjectionsClient; |
@@ -1,2 +0,2 @@ | ||
import { BaseClient } from "./BaseClient"; | ||
import { BaseClient } from "./"; | ||
export interface HttpAction { | ||
@@ -85,3 +85,2 @@ actionType: 'HTTP_POST'; | ||
export declare class ReactionsClient extends BaseClient { | ||
constructor(axiosClient: any, config: any); | ||
createOrUpdateReactionDefinition(request: CreateReactionDefinitionRequest): Promise<void>; | ||
@@ -88,0 +87,0 @@ listReactionDefinitions(): Promise<LoadReactionDefinitionsResponse>; |
@@ -52,7 +52,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var BaseClient_1 = require("./BaseClient"); | ||
var _1 = require("./"); | ||
var ReactionsClient = /** @class */ (function (_super) { | ||
__extends(ReactionsClient, _super); | ||
function ReactionsClient(axiosClient, config) { | ||
return _super.call(this, axiosClient, config) || this; | ||
function ReactionsClient() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
@@ -166,3 +166,3 @@ ReactionsClient.prototype.createOrUpdateReactionDefinition = function (request) { | ||
return ReactionsClient; | ||
}(BaseClient_1.BaseClient)); | ||
}(_1.BaseClient)); | ||
exports.ReactionsClient = ReactionsClient; |
@@ -1,13 +0,19 @@ | ||
import { AggregatesClient } from "./AggregatesClient"; | ||
import { ProjectionsClient } from './ProjectionsClient'; | ||
import { FeedsClient } from './FeedsClient'; | ||
import { ReactionsClient } from './ReactionsClient'; | ||
import { AggregatesClient, FeedsClient, ProjectionsClient, ReactionsClient } from "./"; | ||
export interface DomainEvent { | ||
} | ||
export declare class EventEnvelope<E> { | ||
readonly eventId: string; | ||
readonly eventType: string; | ||
readonly data: E; | ||
readonly encryptedData?: string; | ||
constructor(event: E); | ||
static fromDomainEvent<E extends DomainEvent>(event: E): EventEnvelope<E>; | ||
} | ||
export declare class SerializedInstance { | ||
readonly config: any; | ||
readonly axiosClient: any; | ||
readonly aggregates: AggregatesClient; | ||
readonly projections: ProjectionsClient; | ||
readonly feeds: FeedsClient; | ||
readonly reactions: ReactionsClient; | ||
constructor(config: any, axiosClient: any); | ||
constructor(config: any); | ||
aggregateClient<A>(type: any): AggregatesClient<A>; | ||
projectionsClient(): ProjectionsClient; | ||
feedsClient(): FeedsClient; | ||
reactionsClient(): ReactionsClient; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var AggregatesClient_1 = require("./AggregatesClient"); | ||
var ProjectionsClient_1 = require("./ProjectionsClient"); | ||
var FeedsClient_1 = require("./FeedsClient"); | ||
var ReactionsClient_1 = require("./ReactionsClient"); | ||
var _1 = require("./"); | ||
var uuid_1 = require("uuid"); | ||
var EventEnvelope = /** @class */ (function () { | ||
function EventEnvelope(event) { | ||
this.eventId = uuid_1.v4(); | ||
this.eventType = event.constructor.name; | ||
this.data = event; | ||
} | ||
EventEnvelope.fromDomainEvent = function (event) { | ||
return new EventEnvelope(event); | ||
}; | ||
return EventEnvelope; | ||
}()); | ||
exports.EventEnvelope = EventEnvelope; | ||
var SerializedInstance = /** @class */ (function () { | ||
function SerializedInstance(config, axiosClient) { | ||
function SerializedInstance(config) { | ||
this.config = config; | ||
this.axiosClient = axiosClient; | ||
this.aggregates = new AggregatesClient_1.AggregatesClient(axiosClient, config); | ||
this.projections = new ProjectionsClient_1.ProjectionsClient(axiosClient, config); | ||
this.feeds = new FeedsClient_1.FeedsClient(axiosClient, config); | ||
this.reactions = new ReactionsClient_1.ReactionsClient(axiosClient, config); | ||
} | ||
SerializedInstance.prototype.aggregateClient = function (type) { | ||
return new _1.AggregatesClient(type, this.config); | ||
}; | ||
SerializedInstance.prototype.projectionsClient = function () { | ||
return new _1.ProjectionsClient(this.config); | ||
}; | ||
SerializedInstance.prototype.feedsClient = function () { | ||
return new _1.FeedsClient(this.config); | ||
}; | ||
SerializedInstance.prototype.reactionsClient = function () { | ||
return new _1.ReactionsClient(this.config); | ||
}; | ||
return SerializedInstance; | ||
}()); | ||
exports.SerializedInstance = SerializedInstance; |
@@ -6,3 +6,3 @@ { | ||
"author": "Mattias Holmqvist", | ||
"version": "2.2.0", | ||
"version": "3.0.0", | ||
"main": "dist/index.js", | ||
@@ -34,7 +34,7 @@ "types": "dist/index.d.ts", | ||
"axios": "^0.19.2", | ||
"uuid": "^7.0.2" | ||
"uuid": "^8.3.0", | ||
"@types/uuid": "^8.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^25.2.1", | ||
"@types/uuid": "^7.0.2", | ||
"axios-mock-adapter": "^1.17.0", | ||
@@ -41,0 +41,0 @@ "jest": "^25.1.0", |
106
README.md
@@ -23,8 +23,7 @@ # Serialized Javascript & Typescript client | ||
Then, import the library and initialize the client instance: | ||
Import the library and initialize the client instance: | ||
```typescript | ||
import {Serialized} from "@serialized/serialized-client" | ||
```js | ||
var {Serialized} = require("@serialized/serialized-client") | ||
var uuidv4 = require("uuid").v4 | ||
var serialized = Serialized.create({ | ||
const serialized = Serialized.create({ | ||
accessKey: "<YOUR_ACCESS_KEY>", | ||
@@ -35,18 +34,89 @@ secretAccessKey: "<YOUR_SECRET_ACCESS_KEY>" | ||
Test the client by storing an event: | ||
```js | ||
var aggregateClient = serialized.aggregates; | ||
var request = { | ||
aggregateType: 'user-registration', | ||
aggregateId: uuidv4(), | ||
event: { | ||
eventType: 'UserRegistrationStarted', | ||
data: { | ||
email: 'johndoe@example.com' | ||
} | ||
} | ||
## Create our domain | ||
### State | ||
The state type holds the assembled state from the events during the load of the aggregate. | ||
```typescript | ||
// The different statuses our game can be in | ||
enum GameStatus { | ||
UNDEFINED = 'UNDEFINED', | ||
CREATED = 'CREATED', | ||
STARTED = 'STARTED', | ||
FINISHED = 'FINISHED' | ||
} | ||
type GameState = { | ||
readonly gameId?: string; | ||
readonly status?: GameStatus; | ||
} | ||
``` | ||
Next, we create the state builder, which handles the loaded events one-by-one to create the current state. | ||
The state builder has methods decorated with `@EventHandler` to mark its event handling methods: | ||
```typescript | ||
class GameStateBuilder { | ||
get initialState(): GameState { | ||
return { | ||
status: GameStatus.UNDEFINED | ||
} | ||
await aggregateClient.storeEvent(request) | ||
} | ||
@EventHandler(GameCreated) | ||
handleGameCreated(event: GameCreated, state: GameState): GameState { | ||
return {gameId: state.gameId, status: GameStatus.CREATED}; | ||
} | ||
@EventHandler(GameStarted) | ||
handleGameStarted(event: GameStarted, state: GameState): GameState { | ||
return {...state, status: GameStatus.STARTED}; | ||
} | ||
} | ||
``` | ||
## Aggregate | ||
The aggregate contains the domain logic and each method should return `0..n` events that should be stored for a successful operation. | ||
Any unsuccessful operation should throw an error. | ||
```typescript | ||
@Aggregate('game', GameStateBuilder) | ||
class Game { | ||
constructor(private readonly state: GameState) { | ||
} | ||
create(gameId: string, creationTime: number) { | ||
return [new GameCreated(gameId, creationTime)]; | ||
} | ||
start(gameId: string, startTime: number) { | ||
if(this.state.status !== GameStatus.CREATED) { | ||
throw new Error('Must create Game before you can start it'); | ||
} | ||
return [new GameStarted(gameId, startTime)]; | ||
} | ||
} | ||
``` | ||
Test the client by creating a `Game`: | ||
```typescript | ||
const gameClient = serialized.aggregateClient(Game); | ||
const gameId = uuidv4(); | ||
await gameClient.create(gameId, (game) => ({ | ||
events: game.create(gameId, Date.now()) | ||
})); | ||
``` | ||
To perform an `update` operation, which means loading all events, performing business logic and then appending more events | ||
```typescript | ||
await gameClient.update(gameId, (game: Game) => | ||
({events: game.start(gameId, startTime)})); | ||
``` | ||
## 📄 Client reference | ||
@@ -53,0 +123,0 @@ |
59401
5
1210
134
3
+ Added@types/uuid@^8.3.0
+ Added@types/uuid@8.3.4(transitive)
+ Addeduuid@8.3.2(transitive)
- Removeduuid@7.0.3(transitive)
Updateduuid@^8.3.0