@fluidframework/protocol-base
Advanced tools
Comparing version 0.1037.1000-73492 to 0.1037.1000-75661
@@ -8,3 +8,3 @@ /*! | ||
export declare const pkgName = "@fluidframework/protocol-base"; | ||
export declare const pkgVersion = "0.1037.1000-73492"; | ||
export declare const pkgVersion = "0.1037.1000-75661"; | ||
//# sourceMappingURL=packageVersion.d.ts.map |
@@ -11,3 +11,3 @@ "use strict"; | ||
exports.pkgName = "@fluidframework/protocol-base"; | ||
exports.pkgVersion = "0.1037.1000-73492"; | ||
exports.pkgVersion = "0.1037.1000-75661"; | ||
//# sourceMappingURL=packageVersion.js.map |
@@ -5,4 +5,4 @@ /*! | ||
*/ | ||
import { ICommittedProposal, IProcessMessageResult, ISequencedClient, ISequencedDocumentMessage, ISequencedProposal } from "@fluidframework/protocol-definitions"; | ||
import { Quorum } from "./quorum"; | ||
import { IDocumentAttributes, ICommittedProposal, IProcessMessageResult, IQuorum, ISequencedClient, ISequencedDocumentMessage, ISequencedProposal } from "@fluidframework/protocol-definitions"; | ||
import { IQuorumSnapshot, Quorum } from "./quorum"; | ||
export interface IScribeProtocolState { | ||
@@ -16,11 +16,30 @@ sequenceNumber: number; | ||
export declare function isSystemMessage(message: ISequencedDocumentMessage): boolean; | ||
export interface ILocalSequencedClient extends ISequencedClient { | ||
/** | ||
* True if the client should have left the quorum, false otherwise | ||
*/ | ||
shouldHaveLeft?: boolean; | ||
} | ||
export interface IProtocolHandler { | ||
readonly quorum: IQuorum; | ||
readonly attributes: IDocumentAttributes; | ||
setConnectionState(connected: boolean, clientId: string | undefined): any; | ||
snapshot(): IQuorumSnapshot; | ||
close(): void; | ||
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
getProtocolState(): IScribeProtocolState; | ||
} | ||
/** | ||
* Handles protocol specific ops. | ||
*/ | ||
export declare class ProtocolOpHandler { | ||
export declare class ProtocolOpHandler implements IProtocolHandler { | ||
minimumSequenceNumber: number; | ||
sequenceNumber: number; | ||
readonly quorum: Quorum; | ||
readonly _quorum: Quorum; | ||
get quorum(): Quorum; | ||
readonly term: number; | ||
constructor(minimumSequenceNumber: number, sequenceNumber: number, term: number | undefined, members: [string, ISequencedClient][], proposals: [number, ISequencedProposal, string[]][], values: [string, ICommittedProposal][], sendProposal: (key: string, value: any) => number); | ||
get attributes(): IDocumentAttributes; | ||
setConnectionState(connected: boolean, clientId: string | undefined): void; | ||
snapshot(): IQuorumSnapshot; | ||
close(): void; | ||
@@ -33,2 +52,5 @@ processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
} | ||
export declare class ProtocolOpHandlerWithClientValidation extends ProtocolOpHandler { | ||
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
} | ||
//# sourceMappingURL=protocol.d.ts.map |
@@ -7,3 +7,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ProtocolOpHandler = exports.isSystemMessage = void 0; | ||
exports.ProtocolOpHandlerWithClientValidation = exports.ProtocolOpHandler = exports.isSystemMessage = void 0; | ||
const protocol_definitions_1 = require("@fluidframework/protocol-definitions"); | ||
@@ -36,6 +36,22 @@ const quorum_1 = require("./quorum"); | ||
this.term = term !== null && term !== void 0 ? term : 1; | ||
this.quorum = new quorum_1.Quorum(members, proposals, values, sendProposal); | ||
this._quorum = new quorum_1.Quorum(members, proposals, values, sendProposal); | ||
} | ||
get quorum() { | ||
return this._quorum; | ||
} | ||
get attributes() { | ||
return { | ||
minimumSequenceNumber: this.minimumSequenceNumber, | ||
sequenceNumber: this.sequenceNumber, | ||
term: this.term, | ||
}; | ||
} | ||
setConnectionState(connected, clientId) { | ||
this._quorum.setConnectionState(connected, clientId); | ||
} | ||
snapshot() { | ||
return this._quorum.snapshot(); | ||
} | ||
close() { | ||
this.quorum.close(); | ||
this._quorum.close(); | ||
} | ||
@@ -60,3 +76,3 @@ processMessage(message, local) { | ||
}; | ||
this.quorum.addMember(join.clientId, member); | ||
this._quorum.addMember(join.clientId, member); | ||
break; | ||
@@ -66,7 +82,7 @@ case protocol_definitions_1.MessageType.ClientLeave: | ||
const clientId = JSON.parse(systemLeaveMessage.data); | ||
this.quorum.removeMember(clientId); | ||
this._quorum.removeMember(clientId); | ||
break; | ||
case protocol_definitions_1.MessageType.Propose: | ||
const proposal = message.contents; | ||
this.quorum.addProposal(proposal.key, proposal.value, message.sequenceNumber, local, message.clientSequenceNumber); | ||
this._quorum.addProposal(proposal.key, proposal.value, message.sequenceNumber, local, message.clientSequenceNumber); | ||
// On a quorum proposal, immediately send a response to expedite the approval. | ||
@@ -81,3 +97,3 @@ immediateNoOp = true; | ||
// want to move that logic to this class. | ||
this.quorum.updateMinimumSequenceNumber(message); | ||
this._quorum.updateMinimumSequenceNumber(message); | ||
return { immediateNoOp }; | ||
@@ -91,6 +107,25 @@ } | ||
// this ensures future state changes will not affect outside callers | ||
return Object.assign({ sequenceNumber: this.sequenceNumber, minimumSequenceNumber: this.minimumSequenceNumber }, this.quorum.snapshot()); | ||
return Object.assign({ sequenceNumber: this.sequenceNumber, minimumSequenceNumber: this.minimumSequenceNumber }, this._quorum.snapshot()); | ||
} | ||
} | ||
exports.ProtocolOpHandler = ProtocolOpHandler; | ||
class ProtocolOpHandlerWithClientValidation extends ProtocolOpHandler { | ||
processMessage(message, local) { | ||
const client = this._quorum.getMember(message.clientId); | ||
// Check and report if we're getting messages from a clientId that we previously | ||
// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be | ||
if (message.clientId != null) { | ||
if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) { | ||
// pre-0.58 error message: messageClientIdMissingFromQuorum | ||
throw new Error("Remote message's clientId is missing from the quorum"); | ||
} | ||
if ((client === null || client === void 0 ? void 0 : client.shouldHaveLeft) === true && message.type !== protocol_definitions_1.MessageType.NoOp) { | ||
// pre-0.58 error message: messageClientIdShouldHaveLeft | ||
throw new Error("Remote message's clientId already should have left"); | ||
} | ||
} | ||
return super.processMessage(message, local); | ||
} | ||
} | ||
exports.ProtocolOpHandlerWithClientValidation = ProtocolOpHandlerWithClientValidation; | ||
//# sourceMappingURL=protocol.js.map |
@@ -8,3 +8,3 @@ /*! | ||
export declare const pkgName = "@fluidframework/protocol-base"; | ||
export declare const pkgVersion = "0.1037.1000-73492"; | ||
export declare const pkgVersion = "0.1037.1000-75661"; | ||
//# sourceMappingURL=packageVersion.d.ts.map |
@@ -8,3 +8,3 @@ /*! | ||
export const pkgName = "@fluidframework/protocol-base"; | ||
export const pkgVersion = "0.1037.1000-73492"; | ||
export const pkgVersion = "0.1037.1000-75661"; | ||
//# sourceMappingURL=packageVersion.js.map |
@@ -5,4 +5,4 @@ /*! | ||
*/ | ||
import { ICommittedProposal, IProcessMessageResult, ISequencedClient, ISequencedDocumentMessage, ISequencedProposal } from "@fluidframework/protocol-definitions"; | ||
import { Quorum } from "./quorum"; | ||
import { IDocumentAttributes, ICommittedProposal, IProcessMessageResult, IQuorum, ISequencedClient, ISequencedDocumentMessage, ISequencedProposal } from "@fluidframework/protocol-definitions"; | ||
import { IQuorumSnapshot, Quorum } from "./quorum"; | ||
export interface IScribeProtocolState { | ||
@@ -16,11 +16,30 @@ sequenceNumber: number; | ||
export declare function isSystemMessage(message: ISequencedDocumentMessage): boolean; | ||
export interface ILocalSequencedClient extends ISequencedClient { | ||
/** | ||
* True if the client should have left the quorum, false otherwise | ||
*/ | ||
shouldHaveLeft?: boolean; | ||
} | ||
export interface IProtocolHandler { | ||
readonly quorum: IQuorum; | ||
readonly attributes: IDocumentAttributes; | ||
setConnectionState(connected: boolean, clientId: string | undefined): any; | ||
snapshot(): IQuorumSnapshot; | ||
close(): void; | ||
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
getProtocolState(): IScribeProtocolState; | ||
} | ||
/** | ||
* Handles protocol specific ops. | ||
*/ | ||
export declare class ProtocolOpHandler { | ||
export declare class ProtocolOpHandler implements IProtocolHandler { | ||
minimumSequenceNumber: number; | ||
sequenceNumber: number; | ||
readonly quorum: Quorum; | ||
readonly _quorum: Quorum; | ||
get quorum(): Quorum; | ||
readonly term: number; | ||
constructor(minimumSequenceNumber: number, sequenceNumber: number, term: number | undefined, members: [string, ISequencedClient][], proposals: [number, ISequencedProposal, string[]][], values: [string, ICommittedProposal][], sendProposal: (key: string, value: any) => number); | ||
get attributes(): IDocumentAttributes; | ||
setConnectionState(connected: boolean, clientId: string | undefined): void; | ||
snapshot(): IQuorumSnapshot; | ||
close(): void; | ||
@@ -33,2 +52,5 @@ processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
} | ||
export declare class ProtocolOpHandlerWithClientValidation extends ProtocolOpHandler { | ||
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
} | ||
//# sourceMappingURL=protocol.d.ts.map |
@@ -31,6 +31,22 @@ /*! | ||
this.term = term !== null && term !== void 0 ? term : 1; | ||
this.quorum = new Quorum(members, proposals, values, sendProposal); | ||
this._quorum = new Quorum(members, proposals, values, sendProposal); | ||
} | ||
get quorum() { | ||
return this._quorum; | ||
} | ||
get attributes() { | ||
return { | ||
minimumSequenceNumber: this.minimumSequenceNumber, | ||
sequenceNumber: this.sequenceNumber, | ||
term: this.term, | ||
}; | ||
} | ||
setConnectionState(connected, clientId) { | ||
this._quorum.setConnectionState(connected, clientId); | ||
} | ||
snapshot() { | ||
return this._quorum.snapshot(); | ||
} | ||
close() { | ||
this.quorum.close(); | ||
this._quorum.close(); | ||
} | ||
@@ -55,3 +71,3 @@ processMessage(message, local) { | ||
}; | ||
this.quorum.addMember(join.clientId, member); | ||
this._quorum.addMember(join.clientId, member); | ||
break; | ||
@@ -61,7 +77,7 @@ case MessageType.ClientLeave: | ||
const clientId = JSON.parse(systemLeaveMessage.data); | ||
this.quorum.removeMember(clientId); | ||
this._quorum.removeMember(clientId); | ||
break; | ||
case MessageType.Propose: | ||
const proposal = message.contents; | ||
this.quorum.addProposal(proposal.key, proposal.value, message.sequenceNumber, local, message.clientSequenceNumber); | ||
this._quorum.addProposal(proposal.key, proposal.value, message.sequenceNumber, local, message.clientSequenceNumber); | ||
// On a quorum proposal, immediately send a response to expedite the approval. | ||
@@ -76,3 +92,3 @@ immediateNoOp = true; | ||
// want to move that logic to this class. | ||
this.quorum.updateMinimumSequenceNumber(message); | ||
this._quorum.updateMinimumSequenceNumber(message); | ||
return { immediateNoOp }; | ||
@@ -86,5 +102,23 @@ } | ||
// this ensures future state changes will not affect outside callers | ||
return Object.assign({ sequenceNumber: this.sequenceNumber, minimumSequenceNumber: this.minimumSequenceNumber }, this.quorum.snapshot()); | ||
return Object.assign({ sequenceNumber: this.sequenceNumber, minimumSequenceNumber: this.minimumSequenceNumber }, this._quorum.snapshot()); | ||
} | ||
} | ||
export class ProtocolOpHandlerWithClientValidation extends ProtocolOpHandler { | ||
processMessage(message, local) { | ||
const client = this._quorum.getMember(message.clientId); | ||
// Check and report if we're getting messages from a clientId that we previously | ||
// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be | ||
if (message.clientId != null) { | ||
if (client === undefined && message.type !== MessageType.ClientJoin) { | ||
// pre-0.58 error message: messageClientIdMissingFromQuorum | ||
throw new Error("Remote message's clientId is missing from the quorum"); | ||
} | ||
if ((client === null || client === void 0 ? void 0 : client.shouldHaveLeft) === true && message.type !== MessageType.NoOp) { | ||
// pre-0.58 error message: messageClientIdShouldHaveLeft | ||
throw new Error("Remote message's clientId already should have left"); | ||
} | ||
} | ||
return super.processMessage(message, local); | ||
} | ||
} | ||
//# sourceMappingURL=protocol.js.map |
{ | ||
"name": "@fluidframework/protocol-base", | ||
"version": "0.1037.1000-73492", | ||
"version": "0.1037.1000-75661", | ||
"description": "Fluid protocol base", | ||
@@ -62,3 +62,3 @@ "homepage": "https://fluidframework.com", | ||
"@fluidframework/common-utils": "^0.32.1", | ||
"@fluidframework/gitresources": "0.1037.1000-73492", | ||
"@fluidframework/gitresources": "0.1037.1000-75661", | ||
"@fluidframework/protocol-definitions": "^0.1029.1000-0", | ||
@@ -65,0 +65,0 @@ "lodash": "^4.17.21" |
@@ -9,2 +9,2 @@ /*! | ||
export const pkgName = "@fluidframework/protocol-base"; | ||
export const pkgVersion = "0.1037.1000-73492"; | ||
export const pkgVersion = "0.1037.1000-75661"; |
@@ -7,2 +7,3 @@ /*! | ||
import { | ||
IDocumentAttributes, | ||
IClientJoin, | ||
@@ -12,2 +13,3 @@ ICommittedProposal, | ||
IProposal, | ||
IQuorum, | ||
ISequencedClient, | ||
@@ -19,3 +21,3 @@ ISequencedDocumentMessage, | ||
} from "@fluidframework/protocol-definitions"; | ||
import { Quorum } from "./quorum"; | ||
import { IQuorumSnapshot, Quorum } from "./quorum"; | ||
@@ -47,7 +49,30 @@ export interface IScribeProtocolState { | ||
export interface ILocalSequencedClient extends ISequencedClient { | ||
/** | ||
* True if the client should have left the quorum, false otherwise | ||
*/ | ||
shouldHaveLeft?: boolean; | ||
} | ||
export interface IProtocolHandler { | ||
readonly quorum: IQuorum; | ||
readonly attributes: IDocumentAttributes; | ||
setConnectionState(connected: boolean, clientId: string | undefined); | ||
snapshot(): IQuorumSnapshot; | ||
close(): void; | ||
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult; | ||
getProtocolState(): IScribeProtocolState; | ||
} | ||
/** | ||
* Handles protocol specific ops. | ||
*/ | ||
export class ProtocolOpHandler { | ||
public readonly quorum: Quorum; | ||
export class ProtocolOpHandler implements IProtocolHandler { | ||
public readonly _quorum: Quorum; | ||
public get quorum(): Quorum { | ||
return this._quorum; | ||
} | ||
public readonly term: number; | ||
@@ -65,3 +90,3 @@ | ||
this.term = term ?? 1; | ||
this.quorum = new Quorum( | ||
this._quorum = new Quorum( | ||
members, | ||
@@ -74,4 +99,20 @@ proposals, | ||
public get attributes(): IDocumentAttributes { | ||
return { | ||
minimumSequenceNumber: this.minimumSequenceNumber, | ||
sequenceNumber: this.sequenceNumber, | ||
term: this.term, | ||
}; | ||
} | ||
setConnectionState(connected: boolean, clientId: string | undefined) { | ||
this._quorum.setConnectionState(connected, clientId); | ||
} | ||
snapshot(): IQuorumSnapshot { | ||
return this._quorum.snapshot(); | ||
} | ||
public close() { | ||
this.quorum.close(); | ||
this._quorum.close(); | ||
} | ||
@@ -101,3 +142,3 @@ | ||
}; | ||
this.quorum.addMember(join.clientId, member); | ||
this._quorum.addMember(join.clientId, member); | ||
break; | ||
@@ -108,3 +149,3 @@ | ||
const clientId = JSON.parse(systemLeaveMessage.data) as string; | ||
this.quorum.removeMember(clientId); | ||
this._quorum.removeMember(clientId); | ||
break; | ||
@@ -114,3 +155,3 @@ | ||
const proposal = message.contents as IProposal; | ||
this.quorum.addProposal( | ||
this._quorum.addProposal( | ||
proposal.key, | ||
@@ -134,3 +175,3 @@ proposal.value, | ||
// want to move that logic to this class. | ||
this.quorum.updateMinimumSequenceNumber(message); | ||
this._quorum.updateMinimumSequenceNumber(message); | ||
@@ -149,5 +190,27 @@ return { immediateNoOp }; | ||
minimumSequenceNumber: this.minimumSequenceNumber, | ||
...this.quorum.snapshot(), | ||
...this._quorum.snapshot(), | ||
}; | ||
} | ||
} | ||
export class ProtocolOpHandlerWithClientValidation extends ProtocolOpHandler { | ||
public processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult { | ||
const client: ILocalSequencedClient | undefined = this._quorum.getMember(message.clientId); | ||
// Check and report if we're getting messages from a clientId that we previously | ||
// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be | ||
if (message.clientId != null) { | ||
if (client === undefined && message.type !== MessageType.ClientJoin) { | ||
// pre-0.58 error message: messageClientIdMissingFromQuorum | ||
throw new Error("Remote message's clientId is missing from the quorum"); | ||
} | ||
if (client?.shouldHaveLeft === true && message.type !== MessageType.NoOp) { | ||
// pre-0.58 error message: messageClientIdShouldHaveLeft | ||
throw new Error("Remote message's clientId already should have left"); | ||
} | ||
} | ||
return super.processMessage(message, local); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
259754
3266
+ Added@fluidframework/gitresources@0.1037.1000-75661(transitive)
- Removed@fluidframework/gitresources@0.1037.1000-73492(transitive)