@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 +90 -0
- package/dist/index.cjs +68 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +186 -0
- package/dist/index.d.ts +186 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
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"]}
|
package/dist/index.d.cts
ADDED
|
@@ -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.d.ts
ADDED
|
@@ -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
|
+
}
|