braid-blob 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.
package/README.md CHANGED
@@ -13,10 +13,8 @@ npm install braid-blob
13
13
  ### Basic Server
14
14
 
15
15
  ```javascript
16
- var braid_blob = require('braid-blob')
17
-
18
16
  require('http').createServer((req, res) => {
19
- braid_blob.serve(req, res)
17
+ require('braid-blob').serve(req, res)
20
18
  }).listen(8888)
21
19
  ```
22
20
 
@@ -38,9 +36,7 @@ node server-demo.js
38
36
 
39
37
  Then open http://localhost:8888 in your browser. You can drag and drop images to upload them, and open multiple browser windows to see real-time sync in action.
40
38
 
41
- <!-- TODO: Add demo video
42
- ![Demo](demo.mp4)
43
- -->
39
+ <video src="https://github.com/user-attachments/assets/0418a03f-31f5-4fc4-9ad4-e49fab6394c9" controls width="600"></video>
44
40
 
45
41
  ## API
46
42
 
@@ -77,11 +73,7 @@ Bidirectionally synchronizes a blob between local storage and a remote URL.
77
73
  - `url` - Remote URL (URL object)
78
74
  - `options` - Optional configuration object
79
75
  - `signal` - AbortSignal for cancellation (use to stop sync)
80
- - `content_type` / `accept` - Content type for requests
81
- - `on_pre_connect` - Async callback before connection attempt
82
- - `on_disconnect` - Callback when connection drops
83
- - `on_unauthorized` - Callback on 401/403 responses
84
- - `on_res` - Callback receiving the response object
76
+ - `content_type` - Content type for requests
85
77
 
86
78
  ### `braid_blob.get(key, options)`
87
79
 
@@ -90,11 +82,11 @@ Retrieves a blob from local storage or a remote URL.
90
82
  **Parameters:**
91
83
  - `key` - Local storage key (string) or remote URL (URL object)
92
84
  - `options` - Optional configuration object
93
- - `version` - Request a specific version
94
- - `parents` - Version parents for subscription fork-point
85
+ - `version` - Version ID to check existence (use with `head: true`)
86
+ - `parent` - Version ID; when subscribing, only receive updates newer than this
95
87
  - `subscribe` - Callback function for real-time updates
96
88
  - `head` - If true, returns only metadata (version, content_type) without body
97
- - `content_type` / `accept` - Content type for the request
89
+ - `content_type` - Content type for the request
98
90
  - `signal` - AbortSignal for cancellation
99
91
 
100
92
  **Returns:** `{version, body, content_type}` object, or `null` if not found.
@@ -126,15 +118,15 @@ A simple browser client is included for subscribing to blob updates.
126
118
 
127
119
  ```html
128
120
  <script src="https://unpkg.com/braid-http@~1.3/braid-http-client.js"></script>
129
- <script src="/client.js"></script>
121
+ <script src="http://localhost:8888/client.js"></script>
122
+ <img id="image"/>
130
123
  <script>
131
124
  braid_blob_client('http://localhost:8888/blob.png', {
132
- on_update: (blob, content_type, version) => {
133
- // Called whenever the blob is updated
134
- var url = URL.createObjectURL(new Blob([blob], { type: content_type }))
135
- document.getElementById('image').src = url
136
- },
137
- on_delete: () => console.log('Blob was deleted'),
125
+ // Called whenever the blob is updated
126
+ on_update: (blob, content_type, version) =>
127
+ image.src = URL.createObjectURL(
128
+ new Blob([blob], { type: content_type })),
129
+ on_delete: () => image.src = '',
138
130
  on_error: (e) => console.error('Error:', e)
139
131
  })
140
132
  </script>
@@ -149,10 +141,8 @@ Subscribes to a blob endpoint and receives updates.
149
141
  - `options` - Configuration object
150
142
  - `on_update(blob, content_type, version)` - Callback for updates
151
143
  - `on_delete` - Callback when blob is deleted
152
- - `on_error` - Callback for errors
153
- - `on_res` - Callback receiving the response object
154
-
155
- **Returns:** `{ stop }` - Call `stop()` to unsubscribe.
144
+ - `on_error(e)` - Callback for errors
145
+ - `signal` - AbortSignal for cancellation
156
146
 
157
147
  ## Testing
158
148
 
package/client.js CHANGED
@@ -6,27 +6,27 @@
6
6
  // on_update: (blob, content_type, version) => {
7
7
  // // Called whenever there's a new version of the blob
8
8
  // console.log('New blob:', blob, content_type, version)
9
- // }
9
+ // },
10
+ // on_delete: () => {
11
+ // // Called when the blob is deleted (404 status)
12
+ // },
13
+ // on_error: (error) => {
14
+ // // Called on connection or subscription errors
15
+ // },
16
+ // signal: ac.signal // optional AbortSignal to unsubscribe
10
17
  // })
11
18
  //
12
- // Returns: { stop } - call stop() to unsubscribe
13
- //
14
19
  function braid_blob_client(url, options = {}) {
15
- var ac = new AbortController()
16
- var peer = Math.random().toString(36).substr(2)
17
20
  var current_version = null
18
21
 
19
22
  braid_fetch(url, {
20
23
  headers: { "Merge-Type": "aww" },
21
24
  subscribe: true,
22
25
  retry: () => true,
23
- peer,
24
- signal: ac.signal
26
+ signal: options.signal
25
27
  }).then(res => {
26
- if (options.on_res) options.on_res(res)
27
-
28
28
  res.subscribe(async update => {
29
- if (update.status === 404) {
29
+ if (update.status == 404) {
30
30
  current_version = null
31
31
  if (options.on_delete) options.on_delete()
32
32
  return
@@ -40,12 +40,8 @@ function braid_blob_client(url, options = {}) {
40
40
  current_version = version
41
41
  if (options.on_update) options.on_update(update.body, content_type, update.version)
42
42
  }
43
- }, options.on_error || (e => console.error('braid_blob_client error:', e)))
44
- }).catch(options.on_error || (e => console.error('braid_blob_client error:', e)))
45
-
46
- return {
47
- stop: () => ac.abort()
48
- }
43
+ }, e => options.on_error?.(e))
44
+ }).catch(e => options.on_error?.(e))
49
45
 
50
46
  function compare_events(a, b) {
51
47
  if (!a) a = ''
@@ -60,17 +56,12 @@ function braid_blob_client(url, options = {}) {
60
56
  }
61
57
 
62
58
  function get_event_seq(e) {
63
- if (!e) return ''
64
-
65
59
  for (let i = e.length - 1; i >= 0; i--)
66
60
  if (e[i] === '-') return e.slice(i + 1)
67
61
  return e
68
62
  }
69
63
 
70
64
  function compare_seqs(a, b) {
71
- if (!a) a = ''
72
- if (!b) b = ''
73
-
74
65
  if (a.length !== b.length) return a.length - b.length
75
66
  if (a < b) return -1
76
67
  if (a > b) return 1
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var {http_server: braidify, fetch: braid_fetch} = require('braid-http')
1
+ var {http_server: braidify, fetch: braid_fetch, free_cors} = require('braid-http')
2
2
 
3
3
  function create_braid_blob() {
4
4
  var braid_blob = {
@@ -127,6 +127,8 @@ function create_braid_blob() {
127
127
  options.key = url.pathname
128
128
  }
129
129
 
130
+ free_cors(res)
131
+
130
132
  braidify(req, res)
131
133
  if (res.is_multiplexer) return
132
134
 
@@ -757,11 +759,15 @@ function create_braid_blob() {
757
759
  }
758
760
  }
759
761
 
760
- // Normalize version/parents strings to arrays
762
+ // Normalize parent -> parents
763
+ if (options.parent)
764
+ normalized.parents = options.parent
765
+
766
+ // Normalize version/parents: allow strings, wrap in array for internal use
761
767
  if (typeof normalized.version === 'string')
762
- normalized.version = JSON.parse('[' + normalized.version + ']')
768
+ normalized.version = [normalized.version]
763
769
  if (typeof normalized.parents === 'string')
764
- normalized.parents = JSON.parse('[' + normalized.parents + ']')
770
+ normalized.parents = [normalized.parents]
765
771
 
766
772
  return normalized
767
773
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-blob",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "description": "Library for collaborative blobs over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-blob",
package/server-demo.js CHANGED
@@ -23,12 +23,12 @@ var server = require("http").createServer(async (req, res) => {
23
23
  return
24
24
  }
25
25
 
26
- if (url === '/' || url === '/index.html') {
26
+ if (url === '/') {
27
27
  res.writeHead(200, {
28
28
  "Content-Type": "text/html",
29
29
  "Cache-Control": "no-cache"
30
30
  })
31
- require("fs").createReadStream(`${__dirname}/index.html`).pipe(res)
31
+ require("fs").createReadStream(`${__dirname}/client-demo.html`).pipe(res)
32
32
  return
33
33
  }
34
34
 
File without changes