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 +15 -25
- package/client.js +12 -21
- package/index.js +10 -4
- package/package.json +1 -1
- package/server-demo.js +2 -2
- /package/{index.html → client-demo.html} +0 -0
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
|
-
|
|
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
|
-
|
|
42
|
-

|
|
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`
|
|
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` -
|
|
94
|
-
- `
|
|
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`
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
- `
|
|
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
|
-
|
|
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
|
|
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
|
-
},
|
|
44
|
-
}).catch(
|
|
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
|
|
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 =
|
|
768
|
+
normalized.version = [normalized.version]
|
|
763
769
|
if (typeof normalized.parents === 'string')
|
|
764
|
-
normalized.parents =
|
|
770
|
+
normalized.parents = [normalized.parents]
|
|
765
771
|
|
|
766
772
|
return normalized
|
|
767
773
|
}
|
package/package.json
CHANGED
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 === '/'
|
|
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}/
|
|
31
|
+
require("fs").createReadStream(`${__dirname}/client-demo.html`).pipe(res)
|
|
32
32
|
return
|
|
33
33
|
}
|
|
34
34
|
|
|
File without changes
|