@gqloom/core 0.9.5 → 0.9.7

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.
@@ -434,27 +434,30 @@ interface SubscriptionNeedResolve<TOutput extends GraphQLSilk, TInput extends Gr
434
434
  resolve(resolve: (value: TValue, input: InferInputO<TInput>, payload: ResolverPayload | undefined) => MayPromise<StandardSchemaV1.InferOutput<TOutput>>): Subscription<TOutput, TInput, TValue>;
435
435
  }
436
436
  declare class QueryFactoryWithResolve<TInputO, TOutput extends GraphQLSilk, TInput extends GraphQLSilk<TInputO>> extends BaseChainFactory<Query<TOutput, TInput>> implements Query<TOutput, TInput> {
437
- protected output: TOutput;
437
+ protected outputSilk: TOutput;
438
438
  protected readonly options: QueryOptions<TOutput, TInput>;
439
439
  get "~meta"(): Query<TOutput, TInput>["~meta"];
440
- constructor(output: TOutput, options: QueryOptions<TOutput, TInput>);
440
+ constructor(outputSilk: TOutput, options: QueryOptions<TOutput, TInput>);
441
441
  protected clone(options?: Partial<typeof this.options> | undefined): this;
442
442
  input<TInputNew extends GraphQLSilk<TInputO>>(input: TInputNew): QueryFactoryWithResolve<TInputO, TOutput, TInputNew>;
443
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): QueryFactoryWithResolve<TInputO, TOutputNew, TInput>;
443
444
  }
444
445
  declare class MutationFactoryWithResolve<TInputO, TOutput extends GraphQLSilk, TInput extends GraphQLSilk<TInputO>> extends BaseChainFactory<Query<TOutput, TInput>> implements Mutation<TOutput, TInput> {
445
- protected output: TOutput;
446
+ protected outputSilk: TOutput;
446
447
  protected readonly options: MutationOptions<TOutput, TInput>;
447
448
  get "~meta"(): Mutation<TOutput, TInput>["~meta"];
448
- constructor(output: TOutput, options: MutationOptions<TOutput, TInput>);
449
+ constructor(outputSilk: TOutput, options: MutationOptions<TOutput, TInput>);
449
450
  protected clone(options?: Partial<typeof this.options> | undefined): this;
450
451
  input<TInputNew extends GraphQLSilk<TInputO>>(input: TInputNew): MutationFactoryWithResolve<TInputO, TOutput, TInputNew>;
452
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): MutationFactoryWithResolve<TInputO, TOutputNew, TInput>;
451
453
  }
452
454
  declare class FieldFactoryWithResolve<TParent extends GraphQLSilk, TOutput extends GraphQLSilk> extends BaseChainFactory<Field<TParent, TOutput, undefined, string[] | undefined>> {
453
- protected output: TOutput;
455
+ protected outputSilk: TOutput;
454
456
  protected readonly options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>;
455
457
  get "~meta"(): Field<TParent, TOutput, undefined, string[] | undefined>["~meta"];
456
- constructor(output: TOutput, options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>);
458
+ constructor(outputSilk: TOutput, options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>);
457
459
  protected clone(options?: Partial<typeof this.options> | undefined): this;
460
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): FieldFactoryWithResolve<TParent, TOutputNew>;
458
461
  }
459
462
 
460
463
  interface FieldMeta extends GraphQLFieldOptions {
@@ -434,27 +434,30 @@ interface SubscriptionNeedResolve<TOutput extends GraphQLSilk, TInput extends Gr
434
434
  resolve(resolve: (value: TValue, input: InferInputO<TInput>, payload: ResolverPayload | undefined) => MayPromise<StandardSchemaV1.InferOutput<TOutput>>): Subscription<TOutput, TInput, TValue>;
435
435
  }
436
436
  declare class QueryFactoryWithResolve<TInputO, TOutput extends GraphQLSilk, TInput extends GraphQLSilk<TInputO>> extends BaseChainFactory<Query<TOutput, TInput>> implements Query<TOutput, TInput> {
437
- protected output: TOutput;
437
+ protected outputSilk: TOutput;
438
438
  protected readonly options: QueryOptions<TOutput, TInput>;
439
439
  get "~meta"(): Query<TOutput, TInput>["~meta"];
440
- constructor(output: TOutput, options: QueryOptions<TOutput, TInput>);
440
+ constructor(outputSilk: TOutput, options: QueryOptions<TOutput, TInput>);
441
441
  protected clone(options?: Partial<typeof this.options> | undefined): this;
442
442
  input<TInputNew extends GraphQLSilk<TInputO>>(input: TInputNew): QueryFactoryWithResolve<TInputO, TOutput, TInputNew>;
443
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): QueryFactoryWithResolve<TInputO, TOutputNew, TInput>;
443
444
  }
444
445
  declare class MutationFactoryWithResolve<TInputO, TOutput extends GraphQLSilk, TInput extends GraphQLSilk<TInputO>> extends BaseChainFactory<Query<TOutput, TInput>> implements Mutation<TOutput, TInput> {
445
- protected output: TOutput;
446
+ protected outputSilk: TOutput;
446
447
  protected readonly options: MutationOptions<TOutput, TInput>;
447
448
  get "~meta"(): Mutation<TOutput, TInput>["~meta"];
448
- constructor(output: TOutput, options: MutationOptions<TOutput, TInput>);
449
+ constructor(outputSilk: TOutput, options: MutationOptions<TOutput, TInput>);
449
450
  protected clone(options?: Partial<typeof this.options> | undefined): this;
450
451
  input<TInputNew extends GraphQLSilk<TInputO>>(input: TInputNew): MutationFactoryWithResolve<TInputO, TOutput, TInputNew>;
452
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): MutationFactoryWithResolve<TInputO, TOutputNew, TInput>;
451
453
  }
452
454
  declare class FieldFactoryWithResolve<TParent extends GraphQLSilk, TOutput extends GraphQLSilk> extends BaseChainFactory<Field<TParent, TOutput, undefined, string[] | undefined>> {
453
- protected output: TOutput;
455
+ protected outputSilk: TOutput;
454
456
  protected readonly options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>;
455
457
  get "~meta"(): Field<TParent, TOutput, undefined, string[] | undefined>["~meta"];
456
- constructor(output: TOutput, options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>);
458
+ constructor(outputSilk: TOutput, options: FieldOptions<TParent, TOutput, undefined, string[] | undefined>);
457
459
  protected clone(options?: Partial<typeof this.options> | undefined): this;
460
+ output<TOutputNew extends GraphQLSilk>(output: TOutputNew, transform: (output: StandardSchemaV1.InferOutput<TOutput>) => MayPromise<StandardSchemaV1.InferOutput<TOutputNew>>): FieldFactoryWithResolve<TParent, TOutputNew>;
458
461
  }
459
462
 
460
463
  interface FieldMeta extends GraphQLFieldOptions {
@@ -1,4 +1,4 @@
1
- import { P as OnlyMemoizationPayload, R as ResolverPayload, B as BaseField, v as Middleware, K as ResolvingFields } from './context-DpbzXubn.cjs';
1
+ import { P as OnlyMemoizationPayload, R as ResolverPayload, B as BaseField, v as Middleware, K as ResolvingFields } from './context-D0Bwgtgg.cjs';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import 'graphql';
4
4
 
package/dist/context.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as OnlyMemoizationPayload, R as ResolverPayload, B as BaseField, v as Middleware, K as ResolvingFields } from './context-DpbzXubn.js';
1
+ import { P as OnlyMemoizationPayload, R as ResolverPayload, B as BaseField, v as Middleware, K as ResolvingFields } from './context-D0Bwgtgg.js';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import 'graphql';
4
4
 
package/dist/index.cjs CHANGED
@@ -22,10 +22,11 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  BaseChainFactory: () => BaseChainFactory,
24
24
  ChainResolver: () => ChainResolver,
25
- EasyDataLoader: () => EasyDataLoader,
25
+ EasyDataLoader: () => LoomDataLoader,
26
26
  FieldChainFactory: () => FieldChainFactory,
27
27
  FieldFactoryWithResolve: () => FieldFactoryWithResolve,
28
28
  GraphQLSchemaLoom: () => GraphQLSchemaLoom,
29
+ LoomDataLoader: () => LoomDataLoader,
29
30
  LoomObjectType: () => LoomObjectType,
30
31
  MutationChainFactory: () => MutationChainFactory,
31
32
  MutationFactoryWithResolve: () => MutationFactoryWithResolve,
@@ -410,48 +411,46 @@ function markLocation(message, ...locations) {
410
411
  }
411
412
 
412
413
  // src/utils/loader.ts
413
- var EasyDataLoader = class _EasyDataLoader {
414
+ var LoomDataLoader = class _LoomDataLoader {
414
415
  constructor(batchLoadFn) {
415
416
  this.batchLoadFn = batchLoadFn;
416
- this.queue = [];
417
- this.cache = /* @__PURE__ */ new Map();
417
+ this.results = /* @__PURE__ */ new Map();
418
418
  this.resolvers = /* @__PURE__ */ new Map();
419
419
  }
420
- queue;
421
- cache;
420
+ results;
422
421
  resolvers;
422
+ /**
423
+ * Load data for a given key.
424
+ * @param key - The key to load data for.
425
+ * @returns A promise that resolves to the loaded data.
426
+ */
423
427
  load(key) {
424
- const existing = this.cache.get(key);
428
+ const existing = this.results.get(key);
425
429
  if (existing) return existing;
426
430
  const promise = new Promise((resolve, reject) => {
427
- this.queue.push(key);
428
431
  this.resolvers.set(key, [resolve, reject]);
429
432
  this.nextTickBatchLoad();
430
433
  });
431
- this.cache.set(key, promise);
434
+ this.results.set(key, promise);
432
435
  return promise;
433
436
  }
437
+ /**
438
+ * Clear the cache and reset the loader.
439
+ */
434
440
  clear() {
435
- this.queue = [];
436
- this.cache = /* @__PURE__ */ new Map();
441
+ this.results = /* @__PURE__ */ new Map();
437
442
  this.resolvers = /* @__PURE__ */ new Map();
438
443
  }
439
- clearByKey(key) {
440
- this.queue = this.queue.filter((k) => k !== key);
441
- this.cache.delete(key);
442
- this.resolvers.delete(key);
443
- }
444
444
  async executeBatchLoad() {
445
- if (this.queue.length === 0) return;
446
- const [keys, resolvers] = [this.queue, this.resolvers];
447
- this.queue = [];
445
+ if (this.resolvers.size === 0) return;
446
+ const resolvers = this.resolvers;
448
447
  this.resolvers = /* @__PURE__ */ new Map();
448
+ const keys = Array.from(resolvers.keys());
449
449
  try {
450
450
  const list = await this.batchLoadFn(keys);
451
451
  for (let i = 0; i < list.length; i++) {
452
452
  const data = list[i];
453
- const resolve = resolvers.get(keys[i])?.[0];
454
- const reject = resolvers.get(keys[i])?.[1];
453
+ const [resolve, reject] = resolvers.get(keys[i]) ?? [];
455
454
  if (data instanceof Error) {
456
455
  reject?.(data);
457
456
  } else {
@@ -467,7 +466,17 @@ var EasyDataLoader = class _EasyDataLoader {
467
466
  }
468
467
  nextTickPromise;
469
468
  nextTickBatchLoad() {
470
- this.nextTickPromise ??= _EasyDataLoader.nextTick().then(() => this.executeBatchLoad()).finally(() => this.nextTickPromise = void 0);
469
+ const load = async () => {
470
+ try {
471
+ while (this.resolvers.size > 0) {
472
+ await _LoomDataLoader.nextTick();
473
+ await this.executeBatchLoad();
474
+ }
475
+ } finally {
476
+ this.nextTickPromise = void 0;
477
+ }
478
+ };
479
+ this.nextTickPromise ??= load();
471
480
  return this.nextTickPromise;
472
481
  }
473
482
  static nextTick() {
@@ -902,7 +911,7 @@ var FieldChainFactory = class _FieldChainFactory extends BaseChainFactory {
902
911
  load(resolve) {
903
912
  if (!this.options?.output) throw new Error("Output is required");
904
913
  const hasInput = typeof this.options.input !== "undefined";
905
- const initLoader = () => new EasyDataLoader((args) => {
914
+ const initLoader = () => new LoomDataLoader((args) => {
906
915
  const parents = args.map(
907
916
  ([parent, input]) => hasInput ? [parent, input] : parent
908
917
  );
@@ -1101,64 +1110,91 @@ var SubscriptionChainFactory = class _SubscriptionChainFactory extends BaseChain
1101
1110
  }
1102
1111
  };
1103
1112
  var QueryFactoryWithResolve = class _QueryFactoryWithResolve extends BaseChainFactory {
1104
- constructor(output, options) {
1113
+ constructor(outputSilk, options) {
1105
1114
  super(options);
1106
- this.output = output;
1115
+ this.outputSilk = outputSilk;
1107
1116
  this.options = options;
1108
1117
  }
1109
1118
  get "~meta"() {
1110
- return loom.query(this.output, this.options)["~meta"];
1119
+ return loom.query(this.outputSilk, this.options)["~meta"];
1111
1120
  }
1112
1121
  clone(options) {
1113
- return new _QueryFactoryWithResolve(this.output, {
1122
+ return new _QueryFactoryWithResolve(this.outputSilk, {
1114
1123
  ...this.options,
1115
1124
  ...options
1116
1125
  });
1117
1126
  }
1118
1127
  input(input) {
1119
- return new _QueryFactoryWithResolve(this.output, {
1128
+ return new _QueryFactoryWithResolve(this.outputSilk, {
1120
1129
  ...this.options,
1121
1130
  input
1122
1131
  });
1123
1132
  }
1133
+ output(output, transform) {
1134
+ return new _QueryFactoryWithResolve(output, {
1135
+ ...this.options,
1136
+ middlewares: [
1137
+ ...this.options.middlewares ?? [],
1138
+ async (next) => transform(await next())
1139
+ ]
1140
+ });
1141
+ }
1124
1142
  };
1125
1143
  var MutationFactoryWithResolve = class _MutationFactoryWithResolve extends BaseChainFactory {
1126
- constructor(output, options) {
1144
+ constructor(outputSilk, options) {
1127
1145
  super(options);
1128
- this.output = output;
1146
+ this.outputSilk = outputSilk;
1129
1147
  this.options = options;
1130
1148
  }
1131
1149
  get "~meta"() {
1132
- return loom.mutation(this.output, this.options)["~meta"];
1150
+ return loom.mutation(this.outputSilk, this.options)["~meta"];
1133
1151
  }
1134
1152
  clone(options) {
1135
- return new _MutationFactoryWithResolve(this.output, {
1153
+ return new _MutationFactoryWithResolve(this.outputSilk, {
1136
1154
  ...this.options,
1137
1155
  ...options
1138
1156
  });
1139
1157
  }
1140
1158
  input(input) {
1141
- return new _MutationFactoryWithResolve(this.output, {
1159
+ return new _MutationFactoryWithResolve(this.outputSilk, {
1142
1160
  ...this.options,
1143
1161
  input
1144
1162
  });
1145
1163
  }
1164
+ output(output, transform) {
1165
+ return new _MutationFactoryWithResolve(output, {
1166
+ ...this.options,
1167
+ middlewares: [
1168
+ ...this.options.middlewares ?? [],
1169
+ async (next) => transform(await next())
1170
+ ]
1171
+ });
1172
+ }
1146
1173
  };
1147
1174
  var FieldFactoryWithResolve = class _FieldFactoryWithResolve extends BaseChainFactory {
1148
- constructor(output, options) {
1175
+ constructor(outputSilk, options) {
1149
1176
  super(options);
1150
- this.output = output;
1177
+ this.outputSilk = outputSilk;
1151
1178
  this.options = options;
1152
1179
  }
1153
1180
  get "~meta"() {
1154
- return loom.field(this.output, this.options)["~meta"];
1181
+ return loom.field(this.outputSilk, this.options)["~meta"];
1155
1182
  }
1156
1183
  clone(options) {
1157
- return new _FieldFactoryWithResolve(this.output, {
1184
+ return new _FieldFactoryWithResolve(this.outputSilk, {
1158
1185
  ...this.options,
1159
1186
  ...options
1160
1187
  });
1161
1188
  }
1189
+ output(output, transform) {
1190
+ return new _FieldFactoryWithResolve(output, {
1191
+ ...this.options,
1192
+ middlewares: [
1193
+ ...this.options.middlewares ?? [],
1194
+ async (next) => transform(await next())
1195
+ ]
1196
+ });
1197
+ }
1162
1198
  };
1163
1199
 
1164
1200
  // src/resolver/resolver.ts
@@ -2014,6 +2050,7 @@ function ensureInterfaceType(gqlType, interfaceConfig) {
2014
2050
  FieldChainFactory,
2015
2051
  FieldFactoryWithResolve,
2016
2052
  GraphQLSchemaLoom,
2053
+ LoomDataLoader,
2017
2054
  LoomObjectType,
2018
2055
  MutationChainFactory,
2019
2056
  MutationFactoryWithResolve,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldOptions, Q as QueryOptions, M as MutationOptions, R as ResolverPayload, S as SubscriptionOptions, G as GraphQLFieldOptions, a as StandardSchemaV1, b as GraphQLSilk, c as MayPromise, d as Query, e as QueryChainFactory, f as QueryFactoryWithChain, g as Mutation, h as MutationChainFactory, i as MutationFactoryWithChain, j as Field, k as FieldChainFactory, l as FieldFactoryWithUtils, m as SubscriptionChainFactory, n as Subscription, o as SubscriptionFactoryWithChain, O as Operation, p as FIELD_HIDDEN, q as ResolverOptionsWithExtensions, r as OmitInUnion, V as ValueOf, s as ResolverOptions, t as FieldOrOperation, u as Resolver, I as IS_RESOLVER, v as Middleware, w as InferInputI, W as WEAVER_CONFIG, B as BaseField } from './context-DpbzXubn.cjs';
2
- export { $ as BaseChainFactory, ai as CallableInputParser, D as CallableMiddlewareOptions, _ as ChainFactoryOptions, ae as FieldFactory, a4 as FieldFactoryWithResolve, ag as FieldMeta, a9 as FieldOrOperationType, Z as IChainFactory, aa as InferFieldInput, ab as InferFieldOutput, ah as InferInputO, y as IsAny, a5 as Loom, E as MiddlewareConfig, A as MiddlewareOperation, C as MiddlewareOptions, ad as MutationFactory, a3 as MutationFactoryWithResolve, P as OnlyMemoizationPayload, a8 as OperationType, ac as QueryFactory, a2 as QueryFactoryWithResolve, z as RequireKeys, a0 as ResolvableSubscription, a6 as ResolverOptionsWithParent, K as ResolvingFields, a7 as ResolvingOptions, x as SYMBOLS, af as SubscriptionFactory, a1 as SubscriptionNeedResolve, H as applyMiddlewares, Y as assignContextMap, aj as createInputParser, J as filterMiddlewares, X as getMemoizationMap, L as getResolvingFields, al as getStandardValue, U as isOnlyMemoryPayload, T as onlyMemoization, ak as parseInputValue, N as parseResolvingFields } from './context-DpbzXubn.cjs';
1
+ import { F as FieldOptions, Q as QueryOptions, M as MutationOptions, R as ResolverPayload, S as SubscriptionOptions, G as GraphQLFieldOptions, a as StandardSchemaV1, b as GraphQLSilk, c as MayPromise, d as Query, e as QueryChainFactory, f as QueryFactoryWithChain, g as Mutation, h as MutationChainFactory, i as MutationFactoryWithChain, j as Field, k as FieldChainFactory, l as FieldFactoryWithUtils, m as SubscriptionChainFactory, n as Subscription, o as SubscriptionFactoryWithChain, O as Operation, p as FIELD_HIDDEN, q as ResolverOptionsWithExtensions, r as OmitInUnion, V as ValueOf, s as ResolverOptions, t as FieldOrOperation, u as Resolver, I as IS_RESOLVER, v as Middleware, w as InferInputI, W as WEAVER_CONFIG, B as BaseField } from './context-D0Bwgtgg.cjs';
2
+ export { $ as BaseChainFactory, ai as CallableInputParser, D as CallableMiddlewareOptions, _ as ChainFactoryOptions, ae as FieldFactory, a4 as FieldFactoryWithResolve, ag as FieldMeta, a9 as FieldOrOperationType, Z as IChainFactory, aa as InferFieldInput, ab as InferFieldOutput, ah as InferInputO, y as IsAny, a5 as Loom, E as MiddlewareConfig, A as MiddlewareOperation, C as MiddlewareOptions, ad as MutationFactory, a3 as MutationFactoryWithResolve, P as OnlyMemoizationPayload, a8 as OperationType, ac as QueryFactory, a2 as QueryFactoryWithResolve, z as RequireKeys, a0 as ResolvableSubscription, a6 as ResolverOptionsWithParent, K as ResolvingFields, a7 as ResolvingOptions, x as SYMBOLS, af as SubscriptionFactory, a1 as SubscriptionNeedResolve, H as applyMiddlewares, Y as assignContextMap, aj as createInputParser, J as filterMiddlewares, X as getMemoizationMap, L as getResolvingFields, al as getStandardValue, U as isOnlyMemoryPayload, T as onlyMemoization, ak as parseInputValue, N as parseResolvingFields } from './context-D0Bwgtgg.cjs';
3
3
  import { GraphQLFieldExtensions, GraphQLScalarType, GraphQLObjectType, GraphQLOutputType, GraphQLNullableType, GraphQLList, GraphQLNonNull, GraphQLObjectTypeConfig, GraphQLUnionType, GraphQLInterfaceType, GraphQLInputObjectType, GraphQLFieldMap, GraphQLFieldConfig, GraphQLSchemaConfig, GraphQLNamedType, GraphQLSchema, GraphQLFieldConfigArgumentMap, GraphQLType, GraphQLInputType, GraphQLInterfaceTypeConfig } from 'graphql';
4
4
 
5
5
  declare function getOperationOptions(resolveOrOptions: ((...args: any) => any) | FieldOptions<any, any, any, any> | QueryOptions<any, any> | MutationOptions<any, any>): any;
@@ -271,18 +271,27 @@ declare function tryIn<T>(func: () => T, ...locations: string[]): T;
271
271
  declare function markLocation(message: string, ...locations: string[]): string;
272
272
 
273
273
  type BatchLoadFn<TKey, TData> = (keys: TKey[]) => Promise<(TData | Error)[]>;
274
- declare class EasyDataLoader<TKey, TData> {
274
+ /**
275
+ * GraphQL Loom built-in data loader.
276
+ */
277
+ declare class LoomDataLoader<TKey, TData> {
275
278
  protected readonly batchLoadFn: BatchLoadFn<TKey, TData>;
276
- protected queue: TKey[];
277
- protected cache: Map<TKey, Promise<TData>>;
279
+ protected results: Map<TKey, Promise<TData>>;
278
280
  protected resolvers: Map<TKey, [
279
281
  resolve: (value: TData | PromiseLike<TData>) => void,
280
282
  reject: (reason?: any) => void
281
283
  ]>;
282
284
  constructor(batchLoadFn: BatchLoadFn<TKey, TData>);
285
+ /**
286
+ * Load data for a given key.
287
+ * @param key - The key to load data for.
288
+ * @returns A promise that resolves to the loaded data.
289
+ */
283
290
  load(key: TKey): Promise<TData>;
291
+ /**
292
+ * Clear the cache and reset the loader.
293
+ */
284
294
  clear(): void;
285
- clearByKey(key: TKey): void;
286
295
  protected executeBatchLoad(): Promise<void>;
287
296
  protected nextTickPromise?: Promise<void>;
288
297
  protected nextTickBatchLoad(): Promise<void>;
@@ -467,4 +476,4 @@ interface GQLoomExtensionAttribute {
467
476
  directives?: string[];
468
477
  }
469
478
 
470
- export { BaseField, type BatchLoadFn, ChainResolver, type CoreSchemaWeaverConfig, type CoreSchemaWeaverConfigOptions, type DirectiveItem, type DirectiveRecord, EasyDataLoader, type Executor, Field, FieldChainFactory, FieldFactoryWithUtils, FieldOptions, FieldOrOperation, type GQLoomExtensionAttribute, type GQLoomExtensions, type GlobalWeaverContext, GraphQLFieldOptions, GraphQLSchemaLoom, GraphQLSilk, InferInputI, type ListSilk, LoomObjectType, MayPromise, Middleware, Mutation, MutationChainFactory, MutationFactoryWithChain, MutationOptions, type NonNullSilk, type NullableSilk, OPERATION_OBJECT_NAMES, ObjectChainResolver, OmitInUnion, Operation, Query, QueryChainFactory, QueryFactoryWithChain, QueryOptions, Resolver, type ResolverFactory, ResolverOptions, ResolverOptionsWithExtensions, ResolverPayload, type SchemaWeaver, StandardSchemaV1, Subscription, SubscriptionChainFactory, SubscriptionFactoryWithChain, SubscriptionOptions, type ToExecutorProps, ValueOf, type WeaverConfig, type WeaverContext, capitalize, collectName, collectNames, createField, createMutation, createQuery, createSubscription, deepMerge, defaultSubscriptionResolve, ensureInputObjectType, ensureInputType, ensureInterfaceType, field, getCacheType, getFieldOptions, getGraphQLType, getOperationOptions, getSubscriptionOptions, initWeaverContext, inputToArgs, isSchemaVendorWeaver, isSilk, listSilk, loom, mapValue, markErrorLocation, markLocation, meta, mutation, nonNullSilk, notNullish, nullableSilk, parseSilk, pascalCase, provideWeaverContext, query, resolver, screamingSnakeCase, silk, subscription, toObjMap, tryIn, weave, weaverContext };
479
+ export { BaseField, type BatchLoadFn, ChainResolver, type CoreSchemaWeaverConfig, type CoreSchemaWeaverConfigOptions, type DirectiveItem, type DirectiveRecord, LoomDataLoader as EasyDataLoader, type Executor, Field, FieldChainFactory, FieldFactoryWithUtils, FieldOptions, FieldOrOperation, type GQLoomExtensionAttribute, type GQLoomExtensions, type GlobalWeaverContext, GraphQLFieldOptions, GraphQLSchemaLoom, GraphQLSilk, InferInputI, type ListSilk, LoomDataLoader, LoomObjectType, MayPromise, Middleware, Mutation, MutationChainFactory, MutationFactoryWithChain, MutationOptions, type NonNullSilk, type NullableSilk, OPERATION_OBJECT_NAMES, ObjectChainResolver, OmitInUnion, Operation, Query, QueryChainFactory, QueryFactoryWithChain, QueryOptions, Resolver, type ResolverFactory, ResolverOptions, ResolverOptionsWithExtensions, ResolverPayload, type SchemaWeaver, StandardSchemaV1, Subscription, SubscriptionChainFactory, SubscriptionFactoryWithChain, SubscriptionOptions, type ToExecutorProps, ValueOf, type WeaverConfig, type WeaverContext, capitalize, collectName, collectNames, createField, createMutation, createQuery, createSubscription, deepMerge, defaultSubscriptionResolve, ensureInputObjectType, ensureInputType, ensureInterfaceType, field, getCacheType, getFieldOptions, getGraphQLType, getOperationOptions, getSubscriptionOptions, initWeaverContext, inputToArgs, isSchemaVendorWeaver, isSilk, listSilk, loom, mapValue, markErrorLocation, markLocation, meta, mutation, nonNullSilk, notNullish, nullableSilk, parseSilk, pascalCase, provideWeaverContext, query, resolver, screamingSnakeCase, silk, subscription, toObjMap, tryIn, weave, weaverContext };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldOptions, Q as QueryOptions, M as MutationOptions, R as ResolverPayload, S as SubscriptionOptions, G as GraphQLFieldOptions, a as StandardSchemaV1, b as GraphQLSilk, c as MayPromise, d as Query, e as QueryChainFactory, f as QueryFactoryWithChain, g as Mutation, h as MutationChainFactory, i as MutationFactoryWithChain, j as Field, k as FieldChainFactory, l as FieldFactoryWithUtils, m as SubscriptionChainFactory, n as Subscription, o as SubscriptionFactoryWithChain, O as Operation, p as FIELD_HIDDEN, q as ResolverOptionsWithExtensions, r as OmitInUnion, V as ValueOf, s as ResolverOptions, t as FieldOrOperation, u as Resolver, I as IS_RESOLVER, v as Middleware, w as InferInputI, W as WEAVER_CONFIG, B as BaseField } from './context-DpbzXubn.js';
2
- export { $ as BaseChainFactory, ai as CallableInputParser, D as CallableMiddlewareOptions, _ as ChainFactoryOptions, ae as FieldFactory, a4 as FieldFactoryWithResolve, ag as FieldMeta, a9 as FieldOrOperationType, Z as IChainFactory, aa as InferFieldInput, ab as InferFieldOutput, ah as InferInputO, y as IsAny, a5 as Loom, E as MiddlewareConfig, A as MiddlewareOperation, C as MiddlewareOptions, ad as MutationFactory, a3 as MutationFactoryWithResolve, P as OnlyMemoizationPayload, a8 as OperationType, ac as QueryFactory, a2 as QueryFactoryWithResolve, z as RequireKeys, a0 as ResolvableSubscription, a6 as ResolverOptionsWithParent, K as ResolvingFields, a7 as ResolvingOptions, x as SYMBOLS, af as SubscriptionFactory, a1 as SubscriptionNeedResolve, H as applyMiddlewares, Y as assignContextMap, aj as createInputParser, J as filterMiddlewares, X as getMemoizationMap, L as getResolvingFields, al as getStandardValue, U as isOnlyMemoryPayload, T as onlyMemoization, ak as parseInputValue, N as parseResolvingFields } from './context-DpbzXubn.js';
1
+ import { F as FieldOptions, Q as QueryOptions, M as MutationOptions, R as ResolverPayload, S as SubscriptionOptions, G as GraphQLFieldOptions, a as StandardSchemaV1, b as GraphQLSilk, c as MayPromise, d as Query, e as QueryChainFactory, f as QueryFactoryWithChain, g as Mutation, h as MutationChainFactory, i as MutationFactoryWithChain, j as Field, k as FieldChainFactory, l as FieldFactoryWithUtils, m as SubscriptionChainFactory, n as Subscription, o as SubscriptionFactoryWithChain, O as Operation, p as FIELD_HIDDEN, q as ResolverOptionsWithExtensions, r as OmitInUnion, V as ValueOf, s as ResolverOptions, t as FieldOrOperation, u as Resolver, I as IS_RESOLVER, v as Middleware, w as InferInputI, W as WEAVER_CONFIG, B as BaseField } from './context-D0Bwgtgg.js';
2
+ export { $ as BaseChainFactory, ai as CallableInputParser, D as CallableMiddlewareOptions, _ as ChainFactoryOptions, ae as FieldFactory, a4 as FieldFactoryWithResolve, ag as FieldMeta, a9 as FieldOrOperationType, Z as IChainFactory, aa as InferFieldInput, ab as InferFieldOutput, ah as InferInputO, y as IsAny, a5 as Loom, E as MiddlewareConfig, A as MiddlewareOperation, C as MiddlewareOptions, ad as MutationFactory, a3 as MutationFactoryWithResolve, P as OnlyMemoizationPayload, a8 as OperationType, ac as QueryFactory, a2 as QueryFactoryWithResolve, z as RequireKeys, a0 as ResolvableSubscription, a6 as ResolverOptionsWithParent, K as ResolvingFields, a7 as ResolvingOptions, x as SYMBOLS, af as SubscriptionFactory, a1 as SubscriptionNeedResolve, H as applyMiddlewares, Y as assignContextMap, aj as createInputParser, J as filterMiddlewares, X as getMemoizationMap, L as getResolvingFields, al as getStandardValue, U as isOnlyMemoryPayload, T as onlyMemoization, ak as parseInputValue, N as parseResolvingFields } from './context-D0Bwgtgg.js';
3
3
  import { GraphQLFieldExtensions, GraphQLScalarType, GraphQLObjectType, GraphQLOutputType, GraphQLNullableType, GraphQLList, GraphQLNonNull, GraphQLObjectTypeConfig, GraphQLUnionType, GraphQLInterfaceType, GraphQLInputObjectType, GraphQLFieldMap, GraphQLFieldConfig, GraphQLSchemaConfig, GraphQLNamedType, GraphQLSchema, GraphQLFieldConfigArgumentMap, GraphQLType, GraphQLInputType, GraphQLInterfaceTypeConfig } from 'graphql';
4
4
 
5
5
  declare function getOperationOptions(resolveOrOptions: ((...args: any) => any) | FieldOptions<any, any, any, any> | QueryOptions<any, any> | MutationOptions<any, any>): any;
@@ -271,18 +271,27 @@ declare function tryIn<T>(func: () => T, ...locations: string[]): T;
271
271
  declare function markLocation(message: string, ...locations: string[]): string;
272
272
 
273
273
  type BatchLoadFn<TKey, TData> = (keys: TKey[]) => Promise<(TData | Error)[]>;
274
- declare class EasyDataLoader<TKey, TData> {
274
+ /**
275
+ * GraphQL Loom built-in data loader.
276
+ */
277
+ declare class LoomDataLoader<TKey, TData> {
275
278
  protected readonly batchLoadFn: BatchLoadFn<TKey, TData>;
276
- protected queue: TKey[];
277
- protected cache: Map<TKey, Promise<TData>>;
279
+ protected results: Map<TKey, Promise<TData>>;
278
280
  protected resolvers: Map<TKey, [
279
281
  resolve: (value: TData | PromiseLike<TData>) => void,
280
282
  reject: (reason?: any) => void
281
283
  ]>;
282
284
  constructor(batchLoadFn: BatchLoadFn<TKey, TData>);
285
+ /**
286
+ * Load data for a given key.
287
+ * @param key - The key to load data for.
288
+ * @returns A promise that resolves to the loaded data.
289
+ */
283
290
  load(key: TKey): Promise<TData>;
291
+ /**
292
+ * Clear the cache and reset the loader.
293
+ */
284
294
  clear(): void;
285
- clearByKey(key: TKey): void;
286
295
  protected executeBatchLoad(): Promise<void>;
287
296
  protected nextTickPromise?: Promise<void>;
288
297
  protected nextTickBatchLoad(): Promise<void>;
@@ -467,4 +476,4 @@ interface GQLoomExtensionAttribute {
467
476
  directives?: string[];
468
477
  }
469
478
 
470
- export { BaseField, type BatchLoadFn, ChainResolver, type CoreSchemaWeaverConfig, type CoreSchemaWeaverConfigOptions, type DirectiveItem, type DirectiveRecord, EasyDataLoader, type Executor, Field, FieldChainFactory, FieldFactoryWithUtils, FieldOptions, FieldOrOperation, type GQLoomExtensionAttribute, type GQLoomExtensions, type GlobalWeaverContext, GraphQLFieldOptions, GraphQLSchemaLoom, GraphQLSilk, InferInputI, type ListSilk, LoomObjectType, MayPromise, Middleware, Mutation, MutationChainFactory, MutationFactoryWithChain, MutationOptions, type NonNullSilk, type NullableSilk, OPERATION_OBJECT_NAMES, ObjectChainResolver, OmitInUnion, Operation, Query, QueryChainFactory, QueryFactoryWithChain, QueryOptions, Resolver, type ResolverFactory, ResolverOptions, ResolverOptionsWithExtensions, ResolverPayload, type SchemaWeaver, StandardSchemaV1, Subscription, SubscriptionChainFactory, SubscriptionFactoryWithChain, SubscriptionOptions, type ToExecutorProps, ValueOf, type WeaverConfig, type WeaverContext, capitalize, collectName, collectNames, createField, createMutation, createQuery, createSubscription, deepMerge, defaultSubscriptionResolve, ensureInputObjectType, ensureInputType, ensureInterfaceType, field, getCacheType, getFieldOptions, getGraphQLType, getOperationOptions, getSubscriptionOptions, initWeaverContext, inputToArgs, isSchemaVendorWeaver, isSilk, listSilk, loom, mapValue, markErrorLocation, markLocation, meta, mutation, nonNullSilk, notNullish, nullableSilk, parseSilk, pascalCase, provideWeaverContext, query, resolver, screamingSnakeCase, silk, subscription, toObjMap, tryIn, weave, weaverContext };
479
+ export { BaseField, type BatchLoadFn, ChainResolver, type CoreSchemaWeaverConfig, type CoreSchemaWeaverConfigOptions, type DirectiveItem, type DirectiveRecord, LoomDataLoader as EasyDataLoader, type Executor, Field, FieldChainFactory, FieldFactoryWithUtils, FieldOptions, FieldOrOperation, type GQLoomExtensionAttribute, type GQLoomExtensions, type GlobalWeaverContext, GraphQLFieldOptions, GraphQLSchemaLoom, GraphQLSilk, InferInputI, type ListSilk, LoomDataLoader, LoomObjectType, MayPromise, Middleware, Mutation, MutationChainFactory, MutationFactoryWithChain, MutationOptions, type NonNullSilk, type NullableSilk, OPERATION_OBJECT_NAMES, ObjectChainResolver, OmitInUnion, Operation, Query, QueryChainFactory, QueryFactoryWithChain, QueryOptions, Resolver, type ResolverFactory, ResolverOptions, ResolverOptionsWithExtensions, ResolverPayload, type SchemaWeaver, StandardSchemaV1, Subscription, SubscriptionChainFactory, SubscriptionFactoryWithChain, SubscriptionOptions, type ToExecutorProps, ValueOf, type WeaverConfig, type WeaverContext, capitalize, collectName, collectNames, createField, createMutation, createQuery, createSubscription, deepMerge, defaultSubscriptionResolve, ensureInputObjectType, ensureInputType, ensureInterfaceType, field, getCacheType, getFieldOptions, getGraphQLType, getOperationOptions, getSubscriptionOptions, initWeaverContext, inputToArgs, isSchemaVendorWeaver, isSilk, listSilk, loom, mapValue, markErrorLocation, markLocation, meta, mutation, nonNullSilk, notNullish, nullableSilk, parseSilk, pascalCase, provideWeaverContext, query, resolver, screamingSnakeCase, silk, subscription, toObjMap, tryIn, weave, weaverContext };
package/dist/index.js CHANGED
@@ -169,48 +169,46 @@ function markLocation(message, ...locations) {
169
169
  }
170
170
 
171
171
  // src/utils/loader.ts
172
- var EasyDataLoader = class _EasyDataLoader {
172
+ var LoomDataLoader = class _LoomDataLoader {
173
173
  constructor(batchLoadFn) {
174
174
  this.batchLoadFn = batchLoadFn;
175
- this.queue = [];
176
- this.cache = /* @__PURE__ */ new Map();
175
+ this.results = /* @__PURE__ */ new Map();
177
176
  this.resolvers = /* @__PURE__ */ new Map();
178
177
  }
179
- queue;
180
- cache;
178
+ results;
181
179
  resolvers;
180
+ /**
181
+ * Load data for a given key.
182
+ * @param key - The key to load data for.
183
+ * @returns A promise that resolves to the loaded data.
184
+ */
182
185
  load(key) {
183
- const existing = this.cache.get(key);
186
+ const existing = this.results.get(key);
184
187
  if (existing) return existing;
185
188
  const promise = new Promise((resolve, reject) => {
186
- this.queue.push(key);
187
189
  this.resolvers.set(key, [resolve, reject]);
188
190
  this.nextTickBatchLoad();
189
191
  });
190
- this.cache.set(key, promise);
192
+ this.results.set(key, promise);
191
193
  return promise;
192
194
  }
195
+ /**
196
+ * Clear the cache and reset the loader.
197
+ */
193
198
  clear() {
194
- this.queue = [];
195
- this.cache = /* @__PURE__ */ new Map();
199
+ this.results = /* @__PURE__ */ new Map();
196
200
  this.resolvers = /* @__PURE__ */ new Map();
197
201
  }
198
- clearByKey(key) {
199
- this.queue = this.queue.filter((k) => k !== key);
200
- this.cache.delete(key);
201
- this.resolvers.delete(key);
202
- }
203
202
  async executeBatchLoad() {
204
- if (this.queue.length === 0) return;
205
- const [keys, resolvers] = [this.queue, this.resolvers];
206
- this.queue = [];
203
+ if (this.resolvers.size === 0) return;
204
+ const resolvers = this.resolvers;
207
205
  this.resolvers = /* @__PURE__ */ new Map();
206
+ const keys = Array.from(resolvers.keys());
208
207
  try {
209
208
  const list = await this.batchLoadFn(keys);
210
209
  for (let i = 0; i < list.length; i++) {
211
210
  const data = list[i];
212
- const resolve = resolvers.get(keys[i])?.[0];
213
- const reject = resolvers.get(keys[i])?.[1];
211
+ const [resolve, reject] = resolvers.get(keys[i]) ?? [];
214
212
  if (data instanceof Error) {
215
213
  reject?.(data);
216
214
  } else {
@@ -226,7 +224,17 @@ var EasyDataLoader = class _EasyDataLoader {
226
224
  }
227
225
  nextTickPromise;
228
226
  nextTickBatchLoad() {
229
- this.nextTickPromise ??= _EasyDataLoader.nextTick().then(() => this.executeBatchLoad()).finally(() => this.nextTickPromise = void 0);
227
+ const load = async () => {
228
+ try {
229
+ while (this.resolvers.size > 0) {
230
+ await _LoomDataLoader.nextTick();
231
+ await this.executeBatchLoad();
232
+ }
233
+ } finally {
234
+ this.nextTickPromise = void 0;
235
+ }
236
+ };
237
+ this.nextTickPromise ??= load();
230
238
  return this.nextTickPromise;
231
239
  }
232
240
  static nextTick() {
@@ -633,7 +641,7 @@ var FieldChainFactory = class _FieldChainFactory extends BaseChainFactory {
633
641
  load(resolve) {
634
642
  if (!this.options?.output) throw new Error("Output is required");
635
643
  const hasInput = typeof this.options.input !== "undefined";
636
- const initLoader = () => new EasyDataLoader((args) => {
644
+ const initLoader = () => new LoomDataLoader((args) => {
637
645
  const parents = args.map(
638
646
  ([parent, input]) => hasInput ? [parent, input] : parent
639
647
  );
@@ -832,64 +840,91 @@ var SubscriptionChainFactory = class _SubscriptionChainFactory extends BaseChain
832
840
  }
833
841
  };
834
842
  var QueryFactoryWithResolve = class _QueryFactoryWithResolve extends BaseChainFactory {
835
- constructor(output, options) {
843
+ constructor(outputSilk, options) {
836
844
  super(options);
837
- this.output = output;
845
+ this.outputSilk = outputSilk;
838
846
  this.options = options;
839
847
  }
840
848
  get "~meta"() {
841
- return loom.query(this.output, this.options)["~meta"];
849
+ return loom.query(this.outputSilk, this.options)["~meta"];
842
850
  }
843
851
  clone(options) {
844
- return new _QueryFactoryWithResolve(this.output, {
852
+ return new _QueryFactoryWithResolve(this.outputSilk, {
845
853
  ...this.options,
846
854
  ...options
847
855
  });
848
856
  }
849
857
  input(input) {
850
- return new _QueryFactoryWithResolve(this.output, {
858
+ return new _QueryFactoryWithResolve(this.outputSilk, {
851
859
  ...this.options,
852
860
  input
853
861
  });
854
862
  }
863
+ output(output, transform) {
864
+ return new _QueryFactoryWithResolve(output, {
865
+ ...this.options,
866
+ middlewares: [
867
+ ...this.options.middlewares ?? [],
868
+ async (next) => transform(await next())
869
+ ]
870
+ });
871
+ }
855
872
  };
856
873
  var MutationFactoryWithResolve = class _MutationFactoryWithResolve extends BaseChainFactory {
857
- constructor(output, options) {
874
+ constructor(outputSilk, options) {
858
875
  super(options);
859
- this.output = output;
876
+ this.outputSilk = outputSilk;
860
877
  this.options = options;
861
878
  }
862
879
  get "~meta"() {
863
- return loom.mutation(this.output, this.options)["~meta"];
880
+ return loom.mutation(this.outputSilk, this.options)["~meta"];
864
881
  }
865
882
  clone(options) {
866
- return new _MutationFactoryWithResolve(this.output, {
883
+ return new _MutationFactoryWithResolve(this.outputSilk, {
867
884
  ...this.options,
868
885
  ...options
869
886
  });
870
887
  }
871
888
  input(input) {
872
- return new _MutationFactoryWithResolve(this.output, {
889
+ return new _MutationFactoryWithResolve(this.outputSilk, {
873
890
  ...this.options,
874
891
  input
875
892
  });
876
893
  }
894
+ output(output, transform) {
895
+ return new _MutationFactoryWithResolve(output, {
896
+ ...this.options,
897
+ middlewares: [
898
+ ...this.options.middlewares ?? [],
899
+ async (next) => transform(await next())
900
+ ]
901
+ });
902
+ }
877
903
  };
878
904
  var FieldFactoryWithResolve = class _FieldFactoryWithResolve extends BaseChainFactory {
879
- constructor(output, options) {
905
+ constructor(outputSilk, options) {
880
906
  super(options);
881
- this.output = output;
907
+ this.outputSilk = outputSilk;
882
908
  this.options = options;
883
909
  }
884
910
  get "~meta"() {
885
- return loom.field(this.output, this.options)["~meta"];
911
+ return loom.field(this.outputSilk, this.options)["~meta"];
886
912
  }
887
913
  clone(options) {
888
- return new _FieldFactoryWithResolve(this.output, {
914
+ return new _FieldFactoryWithResolve(this.outputSilk, {
889
915
  ...this.options,
890
916
  ...options
891
917
  });
892
918
  }
919
+ output(output, transform) {
920
+ return new _FieldFactoryWithResolve(output, {
921
+ ...this.options,
922
+ middlewares: [
923
+ ...this.options.middlewares ?? [],
924
+ async (next) => transform(await next())
925
+ ]
926
+ });
927
+ }
893
928
  };
894
929
 
895
930
  // src/resolver/resolver.ts
@@ -1771,10 +1806,11 @@ function ensureInterfaceType(gqlType, interfaceConfig) {
1771
1806
  export {
1772
1807
  BaseChainFactory,
1773
1808
  ChainResolver,
1774
- EasyDataLoader,
1809
+ LoomDataLoader as EasyDataLoader,
1775
1810
  FieldChainFactory,
1776
1811
  FieldFactoryWithResolve,
1777
1812
  GraphQLSchemaLoom,
1813
+ LoomDataLoader,
1778
1814
  LoomObjectType,
1779
1815
  MutationChainFactory,
1780
1816
  MutationFactoryWithResolve,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gqloom/core",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "Create GraphQL schema and resolvers with TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",