@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 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
+ });
@@ -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 };
@@ -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
+ }