@ersbeth/picoflow 2.3.2 → 3.0.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.
Files changed (70) hide show
  1. package/README.md +34 -5
  2. package/SKILL.md +130 -16
  3. package/dist/index.d.ts +767 -0
  4. package/dist/index.js +544 -0
  5. package/dist/inspect.d.ts +252 -0
  6. package/dist/inspect.js +300 -0
  7. package/dist/shared.d.ts +361 -0
  8. package/dist/shared.js +1496 -0
  9. package/dist/shared2.d.ts +93 -0
  10. package/dist/shared2.js +59 -0
  11. package/dist/shared3.d.ts +54 -0
  12. package/dist/shared3.js +17 -0
  13. package/dist/{types/converters/solid.d.ts → solid.d.ts} +10 -8
  14. package/dist/solid.js +63 -0
  15. package/package.json +37 -25
  16. package/dist/picoflow.js +0 -1283
  17. package/dist/types/converters/index.d.ts +0 -1
  18. package/dist/types/core/api/base/flowConfig.d.ts +0 -17
  19. package/dist/types/core/api/base/flowDisposable.d.ts +0 -40
  20. package/dist/types/core/api/base/flowErrors.d.ts +0 -1
  21. package/dist/types/core/api/base/flowObservable.d.ts +0 -26
  22. package/dist/types/core/api/base/flowPrimitiveOptions.d.ts +0 -14
  23. package/dist/types/core/api/base/flowSubscribable.d.ts +0 -78
  24. package/dist/types/core/api/base/flowTracker.d.ts +0 -7
  25. package/dist/types/core/api/base/index.d.ts +0 -7
  26. package/dist/types/core/api/index.d.ts +0 -2
  27. package/dist/types/core/api/nodes/async/flowConstantAsync.d.ts +0 -32
  28. package/dist/types/core/api/nodes/async/flowDerivationAsync.d.ts +0 -37
  29. package/dist/types/core/api/nodes/async/flowStateAsync.d.ts +0 -42
  30. package/dist/types/core/api/nodes/async/flowWritableDerivationAsync.d.ts +0 -31
  31. package/dist/types/core/api/nodes/async/index.d.ts +0 -4
  32. package/dist/types/core/api/nodes/collections/flowArray.d.ts +0 -138
  33. package/dist/types/core/api/nodes/collections/flowMap.d.ts +0 -100
  34. package/dist/types/core/api/nodes/collections/index.d.ts +0 -2
  35. package/dist/types/core/api/nodes/flowEffect.d.ts +0 -28
  36. package/dist/types/core/api/nodes/flowSignal.d.ts +0 -26
  37. package/dist/types/core/api/nodes/flowValue.d.ts +0 -35
  38. package/dist/types/core/api/nodes/index.d.ts +0 -7
  39. package/dist/types/core/api/nodes/sync/flowConstant.d.ts +0 -30
  40. package/dist/types/core/api/nodes/sync/flowDerivation.d.ts +0 -37
  41. package/dist/types/core/api/nodes/sync/flowState.d.ts +0 -40
  42. package/dist/types/core/api/nodes/sync/flowWritableDerivation.d.ts +0 -29
  43. package/dist/types/core/api/nodes/sync/index.d.ts +0 -4
  44. package/dist/types/core/api/nodes/utils.d.ts +0 -22
  45. package/dist/types/core/base/dependenciesRegistry.d.ts +0 -1
  46. package/dist/types/core/base/dependentsRegistry.d.ts +0 -1
  47. package/dist/types/core/base/disposable.d.ts +0 -15
  48. package/dist/types/core/base/errors.d.ts +0 -31
  49. package/dist/types/core/base/executionStack.d.ts +0 -31
  50. package/dist/types/core/base/index.d.ts +0 -8
  51. package/dist/types/core/base/node.d.ts +0 -27
  52. package/dist/types/core/base/observable.d.ts +0 -34
  53. package/dist/types/core/base/observer.d.ts +0 -33
  54. package/dist/types/core/nodes/actionNode.d.ts +0 -1
  55. package/dist/types/core/nodes/arrayNode.d.ts +0 -1
  56. package/dist/types/core/nodes/effectNode.d.ts +0 -1
  57. package/dist/types/core/nodes/index.d.ts +0 -8
  58. package/dist/types/core/nodes/mapNode.d.ts +0 -1
  59. package/dist/types/core/nodes/signalNode.d.ts +0 -1
  60. package/dist/types/core/nodes/valueAsyncNode.d.ts +0 -1
  61. package/dist/types/core/nodes/valueNode.d.ts +0 -1
  62. package/dist/types/core/nodes/valueSyncNode.d.ts +0 -1
  63. package/dist/types/core/schedulers/asyncResolver.d.ts +0 -1
  64. package/dist/types/core/schedulers/asyncScheduler.d.ts +0 -1
  65. package/dist/types/core/schedulers/index.d.ts +0 -4
  66. package/dist/types/core/schedulers/pendingError.d.ts +0 -1
  67. package/dist/types/core/schedulers/scheduler.d.ts +0 -1
  68. package/dist/types/core/schedulers/syncResolver.d.ts +0 -1
  69. package/dist/types/core/schedulers/syncScheduler.d.ts +0 -1
  70. package/dist/types/index.d.ts +0 -2
@@ -0,0 +1,93 @@
1
+ import { r as FlowObservable } from "./shared.js";
2
+ //#region src/core/api/base/flowPrimitiveOptions.d.ts
3
+ /**
4
+ * Compares the value a primitive currently holds against the one being written, and returns `true`
5
+ * when the two count as the same — in which case nothing is notified.
6
+ *
7
+ * Defaults to `===` (see {@link FlowPrimitiveOptions.equals}). Called only on the `resolved` path,
8
+ * where `previous` is the live value rather than a stale cache.
9
+ *
10
+ * A comparator that throws does not throw back at whoever wrote: it fails the node with that error,
11
+ * the write is not applied, and the error surfaces on the next read and in `subscribe`'s `onError`
12
+ * — the same contract a throwing `update()` updater follows. A comparator that throws on every call
13
+ * therefore fails every write, the recovering `set()` included; that is a comparator to fix.
14
+ *
15
+ * @public
16
+ */
17
+ type FlowEquals<T> = (previous: T, next: T) => boolean;
18
+ /**
19
+ * Optional per-instance settings accepted by the primitive factories (`state`, `derivation`,
20
+ * `array`, `map`, `signal`, …).
21
+ *
22
+ * @public
23
+ */
24
+ interface FlowPrimitiveOptions<T = unknown> {
25
+ /**
26
+ * Identifies this primitive in error messages, e.g. `"[PicoFlow] Primitive \"$count\" is disposed"`
27
+ * instead of the unnamed `"[PicoFlow] Primitive is disposed"`. Purely diagnostic — has no effect
28
+ * on reactive behavior.
29
+ */
30
+ name?: string;
31
+ /**
32
+ * Decides whether a write counts as a change. Defaults to `===`, which means `NaN` written over
33
+ * `NaN` re-notifies, `-0` is indistinguishable from `0`, and an object mutated in place and
34
+ * written back under the same reference is a silent no-op (A2-SEM-4). Pass `Object.is` for the
35
+ * first two, or a structural comparator for the third.
36
+ *
37
+ * Honoured by the value primitives only — `array()`, `map()` and `signal()` ignore it, having no
38
+ * single value to compare.
39
+ *
40
+ * A comparator that throws fails the node rather than the write call — see {@link FlowEquals}.
41
+ */
42
+ equals?: FlowEquals<T>;
43
+ /**
44
+ * Recomputes this primitive as soon as it becomes dirty — at the next flush, whether or not
45
+ * anything reads it — instead of lazily at the next read (#118). An eager primitive computes
46
+ * for the first time at the first flush after creation. Defaults to `false`, the documented
47
+ * lazy model: no reader, no work.
48
+ *
49
+ * Honoured by the derivation factories only (`derivation`, `writableDerivation`,
50
+ * `derivationAsync`, `writableDerivationAsync`) — `state`, `constant`, the collections and
51
+ * `signal` ignore it, having no dependency-driven recomputation to hasten.
52
+ */
53
+ eager?: boolean;
54
+ }
55
+ //#endregion
56
+ //#region src/core/api/nodes/flowSignal.d.ts
57
+ /**
58
+ * Manual trigger that notifies subscribers without carrying data.
59
+ *
60
+ * Unlike reactive state or derivations, signals don't hold values. They serve as event emitters
61
+ * that notify dependents when explicitly triggered. Use signals for side effects that should run
62
+ * in response to manual actions rather than data changes.
63
+ *
64
+ * @public
65
+ */
66
+ interface FlowSignal extends FlowObservable<void> {
67
+ /**
68
+ * Notifies every dependent that the event occurred.
69
+ *
70
+ * A signal carries no value, so this is its only emission: dependents are queued for the next
71
+ * flush whether or not anything else changed. Two triggers in the same synchronous turn coalesce
72
+ * into one run, like any other batched notification.
73
+ *
74
+ * Declared here rather than on {@link FlowObservable} because forcing dependents to re-run is a
75
+ * write, not a read: a `constant()` or a `derivation()` must not offer it (A3-ARCH-1, #132).
76
+ */
77
+ trigger(): void;
78
+ }
79
+ /**
80
+ * Creates a signal that can be manually triggered to notify dependents.
81
+ *
82
+ * Signals act as event emitters in the reactive graph. Call `trigger()` to notify all subscribers
83
+ * and reactive computations that depend on the signal. Unlike state or derivations, signals don't
84
+ * carry data values - they simply represent that an event occurred.
85
+ *
86
+ * @param options - Optional settings; `name` identifies this primitive in error messages
87
+ * @returns A FlowSignal that can be triggered manually and subscribed to
88
+ *
89
+ * @public
90
+ */
91
+ declare function signal(options?: FlowPrimitiveOptions): FlowSignal;
92
+ //#endregion
93
+ export { FlowPrimitiveOptions as i, signal as n, FlowEquals as r, FlowSignal as t };
@@ -0,0 +1,59 @@
1
+ import { a as ReadableNode, o as EffectNode, r as syncCore } from "./shared.js";
2
+
3
+ //#region src/core/nodes/derivationNode.ts
4
+ /**
5
+ * The primitive behind `derivation()` and `derivationAsync()`: readable, and recomputable on demand
6
+ * through `refresh()`. No `set`, no `update` (#26, A2-SEM-3).
7
+ * @internal
8
+ */
9
+ var DerivationNode = class extends ReadableNode {
10
+ refresh() {
11
+ this._core.refresh();
12
+ }
13
+ };
14
+
15
+ //#endregion
16
+ //#region src/core/api/nodes/flowEffect.ts
17
+ /**
18
+ * Creates a reactive effect that runs immediately and automatically re-runs when dependencies change.
19
+ *
20
+ * The effect function tracks any reactive values accessed and subscribes to their changes.
21
+ * When any tracked value changes, the effect re-executes with the new values.
22
+ * Optional callbacks handle errors and pending async states.
23
+ *
24
+ * @param data - Function that accesses reactive dependencies and returns data
25
+ * @param onData - Callback invoked with the computed data on each execution
26
+ * @param onError - Optional callback for handling errors during execution
27
+ * @param onPending - Optional callback invoked when async dependencies are pending
28
+ * @param options - Optional settings; `name` identifies the effect in errors and inspection dumps
29
+ * @returns A FlowEffect handle with a `dispose()` method to stop the effect
30
+ *
31
+ * @public
32
+ */
33
+ function subscribe(data, onData, onError, onPending, options) {
34
+ return new EffectNode(data, onData, onError, onPending, options?.name);
35
+ }
36
+
37
+ //#endregion
38
+ //#region src/core/api/nodes/sync/flowDerivation.ts
39
+ /**
40
+ * Creates a derived reactive value that automatically recomputes when dependencies change.
41
+ *
42
+ * The compute function runs when any tracked dependency changes, and the result is cached until the next change.
43
+ * Access reactive values within the compute function to establish dependencies automatically. The derivation
44
+ * computes lazily on first access and then reactively thereafter. Use for derived data that should stay
45
+ * synchronized with source state.
46
+ *
47
+ * @param compute - Function that accesses dependencies and computes the derived value
48
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the
49
+ * default `===` change detection, `eager` recomputes on dirty instead of on read (#118)
50
+ * @returns A FlowDerivation that provides read-only access to the computed value
51
+ *
52
+ * @public
53
+ */
54
+ function derivation(compute, options) {
55
+ return new DerivationNode(syncCore(compute, options, true), "derivation");
56
+ }
57
+
58
+ //#endregion
59
+ export { subscribe as n, DerivationNode as r, derivation as t };
@@ -0,0 +1,54 @@
1
+ import { n as FlowValue } from "./shared.js";
2
+ //#region src/core/api/nodes/utils.d.ts
3
+ /**
4
+ * The type `NotPromise<T>` resolves to when `T` is a promise.
5
+ *
6
+ * A string literal rather than `never`, so the compiler diagnostic spells out the mistake and its fix
7
+ * ("… is not assignable to parameter of type '[PicoFlow] A Promise cannot be held …'") instead of the
8
+ * opaque "not assignable to type 'never'". Being a literal, a plain string equal to this exact text
9
+ * would technically be accepted where a promise is refused — a hole too narrow to matter in practice.
10
+ *
11
+ * @public
12
+ */
13
+ type PromiseNotAllowed = "[PicoFlow] A Promise cannot be held by a synchronous primitive; use stateAsync, derivationAsync or constantAsync";
14
+ /**
15
+ * Type that excludes Promise values from a type.
16
+ *
17
+ * This utility type ensures that synchronous reactive primitives (like `state`, `constant`, `derivation`)
18
+ * only accept non-Promise values. Use this to prevent accidental mixing of sync and async values, which
19
+ * would cause runtime errors. For async values, use the async variants (like `stateAsync`, `constantAsync`).
20
+ *
21
+ * A promise resolves to {@link PromiseNotAllowed}, so the compiler error names the problem; a union that
22
+ * includes a promise member is rejected rather than silently narrowed to its other members.
23
+ *
24
+ * The check is **one level deep**, by design: a promise nested inside an object or an array
25
+ * (`state({ inner: fetchUser() })`) is not detected. Deep detection would be costly and would reject
26
+ * legitimate models that hold promises as data.
27
+ *
28
+ * @public
29
+ */
30
+ type NotPromise<T> = T extends Promise<unknown> ? PromiseNotAllowed : T;
31
+ /**
32
+ * Type that narrows a reactive value to its read side.
33
+ *
34
+ * In practice it removes nothing: all four names live on the writable interfaces (`FlowState`,
35
+ * `FlowWritableDerivation`) rather than on `FlowValue` — `set`, `update` and `refresh` since #114,
36
+ * `trigger` since #132 (A3-ARCH-1), which moved it off the read side for the same reason. They stay
37
+ * named in the `Omit` as the statement of intent, and so that a mutator ever added to `FlowValue`
38
+ * is stripped here without a second edit.
39
+ *
40
+ * Use it to hand a reactive value to code that should observe it but not write to it — a child
41
+ * component, a module that only renders — while keeping write access where the value was created.
42
+ *
43
+ * This is a **compile-time narrowing only**: it removes the methods from the *type*, not from the
44
+ * object, which keeps whatever its factory gave it. A `FlowState` passed as `FlowReadonly` still has
45
+ * `set` at runtime, reachable through a cast or from JavaScript. For a value that must be read-only
46
+ * everywhere, create it with `constant()` or `derivation()` (or their async forms): since #114 those
47
+ * carry no mutator at all, so a `FlowReadonly` backed by one of them is read-only at runtime too
48
+ * (#32, A2-ARCH-3).
49
+ *
50
+ * @public
51
+ */
52
+ type FlowReadonly<T> = Omit<FlowValue<T>, "set" | "update" | "refresh" | "trigger">;
53
+ //#endregion
54
+ export { NotPromise as n, PromiseNotAllowed as r, FlowReadonly as t };
@@ -0,0 +1,17 @@
1
+ import { c as Observable, o as EffectNode } from "./shared.js";
2
+
3
+ //#region src/core/nodes/signalNode.ts
4
+ /**
5
+ * Manual trigger that notifies subscribers without carrying data.
6
+ * @internal
7
+ */
8
+ var SignalNode = class extends Observable {
9
+ _kind = "signal";
10
+ subscribe(onTrigger, onError, onPending, options) {
11
+ if (this._disposed) throw this._disposedError();
12
+ return new EffectNode((t) => this.watch(t), onTrigger, onError, onPending, options?.name);
13
+ }
14
+ };
15
+
16
+ //#endregion
17
+ export { SignalNode as t };
@@ -1,5 +1,8 @@
1
- import { Resource } from 'solid-js';
2
- import { FlowTracker, FlowValue, NotPromise } from '../core/api/index.js';
1
+ /// <reference lib="esnext.disposable" preserve="true" />
2
+ import { l as FlowTracker, n as FlowValue } from "./shared.js";
3
+ import { n as NotPromise } from "./shared3.js";
4
+ import { Resource } from "solid-js";
5
+ //#region src/converters/solid.d.ts
3
6
  /**
4
7
  * Converts a PicoFlow value or getter function into a SolidJS resource.
5
8
  *
@@ -24,9 +27,9 @@ import { FlowTracker, FlowValue, NotPromise } from '../core/api/index.js';
24
27
  * to `from()` are not disposed.
25
28
  *
26
29
  * @example
27
- * ```typescript
28
- * import { from } from 'picoflow/solid';
29
- * import { state, derivation } from 'picoflow';
30
+ * ```tsx
31
+ * import { state } from '@ersbeth/picoflow';
32
+ * import { from } from '@ersbeth/picoflow/solid';
30
33
  *
31
34
  * // Convert a PicoFlow state to a Solid resource
32
35
  * const $count = state(0);
@@ -38,12 +41,11 @@ import { FlowTracker, FlowValue, NotPromise } from '../core/api/index.js';
38
41
  * }
39
42
  *
40
43
  * // Or convert a computation function
41
- * const solidDerived = from((t) => {
42
- * return $count.get(t) * 2;
43
- * });
44
+ * const solidDerived = from((t) => $count.get(t) * 2);
44
45
  * ```
45
46
  *
46
47
  * @public
47
48
  */
48
49
  export declare function from<T>(flow: FlowValue<T>): Resource<T>;
49
50
  export declare function from<T>(flow: (t: FlowTracker) => NotPromise<T>): Resource<T>;
51
+ //#endregion
package/dist/solid.js ADDED
@@ -0,0 +1,63 @@
1
+ import { _ as PicoFlowPreconditionError, i as PICOFLOW_VALUE_NODE } from "./shared.js";
2
+ import { n as subscribe, t as derivation } from "./shared2.js";
3
+ import { createEffect, createResource, onCleanup, onMount, resetErrorBoundaries } from "solid-js";
4
+
5
+ //#region src/converters/solid.ts
6
+ function describeFlowInput(value) {
7
+ if (value === null) return "null";
8
+ if (typeof value === "object") {
9
+ const name = value.constructor?.name;
10
+ return name ? `object (${name})` : "object";
11
+ }
12
+ return typeof value;
13
+ }
14
+ /**
15
+ * Tests for the `picoflow.node` brand rather than `instanceof`: two copies of picoflow in one
16
+ * dependency tree produce two distinct `ReadableNode` class objects, and a node
17
+ * built by one copy fails `instanceof` in the other. `Symbol.for()` resolves to the same value
18
+ * across module copies, so the brand survives that split (A2-RT-1).
19
+ */
20
+ function isValueNode(flow) {
21
+ return typeof flow === "object" && flow !== null && PICOFLOW_VALUE_NODE in flow;
22
+ }
23
+ /**
24
+ * Internal helper that converts a PicoFlow node into a SolidJS resource.
25
+ * @internal
26
+ */
27
+ function fromNode(node, options) {
28
+ const [resource, { refetch }] = createResource(() => node.pick());
29
+ let fx;
30
+ onMount(() => {
31
+ fx = subscribe((t) => node.get(t), () => {
32
+ refetch();
33
+ }, () => {
34
+ refetch();
35
+ }, () => {
36
+ refetch();
37
+ });
38
+ });
39
+ createEffect(() => {
40
+ resource.error ?? resource();
41
+ resetErrorBoundaries();
42
+ });
43
+ onCleanup(() => {
44
+ fx.dispose();
45
+ if (options?.disposeNode) node.dispose();
46
+ });
47
+ return resource;
48
+ }
49
+ /**
50
+ * Internal helper that wraps a getter function in a PicoFlow node and converts it to a SolidJS resource.
51
+ * @internal
52
+ */
53
+ function fromGetter(getter) {
54
+ return fromNode(derivation(getter), { disposeNode: true });
55
+ }
56
+ function from(flow) {
57
+ if (isValueNode(flow)) return fromNode(flow);
58
+ if (typeof flow === "function") return fromGetter(flow);
59
+ throw new PicoFlowPreconditionError(`[PicoFlow] from(): expected a FlowValue or getter function, received ${describeFlowInput(flow)}`);
60
+ }
61
+
62
+ //#endregion
63
+ export { from };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ersbeth/picoflow",
3
- "version": "2.3.2",
3
+ "version": "3.0.0",
4
4
  "description": "Minimal Dataflow library for TypeScript",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.9.0",
@@ -12,40 +12,52 @@
12
12
  "SKILL.md"
13
13
  ],
14
14
  "exports": {
15
- "types": "./dist/types/index.d.ts",
16
- "default": "./dist/picoflow.js"
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./solid": {
20
+ "types": "./dist/solid.d.ts",
21
+ "default": "./dist/solid.js"
22
+ },
23
+ "./inspect": {
24
+ "types": "./dist/inspect.d.ts",
25
+ "default": "./dist/inspect.js"
26
+ }
17
27
  },
18
28
  "scripts": {
19
- "check": "pnpm exec tsc --noEmit",
20
- "lint": "pnpm exec biome check --fix",
21
- "lint:ci": "pnpm exec biome check .",
22
- "build": "pnpm exec vite build --config vite.config.ts",
23
- "build:ci": "pnpm exec vite build --config vite.config.ts && git diff --exit-code dist/",
29
+ "check": "pnpm exec vp check src test",
30
+ "lint": "pnpm exec vp check --fix src test",
31
+ "build": "pnpm exec vp pack",
32
+ "build:ci": "pnpm exec vp pack && git diff --exit-code dist/",
24
33
  "test:install": "playwright install --with-deps chromium",
25
- "test:core": "pnpm exec vitest --config=vitest.core.config.ts",
26
- "test:core:ci": "pnpm exec vitest run --config=vitest.core.config.ts --coverage",
27
- "test:converters": "pnpm exec vitest --config=vitest.converters.config.ts",
28
- "test:converters:ci": "pnpm exec vitest run --config=vitest.converters.config.ts --coverage",
29
- "verify:pre-commit": "pnpm check && pnpm lint:ci && pnpm build && pnpm test:core:ci",
30
- "verify:ci": "pnpm check && pnpm lint:ci && pnpm build:ci && pnpm test:core:ci",
31
- "verify:pre-push": "pnpm check && pnpm lint:ci && pnpm build:ci && pnpm test:core:ci && pnpm test:converters:ci"
34
+ "test:core": "pnpm exec vp test --project core",
35
+ "test:core:ci": "pnpm exec vp test run --project core --coverage --coverage.include='src/core/**/*'",
36
+ "test:converters": "pnpm exec vp test --project converters",
37
+ "test:converters:ci": "pnpm exec vp test run --project converters --coverage --coverage.include='src/converters/**/*' --coverage.include='src/solid.ts'",
38
+ "verify:pre-commit": "pnpm check && pnpm build && pnpm test:core:ci",
39
+ "verify:ci": "pnpm check && pnpm build:ci && pnpm test:core:ci",
40
+ "verify:pre-push": "pnpm check && pnpm build:ci && pnpm test:core:ci && pnpm test:converters:ci"
32
41
  },
33
42
  "peerDependencies": {
34
- "solid-js": "^1.9.7"
43
+ "solid-js": "^1.9.14"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "solid-js": {
47
+ "optional": true
48
+ }
35
49
  },
36
50
  "devDependencies": {
37
- "@biomejs/biome": "2.3.8",
38
51
  "@solidjs/testing-library": "^0.8.10",
39
- "@vitest/browser-playwright": "^4.1.10",
40
- "@vitest/coverage-v8": "4.1.10",
41
- "jsdom": "^27.3.0",
52
+ "@vitest/browser-playwright": "^4.1.11",
53
+ "@vitest/coverage-v8": "4.1.11",
54
+ "jsdom": "^27.4.0",
42
55
  "playwright": "1.62.1",
56
+ "solid-js": "^1.9.15",
43
57
  "typescript": "^5.9.3",
44
- "vite": "^7.3.0",
45
- "vite-plugin-dts": "^4.5.4",
46
- "vite-plugin-solid": "^2.11.10",
47
- "vite-tsconfig-paths": "^6.0.3",
48
- "vitest": "^4.1.10"
58
+ "vite-plugin-solid": "^2.11.14",
59
+ "vite-plus": "0.3.1",
60
+ "vitest": "^4.1.11"
49
61
  },
50
62
  "repository": {
51
63
  "type": "git",