@electric-sql/client 1.5.9 → 1.5.10
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/cjs/index.cjs +31 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +4 -4
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.legacy-esm.js +31 -3
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +31 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/shape-stream-state.ts +72 -35
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-sql/client",
|
|
3
3
|
"description": "Postgres everywhere - your data, in sync, wherever you need it.",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.10",
|
|
5
5
|
"author": "ElectricSQL team and contributors.",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/electric-sql/electric/issues"
|
|
@@ -75,7 +75,7 @@ export type ResponseMetadataTransition =
|
|
|
75
75
|
| { action: `ignored`; state: ShapeStreamState }
|
|
76
76
|
| {
|
|
77
77
|
action: `stale-retry`
|
|
78
|
-
state:
|
|
78
|
+
state: ShapeStreamState
|
|
79
79
|
exceededMaxRetries: boolean
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -122,7 +122,7 @@ export interface UrlParamsContext {
|
|
|
122
122
|
* Each concrete state carries only its relevant fields — there is no shared
|
|
123
123
|
* flat context bag. Transitions create new immutable state objects.
|
|
124
124
|
*
|
|
125
|
-
* `isUpToDate`
|
|
125
|
+
* `isUpToDate` returns true for LiveState and delegating states wrapping LiveState.
|
|
126
126
|
*/
|
|
127
127
|
export abstract class ShapeStreamState {
|
|
128
128
|
abstract readonly kind: ShapeStreamStateKind
|
|
@@ -368,9 +368,10 @@ abstract class ActiveState extends ShapeStreamState {
|
|
|
368
368
|
|
|
369
369
|
/**
|
|
370
370
|
* Captures shared behavior of InitialState, SyncingState, StaleRetryState:
|
|
371
|
-
* - handleResponseMetadata: stale check → parse fields → new SyncingState
|
|
372
|
-
* -
|
|
373
|
-
* -
|
|
371
|
+
* - handleResponseMetadata: stale check → parse fields → new SyncingState (or LiveState for 204)
|
|
372
|
+
* - enterReplayMode(cursor) → new ReplayingState
|
|
373
|
+
* - canEnterReplayMode(): boolean — returns true (StaleRetryState overrides to return false,
|
|
374
|
+
* because entering replay would lose the stale-retry count; see C1 in SPEC.md)
|
|
374
375
|
*/
|
|
375
376
|
abstract class FetchingState extends ActiveState {
|
|
376
377
|
handleResponseMetadata(
|
|
@@ -659,48 +660,60 @@ export class ReplayingState extends ActiveState {
|
|
|
659
660
|
// Delegating states (Paused / Error)
|
|
660
661
|
// ---------------------------------------------------------------------------
|
|
661
662
|
|
|
663
|
+
// Union of all non-delegating states — used to type previousState fields so
|
|
664
|
+
// that PausedState.previousState is never another PausedState, and
|
|
665
|
+
// ErrorState.previousState is never another ErrorState.
|
|
666
|
+
export type ShapeStreamActiveState =
|
|
667
|
+
| InitialState
|
|
668
|
+
| SyncingState
|
|
669
|
+
| LiveState
|
|
670
|
+
| ReplayingState
|
|
671
|
+
| StaleRetryState
|
|
672
|
+
|
|
662
673
|
export class PausedState extends ShapeStreamState {
|
|
663
674
|
readonly kind = `paused` as const
|
|
664
|
-
readonly previousState:
|
|
675
|
+
readonly previousState: ShapeStreamActiveState | ErrorState
|
|
665
676
|
|
|
666
677
|
constructor(previousState: ShapeStreamState) {
|
|
667
678
|
super()
|
|
668
|
-
this.previousState =
|
|
679
|
+
this.previousState = (
|
|
680
|
+
previousState instanceof PausedState
|
|
681
|
+
? previousState.previousState
|
|
682
|
+
: previousState
|
|
683
|
+
) as ShapeStreamActiveState | ErrorState
|
|
669
684
|
}
|
|
670
685
|
|
|
671
|
-
get handle() {
|
|
686
|
+
get handle(): string | undefined {
|
|
672
687
|
return this.previousState.handle
|
|
673
688
|
}
|
|
674
|
-
get offset() {
|
|
689
|
+
get offset(): Offset {
|
|
675
690
|
return this.previousState.offset
|
|
676
691
|
}
|
|
677
|
-
get schema() {
|
|
692
|
+
get schema(): Schema | undefined {
|
|
678
693
|
return this.previousState.schema
|
|
679
694
|
}
|
|
680
|
-
get liveCacheBuster() {
|
|
695
|
+
get liveCacheBuster(): string {
|
|
681
696
|
return this.previousState.liveCacheBuster
|
|
682
697
|
}
|
|
683
|
-
get lastSyncedAt() {
|
|
698
|
+
get lastSyncedAt(): number | undefined {
|
|
684
699
|
return this.previousState.lastSyncedAt
|
|
685
700
|
}
|
|
686
|
-
|
|
687
701
|
get isUpToDate(): boolean {
|
|
688
702
|
return this.previousState.isUpToDate
|
|
689
703
|
}
|
|
690
|
-
|
|
691
|
-
get staleCacheBuster() {
|
|
704
|
+
get staleCacheBuster(): string | undefined {
|
|
692
705
|
return this.previousState.staleCacheBuster
|
|
693
706
|
}
|
|
694
|
-
get staleCacheRetryCount() {
|
|
707
|
+
get staleCacheRetryCount(): number {
|
|
695
708
|
return this.previousState.staleCacheRetryCount
|
|
696
709
|
}
|
|
697
|
-
get sseFallbackToLongPolling() {
|
|
710
|
+
get sseFallbackToLongPolling(): boolean {
|
|
698
711
|
return this.previousState.sseFallbackToLongPolling
|
|
699
712
|
}
|
|
700
|
-
get consecutiveShortSseConnections() {
|
|
713
|
+
get consecutiveShortSseConnections(): number {
|
|
701
714
|
return this.previousState.consecutiveShortSseConnections
|
|
702
715
|
}
|
|
703
|
-
get replayCursor() {
|
|
716
|
+
get replayCursor(): string | undefined {
|
|
704
717
|
return this.previousState.replayCursor
|
|
705
718
|
}
|
|
706
719
|
|
|
@@ -711,7 +724,20 @@ export class PausedState extends ShapeStreamState {
|
|
|
711
724
|
if (transition.action === `accepted`) {
|
|
712
725
|
return { action: `accepted`, state: new PausedState(transition.state) }
|
|
713
726
|
}
|
|
714
|
-
|
|
727
|
+
if (transition.action === `ignored`) {
|
|
728
|
+
return { action: `ignored`, state: this }
|
|
729
|
+
}
|
|
730
|
+
if (transition.action === `stale-retry`) {
|
|
731
|
+
return {
|
|
732
|
+
action: `stale-retry`,
|
|
733
|
+
state: new PausedState(transition.state),
|
|
734
|
+
exceededMaxRetries: transition.exceededMaxRetries,
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
const _exhaustive: never = transition
|
|
738
|
+
throw new Error(
|
|
739
|
+
`PausedState.handleResponseMetadata: unhandled transition action "${(_exhaustive as ResponseMetadataTransition).action}"`
|
|
740
|
+
)
|
|
715
741
|
}
|
|
716
742
|
|
|
717
743
|
withHandle(handle: string): PausedState {
|
|
@@ -733,34 +759,52 @@ export class PausedState extends ShapeStreamState {
|
|
|
733
759
|
|
|
734
760
|
export class ErrorState extends ShapeStreamState {
|
|
735
761
|
readonly kind = `error` as const
|
|
736
|
-
readonly previousState:
|
|
762
|
+
readonly previousState: ShapeStreamActiveState | PausedState
|
|
737
763
|
readonly error: Error
|
|
738
764
|
|
|
739
765
|
constructor(previousState: ShapeStreamState, error: Error) {
|
|
740
766
|
super()
|
|
741
|
-
this.previousState =
|
|
767
|
+
this.previousState = (
|
|
768
|
+
previousState instanceof ErrorState
|
|
769
|
+
? previousState.previousState
|
|
770
|
+
: previousState
|
|
771
|
+
) as ShapeStreamActiveState | PausedState
|
|
742
772
|
this.error = error
|
|
743
773
|
}
|
|
744
774
|
|
|
745
|
-
get handle() {
|
|
775
|
+
get handle(): string | undefined {
|
|
746
776
|
return this.previousState.handle
|
|
747
777
|
}
|
|
748
|
-
get offset() {
|
|
778
|
+
get offset(): Offset {
|
|
749
779
|
return this.previousState.offset
|
|
750
780
|
}
|
|
751
|
-
get schema() {
|
|
781
|
+
get schema(): Schema | undefined {
|
|
752
782
|
return this.previousState.schema
|
|
753
783
|
}
|
|
754
|
-
get liveCacheBuster() {
|
|
784
|
+
get liveCacheBuster(): string {
|
|
755
785
|
return this.previousState.liveCacheBuster
|
|
756
786
|
}
|
|
757
|
-
get lastSyncedAt() {
|
|
787
|
+
get lastSyncedAt(): number | undefined {
|
|
758
788
|
return this.previousState.lastSyncedAt
|
|
759
789
|
}
|
|
760
|
-
|
|
761
790
|
get isUpToDate(): boolean {
|
|
762
791
|
return this.previousState.isUpToDate
|
|
763
792
|
}
|
|
793
|
+
get staleCacheBuster(): string | undefined {
|
|
794
|
+
return this.previousState.staleCacheBuster
|
|
795
|
+
}
|
|
796
|
+
get staleCacheRetryCount(): number {
|
|
797
|
+
return this.previousState.staleCacheRetryCount
|
|
798
|
+
}
|
|
799
|
+
get sseFallbackToLongPolling(): boolean {
|
|
800
|
+
return this.previousState.sseFallbackToLongPolling
|
|
801
|
+
}
|
|
802
|
+
get consecutiveShortSseConnections(): number {
|
|
803
|
+
return this.previousState.consecutiveShortSseConnections
|
|
804
|
+
}
|
|
805
|
+
get replayCursor(): string | undefined {
|
|
806
|
+
return this.previousState.replayCursor
|
|
807
|
+
}
|
|
764
808
|
|
|
765
809
|
withHandle(handle: string): ErrorState {
|
|
766
810
|
return new ErrorState(this.previousState.withHandle(handle), this.error)
|
|
@@ -783,13 +827,6 @@ export class ErrorState extends ShapeStreamState {
|
|
|
783
827
|
// Type alias & factory
|
|
784
828
|
// ---------------------------------------------------------------------------
|
|
785
829
|
|
|
786
|
-
export type ShapeStreamActiveState =
|
|
787
|
-
| InitialState
|
|
788
|
-
| SyncingState
|
|
789
|
-
| LiveState
|
|
790
|
-
| ReplayingState
|
|
791
|
-
| StaleRetryState
|
|
792
|
-
|
|
793
830
|
export function createInitialState(opts: {
|
|
794
831
|
offset: Offset
|
|
795
832
|
handle?: string
|