braid-text 0.0.10 → 0.0.13

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.
package/README.md CHANGED
@@ -16,6 +16,8 @@ This library provides a simple http route handler, along with client code, enabl
16
16
 
17
17
  This library makes it safe, easy & efficient to add collaborative text editing to every user-editable string in your web app. Make your app multiplayer!
18
18
 
19
+ Check out the [**demo video**](https://braid.org/video/https://invisiblecollege.s3.us-west-1.amazonaws.com/braid-meeting-86.mp4#4755) 📺 from the Braid 86 release!
20
+
19
21
  ### Demo: a Wiki!
20
22
 
21
23
  This will run a collaboratively-editable wiki:
package/index.js CHANGED
@@ -118,20 +118,28 @@ braid_text.serve = async (req, res, options = {}) => {
118
118
  done()
119
119
  })
120
120
  )
121
- let patches = await req.patches()
121
+ let patches = null
122
+ let ee = null
123
+ try {
124
+ patches = await req.patches()
125
+ } catch (e) { ee = e }
122
126
  await my_prev_put_p
123
127
 
124
- let body = null
125
- if (patches[0]?.unit === 'everything') {
126
- body = patches[0].content
127
- patches = null
128
- }
129
-
130
128
  try {
129
+ if (ee) throw ee
130
+
131
+ let body = null
132
+ if (patches[0]?.unit === 'everything') {
133
+ body = patches[0].content
134
+ patches = null
135
+ }
136
+
131
137
  await braid_text.put(resource, { peer, version: req.version, parents: req.parents, patches, body, merge_type: req.headers["merge-type"] })
138
+
139
+ options.put_cb(options.key, resource.doc.get())
132
140
  } catch (e) {
133
141
  console.log(`EEE= ${e}:${e.stack}`)
134
- // we couldn't apply the version, presumably because we're missing its parents.
142
+ // we couldn't apply the version, possibly because we're missing its parents,
135
143
  // we want to send a 4XX error, so the client will resend this request later,
136
144
  // hopefully after we've received the necessary parents.
137
145
 
@@ -155,11 +163,9 @@ braid_text.serve = async (req, res, options = {}) => {
155
163
  // - 428 Precondition Required
156
164
  // - pros: the name sounds right
157
165
  // - cons: typically implies that the request was missing an http conditional field like If-Match. that is to say, it implies that the request is missing a precondition, not that the server is missing a precondition
158
- return done_my_turn(425, "The server is missing the parents of this version.")
166
+ return done_my_turn(425, "The server failed to apply this version.")
159
167
  }
160
168
 
161
- options.put_cb(options.key, resource.doc.get())
162
-
163
169
  return done_my_turn(200)
164
170
  }
165
171
 
@@ -544,11 +550,7 @@ async function file_sync(key, process_delta, get_init) {
544
550
  let threshold = 0
545
551
 
546
552
  // Ensure the existence of db_folder
547
- try {
548
- await fs.promises.access(braid_text.db_folder);
549
- } catch (err) {
550
- await fs.promises.mkdir(braid_text.db_folder, { recursive: true });
551
- }
553
+ await fs.promises.mkdir(braid_text.db_folder, { recursive: true });
552
554
 
553
555
  // Read existing files and sort by numbers.
554
556
  const files = (await get_files_for_key(key))
@@ -1273,29 +1275,23 @@ function codePoints_to_index(str, codePoints) {
1273
1275
  }
1274
1276
 
1275
1277
  function encode_filename(filename) {
1276
- // Replace all '!' with '%21'
1277
- let encoded = filename.replace(/!/g, '%21');
1278
-
1279
- // Encode the filename using encodeURIComponent()
1280
- encoded = encodeURIComponent(encoded);
1281
-
1282
- // Replace all '%2F' (for '/') with '!'
1283
- encoded = encoded.replace(/%2F/g, '!');
1284
-
1285
- return encoded;
1278
+ // Swap all "!" and "/" characters
1279
+ let swapped = filename.replace(/[!/]/g, (match) => (match === "!" ? "/" : "!"))
1280
+
1281
+ // Encode the filename using encodeURIComponent()
1282
+ let encoded = encodeURIComponent(swapped)
1283
+
1284
+ return encoded
1286
1285
  }
1287
1286
 
1288
1287
  function decode_filename(encodedFilename) {
1289
- // Replace all '!' with '%2F'
1290
- let decoded = encodedFilename.replace(/!/g, '%2F');
1291
-
1292
- // Decode the filename using decodeURIComponent()
1293
- decoded = decodeURIComponent(decoded);
1294
-
1295
- // Replace all '%21' with '!'
1296
- decoded = decoded.replace(/%21/g, '!');
1297
-
1298
- return decoded;
1288
+ // Decode the filename using decodeURIComponent()
1289
+ let decoded = decodeURIComponent(encodedFilename)
1290
+
1291
+ // Swap all "/" and "!" characters
1292
+ decoded = decoded.replace(/[!/]/g, (match) => (match === "/" ? "!" : "/"))
1293
+
1294
+ return decoded
1299
1295
  }
1300
1296
 
1301
1297
  module.exports = braid_text
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.0.10",
3
+ "version": "0.0.13",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braidjs",
package/server-demo.js CHANGED
@@ -11,6 +11,11 @@ var braid_text = require("./index.js")
11
11
  var server = require("http").createServer(async (req, res) => {
12
12
  console.log(`${req.method} ${req.url}`)
13
13
 
14
+ // Free the CORS
15
+ free_the_cors(req, res)
16
+ if (req.method === 'OPTIONS') return
17
+
18
+
14
19
  if (req.url.endsWith("?editor")) {
15
20
  res.writeHead(200, { "Content-Type": "text/html", "Cache-Control": "no-cache" })
16
21
  require("fs").createReadStream("./editor.html").pipe(res)
@@ -30,9 +35,6 @@ var server = require("http").createServer(async (req, res) => {
30
35
  // var pages = await braid_text.list()
31
36
  // res.writeHead(200, {
32
37
  // "Content-Type": "application/json",
33
- // "Access-Control-Allow-Origin": "*",
34
- // "Access-Control-Allow-Methods": "*",
35
- // "Access-Control-Allow-Headers": "*",
36
38
  // "Access-Control-Expose-Headers": "*"
37
39
  // })
38
40
  // res.end(JSON.stringify(pages))
@@ -73,3 +75,21 @@ var server = require("http").createServer(async (req, res) => {
73
75
  server.listen(port, () => {
74
76
  console.log(`server started on port ${port}`)
75
77
  })
78
+
79
+
80
+ // Free the CORS!
81
+ function free_the_cors (req, res) {
82
+ res.setHeader('Range-Request-Allow-Methods', 'PATCH, PUT')
83
+ res.setHeader('Range-Request-Allow-Units', 'json')
84
+ res.setHeader("Patches", "OK")
85
+ var free_the_cors = {
86
+ "Access-Control-Allow-Origin": "*",
87
+ "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT, UNSUBSCRIBE",
88
+ "Access-Control-Allow-Headers": "subscribe, client, version, parents, merge-type, content-type, content-range, patches, cache-control, peer"
89
+ }
90
+ Object.entries(free_the_cors).forEach(x => res.setHeader(x[0], x[1]))
91
+ if (req.method === 'OPTIONS') {
92
+ res.writeHead(200)
93
+ res.end()
94
+ }
95
+ }