@osdk/react 0.10.0 → 0.10.1-main-20260406220320
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/CHANGELOG.md +10 -0
- package/build/browser/new/hookUtils.js +32 -0
- package/build/browser/new/hookUtils.js.map +1 -0
- package/build/browser/new/useLinks.js +13 -10
- package/build/browser/new/useLinks.js.map +1 -1
- package/build/browser/new/useObjectSet.js +45 -26
- package/build/browser/new/useObjectSet.js.map +1 -1
- package/build/browser/new/useOsdkAggregation.js +32 -38
- package/build/browser/new/useOsdkAggregation.js.map +1 -1
- package/build/browser/new/useOsdkObjects.js +31 -32
- package/build/browser/new/useOsdkObjects.js.map +1 -1
- package/build/cjs/public/experimental.cjs +129 -100
- package/build/cjs/public/experimental.cjs.map +1 -1
- package/build/cjs/public/experimental.d.cts +9 -3
- package/build/esm/new/hookUtils.js +32 -0
- package/build/esm/new/hookUtils.js.map +1 -0
- package/build/esm/new/useLinks.js +13 -10
- package/build/esm/new/useLinks.js.map +1 -1
- package/build/esm/new/useObjectSet.js +45 -26
- package/build/esm/new/useObjectSet.js.map +1 -1
- package/build/esm/new/useOsdkAggregation.js +32 -38
- package/build/esm/new/useOsdkAggregation.js.map +1 -1
- package/build/esm/new/useOsdkObjects.js +31 -32
- package/build/esm/new/useOsdkObjects.js.map +1 -1
- package/build/types/new/hookUtils.d.ts +7 -0
- package/build/types/new/hookUtils.d.ts.map +1 -0
- package/build/types/new/useLinks.d.ts.map +1 -1
- package/build/types/new/useObjectSet.d.ts +5 -2
- package/build/types/new/useObjectSet.d.ts.map +1 -1
- package/build/types/new/useOsdkAggregation.d.ts +1 -1
- package/build/types/new/useOsdkAggregation.d.ts.map +1 -1
- package/build/types/new/useOsdkObjects.d.ts +4 -1
- package/build/types/new/useOsdkObjects.d.ts.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @osdkkit/react
|
|
2
2
|
|
|
3
|
+
## 0.10.1-main-20260406220320
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 51ccca8: Refactor hooks to use canonicalizeOptions for stable memo keys, add objectSet/hasMore/refetch to useOsdkObjects return, support undefined objectSet in useObjectSet
|
|
8
|
+
- Updated dependencies [bcf359f]
|
|
9
|
+
- Updated dependencies [51ccca8]
|
|
10
|
+
- @osdk/client@2.8.1-main-20260406220320
|
|
11
|
+
- @osdk/api@2.8.1-main-20260406220320
|
|
12
|
+
|
|
3
13
|
## 0.10.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export function extractPayloadError(payload, fallbackMessage) {
|
|
18
|
+
if (payload && "error" in payload && payload.error) {
|
|
19
|
+
return payload.error;
|
|
20
|
+
}
|
|
21
|
+
if (payload?.status === "error") {
|
|
22
|
+
return new Error(fallbackMessage);
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
export function isPayloadLoading(payload, enabled) {
|
|
27
|
+
if (!enabled) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return payload?.status === "loading" || payload?.status === "init" || !payload;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=hookUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookUtils.js","names":["extractPayloadError","payload","fallbackMessage","error","status","Error","undefined","isPayloadLoading","enabled"],"sources":["hookUtils.ts"],"sourcesContent":["/*\n * Copyright 2026 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\nexport function extractPayloadError(\n payload: { error?: Error; status?: string } | undefined | null,\n fallbackMessage: string,\n): Error | undefined {\n if (payload && \"error\" in payload && payload.error) {\n return payload.error;\n }\n if (payload?.status === \"error\") {\n return new Error(fallbackMessage);\n }\n return undefined;\n}\n\nexport function isPayloadLoading(\n payload: { status?: string } | undefined | null,\n enabled: boolean,\n): boolean {\n if (!enabled) {\n return false;\n }\n return payload?.status === \"loading\" || payload?.status === \"init\"\n || !payload;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASA,mBAAmBA,CACjCC,OAA8D,EAC9DC,eAAuB,EACJ;EACnB,IAAID,OAAO,IAAI,OAAO,IAAIA,OAAO,IAAIA,OAAO,CAACE,KAAK,EAAE;IAClD,OAAOF,OAAO,CAACE,KAAK;EACtB;EACA,IAAIF,OAAO,EAAEG,MAAM,KAAK,OAAO,EAAE;IAC/B,OAAO,IAAIC,KAAK,CAACH,eAAe,CAAC;EACnC;EACA,OAAOI,SAAS;AAClB;AAEA,OAAO,SAASC,gBAAgBA,CAC9BN,OAA+C,EAC/CO,OAAgB,EACP;EACT,IAAI,CAACA,OAAO,EAAE;IACZ,OAAO,KAAK;EACd;EACA,OAAOP,OAAO,EAAEG,MAAM,KAAK,SAAS,IAAIH,OAAO,EAAEG,MAAM,KAAK,MAAM,IAC7D,CAACH,OAAO;AACf","ignoreList":[]}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import React from "react";
|
|
18
|
+
import { extractPayloadError, isPayloadLoading } from "./hookUtils.js";
|
|
18
19
|
import { makeExternalStore } from "./makeExternalStore.js";
|
|
19
20
|
import { OsdkContext2 } from "./OsdkContext2.js";
|
|
20
21
|
const emptyArray = Object.freeze([]);
|
|
@@ -36,9 +37,11 @@ export function useLinks(objects, linkName, options = {}) {
|
|
|
36
37
|
enabled = true,
|
|
37
38
|
...otherOptions
|
|
38
39
|
} = options;
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const canonOptions = observableClient.canonicalizeOptions({
|
|
41
|
+
where: otherOptions.where,
|
|
42
|
+
orderBy: otherOptions.orderBy,
|
|
43
|
+
$select: otherOptions.$select
|
|
44
|
+
});
|
|
42
45
|
const objectsKey = React.useMemo(() => {
|
|
43
46
|
if (objects === undefined) return "";
|
|
44
47
|
const arr = Array.isArray(objects) ? objects : [objects];
|
|
@@ -60,23 +63,23 @@ export function useLinks(objects, linkName, options = {}) {
|
|
|
60
63
|
}
|
|
61
64
|
return makeExternalStore(observer => observableClient.observeLinks(objectsArray, linkName, {
|
|
62
65
|
linkName,
|
|
63
|
-
where:
|
|
66
|
+
where: canonOptions.where,
|
|
64
67
|
pageSize: otherOptions.pageSize,
|
|
65
|
-
orderBy:
|
|
68
|
+
orderBy: canonOptions.orderBy,
|
|
66
69
|
mode: otherOptions.mode,
|
|
67
70
|
dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,
|
|
68
|
-
...(
|
|
69
|
-
select:
|
|
71
|
+
...(canonOptions.$select ? {
|
|
72
|
+
select: canonOptions.$select
|
|
70
73
|
} : {})
|
|
71
74
|
}, observer), `links ${linkName} for ${objectsKey}`);
|
|
72
|
-
}, [enabled, observableClient, objectsArray, objectsKey, linkName,
|
|
75
|
+
}, [enabled, observableClient, objectsArray, objectsKey, linkName, canonOptions.where, otherOptions.pageSize, canonOptions.orderBy, otherOptions.mode, otherOptions.dedupeIntervalMs, canonOptions.$select]);
|
|
73
76
|
const payload = React.useSyncExternalStore(subscribe, getSnapShot);
|
|
74
77
|
return React.useMemo(() => ({
|
|
75
78
|
links: payload?.resolvedList,
|
|
76
79
|
linkedObjectsBySourcePrimaryKey: payload?.linkedObjectsBySourcePrimaryKey ?? emptyMap,
|
|
77
|
-
isLoading:
|
|
80
|
+
isLoading: isPayloadLoading(payload, enabled),
|
|
78
81
|
isOptimistic: payload?.isOptimistic ?? false,
|
|
79
|
-
error: payload
|
|
82
|
+
error: extractPayloadError(payload, "Failed to load links"),
|
|
80
83
|
fetchMore: payload?.hasMore ? payload?.fetchMore : undefined,
|
|
81
84
|
hasMore: payload?.hasMore ?? false
|
|
82
85
|
}), [payload, enabled]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLinks.js","names":["React","makeExternalStore","OsdkContext2","emptyArray","Object","freeze","emptyMap","Map","useLinks","objects","linkName","options","observableClient","useContext","enabled","otherOptions","stableWhere","useMemo","where","JSON","stringify","stableOrderBy","orderBy","stableSelect","$select","objectsKey","undefined","arr","Array","isArray","map","obj","$apiName","$primaryKey","join","objectsArray","subscribe","getSnapShot","unsubscribe","observer","observeLinks","pageSize","mode","dedupeInterval","dedupeIntervalMs","select","payload","useSyncExternalStore","links","resolvedList","linkedObjectsBySourcePrimaryKey","isLoading","status","isOptimistic","error","fetchMore","hasMore"],"sources":["useLinks.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 LinkedType,\n LinkNames,\n ObjectOrInterfaceDefinition,\n} from \"@osdk/api\";\nimport type { Osdk, PropertyKeys, WhereClause } from \"@osdk/client\";\nimport type { ObserveLinks } from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { makeExternalStore } from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\nexport interface UseLinksOptions<\n T extends ObjectOrInterfaceDefinition,\n> {\n /**\n * Standard OSDK Where clause for filtering linked objects\n */\n where?: WhereClause<T>;\n\n /**\n * The preferred page size for the links list.\n */\n pageSize?: number;\n\n /** Sorting options for the linked objects */\n orderBy?: {\n [K in PropertyKeys<T>]?: \"asc\" | \"desc\";\n };\n\n /**\n * Restrict which properties are returned for each linked object.\n * When provided, only the specified properties will be fetched,\n * reducing payload sizes for list views.\n */\n $select?: readonly PropertyKeys<T>[];\n\n /**\n * The mode to use for fetching data.\n * - undefined: Fetch data if not already in cache\n * - \"force\": Always fetch fresh data\n * - \"offline\": Only use cached data, don't make network requests\n */\n mode?: \"force\" | \"offline\";\n\n /**\n * The number of milliseconds to wait after the last observed link change.\n *\n * Two uses of `useLinks` with the same parameters will only trigger one\n * network request if the second is within `dedupeIntervalMs`.\n */\n dedupeIntervalMs?: number;\n\n /**\n * Enable or disable the query.\n *\n * When `false`, the query will not automatically execute. It will still\n * return any cached data, but will not fetch from the server.\n *\n * This is useful for:\n * - Lazy/on-demand queries that should wait for user interaction\n * - Dependent queries that need data from another query first\n * - Conditional queries based on component state\n *\n * @default true\n * @example\n * // Dependent query - wait for employee data\n * const { object: employee } = useOsdkObject(Employee, employeeId);\n * const { links: reports } = useLinks(employee, \"reports\", {\n * enabled: !!employee\n * });\n */\n enabled?: boolean;\n}\n\nexport interface UseLinksResult<\n Q extends ObjectOrInterfaceDefinition,\n> {\n links: Osdk.Instance<Q>[] | undefined;\n\n /**\n * Maps each source object's primary key to its linked object instances.\n * Useful when observing links from multiple source objects to determine\n * which source links to which targets.\n */\n linkedObjectsBySourcePrimaryKey: ReadonlyMap<\n string | number,\n ReadonlyArray<Osdk.Instance<Q>>\n >;\n\n isLoading: boolean;\n error: Error | undefined;\n\n /**\n * Refers to whether the links are optimistic or not.\n */\n isOptimistic: boolean;\n\n /**\n * Fetch more linked objects if pagination is supported\n */\n fetchMore: (() => Promise<unknown>) | undefined;\n\n /**\n * Indicates if there are more linked objects available to fetch\n */\n hasMore: boolean;\n}\n\nconst emptyArray = Object.freeze([]);\nconst emptyMap: ReadonlyMap<string | number, ReadonlyArray<never>> = new Map();\n\n/**\n * Hook to observe links from an object or array of objects.\n *\n * @param objects The source object(s) to observe links from\n * @param linkName The name of the link to observe\n * @param options Optional configuration for the link query\n * @returns UseLinksResult with links data and metadata\n */\nexport function useLinks<\n T extends ObjectOrInterfaceDefinition,\n L extends LinkNames<T>,\n>(\n objects: Osdk.Instance<T> | Array<Osdk.Instance<T>> | undefined,\n linkName: L,\n options: UseLinksOptions<LinkedType<T, L>> = {},\n): UseLinksResult<LinkedType<T, L>> {\n const { observableClient } = React.useContext(OsdkContext2);\n\n const { enabled = true, ...otherOptions } = options;\n\n const stableWhere = React.useMemo(\n () => otherOptions.where,\n [JSON.stringify(otherOptions.where)],\n );\n\n const stableOrderBy = React.useMemo(\n () => otherOptions.orderBy,\n [JSON.stringify(otherOptions.orderBy)],\n );\n\n const stableSelect = React.useMemo(\n () => otherOptions.$select,\n [JSON.stringify(otherOptions.$select)],\n );\n\n const objectsKey = React.useMemo(() => {\n if (objects === undefined) return \"\";\n const arr = Array.isArray(objects) ? objects : [objects];\n return arr.map(obj => `${obj.$apiName}:${obj.$primaryKey}`).join(\",\");\n }, [objects]);\n\n // Convert single object to array for consistent handling\n const objectsArray: ReadonlyArray<Osdk.Instance<T>> = React.useMemo(() => {\n return objects === undefined\n ? emptyArray\n : Array.isArray(objects)\n ? objects\n : [objects];\n }, [objectsKey, objects]);\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n if (!enabled) {\n return makeExternalStore<ObserveLinks.CallbackArgs<T>>(\n () => ({ unsubscribe: () => {} }),\n `links ${linkName} for ${objectsKey} [DISABLED]`,\n );\n }\n return makeExternalStore<ObserveLinks.CallbackArgs<T>>(\n (observer) =>\n observableClient.observeLinks(\n objectsArray,\n linkName,\n {\n linkName,\n where: stableWhere,\n pageSize: otherOptions.pageSize,\n orderBy: stableOrderBy,\n mode: otherOptions.mode,\n dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,\n ...(stableSelect ? { select: stableSelect } : {}),\n },\n observer,\n ),\n `links ${linkName} for ${objectsKey}`,\n );\n },\n [\n enabled,\n observableClient,\n objectsArray,\n objectsKey,\n linkName,\n stableWhere,\n otherOptions.pageSize,\n stableOrderBy,\n otherOptions.mode,\n otherOptions.dedupeIntervalMs,\n stableSelect,\n ],\n );\n\n const payload = React.useSyncExternalStore(\n subscribe,\n getSnapShot,\n );\n\n return React.useMemo(() => ({\n links: payload?.resolvedList,\n linkedObjectsBySourcePrimaryKey: payload?.linkedObjectsBySourcePrimaryKey\n ?? emptyMap,\n isLoading: enabled\n ? (payload?.status === \"loading\" || payload?.status === \"init\"\n || !payload)\n : false,\n isOptimistic: payload?.isOptimistic ?? false,\n error: payload?.error,\n fetchMore: payload?.hasMore ? payload?.fetchMore : undefined,\n hasMore: payload?.hasMore ?? false,\n }), [payload, enabled]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"useLinks.js","names":["React","extractPayloadError","isPayloadLoading","makeExternalStore","OsdkContext2","emptyArray","Object","freeze","emptyMap","Map","useLinks","objects","linkName","options","observableClient","useContext","enabled","otherOptions","canonOptions","canonicalizeOptions","where","orderBy","$select","objectsKey","useMemo","undefined","arr","Array","isArray","map","obj","$apiName","$primaryKey","join","objectsArray","subscribe","getSnapShot","unsubscribe","observer","observeLinks","pageSize","mode","dedupeInterval","dedupeIntervalMs","select","payload","useSyncExternalStore","links","resolvedList","linkedObjectsBySourcePrimaryKey","isLoading","isOptimistic","error","fetchMore","hasMore"],"sources":["useLinks.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 LinkedType,\n LinkNames,\n ObjectOrInterfaceDefinition,\n} from \"@osdk/api\";\nimport type { Osdk, PropertyKeys, WhereClause } from \"@osdk/client\";\nimport type { ObserveLinks } from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { extractPayloadError, isPayloadLoading } from \"./hookUtils.js\";\nimport { makeExternalStore } from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\nexport interface UseLinksOptions<\n T extends ObjectOrInterfaceDefinition,\n> {\n /**\n * Standard OSDK Where clause for filtering linked objects\n */\n where?: WhereClause<T>;\n\n /**\n * The preferred page size for the links list.\n */\n pageSize?: number;\n\n /** Sorting options for the linked objects */\n orderBy?: {\n [K in PropertyKeys<T>]?: \"asc\" | \"desc\";\n };\n\n /**\n * Restrict which properties are returned for each linked object.\n * When provided, only the specified properties will be fetched,\n * reducing payload sizes for list views.\n */\n $select?: readonly PropertyKeys<T>[];\n\n /**\n * The mode to use for fetching data.\n * - undefined: Fetch data if not already in cache\n * - \"force\": Always fetch fresh data\n * - \"offline\": Only use cached data, don't make network requests\n */\n mode?: \"force\" | \"offline\";\n\n /**\n * The number of milliseconds to wait after the last observed link change.\n *\n * Two uses of `useLinks` with the same parameters will only trigger one\n * network request if the second is within `dedupeIntervalMs`.\n */\n dedupeIntervalMs?: number;\n\n /**\n * Enable or disable the query.\n *\n * When `false`, the query will not automatically execute. It will still\n * return any cached data, but will not fetch from the server.\n *\n * This is useful for:\n * - Lazy/on-demand queries that should wait for user interaction\n * - Dependent queries that need data from another query first\n * - Conditional queries based on component state\n *\n * @default true\n * @example\n * // Dependent query - wait for employee data\n * const { object: employee } = useOsdkObject(Employee, employeeId);\n * const { links: reports } = useLinks(employee, \"reports\", {\n * enabled: !!employee\n * });\n */\n enabled?: boolean;\n}\n\nexport interface UseLinksResult<\n Q extends ObjectOrInterfaceDefinition,\n> {\n links: Osdk.Instance<Q>[] | undefined;\n\n /**\n * Maps each source object's primary key to its linked object instances.\n * Useful when observing links from multiple source objects to determine\n * which source links to which targets.\n */\n linkedObjectsBySourcePrimaryKey: ReadonlyMap<\n string | number,\n ReadonlyArray<Osdk.Instance<Q>>\n >;\n\n isLoading: boolean;\n error: Error | undefined;\n\n /**\n * Refers to whether the links are optimistic or not.\n */\n isOptimistic: boolean;\n\n /**\n * Fetch more linked objects if pagination is supported\n */\n fetchMore: (() => Promise<unknown>) | undefined;\n\n /**\n * Indicates if there are more linked objects available to fetch\n */\n hasMore: boolean;\n}\n\nconst emptyArray = Object.freeze([]);\nconst emptyMap: ReadonlyMap<string | number, ReadonlyArray<never>> = new Map();\n\n/**\n * Hook to observe links from an object or array of objects.\n *\n * @param objects The source object(s) to observe links from\n * @param linkName The name of the link to observe\n * @param options Optional configuration for the link query\n * @returns UseLinksResult with links data and metadata\n */\nexport function useLinks<\n T extends ObjectOrInterfaceDefinition,\n L extends LinkNames<T>,\n>(\n objects: Osdk.Instance<T> | Array<Osdk.Instance<T>> | undefined,\n linkName: L,\n options: UseLinksOptions<LinkedType<T, L>> = {},\n): UseLinksResult<LinkedType<T, L>> {\n const { observableClient } = React.useContext(OsdkContext2);\n\n const { enabled = true, ...otherOptions } = options;\n\n const canonOptions = observableClient.canonicalizeOptions({\n where: otherOptions.where,\n orderBy: otherOptions.orderBy,\n $select: otherOptions.$select,\n });\n\n const objectsKey = React.useMemo(() => {\n if (objects === undefined) return \"\";\n const arr = Array.isArray(objects) ? objects : [objects];\n return arr.map(obj => `${obj.$apiName}:${obj.$primaryKey}`).join(\",\");\n }, [objects]);\n\n // Convert single object to array for consistent handling\n const objectsArray: ReadonlyArray<Osdk.Instance<T>> = React.useMemo(() => {\n return objects === undefined\n ? emptyArray\n : Array.isArray(objects)\n ? objects\n : [objects];\n }, [objectsKey, objects]);\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n if (!enabled) {\n return makeExternalStore<ObserveLinks.CallbackArgs<T>>(\n () => ({ unsubscribe: () => {} }),\n `links ${linkName} for ${objectsKey} [DISABLED]`,\n );\n }\n return makeExternalStore<ObserveLinks.CallbackArgs<T>>(\n (observer) =>\n observableClient.observeLinks(\n objectsArray,\n linkName,\n {\n linkName,\n where: canonOptions.where,\n pageSize: otherOptions.pageSize,\n orderBy: canonOptions.orderBy,\n mode: otherOptions.mode,\n dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,\n ...(canonOptions.$select ? { select: canonOptions.$select } : {}),\n },\n observer,\n ),\n `links ${linkName} for ${objectsKey}`,\n );\n },\n [\n enabled,\n observableClient,\n objectsArray,\n objectsKey,\n linkName,\n canonOptions.where,\n otherOptions.pageSize,\n canonOptions.orderBy,\n otherOptions.mode,\n otherOptions.dedupeIntervalMs,\n canonOptions.$select,\n ],\n );\n\n const payload = React.useSyncExternalStore(\n subscribe,\n getSnapShot,\n );\n\n return React.useMemo(() => ({\n links: payload?.resolvedList,\n linkedObjectsBySourcePrimaryKey: payload?.linkedObjectsBySourcePrimaryKey\n ?? emptyMap,\n isLoading: isPayloadLoading(payload, enabled),\n isOptimistic: payload?.isOptimistic ?? false,\n error: extractPayloadError(payload, \"Failed to load links\"),\n fetchMore: payload?.hasMore ? payload?.fetchMore : undefined,\n hasMore: payload?.hasMore ?? false,\n }), [payload, enabled]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { getWireObjectSet } from "@osdk/client/unstable-do-not-use";
|
|
18
18
|
import React from "react";
|
|
19
|
+
import { extractPayloadError } from "./hookUtils.js";
|
|
19
20
|
import { makeExternalStore } from "./makeExternalStore.js";
|
|
20
21
|
import { OsdkContext2 } from "./OsdkContext2.js";
|
|
21
22
|
const OBJECT_TYPE_PLACEHOLDER = "$__OBJECT__TYPE__PLACEHOLDER";
|
|
@@ -35,13 +36,14 @@ export function useObjectSet(baseObjectSet, options = {}) {
|
|
|
35
36
|
observableClient
|
|
36
37
|
} = React.useContext(OsdkContext2);
|
|
37
38
|
const {
|
|
38
|
-
enabled = true,
|
|
39
|
+
enabled: enabledOption = true,
|
|
39
40
|
streamUpdates,
|
|
40
41
|
...otherOptions
|
|
41
42
|
} = options;
|
|
43
|
+
const enabled = enabledOption && baseObjectSet != null;
|
|
42
44
|
|
|
43
45
|
// Track object type to detect when we switch to a different object type
|
|
44
|
-
const objectTypeKey = enabled ? baseObjectSet.$objectSetInternals.def.apiName : OBJECT_TYPE_PLACEHOLDER;
|
|
46
|
+
const objectTypeKey = enabled && baseObjectSet ? baseObjectSet.$objectSetInternals.def.apiName : OBJECT_TYPE_PLACEHOLDER;
|
|
45
47
|
const previousObjectTypeRef = React.useRef(objectTypeKey);
|
|
46
48
|
const previousCompletedPayloadRef = React.useRef();
|
|
47
49
|
const objectTypeChanged = previousObjectTypeRef.current !== objectTypeKey;
|
|
@@ -50,19 +52,22 @@ export function useObjectSet(baseObjectSet, options = {}) {
|
|
|
50
52
|
previousCompletedPayloadRef.current = undefined;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
|
|
55
|
+
// canonicalizeOptions stabilizes complex query identity options.
|
|
56
|
+
// pageSize is a view level concern (handled per subscriber, not part of
|
|
57
|
+
// query identity), and pivotTo is a plain string that does not need
|
|
58
|
+
// stabilization.
|
|
59
|
+
const canonOptions = observableClient.canonicalizeOptions({
|
|
56
60
|
where: otherOptions.where,
|
|
57
61
|
withProperties: otherOptions.withProperties,
|
|
62
|
+
orderBy: otherOptions.orderBy,
|
|
58
63
|
union: otherOptions.union,
|
|
59
64
|
intersect: otherOptions.intersect,
|
|
60
65
|
subtract: otherOptions.subtract,
|
|
61
|
-
|
|
62
|
-
pageSize: otherOptions.pageSize,
|
|
63
|
-
orderBy: otherOptions.orderBy,
|
|
64
|
-
select: otherOptions.$select
|
|
66
|
+
$select: otherOptions.$select
|
|
65
67
|
});
|
|
68
|
+
const objectSetKey = baseObjectSet ? JSON.stringify(getWireObjectSet(baseObjectSet)) : undefined;
|
|
69
|
+
const baseObjectSetRef = React.useRef(baseObjectSet);
|
|
70
|
+
baseObjectSetRef.current = baseObjectSet;
|
|
66
71
|
const {
|
|
67
72
|
subscribe,
|
|
68
73
|
getSnapShot
|
|
@@ -70,42 +75,56 @@ export function useObjectSet(baseObjectSet, options = {}) {
|
|
|
70
75
|
if (!enabled) {
|
|
71
76
|
return makeExternalStore(() => ({
|
|
72
77
|
unsubscribe: () => {}
|
|
73
|
-
}), process.env.NODE_ENV !== "production" ? `objectSet
|
|
78
|
+
}), process.env.NODE_ENV !== "production" ? `objectSet [DISABLED]` : void 0);
|
|
74
79
|
}
|
|
75
80
|
const initialValue = objectTypeChanged ? undefined : previousCompletedPayloadRef.current;
|
|
76
81
|
return makeExternalStore(observer => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (!baseObjectSetRef.current) {
|
|
83
|
+
return {
|
|
84
|
+
unsubscribe: () => {}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const subscription = observableClient.observeObjectSet(baseObjectSetRef.current, {
|
|
88
|
+
where: canonOptions.where,
|
|
89
|
+
withProperties: canonOptions.withProperties,
|
|
90
|
+
union: canonOptions.union,
|
|
91
|
+
intersect: canonOptions.intersect,
|
|
92
|
+
subtract: canonOptions.subtract,
|
|
83
93
|
pivotTo: otherOptions.pivotTo,
|
|
84
94
|
pageSize: otherOptions.pageSize,
|
|
85
|
-
orderBy:
|
|
95
|
+
orderBy: canonOptions.orderBy,
|
|
86
96
|
dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,
|
|
87
97
|
autoFetchMore: otherOptions.autoFetchMore,
|
|
88
98
|
streamUpdates,
|
|
89
|
-
select:
|
|
99
|
+
select: canonOptions.$select
|
|
90
100
|
}, observer);
|
|
91
101
|
return subscription;
|
|
92
|
-
}, process.env.NODE_ENV !== "production" ? `objectSet ${
|
|
93
|
-
}, [enabled, observableClient,
|
|
102
|
+
}, process.env.NODE_ENV !== "production" ? `objectSet ${objectTypeKey}` : void 0, initialValue);
|
|
103
|
+
}, [enabled, observableClient, objectSetKey, canonOptions.where, canonOptions.withProperties, canonOptions.orderBy, canonOptions.union, canonOptions.intersect, canonOptions.subtract, canonOptions.$select, otherOptions.pivotTo, otherOptions.pageSize, otherOptions.autoFetchMore, otherOptions.dedupeIntervalMs, streamUpdates, objectTypeKey]);
|
|
94
104
|
const payload = React.useSyncExternalStore(subscribe, getSnapShot);
|
|
95
105
|
if (payload && isPayloadCompleted(payload)) {
|
|
96
106
|
previousCompletedPayloadRef.current = payload;
|
|
97
107
|
}
|
|
108
|
+
const typeApiName = baseObjectSet?.$objectSetInternals.def.apiName;
|
|
109
|
+
const refetch = React.useCallback(async () => {
|
|
110
|
+
if (typeApiName) {
|
|
111
|
+
await observableClient.invalidateObjectType(typeApiName);
|
|
112
|
+
}
|
|
113
|
+
}, [observableClient, typeApiName]);
|
|
98
114
|
return React.useMemo(() => {
|
|
99
115
|
const lastLoaded = isPayloadCompleted(payload) ? payload : previousCompletedPayloadRef.current;
|
|
100
116
|
return {
|
|
101
117
|
data: lastLoaded?.resolvedList,
|
|
102
|
-
isLoading: !isPayloadCompleted(payload),
|
|
103
|
-
error: lastLoaded
|
|
118
|
+
isLoading: enabled ? !isPayloadCompleted(payload) : false,
|
|
119
|
+
error: extractPayloadError(lastLoaded, "Failed to load object set"),
|
|
120
|
+
isOptimistic: payload?.isOptimistic ?? false,
|
|
104
121
|
fetchMore: payload?.hasMore ? payload.fetchMore : undefined,
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
hasMore: payload?.hasMore ?? false,
|
|
123
|
+
objectSet: lastLoaded?.objectSet,
|
|
124
|
+
totalCount: lastLoaded?.totalCount,
|
|
125
|
+
refetch
|
|
107
126
|
};
|
|
108
|
-
}, [payload,
|
|
127
|
+
}, [payload, refetch, enabled]);
|
|
109
128
|
}
|
|
110
129
|
function isPayloadCompleted(payload) {
|
|
111
130
|
if (payload != null && "error" in payload) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObjectSet.js","names":["computeObjectSetCacheKey","React","makeExternalStore","OsdkContext2","OBJECT_TYPE_PLACEHOLDER","useObjectSet","baseObjectSet","options","observableClient","useContext","enabled","streamUpdates","otherOptions","objectTypeKey","$objectSetInternals","def","apiName","previousObjectTypeRef","useRef","previousCompletedPayloadRef","objectTypeChanged","current","undefined","stableKey","where","withProperties","union","intersect","subtract","pivotTo","pageSize","orderBy","select","$select","subscribe","getSnapShot","useMemo","unsubscribe","process","env","NODE_ENV","initialValue","observer","subscription","observeObjectSet","dedupeInterval","dedupeIntervalMs","autoFetchMore","payload","useSyncExternalStore","isPayloadCompleted","lastLoaded","data","resolvedList","isLoading","error","fetchMore","hasMore","objectSet","totalCount","status"],"sources":["useObjectSet.tsx"],"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 DerivedProperty,\n LinkNames,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n Osdk,\n PropertyKeys,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\n\nimport {\n computeObjectSetCacheKey,\n type ObserveObjectSetArgs,\n} from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { makeExternalStore, type Snapshot } from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\nexport interface UseObjectSetOptions<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * Where clause for filtering\n */\n where?: WhereClause<Q, RDPs>;\n\n /**\n * Derived properties to add to the object set\n */\n withProperties?: { [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]> };\n\n /**\n * Object sets to union with\n */\n union?: ObjectSet<Q>[];\n\n /**\n * Object sets to intersect with\n */\n intersect?: ObjectSet<Q>[];\n\n /**\n * Object sets to subtract from\n */\n subtract?: ObjectSet<Q>[];\n\n /**\n * Link to pivot to (changes the type)\n */\n pivotTo?: LinkNames<Q>;\n\n /**\n * The preferred page size for the list\n */\n pageSize?: number;\n\n /**\n * Sort order for the results\n */\n orderBy?: {\n [K in PropertyKeys<Q>]?: \"asc\" | \"desc\";\n };\n\n /**\n * Minimum time between fetch requests in milliseconds (defaults to 2000ms)\n */\n dedupeIntervalMs?: number;\n\n /**\n * Automatically fetch additional pages on initial load.\n *\n * - `true`: Fetch all available pages automatically\n * - `number`: Fetch pages until at least this many items are loaded\n * - `undefined` (default): Only fetch the first page, user must call fetchMore()\n */\n autoFetchMore?: boolean | number;\n\n /**\n * Enable streaming updates via websocket subscription.\n * When true, the object set will automatically update when matching objects are\n * added, updated, or removed.\n *\n * @default false\n */\n streamUpdates?: boolean;\n\n /**\n * Restrict which properties are returned for each object.\n * When provided, only the specified properties will be fetched,\n * reducing payload sizes for list views.\n */\n $select?: readonly PropertyKeys<Q>[];\n\n /**\n * Enable or disable the query.\n *\n * When `false`, the query will not automatically execute. It will still\n * return any cached data, but will not fetch from the server.\n *\n * This is useful for:\n * - Lazy/on-demand queries that should wait for user interaction\n * - Dependent queries that need data from another query first\n * - Conditional queries based on component state\n *\n * @default true\n * @example\n * // Dependent query - wait for filter selection\n * const { data: filteredObjects } = useObjectSet(MyObject.all(), {\n * where: { status: selectedStatus },\n * enabled: !!selectedStatus\n * });\n */\n enabled?: boolean;\n}\n\nexport interface UseObjectSetResult<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * The fetched data with derived properties\n */\n data:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined;\n\n /**\n * Whether data is currently being loaded\n */\n isLoading: boolean;\n\n /**\n * Any error that occurred during fetching\n */\n error: Error | undefined;\n\n /**\n * Function to fetch more pages (undefined if no more pages)\n */\n fetchMore: (() => Promise<void>) | undefined;\n\n /**\n * The final ObjectSet after all transformations\n */\n objectSet: ObjectSet<Q, RDPs>;\n\n /**\n * The total count of objects matching the query (if available from the API)\n */\n totalCount?: string;\n}\n\ndeclare const process: {\n env: {\n NODE_ENV: \"development\" | \"production\";\n };\n};\n\nconst OBJECT_TYPE_PLACEHOLDER = \"$__OBJECT__TYPE__PLACEHOLDER\";\n/**\n * React hook for observing and interacting with OSDK object sets.\n *\n * @typeParam Q - The object type definition\n * @typeParam BaseRDPs - Derived properties that already exist on the input ObjectSet\n * @typeParam RDPs - New derived properties to be added via options.withProperties\n *\n * @param baseObjectSet - The ObjectSet to observe (may already have derived properties)\n * @param options - Options for filtering, sorting, and adding new derived properties\n * @returns Object set data with both existing and new derived properties\n */\nexport function useObjectSet<\n Q extends ObjectOrInterfaceDefinition,\n BaseRDPs extends Record<string, SimplePropertyDef> = never,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n baseObjectSet: ObjectSet<Q, BaseRDPs>,\n options: UseObjectSetOptions<Q, RDPs> = {},\n): UseObjectSetResult<Q, RDPs> {\n const { observableClient } = React.useContext(OsdkContext2);\n\n const { enabled = true, streamUpdates, ...otherOptions } = options;\n\n // Track object type to detect when we switch to a different object type\n const objectTypeKey = enabled\n ? baseObjectSet.$objectSetInternals.def.apiName\n : OBJECT_TYPE_PLACEHOLDER;\n\n const previousObjectTypeRef = React.useRef<string>(objectTypeKey);\n const previousCompletedPayloadRef = React.useRef<\n Snapshot<ObserveObjectSetArgs<Q, RDPs>> | undefined\n >();\n\n const objectTypeChanged = previousObjectTypeRef.current !== objectTypeKey;\n if (objectTypeChanged) {\n previousObjectTypeRef.current = objectTypeKey;\n previousCompletedPayloadRef.current = undefined;\n }\n\n // Compute a stable cache key for the ObjectSet and options\n // dedupeIntervalMs and enabled are excluded as they don't affect the data\n const stableKey = computeObjectSetCacheKey(baseObjectSet, {\n where: otherOptions.where,\n withProperties: otherOptions.withProperties,\n union: otherOptions.union,\n intersect: otherOptions.intersect,\n subtract: otherOptions.subtract,\n pivotTo: otherOptions.pivotTo,\n pageSize: otherOptions.pageSize,\n orderBy: otherOptions.orderBy,\n select: otherOptions.$select,\n });\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n if (!enabled) {\n return makeExternalStore<ObserveObjectSetArgs<Q, RDPs>>(\n () => ({ unsubscribe: () => {} }),\n process.env.NODE_ENV !== \"production\"\n ? `objectSet ${stableKey} [DISABLED]`\n : void 0,\n );\n }\n\n const initialValue = objectTypeChanged\n ? undefined\n : previousCompletedPayloadRef.current;\n\n return makeExternalStore<ObserveObjectSetArgs<Q, RDPs>>(\n (observer) => {\n const subscription = observableClient.observeObjectSet(\n baseObjectSet as ObjectSet<Q>,\n {\n where: otherOptions.where,\n withProperties: otherOptions.withProperties,\n union: otherOptions.union,\n intersect: otherOptions.intersect,\n subtract: otherOptions.subtract,\n pivotTo: otherOptions.pivotTo,\n pageSize: otherOptions.pageSize,\n orderBy: otherOptions.orderBy,\n dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,\n autoFetchMore: otherOptions.autoFetchMore,\n streamUpdates,\n select: otherOptions.$select,\n },\n observer,\n );\n return subscription;\n },\n process.env.NODE_ENV !== \"production\"\n ? `objectSet ${stableKey}`\n : void 0,\n initialValue,\n );\n },\n [enabled, observableClient, stableKey, streamUpdates, objectTypeChanged],\n );\n\n const payload = React.useSyncExternalStore(subscribe, getSnapShot);\n if (payload && isPayloadCompleted(payload)) {\n previousCompletedPayloadRef.current = payload;\n }\n\n return React.useMemo(() => {\n const lastLoaded = isPayloadCompleted(payload)\n ? payload\n : previousCompletedPayloadRef.current;\n return {\n data: lastLoaded?.resolvedList as Osdk.Instance<\n Q,\n \"$allBaseProperties\",\n PropertyKeys<Q>,\n RDPs\n >[],\n isLoading: !isPayloadCompleted(payload),\n error: lastLoaded && \"error\" in lastLoaded ? lastLoaded.error : undefined,\n fetchMore: payload?.hasMore ? payload.fetchMore : undefined,\n objectSet: payload?.objectSet as ObjectSet<Q, RDPs> || baseObjectSet,\n totalCount: lastLoaded?.totalCount,\n };\n }, [payload, baseObjectSet]);\n}\n\nfunction isPayloadCompleted<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef>,\n>(\n payload: Snapshot<ObserveObjectSetArgs<Q, RDPs>>,\n): boolean {\n if (payload != null && \"error\" in payload) {\n return true;\n }\n\n if (payload?.status == null) {\n return false;\n }\n\n switch (payload.status) {\n case \"loaded\":\n case \"error\":\n return true;\n case \"loading\":\n case \"init\":\n return false;\n default:\n payload.status satisfies never;\n return false;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"useObjectSet.js","names":["getWireObjectSet","React","extractPayloadError","makeExternalStore","OsdkContext2","OBJECT_TYPE_PLACEHOLDER","useObjectSet","baseObjectSet","options","observableClient","useContext","enabled","enabledOption","streamUpdates","otherOptions","objectTypeKey","$objectSetInternals","def","apiName","previousObjectTypeRef","useRef","previousCompletedPayloadRef","objectTypeChanged","current","undefined","canonOptions","canonicalizeOptions","where","withProperties","orderBy","union","intersect","subtract","$select","objectSetKey","JSON","stringify","baseObjectSetRef","subscribe","getSnapShot","useMemo","unsubscribe","process","env","NODE_ENV","initialValue","observer","subscription","observeObjectSet","pivotTo","pageSize","dedupeInterval","dedupeIntervalMs","autoFetchMore","select","payload","useSyncExternalStore","isPayloadCompleted","typeApiName","refetch","useCallback","invalidateObjectType","lastLoaded","data","resolvedList","isLoading","error","isOptimistic","fetchMore","hasMore","objectSet","totalCount","status"],"sources":["useObjectSet.tsx"],"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 DerivedProperty,\n LinkNames,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n Osdk,\n PropertyKeys,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\n\nimport {\n getWireObjectSet,\n type ObserveObjectSetArgs,\n} from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { extractPayloadError } from \"./hookUtils.js\";\nimport { makeExternalStore, type Snapshot } from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\nexport interface UseObjectSetOptions<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * Where clause for filtering\n */\n where?: WhereClause<Q, RDPs>;\n\n /**\n * Derived properties to add to the object set\n */\n withProperties?: { [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]> };\n\n /**\n * Object sets to union with\n */\n union?: ObjectSet<Q>[];\n\n /**\n * Object sets to intersect with\n */\n intersect?: ObjectSet<Q>[];\n\n /**\n * Object sets to subtract from\n */\n subtract?: ObjectSet<Q>[];\n\n /**\n * Link to pivot to (changes the type)\n */\n pivotTo?: LinkNames<Q>;\n\n /**\n * The preferred page size for the list\n */\n pageSize?: number;\n\n /**\n * Sort order for the results\n */\n orderBy?: {\n [K in PropertyKeys<Q>]?: \"asc\" | \"desc\";\n };\n\n /**\n * Minimum time between fetch requests in milliseconds (defaults to 2000ms)\n */\n dedupeIntervalMs?: number;\n\n /**\n * Automatically fetch additional pages on initial load.\n *\n * - `true`: Fetch all available pages automatically\n * - `number`: Fetch pages until at least this many items are loaded\n * - `undefined` (default): Only fetch the first page, user must call fetchMore()\n */\n autoFetchMore?: boolean | number;\n\n /**\n * Enable streaming updates via websocket subscription.\n * When true, the object set will automatically update when matching objects are\n * added, updated, or removed.\n *\n * @default false\n */\n streamUpdates?: boolean;\n\n /**\n * Restrict which properties are returned for each object.\n * When provided, only the specified properties will be fetched,\n * reducing payload sizes for list views.\n */\n $select?: readonly PropertyKeys<Q>[];\n\n /**\n * Enable or disable the query.\n *\n * When `false`, the query will not automatically execute. It will still\n * return any cached data, but will not fetch from the server.\n *\n * This is useful for:\n * - Lazy/on-demand queries that should wait for user interaction\n * - Dependent queries that need data from another query first\n * - Conditional queries based on component state\n *\n * @default true\n * @example\n * // Dependent query - wait for filter selection\n * const { data: filteredObjects } = useObjectSet(MyObject.all(), {\n * where: { status: selectedStatus },\n * enabled: !!selectedStatus\n * });\n */\n enabled?: boolean;\n}\n\nexport interface UseObjectSetResult<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * The fetched data with derived properties\n */\n data:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined;\n\n /**\n * Whether data is currently being loaded\n */\n isLoading: boolean;\n\n /**\n * Any error that occurred during fetching\n */\n error: Error | undefined;\n\n isOptimistic: boolean;\n\n /**\n * Function to fetch more pages (undefined if no more pages)\n */\n fetchMore: (() => Promise<void>) | undefined;\n\n hasMore: boolean;\n\n /**\n * The final ObjectSet after all transformations\n */\n objectSet: ObjectSet<Q, RDPs> | undefined;\n\n /**\n * The total count of objects matching the query (if available from the API)\n */\n totalCount?: string;\n\n refetch: () => Promise<void>;\n}\n\ndeclare const process: {\n env: {\n NODE_ENV: \"development\" | \"production\";\n };\n};\n\nconst OBJECT_TYPE_PLACEHOLDER = \"$__OBJECT__TYPE__PLACEHOLDER\";\n/**\n * React hook for observing and interacting with OSDK object sets.\n *\n * @typeParam Q - The object type definition\n * @typeParam BaseRDPs - Derived properties that already exist on the input ObjectSet\n * @typeParam RDPs - New derived properties to be added via options.withProperties\n *\n * @param baseObjectSet - The ObjectSet to observe (may already have derived properties)\n * @param options - Options for filtering, sorting, and adding new derived properties\n * @returns Object set data with both existing and new derived properties\n */\nexport function useObjectSet<\n Q extends ObjectOrInterfaceDefinition,\n BaseRDPs extends Record<string, SimplePropertyDef> = never,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n baseObjectSet: ObjectSet<Q, BaseRDPs> | undefined,\n options: UseObjectSetOptions<Q, RDPs> = {},\n): UseObjectSetResult<Q, RDPs> {\n const { observableClient } = React.useContext(OsdkContext2);\n\n const { enabled: enabledOption = true, streamUpdates, ...otherOptions } =\n options;\n const enabled = enabledOption && baseObjectSet != null;\n\n // Track object type to detect when we switch to a different object type\n const objectTypeKey = enabled && baseObjectSet\n ? baseObjectSet.$objectSetInternals.def.apiName\n : OBJECT_TYPE_PLACEHOLDER;\n\n const previousObjectTypeRef = React.useRef<string>(objectTypeKey);\n const previousCompletedPayloadRef = React.useRef<\n Snapshot<ObserveObjectSetArgs<Q, RDPs>> | undefined\n >();\n\n const objectTypeChanged = previousObjectTypeRef.current !== objectTypeKey;\n if (objectTypeChanged) {\n previousObjectTypeRef.current = objectTypeKey;\n previousCompletedPayloadRef.current = undefined;\n }\n\n // canonicalizeOptions stabilizes complex query identity options.\n // pageSize is a view level concern (handled per subscriber, not part of\n // query identity), and pivotTo is a plain string that does not need\n // stabilization.\n const canonOptions = observableClient.canonicalizeOptions({\n where: otherOptions.where,\n withProperties: otherOptions.withProperties,\n orderBy: otherOptions.orderBy,\n union: otherOptions.union,\n intersect: otherOptions.intersect,\n subtract: otherOptions.subtract,\n $select: otherOptions.$select,\n });\n\n const objectSetKey = baseObjectSet\n ? JSON.stringify(getWireObjectSet(baseObjectSet as ObjectSet<Q>))\n : undefined;\n\n const baseObjectSetRef = React.useRef(baseObjectSet);\n baseObjectSetRef.current = baseObjectSet;\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n if (!enabled) {\n return makeExternalStore<ObserveObjectSetArgs<Q, RDPs>>(\n () => ({ unsubscribe: () => {} }),\n process.env.NODE_ENV !== \"production\"\n ? `objectSet [DISABLED]`\n : void 0,\n );\n }\n\n const initialValue = objectTypeChanged\n ? undefined\n : previousCompletedPayloadRef.current;\n\n return makeExternalStore<ObserveObjectSetArgs<Q, RDPs>>(\n (observer) => {\n if (!baseObjectSetRef.current) {\n return { unsubscribe: () => {} };\n }\n const subscription = observableClient.observeObjectSet(\n baseObjectSetRef.current as ObjectSet<Q>,\n {\n where: canonOptions.where,\n withProperties: canonOptions.withProperties,\n union: canonOptions.union,\n intersect: canonOptions.intersect,\n subtract: canonOptions.subtract,\n pivotTo: otherOptions.pivotTo,\n pageSize: otherOptions.pageSize,\n orderBy: canonOptions.orderBy,\n dedupeInterval: otherOptions.dedupeIntervalMs ?? 2_000,\n autoFetchMore: otherOptions.autoFetchMore,\n streamUpdates,\n select: canonOptions.$select,\n },\n observer,\n );\n return subscription;\n },\n process.env.NODE_ENV !== \"production\"\n ? `objectSet ${objectTypeKey}`\n : void 0,\n initialValue,\n );\n },\n [\n enabled,\n observableClient,\n objectSetKey,\n canonOptions.where,\n canonOptions.withProperties,\n canonOptions.orderBy,\n canonOptions.union,\n canonOptions.intersect,\n canonOptions.subtract,\n canonOptions.$select,\n otherOptions.pivotTo,\n otherOptions.pageSize,\n otherOptions.autoFetchMore,\n otherOptions.dedupeIntervalMs,\n streamUpdates,\n objectTypeKey,\n ],\n );\n\n const payload = React.useSyncExternalStore(subscribe, getSnapShot);\n if (payload && isPayloadCompleted(payload)) {\n previousCompletedPayloadRef.current = payload;\n }\n\n const typeApiName = baseObjectSet?.$objectSetInternals.def.apiName;\n\n const refetch = React.useCallback(async () => {\n if (typeApiName) {\n await observableClient.invalidateObjectType(typeApiName);\n }\n }, [observableClient, typeApiName]);\n\n return React.useMemo(() => {\n const lastLoaded = isPayloadCompleted(payload)\n ? payload\n : previousCompletedPayloadRef.current;\n return {\n data: lastLoaded?.resolvedList as Osdk.Instance<\n Q,\n \"$allBaseProperties\",\n PropertyKeys<Q>,\n RDPs\n >[],\n isLoading: enabled\n ? !isPayloadCompleted(payload)\n : false,\n error: extractPayloadError(lastLoaded, \"Failed to load object set\"),\n isOptimistic: payload?.isOptimistic ?? false,\n fetchMore: payload?.hasMore ? payload.fetchMore : undefined,\n hasMore: payload?.hasMore ?? false,\n objectSet: lastLoaded?.objectSet as ObjectSet<Q, RDPs> | undefined,\n totalCount: lastLoaded?.totalCount,\n refetch,\n };\n }, [payload, refetch, enabled]);\n}\n\nfunction isPayloadCompleted<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef>,\n>(\n payload: Snapshot<ObserveObjectSetArgs<Q, RDPs>>,\n): boolean {\n if (payload != null && \"error\" in payload) {\n return true;\n }\n\n if (payload?.status == null) {\n return false;\n }\n\n switch (payload.status) {\n case \"loaded\":\n case \"error\":\n return true;\n case \"loading\":\n case \"init\":\n return false;\n default:\n payload.status satisfies never;\n return false;\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA,SACEA,gBAAgB,QAEX,kCAAkC;AACzC,OAAOC,KAAK,MAAM,OAAO;AACzB,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,iBAAiB,QAAuB,wBAAwB;AACzE,SAASC,YAAY,QAAQ,mBAAmB;AAqJhD,MAAMC,uBAAuB,GAAG,8BAA8B;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAK1BC,aAAiD,EACjDC,OAAqC,GAAG,CAAC,CAAC,EACb;EAC7B,MAAM;IAAEC;EAAiB,CAAC,GAAGR,KAAK,CAACS,UAAU,CAACN,YAAY,CAAC;EAE3D,MAAM;IAAEO,OAAO,EAAEC,aAAa,GAAG,IAAI;IAAEC,aAAa;IAAE,GAAGC;EAAa,CAAC,GACrEN,OAAO;EACT,MAAMG,OAAO,GAAGC,aAAa,IAAIL,aAAa,IAAI,IAAI;;EAEtD;EACA,MAAMQ,aAAa,GAAGJ,OAAO,IAAIJ,aAAa,GAC1CA,aAAa,CAACS,mBAAmB,CAACC,GAAG,CAACC,OAAO,GAC7Cb,uBAAuB;EAE3B,MAAMc,qBAAqB,GAAGlB,KAAK,CAACmB,MAAM,CAASL,aAAa,CAAC;EACjE,MAAMM,2BAA2B,GAAGpB,KAAK,CAACmB,MAAM,CAE9C,CAAC;EAEH,MAAME,iBAAiB,GAAGH,qBAAqB,CAACI,OAAO,KAAKR,aAAa;EACzE,IAAIO,iBAAiB,EAAE;IACrBH,qBAAqB,CAACI,OAAO,GAAGR,aAAa;IAC7CM,2BAA2B,CAACE,OAAO,GAAGC,SAAS;EACjD;;EAEA;EACA;EACA;EACA;EACA,MAAMC,YAAY,GAAGhB,gBAAgB,CAACiB,mBAAmB,CAAC;IACxDC,KAAK,EAAEb,YAAY,CAACa,KAAK;IACzBC,cAAc,EAAEd,YAAY,CAACc,cAAc;IAC3CC,OAAO,EAAEf,YAAY,CAACe,OAAO;IAC7BC,KAAK,EAAEhB,YAAY,CAACgB,KAAK;IACzBC,SAAS,EAAEjB,YAAY,CAACiB,SAAS;IACjCC,QAAQ,EAAElB,YAAY,CAACkB,QAAQ;IAC/BC,OAAO,EAAEnB,YAAY,CAACmB;EACxB,CAAC,CAAC;EAEF,MAAMC,YAAY,GAAG3B,aAAa,GAC9B4B,IAAI,CAACC,SAAS,CAACpC,gBAAgB,CAACO,aAA6B,CAAC,CAAC,GAC/DiB,SAAS;EAEb,MAAMa,gBAAgB,GAAGpC,KAAK,CAACmB,MAAM,CAACb,aAAa,CAAC;EACpD8B,gBAAgB,CAACd,OAAO,GAAGhB,aAAa;EAExC,MAAM;IAAE+B,SAAS;IAAEC;EAAY,CAAC,GAAGtC,KAAK,CAACuC,OAAO,CAC9C,MAAM;IACJ,IAAI,CAAC7B,OAAO,EAAE;MACZ,OAAOR,iBAAiB,CACtB,OAAO;QAAEsC,WAAW,EAAEA,CAAA,KAAM,CAAC;MAAE,CAAC,CAAC,EACjCC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GACjC,sBAAsB,GACtB,KAAK,CACX,CAAC;IACH;IAEA,MAAMC,YAAY,GAAGvB,iBAAiB,GAClCE,SAAS,GACTH,2BAA2B,CAACE,OAAO;IAEvC,OAAOpB,iBAAiB,CACrB2C,QAAQ,IAAK;MACZ,IAAI,CAACT,gBAAgB,CAACd,OAAO,EAAE;QAC7B,OAAO;UAAEkB,WAAW,EAAEA,CAAA,KAAM,CAAC;QAAE,CAAC;MAClC;MACA,MAAMM,YAAY,GAAGtC,gBAAgB,CAACuC,gBAAgB,CACpDX,gBAAgB,CAACd,OAAO,EACxB;QACEI,KAAK,EAAEF,YAAY,CAACE,KAAK;QACzBC,cAAc,EAAEH,YAAY,CAACG,cAAc;QAC3CE,KAAK,EAAEL,YAAY,CAACK,KAAK;QACzBC,SAAS,EAAEN,YAAY,CAACM,SAAS;QACjCC,QAAQ,EAAEP,YAAY,CAACO,QAAQ;QAC/BiB,OAAO,EAAEnC,YAAY,CAACmC,OAAO;QAC7BC,QAAQ,EAAEpC,YAAY,CAACoC,QAAQ;QAC/BrB,OAAO,EAAEJ,YAAY,CAACI,OAAO;QAC7BsB,cAAc,EAAErC,YAAY,CAACsC,gBAAgB,IAAI,KAAK;QACtDC,aAAa,EAAEvC,YAAY,CAACuC,aAAa;QACzCxC,aAAa;QACbyC,MAAM,EAAE7B,YAAY,CAACQ;MACvB,CAAC,EACDa,QACF,CAAC;MACD,OAAOC,YAAY;IACrB,CAAC,EACDL,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GACjC,aAAa7B,aAAa,EAAE,GAC5B,KAAK,CAAC,EACV8B,YACF,CAAC;EACH,CAAC,EACD,CACElC,OAAO,EACPF,gBAAgB,EAChByB,YAAY,EACZT,YAAY,CAACE,KAAK,EAClBF,YAAY,CAACG,cAAc,EAC3BH,YAAY,CAACI,OAAO,EACpBJ,YAAY,CAACK,KAAK,EAClBL,YAAY,CAACM,SAAS,EACtBN,YAAY,CAACO,QAAQ,EACrBP,YAAY,CAACQ,OAAO,EACpBnB,YAAY,CAACmC,OAAO,EACpBnC,YAAY,CAACoC,QAAQ,EACrBpC,YAAY,CAACuC,aAAa,EAC1BvC,YAAY,CAACsC,gBAAgB,EAC7BvC,aAAa,EACbE,aAAa,CAEjB,CAAC;EAED,MAAMwC,OAAO,GAAGtD,KAAK,CAACuD,oBAAoB,CAAClB,SAAS,EAAEC,WAAW,CAAC;EAClE,IAAIgB,OAAO,IAAIE,kBAAkB,CAACF,OAAO,CAAC,EAAE;IAC1ClC,2BAA2B,CAACE,OAAO,GAAGgC,OAAO;EAC/C;EAEA,MAAMG,WAAW,GAAGnD,aAAa,EAAES,mBAAmB,CAACC,GAAG,CAACC,OAAO;EAElE,MAAMyC,OAAO,GAAG1D,KAAK,CAAC2D,WAAW,CAAC,YAAY;IAC5C,IAAIF,WAAW,EAAE;MACf,MAAMjD,gBAAgB,CAACoD,oBAAoB,CAACH,WAAW,CAAC;IAC1D;EACF,CAAC,EAAE,CAACjD,gBAAgB,EAAEiD,WAAW,CAAC,CAAC;EAEnC,OAAOzD,KAAK,CAACuC,OAAO,CAAC,MAAM;IACzB,MAAMsB,UAAU,GAAGL,kBAAkB,CAACF,OAAO,CAAC,GAC1CA,OAAO,GACPlC,2BAA2B,CAACE,OAAO;IACvC,OAAO;MACLwC,IAAI,EAAED,UAAU,EAAEE,YAKf;MACHC,SAAS,EAAEtD,OAAO,GACd,CAAC8C,kBAAkB,CAACF,OAAO,CAAC,GAC5B,KAAK;MACTW,KAAK,EAAEhE,mBAAmB,CAAC4D,UAAU,EAAE,2BAA2B,CAAC;MACnEK,YAAY,EAAEZ,OAAO,EAAEY,YAAY,IAAI,KAAK;MAC5CC,SAAS,EAAEb,OAAO,EAAEc,OAAO,GAAGd,OAAO,CAACa,SAAS,GAAG5C,SAAS;MAC3D6C,OAAO,EAAEd,OAAO,EAAEc,OAAO,IAAI,KAAK;MAClCC,SAAS,EAAER,UAAU,EAAEQ,SAA2C;MAClEC,UAAU,EAAET,UAAU,EAAES,UAAU;MAClCZ;IACF,CAAC;EACH,CAAC,EAAE,CAACJ,OAAO,EAAEI,OAAO,EAAEhD,OAAO,CAAC,CAAC;AACjC;AAEA,SAAS8C,kBAAkBA,CAIzBF,OAAgD,EACvC;EACT,IAAIA,OAAO,IAAI,IAAI,IAAI,OAAO,IAAIA,OAAO,EAAE;IACzC,OAAO,IAAI;EACb;EAEA,IAAIA,OAAO,EAAEiB,MAAM,IAAI,IAAI,EAAE;IAC3B,OAAO,KAAK;EACd;EAEA,QAAQjB,OAAO,CAACiB,MAAM;IACpB,KAAK,QAAQ;IACb,KAAK,OAAO;MACV,OAAO,IAAI;IACb,KAAK,SAAS;IACd,KAAK,MAAM;MACT,OAAO,KAAK;IACd;MACEjB,OAAO,CAACiB,MAAM;MACd,OAAO,KAAK;EAChB;AACF","ignoreList":[]}
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { getWireObjectSet } from "@osdk/client/unstable-do-not-use";
|
|
18
18
|
import React from "react";
|
|
19
|
+
import { extractPayloadError, isPayloadLoading } from "./hookUtils.js";
|
|
19
20
|
import { makeExternalStore, makeExternalStoreAsync } from "./makeExternalStore.js";
|
|
20
21
|
import { OsdkContext2 } from "./OsdkContext2.js";
|
|
21
|
-
const EMPTY_WHERE = {};
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* React hook for performing aggregations on OSDK object sets.
|
|
@@ -55,7 +55,7 @@ const EMPTY_WHERE = {};
|
|
|
55
55
|
|
|
56
56
|
export function useOsdkAggregation(type, options) {
|
|
57
57
|
const {
|
|
58
|
-
where
|
|
58
|
+
where,
|
|
59
59
|
withProperties,
|
|
60
60
|
intersectWith,
|
|
61
61
|
aggregate,
|
|
@@ -65,57 +65,51 @@ export function useOsdkAggregation(type, options) {
|
|
|
65
65
|
const {
|
|
66
66
|
observableClient
|
|
67
67
|
} = React.useContext(OsdkContext2);
|
|
68
|
-
const
|
|
69
|
-
|
|
68
|
+
const canonOptions = observableClient.canonicalizeOptions({
|
|
69
|
+
where,
|
|
70
|
+
withProperties,
|
|
71
|
+
aggregate,
|
|
72
|
+
intersectWith
|
|
73
|
+
});
|
|
74
|
+
const objectSetKey = objectSet ? JSON.stringify(getWireObjectSet(objectSet)) : undefined;
|
|
70
75
|
const objectSetRef = React.useRef(objectSet);
|
|
71
76
|
objectSetRef.current = objectSet;
|
|
72
|
-
const objectSetKeyString = objectSet ? computeObjectSetCacheKey(objectSet) : undefined;
|
|
73
|
-
const stableWithProperties = React.useMemo(() => withProperties, [JSON.stringify(withProperties)]);
|
|
74
|
-
const stableAggregate = React.useMemo(() => aggregate, [JSON.stringify(aggregate)]);
|
|
75
|
-
const stableIntersectWith = React.useMemo(() => intersectWith, [JSON.stringify(intersectWith)]);
|
|
76
77
|
const {
|
|
77
78
|
subscribe,
|
|
78
79
|
getSnapShot
|
|
79
80
|
} = React.useMemo(() => {
|
|
80
|
-
|
|
81
|
+
const currentObjectSet = objectSetRef.current;
|
|
82
|
+
if (currentObjectSet) {
|
|
81
83
|
return makeExternalStoreAsync(observer => observableClient.observeAggregation({
|
|
82
|
-
type
|
|
83
|
-
objectSet:
|
|
84
|
-
where:
|
|
85
|
-
withProperties:
|
|
86
|
-
intersectWith:
|
|
87
|
-
aggregate:
|
|
84
|
+
type,
|
|
85
|
+
objectSet: currentObjectSet,
|
|
86
|
+
where: canonOptions.where,
|
|
87
|
+
withProperties: canonOptions.withProperties,
|
|
88
|
+
intersectWith: canonOptions.intersectWith,
|
|
89
|
+
aggregate: canonOptions.aggregate,
|
|
88
90
|
dedupeInterval: dedupeIntervalMs ?? 2_000
|
|
89
|
-
}, observer), process.env.NODE_ENV !== "production" ? `aggregation ${type.apiName} ${
|
|
91
|
+
}, observer), process.env.NODE_ENV !== "production" ? `aggregation ${type.apiName} ${JSON.stringify(canonOptions.where)}` : void 0);
|
|
90
92
|
}
|
|
91
93
|
return makeExternalStore(observer =>
|
|
92
94
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
93
95
|
observableClient.observeAggregation({
|
|
94
|
-
type
|
|
95
|
-
where:
|
|
96
|
-
withProperties:
|
|
97
|
-
intersectWith:
|
|
98
|
-
aggregate:
|
|
96
|
+
type,
|
|
97
|
+
where: canonOptions.where,
|
|
98
|
+
withProperties: canonOptions.withProperties,
|
|
99
|
+
intersectWith: canonOptions.intersectWith,
|
|
100
|
+
aggregate: canonOptions.aggregate,
|
|
99
101
|
dedupeInterval: dedupeIntervalMs ?? 2_000
|
|
100
|
-
}, observer), process.env.NODE_ENV !== "production" ? `aggregation ${type.apiName} ${JSON.stringify(
|
|
101
|
-
}, [observableClient, type.apiName, type.type,
|
|
102
|
+
}, observer), process.env.NODE_ENV !== "production" ? `aggregation ${type.apiName} ${JSON.stringify(canonOptions.where)}` : void 0);
|
|
103
|
+
}, [observableClient, type.apiName, type.type, objectSetKey, canonOptions.where, canonOptions.withProperties, canonOptions.intersectWith, canonOptions.aggregate, dedupeIntervalMs]);
|
|
102
104
|
const payload = React.useSyncExternalStore(subscribe, getSnapShot);
|
|
103
105
|
const refetch = React.useCallback(async () => {
|
|
104
106
|
await observableClient.invalidateObjectType(type.apiName);
|
|
105
107
|
}, [observableClient, type.apiName]);
|
|
106
|
-
return React.useMemo(() => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
data: payload?.result,
|
|
115
|
-
isLoading: payload?.status === "loading" || payload?.status === "init" || !payload,
|
|
116
|
-
error,
|
|
117
|
-
refetch
|
|
118
|
-
};
|
|
119
|
-
}, [payload, refetch]);
|
|
108
|
+
return React.useMemo(() => ({
|
|
109
|
+
data: payload?.result,
|
|
110
|
+
isLoading: isPayloadLoading(payload, true),
|
|
111
|
+
error: extractPayloadError(payload, "Failed to execute aggregation"),
|
|
112
|
+
refetch
|
|
113
|
+
}), [payload, refetch]);
|
|
120
114
|
}
|
|
121
115
|
//# sourceMappingURL=useOsdkAggregation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOsdkAggregation.js","names":["computeObjectSetCacheKey","React","makeExternalStore","makeExternalStoreAsync","OsdkContext2","EMPTY_WHERE","useOsdkAggregation","type","options","where","withProperties","intersectWith","aggregate","dedupeIntervalMs","objectSet","undefined","observableClient","useContext","canonWhere","canonicalizeWhereClause","stableCanonWhere","useMemo","JSON","stringify","objectSetRef","useRef","current","objectSetKeyString","stableWithProperties","stableAggregate","stableIntersectWith","subscribe","getSnapShot","observer","observeAggregation","dedupeInterval","process","env","NODE_ENV","apiName","payload","useSyncExternalStore","refetch","useCallback","invalidateObjectType","error","status","Error","data","result","isLoading"],"sources":["useOsdkAggregation.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 AggregateOpts,\n AggregationsResults,\n DerivedProperty,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\nimport type { ObjectTypeDefinition } from \"@osdk/client\";\nimport type { ObserveAggregationArgs } from \"@osdk/client/unstable-do-not-use\";\nimport { computeObjectSetCacheKey } from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport {\n makeExternalStore,\n makeExternalStoreAsync,\n} from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\ninterface UseOsdkAggregationBaseOptions<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * Standard OSDK Where clause to filter objects before aggregation\n */\n where?: WhereClause<T, RDPs>;\n\n /**\n * Define derived properties (RDPs) to be computed server-side.\n * The derived properties can be used in the where clause and aggregation groupBy/select.\n */\n withProperties?: { [K in keyof RDPs]: DerivedProperty.Creator<T, RDPs[K]> };\n\n /**\n * Intersect the main query with additional filtered object sets.\n * Each entry creates a separate object set with its own where clause,\n * and the final result is the intersection of all sets.\n */\n intersectWith?: Array<{\n where: WhereClause<T, RDPs>;\n }>;\n\n /**\n * Aggregation options including groupBy and select\n */\n aggregate: A;\n\n /**\n * The number of milliseconds to wait after the last observed aggregation change.\n *\n * Two uses of `useOsdkAggregation` with the same parameters will only trigger one\n * network request if the second is within `dedupeIntervalMs`.\n */\n dedupeIntervalMs?: number;\n}\n\nexport interface UseOsdkAggregationOptions<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> extends UseOsdkAggregationBaseOptions<T, A, RDPs> {}\n\nexport interface UseOsdkAggregationOptionsWithObjectSet<\n T extends ObjectTypeDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> extends UseOsdkAggregationBaseOptions<T, A, RDPs> {\n /**\n * The ObjectSet to aggregate on. Enables aggregation on pivoted, filtered, or composed ObjectSets.\n */\n objectSet: ObjectSet<T>;\n}\n\nconst EMPTY_WHERE = {};\n\nexport interface UseOsdkAggregationResult<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n> {\n data: AggregationsResults<T, A> | undefined;\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => void;\n}\n\ndeclare const process: {\n env: {\n NODE_ENV: \"development\" | \"production\";\n };\n};\n\n/**\n * React hook for performing aggregations on OSDK object sets.\n *\n * Executes server-side aggregations with groupBy and metric calculations on filtered object sets.\n * Supports runtime derived properties and where clauses.\n *\n * @param type - The object or interface type to aggregate\n * @param options - Aggregation configuration including where clause, aggregation spec, and optional derived properties\n * @returns Object containing aggregation results, loading state, error state, and refetch function\n *\n * @example\n * ```tsx\n * // Basic aggregation without ObjectSet\n * const { data, isLoading, error } = useOsdkAggregation(Employee, {\n * where: { department: \"Engineering\" },\n * aggregate: {\n * groupBy: { department: \"exact\" },\n * select: {\n * avgSalary: { $avg: \"salary\" },\n * count: { $count: {} }\n * }\n * }\n * });\n *\n * // With a pivoted ObjectSet\n * const pivotedSet = useMemo(() => $(Employee).pivotTo(\"primaryOffice\"), []);\n * const { data } = useOsdkAggregation(Office, {\n * objectSet: pivotedSet,\n * aggregate: { $select: { $count: \"unordered\" } }\n * });\n * ```\n */\nexport function useOsdkAggregation<\n Q extends ObjectOrInterfaceDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options: UseOsdkAggregationOptions<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A>;\nexport function useOsdkAggregation<\n Q extends ObjectTypeDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options: UseOsdkAggregationOptionsWithObjectSet<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A>;\nexport function useOsdkAggregation<\n Q extends ObjectTypeDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options:\n | UseOsdkAggregationOptions<Q, A, RDPs>\n | UseOsdkAggregationOptionsWithObjectSet<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A> {\n const {\n where = EMPTY_WHERE,\n withProperties,\n intersectWith,\n aggregate,\n dedupeIntervalMs,\n } = options;\n const objectSet = \"objectSet\" in options ? options.objectSet : undefined;\n\n const { observableClient } = React.useContext(OsdkContext2);\n\n const canonWhere = observableClient.canonicalizeWhereClause<Q>(where);\n\n const stableCanonWhere = React.useMemo(\n () => canonWhere,\n [JSON.stringify(canonWhere)],\n );\n\n const objectSetRef = React.useRef(objectSet);\n objectSetRef.current = objectSet;\n\n const objectSetKeyString = objectSet\n ? computeObjectSetCacheKey(objectSet)\n : undefined;\n\n const stableWithProperties = React.useMemo(\n () => withProperties,\n [JSON.stringify(withProperties)],\n );\n\n const stableAggregate = React.useMemo(\n () => aggregate,\n [JSON.stringify(aggregate)],\n );\n\n const stableIntersectWith = React.useMemo(\n () => intersectWith,\n [JSON.stringify(intersectWith)],\n );\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n if (objectSetKeyString && objectSetRef.current) {\n return makeExternalStoreAsync<ObserveAggregationArgs<Q, A>>(\n (observer) =>\n observableClient.observeAggregation(\n {\n type: type,\n objectSet: objectSetRef.current!,\n where: stableCanonWhere,\n withProperties: stableWithProperties,\n intersectWith: stableIntersectWith,\n aggregate: stableAggregate,\n dedupeInterval: dedupeIntervalMs ?? 2_000,\n },\n observer,\n ),\n process.env.NODE_ENV !== \"production\"\n ? `aggregation ${type.apiName} ${objectSetKeyString} ${\n JSON.stringify(stableCanonWhere)\n }`\n : void 0,\n );\n }\n return makeExternalStore<ObserveAggregationArgs<Q, A>>(\n (observer) =>\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n observableClient.observeAggregation(\n {\n type: type,\n where: stableCanonWhere,\n withProperties: stableWithProperties,\n intersectWith: stableIntersectWith,\n aggregate: stableAggregate,\n dedupeInterval: dedupeIntervalMs ?? 2_000,\n },\n observer,\n ),\n process.env.NODE_ENV !== \"production\"\n ? `aggregation ${type.apiName} ${JSON.stringify(stableCanonWhere)}`\n : void 0,\n );\n },\n [\n observableClient,\n type.apiName,\n type.type,\n objectSetKeyString,\n stableCanonWhere,\n stableWithProperties,\n stableIntersectWith,\n stableAggregate,\n dedupeIntervalMs,\n ],\n );\n\n const payload = React.useSyncExternalStore(subscribe, getSnapShot);\n\n const refetch = React.useCallback(async () => {\n await observableClient.invalidateObjectType(type.apiName);\n }, [observableClient, type.apiName]);\n\n return React.useMemo(() => {\n let error: Error | undefined;\n if (payload && \"error\" in payload && payload.error) {\n error = payload.error;\n } else if (payload?.status === \"error\") {\n error = new Error(\"Failed to execute aggregation\");\n }\n\n return {\n data: payload?.result as AggregationsResults<Q, A> | undefined,\n isLoading: payload?.status === \"loading\" || payload?.status === \"init\"\n || !payload,\n error,\n refetch,\n };\n }, [payload, refetch]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"useOsdkAggregation.js","names":["getWireObjectSet","React","extractPayloadError","isPayloadLoading","makeExternalStore","makeExternalStoreAsync","OsdkContext2","useOsdkAggregation","type","options","where","withProperties","intersectWith","aggregate","dedupeIntervalMs","objectSet","undefined","observableClient","useContext","canonOptions","canonicalizeOptions","objectSetKey","JSON","stringify","objectSetRef","useRef","current","subscribe","getSnapShot","useMemo","currentObjectSet","observer","observeAggregation","dedupeInterval","process","env","NODE_ENV","apiName","payload","useSyncExternalStore","refetch","useCallback","invalidateObjectType","data","result","isLoading","error"],"sources":["useOsdkAggregation.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 AggregateOpts,\n AggregationsResults,\n DerivedProperty,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\nimport type { ObjectTypeDefinition } from \"@osdk/client\";\nimport {\n getWireObjectSet,\n type ObserveAggregationArgs,\n} from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { extractPayloadError, isPayloadLoading } from \"./hookUtils.js\";\nimport {\n makeExternalStore,\n makeExternalStoreAsync,\n} from \"./makeExternalStore.js\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\ninterface UseOsdkAggregationBaseOptions<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> {\n /**\n * Standard OSDK Where clause to filter objects before aggregation\n */\n where?: WhereClause<T, RDPs>;\n\n /**\n * Define derived properties (RDPs) to be computed server-side.\n * The derived properties can be used in the where clause and aggregation groupBy/select.\n */\n withProperties?: { [K in keyof RDPs]: DerivedProperty.Creator<T, RDPs[K]> };\n\n /**\n * Intersect the main query with additional filtered object sets.\n * Each entry creates a separate object set with its own where clause,\n * and the final result is the intersection of all sets.\n */\n intersectWith?: Array<{\n where: WhereClause<T, RDPs>;\n }>;\n\n /**\n * Aggregation options including groupBy and select\n */\n aggregate: A;\n\n /**\n * The number of milliseconds to wait after the last observed aggregation change.\n *\n * Two uses of `useOsdkAggregation` with the same parameters will only trigger one\n * network request if the second is within `dedupeIntervalMs`.\n */\n dedupeIntervalMs?: number;\n}\n\nexport interface UseOsdkAggregationOptions<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> extends UseOsdkAggregationBaseOptions<T, A, RDPs> {}\n\nexport interface UseOsdkAggregationOptionsWithObjectSet<\n T extends ObjectTypeDefinition,\n A extends AggregateOpts<T>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n> extends UseOsdkAggregationBaseOptions<T, A, RDPs> {\n /**\n * The ObjectSet to aggregate on. Enables aggregation on pivoted, filtered, or composed ObjectSets.\n */\n objectSet: ObjectSet<T>;\n}\n\nexport interface UseOsdkAggregationResult<\n T extends ObjectOrInterfaceDefinition,\n A extends AggregateOpts<T>,\n> {\n data: AggregationsResults<T, A> | undefined;\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ndeclare const process: {\n env: {\n NODE_ENV: \"development\" | \"production\";\n };\n};\n\n/**\n * React hook for performing aggregations on OSDK object sets.\n *\n * Executes server-side aggregations with groupBy and metric calculations on filtered object sets.\n * Supports runtime derived properties and where clauses.\n *\n * @param type - The object or interface type to aggregate\n * @param options - Aggregation configuration including where clause, aggregation spec, and optional derived properties\n * @returns Object containing aggregation results, loading state, error state, and refetch function\n *\n * @example\n * ```tsx\n * // Basic aggregation without ObjectSet\n * const { data, isLoading, error } = useOsdkAggregation(Employee, {\n * where: { department: \"Engineering\" },\n * aggregate: {\n * groupBy: { department: \"exact\" },\n * select: {\n * avgSalary: { $avg: \"salary\" },\n * count: { $count: {} }\n * }\n * }\n * });\n *\n * // With a pivoted ObjectSet\n * const pivotedSet = useMemo(() => $(Employee).pivotTo(\"primaryOffice\"), []);\n * const { data } = useOsdkAggregation(Office, {\n * objectSet: pivotedSet,\n * aggregate: { $select: { $count: \"unordered\" } }\n * });\n * ```\n */\nexport function useOsdkAggregation<\n Q extends ObjectOrInterfaceDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options: UseOsdkAggregationOptions<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A>;\nexport function useOsdkAggregation<\n Q extends ObjectTypeDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options: UseOsdkAggregationOptionsWithObjectSet<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A>;\nexport function useOsdkAggregation<\n Q extends ObjectTypeDefinition,\n const A extends AggregateOpts<Q>,\n RDPs extends Record<string, SimplePropertyDef> = {},\n>(\n type: Q,\n options:\n | UseOsdkAggregationOptions<Q, A, RDPs>\n | UseOsdkAggregationOptionsWithObjectSet<Q, A, RDPs>,\n): UseOsdkAggregationResult<Q, A> {\n const {\n where,\n withProperties,\n intersectWith,\n aggregate,\n dedupeIntervalMs,\n } = options;\n const objectSet = \"objectSet\" in options ? options.objectSet : undefined;\n\n const { observableClient } = React.useContext(OsdkContext2);\n\n const canonOptions = observableClient.canonicalizeOptions({\n where,\n withProperties,\n aggregate,\n intersectWith,\n });\n\n const objectSetKey = objectSet\n ? JSON.stringify(getWireObjectSet(objectSet as ObjectSet<Q>))\n : undefined;\n\n const objectSetRef = React.useRef(objectSet);\n objectSetRef.current = objectSet;\n\n const { subscribe, getSnapShot } = React.useMemo(\n () => {\n const currentObjectSet = objectSetRef.current;\n if (currentObjectSet) {\n return makeExternalStoreAsync<ObserveAggregationArgs<Q, A>>(\n (observer) =>\n observableClient.observeAggregation(\n {\n type,\n objectSet: currentObjectSet,\n where: canonOptions.where,\n withProperties: canonOptions.withProperties,\n intersectWith: canonOptions.intersectWith,\n aggregate: canonOptions.aggregate,\n dedupeInterval: dedupeIntervalMs ?? 2_000,\n },\n observer,\n ),\n process.env.NODE_ENV !== \"production\"\n ? `aggregation ${type.apiName} ${\n JSON.stringify(canonOptions.where)\n }`\n : void 0,\n );\n }\n return makeExternalStore<ObserveAggregationArgs<Q, A>>(\n (observer) =>\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n observableClient.observeAggregation(\n {\n type,\n where: canonOptions.where,\n withProperties: canonOptions.withProperties,\n intersectWith: canonOptions.intersectWith,\n aggregate: canonOptions.aggregate,\n dedupeInterval: dedupeIntervalMs ?? 2_000,\n },\n observer,\n ),\n process.env.NODE_ENV !== \"production\"\n ? `aggregation ${type.apiName} ${JSON.stringify(canonOptions.where)}`\n : void 0,\n );\n },\n [\n observableClient,\n type.apiName,\n type.type,\n objectSetKey,\n canonOptions.where,\n canonOptions.withProperties,\n canonOptions.intersectWith,\n canonOptions.aggregate,\n dedupeIntervalMs,\n ],\n );\n\n const payload = React.useSyncExternalStore(subscribe, getSnapShot);\n\n const refetch = React.useCallback(async () => {\n await observableClient.invalidateObjectType(type.apiName);\n }, [observableClient, type.apiName]);\n\n return React.useMemo(() => ({\n data: payload?.result as AggregationsResults<Q, A> | undefined,\n isLoading: isPayloadLoading(payload, true),\n error: extractPayloadError(payload, \"Failed to execute aggregation\"),\n refetch,\n }), [payload, refetch]);\n}\n"],"mappings":"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","ignoreList":[]}
|