braid-text 0.2.48 → 0.2.50

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 (2) hide show
  1. package/README.md +95 -69
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -37,7 +37,7 @@ Or try opening the URL in [Braid-Chrome](https://github.com/braid-org/braid-chro
37
37
 
38
38
  Check out the `server-demo.js` file to see examples for how to add simple access control, where a user need only enter a password into a cookie in the javascript console like: `document.cookie = 'password'`; and a `/pages` endpoint to show all the edited pages.
39
39
 
40
- ## General Use on Server
40
+ ## General Use as Server
41
41
 
42
42
  Install it in your project:
43
43
  ```shell
@@ -94,112 +94,138 @@ http_server.on("request", (req, res) => {
94
94
  - `patches`: <small style="color:lightgrey">[optional]</small> Array of patches, each of the form `{unit: 'text', range: '[1:3]', content: 'hi'}`, which would replace the second and third unicode code-points in the text with `hi`. See Braid [Range-Patches](https://github.com/braid-org/braid-spec/blob/master/draft-toomim-httpbis-range-patch-01.txt).
95
95
  - `peer`: <small style="color:lightgrey">[optional]</small> Identifies this peer. This mutation will not be echoed back to `get` subscriptions that use this same `peer` header.
96
96
 
97
- ## General Use on Client
97
+ ## General Use as Client
98
+
99
+ Here's a basic running example to start:
98
100
 
99
101
  ```html
102
+ <!-- 1. Your textarea -->
103
+ <textarea id="my_textarea"></textarea>
104
+
105
+ <!-- 2. Include the libraries -->
106
+ <script src="https://unpkg.com/braid-http@~1.3/braid-http-client.js"></script>
100
107
  <script src="https://unpkg.com/braid-text/simpleton-client.js"></script>
101
- <script>
102
108
 
103
- // connect to the server
104
- let simpleton = simpleton_client('https://example.org/some-resource', {
105
- apply_remote_update: ({ state, patches }) => {
106
-
107
- // Apply the incoming state or patches to local text here.
108
- //
109
- // Example data:
110
- // state: "Hello World" // The new text
111
- // patches: [{ range: [5, 5], content: " World" }] // Patches that create the new text
112
- //
113
- // Then return the new state of textarea as a string:
114
- return new_state
115
- },
116
- generate_local_diff_update: (prev_state) => {
117
-
118
- // Compute diff between prev_state ^ and the current textarea string, such as:
119
- //
120
- // var patches = [{
121
- // range: [5, 5], // The range from position 5 to position 5
122
- // content: " World" // is replaced with the string " World"
123
- // }]
124
- //
125
- // ...to insert something after a prev_state of "Hello".
126
-
127
- // Then return the new state (as a string) and the diff (as `patches`)
128
- return {new_state, patches}
129
- },
109
+ <!-- 3. Wire it up -->
110
+ <script>
111
+ // Connect to server
112
+ var simpleton = simpleton_client('https://braid.org/simpleton_example', {
113
+ on_state: state => my_textarea.value = state, // incoming changes
114
+ get_state: () => my_textarea.value // outgoing changes
130
115
  })
131
-
132
- ...
133
-
134
- // When changes occur in client's textarea, let simpleton know,
135
- // so that it can call generate_local_diff_update() to ask for them.
136
- simpleton.changed()
137
116
 
117
+ // Tell simpleton when user types
118
+ my_textarea.oninput = () => simpleton.changed()
138
119
  </script>
139
120
  ```
140
121
 
141
- See [editor.html](https://raw.githubusercontent.com/braid-org/braid-text/master/editor.html) for a simple working example.
122
+ You should see something if you run this (though the server in this example will likely ignore your changes).
142
123
 
143
- ## Client API
124
+ ### How It Works
125
+
126
+ The client uses a **decoupled update mechanism** for efficiency:
127
+
128
+ 1. When users type, you call `simpleton.changed()` to notify the client that something changed
129
+ 2. The client decides *when* to actually fetch and send updates based on network conditions
130
+ 3. When ready, it calls your `get_state` function to get the current text
131
+
132
+ This design prevents network congestion and handles disconnections gracefully. For example, if you edit offline for hours, the client will send just one efficient diff when reconnecting, rather than thousands of individual keystrokes.
133
+
134
+ ### Advanced Integration
135
+
136
+ For better performance and control, you can work with patches instead of full text:
137
+
138
+ #### Receiving Patches
139
+
140
+ Instead of receiving complete text updates, you can process individual changes:
144
141
 
145
142
  ```javascript
146
- simpleton = simpleton_client(url, options)
143
+ var simpleton = simpleton_client(url, {
144
+ on_patches: (patches) => {
145
+ // Apply each patch to your editor..
146
+ },
147
+ get_state: () => editor.getValue()
148
+ })
147
149
  ```
148
150
 
149
- - `url`: The URL of the resource to synchronize with.
150
- - `options`: An object containing the following properties:
151
+ This is more efficient for large documents and helps preserve cursor position.
151
152
 
152
- ### Incoming Updates
153
+ #### Custom Patch Generation
153
154
 
154
- - `on_patches`: <small style="color:lightgrey">[optional]</small> A function called when patches are received from the server:
155
+ You can provide your own diff algorithm or use patches from your editor's API:
155
156
 
156
- ```javascript
157
- (patches) => {...}
158
- ```
157
+ ```javascript
158
+ var simpleton = simpleton_client(url, {
159
+ on_state: state => editor.setValue(state),
160
+ get_state: () => editor.getValue(),
161
+ get_patches: (prev_state) => {
162
+ // Use your own diff algorithm or editor's change tracking
163
+ return compute_patches(prev_state, editor.getValue())
164
+ }
165
+ })
166
+ ```
159
167
 
160
- - `patches`: An array of patch objects, each representing a string-replace operation. Each patch object has:
161
- - `range`: An array of two numbers, `[start, end]`, specifying the start and end positions of the characters to be deleted.
162
- - `content`: The text to be inserted in place of the deleted characters.
168
+ See [editor.html](https://github.com/braid-org/braid-text/blob/master/editor.html) for a complete example with CodeMirror integration.
163
169
 
164
- Note that patches will always be in order, but the range positions of each patch reference the original string, i.e., the second patch's range values do not take into account the application of the first patch.
170
+ ## Client API
171
+
172
+ ### Constructor
173
+
174
+ ```javascript
175
+ simpleton = simpleton_client(url, options)
176
+ ```
165
177
 
166
- - `on_state`: <small style="color:lightgrey">[optional]</small> A function called when a complete state update is received from the server:
178
+ Creates a new Simpleton client that synchronizes with a Braid-Text server.
167
179
 
168
- ```javascript
169
- (state) => {...}
170
- ```
180
+ **Parameters:**
181
+ - `url`: The URL of the resource to synchronize with
182
+ - `options`: Configuration object with the following properties:
171
183
 
172
- - `state`: The new complete value of the text.
184
+ #### Required Options
173
185
 
174
- ### Local State Management
186
+ - `get_state`: **[required]** Function that returns the current text state
187
+ ```javascript
188
+ () => current_text_string
189
+ ```
175
190
 
176
- - `get_state`: **[required]** A function that returns the current state of the text:
191
+ #### Incoming Updates (choose one)
177
192
 
178
- ```javascript
179
- () => current_state
180
- ```
193
+ - `on_state`: <small style="color:lightgrey">[optional]</small> Callback for receiving complete state updates
194
+ ```javascript
195
+ (state) => { /* update your UI with new text */ }
196
+ ```
181
197
 
182
- - `get_patches`: <small style="color:lightgrey">[optional]</small> A function that generates patches representing changes between a previous state and the current state:
198
+ - `on_patches`: <small style="color:lightgrey">[optional]</small> Callback for receiving incremental changes
199
+ ```javascript
200
+ (patches) => { /* apply patches to your editor */ }
201
+ ```
202
+ Each patch has:
203
+ - `range`: `[start, end]` - positions to delete (in original text coordinates)
204
+ - `content`: Text to insert at that position
205
+
206
+ **Note:** All patches reference positions in the original text before any patches are applied.
183
207
 
184
- ```javascript
185
- (prev_state) => patches
186
- ```
208
+ #### Outgoing Updates
187
209
 
188
- Returns an array of patch objects representing the changes. The default implementation finds a common prefix and suffix for a simple diff, but you can provide a more sophisticated implementation or track patches directly from your editor.
210
+ - `get_patches`: <small style="color:lightgrey">[optional]</small> Custom function to generate patches
211
+ ```javascript
212
+ (previous_state) => array_of_patches
213
+ ```
214
+ If not provided, uses a simple prefix/suffix diff algorithm.
189
215
 
190
- ### Other Options
216
+ #### Additional Options
191
217
 
192
- - `content_type`: <small style="color:lightgrey">[optional]</small> If set, this value will be sent in the `Accept` and `Content-Type` headers to the server.
218
+ - `content_type`: <small style="color:lightgrey">[optional]</small> MIME type for `Accept` and `Content-Type` headers
193
219
 
194
220
  ### Methods
195
221
 
196
- - `simpleton.changed()`: Call this function to report local updates whenever they occur, e.g., in the `oninput` event handler of a textarea being synchronized. The system will call `get_patches` when it needs to send updates to the server.
222
+ - `simpleton.changed()`: Notify the client that local changes have occurred. Call this in your editor's change event handler. The client will call `get_patches` and `get_state` when it's ready to send updates.
197
223
 
198
224
  ### Deprecated Options
199
225
 
200
226
  The following options are deprecated and should be replaced with the new API:
201
227
 
202
- - ~~`apply_remote_update`~~ → Use `on_patches` and `on_state` instead
228
+ - ~~`apply_remote_update`~~ → Use `on_patches` or `on_state` instead
203
229
  - ~~`generate_local_diff_update`~~ → Use `get_patches` and `get_state` instead
204
230
 
205
231
  ## Testing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.48",
3
+ "version": "0.2.50",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",