@dxos/echo-react 0.10.0 → 0.11.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/echo-react",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "React integration for ECHO.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,7 +16,7 @@
16
16
  ".": {
17
17
  "source": "./src/index.ts",
18
18
  "types": "./dist/types/src/index.d.ts",
19
- "default": "./dist/lib/neutral/index.mjs"
19
+ "import": "./dist/lib/index.mjs"
20
20
  }
21
21
  },
22
22
  "types": "dist/types/src/index.d.ts",
@@ -27,7 +27,8 @@
27
27
  "dependencies": {
28
28
  "@effect-atom/atom": "^0.5.3",
29
29
  "@effect-atom/atom-react": "^0.5.0",
30
- "@dxos/echo": "0.10.0"
30
+ "@dxos/log": "0.11.0",
31
+ "@dxos/echo": "0.11.0"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@testing-library/react": "^16.3.2",
@@ -35,7 +36,7 @@
35
36
  "@types/react-dom": "~19.2.3",
36
37
  "react": "~19.2.7",
37
38
  "react-dom": "~19.2.7",
38
- "@dxos/echo-client": "0.10.0"
39
+ "@dxos/echo-client": "0.11.0"
39
40
  },
40
41
  "peerDependencies": {
41
42
  "react": "~19.2.7"
package/src/index.ts CHANGED
@@ -3,5 +3,6 @@
3
3
  //
4
4
 
5
5
  export * from './useQuery';
6
+ export * from './usePagination';
6
7
  export * from './useType';
7
8
  export * from './useObject';
package/src/useObject.ts CHANGED
@@ -118,9 +118,8 @@ export const useObject: {
118
118
  */
119
119
  <T, K extends keyof T>(ref: Ref.Ref<T> | undefined, property: K): [T[K] | undefined, ObjectPropUpdateCallback<T[K]>];
120
120
  } = (<T extends Obj.Unknown, K extends keyof T>(objOrRef: T | Ref.Ref<T> | undefined, property?: K): any => {
121
- // Get the live object for the callback (refs need to dereference).
122
121
  const isRef = Ref.isRef(objOrRef);
123
- const liveObj = isRef ? (objOrRef as Ref.Ref<T>)?.target : (objOrRef as T | undefined);
122
+ const liveObj = useResolveRef(objOrRef);
124
123
 
125
124
  const callback: ObjectPropUpdateCallback<unknown> = useCallback(
126
125
  (updateOrValue: unknown | ((obj: unknown) => unknown)) => {
@@ -150,51 +149,54 @@ export const useObject: {
150
149
  );
151
150
 
152
151
  if (property !== undefined) {
153
- // For refs, subscribe to load event only (not full mutation tracking).
154
- // Property-level updates are handled by useObjectProperty once the ref loads.
155
- useRefLoad(objOrRef);
156
- return [useObjectProperty(liveObj, property as any), callback];
152
+ return [useObjectProperty(liveObj, property), callback];
157
153
  } else {
158
154
  return [useObjectValue(objOrRef), callback];
159
155
  }
160
156
  }) as any;
161
157
 
162
158
  /**
163
- * Internal hook for subscribing to an Echo object or Ref.
159
+ * Hook for subscribing to an Echo object or Ref.
164
160
  */
165
- const useObjectValue = <T extends Obj.Unknown>(objOrRef: T | Ref.Ref<T> | undefined): Obj.Snapshot<T> | undefined => {
161
+ export const useObjectValue = <T extends Obj.Unknown | Obj.Snapshot>(
162
+ objOrRef: T | Ref.Ref<T> | undefined,
163
+ ): T extends Obj.Snapshot ? T : Obj.Snapshot<T & Obj.Unknown> | undefined => {
166
164
  const atom = useMemo(() => {
167
165
  if (objOrRef == null) {
168
- return Atom.make<Obj.Snapshot<T> | undefined>(() => undefined);
166
+ return Atom.make<Obj.Snapshot<T & Obj.Unknown> | undefined>(() => undefined);
169
167
  }
170
168
  if (Ref.isRef(objOrRef)) {
171
169
  return Obj.atom(objOrRef);
172
170
  }
173
- return Obj.atom(objOrRef);
171
+ if (Obj.isSnapshot(objOrRef)) {
172
+ return Atom.make<T>(() => objOrRef);
173
+ }
174
+ return Obj.atom(objOrRef as T & Obj.Unknown);
174
175
  }, [objOrRef]);
175
- return useAtomValue(atom) as Obj.Snapshot<T> | undefined;
176
+ return useAtomValue(atom as any);
176
177
  };
177
178
 
178
179
  /**
179
- * Internal hook for subscribing to ref resolution only (load-once).
180
- * Triggers a re-render when the ref target first becomes available,
181
- * without subscribing to subsequent target mutations.
182
- * For non-refs, this is a no-op.
180
+ * Resolves a Ref to its live target object, or returns the input when it is already an object.
181
+ * For refs, subscribes to load events only (not full mutation tracking).
183
182
  */
184
- const useRefLoad = <T extends Obj.Unknown>(objOrRef: T | Ref.Ref<T> | undefined): void => {
183
+ export const useResolveRef = <T extends Obj.Unknown>(objOrRef: T | Ref.Ref<T> | undefined): T | undefined => {
185
184
  const atom = useMemo(() => {
186
- if (objOrRef == null || !Ref.isRef(objOrRef)) {
185
+ if (objOrRef == null) {
187
186
  return Atom.make<T | undefined>(() => undefined);
188
187
  }
188
+ if (!Ref.isRef(objOrRef)) {
189
+ return Atom.make<T | undefined>(() => objOrRef as T);
190
+ }
189
191
  return objOrRef.atom;
190
192
  }, [objOrRef]);
191
- useAtomValue(atom);
193
+ return useAtomValue(atom);
192
194
  };
193
195
 
194
196
  /**
195
197
  * Internal hook for subscribing to a specific property of an Echo object.
196
198
  */
197
- const useObjectProperty = <T extends Obj.Unknown, K extends keyof T>(
199
+ const useObjectProperty = <T extends Obj.Unknown | Obj.Snapshot, K extends keyof T>(
198
200
  obj: T | undefined,
199
201
  property: K,
200
202
  ): T[K] | undefined => {
@@ -202,7 +204,10 @@ const useObjectProperty = <T extends Obj.Unknown, K extends keyof T>(
202
204
  if (obj == null) {
203
205
  return Atom.make<T[K] | undefined>(() => undefined);
204
206
  }
205
- return Obj.atomProperty(obj, property);
207
+ if (Obj.isSnapshot(obj)) {
208
+ return Atom.make<T[K]>(() => obj[property]);
209
+ }
210
+ return Obj.atomProperty(obj as T & Obj.Unknown, property);
206
211
  }, [obj, property]);
207
212
  return useAtomValue(atom);
208
213
  };