@laboverwire/stitch-wasm 0.5.0 → 0.6.0

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
@@ -83,9 +83,7 @@ wasm-pack build crates/stitch-wasm # produces pkg/
83
83
  wasm-pack test --headless --chrome crates/stitch-wasm # in-browser smoke test
84
84
  ```
85
85
 
86
- The headless suite cannot host a broker, so it asserts the wasm client builds
87
- and fails gracefully when the broker is unreachable; the native broker-backed
88
- `stitch-sync` tests cover the sync engine itself.
86
+ The headless suite asserts the wasm client builds and fails gracefully when the broker is unreachable. When `STITCH_WASM_BROKER_URL` is set at build time (for example `ws://127.0.0.1:8083/mqtt` against mqdb started with `--ws-bind` and a `testuser`/`testpass` password file), it also syncs a child create to that live broker. The native broker-backed `stitch-sync` tests cover the rest of the sync engine.
89
87
 
90
88
  ## License
91
89
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "LabOverWire"
6
6
  ],
7
7
  "description": "Browser (wasm-bindgen) bindings for the stitch reactive state-sync store.",
8
- "version": "0.5.0",
8
+ "version": "0.6.0",
9
9
  "license": "Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",
package/stitch_wasm.d.ts CHANGED
@@ -25,6 +25,22 @@ export class ConnectOptions {
25
25
  set requestProblemInformation(value: boolean | null | undefined);
26
26
  get requestResponseInformation(): boolean | undefined;
27
27
  set requestResponseInformation(value: boolean | null | undefined);
28
+ /**
29
+ * Accept `Session Present = 1` on a client that holds no local session state.
30
+ *
31
+ * By default a client that has not yet established a session in this instance
32
+ * rejects a CONNACK with Session Present set to 1, sends DISCONNECT 0x82 and closes
33
+ * the connection (MQTT-3.2.2-4). Set this to `true` (together with
34
+ * `cleanStart = false`) to deliberately resume a session the broker still holds,
35
+ * for example after a page reload or crash. The client has nothing to resend in
36
+ * that case; the broker resumes delivery of the messages it holds. A CONNACK with
37
+ * Session Present set to 1 in reply to `cleanStart = true` is always rejected.
38
+ *
39
+ * The broker only keeps a session to resume if the previous connection set a non-zero
40
+ * `sessionExpiryInterval`: under MQTT v5 an absent value means 0, so the session ends
41
+ * when the connection closes.
42
+ */
43
+ resumeExistingSession: boolean;
28
44
  get sessionExpiryInterval(): number | undefined;
29
45
  set sessionExpiryInterval(value: number | null | undefined);
30
46
  set authenticationData(value: Uint8Array);
@@ -62,6 +78,13 @@ export class Cursor {
62
78
  export class Database {
63
79
  free(): void;
64
80
  [Symbol.dispose](): void;
81
+ /**
82
+ * Adds a foreign key constraint and persists to storage.
83
+ *
84
+ * # Errors
85
+ * Returns an error if storage fails.
86
+ */
87
+ addForeignKeyAsync(source_entity: string, source_field: string, target_entity: string, target_field: string, on_delete: string): Promise<void>;
65
88
  /**
66
89
  * Adds a foreign key constraint.
67
90
  *
@@ -70,12 +93,12 @@ export class Database {
70
93
  */
71
94
  addForeignKey(source_entity: string, source_field: string, target_entity: string, target_field: string, on_delete: string): void;
72
95
  /**
73
- * Adds a foreign key constraint and persists to storage.
96
+ * Adds an index on the specified fields and backfills from existing records (async).
74
97
  *
75
98
  * # Errors
76
- * Returns an error if storage fails.
99
+ * Returns an error if the storage operation fails during backfill.
77
100
  */
78
- addForeignKeyAsync(source_entity: string, source_field: string, target_entity: string, target_field: string, on_delete: string): Promise<void>;
101
+ addIndexAsync(entity: string, fields: string[]): Promise<void>;
79
102
  /**
80
103
  * Adds an index on the specified fields and backfills from existing records (sync, memory only).
81
104
  *
@@ -84,12 +107,12 @@ export class Database {
84
107
  */
85
108
  addIndex(entity: string, fields: string[]): void;
86
109
  /**
87
- * Adds an index on the specified fields and backfills from existing records (async).
110
+ * Adds a NOT NULL constraint and persists to storage.
88
111
  *
89
112
  * # Errors
90
- * Returns an error if the storage operation fails during backfill.
113
+ * Returns an error if storage fails.
91
114
  */
92
- addIndexAsync(entity: string, fields: string[]): Promise<void>;
115
+ addNotNullAsync(entity: string, field: string): Promise<void>;
93
116
  /**
94
117
  * Adds a NOT NULL constraint on the specified field.
95
118
  *
@@ -98,12 +121,12 @@ export class Database {
98
121
  */
99
122
  addNotNull(entity: string, field: string): void;
100
123
  /**
101
- * Adds a NOT NULL constraint and persists to storage.
124
+ * Adds a relationship definition and persists to storage.
102
125
  *
103
126
  * # Errors
104
127
  * Returns an error if storage fails.
105
128
  */
106
- addNotNullAsync(entity: string, field: string): Promise<void>;
129
+ addRelationshipAsync(source_entity: string, field: string, target_entity: string): Promise<void>;
107
130
  /**
108
131
  * Adds a relationship definition for eager loading.
109
132
  *
@@ -112,12 +135,12 @@ export class Database {
112
135
  */
113
136
  addRelationship(source_entity: string, field: string, target_entity: string): void;
114
137
  /**
115
- * Adds a relationship definition and persists to storage.
138
+ * Adds a schema definition for an entity and persists to storage.
116
139
  *
117
140
  * # Errors
118
- * Returns an error if storage fails.
141
+ * Returns an error if the schema definition is invalid or storage fails.
119
142
  */
120
- addRelationshipAsync(source_entity: string, field: string, target_entity: string): Promise<void>;
143
+ addSchemaAsync(entity: string, schema_js: any): Promise<void>;
121
144
  /**
122
145
  * Adds a schema definition for an entity (sync, memory backend only).
123
146
  *
@@ -126,12 +149,12 @@ export class Database {
126
149
  */
127
150
  addSchema(entity: string, schema_js: any): void;
128
151
  /**
129
- * Adds a schema definition for an entity and persists to storage.
152
+ * Adds a unique constraint and persists to storage.
130
153
  *
131
154
  * # Errors
132
- * Returns an error if the schema definition is invalid or storage fails.
155
+ * Returns an error if storage fails.
133
156
  */
134
- addSchemaAsync(entity: string, schema_js: any): Promise<void>;
157
+ addUniqueConstraintAsync(entity: string, fields: string[]): Promise<void>;
135
158
  /**
136
159
  * Adds a unique constraint on the specified fields.
137
160
  *
@@ -140,12 +163,10 @@ export class Database {
140
163
  */
141
164
  addUniqueConstraint(entity: string, fields: string[]): void;
142
165
  /**
143
- * Adds a unique constraint and persists to storage.
144
- *
145
166
  * # Errors
146
- * Returns an error if storage fails.
167
+ * Returns an error if options are invalid or the backend is not memory-based.
147
168
  */
148
- addUniqueConstraintAsync(entity: string, fields: string[]): Promise<void>;
169
+ countSync(entity: string, options: any): number;
149
170
  /**
150
171
  * Counts records matching optional filters, using indexes when available.
151
172
  *
@@ -155,9 +176,9 @@ export class Database {
155
176
  count(entity: string, options: any): Promise<number>;
156
177
  /**
157
178
  * # Errors
158
- * Returns an error if options are invalid or the backend is not memory-based.
179
+ * Returns an error if validation fails or the backend is not memory-based.
159
180
  */
160
- countSync(entity: string, options: any): number;
181
+ createSync(entity: string, data: any): any;
161
182
  /**
162
183
  * Creates a new record in the specified entity.
163
184
  *
@@ -165,11 +186,6 @@ export class Database {
165
186
  * Returns an error if validation fails or the storage operation fails.
166
187
  */
167
188
  create(entity: string, data: any): Promise<any>;
168
- /**
169
- * # Errors
170
- * Returns an error if validation fails or the backend is not memory-based.
171
- */
172
- createSync(entity: string, data: any): any;
173
189
  /**
174
190
  * Creates a cursor for streaming iteration over records.
175
191
  *
@@ -177,6 +193,11 @@ export class Database {
177
193
  * Returns an error if options are invalid or the storage operation fails.
178
194
  */
179
195
  cursor(entity: string, options: any): Promise<Cursor>;
196
+ /**
197
+ * # Errors
198
+ * Returns an error if the record is not found, foreign key constraints prevent deletion, or the backend is not memory-based.
199
+ */
200
+ deleteSync(entity: string, id: string): void;
180
201
  /**
181
202
  * Deletes a record by entity and ID.
182
203
  *
@@ -184,11 +205,6 @@ export class Database {
184
205
  * Returns an error if the record is not found or foreign key constraints prevent deletion.
185
206
  */
186
207
  delete(entity: string, id: string): Promise<void>;
187
- /**
188
- * # Errors
189
- * Returns an error if the record is not found, foreign key constraints prevent deletion, or the backend is not memory-based.
190
- */
191
- deleteSync(entity: string, id: string): void;
192
208
  /**
193
209
  * Executes a database operation based on an MQTT-style topic.
194
210
  *
@@ -219,13 +235,6 @@ export class Database {
219
235
  */
220
236
  heartbeat(sub_id: string): boolean;
221
237
  isMemoryBackend(): boolean;
222
- /**
223
- * Lists records from an entity with optional filtering, sorting, and pagination.
224
- *
225
- * # Errors
226
- * Returns an error if options are invalid or the storage operation fails.
227
- */
228
- list(entity: string, options: any): Promise<any>;
229
238
  listConstraints(entity: string): any;
230
239
  /**
231
240
  * # Errors
@@ -238,16 +247,16 @@ export class Database {
238
247
  * Returns an error if options are invalid or the backend is not memory-based.
239
248
  */
240
249
  listSync(entity: string, options: any): any;
241
- constructor();
242
- static openEncrypted(db_name: string, passphrase: string): Promise<Database>;
243
- static openPersistent(db_name: string): Promise<Database>;
244
250
  /**
245
- * Reads a record by entity and ID.
251
+ * Lists records from an entity with optional filtering, sorting, and pagination.
246
252
  *
247
253
  * # Errors
248
- * Returns an error if the record is not found or deserialization fails.
254
+ * Returns an error if options are invalid or the storage operation fails.
249
255
  */
250
- read(entity: string, id: string): Promise<any>;
256
+ list(entity: string, options: any): Promise<any>;
257
+ constructor();
258
+ static openEncrypted(db_name: string, passphrase: string): Promise<Database>;
259
+ static openPersistent(db_name: string): Promise<Database>;
251
260
  /**
252
261
  * # Errors
253
262
  * Returns an error if the record is not found or the backend is not memory-based.
@@ -261,10 +270,12 @@ export class Database {
261
270
  */
262
271
  readWithIncludes(entity: string, id: string, includes: any): Promise<any>;
263
272
  /**
273
+ * Reads a record by entity and ID.
274
+ *
264
275
  * # Errors
265
- * Returns `JsValue` if the database is currently borrowed.
276
+ * Returns an error if the record is not found or deserialization fails.
266
277
  */
267
- subscribe(pattern: string, entity: string | null | undefined, callback: Function): string;
278
+ read(entity: string, id: string): Promise<any>;
268
279
  /**
269
280
  * # Errors
270
281
  * Returns `JsValue` if the database is currently borrowed.
@@ -274,19 +285,24 @@ export class Database {
274
285
  * # Errors
275
286
  * Returns `JsValue` if the database is currently borrowed.
276
287
  */
277
- unsubscribe(sub_id: string): boolean;
288
+ subscribe(pattern: string, entity: string | null | undefined, callback: Function): string;
278
289
  /**
279
- * Updates an existing record with new field values.
280
- *
281
290
  * # Errors
282
- * Returns an error if the record is not found or validation fails.
291
+ * Returns `JsValue` if the database is currently borrowed.
283
292
  */
284
- update(entity: string, id: string, fields: any): Promise<any>;
293
+ unsubscribe(sub_id: string): boolean;
285
294
  /**
286
295
  * # Errors
287
296
  * Returns an error if the record is not found, validation fails, or the backend is not memory-based.
288
297
  */
289
298
  updateSync(entity: string, id: string, fields: any): any;
299
+ /**
300
+ * Updates an existing record with new field values.
301
+ *
302
+ * # Errors
303
+ * Returns an error if the record is not found or validation fails.
304
+ */
305
+ update(entity: string, id: string, fields: any): Promise<any>;
290
306
  }
291
307
 
292
308
  export class MessageProperties {
@@ -309,12 +325,12 @@ export class MqttClient {
309
325
  * # Errors
310
326
  * Returns an error if connection fails.
311
327
  */
312
- connect(url: string): Promise<void>;
328
+ connectBroadcastChannel(channelName: string): Promise<void>;
313
329
  /**
314
330
  * # Errors
315
331
  * Returns an error if connection fails.
316
332
  */
317
- connectBroadcastChannel(channelName: string): Promise<void>;
333
+ connectMessagePortWithOptions(port: MessagePort, config: ConnectOptions): Promise<void>;
318
334
  /**
319
335
  * # Errors
320
336
  * Returns an error if connection fails.
@@ -324,12 +340,12 @@ export class MqttClient {
324
340
  * # Errors
325
341
  * Returns an error if connection fails.
326
342
  */
327
- connectMessagePortWithOptions(port: MessagePort, config: ConnectOptions): Promise<void>;
343
+ connectWithOptions(url: string, config: ConnectOptions): Promise<void>;
328
344
  /**
329
345
  * # Errors
330
346
  * Returns an error if connection fails.
331
347
  */
332
- connectWithOptions(url: string, config: ConnectOptions): Promise<void>;
348
+ connect(url: string): Promise<void>;
333
349
  destroy(): void;
334
350
  /**
335
351
  * # Errors
@@ -352,22 +368,22 @@ export class MqttClient {
352
368
  * # Errors
353
369
  * Returns an error if not connected or publish fails.
354
370
  */
355
- publish(topic: string, payload: Uint8Array): Promise<void>;
371
+ publishQos1(topic: string, payload: Uint8Array, callback: Function): Promise<number>;
356
372
  /**
357
373
  * # Errors
358
374
  * Returns an error if not connected or publish fails.
359
375
  */
360
- publishQos1(topic: string, payload: Uint8Array, callback: Function): Promise<number>;
376
+ publishQos2(topic: string, payload: Uint8Array, callback: Function): Promise<number>;
361
377
  /**
362
378
  * # Errors
363
379
  * Returns an error if not connected or publish fails.
364
380
  */
365
- publishQos2(topic: string, payload: Uint8Array, callback: Function): Promise<number>;
381
+ publishWithOptions(topic: string, payload: Uint8Array, options: PublishOptions): Promise<number>;
366
382
  /**
367
383
  * # Errors
368
384
  * Returns an error if not connected or publish fails.
369
385
  */
370
- publishWithOptions(topic: string, payload: Uint8Array, options: PublishOptions): Promise<void>;
386
+ publish(topic: string, payload: Uint8Array): Promise<void>;
371
387
  /**
372
388
  * # Errors
373
389
  * Returns an error if no auth method is set or send fails.
@@ -378,17 +394,17 @@ export class MqttClient {
378
394
  * # Errors
379
395
  * Returns an error if not connected or subscribe fails.
380
396
  */
381
- subscribe(topic: string): Promise<number>;
397
+ subscribeWithCallback(topic: string, callback: Function): Promise<number>;
382
398
  /**
383
399
  * # Errors
384
400
  * Returns an error if not connected or subscribe fails.
385
401
  */
386
- subscribeWithCallback(topic: string, callback: Function): Promise<number>;
402
+ subscribeWithOptions(topic: string, callback: Function, options: SubscribeOptions): Promise<number>;
387
403
  /**
388
404
  * # Errors
389
405
  * Returns an error if not connected or subscribe fails.
390
406
  */
391
- subscribeWithOptions(topic: string, callback: Function, options: SubscribeOptions): Promise<number>;
407
+ subscribe(topic: string): Promise<number>;
392
408
  /**
393
409
  * # Errors
394
410
  * Returns an error if not connected or unsubscribe fails.
@@ -477,6 +493,15 @@ export class Store {
477
493
  * Returns an error if the write fails.
478
494
  */
479
495
  create(entity: string, scope_id: string, data: any, tag?: string | null): Promise<string>;
496
+ /**
497
+ * Compare-and-set delete: remove the row only if its server version still
498
+ * equals `expectedVersion`. Same semantics as `updateIf`.
499
+ *
500
+ * # Errors
501
+ * Returns an error if the argument is malformed, there is no connected
502
+ * remote, or the broker rejects the write (including version mismatch).
503
+ */
504
+ deleteIf(entity: string, id: string, expected_version: number): Promise<void>;
480
505
  /**
481
506
  * Delete a row. No-op if absent.
482
507
  *
@@ -513,20 +538,20 @@ export class Store {
513
538
  */
514
539
  getChildCount(entity: string, scope_id: string): number;
515
540
  /**
516
- * Snapshot of all rows for `entity` within `scopeId`. Equivalent to TS
517
- * `getSnapshot`.
541
+ * Snapshot of `entity` within `scopeId` as an object keyed by row id.
518
542
  *
519
543
  * # Errors
520
544
  * Returns an error if the read fails.
521
545
  */
522
- getSnapshot(entity: string, scope_id: string): any;
546
+ getSnapshotAsMap(entity: string, scope_id: string): any;
523
547
  /**
524
- * Snapshot of `entity` within `scopeId` as an object keyed by row id.
548
+ * Snapshot of all rows for `entity` within `scopeId`. Equivalent to TS
549
+ * `getSnapshot`.
525
550
  *
526
551
  * # Errors
527
552
  * Returns an error if the read fails.
528
553
  */
529
- getSnapshotAsMap(entity: string, scope_id: string): any;
554
+ getSnapshot(entity: string, scope_id: string): any;
530
555
  /**
531
556
  * Change token for `(scopeId, entity)`: increments on every mutation and on
532
557
  * scope load, and resets to `0` when the scope is cleared or replaced by
@@ -570,14 +595,6 @@ export class Store {
570
595
  * Returns an error if the store is not initialized.
571
596
  */
572
597
  isReconnecting(): boolean;
573
- /**
574
- * List rows of `entity`, optionally filtered/sorted. `filter` is
575
- * `{ scopeId?, sort?: [{ field, direction }], projection?: [string] }`.
576
- *
577
- * # Errors
578
- * Returns an error if the read fails or `filter` is malformed.
579
- */
580
- list(entity: string, filter: any): Promise<any>;
581
598
  /**
582
599
  * List all root entities across scopes, optionally sorted (`[{ field,
583
600
  * direction }]`).
@@ -586,6 +603,14 @@ export class Store {
586
603
  * Returns an error if the read fails or `sort` is malformed.
587
604
  */
588
605
  listRootEntities(sort: any): Promise<any>;
606
+ /**
607
+ * List rows of `entity`, optionally filtered/sorted. `filter` is
608
+ * `{ scopeId?, sort?: [{ field, direction }], projection?: [string] }`.
609
+ *
610
+ * # Errors
611
+ * Returns an error if the read fails or `filter` is malformed.
612
+ */
613
+ list(entity: string, filter: any): Promise<any>;
589
614
  /**
590
615
  * Load a scope's rows into the in-memory cache from caller-supplied data,
591
616
  * `{ entity: [records] }`, replacing any currently-loaded scope. Equivalent
@@ -605,21 +630,21 @@ export class Store {
605
630
  */
606
631
  pendingMutationCount(scope_id: string): Promise<number>;
607
632
  /**
608
- * Read a single row from the in-memory cache, or `null` if absent.
633
+ * Read a row straight from durable persistence, bypassing the in-memory
634
+ * cache. Returns `null` if absent. Falls back to memory when the store has
635
+ * no persistence configured.
609
636
  *
610
637
  * # Errors
611
638
  * Returns an error if the read fails.
612
639
  */
613
- read(entity: string, id: string): any;
640
+ readLocalState(entity: string, id: string): Promise<any>;
614
641
  /**
615
- * Read a row straight from durable persistence, bypassing the in-memory
616
- * cache. Returns `null` if absent. Falls back to memory when the store has
617
- * no persistence configured.
642
+ * Read a single row from the in-memory cache, or `null` if absent.
618
643
  *
619
644
  * # Errors
620
645
  * Returns an error if the read fails.
621
646
  */
622
- readLocalState(entity: string, id: string): Promise<any>;
647
+ read(entity: string, id: string): any;
623
648
  /**
624
649
  * `true` once [`Store::initialize`] has completed.
625
650
  */
@@ -701,12 +726,16 @@ export class Store {
701
726
  */
702
727
  subscribeToScope(scope_id: string, entity: string, callback: Function): any;
703
728
  /**
704
- * Partial-update a row.
729
+ * Compare-and-set update: apply `fields` only if the row's server version
730
+ * still equals `expectedVersion` (from a prior row's `_version`). Returns
731
+ * the new version. Requires a live remote; rejects with a
732
+ * `preconditionFailed` error on a stale version.
705
733
  *
706
734
  * # Errors
707
- * Returns an error if the write fails.
735
+ * Returns an error if the argument is malformed, there is no connected
736
+ * remote, or the broker rejects the write (including version mismatch).
708
737
  */
709
- update(entity: string, id: string, fields: any, tag?: string | null): Promise<void>;
738
+ updateIf(entity: string, id: string, fields: any, expected_version: number): Promise<number>;
710
739
  /**
711
740
  * Upsert into persistence directly, bypassing memory and remote.
712
741
  *
@@ -714,6 +743,13 @@ export class Store {
714
743
  * Returns an error if the write fails.
715
744
  */
716
745
  updateLocalState(entity: string, id: string, fields: any): Promise<void>;
746
+ /**
747
+ * Partial-update a row.
748
+ *
749
+ * # Errors
750
+ * Returns an error if the write fails.
751
+ */
752
+ update(entity: string, id: string, fields: any, tag?: string | null): Promise<void>;
717
753
  }
718
754
 
719
755
  export class SubscribeOptions {