@fluidframework/driver-base 2.0.0-dev.4.4.0.162253 → 2.0.0-dev.5.2.0.169897

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 (39) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/documentDeltaConnection.d.ts +6 -4
  3. package/dist/documentDeltaConnection.d.ts.map +1 -1
  4. package/dist/documentDeltaConnection.js +25 -55
  5. package/dist/documentDeltaConnection.js.map +1 -1
  6. package/dist/driverUtils.d.ts +3 -0
  7. package/dist/driverUtils.d.ts.map +1 -1
  8. package/dist/driverUtils.js +32 -1
  9. package/dist/driverUtils.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/packageVersion.d.ts +1 -1
  15. package/dist/packageVersion.js +1 -1
  16. package/dist/packageVersion.js.map +1 -1
  17. package/dist/tsdoc-metadata.json +11 -0
  18. package/lib/documentDeltaConnection.d.ts +6 -4
  19. package/lib/documentDeltaConnection.d.ts.map +1 -1
  20. package/lib/documentDeltaConnection.js +25 -55
  21. package/lib/documentDeltaConnection.js.map +1 -1
  22. package/lib/driverUtils.d.ts +3 -0
  23. package/lib/driverUtils.d.ts.map +1 -1
  24. package/lib/driverUtils.js +30 -0
  25. package/lib/driverUtils.js.map +1 -1
  26. package/lib/index.d.ts +1 -1
  27. package/lib/index.d.ts.map +1 -1
  28. package/lib/index.js +1 -1
  29. package/lib/index.js.map +1 -1
  30. package/lib/packageVersion.d.ts +1 -1
  31. package/lib/packageVersion.js +1 -1
  32. package/lib/packageVersion.js.map +1 -1
  33. package/lib/test/types/validateDriverBasePrevious.generated.js +2 -0
  34. package/lib/test/types/validateDriverBasePrevious.generated.js.map +1 -1
  35. package/package.json +12 -14
  36. package/src/documentDeltaConnection.ts +52 -69
  37. package/src/driverUtils.ts +38 -0
  38. package/src/index.ts +1 -1
  39. package/src/packageVersion.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/driver-base",
3
- "version": "2.0.0-dev.4.4.0.162253",
3
+ "version": "2.0.0-dev.5.2.0.169897",
4
4
  "description": "Shared driver code for Fluid driver implementations",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -17,16 +17,16 @@
17
17
  "dependencies": {
18
18
  "@fluidframework/common-definitions": "^0.20.1",
19
19
  "@fluidframework/common-utils": "^1.1.1",
20
- "@fluidframework/driver-definitions": "2.0.0-dev.4.4.0.162253",
21
- "@fluidframework/driver-utils": "2.0.0-dev.4.4.0.162253",
20
+ "@fluidframework/driver-definitions": "2.0.0-dev.5.2.0.169897",
21
+ "@fluidframework/driver-utils": "2.0.0-dev.5.2.0.169897",
22
22
  "@fluidframework/protocol-definitions": "^1.1.0",
23
- "@fluidframework/telemetry-utils": "2.0.0-dev.4.4.0.162253"
23
+ "@fluidframework/telemetry-utils": "2.0.0-dev.5.2.0.169897"
24
24
  },
25
25
  "devDependencies": {
26
- "@fluid-tools/build-cli": "^0.17.0",
27
- "@fluidframework/build-common": "^1.1.0",
28
- "@fluidframework/build-tools": "^0.17.0",
29
- "@fluidframework/driver-base-previous": "npm:@fluidframework/driver-base@2.0.0-internal.4.1.0",
26
+ "@fluid-tools/build-cli": "^0.20.0-169245",
27
+ "@fluidframework/build-common": "^1.2.0",
28
+ "@fluidframework/build-tools": "^0.20.0-169245",
29
+ "@fluidframework/driver-base-previous": "npm:@fluidframework/driver-base@2.0.0-internal.5.0.0",
30
30
  "@fluidframework/eslint-config-fluid": "^2.0.0",
31
31
  "@microsoft/api-extractor": "^7.34.4",
32
32
  "@types/node": "^14.18.38",
@@ -35,20 +35,18 @@
35
35
  "eslint": "~8.6.0",
36
36
  "prettier": "~2.6.2",
37
37
  "rimraf": "^4.4.0",
38
- "socket.io-client": "^4.4.1",
38
+ "socket.io-client": "^4.6.1",
39
39
  "typescript": "~4.5.5"
40
40
  },
41
41
  "typeValidation": {
42
42
  "broken": {}
43
43
  },
44
44
  "scripts": {
45
- "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
46
- "build:commonjs": "npm run typetests:gen && npm run tsc",
47
- "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
45
+ "build": "fluid-build . --task build",
46
+ "build:commonjs": "fluid-build . --task commonjs",
47
+ "build:compile": "fluid-build . --task compile",
48
48
  "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
49
49
  "build:esnext": "tsc --project ./tsconfig.esnext.json",
50
- "build:full": "npm run build",
51
- "build:full:compile": "npm run build:compile",
52
50
  "build:genver": "gen-version",
53
51
  "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
54
52
  "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
@@ -22,8 +22,9 @@ import {
22
22
  ITokenClaims,
23
23
  ScopeType,
24
24
  } from "@fluidframework/protocol-definitions";
25
- import { IDisposable, ITelemetryLogger } from "@fluidframework/common-definitions";
25
+ import { IDisposable, ITelemetryProperties } from "@fluidframework/common-definitions";
26
26
  import {
27
+ ITelemetryLoggerExt,
27
28
  ChildLogger,
28
29
  extractLogSafeErrorProperties,
29
30
  getCircularReplacer,
@@ -82,21 +83,10 @@ export class DocumentDeltaConnection
82
83
  }
83
84
 
84
85
  public get disposed() {
85
- // Increase the stack trace limit temporarily, so as to debug better in case it occurs.
86
- // We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.
87
- const originalStackTraceLimit = (Error as any).stackTraceLimit;
88
- try {
89
- (Error as any).stackTraceLimit = 50;
90
- assert(
91
- this._disposed || this.socket.connected,
92
- 0x244 /* "Socket is closed, but connection is not!" */,
93
- );
94
- } catch (error) {
95
- const normalizedError = this.addPropsToError(error);
96
- throw normalizedError;
97
- } finally {
98
- (Error as any).stackTraceLimit = originalStackTraceLimit;
99
- }
86
+ assert(
87
+ this._disposed || this.socket.connected,
88
+ 0x244 /* "Socket is closed, but connection is not!" */,
89
+ );
100
90
  return this._disposed;
101
91
  }
102
92
 
@@ -110,7 +100,7 @@ export class DocumentDeltaConnection
110
100
  /**
111
101
  * @deprecated Implementors should manage their own logger or monitoring context
112
102
  */
113
- protected get logger(): ITelemetryLogger {
103
+ protected get logger(): ITelemetryLoggerExt {
114
104
  return this.mc.logger;
115
105
  }
116
106
 
@@ -130,11 +120,12 @@ export class DocumentDeltaConnection
130
120
  protected constructor(
131
121
  protected readonly socket: Socket,
132
122
  public documentId: string,
133
- logger: ITelemetryLogger,
123
+ logger: ITelemetryLoggerExt,
134
124
  private readonly enableLongPollingDowngrades: boolean = false,
135
125
  protected readonly connectionId?: string,
136
126
  ) {
137
127
  super((name, error) => {
128
+ this.addPropsToError(error);
138
129
  logger.sendErrorEvent(
139
130
  {
140
131
  eventName: "DeltaConnection:EventException",
@@ -236,18 +227,7 @@ export class DocumentDeltaConnection
236
227
  }
237
228
 
238
229
  private checkNotDisposed() {
239
- // Increase the stack trace limit temporarily, so as to debug better in case it occurs.
240
- // We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.
241
- const originalStackTraceLimit = (Error as any).stackTraceLimit;
242
- try {
243
- (Error as any).stackTraceLimit = 50;
244
- assert(!this.disposed, 0x20c /* "connection disposed" */);
245
- } catch (error) {
246
- const normalizedError = this.addPropsToError(error);
247
- throw normalizedError;
248
- } finally {
249
- (Error as any).stackTraceLimit = originalStackTraceLimit;
250
- }
230
+ assert(!this.disposed, 0x20c /* "connection disposed" */);
251
231
  }
252
232
 
253
233
  /**
@@ -341,17 +321,6 @@ export class DocumentDeltaConnection
341
321
  private closeSocket(error: IAnyDriverError) {
342
322
  if (this._disposed) {
343
323
  // This would be rare situation due to complexity around socket emitting events.
344
- this.logger.sendTelemetryEvent(
345
- {
346
- eventName: "SocketCloseOnDisposedConnection",
347
- driverVersion,
348
- details: JSON.stringify({
349
- ...this.getConnectionDetailsProps(),
350
- trackedListenerCount: this.trackedListeners.size,
351
- }),
352
- },
353
- error,
354
- );
355
324
  return;
356
325
  }
357
326
  this.closeSocketCore(error);
@@ -409,14 +378,6 @@ export class DocumentDeltaConnection
409
378
 
410
379
  // Let user of connection object know about disconnect.
411
380
  this.emit("disconnect", err);
412
- this.logger.sendTelemetryEvent({
413
- eventName: "AfterDisconnectEvent",
414
- driverVersion,
415
- details: JSON.stringify({
416
- ...this.getConnectionDetailsProps(),
417
- disconnectListenerCount: this.listenerCount("disconnect"),
418
- }),
419
- });
420
381
  }
421
382
 
422
383
  /**
@@ -591,9 +552,14 @@ export class DocumentDeltaConnection
591
552
  // Socket can be disconnected while waiting for Fluid protocol messages
592
553
  // (connect_document_error / connect_document_success), as well as before DeltaManager
593
554
  // had a chance to register its handlers.
594
- this.addTrackedListener("disconnect", (reason) => {
595
- const err = this.createErrorObject("disconnect", reason);
596
- failAndCloseSocket(err);
555
+ this.addTrackedListener("disconnect", (reason, details) => {
556
+ failAndCloseSocket(
557
+ this.createErrorObjectWithProps("disconnect", reason, {
558
+ socketErrorType: details?.context?.type,
559
+ // https://www.rfc-editor.org/rfc/rfc6455#section-7.4
560
+ socketCode: details?.context?.code,
561
+ }),
562
+ );
597
563
  });
598
564
 
599
565
  this.addTrackedListener("error", (error) => {
@@ -705,25 +671,44 @@ export class DocumentDeltaConnection
705
671
  this.connectionListeners.clear();
706
672
  }
707
673
 
674
+ private getErrorMessage(error?: any): string {
675
+ if (error?.type !== "TransportError") {
676
+ return extractLogSafeErrorProperties(error, true).message;
677
+ }
678
+ // JSON.stringify drops Error.message
679
+ const messagePrefix = error?.message !== undefined ? `${error.message}: ` : "";
680
+
681
+ // Websocket errors reported by engine.io-client.
682
+ // They are Error objects with description containing WS error and description = "TransportError"
683
+ // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,
684
+ return `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;
685
+ }
686
+
687
+ private createErrorObjectWithProps(
688
+ handler: string,
689
+ error?: any,
690
+ props?: ITelemetryProperties,
691
+ canRetry = true,
692
+ ): IAnyDriverError {
693
+ return createGenericNetworkError(
694
+ `socket.io (${handler}): ${this.getErrorMessage(error)}`,
695
+ { canRetry },
696
+ {
697
+ ...props,
698
+ driverVersion,
699
+ details: JSON.stringify({
700
+ ...this.getConnectionDetailsProps(),
701
+ }),
702
+ },
703
+ );
704
+ }
705
+
708
706
  /**
709
707
  * Error raising for socket.io issues
710
708
  */
711
709
  protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {
712
- let message: string;
713
- if (error?.type === "TransportError") {
714
- // JSON.stringify drops Error.message
715
- const messagePrefix = error?.message !== undefined ? `${error.message}: ` : "";
716
-
717
- // Websocket errors reported by engine.io-client.
718
- // They are Error objects with description containing WS error and description = "TransportError"
719
- // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,
720
- message = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;
721
- } else {
722
- message = extractLogSafeErrorProperties(error, true).message;
723
- }
724
-
725
- const errorObj = createGenericNetworkError(
726
- `socket.io (${handler}): ${message}`,
710
+ return createGenericNetworkError(
711
+ `socket.io (${handler}): ${this.getErrorMessage(error)}`,
727
712
  { canRetry },
728
713
  {
729
714
  driverVersion,
@@ -732,7 +717,5 @@ export class DocumentDeltaConnection
732
717
  }),
733
718
  },
734
719
  );
735
-
736
- return errorObj;
737
720
  }
738
721
  }
@@ -4,6 +4,8 @@
4
4
  */
5
5
 
6
6
  import { performance } from "@fluidframework/common-utils";
7
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
7
9
 
8
10
  /**
9
11
  * Extract and return the w3c data.
@@ -103,3 +105,39 @@ export async function promiseRaceWithWinner<T>(
103
105
  });
104
106
  });
105
107
  }
108
+
109
+ export function validateMessages(
110
+ reason: string,
111
+ messages: ISequencedDocumentMessage[],
112
+ from: number,
113
+ logger: ITelemetryLoggerExt,
114
+ ) {
115
+ if (messages.length !== 0) {
116
+ const start = messages[0].sequenceNumber;
117
+ const length = messages.length;
118
+ const last = messages[length - 1].sequenceNumber;
119
+ if (start !== from) {
120
+ logger.sendErrorEvent({
121
+ eventName: "OpsFetchViolation",
122
+ reason,
123
+ from,
124
+ start,
125
+ last,
126
+ length,
127
+ });
128
+ messages.length = 0;
129
+ }
130
+ if (last + 1 !== from + length) {
131
+ logger.sendErrorEvent({
132
+ eventName: "OpsFetchViolation",
133
+ reason,
134
+ from,
135
+ start,
136
+ last,
137
+ length,
138
+ });
139
+ // we can do better here by finding consecutive sub-block and return it
140
+ messages.length = 0;
141
+ }
142
+ }
143
+ }
package/src/index.ts CHANGED
@@ -4,4 +4,4 @@
4
4
  */
5
5
 
6
6
  export { DocumentDeltaConnection } from "./documentDeltaConnection";
7
- export { getW3CData, promiseRaceWithWinner } from "./driverUtils";
7
+ export { getW3CData, promiseRaceWithWinner, validateMessages } from "./driverUtils";
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-base";
9
- export const pkgVersion = "2.0.0-dev.4.4.0.162253";
9
+ export const pkgVersion = "2.0.0-dev.5.2.0.169897";