@osdk/react 0.9.3 → 0.10.0-beta.10

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.
Files changed (103) hide show
  1. package/AGENTS.md +46 -221
  2. package/CHANGELOG.md +109 -51
  3. package/build/browser/new/makeExternalStore.js +61 -0
  4. package/build/browser/new/makeExternalStore.js.map +1 -1
  5. package/build/browser/new/useLinks.js +11 -4
  6. package/build/browser/new/useLinks.js.map +1 -1
  7. package/build/browser/new/useObjectSet.js +6 -3
  8. package/build/browser/new/useObjectSet.js.map +1 -1
  9. package/build/browser/new/useOsdkAction.js +2 -2
  10. package/build/browser/new/useOsdkAction.js.map +1 -1
  11. package/build/browser/new/useOsdkAggregation.js +65 -27
  12. package/build/browser/new/useOsdkAggregation.js.map +1 -1
  13. package/build/browser/new/useOsdkFunction.js +17 -12
  14. package/build/browser/new/useOsdkFunction.js.map +1 -1
  15. package/build/browser/new/useOsdkObject.js +36 -17
  16. package/build/browser/new/useOsdkObject.js.map +1 -1
  17. package/build/browser/new/useOsdkObjects.js +28 -19
  18. package/build/browser/new/useOsdkObjects.js.map +1 -1
  19. package/build/browser/{intellisense.test.helpers/useOsdkObjectsWithPivot.js → public/experimental/admin.js} +4 -19
  20. package/build/browser/public/experimental/admin.js.map +1 -0
  21. package/build/browser/public/experimental.js +0 -3
  22. package/build/browser/public/experimental.js.map +1 -1
  23. package/build/browser/useOsdkMetadata.js.map +1 -1
  24. package/build/cjs/{chunk-V32JHU3O.cjs → chunk-OVBG5VXE.cjs} +3 -8
  25. package/build/cjs/chunk-OVBG5VXE.cjs.map +1 -0
  26. package/build/cjs/chunk-SVVMLSKN.cjs +111 -0
  27. package/build/cjs/chunk-SVVMLSKN.cjs.map +1 -0
  28. package/build/cjs/index.cjs +4 -4
  29. package/build/cjs/index.d.cts +1 -1
  30. package/build/cjs/public/experimental/admin.cjs +146 -0
  31. package/build/cjs/public/experimental/admin.cjs.map +1 -0
  32. package/build/cjs/public/experimental/admin.d.cts +118 -0
  33. package/build/cjs/public/experimental.cjs +217 -478
  34. package/build/cjs/public/experimental.cjs.map +1 -1
  35. package/build/cjs/public/experimental.d.cts +88 -127
  36. package/build/cjs/useOsdkMetadata-BElt3F5s.d.cts +15 -0
  37. package/build/esm/new/makeExternalStore.js +61 -0
  38. package/build/esm/new/makeExternalStore.js.map +1 -1
  39. package/build/esm/new/useLinks.js +11 -4
  40. package/build/esm/new/useLinks.js.map +1 -1
  41. package/build/esm/new/useObjectSet.js +6 -3
  42. package/build/esm/new/useObjectSet.js.map +1 -1
  43. package/build/esm/new/useOsdkAction.js +2 -2
  44. package/build/esm/new/useOsdkAction.js.map +1 -1
  45. package/build/esm/new/useOsdkAggregation.js +65 -27
  46. package/build/esm/new/useOsdkAggregation.js.map +1 -1
  47. package/build/esm/new/useOsdkFunction.js +17 -12
  48. package/build/esm/new/useOsdkFunction.js.map +1 -1
  49. package/build/esm/new/useOsdkObject.js +36 -17
  50. package/build/esm/new/useOsdkObject.js.map +1 -1
  51. package/build/esm/new/useOsdkObjects.js +28 -19
  52. package/build/esm/new/useOsdkObjects.js.map +1 -1
  53. package/build/esm/{intellisense.test.helpers/useOsdkObjectsWithPivot.js → public/experimental/admin.js} +4 -19
  54. package/build/esm/public/experimental/admin.js.map +1 -0
  55. package/build/esm/public/experimental.js +0 -3
  56. package/build/esm/public/experimental.js.map +1 -1
  57. package/build/esm/useOsdkMetadata.js.map +1 -1
  58. package/build/types/new/makeExternalStore.d.ts +11 -0
  59. package/build/types/new/makeExternalStore.d.ts.map +1 -1
  60. package/build/types/new/useLinks.d.ts +19 -0
  61. package/build/types/new/useLinks.d.ts.map +1 -1
  62. package/build/types/new/useObjectSet.d.ts +6 -0
  63. package/build/types/new/useObjectSet.d.ts.map +1 -1
  64. package/build/types/new/useOsdkAggregation.d.ts +41 -3
  65. package/build/types/new/useOsdkAggregation.d.ts.map +1 -1
  66. package/build/types/new/useOsdkFunction.d.ts +11 -5
  67. package/build/types/new/useOsdkFunction.d.ts.map +1 -1
  68. package/build/types/new/useOsdkObject.d.ts +12 -1
  69. package/build/types/new/useOsdkObject.d.ts.map +1 -1
  70. package/build/types/new/useOsdkObjects.d.ts +10 -0
  71. package/build/types/new/useOsdkObjects.d.ts.map +1 -1
  72. package/build/types/public/experimental/admin.d.ts +3 -0
  73. package/build/types/public/experimental/admin.d.ts.map +1 -0
  74. package/build/types/public/experimental.d.ts +0 -3
  75. package/build/types/public/experimental.d.ts.map +1 -1
  76. package/build/types/useOsdkMetadata.d.ts +5 -4
  77. package/build/types/useOsdkMetadata.d.ts.map +1 -1
  78. package/docs/querying-data.md +19 -0
  79. package/{build/esm/intellisense.test.helpers/useOsdkObjectsWithProperties.js → experimental/admin.d.ts} +1 -18
  80. package/package.json +29 -8
  81. package/build/browser/intellisense.test.helpers/useOsdkObjectsWithPivot.js.map +0 -1
  82. package/build/browser/intellisense.test.helpers/useOsdkObjectsWithProperties.js +0 -34
  83. package/build/browser/intellisense.test.helpers/useOsdkObjectsWithProperties.js.map +0 -1
  84. package/build/browser/intellisense.test.helpers/useOsdkObjectsWithRids.js +0 -37
  85. package/build/browser/intellisense.test.helpers/useOsdkObjectsWithRids.js.map +0 -1
  86. package/build/browser/intellisense.test.js +0 -172
  87. package/build/browser/intellisense.test.js.map +0 -1
  88. package/build/cjs/chunk-V32JHU3O.cjs.map +0 -1
  89. package/build/cjs/useOsdkMetadata-DFZhnhGZ.d.cts +0 -14
  90. package/build/esm/intellisense.test.helpers/useOsdkObjectsWithPivot.js.map +0 -1
  91. package/build/esm/intellisense.test.helpers/useOsdkObjectsWithProperties.js.map +0 -1
  92. package/build/esm/intellisense.test.helpers/useOsdkObjectsWithRids.js +0 -37
  93. package/build/esm/intellisense.test.helpers/useOsdkObjectsWithRids.js.map +0 -1
  94. package/build/esm/intellisense.test.js +0 -172
  95. package/build/esm/intellisense.test.js.map +0 -1
  96. package/build/types/intellisense.test.d.ts +0 -1
  97. package/build/types/intellisense.test.d.ts.map +0 -1
  98. package/build/types/intellisense.test.helpers/useOsdkObjectsWithPivot.d.ts +0 -1
  99. package/build/types/intellisense.test.helpers/useOsdkObjectsWithPivot.d.ts.map +0 -1
  100. package/build/types/intellisense.test.helpers/useOsdkObjectsWithProperties.d.ts +0 -1
  101. package/build/types/intellisense.test.helpers/useOsdkObjectsWithProperties.d.ts.map +0 -1
  102. package/build/types/intellisense.test.helpers/useOsdkObjectsWithRids.d.ts +0 -1
  103. package/build/types/intellisense.test.helpers/useOsdkObjectsWithRids.d.ts.map +0 -1
package/AGENTS.md CHANGED
@@ -1,21 +1,20 @@
1
- # @osdk/react - AI Agent Instructions
1
+ # @osdk/react
2
2
 
3
- ## Critical Rules
3
+ ## Rules
4
4
 
5
- 1. **Use `OsdkProvider2`** - Not `OsdkProvider`. All modern hooks require `OsdkProvider2`.
6
- 2. **Import from `@osdk/react/experimental`** - Not `@osdk/react`. The main entry point only has legacy hooks.
7
- 3. **Never conditionally call hooks** - Use the `enabled` option instead.
8
- 4. **Keep rendering during loading** - No early returns like `if (isLoading) return <Spinner />`. Show loading indicators while rendering existing data.
5
+ 1. **Use `OsdkProvider2`**, not `OsdkProvider`. All modern hooks require it.
6
+ 2. **Import from `@osdk/react/experimental`**, not `@osdk/react`. Main entry only has legacy hooks.
7
+ 3. **Never conditionally call hooks.** Use the `enabled` option instead.
8
+ 4. **Keep rendering during loading.** No early returns like `if (isLoading) return <Spinner />`. Show loading indicators alongside existing data to prevent UI flashing. Exception: `if (!data && isLoading)` is acceptable for initial load.
9
+ 5. **`useOsdkObject` `enabled` is positional**, not in an options object: `useOsdkObject(Type, id, false)`.
9
10
 
10
11
  ## Exports
11
12
 
12
- **Stable** (`@osdk/react`):
13
+ **Stable** (`@osdk/react`): `OsdkProvider` (legacy), `useOsdkClient`, `useOsdkMetadata`
13
14
 
14
- - `OsdkProvider` - Legacy provider
15
- - `useOsdkClient` - Access client
16
- - `useOsdkMetadata` - Fetch metadata
15
+ **Experimental** (`@osdk/react/experimental`): `OsdkProvider2`, `useOsdkObjects`, `useOsdkObject`, `useOsdkAction`, `useLinks`, `useObjectSet`, `useOsdkAggregation`, `useOsdkFunction`, `useDebouncedCallback`, `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList`
17
16
 
18
- **Experimental** (`@osdk/react/experimental`):
17
+ ## Hook Options
19
18
 
20
19
  - `OsdkProvider2` - Modern provider (use this)
21
20
  - `useOsdkObjects` - Query lists of objects
@@ -24,230 +23,56 @@
24
23
  - `useLinks` - Navigate object relationships
25
24
  - `useObjectSet` - Advanced set operations (union, intersect, subtract, pivot)
26
25
  - `useOsdkAggregation` - Server-side aggregations with groupBy/select
27
- - `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList` - Platform APIs
28
26
  - `useOsdkClient`, `useOsdkMetadata` - Also available from experimental
29
27
 
30
- ## Correct Patterns
31
-
32
- ### Loading States
33
-
34
- ```tsx
35
- import { Todo } from "@my/osdk";
36
- import { useOsdkObjects } from "@osdk/react/experimental";
37
-
38
- function TodoList() {
39
- const { data, isLoading, error } = useOsdkObjects(Todo);
40
-
41
- return (
42
- <div>
43
- {isLoading && <LoadingIndicator />}
44
- {error && <ErrorMessage error={error} />}
45
- {data?.map(todo => <TodoItem key={todo.$primaryKey} todo={todo} />)}
46
- </div>
47
- );
48
- }
49
- ```
28
+ **Experimental Admin** (`@osdk/react/experimental/admin`):
50
29
 
51
- ### Single Object (useOsdkObject)
52
-
53
- ```tsx
54
- import { Employee } from "@my/osdk";
55
- import { useOsdkObject } from "@osdk/react/experimental";
56
-
57
- // By type + primary key (enabled is 3rd positional param)
58
- const { object, isLoading, error, isOptimistic } = useOsdkObject(
59
- Employee,
60
- "employee-123",
61
- true, // enabled (optional, defaults to true)
62
- );
63
-
64
- // By existing instance (enabled is 2nd positional param)
65
- const { object: refreshed } = useOsdkObject(existingEmployee, true);
66
- ```
67
-
68
- ### Conditional Fetching
69
-
70
- ```tsx
71
- // useOsdkObjects uses options object
72
- const { data: reports } = useOsdkObjects(Employee, {
73
- where: { managerId: selectedManagerId },
74
- enabled: !!selectedManagerId,
75
- });
76
-
77
- // useOsdkObject uses positional enabled parameter
78
- const { object: manager } = useOsdkObject(Employee, managerId, !!managerId);
79
- ```
30
+ - `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList` - Platform APIs (requires `@osdk/foundry.admin`)
80
31
 
81
- ### Actions (useOsdkAction)
32
+ ## Correct Patterns
82
33
 
83
- ```tsx
84
- import { $Actions } from "@my/osdk";
85
- import { useOsdkAction } from "@osdk/react/experimental";
86
-
87
- function CompleteTodoButton({ todo }) {
88
- const {
89
- applyAction,
90
- validateAction,
91
- isPending,
92
- isValidating,
93
- error,
94
- data,
95
- validationResult,
96
- } = useOsdkAction($Actions.completeTodo);
97
-
98
- // Validate before applying
99
- const handleValidate = async () => {
100
- const result = await validateAction({ todo, isComplete: true });
101
- };
102
-
103
- // Apply the action
104
- const handleComplete = async () => {
105
- await applyAction({ todo, isComplete: true });
106
- };
107
-
108
- // With optimistic update (use $ prefix for client options)
109
- const handleOptimistic = async () => {
110
- await applyAction({
111
- todo,
112
- isComplete: true,
113
- $optimisticUpdate: (ctx) => {
114
- ctx.updateObject(todo, { isComplete: true });
115
- },
116
- });
117
- };
118
-
119
- return (
120
- <button onClick={handleComplete} disabled={isPending}>
121
- Complete
122
- </button>
123
- );
124
- }
125
- ```
34
+ | Hook | Key Options |
35
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
36
+ | `useOsdkObjects` | `where`, `orderBy`, `pageSize`, `withProperties`, `enabled`, `autoFetchMore`, `dedupeIntervalMs`, `streamUpdates`, `intersectWith`, `pivotTo` |
37
+ | `useObjectSet` | Same as above plus `union`, `intersect`, `subtract`. Use when you need set operations. |
38
+ | `useOsdkObject` | `enabled` is **positional** (2nd param for instance, 3rd for type+key) |
39
+ | `useLinks` | `where`, `pageSize`, `enabled`, `mode` (`"force"` / `"offline"`), `dedupeIntervalMs`. Accepts single object or array. |
40
+ | `useOsdkAction` | Returns `applyAction`, `validateAction`, `isPending`, `error`, `validationResult`. Pass `$optimisticUpdate` with `$` prefix in action params. |
41
+ | `useOsdkAggregation` | `where`, `aggregate: { $groupBy, $select }`. Metrics: `$count`, `sum`, `avg`, `min`, `max`, `exactDistinct`, `approximateDistinct`. |
42
+ | `useOsdkFunction` | `params`, `dependsOn` (object types), `dependsOnObjects` (instances), `enabled`, `dedupeIntervalMs` |
126
43
 
127
- ### Links (useLinks)
44
+ ## Text Search Filters
128
45
 
129
- ```tsx
130
- import { useLinks } from "@osdk/react/experimental";
131
-
132
- // Single object
133
- const { links, isLoading, hasMore, fetchMore, error } = useLinks(
134
- employee,
135
- "directReports",
136
- { pageSize: 20 },
137
- );
138
-
139
- // Multiple objects (returns all linked objects)
140
- const { links: allReports } = useLinks(
141
- [employee1, employee2],
142
- "directReports",
143
- );
144
- ```
46
+ `$startsWith`, `$containsAnyTerm`, `$containsAllTerms`, `$containsAllTermsInOrder`. All support `{ term, fuzzySearch: true }`.
145
47
 
146
- ### Object Set Operations (useObjectSet)
48
+ ## useOsdkObjects vs useObjectSet
147
49
 
148
- ```tsx
149
- import { Employee } from "@my/osdk";
150
- import { useObjectSet } from "@osdk/react/experimental";
151
-
152
- const { data, isLoading, fetchMore, objectSet } = useObjectSet(
153
- Employee.all(),
154
- {
155
- where: { department: "Engineering" },
156
- orderBy: { hireDate: "desc" },
157
- pageSize: 50,
158
- union: [otherObjectSet],
159
- intersect: [anotherObjectSet],
160
- autoFetchMore: 100, // fetch until 100 items
161
- streamUpdates: true,
162
- enabled: true,
163
- },
164
- );
165
- ```
50
+ Use `useOsdkObjects` by default (more optimized). Use `useObjectSet` only when you need `union`/`intersect`/`subtract` set operations.
166
51
 
167
- ### Aggregations (useOsdkAggregation)
52
+ ## Cache
168
53
 
169
- ```tsx
170
- import { Employee } from "@my/osdk";
171
- import { useOsdkAggregation } from "@osdk/react/experimental";
172
-
173
- const { data, isLoading, error, refetch } = useOsdkAggregation(Employee, {
174
- where: { department: "Engineering" },
175
- aggregate: {
176
- groupBy: { department: "exact" },
177
- select: {
178
- avgSalary: { $avg: "salary" },
179
- count: { $count: {} },
180
- },
181
- },
182
- });
183
- ```
54
+ The `ObservableClient` maintains a normalized cache. Objects update automatically after actions. For manual invalidation: `observableClient.invalidateObjects()`, `.invalidateObjectType()`, `.invalidateFunction()`, `.invalidateAll()`.
184
55
 
185
56
  ## Anti-Patterns
186
57
 
187
- ### Wrong: Conditional Hook Call
188
-
189
- ```tsx
190
- if (shouldLoad) {
191
- const { data } = useOsdkObjects(Todo); // NEVER do this
192
- }
193
- ```
194
-
195
- ### Wrong: Early Return During Loading
196
-
197
- ```tsx
198
- if (isLoading) return <Spinner />; // Causes UI flashing
199
- if (!data) return null; // Loses state
200
- ```
201
-
202
- ### Wrong: Importing from Main Entry
203
-
204
- ```tsx
205
- import { useOsdkObjects } from "@osdk/react"; // WRONG - doesn't exist here
206
- ```
207
-
208
- ### Wrong: Using OsdkProvider Instead of OsdkProvider2
209
-
210
58
  ```tsx
211
- <OsdkProvider client={client}> // WRONG - new hooks won't work
212
- ```
213
-
214
- ### Wrong: Using options object for useOsdkObject enabled
215
-
216
- ```tsx
217
- // WRONG - enabled is positional, not in options
218
- const { object } = useOsdkObject(Employee, id, { enabled: false });
219
-
59
+ // WRONG: conditional hook
60
+ if (x) { useOsdkObjects(Todo); }
61
+ // CORRECT: use enabled
62
+ useOsdkObjects(Todo, { enabled: x });
63
+
64
+ // WRONG: early return
65
+ if (isLoading) return <Spinner />;
66
+ // CORRECT: render together
67
+ <div>{isLoading && <Spinner />}{data?.map(...)}</div>
68
+
69
+ // WRONG: import from main entry
70
+ import { useOsdkObjects } from "@osdk/react";
220
71
  // CORRECT
221
- const { object } = useOsdkObject(Employee, id, false);
222
- ```
223
-
224
- ## Hook Options Reference
225
-
226
- **useOsdkObjects / useObjectSet:**
227
-
228
- - `where` - Filter conditions
229
- - `orderBy` - Sort order (`{ field: "asc" | "desc" }`)
230
- - `pageSize` - Results per page
231
- - `withProperties` - Derived properties
232
- - `enabled` - Enable/disable query
233
- - `autoFetchMore` - Auto-pagination (`true` | `number`)
234
- - `dedupeIntervalMs` - Request deduplication
235
- - `streamUpdates` - WebSocket updates
236
-
237
- **useObjectSet additional:**
238
-
239
- - `union`, `intersect`, `subtract` - Set operations
240
- - `pivotTo` - Pivot to linked type
241
-
242
- **useOsdkObject:**
243
-
244
- - `enabled` is a **positional parameter**, not in options
245
-
246
- **useLinks:**
247
-
248
- - `where`, `pageSize`, `enabled`
249
- - `mode` - `"force"` | `"offline"`
250
-
251
- **useOsdkAction:**
72
+ import { useOsdkObjects } from "@osdk/react/experimental";
252
73
 
253
- - `$optimisticUpdate` - Passed to action with `$` prefix
74
+ // WRONG: useOsdkObject enabled in options
75
+ useOsdkObject(Employee, id, { enabled: false });
76
+ // CORRECT: positional
77
+ useOsdkObject(Employee, id, false);
78
+ ```
package/CHANGELOG.md CHANGED
@@ -1,63 +1,136 @@
1
1
  # @osdkkit/react
2
2
 
3
- ## 0.9.3
3
+ ## 0.10.0-beta.10
4
+
5
+ ### Minor Changes
6
+
7
+ - dbbfb6f: Add experimental ActionForm component with field renderers, form state hook, and tests
4
8
 
5
9
  ### Patch Changes
6
10
 
7
- - 679ac34: Allow interface object sets in useObjectSet
11
+ - Updated dependencies [cbfa135]
12
+ - Updated dependencies [f4604c2]
13
+ - @osdk/client@2.8.0-beta.22
14
+ - @osdk/api@2.8.0-beta.22
15
+
16
+ ## 0.10.0-beta.9
8
17
 
9
- ## 0.9.2
18
+ ### Minor Changes
19
+
20
+ - c40444b: Add linkedObjectsBySourcePrimaryKey to link observation responses
10
21
 
11
22
  ### Patch Changes
12
23
 
13
- - 16c9987: Preserve object set data between loads
24
+ - Updated dependencies [c40444b]
25
+ - Updated dependencies [dda14be]
26
+ - @osdk/client@2.8.0-beta.21
27
+ - @osdk/api@2.8.0-beta.21
28
+
29
+ ## 0.10.0-beta.8
30
+
31
+ ### Minor Changes
14
32
 
15
- ## 0.9.1
33
+ - 9720083: Add AGENTS.md files for AI IDE context
34
+ - 09e5659: add $select support to observable client and react hooks
35
+ - 8a82492: Move admin hooks to @osdk/react/experimental/admin subpath to avoid bundler crash when @osdk/foundry.admin is not installed
36
+ - 2ebe62c: package and bundle size optimizations
16
37
 
17
38
  ### Patch Changes
18
39
 
19
- - 17d4115: add interface support to useOsdkObject
40
+ - Updated dependencies [09e5659]
41
+ - Updated dependencies [2ebe62c]
42
+ - @osdk/client@2.8.0-beta.16
43
+ - @osdk/api@2.8.0-beta.16
20
44
 
21
- ## 0.9.0
45
+ ## 0.10.0-beta.7
22
46
 
23
47
  ### Minor Changes
24
48
 
25
- - 6cfe14a: add new useOsdkFunction hook and supporting client infrastructure
26
- - 43d342e: Fix fetchMore in useObjectSet and useLinks
49
+ - 9156827: Preserve object set data between loads
50
+ - 35f2f1a: Add Media inputs/outputs for Queries
51
+ - 71e28ef: Allow interface object sets in useObjectSet
27
52
 
28
53
  ### Patch Changes
29
54
 
30
- - 322c5bc: Simulated release
31
- - ddef59f: update docs
32
- - adca853: fix fetchMore behavior
33
- - acf6331: Include AGENTS.md and docs directory in published package for improved AI assistant support
34
- - 74e3ba7: Preserve aggregate option literal types in useOsdkAggregation using const type parameter
35
- - a6d4d49: fix useLinks stabilization
36
- - ba3159c: improve loading logic to make loading state consistent / reduce flashing
37
- - eb3a556: wire totalCount for osdk react hooks
38
- - a23784c: wire action edit response types through for useOsdkAction
39
- - ecd18e2: fix pivotTo with where usage
40
- - 31cd835: Revert beta changes
41
- - 38d5958: fix order by via key stabilization
42
- - 56ba08f: support interfaces for osdk react hooks
43
- - 0dbd0d0: add useOsdkObjects rid querying support
44
- - 0395d4b: Pins Foundry core and admin packages to monorepo version
45
- - 0b2cd91: fix SimplePropertyDef issue, wire RDPs through, update names
46
- - db28747: rdp typing improvements
55
+ - Updated dependencies [e64bf0b]
56
+ - Updated dependencies [baba327]
57
+ - Updated dependencies [d1ad4d1]
58
+ - Updated dependencies [35f2f1a]
59
+ - Updated dependencies [71e28ef]
60
+ - @osdk/client@2.8.0-beta.14
61
+ - @osdk/api@2.8.0-beta.14
62
+
63
+ ## 0.10.0-beta.6
64
+
65
+ ### Minor Changes
66
+
67
+ - 993c023: ObjectTable supports objectSet input
68
+
69
+ ### Patch Changes
70
+
71
+ - Updated dependencies [8825f8c]
72
+ - @osdk/client@2.8.0-beta.12
73
+ - @osdk/api@2.8.0-beta.12
74
+
75
+ ## 0.10.0-beta.5
47
76
 
48
- ## 0.9.0-rc.11
77
+ ### Minor Changes
78
+
79
+ - 525f277: update useOsdkAggregation to support composed object sets, async
80
+ - d80c234: add interface support to useOsdkObject
81
+ - 996d8e4: memoize hook responses
82
+
83
+ ### Patch Changes
84
+
85
+ - Updated dependencies [642be5f]
86
+ - Updated dependencies [525f277]
87
+ - Updated dependencies [f5f95e2]
88
+ - Updated dependencies [d80c234]
89
+ - @osdk/client@2.8.0-beta.11
90
+ - @osdk/api@2.8.0-beta.11
91
+
92
+ ## 0.10.0-beta.4
93
+
94
+ ### Minor Changes
95
+
96
+ - 727fd0e: fix dual @types/react version mismatch
97
+
98
+ ### Patch Changes
99
+
100
+ - Updated dependencies [8c60682]
101
+ - Updated dependencies [15e1686]
102
+ - Updated dependencies [c9d954d]
103
+ - Updated dependencies [044eb80]
104
+ - Updated dependencies [9d234b9]
105
+ - @osdk/client@2.8.0-beta.6
106
+ - @osdk/api@2.8.0-beta.6
107
+
108
+ ## 0.10.0-beta.3
109
+
110
+ ### Minor Changes
111
+
112
+ - 73e617e: expose dedupeInterval on useLinks and fix forced revalidation bypassing dedupeInterval
113
+ - a027f3c: stabilize subscription deps in useOsdkObjects and useOsdkAggregation
49
114
 
50
115
  ### Patch Changes
51
116
 
52
- - a6d4d49: fix useLinks stabilization
53
- - eb3a556: wire totalCount for osdk react hooks
54
- - 31cd835: Revert beta changes
55
- - 0dbd0d0: add useOsdkObjects rid querying support
56
- - Updated dependencies [eb3a556]
57
- - Updated dependencies [31cd835]
58
- - Updated dependencies [0dbd0d0]
59
- - @osdk/client@2.7.0-rc.15
60
- - @osdk/api@2.7.0-rc.15
117
+ - Updated dependencies [73e617e]
118
+ - Updated dependencies [5848e3c]
119
+ - @osdk/client@2.8.0-beta.4
120
+ - @osdk/api@2.8.0-beta.4
121
+
122
+ ## 0.10.0-beta.2
123
+
124
+ ### Minor Changes
125
+
126
+ - 0d174a2: useOsdkFunction typing updates
127
+
128
+ ### Patch Changes
129
+
130
+ - Updated dependencies [26cec61]
131
+ - Updated dependencies [0d174a2]
132
+ - @osdk/client@2.8.0-beta.3
133
+ - @osdk/api@2.8.0-beta.3
61
134
 
62
135
  ## 0.9.0-beta.10
63
136
 
@@ -177,21 +250,6 @@
177
250
  - @osdk/client@2.7.0-beta.2
178
251
  - @osdk/api@2.7.0-beta.2
179
252
 
180
- ## 0.8.0
181
-
182
- ### Patch Changes
183
-
184
- - 322c5bc: Simulated release
185
- - 13f229d: preserve object set data on rid change
186
- - c5a3815: Add new auto fetch more behavior to useOsdkObjects
187
- - 4b13323: update OSDK toolkit docs
188
- - 9961f06: fix order by via key stabilization
189
- - e7bf02a: Add RDP support to React toolkit
190
- - af4f3bf: Remove the following features for RC:
191
- - Property formatting
192
- - Branching
193
- - Constant RDPs
194
-
195
253
  ## 0.8.0-beta.5
196
254
 
197
255
  ### Minor Changes
@@ -42,4 +42,65 @@ export function makeExternalStore(createObservation, _name, initialValue) {
42
42
  getSnapShot
43
43
  };
44
44
  }
45
+
46
+ /**
47
+ * Like makeExternalStore but for async subscription creation.
48
+ *
49
+ * Uses an isActive flag to handle race conditions:
50
+ * If cleanup runs before promise resolves, the stale subscription is
51
+ * immediately unsubscribed when it eventually resolves
52
+ */
53
+ export function makeExternalStoreAsync(createObservation, _name, initialValue) {
54
+ let lastResult = initialValue;
55
+ function getSnapShot() {
56
+ return lastResult;
57
+ }
58
+ function subscribe(notifyUpdate) {
59
+ let isActive = true;
60
+ let currentSubscription;
61
+ const subscriptionPromise = createObservation({
62
+ next: payload => {
63
+ if (isActive) {
64
+ lastResult = payload;
65
+ notifyUpdate();
66
+ }
67
+ },
68
+ error: error => {
69
+ if (isActive) {
70
+ lastResult = {
71
+ ...(lastResult ?? {}),
72
+ error: error instanceof Error ? error : new Error(String(error))
73
+ };
74
+ notifyUpdate();
75
+ }
76
+ },
77
+ complete: () => {}
78
+ });
79
+ subscriptionPromise.then(sub => {
80
+ if (isActive) {
81
+ currentSubscription = sub;
82
+ } else {
83
+ sub.unsubscribe();
84
+ }
85
+ }).catch(error => {
86
+ if (isActive) {
87
+ lastResult = {
88
+ ...(lastResult ?? {}),
89
+ error: error instanceof Error ? error : new Error(String(error))
90
+ };
91
+ notifyUpdate();
92
+ }
93
+ });
94
+ return () => {
95
+ isActive = false;
96
+ if (currentSubscription) {
97
+ currentSubscription.unsubscribe();
98
+ }
99
+ };
100
+ }
101
+ return {
102
+ subscribe,
103
+ getSnapShot
104
+ };
105
+ }
45
106
  //# sourceMappingURL=makeExternalStore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"makeExternalStore.js","names":["makeExternalStore","createObservation","_name","initialValue","lastResult","getSnapShot","subscribe","notifyUpdate","obs","next","payload","error","Error","String","complete","unsubscribe"],"sources":["makeExternalStore.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n Observer,\n Unsubscribable,\n} from \"@osdk/client/unstable-do-not-use\";\n\nexport type Snapshot<X> =\n | X & { error?: Error }\n | (Partial<X> & { error?: Error })\n | undefined;\n\nexport function makeExternalStore<X>(\n createObservation: (callback: Observer<X | undefined>) => Unsubscribable,\n _name?: string,\n initialValue?: Snapshot<X>,\n): {\n subscribe: (notifyUpdate: () => void) => () => void;\n getSnapShot: () => Snapshot<X>;\n} {\n let lastResult: Snapshot<X> = initialValue;\n\n function getSnapShot(): Snapshot<X> {\n return lastResult;\n }\n\n function subscribe(notifyUpdate: () => void) {\n const obs = createObservation({\n next: (payload) => {\n lastResult = payload as Snapshot<X>;\n notifyUpdate();\n },\n error: (error: unknown) => {\n lastResult = {\n ...(lastResult ?? {}),\n error: error instanceof Error ? error : new Error(String(error)),\n } as Snapshot<X>;\n notifyUpdate();\n },\n complete: () => {},\n });\n\n return (): void => {\n obs.unsubscribe();\n };\n }\n\n return {\n subscribe,\n getSnapShot,\n };\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA,OAAO,SAASA,iBAAiBA,CAC/BC,iBAAwE,EACxEC,KAAc,EACdC,YAA0B,EAI1B;EACA,IAAIC,UAAuB,GAAGD,YAAY;EAE1C,SAASE,WAAWA,CAAA,EAAgB;IAClC,OAAOD,UAAU;EACnB;EAuBA,OAAO;IACLE,SAAS,EAtBX,SAASA,SAASA,CAACC,YAAwB,EAAE;MAC3C,MAAMC,GAAG,GAAGP,iBAAiB,CAAC;QAC5BQ,IAAI,EAAGC,OAAO,IAAK;UACjBN,UAAU,GAAGM,OAAsB;UACnCH,YAAY,CAAC,CAAC;QAChB,CAAC;QACDI,KAAK,EAAGA,KAAc,IAAK;UACzBP,UAAU,GAAG;YACX,IAAIA,UAAU,IAAI,CAAC,CAAC,CAAC;YACrBO,KAAK,EAAEA,KAAK,YAAYC,KAAK,GAAGD,KAAK,GAAG,IAAIC,KAAK,CAACC,MAAM,CAACF,KAAK,CAAC;UACjE,CAAgB;UAChBJ,YAAY,CAAC,CAAC;QAChB,CAAC;QACDO,QAAQ,EAAEA,CAAA,KAAM,CAAC;MACnB,CAAC,CAAC;MAEF,OAAO,MAAY;QACjBN,GAAG,CAACO,WAAW,CAAC,CAAC;MACnB,CAAC;IACH,CAGW;IACTV;EACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"makeExternalStore.js","names":["makeExternalStore","createObservation","_name","initialValue","lastResult","getSnapShot","subscribe","notifyUpdate","obs","next","payload","error","Error","String","complete","unsubscribe","makeExternalStoreAsync","isActive","currentSubscription","subscriptionPromise","then","sub","catch"],"sources":["makeExternalStore.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n Observer,\n Unsubscribable,\n} from \"@osdk/client/unstable-do-not-use\";\n\nexport type Snapshot<X> =\n | X & { error?: Error }\n | (Partial<X> & { error?: Error })\n | undefined;\n\nexport function makeExternalStore<X>(\n createObservation: (callback: Observer<X | undefined>) => Unsubscribable,\n _name?: string,\n initialValue?: Snapshot<X>,\n): {\n subscribe: (notifyUpdate: () => void) => () => void;\n getSnapShot: () => Snapshot<X>;\n} {\n let lastResult: Snapshot<X> = initialValue;\n\n function getSnapShot(): Snapshot<X> {\n return lastResult;\n }\n\n function subscribe(notifyUpdate: () => void) {\n const obs = createObservation({\n next: (payload) => {\n lastResult = payload as Snapshot<X>;\n notifyUpdate();\n },\n error: (error: unknown) => {\n lastResult = {\n ...(lastResult ?? {}),\n error: error instanceof Error ? error : new Error(String(error)),\n } as Snapshot<X>;\n notifyUpdate();\n },\n complete: () => {},\n });\n\n return (): void => {\n obs.unsubscribe();\n };\n }\n\n return {\n subscribe,\n getSnapShot,\n };\n}\n\n/**\n * Like makeExternalStore but for async subscription creation.\n *\n * Uses an isActive flag to handle race conditions:\n * If cleanup runs before promise resolves, the stale subscription is\n * immediately unsubscribed when it eventually resolves\n */\nexport function makeExternalStoreAsync<X>(\n createObservation: (\n callback: Observer<X | undefined>,\n ) => Promise<Unsubscribable>,\n _name?: string,\n initialValue?: Snapshot<X>,\n): {\n subscribe: (notifyUpdate: () => void) => () => void;\n getSnapShot: () => Snapshot<X>;\n} {\n let lastResult: Snapshot<X> = initialValue;\n\n function getSnapShot(): Snapshot<X> {\n return lastResult;\n }\n\n function subscribe(notifyUpdate: () => void) {\n let isActive = true;\n let currentSubscription: Unsubscribable | undefined;\n\n const subscriptionPromise = createObservation({\n next: (payload) => {\n if (isActive) {\n lastResult = payload as Snapshot<X>;\n notifyUpdate();\n }\n },\n error: (error: unknown) => {\n if (isActive) {\n lastResult = {\n ...(lastResult ?? {}),\n error: error instanceof Error ? error : new Error(String(error)),\n } as Snapshot<X>;\n notifyUpdate();\n }\n },\n complete: () => {},\n });\n\n subscriptionPromise.then((sub) => {\n if (isActive) {\n currentSubscription = sub;\n } else {\n sub.unsubscribe();\n }\n }).catch((error: unknown) => {\n if (isActive) {\n lastResult = {\n ...(lastResult ?? {}),\n error: error instanceof Error ? error : new Error(String(error)),\n } as Snapshot<X>;\n notifyUpdate();\n }\n });\n\n return (): void => {\n isActive = false;\n if (currentSubscription) {\n currentSubscription.unsubscribe();\n }\n };\n }\n\n return {\n subscribe,\n getSnapShot,\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -18,6 +18,7 @@ import React from "react";
18
18
  import { makeExternalStore } from "./makeExternalStore.js";
19
19
  import { OsdkContext2 } from "./OsdkContext2.js";
20
20
  const emptyArray = Object.freeze([]);
21
+ const emptyMap = new Map();
21
22
 
22
23
  /**
23
24
  * Hook to observe links from an object or array of objects.
@@ -37,6 +38,7 @@ export function useLinks(objects, linkName, options = {}) {
37
38
  } = options;
38
39
  const stableWhere = React.useMemo(() => otherOptions.where, [JSON.stringify(otherOptions.where)]);
39
40
  const stableOrderBy = React.useMemo(() => otherOptions.orderBy, [JSON.stringify(otherOptions.orderBy)]);
41
+ const stableSelect = React.useMemo(() => otherOptions.$select, [JSON.stringify(otherOptions.$select)]);
40
42
  const objectsKey = React.useMemo(() => {
41
43
  if (objects === undefined) return "";
42
44
  const arr = Array.isArray(objects) ? objects : [objects];
@@ -61,17 +63,22 @@ export function useLinks(objects, linkName, options = {}) {
61
63
  where: stableWhere,
62
64
  pageSize: otherOptions.pageSize,
63
65
  orderBy: stableOrderBy,
64
- mode: otherOptions.mode
66
+ mode: otherOptions.mode,
67
+ dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,
68
+ ...(stableSelect ? {
69
+ select: stableSelect
70
+ } : {})
65
71
  }, observer), `links ${linkName} for ${objectsKey}`);
66
- }, [enabled, observableClient, objectsArray, objectsKey, linkName, stableWhere, otherOptions.pageSize, stableOrderBy, otherOptions.mode]);
72
+ }, [enabled, observableClient, objectsArray, objectsKey, linkName, stableWhere, otherOptions.pageSize, stableOrderBy, otherOptions.mode, otherOptions.dedupeIntervalMs, stableSelect]);
67
73
  const payload = React.useSyncExternalStore(subscribe, getSnapShot);
68
- return {
74
+ return React.useMemo(() => ({
69
75
  links: payload?.resolvedList,
76
+ linkedObjectsBySourcePrimaryKey: payload?.linkedObjectsBySourcePrimaryKey ?? emptyMap,
70
77
  isLoading: enabled ? payload?.status === "loading" || payload?.status === "init" || !payload : false,
71
78
  isOptimistic: payload?.isOptimistic ?? false,
72
79
  error: payload?.error,
73
80
  fetchMore: payload?.hasMore ? payload?.fetchMore : undefined,
74
81
  hasMore: payload?.hasMore ?? false
75
- };
82
+ }), [payload, enabled]);
76
83
  }
77
84
  //# sourceMappingURL=useLinks.js.map