@osdk/react 0.10.0-beta.12 → 0.10.0-beta.14
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 +29 -0
- package/build/browser/new/OsdkContext2.js +22 -2
- package/build/browser/new/OsdkContext2.js.map +1 -1
- package/build/browser/new/useOsdkAction.js +2 -6
- package/build/browser/new/useOsdkAction.js.map +1 -1
- package/build/browser/new/useOsdkFunctions.js +137 -0
- package/build/browser/new/useOsdkFunctions.js.map +1 -0
- package/build/browser/public/unstable-do-not-use.js +18 -0
- package/build/browser/public/unstable-do-not-use.js.map +1 -0
- package/build/cjs/chunk-2N32USW5.cjs +28 -0
- package/build/cjs/chunk-2N32USW5.cjs.map +1 -0
- package/build/cjs/chunk-R4FZ5MUH.cjs +34 -0
- package/build/cjs/chunk-R4FZ5MUH.cjs.map +1 -0
- package/build/cjs/{chunk-SVVMLSKN.cjs → chunk-ZUNR45SJ.cjs} +15 -4
- package/build/cjs/chunk-ZUNR45SJ.cjs.map +1 -0
- package/build/cjs/index.cjs +7 -6
- package/build/cjs/index.cjs.map +1 -1
- package/build/cjs/public/experimental/admin.cjs +11 -11
- package/build/cjs/public/experimental.cjs +30 -33
- package/build/cjs/public/experimental.cjs.map +1 -1
- package/build/cjs/public/experimental.d.cts +4 -120
- package/build/cjs/public/unstable-do-not-use.cjs +114 -0
- package/build/cjs/public/unstable-do-not-use.cjs.map +1 -0
- package/build/cjs/public/unstable-do-not-use.d.cts +35 -0
- package/build/cjs/useOsdkFunction-B0s7lqgN.d.cts +121 -0
- package/build/esm/new/OsdkContext2.js +22 -2
- package/build/esm/new/OsdkContext2.js.map +1 -1
- package/build/esm/new/useOsdkAction.js +2 -6
- package/build/esm/new/useOsdkAction.js.map +1 -1
- package/build/esm/new/useOsdkFunctions.js +137 -0
- package/build/esm/new/useOsdkFunctions.js.map +1 -0
- package/build/esm/public/unstable-do-not-use.js +18 -0
- package/build/esm/public/unstable-do-not-use.js.map +1 -0
- package/build/types/new/OsdkContext2.d.ts +1 -0
- package/build/types/new/OsdkContext2.d.ts.map +1 -1
- package/build/types/new/useOsdkFunctions.d.ts +31 -0
- package/build/types/new/useOsdkFunctions.d.ts.map +1 -0
- package/build/types/public/unstable-do-not-use.d.ts +2 -0
- package/build/types/public/unstable-do-not-use.d.ts.map +1 -0
- package/package.json +14 -5
- package/unstable-do-not-use.d.ts +17 -0
- package/build/cjs/chunk-OVBG5VXE.cjs +0 -50
- package/build/cjs/chunk-OVBG5VXE.cjs.map +0 -1
- package/build/cjs/chunk-SVVMLSKN.cjs.map +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk2N32USW5_cjs = require('../chunk-2N32USW5.cjs');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
9
|
+
|
|
10
|
+
function useOsdkFunctions({
|
|
11
|
+
queries,
|
|
12
|
+
enabled = true
|
|
13
|
+
}) {
|
|
14
|
+
const client = chunk2N32USW5_cjs.useOsdkClient();
|
|
15
|
+
const [results, setResults] = React__default.default.useState(() => queries.map(() => ({
|
|
16
|
+
data: void 0,
|
|
17
|
+
isLoading: false,
|
|
18
|
+
error: void 0,
|
|
19
|
+
lastUpdated: 0
|
|
20
|
+
})));
|
|
21
|
+
const abortControllerRef = React__default.default.useRef(null);
|
|
22
|
+
React__default.default.useEffect(() => {
|
|
23
|
+
if (!enabled || queries.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
abortControllerRef.current?.abort();
|
|
27
|
+
const abortController = new AbortController();
|
|
28
|
+
abortControllerRef.current = abortController;
|
|
29
|
+
const executeQueries = async () => {
|
|
30
|
+
setResults((prev) => queries.map((_, index) => ({
|
|
31
|
+
data: prev[index]?.data,
|
|
32
|
+
// Preserving existing data
|
|
33
|
+
isLoading: queries[index].options?.enabled !== false,
|
|
34
|
+
error: void 0,
|
|
35
|
+
lastUpdated: prev[index]?.lastUpdated || 0
|
|
36
|
+
})));
|
|
37
|
+
for await (const queryResult of executeQueriesGenerator(queries, client)) {
|
|
38
|
+
const {
|
|
39
|
+
index,
|
|
40
|
+
result,
|
|
41
|
+
error
|
|
42
|
+
} = queryResult;
|
|
43
|
+
if (abortController.signal.aborted) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
setResults((prev) => {
|
|
47
|
+
if (abortController.signal.aborted) {
|
|
48
|
+
return prev;
|
|
49
|
+
}
|
|
50
|
+
const newResults = [...prev];
|
|
51
|
+
newResults[index] = {
|
|
52
|
+
data: result,
|
|
53
|
+
isLoading: false,
|
|
54
|
+
error: error instanceof Error ? error : error ? new Error(typeof error === "string" ? error : JSON.stringify(error)) : void 0,
|
|
55
|
+
lastUpdated: Date.now()
|
|
56
|
+
};
|
|
57
|
+
return newResults;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
void executeQueries();
|
|
62
|
+
return () => {
|
|
63
|
+
abortController.abort();
|
|
64
|
+
};
|
|
65
|
+
}, [enabled, client, queries]);
|
|
66
|
+
return results;
|
|
67
|
+
}
|
|
68
|
+
async function* executeQueriesGenerator(queries, client) {
|
|
69
|
+
const queryPromises = queries.map((query, index) => createQueryPromise(query, index, client));
|
|
70
|
+
const pendingPromises = [...queryPromises];
|
|
71
|
+
while (pendingPromises.length > 0) {
|
|
72
|
+
const raceResult = await Promise.race(pendingPromises.map((promise, idx) => promise.then((result) => ({
|
|
73
|
+
result,
|
|
74
|
+
idx
|
|
75
|
+
}))));
|
|
76
|
+
yield raceResult.result;
|
|
77
|
+
void pendingPromises.splice(raceResult.idx, 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
var createQueryPromise = async (query, index, client) => {
|
|
81
|
+
if (query.options?.enabled === false) {
|
|
82
|
+
return {
|
|
83
|
+
index,
|
|
84
|
+
result: void 0,
|
|
85
|
+
error: void 0
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const queryClient = client(query.queryDefinition);
|
|
89
|
+
if ("executeFunction" in queryClient && typeof queryClient.executeFunction === "function") {
|
|
90
|
+
try {
|
|
91
|
+
const result = await queryClient.executeFunction(query.options?.params);
|
|
92
|
+
return {
|
|
93
|
+
index,
|
|
94
|
+
result,
|
|
95
|
+
error: null
|
|
96
|
+
};
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return {
|
|
99
|
+
index,
|
|
100
|
+
result: void 0,
|
|
101
|
+
error
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
index,
|
|
107
|
+
result: void 0,
|
|
108
|
+
error: new Error("Invalid query client: executeFunction method not found")
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
exports.useOsdkFunctions = useOsdkFunctions;
|
|
113
|
+
//# sourceMappingURL=unstable-do-not-use.cjs.map
|
|
114
|
+
//# sourceMappingURL=unstable-do-not-use.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/new/useOsdkFunctions.ts"],"names":["useOsdkClient","React"],"mappings":"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","file":"unstable-do-not-use.cjs","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\nimport React from \"react\";\nimport { useOsdkClient } from \"../useOsdkClient.js\";\n/**\n * React hook for executing multiple OSDK function queries in parallel.\n * Results are returned in the same order as the input queries.\n *\n * @param options - Configuration options containing the queries to execute\n * @returns Array of results in the same order as input queries, each with the same shape as useOsdkFunction\n */\nexport function useOsdkFunctions({\n queries,\n enabled = true\n}) {\n const client = useOsdkClient();\n const [results, setResults] = React.useState(() => queries.map(() => ({\n data: undefined,\n isLoading: false,\n error: undefined,\n lastUpdated: 0\n })));\n const abortControllerRef = React.useRef(null);\n React.useEffect(() => {\n if (!enabled || queries.length === 0) {\n return;\n }\n\n // Cancel previous requests\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n const executeQueries = async () => {\n // Initialize loading state for all queries\n setResults(prev => queries.map((_, index) => ({\n data: prev[index]?.data,\n // Preserving existing data\n isLoading: queries[index].options?.enabled !== false,\n error: undefined,\n lastUpdated: prev[index]?.lastUpdated || 0\n })));\n for await (const queryResult of executeQueriesGenerator(queries, client)) {\n const {\n index,\n result,\n error\n } = queryResult;\n if (abortController.signal.aborted) {\n break;\n }\n setResults(prev => {\n if (abortController.signal.aborted) {\n return prev;\n }\n const newResults = [...prev];\n newResults[index] = {\n data: result,\n isLoading: false,\n error: error instanceof Error ? error : error ? new Error(typeof error === \"string\" ? error : JSON.stringify(error)) : undefined,\n lastUpdated: Date.now()\n };\n return newResults;\n });\n }\n };\n void executeQueries();\n return () => {\n abortController.abort();\n };\n }, [enabled, client, queries]);\n return results;\n}\n/**\n * Generator function that executes queries and yields results as they complete\n */\nasync function* executeQueriesGenerator(queries, client) {\n const queryPromises = queries.map((query, index) => createQueryPromise(query, index, client));\n const pendingPromises = [...queryPromises];\n\n // Yield results as they complete using Promise.race\n while (pendingPromises.length > 0) {\n const raceResult = await Promise.race(pendingPromises.map((promise, idx) => promise.then(result => ({\n result,\n idx\n }))));\n yield raceResult.result;\n\n // Remove the completed promise from the pending list\n void pendingPromises.splice(raceResult.idx, 1);\n }\n}\nconst createQueryPromise = async (query, index, client) => {\n // Skip disabled queries\n if (query.options?.enabled === false) {\n return {\n index,\n result: undefined,\n error: undefined\n };\n }\n const queryClient = client(query.queryDefinition);\n if (\"executeFunction\" in queryClient && typeof queryClient.executeFunction === \"function\") {\n try {\n const result = await queryClient.executeFunction(query.options?.params);\n return {\n index,\n result,\n error: null\n };\n } catch (error) {\n return {\n index,\n result: undefined,\n error\n };\n }\n }\n return {\n index,\n result: undefined,\n error: new Error(\"Invalid query client: executeFunction method not found\")\n };\n};"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { QueryDefinition } from '@osdk/api';
|
|
2
|
+
import { U as UseOsdkFunctionOptions, a as UseOsdkFunctionResult } from '../useOsdkFunction-B0s7lqgN.cjs';
|
|
3
|
+
import '@osdk/client/unstable-do-not-use';
|
|
4
|
+
|
|
5
|
+
interface FunctionQueryParams<Q extends QueryDefinition<unknown>> {
|
|
6
|
+
queryDefinition: Q;
|
|
7
|
+
/**
|
|
8
|
+
* Only allow params and enabled options at the query level,
|
|
9
|
+
* other options are not yet supported in this batch context
|
|
10
|
+
*/
|
|
11
|
+
options?: Pick<UseOsdkFunctionOptions<Q>, "params" | "enabled">;
|
|
12
|
+
}
|
|
13
|
+
interface UseOsdkFunctionsProps {
|
|
14
|
+
/**
|
|
15
|
+
* Array of query configurations to execute
|
|
16
|
+
*/
|
|
17
|
+
queries: Array<FunctionQueryParams<QueryDefinition<unknown>>>;
|
|
18
|
+
/**
|
|
19
|
+
* Whether to enable all queries. When false, no queries will execute.
|
|
20
|
+
* Individual query enabled states are also respected.
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
type UseOsdkFunctionsResult = Array<Omit<UseOsdkFunctionResult<QueryDefinition<unknown>>, "refetch">>;
|
|
26
|
+
/**
|
|
27
|
+
* React hook for executing multiple OSDK function queries in parallel.
|
|
28
|
+
* Results are returned in the same order as the input queries.
|
|
29
|
+
*
|
|
30
|
+
* @param options - Configuration options containing the queries to execute
|
|
31
|
+
* @returns Array of results in the same order as input queries, each with the same shape as useOsdkFunction
|
|
32
|
+
*/
|
|
33
|
+
declare function useOsdkFunctions({ queries, enabled }: UseOsdkFunctionsProps): UseOsdkFunctionsResult;
|
|
34
|
+
|
|
35
|
+
export { type FunctionQueryParams, type UseOsdkFunctionsProps, type UseOsdkFunctionsResult, useOsdkFunctions };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { QueryDefinition, CompileTimeMetadata, ObjectTypeDefinition, Osdk, ObjectSet } from '@osdk/api';
|
|
2
|
+
import { QueryParameterType } from '@osdk/client/unstable-do-not-use';
|
|
3
|
+
|
|
4
|
+
interface UseOsdkFunctionOptions<Q extends QueryDefinition<unknown>> {
|
|
5
|
+
/**
|
|
6
|
+
* Parameters to pass to the function.
|
|
7
|
+
* Must include all required parameters; optional parameters can be omitted.
|
|
8
|
+
*/
|
|
9
|
+
params?: CompileTimeMetadata<Q>["parameters"] extends Record<string, never> ? undefined : QueryParameterType<CompileTimeMetadata<Q>["parameters"]>;
|
|
10
|
+
/**
|
|
11
|
+
* Object types this function depends on.
|
|
12
|
+
* When actions modify objects of these types, the function will automatically refetch.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Refetch when any Employee object changes
|
|
17
|
+
* { dependsOn: [Employee] }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
dependsOn?: Array<ObjectTypeDefinition | string>;
|
|
21
|
+
/**
|
|
22
|
+
* Specific object instances or ObjectSets this function depends on.
|
|
23
|
+
* When any of these specific objects change, the function will refetch.
|
|
24
|
+
* More fine-grained than dependsOn for precise invalidation control.
|
|
25
|
+
*
|
|
26
|
+
* For ObjectSets, the object type is extracted asynchronously and changes
|
|
27
|
+
* to any object of that type will trigger a refetch.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* // Refetch when this specific employee changes
|
|
32
|
+
* { dependsOnObjects: [employee] }
|
|
33
|
+
*
|
|
34
|
+
* // Refetch when any object in the ObjectSet's type changes
|
|
35
|
+
* { dependsOnObjects: [employeeObjectSet] }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
dependsOnObjects?: Array<Osdk.Instance<ObjectTypeDefinition> | ObjectSet<ObjectTypeDefinition>>;
|
|
39
|
+
/**
|
|
40
|
+
* The number of milliseconds to dedupe identical function calls.
|
|
41
|
+
* Two calls with the same function and params will share results
|
|
42
|
+
* if the second call is within this interval of the first.
|
|
43
|
+
* @default 2000
|
|
44
|
+
*/
|
|
45
|
+
dedupeIntervalMs?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Whether to enable the query. When false, the query will not execute.
|
|
48
|
+
* Useful for:
|
|
49
|
+
* - Dependent queries that need to wait for other data
|
|
50
|
+
* - Conditional queries based on component state
|
|
51
|
+
*
|
|
52
|
+
* @default true
|
|
53
|
+
* @example
|
|
54
|
+
* // Dependent query - wait for required data
|
|
55
|
+
* const { data: employee } = useOsdkObject(Employee, employeeId);
|
|
56
|
+
* const { data: report } = useOsdkFunction(getEmployeeReport, {
|
|
57
|
+
* params: { employeeId: employee?.$primaryKey },
|
|
58
|
+
* enabled: !!employee
|
|
59
|
+
* });
|
|
60
|
+
*/
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
}
|
|
63
|
+
interface UseOsdkFunctionResult<Q extends QueryDefinition<unknown>> {
|
|
64
|
+
/**
|
|
65
|
+
* The function result, or undefined if not yet loaded or on error.
|
|
66
|
+
*/
|
|
67
|
+
data: (CompileTimeMetadata<Q>["signature"] extends (...args: never[]) => infer R ? Awaited<R> : never) | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* True while the function is executing.
|
|
70
|
+
*/
|
|
71
|
+
isLoading: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Error if the function execution failed.
|
|
74
|
+
*/
|
|
75
|
+
error: Error | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Timestamp (ms since epoch) of when the result was last fetched.
|
|
78
|
+
*/
|
|
79
|
+
lastUpdated: number;
|
|
80
|
+
/**
|
|
81
|
+
* Manually refetch the function.
|
|
82
|
+
* Useful for "pull to refresh" or retry patterns.
|
|
83
|
+
*/
|
|
84
|
+
refetch: () => void;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* React hook for executing and observing OSDK functions.
|
|
88
|
+
*
|
|
89
|
+
* Provides automatic caching, deduplication, and reactive updates for function calls.
|
|
90
|
+
* Functions are automatically re-fetched when dependencies change (configured via options).
|
|
91
|
+
*
|
|
92
|
+
* @param queryDef - The QueryDefinition to execute
|
|
93
|
+
* @param options - Configuration options for the function call
|
|
94
|
+
* @returns Object containing result, loading state, error, and refetch function
|
|
95
|
+
*
|
|
96
|
+
* @example Basic usage
|
|
97
|
+
* ```tsx
|
|
98
|
+
* const { data, isLoading, error } = useOsdkFunction(getEmployeeStats, {
|
|
99
|
+
* params: { departmentId: "engineering" }
|
|
100
|
+
* });
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @example With dependency tracking
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const { data, refetch } = useOsdkFunction(calculateMetrics, {
|
|
106
|
+
* params: { startDate, endDate },
|
|
107
|
+
* dependsOn: [Employee, Project],
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @example With specific object dependencies
|
|
112
|
+
* ```tsx
|
|
113
|
+
* const { data } = useOsdkFunction(getEmployeeReport, {
|
|
114
|
+
* params: { employeeId: employee.$primaryKey },
|
|
115
|
+
* dependsOnObjects: [employee],
|
|
116
|
+
* });
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
declare function useOsdkFunction<Q extends QueryDefinition<unknown>>(queryDef: Q, options?: UseOsdkFunctionOptions<Q>): UseOsdkFunctionResult<Q>;
|
|
120
|
+
|
|
121
|
+
export { type UseOsdkFunctionOptions as U, type UseOsdkFunctionResult as a, useOsdkFunction as u };
|
|
@@ -15,14 +15,34 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import React from "react";
|
|
18
|
+
export const MISSING_PROVIDER_MESSAGE = "No OsdkProvider2 found. Did you forget to wrap your component tree with <OsdkProvider2>?";
|
|
18
19
|
function fakeClientFn(..._args) {
|
|
19
|
-
throw new Error(
|
|
20
|
+
throw new Error(MISSING_PROVIDER_MESSAGE);
|
|
20
21
|
}
|
|
21
22
|
const fakeClient = Object.assign(fakeClientFn, {
|
|
22
23
|
fetchMetadata: fakeClientFn
|
|
23
24
|
});
|
|
25
|
+
|
|
26
|
+
// Proxy that throws a clear error when any method is called, so hooks like
|
|
27
|
+
// useOsdkObjects get "Did you forget <OsdkProvider2>?" instead of
|
|
28
|
+
// "cannot read canonicalizeWhereClause of undefined".
|
|
29
|
+
// We intercept `get` so every property access returns a throwing function,
|
|
30
|
+
// without needing to enumerate every ObservableClient method.
|
|
31
|
+
// Symbol.toPrimitive and Symbol.toStringTag are accessed by React/devtools
|
|
32
|
+
// during rendering and logging — returning undefined for these avoids
|
|
33
|
+
// spurious throws in contexts unrelated to the user's code.
|
|
34
|
+
const fakeObservableClient = new Proxy({}, {
|
|
35
|
+
get(_target, prop) {
|
|
36
|
+
if (prop === Symbol.toPrimitive || prop === Symbol.toStringTag) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
return (..._args) => {
|
|
40
|
+
throw new Error(MISSING_PROVIDER_MESSAGE);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
});
|
|
24
44
|
export const OsdkContext2 = /*#__PURE__*/React.createContext({
|
|
25
45
|
client: fakeClient,
|
|
26
|
-
observableClient:
|
|
46
|
+
observableClient: fakeObservableClient
|
|
27
47
|
});
|
|
28
48
|
//# sourceMappingURL=OsdkContext2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OsdkContext2.js","names":["React","fakeClientFn","_args","Error","fakeClient","Object","assign","fetchMetadata","OsdkContext2","createContext","client","observableClient"
|
|
1
|
+
{"version":3,"file":"OsdkContext2.js","names":["React","MISSING_PROVIDER_MESSAGE","fakeClientFn","_args","Error","fakeClient","Object","assign","fetchMetadata","fakeObservableClient","Proxy","get","_target","prop","Symbol","toPrimitive","toStringTag","undefined","OsdkContext2","createContext","client","observableClient"],"sources":["OsdkContext2.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { Client } from \"@osdk/client\";\nimport type { ObservableClient } from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\n\nexport const MISSING_PROVIDER_MESSAGE =\n \"No OsdkProvider2 found. Did you forget to wrap your component tree with <OsdkProvider2>?\";\n\nfunction fakeClientFn(..._args: any[]) {\n throw new Error(MISSING_PROVIDER_MESSAGE);\n}\n\nconst fakeClient = Object.assign(fakeClientFn, {\n fetchMetadata: fakeClientFn,\n} as Client);\n\n// Proxy that throws a clear error when any method is called, so hooks like\n// useOsdkObjects get \"Did you forget <OsdkProvider2>?\" instead of\n// \"cannot read canonicalizeWhereClause of undefined\".\n// We intercept `get` so every property access returns a throwing function,\n// without needing to enumerate every ObservableClient method.\n// Symbol.toPrimitive and Symbol.toStringTag are accessed by React/devtools\n// during rendering and logging — returning undefined for these avoids\n// spurious throws in contexts unrelated to the user's code.\nconst fakeObservableClient = new Proxy({} as ObservableClient, {\n get(_target, prop) {\n if (prop === Symbol.toPrimitive || prop === Symbol.toStringTag) {\n return undefined;\n }\n return (..._args: any[]) => {\n throw new Error(MISSING_PROVIDER_MESSAGE);\n };\n },\n});\n\ninterface OsdkContextContents {\n client: Client;\n // keeping the old name for now intentionally\n // in case i need both for a while\n // in the future we can just make\n // this `client: ObservableClient`\n observableClient: ObservableClient;\n}\n\nexport const OsdkContext2: React.Context<OsdkContextContents> = React\n .createContext<OsdkContextContents>({\n client: fakeClient,\n observableClient: fakeObservableClient,\n });\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,OAAOA,KAAK,MAAM,OAAO;AAEzB,OAAO,MAAMC,wBAAwB,GACnC,0FAA0F;AAE5F,SAASC,YAAYA,CAAC,GAAGC,KAAY,EAAE;EACrC,MAAM,IAAIC,KAAK,CAACH,wBAAwB,CAAC;AAC3C;AAEA,MAAMI,UAAU,GAAGC,MAAM,CAACC,MAAM,CAACL,YAAY,EAAE;EAC7CM,aAAa,EAAEN;AACjB,CAAW,CAAC;;AAEZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMO,oBAAoB,GAAG,IAAIC,KAAK,CAAC,CAAC,CAAC,EAAsB;EAC7DC,GAAGA,CAACC,OAAO,EAAEC,IAAI,EAAE;IACjB,IAAIA,IAAI,KAAKC,MAAM,CAACC,WAAW,IAAIF,IAAI,KAAKC,MAAM,CAACE,WAAW,EAAE;MAC9D,OAAOC,SAAS;IAClB;IACA,OAAO,CAAC,GAAGd,KAAY,KAAK;MAC1B,MAAM,IAAIC,KAAK,CAACH,wBAAwB,CAAC;IAC3C,CAAC;EACH;AACF,CAAC,CAAC;AAWF,OAAO,MAAMiB,YAAgD,gBAAGlB,KAAK,CAClEmB,aAAa,CAAsB;EAClCC,MAAM,EAAEf,UAAU;EAClBgB,gBAAgB,EAAEZ;AACpB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -91,9 +91,7 @@ export function useOsdkAction(actionDef) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Abort any existing validation
|
|
94
|
-
|
|
95
|
-
abortControllerRef.current.abort();
|
|
96
|
-
}
|
|
94
|
+
abortControllerRef.current?.abort();
|
|
97
95
|
|
|
98
96
|
// Create new AbortController
|
|
99
97
|
const abortController = new AbortController();
|
|
@@ -131,9 +129,7 @@ export function useOsdkAction(actionDef) {
|
|
|
131
129
|
// Cleanup on unmount
|
|
132
130
|
React.useEffect(() => {
|
|
133
131
|
return () => {
|
|
134
|
-
|
|
135
|
-
abortControllerRef.current.abort();
|
|
136
|
-
}
|
|
132
|
+
abortControllerRef.current?.abort();
|
|
137
133
|
};
|
|
138
134
|
}, []);
|
|
139
135
|
return React.useMemo(() => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOsdkAction.js","names":["ActionValidationError","React","OsdkContext2","useOsdkAction","actionDef","observableClient","useContext","error","setError","useState","data","setData","isPending","setPending","isValidating","setValidating","validationResult","setValidationResult","abortControllerRef","useRef","applyAction","useCallback","hookArgs","current","abort","undefined","Array","isArray","updates","args","map","a","$optimisticUpdate","push","r","optimisticUpdate","ctx","update","e","actionValidation","unknown","validateAction","abortController","AbortController","result","signal","aborted","Error","name","useEffect","useMemo"],"sources":["useOsdkAction.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 ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/client\";\nimport { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionSignatureFromDef,\n ObservableClient,\n} from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\ntype ApplyActionParams<Q extends ActionDefinition<any>> =\n & Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n & {\n [K in keyof ObservableClient.ApplyActionOptions as `$${K}`]:\n ObservableClient.ApplyActionOptions[K];\n };\n\nexport interface UseOsdkActionResult<Q extends ActionDefinition<any>> {\n applyAction: (\n args: ApplyActionParams<Q> | Array<ApplyActionParams<Q>>,\n ) => Promise<ActionEditResponse | undefined>;\n\n error:\n | undefined\n | Partial<{\n actionValidation: ActionValidationError;\n unknown: unknown;\n }>;\n data: ActionEditResponse | undefined;\n\n isPending: boolean;\n isValidating: boolean;\n\n /**\n * Validates the action with the provided arguments without executing it.\n * Calling this function again before the previous validation finishes will cancel\n * the first validation and start a new one.\n * @param args The action arguments to validate\n * @returns A promise that resolves to the validation response, or undefined if aborted\n */\n validateAction: (\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse | undefined>;\n\n validationResult?: ActionValidationResponse;\n}\n\nexport function useOsdkAction<Q extends ActionDefinition<any>>(\n actionDef: Q,\n): UseOsdkActionResult<Q> {\n const { observableClient } = React.useContext(OsdkContext2);\n const [error, setError] = React.useState<UseOsdkActionResult<Q>[\"error\"]>();\n const [data, setData] = React.useState<ActionEditResponse | undefined>();\n const [isPending, setPending] = React.useState(false);\n const [isValidating, setValidating] = React.useState(false);\n const [validationResult, setValidationResult] = React.useState<\n ActionValidationResponse | undefined\n >();\n const abortControllerRef = React.useRef<AbortController | null>(null);\n\n const applyAction = React.useCallback(async function applyAction(\n hookArgs: ApplyActionParams<Q> | Array<ApplyActionParams<Q>>,\n ) {\n try {\n // If validation is in progress, abort it\n if (isValidating && abortControllerRef.current) {\n abortControllerRef.current.abort();\n setValidating(false);\n }\n\n setPending(true);\n setError(undefined);\n\n if (Array.isArray(hookArgs)) {\n const updates: Array<\n ObservableClient.ApplyActionOptions[\"optimisticUpdate\"]\n > = [];\n const args = hookArgs.map(a => {\n const { $optimisticUpdate, ...args } = a;\n if ($optimisticUpdate) {\n updates.push($optimisticUpdate);\n }\n return args;\n });\n\n const r = await observableClient.applyAction(actionDef, args, {\n optimisticUpdate: (ctx) => {\n for (const update of updates) {\n update?.(ctx);\n }\n },\n });\n setData(r);\n return r;\n } else {\n const { $optimisticUpdate, ...args } = hookArgs;\n\n const r = await observableClient.applyAction(actionDef, args, {\n optimisticUpdate: $optimisticUpdate,\n });\n setData(r);\n return r;\n }\n } catch (e) {\n if (e instanceof ActionValidationError) {\n setError({\n actionValidation: e,\n });\n } else {\n setError({ unknown: e });\n }\n throw e;\n } finally {\n setPending(false);\n }\n }, [observableClient, actionDef, isValidating]);\n\n const validateAction = React.useCallback(async function validateAction(\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ): Promise<ActionValidationResponse | undefined> {\n try {\n // Check if action is being applied\n if (isPending) {\n return undefined;\n }\n\n // Abort any existing validation\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Create new AbortController\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setValidating(true);\n setError(undefined);\n\n const result = await observableClient.validateAction(actionDef, args);\n\n // Check if aborted\n if (abortController.signal.aborted) {\n return undefined;\n }\n\n setValidationResult(result);\n return result;\n } catch (e) {\n // Check if it was aborted\n if (e instanceof Error && e.name === \"AbortError\") {\n return undefined;\n }\n\n if (e instanceof ActionValidationError) {\n setError({\n actionValidation: e,\n });\n } else {\n setError({ unknown: e });\n }\n throw e;\n } finally {\n setValidating(false);\n }\n }, [observableClient, actionDef, isPending]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return React.useMemo(() => ({\n applyAction,\n validateAction,\n error,\n data,\n isPending,\n isValidating,\n validationResult,\n }), [\n applyAction,\n validateAction,\n error,\n data,\n isPending,\n isValidating,\n validationResult,\n ]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"useOsdkAction.js","names":["ActionValidationError","React","OsdkContext2","useOsdkAction","actionDef","observableClient","useContext","error","setError","useState","data","setData","isPending","setPending","isValidating","setValidating","validationResult","setValidationResult","abortControllerRef","useRef","applyAction","useCallback","hookArgs","current","abort","undefined","Array","isArray","updates","args","map","a","$optimisticUpdate","push","r","optimisticUpdate","ctx","update","e","actionValidation","unknown","validateAction","abortController","AbortController","result","signal","aborted","Error","name","useEffect","useMemo"],"sources":["useOsdkAction.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 ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/client\";\nimport { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionSignatureFromDef,\n ObservableClient,\n} from \"@osdk/client/unstable-do-not-use\";\nimport React from \"react\";\nimport { OsdkContext2 } from \"./OsdkContext2.js\";\n\ntype ApplyActionParams<Q extends ActionDefinition<any>> =\n & Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0]\n & {\n [K in keyof ObservableClient.ApplyActionOptions as `$${K}`]:\n ObservableClient.ApplyActionOptions[K];\n };\n\nexport interface UseOsdkActionResult<Q extends ActionDefinition<any>> {\n applyAction: (\n args: ApplyActionParams<Q> | Array<ApplyActionParams<Q>>,\n ) => Promise<ActionEditResponse | undefined>;\n\n error:\n | undefined\n | Partial<{\n actionValidation: ActionValidationError;\n unknown: unknown;\n }>;\n data: ActionEditResponse | undefined;\n\n isPending: boolean;\n isValidating: boolean;\n\n /**\n * Validates the action with the provided arguments without executing it.\n * Calling this function again before the previous validation finishes will cancel\n * the first validation and start a new one.\n * @param args The action arguments to validate\n * @returns A promise that resolves to the validation response, or undefined if aborted\n */\n validateAction: (\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ) => Promise<ActionValidationResponse | undefined>;\n\n validationResult?: ActionValidationResponse;\n}\n\nexport function useOsdkAction<Q extends ActionDefinition<any>>(\n actionDef: Q,\n): UseOsdkActionResult<Q> {\n const { observableClient } = React.useContext(OsdkContext2);\n const [error, setError] = React.useState<UseOsdkActionResult<Q>[\"error\"]>();\n const [data, setData] = React.useState<ActionEditResponse | undefined>();\n const [isPending, setPending] = React.useState(false);\n const [isValidating, setValidating] = React.useState(false);\n const [validationResult, setValidationResult] = React.useState<\n ActionValidationResponse | undefined\n >();\n const abortControllerRef = React.useRef<AbortController | null>(null);\n\n const applyAction = React.useCallback(async function applyAction(\n hookArgs: ApplyActionParams<Q> | Array<ApplyActionParams<Q>>,\n ) {\n try {\n // If validation is in progress, abort it\n if (isValidating && abortControllerRef.current) {\n abortControllerRef.current.abort();\n setValidating(false);\n }\n\n setPending(true);\n setError(undefined);\n\n if (Array.isArray(hookArgs)) {\n const updates: Array<\n ObservableClient.ApplyActionOptions[\"optimisticUpdate\"]\n > = [];\n const args = hookArgs.map(a => {\n const { $optimisticUpdate, ...args } = a;\n if ($optimisticUpdate) {\n updates.push($optimisticUpdate);\n }\n return args;\n });\n\n const r = await observableClient.applyAction(actionDef, args, {\n optimisticUpdate: (ctx) => {\n for (const update of updates) {\n update?.(ctx);\n }\n },\n });\n setData(r);\n return r;\n } else {\n const { $optimisticUpdate, ...args } = hookArgs;\n\n const r = await observableClient.applyAction(actionDef, args, {\n optimisticUpdate: $optimisticUpdate,\n });\n setData(r);\n return r;\n }\n } catch (e) {\n if (e instanceof ActionValidationError) {\n setError({\n actionValidation: e,\n });\n } else {\n setError({ unknown: e });\n }\n throw e;\n } finally {\n setPending(false);\n }\n }, [observableClient, actionDef, isValidating]);\n\n const validateAction = React.useCallback(async function validateAction(\n args: Parameters<ActionSignatureFromDef<Q>[\"applyAction\"]>[0],\n ): Promise<ActionValidationResponse | undefined> {\n try {\n // Check if action is being applied\n if (isPending) {\n return undefined;\n }\n\n // Abort any existing validation\n abortControllerRef.current?.abort();\n\n // Create new AbortController\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setValidating(true);\n setError(undefined);\n\n const result = await observableClient.validateAction(actionDef, args);\n\n // Check if aborted\n if (abortController.signal.aborted) {\n return undefined;\n }\n\n setValidationResult(result);\n return result;\n } catch (e) {\n // Check if it was aborted\n if (e instanceof Error && e.name === \"AbortError\") {\n return undefined;\n }\n\n if (e instanceof ActionValidationError) {\n setError({\n actionValidation: e,\n });\n } else {\n setError({ unknown: e });\n }\n throw e;\n } finally {\n setValidating(false);\n }\n }, [observableClient, actionDef, isPending]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n };\n }, []);\n\n return React.useMemo(() => ({\n applyAction,\n validateAction,\n error,\n data,\n isPending,\n isValidating,\n validationResult,\n }), [\n applyAction,\n validateAction,\n error,\n data,\n isPending,\n isValidating,\n validationResult,\n ]);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
import React from "react";
|
|
18
|
+
import { useOsdkClient } from "../useOsdkClient.js";
|
|
19
|
+
/**
|
|
20
|
+
* React hook for executing multiple OSDK function queries in parallel.
|
|
21
|
+
* Results are returned in the same order as the input queries.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Configuration options containing the queries to execute
|
|
24
|
+
* @returns Array of results in the same order as input queries, each with the same shape as useOsdkFunction
|
|
25
|
+
*/
|
|
26
|
+
export function useOsdkFunctions({
|
|
27
|
+
queries,
|
|
28
|
+
enabled = true
|
|
29
|
+
}) {
|
|
30
|
+
const client = useOsdkClient();
|
|
31
|
+
const [results, setResults] = React.useState(() => queries.map(() => ({
|
|
32
|
+
data: undefined,
|
|
33
|
+
isLoading: false,
|
|
34
|
+
error: undefined,
|
|
35
|
+
lastUpdated: 0
|
|
36
|
+
})));
|
|
37
|
+
const abortControllerRef = React.useRef(null);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (!enabled || queries.length === 0) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Cancel previous requests
|
|
44
|
+
abortControllerRef.current?.abort();
|
|
45
|
+
const abortController = new AbortController();
|
|
46
|
+
abortControllerRef.current = abortController;
|
|
47
|
+
void (async () => {
|
|
48
|
+
// Initialize loading state for all queries
|
|
49
|
+
setResults(prev => queries.map((_, index) => ({
|
|
50
|
+
data: prev[index]?.data,
|
|
51
|
+
// Preserving existing data
|
|
52
|
+
isLoading: queries[index].options?.enabled !== false,
|
|
53
|
+
error: undefined,
|
|
54
|
+
lastUpdated: prev[index]?.lastUpdated || 0
|
|
55
|
+
})));
|
|
56
|
+
for await (const queryResult of executeQueriesGenerator(queries, client)) {
|
|
57
|
+
const {
|
|
58
|
+
index,
|
|
59
|
+
result,
|
|
60
|
+
error
|
|
61
|
+
} = queryResult;
|
|
62
|
+
if (abortController.signal.aborted) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
setResults(prev => {
|
|
66
|
+
if (abortController.signal.aborted) {
|
|
67
|
+
return prev;
|
|
68
|
+
}
|
|
69
|
+
const newResults = [...prev];
|
|
70
|
+
newResults[index] = {
|
|
71
|
+
data: result,
|
|
72
|
+
isLoading: false,
|
|
73
|
+
error: error instanceof Error ? error : error ? new Error(typeof error === "string" ? error : JSON.stringify(error)) : undefined,
|
|
74
|
+
lastUpdated: Date.now()
|
|
75
|
+
};
|
|
76
|
+
return newResults;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
})();
|
|
80
|
+
return () => {
|
|
81
|
+
abortController.abort();
|
|
82
|
+
};
|
|
83
|
+
}, [enabled, client, queries]);
|
|
84
|
+
return results;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generator function that executes queries and yields results as they complete
|
|
88
|
+
*/
|
|
89
|
+
async function* executeQueriesGenerator(queries, client) {
|
|
90
|
+
const queryPromises = queries.map((query, index) => createQueryPromise(query, index, client));
|
|
91
|
+
const pendingPromises = [...queryPromises];
|
|
92
|
+
|
|
93
|
+
// Yield results as they complete using Promise.race
|
|
94
|
+
while (pendingPromises.length > 0) {
|
|
95
|
+
const raceResult = await Promise.race(pendingPromises.map((promise, idx) => promise.then(result => ({
|
|
96
|
+
result,
|
|
97
|
+
idx
|
|
98
|
+
}))));
|
|
99
|
+
yield raceResult.result;
|
|
100
|
+
|
|
101
|
+
// Remove the completed promise from the pending list
|
|
102
|
+
void pendingPromises.splice(raceResult.idx, 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const createQueryPromise = async (query, index, client) => {
|
|
106
|
+
// Skip disabled queries
|
|
107
|
+
if (query.options?.enabled === false) {
|
|
108
|
+
return {
|
|
109
|
+
index,
|
|
110
|
+
result: undefined,
|
|
111
|
+
error: undefined
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const queryClient = client(query.queryDefinition);
|
|
115
|
+
if ("executeFunction" in queryClient && typeof queryClient.executeFunction === "function") {
|
|
116
|
+
try {
|
|
117
|
+
const result = await queryClient.executeFunction(query.options?.params);
|
|
118
|
+
return {
|
|
119
|
+
index,
|
|
120
|
+
result,
|
|
121
|
+
error: null
|
|
122
|
+
};
|
|
123
|
+
} catch (error) {
|
|
124
|
+
return {
|
|
125
|
+
index,
|
|
126
|
+
result: undefined,
|
|
127
|
+
error
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
index,
|
|
133
|
+
result: undefined,
|
|
134
|
+
error: new Error("Invalid query client: executeFunction method not found")
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=useOsdkFunctions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOsdkFunctions.js","names":["React","useOsdkClient","useOsdkFunctions","queries","enabled","client","results","setResults","useState","map","data","undefined","isLoading","error","lastUpdated","abortControllerRef","useRef","useEffect","length","current","abort","abortController","AbortController","prev","_","index","options","queryResult","executeQueriesGenerator","result","signal","aborted","newResults","Error","JSON","stringify","Date","now","queryPromises","query","createQueryPromise","pendingPromises","raceResult","Promise","race","promise","idx","then","splice","queryClient","queryDefinition","executeFunction","params"],"sources":["useOsdkFunctions.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\nimport type { CompileTimeMetadata, QueryDefinition } from \"@osdk/api\";\nimport type { Client } from \"@osdk/client\";\nimport React from \"react\";\nimport { useOsdkClient } from \"../useOsdkClient.js\";\nimport type {\n UseOsdkFunctionOptions,\n UseOsdkFunctionResult,\n} from \"./useOsdkFunction.js\";\n\nexport interface FunctionQueryParams<Q extends QueryDefinition<unknown>> {\n queryDefinition: Q;\n /**\n * Only allow params and enabled options at the query level,\n * other options are not yet supported in this batch context\n */\n options?: Pick<UseOsdkFunctionOptions<Q>, \"params\" | \"enabled\">;\n}\n\nexport interface UseOsdkFunctionsProps {\n /**\n * Array of query configurations to execute\n */\n queries: Array<FunctionQueryParams<QueryDefinition<unknown>>>;\n\n /**\n * Whether to enable all queries. When false, no queries will execute.\n * Individual query enabled states are also respected.\n * @default true\n */\n enabled?: boolean;\n}\n\nexport type UseOsdkFunctionsResult = Array<\n Omit<UseOsdkFunctionResult<QueryDefinition<unknown>>, \"refetch\">\n>;\n\n/**\n * React hook for executing multiple OSDK function queries in parallel.\n * Results are returned in the same order as the input queries.\n *\n * @param options - Configuration options containing the queries to execute\n * @returns Array of results in the same order as input queries, each with the same shape as useOsdkFunction\n */\nexport function useOsdkFunctions(\n { queries, enabled = true }: UseOsdkFunctionsProps,\n): UseOsdkFunctionsResult {\n const client = useOsdkClient();\n\n const [results, setResults] = React.useState<\n UseOsdkFunctionsResult\n >(() =>\n queries.map(() => ({\n data: undefined,\n isLoading: false,\n error: undefined,\n lastUpdated: 0,\n }))\n );\n\n const abortControllerRef = React.useRef<AbortController | null>(null);\n\n React.useEffect(() => {\n if (!enabled || queries.length === 0) {\n return;\n }\n\n // Cancel previous requests\n abortControllerRef.current?.abort();\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const executeQueries = async () => {\n // Initialize loading state for all queries\n setResults(prev =>\n queries.map((_, index) => ({\n data: prev[index]?.data, // Preserving existing data\n isLoading: queries[index].options?.enabled !== false,\n error: undefined,\n lastUpdated: prev[index]?.lastUpdated || 0,\n }))\n );\n\n for await (\n const queryResult of executeQueriesGenerator(\n queries,\n client,\n )\n ) {\n const { index, result, error } = queryResult;\n\n if (abortController.signal.aborted) {\n break;\n }\n\n setResults(prev => {\n if (abortController.signal.aborted) {\n return prev;\n }\n const newResults = [...prev];\n newResults[index] = {\n data: result,\n isLoading: false,\n error: error instanceof Error\n ? error\n : error\n ? new Error(\n typeof error === \"string\" ? error : JSON.stringify(error),\n )\n : undefined,\n lastUpdated: Date.now(),\n };\n return newResults;\n });\n }\n };\n\n void executeQueries();\n\n return () => {\n abortController.abort();\n };\n }, [\n enabled,\n client,\n queries,\n ]);\n\n return results;\n}\n\ninterface QueryResult<Q extends QueryDefinition<unknown>> {\n index: number;\n result?:\n | (CompileTimeMetadata<Q>[\"signature\"] extends (...args: never[]) => infer R\n ? Awaited<R>\n : never)\n | undefined;\n error?: unknown;\n}\n/**\n * Generator function that executes queries and yields results as they complete\n */\nasync function* executeQueriesGenerator(\n queries: Array<FunctionQueryParams<QueryDefinition<unknown>>>,\n client: Client,\n): AsyncGenerator<QueryResult<QueryDefinition<unknown>>> {\n const queryPromises = queries.map((query, index) =>\n createQueryPromise<typeof query.queryDefinition>(query, index, client)\n );\n\n const pendingPromises = [...queryPromises];\n\n // Yield results as they complete using Promise.race\n while (pendingPromises.length > 0) {\n const raceResult = await Promise.race(\n pendingPromises.map((promise, idx) =>\n promise.then(result => ({ result, idx }))\n ),\n );\n\n yield raceResult.result;\n\n // Remove the completed promise from the pending list\n void pendingPromises.splice(raceResult.idx, 1);\n }\n}\n\nconst createQueryPromise = async <Q extends QueryDefinition<unknown>>(\n query: FunctionQueryParams<Q>,\n index: number,\n client: Client,\n): Promise<QueryResult<Q>> => {\n // Skip disabled queries\n if (query.options?.enabled === false) {\n return { index, result: undefined, error: undefined };\n }\n\n const queryClient = client(query.queryDefinition);\n\n if (\n \"executeFunction\" in queryClient\n && typeof queryClient.executeFunction === \"function\"\n ) {\n try {\n const result = await queryClient.executeFunction(query.options?.params);\n return { index, result, error: null };\n } catch (error) {\n return { index, result: undefined, error };\n }\n }\n\n return {\n index,\n result: undefined,\n error: new Error(\"Invalid query client: executeFunction method not found\"),\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
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 { useOsdkFunctions } from "../new/useOsdkFunctions.js";
|
|
18
|
+
//# sourceMappingURL=unstable-do-not-use.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unstable-do-not-use.js","names":["useOsdkFunctions"],"sources":["unstable-do-not-use.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 { useOsdkFunctions } from \"../new/useOsdkFunctions.js\";\nexport type {\n FunctionQueryParams,\n UseOsdkFunctionsProps,\n UseOsdkFunctionsResult,\n} from \"../new/useOsdkFunctions.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,gBAAgB,QAAQ,4BAA4B","ignoreList":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Client } from "@osdk/client";
|
|
2
2
|
import type { ObservableClient } from "@osdk/client/unstable-do-not-use";
|
|
3
3
|
import React from "react";
|
|
4
|
+
export declare const MISSING_PROVIDER_MESSAGE = "No OsdkProvider2 found. Did you forget to wrap your component tree with <OsdkProvider2>?";
|
|
4
5
|
interface OsdkContextContents {
|
|
5
6
|
client: Client;
|
|
6
7
|
observableClient: ObservableClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAgBA,cAAc,cAAc,cAAe;AAC3C,cAAc,wBAAwB,kCAAmC;AACzE,OAAO,WAAW,OAAQ;
|
|
1
|
+
{"mappings":"AAgBA,cAAc,cAAc,cAAe;AAC3C,cAAc,wBAAwB,kCAAmC;AACzE,OAAO,WAAW,OAAQ;AAE1B,OAAO,cAAM,2BACX;UA6BQ,oBAAoB;CAC5B,QAAQ;CAKR,kBAAkB;AACnB;AAED,OAAO,cAAMA,cAAc,MAAM,QAAQ","names":["OsdkContext2: React.Context<OsdkContextContents>"],"sources":["../../../src/new/OsdkContext2.ts"],"version":3,"file":"OsdkContext2.d.ts"}
|