@potok-web-framework/core 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/CHANGELOG.md +7 -0
- package/bun.lock +25 -0
- package/package.json +39 -0
- package/src/block.ts +102 -0
- package/src/bootstrap-app.ts +115 -0
- package/src/client-only.ts +17 -0
- package/src/constants.ts +27 -0
- package/src/context.ts +85 -0
- package/src/detect-child.ts +21 -0
- package/src/error-boundary.ts +51 -0
- package/src/exports/client.ts +1 -0
- package/src/exports/hmr.ts +1 -0
- package/src/exports/index.ts +21 -0
- package/src/exports/jsx-runtime.ts +4 -0
- package/src/exports/server.ts +1 -0
- package/src/fragment.ts +28 -0
- package/src/global.dev.d.ts +12 -0
- package/src/hmr/hmr-dev.ts +10 -0
- package/src/hmr/register-component.ts +109 -0
- package/src/hmr/registered-component.ts +59 -0
- package/src/hmr/registry.ts +78 -0
- package/src/hmr/types.ts +6 -0
- package/src/hmr/utils.ts +20 -0
- package/src/html-element.ts +95 -0
- package/src/jsx-types.ts +13 -0
- package/src/lazy.ts +44 -0
- package/src/lib-context-reader.ts +33 -0
- package/src/lib-scripts.ts +8 -0
- package/src/lifecycle.ts +44 -0
- package/src/list.ts +175 -0
- package/src/portal.ts +101 -0
- package/src/prop-types.ts +1165 -0
- package/src/ref.ts +11 -0
- package/src/render-to-dom.ts +325 -0
- package/src/render-to-string.ts +65 -0
- package/src/server-node.ts +98 -0
- package/src/show.ts +46 -0
- package/src/signals.ts +323 -0
- package/src/store.ts +68 -0
- package/src/text.ts +35 -0
- package/src/types.ts +69 -0
- package/src/utils.ts +118 -0
- package/tests/signals.test.ts +403 -0
- package/tsconfig.json +17 -0
- package/vite.config.ts +21 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { test, expect, mock } from 'bun:test'
|
|
2
|
+
import {
|
|
3
|
+
batch,
|
|
4
|
+
createDisposer,
|
|
5
|
+
createEffect,
|
|
6
|
+
createSignal,
|
|
7
|
+
deepTrack,
|
|
8
|
+
untrack,
|
|
9
|
+
} from '@/signals'
|
|
10
|
+
|
|
11
|
+
test('сигнал сохраняет значение и вызывает эффекты при изменении', () => {
|
|
12
|
+
const signal = createSignal({ count: 1 })
|
|
13
|
+
|
|
14
|
+
// Проверка начального значения
|
|
15
|
+
expect(signal.count).toBe(1)
|
|
16
|
+
|
|
17
|
+
const spyFn = mock(() => {
|
|
18
|
+
signal.count
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// Создаём эффект, подписанный на signal.count
|
|
22
|
+
createEffect(spyFn)
|
|
23
|
+
|
|
24
|
+
// Эффект вызывается при инициализации
|
|
25
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
26
|
+
|
|
27
|
+
// Изменение значения вызывает эффект
|
|
28
|
+
signal.count = 2
|
|
29
|
+
expect(signal.count).toBe(2)
|
|
30
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
31
|
+
|
|
32
|
+
// Установка нового значения снова вызывает эффект
|
|
33
|
+
signal.count = 3
|
|
34
|
+
expect(signal.count).toBe(3)
|
|
35
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('эффект вызывается даже при установке сигнала в то же значение', () => {
|
|
39
|
+
const signal = createSignal({ count: 1 })
|
|
40
|
+
|
|
41
|
+
const spyFn = mock(() => {
|
|
42
|
+
signal.count
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
createEffect(spyFn)
|
|
46
|
+
|
|
47
|
+
// Эффект должен вызваться при инициализации
|
|
48
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
49
|
+
|
|
50
|
+
// Установка нового значения вызывает эффект
|
|
51
|
+
signal.count = 2
|
|
52
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
53
|
+
|
|
54
|
+
// Установка снова того же значения вызывает эффект
|
|
55
|
+
signal.count = 2
|
|
56
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('эффект реагирует на изменения всех сигналов, на которые он подписан', () => {
|
|
60
|
+
const firstSignal = createSignal({ count: 1 })
|
|
61
|
+
const secondSignal = createSignal({ count: 1 })
|
|
62
|
+
|
|
63
|
+
const spyFn = mock(() => {
|
|
64
|
+
firstSignal.count
|
|
65
|
+
secondSignal.count
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
createEffect(spyFn)
|
|
69
|
+
|
|
70
|
+
// Эффект вызывается сразу при инициализации
|
|
71
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
72
|
+
|
|
73
|
+
// Изменение первого сигнала
|
|
74
|
+
firstSignal.count++
|
|
75
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
76
|
+
|
|
77
|
+
// Изменение второго сигнала
|
|
78
|
+
secondSignal.count++
|
|
79
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('все эффекты, подписанные на один сигнал, вызываются при изменении', () => {
|
|
83
|
+
const signal = createSignal({ count: 1 })
|
|
84
|
+
|
|
85
|
+
const firstSpyFn = mock(() => {
|
|
86
|
+
signal.count
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const secondSpyFn = mock(() => {
|
|
90
|
+
signal.count
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Создаём два эффекта, подписанных на signal.count
|
|
94
|
+
createEffect(firstSpyFn)
|
|
95
|
+
createEffect(secondSpyFn)
|
|
96
|
+
|
|
97
|
+
// Оба эффекта вызываются один раз при создании
|
|
98
|
+
expect(firstSpyFn).toHaveBeenCalledTimes(1)
|
|
99
|
+
expect(secondSpyFn).toHaveBeenCalledTimes(1)
|
|
100
|
+
|
|
101
|
+
// Изменение сигнала вызывает оба эффекта
|
|
102
|
+
signal.count++
|
|
103
|
+
|
|
104
|
+
expect(signal.count).toBe(2)
|
|
105
|
+
expect(firstSpyFn).toHaveBeenCalledTimes(2)
|
|
106
|
+
expect(secondSpyFn).toHaveBeenCalledTimes(2)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test('вызывает эффект при изменении значения сигнала по ключу', () => {
|
|
110
|
+
const signal = createSignal({ count: 1 })
|
|
111
|
+
|
|
112
|
+
const spyFn = mock(() => {
|
|
113
|
+
signal.count // Чтение для подписки
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
createEffect(spyFn)
|
|
117
|
+
|
|
118
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
119
|
+
|
|
120
|
+
signal.count++ // Изменение значения
|
|
121
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
122
|
+
|
|
123
|
+
signal.count = signal.count // Установка того же значения — всё равно должно вызвать, т.к. мы не проверяем на "одинаковость"
|
|
124
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
125
|
+
|
|
126
|
+
signal.count = 100 // Новое значение
|
|
127
|
+
expect(spyFn).toHaveBeenCalledTimes(4)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('условная подписка: эффект не вызывается, если сигнал не читался', () => {
|
|
131
|
+
const firstSignal = createSignal({ count: 1 })
|
|
132
|
+
const secondSignal = createSignal({ count: 1 })
|
|
133
|
+
|
|
134
|
+
const spyFn = mock(() => {
|
|
135
|
+
// Подписка на secondSignal происходит только при выполнении условия
|
|
136
|
+
if (firstSignal.count < 2) {
|
|
137
|
+
secondSignal.count
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
createEffect(spyFn)
|
|
142
|
+
|
|
143
|
+
// Первый вызов эффекта
|
|
144
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
145
|
+
|
|
146
|
+
// secondSignal.count был прочитан (т.к. условие выполнилось), значит подписка есть
|
|
147
|
+
secondSignal.count++
|
|
148
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
149
|
+
|
|
150
|
+
// Меняем firstSignal так, чтобы условие не выполнялось => secondSignal больше не читается
|
|
151
|
+
firstSignal.count = 2
|
|
152
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
153
|
+
|
|
154
|
+
// Изменение secondSignal — эффекта не будет, т.к. подписка снята
|
|
155
|
+
secondSignal.count++
|
|
156
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
157
|
+
|
|
158
|
+
// Возвращаем условие обратно: подписка снова появится
|
|
159
|
+
firstSignal.count = 1
|
|
160
|
+
expect(spyFn).toHaveBeenCalledTimes(4)
|
|
161
|
+
|
|
162
|
+
// Подписка на secondSignal снова активна
|
|
163
|
+
secondSignal.count++
|
|
164
|
+
expect(spyFn).toHaveBeenCalledTimes(5)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('условная подписка: флаг игнорирования версионирования сохраняет подписку вне зависимости от чтения', () => {
|
|
168
|
+
const firstSignal = createSignal({ count: 1 })
|
|
169
|
+
const secondSignal = createSignal({ count: 1 })
|
|
170
|
+
|
|
171
|
+
const spyFn = mock(() => {
|
|
172
|
+
// При `firstSignal.count < 2` читаем secondSignal
|
|
173
|
+
if (firstSignal.count < 2) {
|
|
174
|
+
secondSignal.count
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
// Второй аргумент `true` — включаем режим игнорирования версионирования
|
|
179
|
+
createEffect(spyFn, true)
|
|
180
|
+
|
|
181
|
+
// Изначальный запуск
|
|
182
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
183
|
+
|
|
184
|
+
// Подписка активна — изменение secondSignal вызывает эффект
|
|
185
|
+
secondSignal.count++
|
|
186
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
187
|
+
|
|
188
|
+
// Условие теперь не выполняется — secondSignal НЕ читается
|
|
189
|
+
firstSignal.count = 2
|
|
190
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
191
|
+
|
|
192
|
+
// Несмотря на то, что secondSignal не был прочитан, эффект всё равно вызывается
|
|
193
|
+
secondSignal.count++
|
|
194
|
+
expect(spyFn).toHaveBeenCalledTimes(4)
|
|
195
|
+
|
|
196
|
+
// Возвращаем обратно выполнение условия
|
|
197
|
+
firstSignal.count = 1
|
|
198
|
+
expect(spyFn).toHaveBeenCalledTimes(5)
|
|
199
|
+
|
|
200
|
+
// Подписка всё ещё живая
|
|
201
|
+
secondSignal.count++
|
|
202
|
+
expect(spyFn).toHaveBeenCalledTimes(6)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('эффект вызывается один раз при батчинге нескольких обновлений', () => {
|
|
206
|
+
const firstSignal = createSignal({ count: 1 })
|
|
207
|
+
const secondSignal = createSignal({ count: 1 })
|
|
208
|
+
|
|
209
|
+
const spyFn = mock(() => {
|
|
210
|
+
firstSignal.count
|
|
211
|
+
secondSignal.count
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
createEffect(spyFn)
|
|
215
|
+
|
|
216
|
+
// Изначально вызывается один раз
|
|
217
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
218
|
+
|
|
219
|
+
// Обновление firstSignal вызывает эффект
|
|
220
|
+
firstSignal.count++
|
|
221
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
222
|
+
|
|
223
|
+
// Обновление secondSignal вызывает эффект
|
|
224
|
+
secondSignal.count++
|
|
225
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
226
|
+
|
|
227
|
+
// Два последовательных обновления вызывают эффект дважды
|
|
228
|
+
firstSignal.count++
|
|
229
|
+
secondSignal.count++
|
|
230
|
+
expect(spyFn).toHaveBeenCalledTimes(5)
|
|
231
|
+
|
|
232
|
+
// Обновления внутри batch вызывают эффект только один раз
|
|
233
|
+
batch(() => {
|
|
234
|
+
firstSignal.count++
|
|
235
|
+
secondSignal.count++
|
|
236
|
+
})
|
|
237
|
+
expect(spyFn).toHaveBeenCalledTimes(6)
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
test('untrack исключает сигналы из подписки внутри эффекта', () => {
|
|
241
|
+
const firstSignal = createSignal({ count: 1 })
|
|
242
|
+
const secondSignal = createSignal({ count: 1 })
|
|
243
|
+
|
|
244
|
+
const spyFn = mock(() => {
|
|
245
|
+
// Читаем firstSignal.count — устанавливаем реактивную подписку на firstSignal
|
|
246
|
+
firstSignal.count
|
|
247
|
+
|
|
248
|
+
// Читаем secondSignal.count внутри untrack — исключаем secondSignal из подписки эффекта
|
|
249
|
+
return untrack(() => secondSignal.count)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
createEffect(spyFn)
|
|
253
|
+
|
|
254
|
+
// Эффект вызывается один раз при создании — начальная инициализация
|
|
255
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
256
|
+
|
|
257
|
+
// Обновляем firstSignal — т.к. есть подписка, эффект должен вызваться заново
|
|
258
|
+
firstSignal.count++
|
|
259
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
260
|
+
|
|
261
|
+
// Обновляем secondSignal — эффект НЕ вызывается, потому что secondSignal был прочитан в untrack
|
|
262
|
+
secondSignal.count++
|
|
263
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
264
|
+
|
|
265
|
+
// Ещё раз обновляем firstSignal — эффект вызывается
|
|
266
|
+
firstSignal.count++
|
|
267
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
268
|
+
|
|
269
|
+
// Проверяем значение, возвращённое первым вызовом эффекта — secondSignal.count равен 1
|
|
270
|
+
expect(spyFn.mock.results[0]?.value).toBe(1)
|
|
271
|
+
|
|
272
|
+
// Проверяем значение, возвращённое вторым вызовом эффекта — secondSignal.count всё ещё 1,
|
|
273
|
+
// т.к. мы не подписаны на его изменения
|
|
274
|
+
expect(spyFn.mock.results[1]?.value).toBe(1)
|
|
275
|
+
|
|
276
|
+
// Проверяем значение, возвращённое третьим вызовом эффекта — secondSignal.count равно 2,
|
|
277
|
+
// т.к. в последнем вызове эффект прочитал значение после обновления firstSignal
|
|
278
|
+
expect(spyFn.mock.results[2]?.value).toBe(2)
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
test('deepTrack: реактивность на глубину отслеживания и разные уровни вложенности', () => {
|
|
282
|
+
const firstSignal = createSignal({
|
|
283
|
+
object: {
|
|
284
|
+
nestedObject: {
|
|
285
|
+
count: 1,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
const secondSignal = createSignal({
|
|
290
|
+
object: {
|
|
291
|
+
nestedObject: {
|
|
292
|
+
count: 1,
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
count: 1,
|
|
296
|
+
})
|
|
297
|
+
const thirdSignal = createSignal({
|
|
298
|
+
object: {
|
|
299
|
+
nestedObject: {
|
|
300
|
+
count: 1,
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
const spyFn = mock(() => {
|
|
306
|
+
// Подписка на верхний уровень объекта firstSignal (без глубокой подписки)
|
|
307
|
+
firstSignal.object
|
|
308
|
+
|
|
309
|
+
// Подписка с глубиной 1 — отслеживает изменения только первого уровня в secondSignal
|
|
310
|
+
deepTrack(secondSignal, 1)
|
|
311
|
+
|
|
312
|
+
// Подписка с глубиной по умолчанию (глубокая) — отслеживает изменения на всех уровнях thirdSignal
|
|
313
|
+
deepTrack(thirdSignal)
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
createEffect(spyFn)
|
|
317
|
+
|
|
318
|
+
// Изначальный вызов эффекта
|
|
319
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
320
|
+
|
|
321
|
+
// Изменение вложенного поля первого сигнала не вызывает эффект (глубина подписки 0)
|
|
322
|
+
firstSignal.object.nestedObject.count++
|
|
323
|
+
expect(spyFn).toHaveBeenCalledTimes(1)
|
|
324
|
+
|
|
325
|
+
// Изменение самого объекта первого сигнала (ссылка) вызывает эффект
|
|
326
|
+
firstSignal.object = {
|
|
327
|
+
nestedObject: {
|
|
328
|
+
count: 2,
|
|
329
|
+
},
|
|
330
|
+
}
|
|
331
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
332
|
+
|
|
333
|
+
// Изменение вложенного поля в secondSignal не вызывает эффект (глубина подписки 1)
|
|
334
|
+
secondSignal.object.nestedObject.count++
|
|
335
|
+
expect(spyFn).toHaveBeenCalledTimes(2)
|
|
336
|
+
|
|
337
|
+
// Изменение поля второго уровня secondSignal (count) вызывает эффект
|
|
338
|
+
secondSignal.count++
|
|
339
|
+
expect(spyFn).toHaveBeenCalledTimes(3)
|
|
340
|
+
|
|
341
|
+
// Изменение ссылки на объект верхнего уровня secondSignal вызывает эффект
|
|
342
|
+
secondSignal.object = {
|
|
343
|
+
nestedObject: {
|
|
344
|
+
count: 1,
|
|
345
|
+
},
|
|
346
|
+
}
|
|
347
|
+
expect(spyFn).toHaveBeenCalledTimes(4)
|
|
348
|
+
|
|
349
|
+
// Изменение вложенного объекта внутри secondSignal.object не вызывает эффект (глубина 1)
|
|
350
|
+
secondSignal.object.nestedObject = {
|
|
351
|
+
count: 1,
|
|
352
|
+
}
|
|
353
|
+
expect(spyFn).toHaveBeenCalledTimes(4)
|
|
354
|
+
|
|
355
|
+
// Изменение вложенного свойства thirdSignal вызывает эффект (глубина подписки глубокая)
|
|
356
|
+
thirdSignal.object.nestedObject.count++
|
|
357
|
+
expect(spyFn).toHaveBeenCalledTimes(5)
|
|
358
|
+
|
|
359
|
+
// Изменение ссылки на объект верхнего уровня thirdSignal вызывает эффект
|
|
360
|
+
thirdSignal.object = {
|
|
361
|
+
nestedObject: {
|
|
362
|
+
count: 1,
|
|
363
|
+
},
|
|
364
|
+
}
|
|
365
|
+
expect(spyFn).toHaveBeenCalledTimes(6)
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
test('createDisposer: удаляет все эффекты, созданные внутри области действия', () => {
|
|
369
|
+
const signal = createSignal({
|
|
370
|
+
count: 1,
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
const firstSpyFn = mock(() => {
|
|
374
|
+
signal.count
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
const secondSpyFn = mock(() => {
|
|
378
|
+
signal.count
|
|
379
|
+
})
|
|
380
|
+
|
|
381
|
+
// Создаём disposer, который регистрирует два эффекта
|
|
382
|
+
const disposer = createDisposer(() => {
|
|
383
|
+
createEffect(firstSpyFn)
|
|
384
|
+
createEffect(secondSpyFn)
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
// Эффекты сразу выполняются один раз при создании
|
|
388
|
+
expect(firstSpyFn).toHaveBeenCalledTimes(1)
|
|
389
|
+
expect(secondSpyFn).toHaveBeenCalledTimes(1)
|
|
390
|
+
|
|
391
|
+
// Изменение сигнала вызывает оба эффекта повторно
|
|
392
|
+
signal.count++
|
|
393
|
+
expect(firstSpyFn).toHaveBeenCalledTimes(2)
|
|
394
|
+
expect(secondSpyFn).toHaveBeenCalledTimes(2)
|
|
395
|
+
|
|
396
|
+
// Отключаем все эффекты, созданные внутри disposer'а
|
|
397
|
+
disposer.dispose()
|
|
398
|
+
|
|
399
|
+
// Изменение сигнала больше не вызывает эффекты
|
|
400
|
+
signal.count++
|
|
401
|
+
expect(firstSpyFn).toHaveBeenCalledTimes(2)
|
|
402
|
+
expect(secondSpyFn).toHaveBeenCalledTimes(2)
|
|
403
|
+
})
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"declaration": true,
|
|
4
|
+
"declarationMap": false,
|
|
5
|
+
"emitDeclarationOnly": true,
|
|
6
|
+
"jsx": "preserve",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"types": ["bun-types"],
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"target": "ESNext",
|
|
14
|
+
"module": "ESNext"
|
|
15
|
+
},
|
|
16
|
+
"include": ["./src/**/*"]
|
|
17
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import dtsPlugin from 'vite-plugin-dts'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
build: {
|
|
6
|
+
lib: {
|
|
7
|
+
entry: {
|
|
8
|
+
index: 'src/exports/index.ts',
|
|
9
|
+
server: 'src/exports/server.ts',
|
|
10
|
+
client: 'src/exports/client.ts',
|
|
11
|
+
'jsx-runtime': 'src/exports/jsx-runtime.ts',
|
|
12
|
+
hmr: 'src/exports/hmr.ts',
|
|
13
|
+
},
|
|
14
|
+
formats: ['es'],
|
|
15
|
+
},
|
|
16
|
+
rolldownOptions: {
|
|
17
|
+
external: ['path', /node:.*/],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
plugins: [dtsPlugin()],
|
|
21
|
+
})
|