@sigrea/vue 0.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 +131 -0
- package/dist/index.cjs +91 -0
- package/dist/index.d.cts +24 -0
- package/dist/index.d.mts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.mjs +84 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# @sigrea/vue
|
|
2
|
+
|
|
3
|
+
`@sigrea/vue` adapts [@sigrea/core](https://www.npmjs.com/package/@sigrea/core) logic modules and signals to Vue 3’s Composition API. It keeps lifecycle scopes aligned with component mounts, forwards deep reactivity, and ships composables that feel first-class inside `<script setup>` or traditional setup functions.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @sigrea/vue @sigrea/core vue
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Vue 3.4+ and Node.js 20+ are required. Equivalent npm or yarn commands work as expected.
|
|
12
|
+
|
|
13
|
+
## What This Adapter Provides
|
|
14
|
+
|
|
15
|
+
- **Signal readers** – `useSignal` consumes shallow signals and computed values inside Vue components.
|
|
16
|
+
- **Deep signal access** – `useDeepSignal` exposes deeply reactive objects with automatic cleanup.
|
|
17
|
+
- **Derived state** – `useComputed` mirrors Vue’s `computed`, but tracks through Sigrea scopes.
|
|
18
|
+
- **Logic lifecycles** – `useLogic` mounts `defineLogic` factories while honoring `onMount` / `onUnmount`.
|
|
19
|
+
- **Snapshots** – `useSnapshot` grants direct access to low-level signal handlers when needed.
|
|
20
|
+
- **Writable bridge** – `useMutableSignal` exposes primitive `signal()` values as `WritableComputedRef`s for two-way bindings.
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Consume a signal
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import { signal } from "@sigrea/core";
|
|
29
|
+
import { useSignal } from "@sigrea/vue";
|
|
30
|
+
|
|
31
|
+
const count = signal(0);
|
|
32
|
+
const value = useSignal(count);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<span>{{ value }}</span>
|
|
37
|
+
</template>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Bridge framework-agnostic logic
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// CounterLogic.ts
|
|
44
|
+
import { defineLogic, signal } from "@sigrea/core";
|
|
45
|
+
|
|
46
|
+
export const CounterLogic = defineLogic<{ initialCount: number }>()((props) => {
|
|
47
|
+
const count = signal(props.initialCount);
|
|
48
|
+
|
|
49
|
+
const increment = () => {
|
|
50
|
+
count.value += 1;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const reset = () => {
|
|
54
|
+
count.value = props.initialCount;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return { count, increment, reset };
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// Counter.vue
|
|
63
|
+
<script setup lang="ts">
|
|
64
|
+
import { useLogic, useSignal } from "@sigrea/vue";
|
|
65
|
+
|
|
66
|
+
import { CounterLogic } from "./CounterLogic";
|
|
67
|
+
|
|
68
|
+
const props = defineProps<{ initialCount: number }>();
|
|
69
|
+
const counter = useLogic(CounterLogic, props);
|
|
70
|
+
const value = useSignal(counter.count);
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<div>
|
|
75
|
+
<span>{{ value }}</span>
|
|
76
|
+
<button @click="counter.increment">Increment</button>
|
|
77
|
+
<button @click="counter.reset">Reset</button>
|
|
78
|
+
</div>
|
|
79
|
+
</template>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Bind writable primitive signals
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
<script setup lang="ts">
|
|
86
|
+
import { signal } from "@sigrea/core";
|
|
87
|
+
import { useMutableSignal } from "@sigrea/vue";
|
|
88
|
+
|
|
89
|
+
const count = signal(0);
|
|
90
|
+
const model = useMutableSignal(count);
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<template>
|
|
94
|
+
<label>
|
|
95
|
+
Count
|
|
96
|
+
<input type="number" v-model.number="model" />
|
|
97
|
+
</label>
|
|
98
|
+
</template>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`useMutableSignal` expects a writable signal produced by `signal()`. Passing a readonly signal throws at runtime so incorrect bindings fail fast.
|
|
102
|
+
|
|
103
|
+
### Bind deep reactive objects
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
<script setup lang="ts">
|
|
107
|
+
import { deepSignal } from "@sigrea/core";
|
|
108
|
+
import { useDeepSignal } from "@sigrea/vue";
|
|
109
|
+
|
|
110
|
+
const profile = deepSignal({ name: "Sigrea" });
|
|
111
|
+
const model = useDeepSignal(profile);
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<template>
|
|
115
|
+
<label>
|
|
116
|
+
Name
|
|
117
|
+
<input v-model="model.name" />
|
|
118
|
+
</label>
|
|
119
|
+
</template>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
- `pnpm install` – install dependencies
|
|
125
|
+
- `pnpm test` – run the Vitest suite
|
|
126
|
+
- `pnpm build` – emit distributable artifacts
|
|
127
|
+
- `pnpm dev` – launch the playground counter demo
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT — see `LICENSE`.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const vue = require('vue');
|
|
4
|
+
const core = require('@sigrea/core');
|
|
5
|
+
|
|
6
|
+
function useLogic(logic, ...args) {
|
|
7
|
+
if (vue.getCurrentInstance() === null) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"useLogic can only be used within a Vue component setup()."
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
const instance = core.mountLogic(logic, ...args);
|
|
13
|
+
vue.onScopeDispose(() => {
|
|
14
|
+
core.cleanupLogic(instance);
|
|
15
|
+
});
|
|
16
|
+
return instance;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function useSnapshot(handler, options) {
|
|
20
|
+
if (vue.getCurrentInstance() === null) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"useSnapshot can only be used within a Vue component setup()."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
const state = vue.shallowRef(handler.getSnapshot().value);
|
|
26
|
+
const update = () => {
|
|
27
|
+
const next = handler.getSnapshot().value;
|
|
28
|
+
if (!Object.is(next, state.value)) {
|
|
29
|
+
state.value = next;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
vue.triggerRef(state);
|
|
33
|
+
};
|
|
34
|
+
const unsubscribe = handler.subscribe(update);
|
|
35
|
+
vue.onScopeDispose(() => {
|
|
36
|
+
unsubscribe();
|
|
37
|
+
});
|
|
38
|
+
if (options?.mode === "mutable") {
|
|
39
|
+
return state;
|
|
40
|
+
}
|
|
41
|
+
return vue.readonly(state);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function useSignal(source) {
|
|
45
|
+
const handler = core.createSignalHandler(source);
|
|
46
|
+
return useSnapshot(handler);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function useComputed(source) {
|
|
50
|
+
const handler = core.createComputedHandler(source);
|
|
51
|
+
return useSnapshot(handler);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function useDeepSignal(source) {
|
|
55
|
+
const handler = core.createDeepSignalHandler(source);
|
|
56
|
+
return useSnapshot(handler, { mode: "mutable" });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function assertWritableSignal(source) {
|
|
60
|
+
let prototype = source;
|
|
61
|
+
let descriptor;
|
|
62
|
+
while (prototype !== null) {
|
|
63
|
+
descriptor = Object.getOwnPropertyDescriptor(prototype, "value");
|
|
64
|
+
if (descriptor !== void 0) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
68
|
+
}
|
|
69
|
+
if (descriptor?.set === void 0) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"useMutableSignal requires a writable signal instance created by signal()."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function useMutableSignal(source) {
|
|
76
|
+
assertWritableSignal(source);
|
|
77
|
+
const state = useSignal(source);
|
|
78
|
+
return vue.computed({
|
|
79
|
+
get: () => state.value,
|
|
80
|
+
set: (value) => {
|
|
81
|
+
source.value = value;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
exports.useComputed = useComputed;
|
|
87
|
+
exports.useDeepSignal = useDeepSignal;
|
|
88
|
+
exports.useLogic = useLogic;
|
|
89
|
+
exports.useMutableSignal = useMutableSignal;
|
|
90
|
+
exports.useSignal = useSignal;
|
|
91
|
+
exports.useSnapshot = useSnapshot;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LogicFunction, LogicArgs, LogicInstance, Signal, ReadonlySignal, Computed, DeepSignal, SnapshotHandler } from '@sigrea/core';
|
|
2
|
+
import * as vue from 'vue';
|
|
3
|
+
import { DeepReadonly, ShallowRef } from 'vue';
|
|
4
|
+
|
|
5
|
+
declare function useLogic<TReturn extends object, TProps = void>(logic: LogicFunction<TReturn, TProps>, ...args: LogicArgs<TProps>): LogicInstance<TReturn>;
|
|
6
|
+
|
|
7
|
+
type ReadableSignal<T> = Signal<T> | ReadonlySignal<T>;
|
|
8
|
+
declare function useSignal<T>(source: ReadableSignal<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
9
|
+
|
|
10
|
+
declare function useComputed<T>(source: Computed<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
11
|
+
|
|
12
|
+
declare function useDeepSignal<T extends object>(source: DeepSignal<T>): vue.ShallowRef<T>;
|
|
13
|
+
|
|
14
|
+
declare function useMutableSignal<T>(source: Signal<T>): vue.WritableComputedRef<vue.DeepReadonly<T>, T>;
|
|
15
|
+
|
|
16
|
+
interface UseSnapshotOptions {
|
|
17
|
+
mode?: "readonly" | "mutable";
|
|
18
|
+
}
|
|
19
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>): DeepReadonly<ShallowRef<T>>;
|
|
20
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>, options: UseSnapshotOptions & {
|
|
21
|
+
mode: "mutable";
|
|
22
|
+
}): ShallowRef<T>;
|
|
23
|
+
|
|
24
|
+
export { useComputed, useDeepSignal, useLogic, useMutableSignal, useSignal, useSnapshot };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LogicFunction, LogicArgs, LogicInstance, Signal, ReadonlySignal, Computed, DeepSignal, SnapshotHandler } from '@sigrea/core';
|
|
2
|
+
import * as vue from 'vue';
|
|
3
|
+
import { DeepReadonly, ShallowRef } from 'vue';
|
|
4
|
+
|
|
5
|
+
declare function useLogic<TReturn extends object, TProps = void>(logic: LogicFunction<TReturn, TProps>, ...args: LogicArgs<TProps>): LogicInstance<TReturn>;
|
|
6
|
+
|
|
7
|
+
type ReadableSignal<T> = Signal<T> | ReadonlySignal<T>;
|
|
8
|
+
declare function useSignal<T>(source: ReadableSignal<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
9
|
+
|
|
10
|
+
declare function useComputed<T>(source: Computed<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
11
|
+
|
|
12
|
+
declare function useDeepSignal<T extends object>(source: DeepSignal<T>): vue.ShallowRef<T>;
|
|
13
|
+
|
|
14
|
+
declare function useMutableSignal<T>(source: Signal<T>): vue.WritableComputedRef<vue.DeepReadonly<T>, T>;
|
|
15
|
+
|
|
16
|
+
interface UseSnapshotOptions {
|
|
17
|
+
mode?: "readonly" | "mutable";
|
|
18
|
+
}
|
|
19
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>): DeepReadonly<ShallowRef<T>>;
|
|
20
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>, options: UseSnapshotOptions & {
|
|
21
|
+
mode: "mutable";
|
|
22
|
+
}): ShallowRef<T>;
|
|
23
|
+
|
|
24
|
+
export { useComputed, useDeepSignal, useLogic, useMutableSignal, useSignal, useSnapshot };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LogicFunction, LogicArgs, LogicInstance, Signal, ReadonlySignal, Computed, DeepSignal, SnapshotHandler } from '@sigrea/core';
|
|
2
|
+
import * as vue from 'vue';
|
|
3
|
+
import { DeepReadonly, ShallowRef } from 'vue';
|
|
4
|
+
|
|
5
|
+
declare function useLogic<TReturn extends object, TProps = void>(logic: LogicFunction<TReturn, TProps>, ...args: LogicArgs<TProps>): LogicInstance<TReturn>;
|
|
6
|
+
|
|
7
|
+
type ReadableSignal<T> = Signal<T> | ReadonlySignal<T>;
|
|
8
|
+
declare function useSignal<T>(source: ReadableSignal<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
9
|
+
|
|
10
|
+
declare function useComputed<T>(source: Computed<T>): Readonly<vue.Ref<vue.DeepReadonly<T>, vue.DeepReadonly<T>>>;
|
|
11
|
+
|
|
12
|
+
declare function useDeepSignal<T extends object>(source: DeepSignal<T>): vue.ShallowRef<T>;
|
|
13
|
+
|
|
14
|
+
declare function useMutableSignal<T>(source: Signal<T>): vue.WritableComputedRef<vue.DeepReadonly<T>, T>;
|
|
15
|
+
|
|
16
|
+
interface UseSnapshotOptions {
|
|
17
|
+
mode?: "readonly" | "mutable";
|
|
18
|
+
}
|
|
19
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>): DeepReadonly<ShallowRef<T>>;
|
|
20
|
+
declare function useSnapshot<T>(handler: SnapshotHandler<T>, options: UseSnapshotOptions & {
|
|
21
|
+
mode: "mutable";
|
|
22
|
+
}): ShallowRef<T>;
|
|
23
|
+
|
|
24
|
+
export { useComputed, useDeepSignal, useLogic, useMutableSignal, useSignal, useSnapshot };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getCurrentInstance, onScopeDispose, shallowRef, readonly, triggerRef, computed } from 'vue';
|
|
2
|
+
import { mountLogic, cleanupLogic, createSignalHandler, createComputedHandler, createDeepSignalHandler } from '@sigrea/core';
|
|
3
|
+
|
|
4
|
+
function useLogic(logic, ...args) {
|
|
5
|
+
if (getCurrentInstance() === null) {
|
|
6
|
+
throw new Error(
|
|
7
|
+
"useLogic can only be used within a Vue component setup()."
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
const instance = mountLogic(logic, ...args);
|
|
11
|
+
onScopeDispose(() => {
|
|
12
|
+
cleanupLogic(instance);
|
|
13
|
+
});
|
|
14
|
+
return instance;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function useSnapshot(handler, options) {
|
|
18
|
+
if (getCurrentInstance() === null) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
"useSnapshot can only be used within a Vue component setup()."
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
const state = shallowRef(handler.getSnapshot().value);
|
|
24
|
+
const update = () => {
|
|
25
|
+
const next = handler.getSnapshot().value;
|
|
26
|
+
if (!Object.is(next, state.value)) {
|
|
27
|
+
state.value = next;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
triggerRef(state);
|
|
31
|
+
};
|
|
32
|
+
const unsubscribe = handler.subscribe(update);
|
|
33
|
+
onScopeDispose(() => {
|
|
34
|
+
unsubscribe();
|
|
35
|
+
});
|
|
36
|
+
if (options?.mode === "mutable") {
|
|
37
|
+
return state;
|
|
38
|
+
}
|
|
39
|
+
return readonly(state);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function useSignal(source) {
|
|
43
|
+
const handler = createSignalHandler(source);
|
|
44
|
+
return useSnapshot(handler);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function useComputed(source) {
|
|
48
|
+
const handler = createComputedHandler(source);
|
|
49
|
+
return useSnapshot(handler);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function useDeepSignal(source) {
|
|
53
|
+
const handler = createDeepSignalHandler(source);
|
|
54
|
+
return useSnapshot(handler, { mode: "mutable" });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function assertWritableSignal(source) {
|
|
58
|
+
let prototype = source;
|
|
59
|
+
let descriptor;
|
|
60
|
+
while (prototype !== null) {
|
|
61
|
+
descriptor = Object.getOwnPropertyDescriptor(prototype, "value");
|
|
62
|
+
if (descriptor !== void 0) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
66
|
+
}
|
|
67
|
+
if (descriptor?.set === void 0) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
"useMutableSignal requires a writable signal instance created by signal()."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function useMutableSignal(source) {
|
|
74
|
+
assertWritableSignal(source);
|
|
75
|
+
const state = useSignal(source);
|
|
76
|
+
return computed({
|
|
77
|
+
get: () => state.value,
|
|
78
|
+
set: (value) => {
|
|
79
|
+
source.value = value;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { useComputed, useDeepSignal, useLogic, useMutableSignal, useSignal, useSnapshot };
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sigrea/vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue adapter bindings for Sigrea logic modules.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/sigrea/vue.git"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/sigrea/vue#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/sigrea/vue/issues"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.mjs",
|
|
26
|
+
"require": "./dist/index.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"main": "./dist/index.cjs",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"keywords": [
|
|
35
|
+
"signals",
|
|
36
|
+
"reactivity",
|
|
37
|
+
"vue",
|
|
38
|
+
"logic",
|
|
39
|
+
"typescript"
|
|
40
|
+
],
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@sigrea/core": "^0.1.0",
|
|
43
|
+
"vue": "^3.4.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@biomejs/biome": "1.9.4",
|
|
47
|
+
"@changesets/cli": "^2.29.6",
|
|
48
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
49
|
+
"@vue/test-utils": "^2.4.0",
|
|
50
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
51
|
+
"lefthook": "1.13.6",
|
|
52
|
+
"tsx": "^4.20.5",
|
|
53
|
+
"typescript": "5.9.3",
|
|
54
|
+
"unbuild": "3.6.1",
|
|
55
|
+
"vite": "^5.4.6",
|
|
56
|
+
"vitest": "^3.2.4",
|
|
57
|
+
"vue": "^3.4.0",
|
|
58
|
+
"jsdom": "^24.1.3"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"dev": "vite --config playground/vite.config.ts",
|
|
62
|
+
"build": "unbuild",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:coverage": "vitest --coverage",
|
|
65
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
66
|
+
"format": "biome check .",
|
|
67
|
+
"format:fix": "biome check --write ."
|
|
68
|
+
}
|
|
69
|
+
}
|