hyperstack-typescript 0.2.5 → 0.3.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/dist/index.esm.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { inflate } from 'pako';
2
+
1
3
  const DEFAULT_MAX_ENTRIES_PER_VIEW = 10000;
2
4
  const DEFAULT_CONFIG = {
3
5
  reconnectIntervals: [1000, 2000, 4000, 8000, 16000],
@@ -13,16 +15,40 @@ class HyperStackError extends Error {
13
15
  }
14
16
  }
15
17
 
18
+ function isCompressedFrame(obj) {
19
+ return (typeof obj === 'object' &&
20
+ obj !== null &&
21
+ obj.compressed === 'gzip' &&
22
+ typeof obj.data === 'string');
23
+ }
24
+ function decompressGzip(base64Data) {
25
+ const binaryString = atob(base64Data);
26
+ const bytes = new Uint8Array(binaryString.length);
27
+ for (let i = 0; i < binaryString.length; i++) {
28
+ bytes[i] = binaryString.charCodeAt(i);
29
+ }
30
+ const decompressed = inflate(bytes);
31
+ return new TextDecoder().decode(decompressed);
32
+ }
33
+ function parseAndDecompress(jsonString) {
34
+ const parsed = JSON.parse(jsonString);
35
+ if (isCompressedFrame(parsed)) {
36
+ const decompressedJson = decompressGzip(parsed.data);
37
+ const frame = JSON.parse(decompressedJson);
38
+ return frame;
39
+ }
40
+ return parsed;
41
+ }
16
42
  function isSnapshotFrame(frame) {
17
43
  return frame.op === 'snapshot';
18
44
  }
19
45
  function parseFrame(data) {
20
46
  if (typeof data === 'string') {
21
- return JSON.parse(data);
47
+ return parseAndDecompress(data);
22
48
  }
23
49
  const decoder = new TextDecoder('utf-8');
24
50
  const jsonString = decoder.decode(data);
25
- return JSON.parse(jsonString);
51
+ return parseAndDecompress(jsonString);
26
52
  }
27
53
  async function parseFrameFromBlob(blob) {
28
54
  const arrayBuffer = await blob.arrayBuffer();
@@ -119,6 +145,7 @@ class ConnectionManager {
119
145
  this.notifyFrameHandlers(frame);
120
146
  }
121
147
  catch (error) {
148
+ console.error('[hyperstack] Error parsing frame:', error);
122
149
  this.updateState('error', 'Failed to parse frame from server');
123
150
  }
124
151
  };
@@ -251,57 +278,6 @@ class ConnectionManager {
251
278
  }
252
279
  }
253
280
 
254
- class ViewData {
255
- constructor() {
256
- this.entities = new Map();
257
- this.accessOrder = [];
258
- }
259
- get(key) {
260
- return this.entities.get(key);
261
- }
262
- set(key, value) {
263
- if (!this.entities.has(key)) {
264
- this.accessOrder.push(key);
265
- }
266
- else {
267
- this.touch(key);
268
- }
269
- this.entities.set(key, value);
270
- }
271
- delete(key) {
272
- const idx = this.accessOrder.indexOf(key);
273
- if (idx !== -1) {
274
- this.accessOrder.splice(idx, 1);
275
- }
276
- return this.entities.delete(key);
277
- }
278
- has(key) {
279
- return this.entities.has(key);
280
- }
281
- values() {
282
- return this.entities.values();
283
- }
284
- keys() {
285
- return this.entities.keys();
286
- }
287
- get size() {
288
- return this.entities.size;
289
- }
290
- touch(key) {
291
- const idx = this.accessOrder.indexOf(key);
292
- if (idx !== -1) {
293
- this.accessOrder.splice(idx, 1);
294
- this.accessOrder.push(key);
295
- }
296
- }
297
- evictOldest() {
298
- const oldest = this.accessOrder.shift();
299
- if (oldest !== undefined) {
300
- this.entities.delete(oldest);
301
- }
302
- return oldest;
303
- }
304
- }
305
281
  function isObject(item) {
306
282
  return item !== null && typeof item === 'object' && !Array.isArray(item);
307
283
  }
@@ -331,189 +307,234 @@ function deepMergeWithAppend(target, source, appendPaths, currentPath = '') {
331
307
  }
332
308
  return result;
333
309
  }
334
- class EntityStore {
335
- constructor(config = {}) {
336
- this.views = new Map();
337
- this.updateCallbacks = new Set();
338
- this.richUpdateCallbacks = new Set();
310
+ class FrameProcessor {
311
+ constructor(storage, config = {}) {
312
+ this.storage = storage;
339
313
  this.maxEntriesPerView = config.maxEntriesPerView === undefined
340
314
  ? DEFAULT_MAX_ENTRIES_PER_VIEW
341
315
  : config.maxEntriesPerView;
342
316
  }
343
- enforceMaxEntries(viewData) {
344
- if (this.maxEntriesPerView === null)
345
- return;
346
- while (viewData.size > this.maxEntriesPerView) {
347
- viewData.evictOldest();
348
- }
349
- }
350
317
  handleFrame(frame) {
351
318
  if (isSnapshotFrame(frame)) {
352
319
  this.handleSnapshotFrame(frame);
353
- return;
354
320
  }
355
- this.handleEntityFrame(frame);
321
+ else {
322
+ this.handleEntityFrame(frame);
323
+ }
356
324
  }
357
325
  handleSnapshotFrame(frame) {
358
326
  const viewPath = frame.entity;
359
- let viewData = this.views.get(viewPath);
360
- if (!viewData) {
361
- viewData = new ViewData();
362
- this.views.set(viewPath, viewData);
363
- }
364
327
  for (const entity of frame.data) {
365
- const previousValue = viewData.get(entity.key);
366
- viewData.set(entity.key, entity.data);
367
- this.notifyUpdate(viewPath, entity.key, {
328
+ const previousValue = this.storage.get(viewPath, entity.key);
329
+ this.storage.set(viewPath, entity.key, entity.data);
330
+ this.storage.notifyUpdate(viewPath, entity.key, {
368
331
  type: 'upsert',
369
332
  key: entity.key,
370
333
  data: entity.data,
371
334
  });
372
- this.notifyRichUpdate(viewPath, entity.key, previousValue, entity.data, 'upsert');
335
+ this.emitRichUpdate(viewPath, entity.key, previousValue, entity.data, 'upsert');
373
336
  }
374
- this.enforceMaxEntries(viewData);
337
+ this.enforceMaxEntries(viewPath);
375
338
  }
376
339
  handleEntityFrame(frame) {
377
340
  const viewPath = frame.entity;
378
- let viewData = this.views.get(viewPath);
379
- if (!viewData) {
380
- viewData = new ViewData();
381
- this.views.set(viewPath, viewData);
382
- }
383
- const previousValue = viewData.get(frame.key);
341
+ const previousValue = this.storage.get(viewPath, frame.key);
384
342
  switch (frame.op) {
385
343
  case 'create':
386
344
  case 'upsert':
387
- viewData.set(frame.key, frame.data);
388
- this.enforceMaxEntries(viewData);
389
- this.notifyUpdate(viewPath, frame.key, {
345
+ this.storage.set(viewPath, frame.key, frame.data);
346
+ this.enforceMaxEntries(viewPath);
347
+ this.storage.notifyUpdate(viewPath, frame.key, {
390
348
  type: 'upsert',
391
349
  key: frame.key,
392
350
  data: frame.data,
393
351
  });
394
- this.notifyRichUpdate(viewPath, frame.key, previousValue, frame.data, frame.op);
352
+ this.emitRichUpdate(viewPath, frame.key, previousValue, frame.data, frame.op);
395
353
  break;
396
354
  case 'patch': {
397
- const existing = viewData.get(frame.key);
355
+ const existing = this.storage.get(viewPath, frame.key);
398
356
  const appendPaths = frame.append ?? [];
399
357
  const merged = existing
400
358
  ? deepMergeWithAppend(existing, frame.data, appendPaths)
401
359
  : frame.data;
402
- viewData.set(frame.key, merged);
403
- this.enforceMaxEntries(viewData);
404
- this.notifyUpdate(viewPath, frame.key, {
360
+ this.storage.set(viewPath, frame.key, merged);
361
+ this.enforceMaxEntries(viewPath);
362
+ this.storage.notifyUpdate(viewPath, frame.key, {
405
363
  type: 'patch',
406
364
  key: frame.key,
407
365
  data: frame.data,
408
366
  });
409
- this.notifyRichUpdate(viewPath, frame.key, previousValue, merged, 'patch', frame.data);
367
+ this.emitRichUpdate(viewPath, frame.key, previousValue, merged, 'patch', frame.data);
410
368
  break;
411
369
  }
412
370
  case 'delete':
413
- viewData.delete(frame.key);
414
- this.notifyUpdate(viewPath, frame.key, {
371
+ this.storage.delete(viewPath, frame.key);
372
+ this.storage.notifyUpdate(viewPath, frame.key, {
415
373
  type: 'delete',
416
374
  key: frame.key,
417
375
  });
418
- if (previousValue !== undefined) {
419
- this.notifyRichDelete(viewPath, frame.key, previousValue);
376
+ if (previousValue !== null) {
377
+ const richUpdate = { type: 'deleted', key: frame.key, lastKnown: previousValue };
378
+ this.storage.notifyRichUpdate(viewPath, frame.key, richUpdate);
420
379
  }
421
380
  break;
422
381
  }
423
382
  }
424
- getAll(viewPath) {
425
- const viewData = this.views.get(viewPath);
426
- if (!viewData)
427
- return [];
428
- return Array.from(viewData.values());
383
+ emitRichUpdate(viewPath, key, before, after, _op, patch) {
384
+ const richUpdate = before === null
385
+ ? { type: 'created', key, data: after }
386
+ : { type: 'updated', key, before, after, patch };
387
+ this.storage.notifyRichUpdate(viewPath, key, richUpdate);
388
+ }
389
+ enforceMaxEntries(viewPath) {
390
+ if (this.maxEntriesPerView === null)
391
+ return;
392
+ if (!this.storage.evictOldest)
393
+ return;
394
+ while (this.storage.size(viewPath) > this.maxEntriesPerView) {
395
+ this.storage.evictOldest(viewPath);
396
+ }
397
+ }
398
+ }
399
+
400
+ class ViewData {
401
+ constructor() {
402
+ this.entities = new Map();
403
+ this.accessOrder = [];
404
+ }
405
+ get(key) {
406
+ return this.entities.get(key);
407
+ }
408
+ set(key, value) {
409
+ if (!this.entities.has(key)) {
410
+ this.accessOrder.push(key);
411
+ }
412
+ else {
413
+ this.touch(key);
414
+ }
415
+ this.entities.set(key, value);
416
+ }
417
+ delete(key) {
418
+ const idx = this.accessOrder.indexOf(key);
419
+ if (idx !== -1) {
420
+ this.accessOrder.splice(idx, 1);
421
+ }
422
+ return this.entities.delete(key);
423
+ }
424
+ has(key) {
425
+ return this.entities.has(key);
426
+ }
427
+ values() {
428
+ return this.entities.values();
429
+ }
430
+ keys() {
431
+ return this.entities.keys();
432
+ }
433
+ get size() {
434
+ return this.entities.size;
435
+ }
436
+ touch(key) {
437
+ const idx = this.accessOrder.indexOf(key);
438
+ if (idx !== -1) {
439
+ this.accessOrder.splice(idx, 1);
440
+ this.accessOrder.push(key);
441
+ }
442
+ }
443
+ evictOldest() {
444
+ const oldest = this.accessOrder.shift();
445
+ if (oldest !== undefined) {
446
+ this.entities.delete(oldest);
447
+ }
448
+ return oldest;
449
+ }
450
+ clear() {
451
+ this.entities.clear();
452
+ this.accessOrder = [];
453
+ }
454
+ }
455
+ class MemoryAdapter {
456
+ constructor(_config = {}) {
457
+ this.views = new Map();
458
+ this.updateCallbacks = new Set();
459
+ this.richUpdateCallbacks = new Set();
429
460
  }
430
461
  get(viewPath, key) {
431
- const viewData = this.views.get(viewPath);
432
- if (!viewData)
462
+ const view = this.views.get(viewPath);
463
+ if (!view)
433
464
  return null;
434
- const value = viewData.get(key);
465
+ const value = view.get(key);
435
466
  return value !== undefined ? value : null;
436
467
  }
468
+ getAll(viewPath) {
469
+ const view = this.views.get(viewPath);
470
+ if (!view)
471
+ return [];
472
+ return Array.from(view.values());
473
+ }
437
474
  getAllSync(viewPath) {
438
- const viewData = this.views.get(viewPath);
439
- if (!viewData)
475
+ const view = this.views.get(viewPath);
476
+ if (!view)
440
477
  return undefined;
441
- return Array.from(viewData.values());
478
+ return Array.from(view.values());
442
479
  }
443
480
  getSync(viewPath, key) {
444
- const viewData = this.views.get(viewPath);
445
- if (!viewData)
481
+ const view = this.views.get(viewPath);
482
+ if (!view)
446
483
  return undefined;
447
- const value = viewData.get(key);
484
+ const value = view.get(key);
448
485
  return value !== undefined ? value : null;
449
486
  }
487
+ has(viewPath, key) {
488
+ return this.views.get(viewPath)?.has(key) ?? false;
489
+ }
450
490
  keys(viewPath) {
451
- const viewData = this.views.get(viewPath);
452
- if (!viewData)
491
+ const view = this.views.get(viewPath);
492
+ if (!view)
453
493
  return [];
454
- return Array.from(viewData.keys());
494
+ return Array.from(view.keys());
455
495
  }
456
496
  size(viewPath) {
457
- const viewData = this.views.get(viewPath);
458
- return viewData?.size ?? 0;
497
+ return this.views.get(viewPath)?.size ?? 0;
459
498
  }
460
- clear() {
461
- this.views.clear();
499
+ set(viewPath, key, data) {
500
+ let view = this.views.get(viewPath);
501
+ if (!view) {
502
+ view = new ViewData();
503
+ this.views.set(viewPath, view);
504
+ }
505
+ view.set(key, data);
506
+ }
507
+ delete(viewPath, key) {
508
+ this.views.get(viewPath)?.delete(key);
462
509
  }
463
- clearView(viewPath) {
464
- this.views.delete(viewPath);
510
+ clear(viewPath) {
511
+ if (viewPath) {
512
+ this.views.get(viewPath)?.clear();
513
+ this.views.delete(viewPath);
514
+ }
515
+ else {
516
+ this.views.clear();
517
+ }
518
+ }
519
+ evictOldest(viewPath) {
520
+ return this.views.get(viewPath)?.evictOldest();
465
521
  }
466
522
  onUpdate(callback) {
467
523
  this.updateCallbacks.add(callback);
468
- return () => {
469
- this.updateCallbacks.delete(callback);
470
- };
524
+ return () => this.updateCallbacks.delete(callback);
471
525
  }
472
526
  onRichUpdate(callback) {
473
527
  this.richUpdateCallbacks.add(callback);
474
- return () => {
475
- this.richUpdateCallbacks.delete(callback);
476
- };
477
- }
478
- subscribe(viewPath, callback) {
479
- const handler = (path, _key, update) => {
480
- if (path === viewPath) {
481
- callback(update);
482
- }
483
- };
484
- this.updateCallbacks.add(handler);
485
- return () => {
486
- this.updateCallbacks.delete(handler);
487
- };
488
- }
489
- subscribeToKey(viewPath, key, callback) {
490
- const handler = (path, updateKey, update) => {
491
- if (path === viewPath && updateKey === key) {
492
- callback(update);
493
- }
494
- };
495
- this.updateCallbacks.add(handler);
496
- return () => {
497
- this.updateCallbacks.delete(handler);
498
- };
528
+ return () => this.richUpdateCallbacks.delete(callback);
499
529
  }
500
530
  notifyUpdate(viewPath, key, update) {
501
531
  for (const callback of this.updateCallbacks) {
502
532
  callback(viewPath, key, update);
503
533
  }
504
534
  }
505
- notifyRichUpdate(viewPath, key, before, after, _op, patch) {
506
- const richUpdate = before === undefined
507
- ? { type: 'created', key, data: after }
508
- : { type: 'updated', key, before, after, patch };
509
- for (const callback of this.richUpdateCallbacks) {
510
- callback(viewPath, key, richUpdate);
511
- }
512
- }
513
- notifyRichDelete(viewPath, key, lastKnown) {
514
- const richUpdate = { type: 'deleted', key, lastKnown };
535
+ notifyRichUpdate(viewPath, key, update) {
515
536
  for (const callback of this.richUpdateCallbacks) {
516
- callback(viewPath, key, richUpdate);
537
+ callback(viewPath, key, update);
517
538
  }
518
539
  }
519
540
  }
@@ -569,12 +590,12 @@ class SubscriptionRegistry {
569
590
  }
570
591
 
571
592
  const MAX_QUEUE_SIZE = 1000;
572
- function createUpdateStream(store, subscriptionRegistry, subscription, keyFilter) {
593
+ function createUpdateStream(storage, subscriptionRegistry, subscription, keyFilter) {
573
594
  return {
574
595
  [Symbol.asyncIterator]() {
575
596
  const queue = [];
576
597
  let waitingResolve = null;
577
- let unsubscribeStore = null;
598
+ let unsubscribeStorage = null;
578
599
  let unsubscribeRegistry = null;
579
600
  let done = false;
580
601
  const handler = (viewPath, key, update) => {
@@ -599,12 +620,12 @@ function createUpdateStream(store, subscriptionRegistry, subscription, keyFilter
599
620
  }
600
621
  };
601
622
  const start = () => {
602
- unsubscribeStore = store.onUpdate(handler);
623
+ unsubscribeStorage = storage.onUpdate(handler);
603
624
  unsubscribeRegistry = subscriptionRegistry.subscribe(subscription);
604
625
  };
605
626
  const cleanup = () => {
606
627
  done = true;
607
- unsubscribeStore?.();
628
+ unsubscribeStorage?.();
608
629
  unsubscribeRegistry?.();
609
630
  };
610
631
  start();
@@ -633,12 +654,12 @@ function createUpdateStream(store, subscriptionRegistry, subscription, keyFilter
633
654
  },
634
655
  };
635
656
  }
636
- function createRichUpdateStream(store, subscriptionRegistry, subscription, keyFilter) {
657
+ function createRichUpdateStream(storage, subscriptionRegistry, subscription, keyFilter) {
637
658
  return {
638
659
  [Symbol.asyncIterator]() {
639
660
  const queue = [];
640
661
  let waitingResolve = null;
641
- let unsubscribeStore = null;
662
+ let unsubscribeStorage = null;
642
663
  let unsubscribeRegistry = null;
643
664
  let done = false;
644
665
  const handler = (viewPath, key, update) => {
@@ -663,12 +684,12 @@ function createRichUpdateStream(store, subscriptionRegistry, subscription, keyFi
663
684
  }
664
685
  };
665
686
  const start = () => {
666
- unsubscribeStore = store.onRichUpdate(handler);
687
+ unsubscribeStorage = storage.onRichUpdate(handler);
667
688
  unsubscribeRegistry = subscriptionRegistry.subscribe(subscription);
668
689
  };
669
690
  const cleanup = () => {
670
691
  done = true;
671
- unsubscribeStore?.();
692
+ unsubscribeStorage?.();
672
693
  unsubscribeRegistry?.();
673
694
  };
674
695
  start();
@@ -698,48 +719,48 @@ function createRichUpdateStream(store, subscriptionRegistry, subscription, keyFi
698
719
  };
699
720
  }
700
721
 
701
- function createTypedStateView(viewDef, store, subscriptionRegistry) {
722
+ function createTypedStateView(viewDef, storage, subscriptionRegistry) {
702
723
  return {
703
724
  watch(key) {
704
- return createUpdateStream(store, subscriptionRegistry, { view: viewDef.view, key }, key);
725
+ return createUpdateStream(storage, subscriptionRegistry, { view: viewDef.view, key }, key);
705
726
  },
706
727
  watchRich(key) {
707
- return createRichUpdateStream(store, subscriptionRegistry, { view: viewDef.view, key }, key);
728
+ return createRichUpdateStream(storage, subscriptionRegistry, { view: viewDef.view, key }, key);
708
729
  },
709
730
  async get(key) {
710
- return store.get(viewDef.view, key);
731
+ return storage.get(viewDef.view, key);
711
732
  },
712
733
  getSync(key) {
713
- return store.getSync(viewDef.view, key);
734
+ return storage.getSync(viewDef.view, key);
714
735
  },
715
736
  };
716
737
  }
717
- function createTypedListView(viewDef, store, subscriptionRegistry) {
738
+ function createTypedListView(viewDef, storage, subscriptionRegistry) {
718
739
  return {
719
740
  watch() {
720
- return createUpdateStream(store, subscriptionRegistry, { view: viewDef.view });
741
+ return createUpdateStream(storage, subscriptionRegistry, { view: viewDef.view });
721
742
  },
722
743
  watchRich() {
723
- return createRichUpdateStream(store, subscriptionRegistry, { view: viewDef.view });
744
+ return createRichUpdateStream(storage, subscriptionRegistry, { view: viewDef.view });
724
745
  },
725
746
  async get() {
726
- return store.getAll(viewDef.view);
747
+ return storage.getAll(viewDef.view);
727
748
  },
728
749
  getSync() {
729
- return store.getAllSync(viewDef.view);
750
+ return storage.getAllSync(viewDef.view);
730
751
  },
731
752
  };
732
753
  }
733
- function createTypedViews(stack, store, subscriptionRegistry) {
754
+ function createTypedViews(stack, storage, subscriptionRegistry) {
734
755
  const views = {};
735
756
  for (const [viewName, viewGroup] of Object.entries(stack.views)) {
736
757
  const group = viewGroup;
737
758
  const typedGroup = {};
738
759
  if (group.state) {
739
- typedGroup.state = createTypedStateView(group.state, store, subscriptionRegistry);
760
+ typedGroup.state = createTypedStateView(group.state, storage, subscriptionRegistry);
740
761
  }
741
762
  if (group.list) {
742
- typedGroup.list = createTypedListView(group.list, store, subscriptionRegistry);
763
+ typedGroup.list = createTypedListView(group.list, storage, subscriptionRegistry);
743
764
  }
744
765
  views[viewName] = typedGroup;
745
766
  }
@@ -749,7 +770,10 @@ function createTypedViews(stack, store, subscriptionRegistry) {
749
770
  class HyperStack {
750
771
  constructor(url, options) {
751
772
  this.stack = options.stack;
752
- this.store = new EntityStore();
773
+ this.storage = options.storage ?? new MemoryAdapter();
774
+ this.processor = new FrameProcessor(this.storage, {
775
+ maxEntriesPerView: options.maxEntriesPerView,
776
+ });
753
777
  this.connection = new ConnectionManager({
754
778
  websocketUrl: url,
755
779
  reconnectIntervals: options.reconnectIntervals,
@@ -757,9 +781,9 @@ class HyperStack {
757
781
  });
758
782
  this.subscriptionRegistry = new SubscriptionRegistry(this.connection);
759
783
  this.connection.onFrame((frame) => {
760
- this.store.handleFrame(frame);
784
+ this.processor.handleFrame(frame);
761
785
  });
762
- this._views = createTypedViews(this.stack, this.store, this.subscriptionRegistry);
786
+ this._views = createTypedViews(this.stack, this.storage, this.subscriptionRegistry);
763
787
  }
764
788
  static async connect(url, options) {
765
789
  if (!url) {
@@ -783,6 +807,9 @@ class HyperStack {
783
807
  get stackName() {
784
808
  return this.stack.name;
785
809
  }
810
+ get store() {
811
+ return this.storage;
812
+ }
786
813
  onConnectionStateChange(callback) {
787
814
  return this.connection.onStateChange(callback);
788
815
  }
@@ -800,10 +827,10 @@ class HyperStack {
800
827
  return this.connection.isConnected();
801
828
  }
802
829
  clearStore() {
803
- this.store.clear();
830
+ this.storage.clear();
804
831
  }
805
832
  getStore() {
806
- return this.store;
833
+ return this.storage;
807
834
  }
808
835
  getConnection() {
809
836
  return this.connection;
@@ -813,5 +840,5 @@ class HyperStack {
813
840
  }
814
841
  }
815
842
 
816
- export { ConnectionManager, DEFAULT_CONFIG, EntityStore, HyperStack, HyperStackError, SubscriptionRegistry, createRichUpdateStream, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, isSnapshotFrame, isValidFrame, parseFrame, parseFrameFromBlob };
843
+ export { ConnectionManager, DEFAULT_CONFIG, DEFAULT_MAX_ENTRIES_PER_VIEW, FrameProcessor, HyperStack, HyperStackError, MemoryAdapter, SubscriptionRegistry, createRichUpdateStream, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, isSnapshotFrame, isValidFrame, parseFrame, parseFrameFromBlob };
817
844
  //# sourceMappingURL=index.esm.js.map