@syncular/core 0.32.0 → 0.32.1

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/dist/crypto.js CHANGED
@@ -111,12 +111,12 @@ export function deserializePlain(declaredType, bytes) {
111
111
  catch {
112
112
  throw new DecryptError(`decrypted ${declaredType} value is not valid UTF-8`);
113
113
  }
114
- if (declaredType === 'json') {
114
+ if (declaredType === 'json' || declaredType === 'blob_ref') {
115
115
  try {
116
116
  JSON.parse(text);
117
117
  }
118
118
  catch {
119
- throw new DecryptError('decrypted json value does not parse');
119
+ throw new DecryptError(`decrypted ${declaredType} value does not parse`);
120
120
  }
121
121
  }
122
122
  return text;
package/dist/message.js CHANGED
@@ -551,6 +551,7 @@ function validateResponseSequence(frames) {
551
551
  inSubscription = true;
552
552
  sawSubscription = true;
553
553
  sawBody = true;
554
+ lastPushResult = undefined;
554
555
  subscriptionHasCommits = false;
555
556
  subscriptionHasSegments = false;
556
557
  break;
@@ -579,9 +580,11 @@ function validateResponseSequence(frames) {
579
580
  case 'ERROR':
580
581
  errorSeen = true;
581
582
  sawBody = true;
583
+ lastPushResult = undefined;
582
584
  break;
583
585
  case 'UNKNOWN':
584
586
  sawBody = true;
587
+ lastPushResult = undefined;
585
588
  break;
586
589
  }
587
590
  }
package/dist/realtime.js CHANGED
@@ -140,7 +140,10 @@ export function parseRealtimeServerEvent(text) {
140
140
  if ('error' in data) {
141
141
  // The publisher-directed error variant (`presence.too_large` /
142
142
  // `presence.forbidden`, §8.6.2) — a string code, no `kind`/`doc`.
143
- requireString(data.error, 'presence.data.error');
143
+ const error = requireString(data.error, 'presence.data.error');
144
+ if (error !== 'presence.too_large' && error !== 'presence.forbidden') {
145
+ malformed(`unknown presence error code ${JSON.stringify(error)}`);
146
+ }
144
147
  }
145
148
  else if ('kind' in data) {
146
149
  validatePresenceKind(data.kind);
package/dist/render.js CHANGED
@@ -268,6 +268,8 @@ function renderRowValue(column, value) {
268
268
  return null;
269
269
  if (value instanceof Uint8Array)
270
270
  return bytesToBase64(value);
271
+ if (typeof value === 'number')
272
+ return Number.isFinite(value) ? value : null;
271
273
  if ((column.type === 'json' || column.type === 'blob_ref') &&
272
274
  typeof value === 'string') {
273
275
  // §11: json and blob_ref (tag 7) render as embedded parsed JSON.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/core",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "description": "Core protocol types and shared utilities for the Syncular sync framework",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
package/src/crypto.ts CHANGED
@@ -148,11 +148,13 @@ export function deserializePlain(
148
148
  `decrypted ${declaredType} value is not valid UTF-8`,
149
149
  );
150
150
  }
151
- if (declaredType === 'json') {
151
+ if (declaredType === 'json' || declaredType === 'blob_ref') {
152
152
  try {
153
153
  JSON.parse(text);
154
154
  } catch {
155
- throw new DecryptError('decrypted json value does not parse');
155
+ throw new DecryptError(
156
+ `decrypted ${declaredType} value does not parse`,
157
+ );
156
158
  }
157
159
  }
158
160
  return text;
package/src/message.ts CHANGED
@@ -824,6 +824,7 @@ function validateResponseSequence(frames: readonly ResponseFrame[]): void {
824
824
  inSubscription = true;
825
825
  sawSubscription = true;
826
826
  sawBody = true;
827
+ lastPushResult = undefined;
827
828
  subscriptionHasCommits = false;
828
829
  subscriptionHasSegments = false;
829
830
  break;
@@ -853,9 +854,11 @@ function validateResponseSequence(frames: readonly ResponseFrame[]): void {
853
854
  case 'ERROR':
854
855
  errorSeen = true;
855
856
  sawBody = true;
857
+ lastPushResult = undefined;
856
858
  break;
857
859
  case 'UNKNOWN':
858
860
  sawBody = true;
861
+ lastPushResult = undefined;
859
862
  break;
860
863
  }
861
864
  }
package/src/realtime.ts CHANGED
@@ -257,7 +257,10 @@ export function parseRealtimeServerEvent(text: string): ParsedRealtimeEvent {
257
257
  if ('error' in data) {
258
258
  // The publisher-directed error variant (`presence.too_large` /
259
259
  // `presence.forbidden`, §8.6.2) — a string code, no `kind`/`doc`.
260
- requireString(data.error, 'presence.data.error');
260
+ const error = requireString(data.error, 'presence.data.error');
261
+ if (error !== 'presence.too_large' && error !== 'presence.forbidden') {
262
+ malformed(`unknown presence error code ${JSON.stringify(error)}`);
263
+ }
261
264
  } else if ('kind' in data) {
262
265
  validatePresenceKind(data.kind);
263
266
  requireString(data.actorId, 'presence.data.actorId');
package/src/render.ts CHANGED
@@ -312,6 +312,7 @@ export function renderMessage(bytes: Uint8Array): JsonValue {
312
312
  function renderRowValue(column: RowColumn, value: RowValue): JsonValue {
313
313
  if (value === null) return null;
314
314
  if (value instanceof Uint8Array) return bytesToBase64(value);
315
+ if (typeof value === 'number') return Number.isFinite(value) ? value : null;
315
316
  if (
316
317
  (column.type === 'json' || column.type === 'blob_ref') &&
317
318
  typeof value === 'string'