Skip to content

Commit 2d3a39e

Browse files
committed
split up entity into multiple files
1 parent cba5470 commit 2d3a39e

File tree

4 files changed

+51
-52
lines changed

4 files changed

+51
-52
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { Any, AnyNoContext, Entity } from './types.js';
2+
3+
/*
4+
/*
5+
* Note: Currently we only use one global cache for all entities.
6+
* In the future we probably want a build function that creates a cache and returns the
7+
* functions (create, update, findMany, …) that use this specific cache.
8+
*
9+
* How does it work?
10+
*
11+
* We store all decoded entities in a cache and for each query we reference the entities relevant to this query.
12+
* Whenever a query is registered we add it to the cache and add a listener to the query. Whenever a query is unregistered we remove the listener from the query.
13+
*/
14+
type DecodedEntitiesCache = Map<
15+
string, // type name
16+
{
17+
decoder: (data: unknown) => unknown;
18+
type: Any; // TODO should be the type of the entity
19+
entities: Map<string, Entity<AnyNoContext>>; // holds all entities of this type
20+
queries: Map<
21+
string, // instead of serializedQueryKey as string we could also have the actual params
22+
{
23+
data: Array<Entity<AnyNoContext>>; // holds the decoded entities of this query and must be a stable reference and use the same reference for the `entities` array
24+
listeners: Array<() => void>; // listeners to this query
25+
}
26+
>;
27+
}
28+
>;
29+
30+
export const decodedEntitiesCache: DecodedEntitiesCache = new Map();

packages/hypergraph/src/entity/entity.ts

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import * as Data from 'effect/Data';
44
import * as Schema from 'effect/Schema';
55
import { generateId } from '../utils/generateId.js';
66
import { hasArrayField } from '../utils/hasArrayField.js';
7+
import { decodedEntitiesCache } from './decodedEntitiesCache.js';
8+
import type { AnyNoContext, Entity, Insert, Update } from './types.js';
79

810
const {
911
Class,
@@ -22,20 +24,6 @@ const {
2224

2325
export { Class };
2426

25-
export type Any = Schema.Schema.Any & {
26-
readonly fields: Schema.Struct.Fields;
27-
readonly insert: Schema.Schema.Any;
28-
readonly update: Schema.Schema.Any;
29-
};
30-
31-
export type AnyNoContext = Schema.Schema.AnyNoContext & {
32-
readonly fields: Schema.Struct.Fields;
33-
readonly insert: Schema.Schema.AnyNoContext;
34-
readonly update: Schema.Schema.AnyNoContext;
35-
};
36-
37-
export type Update<S extends Any> = S['update'];
38-
export type Insert<S extends Any> = S['insert'];
3927
export interface Generated<S extends Schema.Schema.All | Schema.PropertySignature.All>
4028
extends VariantSchema.Field<{
4129
readonly select: S;
@@ -64,44 +52,6 @@ export class EntityNotFoundError extends Data.TaggedError('EntityNotFoundError')
6452
cause?: unknown;
6553
}> {}
6654

67-
export type Entity<S extends AnyNoContext> = Schema.Schema.Type<S> & { type: string };
68-
69-
/*
70-
* Note: Currently we only use one global cache for all entities.
71-
* In the future we probably want a build function that creates a cache and returns the
72-
* functions (create, update, findMany, …) that use this specific cache.
73-
*
74-
* How does it work?
75-
*
76-
* We store all decoded entities in a cache and for each query we reference the entities relevant to this query.
77-
* Whenever a query is registered we add it to the cache and add a listener to the query. Whenever a query is unregistered we remove the listener from the query.
78-
*
79-
* Handling filters is relatively straight forward as they are uniquely identified by their params.
80-
*
81-
* Questions:
82-
* How do we handle findOne?
83-
* Thoughts: Could be just a special case of findMany limited to a specific id or a separate mechanism.
84-
* How do we handle relations?
85-
* Thoughts: We could have a separate query entry for each relation, but when requesting a lot of entities e.g. 1000 only for a nesting one level deep it would result in a lot of cached queries. Not sure this is a good idea.
86-
*/
87-
type DecodedEntitiesCache = Map<
88-
string, // type name
89-
{
90-
decoder: (data: unknown) => unknown;
91-
type: Any; // TODO should be the type of the entity
92-
entities: Map<string, Entity<AnyNoContext>>; // holds all entities of this type
93-
queries: Map<
94-
string, // instead of serializedQueryKey as string we could also have the actual params
95-
{
96-
data: Array<Entity<AnyNoContext>>; // holds the decoded entities of this query and must be a stable reference and use the same reference for the `entities` array
97-
listeners: Array<() => void>; // listeners to this query
98-
}
99-
>;
100-
}
101-
>;
102-
103-
const decodedEntitiesCache: DecodedEntitiesCache = new Map();
104-
10555
const documentChangeListener: {
10656
subscribedQueriesCount: number;
10757
unsubscribe: undefined | (() => void);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './entity.js';
2+
export * from './types.js';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type * as Schema from 'effect/Schema';
2+
3+
export type Any = Schema.Schema.Any & {
4+
readonly fields: Schema.Struct.Fields;
5+
readonly insert: Schema.Schema.Any;
6+
readonly update: Schema.Schema.Any;
7+
};
8+
9+
export type AnyNoContext = Schema.Schema.AnyNoContext & {
10+
readonly fields: Schema.Struct.Fields;
11+
readonly insert: Schema.Schema.AnyNoContext;
12+
readonly update: Schema.Schema.AnyNoContext;
13+
};
14+
15+
export type Update<S extends Any> = S['update'];
16+
export type Insert<S extends Any> = S['insert'];
17+
18+
export type Entity<S extends AnyNoContext> = Schema.Schema.Type<S> & { type: string };

0 commit comments

Comments
 (0)