@wishknish/knishio-client-ts 0.8.1 → 0.8.3
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/dist/index.cjs +42 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.iife.js +42 -12
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +42 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/KnishIOClient.ts +65 -9
- package/src/libraries/GraphQLClient.ts +7 -4
- package/src/schemas/index.ts +2 -1
- package/src/types/index.ts +13 -0
- package/src/validation/schemas.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wishknish/knishio-client-ts",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"productName": "Knish.IO TypeScript SDK Client",
|
|
5
5
|
"description": "TypeScript implementation of the Knish.IO SDK to consume Knish.IO GraphQL APIs with enhanced type safety.",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
package/src/KnishIOClient.ts
CHANGED
|
@@ -136,7 +136,8 @@ import type {
|
|
|
136
136
|
MetaType,
|
|
137
137
|
MetaId,
|
|
138
138
|
BatchId,
|
|
139
|
-
MetaFilter
|
|
139
|
+
MetaFilter,
|
|
140
|
+
RequestPolicy
|
|
140
141
|
} from '@/types'
|
|
141
142
|
|
|
142
143
|
/**
|
|
@@ -152,6 +153,10 @@ export default class KnishIOClient {
|
|
|
152
153
|
private $__client!: GraphQLClient
|
|
153
154
|
private $__serverSdkVersion: number = 3
|
|
154
155
|
private $__logging: boolean = false
|
|
156
|
+
// Default urql request policy applied to reads when the caller doesn't pass
|
|
157
|
+
// one. null = urql's default (cache-first). Server/sync clients set this to
|
|
158
|
+
// 'network-only' so a long-lived client never serves a stale cached read.
|
|
159
|
+
private $__defaultRequestPolicy: RequestPolicy | null = null
|
|
155
160
|
private $__authTokenObjects: Record<string, AuthToken | null> = {}
|
|
156
161
|
private $__authToken: AuthToken | null = null
|
|
157
162
|
private $__authInProcess: boolean = false
|
|
@@ -176,6 +181,7 @@ export default class KnishIOClient {
|
|
|
176
181
|
socket?: { socketUri: string | null; appKey?: string } | null
|
|
177
182
|
serverSdkVersion?: number
|
|
178
183
|
logging?: boolean
|
|
184
|
+
defaultRequestPolicy?: RequestPolicy | null
|
|
179
185
|
}) {
|
|
180
186
|
// Phase 2 Enhancement: Use standardized configuration validation
|
|
181
187
|
const standardValidationResult = ConfigValidator.validateClientConfig(config)
|
|
@@ -213,14 +219,19 @@ export default class KnishIOClient {
|
|
|
213
219
|
serverSdkVersion = 3,
|
|
214
220
|
logging = false
|
|
215
221
|
} = validatedConfig
|
|
216
|
-
|
|
222
|
+
// Read from the RAW config: defaultRequestPolicy is an optional add-on the
|
|
223
|
+
// strict schema now permits, but the validated/inferred shape may not carry
|
|
224
|
+
// it depending on the parser, so take it straight from the caller's config.
|
|
225
|
+
const defaultRequestPolicy = (config.defaultRequestPolicy ?? null) as RequestPolicy | null
|
|
226
|
+
|
|
217
227
|
this.initialize({
|
|
218
228
|
uri: uri as string | string[],
|
|
219
229
|
cellSlug: cellSlug as string | null,
|
|
220
230
|
socket: socket as { socketUri: string | null; appKey?: string } | null,
|
|
221
231
|
client: client as GraphQLClient | null,
|
|
222
232
|
serverSdkVersion,
|
|
223
|
-
logging
|
|
233
|
+
logging,
|
|
234
|
+
defaultRequestPolicy
|
|
224
235
|
})
|
|
225
236
|
}
|
|
226
237
|
|
|
@@ -233,7 +244,8 @@ export default class KnishIOClient {
|
|
|
233
244
|
socket = null,
|
|
234
245
|
client = null,
|
|
235
246
|
serverSdkVersion = 3,
|
|
236
|
-
logging = false
|
|
247
|
+
logging = false,
|
|
248
|
+
defaultRequestPolicy = null
|
|
237
249
|
}: {
|
|
238
250
|
uri: string | string[]
|
|
239
251
|
cellSlug?: string | null
|
|
@@ -241,6 +253,7 @@ export default class KnishIOClient {
|
|
|
241
253
|
client?: GraphQLClient | null
|
|
242
254
|
serverSdkVersion?: number
|
|
243
255
|
logging?: boolean
|
|
256
|
+
defaultRequestPolicy?: RequestPolicy | null
|
|
244
257
|
}): void {
|
|
245
258
|
this.reset()
|
|
246
259
|
|
|
@@ -269,6 +282,9 @@ export default class KnishIOClient {
|
|
|
269
282
|
})
|
|
270
283
|
|
|
271
284
|
this.$__serverSdkVersion = serverSdkVersion
|
|
285
|
+
// Config (not session state) — set here, NOT cleared in reset(), mirroring
|
|
286
|
+
// serverSdkVersion. A re-initialize updates it.
|
|
287
|
+
this.$__defaultRequestPolicy = defaultRequestPolicy
|
|
272
288
|
}
|
|
273
289
|
|
|
274
290
|
/**
|
|
@@ -324,6 +340,22 @@ export default class KnishIOClient {
|
|
|
324
340
|
return this.$__serverSdkVersion
|
|
325
341
|
}
|
|
326
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Gets the client's default urql request policy (null = urql default).
|
|
345
|
+
*/
|
|
346
|
+
getDefaultRequestPolicy(): RequestPolicy | null {
|
|
347
|
+
return this.$__defaultRequestPolicy
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Sets the default urql request policy applied to reads that don't specify
|
|
352
|
+
* one. Pass 'network-only' on a long-lived server/sync client so it never
|
|
353
|
+
* serves a stale cached read; null restores urql's default (cache-first).
|
|
354
|
+
*/
|
|
355
|
+
setDefaultRequestPolicy(policy: RequestPolicy | null): void {
|
|
356
|
+
this.$__defaultRequestPolicy = policy
|
|
357
|
+
}
|
|
358
|
+
|
|
327
359
|
/**
|
|
328
360
|
* Reset common properties
|
|
329
361
|
*/
|
|
@@ -568,7 +600,11 @@ export default class KnishIOClient {
|
|
|
568
600
|
/**
|
|
569
601
|
* Executes a query or mutation
|
|
570
602
|
*/
|
|
571
|
-
async executeQuery(
|
|
603
|
+
async executeQuery(
|
|
604
|
+
query: Query | Mutation,
|
|
605
|
+
variables: Record<string, any> | null = null,
|
|
606
|
+
context: Record<string, any> = {}
|
|
607
|
+
): Promise<Response | null> {
|
|
572
608
|
// Check and refresh authorization token if needed
|
|
573
609
|
// Guard with $__authInProcess to prevent recursive auth refresh
|
|
574
610
|
if (this.$__authToken && this.$__authToken.isExpired() && !this.$__authInProcess) {
|
|
@@ -581,6 +617,8 @@ export default class KnishIOClient {
|
|
|
581
617
|
}
|
|
582
618
|
|
|
583
619
|
if (query instanceof MutationProposeMolecule) {
|
|
620
|
+
// Molecule submissions are writes — never cached, so no request-policy
|
|
621
|
+
// context applies; MutationProposeMolecule.execute takes only variables.
|
|
584
622
|
return await this.withMoleculeLock(async () => {
|
|
585
623
|
const response = await query.execute({ variables: variables || {} })
|
|
586
624
|
this.handlePositionDrift(response)
|
|
@@ -588,8 +626,18 @@ export default class KnishIOClient {
|
|
|
588
626
|
})
|
|
589
627
|
}
|
|
590
628
|
|
|
591
|
-
// Execute the query
|
|
592
|
-
|
|
629
|
+
// Execute the query/mutation, forwarding any urql context (e.g.
|
|
630
|
+
// requestPolicy) assembled by the caller (queryMeta) / createQueryContext().
|
|
631
|
+
// When the caller did NOT specify a request policy, fall back to this
|
|
632
|
+
// client's defaultRequestPolicy (e.g. a long-lived server/sync client set
|
|
633
|
+
// to 'network-only' so it never serves a stale read from the urql cache —
|
|
634
|
+
// removing the footgun of having to pass network-only on every call).
|
|
635
|
+
// Precedence: per-call context.requestPolicy > client default > a query's
|
|
636
|
+
// own createQueryContext() (e.g. ContinuId) > urql default.
|
|
637
|
+
const effectiveContext = (this.$__defaultRequestPolicy && !(context as Record<string, any>).requestPolicy)
|
|
638
|
+
? { requestPolicy: this.$__defaultRequestPolicy, ...context }
|
|
639
|
+
: context
|
|
640
|
+
return await query.execute({ variables: variables || {}, context: effectiveContext })
|
|
593
641
|
}
|
|
594
642
|
|
|
595
643
|
/**
|
|
@@ -1038,7 +1086,8 @@ export default class KnishIOClient {
|
|
|
1038
1086
|
throughMolecule = false,
|
|
1039
1087
|
values = null,
|
|
1040
1088
|
keys = null,
|
|
1041
|
-
atomValues = null
|
|
1089
|
+
atomValues = null,
|
|
1090
|
+
requestPolicy = null
|
|
1042
1091
|
}: {
|
|
1043
1092
|
metaType: MetaType | string
|
|
1044
1093
|
metaId?: MetaId | string | null
|
|
@@ -1055,6 +1104,12 @@ export default class KnishIOClient {
|
|
|
1055
1104
|
values?: any[] | null
|
|
1056
1105
|
keys?: string[] | null
|
|
1057
1106
|
atomValues?: any[] | null
|
|
1107
|
+
/**
|
|
1108
|
+
* urql request policy for this read. Pass 'network-only' to bypass the
|
|
1109
|
+
* client's in-memory cache (e.g. sync engines that must see the current
|
|
1110
|
+
* ledger state). Default null = urql's default (cache-first).
|
|
1111
|
+
*/
|
|
1112
|
+
requestPolicy?: 'cache-first' | 'cache-only' | 'network-only' | 'cache-and-network' | null
|
|
1058
1113
|
}): Promise<Response> {
|
|
1059
1114
|
this.log('info', `KnishIOClient::queryMeta() - Querying metaType: ${metaType}, metaId: ${metaId}...`)
|
|
1060
1115
|
|
|
@@ -1109,7 +1164,8 @@ export default class KnishIOClient {
|
|
|
1109
1164
|
})
|
|
1110
1165
|
}
|
|
1111
1166
|
|
|
1112
|
-
|
|
1167
|
+
const context = requestPolicy ? { requestPolicy } : {}
|
|
1168
|
+
return this.executeQuery(query, variables, context) as Promise<Response>
|
|
1113
1169
|
}
|
|
1114
1170
|
|
|
1115
1171
|
/**
|
|
@@ -159,18 +159,21 @@ export default class GraphQLClient implements IGraphQLClient {
|
|
|
159
159
|
async query<TResult = unknown>(
|
|
160
160
|
request: GraphQLRequest
|
|
161
161
|
): Promise<GraphQLResponse<TResult>> {
|
|
162
|
-
const { query, variables } = request
|
|
163
|
-
|
|
162
|
+
const { query, variables, context } = request
|
|
163
|
+
// Forward the urql context (e.g. requestPolicy: 'network-only'). Without
|
|
164
|
+
// this 3rd arg urql ignores requestPolicy and defaults to cache-first,
|
|
165
|
+
// serving stale results from a long-lived client's in-memory cache.
|
|
166
|
+
const result = await this.$__client.query(query, variables || {}, context).toPromise()
|
|
164
167
|
return this.formatResponse<TResult>(result)
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
async mutation<TResult = unknown>(
|
|
168
171
|
request: GraphQLRequest
|
|
169
172
|
): Promise<GraphQLResponse<TResult>> {
|
|
170
|
-
const { query, variables } = request
|
|
173
|
+
const { query, variables, context } = request
|
|
171
174
|
// Support both query and mutation properties for backward compatibility
|
|
172
175
|
const mutationString = (request as any).mutation || query
|
|
173
|
-
const result = await this.$__client.mutation(mutationString, variables || {}).toPromise()
|
|
176
|
+
const result = await this.$__client.mutation(mutationString, variables || {}, context).toPromise()
|
|
174
177
|
return this.formatResponse<TResult>(result)
|
|
175
178
|
}
|
|
176
179
|
|
package/src/schemas/index.ts
CHANGED
|
@@ -191,7 +191,8 @@ export const KnishIOClientConfigSchema = z.object({
|
|
|
191
191
|
client: z.unknown().optional(),
|
|
192
192
|
socket: z.unknown().optional(),
|
|
193
193
|
serverSdkVersion: z.number().int().min(1).optional(),
|
|
194
|
-
logging: z.boolean().optional()
|
|
194
|
+
logging: z.boolean().optional(),
|
|
195
|
+
defaultRequestPolicy: z.enum(['cache-first', 'cache-only', 'network-only', 'cache-and-network']).nullable().optional()
|
|
195
196
|
}).strict()
|
|
196
197
|
|
|
197
198
|
// =============================================================================
|
package/src/types/index.ts
CHANGED
|
@@ -371,10 +371,23 @@ export interface SignatureResult {
|
|
|
371
371
|
// GRAPHQL OPERATION TYPES
|
|
372
372
|
// =============================================================================
|
|
373
373
|
|
|
374
|
+
/**
|
|
375
|
+
* urql request policy (mirrors @urql/core's RequestPolicy). Controls whether a
|
|
376
|
+
* read hits the client's in-memory cache. 'network-only' bypasses it entirely.
|
|
377
|
+
*/
|
|
378
|
+
export type RequestPolicy = 'cache-first' | 'cache-only' | 'network-only' | 'cache-and-network'
|
|
379
|
+
|
|
374
380
|
export interface GraphQLRequest {
|
|
375
381
|
query: string
|
|
376
382
|
variables?: Record<string, unknown>
|
|
377
383
|
operationName?: string | null
|
|
384
|
+
/**
|
|
385
|
+
* Per-operation urql context (e.g. `{ requestPolicy: 'network-only' }`).
|
|
386
|
+
* Built by Query.execute() from createQueryContext() + per-call context and
|
|
387
|
+
* MUST be forwarded to the urql client, or requestPolicy is silently ignored
|
|
388
|
+
* and urql falls back to its default cache-first policy.
|
|
389
|
+
*/
|
|
390
|
+
context?: Record<string, unknown>
|
|
378
391
|
}
|
|
379
392
|
|
|
380
393
|
export interface GraphQLResponse<T = unknown> {
|
|
@@ -206,7 +206,11 @@ export const KnishIOClientConfigSchema = z.object({
|
|
|
206
206
|
client: z.unknown().optional(),
|
|
207
207
|
socket: z.unknown().optional(),
|
|
208
208
|
serverSdkVersion: z.number().int().min(1).max(10).default(4),
|
|
209
|
-
logging: z.boolean().default(false)
|
|
209
|
+
logging: z.boolean().default(false),
|
|
210
|
+
// Optional default urql request policy for reads (server/sync clients pass
|
|
211
|
+
// 'network-only'). Permitted by the strict schema so the constructor option
|
|
212
|
+
// isn't rejected.
|
|
213
|
+
defaultRequestPolicy: z.enum(['cache-first', 'cache-only', 'network-only', 'cache-and-network']).nullable().optional()
|
|
210
214
|
}).strict()
|
|
211
215
|
|
|
212
216
|
// Environment configuration with validation
|