@semi-solid/solid 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/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +200 -0
- package/package.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 semi-solid contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @semi-solid/solid
|
|
2
|
+
|
|
3
|
+
SolidJS runtime layer for Semi-Solid. Sits between the zero-dependency stubs in `@semi-solid/runtime` and your components, providing reactive implementations that depend on `solid-js`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @semi-solid/solid
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`solid-js ^1.9.0` is a peer dependency — install it alongside this package.
|
|
12
|
+
|
|
13
|
+
## What's inside
|
|
14
|
+
|
|
15
|
+
| Export | Source | Description |
|
|
16
|
+
|--------|--------|-------------|
|
|
17
|
+
| `tap`, `tapWhen`, `tapRemote`, `tapPersonalized`, `liquidRaw`, `blockAttrs` | re-exported from `@semi-solid/runtime` | Compile-time stubs — the compiler replaces these with Liquid output and reactive signals |
|
|
18
|
+
| `t`, `setTranslations` | re-exported from `@semi-solid/runtime` | i18n translation helper |
|
|
19
|
+
| `createTapSignal`, `__setSectionId` | `tapWhen.ts` | Reactive signal that re-fetches from a Shopify data section when dependencies change |
|
|
20
|
+
| `__tapRemoteHtml` | `tapRemote.ts` | Fetches rendered section HTML from another route via the Section Rendering API |
|
|
21
|
+
| `createPersonalizedSignal`, `__setPersonalizationBaseUrl`, `buildUrl` | `tapPersonalized.ts` | Fetches personalized data from an external API with prefetch support |
|
|
22
|
+
| `createStore` | `store.ts` | localStorage-backed reactive store (wishlists, recently viewed, etc.) |
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
Components never import from this package directly. They use the `$lib/` Vite alias, which resolves to `packages/solid/src/`:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// src/snippets/ProductCard.tsx
|
|
30
|
+
import { tap } from '$lib/runtime';
|
|
31
|
+
import { t } from '$lib/i18n';
|
|
32
|
+
|
|
33
|
+
const title = tap('{{ product.title }}', 'Product');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The compiler transforms `tap()` / `tapWhen()` / `tapPersonalized()` calls at build time. The reactive implementations (`createTapSignal`, `createPersonalizedSignal`, etc.) are auto-imported by the compiler into the cleaned output — you don't call them yourself.
|
|
37
|
+
|
|
38
|
+
### createStore
|
|
39
|
+
|
|
40
|
+
`createStore` is the one export you use directly in component code:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { createStore } from '$lib/runtime';
|
|
44
|
+
|
|
45
|
+
const recentlyViewed = createStore<Product>('recently-viewed', { maxItems: 10 });
|
|
46
|
+
|
|
47
|
+
// Read
|
|
48
|
+
const items = recentlyViewed.items(); // Accessor<Product[]>
|
|
49
|
+
|
|
50
|
+
// Write
|
|
51
|
+
recentlyViewed.add(product); // prepends, deduplicates, persists to localStorage
|
|
52
|
+
recentlyViewed.remove(product); // removes by JSON equality
|
|
53
|
+
recentlyViewed.clear(); // empties the store
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
@semi-solid/runtime (zero dependencies — stubs + types)
|
|
60
|
+
|
|
|
61
|
+
@semi-solid/solid (solid-js — reactive implementations)
|
|
62
|
+
|
|
|
63
|
+
Components (import via $lib/ alias)
|
|
64
|
+
|
|
|
65
|
+
@semi-solid/compiler (Vite plugin — transforms source at build time)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The compiler emits `$lib/runtime` and `$lib/tapWhen` imports in the transformed output. The `$lib` alias in `vite.config.ts` points to `packages/solid/src/`, so Vite resolves everything without any component files needing to know the physical path.
|
|
69
|
+
|
|
70
|
+
## Development
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Run tests
|
|
74
|
+
bun run test
|
|
75
|
+
|
|
76
|
+
# Watch mode
|
|
77
|
+
bun run test:watch
|
|
78
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export { blockAttrs, liquidRaw, setTranslations, t, tap, tapPersonalized, tapRemote, tapWhen } from '@semi-solid/runtime';
|
|
2
|
+
import { Accessor } from 'solid-js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* tapWhen runtime implementation.
|
|
6
|
+
*
|
|
7
|
+
* The compiler replaces every `tapWhen(liquidExpr, deps, fallback)` call with
|
|
8
|
+
* `createTapSignal(key, deps, fallback)`. The key is the LHS variable name,
|
|
9
|
+
* injected at compile time so the runtime knows which field to read from the
|
|
10
|
+
* JSON data section response.
|
|
11
|
+
*
|
|
12
|
+
* The data section is a Shopify section that renders only a
|
|
13
|
+
* <script type="application/json"> tag containing the component's tap-mapped
|
|
14
|
+
* values serialised with the | json Liquid filter. It can be fetched via:
|
|
15
|
+
*
|
|
16
|
+
* GET {any-route}?section_id={component-name}-data
|
|
17
|
+
*
|
|
18
|
+
* The currently-mounted component's section ID is communicated via a
|
|
19
|
+
* module-level variable set by the hydration entry immediately before
|
|
20
|
+
* calling render(). This is safe because render() is synchronous and
|
|
21
|
+
* createTapSignal() captures the value in a closure at call time.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
declare function __setSectionId(id: string | null | undefined): void;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a reactive signal for a tap-mapped value.
|
|
27
|
+
*
|
|
28
|
+
* - Initialises the signal from `initial` (the prop value from data-props).
|
|
29
|
+
* - Captures the active section ID at call time (synchronously set by the
|
|
30
|
+
* hydration entry before render()).
|
|
31
|
+
* - Registers a deferred createEffect that re-fetches the data section
|
|
32
|
+
* whenever any dep changes and updates the signal.
|
|
33
|
+
*
|
|
34
|
+
* @param key LHS variable name; used to index the JSON response.
|
|
35
|
+
* @param deps Signal accessors whose changes trigger a re-fetch.
|
|
36
|
+
* @param initial Initial value, usually props.xxx from data-props.
|
|
37
|
+
*/
|
|
38
|
+
declare function createTapSignal<T>(key: string, deps: Accessor<unknown>[], initial: T): Accessor<T>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* tapRemote runtime implementation.
|
|
42
|
+
*
|
|
43
|
+
* The compiler replaces every `tapRemote(Component, url)` call with
|
|
44
|
+
* `__tapRemoteHtml("remote-{kebab-name}", url)`. This function creates a
|
|
45
|
+
* SolidJS signal, fetches the rendered section HTML from the given URL via
|
|
46
|
+
* the Shopify Section Rendering API, and returns an accessor for raw HTML
|
|
47
|
+
* injection.
|
|
48
|
+
*
|
|
49
|
+
* If `url` is a reactive accessor (function), the section is re-fetched
|
|
50
|
+
* whenever the URL changes.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
declare function __tapRemoteHtml(sectionName: string, url: string | Accessor<string>): Accessor<string>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* tapPersonalized runtime implementation.
|
|
57
|
+
*
|
|
58
|
+
* The compiler replaces every `tapPersonalized(url, params, fallback)` call with
|
|
59
|
+
* `createPersonalizedSignal(url, params, fallback)`. This function creates a
|
|
60
|
+
* SolidJS signal, fetches personalized data from the external API, and returns
|
|
61
|
+
* an accessor.
|
|
62
|
+
*
|
|
63
|
+
* The compiler also generates:
|
|
64
|
+
* - <link rel="preconnect"> for the external domain
|
|
65
|
+
* - An inline <script> that starts the fetch early (prefetch), storing the
|
|
66
|
+
* promise on window.__p[url] so this runtime can pick it up without
|
|
67
|
+
* duplicating the request.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
declare function __setPersonalizationBaseUrl(url: string | undefined): void;
|
|
71
|
+
/**
|
|
72
|
+
* Builds a full URL from the endpoint and params.
|
|
73
|
+
* - Resolves relative URLs against _personalizedBaseUrl
|
|
74
|
+
* - Sorts param keys alphabetically (deterministic cache key matching with prefetch)
|
|
75
|
+
* - Builds query string with encodeURIComponent
|
|
76
|
+
*/
|
|
77
|
+
declare function buildUrl(endpoint: string, params: Record<string, unknown>): string;
|
|
78
|
+
declare global {
|
|
79
|
+
interface Window {
|
|
80
|
+
__p?: Record<string, Promise<unknown>>;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Creates a reactive signal for personalized data from an external API.
|
|
85
|
+
*
|
|
86
|
+
* 1. Checks window.__p[url] for a prefetched promise (started by the
|
|
87
|
+
* inline <head> script the compiler generates).
|
|
88
|
+
* 2. If no prefetch, fires a fetch immediately.
|
|
89
|
+
* 3. Sets up a deferred createEffect that re-fetches when any param
|
|
90
|
+
* signal changes.
|
|
91
|
+
*
|
|
92
|
+
* @param url API endpoint URL
|
|
93
|
+
* @param params Named params — may contain signal accessors or plain values
|
|
94
|
+
* @param initial Initial/fallback value
|
|
95
|
+
*/
|
|
96
|
+
declare function createPersonalizedSignal<T>(url: string, params: Record<string, unknown>, initial: T): Accessor<T>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* createStore — a localStorage-backed reactive store using SolidJS signals.
|
|
100
|
+
*
|
|
101
|
+
* Useful for recently viewed items, wishlists, and other client-side
|
|
102
|
+
* persistence that should survive page navigations and browser restarts.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
interface StoreOptions {
|
|
106
|
+
/** Maximum number of items to keep. Default: 20 */
|
|
107
|
+
maxItems?: number;
|
|
108
|
+
}
|
|
109
|
+
interface PersistentStore<T> {
|
|
110
|
+
items: Accessor<T[]>;
|
|
111
|
+
add: (item: T) => void;
|
|
112
|
+
remove: (item: T) => void;
|
|
113
|
+
clear: () => void;
|
|
114
|
+
}
|
|
115
|
+
declare function createStore<T>(key: string, options?: StoreOptions): PersistentStore<T>;
|
|
116
|
+
|
|
117
|
+
export { __setPersonalizationBaseUrl, __setSectionId, __tapRemoteHtml, buildUrl, createPersonalizedSignal, createStore, createTapSignal };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { tap, tapWhen, liquidRaw, blockAttrs, tapRemote, tapPersonalized } from "@semi-solid/runtime";
|
|
3
|
+
import { t, setTranslations } from "@semi-solid/runtime";
|
|
4
|
+
|
|
5
|
+
// src/tapWhen.ts
|
|
6
|
+
import { createSignal, createEffect, on } from "solid-js";
|
|
7
|
+
var _activeSectionId;
|
|
8
|
+
function __setSectionId(id) {
|
|
9
|
+
_activeSectionId = id ?? void 0;
|
|
10
|
+
}
|
|
11
|
+
async function fetchSectionData(sectionId) {
|
|
12
|
+
const url = new URL(
|
|
13
|
+
window.location.pathname + window.location.search,
|
|
14
|
+
window.location.origin
|
|
15
|
+
);
|
|
16
|
+
url.searchParams.set("section_id", sectionId);
|
|
17
|
+
const html = await fetch(url.toString()).then((r) => r.text());
|
|
18
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
19
|
+
const script = doc.querySelector('script[type="application/json"]');
|
|
20
|
+
return JSON.parse(script?.textContent ?? "{}");
|
|
21
|
+
}
|
|
22
|
+
function createTapSignal(key, deps, initial) {
|
|
23
|
+
const sectionId = _activeSectionId;
|
|
24
|
+
const [value, setValue] = createSignal(initial);
|
|
25
|
+
if (sectionId && deps.length > 0) {
|
|
26
|
+
createEffect(
|
|
27
|
+
on(
|
|
28
|
+
deps,
|
|
29
|
+
async () => {
|
|
30
|
+
try {
|
|
31
|
+
const data = await fetchSectionData(sectionId);
|
|
32
|
+
if (key in data) setValue(() => data[key]);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error(`[tapWhen] failed to refresh "${key}":`, e);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{ defer: true }
|
|
38
|
+
// skip initial run — data-props covers the first render
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/tapRemote.ts
|
|
46
|
+
import { createSignal as createSignal2, createEffect as createEffect2, on as on2 } from "solid-js";
|
|
47
|
+
async function fetchSection(sectionName, url) {
|
|
48
|
+
const target = new URL(url, window.location.origin);
|
|
49
|
+
target.searchParams.set("section_id", sectionName);
|
|
50
|
+
const html = await fetch(target.toString()).then((r) => r.text());
|
|
51
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
52
|
+
const wrapper = doc.querySelector('[id^="shopify-section-"]');
|
|
53
|
+
return wrapper?.innerHTML ?? html;
|
|
54
|
+
}
|
|
55
|
+
function __tapRemoteHtml(sectionName, url) {
|
|
56
|
+
const [html, setHtml] = createSignal2("");
|
|
57
|
+
if (typeof url === "function") {
|
|
58
|
+
createEffect2(
|
|
59
|
+
on2(url, async (currentUrl) => {
|
|
60
|
+
try {
|
|
61
|
+
const result = await fetchSection(sectionName, currentUrl);
|
|
62
|
+
setHtml(() => result);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error(`[tapRemote] failed to fetch "${sectionName}":`, e);
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
fetchSection(sectionName, url).then(
|
|
70
|
+
(result) => setHtml(() => result),
|
|
71
|
+
(e) => console.error(`[tapRemote] failed to fetch "${sectionName}":`, e)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return html;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/tapPersonalized.ts
|
|
78
|
+
import { createSignal as createSignal3, createEffect as createEffect3, on as on3 } from "solid-js";
|
|
79
|
+
var _personalizedBaseUrl;
|
|
80
|
+
function __setPersonalizationBaseUrl(url) {
|
|
81
|
+
_personalizedBaseUrl = url;
|
|
82
|
+
}
|
|
83
|
+
function buildUrl(endpoint, params) {
|
|
84
|
+
let base;
|
|
85
|
+
if (/^https?:\/\//.test(endpoint)) {
|
|
86
|
+
base = endpoint;
|
|
87
|
+
} else {
|
|
88
|
+
const origin = _personalizedBaseUrl ?? "";
|
|
89
|
+
base = origin.replace(/\/$/, "") + "/" + endpoint.replace(/^\//, "");
|
|
90
|
+
}
|
|
91
|
+
const keys = Object.keys(params).sort();
|
|
92
|
+
if (keys.length === 0) return base;
|
|
93
|
+
const qs = keys.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(String(params[k] ?? ""))}`).join("&");
|
|
94
|
+
return `${base}?${qs}`;
|
|
95
|
+
}
|
|
96
|
+
function createPersonalizedSignal(url, params, initial) {
|
|
97
|
+
const [value, setValue] = createSignal3(initial);
|
|
98
|
+
function resolveParams() {
|
|
99
|
+
const resolved = {};
|
|
100
|
+
for (const [k, v] of Object.entries(params)) {
|
|
101
|
+
resolved[k] = typeof v === "function" ? v() : v;
|
|
102
|
+
}
|
|
103
|
+
return resolved;
|
|
104
|
+
}
|
|
105
|
+
async function fetchData() {
|
|
106
|
+
const resolved = resolveParams();
|
|
107
|
+
const fullUrl = buildUrl(url, resolved);
|
|
108
|
+
try {
|
|
109
|
+
const prefetch = window.__p?.[fullUrl];
|
|
110
|
+
let data;
|
|
111
|
+
if (prefetch) {
|
|
112
|
+
data = await prefetch;
|
|
113
|
+
delete window.__p[fullUrl];
|
|
114
|
+
} else {
|
|
115
|
+
const res = await fetch(fullUrl);
|
|
116
|
+
data = await res.json();
|
|
117
|
+
}
|
|
118
|
+
setValue(() => data);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.error(`[tapPersonalized] failed to fetch "${url}":`, e);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const accessors = Object.values(params).filter(
|
|
124
|
+
(v) => typeof v === "function"
|
|
125
|
+
);
|
|
126
|
+
if (accessors.length > 0) {
|
|
127
|
+
fetchData();
|
|
128
|
+
createEffect3(
|
|
129
|
+
on3(
|
|
130
|
+
accessors,
|
|
131
|
+
() => {
|
|
132
|
+
fetchData();
|
|
133
|
+
},
|
|
134
|
+
{ defer: true }
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
} else {
|
|
138
|
+
fetchData();
|
|
139
|
+
}
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/store.ts
|
|
144
|
+
import { createSignal as createSignal4 } from "solid-js";
|
|
145
|
+
function readStorage(key) {
|
|
146
|
+
try {
|
|
147
|
+
const raw = localStorage.getItem(key);
|
|
148
|
+
if (!raw) return [];
|
|
149
|
+
return JSON.parse(raw);
|
|
150
|
+
} catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function writeStorage(key, value) {
|
|
155
|
+
try {
|
|
156
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function createStore(key, options) {
|
|
161
|
+
const maxItems = options?.maxItems ?? 20;
|
|
162
|
+
const initial = readStorage(key);
|
|
163
|
+
const [items, setItems] = createSignal4(initial);
|
|
164
|
+
function persist(next) {
|
|
165
|
+
setItems(() => next);
|
|
166
|
+
writeStorage(key, next);
|
|
167
|
+
}
|
|
168
|
+
function add(item) {
|
|
169
|
+
const serialised = JSON.stringify(item);
|
|
170
|
+
const deduped = items().filter((existing) => JSON.stringify(existing) !== serialised);
|
|
171
|
+
const next = [item, ...deduped].slice(0, maxItems);
|
|
172
|
+
persist(next);
|
|
173
|
+
}
|
|
174
|
+
function remove(item) {
|
|
175
|
+
const serialised = JSON.stringify(item);
|
|
176
|
+
const next = items().filter((existing) => JSON.stringify(existing) !== serialised);
|
|
177
|
+
persist(next);
|
|
178
|
+
}
|
|
179
|
+
function clear() {
|
|
180
|
+
persist([]);
|
|
181
|
+
}
|
|
182
|
+
return { items, add, remove, clear };
|
|
183
|
+
}
|
|
184
|
+
export {
|
|
185
|
+
__setPersonalizationBaseUrl,
|
|
186
|
+
__setSectionId,
|
|
187
|
+
__tapRemoteHtml,
|
|
188
|
+
blockAttrs,
|
|
189
|
+
buildUrl,
|
|
190
|
+
createPersonalizedSignal,
|
|
191
|
+
createStore,
|
|
192
|
+
createTapSignal,
|
|
193
|
+
liquidRaw,
|
|
194
|
+
setTranslations,
|
|
195
|
+
t,
|
|
196
|
+
tap,
|
|
197
|
+
tapPersonalized,
|
|
198
|
+
tapRemote,
|
|
199
|
+
tapWhen
|
|
200
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@semi-solid/solid",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@semi-solid/runtime": "0.1.0"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"solid-js": "^1.9.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"tsup": "^8.5.1",
|
|
26
|
+
"typescript": "^5.5.0",
|
|
27
|
+
"vitest": "^2.0.0"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest"
|
|
33
|
+
}
|
|
34
|
+
}
|