braid-text 0.3.5 → 0.3.7

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.
@@ -57,6 +57,8 @@ function simpleton_client(url, {
57
57
  var char_counter = -1
58
58
  var outstanding_changes = 0
59
59
  var max_outstanding_changes = 10
60
+ var throttled = false
61
+ var throttled_update = null
60
62
  var ac = new AbortController()
61
63
 
62
64
  // temporary: our old code uses this deprecated api,
@@ -77,84 +79,108 @@ function simpleton_client(url, {
77
79
  res.subscribe(async update => {
78
80
  // Only accept the update if its parents == our current version
79
81
  update.parents.sort()
80
- if (current_version.length === update.parents.length
81
- && current_version.every((v, i) => v === update.parents[i])) {
82
- current_version = update.version.sort()
83
- update.state = update.body_text
84
-
85
- if (update.patches) {
86
- for (let p of update.patches) {
87
- p.range = p.range.match(/\d+/g).map((x) => 1 * x)
88
- p.content = p.content_text
89
- }
90
- update.patches.sort((a, b) => a.range[0] - b.range[0])
91
-
92
- // convert from code-points to js-indicies
93
- let c = 0
94
- let i = 0
95
- for (let p of update.patches) {
96
- while (c < p.range[0]) {
97
- i += get_char_size(prev_state, i)
98
- c++
99
- }
100
- p.range[0] = i
101
-
102
- while (c < p.range[1]) {
103
- i += get_char_size(prev_state, i)
104
- c++
105
- }
106
- p.range[1] = i
107
- }
108
- }
82
+ if (v_eq(current_version, update.parents)) {
83
+ if (throttled) throttled_update = update
84
+ else await apply_update(update)
85
+ }
86
+ }, on_error)
87
+ }).catch(on_error)
109
88
 
110
- if (apply_remote_update) {
111
- // DEPRECATED
112
- prev_state = apply_remote_update(update)
113
- } else {
114
- var patches = update.patches ||
115
- [{range: [0, 0], content: update.state}]
116
- if (on_patches) {
117
- on_patches(patches)
118
- prev_state = get_state()
119
- } else prev_state = apply_patches(prev_state, patches)
120
- }
89
+ async function apply_update(update) {
90
+ current_version = update.version
91
+ update.state = update.body_text
92
+
93
+ if (update.patches) {
94
+ for (let p of update.patches) {
95
+ p.range = p.range.match(/\d+/g).map((x) => 1 * x)
96
+ p.content = p.content_text
97
+ }
98
+ update.patches.sort((a, b) => a.range[0] - b.range[0])
121
99
 
122
- // if the server gave us a digest,
123
- // go ahead and check it against our new state..
124
- if (update.extra_headers &&
125
- update.extra_headers["repr-digest"] &&
126
- update.extra_headers["repr-digest"].startsWith('sha-256=') &&
127
- update.extra_headers["repr-digest"] !== await get_digest(prev_state)) {
128
- console.log('repr-digest mismatch!')
129
- console.log('repr-digest: ' + update.extra_headers["repr-digest"])
130
- console.log('state: ' + prev_state)
131
- throw new Error('repr-digest mismatch')
100
+ // convert from code-points to js-indicies
101
+ let c = 0
102
+ let i = 0
103
+ for (let p of update.patches) {
104
+ while (c < p.range[0]) {
105
+ i += get_char_size(prev_state, i)
106
+ c++
132
107
  }
108
+ p.range[0] = i
133
109
 
134
- if (on_state) on_state(prev_state)
110
+ while (c < p.range[1]) {
111
+ i += get_char_size(prev_state, i)
112
+ c++
113
+ }
114
+ p.range[1] = i
135
115
  }
136
- }, on_error)
137
- }).catch(on_error)
138
-
116
+ }
117
+
118
+ if (apply_remote_update) {
119
+ // DEPRECATED
120
+ prev_state = apply_remote_update(update)
121
+ } else {
122
+ var patches = update.patches ||
123
+ [{range: [0, 0], content: update.state}]
124
+ if (on_patches) {
125
+ on_patches(patches)
126
+ prev_state = get_state()
127
+ } else prev_state = apply_patches(prev_state, patches)
128
+ }
129
+
130
+ // if the server gave us a digest,
131
+ // go ahead and check it against our new state..
132
+ if (update.extra_headers &&
133
+ update.extra_headers["repr-digest"] &&
134
+ update.extra_headers["repr-digest"].startsWith('sha-256=') &&
135
+ update.extra_headers["repr-digest"] !== await get_digest(prev_state)) {
136
+ console.log('repr-digest mismatch!')
137
+ console.log('repr-digest: ' + update.extra_headers["repr-digest"])
138
+ console.log('state: ' + prev_state)
139
+ throw new Error('repr-digest mismatch')
140
+ }
141
+
142
+ if (on_state) on_state(prev_state)
143
+ }
144
+
139
145
  return {
140
146
  stop: async () => {
141
147
  ac.abort()
142
148
  },
143
149
  changed: () => {
144
- if (outstanding_changes >= max_outstanding_changes) return
150
+ function get_change() {
151
+ if (generate_local_diff_update) {
152
+ // DEPRECATED
153
+ var update = generate_local_diff_update(prev_state)
154
+ if (!update) return null
155
+ return update
156
+ } else {
157
+ var new_state = get_state()
158
+ if (new_state === prev_state) return null
159
+ var patches = get_patches ? get_patches(prev_state) :
160
+ [simple_diff(prev_state, new_state)]
161
+ return {patches, new_state}
162
+ }
163
+ }
145
164
 
146
- if (generate_local_diff_update) {
147
- // DEPRECATED
148
- var update = generate_local_diff_update(prev_state)
149
- if (!update) return // Stop if there wasn't a change!
150
- var {patches, new_state} = update
151
- } else {
152
- var new_state = get_state()
153
- if (new_state === prev_state) return // Stop if there wasn't a change!
154
- var patches = get_patches ? get_patches(prev_state) :
155
- [simple_diff(prev_state, new_state)]
165
+ var change = get_change()
166
+ if (!change) {
167
+ if (throttled) {
168
+ throttled = false
169
+ if (throttled_update &&
170
+ v_eq(current_version, throttled_update.parents))
171
+ apply_update(throttled_update).catch(on_error)
172
+ throttled_update = null
173
+ }
174
+ return
175
+ }
176
+
177
+ if (outstanding_changes >= max_outstanding_changes) {
178
+ throttled = true
179
+ return
156
180
  }
157
181
 
182
+ var {patches, new_state} = change
183
+
158
184
  // Save JS-index patches before code-point conversion mutates them
159
185
  var js_patches = patches.map(p => ({range: [...p.range], content: p.content}))
160
186
 
@@ -210,17 +236,12 @@ function simpleton_client(url, {
210
236
  outstanding_changes--
211
237
  if (on_ack && !outstanding_changes) on_ack()
212
238
 
239
+ throttled = false
240
+
213
241
  // Check for more changes that accumulated while we were sending
214
- if (generate_local_diff_update) {
215
- update = generate_local_diff_update(prev_state)
216
- if (!update) return
217
- ;({patches, new_state} = update)
218
- } else {
219
- new_state = get_state()
220
- if (new_state === prev_state) return
221
- patches = get_patches ? get_patches(prev_state) :
222
- [simple_diff(prev_state, new_state)]
223
- }
242
+ var more = get_change()
243
+ if (!more) return
244
+ ;({patches, new_state} = more)
224
245
  }
225
246
  })()
226
247
 
@@ -228,6 +249,10 @@ function simpleton_client(url, {
228
249
  }
229
250
  }
230
251
 
252
+ function v_eq(a, b) {
253
+ return a.length === b.length && a.every((v, i) => v === b[i])
254
+ }
255
+
231
256
  function get_char_size(s, i) {
232
257
  const charCode = s.charCodeAt(i)
233
258
  return (charCode >= 0xd800 && charCode <= 0xdbff) ? 2 : 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
@@ -23,6 +23,6 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@braid.org/diamond-types-node": "^2.0.1",
26
- "braid-http": "^1.3.105"
26
+ "braid-http": "^1.3.106"
27
27
  }
28
28
  }