@voidhash/mimic 0.0.1-alpha.4 → 0.0.1-alpha.6
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/.turbo/turbo-build.log +13 -13
- package/dist/index.cjs +35 -9
- package/dist/index.d.cts +45 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +45 -16
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +35 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/client/ClientDocument.ts +1 -1
- package/src/client/errors.ts +10 -10
- package/src/primitives/Boolean.ts +1 -1
- package/src/primitives/Literal.ts +1 -1
- package/src/primitives/Number.ts +1 -1
- package/src/primitives/String.ts +1 -1
- package/src/primitives/Struct.ts +2 -2
- package/src/primitives/Tree.ts +2 -2
- package/src/primitives/TreeNode.ts +69 -28
- package/src/primitives/Union.ts +1 -1
- package/src/server/errors.ts +6 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidhash/mimic",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"typescript": "5.8.3",
|
|
20
20
|
"vite-tsconfig-paths": "^5.1.4",
|
|
21
21
|
"vitest": "^3.2.4",
|
|
22
|
-
"@voidhash/tsconfig": "0.0.1-alpha.
|
|
22
|
+
"@voidhash/tsconfig": "0.0.1-alpha.6"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"effect": "^3.19.12"
|
|
@@ -43,7 +43,7 @@ type InitState =
|
|
|
43
43
|
/**
|
|
44
44
|
* Listener for presence changes.
|
|
45
45
|
*/
|
|
46
|
-
export interface PresenceListener<
|
|
46
|
+
export interface PresenceListener<_TData> {
|
|
47
47
|
/** Called when any presence changes (self or others) */
|
|
48
48
|
readonly onPresenceChange?: () => void;
|
|
49
49
|
}
|
package/src/client/errors.ts
CHANGED
|
@@ -19,7 +19,7 @@ export class MimicClientError extends Error {
|
|
|
19
19
|
* Error thrown when a transaction is rejected by the server.
|
|
20
20
|
*/
|
|
21
21
|
export class TransactionRejectedError extends MimicClientError {
|
|
22
|
-
readonly _tag = "TransactionRejectedError";
|
|
22
|
+
override readonly _tag = "TransactionRejectedError";
|
|
23
23
|
readonly transaction: Transaction.Transaction;
|
|
24
24
|
readonly reason: string;
|
|
25
25
|
|
|
@@ -35,7 +35,7 @@ export class TransactionRejectedError extends MimicClientError {
|
|
|
35
35
|
* Error thrown when the transport is not connected.
|
|
36
36
|
*/
|
|
37
37
|
export class NotConnectedError extends MimicClientError {
|
|
38
|
-
readonly _tag = "NotConnectedError";
|
|
38
|
+
override readonly _tag = "NotConnectedError";
|
|
39
39
|
constructor() {
|
|
40
40
|
super("Transport is not connected");
|
|
41
41
|
this.name = "NotConnectedError";
|
|
@@ -46,8 +46,8 @@ export class NotConnectedError extends MimicClientError {
|
|
|
46
46
|
* Error thrown when connection to the server fails.
|
|
47
47
|
*/
|
|
48
48
|
export class ConnectionError extends MimicClientError {
|
|
49
|
-
readonly _tag = "ConnectionError";
|
|
50
|
-
readonly cause?: Error;
|
|
49
|
+
override readonly _tag = "ConnectionError";
|
|
50
|
+
override readonly cause?: Error;
|
|
51
51
|
|
|
52
52
|
constructor(message: string, cause?: Error) {
|
|
53
53
|
super(message);
|
|
@@ -60,7 +60,7 @@ export class ConnectionError extends MimicClientError {
|
|
|
60
60
|
* Error thrown when state drift is detected and cannot be recovered.
|
|
61
61
|
*/
|
|
62
62
|
export class StateDriftError extends MimicClientError {
|
|
63
|
-
readonly _tag = "StateDriftError";
|
|
63
|
+
override readonly _tag = "StateDriftError";
|
|
64
64
|
readonly expectedVersion: number;
|
|
65
65
|
readonly receivedVersion: number;
|
|
66
66
|
|
|
@@ -78,7 +78,7 @@ export class StateDriftError extends MimicClientError {
|
|
|
78
78
|
* Error thrown when a pending transaction times out waiting for confirmation.
|
|
79
79
|
*/
|
|
80
80
|
export class TransactionTimeoutError extends MimicClientError {
|
|
81
|
-
readonly _tag = "TransactionTimeoutError";
|
|
81
|
+
override readonly _tag = "TransactionTimeoutError";
|
|
82
82
|
readonly transaction: Transaction.Transaction;
|
|
83
83
|
readonly timeoutMs: number;
|
|
84
84
|
|
|
@@ -96,7 +96,7 @@ export class TransactionTimeoutError extends MimicClientError {
|
|
|
96
96
|
* Error thrown when rebasing operations fails.
|
|
97
97
|
*/
|
|
98
98
|
export class RebaseError extends MimicClientError {
|
|
99
|
-
readonly _tag = "RebaseError";
|
|
99
|
+
override readonly _tag = "RebaseError";
|
|
100
100
|
readonly transactionId: string;
|
|
101
101
|
|
|
102
102
|
constructor(transactionId: string, message: string) {
|
|
@@ -110,7 +110,7 @@ export class RebaseError extends MimicClientError {
|
|
|
110
110
|
* Error thrown when the client document is in an invalid state.
|
|
111
111
|
*/
|
|
112
112
|
export class InvalidStateError extends MimicClientError {
|
|
113
|
-
readonly _tag = "InvalidStateError";
|
|
113
|
+
override readonly _tag = "InvalidStateError";
|
|
114
114
|
constructor(message: string) {
|
|
115
115
|
super(message);
|
|
116
116
|
this.name = "InvalidStateError";
|
|
@@ -121,7 +121,7 @@ export class InvalidStateError extends MimicClientError {
|
|
|
121
121
|
* Error thrown when WebSocket connection or communication fails.
|
|
122
122
|
*/
|
|
123
123
|
export class WebSocketError extends MimicClientError {
|
|
124
|
-
readonly _tag = "WebSocketError";
|
|
124
|
+
override readonly _tag = "WebSocketError";
|
|
125
125
|
readonly code?: number;
|
|
126
126
|
readonly reason?: string;
|
|
127
127
|
|
|
@@ -137,7 +137,7 @@ export class WebSocketError extends MimicClientError {
|
|
|
137
137
|
* Error thrown when authentication fails.
|
|
138
138
|
*/
|
|
139
139
|
export class AuthenticationError extends MimicClientError {
|
|
140
|
-
readonly _tag = "AuthenticationError";
|
|
140
|
+
override readonly _tag = "AuthenticationError";
|
|
141
141
|
constructor(message: string) {
|
|
142
142
|
super(message);
|
|
143
143
|
this.name = "AuthenticationError";
|
|
@@ -87,7 +87,7 @@ export class BooleanPrimitive<TDefined extends boolean = false> implements Primi
|
|
|
87
87
|
};
|
|
88
88
|
},
|
|
89
89
|
|
|
90
|
-
applyOperation: (
|
|
90
|
+
applyOperation: (_state: boolean | undefined, operation: Operation.Operation<any, any, any>): boolean => {
|
|
91
91
|
if (operation.kind !== "boolean.set") {
|
|
92
92
|
throw new ValidationError(`BooleanPrimitive cannot apply operation of kind: ${operation.kind}`);
|
|
93
93
|
}
|
|
@@ -88,7 +88,7 @@ export class LiteralPrimitive<T extends LiteralValue, TDefined extends boolean =
|
|
|
88
88
|
};
|
|
89
89
|
},
|
|
90
90
|
|
|
91
|
-
applyOperation: (
|
|
91
|
+
applyOperation: (_state: T | undefined, operation: Operation.Operation<any, any, any>): T => {
|
|
92
92
|
if (operation.kind !== "literal.set") {
|
|
93
93
|
throw new ValidationError(`LiteralPrimitive cannot apply operation of kind: ${operation.kind}`);
|
|
94
94
|
}
|
package/src/primitives/Number.ts
CHANGED
|
@@ -128,7 +128,7 @@ export class NumberPrimitive<TDefined extends boolean = false> implements Primit
|
|
|
128
128
|
};
|
|
129
129
|
},
|
|
130
130
|
|
|
131
|
-
applyOperation: (
|
|
131
|
+
applyOperation: (_state: number | undefined, operation: Operation.Operation<any, any, any>): number => {
|
|
132
132
|
if (operation.kind !== "number.set") {
|
|
133
133
|
throw new ValidationError(`NumberPrimitive cannot apply operation of kind: ${operation.kind}`);
|
|
134
134
|
}
|
package/src/primitives/String.ts
CHANGED
|
@@ -147,7 +147,7 @@ export class StringPrimitive<TDefined extends boolean = false> implements Primit
|
|
|
147
147
|
};
|
|
148
148
|
},
|
|
149
149
|
|
|
150
|
-
applyOperation: (
|
|
150
|
+
applyOperation: (_state: string | undefined, operation: Operation.Operation<any, any, any>): string => {
|
|
151
151
|
if (!isCompatibleOperation(operation, this._opDefinitions)) {
|
|
152
152
|
throw new ValidationError(`StringPrimitive cannot apply operation of kind: ${operation.kind}`);
|
|
153
153
|
}
|
package/src/primitives/Struct.ts
CHANGED
|
@@ -149,7 +149,7 @@ export class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TDefi
|
|
|
149
149
|
|
|
150
150
|
// Use a JavaScript Proxy to intercept field access
|
|
151
151
|
return new globalThis.Proxy(base as StructProxy<TFields, TDefined>, {
|
|
152
|
-
get: (target, prop,
|
|
152
|
+
get: (target, prop, _receiver) => {
|
|
153
153
|
// Return base methods (get, set, toSnapshot)
|
|
154
154
|
if (prop === "get") {
|
|
155
155
|
return target.get;
|
|
@@ -175,7 +175,7 @@ export class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TDefi
|
|
|
175
175
|
|
|
176
176
|
return undefined;
|
|
177
177
|
},
|
|
178
|
-
has: (
|
|
178
|
+
has: (_target, prop) => {
|
|
179
179
|
if (prop === "get" || prop === "set" || prop === "toSnapshot") return true;
|
|
180
180
|
if (typeof prop === "string" && prop in fields) return true;
|
|
181
181
|
return false;
|
package/src/primitives/Tree.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface TypedTreeNodeState<TNode extends AnyTreeNodePrimitive> {
|
|
|
37
37
|
/**
|
|
38
38
|
* The state type for trees - a flat array of nodes
|
|
39
39
|
*/
|
|
40
|
-
export type TreeState<
|
|
40
|
+
export type TreeState<_TRoot extends AnyTreeNodePrimitive> = readonly TreeNodeState[];
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Helper to get children sorted by position
|
|
@@ -122,7 +122,7 @@ export interface TypedNodeProxy<TNode extends AnyTreeNodePrimitive> {
|
|
|
122
122
|
/**
|
|
123
123
|
* Node proxy with type narrowing capabilities
|
|
124
124
|
*/
|
|
125
|
-
export interface TreeNodeProxyBase<
|
|
125
|
+
export interface TreeNodeProxyBase<_TRoot extends AnyTreeNodePrimitive> {
|
|
126
126
|
/** The node ID */
|
|
127
127
|
readonly id: string;
|
|
128
128
|
/** The node type (string) */
|
|
@@ -1,23 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as OperationDefinition from "../OperationDefinition";
|
|
3
|
-
import * as Operation from "../Operation";
|
|
4
|
-
import * as OperationPath from "../OperationPath";
|
|
5
|
-
import * as ProxyEnvironment from "../ProxyEnvironment";
|
|
6
|
-
import * as Transform from "../Transform";
|
|
7
|
-
import type { AnyPrimitive, InferState } from "../Primitive";
|
|
1
|
+
import type { InferState } from "../Primitive";
|
|
8
2
|
import { StructPrimitive } from "./Struct";
|
|
9
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Symbol used to identify the Self placeholder
|
|
6
|
+
*/
|
|
7
|
+
const TreeNodeSelfSymbol = Symbol.for("TreeNode.Self");
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
|
-
*
|
|
10
|
+
* Branded type for TreeNodeSelf - distinguishable at compile time
|
|
11
|
+
*/
|
|
12
|
+
declare const SelfBrand: unique symbol;
|
|
13
|
+
export interface TreeNodeSelfType {
|
|
14
|
+
readonly _tag: "TreeNodeSelf";
|
|
15
|
+
readonly _brand: typeof SelfBrand;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Special placeholder for self-referential tree nodes.
|
|
20
|
+
* Use this in the children array when a node type can contain itself.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const FolderNode = TreeNode("folder", {
|
|
25
|
+
* data: Struct({ name: String() }),
|
|
26
|
+
* children: [TreeNodeSelf], // Folder can contain other folders
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const TreeNodeSelf: TreeNodeSelfType = { _tag: "TreeNodeSelf", _symbol: TreeNodeSelfSymbol } as unknown as TreeNodeSelfType;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if a value is the Self placeholder
|
|
13
34
|
*/
|
|
14
|
-
|
|
35
|
+
const isSelf = (value: unknown): boolean => {
|
|
36
|
+
return typeof value === "object" && value !== null && "_symbol" in value && (value as any)._symbol === TreeNodeSelfSymbol;
|
|
37
|
+
};
|
|
15
38
|
|
|
16
39
|
/**
|
|
17
|
-
*
|
|
40
|
+
* Type utility to resolve Self placeholders to the actual node type
|
|
41
|
+
*/
|
|
42
|
+
type ResolveSelf<T, TSelf extends AnyTreeNodePrimitive> =
|
|
43
|
+
T extends TreeNodeSelfType ? TSelf : T;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type utility to resolve all children in a tuple, replacing Self with the node type
|
|
47
|
+
*/
|
|
48
|
+
type ResolveChildrenUnion<TChildren, TSelf extends AnyTreeNodePrimitive> =
|
|
49
|
+
TChildren extends readonly (infer U)[]
|
|
50
|
+
? ResolveSelf<U, TSelf>
|
|
51
|
+
: never;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The type for children - either a direct array or a lazy function (for self-referential nodes).
|
|
55
|
+
*/
|
|
56
|
+
export type TreeNodeChildrenInput = readonly (AnyTreeNodePrimitive | TreeNodeSelfType)[] | (() => readonly (AnyTreeNodePrimitive | TreeNodeSelfType)[]);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Any TreeNodePrimitive type - used for generic constraints.
|
|
18
60
|
*/
|
|
19
|
-
export type
|
|
20
|
-
TChildren extends () => readonly AnyTreeNodePrimitive[] ? ReturnType<TChildren> : TChildren;
|
|
61
|
+
export type AnyTreeNodePrimitive = TreeNodePrimitive<string, StructPrimitive<any>, any>;
|
|
21
62
|
|
|
22
63
|
/**
|
|
23
64
|
* Infer the data state type from a TreeNodePrimitive
|
|
@@ -34,18 +75,18 @@ export type InferTreeNodeType<T extends AnyTreeNodePrimitive> =
|
|
|
34
75
|
/**
|
|
35
76
|
* Infer the allowed children from a TreeNodePrimitive
|
|
36
77
|
*/
|
|
37
|
-
export type InferTreeNodeChildren<T
|
|
38
|
-
T extends TreeNodePrimitive<any, any, infer TChildren> ?
|
|
78
|
+
export type InferTreeNodeChildren<T> =
|
|
79
|
+
T extends TreeNodePrimitive<any, any, infer TChildren> ? TChildren : never;
|
|
39
80
|
|
|
40
81
|
/**
|
|
41
82
|
* Configuration for a TreeNode primitive
|
|
42
83
|
*/
|
|
43
84
|
export interface TreeNodeConfig<
|
|
44
85
|
TData extends StructPrimitive<any>,
|
|
45
|
-
TChildren extends readonly AnyTreeNodePrimitive
|
|
86
|
+
TChildren extends readonly (AnyTreeNodePrimitive | TreeNodeSelfType)[]
|
|
46
87
|
> {
|
|
47
88
|
readonly data: TData;
|
|
48
|
-
readonly children: TChildren;
|
|
89
|
+
readonly children: TChildren | (() => TChildren);
|
|
49
90
|
}
|
|
50
91
|
|
|
51
92
|
/**
|
|
@@ -54,7 +95,7 @@ export interface TreeNodeConfig<
|
|
|
54
95
|
export class TreeNodePrimitive<
|
|
55
96
|
TType extends string,
|
|
56
97
|
TData extends StructPrimitive<any>,
|
|
57
|
-
TChildren extends
|
|
98
|
+
TChildren extends AnyTreeNodePrimitive = AnyTreeNodePrimitive
|
|
58
99
|
> {
|
|
59
100
|
readonly _tag = "TreeNodePrimitive" as const;
|
|
60
101
|
readonly _Type!: TType;
|
|
@@ -63,10 +104,10 @@ export class TreeNodePrimitive<
|
|
|
63
104
|
|
|
64
105
|
private readonly _type: TType;
|
|
65
106
|
private readonly _data: TData;
|
|
66
|
-
private readonly _children:
|
|
107
|
+
private readonly _children: TreeNodeChildrenInput;
|
|
67
108
|
private _resolvedChildren: readonly AnyTreeNodePrimitive[] | undefined;
|
|
68
109
|
|
|
69
|
-
constructor(type: TType, config: TreeNodeConfig<TData,
|
|
110
|
+
constructor(type: TType, config: TreeNodeConfig<TData, readonly (AnyTreeNodePrimitive | TreeNodeSelfType)[]>) {
|
|
70
111
|
this._type = type;
|
|
71
112
|
this._data = config.data;
|
|
72
113
|
this._children = config.children;
|
|
@@ -82,14 +123,14 @@ export class TreeNodePrimitive<
|
|
|
82
123
|
return this._data;
|
|
83
124
|
}
|
|
84
125
|
|
|
85
|
-
/** Get resolved children (resolves lazy thunk if needed) */
|
|
126
|
+
/** Get resolved children (resolves lazy thunk if needed, replaces Self with this node) */
|
|
86
127
|
get children(): readonly AnyTreeNodePrimitive[] {
|
|
87
128
|
if (this._resolvedChildren === undefined) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
129
|
+
const resolved = typeof this._children === "function"
|
|
130
|
+
? (this._children as () => readonly AnyTreeNodePrimitive[])()
|
|
131
|
+
: this._children;
|
|
132
|
+
// Replace Self placeholders with this node
|
|
133
|
+
this._resolvedChildren = resolved.map(child => isSelf(child) ? this : child) as readonly AnyTreeNodePrimitive[];
|
|
93
134
|
}
|
|
94
135
|
return this._resolvedChildren;
|
|
95
136
|
}
|
|
@@ -104,10 +145,10 @@ export class TreeNodePrimitive<
|
|
|
104
145
|
export const TreeNode = <
|
|
105
146
|
TType extends string,
|
|
106
147
|
TData extends StructPrimitive<any>,
|
|
107
|
-
TChildren extends readonly AnyTreeNodePrimitive
|
|
148
|
+
const TChildren extends readonly (AnyTreeNodePrimitive | TreeNodeSelfType)[]
|
|
108
149
|
>(
|
|
109
150
|
type: TType,
|
|
110
151
|
config: TreeNodeConfig<TData, TChildren>
|
|
111
|
-
): TreeNodePrimitive<TType, TData, TChildren
|
|
112
|
-
new TreeNodePrimitive(type, config)
|
|
152
|
+
): TreeNodePrimitive<TType, TData, ResolveChildrenUnion<TChildren, TreeNodePrimitive<TType, TData, any>>> =>
|
|
153
|
+
new TreeNodePrimitive(type, config) as TreeNodePrimitive<TType, TData, ResolveChildrenUnion<TChildren, TreeNodePrimitive<TType, TData, any>>>;
|
|
113
154
|
|
package/src/primitives/Union.ts
CHANGED
|
@@ -33,7 +33,7 @@ export type InferUnionSnapshot<TVariants extends UnionVariants> = {
|
|
|
33
33
|
/**
|
|
34
34
|
* Proxy for accessing union variants
|
|
35
35
|
*/
|
|
36
|
-
export interface UnionProxy<TVariants extends UnionVariants,
|
|
36
|
+
export interface UnionProxy<TVariants extends UnionVariants, _TDiscriminator extends string, TDefined extends boolean = false> {
|
|
37
37
|
/** Gets the current union value */
|
|
38
38
|
get(): MaybeUndefined<InferUnionState<TVariants>, TDefined>;
|
|
39
39
|
|
package/src/server/errors.ts
CHANGED
|
@@ -19,7 +19,7 @@ export class MimicServerError extends Error {
|
|
|
19
19
|
* Error thrown when a transaction fails validation.
|
|
20
20
|
*/
|
|
21
21
|
export class ValidationError extends MimicServerError {
|
|
22
|
-
readonly _tag = "ValidationError";
|
|
22
|
+
override readonly _tag = "ValidationError";
|
|
23
23
|
readonly transactionId: string;
|
|
24
24
|
|
|
25
25
|
constructor(transactionId: string, message: string) {
|
|
@@ -33,7 +33,7 @@ export class ValidationError extends MimicServerError {
|
|
|
33
33
|
* Error thrown when an operation is invalid for the current schema.
|
|
34
34
|
*/
|
|
35
35
|
export class InvalidOperationError extends MimicServerError {
|
|
36
|
-
readonly _tag = "InvalidOperationError";
|
|
36
|
+
override readonly _tag = "InvalidOperationError";
|
|
37
37
|
readonly operationKind: string;
|
|
38
38
|
readonly path: string;
|
|
39
39
|
|
|
@@ -49,9 +49,9 @@ export class InvalidOperationError extends MimicServerError {
|
|
|
49
49
|
* Error thrown when an operation cannot be applied to the current state.
|
|
50
50
|
*/
|
|
51
51
|
export class StateValidationError extends MimicServerError {
|
|
52
|
-
readonly _tag = "StateValidationError";
|
|
52
|
+
override readonly _tag = "StateValidationError";
|
|
53
53
|
readonly transactionId: string;
|
|
54
|
-
readonly cause?: Error;
|
|
54
|
+
override readonly cause?: Error;
|
|
55
55
|
|
|
56
56
|
constructor(transactionId: string, message: string, cause?: Error) {
|
|
57
57
|
super(`Transaction ${transactionId} cannot be applied to current state: ${message}`);
|
|
@@ -65,7 +65,7 @@ export class StateValidationError extends MimicServerError {
|
|
|
65
65
|
* Error thrown when attempting to apply an empty transaction.
|
|
66
66
|
*/
|
|
67
67
|
export class EmptyTransactionError extends MimicServerError {
|
|
68
|
-
readonly _tag = "EmptyTransactionError";
|
|
68
|
+
override readonly _tag = "EmptyTransactionError";
|
|
69
69
|
readonly transactionId: string;
|
|
70
70
|
|
|
71
71
|
constructor(transactionId: string) {
|
|
@@ -79,7 +79,7 @@ export class EmptyTransactionError extends MimicServerError {
|
|
|
79
79
|
* Error thrown when a duplicate transaction is submitted.
|
|
80
80
|
*/
|
|
81
81
|
export class DuplicateTransactionError extends MimicServerError {
|
|
82
|
-
readonly _tag = "DuplicateTransactionError";
|
|
82
|
+
override readonly _tag = "DuplicateTransactionError";
|
|
83
83
|
readonly transactionId: string;
|
|
84
84
|
|
|
85
85
|
constructor(transactionId: string) {
|