@codecks/fetch 0.1.6 → 0.1.8

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.
@@ -1,7 +1,7 @@
1
- import "../query-type-B0L3hwCo.js";
2
- import "../index-obQtSRRg.js";
3
- import { FetchOptions } from "../loader-utils-rQFSDhwf.js";
4
- import { BaseRequester, MissingDataRequest } from "../loader-types-Y0OHlOEK.js";
1
+ import "../query-type-BqQ9oX_U.js";
2
+ import "../index-k-KPWV9R.js";
3
+ import { FetchOptions } from "../loader-utils-BqZKAn_v.js";
4
+ import { BaseRequester, MissingDataRequest } from "../loader-types-fd5tV0FD.js";
5
5
 
6
6
  //#region src/_exploration/api-requester.d.ts
7
7
  declare class ApiRequester implements BaseRequester {
@@ -1,5 +1,5 @@
1
1
  import { configuredFetch, ensureMapValue } from "../collection-utils-CYJaA1a9.js";
2
- import { serializeModel } from "../query-helpers-DgC42MEH.js";
2
+ import { serializeModel } from "../query-helpers-iX1fiqLv.js";
3
3
 
4
4
  //#region src/_exploration/utils/concurrency-limiter.ts
5
5
  var ConcurrencyLimiter = class {
@@ -108,11 +108,23 @@ var ApiRequester = class {
108
108
  key: "",
109
109
  partialInstance: instances
110
110
  });
111
- else for (const [id, data] of Object.entries(instances)) results.push({
112
- model: modelName,
113
- key: id,
114
- partialInstance: data
115
- });
111
+ else for (const [id, data] of Object.entries(instances)) {
112
+ if (data == null) {
113
+ const requested = dataByModel.get(modelName)?.get(id);
114
+ if (!requested) continue;
115
+ results.push({
116
+ model: modelName,
117
+ key: id,
118
+ partialInstance: Object.fromEntries([...requested.fields, ...requested.relations.keys()].map((key) => [key, null]))
119
+ });
120
+ continue;
121
+ }
122
+ results.push({
123
+ model: modelName,
124
+ key: id,
125
+ partialInstance: data
126
+ });
127
+ }
116
128
  return results;
117
129
  }
118
130
  };
@@ -1,8 +1,8 @@
1
- import { InferModelQuery, InferRelQuery, ModelDesc, ModelQuery, RelQuery, RelationEntry, TypedField } from "../query-type-B0L3hwCo.js";
2
- import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId } from "../index-obQtSRRg.js";
3
- import "../loader-types-Y0OHlOEK.js";
4
- import { _rootDesc$1 as _rootDesc } from "../_root-rBEjvjCJ.js";
5
- import { Store } from "../store-LSWKTuHv.js";
1
+ import { InferModelQuery, InferRelQuery, ModelDesc, ModelQuery, RelQuery, RelationEntry, TypedField } from "../query-type-BqQ9oX_U.js";
2
+ import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId } from "../index-k-KPWV9R.js";
3
+ import "../loader-types-fd5tV0FD.js";
4
+ import { _rootDesc$1 as _rootDesc } from "../_root-BW9uzB79.js";
5
+ import { Store } from "../store-BvEJzUVp.js";
6
6
 
7
7
  //#region src/_exploration/create-hooks.d.ts
8
8
  declare const createHooks: (store: Store) => {
@@ -808,6 +808,7 @@ declare const createHooks: (store: Store) => {
808
808
  }>;
809
809
  attachments: RelationEntry<"attachment", {
810
810
  readonly type: "hasMany";
811
+ readonly fkAsArray: true;
811
812
  }>;
812
813
  diffs: RelationEntry<"cardHistory", {
813
814
  readonly type: "hasMany";
@@ -820,15 +821,19 @@ declare const createHooks: (store: Store) => {
820
821
  }>;
821
822
  childCards: RelationEntry<"card", {
822
823
  readonly type: "hasMany";
824
+ readonly fkAsArray: true;
823
825
  }>;
824
826
  inDeps: RelationEntry<"card", {
825
827
  readonly type: "hasMany";
828
+ readonly fkAsArray: true;
826
829
  }>;
827
830
  outDeps: RelationEntry<"card", {
828
831
  readonly type: "hasMany";
832
+ readonly fkAsArray: true;
829
833
  }>;
830
834
  cardReferences: RelationEntry<"card", {
831
835
  readonly type: "hasMany";
836
+ readonly fkAsArray: true;
832
837
  }>;
833
838
  upvotes: RelationEntry<"cardUpvote", {
834
839
  readonly type: "hasMany";
@@ -2524,9 +2529,11 @@ declare const createHooks: (store: Store) => {
2524
2529
  }>;
2525
2530
  inDeps: RelationEntry<"workflowItem", {
2526
2531
  readonly type: "hasMany";
2532
+ readonly fkAsArray: true;
2527
2533
  }>;
2528
2534
  outDeps: RelationEntry<"workflowItem", {
2529
2535
  readonly type: "hasMany";
2536
+ readonly fkAsArray: true;
2530
2537
  }>;
2531
2538
  }, ["itemId"]>;
2532
2539
  }[K], {
@@ -3331,6 +3338,7 @@ declare const createHooks: (store: Store) => {
3331
3338
  }>;
3332
3339
  attachments: RelationEntry<"attachment", {
3333
3340
  readonly type: "hasMany";
3341
+ readonly fkAsArray: true;
3334
3342
  }>;
3335
3343
  diffs: RelationEntry<"cardHistory", {
3336
3344
  readonly type: "hasMany";
@@ -3343,15 +3351,19 @@ declare const createHooks: (store: Store) => {
3343
3351
  }>;
3344
3352
  childCards: RelationEntry<"card", {
3345
3353
  readonly type: "hasMany";
3354
+ readonly fkAsArray: true;
3346
3355
  }>;
3347
3356
  inDeps: RelationEntry<"card", {
3348
3357
  readonly type: "hasMany";
3358
+ readonly fkAsArray: true;
3349
3359
  }>;
3350
3360
  outDeps: RelationEntry<"card", {
3351
3361
  readonly type: "hasMany";
3362
+ readonly fkAsArray: true;
3352
3363
  }>;
3353
3364
  cardReferences: RelationEntry<"card", {
3354
3365
  readonly type: "hasMany";
3366
+ readonly fkAsArray: true;
3355
3367
  }>;
3356
3368
  upvotes: RelationEntry<"cardUpvote", {
3357
3369
  readonly type: "hasMany";
@@ -5047,9 +5059,11 @@ declare const createHooks: (store: Store) => {
5047
5059
  }>;
5048
5060
  inDeps: RelationEntry<"workflowItem", {
5049
5061
  readonly type: "hasMany";
5062
+ readonly fkAsArray: true;
5050
5063
  }>;
5051
5064
  outDeps: RelationEntry<"workflowItem", {
5052
5065
  readonly type: "hasMany";
5066
+ readonly fkAsArray: true;
5053
5067
  }>;
5054
5068
  }, ["itemId"]>;
5055
5069
  }>>(model: K, id: Id, q: Q) => InferModelQuery<{
@@ -5854,6 +5868,7 @@ declare const createHooks: (store: Store) => {
5854
5868
  }>;
5855
5869
  attachments: RelationEntry<"attachment", {
5856
5870
  readonly type: "hasMany";
5871
+ readonly fkAsArray: true;
5857
5872
  }>;
5858
5873
  diffs: RelationEntry<"cardHistory", {
5859
5874
  readonly type: "hasMany";
@@ -5866,15 +5881,19 @@ declare const createHooks: (store: Store) => {
5866
5881
  }>;
5867
5882
  childCards: RelationEntry<"card", {
5868
5883
  readonly type: "hasMany";
5884
+ readonly fkAsArray: true;
5869
5885
  }>;
5870
5886
  inDeps: RelationEntry<"card", {
5871
5887
  readonly type: "hasMany";
5888
+ readonly fkAsArray: true;
5872
5889
  }>;
5873
5890
  outDeps: RelationEntry<"card", {
5874
5891
  readonly type: "hasMany";
5892
+ readonly fkAsArray: true;
5875
5893
  }>;
5876
5894
  cardReferences: RelationEntry<"card", {
5877
5895
  readonly type: "hasMany";
5896
+ readonly fkAsArray: true;
5878
5897
  }>;
5879
5898
  upvotes: RelationEntry<"cardUpvote", {
5880
5899
  readonly type: "hasMany";
@@ -7570,9 +7589,11 @@ declare const createHooks: (store: Store) => {
7570
7589
  }>;
7571
7590
  inDeps: RelationEntry<"workflowItem", {
7572
7591
  readonly type: "hasMany";
7592
+ readonly fkAsArray: true;
7573
7593
  }>;
7574
7594
  outDeps: RelationEntry<"workflowItem", {
7575
7595
  readonly type: "hasMany";
7596
+ readonly fkAsArray: true;
7576
7597
  }>;
7577
7598
  }, ["itemId"]>;
7578
7599
  }[K], Q, {
@@ -8377,6 +8398,7 @@ declare const createHooks: (store: Store) => {
8377
8398
  }>;
8378
8399
  attachments: RelationEntry<"attachment", {
8379
8400
  readonly type: "hasMany";
8401
+ readonly fkAsArray: true;
8380
8402
  }>;
8381
8403
  diffs: RelationEntry<"cardHistory", {
8382
8404
  readonly type: "hasMany";
@@ -8389,15 +8411,19 @@ declare const createHooks: (store: Store) => {
8389
8411
  }>;
8390
8412
  childCards: RelationEntry<"card", {
8391
8413
  readonly type: "hasMany";
8414
+ readonly fkAsArray: true;
8392
8415
  }>;
8393
8416
  inDeps: RelationEntry<"card", {
8394
8417
  readonly type: "hasMany";
8418
+ readonly fkAsArray: true;
8395
8419
  }>;
8396
8420
  outDeps: RelationEntry<"card", {
8397
8421
  readonly type: "hasMany";
8422
+ readonly fkAsArray: true;
8398
8423
  }>;
8399
8424
  cardReferences: RelationEntry<"card", {
8400
8425
  readonly type: "hasMany";
8426
+ readonly fkAsArray: true;
8401
8427
  }>;
8402
8428
  upvotes: RelationEntry<"cardUpvote", {
8403
8429
  readonly type: "hasMany";
@@ -10093,9 +10119,11 @@ declare const createHooks: (store: Store) => {
10093
10119
  }>;
10094
10120
  inDeps: RelationEntry<"workflowItem", {
10095
10121
  readonly type: "hasMany";
10122
+ readonly fkAsArray: true;
10096
10123
  }>;
10097
10124
  outDeps: RelationEntry<"workflowItem", {
10098
10125
  readonly type: "hasMany";
10126
+ readonly fkAsArray: true;
10099
10127
  }>;
10100
10128
  }, ["itemId"]>;
10101
10129
  }>;
@@ -10901,6 +10929,7 @@ declare const createHooks: (store: Store) => {
10901
10929
  }>;
10902
10930
  attachments: RelationEntry<"attachment", {
10903
10931
  readonly type: "hasMany";
10932
+ readonly fkAsArray: true;
10904
10933
  }>;
10905
10934
  diffs: RelationEntry<"cardHistory", {
10906
10935
  readonly type: "hasMany";
@@ -10913,15 +10942,19 @@ declare const createHooks: (store: Store) => {
10913
10942
  }>;
10914
10943
  childCards: RelationEntry<"card", {
10915
10944
  readonly type: "hasMany";
10945
+ readonly fkAsArray: true;
10916
10946
  }>;
10917
10947
  inDeps: RelationEntry<"card", {
10918
10948
  readonly type: "hasMany";
10949
+ readonly fkAsArray: true;
10919
10950
  }>;
10920
10951
  outDeps: RelationEntry<"card", {
10921
10952
  readonly type: "hasMany";
10953
+ readonly fkAsArray: true;
10922
10954
  }>;
10923
10955
  cardReferences: RelationEntry<"card", {
10924
10956
  readonly type: "hasMany";
10957
+ readonly fkAsArray: true;
10925
10958
  }>;
10926
10959
  upvotes: RelationEntry<"cardUpvote", {
10927
10960
  readonly type: "hasMany";
@@ -12617,9 +12650,11 @@ declare const createHooks: (store: Store) => {
12617
12650
  }>;
12618
12651
  inDeps: RelationEntry<"workflowItem", {
12619
12652
  readonly type: "hasMany";
12653
+ readonly fkAsArray: true;
12620
12654
  }>;
12621
12655
  outDeps: RelationEntry<"workflowItem", {
12622
12656
  readonly type: "hasMany";
12657
+ readonly fkAsArray: true;
12623
12658
  }>;
12624
12659
  }, ["itemId"]>;
12625
12660
  }>>(q: Q) => InferRelQuery<typeof _rootDesc, Q, {
@@ -13424,6 +13459,7 @@ declare const createHooks: (store: Store) => {
13424
13459
  }>;
13425
13460
  attachments: RelationEntry<"attachment", {
13426
13461
  readonly type: "hasMany";
13462
+ readonly fkAsArray: true;
13427
13463
  }>;
13428
13464
  diffs: RelationEntry<"cardHistory", {
13429
13465
  readonly type: "hasMany";
@@ -13436,15 +13472,19 @@ declare const createHooks: (store: Store) => {
13436
13472
  }>;
13437
13473
  childCards: RelationEntry<"card", {
13438
13474
  readonly type: "hasMany";
13475
+ readonly fkAsArray: true;
13439
13476
  }>;
13440
13477
  inDeps: RelationEntry<"card", {
13441
13478
  readonly type: "hasMany";
13479
+ readonly fkAsArray: true;
13442
13480
  }>;
13443
13481
  outDeps: RelationEntry<"card", {
13444
13482
  readonly type: "hasMany";
13483
+ readonly fkAsArray: true;
13445
13484
  }>;
13446
13485
  cardReferences: RelationEntry<"card", {
13447
13486
  readonly type: "hasMany";
13487
+ readonly fkAsArray: true;
13448
13488
  }>;
13449
13489
  upvotes: RelationEntry<"cardUpvote", {
13450
13490
  readonly type: "hasMany";
@@ -15140,9 +15180,11 @@ declare const createHooks: (store: Store) => {
15140
15180
  }>;
15141
15181
  inDeps: RelationEntry<"workflowItem", {
15142
15182
  readonly type: "hasMany";
15183
+ readonly fkAsArray: true;
15143
15184
  }>;
15144
15185
  outDeps: RelationEntry<"workflowItem", {
15145
15186
  readonly type: "hasMany";
15187
+ readonly fkAsArray: true;
15146
15188
  }>;
15147
15189
  }, ["itemId"]>;
15148
15190
  }>;
@@ -1,4 +1,4 @@
1
- import { queryToKey } from "../query-helpers-DgC42MEH.js";
1
+ import { queryToKey } from "../query-helpers-iX1fiqLv.js";
2
2
  import { getFieldKey } from "../immediate-cache-DiH8tpJM.js";
3
3
  import { use, useSyncExternalStore } from "react";
4
4
 
@@ -1,5 +1,5 @@
1
- import "../query-type-B0L3hwCo.js";
2
- import { BaseLoader, BaseRequester, MissingDataRequest, OnLoadedFn } from "../loader-types-Y0OHlOEK.js";
1
+ import "../query-type-BqQ9oX_U.js";
2
+ import { BaseLoader, BaseRequester, MissingDataRequest, OnLoadedFn } from "../loader-types-fd5tV0FD.js";
3
3
 
4
4
  //#region src/_exploration/loader.d.ts
5
5
  type DataRequestWithKey = {
@@ -1,4 +1,4 @@
1
- import { serializeModel } from "../query-helpers-DgC42MEH.js";
1
+ import { serializeModel } from "../query-helpers-iX1fiqLv.js";
2
2
 
3
3
  //#region src/_exploration/loader.ts
4
4
  const notYetLoaded = () => {
@@ -1,5 +1,5 @@
1
- import "../query-type-B0L3hwCo.js";
2
- import "../index-obQtSRRg.js";
3
- import "../loader-types-Y0OHlOEK.js";
4
- import { Store } from "../store-LSWKTuHv.js";
1
+ import "../query-type-BqQ9oX_U.js";
2
+ import "../index-k-KPWV9R.js";
3
+ import "../loader-types-fd5tV0FD.js";
4
+ import { Store } from "../store-BvEJzUVp.js";
5
5
  export { Store };
@@ -1,4 +1,4 @@
1
- import { getRelKey, makeRelQuerySerializable, modelMap } from "../query-helpers-DgC42MEH.js";
1
+ import { getRelKey, makeRelQuerySerializable, modelMap } from "../query-helpers-iX1fiqLv.js";
2
2
  import { ImmediateCache } from "../immediate-cache-DiH8tpJM.js";
3
3
 
4
4
  //#region src/_exploration/store.ts
@@ -118,6 +118,9 @@ var Store = class {
118
118
  data[`~${fieldName}`] = cachedValue.value.map((v) => `${v}`);
119
119
  data[fieldName] = relationResults.map((result) => result.data);
120
120
  if (relationResults.some((result) => !result.allPresent)) allPresent = false;
121
+ } else if (cachedValue.value == null) {
122
+ data[`~${fieldName}`] = null;
123
+ data[fieldName] = null;
121
124
  } else {
122
125
  const relationResult = this.checkQueryRecursive(relatedModelDesc, relatedModel, `${cachedValue.value}`, relQuery, missingRequests, acceptDirty);
123
126
  data[`~${fieldName}`] = cachedValue.value != null ? `${cachedValue.value}` : null;
@@ -1,4 +1,4 @@
1
- import { ModelDesc, RelationEntry } from "./query-type-B0L3hwCo.js";
1
+ import { ModelDesc, RelationEntry } from "./query-type-BqQ9oX_U.js";
2
2
 
3
3
  //#region src/models/_root.d.ts
4
4
  declare const _rootDesc: ModelDesc<"_root", {}, {
@@ -1,4 +1,4 @@
1
- import { ModelDesc, Nominal, RelationEntry, TypedField } from "./query-type-B0L3hwCo.js";
1
+ import { ModelDesc, Nominal, RelationEntry, TypedField } from "./query-type-BqQ9oX_U.js";
2
2
 
3
3
  //#region src/models/AccountOnboardingStep.d.ts
4
4
  type AccountOnboardingStepId = Nominal<string, "accountOnboardingStep">;
@@ -947,6 +947,7 @@ declare const modelMap: {
947
947
  }>;
948
948
  attachments: RelationEntry<"attachment", {
949
949
  readonly type: "hasMany";
950
+ readonly fkAsArray: true;
950
951
  }>;
951
952
  diffs: RelationEntry<"cardHistory", {
952
953
  readonly type: "hasMany";
@@ -959,15 +960,19 @@ declare const modelMap: {
959
960
  }>;
960
961
  childCards: RelationEntry<"card", {
961
962
  readonly type: "hasMany";
963
+ readonly fkAsArray: true;
962
964
  }>;
963
965
  inDeps: RelationEntry<"card", {
964
966
  readonly type: "hasMany";
967
+ readonly fkAsArray: true;
965
968
  }>;
966
969
  outDeps: RelationEntry<"card", {
967
970
  readonly type: "hasMany";
971
+ readonly fkAsArray: true;
968
972
  }>;
969
973
  cardReferences: RelationEntry<"card", {
970
974
  readonly type: "hasMany";
975
+ readonly fkAsArray: true;
971
976
  }>;
972
977
  upvotes: RelationEntry<"cardUpvote", {
973
978
  readonly type: "hasMany";
@@ -2663,9 +2668,11 @@ declare const modelMap: {
2663
2668
  }>;
2664
2669
  inDeps: RelationEntry<"workflowItem", {
2665
2670
  readonly type: "hasMany";
2671
+ readonly fkAsArray: true;
2666
2672
  }>;
2667
2673
  outDeps: RelationEntry<"workflowItem", {
2668
2674
  readonly type: "hasMany";
2675
+ readonly fkAsArray: true;
2669
2676
  }>;
2670
2677
  }, ["itemId"]>;
2671
2678
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { InferModelQuery, InferRelQuery, Instance, ModelQuery, RelQuery } from "./query-type-B0L3hwCo.js";
2
- import { modelMap$1 as modelMap } from "./index-obQtSRRg.js";
3
- import { DataLoader, FetchOptions } from "./loader-utils-rQFSDhwf.js";
4
- import { _rootDesc$1 as _rootDesc } from "./_root-rBEjvjCJ.js";
1
+ import { InferModelQuery, InferRelQuery, Instance, ModelQuery, RelQuery } from "./query-type-BqQ9oX_U.js";
2
+ import { modelMap$1 as modelMap } from "./index-k-KPWV9R.js";
3
+ import { DataLoader, FetchOptions } from "./loader-utils-BqZKAn_v.js";
4
+ import { _rootDesc$1 as _rootDesc } from "./_root-BW9uzB79.js";
5
5
 
6
6
  //#region src/loaders/simple-loader.d.ts
7
7
  type SimpleLoaderOptions = FetchOptions;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { configuredFetch, ensureMapValue } from "./collection-utils-CYJaA1a9.js";
2
- import { _rootDesc, getRelKey, makeModelQuerySerializable, modelMap, serializeInstanceQuery } from "./query-helpers-DgC42MEH.js";
2
+ import { _rootDesc, getRelKey, makeModelQuerySerializable, modelMap, serializeInstanceQuery } from "./query-helpers-iX1fiqLv.js";
3
3
 
4
4
  //#region src/model-pool.ts
5
5
  const ROOT_ID = "";
@@ -41,6 +41,7 @@ var ModelPool = class {
41
41
  Object.entries(data).forEach(([modelName, payload]) => {
42
42
  if (modelName === _rootDesc.name) this.addModelInstance(modelName, ROOT_ID, payload);
43
43
  else Object.entries(payload).forEach(([id, payload$1]) => {
44
+ if (payload$1 == null) return;
44
45
  this.addModelInstance(modelName, id, payload$1);
45
46
  });
46
47
  });
@@ -53,10 +54,16 @@ var ModelPool = class {
53
54
 
54
55
  //#endregion
55
56
  //#region src/reconcile-query.ts
57
+ /**
58
+ * The API names an id but answers `null` for it when the token may not read that
59
+ * record. Such an id never enters the pool, and the caller can do nothing about it —
60
+ * unlike an id the response never mentioned at all, which points at a bug worth a warning.
61
+ */
62
+ const isWithheldByApi = (response, model, key) => response[model]?.[key] === null;
56
63
  const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
57
64
  const instance = store.get(instanceModel.name, key);
58
65
  if (!instance) {
59
- console.warn(`no instance found in pool: [${instanceModel.name}, ${key}]`);
66
+ if (!isWithheldByApi(response, instanceModel.name, key)) console.warn(`no instance found in pool: [${instanceModel.name}, ${key}]`);
60
67
  return null;
61
68
  }
62
69
  const result = instanceModel.name === "_root" ? {} : {
@@ -80,7 +87,7 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
80
87
  break;
81
88
  case "hasOne":
82
89
  result[`~${relName}`] = instance[relName] != null ? `${instance[relName]}` : null;
83
- result[relName] = reconcileInstanceQuery(relEntry, response, relModel, `${instance[relName]}`, store);
90
+ result[relName] = instance[relName] != null ? reconcileInstanceQuery(relEntry, response, relModel, `${instance[relName]}`, store) : null;
84
91
  break;
85
92
  case "hasMany":
86
93
  const asName = relEntry.as ?? relName;
@@ -94,11 +101,20 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
94
101
  }
95
102
  case "first":
96
103
  result[`~${asName}`] = val != null ? `${val}` : null;
97
- result[asName] = reconcileInstanceQuery(relEntry, response, relModel, `${val}`, store);
104
+ result[asName] = val != null ? reconcileInstanceQuery(relEntry, response, relModel, `${val}`, store) : null;
98
105
  break;
99
106
  default: {
100
- result[`~${asName}`] = val.map((v) => `${v}`);
101
- result[asName] = val.map((id) => reconcileInstanceQuery(relEntry, response, relModel, `${id}`, store));
107
+ const ids = val ?? [];
108
+ const members = [];
109
+ for (const id of ids) {
110
+ const instance$1 = reconcileInstanceQuery(relEntry, response, relModel, `${id}`, store);
111
+ if (instance$1 != null) members.push({
112
+ key: `${id}`,
113
+ instance: instance$1
114
+ });
115
+ }
116
+ result[`~${asName}`] = members.map((m) => m.key);
117
+ result[asName] = members.map((m) => m.instance);
102
118
  }
103
119
  }
104
120
  break;
@@ -1,4 +1,4 @@
1
- import { SerializableRelationQuery } from "./query-type-B0L3hwCo.js";
1
+ import { SerializableRelationQuery } from "./query-type-BqQ9oX_U.js";
2
2
 
3
3
  //#region src/_exploration/loader-types.d.ts
4
4
  type OnLoadedFn = (model: string, key: string, partialInstance: Record<string, unknown>) => void;
@@ -1,5 +1,5 @@
1
- import { InferModelQuery, ModelQuery } from "./query-type-B0L3hwCo.js";
2
- import { modelMap$1 as modelMap } from "./index-obQtSRRg.js";
1
+ import { InferModelQuery, ModelQuery } from "./query-type-BqQ9oX_U.js";
2
+ import { modelMap$1 as modelMap } from "./index-k-KPWV9R.js";
3
3
 
4
4
  //#region src/loaders/loader-utils.d.ts
5
5
  type ModelMap = typeof modelMap;
@@ -750,8 +750,14 @@ const workflowItemDesc = makeModel({
750
750
  fk: "creatorId"
751
751
  }),
752
752
  diffs: relation("workflowItemHistory", { type: "hasMany" }),
753
- inDeps: relation("workflowItem", { type: "hasMany" }),
754
- outDeps: relation("workflowItem", { type: "hasMany" })
753
+ inDeps: relation("workflowItem", {
754
+ type: "hasMany",
755
+ fkAsArray: true
756
+ }),
757
+ outDeps: relation("workflowItem", {
758
+ type: "hasMany",
759
+ fkAsArray: true
760
+ })
755
761
  },
756
762
  keys: ["itemId"]
757
763
  });
@@ -915,14 +921,29 @@ const cardDesc = makeModel({
915
921
  cardOrders: relation("cardOrder", { type: "hasMany" }),
916
922
  resolvableEntries: relation("resolvableEntry", { type: "hasMany" }),
917
923
  queueEntries: relation("queueEntry", { type: "hasMany" }),
918
- attachments: relation("attachment", { type: "hasMany" }),
924
+ attachments: relation("attachment", {
925
+ type: "hasMany",
926
+ fkAsArray: true
927
+ }),
919
928
  diffs: relation("cardHistory", { type: "hasMany" }),
920
929
  totalTimeTrackingSums: relation("timeTrackingSum", { type: "hasOne" }),
921
930
  userTimeTrackingSums: relation("timeTrackingSum", { type: "hasMany" }),
922
- childCards: relation("card", { type: "hasMany" }),
923
- inDeps: relation("card", { type: "hasMany" }),
924
- outDeps: relation("card", { type: "hasMany" }),
925
- cardReferences: relation("card", { type: "hasMany" }),
931
+ childCards: relation("card", {
932
+ type: "hasMany",
933
+ fkAsArray: true
934
+ }),
935
+ inDeps: relation("card", {
936
+ type: "hasMany",
937
+ fkAsArray: true
938
+ }),
939
+ outDeps: relation("card", {
940
+ type: "hasMany",
941
+ fkAsArray: true
942
+ }),
943
+ cardReferences: relation("card", {
944
+ type: "hasMany",
945
+ fkAsArray: true
946
+ }),
926
947
  upvotes: relation("cardUpvote", { type: "hasMany" })
927
948
  },
928
949
  keys: ["cardId"]
@@ -33,6 +33,7 @@ type BelongsToOpts<TFk extends string> = {
33
33
  };
34
34
  type HasManyOpts = {
35
35
  type: "hasMany";
36
+ fkAsArray?: boolean;
36
37
  };
37
38
  type HasOneOpts = {
38
39
  type: "hasOne";
@@ -95,14 +96,26 @@ interface ModelQuery<T extends AnyDesc, TMap extends ModelMap> {
95
96
  fields?: (keyof T["fields"] & string)[];
96
97
  relations?: RelQuery<T, TMap>;
97
98
  }
98
- interface SimpleHasManyQuery<T extends AnyDesc, TMap extends ModelMap> extends ModelQuery<T, TMap> {
99
+ interface BaseHasManyQuery<T extends AnyDesc, TMap extends ModelMap> extends ModelQuery<T, TMap> {
99
100
  type?: "query";
100
- orderBy?: Order<T>;
101
- limit?: number;
102
- offset?: number;
103
101
  filter?: Filter<T, TMap>;
104
102
  as?: string;
105
103
  }
104
+ /**
105
+ * A `limit`/`offset` "subset" requires an `orderBy` server-side (otherwise the
106
+ * API rejects the query with "needs an order ... to be able to use subset"), and
107
+ * `offset` is only meaningful together with `limit`. The union below makes the
108
+ * omission a compile error instead of a runtime 500.
109
+ */
110
+ type SimpleHasManyQuery<T extends AnyDesc, TMap extends ModelMap> = BaseHasManyQuery<T, TMap> & ({
111
+ orderBy?: Order<T>;
112
+ limit?: never;
113
+ offset?: never;
114
+ } | {
115
+ orderBy: Order<T>;
116
+ limit: number;
117
+ offset?: number;
118
+ });
106
119
  interface CountOrExistQuery<T extends AnyDesc, TMap extends ModelMap> {
107
120
  type: "count" | "exists";
108
121
  filter?: Filter<T, TMap>;
@@ -117,6 +130,30 @@ interface FirstOrLastQuery<T extends AnyDesc, TMap extends ModelMap> extends Mod
117
130
  orderBy: Order<T>;
118
131
  }
119
132
  type HasManyQuery<T extends AnyDesc, TMap extends ModelMap> = SimpleHasManyQuery<T, TMap> | CountOrExistQuery<T, TMap> | FirstOrLastQuery<T, TMap>;
133
+ /**
134
+ * `fkAsArray` hasMany relations (e.g. card `childCards`/`inDeps`/`outDeps`/
135
+ * `cardReferences`/`attachments`, workflowItem `inDeps`/`outDeps`) are stored as
136
+ * a plain id array column server-side. They support only plain selection
137
+ * (`fields` + nested `relations`) and the `count`/`exists` aggregates — any
138
+ * relQuery modifier (`filter`, `orderBy`, `limit`, `offset`, `type: "first"`) is
139
+ * rejected at runtime ("doesn't support relQueries"). The types mirror that.
140
+ */
141
+ interface FkAsArrayQuery<T extends AnyDesc, TMap extends ModelMap> extends ModelQuery<T, TMap> {
142
+ type?: "query";
143
+ as?: string;
144
+ orderBy?: never;
145
+ limit?: never;
146
+ offset?: never;
147
+ filter?: never;
148
+ }
149
+ interface FkAsArrayCountOrExistQuery {
150
+ type: "count" | "exists";
151
+ as: string;
152
+ fields?: never;
153
+ relations?: never;
154
+ filter?: never;
155
+ }
156
+ type FkAsArrayHasManyQuery<T extends AnyDesc, TMap extends ModelMap> = FkAsArrayQuery<T, TMap> | FkAsArrayCountOrExistQuery;
120
157
  type AbstractHasManyQuery = (ModelQuery<any, any> & {
121
158
  type?: "query" | "first";
122
159
  as?: string;
@@ -127,7 +164,12 @@ type AbstractHasManyQuery = (ModelQuery<any, any> & {
127
164
  type HasManyQueryWithAs<T extends AnyDesc, TMap extends ModelMap> = HasManyQuery<T, TMap> & {
128
165
  as: string;
129
166
  };
130
- type HasManyRelQueryEntry<T extends AnyDesc, TMap extends ModelMap, K extends keyof ExtractHasMany<T, TMap>> = HasManyQuery<TMap[T["relations"][K]["relName"]], TMap> | HasManyQueryWithAs<TMap[T["relations"][K]["relName"]], TMap>[];
167
+ type FkAsArrayHasManyQueryWithAs<T extends AnyDesc, TMap extends ModelMap> = FkAsArrayHasManyQuery<T, TMap> & {
168
+ as: string;
169
+ };
170
+ type HasManyRelQueryEntry<T extends AnyDesc, TMap extends ModelMap, K extends keyof ExtractHasMany<T, TMap>> = ExtractHasMany<T, TMap>[K] extends {
171
+ fkAsArray: true;
172
+ } ? FkAsArrayHasManyQuery<ExtractHasMany<T, TMap>[K]["model"], TMap> | FkAsArrayHasManyQueryWithAs<ExtractHasMany<T, TMap>[K]["model"], TMap>[] : HasManyQuery<ExtractHasMany<T, TMap>[K]["model"], TMap> | HasManyQueryWithAs<ExtractHasMany<T, TMap>[K]["model"], TMap>[];
131
173
  type RelQueryEntry<T extends AnyDesc, TMap extends ModelMap, K extends keyof T["relations"]> = K extends keyof ExtractHasMany<T, TMap> ? HasManyRelQueryEntry<T, TMap, K> : ModelQuery<TMap[T["relations"][K]["relName"]], TMap>;
132
174
  /**
133
175
  * examples for account:
@@ -145,11 +187,14 @@ type EnrichBelongsTo<M extends AnyDesc, TMap extends ModelMap> = FilterNeverKeys
145
187
  type: FieldType;
146
188
  } & FieldOpts : never;
147
189
  } : never : never }>;
148
- type ExtractHasMany<M extends AnyDesc, TMap extends ModelMap> = FilterNeverKeys<{ [K in keyof M["relations"]]: M["relations"][K] extends RelationEntry<infer RelName, {
190
+ type ExtractHasMany<M extends AnyDesc, TMap extends ModelMap> = FilterNeverKeys<{ [K in keyof M["relations"]]: M["relations"][K] extends RelationEntry<infer RelName, infer Opts> ? Opts extends {
149
191
  type: "hasMany";
150
- }> ? {
192
+ } ? {
151
193
  model: TMap[RelName];
152
- } : never }>;
194
+ fkAsArray: Opts extends {
195
+ fkAsArray: true;
196
+ } ? true : false;
197
+ } : never : never }>;
153
198
  type ExtractHasOne<M extends AnyDesc, TMap extends ModelMap> = FilterNeverKeys<{ [K in keyof M["relations"]]: M["relations"][K] extends RelationEntry<infer RelName, {
154
199
  type: "hasOne";
155
200
  }> ? {
@@ -1,6 +1,6 @@
1
- import { ModelDesc, ModelQuery, RelationEntry, TypedField } from "./query-type-B0L3hwCo.js";
2
- import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId, modelMap$1 as modelMap } from "./index-obQtSRRg.js";
3
- import { BaseLoader, LoaderResult, MissingDataRequest } from "./loader-types-Y0OHlOEK.js";
1
+ import { ModelDesc, ModelQuery, RelationEntry, TypedField } from "./query-type-BqQ9oX_U.js";
2
+ import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId, modelMap$1 as modelMap } from "./index-k-KPWV9R.js";
3
+ import { BaseLoader, LoaderResult, MissingDataRequest } from "./loader-types-fd5tV0FD.js";
4
4
 
5
5
  //#region src/_exploration/optimistic-manager.d.ts
6
6
 
@@ -898,6 +898,7 @@ declare class Store {
898
898
  }>;
899
899
  attachments: RelationEntry<"attachment", {
900
900
  readonly type: "hasMany";
901
+ readonly fkAsArray: true;
901
902
  }>;
902
903
  diffs: RelationEntry<"cardHistory", {
903
904
  readonly type: "hasMany";
@@ -910,15 +911,19 @@ declare class Store {
910
911
  }>;
911
912
  childCards: RelationEntry<"card", {
912
913
  readonly type: "hasMany";
914
+ readonly fkAsArray: true;
913
915
  }>;
914
916
  inDeps: RelationEntry<"card", {
915
917
  readonly type: "hasMany";
918
+ readonly fkAsArray: true;
916
919
  }>;
917
920
  outDeps: RelationEntry<"card", {
918
921
  readonly type: "hasMany";
922
+ readonly fkAsArray: true;
919
923
  }>;
920
924
  cardReferences: RelationEntry<"card", {
921
925
  readonly type: "hasMany";
926
+ readonly fkAsArray: true;
922
927
  }>;
923
928
  upvotes: RelationEntry<"cardUpvote", {
924
929
  readonly type: "hasMany";
@@ -2614,9 +2619,11 @@ declare class Store {
2614
2619
  }>;
2615
2620
  inDeps: RelationEntry<"workflowItem", {
2616
2621
  readonly type: "hasMany";
2622
+ readonly fkAsArray: true;
2617
2623
  }>;
2618
2624
  outDeps: RelationEntry<"workflowItem", {
2619
2625
  readonly type: "hasMany";
2626
+ readonly fkAsArray: true;
2620
2627
  }>;
2621
2628
  }, ["itemId"]>;
2622
2629
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codecks/fetch",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Quickly create deeply nested queries for the Codecks API with advanced TypeScript support",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -72,11 +72,11 @@ Key: `cardId`
72
72
  - `cardOrders` → [cardOrder](cardOrder.md)
73
73
  - `resolvableEntries` → [resolvableEntry](resolvableEntry.md)
74
74
  - `queueEntries` → [queueEntry](queueEntry.md)
75
- - `attachments` → [attachment](attachment.md)
75
+ - `attachments` → [attachment](attachment.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
76
76
  - `diffs` → [cardHistory](cardHistory.md)
77
77
  - `userTimeTrackingSums` → [timeTrackingSum](timeTrackingSum.md)
78
- - `childCards` → [card](card.md)
79
- - `inDeps` → [card](card.md)
80
- - `outDeps` → [card](card.md)
81
- - `cardReferences` → [card](card.md)
78
+ - `childCards` → [card](card.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
79
+ - `inDeps` → [card](card.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
80
+ - `outDeps` → [card](card.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
81
+ - `cardReferences` → [card](card.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
82
82
  - `upvotes` → [cardUpvote](cardUpvote.md)
@@ -41,5 +41,5 @@ Key: `itemId`
41
41
  ### hasMany
42
42
 
43
43
  - `diffs` → [workflowItemHistory](workflowItemHistory.md)
44
- - `inDeps` → [workflowItem](workflowItem.md)
45
- - `outDeps` → [workflowItem](workflowItem.md)
44
+ - `inDeps` → [workflowItem](workflowItem.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
45
+ - `outDeps` → [workflowItem](workflowItem.md) — `fkAsArray` (plain selection + `count`/`exists` only; no `filter`/`orderBy`/`limit`/`offset`/`first`)
@@ -150,6 +150,35 @@ Pass an array of queries with `as` aliases:
150
150
 
151
151
  ## Pagination (hasMany only)
152
152
 
153
+ A subset (`limit`/`offset`) requires an `orderBy` — the API rejects a subset
154
+ without an order. `offset` is only meaningful together with `limit`. The types
155
+ enforce this, so `limit` on its own is a compile error.
156
+
157
+ ```ts
158
+ {cards: {fields: ["title"], orderBy: "-createdAt", limit: 10, offset: 20}}
159
+ ```
160
+
161
+ ## `fkAsArray` relations (limited capabilities)
162
+
163
+ A handful of hasMany relations are stored server-side as a plain id-array column
164
+ rather than a joined table. These are flagged as `fkAsArray` on their model
165
+ pages and currently are:
166
+
167
+ - `card`: `childCards`, `inDeps`, `outDeps`, `cardReferences`, `attachments`
168
+ - `workflowItem`: `inDeps`, `outDeps`
169
+
170
+ They support **only** plain selection (`fields` + nested `relations`) and the
171
+ `count`/`exists` aggregates. `filter`, `orderBy`, `limit`, `offset`, and
172
+ `type: "first"` are not supported (the API rejects them), and the types reflect
173
+ that.
174
+
153
175
  ```ts
154
- {cards: {fields: ["title"], limit: 10, offset: 20}}
176
+ {childCards: {fields: ["cardId"]}} // OK → array
177
+ {childCards: {type: "count", as: "n"}} // OK → number
178
+ {childCards: {type: "exists", as: "hasChildren"}} // OK → boolean
179
+
180
+ // compile errors:
181
+ {childCards: {fields: ["cardId"], orderBy: "accountSeq"}}
182
+ {childCards: {fields: ["cardId"], limit: 50, orderBy: "accountSeq"}}
183
+ {childCards: {fields: ["cardId"], filter: {status: "started"}}}
155
184
  ```