Skip to content

Commit

Permalink
fix: crud types not working well if initial is {}
Browse files Browse the repository at this point in the history
  • Loading branch information
jmeistrich committed Dec 8, 2024
1 parent ed8ae04 commit 2d26071
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
24 changes: 19 additions & 5 deletions src/sync-plugins/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,23 @@ export type CrudAsOption = 'Map' | 'object' | 'value' | 'array';

export type CrudResult<T> = T;

export interface SyncedCrudPropsNoRead<TLocal, TAsOption extends CrudAsOption> {
get?: never | undefined;
list?: never | undefined;
initial?: InitialValue<TLocal, TAsOption>;
as?: TAsOption;
}
export interface SyncedCrudPropsSingle<TRemote extends object, TLocal> {
get?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
get: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
list?: never | undefined;
initial?: InitialValue<TLocal, 'value'>;
initial?: InitialValue<Partial<NoInfer<TLocal>>, 'value'>;
as?: never | 'value';
}
export interface SyncedCrudPropsMany<TRemote extends object, TLocal, TAsOption extends CrudAsOption> {
list?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
list: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
get?: never | undefined;
as?: TAsOption;
initial?: InitialValue<TLocal, TAsOption>;
initial?: InitialValue<Partial<NoInfer<TLocal>>, TAsOption>;
}
export interface SyncedCrudOnSavedParams<TRemote extends object, TLocal> {
saved: TLocal;
Expand Down Expand Up @@ -178,6 +184,10 @@ function retrySet(
);
}

// The no read version
export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(
props: SyncedCrudPropsNoRead<TRemote, TAsOption> & SyncedCrudPropsBase<TRemote, TLocal>,
): SyncedCrudReturnType<TLocal, TAsOption>;
// The get version
export function syncedCrud<TRemote extends object, TLocal = TRemote>(
props: SyncedCrudPropsSingle<TRemote, TLocal> & SyncedCrudPropsBase<TRemote, TLocal>,
Expand All @@ -191,7 +201,11 @@ export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption e
SyncedCrudPropsBase<TRemote, TLocal>,
): SyncedCrudReturnType<TLocal, TAsOption>;
export function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(
props: (SyncedCrudPropsSingle<TRemote, TLocal> | SyncedCrudPropsMany<TRemote, TLocal, TAsOption>) &
props: (
| SyncedCrudPropsSingle<TRemote, TLocal>
| SyncedCrudPropsMany<TRemote, TLocal, TAsOption>
| SyncedCrudPropsNoRead<TRemote, TAsOption>
) &
SyncedCrudPropsBase<TRemote, TLocal>,
): SyncedCrudReturnType<TLocal, TAsOption> {
const {
Expand Down
45 changes: 41 additions & 4 deletions tests/crud.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,44 @@ describe('Crud record transform', () => {
});
});
});
describe('initial', () => {
const obsGet = observable(
syncedCrud({
get: () => ItemBasicValue(),
// initial: {},
}),
);
const valueGet = obsGet.get();
expectTypeOf<typeof valueGet>().toEqualTypeOf<BasicValue>();

const obsInitial = observable(
syncedCrud({
get: () => ItemBasicValue(),
initial: {},
}),
);
const valueInitial = obsInitial.get();
expectTypeOf<typeof valueInitial>().toEqualTypeOf<BasicValue>();

const obsInitialList = observable(
syncedCrud({
list: () => [ItemBasicValue()],
initial: [],
as: 'array',
}),
);
const valueInitialList = obsInitialList.get();
expectTypeOf<typeof valueInitialList>().toEqualTypeOf<BasicValue[]>();

const obsInitial2 = observable(
syncedCrud({
get: () => ItemBasicValue(),
initial: undefined,
}),
);
const valueInitial2 = obsInitial2.get();
expectTypeOf<typeof valueInitial2>().toEqualTypeOf<BasicValue>();
});
describe('fieldUpdatedAt', () => {
test('fieldUpdatedAt creates if no updatedAt', async () => {
let created = undefined;
Expand Down Expand Up @@ -2454,16 +2492,15 @@ describe('onSaved', () => {
let updated = undefined;
const canSave$ = observable(false);
const isSaving$ = observable(false);
type ExtendedValue = BasicValue & { changing: string };
const obs = observable(
syncedCrud({
initial: {
id1: { ...ItemBasicValue(), updatedAt: 10, changing: '0' } as BasicValue & {
changing: string;
},
id1: { ...ItemBasicValue(), updatedAt: 10, changing: '0' } as ExtendedValue,
},
as: 'object',
fieldUpdatedAt: 'updatedAt',
create: async (input: BasicValue) => {
create: async (input: ExtendedValue) => {
created = clone(input);
return input;
},
Expand Down

0 comments on commit 2d26071

Please sign in to comment.