braid-text 0.2.33 → 0.2.35

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 +54 -16
  2. package/package.json +1 -1
  3. package/test/test.html +228 -0
package/index.js CHANGED
@@ -72,6 +72,10 @@ braid_text.serve = async (req, res, options = {}) => {
72
72
  return my_end(200)
73
73
  }
74
74
 
75
+ var get_current_version = () => ascii_ify(
76
+ resource.doc.getRemoteVersion().map(x => x.join("-")).sort()
77
+ .map(x => JSON.stringify(x)).join(", "))
78
+
75
79
  if (req.method == "GET" || req.method == "HEAD") {
76
80
  if (!req.subscribe) {
77
81
  res.setHeader("Accept-Subscribe", "true")
@@ -88,20 +92,29 @@ braid_text.serve = async (req, res, options = {}) => {
88
92
 
89
93
  let x = null
90
94
  try {
91
- x = await braid_text.get(resource, { version: req.version, parents: req.parents })
95
+ x = await braid_text.get(resource, {
96
+ version: req.version,
97
+ parents: req.parents,
98
+ transfer_encoding: req.headers['accept-transfer-encoding']
99
+ })
92
100
  } catch (e) {
93
101
  return my_end(500, "The server failed to get something. The error generated was: " + e)
94
102
  }
95
103
 
96
- res.setHeader("Version", x.version.map((x) => JSON.stringify(x)).join(", "))
97
-
98
- const buffer = Buffer.from(x.body, "utf8")
99
- res.setHeader("Repr-Digest", `sha-256=:${require('crypto').createHash('sha256').update(buffer).digest('base64')}:`)
100
- res.setHeader("Content-Length", buffer.length)
101
-
102
- if (req.method === "HEAD") return my_end(200)
103
-
104
- return my_end(200, buffer)
104
+ if (req.headers['accept-transfer-encoding'] === 'dt') {
105
+ res.setHeader("Current-Version", get_current_version())
106
+ res.setHeader("Transfer-Encoding", 'dt')
107
+ res.setHeader("Content-Length", x.body.length)
108
+ return my_end(209, req.method === "HEAD" ? null : x.body, 'Multiresponse')
109
+ } else {
110
+ if (req.version || req.parents)
111
+ res.setHeader("Current-Version", get_current_version())
112
+ res.setHeader("Version", ascii_ify(x.version.map((x) => JSON.stringify(x)).join(", ")))
113
+ var buffer = Buffer.from(x.body, "utf8")
114
+ res.setHeader("Repr-Digest", `sha-256=:${require('crypto').createHash('sha256').update(buffer).digest('base64')}:`)
115
+ res.setHeader("Content-Length", buffer.length)
116
+ return my_end(200, req.method === "HEAD" ? null : buffer)
117
+ }
105
118
  } else {
106
119
  if (!res.hasHeader("editable")) res.setHeader("Editable", "true")
107
120
  res.setHeader("Merge-Type", merge_type)
@@ -170,7 +183,7 @@ braid_text.serve = async (req, res, options = {}) => {
170
183
 
171
184
  await braid_text.put(resource, { peer, version: req.version, parents: req.parents, patches, body, merge_type })
172
185
 
173
- res.setHeader("Version", resource.doc.getRemoteVersion().map((x) => x.join("-")).sort())
186
+ res.setHeader("Version", get_current_version())
174
187
 
175
188
  options.put_cb(options.key, resource.val)
176
189
  } catch (e) {
@@ -212,12 +225,38 @@ braid_text.get = async (key, options) => {
212
225
  let resource = (typeof key == 'string') ? await get_resource(key) : key
213
226
 
214
227
  if (!options.subscribe) {
215
- return options.version || options.parents ?
216
- {
228
+ var version = resource.doc.getRemoteVersion().map((x) => x.join("-")).sort()
229
+
230
+ if (options.transfer_encoding === 'dt') {
231
+ // optimization: if requesting current version
232
+ // pretend as if they didn't set a version,
233
+ // and let it be handled as the default
234
+ var op_v = options.version
235
+ if (op_v && v_eq(op_v, version)) op_v = null
236
+
237
+ var bytes = null
238
+ if (op_v || options.parents) {
239
+ if (op_v) {
240
+ var doc = dt_get(resource.doc, op_v)
241
+ bytes = doc.toBytes()
242
+ } else {
243
+ bytes = resource.doc.toBytes()
244
+ var doc = Doc.fromBytes(bytes)
245
+ }
246
+ if (options.parents) {
247
+ bytes = doc.getPatchSince(
248
+ dt_get_local_version(bytes, options.parents))
249
+ }
250
+ doc.free()
251
+ } else bytes = resource.doc.toBytes()
252
+ return { body: bytes }
253
+ }
254
+
255
+ return options.version || options.parents ? {
217
256
  version: options.version || options.parents,
218
257
  body: dt_get_string(resource.doc, options.version || options.parents)
219
258
  } : {
220
- version: resource.doc.getRemoteVersion().map((x) => x.join("-")).sort(),
259
+ version,
221
260
  body: resource.doc.get()
222
261
  }
223
262
  } else {
@@ -244,14 +283,13 @@ braid_text.get = async (key, options) => {
244
283
  options.my_last_sent_version = x.version
245
284
  resource.simpleton_clients.add(options)
246
285
  } else {
247
- let updates = null
248
-
249
286
  if (resource.need_defrag) {
250
287
  if (braid_text.verbose) console.log(`doing defrag..`)
251
288
  resource.need_defrag = false
252
289
  resource.doc = defrag_dt(resource.doc)
253
290
  }
254
291
 
292
+ var updates = null
255
293
  if (!options.parents && !options.version) {
256
294
  options.subscribe({
257
295
  version: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.33",
3
+ "version": "0.2.35",
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
@@ -23,6 +23,13 @@
23
23
  <div id="testContainer"></div>
24
24
  <script type=module>
25
25
 
26
+ import {
27
+ default as init,
28
+ Doc,
29
+ OpLog,
30
+ } from "https://unpkg.com/diamond-types-web";
31
+ var dt_p = init()
32
+
26
33
  let delay = 0
27
34
 
28
35
  function createTestDiv(testName) {
@@ -61,6 +68,227 @@ async function runTest(testName, testFunction, expectedResult) {
61
68
  }
62
69
  }
63
70
 
71
+ runTest(
72
+ "test transfer-encoding dt (with parents)",
73
+ async () => {
74
+ await dt_p
75
+ let key = 'test-' + Math.random().toString(36).slice(2)
76
+ var doc = new Doc('hi')
77
+ doc.ins(0, 'x')
78
+
79
+ let r = await braid_fetch(`/${key}`, {
80
+ method: 'PUT',
81
+ version: ['hi-1'],
82
+ parents: [],
83
+ body: 'xy'
84
+ })
85
+ if (!r.ok) throw 'got: ' + r.statusCode
86
+
87
+ let r2 = await braid_fetch(`/${key}`, {
88
+ parents: ['hi-0'],
89
+ headers: {
90
+ 'Accept-Transfer-Encoding': 'dt'
91
+ }
92
+ })
93
+
94
+ doc.mergeBytes([...new Uint8Array(await r2.arrayBuffer())])
95
+ var text = doc.get()
96
+ doc.free()
97
+
98
+ return r2.headers.get('current-version') + ' ' + r2.headers.get('transfer-encoding') + ' ' + text + ' ' + r2.statusText
99
+ },
100
+ '"hi-1" dt xy Multiresponse'
101
+ )
102
+
103
+ runTest(
104
+ "test transfer-encoding dt",
105
+ async () => {
106
+ await dt_p
107
+ let key = 'test-' + Math.random().toString(36).slice(2)
108
+
109
+ let r = await braid_fetch(`/${key}`, {
110
+ method: 'PUT',
111
+ version: ['hi-1'],
112
+ parents: [],
113
+ body: 'xy'
114
+ })
115
+ if (!r.ok) throw 'got: ' + r.statusCode
116
+
117
+ let r2 = await braid_fetch(`/${key}`, {
118
+ headers: {
119
+ 'Accept-Transfer-Encoding': 'dt'
120
+ }
121
+ })
122
+
123
+ var doc = new Doc('yo')
124
+ doc.mergeBytes([...new Uint8Array(await r2.arrayBuffer())])
125
+ var text = doc.get()
126
+ doc.free()
127
+
128
+ return r2.headers.get('current-version') + ' ' + r2.headers.get('transfer-encoding') + ' ' + text
129
+ },
130
+ '"hi-1" dt xy'
131
+ )
132
+
133
+ runTest(
134
+ "test GETing old version explicitly with transfer-encoding dt",
135
+ async () => {
136
+ await dt_p
137
+ let key = 'test-' + Math.random().toString(36).slice(2)
138
+
139
+ let r = await braid_fetch(`/${key}`, {
140
+ method: 'PUT',
141
+ version: ['hi∑-1'],
142
+ parents: [],
143
+ body: 'xy'
144
+ })
145
+ if (!r.ok) throw 'got: ' + r.statusCode
146
+
147
+ let r2 = await braid_fetch(`/${key}`, {
148
+ version: ['hi∑-0'],
149
+ headers: {
150
+ 'Accept-Transfer-Encoding': 'dt'
151
+ }
152
+ })
153
+
154
+ var doc = new Doc('yo')
155
+ doc.mergeBytes([...new Uint8Array(await r2.arrayBuffer())])
156
+ var text = doc.get()
157
+ doc.free()
158
+
159
+ return r2.headers.get('current-version') + ' ' + text + ' ' + JSON.parse(r2.headers.get('current-version'))
160
+ },
161
+ '"hi\\u2211-1" x hi∑-1'
162
+ )
163
+
164
+ runTest(
165
+ "test GETing current version explicitly with transfer-encoding dt",
166
+ async () => {
167
+ await dt_p
168
+ let key = 'test-' + Math.random().toString(36).slice(2)
169
+
170
+ let r = await braid_fetch(`/${key}`, {
171
+ method: 'PUT',
172
+ version: ['hi∑-1'],
173
+ parents: [],
174
+ body: 'xy'
175
+ })
176
+ if (!r.ok) throw 'got: ' + r.statusCode
177
+
178
+ let r2 = await braid_fetch(`/${key}`, {
179
+ version: ['hi∑-1'],
180
+ headers: {
181
+ 'Accept-Transfer-Encoding': 'dt'
182
+ }
183
+ })
184
+
185
+ var doc = new Doc('yo')
186
+ doc.mergeBytes([...new Uint8Array(await r2.arrayBuffer())])
187
+ var text = doc.get()
188
+ doc.free()
189
+
190
+ return r2.headers.get('current-version') + ' ' + text + ' ' + JSON.parse(r2.headers.get('current-version'))
191
+ },
192
+ '"hi\\u2211-1" xy hi∑-1'
193
+ )
194
+
195
+ runTest(
196
+ "test for Current-Version when GETing old version",
197
+ async () => {
198
+ await dt_p
199
+ let key = 'test-' + Math.random().toString(36).slice(2)
200
+
201
+ let r = await braid_fetch(`/${key}`, {
202
+ method: 'PUT',
203
+ version: ['hi∑-1'],
204
+ parents: [],
205
+ body: 'xy'
206
+ })
207
+ if (!r.ok) throw 'got: ' + r.statusCode
208
+
209
+ let r2 = await braid_fetch(`/${key}`, {
210
+ version: ['hi∑-0']
211
+ })
212
+
213
+ var text = await r2.text()
214
+
215
+ return r2.headers.get('current-version') + ' ' + r2.headers.get('version') + ' ' + text + ' ' + JSON.parse(r2.headers.get('current-version'))
216
+ },
217
+ '"hi\\u2211-1" "hi\\u2211-0" x hi∑-1'
218
+ )
219
+
220
+ runTest(
221
+ "test HEAD for GET without subscribe",
222
+ async () => {
223
+ await dt_p
224
+ let key = 'test-' + Math.random().toString(36).slice(2)
225
+
226
+ let r = await braid_fetch(`/${key}`, {
227
+ method: 'PUT',
228
+ version: ['hi∑-1'],
229
+ parents: [],
230
+ body: 'xy'
231
+ })
232
+ if (!r.ok) throw 'got: ' + r.statusCode
233
+
234
+ let r2 = await braid_fetch(`/${key}`, {
235
+ method: 'HEAD'
236
+ })
237
+
238
+ var text = await r2.text()
239
+
240
+ return r2.headers.get('version') + ' ' + JSON.parse(r2.headers.get('version')) + ` text:[${text}]`
241
+ },
242
+ '"hi\\u2211-1" hi∑-1 text:[]'
243
+ )
244
+
245
+ runTest(
246
+ "test HEAD for GET without subscribe (with transfer-encoding)",
247
+ async () => {
248
+ await dt_p
249
+ let key = 'test-' + Math.random().toString(36).slice(2)
250
+
251
+ let r = await braid_fetch(`/${key}`, {
252
+ method: 'PUT',
253
+ version: ['hi∑-1'],
254
+ parents: [],
255
+ body: 'xy'
256
+ })
257
+ if (!r.ok) throw 'got: ' + r.statusCode
258
+
259
+ let r2 = await braid_fetch(`/${key}`, {
260
+ method: 'HEAD',
261
+ headers: {
262
+ 'accept-transfer-encoding': 'dt'
263
+ }
264
+ })
265
+
266
+ var buf = await r2.arrayBuffer()
267
+
268
+ return r2.headers.get('current-version') + ' ' + JSON.parse(r2.headers.get('current-version')) + ` buf.byteLength:${buf.byteLength}`
269
+ },
270
+ '"hi\\u2211-1" hi∑-1 buf.byteLength:0'
271
+ )
272
+
273
+ runTest(
274
+ "test Version we get from PUTing",
275
+ async () => {
276
+ await dt_p
277
+ let key = 'test-' + Math.random().toString(36).slice(2)
278
+
279
+ let r = await braid_fetch(`/${key}`, {
280
+ method: 'PUT',
281
+ version: ['hi∑-1'],
282
+ parents: [],
283
+ body: 'xy'
284
+ })
285
+ if (!r.ok) throw 'got: ' + r.statusCode
286
+
287
+ return r.headers.get('version')
288
+ },
289
+ '"hi\\u2211-1"'
290
+ )
291
+
64
292
  runTest(
65
293
  "test error code when missing parents",
66
294
  async () => {