entity-repository 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.ts CHANGED
@@ -1,11 +1,24 @@
1
1
  import { ReactNode } from "react";
2
2
  import { type Observable } from "rxjs";
3
3
  import type { ListQueryOptions, ListQueryState } from "./list-query";
4
- import type { EntityConfig, EntityDefinitions, EntityIdTuple, RepositoryQuery } from "./types";
4
+ import type { EntityConfig, EntityDefinitions, EntityIdTuple, RepositoryConfig, RepositoryQuery } from "./types";
5
5
  import { Repository } from "./repository";
6
- export declare function createRepositoryContext<Definitions extends EntityDefinitions, Config extends EntityConfig<Definitions> = EntityConfig<Definitions>>(): {
7
- RepositoryProvider: ({ repository, children, }: {
8
- repository: Repository<Definitions, Config>;
6
+ /**
7
+ * Creates a typed entity repository plus the React hooks that operate on it.
8
+ *
9
+ * The factory OWNS the Repository instance — there's exactly one per call,
10
+ * and it's exposed as `repository` on the return. Consumers don't write
11
+ * `new Repository(...)`; they `import { repository }` and use it directly
12
+ * for code that runs outside React (e.g. seeding rows inside a fetcher
13
+ * closure). Components reach the same instance through the hooks.
14
+ *
15
+ * The `RepositoryProvider` is still emitted so a subtree can opt into a
16
+ * different repository for testing, but in normal use it's a passthrough
17
+ * — `useRepository()` returns the factory-owned singleton by default.
18
+ */
19
+ export declare function createRepositoryContext<Definitions extends EntityDefinitions, Config extends EntityConfig<Definitions> = EntityConfig<Definitions>>(config: RepositoryConfig<Definitions, Config>): {
20
+ repository: Repository<Definitions, Config>;
21
+ RepositoryProvider: ({ children }: {
9
22
  children: ReactNode;
10
23
  }) => import("react/jsx-runtime").JSX.Element;
11
24
  useRepository: () => Repository<Definitions, Config>;
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAA6E,MAAM,OAAO,CAAC;AAE5H,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,wBAAgB,uBAAuB,CACrC,WAAW,SAAS,iBAAiB,EACrC,MAAM,SAAS,YAAY,CAAC,WAAW,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC;oDAOjE;QACD,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5C,QAAQ,EAAE,SAAS,CAAC;KACrB;;yBAyC2B,KAAK,SAAS,MAAM,WAAW,SAClD,KAAK,MACR,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,WACpC,CAAC,EAAE,EAAE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAC7F,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;6BAmDN,KAAK,SAAS,MAAM,WAAW,EAAE,KAAK,SAC7D,KAAK,SACL,KAAK,WACH,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,WACpC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,KACvD,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;wBAlCV,KAAK,SAAS,MAAM,WAAW,EAAE,GAAG,SACtD,KAAK,OACP,GAAG,WACC,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,KAC5C,WAAW,CAAC,KAAK,CAAC,EAAE;yBAvDK,KAAK,cAAc,UAAU,CAAC,KAAK,CAAC,eAAe,MAAM,KAAK;EAmH3F"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAA6E,MAAM,OAAO,CAAC;AAE5H,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACjH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,SAAS,iBAAiB,EACrC,MAAM,SAAS,YAAY,CAAC,WAAW,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,EACpE,MAAM,EAAE,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC;;uCAIH;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE;;yBAqCrC,KAAK,SAAS,MAAM,WAAW,SAClD,KAAK,MACR,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,WACpC,CAAC,EAAE,EAAE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAC7F,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;6BA+CN,KAAK,SAAS,MAAM,WAAW,EAAE,KAAK,SAC7D,KAAK,SACL,KAAK,WACH,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,WACpC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,KACvD,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;wBA/BV,KAAK,SAAS,MAAM,WAAW,EAAE,GAAG,SACtD,KAAK,OACP,GAAG,WACC,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,KAC5C,WAAW,CAAC,KAAK,CAAC,EAAE;yBAtDK,KAAK,cAAc,UAAU,CAAC,KAAK,CAAC,eAAe,MAAM,KAAK;EA+G3F"}
package/dist/react.js CHANGED
@@ -1,17 +1,28 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
3
3
  import { combineLatest, map } from "rxjs";
4
- export function createRepositoryContext() {
5
- const RepositoryReactContext = createContext(null);
6
- function RepositoryProvider({ repository, children, }) {
4
+ import { Repository } from "./repository";
5
+ /**
6
+ * Creates a typed entity repository plus the React hooks that operate on it.
7
+ *
8
+ * The factory OWNS the Repository instance — there's exactly one per call,
9
+ * and it's exposed as `repository` on the return. Consumers don't write
10
+ * `new Repository(...)`; they `import { repository }` and use it directly
11
+ * for code that runs outside React (e.g. seeding rows inside a fetcher
12
+ * closure). Components reach the same instance through the hooks.
13
+ *
14
+ * The `RepositoryProvider` is still emitted so a subtree can opt into a
15
+ * different repository for testing, but in normal use it's a passthrough
16
+ * — `useRepository()` returns the factory-owned singleton by default.
17
+ */
18
+ export function createRepositoryContext(config) {
19
+ const repository = new Repository(config);
20
+ const RepositoryReactContext = createContext(repository);
21
+ function RepositoryProvider({ children }) {
7
22
  return (_jsx(RepositoryReactContext.Provider, { value: repository, children: children }));
8
23
  }
9
24
  function useRepository() {
10
- const context = useContext(RepositoryReactContext);
11
- if (!context) {
12
- throw new Error("RepositoryProvider is missing.");
13
- }
14
- return context;
25
+ return useContext(RepositoryReactContext);
15
26
  }
16
27
  function useSubscribedState(observable, getSnapshot) {
17
28
  const snapshotRef = useRef(getSnapshot());
@@ -32,9 +43,8 @@ export function createRepositoryContext() {
32
43
  * query instance remains stable for a given `id`.
33
44
  */
34
45
  function useRepositoryQuery(table, id, fetcher) {
35
- const repository = useRepository();
36
46
  // eslint-disable-next-line react-hooks/exhaustive-deps -- table/fetcher intentionally ignored
37
- const recordQuery = useMemo(() => repository.recordQuery(table, id, fetcher), [repository, JSON.stringify(id)]);
47
+ const recordQuery = useMemo(() => repository.recordQuery(table, id, fetcher), [JSON.stringify(id)]);
38
48
  return useSubscribedState(recordQuery.$state, () => recordQuery.$state.value);
39
49
  }
40
50
  /**
@@ -49,12 +59,9 @@ export function createRepositoryContext() {
49
59
  * inputs, e.g. a task id).
50
60
  */
51
61
  function useObservableList(table, key, options) {
52
- const repository = useRepository();
53
62
  // eslint-disable-next-line react-hooks/exhaustive-deps -- table/options intentionally ignored (stable for a given key)
54
- const observable = useMemo(() => repository.observableList(table, options), [repository, JSON.stringify(key)]);
63
+ const observable = useMemo(() => repository.observableList(table, options), [JSON.stringify(key)]);
55
64
  return useSubscribedState(observable, () => {
56
- // Pull the current snapshot via a synchronous one-shot subscribe.
57
- // observableList emits its first value synchronously.
58
65
  let snapshot = [];
59
66
  const sub = observable.subscribe((value) => {
60
67
  snapshot = value;
@@ -70,9 +77,8 @@ export function createRepositoryContext() {
70
77
  * list query instance remains stable for a given `param`.
71
78
  */
72
79
  function useRepositoryListQuery(table, param, options, fetcher) {
73
- const repository = useRepository();
74
80
  // eslint-disable-next-line react-hooks/exhaustive-deps -- table/options/fetcher intentionally ignored
75
- const listQuery = useMemo(() => repository.listQuery(table, options, () => fetcher(param)), [repository, JSON.stringify(param)]);
81
+ const listQuery = useMemo(() => repository.listQuery(table, options, () => fetcher(param)), [JSON.stringify(param)]);
76
82
  useEffect(() => {
77
83
  return () => listQuery.dispose();
78
84
  }, [listQuery]);
@@ -80,6 +86,7 @@ export function createRepositoryContext() {
80
86
  return useSubscribedState($state, () => ({ records: listQuery.$records.value, ...listQuery.$status.value }));
81
87
  }
82
88
  return {
89
+ repository,
83
90
  RepositoryProvider,
84
91
  useRepository,
85
92
  useRepositoryQuery,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "entity-repository",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Type-safe entity caching and state management with RxJS and React",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -54,6 +54,7 @@
54
54
  "devDependencies": {
55
55
  "@types/node": "^22.0.0",
56
56
  "@types/react": "^19.2.8",
57
+ "react": "^19.0.0",
57
58
  "tsx": "^4.19.0",
58
59
  "typescript": "^5.9.3"
59
60
  }