braid-text 0.2.50 → 0.2.51

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 (3) hide show
  1. package/index.js +19 -8
  2. package/package.json +1 -1
  3. package/test/test.html +84 -0
package/index.js CHANGED
@@ -70,8 +70,7 @@ braid_text.serve = async (req, res, options = {}) => {
70
70
  }
71
71
 
72
72
  var get_current_version = () => ascii_ify(
73
- resource.doc.getRemoteVersion().map(x => x.join("-")).sort()
74
- .map(x => JSON.stringify(x)).join(", "))
73
+ resource.version.map(x => JSON.stringify(x)).join(", "))
75
74
 
76
75
  if (req.method == "GET" || req.method == "HEAD") {
77
76
  // make sure we have the necessary version and parents
@@ -133,7 +132,17 @@ braid_text.serve = async (req, res, options = {}) => {
133
132
  accept_encoding:
134
133
  req.headers['x-accept-encoding'] ??
135
134
  req.headers['accept-encoding'],
136
- subscribe: x => res.sendVersion(x),
135
+ subscribe: x => {
136
+
137
+ // this is a sanity/rhobustness check..
138
+ // ..this digest is checked on the client..
139
+ // ..it is not strictly necessary
140
+ if (x.version && v_eq(x.version, resource.version)) {
141
+ x["Repr-Digest"] = `sha-256=:${require('crypto').createHash('sha256').update(Buffer.from(resource.val, "utf8")).digest('base64')}:`
142
+ }
143
+
144
+ res.sendVersion(x)
145
+ },
137
146
  write: (x) => res.write(x)
138
147
  }
139
148
 
@@ -233,7 +242,7 @@ braid_text.get = async (key, options) => {
233
242
  if (options.parents) validate_version_array(options.parents)
234
243
 
235
244
  let resource = (typeof key == 'string') ? await get_resource(key) : key
236
- var version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
245
+ var version = resource.version
237
246
 
238
247
  if (!options.subscribe) {
239
248
  if (options.transfer_encoding === 'dt') {
@@ -390,7 +399,7 @@ braid_text.put = async (key, options) => {
390
399
  }
391
400
  }
392
401
 
393
- let parents = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
402
+ let parents = resource.version
394
403
  let og_parents = options_parents || parents
395
404
 
396
405
  let max_pos = resource.length_cache.get('' + og_parents) ??
@@ -526,6 +535,7 @@ braid_text.put = async (key, options) => {
526
535
 
527
536
  for (let b of bytes) resource.doc.mergeBytes(b)
528
537
  resource.val = resource.doc.get()
538
+ resource.version = resource.doc.getRemoteVersion().map(x => x.join("-")).sort()
529
539
 
530
540
  var post_commit_updates = []
531
541
 
@@ -533,7 +543,7 @@ braid_text.put = async (key, options) => {
533
543
  patches = get_xf_patches(resource.doc, v_before)
534
544
  if (braid_text.verbose) console.log(JSON.stringify({ patches }))
535
545
 
536
- let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
546
+ let version = resource.version
537
547
 
538
548
  for (let client of resource.simpleton_clients) {
539
549
  if (peer && client.peer === peer) {
@@ -546,7 +556,7 @@ braid_text.put = async (key, options) => {
546
556
  // if the doc has been freed, exit early
547
557
  if (resource.doc.__wbg_ptr === 0) return
548
558
 
549
- let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
559
+ let version = resource.version
550
560
  let x = { version }
551
561
  x.parents = client.my_last_seen_version
552
562
 
@@ -609,7 +619,7 @@ braid_text.put = async (key, options) => {
609
619
  }
610
620
  } else {
611
621
  if (resource.simpleton_clients.size) {
612
- let version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
622
+ let version = resource.version
613
623
  patches = get_xf_patches(resource.doc, v_before)
614
624
  let x = { version, parents, patches }
615
625
  if (braid_text.verbose) console.log(`sending: ${JSON.stringify(x)}`)
@@ -681,6 +691,7 @@ async function get_resource(key) {
681
691
  })
682
692
 
683
693
  resource.val = resource.doc.get()
694
+ resource.version = resource.doc.getRemoteVersion().map(x => x.join("-")).sort()
684
695
 
685
696
  resource.length_cache = createSimpleCache(braid_text.length_cache_size)
686
697
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.50",
3
+ "version": "0.2.51",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
package/test/test.html CHANGED
@@ -96,6 +96,90 @@ async function runTest(testName, testFunction, expectedResult) {
96
96
  }
97
97
  }
98
98
 
99
+ runTest(
100
+ "test subscribing and verifying digests [simpleton]",
101
+ async () => {
102
+ let key = 'test-' + Math.random().toString(36).slice(2)
103
+
104
+ let r = await braid_fetch(`/${key}`, {
105
+ method: 'PUT',
106
+ version: ['hi-1'],
107
+ parents: [],
108
+ body: 'xx'
109
+ })
110
+ if (!r.ok) throw 'got: ' + r.statusCode
111
+
112
+ let r2 = await braid_fetch(`/${key}`, {
113
+ version: ['hi-0'],
114
+ subscribe: true
115
+ })
116
+ var parts = []
117
+ var p = new Promise(async (done, fail) => {
118
+ r2.subscribe(update => {
119
+ parts.push(update.extra_headers['repr-digest'])
120
+ if (parts.length > 1) done()
121
+ }, fail)
122
+ })
123
+
124
+ await new Promise(done => setTimeout(done, 300))
125
+ let rr = await braid_fetch(`/${key}`, {
126
+ method: 'PUT',
127
+ version: ['hi-2'],
128
+ parents: ['hi-1'],
129
+ patches: [{unit: "text", range: "[1:1]", content: "Y"}]
130
+ })
131
+ if (!rr.ok) throw 'got: ' + rr.statusCode
132
+
133
+ await p
134
+ return JSON.stringify(parts)
135
+ },
136
+ '["sha-256=:Xd6JaIf2dUybFb/jpEGuSAbfL96UABMR4IvxEGIuC74=:","sha-256=:77cl3INcGEtczN0zK3eOgW/YWYAOm8ub73LkVcF2/rA=:"]'
137
+ )
138
+
139
+ runTest(
140
+ "test subscribing and verifying digests [dt]",
141
+ async () => {
142
+ let key = 'test-' + Math.random().toString(36).slice(2)
143
+
144
+ let r = await braid_fetch(`/${key}`, {
145
+ method: 'PUT',
146
+ version: ['hi-1'],
147
+ parents: [],
148
+ body: 'xx'
149
+ })
150
+ if (!r.ok) throw 'got: ' + r.statusCode
151
+
152
+ let r2 = await braid_fetch(`/${key}`, {
153
+ version: ['hi-0'],
154
+ headers: { 'merge-type': 'dt' },
155
+ subscribe: true
156
+ })
157
+ var parts = []
158
+ var p = new Promise(async (done, fail) => {
159
+ r2.subscribe(update => {
160
+
161
+ console.log(`update: ${JSON.stringify(update, null, 4)}`)
162
+
163
+ parts.push(update.extra_headers['repr-digest'])
164
+ if (parts.length > 1) done()
165
+ }, fail)
166
+ })
167
+
168
+ await new Promise(done => setTimeout(done, 300))
169
+ let rr = await braid_fetch(`/${key}`, {
170
+ method: 'PUT',
171
+ version: ['hi-2'],
172
+ parents: ['hi-1'],
173
+ patches: [{unit: "text", range: "[2:2]", content: "Y"}]
174
+ })
175
+ if (!rr.ok) throw 'got: ' + rr.statusCode
176
+
177
+ await p
178
+ return JSON.stringify(parts)
179
+ },
180
+ '["sha-256=:Xd6JaIf2dUybFb/jpEGuSAbfL96UABMR4IvxEGIuC74=:","sha-256=:QknHazou37wCCwv3JXnCoAvXcKszP6xBTxLIiUAETgI=:"]'
181
+ )
182
+
99
183
  runTest(
100
184
  "test PUTing a version that the server already has",
101
185
  async () => {