Skip to content

enhance: Simplify Invalidate schema code #3453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions packages/endpoint/src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
SchemaClass,
IQueryDelegate,
INormalizeDelegate,
SchemaSimple,
} from './interface.js';
import type {
AbstractInstanceType,
Expand All @@ -24,7 +25,6 @@ import {
default as EntityMixin,
default as Entity,
} from './schemas/EntityMixin.js';
import { default as Invalidate } from './schemas/Invalidate.js';
import { default as Query } from './schemas/Query.js';
import type {
CollectionConstructor,
Expand All @@ -34,14 +34,56 @@ import type {
UnionResult,
} from './schemaTypes.js';

export { EntityMap, Invalidate, Query, EntityMixin, Entity };
export { EntityMap, Query, EntityMixin, Entity };

export type { SchemaClass };

export { EntityInterface } from './interface.js';

export * from './schemaTypes.js';

/**
* Marks entity as Invalid.
*
* This triggers suspense for all endpoints requiring it.
* Optional (like variable sized Array and Values) will simply remove the item.
* @see https://dataclient.io/rest/api/Invalidate
*/
export class Invalidate<
E extends EntityInterface & {
process: any;
},
> implements SchemaSimple
{
/**
* Marks entity as Invalid.
*
* This triggers suspense for all endpoints requiring it.
* Optional (like variable sized Array and Values) will simply remove the item.
* @see https://dataclient.io/rest/api/Invalidate
*/
constructor(entity: E);
key: string;
normalize(
input: any,
parent: any,
key: string | undefined,
args: any[],
visit: (...args: any) => any,
delegate: INormalizeDelegate,
): string;

queryKey(args: any, unvisit: unknown, delegate: unknown): undefined;
denormalize(
id: string,
args: readonly any[],
unvisit: (schema: any, input: any) => any,
): AbstractInstanceType<E>;

_denormalizeNullable(): AbstractInstanceType<E> | undefined;
_normalizeNullable(): string | undefined;
}

/**
* Represents arrays
* @see https://dataclient.io/rest/api/Array
Expand Down
213 changes: 134 additions & 79 deletions packages/endpoint/src/schemas/Invalidate.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type {
EntityInterface,
INormalizeDelegate,
SchemaSimple,
} from '../interface.js';
import type { AbstractInstanceType } from '../normal.js';
import type { EntityInterface, INormalizeDelegate } from '../interface.js';
import { AbstractInstanceType } from '../normal.js';
import { INVALID } from '../special.js';

/**
Expand All @@ -13,90 +9,149 @@ import { INVALID } from '../special.js';
* Optional (like variable sized Array and Values) will simply remove the item.
* @see https://dataclient.io/rest/api/Invalidate
*/
export default class Invalidate<
// export default interface Invalidate {
// new <E extends EntityInterface & { process: any }>(entity: E): E;
// }
// export default interface Invalidate<
// E extends EntityInterface & { process: any },
// > {
// new (...args: any[]): E;
// }
export default function Invalidate<
E extends EntityInterface & {
process: any;
},
> implements SchemaSimple
{
declare protected _entity: E;

/**
* Marks entity as Invalid.
*
* This triggers suspense for all endpoints requiring it.
* Optional (like variable sized Array and Values) will simply remove the item.
* @see https://dataclient.io/rest/api/Invalidate
*/
constructor(entity: E) {
if (process.env.NODE_ENV !== 'production' && !entity) {
throw new Error('Invalidate schema requires "entity" option.');
}
this._entity = entity;
>(entity: E): E {
if (process.env.NODE_ENV !== 'production' && !entity) {
throw new Error('Invalidate schema requires "entity" option.');
}
return Object.create(entity, {
normalize: {
value(
input: any,
parent: any,
key: string | undefined,
args: any[],
visit: (...args: any) => any,
delegate: INormalizeDelegate,
): string {
// TODO: what's store needs to be a differing type from fromJS
const processedEntity = entity.process(input, parent, key, args);
let pk = entity.pk(processedEntity, parent, key, args);

get key() {
return this._entity.key;
}
if (
process.env.NODE_ENV !== 'production' &&
(pk === undefined || pk === '' || pk === 'undefined')
) {
const error = new Error(
`Missing usable primary key when normalizing response.

This is likely due to a malformed response.
Try inspecting the network response or fetch() return value.
Or use debugging tools: https://dataclient.io/docs/getting-started/debugging
Learn more about schemas: https://dataclient.io/docs/api/schema

Invalidate(Entity): Invalidate(${this._entity.key})
Value (processed): ${input && JSON.stringify(input, null, 2)}
`,
);
(error as any).status = 400;
throw error;
}
pk = `${pk}`; // ensure pk is a string

normalize(
input: any,
parent: any,
key: string | undefined,
args: any[],
visit: (...args: any) => any,
delegate: INormalizeDelegate,
): string {
// TODO: what's store needs to be a differing type from fromJS
const processedEntity = this._entity.process(input, parent, key, args);
let pk = this._entity.pk(processedEntity, parent, key, args);
// any queued updates are meaningless with delete, so we should just set it
// and creates will have a different pk
delegate.setEntity(this as any, pk, INVALID);
return pk;
},
},
});
}
// export default class Invalidate<
// E extends EntityInterface & {
// process: any;
// },
// > implements SchemaSimple
// {
// declare protected _entity: E;

if (
process.env.NODE_ENV !== 'production' &&
(pk === undefined || pk === '' || pk === 'undefined')
) {
const error = new Error(
`Missing usable primary key when normalizing response.
// /**
// * Marks entity as Invalid.
// *
// * This triggers suspense for all endpoints requiring it.
// * Optional (like variable sized Array and Values) will simply remove the item.
// * @see https://dataclient.io/rest/api/Invalidate
// */
// constructor(entity: E) {
// if (process.env.NODE_ENV !== 'production' && !entity) {
// throw new Error('Invalidate schema requires "entity" option.');
// }
// this._entity = entity;
// }

This is likely due to a malformed response.
Try inspecting the network response or fetch() return value.
Or use debugging tools: https://dataclient.io/docs/getting-started/debugging
Learn more about schemas: https://dataclient.io/docs/api/schema
// get key() {
// return this._entity.key;
// }

Invalidate(Entity): Invalidate(${this._entity.key})
Value (processed): ${input && JSON.stringify(input, null, 2)}
`,
);
(error as any).status = 400;
throw error;
}
pk = `${pk}`; // ensure pk is a string
// normalize(
// input: any,
// parent: any,
// key: string | undefined,
// args: any[],
// visit: (...args: any) => any,
// delegate: INormalizeDelegate,
// ): string {
// // TODO: what's store needs to be a differing type from fromJS
// const processedEntity = this._entity.process(input, parent, key, args);
// let pk = this._entity.pk(processedEntity, parent, key, args);

// any queued updates are meaningless with delete, so we should just set it
// and creates will have a different pk
delegate.setEntity(this as any, pk, INVALID);
return pk;
}
// if (
// process.env.NODE_ENV !== 'production' &&
// (pk === undefined || pk === '' || pk === 'undefined')
// ) {
// const error = new Error(
// `Missing usable primary key when normalizing response.

queryKey(args: any, unvisit: unknown, delegate: unknown): undefined {
return undefined;
}
// This is likely due to a malformed response.
// Try inspecting the network response or fetch() return value.
// Or use debugging tools: https://dataclient.io/docs/getting-started/debugging
// Learn more about schemas: https://dataclient.io/docs/api/schema

denormalize(
id: string,
args: readonly any[],
unvisit: (schema: any, input: any) => any,
): AbstractInstanceType<E> {
return unvisit(this._entity, id) as any;
}
// Invalidate(Entity): Invalidate(${this._entity.key})
// Value (processed): ${input && JSON.stringify(input, null, 2)}
// `,
// );
// (error as any).status = 400;
// throw error;
// }
// pk = `${pk}`; // ensure pk is a string

/* istanbul ignore next */
_denormalizeNullable(): AbstractInstanceType<E> | undefined {
return {} as any;
}
// // any queued updates are meaningless with delete, so we should just set it
// // and creates will have a different pk
// delegate.setEntity(this as any, pk, INVALID);
// return pk;
// }

/* istanbul ignore next */
_normalizeNullable(): string | undefined {
return {} as any;
}
}
// queryKey(args: any, unvisit: unknown, delegate: unknown): undefined {
// return undefined;
// }

// denormalize(
// id: string,
// args: readonly any[],
// unvisit: (schema: any, input: any) => any,
// ): AbstractInstanceType<E> {
// return unvisit(this._entity, id) as any;
// }

// /* istanbul ignore next */
// _denormalizeNullable(): AbstractInstanceType<E> | undefined {
// return {} as any;
// }

// /* istanbul ignore next */
// _normalizeNullable(): string | undefined {
// return {} as any;
// }
// }