Skip to content

Commit

Permalink
revamp onError to be more consistent, have more useful parameters in …
Browse files Browse the repository at this point in the history
…it, to be used from the crud function directly rather than the outer prop
  • Loading branch information
jmeistrich committed Nov 1, 2024
1 parent ad2dc3d commit c3865c8
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 81 deletions.
38 changes: 25 additions & 13 deletions src/sync-plugins/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
symbolDelete,
} from '@legendapp/state';
import {
SyncedErrorParams,
SyncedGetParams,
SyncedOptions,
SyncedSetParams,
Expand Down Expand Up @@ -54,8 +55,14 @@ export interface WaitForSetCrudFnParams<T> extends WaitForSetFnParams<T> {
type: 'create' | 'update' | 'delete';
}

export interface CrudErrorParams extends Omit<SyncedErrorParams, 'source'> {
source: 'list' | 'get' | 'create' | 'update' | 'delete';
}

export type CrudOnErrorFn = (error: Error, params: CrudErrorParams) => void;

export interface SyncedCrudPropsBase<TRemote extends object, TLocal = TRemote>
extends Omit<SyncedOptions<TRemote, TLocal>, 'get' | 'set' | 'initial' | 'subscribe' | 'waitForSet'> {
extends Omit<SyncedOptions<TRemote, TLocal>, 'get' | 'set' | 'initial' | 'subscribe' | 'waitForSet' | 'onError'> {
create?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<CrudResult<TRemote> | null | undefined | void>;
update?(
input: Partial<TRemote>,
Expand All @@ -77,6 +84,7 @@ export interface SyncedCrudPropsBase<TRemote extends object, TLocal = TRemote>
| Promise<any>
| ObservableParam<any>
| ObservableEvent;
onError?: (error: Error, params: CrudErrorParams) => void;
}

type InitialValue<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map'
Expand Down Expand Up @@ -200,16 +208,18 @@ export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption e
};

const transformRows = (data: TRemote[]) => {
return Promise.all(
data.map((value: any) =>
// Skip transforming any children with symbolDelete or fieldDeleted because they'll get deleted by resultsToOutType
value[symbolDelete] ||
(fieldDeleted && value[fieldDeleted]) ||
(fieldDeletedList && value[fieldDeletedList])
? value
: transform!.load!(value, 'get'),
),
);
return data.length
? Promise.all(
data.map((value: any) =>
// Skip transforming any children with symbolDelete or fieldDeleted because they'll get deleted by resultsToOutType
value[symbolDelete] ||
(fieldDeleted && value[fieldDeleted]) ||
(fieldDeletedList && value[fieldDeletedList])
? value
: transform!.load!(value, 'get'),
),
)
: [];
};

const get: undefined | ((params: SyncedGetParams<TRemote>) => TLocal | Promise<TLocal>) =
Expand All @@ -231,7 +241,9 @@ export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption e
if (asType === 'value') {
return transformed.length > 0
? transformed[0]
: ((((isLastSyncMode && lastSync) || fieldDeleted) && value) ?? null);
: getFn
? ((((isLastSyncMode && lastSync) || fieldDeleted) && value) ?? null)
: undefined;
} else {
return resultsToOutType(transformed);
}
Expand Down Expand Up @@ -583,6 +595,6 @@ export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption e
get,
subscribe,
mode: modeParam,
...rest,
...(rest as any),
});
}
18 changes: 13 additions & 5 deletions src/sync-plugins/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
symbolDelete,
when,
} from '@legendapp/state';
import { FieldTransforms, SyncedGetParams, SyncedSubscribeParams } from '@legendapp/state/sync';
import { FieldTransforms, SyncedErrorParams, SyncedGetParams, SyncedSubscribeParams } from '@legendapp/state/sync';
import {
CrudAsOption,
SyncedCrudPropsBase,
Expand Down Expand Up @@ -45,11 +45,12 @@ import { invertFieldMap, transformObjectFields } from '../sync/transformObjectFi

export interface SyncedFirebaseProps<TRemote extends object, TLocal, TAs extends CrudAsOption = 'value'>
extends Omit<SyncedCrudPropsMany<TRemote, TLocal, TAs>, 'list' | 'retry'>,
SyncedCrudPropsBase<TRemote, TLocal> {
Omit<SyncedCrudPropsBase<TRemote, TLocal>, 'onError'> {
refPath: (uid: string | undefined) => string;
query?: (ref: DatabaseReference) => DatabaseReference | Query;
fieldId?: string;
fieldTransforms?: FieldTransforms<TRemote>;
onError?: (error: Error, params: FirebaseErrorParams) => void;
// Also in global config
realtime?: boolean;
requireAuth?: boolean;
Expand Down Expand Up @@ -111,6 +112,12 @@ interface FirebaseFns {
generateId: () => string;
}

export interface FirebaseErrorParams extends Omit<SyncedErrorParams, 'source'> {
source: 'list' | 'get' | 'create' | 'update' | 'delete';
}

type OnErrorFn = (error: Error, params: FirebaseErrorParams) => void;

const fns: FirebaseFns = {
isInitialized: () => {
try {
Expand Down Expand Up @@ -186,7 +193,8 @@ export function syncedFirebase<TRemote extends object, TLocal = TRemote, TAs ext
return ref;
};

const list = async ({ lastSync, onError }: SyncedGetParams<TRemote>): Promise<TRemote[]> => {
const list = async (getParams: SyncedGetParams<TRemote>): Promise<TRemote[]> => {
const { lastSync, onError } = getParams;
const ref = computeRef(lastSync!);

return new Promise((resolve) => {
Expand All @@ -209,7 +217,7 @@ export function syncedFirebase<TRemote extends object, TLocal = TRemote, TAs ext
didList = true;
resolve(values);
},
onError,
(error) => (onError as OnErrorFn)(error, { source: 'list', type: 'get', retry: getParams }),
);
});
};
Expand Down Expand Up @@ -389,7 +397,7 @@ export function syncedFirebase<TRemote extends object, TLocal = TRemote, TAs ext
}

return syncedCrud<TRemote, TLocal, TAs>({
...rest,
...(rest as any), // Workaround for type errors
list,
subscribe,
create,
Expand Down
30 changes: 13 additions & 17 deletions src/sync-plugins/keel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ export interface SyncedKeelPropsBase<TRemote extends { id: string }, TLocal = TR
onError?: (error: Error, params: KeelErrorParams) => void;
}

type OnErrorFn = (error: Error, params: KeelErrorParams) => void;

const modifiedClients = new WeakSet<Record<string, any>>();
const isAuthed$ = observable(false);
const isAuthing$ = observable(false);
Expand Down Expand Up @@ -275,7 +277,7 @@ async function getAllPages<TRemote>(
>,
params: KeelListParams,
listParams: SyncedGetParams<TRemote>,
onError: ((error: Error, params: KeelErrorParams) => void) | undefined,
onError: (error: Error, params: KeelErrorParams) => void,
): Promise<TRemote[]> {
const allData: TRemote[] = [];
let pageInfo: PageInfo | undefined = undefined;
Expand All @@ -302,15 +304,13 @@ async function getAllPages<TRemote>(

if (!handled) {
const err = new Error(error.message, { cause: { error } });
// TODO
onError?.(err, {
onError(err, {
getParams: listParams,
type: 'get',
source: 'list',
action: listFn.name || listFn.toString(),
retry: listParams,
});

throw err;
}
} else if (data) {
pageInfo = data.pageInfo as PageInfo;
Expand Down Expand Up @@ -356,7 +356,6 @@ export function syncedKeel<
fieldDeleted,
realtime,
mode,
onError,
requireAuth = true,
...rest
} = props;
Expand Down Expand Up @@ -385,7 +384,7 @@ export function syncedKeel<

const list = listParam
? async (listParams: SyncedGetParams<TRemote>) => {
const { lastSync } = listParams;
const { lastSync, onError } = listParams;
const queryBySync = !!lastSync && changesSince === 'last-sync';
// If querying with lastSync pass it to the "where" parameters
const where = Object.assign(
Expand All @@ -396,7 +395,7 @@ export function syncedKeel<

realtimeState.current = {};

const promise = getAllPages(props, listParam, params, listParams, onError);
const promise = getAllPages(props, listParam, params, listParams, onError as OnErrorFn);

if (realtime) {
setupSubscribe!(listParams);
Expand All @@ -408,7 +407,7 @@ export function syncedKeel<

const get = getParam
? async (getParams: SyncedGetParams<TRemote>) => {
const { refresh } = getParams;
const { refresh, onError } = getParams;

realtimeState.current = {};

Expand All @@ -425,15 +424,13 @@ export function syncedKeel<

if (!handled) {
const err = new Error(error.message, { cause: { error } });
// TODO
onError?.(err, {
(onError as OnErrorFn)(err, {
getParams,
type: 'get',
source: 'get',
action: getParam.name || getParam.toString(),
retry: getParams,
});

throw err;
}
} else {
return data as TRemote;
Expand All @@ -459,7 +456,7 @@ export function syncedKeel<
fn: Function,
from: 'create' | 'update' | 'delete',
) => {
const { update } = params;
const { update, onError } = params;

if (
from === 'create' &&
Expand All @@ -485,15 +482,14 @@ export function syncedKeel<

if (!handled) {
const err = new Error(error.message, { cause: { error } });
onError?.(err, {
(onError as OnErrorFn)(err, {
setParams: params,
input,
type: 'set',
source: from,
action: fn.name || fn.toString(),
retry: params,
});

throw err;
}
}
};
Expand Down
Loading

0 comments on commit c3865c8

Please sign in to comment.