change_request.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. 'use strict'
  2. const assert = require('check-types').assert
  3. const AuthorList = require('./author_list')
  4. const Change = require('./change')
  5. const Operation = require('./operation')
  6. /**
  7. * @typedef {import("./author")} Author
  8. */
  9. /**
  10. * A `ChangeRequest` is a list of {@link Operation}s that the server can apply
  11. * as a {@link Change}.
  12. *
  13. * If the change is marked as `untransformable`, then the server will not
  14. * attempt to transform it if it is out of date (i.e. if the baseVersion no
  15. * longer matches the project's latest version). For example, if the client
  16. * needs to ensure that a metadata property is set on exactly one file, it can't
  17. * do that reliably if there's a chance that other clients will also change the
  18. * metadata at the same time. The expectation is that if the change is rejected,
  19. * the client will retry on a later version.
  20. */
  21. class ChangeRequest {
  22. /**
  23. * @param {number} baseVersion
  24. * @param {Array.<Operation>} operations
  25. * @param {boolean} [untransformable]
  26. * @param {number[] | Author[]} [authors]
  27. */
  28. constructor(baseVersion, operations, untransformable, authors) {
  29. assert.integer(baseVersion, 'bad baseVersion')
  30. assert.array.of.object(operations, 'bad operations')
  31. assert.maybe.boolean(untransformable, 'ChangeRequest: bad untransformable')
  32. // TODO remove authors once we have JWTs working --- pass as parameter to
  33. // makeChange instead
  34. authors = authors || []
  35. // check all are the same type
  36. AuthorList.assertV1(authors, 'bad authors')
  37. this.authors = authors
  38. this.baseVersion = baseVersion
  39. this.operations = operations
  40. this.untransformable = untransformable || false
  41. }
  42. /**
  43. * For serialization.
  44. *
  45. * @return {Object}
  46. */
  47. toRaw() {
  48. function operationToRaw(operation) {
  49. return operation.toRaw()
  50. }
  51. return {
  52. baseVersion: this.baseVersion,
  53. operations: this.operations.map(operationToRaw),
  54. untransformable: this.untransformable,
  55. authors: this.authors,
  56. }
  57. }
  58. static fromRaw(raw) {
  59. assert.array.of.object(raw.operations, 'bad raw.operations')
  60. return new ChangeRequest(
  61. raw.baseVersion,
  62. raw.operations.map(Operation.fromRaw),
  63. raw.untransformable,
  64. raw.authors
  65. )
  66. }
  67. getBaseVersion() {
  68. return this.baseVersion
  69. }
  70. isUntransformable() {
  71. return this.untransformable
  72. }
  73. makeChange(timestamp) {
  74. return new Change(this.operations, timestamp, this.authors)
  75. }
  76. }
  77. module.exports = ChangeRequest