Skip to content
Merged
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
26 changes: 26 additions & 0 deletions .changeset/major-boxes-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
'@data-client/normalizr': minor
'@data-client/endpoint': minor
'@data-client/rest': minor
'@data-client/graphql': minor
---

Add delegate.INVALID to queryKey

This is used in schema.All.queryKey().

#### Before

```ts
queryKey(args: any, unvisit: any, delegate: IQueryDelegate): any {
if (!found) return INVALID;
}
```

#### After

```ts
queryKey(args: any, unvisit: any, delegate: IQueryDelegate): any {
if (!found) return delegate.INVALID;
}
```
38 changes: 38 additions & 0 deletions .changeset/open-shrimps-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
'@data-client/normalizr': minor
'@data-client/endpoint': minor
'@data-client/rest': minor
'@data-client/graphql': minor
---

Add delegate.invalidate() to normalization

#### Before

```ts
normalize(
input: any,
parent: any,
key: string | undefined,
args: any[],
visit: (...args: any) => any,
delegate: INormalizeDelegate,
): string {
delegate.setEntity(this as any, pk, INVALID);
}
```

#### After

```ts
normalize(
input: any,
parent: any,
key: string | undefined,
args: any[],
visit: (...args: any) => any,
delegate: INormalizeDelegate,
): string {
delegate.invalidate(this as any, pk);
}
```
9 changes: 9 additions & 0 deletions .changeset/tough-areas-show.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@data-client/endpoint': minor
'@data-client/graphql': minor
'@data-client/rest': minor
---

Remove `INVALID` symbol export

Schemas can use delegate.invalidate() in normalize() or return delegate.INVALID in queryKey().
3 changes: 2 additions & 1 deletion packages/core/src/state/__tests__/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { INVALID, Entity } from '@data-client/endpoint';
import { Entity } from '@data-client/endpoint';
import { INVALID } from '@data-client/normalizr';
import { ArticleResource, Article, PaginatedArticle } from '__tests__/new';

import { Controller } from '../..';
Expand Down
1 change: 0 additions & 1 deletion packages/endpoint/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export type { Array, Invalidate, Collection, DefaultArgs } from './schema.js';
export { default as Entity } from './schemas/Entity.js';
export { default as EntityMixin } from './schemas/EntityMixin.js';
export { default as validateRequired } from './validateRequired.js';
export { INVALID } from './special.js';
export type {
EndpointInterface,
ReadEndpoint,
Expand Down
4 changes: 4 additions & 0 deletions packages/endpoint/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ export interface GetIndex {
export interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}

/** Helpers during schema.normalize() */
Expand All @@ -154,6 +156,8 @@ export interface INormalizeDelegate {
entity: any,
meta?: { fetchedAt: number; date: number; expiresAt: number },
): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: { key: string; indexes?: any }, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/endpoint/src/schemas/All.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ArraySchema from './Array.js';
import { IQueryDelegate, Visit } from '../interface.js';
import { EntityInterface, EntityMap, SchemaFunction } from '../schema.js';
import { INVALID } from '../special.js';

/**
* Retrieves all entities in cache
Expand Down Expand Up @@ -29,7 +28,7 @@ export default class AllSchema<
if (this.isSingleSchema) {
const entitiesEntry = delegate.getEntity(this.schema.key);
// we must wait until there are entries for any 'All' query to be Valid
if (entitiesEntry === undefined) return INVALID;
if (entitiesEntry === undefined) return delegate.INVALID;
return Object.values(entitiesEntry).map(
entity => entity && this.schema.pk(entity),
);
Expand All @@ -47,7 +46,7 @@ export default class AllSchema<
},
);
// we need at least one table entry of the Union for this to count as Valid.
if (!found) return INVALID;
if (!found) return delegate.INVALID;
return list;
}
}
5 changes: 1 addition & 4 deletions packages/endpoint/src/schemas/EntityMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import type {
Visit,
IQueryDelegate,
INormalizeDelegate,
Mergeable,
} from '../interface.js';
import { AbstractInstanceType } from '../normal.js';
import { INVALID } from '../special.js';
import type {
IEntityClass,
IEntityInstance,
Expand Down Expand Up @@ -256,8 +254,7 @@ export default function EntityMixin<TBase extends Constructor>(
id = `${this.pk(input, parent, key, args)}`;
// TODO: add undefined id check

// set directly: any queued updates are meaningless with delete
delegate.setEntity(this, id, INVALID);
delegate.invalidate(this, id);
return id;
}
id = this.pk(processedEntity, parent, key, args);
Expand Down
3 changes: 1 addition & 2 deletions packages/endpoint/src/schemas/Invalidate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type {
SchemaSimple,
} from '../interface.js';
import type { AbstractInstanceType } from '../normal.js';
import { INVALID } from '../special.js';

/**
* Marks entity as Invalid.
Expand Down Expand Up @@ -74,7 +73,7 @@ export default class Invalidate<

// 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);
delegate.invalidate(this as any, pk);
return pk;
}

Expand Down
8 changes: 6 additions & 2 deletions packages/endpoint/src/schemas/__tests__/All.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// eslint-env jest
import { initialState, State, Controller } from '@data-client/core';
import { normalize, MemoCache, denormalize } from '@data-client/normalizr';
import {
normalize,
MemoCache,
denormalize,
INVALID,
} from '@data-client/normalizr';
import { IDEntity } from '__tests__/new';

import { schema } from '../..';
import { fromJSState } from './denormalize';
import { INVALID } from '../../special';

let dateSpy: jest.SpyInstance<number, []>;
beforeAll(() => {
Expand Down
3 changes: 1 addition & 2 deletions packages/endpoint/src/schemas/__tests__/Invalidate.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// eslint-env jest
import { Schema, normalize } from '@data-client/normalizr';
import { INVALID, Schema, normalize } from '@data-client/normalizr';
import { IDEntity } from '__tests__/new';
import { fromJS } from 'immutable';

import { SimpleMemoCache, fromJSEntities } from './denormalize';
import { schema } from '../..';
import { INVALID } from '../../special';
import Entity from '../Entity';

let dateSpy: jest.SpyInstance;
Expand Down
4 changes: 1 addition & 3 deletions packages/endpoint/src/schemas/__tests__/Values.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// eslint-env jest
import { normalize } from '@data-client/normalizr';
import { normalize, INVALID } from '@data-client/normalizr';
import { IDEntity } from '__tests__/new';
import { fromJS } from 'immutable';

import { SimpleMemoCache, fromJSEntities } from './denormalize';
import { schema } from '../../';
import { INVALID } from '../../special';
import Entity from '../Entity';

let dateSpy;
Expand Down
1 change: 0 additions & 1 deletion packages/endpoint/src/special.ts

This file was deleted.

4 changes: 4 additions & 0 deletions packages/normalizr/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ export interface GetIndex {
export interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}

/** Helpers during schema.normalize() */
Expand All @@ -140,6 +142,8 @@ export interface INormalizeDelegate {
entity: any,
meta?: { fetchedAt: number; date: number; expiresAt: number },
): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: { key: string; indexes?: any }, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
4 changes: 3 additions & 1 deletion packages/normalizr/src/memo/Delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
IQueryDelegate,
} from '../interface.js';
import { QueryPath, IndexPath } from './types.js';
import { INVALID } from '../denormalize/symbol.js';

export const getDependency =
(delegate: IBaseDelegate) =>
Expand Down Expand Up @@ -58,10 +59,11 @@ export class BaseDelegate implements IBaseDelegate {
}

export class TrackingQueryDelegate implements IQueryDelegate {
readonly INVALID = INVALID;
declare protected snap: IBaseDelegate;
// first dep path is ignored
// we start with schema object, then lookup any 'touched' members and their paths
declare dependencies: Dep<QueryPath>[];
declare readonly dependencies: Dep<QueryPath>[];

constructor(snap: IBaseDelegate, schema: any) {
this.snap = snap;
Expand Down
6 changes: 6 additions & 0 deletions packages/normalizr/src/normalize/NormalizeDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ export class NormalizeDelegate
if (updateMeta) this._setMeta(key, pk, meta);
}

/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: { key: string; indexes?: any }, pk: string) {
// set directly: any queued updates are meaningless with delete
this.setEntity(schema, pk, INVALID);
}

protected _setEntity(key: string, pk: string, entity: any) {
(this.entities[key] as any)[pk] = entity;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ interface GetIndex {
interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}
/** Helpers during schema.normalize() */
interface INormalizeDelegate {
Expand All @@ -89,6 +91,11 @@ interface INormalizeDelegate {
date: number;
expiresAt: number;
}): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: {
key: string;
indexes?: any;
}, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ interface GetIndex {
interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}
/** Helpers during schema.normalize() */
interface INormalizeDelegate {
Expand All @@ -276,6 +278,11 @@ interface INormalizeDelegate {
date: number;
expiresAt: number;
}): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: {
key: string;
indexes?: any;
}, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
Expand Down Expand Up @@ -1150,9 +1157,7 @@ declare abstract class Entity extends Entity_base {

declare function validateRequired(processedEntity: any, requiredDefaults: Record<string, unknown>): string | undefined;

declare const INVALID: unique symbol;

/** https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-4.html#the-noinfer-utility-type */
type NI<T> = NoInfer<T>;

export { type AbstractInstanceType, Array$1 as Array, Collection, type DefaultArgs, type Denormalize, type DenormalizeNullable, type DenormalizeNullableObject, type DenormalizeObject, Endpoint, type EndpointExtendOptions, type EndpointExtraOptions, type EndpointInstance, type EndpointInstanceInterface, type EndpointInterface, type EndpointOptions, type EndpointParam, type EndpointToFunction, Entity, type EntityFields, type EntityMap, EntityMixin, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, INVALID, type INormalizeDelegate, type IQueryDelegate, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type SnapshotInterface, type UnknownError, schema_d as schema, validateRequired };
export { type AbstractInstanceType, Array$1 as Array, Collection, type DefaultArgs, type Denormalize, type DenormalizeNullable, type DenormalizeNullableObject, type DenormalizeObject, Endpoint, type EndpointExtendOptions, type EndpointExtraOptions, type EndpointInstance, type EndpointInstanceInterface, type EndpointInterface, type EndpointOptions, type EndpointParam, type EndpointToFunction, Entity, type EntityFields, type EntityMap, EntityMixin, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, type INormalizeDelegate, type IQueryDelegate, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type SnapshotInterface, type UnknownError, schema_d as schema, validateRequired };
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ interface GetIndex {
interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}
/** Helpers during schema.normalize() */
interface INormalizeDelegate {
Expand All @@ -276,6 +278,11 @@ interface INormalizeDelegate {
date: number;
expiresAt: number;
}): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: {
key: string;
indexes?: any;
}, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
Expand Down Expand Up @@ -1150,8 +1157,6 @@ declare abstract class Entity extends Entity_base {

declare function validateRequired(processedEntity: any, requiredDefaults: Record<string, unknown>): string | undefined;

declare const INVALID: unique symbol;

/** https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-4.html#the-noinfer-utility-type */
type NI<T> = NoInfer<T>;

Expand Down Expand Up @@ -1196,4 +1201,4 @@ interface GQLError {
path: (string | number)[];
}

export { type AbstractInstanceType, Array$1 as Array, Collection, type DefaultArgs, type Denormalize, type DenormalizeNullable, type DenormalizeNullableObject, type DenormalizeObject, Endpoint, type EndpointExtendOptions, type EndpointExtraOptions, type EndpointInstance, type EndpointInstanceInterface, type EndpointInterface, type EndpointOptions, type EndpointParam, type EndpointToFunction, Entity, type EntityFields, type EntityMap, EntityMixin, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, GQLEndpoint, GQLEntity, type GQLError, GQLNetworkError, type GQLOptions, INVALID, type INormalizeDelegate, type IQueryDelegate, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type SnapshotInterface, type UnknownError, schema_d as schema, validateRequired };
export { type AbstractInstanceType, Array$1 as Array, Collection, type DefaultArgs, type Denormalize, type DenormalizeNullable, type DenormalizeNullableObject, type DenormalizeObject, Endpoint, type EndpointExtendOptions, type EndpointExtraOptions, type EndpointInstance, type EndpointInstanceInterface, type EndpointInterface, type EndpointOptions, type EndpointParam, type EndpointToFunction, Entity, type EntityFields, type EntityMap, EntityMixin, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, GQLEndpoint, GQLEntity, type GQLError, GQLNetworkError, type GQLOptions, type INormalizeDelegate, type IQueryDelegate, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type SnapshotInterface, type UnknownError, schema_d as schema, validateRequired };
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ interface GetIndex {
interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}
/** Helpers during schema.normalize() */
interface INormalizeDelegate {
Expand All @@ -102,6 +104,11 @@ interface INormalizeDelegate {
date: number;
expiresAt: number;
}): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: {
key: string;
indexes?: any;
}, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}
Expand Down
Loading
Loading