@quazardous/quarkernel-vue 2.1.0

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 ADDED
@@ -0,0 +1,90 @@
1
+ # @quazardous/quarkernel-vue
2
+
3
+ Vue 3 adapter for QuarKernel - seamless event kernel integration with Vue's reactivity system.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @quazardous/quarkernel @quazardous/quarkernel-vue
9
+ # or
10
+ pnpm add @quazardous/quarkernel @quazardous/quarkernel-vue
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### 1. Install the Plugin
16
+
17
+ ```typescript
18
+ import { createApp } from 'vue';
19
+ import { createKernel } from '@quazardous/quarkernel';
20
+ import { QuarKernelPlugin } from '@quazardous/quarkernel-vue';
21
+ import App from './App.vue';
22
+
23
+ const qk = createKernel();
24
+ const app = createApp(App);
25
+
26
+ app.use(QuarKernelPlugin, { kernel });
27
+ app.mount('#app');
28
+ ```
29
+
30
+ ### 2. Use in Components
31
+
32
+ ```vue
33
+ <script setup lang="ts">
34
+ import { useKernel } from '@quazardous/quarkernel-vue';
35
+ import { onMounted } from 'vue';
36
+
37
+ const qk = useKernel();
38
+
39
+ onMounted(() => {
40
+ qk.on('user:login', async (event) => {
41
+ console.log('User logged in:', event.data);
42
+ });
43
+ });
44
+
45
+ async function login() {
46
+ await qk.emit('user:login', { userId: '123' });
47
+ }
48
+ </script>
49
+ ```
50
+
51
+ ## API
52
+
53
+ ### QuarKernelPlugin
54
+
55
+ Vue plugin that registers the kernel instance globally.
56
+
57
+ **Options:**
58
+ - `kernel`: Kernel instance to provide globally (required)
59
+
60
+ ### useKernel()
61
+
62
+ Composable to access the kernel instance from within component setup functions.
63
+
64
+ **Returns:** The kernel instance provided via the plugin
65
+
66
+ **Throws:**
67
+ - Error if called outside setup() context
68
+ - Error if plugin not installed
69
+
70
+ **SSR Warning:** Warns when accessed during server-side rendering
71
+
72
+ ## TypeScript Support
73
+
74
+ Full TypeScript support with typed events:
75
+
76
+ ```typescript
77
+ interface AppEvents {
78
+ 'user:login': { userId: string };
79
+ 'user:logout': { userId: string };
80
+ }
81
+
82
+ const qk = createKernel<AppEvents>();
83
+
84
+ // In component
85
+ const qk = useKernel<typeof kernel>();
86
+ ```
87
+
88
+ ## License
89
+
90
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+
5
+ // src/plugin.ts
6
+ var KERNEL_INJECTION_KEY = /* @__PURE__ */ Symbol("quarkernel");
7
+ var QuarKernelPlugin = {
8
+ install(app, options) {
9
+ if (!options || !options.kernel) {
10
+ throw new Error("[QuarKernel Vue] Plugin requires a kernel instance in options");
11
+ }
12
+ app.provide(KERNEL_INJECTION_KEY, options.kernel);
13
+ }
14
+ };
15
+ function isSSR() {
16
+ return typeof window === "undefined";
17
+ }
18
+ function useKernel() {
19
+ const instance = vue.getCurrentInstance();
20
+ if (!instance) {
21
+ throw new Error("[QuarKernel Vue] useKernel() must be called within setup() function");
22
+ }
23
+ if (isSSR()) {
24
+ console.warn(
25
+ "[QuarKernel Vue] useKernel() called during server-side rendering. Kernel events should typically run client-side only. Ensure you guard kernel usage in onMounted() or similar lifecycle hooks."
26
+ );
27
+ }
28
+ const kernel = vue.inject(KERNEL_INJECTION_KEY);
29
+ if (!kernel) {
30
+ throw new Error(
31
+ "[QuarKernel Vue] Kernel instance not found. Did you install QuarKernelPlugin with app.use(QuarKernelPlugin, { kernel })?"
32
+ );
33
+ }
34
+ return kernel;
35
+ }
36
+ function useOn(eventName, handler, options) {
37
+ const kernel = useKernel();
38
+ const unbind = kernel.on(eventName, handler, options);
39
+ vue.onUnmounted(() => {
40
+ unbind();
41
+ });
42
+ return unbind;
43
+ }
44
+ function useEventState(eventName, initialValue, options) {
45
+ const kernel = useKernel();
46
+ const state = vue.ref(initialValue);
47
+ const { transform, ...listenerOptions } = options || {};
48
+ const transformFn = transform || ((event) => event.data);
49
+ const unbind = kernel.on(
50
+ eventName,
51
+ (event) => {
52
+ state.value = transformFn(event);
53
+ },
54
+ listenerOptions
55
+ );
56
+ vue.onUnmounted(() => {
57
+ unbind();
58
+ });
59
+ return state;
60
+ }
61
+
62
+ exports.KERNEL_INJECTION_KEY = KERNEL_INJECTION_KEY;
63
+ exports.QuarKernelPlugin = QuarKernelPlugin;
64
+ exports.useEventState = useEventState;
65
+ exports.useKernel = useKernel;
66
+ exports.useOn = useOn;
67
+ //# sourceMappingURL=index.cjs.map
68
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin.ts","../src/use-kernel.ts","../src/use-on.ts","../src/use-event-state.ts"],"names":["getCurrentInstance","inject","onUnmounted","ref"],"mappings":";;;;;AAcO,IAAM,oBAAA,0BAA8B,YAAY;AA2BhD,IAAM,gBAAA,GAA2B;AAAA,EACtC,OAAA,CAAQ,KAAU,OAAA,EAAkC;AAClD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAC/B,MAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,IACjF;AAEA,IAAA,GAAA,CAAI,OAAA,CAAQ,oBAAA,EAAsB,OAAA,CAAQ,MAAM,CAAA;AAAA,EAClD;AACF;AClCA,SAAS,KAAA,GAAiB;AACxB,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AA0BO,SAAS,SAAA,GAA0C;AAExD,EAAA,MAAM,WAAWA,sBAAA,EAAmB;AACpC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,EACvF;AAGA,EAAA,IAAI,OAAM,EAAG;AACX,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KAGF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAASC,WAAU,oBAAoB,CAAA;AAE7C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;ACpBO,SAAS,KAAA,CACd,SAAA,EACA,OAAA,EACA,OAAA,EACY;AACZ,EAAA,MAAM,SAAS,SAAA,EAAU;AAGzB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,EAAA,CAAG,SAAA,EAAW,SAAS,OAAO,CAAA;AAGpD,EAAAC,eAAA,CAAY,MAAM;AAChB,IAAA,MAAA,EAAO;AAAA,EACT,CAAC,CAAA;AAGD,EAAA,OAAO,MAAA;AACT;ACAO,SAAS,aAAA,CACd,SAAA,EACA,YAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,KAAA,GAAQC,QAAO,YAAY,CAAA;AAGjC,EAAA,MAAM,EAAE,SAAA,EAAW,GAAG,eAAA,EAAgB,GAAI,WAAW,EAAC;AACtD,EAAA,MAAM,WAAA,GAAc,SAAA,KAAc,CAAC,KAAA,KAAwB,KAAA,CAAM,IAAA,CAAA;AAGjE,EAAA,MAAM,SAAS,MAAA,CAAO,EAAA;AAAA,IACpB,SAAA;AAAA,IACA,CAAC,KAAA,KAAwB;AACvB,MAAA,KAAA,CAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAAA,IACjC,CAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAAD,gBAAY,MAAM;AAChB,IAAA,MAAA,EAAO;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * Vue plugin for QuarKernel integration\n *\n * Provides global kernel instance access via Vue's provide/inject system.\n * Use with app.use(QuarKernelPlugin, { kernel })\n */\n\nimport type { App, Plugin } from 'vue';\nimport type { Kernel } from '@quazardous/quarkernel';\n\n/**\n * Injection key for kernel instance\n * @internal\n */\nexport const KERNEL_INJECTION_KEY = Symbol('quarkernel');\n\n/**\n * Plugin options\n */\nexport interface QuarKernelPluginOptions {\n /** Kernel instance to provide globally */\n kernel: Kernel;\n}\n\n/**\n * QuarKernel Vue plugin\n *\n * Registers kernel instance globally for access via useKernel() composable\n *\n * @example\n * ```ts\n * import { createApp } from 'vue';\n * import { createKernel } from '@quazardous/quarkernel';\n * import { QuarKernelPlugin } from '@quazardous/quarkernel-vue';\n *\n * const kernel = createKernel();\n * const app = createApp(App);\n *\n * app.use(QuarKernelPlugin, { kernel });\n * ```\n */\nexport const QuarKernelPlugin: Plugin = {\n install(app: App, options: QuarKernelPluginOptions) {\n if (!options || !options.kernel) {\n throw new Error('[QuarKernel Vue] Plugin requires a kernel instance in options');\n }\n\n app.provide(KERNEL_INJECTION_KEY, options.kernel);\n },\n};\n","/**\n * Vue composable for accessing QuarKernel instance\n *\n * Provides type-safe access to the kernel instance registered via plugin.\n * Includes SSR guards to prevent server-side usage.\n */\n\nimport { inject, getCurrentInstance } from 'vue';\nimport type { Kernel } from '@quazardous/quarkernel';\nimport { KERNEL_INJECTION_KEY } from './plugin.js';\n\n/**\n * Check if running in SSR context\n * @internal\n */\nfunction isSSR(): boolean {\n return typeof window === 'undefined';\n}\n\n/**\n * Composable to access QuarKernel instance from components\n *\n * Must be called within setup() function of a component where the plugin was installed.\n * Throws error if plugin not installed or called outside setup context.\n * Warns when accessed during SSR.\n *\n * @example\n * ```ts\n * import { useKernel } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * const kernel = useKernel();\n *\n * kernel.on('user:login', async (event) => {\n * console.log('User logged in:', event.data);\n * });\n *\n * return {};\n * }\n * }\n * ```\n */\nexport function useKernel<T extends Kernel = Kernel>(): T {\n // Check if called within Vue component setup\n const instance = getCurrentInstance();\n if (!instance) {\n throw new Error('[QuarKernel Vue] useKernel() must be called within setup() function');\n }\n\n // SSR guard - warn but don't block (for flexibility)\n if (isSSR()) {\n console.warn(\n '[QuarKernel Vue] useKernel() called during server-side rendering. ' +\n 'Kernel events should typically run client-side only. ' +\n 'Ensure you guard kernel usage in onMounted() or similar lifecycle hooks.'\n );\n }\n\n // Inject kernel instance\n const kernel = inject<T>(KERNEL_INJECTION_KEY);\n\n if (!kernel) {\n throw new Error(\n '[QuarKernel Vue] Kernel instance not found. ' +\n 'Did you install QuarKernelPlugin with app.use(QuarKernelPlugin, { kernel })?'\n );\n }\n\n return kernel;\n}\n","/**\n * Vue composable for event listener registration with automatic cleanup\n *\n * Automatically removes the listener when the component is unmounted.\n * Supports manual cleanup via AbortSignal.\n */\n\nimport { onUnmounted } from 'vue';\nimport type { ListenerFunction, ListenerOptions } from '@quazardous/quarkernel';\nimport { useKernel } from './use-kernel.js';\n\n/**\n * Composable to register event listeners with automatic cleanup\n *\n * The listener is automatically removed when the component unmounts via Vue's\n * onUnmounted lifecycle hook. Manual cleanup is also supported via AbortSignal.\n *\n * @template K - Event name type\n * @param eventName - Event name to listen for\n * @param handler - Listener function\n * @param options - Listener options (optional)\n * @returns Cleanup function to manually remove listener\n *\n * @example\n * ```ts\n * import { useOn } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * // Automatically cleaned up on unmount\n * useOn('user:login', async (event) => {\n * console.log('User logged in:', event.data);\n * });\n *\n * // With options\n * useOn('data:update', handler, {\n * priority: 10,\n * id: 'my-listener'\n * });\n *\n * // Manual cleanup via AbortSignal\n * const controller = new AbortController();\n * useOn('events', handler, {\n * signal: controller.signal\n * });\n * // Later: controller.abort();\n * }\n * }\n * ```\n */\nexport function useOn<K extends string = string>(\n eventName: K,\n handler: ListenerFunction,\n options?: ListenerOptions\n): () => void {\n const kernel = useKernel();\n\n // Register listener on kernel\n const unbind = kernel.on(eventName, handler, options);\n\n // Auto-cleanup on component unmount\n onUnmounted(() => {\n unbind();\n });\n\n // Return unbind for manual cleanup\n return unbind;\n}\n","/**\n * Vue composable for reactive event state\n *\n * Maintains a reactive ref that updates whenever the specified event is emitted.\n * Automatically removes the listener when the component is unmounted.\n */\n\nimport { ref, onUnmounted } from 'vue';\nimport type { Ref } from 'vue';\nimport type { ListenerOptions, IKernelEvent } from '@quazardous/quarkernel';\nimport { useKernel } from './use-kernel.js';\n\n/**\n * Options for useEventState composable\n */\nexport interface UseEventStateOptions extends Omit<ListenerOptions, 'once'> {\n /**\n * Transform function to extract value from event\n * Default: returns event.data\n */\n transform?: (event: IKernelEvent) => any;\n}\n\n/**\n * Composable to maintain reactive state that updates on events\n *\n * Creates a Vue reactive ref that automatically updates when the specified\n * event is emitted. The listener is automatically removed when the component\n * unmounts via Vue's onUnmounted lifecycle hook.\n *\n * @template T - Value type\n * @template K - Event name type\n * @param eventName - Event name to listen for\n * @param initialValue - Initial value for the ref\n * @param options - Listener options and transform function (optional)\n * @returns Reactive ref that updates on events\n *\n * @example\n * ```ts\n * import { useEventState } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * // Simple usage - updates with event.data\n * const userCount = useEventState('user:count', 0);\n *\n * // With transform function\n * const userName = useEventState(\n * 'user:login',\n * 'Guest',\n * {\n * transform: (event) => event.data.name\n * }\n * );\n *\n * // With manual cleanup\n * const controller = new AbortController();\n * const status = useEventState('status', 'idle', {\n * signal: controller.signal\n * });\n * // Later: controller.abort();\n *\n * return { userCount, userName, status };\n * }\n * }\n * ```\n */\nexport function useEventState<T = any, K extends string = string>(\n eventName: K,\n initialValue: T,\n options?: UseEventStateOptions\n): Ref<T> {\n const kernel = useKernel();\n const state = ref<T>(initialValue) as Ref<T>;\n\n // Extract transform function from options\n const { transform, ...listenerOptions } = options || {};\n const transformFn = transform || ((event: IKernelEvent) => event.data);\n\n // Register listener that updates state\n const unbind = kernel.on(\n eventName,\n (event: IKernelEvent) => {\n state.value = transformFn(event);\n },\n listenerOptions\n );\n\n // Auto-cleanup on component unmount\n onUnmounted(() => {\n unbind();\n });\n\n return state;\n}\n"]}
@@ -0,0 +1,186 @@
1
+ import { Plugin, Ref } from 'vue';
2
+ import { Kernel, ListenerFunction, ListenerOptions, IKernelEvent } from '@quazardous/quarkernel';
3
+
4
+ /**
5
+ * Vue plugin for QuarKernel integration
6
+ *
7
+ * Provides global kernel instance access via Vue's provide/inject system.
8
+ * Use with app.use(QuarKernelPlugin, { kernel })
9
+ */
10
+
11
+ /**
12
+ * Injection key for kernel instance
13
+ * @internal
14
+ */
15
+ declare const KERNEL_INJECTION_KEY: unique symbol;
16
+ /**
17
+ * Plugin options
18
+ */
19
+ interface QuarKernelPluginOptions {
20
+ /** Kernel instance to provide globally */
21
+ kernel: Kernel;
22
+ }
23
+ /**
24
+ * QuarKernel Vue plugin
25
+ *
26
+ * Registers kernel instance globally for access via useKernel() composable
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { createApp } from 'vue';
31
+ * import { createKernel } from '@quazardous/quarkernel';
32
+ * import { QuarKernelPlugin } from '@quazardous/quarkernel-vue';
33
+ *
34
+ * const kernel = createKernel();
35
+ * const app = createApp(App);
36
+ *
37
+ * app.use(QuarKernelPlugin, { kernel });
38
+ * ```
39
+ */
40
+ declare const QuarKernelPlugin: Plugin;
41
+
42
+ /**
43
+ * Vue composable for accessing QuarKernel instance
44
+ *
45
+ * Provides type-safe access to the kernel instance registered via plugin.
46
+ * Includes SSR guards to prevent server-side usage.
47
+ */
48
+
49
+ /**
50
+ * Composable to access QuarKernel instance from components
51
+ *
52
+ * Must be called within setup() function of a component where the plugin was installed.
53
+ * Throws error if plugin not installed or called outside setup context.
54
+ * Warns when accessed during SSR.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import { useKernel } from '@quazardous/quarkernel-vue';
59
+ *
60
+ * export default {
61
+ * setup() {
62
+ * const kernel = useKernel();
63
+ *
64
+ * kernel.on('user:login', async (event) => {
65
+ * console.log('User logged in:', event.data);
66
+ * });
67
+ *
68
+ * return {};
69
+ * }
70
+ * }
71
+ * ```
72
+ */
73
+ declare function useKernel<T extends Kernel = Kernel>(): T;
74
+
75
+ /**
76
+ * Vue composable for event listener registration with automatic cleanup
77
+ *
78
+ * Automatically removes the listener when the component is unmounted.
79
+ * Supports manual cleanup via AbortSignal.
80
+ */
81
+
82
+ /**
83
+ * Composable to register event listeners with automatic cleanup
84
+ *
85
+ * The listener is automatically removed when the component unmounts via Vue's
86
+ * onUnmounted lifecycle hook. Manual cleanup is also supported via AbortSignal.
87
+ *
88
+ * @template K - Event name type
89
+ * @param eventName - Event name to listen for
90
+ * @param handler - Listener function
91
+ * @param options - Listener options (optional)
92
+ * @returns Cleanup function to manually remove listener
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * import { useOn } from '@quazardous/quarkernel-vue';
97
+ *
98
+ * export default {
99
+ * setup() {
100
+ * // Automatically cleaned up on unmount
101
+ * useOn('user:login', async (event) => {
102
+ * console.log('User logged in:', event.data);
103
+ * });
104
+ *
105
+ * // With options
106
+ * useOn('data:update', handler, {
107
+ * priority: 10,
108
+ * id: 'my-listener'
109
+ * });
110
+ *
111
+ * // Manual cleanup via AbortSignal
112
+ * const controller = new AbortController();
113
+ * useOn('events', handler, {
114
+ * signal: controller.signal
115
+ * });
116
+ * // Later: controller.abort();
117
+ * }
118
+ * }
119
+ * ```
120
+ */
121
+ declare function useOn<K extends string = string>(eventName: K, handler: ListenerFunction, options?: ListenerOptions): () => void;
122
+
123
+ /**
124
+ * Vue composable for reactive event state
125
+ *
126
+ * Maintains a reactive ref that updates whenever the specified event is emitted.
127
+ * Automatically removes the listener when the component is unmounted.
128
+ */
129
+
130
+ /**
131
+ * Options for useEventState composable
132
+ */
133
+ interface UseEventStateOptions extends Omit<ListenerOptions, 'once'> {
134
+ /**
135
+ * Transform function to extract value from event
136
+ * Default: returns event.data
137
+ */
138
+ transform?: (event: IKernelEvent) => any;
139
+ }
140
+ /**
141
+ * Composable to maintain reactive state that updates on events
142
+ *
143
+ * Creates a Vue reactive ref that automatically updates when the specified
144
+ * event is emitted. The listener is automatically removed when the component
145
+ * unmounts via Vue's onUnmounted lifecycle hook.
146
+ *
147
+ * @template T - Value type
148
+ * @template K - Event name type
149
+ * @param eventName - Event name to listen for
150
+ * @param initialValue - Initial value for the ref
151
+ * @param options - Listener options and transform function (optional)
152
+ * @returns Reactive ref that updates on events
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * import { useEventState } from '@quazardous/quarkernel-vue';
157
+ *
158
+ * export default {
159
+ * setup() {
160
+ * // Simple usage - updates with event.data
161
+ * const userCount = useEventState('user:count', 0);
162
+ *
163
+ * // With transform function
164
+ * const userName = useEventState(
165
+ * 'user:login',
166
+ * 'Guest',
167
+ * {
168
+ * transform: (event) => event.data.name
169
+ * }
170
+ * );
171
+ *
172
+ * // With manual cleanup
173
+ * const controller = new AbortController();
174
+ * const status = useEventState('status', 'idle', {
175
+ * signal: controller.signal
176
+ * });
177
+ * // Later: controller.abort();
178
+ *
179
+ * return { userCount, userName, status };
180
+ * }
181
+ * }
182
+ * ```
183
+ */
184
+ declare function useEventState<T = any, K extends string = string>(eventName: K, initialValue: T, options?: UseEventStateOptions): Ref<T>;
185
+
186
+ export { KERNEL_INJECTION_KEY, QuarKernelPlugin, type QuarKernelPluginOptions, type UseEventStateOptions, useEventState, useKernel, useOn };
@@ -0,0 +1,186 @@
1
+ import { Plugin, Ref } from 'vue';
2
+ import { Kernel, ListenerFunction, ListenerOptions, IKernelEvent } from '@quazardous/quarkernel';
3
+
4
+ /**
5
+ * Vue plugin for QuarKernel integration
6
+ *
7
+ * Provides global kernel instance access via Vue's provide/inject system.
8
+ * Use with app.use(QuarKernelPlugin, { kernel })
9
+ */
10
+
11
+ /**
12
+ * Injection key for kernel instance
13
+ * @internal
14
+ */
15
+ declare const KERNEL_INJECTION_KEY: unique symbol;
16
+ /**
17
+ * Plugin options
18
+ */
19
+ interface QuarKernelPluginOptions {
20
+ /** Kernel instance to provide globally */
21
+ kernel: Kernel;
22
+ }
23
+ /**
24
+ * QuarKernel Vue plugin
25
+ *
26
+ * Registers kernel instance globally for access via useKernel() composable
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { createApp } from 'vue';
31
+ * import { createKernel } from '@quazardous/quarkernel';
32
+ * import { QuarKernelPlugin } from '@quazardous/quarkernel-vue';
33
+ *
34
+ * const kernel = createKernel();
35
+ * const app = createApp(App);
36
+ *
37
+ * app.use(QuarKernelPlugin, { kernel });
38
+ * ```
39
+ */
40
+ declare const QuarKernelPlugin: Plugin;
41
+
42
+ /**
43
+ * Vue composable for accessing QuarKernel instance
44
+ *
45
+ * Provides type-safe access to the kernel instance registered via plugin.
46
+ * Includes SSR guards to prevent server-side usage.
47
+ */
48
+
49
+ /**
50
+ * Composable to access QuarKernel instance from components
51
+ *
52
+ * Must be called within setup() function of a component where the plugin was installed.
53
+ * Throws error if plugin not installed or called outside setup context.
54
+ * Warns when accessed during SSR.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import { useKernel } from '@quazardous/quarkernel-vue';
59
+ *
60
+ * export default {
61
+ * setup() {
62
+ * const kernel = useKernel();
63
+ *
64
+ * kernel.on('user:login', async (event) => {
65
+ * console.log('User logged in:', event.data);
66
+ * });
67
+ *
68
+ * return {};
69
+ * }
70
+ * }
71
+ * ```
72
+ */
73
+ declare function useKernel<T extends Kernel = Kernel>(): T;
74
+
75
+ /**
76
+ * Vue composable for event listener registration with automatic cleanup
77
+ *
78
+ * Automatically removes the listener when the component is unmounted.
79
+ * Supports manual cleanup via AbortSignal.
80
+ */
81
+
82
+ /**
83
+ * Composable to register event listeners with automatic cleanup
84
+ *
85
+ * The listener is automatically removed when the component unmounts via Vue's
86
+ * onUnmounted lifecycle hook. Manual cleanup is also supported via AbortSignal.
87
+ *
88
+ * @template K - Event name type
89
+ * @param eventName - Event name to listen for
90
+ * @param handler - Listener function
91
+ * @param options - Listener options (optional)
92
+ * @returns Cleanup function to manually remove listener
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * import { useOn } from '@quazardous/quarkernel-vue';
97
+ *
98
+ * export default {
99
+ * setup() {
100
+ * // Automatically cleaned up on unmount
101
+ * useOn('user:login', async (event) => {
102
+ * console.log('User logged in:', event.data);
103
+ * });
104
+ *
105
+ * // With options
106
+ * useOn('data:update', handler, {
107
+ * priority: 10,
108
+ * id: 'my-listener'
109
+ * });
110
+ *
111
+ * // Manual cleanup via AbortSignal
112
+ * const controller = new AbortController();
113
+ * useOn('events', handler, {
114
+ * signal: controller.signal
115
+ * });
116
+ * // Later: controller.abort();
117
+ * }
118
+ * }
119
+ * ```
120
+ */
121
+ declare function useOn<K extends string = string>(eventName: K, handler: ListenerFunction, options?: ListenerOptions): () => void;
122
+
123
+ /**
124
+ * Vue composable for reactive event state
125
+ *
126
+ * Maintains a reactive ref that updates whenever the specified event is emitted.
127
+ * Automatically removes the listener when the component is unmounted.
128
+ */
129
+
130
+ /**
131
+ * Options for useEventState composable
132
+ */
133
+ interface UseEventStateOptions extends Omit<ListenerOptions, 'once'> {
134
+ /**
135
+ * Transform function to extract value from event
136
+ * Default: returns event.data
137
+ */
138
+ transform?: (event: IKernelEvent) => any;
139
+ }
140
+ /**
141
+ * Composable to maintain reactive state that updates on events
142
+ *
143
+ * Creates a Vue reactive ref that automatically updates when the specified
144
+ * event is emitted. The listener is automatically removed when the component
145
+ * unmounts via Vue's onUnmounted lifecycle hook.
146
+ *
147
+ * @template T - Value type
148
+ * @template K - Event name type
149
+ * @param eventName - Event name to listen for
150
+ * @param initialValue - Initial value for the ref
151
+ * @param options - Listener options and transform function (optional)
152
+ * @returns Reactive ref that updates on events
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * import { useEventState } from '@quazardous/quarkernel-vue';
157
+ *
158
+ * export default {
159
+ * setup() {
160
+ * // Simple usage - updates with event.data
161
+ * const userCount = useEventState('user:count', 0);
162
+ *
163
+ * // With transform function
164
+ * const userName = useEventState(
165
+ * 'user:login',
166
+ * 'Guest',
167
+ * {
168
+ * transform: (event) => event.data.name
169
+ * }
170
+ * );
171
+ *
172
+ * // With manual cleanup
173
+ * const controller = new AbortController();
174
+ * const status = useEventState('status', 'idle', {
175
+ * signal: controller.signal
176
+ * });
177
+ * // Later: controller.abort();
178
+ *
179
+ * return { userCount, userName, status };
180
+ * }
181
+ * }
182
+ * ```
183
+ */
184
+ declare function useEventState<T = any, K extends string = string>(eventName: K, initialValue: T, options?: UseEventStateOptions): Ref<T>;
185
+
186
+ export { KERNEL_INJECTION_KEY, QuarKernelPlugin, type QuarKernelPluginOptions, type UseEventStateOptions, useEventState, useKernel, useOn };
package/dist/index.js ADDED
@@ -0,0 +1,62 @@
1
+ import { getCurrentInstance, inject, onUnmounted, ref } from 'vue';
2
+
3
+ // src/plugin.ts
4
+ var KERNEL_INJECTION_KEY = /* @__PURE__ */ Symbol("quarkernel");
5
+ var QuarKernelPlugin = {
6
+ install(app, options) {
7
+ if (!options || !options.kernel) {
8
+ throw new Error("[QuarKernel Vue] Plugin requires a kernel instance in options");
9
+ }
10
+ app.provide(KERNEL_INJECTION_KEY, options.kernel);
11
+ }
12
+ };
13
+ function isSSR() {
14
+ return typeof window === "undefined";
15
+ }
16
+ function useKernel() {
17
+ const instance = getCurrentInstance();
18
+ if (!instance) {
19
+ throw new Error("[QuarKernel Vue] useKernel() must be called within setup() function");
20
+ }
21
+ if (isSSR()) {
22
+ console.warn(
23
+ "[QuarKernel Vue] useKernel() called during server-side rendering. Kernel events should typically run client-side only. Ensure you guard kernel usage in onMounted() or similar lifecycle hooks."
24
+ );
25
+ }
26
+ const kernel = inject(KERNEL_INJECTION_KEY);
27
+ if (!kernel) {
28
+ throw new Error(
29
+ "[QuarKernel Vue] Kernel instance not found. Did you install QuarKernelPlugin with app.use(QuarKernelPlugin, { kernel })?"
30
+ );
31
+ }
32
+ return kernel;
33
+ }
34
+ function useOn(eventName, handler, options) {
35
+ const kernel = useKernel();
36
+ const unbind = kernel.on(eventName, handler, options);
37
+ onUnmounted(() => {
38
+ unbind();
39
+ });
40
+ return unbind;
41
+ }
42
+ function useEventState(eventName, initialValue, options) {
43
+ const kernel = useKernel();
44
+ const state = ref(initialValue);
45
+ const { transform, ...listenerOptions } = options || {};
46
+ const transformFn = transform || ((event) => event.data);
47
+ const unbind = kernel.on(
48
+ eventName,
49
+ (event) => {
50
+ state.value = transformFn(event);
51
+ },
52
+ listenerOptions
53
+ );
54
+ onUnmounted(() => {
55
+ unbind();
56
+ });
57
+ return state;
58
+ }
59
+
60
+ export { KERNEL_INJECTION_KEY, QuarKernelPlugin, useEventState, useKernel, useOn };
61
+ //# sourceMappingURL=index.js.map
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin.ts","../src/use-kernel.ts","../src/use-on.ts","../src/use-event-state.ts"],"names":["onUnmounted"],"mappings":";;;AAcO,IAAM,oBAAA,0BAA8B,YAAY;AA2BhD,IAAM,gBAAA,GAA2B;AAAA,EACtC,OAAA,CAAQ,KAAU,OAAA,EAAkC;AAClD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAC/B,MAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,IACjF;AAEA,IAAA,GAAA,CAAI,OAAA,CAAQ,oBAAA,EAAsB,OAAA,CAAQ,MAAM,CAAA;AAAA,EAClD;AACF;AClCA,SAAS,KAAA,GAAiB;AACxB,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AA0BO,SAAS,SAAA,GAA0C;AAExD,EAAA,MAAM,WAAW,kBAAA,EAAmB;AACpC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,EACvF;AAGA,EAAA,IAAI,OAAM,EAAG;AACX,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KAGF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,OAAU,oBAAoB,CAAA;AAE7C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;ACpBO,SAAS,KAAA,CACd,SAAA,EACA,OAAA,EACA,OAAA,EACY;AACZ,EAAA,MAAM,SAAS,SAAA,EAAU;AAGzB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,EAAA,CAAG,SAAA,EAAW,SAAS,OAAO,CAAA;AAGpD,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,MAAA,EAAO;AAAA,EACT,CAAC,CAAA;AAGD,EAAA,OAAO,MAAA;AACT;ACAO,SAAS,aAAA,CACd,SAAA,EACA,YAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,KAAA,GAAQ,IAAO,YAAY,CAAA;AAGjC,EAAA,MAAM,EAAE,SAAA,EAAW,GAAG,eAAA,EAAgB,GAAI,WAAW,EAAC;AACtD,EAAA,MAAM,WAAA,GAAc,SAAA,KAAc,CAAC,KAAA,KAAwB,KAAA,CAAM,IAAA,CAAA;AAGjE,EAAA,MAAM,SAAS,MAAA,CAAO,EAAA;AAAA,IACpB,SAAA;AAAA,IACA,CAAC,KAAA,KAAwB;AACvB,MAAA,KAAA,CAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAAA,IACjC,CAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAAA,YAAY,MAAM;AAChB,IAAA,MAAA,EAAO;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT","file":"index.js","sourcesContent":["/**\n * Vue plugin for QuarKernel integration\n *\n * Provides global kernel instance access via Vue's provide/inject system.\n * Use with app.use(QuarKernelPlugin, { kernel })\n */\n\nimport type { App, Plugin } from 'vue';\nimport type { Kernel } from '@quazardous/quarkernel';\n\n/**\n * Injection key for kernel instance\n * @internal\n */\nexport const KERNEL_INJECTION_KEY = Symbol('quarkernel');\n\n/**\n * Plugin options\n */\nexport interface QuarKernelPluginOptions {\n /** Kernel instance to provide globally */\n kernel: Kernel;\n}\n\n/**\n * QuarKernel Vue plugin\n *\n * Registers kernel instance globally for access via useKernel() composable\n *\n * @example\n * ```ts\n * import { createApp } from 'vue';\n * import { createKernel } from '@quazardous/quarkernel';\n * import { QuarKernelPlugin } from '@quazardous/quarkernel-vue';\n *\n * const kernel = createKernel();\n * const app = createApp(App);\n *\n * app.use(QuarKernelPlugin, { kernel });\n * ```\n */\nexport const QuarKernelPlugin: Plugin = {\n install(app: App, options: QuarKernelPluginOptions) {\n if (!options || !options.kernel) {\n throw new Error('[QuarKernel Vue] Plugin requires a kernel instance in options');\n }\n\n app.provide(KERNEL_INJECTION_KEY, options.kernel);\n },\n};\n","/**\n * Vue composable for accessing QuarKernel instance\n *\n * Provides type-safe access to the kernel instance registered via plugin.\n * Includes SSR guards to prevent server-side usage.\n */\n\nimport { inject, getCurrentInstance } from 'vue';\nimport type { Kernel } from '@quazardous/quarkernel';\nimport { KERNEL_INJECTION_KEY } from './plugin.js';\n\n/**\n * Check if running in SSR context\n * @internal\n */\nfunction isSSR(): boolean {\n return typeof window === 'undefined';\n}\n\n/**\n * Composable to access QuarKernel instance from components\n *\n * Must be called within setup() function of a component where the plugin was installed.\n * Throws error if plugin not installed or called outside setup context.\n * Warns when accessed during SSR.\n *\n * @example\n * ```ts\n * import { useKernel } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * const kernel = useKernel();\n *\n * kernel.on('user:login', async (event) => {\n * console.log('User logged in:', event.data);\n * });\n *\n * return {};\n * }\n * }\n * ```\n */\nexport function useKernel<T extends Kernel = Kernel>(): T {\n // Check if called within Vue component setup\n const instance = getCurrentInstance();\n if (!instance) {\n throw new Error('[QuarKernel Vue] useKernel() must be called within setup() function');\n }\n\n // SSR guard - warn but don't block (for flexibility)\n if (isSSR()) {\n console.warn(\n '[QuarKernel Vue] useKernel() called during server-side rendering. ' +\n 'Kernel events should typically run client-side only. ' +\n 'Ensure you guard kernel usage in onMounted() or similar lifecycle hooks.'\n );\n }\n\n // Inject kernel instance\n const kernel = inject<T>(KERNEL_INJECTION_KEY);\n\n if (!kernel) {\n throw new Error(\n '[QuarKernel Vue] Kernel instance not found. ' +\n 'Did you install QuarKernelPlugin with app.use(QuarKernelPlugin, { kernel })?'\n );\n }\n\n return kernel;\n}\n","/**\n * Vue composable for event listener registration with automatic cleanup\n *\n * Automatically removes the listener when the component is unmounted.\n * Supports manual cleanup via AbortSignal.\n */\n\nimport { onUnmounted } from 'vue';\nimport type { ListenerFunction, ListenerOptions } from '@quazardous/quarkernel';\nimport { useKernel } from './use-kernel.js';\n\n/**\n * Composable to register event listeners with automatic cleanup\n *\n * The listener is automatically removed when the component unmounts via Vue's\n * onUnmounted lifecycle hook. Manual cleanup is also supported via AbortSignal.\n *\n * @template K - Event name type\n * @param eventName - Event name to listen for\n * @param handler - Listener function\n * @param options - Listener options (optional)\n * @returns Cleanup function to manually remove listener\n *\n * @example\n * ```ts\n * import { useOn } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * // Automatically cleaned up on unmount\n * useOn('user:login', async (event) => {\n * console.log('User logged in:', event.data);\n * });\n *\n * // With options\n * useOn('data:update', handler, {\n * priority: 10,\n * id: 'my-listener'\n * });\n *\n * // Manual cleanup via AbortSignal\n * const controller = new AbortController();\n * useOn('events', handler, {\n * signal: controller.signal\n * });\n * // Later: controller.abort();\n * }\n * }\n * ```\n */\nexport function useOn<K extends string = string>(\n eventName: K,\n handler: ListenerFunction,\n options?: ListenerOptions\n): () => void {\n const kernel = useKernel();\n\n // Register listener on kernel\n const unbind = kernel.on(eventName, handler, options);\n\n // Auto-cleanup on component unmount\n onUnmounted(() => {\n unbind();\n });\n\n // Return unbind for manual cleanup\n return unbind;\n}\n","/**\n * Vue composable for reactive event state\n *\n * Maintains a reactive ref that updates whenever the specified event is emitted.\n * Automatically removes the listener when the component is unmounted.\n */\n\nimport { ref, onUnmounted } from 'vue';\nimport type { Ref } from 'vue';\nimport type { ListenerOptions, IKernelEvent } from '@quazardous/quarkernel';\nimport { useKernel } from './use-kernel.js';\n\n/**\n * Options for useEventState composable\n */\nexport interface UseEventStateOptions extends Omit<ListenerOptions, 'once'> {\n /**\n * Transform function to extract value from event\n * Default: returns event.data\n */\n transform?: (event: IKernelEvent) => any;\n}\n\n/**\n * Composable to maintain reactive state that updates on events\n *\n * Creates a Vue reactive ref that automatically updates when the specified\n * event is emitted. The listener is automatically removed when the component\n * unmounts via Vue's onUnmounted lifecycle hook.\n *\n * @template T - Value type\n * @template K - Event name type\n * @param eventName - Event name to listen for\n * @param initialValue - Initial value for the ref\n * @param options - Listener options and transform function (optional)\n * @returns Reactive ref that updates on events\n *\n * @example\n * ```ts\n * import { useEventState } from '@quazardous/quarkernel-vue';\n *\n * export default {\n * setup() {\n * // Simple usage - updates with event.data\n * const userCount = useEventState('user:count', 0);\n *\n * // With transform function\n * const userName = useEventState(\n * 'user:login',\n * 'Guest',\n * {\n * transform: (event) => event.data.name\n * }\n * );\n *\n * // With manual cleanup\n * const controller = new AbortController();\n * const status = useEventState('status', 'idle', {\n * signal: controller.signal\n * });\n * // Later: controller.abort();\n *\n * return { userCount, userName, status };\n * }\n * }\n * ```\n */\nexport function useEventState<T = any, K extends string = string>(\n eventName: K,\n initialValue: T,\n options?: UseEventStateOptions\n): Ref<T> {\n const kernel = useKernel();\n const state = ref<T>(initialValue) as Ref<T>;\n\n // Extract transform function from options\n const { transform, ...listenerOptions } = options || {};\n const transformFn = transform || ((event: IKernelEvent) => event.data);\n\n // Register listener that updates state\n const unbind = kernel.on(\n eventName,\n (event: IKernelEvent) => {\n state.value = transformFn(event);\n },\n listenerOptions\n );\n\n // Auto-cleanup on component unmount\n onUnmounted(() => {\n unbind();\n });\n\n return state;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@quazardous/quarkernel-vue",
3
+ "version": "2.1.0",
4
+ "type": "module",
5
+ "description": "Vue 3 adapter for QuarKernel - event kernel integration with Vue reactivity",
6
+ "author": "quazardous <berliozdavid@gmail.com>",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/quazardous/quarkernel.git",
11
+ "directory": "packages/vue"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/quazardous/quarkernel/issues"
15
+ },
16
+ "homepage": "https://github.com/quazardous/quarkernel#readme",
17
+ "keywords": [
18
+ "quarkernel",
19
+ "vue",
20
+ "vue3",
21
+ "event",
22
+ "events",
23
+ "kernel",
24
+ "composable",
25
+ "plugin",
26
+ "reactivity"
27
+ ],
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "require": "./dist/index.cjs"
33
+ }
34
+ },
35
+ "main": "./dist/index.cjs",
36
+ "module": "./dist/index.js",
37
+ "types": "./dist/index.d.ts",
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "sideEffects": false,
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ },
47
+ "scripts": {
48
+ "build": "tsup",
49
+ "build:watch": "tsup --watch",
50
+ "test": "vitest run",
51
+ "test:watch": "vitest",
52
+ "clean": "rm -rf dist"
53
+ },
54
+ "peerDependencies": {
55
+ "@quazardous/quarkernel": "^2.1.0",
56
+ "vue": "^3.3.0"
57
+ },
58
+ "devDependencies": {
59
+ "@quazardous/quarkernel": "file:../quarkernel",
60
+ "jsdom": "^23.0.0",
61
+ "tsup": "^8.0.0",
62
+ "typescript": "^5.3.0",
63
+ "vitest": "^1.0.0",
64
+ "vue": "^3.3.0"
65
+ }
66
+ }