@mearie/vue 0.0.0-next-20260228035926
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/LICENSE +20 -0
- package/README.md +70 -0
- package/dist/index.cjs +173 -0
- package/dist/index.d.cts +115 -0
- package/dist/index.d.mts +115 -0
- package/dist/index.mjs +163 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright 2025 Bae Junehyeon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @mearie/vue
|
|
2
|
+
|
|
3
|
+
Vue bindings for Mearie GraphQL client.
|
|
4
|
+
|
|
5
|
+
This package provides Vue composables, plugins, and the GraphQL client runtime
|
|
6
|
+
for using Mearie in Vue applications.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -D mearie
|
|
12
|
+
npm install @mearie/vue
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The `mearie` package provides build-time code generation, while `@mearie/vue`
|
|
16
|
+
includes the runtime client and Vue-specific composables.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
First, create a client and set up the plugin in your app:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// src/main.ts
|
|
24
|
+
import { createApp } from 'vue';
|
|
25
|
+
import { createClient, httpExchange, cacheExchange, dedupExchange, ClientPlugin } from '@mearie/vue';
|
|
26
|
+
import { schema } from '$mearie';
|
|
27
|
+
import App from './App.vue';
|
|
28
|
+
|
|
29
|
+
const client = createClient({
|
|
30
|
+
schema,
|
|
31
|
+
exchanges: [dedupExchange(), cacheExchange(), httpExchange({ url: 'https://api.example.com/graphql' })],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const app = createApp(App);
|
|
35
|
+
app.use(ClientPlugin, { client });
|
|
36
|
+
app.mount('#app');
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then use it in your components:
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<!-- src/components/UserProfile.vue -->
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import { graphql } from '$mearie';
|
|
45
|
+
import { useQuery } from '@mearie/vue';
|
|
46
|
+
|
|
47
|
+
const props = defineProps<{ userId: string }>();
|
|
48
|
+
|
|
49
|
+
const { data, loading } = useQuery(
|
|
50
|
+
graphql(`
|
|
51
|
+
query GetUser($id: ID!) {
|
|
52
|
+
user(id: $id) {
|
|
53
|
+
id
|
|
54
|
+
name
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`),
|
|
58
|
+
() => ({ id: props.userId }),
|
|
59
|
+
);
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<div v-if="loading">Loading...</div>
|
|
64
|
+
<h1 v-else>{{ data.user.name }}</h1>
|
|
65
|
+
</template>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
Full documentation is available at <https://mearie.dev/frameworks/vue>.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let _mearie_core = require("@mearie/core");
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
let _mearie_core_stream = require("@mearie/core/stream");
|
|
5
|
+
|
|
6
|
+
//#region src/client-plugin.ts
|
|
7
|
+
const ClientKey = Symbol("mearie-client");
|
|
8
|
+
const ClientPlugin = { install(app, options) {
|
|
9
|
+
app.provide(ClientKey, options.client);
|
|
10
|
+
} };
|
|
11
|
+
const useClient = () => {
|
|
12
|
+
const client = (0, vue.inject)(ClientKey);
|
|
13
|
+
if (!client) throw new Error("useClient must be used within a ClientPlugin context");
|
|
14
|
+
return client;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/use-query.ts
|
|
19
|
+
const useQuery = ((query, variables, options) => {
|
|
20
|
+
const client = useClient();
|
|
21
|
+
const initialOpts = (0, vue.toValue)(options);
|
|
22
|
+
const data = (0, vue.ref)(initialOpts?.initialData);
|
|
23
|
+
const loading = (0, vue.ref)(!initialOpts?.skip && !initialOpts?.initialData);
|
|
24
|
+
const error = (0, vue.ref)(void 0);
|
|
25
|
+
let unsubscribe = null;
|
|
26
|
+
let initialized = false;
|
|
27
|
+
const execute = () => {
|
|
28
|
+
unsubscribe?.();
|
|
29
|
+
if ((0, vue.toValue)(options)?.skip) return;
|
|
30
|
+
if (!initialized && initialOpts?.initialData) loading.value = true;
|
|
31
|
+
initialized = true;
|
|
32
|
+
error.value = void 0;
|
|
33
|
+
unsubscribe = (0, _mearie_core_stream.pipe)(client.executeQuery(query, (0, vue.toValue)(variables), (0, vue.toValue)(options)), (0, _mearie_core_stream.subscribe)({ next: (result) => {
|
|
34
|
+
if (result.errors && result.errors.length > 0) {
|
|
35
|
+
error.value = new _mearie_core.AggregatedError(result.errors);
|
|
36
|
+
loading.value = false;
|
|
37
|
+
} else {
|
|
38
|
+
data.value = result.data;
|
|
39
|
+
loading.value = false;
|
|
40
|
+
error.value = void 0;
|
|
41
|
+
}
|
|
42
|
+
} }));
|
|
43
|
+
};
|
|
44
|
+
(0, vue.watchEffect)((onCleanup) => {
|
|
45
|
+
execute();
|
|
46
|
+
onCleanup(() => {
|
|
47
|
+
unsubscribe?.();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
data,
|
|
52
|
+
loading,
|
|
53
|
+
error,
|
|
54
|
+
refetch: execute
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/use-subscription.ts
|
|
60
|
+
const useSubscription = (subscription, ...[variables, options]) => {
|
|
61
|
+
const client = useClient();
|
|
62
|
+
const data = (0, vue.ref)(void 0);
|
|
63
|
+
const loading = (0, vue.ref)(!(0, vue.toValue)(options)?.skip);
|
|
64
|
+
const error = (0, vue.ref)(void 0);
|
|
65
|
+
let unsubscribe = null;
|
|
66
|
+
const execute = () => {
|
|
67
|
+
unsubscribe?.();
|
|
68
|
+
if ((0, vue.toValue)(options)?.skip) return;
|
|
69
|
+
loading.value = true;
|
|
70
|
+
error.value = void 0;
|
|
71
|
+
unsubscribe = (0, _mearie_core_stream.pipe)(client.executeSubscription(subscription, (0, vue.toValue)(variables), (0, vue.toValue)(options)), (0, _mearie_core_stream.subscribe)({ next: (result) => {
|
|
72
|
+
if (result.errors && result.errors.length > 0) {
|
|
73
|
+
const err = new _mearie_core.AggregatedError(result.errors);
|
|
74
|
+
error.value = err;
|
|
75
|
+
loading.value = false;
|
|
76
|
+
(0, vue.toValue)(options)?.onError?.(err);
|
|
77
|
+
} else {
|
|
78
|
+
const resultData = result.data;
|
|
79
|
+
data.value = resultData;
|
|
80
|
+
loading.value = false;
|
|
81
|
+
(0, vue.toValue)(options)?.onData?.(resultData);
|
|
82
|
+
}
|
|
83
|
+
} }));
|
|
84
|
+
};
|
|
85
|
+
(0, vue.watchEffect)((onCleanup) => {
|
|
86
|
+
execute();
|
|
87
|
+
onCleanup(() => {
|
|
88
|
+
unsubscribe?.();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
data,
|
|
93
|
+
loading,
|
|
94
|
+
error
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/use-mutation.ts
|
|
100
|
+
const useMutation = (mutation) => {
|
|
101
|
+
const client = useClient();
|
|
102
|
+
const data = (0, vue.ref)(void 0);
|
|
103
|
+
const loading = (0, vue.ref)(false);
|
|
104
|
+
const error = (0, vue.ref)(void 0);
|
|
105
|
+
const execute = async (variables, options) => {
|
|
106
|
+
loading.value = true;
|
|
107
|
+
error.value = void 0;
|
|
108
|
+
try {
|
|
109
|
+
const result = await (0, _mearie_core_stream.pipe)(client.executeMutation(mutation, variables, options), (0, _mearie_core_stream.take)(1), _mearie_core_stream.collect);
|
|
110
|
+
if (result.errors && result.errors.length > 0) {
|
|
111
|
+
const err = new _mearie_core.AggregatedError(result.errors);
|
|
112
|
+
error.value = err;
|
|
113
|
+
loading.value = false;
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
data.value = result.data;
|
|
117
|
+
loading.value = false;
|
|
118
|
+
return result.data;
|
|
119
|
+
} catch (err) {
|
|
120
|
+
if (err instanceof _mearie_core.AggregatedError) error.value = err;
|
|
121
|
+
loading.value = false;
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return [execute, {
|
|
126
|
+
data,
|
|
127
|
+
loading,
|
|
128
|
+
error
|
|
129
|
+
}];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/use-fragment.ts
|
|
134
|
+
const useFragment = ((fragment, fragmentRef, ...[options]) => {
|
|
135
|
+
const client = useClient();
|
|
136
|
+
const initialRef = (0, vue.toValue)(fragmentRef);
|
|
137
|
+
let initialData;
|
|
138
|
+
if (initialRef == null) initialData = null;
|
|
139
|
+
else {
|
|
140
|
+
const result = (0, _mearie_core_stream.pipe)(client.executeFragment(fragment, initialRef, (0, vue.toValue)(options)), _mearie_core_stream.peek);
|
|
141
|
+
if (result.data === void 0) throw new Error("Fragment data not found");
|
|
142
|
+
initialData = result.data;
|
|
143
|
+
}
|
|
144
|
+
const data = (0, vue.ref)(initialData);
|
|
145
|
+
(0, vue.watchEffect)((onCleanup) => {
|
|
146
|
+
const currentRef = (0, vue.toValue)(fragmentRef);
|
|
147
|
+
if (currentRef == null) {
|
|
148
|
+
data.value = null;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const unsubscribe = (0, _mearie_core_stream.pipe)(client.executeFragment(fragment, currentRef, (0, vue.toValue)(options)), (0, _mearie_core_stream.subscribe)({ next: (result) => {
|
|
152
|
+
if (result.data !== void 0) data.value = result.data;
|
|
153
|
+
} }));
|
|
154
|
+
onCleanup(() => unsubscribe());
|
|
155
|
+
});
|
|
156
|
+
return { get data() {
|
|
157
|
+
return data.value;
|
|
158
|
+
} };
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
//#endregion
|
|
162
|
+
exports.ClientPlugin = ClientPlugin;
|
|
163
|
+
exports.useClient = useClient;
|
|
164
|
+
exports.useFragment = useFragment;
|
|
165
|
+
exports.useMutation = useMutation;
|
|
166
|
+
exports.useQuery = useQuery;
|
|
167
|
+
exports.useSubscription = useSubscription;
|
|
168
|
+
Object.keys(_mearie_core).forEach(function (k) {
|
|
169
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
170
|
+
enumerable: true,
|
|
171
|
+
get: function () { return _mearie_core[k]; }
|
|
172
|
+
});
|
|
173
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { AggregatedError, Artifact, Client, DataOf, FragmentOptions, FragmentRefs, MutationOptions, QueryOptions, SchemaMeta, SubscriptionOptions, VariablesOf } from "@mearie/core";
|
|
2
|
+
import { App, MaybeRefOrGetter, Ref } from "vue";
|
|
3
|
+
export * from "@mearie/core";
|
|
4
|
+
|
|
5
|
+
//#region src/client-plugin.d.ts
|
|
6
|
+
type ClientPluginOptions<TMeta extends SchemaMeta = SchemaMeta> = {
|
|
7
|
+
client: Client<TMeta>;
|
|
8
|
+
};
|
|
9
|
+
declare const ClientPlugin: {
|
|
10
|
+
install<TMeta extends SchemaMeta = SchemaMeta>(app: App, options: ClientPluginOptions<TMeta>): void;
|
|
11
|
+
};
|
|
12
|
+
declare const useClient: <TMeta extends SchemaMeta = SchemaMeta>() => Client<TMeta>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/use-query.d.ts
|
|
15
|
+
type UseQueryOptions<T extends Artifact<'query'> = Artifact<'query'>> = QueryOptions<T> & {
|
|
16
|
+
skip?: boolean;
|
|
17
|
+
};
|
|
18
|
+
type Query<T extends Artifact<'query'>> = {
|
|
19
|
+
data: Ref<undefined>;
|
|
20
|
+
loading: Ref<true>;
|
|
21
|
+
error: Ref<undefined>;
|
|
22
|
+
refetch: () => void;
|
|
23
|
+
} | {
|
|
24
|
+
data: Ref<DataOf<T>>;
|
|
25
|
+
loading: Ref<false>;
|
|
26
|
+
error: Ref<undefined>;
|
|
27
|
+
refetch: () => void;
|
|
28
|
+
} | {
|
|
29
|
+
data: Ref<DataOf<T> | undefined>;
|
|
30
|
+
loading: Ref<false>;
|
|
31
|
+
error: Ref<AggregatedError>;
|
|
32
|
+
refetch: () => void;
|
|
33
|
+
};
|
|
34
|
+
type DefinedQuery<T extends Artifact<'query'>> = {
|
|
35
|
+
data: Ref<DataOf<T>>;
|
|
36
|
+
loading: Ref<true>;
|
|
37
|
+
error: Ref<undefined>;
|
|
38
|
+
refetch: () => void;
|
|
39
|
+
} | {
|
|
40
|
+
data: Ref<DataOf<T>>;
|
|
41
|
+
loading: Ref<false>;
|
|
42
|
+
error: Ref<undefined>;
|
|
43
|
+
refetch: () => void;
|
|
44
|
+
} | {
|
|
45
|
+
data: Ref<DataOf<T>>;
|
|
46
|
+
loading: Ref<false>;
|
|
47
|
+
error: Ref<AggregatedError>;
|
|
48
|
+
refetch: () => void;
|
|
49
|
+
};
|
|
50
|
+
type UseQueryFn = {
|
|
51
|
+
<T extends Artifact<'query'>>(query: T, variables: MaybeRefOrGetter<VariablesOf<T>> | undefined, options: MaybeRefOrGetter<UseQueryOptions<T> & {
|
|
52
|
+
initialData: DataOf<T>;
|
|
53
|
+
}>): DefinedQuery<T>;
|
|
54
|
+
<T extends Artifact<'query'>>(query: T, ...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, MaybeRefOrGetter<UseQueryOptions<T>>?] : [MaybeRefOrGetter<VariablesOf<T>>, MaybeRefOrGetter<UseQueryOptions<T>>?]): Query<T>;
|
|
55
|
+
};
|
|
56
|
+
declare const useQuery: UseQueryFn;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/use-subscription.d.ts
|
|
59
|
+
type Subscription<T extends Artifact<'subscription'>> = {
|
|
60
|
+
data: Ref<undefined>;
|
|
61
|
+
loading: Ref<true>;
|
|
62
|
+
error: Ref<undefined>;
|
|
63
|
+
} | {
|
|
64
|
+
data: Ref<DataOf<T> | undefined>;
|
|
65
|
+
loading: Ref<false>;
|
|
66
|
+
error: Ref<undefined>;
|
|
67
|
+
} | {
|
|
68
|
+
data: Ref<DataOf<T> | undefined>;
|
|
69
|
+
loading: Ref<false>;
|
|
70
|
+
error: Ref<AggregatedError>;
|
|
71
|
+
};
|
|
72
|
+
type UseSubscriptionOptions<T extends Artifact<'subscription'>> = SubscriptionOptions & {
|
|
73
|
+
skip?: boolean;
|
|
74
|
+
onData?: (data: DataOf<T>) => void;
|
|
75
|
+
onError?: (error: AggregatedError) => void;
|
|
76
|
+
};
|
|
77
|
+
declare const useSubscription: <T extends Artifact<"subscription">>(subscription: T, ...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, MaybeRefOrGetter<UseSubscriptionOptions<T>>?] : [MaybeRefOrGetter<VariablesOf<T>>, MaybeRefOrGetter<UseSubscriptionOptions<T>>?]) => Subscription<T>;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/use-mutation.d.ts
|
|
80
|
+
type MutationResult<T extends Artifact<'mutation'>> = {
|
|
81
|
+
data: Ref<undefined>;
|
|
82
|
+
loading: Ref<true>;
|
|
83
|
+
error: Ref<undefined>;
|
|
84
|
+
} | {
|
|
85
|
+
data: Ref<DataOf<T> | undefined>;
|
|
86
|
+
loading: Ref<false>;
|
|
87
|
+
error: Ref<undefined>;
|
|
88
|
+
} | {
|
|
89
|
+
data: Ref<DataOf<T> | undefined>;
|
|
90
|
+
loading: Ref<false>;
|
|
91
|
+
error: Ref<AggregatedError>;
|
|
92
|
+
};
|
|
93
|
+
type UseMutationOptions = MutationOptions;
|
|
94
|
+
type Mutation<T extends Artifact<'mutation'>> = [(...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, UseMutationOptions?] : [VariablesOf<T>, UseMutationOptions?]) => Promise<DataOf<T>>, MutationResult<T>];
|
|
95
|
+
declare const useMutation: <T extends Artifact<"mutation">>(mutation: T) => Mutation<T>;
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/use-fragment.d.ts
|
|
98
|
+
type UseFragmentOptions = FragmentOptions;
|
|
99
|
+
type Fragment<T extends Artifact<'fragment'>> = {
|
|
100
|
+
data: DataOf<T>;
|
|
101
|
+
};
|
|
102
|
+
type FragmentList<T extends Artifact<'fragment'>> = {
|
|
103
|
+
data: DataOf<T>[];
|
|
104
|
+
};
|
|
105
|
+
type OptionalFragment<T extends Artifact<'fragment'>> = {
|
|
106
|
+
data: DataOf<T> | null;
|
|
107
|
+
};
|
|
108
|
+
type UseFragmentFn = {
|
|
109
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']>[]>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): FragmentList<T>;
|
|
110
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']>>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): Fragment<T>;
|
|
111
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']> | null | undefined>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): OptionalFragment<T>;
|
|
112
|
+
};
|
|
113
|
+
declare const useFragment: UseFragmentFn;
|
|
114
|
+
//#endregion
|
|
115
|
+
export { ClientPlugin, type ClientPluginOptions, type DefinedQuery, type Fragment, type FragmentList, type Mutation, type OptionalFragment, type Query, type Subscription, type UseFragmentOptions, type UseMutationOptions, type UseQueryOptions, type UseSubscriptionOptions, useClient, useFragment, useMutation, useQuery, useSubscription };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { AggregatedError, Artifact, Client, DataOf, FragmentOptions, FragmentRefs, MutationOptions, QueryOptions, SchemaMeta, SubscriptionOptions, VariablesOf } from "@mearie/core";
|
|
2
|
+
import { App, MaybeRefOrGetter, Ref } from "vue";
|
|
3
|
+
export * from "@mearie/core";
|
|
4
|
+
|
|
5
|
+
//#region src/client-plugin.d.ts
|
|
6
|
+
type ClientPluginOptions<TMeta extends SchemaMeta = SchemaMeta> = {
|
|
7
|
+
client: Client<TMeta>;
|
|
8
|
+
};
|
|
9
|
+
declare const ClientPlugin: {
|
|
10
|
+
install<TMeta extends SchemaMeta = SchemaMeta>(app: App, options: ClientPluginOptions<TMeta>): void;
|
|
11
|
+
};
|
|
12
|
+
declare const useClient: <TMeta extends SchemaMeta = SchemaMeta>() => Client<TMeta>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/use-query.d.ts
|
|
15
|
+
type UseQueryOptions<T extends Artifact<'query'> = Artifact<'query'>> = QueryOptions<T> & {
|
|
16
|
+
skip?: boolean;
|
|
17
|
+
};
|
|
18
|
+
type Query<T extends Artifact<'query'>> = {
|
|
19
|
+
data: Ref<undefined>;
|
|
20
|
+
loading: Ref<true>;
|
|
21
|
+
error: Ref<undefined>;
|
|
22
|
+
refetch: () => void;
|
|
23
|
+
} | {
|
|
24
|
+
data: Ref<DataOf<T>>;
|
|
25
|
+
loading: Ref<false>;
|
|
26
|
+
error: Ref<undefined>;
|
|
27
|
+
refetch: () => void;
|
|
28
|
+
} | {
|
|
29
|
+
data: Ref<DataOf<T> | undefined>;
|
|
30
|
+
loading: Ref<false>;
|
|
31
|
+
error: Ref<AggregatedError>;
|
|
32
|
+
refetch: () => void;
|
|
33
|
+
};
|
|
34
|
+
type DefinedQuery<T extends Artifact<'query'>> = {
|
|
35
|
+
data: Ref<DataOf<T>>;
|
|
36
|
+
loading: Ref<true>;
|
|
37
|
+
error: Ref<undefined>;
|
|
38
|
+
refetch: () => void;
|
|
39
|
+
} | {
|
|
40
|
+
data: Ref<DataOf<T>>;
|
|
41
|
+
loading: Ref<false>;
|
|
42
|
+
error: Ref<undefined>;
|
|
43
|
+
refetch: () => void;
|
|
44
|
+
} | {
|
|
45
|
+
data: Ref<DataOf<T>>;
|
|
46
|
+
loading: Ref<false>;
|
|
47
|
+
error: Ref<AggregatedError>;
|
|
48
|
+
refetch: () => void;
|
|
49
|
+
};
|
|
50
|
+
type UseQueryFn = {
|
|
51
|
+
<T extends Artifact<'query'>>(query: T, variables: MaybeRefOrGetter<VariablesOf<T>> | undefined, options: MaybeRefOrGetter<UseQueryOptions<T> & {
|
|
52
|
+
initialData: DataOf<T>;
|
|
53
|
+
}>): DefinedQuery<T>;
|
|
54
|
+
<T extends Artifact<'query'>>(query: T, ...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, MaybeRefOrGetter<UseQueryOptions<T>>?] : [MaybeRefOrGetter<VariablesOf<T>>, MaybeRefOrGetter<UseQueryOptions<T>>?]): Query<T>;
|
|
55
|
+
};
|
|
56
|
+
declare const useQuery: UseQueryFn;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/use-subscription.d.ts
|
|
59
|
+
type Subscription<T extends Artifact<'subscription'>> = {
|
|
60
|
+
data: Ref<undefined>;
|
|
61
|
+
loading: Ref<true>;
|
|
62
|
+
error: Ref<undefined>;
|
|
63
|
+
} | {
|
|
64
|
+
data: Ref<DataOf<T> | undefined>;
|
|
65
|
+
loading: Ref<false>;
|
|
66
|
+
error: Ref<undefined>;
|
|
67
|
+
} | {
|
|
68
|
+
data: Ref<DataOf<T> | undefined>;
|
|
69
|
+
loading: Ref<false>;
|
|
70
|
+
error: Ref<AggregatedError>;
|
|
71
|
+
};
|
|
72
|
+
type UseSubscriptionOptions<T extends Artifact<'subscription'>> = SubscriptionOptions & {
|
|
73
|
+
skip?: boolean;
|
|
74
|
+
onData?: (data: DataOf<T>) => void;
|
|
75
|
+
onError?: (error: AggregatedError) => void;
|
|
76
|
+
};
|
|
77
|
+
declare const useSubscription: <T extends Artifact<"subscription">>(subscription: T, ...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, MaybeRefOrGetter<UseSubscriptionOptions<T>>?] : [MaybeRefOrGetter<VariablesOf<T>>, MaybeRefOrGetter<UseSubscriptionOptions<T>>?]) => Subscription<T>;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/use-mutation.d.ts
|
|
80
|
+
type MutationResult<T extends Artifact<'mutation'>> = {
|
|
81
|
+
data: Ref<undefined>;
|
|
82
|
+
loading: Ref<true>;
|
|
83
|
+
error: Ref<undefined>;
|
|
84
|
+
} | {
|
|
85
|
+
data: Ref<DataOf<T> | undefined>;
|
|
86
|
+
loading: Ref<false>;
|
|
87
|
+
error: Ref<undefined>;
|
|
88
|
+
} | {
|
|
89
|
+
data: Ref<DataOf<T> | undefined>;
|
|
90
|
+
loading: Ref<false>;
|
|
91
|
+
error: Ref<AggregatedError>;
|
|
92
|
+
};
|
|
93
|
+
type UseMutationOptions = MutationOptions;
|
|
94
|
+
type Mutation<T extends Artifact<'mutation'>> = [(...[variables, options]: VariablesOf<T> extends Record<string, never> ? [undefined?, UseMutationOptions?] : [VariablesOf<T>, UseMutationOptions?]) => Promise<DataOf<T>>, MutationResult<T>];
|
|
95
|
+
declare const useMutation: <T extends Artifact<"mutation">>(mutation: T) => Mutation<T>;
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/use-fragment.d.ts
|
|
98
|
+
type UseFragmentOptions = FragmentOptions;
|
|
99
|
+
type Fragment<T extends Artifact<'fragment'>> = {
|
|
100
|
+
data: DataOf<T>;
|
|
101
|
+
};
|
|
102
|
+
type FragmentList<T extends Artifact<'fragment'>> = {
|
|
103
|
+
data: DataOf<T>[];
|
|
104
|
+
};
|
|
105
|
+
type OptionalFragment<T extends Artifact<'fragment'>> = {
|
|
106
|
+
data: DataOf<T> | null;
|
|
107
|
+
};
|
|
108
|
+
type UseFragmentFn = {
|
|
109
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']>[]>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): FragmentList<T>;
|
|
110
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']>>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): Fragment<T>;
|
|
111
|
+
<T extends Artifact<'fragment'>>(fragment: T, fragmentRef: MaybeRefOrGetter<FragmentRefs<T['name']> | null | undefined>, ...options: [MaybeRefOrGetter<UseFragmentOptions>?]): OptionalFragment<T>;
|
|
112
|
+
};
|
|
113
|
+
declare const useFragment: UseFragmentFn;
|
|
114
|
+
//#endregion
|
|
115
|
+
export { ClientPlugin, type ClientPluginOptions, type DefinedQuery, type Fragment, type FragmentList, type Mutation, type OptionalFragment, type Query, type Subscription, type UseFragmentOptions, type UseMutationOptions, type UseQueryOptions, type UseSubscriptionOptions, useClient, useFragment, useMutation, useQuery, useSubscription };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { AggregatedError } from "@mearie/core";
|
|
2
|
+
import { inject, ref, toValue, watchEffect } from "vue";
|
|
3
|
+
import { collect, peek, pipe, subscribe, take } from "@mearie/core/stream";
|
|
4
|
+
|
|
5
|
+
export * from "@mearie/core"
|
|
6
|
+
|
|
7
|
+
//#region src/client-plugin.ts
|
|
8
|
+
const ClientKey = Symbol("mearie-client");
|
|
9
|
+
const ClientPlugin = { install(app, options) {
|
|
10
|
+
app.provide(ClientKey, options.client);
|
|
11
|
+
} };
|
|
12
|
+
const useClient = () => {
|
|
13
|
+
const client = inject(ClientKey);
|
|
14
|
+
if (!client) throw new Error("useClient must be used within a ClientPlugin context");
|
|
15
|
+
return client;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/use-query.ts
|
|
20
|
+
const useQuery = ((query, variables, options) => {
|
|
21
|
+
const client = useClient();
|
|
22
|
+
const initialOpts = toValue(options);
|
|
23
|
+
const data = ref(initialOpts?.initialData);
|
|
24
|
+
const loading = ref(!initialOpts?.skip && !initialOpts?.initialData);
|
|
25
|
+
const error = ref(void 0);
|
|
26
|
+
let unsubscribe = null;
|
|
27
|
+
let initialized = false;
|
|
28
|
+
const execute = () => {
|
|
29
|
+
unsubscribe?.();
|
|
30
|
+
if (toValue(options)?.skip) return;
|
|
31
|
+
if (!initialized && initialOpts?.initialData) loading.value = true;
|
|
32
|
+
initialized = true;
|
|
33
|
+
error.value = void 0;
|
|
34
|
+
unsubscribe = pipe(client.executeQuery(query, toValue(variables), toValue(options)), subscribe({ next: (result) => {
|
|
35
|
+
if (result.errors && result.errors.length > 0) {
|
|
36
|
+
error.value = new AggregatedError(result.errors);
|
|
37
|
+
loading.value = false;
|
|
38
|
+
} else {
|
|
39
|
+
data.value = result.data;
|
|
40
|
+
loading.value = false;
|
|
41
|
+
error.value = void 0;
|
|
42
|
+
}
|
|
43
|
+
} }));
|
|
44
|
+
};
|
|
45
|
+
watchEffect((onCleanup) => {
|
|
46
|
+
execute();
|
|
47
|
+
onCleanup(() => {
|
|
48
|
+
unsubscribe?.();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
data,
|
|
53
|
+
loading,
|
|
54
|
+
error,
|
|
55
|
+
refetch: execute
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/use-subscription.ts
|
|
61
|
+
const useSubscription = (subscription, ...[variables, options]) => {
|
|
62
|
+
const client = useClient();
|
|
63
|
+
const data = ref(void 0);
|
|
64
|
+
const loading = ref(!toValue(options)?.skip);
|
|
65
|
+
const error = ref(void 0);
|
|
66
|
+
let unsubscribe = null;
|
|
67
|
+
const execute = () => {
|
|
68
|
+
unsubscribe?.();
|
|
69
|
+
if (toValue(options)?.skip) return;
|
|
70
|
+
loading.value = true;
|
|
71
|
+
error.value = void 0;
|
|
72
|
+
unsubscribe = pipe(client.executeSubscription(subscription, toValue(variables), toValue(options)), subscribe({ next: (result) => {
|
|
73
|
+
if (result.errors && result.errors.length > 0) {
|
|
74
|
+
const err = new AggregatedError(result.errors);
|
|
75
|
+
error.value = err;
|
|
76
|
+
loading.value = false;
|
|
77
|
+
toValue(options)?.onError?.(err);
|
|
78
|
+
} else {
|
|
79
|
+
const resultData = result.data;
|
|
80
|
+
data.value = resultData;
|
|
81
|
+
loading.value = false;
|
|
82
|
+
toValue(options)?.onData?.(resultData);
|
|
83
|
+
}
|
|
84
|
+
} }));
|
|
85
|
+
};
|
|
86
|
+
watchEffect((onCleanup) => {
|
|
87
|
+
execute();
|
|
88
|
+
onCleanup(() => {
|
|
89
|
+
unsubscribe?.();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
data,
|
|
94
|
+
loading,
|
|
95
|
+
error
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/use-mutation.ts
|
|
101
|
+
const useMutation = (mutation) => {
|
|
102
|
+
const client = useClient();
|
|
103
|
+
const data = ref(void 0);
|
|
104
|
+
const loading = ref(false);
|
|
105
|
+
const error = ref(void 0);
|
|
106
|
+
const execute = async (variables, options) => {
|
|
107
|
+
loading.value = true;
|
|
108
|
+
error.value = void 0;
|
|
109
|
+
try {
|
|
110
|
+
const result = await pipe(client.executeMutation(mutation, variables, options), take(1), collect);
|
|
111
|
+
if (result.errors && result.errors.length > 0) {
|
|
112
|
+
const err = new AggregatedError(result.errors);
|
|
113
|
+
error.value = err;
|
|
114
|
+
loading.value = false;
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
data.value = result.data;
|
|
118
|
+
loading.value = false;
|
|
119
|
+
return result.data;
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (err instanceof AggregatedError) error.value = err;
|
|
122
|
+
loading.value = false;
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
return [execute, {
|
|
127
|
+
data,
|
|
128
|
+
loading,
|
|
129
|
+
error
|
|
130
|
+
}];
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/use-fragment.ts
|
|
135
|
+
const useFragment = ((fragment, fragmentRef, ...[options]) => {
|
|
136
|
+
const client = useClient();
|
|
137
|
+
const initialRef = toValue(fragmentRef);
|
|
138
|
+
let initialData;
|
|
139
|
+
if (initialRef == null) initialData = null;
|
|
140
|
+
else {
|
|
141
|
+
const result = pipe(client.executeFragment(fragment, initialRef, toValue(options)), peek);
|
|
142
|
+
if (result.data === void 0) throw new Error("Fragment data not found");
|
|
143
|
+
initialData = result.data;
|
|
144
|
+
}
|
|
145
|
+
const data = ref(initialData);
|
|
146
|
+
watchEffect((onCleanup) => {
|
|
147
|
+
const currentRef = toValue(fragmentRef);
|
|
148
|
+
if (currentRef == null) {
|
|
149
|
+
data.value = null;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const unsubscribe = pipe(client.executeFragment(fragment, currentRef, toValue(options)), subscribe({ next: (result) => {
|
|
153
|
+
if (result.data !== void 0) data.value = result.data;
|
|
154
|
+
} }));
|
|
155
|
+
onCleanup(() => unsubscribe());
|
|
156
|
+
});
|
|
157
|
+
return { get data() {
|
|
158
|
+
return data.value;
|
|
159
|
+
} };
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
//#endregion
|
|
163
|
+
export { ClientPlugin, useClient, useFragment, useMutation, useQuery, useSubscription };
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mearie/vue",
|
|
3
|
+
"version": "0.0.0-next-20260228035926",
|
|
4
|
+
"description": "Type-safe, zero-overhead GraphQL client",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"graphql",
|
|
7
|
+
"graphql-client",
|
|
8
|
+
"typescript",
|
|
9
|
+
"codegen",
|
|
10
|
+
"cache"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/devunt/mearie#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/devunt/mearie/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/devunt/mearie.git",
|
|
19
|
+
"directory": "packages/vue"
|
|
20
|
+
},
|
|
21
|
+
"funding": {
|
|
22
|
+
"type": "github",
|
|
23
|
+
"url": "https://github.com/sponsors/devunt"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Bae Junehyeon <finn@penxle.io>",
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"type": "module",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/index.d.mts",
|
|
33
|
+
"default": "./dist/index.mjs"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/index.d.cts",
|
|
37
|
+
"default": "./dist/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"package.json",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@mearie/core": "0.0.0-next-20260228035926"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"tsdown": "^0.20.3",
|
|
52
|
+
"typescript": "^5.9.3",
|
|
53
|
+
"vue": "^3.5.29"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"vue": "^3.3.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"bun": ">=1.2.0",
|
|
60
|
+
"deno": ">=2.2.0",
|
|
61
|
+
"node": ">=20.0.0"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsdown",
|
|
68
|
+
"typecheck": "tsc"
|
|
69
|
+
},
|
|
70
|
+
"main": "./dist/index.cjs",
|
|
71
|
+
"module": "./dist/index.mjs",
|
|
72
|
+
"types": "./dist/index.d.mts"
|
|
73
|
+
}
|