braid-text 0.2.39 → 0.2.40

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 +39 -31
  2. package/package.json +1 -1
  3. package/test/test.html +58 -1
package/index.js CHANGED
@@ -3,8 +3,6 @@ let { Doc, OpLog, Branch } = require("@braid.org/diamond-types-node")
3
3
  let braidify = require("braid-http").http_server
4
4
  let fs = require("fs")
5
5
 
6
- let MISSING_PARENT_VERSION = 'missing parent version'
7
-
8
6
  let braid_text = {
9
7
  verbose: false,
10
8
  db_folder: './braid-text-db',
@@ -76,18 +74,25 @@ braid_text.serve = async (req, res, options = {}) => {
76
74
  .map(x => JSON.stringify(x)).join(", "))
77
75
 
78
76
  if (req.method == "GET" || req.method == "HEAD") {
77
+ // make sure we have the necessary version and parents
78
+ var unknowns = []
79
+ for (var event of (req.version || []).concat(req.parents || [])) {
80
+ var [actor, seq] = decode_version(event)
81
+ if (!resource.actor_seqs[actor]?.has(seq))
82
+ unknowns.push(event)
83
+ }
84
+ if (unknowns.length)
85
+ return my_end(309, '', "Version Unknown", {
86
+ Version: ascii_ify(unknowns.map(e => JSON.stringify(e)).join(', '))
87
+ })
88
+
79
89
  if (!req.subscribe) {
80
90
  res.setHeader("Accept-Subscribe", "true")
81
91
 
82
92
  // special case for HEAD asking for version/parents,
83
93
  // to be faster by not reconstructing body
84
- if (req.method === "HEAD" && (req.version || req.parents)) {
85
- if ((req.version || req.parents).every(event => {
86
- var [actor, seq] = decode_version(event)
87
- return resource.actor_seqs[actor]?.has(seq)
88
- })) return my_end(200)
89
- else return my_end(500, "Unknown Version")
90
- }
94
+ if (req.method === "HEAD" && (req.version || req.parents))
95
+ return my_end(200)
91
96
 
92
97
  let x = null
93
98
  try {
@@ -167,15 +172,29 @@ braid_text.serve = async (req, res, options = {}) => {
167
172
  patches = null
168
173
  }
169
174
 
170
- if (req.parents) await wait_for_events(
171
- options.key,
172
- req.parents,
173
- resource.actor_seqs,
174
- // approximation of memory usage for this update
175
- body ? body.length :
176
- patches.reduce((a, b) => a + b.range.length + b.content.length, 0),
177
- options.put_buffer_max_time,
178
- options.put_buffer_max_space)
175
+ if (req.parents) {
176
+ await wait_for_events(
177
+ options.key,
178
+ req.parents,
179
+ resource.actor_seqs,
180
+ // approximation of memory usage for this update
181
+ body ? body.length :
182
+ patches.reduce((a, b) => a + b.range.length + b.content.length, 0),
183
+ options.put_buffer_max_time,
184
+ options.put_buffer_max_space)
185
+
186
+ // make sure we have the necessary parents now
187
+ var unknowns = []
188
+ for (var event of req.parents) {
189
+ var [actor, seq] = decode_version(event)
190
+ if (!resource.actor_seqs[actor]?.has(seq)) unknowns.push(event)
191
+ }
192
+ if (unknowns.length)
193
+ return done_my_turn(309, '', "Version Unknown", {
194
+ Version: ascii_ify(unknowns.map(e => JSON.stringify(e)).join(', ')),
195
+ 'Retry-After': '1'
196
+ })
197
+ }
179
198
 
180
199
  var {change_count} = await braid_text.put(resource, { peer, version: req.version, parents: req.parents, patches, body, merge_type })
181
200
 
@@ -186,18 +205,7 @@ braid_text.serve = async (req, res, options = {}) => {
186
205
  options.put_cb(options.key, resource.val)
187
206
  } catch (e) {
188
207
  console.log(`${req.method} ERROR: ${e.stack}`)
189
- if (e.message?.startsWith(MISSING_PARENT_VERSION)) {
190
- // we couldn't apply the version, because we're missing its parents;
191
- // we want to send some kind of error that gives the client faith,
192
- // that resending this request later may work,
193
- // hopefully after we've received the necessary parents.
194
- return done_my_turn(309, e.message, 'Version Unknown', {
195
- Parents: req.headers.parents,
196
- 'Retry-After': '1'
197
- })
198
- } else {
199
- return done_my_turn(500, "The server failed to apply this version. The error generated was: " + e)
200
- }
208
+ return done_my_turn(500, "The server failed to apply this version. The error generated was: " + e)
201
209
  }
202
210
 
203
211
  return done_my_turn(200)
@@ -364,7 +372,7 @@ braid_text.put = async (key, options) => {
364
372
  for (let p of options_parents) {
365
373
  let P = decode_version(p)
366
374
  if (!resource.actor_seqs[P[0]]?.has(P[1]))
367
- throw new Error(`${MISSING_PARENT_VERSION}: ${p}`)
375
+ throw new Error(`missing parent version: ${p}`)
368
376
  }
369
377
  }
370
378
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.39",
3
+ "version": "0.2.40",
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
@@ -485,7 +485,7 @@ runTest(
485
485
  parents: ['missing-0', 'y😀-0'],
486
486
  body: 'xx'
487
487
  })
488
- return r.status + ' ' + r.ok + ' ' + r.statusText + ' ' + r.headers.get('Parents')
488
+ return r.status + ' ' + r.ok + ' ' + r.statusText + ' ' + r.headers.get('Version')
489
489
  },
490
490
  '309 false Version Unknown "missing-0", "y\\ud83d\\ude00-0"'
491
491
  )
@@ -797,6 +797,8 @@ runTest(
797
797
  method: 'HEAD',
798
798
  version: ['hi-5']
799
799
  })
800
+ if (r.status !== 309) throw 'expected 309, got: ' + r.status
801
+ if (r.statusText !== 'Version Unknown') throw 'unexpected status text: ' + r.statusText
800
802
  if (r.ok) throw 'found version we should not have found'
801
803
 
802
804
  var r = await braid_fetch(`/${key}`, {
@@ -810,4 +812,59 @@ runTest(
810
812
  'worked out!'
811
813
  )
812
814
 
815
+ runTest(
816
+ "test asking for parents that should and shouldn't be there",
817
+ async () => {
818
+ var key = 'test-' + Math.random().toString(36).slice(2)
819
+
820
+ var r = await braid_fetch(`/${key}`, {
821
+ method: 'PUT',
822
+ version: ['hi-10'],
823
+ parents: [],
824
+ body: 'x'
825
+ })
826
+ if (!r.ok) throw 'got: ' + r.statusCode
827
+
828
+ var r = await braid_fetch(`/${key}`, {
829
+ method: 'HEAD',
830
+ parents: ['hi-5']
831
+ })
832
+ if (r.status !== 309) throw 'expected 309, got: ' + r.status
833
+ if (r.ok) throw 'found parents we should not have found'
834
+
835
+ var r = await braid_fetch(`/${key}`, {
836
+ method: 'HEAD',
837
+ parents: ['hi-10']
838
+ })
839
+ if (!r.ok) throw 'could not find parents we should have found'
840
+
841
+ return 'worked out!'
842
+ },
843
+ 'worked out!'
844
+ )
845
+
846
+ runTest(
847
+ "test that 309 returns all missing events",
848
+ async () => {
849
+ var key = 'test-' + Math.random().toString(36).slice(2)
850
+
851
+ var r = await braid_fetch(`/${key}`, {
852
+ method: 'PUT',
853
+ version: ['hi-11'],
854
+ parents: [],
855
+ body: 'xyz'
856
+ })
857
+ if (!r.ok) throw 'got: ' + r.statusCode
858
+
859
+ var r = await braid_fetch(`/${key}`, {
860
+ method: 'HEAD',
861
+ version: ['yo-1', 'hi-11'],
862
+ parents: ['hi-5', 'hi-8', 'hi-9', 'hi-10']
863
+ })
864
+ if (r.status !== 309) throw 'expected 309, got: ' + r.status
865
+ return r.headers.get('version')
866
+ },
867
+ '"yo-1", "hi-5", "hi-8"'
868
+ )
869
+
813
870
  </script>