diff --git a/packages/endpoint/src/schema.d.ts b/packages/endpoint/src/schema.d.ts index 31c0c19431bc..d6827bae2c1c 100644 --- a/packages/endpoint/src/schema.d.ts +++ b/packages/endpoint/src/schema.d.ts @@ -5,6 +5,7 @@ import type { SchemaClass, IQueryDelegate, INormalizeDelegate, + SchemaSimple, } from './interface.js'; import type { AbstractInstanceType, @@ -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, @@ -34,7 +34,7 @@ import type { UnionResult, } from './schemaTypes.js'; -export { EntityMap, Invalidate, Query, EntityMixin, Entity }; +export { EntityMap, Query, EntityMixin, Entity }; export type { SchemaClass }; @@ -42,6 +42,48 @@ 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; + + _denormalizeNullable(): AbstractInstanceType | undefined; + _normalizeNullable(): string | undefined; +} + /** * Represents arrays * @see https://dataclient.io/rest/api/Array diff --git a/packages/endpoint/src/schemas/Invalidate.ts b/packages/endpoint/src/schemas/Invalidate.ts index ddc5d782456b..3e1cd27229c0 100644 --- a/packages/endpoint/src/schemas/Invalidate.ts +++ b/packages/endpoint/src/schemas/Invalidate.ts @@ -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'; /** @@ -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 (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 { - 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 | 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 { +// return unvisit(this._entity, id) as any; +// } + +// /* istanbul ignore next */ +// _denormalizeNullable(): AbstractInstanceType | undefined { +// return {} as any; +// } + +// /* istanbul ignore next */ +// _normalizeNullable(): string | undefined { +// return {} as any; +// } +// }