@mittwald/react-ghostmaker 1.5.0-alpha.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +871 -0
- package/dist/esm/index.js +7 -7
- package/dist/esm/invalidate.js +4 -8
- package/dist/esm/makeGhost.js +8 -6
- package/dist/esm/makeGhost.test-d.js +1 -1
- package/dist/esm/makeGhost.test.js +11 -9
- package/dist/esm/maybeGhost/asGhost.js +2 -2
- package/dist/esm/maybeGhost/asGhost.test.js +2 -2
- package/dist/esm/maybeGhost/index.js +2 -2
- package/dist/esm/maybeGhost/types.test-d.js +1 -1
- package/dist/esm/polytype.js +2 -2
- package/dist/esm/queries.js +3 -3
- package/dist/esm/queries.test.js +1 -1
- package/dist/esm/reset.js +6 -0
- package/dist/esm/resolveGhostChain.js +4 -11
- package/dist/esm/testMocks.js +2 -2
- package/dist/esm/useGhostChain.js +66 -34
- package/dist/esm/withEachGhost.js +10 -0
- package/dist/types/index.d.ts +8 -8
- package/dist/types/invalidate.d.ts +1 -1
- package/dist/types/makeGhost.d.ts +1 -1
- package/dist/types/maybeGhost/asGhost.d.ts +2 -2
- package/dist/types/maybeGhost/index.d.ts +2 -2
- package/dist/types/maybeGhost/types.d.ts +1 -1
- package/dist/types/modelIdentifier.d.ts +1 -1
- package/dist/types/polytype.d.ts +1 -1
- package/dist/types/queries.d.ts +3 -3
- package/dist/types/reset.d.ts +3 -0
- package/dist/types/resolveGhostChain.d.ts +1 -1
- package/dist/types/testMocks.d.ts +2 -2
- package/dist/types/types.d.ts +8 -3
- package/dist/types/useGhostChain.d.ts +2 -2
- package/dist/types/withEachGhost.d.ts +2 -0
- package/package.json +23 -23
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { makeGhost } from "./makeGhost";
|
|
2
|
-
export { registerModelIdentifier } from "./modelIdentifier";
|
|
3
|
-
export { getQueryContext, forwardQueryContext } from "./context";
|
|
4
|
-
export { invalidateGhosts } from "./invalidate";
|
|
5
|
-
export * from "./maybeGhost";
|
|
6
|
-
export { GhostMakerModel, ghostMakerModel } from "./metaData";
|
|
7
|
-
export { getModelId, getModelName } from "./queries";
|
|
1
|
+
export { makeGhost } from "./makeGhost.js";
|
|
2
|
+
export { registerModelIdentifier } from "./modelIdentifier.js";
|
|
3
|
+
export { getQueryContext, forwardQueryContext } from "./context.js";
|
|
4
|
+
export { invalidateGhosts } from "./invalidate.js";
|
|
5
|
+
export * from "./maybeGhost/index.js";
|
|
6
|
+
export { GhostMakerModel, ghostMakerModel } from "./metaData.js";
|
|
7
|
+
export { getModelId, getModelName } from "./queries.js";
|
package/dist/esm/invalidate.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
import { withEachGhost } from "./withEachGhost.js";
|
|
1
2
|
export async function invalidateGhosts(queryClient, queryKey) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
await queryClient.invalidateQueries({
|
|
6
|
-
queryKey: partialKey,
|
|
7
|
-
exact,
|
|
8
|
-
});
|
|
9
|
-
}
|
|
3
|
+
await withEachGhost(queryKey, async (filter) => {
|
|
4
|
+
await queryClient.invalidateQueries(filter);
|
|
5
|
+
});
|
|
10
6
|
}
|
package/dist/esm/makeGhost.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
|
-
import { isGhostMarker, transformFnProp, } from "./types";
|
|
3
|
-
import { useGhostChain } from "./useGhostChain";
|
|
4
|
-
import { RenderComponent } from "./RenderComponent";
|
|
5
|
-
import { resolveGhostChain } from "./resolveGhostChain";
|
|
6
|
-
import { invalidateGhosts } from "./invalidate";
|
|
7
|
-
import { queries } from "./queries";
|
|
2
|
+
import { isGhostMarker, transformFnProp, } from "./types.js";
|
|
3
|
+
import { useGhostChain } from "./useGhostChain.js";
|
|
4
|
+
import { RenderComponent } from "./RenderComponent.js";
|
|
5
|
+
import { resolveGhostChain } from "./resolveGhostChain.js";
|
|
6
|
+
import { invalidateGhosts } from "./invalidate.js";
|
|
7
|
+
import { queries } from "./queries.js";
|
|
8
|
+
import { resetGhosts } from "./reset.js";
|
|
8
9
|
function buildGhostDeep(target, ghostChain) {
|
|
9
10
|
const proxyTarget = (() => {
|
|
10
11
|
// Dummy function to allow ghosting function calls
|
|
@@ -28,6 +29,7 @@ function buildGhostDeep(target, ghostChain) {
|
|
|
28
29
|
return ghost;
|
|
29
30
|
},
|
|
30
31
|
invalidate: (queryClient) => invalidateGhosts(queryClient, queries.ghostChain(target, ghostChain)),
|
|
32
|
+
reset: (queryClient) => resetGhosts(queryClient, queries.ghostChain(target, ghostChain)),
|
|
31
33
|
};
|
|
32
34
|
const ghost = new Proxy(proxyTarget, {
|
|
33
35
|
get: ($, prop) => {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cleanup, render } from "@testing-library/react";
|
|
3
3
|
import { describe, expect, test, vitest, beforeEach, afterEach } from "vitest";
|
|
4
|
-
import { CustomerDetailed, CustomerGhost, Project, ProjectDetailed, ProjectGhost, advanceSleepTimer, customerMocks, getCustomerNameGhostIds, projectMocks, } from "./testMocks";
|
|
4
|
+
import { CustomerDetailed, CustomerGhost, Project, ProjectDetailed, ProjectGhost, advanceSleepTimer, customerMocks, getCustomerNameGhostIds, projectMocks, } from "./testMocks.js";
|
|
5
5
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
6
|
-
import { invalidateGhosts } from "./invalidate";
|
|
7
|
-
import { makeGhost } from "./makeGhost";
|
|
6
|
+
import { invalidateGhosts } from "./invalidate.js";
|
|
7
|
+
import { makeGhost } from "./makeGhost.js";
|
|
8
|
+
import { cleanupTargetHashes } from "./useGhostChain.js";
|
|
8
9
|
beforeEach(() => {
|
|
9
10
|
vitest.useFakeTimers();
|
|
11
|
+
cleanupTargetHashes();
|
|
10
12
|
});
|
|
11
13
|
afterEach(() => {
|
|
12
14
|
vitest.runOnlyPendingTimers();
|
|
@@ -181,7 +183,7 @@ describe("Hooks", () => {
|
|
|
181
183
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
182
184
|
expect(customerMocks.getName).toHaveBeenCalledTimes(1);
|
|
183
185
|
result.current?.invalidate();
|
|
184
|
-
await vitest.
|
|
186
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
185
187
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
186
188
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
187
189
|
expect(customerMocks.getName).toHaveBeenCalledTimes(2);
|
|
@@ -196,7 +198,7 @@ describe("Hooks", () => {
|
|
|
196
198
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
197
199
|
expect(customerMocks.getName).toHaveBeenCalledTimes(1);
|
|
198
200
|
ghost.invalidate(queryClient);
|
|
199
|
-
await vitest.
|
|
201
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
200
202
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
201
203
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
202
204
|
expect(customerMocks.getName).toHaveBeenCalledTimes(2);
|
|
@@ -211,7 +213,7 @@ describe("Hooks", () => {
|
|
|
211
213
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
212
214
|
expect(customerMocks.getName).toHaveBeenCalledTimes(1);
|
|
213
215
|
invalidateGhosts(queryClient, getCustomerNameGhostIds.current.queryKey);
|
|
214
|
-
await vitest.
|
|
216
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
215
217
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
216
218
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
217
219
|
expect(customerMocks.getName).toHaveBeenCalledTimes(2);
|
|
@@ -223,7 +225,7 @@ describe("Hooks", () => {
|
|
|
223
225
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
224
226
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
225
227
|
ghost.invalidate(queryClient);
|
|
226
|
-
await vitest.
|
|
228
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
227
229
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
228
230
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
229
231
|
});
|
|
@@ -234,7 +236,7 @@ describe("Hooks", () => {
|
|
|
234
236
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(1);
|
|
235
237
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(0);
|
|
236
238
|
specialGhost.invalidate(queryClient);
|
|
237
|
-
await vitest.
|
|
239
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
238
240
|
expect(projectMocks.getDetailed).toHaveBeenCalledTimes(2);
|
|
239
241
|
expect(customerMocks.getDetailed).toHaveBeenCalledTimes(0);
|
|
240
242
|
});
|
|
@@ -246,7 +248,7 @@ describe("Hooks", () => {
|
|
|
246
248
|
.fn()
|
|
247
249
|
.mockImplementation((id) => new ProjectDetailed(id, `CHANGED! Project ${id}`, "C1"));
|
|
248
250
|
projectGhost.invalidate(queryClient);
|
|
249
|
-
await vitest.
|
|
251
|
+
await vitest.runOnlyPendingTimersAsync();
|
|
250
252
|
expect(projectMocks.getName).toHaveBeenCalledTimes(2);
|
|
251
253
|
});
|
|
252
254
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { makeGhost } from "../makeGhost";
|
|
2
|
-
import { isReactGhost } from "../types";
|
|
1
|
+
import { makeGhost } from "../makeGhost.js";
|
|
2
|
+
import { isReactGhost } from "../types.js";
|
|
3
3
|
export function asGhost(maybeGhost) {
|
|
4
4
|
if (isReactGhost(maybeGhost)) {
|
|
5
5
|
return maybeGhost;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { asGhostProps } from "../maybeGhost";
|
|
2
|
-
import { isReactGhost } from "../types";
|
|
1
|
+
import { asGhostProps } from "../maybeGhost/index.js";
|
|
2
|
+
import { isReactGhost } from "../types.js";
|
|
3
3
|
import { expect, test } from "vitest";
|
|
4
4
|
test("makes Ghosts of all props", () => {
|
|
5
5
|
const ghostProps = asGhostProps({
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./asGhost";
|
|
2
|
-
export * from "./types";
|
|
1
|
+
export * from "./asGhost.js";
|
|
2
|
+
export * from "./types.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expectTypeOf, test } from "vitest";
|
|
2
|
-
import { asGhostProps } from "./asGhost";
|
|
2
|
+
import { asGhostProps } from "./asGhost.js";
|
|
3
3
|
describe("fixupMaybeReactGhostProps()", () => {
|
|
4
4
|
test("works for one prop", () => {
|
|
5
5
|
expectTypeOf(asGhostProps({})).toEqualTypeOf();
|
package/dist/esm/polytype.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { getPrototypeListOf } from "polytype";
|
|
2
|
-
import { getProtoypes } from "./metaData";
|
|
2
|
+
import { getProtoypes } from "./metaData.js";
|
|
3
3
|
getProtoypes.current = getPrototypeListOf;
|
|
4
|
-
export { GhostMakerModel } from "./metaData";
|
|
4
|
+
export { GhostMakerModel } from "./metaData.js";
|
package/dist/esm/queries.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import is from "@sindresorhus/is";
|
|
2
|
-
import { hashObject } from "./hash";
|
|
3
|
-
import { getMetaData } from "./metaData";
|
|
4
|
-
import { modelIdentifiers } from "./modelIdentifier";
|
|
2
|
+
import { hashObject } from "./hash.js";
|
|
3
|
+
import { getMetaData } from "./metaData.js";
|
|
4
|
+
import { modelIdentifiers } from "./modelIdentifier.js";
|
|
5
5
|
export const getModelName = (something) => {
|
|
6
6
|
return getMetaData(something)?.name;
|
|
7
7
|
};
|
package/dist/esm/queries.test.js
CHANGED
|
@@ -32,7 +32,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import { getMetaData, GhostMakerModel } from "./metaData";
|
|
35
|
+
import { getMetaData, GhostMakerModel } from "./metaData.js";
|
|
36
36
|
import { expect, test } from "vitest";
|
|
37
37
|
let GrandParent = (() => {
|
|
38
38
|
let _classDecorators = [GhostMakerModel({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import is, { assert } from "@sindresorhus/is";
|
|
2
|
-
import { isReactGhost, transformFnProp, } from "./types";
|
|
3
|
-
import { getQueryContext, ghostFnContext } from "./context";
|
|
2
|
+
import { isReactGhost, transformFnProp, } from "./types.js";
|
|
4
3
|
const resolveGhostChainItem = async (target, item) => {
|
|
5
4
|
const { propName, args } = item;
|
|
6
5
|
if (propName === transformFnProp) {
|
|
@@ -22,19 +21,13 @@ const resolveGhostChainItem = async (target, item) => {
|
|
|
22
21
|
return property;
|
|
23
22
|
}
|
|
24
23
|
assert.function(property);
|
|
25
|
-
|
|
24
|
+
const asyncFn = property.bind(target);
|
|
25
|
+
return await asyncFn(...args);
|
|
26
26
|
};
|
|
27
27
|
export const resolveGhostChain = async (target, stack) => {
|
|
28
28
|
let result = target;
|
|
29
|
-
const queryContext = getQueryContext();
|
|
30
29
|
for (const item of stack) {
|
|
31
|
-
|
|
32
|
-
const resolveGhostChainItemWithContext = ghostFnContext.bind({ query: queryContext }, resolveGhostChainItem);
|
|
33
|
-
result = await resolveGhostChainItemWithContext(result, item);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
result = await resolveGhostChainItem(result, item);
|
|
37
|
-
}
|
|
30
|
+
result = await resolveGhostChainItem(result, item);
|
|
38
31
|
}
|
|
39
32
|
return result;
|
|
40
33
|
};
|
package/dist/esm/testMocks.js
CHANGED
|
@@ -33,8 +33,8 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
35
|
import { beforeEach, vitest } from "vitest";
|
|
36
|
-
import { getQueryContext, makeGhost } from ".";
|
|
37
|
-
import { GhostMakerModel } from "./metaData";
|
|
36
|
+
import { getQueryContext, makeGhost } from "./index.js";
|
|
37
|
+
import { GhostMakerModel } from "./metaData.js";
|
|
38
38
|
const sleep = () => new Promise((resolve) => setTimeout(resolve, 200));
|
|
39
39
|
export const advanceSleepTimer = async (times = 1) => {
|
|
40
40
|
for (let i = 0; i < times; i++) {
|
|
@@ -1,52 +1,84 @@
|
|
|
1
|
-
import is from "@sindresorhus/is";
|
|
2
|
-
import { useEffect, useEffectEvent,
|
|
1
|
+
import is, { assert } from "@sindresorhus/is";
|
|
2
|
+
import { useEffect, useEffectEvent, useMemo } from "react";
|
|
3
|
+
import { transformFnProp, } from "./types.js";
|
|
3
4
|
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
|
|
4
|
-
import { queries } from "./queries";
|
|
5
|
-
import { ghostFnContext } from "./context";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { queries } from "./queries.js";
|
|
6
|
+
import { ghostFnContext } from "./context.js";
|
|
7
|
+
import { invalidateGhosts } from "./invalidate.js";
|
|
8
|
+
import { hashObject } from "./hash.js";
|
|
9
|
+
import { resetGhosts } from "./reset.js";
|
|
8
10
|
export const useGhostChain = (target, chain, options) => {
|
|
9
11
|
const queryClient = useQueryClient();
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const context = {
|
|
13
|
+
queryKey: queries.target(target),
|
|
14
|
+
};
|
|
15
|
+
const value = chain.reduce((currentTarget, item) => useGhostChainItem(currentTarget, item, options, context), target);
|
|
16
|
+
const invalidate = () => invalidateGhosts(queryClient, queries.ghostChain(target, chain));
|
|
17
|
+
const reset = () => resetGhosts(queryClient, queries.ghostChain(target, chain));
|
|
18
|
+
return {
|
|
19
|
+
value,
|
|
20
|
+
invalidate,
|
|
21
|
+
reset,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const useGhostChainItem = (target, item, options = {}, context) => {
|
|
25
|
+
const { propName, args } = item;
|
|
26
|
+
if (propName === transformFnProp) {
|
|
27
|
+
assert.array(args);
|
|
28
|
+
const transformFn = args[0];
|
|
29
|
+
assert.function(transformFn, "transform requires a mapping function");
|
|
30
|
+
const transformDependencies = args[1] ?? [];
|
|
31
|
+
assert.array(transformDependencies);
|
|
32
|
+
return useMemo(() => transformFn(target), [target, ...transformDependencies]);
|
|
33
|
+
}
|
|
34
|
+
if (is.nullOrUndefined(target)) {
|
|
35
|
+
return target;
|
|
36
|
+
}
|
|
37
|
+
assert.object(target);
|
|
38
|
+
const targetPropertyName = propName;
|
|
39
|
+
const targetProperty = target[targetPropertyName];
|
|
40
|
+
context.queryKey = queries.chainItem(context.queryKey, item);
|
|
41
|
+
if (args === undefined) {
|
|
42
|
+
// no function call, just a property access
|
|
43
|
+
return targetProperty;
|
|
44
|
+
}
|
|
45
|
+
assert.function(targetProperty);
|
|
46
|
+
const targetFn = targetProperty.bind(target);
|
|
47
|
+
const queryKey = [...context.queryKey];
|
|
48
|
+
const query = useSuspenseQuery({
|
|
13
49
|
...options,
|
|
50
|
+
queryKey,
|
|
14
51
|
queryFn: async (ctx) => {
|
|
15
|
-
const targetFnWithContext = ghostFnContext.bind({ query: ctx },
|
|
16
|
-
return { result: await targetFnWithContext() };
|
|
52
|
+
const targetFnWithContext = ghostFnContext.bind({ query: ctx }, targetFn);
|
|
53
|
+
return { result: await targetFnWithContext(...args) };
|
|
17
54
|
},
|
|
18
|
-
queryKey,
|
|
19
55
|
});
|
|
20
|
-
if (queryResult.error) {
|
|
21
|
-
throw queryResult.error;
|
|
22
|
-
}
|
|
23
56
|
useTargetAutoInvalidate(target, queryKey);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}),
|
|
29
|
-
};
|
|
57
|
+
if (query.error) {
|
|
58
|
+
throw query.error;
|
|
59
|
+
}
|
|
60
|
+
return query.data.result;
|
|
30
61
|
};
|
|
62
|
+
const targetHashes = new Map();
|
|
31
63
|
const useTargetAutoInvalidate = (target, queryKey) => {
|
|
32
64
|
const queryClient = useQueryClient();
|
|
33
|
-
const invalidate = () => queryClient.invalidateQueries({
|
|
34
|
-
queryKey,
|
|
35
|
-
});
|
|
36
|
-
const targetHash = is.object(target) ? hashObject(target) : target;
|
|
37
|
-
const prevTargetHash = useRef(targetHash);
|
|
38
|
-
const joinedQueryKey = queryKey.join(".");
|
|
39
|
-
const prevQueryId = useRef(joinedQueryKey);
|
|
40
|
-
const needsRefresh = prevQueryId.current === joinedQueryKey &&
|
|
41
|
-
prevTargetHash.current !== targetHash;
|
|
42
|
-
prevTargetHash.current = targetHash;
|
|
43
|
-
prevQueryId.current = joinedQueryKey;
|
|
44
65
|
const onTargetChangeEvent = useEffectEvent(() => {
|
|
66
|
+
const joinedQueryKey = queryKey.join(".");
|
|
67
|
+
const targetHash = hashObject(target);
|
|
68
|
+
const prevTargetHash = targetHashes.get(joinedQueryKey);
|
|
69
|
+
const needsRefresh = prevTargetHash !== undefined && prevTargetHash !== targetHash;
|
|
70
|
+
targetHashes.set(joinedQueryKey, targetHash);
|
|
45
71
|
if (needsRefresh) {
|
|
46
|
-
|
|
72
|
+
queryClient.invalidateQueries({
|
|
73
|
+
queryKey,
|
|
74
|
+
});
|
|
47
75
|
}
|
|
48
76
|
});
|
|
49
77
|
useEffect(() => {
|
|
50
78
|
onTargetChangeEvent();
|
|
51
|
-
}, [
|
|
79
|
+
}, [target]);
|
|
80
|
+
};
|
|
81
|
+
/** @internal */
|
|
82
|
+
export const cleanupTargetHashes = () => {
|
|
83
|
+
targetHashes.clear();
|
|
52
84
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { makeGhost } from "./makeGhost";
|
|
2
|
-
export { registerModelIdentifier } from "./modelIdentifier";
|
|
3
|
-
export { type ReactGhost, UseGhostReturn } from "./types";
|
|
4
|
-
export { getQueryContext, forwardQueryContext } from "./context";
|
|
5
|
-
export { invalidateGhosts } from "./invalidate";
|
|
6
|
-
export * from "./maybeGhost";
|
|
7
|
-
export { GhostMakerModel, ghostMakerModel } from "./metaData";
|
|
8
|
-
export { getModelId, getModelName } from "./queries";
|
|
1
|
+
export { makeGhost } from "./makeGhost.ts";
|
|
2
|
+
export { registerModelIdentifier } from "./modelIdentifier.ts";
|
|
3
|
+
export { type ReactGhost, UseGhostReturn } from "./types.ts";
|
|
4
|
+
export { getQueryContext, forwardQueryContext } from "./context.ts";
|
|
5
|
+
export { invalidateGhosts } from "./invalidate.ts";
|
|
6
|
+
export * from "./maybeGhost/index.ts";
|
|
7
|
+
export { GhostMakerModel, ghostMakerModel } from "./metaData.ts";
|
|
8
|
+
export { getModelId, getModelName } from "./queries.ts";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type ReactGhost } from "./types";
|
|
1
|
+
import { type ReactGhost } from "./types.ts";
|
|
2
2
|
export declare function makeGhost<T>(target: T): ReactGhost<T>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReactGhost } from "../types";
|
|
2
|
-
import type { MaybeReactGhost, PropsWithFixedUpReactGhosts, PropsWithMaybeReactGhosts } from "./types";
|
|
1
|
+
import { type ReactGhost } from "../types.ts";
|
|
2
|
+
import type { MaybeReactGhost, PropsWithFixedUpReactGhosts, PropsWithMaybeReactGhosts } from "./types.ts";
|
|
3
3
|
export declare function asGhost<T>(maybeGhost: MaybeReactGhost<T>): ReactGhost<T>;
|
|
4
4
|
export declare function asGhostProps<T, TProps extends (keyof T)[] = (keyof T)[]>(props: PropsWithMaybeReactGhosts<T, TProps>, keys?: TProps): PropsWithFixedUpReactGhosts<T, TProps>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./asGhost";
|
|
2
|
-
export * from "./types";
|
|
1
|
+
export * from "./asGhost.ts";
|
|
2
|
+
export * from "./types.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type OrOptional, type ReactGhost } from "../types";
|
|
1
|
+
import { type OrOptional, type ReactGhost } from "../types.ts";
|
|
2
2
|
export type MaybeReactGhost<T> = T extends ReactGhost<infer U> ? ReactGhost<U> | U : T | ReactGhost<T>;
|
|
3
3
|
export type PropsWithMaybeReactGhosts<T, TProps extends (keyof T)[]> = {
|
|
4
4
|
[K in keyof T]: K extends TProps[number] ? MaybeReactGhost<T[K] | OrOptional<T[K]>> : T[K] | OrOptional<T[K]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModelIdentifier } from "./types";
|
|
1
|
+
import type { ModelIdentifier } from "./types.ts";
|
|
2
2
|
export declare const modelIdentifiers: ModelIdentifier[];
|
|
3
3
|
/** @deprecated Use GhostMakerModel (decorator) instead */
|
|
4
4
|
export declare const registerModelIdentifier: (identifier: ModelIdentifier) => void;
|
package/dist/types/polytype.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { GhostMakerModel } from "./metaData";
|
|
1
|
+
export { GhostMakerModel } from "./metaData.ts";
|
package/dist/types/queries.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { GhostChain, GhostChainItem, QueryKey } from "./types";
|
|
1
|
+
import type { GhostChain, GhostChainItem, QueryKey } from "./types.ts";
|
|
2
2
|
export declare const getModelName: (something: unknown) => string | undefined;
|
|
3
3
|
export declare const getModelId: (something: unknown) => string | undefined;
|
|
4
4
|
export declare const queries: {
|
|
5
5
|
ghostmaker: () => string[];
|
|
6
6
|
target: (target: unknown) => string[];
|
|
7
|
-
chainItem: (prev: QueryKey, chainItem: GhostChainItem) =>
|
|
8
|
-
ghostChain: (target: unknown, chain: GhostChain) =>
|
|
7
|
+
chainItem: (prev: QueryKey, chainItem: GhostChainItem) => unknown[];
|
|
8
|
+
ghostChain: (target: unknown, chain: GhostChain) => unknown[];
|
|
9
9
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type GhostChain } from "./types";
|
|
1
|
+
import { type GhostChain } from "./types.ts";
|
|
2
2
|
export declare const resolveGhostChain: (target: unknown, stack: GhostChain) => Promise<unknown>;
|
|
@@ -41,5 +41,5 @@ export declare class ProjectDetailed {
|
|
|
41
41
|
getName(): string;
|
|
42
42
|
getStatus(): Promise<string>;
|
|
43
43
|
}
|
|
44
|
-
export declare const ProjectGhost: import("./types").ReactGhost<typeof Project>;
|
|
45
|
-
export declare const CustomerGhost: import("./types").ReactGhost<typeof Customer>;
|
|
44
|
+
export declare const ProjectGhost: import("./types.ts").ReactGhost<typeof Project>;
|
|
45
|
+
export declare const CustomerGhost: import("./types.ts").ReactGhost<typeof Customer>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -7,13 +7,16 @@ export type AnyFunction = (...args: ExplicitAny[]) => ExplicitAny;
|
|
|
7
7
|
export interface UseQueryReturnType<T> {
|
|
8
8
|
result: T;
|
|
9
9
|
}
|
|
10
|
-
export type
|
|
10
|
+
export type UseGhostOptions<T = unknown> = Omit<UseQueryOptions<UseQueryReturnType<T>>, "queryKey" | "queryFn">;
|
|
11
|
+
/** @deprecated Use `UseGhostOptions<unknown>` instead. */
|
|
12
|
+
export type useGhostOptions = UseGhostOptions<unknown>;
|
|
11
13
|
export interface ReactGhostMethods<T> extends Promise<T> {
|
|
12
|
-
useGhost: (options?:
|
|
13
|
-
use: (options?:
|
|
14
|
+
useGhost: (options?: UseGhostOptions<T>) => UseGhostReturn<T>;
|
|
15
|
+
use: (options?: UseGhostOptions<T>) => T;
|
|
14
16
|
render: (transform?: (item: T) => ReactNode) => ReactNode;
|
|
15
17
|
transform: <U, U2 = U>(fn: (item: T extends ReactGhost<infer T2> ? T2 : T) => U2, dependencies?: DependencyList) => ReactGhost<U2>;
|
|
16
18
|
invalidate: (queryClient: QueryClient) => Promise<void>;
|
|
19
|
+
reset: (queryClient: QueryClient) => Promise<void>;
|
|
17
20
|
}
|
|
18
21
|
export declare const transformFnProp: "___transformFn";
|
|
19
22
|
export declare const isGhostMarker: "___ghostMarker";
|
|
@@ -28,12 +31,14 @@ export type GhostChain = GhostChainItem[];
|
|
|
28
31
|
export type GhostChainTargetType = UnknownRecord | Class<unknown> | null | undefined;
|
|
29
32
|
export type QueryKey = readonly unknown[];
|
|
30
33
|
export type InvalidateGhostFn = () => Promise<void>;
|
|
34
|
+
export type ResetGhostFn = () => Promise<void>;
|
|
31
35
|
export interface GhostChainContext {
|
|
32
36
|
queryKey: QueryKey;
|
|
33
37
|
}
|
|
34
38
|
export interface UseGhostReturn<T> {
|
|
35
39
|
value: T;
|
|
36
40
|
invalidate: InvalidateGhostFn;
|
|
41
|
+
reset: ResetGhostFn;
|
|
37
42
|
}
|
|
38
43
|
export declare function isReactGhost<T>(something: unknown): something is ReactGhost<T>;
|
|
39
44
|
export type ModelIdentifier = (model: unknown) => string | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type GhostChain, type
|
|
2
|
-
export declare const useGhostChain: <T>(target: unknown, chain: GhostChain, options?:
|
|
1
|
+
import { type GhostChain, type UseGhostOptions, type UseGhostReturn } from "./types.ts";
|
|
2
|
+
export declare const useGhostChain: <T>(target: unknown, chain: GhostChain, options?: UseGhostOptions<T>) => UseGhostReturn<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mittwald/react-ghostmaker",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"author": "Mittwald CM Service GmbH & Co. KG <opensource@mittwald.de>",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Marco Falkenberg <m.falkenberg@mittwald.de>"
|
|
@@ -38,38 +38,38 @@
|
|
|
38
38
|
"dist"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@sindresorhus/is": "^7.
|
|
41
|
+
"@sindresorhus/is": "^7.2.0",
|
|
42
42
|
"context": "^3.0.33",
|
|
43
|
-
"object-code": "^
|
|
44
|
-
"type-fest": "^5.
|
|
43
|
+
"object-code": "^2.0.0",
|
|
44
|
+
"type-fest": "^5.4.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@eslint/eslintrc": "^3.3.
|
|
48
|
-
"@eslint/js": "^9.39.
|
|
49
|
-
"@tanstack/react-query": "^5.90.
|
|
47
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
48
|
+
"@eslint/js": "^9.39.2",
|
|
49
|
+
"@tanstack/react-query": "^5.90.20",
|
|
50
50
|
"@testing-library/dom": "^10.4.1",
|
|
51
|
-
"@testing-library/react": "^16.3.
|
|
52
|
-
"@types/react": "^19.2.
|
|
53
|
-
"@types/react-dom": "^19.2.
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
55
|
-
"@typescript-eslint/parser": "^8.
|
|
56
|
-
"eslint": "^9.
|
|
51
|
+
"@testing-library/react": "^16.3.2",
|
|
52
|
+
"@types/react": "^19.2.13",
|
|
53
|
+
"@types/react-dom": "^19.2.3",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
55
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
56
|
+
"eslint": "^9.39.2",
|
|
57
57
|
"eslint-config-prettier": "^10.1.8",
|
|
58
58
|
"eslint-plugin-json": "^4.0.1",
|
|
59
|
-
"eslint-plugin-prettier": "^5.5.
|
|
59
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
60
60
|
"globals": "^16.5.0",
|
|
61
|
-
"happy-dom": "^20.
|
|
61
|
+
"happy-dom": "^20.5.3",
|
|
62
62
|
"license-checker-rseidelsohn": "^4.4.2",
|
|
63
63
|
"polytype": "^0.17.0",
|
|
64
|
-
"prettier": "^3.
|
|
65
|
-
"prettier-plugin-jsdoc": "^1.
|
|
66
|
-
"prettier-plugin-pkgsort": "^0.
|
|
67
|
-
"prettier-plugin-sort-json": "^4.
|
|
68
|
-
"react": "^19.2.
|
|
69
|
-
"react-dom": "^19.2.
|
|
70
|
-
"rimraf": "^6.
|
|
64
|
+
"prettier": "^3.8.1",
|
|
65
|
+
"prettier-plugin-jsdoc": "^1.8.0",
|
|
66
|
+
"prettier-plugin-pkgsort": "^0.3.0",
|
|
67
|
+
"prettier-plugin-sort-json": "^4.2.0",
|
|
68
|
+
"react": "^19.2.4",
|
|
69
|
+
"react-dom": "^19.2.4",
|
|
70
|
+
"rimraf": "^6.1.2",
|
|
71
71
|
"typescript": "^5.9.3",
|
|
72
|
-
"vitest": "^
|
|
72
|
+
"vitest": "^4.0.18"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@tanstack/react-query": "^5",
|