nuabase 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,9 +46,9 @@ const classifyLeads = new Nua().createArrayFn({
46
46
  **4. Invoke.** Call it like any other async function:
47
47
 
48
48
  ```ts
49
- const result = await classifyLeads.now(leads, 'id');
49
+ const result = await classifyLeads(leads, 'id');
50
50
  if (result.isError) throw new Error(result.error);
51
- console.log(result.data[0].insights);
51
+ console.log(result.data[0].leadInsights);
52
52
  // -> { industry: 'Software', company_size: 'Mid-market' }
53
53
  ```
54
54
 
@@ -107,34 +107,35 @@ const rows = [
107
107
  },
108
108
  ];
109
109
 
110
- const response = await enrichLeads.now(rows, 'leadId'); // `leadId` is the primary key field
110
+ const response = await enrichLeads(rows, 'leadId'); // `leadId` is the primary key field
111
111
 
112
112
  if (response.isError) {
113
113
  console.error(response.error);
114
114
  return;
115
115
  }
116
116
 
117
- response.data.forEach(({ id, leadInsights }) => {
117
+ response.data.forEach(({ leadId, leadInsights }) => {
118
118
  // leadInsights satisfies the LeadInsights schema
119
- console.log(id, leadInsights.company_name, leadInsights.industry, leadInsights.company_size);
119
+ console.log(leadId, leadInsights.company_name, leadInsights.industry, leadInsights.company_size);
120
120
  });
121
121
 
122
122
  console.log(response.data);
123
123
  // -> [
124
124
  // {
125
- // id: 'lead-101',
125
+ // leadId: 'lead-101',
126
126
  // leadInsights: {
127
127
  // company_name: 'Acme Analytics',
128
128
  // industry: 'Software',
129
129
  // company_size: 'Mid-market',
130
130
  // recommended_follow_up: 'Call',
131
131
  // },
132
+ // sourceRow: { leadId: 'lead-101', name: 'Acme Analytics', notes: '...' },
132
133
  // },
133
134
  // // ...
134
135
  // ];
135
136
  ```
136
137
 
137
- `map(data, primaryKey)` submits an asynchronous mapping job. But `map.now(data, primaryKey)` is immediate — it waits for completion and returns the full result.
138
+ The default invocation waits for completion and returns the full result. Use `.queue(data, primaryKey)` to submit an asynchronous job and receive streaming updates via SSE.
138
139
 
139
140
  ## Why Nuabase
140
141
 
@@ -149,14 +150,15 @@ Every call returns a discriminated union. When `isError` is `true`, you get a fl
149
150
 
150
151
  **Success**
151
152
 
152
- | Field | Type | Description |
153
- | ------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
154
- | `isSuccess` | `true` | Indicates that the request completed successfully. |
155
- | `data` | `Array<{ [primaryKey]: unknown; [outputName]: z.infer<typeof output> }>` | Rows that merged the original primary key with the validated schema output. |
156
- | `llmRequestId` | `string` | Unique identifier for tracing each Nuabase LLM execution. |
157
- | `cacheHits` | `number` | Count of input rows served from Nuabase response cache. |
158
- | `rowsWithNoResults` | `string[]` | Primary keys that could not be resolved by the model. |
159
- | `isError` | `false \| undefined` | Absent on success; included for type narrowing. |
153
+ | Field | Type | Description |
154
+ | ------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
155
+ | `isSuccess` | `true` | Indicates that the request completed successfully. |
156
+ | `data` | `Array<{ [primaryKey]: unknown; [outputName]: z.infer<typeof output>; sourceRow: InputRow }>` | Rows that merged the original primary key with the validated schema output, plus the full `sourceRow` for convenience. |
157
+ | `llmRequestId` | `string` | Unique identifier for tracing each Nuabase LLM execution. |
158
+ | `usage` | `{ promptTokens: number; completionTokens: number; totalTokens: number }` | Token usage statistics for the LLM request. |
159
+ | `cacheHits` | `number` | Count of input rows served from Nuabase response cache. |
160
+ | `rowsWithNoResults` | `string[]` | Primary keys that could not be resolved by the model. |
161
+ | `isError` | `false \| undefined` | Absent on success; included for type narrowing. |
160
162
 
161
163
  **Error**
162
164
 
@@ -173,28 +175,33 @@ Creates a client bound to your Nuabase account. Provide:
173
175
  - `apiKey?: string` – API key for authentication. Defaults to `process.env.NUABASE_API_KEY`.
174
176
  - `baseUrl?: string` – Override the API host. Defaults to `https://api.nuabase.com`.
175
177
 
176
- **`nua.map({ name, prompt, output })`**
177
- Declares a typed mapping function backed by Nuabase. Parameters:
178
+ **`nua.createArrayFn({ prompt, output })`**
179
+ Declares a typed array mapping function backed by Nuabase. Parameters:
178
180
 
179
- - `name: string` – Label applied to the enriched payload in each response row (e.g., `result.data[i][name]`).
180
181
  - `prompt: string` – Natural-language instructions sent to the LLM.
181
- - `output: ZodSchema` – Zod schema describing the output shape. Nuabase stores the JSON Schema twin and validates responses against it before returning.
182
+ - `output: { name: string; schema: ZodSchema }` – Output configuration with a name and Zod schema describing the output shape.
182
183
 
183
- Returns a callable object (the mapper) with two entry points:
184
+ Returns a callable function with two modes:
184
185
 
185
- - `mapper(data, primaryKey)` – Submits the job asynchronously and returns immediately with metadata and eventual results.
186
- - `mapper.now(data, primaryKey)` – Runs the job and waits until the full enriched result set is ready.
186
+ - `fn(data, primaryKey)` – Default mode. Runs the job and waits until the full enriched result set is ready.
187
+ - `fn.queue(data, primaryKey)` – Submits the job asynchronously and returns streaming metadata via SSE.
187
188
 
188
- Both entry points expect:
189
+ Both modes expect:
189
190
 
190
191
  - `data: Array<Record<string, unknown>>` – Rows you want Nuabase to enrich. Each row must include the primary key.
191
192
  - `primaryKey: string` – Field name that uniquely identifies each row within `data`. The SDK throws if the field is missing on any item.
192
193
 
193
- Both entry points resolve to either:
194
+ Both modes resolve to either:
194
195
 
195
- - **Success** – `{ isSuccess: true, data, llmRequestId, cacheHits, rowsWithNoResults }`.
196
+ - **Success** – `{ isSuccess: true, data, llmRequestId, usage, cacheHits, rowsWithNoResults }`.
196
197
  - **Error** – `{ isError: true, error }`.
197
198
 
199
+ **`nua.createFn({ prompt, output })`**
200
+ Declares a typed single-value function backed by Nuabase. Similar to `createArrayFn` but for processing a single input value instead of an array. Returns a function that accepts a single input value.
201
+
202
+ **`nua.getRequest(llmRequestId)`**
203
+ Retrieves request details for a completed LLM execution using its request ID.
204
+
198
205
  ## Next Steps
199
206
 
200
207
  - Create an API key or inspect request logs in the [Nuabase Console](https://console.nuabase.com/).
@@ -55,22 +55,60 @@ function getErrorMessageFromException(error) {
55
55
  return String(error);
56
56
  }
57
57
 
58
- class NuabaseAPIClient {
59
- constructor(config = {}) {
60
- this.apiKey = resolveConfigValue(config, "apiKey", "NUABASE_API_KEY") || "";
61
- this.baseUrl = resolveConfigValue(config, "baseUrl", "NUABASE_API_URL") || "https://api.nuabase.com";
62
- if (!this.apiKey) {
58
+ const isBrowserEnvironment = () => typeof window !== "undefined" && !!window.document;
59
+ class NuabaseAuthTokenManager {
60
+ constructor(config) {
61
+ this.apiKey = resolveConfigValue(config, "apiKey", "NUABASE_API_KEY") || void 0;
62
+ this.fetchToken = config.fetchToken;
63
+ if (this.apiKey && this.fetchToken) {
64
+ throw new Error("Provide either an apiKey or a fetchToken function, but not both.");
65
+ }
66
+ if (!this.apiKey && !this.fetchToken) {
63
67
  throw new Error(
64
- "API key is required. Provide it via config.apiKey or NUABASE_API_KEY environment variable."
68
+ "Authentication is required. Provide config.apiKey/NUABASE_API_KEY or a fetchToken function."
69
+ );
70
+ }
71
+ if (this.apiKey && isBrowserEnvironment()) {
72
+ throw new Error(
73
+ "found config.apiKey. It is a private secret that must only be used in server environments."
65
74
  );
66
75
  }
67
76
  }
77
+ async getToken() {
78
+ if (this.apiKey) {
79
+ return this.apiKey;
80
+ }
81
+ if (!this.fetchToken) {
82
+ throw new Error("Unable to resolve API token because no fetchToken function is configured.");
83
+ }
84
+ if (this.apiToken) {
85
+ return this.apiToken;
86
+ }
87
+ if (!this.pendingTokenPromise) {
88
+ this.pendingTokenPromise = this.fetchToken().then((token) => {
89
+ if (!token) {
90
+ throw new Error("fetchToken must resolve a non-empty API token.");
91
+ }
92
+ this.apiToken = token;
93
+ return token;
94
+ }).finally(() => {
95
+ this.pendingTokenPromise = void 0;
96
+ });
97
+ }
98
+ return this.pendingTokenPromise;
99
+ }
100
+ }
101
+ class NuabaseAPIClient {
102
+ constructor(config = {}) {
103
+ this.baseUrl = resolveConfigValue(config, "baseUrl", "NUABASE_API_URL") || "https://api.nuabase.com";
104
+ this.authTokenManager = new NuabaseAuthTokenManager(config);
105
+ }
68
106
  async request(method, urlPath, params) {
69
107
  const url = `${this.baseUrl}/${urlPath}`;
70
108
  let response;
71
109
  const hasBody = method !== "GET" && params !== void 0;
72
110
  const headers = {
73
- Authorization: `Bearer ${this.apiKey}`
111
+ Authorization: `Bearer ${await this.authTokenManager.getToken()}`
74
112
  };
75
113
  if (hasBody) {
76
114
  headers["Content-Type"] = "application/json";
@@ -119,6 +157,12 @@ const validateArrayRequestParams = (data, primaryKeyName) => {
119
157
  });
120
158
  };
121
159
 
160
+ const zs_NormalizedUsage = zod.z.object({
161
+ promptTokens: zod.z.number(),
162
+ completionTokens: zod.z.number(),
163
+ totalTokens: zod.z.number()
164
+ }).strict();
165
+
122
166
  const zs_ResponseRecord = (primaryKeyName, outputKey, outputSchema) => {
123
167
  const primaryKeySchema = zod.z.any();
124
168
  const shape = {
@@ -141,7 +185,8 @@ const createNuaApiResponseCastArray = (primaryKeyName, outputKey, outputSchema)
141
185
  cacheHits: zod.z.number(),
142
186
  rowsWithNoResults: zod.z.array(zod.z.string()),
143
187
  isSuccess: zod.z.literal(true),
144
- isError: zod.z.optional(zod.z.literal(false))
188
+ isError: zod.z.optional(zod.z.literal(false)),
189
+ usage: zs_NormalizedUsage
145
190
  }).strict();
146
191
  };
147
192
  const zs_NuaApiResponse_CastArray = createNuaApiResponseCastArray;
@@ -203,7 +248,7 @@ const createArrayFn = (client, inputFnDef) => {
203
248
  return { error: String(response.error), isError: true };
204
249
  return void 0;
205
250
  };
206
- const baseFn = async (data, primaryKeyName) => {
251
+ const queueFn = async (data, primaryKeyName) => {
207
252
  validateArrayRequestParams(data, primaryKeyName);
208
253
  const response = await client.request(
209
254
  "POST",
@@ -225,7 +270,7 @@ const createArrayFn = (client, inputFnDef) => {
225
270
  }
226
271
  return parsedResponse.data;
227
272
  };
228
- const nowFn = async (data, primaryKeyName) => {
273
+ const baseNowFn = async (data, primaryKeyName) => {
229
274
  validateArrayRequestParams(data, primaryKeyName);
230
275
  const response = await client.request(
231
276
  "POST",
@@ -257,11 +302,12 @@ const createArrayFn = (client, inputFnDef) => {
257
302
  primaryKeyName
258
303
  ),
259
304
  rowsWithNoResults: parsedResponse.data.rowsWithNoResults,
260
- cacheHits: parsedResponse.data.cacheHits
305
+ cacheHits: parsedResponse.data.cacheHits,
306
+ usage: parsedResponse.data.usage
261
307
  };
262
308
  };
263
- return Object.assign(baseFn, {
264
- now: nowFn
309
+ return Object.assign(baseNowFn, {
310
+ queue: queueFn
265
311
  });
266
312
  };
267
313
 
@@ -272,7 +318,8 @@ const createNuaApiResponseCastValue = (outputKey, outputSchema) => {
272
318
  data: outputSchema,
273
319
  isCacheHit: zod.z.boolean(),
274
320
  isSuccess: zod.z.literal(true),
275
- isError: zod.z.optional(zod.z.literal(false))
321
+ isError: zod.z.optional(zod.z.literal(false)),
322
+ usage: zs_NormalizedUsage
276
323
  }).strict();
277
324
  };
278
325
  const zs_NuaApiResponse_CastValue = createNuaApiResponseCastValue;
@@ -319,7 +366,7 @@ const createValueFn = (client, inputFnDef) => {
319
366
  path,
320
367
  toCastValueApiRequest(fnDef.prompt, data, fnDef.output.name, outputJsonSchema)
321
368
  );
322
- const baseFn = async (data) => {
369
+ const queueFn = async (data) => {
323
370
  const response = await sendRequest("cast/value", data);
324
371
  const error = toNuabaseError(response);
325
372
  if (error) return error;
@@ -330,7 +377,7 @@ const createValueFn = (client, inputFnDef) => {
330
377
  }
331
378
  return parsedResponse.data;
332
379
  };
333
- const nowFn = async (data) => {
380
+ const baseNowFn = async (data) => {
334
381
  const response = await sendRequest("cast/value/now", data);
335
382
  const error = toNuabaseError(response);
336
383
  if (error) return error;
@@ -349,11 +396,12 @@ const createValueFn = (client, inputFnDef) => {
349
396
  llmRequestId: parsedResponse.data.llmRequestId,
350
397
  kind: parsedResponse.data.kind,
351
398
  data: parsedResponse.data.data,
352
- isCacheHit: parsedResponse.data.isCacheHit
399
+ isCacheHit: parsedResponse.data.isCacheHit,
400
+ usage: parsedResponse.data.usage
353
401
  };
354
402
  };
355
- return Object.assign(baseFn, {
356
- now: nowFn
403
+ return Object.assign(baseNowFn, {
404
+ queue: queueFn
357
405
  });
358
406
  };
359
407
 
@@ -53,22 +53,60 @@ function getErrorMessageFromException(error) {
53
53
  return String(error);
54
54
  }
55
55
 
56
- class NuabaseAPIClient {
57
- constructor(config = {}) {
58
- this.apiKey = resolveConfigValue(config, "apiKey", "NUABASE_API_KEY") || "";
59
- this.baseUrl = resolveConfigValue(config, "baseUrl", "NUABASE_API_URL") || "https://api.nuabase.com";
60
- if (!this.apiKey) {
56
+ const isBrowserEnvironment = () => typeof window !== "undefined" && !!window.document;
57
+ class NuabaseAuthTokenManager {
58
+ constructor(config) {
59
+ this.apiKey = resolveConfigValue(config, "apiKey", "NUABASE_API_KEY") || void 0;
60
+ this.fetchToken = config.fetchToken;
61
+ if (this.apiKey && this.fetchToken) {
62
+ throw new Error("Provide either an apiKey or a fetchToken function, but not both.");
63
+ }
64
+ if (!this.apiKey && !this.fetchToken) {
61
65
  throw new Error(
62
- "API key is required. Provide it via config.apiKey or NUABASE_API_KEY environment variable."
66
+ "Authentication is required. Provide config.apiKey/NUABASE_API_KEY or a fetchToken function."
67
+ );
68
+ }
69
+ if (this.apiKey && isBrowserEnvironment()) {
70
+ throw new Error(
71
+ "found config.apiKey. It is a private secret that must only be used in server environments."
63
72
  );
64
73
  }
65
74
  }
75
+ async getToken() {
76
+ if (this.apiKey) {
77
+ return this.apiKey;
78
+ }
79
+ if (!this.fetchToken) {
80
+ throw new Error("Unable to resolve API token because no fetchToken function is configured.");
81
+ }
82
+ if (this.apiToken) {
83
+ return this.apiToken;
84
+ }
85
+ if (!this.pendingTokenPromise) {
86
+ this.pendingTokenPromise = this.fetchToken().then((token) => {
87
+ if (!token) {
88
+ throw new Error("fetchToken must resolve a non-empty API token.");
89
+ }
90
+ this.apiToken = token;
91
+ return token;
92
+ }).finally(() => {
93
+ this.pendingTokenPromise = void 0;
94
+ });
95
+ }
96
+ return this.pendingTokenPromise;
97
+ }
98
+ }
99
+ class NuabaseAPIClient {
100
+ constructor(config = {}) {
101
+ this.baseUrl = resolveConfigValue(config, "baseUrl", "NUABASE_API_URL") || "https://api.nuabase.com";
102
+ this.authTokenManager = new NuabaseAuthTokenManager(config);
103
+ }
66
104
  async request(method, urlPath, params) {
67
105
  const url = `${this.baseUrl}/${urlPath}`;
68
106
  let response;
69
107
  const hasBody = method !== "GET" && params !== void 0;
70
108
  const headers = {
71
- Authorization: `Bearer ${this.apiKey}`
109
+ Authorization: `Bearer ${await this.authTokenManager.getToken()}`
72
110
  };
73
111
  if (hasBody) {
74
112
  headers["Content-Type"] = "application/json";
@@ -117,6 +155,12 @@ const validateArrayRequestParams = (data, primaryKeyName) => {
117
155
  });
118
156
  };
119
157
 
158
+ const zs_NormalizedUsage = z.object({
159
+ promptTokens: z.number(),
160
+ completionTokens: z.number(),
161
+ totalTokens: z.number()
162
+ }).strict();
163
+
120
164
  const zs_ResponseRecord = (primaryKeyName, outputKey, outputSchema) => {
121
165
  const primaryKeySchema = z.any();
122
166
  const shape = {
@@ -139,7 +183,8 @@ const createNuaApiResponseCastArray = (primaryKeyName, outputKey, outputSchema)
139
183
  cacheHits: z.number(),
140
184
  rowsWithNoResults: z.array(z.string()),
141
185
  isSuccess: z.literal(true),
142
- isError: z.optional(z.literal(false))
186
+ isError: z.optional(z.literal(false)),
187
+ usage: zs_NormalizedUsage
143
188
  }).strict();
144
189
  };
145
190
  const zs_NuaApiResponse_CastArray = createNuaApiResponseCastArray;
@@ -201,7 +246,7 @@ const createArrayFn = (client, inputFnDef) => {
201
246
  return { error: String(response.error), isError: true };
202
247
  return void 0;
203
248
  };
204
- const baseFn = async (data, primaryKeyName) => {
249
+ const queueFn = async (data, primaryKeyName) => {
205
250
  validateArrayRequestParams(data, primaryKeyName);
206
251
  const response = await client.request(
207
252
  "POST",
@@ -223,7 +268,7 @@ const createArrayFn = (client, inputFnDef) => {
223
268
  }
224
269
  return parsedResponse.data;
225
270
  };
226
- const nowFn = async (data, primaryKeyName) => {
271
+ const baseNowFn = async (data, primaryKeyName) => {
227
272
  validateArrayRequestParams(data, primaryKeyName);
228
273
  const response = await client.request(
229
274
  "POST",
@@ -255,11 +300,12 @@ const createArrayFn = (client, inputFnDef) => {
255
300
  primaryKeyName
256
301
  ),
257
302
  rowsWithNoResults: parsedResponse.data.rowsWithNoResults,
258
- cacheHits: parsedResponse.data.cacheHits
303
+ cacheHits: parsedResponse.data.cacheHits,
304
+ usage: parsedResponse.data.usage
259
305
  };
260
306
  };
261
- return Object.assign(baseFn, {
262
- now: nowFn
307
+ return Object.assign(baseNowFn, {
308
+ queue: queueFn
263
309
  });
264
310
  };
265
311
 
@@ -270,7 +316,8 @@ const createNuaApiResponseCastValue = (outputKey, outputSchema) => {
270
316
  data: outputSchema,
271
317
  isCacheHit: z.boolean(),
272
318
  isSuccess: z.literal(true),
273
- isError: z.optional(z.literal(false))
319
+ isError: z.optional(z.literal(false)),
320
+ usage: zs_NormalizedUsage
274
321
  }).strict();
275
322
  };
276
323
  const zs_NuaApiResponse_CastValue = createNuaApiResponseCastValue;
@@ -317,7 +364,7 @@ const createValueFn = (client, inputFnDef) => {
317
364
  path,
318
365
  toCastValueApiRequest(fnDef.prompt, data, fnDef.output.name, outputJsonSchema)
319
366
  );
320
- const baseFn = async (data) => {
367
+ const queueFn = async (data) => {
321
368
  const response = await sendRequest("cast/value", data);
322
369
  const error = toNuabaseError(response);
323
370
  if (error) return error;
@@ -328,7 +375,7 @@ const createValueFn = (client, inputFnDef) => {
328
375
  }
329
376
  return parsedResponse.data;
330
377
  };
331
- const nowFn = async (data) => {
378
+ const baseNowFn = async (data) => {
332
379
  const response = await sendRequest("cast/value/now", data);
333
380
  const error = toNuabaseError(response);
334
381
  if (error) return error;
@@ -347,11 +394,12 @@ const createValueFn = (client, inputFnDef) => {
347
394
  llmRequestId: parsedResponse.data.llmRequestId,
348
395
  kind: parsedResponse.data.kind,
349
396
  data: parsedResponse.data.data,
350
- isCacheHit: parsedResponse.data.isCacheHit
397
+ isCacheHit: parsedResponse.data.isCacheHit,
398
+ usage: parsedResponse.data.usage
351
399
  };
352
400
  };
353
- return Object.assign(baseFn, {
354
- now: nowFn
401
+ return Object.assign(baseNowFn, {
402
+ queue: queueFn
355
403
  });
356
404
  };
357
405
 
@@ -1,11 +1,19 @@
1
1
  import { NuabaseError } from './error-response';
2
- export type NuabaseConfig = {
2
+ type NuabaseApiKeyConfig = {
3
3
  apiKey?: string;
4
+ fetchToken?: never;
4
5
  baseUrl?: string;
5
6
  };
7
+ type NuabaseTokenConfig = {
8
+ fetchToken: () => Promise<string>;
9
+ apiKey?: never;
10
+ baseUrl?: string;
11
+ };
12
+ export type NuabaseConfig = NuabaseApiKeyConfig | NuabaseTokenConfig;
6
13
  export declare class NuabaseAPIClient {
7
- private readonly apiKey;
8
14
  private readonly baseUrl;
15
+ private readonly authTokenManager;
9
16
  constructor(config?: NuabaseConfig);
10
17
  request(method: 'GET' | 'POST', urlPath: string, params?: object): Promise<NuabaseError | unknown>;
11
18
  }
19
+ export {};
@@ -1,3 +1,4 @@
1
+ import { NormalizedUsage } from '../common/normalized-usage';
1
2
  import { z } from 'zod';
2
3
  export type UserDataPKValue = string | number;
3
4
  export type PrimaryKeyedInputRecord<PrimaryKeyName extends string> = Record<PrimaryKeyName, UserDataPKValue> & Record<string, unknown>;
@@ -10,6 +11,7 @@ type NuaApiResponseShape<OutputZodSchema extends z.ZodTypeAny, OutputName extend
10
11
  rowsWithNoResults: UserDataPKValue[];
11
12
  isSuccess: true;
12
13
  isError?: false;
14
+ usage: NormalizedUsage;
13
15
  };
14
16
  type NuaApiResponseCastArrayBuilder = <OutputZodSchema extends z.ZodTypeAny, OutputName extends string, PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>>(primaryKeyName: PrimaryKeyName, outputKey: OutputName, outputSchema: OutputZodSchema) => z.ZodType<NuaApiResponseShape<OutputZodSchema, OutputName, PrimaryKeyName, InputRecord>>;
15
17
  export declare const zs_NuaApiResponse_CastArray: NuaApiResponseCastArrayBuilder;
@@ -27,7 +27,7 @@ export type CastArraySuccessWithSource<OutputZodSchema extends z.ZodTypeAny, Out
27
27
  export type ArrayFnResult<OutputZodSchema extends z.ZodTypeAny, OutputName extends string, PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>> = NuabaseError | CastArraySuccessWithSource<OutputZodSchema, OutputName, PrimaryKeyName, InputRecord>;
28
28
  export type ArrayFnQueuedResult = NuabaseError | NuaQueuedResponse;
29
29
  export type ArrayFn<OutputZodSchema extends z.ZodTypeAny, OutputName extends string> = {
30
- <PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>>(data: InputRecord[], primaryKeyName: PrimaryKeyName): Promise<ArrayFnQueuedResult>;
31
- now: <PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>>(data: InputRecord[], primaryKeyName: PrimaryKeyName) => Promise<ArrayFnResult<OutputZodSchema, OutputName, PrimaryKeyName, InputRecord>>;
30
+ <PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>>(data: InputRecord[], primaryKeyName: PrimaryKeyName): Promise<ArrayFnResult<OutputZodSchema, OutputName, PrimaryKeyName, InputRecord>>;
31
+ queue: <PrimaryKeyName extends string, InputRecord extends PrimaryKeyedInputRecord<PrimaryKeyName>>(data: InputRecord[], primaryKeyName: PrimaryKeyName) => Promise<ArrayFnQueuedResult>;
32
32
  };
33
33
  export {};
@@ -1,3 +1,4 @@
1
+ import { NormalizedUsage } from '../common/normalized-usage';
1
2
  import { z } from 'zod';
2
3
  type NuaApiResponseShape<OutputZodSchema extends z.ZodTypeAny> = {
3
4
  llmRequestId: string;
@@ -6,6 +7,7 @@ type NuaApiResponseShape<OutputZodSchema extends z.ZodTypeAny> = {
6
7
  isCacheHit: boolean;
7
8
  isSuccess: true;
8
9
  isError?: false;
10
+ usage: NormalizedUsage;
9
11
  };
10
12
  type NuaApiResponseCastValueBuilder = <OutputZodSchema extends z.ZodTypeAny, OutputName extends string>(outputKey: OutputName, outputSchema: OutputZodSchema) => z.ZodType<NuaApiResponseShape<OutputZodSchema>>;
11
13
  export declare const zs_NuaApiResponse_CastValue: NuaApiResponseCastValueBuilder;
@@ -13,6 +13,6 @@ export declare const validateValueFnDef: <OutputName extends string, OutputZodSc
13
13
  export type ValueFnResult<OutputZodSchema extends z.ZodTypeAny, OutputName extends string> = NuabaseError | NuaApiResponse_CastValue<OutputZodSchema, OutputName>;
14
14
  export type ValueFnQueuedResult = NuabaseError | NuaQueuedResponse;
15
15
  export type ValueFn<OutputZodSchema extends z.ZodTypeAny, OutputName extends string> = {
16
- (data: unknown): Promise<ValueFnQueuedResult>;
17
- now: (data: unknown) => Promise<ValueFnResult<OutputZodSchema, OutputName>>;
16
+ (data: unknown): Promise<ValueFnResult<OutputZodSchema, OutputName>>;
17
+ queue: (data: unknown) => Promise<ValueFnQueuedResult>;
18
18
  };
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ export type NormalizedUsage = {
3
+ promptTokens: number;
4
+ completionTokens: number;
5
+ totalTokens: number;
6
+ };
7
+ export declare const zs_NormalizedUsage: z.ZodType<NormalizedUsage>;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "nuabase",
3
3
  "description": "Nuabase TypeScript client to create typed functions from LLM prompts",
4
4
  "packageManager": "yarn@4.10.3+sha512.c38cafb5c7bb273f3926d04e55e1d8c9dfa7d9c3ea1f36a4868fa028b9e5f72298f0b7f401ad5eb921749eb012eb1c3bb74bf7503df3ee43fd600d14a018266f",
5
- "version": "1.1.0",
5
+ "version": "1.2.0",
6
6
  "type": "module",
7
7
  "author": "Jasim A Basheer <jasim@nuabase.com>",
8
8
  "engines": {