braidfs 0.0.54 → 0.0.56

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/README.md +53 -30
  2. package/index.js +29 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,45 @@
1
- # braidfs
1
+ # BraidFS: Braid your Filesystem with the Web
2
2
 
3
- Sync Braid URLs as files on disk.
3
+ Provides interoperability between **web pages** via http and your **OS filesystem**.
4
+ - Using collaborative CRDTs and the Braid extensions for HTTP.
4
5
 
5
- Like Dropbox (file sync), plus Google Docs (collaborative editing), all over HTTP.
6
+ The `braidfs` daemon performs bi-directional synchronization between remote Braid-HTTP resources and your local filesystem.
7
+
8
+ ### Web resources map onto your filesystem
9
+
10
+ It creates a `~/http` folder in your home directory to synchronize webpages with:
11
+
12
+ ```
13
+ ~/http/
14
+ ├── example.com/
15
+ │ ├── document.html
16
+ │ ├── notes.md
17
+ │ └── assets/
18
+ │ └── style.css
19
+ └── braid.org/
20
+ └── meeting-53
21
+ ```
22
+
23
+
24
+ https://github.com/user-attachments/assets/4fb36208-e0bd-471b-b47b-bbeee20e4f3f
25
+
26
+
27
+
28
+ ### Two-way sync edits between files and web
29
+
30
+ As long as `braidfs` is running, it will keep the file and web resources in
31
+ sync!
32
+
33
+ - Edit to the file → web resource
34
+ - Edit to the web resource → file
35
+
36
+ Each edit to the file is diffed and sent as a CRDT patch, so you can edit
37
+ files offline, and even collaboratively edit them, with one caveat:
38
+
39
+ #### Caveat
40
+
41
+ For the period of time that you have edited the file in your editor but not
42
+ saved it, external edits cannot be integrated.
6
43
 
7
44
  ## Installation
8
45
 
@@ -14,10 +51,10 @@ npm install -g braidfs
14
51
 
15
52
  ## Usage
16
53
 
17
- To start the braidfs server:
54
+ To start the braidfs daemon:
18
55
 
19
56
  ```
20
- braidfs serve
57
+ braidfs run
21
58
  ```
22
59
 
23
60
  To sync a URL:
@@ -37,45 +74,31 @@ To unsync a URL:
37
74
  braidfs unsync <url>
38
75
  ```
39
76
 
40
- ## Accessing the Server
41
-
42
- The braidfs server runs on `http://localhost:10000` by default and provides the following endpoints:
43
-
44
- - `/<url>`: Synchronizes the specified URL: creates a local file, and provides a Braid-HTTP interface
45
- - `/.braidfs/config`: Displays the current configuration
46
- - `/.braidfs/errors`: Shows the error log
47
-
48
- Accessing a URL through the proxy (e.g., `http://localhost:10000/https://example.com/file.txt`) will automatically add it to the set of synced URLs, similar to using `braidfs sync <url>`.
49
-
50
77
  ## Configuration
51
78
 
52
- braidfs looks for a configuration file at `~/http/.braidfs/config`. You can set the following options:
79
+ braidfs looks for a configuration file at `~/http/.braidfs/config`, or creates it if it doesn't exist. You can set the following options:
53
80
 
54
- - `port`: The port number for the proxy server (default: 10000)
55
- - `sync`: An object where the keys are URLs to sync, and the values are simply "true"
56
- - `domains`: An object for setting domain-specific configurations, including authentication headers
81
+ - `sync`: An object where the keys are URLs to sync, and the values are simply `true`
82
+ - `cookies`: An object for setting domain-specific cookies for authentication
83
+ - `port`: The port number for the internal daemon (default: 45678)
57
84
 
58
- Example `config.json`:
85
+ Example `config`:
59
86
 
60
87
  ```json
61
88
  {
62
- "port": 10000,
63
89
  "sync": {
64
90
  "https://example.com/document1.txt": true,
65
91
  "https://example.com/document2.txt": true
66
92
  },
67
- "domains": {
68
- "example.com": {
69
- "auth_headers": {
70
- "Cookie": "secret_pass"
71
- }
72
- }
73
- }
93
+ "cookies": {
94
+ "example.com": "secret_pass"
95
+ },
96
+ "port": 45678
74
97
  }
75
98
  ```
76
99
 
77
- The `domains` configuration allows you to set authentication headers for specific domains. In the example above, any requests to `example.com` will include the specified `Cookie` header.
100
+ The `cookies` configuration allows you to set authentication cookies for specific domains. In the example above, any requests to `example.com` will include the specified cookie value.
78
101
 
79
102
  ## Security
80
103
 
81
- braidfs is designed to run locally and only accepts connections from localhost (127.0.0.1 or ::1) for security reasons. The `domains` configuration enables secure communication with servers that require authentication by allowing you to set domain-specific headers.
104
+ braidfs is designed to run locally and only accepts connections from localhost (127.0.0.1 or ::1) for security reasons. The `cookies` configuration enables secure communication with servers that require authentication by allowing you to set domain-specific cookie values.
package/index.js CHANGED
@@ -23,14 +23,25 @@ var config = null,
23
23
  if (require('fs').existsSync(proxy_base)) {
24
24
  try {
25
25
  config = JSON.parse(require('fs').readFileSync(braidfs_config_file, 'utf8'))
26
+
27
+ // for 0.0.55 users upgrading to 0.0.56,
28
+ // which changes the config "domains" key to "cookies",
29
+ // and condenses its structure a bit
30
+ if (config.domains) {
31
+ config.cookies = Object.fromEntries(Object.entries(config.domains).map(([k, v]) => {
32
+ if (v.auth_headers?.Cookie) return [k, v.auth_headers.Cookie]
33
+ }).filter(x => x))
34
+ delete config.domains
35
+ require('fs').writeFileSync(braidfs_config_file, JSON.stringify(config, null, 4))
36
+ }
26
37
  } catch (e) {
27
38
  return console.log(`Cannot parse the configuration file at: ${braidfs_config_file}`)
28
39
  }
29
40
  } else {
30
41
  config = {
31
- port: 10000,
32
42
  sync: {},
33
- domains: { 'example.com': { auth_headers: { Cookie: "secret_pass" } } },
43
+ cookies: { 'example.com': 'secret_pass' },
44
+ port: 45678,
34
45
  scan_interval_ms: 1000 * 20,
35
46
  }
36
47
  require('fs').mkdirSync(braidfs_config_dir, { recursive: true })
@@ -43,10 +54,10 @@ require('fs').mkdirSync(temp_folder, { recursive: true })
43
54
 
44
55
  // process command line args
45
56
  let to_run_in_background = process.platform === 'darwin' ? `
46
- To run server in background:
47
- launchctl submit -l org.braid.braidfs -- braidfs serve` : ''
57
+ To run daemon in background:
58
+ launchctl submit -l org.braid.braidfs -- braidfs run` : ''
48
59
  let argv = process.argv.slice(2)
49
- if (argv.length === 1 && argv[0] === 'serve') {
60
+ if (argv.length === 1 && argv[0].match(/^(run|serve)$/)) {
50
61
  return main()
51
62
  } else if (argv.length && argv.length % 2 == 0 && argv.every((x, i) => i % 2 != 0 || x.match(/^(sync|unsync)$/))) {
52
63
  let operations = []
@@ -71,13 +82,13 @@ if (argv.length === 1 && argv[0] === 'serve') {
71
82
  }).then(() => console.log(`${operation}ed: ${url}`))
72
83
  )).then(() => console.log('All operations completed successfully.'))
73
84
  .catch(() => {
74
- return console.log(`The braidfs server does not appear to be running.
85
+ return console.log(`The braidfs daemon does not appear to be running.
75
86
  You can run it with:
76
- braidfs serve${to_run_in_background}`)
87
+ braidfs run${to_run_in_background}`)
77
88
  })
78
89
  } else {
79
90
  return console.log(`Usage:
80
- braidfs serve
91
+ braidfs run
81
92
  braidfs sync <URL>
82
93
  braidfs unsync <URL>${to_run_in_background}`)
83
94
  }
@@ -106,7 +117,7 @@ async function main() {
106
117
 
107
118
  braid_text.serve(req, res, { key: normalize_url(url) })
108
119
  }).listen(config.port, () => {
109
- console.log(`server started on port ${config.port}`)
120
+ console.log(`daemon started on port ${config.port}`)
110
121
  if (!config.allow_remote_access) console.log('!! only accessible from localhost !!')
111
122
 
112
123
  proxy_url('.braidfs/config').then(() => {
@@ -132,12 +143,12 @@ async function main() {
132
143
  // have the appropriate connections reconnect
133
144
  let changed = new Set()
134
145
  // any old domains no longer exist?
135
- for (let domain of Object.keys(prev.domains ?? {}))
136
- if (!config.domains?.[domain]) changed.add(domain)
146
+ for (let domain of Object.keys(prev.cookies ?? {}))
147
+ if (!config.cookies?.[domain]) changed.add(domain)
137
148
  // any new domains not like the old?
138
- for (let [domain, v] of Object.entries(config.domains ?? {}))
139
- if (!prev.domains?.[domain]
140
- || JSON.stringify(prev.domains[domain]) !== JSON.stringify(v))
149
+ for (let [domain, v] of Object.entries(config.cookies ?? {}))
150
+ if (!prev.cookies?.[domain]
151
+ || JSON.stringify(prev.cookies[domain]) !== JSON.stringify(v))
141
152
  changed.add(domain)
142
153
  // ok, have every domain which has changed reconnect
143
154
  for (let [path, x] of Object.entries(proxy_url.cache))
@@ -159,7 +170,7 @@ async function main() {
159
170
  watch_files()
160
171
  setTimeout(scan_files, 1200)
161
172
  }).on('error', e => {
162
- if (e.code === 'EADDRINUSE') return console.log(`server already running on port ${config.port}`)
173
+ if (e.code === 'EADDRINUSE') return console.log(`port ${config.port} is in use`)
163
174
  throw e
164
175
  })
165
176
  }
@@ -388,7 +399,7 @@ async function proxy_url(url) {
388
399
  headers: {
389
400
  "Merge-Type": "dt",
390
401
  "Content-Type": 'text/plain',
391
- ...config.domains?.[(new URL(url)).hostname]?.auth_headers,
402
+ ...(x => x && {Cookie: x})(config.cookies?.[new URL(url).hostname])
392
403
  },
393
404
  method: "PUT",
394
405
  retry: true,
@@ -542,7 +553,7 @@ async function proxy_url(url) {
542
553
  headers: {
543
554
  "Merge-Type": "dt",
544
555
  Accept: 'text/plain',
545
- ...config.domains?.[(new URL(url)).hostname]?.auth_headers,
556
+ ...(x => x && {Cookie: x})(config.cookies?.[new URL(url).hostname]),
546
557
  },
547
558
  subscribe: true,
548
559
  retry: {
@@ -594,7 +605,7 @@ async function proxy_url(url) {
594
605
  method: "HEAD",
595
606
  headers: {
596
607
  Accept: 'text/plain',
597
- ...config.domains?.[(new URL(url)).hostname]?.auth_headers,
608
+ ...(x => x && {Cookie: x})(config.cookies?.[new URL(url).hostname]),
598
609
  },
599
610
  retry: true
600
611
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braidfs",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "description": "braid technology synchronizing files and webpages",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braidfs",