Skip to content

Commit 4929cd5

Browse files
committed
enhance: delegate.getEntities -> delegate.forEntities
1 parent 421b6ba commit 4929cd5

File tree

14 files changed

+164
-97
lines changed

14 files changed

+164
-97
lines changed

.changeset/proud-taxes-bake.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,26 @@
33
'@data-client/endpoint': minor
44
---
55

6-
delegate.getEntity(this.key) -> delegate.getEntities(this.key)
6+
delegate.getEntity(key) -> delegate.forEntities(key, cb)
77

8-
This applies to both schema.queryKey and schema.normalize method delegates.
8+
This applies to both schema.queryKey and schema.normalize method delegates.
9+
10+
#### Before
11+
12+
```ts
13+
const entities = delegate.getEntity(this.key);
14+
if (entities)
15+
Object.keys(entities).forEach(collectionPk => {
16+
if (!filterCollections(JSON.parse(collectionPk))) return;
17+
delegate.mergeEntity(this, collectionPk, normalizedValue);
18+
});
19+
```
20+
21+
#### After
22+
23+
```ts
24+
delegate.forEntities(this.key, ([collectionKey]) => {
25+
if (!filterCollections(JSON.parse(collectionKey))) return;
26+
delegate.mergeEntity(this, collectionKey, normalizedValue);
27+
});
28+
```

packages/endpoint/src/interface.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ export interface CheckLoop {
127127
(entityKey: string, pk: string, input: object): boolean;
128128
}
129129

130-
/** Get all normalized entities of one type from store */
131-
export interface GetEntities {
132-
(key: string): { readonly [pk: string]: any } | undefined;
130+
/** Loop over all entities of a given key */
131+
export interface ForEntities {
132+
(key: string, callbackfn: (value: [string, unknown]) => void): boolean;
133133
}
134134
/** Get normalized Entity from store */
135135
export interface GetEntity {
@@ -143,7 +143,7 @@ export interface GetIndex {
143143

144144
/** Accessors to the currently processing state while building query */
145145
export interface IQueryDelegate {
146-
getEntities: GetEntities;
146+
forEntities: ForEntities;
147147
getEntity: GetEntity;
148148
getIndex: GetIndex;
149149
/** Return to consider results invalid */
@@ -154,8 +154,8 @@ export interface IQueryDelegate {
154154
export interface INormalizeDelegate {
155155
/** Action meta-data for this normalize call */
156156
readonly meta: { fetchedAt: number; date: number; expiresAt: number };
157-
/** Get all normalized entities of one type from store */
158-
getEntities: GetEntities;
157+
/** Loop over all entities of a given key */
158+
forEntities: ForEntities;
159159
/** Gets any previously normalized entity from store */
160160
getEntity: GetEntity;
161161
/** Updates an entity using merge lifecycles when it has previously been set */

packages/endpoint/src/schemas/All.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,30 @@ export default class AllSchema<
2626

2727
queryKey(args: any, unvisit: any, delegate: IQueryDelegate): any {
2828
if (this.isSingleSchema) {
29-
const entitiesEntry = delegate.getEntities(this.schema.key);
29+
const entities: any[] = [];
30+
if (
31+
delegate.forEntities(this.schema.key, ([pk, entity]) => {
32+
if (entity) entities.push(this.schema.pk(entity));
33+
})
34+
)
35+
return entities;
3036
// we must wait until there are entries for any 'All' query to be Valid
31-
if (entitiesEntry === undefined) return delegate.INVALID;
32-
return Object.values(entitiesEntry).map(
33-
entity => entity && this.schema.pk(entity),
34-
);
37+
return delegate.INVALID;
3538
}
3639
let found = false;
3740
const list = Object.values(this.schema as Record<string, any>).flatMap(
3841
(schema: EntityInterface) => {
39-
const entitiesEntry = delegate.getEntities(schema.key);
40-
if (entitiesEntry === undefined) return [];
41-
found = true;
42-
return Object.entries(entitiesEntry).map(([key, entity]) => ({
43-
id: entity && schema.pk(entity, undefined, key, []),
44-
schema: this.getSchemaAttribute(entity, undefined, key),
45-
}));
42+
const entities: any[] = [];
43+
if (
44+
delegate.forEntities(schema.key, ([pk, entity]) => {
45+
entities.push({
46+
id: entity && schema.pk(entity, undefined, pk, []),
47+
schema: this.getSchemaAttribute(entity, undefined, pk),
48+
});
49+
})
50+
)
51+
found = true;
52+
return entities;
4653
},
4754
);
4855
// we need at least one table entry of the Union for this to count as Valid.

packages/endpoint/src/schemas/Collection.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,10 @@ function normalizeCreate(
326326
// parent is args when not nested
327327
const filterCollections = (this.createCollectionFilter as any)(...args);
328328
// add to any collections that match this
329-
const entities = delegate.getEntities(this.key);
330-
if (entities)
331-
Object.keys(entities).forEach(collectionPk => {
332-
if (!filterCollections(JSON.parse(collectionPk))) return;
333-
delegate.mergeEntity(this, collectionPk, normalizedValue);
334-
});
329+
delegate.forEntities(this.key, ([collectionKey]) => {
330+
if (!filterCollections(JSON.parse(collectionKey))) return;
331+
delegate.mergeEntity(this, collectionKey, normalizedValue);
332+
});
335333
return normalizedValue as any;
336334
}
337335

packages/normalizr/src/delegate/BaseDelegate.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ export abstract class BaseDelegate {
1717
this.indexes = indexes;
1818
}
1919

20-
abstract getEntities(...path: EntitiesPath): object | undefined;
20+
abstract forEntities(
21+
key: string,
22+
callbackfn: (value: [string, unknown]) => void,
23+
): boolean;
24+
25+
// we must expose the entities object to track in our WeakDependencyMap
26+
// however, this should not be part of the public API
27+
protected abstract getEntities(key: string): object | undefined;
2128
abstract getEntity(key: string, pk: string): object | undefined;
2229
abstract getIndex(...path: IndexPath): object | undefined;
2330
abstract getIndexEnd(entity: any, value: string): string | undefined;
@@ -40,10 +47,14 @@ export abstract class BaseDelegate {
4047
dependencies.push({ path, entity });
4148
return entity;
4249
},
43-
getEntities(...path: EntitiesPath) {
44-
const entity = base.getEntities(...path);
45-
dependencies.push({ path, entity });
46-
return entity;
50+
forEntities(
51+
key: string,
52+
callbackfn: (value: [string, any]) => void,
53+
): boolean {
54+
const entity = base.getEntities(key);
55+
// always push even if entity is undefined
56+
dependencies.push({ path: [key], entity });
57+
return base.forEntities(key, callbackfn);
4758
},
4859
};
4960
return [delegate, dependencies];

packages/normalizr/src/delegate/Delegate.imm.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { BaseDelegate } from './BaseDelegate.js';
22

33
export type ImmutableJSEntityTable = {
4-
get(key: string): { toJS(): any } | undefined;
4+
get(key: string):
5+
| {
6+
forEach(
7+
sideEffect: (value: any, key: string, iter: any) => unknown,
8+
context?: unknown,
9+
): number;
10+
}
11+
| undefined;
512
getIn(k: [key: string, pk: string]): { toJS(): any } | undefined;
613
setIn(k: [key: string, pk: string], value: any);
714
};
@@ -18,8 +25,27 @@ export class ImmDelegate extends BaseDelegate {
1825
super(state);
1926
}
2027

21-
getEntities(key: string): any {
22-
return this.entities.get(key)?.toJS();
28+
forEntities(
29+
key: string,
30+
callbackfn: (value: [string, unknown]) => void,
31+
): boolean {
32+
const entities = this.getEntities(key);
33+
if (!entities) return false;
34+
entities.forEach((entity: any, pk: string) => {
35+
callbackfn([pk, entity]);
36+
});
37+
return true;
38+
}
39+
40+
protected getEntities(key: string):
41+
| {
42+
forEach(
43+
sideEffect: (value: any, key: string, iter: any) => unknown,
44+
context?: unknown,
45+
): number;
46+
}
47+
| undefined {
48+
return this.entities.get(key);
2349
}
2450

2551
getEntity(...path: [key: string, pk: string]): any {

packages/normalizr/src/delegate/Delegate.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,21 @@ export class POJODelegate extends BaseDelegate {
1414
super(state);
1515
}
1616

17-
getEntities(key: string): any {
17+
forEntities(
18+
key: string,
19+
callbackfn: (
20+
value: [string, unknown],
21+
index: number,
22+
array: [string, unknown][],
23+
) => void,
24+
): boolean {
25+
const entities = this.getEntities(key);
26+
if (entities === undefined) return false;
27+
Object.entries(entities).forEach(callbackfn);
28+
return true;
29+
}
30+
31+
protected getEntities(key: string): object | undefined {
1832
return this.entities[key];
1933
}
2034

packages/normalizr/src/interface.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ export interface CheckLoop {
114114
(entityKey: string, pk: string, input: object): boolean;
115115
}
116116

117-
/** Get all normalized entities of one type from store */
118-
export interface GetEntities {
119-
(key: string): { readonly [pk: string]: any } | undefined;
117+
/** Loop over all entities of a given key */
118+
export interface ForEntities {
119+
(key: string, callbackfn: (value: [string, unknown]) => void): boolean;
120120
}
121121
/** Get normalized Entity from store */
122122
export interface GetEntity {
@@ -130,7 +130,7 @@ export interface GetIndex {
130130

131131
/** Accessors to the currently processing state while building query */
132132
export interface IQueryDelegate {
133-
getEntities: GetEntities;
133+
forEntities: ForEntities;
134134
getEntity: GetEntity;
135135
getIndex: GetIndex;
136136
/** Return to consider results invalid */
@@ -141,8 +141,8 @@ export interface IQueryDelegate {
141141
export interface INormalizeDelegate {
142142
/** Action meta-data for this normalize call */
143143
readonly meta: { fetchedAt: number; date: number; expiresAt: number };
144-
/** Get all normalized entities of one type from store */
145-
getEntities: GetEntities;
144+
/** Loop over all entities of a given key */
145+
forEntities: ForEntities;
146146
/** Gets any previously normalized entity from store */
147147
getEntity: GetEntity;
148148
/** Updates an entity using merge lifecycles when it has previously been set */

website/src/components/Playground/editor-types/@data-client/core.d.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,9 @@ interface EntityPath {
5757
type IndexPath = [key: string, index: string, value: string];
5858
type EntitiesPath = [key: string];
5959
type QueryPath = IndexPath | [key: string, pk: string] | EntitiesPath;
60-
/** Get all normalized entities of one type from store */
61-
interface GetEntities {
62-
(key: string): {
63-
readonly [pk: string]: any;
64-
} | undefined;
60+
/** Loop over all entities of a given key */
61+
interface ForEntities {
62+
(key: string, callbackfn: (value: [string, unknown]) => void): boolean;
6563
}
6664
/** Get normalized Entity from store */
6765
interface GetEntity {
@@ -74,7 +72,7 @@ interface GetIndex {
7472
}
7573
/** Accessors to the currently processing state while building query */
7674
interface IQueryDelegate {
77-
getEntities: GetEntities;
75+
forEntities: ForEntities;
7876
getEntity: GetEntity;
7977
getIndex: GetIndex;
8078
/** Return to consider results invalid */
@@ -88,8 +86,8 @@ interface INormalizeDelegate {
8886
date: number;
8987
expiresAt: number;
9088
};
91-
/** Get all normalized entities of one type from store */
92-
getEntities: GetEntities;
89+
/** Loop over all entities of a given key */
90+
forEntities: ForEntities;
9391
/** Gets any previously normalized entity from store */
9492
getEntity: GetEntity;
9593
/** Updates an entity using merge lifecycles when it has previously been set */
@@ -230,7 +228,8 @@ declare abstract class BaseDelegate {
230228
entities: any;
231229
indexes: any;
232230
});
233-
abstract getEntities(...path: EntitiesPath): object | undefined;
231+
abstract forEntities(key: string, callbackfn: (value: [string, unknown]) => void): boolean;
232+
protected abstract getEntities(key: string): object | undefined;
234233
abstract getEntity(key: string, pk: string): object | undefined;
235234
abstract getIndex(...path: IndexPath): object | undefined;
236235
abstract getIndexEnd(entity: any, value: string): string | undefined;

website/src/components/Playground/editor-types/@data-client/endpoint.d.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,9 @@ type EntitiesPath = [key: string];
264264
interface CheckLoop {
265265
(entityKey: string, pk: string, input: object): boolean;
266266
}
267-
/** Get all normalized entities of one type from store */
268-
interface GetEntities {
269-
(key: string): {
270-
readonly [pk: string]: any;
271-
} | undefined;
267+
/** Loop over all entities of a given key */
268+
interface ForEntities {
269+
(key: string, callbackfn: (value: [string, unknown]) => void): boolean;
272270
}
273271
/** Get normalized Entity from store */
274272
interface GetEntity {
@@ -281,7 +279,7 @@ interface GetIndex {
281279
}
282280
/** Accessors to the currently processing state while building query */
283281
interface IQueryDelegate {
284-
getEntities: GetEntities;
282+
forEntities: ForEntities;
285283
getEntity: GetEntity;
286284
getIndex: GetIndex;
287285
/** Return to consider results invalid */
@@ -295,8 +293,8 @@ interface INormalizeDelegate {
295293
date: number;
296294
expiresAt: number;
297295
};
298-
/** Get all normalized entities of one type from store */
299-
getEntities: GetEntities;
296+
/** Loop over all entities of a given key */
297+
forEntities: ForEntities;
300298
/** Gets any previously normalized entity from store */
301299
getEntity: GetEntity;
302300
/** Updates an entity using merge lifecycles when it has previously been set */
@@ -1194,4 +1192,4 @@ declare function validateRequired(processedEntity: any, requiredDefaults: Record
11941192
/** https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-4.html#the-noinfer-utility-type */
11951193
type NI<T> = NoInfer<T>;
11961194

1197-
export { type AbstractInstanceType, Array$1 as Array, type CheckLoop, 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, type EntitiesPath, Entity, type EntityFields, type EntityInterface, type EntityMap, EntityMixin, type EntityPath, type EntityTable, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, type GetEntities, type GetEntity, type GetIndex, type IEntityClass, type IEntityInstance, type INormalizeDelegate, type IQueryDelegate, type IndexPath, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedIndex, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type Serializable, type SnapshotInterface, type UnknownError, type Visit, schema_d as schema, validateRequired };
1195+
export { type AbstractInstanceType, Array$1 as Array, type CheckLoop, 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, type EntitiesPath, Entity, type EntityFields, type EntityInterface, type EntityMap, EntityMixin, type EntityPath, type EntityTable, type ErrorTypes, type ExpiryStatusInterface, ExtendableEndpoint, type FetchFunction, type ForEntities, type GetEntity, type GetIndex, type IEntityClass, type IEntityInstance, type INormalizeDelegate, type IQueryDelegate, type IndexPath, Invalidate, type KeyofEndpointInstance, type Mergeable, type MutateEndpoint, type NI, type NetworkError, type Normalize, type NormalizeNullable, type NormalizeObject, type NormalizedEntity, type NormalizedIndex, type NormalizedNullableObject, type ObjectArgs, type PolymorphicInterface, type Queryable, type ReadEndpoint, type RecordClass, type ResolveType, type Schema, type SchemaArgs, type SchemaClass, type SchemaSimple, type Serializable, type SnapshotInterface, type UnknownError, type Visit, schema_d as schema, validateRequired };

0 commit comments

Comments
 (0)