Skip to content

Commit

Permalink
Use existing Subscribable
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkpiano committed Feb 20, 2025
1 parent 2a16c31 commit c2263f8
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 24 deletions.
7 changes: 4 additions & 3 deletions packages/xstate-store/src/select.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { toObserver } from './toObserver';
import type {
Store,
StoreContext,
EventObject,
Selector,
Selection
} from './types';

export function select<
TContext extends StoreContext,
TEvent extends EventObject,
Expand All @@ -17,14 +17,15 @@ export function select<
equalityFn: (a: TSelected, b: TSelected) => boolean = Object.is
): Selection<TSelected> {
return {
subscribe: (callback: (selected: TSelected) => void) => {
subscribe: (observerOrFn) => {
const observer = toObserver(observerOrFn);
let previousSelected = selector(store.getSnapshot().context);

return store.subscribe((snapshot) => {
const nextSelected = selector(snapshot.context);
if (!equalityFn(previousSelected, nextSelected)) {
previousSelected = nextSelected;
callback(nextSelected);
observer.next?.(nextSelected);
}
});
},
Expand Down
18 changes: 1 addition & 17 deletions packages/xstate-store/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { toObserver } from './toObserver';
import {
EnqueueObject,
EventObject,
Expand All @@ -19,23 +20,6 @@ const symbolObservable: typeof Symbol.observable = (() =>
(typeof Symbol === 'function' && Symbol.observable) ||
'@@observable')() as any;

function toObserver<T>(
nextHandler?: Observer<T> | ((value: T) => void),
errorHandler?: (error: any) => void,
completionHandler?: () => void
): Observer<T> {
const isObserver = typeof nextHandler === 'object';
const self = isObserver ? nextHandler : undefined;

return {
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(
self
)
};
}

/**
* Updates a context object using a recipe function.
*
Expand Down
18 changes: 18 additions & 0 deletions packages/xstate-store/src/toObserver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Observer } from './types';

export function toObserver<T>(
nextHandler?: Observer<T> | ((value: T) => void),
errorHandler?: (error: any) => void,
completionHandler?: () => void
): Observer<T> {
const isObserver = typeof nextHandler === 'object';
const self = isObserver ? nextHandler : undefined;

return {
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(
self
)
};
}
5 changes: 1 addition & 4 deletions packages/xstate-store/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,6 @@ export type EventMap<TEvent extends EventObject> = {

export type Selector<TContext, TSelected> = (context: TContext) => TSelected;

export interface Selection<TSelected> {
subscribe: (callback: (selected: TSelected) => void) => {
unsubscribe: () => void;
};
export interface Selection<TSelected> extends Subscribable<TSelected> {
get: () => TSelected;
}

0 comments on commit c2263f8

Please sign in to comment.