@codecks/fetch 0.1.3 → 0.1.5
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/_exploration/api-requester.d.ts +1 -1
- package/dist/_exploration/create-hooks.d.ts +2 -2
- package/dist/_exploration/create-hooks.js +42 -23
- package/dist/_exploration/loader.d.ts +1 -1
- package/dist/_exploration/store.d.ts +2 -2
- package/dist/_exploration/store.js +15 -6
- package/dist/index.js +4 -3
- package/dist/{loader-types-CMF96Ae1.d.ts → loader-types-Dp0CSVTf.d.ts} +2 -2
- package/dist/{store-C_DXGjif.d.ts → store-B6JWZnAO.d.ts} +1 -1
- package/package.json +9 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../query-type-Dx5ZCv5N.js";
|
|
2
2
|
import "../index-DUBsesYl.js";
|
|
3
3
|
import { FetchOptions } from "../loader-utils-Du-CTKH-.js";
|
|
4
|
-
import { BaseRequester, MissingDataRequest } from "../loader-types-
|
|
4
|
+
import { BaseRequester, MissingDataRequest } from "../loader-types-Dp0CSVTf.js";
|
|
5
5
|
|
|
6
6
|
//#region src/_exploration/api-requester.d.ts
|
|
7
7
|
declare class ApiRequester implements BaseRequester {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { InferModelQuery, InferRelQuery, ModelDesc, ModelQuery, RelQuery, RelationEntry, TypedField } from "../query-type-Dx5ZCv5N.js";
|
|
2
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-DUBsesYl.js";
|
|
3
|
-
import "../loader-types-
|
|
3
|
+
import "../loader-types-Dp0CSVTf.js";
|
|
4
4
|
import { _rootDesc$1 as _rootDesc } from "../_root-D1Faf8cg.js";
|
|
5
|
-
import { Store } from "../store-
|
|
5
|
+
import { Store } from "../store-B6JWZnAO.js";
|
|
6
6
|
|
|
7
7
|
//#region src/_exploration/create-hooks.d.ts
|
|
8
8
|
declare const createHooks: (store: Store) => {
|
|
@@ -2,28 +2,32 @@ import { queryToKey } from "../query-helpers-DsMMOtSO.js";
|
|
|
2
2
|
import { use, useSyncExternalStore } from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/_exploration/user-query-manager.ts
|
|
5
|
-
const diffResults = (
|
|
6
|
-
const
|
|
5
|
+
const diffResults = (prevTrackedData, nextStorePayload) => {
|
|
6
|
+
const nextPartKeys = nextStorePayload.partKeys;
|
|
7
|
+
const prevSet = new Set(prevTrackedData.partKeys);
|
|
8
|
+
const nextSet = new Set(nextPartKeys);
|
|
9
|
+
const added = nextPartKeys.filter((key) => !prevSet.has(key));
|
|
10
|
+
const removed = prevTrackedData.partKeys.filter((key) => !nextSet.has(key));
|
|
7
11
|
return {
|
|
8
|
-
added
|
|
9
|
-
removed
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
added,
|
|
13
|
+
removed,
|
|
14
|
+
nextTrackedData: {
|
|
15
|
+
partKeys: nextPartKeys,
|
|
16
|
+
value: nextStorePayload.value
|
|
13
17
|
}
|
|
14
18
|
};
|
|
15
19
|
};
|
|
16
20
|
const createStoreQuery = (opts) => {
|
|
17
21
|
const { onDispose, updateDataListener, store, q, ids, model } = opts;
|
|
18
22
|
const queryListeners = new Set();
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
let trackedData = {
|
|
24
|
+
partKeys: [],
|
|
25
|
+
value: null
|
|
22
26
|
};
|
|
23
|
-
const reconcileNextResult = (
|
|
24
|
-
const { added, removed,
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
+
const reconcileNextResult = (storePayload) => {
|
|
28
|
+
const { added, removed, nextTrackedData } = diffResults(trackedData, storePayload);
|
|
29
|
+
if (added.length || removed.length) {
|
|
30
|
+
trackedData = nextTrackedData;
|
|
27
31
|
updateDataListener({
|
|
28
32
|
added,
|
|
29
33
|
removed
|
|
@@ -34,13 +38,26 @@ const createStoreQuery = (opts) => {
|
|
|
34
38
|
const notify = () => {
|
|
35
39
|
loadData();
|
|
36
40
|
};
|
|
41
|
+
let userQueryResult;
|
|
37
42
|
const loadData = () => {
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
const storeResult = store.loadData(model, ids, q);
|
|
44
|
+
if (storeResult.state === "pending") userQueryResult = {
|
|
45
|
+
state: "pending",
|
|
46
|
+
promise: storeResult.promise.then((storePayload) => {
|
|
47
|
+
reconcileNextResult(storePayload);
|
|
48
|
+
return storePayload.value;
|
|
49
|
+
})
|
|
50
|
+
};
|
|
51
|
+
else {
|
|
52
|
+
const storePayload = storeResult.payload;
|
|
53
|
+
reconcileNextResult(storePayload);
|
|
54
|
+
userQueryResult = {
|
|
55
|
+
state: "resolved",
|
|
56
|
+
value: storePayload.value
|
|
57
|
+
};
|
|
58
|
+
}
|
|
42
59
|
};
|
|
43
|
-
|
|
60
|
+
loadData();
|
|
44
61
|
const subscribe = (listener) => {
|
|
45
62
|
queryListeners.add(listener);
|
|
46
63
|
return () => {
|
|
@@ -48,12 +65,12 @@ const createStoreQuery = (opts) => {
|
|
|
48
65
|
if (queryListeners.size === 0) onDispose();
|
|
49
66
|
updateDataListener({
|
|
50
67
|
added: [],
|
|
51
|
-
removed:
|
|
68
|
+
removed: trackedData.partKeys
|
|
52
69
|
}, notify);
|
|
53
70
|
};
|
|
54
71
|
};
|
|
55
72
|
const get = () => {
|
|
56
|
-
return
|
|
73
|
+
return userQueryResult;
|
|
57
74
|
};
|
|
58
75
|
return {
|
|
59
76
|
subscribe,
|
|
@@ -122,10 +139,12 @@ const createHooks = (store) => {
|
|
|
122
139
|
return val.value;
|
|
123
140
|
};
|
|
124
141
|
const useFetch = (model, id, q) => {
|
|
125
|
-
|
|
142
|
+
const res = useQueryManager(model, [id], q);
|
|
143
|
+
return res[id];
|
|
126
144
|
};
|
|
127
145
|
const useFetchFromRoot = (q) => {
|
|
128
|
-
|
|
146
|
+
const res = useQueryManager("_root", [""], { relations: q });
|
|
147
|
+
return res[""];
|
|
129
148
|
};
|
|
130
149
|
return {
|
|
131
150
|
useFetch,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../query-type-Dx5ZCv5N.js";
|
|
2
|
-
import { BaseLoader, BaseRequester, MissingDataRequest, OnLoadedFn } from "../loader-types-
|
|
2
|
+
import { BaseLoader, BaseRequester, MissingDataRequest, OnLoadedFn } from "../loader-types-Dp0CSVTf.js";
|
|
3
3
|
|
|
4
4
|
//#region src/_exploration/loader.d.ts
|
|
5
5
|
type DataRequestWithKey = {
|
|
@@ -71,14 +71,15 @@ var Store = class {
|
|
|
71
71
|
if (missingRequests.length > 0) this.loader.loadBatch(missingRequests);
|
|
72
72
|
return {
|
|
73
73
|
state: "resolved",
|
|
74
|
-
|
|
74
|
+
payload: {
|
|
75
75
|
value: resultObj,
|
|
76
76
|
partKeys: allPartKeys
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
const promise = this.loader.loadBatch(missingRequests).then(() => {
|
|
81
|
-
|
|
81
|
+
const res = this.loadData(model, ids, q, acceptDirty, iteration + 1);
|
|
82
|
+
return res.state === "pending" ? res.promise : res.payload;
|
|
82
83
|
});
|
|
83
84
|
return {
|
|
84
85
|
state: "pending",
|
|
@@ -97,7 +98,10 @@ var Store = class {
|
|
|
97
98
|
* Accumulates missing requests in the missingRequests array
|
|
98
99
|
*/
|
|
99
100
|
checkQueryRecursive(desc, model, id, query, missingRequests, acceptDirty) {
|
|
100
|
-
const data = {}
|
|
101
|
+
const data = model === "_root" ? {} : {
|
|
102
|
+
"~model": model,
|
|
103
|
+
"~key": id
|
|
104
|
+
};
|
|
101
105
|
const partKeys = [];
|
|
102
106
|
let allPresent = true;
|
|
103
107
|
if (query.fields) for (const field of query.fields) {
|
|
@@ -135,13 +139,18 @@ var Store = class {
|
|
|
135
139
|
if (acceptsData) {
|
|
136
140
|
if (!relatedModelDesc) throw new Error(`Model ${relatedModel} not found`);
|
|
137
141
|
const fieldName = relQuery.as || relationName;
|
|
138
|
-
if (
|
|
139
|
-
|
|
142
|
+
if (relQuery.type === "count" || relQuery.type === "exists") {
|
|
143
|
+
data[fieldName] = cachedValue.value;
|
|
144
|
+
partKeys.push(...cachedValue.partKeys);
|
|
145
|
+
} else if (Array.isArray(cachedValue.value)) {
|
|
146
|
+
const relationResults = cachedValue.value.map((key) => this.checkQueryRecursive(relatedModelDesc, relatedModel, `${key}`, relQuery, missingRequests, acceptDirty));
|
|
147
|
+
data[`~${fieldName}`] = cachedValue.value.map((v) => `${v}`);
|
|
140
148
|
data[fieldName] = relationResults.map((result) => result.data);
|
|
141
149
|
partKeys.push(...relationResults.flatMap((result) => result.partKeys));
|
|
142
150
|
if (relationResults.some((result) => !result.allPresent)) allPresent = false;
|
|
143
151
|
} else {
|
|
144
|
-
const relationResult = this.checkQueryRecursive(relatedModelDesc, relatedModel, cachedValue.value
|
|
152
|
+
const relationResult = this.checkQueryRecursive(relatedModelDesc, relatedModel, `${cachedValue.value}`, relQuery, missingRequests, acceptDirty);
|
|
153
|
+
data[`~${fieldName}`] = cachedValue.value != null ? `${cachedValue.value}` : null;
|
|
145
154
|
data[fieldName] = relationResult.data;
|
|
146
155
|
partKeys.push(...relationResult.partKeys);
|
|
147
156
|
if (!relationResult.allPresent) allPresent = false;
|
package/dist/index.js
CHANGED
|
@@ -75,10 +75,11 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
|
|
|
75
75
|
switch (opts.type) {
|
|
76
76
|
case "belongsTo":
|
|
77
77
|
result[opts.fk] = instance[relName];
|
|
78
|
+
result[`~${relName}`] = instance[relName] != null ? `${instance[relName]}` : null;
|
|
78
79
|
result[relName] = opts.fk ? reconcileInstanceQuery(relEntry, response, relModel, `${instance[relName]}`, store) : null;
|
|
79
80
|
break;
|
|
80
81
|
case "hasOne":
|
|
81
|
-
result[`~${relName}`] = instance[relName];
|
|
82
|
+
result[`~${relName}`] = instance[relName] != null ? `${instance[relName]}` : null;
|
|
82
83
|
result[relName] = reconcileInstanceQuery(relEntry, response, relModel, `${instance[relName]}`, store);
|
|
83
84
|
break;
|
|
84
85
|
case "hasMany":
|
|
@@ -92,11 +93,11 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
|
|
|
92
93
|
break;
|
|
93
94
|
}
|
|
94
95
|
case "first":
|
|
95
|
-
result[`~${asName}`] = val;
|
|
96
|
+
result[`~${asName}`] = val != null ? `${val}` : null;
|
|
96
97
|
result[asName] = reconcileInstanceQuery(relEntry, response, relModel, `${val}`, store);
|
|
97
98
|
break;
|
|
98
99
|
default: {
|
|
99
|
-
result[`~${asName}`] = val;
|
|
100
|
+
result[`~${asName}`] = val.map((v) => `${v}`);
|
|
100
101
|
result[asName] = val.map((id) => reconcileInstanceQuery(relEntry, response, relModel, `${id}`, store));
|
|
101
102
|
}
|
|
102
103
|
}
|
|
@@ -12,10 +12,10 @@ type LoaderPayload = {
|
|
|
12
12
|
};
|
|
13
13
|
type LoaderResult = {
|
|
14
14
|
state: "resolved";
|
|
15
|
-
|
|
15
|
+
payload: LoaderPayload;
|
|
16
16
|
} | {
|
|
17
17
|
state: "pending";
|
|
18
|
-
promise: Promise<
|
|
18
|
+
promise: Promise<LoaderPayload>;
|
|
19
19
|
};
|
|
20
20
|
type MissingDataRequest = {
|
|
21
21
|
type: "field";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ModelDesc, ModelQuery, RelationEntry, TypedField } from "./query-type-Dx5ZCv5N.js";
|
|
2
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-DUBsesYl.js";
|
|
3
|
-
import { BaseLoader, LoaderResult } from "./loader-types-
|
|
3
|
+
import { BaseLoader, LoaderResult } from "./loader-types-Dp0CSVTf.js";
|
|
4
4
|
|
|
5
5
|
//#region src/_exploration/immediate-cache.d.ts
|
|
6
6
|
type FieldMeta = {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codecks/fetch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Quickly create deeply nested queries for the Codecks API with advanced TypeScript support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"homepage": "https://github.com/codecks-io/
|
|
7
|
+
"homepage": "https://github.com/codecks-io/fetch#readme",
|
|
8
8
|
"bugs": {
|
|
9
|
-
"url": "https://github.com/codecks-io/
|
|
9
|
+
"url": "https://github.com/codecks-io/fetch/issues"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "git+https://github.com/codecks-io/
|
|
13
|
+
"url": "git+https://github.com/codecks-io/fetch.git"
|
|
14
14
|
},
|
|
15
15
|
"author": "Daniel Berndt <daniel@codecks.io>",
|
|
16
16
|
"files": [
|
|
@@ -44,8 +44,13 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@changesets/cli": "^2.29.7",
|
|
47
|
+
"@testing-library/dom": "^10.4.1",
|
|
48
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
49
|
+
"@testing-library/react": "^16.3.0",
|
|
50
|
+
"@testing-library/user-event": "^14.6.1",
|
|
47
51
|
"@types/node": "^22.15.17",
|
|
48
52
|
"@types/react": "^19.2.2",
|
|
53
|
+
"happy-dom": "^20.0.10",
|
|
49
54
|
"msw": "^2.10.4",
|
|
50
55
|
"prettier": "^3.6.2",
|
|
51
56
|
"tsdown": "^0.11.9",
|